/// <reference types="node" />

import * as esbuild from 'esbuild';
import { Plugin as Plugin_2 } from 'rollup';
import { Plugin as Plugin_3 } from 'esbuild';

export declare function buildPath(...parts: string[]): string;

export declare function esBuildBundle(confPath?: string | TFeRoomConfig | FeRoomConfigFile): Promise<esbuild.BuildResult<esbuild.BuildOptions>>;

export declare function esBuildCtx(confPath?: string | TFeRoomConfig | FeRoomConfigFile, onReBuild?: TESReBuildCallback): Promise<esbuild.BuildContext<esbuild.BuildOptions>>;

export declare const esbuildFeRoomPlugin: (conf: FeRoomConfigFile) => Plugin_3;

export declare class FeRoomConfigFile {
    protected watch: boolean;
    protected files: string[];
    protected data?: TFeRoomConfig;
    protected rendered?: TFeRoomConfig;
    protected listeners: ((cfg: TFeRoomConfig) => void | Promise<void>)[];
    constructor(path?: string | TFeRoomConfig, watch?: boolean);
    get(): Promise<TFeRoomConfig>;
    onChange(cb: (cfg: TFeRoomConfig) => void | Promise<void>): void;
    protected readConfig(): TFeRoomConfig<TFeRoomExtensionsOptionsAll> | Promise<TFeRoomConfig<TFeRoomExtensionsOptionsAll>>;
    protected buildConfig(filePath: string): Promise<TFeRoomConfig<TFeRoomExtensionsOptionsAll>>;
    protected loadJsConf(content: string): Promise<TFeRoomConfig>;
    protected fireChange(newConfig: TFeRoomConfig): void;
    render(): Promise<TFeRoomConfig>;
}

export declare class FeRoomRegister {
    private opts;
    constructor(opts: {
        host: string;
    });
    getUrl(path: string): string;
    register(opts?: {
        conf?: FeRoomConfigFile | TFeRoomConfig | string;
        activate?: boolean;
        files?: Record<string, string | Buffer>;
    }): Promise<void>;
    gatherFiles(conf: TFeRoomConfig, replace?: Record<string, string | Buffer>): Promise<Record<string, string | Buffer>>;
    postModule(module: {
        id: string;
        version: string;
        files: Record<string, string | Buffer>;
        activate?: boolean;
    }): Promise<void>;
}

export declare function getFilesByPattern(include?: string[], exclude?: string[]): Promise<string[]>;

export declare function getLockVersion(dep: string): string;

export declare function globPromise(path: string): Promise<string[]>;

export declare const logger: {
    clear: () => number;
    title: (text: string) => void;
    step: (text: string) => void;
    info: (text: string) => void;
    warn: (text: string) => void;
    error: (text: string) => void;
    dev: (text: string) => void;
};

export declare const pkg: {
    name: string;
    version: string;
    files: string[];
    module: string;
    main: string;
    dependencies?: Record<string, string> | undefined;
    peerDependencies?: Record<string, string> | undefined;
    devDependencies?: Record<string, string> | undefined;
};

export declare const rootPath: string;

declare type TClassConstructor<T = unknown> = new (...args: any[]) => T;

declare type TESReBuildCallback = (result: esbuild.BuildResult<esbuild.BuildOptions>) => void | Promise<void>;

declare interface TFeRoomConfig<EXT extends object = TFeRoomExtensionsOptionsAll> {
    devServer?: TFeRoomDevServerOptions;
    registerOptions?: TFeRoomRegisterOptions;
    buildOptions?: TFeRoomRollupOptions;
    extensions?: EXT;
}

declare interface TFeRoomDevServerOptions {
    port?: number;
    shared?: string;
    feroom?: TFeRoomServerOptions;
    ext?: (TClassConstructor<TFeRoomExtension> | TFeRoomExtension)[];
}

declare interface TFeRoomExtension {
    injectGlobals?(): Record<string, unknown>;
    injectImportMap?(): Record<string, string>;
    injectHead?(): string;
    injectIndexBody?(): string;
}

declare type TFeRoomExtensionsOptionsAll = TSharedMenuCfg & TVueRoutesCfg;

declare interface TFeRoomRegisterOptions {
    id?: string;
    entry?: string;
    label?: string;
    description?: string;
    include?: string[];
    exclude?: string[];
    preloadEntry?: boolean | 'head' | 'body:first' | 'body:last';
    preloadScripts?: string | string[];
    preloadCss?: string | string[];
    appendHead?: string;
    appendBody?: string;
    globals?: object;
    lockDependency?: {
        [name: string]: string;
    };
    importNpmDependencies?: {
        [name: string]: TNpmModuleData;
    };
}

declare interface TFeRoomRollupOptions {
    input?: string;
    ts?: boolean | object;
    vue?: boolean | object;
    css?: string | object;
    nodeResolve?: object;
    dependencies?: {
        bundle?: string[];
        lockVersion?: string[];
    };
    output?: string;
    plugins?: Plugin_2[];
}

declare interface TFeRoomServerOptions {
    modulesPrefixPath?: string;
    globals?: object;
    title?: string;
    preloadCss?: (string | [string, string])[];
    preloadScript?: (string | [string, string])[];
    preloadModule?: string[];
    body?: string;
    head?: string;
    importMap?: {
        [name: string]: string;
    };
    importNpmDependencies?: {
        [name: string]: TNpmModuleData;
    };
}

declare interface TMenuItem {
    icon?: string;
    route?: string;
    children?: Record<string, TMenuItem>;
    description?: string;
    params?: Record<string, string>;
}

declare interface TModuleData<EXT extends object = object> {
    id: string;
    version: string;
    files: Record<string, string | {
        type: 'Buffer';
        data: number[];
    } | Buffer>;
    entry: string;
    source: string;
    config: TFeRoomConfig<EXT>;
    activate?: boolean;
}

declare type TNpmModuleData<EXT extends object = object> = {
    registry?: string;
    name?: string;
    version?: string;
    forceRegister?: boolean;
    activateIfNewer?: boolean;
} & Partial<TModuleData<EXT>>;

declare type TSharedMenu = Record<string, TMenuItem>;

declare interface TSharedMenuCfg {
    sharedMenu?: TSharedMenu;
}

declare interface TVueRoute {
    path: string;
    component?: string;
    children?: TVueRoute[];
    name?: string;
    props?: boolean;
}

declare interface TVueRoutesCfg {
    vueRoutes?: TVueRoute[];
}

export declare function unbuildPath(path: string): string;

export { }
