import { InlineConfig, PluginOption } from 'vite';
import { InputOption, OutputOptions, ExternalOption } from 'rollup';
import { TransformOptions } from 'esbuild';

type Target = "modules" | "esnext" | "es2015" | "es2020" | TransformOptions["target"] | false;
type Mode = "server-first" | "client-first" | "parallel" | "skip";
type ServerConfig = {
    external: string[] | true;
    noExternal: string | RegExp | (string | RegExp)[] | true;
    output: OutputOptions;
    minify: boolean | "terser" | "esbuild";
    target: Target;
    outDir: string;
    emptyOutDir: boolean;
    privateDir: string;
    define: Record<string, any>;
};
type ClientConfig = {
    external: ExternalOption;
    output: OutputOptions | OutputOptions[];
    minify: boolean | "terser" | "esbuild";
    target: Target;
    outDir: string;
    emptyOutDir: boolean;
    publicDir: string;
    define: Record<string, any>;
};
type BuilderOpts = {
    mode?: Mode;
    serverEntry: string;
    serverConfig?: Partial<ServerConfig>;
    serverBuild?: (config: InlineConfig) => InlineConfig;
    serverPlugins?: PluginOption[];
    clientEntry?: InputOption;
    clientConfig?: Partial<ClientConfig>;
    clientBuild?: (config: InlineConfig) => InlineConfig;
    clientPlugins?: PluginOption[];
};

/**
 * Builder function to configure the server-side and client-side build process.
 * It takes in an options object that can override the default configuration.
 *
 * Default configuration:
 * ```typescript
 * {
 *   mode: "server-first",
 *   serverEntry: <<Value is Required>>,
 *   serverConfig: {
 *     external: [],
 *     noExternal: [],
 *     output: {
 *       format: "es",
 *       entryFileNames: "app.js",
 *       chunkFileNames: "bin/[name]-[hash].js",
 *       assetFileNames: "assets/[name]-[hash].[ext]",
 *     },
 *     minify: false,
 *     target: "esnext",
 *     outDir: "dist",
 *     emptyOutDir: true,
 *     privateDir: "private",
 *     define: {},
 *   },
 *   serverBuild: (config) => config,
 *   serverPlugins: [],
 *   clientEntry: { main: "index.html" },
 *   clientConfig: {
 *     external: () => false,
 *     output: {
 *       entryFileNames: "assets/[name]-[hash].js",
 *       chunkFileNames: "chunks/[name]-[hash].js",
 *       assetFileNames: "assets/[name]-[hash].[ext]",
 *     },
 *     minify: true,
 *     target: "modules",
 *     outDir: "dist/public",
 *     emptyOutDir: true,
 *     publicDir: "public",
 *     define: {},
 *   },
 *   clientBuild: (config) => config,
 *   clientPlugins: [],
 * }
 * ```
 */
declare const builder: (opts: BuilderOpts) => PluginOption;
declare const pluginBuilder: (opts: BuilderOpts) => PluginOption;

export { builder, builder as default, pluginBuilder };
