tsdown 0.15.12 → 0.16.0

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.
@@ -0,0 +1,13 @@
1
+ import { d as UserConfig, f as UserConfigExport, p as UserConfigFn } from "./index-CSOY_TcZ.mjs";
2
+
3
+ //#region src/config.d.ts
4
+
5
+ /**
6
+ * Defines the configuration for tsdown.
7
+ */
8
+ declare function defineConfig(options: UserConfig): UserConfig;
9
+ declare function defineConfig(options: UserConfig[]): UserConfig[];
10
+ declare function defineConfig(options: UserConfigFn): UserConfigFn;
11
+ declare function defineConfig(options: UserConfigExport): UserConfigExport;
12
+ //#endregion
13
+ export { defineConfig as t };
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { f as UserConfig, p as UserConfigFn } from "./types-XjcKkhrO.mjs";
2
- import { t as defineConfig } from "./config-Bl5kiN1A.mjs";
3
- export { UserConfig, UserConfigFn, defineConfig };
1
+ import { d as UserConfig, f as UserConfigExport, p as UserConfigFn } from "./index-CSOY_TcZ.mjs";
2
+ import { t as defineConfig } from "./config-8JTxhwDL.mjs";
3
+ export { UserConfig, UserConfigExport, UserConfigFn, defineConfig };
@@ -1,11 +1,12 @@
1
1
  import "ansis";
2
2
  import { BuildOptions, ExternalOption, InputOption, InputOptions, InternalModuleFormat, MinifyOptions, ModuleFormat, ModuleTypes, OutputAsset, OutputChunk, OutputOptions, Plugin, TreeshakingOptions } from "rolldown";
3
3
  import { Hookable } from "hookable";
4
+ import { Options as DtsOptions } from "rolldown-plugin-dts";
4
5
  import { CheckPackageOptions } from "@arethetypeswrong/core";
6
+ import { StartOptions } from "@vitejs/devtools/cli-commands";
7
+ import { PackageJson } from "pkg-types";
5
8
  import { Options as PublintOptions } from "publint";
6
- import { Options as DtsOptions } from "rolldown-plugin-dts";
7
9
  import { Options as UnusedOptions } from "unplugin-unused";
8
- import { PackageJson } from "pkg-types";
9
10
 
10
11
  //#region src/utils/types.d.ts
11
12
  type Overwrite<T, U> = Omit<T, keyof U> & U;
@@ -45,7 +46,23 @@ interface CopyEntry {
45
46
  to: string;
46
47
  }
47
48
  type CopyOptions = Arrayable<string | CopyEntry>;
48
- type CopyOptionsFn = (options: ResolvedOptions) => Awaitable<CopyOptions>;
49
+ type CopyOptionsFn = (options: ResolvedConfig) => Awaitable<CopyOptions>;
50
+ //#endregion
51
+ //#region src/features/debug.d.ts
52
+ interface DebugOptions extends NonNullable<InputOptions["debug"]> {
53
+ /**
54
+ * **[experimental]** Enable devtools integration. `@vitejs/devtools` must be installed as a dependency.
55
+ *
56
+ * Defaults to true, if `@vitejs/devtools` is installed.
57
+ */
58
+ devtools?: boolean | Partial<StartOptions>;
59
+ /**
60
+ * Clean devtools stale sessions.
61
+ *
62
+ * @default true
63
+ */
64
+ clean?: boolean;
65
+ }
49
66
  //#endregion
50
67
  //#region src/features/exports.d.ts
51
68
  type TsdownChunks = Partial<Record<NormalizedFormat, Array<OutputChunk | OutputAsset>>>;
