@navecss/core 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -9
- package/dist/bin.js +3 -3
- package/dist/{chunk-63H2FLGU.js → chunk-B5CWZIBK.js} +1 -1
- package/dist/{chunk-BCUK4M4P.js → chunk-EYMFWE3A.js} +1866 -56
- package/dist/{chunk-MWHZ26S4.js → chunk-KDLLTOAM.js} +6 -34
- package/dist/{chunk-KKUYU75D.js → chunk-R6R5DSTT.js} +1 -1
- package/dist/collect.d.ts +309 -13
- package/dist/collect.js +37 -1
- package/dist/lightningcss.js +3 -3
- package/dist/postcss.js +2 -2
- package/dist/vite.js +109 -914
- package/package.json +11 -12
- package/skills/navecss/SKILL.md +1 -1
|
@@ -383,6 +383,171 @@ function isImportingCx(program, sources) {
|
|
|
383
383
|
});
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
// src/vite-cx-member.ts
|
|
387
|
+
var READ_MEMBERS = /* @__PURE__ */ new Set(["dynamic", "raw"]);
|
|
388
|
+
var CALL_MEMBERS = /* @__PURE__ */ new Set(["apply", "call"]);
|
|
389
|
+
var LEFT_TARGETS = /* @__PURE__ */ new Set([
|
|
390
|
+
"AssignmentExpression",
|
|
391
|
+
"AssignmentPattern",
|
|
392
|
+
"ForInStatement",
|
|
393
|
+
"ForOfStatement"
|
|
394
|
+
]);
|
|
395
|
+
var WHOLE_TARGETS = /* @__PURE__ */ new Set([
|
|
396
|
+
"ArrayPattern",
|
|
397
|
+
"RestElement",
|
|
398
|
+
"UpdateExpression"
|
|
399
|
+
]);
|
|
400
|
+
function unwrapped(analysis, node) {
|
|
401
|
+
let current = node;
|
|
402
|
+
for (; ; ) {
|
|
403
|
+
const parent = analysis.parentOf.get(current);
|
|
404
|
+
if (!parent || wrappedBy(parent) !== current) return current;
|
|
405
|
+
current = parent;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function isMemberWrite(analysis, member) {
|
|
409
|
+
const top = unwrapped(analysis, member);
|
|
410
|
+
const parent = analysis.parentOf.get(top);
|
|
411
|
+
if (!parent) return false;
|
|
412
|
+
if (LEFT_TARGETS.has(parent.type)) return nodeAt(parent, "left") === top;
|
|
413
|
+
if (WHOLE_TARGETS.has(parent.type)) return true;
|
|
414
|
+
if (parent.type === "UnaryExpression") return parent.operator === "delete";
|
|
415
|
+
return parent.type === "Property" && nodeAt(parent, "value") === top && analysis.parentOf.get(parent)?.type === "ObjectPattern";
|
|
416
|
+
}
|
|
417
|
+
function isCallee(analysis, member) {
|
|
418
|
+
const top = unwrapped(analysis, member);
|
|
419
|
+
const parent = analysis.parentOf.get(top);
|
|
420
|
+
return parent?.type === "CallExpression" && nodeAt(parent, "callee") === top;
|
|
421
|
+
}
|
|
422
|
+
function memberRoleOf(analysis, member) {
|
|
423
|
+
if (member.computed === true || isMemberWrite(analysis, member)) return "unknown";
|
|
424
|
+
const name = propertyNameOf(nodeAt(member, "property"), false);
|
|
425
|
+
if (name !== void 0 && READ_MEMBERS.has(name)) return "read";
|
|
426
|
+
if (name === void 0 || !CALL_MEMBERS.has(name)) return "unknown";
|
|
427
|
+
return isCallee(analysis, member) ? "call" : "read";
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/vite-cx-flow.ts
|
|
431
|
+
var CALLED = { kind: "called" };
|
|
432
|
+
var SAFE = { kind: "safe" };
|
|
433
|
+
var UNBOUND = { kind: "unbound" };
|
|
434
|
+
var HARMLESS_PARENTS = /* @__PURE__ */ new Set(["ExpressionStatement", "UnaryExpression"]);
|
|
435
|
+
var TESTING_PARENTS = /* @__PURE__ */ new Set([
|
|
436
|
+
"ConditionalExpression",
|
|
437
|
+
"DoWhileStatement",
|
|
438
|
+
"ForStatement",
|
|
439
|
+
"IfStatement",
|
|
440
|
+
"WhileStatement"
|
|
441
|
+
]);
|
|
442
|
+
function ownExportOf(analysis, declarator) {
|
|
443
|
+
const declaration = analysis.parentOf.get(declarator);
|
|
444
|
+
const statement = declaration && analysis.parentOf.get(declaration);
|
|
445
|
+
if (statement?.type !== "ExportNamedDeclaration") return void 0;
|
|
446
|
+
const id = nodeAt(declarator, "id");
|
|
447
|
+
return id ? exportNameOf(id) : void 0;
|
|
448
|
+
}
|
|
449
|
+
function isMemberPattern(pattern) {
|
|
450
|
+
if (pattern.type !== "ObjectPattern") return false;
|
|
451
|
+
return nodesAt(pattern, "properties").every((property) => {
|
|
452
|
+
if (property.type !== "Property") return false;
|
|
453
|
+
if (property.computed === true) return false;
|
|
454
|
+
const name = propertyNameOf(nodeAt(property, "key"), false);
|
|
455
|
+
return name !== void 0 && READ_MEMBERS.has(name);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
function declaredStep(analysis, declarator) {
|
|
459
|
+
const id = nodeAt(declarator, "id");
|
|
460
|
+
if (id?.type === "Identifier") {
|
|
461
|
+
const exportedAs = ownExportOf(analysis, declarator);
|
|
462
|
+
return { kind: "aliased", id, ...exportedAs !== void 0 && { exportedAs } };
|
|
463
|
+
}
|
|
464
|
+
return id && isMemberPattern(id) ? SAFE : UNBOUND;
|
|
465
|
+
}
|
|
466
|
+
function memberStep(analysis, node) {
|
|
467
|
+
const role = memberRoleOf(analysis, node);
|
|
468
|
+
if (role === "call") return CALLED;
|
|
469
|
+
return role === "read" ? SAFE : UNBOUND;
|
|
470
|
+
}
|
|
471
|
+
function exportStep(parent) {
|
|
472
|
+
if (parent.type === "ExportDefaultDeclaration") return { kind: "exported", name: "default" };
|
|
473
|
+
const name = exportNameOf(nodeAt(parent, "exported"));
|
|
474
|
+
return name === void 0 ? UNBOUND : { kind: "exported", name };
|
|
475
|
+
}
|
|
476
|
+
function isHarmlessOperation(analysis, top, parent) {
|
|
477
|
+
if (parent.type === "BinaryExpression") {
|
|
478
|
+
return !(parent.operator === "instanceof" && nodeAt(parent, "left") === top);
|
|
479
|
+
}
|
|
480
|
+
const tag = analysis.parentOf.get(parent);
|
|
481
|
+
return !(tag?.type === "TaggedTemplateExpression" && nodeAt(tag, "quasi") === parent);
|
|
482
|
+
}
|
|
483
|
+
function readingStep(analysis, top, parent) {
|
|
484
|
+
const { type } = parent;
|
|
485
|
+
if (TESTING_PARENTS.has(type)) return nodeAt(parent, "test") === top ? SAFE : UNBOUND;
|
|
486
|
+
if (type === "BinaryExpression" || type === "TemplateLiteral") {
|
|
487
|
+
return isHarmlessOperation(analysis, top, parent) ? SAFE : UNBOUND;
|
|
488
|
+
}
|
|
489
|
+
if (type === "SpreadElement" || HARMLESS_PARENTS.has(type)) return SAFE;
|
|
490
|
+
if (type !== "SequenceExpression") return UNBOUND;
|
|
491
|
+
return nodesAt(parent, "expressions").at(-1) === top ? stepOf(analysis, parent) : SAFE;
|
|
492
|
+
}
|
|
493
|
+
function stepAbove(analysis, top, parent) {
|
|
494
|
+
switch (parent.type) {
|
|
495
|
+
case "CallExpression": {
|
|
496
|
+
return nodeAt(parent, "callee") === top ? CALLED : UNBOUND;
|
|
497
|
+
}
|
|
498
|
+
case "ExportDefaultDeclaration":
|
|
499
|
+
case "ExportSpecifier": {
|
|
500
|
+
return exportStep(parent);
|
|
501
|
+
}
|
|
502
|
+
case "MemberExpression": {
|
|
503
|
+
return nodeAt(parent, "object") === top ? memberStep(analysis, parent) : SAFE;
|
|
504
|
+
}
|
|
505
|
+
case "VariableDeclarator": {
|
|
506
|
+
return nodeAt(parent, "init") === top ? declaredStep(analysis, parent) : SAFE;
|
|
507
|
+
}
|
|
508
|
+
default: {
|
|
509
|
+
return readingStep(analysis, top, parent);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function stepOf(analysis, node) {
|
|
514
|
+
const top = unwrapped(analysis, node);
|
|
515
|
+
const parent = analysis.parentOf.get(top);
|
|
516
|
+
return parent ? stepAbove(analysis, top, parent) : UNBOUND;
|
|
517
|
+
}
|
|
518
|
+
function usesOfAlias(analysis, id) {
|
|
519
|
+
const alias = analysis.bindingDeclaredBy(id);
|
|
520
|
+
if (!alias) return { isWritten: true, nodes: [] };
|
|
521
|
+
const uses = analysis.references.filter(({ binding }) => binding === alias);
|
|
522
|
+
return { isWritten: alias.writes > 0, nodes: uses.map(({ node }) => node) };
|
|
523
|
+
}
|
|
524
|
+
function flowOf(analysis, start) {
|
|
525
|
+
const names = /* @__PURE__ */ new Set();
|
|
526
|
+
const state = { isCalled: false, isUnbound: false };
|
|
527
|
+
const seen = /* @__PURE__ */ new Set();
|
|
528
|
+
const stack = [start];
|
|
529
|
+
while (stack.length > 0 && !state.isUnbound) {
|
|
530
|
+
const node = stack.pop();
|
|
531
|
+
if (seen.has(node)) continue;
|
|
532
|
+
seen.add(node);
|
|
533
|
+
followStep(stepOf(analysis, node), { analysis, names, stack, state });
|
|
534
|
+
}
|
|
535
|
+
return { ...state, names };
|
|
536
|
+
}
|
|
537
|
+
function followStep(step, walk) {
|
|
538
|
+
const { analysis, names, stack, state } = walk;
|
|
539
|
+
if (step.kind === "aliased") {
|
|
540
|
+
if (step.exportedAs !== void 0) names.add(step.exportedAs);
|
|
541
|
+
const alias = usesOfAlias(analysis, step.id);
|
|
542
|
+
state.isUnbound = alias.isWritten;
|
|
543
|
+
pushAll(stack, alias.nodes);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (step.kind === "exported") names.add(step.name);
|
|
547
|
+
state.isCalled ||= step.kind === "called";
|
|
548
|
+
state.isUnbound ||= step.kind === "unbound";
|
|
549
|
+
}
|
|
550
|
+
|
|
386
551
|
// src/vite-cx-refuse.ts
|
|
387
552
|
function textOf(reading, node) {
|
|
388
553
|
return reading.code.slice(node.start, node.end);
|
|
@@ -431,8 +596,41 @@ function isRenamedReexportOf(reading, expression) {
|
|
|
431
596
|
return parent?.type === "ExportSpecifier" && exportNameOf(nodeAt(parent, "exported")) !== "cx";
|
|
432
597
|
}
|
|
433
598
|
|
|
599
|
+
// src/vite-cx-hand-out.ts
|
|
600
|
+
function reexportedAs(reading, expression) {
|
|
601
|
+
const name = reexportNameOf(reading, expression);
|
|
602
|
+
return name === void 0 ? void 0 : { exportedAs: [name] };
|
|
603
|
+
}
|
|
604
|
+
function unboundIn(reading, use) {
|
|
605
|
+
return reading.isDependency === true ? { ...use, isUnboundHandOut: true } : use;
|
|
606
|
+
}
|
|
607
|
+
function handOutOf(reading, expression) {
|
|
608
|
+
if (reading.isDependency !== true) return {};
|
|
609
|
+
const flow = flowOf(reading.analysis, expression);
|
|
610
|
+
if (flow.isUnbound) return { isUnboundHandOut: true };
|
|
611
|
+
if (flow.names.size === 0) return {};
|
|
612
|
+
return { exportedAs: [...flow.names], isRenamed: true };
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// src/vite-cx-unref.ts
|
|
616
|
+
function isVueUnref(reading, callee) {
|
|
617
|
+
if (callee?.type !== "Identifier") return false;
|
|
618
|
+
const binding = reading.analysis.referenceOf(callee)?.binding;
|
|
619
|
+
return binding?.kind === "import" && binding.source === "vue" && binding.imported === "unref";
|
|
620
|
+
}
|
|
621
|
+
function throughUnref(reading, expression) {
|
|
622
|
+
let current = expression;
|
|
623
|
+
for (; ; ) {
|
|
624
|
+
const call = reading.analysis.parentOf.get(current);
|
|
625
|
+
const args = call ? nodesAt(call, "arguments") : [];
|
|
626
|
+
const isUnref = call?.type === "CallExpression" && args.length === 1 && args[0] === current && isVueUnref(reading, nodeAt(call, "callee"));
|
|
627
|
+
if (!isUnref) return current;
|
|
628
|
+
current = call;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
434
632
|
// src/vite-cx-reference.ts
|
|
435
|
-
function
|
|
633
|
+
function isCallee2(parent, node) {
|
|
436
634
|
return parent?.type === "CallExpression" && nodeAt(parent, "callee") === node;
|
|
437
635
|
}
|
|
438
636
|
function isOnlyRaw(pattern) {
|
|
@@ -447,38 +645,37 @@ function refused(node, local, phrase) {
|
|
|
447
645
|
}
|
|
448
646
|
function rawMemberUse(parent, member, local) {
|
|
449
647
|
const isAlias = parent?.type === "VariableDeclarator" && nodeAt(parent, "init") === member && nodeAt(parent, "id")?.type === "Identifier";
|
|
450
|
-
if (isAlias ||
|
|
648
|
+
if (isAlias || isCallee2(parent, member)) return { kind: "raw", node: member, local };
|
|
451
649
|
return refused(member, local, `${local}.raw is used other than by calling it`);
|
|
452
650
|
}
|
|
453
651
|
function memberUse(reading, member, local) {
|
|
652
|
+
const use = namedMemberUse(reading, member, local);
|
|
653
|
+
const isUnbound = member.computed === true || isMemberWrite(reading.analysis, member);
|
|
654
|
+
if (!isUnbound || reading.isDependency !== true) return use;
|
|
655
|
+
return unboundIn(
|
|
656
|
+
reading,
|
|
657
|
+
use.kind === "refused" ? use : refused(member, local, `${local} is read with a computed member`)
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
function namedMemberUse(reading, member, local) {
|
|
454
661
|
const parent = reading.analysis.parentOf.get(member);
|
|
455
662
|
const isComputed = member.computed === true;
|
|
456
663
|
const name = propertyNameOf(nodeAt(member, "property"), isComputed);
|
|
457
664
|
if (name === "raw") return rawMemberUse(parent, member, local);
|
|
458
665
|
if (name === "dynamic" && !isComputed) {
|
|
459
|
-
if (parent &&
|
|
666
|
+
if (parent && isCallee2(parent, member)) return { kind: "dynamic", node: parent, local };
|
|
460
667
|
return refused(member, local, `${local}.dynamic is referenced other than by a direct call`);
|
|
461
668
|
}
|
|
462
669
|
if (name === "call" || name === "apply") {
|
|
463
670
|
return refused(member, local, `${local} is called through .${name}()`);
|
|
464
671
|
}
|
|
465
|
-
|
|
466
|
-
return refused(member, local, `${local}.${name ?? "?"} is not a member the build reads`);
|
|
467
|
-
}
|
|
468
|
-
function isVueUnref(reading, callee) {
|
|
469
|
-
if (callee?.type !== "Identifier") return false;
|
|
470
|
-
const binding = reading.analysis.referenceOf(callee)?.binding;
|
|
471
|
-
return binding?.kind === "import" && binding.source === "vue" && binding.imported === "unref";
|
|
672
|
+
return otherMemberUse(reading, member, { local, name, isComputed });
|
|
472
673
|
}
|
|
473
|
-
function
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const isUnref = call?.type === "CallExpression" && args.length === 1 && args[0] === current && isVueUnref(reading, nodeAt(call, "callee"));
|
|
479
|
-
if (!isUnref) return current;
|
|
480
|
-
current = call;
|
|
481
|
-
}
|
|
674
|
+
function otherMemberUse(reading, member, read) {
|
|
675
|
+
const { isComputed, local, name } = read;
|
|
676
|
+
const phrase = isComputed ? `${local} is read with a computed member` : `${local}.${name ?? "?"} is not a member the build reads`;
|
|
677
|
+
const use = refused(member, local, phrase);
|
|
678
|
+
return unboundIn(reading, use);
|
|
482
679
|
}
|
|
483
680
|
function ancestor(reading, node, levels) {
|
|
484
681
|
let current = node;
|
|
@@ -506,7 +703,7 @@ function rawDestructuring(parent, expression, local) {
|
|
|
506
703
|
function readableUse(reading, expression, local) {
|
|
507
704
|
const parent = reading.analysis.parentOf.get(expression);
|
|
508
705
|
if (!parent) return void 0;
|
|
509
|
-
if (
|
|
706
|
+
if (isCallee2(parent, expression)) return { kind: "call", node: parent, local };
|
|
510
707
|
if (parent.type === "MemberExpression" && nodeAt(parent, "object") === expression) {
|
|
511
708
|
return memberUse(reading, parent, local);
|
|
512
709
|
}
|
|
@@ -518,21 +715,16 @@ function useOfExpression(reading, start, local) {
|
|
|
518
715
|
if (readable) return readable;
|
|
519
716
|
const exposedAs = exposureName(reading, expression);
|
|
520
717
|
if (exposedAs !== void 0) return { kind: "exposure", node: expression, local, exposedAs };
|
|
521
|
-
const phrase = phraseFor(reading, expression, local);
|
|
522
718
|
const isReexport = isReexportOf(reading, expression);
|
|
523
719
|
const isRenamed = isReexport && isRenamedReexportOf(reading, expression);
|
|
524
|
-
const exportedAs = reexportedAs(reading, expression);
|
|
525
720
|
return {
|
|
526
|
-
...refused(expression, local,
|
|
721
|
+
...refused(expression, local, phraseFor(reading, expression, local)),
|
|
527
722
|
isReexport,
|
|
528
723
|
...isRenamed && { isRenamed },
|
|
529
|
-
...
|
|
724
|
+
...reexportedAs(reading, expression),
|
|
725
|
+
...!isReexport && handOutOf(reading, expression)
|
|
530
726
|
};
|
|
531
727
|
}
|
|
532
|
-
function reexportedAs(reading, expression) {
|
|
533
|
-
const name = reexportNameOf(reading, expression);
|
|
534
|
-
return name === void 0 ? void 0 : { exportedAs: [name] };
|
|
535
|
-
}
|
|
536
728
|
function isOtherKey(property) {
|
|
537
729
|
if (property.type !== "Property") return false;
|
|
538
730
|
const name = propertyNameOf(nodeAt(property, "key"), property.computed === true);
|
|
@@ -569,7 +761,9 @@ function namespaceUse(reading, expression, cx) {
|
|
|
569
761
|
if (isListed && isOtherExport) return void 0;
|
|
570
762
|
const use = refused(expression, local, `${local} is used other than as ${local}.cx`);
|
|
571
763
|
const exportedAs = reexportedAs(reading, expression);
|
|
572
|
-
|
|
764
|
+
if (exportedAs) return { ...use, ...exportedAs, isRenamed: true };
|
|
765
|
+
if (patternDestructuring(reading, expression)) return unboundIn(reading, use);
|
|
766
|
+
return { ...use, ...handOutOf(reading, expression) };
|
|
573
767
|
}
|
|
574
768
|
function useOf(reading, reference2, cx) {
|
|
575
769
|
if (cx.isNamespace) return namespaceUse(reading, reference2.node, cx);
|
|
@@ -580,6 +774,407 @@ function useOf(reading, reference2, cx) {
|
|
|
580
774
|
return { ...use, isListable: !isDeclaredSource };
|
|
581
775
|
}
|
|
582
776
|
|
|
777
|
+
// src/vite-cx-take-keys.ts
|
|
778
|
+
var CX_ONLY = /* @__PURE__ */ new Set(["cx"]);
|
|
779
|
+
function isCxName(names, name) {
|
|
780
|
+
return names === void 0 || names.has(name);
|
|
781
|
+
}
|
|
782
|
+
function patternKeys(pattern, names) {
|
|
783
|
+
const taken = [];
|
|
784
|
+
for (const property of nodesAt(pattern, "properties")) {
|
|
785
|
+
const key = property.type === "Property" ? propertyNameOf(nodeAt(property, "key"), property.computed === true) : void 0;
|
|
786
|
+
if (key === void 0) return void 0;
|
|
787
|
+
if (isCxName(names, key)) taken.push(key);
|
|
788
|
+
}
|
|
789
|
+
return taken;
|
|
790
|
+
}
|
|
791
|
+
function referenceTakes(analysis, node, names) {
|
|
792
|
+
const read = memberReadOf({ analysis }, node);
|
|
793
|
+
if (read) {
|
|
794
|
+
if (read.key === void 0) return void 0;
|
|
795
|
+
return isCxName(names, read.key) ? [read.key] : [];
|
|
796
|
+
}
|
|
797
|
+
const pattern = patternDestructuring({ analysis }, node);
|
|
798
|
+
return pattern?.type === "ObjectPattern" ? patternKeys(pattern, names) : void 0;
|
|
799
|
+
}
|
|
800
|
+
function outermost(analysis, node) {
|
|
801
|
+
let current = node;
|
|
802
|
+
let parent = analysis.parentOf.get(current);
|
|
803
|
+
while (parent?.type === "ParenthesizedExpression") {
|
|
804
|
+
current = parent;
|
|
805
|
+
parent = analysis.parentOf.get(current);
|
|
806
|
+
}
|
|
807
|
+
return current;
|
|
808
|
+
}
|
|
809
|
+
function thenCall(analysis, node) {
|
|
810
|
+
const member = analysis.parentOf.get(node);
|
|
811
|
+
if (member?.type !== "MemberExpression" || nodeAt(member, "object") !== node) return void 0;
|
|
812
|
+
const key = propertyNameOf(nodeAt(member, "property"), member.computed === true);
|
|
813
|
+
const call = analysis.parentOf.get(member);
|
|
814
|
+
return key === "then" && call?.type === "CallExpression" && nodeAt(call, "callee") === member ? call : void 0;
|
|
815
|
+
}
|
|
816
|
+
function thenCallback(analysis, node) {
|
|
817
|
+
const call = thenCall(analysis, node);
|
|
818
|
+
const callback = call && nodesAt(call, "arguments")[0];
|
|
819
|
+
const isInline = callback?.type === "ArrowFunctionExpression" || callback?.type === "FunctionExpression";
|
|
820
|
+
return isInline ? callback : void 0;
|
|
821
|
+
}
|
|
822
|
+
function referencesToParameter(analysis, owner, name) {
|
|
823
|
+
return analysis.references.filter(
|
|
824
|
+
({ binding }) => binding?.kind === "param" && binding.owner === owner && binding.name === name
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
function parameterTakes(analysis, callback, names) {
|
|
828
|
+
const parameter = nodesAt(callback, "params")[0];
|
|
829
|
+
if (parameter === void 0) return [];
|
|
830
|
+
if (parameter.type === "ObjectPattern") return patternKeys(parameter, names);
|
|
831
|
+
const name = parameter.type === "Identifier" ? stringAt(parameter, "name") : void 0;
|
|
832
|
+
if (name === void 0) return void 0;
|
|
833
|
+
const found = [];
|
|
834
|
+
for (const { binding, node } of referencesToParameter(analysis, callback, name)) {
|
|
835
|
+
const taken = binding?.writes === 0 ? referenceTakes(analysis, node, names) : void 0;
|
|
836
|
+
if (taken === void 0) return void 0;
|
|
837
|
+
pushAll(found, taken);
|
|
838
|
+
}
|
|
839
|
+
return found;
|
|
840
|
+
}
|
|
841
|
+
function variableTakes(analysis, init, names) {
|
|
842
|
+
const declarator = analysis.parentOf.get(init);
|
|
843
|
+
const declaration = declarator && analysis.parentOf.get(declarator);
|
|
844
|
+
if (declaration && analysis.parentOf.get(declaration)?.type === "ExportNamedDeclaration") {
|
|
845
|
+
return void 0;
|
|
846
|
+
}
|
|
847
|
+
const found = [];
|
|
848
|
+
for (const { binding, node } of analysis.references) {
|
|
849
|
+
if (binding?.init !== init) continue;
|
|
850
|
+
const taken = binding.writes === 0 ? referenceTakes(analysis, node, names) : void 0;
|
|
851
|
+
if (taken === void 0) return void 0;
|
|
852
|
+
pushAll(found, taken);
|
|
853
|
+
}
|
|
854
|
+
return found;
|
|
855
|
+
}
|
|
856
|
+
function awaitedKeys(analysis, awaited, names) {
|
|
857
|
+
const declarator = analysis.parentOf.get(awaited);
|
|
858
|
+
const isVariable = declarator?.type === "VariableDeclarator" && nodeAt(declarator, "init") === awaited && nodeAt(declarator, "id")?.type === "Identifier";
|
|
859
|
+
return isVariable ? variableTakes(analysis, awaited, names) : referenceTakes(analysis, awaited, names);
|
|
860
|
+
}
|
|
861
|
+
function dynamicKeys(analysis, node, names) {
|
|
862
|
+
const awaited = analysis.parentOf.get(node);
|
|
863
|
+
if (awaited?.type === "AwaitExpression") {
|
|
864
|
+
return awaitedKeys(analysis, outermost(analysis, awaited), names);
|
|
865
|
+
}
|
|
866
|
+
const callback = thenCallback(analysis, node);
|
|
867
|
+
return callback && parameterTakes(analysis, callback, names);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// src/vite-commonjs-exports.ts
|
|
871
|
+
function isName(node, name) {
|
|
872
|
+
return node?.type === "Identifier" && node.name === name;
|
|
873
|
+
}
|
|
874
|
+
function isModuleExports(node) {
|
|
875
|
+
if (node?.type !== "MemberExpression" || node.computed === true) return false;
|
|
876
|
+
return isName(nodeAt(node, "object"), "module") && isName(nodeAt(node, "property"), "exports");
|
|
877
|
+
}
|
|
878
|
+
function isExportsObject(node) {
|
|
879
|
+
return isName(node, "exports") || isModuleExports(node);
|
|
880
|
+
}
|
|
881
|
+
function memberOf(node) {
|
|
882
|
+
if (node?.type !== "MemberExpression" || node.computed === true) return void 0;
|
|
883
|
+
const object = nodeAt(node, "object");
|
|
884
|
+
const name = exportNameOf(nodeAt(node, "property"));
|
|
885
|
+
return object === void 0 || name === void 0 ? void 0 : { name, object };
|
|
886
|
+
}
|
|
887
|
+
function exportsMemberOf(node) {
|
|
888
|
+
const member = memberOf(node);
|
|
889
|
+
if (!member) return void 0;
|
|
890
|
+
return isExportsObject(member.object) ? member.name : void 0;
|
|
891
|
+
}
|
|
892
|
+
function statementCallOf(statement) {
|
|
893
|
+
if (statement.type !== "ExpressionStatement") return void 0;
|
|
894
|
+
const expression = nodeAt(statement, "expression");
|
|
895
|
+
return expression?.type === "CallExpression" ? expression : void 0;
|
|
896
|
+
}
|
|
897
|
+
function definePropertyOf(statement) {
|
|
898
|
+
const call = statementCallOf(statement);
|
|
899
|
+
const callee = call && memberOf(nodeAt(call, "callee"));
|
|
900
|
+
if (!call || callee?.name !== "defineProperty" || !isName(callee.object, "Object")) {
|
|
901
|
+
return void 0;
|
|
902
|
+
}
|
|
903
|
+
const [target, key, descriptor] = nodesAt(call, "arguments");
|
|
904
|
+
return { as: staticStringOf(key), descriptor, target };
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// src/vite-commonjs-emits.ts
|
|
908
|
+
function initOf(analysis, name) {
|
|
909
|
+
const binding = analysis.referenceOf(name)?.binding;
|
|
910
|
+
return binding?.writes === 0 ? binding.init : void 0;
|
|
911
|
+
}
|
|
912
|
+
function isOwnHelperRead(node) {
|
|
913
|
+
const member = memberOf(node);
|
|
914
|
+
return member?.name === "__exportStar" && member.object.type === "ThisExpression";
|
|
915
|
+
}
|
|
916
|
+
function isThisGuard(node) {
|
|
917
|
+
if (node?.type !== "LogicalExpression" || node.operator !== "&&") return false;
|
|
918
|
+
return nodeAt(node, "left")?.type === "ThisExpression" && isOwnHelperRead(nodeAt(node, "right"));
|
|
919
|
+
}
|
|
920
|
+
function isOwnHelper(node) {
|
|
921
|
+
if (node?.type !== "LogicalExpression" || node.operator !== "||") return false;
|
|
922
|
+
return isThisGuard(nodeAt(node, "left")) && nodeAt(node, "right")?.type === "FunctionExpression";
|
|
923
|
+
}
|
|
924
|
+
function isTslibRequire(node) {
|
|
925
|
+
if (node?.type !== "CallExpression" || !isName(nodeAt(node, "callee"), "require")) return false;
|
|
926
|
+
const args = nodesAt(node, "arguments");
|
|
927
|
+
return args.length === 1 && staticStringOf(args[0]) === "tslib";
|
|
928
|
+
}
|
|
929
|
+
function isTslibMember(callee, analysis) {
|
|
930
|
+
const member = memberOf(callee);
|
|
931
|
+
if (member?.object.type !== "Identifier") return false;
|
|
932
|
+
return isTslibRequire(initOf(analysis, member.object));
|
|
933
|
+
}
|
|
934
|
+
function isExportStarCallee(callee, analysis) {
|
|
935
|
+
if (isName(callee, "__exportStar")) return isOwnHelper(initOf(analysis, callee));
|
|
936
|
+
return memberOf(callee)?.name === "__exportStar" && isTslibMember(callee, analysis);
|
|
937
|
+
}
|
|
938
|
+
function exportStarOf(statement, input) {
|
|
939
|
+
const call = statementCallOf(statement);
|
|
940
|
+
if (!call) return void 0;
|
|
941
|
+
const [required, target] = nodesAt(call, "arguments");
|
|
942
|
+
if (required === void 0 || !input.requires.has(required) || !isExportsObject(target)) {
|
|
943
|
+
return void 0;
|
|
944
|
+
}
|
|
945
|
+
const analysis = input.analysis();
|
|
946
|
+
const isHelper = !analysis.hasDirectEval && isExportStarCallee(nodeAt(call, "callee"), analysis);
|
|
947
|
+
return isHelper ? required : void 0;
|
|
948
|
+
}
|
|
949
|
+
function starForwardOf(statement, input) {
|
|
950
|
+
const required = exportStarOf(statement, input);
|
|
951
|
+
if (required === void 0) return void 0;
|
|
952
|
+
const named = input.names?.values().filter((name) => name !== "default").toArray();
|
|
953
|
+
const takes = named?.length === 0 ? [] : [{ shape: "star", names: [], isForward: true }];
|
|
954
|
+
return { given: named ?? [], require: required, takes };
|
|
955
|
+
}
|
|
956
|
+
function returnOf(block) {
|
|
957
|
+
const statements = nodesAt(block, "body");
|
|
958
|
+
const only = statements.length === 1 ? statements[0] : void 0;
|
|
959
|
+
return only?.type === "ReturnStatement" ? nodeAt(only, "argument") : void 0;
|
|
960
|
+
}
|
|
961
|
+
function returnedBy(getter) {
|
|
962
|
+
const isArrow = getter?.type === "ArrowFunctionExpression";
|
|
963
|
+
if (!getter || !isArrow && getter.type !== "FunctionExpression") return void 0;
|
|
964
|
+
const body = nodeAt(getter, "body");
|
|
965
|
+
if (body?.type === "BlockStatement") return returnOf(body);
|
|
966
|
+
return isArrow ? body : void 0;
|
|
967
|
+
}
|
|
968
|
+
function getterOf(descriptor) {
|
|
969
|
+
if (descriptor?.type !== "ObjectExpression") return void 0;
|
|
970
|
+
const property = nodesAt(descriptor, "properties").find((node) => {
|
|
971
|
+
const isGet = propertyNameOf(nodeAt(node, "key"), node.computed === true) === "get";
|
|
972
|
+
return node.type === "Property" && isGet;
|
|
973
|
+
});
|
|
974
|
+
return property && nodeAt(property, "value");
|
|
975
|
+
}
|
|
976
|
+
function getterReadOf(statement) {
|
|
977
|
+
const define = definePropertyOf(statement);
|
|
978
|
+
if (define?.as === void 0 || !isExportsObject(define.target)) return void 0;
|
|
979
|
+
const member = memberOf(returnedBy(getterOf(define.descriptor)));
|
|
980
|
+
if (member?.object.type !== "Identifier") return void 0;
|
|
981
|
+
return { as: define.as, name: member.name, object: member.object };
|
|
982
|
+
}
|
|
983
|
+
function boundForwardOf(require2, reads, context) {
|
|
984
|
+
const uses = context.analysis.references.filter(({ binding: binding2 }) => binding2?.init === require2);
|
|
985
|
+
const binding = uses[0]?.binding;
|
|
986
|
+
if (!binding || binding.writes > 0) return void 0;
|
|
987
|
+
const read = uses.map(({ node }) => reads.get(node));
|
|
988
|
+
if (read.includes(void 0)) return void 0;
|
|
989
|
+
const cx = read.filter((getter) => getter !== void 0 && isCxName(context.names, getter.name));
|
|
990
|
+
const names = [...new Set(cx.map((getter) => getter.name))];
|
|
991
|
+
const takes = names.length === 0 ? [] : [{ shape: "names", names, isPassedOn: true, isForward: true }];
|
|
992
|
+
return { given: cx.map((getter) => getter.as), require: require2, takes };
|
|
993
|
+
}
|
|
994
|
+
function boundForwardsOf(program, input) {
|
|
995
|
+
const reads = /* @__PURE__ */ new Map();
|
|
996
|
+
for (const statement of nodesAt(program, "body")) {
|
|
997
|
+
const read = getterReadOf(statement);
|
|
998
|
+
if (read) reads.set(read.object, read);
|
|
999
|
+
}
|
|
1000
|
+
if (reads.size === 0) return [];
|
|
1001
|
+
const analysis = input.analysis();
|
|
1002
|
+
if (analysis.hasDirectEval) return [];
|
|
1003
|
+
const context = { analysis, names: input.names };
|
|
1004
|
+
return [...input.requires].flatMap((require2) => {
|
|
1005
|
+
const forward = boundForwardOf(require2, reads, context);
|
|
1006
|
+
return forward ? [forward] : [];
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// src/vite-require-interop.ts
|
|
1011
|
+
var INTEROP_HELPERS = /* @__PURE__ */ new Set([
|
|
1012
|
+
"__importDefault",
|
|
1013
|
+
"__importStar",
|
|
1014
|
+
"__toESM",
|
|
1015
|
+
"_interop_require_default",
|
|
1016
|
+
"_interop_require_wildcard",
|
|
1017
|
+
"_interopRequireDefault",
|
|
1018
|
+
"_interopRequireWildcard"
|
|
1019
|
+
]);
|
|
1020
|
+
function isInteropCallee(analysis, callee) {
|
|
1021
|
+
if (callee?.type === "Identifier") {
|
|
1022
|
+
const binding = analysis.referenceOf(callee)?.binding;
|
|
1023
|
+
const isDeclared = binding !== void 0 && binding.kind !== "import" && binding.kind !== "param";
|
|
1024
|
+
return INTEROP_HELPERS.has(callee.name) && isDeclared;
|
|
1025
|
+
}
|
|
1026
|
+
const member = memberOf(callee);
|
|
1027
|
+
return member !== void 0 && INTEROP_HELPERS.has(member.name) && isTslibMember(callee, analysis);
|
|
1028
|
+
}
|
|
1029
|
+
function unwrappedFromInterop(analysis, node) {
|
|
1030
|
+
let current = node;
|
|
1031
|
+
for (; ; ) {
|
|
1032
|
+
const parent = analysis.parentOf.get(current);
|
|
1033
|
+
if (parent?.type === "AwaitExpression") {
|
|
1034
|
+
current = parent;
|
|
1035
|
+
continue;
|
|
1036
|
+
}
|
|
1037
|
+
const args = parent ? nodesAt(parent, "arguments") : [];
|
|
1038
|
+
const isFirstArgument = parent?.type === "CallExpression" && args[0] === current;
|
|
1039
|
+
if (!parent || !isFirstArgument || !isInteropCallee(analysis, nodeAt(parent, "callee"))) {
|
|
1040
|
+
return current;
|
|
1041
|
+
}
|
|
1042
|
+
current = parent;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// src/vite-require-uses.ts
|
|
1047
|
+
var INHERITED_NAMES = /* @__PURE__ */ new Set([
|
|
1048
|
+
...Object.getOwnPropertyNames(Object.prototype),
|
|
1049
|
+
...Object.getOwnPropertyNames(Function.prototype)
|
|
1050
|
+
]);
|
|
1051
|
+
function isExportKey(key) {
|
|
1052
|
+
return key !== void 0 && !INHERITED_NAMES.has(key);
|
|
1053
|
+
}
|
|
1054
|
+
function isCalled(analysis, node) {
|
|
1055
|
+
const parent = analysis.parentOf.get(node);
|
|
1056
|
+
if (parent?.type === "CallExpression") return nodeAt(parent, "callee") === node;
|
|
1057
|
+
if (parent?.type !== "SequenceExpression") return false;
|
|
1058
|
+
return nodesAt(parent, "expressions").at(-1) === node && isCalled(analysis, parent);
|
|
1059
|
+
}
|
|
1060
|
+
function isCalledWithReceiver(analysis, member) {
|
|
1061
|
+
return analysis.parentOf.get(member)?.type === "CallExpression";
|
|
1062
|
+
}
|
|
1063
|
+
function isMemberCall(analysis, node, cxNames) {
|
|
1064
|
+
const member = analysis.parentOf.get(node);
|
|
1065
|
+
if (member?.type !== "MemberExpression" || nodeAt(member, "object") !== node) return false;
|
|
1066
|
+
const key = propertyNameOf(nodeAt(member, "property"), member.computed === true);
|
|
1067
|
+
if (!isExportKey(key) || !isCalled(analysis, member)) return false;
|
|
1068
|
+
return isCxName(cxNames, key) || !isCalledWithReceiver(analysis, member);
|
|
1069
|
+
}
|
|
1070
|
+
function destructuredNames(pattern) {
|
|
1071
|
+
if (pattern.type !== "ObjectPattern") return void 0;
|
|
1072
|
+
const names = [];
|
|
1073
|
+
for (const property of nodesAt(pattern, "properties")) {
|
|
1074
|
+
const value = nodeAt(property, "value");
|
|
1075
|
+
const key = propertyNameOf(nodeAt(property, "key"), property.computed === true);
|
|
1076
|
+
if (!isExportKey(key) || property.type !== "Property" || value?.type !== "Identifier") {
|
|
1077
|
+
return void 0;
|
|
1078
|
+
}
|
|
1079
|
+
names.push(value.name);
|
|
1080
|
+
}
|
|
1081
|
+
return names;
|
|
1082
|
+
}
|
|
1083
|
+
function isOnlyUsedAs(analysis, names, isUse) {
|
|
1084
|
+
const matching = analysis.references.filter(
|
|
1085
|
+
({ binding }) => binding !== void 0 && binding.kind !== "param" && names.includes(binding.name)
|
|
1086
|
+
);
|
|
1087
|
+
return matching.every(({ binding, node }) => binding.writes === 0 && isUse(node));
|
|
1088
|
+
}
|
|
1089
|
+
function isBoundAndCalled(analysis, input, isUsedAs) {
|
|
1090
|
+
const { cxNames, pattern } = input;
|
|
1091
|
+
if (pattern?.type === "Identifier") {
|
|
1092
|
+
return isUsedAs([pattern.name], (node) => isMemberCall(analysis, node, cxNames));
|
|
1093
|
+
}
|
|
1094
|
+
const names = pattern && destructuredNames(pattern);
|
|
1095
|
+
return names !== void 0 && isUsedAs(names, (node) => isCalled(analysis, node));
|
|
1096
|
+
}
|
|
1097
|
+
function isExportedDeclarator(analysis, declarator) {
|
|
1098
|
+
const declaration = analysis.parentOf.get(declarator);
|
|
1099
|
+
return declaration !== void 0 && analysis.parentOf.get(declaration)?.type === "ExportNamedDeclaration";
|
|
1100
|
+
}
|
|
1101
|
+
function isDeclaredAndCalled(analysis, declarator, input) {
|
|
1102
|
+
if (nodeAt(declarator, "init") !== input.top || isExportedDeclarator(analysis, declarator)) {
|
|
1103
|
+
return false;
|
|
1104
|
+
}
|
|
1105
|
+
return isBoundAndCalled(
|
|
1106
|
+
analysis,
|
|
1107
|
+
{ cxNames: input.cxNames, pattern: nodeAt(declarator, "id") },
|
|
1108
|
+
(names, isUse) => isOnlyUsedAs(analysis, names, isUse)
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
function isMemberDeclaredAndCalled(analysis, member) {
|
|
1112
|
+
const name = propertyNameOf(nodeAt(member, "property"), member.computed === true);
|
|
1113
|
+
const declarator = analysis.parentOf.get(member);
|
|
1114
|
+
if (!isExportKey(name) || declarator?.type !== "VariableDeclarator") return false;
|
|
1115
|
+
if (isExportedDeclarator(analysis, declarator)) return false;
|
|
1116
|
+
const id = nodeAt(declarator, "id");
|
|
1117
|
+
if (nodeAt(declarator, "init") !== member || id?.type !== "Identifier") return false;
|
|
1118
|
+
return isOnlyUsedAs(analysis, [id.name], (node) => isCalled(analysis, node));
|
|
1119
|
+
}
|
|
1120
|
+
function isCallbackCalledOnly(analysis, callback, cxNames) {
|
|
1121
|
+
if (callback?.type !== "ArrowFunctionExpression") return false;
|
|
1122
|
+
const parameter = nodesAt(callback, "params")[0];
|
|
1123
|
+
if (!parameter) return true;
|
|
1124
|
+
const isInside = (node) => node.start >= callback.start && node.end <= callback.end;
|
|
1125
|
+
return isBoundAndCalled(
|
|
1126
|
+
analysis,
|
|
1127
|
+
{ cxNames, pattern: parameter },
|
|
1128
|
+
(names, isUse) => analysis.references.filter(({ node }) => isInside(node) && names.includes(node.name)).every(({ node }) => isUse(node))
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
function isPromiseUsedAsCallsOnly(analysis, promise, cxNames) {
|
|
1132
|
+
const member = analysis.parentOf.get(promise);
|
|
1133
|
+
if (member?.type === "ExpressionStatement") return true;
|
|
1134
|
+
if (member?.type !== "MemberExpression" || nodeAt(member, "object") !== promise) return false;
|
|
1135
|
+
const name = propertyNameOf(nodeAt(member, "property"), member.computed === true);
|
|
1136
|
+
const call = analysis.parentOf.get(member);
|
|
1137
|
+
if (name !== "then" || call?.type !== "CallExpression" || nodeAt(call, "callee") !== member) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
return isCallbackCalledOnly(analysis, nodesAt(call, "arguments")[0], cxNames);
|
|
1141
|
+
}
|
|
1142
|
+
function isAwaitedUpTo(analysis, node, top) {
|
|
1143
|
+
let current = node;
|
|
1144
|
+
while (current && current !== top) {
|
|
1145
|
+
current = analysis.parentOf.get(current);
|
|
1146
|
+
if (current?.type === "AwaitExpression") return true;
|
|
1147
|
+
}
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
function isResultUsedAsCallsOnly(analysis, top, cxNames) {
|
|
1151
|
+
const parent = analysis.parentOf.get(top);
|
|
1152
|
+
if (parent?.type === "ExpressionStatement") return true;
|
|
1153
|
+
if (parent?.type === "MemberExpression") {
|
|
1154
|
+
return isMemberCall(analysis, top, cxNames) || isMemberDeclaredAndCalled(analysis, parent);
|
|
1155
|
+
}
|
|
1156
|
+
return parent?.type === "VariableDeclarator" && isDeclaredAndCalled(analysis, parent, { cxNames, top });
|
|
1157
|
+
}
|
|
1158
|
+
function isEqualsDeclaredAndCalled(analysis, declaration, cxNames) {
|
|
1159
|
+
if (analysis.parentOf.get(declaration)?.type === "ExportNamedDeclaration") return false;
|
|
1160
|
+
return isBoundAndCalled(
|
|
1161
|
+
analysis,
|
|
1162
|
+
{ cxNames, pattern: nodeAt(declaration, "id") },
|
|
1163
|
+
(names, isUse) => isOnlyUsedAs(analysis, names, isUse)
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
function isUsedAsCallsOnly(analysis, require2, cxNames) {
|
|
1167
|
+
if (analysis.hasDirectEval) return false;
|
|
1168
|
+
if (require2.type === "TSImportEqualsDeclaration") {
|
|
1169
|
+
return isEqualsDeclaredAndCalled(analysis, require2, cxNames);
|
|
1170
|
+
}
|
|
1171
|
+
const top = unwrappedFromInterop(analysis, require2);
|
|
1172
|
+
if (require2.type === "ImportExpression" && !isAwaitedUpTo(analysis, require2, top)) {
|
|
1173
|
+
return isPromiseUsedAsCallsOnly(analysis, top, cxNames);
|
|
1174
|
+
}
|
|
1175
|
+
return isResultUsedAsCallsOnly(analysis, top, cxNames);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
583
1178
|
// src/vite-cx-source-forms.ts
|
|
584
1179
|
var REEXPORT_TEXT = "a re-export of cx, which the build follows only from a module listed in cxModules.";
|
|
585
1180
|
var SECOND_HOP_TEXT = "a re-export of the cx of a module listed in cxModules, which the build follows one step only.";
|
|
@@ -615,23 +1210,31 @@ function reexportProblem(code, node, isListed) {
|
|
|
615
1210
|
exportedAs: exportedNamesOf(node)
|
|
616
1211
|
};
|
|
617
1212
|
}
|
|
618
|
-
function
|
|
1213
|
+
function dynamicImportProblem(code, node, options, analysis) {
|
|
1214
|
+
const isHandedOut2 = options.isDependency === true && !isUsedAsCallsOnly(analysis, node, CX_ONLY);
|
|
1215
|
+
return {
|
|
1216
|
+
kind: "reference",
|
|
1217
|
+
offset: node.start,
|
|
1218
|
+
construct: code.slice(node.start, node.end),
|
|
1219
|
+
text: DYNAMIC_IMPORT_TEXT,
|
|
1220
|
+
...isHandedOut2 && { isUnboundHandOut: true }
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
function sourceFormProblem(code, node, options, analysis) {
|
|
619
1224
|
const source = staticStringOf(nodeAt(node, "source"));
|
|
620
1225
|
if (source === void 0 || !options.cxSources.has(source)) return void 0;
|
|
621
1226
|
if (node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") {
|
|
622
1227
|
if (isTypeOnly(node) || options.isDeclared === true) return void 0;
|
|
623
1228
|
return reexportProblem(code, node, options.declaredSources?.has(source) === true);
|
|
624
1229
|
}
|
|
625
|
-
|
|
626
|
-
const construct = code.slice(node.start, node.end);
|
|
627
|
-
return { kind: "reference", offset: node.start, construct, text: DYNAMIC_IMPORT_TEXT };
|
|
1230
|
+
return node.type === "ImportExpression" ? dynamicImportProblem(code, node, options, analysis) : void 0;
|
|
628
1231
|
}
|
|
629
|
-
function sourceFormProblems(code, program, options) {
|
|
1232
|
+
function sourceFormProblems(code, program, options, analysis) {
|
|
630
1233
|
const problems = [];
|
|
631
1234
|
const stack = [program];
|
|
632
1235
|
while (stack.length > 0) {
|
|
633
1236
|
const node = stack.pop();
|
|
634
|
-
const problem2 = sourceFormProblem(code, node, options);
|
|
1237
|
+
const problem2 = sourceFormProblem(code, node, options, analysis);
|
|
635
1238
|
if (problem2) problems.push(problem2);
|
|
636
1239
|
pushAll(stack, childrenOf(node));
|
|
637
1240
|
}
|
|
@@ -1525,6 +2128,7 @@ function declarePattern(pattern, spec, scope, walker) {
|
|
|
1525
2128
|
if (spec.owner) binding.owner = spec.owner;
|
|
1526
2129
|
const declared = declare(into, binding, isAssigning);
|
|
1527
2130
|
if (spec.init) declared.init = spec.init;
|
|
2131
|
+
walker.declarations.set(pattern, declared);
|
|
1528
2132
|
return;
|
|
1529
2133
|
}
|
|
1530
2134
|
DECLARE[pattern.type]?.(pattern, spec, scope, walker);
|
|
@@ -1758,6 +2362,10 @@ var HANDLERS = {
|
|
|
1758
2362
|
ImportDeclaration: (node, scope) => {
|
|
1759
2363
|
declareImport(node, scope);
|
|
1760
2364
|
},
|
|
2365
|
+
TSImportEqualsDeclaration: (node, scope, walker) => {
|
|
2366
|
+
if (!isTypeOnly(node)) declarePattern(nodeAt(node, "id"), { kind: "const" }, scope, walker);
|
|
2367
|
+
visitKeys(node, ["moduleReference"], scope, walker);
|
|
2368
|
+
},
|
|
1761
2369
|
ExportNamedDeclaration: visitExport,
|
|
1762
2370
|
VariableDeclaration: visitDeclaration,
|
|
1763
2371
|
FunctionDeclaration: (node, scope, walker) => {
|
|
@@ -1833,6 +2441,7 @@ function analyze(program) {
|
|
|
1833
2441
|
const walker = {
|
|
1834
2442
|
references: [],
|
|
1835
2443
|
parentOf: /* @__PURE__ */ new Map(),
|
|
2444
|
+
declarations: /* @__PURE__ */ new Map(),
|
|
1836
2445
|
evalScopes: [],
|
|
1837
2446
|
visit: (node, scope) => {
|
|
1838
2447
|
visit(node, scope, walker);
|
|
@@ -1854,7 +2463,8 @@ function analyze(program) {
|
|
|
1854
2463
|
hasDirectEval: evalScopes.length > 0,
|
|
1855
2464
|
references: walker.references,
|
|
1856
2465
|
parentOf: walker.parentOf,
|
|
1857
|
-
referenceOf: (node) => byNode.get(node)
|
|
2466
|
+
referenceOf: (node) => byNode.get(node),
|
|
2467
|
+
bindingDeclaredBy: (node) => walker.declarations.get(node)
|
|
1858
2468
|
};
|
|
1859
2469
|
}
|
|
1860
2470
|
|
|
@@ -1977,7 +2587,8 @@ function refusedProblem(reading, use) {
|
|
|
1977
2587
|
text: `${use.phrase ?? ""}.`,
|
|
1978
2588
|
...use.isReexport && { isListable: use.isListable },
|
|
1979
2589
|
...use.isRenamed === true && { isRenamed: true },
|
|
1980
|
-
...use.exportedAs && { exportedAs: use.exportedAs }
|
|
2590
|
+
...use.exportedAs && { exportedAs: use.exportedAs },
|
|
2591
|
+
...use.isUnboundHandOut === true && { isUnboundHandOut: true }
|
|
1981
2592
|
};
|
|
1982
2593
|
}
|
|
1983
2594
|
function readUse(reading, use, analysis) {
|
|
@@ -2018,7 +2629,8 @@ function readUses(reading, program) {
|
|
|
2018
2629
|
analysis,
|
|
2019
2630
|
code,
|
|
2020
2631
|
allowsExposure: options.isVueScript === true,
|
|
2021
|
-
declaredSources: options.declaredSources
|
|
2632
|
+
declaredSources: options.declaredSources,
|
|
2633
|
+
isDependency: options.isDependency
|
|
2022
2634
|
};
|
|
2023
2635
|
for (const reference2 of analysis.references) {
|
|
2024
2636
|
const cx = reference2.binding && bindings.get(reference2.binding);
|
|
@@ -2060,7 +2672,7 @@ function readModule(code, program, options) {
|
|
|
2060
2672
|
cxSources: options.cxSources,
|
|
2061
2673
|
declaredSources: options.declaredSources ?? /* @__PURE__ */ new Set()
|
|
2062
2674
|
}) : [];
|
|
2063
|
-
for (const problem2 of [...sourceFormProblems(code, program, options), ...listed]) {
|
|
2675
|
+
for (const problem2 of [...sourceFormProblems(code, program, options, analysis), ...listed]) {
|
|
2064
2676
|
report(reading, problem2);
|
|
2065
2677
|
}
|
|
2066
2678
|
for (const atom of atomsWrittenIn(code)) result.classes.add(atom);
|
|
@@ -2437,10 +3049,198 @@ function unprunedAtoms(css, emitted) {
|
|
|
2437
3049
|
return [...atoms].toSorted((a, b) => a.localeCompare(b));
|
|
2438
3050
|
}
|
|
2439
3051
|
|
|
2440
|
-
// src/vite-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
3052
|
+
// src/vite-css-id.ts
|
|
3053
|
+
var STYLESHEET = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
|
|
3054
|
+
var SPECIAL_QUERY = /[?&](?:worker|sharedworker|raw|url)\b/;
|
|
3055
|
+
var CSS_MODULE = /\.module\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
|
|
3056
|
+
var TEXT_QUERY = /[?&](?:inline|direct|transform-only)\b/;
|
|
3057
|
+
function isStylesheetPath(id) {
|
|
3058
|
+
return STYLESHEET.test(id);
|
|
3059
|
+
}
|
|
3060
|
+
function isStylesheetId(id) {
|
|
3061
|
+
return STYLESHEET.test(id) && !SPECIAL_QUERY.test(id);
|
|
3062
|
+
}
|
|
3063
|
+
function isCssModuleId(id) {
|
|
3064
|
+
return isStylesheetId(id) && CSS_MODULE.test(id) && !TEXT_QUERY.test(id);
|
|
3065
|
+
}
|
|
3066
|
+
function isUnreadStylesheet(id) {
|
|
3067
|
+
return isStylesheetId(id) && !isCssModuleId(id);
|
|
3068
|
+
}
|
|
3069
|
+
function canHoldDirective(code) {
|
|
3070
|
+
return /@[n\\]/i.test(code);
|
|
3071
|
+
}
|
|
3072
|
+
function filePathOf(id) {
|
|
3073
|
+
const query = id.indexOf("?");
|
|
3074
|
+
return query === -1 ? id : id.slice(0, query);
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
// src/vite-cx-text-test.ts
|
|
3078
|
+
function literalPattern(text) {
|
|
3079
|
+
return text.replaceAll(/[$()*+.?[\\\]^{|}]/g, String.raw`\$&`);
|
|
3080
|
+
}
|
|
3081
|
+
var INSIDE = String.raw`[^\n'"\x60\\]{0,512}`;
|
|
3082
|
+
var EXTENSION = String.raw`\.[^\n'"\x60\\/?#.]*`;
|
|
3083
|
+
var QUOTE = String.raw`['"\x60]`;
|
|
3084
|
+
function textTestOf(names) {
|
|
3085
|
+
if (names.size === 0) return void 0;
|
|
3086
|
+
const listed = [...names].map((name) => literalPattern(name)).join("|");
|
|
3087
|
+
const named = `${QUOTE}(?:${INSIDE}/)?(?:${listed})(?:${EXTENSION})?/*(?:[?#]${INSIDE})?${QUOTE}`;
|
|
3088
|
+
const directory = String.raw`(?:\bfrom|\bimport)\s*(?:\(\s*)?${QUOTE}\.{1,2}(?:/\.{1,2})*/?${QUOTE}`;
|
|
3089
|
+
return new RegExp(names.has("index") ? `${named}|${directory}` : named);
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
// src/vite-path-text.ts
|
|
3093
|
+
function baseNameOf(file) {
|
|
3094
|
+
let end = file.length;
|
|
3095
|
+
while (end > 1 && file[end - 1] === "/") end -= 1;
|
|
3096
|
+
const start = file.lastIndexOf("/", end - 1) + 1;
|
|
3097
|
+
return file.slice(start, end);
|
|
3098
|
+
}
|
|
3099
|
+
function extensionOf(file) {
|
|
3100
|
+
const segment = baseNameOf(file);
|
|
3101
|
+
const dot = segment.lastIndexOf(".");
|
|
3102
|
+
return segment === ".." || dot <= 0 ? "" : segment.slice(dot);
|
|
3103
|
+
}
|
|
3104
|
+
function stemOf(file) {
|
|
3105
|
+
const segment = baseNameOf(file);
|
|
3106
|
+
const extension = extensionOf(file);
|
|
3107
|
+
return extension === "" || extension === segment ? segment : segment.slice(0, -extension.length);
|
|
3108
|
+
}
|
|
3109
|
+
function directoryOf(file) {
|
|
3110
|
+
let end = file.length;
|
|
3111
|
+
while (end > 1 && file[end - 1] === "/") end -= 1;
|
|
3112
|
+
const slash = file.lastIndexOf("/", end - 1);
|
|
3113
|
+
if (slash === -1) return ".";
|
|
3114
|
+
let cut2 = slash;
|
|
3115
|
+
while (cut2 > 1 && file[cut2 - 1] === "/") cut2 -= 1;
|
|
3116
|
+
return file.slice(0, cut2 === 0 ? 1 : cut2);
|
|
3117
|
+
}
|
|
3118
|
+
function rootEntryOf(root) {
|
|
3119
|
+
let end = root.length;
|
|
3120
|
+
while (end > 0 && (root[end - 1] === "/" || root[end - 1] === "\\")) end -= 1;
|
|
3121
|
+
return `${root.slice(0, end)}/index.html`;
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
// src/vite-cx-modules.ts
|
|
3125
|
+
function isRelative(text) {
|
|
3126
|
+
const cut2 = text.search(/[#?]/);
|
|
3127
|
+
const path = cut2 === -1 ? text : text.slice(0, cut2);
|
|
3128
|
+
return path === "." || path === ".." || path.startsWith("./") || path.startsWith("../");
|
|
3129
|
+
}
|
|
3130
|
+
function fileOf(id) {
|
|
3131
|
+
return filePathOf(id).replaceAll("\\", "/");
|
|
3132
|
+
}
|
|
3133
|
+
function namesOf(file) {
|
|
3134
|
+
const name = stemOf(file);
|
|
3135
|
+
return name === "index" ? [name, baseNameOf(directoryOf(file))] : [name];
|
|
3136
|
+
}
|
|
3137
|
+
function entriesNaming(declared, id) {
|
|
3138
|
+
const file = fileOf(id);
|
|
3139
|
+
return declared.ids.entries().filter(([, resolved]) => fileOf(resolved) === file).map(([entry]) => entry).toArray();
|
|
3140
|
+
}
|
|
3141
|
+
async function declaredModulesFor(context, resolver, environment) {
|
|
3142
|
+
const { cxModules } = context.options;
|
|
3143
|
+
if (cxModules.length === 0) return void 0;
|
|
3144
|
+
const known = context.state.declared.get(environment);
|
|
3145
|
+
if (known) return known;
|
|
3146
|
+
const made = resolveEntries(context, resolver);
|
|
3147
|
+
context.state.declared.set(environment, made);
|
|
3148
|
+
return made;
|
|
3149
|
+
}
|
|
3150
|
+
async function resolveOrNull(resolver, source, importer) {
|
|
3151
|
+
try {
|
|
3152
|
+
return await resolver.resolve?.(source, importer) ?? void 0;
|
|
3153
|
+
} catch {
|
|
3154
|
+
return void 0;
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
async function resolveEntries(context, resolver) {
|
|
3158
|
+
const from = rootEntryOf(context.root);
|
|
3159
|
+
const nave = await resolveOrNull(resolver, CX_SOURCE, from);
|
|
3160
|
+
const naveFile = nave === void 0 ? void 0 : fileOf(nave.id);
|
|
3161
|
+
const resolved = await Promise.all(
|
|
3162
|
+
context.options.cxModules.map(async (entry) => {
|
|
3163
|
+
const found = await resolveOrNull(resolver, entry, from);
|
|
3164
|
+
return [entry, found?.id];
|
|
3165
|
+
})
|
|
3166
|
+
);
|
|
3167
|
+
const kept = resolved.filter(
|
|
3168
|
+
([entry, id]) => entry !== CX_SOURCE && (id === void 0 || fileOf(id) !== naveFile)
|
|
3169
|
+
);
|
|
3170
|
+
const ids = new Map(kept.filter((pair) => pair[1] !== void 0));
|
|
3171
|
+
const files = new Set(ids.values().map((id) => fileOf(id)));
|
|
3172
|
+
const names = new Set(files.values().flatMap((file) => namesOf(file)));
|
|
3173
|
+
return {
|
|
3174
|
+
entries: new Set(kept.map(([entry]) => entry).filter((entry) => !isRelative(entry))),
|
|
3175
|
+
ids,
|
|
3176
|
+
files,
|
|
3177
|
+
names,
|
|
3178
|
+
textTest: textTestOf(names)
|
|
3179
|
+
};
|
|
3180
|
+
}
|
|
3181
|
+
function forgetDeclared(state, environment) {
|
|
3182
|
+
state.declared.delete(environment);
|
|
3183
|
+
const prefix = `${environment}\0`;
|
|
3184
|
+
for (const key of state.recognised.keys())
|
|
3185
|
+
if (key.startsWith(prefix)) state.recognised.delete(key);
|
|
3186
|
+
}
|
|
3187
|
+
function withoutTrailingSlashes(text) {
|
|
3188
|
+
let end = text.length;
|
|
3189
|
+
while (end > 0 && text[end - 1] === "/") end -= 1;
|
|
3190
|
+
return text.slice(0, end);
|
|
3191
|
+
}
|
|
3192
|
+
function lastSegmentOf(specifier) {
|
|
3193
|
+
const cut2 = specifier.slice(1).search(/[#?]/);
|
|
3194
|
+
const bare = withoutTrailingSlashes(cut2 === -1 ? specifier : specifier.slice(0, cut2 + 1));
|
|
3195
|
+
const segment = bare.slice(bare.lastIndexOf("/") + 1);
|
|
3196
|
+
return segment === "." || segment === ".." ? "index" : segment;
|
|
3197
|
+
}
|
|
3198
|
+
function isNamingListed(specifier, declared) {
|
|
3199
|
+
const segment = lastSegmentOf(specifier);
|
|
3200
|
+
if (declared.names.has(segment)) return true;
|
|
3201
|
+
const extension = extensionOf(segment);
|
|
3202
|
+
return extension !== "" && declared.names.has(segment.slice(0, -extension.length));
|
|
3203
|
+
}
|
|
3204
|
+
function isAboutListed(input, declared) {
|
|
3205
|
+
if (!declared) return false;
|
|
3206
|
+
return isListedFile(declared, input.id) || isMentioningDeclared(input.code, declared);
|
|
3207
|
+
}
|
|
3208
|
+
function isListedFile(declared, id) {
|
|
3209
|
+
return declared.files.has(fileOf(id));
|
|
3210
|
+
}
|
|
3211
|
+
function isMentioningDeclared(code, declared) {
|
|
3212
|
+
for (const entry of declared.entries) if (code.includes(entry)) return true;
|
|
3213
|
+
return declared.textTest?.test(code) ?? false;
|
|
3214
|
+
}
|
|
3215
|
+
function recognisedKey(environment, file, importer) {
|
|
3216
|
+
return `${environment}\0${file}\0${importer}`;
|
|
3217
|
+
}
|
|
3218
|
+
|
|
3219
|
+
// src/vite-declared-echoes.ts
|
|
3220
|
+
var ECHO_KINDS = /* @__PURE__ */ new Set([
|
|
3221
|
+
"argument",
|
|
3222
|
+
"dynamic",
|
|
3223
|
+
"own",
|
|
3224
|
+
"reference",
|
|
3225
|
+
"unknown"
|
|
3226
|
+
]);
|
|
3227
|
+
function withoutEchoes(modules) {
|
|
3228
|
+
const broken = new Set(
|
|
3229
|
+
modules.flatMap(
|
|
3230
|
+
(module) => module.problems.flatMap(
|
|
3231
|
+
(problem2) => problem2.kind === "declared" && problem2.moduleId !== void 0 && !problem2.hasNaveCx ? [fileOf(problem2.moduleId)] : []
|
|
3232
|
+
)
|
|
3233
|
+
)
|
|
3234
|
+
);
|
|
3235
|
+
const isEcho = (module) => module.onlyVia !== void 0 && [...module.onlyVia].every((file) => broken.has(file));
|
|
3236
|
+
return modules.flatMap(
|
|
3237
|
+
(module) => isEcho(module) ? module.problems.filter((problem2) => !ECHO_KINDS.has(problem2.kind)) : module.problems
|
|
3238
|
+
);
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
// src/vite-module-id.ts
|
|
3242
|
+
function isDependencyId(id) {
|
|
3243
|
+
return filePathOf(id).replaceAll("\\", "/").includes("/node_modules/");
|
|
2444
3244
|
}
|
|
2445
3245
|
|
|
2446
3246
|
// src/vite-problems.ts
|
|
@@ -2469,6 +3269,43 @@ function cut(text, limit = 40) {
|
|
|
2469
3269
|
return oneLine.length > limit ? `${oneLine.slice(0, limit)}...` : oneLine;
|
|
2470
3270
|
}
|
|
2471
3271
|
|
|
3272
|
+
// src/vite-takes-host.ts
|
|
3273
|
+
function parseOf(host, code, id) {
|
|
3274
|
+
return host.parseModule ? host.parseModule(code, id) : host.parse?.(code);
|
|
3275
|
+
}
|
|
3276
|
+
async function resolvedIds(host, source, importer) {
|
|
3277
|
+
if (host.resolveAll) return await host.resolveAll(source, importer);
|
|
3278
|
+
const resolved = await host.resolve?.(source, importer);
|
|
3279
|
+
return resolved ? [resolved.id] : [];
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
// src/vite-specifiers.ts
|
|
3283
|
+
function isTypeOnlyDeclaration(node) {
|
|
3284
|
+
if (isTypeOnly(node)) return true;
|
|
3285
|
+
return nodesAt(node, "specifiers").length > 0 && valueSpecifiersOf(node).length === 0;
|
|
3286
|
+
}
|
|
3287
|
+
function specifiersIn(program) {
|
|
3288
|
+
const found = /* @__PURE__ */ new Map();
|
|
3289
|
+
const stack = [program];
|
|
3290
|
+
while (stack.length > 0) {
|
|
3291
|
+
const node = stack.pop();
|
|
3292
|
+
const where = isTypeOnlyDeclaration(node) ? void 0 : nodeAt(node, "source");
|
|
3293
|
+
const source = staticStringOf(where);
|
|
3294
|
+
if (where !== void 0 && source !== void 0) {
|
|
3295
|
+
found.set(source, Math.min(found.get(source) ?? Infinity, where.start));
|
|
3296
|
+
}
|
|
3297
|
+
pushAll(stack, childrenOf(node));
|
|
3298
|
+
}
|
|
3299
|
+
return [...found].toSorted(([, a], [, b]) => a - b).map(([source]) => source);
|
|
3300
|
+
}
|
|
3301
|
+
function specifiersOf(host, importer) {
|
|
3302
|
+
try {
|
|
3303
|
+
return specifiersIn(parseOf(host, importer.code, importer.id));
|
|
3304
|
+
} catch {
|
|
3305
|
+
return void 0;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
|
|
2472
3309
|
// src/vite-class-map-message.ts
|
|
2473
3310
|
var CLASS_MAP_NOT_PARSED = "the module could not be read, so the atoms it names would not ship: it is a CSS Module, and the JavaScript Vite wrote for its class map did not parse. A plugin that runs after Vite's CSS step has changed that JavaScript: have that plugin leave a CSS Module's JavaScript valid.";
|
|
2474
3311
|
|
|
@@ -2513,10 +3350,11 @@ function clausesOf(takes) {
|
|
|
2513
3350
|
const passedOn = takes.some((take) => take.isPassedOn === true) ? "; where a file re-exports what it takes, import cx from @navecss/core/cx in the files that call it, call cx there in its place, and drop the re-export" : "";
|
|
2514
3351
|
return { files, listed, whole: `${wholeClause}${passedOn}` };
|
|
2515
3352
|
}
|
|
2516
|
-
function takenLine(pkg, takes,
|
|
3353
|
+
function takenLine(pkg, takes, input) {
|
|
2517
3354
|
const { files, listed, whole } = clausesOf(takes);
|
|
3355
|
+
const { hasPackageFix, rootName } = input;
|
|
2518
3356
|
const fix = hasPackageFix ? FIX : "";
|
|
2519
|
-
return `${pkg} re-exports cx, and your code takes that cx, from the package or through another package that re-exports it, in ${listed}. The build does not read calls made through what your code takes there, and the keepFor entry stands in only for the package's own calls: ${files}, import cx from @navecss/core/cx instead and call cx in its place${whole}. The build prints no cxModules entry for this, since it found none of these takes made, by an import it can read and a specifier that resolves from
|
|
3357
|
+
return `${pkg} re-exports cx, and your code takes that cx, from the package or through another package that re-exports it, in ${listed}. The build does not read calls made through what your code takes there, and the keepFor entry stands in only for the package's own calls: ${files}, import cx from @navecss/core/cx instead and call cx in its place${whole}. The build prints no cxModules entry for this, since it found none of these takes made, by an import it can read and a specifier that resolves from ${rootName}, from a module that re-exports cx from @navecss/core/cx itself and only under the name cx. Once your code makes none of these takes, the keepFor entry clears this.${fix}`;
|
|
2520
3358
|
}
|
|
2521
3359
|
function forwardLine(pkg, takes) {
|
|
2522
3360
|
const { files, listed, whole } = clausesOf(takes);
|
|
@@ -2537,6 +3375,12 @@ function isRenamedOrReached(problem2) {
|
|
|
2537
3375
|
function isSecondHop(problem2) {
|
|
2538
3376
|
return problem2.kind === "reexport" && problem2.isListable === false && problem2.pkg !== void 0;
|
|
2539
3377
|
}
|
|
3378
|
+
function isHandedOut(problem2) {
|
|
3379
|
+
return problem2.kind === "reference" && problem2.isRenamed === true && problem2.exportedAs !== void 0;
|
|
3380
|
+
}
|
|
3381
|
+
function handedOutClause(pkg) {
|
|
3382
|
+
return ` ${pkg} also gives cx out under another name, and the build does not read calls made through it: where your code imports it from ${pkg} or one of its subpaths, import cx from @navecss/core/cx instead and call cx in its place.`;
|
|
3383
|
+
}
|
|
2540
3384
|
function callsLine(pkg, problems, entry) {
|
|
2541
3385
|
if (problems.every((problem2) => problem2.kind === "own")) {
|
|
2542
3386
|
return `${pkg} names atoms of your own, which have no class, so a keepFor entry cannot make its calls produce a Nave class. The fix is the package's: it must name atoms Nave ships.`;
|
|
@@ -2547,8 +3391,20 @@ function callsLine(pkg, problems, entry) {
|
|
|
2547
3391
|
const places = count === 1 ? "1 place" : `${count} places`;
|
|
2548
3392
|
return `${pkg} calls cx.dynamic() in ${places}, and keepFor lists no atoms for it, so none of them applies a class. List the atoms those calls can take, from its documentation, under its name in ${entry}.`;
|
|
2549
3393
|
}
|
|
2550
|
-
|
|
3394
|
+
const handedOut = problems.some((problem2) => isHandedOut(problem2)) ? handedOutClause(pkg) : "";
|
|
3395
|
+
return `${pkg} is a dependency, so its code is not yours to change. List the atoms its calls can produce, from its documentation, under its name in ${entry}. The lasting fix is the package's: names chosen at run time go through cx.dynamic().${handedOut}`;
|
|
3396
|
+
}
|
|
3397
|
+
function heldLine(pkg, held2, everyAtom) {
|
|
3398
|
+
const formOf = (problem2) => {
|
|
3399
|
+
const sentence = problem2.text.replace(/\.(\s.*)?$/su, "");
|
|
3400
|
+
return problem2.construct === "" ? sentence : `${cut(problem2.construct)}: ${sentence}`;
|
|
3401
|
+
};
|
|
3402
|
+
const places = [
|
|
3403
|
+
...new Set(held2.map((problem2) => `${problem2.file} (${formOf(problem2)})`))
|
|
3404
|
+
].toSorted(compareText);
|
|
3405
|
+
return `${pkg} uses cx in ${places.join(", ")}. From there the build cannot tell whether a call of your code goes through it, and the keepFor entry does not stand in for that, so the build fails whenever these files are part of it, whatever your code takes from ${pkg}. The fix is the package's, in a release of it or a patched copy: export it by name from an ES module, as in export { cx as cn } from '@navecss/core/cx', which the build then checks wherever your code takes it. Until then, ship every atom: ${everyAtom}`;
|
|
2551
3406
|
}
|
|
3407
|
+
var EVERY_ATOM = 'see "Which atoms the build ships" in node_modules/@navecss/core/README.md.';
|
|
2552
3408
|
var LASTING_FIX = "The lasting fix is the package's: import cx from @navecss/core/cx where it is called, or re-export it from the package's entry.";
|
|
2553
3409
|
function listedLine(pkg, specifiers, configured, home) {
|
|
2554
3410
|
const array = cxModulesArray(configured, specifiers);
|
|
@@ -2596,7 +3452,8 @@ function takeLines(pkg, all, home) {
|
|
|
2596
3452
|
const lines = [];
|
|
2597
3453
|
if (takes.length > 0) {
|
|
2598
3454
|
const hasPackageFix = plain.some((problem2) => isRenamedOrReached(problem2)) || takes.some((take) => take.isReached);
|
|
2599
|
-
|
|
3455
|
+
const rootName = plain.find((problem2) => problem2.rootName !== void 0)?.rootName;
|
|
3456
|
+
lines.push(takenLine(pkg, takes, { hasPackageFix, rootName: rootName ?? "the project root" }));
|
|
2600
3457
|
}
|
|
2601
3458
|
if (hops.length > 0)
|
|
2602
3459
|
lines.push(
|
|
@@ -2610,9 +3467,12 @@ function takeLines(pkg, all, home) {
|
|
|
2610
3467
|
lines.push(callsThroughLine(pkg, [...new Set(callers)].toSorted(compareText), home));
|
|
2611
3468
|
return lines;
|
|
2612
3469
|
}
|
|
2613
|
-
function packageLines(pkg, all, configured,
|
|
3470
|
+
function packageLines(pkg, all, configured, places) {
|
|
3471
|
+
const { home, everyAtom } = places;
|
|
2614
3472
|
const isTaken = (problem2) => (problem2.takes?.length ?? 0) > 0;
|
|
2615
|
-
const
|
|
3473
|
+
const kept = all.filter((problem2) => !isTaken(problem2) && problem2.callers === void 0);
|
|
3474
|
+
const held2 = kept.filter((problem2) => problem2.isHeld === true);
|
|
3475
|
+
const problems = kept.filter((problem2) => problem2.isHeld !== true);
|
|
2616
3476
|
const entry = `${home}: keepFor: { '${pkg}': ['<atom>'] }`;
|
|
2617
3477
|
const reexports = problems.filter((problem2) => isListableReexport(problem2));
|
|
2618
3478
|
const internal = reexports.filter(
|
|
@@ -2632,6 +3492,7 @@ function packageLines(pkg, all, configured, home) {
|
|
|
2632
3492
|
lines.push(declaredLine(pkg, entries.toSorted(compareText), internal.length > 0, home));
|
|
2633
3493
|
}
|
|
2634
3494
|
if (rest.length > 0) lines.push(callsLine(pkg, rest, entry));
|
|
3495
|
+
if (held2.length > 0) lines.push(heldLine(pkg, held2, everyAtom));
|
|
2635
3496
|
const listed = named.length > 0 ? listedLine(pkg, named, configured, home) : void 0;
|
|
2636
3497
|
if (listed !== void 0) lines.push(listed);
|
|
2637
3498
|
if (internal.length > 0) {
|
|
@@ -2647,6 +3508,951 @@ function packageLines(pkg, all, configured, home) {
|
|
|
2647
3508
|
return lines;
|
|
2648
3509
|
}
|
|
2649
3510
|
|
|
3511
|
+
// src/vite-dependency-reexports.ts
|
|
3512
|
+
async function isResolvingTo(ctx, input) {
|
|
3513
|
+
try {
|
|
3514
|
+
const resolved = await resolvedIds(ctx, input.specifier, input.from);
|
|
3515
|
+
return resolved.some((id) => fileOf(id) === input.file);
|
|
3516
|
+
} catch {
|
|
3517
|
+
return false;
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
function importersOf(ctx, id) {
|
|
3521
|
+
const info = ctx.getModuleInfo?.(id);
|
|
3522
|
+
return [.../* @__PURE__ */ new Set([...info?.importers ?? [], ...info?.dynamicImporters ?? []])];
|
|
3523
|
+
}
|
|
3524
|
+
async function specifiersWritten(ctx, input) {
|
|
3525
|
+
const { file, importer } = input;
|
|
3526
|
+
const code = ctx.getModuleInfo?.(importer)?.code;
|
|
3527
|
+
if (code === null || code === void 0) return [];
|
|
3528
|
+
const written = specifiersOf(ctx, { id: importer, code }) ?? [];
|
|
3529
|
+
const found = [];
|
|
3530
|
+
for (const specifier of written) {
|
|
3531
|
+
if (await isResolvingTo(ctx, { file, from: importer, specifier })) found.push(specifier);
|
|
3532
|
+
}
|
|
3533
|
+
return found;
|
|
3534
|
+
}
|
|
3535
|
+
async function specifiersInto(ctx, context, input) {
|
|
3536
|
+
const found = /* @__PURE__ */ new Set();
|
|
3537
|
+
for (const importer of importersOf(ctx, input.id)) {
|
|
3538
|
+
const owner = isDependencyId(importer) ? await context.packageOf(importer) : void 0;
|
|
3539
|
+
if (owner === input.pkg) continue;
|
|
3540
|
+
const written = await specifiersWritten(ctx, { file: fileOf(input.id), importer });
|
|
3541
|
+
for (const specifier of written) found.add(specifier);
|
|
3542
|
+
}
|
|
3543
|
+
return found.values().toArray().toSorted(compareText);
|
|
3544
|
+
}
|
|
3545
|
+
async function clearingSpecifier(ctx, context, input) {
|
|
3546
|
+
const from = rootEntryOf(context.root);
|
|
3547
|
+
const file = fileOf(input.id);
|
|
3548
|
+
if (await isResolvingTo(ctx, { file, from, specifier: input.pkg })) return input.pkg;
|
|
3549
|
+
const specifiers = await specifiersInto(ctx, context, input);
|
|
3550
|
+
for (const specifier of specifiers) {
|
|
3551
|
+
if (await isResolvingTo(ctx, { file, from, specifier })) return specifier;
|
|
3552
|
+
}
|
|
3553
|
+
return void 0;
|
|
3554
|
+
}
|
|
3555
|
+
async function withClearingSpecifiers(ctx, context, problems) {
|
|
3556
|
+
const asked = /* @__PURE__ */ new Map();
|
|
3557
|
+
const clearing = (pkg, id) => {
|
|
3558
|
+
const known = asked.get(id);
|
|
3559
|
+
if (known) return known;
|
|
3560
|
+
const answer = clearingSpecifier(ctx, context, { id, pkg });
|
|
3561
|
+
asked.set(id, answer);
|
|
3562
|
+
return answer;
|
|
3563
|
+
};
|
|
3564
|
+
const entriesOf = async (id) => {
|
|
3565
|
+
const declared = await declaredModulesFor(context, ctx, ctx.environment.name);
|
|
3566
|
+
return declared ? entriesNaming(declared, id) : [];
|
|
3567
|
+
};
|
|
3568
|
+
const renamed = new Set(
|
|
3569
|
+
problems.flatMap(
|
|
3570
|
+
(problem2) => problem2.isRenamed === true && problem2.moduleId !== void 0 ? [problem2.moduleId] : []
|
|
3571
|
+
)
|
|
3572
|
+
);
|
|
3573
|
+
return await Promise.all(
|
|
3574
|
+
problems.map(async (problem2) => {
|
|
3575
|
+
const { moduleId, pkg } = problem2;
|
|
3576
|
+
if (pkg === void 0 || moduleId === void 0) return problem2;
|
|
3577
|
+
if (problem2.kind === "declared") return { ...problem2, entries: await entriesOf(moduleId) };
|
|
3578
|
+
if (!isListableReexport(problem2)) return problem2;
|
|
3579
|
+
if (renamed.has(moduleId)) return { ...problem2, isRenamed: true };
|
|
3580
|
+
const specifier = await clearing(pkg, moduleId);
|
|
3581
|
+
return specifier === void 0 ? problem2 : { ...problem2, specifier };
|
|
3582
|
+
})
|
|
3583
|
+
);
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
// src/vite-cx-reexported.ts
|
|
3587
|
+
function declaredNames2(pattern) {
|
|
3588
|
+
const found = [];
|
|
3589
|
+
const stack = pattern ? [pattern] : [];
|
|
3590
|
+
while (stack.length > 0) {
|
|
3591
|
+
const node = stack.pop();
|
|
3592
|
+
if (node.type === "Identifier") {
|
|
3593
|
+
found.push(stringAt(node, "name") ?? "");
|
|
3594
|
+
} else if (node.type === "AssignmentPattern") {
|
|
3595
|
+
pushAll(
|
|
3596
|
+
stack,
|
|
3597
|
+
[nodeAt(node, "left")].filter((part) => part !== void 0)
|
|
3598
|
+
);
|
|
3599
|
+
} else {
|
|
3600
|
+
const single = ["argument", "value"].map((key) => nodeAt(node, key));
|
|
3601
|
+
const lists = ["properties", "elements"].flatMap((key) => nodesAt(node, key));
|
|
3602
|
+
pushAll(
|
|
3603
|
+
stack,
|
|
3604
|
+
single.filter((part) => part !== void 0)
|
|
3605
|
+
);
|
|
3606
|
+
pushAll(stack, lists);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
return found;
|
|
3610
|
+
}
|
|
3611
|
+
function ownExports(program) {
|
|
3612
|
+
const found = /* @__PURE__ */ new Set();
|
|
3613
|
+
for (const statement of nodesAt(program, "body")) {
|
|
3614
|
+
const namespace = statement.type === "ExportAllDeclaration" ? exportNameOf(nodeAt(statement, "exported")) : void 0;
|
|
3615
|
+
if (namespace !== void 0) found.add(namespace);
|
|
3616
|
+
if (statement.type !== "ExportNamedDeclaration") continue;
|
|
3617
|
+
const declaration = nodeAt(statement, "declaration");
|
|
3618
|
+
const declared = nodesAt(declaration ?? statement, "declarations").flatMap(
|
|
3619
|
+
(declarator) => declaredNames2(nodeAt(declarator, "id"))
|
|
3620
|
+
);
|
|
3621
|
+
for (const name of [...declared, ...declaredNames2(declaration && nodeAt(declaration, "id"))]) {
|
|
3622
|
+
found.add(name);
|
|
3623
|
+
}
|
|
3624
|
+
for (const specifier of nodesAt(statement, "specifiers")) {
|
|
3625
|
+
const name = exportNameOf(nodeAt(specifier, "exported"));
|
|
3626
|
+
if (name !== void 0) found.add(name);
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
return found;
|
|
3630
|
+
}
|
|
3631
|
+
function exportedBy(node, source, own) {
|
|
3632
|
+
const from = staticStringOf(nodeAt(node, "source"));
|
|
3633
|
+
if (from === void 0 || !source.reaches.has(from)) return [];
|
|
3634
|
+
if (node.type === "ExportAllDeclaration") {
|
|
3635
|
+
const namespace = exportNameOf(nodeAt(node, "exported"));
|
|
3636
|
+
if (namespace !== void 0) return [namespace];
|
|
3637
|
+
return source.names.values().filter((name) => name !== "default" && !own.has(name) && !source.rivals.has(name)).toArray();
|
|
3638
|
+
}
|
|
3639
|
+
return nodesAt(node, "specifiers").flatMap((specifier) => {
|
|
3640
|
+
const local = exportNameOf(nodeAt(specifier, "local"));
|
|
3641
|
+
const exported = exportNameOf(nodeAt(specifier, "exported"));
|
|
3642
|
+
return local !== void 0 && exported !== void 0 && source.names.has(local) ? [exported] : [];
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
function isImportedFrom(binding, source) {
|
|
3646
|
+
if (binding?.kind !== "import" || binding.source === void 0) return false;
|
|
3647
|
+
if (!source.reaches.has(binding.source)) return false;
|
|
3648
|
+
return binding.imported === "*" || source.names.has(binding.imported ?? "");
|
|
3649
|
+
}
|
|
3650
|
+
function starSources(program) {
|
|
3651
|
+
return nodesAt(program, "body").flatMap((statement) => {
|
|
3652
|
+
const source = staticStringOf(nodeAt(statement, "source"));
|
|
3653
|
+
const isStar = statement.type === "ExportAllDeclaration" && !nodeAt(statement, "exported");
|
|
3654
|
+
return isStar && source !== void 0 ? [source] : [];
|
|
3655
|
+
});
|
|
3656
|
+
}
|
|
3657
|
+
function reexportedNames(program, source) {
|
|
3658
|
+
const found = /* @__PURE__ */ new Set();
|
|
3659
|
+
const own = ownExports(program);
|
|
3660
|
+
const stack = [program];
|
|
3661
|
+
while (stack.length > 0) {
|
|
3662
|
+
const node = stack.pop();
|
|
3663
|
+
if (node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") {
|
|
3664
|
+
for (const name of exportedBy(node, source, own)) found.add(name);
|
|
3665
|
+
}
|
|
3666
|
+
pushAll(stack, childrenOf(node));
|
|
3667
|
+
}
|
|
3668
|
+
const analysis = analyze(program);
|
|
3669
|
+
for (const reference2 of analysis.references) {
|
|
3670
|
+
if (!isImportedFrom(reference2.binding, source)) continue;
|
|
3671
|
+
for (const name of flowOf(analysis, reference2.node).names) found.add(name);
|
|
3672
|
+
}
|
|
3673
|
+
return [...found];
|
|
3674
|
+
}
|
|
3675
|
+
|
|
3676
|
+
// src/vite-cx-star-exports.ts
|
|
3677
|
+
function resolvedFiles(ctx, resolutions, input) {
|
|
3678
|
+
const key = `${input.id}\0${input.specifier}`;
|
|
3679
|
+
const known = resolutions.get(key);
|
|
3680
|
+
if (known) return known;
|
|
3681
|
+
const asked = (async () => {
|
|
3682
|
+
try {
|
|
3683
|
+
const ids = await resolvedIds(ctx, input.specifier, input.id);
|
|
3684
|
+
return ids.map((id) => fileOf(id));
|
|
3685
|
+
} catch {
|
|
3686
|
+
return [];
|
|
3687
|
+
}
|
|
3688
|
+
})();
|
|
3689
|
+
resolutions.set(key, asked);
|
|
3690
|
+
return asked;
|
|
3691
|
+
}
|
|
3692
|
+
function ownNamesOf(program, file, cxExports) {
|
|
3693
|
+
const found = { names: ownExports(program), cx: /* @__PURE__ */ new Set() };
|
|
3694
|
+
for (const name of found.names) {
|
|
3695
|
+
if (cxExports.get(file)?.has(name)) found.cx.add(name);
|
|
3696
|
+
}
|
|
3697
|
+
return found;
|
|
3698
|
+
}
|
|
3699
|
+
function unreadProgram(ctx, input) {
|
|
3700
|
+
const { file, seen } = input;
|
|
3701
|
+
const code = ctx.getModuleInfo?.(file)?.code;
|
|
3702
|
+
const isUnread = !seen.has(file) && typeof code === "string";
|
|
3703
|
+
seen.add(file);
|
|
3704
|
+
return isUnread ? parseOf(ctx, code, file) : void 0;
|
|
3705
|
+
}
|
|
3706
|
+
function addBelow(found, belows) {
|
|
3707
|
+
for (const below of belows) {
|
|
3708
|
+
for (const name of below.cx) {
|
|
3709
|
+
found.names.add(name);
|
|
3710
|
+
found.cx.add(name);
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
const first2 = belows.at(0)?.names ?? /* @__PURE__ */ new Set();
|
|
3714
|
+
for (const name of first2) {
|
|
3715
|
+
if (belows.every((below) => below.names.has(name))) found.names.add(name);
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
function rivalsIn(exported) {
|
|
3719
|
+
return new Set([...exported.names].filter((name) => !exported.cx.has(name)));
|
|
3720
|
+
}
|
|
3721
|
+
async function addStars(ctx, input) {
|
|
3722
|
+
const { found, file, program, walk } = input;
|
|
3723
|
+
for (const specifier of starSources(program)) {
|
|
3724
|
+
const stars = await resolvedFiles(ctx, walk.resolutions, { id: file, specifier });
|
|
3725
|
+
const belows = [];
|
|
3726
|
+
for (const star of stars) {
|
|
3727
|
+
const branch = stars.length > 1 ? { ...walk, seen: new Set(walk.seen) } : walk;
|
|
3728
|
+
belows.push(await exportsOf(ctx, { file: star, walk: branch }));
|
|
3729
|
+
}
|
|
3730
|
+
addBelow(found, belows);
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
async function exportsOf(ctx, input) {
|
|
3734
|
+
const { file, walk } = input;
|
|
3735
|
+
const program = unreadProgram(ctx, { file, seen: walk.seen });
|
|
3736
|
+
if (!program) return { names: /* @__PURE__ */ new Set(), cx: /* @__PURE__ */ new Set() };
|
|
3737
|
+
const found = ownNamesOf(program, file, walk.cxExports);
|
|
3738
|
+
await addStars(ctx, { found, file, program, walk });
|
|
3739
|
+
return found;
|
|
3740
|
+
}
|
|
3741
|
+
async function rivalsOf(ctx, input) {
|
|
3742
|
+
const { cxExports, id, program, reaches, resolutions } = input;
|
|
3743
|
+
const rivals = /* @__PURE__ */ new Set();
|
|
3744
|
+
const others = starSources(program).filter((text) => !reaches.has(text));
|
|
3745
|
+
for (const specifier of others) {
|
|
3746
|
+
const files = await resolvedFiles(ctx, resolutions, { id, specifier });
|
|
3747
|
+
const rivalsPerFile = [];
|
|
3748
|
+
for (const file of files) {
|
|
3749
|
+
const walk = { cxExports, resolutions, seen: /* @__PURE__ */ new Set() };
|
|
3750
|
+
rivalsPerFile.push(rivalsIn(await exportsOf(ctx, { file, walk })));
|
|
3751
|
+
}
|
|
3752
|
+
const [first2 = /* @__PURE__ */ new Set()] = rivalsPerFile;
|
|
3753
|
+
for (const name of first2) {
|
|
3754
|
+
if (rivalsPerFile.every((found) => found.has(name))) rivals.add(name);
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
return rivals;
|
|
3758
|
+
}
|
|
3759
|
+
|
|
3760
|
+
// src/vite-require-takes.ts
|
|
3761
|
+
var WHOLE = { shape: "unreadable", names: [] };
|
|
3762
|
+
function held(specifier) {
|
|
3763
|
+
return {
|
|
3764
|
+
...WHOLE,
|
|
3765
|
+
isHeld: true,
|
|
3766
|
+
form: `requires ${specifier} and uses what it returns where the build cannot follow it`
|
|
3767
|
+
};
|
|
3768
|
+
}
|
|
3769
|
+
function isCreateRequireCall(node) {
|
|
3770
|
+
if (node?.type !== "CallExpression") return false;
|
|
3771
|
+
const callee = nodeAt(node, "callee");
|
|
3772
|
+
if (isName(callee, "createRequire")) return true;
|
|
3773
|
+
return callee?.type === "MemberExpression" && isName(nodeAt(callee, "property"), "createRequire");
|
|
3774
|
+
}
|
|
3775
|
+
function nodesIn(program) {
|
|
3776
|
+
const found = [];
|
|
3777
|
+
const stack = [program];
|
|
3778
|
+
while (stack.length > 0) {
|
|
3779
|
+
const node = stack.pop();
|
|
3780
|
+
found.push(node);
|
|
3781
|
+
pushAll(stack, childrenOf(node));
|
|
3782
|
+
}
|
|
3783
|
+
return found;
|
|
3784
|
+
}
|
|
3785
|
+
function requireNamesIn(nodes) {
|
|
3786
|
+
const names = /* @__PURE__ */ new Set(["require"]);
|
|
3787
|
+
for (const node of nodes) {
|
|
3788
|
+
const id = nodeAt(node, "id");
|
|
3789
|
+
if (node.type !== "VariableDeclarator" || id?.type !== "Identifier") continue;
|
|
3790
|
+
if (isCreateRequireCall(nodeAt(node, "init"))) names.add(id.name);
|
|
3791
|
+
}
|
|
3792
|
+
return names;
|
|
3793
|
+
}
|
|
3794
|
+
function equalsSpecifierOf(node) {
|
|
3795
|
+
const reference2 = nodeAt(node, "moduleReference");
|
|
3796
|
+
if (node.importKind === "type" || reference2?.type !== "TSExternalModuleReference") {
|
|
3797
|
+
return void 0;
|
|
3798
|
+
}
|
|
3799
|
+
return staticStringOf(nodeAt(reference2, "expression"));
|
|
3800
|
+
}
|
|
3801
|
+
function isRequireCallee(callee, requireNames) {
|
|
3802
|
+
if (callee?.type === "Identifier") return requireNames.has(callee.name);
|
|
3803
|
+
return isCreateRequireCall(callee);
|
|
3804
|
+
}
|
|
3805
|
+
function requiredBy(node, requireNames) {
|
|
3806
|
+
if (node.type === "TSImportEqualsDeclaration") return equalsSpecifierOf(node);
|
|
3807
|
+
if (node.type !== "CallExpression") return void 0;
|
|
3808
|
+
const args = nodesAt(node, "arguments");
|
|
3809
|
+
const isRequire = isRequireCallee(nodeAt(node, "callee"), requireNames);
|
|
3810
|
+
return isRequire && args.length === 1 ? staticStringOf(args[0]) : void 0;
|
|
3811
|
+
}
|
|
3812
|
+
function requireCallsOf(program) {
|
|
3813
|
+
const nodes = nodesIn(program);
|
|
3814
|
+
const requireNames = requireNamesIn(nodes);
|
|
3815
|
+
return nodes.flatMap((node) => {
|
|
3816
|
+
const specifier = requiredBy(node, requireNames);
|
|
3817
|
+
return specifier === void 0 ? [] : [{ node, specifier }];
|
|
3818
|
+
});
|
|
3819
|
+
}
|
|
3820
|
+
function requireSpecifiersIn(program) {
|
|
3821
|
+
return [...new Set(requireCallsOf(program).map(({ specifier }) => specifier))];
|
|
3822
|
+
}
|
|
3823
|
+
function assignmentOf(statement) {
|
|
3824
|
+
if (statement.type !== "ExpressionStatement") return void 0;
|
|
3825
|
+
const expression = nodeAt(statement, "expression");
|
|
3826
|
+
if (expression?.type !== "AssignmentExpression" || expression.operator !== "=") return void 0;
|
|
3827
|
+
return { left: nodeAt(expression, "left"), right: nodeAt(expression, "right") };
|
|
3828
|
+
}
|
|
3829
|
+
function wholeForwardOf(left, right, input) {
|
|
3830
|
+
if (right === void 0 || !input.requires.has(right) || !isModuleExports(left)) return void 0;
|
|
3831
|
+
const given = input.names === void 0 ? [] : input.names.values().toArray();
|
|
3832
|
+
return { given, require: right, takes: [{ shape: "star", names: [], isForward: true }] };
|
|
3833
|
+
}
|
|
3834
|
+
function memberForwardOf(left, right, input) {
|
|
3835
|
+
const as = exportsMemberOf(left);
|
|
3836
|
+
const member = memberOf(right);
|
|
3837
|
+
if (as === void 0 || !member || !input.requires.has(member.object)) return void 0;
|
|
3838
|
+
if (!isCxName(input.names, member.name)) return void 0;
|
|
3839
|
+
const taken = { shape: "names", names: [member.name], isPassedOn: true, isForward: true };
|
|
3840
|
+
return { given: [as], require: member.object, takes: [taken] };
|
|
3841
|
+
}
|
|
3842
|
+
function forwardOf(statement, input) {
|
|
3843
|
+
const assignment = assignmentOf(statement);
|
|
3844
|
+
if (!assignment) return starForwardOf(statement, input);
|
|
3845
|
+
const { left, right } = assignment;
|
|
3846
|
+
return wholeForwardOf(left, right, input) ?? memberForwardOf(left, right, input);
|
|
3847
|
+
}
|
|
3848
|
+
function isMarkerWrite(statement) {
|
|
3849
|
+
const assignment = assignmentOf(statement);
|
|
3850
|
+
if (assignment) return exportsMemberOf(assignment.left) === "__esModule";
|
|
3851
|
+
const define = definePropertyOf(statement);
|
|
3852
|
+
return define !== void 0 && isExportsObject(define.target) && define.as === "__esModule";
|
|
3853
|
+
}
|
|
3854
|
+
function isMarkedEsModule(program) {
|
|
3855
|
+
return nodesAt(program, "body").some((statement) => isMarkerWrite(statement));
|
|
3856
|
+
}
|
|
3857
|
+
function forwardsIn(program, input) {
|
|
3858
|
+
const written = nodesAt(program, "body").flatMap((statement) => {
|
|
3859
|
+
const forward = forwardOf(statement, input);
|
|
3860
|
+
return forward ? [forward] : [];
|
|
3861
|
+
});
|
|
3862
|
+
return [...written, ...boundForwardsOf(program, input)];
|
|
3863
|
+
}
|
|
3864
|
+
function requireTakesIn(program, input) {
|
|
3865
|
+
const requires = requireCallsOf(program).filter(({ specifier }) => input.reaches.has(specifier));
|
|
3866
|
+
if (requires.length === 0) return { given: [], takes: [] };
|
|
3867
|
+
let analysis;
|
|
3868
|
+
const forwardInput = {
|
|
3869
|
+
analysis: () => analysis ??= analyze(program),
|
|
3870
|
+
names: input.names,
|
|
3871
|
+
requires: new Set(requires.map(({ node }) => node))
|
|
3872
|
+
};
|
|
3873
|
+
const forwards = input.readsForwards ? forwardsIn(program, forwardInput) : [];
|
|
3874
|
+
const forwarded = new Set(forwards.map((forward) => forward.require));
|
|
3875
|
+
const takes = forwards.flatMap((forward) => forward.takes);
|
|
3876
|
+
const others = requires.filter(({ node }) => !forwarded.has(node));
|
|
3877
|
+
if (input.readsForwards) {
|
|
3878
|
+
const analysisOf = forwardInput.analysis();
|
|
3879
|
+
for (const { node, specifier } of others) {
|
|
3880
|
+
takes.push(isUsedAsCallsOnly(analysisOf, node, input.names) ? WHOLE : held(specifier));
|
|
3881
|
+
}
|
|
3882
|
+
} else if (others.length > 0) takes.push(WHOLE);
|
|
3883
|
+
const given = new Set(forwards.flatMap((forward) => forward.given));
|
|
3884
|
+
if (given.size > 0 && !isMarkedEsModule(program)) given.add("default");
|
|
3885
|
+
return { given: [...given], takes };
|
|
3886
|
+
}
|
|
3887
|
+
|
|
3888
|
+
// src/vite-listed-holders.ts
|
|
3889
|
+
async function reachingSpecifiers(ctx, input) {
|
|
3890
|
+
const { code, file, id, resolutions } = input;
|
|
3891
|
+
const program = parseOf(ctx, code, id);
|
|
3892
|
+
if (!program) return void 0;
|
|
3893
|
+
const reachingOf = async (specifiers) => {
|
|
3894
|
+
const reaching = /* @__PURE__ */ new Set();
|
|
3895
|
+
for (const specifier of specifiers) {
|
|
3896
|
+
const files = await resolvedFiles(ctx, resolutions, { id, specifier });
|
|
3897
|
+
if (files.includes(file)) reaching.add(specifier);
|
|
3898
|
+
}
|
|
3899
|
+
return reaching;
|
|
3900
|
+
};
|
|
3901
|
+
const reaches = await reachingOf(specifiersIn(program));
|
|
3902
|
+
const requires = await reachingOf(requireSpecifiersIn(program));
|
|
3903
|
+
return { program, reaches, requires };
|
|
3904
|
+
}
|
|
3905
|
+
async function reexportedBy(ctx, input) {
|
|
3906
|
+
const code = ctx.getModuleInfo?.(input.id)?.code;
|
|
3907
|
+
if (code === null || code === void 0) return [];
|
|
3908
|
+
try {
|
|
3909
|
+
const read = await reachingSpecifiers(ctx, { ...input, code });
|
|
3910
|
+
if (!read) return [];
|
|
3911
|
+
const { program, reaches, requires } = read;
|
|
3912
|
+
const forwarded = requires.size === 0 ? [] : requireTakesIn(program, { names: input.names, reaches: requires, readsForwards: true }).given;
|
|
3913
|
+
if (reaches.size === 0) return forwarded;
|
|
3914
|
+
const rivals = await rivalsOf(ctx, { ...input, program, reaches });
|
|
3915
|
+
const reexported2 = reexportedNames(program, { names: input.names, reaches, rivals });
|
|
3916
|
+
return [.../* @__PURE__ */ new Set([...reexported2, ...forwarded])];
|
|
3917
|
+
} catch {
|
|
3918
|
+
return [];
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
async function reexportsOf(ctx, input) {
|
|
3922
|
+
const importers = importersOf(ctx, input.id).filter((importer) => isDependencyId(importer));
|
|
3923
|
+
const found = /* @__PURE__ */ new Map();
|
|
3924
|
+
for (const importer of importers) {
|
|
3925
|
+
const added = await reexportedBy(ctx, { ...input, file: fileOf(input.id), id: importer });
|
|
3926
|
+
if (added.length > 0) found.set(importer, added);
|
|
3927
|
+
}
|
|
3928
|
+
return found;
|
|
3929
|
+
}
|
|
3930
|
+
async function holdersOf(ctx, origin) {
|
|
3931
|
+
const held2 = /* @__PURE__ */ new Map([[origin.id, origin.names]]);
|
|
3932
|
+
const queue = [origin.id];
|
|
3933
|
+
while (queue.length > 0) {
|
|
3934
|
+
const id = queue.shift();
|
|
3935
|
+
const reexports = await reexportsOf(ctx, {
|
|
3936
|
+
cxExports: origin.cxExports,
|
|
3937
|
+
id,
|
|
3938
|
+
names: held2.get(id),
|
|
3939
|
+
resolutions: origin.resolutions
|
|
3940
|
+
});
|
|
3941
|
+
for (const [importer, added] of reexports) {
|
|
3942
|
+
const known = held2.get(importer) ?? /* @__PURE__ */ new Set();
|
|
3943
|
+
const isNew = importer !== origin.id && added.some((name) => !known.has(name));
|
|
3944
|
+
if (isNew) {
|
|
3945
|
+
held2.set(importer, /* @__PURE__ */ new Set([...known, ...added]));
|
|
3946
|
+
queue.push(importer);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
return held2.entries().map(([id, names]) => ({ id, names, isReached: id !== origin.id })).toArray();
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3953
|
+
// src/vite-cx-reference-names.ts
|
|
3954
|
+
function leftmostName(node) {
|
|
3955
|
+
let current = node;
|
|
3956
|
+
while (current?.type === "TSQualifiedName") current = nodeAt(current, "left");
|
|
3957
|
+
return current?.type === "Identifier" ? current.name : void 0;
|
|
3958
|
+
}
|
|
3959
|
+
function typeNameOf(node) {
|
|
3960
|
+
if (node.type === "TSTypeQuery") return leftmostName(nodeAt(node, "exprName"));
|
|
3961
|
+
return node.type === "TSTypeReference" ? leftmostName(nodeAt(node, "typeName")) : void 0;
|
|
3962
|
+
}
|
|
3963
|
+
function jsxNameOf(node) {
|
|
3964
|
+
if (node.type !== "JSXOpeningElement") return void 0;
|
|
3965
|
+
let current = nodeAt(node, "name");
|
|
3966
|
+
while (current?.type === "JSXMemberExpression") current = nodeAt(current, "object");
|
|
3967
|
+
return current?.type === "JSXIdentifier" ? current.name : void 0;
|
|
3968
|
+
}
|
|
3969
|
+
function jsxMemberOf(node) {
|
|
3970
|
+
if (node.type !== "JSXOpeningElement") return void 0;
|
|
3971
|
+
let current = nodeAt(node, "name");
|
|
3972
|
+
while (current?.type === "JSXMemberExpression") {
|
|
3973
|
+
const object = nodeAt(current, "object");
|
|
3974
|
+
if (object?.type === "JSXIdentifier") {
|
|
3975
|
+
const member = nodeAt(current, "property")?.name;
|
|
3976
|
+
return typeof member === "string" ? { member, name: object.name } : void 0;
|
|
3977
|
+
}
|
|
3978
|
+
current = object;
|
|
3979
|
+
}
|
|
3980
|
+
return void 0;
|
|
3981
|
+
}
|
|
3982
|
+
function jsxMembersIn(program) {
|
|
3983
|
+
const found = /* @__PURE__ */ new Map();
|
|
3984
|
+
const stack = [program];
|
|
3985
|
+
while (stack.length > 0) {
|
|
3986
|
+
const node = stack.pop();
|
|
3987
|
+
const read = jsxMemberOf(node);
|
|
3988
|
+
if (read) found.set(read.name, (found.get(read.name) ?? /* @__PURE__ */ new Set()).add(read.member));
|
|
3989
|
+
pushAll(stack, childrenOf(node));
|
|
3990
|
+
}
|
|
3991
|
+
return found;
|
|
3992
|
+
}
|
|
3993
|
+
function namesIn(program, nameOf) {
|
|
3994
|
+
const found = /* @__PURE__ */ new Set();
|
|
3995
|
+
const stack = [program];
|
|
3996
|
+
while (stack.length > 0) {
|
|
3997
|
+
const node = stack.pop();
|
|
3998
|
+
const name = nameOf(node);
|
|
3999
|
+
if (name !== void 0) found.add(name);
|
|
4000
|
+
pushAll(stack, childrenOf(node));
|
|
4001
|
+
}
|
|
4002
|
+
return found;
|
|
4003
|
+
}
|
|
4004
|
+
|
|
4005
|
+
// src/vite-cx-take-passing.ts
|
|
4006
|
+
function usesOf(analysis, source, specifier) {
|
|
4007
|
+
const local = exportNameOf(nodeAt(specifier, "local"));
|
|
4008
|
+
return analysis.references.filter(
|
|
4009
|
+
({ binding }) => binding?.kind === "import" && binding.source === source && binding.name === local
|
|
4010
|
+
);
|
|
4011
|
+
}
|
|
4012
|
+
function isPure(flow) {
|
|
4013
|
+
return flow.names.size > 0 && !flow.isCalled && !flow.isUnbound;
|
|
4014
|
+
}
|
|
4015
|
+
function passingOf(analysis, source, specifier) {
|
|
4016
|
+
const flows = usesOf(analysis, source, specifier).map((use) => flowOf(analysis, use.node));
|
|
4017
|
+
if (flows.every((flow) => flow.names.size === 0)) return {};
|
|
4018
|
+
return flows.every((flow) => isPure(flow)) ? { isForward: true, isPassedOn: true } : { isPassedOn: true };
|
|
4019
|
+
}
|
|
4020
|
+
function isCarriedOn(analysis, source, specifier) {
|
|
4021
|
+
return usesOf(analysis, source, specifier).some((use) => flowOf(analysis, use.node).isUnbound);
|
|
4022
|
+
}
|
|
4023
|
+
function isValueCarried(analysis, node) {
|
|
4024
|
+
const flow = flowOf(analysis, node);
|
|
4025
|
+
return flow.isUnbound || flow.names.size > 0;
|
|
4026
|
+
}
|
|
4027
|
+
function isExportedDeclarator2(analysis, declarator) {
|
|
4028
|
+
const declaration = analysis.parentOf.get(declarator);
|
|
4029
|
+
const statement = declaration && analysis.parentOf.get(declaration);
|
|
4030
|
+
return statement?.type === "ExportNamedDeclaration";
|
|
4031
|
+
}
|
|
4032
|
+
function isBoundNameCarried(analysis, property) {
|
|
4033
|
+
const value = nodeAt(property, "value");
|
|
4034
|
+
const declarator = analysis.parentOf.get(analysis.parentOf.get(property) ?? property);
|
|
4035
|
+
const alias = value?.type === "Identifier" ? analysis.bindingDeclaredBy(value) : void 0;
|
|
4036
|
+
if (!alias || declarator?.type !== "VariableDeclarator" || isExportedDeclarator2(analysis, declarator)) {
|
|
4037
|
+
return true;
|
|
4038
|
+
}
|
|
4039
|
+
return analysis.references.some(
|
|
4040
|
+
(use) => use.binding === alias && isValueCarried(analysis, use.node)
|
|
4041
|
+
);
|
|
4042
|
+
}
|
|
4043
|
+
function isPatternCarried(analysis, pattern, names) {
|
|
4044
|
+
return nodesAt(pattern, "properties").some((property) => {
|
|
4045
|
+
const key = propertyNameOf(nodeAt(property, "key"), property.computed === true);
|
|
4046
|
+
if (key === void 0) return false;
|
|
4047
|
+
if (INHERITED_NAMES.has(key)) return true;
|
|
4048
|
+
return isCxName(names, key) && isBoundNameCarried(analysis, property);
|
|
4049
|
+
});
|
|
4050
|
+
}
|
|
4051
|
+
function isCalledWithReceiver2(analysis, member) {
|
|
4052
|
+
let top = unwrapped(analysis, member);
|
|
4053
|
+
let parent = analysis.parentOf.get(top);
|
|
4054
|
+
while (parent?.type === "ChainExpression") {
|
|
4055
|
+
top = unwrapped(analysis, parent);
|
|
4056
|
+
parent = analysis.parentOf.get(top);
|
|
4057
|
+
}
|
|
4058
|
+
if (parent?.type === "CallExpression") return nodeAt(parent, "callee") === top;
|
|
4059
|
+
return parent?.type === "TaggedTemplateExpression" && nodeAt(parent, "tag") === top;
|
|
4060
|
+
}
|
|
4061
|
+
function isUseCarried(analysis, node, names) {
|
|
4062
|
+
const read = memberReadOf({ analysis }, node);
|
|
4063
|
+
if (read) {
|
|
4064
|
+
if (read.key === void 0) return isCalledWithReceiver2(analysis, read.member);
|
|
4065
|
+
if (INHERITED_NAMES.has(read.key)) return true;
|
|
4066
|
+
if (!isCxName(names, read.key)) return isCalledWithReceiver2(analysis, read.member);
|
|
4067
|
+
return isValueCarried(analysis, read.member);
|
|
4068
|
+
}
|
|
4069
|
+
const pattern = patternDestructuring({ analysis }, node);
|
|
4070
|
+
return pattern?.type === "ObjectPattern" && isPatternCarried(analysis, pattern, names);
|
|
4071
|
+
}
|
|
4072
|
+
function heldNamespace(analysis, references, names, source) {
|
|
4073
|
+
const isCarried = references.some(({ node }) => isUseCarried(analysis, node, names));
|
|
4074
|
+
return isCarried ? withHeld({ shape: "namespace", names: [] }, source) : void 0;
|
|
4075
|
+
}
|
|
4076
|
+
function withHeld(taken, source) {
|
|
4077
|
+
const isWhole = taken.names.length === 0 && taken.isForward !== true;
|
|
4078
|
+
if (!isWhole || taken.shape === "names" || taken.shape === "star") return taken;
|
|
4079
|
+
const form = taken.shape === "namespace" ? `uses the namespace of ${source} where the build cannot follow it` : `imports ${source} and uses it where the build cannot follow it`;
|
|
4080
|
+
return { ...taken, isHeld: true, form };
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
// src/vite-cx-takes.ts
|
|
4084
|
+
var UNREADABLE = { shape: "unreadable", names: [] };
|
|
4085
|
+
function namespaceTakes(analysis, references, names) {
|
|
4086
|
+
const found = /* @__PURE__ */ new Set();
|
|
4087
|
+
for (const reference2 of references) {
|
|
4088
|
+
const taken = referenceTakes(analysis, reference2.node, names);
|
|
4089
|
+
if (taken === void 0) return { shape: "namespace", names: [] };
|
|
4090
|
+
for (const name of taken) found.add(name);
|
|
4091
|
+
}
|
|
4092
|
+
return found.size === 0 ? void 0 : { shape: "namespace", names: [...found] };
|
|
4093
|
+
}
|
|
4094
|
+
function referencesTo(analysis, source, specifier) {
|
|
4095
|
+
const local = exportNameOf(nodeAt(specifier, "local"));
|
|
4096
|
+
return analysis.references.filter(({ binding }) => {
|
|
4097
|
+
return binding?.kind === "import" && binding.imported === "*" && binding.source === source && binding.name === local;
|
|
4098
|
+
});
|
|
4099
|
+
}
|
|
4100
|
+
function isTypeUseOnly(scan, source, specifier) {
|
|
4101
|
+
const local = exportNameOf(nodeAt(specifier, "local"));
|
|
4102
|
+
if (local === void 0 || !scan.typeNames().has(local) || scan.jsxNames().has(local)) {
|
|
4103
|
+
return false;
|
|
4104
|
+
}
|
|
4105
|
+
return usesOf(scan.analysis(), source, specifier).length === 0;
|
|
4106
|
+
}
|
|
4107
|
+
function namespaceTakesOf(scan, source, specifier) {
|
|
4108
|
+
const references = referencesTo(scan.analysis(), source, specifier);
|
|
4109
|
+
const taken = namespaceTakes(scan.analysis(), references, scan.names);
|
|
4110
|
+
if (taken?.names.length === 0) return taken;
|
|
4111
|
+
const local = exportNameOf(nodeAt(specifier, "local"));
|
|
4112
|
+
const tags = local === void 0 ? [] : [...scan.jsxMembers(local)];
|
|
4113
|
+
const names = /* @__PURE__ */ new Set([
|
|
4114
|
+
...taken?.names ?? [],
|
|
4115
|
+
...tags.filter((name) => isCxName(scan.names, name))
|
|
4116
|
+
]);
|
|
4117
|
+
return names.size === 0 ? void 0 : { shape: "namespace", names: [...names] };
|
|
4118
|
+
}
|
|
4119
|
+
function namespaceTake(scan, source, specifier) {
|
|
4120
|
+
const references = referencesTo(scan.analysis(), source, specifier);
|
|
4121
|
+
const held2 = scan.isDependency && heldNamespace(scan.analysis(), references, scan.names, source);
|
|
4122
|
+
if (held2) return held2;
|
|
4123
|
+
const taken = namespaceTakesOf(scan, source, specifier);
|
|
4124
|
+
const isForward = passingOf(scan.analysis(), source, specifier).isForward;
|
|
4125
|
+
const forwarded = taken && { ...taken, ...isForward && { isForward } };
|
|
4126
|
+
return forwarded && scan.isDependency ? withHeld(forwarded, source) : forwarded;
|
|
4127
|
+
}
|
|
4128
|
+
function namedTake(scan, source, specifier) {
|
|
4129
|
+
const imported = specifier.type === "ImportDefaultSpecifier" ? "default" : exportNameOf(nodeAt(specifier, "imported"));
|
|
4130
|
+
if (imported === void 0 || !isCxName(scan.names, imported)) return void 0;
|
|
4131
|
+
if (isTypeUseOnly(scan, source, specifier)) return void 0;
|
|
4132
|
+
const isHeld = scan.isDependency && isCarriedOn(scan.analysis(), source, specifier);
|
|
4133
|
+
const form = `uses ${imported} from ${source} where the build cannot follow it`;
|
|
4134
|
+
return {
|
|
4135
|
+
shape: "names",
|
|
4136
|
+
names: [imported],
|
|
4137
|
+
...passingOf(scan.analysis(), source, specifier),
|
|
4138
|
+
...isHeld && { isHeld: true, form }
|
|
4139
|
+
};
|
|
4140
|
+
}
|
|
4141
|
+
function importTakes(node, source, scan) {
|
|
4142
|
+
return valueSpecifiersOf(node).flatMap((specifier) => {
|
|
4143
|
+
const taken = specifier.type === "ImportNamespaceSpecifier" ? namespaceTake(scan, source, specifier) : namedTake(scan, source, specifier);
|
|
4144
|
+
return taken ? [taken] : [];
|
|
4145
|
+
});
|
|
4146
|
+
}
|
|
4147
|
+
function exportTakes(node, scan) {
|
|
4148
|
+
if (node.type === "ExportAllDeclaration") {
|
|
4149
|
+
if (nodeAt(node, "exported") !== void 0) {
|
|
4150
|
+
return [{ shape: "namespace", names: [], isForward: true }];
|
|
4151
|
+
}
|
|
4152
|
+
const hasNamed = scan.names === void 0 || scan.names.keys().some((name) => name !== "default");
|
|
4153
|
+
return hasNamed ? [{ shape: "star", names: [], isForward: true }] : [];
|
|
4154
|
+
}
|
|
4155
|
+
const re = valueSpecifiersOf(node).map((specifier) => exportNameOf(nodeAt(specifier, "local"))).filter((name) => name !== void 0 && isCxName(scan.names, name));
|
|
4156
|
+
return re.length === 0 ? [] : [{ shape: "names", names: re, isPassedOn: true, isForward: true }];
|
|
4157
|
+
}
|
|
4158
|
+
function dynamicTakes(node, scan) {
|
|
4159
|
+
const keys = dynamicKeys(scan.analysis(), node, scan.names);
|
|
4160
|
+
if (keys === void 0) return [{ shape: "dynamic-import", names: [] }];
|
|
4161
|
+
return keys.length === 0 ? [] : [{ shape: "dynamic-import", names: keys }];
|
|
4162
|
+
}
|
|
4163
|
+
function takesOf(node, scan) {
|
|
4164
|
+
const source = staticStringOf(nodeAt(node, "source"));
|
|
4165
|
+
if (source === void 0 || !scan.reaches.has(source)) return [];
|
|
4166
|
+
if (isTypeOnly(node)) return [];
|
|
4167
|
+
if (node.type === "ImportDeclaration") return importTakes(node, source, scan);
|
|
4168
|
+
if (node.type === "ImportExpression") {
|
|
4169
|
+
if (!scan.isDependency) return dynamicTakes(node, scan);
|
|
4170
|
+
const taken = isUsedAsCallsOnly(scan.analysis(), node, scan.names) ? dynamicTakes(node, scan) : [{ shape: "dynamic-import", names: [] }];
|
|
4171
|
+
return taken.map((one) => withHeld(one, source));
|
|
4172
|
+
}
|
|
4173
|
+
return exportTakes(node, scan);
|
|
4174
|
+
}
|
|
4175
|
+
function takesIn(program, input) {
|
|
4176
|
+
let analysis;
|
|
4177
|
+
let typeNames;
|
|
4178
|
+
let jsxNames;
|
|
4179
|
+
let jsxMembers;
|
|
4180
|
+
const scan = {
|
|
4181
|
+
...input,
|
|
4182
|
+
isDependency: input.isDependency === true,
|
|
4183
|
+
analysis: () => analysis ??= analyze(program),
|
|
4184
|
+
typeNames: () => typeNames ??= namesIn(program, typeNameOf),
|
|
4185
|
+
jsxNames: () => jsxNames ??= namesIn(program, jsxNameOf),
|
|
4186
|
+
jsxMembers: (local) => (jsxMembers ??= jsxMembersIn(program)).get(local) ?? /* @__PURE__ */ new Set()
|
|
4187
|
+
};
|
|
4188
|
+
const found = [];
|
|
4189
|
+
const stack = [program];
|
|
4190
|
+
while (stack.length > 0) {
|
|
4191
|
+
const node = stack.pop();
|
|
4192
|
+
pushAll(found, takesOf(node, scan));
|
|
4193
|
+
pushAll(stack, childrenOf(node));
|
|
4194
|
+
}
|
|
4195
|
+
return found;
|
|
4196
|
+
}
|
|
4197
|
+
|
|
4198
|
+
// src/vite-listed-routes.ts
|
|
4199
|
+
function importTakesOf(program, input) {
|
|
4200
|
+
return input.reaches.size === 0 ? [] : takesIn(program, input);
|
|
4201
|
+
}
|
|
4202
|
+
function unreadableFor(id, module) {
|
|
4203
|
+
return isDependencyId(id) ? { ...UNREADABLE, isHeld: true, form: `takes ${module} in a way the build cannot read` } : UNREADABLE;
|
|
4204
|
+
}
|
|
4205
|
+
function requireTakesOf(program, input) {
|
|
4206
|
+
if (input.requires.size === 0) return [];
|
|
4207
|
+
return requireTakesIn(program, {
|
|
4208
|
+
names: input.names,
|
|
4209
|
+
reaches: input.requires,
|
|
4210
|
+
readsForwards: isDependencyId(input.id)
|
|
4211
|
+
}).takes;
|
|
4212
|
+
}
|
|
4213
|
+
async function takenBy(ctx, input) {
|
|
4214
|
+
const { file, id, label, names, resolutions } = input;
|
|
4215
|
+
const unreadable = () => unreadableFor(id, label);
|
|
4216
|
+
const code = ctx.getModuleInfo?.(id)?.code;
|
|
4217
|
+
try {
|
|
4218
|
+
const read = code === null || code === void 0 ? void 0 : await reachingSpecifiers(ctx, { code, file, id, resolutions });
|
|
4219
|
+
if (!read) return [unreadable()];
|
|
4220
|
+
const { program, reaches, requires } = read;
|
|
4221
|
+
if (reaches.size === 0 && requires.size === 0) return [unreadable()];
|
|
4222
|
+
return [
|
|
4223
|
+
...importTakesOf(program, { isDependency: isDependencyId(id), names, reaches }),
|
|
4224
|
+
...requireTakesOf(program, { id, names, requires })
|
|
4225
|
+
];
|
|
4226
|
+
} catch {
|
|
4227
|
+
return [unreadable()];
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
function merged(takes) {
|
|
4231
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
4232
|
+
for (const take of takes) {
|
|
4233
|
+
const key = `${take.taker}\0${take.shape}`;
|
|
4234
|
+
const known = byKey.get(key);
|
|
4235
|
+
const names = /* @__PURE__ */ new Set([...known?.names ?? [], ...take.names]);
|
|
4236
|
+
const isReached = take.isReached || known?.isReached === true;
|
|
4237
|
+
const isPassedOn = take.isPassedOn === true || known?.isPassedOn === true;
|
|
4238
|
+
byKey.set(key, { ...take, isPassedOn, isReached, names: [...names].toSorted(compareText) });
|
|
4239
|
+
}
|
|
4240
|
+
return byKey.values().toArray();
|
|
4241
|
+
}
|
|
4242
|
+
async function isCounted(context, input) {
|
|
4243
|
+
const { importer, isEntry, pkg, wantCalls } = input;
|
|
4244
|
+
if (wantCalls || !isDependencyId(importer)) return true;
|
|
4245
|
+
if (!isEntry) return false;
|
|
4246
|
+
return await context.packageOf(importer) !== pkg;
|
|
4247
|
+
}
|
|
4248
|
+
async function routesOf(ctx, context, input) {
|
|
4249
|
+
const { holder, importer, isEntry, resolutions, wantCalls } = input;
|
|
4250
|
+
const isDependency = isDependencyId(importer);
|
|
4251
|
+
const taker = context.labelOf(importer);
|
|
4252
|
+
const taken = await takenBy(ctx, {
|
|
4253
|
+
file: fileOf(holder.id),
|
|
4254
|
+
id: importer,
|
|
4255
|
+
label: context.labelOf(fileOf(holder.id)),
|
|
4256
|
+
names: holder.names,
|
|
4257
|
+
resolutions
|
|
4258
|
+
});
|
|
4259
|
+
const takes = taken.map((take) => ({ ...take, taker, isReached: holder.isReached }));
|
|
4260
|
+
if (isDependency) {
|
|
4261
|
+
const pkg = await context.packageOf(importer) ?? taker;
|
|
4262
|
+
const held2 = takes.filter((take) => take.isHeld === true).map((take) => ({ form: take.form ?? "", importer, pkg, taker }));
|
|
4263
|
+
const calls = takes.filter((take) => take.isForward !== true && take.isHeld !== true);
|
|
4264
|
+
return { entry: isEntry ? calls : [], told: [], calls: wantCalls ? calls : [], held: held2 };
|
|
4265
|
+
}
|
|
4266
|
+
const isCleared = (take) => isEntry && take.shape !== "unreadable";
|
|
4267
|
+
return {
|
|
4268
|
+
entry: takes.filter((take) => isCleared(take)),
|
|
4269
|
+
told: takes.filter((take) => !isCleared(take)),
|
|
4270
|
+
calls: [],
|
|
4271
|
+
held: []
|
|
4272
|
+
};
|
|
4273
|
+
}
|
|
4274
|
+
function serverTakesOf(found, holder) {
|
|
4275
|
+
const takes = [];
|
|
4276
|
+
for (const taken of found.takes) {
|
|
4277
|
+
const names = taken.names.filter((name) => holder.names.has(name));
|
|
4278
|
+
const isWhole = taken.names.length === 0;
|
|
4279
|
+
const hasNamed = holder.names.keys().some((name) => name !== "default");
|
|
4280
|
+
const isTaken = taken.shape === "star" ? hasNamed : isWhole || names.length > 0;
|
|
4281
|
+
if (isTaken) {
|
|
4282
|
+
const kept = isWhole ? taken.names : names;
|
|
4283
|
+
takes.push({
|
|
4284
|
+
...taken,
|
|
4285
|
+
names: kept,
|
|
4286
|
+
taker: found.taker,
|
|
4287
|
+
isReached: holder.isReached,
|
|
4288
|
+
...found.isRecorded === true && { isRecorded: true }
|
|
4289
|
+
});
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4292
|
+
return takes;
|
|
4293
|
+
}
|
|
4294
|
+
async function takesFrom(ctx, context, input) {
|
|
4295
|
+
const { holder, isEntry, pkg, resolutions, wantCalls } = input;
|
|
4296
|
+
const importers = importersOf(ctx, holder.id);
|
|
4297
|
+
const entry = [];
|
|
4298
|
+
const told = [];
|
|
4299
|
+
const calls = [];
|
|
4300
|
+
const held2 = [];
|
|
4301
|
+
for (const importer of importers) {
|
|
4302
|
+
const routes = await routesOf(ctx, context, {
|
|
4303
|
+
holder,
|
|
4304
|
+
importer,
|
|
4305
|
+
isEntry,
|
|
4306
|
+
resolutions,
|
|
4307
|
+
wantCalls
|
|
4308
|
+
});
|
|
4309
|
+
pushAll(held2, routes.held);
|
|
4310
|
+
if (!await isCounted(context, { importer, isEntry, pkg, wantCalls })) continue;
|
|
4311
|
+
pushAll(entry, routes.entry);
|
|
4312
|
+
pushAll(told, routes.told);
|
|
4313
|
+
pushAll(calls, routes.calls);
|
|
4314
|
+
}
|
|
4315
|
+
return { entry: merged(entry), told: merged(told), calls: merged(calls), held: held2 };
|
|
4316
|
+
}
|
|
4317
|
+
function serverRoutes(holder, input) {
|
|
4318
|
+
const file = fileOf(holder.id);
|
|
4319
|
+
const fromServer = input.serverImports.filter((one) => one.file === file);
|
|
4320
|
+
const takes = fromServer.flatMap((found) => serverTakesOf(found, holder));
|
|
4321
|
+
const isCleared = (take) => input.isEntry && take.shape !== "unreadable";
|
|
4322
|
+
return {
|
|
4323
|
+
entry: takes.filter((take) => isCleared(take)),
|
|
4324
|
+
told: takes.filter((take) => !isCleared(take))
|
|
4325
|
+
};
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4328
|
+
// src/vite-listed-takes.ts
|
|
4329
|
+
async function prepareOne(ctx, context, input) {
|
|
4330
|
+
const { isHop, problems, walk } = input;
|
|
4331
|
+
const first2 = problems[0];
|
|
4332
|
+
const pkg = first2.pkg;
|
|
4333
|
+
const names = new Set(problems.flatMap((problem2) => problem2.exportedAs ?? []));
|
|
4334
|
+
const hasEntry = !isHop && problems.some((problem2) => problem2.specifier !== void 0);
|
|
4335
|
+
const holders = await holdersOf(ctx, { ...walk, id: first2.moduleId, names });
|
|
4336
|
+
const routed = await Promise.all(
|
|
4337
|
+
holders.map(
|
|
4338
|
+
(holder) => takesFrom(ctx, context, {
|
|
4339
|
+
holder,
|
|
4340
|
+
isEntry: hasEntry && !holder.isReached,
|
|
4341
|
+
pkg,
|
|
4342
|
+
resolutions: walk.resolutions,
|
|
4343
|
+
wantCalls: isHop
|
|
4344
|
+
})
|
|
4345
|
+
)
|
|
4346
|
+
);
|
|
4347
|
+
const isListed = Object.hasOwn(context.options.keepFor, pkg);
|
|
4348
|
+
return { hasEntry, holders, isHop, isListed, problems, rootName: context.rootName, routed };
|
|
4349
|
+
}
|
|
4350
|
+
function heldProblemsOf(routed) {
|
|
4351
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
4352
|
+
const all = routed.flatMap((route) => route.held);
|
|
4353
|
+
for (const held2 of all) byKey.set(`${held2.importer}\0${held2.form}`, held2);
|
|
4354
|
+
return byKey.values().map((held2) => ({
|
|
4355
|
+
kind: "reference",
|
|
4356
|
+
offset: 0,
|
|
4357
|
+
construct: "",
|
|
4358
|
+
text: `${held2.form}.`,
|
|
4359
|
+
file: held2.taker,
|
|
4360
|
+
line: 0,
|
|
4361
|
+
column: 0,
|
|
4362
|
+
unknownLine: "",
|
|
4363
|
+
pkg: held2.pkg,
|
|
4364
|
+
moduleId: held2.importer,
|
|
4365
|
+
isHeld: true
|
|
4366
|
+
})).toArray();
|
|
4367
|
+
}
|
|
4368
|
+
function decideOne(prepared, serverImports) {
|
|
4369
|
+
return [...heldProblemsOf(prepared.routed), ...decidedByTakes(prepared, serverImports)];
|
|
4370
|
+
}
|
|
4371
|
+
function decidedByTakes(prepared, serverImports) {
|
|
4372
|
+
const { hasEntry, holders, isHop, isListed, problems, rootName, routed } = prepared;
|
|
4373
|
+
const fromServer = holders.map(
|
|
4374
|
+
(holder) => serverRoutes(holder, { isEntry: hasEntry && !holder.isReached, serverImports })
|
|
4375
|
+
);
|
|
4376
|
+
const entry = [...routed.flatMap((route) => route.entry), ...fromServer.flatMap((r) => r.entry)];
|
|
4377
|
+
if (entry.length > 0) return problems.filter((problem2) => problem2.specifier !== void 0);
|
|
4378
|
+
const told = merged([
|
|
4379
|
+
...routed.flatMap((route) => route.told),
|
|
4380
|
+
...fromServer.flatMap((route) => route.told)
|
|
4381
|
+
]);
|
|
4382
|
+
const callers = isHop && !isListed ? callersOf(routed) : [];
|
|
4383
|
+
if (told.length === 0 && callers.length === 0) return [];
|
|
4384
|
+
return problems.map((problem2) => ({
|
|
4385
|
+
...problem2,
|
|
4386
|
+
...told.length > 0 && { takes: told, rootName },
|
|
4387
|
+
...callers.length > 0 && { callers }
|
|
4388
|
+
}));
|
|
4389
|
+
}
|
|
4390
|
+
function callersOf(routed) {
|
|
4391
|
+
const callers = new Set(routed.flatMap((route) => route.calls.map((call) => call.taker)));
|
|
4392
|
+
return [...callers].toSorted(compareText);
|
|
4393
|
+
}
|
|
4394
|
+
async function prepareReexports(ctx, context, standingIn) {
|
|
4395
|
+
const exporting = standingIn.filter((problem2) => problem2.exportedAs !== void 0);
|
|
4396
|
+
const located = await withClearingSpecifiers(ctx, context, exporting);
|
|
4397
|
+
const byModule = /* @__PURE__ */ new Map();
|
|
4398
|
+
const hops = /* @__PURE__ */ new Map();
|
|
4399
|
+
for (const problem2 of located) {
|
|
4400
|
+
if (problem2.moduleId === void 0 || problem2.pkg === void 0) continue;
|
|
4401
|
+
const group = isSecondHop(problem2) ? hops : byModule;
|
|
4402
|
+
group.set(problem2.moduleId, [...group.get(problem2.moduleId) ?? [], problem2]);
|
|
4403
|
+
}
|
|
4404
|
+
const cxExports = new Map(
|
|
4405
|
+
[...byModule.values(), ...hops.values()].map((problems) => [
|
|
4406
|
+
fileOf(problems[0].moduleId),
|
|
4407
|
+
new Set(problems.flatMap((problem2) => problem2.exportedAs ?? []))
|
|
4408
|
+
])
|
|
4409
|
+
);
|
|
4410
|
+
const walk = { cxExports, resolutions: /* @__PURE__ */ new Map() };
|
|
4411
|
+
return await Promise.all([
|
|
4412
|
+
...byModule.values().map((problems) => prepareOne(ctx, context, { isHop: false, problems, walk })),
|
|
4413
|
+
...hops.values().map((problems) => prepareOne(ctx, context, { isHop: true, problems, walk }))
|
|
4414
|
+
]);
|
|
4415
|
+
}
|
|
4416
|
+
function decideReexports(prepared, serverImports) {
|
|
4417
|
+
const decided = prepared.flatMap((one) => decideOne(one, serverImports));
|
|
4418
|
+
const isFirst = (problem2, index) => problem2.isHeld !== true || decided.findIndex(
|
|
4419
|
+
(other) => other.isHeld === true && other.moduleId === problem2.moduleId && other.text === problem2.text
|
|
4420
|
+
) === index;
|
|
4421
|
+
return decided.filter((problem2, index) => isFirst(problem2, index));
|
|
4422
|
+
}
|
|
4423
|
+
|
|
4424
|
+
// src/vite-reexport-judge.ts
|
|
4425
|
+
async function judgeReexports(host, context, modules, serverImports = []) {
|
|
4426
|
+
const kept = await withClearingSpecifiers(
|
|
4427
|
+
host,
|
|
4428
|
+
context,
|
|
4429
|
+
withoutEchoes(
|
|
4430
|
+
modules.map((module) => ({
|
|
4431
|
+
onlyVia: module.onlyVia,
|
|
4432
|
+
problems: [
|
|
4433
|
+
...module.problems,
|
|
4434
|
+
...module.suppressed.filter((problem2) => problem2.kind === "declared")
|
|
4435
|
+
]
|
|
4436
|
+
}))
|
|
4437
|
+
)
|
|
4438
|
+
);
|
|
4439
|
+
const suppressed = modules.flatMap((module) => module.suppressed);
|
|
4440
|
+
const held2 = suppressed.filter((problem2) => problem2.isUnboundHandOut === true).map((problem2) => ({ ...problem2, isHeld: true }));
|
|
4441
|
+
const standingIn = [
|
|
4442
|
+
...suppressed.filter((problem2) => problem2.isUnboundHandOut !== true),
|
|
4443
|
+
...kept.filter((problem2) => isSecondHop(problem2))
|
|
4444
|
+
];
|
|
4445
|
+
const rest = kept.filter((problem2) => !isSecondHop(problem2));
|
|
4446
|
+
const prepared = await prepareReexports(host, context, standingIn);
|
|
4447
|
+
return { problems: [...rest, ...held2, ...decideReexports(prepared, serverImports)], prepared };
|
|
4448
|
+
}
|
|
4449
|
+
|
|
4450
|
+
// src/vite-restorers.ts
|
|
4451
|
+
function withRestorers(atoms) {
|
|
4452
|
+
if (atoms.has("srOnly")) atoms.add("srOnlyFocusable");
|
|
4453
|
+
return atoms;
|
|
4454
|
+
}
|
|
4455
|
+
|
|
2650
4456
|
// src/vite-used-report.ts
|
|
2651
4457
|
var LINE_UNKNOWN_WITHOUT_MAP = " (line unknown: this file's compiled code has no source map in this build; with build.sourcemap set in the Vite config, the report gives the line if the source maps then lead back to it)";
|
|
2652
4458
|
var LINE_UNKNOWN_UNMAPPED = " (line unknown: no source map leads from the compiled code to this file)";
|
|
@@ -2704,11 +4510,11 @@ function applicationLines(application, configured, home) {
|
|
|
2704
4510
|
}
|
|
2705
4511
|
return lines;
|
|
2706
4512
|
}
|
|
2707
|
-
function remedyBlock(problems, listed,
|
|
4513
|
+
function remedyBlock(problems, listed, places, hostRemedies) {
|
|
2708
4514
|
const configured = withoutRemoved(problems, listed);
|
|
2709
4515
|
const application = problems.filter((problem2) => problem2.pkg === void 0);
|
|
2710
4516
|
const lines = [
|
|
2711
|
-
...applicationLines(application, configured, home),
|
|
4517
|
+
...applicationLines(application, configured, places.home),
|
|
2712
4518
|
...hostRemedies?.(application) ?? []
|
|
2713
4519
|
];
|
|
2714
4520
|
const byPackage = /* @__PURE__ */ new Map();
|
|
@@ -2717,7 +4523,7 @@ function remedyBlock(problems, listed, home, hostRemedies) {
|
|
|
2717
4523
|
byPackage.set(problem2.pkg, [...byPackage.get(problem2.pkg) ?? [], problem2]);
|
|
2718
4524
|
}
|
|
2719
4525
|
for (const pkg of byPackage.keys().toArray().toSorted(compareText)) {
|
|
2720
|
-
lines.push(...packageLines(pkg, byPackage.get(pkg), configured,
|
|
4526
|
+
lines.push(...packageLines(pkg, byPackage.get(pkg), configured, places));
|
|
2721
4527
|
}
|
|
2722
4528
|
if (application.some((problem2) => problem2.needsAvailable)) lines.push(availableLine());
|
|
2723
4529
|
return lines;
|
|
@@ -2749,17 +4555,21 @@ function problemLines(problems) {
|
|
|
2749
4555
|
function noun(count, word) {
|
|
2750
4556
|
return `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
2751
4557
|
}
|
|
2752
|
-
function buildReport(problems, configured, home,
|
|
4558
|
+
function buildReport(problems, configured, home, host) {
|
|
4559
|
+
const { remedies: hostRemedies, everyAtom = EVERY_ATOM } = typeof host === "function" ? { remedies: host } : host ?? {};
|
|
2753
4560
|
const files = new Set(problems.map((problem2) => problem2.file)).size;
|
|
2754
4561
|
const first2 = `${noun(problems.length, "problem")} in ${noun(files, "file")}: ${REPORT_CAUSE}`;
|
|
2755
4562
|
return [
|
|
2756
4563
|
first2,
|
|
2757
4564
|
...problemLines(problems),
|
|
2758
|
-
...remedyBlock(problems, configured, home, hostRemedies)
|
|
4565
|
+
...remedyBlock(problems, configured, { home, everyAtom }, hostRemedies)
|
|
2759
4566
|
].join("\n");
|
|
2760
4567
|
}
|
|
2761
4568
|
function moduleReport(problems, configured, home) {
|
|
2762
|
-
return [
|
|
4569
|
+
return [
|
|
4570
|
+
...problemLines(problems),
|
|
4571
|
+
...remedyBlock(problems, configured, { home, everyAtom: EVERY_ATOM })
|
|
4572
|
+
].join("\n");
|
|
2763
4573
|
}
|
|
2764
4574
|
|
|
2765
|
-
export { CLASS_MAP_NOT_PARSED, CX_SOURCE, LINE_UNKNOWN_UNMAPPED, LINE_UNKNOWN_WITHOUT_MAP, REPORT_CAUSE, analyze, applyEdits, assertOptions, atomOfClass, atomsWrittenIn, buildReport, childrenOf, combinedMapOf, compareText, cxModulesArray,
|
|
4575
|
+
export { CLASS_MAP_NOT_PARSED, CX_ONLY, CX_SOURCE, LINE_UNKNOWN_UNMAPPED, LINE_UNKNOWN_WITHOUT_MAP, REPORT_CAUSE, UNREADABLE, analyze, applyEdits, assertOptions, atomOfClass, atomsWrittenIn, buildReport, canHoldDirective, childrenOf, combinedMapOf, compareText, cxModulesArray, decideReexports, declaredModulesFor, fileOf, filePathOf, flowOf, forgetDeclared, inspectAtomicLayer, isAboutListed, isCssModuleId, isDependencyId, isListedFile, isNamingListed, isNode, isRelative, isResolvingTo, isStylesheetId, isStylesheetPath, isUnreadStylesheet, isUsedAsCallsOnly, judgeReexports, keptAtoms, moduleReport, nodeAt, nodesAt, placerFor, pruneAtomicLayer, pushAll, readModule, recognisedKey, resolveOrNull, resolveUsedOptions, specifiersIn, specifiersOf, staticStringOf, takesIn, toSourceMap, unprunedAtoms, withRestorers, withoutRemoved };
|