// ---- index.d.mts ----
import * as tsup from 'tsup';
import { build as build$1 } from 'tsup';
export { Format, NormalizedOptions, Options } from 'tsup';

declare module '@npmcli/arborist' {
    export interface Node {
        name: string;
        path: string;
        realpath: string;
        package: Record<string, any>;
        isLink?: boolean;
        isRoot?: boolean;
        children?: Map<string, Node>;
    }

    export default class Arborist {
        constructor(options: { path: string });
        loadActual(): Promise<Node>;
    }
}

declare module 'npm-packlist' {
    export default function packlist(tree: {
        name: string;
        path: string;
        realpath: string;
        package: Record<string, any>;
        isLink?: boolean;
        isRoot?: boolean;
        children?: Map<string, any>;
    }): Promise<string[]>;
}

/**
 * Creates a tarball from a package
 *
 * @param options - options to customize the tarball
 * @returns an object containing the tarball path and included files
 */
declare function createTarball({ packageDir, packageJsonData, outputTarballPath }: PublishCreateOptions): Promise<PublishCreateResult>;

/**
 * Merges the contents of all files from the `files` array into `outFile`
 * @param files array of file paths or glob patterns (glob supported)
 * @param outFile destination file to write merged content (relative/absolute)
 * @param onResolvedFiles optional callback that is called after files are resolved and validated
 */
declare function mergeFiles(files: string[], outFile: string, onResolvedFiles?: (resolvedFiles: string[]) => void): Promise<void>;

declare class BuildUtils$1 {
    /**
     * The default build options
     */
    static readonly defaultConfigOptions: BuildOptions;
    /**
     * Array of commonly ignored entries
     */
    static readonly ignoredEntries: string[];
    /**
     * Aray of commonly used entries
     */
    static readonly entriesCommon: string[];
    /**
     * Array of index entries
     */
    static readonly entriesIndex: string[];
    /**
     * Array of default entries including index files and commonly ignored entries
     */
    static readonly defaultEntriesIndex: string[];
    /**
     * Array of default entries including any .ts files and commonly ignored entries
     */
    static readonly defaultEntriesCommon: string[];
    /**
     * Default options
     *
     * See all available options here: https://www.jsdocs.io/package/tsup#Options
     *
     * @default '{ tsconfig: "tsconfig.json", dts: true, format: ["esm"], minify: true }'
     * @param options configuration with entry, clean and splitting as required properties to avoid unintended behaviour
     * @param config (optional) configure tochibuild behaviour
     * @param throwErr (optional) whether or not to throw an error if something goes wrong
     * @param isCli (optional) whether or not this is being called from the CLI
     */
    static readonly handleOptions: (options: BuildOptionsParams<"entry" | "clean" | "splitting">, config?: TochibuildConfig, throwErr?: boolean, isCli?: boolean) => any;
    /**
     * Default options for index files as entry
     *
     * See all available options here: https://www.jsdocs.io/package/tsup#Options
     *
     * @default '{ entry: BuildUtils.defaultEntriesIndex, tsconfig: "tsconfig.json", dts: true, format: ["esm"], minify: true }'
     * @param options configuration with clean and splitting as required properties to avoid unintended behaviour
     * @param config (optional) configure tochibuild behaviour
     * @param throwErr (optional) whether or not to throw an error if something goes wrong
     * @param isCli (optional) whether or not this is being called from the CLI
     */
    static readonly handleOptionsWithIndexEntries: (options: BuildOptionsParams<"clean" | "splitting">, config?: TochibuildConfig, throwErr?: boolean, isCli?: boolean) => any;
    /**
     * Default options for common files as entry
     *
     * See all available options here: https://www.jsdocs.io/package/tsup#Options
     *
     * @default '{ entry: BuildUtils.defaultEntriesCommon, tsconfig: "tsconfig.json", dts: true, format: ["esm"], minify: true }'
     * @param options configuration with clean and splitting as required properties to avoid unintended behaviour
     * @param config (optional) configure tochibuild behaviour
     * @param throwErr (optional) whether or not to throw an error if something goes wrong
     * @param isCli (optional) whether or not this is being called from the CLI
     */
    static readonly handleOptionsWithCommonEntries: (options: BuildOptionsParams<"clean" | "splitting">, config?: TochibuildConfig, throwErr?: boolean, isCli?: boolean) => any;
    static readonly generateConfig: typeof generateConfig;
    static readonly ensureEntries: typeof ensureEntries;
    static readonly createTarball: typeof createTarball;
    static readonly mergeFiles: typeof mergeFiles;
    /**
     * Merge build options
     *
     * @param options the primary build options
     * @param config configure the overriding options and how to merge them
     * @param throwErr (optional) whether or not to throw an error if something goes wrong
     * @param isCli (optional) whether or not this is being called from the CLI
     */
    static readonly mergeBuildOptions: <TRequiredKeys extends keyof (BuildOptions | BuildOptionsWithConfig) = any, TOpts extends BuildOptionsResult<TRequiredKeys> | BuildOptionsParams<TRequiredKeys> = BuildOptionsParams<TRequiredKeys>>(options: TOpts, config: MergeBuildOptionsConfig, throwErr?: boolean, isCli?: boolean) => any;
    /**
     * Merge build options asynchronously
     *
     * @param options the primary build options
     * @param config configure the overriding options and how to merge them
     * @param throwErr (optional) whether or not to throw an error if something goes wrong
     * @param isCli (optional) whether or not this is being called from the CLI
     */
    static readonly mergeBuildOptionsAsync: <TOpts extends BuildOptionsResult | BuildOptionsParams, TConfig extends MergeBuildOptionsConfigAsync>(options: TOpts, config: TConfig, throwErr?: boolean, isCli?: boolean) => Promise<any>;
    /**
     * Get the file path and json data from a package.json
     *
     * If no rootDir is passed or if it's undefined, then the current working directory will be used
     *
     * @param rootDir the directory the package.json is in
     * @param throwErr whether or not to throw an error if something goes wrong
     */
    static readonly getPackageJson: <TPackageJson extends Record<string, any> = Record<string, any>>(rootDir?: string, throwErr?: boolean) => {
        filePath: string | undefined;
        data: TPackageJson | undefined;
    };
    /**
     * Get dependencies from a package.json file using config
     *
     * @param config configuration from {@link TochibuildConfig}
     * @param packageJsonPath the package.json file path
     */
    static readonly getPackageJsonDepsEntriesFromConfig: (config: TochibuildConfig | undefined, packageJsonPath?: string) => string[];
    /**
     * Get dependencies from a package.json file as entries
     *
     * @param packageJsonPath the package.json file path
     * @param filter the types of dependencies to include
     */
    static readonly getPackageJsonDepsEntries: (packageJsonPath: string | undefined, filter?: ("dependencies" | "devDependencies" | "peerDependencies")[]) => string[];
    /**
     * Get dependencies from a package.json file
     *
     * @param packageJsonPath the package.json file path
     * @param filter the types of dependencies to include
     */
    static readonly getPackageJsonDeps: (packageJsonPath: string | undefined) => {
        toArray: (filter?: ("dependencies" | "devDependencies" | "peerDependencies")[]) => string[];
        dependencies: any;
        devDependencies: any;
        peerDependencies: any;
    };
}

