@animus-ui/extract 0.1.3 → 0.1.5
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 +14 -0
- package/dist/analyze-project-args.d.ts +6 -2
- package/dist/analyze-project-args.d.ts.map +1 -1
- package/dist/asset-placeholders.d.ts +29 -0
- package/dist/asset-placeholders.d.ts.map +1 -0
- package/dist/content-hash.d.ts +5 -3
- package/dist/content-hash.d.ts.map +1 -1
- package/dist/correlate-external-tokens.d.ts +46 -0
- package/dist/correlate-external-tokens.d.ts.map +1 -0
- package/dist/discover-packages.d.ts +32 -8
- package/dist/discover-packages.d.ts.map +1 -1
- package/dist/dynamic-prop-config.d.ts +21 -7
- package/dist/dynamic-prop-config.d.ts.map +1 -1
- package/dist/engine-adapter.d.ts +1 -1
- package/dist/engine-adapter.d.ts.map +1 -1
- package/dist/index.cjs +505 -38
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +506 -45
- package/dist/manifest-diagnostics.d.ts +3 -0
- package/dist/manifest-diagnostics.d.ts.map +1 -1
- package/dist/resolve-asset.d.ts +14 -0
- package/dist/resolve-asset.d.ts.map +1 -0
- package/dist/run-analysis.d.ts +2 -0
- package/dist/run-analysis.d.ts.map +1 -1
- package/dist/system-config.d.ts +5 -0
- package/dist/system-config.d.ts.map +1 -1
- package/dist/system-props-module.d.ts +4 -0
- package/dist/system-props-module.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
4
|
-
import { dirname, extname, isAbsolute, join, relative, resolve } from "path";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "fs";
|
|
4
|
+
import { dirname, extname, isAbsolute, join, relative, resolve, sep } from "path";
|
|
5
|
+
import { createRequire as createRequire$1 } from "module";
|
|
5
6
|
import browserslist from "browserslist";
|
|
6
7
|
import { browserslistToTargets, transform } from "lightningcss";
|
|
7
|
-
import {
|
|
8
|
-
import { realpathSync } from "node:fs";
|
|
8
|
+
import { isUnitlessProperty } from "@animus-ui/properties";
|
|
9
|
+
import { realpathSync as realpathSync$1 } from "node:fs";
|
|
9
10
|
import { basename, dirname as dirname$1, join as join$1, normalize } from "node:path";
|
|
10
11
|
//#region \0rolldown/runtime.js
|
|
11
12
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
@@ -101,7 +102,8 @@ function buildAnalyzeProjectArgs(inputs) {
|
|
|
101
102
|
inputs.pathAliasesJson,
|
|
102
103
|
inputs.keyframesJson,
|
|
103
104
|
inputs.staticCssJson,
|
|
104
|
-
inputs.conditionAliasesJson
|
|
105
|
+
inputs.conditionAliasesJson,
|
|
106
|
+
inputs.externalDirsJson
|
|
105
107
|
];
|
|
106
108
|
}
|
|
107
109
|
//#endregion
|
|
@@ -119,7 +121,7 @@ function createV2EngineApi(deps) {
|
|
|
119
121
|
const native = loadNativeEngine();
|
|
120
122
|
return {
|
|
121
123
|
loadSystemModule: (...args) => native.loadSystemModule(...args),
|
|
122
|
-
analyzeProject: (filesJsonRaw, scalesJson, variableMapJson, contextualVarsJson, propConfigJson, groupRegistryJson, packageResolutionJson, devMode, emitterConfigJson, selectorAliasesJson, _selectorOrderJson, globalStyleBlocksJson, pathAliasesJson, keyframesJson, staticCssJson, conditionAliasesJson) => {
|
|
124
|
+
analyzeProject: (filesJsonRaw, scalesJson, variableMapJson, contextualVarsJson, propConfigJson, groupRegistryJson, packageResolutionJson, devMode, emitterConfigJson, selectorAliasesJson, _selectorOrderJson, globalStyleBlocksJson, pathAliasesJson, keyframesJson, staticCssJson, conditionAliasesJson, externalDirsJson) => {
|
|
123
125
|
const filesJson = deps.rehydrateFilesJson ? deps.rehydrateFilesJson(filesJsonRaw) : filesJsonRaw;
|
|
124
126
|
const sent = /* @__PURE__ */ new Map();
|
|
125
127
|
for (const entry of JSON.parse(filesJson)) sent.set(entry.path, entry.source);
|
|
@@ -142,6 +144,7 @@ function createV2EngineApi(deps) {
|
|
|
142
144
|
packageResolutionJson: packageResolutionJson ?? void 0,
|
|
143
145
|
pathAliasesJson: pathAliasesJson ?? void 0,
|
|
144
146
|
staticCssJson: staticCssJson ?? void 0,
|
|
147
|
+
externalDirsJson: externalDirsJson ?? void 0,
|
|
145
148
|
devMode
|
|
146
149
|
};
|
|
147
150
|
const engine = new native.ExtractEngine(config);
|
|
@@ -200,8 +203,10 @@ function assertNoRetiredEngineSelection(engineOption) {
|
|
|
200
203
|
//#region pipeline/content-hash.ts
|
|
201
204
|
/**
|
|
202
205
|
* MD5 content hash used for file-change detection (HMR diffing) by both
|
|
203
|
-
* extraction plugins
|
|
204
|
-
* cache keys written by one
|
|
206
|
+
* extraction plugins, and for content-addressing copied asset bytes. The
|
|
207
|
+
* algorithm/encoding is a cross-plugin contract: cache keys written by one
|
|
208
|
+
* build path must compare equal in the next. Accepts a Buffer directly so
|
|
209
|
+
* binary sources hash without an intermediate string copy.
|
|
205
210
|
*/
|
|
206
211
|
function contentHash(source) {
|
|
207
212
|
return createHash("md5").update(source).digest("hex");
|
|
@@ -264,6 +269,14 @@ const PACKAGE_SRC_EXCLUDES = [
|
|
|
264
269
|
".test.",
|
|
265
270
|
".spec."
|
|
266
271
|
];
|
|
272
|
+
/** Exclusions for the compiled-output fallback when a package does not ship src/. */
|
|
273
|
+
const PACKAGE_OUTPUT_EXCLUDES = [
|
|
274
|
+
"node_modules",
|
|
275
|
+
".test.",
|
|
276
|
+
".spec.",
|
|
277
|
+
".d.ts",
|
|
278
|
+
".map"
|
|
279
|
+
];
|
|
267
280
|
const isFile = (path) => {
|
|
268
281
|
try {
|
|
269
282
|
return statSync(path).isFile();
|
|
@@ -285,6 +298,42 @@ function resolveAbsolutePathSpecifier(absSpecifier, extensionsSet) {
|
|
|
285
298
|
...Array.from(extensionsSet, (ext) => join(absSpecifier, `index${ext}`))
|
|
286
299
|
].find(isFile) ?? null;
|
|
287
300
|
}
|
|
301
|
+
/** The package-name half of a bare specifier (`@scope/name/sub` → `@scope/name`). */
|
|
302
|
+
function bareSpecifierPackageName(specifier) {
|
|
303
|
+
const segments = specifier.split("/");
|
|
304
|
+
return specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0];
|
|
305
|
+
}
|
|
306
|
+
function sourceEntryForSpecifier(specifier, srcDir, extensionsSet) {
|
|
307
|
+
if (isAbsolute(specifier)) {
|
|
308
|
+
const resolved = resolveAbsolutePathSpecifier(specifier, extensionsSet);
|
|
309
|
+
if (!resolved) return null;
|
|
310
|
+
return !relative(srcDir, resolved).startsWith("..") ? resolved : null;
|
|
311
|
+
}
|
|
312
|
+
const packageName = bareSpecifierPackageName(specifier);
|
|
313
|
+
return resolveAbsolutePathSpecifier(join(srcDir, specifier.slice(packageName.length + 1) || "index"), extensionsSet);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* The D13 dist-freshness check: applicable only when a specifier has BOTH a
|
|
317
|
+
* walked src/ tree and a resolved dist entry that exists on disk outside that
|
|
318
|
+
* tree; stale when the dist entry's mtime is older than the newest walked
|
|
319
|
+
* source file's. Not applicable (never stale) when the entry resolves inside
|
|
320
|
+
* src/ (no dist to skew), when the entry file is missing, or when no source
|
|
321
|
+
* file's mtime is readable. Detection only — reporting is the caller's policy.
|
|
322
|
+
*/
|
|
323
|
+
function distEntryIsStale(absEntry, srcDir, srcFiles) {
|
|
324
|
+
if (!relative(srcDir, absEntry).startsWith("..")) return false;
|
|
325
|
+
let distMtime;
|
|
326
|
+
try {
|
|
327
|
+
distMtime = statSync(absEntry).mtimeMs;
|
|
328
|
+
} catch {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
let newestSrcMtime = -Infinity;
|
|
332
|
+
for (const srcFile of srcFiles) try {
|
|
333
|
+
newestSrcMtime = Math.max(newestSrcMtime, statSync(srcFile).mtimeMs);
|
|
334
|
+
} catch {}
|
|
335
|
+
return distMtime < newestSrcMtime;
|
|
336
|
+
}
|
|
288
337
|
/**
|
|
289
338
|
* Shared external-package source collection (spec:
|
|
290
339
|
* external-package-file-discovery), consumed by both extraction plugins.
|
|
@@ -310,6 +359,8 @@ async function collectExternalPackageSources(opts) {
|
|
|
310
359
|
const packageMap = {};
|
|
311
360
|
const sourceEntries = /* @__PURE__ */ new Map();
|
|
312
361
|
const packageDirs = [];
|
|
362
|
+
const dirOwners = {};
|
|
363
|
+
const fileOwners = {};
|
|
313
364
|
const outcomes = [];
|
|
314
365
|
const alreadyIngested = (relPath) => hasEntry(relPath) || pushed.has(relPath);
|
|
315
366
|
for (const specifier of specifiers) {
|
|
@@ -330,17 +381,30 @@ async function collectExternalPackageSources(opts) {
|
|
|
330
381
|
}
|
|
331
382
|
const srcDir = join(findPackageRoot(absEntry), "src");
|
|
332
383
|
let fileCount = 0;
|
|
384
|
+
let staleDist = false;
|
|
333
385
|
if (existsSync(srcDir)) {
|
|
334
386
|
packageDirs.push(srcDir);
|
|
335
|
-
|
|
336
|
-
|
|
387
|
+
dirOwners[srcDir] ??= specifier;
|
|
388
|
+
const srcEntry = sourceEntryForSpecifier(specifier, srcDir, extensionsSet);
|
|
389
|
+
if (srcEntry) {
|
|
337
390
|
packageMap[specifier] = relative(rootDir, srcEntry);
|
|
338
391
|
sourceEntries.set(specifier, srcEntry);
|
|
339
392
|
} else packageMap[specifier] = relative(rootDir, absEntry);
|
|
393
|
+
if (!isAbsolute(specifier)) {
|
|
394
|
+
const packageName = bareSpecifierPackageName(specifier);
|
|
395
|
+
if (packageName !== specifier && !(packageName in packageMap)) {
|
|
396
|
+
const rootEntry = sourceEntryForSpecifier(packageName, srcDir, extensionsSet);
|
|
397
|
+
if (rootEntry) {
|
|
398
|
+
packageMap[packageName] = relative(rootDir, rootEntry);
|
|
399
|
+
sourceEntries.set(packageName, rootEntry);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
340
403
|
const pkgFiles = discoverFiles(srcDir, srcDir, [], extensionsSet).filter((absPath) => {
|
|
341
404
|
const inPkg = relative(srcDir, absPath);
|
|
342
405
|
return !PACKAGE_SRC_EXCLUDES.some((pattern) => inPkg.includes(pattern));
|
|
343
406
|
});
|
|
407
|
+
staleDist = distEntryIsStale(absEntry, srcDir, pkgFiles);
|
|
344
408
|
for (const pkgFile of pkgFiles) {
|
|
345
409
|
const relPath = relative(rootDir, pkgFile);
|
|
346
410
|
if (alreadyIngested(relPath)) {
|
|
@@ -361,28 +425,48 @@ async function collectExternalPackageSources(opts) {
|
|
|
361
425
|
source: processed.source
|
|
362
426
|
});
|
|
363
427
|
pushed.add(processed.relPath);
|
|
428
|
+
fileOwners[processed.relPath] ??= specifier;
|
|
364
429
|
fileCount++;
|
|
365
430
|
}
|
|
366
431
|
} else {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
432
|
+
const outputDir = dirname(absEntry);
|
|
433
|
+
packageDirs.push(outputDir);
|
|
434
|
+
dirOwners[outputDir] ??= specifier;
|
|
435
|
+
packageMap[specifier] = relative(rootDir, absEntry);
|
|
436
|
+
const outputExtensions = new Set(extensionsSet);
|
|
437
|
+
outputExtensions.add(extname(absEntry));
|
|
438
|
+
const outputFiles = discoverFiles(outputDir, outputDir, [], outputExtensions).filter((file) => {
|
|
439
|
+
const relToOutput = relative(outputDir, file);
|
|
440
|
+
return !PACKAGE_OUTPUT_EXCLUDES.some((pattern) => relToOutput.includes(pattern));
|
|
441
|
+
});
|
|
442
|
+
if (!outputFiles.includes(absEntry)) outputFiles.unshift(absEntry);
|
|
443
|
+
for (const outputFile of outputFiles) {
|
|
444
|
+
const outputRelPath = relative(rootDir, outputFile);
|
|
445
|
+
if (alreadyIngested(outputRelPath)) {
|
|
446
|
+
fileCount++;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
let source;
|
|
450
|
+
try {
|
|
451
|
+
source = readFileSync(outputFile, "utf-8");
|
|
452
|
+
} catch (err) {
|
|
453
|
+
onUnreadable(outputRelPath, err);
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
const processed = await preprocessFile(source, outputRelPath, outputFile);
|
|
457
|
+
if (!processed) continue;
|
|
373
458
|
entries.push({
|
|
374
|
-
path: relPath,
|
|
375
|
-
source
|
|
459
|
+
path: processed.relPath,
|
|
460
|
+
source: processed.source
|
|
376
461
|
});
|
|
377
|
-
pushed.add(relPath);
|
|
462
|
+
pushed.add(processed.relPath);
|
|
463
|
+
fileOwners[processed.relPath] ??= specifier;
|
|
378
464
|
fileCount++;
|
|
379
|
-
} catch (err) {
|
|
380
|
-
onUnreadable(relPath, err);
|
|
381
465
|
}
|
|
382
466
|
}
|
|
383
467
|
outcomes.push({
|
|
384
468
|
specifier,
|
|
385
|
-
outcome: fileCount > 0 ? "resolved" : "empty",
|
|
469
|
+
outcome: staleDist ? "stale-dist" : fileCount > 0 ? "resolved" : "empty",
|
|
386
470
|
fileCount
|
|
387
471
|
});
|
|
388
472
|
}
|
|
@@ -391,24 +475,33 @@ async function collectExternalPackageSources(opts) {
|
|
|
391
475
|
packageMap,
|
|
392
476
|
sourceEntries,
|
|
393
477
|
packageDirs,
|
|
478
|
+
dirOwners,
|
|
479
|
+
fileOwners,
|
|
394
480
|
outcomes
|
|
395
481
|
};
|
|
396
482
|
}
|
|
397
483
|
/**
|
|
398
|
-
* Extract external DS package names from
|
|
484
|
+
* Extract external DS package names from inheritance declarations in the
|
|
485
|
+
* system file.
|
|
399
486
|
*
|
|
400
|
-
* Supports
|
|
401
|
-
* - Primary
|
|
402
|
-
*
|
|
487
|
+
* Supports four forms:
|
|
488
|
+
* - Primary: `createSystem(...).extend(identifier)` chain calls
|
|
489
|
+
* (repeatable, mixable with `.from()` links; each call
|
|
490
|
+
* contributes one source; a library-bundle identifier
|
|
491
|
+
* traces its base import)
|
|
492
|
+
* - Deprecated chain: `createSystem(...).from(identifier)` chain calls
|
|
493
|
+
* - Deprecated alias: `createSystem({ includes: [identifier, ...] })`
|
|
494
|
+
* - Legacy: `.includes([identifier, ...])` chain method (RC
|
|
495
|
+
* migration fallback)
|
|
403
496
|
*
|
|
404
497
|
* For each identifier found, traces back to its import declaration and returns
|
|
405
498
|
* the import specifier: a bare specifier normalized to its package name, a
|
|
406
499
|
* relative specifier resolved against the system file's directory into an
|
|
407
500
|
* absolute path (so a sibling package referenced by path contributes discovery
|
|
408
|
-
* too). Only packages explicitly declared
|
|
409
|
-
* external DS dependencies.
|
|
501
|
+
* too). Only packages explicitly declared through one of these forms are
|
|
502
|
+
* treated as external DS dependencies.
|
|
410
503
|
*
|
|
411
|
-
* Falls back to empty array if no
|
|
504
|
+
* Falls back to empty array if no declaration is found.
|
|
412
505
|
*/
|
|
413
506
|
/**
|
|
414
507
|
* The message for the strict/warn gate over unresolvable includes, or null
|
|
@@ -421,6 +514,18 @@ function unresolvableIncludesMessage(outcomes) {
|
|
|
421
514
|
if (unresolvable.length === 0) return null;
|
|
422
515
|
return `[animus-extract] unresolvable include specifier(s): ${unresolvable.join(", ")}`;
|
|
423
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* The message for the strict/warn gate over stale dist entries
|
|
519
|
+
* (first-class-extension D13), or null when no declared specifier is stale.
|
|
520
|
+
* A stale dist silently skews merged registry content while discovery
|
|
521
|
+
* compiles the fresh sources, so it surfaces like an unresolvable specifier:
|
|
522
|
+
* non-strict consumers warn with this line, strict consumers throw it.
|
|
523
|
+
*/
|
|
524
|
+
function staleDistIncludesMessage(outcomes) {
|
|
525
|
+
const stale = outcomes.filter((record) => record.outcome === "stale-dist").map((record) => record.specifier);
|
|
526
|
+
if (stale.length === 0) return null;
|
|
527
|
+
return `[animus-extract] stale dist for include specifier(s): ${stale.join(", ")} — dist entry is older than the newest src/ file; rebuild the package(s) before extracting`;
|
|
528
|
+
}
|
|
424
529
|
function extractSystemFilePackages(systemFilePath) {
|
|
425
530
|
let source;
|
|
426
531
|
try {
|
|
@@ -443,6 +548,94 @@ function extractSystemFilePackages(systemFilePath) {
|
|
|
443
548
|
};
|
|
444
549
|
collectIdentifiers(constructorRegex);
|
|
445
550
|
collectIdentifiers(chainRegex);
|
|
551
|
+
const IDENT_START_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*/;
|
|
552
|
+
/** Position after any run of whitespace, line comments, block comments. */
|
|
553
|
+
const skipTrivia = (from) => {
|
|
554
|
+
let pos = from;
|
|
555
|
+
for (;;) {
|
|
556
|
+
while (pos < source.length && /\s/.test(source[pos])) pos++;
|
|
557
|
+
if (source.startsWith("//", pos)) {
|
|
558
|
+
const newline = source.indexOf("\n", pos);
|
|
559
|
+
pos = newline === -1 ? source.length : newline + 1;
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
if (source.startsWith("/*", pos)) {
|
|
563
|
+
const close = source.indexOf("*/", pos + 2);
|
|
564
|
+
pos = close === -1 ? source.length : close + 2;
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
return pos;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
/**
|
|
571
|
+
* Consume consecutive extend/from links starting at `from`, collecting
|
|
572
|
+
* each link's base identifier; tolerates trivia between tokens and a
|
|
573
|
+
* trailing comma in the argument list. Returns the position after the
|
|
574
|
+
* last consumed link (`from` itself when none matched).
|
|
575
|
+
*/
|
|
576
|
+
const consumeChainLinks = (from) => {
|
|
577
|
+
let pos = from;
|
|
578
|
+
for (;;) {
|
|
579
|
+
let cursor = skipTrivia(pos);
|
|
580
|
+
if (source[cursor] !== ".") return pos;
|
|
581
|
+
cursor = skipTrivia(cursor + 1);
|
|
582
|
+
const method = IDENT_START_RE.exec(source.slice(cursor))?.[0];
|
|
583
|
+
if (method !== "extend" && method !== "from") return pos;
|
|
584
|
+
cursor = skipTrivia(cursor + method.length);
|
|
585
|
+
if (source[cursor] !== "(") return pos;
|
|
586
|
+
cursor = skipTrivia(cursor + 1);
|
|
587
|
+
const base = IDENT_START_RE.exec(source.slice(cursor))?.[0];
|
|
588
|
+
if (!base) return pos;
|
|
589
|
+
cursor = skipTrivia(cursor + base.length);
|
|
590
|
+
while (source[cursor] === ".") {
|
|
591
|
+
const afterDot = skipTrivia(cursor + 1);
|
|
592
|
+
const segment = IDENT_START_RE.exec(source.slice(afterDot))?.[0];
|
|
593
|
+
if (!segment) break;
|
|
594
|
+
cursor = skipTrivia(afterDot + segment.length);
|
|
595
|
+
}
|
|
596
|
+
if (source[cursor] === ",") cursor = skipTrivia(cursor + 1);
|
|
597
|
+
if (source[cursor] !== ")") return pos;
|
|
598
|
+
identifiers.add(base);
|
|
599
|
+
pos = cursor + 1;
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
/** Identifier assigned directly before `index` (`const x = <here>`), if any. */
|
|
603
|
+
const boundIdentifierBefore = (index) => {
|
|
604
|
+
const match = /([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=\s*$/.exec(source.slice(0, index));
|
|
605
|
+
return match ? match[1] : null;
|
|
606
|
+
};
|
|
607
|
+
const chainRootIdentifiers = /* @__PURE__ */ new Set();
|
|
608
|
+
const createSystemAnchor = /createSystem\s*\(/g;
|
|
609
|
+
let anchorMatch;
|
|
610
|
+
while ((anchorMatch = createSystemAnchor.exec(source)) !== null) {
|
|
611
|
+
let pos = anchorMatch.index + anchorMatch[0].length;
|
|
612
|
+
let depth = 1;
|
|
613
|
+
while (pos < source.length && depth > 0) {
|
|
614
|
+
const ch = source[pos];
|
|
615
|
+
if (ch === "(") depth++;
|
|
616
|
+
else if (ch === ")") depth--;
|
|
617
|
+
pos++;
|
|
618
|
+
}
|
|
619
|
+
consumeChainLinks(pos);
|
|
620
|
+
const bound = boundIdentifierBefore(anchorMatch.index);
|
|
621
|
+
if (bound) chainRootIdentifiers.add(bound);
|
|
622
|
+
}
|
|
623
|
+
const scannedRoots = /* @__PURE__ */ new Set();
|
|
624
|
+
for (;;) {
|
|
625
|
+
const pendingRoots = [...chainRootIdentifiers].filter((root) => !scannedRoots.has(root));
|
|
626
|
+
if (pendingRoots.length === 0) break;
|
|
627
|
+
for (const root of pendingRoots) {
|
|
628
|
+
scannedRoots.add(root);
|
|
629
|
+
const rootUse = new RegExp(`(?<![a-zA-Z0-9_$])${root.replace(/\$/g, "\\$")}(?![a-zA-Z0-9_$])`, "g");
|
|
630
|
+
let useMatch;
|
|
631
|
+
while ((useMatch = rootUse.exec(source)) !== null) {
|
|
632
|
+
const afterIdentifier = useMatch.index + useMatch[0].length;
|
|
633
|
+
if (consumeChainLinks(afterIdentifier) === afterIdentifier) continue;
|
|
634
|
+
const bound = boundIdentifierBefore(useMatch.index);
|
|
635
|
+
if (bound) chainRootIdentifiers.add(bound);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
446
639
|
if (identifiers.size === 0) return [];
|
|
447
640
|
const importMap = /* @__PURE__ */ new Map();
|
|
448
641
|
const importRegex = /^\s*import\s+(?:([a-zA-Z_$][a-zA-Z0-9_$]*)\s*,\s*)?(?:\{([^}]*)\}|([a-zA-Z_$][a-zA-Z0-9_$]*))\s+from\s+['"]([^'"]+)['"]/gm;
|
|
@@ -463,14 +656,265 @@ function extractSystemFilePackages(systemFilePath) {
|
|
|
463
656
|
const specifier = importMap.get(id);
|
|
464
657
|
if (!specifier) continue;
|
|
465
658
|
if (specifier.startsWith(".")) packages.add(resolve(systemFileDir, specifier));
|
|
466
|
-
else
|
|
467
|
-
const pkgName = specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0];
|
|
468
|
-
packages.add(pkgName);
|
|
469
|
-
}
|
|
659
|
+
else packages.add(specifier);
|
|
470
660
|
}
|
|
471
661
|
return Array.from(packages);
|
|
472
662
|
}
|
|
473
663
|
//#endregion
|
|
664
|
+
//#region pipeline/asset-placeholders.ts
|
|
665
|
+
/**
|
|
666
|
+
* Host-side handling of `asset()` placeholders (global-styles-system):
|
|
667
|
+
* `animus-asset:<specifier>` markers ride through the sandbox and the
|
|
668
|
+
* emitter byte-exact; each HOST plugin substitutes them with its bundler's
|
|
669
|
+
* resolved asset URL after extraction. This module owns the shared scanning
|
|
670
|
+
* and replacement mechanics — resolution and strict gating stay at the
|
|
671
|
+
* plugin call sites.
|
|
672
|
+
*/
|
|
673
|
+
/** Mirrors the producer-side constant in `@animus-ui/system`'s `asset.ts`
|
|
674
|
+
* (extract must not take a runtime dependency on system); the pairing is
|
|
675
|
+
* pinned by a contract test in `tests/asset-placeholders.test.ts`. */
|
|
676
|
+
const ASSET_PLACEHOLDER_PREFIX = "animus-asset:";
|
|
677
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
678
|
+
const PREFIX_RE = escapeRegExp(ASSET_PLACEHOLDER_PREFIX);
|
|
679
|
+
/**
|
|
680
|
+
* Quoted `url('animus-asset:<specifier>')` form — the emitter always quotes
|
|
681
|
+
* `url()` values, so a quoted match carries the FULL specifier, including
|
|
682
|
+
* whitespace and parentheses (D5 pins the placeholder as specifier-verbatim,
|
|
683
|
+
* so scanning fidelity is the only place such characters can be honored).
|
|
684
|
+
*/
|
|
685
|
+
const QUOTED_PLACEHOLDER_RE = new RegExp(`(['"])${PREFIX_RE}([^'"]*?)\\1`, "g");
|
|
686
|
+
/** Bare-form fallback: a placeholder up to CSS url()/quote/whitespace. */
|
|
687
|
+
const BARE_PLACEHOLDER_RE = new RegExp(`${PREFIX_RE}([^'")\\s]+)`, "g");
|
|
688
|
+
/** Unique asset specifiers referenced by placeholders, in appearance order. */
|
|
689
|
+
function findAssetSpecifiers(css) {
|
|
690
|
+
if (!css.includes("animus-asset:")) return [];
|
|
691
|
+
const seen = /* @__PURE__ */ new Set();
|
|
692
|
+
const remainder = css.replace(QUOTED_PLACEHOLDER_RE, (_match, _quote, specifier) => {
|
|
693
|
+
seen.add(specifier);
|
|
694
|
+
return "";
|
|
695
|
+
});
|
|
696
|
+
for (const match of remainder.matchAll(BARE_PLACEHOLDER_RE)) seen.add(match[1]);
|
|
697
|
+
return [...seen];
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Replace each specifier's placeholder with its substitution. Specifiers
|
|
701
|
+
* absent from the map keep their placeholder — the caller decides whether
|
|
702
|
+
* that is a strict failure or a warn-and-emit-literally. A substitution may
|
|
703
|
+
* itself be a bundler marker (e.g. Vite's `__VITE_ASSET__<ref>__`) that the
|
|
704
|
+
* host's own asset pipeline resolves to a hashed file name later.
|
|
705
|
+
*
|
|
706
|
+
* Each replacement is anchored to a following delimiter (quote, `)`,
|
|
707
|
+
* whitespace, or end of input) so a specifier that textually prefixes a
|
|
708
|
+
* longer one can never clobber the longer placeholder; longest-first
|
|
709
|
+
* ordering additionally lets the longer of two mapped specifiers claim its
|
|
710
|
+
* occurrences before the shorter runs.
|
|
711
|
+
*/
|
|
712
|
+
function substituteAssetPlaceholders(css, urlBySpecifier) {
|
|
713
|
+
if (urlBySpecifier.size === 0) return css;
|
|
714
|
+
if (!css.includes("animus-asset:")) return css;
|
|
715
|
+
const specifiers = [...urlBySpecifier.keys()].sort((a, b) => b.length - a.length);
|
|
716
|
+
let out = css;
|
|
717
|
+
for (const specifier of specifiers) {
|
|
718
|
+
const placeholder = new RegExp(escapeRegExp(ASSET_PLACEHOLDER_PREFIX + specifier) + String.raw`(?=['")\s]|$)`, "g");
|
|
719
|
+
out = out.replace(placeholder, () => urlBySpecifier.get(specifier));
|
|
720
|
+
}
|
|
721
|
+
return out;
|
|
722
|
+
}
|
|
723
|
+
//#endregion
|
|
724
|
+
//#region pipeline/resolve-asset.ts
|
|
725
|
+
/**
|
|
726
|
+
* Node-side asset specifier resolution shared by the host plugins (the
|
|
727
|
+
* asset() contract, global-styles-system): host path aliases apply FIRST —
|
|
728
|
+
* an alias such as `@fonts` works in application modules, so
|
|
729
|
+
* `asset('@fonts/inter.woff2')` must resolve identically — then direct Node
|
|
730
|
+
* resolution, then the package-root fallback (exports maps rarely list
|
|
731
|
+
* asset subpaths). Bundler-native resolution (Vite's `this.resolve`) is
|
|
732
|
+
* still preferred where available; this resolver covers the paths that have
|
|
733
|
+
* no bundler hook (Next's session, Vite's dev re-analysis).
|
|
734
|
+
*/
|
|
735
|
+
const requireByRoot = /* @__PURE__ */ new Map();
|
|
736
|
+
function requireAnchoredAt(rootDir) {
|
|
737
|
+
let req = requireByRoot.get(rootDir);
|
|
738
|
+
if (!req) {
|
|
739
|
+
req = createRequire$1(join(rootDir, "package.json"));
|
|
740
|
+
requireByRoot.set(rootDir, req);
|
|
741
|
+
}
|
|
742
|
+
return req;
|
|
743
|
+
}
|
|
744
|
+
function packageRootFromEntry(entry) {
|
|
745
|
+
let current = dirname(entry);
|
|
746
|
+
while (true) {
|
|
747
|
+
if (existsSync(join(current, "package.json"))) return current;
|
|
748
|
+
const parent = dirname(current);
|
|
749
|
+
if (parent === current) return null;
|
|
750
|
+
current = parent;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
const aliasTableCache = /* @__PURE__ */ new Map();
|
|
754
|
+
function parseAliasTable(pathAliasesJson) {
|
|
755
|
+
const cached = aliasTableCache.get(pathAliasesJson);
|
|
756
|
+
if (cached) return cached;
|
|
757
|
+
let aliases;
|
|
758
|
+
try {
|
|
759
|
+
aliases = JSON.parse(pathAliasesJson).aliases ?? [];
|
|
760
|
+
} catch {
|
|
761
|
+
aliases = [];
|
|
762
|
+
}
|
|
763
|
+
aliasTableCache.set(pathAliasesJson, aliases);
|
|
764
|
+
return aliases;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Map a specifier through the harvested host alias table (the same
|
|
768
|
+
* `pathAliasesJson` wire the engine consumes — entries pre-sorted longest
|
|
769
|
+
* pattern first by `buildPathAliasesJson`). Returns an absolute path to an
|
|
770
|
+
* EXISTING file, or null when no alias claims the specifier.
|
|
771
|
+
*/
|
|
772
|
+
function resolveThroughPathAliases(specifier, rootDir, pathAliasesJson) {
|
|
773
|
+
if (!pathAliasesJson) return null;
|
|
774
|
+
const aliases = parseAliasTable(pathAliasesJson);
|
|
775
|
+
for (const alias of aliases) {
|
|
776
|
+
let mapped = null;
|
|
777
|
+
if (alias.type === "exact") {
|
|
778
|
+
if (alias.pattern === specifier) mapped = alias.replacement;
|
|
779
|
+
} else if (specifier.startsWith(alias.pattern)) mapped = alias.replacement + specifier.slice(alias.pattern.length);
|
|
780
|
+
if (mapped === null) continue;
|
|
781
|
+
const absolute = isAbsolute(mapped) ? mapped : join(rootDir, mapped);
|
|
782
|
+
if (existsSync(absolute)) return absolute;
|
|
783
|
+
}
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Resolve an asset specifier to an absolute file: host aliases, then direct
|
|
788
|
+
* Node resolution anchored at `rootDir`, then the package-root fallback.
|
|
789
|
+
* Returns null when nothing matches — strict gating stays at the caller.
|
|
790
|
+
*/
|
|
791
|
+
function resolveAssetFile(specifier, rootDir, pathAliasesJson) {
|
|
792
|
+
const aliased = resolveThroughPathAliases(specifier, rootDir, pathAliasesJson);
|
|
793
|
+
if (aliased) return aliased;
|
|
794
|
+
const requireFromRoot = requireAnchoredAt(rootDir);
|
|
795
|
+
try {
|
|
796
|
+
return requireFromRoot.resolve(specifier);
|
|
797
|
+
} catch {}
|
|
798
|
+
const segments = specifier.split("/");
|
|
799
|
+
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0];
|
|
800
|
+
const subpath = specifier.slice(packageName.length + 1);
|
|
801
|
+
if (!subpath) return null;
|
|
802
|
+
for (const modulesDir of requireFromRoot.resolve.paths(packageName) ?? []) {
|
|
803
|
+
const packageRoot = join(modulesDir, packageName);
|
|
804
|
+
if (!existsSync(join(packageRoot, "package.json"))) continue;
|
|
805
|
+
const candidate = join(packageRoot, subpath);
|
|
806
|
+
if (existsSync(candidate)) return candidate;
|
|
807
|
+
}
|
|
808
|
+
try {
|
|
809
|
+
const packageRoot = packageRootFromEntry(requireFromRoot.resolve(packageName));
|
|
810
|
+
if (!packageRoot) return null;
|
|
811
|
+
const candidate = join(packageRoot, subpath);
|
|
812
|
+
return existsSync(candidate) ? candidate : null;
|
|
813
|
+
} catch {
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
//#endregion
|
|
818
|
+
//#region pipeline/correlate-external-tokens.ts
|
|
819
|
+
/**
|
|
820
|
+
* Index the loader-captured theme manifests by owning specifier. Module paths
|
|
821
|
+
* are canonical absolute paths (symlinks resolved), so each package dir is
|
|
822
|
+
* realpath'd before prefix-matching; a module outside every known package dir
|
|
823
|
+
* (typically the consumer's own theme) contributes nothing.
|
|
824
|
+
*/
|
|
825
|
+
function buildSourceTokenIndex(opts) {
|
|
826
|
+
const index = /* @__PURE__ */ new Map();
|
|
827
|
+
if (!opts.sourceThemeManifestsJson) return index;
|
|
828
|
+
let manifests;
|
|
829
|
+
try {
|
|
830
|
+
manifests = JSON.parse(opts.sourceThemeManifestsJson);
|
|
831
|
+
} catch {
|
|
832
|
+
return index;
|
|
833
|
+
}
|
|
834
|
+
const realDirOwners = [];
|
|
835
|
+
const addOwnerDir = (dir, specifier) => {
|
|
836
|
+
if (!realDirOwners.some((entry) => entry.dir === dir)) realDirOwners.push({
|
|
837
|
+
dir,
|
|
838
|
+
specifier
|
|
839
|
+
});
|
|
840
|
+
};
|
|
841
|
+
for (const [dir, specifier] of Object.entries(opts.dirOwners)) {
|
|
842
|
+
let real = dir;
|
|
843
|
+
try {
|
|
844
|
+
real = realpathSync(dir);
|
|
845
|
+
} catch {}
|
|
846
|
+
addOwnerDir(real, specifier);
|
|
847
|
+
let packageRoot = real;
|
|
848
|
+
while (packageRoot !== dirname(packageRoot) && !existsSync(join(packageRoot, "package.json"))) packageRoot = dirname(packageRoot);
|
|
849
|
+
if (existsSync(join(packageRoot, "package.json"))) addOwnerDir(packageRoot, specifier);
|
|
850
|
+
}
|
|
851
|
+
for (const [modulePath, exports] of Object.entries(manifests)) {
|
|
852
|
+
const owner = realDirOwners.find(({ dir }) => modulePath === dir || modulePath.startsWith(dir + sep));
|
|
853
|
+
if (!owner) continue;
|
|
854
|
+
let tokens = index.get(owner.specifier);
|
|
855
|
+
if (!tokens) {
|
|
856
|
+
tokens = /* @__PURE__ */ new Set();
|
|
857
|
+
index.set(owner.specifier, tokens);
|
|
858
|
+
}
|
|
859
|
+
for (const paths of Object.values(exports)) for (const token of paths) tokens.add(token);
|
|
860
|
+
}
|
|
861
|
+
return index;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* The correlation join. Returns one teaching-error message per distinct
|
|
865
|
+
* (component, token, specifier) whose file belongs to a discovered source AND
|
|
866
|
+
* whose token that source's manifest defines. The messages follow the
|
|
867
|
+
* standard severity routing at the CALLER (throw under `strict`, warn
|
|
868
|
+
* otherwise) — this join never reports on its own.
|
|
869
|
+
*/
|
|
870
|
+
function correlateExternalTokenDiagnostics(opts) {
|
|
871
|
+
const messages = [];
|
|
872
|
+
const seen = /* @__PURE__ */ new Set();
|
|
873
|
+
for (const diagnostic of opts.diagnostics ?? []) {
|
|
874
|
+
if (diagnostic.kind !== "external-token-candidate" || !diagnostic.token) continue;
|
|
875
|
+
const specifier = opts.fileOwners[diagnostic.file];
|
|
876
|
+
if (!specifier) continue;
|
|
877
|
+
if (!opts.sourceTokens.get(specifier)?.has(diagnostic.token)) continue;
|
|
878
|
+
const key = `${diagnostic.component}\u0000${diagnostic.token}\u0000${specifier}`;
|
|
879
|
+
if (seen.has(key)) continue;
|
|
880
|
+
seen.add(key);
|
|
881
|
+
messages.push(`${diagnostic.component} (from '${specifier}') references token '${diagnostic.token}', which the consumer theme does not define — inherit the source's tokens with createTheme().extend(...) using the tokens (or bundle) export of '${specifier}'`);
|
|
882
|
+
}
|
|
883
|
+
return messages;
|
|
884
|
+
}
|
|
885
|
+
const indexCache = /* @__PURE__ */ new WeakMap();
|
|
886
|
+
/**
|
|
887
|
+
* The complete cross-source token-contract gate both plugins share
|
|
888
|
+
* (extraction-diagnostics): index the loader-captured source manifests,
|
|
889
|
+
* join them against the engine's candidates, and route the resulting
|
|
890
|
+
* teaching errors — throw under `strict`, warn otherwise. One entry point
|
|
891
|
+
* so the two hosts cannot drift on wiring or severity semantics.
|
|
892
|
+
*/
|
|
893
|
+
function enforceExternalTokenContracts(opts) {
|
|
894
|
+
const manifestsJson = opts.sourceThemeManifestsJson ?? "";
|
|
895
|
+
const cached = indexCache.get(opts.dirOwners);
|
|
896
|
+
let sourceTokens;
|
|
897
|
+
if (cached && cached.manifestsJson === manifestsJson) sourceTokens = cached.index;
|
|
898
|
+
else {
|
|
899
|
+
sourceTokens = buildSourceTokenIndex({
|
|
900
|
+
sourceThemeManifestsJson: opts.sourceThemeManifestsJson,
|
|
901
|
+
dirOwners: opts.dirOwners
|
|
902
|
+
});
|
|
903
|
+
indexCache.set(opts.dirOwners, {
|
|
904
|
+
manifestsJson,
|
|
905
|
+
index: sourceTokens
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
const messages = correlateExternalTokenDiagnostics({
|
|
909
|
+
diagnostics: opts.diagnostics,
|
|
910
|
+
fileOwners: opts.fileOwners,
|
|
911
|
+
sourceTokens
|
|
912
|
+
});
|
|
913
|
+
if (messages.length === 0) return;
|
|
914
|
+
if (opts.strict) throw new Error(`${opts.prefix} ${messages.join("\n")}`);
|
|
915
|
+
for (const message of messages) opts.warn(message);
|
|
916
|
+
}
|
|
917
|
+
//#endregion
|
|
474
918
|
//#region pipeline/path-aliases.ts
|
|
475
919
|
/**
|
|
476
920
|
* Normalize alias pairs: strip a `rootDir` prefix from targets, classify
|
|
@@ -564,7 +1008,7 @@ function surfaceManifestDiagnostics(manifest, warn) {
|
|
|
564
1008
|
*/
|
|
565
1009
|
function applyUnitFallback(css) {
|
|
566
1010
|
return css.replace(/([a-z-]+)\s*:\s*([^;{}]+);/g, (match, prop, value) => {
|
|
567
|
-
if (
|
|
1011
|
+
if (isUnitlessProperty(prop)) return match;
|
|
568
1012
|
let depth = 0;
|
|
569
1013
|
let fixed = "";
|
|
570
1014
|
let i = 0;
|
|
@@ -623,9 +1067,15 @@ function buildAnalysisInputs(opts) {
|
|
|
623
1067
|
pathAliasesJson: opts.pathAliasesJson,
|
|
624
1068
|
keyframesJson: opts.system.keyframesJson,
|
|
625
1069
|
staticCssJson: opts.staticCssJson ?? null,
|
|
626
|
-
conditionAliasesJson: opts.system.conditionAliasesJson ?? null
|
|
1070
|
+
conditionAliasesJson: opts.system.conditionAliasesJson ?? null,
|
|
1071
|
+
externalDirsJson: opts.externalDirs?.length && hasSourceThemeManifests(opts.system) ? JSON.stringify(opts.externalDirs) : null
|
|
627
1072
|
};
|
|
628
1073
|
}
|
|
1074
|
+
/** Whether the loader captured at least one source built-theme manifest. */
|
|
1075
|
+
function hasSourceThemeManifests(system) {
|
|
1076
|
+
const json = system.sourceThemeManifestsJson;
|
|
1077
|
+
return typeof json === "string" && json.length > 0 && json !== "{}";
|
|
1078
|
+
}
|
|
629
1079
|
/**
|
|
630
1080
|
* The one analysis invocation both plugins share: build the emitter
|
|
631
1081
|
* config, serialize inputs, call the NAPI `analyzeProject`, parse the
|
|
@@ -758,19 +1208,26 @@ function loadSystemConfig(engineApi, opts) {
|
|
|
758
1208
|
conditionAliasesJson: config.conditionAliases || null,
|
|
759
1209
|
globalStyleBlocksJson: config.globalStyleBlocks || null,
|
|
760
1210
|
keyframesJson: config.keyframesBlocks || null,
|
|
761
|
-
dependencies: config.dependencies ?? []
|
|
1211
|
+
dependencies: config.dependencies ?? [],
|
|
1212
|
+
sourceThemeManifestsJson: config.sourceThemeManifests || null
|
|
762
1213
|
};
|
|
763
1214
|
}
|
|
764
1215
|
//#endregion
|
|
765
1216
|
//#region pipeline/dynamic-prop-config.ts
|
|
766
1217
|
function buildDynamicPropConfig(dynamicProps) {
|
|
767
1218
|
const configEntries = {};
|
|
768
|
-
for (const [propName, meta] of Object.entries(dynamicProps))
|
|
769
|
-
varName: meta.
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
1219
|
+
for (const [propName, meta] of Object.entries(dynamicProps)) {
|
|
1220
|
+
if (!meta.varName || !meta.slotClass) throw new Error(`buildDynamicPropConfig: dynamic prop '${propName}' carries no slot metadata — expected varName and slotClass, got keys [${Object.keys(meta).join(", ")}].`);
|
|
1221
|
+
const entry = {
|
|
1222
|
+
varName: meta.varName,
|
|
1223
|
+
slotClass: meta.slotClass
|
|
1224
|
+
};
|
|
1225
|
+
if (meta.property) entry.property = meta.property;
|
|
1226
|
+
if (meta.properties && meta.properties.length > 0) entry.properties = meta.properties;
|
|
1227
|
+
if (meta.transformName) entry.transformName = meta.transformName;
|
|
1228
|
+
if (meta.scaleValues && Object.keys(meta.scaleValues).length > 0) entry.scaleValues = meta.scaleValues;
|
|
1229
|
+
configEntries[propName] = entry;
|
|
1230
|
+
}
|
|
774
1231
|
return configEntries;
|
|
775
1232
|
}
|
|
776
1233
|
//#endregion
|
|
@@ -784,6 +1241,10 @@ function buildDynamicPropConfig(dynamicProps) {
|
|
|
784
1241
|
* Runtime transform functions for dynamic props are not yet supported
|
|
785
1242
|
* (transforms are resolved at extraction time via boa_engine in Rust), so
|
|
786
1243
|
* `transforms` defaults to an empty object literal.
|
|
1244
|
+
*
|
|
1245
|
+
* `dynamicPropConfig` entries carry the CSS property the slot class declares
|
|
1246
|
+
* — the runtime's unit-fallback decision. Their field order and omission
|
|
1247
|
+
* rules belong to buildDynamicPropConfig.
|
|
787
1248
|
*/
|
|
788
1249
|
function buildSystemPropsModule(opts) {
|
|
789
1250
|
const dynamicPropConfig = buildDynamicPropConfig(opts.dynamicProps);
|
|
@@ -1083,7 +1544,7 @@ function toWatchKeys(input) {
|
|
|
1083
1544
|
*/
|
|
1084
1545
|
function realpathThroughNearestExistingAncestor(path) {
|
|
1085
1546
|
try {
|
|
1086
|
-
return realpathSync(path);
|
|
1547
|
+
return realpathSync$1(path);
|
|
1087
1548
|
} catch {}
|
|
1088
1549
|
const suffix = [];
|
|
1089
1550
|
let current = path;
|
|
@@ -1093,9 +1554,9 @@ function realpathThroughNearestExistingAncestor(path) {
|
|
|
1093
1554
|
suffix.unshift(basename(current));
|
|
1094
1555
|
current = parent;
|
|
1095
1556
|
try {
|
|
1096
|
-
return join$1(realpathSync(current), ...suffix);
|
|
1557
|
+
return join$1(realpathSync$1(current), ...suffix);
|
|
1097
1558
|
} catch {}
|
|
1098
1559
|
}
|
|
1099
1560
|
}
|
|
1100
1561
|
//#endregion
|
|
1101
|
-
export { ANIMUS_LAYERS, DEFAULT_EXTENSIONS, RETIRED_ENGINE_MESSAGE, applyPrefix, applyUnitFallback, assembleStylesheet, assertNoRetiredEngineSelection, buildAnalysisInputs, buildAnalyzeProjectArgs, buildDynamicPropConfig, buildPathAliasesJson, buildSystemPropsModule, camelToKebab, clearEngineCache, collectExternalPackageSources, contentHash, createV2EngineApi, discoverFiles, extractSystemFilePackages, findPackageRoot, formatRustTimingWaterfall, loadSystemConfig, postProcessCss, preprocessMdx, readTsconfigAliasPairs, resolveLightningTargets, runProjectAnalysis, serializeStaticCss, stripLeadingLayerDeclaration, surfaceManifestDiagnostics, toWatchKeys, unresolvableIncludesMessage, validateLayerOrder };
|
|
1562
|
+
export { ANIMUS_LAYERS, DEFAULT_EXTENSIONS, RETIRED_ENGINE_MESSAGE, applyPrefix, applyUnitFallback, assembleStylesheet, assertNoRetiredEngineSelection, buildAnalysisInputs, buildAnalyzeProjectArgs, buildDynamicPropConfig, buildPathAliasesJson, buildSystemPropsModule, camelToKebab, clearEngineCache, collectExternalPackageSources, contentHash, createV2EngineApi, discoverFiles, enforceExternalTokenContracts, extractSystemFilePackages, findAssetSpecifiers, findPackageRoot, formatRustTimingWaterfall, loadSystemConfig, postProcessCss, preprocessMdx, readTsconfigAliasPairs, resolveAssetFile, resolveLightningTargets, resolveThroughPathAliases, runProjectAnalysis, serializeStaticCss, staleDistIncludesMessage, stripLeadingLayerDeclaration, substituteAssetPlaceholders, surfaceManifestDiagnostics, toWatchKeys, unresolvableIncludesMessage, validateLayerOrder };
|