import { BuildOptions, ExternalOption, InputOption, InputOptions, InternalModuleFormat, MinifyOptions, ModuleFormat, OutputOptions, Plugin } from "rolldown";
import { Hookable } from "hookable";
import { Options } from "publint";
import { Options as Options$1 } from "rolldown-plugin-dts";
import { Options as Options$2 } from "unplugin-unused";
import { PackageJson } from "pkg-types";

//#region src/utils/types.d.ts
type Overwrite<T, U> = Omit<T, keyof U> & U;
type Awaitable<T> = T | Promise<T>;
type MarkPartial<T, K extends keyof T> = Omit<Required<T>, K> & Partial<Pick<T, K>>;
type Arrayable<T> = T | T[];

//#endregion
//#region src/features/copy.d.ts
interface CopyEntry {
  from: string;
  to: string;
}
type CopyOptions = Arrayable<string | CopyEntry>;
type CopyOptionsFn = (options: ResolvedOptions) => Awaitable<CopyOptions>;

//#endregion
//#region src/features/hooks.d.ts
interface BuildContext {
  options: ResolvedOptions;
  pkg?: PackageJson;
  hooks: Hookable<TsdownHooks>;
}
interface RolldownContext {
  buildOptions: BuildOptions;
}
/**
* Hooks for tsdown.
*/
interface TsdownHooks {
  /**
  * Invoked before each tsdown build starts.
  * Use this hook to perform setup or preparation tasks.
  */
  "build:prepare": (ctx: BuildContext) => void | Promise<void>;
  /**
  * Invoked before each Rolldown build.
  * For dual-format builds, this hook is called for each format.
  * Useful for configuring or modifying the build context before bundling.
  */
  "build:before": (ctx: BuildContext & RolldownContext) => void | Promise<void>;
  /**
  * Invoked after each tsdown build completes.
  * Use this hook for cleanup or post-processing tasks.
  */
  "build:done": (ctx: BuildContext) => void | Promise<void>;
}

//#endregion
//#region src/utils/package.d.ts
type PackageType = "module" | "commonjs" | undefined;

//#endregion
//#region src/features/output.d.ts
interface OutExtensionContext {
  options: InputOptions;
  format: NormalizedFormat;
  /** "type" field in project's package.json */
  pkgType?: PackageType;
}
interface OutExtensionObject {
  js?: string;
  dts?: string;
}
type OutExtensionFactory = (context: OutExtensionContext) => OutExtensionObject | undefined;

//#endregion
//#region src/features/report.d.ts
interface ReportOptions {
  /**
  * Enable/disable brotli-compressed size reporting.
  * Compressing large output files can be slow, so disabling this may increase build performance for large projects.
  *
  * @default false
  */
  brotli?: boolean;
  /**
  * Skip reporting compressed size for files larger than this size.
  * @default 1_000_000 // 1MB
  */
  maxCompressSize?: number;
}
declare function ReportPlugin(options: ReportOptions, cwd: string, cjsDts?: boolean): Plugin;