/**
 * Ensures that the passed entries includes the certain ones
 *
 * NOTE: only works for string arrays (otherwise will return the same entry) and will not overwrite or duplicate the entries
 *
 * @param entry the entries to check
 * @param type the type of entries to ensure
 */
declare function ensureEntries(entry: BuildOptions['entry'], type: ('ignoredEntries' | 'entriesIndex' | 'entriesCommon' | 'defaultEntriesIndex' | 'defaultEntriesCommon')[]): BuildOptions['entry'];
/**
 * Generate a config file
 *
 * @param cliModule which module to use
 * @param options (optional) configure how to generate the config
 * @param throwErr (optional) whether or not to throw an error if something goes wrong
 * @param isCli (optional) whether or not this is being called from the CLI
 */
declare function generateConfig(cliModule: CLIModule, options?: GenerateConfigOptionsCLI, throwErr?: boolean, isCli?: boolean): void;

type DefineConfigOptions = BuildOptionsParams<'entry' | 'clean' | 'splitting'>;
type DefineConfigOptionsIndexEntries = BuildOptionsParams<'clean' | 'splitting'>;
type DefineConfigOptionsCommonEntries = BuildOptionsParams<'clean' | 'splitting'>;
declare const BuildUtils: typeof BuildUtils$1;
declare const build: typeof build$1;
declare const _default: {
    utils: typeof BuildUtils$1;
    build: typeof build$1;
    defineConfig: typeof defineConfig;
    defineConfigWithIndexEntries: typeof defineConfigWithIndexEntries;
    defineConfigWithCommonEntries: typeof defineConfigWithCommonEntries;
};

/**
 * Define tochibuild configuration
 *
 * See all available options here: https://www.jsdocs.io/package/tsup#Options
 *
 * @default '{ tsconfig: "tsconfig.json", dts: true, format: ["esm"], minify: true }'
 * @param options configuration with entry, clean and splitting as required properties to avoid unintended behaviour
 * @param config (optional) configure tochibuild behaviour
 */
declare function defineConfig(options: DefineConfigOptions, config?: TochibuildConfig): Promise<tsup.Options | tsup.Options[] | ((overrideOptions: tsup.Options) => tsup.Options | tsup.Options[] | Promise<tsup.Options | tsup.Options[]>)>;
/**
 * Define tochibuild configuration with index files as entry
 *
 * See all available options here: https://www.jsdocs.io/package/tsup#Options
 *
 * @default '{ entry: BuildUtils.defaultEntriesIndex, tsconfig: "tsconfig.json", dts: true, format: ["esm"], minify: true }'
 * @param options configuration with clean and splitting as required properties to avoid unintended behaviour
 * @param config (optional) configure tochibuild behaviour
 */
