tsdown 0.14.2 → 0.15.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.
package/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
1
  The MIT License (MIT)
2
2
 
3
3
  Copyright (c) 2025-present VoidZero Inc. & Contributors
4
- Copyright (c) 2024 三咲智子 Kevin Deng (https://github.com/sxzz)
4
+ Copyright (c) 2024 Kevin Deng (https://github.com/sxzz)
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  of this software and associated documentation files (the "Software"), to deal
package/client.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ interface ImportGlobOptions<Eager extends boolean> {
2
+ /**
3
+ * Import as static or dynamic
4
+ *
5
+ * @default false
6
+ */
7
+ eager?: Eager
8
+ /**
9
+ * Import only the specific named export. Set to `default` to import the default export.
10
+ */
11
+ import?: string
12
+ /**
13
+ * Custom queries
14
+ */
15
+ query?: string | Record<string, string | number | boolean>
16
+ /**
17
+ * Search files also inside `node_modules/` and hidden directories (e.g. `.git/`). This might have impact on performance.
18
+ *
19
+ * @default false
20
+ */
21
+ exhaustive?: boolean
22
+ /**
23
+ * Base path to resolve relative paths.
24
+ */
25
+ base?: string
26
+ }
27
+
28
+ type GeneralImportGlobOptions = ImportGlobOptions<boolean>
29
+
30
+ interface KnownAsTypeMap {
31
+ raw: string
32
+ url: string
33
+ }
34
+
35
+ interface ImportGlobFunction {
36
+ /**
37
+ * Import a list of files with a glob pattern.
38
+ *
39
+ * Overload 1: Module generic provided, infer the type from `eager: false`
40
+ */
41
+ <M>(
42
+ glob: string | string[],
43
+ options?: ImportGlobOptions<false>,
44
+ ): Record<string, () => Promise<M>>
45
+ /**
46
+ * Import a list of files with a glob pattern.
47
+ *
48
+ * Overload 2: Module generic provided, infer the type from `eager: true`
49
+ */
50
+ <M>(
51
+ glob: string | string[],
52
+ options: ImportGlobOptions<true>,
53
+ ): Record<string, M>
54
+ }
55
+
56
+ interface ImportMeta {
57
+ glob: ImportGlobFunction
58
+ }
@@ -1,4 +1,4 @@
1
- import { UserConfig, UserConfigFn } from "./types-cXo_SNGd.mjs";
1
+ import { UserConfig, UserConfigFn } from "./types-CttfsBjJ.mjs";
2
2
 
3
3
  //#region src/config.d.ts
4
4
 
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { UserConfig, UserConfigFn } from "./types-cXo_SNGd.mjs";
2
- import { defineConfig } from "./config-DwMASPo6.mjs";
1
+ import { UserConfig, UserConfigFn } from "./types-CttfsBjJ.mjs";
2
+ import { defineConfig } from "./config-Cb8AaSYW.mjs";
3
3
  export { UserConfig, UserConfigFn, defineConfig };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, Logger, ModuleTypes, NormalizedFormat, NormalizedUserConfig, Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, ResolvedOptions, RolldownContext, Sourcemap, TsdownChunks, TsdownHooks, UnusedOptions, UserConfig, UserConfigFn, Workspace, globalLogger } from "./types-cXo_SNGd.mjs";
2
- import { defineConfig } from "./config-DwMASPo6.mjs";
1
+ import { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, Logger, ModuleTypes, NormalizedFormat, NormalizedUserConfig, Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, ResolvedOptions, RolldownContext, Sourcemap, TsdownChunks, TsdownHooks, UnusedOptions, UserConfig, UserConfigFn, Workspace, globalLogger } from "./types-CttfsBjJ.mjs";
2
+ import { defineConfig } from "./config-Cb8AaSYW.mjs";
3
3
 
4
4
  //#region src/index.d.ts
5
5
 
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defineConfig } from "./config-CCGWF4al.mjs";
2
- import { build, buildSingle, shimFile } from "./src-BhIGOkxO.mjs";
3
- import { globalLogger } from "./logger-CGMSjTLn.mjs";
2
+ import { build, buildSingle, shimFile } from "./src-Cv09-2ZP.mjs";
3
+ import { globalLogger } from "./logger-C09npKHT.mjs";
4
4
 
5
5
  export { build, buildSingle, defineConfig, globalLogger, shimFile };
