[
  {
    "path": ".devcontainer/Dockerfile",
    "content": "# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.222.0/containers/javascript-node/.devcontainer/base.Dockerfile\n\n# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 16, 14, 12, 16-bullseye, 14-bullseye, 12-bullseye, 16-buster, 14-buster, 12-buster\nARG VARIANT=\"16-bullseye\"\nFROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}\n\n# [Optional] Uncomment this section to install additional OS packages.\n# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \\\n#     && apt-get -y install --no-install-recommends <your-package-list-here>\n\n# [Optional] Uncomment if you want to install an additional version of node using nvm\n# ARG EXTRA_NODE_VERSION=10\n# RUN su node -c \"source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}\"\n\n# [Optional] Uncomment if you want to install more global node modules\nRUN su node -c \"npm install -g pnpm\"\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:\n// https://github.com/microsoft/vscode-dev-containers/tree/v0.222.0/containers/javascript-node\n{\n  \"name\": \"Node.js\",\n  \"build\": {\n    \"dockerfile\": \"Dockerfile\",\n    // Update 'VARIANT' to pick a Node version: 16, 14, 12.\n    // Append -bullseye or -buster to pin to an OS version.\n    // Use -bullseye variants on local arm64/Apple Silicon.\n    \"args\": { \"VARIANT\": \"16-bullseye\" }\n  },\n\n  // Set *default* container specific settings.json values on container create.\n  \"settings\": {},\n\n  // Add the IDs of extensions you want installed when the container is created.\n  \"extensions\": [\"dbaeumer.vscode-eslint\"],\n\n  // Use 'forwardPorts' to make a list of ports inside the container available locally.\n  // \"forwardPorts\": [],\n\n  // Use 'postCreateCommand' to run commands after the container is created.\n  \"postCreateCommand\": \"pnpm install\",\n\n  // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.\n  \"remoteUser\": \"node\"\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = false\ninsert_final_newline = false"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf"
  },
  {
    "path": ".github/renovate.json5",
    "content": "{\n  extends: ['config:recommended', 'schedule:weekly', 'group:allNonMajor'],\n  labels: ['dependencies'],\n  rangeStrategy: 'bump',\n  packageRules: [\n    {\n      matchDepTypes: ['peerDependencies'],\n      enabled: false,\n    },\n  ],\n  ignoreDeps: ['node'],\n  postUpdateOptions: ['pnpmDedupe'],\n}\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches:\n      - main\n\n  pull_request:\n    branches:\n      - main\n\njobs:\n  test:\n    strategy:\n      matrix:\n        os: [ubuntu-latest, windows-latest]\n        node-version: [18, 20, 22]\n\n    runs-on: ${{ matrix.os }}\n\n    # Steps represent a sequence of tasks that will be executed as part of the job\n    steps:\n      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it\n      - uses: actions/checkout@v4\n\n      - uses: pnpm/action-setup@v4.1.0\n        name: Install pnpm\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node-version }}\n          cache: pnpm\n\n      - name: Install deps\n        run: pnpm i\n\n      # Runs a set of commands using the runners shell\n      - name: Build and Test\n        run: pnpm test\n"
  },
  {
    "path": ".github/workflows/format.yml",
    "content": "name: Fix\n\non:\n  push:\n    branches-ignore:\n      - main\n      - dev\n\njobs:\n  format:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: pnpm/action-setup@v4.1.0\n        name: Install pnpm\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: lts/*\n          cache: pnpm\n\n      - run: pnpm i\n\n      - name: Format\n        run: pnpm run format\n\n      - name: Commit files and push\n        continue-on-error: true\n        if: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/dev' }}\n        run: |\n          git config --local user.email \"github-actions[bot]@users.noreply.github.com\"\n          git config --local user.name \"github-actions[bot]\"\n          git add --all\n          git commit -m \"chore(ci): [bot] format code\"\n          git push\n"
  },
  {
    "path": ".github/workflows/release-continuous.yml",
    "content": "name: Publish Any Commit\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - uses: pnpm/action-setup@v4.1.0\n        name: Install pnpm\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: lts/*\n          cache: pnpm\n\n      - name: Install dependencies\n        run: pnpm install\n\n      - name: Build\n        run: pnpm build\n\n      - run: pnpx pkg-pr-new publish\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    tags:\n      - 'v*'\n\njobs:\n  release:\n    uses: sxzz/workflows/.github/workflows/release.yml@v1\n    with:\n      publish: true\n    permissions:\n      contents: write\n      id-token: write\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n*.log\ndist\n.cache\nplayground\n.idea\n.DS_Store\n.eslintcache\n"
  },
  {
    "path": ".prettierignore",
    "content": "pnpm-lock.yaml\n.cache\ndist\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"singleQuote\": true,\n  \"semi\": false\n}\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\n## Making changes\n\n1. Fork the repository.\n2. Make changes.\n3. Add tests in `test/`.\n4. Run tests with `pnpm test`.\n\n## Release changes\n\n1. Merge PRs into dev branch.\n2. Merge dev branch into main branch with `git checkout main && git merge dev`\n3. Push main branch to remote with `git push`\n4. GitHub action will create a release and publish it to npm.\n\nFeel free to improve this process by creating an issue or PR.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 EGOIST\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "> [!WARNING]\n> This project is not actively maintained anymore. Please consider using [tsdown](https://github.com/rolldown/tsdown/) instead. Read more in [the migration guide](https://tsdown.dev/guide/migrate-from-tsup).\n\n# tsup\n\n[![npm version](https://badgen.net/npm/v/tsup)](https://npm.im/tsup) [![npm downloads](https://badgen.net/npm/dm/tsup)](https://npm.im/tsup)\n\nBundle your TypeScript library with no config, powered by [esbuild](https://github.com/evanw/esbuild).\n\n## 👀 What can it bundle?\n\nAnything that's supported by Node.js natively, namely `.js`, `.json`, `.mjs`. And TypeScript `.ts`, `.tsx`. [CSS support is experimental](https://tsup.egoist.dev/#css-support).\n\n## ⚙️ Install\n\nInstall it locally in your project folder:\n\n```bash\nnpm i tsup -D\n# Or Yarn\nyarn add tsup --dev\n# Or pnpm\npnpm add tsup -D\n```\n\nYou can also install it globally but it's not recommended.\n\n## 📖 Usage\n\n### Bundle files\n\n```bash\ntsup [...files]\n```\n\nFiles are written into `./dist`.\n\nYou can bundle multiple files in one go:\n\n```bash\ntsup src/index.ts src/cli.ts\n```\n\nThis will output `dist/index.js` and `dist/cli.js`.\n\n## 📚 Documentation\n\nFor complete usages, please dive into the [docs](https://tsup.egoist.dev).\n\nFor all configuration options, please see [the API docs](https://jsdocs.io/package/tsup).\n\n## 💬 Discussions\n\nHead over to the [discussions](https://github.com/egoist/tsup/discussions) to share your ideas.\n\n## Sponsors\n\n<p align=\"center\">\n  <a href=\"https://chromatic.com\" target=\"_blank\"><picture>\n  <source media=\"(prefers-color-scheme: dark)\" width=\"500\" srcset=\"https://fastly.jsdelivr.net/gh/egoist-bot/images@main/uPic/Group 2 (2).png\">\n  <img alt=\"Ship UIs faster with automated workflows for Storybook\"  width=\"500\" src=\"https://fastly.jsdelivr.net/gh/egoist-bot/images@main/uPic/Group%202%20(1).png\">\n</picture></a>\n</p>\n\n<p align=\"center\">\n<a href=\"https://github.com/sponsors/egoist\" target=\"_blank\"><img src=\"https://sponsors-images.egoist.dev/sponsors.svg\" alt=\"sponsors\"></a>\n</p>\n\n## Project Stats\n\n![Alt](https://repobeats.axiom.co/api/embed/4ef361ec8445b33c2dab451e1d23784015834c72.svg 'Repobeats analytics image')\n\n## License\n\nMIT &copy; [EGOIST](https://github.com/sponsors/egoist)\n"
  },
  {
    "path": "assets/cjs_shims.js",
    "content": "// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n  typeof document === \"undefined\" \n    ? new URL(`file:${__filename}`).href \n    : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n      ? document.currentScript.src \n      : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n"
  },
  {
    "path": "assets/esm_shims.js",
    "content": "// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n"
  },
  {
    "path": "assets/package.json",
    "content": "{\n  \"sideEffects\": false\n}\n"
  },
  {
    "path": "docs/README.md",
    "content": "```js preact\nimport { html } from 'docup'\n\nexport default () => {\n  const isPreview = location.hostname !== 'tsup.egoist.dev'\n\n  if (!isPreview) return null\n\n  return html`\n    <div class=\"message message_type__warning\">\n      This is a preview version of the docs.\n    </div>\n  `\n}\n```\n\nBundle your TypeScript library with no config, powered by [esbuild](https://github.com/evanw/esbuild).\n\n## What can it bundle?\n\nAnything that's supported by Node.js natively, namely `.js`, `.json`, `.mjs`. And TypeScript `.ts`, `.tsx`. [CSS support is experimental](#css-support).\n\n## Install\n\nInstall it locally in your project folder:\n\n```bash\nnpm i tsup -D\n# Or Yarn\nyarn add tsup --dev\n# Or pnpm\npnpm add tsup -D\n```\n\nYou can also install it globally but it's not recommended.\n\n## Usage\n\n### Bundle files\n\n```bash\ntsup [...files]\n```\n\nFiles are written into `./dist`.\n\nYou can bundle multiple files in one go:\n\n```bash\ntsup src/index.ts src/cli.ts\n```\n\nThis will output `dist/index.js` and `dist/cli.js`.\n\n### Excluding packages\n\nBy default tsup bundles all `import`-ed modules but `dependencies` and `peerDependencies` in your `package.json` are always excluded, you can also use `--external <module|pkgJson>` flag to mark other packages or other special `package.json`'s `dependencies` and `peerDependencies` as external.\n\n### Excluding all packages\n\nIf you are using **tsup** to build for **Node.js** applications/APIs, usually bundling dependencies is not needed, and it can even break things, for instance, while outputting to [ESM](https://nodejs.org/api/esm.html).\n\ntsup automatically excludes packages specified in the `dependencies` and `peerDependencies` fields in the `package.json`, but if it somehow doesn't exclude some packages, this library also has a special executable `tsup-node` that automatically skips bundling any Node.js package.\n\n```bash\ntsup-node src/index.ts\n```\n\nAll other CLI flags still apply to this command. You can still use the `noExternal` option to reinclude packages in the bundle,\nfor example packages that belong to a local monorepository.\n\n**If the regular `tsup` command doesn't work for you, please submit an issue with a link to your repo so we can make the default command better.**\n\n### Using custom configuration\n\nYou can also use `tsup` using file configurations or in a property inside your `package.json`, and you can even use `TypeScript` and have type-safety while you are using it.\n\n> INFO: Most of these options can be overwritten using the CLI options\n\nYou can use any of these files:\n\n- `tsup.config.ts`\n- `tsup.config.js`\n- `tsup.config.cjs`\n- `tsup.config.json`\n- `tsup` property in your `package.json`\n\n> INFO: In all the custom files you can export the options either as `tsup`, `default` or `module.exports =`\n\nYou can also specify a custom filename using the `--config` flag, or passing `--no-config` to disable config files.\n\n[Check out all available options](https://jsdocs.io/package/tsup).\n\n#### TypeScript / JavaScript\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  entry: ['src/index.ts'],\n  splitting: false,\n  sourcemap: true,\n  clean: true,\n})\n```\n\n#### Conditional config\n\nIf the config needs to be conditionally determined based on CLI flags, it can export a function instead:\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig((options) => {\n  return {\n    minify: !options.watch,\n  }\n})\n```\n\nThe `options` here is derived from CLI flags.\n\n#### package.json\n\n```json\n{\n  \"tsup\": {\n    \"entry\": [\"src/index.ts\"],\n    \"splitting\": false,\n    \"sourcemap\": true,\n    \"clean\": true\n  },\n  \"scripts\": {\n    \"build\": \"tsup\"\n  }\n}\n```\n\n#### JSON Schema Store\n\nDevelopers who are using [vscode](https://code.visualstudio.com/) or text editor which supports the JSON Language Server can leverage the [tsup schema store](https://cdn.jsdelivr.net/npm/tsup/schema.json) via CDN. This schema store will provide intellisense capabilities such as completions, validations and descriptions within JSON file configurations like the `tsup.config.json` and `package.json` (tsup) property.\n\nProvide the following configuration in your `.vscode/settings.json` (or global) settings file:\n\n```json\n{\n  \"json.schemas\": [\n    {\n      \"url\": \"https://cdn.jsdelivr.net/npm/tsup/schema.json\",\n      \"fileMatch\": [\"package.json\", \"tsup.config.json\"]\n    }\n  ]\n}\n```\n\n### Multiple entrypoints\n\nBeside using positional arguments `tsup [...files]` to specify multiple entrypoints, you can also use the cli flag `--entry`:\n\n```bash\n# Outputs `dist/a.js` and `dist/b.js`.\ntsup --entry src/a.ts --entry src/b.ts\n```\n\nThe associated output file names can be defined as follows:\n\n```bash\n# Outputs `dist/foo.js` and `dist/bar.js`.\ntsup --entry.foo src/a.ts --entry.bar src/b.ts\n```\n\nIt's equivalent to the following `tsup.config.ts`:\n\n```ts\nexport default defineConfig({\n  // Outputs `dist/a.js` and `dist/b.js`.\n  entry: ['src/a.ts', 'src/b.ts'],\n  // Outputs `dist/foo.js` and `dist/bar.js`\n  entry: {\n    foo: 'src/a.ts',\n    bar: 'src/b.ts',\n  },\n})\n```\n\n### Generate declaration file\n\n```bash\ntsup index.ts --dts\n```\n\nThis will emit `./dist/index.js` and `./dist/index.d.ts`. When emitting multiple [bundle formats](#bundle-formats), one declaration file per bundle format is generated. This is required for consumers to get accurate type checking with TypeScript. Note that declaration files generated by any tool other than `tsc` are not guaranteed to be error-free, so it's a good idea to test the output with `tsc` or a tool like [@arethetypeswrong/cli](https://www.npmjs.com/package/@arethetypeswrong/cli) before publishing.\n\nIf you have multiple entry files, each entry will get a corresponding `.d.ts` file. So when you only want to generate declaration file for a single entry, use `--dts <entry>` format, e.g. `--dts src/index.ts`.\n\nNote that `--dts` does not resolve external (aka in `node_modules`) types used in the `.d.ts` file, if that's somehow a requirement, try the experimental `--dts-resolve` flag instead.\n\nSince tsup version 8.0.0, you can also use `--experimental-dts` flag to generate declaration files. This flag use [@microsoft/api-extractor](https://www.npmjs.com/package/@microsoft/api-extractor) to generate declaration files, which is more reliable than the previous `--dts` flag. It's still experimental and we are looking for feedbacks.\n\nTo use `--experimental-dts`, you would need to install `@microsoft/api-extractor`, as it's a peer dependency of tsup:\n\n```bash\nnpm i @microsoft/api-extractor -D\n# Or Yarn\nyarn add @microsoft/api-extractor --dev\n```\n\n#### Emit declaration file only\n\nThe `--dts-only` flag is the equivalent of the `emitDeclarationOnly` option in `tsc`. Using this flag will only emit the declaration file, without the JavaScript files.\n\n#### Generate TypeScript declaration maps (.d.ts.map)\n\nTypeScript declaration maps are mainly used to quickly jump to type definitions in the context of a monorepo (see [source issue](https://github.com/Microsoft/TypeScript/issues/14479) and [official documentation](https://www.typescriptlang.org/tsconfig/#declarationMap)).\n\nThey should not be included in a published NPM package and should not be confused with sourcemaps.\n\n[Tsup is not able to generate those files](https://github.com/egoist/tsup/issues/564). Instead, you should use the TypeScript compiler directly, by running the following command after the build is done: `tsc --emitDeclarationOnly --declaration`.\n\nYou can combine this command with Tsup [`onSuccess`](https://tsup.egoist.dev/#onsuccess) callback.\n\n### Generate sourcemap file\n\n```bash\ntsup index.ts --sourcemap\n```\n\nThis will emit `./dist/index.js` and `./dist/index.js.map`.\n\nIf you set multiple entry files, each entry will get a corresponding `.map` file.\n\nIf you want to inline sourcemap, you can try:\n\n```bash\ntsup index.ts --sourcemap inline\n```\n\n> Warning: Note that inline sourcemap is solely used for development, e.g. when developing a browser extension and the access to `.map` file is not allowed, and it's not recommended for production.\n\n> Warning: Source map is not supported in `--dts` build.\n\n### Bundle formats\n\nSupported format: `esm`, `cjs`, (default) and `iife`.\n\nYou can bundle in multiple formats in one go:\n\n```bash\ntsup src/index.ts --format esm,cjs,iife\n```\n\nThat will output files in following folder structure:\n\n```bash\ndist\n├── index.mjs         # esm\n├── index.global.js   # iife\n└── index.js          # cjs\n```\n\nIf the `type` field in your `package.json` is set to `module`, the filenames will be slightly different:\n\n```bash\ndist\n├── index.js          # esm\n├── index.global.js   # iife\n└── index.cjs         # cjs\n```\n\nRead more about [`esm` support in Node.js](https://nodejs.org/api/esm.html#esm_enabling).\n\nIf you don't want extensions like `.mjs` or `.cjs`, e.g. you want your library to be used in a bundler (or environment) that doesn't support those, you can enable `--legacy-output` flag:\n\n```bash\ntsup src/index.ts --format esm,cjs,iife --legacy-output\n```\n\n..which outputs to:\n\n```bash\ndist\n├── esm\n│   └── index.js\n├── iife\n│   └── index.js\n└── index.js\n```\n\n### Output extension\n\nYou can also change the output extension of the files by using `outExtension` option:\n\n```ts\nexport default defineConfig({\n  outExtension({ format }) {\n    return {\n      js: `.${format}.js`,\n    }\n  },\n})\n```\n\nThis will generate your files to `[name].[format].js`.\n\nThe signature of `outExtension` is:\n\n```ts\ntype OutExtension = (ctx: Context) => Result\n\ntype Context = {\n  options: NormalizedOptions\n  format: Format\n  /** \"type\" field in project's package.json */\n  pkgType?: string\n}\n\ntype Result = { js?: string }\n```\n\n### Code Splitting\n\nCode splitting currently only works with the `esm` output format, and it's enabled by default. If you want code splitting for `cjs` output format as well, try using `--splitting` flag which is an experimental feature to get rid of [the limitation in esbuild](https://esbuild.github.io/api/#splitting).\n\nTo disable code splitting altogether, try the `--no-splitting` flag instead.\n\n### Target environment\n\nYou can use the `target` option in `tsup.config.ts` or the `--target` flag to set the target environment for the generated JavaScript and/or CSS code. Each target environment is an environment name followed by a version number. The following environment names are currently supported:\n\n- chrome\n- edge\n- firefox\n- hermes\n- ie\n- ios\n- node\n- opera\n- rhino\n- safari\n\nIn addition, you can also specify JavaScript language versions such as `es2020`.\n\nThe value for `target` defaults to `compilerOptions.target` in your `tsconfig.json`, or `node14` if unspecified. For more information check out esbuild's [target](https://esbuild.github.io/api/#target) option.\n\n#### ES5 support\n\nYou can use `--target es5` to compile the code down to es5, in this target your code will be transpiled by esbuild to es2020 first, and then transpiled to es5 by [SWC](https://swc.rs).\n\n### Compile-time environment variables\n\nYou can use `--env` flag to define compile-time environment variables:\n\n```bash\ntsup src/index.ts --env.NODE_ENV production\n```\n\nNote that `--env.VAR_NAME` only recognizes `process.env.VAR_NAME` and `import.meta.env.VAR_NAME`. If you use `process.env`, it will only take effect when it is used as a built-in global variable. Therefore, do not import `process` from `node:process`.\n\n### Building CLI app\n\nWhen an entry file like `src/cli.ts` contains hashbang like `#!/bin/env node` tsup will automatically make the output file executable, so you don't have to run `chmod +x dist/cli.js`.\n\n### Interop with CommonJS\n\nBy default, esbuild will transform `export default x` to `module.exports.default = x` in CommonJS, but you can change this behavior by using the `--cjsInterop` flag: If there are only default exports and no named exports, it will be transformed to `module.exports = x` instead.\n\n```bash\ntsup src/index.ts --cjsInterop\n```\n\n### Watch mode\n\n```bash\ntsup src/index.ts --watch\n```\n\nTurn on watch mode. This means that after the initial build, tsup will continue to watch for changes in any of the resolved files.\n\n> INFO: By default it always ignores `dist`, `node_modules` & `.git`\n\n```bash\ntsup src/index.ts --watch --ignore-watch ignore-this-folder-too\n```\n\n> INFO: You can specify more than a folder repeating \"--ignore-watch\", for example: `tsup src src/index.ts --watch --ignore-watch folder1 --ignore-watch folder2`\n\n### onSuccess\n\nYou can specify command to be executed after a successful build, specially useful for **Watch mode**\n\n```bash\ntsup src/index.ts --watch --onSuccess \"node dist/index.js\"\n```\n\n`onSuccess` can also be a `function` that returns `Promise`. For this to work, you need to use `tsup.config.ts` instead of the cli flag:\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  async onSuccess() {\n    // Start some long running task\n    // Like a server\n  },\n})\n```\n\nYou can return a cleanup function in `onSuccess`:\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  onSuccess() {\n    const server = http.createServer((req, res) => {\n      res.end('Hello World!')\n    })\n    server.listen(3000)\n    return () => {\n      server.close()\n    }\n  },\n})\n```\n\n### Minify output\n\nYou can also minify the output, resulting into lower bundle sizes by using the `--minify` flag.\n\n```bash\ntsup src/index.ts --minify\n```\n\nTo use [Terser](https://github.com/terser/terser) instead of esbuild for minification, pass terser as argument value\n\n```bash\ntsup src/index.ts --minify terser\n```\n\n> NOTE: You must have terser installed. Install it with `npm install -D terser`\n\nIn `tsup.config.js`, you can pass `terserOptions` which will be passed to `terser.minify` as it is.\n\n### Custom loader\n\nEsbuild loader list:\n\n```ts\ntype Loader =\n  | 'js'\n  | 'jsx'\n  | 'ts'\n  | 'tsx'\n  | 'css'\n  | 'json'\n  | 'text'\n  | 'base64'\n  | 'file'\n  | 'dataurl'\n  | 'binary'\n  | 'copy'\n  | 'default'\n```\n\nTo use a custom loader via CLI flag:\n\n```bash\ntsup --loader \".jpg=base64\" --loader \".webp=file\"\n```\n\nOr via `tsup.config.ts`:\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  loader: {\n    '.jpg': 'base64',\n    '.webp': 'file',\n  },\n})\n```\n\n### Tree shaking\n\nesbuild has [tree shaking](https://esbuild.github.io/api/#tree-shaking) enabled by default, but sometimes it's not working very well, see [#1794](https://github.com/evanw/esbuild/issues/1794) [#1435](https://github.com/evanw/esbuild/issues/1435), so tsup offers an additional option to let you use Rollup for tree shaking instead:\n\n```bash\ntsup src/index.ts --treeshake\n```\n\nThis flag above will enable Rollup for tree shaking, and it's equivalent to the following `tsup.config.ts`:\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  treeshake: true,\n})\n```\n\nThis option has the same type as the `treeshake` option in Rollup, [see more](https://rollupjs.org/guide/en/#treeshake).\n\n### What about type checking?\n\nesbuild is fast because it doesn't perform any type checking, you already get type checking from your IDE like VS Code or WebStorm.\n\nAdditionally, if you want type checking at build time, you can enable `--dts`, which will run a real TypeScript compiler to generate declaration file so you get type checking as well.\n\n### CSS support\n\nesbuild has [experimental CSS support](https://esbuild.github.io/content-types/#css), and tsup allows you to use PostCSS plugins on top of native CSS support.\n\nTo use PostCSS, you need to install PostCSS:\n\n```bash\nnpm i postcss -D\n# Or Yarn\nyarn add postcss --dev\n```\n\n..and populate a `postcss.config.js` in your project\n\n```js\nmodule.exports = {\n  plugins: [require('tailwindcss')(), require('autoprefixer')()],\n}\n```\n\n### Metafile\n\nPassing `--metafile` flag to tell esbuild to produce some metadata about the build in JSON format. You can feed the output file to analysis tools like [bundle buddy](https://www.bundle-buddy.com/esbuild) to visualize the modules in your bundle and how much space each one takes up.\n\nThe file outputs as `metafile-{format}.json`, e.g. `tsup --format cjs,esm` will generate `metafile-cjs.json` and `metafile-esm.json`.\n\n### Custom esbuild plugin and options\n\nUse `esbuildPlugins` and `esbuildOptions` respectively in `tsup.config.ts`:\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  esbuildPlugins: [YourPlugin],\n  esbuildOptions(options, context) {\n    options.define.foo = '\"bar\"'\n  },\n})\n```\n\nThe `context` argument for `esbuildOptions`:\n\n- `context.format`: `cjs`, `esm`, `iife`\n\nSee all options [here](https://esbuild.github.io/api/#build-api), and [how to write an esbuild plugin](https://esbuild.github.io/plugins/#using-plugins).\n\n---\n\nFor more details:\n\n```bash\ntsup --help\n```\n\n### Inject cjs and esm shims\n\nEnabling this option will fill in some code when building esm/cjs to make it work, such as `__dirname` which is only available in the cjs module and `import.meta.url` which is only available in the esm module\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  shims: true,\n})\n```\n\n- When building the cjs bundle, it will compile `import.meta.url` as `typeof document === \"undefined\" ? new URL(\"file:\" + __filename).href : document.currentScript && document.currentScript.src || new URL(\"main.js\", document.baseURI).href`\n- When building the esm bundle, it will compile `__dirname` as `path.dirname(fileURLToPath(import.meta.url))`\n\n### Copy files to output directory\n\nUse `--publicDir` flag to copy files inside `./public` folder to the output directory.\n\nYou can also specify a custom directory using `--publicDir another-directory`.\n\n### JavaScript API\n\nIf you want to use `tsup` in your Node.js program, you can use the JavaScript API:\n\n```js\nimport { build } from 'tsup'\n\nawait build({\n  entry: ['src/index.ts'],\n  sourcemap: true,\n  dts: true,\n})\n```\n\nFor all available options for the `build` function, please see [the API docs](https://jsdocs.io/package/tsup).\n\n### Using custom tsconfig.json\n\nYou can also use custom tsconfig.json file configurations by using the `--tsconfig` flag:\n\n```bash\ntsup --tsconfig tsconfig.prod.json\n```\n\nBy default, tsup try to find the `tsconfig.json` file in the current directory, if it's not found, it will use the default tsup config.\n\n### Using custom Swc configuration\n\nWhen you use legacy TypeScript decorator by enabling `emitDecoratorMetadata` in your tsconfig, tsup will automatically use [SWC](https://swc.rs) to transpile\ndecorators. In this case, you can give extra swc configuration in the `tsup.config.ts` file.\n\nFor example, if you have to define `useDefineForClassFields`, you can do that as follows:\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  entry: ['src/index.ts'],\n  splitting: false,\n  sourcemap: true,\n  clean: true,\n  swc: {\n    jsc: {\n      transform: {\n        useDefineForClassFields: true\n      }\n    }\n  }\n})\n```\n\nNote: some SWC options cannot be configured:\n\n```json\n{\n  \"parser\": {\n    \"syntax\": \"typescript\",\n    \"decorators\": true\n  },\n  \"transform\": {\n    \"legacyDecorator\": true,\n    \"decoratorMetadata\": true\n  },\n  \"keepClassNames\": true,\n  \"target\": \"es2022\"\n}\n ```\n\nYou can also define a custom `.swcrc` configuration file. Just set `swcrc` to `true` \nin `tsup.config.ts` to allow SWC plugin to discover automatically your custom swc config file.\n\n```ts\nimport { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  entry: ['src/index.ts'],\n  splitting: false,\n  sourcemap: true,\n  clean: true,\n  swc: {\n    swcrc: true\n  }\n})\n```\n\n## Troubleshooting\n\n### error: No matching export in \"xxx.ts\" for import \"xxx\"\n\nThis usually happens when you have `emitDecoratorMetadata` enabled in your tsconfig.json, in this mode we use [SWC](https://swc.rs) to transpile decorators to JavaScript so exported types will be eliminated, that's why esbuild won't be able to find corresponding exports. You can fix this by changing your import statement from `import { SomeType }` to `import { type SomeType }` or `import type { SomeType }`.\n\n## License\n\nMIT &copy; [EGOIST](https://github.com/sponsors/egoist)\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n    />\n    <title>tsup</title>\n    <meta name=\"description\" content=\"bundle typescript library with ease\" />\n    <meta property=\"og:title\" content=\"tsup\" />\n    <meta\n      property=\"og:description\"\n      content=\"bundle typescript library with ease\"\n    />\n    <meta name=\"twitter:card\" content=\"summary\" />\n    <!-- Stylesheet -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdn.jsdelivr.net/npm/@egoist/docup@2/dist/docup.min.css\"\n    />\n    <style>\n      .logo-dark {\n        display: none;\n      }\n      @media (prefers-color-scheme: dark) {\n        .logo {\n          display: none;\n        }\n        .logo-dark {\n          display: block;\n        }\n      }\n    </style>\n  </head>\n  <body>\n    <script type=\"module\">\n      import * as docup from 'https://cdn.jsdelivr.net/npm/@egoist/docup@2/dist/docup.min.js'\n      docup.init({\n        // ..options\n        navLinks: [\n          { text: `Type Doc`, link: `https://jsdocs.io/package/tsup` },\n          {\n            text: `GitHub`,\n            link: `https://github.com/egoist/tsup`,\n          },\n          {\n            text: `❤️️ Sponsor`,\n            link: `https://github.com/sponsors/egoist`,\n          },\n        ],\n        beforeSidebar: `<div style=\"padding: 20px;\">\n        <div style=\"margin-bottom:10px\">\n          <strong style=\"font-size: 0.8rem;color:#ccc;\">SPONSOR</strong>\n        </div>\n        <a href=\"https://chromatic.com\" rel=\"nofollow noopener\" target=\"_blank\"\n          ><img \n            title=\"Ship UIs faster with automated workflows for Storybook\" \n            alt=\"chromatic logo\" \n            class=\"logo\"\n            src=\"https://fastly.jsdelivr.net/gh/egoist-bot/images@main/uPic/Group 2 (1).png\"\n        /><img \n            title=\"Ship UIs faster with automated workflows for Storybook\" \n            alt=\"chromatic logo\" \n            class=\"logo logo-dark\"\n            src=\"https://fastly.jsdelivr.net/gh/egoist-bot/images@main/uPic/Group 2 (2).png\"\n        /></a>\n      </div>`,\n      })\n    </script>\n    <script\n      async\n      defer\n      data-website-id=\"24610d03-48c4-4ad3-8557-4d424349d2ba\"\n      src=\"https://umami.egoist.dev/mami.js\"\n    ></script>\n  </body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"tsup\",\n  \"version\": \"8.5.1\",\n  \"packageManager\": \"pnpm@10.22.0\",\n  \"description\": \"Bundle your TypeScript library with no config, powered by esbuild\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://tsup.egoist.dev/\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/egoist/tsup.git\"\n  },\n  \"author\": \"EGOIST\",\n  \"files\": [\n    \"/assets\",\n    \"/dist\",\n    \"/schema.json\"\n  ],\n  \"main\": \"dist/index.js\",\n  \"types\": \"dist/index.d.ts\",\n  \"bin\": {\n    \"tsup\": \"dist/cli-default.js\",\n    \"tsup-node\": \"dist/cli-node.js\"\n  },\n  \"scripts\": {\n    \"dev\": \"pnpm run build-fast --watch\",\n    \"build\": \"tsup src/cli-*.ts src/index.ts src/rollup.ts --clean --splitting\",\n    \"prepublishOnly\": \"pnpm run build\",\n    \"test\": \"pnpm run build && pnpm run test-only\",\n    \"format\": \"prettier --write .\",\n    \"test-only\": \"vitest run\",\n    \"build-fast\": \"pnpm run build --no-dts\",\n    \"release\": \"bumpp\"\n  },\n  \"peerDependencies\": {\n    \"@microsoft/api-extractor\": \"^7.36.0\",\n    \"@swc/core\": \"^1\",\n    \"postcss\": \"^8.4.12\",\n    \"typescript\": \">=4.5.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@microsoft/api-extractor\": {\n      \"optional\": true\n    },\n    \"@swc/core\": {\n      \"optional\": true\n    },\n    \"postcss\": {\n      \"optional\": true\n    },\n    \"typescript\": {\n      \"optional\": true\n    }\n  },\n  \"dependencies\": {\n    \"bundle-require\": \"^5.1.0\",\n    \"cac\": \"^6.7.14\",\n    \"chokidar\": \"^4.0.3\",\n    \"consola\": \"^3.4.0\",\n    \"debug\": \"^4.4.0\",\n    \"esbuild\": \"^0.27.0\",\n    \"fix-dts-default-cjs-exports\": \"^1.0.0\",\n    \"joycon\": \"^3.1.1\",\n    \"picocolors\": \"^1.1.1\",\n    \"postcss-load-config\": \"^6.0.1\",\n    \"resolve-from\": \"^5.0.0\",\n    \"rollup\": \"^4.34.8\",\n    \"source-map\": \"^0.7.6\",\n    \"sucrase\": \"^3.35.0\",\n    \"tinyexec\": \"^0.3.2\",\n    \"tinyglobby\": \"^0.2.11\",\n    \"tree-kill\": \"^1.2.2\"\n  },\n  \"devDependencies\": {\n    \"@microsoft/api-extractor\": \"^7.50.0\",\n    \"@rollup/plugin-json\": \"6.1.0\",\n    \"@swc/core\": \"1.10.18\",\n    \"@types/debug\": \"4.1.12\",\n    \"@types/node\": \"22.13.4\",\n    \"@types/resolve\": \"1.20.6\",\n    \"bumpp\": \"^10.0.3\",\n    \"flat\": \"6.0.1\",\n    \"postcss\": \"8.5.2\",\n    \"postcss-simple-vars\": \"7.0.1\",\n    \"prettier\": \"3.5.1\",\n    \"resolve\": \"1.22.10\",\n    \"rollup-plugin-dts\": \"6.1.1\",\n    \"sass\": \"1.85.0\",\n    \"strip-json-comments\": \"5.0.1\",\n    \"svelte\": \"5.19.9\",\n    \"svelte-preprocess\": \"6.0.3\",\n    \"terser\": \"^5.39.0\",\n    \"ts-essentials\": \"10.0.4\",\n    \"tsup\": \"8.3.6\",\n    \"typescript\": \"5.7.3\",\n    \"vitest\": \"3.0.6\",\n    \"wait-for-expect\": \"3.0.2\"\n  },\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"pnpm\": {\n    \"onlyBuiltDependencies\": [\n      \"@parcel/watcher\",\n      \"@swc/core\",\n      \"esbuild\",\n      \"svelte-preprocess\"\n    ]\n  }\n}\n"
  },
  {
    "path": "schema.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema\",\n  \"$id\": \"tsup\",\n  \"version\": 1.1,\n  \"anyOf\": [\n    {\n      \"type\": \"object\",\n      \"required\": [\"tsup\"],\n      \"additionalProperties\": true,\n      \"properties\": {\n        \"tsup\": {\n          \"type\": [\"object\", \"array\"],\n          \"oneOf\": [\n            {\n              \"type\": \"object\",\n              \"additionalProperties\": false,\n              \"$ref\": \"#/definitions/options\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"additionalProperties\": false,\n                \"$ref\": \"#/definitions/options\"\n              }\n            }\n          ]\n        }\n      }\n    },\n    {\n      \"type\": [\"object\", \"array\"],\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"$ref\": \"#/definitions/options\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/options\"\n          }\n        }\n      ]\n    }\n  ],\n  \"definitions\": {\n    \"options\": {\n      \"type\": \"object\",\n      \"markdownDescription\": \"Configuration options for [tsup](https://tsup.egoist.dev)\",\n      \"properties\": {\n        \"entry\": {\n          \"markdownDescription\": \"Files that each serve as an input to the bundling algorithm.\\n\\n---\\nReferences:\\n- [Entry Points](https://esbuild.github.io/api/#entry-points) - esbuild\\n - [Multiple Entrypoints](https://tsup.egoist.dev/#multiple-entrypoints) - tsup\",\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"object\"\n            }\n          ]\n        },\n        \"treeshake\": {\n          \"markdownDescription\": \"By default esbuild already does treeshaking but this option allow you to perform additional treeshaking with Rollup and result in smaller bundle size.\",\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"string\",\n              \"enum\": [\"smallest\", \"safest\", \"recommended\"]\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"Optional config name to show in CLI output\"\n        },\n        \"legacyOutput\": {\n          \"type\": \"boolean\",\n          \"description\": \"Output different formats to different folder instead of using different extension\"\n        },\n        \"target\": {\n          \"markdownDescription\": \"This sets the target environment for the generated code\\n\\n---\\nReferences:\\n- [Target](https://esbuild.github.io/api/#target) - esbuild\",\n          \"default\": \"node14\",\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          ]\n        },\n        \"minify\": {\n          \"description\": \"When enabled, the generated code will be minified instead of pretty-printed.\",\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"string\",\n              \"enum\": [\"terser\"]\n            }\n          ]\n        },\n        \"minifyWhitespace\": {\n          \"type\": \"boolean\"\n        },\n        \"minifyIdentifiers\": {\n          \"type\": \"boolean\"\n        },\n        \"minifySyntax\": {\n          \"type\": \"boolean\"\n        },\n        \"keepNames\": {\n          \"type\": \"boolean\"\n        },\n        \"watch\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"string\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": [\"string\", \"boolean\"]\n              }\n            }\n          ]\n        },\n        \"ignoreWatch\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          ]\n        },\n        \"onSuccess\": {\n          \"type\": \"string\"\n        },\n        \"jsxFactory\": {\n          \"type\": \"string\"\n        },\n        \"jsxFragment\": {\n          \"type\": \"string\"\n        },\n        \"outDir\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"oneOf\": [\n            {\n              \"enum\": [\"cjs\", \"iife\", \"esm\"],\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\",\n                \"enum\": [\"cjs\", \"iife\", \"esm\"]\n              }\n            }\n          ]\n        },\n        \"swc\": {\n          \"type\": \"object\"\n        },\n        \"globalName\": {\n          \"type\": \"string\"\n        },\n        \"env\": {\n          \"type\": \"object\"\n        },\n        \"define\": {\n          \"type\": \"object\"\n        },\n        \"dts\": {\n          \"markdownDescription\": \"This will emit `./dist/index.js` and `./dist/index.d.ts`.\\n\\nIf you have multiple entry files, each entry will get a corresponding `.d.ts` file. So when you only want to generate declaration file for a single entry, use `--dts <entry>` format, e.g. `--dts src/index.ts`.\\n\\n**Note** that `--dts` does not resolve external (aka in node_modules) types used in the `.d.ts file`, if that's somehow a requirement, try the experimental `--dts-resolve` flag instead.\",\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"object\",\n              \"properties\": {\n                \"entry\": {\n                  \"oneOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"object\"\n                    },\n                    {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  ]\n                }\n              }\n            }\n          ]\n        },\n        \"sourcemap\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"enum\": [\"inline\"]\n            }\n          ]\n        },\n        \"noExternal\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"description\": \"Always bundle modules matching given patterns\"\n        },\n        \"external\": {\n          \"description\": \"Don't bundle these modules\",\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"replaceNodeEnv\": {\n          \"type\": \"boolean\",\n          \"markdownDescription\": \"Replace `process.env.NODE_ENV` with `production` or `development` `production` when the bundled is minified, `development` otherwise\"\n        },\n        \"splitting\": {\n          \"type\": \"boolean\",\n          \"default\": true,\n          \"markdownDescription\": \"You may want to disable code splitting sometimes: [`#255`](https://github.com/egoist/tsup/issues/255)\"\n        },\n        \"clean\": {\n          \"description\": \"Clean output directory before each buil\",\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          ]\n        },\n        \"silent\": {\n          \"type\": \"boolean\",\n          \"description\": \"Suppress non-error logs (excluding \\\"onSuccess\\\" process output)\"\n        },\n        \"skipNodeModulesBundle\": {\n          \"type\": \"boolean\",\n          \"description\": \"Skip node_modules bundling\"\n        },\n        \"pure\": {\n          \"markdownDescription\": \"See:\\n- [Pure](https://esbuild.github.io/api/#pure) - esbuild\",\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          ]\n        },\n        \"bundle\": {\n          \"default\": true,\n          \"type\": \"boolean\",\n          \"description\": \"Disable bundling, default to true\"\n        },\n        \"inject\": {\n          \"markdownDescription\": \"This option allows you to automatically replace a global variable with an import from another file.\\n\\n---\\nSee:\\n- [Inject](https://esbuild.github.io/api/#inject) - esbuild\",\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"metafile\": {\n          \"type\": \"boolean\",\n          \"markdownDescription\": \"Emit esbuild metafile.\\n\\n---\\nSee:\\n- [Metafile](https://esbuild.github.io/api/#metafile) - esbuild\"\n        },\n        \"footer\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"js\": {\n              \"type\": \"string\"\n            },\n            \"css\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"banner\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"js\": {\n              \"type\": \"string\"\n            },\n            \"css\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"platform\": {\n          \"description\": \"Target platform\",\n          \"type\": \"string\",\n          \"default\": \"node\",\n          \"enum\": [\"node\", \"browser\", \"neutral\"]\n        },\n        \"config\": {\n          \"markdownDescription\": \"Disable config file with `false` or pass a custom config filename\",\n          \"type\": [\"boolean\", \"string\"]\n        },\n        \"tsconfig\": {\n          \"type\": \"string\",\n          \"description\": \" Use a custom tsconfig\"\n        },\n        \"injectStyle\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"Inject CSS as style tags to document head\"\n        },\n        \"shims\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"Inject cjs and esm shims if needed\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/api-extractor.ts",
    "content": "import path from 'node:path'\nimport { handleError } from './errors'\nimport {\n  type ExportDeclaration,\n  formatAggregationExports,\n  formatDistributionExports,\n} from './exports'\nimport { loadPkg } from './load'\nimport { createLogger } from './log'\nimport {\n  defaultOutExtension,\n  ensureTempDeclarationDir,\n  getApiExtractor,\n  removeFiles,\n  toAbsolutePath,\n  writeFileSync,\n} from './utils'\nimport type { Format, NormalizedOptions } from './options'\nimport type {\n  ExtractorResult,\n  IConfigFile,\n  IExtractorConfigPrepareOptions,\n} from '@microsoft/api-extractor'\n\nconst logger = createLogger()\n\nfunction rollupDtsFile(\n  inputFilePath: string,\n  outputFilePath: string,\n  tsconfigFilePath: string,\n) {\n  const cwd = process.cwd()\n  const packageJsonFullPath = path.join(cwd, 'package.json')\n  const configObject: IConfigFile = {\n    mainEntryPointFilePath: inputFilePath,\n    apiReport: {\n      enabled: false,\n\n      // `reportFileName` is not been used. It's just to fit the requirement of API Extractor.\n      reportFileName: 'tsup-report.api.md',\n    },\n    docModel: { enabled: false },\n    dtsRollup: {\n      enabled: true,\n      untrimmedFilePath: outputFilePath,\n    },\n    tsdocMetadata: { enabled: false },\n    compiler: {\n      tsconfigFilePath,\n    },\n    projectFolder: cwd,\n    newlineKind: 'lf',\n  }\n  const prepareOptions: IExtractorConfigPrepareOptions = {\n    configObject,\n    configObjectFullPath: undefined,\n    packageJsonFullPath,\n  }\n\n  const imported = getApiExtractor()\n  if (!imported) {\n    throw new Error(\n      `@microsoft/api-extractor is not installed. Please install it first.`,\n    )\n  }\n  const { ExtractorConfig, Extractor } = imported\n\n  const extractorConfig = ExtractorConfig.prepare(prepareOptions)\n\n  // Invoke API Extractor\n  const extractorResult: ExtractorResult = Extractor.invoke(extractorConfig, {\n    // Equivalent to the \"--local\" command-line parameter\n    localBuild: true,\n\n    // Equivalent to the \"--verbose\" command-line parameter\n    showVerboseMessages: true,\n  })\n\n  if (!extractorResult.succeeded) {\n    throw new Error(\n      `API Extractor completed with ${extractorResult.errorCount} errors and ${extractorResult.warningCount} warnings when processing ${inputFilePath}`,\n    )\n  }\n}\n\nasync function rollupDtsFiles(\n  options: NormalizedOptions,\n  exports: ExportDeclaration[],\n  format: Format,\n) {\n  if (!options.experimentalDts || !options.experimentalDts?.entry) {\n    return\n  }\n\n  /**\n   * `.tsup/declaration` directory\n   */\n  const declarationDir = ensureTempDeclarationDir()\n  const outDir = options.outDir || 'dist'\n  const pkg = await loadPkg(process.cwd())\n  const dtsExtension = defaultOutExtension({ format, pkgType: pkg.type }).dts\n  const tsconfig = options.tsconfig || 'tsconfig.json'\n\n  let dtsInputFilePath = path.join(\n    declarationDir,\n    `_tsup-dts-aggregation${dtsExtension}`,\n  )\n  // @microsoft/api-extractor doesn't support `.d.mts` and `.d.cts` file as a\n  // entrypoint yet. So we replace the extension here as a temporary workaround.\n  //\n  // See the issue for more details:\n  // https://github.com/microsoft/rushstack/pull/4196\n  dtsInputFilePath = dtsInputFilePath\n    .replace(/\\.d\\.mts$/, '.dmts.d.ts')\n    .replace(/\\.d\\.cts$/, '.dcts.d.ts')\n\n  const dtsOutputFilePath = path.join(outDir, `_tsup-dts-rollup${dtsExtension}`)\n\n  writeFileSync(\n    dtsInputFilePath,\n    formatAggregationExports(exports, declarationDir),\n  )\n\n  rollupDtsFile(dtsInputFilePath, dtsOutputFilePath, tsconfig)\n\n  for (let [out, sourceFileName] of Object.entries(\n    options.experimentalDts.entry,\n  )) {\n    /**\n     * Source file name (`src/index.ts`)\n     *\n     * @example\n     *\n     * ```ts\n     * import { defineConfig } from 'tsup'\n     *\n     * export default defineConfig({\n     *   entry: { index: 'src/index.ts' },\n     *   // Here `src/index.ts` is our `sourceFileName`.\n     * })\n     * ```\n     */\n    sourceFileName = toAbsolutePath(sourceFileName)\n    /**\n     * Output file name (`dist/index.d.ts`)\n     *\n     * @example\n     *\n     * ```ts\n     * import { defineConfig } from 'tsup'\n     *\n     * export default defineConfig({\n     *  entry: { index: 'src/index.ts' },\n     * // Here `dist/index.d.ts` is our `outFileName`.\n     * })\n     * ```\n     */\n    const outFileName = path.join(outDir, out + dtsExtension)\n\n    // Find all declarations that are exported from the current source file\n    const currentExports = exports.filter(\n      (declaration) => declaration.sourceFileName === sourceFileName,\n    )\n\n    writeFileSync(\n      outFileName,\n      formatDistributionExports(currentExports, outFileName, dtsOutputFilePath),\n    )\n  }\n}\n\nasync function cleanDtsFiles(options: NormalizedOptions) {\n  if (options.clean) {\n    await removeFiles(['**/*.d.{ts,mts,cts}'], options.outDir)\n  }\n}\n\nexport async function runDtsRollup(\n  options: NormalizedOptions,\n  exports?: ExportDeclaration[],\n) {\n  try {\n    const start = Date.now()\n    const getDuration = () => {\n      return `${Math.floor(Date.now() - start)}ms`\n    }\n    logger.info('dts', 'Build start')\n\n    if (!exports) {\n      throw new Error('Unexpected internal error: dts exports is not define')\n    }\n    await cleanDtsFiles(options)\n    for (const format of options.format) {\n      await rollupDtsFiles(options, exports, format)\n    }\n    logger.success('dts', `⚡️ Build success in ${getDuration()}`)\n  } catch (error) {\n    handleError(error)\n    logger.error('dts', 'Build error')\n  }\n}\n"
  },
  {
    "path": "src/cli-default.ts",
    "content": "#!/usr/bin/env node\nimport { handleError } from './errors'\nimport { main } from './cli-main'\n\nmain().catch(handleError)\n"
  },
  {
    "path": "src/cli-main.ts",
    "content": "import { cac } from 'cac'\nimport { flatten } from 'flat'\nimport { version } from '../package.json'\nimport { slash } from './utils'\nimport type { Format, Options } from '.'\n\nfunction ensureArray(input: string): string[] {\n  return Array.isArray(input) ? input : input.split(',')\n}\n\nexport async function main(options: Options = {}) {\n  const cli = cac('tsup')\n\n  cli\n    .command('[...files]', 'Bundle files', {\n      ignoreOptionDefaultValue: true,\n    })\n    .option('--entry.* <file>', 'Use a key-value pair as entry files')\n    .option('-d, --out-dir <dir>', 'Output directory', { default: 'dist' })\n    .option('--format <format>', 'Bundle format, \"cjs\", \"iife\", \"esm\"', {\n      default: 'cjs',\n    })\n    .option('--minify [terser]', 'Minify bundle')\n    .option('--minify-whitespace', 'Minify whitespace')\n    .option('--minify-identifiers', 'Minify identifiers')\n    .option('--minify-syntax', 'Minify syntax')\n    .option(\n      '--keep-names',\n      'Keep original function and class names in minified code',\n    )\n    .option('--target <target>', 'Bundle target, \"es20XX\" or \"esnext\"', {\n      default: 'es2017',\n    })\n    .option(\n      '--legacy-output',\n      'Output different formats to different folder instead of using different extensions',\n    )\n    .option('--dts [entry]', 'Generate declaration file')\n    .option('--dts-resolve', 'Resolve externals types used for d.ts files')\n    .option('--dts-only', 'Emit declaration files only')\n    .option(\n      '--experimental-dts [entry]',\n      'Generate declaration file (experimental)',\n    )\n    .option(\n      '--sourcemap [inline]',\n      'Generate external sourcemap, or inline source: --sourcemap inline',\n    )\n    .option(\n      '--watch [path]',\n      'Watch mode, if path is not specified, it watches the current folder \".\". Repeat \"--watch\" for more than one path',\n    )\n    .option('--ignore-watch <path>', 'Ignore custom paths in watch mode')\n    .option(\n      '--onSuccess <command>',\n      'Execute command after successful build, specially useful for watch mode',\n    )\n    .option('--env.* <value>', 'Define compile-time env variables')\n    .option(\n      '--inject <file>',\n      'Replace a global variable with an import from another file',\n    )\n    .option('--define.* <value>', 'Define compile-time constants')\n    .option(\n      '--external <name>',\n      'Mark specific packages / package.json (dependencies and peerDependencies) as external',\n    )\n    .option('--global-name <name>', 'Global variable name for iife format')\n    .option('--jsxFactory <jsxFactory>', 'Name of JSX factory function', {\n      default: 'React.createElement',\n    })\n    .option('--jsxFragment <jsxFragment>', 'Name of JSX fragment function', {\n      default: 'React.Fragment',\n    })\n    .option('--replaceNodeEnv', 'Replace process.env.NODE_ENV')\n    .option('--no-splitting', 'Disable code splitting')\n    .option('--clean', 'Clean output directory')\n    .option(\n      '--silent',\n      'Suppress non-error logs (excluding \"onSuccess\" process output)',\n    )\n    .option('--pure <express>', 'Mark specific expressions as pure')\n    .option('--metafile', 'Emit esbuild metafile (a JSON file)')\n    .option('--platform <platform>', 'Target platform', {\n      default: 'node',\n    })\n    .option('--loader <ext=loader>', 'Specify the loader for a file extension')\n    .option('--tsconfig <filename>', 'Use a custom tsconfig')\n    .option('--config <filename>', 'Use a custom config file')\n    .option('--no-config', 'Disable config file')\n    .option('--shims', 'Enable cjs and esm shims')\n    .option('--inject-style', 'Inject style tag to document head')\n    .option(\n      '--treeshake [strategy]',\n      'Using Rollup for treeshaking instead, \"recommended\" or \"smallest\" or \"safest\"',\n    )\n    .option('--publicDir [dir]', 'Copy public directory to output directory')\n    .option(\n      '--killSignal <signal>',\n      'Signal to kill child process, \"SIGTERM\" or \"SIGKILL\"',\n    )\n    .option('--cjsInterop', 'Enable cjs interop')\n    .action(async (files: string[], flags) => {\n      const { build } = await import('.')\n      Object.assign(options, {\n        ...flags,\n      })\n      if (!options.entry && files.length > 0) {\n        options.entry = files.map(slash)\n      }\n      if (flags.format) {\n        const format = ensureArray(flags.format) as Format[]\n        options.format = format\n      }\n      if (flags.external) {\n        const external = ensureArray(flags.external)\n        options.external = external\n      }\n      if (flags.target) {\n        options.target = flags.target.includes(',')\n          ? flags.target.split(',')\n          : flags.target\n      }\n      if (flags.dts || flags.dtsResolve || flags.dtsOnly) {\n        options.dts = {}\n        if (typeof flags.dts === 'string') {\n          options.dts.entry = flags.dts\n        }\n        if (flags.dtsResolve) {\n          options.dts.resolve = flags.dtsResolve\n        }\n        if (flags.dtsOnly) {\n          options.dts.only = true\n        }\n      }\n      if (flags.inject) {\n        const inject = ensureArray(flags.inject)\n        options.inject = inject\n      }\n      if (flags.define) {\n        const define: Record<string, string> = flatten(flags.define)\n        options.define = define\n      }\n      if (flags.loader) {\n        const loader = ensureArray(flags.loader)\n        options.loader = loader.reduce((result, item) => {\n          const parts = item.split('=')\n          return {\n            ...result,\n            [parts[0]]: parts[1],\n          }\n        }, {})\n      }\n      await build(options)\n    })\n\n  cli.help()\n\n  cli.version(version)\n\n  cli.parse(process.argv, { run: false })\n  await cli.runMatchedCommand()\n}\n"
  },
  {
    "path": "src/cli-node.ts",
    "content": "#!/usr/bin/env node\nimport { handleError } from './errors'\nimport { main } from './cli-main'\n\nmain({\n  skipNodeModulesBundle: true,\n}).catch(handleError)\n"
  },
  {
    "path": "src/errors.ts",
    "content": "import { isMainThread, parentPort } from 'node:worker_threads'\nimport colors from 'picocolors'\n\nexport class PrettyError extends Error {\n  constructor(message: string) {\n    super(message)\n    this.name = this.constructor.name\n    if (typeof Error.captureStackTrace === 'function') {\n      Error.captureStackTrace(this, this.constructor)\n    } else {\n      this.stack = new Error(message).stack\n    }\n  }\n}\n\nexport function handleError(error: any) {\n  if (error.loc) {\n    console.error(\n      colors.bold(\n        colors.red(\n          `Error parsing: ${error.loc.file}:${error.loc.line}:${error.loc.column}`,\n        ),\n      ),\n    )\n  }\n  if (error.frame) {\n    console.error(colors.red(error.message))\n    console.error(colors.dim(error.frame))\n  } else if (error instanceof PrettyError) {\n    console.error(colors.red(error.message))\n  } else {\n    console.error(colors.red(error.stack))\n  }\n  process.exitCode = 1\n  if (!isMainThread && parentPort) {\n    parentPort.postMessage('error')\n  }\n}\n"
  },
  {
    "path": "src/esbuild/external.ts",
    "content": "import { match, tsconfigPathsToRegExp } from 'bundle-require'\nimport type { Plugin } from 'esbuild'\n\n// Must not start with \"/\" or \"./\" or \"../\" or \"C:\\\" or be the exact strings \"..\" or \".\"\nconst NON_NODE_MODULE_RE = /^[A-Z]:[/\\\\]|^\\.{0,2}\\/|^\\.{1,2}$/\n\nexport const externalPlugin = ({\n  external,\n  noExternal,\n  skipNodeModulesBundle,\n  tsconfigResolvePaths,\n}: {\n  external?: (string | RegExp)[]\n  noExternal?: (string | RegExp)[]\n  skipNodeModulesBundle?: boolean\n  tsconfigResolvePaths?: Record<string, string[]>\n}): Plugin => {\n  return {\n    name: `external`,\n\n    setup(build) {\n      if (skipNodeModulesBundle) {\n        const resolvePatterns = tsconfigPathsToRegExp(\n          tsconfigResolvePaths || {},\n        )\n        build.onResolve({ filter: /.*/ }, (args) => {\n          // Resolve `paths` from tsconfig\n          if (match(args.path, resolvePatterns)) {\n            return\n          }\n          // Respect explicit external/noExternal conditions\n          if (match(args.path, noExternal)) {\n            return\n          }\n          if (match(args.path, external)) {\n            return { external: true }\n          }\n          // Exclude any other import that looks like a Node module\n          if (!NON_NODE_MODULE_RE.test(args.path)) {\n            return {\n              path: args.path,\n              external: true,\n            }\n          }\n        })\n      } else {\n        build.onResolve({ filter: /.*/ }, (args) => {\n          // Respect explicit external/noExternal conditions\n          if (match(args.path, noExternal)) {\n            return\n          }\n          if (match(args.path, external)) {\n            return { external: true }\n          }\n        })\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/esbuild/index.ts",
    "content": "import fs from 'node:fs'\nimport path from 'node:path'\nimport {\n  type BuildResult,\n  type Plugin as EsbuildPlugin,\n  build as esbuild,\n  formatMessages,\n} from 'esbuild'\nimport consola from 'consola'\nimport { getProductionDeps, loadPkg } from '../load'\nimport { type Logger, getSilent } from '../log'\nimport { defaultOutExtension, truthy } from '../utils'\nimport { nodeProtocolPlugin } from './node-protocol'\nimport { externalPlugin } from './external'\nimport { postcssPlugin } from './postcss'\nimport { sveltePlugin } from './svelte'\nimport { swcPlugin } from './swc'\nimport { nativeNodeModulesPlugin } from './native-node-module'\nimport type { PluginContainer } from '../plugin'\nimport type { Format, NormalizedOptions } from '..'\nimport type { OutExtensionFactory } from '../options'\n\nconst getOutputExtensionMap = (\n  options: NormalizedOptions,\n  format: Format,\n  pkgType: string | undefined,\n) => {\n  const outExtension: OutExtensionFactory =\n    options.outExtension || defaultOutExtension\n\n  const defaultExtension = defaultOutExtension({ format, pkgType })\n  const extension = outExtension({ options, format, pkgType })\n  return {\n    '.js': extension.js || defaultExtension.js,\n  }\n}\n\n/**\n * Support to exclude special package.json\n */\nconst generateExternal = async (external: (string | RegExp)[]) => {\n  const result: (string | RegExp)[] = []\n\n  for (const item of external) {\n    if (typeof item !== 'string' || !item.endsWith('package.json')) {\n      result.push(item)\n      continue\n    }\n\n    const pkgPath: string = path.isAbsolute(item)\n      ? path.dirname(item)\n      : path.dirname(path.resolve(process.cwd(), item))\n\n    const deps = await getProductionDeps(pkgPath)\n    result.push(...deps)\n  }\n\n  return result\n}\n\nexport async function runEsbuild(\n  options: NormalizedOptions,\n  {\n    format,\n    css,\n    logger,\n    buildDependencies,\n    pluginContainer,\n  }: {\n    format: Format\n    css?: Map<string, string>\n    buildDependencies: Set<string>\n    logger: Logger\n    pluginContainer: PluginContainer\n  },\n) {\n  const pkg = await loadPkg(process.cwd())\n  const deps = await getProductionDeps(process.cwd())\n  const external = [\n    // Exclude dependencies, e.g. `lodash`, `lodash/get`\n    ...deps.map((dep) => new RegExp(`^${dep}($|\\\\/|\\\\\\\\)`)),\n    ...(await generateExternal(options.external || [])),\n  ]\n  const outDir = options.outDir\n\n  const outExtension = getOutputExtensionMap(options, format, pkg.type)\n  const env: { [k: string]: string } = {\n    ...options.env,\n  }\n\n  if (options.replaceNodeEnv) {\n    env.NODE_ENV =\n      options.minify || options.minifyWhitespace ? 'production' : 'development'\n  }\n\n  logger.info(format, 'Build start')\n\n  const startTime = Date.now()\n\n  let result: BuildResult | undefined\n\n  const splitting =\n    format === 'iife'\n      ? false\n      : typeof options.splitting === 'boolean'\n        ? options.splitting\n        : format === 'esm'\n\n  const platform = options.platform || 'node'\n  const loader = options.loader || {}\n  const injectShims = options.shims\n\n  pluginContainer.setContext({\n    format,\n    splitting,\n    options,\n    logger,\n  })\n\n  await pluginContainer.buildStarted()\n  const esbuildPlugins: Array<EsbuildPlugin | false | undefined> = [\n    options.removeNodeProtocol && nodeProtocolPlugin(),\n    {\n      name: 'modify-options',\n      setup(build) {\n        pluginContainer.modifyEsbuildOptions(build.initialOptions)\n        if (options.esbuildOptions) {\n          options.esbuildOptions(build.initialOptions, { format })\n        }\n      },\n    },\n    // esbuild's `external` option doesn't support RegExp\n    // So here we use a custom plugin to implement it\n    format !== 'iife' &&\n      externalPlugin({\n        external,\n        noExternal: options.noExternal,\n        skipNodeModulesBundle: options.skipNodeModulesBundle,\n        tsconfigResolvePaths: options.tsconfigResolvePaths,\n      }),\n    options.tsconfigDecoratorMetadata && swcPlugin({ ...options.swc, logger }),\n    nativeNodeModulesPlugin(),\n    postcssPlugin({\n      css,\n      inject: options.injectStyle,\n      cssLoader: loader['.css'],\n    }),\n    sveltePlugin({ css }),\n    ...(options.esbuildPlugins || []),\n  ]\n\n  const banner =\n    typeof options.banner === 'function'\n      ? options.banner({ format })\n      : options.banner\n  const footer =\n    typeof options.footer === 'function'\n      ? options.footer({ format })\n      : options.footer\n\n  try {\n    result = await esbuild({\n      entryPoints: options.entry,\n      format:\n        (format === 'cjs' && splitting) || options.treeshake ? 'esm' : format,\n      bundle: typeof options.bundle === 'undefined' ? true : options.bundle,\n      platform,\n      globalName: options.globalName,\n      jsxFactory: options.jsxFactory,\n      jsxFragment: options.jsxFragment,\n      sourcemap: options.sourcemap ? 'external' : false,\n      target: options.target,\n      banner,\n      footer,\n      tsconfig: options.tsconfig,\n      loader: {\n        '.aac': 'file',\n        '.css': 'file',\n        '.eot': 'file',\n        '.flac': 'file',\n        '.gif': 'file',\n        '.jpeg': 'file',\n        '.jpg': 'file',\n        '.mp3': 'file',\n        '.mp4': 'file',\n        '.ogg': 'file',\n        '.otf': 'file',\n        '.png': 'file',\n        '.svg': 'file',\n        '.ttf': 'file',\n        '.wav': 'file',\n        '.webm': 'file',\n        '.webp': 'file',\n        '.woff': 'file',\n        '.woff2': 'file',\n        ...loader,\n      },\n      mainFields:\n        platform === 'node'\n          ? ['module', 'main']\n          : ['browser', 'module', 'main'],\n      plugins: esbuildPlugins.filter(truthy),\n      define: {\n        TSUP_FORMAT: JSON.stringify(format),\n        ...(format === 'cjs' && injectShims\n          ? {\n              'import.meta.url': 'importMetaUrl',\n            }\n          : {}),\n        ...options.define,\n        ...Object.keys(env).reduce((res, key) => {\n          const value = JSON.stringify(env[key])\n          return {\n            ...res,\n            [`process.env.${key}`]: value,\n            [`import.meta.env.${key}`]: value,\n          }\n        }, {}),\n      },\n      inject: [\n        format === 'cjs' && injectShims\n          ? path.join(__dirname, '../assets/cjs_shims.js')\n          : '',\n        format === 'esm' && injectShims && platform === 'node'\n          ? path.join(__dirname, '../assets/esm_shims.js')\n          : '',\n        ...(options.inject || []),\n      ].filter(Boolean),\n      outdir:\n        options.legacyOutput && format !== 'cjs'\n          ? path.join(outDir, format)\n          : outDir,\n      outExtension: options.legacyOutput ? undefined : outExtension,\n      write: false,\n      splitting,\n      logLevel: 'error',\n      minify: options.minify === 'terser' ? false : options.minify,\n      minifyWhitespace: options.minifyWhitespace,\n      minifyIdentifiers: options.minifyIdentifiers,\n      minifySyntax: options.minifySyntax,\n      keepNames: options.keepNames,\n      pure: typeof options.pure === 'string' ? [options.pure] : options.pure,\n      metafile: true,\n    })\n  } catch (error) {\n    logger.error(format, 'Build failed')\n    throw error\n  }\n\n  if (result && result.warnings && !getSilent()) {\n    const messages = result.warnings.filter((warning) => {\n      if (\n        warning.text.includes(\n          `This call to \"require\" will not be bundled because`,\n        ) ||\n        warning.text.includes(`Indirect calls to \"require\" will not be bundled`)\n      )\n        return false\n\n      return true\n    })\n    const formatted = await formatMessages(messages, {\n      kind: 'warning',\n      color: true,\n    })\n    formatted.forEach((message) => {\n      consola.warn(message)\n    })\n  }\n\n  // Manually write files\n  if (result && result.outputFiles) {\n    await pluginContainer.buildFinished({\n      outputFiles: result.outputFiles,\n      metafile: result.metafile,\n    })\n\n    const timeInMs = Date.now() - startTime\n    logger.success(format, `⚡️ Build success in ${Math.floor(timeInMs)}ms`)\n  }\n\n  if (result.metafile) {\n    for (const file of Object.keys(result.metafile.inputs)) {\n      buildDependencies.add(file)\n    }\n\n    if (options.metafile) {\n      const outPath = path.resolve(outDir, `metafile-${format}.json`)\n      await fs.promises.mkdir(path.dirname(outPath), { recursive: true })\n      await fs.promises.writeFile(\n        outPath,\n        JSON.stringify(result.metafile),\n        'utf8',\n      )\n    }\n  }\n}\n"
  },
  {
    "path": "src/esbuild/native-node-module.ts",
    "content": "import path from 'node:path'\nimport type { Plugin } from 'esbuild'\n\n// Copied from https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487\nexport const nativeNodeModulesPlugin = (): Plugin => {\n  return {\n    name: 'native-node-modules',\n    setup(build) {\n      // If a \".node\" file is imported within a module in the \"file\" namespace, resolve\n      // it to an absolute path and put it into the \"node-file\" virtual namespace.\n      build.onResolve({ filter: /\\.node$/, namespace: 'file' }, (args) => {\n        const resolvedId = require.resolve(args.path, {\n          paths: [args.resolveDir],\n        })\n        if (resolvedId.endsWith('.node')) {\n          return {\n            path: resolvedId,\n            namespace: 'node-file',\n          }\n        }\n        return {\n          path: resolvedId,\n        }\n      })\n\n      // Files in the \"node-file\" virtual namespace call \"require()\" on the\n      // path from esbuild of the \".node\" file in the output directory.\n      build.onLoad({ filter: /.*/, namespace: 'node-file' }, (args) => {\n        return {\n          contents: `\n            import path from ${JSON.stringify(args.path)}\n            try { module.exports = require(path) }\n            catch {}\n          `,\n          resolveDir: path.dirname(args.path),\n        }\n      })\n\n      // If a \".node\" file is imported within a module in the \"node-file\" namespace, put\n      // it in the \"file\" namespace where esbuild's default loading behavior will handle\n      // it. It is already an absolute path since we resolved it to one above.\n      build.onResolve(\n        { filter: /\\.node$/, namespace: 'node-file' },\n        (args) => ({\n          path: args.path,\n          namespace: 'file',\n        }),\n      )\n\n      // Tell esbuild's default loading behavior to use the \"file\" loader for\n      // these \".node\" files.\n      const opts = build.initialOptions\n      opts.loader = opts.loader || {}\n      opts.loader['.node'] = 'file'\n    },\n  }\n}\n"
  },
  {
    "path": "src/esbuild/node-protocol.ts",
    "content": "import type { Plugin } from 'esbuild'\n\n/**\n * The node: protocol was added to require in Node v14.18.0\n * https://nodejs.org/api/esm.html#node-imports\n */\nexport const nodeProtocolPlugin = (): Plugin => {\n  const nodeProtocol = 'node:'\n\n  return {\n    name: 'node-protocol-plugin',\n    setup({ onResolve }) {\n      onResolve(\n        {\n          filter: /^node:/,\n        },\n        ({ path }) => ({\n          path: path.slice(nodeProtocol.length),\n          external: true,\n        }),\n      )\n    },\n  }\n}\n"
  },
  {
    "path": "src/esbuild/postcss.ts",
    "content": "import fs from 'node:fs'\nimport { type Loader, type Plugin, transform } from 'esbuild'\nimport { getPostcss } from '../utils'\nimport type { Result } from 'postcss-load-config'\n\nexport const postcssPlugin = ({\n  css,\n  inject,\n  cssLoader,\n}: {\n  css?: Map<string, string>\n  inject?: boolean | ((css: string, fileId: string) => string | Promise<string>)\n  cssLoader?: Loader\n}): Plugin => {\n  return {\n    name: 'postcss',\n\n    setup(build) {\n      let configCache: Result\n\n      const getPostcssConfig = async () => {\n        const loadConfig = require('postcss-load-config')\n\n        if (configCache) {\n          return configCache\n        }\n\n        try {\n          const result = await loadConfig({}, process.cwd())\n          configCache = result\n          return result\n        } catch (error: any) {\n          if (error.message.includes('No PostCSS Config found in')) {\n            const result = { plugins: [], options: {} }\n            return result\n          }\n          throw error\n        }\n      }\n\n      build.onResolve({ filter: /^#style-inject$/ }, () => {\n        return { path: '#style-inject', namespace: '#style-inject' }\n      })\n\n      build.onLoad(\n        { filter: /^#style-inject$/, namespace: '#style-inject' },\n        () => {\n          return {\n            // Taken from https://github.com/egoist/style-inject/blob/master/src/index.js (MIT)\n            contents: `\n          export default function styleInject(css, { insertAt } = {}) {\n            if (!css || typeof document === 'undefined') return\n          \n            const head = document.head || document.getElementsByTagName('head')[0]\n            const style = document.createElement('style')\n            style.type = 'text/css'\n          \n            if (insertAt === 'top') {\n              if (head.firstChild) {\n                head.insertBefore(style, head.firstChild)\n              } else {\n                head.appendChild(style)\n              }\n            } else {\n              head.appendChild(style)\n            }\n          \n            if (style.styleSheet) {\n              style.styleSheet.cssText = css\n            } else {\n              style.appendChild(document.createTextNode(css))\n            }\n          }\n          `,\n            loader: 'js',\n          }\n        },\n      )\n\n      build.onLoad({ filter: /\\.css$/ }, async (args) => {\n        let contents: string\n\n        if (css && args.path.endsWith('.svelte.css')) {\n          contents = css.get(args.path)!\n        } else {\n          contents = await fs.promises.readFile(args.path, 'utf8')\n        }\n\n        // Load postcss config\n        const { plugins, options } = await getPostcssConfig()\n\n        if (plugins && plugins.length > 0) {\n          // Load postcss\n          const postcss = getPostcss()\n          if (!postcss) {\n            return {\n              errors: [\n                {\n                  text: `postcss is not installed`,\n                },\n              ],\n            }\n          }\n\n          // Transform CSS\n          const result = await postcss\n            ?.default(plugins)\n            .process(contents, { ...options, from: args.path })\n\n          contents = result.css\n        }\n\n        if (inject) {\n          contents = (\n            await transform(contents, {\n              minify: build.initialOptions.minify,\n              minifyIdentifiers: build.initialOptions.minifyIdentifiers,\n              minifySyntax: build.initialOptions.minifySyntax,\n              minifyWhitespace: build.initialOptions.minifyWhitespace,\n              logLevel: build.initialOptions.logLevel,\n              loader: 'css',\n            })\n          ).code\n\n          contents =\n            typeof inject === 'function'\n              ? await inject(JSON.stringify(contents), args.path)\n              : `import styleInject from '#style-inject';styleInject(${JSON.stringify(\n                  contents,\n                )})`\n\n          return {\n            contents,\n            loader: 'js',\n          }\n        }\n\n        return {\n          contents,\n          loader: cssLoader ?? 'css',\n        }\n      })\n    },\n  }\n}\n"
  },
  {
    "path": "src/esbuild/svelte.ts",
    "content": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { type Plugin, transform } from 'esbuild'\nimport { localRequire } from '../utils'\n\nconst useSvelteCssExtension = (p: string) =>\n  p.replace(/\\.svelte$/, '.svelte.css')\n\nexport const sveltePlugin = ({\n  css,\n}: {\n  css?: Map<string, string>\n}): Plugin => {\n  return {\n    name: 'svelte',\n\n    setup(build) {\n      let svelte: typeof import('svelte/compiler')\n      let sveltePreprocessor: typeof import('svelte-preprocess').default\n\n      build.onResolve({ filter: /\\.svelte\\.css$/ }, (args) => {\n        return {\n          path: path.relative(\n            process.cwd(),\n            path.join(args.resolveDir, args.path),\n          ),\n          namespace: 'svelte-css',\n        }\n      })\n\n      build.onLoad({ filter: /\\.svelte$/ }, async (args) => {\n        svelte = svelte || localRequire('svelte/compiler')\n        sveltePreprocessor =\n          sveltePreprocessor || localRequire('svelte-preprocess')\n\n        if (!svelte) {\n          return {\n            errors: [{ text: `You need to install \"svelte\" in your project` }],\n          }\n        }\n\n        // This converts a message in Svelte's format to esbuild's format\n        const convertMessage = ({ message, start, end }: any) => {\n          let location\n          if (start && end) {\n            const lineText = source.split(/\\r\\n|\\r|\\n/g)[start.line - 1]\n            const lineEnd =\n              start.line === end.line ? end.column : lineText.length\n            location = {\n              file: filename,\n              line: start.line,\n              column: start.column,\n              length: lineEnd - start.column,\n              lineText,\n            }\n          }\n          return { text: message, location }\n        }\n\n        // Load the file from the file system\n        const source = await fs.promises.readFile(args.path, 'utf8')\n        const filename = path.relative(process.cwd(), args.path)\n\n        // Convert Svelte syntax to JavaScript\n        try {\n          const preprocess = await svelte.preprocess(\n            source,\n            sveltePreprocessor\n              ? sveltePreprocessor({\n                  sourceMap: true,\n                  typescript: {\n                    compilerOptions: {\n                      verbatimModuleSyntax: true,\n                    },\n                  },\n                })\n              : {\n                  async script({ content, attributes }) {\n                    if (attributes.lang !== 'ts') return { code: content }\n\n                    const { code, map } = await transform(content, {\n                      sourcefile: args.path,\n                      loader: 'ts',\n                      sourcemap: true,\n                      tsconfigRaw: {\n                        compilerOptions: {\n                          verbatimModuleSyntax: true,\n                        },\n                      },\n                      logLevel: build.initialOptions.logLevel,\n                    })\n                    return {\n                      code,\n                      map,\n                    }\n                  },\n                },\n            {\n              filename: args.path,\n            },\n          )\n          const result = svelte.compile(preprocess.code, {\n            filename,\n            css: 'external',\n          })\n\n          let contents = result.js.code\n          if (css && result.css && result.css.code) {\n            const cssPath = useSvelteCssExtension(filename)\n            css.set(cssPath, result.css.code)\n            // Directly prepend the `import` statement as sourcemap doesn't matter for now\n            // If that's need we should use `magic-string`\n            contents = `import '${useSvelteCssExtension(path.basename(args.path))}';${\n              contents\n            }`\n          }\n          return { contents, warnings: result.warnings.map(convertMessage) }\n        } catch (error) {\n          return { errors: [convertMessage(error)] }\n        }\n      })\n    },\n  }\n}\n"
  },
  {
    "path": "src/esbuild/swc.test.ts",
    "content": "import { describe, expect, test, vi } from 'vitest'\nimport { swcPlugin, type SwcPluginConfig } from './swc'\nimport { localRequire } from '../utils'\n\nvi.mock('../utils')\n\nconst getFixture = async (opts: Partial<SwcPluginConfig> = {}) => {\n  const swc = {\n    transformFile: vi.fn().mockResolvedValue({\n      code: 'source-code',\n      map: JSON.stringify({\n        sources: ['file:///path/to/file.ts'],\n      }),\n    }),\n  }\n\n  const logger = {\n    warn: vi.fn(),\n    error: vi.fn(),\n    info: vi.fn(),\n  }\n\n  const build = {\n    initialOptions: {\n      keepNames: true,\n    },\n    onLoad: vi.fn(),\n  }\n\n  vi.mocked(localRequire).mockReturnValue(swc)\n\n  const plugin = swcPlugin({\n    ...opts,\n    logger: logger as never,\n  })\n\n  await plugin.setup(build as never)\n\n  const onLoad = build.onLoad.mock.calls[0][1] as Function\n\n  return { swc, onLoad, logger, build }\n}\ndescribe('swcPlugin', () => {\n  test('swcPlugin transforms TypeScript code with decorators and default plugin swc option', async () => {\n    const { swc, onLoad } = await getFixture()\n\n    await onLoad({\n      path: 'file.ts',\n    })\n\n    expect(swc.transformFile).toHaveBeenCalledWith('file.ts', {\n      configFile: false,\n      jsc: {\n        keepClassNames: true,\n        parser: {\n          decorators: true,\n          syntax: 'typescript',\n        },\n        target: 'es2022',\n        transform: {\n          decoratorMetadata: true,\n          legacyDecorator: true,\n        },\n      },\n      sourceMaps: true,\n      swcrc: false,\n    })\n  })\n  test('swcPlugin transforms TypeScript code and use given plugin swc option', async () => {\n    const { swc, onLoad } = await getFixture({\n      jsc: {\n        transform: {\n          useDefineForClassFields: true,\n        },\n      },\n    })\n\n    await onLoad({\n      path: 'file.ts',\n    })\n\n    expect(swc.transformFile).toHaveBeenCalledWith('file.ts', {\n      configFile: false,\n      jsc: {\n        keepClassNames: true,\n        parser: {\n          decorators: true,\n          syntax: 'typescript',\n        },\n        target: 'es2022',\n        transform: {\n          decoratorMetadata: true,\n          legacyDecorator: true,\n          useDefineForClassFields: true,\n        },\n      },\n      sourceMaps: true,\n      swcrc: false,\n    })\n  })\n})\n"
  },
  {
    "path": "src/esbuild/swc.ts",
    "content": "/**\n * Use SWC to emit decorator metadata\n */\nimport path from 'node:path'\nimport { localRequire } from '../utils'\nimport type { JscConfig, Options } from '@swc/core'\nimport type { Plugin } from 'esbuild'\nimport type { Logger } from '../log'\n\nexport type SwcPluginConfig = { logger: Logger } & Options\n\nexport const swcPlugin = ({ logger, ...swcOptions }: SwcPluginConfig): Plugin => {\n  return {\n    name: 'swc',\n\n    setup(build) {\n      const swc: typeof import('@swc/core') = localRequire('@swc/core')\n\n      if (!swc) {\n        logger.warn(\n          build.initialOptions.format!,\n          `You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin`,\n        )\n        return\n      }\n\n      // Force esbuild to keep class names as well\n      build.initialOptions.keepNames = true\n\n      build.onLoad({ filter: /\\.[jt]sx?$/ }, async (args) => {\n        const isTs = /\\.tsx?$/.test(args.path)\n\n        const jsc: JscConfig = {\n          ...swcOptions.jsc,\n          parser: {\n            ...swcOptions.jsc?.parser,\n            syntax: isTs ? 'typescript' : 'ecmascript',\n            decorators: true,\n          },\n          transform: {\n            ...swcOptions.jsc?.transform,\n            legacyDecorator: true,\n            decoratorMetadata: true,\n          },\n          keepClassNames: true,\n          target: 'es2022',\n        }\n\n        const result = await swc.transformFile(args.path, {\n          ...swcOptions,\n          jsc,\n          sourceMaps: true,\n          configFile: false,\n          swcrc: swcOptions.swcrc ?? false,\n        })\n\n        let code = result.code\n        if (result.map) {\n          const map: { sources: string[] } = JSON.parse(result.map)\n          // Make sure sources are relative path\n          map.sources = map.sources.map((source) => {\n            return path.isAbsolute(source)\n              ? path.relative(path.dirname(args.path), source)\n              : source\n          })\n          code += `//# sourceMappingURL=data:application/json;base64,${Buffer.from(\n            JSON.stringify(map),\n          ).toString('base64')}`\n        }\n        return {\n          contents: code,\n        }\n      })\n    },\n  }\n}\n"
  },
  {
    "path": "src/exports.ts",
    "content": "import path from 'node:path'\nimport { replaceDtsWithJsExtensions, slash, truthy } from './utils'\n\nexport type ExportDeclaration = ModuleExport | NamedExport\n\ninterface ModuleExport {\n  kind: 'module'\n  sourceFileName: string\n  destFileName: string\n  moduleName: string\n  isTypeOnly: boolean\n}\n\ninterface NamedExport {\n  kind: 'named'\n  sourceFileName: string\n  destFileName: string\n  alias: string\n  name: string\n  isTypeOnly: boolean\n}\n\nexport function formatAggregationExports(\n  exports: ExportDeclaration[],\n  declarationDirPath: string,\n): string {\n  const lines = exports\n    .map((declaration) =>\n      formatAggregationExport(declaration, declarationDirPath),\n    )\n    .filter(truthy)\n\n  if (lines.length === 0) {\n    lines.push('export {};')\n  }\n\n  return `${lines.join('\\n')}\\n`\n}\n\nfunction formatAggregationExport(\n  declaration: ExportDeclaration,\n  declarationDirPath: string,\n): string {\n  const dest = replaceDtsWithJsExtensions(\n    `./${path.posix.normalize(\n      slash(path.relative(declarationDirPath, declaration.destFileName)),\n    )}`,\n  )\n\n  if (declaration.kind === 'module') {\n    // Not implemented\n    return ''\n  } else if (declaration.kind === 'named') {\n    return [\n      'export',\n      declaration.isTypeOnly ? 'type' : '',\n      '{',\n      declaration.name,\n      declaration.name === declaration.alias ? '' : `as ${declaration.alias}`,\n      '} from',\n      `'${dest}';`,\n    ]\n      .filter(truthy)\n      .join(' ')\n  } else {\n    throw new Error('Unknown declaration')\n  }\n}\n\nexport function formatDistributionExports(\n  exports: ExportDeclaration[],\n  fromFilePath: string,\n  toFilePath: string,\n) {\n  let importPath = replaceDtsWithJsExtensions(\n    path.posix.relative(\n      path.posix.dirname(path.posix.normalize(slash(fromFilePath))),\n      path.posix.normalize(slash(toFilePath)),\n    ),\n  )\n  if (!/^\\.+\\//.test(importPath)) {\n    importPath = `./${importPath}`\n  }\n\n  const seen = {\n    named: new Set<string>(),\n    module: new Set<string>(),\n  }\n\n  const lines = exports\n    .filter((declaration) => {\n      if (declaration.kind === 'module') {\n        if (seen.module.has(declaration.moduleName)) {\n          return false\n        }\n        seen.module.add(declaration.moduleName)\n        return true\n      } else if (declaration.kind === 'named') {\n        if (seen.named.has(declaration.name)) {\n          return false\n        }\n        seen.named.add(declaration.name)\n        return true\n      } else {\n        return false\n      }\n    })\n    .map((declaration) => formatDistributionExport(declaration, importPath))\n    .filter(truthy)\n\n  if (lines.length === 0) {\n    lines.push('export {};')\n  }\n\n  return `${lines.join('\\n')}\\n`\n}\n\nfunction formatDistributionExport(\n  declaration: ExportDeclaration,\n  dest: string,\n): string {\n  if (declaration.kind === 'named') {\n    return [\n      'export',\n      declaration.isTypeOnly ? 'type' : '',\n      '{',\n      declaration.alias,\n      declaration.name === declaration.alias ? '' : `as ${declaration.name}`,\n      '} from',\n      `'${dest}';`,\n    ]\n      .filter(truthy)\n      .join(' ')\n  } else if (declaration.kind === 'module') {\n    return `export * from '${declaration.moduleName}';`\n  }\n  return ''\n}\n"
  },
  {
    "path": "src/fs.ts",
    "content": "import path from 'node:path'\nimport fs from 'node:fs'\n\nexport const outputFile = async (\n  filepath: string,\n  data: any,\n  options?: { mode?: fs.Mode },\n) => {\n  await fs.promises.mkdir(path.dirname(filepath), { recursive: true })\n  await fs.promises.writeFile(filepath, data, options)\n}\n\nexport function copyDirSync(srcDir: string, destDir: string): void {\n  if (!fs.existsSync(srcDir)) return\n\n  fs.mkdirSync(destDir, { recursive: true })\n  for (const file of fs.readdirSync(srcDir)) {\n    const srcFile = path.resolve(srcDir, file)\n    if (srcFile === destDir) {\n      continue\n    }\n    const destFile = path.resolve(destDir, file)\n    const stat = fs.statSync(srcFile)\n    if (stat.isDirectory()) {\n      copyDirSync(srcFile, destFile)\n    } else {\n      fs.copyFileSync(srcFile, destFile)\n    }\n  }\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "import path from 'node:path'\nimport fs from 'node:fs'\nimport { Worker } from 'node:worker_threads'\nimport { loadTsConfig } from 'bundle-require'\nimport { exec, type Result as ExecChild } from 'tinyexec'\nimport { glob, globSync } from 'tinyglobby'\nimport kill from 'tree-kill'\nimport { version } from '../package.json'\nimport { PrettyError, handleError } from './errors'\nimport { getAllDepsHash, loadTsupConfig } from './load'\nimport {\n  type MaybePromise,\n  debouncePromise,\n  removeFiles,\n  resolveExperimentalDtsConfig,\n  resolveInitialExperimentalDtsConfig,\n  slash,\n} from './utils'\nimport { createLogger, setSilent } from './log'\nimport { runEsbuild } from './esbuild'\nimport { shebang } from './plugins/shebang'\nimport { cjsSplitting } from './plugins/cjs-splitting'\nimport { PluginContainer } from './plugin'\nimport { swcTarget } from './plugins/swc-target'\nimport { sizeReporter } from './plugins/size-reporter'\nimport { treeShakingPlugin } from './plugins/tree-shaking'\nimport { copyPublicDir, isInPublicDir } from './lib/public-dir'\nimport { terserPlugin } from './plugins/terser'\nimport { runTypeScriptCompiler } from './tsc'\nimport { runDtsRollup } from './api-extractor'\nimport { cjsInterop } from './plugins/cjs-interop'\nimport type { Format, KILL_SIGNAL, NormalizedOptions, Options } from './options'\n\nexport type { Format, Options, NormalizedOptions }\n\nexport const defineConfig = (\n  options:\n    | Options\n    | Options[]\n    | ((\n        /** The options derived from CLI flags */\n        overrideOptions: Options,\n      ) => MaybePromise<Options | Options[]>),\n) => options\n\n/**\n * tree-kill use `taskkill` command on Windows to kill the process,\n * it may return 128 as exit code when the process has already exited.\n * @see https://github.com/egoist/tsup/issues/976\n */\nconst isTaskkillCmdProcessNotFoundError = (err: Error) => {\n  return (\n    process.platform === 'win32' &&\n    'cmd' in err &&\n    'code' in err &&\n    typeof err.cmd === 'string' &&\n    err.cmd.startsWith('taskkill') &&\n    err.code === 128\n  )\n}\n\nconst killProcess = ({ pid, signal }: { pid: number; signal: KILL_SIGNAL }) =>\n  new Promise<void>((resolve, reject) => {\n    kill(pid, signal, (err) => {\n      if (err && !isTaskkillCmdProcessNotFoundError(err)) return reject(err)\n      resolve()\n    })\n  })\n\nconst normalizeOptions = async (\n  logger: ReturnType<typeof createLogger>,\n  optionsFromConfigFile: Options | undefined,\n  optionsOverride: Options,\n) => {\n  const _options = {\n    ...optionsFromConfigFile,\n    ...optionsOverride,\n  }\n\n  const options: Partial<NormalizedOptions> = {\n    outDir: 'dist',\n    removeNodeProtocol: true,\n    ..._options,\n    format:\n      typeof _options.format === 'string'\n        ? [_options.format as Format]\n        : _options.format || ['cjs'],\n    dts:\n      typeof _options.dts === 'boolean'\n        ? _options.dts\n          ? {}\n          : undefined\n        : typeof _options.dts === 'string'\n          ? { entry: _options.dts }\n          : _options.dts,\n\n    experimentalDts: await resolveInitialExperimentalDtsConfig(\n      _options.experimentalDts,\n    ),\n  }\n\n  setSilent(options.silent)\n\n  const entry = options.entry || options.entryPoints\n\n  if (!entry || Object.keys(entry).length === 0) {\n    throw new PrettyError(`No input files, try \"tsup <your-file>\" instead`)\n  }\n\n  if (Array.isArray(entry)) {\n    options.entry = await glob(entry)\n    // Ensure entry exists\n    if (!options.entry || options.entry.length === 0) {\n      throw new PrettyError(`Cannot find ${entry}`)\n    } else {\n      logger.info('CLI', `Building entry: ${options.entry.join(', ')}`)\n    }\n  } else {\n    Object.keys(entry).forEach((alias) => {\n      const filename = entry[alias]!\n      if (!fs.existsSync(filename)) {\n        throw new PrettyError(`Cannot find ${alias}: ${filename}`)\n      }\n    })\n    options.entry = entry\n    logger.info('CLI', `Building entry: ${JSON.stringify(entry)}`)\n  }\n\n  const tsconfig = loadTsConfig(process.cwd(), options.tsconfig)\n  if (tsconfig) {\n    logger.info(\n      'CLI',\n      `Using tsconfig: ${path.relative(process.cwd(), tsconfig.path)}`,\n    )\n    options.tsconfig = tsconfig.path\n    options.tsconfigResolvePaths = tsconfig.data?.compilerOptions?.paths || {}\n    options.tsconfigDecoratorMetadata =\n      tsconfig.data?.compilerOptions?.emitDecoratorMetadata\n    if (options.dts) {\n      options.dts.compilerOptions = {\n        ...(tsconfig.data.compilerOptions || {}),\n        ...(options.dts.compilerOptions || {}),\n      }\n    }\n\n    if (options.experimentalDts) {\n      options.experimentalDts = await resolveExperimentalDtsConfig(\n        options as NormalizedOptions,\n        tsconfig,\n      )\n    }\n\n    if (!options.target) {\n      options.target = tsconfig.data?.compilerOptions?.target?.toLowerCase()\n    }\n  } else if (options.tsconfig) {\n    throw new PrettyError(`Cannot find tsconfig: ${options.tsconfig}`)\n  }\n\n  if (!options.target) {\n    options.target = 'node16'\n  }\n\n  return options as NormalizedOptions\n}\n\nexport async function build(_options: Options) {\n  const config =\n    _options.config === false\n      ? {}\n      : await loadTsupConfig(\n          process.cwd(),\n          _options.config === true ? undefined : _options.config,\n        )\n\n  const configData =\n    typeof config.data === 'function'\n      ? await config.data(_options)\n      : config.data\n\n  await Promise.all(\n    [...(Array.isArray(configData) ? configData : [configData])].map(\n      async (item) => {\n        const logger = createLogger(item?.name)\n        const options = await normalizeOptions(logger, item, _options)\n\n        logger.info('CLI', `tsup v${version}`)\n\n        if (config.path) {\n          logger.info('CLI', `Using tsup config: ${config.path}`)\n        }\n\n        if (options.watch) {\n          logger.info('CLI', 'Running in watch mode')\n        }\n\n        const experimentalDtsTask = async () => {\n          if (!options.dts && options.experimentalDts) {\n            const exports = runTypeScriptCompiler(options)\n            await runDtsRollup(options, exports)\n          }\n        }\n\n        const dtsTask = async () => {\n          if (options.dts && options.experimentalDts) {\n            throw new Error(\n              \"You can't use both `dts` and `experimentalDts` at the same time\",\n            )\n          }\n\n          await experimentalDtsTask()\n\n          if (options.dts) {\n            await new Promise<void>((resolve, reject) => {\n              const worker = new Worker(path.join(__dirname, './rollup.js'))\n\n              const terminateWorker = () => {\n                if (options.watch) return\n                worker.terminate()\n              }\n\n              worker.postMessage({\n                configName: item?.name,\n                options: {\n                  ...options, // functions cannot be cloned\n                  injectStyle:\n                    typeof options.injectStyle === 'function'\n                      ? undefined\n                      : options.injectStyle,\n                  banner: undefined,\n                  footer: undefined,\n                  esbuildPlugins: undefined,\n                  esbuildOptions: undefined,\n                  plugins: undefined,\n                  treeshake: undefined,\n                  onSuccess: undefined,\n                  outExtension: undefined,\n                },\n              })\n              worker.on('message', (data) => {\n                if (data === 'error') {\n                  terminateWorker()\n                  reject(new Error('error occurred in dts build'))\n                } else if (data === 'success') {\n                  terminateWorker()\n                  resolve()\n                } else {\n                  const { type, text } = data\n                  if (type === 'log') {\n                    console.log(text)\n                  } else if (type === 'error') {\n                    console.error(text)\n                  }\n                }\n              })\n            })\n          }\n        }\n\n        const mainTasks = async () => {\n          if (!options.dts?.only) {\n            let onSuccessProcess: ExecChild | undefined\n            let onSuccessCleanup: (() => any) | undefined | void\n            /** Files imported by the entry */\n            const buildDependencies: Set<string> = new Set()\n\n            let depsHash = await getAllDepsHash(process.cwd())\n\n            const doOnSuccessCleanup = async () => {\n              if (onSuccessProcess) {\n                await killProcess({\n                  pid: onSuccessProcess.pid!,\n                  signal: options.killSignal || 'SIGTERM',\n                })\n              } else if (onSuccessCleanup) {\n                await onSuccessCleanup()\n              }\n              // reset them in all occasions anyway\n              onSuccessProcess = undefined\n              onSuccessCleanup = undefined\n            }\n\n            const debouncedBuildAll = debouncePromise(\n              () => {\n                return buildAll()\n              },\n              100,\n              handleError,\n            )\n\n            const buildAll = async () => {\n              await doOnSuccessCleanup()\n              // Store previous build dependencies in case the build failed\n              // So we can restore it\n              const previousBuildDependencies = new Set(buildDependencies)\n              buildDependencies.clear()\n\n              if (options.clean) {\n                const extraPatterns = Array.isArray(options.clean)\n                  ? options.clean\n                  : []\n                // .d.ts files are removed in the `dtsTask` instead\n                // `dtsTask` is a separate process, which might start before `mainTasks`\n                if (options.dts || options.experimentalDts) {\n                  extraPatterns.unshift('!**/*.d.{ts,cts,mts}')\n                }\n                await removeFiles(['**/*', ...extraPatterns], options.outDir)\n                logger.info('CLI', 'Cleaning output folder')\n              }\n\n              const css: Map<string, string> = new Map()\n              await Promise.all([\n                ...options.format.map(async (format, index) => {\n                  const pluginContainer = new PluginContainer([\n                    shebang(),\n                    ...(options.plugins || []),\n                    treeShakingPlugin({\n                      treeshake: options.treeshake,\n                      name: options.globalName,\n                      silent: options.silent,\n                    }),\n                    cjsSplitting(),\n                    cjsInterop(),\n                    swcTarget(),\n                    sizeReporter(),\n                    terserPlugin({\n                      minifyOptions: options.minify,\n                      format,\n                      terserOptions: options.terserOptions,\n                      globalName: options.globalName,\n                      logger,\n                    }),\n                  ])\n                  await runEsbuild(options, {\n                    pluginContainer,\n                    format,\n                    css: index === 0 || options.injectStyle ? css : undefined,\n                    logger,\n                    buildDependencies,\n                  }).catch((error) => {\n                    previousBuildDependencies.forEach((v) =>\n                      buildDependencies.add(v),\n                    )\n                    throw error\n                  })\n                }),\n              ])\n\n              copyPublicDir(options.publicDir, options.outDir)\n\n              if (options.onSuccess) {\n                if (typeof options.onSuccess === 'function') {\n                  onSuccessCleanup = await options.onSuccess()\n                } else {\n                  onSuccessProcess = exec(options.onSuccess, [], {\n                    nodeOptions: { shell: true, stdio: 'inherit' },\n                  })\n                  onSuccessProcess.process?.on('exit', (code) => {\n                    if (code && code !== 0) {\n                      process.exitCode = code\n                    }\n                  })\n                }\n              }\n            }\n\n            const startWatcher = async () => {\n              if (!options.watch) return\n\n              const { watch } = await import('chokidar')\n\n              const customIgnores = options.ignoreWatch\n                ? Array.isArray(options.ignoreWatch)\n                  ? options.ignoreWatch\n                  : [options.ignoreWatch]\n                : []\n\n              const ignored = [\n                '**/{.git,node_modules}/**',\n                options.outDir,\n                ...customIgnores,\n              ]\n\n              const watchPaths =\n                typeof options.watch === 'boolean'\n                  ? '.'\n                  : Array.isArray(options.watch)\n                    ? options.watch.filter((path) => typeof path === 'string')\n                    : options.watch\n\n              logger.info(\n                'CLI',\n                `Watching for changes in ${\n                  Array.isArray(watchPaths)\n                    ? watchPaths.map((v) => `\"${v}\"`).join(' | ')\n                    : `\"${watchPaths}\"`\n                }`,\n              )\n              logger.info(\n                'CLI',\n                `Ignoring changes in ${ignored\n                  .map((v) => `\"${v}\"`)\n                  .join(' | ')}`,\n              )\n\n              const watcher = watch(await glob(watchPaths), {\n                ignoreInitial: true,\n                ignorePermissionErrors: true,\n                ignored: (p) => globSync(p, { ignore: ignored }).length === 0,\n              })\n              watcher.on('all', async (type, file) => {\n                file = slash(file)\n\n                if (\n                  options.publicDir &&\n                  isInPublicDir(options.publicDir, file)\n                ) {\n                  logger.info('CLI', `Change in public dir: ${file}`)\n                  copyPublicDir(options.publicDir, options.outDir)\n                  return\n                }\n\n                // By default we only rebuild when imported files change\n                // If you specify custom `watch`, a string or multiple strings\n                // We rebuild when those files change\n                let shouldSkipChange = false\n\n                if (options.watch === true) {\n                  if (file === 'package.json' && !buildDependencies.has(file)) {\n                    const currentHash = await getAllDepsHash(process.cwd())\n                    shouldSkipChange = currentHash === depsHash\n                    depsHash = currentHash\n                  } else if (!buildDependencies.has(file)) {\n                    shouldSkipChange = true\n                  }\n                }\n\n                if (shouldSkipChange) {\n                  return\n                }\n\n                logger.info('CLI', `Change detected: ${type} ${file}`)\n                debouncedBuildAll()\n              })\n            }\n\n            logger.info('CLI', `Target: ${options.target}`)\n\n            await buildAll()\n\n            startWatcher()\n          }\n        }\n\n        await Promise.all([dtsTask(), mainTasks()])\n      },\n    ),\n  )\n}\n"
  },
  {
    "path": "src/lib/public-dir.ts",
    "content": "import path from 'node:path'\nimport { copyDirSync } from '../fs'\nimport { slash } from '../utils'\n\nexport const copyPublicDir = (\n  publicDir: string | boolean | undefined,\n  outDir: string,\n) => {\n  if (!publicDir) return\n  copyDirSync(path.resolve(publicDir === true ? 'public' : publicDir), outDir)\n}\n\nexport const isInPublicDir = (\n  publicDir: string | boolean | undefined,\n  filePath: string,\n) => {\n  if (!publicDir) return false\n  const publicPath = slash(\n    path.resolve(publicDir === true ? 'public' : publicDir),\n  )\n  return slash(path.resolve(filePath)).startsWith(`${publicPath}/`)\n}\n"
  },
  {
    "path": "src/lib/report-size.ts",
    "content": "import colors from 'picocolors'\nimport type { Logger } from '../log'\n\nconst prettyBytes = (bytes: number) => {\n  if (bytes === 0) return '0 B'\n  const unit = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n  const exp = Math.floor(Math.log(bytes) / Math.log(1024))\n  return `${(bytes / 1024 ** exp).toFixed(2)} ${unit[exp]}`\n}\n\nconst getLengthOfLongestString = (strings: string[]) => {\n  return strings.reduce((max, str) => {\n    return Math.max(max, str.length)\n  }, 0)\n}\n\nconst padRight = (str: string, maxLength: number) => {\n  return str + ' '.repeat(maxLength - str.length)\n}\n\nexport const reportSize = (\n  logger: Logger,\n  format: string,\n  files: { [name: string]: number },\n) => {\n  const filenames = Object.keys(files)\n  const maxLength = getLengthOfLongestString(filenames) + 1\n  for (const name of filenames) {\n    logger.success(\n      format,\n      `${colors.bold(padRight(name, maxLength))}${colors.green(\n        prettyBytes(files[name]),\n      )}`,\n    )\n  }\n}\n"
  },
  {
    "path": "src/load.ts",
    "content": "import fs from 'node:fs'\nimport path from 'node:path'\nimport JoyCon from 'joycon'\nimport { bundleRequire } from 'bundle-require'\nimport { jsoncParse } from './utils'\nimport type { defineConfig } from './'\n\nconst joycon = new JoyCon()\n\nconst loadJson = async (filepath: string) => {\n  try {\n    return jsoncParse(await fs.promises.readFile(filepath, 'utf8'))\n  } catch (error) {\n    if (error instanceof Error) {\n      throw new Error(\n        `Failed to parse ${path.relative(process.cwd(), filepath)}: ${\n          error.message\n        }`,\n      )\n    } else {\n      throw error\n    }\n  }\n}\n\nconst jsonLoader = {\n  test: /\\.json$/,\n  load(filepath: string) {\n    return loadJson(filepath)\n  },\n}\n\njoycon.addLoader(jsonLoader)\n\nexport async function loadTsupConfig(\n  cwd: string,\n  configFile?: string,\n): Promise<{ path?: string; data?: ReturnType<typeof defineConfig> }> {\n  const configJoycon = new JoyCon()\n  const configPath = await configJoycon.resolve({\n    files: configFile\n      ? [configFile]\n      : [\n          'tsup.config.ts',\n          'tsup.config.cts',\n          'tsup.config.mts',\n          'tsup.config.js',\n          'tsup.config.cjs',\n          'tsup.config.mjs',\n          'tsup.config.json',\n          'package.json',\n        ],\n    cwd,\n    stopDir: path.parse(cwd).root,\n    packageKey: 'tsup',\n  })\n\n  if (configPath) {\n    if (configPath.endsWith('.json')) {\n      let data = await loadJson(configPath)\n      if (configPath.endsWith('package.json')) {\n        data = data.tsup\n      }\n      if (data) {\n        return { path: configPath, data }\n      }\n      return {}\n    }\n\n    const config = await bundleRequire({\n      filepath: configPath,\n    })\n    return {\n      path: configPath,\n      data: config.mod.tsup || config.mod.default || config.mod,\n    }\n  }\n\n  return {}\n}\n\nexport async function loadPkg(cwd: string, clearCache: boolean = false) {\n  if (clearCache) {\n    joycon.clearCache()\n  }\n  const { data } = await joycon.load(['package.json'], cwd, path.dirname(cwd))\n  return data || {}\n}\n\n/*\n * Production deps should be excluded from the bundle\n */\nexport async function getProductionDeps(\n  cwd: string,\n  clearCache: boolean = false,\n) {\n  const data = await loadPkg(cwd, clearCache)\n\n  const deps = Array.from(\n    new Set([\n      ...Object.keys(data.dependencies || {}),\n      ...Object.keys(data.peerDependencies || {}),\n    ]),\n  )\n\n  return deps\n}\n\n/**\n * Use this to determine if we should rebuild when package.json changes\n */\nexport async function getAllDepsHash(cwd: string) {\n  const data = await loadPkg(cwd, true)\n\n  return JSON.stringify({\n    ...data.dependencies,\n    ...data.peerDependencies,\n    ...data.devDependencies,\n  })\n}\n"
  },
  {
    "path": "src/log.ts",
    "content": "import util from 'node:util'\nimport { isMainThread, parentPort } from 'node:worker_threads'\nimport colors from 'picocolors'\n\ntype LOG_TYPE = 'info' | 'success' | 'error' | 'warn'\n\nexport const colorize = (type: LOG_TYPE, data: any, onlyImportant = false) => {\n  if (onlyImportant && (type === 'info' || type === 'success')) return data\n\n  const color =\n    type === 'info'\n      ? 'blue'\n      : type === 'error'\n        ? 'red'\n        : type === 'warn'\n          ? 'yellow'\n          : 'green'\n  return colors[color](data)\n}\n\nexport const makeLabel = (\n  name: string | undefined,\n  input: string,\n  type: LOG_TYPE,\n) => {\n  return [\n    name && `${colors.dim('[')}${name.toUpperCase()}${colors.dim(']')}`,\n    colorize(type, input.toUpperCase()),\n  ]\n    .filter(Boolean)\n    .join(' ')\n}\n\nlet silent = false\n\nexport function setSilent(isSilent?: boolean) {\n  silent = !!isSilent\n}\n\nexport function getSilent() {\n  return silent\n}\n\nexport type Logger = ReturnType<typeof createLogger>\n\nexport const createLogger = (name?: string) => {\n  return {\n    setName(_name: string) {\n      name = _name\n    },\n\n    success(label: string, ...args: any[]) {\n      return this.log(label, 'success', ...args)\n    },\n\n    info(label: string, ...args: any[]) {\n      return this.log(label, 'info', ...args)\n    },\n\n    error(label: string, ...args: any[]) {\n      return this.log(label, 'error', ...args)\n    },\n\n    warn(label: string, ...args: any[]) {\n      return this.log(label, 'warn', ...args)\n    },\n\n    log(\n      label: string,\n      type: 'info' | 'success' | 'error' | 'warn',\n      ...data: unknown[]\n    ) {\n      const args = [\n        makeLabel(name, label, type),\n        ...data.map((item) => colorize(type, item, true)),\n      ]\n      switch (type) {\n        case 'error': {\n          if (!isMainThread) {\n            parentPort?.postMessage({\n              type: 'error',\n              text: util.format(...args),\n            })\n            return\n          }\n\n          return console.error(...args)\n        }\n        default:\n          if (silent) return\n\n          if (!isMainThread) {\n            parentPort?.postMessage({\n              type: 'log',\n              text: util.format(...args),\n            })\n            return\n          }\n\n          console.log(...args)\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/options.ts",
    "content": "import type { BuildOptions, Plugin as EsbuildPlugin, Loader } from 'esbuild'\nimport type { InputOption } from 'rollup'\nimport type { MinifyOptions } from 'terser'\nimport type { MarkRequired } from 'ts-essentials'\nimport type { Plugin } from './plugin'\nimport type { TreeshakingStrategy } from './plugins/tree-shaking'\nimport type { SwcPluginConfig } from './esbuild/swc.js'\n\nexport type KILL_SIGNAL = 'SIGKILL' | 'SIGTERM'\n\nexport type Format = 'cjs' | 'esm' | 'iife'\n\nexport type ContextForOutPathGeneration = {\n  options: NormalizedOptions\n  format: Format\n  /** \"type\" field in project's package.json */\n  pkgType?: string\n}\n\nexport type OutExtensionObject = { js?: string; dts?: string }\n\nexport type OutExtensionFactory = (\n  ctx: ContextForOutPathGeneration,\n) => OutExtensionObject\n\nexport type DtsConfig = {\n  entry?: InputOption\n  /** Resolve external types used in dts files from node_modules */\n  resolve?: boolean | (string | RegExp)[]\n  /** Emit declaration files only */\n  only?: boolean\n  /** Insert at the top of each output .d.ts file  */\n  banner?: string\n  /** Insert at the bottom */\n  footer?: string\n  /**\n   * Overrides `compilerOptions`\n   * This option takes higher priority than `compilerOptions` in tsconfig.json\n   */\n  compilerOptions?: any\n}\n\nexport type ExperimentalDtsConfig = {\n  entry?: InputOption\n  /**\n   * Overrides `compilerOptions`\n   * This option takes higher priority than `compilerOptions` in tsconfig.json\n   */\n  compilerOptions?: any\n}\n\nexport type BannerOrFooter =\n  | {\n      js?: string\n      css?: string\n    }\n  | ((ctx: { format: Format }) => { js?: string; css?: string } | undefined)\n\nexport type BrowserTarget =\n  | 'chrome'\n  | 'deno'\n  | 'edge'\n  | 'firefox'\n  | 'hermes'\n  | 'ie'\n  | 'ios'\n  | 'node'\n  | 'opera'\n  | 'rhino'\n  | 'safari'\nexport type BrowserTargetWithVersion =\n  | `${BrowserTarget}${number}`\n  | `${BrowserTarget}${number}.${number}`\n  | `${BrowserTarget}${number}.${number}.${number}`\nexport type EsTarget =\n  | 'es3'\n  | 'es5'\n  | 'es6'\n  | 'es2015'\n  | 'es2016'\n  | 'es2017'\n  | 'es2018'\n  | 'es2019'\n  | 'es2020'\n  | 'es2021'\n  | 'es2022'\n  | 'es2023'\n  | 'es2024'\n  | 'esnext'\n\nexport type Target =\n  | BrowserTarget\n  | BrowserTargetWithVersion\n  | EsTarget\n  | (string & {})\n\nexport type Entry = string[] | Record<string, string>\n\n/**\n * The options available in tsup.config.ts\n * Not all of them are available from CLI flags\n */\nexport type Options = {\n  /** Optional config name to show in CLI output */\n  name?: string\n  /**\n   * @deprecated Use `entry` instead\n   */\n  entryPoints?: Entry\n  entry?: Entry\n  /**\n   * Output different formats to different folder instead of using different extensions\n   */\n  legacyOutput?: boolean\n  /**\n   * Compile target\n   *\n   * default to `node16`\n   */\n  target?: Target | Target[]\n  minify?: boolean | 'terser'\n  terserOptions?: MinifyOptions\n  minifyWhitespace?: boolean\n  minifyIdentifiers?: boolean\n  minifySyntax?: boolean\n  keepNames?: boolean\n  watch?: boolean | string | (string | boolean)[]\n  ignoreWatch?: string[] | string\n  onSuccess?:\n    | string\n    | (() => Promise<void | undefined | (() => void | Promise<void>)>)\n  jsxFactory?: string\n  jsxFragment?: string\n  outDir?: string\n  outExtension?: OutExtensionFactory\n  format?: Format[] | Format\n  globalName?: string\n  env?: {\n    [k: string]: string\n  }\n  define?: {\n    [k: string]: string\n  }\n  dts?: boolean | string | DtsConfig\n  experimentalDts?: boolean | string | ExperimentalDtsConfig\n  sourcemap?: boolean | 'inline'\n  /** Always bundle modules matching given patterns */\n  noExternal?: (string | RegExp)[]\n  /** Don't bundle these modules */\n  external?: (string | RegExp)[]\n  /**\n   * Replace `process.env.NODE_ENV` with `production` or `development`\n   * `production` when the bundled is minified, `development` otherwise\n   */\n  replaceNodeEnv?: boolean\n  /**\n   * Code splitting\n   * Default to `true` for ESM, `false` for CJS.\n   *\n   * You can set it to `true` explicitly, and may want to disable code splitting sometimes: [`#255`](https://github.com/egoist/tsup/issues/255)\n   */\n  splitting?: boolean\n  /**\n   * Clean output directory before each build\n   */\n  clean?: boolean | string[]\n  esbuildPlugins?: EsbuildPlugin[]\n  esbuildOptions?: (options: BuildOptions, context: { format: Format }) => void\n  /**\n   * Suppress non-error logs (excluding \"onSuccess\" process output)\n   */\n  silent?: boolean\n  /**\n   * Skip node_modules bundling\n   * Will still bundle modules matching the `noExternal` option\n   */\n  skipNodeModulesBundle?: boolean\n  /**\n   * @see https://esbuild.github.io/api/#pure\n   */\n  pure?: string | string[]\n  /**\n   * Disable bundling, default to true\n   */\n  bundle?: boolean\n  /**\n   * This option allows you to automatically replace a global variable with an import from another file.\n   * @see https://esbuild.github.io/api/#inject\n   */\n  inject?: string[]\n  /**\n   * Emit esbuild metafile\n   * @see https://esbuild.github.io/api/#metafile\n   */\n  metafile?: boolean\n  footer?: BannerOrFooter\n  banner?: BannerOrFooter\n  /**\n   * Target platform\n   * @default `node`\n   */\n  platform?: 'node' | 'browser' | 'neutral'\n  /**\n   * Esbuild loader option\n   */\n  loader?: Record<string, Loader>\n  /**\n   * Disable config file with `false`\n   * Or pass a custom config filename\n   */\n  config?: boolean | string\n  /**\n   * Use a custom tsconfig\n   */\n  tsconfig?: string\n  /**\n   * Inject CSS as style tags to document head\n   * @default {false}\n   */\n  injectStyle?:\n    | boolean\n    | ((css: string, fileId: string) => string | Promise<string>)\n  /**\n   * Inject cjs and esm shims if needed\n   * @default false\n   */\n  shims?: boolean\n  /**\n   * TSUP plugins\n   * @experimental\n   * @alpha\n   */\n  plugins?: Plugin[]\n  /**\n   * By default esbuild already does treeshaking\n   *\n   * But this option allow you to perform additional treeshaking with Rollup\n   *\n   * This can result in smaller bundle size\n   */\n  treeshake?: TreeshakingStrategy\n  /**\n   * Copy the files inside `publicDir` to output directory\n   */\n  publicDir?: string | boolean\n  killSignal?: KILL_SIGNAL\n  /**\n   * Interop default within `module.exports` in cjs\n   * @default false\n   */\n  cjsInterop?: boolean\n\n  /**\n   * Remove `node:` protocol from imports\n   *\n   * The default value will be flipped to `false` in the next major release\n   * @default true\n   */\n  removeNodeProtocol?: boolean\n  \n  swc?: SwcPluginConfig;\n}\n\nexport interface NormalizedExperimentalDtsConfig {\n  entry: { [entryAlias: string]: string }\n  compilerOptions?: any\n}\n\nexport type NormalizedOptions = Omit<\n  MarkRequired<Options, 'entry' | 'outDir'>,\n  'dts' | 'experimentalDts' | 'format'\n> & {\n  dts?: DtsConfig\n  experimentalDts?: NormalizedExperimentalDtsConfig\n  tsconfigResolvePaths: Record<string, string[]>\n  tsconfigDecoratorMetadata?: boolean\n  format: Format[]\n  swc?: SwcPluginConfig\n}\n"
  },
  {
    "path": "src/plugin.ts",
    "content": "import path from 'node:path'\nimport {\n  type RawSourceMap,\n  SourceMapConsumer,\n  SourceMapGenerator,\n} from 'source-map'\nimport { outputFile } from './fs'\nimport type {\n  BuildOptions as EsbuildOptions,\n  Metafile,\n  OutputFile,\n} from 'esbuild'\nimport type { Format, NormalizedOptions } from '.'\nimport type { Logger } from './log'\nimport { slash, type MaybePromise } from './utils'\nimport type { SourceMap } from 'rollup'\n\nexport type ChunkInfo = {\n  type: 'chunk'\n  code: string\n  map?: string | RawSourceMap | null\n  path: string\n  /**\n   * Sets the file mode\n   */\n  mode?: number\n  entryPoint?: string\n  exports?: string[]\n  imports?: Metafile['outputs'][string]['imports']\n}\n\nexport type AssetInfo = {\n  type: 'asset'\n  path: string\n  contents: Uint8Array\n}\n\nexport type RenderChunk = (\n  this: PluginContext,\n  code: string,\n  chunkInfo: ChunkInfo,\n) => MaybePromise<\n  | {\n      code: string\n      map?: object | string | SourceMap | null\n    }\n  | undefined\n  | null\n  | void\n>\n\nexport type BuildStart = (this: PluginContext) => MaybePromise<void>\nexport type BuildEnd = (\n  this: PluginContext,\n  ctx: { writtenFiles: WrittenFile[] },\n) => MaybePromise<void>\n\nexport type ModifyEsbuildOptions = (\n  this: PluginContext,\n  options: EsbuildOptions,\n) => void\n\nexport type Plugin = {\n  name: string\n\n  esbuildOptions?: ModifyEsbuildOptions\n\n  buildStart?: BuildStart\n\n  renderChunk?: RenderChunk\n\n  buildEnd?: BuildEnd\n}\n\nexport type PluginContext = {\n  format: Format\n  splitting?: boolean\n  options: NormalizedOptions\n  logger: Logger\n}\n\nexport type WrittenFile = { readonly name: string; readonly size: number }\n\nconst parseSourceMap = (map?: string | object | null) => {\n  return typeof map === 'string' ? JSON.parse(map) : map\n}\n\nconst isJS = (path: string) => /\\.(js|mjs|cjs)$/.test(path)\nconst isCSS = (path: string) => /\\.css$/.test(path)\n\nexport class PluginContainer {\n  plugins: Plugin[]\n  context?: PluginContext\n\n  constructor(plugins: Plugin[]) {\n    this.plugins = plugins\n  }\n\n  setContext(context: PluginContext) {\n    this.context = context\n  }\n\n  getContext() {\n    if (!this.context) throw new Error(`Plugin context is not set`)\n    return this.context\n  }\n\n  modifyEsbuildOptions(options: EsbuildOptions) {\n    for (const plugin of this.plugins) {\n      if (plugin.esbuildOptions) {\n        plugin.esbuildOptions.call(this.getContext(), options)\n      }\n    }\n  }\n\n  async buildStarted() {\n    for (const plugin of this.plugins) {\n      if (plugin.buildStart) {\n        await plugin.buildStart.call(this.getContext())\n      }\n    }\n  }\n\n  async buildFinished({\n    outputFiles,\n    metafile,\n  }: {\n    outputFiles: OutputFile[]\n    metafile?: Metafile\n  }) {\n    const files: Array<ChunkInfo | AssetInfo> = outputFiles\n      .filter((file) => !file.path.endsWith('.map'))\n      .map((file): ChunkInfo | AssetInfo => {\n        if (isJS(file.path) || isCSS(file.path)) {\n          const relativePath = slash(path.relative(process.cwd(), file.path))\n          const meta = metafile?.outputs[relativePath]\n          return {\n            type: 'chunk',\n            path: file.path,\n            code: file.text,\n            map: outputFiles.find((f) => f.path === `${file.path}.map`)?.text,\n            entryPoint: meta?.entryPoint,\n            exports: meta?.exports,\n            imports: meta?.imports,\n          }\n        } else {\n          return { type: 'asset', path: file.path, contents: file.contents }\n        }\n      })\n\n    const writtenFiles: WrittenFile[] = []\n\n    await Promise.all(\n      files.map(async (info) => {\n        for (const plugin of this.plugins) {\n          if (info.type === 'chunk' && plugin.renderChunk) {\n            const result = await plugin.renderChunk.call(\n              this.getContext(),\n              info.code,\n              info,\n            )\n            if (result) {\n              info.code = result.code\n              if (result.map) {\n                const originalConsumer = await new SourceMapConsumer(\n                  parseSourceMap(info.map),\n                )\n                const newConsumer = await new SourceMapConsumer(\n                  parseSourceMap(result.map),\n                )\n                const generator = SourceMapGenerator.fromSourceMap(newConsumer)\n                generator.applySourceMap(originalConsumer, info.path)\n                info.map = generator.toJSON()\n                originalConsumer.destroy()\n                newConsumer.destroy()\n              }\n            }\n          }\n        }\n\n        const inlineSourceMap = this.context!.options.sourcemap === 'inline'\n        const contents =\n          info.type === 'chunk'\n            ? info.code +\n              getSourcemapComment(\n                inlineSourceMap,\n                info.map,\n                info.path,\n                isCSS(info.path),\n              )\n            : info.contents\n        await outputFile(info.path, contents, {\n          mode: info.type === 'chunk' ? info.mode : undefined,\n        })\n        writtenFiles.push({\n          get name() {\n            return path.relative(process.cwd(), info.path)\n          },\n          get size() {\n            return contents.length\n          },\n        })\n        if (info.type === 'chunk' && info.map && !inlineSourceMap) {\n          const map =\n            typeof info.map === 'string' ? JSON.parse(info.map) : info.map\n          const outPath = `${info.path}.map`\n          const contents = JSON.stringify(map)\n          await outputFile(outPath, contents)\n          writtenFiles.push({\n            get name() {\n              return path.relative(process.cwd(), outPath)\n            },\n            get size() {\n              return contents.length\n            },\n          })\n        }\n      }),\n    )\n\n    for (const plugin of this.plugins) {\n      if (plugin.buildEnd) {\n        await plugin.buildEnd.call(this.getContext(), { writtenFiles })\n      }\n    }\n  }\n}\n\nconst getSourcemapComment = (\n  inline: boolean,\n  map: RawSourceMap | string | null | undefined,\n  filepath: string,\n  isCssFile: boolean,\n) => {\n  if (!map) return ''\n  const prefix = isCssFile ? '/*' : '//'\n  const suffix = isCssFile ? ' */' : ''\n  const url = inline\n    ? `data:application/json;base64,${Buffer.from(\n        typeof map === 'string' ? map : JSON.stringify(map),\n      ).toString('base64')}`\n    : `${path.basename(filepath)}.map`\n  return `${prefix}# sourceMappingURL=${url}${suffix}`\n}\n"
  },
  {
    "path": "src/plugins/cjs-interop.ts",
    "content": "import type { Plugin } from '../plugin'\n\nexport const cjsInterop = (): Plugin => {\n  return {\n    name: 'cjs-interop',\n\n    renderChunk(code, info) {\n      if (\n        !this.options.cjsInterop ||\n        this.format !== 'cjs' ||\n        info.type !== 'chunk' ||\n        !/\\.(js|cjs)$/.test(info.path) ||\n        !info.entryPoint ||\n        info.exports?.length !== 1 ||\n        info.exports[0] !== 'default'\n      ) {\n        return\n      }\n\n      return {\n        code: `${code}\\nmodule.exports = exports.default;\\n`,\n        map: info.map,\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/plugins/cjs-splitting.ts",
    "content": "// Workaround to enable code splitting for cjs format\n// Manually transform esm to cjs\n// TODO: remove this once esbuild supports code splitting for cjs natively\nimport type { Plugin } from '../plugin'\n\nexport const cjsSplitting = (): Plugin => {\n  return {\n    name: 'cjs-splitting',\n\n    async renderChunk(code, info) {\n      if (\n        !this.splitting ||\n        this.options.treeshake || // <-- handled by rollup\n        this.format !== 'cjs' ||\n        info.type !== 'chunk' ||\n        !/\\.(js|cjs)$/.test(info.path)\n      ) {\n        return\n      }\n\n      const { transform } = await import('sucrase')\n\n      const result = transform(code, {\n        filePath: info.path,\n        transforms: ['imports'],\n        sourceMapOptions: this.options.sourcemap\n          ? {\n              compiledFilename: info.path,\n            }\n          : undefined,\n      })\n\n      return {\n        code: result.code,\n        map: result.sourceMap,\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/plugins/shebang.ts",
    "content": "import type { Plugin } from '../plugin'\n\nexport const shebang = (): Plugin => {\n  return {\n    name: 'shebang',\n\n    renderChunk(_, info) {\n      if (\n        info.type === 'chunk' &&\n        /\\.(cjs|js|mjs)$/.test(info.path) &&\n        info.code.startsWith('#!')\n      ) {\n        info.mode = 0o755\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/plugins/size-reporter.ts",
    "content": "import { reportSize } from '../lib/report-size'\nimport type { Plugin } from '../plugin'\n\nexport const sizeReporter = (): Plugin => {\n  return {\n    name: 'size-reporter',\n\n    buildEnd({ writtenFiles }) {\n      reportSize(\n        this.logger,\n        this.format,\n        writtenFiles.reduce((res, file) => {\n          return {\n            ...res,\n            [file.name]: file.size,\n          }\n        }, {}),\n      )\n    },\n  }\n}\n"
  },
  {
    "path": "src/plugins/swc-target.ts",
    "content": "import { PrettyError } from '../errors'\nimport { localRequire } from '../utils'\nimport type { ModuleConfig } from '@swc/core'\nimport type { Plugin } from '../plugin'\n\nconst TARGETS = ['es5', 'es3'] as const\n\nexport const swcTarget = (): Plugin => {\n  let enabled = false\n  let target: (typeof TARGETS)[number]\n\n  return {\n    name: 'swc-target',\n\n    esbuildOptions(options) {\n      if (\n        typeof options.target === 'string' &&\n        TARGETS.includes(options.target as any)\n      ) {\n        target = options.target as any\n        options.target = 'es2020'\n        enabled = true\n      }\n    },\n\n    async renderChunk(code, info) {\n      if (!enabled || !/\\.(cjs|mjs|js)$/.test(info.path)) {\n        return\n      }\n      const swc: typeof import('@swc/core') = localRequire('@swc/core')\n\n      if (!swc) {\n        throw new PrettyError(\n          `@swc/core is required for ${target} target. Please install it with \\`npm install @swc/core -D\\``,\n        )\n      }\n\n      const result = await swc.transform(code, {\n        filename: info.path,\n        sourceMaps: this.options.sourcemap,\n        minify: Boolean(this.options.minify),\n        jsc: {\n          target,\n          parser: {\n            syntax: 'ecmascript',\n          },\n          minify:\n            this.options.minify === true\n              ? {\n                  compress: false,\n                  mangle: {\n                    reserved: this.options.globalName\n                      ? [this.options.globalName]\n                      : [],\n                  },\n                }\n              : undefined,\n        },\n        module: {\n          type: this.format === 'cjs' ? 'commonjs' : 'es6',\n        } satisfies ModuleConfig,\n      })\n      return {\n        code: result.code,\n        map: result.map,\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/plugins/terser.ts",
    "content": "import { PrettyError } from '../errors'\nimport { localRequire } from '../utils'\nimport type { MinifyOptions } from 'terser'\nimport type { Logger } from '../log'\nimport type { Format, Options } from '../options'\nimport type { Plugin } from '../plugin'\n\nexport const terserPlugin = ({\n  minifyOptions,\n  format,\n  terserOptions = {},\n  globalName,\n  logger,\n}: {\n  minifyOptions: Options['minify']\n  format: Format\n  terserOptions?: MinifyOptions\n  globalName?: string\n  logger: Logger\n}): Plugin => {\n  return {\n    name: 'terser',\n\n    async renderChunk(code, info) {\n      if (minifyOptions !== 'terser' || !/\\.(cjs|js|mjs)$/.test(info.path))\n        return\n\n      const terser: typeof import('terser') | undefined = localRequire('terser')\n\n      if (!terser) {\n        throw new PrettyError(\n          'terser is required for terser minification. Please install it with `npm install terser -D`',\n        )\n      }\n\n      const { minify } = terser\n\n      const defaultOptions: MinifyOptions = {}\n\n      if (format === 'esm') {\n        defaultOptions.module = true\n      } else if (!(format === 'iife' && globalName !== undefined)) {\n        defaultOptions.toplevel = true\n      }\n\n      try {\n        const minifiedOutput = await minify(\n          { [info.path]: code },\n          { ...defaultOptions, ...terserOptions },\n        )\n\n        logger.info('TERSER', 'Minifying with Terser')\n\n        if (!minifiedOutput.code) {\n          logger.error('TERSER', 'Failed to minify with terser')\n        }\n\n        logger.success('TERSER', 'Terser Minification success')\n\n        return { code: minifiedOutput.code!, map: minifiedOutput.map }\n      } catch (error) {\n        logger.error('TERSER', 'Failed to minify with terser')\n        logger.error('TERSER', error)\n      }\n\n      return { code, map: info.map }\n    },\n  }\n}\n"
  },
  {
    "path": "src/plugins/tree-shaking.ts",
    "content": "import path from 'node:path'\nimport { type TreeshakingOptions, type TreeshakingPreset, rollup } from 'rollup'\nimport type { Plugin } from '../plugin'\n\nexport type TreeshakingStrategy =\n  | boolean\n  | TreeshakingOptions\n  | TreeshakingPreset\n\nexport const treeShakingPlugin = ({\n  treeshake,\n  name,\n  silent,\n}: {\n  treeshake?: TreeshakingStrategy\n  name?: string\n  silent?: boolean\n}): Plugin => {\n  return {\n    name: 'tree-shaking',\n\n    async renderChunk(code, info) {\n      if (!treeshake || !/\\.(cjs|js|mjs)$/.test(info.path)) return\n\n      const bundle = await rollup({\n        input: [info.path],\n        plugins: [\n          {\n            name: 'tsup',\n            resolveId(source) {\n              if (source === info.path) return source\n              return false\n            },\n            load(id) {\n              if (id === info.path) return { code, map: info.map }\n            },\n          },\n        ],\n        treeshake,\n        makeAbsoluteExternalsRelative: false,\n        preserveEntrySignatures: 'exports-only',\n        onwarn: silent ? () => {} : undefined,\n      })\n\n      const result = await bundle.generate({\n        interop: 'auto',\n        format: this.format,\n        file: info.path,\n        sourcemap: !!this.options.sourcemap,\n        compact: !!this.options.minify,\n        name,\n      })\n\n      for (const file of result.output) {\n        if (\n          file.type === 'chunk' &&\n          file.fileName === path.basename(info.path)\n        ) {\n          return {\n            code: file.code,\n            map: file.map,\n          }\n        }\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "src/rollup/ts-resolve.ts",
    "content": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { builtinModules } from 'node:module'\nimport _resolve from 'resolve'\nimport createDebug from 'debug'\nimport type { PluginImpl } from 'rollup'\n\nconst debug = createDebug('tsup:ts-resolve')\n\nconst resolveModule = (\n  id: string,\n  opts: _resolve.AsyncOpts,\n): Promise<string | null> =>\n  new Promise((resolve, reject) => {\n    _resolve(id, opts, (err, res) => {\n      // @ts-expect-error error code is not typed\n      if (err?.code === 'MODULE_NOT_FOUND') return resolve(null)\n      if (err) return reject(err)\n      resolve(res || null)\n    })\n  })\n\nexport type TsResolveOptions = {\n  resolveOnly?: Array<string | RegExp>\n  ignore?: (source: string, importer?: string) => boolean\n}\n\nexport const tsResolvePlugin: PluginImpl<TsResolveOptions> = ({\n  resolveOnly,\n  ignore,\n} = {}) => {\n  const resolveExtensions = ['.d.ts', '.ts']\n\n  return {\n    name: `ts-resolve`,\n\n    async resolveId(source, importer) {\n      debug('resolveId source: %s', source)\n      debug('resolveId importer: %s ', importer)\n\n      if (!importer) return null\n\n      // ignore IDs with null character, these belong to other plugins\n      if (/\\0/.test(source)) return null\n\n      if (builtinModules.includes(source)) return false\n\n      if (ignore && ignore(source, importer)) {\n        debug('ignored %s', source)\n        return null\n      }\n\n      if (resolveOnly) {\n        const shouldResolve = resolveOnly.some((v) => {\n          if (typeof v === 'string') return v === source\n          return v.test(source)\n        })\n        if (!shouldResolve) {\n          debug('skipped by matching resolveOnly: %s', source)\n          return null\n        }\n      }\n\n      // Skip absolute path\n      if (path.isAbsolute(source)) {\n        debug(`skipped absolute path: %s`, source)\n        return null\n      }\n\n      const basedir = importer\n        ? await fs.promises.realpath(path.dirname(importer))\n        : process.cwd()\n\n      // A relative path\n      if (source[0] === '.') {\n        return resolveModule(source, {\n          basedir,\n          extensions: resolveExtensions,\n        })\n      }\n\n      let id: string | null = null\n\n      // Try resolving as relative path if `importer` is not present\n      if (!importer) {\n        id = await resolveModule(`./${source}`, {\n          basedir,\n          extensions: resolveExtensions,\n        })\n      }\n\n      // Try resolving in node_modules\n      if (!id) {\n        id = await resolveModule(source, {\n          basedir,\n          extensions: resolveExtensions,\n          packageFilter(pkg) {\n            pkg.main = pkg.types || pkg.typings\n            return pkg\n          },\n          paths: ['node_modules', 'node_modules/@types'],\n        })\n      }\n\n      if (id) {\n        debug('resolved %s to %s', source, id)\n        return id\n      }\n\n      debug('mark %s as external', source)\n      // Just make it external if can't be resolved, i.e. tsconfig path alias\n      return false\n    },\n  }\n}\n"
  },
  {
    "path": "src/rollup.ts",
    "content": "import { parentPort } from 'node:worker_threads'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport jsonPlugin from '@rollup/plugin-json'\nimport resolveFrom from 'resolve-from'\nimport { handleError } from './errors'\nimport { defaultOutExtension, removeFiles, toObjectEntry } from './utils'\nimport { type TsResolveOptions, tsResolvePlugin } from './rollup/ts-resolve'\nimport { createLogger, setSilent } from './log'\nimport { getProductionDeps, loadPkg } from './load'\nimport { reportSize } from './lib/report-size'\nimport type { NormalizedOptions } from './'\nimport type { InputOptions, OutputOptions, Plugin } from 'rollup'\nimport { FixDtsDefaultCjsExportsPlugin } from 'fix-dts-default-cjs-exports/rollup'\n\nconst logger = createLogger()\n\nconst parseCompilerOptions = (compilerOptions?: any) => {\n  if (!compilerOptions) return {}\n  const { options } = ts.parseJsonConfigFileContent(\n    { compilerOptions },\n    ts.sys,\n    './',\n  )\n  return options\n}\n\n// Use `require` to esbuild use the cjs build of rollup-plugin-dts\n// the mjs build of rollup-plugin-dts uses `import.meta.url` which makes Node throws syntax error\n// since tsup is published as a commonjs module for now\nconst dtsPlugin: typeof import('rollup-plugin-dts') = require('rollup-plugin-dts')\n\ntype RollupConfig = {\n  inputConfig: InputOptions\n  outputConfig: OutputOptions[]\n}\n\nconst getRollupConfig = async (\n  options: NormalizedOptions,\n): Promise<RollupConfig> => {\n  setSilent(options.silent)\n\n  const compilerOptions = parseCompilerOptions(options.dts?.compilerOptions)\n\n  const dtsOptions = options.dts || {}\n  dtsOptions.entry = dtsOptions.entry || options.entry\n\n  if (Array.isArray(dtsOptions.entry) && dtsOptions.entry.length > 1) {\n    dtsOptions.entry = toObjectEntry(dtsOptions.entry)\n  }\n\n  let tsResolveOptions: TsResolveOptions | undefined\n\n  if (dtsOptions.resolve) {\n    tsResolveOptions = {}\n    // Only resolve specific types when `dts.resolve` is an array\n    if (Array.isArray(dtsOptions.resolve)) {\n      tsResolveOptions.resolveOnly = dtsOptions.resolve\n    }\n\n    // `paths` should be handled by rollup-plugin-dts\n    if (compilerOptions.paths) {\n      const res = Object.keys(compilerOptions.paths).map(\n        (p) => new RegExp(`^${p.replace('*', '.+')}$`),\n      )\n      tsResolveOptions.ignore = (source) => {\n        return res.some((re) => re.test(source))\n      }\n    }\n  }\n\n  const pkg = await loadPkg(process.cwd())\n  const deps = await getProductionDeps(process.cwd())\n\n  const tsupCleanPlugin: Plugin = {\n    name: 'tsup:clean',\n    async buildStart() {\n      if (options.clean) {\n        await removeFiles(['**/*.d.{ts,mts,cts}'], options.outDir)\n      }\n    },\n  }\n\n  const ignoreFiles: Plugin = {\n    name: 'tsup:ignore-files',\n    load(id) {\n      if (!/\\.(js|cjs|mjs|jsx|ts|tsx|mts|json)$/.test(id)) {\n        return ''\n      }\n    },\n  }\n\n  return {\n    inputConfig: {\n      input: dtsOptions.entry,\n      onwarn(warning, handler) {\n        if (\n          warning.code === 'UNRESOLVED_IMPORT' ||\n          warning.code === 'CIRCULAR_DEPENDENCY' ||\n          warning.code === 'EMPTY_BUNDLE'\n        ) {\n          return\n        }\n        return handler(warning)\n      },\n      plugins: [\n        tsupCleanPlugin,\n        tsResolveOptions && tsResolvePlugin(tsResolveOptions),\n        jsonPlugin(),\n        ignoreFiles,\n        dtsPlugin.default({\n          tsconfig: options.tsconfig,\n          compilerOptions: {\n            ...compilerOptions,\n            baseUrl: compilerOptions.baseUrl || '.',\n            // Ensure \".d.ts\" modules are generated\n            declaration: true,\n            // Skip \".js\" generation\n            noEmit: false,\n            emitDeclarationOnly: true,\n            // Skip code generation when error occurs\n            noEmitOnError: true,\n            // Avoid extra work\n            checkJs: false,\n            declarationMap: false,\n            skipLibCheck: true,\n            preserveSymlinks: false,\n            // Ensure we can parse the latest code\n            target: ts.ScriptTarget.ESNext,\n          },\n        }),\n      ].filter(Boolean),\n      external: [\n        // Exclude dependencies, e.g. `lodash`, `lodash/get`\n        ...deps.map((dep) => new RegExp(`^${dep}($|\\\\/|\\\\\\\\)`)),\n        ...(options.external || []),\n      ],\n    },\n    outputConfig: options.format.map((format): OutputOptions => {\n      const outputExtension =\n        options.outExtension?.({ format, options, pkgType: pkg.type }).dts ||\n        defaultOutExtension({ format, pkgType: pkg.type }).dts\n      return {\n        dir: options.outDir || 'dist',\n        format: 'esm',\n        exports: 'named',\n        banner: dtsOptions.banner,\n        footer: dtsOptions.footer,\n        entryFileNames: `[name]${outputExtension}`,\n        chunkFileNames: `[name]-[hash]${outputExtension}`,\n        plugins: [\n          format === 'cjs' &&\n            options.cjsInterop &&\n            FixDtsDefaultCjsExportsPlugin(),\n        ].filter(Boolean),\n      }\n    }),\n  }\n}\n\nasync function runRollup(options: RollupConfig) {\n  const { rollup } = await import('rollup')\n  try {\n    const start = Date.now()\n    const getDuration = () => {\n      return `${Math.floor(Date.now() - start)}ms`\n    }\n    logger.info('dts', 'Build start')\n    const bundle = await rollup(options.inputConfig)\n    const results = await Promise.all(options.outputConfig.map(bundle.write))\n    const outputs = results.flatMap((result) => result.output)\n    logger.success('dts', `⚡️ Build success in ${getDuration()}`)\n    reportSize(\n      logger,\n      'dts',\n      outputs.reduce((res, info) => {\n        const name = path.relative(\n          process.cwd(),\n          path.join(options.outputConfig[0].dir || '.', info.fileName),\n        )\n        return {\n          ...res,\n          [name]: info.type === 'chunk' ? info.code.length : info.source.length,\n        }\n      }, {}),\n    )\n  } catch (error) {\n    handleError(error)\n    logger.error('dts', 'Build error')\n  }\n}\n\nasync function watchRollup(options: {\n  inputConfig: InputOptions\n  outputConfig: OutputOptions[]\n}) {\n  const { watch } = await import('rollup')\n\n  watch({\n    ...options.inputConfig,\n    plugins: options.inputConfig.plugins,\n    output: options.outputConfig,\n  }).on('event', (event) => {\n    if (event.code === 'START') {\n      logger.info('dts', 'Build start')\n    } else if (event.code === 'BUNDLE_END') {\n      logger.success('dts', `⚡️ Build success in ${event.duration}ms`)\n      parentPort?.postMessage('success')\n    } else if (event.code === 'ERROR') {\n      logger.error('dts', 'Build failed')\n      handleError(event.error)\n    }\n  })\n}\n\nconst startRollup = async (options: NormalizedOptions) => {\n  const config = await getRollupConfig(options)\n  if (options.watch) {\n    watchRollup(config)\n  } else {\n    try {\n      await runRollup(config)\n      parentPort?.postMessage('success')\n    } catch {\n      parentPort?.postMessage('error')\n    }\n  }\n}\n\nparentPort?.on('message', (data) => {\n  logger.setName(data.configName)\n  const hasTypescript = resolveFrom.silent(process.cwd(), 'typescript')\n  if (!hasTypescript) {\n    logger.error('dts', `You need to install \"typescript\" in your project`)\n    parentPort?.postMessage('error')\n    return\n  }\n  startRollup(data.options)\n})\n"
  },
  {
    "path": "src/run.ts",
    "content": "import { spawn } from 'node:child_process'\n\nexport function runCode(filename: string, { args }: { args: string[] }) {\n  const cmd = spawn('node', [filename, ...args], {\n    stdio: 'inherit',\n  })\n  cmd.on('exit', (code) => {\n    process.exitCode = code || 0\n  })\n}\n"
  },
  {
    "path": "src/tsc.ts",
    "content": "import { dirname } from 'node:path'\nimport { loadTsConfig } from 'bundle-require'\nimport ts from 'typescript'\nimport { handleError } from './errors'\nimport { createLogger } from './log'\nimport { ensureTempDeclarationDir, toAbsolutePath } from './utils'\nimport type { ExportDeclaration } from './exports'\nimport type { NormalizedOptions } from './options'\n\nconst logger = createLogger()\n\nclass AliasPool {\n  private seen = new Set<string>()\n\n  assign(name: string): string {\n    let suffix = 0\n    let alias = name === 'default' ? 'default_alias' : name\n\n    while (this.seen.has(alias)) {\n      alias = `${name}_alias_${++suffix}`\n      if (suffix >= 1000) {\n        throw new Error(\n          'Alias generation exceeded limit. Possible infinite loop detected.',\n        )\n      }\n    }\n\n    this.seen.add(alias)\n    return alias\n  }\n}\n\n/**\n * Get all export declarations from root files.\n */\nfunction getExports(\n  program: ts.Program,\n  fileMapping: Map<string, string>,\n): ExportDeclaration[] {\n  const checker = program.getTypeChecker()\n  const aliasPool = new AliasPool()\n  const assignAlias = aliasPool.assign.bind(aliasPool)\n\n  function extractExports(sourceFileName: string): ExportDeclaration[] {\n    const cwd = program.getCurrentDirectory()\n    sourceFileName = toAbsolutePath(sourceFileName, cwd)\n\n    const sourceFile = program.getSourceFile(sourceFileName)\n    if (!sourceFile) {\n      return []\n    }\n\n    const destFileName = fileMapping.get(sourceFileName)\n    if (!destFileName) {\n      return []\n    }\n\n    const moduleSymbol = checker.getSymbolAtLocation(sourceFile)\n    if (!moduleSymbol) {\n      return []\n    }\n\n    const exports: ExportDeclaration[] = []\n\n    const exportSymbols = checker.getExportsOfModule(moduleSymbol)\n    exportSymbols.forEach((symbol) => {\n      const name = symbol.getName()\n      exports.push({\n        kind: 'named',\n        sourceFileName,\n        destFileName,\n        name,\n        alias: assignAlias(name),\n        isTypeOnly: false,\n      })\n    })\n\n    return exports\n  }\n\n  return program.getRootFileNames().flatMap(extractExports)\n}\n\n/**\n * Use TypeScript compiler to emit declaration files.\n *\n * @returns The mapping from source TS file paths to output declaration file paths\n */\nfunction emitDtsFiles(program: ts.Program, host: ts.CompilerHost) {\n  const fileMapping = new Map<string, string>()\n\n  const writeFile: ts.WriteFileCallback = (\n    fileName,\n    text,\n    writeByteOrderMark,\n    onError,\n    sourceFiles,\n    data,\n  ) => {\n    const sourceFile = sourceFiles?.[0]\n    const sourceFileName = sourceFile?.fileName\n\n    if (sourceFileName && !fileName.endsWith('.map')) {\n      const cwd = program.getCurrentDirectory()\n      fileMapping.set(\n        toAbsolutePath(sourceFileName, cwd),\n        toAbsolutePath(fileName, cwd),\n      )\n    }\n\n    return host.writeFile(\n      fileName,\n      text,\n      writeByteOrderMark,\n      onError,\n      sourceFiles,\n      data,\n    )\n  }\n\n  const emitResult = program.emit(undefined, writeFile, undefined, true)\n\n  const diagnostics = ts\n    .getPreEmitDiagnostics(program)\n    .concat(emitResult.diagnostics)\n\n  const diagnosticMessages: string[] = []\n\n  diagnostics.forEach((diagnostic) => {\n    if (diagnostic.file) {\n      const { line, character } = ts.getLineAndCharacterOfPosition(\n        diagnostic.file,\n        diagnostic.start!,\n      )\n      const message = ts.flattenDiagnosticMessageText(\n        diagnostic.messageText,\n        '\\n',\n      )\n      diagnosticMessages.push(\n        `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`,\n      )\n    } else {\n      const message = ts.flattenDiagnosticMessageText(\n        diagnostic.messageText,\n        '\\n',\n      )\n      diagnosticMessages.push(message)\n    }\n  })\n\n  const diagnosticMessage = diagnosticMessages.join('\\n')\n  if (diagnosticMessage) {\n    logger.error(\n      'TSC',\n      `Failed to emit declaration files.\\n\\n${diagnosticMessage}`,\n    )\n    throw new Error('TypeScript compilation failed')\n  }\n\n  return fileMapping\n}\n\nfunction emit(compilerOptions?: any, tsconfig?: string) {\n  const cwd = process.cwd()\n  const rawTsconfig = loadTsConfig(cwd, tsconfig)\n  if (!rawTsconfig) {\n    throw new Error(`Unable to find ${tsconfig || 'tsconfig.json'} in ${cwd}`)\n  }\n\n  const declarationDir = ensureTempDeclarationDir()\n\n  const parsedTsconfig = ts.parseJsonConfigFileContent(\n    {\n      ...rawTsconfig.data,\n      compilerOptions: {\n        ...rawTsconfig.data?.compilerOptions,\n        ...compilerOptions,\n\n        // Enable declaration emit and disable javascript emit\n        noEmit: false,\n        declaration: true,\n        declarationMap: true,\n        declarationDir,\n        emitDeclarationOnly: true,\n      },\n    },\n    ts.sys,\n    tsconfig ? dirname(tsconfig) : './',\n  )\n\n  const options: ts.CompilerOptions = parsedTsconfig.options\n\n  const host: ts.CompilerHost = ts.createCompilerHost(options)\n  const program: ts.Program = ts.createProgram(\n    parsedTsconfig.fileNames,\n    options,\n    host,\n  )\n\n  const fileMapping = emitDtsFiles(program, host)\n  return getExports(program, fileMapping)\n}\n\nexport function runTypeScriptCompiler(options: NormalizedOptions) {\n  try {\n    const start = Date.now()\n    const getDuration = () => {\n      return `${Math.floor(Date.now() - start)}ms`\n    }\n    logger.info('tsc', 'Build start')\n    const dtsOptions = options.experimentalDts!\n    const exports = emit(dtsOptions.compilerOptions, options.tsconfig)\n    logger.success('tsc', `⚡️ Build success in ${getDuration()}`)\n    return exports\n  } catch (error) {\n    handleError(error)\n    logger.error('tsc', 'Build error')\n  }\n}\n"
  },
  {
    "path": "src/utils.ts",
    "content": "import fs from 'node:fs'\nimport path from 'node:path'\nimport resolveFrom from 'resolve-from'\nimport type { InputOption } from 'rollup'\nimport strip from 'strip-json-comments'\nimport { glob } from 'tinyglobby'\nimport type {\n  Entry,\n  Format,\n  NormalizedExperimentalDtsConfig,\n  NormalizedOptions,\n  Options,\n} from './options'\n\nexport type MaybePromise<T> = T | Promise<T>\n\nexport type External =\n  | string\n  | RegExp\n  | ((id: string, parentId?: string) => boolean)\n\nexport function isExternal(\n  externals: External | External[],\n  id: string,\n  parentId?: string,\n) {\n  id = slash(id)\n\n  if (!Array.isArray(externals)) {\n    externals = [externals]\n  }\n\n  for (const external of externals) {\n    if (\n      typeof external === 'string' &&\n      (id === external || id.includes(`/node_modules/${external}/`))\n    ) {\n      return true\n    }\n    if (external instanceof RegExp && external.test(id)) {\n      return true\n    }\n    if (typeof external === 'function' && external(id, parentId)) {\n      return true\n    }\n  }\n\n  return false\n}\n\nexport function getPostcss(): null | Awaited<typeof import('postcss')> {\n  return localRequire('postcss')\n}\n\nexport function getApiExtractor(): null | Awaited<\n  typeof import('@microsoft/api-extractor')\n> {\n  return localRequire('@microsoft/api-extractor')\n}\n\nexport function localRequire(moduleName: string) {\n  const p = resolveFrom.silent(process.cwd(), moduleName)\n  return p && require(p)\n}\n\nexport function pathExists(p: string) {\n  return new Promise((resolve) => {\n    fs.access(p, (err) => {\n      resolve(!err)\n    })\n  })\n}\n\nexport async function removeFiles(patterns: string[], dir: string) {\n  const files = await glob(patterns, {\n    cwd: dir,\n    absolute: true,\n  })\n  files.forEach((file) => fs.existsSync(file) && fs.unlinkSync(file))\n}\n\nexport function debouncePromise<T extends unknown[]>(\n  fn: (...args: T) => Promise<void>,\n  delay: number,\n  onError: (err: unknown) => void,\n) {\n  let timeout: ReturnType<typeof setTimeout> | undefined\n\n  let promiseInFly: Promise<void> | undefined\n\n  let callbackPending: (() => void) | undefined\n\n  return function debounced(...args: Parameters<typeof fn>) {\n    if (promiseInFly) {\n      callbackPending = () => {\n        debounced(...args)\n        callbackPending = undefined\n      }\n    } else {\n      if (timeout != null) clearTimeout(timeout)\n\n      timeout = setTimeout(() => {\n        timeout = undefined\n        promiseInFly = fn(...args)\n          .catch(onError)\n          .finally(() => {\n            promiseInFly = undefined\n            if (callbackPending) callbackPending()\n          })\n      }, delay)\n    }\n  }\n}\n\n// Taken from https://github.com/sindresorhus/slash/blob/main/index.js (MIT)\nexport function slash(path: string) {\n  const isExtendedLengthPath = path.startsWith('\\\\\\\\?\\\\')\n\n  if (isExtendedLengthPath) {\n    return path\n  }\n\n  return path.replace(/\\\\/g, '/')\n}\n\ntype Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T // from lodash\n\nexport function truthy<T>(value: T): value is Truthy<T> {\n  return Boolean(value)\n}\n\nexport function jsoncParse(data: string) {\n  try {\n    return new Function(`return ${strip(data).trim()}`)()\n  } catch {\n    // Silently ignore any error\n    // That's what tsc/jsonc-parser did after all\n    return {}\n  }\n}\n\nexport function defaultOutExtension({\n  format,\n  pkgType,\n}: {\n  format: Format\n  pkgType?: string\n}): { js: string; dts: string } {\n  let jsExtension = '.js'\n  let dtsExtension = '.d.ts'\n  const isModule = pkgType === 'module'\n  if (isModule && format === 'cjs') {\n    jsExtension = '.cjs'\n    dtsExtension = '.d.cts'\n  }\n  if (!isModule && format === 'esm') {\n    jsExtension = '.mjs'\n    dtsExtension = '.d.mts'\n  }\n  if (format === 'iife') {\n    jsExtension = '.global.js'\n  }\n  return {\n    js: jsExtension,\n    dts: dtsExtension,\n  }\n}\n\nexport function ensureTempDeclarationDir(): string {\n  const cwd = process.cwd()\n  const dirPath = path.join(cwd, '.tsup', 'declaration')\n\n  if (fs.existsSync(dirPath)) {\n    return dirPath\n  }\n\n  fs.mkdirSync(dirPath, { recursive: true })\n\n  const gitIgnorePath = path.join(cwd, '.tsup', '.gitignore')\n  writeFileSync(gitIgnorePath, '**/*\\n')\n\n  return dirPath\n}\n\n// Make sure the entry is an object\n// We use the base path (without extension) as the entry name\n// To make declaration files work with multiple entrypoints\n// See #316\nexport const toObjectEntry = (entry: string | Entry) => {\n  if (typeof entry === 'string') {\n    entry = [entry]\n  }\n  if (!Array.isArray(entry)) {\n    return entry\n  }\n  entry = entry.map((e) => e.replace(/\\\\/g, '/'))\n  const ancestor = findLowestCommonAncestor(entry)\n  return entry.reduce(\n    (result, item) => {\n      const key = item\n        .replace(ancestor, '')\n        .replace(/^\\//, '')\n        .replace(/\\.[a-z]+$/, '')\n      return {\n        ...result,\n        [key]: item,\n      }\n    },\n    {} as Record<string, string>,\n  )\n}\n\nconst findLowestCommonAncestor = (filepaths: string[]) => {\n  if (filepaths.length <= 1) return ''\n  const [first, ...rest] = filepaths\n  let ancestor = first.split('/')\n  for (const filepath of rest) {\n    const directories = filepath.split('/', ancestor.length)\n    let index = 0\n    for (const directory of directories) {\n      if (directory === ancestor[index]) {\n        index += 1\n      } else {\n        ancestor = ancestor.slice(0, index)\n        break\n      }\n    }\n    ancestor = ancestor.slice(0, index)\n  }\n\n  return ancestor.length <= 1 && ancestor[0] === ''\n    ? `/${ancestor[0]}`\n    : ancestor.join('/')\n}\n\nexport function toAbsolutePath(p: string, cwd?: string): string {\n  if (path.isAbsolute(p)) {\n    return p\n  }\n\n  return slash(path.normalize(path.join(cwd || process.cwd(), p)))\n}\n\nexport function trimDtsExtension(fileName: string) {\n  return fileName.replace(/\\.d\\.(ts|mts|cts)x?$/, '')\n}\n\nexport function writeFileSync(filePath: string, content: string) {\n  fs.mkdirSync(path.dirname(filePath), { recursive: true })\n  fs.writeFileSync(filePath, content)\n}\n\n/**\n * Replaces TypeScript declaration file\n * extensions (`.d.ts`, `.d.mts`, `.d.cts`)\n * with their corresponding JavaScript variants (`.js`, `.mjs`, `.cjs`).\n *\n * @param dtsFilePath - The file path to be transformed.\n * @returns The updated file path with the JavaScript extension.\n *\n * @internal\n */\nexport function replaceDtsWithJsExtensions(dtsFilePath: string) {\n  return dtsFilePath.replace(\n    /\\.d\\.(ts|mts|cts)$/,\n    (_, fileExtension: string) => {\n      switch (fileExtension) {\n        case 'ts':\n          return '.js'\n        case 'mts':\n          return '.mjs'\n        case 'cts':\n          return '.cjs'\n        default:\n          return ''\n      }\n    },\n  )\n}\n\n/**\n * Converts an array of {@link NormalizedOptions.entry | entry paths}\n * into an object where the keys represent the output\n * file names (without extensions) and the values\n * represent the corresponding input file paths.\n *\n * @param arrayOfEntries - An array of file path entries as strings.\n * @returns An object where the keys are the output file name and the values are the input file name.\n *\n * @example\n *\n * ```ts\n * import { defineConfig } from 'tsup'\n *\n * export default defineConfig({\n *   entry: ['src/index.ts', 'src/types.ts'],\n *   // Becomes `{ index: 'src/index.ts', types: 'src/types.ts' }`\n * })\n * ```\n *\n * @internal\n */\nconst convertArrayEntriesToObjectEntries = (arrayOfEntries: string[]) => {\n  const objectEntries = Object.fromEntries(\n    arrayOfEntries.map(\n      (entry) =>\n        [\n          path.posix.join(\n            ...entry\n              .split(path.posix.sep)\n              .slice(1, -1)\n              .concat(path.parse(entry).name),\n          ),\n          entry,\n        ] as const,\n    ),\n  )\n\n  return objectEntries\n}\n\n/**\n * Resolves and standardizes entry paths into an object format. If the provided\n * entry is a string or an array of strings, it resolves any potential glob\n * patterns and converts the result into an entry object. If the input is\n * already an object, it is returned as-is.\n *\n * @example\n *\n * ```ts\n * import { defineConfig } from 'tsup'\n *\n * export default defineConfig({\n *   entry: { index: 'src/index.ts' },\n *   format: ['esm', 'cjs'],\n *   experimentalDts: { entry: 'src/**\\/*.ts' },\n *   // becomes experimentalDts: { entry: { index: 'src/index.ts', types: 'src/types.ts } }\n * })\n * ```\n *\n * @internal\n */\nconst resolveEntryPaths = async (entryPaths: InputOption) => {\n  const resolvedEntryPaths =\n    typeof entryPaths === 'string' || Array.isArray(entryPaths)\n      ? convertArrayEntriesToObjectEntries(await glob(entryPaths))\n      : entryPaths\n\n  return resolvedEntryPaths\n}\n\n/**\n * Resolves the\n * {@link NormalizedExperimentalDtsConfig | experimental DTS config} by\n * resolving entry paths and merging the provided TypeScript configuration\n * options.\n *\n * @param options - The options containing entry points and experimental DTS\n * configuration.\n * @param tsconfig - The loaded TypeScript configuration data.\n *\n * @internal\n */\nexport const resolveExperimentalDtsConfig = async (\n  options: NormalizedOptions,\n  tsconfig: any,\n): Promise<NormalizedExperimentalDtsConfig> => {\n  const resolvedEntryPaths = await resolveEntryPaths(\n    options.experimentalDts?.entry || options.entry,\n  )\n\n  // Fallback to `options.entry` if we end up with an empty object.\n  const experimentalDtsObjectEntry =\n    Object.keys(resolvedEntryPaths).length === 0\n      ? Array.isArray(options.entry)\n        ? convertArrayEntriesToObjectEntries(options.entry)\n        : options.entry\n      : resolvedEntryPaths\n\n  const normalizedExperimentalDtsConfig: NormalizedExperimentalDtsConfig = {\n    compilerOptions: {\n      ...(tsconfig.data.compilerOptions || {}),\n      ...(options.experimentalDts?.compilerOptions || {}),\n    },\n\n    entry: experimentalDtsObjectEntry,\n  }\n\n  return normalizedExperimentalDtsConfig\n}\n\n/**\n * Resolves the initial experimental DTS configuration into a consistent\n * {@link NormalizedExperimentalDtsConfig} object.\n *\n * @internal\n */\nexport const resolveInitialExperimentalDtsConfig = async (\n  experimentalDts: Options['experimentalDts'],\n): Promise<NormalizedExperimentalDtsConfig | undefined> => {\n  if (experimentalDts == null) {\n    return\n  }\n\n  if (typeof experimentalDts === 'boolean')\n    return experimentalDts ? { entry: {} } : undefined\n\n  if (typeof experimentalDts === 'string') {\n    // Treats the string as a glob pattern, resolving it to entry paths and\n    // returning an object with the `entry` property.\n    return {\n      entry: convertArrayEntriesToObjectEntries(await glob(experimentalDts)),\n    }\n  }\n\n  return {\n    ...experimentalDts,\n\n    entry:\n      experimentalDts?.entry == null\n        ? {}\n        : await resolveEntryPaths(experimentalDts.entry),\n  }\n}\n"
  },
  {
    "path": "test/__snapshots__/css.test.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`import css 1`] = `\n\"\"use strict\";\n\"\n`;\n\nexports[`import css in --dts 1`] = `\n\"\"use strict\";\n\"\n`;\n\nexports[`support tailwindcss postcss plugin 1`] = `\n\"\"use strict\";\n\"\n`;\n"
  },
  {
    "path": "test/__snapshots__/dts.test.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`declaration files with multiple entrypoints #316 1`] = `\n\"declare const foo = 1;\n\nexport { foo };\n\"\n`;\n\nexports[`declaration files with multiple entrypoints #316 2`] = `\n\"declare const bar = \"bar\";\n\nexport { bar };\n\"\n`;\n\nexports[`enable --dts-resolve for specific module 1`] = `\n\"export * from 'vue';\n\ntype MarkRequired<T, RK extends keyof T> = Exclude<T, RK> & Required<Pick<T, RK>>\n\nexport type { MarkRequired };\n\"\n`;\n\nexports[`not bundle \\`package/subpath\\` in dts (resolve) 1`] = `\n\"import * as foo_bar from 'foo/bar';\n\ndeclare const stuff: foo_bar.Foobar;\n\nexport { stuff };\n\"\n`;\n\nexports[`should emit declaration files with experimentalDts 1`] = `\n\"\n//////////////////////////////////////////////////////////////////////\n// dist/_tsup-dts-rollup.d.mts\n//////////////////////////////////////////////////////////////////////\n\nimport { PipeableStream } from 'react-dom/server';\nimport { ReactDOMServerReadableStream } from 'react-dom/server';\nimport { renderToNodeStream } from 'react-dom/server';\nimport { renderToPipeableStream } from 'react-dom/server';\nimport { RenderToPipeableStreamOptions } from 'react-dom/server';\nimport { renderToReadableStream } from 'react-dom/server';\nimport { RenderToReadableStreamOptions } from 'react-dom/server';\nimport { renderToStaticMarkup } from 'react-dom/server';\nimport { renderToStaticNodeStream } from 'react-dom/server';\nimport { renderToString } from 'react-dom/server';\nimport { ServerOptions } from 'react-dom/server';\nimport * as ServerThirdPartyNamespace from 'react-dom';\nimport { version } from 'react-dom/server';\n\ndeclare interface ClientRenderOptions {\n    document: boolean;\n}\nexport { ClientRenderOptions }\nexport { ClientRenderOptions as ClientRenderOptions_alias_1 }\n\nexport declare function default_alias(options: ServerRenderOptions): void;\n\nexport { PipeableStream }\n\nexport { ReactDOMServerReadableStream }\n\ndeclare function render(options: ClientRenderOptions): string;\nexport { render }\nexport { render as render_alias_1 }\n\n/**\n * Comment for server render function\n */\nexport declare function render_alias_2(options: ServerRenderOptions): string;\n\nexport { renderToNodeStream }\n\nexport { renderToPipeableStream }\n\nexport { RenderToPipeableStreamOptions }\n\nexport { renderToReadableStream }\n\nexport { RenderToReadableStreamOptions }\n\nexport { renderToStaticMarkup }\n\nexport { renderToStaticNodeStream }\n\nexport { renderToString }\n\nexport declare class ServerClass {\n}\n\ndeclare const serverConstant = 1;\nexport { serverConstant }\nexport { serverConstant as serverConstantAlias }\n\nexport { ServerOptions }\n\nexport declare interface ServerRenderOptions {\n    /**\n     * Comment for ServerRenderOptions.stream\n     *\n     * @public\n     *\n     * @my_custom_tag\n     */\n    stream: boolean;\n}\n\nexport { ServerThirdPartyNamespace }\n\ndeclare function sharedFunction<T>(value: T): T | null;\nexport { sharedFunction }\nexport { sharedFunction as sharedFunction_alias_1 }\nexport { sharedFunction as sharedFunction_alias_2 }\nexport { sharedFunction as sharedFunction_alias_3 }\n\ndeclare type sharedType = {\n    shared: boolean;\n};\nexport { sharedType }\nexport { sharedType as sharedType_alias_1 }\nexport { sharedType as sharedType_alias_2 }\nexport { sharedType as sharedType_alias_3 }\n\nexport declare const VERSION: \"0.0.0\";\n\nexport { version }\n\nexport { }\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/_tsup-dts-rollup.d.ts\n//////////////////////////////////////////////////////////////////////\n\nimport { PipeableStream } from 'react-dom/server';\nimport { ReactDOMServerReadableStream } from 'react-dom/server';\nimport { renderToNodeStream } from 'react-dom/server';\nimport { renderToPipeableStream } from 'react-dom/server';\nimport { RenderToPipeableStreamOptions } from 'react-dom/server';\nimport { renderToReadableStream } from 'react-dom/server';\nimport { RenderToReadableStreamOptions } from 'react-dom/server';\nimport { renderToStaticMarkup } from 'react-dom/server';\nimport { renderToStaticNodeStream } from 'react-dom/server';\nimport { renderToString } from 'react-dom/server';\nimport { ServerOptions } from 'react-dom/server';\nimport * as ServerThirdPartyNamespace from 'react-dom';\nimport { version } from 'react-dom/server';\n\ndeclare interface ClientRenderOptions {\n    document: boolean;\n}\nexport { ClientRenderOptions }\nexport { ClientRenderOptions as ClientRenderOptions_alias_1 }\n\nexport declare function default_alias(options: ServerRenderOptions): void;\n\nexport { PipeableStream }\n\nexport { ReactDOMServerReadableStream }\n\ndeclare function render(options: ClientRenderOptions): string;\nexport { render }\nexport { render as render_alias_1 }\n\n/**\n * Comment for server render function\n */\nexport declare function render_alias_2(options: ServerRenderOptions): string;\n\nexport { renderToNodeStream }\n\nexport { renderToPipeableStream }\n\nexport { RenderToPipeableStreamOptions }\n\nexport { renderToReadableStream }\n\nexport { RenderToReadableStreamOptions }\n\nexport { renderToStaticMarkup }\n\nexport { renderToStaticNodeStream }\n\nexport { renderToString }\n\nexport declare class ServerClass {\n}\n\ndeclare const serverConstant = 1;\nexport { serverConstant }\nexport { serverConstant as serverConstantAlias }\n\nexport { ServerOptions }\n\nexport declare interface ServerRenderOptions {\n    /**\n     * Comment for ServerRenderOptions.stream\n     *\n     * @public\n     *\n     * @my_custom_tag\n     */\n    stream: boolean;\n}\n\nexport { ServerThirdPartyNamespace }\n\ndeclare function sharedFunction<T>(value: T): T | null;\nexport { sharedFunction }\nexport { sharedFunction as sharedFunction_alias_1 }\nexport { sharedFunction as sharedFunction_alias_2 }\nexport { sharedFunction as sharedFunction_alias_3 }\n\ndeclare type sharedType = {\n    shared: boolean;\n};\nexport { sharedType }\nexport { sharedType as sharedType_alias_1 }\nexport { sharedType as sharedType_alias_2 }\nexport { sharedType as sharedType_alias_3 }\n\nexport declare const VERSION: \"0.0.0\";\n\nexport { version }\n\nexport { }\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/index.d.mts\n//////////////////////////////////////////////////////////////////////\n\nexport { VERSION } from './_tsup-dts-rollup.mjs';\nexport { render_alias_1 as render } from './_tsup-dts-rollup.mjs';\nexport { ClientRenderOptions_alias_1 as ClientRenderOptions } from './_tsup-dts-rollup.mjs';\nexport { sharedFunction_alias_1 as sharedFunction } from './_tsup-dts-rollup.mjs';\nexport { sharedType_alias_1 as sharedType } from './_tsup-dts-rollup.mjs';\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/index.d.ts\n//////////////////////////////////////////////////////////////////////\n\nexport { VERSION } from './_tsup-dts-rollup.js';\nexport { render_alias_1 as render } from './_tsup-dts-rollup.js';\nexport { ClientRenderOptions_alias_1 as ClientRenderOptions } from './_tsup-dts-rollup.js';\nexport { sharedFunction_alias_1 as sharedFunction } from './_tsup-dts-rollup.js';\nexport { sharedType_alias_1 as sharedType } from './_tsup-dts-rollup.js';\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/my-lib-client.d.mts\n//////////////////////////////////////////////////////////////////////\n\nexport { render } from './_tsup-dts-rollup.mjs';\nexport { ClientRenderOptions } from './_tsup-dts-rollup.mjs';\nexport { sharedFunction } from './_tsup-dts-rollup.mjs';\nexport { sharedType } from './_tsup-dts-rollup.mjs';\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/my-lib-client.d.ts\n//////////////////////////////////////////////////////////////////////\n\nexport { render } from './_tsup-dts-rollup.js';\nexport { ClientRenderOptions } from './_tsup-dts-rollup.js';\nexport { sharedFunction } from './_tsup-dts-rollup.js';\nexport { sharedType } from './_tsup-dts-rollup.js';\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/server/index.d.mts\n//////////////////////////////////////////////////////////////////////\n\nexport { render_alias_2 as render } from '../_tsup-dts-rollup.mjs';\nexport { default_alias as default } from '../_tsup-dts-rollup.mjs';\nexport { ServerRenderOptions } from '../_tsup-dts-rollup.mjs';\nexport { serverConstant } from '../_tsup-dts-rollup.mjs';\nexport { serverConstantAlias } from '../_tsup-dts-rollup.mjs';\nexport { ServerClass } from '../_tsup-dts-rollup.mjs';\nexport { ServerThirdPartyNamespace } from '../_tsup-dts-rollup.mjs';\nexport { sharedFunction_alias_2 as sharedFunction } from '../_tsup-dts-rollup.mjs';\nexport { sharedType_alias_2 as sharedType } from '../_tsup-dts-rollup.mjs';\nexport { renderToPipeableStream } from '../_tsup-dts-rollup.mjs';\nexport { renderToString } from '../_tsup-dts-rollup.mjs';\nexport { renderToNodeStream } from '../_tsup-dts-rollup.mjs';\nexport { renderToStaticMarkup } from '../_tsup-dts-rollup.mjs';\nexport { renderToStaticNodeStream } from '../_tsup-dts-rollup.mjs';\nexport { renderToReadableStream } from '../_tsup-dts-rollup.mjs';\nexport { RenderToPipeableStreamOptions } from '../_tsup-dts-rollup.mjs';\nexport { PipeableStream } from '../_tsup-dts-rollup.mjs';\nexport { ServerOptions } from '../_tsup-dts-rollup.mjs';\nexport { RenderToReadableStreamOptions } from '../_tsup-dts-rollup.mjs';\nexport { ReactDOMServerReadableStream } from '../_tsup-dts-rollup.mjs';\nexport { version } from '../_tsup-dts-rollup.mjs';\n\n\n//////////////////////////////////////////////////////////////////////\n// dist/server/index.d.ts\n//////////////////////////////////////////////////////////////////////\n\nexport { render_alias_2 as render } from '../_tsup-dts-rollup.js';\nexport { default_alias as default } from '../_tsup-dts-rollup.js';\nexport { ServerRenderOptions } from '../_tsup-dts-rollup.js';\nexport { serverConstant } from '../_tsup-dts-rollup.js';\nexport { serverConstantAlias } from '../_tsup-dts-rollup.js';\nexport { ServerClass } from '../_tsup-dts-rollup.js';\nexport { ServerThirdPartyNamespace } from '../_tsup-dts-rollup.js';\nexport { sharedFunction_alias_2 as sharedFunction } from '../_tsup-dts-rollup.js';\nexport { sharedType_alias_2 as sharedType } from '../_tsup-dts-rollup.js';\nexport { renderToPipeableStream } from '../_tsup-dts-rollup.js';\nexport { renderToString } from '../_tsup-dts-rollup.js';\nexport { renderToNodeStream } from '../_tsup-dts-rollup.js';\nexport { renderToStaticMarkup } from '../_tsup-dts-rollup.js';\nexport { renderToStaticNodeStream } from '../_tsup-dts-rollup.js';\nexport { renderToReadableStream } from '../_tsup-dts-rollup.js';\nexport { RenderToPipeableStreamOptions } from '../_tsup-dts-rollup.js';\nexport { PipeableStream } from '../_tsup-dts-rollup.js';\nexport { ServerOptions } from '../_tsup-dts-rollup.js';\nexport { RenderToReadableStreamOptions } from '../_tsup-dts-rollup.js';\nexport { ReactDOMServerReadableStream } from '../_tsup-dts-rollup.js';\nexport { version } from '../_tsup-dts-rollup.js';\n\"\n`;\n"
  },
  {
    "path": "test/__snapshots__/index.test.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`code splitting in cjs format 1`] = `\n\"\"use strict\";Object.defineProperty(exports, \"__esModule\", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }// input.ts\nvar foo = () => Promise.resolve().then(() => _interopRequireWildcard(require(\"./foo-D62QZYUQ.js\")));\n\n\nexports.foo = foo;\n\"\n`;\n\nexports[`code splitting in cjs format 2`] = `\n\"\"use strict\";Object.defineProperty(exports, \"__esModule\", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }// another-input.ts\nvar foo = () => Promise.resolve().then(() => _interopRequireWildcard(require(\"./foo-D62QZYUQ.js\")));\n\n\nexports.foo = foo;\n\"\n`;\n\nexports[`disable code splitting to get proper module.exports = 1`] = `\n\"\"use strict\";\n\n// input.ts\nmodule.exports = 123;\n\"\n`;\n\nexports[`don't remove node protocol 1`] = `\n\"\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n  // If the importer is in node compatibility mode or this is not an ESM\n  // file that has been converted to a CommonJS file using a Babel-\n  // compatible transform (i.e. \"__esModule\" has not been set), then set\n  // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n  isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n  mod\n));\n\n// input.ts\nvar import_node_fs = __toESM(require(\"node:fs\"));\nconsole.log(import_node_fs.default);\n\"\n`;\n\nexports[`external 1`] = `\n\"\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// input.ts\nvar input_exports = {};\n__export(input_exports, {\n  bar: () => import_bar.bar,\n  baz: () => baz,\n  foo: () => import_foo.foo,\n  qux: () => import_qux.qux\n});\nmodule.exports = __toCommonJS(input_exports);\nvar import_foo = require(\"foo\");\nvar import_bar = require(\"bar\");\n\n// node_modules/baz/index.ts\nvar baz = \"baz\";\n\n// input.ts\nvar import_qux = require(\"qux\");\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  bar,\n  baz,\n  foo,\n  qux\n});\n\"\n`;\n\nexports[`multiple targets 1`] = `\n\"\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// input.ts\nvar input_exports = {};\n__export(input_exports, {\n  answer: () => answer\n});\nmodule.exports = __toCommonJS(input_exports);\nvar answer = 42;\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  answer\n});\n\"\n`;\n\nexports[`node protocol 1`] = `\n\"\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n  // If the importer is in node compatibility mode or this is not an ESM\n  // file that has been converted to a CommonJS file using a Babel-\n  // compatible transform (i.e. \"__esModule\" has not been set), then set\n  // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n  isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n  mod\n));\n\n// input.ts\nvar import_node_fs = __toESM(require(\"fs\"));\nconsole.log(import_node_fs.default);\n\"\n`;\n\nexports[`simple 1`] = `\n\"\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// input.ts\nvar input_exports = {};\n__export(input_exports, {\n  default: () => input_default\n});\nmodule.exports = __toCommonJS(input_exports);\n\n// foo.ts\nvar foo_default = \"foo\";\n\n// input.ts\nvar input_default = foo_default;\n\"\n`;\n"
  },
  {
    "path": "test/__snapshots__/tsconfig.test.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`support baseUrl and paths in tsconfig.json 1`] = `\n\"var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// input.ts\nvar input_exports = {};\n__export(input_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(input_exports);\n\n// foo.ts\nvar foo = \"foo\";\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  foo\n});\n\"\n`;\n\nexports[`support baseUrl and paths in tsconfig.json in --dts build 1`] = `\n\"declare const foo = \"foo\";\n\nexport { foo };\n\"\n`;\n\nexports[`support baseUrl and paths in tsconfig.json in --dts-resolve build 1`] = `\n\"declare const foo = \"foo\";\n\nexport { foo };\n\"\n`;\n"
  },
  {
    "path": "test/css.test.ts",
    "content": "import { expect, test } from 'vitest'\nimport { getTestName, run } from './utils'\n\ntest('import css', async () => {\n  const { output, outFiles } = await run(getTestName(), {\n    'input.ts': `\n    import './foo.css'\n    `,\n    'postcss.config.js': `\n    module.exports = {\n      plugins: [require('postcss-simple-vars')()]\n    }\n    `,\n    'foo.css': `\n  $color: blue;\n\n  .foo {\n    color: $color;\n  }\n    `,\n  })\n\n  expect(output, `\"\"`).toMatchSnapshot()\n  expect(outFiles).toEqual(['input.css', 'input.js'])\n})\n\ntest('support tailwindcss postcss plugin', async () => {\n  const { output, outFiles } = await run(getTestName(), {\n    'input.ts': `\n      import './foo.css'\n    `,\n    'postcss.config.js': `\n      module.exports = {\n        plugins: {\n          tailwindcss: {},\n          autoprefixer: {},\n        }\n      }\n    `,\n    'foo.css': `\n      @tailwind base;\n      @tailwind components;\n      @tailwind utilities;\n    `,\n  })\n  expect(output).toMatchSnapshot()\n  expect(outFiles).toEqual(['input.css', 'input.js'])\n})\n\ntest('import css in --dts', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    import './foo.css'\n    `,\n      'foo.css': `\n  .foo {\n    color: blue\n  }\n    `,\n    },\n    { flags: ['--dts'] },\n  )\n\n  expect(output).toMatchSnapshot()\n  expect(outFiles).toEqual(['input.css', 'input.d.ts', 'input.js'])\n})\n"
  },
  {
    "path": "test/dts.test.ts",
    "content": "import path from 'node:path'\nimport { expect, test } from 'vitest'\nimport { slash } from '../src/utils'\nimport { getTestName, run } from './utils'\n\ntest('not bundle `package/subpath` in dts (resolve)', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'package.json': `{ \"dependencies\": { \"foo\": \"*\" } }`,\n      'input.ts': `export const stuff: import('foo/bar').Foobar = { foo: 'foo', bar: 'bar' };`,\n      'node_modules/foo/bar.d.ts': `export type Foobar = { foo: 'foo', bar: 'bar' }`,\n      'node_modules/foo/package.json': `{ \"name\": \"foo\", \"version\": \"0.0.0\" }`,\n    },\n    {\n      flags: ['--dts', '--dts-resolve'],\n    },\n  )\n  const content = await getFileContent('dist/input.d.ts')\n  expect(content).toMatchSnapshot()\n})\n\ntest('enable --dts-resolve for specific module', async () => {\n  const { getFileContent } = await run(getTestName(), {\n    'input.ts': `export * from 'vue'\n      export type {MarkRequired} from 'foo'\n      `,\n    'node_modules/foo/index.d.ts': `\n      export type MarkRequired<T, RK extends keyof T> = Exclude<T, RK> & Required<Pick<T, RK>>\n      `,\n    'node_modules/foo/package.json': `{ \"name\": \"foo\", \"version\": \"0.0.0\" }`,\n    'tsup.config.ts': `\n      export default {\n        dts: {\n          resolve: ['foo']\n        },\n      }\n      `,\n  })\n  const content = await getFileContent('dist/input.d.ts')\n  expect(content).toMatchSnapshot()\n})\n\ntest(`custom tsconfig should pass to dts plugin`, async () => {\n  const { outFiles } = await run(getTestName(), {\n    'input.ts': `export const foo = { name: 'foo'}`,\n    'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"baseUrl\":\".\",\n          \"target\": \"esnext\",\n          \"incremental\": true\n        }\n      }`,\n    'tsconfig.build.json': `{\n        \"compilerOptions\": {\n          \"baseUrl\":\".\",\n          \"target\": \"esnext\"\n        }\n      }`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          format: 'esm',\n          tsconfig: './tsconfig.build.json',\n          dts: {\n            only: true\n          }\n        }\n      `,\n  })\n  expect(outFiles).toEqual(['input.d.mts'])\n})\n\ntest('should emit a declaration file per format', async () => {\n  const { outFiles } = await run(getTestName(), {\n    'input.ts': `export default 'foo'`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          format: ['esm', 'cjs'],\n          dts: true\n        }`,\n  })\n  expect(outFiles).toEqual([\n    'input.d.mts',\n    'input.d.ts',\n    'input.js',\n    'input.mjs',\n  ])\n})\n\ntest('should emit a declaration file per format (type: module)', async () => {\n  const { outFiles } = await run(getTestName(), {\n    'input.ts': `export default 'foo'`,\n    'package.json': `{\n      \"type\": \"module\"\n    }`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          format: ['esm', 'cjs'],\n          dts: true\n        }`,\n  })\n  expect(outFiles).toEqual([\n    'input.cjs',\n    'input.d.cts',\n    'input.d.ts',\n    'input.js',\n  ])\n})\n\ntest('should emit dts chunks per format', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'src/input1.ts': `\n          import type { InternalType } from './shared.js'\n\n          export function getValue(value: InternalType) {\n            return value;\n          }\n      `,\n      'src/input2.ts': `\n          import type { InternalType } from './shared.js'\n\n          export function getValue(value: InternalType) {\n            return value;\n          }\n      `,\n      'src/shared.ts': `export type InternalType = 'foo'`,\n      'tsup.config.ts': `\n        export default {\n          entry: ['./src/input1.ts', './src/input2.ts'],\n          format: ['esm', 'cjs'],\n          dts: true\n        }`,\n    },\n    { entry: [] },\n  )\n  expect(outFiles).toEqual([\n    'input1.d.mts',\n    'input1.d.ts',\n    'input1.js',\n    'input1.mjs',\n    'input2.d.mts',\n    'input2.d.ts',\n    'input2.js',\n    'input2.mjs',\n    'shared-jWa9aNVo.d.mts',\n    'shared-jWa9aNVo.d.ts',\n  ])\n})\n\ntest('should emit dts chunks per format (type: module)', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'src/input1.ts': `\n          import type { InternalType } from './shared.js'\n\n          export function getValue(value: InternalType) {\n            return value;\n          }\n      `,\n      'src/input2.ts': `\n          import type { InternalType } from './shared.js'\n\n          export function getValue(value: InternalType) {\n            return value;\n          }\n      `,\n      'src/shared.ts': `export type InternalType = 'foo'`,\n      'tsup.config.ts': `\n        export default {\n          entry: ['./src/input1.ts', './src/input2.ts'],\n          format: ['esm', 'cjs'],\n          dts: true\n        }`,\n      'package.json': `{\n          \"type\": \"module\"\n        }`,\n    },\n    { entry: [] },\n  )\n  expect(outFiles).toEqual([\n    'input1.cjs',\n    'input1.d.cts',\n    'input1.d.ts',\n    'input1.js',\n    'input2.cjs',\n    'input2.d.cts',\n    'input2.d.ts',\n    'input2.js',\n    'shared-jWa9aNVo.d.cts',\n    'shared-jWa9aNVo.d.ts',\n  ])\n})\n\ntest('should emit declaration files with experimentalDts', async () => {\n  const files = {\n    'package.json': `\n        {\n          \"name\": \"tsup-playground\",\n          \"private\": true,\n          \"version\": \"0.0.0\",\n          \"main\": \"dist/index.js\",\n          \"module\": \"dist/index.mjs\",\n          \"types\": \"dist/index.d.ts\",\n          \"exports\": {\n              \".\": {\n                  \"types\": \"./dist/index.d.ts\",\n                  \"require\": \"./dist/index.js\",\n                  \"import\": \"./dist/index.mjs\",\n                  \"default\": \"./dist/index.js\"\n              },\n              \"./client\": {\n                  \"types\": \"./dist/my-lib-client.d.ts\",\n                  \"require\": \"./dist/my-lib-client.js\",\n                  \"import\": \"./dist/my-lib-client.mjs\",\n                  \"default\": \"./dist/my-lib-client.js\"\n              },\n              \"./server\": {\n                  \"types\": \"./dist/server/index.d.ts\",\n                  \"require\": \"./dist/server/index.js\",\n                  \"import\": \"./dist/server/index.mjs\",\n                  \"default\": \"./dist/server/index.js\"\n              }\n          }\n        }\n    `,\n    'tsconfig.json': `\n        {\n          \"compilerOptions\": {\n              \"target\": \"ES2020\",\n              \"skipLibCheck\": true,\n              \"noEmit\": true\n          },\n          \"include\": [\"./src\"]\n        }\n    `,\n    'tsup.config.ts': `\n        export default {\n          name: 'tsup',\n          target: 'es2022',\n          format: [\n            'esm',\n            'cjs'\n          ],\n          entry: {\n            index: './src/index.ts',\n            'my-lib-client': './src/client.ts',\n            'server/index': './src/server.ts',\n          },\n        }\n    `,\n    'src/shared.ts': `\n        export function sharedFunction<T>(value: T): T | null {\n          return value || null\n        }\n\n        type sharedType = {\n          shared: boolean\n        }\n\n        export type { sharedType }\n    `,\n    'src/server.ts': `\n        export * from './shared'\n\n        /**\n         * Comment for server render function\n         */\n        export function render(options: ServerRenderOptions): string {\n          return JSON.stringify(options)\n        }\n\n        export interface ServerRenderOptions {\n          /**\n           * Comment for ServerRenderOptions.stream\n           *\n           * @public\n           *\n           * @my_custom_tag\n           */\n          stream: boolean\n        }\n\n        export const serverConstant = 1\n\n        export { serverConstant as serverConstantAlias }\n\n        export class ServerClass {};\n\n        export default function serverDefaultExport(options: ServerRenderOptions): void {};\n\n        // Export a third party module as a namespace\n        import * as ServerThirdPartyNamespace from 'react-dom';\n        export { ServerThirdPartyNamespace }\n\n        // Export a third party module\n        export * from 'react-dom/server';\n\n    `,\n    'src/client.ts': `\n        export * from './shared'\n\n        export function render(options: ClientRenderOptions): string {\n          return JSON.stringify(options)\n        }\n\n        export interface ClientRenderOptions {\n          document: boolean\n        }\n    `,\n    'src/index.ts': `\n        export * from './client'\n        export * from './shared'\n\n        export const VERSION = '0.0.0' as const\n    `,\n  }\n  const { outFiles, getFileContent } = await run(getTestName(), files, {\n    entry: [],\n    flags: ['--experimental-dts'],\n  })\n  const snapshots: string[] = []\n  await Promise.all(\n    outFiles\n      .filter((outFile) => outFile.includes('.d.'))\n      .map(async (outFile) => {\n        const filePath = path.join('dist', outFile)\n        const content = await getFileContent(filePath)\n        snapshots.push(\n          [\n            '',\n            '/'.repeat(70),\n            `// ${path.posix.normalize(slash(filePath))}`,\n            '/'.repeat(70),\n            '',\n            content,\n          ].join('\\n'),\n        )\n      }),\n  )\n  expect(snapshots.sort().join('\\n')).toMatchSnapshot()\n})\n\ntest('should only include exported declarations with experimentalDts', async () => {\n  const files = {\n    'package.json': `{ \"name\": \"tsup-playground\", \"private\": true }`,\n    'tsconfig.json': `{ \"compilerOptions\": { \"skipLibCheck\": true } }`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['./src/entry1.ts', './src/entry2.ts']\n        }\n    `,\n    'src/shared.ts': `\n        export const declare1 = 'declare1'\n        export const declare2 = 'declare2'\n    `,\n    'src/entry1.ts': `\n        export { declare1 } from './shared'\n    `,\n    'src/entry2.ts': `\n        export { declare2 } from './shared'\n    `,\n  }\n  const { getFileContent } = await run(getTestName(), files, {\n    entry: [],\n    flags: ['--experimental-dts'],\n  })\n\n  const entry1dts = await getFileContent('dist/entry1.d.ts')\n  const entry2dts = await getFileContent('dist/entry2.d.ts')\n\n  expect(entry1dts).toContain('declare1')\n  expect(entry1dts).not.toContain('declare2')\n\n  expect(entry2dts).toContain('declare2')\n  expect(entry2dts).not.toContain('declare1')\n})\n\ntest('.d.ts files should be cleaned when --clean and --experimental-dts are provided', async () => {\n  const filesFoo = {\n    'package.json': `{ \"name\": \"tsup-playground\", \"private\": true }`,\n    'foo.ts': `export const foo = 1`,\n    'tsconfig.json': JSON.stringify(\n      {\n        compilerOptions: { skipLibCheck: true },\n      },\n      null,\n      2,\n    ),\n  }\n\n  const filesFooBar = {\n    ...filesFoo,\n    'bar.ts': `export const bar = 2`,\n  }\n\n  // First run with both foo and bar\n  const result1 = await run(getTestName(), filesFooBar, {\n    entry: ['foo.ts', 'bar.ts'],\n    flags: ['--experimental-dts'],\n  })\n\n  expect(result1.outFiles).toContain('foo.d.ts')\n  expect(result1.outFiles).toContain('foo.js')\n  expect(result1.outFiles).toContain('bar.d.ts')\n  expect(result1.outFiles).toContain('bar.js')\n\n  // Second run with only foo\n  const result2 = await run(getTestName(), filesFoo, {\n    entry: ['foo.ts'],\n    flags: ['--experimental-dts'],\n  })\n\n  // When --clean is not provided, the previous bar.* files should still exist\n  expect(result2.outFiles).toContain('foo.d.ts')\n  expect(result2.outFiles).toContain('foo.js')\n  expect(result2.outFiles).toContain('bar.d.ts')\n  expect(result2.outFiles).toContain('bar.js')\n\n  // Third run with only foo and --clean\n  const result3 = await run(getTestName(), filesFoo, {\n    entry: ['foo.ts'],\n    flags: ['--experimental-dts', '--clean'],\n  })\n\n  // When --clean is provided, the previous bar.* files should be deleted\n  expect(result3.outFiles).toContain('foo.d.ts')\n  expect(result3.outFiles).toContain('foo.js')\n  expect(result3.outFiles).not.toContain('bar.d.ts')\n  expect(result3.outFiles).not.toContain('bar.js')\n})\n\ntest('dts only: ignore files', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n      import './style.scss'\n\n      export const a = 1\n      `,\n      'style.scss': `\n      @keyframes gallery-loading-spinner {\n        0% {}\n      }\n      `,\n    },\n    {\n      entry: ['input.ts'],\n      flags: ['--dts-only'],\n    },\n  )\n  expect(outFiles).toMatchInlineSnapshot(`\n    [\n      \"input.d.ts\",\n    ]\n  `)\n})\n\ntest('declaration files with multiple entrypoints #316', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'src/index.ts': `export const foo = 1`,\n      'src/bar/index.ts': `export const bar = 'bar'`,\n    },\n    { flags: ['--dts'], entry: ['src/index.ts', 'src/bar/index.ts'] },\n  )\n  expect(\n    await getFileContent('dist/index.d.ts'),\n    'dist/index.d.ts',\n  ).toMatchSnapshot()\n  expect(\n    await getFileContent('dist/bar/index.d.ts'),\n    'dist/bar/index.d.ts',\n  ).toMatchSnapshot()\n})\n"
  },
  {
    "path": "test/example.test.ts",
    "content": "import { test } from 'vitest'\nimport { getTestName, run } from './utils'\n\ntest('bundle vue and ts-essentials with --dts --dts-resolve flag', async () => {\n  await run(\n    getTestName(),\n    {\n      'input.ts': `export * from 'vue'\n      export type { MarkRequired } from 'ts-essentials'\n      `,\n    },\n    {\n      flags: ['--dts', '--dts-resolve'],\n    },\n  )\n})\n\ntest('bundle @egoist/path-parser with --dts --dts-resolve flag', async () => {\n  await run(\n    getTestName(),\n    {\n      'input.ts': `import type { PathParser } from '@egoist/path-parser'\n      export type Opts = {\n        parser: PathParser\n        route: string\n      }\n      `,\n    },\n    {\n      flags: ['--dts', '--dts-resolve'],\n    },\n  )\n})\n"
  },
  {
    "path": "test/experimental-dts.test.ts",
    "content": "import { test } from 'vitest'\nimport type { Options } from '../src/index.js'\nimport { getTestName, run } from './utils.js'\n\ntest.for([\n  { moduleResolution: 'NodeNext', moduleKind: 'NodeNext' },\n  { moduleResolution: 'Node16', moduleKind: 'Node16' },\n  { moduleResolution: 'Bundler', moduleKind: 'ESNext' },\n  { moduleResolution: 'Bundler', moduleKind: 'Preserve' },\n  { moduleResolution: 'Node10', moduleKind: 'ESNext' },\n  { moduleResolution: 'Node10', moduleKind: 'CommonJS' },\n  { moduleResolution: 'Node', moduleKind: 'ESNext' },\n  { moduleResolution: 'Node', moduleKind: 'CommonJS' },\n] as const)(\n  \"experimentalDts works with TypeScript's $moduleResolution module resolution and module set to $moduleKind\",\n  async ({ moduleResolution, moduleKind }, { expect, task }) => {\n    const { getFileContent, outFiles } = await run(\n      getTestName(),\n      {\n        'src/types.ts': `export type Person = { name: string }`,\n        'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n        'tsup.config.ts': `export default ${JSON.stringify(\n          {\n            name: task.name,\n            entry: { index: 'src/index.ts' },\n            format: ['esm', 'cjs'],\n            experimentalDts: true,\n          } satisfies Options,\n          null,\n          2,\n        )}`,\n        'package.json': JSON.stringify(\n          {\n            name: 'testing-experimental-dts',\n            description: task.name,\n            type: 'module',\n          },\n          null,\n          2,\n        ),\n        'tsconfig.json': JSON.stringify(\n          {\n            compilerOptions: {\n              module: moduleKind,\n              moduleResolution,\n              outDir: './dist',\n              rootDir: './src',\n              skipLibCheck: true,\n              strict: true,\n            },\n            include: ['src'],\n          },\n          null,\n          2,\n        ),\n      },\n      {\n        entry: [],\n      },\n    )\n\n    expect(outFiles).toStrictEqual([\n      '_tsup-dts-rollup.d.cts',\n      '_tsup-dts-rollup.d.ts',\n      'index.cjs',\n      'index.d.cts',\n      'index.d.ts',\n      'index.js',\n    ])\n\n    const indexDtsContent = [\n      `export { foo } from './_tsup-dts-rollup.js';`,\n      `export { Person } from './_tsup-dts-rollup.js';\\n`,\n    ].join('\\n')\n\n    expect(await getFileContent('dist/index.d.ts')).toStrictEqual(\n      indexDtsContent,\n    )\n\n    expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n      indexDtsContent.replaceAll(\n        `'./_tsup-dts-rollup.js'`,\n        `'./_tsup-dts-rollup.cjs'`,\n      ),\n    )\n  },\n)\n\ntest('experimentalDts works when `entry` is set to an array', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: ['src/index.ts'],\n          format: ['esm', 'cjs'],\n          experimentalDts: true,\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'testing-experimental-dts-entry-array',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n\ntest('experimentalDts works when `entry` is set to an array of globs', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: ['src/**/*.ts'],\n          format: ['esm', 'cjs'],\n          experimentalDts: true,\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'entry-array-of-globs',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n    'types.cjs',\n    'types.d.cts',\n    'types.d.ts',\n    'types.js',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  const typesDtsContent = `export { Person_alias_1 as Person } from './_tsup-dts-rollup.js';\\n`\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n\n  expect(await getFileContent('dist/types.d.ts')).toStrictEqual(typesDtsContent)\n\n  expect(await getFileContent('dist/types.d.cts')).toStrictEqual(\n    typesDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n\ntest('experimentalDts.entry can work independent from `options.entry`', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: ['src/**/*.ts'],\n          format: ['esm', 'cjs'],\n          experimentalDts: { entry: { index: 'src/index.ts' } },\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'testing-experimental-dts-entry-can-work-independent',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n    'types.cjs',\n    'types.js',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n\ntest('experimentalDts.entry can be an array of globs', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: { index: 'src/index.ts' },\n          format: ['esm', 'cjs'],\n          experimentalDts: { entry: ['src/**/*.ts'] },\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'testing-experimental-dts-entry-array-of-globs',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n    'types.d.cts',\n    'types.d.ts',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n\ntest('experimentalDts can be a string', async ({ expect, task }) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: ['src/**/*.ts'],\n          format: ['esm', 'cjs'],\n          experimentalDts: 'src/index.ts',\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'testing-experimental-dts-can-be-a-string',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n    'types.cjs',\n    'types.js',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n\ntest('experimentalDts can be a string of glob pattern', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: { index: 'src/index.ts' },\n          format: ['esm', 'cjs'],\n          experimentalDts: 'src/**/*.ts',\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'testing-experimental-dts-can-be-a-string-of-glob-pattern',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n    'types.d.cts',\n    'types.d.ts',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n\ntest('experimentalDts.entry can be a string of glob pattern', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/types.ts': `export type Person = { name: string }`,\n      'src/index.ts': `export const foo = [1, 2, 3]\\nexport type { Person } from './types.js'`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: { index: 'src/index.ts' },\n          format: ['esm', 'cjs'],\n          experimentalDts: { entry: 'src/**/*.ts' },\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'testing-experimental-dts-entry-can-be-a-string-of-glob-pattern',\n          description: task.name,\n          type: 'module',\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual([\n    '_tsup-dts-rollup.d.cts',\n    '_tsup-dts-rollup.d.ts',\n    'index.cjs',\n    'index.d.cts',\n    'index.d.ts',\n    'index.js',\n    'types.d.cts',\n    'types.d.ts',\n  ])\n\n  const indexDtsContent = [\n    `export { foo } from './_tsup-dts-rollup.js';`,\n    `export { Person } from './_tsup-dts-rollup.js';\\n`,\n  ].join('\\n')\n\n  expect(await getFileContent('dist/index.d.ts')).toStrictEqual(indexDtsContent)\n\n  expect(await getFileContent('dist/index.d.cts')).toStrictEqual(\n    indexDtsContent.replaceAll(\n      `'./_tsup-dts-rollup.js'`,\n      `'./_tsup-dts-rollup.cjs'`,\n    ),\n  )\n})\n"
  },
  {
    "path": "test/graphql.test.ts",
    "content": "import { expect, test } from 'vitest'\nimport { getTestName, run } from './utils'\n\ntest('bundle graphql-tools with --dts flag', async () => {\n  await run(\n    getTestName(),\n    {\n      'input.ts': `export { makeExecutableSchema } from 'graphql-tools'`,\n    },\n    {\n      flags: ['--dts'],\n    },\n  )\n})\n\ntest('bundle graphql-tools with --dts-resolve flag', async () => {\n  await run(\n    getTestName(),\n    {\n      'input.ts': `export { makeExecutableSchema } from 'graphql-tools'`,\n    },\n    {\n      flags: ['--dts-resolve'],\n    },\n  )\n})\n\ntest('bundle graphql-tools with --sourcemap flag', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `export { makeExecutableSchema } from 'graphql-tools'`,\n    },\n    {\n      flags: ['--sourcemap'],\n    },\n  )\n  expect(outFiles).toEqual(['input.js', 'input.js.map'])\n})\n\ntest('bundle graphql-tools with --sourcemap inline flag', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `export { makeExecutableSchema } from 'graphql-tools'`,\n    },\n    {\n      flags: ['--sourcemap', 'inline'],\n    },\n  )\n\n  expect(output).toContain('//# sourceMappingURL=data:application/json;base64')\n  expect(outFiles).toEqual(['input.js'])\n})\n"
  },
  {
    "path": "test/index.test.ts",
    "content": "import path from 'node:path'\nimport fs from 'node:fs'\nimport { expect, test } from 'vitest'\nimport waitForExpect from 'wait-for-expect'\nimport { debouncePromise } from '../src/utils'\nimport { getTestName, run } from './utils'\n\ntest('simple', async () => {\n  const { output, outFiles } = await run(getTestName(), {\n    'input.ts': `import foo from './foo';export default foo`,\n    'foo.ts': `export default 'foo'`,\n  })\n  expect(output).toMatchSnapshot()\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('should not filter unknown directives during bundle', async () => {\n  const { output, outFiles } = await run(getTestName(), {\n    'input.ts': `'use client'\\nexport default 'foo'`,\n  })\n  expect(output).toContain('use client')\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('multiple formats', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export const a = 1\n    `,\n    },\n    {\n      flags: ['--format', 'esm,cjs,iife'],\n    },\n  )\n\n  expect(outFiles).toEqual(['input.global.js', 'input.js', 'input.mjs'])\n})\n\ntest('multiple formats and pkg.type is module', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export const a = 1\n    `,\n      'package.json': JSON.stringify({ type: 'module' }),\n    },\n    {\n      flags: ['--format', 'esm,cjs,iife'],\n    },\n  )\n\n  expect(outFiles).toEqual(['input.cjs', 'input.global.js', 'input.js'])\n})\n\ntest('minify', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export function foo() {\n      return 'foo'\n    }\n    `,\n    },\n    {\n      flags: ['--minify'],\n    },\n  )\n\n  expect(output).toContain(`return\"foo\"`)\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('minify with es5 target', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export function foo() {\n      return 'foo'\n    }\n    `,\n    },\n    {\n      flags: ['--minify', '--target', 'es5'],\n    },\n  )\n\n  expect(output).toContain(`return\"foo\"`)\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('env flag', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export const env = process.env.NODE_ENV\n    `,\n    },\n    {\n      flags: ['--env.NODE_ENV', 'production'],\n    },\n  )\n\n  expect(output).toContain('var env = \"production\"')\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('node protocol', async () => {\n  const { output } = await run(getTestName(), {\n    'input.ts': `import fs from 'node:fs'; console.log(fs)`,\n  })\n  expect(output).toMatchSnapshot()\n  expect(output).not.contain('node:fs')\n})\n\ntest(\"don't remove node protocol\", async () => {\n  const { output } = await run(getTestName(), {\n    'input.ts': `import fs from 'node:fs'; console.log(fs)`,\n    'tsup.config.ts': `\n    export default {\n      removeNodeProtocol: false,\n    }`,\n  })\n  expect(output).toMatchSnapshot()\n  expect(output).contain('node:fs')\n})\n\ntest('external', async () => {\n  const { output } = await run(getTestName(), {\n    'input.ts': `export {foo} from 'foo'\n    export {bar} from 'bar'\n    export {baz} from 'baz'\n    export {qux} from 'qux'\n    `,\n    'node_modules/foo/index.ts': `export const foo = 'foo'`,\n    'node_modules/foo/package.json': `{\"name\":\"foo\",\"version\":\"0.0.0\"}`,\n    'node_modules/bar/index.ts': `export const bar = 'bar'`,\n    'node_modules/bar/package.json': `{\"name\":\"bar\",\"version\":\"0.0.0\"}`,\n    'node_modules/baz/index.ts': `export const baz = 'baz'`,\n    'node_modules/baz/package.json': `{\"name\":\"baz\",\"version\":\"0.0.0\"}`,\n    'node_modules/qux/index.ts': `export const qux = 'qux'`,\n    'node_modules/qux/package.json': `{\"name\":\"qux\",\"version\":\"0.0.0\"}`,\n    'another/package.json': `{\"name\":\"another-pkg\",\"dependencies\":{\"qux\":\"0.0.0\"}}`,\n    'tsup.config.ts': `\n    export default {\n      external: [/f/, 'bar', 'another/package.json']\n    }\n    `,\n  })\n  expect(output).toMatchSnapshot()\n})\n\ntest('noExternal are respected when skipNodeModulesBundle is true', async () => {\n  const { output } = await run(getTestName(), {\n    'input.ts': `export {foo} from 'foo'\n    export {bar} from 'bar'\n    export {baz} from 'baz'\n    `,\n    'node_modules/foo/index.ts': `export const foo = 'foo'`,\n    'node_modules/foo/package.json': `{\"name\":\"foo\",\"version\":\"0.0.0\"}`,\n    'node_modules/bar/index.ts': `export const bar = 'bar'`,\n    'node_modules/bar/package.json': `{\"name\":\"bar\",\"version\":\"0.0.0\"}`,\n    'node_modules/baz/index.ts': `export const baz = 'baz'`,\n    'node_modules/baz/package.json': `{\"name\":\"baz\",\"version\":\"0.0.0\"}`,\n    'tsup.config.ts': `\n    export default {\n      skipNodeModulesBundle: true,\n      noExternal: [/foo/]\n    }\n    `,\n  })\n  expect(output).toContain(`var foo = \"foo\"`)\n  expect(output).not.toContain(`var bar = \"bar\"`)\n  expect(output).not.toContain(`var baz = \"baz\"`)\n})\n\ntest('disable code splitting to get proper module.exports =', async () => {\n  const { output } = await run(\n    getTestName(),\n    {\n      'input.ts': `export = 123`,\n    },\n    {\n      flags: ['--no-splitting'],\n    },\n  )\n  expect(output).toMatchSnapshot()\n})\n\ntest('onSuccess', async () => {\n  const { logs } = await run(\n    getTestName(),\n    {\n      'input.ts': \"console.log('test');\",\n    },\n    {\n      flags: ['--onSuccess', 'echo hello && echo world'],\n    },\n  )\n\n  expect(logs.includes('hello')).toEqual(true)\n  expect(logs.includes('world')).toEqual(true)\n})\n\ntest('onSuccess: use a function from config file', async () => {\n  const { logs } = await run(getTestName(), {\n    'input.ts': \"console.log('test');\",\n    'tsup.config.ts': `\n        export default {\n          onSuccess: async () => {\n            console.log('hello')\n            await new Promise((resolve) => {\n              setTimeout(() => {\n                console.log('world')\n                resolve('')  \n              }, 1_000)\n            })\n          }\n        }`,\n  })\n\n  expect(logs.includes('hello')).toEqual(true)\n  expect(logs.includes('world')).toEqual(true)\n})\n\ntest(`transform import.meta.url in cjs format`, async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `export default import.meta.url`,\n    },\n    {\n      flags: ['--shims'],\n    },\n  )\n  expect(await getFileContent('dist/input.js')).toContain('getImportMetaUrl')\n})\n\ntest(`transform __dirname and __filename in esm format`, async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `export const a = __dirname\n    export const b = __filename\n    `,\n    },\n    {\n      flags: ['--format', 'esm', '--shims'],\n    },\n  )\n  const code = await getFileContent('dist/input.mjs')\n\n  expect(code).toContain('getFilename')\n  expect(code).toContain('getDirname')\n})\n\ntest('debounce promise', async () => {\n  try {\n    const equal = <T>(a: T, b: T) => {\n      const result = a === b\n      if (!result) throw new Error(`${a} !== ${b}`)\n    }\n\n    const sleep = (n: number = Math.trunc(Math.random() * 50) + 20) =>\n      new Promise<void>((resolve) => setTimeout(resolve, n))\n\n    let n = 0\n\n    const debounceFunction = debouncePromise(\n      async () => {\n        await sleep()\n        ++n\n      },\n      100,\n      (err: any) => {\n        expect.fail(err.message)\n      },\n    )\n\n    expect(n).toEqual(0)\n\n    debounceFunction()\n    debounceFunction()\n    debounceFunction()\n    debounceFunction()\n\n    await waitForExpect(() => {\n      equal(n, 1)\n    })\n    await sleep(100)\n\n    expect(n).toEqual(1)\n\n    debounceFunction()\n\n    await waitForExpect(() => {\n      equal(n, 2)\n    })\n  } catch (error: any) {\n    return expect.fail(error.message)\n  }\n})\n\ntest('exclude dependencies', async () => {\n  const { getFileContent } = await run(getTestName(), {\n    'input.ts': `export {foo} from 'foo';export {nested} from 'foo/nested'`,\n    'package.json': `{\"dependencies\":{\"foo\":\"0.0.0\"}}`,\n    'node_modules/foo/index.js': `export const foo = 'foo'`,\n    'node_modules/foo/package.json': `{\"name\":\"foo\"}`,\n  })\n  const contents = await getFileContent('dist/input.js')\n  expect(contents).toContain('require(\"foo\")')\n  expect(contents).toContain('require(\"foo/nested\")')\n})\n\ntest('code splitting in cjs format', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `const foo = () => import('./foo');export {foo}`,\n      'another-input.ts': `const foo = () => import('./foo');export {foo}`,\n      'foo.ts': `export const foo = 'bar'`,\n    },\n    { flags: ['another-input.ts', '--splitting'] },\n  )\n  expect(await getFileContent('dist/input.js')).toMatchSnapshot()\n  expect(await getFileContent('dist/another-input.js')).toMatchSnapshot()\n})\n\ntest('esbuild metafile', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    { 'input.ts': `export const foo = 1` },\n    {\n      flags: ['--metafile'],\n    },\n  )\n  expect(outFiles).toEqual(['input.js', 'metafile-cjs.json'])\n})\n\ntest('multiple entry with the same base name', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'src/input.ts': `export const foo = 1`,\n      'src/bar/input.ts': `export const bar = 2`,\n    },\n    {\n      entry: ['src/input.ts', 'src/bar/input.ts'],\n    },\n  )\n  expect(outFiles).toEqual(['bar/input.js', 'input.js'])\n})\n\ntest('windows: backslash in entry', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    { 'src/input.ts': `export const foo = 1` },\n    {\n      entry: [String.raw`src\\input.ts`],\n    },\n  )\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('emit declaration files only', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `export const foo = 1`,\n    },\n    {\n      flags: ['--dts-only'],\n    },\n  )\n  expect(outFiles).toEqual(['input.d.ts'])\n})\n\ntest('decorator metadata', async () => {\n  const { getFileContent } = await run(getTestName(), {\n    'input.ts': `\n        function Injectable() {}\n\n        @Injectable()\n        export class Foo {\n          @Field()\n          bar() {}\n        }\n      `,\n    'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"emitDecoratorMetadata\": true,\n        }\n      }`,\n  })\n  const contents = await getFileContent('dist/input.js')\n  expect(contents).toContain(`_ts_metadata(\"design:type\", Function)`)\n})\n\ntest('inject style', async () => {\n  const { outFiles, output } = await run(\n    getTestName(),\n    {\n      'input.ts': `import './style.css'`,\n      'style.css': `.hello { color: red }`,\n    },\n    {\n      flags: ['--inject-style', '--minify'],\n    },\n  )\n  expect(outFiles).toEqual(['input.js'])\n  expect(output).toContain('.hello{color:red}')\n})\n\ntest('inject style in multi formats', async () => {\n  const { outFiles, getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `export * from './App.svelte'`,\n      'App.svelte': `\n      <span>{msg}</span>\n\n      <style>\n      span {color: red}\n      </style>`,\n    },\n    {\n      flags: ['--inject-style', '--minify', '--format', 'esm,cjs,iife'],\n    },\n  )\n  expect(outFiles).toEqual(['input.global.js', 'input.js', 'input.mjs'])\n  for (const file of outFiles) {\n    expect(await getFileContent(`dist/${file}`)).toContain('{color:red}')\n  }\n})\n\ntest('shebang', async () => {\n  const { outDir } = await run(\n    getTestName(),\n    {\n      'a.ts': `#!/usr/bin/env node\\bconsole.log('a')`,\n      'b.ts': `console.log('b')`,\n    },\n    {\n      entry: ['a.ts', 'b.ts'],\n    },\n  )\n\n  if (process.platform === 'win32') {\n    return\n  }\n\n  expect(() => {\n    fs.accessSync(path.join(outDir, 'a.js'), fs.constants.X_OK)\n  }).not.toThrow()\n  expect(() => {\n    fs.accessSync(path.join(outDir, 'b.js'), fs.constants.X_OK)\n  }).toThrow()\n})\n\ntest('es5 target', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export class Foo {\n      hi (): void {\n        let a = () => 'foo'\n\n        console.log(a())\n      }\n    }\n    `,\n    },\n    {\n      flags: ['--target', 'es5'],\n    },\n  )\n  expect(output).toMatch(/_create_class/)\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('es5 minify', async () => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n    export class Foo {\n      hi (): void {\n        let a = () => 'foo'\n\n        console.log(a())\n      }\n    }\n    `,\n    },\n    {\n      flags: [\n        '--target',\n        'es5',\n        '--format',\n        'iife',\n        '--globalName',\n        'FooAPI',\n        '--minify',\n      ],\n    },\n  )\n  expect(outFiles).toEqual(['input.global.js'])\n  const iifeBundle = await getFileContent('dist/input.global.js')\n  expect(iifeBundle).toMatch(/var FooAPI/)\n  expect(iifeBundle).not.toMatch(/createClass/)\n})\n\ntest('multiple targets', async () => {\n  const { output, outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n      export const answer = 42\n      `,\n    },\n    {\n      entry: ['input.ts'],\n      flags: ['--target', 'es2020,chrome58,firefox57,safari11,edge16'],\n    },\n  )\n  expect(output).toMatchSnapshot()\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('native-node-module plugin should handle *.node(.js) import properly', async () => {\n  await run(\n    getTestName(),\n    {\n      'input.tsx': `export * from './hi.node'`,\n      'hi.node.js': `export const hi = 'hi'`,\n    },\n    {\n      entry: ['input.tsx'],\n    },\n  )\n})\n\ntest('proper sourcemap sources path when swc is enabled', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `export const hi = 'hi'`,\n      'tsconfig.json': JSON.stringify({\n        compilerOptions: {\n          emitDecoratorMetadata: true,\n        },\n      }),\n    },\n    {\n      entry: ['input.ts'],\n      flags: ['--sourcemap'],\n    },\n  )\n  const map = await getFileContent('dist/input.js.map')\n  expect(map).toContain(`[\"../input.ts\"]`)\n})\n\n// Fixing https://github.com/evanw/esbuild/issues/1794\ntest('use rollup for treeshaking', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `\n      export { useRoute } from 'vue-router'\n      `,\n    },\n    {\n      entry: ['input.ts'],\n      flags: ['--treeshake', '--external', 'vue', '--format', 'esm'],\n    },\n  )\n  expect(await getFileContent('dist/input.mjs')).toContain(\n    `function useRoute(_name) {\n  return inject(routeLocationKey);\n}`,\n  )\n})\n\ntest('use rollup for treeshaking --format cjs', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'package.json': `{\n        \"dependencies\": {\n          \"react-select\": \"5.7.0\",\n          \"react\": \"17.0.2\",\n          \"react-dom\": \"17.0.2\"\n        }\n      }`,\n      'input.tsx': `\n      import ReactSelect from 'react-select'\n      \n      export const Component = (props: {}) => {\n        return <ReactSelect {...props} />\n      };\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"baseUrl\": \".\",\n          \"esModuleInterop\": true,\n          \"isolatedModules\": true,\n          \"jsx\": \"react-jsx\",\n          \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n          \"module\": \"esnext\",\n          \"moduleResolution\": \"node\",\n          \"noEmit\": true,\n          \"rootDir\": \".\",\n          \"skipLibCheck\": true,\n          \"sourceMap\": true,\n          \"strict\": true,\n          \"target\": \"es6\",\n          \"importHelpers\": true,\n          \"outDir\": \"dist\"\n        }\n      }`,\n    },\n    {\n      entry: ['input.tsx'],\n      flags: ['--treeshake', '--target', 'es2022', '--format', 'cjs'],\n    },\n  )\n\n  expect(await getFileContent('dist/input.js')).toContain(\n    `jsxRuntime.jsx(ReactSelect__default.default`,\n  )\n})\n\ntest('custom output extension', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `export const foo = [1,2,3]`,\n      'tsup.config.ts': `export default {\n        outExtension({ format }) {\n          return {\n            js: '.' + format + '.js'\n          }\n        }\n      }`,\n    },\n    {\n      entry: ['input.ts'],\n      flags: ['--format', 'esm,cjs'],\n    },\n  )\n  expect(outFiles).toMatchInlineSnapshot(`\n    [\n      \"input.cjs.js\",\n      \"input.esm.js\",\n    ]\n  `)\n})\n\ntest('custom config file', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `export const foo = [1,2,3]`,\n      'custom.config.ts': `export default {\n        format: ['esm']\n      }`,\n    },\n    {\n      entry: ['input.ts'],\n      flags: ['--config', 'custom.config.ts'],\n    },\n  )\n  expect(outFiles).toMatchInlineSnapshot(`\n    [\n      \"input.mjs\",\n    ]\n  `)\n})\n\ntest('use an object as entry from cli flag', async () => {\n  const { outFiles } = await run(\n    getTestName(),\n    {\n      'input.ts': `export const foo = [1,2,3]`,\n    },\n    {\n      flags: ['--entry.foo', 'input.ts'],\n    },\n  )\n  expect(outFiles).toMatchInlineSnapshot(`\n    [\n      \"foo.js\",\n    ]\n  `)\n})\n\ntest('remove unused code', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `if (import.meta.foo) {\n        console.log(1)\n      } else {\n        console.log(2)\n      }`,\n      'tsup.config.ts': `export default {\n        define: {\n          'import.meta.foo': 'false'\n        },\n        treeshake: true\n      }`,\n    },\n    {},\n  )\n  expect(await getFileContent('dist/input.js')).not.toContain('console.log(1)')\n})\n\ntest('treeshake should work with hashbang', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': '#!/usr/bin/node\\nconsole.log(123)',\n    },\n    {\n      flags: ['--treeshake'],\n    },\n  )\n  expect(await getFileContent('dist/input.js')).toMatchInlineSnapshot(`\n    \"#!/usr/bin/node\n    'use strict';\n\n    // input.ts\n    console.log(123);\n    \"\n  `)\n})\n\ntest('support target in tsconfig.json', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `await import('./foo')`,\n      'foo.ts': `export default 'foo'`,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"baseUrl\":\".\",\n          \"target\": \"esnext\"\n        }\n      }`,\n    },\n    {\n      flags: ['--format', 'esm'],\n    },\n  )\n  expect(await getFileContent('dist/input.mjs')).contains('await import(')\n})\n\ntest('override target in tsconfig.json', async () => {\n  await expect(\n    run(\n      getTestName(),\n      {\n        'input.ts': `await import('./foo')`,\n        'foo.ts': `export default 'foo'`,\n        'tsconfig.json': `{\n          \"compilerOptions\": {\n            \"baseUrl\":\".\",\n            \"target\": \"esnext\"\n          }\n        }`,\n      },\n      {\n        flags: ['--format', 'esm', '--target', 'es2018'],\n      },\n    ),\n  ).rejects.toThrowError(\n    `Top-level await is not available in the configured target environment (\"es2018\")`,\n  )\n})\n\ntest(`should generate export {} when there are no exports in source file`, async () => {\n  const { outFiles, getFileContent } = await run(getTestName(), {\n    'input.ts': `const a = 'a'`,\n    'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"baseUrl\":\".\",\n          \"target\": \"esnext\",\n        }\n      }`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          format: 'esm',\n          dts: true\n        }\n      `,\n  })\n  expect(outFiles).toEqual(['input.d.mts', 'input.mjs'])\n  expect(await getFileContent('dist/input.d.mts')).toMatch(/export {\\s*}/)\n})\n\ntest('custom inject style function - sync', async () => {\n  const { outFiles, getFileContent } = await run(getTestName(), {\n    'input.ts': `import './style.css'`,\n    'style.css': `.hello { color: red }`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          minify: true,\n          format: ['esm', 'cjs'],\n          injectStyle: (css) => {\n            return \"__custom_inject_style__(\" + css +\")\";\n          }\n        }`,\n  })\n  expect(outFiles).toEqual(['input.js', 'input.mjs'])\n  expect(await getFileContent('dist/input.mjs')).toContain(\n    '__custom_inject_style__(`.hello{color:red}\\n`)',\n  )\n  expect(await getFileContent('dist/input.js')).toContain(\n    '__custom_inject_style__(`.hello{color:red}\\n`)',\n  )\n})\n\ntest('custom inject style function - async', async () => {\n  const { outFiles, getFileContent } = await run(getTestName(), {\n    'input.ts': `import './style.css'`,\n    'style.css': `.hello { color: red }`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          minify: true,\n          format: ['esm', 'cjs'],\n          injectStyle: async (css) => {\n            await new Promise(resolve => setTimeout(resolve, 100));\n            return \"__custom_async_inject_style__(\" + css +\")\";\n          }\n        }`,\n  })\n  expect(outFiles).toEqual(['input.js', 'input.mjs'])\n  expect(await getFileContent('dist/input.mjs')).toContain(\n    '__custom_async_inject_style__(`.hello{color:red}\\n`)',\n  )\n  expect(await getFileContent('dist/input.js')).toContain(\n    '__custom_async_inject_style__(`.hello{color:red}\\n`)',\n  )\n})\n\ntest('preserve top-level variable for IIFE format', async () => {\n  const { outFiles, getFileContent } = await run(getTestName(), {\n    'input.ts': `export default 'foo'`,\n    'tsup.config.ts': `\n        export default {\n          entry: ['src/input.ts'],\n          globalName: 'globalFoo',\n          minify: 'terser',\n          format: ['iife']\n        }`,\n  })\n  expect(outFiles).toEqual(['input.global.js'])\n  expect(await getFileContent('dist/input.global.js')).toMatch(/globalFoo\\s*=/)\n})\n\ntest('should load postcss esm config', async () => {\n  const { outFiles, getFileContent } = await run(getTestName(), {\n    'input.ts': `\n    import './foo.css'\n    `,\n    'package.json': `{\n      \"type\": \"module\"\n    }`,\n    'postcss.config.js': `\n    export default {\n      plugins: {'postcss-simple-vars': {}}\n    }\n    `,\n    'foo.css': `\n  $color: blue;\n\n  .foo {\n    color: $color;\n  }\n    `,\n  })\n\n  expect(outFiles).toEqual(['input.cjs', 'input.css'])\n  expect(await getFileContent('dist/input.css')).toContain('color: blue;')\n})\n\ntest('generate sourcemap with --treeshake', async () => {\n  const sourceCode = 'export function getValue(val: any){ return val; }'\n  const { outFiles, getFileContent } = await run(\n    getTestName(),\n    {\n      'src/input.ts': sourceCode,\n    },\n    {\n      entry: ['src/input.ts'],\n      flags: ['--treeshake', '--sourcemap', '--format=cjs,esm,iife'],\n    },\n  )\n\n  expect(outFiles.length).toBe(6)\n\n  await Promise.all(\n    outFiles\n      .filter((fileName) => fileName.endsWith('.map'))\n      .map(async (sourceMapFile) => {\n        const sourceMap = await getFileContent(`dist/${sourceMapFile}`).then(\n          (rawContent) => JSON.parse(rawContent),\n        )\n\n        expect(sourceMap.sources[0]).toBe('../src/input.ts')\n        expect(sourceMap.sourcesContent[0]).toBe(sourceCode)\n\n        const outputFileName = sourceMapFile.replace('.map', '')\n        expect(sourceMap.file).toBe(outputFileName)\n      }),\n  )\n})\n"
  },
  {
    "path": "test/package.json",
    "content": "{\n  \"private\": true,\n  \"devDependencies\": {\n    \"@egoist/path-parser\": \"1.0.6\",\n    \"@types/react\": \"18.3.6\",\n    \"@types/react-dom\": \"18.3.0\",\n    \"autoprefixer\": \"10.4.20\",\n    \"graphql\": \"^16.9.0\",\n    \"graphql-tools\": \"^9.0.1\",\n    \"react\": \"18.3.1\",\n    \"react-dom\": \"18.3.1\",\n    \"react-select\": \"5.8.0\",\n    \"tailwindcss\": \"3.4.11\",\n    \"vue\": \"3.5.6\",\n    \"vue-router\": \"4.4.5\"\n  },\n  \"tsup\": {}\n}\n"
  },
  {
    "path": "test/shims.test.ts",
    "content": "import { test } from 'vitest'\nimport type { Options } from '../src/index.js'\nimport { getTestName, run } from './utils.js'\n\ntest('removeNodeProtocol works on shims', async ({ expect, task }) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/index.ts': 'export const foo = __dirname',\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: { index: 'src/index.ts' },\n          format: ['esm'],\n          shims: true,\n          removeNodeProtocol: true,\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'remove-node-protocol-works-on-shims',\n          description: task.name,\n          type: 'commonjs',\n          sideEffects: false,\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual(['index.mjs'])\n\n  const indexMjsContent = `// ../../../assets/esm_shims.js\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nvar getFilename = () => fileURLToPath(import.meta.url);\nvar getDirname = () => path.dirname(getFilename());\nvar __dirname = /* @__PURE__ */ getDirname();\n\n// src/index.ts\nvar foo = __dirname;\nexport {\n  foo\n};\n`\n\n  expect(await getFileContent('dist/index.mjs')).toStrictEqual(indexMjsContent)\n})\n\ntest('disabling removeNodeProtocol retains node protocol in shims', async ({\n  expect,\n  task,\n}) => {\n  const { getFileContent, outFiles } = await run(\n    getTestName(),\n    {\n      'src/index.ts': `export const foo = __dirname`,\n      'tsup.config.ts': `export default ${JSON.stringify(\n        {\n          name: task.name,\n          entry: { index: 'src/index.ts' },\n          format: ['esm'],\n          shims: true,\n          removeNodeProtocol: false,\n        } satisfies Options,\n        null,\n        2,\n      )}`,\n      'package.json': JSON.stringify(\n        {\n          name: 'disabling-remove-node-protocol-retains-node-protocol-in-shims',\n          description: task.name,\n          type: 'commonjs',\n          sideEffects: false,\n        },\n        null,\n        2,\n      ),\n      'tsconfig.json': JSON.stringify(\n        {\n          compilerOptions: {\n            outDir: './dist',\n            rootDir: './src',\n            skipLibCheck: true,\n            strict: true,\n          },\n          include: ['src'],\n        },\n        null,\n        2,\n      ),\n    },\n    {\n      entry: [],\n    },\n  )\n\n  expect(outFiles).toStrictEqual(['index.mjs'])\n\n  const indexMjsContent = `// ../../../assets/esm_shims.js\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nvar getFilename = () => fileURLToPath(import.meta.url);\nvar getDirname = () => path.dirname(getFilename());\nvar __dirname = /* @__PURE__ */ getDirname();\n\n// src/index.ts\nvar foo = __dirname;\nexport {\n  foo\n};\n`\n\n  expect(await getFileContent('dist/index.mjs')).toStrictEqual(indexMjsContent)\n})\n"
  },
  {
    "path": "test/svelte.test.ts",
    "content": "import { expect, test } from 'vitest'\nimport { getTestName, run } from './utils'\n\ntest('bundle svelte', async () => {\n  const { output, getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `import App from './App.svelte'\n      export { App }\n      `,\n      'App.svelte': `\n      <script>\n      let msg = 'hello svelte'\n      </script>\n\n      <span>{msg}</span>\n\n      <style>\n      span {color: red}\n      </style>\n      `,\n    },\n    {\n      // To make the snapshot leaner\n      flags: ['--external', 'svelte/internal'],\n    },\n  )\n  expect(output).not.toContain('<script>')\n  const css = await getFileContent('dist/input.css')\n  expect(css).toContain('color: red;')\n})\n\ntest('bundle svelte without styles', async () => {\n  const { outFiles } = await run(getTestName(), {\n    'input.ts': `import App from './App.svelte'\n      export { App }\n      `,\n    'App.svelte': `\n      <script>\n      let msg = 'hello svelte'\n      </script>\n\n      <span>{msg}</span>\n      `,\n  })\n\n  expect(outFiles).toEqual(['input.js'])\n})\n\ntest('svelte: typescript support', async () => {\n  const { outFiles, output } = await run(getTestName(), {\n    'input.ts': `import App from './App.svelte'\n      export { App }\n      `,\n    'App.svelte': `\n      <script lang=\"ts\">\n      import Component from './Component.svelte'\n      let say: string = 'hello'\n      let name: string = 'svelte'\n      </script>\n\n      <Component {name}>{say}</Component>\n      `,\n    'Component.svelte': `\n      <script lang=\"ts\">\n      export let name: string\n      </script>\n\n      <slot /> {name}\n    `,\n  })\n\n  expect(outFiles).toEqual(['input.js'])\n  expect(output).toContain('// Component.svelte')\n})\n\ntest('svelte: sass support', async () => {\n  const { outFiles, getFileContent } = await run(getTestName(), {\n    'input.ts': `import App from './App.svelte'\n      export { App }\n      `,\n    'App.svelte': `\n      <div class=\"test\">Hello</div>\n      <style lang=\"scss\">\n      .test { &:hover { color: red } }\n      </style>\n      `,\n  })\n\n  expect(outFiles).toEqual(['input.css', 'input.js'])\n  const outputCss = await getFileContent('dist/input.css')\n  expect(outputCss).toMatch(/\\.svelte-\\w+:hover/)\n})\n"
  },
  {
    "path": "test/tsconfig.test.ts",
    "content": "import { expect, test } from 'vitest'\nimport { getTestName, run } from './utils'\n\ntest('custom tsconfig', async () => {\n  await run(\n    getTestName(),\n    {\n      'input.ts': `export const foo = 'foo'`,\n      'tsconfig.build.json': `{\n      \"compilerOptions\": {\n        \"baseUrl\":\".\"\n      }\n    }`,\n    },\n    { flags: ['--tsconfig', 'tsconfig.build.json'] },\n  )\n})\n\ntest('support baseUrl and paths in tsconfig.json', async () => {\n  const { getFileContent } = await run(getTestName(), {\n    'input.ts': `export * from '@/foo'`,\n    'foo.ts': `export const foo = 'foo'`,\n    'tsconfig.json': `{\n      \"compilerOptions\": {\n        \"baseUrl\":\".\",\n        \"paths\":{\"@/*\": [\"./*\"]}\n      }\n    }`,\n  })\n  expect(await getFileContent('dist/input.js')).toMatchSnapshot()\n})\n\ntest('support baseUrl and paths in tsconfig.json in --dts build', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `export * from '@/foo'`,\n      'src/foo.ts': `export const foo = 'foo'`,\n      'tsconfig.json': `{\n      \"compilerOptions\": {\n        \"baseUrl\":\".\",\n        \"paths\":{\"@/*\": [\"./src/*\"]}\n      }\n    }`,\n    },\n    { flags: ['--dts'] },\n  )\n  expect(await getFileContent('dist/input.d.ts')).toMatchSnapshot()\n})\n\ntest('support baseUrl and paths in tsconfig.json in --dts-resolve build', async () => {\n  const { getFileContent } = await run(\n    getTestName(),\n    {\n      'input.ts': `export * from '@/foo'`,\n      'src/foo.ts': `export const foo = 'foo'`,\n      'tsconfig.json': `{\n      \"compilerOptions\": {\n        \"baseUrl\":\".\",\n        \"paths\":{\"@/*\": [\"./src/*\"]}\n      }\n    }`,\n    },\n    { flags: ['--dts-resolve'] },\n  )\n  expect(await getFileContent('dist/input.d.ts')).toMatchSnapshot()\n})\n"
  },
  {
    "path": "test/utils.ts",
    "content": "import fs from 'node:fs'\nimport fsp from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { expect } from 'vitest'\nimport { exec } from 'tinyexec'\nimport { glob } from 'tinyglobby'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst cacheDir = path.resolve(__dirname, '.cache')\nconst bin = path.resolve(__dirname, '../dist/cli-default.js')\n\nexport function getTestName() {\n  const name = expect\n    .getState()\n    .currentTestName?.replace(/^[a-z]+/g, '_')\n    .replace(/-/g, '_')\n\n  if (!name) {\n    throw new Error('No test name')\n  }\n\n  return name\n}\n\nexport async function run(\n  title: string,\n  files: { [name: string]: string },\n  options: {\n    entry?: string[]\n    flags?: string[]\n    env?: Record<string, string>\n  } = {},\n) {\n  const testDir = path.resolve(cacheDir, filenamify(title))\n\n  // Write entry files on disk\n  await Promise.all(\n    Object.keys(files).map(async (name) => {\n      const filePath = path.resolve(testDir, name)\n      const parentDir = path.dirname(filePath)\n      // Thanks to `recursive: true`, this doesn't fail even if the directory already exists.\n      await fsp.mkdir(parentDir, { recursive: true })\n      return fsp.writeFile(filePath, files[name], 'utf8')\n    }),\n  )\n\n  const entry = options.entry || ['input.ts']\n\n  // Run tsup cli\n  const processPromise = exec(bin, [...entry, ...(options.flags || [])], {\n    nodeOptions: {\n      cwd: testDir,\n      env: { ...process.env, ...options.env },\n    },\n  })\n  const { stdout, stderr } = await processPromise\n\n  const logs = stdout + stderr\n  if (processPromise.exitCode !== 0) {\n    throw new Error(logs)\n  }\n\n  // Get output\n  const outFiles = await glob(['**/*'], {\n    cwd: path.resolve(testDir, 'dist'),\n  }).then((res) => res.sort())\n\n  return {\n    get output() {\n      return fs.readFileSync(path.resolve(testDir, 'dist/input.js'), 'utf8')\n    },\n    outFiles,\n    logs,\n    outDir: path.resolve(testDir, 'dist'),\n    getFileContent(filename: string) {\n      return fsp.readFile(path.resolve(testDir, filename), 'utf8')\n    },\n  }\n}\n\nfunction filenamify(input: string) {\n  return input.replace(/[^a-zA-Z0-9]/g, '-')\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"lib\": [\"es2022\"],\n    \"moduleDetection\": \"force\",\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"types\": [\"node\"],\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true,\n    \"declarationDir\": \"dist\",\n    \"outDir\": \"./dist\",\n    \"esModuleInterop\": true,\n    \"isolatedModules\": true,\n    \"verbatimModuleSyntax\": true,\n    \"skipLibCheck\": true\n  }\n}\n"
  },
  {
    "path": "tsup.config.ts",
    "content": "import { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  name: 'tsup',\n  target: 'node18',\n  dts: {\n    resolve: true,\n    // build types for `src/index.ts` only\n    // otherwise `Options` will not be exported by `tsup`, not sure how this happens, probably a bug in rollup-plugin-dts\n    entry: './src/index.ts',\n  },\n})\n"
  },
  {
    "path": "vitest-global.ts",
    "content": "import path from 'node:path'\nimport fs from 'node:fs/promises'\nimport { exec } from 'tinyexec'\n\nexport default async function setup() {\n  const testDir = path.resolve(__dirname, 'test')\n  const cacheDir = path.resolve(testDir, '.cache')\n  await fs.rm(cacheDir, { recursive: true, force: true })\n  console.log(`Installing dependencies in ./test folder`)\n  await exec('pnpm', ['i'], { nodeOptions: { cwd: testDir } })\n  console.log(`Done... start testing..`)\n}\n"
  },
  {
    "path": "vitest.config.mts",
    "content": "import { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n  test: {\n    testTimeout: 50000,\n    globalSetup: 'vitest-global.ts',\n    include: [\"test/*.test.ts\", \"src/**/*.test.ts\"]\n  },\n})\n"
  }
]