declare function defineConfigWithIndexEntries(options: DefineConfigOptionsIndexEntries, config?: TochibuildConfig): Promise<tsup.Options | tsup.Options[] | ((overrideOptions: tsup.Options) => tsup.Options | tsup.Options[] | Promise<tsup.Options | tsup.Options[]>)>;
/**
 * Define tochibuild configuration with common files as entry
 *
 * See all available options here: https://www.jsdocs.io/package/tsup#Options
 *
 * @default '{ entry: BuildUtils.defaultEntriesCommon, tsconfig: "tsconfig.json", dts: true, format: ["esm"], minify: true }'
 * @param options configuration with clean and splitting as required properties to avoid unintended behaviour
 * @param config (optional) configure tochibuild behaviour
 */
declare function defineConfigWithCommonEntries(options: DefineConfigOptionsCommonEntries, config?: TochibuildConfig): Promise<tsup.Options | tsup.Options[] | ((overrideOptions: tsup.Options) => tsup.Options | tsup.Options[] | Promise<tsup.Options | tsup.Options[]>)>;

export { BuildUtils, type DefineConfigOptions, type DefineConfigOptionsCommonEntries, type DefineConfigOptionsIndexEntries, build, _default as default, defineConfig, defineConfigWithCommonEntries, defineConfigWithIndexEntries };


// ---- cli.d.ts ----
/// <reference types="commander" />

type CLIcac = import('cac').CAC;
type CLIModule = '@tochii/build' | 'tochibuild';

type CommandHandler = (cliModule: CLIModule, cli: CLIcac) => MaybePromise<void>;

type BuildOptionsCliFlag = keyof BuildOptionsCliFlagMap | '--no-config' | (string & {});

/**
 * Maps CLI flags (both long and short versions) to their corresponding {@link BuildOptions} property keys.
 */
interface BuildOptionsCliFlagMap extends Record<string, keyof BuildOptions> {
    // output directory
    '-d': 'outDir';
    '--out-dir': 'outDir';

    // format
    '--format': 'format';

    // minification
    '--minify': 'minify';
    '--minify-whitespace': 'minifyWhitespace';
    '--minify-identifiers': 'minifyIdentifiers';
    '--minify-syntax': 'minifySyntax';

    // misc flags
    '--keep-names': 'keepNames';
    '--target': 'target';
    '--legacy-output': 'legacyOutput';
    '--sourcemap': 'sourcemap';

    // watch and dev
    '--watch': 'watch';
    '--onSuccess': 'onSuccess';

    // inject and externals
    '--inject': 'inject';
    '--external': 'external';

    // output options
    '--global-name': 'globalName';
    '--jsxFactory': 'jsxFactory';
    '--jsxFragment': 'jsxFragment';
    '--replaceNodeEnv': 'replaceNodeEnv';
    '--no-splitting': 'splitting';
    '--clean': 'clean';
    '--silent': 'silent';
    '--pure': 'pure';
    '--metafile': 'metafile';

    // platform and env
    '--platform': 'platform';
    '--loader': 'loader';
    '--tsconfig': 'tsconfig';
    '--config': 'config';
    '--shims': 'shims';
    '--inject-style': 'injectStyle';

    // tree shaking and public assets
    '--treeshake': 'treeshake';
    '--publicDir': 'publicDir';

    // process control
    '--killSignal': 'killSignal';
    '--cjsInterop': 'cjsInterop';
}

/**
 * Provides default values for supported CLI flags (where applicable).
 */
interface BuildOptionsCliDefaults extends Partial<Record<keyof BuildOptionsCliFlagMap, unknown>> {
    '--format': 'esm';
    '--minify': false;
    '--sourcemap': false;
    '--watch': false;
    '--clean': false;
    '--silent': false;
    '--shims': true;
    '--splitting': true;
    '--treeshake': true;
    '--cjsInterop': true;
    '--platform': 'node';
    '--target': 'esnext';
}

type BuildOptionsCliAllowedTypes = string | string[] | boolean;
type BuildOptionsCliReplaceIfNotAllowed<T> = T extends BuildOptionsCliAllowedTypes ? T : string;
type BuildOptionsCliFlags = {
    [K in BuildOptionsCliKeys]: BuildOptionsCliReplaceIfNotAllowed<BuildOptions[K]>;
};
type BuildOptionsCliKeys =
    | 'outDir'
    | 'format'
    | 'minify'
    | 'minifyWhitespace'
    | 'minifyIdentifiers'
    | 'minifySyntax'
    | 'keepNames'
    | 'target'
    | 'legacyOutput'
    | 'sourcemap'
    | 'watch'
    | 'onSuccess'
    | 'inject'
    | 'external'
    | 'globalName'
    | 'jsxFactory'
    | 'jsxFragment'
    | 'replaceNodeEnv'
    | 'splitting'
    | 'clean'
    | 'silent'
    | 'pure'
    | 'metafile'
    | 'platform'
    | 'loader'
    | 'tsconfig'
    | 'config'
    | 'shims'
    | 'injectStyle'
    | 'treeshake'
    | 'publicDir'
    | 'killSignal'
    | 'cjsInterop';


