tsdown 0.21.9 → 0.22.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,20 @@
1
1
  import { createRequire as __cjs_createRequire } from "node:module";
2
2
  const __cjs_require = __cjs_createRequire(import.meta.url);
3
- import { a as getPackageType, c as isGlobEntry, d as cleanOutDir, i as loadConfigFile, l as toObjectEntry, n as mergeUserOptions, o as writeExports, r as resolveUserConfig, s as buildExe, t as mergeConfig, u as cleanChunks } from "./options-8hmVMssn.mjs";
3
+ import { a as getPackageType, c as isGlobEntry, d as cleanOutDir, i as loadConfigFile, l as toObjectEntry, n as mergeUserOptions, o as writeExports, r as resolveUserConfig, s as buildExe, t as mergeConfig, u as cleanChunks } from "./options-DLofT9Im.mjs";
4
4
  import { r as fsRemove } from "./fs-Dd6Htx2P.mjs";
5
5
  import { a as pkgExists, l as slash, n as importWithError, o as promiseWithResolvers, t as debounce } from "./general-D3muxt2f.mjs";
6
6
  import { a as globalLogger, t as LogLevels } from "./logger-uV8l1UFa.mjs";
7
7
  import { i as getShimsInject, n as DepsPlugin } from "./format-CajNSstg.mjs";
8
- import { a as ReportPlugin, i as ShebangPlugin, n as endsWithConfig, o as NodeProtocolPlugin, r as addOutDirToChunks, s as copy, t as WatchPlugin } from "./watch-D6EGzM6P.mjs";
9
- import { t as version } from "./package-JOXUdJGa.mjs";
8
+ import { a as ReportPlugin, i as ShebangPlugin, n as endsWithConfig, o as NodeProtocolPlugin, r as addOutDirToChunks, s as copy, t as WatchPlugin } from "./watch-B659_4oi.mjs";
9
+ import { t as version } from "./package-YlYsw3G3.mjs";
10
10
  import { mkdtemp, readFile, readdir, writeFile } from "node:fs/promises";
11
11
  import path from "node:path";
12
12
  import process from "node:process";
13
13
  import { bold, dim, green } from "ansis";
14
14
  import { createDebug } from "obug";
15
+ import { RE_CSS, RE_DTS, RE_JS, filename_js_to_dts } from "rolldown-plugin-dts/internal";
15
16
  import { glob } from "tinyglobby";
16
17
  import readline from "node:readline";
17
- import { RE_CSS, RE_DTS, RE_JS, filename_js_to_dts } from "rolldown-plugin-dts/internal";
18
18
  import { tmpdir } from "node:os";
19
19
  const satisfies = __cjs_require("semver/functions/satisfies.js");
20
20
  import { exec, x } from "tinyexec";
@@ -38,7 +38,7 @@ var __exportAll = (all, no_symbols) => {
38
38
  };
39
39
  //#endregion
40
40
  //#region src/config/workspace.ts
