import { Config } from '@swc/types';
import { Options } from 'ts-loader';
import { Configuration } from 'webpack';
import { Configuration as Configuration$1 } from 'webpack-dev-server';

declare const BuildType: {
    readonly REACT_APP: "REACT_APP";
    readonly NEST_APP: "NEST_APP";
};
type BuildType = (typeof BuildType)[keyof typeof BuildType];

declare const NodeEnv: {
    readonly DEVELOPMENT: "development";
    readonly PRODUCTION: "production";
    readonly TEST: "test";
};
type NodeEnv = (typeof NodeEnv)[keyof typeof NodeEnv];

type BaseContextOptions<TBuildType extends BuildType = BuildType> = {
    buildType: TBuildType;
    id: string;
    rootDir: string;
    outDir?: string | undefined;
    cacheDir?: string | undefined;
    entryFile: string;
    nodeEnv: NodeEnv;
    envVars?: Record<string, string | undefined> | undefined;
    isProduction: boolean;
    isWatchMode: boolean;
    isDevServer: boolean;
    publicUrl: URL;
    useSWC?: boolean | undefined;
    swcLoaderConfig?: Partial<Config> | undefined;
    tsLoaderConfig?: Partial<Options> | undefined;
};
declare abstract class BaseContext<TBuildType extends BuildType = BuildType> {
    protected _buildType: TBuildType;
    protected _id: string;
    protected _projectDir: string;
    protected _rootDir: string;
    protected _outDir: string;
    protected _cacheDir: string;
    protected _pkgJsonFile: string;
    protected _tsconfigFile: string;
    protected _entryFile: string;
    protected _nodeEnv: NodeEnv;
    protected _envVars: Record<string, string | undefined>;
    protected _isProduction: boolean;
    protected _isWatchMode: boolean;
    protected _isDevServer: boolean;
    protected _publicUrl: URL;
    protected _useSWC: boolean;
    protected _swcLoaderConfig: Partial<Config>;
    protected _tsLoaderConfig: Partial<Options>;
    constructor(options: BaseContextOptions<TBuildType>);
    get buildType(): TBuildType;
    get id(): string;
    get projectDir(): string;
    get rootDir(): string;
    get outDir(): string;
    get cacheDir(): string;
    get pkgJsonFile(): string;
    get tsconfigFile(): string;
    get entryFile(): string;
    get nodeEnv(): NodeEnv;
    get envVars(): Record<string, string | undefined>;
    get isProduction(): boolean;
    get isWatchMode(): boolean;
    get isDevServer(): boolean;
    get publicUrl(): URL;
    get useSWC(): boolean;
    get swcLoaderConfig(): Partial<Config>;
    get tsLoaderConfig(): Partial<Options>;
    print(): void;
}

type WebpackConfiguration = Configuration & {
    devServer?: Configuration$1;
};
type WebpackEnv = {
    WEBPACK_BUNDLE?: boolean;
    WEBPACK_BUILD?: boolean;
    WEBPACK_WATCH?: boolean;
    WEBPACK_SERVE?: boolean;
    WEBPACK_PACKAGE?: string;
    WEBPACK_DEV_SERVER_PACKAGE?: string;
};

type Preset = {
    presetName: string;
} & Partial<WebpackConfiguration>;
type PresetFunc = (context: BaseContext, config: Partial<WebpackConfiguration>) => Preset;

type NestAppContextOptions = BaseContextOptions<typeof BuildType.NEST_APP> & {
    outFilename?: string | undefined;
};

type ReactAppContextOptions = BaseContextOptions<typeof BuildType.REACT_APP> & {
    htmlTemplateFile?: string | undefined;
};

type ContextOptions = NestAppContextOptions | ReactAppContextOptions;

type KeysOfUnion<T> = T extends unknown ? keyof T : never;
type DistributedOmit<T, K extends KeysOfUnion<T>> = T extends unknown ? Omit<T, K> : never;
type CreateBuildConfigurationOptions = DistributedOmit<ContextOptions, 'rootDir' | 'nodeEnv' | 'isProduction' | 'isDevServer' | 'isWatchMode' | 'publicUrl'>;
declare function createBuildConfiguration(rootDir: string, getOptions: () => CreateBuildConfigurationOptions | Promise<CreateBuildConfigurationOptions>): (env?: WebpackEnv) => Promise<WebpackConfiguration>;

declare const mergeConfig: (firstConfiguration: object | object[], ...configurations: object[]) => object;

export { BuildType, type CreateBuildConfigurationOptions, NodeEnv, type Preset, type PresetFunc, type WebpackConfiguration, type WebpackEnv, createBuildConfiguration, mergeConfig };