// ---- commands.d.ts ----
type GenerateConfigOptionsCLI = {
    /**
     * The file extension to use
     * @default '.ts'
     */
    ext?: '.ts' | '.js' | '.cjs' | '.json';

    /**
     * The name of the file to generate
     * @default 'tochibuild.config'
     */
    filename?: 'tochibuild.config' | (string & {});

    /**
     * If the file already exists, overwrite it
     * @default false
     */
    overwrite?: boolean;

    /**
     * The output directories
     * @default the current working directory
     */
    outDir?: string[];
};

type CreateTarballOptionsCLI = {
    /**
     * Path to the original package directory (relative/absolute)
     * @default the current working directory
     */
    dir?: string;

    /**
     * The custom path to the package.json file (relative/absolute)
     * @default 'package.json'
     */
    pkg?: string;

    /**
     * The output tarball path (relative/absolute)
     * @default tochibuild.package.tgz
     */
    out?: string[];
};


// ---- lifecycle.d.ts ----
type BuildLifecyclePackageJsonHandler =
    | PackageJsonOptions
    | ((override: PackageJsonOptions) => PackageJsonOptions);
type BuildLifecyclePackageJsonValue =
    | string
    | BuildLifecyclePackageJsonHandler
    | {
          /**
           * The path to the package.json file (relative to the current working directory)
           *
           * Use the `data` property instead if you already have the package.json data
           */
          path?: string;

          /**
           * The package.json data
           *
           * Use the `path` property instead if you don't have the package.json data
           */
          data?: BuildLifecyclePackageJsonHandler;
      };

type BuildLifecycleRegistryUri =
    | 'https://registry.npmjs.org/'
    | 'https://registry.yarnpkg.com/'
    | 'https://npm.pkg.github.com/';

interface BuildLifecycleRegistry extends Record<string, BuildLifecycleRegistryUri> {
    npm: 'https://registry.npmjs.org/';
    yarn: 'https://registry.yarnpkg.com/';
    pnpm: 'https://registry.npmjs.org/';
    bun: 'https://registry.npmjs.org/';
    github: 'https://npm.pkg.github.com/';
}

type BuildLifecycleHookOptions<
    TDefaultHooks extends Record<string, any> = BuildLifecycleDefaultHooks<any>,
> = (BuildLifecycleHookOptionsCli | BuildLifecycleHookOptionsAction) & {
    /**
     * The description of what the hook does
     * @example 'generate pokemons'
     */
    description?: string;

    /**
     * The lifecycle position of the hook
     */
    position:
        | 'before.build'
        | `before.${keyof TDefaultHooks}`
        | 'after.build'
        | `after.${keyof TDefaultHooks}`;
};

type BuildLifecycleHookOptionsCli = {
    /**
     * The name of the hook
     * @example 'my special hook'
     */
    name?: string;

    /**
     * The cli to use for this hook
     */
    cli: {
        /**
         * The name of the cli to use for this hook
         *
         * If `undefined` or `null` is provided, then the one from {@link BuildLifecycleOptions} will be used
         *
         * @example 'node', 'nodemon' or 'tsx'
         */
        name:
            | keyof Omit<BuildLifecycleRegistry, 'github'>
            | 'node'
            | (string & {})
            | undefined
            | null;

        /**
         * The command and arguments to use for this hook (eg. `run`, `script.js`)
         *
         * The provided cli name will be prefixed to the command
         */
        args: string[];
    };
};

type TBuildUtils = typeof import('../utils/index').BuildUtils;
type BuildLifecycleHookOptionsAction = {
    /**
     * The name of the hook
     * @example 'my special hook'
     */
    name: string;

    /**
     * The action to perform for this hook
     *
     * @param utils build utilities
     * @param config the settings from the configuration file
     * @param packageJson data from package.json
     */
    action: (
        utils: TBuildUtils,
        config: TochibuildConfig | undefined,
        packageJson: PackageJsonOptions | undefined
    ) => MaybePromise<void>;
};

type BuildLifecycleDefaultHookOptionsKnown<
    TPackageManager extends keyof BuildLifecycleRegistry,
    TBuildLifecycleHookName extends BuildLifecycleDefaultHookName,
> = BuildLifecyclePackageManagerOptions<
    TPackageManager,
    TBuildLifecycleHookName
>[TPackageManager][TBuildLifecycleHookName];

type BuildLifecycleDefaultHookOptionsUnknown = Record<string, any>;

type BuildLifecycleDefaultHookOptions<
    TPackageManager extends keyof BuildLifecycleRegistry | (string & {}),
    TBuildLifecycleHookName extends BuildLifecycleDefaultHookName,
> = (TPackageManager extends keyof BuildLifecycleRegistry
    ? BuildLifecycleDefaultHookOptionsKnown<TPackageManager, TBuildLifecycleHookName>
    : BuildLifecycleDefaultHookOptionsUnknown) & {
    /**
     * The package manager to use
     *
     * If none is provided, then the one from {@link BuildLifecycleOptions} will be used
     */
    packageManager?:
        | ConditionalType<
              TBuildLifecycleHookName,
              'deprecate',
              'npm',
              keyof Omit<BuildLifecycleRegistry, 'github'>
          >
        | (string & {});

    /**
     * The command to use
     */
    command?: TBuildLifecycleHookName | (string & {});

    /**
     * The arguments for the command if any (eg. `--no-private`)
     *
     * NOTE: the tarball will be created automatically (recommended) if not provided
     */
    args?: string[];
};