41
- const debug$4 = createDebug("tsdown:config:workspace");
41
+ const debug$5 = createDebug("tsdown:config:workspace");
42
42
  const DEFAULT_EXCLUDE_WORKSPACE = [
43
43
  "**/node_modules/**",
44
44
  "**/dist/**",
@@ -72,7 +72,7 @@ async function resolveWorkspace(config, inlineConfig, rootDeps) {
72
72
  if (packages.length === 0) throw new Error("No workspace packages found, please check your config");
73
73
  return {
74
74
  configs: (await Promise.all(packages.map(async (cwd) => {
75
- debug$4("loading workspace config %s", cwd);
75
+ debug$5("loading workspace config %s", cwd);
76
76
  const { configs, deps: workspaceDeps } = await loadConfigFile({
77
77
  ...inlineConfig,
78
78
  config: workspaceConfig,
@@ -86,20 +86,20 @@ async function resolveWorkspace(config, inlineConfig, rootDeps) {
86
86
  }
87
87
  //#endregion
88
88
  //#region src/config/index.ts
89
- const debug$3 = createDebug("tsdown:config");
89
+ const debug$4 = createDebug("tsdown:config");
90
90
  async function resolveConfig(inlineConfig) {
91
- debug$3("inline config %O", inlineConfig);
91
+ debug$4("inline config %O", inlineConfig);
92
92
  if (inlineConfig.cwd) inlineConfig.cwd = path.resolve(inlineConfig.cwd);
93
93
  const { configs: rootConfigs, deps: rootDeps } = await loadConfigFile(inlineConfig);
94
94
  const globalDeps = new Set(rootDeps);
95
95
  const configs = (await Promise.all(rootConfigs.map(async (rootConfig) => {
96
96
  const { configs: workspaceConfigs, deps: workspaceDeps } = await resolveWorkspace(rootConfig, inlineConfig, rootDeps);
97
- debug$3("workspace configs %O", workspaceConfigs);
97
+ debug$4("workspace configs %O", workspaceConfigs);
98
98
  const configs = (await Promise.all(workspaceConfigs.filter((config) => !config.workspace || config.entry).map((config) => resolveUserConfig(config, inlineConfig, workspaceDeps)))).flat().filter((config) => !!config);
99
99
  workspaceDeps.forEach((dep) => globalDeps.add(dep));
100
100
  return configs;
101
101
  }))).flat();
102
- debug$3("resolved configs %O", configs);
102
+ debug$4("resolved configs %O", configs);
103
103
  if (configs.length === 0) throw new Error("No valid configuration found.");
104
104
  return {
105
105
  configs,
@@ -176,7 +176,7 @@ function executeOnSuccess(config) {
176
176
  }
177
177
  //#endregion
178
178
  //#region src/features/pkg/attw.ts
179
- const debug$2 = createDebug("tsdown:attw");
179
+ const debug$3 = createDebug("tsdown:attw");
180
180
  const label$1 = dim`[attw]`;
181
181
  const problemFlags = {
182
182
  NoResolution: "no-resolution",
@@ -213,7 +213,7 @@ async function attw(options, tarball) {
213
213
  const invalidRules = ignoreRules.filter((rule) => !Object.values(problemFlags).includes(rule));
214
214
  if (invalidRules.length) options.logger.warn(`attw config option 'ignoreRules' contains invalid value '${invalidRules.join(", ")}'.`);
215
215
  const t = performance.now();
216
- debug$2("Running attw check");
216
+ debug$3("Running attw check");
217
217
  const attwCore = options.attw.module || await importWithError("@arethetypeswrong/core");
218
218
  const pkg = attwCore.createPackageFromTarballData(tarball);
219
219
  const checkResult = await attwCore.checkPackage(pkg, attwOptions);
@@ -256,7 +256,7 @@ function formatProblem(packageName, problem) {
256
256
  }
257
257
  //#endregion
258
258
  //#region src/features/pkg/publint.ts
259
- const debug$1 = createDebug("tsdown:publint");
259
+ const debug$2 = createDebug("tsdown:publint");
260
260
  const label = dim`[publint]`;
261
261
  async function publint(options, tarball) {
262
262
  if (!options.publint) return;
@@ -265,20 +265,20 @@ async function publint(options, tarball) {
265
265
  return;
266
266
  }
267
267
  const t = performance.now();
268
- debug$1("Running publint");
268
+ debug$2("Running publint");
269
269
  const { publint } = options.publint.module?.[0] || await importWithError("publint");
270
270
  const { formatMessage } = options.publint.module?.[1] || await importWithError("publint/utils");
271
- const { messages } = await publint({
271
+ const { messages, pkg } = await publint({
272
272
  ...options.publint,
273
273
  pack: { tarball: tarball.buffer }
274
274
  });
275
- debug$1("Found %d issues", messages.length);
275
+ debug$2("Found %d issues", messages.length);
276
276
  if (!messages.length) {
277
277
  options.logger.success(options.nameLabel, label, "No issues found", dim`(${Math.round(performance.now() - t)}ms)`);
278
278
  return;
279
279
  }
280
280
  for (const message of messages) {
281
- const formattedMessage = formatMessage(message, options.pkg);
281
+ const formattedMessage = formatMessage(message, pkg);
282
282
  const logType = {
283
283
  error: "error",
284
284
  warning: "warn",
@@ -289,6 +289,7 @@ async function publint(options, tarball) {
289
289
  }
290
290
  //#endregion
291
291
  //#region src/features/pkg/index.ts
292
+ const debug$1 = createDebug("tsdown:pkg");
292
293
  function initBundleByPkg(configs) {
293
294
  const map = {};
294
295
  for (const config of configs) {
@@ -347,10 +348,14 @@ async function packTarball(packageJsonPath) {
347
348
  const { detect } = await import("./detect-DN3DXXYt.mjs");
348
349
  try {
349
350
  const detected = await detect({ cwd: pkgDir });
351
+ debug$1("Detected package manager: %o", detected);
350
352
  if (detected?.name === "deno") throw new Error(`Cannot pack tarball for Deno projects at ${pkgDir}`);
351
- return readFile(await pack(pkgDir, detected, destination, true));
353
+ const tarballPath = await pack(pkgDir, detected, destination, true);
354
+ debug$1("Packed tarball at %s", tarballPath);
355
+ return readFile(tarballPath);
352
356
  } finally {
353
- await fsRemove(destination);
357
+ if (debug$1.enabled) debug$1("Preserving pack directory for debugging: %s", destination);
358
+ else await fsRemove(destination);
354
359
  }
355
360
  }
356
361
  function dedupeConfigs(configs, key) {
@@ -578,8 +583,7 @@ async function resolveOutputOptions(inputOptions, config, format, cjsDts) {
578
583
  }, config.outputOptions, [format, { cjsDts }]);
579
584
  }
580
585
  async function getDebugRolldownDir() {
581
- if (!debug.enabled) return;
582
- return await mkdtemp(path.join(tmpdir(), "tsdown-config-"));
586
+ if (debug.enabled) return await mkdtemp(path.join(tmpdir(), "tsdown-config-"));
583
587
  }
584
588
  async function debugBuildOptions(dir, name, format, buildOptions) {
585
589
  const outFile = path.join(dir, `rolldown.config.${format}.js`);
@@ -1,4 +1,4 @@
1
- import { d as UserConfig, f as UserConfigExport, i as InlineConfig, o as ResolvedConfig, p as UserConfigFn } from "./types-BZNNnDKc.mjs";
1
+ import { d as UserConfig, f as UserConfigExport, i as InlineConfig, o as ResolvedConfig, p as UserConfigFn } from "./types-Da8mQtCf.mjs";
2
2
 
3
3
  //#region src/config/options.d.ts
4
4
  /**
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { d as UserConfig, f as UserConfigExport, p as UserConfigFn } from "./types-BZNNnDKc.mjs";
2
- import { n as mergeConfig, t as defineConfig } from "./config-CuK0i1Bc.mjs";
1
+ import { d as UserConfig, f as UserConfigExport, p as UserConfigFn } from "./types-Da8mQtCf.mjs";
2
+ import { n as mergeConfig, t as defineConfig } from "./config-CoZ57pPv.mjs";
3
3
  export { UserConfig, UserConfigExport, UserConfigFn, defineConfig, mergeConfig };
package/dist/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as mergeConfig } from "./options-8hmVMssn.mjs";
1
+ import { t as mergeConfig } from "./options-DLofT9Im.mjs";
2
2
  //#region src/config.ts
3
3
  function defineConfig(options) {
4
4
  return options;
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as Arrayable, i as globalLogger, r as Logger } from "./index-DraNj4FA.mjs";
2
- import { A as PackageType, B as ResolvedDepsConfig, C as ChunkAddon, D as OutExtensionFactory, E as OutExtensionContext, F as SeaConfig, G as CopyOptionsFn, H as TsdownBundle, I as DevtoolsOptions, L as DepsConfig, M as RolldownContext, N as TsdownHooks, O as OutExtensionObject, P as ExeOptions, S as AttwOptions, T as ChunkAddonObject, U as CopyEntry, V as RolldownChunk, W as CopyOptions, a as NormalizedFormat, b as PublintOptions, c as TreeshakingOptions, d as UserConfig, f as UserConfigExport, g as ReportOptions, h as Workspace, i as InlineConfig, j as BuildContext, k as PackageJsonWithPath, l as TsdownInputOption, m as WithEnabled, n as DtsOptions, o as ResolvedConfig, p as UserConfigFn, r as Format, s as Sourcemap, t as CIOption, u as UnusedOptions, v as TsdownPlugin, w as ChunkAddonFunction, x as ExportsOptions, y as TsdownPluginOption, z as NoExternalFn } from "./types-BZNNnDKc.mjs";
3
- import { n as mergeConfig, r as resolveUserConfig, t as defineConfig } from "./config-CuK0i1Bc.mjs";
2
+ import { A as PackageType, B as ResolvedDepsConfig, C as ChunkAddon, D as OutExtensionFactory, E as OutExtensionContext, F as SeaConfig, G as CopyOptionsFn, H as TsdownBundle, I as DevtoolsOptions, L as DepsConfig, M as RolldownContext, N as TsdownHooks, O as OutExtensionObject, P as ExeOptions, S as AttwOptions, T as ChunkAddonObject, U as CopyEntry, V as RolldownChunk, W as CopyOptions, a as NormalizedFormat, b as PublintOptions, c as TreeshakingOptions, d as UserConfig, f as UserConfigExport, g as ReportOptions, h as Workspace, i as InlineConfig, j as BuildContext, k as PackageJsonWithPath, l as TsdownInputOption, m as WithEnabled, n as DtsOptions, o as ResolvedConfig, p as UserConfigFn, r as Format, s as Sourcemap, t as CIOption, u as UnusedOptions, v as TsdownPlugin, w as ChunkAddonFunction, x as ExportsOptions, y as TsdownPluginOption, z as NoExternalFn } from "./types-Da8mQtCf.mjs";
3
+ import { n as mergeConfig, r as resolveUserConfig, t as defineConfig } from "./config-CoZ57pPv.mjs";
4
4
  import * as Rolldown from "rolldown";
5
5
 
6
6
  //#region src/build.d.ts
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { n as buildWithConfigs, t as build } from "./build-OX8uszs6.mjs";
2
- import { r as resolveUserConfig, t as mergeConfig } from "./options-8hmVMssn.mjs";
1
+ import { n as buildWithConfigs, t as build } from "./build-CABwL9HG.mjs";
2
+ import { r as resolveUserConfig, t as mergeConfig } from "./options-DLofT9Im.mjs";
3
3
  import { a as globalLogger } from "./logger-uV8l1UFa.mjs";
4
4
  import { defineConfig } from "./config.mjs";
5
5
  import { t as enableDebug } from "./debug-CLlnG64L.mjs";
@@ -11,9 +11,9 @@ import process, { env } from "node:process";
11
11
  import { blue, bold, dim, red, underline } from "ansis";
12
12
  import { createDefu } from "defu";
13
13
  import { createDebug } from "obug";
14
+ import { RE_CSS, RE_DTS, RE_NODE_MODULES, parseTsconfig } from "rolldown-plugin-dts/internal";
14
15
  import { glob, isDynamicPattern } from "tinyglobby";
15
16
  const picomatch = __cjs_require("picomatch");
16
- import { RE_CSS, RE_DTS, RE_NODE_MODULES } from "rolldown-plugin-dts/internal";
17
17
  import { tmpdir } from "node:os";
18
18
  const satisfies = __cjs_require("semver/functions/satisfies.js");
19
19
  import { x } from "tinyexec";
@@ -399,25 +399,19 @@ function exportCss(exports, chunks, css, pkgRoot) {
399
399
  return;
400
400
  }
401
401
  }
402
- function hasExportsTypes(pkg) {
403
- const exports = pkg?.exports;
404
- if (!exports) return false;
405
- if (typeof exports === "object" && exports !== null && !Array.isArray(exports)) {
406
- if ("types" in exports) return true;
407
- if ("." in exports) {
408
- const mainExport = exports["."];
409
- if (typeof mainExport === "object" && mainExport !== null && "types" in mainExport) return true;
410
- }
411
- }
412
- return false;
402
+ function hasExportsTypes(value) {
403
+ if (value == null || typeof value !== "object") return false;
404
+ if (Array.isArray(value)) return value.some(hasExportsTypes);
405
+ if ("types" in value) return true;
406
+ return Object.values(value).some(hasExportsTypes);
413
407
  }
414
408
  const RE_SHEBANG = /^#!.*/;
415
409
  function generateBin(bin, devExports, pkg, chunks, pkgRoot, logger, cwd) {
416
- if (!bin) return;
417
- if (bin === true || typeof bin === "string") {
410
+ if (bin === false) return;
411
+ if (bin === true || bin === void 0 || typeof bin === "string") {
418
412
  if (!pkg.name) throw new Error("Package name is required when using string form for `bin`");
419
413
  const binName = pkg.name[0] === "@" ? pkg.name.split("/", 2)[1] : pkg.name;
420
- if (bin === true) {
414
+ if (bin === true || bin === void 0) {
421
415
  let detected;
422
416
  const seen = /* @__PURE__ */ new Set();
423
417
  for (const format of ["es", "cjs"]) {
@@ -428,12 +422,16 @@ function generateBin(bin, devExports, pkg, chunks, pkgRoot, logger, cwd) {
428
422
  if (!RE_SHEBANG.test(chunk.code)) continue;
429
423
  if (seen.has(chunk.facadeModuleId)) continue;
430
424
  seen.add(chunk.facadeModuleId);
431
- if (detected) throw new Error("Multiple entry chunks with shebangs found. Use `exports.bin: { name: \"./src/file.ts\" }` to specify which one to use.");
425
+ if (detected) {
426
+ if (bin === true) throw new Error("Multiple entry chunks with shebangs found. Use `exports.bin: { command: \"./src/file.ts\" }` to specify which one to use.");
427
+ logger.warn("Multiple entry chunks with shebangs found. Use `exports.bin: true` or `exports.bin: { command: \"./src/file.ts\" }` to configure explicitly.");
428
+ return;
429
+ }
432
430
  detected = devExports ? `./${slash(path.relative(pkgRoot, chunk.facadeModuleId))}` : join(pkgRoot, chunk.outDir, slash(chunk.fileName));
433
431
  }
434
432
  }
435
433
  if (detected == null) {
436
- logger.warn("`exports.bin` is true but no entry chunks with shebangs were found");
434
+ if (bin === true) logger.warn("`exports.bin` is true but no entry chunks with shebangs were found");
437
435
  return;
438
436
  }
439
437
  return { [binName]: detected };
@@ -654,8 +652,7 @@ const isBun = !!process.versions.bun;
654
652
  const nativeTS = process.features.typescript || process.versions.deno;
655
653
  const autoLoader = isBun || nativeTS && isSupported ? "native" : "unrun";
656
654
  function resolveConfigLoader(configLoader = "auto") {
657
- if (configLoader === "auto") return autoLoader;
658
- else return configLoader === "native" ? "native" : "unrun";
655
+ return configLoader === "auto" ? autoLoader : configLoader;
659
656
  }
660
657
  function createParser(loader) {
661
658
  return async (filepath) => {
@@ -666,7 +663,12 @@ function createParser(loader) {
666
663
  const parsed = JSON.parse(contents);
667
664
  return [isPkgJson ? parsed?.tsdown : parsed, new Set([filepath])];
668
665
  }
669
- return (loader === "native" ? nativeImport : unrunImport)(filepath);
666
+ switch (loader) {
667
+ case "native": return nativeImport(filepath);
668
+ case "tsx": return tsxImport(filepath);
669
+ case "unrun": return unrunImport(filepath);
670
+ default: throw new Error(`Unknown config loader: ${loader}`);
671
+ }
670
672
  };
671
673
  }
672
674
  async function nativeImport(id) {
@@ -678,14 +680,19 @@ async function nativeImport(id) {
678
680
  init({ skipNodeModules: true });
679
681
  } else if (!isBun) url.searchParams.set("no-cache", crypto.randomUUID());
680
682
  const mod = await depsStore.run(deps, () => import(url.href, { with: importAttributes }).catch((error) => {
681
- if (error?.message?.includes?.("Cannot find module")) throw new Error(`Failed to load the config file. Try setting the --config-loader CLI flag to \`unrun\`.\n\n${error.message}`, { cause: error });
682
- if (typeof error?.stack === "string" && error.stack.includes("node:internal/modules/esm/translators")) throw new Error(`Failed to load the config file due to a known Node.js bug. Try setting the --config-loader CLI flag to \`unrun\` or upgrading Node.js to v24.11.1 or later.\n\n${error.message}`, { cause: error });
683
+ if (error?.message?.includes?.("Cannot find module")) throw new Error(`Failed to load the config file. Try setting the --config-loader CLI flag to \`tsx\` or \`unrun\`.\n\n${error.message}`, { cause: error });
684
+ if (typeof error?.stack === "string" && error.stack.includes("node:internal/modules/esm/translators")) throw new Error(`Failed to load the config file due to a known Node.js bug. Try setting the --config-loader CLI flag to \`tsx\` or \`unrun\`, or upgrading Node.js to v24.11.1 or later.\n\n${error.message}`, { cause: error });
683
685
  throw error;
684
686
  }));
685
- return [mod.default || mod, deps];
687
+ return [mod?.default || mod, deps];
688
+ }
689
+ async function tsxImport(id) {
690
+ const { tsImport } = await importWithError("tsx/esm/api");
691
+ const module = await tsImport(pathToFileURL(id).href, import.meta.url);
692
+ return [module?.default || module, new Set([id])];
686
693
  }
687
694
  async function unrunImport(id) {
688
- const { unrun } = await import("unrun");
695
+ const { unrun } = await importWithError("unrun");
689
696
  const { module, dependencies } = await unrun({ path: pathToFileURL(id).href });
690
697
  return [module, new Set(dependencies)];
691
698
  }
@@ -738,7 +745,10 @@ async function resolveUserConfig(userConfig, inlineConfig, configDeps) {
738
745
  unused = resolveFeatureOption(unused, {});
739
746
  report = resolveFeatureOption(report, {});
740
747
  exe = resolveFeatureOption(exe, {});
741
- if (dts == null) dts = exe ? false : !!(pkg?.types || pkg?.typings || hasExportsTypes(pkg));
748
+ if (dts == null) if (exe) dts = false;
749
+ else if (pkg?.types || pkg?.typings || hasExportsTypes(pkg?.exports)) dts = true;
750
+ else if (tsconfig) dts = !!parseTsconfig(tsconfig).compilerOptions?.declaration;
751
+ else dts = false;
742
752
  dts = resolveFeatureOption(dts, {});
743
753
  if (!pkg) {
744
754
  if (exports) throw new Error("`package.json` not found, cannot write exports");
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.21.9";
2
+ var version = "0.22.0-beta.1";
3
3
  //#endregion
4
4
  export { version as t };
@@ -1,5 +1,5 @@
1
1
  import { r as Logger } from "./index-DraNj4FA.mjs";
2
- import { H as TsdownBundle, R as DepsPlugin, _ as ReportPlugin } from "./types-BZNNnDKc.mjs";
2
+ import { H as TsdownBundle, R as DepsPlugin, _ as ReportPlugin } from "./types-Da8mQtCf.mjs";
3
3
  import { Plugin } from "rolldown";
4
4
 
5
5
  //#region src/features/node-protocol.d.ts
package/dist/plugins.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  import { n as DepsPlugin } from "./format-CajNSstg.mjs";
2
- import { a as ReportPlugin, i as ShebangPlugin, o as NodeProtocolPlugin, t as WatchPlugin } from "./watch-D6EGzM6P.mjs";
2
+ import { a as ReportPlugin, i as ShebangPlugin, o as NodeProtocolPlugin, t as WatchPlugin } from "./watch-B659_4oi.mjs";
3
3
  export { DepsPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin, WatchPlugin };
package/dist/run.mjs CHANGED
@@ -1,15 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire as __cjs_createRequire } from "node:module";
3
- const __cjs_require = __cjs_createRequire(import.meta.url);
4
2
  import { a as globalLogger } from "./logger-uV8l1UFa.mjs";
5
- import { t as version } from "./package-JOXUdJGa.mjs";
3
+ import { t as version } from "./package-YlYsw3G3.mjs";
6
4
  import { t as enableDebug } from "./debug-CLlnG64L.mjs";
7
5
  import module from "node:module";
8
6
  import process from "node:process";
9
- import { blue, hex, yellow } from "ansis";
7
+ import { blue, hex } from "ansis";
10
8
  import { x } from "tinyexec";
11
9
  import { VERSION } from "rolldown";
12
- const lt = __cjs_require("semver/functions/lt.js");
13
10
  import { cac } from "cac";
14
11
  //#region src/cli.ts
15
12
  const cli = cac("tsdown");
@@ -17,10 +14,10 @@ cli.help().version(version);
17
14
  cli.command("[...files]", "Bundle files", {
18
15
  ignoreOptionDefaultValue: true,
19
16
  allowUnknownOptions: true
20
- }).option("-c, --config <filename>", "Use a custom config file").option("--config-loader <loader>", "Config loader to use: auto, native, unrun", { default: "auto" }).option("--no-config", "Disable config file").option("-f, --format <format>", "Bundle format: esm, cjs, iife, umd", { default: "esm" }).option("--clean", "Clean output directory, --no-clean to disable").option("--deps.never-bundle <module>", "Mark dependencies as external").option("--minify", "Minify output").option("--devtools", "Enable devtools integration").option("--debug [feat]", "Show debug logs").option("--target <target>", "Bundle target, e.g \"es2015\", \"esnext\"").option("-l, --logLevel <level>", "Set log level: info, warn, error, silent").option("--fail-on-warn", "Fail on warnings", { default: true }).option("--no-write", "Disable writing files to disk, incompatible with watch mode").option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--shims", "Enable cjs and esm shims ", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("--dts", "Generate dts files").option("--publint", "Enable publint", { default: false }).option("--attw", "Enable Are the types wrong integration", { default: false }).option("--unused", "Enable unused dependencies check", { default: false }).option("-w, --watch [path]", "Watch mode").option("--ignore-watch <path>", "Ignore custom paths in watch mode").option("--from-vite [vitest]", "Reuse config from Vite or Vitest").option("--report", "Size report", { default: true }).option("--env.* <value>", "Define compile-time env variables").option("--env-file <file>", "Load environment variables from a file, when used together with --env, variables in --env take precedence").option("--env-prefix <prefix>", "Prefix for env variables to inject into the bundle", { default: "TSDOWN_" }).option("--on-success <command>", "Command to run on success").option("--copy <dir>", "Copy files to output dir").option("--public-dir <dir>", "Alias for --copy, deprecated").option("--tsconfig <tsconfig>", "Set tsconfig path").option("--unbundle", "Unbundle mode").option("--root <dir>", "Root directory of input files").option("--exe", "Bundle as executable").option("-W, --workspace [dir]", "Enable workspace mode").option("-F, --filter <pattern>", "Filter configs (cwd or name), e.g. /pkg-name$/ or pkg-name").option("--exports", "Generate export-related metadata for package.json (experimental)").action(async (input, flags) => {
17
+ }).option("-c, --config <filename>", "Use a custom config file").option("--config-loader <loader>", "Config loader to use: auto, native, tsx, unrun", { default: "auto" }).option("--no-config", "Disable config file").option("-f, --format <format>", "Bundle format: esm, cjs, iife, umd", { default: "esm" }).option("--clean", "Clean output directory, --no-clean to disable").option("--deps.never-bundle <module>", "Mark dependencies as external").option("--minify", "Minify output").option("--devtools", "Enable devtools integration").option("--debug [feat]", "Show debug logs").option("--target <target>", "Bundle target, e.g \"es2015\", \"esnext\"").option("-l, --logLevel <level>", "Set log level: info, warn, error, silent").option("--fail-on-warn", "Fail on warnings", { default: true }).option("--no-write", "Disable writing files to disk, incompatible with watch mode").option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--shims", "Enable cjs and esm shims ", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("--dts", "Generate dts files").option("--publint", "Enable publint", { default: false }).option("--attw", "Enable Are the types wrong integration", { default: false }).option("--unused", "Enable unused dependencies check", { default: false }).option("-w, --watch [path]", "Watch mode").option("--ignore-watch <path>", "Ignore custom paths in watch mode").option("--from-vite [vitest]", "Reuse config from Vite or Vitest").option("--report", "Size report", { default: true }).option("--env.* <value>", "Define compile-time env variables").option("--env-file <file>", "Load environment variables from a file, when used together with --env, variables in --env take precedence").option("--env-prefix <prefix>", "Prefix for env variables to inject into the bundle", { default: "TSDOWN_" }).option("--on-success <command>", "Command to run on success").option("--copy <dir>", "Copy files to output dir").option("--public-dir <dir>", "Alias for --copy, deprecated").option("--tsconfig <tsconfig>", "Set tsconfig path").option("--unbundle", "Unbundle mode").option("--root <dir>", "Root directory of input files").option("--exe", "Bundle as executable").option("-W, --workspace [dir]", "Enable workspace mode").option("-F, --filter <pattern>", "Filter configs (cwd or name), e.g. /pkg-name$/ or pkg-name").option("--exports", "Generate export-related metadata for package.json (experimental)").action(async (input, flags) => {
21
18
  globalLogger.level = flags.logLevel || "info";
22
19
  globalLogger.info(`${blue`tsdown v${version}`} powered by ${hex("#ff7e17")`rolldown v${VERSION}`}`);
23
- const { build } = await import("./build-OX8uszs6.mjs").then((n) => n.r);
20
+ const { build } = await import("./build-CABwL9HG.mjs").then((n) => n.r);
24
21
  if (input.length > 0) flags.entry = input;
25
22
  await build(flags);
26
23
  });
@@ -54,7 +51,6 @@ async function runCLI() {
54
51
  }
55
52
  //#endregion
56
53
  //#region src/run.ts
57
- if (!process.versions.bun && lt(process.version, "22.18.0")) console.warn(yellow`[tsdown] Node.js ${process.version} is deprecated. Support will be removed in the next minor release. Please upgrade to Node.js v22.18.0 or later.`);
58
54
  try {
59
55
  module.enableCompileCache?.();
60
56
  } catch {}
@@ -2,7 +2,6 @@ import { a as Arrayable, c as Overwrite, n as LogLevel, o as Awaitable, r as Log
2
2
  import { BuildOptions, ChecksOptions, ExternalOption, InputOptions, InternalModuleFormat, MinifyOptions, ModuleFormat, ModuleTypes, OutputAsset, OutputChunk, OutputOptions, Plugin, RolldownPlugin, TreeshakingOptions } from "rolldown";
3
3
  import { Hookable } from "hookable";
4
4
  import { Buffer } from "node:buffer";
5
- import * as _$_tsdown_css0 from "@tsdown/css";
6
5
  import { StartOptions } from "@vitejs/devtools/cli-commands";
7
6
  import { ExeExtensionOptions } from "@tsdown/exe";
8
7
  import * as _$_arethetypeswrong_core0 from "@arethetypeswrong/core";
@@ -10,6 +9,7 @@ import { CheckPackageOptions } from "@arethetypeswrong/core";
10
9
  import * as _$publint from "publint";
11
10
  import { Options } from "publint";
12
11
  import * as _$publint_utils0 from "publint/utils";
12
+ import { CssOptions } from "@tsdown/css";
13
13
  import { Options as Options$1 } from "rolldown-plugin-dts";
14
14
  import { Options as UnusedOptions } from "unplugin-unused";
15
15
 
@@ -59,7 +59,8 @@ type NoExternalFn = (id: string, importer: string | undefined) => boolean | null
59
59
  interface DepsConfig {
60
60
  /**
61
61
  * Mark dependencies as external (not bundled).
62
- * Accepts strings, regular expressions, or Rolldown's `ExternalOption`.
62
+ * Accepts strings, regular expressions, or Rolldown's
63
+ * {@linkcode ExternalOption}.
63
64
  */
64
65
  neverBundle?: ExternalOption;
65
66
  /**
@@ -77,13 +78,13 @@ interface DepsConfig {
77
78
  */
78
79
  onlyBundle?: Arrayable<string | RegExp> | false;
79
80
  /**
80
- * @deprecated Use {@link onlyBundle} instead.
81
+ * @deprecated Use {@linkcode onlyBundle} instead.
81
82
  */
82
83
  onlyAllowBundle?: Arrayable<string | RegExp> | false;
83
84
  /**
84
85
  * Skip bundling all `node_modules` dependencies.
85
86
  *
86
- * **Note:** This option cannot be used together with `alwaysBundle`.
87
+ * **Note:** This option cannot be used together with {@linkcode alwaysBundle}.
87
88
  *
88
89
  * @default false
89
90
  */
@@ -143,18 +144,31 @@ interface ExeOptions extends ExeExtensionOptions {
143
144
  */
144
145
  interface SeaConfig {
145
146
  main?: string;
146
- /** Optional, if not specified, uses the current Node.js binary */
147
+ /**
148
+ * Optional, if not specified, uses the current Node.js binary
149
+ */
147
150
  executable?: string;
148
151
  output?: string;
152
+ /**
153
+ * @default tsdownConfig.format === 'es' ? 'module' : 'commonjs'
154
+ */
149
155
  mainFormat?: "commonjs" | "module";
150
- /** @default true */
156
+ /**
157
+ * @default true
158
+ */
151
159
  disableExperimentalSEAWarning?: boolean;
152
- /** @default false */
160
+ /**
161
+ * @default false
162
+ */
153
163
  useSnapshot?: boolean;
154
- /** @default false */
164
+ /**
165
+ * @default false
166
+ */
155
167
  useCodeCache?: boolean;
156
168
  execArgv?: string[];
157
- /** @default "env" */
169
+ /**
170
+ * @default 'env'
171
+ */
158
172
  execArgvExtension?: "none" | "env" | "cli";
159
173
  assets?: Record<string, string>;
160
174
  }
@@ -201,7 +215,9 @@ type PackageType = "module" | "commonjs" | undefined;
201
215
  interface OutExtensionContext {
202
216
  options: InputOptions;
203
217
  format: NormalizedFormat;
204
- /** "type" field in project's package.json */
218
+ /**
219
+ * `"type"` field in project's `package.json`.
220
+ */
205
221
  pkgType?: PackageType;
206
222
  }
207
223
  interface OutExtensionObject {
@@ -266,6 +282,10 @@ interface AttwOptions extends CheckPackageOptions {
266
282
  * ```ts
267
283
  * ignoreRules: ['no-resolution', 'false-cjs']
268
284
  * ```
285
+ *
286
+ * @default []
287
+ *
288
+ * @uniqueItems
269
289
  */
270
290
  ignoreRules?: ("no-resolution" | "untyped-resolution" | "false-cjs" | "false-esm" | "cjs-resolves-to-esm" | "fallback-condition" | "cjs-only-exports-default" | "named-exports" | "false-export-default" | "missing-export-equals" | "unexpected-module-syntax" | "internal-resolution-error" | (string & {}))[];
271
291
  }
@@ -274,17 +294,42 @@ interface AttwOptions extends CheckPackageOptions {
274
294
  interface ExportsOptions {
275
295
  /**
276
296
  * Generate exports that link to source code during development.
277
- * - string: add as a custom condition.
278
- * - true: all conditions point to source files, and add dist exports to `publishConfig`.
297
+ * - `string`: add as a custom condition.
298
+ * - `true`: all conditions point to source files, and add `dist` exports to `publishConfig`.
279
299
  */
280
300
  devExports?: boolean | string;
281
301
  /**
282
- * Exports for package.json file.
302
+ * Generate `exports` for `package.json` file.
303
+ *
304
+ * @example
305
+ * ```json
306
+ * {
307
+ * "exports": {
308
+ * ".": {
309
+ * "types": "./dist/index.d.mts",
310
+ * "import": "./dist/index.mjs"
311
+ * },
312
+ * "./package.json": "./package.json"
313
+ * }
314
+ * }
315
+ * ```
316
+ *
283
317
  * @default true
284
318
  */
285
319
  packageJson?: boolean;
286
320
  /**
287
- * Exports for all files.
321
+ * Generate `exports` for all files.
322
+ *
323
+ * @example
324
+ * ```json
325
+ * {
326
+ * "exports": {
327
+ * "./*": "./*"
328
+ * }
329
+ * }
330
+ * ```
331
+ *
332
+ * @default false
288
333
  */
289
334
  all?: boolean;
290
335
  /**
@@ -294,7 +339,9 @@ interface ExportsOptions {
294
339
  * **Note:** Do not include file extensions, and paths should be relative to the dist directory.
295
340
  *
296
341
  * @example
342
+ * ```ts
297
343
  * exclude: ['cli', '**\/*.test', /internal/]
344
+ * ```
298
345
  */
299
346
  exclude?: (RegExp | string)[];
300
347
  /**
@@ -311,10 +358,12 @@ interface ExportsOptions {
311
358
  * Use this to add additional exports in the exported package, such as workers or assets.
312
359
  *
313
360
  * @example
361
+ * ```ts
314
362
  * customExports(exports) {
315
363
  * exports['./worker.js'] = './dist/worker.js';
316
364
  * return exports;
317
365
  * }
366
+ * ```
318
367
  *
319
368
  * @example
320
369
  * ```jsonc
@@ -334,7 +383,7 @@ interface ExportsOptions {
334
383
  isPublish: boolean;
335
384
  }) => Awaitable<Record<string, any>>);
336
385
  /**
337
- * Generate `inlinedDependencies` field in package.json.
386
+ * Generate `inlinedDependencies` field in `package.json`.
338
387
  * Lists dependencies that are physically inlined into the bundle with their exact versions.
339
388
  *
340
389
  * @default true
@@ -354,19 +403,62 @@ interface ExportsOptions {
354
403
  */
355
404
  extensions?: boolean;
356
405
  /**
357
- * Auto-generate the `bin` field in package.json.
406
+ * Generate the `bin` field in `package.json` for CLI executables.
358
407
  *
359
- * - `true`: Auto-detect entry chunks with shebangs. Uses package name (without scope) as bin name.
360
- * Errors if multiple shebang entries are found.
361
- * - `string`: Source file path to use as the bin entry. Bin name defaults to package name (without scope).
362
- * - `Record<string, string>`: Map of bin command names to source file paths.
408
+ * Behavior depends on the value:
409
+ *
410
+ * - *Unset* (default): Soft auto-detect. Scans entry chunks for shebangs
411
+ * (e.g. `#!/usr/bin/env node`). If exactly one is found, it is used as
412
+ * the bin entry. If multiple are found, a warning is shown and no `bin`
413
+ * field is written. If none are found, nothing happens silently.
414
+ * - `true`: Strict auto-detect. Same as the default, but throws if
415
+ * multiple shebang entries are found, and warns if none are found.
416
+ * Use this when your package is known to ship a CLI and you want to
417
+ * fail fast on misconfiguration.
418
+ * - `false`: Disable bin generation entirely, even if shebangs are
419
+ * present.
420
+ * - `string`: Use the given source file path (relative to `cwd`) as the
421
+ * CLI entry. The command name is derived from the package name without
422
+ * its scope. Warns if the source file does not contain a shebang.
423
+ * - `Record<string, string>`: Explicitly map command names to source file
424
+ * paths (relative to `cwd`). Warns for each source file that does not
425
+ * contain a shebang.
426
+ *
427
+ * When {@link ExportsOptions.devExports} is enabled, the `bin` field in
428
+ * `package.json` points to source files during local development, while
429
+ * `publishConfig.bin` points to built output paths for publishing.
363
430
  *
364
431
  * @example
365
- * bin: true
432
+ * <caption>Auto-detect a CLI entry from a shebang</caption>
433
+ *
434
+ * ```ts
435
+ * {
436
+ * bin: true
437
+ * }
438
+ * ```
439
+ *
366
440
  * @example
367
- * bin: './src/cli.ts'
441
+ * <caption>Single CLI command with an explicit source entry</caption>
442
+ *
443
+ * ```ts
444
+ * {
445
+ * bin: './src/cli.ts'
446
+ * }
447
+ * ```
448
+ *
368
449
  * @example
369
- * bin: { tool: './src/cli-tool.ts' }
450
+ * <caption>Multiple named CLI commands</caption>
451
+ *
452
+ * ```ts
453
+ * {
454
+ * bin: {
455
+ * tool: './src/cli.ts',
456
+ * serve: './src/cli-extra.ts',
457
+ * },
458
+ * }
459
+ * ```
460
+ *
461
+ * @see {@link https://docs.npmjs.com/cli/v11/configuring-npm/package-json#bin | npm documentation for the `bin` field}
370
462
  */
371
463
  bin?: boolean | string | Record<string, string>;
372
464
  }
@@ -378,8 +470,8 @@ interface PublintOptions extends Omit<Options, "pack" | "pkgDir"> {
378
470
  //#endregion
379
471
  //#region src/features/plugin.d.ts
380
472
  /**
381
- * A tsdown-aware plugin. Extends Rolldown's `Plugin` with tsdown-specific
382
- * lifecycle hooks.
473
+ * A tsdown-aware plugin. Extends Rolldown's {@linkcode Plugin} with
474
+ * tsdown-specific lifecycle hooks.
383
475
  *
384
476
  * Plugins that only use Rolldown's own lifecycle continue to work unchanged;
385
477
  * tsdown detects these optional methods via runtime duck-typing.
@@ -389,18 +481,19 @@ interface TsdownPlugin<A = any> extends Plugin<A> {
389
481
  * Modify tsdown's user config before it is resolved. Analogous to Vite's
390
482
  * [`config`](https://vite.dev/guide/api-plugin.html#config) hook.
391
483
  *
392
- * The hook may mutate `config` in place, or return a partial {@link UserConfig}
393
- * that will be deep-merged into the current config. Array fields are
394
- * replaced (not concatenated) during merging — to append plugins, mutate
395
- * `config.plugins` in place.
484
+ * The hook may mutate {@linkcode config} in place, or return a partial
485
+ * {@linkcode UserConfig} that will be deep-merged into the current config.
486
+ * Array fields are replaced (not concatenated) during merging — to append
487
+ * plugins, mutate {@linkcode UserConfig.plugins | config.plugins} in place.
396
488
  *
397
- * The second argument is the original {@link InlineConfig} passed to
398
- * `build()` (typically the CLI flags), useful for distinguishing values
399
- * that came from the command line vs. the config file.
489
+ * The second argument is the original {@linkcode InlineConfig} passed to
490
+ * {@linkcode build | build()} (typically the CLI flags), useful for
491
+ * distinguishing values that came from the command line vs. the config file.
400
492
  *
401
- * Plugins injected via `fromVite` do not receive this hook, because they
402
- * are loaded after the tsdownConfig phase. Likewise, new plugins added by
403
- * another plugin's `tsdownConfig` do not themselves receive this hook
493
+ * Plugins injected via {@linkcode UserConfig.fromVite | fromVite} do not
494
+ * receive this hook, because they are loaded after the
495
+ * {@linkcode tsdownConfig} phase. Likewise, new plugins added by another
496
+ * plugin's {@linkcode tsdownConfig} do not themselves receive this hook
404
497
  * (plugins are snapshotted before dispatch).
405
498
  */
406
499
  tsdownConfig?: (config: UserConfig, inlineConfig: InlineConfig) => Awaitable<UserConfig | void | null>;
@@ -409,18 +502,20 @@ interface TsdownPlugin<A = any> extends Plugin<A> {
409
502
  * Vite's [`configResolved`](https://vite.dev/guide/api-plugin.html#configresolved)
410
503
  * hook.
411
504
  *
412
- * This hook fires once per produced {@link ResolvedConfig} — i.e. once
413
- * per output format when `format` is an array. Typical usage is to stash
414
- * the resolved config for later use in Rolldown hooks. Mutations made to
415
- * `resolvedConfig` here are not supported.
505
+ * This hook fires once per produced {@linkcode ResolvedConfig} — i.e. once
506
+ * per output format when {@linkcode UserConfig.format | format} is an array.
507
+ * Typical usage is to stash the resolved config for later use in
508
+ * Rolldown hooks. Mutations made to {@linkcode resolvedConfig} here are
509
+ * not supported.
416
510
  */
417
511
  tsdownConfigResolved?: (resolvedConfig: ResolvedConfig) => Awaitable<void>;
418
512
  }
419
513
  /**
420
514
  * A tsdown plugin slot — accepts tsdown plugins, any Rolldown plugin form,
421
- * `null`/`undefined`/`false`, promises, and nested arrays. Mirrors Rolldown's
422
- * {@link RolldownPluginOption} but with {@link TsdownPlugin} as the atom so
423
- * that tsdown-specific hooks are type-checked.
515
+ * `null`/`undefined`/`false`, {@linkcode Promise | promises}, and
516
+ * nested arrays. Mirrors Rolldown's {@linkcode RolldownPluginOption} but with
517
+ * {@linkcode TsdownPlugin} as the atom so that tsdown-specific hooks are
518
+ * type-checked.
424
519
  */
425
520
  type TsdownPluginOption<A = any> = Awaitable<TsdownPlugin<A> | RolldownPlugin<A> | {
426
521
  name: string;
@@ -444,7 +539,7 @@ interface ReportOptions {
444
539
  brotli?: boolean;
445
540
  /**
446
541
  * Skip reporting compressed size for files larger than this size.
447
- * @default 1_000_000 // 1MB
542
+ * @default 1_000_000 // 1 MB
448
543
  */
449
544
  maxCompressSize?: number;
450
545
  }
@@ -495,10 +590,12 @@ interface Workspace {
495
590
  * - `auto`: Automatically detect `package.json` files in the workspace.
496
591
  * @default 'auto'
497
592
  */
498
- include?: Arrayable<string> | "auto";
593
+ include?: "auto" | (string & {}) | string[];
499
594
  /**
500
595
  * Exclude directories from workspace.
501
596
  * Defaults to all `node_modules`, `dist`, `test`, `tests`, `temp`, and `tmp` directories.
597
+ *
598
+ * @default ['**\/node_modules/**', '**\/dist/**', '**\/test?(s)/**', '**\/t?(e)mp/**']
502
599
  */
503
600
  exclude?: Arrayable<string>;
504
601
  /**
@@ -508,7 +605,10 @@ interface Workspace {
508
605
  }
509
606
  type CIOption = "ci-only" | "local-only";
510
607
  type WithEnabled<T> = boolean | undefined | CIOption | (T & {
511
- /** @default true */enabled?: boolean | CIOption;
608
+ /**
609
+ * @default true
610
+ */
611
+ enabled?: boolean | CIOption;
512
612
  });
513
613
  /**
514
614
  * Options for tsdown.
@@ -524,6 +624,8 @@ interface UserConfig {
524
624
  * "hooks/*": ["./src/hooks/*.ts", "!./src/hooks/index.ts"],
525
625
  * }
526
626
  * ```
627
+ *
628
+ * @default { index: 'src/index.ts'}
527
629
  */
528
630
  entry?: TsdownInputOption;
529
631
  /**
@@ -531,23 +633,26 @@ interface UserConfig {
531
633
  */
532
634
  deps?: DepsConfig;
533
635
  /**
534
- * @deprecated Use `deps.neverBundle` instead.
636
+ * @deprecated Use {@linkcode DepsConfig.neverBundle | deps.neverBundle} instead.
535
637
  */
536
638
  external?: ExternalOption;
537
639
  /**
538
- * @deprecated Use `deps.alwaysBundle` instead.
640
+ * @deprecated Use {@linkcode DepsConfig.alwaysBundle | deps.alwaysBundle} instead.
539
641
  */
540
642
  noExternal?: Arrayable<string | RegExp> | NoExternalFn;
541
643
  /**
542
- * @deprecated Use `deps.onlyBundle` instead.
644
+ * @deprecated Use {@linkcode DepsConfig.onlyBundle | deps.onlyBundle} instead.
543
645
  */
544
646
  inlineOnly?: Arrayable<string | RegExp> | false;
545
647
  /**
546
- * @deprecated Use `deps.skipNodeModulesBundle` instead.
648
+ * @deprecated Use {@linkcode DepsConfig.skipNodeModulesBundle | deps.skipNodeModulesBundle} instead.
547
649
  * @default false
548
650
  */
549
651
  skipNodeModulesBundle?: boolean;
550
652
  alias?: Record<string, string>;
653
+ /**
654
+ * @default true
655
+ */
551
656
  tsconfig?: string | boolean;
552
657
  /**
553
658
  * Specifies the target runtime platform for the build.
@@ -600,6 +705,8 @@ interface UserConfig {
600
705
  * "NODE_ENV": "production"
601
706
  * }
602
707
  * ```
708
+ *
709
+ * @default {}
603
710
  */
604
711
  env?: Record<string, any>;
605
712
  /**
@@ -614,7 +721,9 @@ interface UserConfig {
614
721
  */
615
722
  envPrefix?: string | string[];
616
723
  define?: Record<string, string>;
617
- /** @default false */
724
+ /**
725
+ * @default false
726
+ */
618
727
  shims?: boolean;
619
728
  /**
620
729
  * Configure tree shaking options.
@@ -628,36 +737,70 @@ interface UserConfig {
628
737
  * Lets you import or require files like images or fonts.
629
738
  * @example
630
739
  * ```json
631
- * { '.jpg': 'asset', '.png': 'base64' }
740
+ * { ".jpg": "asset", ".png": "base64" }
632
741
  * ```
633
742
  */
634
743
  loader?: ModuleTypes;
635
744
  /**
636
- * If enabled, strips the `node:` protocol prefix from import source.
745
+ * Remove the `node:` prefix from built-in Node.js module imports.
746
+ * When enabled, rewrites import sources like `node:fs` to `fs`.
637
747
  *
638
748
  * @default false
639
- * @deprecated Use `nodeProtocol: 'strip'` instead.
749
+ * @deprecated Use {@linkcode nodeProtocol | nodeProtocol: 'strip'} instead.
640
750
  *
641
751
  * @example
642
- * // With removeNodeProtocol enabled:
643
- * import('node:fs'); // becomes import('fs')
752
+ * <caption>`removeNodeProtocol: true` remove the `node:` prefix</caption>
753
+ *
754
+ * ```ts
755
+ * // Input
756
+ * import 'node:fs'
757
+ *
758
+ * // Output
759
+ * import 'fs'
760
+ * ```
644
761
  */
645
762
  removeNodeProtocol?: boolean;
646
763
  /**
647
- * - If `true`, add `node:` prefix to built-in modules.
648
- * - If `'strip'`, strips the `node:` protocol prefix from import source.
649
- * - If `false`, does not modify the import source.
764
+ * Control whether built-in Node.js module imports use the `node:` protocol.
765
+ *
766
+ * - `true`: Add the `node:` prefix to built-in module imports.
767
+ * - `'strip'`: Remove the `node:` prefix from built-in module imports.
768
+ * - `false`: Do not transform built-in module imports.
650
769
  *
651
770
  * @default false
652
771
  *
653
772
  * @example
654
- * // With nodeProtocol enabled:
655
- * import('fs'); // becomes import('node:fs')
656
- * // With nodeProtocol set to 'strip':
657
- * import('node:fs'); // becomes import('fs')
658
- * // With nodeProtocol set to false:
659
- * import('node:fs'); // remains import('node:fs')
773
+ * <caption>`nodeProtocol: true` add the `node:` prefix</caption>
660
774
  *
775
+ * ```ts
776
+ * // Input
777
+ * import 'fs'
778
+ *
779
+ * // Output
780
+ * import 'node:fs'
781
+ * ```
782
+ *
783
+ * @example
784
+ * <caption>`nodeProtocol: 'strip'` — remove the `node:` prefix</caption>
785
+ *
786
+ * ```ts
787
+ * // Input
788
+ * import 'node:fs'
789
+ *
790
+ * // Output
791
+ * import 'fs'
792
+ * ```
793
+ *
794
+ * @example
795
+ * <caption>`nodeProtocol: false` — do not transform imports</caption>
796
+ *
797
+ * ```ts
798
+ * // Input
799
+ * import 'node:fs'
800
+ *
801
+ * // Output
802
+ * import 'node:fs'
803
+ * ```
661
804
  */
662
805
  nodeProtocol?: "strip" | boolean;
663
806
  /**
@@ -687,11 +830,13 @@ interface UserConfig {
687
830
  * - `iife`: IIFE
688
831
  * - `umd`: UMD
689
832
  *
690
- * Defaults to ESM.
833
+ * @default 'esm'
691
834
  */
692
835
  format?: Format | Format[] | Partial<Record<Format, Partial<ResolvedConfig>>>;
693
836
  globalName?: string;
694
- /** @default 'dist' */
837
+ /**
838
+ * @default 'dist'
839
+ */
695
840
  outDir?: string;
696
841
  /**
697
842
  * Whether to write the files to disk.
@@ -703,7 +848,7 @@ interface UserConfig {
703
848
  * Whether to generate source map files.
704
849
  *
705
850
  * Note that this option will always be `true` if you have
706
- * [`declarationMap`](https://www.typescriptlang.org/tsconfig/#declarationMap)
851
+ * {@link https://www.typescriptlang.org/tsconfig/#declarationMap | `declarationMap`}
707
852
  * option enabled in your `tsconfig.json`.
708
853
  *
709
854
  * @default false
@@ -723,8 +868,8 @@ interface UserConfig {
723
868
  footer?: ChunkAddon;
724
869
  banner?: ChunkAddon;
725
870
  /**
726
- * Determines whether unbundle mode is enabled.
727
- * When set to true, the output files will mirror the input file structure.
871
+ * Determines whether `unbundle` is enabled.
872
+ * When set to `true`, the output files will mirror the input file structure.
728
873
  * @default false
729
874
  */
730
875
  unbundle?: boolean;
@@ -738,7 +883,7 @@ interface UserConfig {
738
883
  */
739
884
  root?: string;
740
885
  /**
741
- * @deprecated Use `unbundle` instead.
886
+ * @deprecated Use {@linkcode unbundle} instead.
742
887
  * @default true
743
888
  */
744
889
  bundle?: boolean;
@@ -747,12 +892,15 @@ interface UserConfig {
747
892
  * The extension will always be `.cjs` or `.mjs`.
748
893
  * Otherwise, it will depend on the package type.
749
894
  *
750
- * Defaults to `true` if `platform` is set to `node`, `false` otherwise.
895
+ * Defaults to `true` if {@linkcode platform} is set to `node`,
896
+ * `false` otherwise.
897
+ *
898
+ * @default platform === 'node'
751
899
  */
752
900
  fixedExtension?: boolean;
753
901
  /**
754
902
  * Custom extensions for output files.
755
- * `fixedExtension` will be overridden by this option.
903
+ * {@linkcode fixedExtension} will be overridden by this option.
756
904
  */
757
905
  outExtensions?: OutExtensionFactory;
758
906
  /**
@@ -772,8 +920,10 @@ interface UserConfig {
772
920
  }) => Awaitable<OutputOptions | void | null>);
773
921
  /**
774
922
  * The working directory of the config file.
775
- * - Defaults to `process.cwd()` for root config.
776
- * - Defaults to the package directory for workspace config.
923
+ * - Defaults to {@linkcode process.cwd | process.cwd()} for root config.
924
+ * - Defaults to the package directory for {@linkcode workspace} config.
925
+ *
926
+ * @default process.cwd()
777
927
  */
778
928
  cwd?: string;
779
929
  /**
@@ -812,7 +962,7 @@ interface UserConfig {
812
962
  /**
813
963
  * **[experimental]** Enable devtools.
814
964
  *
815
- *DevTools is still under development, and this is for early testers only.
965
+ * DevTools is still under development, and this is for early testers only.
816
966
  *
817
967
  * This may slow down the build process significantly.
818
968
  *
@@ -827,7 +977,7 @@ interface UserConfig {
827
977
  * Enables generation of TypeScript declaration files (`.d.ts`).
828
978
  *
829
979
  * By default, this option is auto-detected based on your project's `package.json`:
830
- * - If {@link exe} is enabled, declaration file generation is disabled by default.
980
+ * - If {@linkcode exe} is enabled, declaration file generation is disabled by default.
831
981
  * - If the `types` field is present, or if the main `exports` contains a `types` entry, declaration file generation is enabled by default.
832
982
  * - Otherwise, declaration file generation is disabled by default.
833
983
  */
@@ -839,7 +989,7 @@ interface UserConfig {
839
989
  */
840
990
  unused?: WithEnabled<UnusedOptions>;
841
991
  /**
842
- * Run publint after bundling.
992
+ * Run `publint` after bundling.
843
993
  * Requires `publint` to be installed.
844
994
  * @default false
845
995
  */
@@ -868,19 +1018,22 @@ interface UserConfig {
868
1018
  *
869
1019
  * This will set the `main`, `module`, `types`, `exports` fields in `package.json`
870
1020
  * to point to the generated files.
1021
+ *
1022
+ * @default false
871
1023
  */
872
1024
  exports?: WithEnabled<ExportsOptions>;
873
1025
  /**
874
1026
  * **[experimental]** CSS options.
875
1027
  * Requires `@tsdown/css` to be installed.
876
1028
  */
877
- css?: _$_tsdown_css0.CssOptions;
1029
+ css?: CssOptions;
878
1030
  /**
879
- * @deprecated Use `css.inject` instead.
1031
+ * @deprecated Use {@linkcode CssOptions.inject | css.inject} instead.
880
1032
  */
881
1033
  injectStyle?: boolean;
882
1034
  /**
883
- * @deprecated Alias for `copy`, will be removed in the future.
1035
+ * @alias copy
1036
+ * @deprecated Alias for {@linkcode copy}, will be removed in the future.
884
1037
  */
885
1038
  publicDir?: CopyOptions | CopyOptionsFn;
886
1039
  /**
@@ -903,6 +1056,8 @@ interface UserConfig {
903
1056
  *
904
1057
  * This will bundle the output into a single executable file using Node.js SEA.
905
1058
  * Note that this is only supported on Node.js 25.7.0 and later, and is not supported in Bun or Deno.
1059
+ *
1060
+ * @default false
906
1061
  */
907
1062
  exe?: WithEnabled<ExeOptions>;
908
1063
  /**
@@ -920,7 +1075,7 @@ interface InlineConfig extends UserConfig {
920
1075
  * Config loader to use. It can only be set via CLI or API.
921
1076
  * @default 'auto'
922
1077
  */
923
- configLoader?: "auto" | "native" | "unrun";
1078
+ configLoader?: "auto" | "native" | "tsx" | "unrun";
924
1079
  /**
925
1080
  * Filter configs by cwd or name.
926
1081
  */
@@ -932,7 +1087,13 @@ type UserConfigFn = (inlineConfig: InlineConfig, context: {
932
1087
  }) => Awaitable<Arrayable<UserConfig>>;
933
1088
  type UserConfigExport = Awaitable<Arrayable<UserConfig> | UserConfigFn>;
934
1089
  type ResolvedConfig = Overwrite<MarkPartial<Omit<UserConfig, "workspace" | "fromVite" | "publicDir" | "bundle" | "injectStyle" | "removeNodeProtocol" | "external" | "noExternal" | "inlineOnly" | "skipNodeModulesBundle" | "logLevel" | "failOnWarn" | "customLogger" | "envFile" | "envPrefix">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "onSuccess" | "outExtensions" | "hooks" | "copy" | "loader" | "name" | "banner" | "footer" | "checks" | "css">, {
935
- /** Resolved entry map (after glob expansion) */entry: Record<string, string>; /** Original entry config before glob resolution (for watch mode re-globbing) */
1090
+ /**
1091
+ * Resolved entry map (after glob expansion)
1092
+ */
1093
+ entry: Record<string, string>;
1094
+ /**
1095
+ * Original entry config before glob resolution (for watch mode re-globbing)
1096
+ */
936
1097
  rawEntry?: TsdownInputOption;
937
1098
  nameLabel: string | undefined;
938
1099
  format: NormalizedFormat;
@@ -942,7 +1103,10 @@ type ResolvedConfig = Overwrite<MarkPartial<Omit<UserConfig, "workspace" | "from
942
1103
  nodeProtocol: "strip" | boolean;
943
1104
  logger: Logger;
944
1105
  ignoreWatch: Array<string | RegExp>;
945
- deps: ResolvedDepsConfig; /** Resolved root directory of input files */
1106
+ deps: ResolvedDepsConfig;
1107
+ /**
1108
+ * Resolved root directory of input files
1109
+ */
946
1110
  root: string;
947
1111
  configDeps: Set<string>;
948
1112
  dts: false | DtsOptions;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tsdown",
3
3
  "type": "module",
4
- "version": "0.21.9",
4
+ "version": "0.22.0-beta.1",
5
5
  "description": "The Elegant Bundler for Libraries",
6
6
  "author": "Kevin Deng <sxzz@sxzz.moe>",
7
7
  "license": "MIT",
@@ -44,16 +44,18 @@
44
44
  "access": "public"
45
45
  },
46
46
  "engines": {
47
- "node": ">=20.19.0"
47
+ "node": ">=22.18.0"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@arethetypeswrong/core": "^0.18.1",
51
51
  "@vitejs/devtools": "*",
52
- "publint": "^0.3.0",
52
+ "publint": "^0.3.8",
53
+ "tsx": "*",
53
54
  "typescript": "^5.0.0 || ^6.0.0",
54
55
  "unplugin-unused": "^0.5.0",
55
- "@tsdown/css": "0.21.9",
56
- "@tsdown/exe": "0.21.9"
56
+ "unrun": "*",
57
+ "@tsdown/css": "0.22.0-beta.1",
58
+ "@tsdown/exe": "0.22.0-beta.1"
57
59
  },
58
60
  "peerDependenciesMeta": {
59
61
  "@arethetypeswrong/core": {
@@ -71,11 +73,17 @@
71
73
  "publint": {
72
74
  "optional": true
73
75
  },
76
+ "tsx": {
77
+ "optional": true
78
+ },
74
79
  "typescript": {
75
80
  "optional": true
76
81
  },
77
82
  "unplugin-unused": {
78
83
  "optional": true
84
+ },
85
+ "unrun": {
86
+ "optional": true
79
87
  }
80
88
  },
81
89
  "dependencies": {
@@ -87,14 +95,13 @@
87
95
  "import-without-cache": "^0.3.3",
88
96
  "obug": "^2.1.1",
89
97
  "picomatch": "^4.0.4",
90
- "rolldown": "1.0.0-rc.16",
98
+ "rolldown": "1.0.0-rc.17",
91
99
  "rolldown-plugin-dts": "^0.23.2",
92
100
  "semver": "^7.7.4",
93
101
  "tinyexec": "^1.1.1",
94
102
  "tinyglobby": "^0.2.16",
95
103
  "tree-kill": "^1.2.2",
96
- "unconfig-core": "^7.5.0",
97
- "unrun": "^0.2.36"
104
+ "unconfig-core": "^7.5.0"
98
105
  },
99
106
  "inlinedDependencies": {
100
107
  "is-in-ci": "2.0.0",
@@ -105,22 +112,22 @@
105
112
  "@arethetypeswrong/core": "^0.18.2",
106
113
  "@sxzz/eslint-config": "^7.8.4",
107
114
  "@sxzz/prettier-config": "^2.3.1",
108
- "@sxzz/test-utils": "^0.5.16",
115
+ "@sxzz/test-utils": "^0.5.18",
109
116
  "@types/node": "^25.6.0",
110
117
  "@types/picomatch": "^4.0.3",
111
118
  "@types/semver": "^7.7.1",
112
- "@typescript/native-preview": "7.0.0-dev.20260416.1",
119
+ "@typescript/native-preview": "7.0.0-dev.20260425.1",
113
120
  "@unocss/eslint-plugin": "^66.6.8",
114
- "@vitejs/devtools": "^0.1.13",
115
- "@vitest/coverage-v8": "^4.1.4",
116
- "@vitest/ui": "^4.1.4",
121
+ "@vitejs/devtools": "^0.1.15",
122
+ "@vitest/coverage-v8": "^4.1.5",
123
+ "@vitest/ui": "^4.1.5",
117
124
  "@vueuse/core": "^14.2.1",
118
- "baseline-browser-mapping": "^2.10.19",
125
+ "baseline-browser-mapping": "^2.10.22",
119
126
  "bumpp": "^11.0.1",
120
127
  "dedent": "^1.7.2",
121
- "eslint": "^10.2.0",
128
+ "eslint": "^10.2.1",
122
129
  "is-in-ci": "^2.0.0",
123
- "memfs": "^4.57.1",
130
+ "memfs": "^4.57.2",
124
131
  "package-manager-detector": "^1.6.0",
125
132
  "pkg-types": "^2.3.0",
126
133
  "postcss": "^8.5.10",
@@ -129,18 +136,20 @@
129
136
  "publint": "^0.3.18",
130
137
  "rolldown-plugin-require-cjs": "^0.4.0",
131
138
  "sass": "^1.99.0",
132
- "tsnapi": "^0.3.0",
133
- "typescript": "~6.0.2",
139
+ "tsnapi": "^0.3.2",
140
+ "tsx": "^4.20.3",
141
+ "typescript": "~6.0.3",
134
142
  "unocss": "^66.6.8",
135
143
  "unplugin-ast": "^0.16.0",
136
144
  "unplugin-raw": "^0.7.0",
137
145
  "unplugin-unused": "^0.5.7",
138
146
  "unplugin-vue": "^7.1.1",
139
- "vite": "^8.0.8",
140
- "vitest": "^4.1.4",
141
- "vue": "^3.5.32",
142
- "@tsdown/exe": "0.21.9",
143
- "@tsdown/css": "0.21.9"
147
+ "unrun": "^0.2.37",
148
+ "vite": "^8.0.10",
149
+ "vitest": "^4.1.5",
150
+ "vue": "^3.5.33",
151
+ "@tsdown/css": "0.22.0-beta.1",
152
+ "@tsdown/exe": "0.22.0-beta.1"
144
153
  },
145
154
  "prettier": "@sxzz/prettier-config",
146
155
  "scripts": {
@@ -7,8 +7,8 @@ import { chmod } from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { bold, dim, green, underline } from "ansis";
9
9
  import { createDebug } from "obug";
10
- import { glob, isDynamicPattern } from "tinyglobby";
11
10
  import { RE_DTS } from "rolldown-plugin-dts/internal";
11
+ import { glob, isDynamicPattern } from "tinyglobby";
12
12
  import { promisify } from "node:util";
13
13
  import { Buffer } from "node:buffer";
14
14
  import { brotliCompress, gzip } from "node:zlib";