@@ -70,7 +87,7 @@ interface ExportsOptions {
70
87
  //#endregion
71
88
  //#region src/features/hooks.d.ts
72
89
  interface BuildContext {
73
- options: ResolvedOptions;
90
+ options: ResolvedConfig;
74
91
  hooks: Hookable<TsdownHooks>;
75
92
  }
76
93
  interface RolldownContext {
@@ -161,7 +178,7 @@ interface ReportOptions {
161
178
  }
162
179
  declare function ReportPlugin(userOptions: ReportOptions, logger: Logger, cwd: string, cjsDts?: boolean, name?: string, isMultiFormat?: boolean): Plugin;
163
180
  //#endregion
164
- //#region src/options/types.d.ts
181
+ //#region src/config/types.d.ts
165
182
  type Sourcemap = boolean | "inline" | "hidden";
166
183
  type Format = ModuleFormat;
167
184
  type NormalizedFormat = InternalModuleFormat;
@@ -186,7 +203,7 @@ type NoExternalFn = (id: string, importer: string | undefined) => boolean | null
186
203
  /**
187
204
  * Options for tsdown.
188
205
  */
189
- interface Options {
206
+ interface UserConfig {
190
207
  /**
191
208
  * Defaults to `'src/index.ts'` if it exists.
192
209
  */
@@ -356,7 +373,8 @@ interface Options {
356
373
  * Use a fixed extension for output files.
357
374
  * The extension will always be `.cjs` or `.mjs`.
358
375
  * Otherwise, it will depend on the package type.
359
- * @default false
376
+ *
377
+ * Defaults to `true` if `platform` is set to `node`, `false` otherwise.
360
378
  */
361
379
  fixedExtension?: boolean;
362
380
  /**
@@ -411,15 +429,6 @@ interface Options {
411
429
  */
412
430
  customLogger?: Logger;
413
431
  /**
414
- * Config file path
415
- */
416
- config?: boolean | string;
417
- /**
418
- * Config loader to use. It can only be set via CLI or API.
419
- * @default 'auto'
420
- */
421
- configLoader?: "auto" | "native" | "unconfig" | "unrun";
422
- /**
423
432
  * Reuse config from Vite or Vitest (experimental)
424
433
  * @default false
425
434
  */
@@ -432,7 +441,17 @@ interface Options {
432
441
  /**
433
442
  * You can specify command to be executed after a successful build, specially useful for Watch mode
434
443
  */
435
- onSuccess?: string | ((config: ResolvedOptions, signal: AbortSignal) => void | Promise<void>);
444
+ onSuccess?: string | ((config: ResolvedConfig, signal: AbortSignal) => void | Promise<void>);
445
+ /**
446
+ * **[experimental]** Enable debug mode.
447
+ *
448
+ * Both debug mode and Vite DevTools are still under development, and this is for early testers only.
449
+ *
450
+ * This may slow down the build process significantly.
451
+ *
452
+ * @default false
453
+ */
454
+ debug?: boolean | DebugOptions;
436
455
  /**
437
456
  * Enables generation of TypeScript declaration files (`.d.ts`).
438
457
  *
@@ -500,24 +519,31 @@ interface Options {
500
519
  * This allows you to build multiple packages in a monorepo.
501
520
  */
502
521
  workspace?: Workspace | Arrayable<string> | true;
522
+ }
523
+ interface InlineConfig extends UserConfig {
524
+ /**
525
+ * Config file path
526
+ */
527
+ config?: boolean | string;
528
+ /**
529
+ * Config loader to use. It can only be set via CLI or API.
530
+ * @default 'auto'
531
+ */
532
+ configLoader?: "auto" | "native" | "unconfig" | "unrun";
503
533
  /**
504
534
  * Filter workspace packages. This option is only available in workspace mode.
505
535
  */
506
536
  filter?: RegExp | string | string[];
507
537
  }
508
- /**
509
- * Options without specifying config file path.
510
- */
511
- type UserConfig = Arrayable<Omit<Options, "config" | "filter" | "configLoader">>;
512
- type UserConfigFn = (cliOptions: Options) => Awaitable<UserConfig>;
513
- type NormalizedUserConfig = Exclude<UserConfig, any[]>;
514
- type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "workspace" | "filter" | "silent" | "logLevel" | "failOnWarn" | "customLogger" | "configLoader">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "onSuccess" | "fixedExtension" | "outExtensions" | "hooks" | "removeNodeProtocol" | "copy" | "loader" | "name" | "bundle" | "banner" | "footer">, {
538
+ type UserConfigFn = (inlineConfig: InlineConfig) => Awaitable<Arrayable<UserConfig>>;
539
+ type UserConfigExport = Awaitable<Arrayable<UserConfig> | UserConfigFn>;
540
+ type ResolvedConfig = Overwrite<MarkPartial<Omit<UserConfig, "workspace" | "fromVite" | "publicDir" | "silent" | "bundle" | "removeNodeProtocol" | "logLevel" | "failOnWarn" | "customLogger">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "onSuccess" | "outExtensions" | "hooks" | "copy" | "loader" | "name" | "banner" | "footer">, {
515
541
  format: NormalizedFormat[];
516
542
  target?: string[];
517
543
  clean: string[];
518
544
  dts: false | DtsOptions;
519
545
  report: false | ReportOptions;
520
- tsconfig: string | false;
546
+ tsconfig: false | string;
521
547
  pkg?: PackageJson;
522
548
  exports: false | ExportsOptions;
523
549
  nodeProtocol: "strip" | boolean;
@@ -525,6 +551,7 @@ type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "w
525
551
  ignoreWatch: Array<string | RegExp>;
526
552
  noExternal?: NoExternalFn;
527
553
  inlineOnly?: Array<string | RegExp>;
528
- }>, "config" | "fromVite">;
554
+ debug: false | DebugOptions;
555
+ }>;
529
556
  //#endregion
530
- export { TsdownChunks as A, OutExtensionFactory as C, RolldownContext as D, BuildContext as E, CopyOptions as M, CopyOptionsFn as N, TsdownHooks as O, AttwOptions as P, OutExtensionContext as S, PackageType as T, Logger as _, NormalizedUserConfig as a, ChunkAddonFunction as b, ResolvedOptions as c, UnusedOptions as d, UserConfig as f, ReportPlugin as g, ReportOptions as h, NormalizedFormat as i, CopyEntry as j, ExportsOptions as k, Sourcemap as l, Workspace as m, Format as n, Options as o, UserConfigFn as p, NoExternalFn as r, PublintOptions as s, DtsOptions as t, TreeshakingOptions as u, globalLogger as v, OutExtensionObject as w, ChunkAddonObject as x, ChunkAddon as y };
557
+ export { TsdownChunks as A, OutExtensionFactory as C, RolldownContext as D, BuildContext as E, AttwOptions as F, CopyEntry as M, CopyOptions as N, TsdownHooks as O, CopyOptionsFn as P, OutExtensionContext as S, PackageType as T, Logger as _, NormalizedFormat as a, ChunkAddonFunction as b, Sourcemap as c, UserConfig as d, UserConfigExport as f, ReportPlugin as g, ReportOptions as h, NoExternalFn as i, DebugOptions as j, ExportsOptions as k, TreeshakingOptions as l, Workspace as m, Format as n, PublintOptions as o, UserConfigFn as p, InlineConfig as r, ResolvedConfig as s, DtsOptions as t, UnusedOptions as u, globalLogger as v, OutExtensionObject as w, ChunkAddonObject as x, ChunkAddon as y };
package/dist/index.d.mts CHANGED
@@ -1,12 +1,12 @@
1
- import { A as TsdownChunks, C as OutExtensionFactory, D as RolldownContext, E as BuildContext, M as CopyOptions, N as CopyOptionsFn, O as TsdownHooks, P as AttwOptions, S as OutExtensionContext, T as PackageType, _ as Logger, a as NormalizedUserConfig, b as ChunkAddonFunction, c as ResolvedOptions, d as UnusedOptions, f as UserConfig, h as ReportOptions, i as NormalizedFormat, j as CopyEntry, k as ExportsOptions, l as Sourcemap, m as Workspace, n as Format, o as Options, p as UserConfigFn, r as NoExternalFn, s as PublintOptions, t as DtsOptions, u as TreeshakingOptions, v as globalLogger, w as OutExtensionObject, x as ChunkAddonObject, y as ChunkAddon } from "./types-XjcKkhrO.mjs";
2
- import { t as defineConfig } from "./config-Bl5kiN1A.mjs";
1
+ import { A as TsdownChunks, C as OutExtensionFactory, D as RolldownContext, E as BuildContext, F as AttwOptions, M as CopyEntry, N as CopyOptions, O as TsdownHooks, P as CopyOptionsFn, S as OutExtensionContext, T as PackageType, _ as Logger, a as NormalizedFormat, b as ChunkAddonFunction, c as Sourcemap, d as UserConfig, f as UserConfigExport, h as ReportOptions, i as NoExternalFn, j as DebugOptions, k as ExportsOptions, l as TreeshakingOptions, m as Workspace, n as Format, o as PublintOptions, p as UserConfigFn, r as InlineConfig, s as ResolvedConfig, t as DtsOptions, u as UnusedOptions, v as globalLogger, w as OutExtensionObject, x as ChunkAddonObject, y as ChunkAddon } from "./index-CSOY_TcZ.mjs";
2
+ import { t as defineConfig } from "./config-8JTxhwDL.mjs";
3
3
 
4
4
  //#region src/index.d.ts
5
5
 
6
6
  /**
7
7
  * Build with tsdown.
8
8
  */
9
- declare function build(userOptions?: Options): Promise<void>;
9
+ declare function build(userOptions?: InlineConfig): Promise<void>;
10
10
  /** @internal */
11
11
  declare const shimFile: string;
12
12
  /**
@@ -17,6 +17,6 @@ declare const shimFile: string;
17
17
  * @private
18
18
  * @param config Resolved options
19
19
  */
20
- declare function buildSingle(config: ResolvedOptions, clean: () => Promise<void>): Promise<(() => Promise<void>) | undefined>;
20
+ declare function buildSingle(config: ResolvedConfig, clean: () => Promise<void>): Promise<(() => Promise<void>) | undefined>;
21
21
  //#endregion
22
- export { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, type Logger, NoExternalFn, NormalizedFormat, NormalizedUserConfig, type Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, type ResolvedOptions, RolldownContext, Sourcemap, TreeshakingOptions, TsdownChunks, TsdownHooks, UnusedOptions, type UserConfig, type UserConfigFn, Workspace, build, buildSingle, defineConfig, globalLogger, shimFile };
22
+ export { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DebugOptions, DtsOptions, ExportsOptions, Format, InlineConfig, type Logger, NoExternalFn, NormalizedFormat, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, ResolvedConfig, RolldownContext, Sourcemap, TreeshakingOptions, TsdownChunks, TsdownHooks, UnusedOptions, UserConfig, UserConfigExport, UserConfigFn, Workspace, build, buildSingle, defineConfig, globalLogger, shimFile };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as defineConfig } from "./config-BPLXnzPK.mjs";
2
- import { n as buildSingle, r as shimFile, t as build } from "./src-Cy1Bj4rU.mjs";
3
- import { a as globalLogger } from "./package-qYegZAPv.mjs";
2
+ import { n as buildSingle, r as shimFile, t as build } from "./src-B9FIpS_R.mjs";
3
+ import { a as globalLogger } from "./package-CTfVaX9t.mjs";
4
4
 
5
5
  export { build, buildSingle, defineConfig, globalLogger, shimFile };
@@ -1,4 +1,4 @@
1
- import { a as globalLogger, t as version } from "./package-qYegZAPv.mjs";
1
+ import { a as globalLogger, t as version } from "./package-CTfVaX9t.mjs";
2
2
  import process from "node:process";
3
3
  import { bold, green, underline } from "ansis";
4
4
  import { readFile, unlink, writeFile } from "node:fs/promises";
@@ -38,6 +38,22 @@ function matchPattern(id, patterns) {
38
38
  return id === pattern;
39
39
  });
40
40
  }
41
+ function pkgExists(moduleName) {
42
+ try {
43
+ import.meta.resolve(moduleName);
44
+ return true;
45
+ } catch {}
46
+ return false;
47
+ }
48
+ async function importWithError(moduleName) {
49
+ try {
50
+ return await import(moduleName);
51
+ } catch (error) {
52
+ const final = /* @__PURE__ */ new Error(`Failed to import module "${moduleName}". Please ensure it is installed.`);
53
+ final.cause = error;
54
+ throw final;
55
+ }
56
+ }
41
57
 
42
58
  //#endregion
43
59
  //#region src/utils/logger.ts
@@ -146,7 +162,7 @@ function hue2rgb(p, q, t) {
146
162
 
147
163
  //#endregion
148
164
  //#region package.json
149
- var version = "0.15.12";
165
+ var version = "0.16.0";
150
166
 
151
167
  //#endregion
152
- export { globalLogger as a, debounce as c, resolveComma as d, resolveRegex as f, generateColor as i, matchPattern as l, toArray as m, LogLevels as n, prettyFormat as o, slash as p, createLogger as r, prettyName as s, version as t, noop as u };
168
+ export { globalLogger as a, debounce as c, noop as d, pkgExists as f, toArray as g, slash as h, generateColor as i, importWithError as l, resolveRegex as m, LogLevels as n, prettyFormat as o, resolveComma as p, createLogger as r, prettyName as s, version as t, matchPattern as u };
@@ -1,4 +1,4 @@
1
- import { _ as Logger, c as ResolvedOptions, g as ReportPlugin } from "./types-XjcKkhrO.mjs";
1
+ import { _ as Logger, g as ReportPlugin, s as ResolvedConfig } from "./index-CSOY_TcZ.mjs";
2
2
  import { Plugin } from "rolldown";
3
3
  import { PackageJson } from "pkg-types";
4
4
 
@@ -8,7 +8,7 @@ declare function ExternalPlugin({
8
8
  noExternal,
9
9
  inlineOnly,
10
10
  skipNodeModulesBundle
11
- }: ResolvedOptions): Plugin;
11
+ }: ResolvedConfig): Plugin;
12
12
  //#endregion
13
13
  //#region src/features/shebang.d.ts
14
14
  declare function ShebangPlugin(logger: Logger, cwd: string, name?: string, isMultiFormat?: boolean): Plugin;
package/dist/plugins.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./config-BPLXnzPK.mjs";
2
- import { a as ReportPlugin, i as ShebangPlugin, o as NodeProtocolPlugin, s as ExternalPlugin } from "./src-Cy1Bj4rU.mjs";
3
- import "./package-qYegZAPv.mjs";
2
+ import { a as ReportPlugin, i as ShebangPlugin, o as NodeProtocolPlugin, s as ExternalPlugin } from "./src-B9FIpS_R.mjs";
3
+ import "./package-CTfVaX9t.mjs";
4
4
 
5
5
  export { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin };
package/dist/run.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cjs_createRequire } from "node:module";
3
3
  const __cjs_require = __cjs_createRequire(import.meta.url);