type BuildLifecycleDefaultHookName = 'publish' | 'deprecate';
type BuildLifecycleDefaultHooks<
    TPackageManager extends keyof BuildLifecycleRegistry | (string & {}),
> = {
    /**
     * The default publish command for the selected package manager
     *
     * More info:
     * - [npm](https://docs.npmjs.com/cli/commands/npm-publish)
     * - [yarn](https://yarnpkg.com/cli/npm/publish)
     * - [pnpm](https://pnpm.io/cli/publish)
     * - [bun](https://bun.sh/docs/cli/publish)
     */
    publish?: BuildLifecycleDefaultHookOptions<TPackageManager, 'publish'>;

    /**
     * The default deprecate command for the selected package manager
     *
     * NOTE: this hook is unaware of workspaces
     *
     * More info:
     * - [npm](https://docs.npmjs.com/cli/commands/npm-deprecate)
     * - only npm supports deprecating packages
     */
    deprecate?: BuildLifecycleDefaultHookOptions<TPackageManager, 'deprecate'>;
};

type BuildLifecycleOptions<TPackageManager extends keyof BuildLifecycleRegistry | (string & {})> = {
    /**
     * The package manager to use
     */
    packageManager: TPackageManager;

    /**
     * The access level of the package
     * @default 'restricted'
     */
    access?: 'public' | 'restricted' | (string & {});

    /**
     * The registry to publish to
     * @default 'https://registry.npmjs.org/'
     */
    registry?: BuildLifecycleRegistryUri | (string & {});

    /**
     * The hooks to use for the build lifecycle
     *
     * These hooks are not running or overriding any pre/post scripts in your package.json
     */
    hooks?: BuildLifecycleDefaultHooks<TPackageManager> & {
        /**
         * Add your own hook(s)
         */
        custom?: MaybeArray<BuildLifecycleHookOptions>;
    };

    /**
     * The package.json to use for the published package
     *
     * If a string is provided (relative to the current working directory), it will be used as the path to the package.json
     *
     * Configure the options using {@link BuildLifecyclePackageJsonValue}
     *
     * @default 'package.json'
     */
    packageJson?: BuildLifecyclePackageJsonValue;
};

type MaybeNpmOnlyOptions<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
    TBuildLifecyclePackageManagerOptions extends Record<
        TPackageManagerCommandName,
        Record<string, any>
    >,
> = ConditionalType<
    TPackageManagerCommandName,
    'deprecate',
    TBuildLifecyclePackageManagerOptions,
    TPackageManager
>;

interface BuildLifecyclePackageManagerOptions<
    TPackageManager extends keyof BuildLifecycleRegistry,
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManager, Record<TPackageManagerCommandName, Record<string, any>>> {
    npm: MaybeNpmOnlyOptions<
        TPackageManagerCommandName,
        BuildLifecyclePackageManagerOptionsNpm<TPackageManagerCommandName>
    >;
    yarn: MaybeNpmOnlyOptions<
        TPackageManagerCommandName,
        BuildLifecyclePackageManagerOptionsYarn<TPackageManagerCommandName>
    >;
    pnpm: MaybeNpmOnlyOptions<
        TPackageManagerCommandName,
        BuildLifecyclePackageManagerOptionsPnpm<TPackageManagerCommandName>
    >;
    bun: MaybeNpmOnlyOptions<
        TPackageManagerCommandName,
        BuildLifecyclePackageManagerOptionsBun<TPackageManagerCommandName>
    >;
    github: MaybeNpmOnlyOptions<
        TPackageManagerCommandName,
        BuildLifecyclePackageManagerOptionsGithub<TPackageManagerCommandName>
    >;
}

interface BuildLifecyclePackageManagerOptionsNpm<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManagerCommandName, Record<string, any>> {
    /**
     * The publish command for `npm@11`
     * @see https://docs.npmjs.com/cli/v11/commands/npm-publish
     */
    publish?: NpmPublishOptions;

    /**
     * The deprecate command for `npm@11`
     * @see https://docs.npmjs.com/cli/v11/commands/npm-deprecate
     */
    deprecate?: NpmDeprecateOptions;
}

interface BuildLifecyclePackageManagerOptionsYarn<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManagerCommandName, Record<string, any>> {
    /**
     * The publish command for `yarn`
     * @see https://yarnpkg.com/cli/publish
     */
    publish?: YarnPublishOptions;
}

interface BuildLifecyclePackageManagerOptionsYarn<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManagerCommandName, Record<string, any>> {
    /**
     * The publish command for `yarn`
     * @see https://yarnpkg.com/cli/publish
     */
    publish?: YarnPublishOptions;
}

