@savvy-web/tsdown-plugins 2.4.16 → 2.5.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.
@@ -57,7 +57,7 @@ async function buildTargetGroups(options) {
57
57
  logLevel: "silent",
58
58
  customLogger: createTsdownLogger(collector, groupId)
59
59
  };
60
- const metricsPlugins = (groupId, pass) => collector === void 0 ? [] : [buildMetricsPlugin(collector, groupId, pass, verbose)];
60
+ const metricsPlugins = (groupId, pass, suppressMixedExports = false) => collector === void 0 ? [] : [buildMetricsPlugin(collector, groupId, pass, verbose, suppressMixedExports)];
61
61
  const timingChecks = { checks: { pluginTimings: verbose } };
62
62
  const timed = async (groupId, pass, run) => {
63
63
  const timer = createTimer();
@@ -144,28 +144,24 @@ async function buildTargetGroups(options) {
144
144
  ...timingChecks,
145
145
  ...instrument(group.id),
146
146
  ...part.css !== void 0 ? { css: part.css } : {},
147
- ...partExternals?.length || partBundleNodeModules || partBundle?.length ? { deps: {
147
+ ...partExternals?.length || partBundle?.length ? { deps: {
148
148
  ...partExternals?.length ? { neverBundle: partExternals } : {},
149
- ...partBundle?.length ? { alwaysBundle: partBundle } : {},
150
- ...partBundleNodeModules ? { skipNodeModulesBundle: false } : {}
149
+ ...partBundle?.length ? { alwaysBundle: partBundle } : {}
151
150
  } } : {},
152
151
  ...js.cjsDefault !== void 0 ? { cjsDefault: js.cjsDefault } : {},
153
152
  plugins: [
154
153
  ...manifestPlugin ? [manifestPlugin] : [],
155
154
  ...js.format.includes("cjs") ? [nodeBuiltinDefaultInterop(), cjsDefaultInterop()] : [],
156
155
  ...options.extraPlugins ?? [],
157
- ...metricsPlugins(group.id, "js")
156
+ ...metricsPlugins(group.id, "js", js.format.includes("cjs"))
158
157
  ]
159
158
  }));
160
159
  const dtsNeverBundle = [...partExternals ?? [], ...partDtsExternals ?? []];
161
160
  if (options.emitDts === false || Object.keys(dts.entry).length === 0) continue;
162
- const dtsDeps = dtsNeverBundle.length > 0 || partBundleNodeModules || dts.bundledPackages ? { deps: {
161
+ const dtsDeps = dtsNeverBundle.length > 0 || dts.bundledPackages ? { deps: {
163
162
  ...dtsNeverBundle.length > 0 ? { neverBundle: dtsNeverBundle } : {},
164
- ...partBundleNodeModules ? {
165
- skipNodeModulesBundle: false,
166
- ...dts.bundledPackages ? { dts: { alwaysBundle: dts.bundledPackages } } : {}
167
- } : dts.bundledPackages ? {
168
- skipNodeModulesBundle: true,
163
+ ...dts.bundledPackages ? partBundleNodeModules ? { dts: { alwaysBundle: dts.bundledPackages } } : {
164
+ neverBundle: true,
169
165
  dts: { alwaysBundle: dts.bundledPackages }
170
166
  } : {}
171
167
  } } : {};
@@ -240,7 +236,7 @@ async function buildTargetGroups(options) {
240
236
  plugins: [
241
237
  ...dts.format.includes("cjs") ? [nodeBuiltinDefaultInterop(), cjsDefaultInterop()] : [],
242
238
  ...options.extraPlugins ?? [],
243
- ...metricsPlugins(group.id, "dts")
239
+ ...metricsPlugins(group.id, "dts", dts.format.includes("cjs"))
244
240
  ]
245
241
  });
246
242
  }
@@ -263,13 +259,10 @@ async function buildTargetGroups(options) {
263
259
  define: decl.define,
264
260
  ...timingChecks,
265
261
  logLevel: "silent",
266
- ...dtsNeverBundle.length > 0 || partBundleNodeModules || decl.bundledPackages ? { deps: {
262
+ ...dtsNeverBundle.length > 0 || decl.bundledPackages ? { deps: {
267
263
  ...dtsNeverBundle.length > 0 ? { neverBundle: dtsNeverBundle } : {},
268
- ...partBundleNodeModules ? {
269
- skipNodeModulesBundle: false,
270
- ...decl.bundledPackages ? { dts: { alwaysBundle: decl.bundledPackages } } : {}
271
- } : decl.bundledPackages ? {
272
- skipNodeModulesBundle: true,
264
+ ...decl.bundledPackages ? partBundleNodeModules ? { dts: { alwaysBundle: decl.bundledPackages } } : {
265
+ neverBundle: true,
273
266
  dts: { alwaysBundle: decl.bundledPackages }
274
267
  } : {}
275
268
  } } : {},
@@ -288,8 +281,7 @@ async function buildTargetGroups(options) {
288
281
  const isProdGroup = group.id !== "dev";
289
282
  const looseDeps = {
290
283
  ...options.externals?.length ? { neverBundle: options.externals } : {},
291
- ...options.bundle?.length ? { alwaysBundle: options.bundle } : {},
292
- ...options.bundleNodeModules ? { skipNodeModulesBundle: false } : {}
284
+ ...options.bundle?.length ? { alwaysBundle: options.bundle } : {}
293
285
  };
294
286
  for (const lf of options.looseFiles ?? []) {
295
287
  const hasCjs = lf.format === "cjs";
@@ -317,7 +309,7 @@ async function buildTargetGroups(options) {
317
309
  plugins: [
318
310
  ...hasCjs ? [nodeBuiltinDefaultInterop(), cjsDefaultInterop()] : [],
319
311
  ...options.extraPlugins ?? [],
320
- ...metricsPlugins(group.id, "loose")
312
+ ...metricsPlugins(group.id, "loose", hasCjs)
321
313
  ]
322
314
  }));
323
315
  }
package/index.d.ts CHANGED
@@ -177,7 +177,10 @@ declare const DiagnosticEntry_base: Schema.Class<DiagnosticEntry, Schema.Struct<
177
177
  readonly source: Schema.Literals<readonly ["tsdown", "rolldown", "api-extractor"]>;
178
178
  readonly level: Schema.Literals<readonly ["warn", "error"]>;
179
179
  readonly text: Schema.String;
180
- /** API Extractor messageId (e.g. "ae-forgotten-export"); used to group suppressed messages by type. */
180
+ /**
181
+ * Diagnostic identifier — an API Extractor messageId (e.g. "ae-forgotten-export") or a
182
+ * rolldown warning code (e.g. "MIXED_EXPORTS"); used to group suppressed messages by type.
183
+ */
181
184
  readonly code: Schema.optional<Schema.String>;
182
185
  /** True when shown as `warn` locally but a hard error in CI (drives the "[fails CI]" nudge). */
183
186
  readonly ciFatal: Schema.optional<Schema.Boolean>;
@@ -326,10 +329,11 @@ interface DeriveOptions {
326
329
  */
327
330
  readonly bundledPackages?: ReadonlyArray<string> | undefined;
328
331
  /**
329
- * Force-bundle node_modules (and workspace) JS dependencies into the JS pass (tsdown
330
- * `deps.skipNodeModulesBundle: false`). Consumed here ONLY to decide the JS pass's
331
- * `unbundle` posture — see {@link DerivedTsdownOptions.unbundle} — the `deps` shape
332
- * itself is computed separately in `buildTargetGroups`.
332
+ * Force-bundle node_modules (and workspace) JS dependencies into the JS pass.
333
+ * Consumed here ONLY to decide the JS pass's `unbundle` posture — see
334
+ * {@link DerivedTsdownOptions.unbundle} — which is the whole of its effect: tsdown
335
+ * already bundles anything the manifest does not declare as a production dependency,
336
+ * so no `deps` flag is needed to force it.
333
337
  */
334
338
  readonly bundleNodeModules?: boolean | undefined;
335
339
  }
@@ -544,7 +548,7 @@ interface BuildTargetGroupsOptions {
544
548
  /**
545
549
  * External packages whose declarations are inlined into the bundled dts
546
550
  * (rslib `dtsBundledPackages` equivalent). Forwarded to the dts pass as
547
- * `deps.dts.alwaysBundle` alongside `skipNodeModulesBundle: true`; unlike
551
+ * `deps.dts.alwaysBundle` alongside `deps.neverBundle: true`; unlike
548
552
  * `deps.onlyBundle` this does not enable tsdown's strict-mode check that
549
553
  * errors on every unlisted transitive dependency. The JS pass is unaffected.
550
554
  */
@@ -552,16 +556,17 @@ interface BuildTargetGroupsOptions {
552
556
  /**
553
557
  * Force-bundle node_modules (and workspace) JS dependencies that are not
554
558
  * externalized, restoring the rslib bundle-everything-except-externals
555
- * behavior. Sets tsdown `deps.skipNodeModulesBundle: false`; the dts pass
556
- * posture mirrors the JS pass, so the bundled declarations are also
559
+ * behavior. Acts through the JS pass's `unbundle: false` posture, NOT through a
560
+ * `deps` flag: bundling node_modules is already tsdown's default for anything the
561
+ * manifest does not declare as a production dependency. The dts pass mirrors it by
562
+ * likewise leaving that default in place, so the bundled declarations are also
557
563
  * self-contained. Defaults to false (current behavior).
558
564
  */
559
565
  readonly bundleNodeModules?: boolean | undefined;
560
566
  /**
561
567
  * Force-bundle (inline) these packages into the JS output (tsdown `deps.alwaysBundle`),
562
568
  * even declared deps that would otherwise be auto-externalized. The inverse of
563
- * `externals`. JS pass only; `alwaysBundle` is allowed alongside our
564
- * `skipNodeModulesBundle: false` (the throw only fires when skipNodeModulesBundle is true).
569
+ * `externals`. JS pass only.
565
570
  */
566
571
  readonly bundle?: ReadonlyArray<string> | undefined;
567
572
  /** Output formats to emit. Defaults to esm-only when unset. */
@@ -1738,9 +1743,13 @@ declare function writeIssuesArtifact(opts: {
1738
1743
  * defensive onLog for rolldown-level diagnostics that bypass tsdown's logger. Append it to each
1739
1744
  * build pass's `plugins` array. `bytes` is taken from the in-memory chunk/asset content (no fs);
1740
1745
  * `gzip` is computed only when `verbose`.
1746
+ *
1747
+ * Set `suppressMixedExports` for a pass whose emitted CJS carries the `cjsDefaultInterop()`
1748
+ * footer — see the onLog comment below for why rolldown's MIXED_EXPORTS advice does not apply
1749
+ * there.
1741
1750
  * @public
1742
1751
  */
1743
- declare function buildMetricsPlugin(collector: BuildCollector, groupId: string, pass: PassKind, verbose: boolean): Plugin;
1752
+ declare function buildMetricsPlugin(collector: BuildCollector, groupId: string, pass: PassKind, verbose: boolean, suppressMixedExports?: boolean): Plugin;
1744
1753
  //#endregion
1745
1754
  //#region src/report/services/EnvironmentDetector.d.ts
1746
1755
  /** @public */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/tsdown-plugins",
3
- "version": "2.4.16",
3
+ "version": "2.5.0",
4
4
  "private": false,
5
5
  "description": "Interface-only tsdown/rolldown plugin pack powering @savvy-web/bundler",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/tsdown-plugins",
@@ -34,7 +34,7 @@
34
34
  "@effected/npm": "^0.11.0",
35
35
  "@effected/package-json": "^0.10.2",
36
36
  "@effected/tsconfig-json": "^0.6.0",
37
- "@effected/workspaces": "^0.15.0",
37
+ "@effected/workspaces": "^0.15.1",
38
38
  "@microsoft/api-extractor": "^7.58.12",
39
39
  "@microsoft/tsdoc": "^0.16.0",
40
40
  "@microsoft/tsdoc-config": "^0.18.1",
@@ -16,9 +16,13 @@ function byteLength(content) {
16
16
  * defensive onLog for rolldown-level diagnostics that bypass tsdown's logger. Append it to each
17
17
  * build pass's `plugins` array. `bytes` is taken from the in-memory chunk/asset content (no fs);
18
18
  * `gzip` is computed only when `verbose`.
19
+ *
20
+ * Set `suppressMixedExports` for a pass whose emitted CJS carries the `cjsDefaultInterop()`
21
+ * footer — see the onLog comment below for why rolldown's MIXED_EXPORTS advice does not apply
22
+ * there.
19
23
  * @public
20
24
  */
21
- function buildMetricsPlugin(collector, groupId, pass, verbose) {
25
+ function buildMetricsPlugin(collector, groupId, pass, verbose, suppressMixedExports = false) {
22
26
  return {
23
27
  name: "savvy:build-metrics",
24
28
  writeBundle(_outputOptions, bundle) {
@@ -42,6 +46,15 @@ function buildMetricsPlugin(collector, groupId, pass, verbose) {
42
46
  ...l.loc?.line !== void 0 ? { line: l.loc.line } : {},
43
47
  ...l.loc?.column !== void 0 ? { column: l.loc.column } : {}
44
48
  };
49
+ if (suppressMixedExports && l.code === "MIXED_EXPORTS") {
50
+ collector.recordSuppressed(groupId, {
51
+ source: "rolldown",
52
+ level: "warn",
53
+ code: "MIXED_EXPORTS",
54
+ ...entry
55
+ });
56
+ return false;
57
+ }
45
58
  if (level === "error") {
46
59
  collector.recordError(groupId, {
47
60
  source: "rolldown",
package/report/schema.js CHANGED
@@ -16,7 +16,10 @@ var DiagnosticEntry = class extends Schema.Class("DiagnosticEntry")({
16
16
  ]),
17
17
  level: Schema.Literals(["warn", "error"]),
18
18
  text: Schema.String,
19
- /** API Extractor messageId (e.g. "ae-forgotten-export"); used to group suppressed messages by type. */
19
+ /**
20
+ * Diagnostic identifier — an API Extractor messageId (e.g. "ae-forgotten-export") or a
21
+ * rolldown warning code (e.g. "MIXED_EXPORTS"); used to group suppressed messages by type.
22
+ */
20
23
  code: Schema.optional(Schema.String),
21
24
  /** True when shown as `warn` locally but a hard error in CI (drives the "[fails CI]" nudge). */
22
25
  ciFatal: Schema.optional(Schema.Boolean),
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.58.12"
8
+ "packageVersion": "7.58.13"
9
9
  }
10
10
  ]
11
11
  }