4
- import { a as globalLogger, d as resolveComma, m as toArray, t as version } from "./package-qYegZAPv.mjs";
4
+ import { a as globalLogger, g as toArray, p as resolveComma, t as version } from "./package-CTfVaX9t.mjs";
5
5
  import module from "node:module";
6
6
  import process from "node:process";
7
7
  import { dim } from "ansis";
@@ -9,13 +9,28 @@ import { VERSION } from "rolldown";
9
9
  const Debug = __cjs_require("debug");
10
10
  import { cac } from "cac";
11
11
 
12
+ //#region src/features/debug.ts
13
+ const debug = Debug("tsdown:debug");
14
+ function enableDebugLog(cliOptions) {
15
+ const { debugLogs } = cliOptions;
16
+ if (!debugLogs) return;
17
+ let namespace;
18
+ if (debugLogs === true) namespace = "tsdown:*";
19
+ else namespace = resolveComma(toArray(debugLogs)).map((v) => `tsdown:${v}`).join(",");
20
+ const enabled = Debug.disable();
21
+ if (enabled) namespace += `,${enabled}`;
22
+ Debug.enable(namespace);
23
+ debug("Debugging enabled", namespace);
24
+ }
25
+
26
+ //#endregion
12
27
  //#region src/cli.ts
13
28
  const cli = cac("tsdown");
14
29
  cli.help().version(version);