@@ -45,10 +45,8 @@ const warnedMessages = /* @__PURE__ */ new Set();
45
45
  function createLogger(level = "info", { customLogger, console = globalThis.console, failOnWarn = false } = {}) {
46
46
  if (customLogger) return customLogger;
47
47
  function output(type, msg) {
48
- const thresh = LogLevels[logger.level];
49
- if (thresh < LogLevels[type]) return;
50
- const method = type === "info" ? "log" : type;
51
- console[method](msg);
48
+ if (LogLevels[logger.level] < LogLevels[type]) return;
49
+ console[type === "info" ? "log" : type](msg);
52
50
  }
53
51
  const logger = {
54
52
  level,
@@ -104,9 +102,7 @@ function generateColor(name = "default") {
104
102
  let hash = 0;
105
103
  for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
106
104
  const hue = hash % 360;
107
- const saturation = 35;
108
- const lightness = 55;
109
- color = rgb(...hslToRgb(hue, saturation, lightness));
105
+ color = rgb(...hslToRgb(hue, 35, 55));
110
106
  }
111
107
  colors.set(name, color);
112
108
  return color;
@@ -1,5 +1,5 @@
1
- import { globalLogger } from "./logger-CGMSjTLn.mjs";
2
- import { version } from "./package-DOwY1eta.mjs";
1
+ import { globalLogger } from "./logger-C09npKHT.mjs";
2
+ import { version } from "./package-CGTDSgsc.mjs";
3
3
  import process from "node:process";
4
4
  import { bold, green, underline } from "ansis";
5
5
  import { readFile, unlink, writeFile } from "node:fs/promises";
@@ -17,8 +17,7 @@ async function migrate({ cwd, dryRun }) {
17
17
  globalLogger.warn(`\n\nBefore proceeding, review the migration guide at ${underline`https://tsdown.dev/guide/migrate-from-tsup`}, as this process will modify your files.\nUncommitted changes will be lost. Use the ${green`--dry-run`} flag to preview changes without applying them.`);
18
18
  const input = await rl.question(bold`Continue? (Y/n) `);
19
19
  rl.close();
20
- const confirm = input.toLowerCase() === "y" || input === "";
21
- if (!confirm) {
20
+ if (!(input.toLowerCase() === "y" || input === "")) {
22
21
  globalLogger.error("Migration cancelled.");
23
22
  process.exitCode = 1;
24
23
  return;
@@ -0,0 +1,5 @@
1
+ //#region package.json
2
+ var version = "0.15.1";
3
+
4
+ //#endregion
5
+ export { version };
@@ -1,4 +1,4 @@
1
- import { Logger, ReportPlugin, ResolvedOptions } from "./types-cXo_SNGd.mjs";
1
+ import { Logger, ReportPlugin, ResolvedOptions } from "./types-CttfsBjJ.mjs";
2
2
  import { Plugin } from "rolldown";
3
3
  import { PackageJson } from "pkg-types";
4
4
 
package/dist/plugins.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./config-CCGWF4al.mjs";
2
- import { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin } from "./src-BhIGOkxO.mjs";
3
- import "./logger-CGMSjTLn.mjs";
2
+ import { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin } from "./src-Cv09-2ZP.mjs";
3
+ import "./logger-C09npKHT.mjs";
4
4
 
5
5
  export { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin };
package/dist/run.d.mts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export { };
package/dist/run.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { globalLogger, resolveComma, toArray } from "./logger-CGMSjTLn.mjs";
3
- import { version } from "./package-DOwY1eta.mjs";
2
+ import { globalLogger, resolveComma, toArray } from "./logger-C09npKHT.mjs";
3
+ import { version } from "./package-CGTDSgsc.mjs";
4
4
  import module from "node:module";
5
5
  import process from "node:process";
6
6
  import { dim } from "ansis";
@@ -14,7 +14,7 @@ cli.help().version(version);
14
14
  cli.command("[...files]", "Bundle files", {
15
15
  ignoreOptionDefaultValue: true,
16
16
  allowUnknownOptions: true
17
- }).option("-c, --config <filename>", "Use a custom config file").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("--external <module>", "Mark dependencies as external").option("--minify", "Minify output").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("-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("--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("-W, --workspace [dir]", "Enable workspace mode").option("-F, --filter <pattern>", "Filter workspace packages, e.g. /regex/ or substring").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, unconfig", { 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("--external <module>", "Mark dependencies as external").option("--minify", "Minify output").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("-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("--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("-W, --workspace [dir]", "Enable workspace mode").option("-F, --filter <pattern>", "Filter workspace packages, e.g. /regex/ or substring").option("--exports", "Generate export-related metadata for package.json (experimental)").action(async (input, flags) => {
18
18
  globalLogger.level = flags.logLevel || (flags.silent ? "silent" : "info");
19
19
  globalLogger.info(`tsdown ${dim`v${version}`} powered by rolldown ${dim`v${VERSION}`}`);
20
20
  const { build: build$1 } = await import("./index.mjs");
@@ -22,7 +22,7 @@ cli.command("[...files]", "Bundle files", {
22
22
  await build$1(flags);
23
23
  });
24
24
  cli.command("migrate", "Migrate from tsup to tsdown").option("-c, --cwd <dir>", "Working directory").option("-d, --dry-run", "Dry run").action(async (args) => {
25
- const { migrate } = await import("./migrate-DQpxfr1J.mjs");
25
+ const { migrate } = await import("./migrate-CliKn3g9.mjs");
26
26
  await migrate(args);
27
27
  });
28
28
  async function runCLI() {
@@ -1,4 +1,4 @@
1
- import { LogLevels, createLogger, debounce, generateColor, globalLogger, noop, prettyFormat, prettyName, resolveComma, resolveRegex, slash, toArray } from "./logger-CGMSjTLn.mjs";
1
+ import { LogLevels, createLogger, debounce, generateColor, globalLogger, noop, prettyFormat, prettyName, resolveComma, resolveRegex, slash, toArray } from "./logger-C09npKHT.mjs";
2
2
  import { builtinModules } from "node:module";
3
3
  import path, { dirname, normalize, sep } from "node:path";
4
4
  import process from "node:process";
@@ -17,6 +17,7 @@ import satisfies from "semver/functions/satisfies.js";
17
17
  import { glob } from "tinyglobby";
18
18
  import { RE_CSS, RE_DTS, RE_JS } from "rolldown-plugin-dts/filename";
19
19
  import { createHooks } from "hookable";
20
+ import { importGlobPlugin } from "rolldown/experimental";
20
21
  import minVersion from "semver/ranges/min-version.js";
21
22
  import { up } from "empathic/find";
22
23
  import { up as up$1 } from "empathic/package";
@@ -93,8 +94,7 @@ function formatProblem(problem) {
93
94
  case "CJSResolvesToESM": return ` ⚡ CJS resolves to ESM${resolutionKind}${entrypoint}`;
94
95
  case "NamedExports": {
95
96
  const missingExports = problem.missing?.length > 0 ? ` Missing: ${problem.missing.join(", ")}` : "";
96
- const allMissing = problem.isMissingAllNamed ? " (all named exports missing)" : "";
97
- return ` 📤 Named exports problem${allMissing}${missingExports}\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
97
+ return ` 📤 Named exports problem${problem.isMissingAllNamed ? " (all named exports missing)" : ""}${missingExports}\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
98
98
  }
99
99
  case "FallbackCondition": return ` 🎯 Fallback condition used${resolutionKind}${entrypoint}`;
100
100
  case "FalseExportDefault": return ` 🎭 False export default\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
@@ -139,8 +139,7 @@ async function attw(options) {
139
139
  return true;
140
140
  });
141
141
  if (problems.length) {
142
- const problemList = problems.map(formatProblem).join("\n");
143
- const problemMessage = `Are the types wrong problems found:\n${problemList}`;
142
+ const problemMessage = `Are the types wrong problems found:\n${problems.map(formatProblem).join("\n")}`;
144
143
  if (level === "error") throw new Error(problemMessage);
145
144
  options.logger.warn(problemMessage);
146
145
  }
@@ -163,11 +162,10 @@ async function attw(options) {
163
162
  */
164
163
  function warnLegacyCJS(config) {
165
164
  if (!config.format.includes("cjs") || !config.target) return;
166
- const legacy = config.target.some((t) => {
165
+ if (config.target.some((t) => {
167
166
  const version = coerce(t.split("node")[1]);
168
167
  return version && satisfies(version, ">=23.0.0 || >=22.12.0");
169
- });
170
- if (legacy) config.logger.warnOnce("We recommend using the ESM format instead of CommonJS.\nThe ESM format is compatible with modern platforms and runtimes, and most new libraries are now distributed only in ESM format.\nLearn more at https://nodejs.org/en/learn/modules/publishing-a-package#how-did-we-get-here");
168
+ })) config.logger.warnOnce("We recommend using the ESM format instead of CommonJS.\nThe ESM format is compatible with modern platforms and runtimes, and most new libraries are now distributed only in ESM format.\nLearn more at https://nodejs.org/en/learn/modules/publishing-a-package#how-did-we-get-here");
171
169
  }
172
170
 
173
171
  //#endregion
@@ -184,10 +182,7 @@ async function cleanOutDir(configs) {
184
182
  onlyFiles: false
185
183
  });
186
184
  const normalizedOutDir = config.outDir.replace(RE_LAST_SLASH, "");
187
- for (const file of files) {
188
- const normalizedFile = file.replace(RE_LAST_SLASH, "");
189
- if (normalizedFile !== normalizedOutDir) removes.add(file);
190
- }
185
+ for (const file of files) if (file.replace(RE_LAST_SLASH, "") !== normalizedOutDir) removes.add(file);
191
186
  }
192
187
  if (!removes.size) return;
193
188
  globalLogger.info(`Cleaning ${removes.size} files`);
@@ -263,10 +258,7 @@ async function generateExports(pkg, outDir, chunks, { devExports, all, customExp
263
258
  else main = distFile;
264
259
  else if (format === "es") if (isDts) esmTypes = distFile;
265
260
  else module$1 = distFile;
266
- } else {
267
- const isDirIndex = name.endsWith("/index");
268
- name = isDirIndex ? `./${name.slice(0, -6)}` : `./${name}`;
269
- }
261
+ } else name = name.endsWith("/index") ? `./${name.slice(0, -6)}` : `./${name}`;
270
262
  let subExport = exportsMap.get(name);
271
263
  if (!subExport) {
272
264
  subExport = {};
@@ -345,13 +337,12 @@ async function createHooks$1(options) {
345
337
  const hooks = createHooks();
346
338
  if (typeof options.hooks === "object") hooks.addHooks(options.hooks);
347
339
  else if (typeof options.hooks === "function") await options.hooks(hooks);
348
- const context = {
349
- options,
350
- hooks
351
- };
352
340
  return {
353
341
  hooks,
354
- context
342
+ context: {
343
+ options,
344
+ hooks
345
+ }
355
346
  };
356
347
  }
357
348
 
@@ -570,7 +561,11 @@ async function loadConfigFile(options, workspace) {
570
561
  } else if (stats.isDirectory()) cwd = resolved;
571
562
  }
572
563
  }
573
- const nativeTS = process.features.typescript || process.versions.bun || process.versions.deno;
564
+ let isNative = false;
565
+ if (!loaded) {
566
+ if (!options.configLoader || options.configLoader === "auto") isNative = !!(process.features.typescript || process.versions.bun || process.versions.deno);
567
+ else if (options.configLoader === "native") isNative = true;
568
+ }
574
569
  let { config, sources } = await loadConfig.async({
575
570
  sources: overrideConfig ? [{
576
571
  files: filePath,
@@ -587,11 +582,7 @@ async function loadConfigFile(options, workspace) {
587
582
  "json",
588
583
  ""
589
584
  ],
590
- parser: loaded || !nativeTS ? "auto" : async (filepath) => {
591
- const mod = await import(pathToFileURL(filepath).href);
592
- const config$1 = mod.default || mod;
593
- return config$1;
594
- }
585
+ parser: isNative ? nativeImport : "auto"
595
586
  }, {
596
587
  files: "package.json",
597
588
  extensions: [],
@@ -611,6 +602,16 @@ async function loadConfigFile(options, workspace) {
611
602
  file
612
603
  };
613
604
  }
605
+ async function nativeImport(id) {
606
+ const mod = await import(pathToFileURL(id).href).catch((error) => {
607
+ if (error?.message?.includes?.("Cannot find module")) {
608
+ const configError = /* @__PURE__ */ new Error(`Failed to load the config file. Try setting the --config-loader CLI flag to \`unconfig\`.\n\n${error.message}`);
609
+ configError.cause = error;
610
+ throw configError;
611
+ } else throw error;
612
+ });
613
+ return mod.default || mod;
614
+ }
614
615
 
615
616
  //#endregion
616
617
  //#region src/options/index.ts
@@ -676,25 +677,24 @@ async function resolveWorkspace(config, options) {
676
677
  if (packages.length === 0) throw new Error("No packages matched the filters");
677
678
  }
678
679
  const files = [];
679
- const configs = (await Promise.all(packages.map(async (cwd) => {
680
- debug$3("loading workspace config %s", cwd);
681
- const { configs: configs$1, file } = await loadConfigFile({
682
- ...options,
683
- config: workspaceConfig,
684
- cwd
685
- }, cwd);
686
- if (file) {
687
- debug$3("loaded workspace config file %s", file);
688
- files.push(file);
689
- } else debug$3("no workspace config file found in %s", cwd);
690
- return configs$1.map((config$1) => ({
691
- ...normalized,
692
- cwd,
693
- ...config$1
694
- }));
695
- }))).flat();
696
680
  return {
697
- configs,
681
+ configs: (await Promise.all(packages.map(async (cwd) => {
682
+ debug$3("loading workspace config %s", cwd);
683
+ const { configs, file } = await loadConfigFile({
684
+ ...options,
685
+ config: workspaceConfig,
686
+ cwd
687
+ }, cwd);
688
+ if (file) {
689
+ debug$3("loaded workspace config file %s", file);
690
+ files.push(file);
691
+ } else debug$3("no workspace config file found in %s", cwd);
692
+ return configs.map((config$1) => ({
693
+ ...normalized,
694
+ cwd,
695
+ ...config$1
696
+ }));
697
+ }))).flat(),
698
698
  files
699
699
  };
700
700
  }
@@ -705,6 +705,7 @@ async function resolveConfig(userConfig) {
705
705
  failOnWarn
706
706
  });
707
707
  if (typeof bundle === "boolean") logger.warn("`bundle` option is deprecated. Use `unbundle` instead.");
708
+ if (removeNodeProtocol && nodeProtocol) throw new TypeError("`removeNodeProtocol` is deprecated. Please only use `nodeProtocol` instead.");
708
709
  nodeProtocol = nodeProtocol ?? (removeNodeProtocol ? "strip" : false);
709
710
  outDir = path.resolve(cwd, outDir);
710
711
  clean = resolveClean(clean, outDir, cwd);
@@ -735,7 +736,7 @@ async function resolveConfig(userConfig) {
735
736
  if (typeof ignore === "string") return path.resolve(cwd, ignore);
736
737
  return ignore;
737
738
  });
738
- const config = {
739
+ return {
739
740
  ...userConfig,
740
741
  entry,
741
742
  plugins,
@@ -771,7 +772,6 @@ async function resolveConfig(userConfig) {
771
772
  nodeProtocol,
772
773
  cjsDefault
773
774
  };
774
- return config;
775
775
  }
776
776
  async function mergeUserOptions(defaults, user, args) {
777
777
  const userOutputOptions = typeof user === "function" ? await user(defaults, ...args) : user;
@@ -794,8 +794,7 @@ function ExternalPlugin(options) {
794
794
  const { noExternal } = options;
795
795
  if (typeof noExternal === "function" && noExternal(id, importer)) return;
796
796
  if (noExternal) {
797
- const noExternalPatterns = toArray(noExternal);
798
- if (noExternalPatterns.some((pattern) => {
797
+ if (toArray(noExternal).some((pattern) => {
799
798
  if (pattern instanceof RegExp) {
800
799
  pattern.lastIndex = 0;
801
800
  return pattern.test(id);
@@ -836,8 +835,7 @@ function getProductionDeps(pkg) {
836
835
  */
837
836
  function esbuildTargetToLightningCSS(target) {
838
837
  let targets;
839
- const targetString = target.join(" ").toLowerCase();
840
- const matches = [...targetString.matchAll(TARGET_REGEX)];
838
+ const matches = [...target.join(" ").toLowerCase().matchAll(TARGET_REGEX)];
841
839
  for (const match of matches) {
842
840
  const name = match[1];
843
841
  const browser = ESBUILD_LIGHTNINGCSS_MAPPING[name];
@@ -878,6 +876,7 @@ async function LightningCSSPlugin(options) {
878
876
 
879
877
  //#endregion
880
878
  //#region src/features/node-protocol.ts
879
+ const modulesWithoutProtocol = builtinModules.filter((mod) => !mod.startsWith("node:"));
881
880
  /**
882
881
  * The `node:` protocol was added in Node.js v14.18.0.
883
882
  * @see https://nodejs.org/api/esm.html#node-imports
@@ -887,7 +886,7 @@ function NodeProtocolPlugin(nodeProtocolOption) {
887
886
  name: "tsdown:node-protocol:strip",
888
887
  resolveId: {
889
888
  order: "pre",
890
- filter: { id: /^node:/ },
889
+ filter: { id: /* @__PURE__ */ new RegExp(`^node:(${modulesWithoutProtocol.join("|")})$`) },
891
890
  handler(id) {
892
891
  return {
893
892
  id: id.slice(5),
@@ -897,12 +896,11 @@ function NodeProtocolPlugin(nodeProtocolOption) {
897
896
  }
898
897
  }
899
898
  };
900
- const builtinModulesRegex = /* @__PURE__ */ new RegExp(`^(${builtinModules.join("|")})$`);
901
899
  return {
902
900
  name: "tsdown:node-protocol:add",
903
901
  resolveId: {
904
902
  order: "pre",
905
- filter: { id: builtinModulesRegex },
903
+ filter: { id: /* @__PURE__ */ new RegExp(`^(${modulesWithoutProtocol.join("|")})$`) },
906
904
  handler(id) {
907
905
  return {
908
906
  id: `node:${id}`,
@@ -946,10 +944,15 @@ function createChunkFilename(basename, jsExtension, dtsExtension) {
946
944
  return `${basename}${chunk.name.endsWith(".d") ? dtsExtension : jsExtension}`;
947
945
  };
948
946
  }
949
- function resolveChunkAddon(chunkAddon, format) {
947
+ function resolveChunkAddon(chunkAddon, format, dts) {
950
948
  if (!chunkAddon) return;
951
949
  return (chunk) => {
952
- if (typeof chunkAddon === "function") chunkAddon = chunkAddon({ format });
950
+ if (!dts && RE_DTS.test(chunk.fileName)) return "";
951
+ if (typeof chunkAddon === "function") chunkAddon = chunkAddon({
952
+ format,
953
+ fileName: chunk.fileName
954
+ });
955
+ if (typeof chunkAddon === "string") return chunkAddon;
953
956
  switch (true) {
954
957
  case RE_JS.test(chunk.fileName): return chunkAddon?.js || "";
955
958
  case RE_CSS.test(chunk.fileName): return chunkAddon?.css || "";
@@ -1080,7 +1083,7 @@ async function getBuildOptions(config, format, isMultiFormat, cjsDts = false) {
1080
1083
  return rolldownConfig;
1081
1084
  }
1082
1085
  async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1083
- const { entry, external, plugins: userPlugins, platform, alias, treeshake, dts, unused, target, define, shims, tsconfig, cwd, report, env, nodeProtocol, loader, name, logger, cjsDefault } = config;
1086
+ const { entry, external, plugins: userPlugins, platform, alias, treeshake, dts, unused, target, define, shims, tsconfig, cwd, report, env, nodeProtocol, loader, name, logger, cjsDefault, banner, footer } = config;
1084
1087
  const plugins = [];
1085
1088
  if (nodeProtocol) plugins.push(NodeProtocolPlugin(nodeProtocol));
1086
1089
  if (config.pkg || config.skipNodeModulesBundle) plugins.push(ExternalPlugin(config));
@@ -1088,6 +1091,8 @@ async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1088
1091
  const { dts: dtsPlugin } = await import("rolldown-plugin-dts");
1089
1092
  const options = {
1090
1093
  tsconfig,
1094
+ banner: resolveChunkAddon(banner, format, true),
1095
+ footer: resolveChunkAddon(footer, format, true),
1091
1096
  ...dts
1092
1097
  };
1093
1098
  if (format === "es") plugins.push(dtsPlugin(options));
@@ -1103,11 +1108,11 @@ async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1103
1108
  plugins.push(Unused.rolldown(unused === true ? {} : unused));
1104
1109
  }
1105
1110
  if (target) plugins.push(RuntimeHelperCheckPlugin(logger, target), await LightningCSSPlugin({ target }));
1106
- plugins.push(ShebangPlugin(logger, cwd, name, isMultiFormat));
1111
+ plugins.push(ShebangPlugin(logger, cwd, name, isMultiFormat), importGlobPlugin());
1107
1112
  }
1108
1113
  if (report && LogLevels[logger.level] >= 3) plugins.push(ReportPlugin(report, logger, cwd, cjsDts, name, isMultiFormat));
1109
1114
  if (!cjsDts) plugins.push(userPlugins);
1110
- const inputOptions = await mergeUserOptions({
1115
+ return await mergeUserOptions({
1111
1116
  input: entry,
1112
1117
  cwd,
1113
1118
  external,
@@ -1133,12 +1138,11 @@ async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1133
1138
  defaultHandler(level, log);
1134
1139
  } : void 0
1135
1140
  }, config.inputOptions, [format, { cjsDts }]);
1136
- return inputOptions;
1137
1141
  }
1138
1142
  async function resolveOutputOptions(inputOptions, config, format, cjsDts) {
1139
1143
  const { entry, outDir, sourcemap, minify, unbundle, banner, footer, cjsDefault } = config;
1140
1144
  const [entryFileNames, chunkFileNames] = resolveChunkFilename(config, inputOptions, format);
1141
- const outputOptions = await mergeUserOptions({
1145
+ return await mergeUserOptions({
1142
1146
  format: cjsDts ? "es" : format,
1143
1147
  name: config.globalName,
1144
1148
  sourcemap,
@@ -1152,7 +1156,6 @@ async function resolveOutputOptions(inputOptions, config, format, cjsDts) {
1152
1156
  banner: resolveChunkAddon(banner, format),
1153
1157
  footer: resolveChunkAddon(footer, format)
1154
1158
  }, config.outputOptions, [format, { cjsDts }]);
1155
- return outputOptions;
1156
1159
  }
1157
1160
 
1158
1161
  //#endregion
@@ -120,8 +120,9 @@ interface ChunkAddonObject {
120
120
  }
121
121
  type ChunkAddonFunction = (ctx: {
122
122
  format: Format;
123
- }) => ChunkAddonObject | undefined;
124
- type ChunkAddon = ChunkAddonObject | ChunkAddonFunction;
123
+ fileName: string;
124
+ }) => ChunkAddonObject | string | undefined;
125
+ type ChunkAddon = ChunkAddonObject | ChunkAddonFunction | string;
125
126
  //#endregion
126
127
  //#region src/utils/logger.d.ts
127
128
  type LogType = "error" | "warn" | "info";
@@ -209,8 +210,9 @@ interface Options {
209
210
  *
210
211
  * Determines the JavaScript version or runtime(s) for which the code should be compiled.
211
212
  * If not set, defaults to the value of `engines.node` in your project's `package.json`.
213
+ * If no `engines.node` field exists, no syntax transformations are applied.
212
214
  *
213
- * Accepts a single target (e.g., `'es2020'`, `'node18'`) or an array of targets.
215
+ * Accepts a single target (e.g., `'es2020'`, `'node18'`), an array of targets, or `false` to disable all transformations.
214
216
  *
215
217
  * @see {@link https://tsdown.dev/options/target#supported-targets} for a list of valid targets and more details.
216
218
  *
@@ -225,6 +227,12 @@ interface Options {
225
227
  * // Target multiple environments
226
228
  * { "target": ["node18", "es2020"] }
227
229
  * ```
230
+ *
231
+ * @example
232
+ * ```jsonc
233
+ * // Disable all syntax transformations
234
+ * { "target": false }
235
+ * ```
228
236
  */
229
237
  target?: string | string[] | false;
230
238
  /**
@@ -267,9 +275,9 @@ interface Options {
267
275
  */
268
276
  removeNodeProtocol?: boolean;
269
277
  /**
270
- * - If true, add `node:` prefix to built-in modules.
271
- * - If 'strip', strips the `node:` protocol prefix from import source.
272
- * - If false, does not modify the import source.
278
+ * - If `true`, add `node:` prefix to built-in modules.
279
+ * - If `'strip'`, strips the `node:` protocol prefix from import source.
280
+ * - If `false`, does not modify the import source.
273
281
  *
274
282
  * @default false
275
283
  *
@@ -378,6 +386,11 @@ interface Options {
378
386
  */
379
387
  config?: boolean | string;
380
388
  /**
389
+ * Config loader to use. It can only be set via CLI or API.
390
+ * @default 'auto'
391
+ */
392
+ configLoader?: "auto" | "native" | "unconfig";
393
+ /**
381
394
  * Reuse config from Vite or Vitest (experimental)
382
395
  * @default false
383
396
  */
@@ -460,10 +473,10 @@ interface Options {
460
473
  /**
461
474
  * Options without specifying config file path.
462
475
  */
463
- type UserConfig = Arrayable<Omit<Options, "config" | "filter">>;
476
+ type UserConfig = Arrayable<Omit<Options, "config" | "filter" | "configLoader">>;
464
477
  type UserConfigFn = (cliOptions: Options) => Awaitable<UserConfig>;
465
478
  type NormalizedUserConfig = Exclude<UserConfig, any[]>;
466
- type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "workspace" | "filter" | "silent" | "logLevel" | "failOnWarn" | "customLogger">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "noExternal" | "onSuccess" | "fixedExtension" | "outExtensions" | "hooks" | "removeNodeProtocol" | "copy" | "loader" | "name" | "bundle" | "banner" | "footer">, {
479
+ type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "workspace" | "filter" | "silent" | "logLevel" | "failOnWarn" | "customLogger" | "configLoader">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "noExternal" | "onSuccess" | "fixedExtension" | "outExtensions" | "hooks" | "removeNodeProtocol" | "copy" | "loader" | "name" | "bundle" | "banner" | "footer">, {
467
480
  format: NormalizedFormat[];
468
481
  target?: string[];
469
482
  clean: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsdown",
3
- "version": "0.14.2",
3
+ "version": "0.15.1",
4
4
  "description": "The Elegant Bundler for Libraries",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,9 +12,10 @@
12
12
  "type": "git",
13
13
  "url": "git+https://github.com/rolldown/tsdown.git"
14
14
  },
15
- "author": "三咲智子 Kevin Deng <sxzz@sxzz.moe>",
15
+ "author": "Kevin Deng <sxzz@sxzz.moe>",
16
16
  "funding": "https://github.com/sponsors/sxzz",
17
17
  "files": [
18
+ "client.d.ts",
18
19
  "dist",
19
20
  "esm-shims.js"
20
21
  ],
@@ -26,7 +27,8 @@
26
27
  "./config": "./dist/config.mjs",
27
28
  "./plugins": "./dist/plugins.mjs",
28
29
  "./run": "./dist/run.mjs",
29
- "./package.json": "./package.json"
30
+ "./package.json": "./package.json",
31
+ "./client": "./client.d.ts"
30
32
  },
31
33
  "typesVersions": {
32
34
  "*": {
@@ -75,10 +77,10 @@
75
77
  "empathic": "^2.0.0",
76
78
  "hookable": "^5.5.3",
77
79
  "rolldown": "latest",
78
- "rolldown-plugin-dts": "^0.15.8",
80
+ "rolldown-plugin-dts": "^0.16.5",
79
81
  "semver": "^7.7.2",
80
82
  "tinyexec": "^1.0.1",
81
- "tinyglobby": "^0.2.14",
83
+ "tinyglobby": "^0.2.15",
82
84
  "tree-kill": "^1.2.2",
83
85
  "unconfig": "^7.3.3"
84
86
  },
@@ -88,21 +90,21 @@
88
90
  "@sxzz/prettier-config": "^2.2.4",
89
91
  "@sxzz/test-utils": "^0.5.10",
90
92
  "@types/debug": "^4.1.12",
91
- "@types/node": "^24.3.0",
92
- "@types/semver": "^7.7.0",
93
- "@unocss/eslint-plugin": "^66.4.2",
94
- "@vueuse/core": "^13.7.0",
93
+ "@types/node": "^24.3.1",
94
+ "@types/semver": "^7.7.1",
95
+ "@unocss/eslint-plugin": "^66.5.1",
96
+ "@vueuse/core": "^13.9.0",
95
97
  "bumpp": "^10.2.3",
96
- "eslint": "^9.34.0",
98
+ "eslint": "^9.35.0",
97
99
  "lightningcss": "^1.30.1",
98
100
  "pkg-types": "^2.3.0",
99
101
  "prettier": "^3.6.2",
100
102
  "publint": "^0.3.12",
101
103
  "tsx": "^4.20.5",
102
104
  "typescript": "~5.9.2",
103
- "unocss": "^66.4.2",
105
+ "unocss": "^66.5.1",
104
106
  "unplugin-lightningcss": "^0.4.2",
105
- "unplugin-unused": "^0.5.2",
107
+ "unplugin-unused": "^0.5.3",
106
108
  "vite": "npm:rolldown-vite@latest",
107
109
  "vitest": "^3.2.4"
108
110
  },
@@ -1,5 +0,0 @@
1
- //#region package.json
2
- var version = "0.14.2";
3
-
4
- //#endregion
5
- export { version };