interface BuildLifecyclePackageManagerOptionsPnpm<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManagerCommandName, Record<string, any>> {
    /**
     * The publish command for `pnpm`
     * @see https://pnpm.io/cli/publish
     */
    publish?: PnpmPublishOptions;
}

interface BuildLifecyclePackageManagerOptionsBun<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManagerCommandName, Record<string, any>> {
    /**
     * The publish command for `bun`
     * @see https://bun.sh/docs/cli/publish
     */
    publish?: BunPublishOptions;
}

interface BuildLifecyclePackageManagerOptionsGithub<
    TPackageManagerCommandName extends BuildLifecycleDefaultHookName,
> extends Record<TPackageManagerCommandName, Record<string, any>> {
    /**
     * The publish command for GitHub's npm registry
     */
    publish?: GithubPublishOptions;
}


// ---- npm.d.ts ----
interface NpmPublishOptions {
    /**
     * The tag that will be added to the package in the registry.
     * @default 'latest'
     */
    tag?: string;

    /**
     * Control access level for scoped packages.
     * @default 'public' for new packages; no change for existing
     */
    access?: 'public' | 'restricted' | null;

    /**
     * Indicates a dry run without actual publishing.
     * @default false
     */
    'dry-run'?: boolean;

    /**
     * One-time password for 2FA-enabled accounts.
     * @default null
     */
    otp?: string | null;

    /**
     * Run the command in the context of a specific workspace.
     * Can be passed multiple times.
     */
    workspace?: string | string[];

    /**
     * Run the command in the context of all configured workspaces.
     * @default null
     */
    workspaces?: boolean | null;

    /**
     * Include the workspace root when workspaces are enabled.
     * @default false
     */
    'include-workspace-root'?: boolean;

    /**
     * Link the package to its CI/CD provenance on supported systems.
     * Cannot be used with `provenance-file`.
     * @default false
     */
    provenance?: boolean;

    /**
     * Path to a provenance bundle to use during publish.
     * Cannot be used with `provenance`.
     * @default null
     */
    'provenance-file'?: string | null;

    /**
     * Skip publishing if package.json has "private": true.
     * @default false
     */
    'no-private'?: boolean;
}

interface NpmDeprecateOptions {
    /**
     * The version or semver range to deprecate.
     */
    version: string;

    /**
     * The deprecation message to be shown.
     * Use an empty string to remove the deprecation.
     */
    message: string;

    /**
     * Indicates a dry run without actual changes.
     * @default false
     */
    'dry-run'?: boolean;

    /**
     * One-time password for 2FA-enabled accounts.
     * @default null
     */
    otp?: string | null;
}

interface YarnPublishOptions
    extends Omit<NpmPublishOptions, 'access' | 'otp' | 'provenance' | 'provenance-file'> {
    'no-git-tag-version'?: boolean;
}

interface PnpmPublishOptions extends Omit<NpmPublishOptions, 'provenance' | 'provenance-file'> {
    tag?: string;
}

interface BunPublishOptions
    extends Omit<
        NpmPublishOptions,
        | 'otp'
        | 'provenance'
        | 'provenance-file'
        | 'workspace'
        | 'workspaces'
        | 'include-workspace-root'
    > {}

interface GithubPublishOptions
    extends Omit<NpmPublishOptions, 'access' | 'provenance' | 'provenance-file'> {
    token?: string;
    'dry-run'?: boolean;
}


// ---- pkg.json.d.ts ----
/**
 * Represents the structure of a package.json file.
 * All properties are optional to allow for partial definitions.
 */
interface PackageJsonOptions {
    [key: string]: Record<string, any> | string | number | boolean | null;

    /**
     * The name of your package.
     * Must be lowercase and may include hyphens and underscores.
     * @example "my-awesome-package"
     */
    name?: string;

    /**
     * The version of your package.
     * Must follow semantic versioning.
     * @example "1.0.0"
     */
    version?: string;

    /**
     * A brief description of your package.
     * @example "A package that does awesome things."
     */
    description?: string;

    /**
     * The entry point to your package.
     * @example "index.js"
     */
    main?: string;

    /**
     * The module entry point for ES6 module systems.
     * @example "dist/index.mjs"
     */
    module?: string;

    /**
     * The types entry point for TypeScript definitions.
     * @example "dist/index.d.ts"
     */
    types?: string;

    /**
     * An array of keywords that describes your package.
     * Helps people discover your package as it's listed in npm search.
     * @example ["awesome", "package", "nodejs"]
     */
    keywords?: string[];

    /**
     * The license for your package.
     * @example "MIT"
     */
    license?: string;

    /**
     * The author of the package.
     * Can be a string or an object with name, email, and url.
     * @example "Jane Doe <jane@example.com> (https://example.com)"
     */
    author?:
        | string
        | {
              name: string;
              email?: string;
              url?: string;
          };

    /**
     * A list of contributors to the package.
     * Each contributor can be a string or an object with name, email, and url.
     */
    contributors?: Array<
        | string
        | {
              name: string;
              email?: string;
              url?: string;
          }
    >;

    /**
     * The URL to the homepage of your package.
     * @example "https://example.com"
     */
    homepage?: string;

