@animus-ui/extract 0.1.25 → 0.1.26
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/crates/extract-v2/animus-extract-v2.darwin-arm64.node +0 -0
- package/crates/extract-v2/animus-extract-v2.linux-arm64-gnu.node +0 -0
- package/crates/extract-v2/animus-extract-v2.linux-x64-gnu.node +0 -0
- package/crates/extract-v2/index.d.ts +101 -6
- package/dist/index.cjs +48 -5
- package/dist/index.mjs +2 -2
- package/dist/pipeline/alias-agreement.d.ts +107 -0
- package/dist/pipeline/alias-agreement.d.ts.map +1 -0
- package/dist/pipeline/analyze-project-args.d.ts +7 -2
- package/dist/pipeline/analyze-project-args.d.ts.map +1 -1
- package/dist/pipeline/asset-copies.d.ts +20 -0
- package/dist/pipeline/asset-copies.d.ts.map +1 -0
- package/dist/pipeline/built-in-asset-types.d.ts +9 -0
- package/dist/pipeline/built-in-asset-types.d.ts.map +1 -0
- package/dist/pipeline/core-options.d.ts +31 -7
- package/dist/pipeline/core-options.d.ts.map +1 -1
- package/dist/pipeline/discover-packages.d.ts +98 -12
- package/dist/pipeline/discover-packages.d.ts.map +1 -1
- package/dist/pipeline/engine-adapter.d.ts +41 -3
- package/dist/pipeline/engine-adapter.d.ts.map +1 -1
- package/dist/pipeline/engine-retirement.d.ts +7 -1
- package/dist/pipeline/engine-retirement.d.ts.map +1 -1
- package/dist/pipeline/extension-policy.d.ts +95 -0
- package/dist/pipeline/extension-policy.d.ts.map +1 -0
- package/dist/pipeline/host-assets.d.ts +32 -0
- package/dist/pipeline/host-assets.d.ts.map +1 -0
- package/dist/pipeline/host-expansions.d.ts +92 -0
- package/dist/pipeline/host-expansions.d.ts.map +1 -0
- package/dist/pipeline/host-extensions.d.ts +64 -0
- package/dist/pipeline/host-extensions.d.ts.map +1 -0
- package/dist/pipeline/host-package-resolver.d.ts +40 -0
- package/dist/pipeline/host-package-resolver.d.ts.map +1 -0
- package/dist/pipeline/index.d.ts +32 -8
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/kit-publication.d.ts.map +1 -1
- package/dist/pipeline/manifest-diagnostics.d.ts +25 -4
- package/dist/pipeline/manifest-diagnostics.d.ts.map +1 -1
- package/dist/pipeline/manifest-schema.d.ts +16 -0
- package/dist/pipeline/manifest-schema.d.ts.map +1 -1
- package/dist/pipeline/output-targets.d.ts +52 -0
- package/dist/pipeline/output-targets.d.ts.map +1 -0
- package/dist/pipeline/probe-evidence.d.ts +58 -0
- package/dist/pipeline/probe-evidence.d.ts.map +1 -0
- package/dist/pipeline/run-analysis.d.ts +26 -0
- package/dist/pipeline/run-analysis.d.ts.map +1 -1
- package/dist/pipeline/runtime-import.d.ts +10 -0
- package/dist/pipeline/runtime-import.d.ts.map +1 -0
- package/dist/pipeline/served-files.d.ts +16 -0
- package/dist/pipeline/served-files.d.ts.map +1 -0
- package/dist/pipeline/source-corpus.d.ts +4 -0
- package/dist/pipeline/source-corpus.d.ts.map +1 -1
- package/dist/pipeline/source-ingestion.d.ts +37 -5
- package/dist/pipeline/source-ingestion.d.ts.map +1 -1
- package/dist/pipeline/system-config.d.ts +18 -0
- package/dist/pipeline/system-config.d.ts.map +1 -1
- package/dist/pipeline/system-instances.d.ts +27 -0
- package/dist/pipeline/system-instances.d.ts.map +1 -0
- package/dist/pipeline/tsconfig-paths.d.ts +4 -0
- package/dist/pipeline/tsconfig-paths.d.ts.map +1 -1
- package/dist/pipeline/vite-expansions.d.ts +40 -0
- package/dist/pipeline/vite-expansions.d.ts.map +1 -0
- package/dist/pipeline/webpack-expansions.d.ts +55 -0
- package/dist/pipeline/webpack-expansions.d.ts.map +1 -0
- package/dist/pipeline/workspace-packages.d.ts +13 -0
- package/dist/pipeline/workspace-packages.d.ts.map +1 -0
- package/dist/{pipeline-YGWpNr_Z.mjs → pipeline-BzMQ_Z0M.mjs} +2285 -773
- package/dist/{pipeline-DOgKR4VZ.cjs → pipeline-DyUf-eKZ.cjs} +2556 -768
- package/dist/session/coalescing-window.d.ts +34 -0
- package/dist/session/coalescing-window.d.ts.map +1 -0
- package/dist/session/extraction-session.d.ts +297 -35
- package/dist/session/extraction-session.d.ts.map +1 -1
- package/dist/session/index.d.ts +7 -3
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/published-set.d.ts +6 -1
- package/dist/session/published-set.d.ts.map +1 -1
- package/dist/session/resolve-packages.d.ts +9 -5
- package/dist/session/resolve-packages.d.ts.map +1 -1
- package/dist/session/singleton.d.ts +218 -53
- package/dist/session/singleton.d.ts.map +1 -1
- package/dist/session/turbopack-orchestrator.d.ts.map +1 -1
- package/dist/session.cjs +1462 -510
- package/dist/session.mjs +1430 -489
- package/package.json +4 -4
|
@@ -23,9 +23,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
let node_path = require("node:path");
|
|
24
24
|
node_path = __toESM(node_path);
|
|
25
25
|
let crypto = require("crypto");
|
|
26
|
+
let node_fs = require("node:fs");
|
|
26
27
|
let fs = require("fs");
|
|
27
28
|
let path = require("path");
|
|
28
|
-
let node_fs = require("node:fs");
|
|
29
29
|
let module$1 = require("module");
|
|
30
30
|
let browserslist = require("browserslist");
|
|
31
31
|
browserslist = __toESM(browserslist);
|
|
@@ -90,7 +90,7 @@ function assembleStylesheet(options) {
|
|
|
90
90
|
//#endregion
|
|
91
91
|
//#region pipeline/analyze-project-args.ts
|
|
92
92
|
/** @internal */
|
|
93
|
-
function buildAnalyzeProjectArgs(inputs) {
|
|
93
|
+
function buildAnalyzeProjectArgs(inputs, probeEvidence) {
|
|
94
94
|
const args = [
|
|
95
95
|
inputs.filesJson,
|
|
96
96
|
inputs.scalesJson,
|
|
@@ -118,16 +118,12 @@ function buildAnalyzeProjectArgs(inputs) {
|
|
|
118
118
|
inputs.generatedNamesJson,
|
|
119
119
|
inputs.propertyRecordsJson
|
|
120
120
|
];
|
|
121
|
-
const last = tail.findLastIndex((slot) => slot !== void 0 && slot !== "");
|
|
121
|
+
const last = probeEvidence === void 0 ? tail.findLastIndex((slot) => slot !== void 0 && slot !== "") : tail.length - 1;
|
|
122
122
|
for (const slot of tail.slice(0, last + 1)) args.push(slot || void 0);
|
|
123
|
+
if (probeEvidence !== void 0) args.push(probeEvidence);
|
|
123
124
|
return args;
|
|
124
125
|
}
|
|
125
126
|
//#endregion
|
|
126
|
-
//#region pipeline/content-hash.ts
|
|
127
|
-
function contentHash(source) {
|
|
128
|
-
return (0, crypto.createHash)("md5").update(source).digest("hex");
|
|
129
|
-
}
|
|
130
|
-
//#endregion
|
|
131
127
|
//#region pipeline/internal-wire.ts
|
|
132
128
|
function parseInternalWire(json, wire) {
|
|
133
129
|
let parsed;
|
|
@@ -139,6 +135,160 @@ function parseInternalWire(json, wire) {
|
|
|
139
135
|
return parsed;
|
|
140
136
|
}
|
|
141
137
|
//#endregion
|
|
138
|
+
//#region pipeline/content-hash.ts
|
|
139
|
+
function contentHash(source) {
|
|
140
|
+
return (0, crypto.createHash)("md5").update(source).digest("hex");
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region pipeline/extension-policy.ts
|
|
144
|
+
/**
|
|
145
|
+
* The one extension policy: the order in which a relative or aliased
|
|
146
|
+
* specifier's candidate files are tried. Source ingestion reads it here. The
|
|
147
|
+
* system loader and the extractor read `extension_policy.json`, which
|
|
148
|
+
* `node packages/extract/scripts/extension-policy.ts --write` generates from
|
|
149
|
+
* it, so every resolver tries the same files in the same order.
|
|
150
|
+
*
|
|
151
|
+
* The order: the base itself, the base with each appended extension, its
|
|
152
|
+
* `index` with each, then the sources an emitted NodeNext extension stands
|
|
153
|
+
* for (`./x.js` for `x.ts`), spelled exactly.
|
|
154
|
+
*/
|
|
155
|
+
const EXTENSION_POLICY = {
|
|
156
|
+
/** Appended to the base, then to `{base}/index`. */
|
|
157
|
+
appended: [
|
|
158
|
+
".ts",
|
|
159
|
+
".tsx",
|
|
160
|
+
".js",
|
|
161
|
+
".jsx",
|
|
162
|
+
".mjs"
|
|
163
|
+
],
|
|
164
|
+
/** An emitted extension, and the source extensions it names, in order. */
|
|
165
|
+
nodeNext: [
|
|
166
|
+
[".js", [
|
|
167
|
+
".ts",
|
|
168
|
+
".tsx",
|
|
169
|
+
".jsx"
|
|
170
|
+
]],
|
|
171
|
+
[".jsx", [".tsx"]],
|
|
172
|
+
[".mjs", [".mts"]],
|
|
173
|
+
[".cjs", [".cts"]]
|
|
174
|
+
]
|
|
175
|
+
};
|
|
176
|
+
const BUILT_IN_ORDER = {
|
|
177
|
+
appended: EXTENSION_POLICY.appended,
|
|
178
|
+
nodeNext: EXTENSION_POLICY.nodeNext,
|
|
179
|
+
alias: []
|
|
180
|
+
};
|
|
181
|
+
/** The files `base` can name, in policy order: itself, with each appended
|
|
182
|
+
* extension, as a directory's index with each, then the sources its
|
|
183
|
+
* emitted NodeNext extension stands for (`x.js` names `x.ts`), spelled
|
|
184
|
+
* exactly. Given `sources`, only extensions in it are tried, and under the
|
|
185
|
+
* built-in order those it lacks (`.mdx`) follow its own. A configured
|
|
186
|
+
* alias of the base's suffix replaces all of these. `index` spells a
|
|
187
|
+
* directory's index path. */
|
|
188
|
+
function policyCandidates(base, options = {}) {
|
|
189
|
+
const { sources, index = (directory, file) => `${directory}/${file}`, policy = BUILT_IN_ORDER } = options;
|
|
190
|
+
const alias = policy.alias.find(([from]) => base.endsWith(from));
|
|
191
|
+
if (alias !== void 0) {
|
|
192
|
+
const [from, sequence] = alias;
|
|
193
|
+
const stem = base.slice(0, base.length - from.length);
|
|
194
|
+
return sequence.map((to) => `${stem}${to}`);
|
|
195
|
+
}
|
|
196
|
+
const admitted = (extension) => !sources || sources.has(extension);
|
|
197
|
+
const appended = [...policy.appended.filter(admitted), ...sources && policy.appended === EXTENSION_POLICY.appended ? [...sources].filter((s) => !policy.appended.includes(s)) : []];
|
|
198
|
+
const name = base.slice(Math.max(base.lastIndexOf("/"), base.lastIndexOf("\\")) + 1);
|
|
199
|
+
const dot = name.lastIndexOf(".");
|
|
200
|
+
const emitted = dot === -1 ? "" : name.slice(dot);
|
|
201
|
+
const stem = base.slice(0, base.length - emitted.length);
|
|
202
|
+
const nodeNext = (policy.nodeNext.find(([from]) => from === emitted)?.[1] ?? []).filter(admitted);
|
|
203
|
+
return [
|
|
204
|
+
base,
|
|
205
|
+
...appended.map((extension) => `${base}${extension}`),
|
|
206
|
+
...appended.map((extension) => index(base, `index${extension}`)),
|
|
207
|
+
...nodeNext.map((source) => `${stem}${source}`)
|
|
208
|
+
];
|
|
209
|
+
}
|
|
210
|
+
/** The first of `candidates` that `see` finds, in order; a candidate found
|
|
211
|
+
* only under another case ends the probe as a mismatch. */
|
|
212
|
+
function probeCandidates(candidates, see) {
|
|
213
|
+
for (const candidate of candidates) {
|
|
214
|
+
const seen = see(candidate);
|
|
215
|
+
if (seen.kind === "file") return {
|
|
216
|
+
kind: "found",
|
|
217
|
+
path: candidate
|
|
218
|
+
};
|
|
219
|
+
if (seen.kind === "case-only") return {
|
|
220
|
+
kind: "case-mismatch",
|
|
221
|
+
candidate,
|
|
222
|
+
actual: seen.actual
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return { kind: "absent" };
|
|
226
|
+
}
|
|
227
|
+
const isFile = (path) => {
|
|
228
|
+
try {
|
|
229
|
+
return (0, node_fs.statSync)(path).isFile();
|
|
230
|
+
} catch {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
/** Whether `directory` lists an entry spelled exactly `name`. */
|
|
235
|
+
function lists(directory, name) {
|
|
236
|
+
try {
|
|
237
|
+
return (0, node_fs.readdirSync)(directory || ".").includes(name);
|
|
238
|
+
} catch {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/** `path`'s real path as the filesystem reports it; as given when it cannot
|
|
243
|
+
* be read. */
|
|
244
|
+
const reported = (path) => {
|
|
245
|
+
try {
|
|
246
|
+
return node_fs.realpathSync.native(path);
|
|
247
|
+
} catch {
|
|
248
|
+
return path;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
/** What the filesystem holds at `candidate`: a file it opens under exactly
|
|
252
|
+
* that spelling, or one it opens although a directory below the one the
|
|
253
|
+
* candidate shares with `within` lists no entry spelled as the candidate
|
|
254
|
+
* spells it (a case- or normalization-insensitive filesystem opening
|
|
255
|
+
* another spelling). Nothing is folded: the filesystem decides what opens,
|
|
256
|
+
* and its listings decide the spelling, so a file a case-sensitive
|
|
257
|
+
* filesystem cannot open is simply missing. The shared directory is
|
|
258
|
+
* spelled as given, as a specifier spells only the path from its
|
|
259
|
+
* importer's directory and a manifest only the paths in its package. `..`
|
|
260
|
+
* is taken back lexically, as Node and the bundlers resolve a specifier
|
|
261
|
+
* before opening it. The system loader reads it alike. */
|
|
262
|
+
function seeOnDisk(candidate, within) {
|
|
263
|
+
const path = (0, node_path.normalize)(candidate);
|
|
264
|
+
if (!isFile(path)) return { kind: "missing" };
|
|
265
|
+
const { root } = (0, node_path.parse)(path);
|
|
266
|
+
const names = path.slice(root.length).split(node_path.sep).filter(Boolean);
|
|
267
|
+
const baseNames = within === void 0 ? [] : (0, node_path.normalize)(within).slice(root.length).split(node_path.sep).filter(Boolean);
|
|
268
|
+
let shared = 0;
|
|
269
|
+
while (shared < baseNames.length && names[shared] === baseNames[shared] && names[shared] !== "..") shared++;
|
|
270
|
+
let directory = (0, node_path.join)(root, ...names.slice(0, shared));
|
|
271
|
+
for (const name of names.slice(shared)) {
|
|
272
|
+
if (!lists(directory, name)) return {
|
|
273
|
+
kind: "case-only",
|
|
274
|
+
actual: reported(path)
|
|
275
|
+
};
|
|
276
|
+
directory = (0, node_path.join)(directory, name);
|
|
277
|
+
}
|
|
278
|
+
return { kind: "file" };
|
|
279
|
+
}
|
|
280
|
+
/** The first of `candidates` the filesystem holds, spelled exactly below
|
|
281
|
+
* `within` when given. */
|
|
282
|
+
function probeOnDisk(candidates, within) {
|
|
283
|
+
return probeCandidates(candidates, (candidate) => seeOnDisk(candidate, within));
|
|
284
|
+
}
|
|
285
|
+
/** Why `subject` names no file: the file it would load is spelled otherwise
|
|
286
|
+
* on disk. `remedy` says what to respell. The system loader words it
|
|
287
|
+
* alike. */
|
|
288
|
+
function caseMismatchReason(subject, mismatch, remedy) {
|
|
289
|
+
return `${subject} names ${mismatch.candidate}, but the file on disk is ${mismatch.actual}, spelled differently: a case- or normalization-insensitive filesystem loads it and a sensitive one does not — ${remedy}`;
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
142
292
|
//#region pipeline/asset-placeholders.ts
|
|
143
293
|
const ASSET_PLACEHOLDER_PREFIX = "animus-asset:";
|
|
144
294
|
const URL_OPEN_RE = /url\(\s*(['"]?)/gi;
|
|
@@ -316,15 +466,6 @@ function warnLine(diagnostic) {
|
|
|
316
466
|
/** Stable code for selector forms with no substitutable subject; the
|
|
317
467
|
* extraction engine mints the same string. */
|
|
318
468
|
const SELECTOR_UNSUPPORTED_SUBJECT = "animus.selector.unsupported-subject";
|
|
319
|
-
/** The one matcher for the engine's unresolved-parent chain-drop message;
|
|
320
|
-
* consumers match through the exported helpers, never their own copy. */
|
|
321
|
-
const UNRESOLVED_PARENT_RE = /chain dropped: could not resolve parent component '([^']+)'/;
|
|
322
|
-
function isUnresolvedParentDrop(diagnostic) {
|
|
323
|
-
return UNRESOLVED_PARENT_RE.test(diagnostic.message);
|
|
324
|
-
}
|
|
325
|
-
function unresolvedParentName(diagnostic) {
|
|
326
|
-
return UNRESOLVED_PARENT_RE.exec(diagnostic.message)?.[1] ?? null;
|
|
327
|
-
}
|
|
328
469
|
const DIAGNOSTIC_LEVELS = /* @__PURE__ */ new Set([
|
|
329
470
|
"off",
|
|
330
471
|
"info",
|
|
@@ -446,7 +587,7 @@ const NO_KIT_FILES = "animus.discovery.no-kit-files";
|
|
|
446
587
|
* TypeScript source: discovery guesses its source from `src/`. */
|
|
447
588
|
const KIT_WITHOUT_SOURCE_CONDITION = "animus.discovery.kit-without-source-condition";
|
|
448
589
|
/** A kit's `animus` export condition names a file that is missing or outside
|
|
449
|
-
* its package, so that entry is
|
|
590
|
+
* its package, so that entry is read from its runtime target instead. */
|
|
450
591
|
const INVALID_KIT_SOURCE_CONDITION = "animus.discovery.invalid-source-condition";
|
|
451
592
|
/** A kit the application imports whose system the application's system
|
|
452
593
|
* does not include: its components are not extracted. */
|
|
@@ -454,10 +595,34 @@ const KIT_SYSTEM_NOT_INCLUDED = "animus.kit.system-not-included";
|
|
|
454
595
|
/** A system file's `createSystem` binding that discovery could not follow to
|
|
455
596
|
* Animus's factory, so it is no root. */
|
|
456
597
|
const UNPROVEN_ROOT_BINDING = "animus.discovery.unproven-root-binding";
|
|
598
|
+
/** A system builder, a `createSystem` chain not yet built, leaves the
|
|
599
|
+
* bindings and chains discovery follows, so kits extended on it from there
|
|
600
|
+
* are not read as members. */
|
|
601
|
+
const UNFOLLOWED_SYSTEM_BUILDER = "animus.discovery.unfollowed-system-builder";
|
|
457
602
|
/** A system file calls `createSystem` with no import or local binding. The
|
|
458
603
|
* system loader evaluates the file without auto-imports, where the name is
|
|
459
604
|
* undefined, so the call is no root. */
|
|
460
605
|
const UNIMPORTED_CREATE_SYSTEM = "animus.discovery.unimported-create-system";
|
|
606
|
+
/** A tsconfig path alias the host bundler resolves to another file than
|
|
607
|
+
* analysis does (spec §2.2 A7): report only. */
|
|
608
|
+
const ALIAS_MISMATCH = "animus.discovery.alias-mismatch";
|
|
609
|
+
/** A package the host bundler resolves to a file in no package of its own,
|
|
610
|
+
* where discovery reads the installed package instead (spec §2.2 A4):
|
|
611
|
+
* report only. */
|
|
612
|
+
const PACKAGE_MISMATCH = "animus.discovery.package-mismatch";
|
|
613
|
+
/** A system-file kit whose analysed instance is not the one the system
|
|
614
|
+
* load evaluated (spec §2.2 A4): its components would be extracted
|
|
615
|
+
* against another instance's vocabulary. */
|
|
616
|
+
const SYSTEM_INSTANCE_MISMATCH = "animus.discovery.system-instance-mismatch";
|
|
617
|
+
/** An import the host resolves, from its importer, into another instance
|
|
618
|
+
* of a discovered package whose file is not analysed and that no source
|
|
619
|
+
* redirect covers: the importer would render unextracted builder code
|
|
620
|
+
* (spec §2.2 A4, SA1). */
|
|
621
|
+
const UNREAD_PACKAGE_INSTANCE = "animus.discovery.unread-package-instance";
|
|
622
|
+
/** An import the host resolves, from its importer, into another instance
|
|
623
|
+
* of a discovered package, which a request-keyed source redirect replaces
|
|
624
|
+
* with the instance discovery read (spec §2.2 A4). */
|
|
625
|
+
const REPLACED_PACKAGE_INSTANCE = "animus.discovery.replaced-package-instance";
|
|
461
626
|
/** What a skipped source file costs: the analysis never sees what it
|
|
462
627
|
* renders. */
|
|
463
628
|
const SKIPPED_SOURCE_COST = "skipped: its renders are not seen, so nothing is pruned and every component, variant option and state is kept until it is analyzed";
|
|
@@ -543,6 +708,12 @@ const DIAGNOSTIC_SEVERITY = /* @__PURE__ */ new Map([
|
|
|
543
708
|
[KIT_STALE_DESCRIPTOR, "warn"],
|
|
544
709
|
[UNPROVEN_ROOT_BINDING, "warn"],
|
|
545
710
|
[UNIMPORTED_CREATE_SYSTEM, "warn"],
|
|
711
|
+
[UNFOLLOWED_SYSTEM_BUILDER, "warn"],
|
|
712
|
+
[ALIAS_MISMATCH, "warn"],
|
|
713
|
+
[PACKAGE_MISMATCH, "warn"],
|
|
714
|
+
[SYSTEM_INSTANCE_MISMATCH, "error"],
|
|
715
|
+
[UNREAD_PACKAGE_INSTANCE, "error"],
|
|
716
|
+
[REPLACED_PACKAGE_INSTANCE, "warn"],
|
|
546
717
|
[VOCABULARY_COLLISION, "warn"],
|
|
547
718
|
[VOCABULARY_LEGACY_VERB, "warn"],
|
|
548
719
|
[INVALID_PROPERTY_REGISTRATION, "error"],
|
|
@@ -744,6 +915,135 @@ async function preprocessMdx(source, filename) {
|
|
|
744
915
|
}
|
|
745
916
|
}
|
|
746
917
|
//#endregion
|
|
918
|
+
//#region pipeline/host-expansions.ts
|
|
919
|
+
/**
|
|
920
|
+
* The host's expansion of each listed load the expander reproduces, with
|
|
921
|
+
* each file read as the analysis and the host read it: a module the
|
|
922
|
+
* analysis holds, loaded as code without a query; a file the host loads as
|
|
923
|
+
* an opaque value (spec §2.2 A8); otherwise a file the analysis does not
|
|
924
|
+
* read. A query can select other code than the module (a plugin's
|
|
925
|
+
* transform), so a queried file that is not opaque is never the analysed
|
|
926
|
+
* module, and it keeps its query.
|
|
927
|
+
*/
|
|
928
|
+
function hostExpansions(loads, rootDir, analysed, expander, isAsset) {
|
|
929
|
+
const expansions = [];
|
|
930
|
+
for (const load of loads) {
|
|
931
|
+
const expanded = expander.expand(load, rootDir);
|
|
932
|
+
if (expanded === void 0) continue;
|
|
933
|
+
const files = /* @__PURE__ */ new Map();
|
|
934
|
+
for (const { path, query } of expanded) {
|
|
935
|
+
const opaque = isAsset?.((0, node_path.join)(rootDir, path), query) ?? false;
|
|
936
|
+
const status = query === "" && analysed.has(path) ? "analysed" : opaque ? "opaque" : "unanalysed";
|
|
937
|
+
const key = `${path}${query}`;
|
|
938
|
+
files.set(key, {
|
|
939
|
+
path: status === "analysed" ? path : key,
|
|
940
|
+
status
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
expansions.push({
|
|
944
|
+
importer: load.importer,
|
|
945
|
+
start: load.start,
|
|
946
|
+
closed: true,
|
|
947
|
+
files: [...files.values()]
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
return expansions;
|
|
951
|
+
}
|
|
952
|
+
//#endregion
|
|
953
|
+
//#region pipeline/probe-evidence.ts
|
|
954
|
+
let generations = 0;
|
|
955
|
+
/** `rootDir` at its real path, where the filesystem reports spellings. */
|
|
956
|
+
function realRoot(rootDir) {
|
|
957
|
+
try {
|
|
958
|
+
return node_fs.realpathSync.native(rootDir);
|
|
959
|
+
} catch {
|
|
960
|
+
return rootDir;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* What the host's filesystem opens for `base` (spec §2.2 A2, A8): the first
|
|
965
|
+
* of its candidates, in the host's order, that the host opens. The
|
|
966
|
+
* filesystem decides what opens, and each name below the session root is
|
|
967
|
+
* checked against its own directory's listing (`seeOnDisk`); nothing is
|
|
968
|
+
* folded. Null where no candidate opens.
|
|
969
|
+
*
|
|
970
|
+
* A candidate the analysis holds answers before the filesystem is asked: an
|
|
971
|
+
* adapted original's analysis child need not exist on disk. A file the host
|
|
972
|
+
* opens that the analysis holds no module for is read as an adapted
|
|
973
|
+
* original (analysed as its first later child), an asset, or a file
|
|
974
|
+
* analysis never reads.
|
|
975
|
+
*/
|
|
976
|
+
function hostCandidate(rootDir, base, analysed, order, readings = {}, root = realRoot(rootDir)) {
|
|
977
|
+
const at = base.indexOf("?");
|
|
978
|
+
const query = at === -1 ? "" : base.slice(at);
|
|
979
|
+
const candidates = policyCandidates(at === -1 ? base : base.slice(0, at), { policy: order });
|
|
980
|
+
for (const [index, file] of candidates.entries()) {
|
|
981
|
+
const candidate = `${file}${query}`;
|
|
982
|
+
const opaque = () => readings.isAsset?.((0, node_path.join)(rootDir, file), query);
|
|
983
|
+
if (analysed.has(file)) return query !== "" && opaque() ? {
|
|
984
|
+
candidate,
|
|
985
|
+
actual: null,
|
|
986
|
+
analysedAs: null,
|
|
987
|
+
reading: "asset"
|
|
988
|
+
} : {
|
|
989
|
+
candidate,
|
|
990
|
+
actual: null,
|
|
991
|
+
analysedAs: file
|
|
992
|
+
};
|
|
993
|
+
const seen = seeOnDisk((0, node_path.join)(rootDir, file), rootDir);
|
|
994
|
+
if (seen.kind === "missing") continue;
|
|
995
|
+
if (seen.kind === "case-only") return {
|
|
996
|
+
candidate,
|
|
997
|
+
actual: (0, node_path.relative)(root, seen.actual),
|
|
998
|
+
analysedAs: null
|
|
999
|
+
};
|
|
1000
|
+
const children = readings.adapted?.get(file);
|
|
1001
|
+
if (children !== void 0) return {
|
|
1002
|
+
candidate,
|
|
1003
|
+
actual: null,
|
|
1004
|
+
analysedAs: candidates.slice(index + 1).find((later) => children.includes(later)) ?? null,
|
|
1005
|
+
reading: "adapted"
|
|
1006
|
+
};
|
|
1007
|
+
return {
|
|
1008
|
+
candidate,
|
|
1009
|
+
actual: null,
|
|
1010
|
+
analysedAs: null,
|
|
1011
|
+
reading: opaque() ? "asset" : "unanalysed"
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* The session's host-candidate evidence for one analysis (spec §2.3): each
|
|
1018
|
+
* probe base the engine's `prepare` names, as `hostCandidate` reads it, and
|
|
1019
|
+
* the host's expansion of each computed load it lists (spec §6.3). The
|
|
1020
|
+
* evidence carries the input identity `prepare` reported, and each call is a
|
|
1021
|
+
* new ingest generation, so no evidence is read for other files.
|
|
1022
|
+
*/
|
|
1023
|
+
function gatherProbeEvidence(rootDir, analysed, order, readings = {}) {
|
|
1024
|
+
const root = realRoot(rootDir);
|
|
1025
|
+
return (bases, identity, loads = []) => {
|
|
1026
|
+
const byBase = {};
|
|
1027
|
+
for (const base of bases) {
|
|
1028
|
+
const host = hostCandidate(rootDir, base, analysed, order, readings, root);
|
|
1029
|
+
if (host !== null) byBase[base] = host;
|
|
1030
|
+
}
|
|
1031
|
+
const expansions = readings.expander === void 0 ? [] : hostExpansions(loads, rootDir, analysed, readings.expander, readings.isAsset);
|
|
1032
|
+
generations += 1;
|
|
1033
|
+
return JSON.stringify({
|
|
1034
|
+
generation: generations,
|
|
1035
|
+
identity,
|
|
1036
|
+
bases: byBase,
|
|
1037
|
+
...expansions.length > 0 && { expansions }
|
|
1038
|
+
});
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
/** Each adapted original and its analysis children, from ingestion's
|
|
1042
|
+
* ownership: an original whose children are other paths than its own. */
|
|
1043
|
+
function adaptedOriginals(ownership) {
|
|
1044
|
+
return new Map(Object.entries(ownership).filter(([original, { analysisPaths }]) => !(analysisPaths.length === 1 && analysisPaths[0] === original)).map(([original, { analysisPaths }]) => [original, analysisPaths]));
|
|
1045
|
+
}
|
|
1046
|
+
//#endregion
|
|
747
1047
|
//#region pipeline/svelte-source-adapter.ts
|
|
748
1048
|
const isCompilerReference = (value) => Object(value) === value;
|
|
749
1049
|
const isCompilerCallable = (value) => {
|
|
@@ -841,14 +1141,14 @@ function sourceLocation(source, node) {
|
|
|
841
1141
|
function createsNestedBindingScope(node) {
|
|
842
1142
|
return node.type === "BlockStatement" || node.type === "CatchClause" || node.type === "ClassBody" || node.type === "ClassDeclaration" || node.type === "ClassExpression" || node.type === "ForInStatement" || node.type === "ForOfStatement" || node.type === "ForStatement" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "StaticBlock" || node.type === "SwitchStatement" || node.type === "TSModuleBlock";
|
|
843
1143
|
}
|
|
844
|
-
function walk(node, visit, nestedScopeDepth = 0) {
|
|
1144
|
+
function walk$1(node, visit, nestedScopeDepth = 0) {
|
|
845
1145
|
visit(node, nestedScopeDepth);
|
|
846
1146
|
const childScopeDepth = nestedScopeDepth + (createsNestedBindingScope(node) ? 1 : 0);
|
|
847
1147
|
for (const [key, value] of Object.entries(node)) {
|
|
848
1148
|
if (key === "loc" || key === "start" || key === "end") continue;
|
|
849
1149
|
if (Array.isArray(value)) {
|
|
850
|
-
for (const item of value) if (isNode(item)) walk(item, visit, childScopeDepth);
|
|
851
|
-
} else if (isNode(value)) walk(value, visit, childScopeDepth);
|
|
1150
|
+
for (const item of value) if (isNode(item)) walk$1(item, visit, childScopeDepth);
|
|
1151
|
+
} else if (isNode(value)) walk$1(value, visit, childScopeDepth);
|
|
852
1152
|
}
|
|
853
1153
|
}
|
|
854
1154
|
/**
|
|
@@ -1050,7 +1350,7 @@ function isJsxAttributeName(name) {
|
|
|
1050
1350
|
}
|
|
1051
1351
|
function tsxIncompatibleValue(value) {
|
|
1052
1352
|
let incompatible = null;
|
|
1053
|
-
walk(value, (node) => {
|
|
1353
|
+
walk$1(value, (node) => {
|
|
1054
1354
|
if (incompatible) return;
|
|
1055
1355
|
if (node.type === "TSTypeAssertion" || node.type === "ArrowFunctionExpression" && childNode(node.typeParameters) !== null) incompatible = node;
|
|
1056
1356
|
});
|
|
@@ -1147,7 +1447,7 @@ function projectScope(script, scope, source, originalPath, options, inherited, p
|
|
|
1147
1447
|
const bindings = inherited ? new Map([...inherited.bindings, ...ownBindings]) : ownBindings;
|
|
1148
1448
|
const witnesses = [];
|
|
1149
1449
|
const diagnostics = [];
|
|
1150
|
-
if (bindings.size > 0) walk(script.content, (node, nestedScopeDepth) => {
|
|
1450
|
+
if (bindings.size > 0) walk$1(script.content, (node, nestedScopeDepth) => {
|
|
1151
1451
|
const site = resolverCallSite(node, bindings);
|
|
1152
1452
|
if (!site) return;
|
|
1153
1453
|
const { access, form } = site;
|
|
@@ -1312,17 +1612,6 @@ function parseFilesJson(filesJson, context) {
|
|
|
1312
1612
|
function isAdvisorySourceDiagnostic(diagnostic) {
|
|
1313
1613
|
return diagnostic.code === "SOURCE_NATIVE_PARSE_ERROR";
|
|
1314
1614
|
}
|
|
1315
|
-
const RELATIVE_PROBE_SUFFIXES = [
|
|
1316
|
-
"",
|
|
1317
|
-
".ts",
|
|
1318
|
-
".tsx",
|
|
1319
|
-
".js",
|
|
1320
|
-
".jsx",
|
|
1321
|
-
"/index.ts",
|
|
1322
|
-
"/index.tsx",
|
|
1323
|
-
"/index.js",
|
|
1324
|
-
"/index.jsx"
|
|
1325
|
-
];
|
|
1326
1615
|
function extension(path) {
|
|
1327
1616
|
const basename = node_path.posix.basename(path);
|
|
1328
1617
|
const dot = basename.lastIndexOf(".");
|
|
@@ -1331,27 +1620,40 @@ function extension(path) {
|
|
|
1331
1620
|
function canonicalResolverPath(path) {
|
|
1332
1621
|
return node_path.posix.normalize(path.replaceAll("\\", "/"));
|
|
1333
1622
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
".tsx",
|
|
1338
|
-
".jsx"
|
|
1339
|
-
],
|
|
1340
|
-
".jsx": [".tsx"],
|
|
1341
|
-
".mjs": [".mts"],
|
|
1342
|
-
".cjs": [".cts"]
|
|
1343
|
-
};
|
|
1344
|
-
/** The paths a relative specifier can name from `importerPath`, in probe
|
|
1345
|
-
* order: as written with each source suffix, then a NodeNext emitted
|
|
1346
|
-
* extension's sources. Empty for a non-relative specifier. */
|
|
1347
|
-
function relativeSourceCandidates(importerPath, specifier) {
|
|
1623
|
+
/** The paths a relative specifier can name from `importerPath`, in the
|
|
1624
|
+
* extension policy's probe order. Empty for a non-relative specifier. */
|
|
1625
|
+
function relativeSourceCandidates(importerPath, specifier, policy) {
|
|
1348
1626
|
if (!specifier.startsWith(".")) return [];
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1627
|
+
return policyCandidates(node_path.posix.normalize(node_path.posix.join(node_path.posix.dirname(canonicalResolverPath(importerPath)), specifier)), { policy });
|
|
1628
|
+
}
|
|
1629
|
+
function resolveRelativeSource(importerPath, specifier, files, analysed, opened, policy, host) {
|
|
1630
|
+
if (host !== void 0 && specifier.startsWith(".")) {
|
|
1631
|
+
const first = hostCandidate(host.rootDir, node_path.posix.normalize(node_path.posix.join(node_path.posix.dirname(canonicalResolverPath(importerPath)), specifier)), analysed, policy, { adapted: host.adapted });
|
|
1632
|
+
if (first !== null) {
|
|
1633
|
+
if (first.actual) {
|
|
1634
|
+
opened({
|
|
1635
|
+
candidate: first.candidate,
|
|
1636
|
+
opened: first.actual,
|
|
1637
|
+
why: "case-mismatch"
|
|
1638
|
+
});
|
|
1639
|
+
return null;
|
|
1640
|
+
}
|
|
1641
|
+
if (first.reading === "unanalysed") {
|
|
1642
|
+
const candidates = relativeSourceCandidates(importerPath, specifier, policy);
|
|
1643
|
+
const later = candidates.slice(candidates.indexOf(first.candidate) + 1).find((candidate) => files.has(candidate));
|
|
1644
|
+
const opening = {
|
|
1645
|
+
candidate: first.candidate,
|
|
1646
|
+
opened: first.candidate,
|
|
1647
|
+
why: "skipped"
|
|
1648
|
+
};
|
|
1649
|
+
if (later !== void 0) opening.later = later;
|
|
1650
|
+
opened(opening);
|
|
1651
|
+
return null;
|
|
1652
|
+
}
|
|
1653
|
+
return first.analysedAs === null ? null : files.get(first.analysedAs) ?? null;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
for (const candidate of relativeSourceCandidates(importerPath, specifier, policy)) {
|
|
1355
1657
|
const actualPath = files.get(candidate);
|
|
1356
1658
|
if (actualPath !== void 0) return actualPath;
|
|
1357
1659
|
}
|
|
@@ -1359,15 +1661,22 @@ function resolveRelativeSource(importerPath, specifier, files) {
|
|
|
1359
1661
|
}
|
|
1360
1662
|
var ResolverExportIndex = class {
|
|
1361
1663
|
facts;
|
|
1664
|
+
extensions;
|
|
1665
|
+
host;
|
|
1362
1666
|
collisions;
|
|
1363
1667
|
files;
|
|
1668
|
+
analysed;
|
|
1669
|
+
/** Each resolver call that ended Incomplete, once. */
|
|
1670
|
+
openings = /* @__PURE__ */ new Map();
|
|
1364
1671
|
resolverBindings = /* @__PURE__ */ new Map();
|
|
1365
1672
|
/** Both memos live for one ingest only — the index is rebuilt per call,
|
|
1366
1673
|
* so neither needs invalidation. */
|
|
1367
1674
|
attributionMemo = /* @__PURE__ */ new Map();
|
|
1368
1675
|
resolveMemo = /* @__PURE__ */ new Map();
|
|
1369
|
-
constructor(facts, analysisPaths) {
|
|
1676
|
+
constructor(facts, analysisPaths, extensions, host) {
|
|
1370
1677
|
this.facts = facts;
|
|
1678
|
+
this.extensions = extensions;
|
|
1679
|
+
this.host = host;
|
|
1371
1680
|
const pathsByCanonical = /* @__PURE__ */ new Map();
|
|
1372
1681
|
for (const path of analysisPaths) {
|
|
1373
1682
|
const canonicalPath = canonicalResolverPath(path);
|
|
@@ -1392,6 +1701,7 @@ var ResolverExportIndex = class {
|
|
|
1392
1701
|
if (paths.length === 1 && factPaths.length === 1) files.set(canonicalPath, factPaths[0]);
|
|
1393
1702
|
}
|
|
1394
1703
|
this.files = files;
|
|
1704
|
+
this.analysed = new Set(files.keys());
|
|
1395
1705
|
for (const [path, file] of Object.entries(facts.files)) this.resolverBindings.set(path, new Set(file.chains.filter((chain) => chain.descriptor.terminal === "asClass" && chain.descriptor.extractable && chain.fatalError === null).map((chain) => chain.descriptor.binding)));
|
|
1396
1706
|
}
|
|
1397
1707
|
attribute(importerPath, request) {
|
|
@@ -1412,7 +1722,11 @@ var ResolverExportIndex = class {
|
|
|
1412
1722
|
const key = `${importerPath}\0${specifier}`;
|
|
1413
1723
|
let resolved = this.resolveMemo.get(key);
|
|
1414
1724
|
if (resolved === void 0) {
|
|
1415
|
-
resolved = resolveRelativeSource(importerPath, specifier, this.files)
|
|
1725
|
+
resolved = resolveRelativeSource(importerPath, specifier, this.files, this.analysed, (opening) => this.openings.set(key, {
|
|
1726
|
+
importer: importerPath,
|
|
1727
|
+
specifier,
|
|
1728
|
+
...opening
|
|
1729
|
+
}), this.extensions, this.host);
|
|
1416
1730
|
this.resolveMemo.set(key, resolved);
|
|
1417
1731
|
}
|
|
1418
1732
|
return resolved;
|
|
@@ -1534,7 +1848,10 @@ async function ingestSourceEntries(rawEntries, options) {
|
|
|
1534
1848
|
messages: file.parseDiagnostics
|
|
1535
1849
|
});
|
|
1536
1850
|
}
|
|
1537
|
-
const resolvers = new ResolverExportIndex(facts, analysisEntries.map((entry) => entry.path)
|
|
1851
|
+
const resolvers = new ResolverExportIndex(facts, analysisEntries.map((entry) => entry.path), options.extensions, options.rootDir === void 0 ? void 0 : {
|
|
1852
|
+
rootDir: options.rootDir,
|
|
1853
|
+
adapted: adaptedOriginals(ownership)
|
|
1854
|
+
});
|
|
1538
1855
|
for (const { canonicalPath, paths } of resolvers.collisions) for (let index = 0; index < paths.length; index += 1) {
|
|
1539
1856
|
const path = paths[index];
|
|
1540
1857
|
const conflictingPath = paths[(index + 1) % paths.length];
|
|
@@ -1569,13 +1886,14 @@ async function ingestSourceEntries(rawEntries, options) {
|
|
|
1569
1886
|
diagnostics
|
|
1570
1887
|
};
|
|
1571
1888
|
if (abortedParses.length > 0) result.abortedParses = abortedParses;
|
|
1889
|
+
if (resolvers.openings.size > 0) result.openings = [...resolvers.openings.values()];
|
|
1572
1890
|
return result;
|
|
1573
1891
|
}
|
|
1574
1892
|
/**
|
|
1575
1893
|
* `parseCount` counts the parses performed by THIS call, so a fully-memoized
|
|
1576
1894
|
* pass reports zero.
|
|
1577
1895
|
*/
|
|
1578
|
-
function collectFileFacts(analysisEntries, options) {
|
|
1896
|
+
function collectFileFacts(analysisEntries, options, evict = true) {
|
|
1579
1897
|
const cache = options.factsCache;
|
|
1580
1898
|
if (!cache) return JSON.parse(options.extractFacts(JSON.stringify(analysisEntries)));
|
|
1581
1899
|
const pending = analysisEntries.filter((entry) => cache.get(entry.path)?.hash !== entry.hash);
|
|
@@ -1592,8 +1910,10 @@ function collectFileFacts(analysisEntries, options) {
|
|
|
1592
1910
|
else cache.delete(entry.path);
|
|
1593
1911
|
}
|
|
1594
1912
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1913
|
+
if (evict) {
|
|
1914
|
+
const currentPaths = new Set(analysisEntries.map((entry) => entry.path));
|
|
1915
|
+
for (const path of [...cache.keys()]) if (!currentPaths.has(path)) cache.delete(path);
|
|
1916
|
+
}
|
|
1597
1917
|
const files = {};
|
|
1598
1918
|
for (const entry of analysisEntries) {
|
|
1599
1919
|
const cached = cache.get(entry.path);
|
|
@@ -1643,15 +1963,26 @@ function createSourceIngestor(host) {
|
|
|
1643
1963
|
/** Non-strict dedupe: a quarantined original re-ingests on every later
|
|
1644
1964
|
* corpus pass, so re-warning it on each save is noise. */
|
|
1645
1965
|
const warnedByOriginal = /* @__PURE__ */ new Map();
|
|
1966
|
+
const extractFacts = () => {
|
|
1967
|
+
const extract = host.engineApi().extractFacts;
|
|
1968
|
+
if (extract === void 0) throw new Error(`${host.prefix} native engine does not expose extractFacts required for source adaptation`);
|
|
1969
|
+
return extract;
|
|
1970
|
+
};
|
|
1646
1971
|
return {
|
|
1647
1972
|
async ingest(entries) {
|
|
1648
|
-
const extractFacts = host.engineApi().extractFacts;
|
|
1649
|
-
if (extractFacts === void 0) throw new Error(`${host.prefix} native engine does not expose extractFacts required for source adaptation`);
|
|
1650
1973
|
return ingestSourceEntries(entries, {
|
|
1651
|
-
extractFacts,
|
|
1652
|
-
factsCache
|
|
1974
|
+
extractFacts: extractFacts(),
|
|
1975
|
+
factsCache,
|
|
1976
|
+
extensions: host.extensions?.(),
|
|
1977
|
+
rootDir: host.rootDir?.()
|
|
1653
1978
|
});
|
|
1654
1979
|
},
|
|
1980
|
+
facts(entries) {
|
|
1981
|
+
return collectFileFacts(entries, {
|
|
1982
|
+
extractFacts: extractFacts(),
|
|
1983
|
+
factsCache
|
|
1984
|
+
}, false);
|
|
1985
|
+
},
|
|
1655
1986
|
surfaceDiagnostics(diagnostics) {
|
|
1656
1987
|
const fatal = diagnostics.filter((diagnostic) => !isAdvisorySourceDiagnostic(diagnostic));
|
|
1657
1988
|
const invalidOriginals = new Set(fatal.map((diagnostic) => diagnostic.originalPath));
|
|
@@ -1699,9 +2030,16 @@ function createV2EngineApi(deps) {
|
|
|
1699
2030
|
return {
|
|
1700
2031
|
loadSystemModule: (...args) => native.loadSystemModule(...args),
|
|
1701
2032
|
extractFacts: (filesJson) => native.extractFacts(filesJson),
|
|
1702
|
-
moduleSpecifiers: (filesJson) => native.moduleSpecifiers(filesJson),
|
|
2033
|
+
moduleSpecifiers: (filesJson, pathAliasesJson) => native.moduleSpecifiers(filesJson, pathAliasesJson),
|
|
2034
|
+
systemMembership: (inputsJson) => native.systemMembership(inputsJson),
|
|
1703
2035
|
diagnosticCodes: () => native.diagnosticCodes(),
|
|
1704
|
-
|
|
2036
|
+
resolveSpecifier: native.resolveSpecifier === void 0 ? void 0 : (specifier, fromDir, conditions, workspaces, extensionPolicyJson) => native.resolveSpecifier(specifier, fromDir, conditions, workspaces, extensionPolicyJson),
|
|
2037
|
+
fingerprintFile: native.fingerprintFile === void 0 ? void 0 : (path) => native.fingerprintFile(path) ?? null,
|
|
2038
|
+
fingerprintBytes: native.fingerprintBytes === void 0 ? void 0 : (bytes) => native.fingerprintBytes(bytes),
|
|
2039
|
+
declaresKitSource: native.declaresKitSource === void 0 ? void 0 : (packageDir) => native.declaresKitSource(packageDir),
|
|
2040
|
+
locatePackage: native.locatePackage === void 0 ? void 0 : (name, fromDir, workspaces) => native.locatePackage(name, fromDir, workspaces) ?? null,
|
|
2041
|
+
resolveKitSourceRoot: native.resolveKitSourceRoot === void 0 ? void 0 : (specifier, fromDir, conditions, workspaces, extensionPolicyJson, hostEntry, packageDir) => native.resolveKitSourceRoot(specifier, fromDir, conditions, workspaces, extensionPolicyJson, hostEntry, packageDir),
|
|
2042
|
+
analyzeProject: (filesJsonRaw, scalesJson, variableMapJson, contextualVarsJson, propConfigJson, groupRegistryJson, packageResolutionJson, devMode, emitterConfigJson, selectorAliasesJson, _selectorOrderJson, globalStyleBlocksJson, pathAliasesJson, keyframesJson, staticCssJson, conditionAliasesJson, externalDirsJson, transformSourcesJson, transformProvenanceJson, declarationScalesJson, analysisContextJson, generatedNamesJson, propertyRecordsJson, probeEvidence) => {
|
|
1705
2043
|
const filesJson = deps.rehydrateFilesJson ? deps.rehydrateFilesJson(filesJsonRaw) : filesJsonRaw;
|
|
1706
2044
|
const sent = /* @__PURE__ */ new Map();
|
|
1707
2045
|
for (const entry of parseFilesJson(filesJson, label)) sent.set(entry.path, entry.source);
|
|
@@ -1735,7 +2073,12 @@ function createV2EngineApi(deps) {
|
|
|
1735
2073
|
};
|
|
1736
2074
|
const engine = new native.ExtractEngine(config);
|
|
1737
2075
|
store.setEngine(engine);
|
|
1738
|
-
|
|
2076
|
+
let evidence;
|
|
2077
|
+
if (probeEvidence !== void 0) {
|
|
2078
|
+
const prepared = parseInternalWire(engine.prepare(filesJson), "ExtractEngine.prepare");
|
|
2079
|
+
evidence = probeEvidence(prepared.bases, prepared.identity, prepared.loads);
|
|
2080
|
+
}
|
|
2081
|
+
return engine.analyze(filesJson, evidence);
|
|
1739
2082
|
},
|
|
1740
2083
|
transformFile: (source, path, _manifest) => {
|
|
1741
2084
|
const engine = store.getEngine();
|
|
@@ -1761,10 +2104,112 @@ function createV2EngineApi(deps) {
|
|
|
1761
2104
|
};
|
|
1762
2105
|
}
|
|
1763
2106
|
//#endregion
|
|
1764
|
-
//#region pipeline/
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
2107
|
+
//#region pipeline/source-identity.ts
|
|
2108
|
+
/**
|
|
2109
|
+
* One derivation of source identity for discovery, watch ingestion, ownership
|
|
2110
|
+
* and deletion: event paths are lookup INPUTS only and never fork identity.
|
|
2111
|
+
*/
|
|
2112
|
+
/**
|
|
2113
|
+
* True when `target` is `root` or a descendant, decided by `relative()`
|
|
2114
|
+
* shape: string prefixing would let `/ui` claim `/ui-old`.
|
|
2115
|
+
*/
|
|
2116
|
+
function isPathWithinRoot(root, target, pathApi = node_path.default) {
|
|
2117
|
+
const rel = pathApi.relative(root, target);
|
|
2118
|
+
return rel === "" || !pathApi.isAbsolute(rel) && rel !== ".." && !rel.startsWith(".." + pathApi.sep);
|
|
2119
|
+
}
|
|
2120
|
+
/**
|
|
2121
|
+
* True when two paths share a platform root (win32 drive letter or UNC
|
|
2122
|
+
* share; always true on posix). Drive letters compare case-insensitively.
|
|
2123
|
+
*/
|
|
2124
|
+
function sharesVolumeRoot(a, b, pathApi = node_path.default) {
|
|
2125
|
+
const volumeOf = (p) => pathApi.parse(pathApi.resolve(p)).root.toLowerCase();
|
|
2126
|
+
return volumeOf(a) === volumeOf(b);
|
|
2127
|
+
}
|
|
2128
|
+
function canonicalize(p) {
|
|
2129
|
+
try {
|
|
2130
|
+
return (0, node_fs.realpathSync)(p);
|
|
2131
|
+
} catch {
|
|
2132
|
+
return null;
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
function createSourceIdentity(rootDir) {
|
|
2136
|
+
const normalizedRootDir = node_path.default.normalize(rootDir);
|
|
2137
|
+
const canonicalRootDir = canonicalize(normalizedRootDir) ?? normalizedRootDir;
|
|
2138
|
+
const roots = [];
|
|
2139
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
2140
|
+
const owningRecord = (canonicalPath) => {
|
|
2141
|
+
let owner = null;
|
|
2142
|
+
for (const record of roots) {
|
|
2143
|
+
if (!isPathWithinRoot(record.canonical, canonicalPath)) continue;
|
|
2144
|
+
if (!owner || record.canonical.length > owner.canonical.length) owner = record;
|
|
2145
|
+
}
|
|
2146
|
+
return owner;
|
|
2147
|
+
};
|
|
2148
|
+
return {
|
|
2149
|
+
rootDir: normalizedRootDir,
|
|
2150
|
+
canonicalRootDir,
|
|
2151
|
+
registerExternalRoot(root) {
|
|
2152
|
+
const asRegistered = node_path.default.normalize(root);
|
|
2153
|
+
const canonical = canonicalize(asRegistered) ?? asRegistered;
|
|
2154
|
+
const existing = roots.find((record) => record.canonical === canonical);
|
|
2155
|
+
if (existing) return existing.canonical;
|
|
2156
|
+
roots.push({
|
|
2157
|
+
asRegistered,
|
|
2158
|
+
canonical
|
|
2159
|
+
});
|
|
2160
|
+
return canonical;
|
|
2161
|
+
},
|
|
2162
|
+
externalRoots() {
|
|
2163
|
+
return roots.map((record) => record.canonical);
|
|
2164
|
+
},
|
|
2165
|
+
resolveSourceId(inputPath) {
|
|
2166
|
+
const lexical = node_path.default.normalize(inputPath);
|
|
2167
|
+
const canonical = canonicalize(lexical);
|
|
2168
|
+
if (canonical === null) return null;
|
|
2169
|
+
const owner = owningRecord(canonical);
|
|
2170
|
+
const ownedBy = (record) => {
|
|
2171
|
+
const pathInRoot = node_path.default.relative(record.canonical, canonical);
|
|
2172
|
+
return {
|
|
2173
|
+
sourceKey: node_path.default.relative(normalizedRootDir, node_path.default.join(record.asRegistered, pathInRoot)),
|
|
2174
|
+
owningRoot: record.canonical,
|
|
2175
|
+
pathInRoot
|
|
2176
|
+
};
|
|
2177
|
+
};
|
|
2178
|
+
const ownerIsMoreSpecific = owner !== null && owner.canonical.length > canonicalRootDir.length;
|
|
2179
|
+
let resolved;
|
|
2180
|
+
if (!ownerIsMoreSpecific && isPathWithinRoot(canonicalRootDir, canonical)) {
|
|
2181
|
+
const key = node_path.default.relative(canonicalRootDir, canonical);
|
|
2182
|
+
resolved = {
|
|
2183
|
+
sourceKey: key,
|
|
2184
|
+
owningRoot: null,
|
|
2185
|
+
pathInRoot: key
|
|
2186
|
+
};
|
|
2187
|
+
} else if (owner) resolved = ownedBy(owner);
|
|
2188
|
+
else return null;
|
|
2189
|
+
aliases.set(lexical, resolved);
|
|
2190
|
+
aliases.set(canonical, resolved);
|
|
2191
|
+
return resolved;
|
|
2192
|
+
},
|
|
2193
|
+
resolveDeletedSourceId(inputPath) {
|
|
2194
|
+
return aliases.get(node_path.default.normalize(inputPath)) ?? null;
|
|
2195
|
+
},
|
|
2196
|
+
containingExternalRoot(inputPath) {
|
|
2197
|
+
const lexical = node_path.default.normalize(inputPath);
|
|
2198
|
+
let owner = null;
|
|
2199
|
+
for (const record of roots) {
|
|
2200
|
+
if (!(isPathWithinRoot(record.canonical, lexical) || isPathWithinRoot(record.asRegistered, lexical))) continue;
|
|
2201
|
+
if (!owner || record.canonical.length > owner.canonical.length) owner = record;
|
|
2202
|
+
}
|
|
2203
|
+
if (owner) return owner.canonical;
|
|
2204
|
+
const canonical = canonicalize(lexical);
|
|
2205
|
+
if (canonical === null) return null;
|
|
2206
|
+
for (const record of roots) {
|
|
2207
|
+
if (!isPathWithinRoot(record.canonical, canonical)) continue;
|
|
2208
|
+
if (!owner || record.canonical.length > owner.canonical.length) owner = record;
|
|
2209
|
+
}
|
|
2210
|
+
return owner?.canonical ?? null;
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
1768
2213
|
}
|
|
1769
2214
|
//#endregion
|
|
1770
2215
|
//#region pipeline/core-options.ts
|
|
@@ -1873,6 +2318,11 @@ const CORE_VALUE_GATES = [
|
|
|
1873
2318
|
ok: isString,
|
|
1874
2319
|
expected: "a string path"
|
|
1875
2320
|
},
|
|
2321
|
+
{
|
|
2322
|
+
key: "root",
|
|
2323
|
+
ok: isString,
|
|
2324
|
+
expected: "a string path"
|
|
2325
|
+
},
|
|
1876
2326
|
{
|
|
1877
2327
|
key: "exclude",
|
|
1878
2328
|
ok: isStringArray,
|
|
@@ -1991,30 +2441,101 @@ function globToRegExp(glob) {
|
|
|
1991
2441
|
}
|
|
1992
2442
|
return new RegExp(`^${out}$`);
|
|
1993
2443
|
}
|
|
2444
|
+
/** Whether a root-relative path is `dir` or lies under it, a literal path
|
|
2445
|
+
* prefix: an output name is never a pattern. */
|
|
2446
|
+
function compileOutputDir(dir) {
|
|
2447
|
+
return (_full, rel) => {
|
|
2448
|
+
const normalized = rel.split("\\").join("/");
|
|
2449
|
+
return normalized === dir || normalized.startsWith(`${dir}/`);
|
|
2450
|
+
};
|
|
2451
|
+
}
|
|
1994
2452
|
/**
|
|
1995
|
-
* A user list replaces only the replaceable defaults.
|
|
1996
|
-
*
|
|
2453
|
+
* A user list replaces only the replaceable defaults. A host's output
|
|
2454
|
+
* directories (`outputExclusion`) always apply, whatever the user's list.
|
|
1997
2455
|
*/
|
|
1998
|
-
function createExcludeMatcher(userPatterns,
|
|
1999
|
-
const
|
|
2000
|
-
|
|
2001
|
-
for (const pattern of
|
|
2002
|
-
|
|
2003
|
-
|
|
2456
|
+
function createExcludeMatcher(userPatterns, outputDirs = []) {
|
|
2457
|
+
const userList = userPatterns ?? REPLACEABLE_DEFAULT_EXCLUDE;
|
|
2458
|
+
const compiled = [];
|
|
2459
|
+
for (const pattern of STRUCTURAL_EXCLUDE) compiled.push({
|
|
2460
|
+
pattern,
|
|
2461
|
+
test: compilePattern(pattern),
|
|
2462
|
+
isUser: userList.includes(pattern)
|
|
2463
|
+
});
|
|
2464
|
+
for (const dir of outputDirs) compiled.push({
|
|
2465
|
+
pattern: dir,
|
|
2466
|
+
test: compileOutputDir(dir),
|
|
2467
|
+
isUser: false
|
|
2468
|
+
});
|
|
2469
|
+
for (const pattern of userList) {
|
|
2470
|
+
if (STRUCTURAL_EXCLUDE.includes(pattern)) continue;
|
|
2471
|
+
compiled.push({
|
|
2472
|
+
pattern,
|
|
2473
|
+
test: compilePattern(pattern),
|
|
2474
|
+
isUser: true
|
|
2475
|
+
});
|
|
2476
|
+
}
|
|
2477
|
+
const hits = new Map(compiled.map((c) => [c.pattern, 0]));
|
|
2004
2478
|
const explain = (full, rel) => {
|
|
2005
|
-
|
|
2479
|
+
let excludedBy = null;
|
|
2480
|
+
for (const { pattern, test, isUser } of compiled) {
|
|
2481
|
+
if (excludedBy !== null && !isUser) continue;
|
|
2482
|
+
if (!test(full, rel)) continue;
|
|
2006
2483
|
hits.set(pattern, (hits.get(pattern) ?? 0) + 1);
|
|
2007
|
-
|
|
2484
|
+
excludedBy ??= pattern;
|
|
2008
2485
|
}
|
|
2009
|
-
return
|
|
2486
|
+
return excludedBy;
|
|
2010
2487
|
};
|
|
2011
2488
|
return {
|
|
2012
|
-
patterns:
|
|
2489
|
+
patterns: compiled.map((c) => c.pattern),
|
|
2013
2490
|
matches: (full, rel) => explain(full, rel) !== null,
|
|
2014
2491
|
explain,
|
|
2015
|
-
stats: () => hits
|
|
2492
|
+
stats: () => hits,
|
|
2493
|
+
unmatched: () => (userPatterns ?? []).filter((pattern) => hits.get(pattern) === 0)
|
|
2494
|
+
};
|
|
2495
|
+
}
|
|
2496
|
+
/** One line per user pattern that matched nothing, which every host
|
|
2497
|
+
* prints to stderr after its first discovery, as the CLI always has. */
|
|
2498
|
+
function unmatchedExcludeLines(matcher) {
|
|
2499
|
+
return matcher.unmatched().map((pattern) => `[animus] exclude pattern '${pattern}' matched nothing`);
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* A host's output directory as an exclusion: root-relative with `/`
|
|
2503
|
+
* separators, matched as a literal path prefix, so a user list, which
|
|
2504
|
+
* replaces the defaults, never re-admits output. Null when the directory is
|
|
2505
|
+
* outside the root or is the root itself.
|
|
2506
|
+
*/
|
|
2507
|
+
function outputExclusion(root, outDir) {
|
|
2508
|
+
if (!isPathWithinRoot(root, outDir)) return null;
|
|
2509
|
+
const rel = (0, path.relative)(root, outDir);
|
|
2510
|
+
return rel === "" ? null : rel.split(path.sep).join("/");
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* The output directory a source file's real path lies in, or null. Applied
|
|
2514
|
+
* where a host assembles its analysis inputs: a file reached under another
|
|
2515
|
+
* spelling, through a source-tree link or a package's entry, is output too.
|
|
2516
|
+
*/
|
|
2517
|
+
function outputSourceGuard(root, outputDirs) {
|
|
2518
|
+
if (outputDirs.length === 0) return () => null;
|
|
2519
|
+
const realDirs = outputDirs.map((dir) => ({
|
|
2520
|
+
dir,
|
|
2521
|
+
real: realPathOf((0, path.resolve)(root, dir))
|
|
2522
|
+
}));
|
|
2523
|
+
return (absPath) => {
|
|
2524
|
+
const real = realPathOf(absPath);
|
|
2525
|
+
return realDirs.find((o) => isPathWithinRoot(o.real, real))?.dir ?? null;
|
|
2016
2526
|
};
|
|
2017
2527
|
}
|
|
2528
|
+
/** The warning for a source a host refused as output. */
|
|
2529
|
+
function outputSourceMessage(relPath, outputDir) {
|
|
2530
|
+
return `${relPath} resolves into the output directory '${outputDir}', which is never source; it is not analysed`;
|
|
2531
|
+
}
|
|
2532
|
+
function realPathOf(path$8) {
|
|
2533
|
+
try {
|
|
2534
|
+
return (0, fs.realpathSync)(path$8);
|
|
2535
|
+
} catch {
|
|
2536
|
+
return path$8;
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2018
2539
|
function resolveMode(explicit, driverDefault) {
|
|
2019
2540
|
if (explicit === "development" || explicit === "production") return {
|
|
2020
2541
|
mode: explicit,
|
|
@@ -2026,18 +2547,92 @@ function resolveMode(explicit, driverDefault) {
|
|
|
2026
2547
|
};
|
|
2027
2548
|
}
|
|
2028
2549
|
//#endregion
|
|
2029
|
-
//#region pipeline/
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2550
|
+
//#region pipeline/engine-retirement.ts
|
|
2551
|
+
const RETIRED_ENGINE_MESSAGE = "animus: the 'v1' extraction engine is no longer supported, and v2 is the only engine. Remove the engine option from your Animus config and unset the ANIMUS_ENGINE environment variable.";
|
|
2552
|
+
/**
|
|
2553
|
+
* v2 is the only engine (SA2): the option and `ANIMUS_ENGINE`, a startup
|
|
2554
|
+
* input a worker may pass as captured, accept `v2` or nothing. Hosts call
|
|
2555
|
+
* this before the native module loads, so another selection never reaches
|
|
2556
|
+
* it; either fails as a configuration error naming its source.
|
|
2557
|
+
*/
|
|
2558
|
+
function assertSupportedEngine(engineOption, environmentSelection = process.env.ANIMUS_ENGINE) {
|
|
2559
|
+
const selections = [[engineOption, "the engine option"], [environmentSelection || void 0, "ANIMUS_ENGINE"]];
|
|
2560
|
+
for (const [selection, source] of selections) {
|
|
2561
|
+
if (selection === void 0 || selection === "v2") continue;
|
|
2562
|
+
if (selection === "v1") throw new AnimusConfigError(`${RETIRED_ENGINE_MESSAGE} (from ${source})`);
|
|
2563
|
+
throw new AnimusConfigError(`animus: unknown extraction engine "${selection}" from ${source}: v2 is the only engine.`);
|
|
2039
2564
|
}
|
|
2040
|
-
|
|
2565
|
+
}
|
|
2566
|
+
//#endregion
|
|
2567
|
+
//#region pipeline/asset-copies.ts
|
|
2568
|
+
/**
|
|
2569
|
+
* Immutable asset copies: one binding from an `asset()` source file to a
|
|
2570
|
+
* content-digested name, shared by every host that serves copies.
|
|
2571
|
+
*/
|
|
2572
|
+
/** Copies `sourcePath` into `assetsDir` under its content-digested name,
|
|
2573
|
+
* once: a copy is never overwritten, so a URL naming it always serves the
|
|
2574
|
+
* bytes it named. */
|
|
2575
|
+
function writeAssetCopy(sourcePath, assetsDir) {
|
|
2576
|
+
const bytes = (0, fs.readFileSync)(sourcePath);
|
|
2577
|
+
const digest = contentHash(bytes);
|
|
2578
|
+
const ext = (0, path.extname)(sourcePath);
|
|
2579
|
+
const fileName = `${(0, path.basename)(sourcePath, ext)}.${digest.slice(0, 8)}${ext}`;
|
|
2580
|
+
if (!(0, fs.existsSync)(assetsDir)) (0, fs.mkdirSync)(assetsDir, { recursive: true });
|
|
2581
|
+
const copyPath = (0, path.join)(assetsDir, fileName);
|
|
2582
|
+
if (!(0, fs.existsSync)(copyPath)) (0, fs.writeFileSync)(copyPath, bytes);
|
|
2583
|
+
return {
|
|
2584
|
+
fileName,
|
|
2585
|
+
digest,
|
|
2586
|
+
bytes
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2589
|
+
/** Sync `assets/` to the current build's file set; per-entry failures are
|
|
2590
|
+
* tolerated — a concurrent session may have removed the same file. */
|
|
2591
|
+
function pruneStaleAssets(assetsDir, expected) {
|
|
2592
|
+
if (!(0, fs.existsSync)(assetsDir)) return;
|
|
2593
|
+
let entries;
|
|
2594
|
+
try {
|
|
2595
|
+
entries = (0, fs.readdirSync)(assetsDir);
|
|
2596
|
+
} catch {
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
2599
|
+
for (const entry of entries) {
|
|
2600
|
+
if (expected.has(entry)) continue;
|
|
2601
|
+
try {
|
|
2602
|
+
(0, fs.unlinkSync)((0, path.join)(assetsDir, entry));
|
|
2603
|
+
} catch {}
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
//#endregion
|
|
2607
|
+
//#region pipeline/runtime-import.ts
|
|
2608
|
+
/** The runtime every adapter emits by default (spine row 1). */
|
|
2609
|
+
const DEFAULT_RUNTIME_IMPORT = "@animus-ui/system/runtime";
|
|
2610
|
+
/** The entries that supply every terminal: an override naming another must
|
|
2611
|
+
* extract only `.asClass()` terminals. */
|
|
2612
|
+
const FULL_RUNTIME_IMPORTS = /* @__PURE__ */ new Set([DEFAULT_RUNTIME_IMPORT, "@animus-ui/system"]);
|
|
2613
|
+
/** Throws when `runtimeImport` names a module that cannot supply a
|
|
2614
|
+
* terminal the manifest extracted. */
|
|
2615
|
+
function assertRuntimeImportSuppliesTerminals(runtimeImport, manifest) {
|
|
2616
|
+
if (!runtimeImport || FULL_RUNTIME_IMPORTS.has(runtimeImport)) return;
|
|
2617
|
+
const offenders = [];
|
|
2618
|
+
for (const [id, descriptor] of Object.entries(manifest.components)) if (/\bcreateComponent\(|\bcreateComposedFamily\(/.test(descriptor.replacement)) offenders.push(id);
|
|
2619
|
+
if (offenders.length === 0) return;
|
|
2620
|
+
const shown = offenders.slice(0, 5).join(", ");
|
|
2621
|
+
throw new Error(`[animus-extract] runtimeImport '${runtimeImport}' is valid only when every extracted terminal is .asClass(), but ${offenders.length} component(s) need createComponent/createComposedFamily from the default '${DEFAULT_RUNTIME_IMPORT}' runtime: ${shown}` + (offenders.length > 5 ? ", …" : "") + `. Remove the override or convert these terminals to .asClass().`);
|
|
2622
|
+
}
|
|
2623
|
+
//#endregion
|
|
2624
|
+
//#region pipeline/discover-files.ts
|
|
2625
|
+
function pathCharRank(code) {
|
|
2626
|
+
return code === 47 || code === 92 ? -1 : code;
|
|
2627
|
+
}
|
|
2628
|
+
function compareDiscoveryOrder(a, b) {
|
|
2629
|
+
const shared = Math.min(a.length, b.length);
|
|
2630
|
+
for (let i = 0; i < shared; i++) {
|
|
2631
|
+
const left = pathCharRank(a.charCodeAt(i));
|
|
2632
|
+
const right = pathCharRank(b.charCodeAt(i));
|
|
2633
|
+
if (left !== right) return left - right;
|
|
2634
|
+
}
|
|
2635
|
+
return a.length - b.length;
|
|
2041
2636
|
}
|
|
2042
2637
|
function discoverFiles(dir, rootDir, exclude, extensionsSet) {
|
|
2043
2638
|
return walkFiles(dir, rootDir, exclude, extensionsSet).sort(compareDiscoveryOrder);
|
|
@@ -2066,6 +2661,161 @@ function walkFiles(dir, rootDir, exclude, extensionsSet) {
|
|
|
2066
2661
|
return results;
|
|
2067
2662
|
}
|
|
2068
2663
|
//#endregion
|
|
2664
|
+
//#region pipeline/host-extensions.ts
|
|
2665
|
+
/** Animus's own order, where no host resolver configuration exists. */
|
|
2666
|
+
const BUILT_IN_EXTENSION_POLICY = {
|
|
2667
|
+
appended: EXTENSION_POLICY.appended,
|
|
2668
|
+
nodeNext: EXTENSION_POLICY.nodeNext,
|
|
2669
|
+
alias: [],
|
|
2670
|
+
resolverVersion: "built-in"
|
|
2671
|
+
};
|
|
2672
|
+
/** The TypeScript output a source compiles to, as a host that resolves an
|
|
2673
|
+
* emitted extension to its TypeScript source reads it. */
|
|
2674
|
+
const TYPESCRIPT_OUTPUTS = [
|
|
2675
|
+
[".js", [".ts", ".tsx"]],
|
|
2676
|
+
[".jsx", [".tsx"]],
|
|
2677
|
+
[".mjs", [".mts"]],
|
|
2678
|
+
[".cjs", [".cts"]]
|
|
2679
|
+
];
|
|
2680
|
+
/** esbuild's rewritten file extensions, which also let `.jsx` name `.ts`. */
|
|
2681
|
+
const ESBUILD_OUTPUTS = [
|
|
2682
|
+
[".js", [".ts", ".tsx"]],
|
|
2683
|
+
[".jsx", [".ts", ".tsx"]],
|
|
2684
|
+
[".mjs", [".mts"]],
|
|
2685
|
+
[".cjs", [".cts"]]
|
|
2686
|
+
];
|
|
2687
|
+
/** Documented defaults, for a host whose resolved order is not readable. */
|
|
2688
|
+
const HOST_DEFAULT_EXTENSIONS = {
|
|
2689
|
+
vite: [
|
|
2690
|
+
".mjs",
|
|
2691
|
+
".js",
|
|
2692
|
+
".mts",
|
|
2693
|
+
".ts",
|
|
2694
|
+
".jsx",
|
|
2695
|
+
".tsx",
|
|
2696
|
+
".json"
|
|
2697
|
+
],
|
|
2698
|
+
webpack: [
|
|
2699
|
+
".js",
|
|
2700
|
+
".json",
|
|
2701
|
+
".wasm"
|
|
2702
|
+
],
|
|
2703
|
+
/** Rspack 1's documented default; later versions document another. */
|
|
2704
|
+
rspack1: [
|
|
2705
|
+
".js",
|
|
2706
|
+
".json",
|
|
2707
|
+
".wasm"
|
|
2708
|
+
],
|
|
2709
|
+
turbopack: [
|
|
2710
|
+
".tsx",
|
|
2711
|
+
".ts",
|
|
2712
|
+
".jsx",
|
|
2713
|
+
".js",
|
|
2714
|
+
".mjs",
|
|
2715
|
+
".json"
|
|
2716
|
+
],
|
|
2717
|
+
esbuild: [
|
|
2718
|
+
".tsx",
|
|
2719
|
+
".ts",
|
|
2720
|
+
".jsx",
|
|
2721
|
+
".js",
|
|
2722
|
+
".css",
|
|
2723
|
+
".json"
|
|
2724
|
+
]
|
|
2725
|
+
};
|
|
2726
|
+
function label(host, version, how) {
|
|
2727
|
+
return `${version ? `${host}@${version}` : host} ${how}`;
|
|
2728
|
+
}
|
|
2729
|
+
/** Vite's `resolve.extensions`, which `configResolved` holds with its
|
|
2730
|
+
* defaults applied. A TypeScript importer's `./x.js` names `x.ts` too.
|
|
2731
|
+
* Only the default order is captured, as a real build resolves it. A
|
|
2732
|
+
* configured list does not describe Vite's effective resolution: Vite 8's
|
|
2733
|
+
* resolver falls back past it (`['.js']` still loads `./only` as
|
|
2734
|
+
* `only.tsx`), so it is unreadable. */
|
|
2735
|
+
function viteExtensionPolicy(extensions, version) {
|
|
2736
|
+
if (extensions.length !== HOST_DEFAULT_EXTENSIONS.vite.length || extensions.some((ext, i) => ext !== HOST_DEFAULT_EXTENSIONS.vite[i])) return {
|
|
2737
|
+
...BUILT_IN_EXTENSION_POLICY,
|
|
2738
|
+
resolverVersion: "built-in (hostOptionUnreadable: vite configured extensions)"
|
|
2739
|
+
};
|
|
2740
|
+
return {
|
|
2741
|
+
appended: [...extensions],
|
|
2742
|
+
nodeNext: TYPESCRIPT_OUTPUTS,
|
|
2743
|
+
alias: [],
|
|
2744
|
+
resolverVersion: label("vite", version, "captured")
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
/** webpack's or Rspack's resolved order for an ESM import: the root
|
|
2748
|
+
* `resolve` with `byDependency.esm` merged over it as the bundler merges
|
|
2749
|
+
* it, a `...` standing for what it extends. `extensionAlias` is kept whole
|
|
2750
|
+
* and in order. Where neither sets extensions, the bundler's documented
|
|
2751
|
+
* default stands in; for Rspack only version 1's is known. */
|
|
2752
|
+
function webpackExtensionPolicy(host, resolve, version) {
|
|
2753
|
+
const esm = resolve.byDependency?.esm;
|
|
2754
|
+
const unset = resolve.extensions === void 0 && esm?.extensions === void 0;
|
|
2755
|
+
const defaults = !(host === "rspack") ? HOST_DEFAULT_EXTENSIONS.webpack : version?.startsWith("1.") ? HOST_DEFAULT_EXTENSIONS.rspack1 : null;
|
|
2756
|
+
if ([...Object.values(resolve.extensionAlias ?? {}), ...Object.values(esm?.extensionAlias ?? {})].some((value) => !Array.isArray(value))) return {
|
|
2757
|
+
...BUILT_IN_EXTENSION_POLICY,
|
|
2758
|
+
resolverVersion: "built-in (hostOptionUnreadable: string extensionAlias)"
|
|
2759
|
+
};
|
|
2760
|
+
const extendsBase = (list) => list === void 0 || list.includes("...");
|
|
2761
|
+
if (defaults === null && extendsBase(esm?.extensions) && extendsBase(resolve.extensions)) return {
|
|
2762
|
+
...BUILT_IN_EXTENSION_POLICY,
|
|
2763
|
+
resolverVersion: `built-in (hostOptionUnreadable: ${host}${version ? `@${version}` : ""} defaults)`
|
|
2764
|
+
};
|
|
2765
|
+
const extend = (list, base) => list === void 0 ? base : list.flatMap((extension) => extension === "..." ? base : [extension]);
|
|
2766
|
+
const root = extend(resolve.extensions, defaults ?? []);
|
|
2767
|
+
const sequence = (value) => Array.isArray(value) ? value : [value];
|
|
2768
|
+
const alias = new Map(Object.entries(resolve.extensionAlias ?? {}).map(([emitted, value]) => [emitted, sequence(value).filter((extension) => extension !== "...")]));
|
|
2769
|
+
for (const [emitted, value] of Object.entries(esm?.extensionAlias ?? {})) {
|
|
2770
|
+
const base = alias.get(emitted) ?? [];
|
|
2771
|
+
alias.set(emitted, sequence(value).flatMap((extension) => extension === "..." ? base : [extension]));
|
|
2772
|
+
}
|
|
2773
|
+
return {
|
|
2774
|
+
appended: [...extend(esm?.extensions, root)],
|
|
2775
|
+
nodeNext: [],
|
|
2776
|
+
alias: [...alias].map(([emitted, extensions]) => [emitted, [...extensions]]),
|
|
2777
|
+
resolverVersion: label(host, version, unset ? "default" : "captured")
|
|
2778
|
+
};
|
|
2779
|
+
}
|
|
2780
|
+
/** Turbopack's `turbopack.resolveExtensions`, or its documented default
|
|
2781
|
+
* when the Next config sets none. It substitutes no source: under Next
|
|
2782
|
+
* 16.3, `./x.js` beside only `x.ts` names no module. */
|
|
2783
|
+
function turbopackExtensionPolicy(resolveExtensions, nextVersion) {
|
|
2784
|
+
return {
|
|
2785
|
+
appended: [...resolveExtensions ?? HOST_DEFAULT_EXTENSIONS.turbopack],
|
|
2786
|
+
nodeNext: [],
|
|
2787
|
+
alias: [],
|
|
2788
|
+
resolverVersion: label("turbopack", nextVersion, resolveExtensions === void 0 ? "default" : "captured")
|
|
2789
|
+
};
|
|
2790
|
+
}
|
|
2791
|
+
/** esbuild's `resolveExtensions`, or its default when the build sets none. */
|
|
2792
|
+
function esbuildExtensionPolicy(resolveExtensions, version) {
|
|
2793
|
+
return {
|
|
2794
|
+
appended: [...resolveExtensions ?? HOST_DEFAULT_EXTENSIONS.esbuild],
|
|
2795
|
+
nodeNext: ESBUILD_OUTPUTS,
|
|
2796
|
+
alias: [],
|
|
2797
|
+
resolverVersion: label("esbuild", version, resolveExtensions === void 0 ? "default" : "captured")
|
|
2798
|
+
};
|
|
2799
|
+
}
|
|
2800
|
+
/** Rollup leaves the extension order to its resolver plugins, which keep
|
|
2801
|
+
* their options private: a TypeScript build sets `@rollup/plugin-node-resolve`'s
|
|
2802
|
+
* `extensions`, which no documented default matches. The built-in policy
|
|
2803
|
+
* answers, with the reason. */
|
|
2804
|
+
function rollupExtensionPolicy(usesNodeResolve) {
|
|
2805
|
+
return {
|
|
2806
|
+
...BUILT_IN_EXTENSION_POLICY,
|
|
2807
|
+
resolverVersion: usesNodeResolve ? "built-in (hostOptionUnreadable: rollup-node-resolve)" : "built-in (hostOptionUnreadable: rollup resolver plugins)"
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
/** The policy as the system loader reads it (`ExtensionPolicy`). */
|
|
2811
|
+
function extensionPolicyJson(policy) {
|
|
2812
|
+
return JSON.stringify({
|
|
2813
|
+
appended: policy.appended,
|
|
2814
|
+
nodeNext: policy.nodeNext,
|
|
2815
|
+
alias: policy.alias
|
|
2816
|
+
});
|
|
2817
|
+
}
|
|
2818
|
+
//#endregion
|
|
2069
2819
|
//#region pipeline/tsconfig-paths.ts
|
|
2070
2820
|
/**
|
|
2071
2821
|
* tsconfig `paths` → alias pairs, for drivers with no live bundler config.
|
|
@@ -2149,10 +2899,10 @@ function decodePaths(value) {
|
|
|
2149
2899
|
function decodeExtends(value) {
|
|
2150
2900
|
return (Array.isArray(value) ? value : [value]).filter(isJsonString);
|
|
2151
2901
|
}
|
|
2152
|
-
function readConfig(path$
|
|
2902
|
+
function readConfig(path$6) {
|
|
2153
2903
|
let raw;
|
|
2154
2904
|
try {
|
|
2155
|
-
raw = (0, fs.readFileSync)(path$
|
|
2905
|
+
raw = (0, fs.readFileSync)(path$6, "utf-8");
|
|
2156
2906
|
} catch {
|
|
2157
2907
|
return null;
|
|
2158
2908
|
}
|
|
@@ -2165,22 +2915,33 @@ function readConfig(path$8) {
|
|
|
2165
2915
|
const root = isJsonBlock(parsed) ? parsed : {};
|
|
2166
2916
|
const compilerOptions = isJsonBlock(root.compilerOptions) ? root.compilerOptions : {};
|
|
2167
2917
|
return {
|
|
2168
|
-
dir: (0, path.dirname)(path$
|
|
2918
|
+
dir: (0, path.dirname)(path$6),
|
|
2169
2919
|
baseUrl: isJsonString(compilerOptions.baseUrl) ? compilerOptions.baseUrl : null,
|
|
2170
2920
|
paths: decodePaths(compilerOptions.paths),
|
|
2171
2921
|
extends: decodeExtends(root.extends)
|
|
2172
2922
|
};
|
|
2173
2923
|
}
|
|
2174
|
-
|
|
2924
|
+
/** Where an `extends` specifier can name a config: a relative one as
|
|
2925
|
+
* written, with `.json`, or as a directory's tsconfig; a package's under
|
|
2926
|
+
* each ancestor's `node_modules`. Resolution takes the first that exists. */
|
|
2927
|
+
function extendsCandidates(specifier, fromDir) {
|
|
2175
2928
|
if (specifier.startsWith(".") || (0, path.isAbsolute)(specifier)) {
|
|
2176
2929
|
const base = (0, path.resolve)(fromDir, specifier);
|
|
2177
|
-
|
|
2930
|
+
return [
|
|
2178
2931
|
base,
|
|
2179
2932
|
`${base}.json`,
|
|
2180
2933
|
(0, path.join)(base, "tsconfig.json")
|
|
2181
|
-
]
|
|
2182
|
-
|
|
2934
|
+
];
|
|
2935
|
+
}
|
|
2936
|
+
const target = specifier.endsWith(".json") ? specifier : `${specifier}/tsconfig.json`;
|
|
2937
|
+
const candidates = [];
|
|
2938
|
+
for (let dir = (0, path.resolve)(fromDir);; dir = (0, path.dirname)(dir)) {
|
|
2939
|
+
candidates.push((0, path.join)(dir, "node_modules", target));
|
|
2940
|
+
if ((0, path.dirname)(dir) === dir) return candidates;
|
|
2183
2941
|
}
|
|
2942
|
+
}
|
|
2943
|
+
function resolveExtendsTarget(specifier, fromDir) {
|
|
2944
|
+
if (specifier.startsWith(".") || (0, path.isAbsolute)(specifier)) return extendsCandidates(specifier, fromDir).find((candidate) => (0, fs.existsSync)(candidate)) ?? null;
|
|
2184
2945
|
try {
|
|
2185
2946
|
return require.resolve(specifier.endsWith(".json") ? specifier : `${specifier}/tsconfig.json`, { paths: [fromDir] });
|
|
2186
2947
|
} catch {
|
|
@@ -2192,13 +2953,12 @@ function resolveExtendsTarget(specifier, fromDir) {
|
|
|
2192
2953
|
}
|
|
2193
2954
|
}
|
|
2194
2955
|
/** Child-first flattened extends chain starting at `entryPath`. */
|
|
2195
|
-
function loadChain(entryPath) {
|
|
2956
|
+
function loadChain(entryPath, visited = /* @__PURE__ */ new Set(), absent = /* @__PURE__ */ new Set()) {
|
|
2196
2957
|
const chain = [];
|
|
2197
|
-
const visited = /* @__PURE__ */ new Set();
|
|
2198
2958
|
const queue = [entryPath];
|
|
2199
2959
|
while (queue.length > 0) {
|
|
2200
|
-
const path$
|
|
2201
|
-
const key = (0, path.resolve)(path$
|
|
2960
|
+
const path$7 = queue.shift();
|
|
2961
|
+
const key = (0, path.resolve)(path$7);
|
|
2202
2962
|
if (visited.has(key)) continue;
|
|
2203
2963
|
visited.add(key);
|
|
2204
2964
|
const node = readConfig(key);
|
|
@@ -2207,10 +2967,20 @@ function loadChain(entryPath) {
|
|
|
2207
2967
|
for (const parent of node.extends) {
|
|
2208
2968
|
const resolved = resolveExtendsTarget(parent, node.dir);
|
|
2209
2969
|
if (resolved) queue.push(resolved);
|
|
2970
|
+
else for (const candidate of extendsCandidates(parent, node.dir)) absent.add(candidate);
|
|
2210
2971
|
}
|
|
2211
2972
|
}
|
|
2212
2973
|
return chain;
|
|
2213
2974
|
}
|
|
2975
|
+
/** Every tsconfig file the project's alias chain reads or looks for, absent
|
|
2976
|
+
* ones included, an unresolved `extends` target's candidates among them:
|
|
2977
|
+
* an edit, creation or deletion of any changes the aliases. */
|
|
2978
|
+
function tsconfigChainPaths(rootDir) {
|
|
2979
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2980
|
+
const absent = /* @__PURE__ */ new Set();
|
|
2981
|
+
loadChain((0, path.join)(rootDir, "tsconfig.json"), visited, absent);
|
|
2982
|
+
return [...visited, ...absent];
|
|
2983
|
+
}
|
|
2214
2984
|
/**
|
|
2215
2985
|
* The project's tsconfig path aliases as `buildPathAliasesJson` pairs; empty
|
|
2216
2986
|
* when no readable tsconfig, or no usable `paths`, exists.
|
|
@@ -2350,112 +3120,42 @@ function kitDescriptorDiagnostics(records, manifest) {
|
|
|
2350
3120
|
return diagnostics;
|
|
2351
3121
|
}
|
|
2352
3122
|
//#endregion
|
|
2353
|
-
//#region pipeline/
|
|
2354
|
-
/**
|
|
2355
|
-
|
|
2356
|
-
* and deletion: event paths are lookup INPUTS only and never fork identity.
|
|
2357
|
-
*/
|
|
2358
|
-
/**
|
|
2359
|
-
* True when `target` is `root` or a descendant, decided by `relative()`
|
|
2360
|
-
* shape: string prefixing would let `/ui` claim `/ui-old`.
|
|
2361
|
-
*/
|
|
2362
|
-
function isPathWithinRoot(root, target, pathApi = node_path.default) {
|
|
2363
|
-
const rel = pathApi.relative(root, target);
|
|
2364
|
-
return rel === "" || !pathApi.isAbsolute(rel) && rel !== ".." && !rel.startsWith(".." + pathApi.sep);
|
|
2365
|
-
}
|
|
2366
|
-
/**
|
|
2367
|
-
* True when two paths share a platform root (win32 drive letter or UNC
|
|
2368
|
-
* share; always true on posix). Drive letters compare case-insensitively.
|
|
2369
|
-
*/
|
|
2370
|
-
function sharesVolumeRoot(a, b, pathApi = node_path.default) {
|
|
2371
|
-
const volumeOf = (p) => pathApi.parse(pathApi.resolve(p)).root.toLowerCase();
|
|
2372
|
-
return volumeOf(a) === volumeOf(b);
|
|
2373
|
-
}
|
|
2374
|
-
function canonicalize(p) {
|
|
3123
|
+
//#region pipeline/workspace-packages.ts
|
|
3124
|
+
/** The parsed `package.json` in `dir`, or null when it cannot be read. */
|
|
3125
|
+
function readManifest(dir) {
|
|
2375
3126
|
try {
|
|
2376
|
-
return (0,
|
|
3127
|
+
return JSON.parse((0, fs.readFileSync)((0, path.join)(dir, "package.json"), "utf-8"));
|
|
2377
3128
|
} catch {
|
|
2378
3129
|
return null;
|
|
2379
3130
|
}
|
|
2380
3131
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
};
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
roots.push({
|
|
2403
|
-
asRegistered,
|
|
2404
|
-
canonical
|
|
2405
|
-
});
|
|
2406
|
-
return canonical;
|
|
2407
|
-
},
|
|
2408
|
-
externalRoots() {
|
|
2409
|
-
return roots.map((record) => record.canonical);
|
|
2410
|
-
},
|
|
2411
|
-
resolveSourceId(inputPath) {
|
|
2412
|
-
const lexical = node_path.default.normalize(inputPath);
|
|
2413
|
-
const canonical = canonicalize(lexical);
|
|
2414
|
-
if (canonical === null) return null;
|
|
2415
|
-
const owner = owningRecord(canonical);
|
|
2416
|
-
const ownedBy = (record) => {
|
|
2417
|
-
const pathInRoot = node_path.default.relative(record.canonical, canonical);
|
|
2418
|
-
return {
|
|
2419
|
-
sourceKey: node_path.default.relative(normalizedRootDir, node_path.default.join(record.asRegistered, pathInRoot)),
|
|
2420
|
-
owningRoot: record.canonical,
|
|
2421
|
-
pathInRoot
|
|
2422
|
-
};
|
|
2423
|
-
};
|
|
2424
|
-
const ownerIsMoreSpecific = owner !== null && owner.canonical.length > canonicalRootDir.length;
|
|
2425
|
-
let resolved;
|
|
2426
|
-
if (!ownerIsMoreSpecific && isPathWithinRoot(canonicalRootDir, canonical)) {
|
|
2427
|
-
const key = node_path.default.relative(canonicalRootDir, canonical);
|
|
2428
|
-
resolved = {
|
|
2429
|
-
sourceKey: key,
|
|
2430
|
-
owningRoot: null,
|
|
2431
|
-
pathInRoot: key
|
|
2432
|
-
};
|
|
2433
|
-
} else if (owner) resolved = ownedBy(owner);
|
|
2434
|
-
else return null;
|
|
2435
|
-
aliases.set(lexical, resolved);
|
|
2436
|
-
aliases.set(canonical, resolved);
|
|
2437
|
-
return resolved;
|
|
2438
|
-
},
|
|
2439
|
-
resolveDeletedSourceId(inputPath) {
|
|
2440
|
-
return aliases.get(node_path.default.normalize(inputPath)) ?? null;
|
|
2441
|
-
},
|
|
2442
|
-
containingExternalRoot(inputPath) {
|
|
2443
|
-
const lexical = node_path.default.normalize(inputPath);
|
|
2444
|
-
let owner = null;
|
|
2445
|
-
for (const record of roots) {
|
|
2446
|
-
if (!(isPathWithinRoot(record.canonical, lexical) || isPathWithinRoot(record.asRegistered, lexical))) continue;
|
|
2447
|
-
if (!owner || record.canonical.length > owner.canonical.length) owner = record;
|
|
2448
|
-
}
|
|
2449
|
-
if (owner) return owner.canonical;
|
|
2450
|
-
const canonical = canonicalize(lexical);
|
|
2451
|
-
if (canonical === null) return null;
|
|
2452
|
-
for (const record of roots) {
|
|
2453
|
-
if (!isPathWithinRoot(record.canonical, canonical)) continue;
|
|
2454
|
-
if (!owner || record.canonical.length > owner.canonical.length) owner = record;
|
|
2455
|
-
}
|
|
2456
|
-
return owner?.canonical ?? null;
|
|
3132
|
+
/**
|
|
3133
|
+
* The packages the session root's `package.json` declares as workspaces, by
|
|
3134
|
+
* name, at their real directories, so a linked workspace is one package. The
|
|
3135
|
+
* system loader consults them after a `node_modules` lookup misses. Only
|
|
3136
|
+
* literal entries name a package; a glob entry (`packages/*`) names none
|
|
3137
|
+
* yet. None when the manifest is absent or declares none.
|
|
3138
|
+
*/
|
|
3139
|
+
function declaredWorkspacePackages(rootDir) {
|
|
3140
|
+
const rootPkg = readManifest(rootDir);
|
|
3141
|
+
if (!isJsonBlock(rootPkg)) return {};
|
|
3142
|
+
const workspaces = rootPkg.workspaces;
|
|
3143
|
+
const declared = isJsonBlock(workspaces) ? workspaces.packages : workspaces;
|
|
3144
|
+
if (!Array.isArray(declared)) return {};
|
|
3145
|
+
const packages = /* @__PURE__ */ new Map();
|
|
3146
|
+
for (const entry of declared) {
|
|
3147
|
+
if (!isJsonString(entry)) continue;
|
|
3148
|
+
let dir;
|
|
3149
|
+
try {
|
|
3150
|
+
dir = (0, fs.realpathSync)((0, path.resolve)(rootDir, entry));
|
|
3151
|
+
} catch {
|
|
3152
|
+
continue;
|
|
2457
3153
|
}
|
|
2458
|
-
|
|
3154
|
+
const manifest = readManifest(dir);
|
|
3155
|
+
const name = isJsonBlock(manifest) ? manifest.name : void 0;
|
|
3156
|
+
if (isJsonString(name) && name !== "" && !packages.has(name)) packages.set(name, dir);
|
|
3157
|
+
}
|
|
3158
|
+
return Object.fromEntries(packages);
|
|
2459
3159
|
}
|
|
2460
3160
|
//#endregion
|
|
2461
3161
|
//#region pipeline/discover-packages.ts
|
|
@@ -2483,34 +3183,31 @@ const PACKAGE_OUTPUT_EXCLUDES = [
|
|
|
2483
3183
|
".d.ts",
|
|
2484
3184
|
".map"
|
|
2485
3185
|
];
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
absSpecifier,
|
|
2496
|
-
...Array.from(extensionsSet, (ext) => absSpecifier + ext),
|
|
2497
|
-
...Array.from(extensionsSet, (ext) => (0, path.join)(absSpecifier, `index${ext}`))
|
|
2498
|
-
].find(isFile$1) ?? null;
|
|
3186
|
+
/** The file an absolute path specifier names, through the extension
|
|
3187
|
+
* policy, spelled exactly below the directory it shares with `within`
|
|
3188
|
+
* when given; a file differing only in case is a mismatch. */
|
|
3189
|
+
function probeAbsolutePathSpecifier(absSpecifier, extensionsSet, within, policy) {
|
|
3190
|
+
return probeOnDisk(policyCandidates((0, path.normalize)(absSpecifier), {
|
|
3191
|
+
sources: extensionsSet,
|
|
3192
|
+
index: path.join,
|
|
3193
|
+
policy
|
|
3194
|
+
}), within);
|
|
2499
3195
|
}
|
|
2500
3196
|
/** The package a bare specifier names: `@scope/name` or `name`. */
|
|
2501
3197
|
function bareSpecifierPackageName(specifier) {
|
|
2502
3198
|
const segments = specifier.split("/");
|
|
2503
3199
|
return specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0];
|
|
2504
3200
|
}
|
|
2505
|
-
function sourceEntryForSpecifier(specifier, srcDir, extensionsSet) {
|
|
3201
|
+
function sourceEntryForSpecifier(specifier, srcDir, extensionsSet, rootDir, policy) {
|
|
2506
3202
|
if ((0, path.isAbsolute)(specifier)) {
|
|
2507
|
-
const
|
|
2508
|
-
if (
|
|
2509
|
-
return isPathWithinRoot(srcDir,
|
|
3203
|
+
const probed = probeAbsolutePathSpecifier(specifier, extensionsSet, rootDir, policy);
|
|
3204
|
+
if (probed.kind !== "found") return null;
|
|
3205
|
+
return isPathWithinRoot(srcDir, probed.path) ? probed.path : null;
|
|
2510
3206
|
}
|
|
2511
3207
|
const packageName = bareSpecifierPackageName(specifier);
|
|
2512
3208
|
const subpath = specifier.slice(packageName.length + 1);
|
|
2513
|
-
|
|
3209
|
+
const probed = probeAbsolutePathSpecifier((0, path.join)(srcDir, subpath || "index"), extensionsSet, srcDir, policy);
|
|
3210
|
+
return probed.kind === "found" ? probed.path : null;
|
|
2514
3211
|
}
|
|
2515
3212
|
/** The package's parsed `package.json`, or null when it cannot be read. */
|
|
2516
3213
|
function readPackageManifest(pkgRoot) {
|
|
@@ -2535,78 +3232,50 @@ function exportsSubpaths(manifest) {
|
|
|
2535
3232
|
* its source in every host, and the system loader prefers it.
|
|
2536
3233
|
*/
|
|
2537
3234
|
const KIT_SOURCE_CONDITION = "animus";
|
|
2538
|
-
/** The
|
|
2539
|
-
*
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
for (const [subpath, value] of exportsSubpaths(readPackageManifest(pkgRoot))) {
|
|
2547
|
-
if (subpath.includes("*") || !isJsonBlock(value)) continue;
|
|
2548
|
-
const target = value[KIT_SOURCE_CONDITION];
|
|
2549
|
-
if (!isJsonString(target)) continue;
|
|
2550
|
-
const file = (0, path.resolve)(pkgRoot, target);
|
|
2551
|
-
if (isPathWithinRoot(pkgRoot, file) && isFile$1(file)) condition.entries.push([subpath, file]);
|
|
2552
|
-
else condition.invalid.push([subpath, target]);
|
|
2553
|
-
}
|
|
2554
|
-
if (condition.entries.length === 0 && condition.invalid.length === 0) return null;
|
|
2555
|
-
condition.root = sourceRoot(condition.entries);
|
|
2556
|
-
return condition;
|
|
2557
|
-
}
|
|
2558
|
-
/** The deepest directory holding every entry's file. */
|
|
2559
|
-
function sourceRoot(entries) {
|
|
2560
|
-
return entries.reduce((root, [, file]) => root === null ? (0, path.dirname)(file) : commonDirectory(root, (0, path.dirname)(file)), null);
|
|
2561
|
-
}
|
|
2562
|
-
/** A TypeScript source file; compiled output and declarations are not. */
|
|
2563
|
-
const TS_SOURCE = /(?<!\.d)\.[cm]?tsx?$/;
|
|
2564
|
-
/** A kit with no source condition whose every exact `exports` entry already
|
|
2565
|
-
* targets TypeScript source in the package under `import` or `default`:
|
|
2566
|
-
* those targets are its source, as the condition would name them. Null
|
|
2567
|
-
* when any exact entry has no such target, such as one only `require` or
|
|
2568
|
-
* `types` reaches, or there is no exact entry. */
|
|
2569
|
-
function sourceExportsCondition(pkgRoot) {
|
|
2570
|
-
const entries = [];
|
|
2571
|
-
for (const [subpath, value] of exportsSubpaths(readPackageManifest(pkgRoot))) {
|
|
2572
|
-
if (subpath.includes("*")) continue;
|
|
2573
|
-
const target = exportTarget(value);
|
|
2574
|
-
const file = target === null ? null : (0, path.resolve)(pkgRoot, target);
|
|
2575
|
-
if (file === null || !TS_SOURCE.test(file) || !isPathWithinRoot(pkgRoot, file) || !isFile$1(file)) return null;
|
|
2576
|
-
entries.push([subpath, file]);
|
|
2577
|
-
}
|
|
2578
|
-
if (entries.length === 0) return null;
|
|
2579
|
-
return {
|
|
2580
|
-
entries,
|
|
2581
|
-
invalid: [],
|
|
2582
|
-
root: sourceRoot(entries)
|
|
3235
|
+
/** The system loader's package locator under the session's declared
|
|
3236
|
+
* `workspaces`: the first `node_modules/<name>` up the tree, then the
|
|
3237
|
+
* workspace of that name. */
|
|
3238
|
+
function nativePackageLocator(engine, workspaces) {
|
|
3239
|
+
const native = engine.locatePackage;
|
|
3240
|
+
return (name, fromDir) => {
|
|
3241
|
+
if (native === void 0) throw new Error("the native engine does not expose locatePackage, which kit discovery needs — rebuild @animus-ui/extract");
|
|
3242
|
+
return native(name, fromDir, workspaces);
|
|
2583
3243
|
};
|
|
2584
3244
|
}
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
return
|
|
3245
|
+
/** The native table's kit source roots under one resolution context. */
|
|
3246
|
+
function nativeKitSourceRoot(engine, fromDir, conditions, workspaces, policyJson) {
|
|
3247
|
+
const native = engine.resolveKitSourceRoot;
|
|
3248
|
+
return (specifier, packageDir, hostEntry) => {
|
|
3249
|
+
if (native === void 0) throw new Error("the native engine does not expose resolveKitSourceRoot, which kit discovery needs — rebuild @animus-ui/extract");
|
|
3250
|
+
const answer = parseInternalWire(native(specifier, fromDir, [...conditions], workspaces, policyJson, hostEntry ?? void 0, packageDir), "resolveKitSourceRoot");
|
|
3251
|
+
if (answer.rule === void 0) return null;
|
|
3252
|
+
return {
|
|
3253
|
+
rule: answer.rule,
|
|
3254
|
+
root: answer.root ?? null,
|
|
3255
|
+
entries: answer.entries ?? [],
|
|
3256
|
+
invalid: answer.invalid ?? [],
|
|
3257
|
+
unresolved: answer.unresolved ?? null
|
|
3258
|
+
};
|
|
3259
|
+
};
|
|
2589
3260
|
}
|
|
2590
|
-
/**
|
|
2591
|
-
|
|
3261
|
+
/**
|
|
3262
|
+
* Whether `dir`, the nearest manifest above a host's answer, is a package
|
|
3263
|
+
* the host resolved into: its manifest names a package, and it is not the
|
|
3264
|
+
* project or a directory holding it. A host answer from a dependency cache
|
|
3265
|
+
* (`node_modules/.vite/deps`), or from a file outside every package, finds
|
|
3266
|
+
* the application's own manifest, which is no package root. The name need
|
|
3267
|
+
* not be the specifier's: a host alias resolves one package to another,
|
|
3268
|
+
* and the host's package is the one the bundle renders (spec §2.2 A4).
|
|
3269
|
+
*/
|
|
3270
|
+
function isHostPackageRoot(dir, rootDir) {
|
|
2592
3271
|
const manifest = readPackageManifest(dir);
|
|
2593
|
-
return isJsonBlock(manifest) && manifest.name
|
|
3272
|
+
return isJsonBlock(manifest) && isJsonString(manifest.name) && manifest.name !== "" && !isPathWithinRoot(realPath(dir), realPath(rootDir));
|
|
2594
3273
|
}
|
|
2595
|
-
function realPath(path$
|
|
3274
|
+
function realPath(path$2) {
|
|
2596
3275
|
try {
|
|
2597
|
-
return (0, fs.realpathSync)(path$
|
|
3276
|
+
return (0, fs.realpathSync)(path$2);
|
|
2598
3277
|
} catch {
|
|
2599
|
-
return path$
|
|
2600
|
-
}
|
|
2601
|
-
}
|
|
2602
|
-
/** The root of the installed package `name` as Node finds it from `fromDir`,
|
|
2603
|
-
* the first `node_modules/<name>` up the directory tree, at its real path,
|
|
2604
|
-
* as host resolvers report a linked package. */
|
|
2605
|
-
function locatePackageRoot(name, fromDir) {
|
|
2606
|
-
for (let dir = fromDir;; dir = (0, path.dirname)(dir)) {
|
|
2607
|
-
const candidate = (0, path.join)(dir, "node_modules", name);
|
|
2608
|
-
if ((0, fs.existsSync)((0, path.join)(candidate, "package.json"))) return realPath(candidate);
|
|
2609
|
-
if (dir === (0, path.dirname)(dir)) return null;
|
|
3278
|
+
return path$2;
|
|
2610
3279
|
}
|
|
2611
3280
|
}
|
|
2612
3281
|
/**
|
|
@@ -2752,14 +3421,21 @@ function distEntryIsStale(absEntry, srcDir, srcFiles) {
|
|
|
2752
3421
|
return distMtime < newestSrcMtime;
|
|
2753
3422
|
}
|
|
2754
3423
|
async function collectExternalPackageSources(opts) {
|
|
2755
|
-
const { specifiers,
|
|
3424
|
+
const { specifiers, unresolvedReason, kitSourceRoot, locatePackage, rootDir, extensionsSet, hasEntry, onSourceRead, onUnreadable, onPackageResolved, requireSourceEntry, extensions, hostOutputDirs = [] } = opts;
|
|
3425
|
+
const answers = /* @__PURE__ */ new Map();
|
|
3426
|
+
const resolveSpecifier = (specifier) => {
|
|
3427
|
+
let answer = answers.get(specifier);
|
|
3428
|
+
if (answer === void 0) {
|
|
3429
|
+
answer = Promise.resolve().then(() => opts.resolveSpecifier(specifier));
|
|
3430
|
+
answers.set(specifier, answer);
|
|
3431
|
+
}
|
|
3432
|
+
return answer;
|
|
3433
|
+
};
|
|
2756
3434
|
const entries = [];
|
|
2757
3435
|
const pushed = /* @__PURE__ */ new Set();
|
|
2758
3436
|
const packageMap = {};
|
|
2759
3437
|
const sourceEntries = /* @__PURE__ */ new Map();
|
|
2760
3438
|
const sourceEntrySideEffects = /* @__PURE__ */ new Map();
|
|
2761
|
-
/** `replaced` names the entry the redirect stands in for; it is only
|
|
2762
|
-
* needed, and so only resolved, for a glob list. */
|
|
2763
3439
|
/** The entry `subpath` of the package resolves to without the redirect.
|
|
2764
3440
|
* A resolver with no `import` condition, as Node's `require` has none,
|
|
2765
3441
|
* finds no ESM-only entry, so the manifest's own target answers then. */
|
|
@@ -2770,6 +3446,8 @@ async function collectExternalPackageSources(opts) {
|
|
|
2770
3446
|
} catch {}
|
|
2771
3447
|
return packageExportEntries(pkgRoot).find(([entry]) => entry === subpath)?.[1] ?? null;
|
|
2772
3448
|
};
|
|
3449
|
+
/** `replaced` names the entry the redirect stands in for; it is only
|
|
3450
|
+
* needed, and so only resolved, for a glob list. */
|
|
2773
3451
|
const redirect = async (specifier, srcEntry, pkgRoot, replaced) => {
|
|
2774
3452
|
sourceEntries.set(specifier, srcEntry);
|
|
2775
3453
|
const field = readPackageSideEffects(pkgRoot);
|
|
@@ -2814,8 +3492,18 @@ async function collectExternalPackageSources(opts) {
|
|
|
2814
3492
|
return true;
|
|
2815
3493
|
};
|
|
2816
3494
|
const diagnostics = [];
|
|
2817
|
-
const
|
|
3495
|
+
const reported = /* @__PURE__ */ new Set();
|
|
3496
|
+
const report = (packageName, pkgRoot, condition) => {
|
|
3497
|
+
const copy = realPath(pkgRoot);
|
|
3498
|
+
for (const finding of sourceConditionDiagnostics(packageName, condition)) {
|
|
3499
|
+
const key = `${copy}\0${finding.code}\0${finding.message}`;
|
|
3500
|
+
if (reported.has(key)) continue;
|
|
3501
|
+
reported.add(key);
|
|
3502
|
+
diagnostics.push(finding);
|
|
3503
|
+
}
|
|
3504
|
+
};
|
|
2818
3505
|
const kitDescriptors = [];
|
|
3506
|
+
const packageInstances = {};
|
|
2819
3507
|
const describedRoots = /* @__PURE__ */ new Set();
|
|
2820
3508
|
for (const specifier of specifiers) {
|
|
2821
3509
|
let absEntry;
|
|
@@ -2824,23 +3512,78 @@ async function collectExternalPackageSources(opts) {
|
|
|
2824
3512
|
} catch {
|
|
2825
3513
|
absEntry = null;
|
|
2826
3514
|
}
|
|
2827
|
-
|
|
3515
|
+
let caseMismatch;
|
|
3516
|
+
if ((0, path.isAbsolute)(specifier)) {
|
|
3517
|
+
const own = probeAbsolutePathSpecifier(specifier, extensionsSet, rootDir, extensions);
|
|
3518
|
+
const hosted = absEntry === null ? null : (0, path.normalize)(absEntry);
|
|
3519
|
+
const seen = hosted === null ? null : seeOnDisk(hosted, rootDir);
|
|
3520
|
+
const probed = own.kind === "case-mismatch" || hosted === null || seen === null ? own : seen.kind === "case-only" ? {
|
|
3521
|
+
kind: "case-mismatch",
|
|
3522
|
+
candidate: hosted,
|
|
3523
|
+
actual: seen.actual
|
|
3524
|
+
} : {
|
|
3525
|
+
kind: "found",
|
|
3526
|
+
path: hosted
|
|
3527
|
+
};
|
|
3528
|
+
absEntry = probed.kind === "found" ? probed.path : null;
|
|
3529
|
+
if (probed.kind === "case-mismatch") caseMismatch = caseMismatchReason(`'${specifier}'`, probed, "spell the include as the file is spelled");
|
|
3530
|
+
}
|
|
2828
3531
|
const packageName = (0, path.isAbsolute)(specifier) ? null : bareSpecifierPackageName(specifier);
|
|
2829
|
-
|
|
2830
|
-
const locatedRoot = packageName &&
|
|
2831
|
-
|
|
2832
|
-
|
|
3532
|
+
let resolvedRoot = absEntry ? findPackageRoot(absEntry) : null;
|
|
3533
|
+
const locatedRoot = packageName && locatePackage(packageName, opts.locateFrom?.(specifier) ?? rootDir);
|
|
3534
|
+
if (resolvedRoot && locatedRoot && absEntry && realPath(resolvedRoot) !== locatedRoot && isPathWithinRoot(locatedRoot, realPath(absEntry))) {
|
|
3535
|
+
while (realPath(resolvedRoot) !== locatedRoot && resolvedRoot !== (0, path.dirname)(resolvedRoot)) resolvedRoot = (0, path.dirname)(resolvedRoot);
|
|
3536
|
+
if (realPath(resolvedRoot) !== locatedRoot) resolvedRoot = locatedRoot;
|
|
3537
|
+
}
|
|
3538
|
+
const pkgRoot = resolvedRoot && (!locatedRoot || isHostPackageRoot(resolvedRoot, rootDir) || realPath(resolvedRoot) === locatedRoot) ? resolvedRoot : locatedRoot || resolvedRoot;
|
|
3539
|
+
if (absEntry && packageName && locatedRoot && pkgRoot === locatedRoot && !isPathWithinRoot(locatedRoot, realPath(absEntry)) && !realPath(absEntry).split(path.sep).includes("node_modules")) diagnostics.push(packageMismatchDiagnostic(specifier, (0, path.relative)(rootDir, absEntry), (0, path.relative)(rootDir, locatedRoot)));
|
|
3540
|
+
const selection = packageName && pkgRoot ? kitSourceRoot(specifier, pkgRoot, absEntry) : null;
|
|
3541
|
+
if (selection?.unresolved) {
|
|
3542
|
+
absEntry = null;
|
|
3543
|
+
caseMismatch = selection.unresolved;
|
|
3544
|
+
}
|
|
3545
|
+
const condition = selection && (selection.rule === "animus" || selection.rule === "source-exports" || selection.invalid.length > 0) ? {
|
|
3546
|
+
entries: selection.entries,
|
|
3547
|
+
invalid: selection.invalid,
|
|
3548
|
+
root: selection.rule === "compiled" ? null : selection.root
|
|
3549
|
+
} : null;
|
|
3550
|
+
if (selection?.unresolved && condition && packageName && pkgRoot) report(packageName, pkgRoot, condition);
|
|
2833
3551
|
const entryKey = packageName && `.${specifier.slice(packageName.length)}`;
|
|
2834
3552
|
absEntry ??= condition?.entries.find(([entry]) => entry === entryKey)?.[1] ?? null;
|
|
2835
3553
|
if (!absEntry || !pkgRoot) {
|
|
2836
|
-
|
|
3554
|
+
const record = {
|
|
2837
3555
|
specifier,
|
|
2838
3556
|
outcome: "unresolvable",
|
|
2839
3557
|
fileCount: 0
|
|
3558
|
+
};
|
|
3559
|
+
const reason = caseMismatch ?? unresolvedReason?.(specifier);
|
|
3560
|
+
if (reason !== void 0) record.reason = reason;
|
|
3561
|
+
outcomes.push(record);
|
|
3562
|
+
continue;
|
|
3563
|
+
}
|
|
3564
|
+
const hostOutput = hostOutputDirs.find((dir) => isPathWithinRoot(dir, pkgRoot) || isPathWithinRoot(realPath(dir), realPath(pkgRoot)));
|
|
3565
|
+
if (hostOutput !== void 0) {
|
|
3566
|
+
outcomes.push({
|
|
3567
|
+
specifier,
|
|
3568
|
+
outcome: "unresolvable",
|
|
3569
|
+
fileCount: 0,
|
|
3570
|
+
reason: `the package lies inside the host's output directory ${hostOutput}, which is never source`
|
|
2840
3571
|
});
|
|
2841
3572
|
continue;
|
|
2842
3573
|
}
|
|
3574
|
+
if (requireSourceEntry?.(specifier)) {
|
|
3575
|
+
if (!(condition && packageName ? condition.entries.some(([entry]) => entry === entryKey) : selection?.rule === "src" && sourceEntryForSpecifier(specifier, (0, path.join)(pkgRoot, "src"), extensionsSet, rootDir, extensions) !== null)) {
|
|
3576
|
+
outcomes.push({
|
|
3577
|
+
specifier,
|
|
3578
|
+
outcome: "unresolvable",
|
|
3579
|
+
fileCount: 0,
|
|
3580
|
+
reason: "the host does not resolve it, and the system loader finds only compiled output that no source entry redirects to — link the package into node_modules, or give it an \"animus\" source condition"
|
|
3581
|
+
});
|
|
3582
|
+
continue;
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
2843
3585
|
const realRoot = realPath(pkgRoot);
|
|
3586
|
+
if (packageName) packageInstances[packageName] ??= realRoot;
|
|
2844
3587
|
if (!describedRoots.has(realRoot)) {
|
|
2845
3588
|
describedRoots.add(realRoot);
|
|
2846
3589
|
const described = readKitDescriptor(pkgRoot, rootDir);
|
|
@@ -2850,10 +3593,24 @@ async function collectExternalPackageSources(opts) {
|
|
|
2850
3593
|
const srcDir = (0, path.join)(pkgRoot, "src");
|
|
2851
3594
|
let fileCount = 0;
|
|
2852
3595
|
let staleDist = false;
|
|
2853
|
-
if (packageName
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
3596
|
+
if (packageName) report(packageName, pkgRoot, condition);
|
|
3597
|
+
const ingestOutput = (entryFile) => {
|
|
3598
|
+
const outputDir = (0, path.dirname)(entryFile);
|
|
3599
|
+
packageDirs.push(outputDir);
|
|
3600
|
+
if (linked) linkedDirs.push(outputDir);
|
|
3601
|
+
outputDirs.push(outputDir);
|
|
3602
|
+
claimDir(outputDir, specifier);
|
|
3603
|
+
onPackageResolved?.(specifier, outputDir);
|
|
3604
|
+
const outputExtensions = new Set(extensionsSet);
|
|
3605
|
+
outputExtensions.add((0, path.extname)(entryFile));
|
|
3606
|
+
dirExtensions[outputDir] = [...outputExtensions];
|
|
3607
|
+
const outputFiles = discoverFiles(outputDir, outputDir, void 0, outputExtensions).filter((file) => {
|
|
3608
|
+
const relToOutput = (0, path.relative)(outputDir, file);
|
|
3609
|
+
return !PACKAGE_OUTPUT_EXCLUDES.some((pattern) => relToOutput.includes(pattern));
|
|
3610
|
+
});
|
|
3611
|
+
if (!outputFiles.includes(entryFile)) outputFiles.unshift(entryFile);
|
|
3612
|
+
for (const outputFile of outputFiles) if (ingest(outputFile, specifier)) fileCount++;
|
|
3613
|
+
};
|
|
2857
3614
|
if (condition && packageName) {
|
|
2858
3615
|
for (const [entry, target] of condition.entries) {
|
|
2859
3616
|
const entrySpecifier = packageName + entry.slice(1);
|
|
@@ -2861,6 +3618,7 @@ async function collectExternalPackageSources(opts) {
|
|
|
2861
3618
|
await redirect(entrySpecifier, target, pkgRoot, () => shippedEntry(entrySpecifier, pkgRoot, entry));
|
|
2862
3619
|
}
|
|
2863
3620
|
packageMap[specifier] ??= (0, path.relative)(rootDir, absEntry);
|
|
3621
|
+
if (!condition.entries.some(([entry]) => entry === entryKey)) ingestOutput(absEntry);
|
|
2864
3622
|
if (condition.root) {
|
|
2865
3623
|
packageDirs.push(condition.root);
|
|
2866
3624
|
if (linked) linkedDirs.push(condition.root);
|
|
@@ -2869,13 +3627,13 @@ async function collectExternalPackageSources(opts) {
|
|
|
2869
3627
|
onPackageResolved?.(specifier, condition.root);
|
|
2870
3628
|
for (const file of walkPackageSources(condition.root, extensionsSet)) if (ingest(file, specifier)) fileCount++;
|
|
2871
3629
|
}
|
|
2872
|
-
} else if ((0, fs.existsSync)(srcDir)) {
|
|
3630
|
+
} else if (selection === null ? (0, fs.existsSync)(srcDir) : selection.rule === "src") {
|
|
2873
3631
|
packageDirs.push(srcDir);
|
|
2874
3632
|
if (linked) linkedDirs.push(srcDir);
|
|
2875
3633
|
claimDir(srcDir, specifier);
|
|
2876
3634
|
dirExtensions[srcDir] = [...extensionsSet];
|
|
2877
3635
|
onPackageResolved?.(specifier, srcDir);
|
|
2878
|
-
const srcEntry = sourceEntryForSpecifier(specifier, srcDir, extensionsSet);
|
|
3636
|
+
const srcEntry = sourceEntryForSpecifier(specifier, srcDir, extensionsSet, rootDir, extensions);
|
|
2879
3637
|
if (srcEntry) {
|
|
2880
3638
|
packageMap[specifier] = (0, path.relative)(rootDir, srcEntry);
|
|
2881
3639
|
const replaced = absEntry;
|
|
@@ -2883,7 +3641,7 @@ async function collectExternalPackageSources(opts) {
|
|
|
2883
3641
|
} else packageMap[specifier] = (0, path.relative)(rootDir, absEntry);
|
|
2884
3642
|
if (packageName) {
|
|
2885
3643
|
if (packageName !== specifier && !(packageName in packageMap)) {
|
|
2886
|
-
const rootEntry = sourceEntryForSpecifier(packageName, srcDir, extensionsSet);
|
|
3644
|
+
const rootEntry = sourceEntryForSpecifier(packageName, srcDir, extensionsSet, rootDir, extensions);
|
|
2887
3645
|
if (rootEntry) {
|
|
2888
3646
|
packageMap[packageName] = (0, path.relative)(rootDir, rootEntry);
|
|
2889
3647
|
await redirect(packageName, rootEntry, pkgRoot, () => shippedEntry(packageName, pkgRoot, "."));
|
|
@@ -2894,22 +3652,8 @@ async function collectExternalPackageSources(opts) {
|
|
|
2894
3652
|
staleDist = linked && distEntryIsStale(absEntry, srcDir, pkgFiles);
|
|
2895
3653
|
for (const pkgFile of pkgFiles) if (ingest(pkgFile, specifier)) fileCount++;
|
|
2896
3654
|
} else {
|
|
2897
|
-
const outputDir = (0, path.dirname)(absEntry);
|
|
2898
|
-
packageDirs.push(outputDir);
|
|
2899
|
-
if (linked) linkedDirs.push(outputDir);
|
|
2900
|
-
outputDirs.push(outputDir);
|
|
2901
|
-
claimDir(outputDir, specifier);
|
|
2902
|
-
onPackageResolved?.(specifier, outputDir);
|
|
2903
3655
|
packageMap[specifier] = (0, path.relative)(rootDir, absEntry);
|
|
2904
|
-
|
|
2905
|
-
outputExtensions.add((0, path.extname)(absEntry));
|
|
2906
|
-
dirExtensions[outputDir] = [...outputExtensions];
|
|
2907
|
-
const outputFiles = discoverFiles(outputDir, outputDir, void 0, outputExtensions).filter((file) => {
|
|
2908
|
-
const relToOutput = (0, path.relative)(outputDir, file);
|
|
2909
|
-
return !PACKAGE_OUTPUT_EXCLUDES.some((pattern) => relToOutput.includes(pattern));
|
|
2910
|
-
});
|
|
2911
|
-
if (!outputFiles.includes(absEntry)) outputFiles.unshift(absEntry);
|
|
2912
|
-
for (const outputFile of outputFiles) if (ingest(outputFile, specifier)) fileCount++;
|
|
3656
|
+
ingestOutput(absEntry);
|
|
2913
3657
|
}
|
|
2914
3658
|
if (packageName) for (const [subpath, target] of packageExportEntries(pkgRoot)) {
|
|
2915
3659
|
const entrySpecifier = packageName + subpath.slice(1);
|
|
@@ -2917,6 +3661,16 @@ async function collectExternalPackageSources(opts) {
|
|
|
2917
3661
|
if (entrySpecifier in packageMap || !alreadyIngested(targetRelPath)) continue;
|
|
2918
3662
|
packageMap[entrySpecifier] = targetRelPath;
|
|
2919
3663
|
}
|
|
3664
|
+
const ownManifest = readPackageManifest(pkgRoot);
|
|
3665
|
+
const hostName = isJsonBlock(ownManifest) ? ownManifest.name : void 0;
|
|
3666
|
+
if (packageName && locatedRoot && realPath(pkgRoot) !== locatedRoot && isJsonString(hostName) && hostName !== "" && hostName !== packageName) for (const [key, entry] of [...sourceEntries]) {
|
|
3667
|
+
if (key !== packageName && !key.startsWith(`${packageName}/`)) continue;
|
|
3668
|
+
const hostKey = hostName + key.slice(packageName.length);
|
|
3669
|
+
if (sourceEntries.has(hostKey)) continue;
|
|
3670
|
+
sourceEntries.set(hostKey, entry);
|
|
3671
|
+
const sideEffects = sourceEntrySideEffects.get(key);
|
|
3672
|
+
if (sideEffects !== void 0) sourceEntrySideEffects.set(hostKey, sideEffects);
|
|
3673
|
+
}
|
|
2920
3674
|
outcomes.push({
|
|
2921
3675
|
specifier,
|
|
2922
3676
|
outcome: staleDist ? "stale-dist" : fileCount > 0 ? "resolved" : "empty",
|
|
@@ -2936,7 +3690,8 @@ async function collectExternalPackageSources(opts) {
|
|
|
2936
3690
|
fileOwners,
|
|
2937
3691
|
outcomes,
|
|
2938
3692
|
diagnostics: [...diagnostics, ...noKitFilesDiagnostics(outcomes)],
|
|
2939
|
-
kitDescriptors
|
|
3693
|
+
kitDescriptors,
|
|
3694
|
+
packageInstances
|
|
2940
3695
|
};
|
|
2941
3696
|
}
|
|
2942
3697
|
/** The dependency names a manifest lists in `fields`. */
|
|
@@ -2949,14 +3704,22 @@ function dependencyNames(manifest, fields) {
|
|
|
2949
3704
|
}
|
|
2950
3705
|
return [...names];
|
|
2951
3706
|
}
|
|
3707
|
+
/** Whether the package at `pkgRoot` declares the kit source condition, as
|
|
3708
|
+
* the system loader's table reads its manifest: an `animus` key anywhere in
|
|
3709
|
+
* its `exports`, on any entry, subpath or pattern, valid or not. */
|
|
3710
|
+
function declaresKitSource(engine, pkgRoot) {
|
|
3711
|
+
if (engine.declaresKitSource === void 0) throw new Error("the native engine does not expose declaresKitSource, which kit discovery needs — rebuild @animus-ui/extract");
|
|
3712
|
+
return engine.declaresKitSource(pkgRoot);
|
|
3713
|
+
}
|
|
2952
3714
|
/** The source kits the application at `rootDir` declares as dependencies.
|
|
2953
3715
|
* A bundler serves an installed one as compiled code unless told
|
|
2954
3716
|
* otherwise: Next keeps it external on the server unless it is in
|
|
2955
3717
|
* `transpilePackages`, and Vite's optimizer prebundles it. */
|
|
2956
|
-
function sourceKitDependencies(rootDir) {
|
|
3718
|
+
function sourceKitDependencies(rootDir, engine) {
|
|
3719
|
+
const locatePackage = nativePackageLocator(engine, declaredWorkspacePackages(rootDir));
|
|
2957
3720
|
return dependencyNames(readPackageManifest(rootDir), ["dependencies", "devDependencies"]).flatMap((name) => {
|
|
2958
|
-
const pkgRoot =
|
|
2959
|
-
if (pkgRoot === null ||
|
|
3721
|
+
const pkgRoot = locatePackage(name, rootDir);
|
|
3722
|
+
if (pkgRoot === null || !declaresKitSource(engine, pkgRoot)) return [];
|
|
2960
3723
|
return [{
|
|
2961
3724
|
name,
|
|
2962
3725
|
installed: isInstalledPackage(pkgRoot),
|
|
@@ -2964,6 +3727,34 @@ function sourceKitDependencies(rootDir) {
|
|
|
2964
3727
|
}];
|
|
2965
3728
|
});
|
|
2966
3729
|
}
|
|
3730
|
+
/**
|
|
3731
|
+
* The installed packages a system's membership reaches: each is a kit,
|
|
3732
|
+
* whether or not it declares the source condition, and so is every kit its
|
|
3733
|
+
* own system extends or includes. Read before any host resolves (a
|
|
3734
|
+
* bundler's config), so the application's modules import as the system
|
|
3735
|
+
* loader resolves them from the root, and a kit's from its own directory.
|
|
3736
|
+
*/
|
|
3737
|
+
async function systemKitDependencies(rootDir, systemPath, engine) {
|
|
3738
|
+
const workspaces = declaredWorkspacePackages(rootDir);
|
|
3739
|
+
const resolveSpecifier = engine.resolveSpecifier;
|
|
3740
|
+
const systemPackageRoot = findPackageRoot(systemPath);
|
|
3741
|
+
const kitMembers = /* @__PURE__ */ new Map();
|
|
3742
|
+
const members = await extractSystemFilePackages(systemPath, engine, void 0, (specifier, importer) => resolveSpecifier?.(specifier, findPackageRoot(importer) === systemPackageRoot ? rootDir : (0, path.dirname)(importer), [], workspaces, extensionPolicyJson(BUILT_IN_EXTENSION_POLICY))?.path ?? null, void 0, kitMembers);
|
|
3743
|
+
const locatePackage = nativePackageLocator(engine, workspaces);
|
|
3744
|
+
const roots = /* @__PURE__ */ new Map();
|
|
3745
|
+
for (const member of members) {
|
|
3746
|
+
if (!isPackageSpecifier(member)) continue;
|
|
3747
|
+
const name = bareSpecifierPackageName(member);
|
|
3748
|
+
const file = kitMembers.get(member);
|
|
3749
|
+
const pkgRoot = file ? findPackageRoot(file) : locatePackage(name, rootDir);
|
|
3750
|
+
if (pkgRoot !== null && !roots.has(name)) roots.set(name, pkgRoot);
|
|
3751
|
+
}
|
|
3752
|
+
return [...roots].map(([name, pkgRoot]) => ({
|
|
3753
|
+
name,
|
|
3754
|
+
installed: isInstalledPackage(pkgRoot),
|
|
3755
|
+
dependencies: dependencyNames(readPackageManifest(pkgRoot), ["dependencies"])
|
|
3756
|
+
}));
|
|
3757
|
+
}
|
|
2967
3758
|
/** A specifier that names a package: not relative or absolute, and no URL,
|
|
2968
3759
|
* scheme (`node:`, `virtual:`), subpath import or virtual id. */
|
|
2969
3760
|
function isPackageSpecifier(specifier) {
|
|
@@ -2979,22 +3770,19 @@ function isPackageSpecifier(specifier) {
|
|
|
2979
3770
|
* file the engine parses as it is; an adapted source (`.svelte`, `.mdx`)
|
|
2980
3771
|
* reaches the engine only as its generated children.
|
|
2981
3772
|
*/
|
|
2982
|
-
function importedKitDiagnostics(files, engine, rootDir, systemKits) {
|
|
2983
|
-
const {
|
|
2984
|
-
|
|
2985
|
-
|
|
3773
|
+
function importedKitDiagnostics(files, engine, rootDir, systemKits, factsOf) {
|
|
3774
|
+
const parsed = files.filter(({ path: path$3 }) => isEngineTransformExtension(path$3));
|
|
3775
|
+
if (parsed.length === 0) return [];
|
|
3776
|
+
const locatePackage = nativePackageLocator(engine, declaredWorkspacePackages(rootDir));
|
|
2986
3777
|
let facts;
|
|
2987
3778
|
try {
|
|
2988
|
-
facts =
|
|
2989
|
-
path: path$5,
|
|
2990
|
-
source
|
|
2991
|
-
})))), "extractFacts");
|
|
3779
|
+
facts = factsOf(parsed);
|
|
2992
3780
|
} catch {
|
|
2993
3781
|
return [];
|
|
2994
3782
|
}
|
|
2995
3783
|
const seen = new Set(systemKits.filter((specifier) => !(0, path.isAbsolute)(specifier)).map(bareSpecifierPackageName));
|
|
2996
3784
|
const diagnostics = [];
|
|
2997
|
-
for (const [path$
|
|
3785
|
+
for (const [path$4, file] of Object.entries(facts.files)) {
|
|
2998
3786
|
if (file.parsePanicked) continue;
|
|
2999
3787
|
const specifiers = [...file.imports.map((fact) => fact.source), ...file.exports.flatMap((fact) => fact.source === null ? [] : [fact.source])];
|
|
3000
3788
|
for (const specifier of specifiers) {
|
|
@@ -3002,9 +3790,9 @@ function importedKitDiagnostics(files, engine, rootDir, systemKits) {
|
|
|
3002
3790
|
const name = bareSpecifierPackageName(specifier);
|
|
3003
3791
|
if (seen.has(name)) continue;
|
|
3004
3792
|
seen.add(name);
|
|
3005
|
-
const pkgRoot =
|
|
3006
|
-
if (pkgRoot &&
|
|
3007
|
-
file: path$
|
|
3793
|
+
const pkgRoot = locatePackage(name, (0, path.dirname)((0, path.resolve)(rootDir, path$4)));
|
|
3794
|
+
if (pkgRoot && declaresKitSource(engine, pkgRoot)) diagnostics.push({
|
|
3795
|
+
file: path$4,
|
|
3008
3796
|
component: name,
|
|
3009
3797
|
kind: "warn",
|
|
3010
3798
|
message: `the application imports this kit, but its system is not included in the application's system, so its components are not extracted — include the kit's system in the application's system: createSystem().extend(<the kit's system>)`,
|
|
@@ -3016,7 +3804,19 @@ function importedKitDiagnostics(files, engine, rootDir, systemKits) {
|
|
|
3016
3804
|
return diagnostics;
|
|
3017
3805
|
}
|
|
3018
3806
|
/** A kit without the source condition, warned once, or each condition entry
|
|
3019
|
-
*
|
|
3807
|
+
* the loader does not read as source: missing, spelled otherwise on disk,
|
|
3808
|
+
* no package target Node accepts (each read from its runtime target), or
|
|
3809
|
+
* percent-escaped (refused, failing the load). */
|
|
3810
|
+
function packageMismatchDiagnostic(specifier, hostEntry, located) {
|
|
3811
|
+
return {
|
|
3812
|
+
file: specifier,
|
|
3813
|
+
component: "kit",
|
|
3814
|
+
kind: "warn",
|
|
3815
|
+
message: `the host bundler resolves '${specifier}' to ${hostEntry}, which lies in no package, so discovery reads the installed package at ${located} instead and the bundle may render another module than the one analysed — make the bundler resolve '${specifier}' to a package`,
|
|
3816
|
+
code: PACKAGE_MISMATCH,
|
|
3817
|
+
severity: severityFor(PACKAGE_MISMATCH)
|
|
3818
|
+
};
|
|
3819
|
+
}
|
|
3020
3820
|
function sourceConditionDiagnostics(packageName, condition) {
|
|
3021
3821
|
if (condition === null) return [{
|
|
3022
3822
|
file: packageName,
|
|
@@ -3026,11 +3826,11 @@ function sourceConditionDiagnostics(packageName, condition) {
|
|
|
3026
3826
|
code: KIT_WITHOUT_SOURCE_CONDITION,
|
|
3027
3827
|
severity: severityFor(KIT_WITHOUT_SOURCE_CONDITION)
|
|
3028
3828
|
}];
|
|
3029
|
-
return condition.invalid.map(([subpath, target]) => ({
|
|
3829
|
+
return condition.invalid.map(([subpath, target, why]) => ({
|
|
3030
3830
|
file: packageName,
|
|
3031
3831
|
component: "kit",
|
|
3032
3832
|
kind: "warn",
|
|
3033
|
-
message: `exports["${subpath}"].${KIT_SOURCE_CONDITION} names ${target}, which
|
|
3833
|
+
message: why.includes("percent-escape unsupported") ? `exports["${subpath}"].${KIT_SOURCE_CONDITION} names ${target}, which ${why}, so the system loader fails to load that entry` : `exports["${subpath}"].${KIT_SOURCE_CONDITION} names ${target}, which ${why}, so that entry is read from its runtime target instead of source`,
|
|
3034
3834
|
code: INVALID_KIT_SOURCE_CONDITION,
|
|
3035
3835
|
severity: severityFor(INVALID_KIT_SOURCE_CONDITION)
|
|
3036
3836
|
}));
|
|
@@ -3087,13 +3887,16 @@ function excludeCollectedPackages(collected, rejectedSpecifiers, rootDir) {
|
|
|
3087
3887
|
fileOwners,
|
|
3088
3888
|
outcomes: collected.outcomes,
|
|
3089
3889
|
diagnostics: collected.diagnostics,
|
|
3090
|
-
kitDescriptors: collected.kitDescriptors.filter((record) => !rejectedDirs.some((dir) => isPathWithinRoot((0, path.resolve)(rootDir, record.packageRoot), dir)))
|
|
3890
|
+
kitDescriptors: collected.kitDescriptors.filter((record) => !rejectedDirs.some((dir) => isPathWithinRoot((0, path.resolve)(rootDir, record.packageRoot), dir))),
|
|
3891
|
+
packageInstances: Object.fromEntries(Object.entries(collected.packageInstances).filter(([, root]) => !rejectedDirs.some((dir) => isPathWithinRoot(root, dir))))
|
|
3091
3892
|
};
|
|
3092
3893
|
}
|
|
3093
|
-
|
|
3094
|
-
|
|
3894
|
+
/** Every unresolvable include, with why where the resolver said, and the
|
|
3895
|
+
* system file that includes them when the caller knows it. */
|
|
3896
|
+
function unresolvableIncludesMessage(outcomes, importer) {
|
|
3897
|
+
const unresolvable = outcomes.filter((record) => record.outcome === "unresolvable").map((record) => record.reason === void 0 ? record.specifier : `${record.specifier} (${record.reason})`);
|
|
3095
3898
|
if (unresolvable.length === 0) return null;
|
|
3096
|
-
return `[animus-extract] unresolvable include specifier(s): ${unresolvable.join(", ")}`;
|
|
3899
|
+
return `[animus-extract] unresolvable include specifier(s)${importer === void 0 ? "" : ` in ${importer}`}: ${unresolvable.join(", ")}`;
|
|
3097
3900
|
}
|
|
3098
3901
|
/** A stale dist silently skews merged registry content while discovery
|
|
3099
3902
|
* compiles the fresh sources; null when no specifier is stale. */
|
|
@@ -3108,12 +3911,12 @@ function staleDistIncludesMessage(outcomes) {
|
|
|
3108
3911
|
function engineModuleParser(engine) {
|
|
3109
3912
|
const { extractFacts } = engine;
|
|
3110
3913
|
if (!extractFacts) return void 0;
|
|
3111
|
-
return (source, path$
|
|
3914
|
+
return (source, path$5) => {
|
|
3112
3915
|
try {
|
|
3113
3916
|
const facts = parseInternalWire(extractFacts(JSON.stringify([{
|
|
3114
|
-
path: path$
|
|
3917
|
+
path: path$5,
|
|
3115
3918
|
source
|
|
3116
|
-
}])), "extractFacts").files[path$
|
|
3919
|
+
}])), "extractFacts").files[path$5];
|
|
3117
3920
|
return facts && !facts.parsePanicked ? {
|
|
3118
3921
|
imports: facts.imports,
|
|
3119
3922
|
exports: facts.exports,
|
|
@@ -3124,178 +3927,24 @@ function engineModuleParser(engine) {
|
|
|
3124
3927
|
}
|
|
3125
3928
|
};
|
|
3126
3929
|
}
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
*
|
|
3130
|
-
async function resolveModuleFile(importer, specifier, resolvePackage) {
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
return
|
|
3930
|
+
/** The file a specifier names from `importer`, or why it names none: a
|
|
3931
|
+
* relative one by the ingestion's probe order, spelled exactly, a bare one
|
|
3932
|
+
* by the host's package resolution. */
|
|
3933
|
+
async function resolveModuleFile(importer, specifier, resolvePackage, extensions) {
|
|
3934
|
+
const unresolved = { why: `'${specifier}' could not be resolved` };
|
|
3935
|
+
if (specifier.startsWith(".")) {
|
|
3936
|
+
const probed = probeOnDisk(relativeSourceCandidates(importer, specifier, extensions), (0, path.dirname)(importer));
|
|
3937
|
+
if (probed.kind === "found") return { file: probed.path };
|
|
3938
|
+
return probed.kind === "case-mismatch" ? {
|
|
3939
|
+
why: caseMismatchReason(`'${specifier}'`, probed, "spell the import as the file is spelled"),
|
|
3940
|
+
caseMismatch: true
|
|
3941
|
+
} : unresolved;
|
|
3136
3942
|
}
|
|
3137
|
-
}
|
|
3138
|
-
const escapeRegExp$1 = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3139
|
-
/**
|
|
3140
|
-
* Follows `name`, exported by the module `specifier` names from `importer`,
|
|
3141
|
-
* through re-exports to its declaration. It is Animus's factory only when
|
|
3142
|
-
* that is `createSystem` of `@animus-ui/system`, and another identity only
|
|
3143
|
-
* when a module is shown to declare it; anything discovery cannot follow is
|
|
3144
|
-
* unknown.
|
|
3145
|
-
*/
|
|
3146
|
-
async function exportIdentity(importer, specifier, name, following, seen) {
|
|
3147
|
-
if (ANIMUS_SYSTEM_SPECIFIER.test(specifier)) return name === "createSystem" ? { kind: "animus" } : {
|
|
3148
|
-
kind: "other",
|
|
3149
|
-
what: `'${name}' of ${specifier}`
|
|
3150
|
-
};
|
|
3151
|
-
const file = await resolveModuleFile(importer, specifier, following.resolvePackage);
|
|
3152
|
-
if (file === null) return {
|
|
3153
|
-
kind: "unknown",
|
|
3154
|
-
why: `'${specifier}' could not be resolved`
|
|
3155
|
-
};
|
|
3156
|
-
const key = `${file}#${name}`;
|
|
3157
|
-
if (seen.has(key)) return {
|
|
3158
|
-
kind: "unknown",
|
|
3159
|
-
why: `'${specifier}' re-exports it in a cycle`
|
|
3160
|
-
};
|
|
3161
|
-
seen.add(key);
|
|
3162
|
-
let source;
|
|
3163
3943
|
try {
|
|
3164
|
-
|
|
3944
|
+
const file = await resolvePackage?.(specifier, importer);
|
|
3945
|
+
return file ? { file: file.split("?")[0] } : unresolved;
|
|
3165
3946
|
} catch {
|
|
3166
|
-
return
|
|
3167
|
-
kind: "unknown",
|
|
3168
|
-
why: `'${specifier}' could not be read`
|
|
3169
|
-
};
|
|
3170
|
-
}
|
|
3171
|
-
const record = following.parseModule(source, file);
|
|
3172
|
-
if (record === null) return {
|
|
3173
|
-
kind: "unknown",
|
|
3174
|
-
why: `'${specifier}' could not be parsed`
|
|
3175
|
-
};
|
|
3176
|
-
const exported = record.exports.find((entry) => entry.exported === name);
|
|
3177
|
-
if (exported?.source) return exportIdentity(file, exported.source, exported.original ?? name, following, seen);
|
|
3178
|
-
const local = exported?.local ?? name;
|
|
3179
|
-
const imported = record.imports.find((entry) => entry.local === local);
|
|
3180
|
-
if (exported && imported) return exportIdentity(file, imported.source, imported.imported, following, seen);
|
|
3181
|
-
if (exported || new RegExp(`\\bexport\\s+(?:async\\s+)?(?:function\\*?|class|const|let|var)\\s+${escapeRegExp$1(name)}\\b`).test(source)) return {
|
|
3182
|
-
kind: "other",
|
|
3183
|
-
what: `the '${name}' that '${specifier}' declares`
|
|
3184
|
-
};
|
|
3185
|
-
const stars = [];
|
|
3186
|
-
for (const match of source.matchAll(/\bexport\s*\*\s*from\s*['"]([^'"]+)['"]/g)) stars.push(await exportIdentity(file, match[1], name, following, seen));
|
|
3187
|
-
const definite = stars.filter((identity) => identity.kind !== "unknown");
|
|
3188
|
-
if (definite.length === 1) return definite[0];
|
|
3189
|
-
if (definite.length > 1) return {
|
|
3190
|
-
kind: "unknown",
|
|
3191
|
-
why: `more than one \`export *\` of '${specifier}' provides '${name}'`
|
|
3192
|
-
};
|
|
3193
|
-
return stars.find((identity) => identity.kind === "unknown") ?? {
|
|
3194
|
-
kind: "unknown",
|
|
3195
|
-
why: `'${specifier}' has no export '${name}' discovery can read`
|
|
3196
|
-
};
|
|
3197
|
-
}
|
|
3198
|
-
/** 1-based line and column of `offset` in `source`. */
|
|
3199
|
-
function locationIn(source, offset) {
|
|
3200
|
-
const before = source.slice(0, offset);
|
|
3201
|
-
const lineStart = before.lastIndexOf("\n") + 1;
|
|
3202
|
-
return {
|
|
3203
|
-
line: before.split("\n").length,
|
|
3204
|
-
column: offset - lineStart + 1
|
|
3205
|
-
};
|
|
3206
|
-
}
|
|
3207
|
-
const NAMESPACE_IMPORT = /\bimport\s+(?:[a-zA-Z_$][a-zA-Z0-9_$]*\s*,\s*)?\*\s*as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
3208
|
-
/**
|
|
3209
|
-
* The callees that are Animus's `createSystem` in a parsed system file. A
|
|
3210
|
-
* binding counts once its identity is followed to the factory: a named
|
|
3211
|
-
* import, through local and package re-exports; a namespace import's
|
|
3212
|
-
* member; or a property destructured from a namespace import, `require` or
|
|
3213
|
-
* `import()` of a module. A binding named `createSystem` shown to be
|
|
3214
|
-
* something else is no root. One whose identity discovery cannot follow
|
|
3215
|
-
* keeps the admission spelling gave it, so a resolution limit never drops a
|
|
3216
|
-
* kit. Both are reported. A call of the bare name, which the file neither
|
|
3217
|
-
* imports nor declares, is no root: the system loader evaluates the file
|
|
3218
|
-
* without auto-imports, where the name is undefined. It is reported once.
|
|
3219
|
-
*/
|
|
3220
|
-
async function systemRoots(systemFilePath, source, record, following) {
|
|
3221
|
-
const { imports } = record;
|
|
3222
|
-
const roots = /* @__PURE__ */ new Set();
|
|
3223
|
-
const identityOf = (specifier, name) => exportIdentity(systemFilePath, specifier, name, following, /* @__PURE__ */ new Set());
|
|
3224
|
-
const called = (callee) => callOf(callee).test(source);
|
|
3225
|
-
/** Admits a binding named `createSystem` by its identity: an unknown one
|
|
3226
|
-
* keeps `spellingAdmits`, and every unproven one is reported. */
|
|
3227
|
-
const admit = (local, offset, identity, spellingAdmits) => {
|
|
3228
|
-
if (identity.kind === "animus") {
|
|
3229
|
-
roots.add(local);
|
|
3230
|
-
return;
|
|
3231
|
-
}
|
|
3232
|
-
if (identity.kind === "unknown" && spellingAdmits) roots.add(local);
|
|
3233
|
-
const shown = identity.kind === "other" ? `it is ${identity.what}, so it is not read as a system root` : `discovery cannot follow what it is bound to (${identity.why}), so it is ${spellingAdmits ? "still read" : "not read"} as a system root by its name alone`;
|
|
3234
|
-
following.report?.({
|
|
3235
|
-
file: systemFilePath,
|
|
3236
|
-
component: local,
|
|
3237
|
-
kind: "warn",
|
|
3238
|
-
message: `'${local}' is not proven to be Animus's createSystem: ${shown} — import createSystem from '@animus-ui/system', directly or through a re-export discovery can follow`,
|
|
3239
|
-
code: UNPROVEN_ROOT_BINDING,
|
|
3240
|
-
severity: severityFor(UNPROVEN_ROOT_BINDING),
|
|
3241
|
-
...locationIn(source, offset)
|
|
3242
|
-
});
|
|
3243
|
-
};
|
|
3244
|
-
for (const binding of imports) {
|
|
3245
|
-
if (binding.imported === "createSystem" || binding.local === "createSystem") {
|
|
3246
|
-
const statement = new RegExp(`\\bimport\\b[^;]*?\\bfrom\\s*['"]${escapeRegExp$1(binding.source)}['"]`, "g");
|
|
3247
|
-
let offset = 0;
|
|
3248
|
-
for (const match of source.matchAll(statement)) {
|
|
3249
|
-
const at = match[0].search(new RegExp(`(?<![a-zA-Z0-9_$])${escapeRegExp$1(binding.local)}\\b`));
|
|
3250
|
-
if (at !== -1) {
|
|
3251
|
-
offset = match.index + at;
|
|
3252
|
-
break;
|
|
3253
|
-
}
|
|
3254
|
-
}
|
|
3255
|
-
admit(binding.local, offset, await identityOf(binding.source, binding.imported), binding.imported === "createSystem");
|
|
3256
|
-
continue;
|
|
3257
|
-
}
|
|
3258
|
-
if (binding.source.startsWith(".") && called(binding.local) && (await identityOf(binding.source, binding.imported)).kind === "animus") roots.add(binding.local);
|
|
3259
|
-
}
|
|
3260
|
-
const namespaces = /* @__PURE__ */ new Map();
|
|
3261
|
-
for (const [, namespace, specifier] of source.matchAll(NAMESPACE_IMPORT)) {
|
|
3262
|
-
namespaces.set(namespace, specifier);
|
|
3263
|
-
const member = `${namespace}.createSystem`;
|
|
3264
|
-
if (ANIMUS_SYSTEM_SPECIFIER.test(specifier) || specifier.startsWith(".") && called(member) && (await identityOf(specifier, "createSystem")).kind === "animus") roots.add(member);
|
|
3265
|
-
}
|
|
3266
|
-
const destructuredFrom = (initializer) => {
|
|
3267
|
-
const loaded = /^\(?\s*(?:(?:await\s+)?import|require)\(\s*['"]([^'"]+)['"]\s*\)\s*\)?$/.exec(initializer);
|
|
3268
|
-
if (loaded) return identityOf(loaded[1], "createSystem");
|
|
3269
|
-
const namespace = namespaces.get(initializer);
|
|
3270
|
-
if (namespace !== void 0) return identityOf(namespace, "createSystem");
|
|
3271
|
-
return Promise.resolve({
|
|
3272
|
-
kind: "unknown",
|
|
3273
|
-
why: `it is destructured from '${initializer}', which is not a module namespace`
|
|
3274
|
-
});
|
|
3275
|
-
};
|
|
3276
|
-
for (const { local, offset, initializer } of destructuredCreateSystems(source)) admit(local, offset, await destructuredFrom(initializer), local === "createSystem");
|
|
3277
|
-
const unimported = unimportedCreateSystemCall(systemFilePath, record);
|
|
3278
|
-
if (unimported) following.report?.(unimported);
|
|
3279
|
-
return roots;
|
|
3280
|
-
}
|
|
3281
|
-
/** A call of `callee` as a whole name, not a member. */
|
|
3282
|
-
function callOf(callee) {
|
|
3283
|
-
return new RegExp(`(?<![a-zA-Z0-9_$.])${escapeRegExp$1(callee)}\\s*\\(`);
|
|
3284
|
-
}
|
|
3285
|
-
/** Each `createSystem` property a declaration destructures: its local name,
|
|
3286
|
-
* its offset in `source`, and the destructured initializer. */
|
|
3287
|
-
function* destructuredCreateSystems(source) {
|
|
3288
|
-
for (const match of source.matchAll(/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*([^;\n]+)/g)) {
|
|
3289
|
-
const [whole, pattern, initializer] = match;
|
|
3290
|
-
for (const property of pattern.split(",")) {
|
|
3291
|
-
const binding = /^\s*createSystem\s*(?::\s*([a-zA-Z_$][a-zA-Z0-9_$]*))?\s*(?:=[\s\S]*)?$/.exec(property);
|
|
3292
|
-
if (!binding) continue;
|
|
3293
|
-
yield {
|
|
3294
|
-
local: binding[1] ?? "createSystem",
|
|
3295
|
-
offset: match.index + whole.indexOf("createSystem"),
|
|
3296
|
-
initializer: initializer.trim()
|
|
3297
|
-
};
|
|
3298
|
-
}
|
|
3947
|
+
return unresolved;
|
|
3299
3948
|
}
|
|
3300
3949
|
}
|
|
3301
3950
|
/** The warning for a `createSystem` call that the parser's scopes leave
|
|
@@ -3315,229 +3964,427 @@ function unimportedCreateSystemCall(systemFilePath, record) {
|
|
|
3315
3964
|
column: call[1]
|
|
3316
3965
|
};
|
|
3317
3966
|
}
|
|
3318
|
-
/**
|
|
3319
|
-
*
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3967
|
+
/** The rounds a membership read resolves the modules it asks for: each
|
|
3968
|
+
* reads the modules the last one's identities stopped at, one re-export
|
|
3969
|
+
* hop further. Past it, what is still asked for is finalized as
|
|
3970
|
+
* unresolved and read once more, so an identity it could not follow keeps
|
|
3971
|
+
* the admission its name gives it, with a finding. */
|
|
3972
|
+
const MEMBERSHIP_ROUNDS = 256;
|
|
3973
|
+
/**
|
|
3974
|
+
* The packages and local modules a system file's roots extend or include,
|
|
3975
|
+
* from the engine's own read of it (spec §2.3 step 5): a bare specifier as
|
|
3976
|
+
* its import spells it, a relative one resolved against the system file.
|
|
3977
|
+
* The engine follows each root binding's identity through the modules this
|
|
3978
|
+
* supplies on request: a relative one by the host's extension order,
|
|
3979
|
+
* spelled exactly, a bare one by the host's package resolution.
|
|
3980
|
+
*/
|
|
3981
|
+
async function extractSystemFilePackages(systemFilePath, engine, report, resolvePackage, extensions, kitMembers) {
|
|
3982
|
+
const { systemMembership } = engine;
|
|
3983
|
+
if (systemMembership === void 0) throw new Error("the native engine does not expose systemMembership, which discovery needs — rebuild @animus-ui/extract");
|
|
3984
|
+
const files = {};
|
|
3326
3985
|
try {
|
|
3327
|
-
|
|
3986
|
+
files[systemFilePath] = (0, fs.readFileSync)(systemFilePath, "utf-8");
|
|
3328
3987
|
} catch {
|
|
3329
3988
|
return [];
|
|
3330
3989
|
}
|
|
3331
|
-
const
|
|
3332
|
-
let
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
}
|
|
3990
|
+
const resolved = {};
|
|
3991
|
+
let answer;
|
|
3992
|
+
for (let round = 0;; round++) {
|
|
3993
|
+
answer = parseInternalWire(systemMembership(JSON.stringify({
|
|
3994
|
+
system: systemFilePath,
|
|
3995
|
+
files,
|
|
3996
|
+
resolved
|
|
3997
|
+
})), "systemMembership");
|
|
3998
|
+
if (answer.needs.length === 0) break;
|
|
3999
|
+
for (const [importer, specifier] of answer.needs) {
|
|
4000
|
+
const key = `${importer}\0${specifier}`;
|
|
4001
|
+
const found = round >= MEMBERSHIP_ROUNDS ? { why: `following '${specifier}' stopped after ${MEMBERSHIP_ROUNDS} re-exports` } : await resolveModuleFile(importer, specifier, resolvePackage, extensions);
|
|
4002
|
+
if ("file" in found) {
|
|
4003
|
+
resolved[key] = { file: found.file };
|
|
4004
|
+
if (!(found.file in files)) try {
|
|
4005
|
+
files[found.file] = (0, fs.readFileSync)(found.file, "utf-8");
|
|
4006
|
+
} catch {}
|
|
4007
|
+
} else resolved[key] = {
|
|
4008
|
+
why: found.why,
|
|
4009
|
+
caseMismatch: found.caseMismatch
|
|
4010
|
+
};
|
|
3349
4011
|
}
|
|
3350
|
-
}
|
|
3351
|
-
if (
|
|
3352
|
-
|
|
3353
|
-
const
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
4012
|
+
}
|
|
4013
|
+
if (!answer.parsed) return [];
|
|
4014
|
+
const reportedUnimported = /* @__PURE__ */ new Set();
|
|
4015
|
+
for (const finding of answer.findings) {
|
|
4016
|
+
if (finding.kind === "unimported") {
|
|
4017
|
+
if (reportedUnimported.has(finding.file)) continue;
|
|
4018
|
+
reportedUnimported.add(finding.file);
|
|
4019
|
+
report?.({
|
|
4020
|
+
file: finding.file,
|
|
4021
|
+
component: "createSystem",
|
|
4022
|
+
kind: "warn",
|
|
4023
|
+
message: `'createSystem' is called with no import or local binding, so it is not read as a system root: the system loader evaluates this file without auto-imports, where the name is undefined — import createSystem from '@animus-ui/system'`,
|
|
4024
|
+
code: UNIMPORTED_CREATE_SYSTEM,
|
|
4025
|
+
severity: severityFor(UNIMPORTED_CREATE_SYSTEM),
|
|
4026
|
+
line: finding.line,
|
|
4027
|
+
column: finding.column
|
|
4028
|
+
});
|
|
4029
|
+
continue;
|
|
4030
|
+
}
|
|
4031
|
+
if (finding.kind === "escapes") {
|
|
4032
|
+
report?.({
|
|
4033
|
+
file: finding.file,
|
|
4034
|
+
component: "createSystem",
|
|
4035
|
+
kind: "warn",
|
|
4036
|
+
message: `a system builder leaves what discovery follows here (${finding.how}), so a kit extended on it from there is not read as a member and its components are not extracted — extend it in the chain that creates it, or through a variable`,
|
|
4037
|
+
code: UNFOLLOWED_SYSTEM_BUILDER,
|
|
4038
|
+
severity: severityFor(UNFOLLOWED_SYSTEM_BUILDER),
|
|
4039
|
+
line: finding.line,
|
|
4040
|
+
column: finding.column
|
|
4041
|
+
});
|
|
4042
|
+
continue;
|
|
3369
4043
|
}
|
|
4044
|
+
const shown = finding.what !== null ? `it is ${finding.what}, so it is not read as a system root` : `discovery cannot follow what it is bound to (${finding.why}), so it is ${finding.admitted ? "still read" : "not read"} as a system root by its name alone`;
|
|
4045
|
+
report?.({
|
|
4046
|
+
file: finding.file,
|
|
4047
|
+
component: finding.local,
|
|
4048
|
+
kind: "warn",
|
|
4049
|
+
message: `'${finding.local}' is not proven to be Animus's createSystem: ${shown} — import createSystem from '@animus-ui/system', directly or through a re-export discovery can follow`,
|
|
4050
|
+
code: UNPROVEN_ROOT_BINDING,
|
|
4051
|
+
severity: severityFor(UNPROVEN_ROOT_BINDING),
|
|
4052
|
+
line: finding.line,
|
|
4053
|
+
column: finding.column
|
|
4054
|
+
});
|
|
4055
|
+
}
|
|
4056
|
+
const systemPackageRoot = findPackageRoot(systemFilePath);
|
|
4057
|
+
for (const { specifier, importer } of answer.members) {
|
|
4058
|
+
const file = resolved[`${importer}\0${specifier}`]?.file;
|
|
4059
|
+
if (file !== void 0 && !specifier.startsWith(".") && findPackageRoot(importer) !== systemPackageRoot && !kitMembers?.has(specifier)) kitMembers?.set(specifier, file);
|
|
4060
|
+
}
|
|
4061
|
+
return [...new Set(answer.members.map(({ specifier, importer }) => specifier.startsWith(".") ? (0, path.resolve)((0, path.dirname)(importer), specifier) : specifier))];
|
|
4062
|
+
}
|
|
4063
|
+
//#endregion
|
|
4064
|
+
//#region pipeline/alias-agreement.ts
|
|
4065
|
+
/** A file's identity on disk: its real path, which follows links and
|
|
4066
|
+
* takes the case the filesystem lists; the path itself where it is not
|
|
4067
|
+
* there. */
|
|
4068
|
+
function physical(file) {
|
|
4069
|
+
try {
|
|
4070
|
+
return node_fs.realpathSync.native(file);
|
|
4071
|
+
} catch {
|
|
4072
|
+
return (0, node_path.resolve)(file);
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
4075
|
+
/** What a host's module id names: a file on disk, its query dropped and a
|
|
4076
|
+
* dev server's `/@fs/` prefix removed; a virtual id as written; or no
|
|
4077
|
+
* file, where the id names a path nothing is at (an alias applied to a
|
|
4078
|
+
* missing module). */
|
|
4079
|
+
function hostTarget(id) {
|
|
4080
|
+
const path = id.split("?")[0];
|
|
4081
|
+
const file = path.startsWith("/@fs/") ? path.slice(4) : path;
|
|
4082
|
+
if (id.startsWith("\0") || !(0, node_path.isAbsolute)(file)) return { virtual: id };
|
|
4083
|
+
return (0, node_fs.existsSync)(file) ? { file } : null;
|
|
4084
|
+
}
|
|
4085
|
+
/** What a session's comparisons keep between analyses (spec §2.2 A7):
|
|
4086
|
+
* each file's result by its content hash, while the aliases and the file
|
|
4087
|
+
* set are the same. A new alias set, or a file added or removed, compares
|
|
4088
|
+
* every file again. */
|
|
4089
|
+
var AliasAgreementCache = class {
|
|
4090
|
+
scope = "";
|
|
4091
|
+
byFile = /* @__PURE__ */ new Map();
|
|
4092
|
+
};
|
|
4093
|
+
function packageReadRecord(input) {
|
|
4094
|
+
let analysed = null;
|
|
4095
|
+
const rendered = /* @__PURE__ */ new Map();
|
|
4096
|
+
return {
|
|
4097
|
+
rootDir: input.rootDir,
|
|
4098
|
+
roots: input.roots,
|
|
4099
|
+
redirected: input.redirected,
|
|
4100
|
+
holds(file) {
|
|
4101
|
+
analysed ??= new Set(input.analysed.map((path) => physical((0, node_path.join)(input.rootDir, path))));
|
|
4102
|
+
return analysed.has(file);
|
|
4103
|
+
},
|
|
4104
|
+
rendersBuilder(file) {
|
|
4105
|
+
let renders = rendered.get(file);
|
|
4106
|
+
if (renders === void 0) {
|
|
4107
|
+
renders = input.rendersBuilder(file);
|
|
4108
|
+
rendered.set(file, renders);
|
|
4109
|
+
}
|
|
4110
|
+
return renders;
|
|
4111
|
+
},
|
|
4112
|
+
reported: /* @__PURE__ */ new Set()
|
|
3370
4113
|
};
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
4114
|
+
}
|
|
4115
|
+
/**
|
|
4116
|
+
* An import of a discovered package that the host resolves, from its
|
|
4117
|
+
* importer, to `resolved` (spec §2.2 A4). None where the analysis holds
|
|
4118
|
+
* that file, or the request is not a discovered package's. Otherwise the
|
|
4119
|
+
* importer would render a file extraction never read:
|
|
4120
|
+
* - another instance's: unextracted builder code
|
|
4121
|
+
* (`animus.discovery.unread-package-instance`), or, where a source
|
|
4122
|
+
* redirect serves the instance read in its place, that instance
|
|
4123
|
+
* (`animus.discovery.replaced-package-instance`);
|
|
4124
|
+
* - a file of the instance read that the analysis does not hold, and no
|
|
4125
|
+
* redirect covers, which declares builder chains (a compiled subpath):
|
|
4126
|
+
* `animus.discovery.unread-package-instance`.
|
|
4127
|
+
*/
|
|
4128
|
+
function packageInstanceFinding(record, importer, specifier, resolved) {
|
|
4129
|
+
const readRoot = isPackageSpecifier(specifier) ? record.roots[bareSpecifierPackageName(specifier)] : void 0;
|
|
4130
|
+
if (readRoot === void 0) return null;
|
|
4131
|
+
const file = physical(resolved);
|
|
4132
|
+
if (record.holds(file)) return null;
|
|
4133
|
+
const instance = physical(findPackageRoot(file));
|
|
4134
|
+
const redirected = record.redirected.has(specifier);
|
|
4135
|
+
const shown = (path) => (0, node_path.relative)(record.rootDir, path).split(node_path.sep).join(node_path.posix.sep);
|
|
4136
|
+
const finding = (code, message) => ({
|
|
4137
|
+
file: importer,
|
|
4138
|
+
component: `import '${specifier}'`,
|
|
4139
|
+
kind: code === "animus.discovery.replaced-package-instance" ? "warn" : "error",
|
|
4140
|
+
message,
|
|
4141
|
+
code,
|
|
4142
|
+
severity: severityFor(code)
|
|
4143
|
+
});
|
|
4144
|
+
if (instance === readRoot) {
|
|
4145
|
+
if (redirected || !record.rendersBuilder(file)) return null;
|
|
4146
|
+
return finding(UNREAD_PACKAGE_INSTANCE, `'${specifier}' in ${importer} resolves through the host bundler to ${shown(file)}, a file of the package extraction reads (${shown(readRoot)}) that it does not analyse, and which declares builder chains, so this importer would render unextracted builder code — import the package by an entry extraction reads, or give this entry an "animus" source condition`);
|
|
4147
|
+
}
|
|
4148
|
+
const where = `'${specifier}' in ${importer} resolves through the host bundler to ${shown(file)}, in another instance of the package (${shown(instance)}) than extraction reads (${shown(readRoot)})`;
|
|
4149
|
+
return redirected ? finding(REPLACED_PACKAGE_INSTANCE, `${where}; the source redirect serves the instance read in its place, so this importer renders that one, not its own — resolve the package to one instance`) : finding(UNREAD_PACKAGE_INSTANCE, `${where}, which is not analysed, so this importer would render unextracted builder code — resolve the package to one instance`);
|
|
4150
|
+
}
|
|
4151
|
+
/**
|
|
4152
|
+
* Where the analysis and the host disagree on a path alias (spec §2.2 A7,
|
|
4153
|
+
* report only: resolution never changes). Each analysed import whose
|
|
4154
|
+
* specifier, as the parser decodes it, an alias the analysis reads names
|
|
4155
|
+
* (tsconfig paths, or the host's own aliases) is resolved as the analysis
|
|
4156
|
+
* resolves it (the alias's expansion through the host's extension order)
|
|
4157
|
+
* and by the host's own resolver. A different physical file, or a file
|
|
4158
|
+
* only one of them finds, is `animus.discovery.alias-mismatch`. A request
|
|
4159
|
+
* the host's resolver fails on is unavailable for that request alone.
|
|
4160
|
+
*
|
|
4161
|
+
* Each import of a discovered package is resolved by the host from its
|
|
4162
|
+
* importer too (spec §2.2 A4): an answer in another instance than the one
|
|
4163
|
+
* read, in a file the analysis does not hold, is
|
|
4164
|
+
* `animus.discovery.unread-package-instance` (the importer would render
|
|
4165
|
+
* unextracted builder code), or `animus.discovery.replaced-package-instance`
|
|
4166
|
+
* where a source redirect serves the instance read in its place.
|
|
4167
|
+
*/
|
|
4168
|
+
async function compareAliases(input) {
|
|
4169
|
+
const { cache, packages } = input;
|
|
4170
|
+
const scope = JSON.stringify([
|
|
4171
|
+
input.pathAliasesJson,
|
|
4172
|
+
input.fileEntries.map((entry) => entry.path).sort(),
|
|
4173
|
+
packages?.roots ?? {},
|
|
4174
|
+
[...packages?.redirected ?? []].sort()
|
|
4175
|
+
]);
|
|
4176
|
+
if (cache.scope !== scope) {
|
|
4177
|
+
cache.scope = scope;
|
|
4178
|
+
cache.byFile.clear();
|
|
4179
|
+
}
|
|
4180
|
+
if (!(input.pathAliasesJson !== null && JSON.parse(input.pathAliasesJson).aliases.length > 0) && Object.keys(packages?.roots ?? {}).length === 0) return {
|
|
4181
|
+
findings: [],
|
|
4182
|
+
unavailable: 0
|
|
3377
4183
|
};
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
pos = skipTrivia(pos);
|
|
3392
|
-
continue;
|
|
3393
|
-
}
|
|
3394
|
-
if ("<([{".includes(ch)) depth++;
|
|
3395
|
-
else if (")]}".includes(ch) || ch === ">" && source[pos - 1] !== "=") {
|
|
3396
|
-
depth--;
|
|
3397
|
-
if (depth === 0) return pos + 1;
|
|
3398
|
-
}
|
|
3399
|
-
pos++;
|
|
4184
|
+
const changed = input.fileEntries.filter((entry) => cache.byFile.get(entry.path)?.hash !== entry.hash);
|
|
4185
|
+
const { files, bases } = changed.length === 0 ? { files: {} } : JSON.parse(input.moduleSpecifiers(JSON.stringify(changed.map(({ path, source }) => ({
|
|
4186
|
+
path,
|
|
4187
|
+
source
|
|
4188
|
+
}))), input.pathAliasesJson ?? void 0));
|
|
4189
|
+
const analysed = new Set(input.fileEntries.map((entry) => entry.path));
|
|
4190
|
+
const packageAnswers = /* @__PURE__ */ new Map();
|
|
4191
|
+
const comparePackage = async (record, importer, specifier) => {
|
|
4192
|
+
const key = `${node_path.posix.dirname(importer)}\0${specifier}`;
|
|
4193
|
+
let answer = packageAnswers.get(key);
|
|
4194
|
+
if (answer === void 0) {
|
|
4195
|
+
answer = input.resolve(specifier, (0, node_path.join)(input.rootDir, importer));
|
|
4196
|
+
packageAnswers.set(key, answer);
|
|
3400
4197
|
}
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
let cursor = skipTrivia(pos);
|
|
3407
|
-
if (source[cursor] !== ".") return pos;
|
|
3408
|
-
cursor = skipTrivia(cursor + 1);
|
|
3409
|
-
const method = IDENT_START_RE.exec(source.slice(cursor))?.[0];
|
|
3410
|
-
if (method !== "extend" && method !== "from") return pos;
|
|
3411
|
-
cursor = skipTrivia(cursor + method.length);
|
|
3412
|
-
if (source[cursor] === "<") {
|
|
3413
|
-
const afterTypeArguments = skipBalanced(cursor);
|
|
3414
|
-
if (afterTypeArguments === -1) return pos;
|
|
3415
|
-
cursor = skipTrivia(afterTypeArguments);
|
|
3416
|
-
}
|
|
3417
|
-
if (source[cursor] !== "(") return pos;
|
|
3418
|
-
cursor = skipTrivia(cursor + 1);
|
|
3419
|
-
const base = IDENT_START_RE.exec(source.slice(cursor))?.[0];
|
|
3420
|
-
if (!base) return pos;
|
|
3421
|
-
cursor = skipTrivia(cursor + base.length);
|
|
3422
|
-
while (source[cursor] === ".") {
|
|
3423
|
-
const afterDot = skipTrivia(cursor + 1);
|
|
3424
|
-
const segment = IDENT_START_RE.exec(source.slice(afterDot))?.[0];
|
|
3425
|
-
if (!segment) break;
|
|
3426
|
-
cursor = skipTrivia(afterDot + segment.length);
|
|
3427
|
-
}
|
|
3428
|
-
if (source[cursor] === ",") cursor = skipTrivia(cursor + 1);
|
|
3429
|
-
if (source[cursor] !== ")") return pos;
|
|
3430
|
-
identifiers.add(base);
|
|
3431
|
-
pos = cursor + 1;
|
|
4198
|
+
let id;
|
|
4199
|
+
try {
|
|
4200
|
+
id = await answer;
|
|
4201
|
+
} catch {
|
|
4202
|
+
return "unavailable";
|
|
3432
4203
|
}
|
|
4204
|
+
const host = id === null ? null : hostTarget(id);
|
|
4205
|
+
if (host === null || "virtual" in host) return null;
|
|
4206
|
+
return packageInstanceFinding(record, importer, specifier, host.file);
|
|
3433
4207
|
};
|
|
3434
|
-
const
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
cursor++;
|
|
3443
|
-
while (cursor < source.length) {
|
|
3444
|
-
const ch = source[cursor];
|
|
3445
|
-
if (ch === ";" || ch === ",") break;
|
|
3446
|
-
if (ch === "\n" && /^\s*(?:export\s+)?(?:const|let|var|function|class|type|interface|import)\b/.test(source.slice(cursor + 1, cursor + 80))) break;
|
|
3447
|
-
if (ch === "=" && source[cursor + 1] !== ">") break;
|
|
3448
|
-
if ("<([{".includes(ch) || ch === "'" || ch === "\"" || ch === "`") {
|
|
3449
|
-
const after = "<([{".includes(ch) ? skipBalanced(cursor) : skipString(cursor);
|
|
3450
|
-
if (after === -1) break;
|
|
3451
|
-
cursor = after;
|
|
3452
|
-
continue;
|
|
3453
|
-
}
|
|
3454
|
-
cursor = ch === "=" ? cursor + 2 : cursor + 1;
|
|
3455
|
-
}
|
|
4208
|
+
const compare = async (importer, specifier, base) => {
|
|
4209
|
+
const candidate = hostCandidate(input.rootDir, base, analysed, input.order, input.readings);
|
|
4210
|
+
const analysis = candidate === null ? null : candidate.analysedAs ?? candidate.candidate.split("?")[0];
|
|
4211
|
+
let id;
|
|
4212
|
+
try {
|
|
4213
|
+
id = await input.resolve(specifier, (0, node_path.join)(input.rootDir, importer));
|
|
4214
|
+
} catch {
|
|
4215
|
+
return "unavailable";
|
|
3456
4216
|
}
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
const match = /([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=\s*$/.exec(source.slice(0, index));
|
|
3469
|
-
return match ? match[1] : null;
|
|
4217
|
+
const host = id === null ? null : hostTarget(id);
|
|
4218
|
+
if (analysis === null || host === null ? analysis === host : "file" in host && physical((0, node_path.join)(input.rootDir, analysis)) === physical(host.file)) return null;
|
|
4219
|
+
const shown = host === null ? "no file" : "virtual" in host ? host.virtual : (0, node_path.relative)(input.rootDir, host.file).split(node_path.sep).join(node_path.posix.sep);
|
|
4220
|
+
return {
|
|
4221
|
+
file: importer,
|
|
4222
|
+
component: `alias '${specifier}'`,
|
|
4223
|
+
kind: "warn",
|
|
4224
|
+
message: `'${specifier}' in ${importer} resolves to ${analysis ?? "no file"} through the path aliases analysis reads, but the host bundler resolves it to ${shown}, so the analysis may read another module than the one the bundle renders — make the bundler's resolution and the aliases (tsconfig paths) agree`,
|
|
4225
|
+
code: ALIAS_MISMATCH,
|
|
4226
|
+
severity: severityFor(ALIAS_MISMATCH)
|
|
4227
|
+
};
|
|
3470
4228
|
};
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
4229
|
+
await Promise.all(changed.map(async ({ path, hash }) => {
|
|
4230
|
+
const results = await Promise.all((files[path] ?? []).flatMap((specifier) => {
|
|
4231
|
+
const base = bases?.[path]?.[specifier];
|
|
4232
|
+
if (base !== void 0) return [compare(path, specifier, base)];
|
|
4233
|
+
return packages !== void 0 && isPackageSpecifier(specifier) && packages.roots[bareSpecifierPackageName(specifier)] !== void 0 ? [comparePackage(packages, path, specifier)] : [];
|
|
4234
|
+
}));
|
|
4235
|
+
cache.byFile.set(path, {
|
|
4236
|
+
hash,
|
|
4237
|
+
findings: results.filter((result) => result !== null && result !== "unavailable"),
|
|
4238
|
+
unavailable: results.filter((result) => result === "unavailable").length
|
|
4239
|
+
});
|
|
4240
|
+
}));
|
|
4241
|
+
const kept = input.fileEntries.flatMap((entry) => cache.byFile.get(entry.path) ?? []);
|
|
4242
|
+
return {
|
|
4243
|
+
findings: kept.flatMap((file) => file.findings),
|
|
4244
|
+
unavailable: kept.reduce((total, file) => total + file.unavailable, 0)
|
|
4245
|
+
};
|
|
4246
|
+
}
|
|
4247
|
+
//#endregion
|
|
4248
|
+
//#region pipeline/host-package-resolver.ts
|
|
4249
|
+
/**
|
|
4250
|
+
* Package resolution for discovery: one resolver, whose answers are the
|
|
4251
|
+
* host's where it resolves imports itself (spec §2.2 A4), and the system
|
|
4252
|
+
* loader's otherwise, and for a declared workspace the host cannot resolve.
|
|
4253
|
+
*/
|
|
4254
|
+
/**
|
|
4255
|
+
* A declared workspace that nothing links into `node_modules` is no package
|
|
4256
|
+
* to the host, though the system loader resolves it: where the host finds
|
|
4257
|
+
* nothing, discovery asks the loader.
|
|
4258
|
+
*/
|
|
4259
|
+
function discoveryResolver(hostResolve, engine, context) {
|
|
4260
|
+
const load = (specifier, fromDir) => {
|
|
4261
|
+
const native = engine.resolveSpecifier;
|
|
4262
|
+
if (native === void 0) throw new Error("the native engine does not expose resolveSpecifier, which package resolution needs — rebuild @animus-ui/extract");
|
|
4263
|
+
return native(specifier, fromDir, [...context.conditions], context.workspaces, extensionPolicyJson(context.extensions));
|
|
4264
|
+
};
|
|
4265
|
+
const loaderResolve = (specifier, fromDir) => load(specifier, fromDir).path ?? null;
|
|
4266
|
+
if (hostResolve === null) {
|
|
4267
|
+
const unresolved = /* @__PURE__ */ new Map();
|
|
4268
|
+
return {
|
|
4269
|
+
hostFirst: false,
|
|
4270
|
+
async resolveSpecifier(specifier) {
|
|
4271
|
+
const entry = load(specifier, context.rootDir);
|
|
4272
|
+
if (entry.path) return entry.path;
|
|
4273
|
+
unresolved.set(specifier, entry.unresolved ?? "it names no file");
|
|
4274
|
+
return null;
|
|
4275
|
+
},
|
|
4276
|
+
unresolvedReason: (specifier) => unresolved.get(specifier),
|
|
4277
|
+
requireSourceEntry: () => false,
|
|
4278
|
+
loaderResolve
|
|
4279
|
+
};
|
|
3502
4280
|
}
|
|
3503
|
-
|
|
3504
|
-
const
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
if (namedImports) for (const binding of namedImports.split(",")) {
|
|
3514
|
-
const parts = binding.trim().split(/\s+as\s+/);
|
|
3515
|
-
const localName = (parts[1] || parts[0]).trim();
|
|
3516
|
-
if (localName) importMap.set(localName, specifier);
|
|
4281
|
+
const loaderOnly = /* @__PURE__ */ new Set();
|
|
4282
|
+
const rootImporter = (0, path.join)(context.rootDir, "__animus_discovery__.js");
|
|
4283
|
+
return {
|
|
4284
|
+
hostFirst: true,
|
|
4285
|
+
async resolveSpecifier(specifier) {
|
|
4286
|
+
let hosted;
|
|
4287
|
+
try {
|
|
4288
|
+
hosted = await hostResolve(specifier, rootImporter);
|
|
4289
|
+
} catch {
|
|
4290
|
+
hosted = null;
|
|
3517
4291
|
}
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
while (!importMap.has(current) && !seen.has(current)) {
|
|
3527
|
-
seen.add(current);
|
|
3528
|
-
const target = aliasOf.get(current);
|
|
3529
|
-
if (!target) break;
|
|
3530
|
-
current = target;
|
|
3531
|
-
}
|
|
3532
|
-
return current;
|
|
4292
|
+
if (hosted !== null || !Object.hasOwn(context.workspaces, bareSpecifierPackageName(specifier))) return hosted;
|
|
4293
|
+
const loaded = loaderResolve(specifier, context.rootDir);
|
|
4294
|
+
if (loaded) loaderOnly.add(specifier);
|
|
4295
|
+
return loaded;
|
|
4296
|
+
},
|
|
4297
|
+
unresolvedReason: () => void 0,
|
|
4298
|
+
requireSourceEntry: (specifier) => loaderOnly.has(specifier),
|
|
4299
|
+
loaderResolve
|
|
3533
4300
|
};
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
4301
|
+
}
|
|
4302
|
+
//#endregion
|
|
4303
|
+
//#region pipeline/output-targets.ts
|
|
4304
|
+
/**
|
|
4305
|
+
* Where a bundler writes, as one model: the directories it fills and the
|
|
4306
|
+
* files it writes by exact name. Discovery excludes both, and the Rollup
|
|
4307
|
+
* family's render check reads both, so the two never classify output
|
|
4308
|
+
* differently.
|
|
4309
|
+
*/
|
|
4310
|
+
function noOutputTargets() {
|
|
4311
|
+
return {
|
|
4312
|
+
dirs: [],
|
|
4313
|
+
files: []
|
|
4314
|
+
};
|
|
4315
|
+
}
|
|
4316
|
+
/** Each output's named directory or file; one naming neither writes to
|
|
4317
|
+
* `fallbackDir` when there is one. */
|
|
4318
|
+
function targetsOf(base, outputs, fallbackDir) {
|
|
4319
|
+
const targets = noOutputTargets();
|
|
4320
|
+
for (const output of outputs) if (output.dir !== void 0) targets.dirs.push((0, path.resolve)(base, output.dir));
|
|
4321
|
+
else if (output.file !== void 0) targets.files.push((0, path.resolve)(base, output.file));
|
|
4322
|
+
else if (fallbackDir !== void 0) targets.dirs.push((0, path.resolve)(base, fallbackDir));
|
|
4323
|
+
return targets;
|
|
4324
|
+
}
|
|
4325
|
+
/** The targets of Rollup's or Rolldown's output options at render. */
|
|
4326
|
+
function rollupOutputTargets(output) {
|
|
4327
|
+
return targetsOf(process.cwd(), [output]);
|
|
4328
|
+
}
|
|
4329
|
+
/** Every Vite environment's outputs, as Vite's own `getResolvedOutDirs`
|
|
4330
|
+
* reads them: each output's `dir`, else the environment's `outDir`. */
|
|
4331
|
+
function viteOutputTargets(config) {
|
|
4332
|
+
return mergeOutputTargets([config.build, ...Object.values(config.environments ?? {}).flatMap((environment) => environment.build === void 0 ? [] : [environment.build])].map((build) => {
|
|
4333
|
+
const output = build.rolldownOptions?.output ?? build.rollupOptions?.output;
|
|
4334
|
+
const outputs = output === void 0 ? [{}] : Array.isArray(output) ? output : [output];
|
|
4335
|
+
return targetsOf(config.root, outputs, build.outDir);
|
|
4336
|
+
}));
|
|
4337
|
+
}
|
|
4338
|
+
/** esbuild's `outdir`, or its exact `outfile`. */
|
|
4339
|
+
function esbuildOutputTargets(options) {
|
|
4340
|
+
return targetsOf(options.absWorkingDir ?? process.cwd(), [{
|
|
4341
|
+
dir: options.outdir,
|
|
4342
|
+
file: options.outfile
|
|
4343
|
+
}]);
|
|
4344
|
+
}
|
|
4345
|
+
/** webpack's `output.path`, up to its first segment holding a template
|
|
4346
|
+
* placeholder (`out/[fullhash]` writes under `out`). */
|
|
4347
|
+
function webpackOutputTargets(outputPath) {
|
|
4348
|
+
if (outputPath === void 0) return noOutputTargets();
|
|
4349
|
+
const segments = outputPath.split(path.sep);
|
|
4350
|
+
const placeholder = segments.findIndex((segment) => segment.includes("["));
|
|
4351
|
+
const fixed = placeholder === -1 ? outputPath : segments.slice(0, placeholder).join(path.sep);
|
|
4352
|
+
return {
|
|
4353
|
+
dirs: fixed === "" ? [] : [fixed],
|
|
4354
|
+
files: []
|
|
4355
|
+
};
|
|
4356
|
+
}
|
|
4357
|
+
function mergeOutputTargets(all) {
|
|
4358
|
+
return {
|
|
4359
|
+
dirs: [...new Set(all.flatMap((targets) => targets.dirs))],
|
|
4360
|
+
files: [...new Set(all.flatMap((targets) => targets.files))]
|
|
4361
|
+
};
|
|
4362
|
+
}
|
|
4363
|
+
/** The Session's structural exclusions: every target inside the root. A
|
|
4364
|
+
* directory that is the root excludes nothing; its files still can. */
|
|
4365
|
+
function outputExclusions(root, targets) {
|
|
4366
|
+
return [...targets.dirs, ...targets.files].flatMap((target) => {
|
|
4367
|
+
const exclusion = outputExclusion(root, target);
|
|
4368
|
+
return exclusion === null ? [] : [exclusion];
|
|
4369
|
+
});
|
|
4370
|
+
}
|
|
4371
|
+
/** The analysed files a build's targets hold, as the render check reports
|
|
4372
|
+
* them: a file target the analysis read is the build's own earlier
|
|
4373
|
+
* output; a file inside a directory target is earlier output or a source
|
|
4374
|
+
* the bundler writes beside, which the check cannot tell apart. */
|
|
4375
|
+
function analysedOutputs(root, targets, analyzed) {
|
|
4376
|
+
const earlier = analyzed.filter((file) => targets.files.includes(file));
|
|
4377
|
+
const inside = targets.dirs.flatMap((dir) => {
|
|
4378
|
+
const exclusion = outputExclusion(root, dir);
|
|
4379
|
+
const held = analyzed.filter((file) => !earlier.includes(file) && isPathWithinRoot(dir, file));
|
|
4380
|
+
return exclusion === null || held.length === 0 ? [] : [{
|
|
4381
|
+
exclusion,
|
|
4382
|
+
held
|
|
4383
|
+
}];
|
|
4384
|
+
});
|
|
4385
|
+
const rel = (file) => (0, path.relative)(root, file);
|
|
4386
|
+
const parts = [...earlier.length === 0 ? [] : [`it analysed its own earlier output: ${earlier.map(rel).join(", ")}. Add ${earlier.map((file) => `'${rel(file)}'`).join(", ")} to the plugin's \`exclude\` option`], ...inside.map(({ exclusion, held }) => `it analysed files inside its output directory '${exclusion}': ${held.map(rel).join(", ")}. If they are earlier output, add '${exclusion}' to the plugin's \`exclude\` option; if they are sources, write the output outside the source tree`)];
|
|
4387
|
+
return parts.length === 0 ? null : `[animus] this build ${parts.join("; and ")}.`;
|
|
3541
4388
|
}
|
|
3542
4389
|
//#endregion
|
|
3543
4390
|
//#region pipeline/source-corpus.ts
|
|
@@ -3558,6 +4405,7 @@ function createSourceCorpus(host, ingestor = createSourceIngestor(host)) {
|
|
|
3558
4405
|
ownership: {}
|
|
3559
4406
|
};
|
|
3560
4407
|
return {
|
|
4408
|
+
facts: (entries) => ingestor.facts(entries),
|
|
3561
4409
|
async prepare(input) {
|
|
3562
4410
|
const rawEntries = "fileCache" in input ? assembleRawEntries(input) : input;
|
|
3563
4411
|
const ingested = await ingestor.ingest(rawEntries);
|
|
@@ -4376,15 +5224,27 @@ function buildAnalysisInputs(opts) {
|
|
|
4376
5224
|
if (opts.system.declarationScalesJson) inputs.declarationScalesJson = opts.system.declarationScalesJson;
|
|
4377
5225
|
if (opts.system.generatedNamesJson) inputs.generatedNamesJson = opts.system.generatedNamesJson;
|
|
4378
5226
|
if (opts.system.propertyRecordsJson) inputs.propertyRecordsJson = opts.system.propertyRecordsJson;
|
|
4379
|
-
const context = opts.analysisContext;
|
|
4380
|
-
if (context
|
|
5227
|
+
const context = analysisContextJson(opts.analysisContext);
|
|
5228
|
+
if (context !== void 0) inputs.analysisContextJson = context;
|
|
5229
|
+
return inputs;
|
|
5230
|
+
}
|
|
5231
|
+
/** The engine's wire for what the host knows; present only when the host
|
|
5232
|
+
* knows something, so a host that knows nothing persists unchanged inputs. */
|
|
5233
|
+
function analysisContextJson(context) {
|
|
5234
|
+
if (!(context?.skippedSources?.length || context?.unbundledComputedImports || context?.packageDirs?.length || context?.extensions || context?.openings?.length)) return;
|
|
5235
|
+
return JSON.stringify({
|
|
4381
5236
|
skippedSources: context.skippedSources ?? [],
|
|
4382
5237
|
unbundledComputedImports: context.unbundledComputedImports ?? false,
|
|
4383
5238
|
packageDirs: context.packageDirs ?? [],
|
|
4384
5239
|
linkedDirs: context.linkedDirs ?? [],
|
|
4385
|
-
outputDirs: context.outputDirs ?? []
|
|
5240
|
+
outputDirs: context.outputDirs ?? [],
|
|
5241
|
+
...context.extensions && { extensions: {
|
|
5242
|
+
appended: context.extensions.appended,
|
|
5243
|
+
nodeNext: context.extensions.nodeNext,
|
|
5244
|
+
alias: context.extensions.alias
|
|
5245
|
+
} },
|
|
5246
|
+
...context.openings?.length && { openings: context.openings }
|
|
4386
5247
|
});
|
|
4387
|
-
return inputs;
|
|
4388
5248
|
}
|
|
4389
5249
|
function hasSourceThemeManifests(system) {
|
|
4390
5250
|
const json = system.sourceThemeManifestsJson ?? "";
|
|
@@ -4418,7 +5278,11 @@ function runProjectAnalysis(engineApi, opts) {
|
|
|
4418
5278
|
const inputs = buildAnalysisInputs(opts);
|
|
4419
5279
|
const serializeMs = Math.round(performance.now() - t);
|
|
4420
5280
|
t = performance.now();
|
|
4421
|
-
const manifestJson = analyzeProject(...buildAnalyzeProjectArgs(inputs))
|
|
5281
|
+
const manifestJson = analyzeProject(...buildAnalyzeProjectArgs(inputs, opts.rootDir === void 0 ? void 0 : gatherProbeEvidence(opts.rootDir, new Set(opts.fileEntries.map((entry) => entry.path)), opts.analysisContext?.extensions, {
|
|
5282
|
+
isAsset: opts.assets?.isAsset,
|
|
5283
|
+
adapted: opts.adapted,
|
|
5284
|
+
expander: opts.loadExpander
|
|
5285
|
+
})));
|
|
4422
5286
|
const extractMs = Math.round(performance.now() - t);
|
|
4423
5287
|
t = performance.now();
|
|
4424
5288
|
const manifest = JSON.parse(manifestJson);
|
|
@@ -4654,12 +5518,20 @@ function renameDeclarationRecords(declarationScalesJson, rename) {
|
|
|
4654
5518
|
}
|
|
4655
5519
|
//#endregion
|
|
4656
5520
|
//#region pipeline/system-config.ts
|
|
5521
|
+
function systemLoadReads(error) {
|
|
5522
|
+
const thrown = error;
|
|
5523
|
+
const carrier = thrown?.dependencies ? thrown : thrown?.cause;
|
|
5524
|
+
return {
|
|
5525
|
+
dependencies: carrier?.dependencies ?? [],
|
|
5526
|
+
missing: carrier?.missing ?? []
|
|
5527
|
+
};
|
|
5528
|
+
}
|
|
4657
5529
|
/** The loader's evaluation of the system file. A failure on a file that
|
|
4658
5530
|
* calls `createSystem` with no binding leads with discovery's warning line
|
|
4659
5531
|
* for it, then keeps the loader's own error. */
|
|
4660
|
-
function evaluateSystemModule(engine, systemPath, rootDir, conditions) {
|
|
5532
|
+
function evaluateSystemModule(engine, systemPath, rootDir, conditions, workspaces, extensions) {
|
|
4661
5533
|
try {
|
|
4662
|
-
return engine.loadSystemModule(systemPath, rootDir, void 0, conditions);
|
|
5534
|
+
return engine.loadSystemModule(systemPath, rootDir, void 0, conditions, workspaces, extensions && extensionPolicyJson(extensions));
|
|
4663
5535
|
} catch (error) {
|
|
4664
5536
|
let source;
|
|
4665
5537
|
try {
|
|
@@ -4678,7 +5550,7 @@ function evaluateSystemModule(engine, systemPath, rootDir, conditions) {
|
|
|
4678
5550
|
* variable name. Error handling stays at the call site.
|
|
4679
5551
|
*/
|
|
4680
5552
|
function loadSystemConfig(engineApi, opts) {
|
|
4681
|
-
const config = evaluateSystemModule(engineApi(), opts.systemPath, opts.rootDir, opts.conditions);
|
|
5553
|
+
const config = evaluateSystemModule(engineApi(), opts.systemPath, opts.rootDir, opts.conditions, opts.workspaces, opts.extensions);
|
|
4682
5554
|
let scalesJson = config.scalesJson;
|
|
4683
5555
|
let variableMapJson = config.variableMapJson;
|
|
4684
5556
|
const registrations = splitInvalidPropertyRegistrations(config.variableCss);
|
|
@@ -4728,6 +5600,7 @@ function loadSystemConfig(engineApi, opts) {
|
|
|
4728
5600
|
keyframesJson: config.keyframesBlocks || null,
|
|
4729
5601
|
vocabularyWitnessesJson: config.vocabularyWitnesses || null,
|
|
4730
5602
|
dependencies: config.dependencies ?? [],
|
|
5603
|
+
missing: config.missing ?? [],
|
|
4731
5604
|
sourceThemeManifestsJson: config.sourceThemeManifests || null
|
|
4732
5605
|
};
|
|
4733
5606
|
if (declarationScalesJson) system.declarationScalesJson = declarationScalesJson;
|
|
@@ -4847,13 +5720,6 @@ const CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
4847
5720
|
".mjs",
|
|
4848
5721
|
".cjs"
|
|
4849
5722
|
]);
|
|
4850
|
-
const isFile = (path) => {
|
|
4851
|
-
try {
|
|
4852
|
-
return (0, node_fs.statSync)(path).isFile();
|
|
4853
|
-
} catch {
|
|
4854
|
-
return false;
|
|
4855
|
-
}
|
|
4856
|
-
};
|
|
4857
5723
|
const posixPath = (path) => path.split(node_path.sep).join("/");
|
|
4858
5724
|
/**
|
|
4859
5725
|
* The package-relative files `npm pack` publishes, read with npm's own rules
|
|
@@ -4982,8 +5848,14 @@ function kitPublicationFailures(pkgRoot, engine, artifactDir) {
|
|
|
4982
5848
|
const matched = files.filter((file) => pattern.test(file));
|
|
4983
5849
|
if (matched.length === 0) failures.push(`package.json: the "animus" target of exports["${subpath}"], ${target}, matches no file in the package`);
|
|
4984
5850
|
for (const file of matched) admit(subpath, file);
|
|
4985
|
-
} else
|
|
4986
|
-
|
|
5851
|
+
} else {
|
|
5852
|
+
const seen = seeOnDisk((0, node_path.resolve)(pkgRoot, target), pkgRoot);
|
|
5853
|
+
if (seen.kind === "file") admit(subpath, relPath);
|
|
5854
|
+
else failures.push(seen.kind === "case-only" ? `package.json: ${caseMismatchReason(`the "animus" target of exports["${subpath}"]`, {
|
|
5855
|
+
candidate: target,
|
|
5856
|
+
actual: rel(seen.actual)
|
|
5857
|
+
}, "spell the target as the file is spelled")}` : `package.json: the "animus" target of exports["${subpath}"], ${target}, does not exist in the package`);
|
|
5858
|
+
}
|
|
4987
5859
|
}
|
|
4988
5860
|
const visited = /* @__PURE__ */ new Set();
|
|
4989
5861
|
while (queue.length > 0) {
|
|
@@ -4996,8 +5868,13 @@ function kitPublicationFailures(pkgRoot, engine, artifactDir) {
|
|
|
4996
5868
|
}])), "moduleSpecifiers").files[file] ?? [];
|
|
4997
5869
|
for (const specifier of specifiers) {
|
|
4998
5870
|
if (specifier.startsWith(".")) {
|
|
4999
|
-
const
|
|
5000
|
-
|
|
5871
|
+
const probed = probeOnDisk(relativeSourceCandidates(file, specifier), (0, node_path.dirname)(file));
|
|
5872
|
+
const target = probed.kind === "found" ? probed.path : void 0;
|
|
5873
|
+
if (probed.kind === "case-mismatch") failures.push(`${rel(file)}: ${caseMismatchReason(`import '${specifier}'`, {
|
|
5874
|
+
candidate: rel(probed.candidate),
|
|
5875
|
+
actual: rel(probed.actual)
|
|
5876
|
+
}, "spell the import as the file is spelled")}`);
|
|
5877
|
+
else if (target === void 0) failures.push(`${rel(file)}: import '${specifier}' resolves to no file in the package`);
|
|
5001
5878
|
else if (outside(rel(target))) failures.push(`${rel(file)}: import '${specifier}' resolves to ${rel(target)}, outside the package`);
|
|
5002
5879
|
else if (!published(rel(target))) failures.push(`${rel(file)}: import '${specifier}' resolves to ${rel(target)}, which is not in the published files`);
|
|
5003
5880
|
else if (CODE_EXTENSIONS.has((0, node_path.extname)(target))) queue.push(target);
|
|
@@ -5096,18 +5973,665 @@ function realpathThroughNearestExistingAncestor(path) {
|
|
|
5096
5973
|
}
|
|
5097
5974
|
}
|
|
5098
5975
|
//#endregion
|
|
5976
|
+
//#region pipeline/built-in-asset-types.ts
|
|
5977
|
+
/** The Vite version the built-in types come from. */
|
|
5978
|
+
const BUILT_IN_ASSET_SOURCE = "vite@8.2.2";
|
|
5979
|
+
/** Asset extensions, as regular-expression alternatives, a session with no
|
|
5980
|
+
* readable host classification reads as assets (spec §2.2 A8). */
|
|
5981
|
+
const BUILT_IN_ASSET_TYPES = [
|
|
5982
|
+
"apng",
|
|
5983
|
+
"bmp",
|
|
5984
|
+
"png",
|
|
5985
|
+
"jpe?g",
|
|
5986
|
+
"jfif",
|
|
5987
|
+
"pjpeg",
|
|
5988
|
+
"pjp",
|
|
5989
|
+
"gif",
|
|
5990
|
+
"svg",
|
|
5991
|
+
"ico",
|
|
5992
|
+
"webp",
|
|
5993
|
+
"avif",
|
|
5994
|
+
"cur",
|
|
5995
|
+
"jxl",
|
|
5996
|
+
"mp4",
|
|
5997
|
+
"webm",
|
|
5998
|
+
"ogg",
|
|
5999
|
+
"mp3",
|
|
6000
|
+
"wav",
|
|
6001
|
+
"flac",
|
|
6002
|
+
"aac",
|
|
6003
|
+
"opus",
|
|
6004
|
+
"mov",
|
|
6005
|
+
"m4a",
|
|
6006
|
+
"vtt",
|
|
6007
|
+
"woff2?",
|
|
6008
|
+
"eot",
|
|
6009
|
+
"ttf",
|
|
6010
|
+
"otf",
|
|
6011
|
+
"webmanifest",
|
|
6012
|
+
"pdf",
|
|
6013
|
+
"txt"
|
|
6014
|
+
];
|
|
6015
|
+
/** Stylesheet extensions, as regular-expression alternatives, a session
|
|
6016
|
+
* with no readable host classification reads as stylesheets. */
|
|
6017
|
+
const BUILT_IN_STYLESHEET_TYPES = [
|
|
6018
|
+
"css",
|
|
6019
|
+
"less",
|
|
6020
|
+
"sass",
|
|
6021
|
+
"scss",
|
|
6022
|
+
"styl",
|
|
6023
|
+
"stylus",
|
|
6024
|
+
"pcss",
|
|
6025
|
+
"postcss",
|
|
6026
|
+
"sss"
|
|
6027
|
+
];
|
|
6028
|
+
//#endregion
|
|
6029
|
+
//#region pipeline/host-assets.ts
|
|
6030
|
+
const BUILT_IN_ASSET_RE = new RegExp(`\\.(?:${BUILT_IN_ASSET_TYPES.join("|")})$`, "i");
|
|
6031
|
+
/** Vite's stylesheet test (`isCSSRequest`), on the final extension only: a
|
|
6032
|
+
* `x.css.ts` is a module. Exact case, as Vite reads it. */
|
|
6033
|
+
const STYLESHEET_RE = new RegExp(`\\.(?:${BUILT_IN_STYLESHEET_TYPES.join("|")})$`);
|
|
6034
|
+
/** JSON, as Vite's json plugin, webpack's `json` type, esbuild's `json`
|
|
6035
|
+
* loader and Turbopack read it: the final extension, exact case. */
|
|
6036
|
+
const JSON_RE = /\.json$/;
|
|
6037
|
+
/** The queries Vite answers with a string whatever the file holds: `?url`
|
|
6038
|
+
* and `?raw`. Any other query keeps the file's own reading. */
|
|
6039
|
+
const VITE_OPAQUE_QUERY_RE = /[?&](?:url|raw)\b/;
|
|
6040
|
+
/** The built-in classification, where no host's can be read or is not
|
|
6041
|
+
* modelled (webpack's and Rspack's rules, as a conditional rule may never
|
|
6042
|
+
* apply): Vite's known asset types, `svg` included, its CSS languages
|
|
6043
|
+
* (`BUILT_IN_ASSET_SOURCE`) and JSON, read with Vite's queries. */
|
|
6044
|
+
function builtInAssetClassification(reason, detail) {
|
|
6045
|
+
return {
|
|
6046
|
+
isAsset: (file, query) => VITE_OPAQUE_QUERY_RE.test(query) || BUILT_IN_ASSET_RE.test(file) || STYLESHEET_RE.test(file) || JSON_RE.test(file),
|
|
6047
|
+
resolverVersion: `built-in (${reason}${detail ? `: ${detail}` : ""}; ${BUILT_IN_ASSET_SOURCE})`
|
|
6048
|
+
};
|
|
6049
|
+
}
|
|
6050
|
+
/** Vite's own classification: `?url` and `?raw`, its known asset types and
|
|
6051
|
+
* the user's `assetsInclude`, as `ResolvedConfig.assetsInclude` answers,
|
|
6052
|
+
* its CSS languages (`isCSSRequest`), and its json plugin's JSON. */
|
|
6053
|
+
function viteAssetClassification(assetsInclude, version) {
|
|
6054
|
+
return {
|
|
6055
|
+
isAsset: (file, query) => VITE_OPAQUE_QUERY_RE.test(query) || assetsInclude(file) || STYLESHEET_RE.test(file) || JSON_RE.test(file),
|
|
6056
|
+
resolverVersion: `${version ? `vite@${version}` : "vite"} captured`
|
|
6057
|
+
};
|
|
6058
|
+
}
|
|
6059
|
+
/** esbuild's built-in loaders, which a configured `loader` map extends. */
|
|
6060
|
+
const ESBUILD_DEFAULT_LOADERS = {
|
|
6061
|
+
"": "js",
|
|
6062
|
+
".js": "js",
|
|
6063
|
+
".mjs": "js",
|
|
6064
|
+
".cjs": "js",
|
|
6065
|
+
".jsx": "jsx",
|
|
6066
|
+
".ts": "ts",
|
|
6067
|
+
".cts": "ts",
|
|
6068
|
+
".mts": "ts",
|
|
6069
|
+
".tsx": "tsx",
|
|
6070
|
+
".css": "css",
|
|
6071
|
+
".module.css": "local-css",
|
|
6072
|
+
".json": "json",
|
|
6073
|
+
".txt": "text"
|
|
6074
|
+
};
|
|
6075
|
+
/** esbuild loaders whose module is an opaque value: a URL, the file's bytes
|
|
6076
|
+
* or text, a stylesheet, or JSON. `copy` keeps the file as code. */
|
|
6077
|
+
const ESBUILD_OPAQUE_LOADERS = /* @__PURE__ */ new Set([
|
|
6078
|
+
"file",
|
|
6079
|
+
"dataurl",
|
|
6080
|
+
"base64",
|
|
6081
|
+
"binary",
|
|
6082
|
+
"text",
|
|
6083
|
+
"css",
|
|
6084
|
+
"local-css",
|
|
6085
|
+
"global-css",
|
|
6086
|
+
"json"
|
|
6087
|
+
]);
|
|
6088
|
+
/** esbuild's classification, from its `loader` map: the loader esbuild
|
|
6089
|
+
* picks for a file is the longest extension of its name the map holds,
|
|
6090
|
+
* exact case. */
|
|
6091
|
+
function esbuildAssetClassification(loader) {
|
|
6092
|
+
const loaders = new Map(Object.entries({
|
|
6093
|
+
...ESBUILD_DEFAULT_LOADERS,
|
|
6094
|
+
...loader
|
|
6095
|
+
}));
|
|
6096
|
+
return {
|
|
6097
|
+
isAsset: (file) => {
|
|
6098
|
+
let name = file.slice(Math.max(file.lastIndexOf("/"), file.lastIndexOf("\\")) + 1);
|
|
6099
|
+
let picked = name.includes(".") ? void 0 : loaders.get("");
|
|
6100
|
+
for (let dot = name.indexOf("."); dot !== -1; dot = name.indexOf(".")) {
|
|
6101
|
+
picked = loaders.get(name.slice(dot));
|
|
6102
|
+
if (picked !== void 0) break;
|
|
6103
|
+
name = name.slice(dot + 1);
|
|
6104
|
+
}
|
|
6105
|
+
return picked !== void 0 && ESBUILD_OPAQUE_LOADERS.has(picked);
|
|
6106
|
+
},
|
|
6107
|
+
resolverVersion: "esbuild captured"
|
|
6108
|
+
};
|
|
6109
|
+
}
|
|
6110
|
+
/** Turbopack's classification under Next: Next's static-image table
|
|
6111
|
+
* (`nextImageLoaderRegex`), unless `images.disableStaticImages`, and its
|
|
6112
|
+
* stylesheets (`regexLikeCss`), as the installed `next` declares them,
|
|
6113
|
+
* and JSON. Built-in where Next cannot be read. */
|
|
6114
|
+
function nextImageAssetClassification(rootDir, disableStaticImages) {
|
|
6115
|
+
try {
|
|
6116
|
+
const require$1 = (0, node_module.createRequire)(`${rootDir}/package.json`);
|
|
6117
|
+
const { version } = require$1("next/package.json");
|
|
6118
|
+
const { nextImageLoaderRegex } = require$1("next/dist/build/webpack-config");
|
|
6119
|
+
const { regexLikeCss } = require$1("next/dist/build/webpack/config/blocks/css");
|
|
6120
|
+
if (!(nextImageLoaderRegex instanceof RegExp) || !(regexLikeCss instanceof RegExp)) return builtInAssetClassification("hostOptionUnreadable", `next@${version} image and stylesheet types`);
|
|
6121
|
+
return {
|
|
6122
|
+
isAsset: (file) => JSON_RE.test(file) || regexLikeCss.test(file) || !disableStaticImages && nextImageLoaderRegex.test(file),
|
|
6123
|
+
resolverVersion: `from next@${version}`
|
|
6124
|
+
};
|
|
6125
|
+
} catch {
|
|
6126
|
+
return builtInAssetClassification("hostOptionUnreadable", "next");
|
|
6127
|
+
}
|
|
6128
|
+
}
|
|
6129
|
+
//#endregion
|
|
6130
|
+
//#region pipeline/vite-expansions.ts
|
|
6131
|
+
/** The glob syntax read here: literal characters, `*` and a whole-segment
|
|
6132
|
+
* `**`, and a `{a,b}` group of literal alternatives. Anything else (`?`,
|
|
6133
|
+
* classes, extglobs, nested groups) is not reproduced. */
|
|
6134
|
+
const UNREAD_SYNTAX = /[?[\]()!+@\\]/;
|
|
6135
|
+
function segmentOf(text) {
|
|
6136
|
+
if (text === "**") return { kind: "globstar" };
|
|
6137
|
+
if (UNREAD_SYNTAX.test(text) || text.includes("**")) return void 0;
|
|
6138
|
+
let source = "";
|
|
6139
|
+
for (const part of text.split(/(\{[^{}]*\}|\*)/)) if (part === "*") source += "[^/]*";
|
|
6140
|
+
else if (part.startsWith("{") && part.endsWith("}")) {
|
|
6141
|
+
const options = part.slice(1, -1).split(",");
|
|
6142
|
+
if (options.some((option) => /[{}*]/.test(option))) return void 0;
|
|
6143
|
+
source += `(?:${options.map(escape).join("|")})`;
|
|
6144
|
+
} else if (/[{}]/.test(part)) return void 0;
|
|
6145
|
+
else source += escape(part);
|
|
6146
|
+
return {
|
|
6147
|
+
kind: "match",
|
|
6148
|
+
test: new RegExp(`^${source}$`),
|
|
6149
|
+
dotted: text.startsWith(".")
|
|
6150
|
+
};
|
|
6151
|
+
}
|
|
6152
|
+
function escape(text) {
|
|
6153
|
+
return text.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
|
|
6154
|
+
}
|
|
6155
|
+
/**
|
|
6156
|
+
* A pattern as Vite resolves it (`toAbsoluteGlob`): relative to the
|
|
6157
|
+
* importer's directory, or with `/` to the Vite root. A pattern in another
|
|
6158
|
+
* form (an alias, a bare name) or with syntax not read here is undefined.
|
|
6159
|
+
*/
|
|
6160
|
+
function resolveGlob(pattern, importerDir, viteRoot) {
|
|
6161
|
+
const negated = pattern.startsWith("!");
|
|
6162
|
+
const body = negated ? pattern.slice(1) : pattern;
|
|
6163
|
+
const start = body.startsWith("/") ? viteRoot : body.startsWith("./") || body.startsWith("../") ? importerDir : void 0;
|
|
6164
|
+
if (start === void 0) return void 0;
|
|
6165
|
+
const parts = body.split("/").filter((part) => part !== "" && part !== ".");
|
|
6166
|
+
let base = start;
|
|
6167
|
+
let index = 0;
|
|
6168
|
+
if (parts.some((part) => part !== ".." && UNREAD_SYNTAX.test(part))) return;
|
|
6169
|
+
while (index < parts.length - 1 && !/[*{}]/.test(parts[index])) {
|
|
6170
|
+
base = parts[index] === ".." ? (0, node_path.dirname)(base) : (0, node_path.resolve)(base, parts[index]);
|
|
6171
|
+
index += 1;
|
|
6172
|
+
}
|
|
6173
|
+
const segments = [];
|
|
6174
|
+
for (const part of parts.slice(index)) {
|
|
6175
|
+
if (part === "..") return void 0;
|
|
6176
|
+
const segment = segmentOf(part);
|
|
6177
|
+
if (segment === void 0) return void 0;
|
|
6178
|
+
segments.push(segment);
|
|
6179
|
+
}
|
|
6180
|
+
return {
|
|
6181
|
+
negated,
|
|
6182
|
+
base,
|
|
6183
|
+
segments
|
|
6184
|
+
};
|
|
6185
|
+
}
|
|
6186
|
+
/** Whether `names`, a path below a glob's base, matches its segments. A
|
|
6187
|
+
* wildcard never matches a dot-led name unless `dot`. */
|
|
6188
|
+
function matches(segments, names, dot) {
|
|
6189
|
+
const [segment, ...rest] = segments;
|
|
6190
|
+
if (segment === void 0) return names.length === 0;
|
|
6191
|
+
if (segment.kind === "globstar") {
|
|
6192
|
+
if (matches(rest, names, dot)) return true;
|
|
6193
|
+
const [name, ...more] = names;
|
|
6194
|
+
if (name === void 0 || !dot && name.startsWith(".")) return false;
|
|
6195
|
+
return matches(segments, more, dot);
|
|
6196
|
+
}
|
|
6197
|
+
const [name, ...more] = names;
|
|
6198
|
+
if (name === void 0) return false;
|
|
6199
|
+
if (!dot && name.startsWith(".") && !segment.dotted) return false;
|
|
6200
|
+
return segment.test.test(name) && matches(rest, more, dot);
|
|
6201
|
+
}
|
|
6202
|
+
/** Every file below `dir`, following symbolic links as Vite does, each
|
|
6203
|
+
* directory once by its real path. A read the walk cannot finish throws:
|
|
6204
|
+
* the expansion would not be every file. */
|
|
6205
|
+
function walk(dir, prefix = [], visited = /* @__PURE__ */ new Set()) {
|
|
6206
|
+
const real = (0, node_fs.realpathSync)(dir);
|
|
6207
|
+
if (visited.has(real)) return [];
|
|
6208
|
+
const inside = new Set(visited).add(real);
|
|
6209
|
+
const files = [];
|
|
6210
|
+
for (const name of (0, node_fs.readdirSync)(dir)) {
|
|
6211
|
+
const path = `${dir}${node_path.sep}${name}`;
|
|
6212
|
+
const names = [...prefix, name];
|
|
6213
|
+
const stat = (0, node_fs.statSync)(path);
|
|
6214
|
+
if (stat.isDirectory()) files.push(...walk(path, names, inside));
|
|
6215
|
+
else if (stat.isFile()) files.push({
|
|
6216
|
+
names,
|
|
6217
|
+
path,
|
|
6218
|
+
real: (0, node_fs.realpathSync)(path)
|
|
6219
|
+
});
|
|
6220
|
+
}
|
|
6221
|
+
return files;
|
|
6222
|
+
}
|
|
6223
|
+
/** The files a set of Vite globs selects: in any affirmed glob and no
|
|
6224
|
+
* negated one, `node_modules` and dot-led names left out unless
|
|
6225
|
+
* `exhaustive`, the importer itself never. */
|
|
6226
|
+
function expandGlobs(globs, importer, exhaustive) {
|
|
6227
|
+
const affirmed = globs.filter((glob) => !glob.negated);
|
|
6228
|
+
const negated = globs.filter((glob) => glob.negated);
|
|
6229
|
+
const inside = (glob, file) => {
|
|
6230
|
+
const rel = (0, node_path.relative)(glob.base, file);
|
|
6231
|
+
if ((0, node_path.isAbsolute)(rel) || rel.split(node_path.sep)[0] === "..") return false;
|
|
6232
|
+
return matches(glob.segments, rel.split(node_path.sep), exhaustive);
|
|
6233
|
+
};
|
|
6234
|
+
const selected = /* @__PURE__ */ new Set();
|
|
6235
|
+
for (const glob of affirmed) for (const { names, path, real } of walk(glob.base)) {
|
|
6236
|
+
if (!exhaustive && names.includes("node_modules")) continue;
|
|
6237
|
+
if (path === importer || !inside(glob, path)) continue;
|
|
6238
|
+
if (negated.some((other) => inside(other, path))) continue;
|
|
6239
|
+
selected.add(real);
|
|
6240
|
+
}
|
|
6241
|
+
return [...selected].sort();
|
|
6242
|
+
}
|
|
6243
|
+
/** The queries a glob's `query` option is read as: Vite's opaque ones,
|
|
6244
|
+
* with or without the `?` it adds. */
|
|
6245
|
+
const GLOB_QUERIES = /* @__PURE__ */ new Map([
|
|
6246
|
+
[void 0, ""],
|
|
6247
|
+
["raw", "?raw"],
|
|
6248
|
+
["?raw", "?raw"],
|
|
6249
|
+
["url", "?url"],
|
|
6250
|
+
["?url", "?url"]
|
|
6251
|
+
]);
|
|
6252
|
+
/** The boolean an option is written as; absent, `false`. */
|
|
6253
|
+
const GLOB_FLAGS = /* @__PURE__ */ new Map([
|
|
6254
|
+
[void 0, false],
|
|
6255
|
+
[true, true],
|
|
6256
|
+
[false, false]
|
|
6257
|
+
]);
|
|
6258
|
+
/** A glob's options as Vite reads them (`parseGlobOptions`): the query each
|
|
6259
|
+
* file is imported with and whether the glob is exhaustive. `import`
|
|
6260
|
+
* selects an export, not files. Undefined for an option set not
|
|
6261
|
+
* reproduced here: another query, `base`, `caseSensitive`, or the
|
|
6262
|
+
* deprecated `as`, which a Vite 8 build does not apply as a query. */
|
|
6263
|
+
function globOptions(options) {
|
|
6264
|
+
if (options === null) return {
|
|
6265
|
+
query: "",
|
|
6266
|
+
exhaustive: false
|
|
6267
|
+
};
|
|
6268
|
+
for (const key of Object.keys(options)) if (![
|
|
6269
|
+
"eager",
|
|
6270
|
+
"import",
|
|
6271
|
+
"exhaustive",
|
|
6272
|
+
"query"
|
|
6273
|
+
].includes(key)) return;
|
|
6274
|
+
const query = GLOB_QUERIES.get(options.query);
|
|
6275
|
+
const exhaustive = GLOB_FLAGS.get(options.exhaustive);
|
|
6276
|
+
if (query === void 0 || exhaustive === void 0) return void 0;
|
|
6277
|
+
if (!GLOB_FLAGS.has(options.eager)) return void 0;
|
|
6278
|
+
return {
|
|
6279
|
+
query,
|
|
6280
|
+
exhaustive
|
|
6281
|
+
};
|
|
6282
|
+
}
|
|
6283
|
+
/**
|
|
6284
|
+
* The glob a variable `import()` of a template literal becomes under
|
|
6285
|
+
* Vite's dynamic-import-vars (`dynamicImportToGlob`): each substitution one
|
|
6286
|
+
* `*` within a segment. It must start `./` or `../` and name a file
|
|
6287
|
+
* extension in its last static text; Vite leaves any other one, and a
|
|
6288
|
+
* concatenation, a runtime import, which it does not expand.
|
|
6289
|
+
*/
|
|
6290
|
+
function importVarsGlob(quasis) {
|
|
6291
|
+
if (quasis.length < 2) return void 0;
|
|
6292
|
+
const head = quasis[0];
|
|
6293
|
+
if (!head.startsWith("./") && !head.startsWith("../")) return void 0;
|
|
6294
|
+
if (quasis.slice(1, -1).some((quasi) => quasi === "")) return void 0;
|
|
6295
|
+
if (quasis.some((quasi) => /[*?{}[\]]/.test(quasi))) return void 0;
|
|
6296
|
+
const last = quasis[quasis.length - 1];
|
|
6297
|
+
if (!/\.[a-z0-9]+$/i.test(last) || last.includes("?")) return void 0;
|
|
6298
|
+
return quasis.join("*");
|
|
6299
|
+
}
|
|
6300
|
+
/**
|
|
6301
|
+
* How a bundled Vite environment (Vite 8, rolldown's native glob and
|
|
6302
|
+
* dynamic-import-vars plugins) expands computed loads (spec §6.3):
|
|
6303
|
+
* `import.meta.glob` and a variable `import()`. `importVars` is false where
|
|
6304
|
+
* the project's `build.dynamicImportVarsOptions` differ from Vite's
|
|
6305
|
+
* default, which transforms every importer outside `node_modules`.
|
|
6306
|
+
* Anything this does not reproduce exactly lists no expansion.
|
|
6307
|
+
*/
|
|
6308
|
+
function viteLoadExpander(viteRoot, importVars) {
|
|
6309
|
+
return { expand(load, rootDir) {
|
|
6310
|
+
const importer = (0, node_path.resolve)(rootDir, load.importer);
|
|
6311
|
+
const importerDir = (0, node_path.dirname)(importer);
|
|
6312
|
+
let patterns;
|
|
6313
|
+
let query = "";
|
|
6314
|
+
let exhaustive = false;
|
|
6315
|
+
if (load.kind === "glob" && load.args && "patterns" in load.args) {
|
|
6316
|
+
const read = globOptions(load.args.options);
|
|
6317
|
+
if (read === void 0) return void 0;
|
|
6318
|
+
({query, exhaustive} = read);
|
|
6319
|
+
patterns = load.args.patterns;
|
|
6320
|
+
} else if (load.kind === "import" && load.args && "quasis" in load.args) {
|
|
6321
|
+
if (!importVars || importer.split(node_path.sep).includes("node_modules") || !load.args.template || load.args.options !== null || load.args.comments.some((comment) => comment.includes("@vite-ignore"))) return;
|
|
6322
|
+
const glob = importVarsGlob(load.args.quasis);
|
|
6323
|
+
if (glob === void 0) return void 0;
|
|
6324
|
+
patterns = [glob];
|
|
6325
|
+
} else return;
|
|
6326
|
+
const globs = [];
|
|
6327
|
+
for (const pattern of patterns) {
|
|
6328
|
+
const glob = resolveGlob(pattern, importerDir, viteRoot);
|
|
6329
|
+
if (glob === void 0) return void 0;
|
|
6330
|
+
globs.push(glob);
|
|
6331
|
+
}
|
|
6332
|
+
if (!globs.some((glob) => !glob.negated)) return void 0;
|
|
6333
|
+
let files;
|
|
6334
|
+
let realRoot;
|
|
6335
|
+
try {
|
|
6336
|
+
files = expandGlobs(globs, importer, exhaustive);
|
|
6337
|
+
realRoot = (0, node_fs.realpathSync)(rootDir);
|
|
6338
|
+
} catch {
|
|
6339
|
+
return;
|
|
6340
|
+
}
|
|
6341
|
+
return files.map((file) => ({
|
|
6342
|
+
path: (0, node_path.relative)(realRoot, file).split(node_path.sep).join(node_path.posix.sep),
|
|
6343
|
+
query
|
|
6344
|
+
}));
|
|
6345
|
+
} };
|
|
6346
|
+
}
|
|
6347
|
+
/** Whether `build.dynamicImportVarsOptions` are Vite's default, which
|
|
6348
|
+
* transforms every importer outside `node_modules`. */
|
|
6349
|
+
function defaultImportVars(options) {
|
|
6350
|
+
const exclude = options?.exclude;
|
|
6351
|
+
return options?.include === void 0 && Array.isArray(exclude) && exclude.length === 1 && exclude[0] instanceof RegExp && exclude[0].source === "node_modules" && exclude[0].flags === "";
|
|
6352
|
+
}
|
|
6353
|
+
/** The aliases Vite adds to every configuration (`clientAlias`), which
|
|
6354
|
+
* name only its own `@vite/` modules. */
|
|
6355
|
+
const VITE_CLIENT_ALIASES = /* @__PURE__ */ new Set(["^\\/?@vite\\/env", "^\\/?@vite\\/client"]);
|
|
6356
|
+
/** Whether an alias could rewrite a relative or root specifier, which the
|
|
6357
|
+
* expander reads without the resolver: a string from `.` or `/`, or a
|
|
6358
|
+
* RegExp other than Vite's own client aliases. */
|
|
6359
|
+
function aliasesRelative(aliases) {
|
|
6360
|
+
return (aliases ?? []).some(({ find }) => find instanceof RegExp ? !(find.flags === "" && VITE_CLIENT_ALIASES.has(find.source)) : find.startsWith(".") || find.startsWith("/"));
|
|
6361
|
+
}
|
|
6362
|
+
/**
|
|
6363
|
+
* The expander for a resolved Vite configuration: only where every
|
|
6364
|
+
* environment is bundled (Vite 8, rolldown's native plugins; an earlier
|
|
6365
|
+
* Vite marks none), and no alias could rewrite a relative or root
|
|
6366
|
+
* specifier. A variable `import()` is expanded only where every environment
|
|
6367
|
+
* keeps Vite's default dynamic-import-vars options.
|
|
6368
|
+
*/
|
|
6369
|
+
function viteHostExpander(config) {
|
|
6370
|
+
const environments = Object.values(config.environments ?? {});
|
|
6371
|
+
if (environments.length === 0 || !environments.every((environment) => environment.isBundled === true) || aliasesRelative(config.resolve?.alias)) return;
|
|
6372
|
+
return viteLoadExpander(config.root, environments.every((environment) => defaultImportVars(environment.build?.dynamicImportVarsOptions)));
|
|
6373
|
+
}
|
|
6374
|
+
//#endregion
|
|
6375
|
+
//#region pipeline/webpack-expansions.ts
|
|
6376
|
+
/** Webpack's `quoteMeta`. */
|
|
6377
|
+
function quoteMeta(text) {
|
|
6378
|
+
return text.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
|
|
6379
|
+
}
|
|
6380
|
+
/** A literal as a RegExp, where webpack tests it statelessly: a global or
|
|
6381
|
+
* sticky one carries state between tests, which is not reproduced. */
|
|
6382
|
+
function regex(literal) {
|
|
6383
|
+
if (literal === null) return void 0;
|
|
6384
|
+
if (/[gy]/.test(literal.flags)) return null;
|
|
6385
|
+
try {
|
|
6386
|
+
return new RegExp(literal.source, literal.flags);
|
|
6387
|
+
} catch {
|
|
6388
|
+
return null;
|
|
6389
|
+
}
|
|
6390
|
+
}
|
|
6391
|
+
/** Webpack's `splitContextFromPrefix`. */
|
|
6392
|
+
function splitContextFromPrefix(prefix) {
|
|
6393
|
+
const at = prefix.lastIndexOf("/");
|
|
6394
|
+
return at >= 0 ? {
|
|
6395
|
+
context: prefix.slice(0, at),
|
|
6396
|
+
prefix: `.${prefix.slice(at)}`
|
|
6397
|
+
} : {
|
|
6398
|
+
context: ".",
|
|
6399
|
+
prefix
|
|
6400
|
+
};
|
|
6401
|
+
}
|
|
6402
|
+
/** A context directory webpack resolves relative to the importer; another
|
|
6403
|
+
* form goes through the resolver (aliases, modules), not reproduced. */
|
|
6404
|
+
function contextDir(importerDir, context) {
|
|
6405
|
+
return context === "." || context.startsWith("./") || context.startsWith("../") ? (0, node_path.resolve)(importerDir, context) : void 0;
|
|
6406
|
+
}
|
|
6407
|
+
/** The comments that change which files a webpack context holds. */
|
|
6408
|
+
const SELECTING_COMMENT = /webpack(?:Include|Exclude|Ignore)\b/;
|
|
6409
|
+
/**
|
|
6410
|
+
* The context webpack builds for a template literal or a concatenation
|
|
6411
|
+
* (`ContextDependencyHelpers.create`), with the default wrapped-context
|
|
6412
|
+
* options (`/.*\/`, recursive): a template's inner text joins the
|
|
6413
|
+
* expression pattern; a concatenation keeps its prefix and postfix only.
|
|
6414
|
+
*/
|
|
6415
|
+
function specifierContext(load, importerDir) {
|
|
6416
|
+
const { args } = load;
|
|
6417
|
+
if (args === null || !("quasis" in args)) return void 0;
|
|
6418
|
+
if (args.options !== null) return void 0;
|
|
6419
|
+
if (args.comments.some((comment) => SELECTING_COMMENT.test(comment))) return;
|
|
6420
|
+
const { quasis, template } = args;
|
|
6421
|
+
if (quasis.length < 2 || !template && quasis.length > 2) return void 0;
|
|
6422
|
+
const { context, prefix } = splitContextFromPrefix(quasis[0]);
|
|
6423
|
+
const postfixRaw = quasis[quasis.length - 1];
|
|
6424
|
+
if (postfixRaw.includes("#")) return void 0;
|
|
6425
|
+
const at = postfixRaw.indexOf("?");
|
|
6426
|
+
const postfix = at === -1 ? postfixRaw : postfixRaw.slice(0, at);
|
|
6427
|
+
const query = at === -1 ? "" : postfixRaw.slice(at);
|
|
6428
|
+
const inner = template ? quasis.slice(1, -1).map((quasi) => `${quoteMeta(quasi)}.*`).join("") : "";
|
|
6429
|
+
const dir = contextDir(importerDir, context);
|
|
6430
|
+
if (dir === void 0) return void 0;
|
|
6431
|
+
return {
|
|
6432
|
+
dir,
|
|
6433
|
+
recursive: true,
|
|
6434
|
+
regExp: new RegExp(`^${quoteMeta(prefix)}.*${inner}${quoteMeta(postfix)}$`),
|
|
6435
|
+
include: void 0,
|
|
6436
|
+
exclude: void 0,
|
|
6437
|
+
query,
|
|
6438
|
+
category: load.kind === "require" ? "commonjs" : "esm"
|
|
6439
|
+
};
|
|
6440
|
+
}
|
|
6441
|
+
/** `require.context(dir, recursive, regExp, mode)` and
|
|
6442
|
+
* `import.meta.webpackContext(dir, { … })`, with webpack's defaults. */
|
|
6443
|
+
function directContext(load, importerDir) {
|
|
6444
|
+
const { args } = load;
|
|
6445
|
+
if (args === null || !("dir" in args)) return void 0;
|
|
6446
|
+
const regExp = regex(args.regExp);
|
|
6447
|
+
const include = regex(args.include);
|
|
6448
|
+
const exclude = regex(args.exclude);
|
|
6449
|
+
if (regExp === null || include === null || exclude === null) return;
|
|
6450
|
+
const dir = contextDir(importerDir, args.dir);
|
|
6451
|
+
if (dir === void 0) return void 0;
|
|
6452
|
+
return {
|
|
6453
|
+
dir,
|
|
6454
|
+
recursive: args.recursive ?? true,
|
|
6455
|
+
regExp: regExp ?? /^\.\/.*$/,
|
|
6456
|
+
include,
|
|
6457
|
+
exclude,
|
|
6458
|
+
query: "",
|
|
6459
|
+
category: load.kind === "context" ? "commonjs" : "esm"
|
|
6460
|
+
};
|
|
6461
|
+
}
|
|
6462
|
+
/** A group of module directory names, rather than one absolute module
|
|
6463
|
+
* directory. */
|
|
6464
|
+
function isModuleGroup(modules) {
|
|
6465
|
+
return Array.isArray(modules);
|
|
6466
|
+
}
|
|
6467
|
+
/** The requests webpack tests a context file's regExp against
|
|
6468
|
+
* (`RequireContextPlugin`'s `alternativeRequests`). */
|
|
6469
|
+
function alternatives(context, request, reading) {
|
|
6470
|
+
let items = [request];
|
|
6471
|
+
if (!reading.fullySpecified) {
|
|
6472
|
+
const extended = [];
|
|
6473
|
+
for (const item of items) {
|
|
6474
|
+
for (const extension of reading.extensions) if (item.endsWith(extension)) extended.push(item.slice(0, -extension.length));
|
|
6475
|
+
if (!reading.enforceExtension) extended.push(item);
|
|
6476
|
+
}
|
|
6477
|
+
items = [];
|
|
6478
|
+
for (const item of extended) {
|
|
6479
|
+
for (const mainFile of reading.mainFiles) if (item.endsWith(`/${mainFile}`)) {
|
|
6480
|
+
items.push(item.slice(0, -mainFile.length));
|
|
6481
|
+
items.push(item.slice(0, -mainFile.length - 1));
|
|
6482
|
+
}
|
|
6483
|
+
items.push(item);
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6486
|
+
const requests = [];
|
|
6487
|
+
for (const item of items) {
|
|
6488
|
+
let hidden = false;
|
|
6489
|
+
for (const modules of reading.modules) if (isModuleGroup(modules)) {
|
|
6490
|
+
for (const name of modules) if (item.startsWith(`./${name}/`)) {
|
|
6491
|
+
requests.push(item.slice(name.length + 3));
|
|
6492
|
+
hidden = true;
|
|
6493
|
+
}
|
|
6494
|
+
} else {
|
|
6495
|
+
const dir = modules.replace(/\\/g, "/");
|
|
6496
|
+
const full = context.replace(/\\/g, "/") + item.slice(1);
|
|
6497
|
+
if (full.startsWith(dir)) requests.push(full.slice(dir.length + 1));
|
|
6498
|
+
}
|
|
6499
|
+
if (!hidden) requests.push(item);
|
|
6500
|
+
}
|
|
6501
|
+
return requests;
|
|
6502
|
+
}
|
|
6503
|
+
/** The files a context holds (`resolveDependencies`): below its directory,
|
|
6504
|
+
* dot-led names skipped, `exclude` and `include` tested on each absolute
|
|
6505
|
+
* path, a file kept when any of its alternative requests matches. */
|
|
6506
|
+
function contextFiles(context, reading) {
|
|
6507
|
+
const files = [];
|
|
6508
|
+
const visit = (dir, visited) => {
|
|
6509
|
+
const real = (0, node_fs.realpathSync)(dir);
|
|
6510
|
+
const names = (0, node_fs.readdirSync)(dir).map((name) => name.normalize("NFC"));
|
|
6511
|
+
if (visited.has(real)) return;
|
|
6512
|
+
const inside = new Set(visited).add(real);
|
|
6513
|
+
for (const name of names) {
|
|
6514
|
+
if (name.startsWith(".")) continue;
|
|
6515
|
+
const path = `${dir}${node_path.sep}${name}`;
|
|
6516
|
+
if (context.exclude?.test(path)) continue;
|
|
6517
|
+
const stat = (0, node_fs.statSync)(path);
|
|
6518
|
+
if (stat.isDirectory()) {
|
|
6519
|
+
if (context.recursive) visit(path, inside);
|
|
6520
|
+
} else if (stat.isFile() && (!context.include || context.include.test(path))) {
|
|
6521
|
+
const request = `.${path.slice(context.dir.length).replace(/\\/g, "/")}`;
|
|
6522
|
+
if (alternatives(context.dir, request, reading).some((alternative) => context.regExp.test(alternative))) files.push((0, node_fs.realpathSync)(path));
|
|
6523
|
+
}
|
|
6524
|
+
}
|
|
6525
|
+
};
|
|
6526
|
+
visit(context.dir, /* @__PURE__ */ new Set());
|
|
6527
|
+
return files.sort();
|
|
6528
|
+
}
|
|
6529
|
+
/**
|
|
6530
|
+
* How a webpack 5 build expands computed loads (spec §6.3): a template or
|
|
6531
|
+
* concatenated `import()` or `require()`, `require.context` and
|
|
6532
|
+
* `import.meta.webpackContext`, each a context module whose files
|
|
6533
|
+
* `ContextModuleFactory` lists. `resolveReading` is the resolver's options
|
|
6534
|
+
* for a dependency category; `wrappedDefaults` is false where the project
|
|
6535
|
+
* changes `wrappedContextRegExp` or `wrappedContextRecursive`. Anything not
|
|
6536
|
+
* reproduced exactly lists no expansion.
|
|
6537
|
+
*/
|
|
6538
|
+
function webpackLoadExpander(resolveReading, wrappedDefaults) {
|
|
6539
|
+
return { expand(load, rootDir) {
|
|
6540
|
+
const importerDir = (0, node_path.dirname)((0, node_path.resolve)(rootDir, load.importer));
|
|
6541
|
+
let context;
|
|
6542
|
+
if (load.kind === "import" || load.kind === "require") context = wrappedDefaults ? specifierContext(load, importerDir) : void 0;
|
|
6543
|
+
else if (load.kind === "context" || load.kind === "webpackContext") context = directContext(load, importerDir);
|
|
6544
|
+
if (context === void 0) return void 0;
|
|
6545
|
+
const reading = resolveReading(context.category);
|
|
6546
|
+
if (reading === void 0 || reading.aliasNames.length > 0) return;
|
|
6547
|
+
let files;
|
|
6548
|
+
let realRoot;
|
|
6549
|
+
try {
|
|
6550
|
+
files = contextFiles(context, reading);
|
|
6551
|
+
realRoot = (0, node_fs.realpathSync)(rootDir);
|
|
6552
|
+
} catch {
|
|
6553
|
+
return;
|
|
6554
|
+
}
|
|
6555
|
+
return files.map((file) => ({
|
|
6556
|
+
path: (0, node_path.relative)(realRoot, file).split(node_path.sep).join(node_path.posix.sep),
|
|
6557
|
+
query: context.query
|
|
6558
|
+
}));
|
|
6559
|
+
} };
|
|
6560
|
+
}
|
|
6561
|
+
/** A rule entry, rather than `'...'` or a falsy placeholder. */
|
|
6562
|
+
function isRule(rule) {
|
|
6563
|
+
return rule instanceof Object;
|
|
6564
|
+
}
|
|
6565
|
+
/** Every rule, nested `rules` and `oneOf` included. */
|
|
6566
|
+
function everyRule(rules) {
|
|
6567
|
+
return rules.filter(isRule).flatMap((rule) => [
|
|
6568
|
+
rule,
|
|
6569
|
+
...everyRule(rule.rules ?? []),
|
|
6570
|
+
...everyRule(rule.oneOf ?? [])
|
|
6571
|
+
]);
|
|
6572
|
+
}
|
|
6573
|
+
/**
|
|
6574
|
+
* The expander for a webpack 5 compiler. Each expansion reads the
|
|
6575
|
+
* compiler's options again and lists nothing where a rule carries its own
|
|
6576
|
+
* resolve options or context parser options, `module.defaultRules` is not
|
|
6577
|
+
* webpack's own, or the options cannot be read.
|
|
6578
|
+
*/
|
|
6579
|
+
function webpackHostExpander(reading) {
|
|
6580
|
+
return { expand(load, rootDir) {
|
|
6581
|
+
let options;
|
|
6582
|
+
try {
|
|
6583
|
+
options = reading.options();
|
|
6584
|
+
} catch {
|
|
6585
|
+
return;
|
|
6586
|
+
}
|
|
6587
|
+
if (everyRule(options.rules).some((rule) => rule.resolve !== void 0 || Object.keys(rule.parser ?? {}).some((key) => key.includes("Context"))) || !options.defaultRulesAreWebpacks) return void 0;
|
|
6588
|
+
return webpackLoadExpander(reading.resolveReading, options.wrappedDefaults).expand(load, rootDir);
|
|
6589
|
+
} };
|
|
6590
|
+
}
|
|
6591
|
+
//#endregion
|
|
6592
|
+
//#region pipeline/served-files.ts
|
|
6593
|
+
function servedFiles(manifest) {
|
|
6594
|
+
const dropped = /* @__PURE__ */ new Map();
|
|
6595
|
+
for (const input of manifest.missing_inputs ?? []) {
|
|
6596
|
+
if (input.outcome === "failed-parent") continue;
|
|
6597
|
+
if (!dropped.has(input.file)) dropped.set(input.file, input);
|
|
6598
|
+
}
|
|
6599
|
+
return {
|
|
6600
|
+
listed: new Set(Object.entries(manifest.files ?? {}).filter(([, ids]) => ids.length > 0).map(([file]) => file)),
|
|
6601
|
+
dropped
|
|
6602
|
+
};
|
|
6603
|
+
}
|
|
6604
|
+
/** Why a file dropped over its extension parent is not served: its builder
|
|
6605
|
+
* code would render with empty classes. */
|
|
6606
|
+
function droppedExtensionMessage(drop) {
|
|
6607
|
+
const from = drop.specifier === null ? "" : ` from '${drop.specifier}'`;
|
|
6608
|
+
return `[animus-extract] cannot serve ${drop.file}: '${drop.component}' extends '${drop.parent}'${from}, which the analysis could not resolve (${drop.outcome}); serving it untransformed would render it without its styles. Make the parent an analysed Animus component, or remove the extension.`;
|
|
6609
|
+
}
|
|
6610
|
+
//#endregion
|
|
5099
6611
|
Object.defineProperty(exports, "ANIMUS_LAYERS", {
|
|
5100
6612
|
enumerable: true,
|
|
5101
6613
|
get: function() {
|
|
5102
6614
|
return ANIMUS_LAYERS;
|
|
5103
6615
|
}
|
|
5104
6616
|
});
|
|
6617
|
+
Object.defineProperty(exports, "AliasAgreementCache", {
|
|
6618
|
+
enumerable: true,
|
|
6619
|
+
get: function() {
|
|
6620
|
+
return AliasAgreementCache;
|
|
6621
|
+
}
|
|
6622
|
+
});
|
|
5105
6623
|
Object.defineProperty(exports, "AnimusConfigError", {
|
|
5106
6624
|
enumerable: true,
|
|
5107
6625
|
get: function() {
|
|
5108
6626
|
return AnimusConfigError;
|
|
5109
6627
|
}
|
|
5110
6628
|
});
|
|
6629
|
+
Object.defineProperty(exports, "BUILT_IN_EXTENSION_POLICY", {
|
|
6630
|
+
enumerable: true,
|
|
6631
|
+
get: function() {
|
|
6632
|
+
return BUILT_IN_EXTENSION_POLICY;
|
|
6633
|
+
}
|
|
6634
|
+
});
|
|
5111
6635
|
Object.defineProperty(exports, "CORE_OPTION_KEYS", {
|
|
5112
6636
|
enumerable: true,
|
|
5113
6637
|
get: function() {
|
|
@@ -5126,6 +6650,12 @@ Object.defineProperty(exports, "DEFAULT_EXTENSIONS", {
|
|
|
5126
6650
|
return DEFAULT_EXTENSIONS;
|
|
5127
6651
|
}
|
|
5128
6652
|
});
|
|
6653
|
+
Object.defineProperty(exports, "DEFAULT_RUNTIME_IMPORT", {
|
|
6654
|
+
enumerable: true,
|
|
6655
|
+
get: function() {
|
|
6656
|
+
return DEFAULT_RUNTIME_IMPORT;
|
|
6657
|
+
}
|
|
6658
|
+
});
|
|
5129
6659
|
Object.defineProperty(exports, "DIAGNOSTIC_LEVELS", {
|
|
5130
6660
|
enumerable: true,
|
|
5131
6661
|
get: function() {
|
|
@@ -5180,6 +6710,12 @@ Object.defineProperty(exports, "STRUCTURAL_EXCLUDE", {
|
|
|
5180
6710
|
return STRUCTURAL_EXCLUDE;
|
|
5181
6711
|
}
|
|
5182
6712
|
});
|
|
6713
|
+
Object.defineProperty(exports, "SYSTEM_INSTANCE_MISMATCH", {
|
|
6714
|
+
enumerable: true,
|
|
6715
|
+
get: function() {
|
|
6716
|
+
return SYSTEM_INSTANCE_MISMATCH;
|
|
6717
|
+
}
|
|
6718
|
+
});
|
|
5183
6719
|
Object.defineProperty(exports, "VOCABULARY_COLLISION", {
|
|
5184
6720
|
enumerable: true,
|
|
5185
6721
|
get: function() {
|
|
@@ -5198,6 +6734,18 @@ Object.defineProperty(exports, "adaptSvelteSource", {
|
|
|
5198
6734
|
return adaptSvelteSource;
|
|
5199
6735
|
}
|
|
5200
6736
|
});
|
|
6737
|
+
Object.defineProperty(exports, "adaptedOriginals", {
|
|
6738
|
+
enumerable: true,
|
|
6739
|
+
get: function() {
|
|
6740
|
+
return adaptedOriginals;
|
|
6741
|
+
}
|
|
6742
|
+
});
|
|
6743
|
+
Object.defineProperty(exports, "analysedOutputs", {
|
|
6744
|
+
enumerable: true,
|
|
6745
|
+
get: function() {
|
|
6746
|
+
return analysedOutputs;
|
|
6747
|
+
}
|
|
6748
|
+
});
|
|
5201
6749
|
Object.defineProperty(exports, "applyPrefix", {
|
|
5202
6750
|
enumerable: true,
|
|
5203
6751
|
get: function() {
|
|
@@ -5228,10 +6776,22 @@ Object.defineProperty(exports, "assertNoErrorDiagnostics", {
|
|
|
5228
6776
|
return assertNoErrorDiagnostics;
|
|
5229
6777
|
}
|
|
5230
6778
|
});
|
|
5231
|
-
Object.defineProperty(exports, "
|
|
6779
|
+
Object.defineProperty(exports, "assertRuntimeImportSuppliesTerminals", {
|
|
5232
6780
|
enumerable: true,
|
|
5233
6781
|
get: function() {
|
|
5234
|
-
return
|
|
6782
|
+
return assertRuntimeImportSuppliesTerminals;
|
|
6783
|
+
}
|
|
6784
|
+
});
|
|
6785
|
+
Object.defineProperty(exports, "assertSupportedEngine", {
|
|
6786
|
+
enumerable: true,
|
|
6787
|
+
get: function() {
|
|
6788
|
+
return assertSupportedEngine;
|
|
6789
|
+
}
|
|
6790
|
+
});
|
|
6791
|
+
Object.defineProperty(exports, "bareSpecifierPackageName", {
|
|
6792
|
+
enumerable: true,
|
|
6793
|
+
get: function() {
|
|
6794
|
+
return bareSpecifierPackageName;
|
|
5235
6795
|
}
|
|
5236
6796
|
});
|
|
5237
6797
|
Object.defineProperty(exports, "buildAnalysisInputs", {
|
|
@@ -5270,12 +6830,24 @@ Object.defineProperty(exports, "buildSystemPropsModule", {
|
|
|
5270
6830
|
return buildSystemPropsModule;
|
|
5271
6831
|
}
|
|
5272
6832
|
});
|
|
6833
|
+
Object.defineProperty(exports, "builtInAssetClassification", {
|
|
6834
|
+
enumerable: true,
|
|
6835
|
+
get: function() {
|
|
6836
|
+
return builtInAssetClassification;
|
|
6837
|
+
}
|
|
6838
|
+
});
|
|
5273
6839
|
Object.defineProperty(exports, "camelToKebab", {
|
|
5274
6840
|
enumerable: true,
|
|
5275
6841
|
get: function() {
|
|
5276
6842
|
return camelToKebab;
|
|
5277
6843
|
}
|
|
5278
6844
|
});
|
|
6845
|
+
Object.defineProperty(exports, "caseMismatchReason", {
|
|
6846
|
+
enumerable: true,
|
|
6847
|
+
get: function() {
|
|
6848
|
+
return caseMismatchReason;
|
|
6849
|
+
}
|
|
6850
|
+
});
|
|
5279
6851
|
Object.defineProperty(exports, "clearEngineCache", {
|
|
5280
6852
|
enumerable: true,
|
|
5281
6853
|
get: function() {
|
|
@@ -5288,6 +6860,12 @@ Object.defineProperty(exports, "collectExternalPackageSources", {
|
|
|
5288
6860
|
return collectExternalPackageSources;
|
|
5289
6861
|
}
|
|
5290
6862
|
});
|
|
6863
|
+
Object.defineProperty(exports, "compareAliases", {
|
|
6864
|
+
enumerable: true,
|
|
6865
|
+
get: function() {
|
|
6866
|
+
return compareAliases;
|
|
6867
|
+
}
|
|
6868
|
+
});
|
|
5291
6869
|
Object.defineProperty(exports, "compareDiscoveryOrder", {
|
|
5292
6870
|
enumerable: true,
|
|
5293
6871
|
get: function() {
|
|
@@ -5324,6 +6902,12 @@ Object.defineProperty(exports, "createV2EngineApi", {
|
|
|
5324
6902
|
return createV2EngineApi;
|
|
5325
6903
|
}
|
|
5326
6904
|
});
|
|
6905
|
+
Object.defineProperty(exports, "declaredWorkspacePackages", {
|
|
6906
|
+
enumerable: true,
|
|
6907
|
+
get: function() {
|
|
6908
|
+
return declaredWorkspacePackages;
|
|
6909
|
+
}
|
|
6910
|
+
});
|
|
5327
6911
|
Object.defineProperty(exports, "diffFilePlans", {
|
|
5328
6912
|
enumerable: true,
|
|
5329
6913
|
get: function() {
|
|
@@ -5336,6 +6920,18 @@ Object.defineProperty(exports, "discoverFiles", {
|
|
|
5336
6920
|
return discoverFiles;
|
|
5337
6921
|
}
|
|
5338
6922
|
});
|
|
6923
|
+
Object.defineProperty(exports, "discoveryResolver", {
|
|
6924
|
+
enumerable: true,
|
|
6925
|
+
get: function() {
|
|
6926
|
+
return discoveryResolver;
|
|
6927
|
+
}
|
|
6928
|
+
});
|
|
6929
|
+
Object.defineProperty(exports, "droppedExtensionMessage", {
|
|
6930
|
+
enumerable: true,
|
|
6931
|
+
get: function() {
|
|
6932
|
+
return droppedExtensionMessage;
|
|
6933
|
+
}
|
|
6934
|
+
});
|
|
5339
6935
|
Object.defineProperty(exports, "enforceExternalTokenContracts", {
|
|
5340
6936
|
enumerable: true,
|
|
5341
6937
|
get: function() {
|
|
@@ -5348,12 +6944,36 @@ Object.defineProperty(exports, "engineModuleParser", {
|
|
|
5348
6944
|
return engineModuleParser;
|
|
5349
6945
|
}
|
|
5350
6946
|
});
|
|
6947
|
+
Object.defineProperty(exports, "esbuildAssetClassification", {
|
|
6948
|
+
enumerable: true,
|
|
6949
|
+
get: function() {
|
|
6950
|
+
return esbuildAssetClassification;
|
|
6951
|
+
}
|
|
6952
|
+
});
|
|
6953
|
+
Object.defineProperty(exports, "esbuildExtensionPolicy", {
|
|
6954
|
+
enumerable: true,
|
|
6955
|
+
get: function() {
|
|
6956
|
+
return esbuildExtensionPolicy;
|
|
6957
|
+
}
|
|
6958
|
+
});
|
|
6959
|
+
Object.defineProperty(exports, "esbuildOutputTargets", {
|
|
6960
|
+
enumerable: true,
|
|
6961
|
+
get: function() {
|
|
6962
|
+
return esbuildOutputTargets;
|
|
6963
|
+
}
|
|
6964
|
+
});
|
|
5351
6965
|
Object.defineProperty(exports, "excludeCollectedPackages", {
|
|
5352
6966
|
enumerable: true,
|
|
5353
6967
|
get: function() {
|
|
5354
6968
|
return excludeCollectedPackages;
|
|
5355
6969
|
}
|
|
5356
6970
|
});
|
|
6971
|
+
Object.defineProperty(exports, "extensionPolicyJson", {
|
|
6972
|
+
enumerable: true,
|
|
6973
|
+
get: function() {
|
|
6974
|
+
return extensionPolicyJson;
|
|
6975
|
+
}
|
|
6976
|
+
});
|
|
5357
6977
|
Object.defineProperty(exports, "extractSystemFilePackages", {
|
|
5358
6978
|
enumerable: true,
|
|
5359
6979
|
get: function() {
|
|
@@ -5438,16 +7058,10 @@ Object.defineProperty(exports, "isExcludedPackageRelativePath", {
|
|
|
5438
7058
|
return isExcludedPackageRelativePath;
|
|
5439
7059
|
}
|
|
5440
7060
|
});
|
|
5441
|
-
Object.defineProperty(exports, "
|
|
7061
|
+
Object.defineProperty(exports, "isPackageSpecifier", {
|
|
5442
7062
|
enumerable: true,
|
|
5443
7063
|
get: function() {
|
|
5444
|
-
return
|
|
5445
|
-
}
|
|
5446
|
-
});
|
|
5447
|
-
Object.defineProperty(exports, "isJsonString", {
|
|
5448
|
-
enumerable: true,
|
|
5449
|
-
get: function() {
|
|
5450
|
-
return isJsonString;
|
|
7064
|
+
return isPackageSpecifier;
|
|
5451
7065
|
}
|
|
5452
7066
|
});
|
|
5453
7067
|
Object.defineProperty(exports, "isPathWithinRoot", {
|
|
@@ -5456,12 +7070,6 @@ Object.defineProperty(exports, "isPathWithinRoot", {
|
|
|
5456
7070
|
return isPathWithinRoot;
|
|
5457
7071
|
}
|
|
5458
7072
|
});
|
|
5459
|
-
Object.defineProperty(exports, "isUnresolvedParentDrop", {
|
|
5460
|
-
enumerable: true,
|
|
5461
|
-
get: function() {
|
|
5462
|
-
return isUnresolvedParentDrop;
|
|
5463
|
-
}
|
|
5464
|
-
});
|
|
5465
7073
|
Object.defineProperty(exports, "keepsKitSourceEffects", {
|
|
5466
7074
|
enumerable: true,
|
|
5467
7075
|
get: function() {
|
|
@@ -5492,12 +7100,78 @@ Object.defineProperty(exports, "loadSystemConfig", {
|
|
|
5492
7100
|
return loadSystemConfig;
|
|
5493
7101
|
}
|
|
5494
7102
|
});
|
|
7103
|
+
Object.defineProperty(exports, "mergeOutputTargets", {
|
|
7104
|
+
enumerable: true,
|
|
7105
|
+
get: function() {
|
|
7106
|
+
return mergeOutputTargets;
|
|
7107
|
+
}
|
|
7108
|
+
});
|
|
7109
|
+
Object.defineProperty(exports, "nativeKitSourceRoot", {
|
|
7110
|
+
enumerable: true,
|
|
7111
|
+
get: function() {
|
|
7112
|
+
return nativeKitSourceRoot;
|
|
7113
|
+
}
|
|
7114
|
+
});
|
|
7115
|
+
Object.defineProperty(exports, "nativePackageLocator", {
|
|
7116
|
+
enumerable: true,
|
|
7117
|
+
get: function() {
|
|
7118
|
+
return nativePackageLocator;
|
|
7119
|
+
}
|
|
7120
|
+
});
|
|
7121
|
+
Object.defineProperty(exports, "nextImageAssetClassification", {
|
|
7122
|
+
enumerable: true,
|
|
7123
|
+
get: function() {
|
|
7124
|
+
return nextImageAssetClassification;
|
|
7125
|
+
}
|
|
7126
|
+
});
|
|
5495
7127
|
Object.defineProperty(exports, "noKitFilesDiagnostics", {
|
|
5496
7128
|
enumerable: true,
|
|
5497
7129
|
get: function() {
|
|
5498
7130
|
return noKitFilesDiagnostics;
|
|
5499
7131
|
}
|
|
5500
7132
|
});
|
|
7133
|
+
Object.defineProperty(exports, "noOutputTargets", {
|
|
7134
|
+
enumerable: true,
|
|
7135
|
+
get: function() {
|
|
7136
|
+
return noOutputTargets;
|
|
7137
|
+
}
|
|
7138
|
+
});
|
|
7139
|
+
Object.defineProperty(exports, "outputExclusion", {
|
|
7140
|
+
enumerable: true,
|
|
7141
|
+
get: function() {
|
|
7142
|
+
return outputExclusion;
|
|
7143
|
+
}
|
|
7144
|
+
});
|
|
7145
|
+
Object.defineProperty(exports, "outputExclusions", {
|
|
7146
|
+
enumerable: true,
|
|
7147
|
+
get: function() {
|
|
7148
|
+
return outputExclusions;
|
|
7149
|
+
}
|
|
7150
|
+
});
|
|
7151
|
+
Object.defineProperty(exports, "outputSourceGuard", {
|
|
7152
|
+
enumerable: true,
|
|
7153
|
+
get: function() {
|
|
7154
|
+
return outputSourceGuard;
|
|
7155
|
+
}
|
|
7156
|
+
});
|
|
7157
|
+
Object.defineProperty(exports, "outputSourceMessage", {
|
|
7158
|
+
enumerable: true,
|
|
7159
|
+
get: function() {
|
|
7160
|
+
return outputSourceMessage;
|
|
7161
|
+
}
|
|
7162
|
+
});
|
|
7163
|
+
Object.defineProperty(exports, "packageInstanceFinding", {
|
|
7164
|
+
enumerable: true,
|
|
7165
|
+
get: function() {
|
|
7166
|
+
return packageInstanceFinding;
|
|
7167
|
+
}
|
|
7168
|
+
});
|
|
7169
|
+
Object.defineProperty(exports, "packageReadRecord", {
|
|
7170
|
+
enumerable: true,
|
|
7171
|
+
get: function() {
|
|
7172
|
+
return packageReadRecord;
|
|
7173
|
+
}
|
|
7174
|
+
});
|
|
5501
7175
|
Object.defineProperty(exports, "parseFilesJson", {
|
|
5502
7176
|
enumerable: true,
|
|
5503
7177
|
get: function() {
|
|
@@ -5522,12 +7196,24 @@ Object.defineProperty(exports, "preprocessMdx", {
|
|
|
5522
7196
|
return preprocessMdx;
|
|
5523
7197
|
}
|
|
5524
7198
|
});
|
|
7199
|
+
Object.defineProperty(exports, "probeAbsolutePathSpecifier", {
|
|
7200
|
+
enumerable: true,
|
|
7201
|
+
get: function() {
|
|
7202
|
+
return probeAbsolutePathSpecifier;
|
|
7203
|
+
}
|
|
7204
|
+
});
|
|
5525
7205
|
Object.defineProperty(exports, "projectExternalFileOwners", {
|
|
5526
7206
|
enumerable: true,
|
|
5527
7207
|
get: function() {
|
|
5528
7208
|
return projectExternalFileOwners;
|
|
5529
7209
|
}
|
|
5530
7210
|
});
|
|
7211
|
+
Object.defineProperty(exports, "pruneStaleAssets", {
|
|
7212
|
+
enumerable: true,
|
|
7213
|
+
get: function() {
|
|
7214
|
+
return pruneStaleAssets;
|
|
7215
|
+
}
|
|
7216
|
+
});
|
|
5531
7217
|
Object.defineProperty(exports, "readKitDescriptor", {
|
|
5532
7218
|
enumerable: true,
|
|
5533
7219
|
get: function() {
|
|
@@ -5546,12 +7232,6 @@ Object.defineProperty(exports, "reportSurvivingAssetPlaceholders", {
|
|
|
5546
7232
|
return reportSurvivingAssetPlaceholders;
|
|
5547
7233
|
}
|
|
5548
7234
|
});
|
|
5549
|
-
Object.defineProperty(exports, "resolveAbsolutePathSpecifier", {
|
|
5550
|
-
enumerable: true,
|
|
5551
|
-
get: function() {
|
|
5552
|
-
return resolveAbsolutePathSpecifier;
|
|
5553
|
-
}
|
|
5554
|
-
});
|
|
5555
7235
|
Object.defineProperty(exports, "resolveAssetFile", {
|
|
5556
7236
|
enumerable: true,
|
|
5557
7237
|
get: function() {
|
|
@@ -5582,6 +7262,18 @@ Object.defineProperty(exports, "resolveVerbosity", {
|
|
|
5582
7262
|
return resolveVerbosity;
|
|
5583
7263
|
}
|
|
5584
7264
|
});
|
|
7265
|
+
Object.defineProperty(exports, "rollupExtensionPolicy", {
|
|
7266
|
+
enumerable: true,
|
|
7267
|
+
get: function() {
|
|
7268
|
+
return rollupExtensionPolicy;
|
|
7269
|
+
}
|
|
7270
|
+
});
|
|
7271
|
+
Object.defineProperty(exports, "rollupOutputTargets", {
|
|
7272
|
+
enumerable: true,
|
|
7273
|
+
get: function() {
|
|
7274
|
+
return rollupOutputTargets;
|
|
7275
|
+
}
|
|
7276
|
+
});
|
|
5585
7277
|
Object.defineProperty(exports, "runProjectAnalysis", {
|
|
5586
7278
|
enumerable: true,
|
|
5587
7279
|
get: function() {
|
|
@@ -5600,6 +7292,18 @@ Object.defineProperty(exports, "serializeStaticCss", {
|
|
|
5600
7292
|
return serializeStaticCss;
|
|
5601
7293
|
}
|
|
5602
7294
|
});
|
|
7295
|
+
Object.defineProperty(exports, "servedFiles", {
|
|
7296
|
+
enumerable: true,
|
|
7297
|
+
get: function() {
|
|
7298
|
+
return servedFiles;
|
|
7299
|
+
}
|
|
7300
|
+
});
|
|
7301
|
+
Object.defineProperty(exports, "severityFor", {
|
|
7302
|
+
enumerable: true,
|
|
7303
|
+
get: function() {
|
|
7304
|
+
return severityFor;
|
|
7305
|
+
}
|
|
7306
|
+
});
|
|
5603
7307
|
Object.defineProperty(exports, "sharesVolumeRoot", {
|
|
5604
7308
|
enumerable: true,
|
|
5605
7309
|
get: function() {
|
|
@@ -5654,18 +7358,48 @@ Object.defineProperty(exports, "surfaceManifestDiagnostics", {
|
|
|
5654
7358
|
return surfaceManifestDiagnostics;
|
|
5655
7359
|
}
|
|
5656
7360
|
});
|
|
7361
|
+
Object.defineProperty(exports, "systemKitDependencies", {
|
|
7362
|
+
enumerable: true,
|
|
7363
|
+
get: function() {
|
|
7364
|
+
return systemKitDependencies;
|
|
7365
|
+
}
|
|
7366
|
+
});
|
|
5657
7367
|
Object.defineProperty(exports, "systemLoadDiagnostics", {
|
|
5658
7368
|
enumerable: true,
|
|
5659
7369
|
get: function() {
|
|
5660
7370
|
return systemLoadDiagnostics;
|
|
5661
7371
|
}
|
|
5662
7372
|
});
|
|
7373
|
+
Object.defineProperty(exports, "systemLoadReads", {
|
|
7374
|
+
enumerable: true,
|
|
7375
|
+
get: function() {
|
|
7376
|
+
return systemLoadReads;
|
|
7377
|
+
}
|
|
7378
|
+
});
|
|
5663
7379
|
Object.defineProperty(exports, "toWatchKeys", {
|
|
5664
7380
|
enumerable: true,
|
|
5665
7381
|
get: function() {
|
|
5666
7382
|
return toWatchKeys;
|
|
5667
7383
|
}
|
|
5668
7384
|
});
|
|
7385
|
+
Object.defineProperty(exports, "tsconfigChainPaths", {
|
|
7386
|
+
enumerable: true,
|
|
7387
|
+
get: function() {
|
|
7388
|
+
return tsconfigChainPaths;
|
|
7389
|
+
}
|
|
7390
|
+
});
|
|
7391
|
+
Object.defineProperty(exports, "turbopackExtensionPolicy", {
|
|
7392
|
+
enumerable: true,
|
|
7393
|
+
get: function() {
|
|
7394
|
+
return turbopackExtensionPolicy;
|
|
7395
|
+
}
|
|
7396
|
+
});
|
|
7397
|
+
Object.defineProperty(exports, "unmatchedExcludeLines", {
|
|
7398
|
+
enumerable: true,
|
|
7399
|
+
get: function() {
|
|
7400
|
+
return unmatchedExcludeLines;
|
|
7401
|
+
}
|
|
7402
|
+
});
|
|
5669
7403
|
Object.defineProperty(exports, "unreadableSourceDiagnostic", {
|
|
5670
7404
|
enumerable: true,
|
|
5671
7405
|
get: function() {
|
|
@@ -5678,16 +7412,40 @@ Object.defineProperty(exports, "unresolvableIncludesMessage", {
|
|
|
5678
7412
|
return unresolvableIncludesMessage;
|
|
5679
7413
|
}
|
|
5680
7414
|
});
|
|
5681
|
-
Object.defineProperty(exports, "
|
|
7415
|
+
Object.defineProperty(exports, "validateLayerOrder", {
|
|
5682
7416
|
enumerable: true,
|
|
5683
7417
|
get: function() {
|
|
5684
|
-
return
|
|
7418
|
+
return validateLayerOrder;
|
|
5685
7419
|
}
|
|
5686
7420
|
});
|
|
5687
|
-
Object.defineProperty(exports, "
|
|
7421
|
+
Object.defineProperty(exports, "viteAssetClassification", {
|
|
5688
7422
|
enumerable: true,
|
|
5689
7423
|
get: function() {
|
|
5690
|
-
return
|
|
7424
|
+
return viteAssetClassification;
|
|
7425
|
+
}
|
|
7426
|
+
});
|
|
7427
|
+
Object.defineProperty(exports, "viteExtensionPolicy", {
|
|
7428
|
+
enumerable: true,
|
|
7429
|
+
get: function() {
|
|
7430
|
+
return viteExtensionPolicy;
|
|
7431
|
+
}
|
|
7432
|
+
});
|
|
7433
|
+
Object.defineProperty(exports, "viteHostExpander", {
|
|
7434
|
+
enumerable: true,
|
|
7435
|
+
get: function() {
|
|
7436
|
+
return viteHostExpander;
|
|
7437
|
+
}
|
|
7438
|
+
});
|
|
7439
|
+
Object.defineProperty(exports, "viteLoadExpander", {
|
|
7440
|
+
enumerable: true,
|
|
7441
|
+
get: function() {
|
|
7442
|
+
return viteLoadExpander;
|
|
7443
|
+
}
|
|
7444
|
+
});
|
|
7445
|
+
Object.defineProperty(exports, "viteOutputTargets", {
|
|
7446
|
+
enumerable: true,
|
|
7447
|
+
get: function() {
|
|
7448
|
+
return viteOutputTargets;
|
|
5691
7449
|
}
|
|
5692
7450
|
});
|
|
5693
7451
|
Object.defineProperty(exports, "vocabularyWitnessDiagnostics", {
|
|
@@ -5702,3 +7460,33 @@ Object.defineProperty(exports, "walkPackageSources", {
|
|
|
5702
7460
|
return walkPackageSources;
|
|
5703
7461
|
}
|
|
5704
7462
|
});
|
|
7463
|
+
Object.defineProperty(exports, "webpackExtensionPolicy", {
|
|
7464
|
+
enumerable: true,
|
|
7465
|
+
get: function() {
|
|
7466
|
+
return webpackExtensionPolicy;
|
|
7467
|
+
}
|
|
7468
|
+
});
|
|
7469
|
+
Object.defineProperty(exports, "webpackHostExpander", {
|
|
7470
|
+
enumerable: true,
|
|
7471
|
+
get: function() {
|
|
7472
|
+
return webpackHostExpander;
|
|
7473
|
+
}
|
|
7474
|
+
});
|
|
7475
|
+
Object.defineProperty(exports, "webpackLoadExpander", {
|
|
7476
|
+
enumerable: true,
|
|
7477
|
+
get: function() {
|
|
7478
|
+
return webpackLoadExpander;
|
|
7479
|
+
}
|
|
7480
|
+
});
|
|
7481
|
+
Object.defineProperty(exports, "webpackOutputTargets", {
|
|
7482
|
+
enumerable: true,
|
|
7483
|
+
get: function() {
|
|
7484
|
+
return webpackOutputTargets;
|
|
7485
|
+
}
|
|
7486
|
+
});
|
|
7487
|
+
Object.defineProperty(exports, "writeAssetCopy", {
|
|
7488
|
+
enumerable: true,
|
|
7489
|
+
get: function() {
|
|
7490
|
+
return writeAssetCopy;
|
|
7491
|
+
}
|
|
7492
|
+
});
|