@savvy-web/tsdown-plugins 0.11.2 → 0.12.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.
- package/build/build-target-groups.js +97 -32
- package/build/strip-maps.js +1 -1
- package/build/sync-public.js +1 -1
- package/config-validation/ConfigValidatorLive.js +1 -1
- package/dts/reexport-stub.js +92 -0
- package/dts/resolved-tsconfig.js +30 -3
- package/entry/package-json-entries.js +1 -1
- package/exe/build.js +1 -1
- package/index.d.ts +98 -18
- package/index.js +3 -2
- package/jsx/config.js +1 -1
- package/meta/generate.js +1 -1
- package/meta/tsconfig-resolver.js +1 -1
- package/meta/tsdoc-config.js +1 -1
- package/package.json +1 -1
- package/report/issues-artifact.js +1 -1
- package/targets/binding.js +1 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { analyzeReexportBarrel, collectExportNames, renderReexportStub } from "../dts/reexport-stub.js";
|
|
2
|
+
import { writeDtsEmitTsconfig } from "../dts/resolved-tsconfig.js";
|
|
1
3
|
import { emitManifest } from "../manifest/emit-manifest.js";
|
|
2
4
|
import { buildMetricsPlugin } from "../report/metrics-plugin.js";
|
|
3
5
|
import { createTimer } from "../report/timer.js";
|
|
@@ -6,10 +8,17 @@ import { cjsDefaultInterop } from "./cjs-default-interop.js";
|
|
|
6
8
|
import { nodeBuiltinDefaultInterop } from "./node-builtin-default-interop.js";
|
|
7
9
|
import { syncPublicDir } from "./sync-public.js";
|
|
8
10
|
import { deriveDeclarationsPassOptions, deriveDtsPassOptions, deriveTargetGroupOptions, outDirFor } from "./target-groups.js";
|
|
9
|
-
import {
|
|
11
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
10
13
|
|
|
11
14
|
//#region src/build/build-target-groups.ts
|
|
12
15
|
/**
|
|
16
|
+
* Entry name of the conventional primary (".") export, which `createEntryName` maps to "index". It is
|
|
17
|
+
* the re-export-stub base: a secondary entry that re-exports a subset of it gets a thin stub pointing
|
|
18
|
+
* here instead of a self-contained rollup.
|
|
19
|
+
*/
|
|
20
|
+
const STUB_BASE_ENTRY = "index";
|
|
21
|
+
/**
|
|
13
22
|
* Run tsdown.build() per TargetGroup. Composable so the escape hatch gets multi-group too.
|
|
14
23
|
*
|
|
15
24
|
* Each group runs TWO passes to the SAME outDir:
|
|
@@ -28,6 +37,7 @@ import { dirname, join } from "node:path";
|
|
|
28
37
|
async function buildTargetGroups(options) {
|
|
29
38
|
const build = options.build ?? (await import("tsdown")).build;
|
|
30
39
|
const publicDir = join(options.cwd, "public");
|
|
40
|
+
const dtsEmitTsconfigPath = writeDtsEmitTsconfig(options.tsconfigPath);
|
|
31
41
|
const collector = options.collector;
|
|
32
42
|
const verbose = options.verbose ?? false;
|
|
33
43
|
const instrument = (groupId) => collector === void 0 ? {} : {
|
|
@@ -68,7 +78,7 @@ async function buildTargetGroups(options) {
|
|
|
68
78
|
cwd: options.cwd,
|
|
69
79
|
version: options.version,
|
|
70
80
|
entry: part.entry,
|
|
71
|
-
tsconfigPath:
|
|
81
|
+
tsconfigPath: dtsEmitTsconfigPath,
|
|
72
82
|
devManifest: options.devManifest,
|
|
73
83
|
...partExternals !== void 0 ? { externals: partExternals } : {},
|
|
74
84
|
...partBundledPackages !== void 0 ? { bundledPackages: partBundledPackages } : {},
|
|
@@ -133,36 +143,91 @@ async function buildTargetGroups(options) {
|
|
|
133
143
|
if (isBase) syncPublicDir(publicDir, join(js.outDir, "public"));
|
|
134
144
|
const dtsNeverBundle = [...partExternals ?? [], ...partDtsExternals ?? []];
|
|
135
145
|
if (Object.keys(dts.entry).length === 0) continue;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
146
|
+
const dtsDeps = dtsNeverBundle.length > 0 || partBundleNodeModules || dts.bundledPackages ? { deps: {
|
|
147
|
+
...dtsNeverBundle.length > 0 ? { neverBundle: dtsNeverBundle } : {},
|
|
148
|
+
...partBundleNodeModules ? {
|
|
149
|
+
skipNodeModulesBundle: false,
|
|
150
|
+
...dts.bundledPackages ? { dts: { alwaysBundle: dts.bundledPackages } } : {}
|
|
151
|
+
} : dts.bundledPackages ? {
|
|
152
|
+
skipNodeModulesBundle: true,
|
|
153
|
+
dts: { alwaysBundle: dts.bundledPackages }
|
|
154
|
+
} : {}
|
|
155
|
+
} } : {};
|
|
156
|
+
const stubEntries = /* @__PURE__ */ new Map();
|
|
157
|
+
const readSource = (src) => {
|
|
158
|
+
try {
|
|
159
|
+
return readFileSync(isAbsolute(src) ? src : join(options.cwd, src), "utf-8");
|
|
160
|
+
} catch {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const baseSrc = dts.entry[STUB_BASE_ENTRY];
|
|
165
|
+
if (baseSrc !== void 0 && Object.keys(dts.entry).length > 1) {
|
|
166
|
+
const baseSource = readSource(baseSrc);
|
|
167
|
+
const base = baseSource !== void 0 ? collectExportNames(baseSource) : void 0;
|
|
168
|
+
if (base?.complete === true) for (const [entryName, entrySource] of Object.entries(dts.entry)) {
|
|
169
|
+
if (entryName === STUB_BASE_ENTRY || entryName.includes("/")) continue;
|
|
170
|
+
const source = readSource(entrySource);
|
|
171
|
+
if (source === void 0) continue;
|
|
172
|
+
const analysis = analyzeReexportBarrel(source);
|
|
173
|
+
if (!analysis.isPureNamedReexportBarrel) continue;
|
|
174
|
+
const all = [...analysis.valueNames, ...analysis.typeNames];
|
|
175
|
+
if (all.length === 0 || !all.every((n) => base.names.has(n))) continue;
|
|
176
|
+
stubEntries.set(entryName, {
|
|
177
|
+
valueNames: analysis.valueNames,
|
|
178
|
+
typeNames: analysis.typeNames
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
await timed(group.id, "dts", async () => {
|
|
183
|
+
for (const [entryName, entrySource] of Object.entries(dts.entry)) {
|
|
184
|
+
const stub = stubEntries.get(entryName);
|
|
185
|
+
if (stub !== void 0) {
|
|
186
|
+
const variants = [{
|
|
187
|
+
file: `${entryName}.d.ts`,
|
|
188
|
+
spec: `./${STUB_BASE_ENTRY}.js`
|
|
189
|
+
}];
|
|
190
|
+
if (dts.format.includes("cjs")) variants.push({
|
|
191
|
+
file: `${entryName}.d.cts`,
|
|
192
|
+
spec: `./${STUB_BASE_ENTRY}.cjs`
|
|
193
|
+
});
|
|
194
|
+
for (const variant of variants) {
|
|
195
|
+
const content = renderReexportStub({
|
|
196
|
+
valueNames: stub.valueNames,
|
|
197
|
+
typeNames: stub.typeNames,
|
|
198
|
+
baseSpecifier: variant.spec
|
|
199
|
+
});
|
|
200
|
+
writeFileSync(join(partOutDir, variant.file), content, "utf-8");
|
|
201
|
+
collector?.recordEmitted(group.id, "dts", {
|
|
202
|
+
path: variant.file,
|
|
203
|
+
bytes: Buffer.byteLength(content)
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
await build({
|
|
209
|
+
config: false,
|
|
210
|
+
cwd: options.cwd,
|
|
211
|
+
entry: { [entryName]: entrySource },
|
|
212
|
+
outDir: partOutDir,
|
|
213
|
+
format: dts.format,
|
|
214
|
+
platform: dts.platform,
|
|
215
|
+
sourcemap: dts.sourcemap,
|
|
216
|
+
unbundle: dts.unbundle,
|
|
217
|
+
clean: false,
|
|
218
|
+
fixedExtension: dts.fixedExtension,
|
|
219
|
+
dts: dts.dts,
|
|
220
|
+
define: dts.define,
|
|
221
|
+
...instrument(group.id),
|
|
222
|
+
...dtsDeps,
|
|
223
|
+
plugins: [
|
|
224
|
+
...dts.format.includes("cjs") ? [nodeBuiltinDefaultInterop(), cjsDefaultInterop()] : [],
|
|
225
|
+
...options.extraPlugins ?? [],
|
|
226
|
+
...metricsPlugins(group.id, "dts")
|
|
227
|
+
]
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
});
|
|
166
231
|
if (js.isProd && options.emitDeclarations === true && Object.keys(decl.entry).length > 0) {
|
|
167
232
|
const partDeclDir = part.outSubdir !== void 0 ? join(decl.outDir, part.outSubdir) : decl.outDir;
|
|
168
233
|
try {
|
package/build/strip-maps.js
CHANGED
package/build/sync-public.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { dirname, join, relative } from "node:path";
|
|
2
1
|
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
2
|
+
import { dirname, join, relative } from "node:path";
|
|
3
3
|
|
|
4
4
|
//#region src/build/sync-public.ts
|
|
5
5
|
/** Recursively collect every file path under `dir`, relative to `base`. */
|
|
@@ -3,8 +3,8 @@ import { normalizeLooseFiles } from "../build/loose-files.js";
|
|
|
3
3
|
import { ConfigValidator } from "./ConfigValidator.js";
|
|
4
4
|
import { normalizeExeOptions } from "../exe/config.js";
|
|
5
5
|
import { resolveTargets } from "../targets/resolve-targets.js";
|
|
6
|
-
import { Effect, Layer } from "effect";
|
|
7
6
|
import { existsSync, statSync } from "node:fs";
|
|
7
|
+
import { Effect, Layer } from "effect";
|
|
8
8
|
|
|
9
9
|
//#region src/config-validation/ConfigValidatorLive.ts
|
|
10
10
|
const VALID_SYNTAX_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
//#region src/dts/reexport-stub.ts
|
|
4
|
+
function parse(source, fileName) {
|
|
5
|
+
return ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Analyze an entry source as a candidate pure re-export barrel: classify its re-exported names into
|
|
9
|
+
* value vs type-only and report whether it is expressible as a thin stub. Pure parsing — no I/O.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
function analyzeReexportBarrel(source, fileName = "entry.ts") {
|
|
14
|
+
const sf = parse(source, fileName);
|
|
15
|
+
const valueNames = [];
|
|
16
|
+
const typeNames = [];
|
|
17
|
+
let pure = true;
|
|
18
|
+
for (const stmt of sf.statements) {
|
|
19
|
+
if (ts.isExportDeclaration(stmt) && stmt.moduleSpecifier !== void 0) {
|
|
20
|
+
const clause = stmt.exportClause;
|
|
21
|
+
if (clause !== void 0 && ts.isNamedExports(clause)) {
|
|
22
|
+
for (const el of clause.elements) (stmt.isTypeOnly || el.isTypeOnly ? typeNames : valueNames).push(el.name.text);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
pure = false;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
pure = false;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
valueNames,
|
|
32
|
+
typeNames,
|
|
33
|
+
isPureNamedReexportBarrel: pure
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Collect every name a module exports (named re-exports, namespace re-exports, and local `export`
|
|
38
|
+
* declarations). Used to test whether a barrel's re-exports are a strict subset of a base entry, so
|
|
39
|
+
* a stub re-exporting from that base resolves every symbol. Pure parsing — no I/O.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
function collectExportNames(source, fileName = "entry.ts") {
|
|
44
|
+
const sf = parse(source, fileName);
|
|
45
|
+
const names = /* @__PURE__ */ new Set();
|
|
46
|
+
let complete = true;
|
|
47
|
+
const addBindingName = (name) => {
|
|
48
|
+
if (ts.isIdentifier(name)) names.add(name.text);
|
|
49
|
+
else for (const el of name.elements) if (ts.isBindingElement(el)) addBindingName(el.name);
|
|
50
|
+
};
|
|
51
|
+
for (const stmt of sf.statements) {
|
|
52
|
+
if (ts.isExportDeclaration(stmt)) {
|
|
53
|
+
const clause = stmt.exportClause;
|
|
54
|
+
if (clause === void 0) {
|
|
55
|
+
if (stmt.moduleSpecifier !== void 0) complete = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (ts.isNamespaceExport(clause)) {
|
|
59
|
+
names.add(clause.name.text);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
for (const el of clause.elements) names.add(el.name.text);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!(ts.canHaveModifiers(stmt) ? (ts.getModifiers(stmt) ?? []).some((m) => m.kind === ts.SyntaxKind.ExportKeyword) : false)) continue;
|
|
66
|
+
if (ts.isVariableStatement(stmt)) for (const decl of stmt.declarationList.declarations) addBindingName(decl.name);
|
|
67
|
+
else if ((ts.isFunctionDeclaration(stmt) || ts.isClassDeclaration(stmt) || ts.isInterfaceDeclaration(stmt) || ts.isTypeAliasDeclaration(stmt) || ts.isEnumDeclaration(stmt) || ts.isModuleDeclaration(stmt)) && stmt.name !== void 0 && ts.isIdentifier(stmt.name)) names.add(stmt.name.text);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
names,
|
|
71
|
+
complete
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Render a thin re-export-stub `.d.ts`/`.d.cts` body: named re-exports of `valueNames` and
|
|
76
|
+
* `typeNames` from `baseSpecifier` (the published file of the base entry, e.g. `./index.js` for the
|
|
77
|
+
* ESM `.d.ts` or `./index.cjs` for the CJS `.d.cts`). Names are sorted so the output is
|
|
78
|
+
* deterministic. Returns the empty string when there is nothing to re-export.
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
function renderReexportStub(options) {
|
|
83
|
+
const sortedValues = [...options.valueNames].sort();
|
|
84
|
+
const sortedTypes = [...options.typeNames].sort();
|
|
85
|
+
const lines = [];
|
|
86
|
+
if (sortedValues.length > 0) lines.push(`export { ${sortedValues.join(", ")} } from "${options.baseSpecifier}";`);
|
|
87
|
+
if (sortedTypes.length > 0) lines.push(`export type { ${sortedTypes.join(", ")} } from "${options.baseSpecifier}";`);
|
|
88
|
+
return lines.length > 0 ? `${lines.join("\n")}\n` : "";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { analyzeReexportBarrel, collectExportNames, renderReexportStub };
|
package/dts/resolved-tsconfig.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
|
|
5
5
|
//#region src/dts/resolved-tsconfig.ts
|
|
@@ -47,6 +47,33 @@ function writeResolvedTsconfig(options) {
|
|
|
47
47
|
writeFileSync(path, `${JSON.stringify(cfg, null, " ")}\n`, "utf-8");
|
|
48
48
|
return path;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Derive a dts-EMIT variant of an already-written resolved tsconfig that adds
|
|
52
|
+
* `stableTypeOrdering: true`, and return its path. This makes the TypeScript declaration emitter
|
|
53
|
+
* (rolldown-plugin-dts on `typescript@6`) order union/type members deterministically, so a
|
|
54
|
+
* multi-union `.d.ts` (e.g. an Effect `Layer.Layer<…>` requirement channel) does not flip member
|
|
55
|
+
* order across otherwise-identical builds (#156). It is kept in a SEPARATE file from the
|
|
56
|
+
* api-extractor tsconfig on purpose: `@microsoft/api-extractor` pins `typescript ~5.9`, which
|
|
57
|
+
* predates the flag and hard-errors on the unknown compiler option — so only the emit passes
|
|
58
|
+
* (which run on TS6) ever see it, while the api-extractor compile reads the original clean config.
|
|
59
|
+
*
|
|
60
|
+
* Best-effort: if the base tsconfig cannot be read or parsed (e.g. a synthetic test path that was
|
|
61
|
+
* never written), the original path is returned unchanged — the emit then simply keeps TS's
|
|
62
|
+
* default ordering rather than aborting the build at this layer.
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
function writeDtsEmitTsconfig(resolvedTsconfigPath) {
|
|
67
|
+
const absBase = isAbsolute(resolvedTsconfigPath) ? resolvedTsconfigPath : resolve(resolvedTsconfigPath);
|
|
68
|
+
if (!existsSync(absBase)) return resolvedTsconfigPath;
|
|
69
|
+
const cfg = {
|
|
70
|
+
extends: absBase,
|
|
71
|
+
compilerOptions: { stableTypeOrdering: true }
|
|
72
|
+
};
|
|
73
|
+
const path = join(tmpdir(), `tsconfig-dts-emit-${process.pid}-${absBase.replace(/[^\w]/g, "_")}.json`);
|
|
74
|
+
writeFileSync(path, `${JSON.stringify(cfg, null, " ")}\n`, "utf-8");
|
|
75
|
+
return path;
|
|
76
|
+
}
|
|
50
77
|
|
|
51
78
|
//#endregion
|
|
52
|
-
export { buildResolvedTsconfig, writeResolvedTsconfig };
|
|
79
|
+
export { buildResolvedTsconfig, writeDtsEmitTsconfig, writeResolvedTsconfig };
|
package/exe/build.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { buildMetricsPlugin } from "../report/metrics-plugin.js";
|
|
2
2
|
import { createTimer } from "../report/timer.js";
|
|
3
3
|
import { createTsdownLogger } from "../report/tsdown-logger.js";
|
|
4
|
-
import { join } from "node:path";
|
|
5
4
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
|
|
8
8
|
//#region src/exe/build.ts
|
package/index.d.ts
CHANGED
|
@@ -177,21 +177,21 @@ declare const DiagnosticEntry_base: Schema.Class<DiagnosticEntry, {
|
|
|
177
177
|
line: Schema.optional<typeof Schema.Number>;
|
|
178
178
|
column: Schema.optional<typeof Schema.Number>;
|
|
179
179
|
}>, never, {
|
|
180
|
-
readonly
|
|
181
|
-
} & {
|
|
182
|
-
readonly source: "tsdown" | "rolldown" | "api-extractor";
|
|
183
|
-
} & {
|
|
184
|
-
readonly level: "warn" | "error";
|
|
180
|
+
readonly ciFatal?: boolean | undefined;
|
|
185
181
|
} & {
|
|
186
182
|
readonly code?: string | undefined;
|
|
187
183
|
} & {
|
|
188
|
-
readonly
|
|
184
|
+
readonly column?: number | undefined;
|
|
189
185
|
} & {
|
|
190
186
|
readonly file?: string | undefined;
|
|
191
187
|
} & {
|
|
192
188
|
readonly line?: number | undefined;
|
|
193
189
|
} & {
|
|
194
|
-
readonly
|
|
190
|
+
readonly level: "error" | "warn";
|
|
191
|
+
} & {
|
|
192
|
+
readonly source: "api-extractor" | "rolldown" | "tsdown";
|
|
193
|
+
} & {
|
|
194
|
+
readonly text: string;
|
|
195
195
|
}, {}, {}>;
|
|
196
196
|
/**
|
|
197
197
|
* A captured warning or error, from tsdown's logger, rolldown's onLog, or API Extractor.
|
|
@@ -208,11 +208,11 @@ declare const EmittedFile_base: Schema.Class<EmittedFile, {
|
|
|
208
208
|
bytes: typeof Schema.Number;
|
|
209
209
|
gzip: Schema.optional<typeof Schema.Number>;
|
|
210
210
|
}>, never, {
|
|
211
|
-
readonly
|
|
211
|
+
readonly gzip?: number | undefined;
|
|
212
212
|
} & {
|
|
213
213
|
readonly bytes: number;
|
|
214
214
|
} & {
|
|
215
|
-
readonly
|
|
215
|
+
readonly path: string;
|
|
216
216
|
}, {}, {}>;
|
|
217
217
|
/**
|
|
218
218
|
* One emitted output file with its in-memory byte size (gzip only when --verbose).
|
|
@@ -229,11 +229,11 @@ declare const PassReport_base: Schema.Class<PassReport, {
|
|
|
229
229
|
files: Schema.Array$<typeof EmittedFile>;
|
|
230
230
|
ms: typeof Schema.Number;
|
|
231
231
|
}>, never, {
|
|
232
|
-
readonly
|
|
232
|
+
readonly files: readonly EmittedFile[];
|
|
233
233
|
} & {
|
|
234
|
-
readonly id: "
|
|
234
|
+
readonly id: "dts" | "exe" | "js" | "loose" | "meta";
|
|
235
235
|
} & {
|
|
236
|
-
readonly
|
|
236
|
+
readonly ms: number;
|
|
237
237
|
}, {}, {}>;
|
|
238
238
|
/**
|
|
239
239
|
* One build pass within a target group (js / dts / loose / exe / meta).
|
|
@@ -260,17 +260,17 @@ declare const TargetGroupReport_base: Schema.Class<TargetGroupReport, {
|
|
|
260
260
|
}>, never, {
|
|
261
261
|
readonly entries: readonly string[];
|
|
262
262
|
} & {
|
|
263
|
-
readonly
|
|
263
|
+
readonly errors: readonly DiagnosticEntry[];
|
|
264
264
|
} & {
|
|
265
|
-
readonly
|
|
265
|
+
readonly id: string;
|
|
266
266
|
} & {
|
|
267
267
|
readonly passes: readonly PassReport[];
|
|
268
268
|
} & {
|
|
269
|
-
readonly
|
|
269
|
+
readonly suppressed: readonly DiagnosticEntry[];
|
|
270
270
|
} & {
|
|
271
|
-
readonly
|
|
271
|
+
readonly timings: ReportTimings;
|
|
272
272
|
} & {
|
|
273
|
-
readonly
|
|
273
|
+
readonly warnings: readonly DiagnosticEntry[];
|
|
274
274
|
}, {}, {}>;
|
|
275
275
|
/** @public */
|
|
276
276
|
declare class TargetGroupReport extends TargetGroupReport_base {}
|
|
@@ -1109,6 +1109,69 @@ declare class ConfigValidator extends ConfigValidator_base {}
|
|
|
1109
1109
|
*/
|
|
1110
1110
|
declare const ConfigValidatorLive: Layer.Layer<ConfigValidator, never, never>;
|
|
1111
1111
|
//#endregion
|
|
1112
|
+
//#region src/dts/reexport-stub.d.ts
|
|
1113
|
+
/**
|
|
1114
|
+
* The analysis of an entry source treated as a candidate re-export barrel.
|
|
1115
|
+
*
|
|
1116
|
+
* @public
|
|
1117
|
+
*/
|
|
1118
|
+
interface ReexportBarrelAnalysis {
|
|
1119
|
+
/** Value (non-type-only) names the module re-exports, after `as` aliasing. */
|
|
1120
|
+
readonly valueNames: ReadonlyArray<string>;
|
|
1121
|
+
/** Type-only names the module re-exports (`export type { … }`), after `as` aliasing. */
|
|
1122
|
+
readonly typeNames: ReadonlyArray<string>;
|
|
1123
|
+
/**
|
|
1124
|
+
* True iff EVERY top-level statement is a NAMED re-export `from` another module
|
|
1125
|
+
* (`export { … } from "…"` / `export type { … } from "…"`). A module that declares anything
|
|
1126
|
+
* locally, re-exports a namespace (`export * as NS from`), star-re-exports (`export * from`), or
|
|
1127
|
+
* has a bare `export { … }` without `from` is NOT a pure named barrel and cannot be expressed as
|
|
1128
|
+
* a thin re-export stub of another entry.
|
|
1129
|
+
*/
|
|
1130
|
+
readonly isPureNamedReexportBarrel: boolean;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* The set of names a module exports, plus whether that set is fully known.
|
|
1134
|
+
*
|
|
1135
|
+
* @public
|
|
1136
|
+
*/
|
|
1137
|
+
interface ModuleExportNames {
|
|
1138
|
+
readonly names: ReadonlySet<string>;
|
|
1139
|
+
/**
|
|
1140
|
+
* False when the module contains a star re-export (`export * from "…"`) whose target exports
|
|
1141
|
+
* cannot be enumerated from this source alone — the name set is then a lower bound, not complete,
|
|
1142
|
+
* so callers must not use it for a strict subset decision.
|
|
1143
|
+
*/
|
|
1144
|
+
readonly complete: boolean;
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Analyze an entry source as a candidate pure re-export barrel: classify its re-exported names into
|
|
1148
|
+
* value vs type-only and report whether it is expressible as a thin stub. Pure parsing — no I/O.
|
|
1149
|
+
*
|
|
1150
|
+
* @public
|
|
1151
|
+
*/
|
|
1152
|
+
declare function analyzeReexportBarrel(source: string, fileName?: string): ReexportBarrelAnalysis;
|
|
1153
|
+
/**
|
|
1154
|
+
* Collect every name a module exports (named re-exports, namespace re-exports, and local `export`
|
|
1155
|
+
* declarations). Used to test whether a barrel's re-exports are a strict subset of a base entry, so
|
|
1156
|
+
* a stub re-exporting from that base resolves every symbol. Pure parsing — no I/O.
|
|
1157
|
+
*
|
|
1158
|
+
* @public
|
|
1159
|
+
*/
|
|
1160
|
+
declare function collectExportNames(source: string, fileName?: string): ModuleExportNames;
|
|
1161
|
+
/**
|
|
1162
|
+
* Render a thin re-export-stub `.d.ts`/`.d.cts` body: named re-exports of `valueNames` and
|
|
1163
|
+
* `typeNames` from `baseSpecifier` (the published file of the base entry, e.g. `./index.js` for the
|
|
1164
|
+
* ESM `.d.ts` or `./index.cjs` for the CJS `.d.cts`). Names are sorted so the output is
|
|
1165
|
+
* deterministic. Returns the empty string when there is nothing to re-export.
|
|
1166
|
+
*
|
|
1167
|
+
* @public
|
|
1168
|
+
*/
|
|
1169
|
+
declare function renderReexportStub(options: {
|
|
1170
|
+
readonly valueNames: ReadonlyArray<string>;
|
|
1171
|
+
readonly typeNames: ReadonlyArray<string>;
|
|
1172
|
+
readonly baseSpecifier: string;
|
|
1173
|
+
}): string;
|
|
1174
|
+
//#endregion
|
|
1112
1175
|
//#region src/dts/resolved-tsconfig.d.ts
|
|
1113
1176
|
/** @public */
|
|
1114
1177
|
interface ResolvedTsconfigOptions {
|
|
@@ -1139,6 +1202,23 @@ declare function buildResolvedTsconfig(options: ResolvedTsconfigOptions): Resolv
|
|
|
1139
1202
|
* @public
|
|
1140
1203
|
*/
|
|
1141
1204
|
declare function writeResolvedTsconfig(options: ResolvedTsconfigOptions): string;
|
|
1205
|
+
/**
|
|
1206
|
+
* Derive a dts-EMIT variant of an already-written resolved tsconfig that adds
|
|
1207
|
+
* `stableTypeOrdering: true`, and return its path. This makes the TypeScript declaration emitter
|
|
1208
|
+
* (rolldown-plugin-dts on `typescript@6`) order union/type members deterministically, so a
|
|
1209
|
+
* multi-union `.d.ts` (e.g. an Effect `Layer.Layer<…>` requirement channel) does not flip member
|
|
1210
|
+
* order across otherwise-identical builds (#156). It is kept in a SEPARATE file from the
|
|
1211
|
+
* api-extractor tsconfig on purpose: `@microsoft/api-extractor` pins `typescript ~5.9`, which
|
|
1212
|
+
* predates the flag and hard-errors on the unknown compiler option — so only the emit passes
|
|
1213
|
+
* (which run on TS6) ever see it, while the api-extractor compile reads the original clean config.
|
|
1214
|
+
*
|
|
1215
|
+
* Best-effort: if the base tsconfig cannot be read or parsed (e.g. a synthetic test path that was
|
|
1216
|
+
* never written), the original path is returned unchanged — the emit then simply keeps TS's
|
|
1217
|
+
* default ordering rather than aborting the build at this layer.
|
|
1218
|
+
*
|
|
1219
|
+
* @public
|
|
1220
|
+
*/
|
|
1221
|
+
declare function writeDtsEmitTsconfig(resolvedTsconfigPath: string): string;
|
|
1142
1222
|
//#endregion
|
|
1143
1223
|
//#region src/entry/extract.d.ts
|
|
1144
1224
|
/** @public */
|
|
@@ -1718,5 +1798,5 @@ declare function resolveTargets(options: {
|
|
|
1718
1798
|
baseName: string;
|
|
1719
1799
|
}): TargetResolution;
|
|
1720
1800
|
//#endregion
|
|
1721
|
-
export { BuildCollector, BuildCollectorTag, type BuildEmittedManifestOptions, type BuildFormat, type BuildGroupSpec, type BuildIssues, type BuildPlatform, type BuildReport, BuildReport as BuildReportSchema, type BuildTargetGroupsOptions, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, type CssOptions, DEFAULT_EXE_NODE_VERSION, type DeriveOptions, type DerivedTsdownOptions, type DiagnosticEntry, type DiagnosticInput, type DualExports, type EmitManifestOptions, type EmittedFile, type EntryOverride, type Environment, EnvironmentDetector, EnvironmentDetectorLive, type ExeBuild, type ExeConfig, type ExeRewrite, type ExeSeaConfig, type ExeTarget, type ExeTargetInput, type Executor, ExecutorResolver, ExecutorResolverLive, type ExtractOptions, type ExtractResult, FormatSelector, FormatSelectorLive, type Formatter, type FormatterContext, type GenerateMetaOptions, type Json, JsonFormatter, type JsxConfig, type LooseFileSpec, type LooseFiles, type ManifestLike, MarkdownFormatter, MetaGenerationError, type MetaOptions, type MetaResult, type NextVersions, type NormalizedExe, type NormalizedLooseFile, type NormalizedMeta, type OutputFormat, OutputRenderer, OutputRendererLive, type PackageJsonEntriesOptions, type PackageJsonLike, type PassKind, type PassReport, type PkgOsCpu, type PlainDiagnostic, type PortableTsconfig, type PublishTargetObject, type PublishTargetValue, type PublishTargets, type RenderReportOptions, type RenderedOutput, ReportPipelineLive, ReportTimings, type ResolvedCompilerOptions, type ResolvedGroup, type ResolvedTarget, type ResolvedTsconfig, type ResolvedTsconfigOptions, type RunExeBuildOptions, type RunMetaPassOptions, SilentFormatter, type TargetGroupId, type TargetGroupRef, type TargetGroupReport, TargetGroupReport as TargetGroupReportSchema, type TargetResolution, TerminalFormatter, type Timer, type TransformManifestOptions, type TsconfigJsx, TsconfigResolver, type TsdocOptions, type TsdocTagDefinition, type TsdownBuild, type TsdownLogger, type ValidationInput, type WarningSuppressionRule, applySubdirMetaEntries, buildEmittedManifest, buildMetricsPlugin, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, computeExeFileName, createEntryName, createTimer, createTsdownLogger, defaultManifestTransform, deriveExportPaths, deriveTargetGroupOptions, emitManifest, extractEntries, flattenIssues, formatTime, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveManifest, resolveNextVersions, resolvePortableTsconfig, resolveTargets, rewriteMetaVersions, runExeBuild, runMetaPass, serializeIssues, syncPublicDir, transformBin, transformExports, transformManifest, writeIssuesArtifact, writeResolvedTsconfig, writeTargetsBinding };
|
|
1801
|
+
export { BuildCollector, BuildCollectorTag, type BuildEmittedManifestOptions, type BuildFormat, type BuildGroupSpec, type BuildIssues, type BuildPlatform, type BuildReport, BuildReport as BuildReportSchema, type BuildTargetGroupsOptions, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, type CssOptions, DEFAULT_EXE_NODE_VERSION, type DeriveOptions, type DerivedTsdownOptions, type DiagnosticEntry, type DiagnosticInput, type DualExports, type EmitManifestOptions, type EmittedFile, type EntryOverride, type Environment, EnvironmentDetector, EnvironmentDetectorLive, type ExeBuild, type ExeConfig, type ExeRewrite, type ExeSeaConfig, type ExeTarget, type ExeTargetInput, type Executor, ExecutorResolver, ExecutorResolverLive, type ExtractOptions, type ExtractResult, FormatSelector, FormatSelectorLive, type Formatter, type FormatterContext, type GenerateMetaOptions, type Json, JsonFormatter, type JsxConfig, type LooseFileSpec, type LooseFiles, type ManifestLike, MarkdownFormatter, MetaGenerationError, type MetaOptions, type MetaResult, type ModuleExportNames, type NextVersions, type NormalizedExe, type NormalizedLooseFile, type NormalizedMeta, type OutputFormat, OutputRenderer, OutputRendererLive, type PackageJsonEntriesOptions, type PackageJsonLike, type PassKind, type PassReport, type PkgOsCpu, type PlainDiagnostic, type PortableTsconfig, type PublishTargetObject, type PublishTargetValue, type PublishTargets, type ReexportBarrelAnalysis, type RenderReportOptions, type RenderedOutput, ReportPipelineLive, ReportTimings, type ResolvedCompilerOptions, type ResolvedGroup, type ResolvedTarget, type ResolvedTsconfig, type ResolvedTsconfigOptions, type RunExeBuildOptions, type RunMetaPassOptions, SilentFormatter, type TargetGroupId, type TargetGroupRef, type TargetGroupReport, TargetGroupReport as TargetGroupReportSchema, type TargetResolution, TerminalFormatter, type Timer, type TransformManifestOptions, type TsconfigJsx, TsconfigResolver, type TsdocOptions, type TsdocTagDefinition, type TsdownBuild, type TsdownLogger, type ValidationInput, type WarningSuppressionRule, analyzeReexportBarrel, applySubdirMetaEntries, buildEmittedManifest, buildMetricsPlugin, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, collectExportNames, computeExeFileName, createEntryName, createTimer, createTsdownLogger, defaultManifestTransform, deriveExportPaths, deriveTargetGroupOptions, emitManifest, extractEntries, flattenIssues, formatTime, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReexportStub, renderReport, resolveJsxConfig, resolveManifest, resolveNextVersions, resolvePortableTsconfig, resolveTargets, rewriteMetaVersions, runExeBuild, runMetaPass, serializeIssues, syncPublicDir, transformBin, transformExports, transformManifest, writeDtsEmitTsconfig, writeIssuesArtifact, writeResolvedTsconfig, writeTargetsBinding };
|
|
1722
1802
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { analyzeReexportBarrel, collectExportNames, renderReexportStub } from "./dts/reexport-stub.js";
|
|
2
|
+
import { buildResolvedTsconfig, writeDtsEmitTsconfig, writeResolvedTsconfig } from "./dts/resolved-tsconfig.js";
|
|
1
3
|
import { resolveManifest } from "./catalog/resolve-catalogs.js";
|
|
2
4
|
import { createEntryName, extractEntries } from "./entry/extract.js";
|
|
3
5
|
import { defaultManifestTransform, normalizeBinPaths, transformBin, transformExports, transformManifest } from "./manifest/transform.js";
|
|
@@ -19,7 +21,6 @@ import { DEFAULT_EXE_NODE_VERSION, normalizeExeOptions } from "./exe/config.js";
|
|
|
19
21
|
import { isTargetObject } from "./targets/config.js";
|
|
20
22
|
import { resolveTargets } from "./targets/resolve-targets.js";
|
|
21
23
|
import { ConfigValidatorLive } from "./config-validation/ConfigValidatorLive.js";
|
|
22
|
-
import { buildResolvedTsconfig, writeResolvedTsconfig } from "./dts/resolved-tsconfig.js";
|
|
23
24
|
import { packageJsonEntries } from "./entry/package-json-entries.js";
|
|
24
25
|
import { runExeBuild } from "./exe/build.js";
|
|
25
26
|
import { computeExeFileName } from "./exe/filename.js";
|
|
@@ -49,4 +50,4 @@ import { ReportPipelineLive, renderReport } from "./report/pipeline.js";
|
|
|
49
50
|
import { writeTargetsBinding } from "./targets/binding.js";
|
|
50
51
|
import { CatalogAssemblyError, CatalogResolutionError } from "workspaces-effect";
|
|
51
52
|
|
|
52
|
-
export { BuildCollector, BuildCollectorTag, BuildReport as BuildReportSchema, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, DEFAULT_EXE_NODE_VERSION, EnvironmentDetector, EnvironmentDetectorLive, ExecutorResolver, ExecutorResolverLive, FormatSelector, FormatSelectorLive, JsonFormatter, MarkdownFormatter, MetaGenerationError, OutputRenderer, OutputRendererLive, ReportPipelineLive, ReportTimings, SilentFormatter, TargetGroupReport as TargetGroupReportSchema, TerminalFormatter, TsconfigResolver, applySubdirMetaEntries, buildEmittedManifest, buildMetricsPlugin, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, computeExeFileName, createEntryName, createTimer, createTsdownLogger, defaultManifestTransform, deriveExportPaths, deriveTargetGroupOptions, emitManifest, extractEntries, flattenIssues, formatTime, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveManifest, resolveNextVersions, resolvePortableTsconfig, resolveTargets, rewriteMetaVersions, runExeBuild, runMetaPass, serializeIssues, syncPublicDir, transformBin, transformExports, transformManifest, writeIssuesArtifact, writeResolvedTsconfig, writeTargetsBinding };
|
|
53
|
+
export { BuildCollector, BuildCollectorTag, BuildReport as BuildReportSchema, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, DEFAULT_EXE_NODE_VERSION, EnvironmentDetector, EnvironmentDetectorLive, ExecutorResolver, ExecutorResolverLive, FormatSelector, FormatSelectorLive, JsonFormatter, MarkdownFormatter, MetaGenerationError, OutputRenderer, OutputRendererLive, ReportPipelineLive, ReportTimings, SilentFormatter, TargetGroupReport as TargetGroupReportSchema, TerminalFormatter, TsconfigResolver, analyzeReexportBarrel, applySubdirMetaEntries, buildEmittedManifest, buildMetricsPlugin, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, collectExportNames, computeExeFileName, createEntryName, createTimer, createTsdownLogger, defaultManifestTransform, deriveExportPaths, deriveTargetGroupOptions, emitManifest, extractEntries, flattenIssues, formatTime, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReexportStub, renderReport, resolveJsxConfig, resolveManifest, resolveNextVersions, resolvePortableTsconfig, resolveTargets, rewriteMetaVersions, runExeBuild, runMetaPass, serializeIssues, syncPublicDir, transformBin, transformExports, transformManifest, writeDtsEmitTsconfig, writeIssuesArtifact, writeResolvedTsconfig, writeTargetsBinding };
|
package/jsx/config.js
CHANGED
package/meta/generate.js
CHANGED
|
@@ -2,8 +2,8 @@ import { runApiExtractor } from "./api-extractor.js";
|
|
|
2
2
|
import { mergeApiModels } from "./merge-models.js";
|
|
3
3
|
import { resolvePortableTsconfig } from "./tsconfig-resolver.js";
|
|
4
4
|
import { writeTsdocConfig } from "./tsdoc-config.js";
|
|
5
|
-
import { join } from "node:path";
|
|
6
5
|
import { copyFileSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
7
|
|
|
8
8
|
//#region src/meta/generate.ts
|
|
9
9
|
function unscopedName(name) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
1
|
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
3
|
import { JsxEmit, ModuleDetectionKind, ModuleKind, ModuleResolutionKind, NewLineKind, ScriptTarget, flattenDiagnosticMessageText, getParsedCommandLineOfConfigFile, sys } from "typescript";
|
|
4
4
|
|
|
5
5
|
//#region src/meta/tsconfig-resolver.ts
|
package/meta/tsdoc-config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/tsdown-plugins",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { dirname, join } from "node:path";
|
|
2
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
3
|
|
|
4
4
|
//#region src/report/issues-artifact.ts
|
|
5
5
|
/** Copy a DiagnosticEntry to a plain object, omitting undefined optionals for stable output. */
|