    /**
     * Information about the bugs for your package.
     * Can be a URL or an object with url and email.
     */
    bugs?:
        | string
        | {
              url?: string;
              email?: string;
          };

    /**
     * The repository where your package's source code lives.
     * Can be a string or an object with type and url.
     */
    repository?:
        | string
        | {
              type: string;
              url: string;
              directory?: string;
          };

    /**
     * Script commands that are run at various times in the lifecycle of your package.
     * @example { "start": "node index.js", "test": "jest" }
     */
    scripts?: Record<string, string>;

    /**
     * Dependencies that are required to run your package.
     * @example { "express": "^4.17.1" }
     */
    dependencies?: Record<string, string>;

    /**
     * Dependencies that are only needed for development and testing.
     * @example { "jest": "^26.6.3" }
     */
    devDependencies?: Record<string, string>;

    /**
     * Optional dependencies that are not required for your package to work.
     * @example { "fsevents": "^2.3.2" }
     */
    optionalDependencies?: Record<string, string>;

    /**
     * Dependencies that are bundled when publishing the package.
     * @example { "lodash": "^4.17.21" }
     */
    bundledDependencies?: string[];

    /**
     * Engines that your package is compatible with.
     * @example { "node": ">=12.0.0" }
     */
    engines?: Record<string, string>;

    /**
     * Operating systems your package is compatible with.
     * @example ["darwin", "linux"]
     */
    os?: string[];

    /**
     * CPU architectures your package is compatible with.
     * @example ["x64", "arm64"]
     */
    cpu?: string[];

    /**
     * Files to include when publishing your package.
     * @example ["dist/", "README.md"]
     */
    files?: string[];

    /**
     * The directory that contains the executable files.
     * @example "bin"
     */
    bin?: string | Record<string, string>;

    /**
     * Configuration options for your package.
     * These can be used by your package's code.
     */
    config?: Record<string, any>;

    /**
     * A map of package names to versions that your package depends on.
     * These dependencies are bundled when publishing the package.
     */
    bundleDependencies?: Record<string, string>;

    /**
     * A map of package names to versions that your package depends on.
     * These dependencies are peer dependencies.
     */
    peerDependencies?: Record<string, string>;

    /**
     * A map of package names to versions that your package depends on.
     * These dependencies are optional peer dependencies.
     */
    peerDependenciesMeta?: Record<
        string,
        {
            optional?: boolean;
        }
    >;

    /**
     * A map of package names to versions that your package depends on.
     * These dependencies are used for overrides.
     */
    overrides?: Record<string, string | Record<string, string>>;

    /**
     * A map of package names to versions that your package depends on.
     * These dependencies are used for resolutions.
     */
    resolutions?: Record<string, string>;

    /**
     * A map of package names to versions that your package depends on.
     * These dependencies are used for workspaces.
     */
    workspaces?:
        | string[]
        | {
              packages?: string[];
              nohoist?: string[];
          };

    /**
     * The package's publish configuration.
     */
    publishConfig?: {
        access?: 'public' | 'restricted';
        registry?: string;
        tag?: string;
    };

    /**
     * The package's funding information.
     * Can be a string or an object with type and url.
     */
    funding?:
        | string
        | {
              type?: string;
              url: string;
          };

    /**
     * The package's exports field.
     * Specifies which module should be used when the package is imported.
     */
    exports?: string | Record<string, string | Record<string, string>>;

    /**
     * The package's imports field.
     * Specifies internal package imports.
     */
    imports?: Record<string, string | Record<string, string>>;

    /**
     * The package's type.
     * Can be "commonjs" or "module".
     */
    type?: 'commonjs' | 'module';

    /**
     * The package's side effects.
     * Can be a boolean or an array of strings.
     */
    sideEffects?: boolean | string[];

    /**
     * The package's private flag.
     * If true, prevents the package from being published.
     */
    private?: boolean;

    /**
     * The options available in `tochibuild.config.ts` Not all of them are available from CLI flags
     */
    tochibuild?: BuildOptions;

    /**
     * The options available in `tsup.config.ts` Not all of them are available from CLI flags
     */
    tsup?: BuildOptions;
}


// ---- shims.d.ts ----
declare module '@npmcli/arborist' {
    export interface Node {
        name: string;
        path: string;
        realpath: string;
        package: Record<string, any>;
        isLink?: boolean;
        isRoot?: boolean;
        children?: Map<string, Node>;
    }

    export default class Arborist {
        constructor(options: { path: string });
        loadActual(): Promise<Node>;
    }
}

declare module 'npm-packlist' {
    export default function packlist(tree: {
        name: string;
        path: string;
        realpath: string;
        package: Record<string, any>;
        isLink?: boolean;
        isRoot?: boolean;
        children?: Map<string, any>;
    }): Promise<string[]>;
}


// ---- tarball.d.ts ----
/**
 * Options for creating a publishable tarball from a package.
 */
interface PublishCreateOptions {
    /**
     * Path to the original package directory (relative/absolute).
     */
    packageDir: string;