15
30
  cli.command("[...files]", "Bundle files", {
16
31
  ignoreOptionDefaultValue: true,
17
32
  allowUnknownOptions: true
18
- }).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) => {
33
+ }).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", "Enable debug mode").option("--debug-logs [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) => {
19
34
  globalLogger.level = flags.logLevel || (flags.silent ? "error" : "info");
20
35
  globalLogger.info(`tsdown ${dim`v${version}`} powered by rolldown ${dim`v${VERSION}`}`);
21
36
  const { build: build$1 } = await import("./index.mjs");
@@ -23,20 +38,12 @@ cli.command("[...files]", "Bundle files", {
23
38
  await build$1(flags);
24
39
  });
25
40
  cli.command("migrate", "Migrate from tsup to tsdown").option("-c, --cwd <dir>", "Working directory").option("-d, --dry-run", "Dry run").action(async (args) => {
26
- const { migrate } = await import("./migrate-GNvnRFv2.mjs");
41
+ const { migrate } = await import("./migrate-C8f4tEcE.mjs");
27
42
  await migrate(args);
28
43
  });
29
44
  async function runCLI() {
30
45
  cli.parse(process.argv, { run: false });
31
- if (cli.options.debug) {
32
- let namespace;
33
- if (cli.options.debug === true) namespace = "tsdown:*";
34
- else namespace = resolveComma(toArray(cli.options.debug)).map((v) => `tsdown:${v}`).join(",");
35
- const enabled = Debug.disable();
36
- if (enabled) namespace += `,${enabled}`;
37
- Debug.enable(namespace);
38
- Debug("tsdown:debug")("Debugging enabled", namespace);
39
- }
46
+ enableDebugLog(cli.options);
40
47
  try {
41
48
  await cli.runMatchedCommand();
42
49
  } catch (error) {
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __cjs_createRequire } from "node:module";
2
2
  const __cjs_require = __cjs_createRequire(import.meta.url);
3
- import { a as globalLogger, c as debounce, d as resolveComma, f as resolveRegex, i as generateColor, l as matchPattern, m as toArray, n as LogLevels, o as prettyFormat, p as slash, r as createLogger, s as prettyName, t as version, u as noop } from "./package-qYegZAPv.mjs";
3
+ import { a as globalLogger, c as debounce, d as noop, f as pkgExists, g as toArray, h as slash, i as generateColor, l as importWithError, m as resolveRegex, n as LogLevels, o as prettyFormat, p as resolveComma, r as createLogger, s as prettyName, t as version, u as matchPattern } from "./package-CTfVaX9t.mjs";
4
4
  import { builtinModules, isBuiltin } from "node:module";
5
5
  import path, { dirname, join, normalize, sep } from "node:path";
6
6
  import process from "node:process";
@@ -9,21 +9,21 @@ import { blue, bold, dim, green, underline } from "ansis";
9
9
  import { VERSION, build } from "rolldown";
10
10
  import { exec } from "tinyexec";
11
11
  const treeKill = __cjs_require("tree-kill");
12
- import child_process from "node:child_process";
13
- import { access, chmod, cp, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
14
- import { tmpdir } from "node:os";
15
- import util, { promisify } from "node:util";
16
12
  const Debug = __cjs_require("debug");
17
- const coerce = __cjs_require("semver/functions/coerce.js");
18
- const satisfies = __cjs_require("semver/functions/satisfies.js");
19
13
  import { glob } from "tinyglobby";
14
+ import { access, chmod, cp, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
20
15
  import { RE_CSS, RE_DTS, RE_JS, RE_NODE_MODULES } from "rolldown-plugin-dts/filename";
21
- import { createHooks } from "hookable";
22
- import { importGlobPlugin } from "rolldown/experimental";
23
16
  const minVersion = __cjs_require("semver/ranges/min-version.js");
24
17
  import { up } from "empathic/find";
25
18
  import { up as up$1 } from "empathic/package";
26
19
  import { loadConfig } from "unconfig";
20
+ import child_process from "node:child_process";
21
+ import { tmpdir } from "node:os";
22
+ import util, { promisify } from "node:util";
23
+ const coerce = __cjs_require("semver/functions/coerce.js");
24
+ const satisfies = __cjs_require("semver/functions/satisfies.js");
25
+ import { createHooks } from "hookable";
26
+ import { importGlobPlugin } from "rolldown/experimental";
27
27
  import { Buffer } from "node:buffer";
28
28
  import { brotliCompress, gzip } from "node:zlib";
29
29
  import readline from "node:readline";
@@ -67,115 +67,14 @@ function lowestCommonAncestor(...filepaths) {
67
67
  return ancestor.length <= 1 && ancestor[0] === "" ? sep + ancestor[0] : ancestor.join(sep);
68
68
  }
69
69
 
70
- //#endregion
71
- //#region src/features/attw.ts
72
- const debug$7 = Debug("tsdown:attw");
73
- const exec$1 = promisify(child_process.exec);
74
- /**
75
- * ATTW profiles.
76
- * Defines the resolution modes to ignore for each profile.
77
- *
78
- * @see https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/packages/cli/README.md#profiles
79
- */
80
- const profiles = {
81
- strict: [],
82
- node16: ["node10"],
83
- esmOnly: ["node10", "node16-cjs"]
84
- };
85
- /**
86
- * Format an ATTW problem for display
87
- */
88
- function formatProblem(problem) {
89
- const resolutionKind = "resolutionKind" in problem ? ` (${problem.resolutionKind})` : "";
90
- const entrypoint = "entrypoint" in problem ? ` at ${problem.entrypoint}` : "";
91
- switch (problem.kind) {
92
- case "NoResolution": return ` ❌ No resolution${resolutionKind}${entrypoint}`;
93
- case "UntypedResolution": return ` ⚠️ Untyped resolution${resolutionKind}${entrypoint}`;
94
- case "FalseESM": return ` 🔄 False ESM: Types indicate ESM (${problem.typesModuleKind}) but implementation is CJS (${problem.implementationModuleKind})\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
95
- case "FalseCJS": return ` 🔄 False CJS: Types indicate CJS (${problem.typesModuleKind}) but implementation is ESM (${problem.implementationModuleKind})\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
96
- case "CJSResolvesToESM": return ` ⚡ CJS resolves to ESM${resolutionKind}${entrypoint}`;
97
- case "NamedExports": {
98
- const missingExports = problem.missing?.length > 0 ? ` Missing: ${problem.missing.join(", ")}` : "";
99
- return ` 📤 Named exports problem${problem.isMissingAllNamed ? " (all named exports missing)" : ""}${missingExports}\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
100
- }
101
- case "FallbackCondition": return ` 🎯 Fallback condition used${resolutionKind}${entrypoint}`;
102
- case "FalseExportDefault": return ` 🎭 False export default\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
103
- case "MissingExportEquals": return ` 📝 Missing export equals\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
104
- case "InternalResolutionError": return ` 💥 Internal resolution error in ${problem.fileName} (${problem.resolutionOption})\n Module: ${problem.moduleSpecifier} | Mode: ${problem.resolutionMode}`;
105
- case "UnexpectedModuleSyntax": return ` 📋 Unexpected module syntax in ${problem.fileName}\n Expected: ${problem.moduleKind} | Found: ${problem.syntax === 99 ? "ESM" : "CJS"}`;
106
- case "CJSOnlyExportsDefault": return ` 🏷️ CJS only exports default in ${problem.fileName}`;
107
- default: return ` ❓ Unknown problem: ${JSON.stringify(problem)}`;
108
- }
109
- }
110
- async function attw(options) {
111
- if (!options.attw) return;
112
- if (!options.pkg) {
113
- options.logger.warn("attw is enabled but package.json is not found");
114
- return;
115
- }
116
- const { profile = "strict", level = "warn",...attwOptions } = options.attw === true ? {} : options.attw;
117
- const t = performance.now();
118
- debug$7("Running attw check");
119
- const tempDir = await mkdtemp(path.join(tmpdir(), "tsdown-attw-"));
120
- let attwCore;
121
- try {
122
- attwCore = await import("@arethetypeswrong/core");
123
- } catch {
124
- options.logger.error(`ATTW check requires ${blue`@arethetypeswrong/core`} to be installed.`);
125
- return;
126
- }
127
- try {
128
- const { stdout: tarballInfo } = await exec$1(`npm pack --json ----pack-destination ${tempDir}`, {
129
- encoding: "utf8",
130
- cwd: options.cwd
131
- });
132
- const parsed = JSON.parse(tarballInfo);
133
- if (!Array.isArray(parsed) || !parsed[0]?.filename) throw new Error("Invalid npm pack output format");
134
- const tarball = await readFile(path.join(tempDir, parsed[0].filename));
135
- const pkg = attwCore.createPackageFromTarballData(tarball);
136
- const checkResult = await attwCore.checkPackage(pkg, attwOptions);
137
- if (checkResult.types !== false && checkResult.problems.length) {
138
- const problems = checkResult.problems.filter((problem) => {
139
- if ("resolutionKind" in problem) return !profiles[profile]?.includes(problem.resolutionKind);
140
- return true;
141
- });
142
- if (problems.length) {
143
- const problemMessage = `Are the types wrong problems found:\n${problems.map(formatProblem).join("\n")}`;
144
- if (level === "error") throw new Error(problemMessage);
145
- options.logger.warn(problemMessage);
146
- }
147
- } else options.logger.success(`No Are the types wrong problems found`, dim`(${Math.round(performance.now() - t)}ms)`);
148
- } catch (error) {
149
- options.logger.error("ATTW check failed:", error);
150
- debug$7("Found errors, setting exit code to 1");
151
- process.exitCode = 1;
152
- } finally {
153
- await fsRemove(tempDir);
154
- }
155
- }
156
-
157
- //#endregion
158
- //#region src/features/cjs.ts
159
- /**
160
- * If the config includes the `cjs` format and
161
- * one of its target >= node 23.0.0 / 22.12.0,
162
- * warn the user about the deprecation of CommonJS.
163
- */
164
- function warnLegacyCJS(config) {
165
- if (!config.format.includes("cjs") || !config.target) return;
166
- if (config.target.some((t) => {
167
- const version$1 = coerce(t.split("node")[1]);
168
- return version$1 && satisfies(version$1, ">=23.0.0 || >=22.12.0");
169
- })) 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");
170
- }
171
-
172
70
  //#endregion
173
71
  //#region src/features/clean.ts
174
- const debug$6 = Debug("tsdown:clean");
72
+ const debug$7 = Debug("tsdown:clean");
175
73
  const RE_LAST_SLASH = /[/\\]$/;
176
74
  async function cleanOutDir(configs) {
177
75
  const removes = /* @__PURE__ */ new Set();
178
76
  for (const config of configs) {
77
+ if (config.debug && (config.debug.clean ?? true)) config.clean.push(".rolldown");
179
78
  if (!config.clean.length) continue;
180
79
  const files = await glob(config.clean, {
181
80
  cwd: config.cwd,
@@ -188,10 +87,10 @@ async function cleanOutDir(configs) {
188
87
  if (!removes.size) return;
189
88
  globalLogger.info(`Cleaning ${removes.size} files`);
190
89
  await Promise.all([...removes].map(async (file) => {
191
- debug$6("Removing", file);
90
+ debug$7("Removing", file);
192
91
  await fsRemove(file);
193
92
  }));
194
- debug$6("Removed %d files", removes.size);
93
+ debug$7("Removed %d files", removes.size);
195
94
  }
196
95
  function resolveClean(clean, outDir, cwd) {
197
96
  if (clean === true) clean = [slash(outDir)];
@@ -201,18 +100,32 @@ function resolveClean(clean, outDir, cwd) {
201
100
  }
202
101
 
203
102
  //#endregion
204
- //#region src/features/copy.ts
205
- async function copy(options) {
206
- if (!options.copy) return;
207
- const copy$1 = typeof options.copy === "function" ? await options.copy(options) : options.copy;
208
- await Promise.all(toArray(copy$1).map((dir) => {
209
- const from = typeof dir === "string" ? dir : dir.from;
210
- const to = typeof dir === "string" ? path.resolve(options.outDir, path.basename(from)) : dir.to;
211
- return cp$1(options.cwd, from, to);
212
- }));
103
+ //#region src/features/entry.ts
104
+ async function resolveEntry(logger, entry, cwd, name) {
105
+ const nameLabel = name ? `[${name}] ` : "";
106
+ if (!entry || Object.keys(entry).length === 0) {
107
+ const defaultEntry = path.resolve(cwd, "src/index.ts");
108
+ if (await fsExists(defaultEntry)) entry = { index: defaultEntry };
109
+ else throw new Error(`${nameLabel}No input files, try "tsdown <your-file>" or create src/index.ts`);
110
+ }
111
+ const entryMap = await toObjectEntry(entry, cwd);
112
+ const entries = Object.values(entryMap);
113
+ if (entries.length === 0) throw new Error(`${nameLabel}Cannot find entry: ${JSON.stringify(entry)}`);
114
+ logger.info(prettyName(name), `entry: ${generateColor(name)(entries.map((entry$1) => path.relative(cwd, entry$1)).join(", "))}`);
115
+ return entryMap;
213
116
  }
214
- function cp$1(cwd, from, to) {
215
- return fsCopy(path.resolve(cwd, from), path.resolve(cwd, to));
117
+ async function toObjectEntry(entry, cwd) {
118
+ if (typeof entry === "string") entry = [entry];
119
+ if (!Array.isArray(entry)) return entry;
120
+ const resolvedEntry = (await glob(entry, {
121
+ cwd,
122
+ expandDirectories: false
123
+ })).map((file) => path.resolve(cwd, file));
124
+ const base = lowestCommonAncestor(...resolvedEntry);
125
+ return Object.fromEntries(resolvedEntry.map((file) => {
126
+ const relative = path.relative(base, file);
127
+ return [relative.slice(0, relative.length - path.extname(relative).length), file];
128
+ }));
216
129
  }
217
130
 
218
131
  //#endregion
@@ -334,86 +247,6 @@ function hasExportsTypes(pkg) {
334
247
  return false;
335
248
  }
336
249
 
337
- //#endregion
338
- //#region src/features/hooks.ts
339
- async function createHooks$1(options) {
340
- const hooks = createHooks();
341
- if (typeof options.hooks === "object") hooks.addHooks(options.hooks);
342
- else if (typeof options.hooks === "function") await options.hooks(hooks);
343
- return {
344
- hooks,
345
- context: {
346
- options,
347
- hooks
348
- }
349
- };
350
- }
351
-
352
- //#endregion
353
- //#region src/features/publint.ts
354
- const debug$5 = Debug("tsdown:publint");
355
- async function publint(options) {
356
- if (!options.publint) return;
357
- if (!options.pkg) {
358
- options.logger.warn(prettyName(options.name), "publint is enabled but package.json is not found");
359
- return;
360
- }
361
- const t = performance.now();
362
- debug$5("Running publint");
363
- const { publint: publint$1 } = await import("publint");
364
- const { formatMessage } = await import("publint/utils");
365
- const { messages } = await publint$1({
366
- ...options.publint === true ? {} : options.publint,
367
- pkgDir: path.dirname(options.pkg.packageJsonPath)
368
- });
369
- debug$5("Found %d issues", messages.length);
370
- if (!messages.length) options.logger.success(prettyName(options.name), `No publint issues found`, dim`(${Math.round(performance.now() - t)}ms)`);
371
- let hasError = false;
372
- for (const message of messages) {
373
- hasError ||= message.type === "error";
374
- const formattedMessage = formatMessage(message, options.pkg);
375
- const logType = {
376
- error: "error",
377
- warning: "warn",
378
- suggestion: "info"
379
- }[message.type];
380
- options.logger[logType](prettyName(options.name), formattedMessage);
381
- }
382
- if (hasError) {
383
- debug$5("Found errors, setting exit code to 1");
384
- process.exitCode = 1;
385
- }
386
- }
387
-
388
- //#endregion
389
- //#region src/features/entry.ts
390
- async function resolveEntry(logger, entry, cwd, name) {
391
- const nameLabel = name ? `[${name}] ` : "";
392
- if (!entry || Object.keys(entry).length === 0) {
393
- const defaultEntry = path.resolve(cwd, "src/index.ts");
394
- if (await fsExists(defaultEntry)) entry = { index: defaultEntry };
395
- else throw new Error(`${nameLabel}No input files, try "tsdown <your-file>" or create src/index.ts`);
396
- }
397
- const entryMap = await toObjectEntry(entry, cwd);
398
- const entries = Object.values(entryMap);
399
- if (entries.length === 0) throw new Error(`${nameLabel}Cannot find entry: ${JSON.stringify(entry)}`);
400
- logger.info(prettyName(name), `entry: ${generateColor(name)(entries.map((entry$1) => path.relative(cwd, entry$1)).join(", "))}`);
401
- return entryMap;
402
- }
403
- async function toObjectEntry(entry, cwd) {
404
- if (typeof entry === "string") entry = [entry];
405
- if (!Array.isArray(entry)) return entry;
406
- const resolvedEntry = (await glob(entry, {
407
- cwd,
408
- expandDirectories: false
409
- })).map((file) => path.resolve(cwd, file));
410
- const base = lowestCommonAncestor(...resolvedEntry);
411
- return Object.fromEntries(resolvedEntry.map((file) => {
412
- const relative = path.relative(base, file);
413
- return [relative.slice(0, relative.length - path.extname(relative).length), file];
414
- }));
415
- }
416
-
417
250
  //#endregion
418
251
  //#region src/features/target.ts
419
252
  function resolveTarget(logger, target, pkg, name) {
@@ -467,11 +300,11 @@ async function resolveTsconfig(logger, tsconfig, cwd, name) {
467
300
 
468
301
  //#endregion
469
302
  //#region src/utils/package.ts
470
- const debug$4 = Debug("tsdown:package");
303
+ const debug$6 = Debug("tsdown:package");
471
304
  async function readPackageJson(dir) {
472
305
  const packageJsonPath = up$1({ cwd: dir });
473
306
  if (!packageJsonPath) return;
474
- debug$4("Reading package.json:", packageJsonPath);
307
+ debug$6("Reading package.json:", packageJsonPath);
475
308
  const contents = await readFile(packageJsonPath, "utf8");
476
309
  return {
477
310
  ...JSON.parse(contents),
@@ -498,7 +331,7 @@ function normalizeFormat(format) {
498
331
  }
499
332
 
500
333
  //#endregion
501
- //#region src/options/config.ts
334
+ //#region src/config/config.ts
502
335
  async function loadViteConfig(prefix, cwd) {
503
336
  const { config, sources: [source] } = await loadConfig({
504
337
  sources: [{
@@ -527,10 +360,10 @@ async function loadViteConfig(prefix, cwd) {
527
360
  return resolved;
528
361
  }
529
362
  let loaded = false;
530
- async function loadConfigFile(options, workspace) {
531
- let cwd = options.cwd || process.cwd();
363
+ async function loadConfigFile(inlineConfig, workspace) {
364
+ let cwd = inlineConfig.cwd || process.cwd();
532
365
  let overrideConfig = false;
533
- let { config: filePath } = options;
366
+ let { config: filePath } = inlineConfig;
534
367
  if (filePath === false) return { configs: [{}] };
535
368
  if (typeof filePath === "string") {
536
369
  const stats = await fsStat(filePath);
@@ -545,8 +378,8 @@ async function loadConfigFile(options, workspace) {
545
378
  }
546
379
  let isNative = false;
547
380
  if (!loaded) {
548
- if (!options.configLoader || options.configLoader === "auto") isNative = !!(process.features.typescript || process.versions.bun || process.versions.deno);
549
- else if (options.configLoader === "native") isNative = true;
381
+ if (!inlineConfig.configLoader || inlineConfig.configLoader === "auto") isNative = !!(process.features.typescript || process.versions.bun || process.versions.deno);
382
+ else if (inlineConfig.configLoader === "native") isNative = true;
550
383
  }
551
384
  let { config, sources } = await loadConfig.async({
552
385
  sources: overrideConfig ? [{
@@ -564,7 +397,7 @@ async function loadConfigFile(options, workspace) {
564
397
  "json",
565
398
  ""
566
399
  ],
567
- parser: options.configLoader === "unrun" ? unrunImport : isNative ? nativeImport : "auto"
400
+ parser: inlineConfig.configLoader === "unrun" ? unrunImport : isNative ? nativeImport : "auto"
568
401
  }, {
569
402
  files: "package.json",
570
403
  extensions: [],
@@ -574,7 +407,8 @@ async function loadConfigFile(options, workspace) {
574
407
  stopAt: workspace && path.dirname(workspace),
575
408
  defaults: {}
576
409
  }).finally(() => loaded = true);
577
- if (typeof config === "function") config = await config(options);
410
+ config = await config;
411
+ if (typeof config === "function") config = await config(inlineConfig);
578
412
  config = toArray(config);
579
413
  if (config.length === 0) config.push({});
580
414
  const file = sources[0];
@@ -595,7 +429,7 @@ async function nativeImport(id) {
595
429
  return mod.default || mod;
596
430
  }
597
431
  async function unrunImport(id) {
598
- const { unrun } = await import("unrun");
432
+ const { unrun } = await importWithError("unrun");
599
433
  const { module: module$1 } = await unrun({ path: pathToFileURL(id).href }).catch((error) => {
600
434
  if (error?.message?.includes?.("Cannot find module")) {
601
435
  const configError = /* @__PURE__ */ new Error(`Failed to load the config file. \`unrun\` is experimental; try setting the --config-loader CLI flag to \`unconfig\` instead.\n\n${error.message}`);
@@ -607,38 +441,38 @@ async function unrunImport(id) {
607
441
  }
608
442
 
609
443
  //#endregion
610
- //#region src/options/index.ts
611
- const debug$3 = Debug("tsdown:options");
444
+ //#region src/config/index.ts
445
+ const debug$5 = Debug("tsdown:options");
612
446
  const DEFAULT_EXCLUDE_WORKSPACE = [
613
447
  "**/node_modules/**",
614
448
  "**/dist/**",
615
449
  "**/test?(s)/**",
616
450
  "**/t?(e)mp/**"
617
451
  ];
618
- async function resolveOptions(options) {
619
- debug$3("options %O", options);
620
- const { configs: rootConfigs, file } = await loadConfigFile(options);
452
+ async function resolveConfig(inlineConfig) {
453
+ debug$5("inline config %O", inlineConfig);
454
+ const { configs: rootConfigs, file } = await loadConfigFile(inlineConfig);
621
455
  const files = [];
622
456
  if (file) {
623
457
  files.push(file);
624
- debug$3("loaded root config file %s", file);
625
- debug$3("root configs %O", rootConfigs);
626
- } else debug$3("no root config file found");
458
+ debug$5("loaded root user config file %s", file);
459
+ debug$5("root user configs %O", rootConfigs);
460
+ } else debug$5("no root user config file found");
627
461
  const configs = (await Promise.all(rootConfigs.map(async (rootConfig) => {
628
- const { configs: workspaceConfigs, files: workspaceFiles } = await resolveWorkspace(rootConfig, options);
462
+ const { configs: workspaceConfigs, files: workspaceFiles } = await resolveWorkspace(rootConfig, inlineConfig);
629
463
  if (workspaceFiles) files.push(...workspaceFiles);
630
- return Promise.all(workspaceConfigs.filter((config) => !config.workspace || config.entry).map((config) => resolveConfig(config)));
464
+ return Promise.all(workspaceConfigs.filter((config) => !config.workspace || config.entry).map((config) => resolveUserConfig(config)));
631
465
  }))).flat();
632
- debug$3("resolved configs %O", configs);
466
+ debug$5("resolved configs %O", configs);
633
467
  return {
634
468
  configs,
635
469
  files
636
470
  };
637
471
  }
638
- async function resolveWorkspace(config, options) {
472
+ async function resolveWorkspace(config, inlineConfig) {
639
473
  const normalized = {
640
474
  ...config,
641
- ...options
475
+ ...inlineConfig
642
476
  };
643
477
  const rootCwd = normalized.cwd || process.cwd();
644
478
  let { workspace } = normalized;
@@ -662,26 +496,26 @@ async function resolveWorkspace(config, options) {
662
496
  expandDirectories: false
663
497
  })).map((file) => slash(path.resolve(file)));
664
498
  if (packages.length === 0) throw new Error("No workspace packages found, please check your config");
665
- if (options.filter) {
666
- options.filter = resolveRegex(options.filter);
499
+ if (inlineConfig.filter) {
500
+ inlineConfig.filter = resolveRegex(inlineConfig.filter);
667
501
  packages = packages.filter((path$1) => {
668
- return typeof options.filter === "string" ? path$1.includes(options.filter) : Array.isArray(options.filter) ? options.filter.some((filter) => path$1.includes(filter)) : options.filter.test(path$1);
502
+ return typeof inlineConfig.filter === "string" ? path$1.includes(inlineConfig.filter) : Array.isArray(inlineConfig.filter) ? inlineConfig.filter.some((filter) => path$1.includes(filter)) : inlineConfig.filter.test(path$1);
669
503
  });
670
504
  if (packages.length === 0) throw new Error("No packages matched the filters");
671
505
  }
672
506
  const files = [];
673
507
  return {
674
508
  configs: (await Promise.all(packages.map(async (cwd) => {
675
- debug$3("loading workspace config %s", cwd);
509
+ debug$5("loading workspace config %s", cwd);
676
510
  const { configs, file } = await loadConfigFile({
677
- ...options,
511
+ ...inlineConfig,
678
512
  config: workspaceConfig,
679
513
  cwd
680
514
  }, cwd);
681
515
  if (file) {
682
- debug$3("loaded workspace config file %s", file);
516
+ debug$5("loaded workspace config file %s", file);
683
517
  files.push(file);
684
- } else debug$3("no workspace config file found in %s", cwd);
518
+ } else debug$5("no workspace config file found in %s", cwd);
685
519
  return configs.map((config$1) => ({
686
520
  ...normalized,
687
521
  cwd,
@@ -691,8 +525,8 @@ async function resolveWorkspace(config, options) {
691
525
  files
692
526
  };
693
527
  }
694
- async function resolveConfig(userConfig) {
695
- let { entry, format = ["es"], plugins = [], clean = true, silent = false, logLevel = silent ? "silent" : "info", failOnWarn = false, customLogger, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts, unused = false, watch = false, ignoreWatch, shims = false, skipNodeModulesBundle = false, publint: publint$1 = false, attw: attw$1 = false, fromVite, alias, tsconfig, report = true, target, env = {}, copy: copy$1, publicDir, hash, cwd = process.cwd(), name, workspace, external, noExternal, exports = false, bundle, unbundle = typeof bundle === "boolean" ? !bundle : false, removeNodeProtocol, nodeProtocol, cjsDefault = true, globImport = true, inlineOnly } = userConfig;
528
+ async function resolveUserConfig(userConfig) {
529
+ let { entry, format = ["es"], plugins = [], clean = true, silent = false, logLevel = silent ? "silent" : "info", failOnWarn = false, customLogger, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts, unused = false, watch = false, ignoreWatch, shims = false, skipNodeModulesBundle = false, publint: publint$1 = false, attw: attw$1 = false, fromVite, alias, tsconfig, report = true, target, env = {}, copy: copy$1, publicDir, hash, cwd = process.cwd(), name, workspace, external, noExternal, exports = false, bundle, unbundle = typeof bundle === "boolean" ? !bundle : false, removeNodeProtocol, nodeProtocol, cjsDefault = true, globImport = true, inlineOnly, fixedExtension = platform === "node", debug: debug$8 = false } = userConfig;
696
530
  const logger = createLogger(logLevel, {
697
531
  customLogger,
698
532
  failOnWarn
@@ -737,6 +571,10 @@ async function resolveConfig(userConfig) {
737
571
  noExternal = (id) => matchPattern(id, noExternalPatterns);
738
572
  }
739
573
  if (inlineOnly != null) inlineOnly = toArray(inlineOnly);
574
+ if (debug$8) {
575
+ if (debug$8 === true) debug$8 = {};
576
+ debug$8.devtools ??= !!pkgExists("@vitejs/devtools/cli");
577
+ }
740
578
  return {
741
579
  ...userConfig,
742
580
  entry,
@@ -773,7 +611,9 @@ async function resolveConfig(userConfig) {
773
611
  nodeProtocol,
774
612
  cjsDefault,
775
613
  globImport,
776
- inlineOnly
614
+ inlineOnly,
615
+ fixedExtension,
616
+ debug: debug$8
777
617
  };
778
618
  }
779
619
  async function mergeUserOptions(defaults, user, args) {
@@ -784,6 +624,174 @@ async function mergeUserOptions(defaults, user, args) {
784
624
  };
785
625
  }
786
626
 
627
+ //#endregion
628
+ //#region src/features/attw.ts
629
+ const debug$4 = Debug("tsdown:attw");
630
+ const exec$1 = promisify(child_process.exec);
631
+ /**
632
+ * ATTW profiles.
633
+ * Defines the resolution modes to ignore for each profile.
634
+ *
635
+ * @see https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/packages/cli/README.md#profiles
636
+ */
637
+ const profiles = {
638
+ strict: [],
639
+ node16: ["node10"],
640
+ esmOnly: ["node10", "node16-cjs"]
641
+ };
642
+ /**
643
+ * Format an ATTW problem for display
644
+ */
645
+ function formatProblem(problem) {
646
+ const resolutionKind = "resolutionKind" in problem ? ` (${problem.resolutionKind})` : "";
647
+ const entrypoint = "entrypoint" in problem ? ` at ${problem.entrypoint}` : "";
648
+ switch (problem.kind) {
649
+ case "NoResolution": return ` ❌ No resolution${resolutionKind}${entrypoint}`;
650
+ case "UntypedResolution": return ` ⚠️ Untyped resolution${resolutionKind}${entrypoint}`;
651
+ case "FalseESM": return ` 🔄 False ESM: Types indicate ESM (${problem.typesModuleKind}) but implementation is CJS (${problem.implementationModuleKind})\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
652
+ case "FalseCJS": return ` 🔄 False CJS: Types indicate CJS (${problem.typesModuleKind}) but implementation is ESM (${problem.implementationModuleKind})\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
653
+ case "CJSResolvesToESM": return ` ⚡ CJS resolves to ESM${resolutionKind}${entrypoint}`;
654
+ case "NamedExports": {
655
+ const missingExports = problem.missing?.length > 0 ? ` Missing: ${problem.missing.join(", ")}` : "";
656
+ return ` 📤 Named exports problem${problem.isMissingAllNamed ? " (all named exports missing)" : ""}${missingExports}\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
657
+ }
658
+ case "FallbackCondition": return ` 🎯 Fallback condition used${resolutionKind}${entrypoint}`;
659
+ case "FalseExportDefault": return ` 🎭 False export default\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
660
+ case "MissingExportEquals": return ` 📝 Missing export equals\n Types: ${problem.typesFileName} | Implementation: ${problem.implementationFileName}`;
661
+ case "InternalResolutionError": return ` 💥 Internal resolution error in ${problem.fileName} (${problem.resolutionOption})\n Module: ${problem.moduleSpecifier} | Mode: ${problem.resolutionMode}`;
662
+ case "UnexpectedModuleSyntax": return ` 📋 Unexpected module syntax in ${problem.fileName}\n Expected: ${problem.moduleKind} | Found: ${problem.syntax === 99 ? "ESM" : "CJS"}`;
663
+ case "CJSOnlyExportsDefault": return ` 🏷️ CJS only exports default in ${problem.fileName}`;
664
+ default: return ` ❓ Unknown problem: ${JSON.stringify(problem)}`;
665
+ }
666
+ }
667
+ async function attw(options) {
668
+ if (!options.attw) return;
669
+ if (!options.pkg) {
670
+ options.logger.warn("attw is enabled but package.json is not found");
671
+ return;
672
+ }
673
+ const { profile = "strict", level = "warn",...attwOptions } = options.attw === true ? {} : options.attw;
674
+ const t = performance.now();
675
+ debug$4("Running attw check");
676
+ const tempDir = await mkdtemp(path.join(tmpdir(), "tsdown-attw-"));
677
+ let attwCore;
678
+ try {
679
+ attwCore = await importWithError("@arethetypeswrong/core");
680
+ } catch {
681
+ options.logger.error(`ATTW check requires ${blue`@arethetypeswrong/core`} to be installed.`);
682
+ return;
683
+ }
684
+ try {
685
+ const { stdout: tarballInfo } = await exec$1(`npm pack --json ----pack-destination ${tempDir}`, {
686
+ encoding: "utf8",
687
+ cwd: options.cwd
688
+ });
689
+ const parsed = JSON.parse(tarballInfo);
690
+ if (!Array.isArray(parsed) || !parsed[0]?.filename) throw new Error("Invalid npm pack output format");
691
+ const tarball = await readFile(path.join(tempDir, parsed[0].filename));
692
+ const pkg = attwCore.createPackageFromTarballData(tarball);
693
+ const checkResult = await attwCore.checkPackage(pkg, attwOptions);
694
+ if (checkResult.types !== false && checkResult.problems.length) {
695
+ const problems = checkResult.problems.filter((problem) => {
696
+ if ("resolutionKind" in problem) return !profiles[profile]?.includes(problem.resolutionKind);
697
+ return true;
698
+ });
699
+ if (problems.length) {
700
+ const problemMessage = `Are the types wrong problems found:\n${problems.map(formatProblem).join("\n")}`;
701
+ if (level === "error") throw new Error(problemMessage);
702
+ options.logger.warn(problemMessage);
703
+ }
704
+ } else options.logger.success(`No Are the types wrong problems found`, dim`(${Math.round(performance.now() - t)}ms)`);
705
+ } catch (error) {
706
+ options.logger.error("ATTW check failed:", error);
707
+ debug$4("Found errors, setting exit code to 1");
708
+ process.exitCode = 1;
709
+ } finally {
710
+ await fsRemove(tempDir);
711
+ }
712
+ }
713
+
714
+ //#endregion
715
+ //#region src/features/cjs.ts
716
+ /**
717
+ * If the config includes the `cjs` format and
718
+ * one of its target >= node 23.0.0 / 22.12.0,
719
+ * warn the user about the deprecation of CommonJS.
720
+ */
721
+ function warnLegacyCJS(config) {
722
+ if (!config.format.includes("cjs") || !config.target) return;
723
+ if (config.target.some((t) => {
724
+ const version$1 = coerce(t.split("node")[1]);
725
+ return version$1 && satisfies(version$1, ">=23.0.0 || >=22.12.0");
726
+ })) 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");
727
+ }
728
+
729
+ //#endregion
730
+ //#region src/features/copy.ts
731
+ async function copy(options) {
732
+ if (!options.copy) return;
733
+ const copy$1 = typeof options.copy === "function" ? await options.copy(options) : options.copy;
734
+ await Promise.all(toArray(copy$1).map((dir) => {
735
+ const from = typeof dir === "string" ? dir : dir.from;
736
+ const to = typeof dir === "string" ? path.resolve(options.outDir, path.basename(from)) : dir.to;
737
+ return cp$1(options.cwd, from, to);
738
+ }));
739
+ }
740
+ function cp$1(cwd, from, to) {
741
+ return fsCopy(path.resolve(cwd, from), path.resolve(cwd, to));
742
+ }
743
+
744
+ //#endregion
745
+ //#region src/features/hooks.ts
746
+ async function createHooks$1(options) {
747
+ const hooks = createHooks();
748
+ if (typeof options.hooks === "object") hooks.addHooks(options.hooks);
749
+ else if (typeof options.hooks === "function") await options.hooks(hooks);
750
+ return {
751
+ hooks,
752
+ context: {
753
+ options,
754
+ hooks
755
+ }
756
+ };
757
+ }
758
+
759
+ //#endregion
760
+ //#region src/features/publint.ts
761
+ const debug$3 = Debug("tsdown:publint");
762
+ async function publint(options) {
763
+ if (!options.publint) return;
764
+ if (!options.pkg) {
765
+ options.logger.warn(prettyName(options.name), "publint is enabled but package.json is not found");
766
+ return;
767
+ }
768
+ const t = performance.now();
769
+ debug$3("Running publint");
770
+ const { publint: publint$1 } = await importWithError("publint");
771
+ const { formatMessage } = await import("publint/utils");
772
+ const { messages } = await publint$1({
773
+ ...options.publint === true ? {} : options.publint,
774
+ pkgDir: path.dirname(options.pkg.packageJsonPath)
775
+ });
776
+ debug$3("Found %d issues", messages.length);
777
+ if (!messages.length) options.logger.success(prettyName(options.name), `No publint issues found`, dim`(${Math.round(performance.now() - t)}ms)`);
778
+ let hasError = false;
779
+ for (const message of messages) {
780
+ hasError ||= message.type === "error";
781
+ const formattedMessage = formatMessage(message, options.pkg);
782
+ const logType = {
783
+ error: "error",
784
+ warning: "warn",
785
+ suggestion: "info"
786
+ }[message.type];
787
+ options.logger[logType](prettyName(options.name), formattedMessage);
788
+ }
789
+ if (hasError) {
790
+ debug$3("Found errors, setting exit code to 1");
791
+ process.exitCode = 1;
792
+ }
793
+ }
794
+
787
795
  //#endregion
788
796
  //#region src/features/external.ts
789
797
  const debug$2 = Debug("tsdown:external");
@@ -1104,7 +1112,7 @@ async function getBuildOptions(config, format, isMultiFormat, cjsDts = false) {
1104
1112
  return rolldownConfig;
1105
1113
  }
1106
1114
  async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1107
- const { entry, external, plugins: userPlugins, platform, alias, treeshake, dts, unused, target, shims, tsconfig, cwd, report, env, nodeProtocol, loader, name, logger, cjsDefault, banner, footer, globImport } = config;
1115
+ const { entry, external, plugins: userPlugins, platform, alias, treeshake, dts, unused, target, shims, tsconfig, cwd, report, env, nodeProtocol, loader, name, logger, cjsDefault, banner, footer, globImport, debug: debug$8 } = config;
1108
1116
  const plugins = [];
1109
1117
  if (nodeProtocol) plugins.push(NodeProtocolPlugin(nodeProtocol));
1110
1118
  if (config.pkg || config.skipNodeModulesBundle) plugins.push(ExternalPlugin(config));
@@ -1125,7 +1133,7 @@ async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1125
1133
  }
1126
1134
  if (!cjsDts) {
1127
1135
  if (unused) {
1128
- const { Unused } = await import("unplugin-unused");
1136
+ const { Unused } = await importWithError("unplugin-unused");
1129
1137
  plugins.push(Unused.rolldown(unused === true ? {} : unused));
1130
1138
  }
1131
1139
  if (target) plugins.push(await LightningCSSPlugin({ target }));
@@ -1163,7 +1171,8 @@ async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1163
1171
  onLog: cjsDefault ? (level, log, defaultHandler) => {
1164
1172
  if (log.code === "MIXED_EXPORT") return;
1165
1173
  defaultHandler(level, log);
1166
- } : void 0
1174
+ } : void 0,
1175
+ debug: debug$8 || void 0
1167
1176
  }, config.inputOptions, [format, { cjsDts }]);
1168
1177
  }
1169
1178
  async function resolveOutputOptions(inputOptions, config, format, cjsDts) {
@@ -1319,7 +1328,7 @@ async function watchBuild(options, configFiles, rebuild, restart) {
1319
1328
  */
1320
1329
  async function build$1(userOptions = {}) {
1321
1330
  globalLogger.level = userOptions.logLevel || (userOptions.silent ? "error" : "info");
1322
- const { configs, files: configFiles } = await resolveOptions(userOptions);
1331
+ const { configs, files: configFiles } = await resolveConfig(userOptions);
1323
1332
  let cleanPromise;
1324
1333
  const clean = () => {
1325
1334
  if (cleanPromise) return cleanPromise;
@@ -1334,6 +1343,20 @@ async function build$1(userOptions = {}) {
1334
1343
  const watcher = await watchBuild(config, configFiles, rebuild, restart);
1335
1344
  disposeCbs.push(() => watcher.close());
1336
1345
  }
1346
+ let firstDevtoolsConfig = configs.find((config) => config.debug && config.debug.devtools);
1347
+ if (disposeCbs.length && firstDevtoolsConfig) {
1348
+ globalLogger.warn("Devtools is not supported in watch mode, disabling it.");
1349
+ firstDevtoolsConfig = void 0;
1350
+ }
1351
+ if (firstDevtoolsConfig) {
1352
+ const { start } = await importWithError("@vitejs/devtools/cli-commands");
1353
+ const devtoolsOptions = firstDevtoolsConfig.debug.devtools;
1354
+ await start({
1355
+ host: "127.0.0.1",
1356
+ open: true,
1357
+ ...typeof devtoolsOptions === "object" ? devtoolsOptions : {}
1358
+ });
1359
+ }
1337
1360
  if (disposeCbs.length) disposeCbs.push(shortcuts(restart));
1338
1361
  async function restart() {
1339
1362
  for (const dispose of disposeCbs) await dispose();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsdown",
3
- "version": "0.15.12",
3
+ "version": "0.16.0",
4
4
  "description": "The Elegant Bundler for Libraries",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,6 +46,7 @@
46
46
  },
47
47
  "peerDependencies": {
48
48
  "@arethetypeswrong/core": "^0.18.1",
49
+ "@vitejs/devtools": "^0.0.0-alpha.10",
49
50
  "publint": "^0.3.0",
50
51
  "typescript": "^5.0.0",
51
52
  "unplugin-lightningcss": "^0.4.0",
@@ -56,6 +57,9 @@
56
57
  "@arethetypeswrong/core": {
57
58
  "optional": true
58
59
  },
60
+ "@vitejs/devtools": {
61
+ "optional": true
62
+ },
59
63
  "publint": {
60
64
  "optional": true
61
65
  },
@@ -80,8 +84,8 @@
80
84
  "diff": "^8.0.2",
81
85
  "empathic": "^2.0.0",
82
86
  "hookable": "^5.5.3",
83
- "rolldown": "1.0.0-beta.45",
84
- "rolldown-plugin-dts": "^0.17.2",
87
+ "rolldown": "1.0.0-beta.46",
88
+ "rolldown-plugin-dts": "^0.17.3",
85
89
  "semver": "^7.7.3",
86
90
  "tinyexec": "^1.0.1",
87
91
  "tinyglobby": "^0.2.15",
@@ -90,16 +94,17 @@
90
94
  },
91
95
  "devDependencies": {
92
96
  "@arethetypeswrong/core": "^0.18.2",
93
- "@sxzz/eslint-config": "^7.2.7",
97
+ "@sxzz/eslint-config": "^7.2.8",
94
98
  "@sxzz/prettier-config": "^2.2.4",
95
99
  "@sxzz/test-utils": "^0.5.12",
96
100
  "@types/debug": "^4.1.12",
97
- "@types/node": "^24.9.2",
101
+ "@types/node": "^24.10.0",
98
102
  "@types/semver": "^7.7.1",
99
103
  "@unocss/eslint-plugin": "^66.5.4",
104
+ "@vitejs/devtools": "^0.0.0-alpha.10",
100
105
  "@vueuse/core": "^14.0.0",
101
106
  "bumpp": "^10.3.1",
102
- "eslint": "^9.38.0",
107
+ "eslint": "^9.39.1",
103
108
  "lightningcss": "^1.30.2",
104
109
  "pkg-types": "^2.3.0",
105
110
  "prettier": "^3.6.2",
@@ -108,10 +113,10 @@
108
113
  "typescript": "~5.9.3",
109
114
  "unocss": "^66.5.4",
110
115
  "unplugin-lightningcss": "^0.4.3",
111
- "unplugin-unused": "^0.5.4",
112
- "unrun": "^0.2.1",
116
+ "unplugin-unused": "^0.5.5",
117
+ "unrun": "^0.2.2",
113
118
  "vite": "npm:rolldown-vite@latest",
114
- "vitest": "^4.0.4"
119
+ "vitest": "^4.0.6"
115
120
  },
116
121
  "engines": {
117
122
  "node": ">=20.19.0"
@@ -1,11 +0,0 @@
1
- import { f as UserConfig, p as UserConfigFn } from "./types-XjcKkhrO.mjs";
2
-
3
- //#region src/config.d.ts
4
-
5
- /**
6
- * Defines the configuration for tsdown.
7
- */
8
- declare function defineConfig(options: UserConfig): UserConfig;
9
- declare function defineConfig(options: UserConfigFn): UserConfigFn;
10
- //#endregion
11
- export { defineConfig as t };