//#endregion
//#region src/options.d.ts
type Sourcemap = boolean | "inline" | "hidden";
type Format = Exclude<ModuleFormat, "experimental-app">;
type NormalizedFormat = Exclude<InternalModuleFormat, "app">;
/**
* Options for tsdown.
*/
interface Options$3 {
  entry?: InputOption;
  external?: ExternalOption;
  noExternal?: Arrayable<string | RegExp> | ((id: string, importer: string | undefined) => boolean | null | undefined | void);
  alias?: Record<string, string>;
  tsconfig?: string | boolean;
  /** @default 'node' */
  platform?: "node" | "neutral" | "browser";
  inputOptions?: InputOptions | ((options: InputOptions, format: NormalizedFormat) => Awaitable<InputOptions | void | null>);
  /** @default ['es'] */
  format?: Format | Format[];
  globalName?: string;
  /** @default 'dist' */
  outDir?: string;
  /** @default false */
  sourcemap?: Sourcemap;
  /**
  * Clean directories before build.
  *
  * Default to output directory.
  * @default true
  */
  clean?: boolean | string[];
  /** @default false */
  minify?: boolean | "dce-only" | MinifyOptions;
  /**
  * Specifies the compilation target environment(s).
  *
  * Determines the JavaScript version or runtime(s) for which the code should be compiled.
  * If not set, defaults to the value of `engines.node` in your project's `package.json`.
  *
  * Accepts a single target (e.g., `'es2020'`, `'node18'`) or an array of targets.
  *
  * @see {@link https://tsdown.dev/guide/target#supported-targets} for a list of valid targets and more details.
  *
  * @example
  * ```jsonc
  * // Target a single environment
  * { "target": "node18" }
  * ```
  *
  * @example
  * ```jsonc
  * // Target multiple environments
  * { "target": ["node18", "es2020"] }
  * ```
  */
  target?: string | string[] | false;
  define?: Record<string, string>;
  /** @default false */
  shims?: boolean;
  /**
  * Use a fixed extension for output files.
  * The extension will always be `.cjs` or `.mjs`.
  * Otherwise, it will depend on the package type.
  * @default false
  */
  fixedExtension?: boolean;
  /**
  * Custom extensions for output files.
  * `fixedExtension` will be overridden by this option.
  */
  outExtensions?: OutExtensionFactory;
  outputOptions?: OutputOptions | ((options: OutputOptions, format: NormalizedFormat) => Awaitable<OutputOptions | void | null>);
  /** @default true */
  treeshake?: boolean;
  plugins?: InputOptions["plugins"];
  /** @default false */
  silent?: boolean;
  /**
  * Config file path
  */
  config?: boolean | string;
  /** @default false */
  watch?: boolean | string | string[];
  /**
  * You can specify command to be executed after a successful build, specially useful for Watch mode
  */
  onSuccess?: string | ((config: ResolvedOptions) => void | Promise<void>);
  /**
  * Skip bundling `node_modules`.
  * @default false
  */
  skipNodeModulesBundle?: boolean;
  /**
  * Reuse config from Vite or Vitest (experimental)
  * @default false
  */
  fromVite?: boolean | "vitest";
  /**
  * Emit TypeScript declaration files (.d.ts).
  *
  * By default, this feature is auto-detected based on the presence of the `types` field in the `package.json` file.
  * - If the `types` field is present in `package.json`, declaration file emission is enabled.
  * - If the `types` field is absent, declaration file emission is disabled by default.
  */
  dts?: boolean | Options$1;
  /**
  * Enable unused dependencies check with `unplugin-unused`
  * Requires `unplugin-unused` to be installed.
  * @default false
  */
  unused?: boolean | Options$2;
  /**
  * Run publint after bundling.
  * Requires `publint` to be installed.
  * @default false
  */
  publint?: boolean | Options;
  /**
  * Enable size reporting after bundling.
  * @default true
  */
  report?: boolean | ReportOptions;
  /**
  * Compile-time env variables.
  * @example
  * ```json
  * {
  *   "DEBUG": true,
  *   "NODE_ENV": "production"
  * }
  * ```
  */
  env?: Record<string, any>;
  /**
  * @deprecated Alias for `copy`, will be removed in the future.
  */
  publicDir?: CopyOptions | CopyOptionsFn;
  /**
  * Copy files to another directory.
  * @example
  * ```ts
  * [
  *   'src/assets',
  *   { from: 'src/assets', to: 'dist/assets' },
  * ]
  * ```
  */
  copy?: CopyOptions | CopyOptionsFn;
  hooks?: Partial<TsdownHooks> | ((hooks: Hookable<TsdownHooks>) => Awaitable<void>);
  /**
  * If enabled, strips the `node:` protocol prefix from import source.
  *
  * @default false
  *
  * @example
  * // With removeNodeProtocol enabled:
  * import('node:fs'); // becomes import('fs')
  */
  removeNodeProtocol?: boolean;
  /**
  * If enabled, appends hash to chunk filenames.
  * @default true
  */
  hash?: boolean;
}
/**
* Options without specifying config file path.
*/
type UserConfig = Arrayable<Omit<Options$3, "config">>;
type UserConfigFn = (cliOptions: Options$3) => Awaitable<UserConfig>;
type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options$3, "publicDir">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "noExternal" | "onSuccess" | "fixedExtension" | "outExtensions" | "hooks" | "removeNodeProtocol" | "copy">, {
  format: NormalizedFormat[];
  target?: string[];
  clean: string[];
  dts: false | Options$1;
  report: false | ReportOptions;
  tsconfig: string | false;
  cwd: string;
  pkg?: PackageJson;
}>, "config" | "fromVite">;

//#endregion
export { BuildContext, Options$3 as Options, ReportPlugin as ReportPlugin$1, ResolvedOptions, TsdownHooks, UserConfig, UserConfigFn };