    /**
     * Custom `package.json` content to include in the tarball.
     * 
     * If undefined then the original `package.json` will be used.
     */
    packageJsonData: PackageJsonOptions | undefined;

    /**
     * Output path for the generated `.tgz` tarball (relative/absolute).
     * 
     * @default 'tochibuild.package.tgz'
     */
    outputTarballPath?: string;
}

/**
 * Result returned after successfully creating the tarball.
 */
interface PublishCreateResult {
    /**
     * The name of the package (from the custom `package.json`).
     */
    name: string;

    /**
     * Relative path (from `process.cwd()`) to the generated tarball.
     */
    tarballRelativePath: string;

    /**
     * Absolute path to the generated tarball.
     */
    tarballPath: string;

    /**
     * List of files included in the tarball (based on npm-packlist).
     */
    fileList: string[];
}


// ---- types.d.ts ----
/// <reference types="tsup" />

type TsupOptions = import('tsup').Options;

/**
 * The options available in tochibuild.config.ts
 *
 * Not all of them are available from CLI flags
 */
interface BuildOptions extends TsupOptions {}

/**
 * The options available in tochibuild.config.ts including { `tochibuildConfig`: {@link TochibuildConfig} }
 *
 * Not all of them are available from CLI flags
 */
type BuildOptionsWithConfig<
    TPackageManager extends
        | keyof BuildLifecycleRegistry
        | (string & {}) = keyof BuildLifecycleRegistry,
> = BuildOptions & {
    tochibuildConfig?: TochibuildConfig<TPackageManager>;
};

type MaybePromise<T> = T | Promise<T>;
type MaybeArray<T> = T | T[];

type ConditionalType<IfType, ExtendsThisType, ThenA, ElseB> = IfType extends ExtendsThisType
    ? ThenA
    : ElseB;

type BuildOptionsParam<RequiredKeys extends keyof BuildOptions = any> = MaybeArray<
    WithRequired<BuildOptions, RequiredKeys>
>;

/**
 * Override the config file options with the options derived from CLI flags
 * @param cliOptions the options derived from CLI flags
 */
type BuildOptionsOverrideParam<RequiredKeys extends keyof BuildOptions = any> = (
    cliOptions: BuildOptions
) => MaybePromise<BuildOptionsParam<RequiredKeys>>;

type BuildOptionsParams<RequiredKeys extends keyof BuildOptions = any> =
    | BuildOptionsParam<RequiredKeys>
    | BuildOptionsOverrideParam<RequiredKeys>;

type BuildOptionsResultValue<RequiredKeys extends keyof BuildOptionsWithConfig = any> = MaybeArray<
    WithRequired<BuildOptionsWithConfig, RequiredKeys>
>;

/**
 * Override the config file options with the options derived from CLI flags
 * @param cliOptions the options derived from CLI flags
 */
type BuildOptionsResultOverrideValue<RequiredKeys extends keyof BuildOptionsWithConfig = any> = (
    cliOptions: BuildOptionsWithConfig
) => MaybePromise<BuildOptionsResultValue<RequiredKeys>>;

type BuildOptionsResult<RequiredKeys extends keyof BuildOptionsWithConfig = any> =
    | BuildOptionsResultValue<RequiredKeys>
    | BuildOptionsResultOverrideValue<RequiredKeys>;

type TochibuildConfig<
    TPackageManager extends
        | keyof BuildLifecycleRegistry
        | (string & {}) = keyof BuildLifecycleRegistry,
> = {
    /**
     * @default false
     */
    includePackageJsonDeps?: boolean;

    /**
     * @default false
     */
    includePackageJsonDevDeps?: boolean;

    /**
     * @default false
     */
    includePackageJsonPeerDeps?: boolean;
    defaultBuildOptions?: BuildOptions;

    /**
     * @default false
     */
    excludeIgnoredEntries?: boolean;

    /**
     * Customize what happens before and after the build process using {@link BuildLifecycleOptions} (eg. publishing, deprecating, custom hooks, etc.)
     */
    lifecycle?: BuildLifecycleOptions<TPackageManager>;
};

type MergeConfigOverride = {
    /**
     * The parameter (`opts:` {@link BuildOptionsResult}) from {@link mergeOptions} may be a function and therefore you should:
     *
     * - set `execute` to `true` if `opts` was dynamically imported from a module (config file) and should be resolved to get the final options.
     * - set `execute` to `false` if `opts` is not supposed to be resolved yet.
     */
    execute: true;

    /**
     * Override the config file options with these options
     */
    overrideOptions: BuildOptionsWithConfig;
};

type MergeConfigModify = {
    /**
     * Override the config file options with the options derived from CLI flags
     * @param cliOptions the options derived from CLI flags
     */
    overrideOptions: (cliOptions: BuildOptionsWithConfig) => BuildOptionsWithConfig;

    /**
     * Override the result of `overrideOptions` with these options
     */
    overrideOptionsCustom?: BuildOptionsWithConfig;
};

type MergeBuildOptionsConfig = MergeConfigModify;
type MergeBuildOptionsConfigAsync = MergeConfigOverride | (MergeConfigModify & { execute?: false });
