@homebound/truss 2.29.7 → 2.29.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/plugin/index.js +195 -137
- package/build/plugin/index.js.map +1 -1
- package/build/runtime.d.ts +32 -8
- package/build/runtime.js +40 -113
- package/build/runtime.js.map +1 -1
- package/build/vitest.d.ts +2 -5
- package/package.json +14 -14
- package/tsconfig.tsbuildinfo +1 -1
package/build/plugin/index.js
CHANGED
|
@@ -56,6 +56,7 @@ function removeCssImport(ast, cssBinding) {
|
|
|
56
56
|
ast.program.body.splice(i, 1);
|
|
57
57
|
} else {
|
|
58
58
|
node.specifiers.splice(cssSpecIndex, 1);
|
|
59
|
+
hoistTypeOnlyImportKind(node);
|
|
59
60
|
}
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
@@ -76,10 +77,10 @@ function insertAfterLeadingImports(ast, statements) {
|
|
|
76
77
|
}
|
|
77
78
|
function findNamedImportBinding(ast, importedName, source) {
|
|
78
79
|
for (const node of ast.program.body) {
|
|
79
|
-
if (!t.isImportDeclaration(node)) continue;
|
|
80
|
+
if (!t.isImportDeclaration(node) || node.importKind === "type") continue;
|
|
80
81
|
if (source !== void 0 && node.source.value !== source) continue;
|
|
81
82
|
for (const spec of node.specifiers) {
|
|
82
|
-
if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported, { name: importedName })) {
|
|
83
|
+
if (t.isImportSpecifier(spec) && spec.importKind !== "type" && t.isIdentifier(spec.imported, { name: importedName })) {
|
|
83
84
|
return spec.local.name;
|
|
84
85
|
}
|
|
85
86
|
}
|
|
@@ -109,7 +110,9 @@ function replaceCssImportWithNamedImports(ast, cssBinding, source, imports) {
|
|
|
109
110
|
}
|
|
110
111
|
function upsertNamedImports(ast, source, imports) {
|
|
111
112
|
if (imports.length === 0) return;
|
|
112
|
-
const existing =
|
|
113
|
+
const existing = ast.program.body.find(
|
|
114
|
+
(node) => t.isImportDeclaration(node) && node.source.value === source && node.importKind !== "type" && !node.specifiers.some((spec) => t.isImportNamespaceSpecifier(spec))
|
|
115
|
+
);
|
|
113
116
|
if (!existing) {
|
|
114
117
|
const importDecl = t.importDeclaration(imports.map(toImportSpecifier), t.stringLiteral(source));
|
|
115
118
|
ast.program.body.splice(findLastImportIndex(ast) + 1, 0, importDecl);
|
|
@@ -117,7 +120,7 @@ function upsertNamedImports(ast, source, imports) {
|
|
|
117
120
|
}
|
|
118
121
|
for (const entry of imports) {
|
|
119
122
|
const exists = existing.specifiers.some((spec) => {
|
|
120
|
-
return t.isImportSpecifier(spec) && t.isIdentifier(spec.imported, { name: entry.importedName });
|
|
123
|
+
return t.isImportSpecifier(spec) && spec.importKind !== "type" && t.isIdentifier(spec.imported, { name: entry.importedName });
|
|
121
124
|
});
|
|
122
125
|
if (!exists) existing.specifiers.push(toImportSpecifier(entry));
|
|
123
126
|
}
|
|
@@ -183,16 +186,23 @@ function memberPropertyName(node) {
|
|
|
183
186
|
if (node.computed && t.isStringLiteral(node.property)) return node.property.value;
|
|
184
187
|
return null;
|
|
185
188
|
}
|
|
189
|
+
function hoistTypeOnlyImportKind(node) {
|
|
190
|
+
if (node.importKind === "type") return;
|
|
191
|
+
const typeOnly = node.specifiers.every((spec) => t.isImportSpecifier(spec) && spec.importKind === "type");
|
|
192
|
+
if (!typeOnly) return;
|
|
193
|
+
node.importKind = "type";
|
|
194
|
+
for (const spec of node.specifiers) {
|
|
195
|
+
if (t.isImportSpecifier(spec)) spec.importKind = null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
186
198
|
function toImportSpecifier(entry) {
|
|
187
199
|
return t.importSpecifier(t.identifier(entry.localName), t.identifier(entry.importedName));
|
|
188
200
|
}
|
|
189
201
|
|
|
190
202
|
// src/plugin/babel-utils.ts
|
|
191
|
-
import
|
|
203
|
+
import generate from "@babel/generator";
|
|
192
204
|
import { parse } from "@babel/parser";
|
|
193
|
-
import
|
|
194
|
-
var generate = _generate.default ?? _generate;
|
|
195
|
-
var traverse = _traverse.default ?? _traverse;
|
|
205
|
+
import traverse from "@babel/traverse";
|
|
196
206
|
function parseModule(code, filename) {
|
|
197
207
|
return parse(code, {
|
|
198
208
|
sourceType: "module",
|
|
@@ -2486,6 +2496,84 @@ function sortRulesByPriority(rules) {
|
|
|
2486
2496
|
return decorated.map((d) => ({ rule: d.rule, priority: d.priority }));
|
|
2487
2497
|
}
|
|
2488
2498
|
|
|
2499
|
+
// src/plugin/truss-css.ts
|
|
2500
|
+
var RULE_ANNOTATION_RE = /^\/\* @truss p:([\d.]+) c:(\S+) \*\/$/;
|
|
2501
|
+
var PROPERTY_ANNOTATION_RE = /^\/\* @truss @property \*\/$/;
|
|
2502
|
+
var ARBITRARY_START_RE = /^\/\* @truss arbitrary:start \*\/$/;
|
|
2503
|
+
var ARBITRARY_END_RE = /^\/\* @truss arbitrary:end \*\/$/;
|
|
2504
|
+
var PROPERTY_VAR_RE = /^@property\s+(--\S+)/;
|
|
2505
|
+
function parseTrussCss(cssText) {
|
|
2506
|
+
const lines = cssText.split("\n");
|
|
2507
|
+
const rules = [];
|
|
2508
|
+
const properties = [];
|
|
2509
|
+
const arbitraryCssBlocks = [];
|
|
2510
|
+
let i = 0;
|
|
2511
|
+
function takeAnnotatedLine() {
|
|
2512
|
+
i++;
|
|
2513
|
+
while (i < lines.length && lines[i].trim() === "") i++;
|
|
2514
|
+
return i < lines.length ? lines[i].trim() : null;
|
|
2515
|
+
}
|
|
2516
|
+
while (i < lines.length) {
|
|
2517
|
+
const line = lines[i].trim();
|
|
2518
|
+
const ruleMatch = RULE_ANNOTATION_RE.exec(line);
|
|
2519
|
+
if (ruleMatch) {
|
|
2520
|
+
const cssText2 = takeAnnotatedLine();
|
|
2521
|
+
if (cssText2 !== null) {
|
|
2522
|
+
rules.push({ priority: parseFloat(ruleMatch[1]), className: ruleMatch[2], cssText: cssText2 });
|
|
2523
|
+
}
|
|
2524
|
+
i++;
|
|
2525
|
+
continue;
|
|
2526
|
+
}
|
|
2527
|
+
if (PROPERTY_ANNOTATION_RE.test(line)) {
|
|
2528
|
+
const propLine = takeAnnotatedLine();
|
|
2529
|
+
const varMatch = propLine === null ? null : PROPERTY_VAR_RE.exec(propLine);
|
|
2530
|
+
if (propLine !== null && varMatch) {
|
|
2531
|
+
properties.push({ cssText: propLine, varName: varMatch[1] });
|
|
2532
|
+
}
|
|
2533
|
+
i++;
|
|
2534
|
+
continue;
|
|
2535
|
+
}
|
|
2536
|
+
if (ARBITRARY_START_RE.test(line)) {
|
|
2537
|
+
i++;
|
|
2538
|
+
const blockLines = [];
|
|
2539
|
+
while (i < lines.length && !ARBITRARY_END_RE.test(lines[i].trim())) {
|
|
2540
|
+
blockLines.push(lines[i]);
|
|
2541
|
+
i++;
|
|
2542
|
+
}
|
|
2543
|
+
const blockText = blockLines.join("\n").trim();
|
|
2544
|
+
if (blockText.length > 0) {
|
|
2545
|
+
arbitraryCssBlocks.push({ cssText: blockText });
|
|
2546
|
+
}
|
|
2547
|
+
if (i < lines.length && ARBITRARY_END_RE.test(lines[i].trim())) {
|
|
2548
|
+
i++;
|
|
2549
|
+
}
|
|
2550
|
+
continue;
|
|
2551
|
+
}
|
|
2552
|
+
i++;
|
|
2553
|
+
}
|
|
2554
|
+
return { rules, properties, arbitraryCssBlocks };
|
|
2555
|
+
}
|
|
2556
|
+
function serializeTrussCss(css) {
|
|
2557
|
+
const lines = [];
|
|
2558
|
+
for (const rule of css.rules) {
|
|
2559
|
+
lines.push(`/* @truss p:${rule.priority} c:${rule.className} */`, rule.cssText);
|
|
2560
|
+
}
|
|
2561
|
+
for (const prop of css.properties) {
|
|
2562
|
+
lines.push(`/* @truss @property */`, prop.cssText);
|
|
2563
|
+
}
|
|
2564
|
+
for (const block of css.arbitraryCssBlocks) {
|
|
2565
|
+
lines.push(annotateArbitraryCssBlock(block.cssText));
|
|
2566
|
+
}
|
|
2567
|
+
return lines.join("\n");
|
|
2568
|
+
}
|
|
2569
|
+
function annotateArbitraryCssBlock(cssText) {
|
|
2570
|
+
const trimmed = cssText.trim();
|
|
2571
|
+
if (trimmed.length === 0) {
|
|
2572
|
+
return "";
|
|
2573
|
+
}
|
|
2574
|
+
return ["/* @truss arbitrary:start */", trimmed, "/* @truss arbitrary:end */"].join("\n");
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2489
2577
|
// src/plugin/emit-css.ts
|
|
2490
2578
|
function collectAtomicRules(chains, mapping) {
|
|
2491
2579
|
const rules = /* @__PURE__ */ new Map();
|
|
@@ -2545,22 +2633,28 @@ function whenSelectorFor(whenPseudo) {
|
|
|
2545
2633
|
pseudo: whenPseudo.pseudo
|
|
2546
2634
|
};
|
|
2547
2635
|
}
|
|
2548
|
-
function
|
|
2636
|
+
function generateCssData(rules) {
|
|
2549
2637
|
const sorted = sortRulesByPriority(rules.values());
|
|
2550
|
-
const
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2638
|
+
const css = {
|
|
2639
|
+
rules: sorted.map((entry) => ({
|
|
2640
|
+
priority: entry.priority,
|
|
2641
|
+
className: entry.rule.className,
|
|
2642
|
+
cssText: formatRule(entry.rule)
|
|
2643
|
+
})),
|
|
2644
|
+
properties: [],
|
|
2645
|
+
arbitraryCssBlocks: []
|
|
2646
|
+
};
|
|
2555
2647
|
for (const { rule } of sorted) {
|
|
2556
2648
|
for (const declaration of rule.declarations) {
|
|
2557
2649
|
if (declaration.cssVarName) {
|
|
2558
|
-
|
|
2559
|
-
|
|
2650
|
+
css.properties.push({
|
|
2651
|
+
varName: declaration.cssVarName,
|
|
2652
|
+
cssText: `@property ${declaration.cssVarName} { syntax: "*"; inherits: false; }`
|
|
2653
|
+
});
|
|
2560
2654
|
}
|
|
2561
2655
|
}
|
|
2562
2656
|
}
|
|
2563
|
-
return
|
|
2657
|
+
return css;
|
|
2564
2658
|
}
|
|
2565
2659
|
function formatRule(rule) {
|
|
2566
2660
|
const duplicateClassName = !!rule.mediaQuery;
|
|
@@ -2805,6 +2899,38 @@ ${body}
|
|
|
2805
2899
|
import * as t15 from "@babel/types";
|
|
2806
2900
|
import { basename } from "path";
|
|
2807
2901
|
|
|
2902
|
+
// src/plugin/test-css.ts
|
|
2903
|
+
import { parse as parse2 } from "css-tree";
|
|
2904
|
+
function createTestCssPayload(css) {
|
|
2905
|
+
const payload = {};
|
|
2906
|
+
if (css.rules.length > 0) {
|
|
2907
|
+
payload.rules = css.rules.map((rule) => {
|
|
2908
|
+
const atRule = atRulePrelude(rule.cssText);
|
|
2909
|
+
return { ...rule, ...atRule === void 0 ? {} : { atRule } };
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2912
|
+
if (css.properties.length > 0) payload.properties = css.properties;
|
|
2913
|
+
const arbitraryRules = css.arbitraryCssBlocks.flatMap((block) => splitArbitraryCss(block.cssText));
|
|
2914
|
+
if (arbitraryRules.length > 0) payload.arbitraryRules = arbitraryRules;
|
|
2915
|
+
return payload;
|
|
2916
|
+
}
|
|
2917
|
+
function splitArbitraryCss(cssText) {
|
|
2918
|
+
const root = parse2(cssText, {
|
|
2919
|
+
context: "stylesheet",
|
|
2920
|
+
positions: true,
|
|
2921
|
+
parseRulePrelude: false,
|
|
2922
|
+
parseAtrulePrelude: false,
|
|
2923
|
+
parseValue: false
|
|
2924
|
+
});
|
|
2925
|
+
const rules = [];
|
|
2926
|
+
root.children.forEach((node) => {
|
|
2927
|
+
if (node.type === "Rule" || node.type === "Atrule") {
|
|
2928
|
+
rules.push(cssText.slice(node.loc.start.offset, node.loc.end.offset));
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2931
|
+
return rules;
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2808
2934
|
// src/plugin/emit-style-hash.ts
|
|
2809
2935
|
import * as t13 from "@babel/types";
|
|
2810
2936
|
function buildStyleHashProperties(segments, mapping, maybeIncHelperName, maybeCssVarHelperName) {
|
|
@@ -3271,7 +3397,8 @@ function transformTruss(code, filename, mapping, options = {}) {
|
|
|
3271
3397
|
if (sites.length === 0 && !hasCssPropsCall && !hasBuildtimeJsxCssAttribute) return null;
|
|
3272
3398
|
const chains = sites.map((s) => s.resolvedChain);
|
|
3273
3399
|
const { rules, needsMaybeInc, needsMaybeCssVar } = collectAtomicRules(chains, mapping);
|
|
3274
|
-
const
|
|
3400
|
+
const cssData = generateCssData(rules);
|
|
3401
|
+
const cssText = serializeTrussCss(cssData);
|
|
3275
3402
|
const runtime = createRuntimeHelpers(ast, usedTopLevelNames);
|
|
3276
3403
|
const maybeIncHelperName = needsMaybeInc ? reservePreferredName(usedTopLevelNames, "__maybeInc") : null;
|
|
3277
3404
|
const maybeCssVarHelperName = needsMaybeCssVar ? runtime.use("maybeCssVar") : null;
|
|
@@ -3317,7 +3444,9 @@ function transformTruss(code, filename, mapping, options = {}) {
|
|
|
3317
3444
|
}
|
|
3318
3445
|
if (options.injectCss && cssText.length > 0) {
|
|
3319
3446
|
declarationsToInsert.push(
|
|
3320
|
-
t15.expressionStatement(
|
|
3447
|
+
t15.expressionStatement(
|
|
3448
|
+
t15.callExpression(t15.identifier("__injectTrussCSS"), [t15.valueToNode(createTestCssPayload(cssData))])
|
|
3449
|
+
)
|
|
3321
3450
|
);
|
|
3322
3451
|
}
|
|
3323
3452
|
for (const { message, line } of errorMessages) {
|
|
@@ -3436,78 +3565,11 @@ function findLastImportLine(lines) {
|
|
|
3436
3565
|
|
|
3437
3566
|
// src/plugin/merge-css.ts
|
|
3438
3567
|
import { readFileSync as readFileSync2 } from "fs";
|
|
3439
|
-
|
|
3440
|
-
// src/truss-css.ts
|
|
3441
|
-
var RULE_ANNOTATION_RE = /^\/\* @truss p:([\d.]+) c:(\S+) \*\/$/;
|
|
3442
|
-
var PROPERTY_ANNOTATION_RE = /^\/\* @truss @property \*\/$/;
|
|
3443
|
-
var ARBITRARY_START_RE = /^\/\* @truss arbitrary:start \*\/$/;
|
|
3444
|
-
var ARBITRARY_END_RE = /^\/\* @truss arbitrary:end \*\/$/;
|
|
3445
|
-
var PROPERTY_VAR_RE = /^@property\s+(--\S+)/;
|
|
3446
|
-
function parseTrussCss(cssText) {
|
|
3447
|
-
const lines = cssText.split("\n");
|
|
3448
|
-
const rules = [];
|
|
3449
|
-
const properties = [];
|
|
3450
|
-
const arbitraryCssBlocks = [];
|
|
3451
|
-
let i = 0;
|
|
3452
|
-
function takeAnnotatedLine() {
|
|
3453
|
-
i++;
|
|
3454
|
-
while (i < lines.length && lines[i].trim() === "") i++;
|
|
3455
|
-
return i < lines.length ? lines[i].trim() : null;
|
|
3456
|
-
}
|
|
3457
|
-
while (i < lines.length) {
|
|
3458
|
-
const line = lines[i].trim();
|
|
3459
|
-
const ruleMatch = RULE_ANNOTATION_RE.exec(line);
|
|
3460
|
-
if (ruleMatch) {
|
|
3461
|
-
const cssText2 = takeAnnotatedLine();
|
|
3462
|
-
if (cssText2 !== null) {
|
|
3463
|
-
rules.push({ priority: parseFloat(ruleMatch[1]), className: ruleMatch[2], cssText: cssText2 });
|
|
3464
|
-
}
|
|
3465
|
-
i++;
|
|
3466
|
-
continue;
|
|
3467
|
-
}
|
|
3468
|
-
if (PROPERTY_ANNOTATION_RE.test(line)) {
|
|
3469
|
-
const propLine = takeAnnotatedLine();
|
|
3470
|
-
const varMatch = propLine === null ? null : PROPERTY_VAR_RE.exec(propLine);
|
|
3471
|
-
if (propLine !== null && varMatch) {
|
|
3472
|
-
properties.push({ cssText: propLine, varName: varMatch[1] });
|
|
3473
|
-
}
|
|
3474
|
-
i++;
|
|
3475
|
-
continue;
|
|
3476
|
-
}
|
|
3477
|
-
if (ARBITRARY_START_RE.test(line)) {
|
|
3478
|
-
i++;
|
|
3479
|
-
const blockLines = [];
|
|
3480
|
-
while (i < lines.length && !ARBITRARY_END_RE.test(lines[i].trim())) {
|
|
3481
|
-
blockLines.push(lines[i]);
|
|
3482
|
-
i++;
|
|
3483
|
-
}
|
|
3484
|
-
const blockText = blockLines.join("\n").trim();
|
|
3485
|
-
if (blockText.length > 0) {
|
|
3486
|
-
arbitraryCssBlocks.push({ cssText: blockText });
|
|
3487
|
-
}
|
|
3488
|
-
if (i < lines.length && ARBITRARY_END_RE.test(lines[i].trim())) {
|
|
3489
|
-
i++;
|
|
3490
|
-
}
|
|
3491
|
-
continue;
|
|
3492
|
-
}
|
|
3493
|
-
i++;
|
|
3494
|
-
}
|
|
3495
|
-
return { rules, properties, arbitraryCssBlocks };
|
|
3496
|
-
}
|
|
3497
|
-
function annotateArbitraryCssBlock(cssText) {
|
|
3498
|
-
const trimmed = cssText.trim();
|
|
3499
|
-
if (trimmed.length === 0) {
|
|
3500
|
-
return "";
|
|
3501
|
-
}
|
|
3502
|
-
return ["/* @truss arbitrary:start */", trimmed, "/* @truss arbitrary:end */"].join("\n");
|
|
3503
|
-
}
|
|
3504
|
-
|
|
3505
|
-
// src/plugin/merge-css.ts
|
|
3506
3568
|
function readTrussCss(filePath) {
|
|
3507
3569
|
const content = readFileSync2(filePath, "utf8");
|
|
3508
3570
|
return parseTrussCss(content);
|
|
3509
3571
|
}
|
|
3510
|
-
function
|
|
3572
|
+
function mergeTrussCssData(sources) {
|
|
3511
3573
|
const seenClasses = /* @__PURE__ */ new Set();
|
|
3512
3574
|
const allRules = [];
|
|
3513
3575
|
const seenProperties = /* @__PURE__ */ new Set();
|
|
@@ -3532,19 +3594,11 @@ function mergeTrussCss(sources) {
|
|
|
3532
3594
|
return { rule, key: ruleSortKey(rule.priority, rule.className, atRulePrelude(rule.cssText)) };
|
|
3533
3595
|
});
|
|
3534
3596
|
decorated.sort((a, b) => compareRuleSortKeys(a.key, b.key));
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
}
|
|
3540
|
-
for (const prop of allProperties) {
|
|
3541
|
-
lines.push(`/* @truss @property */`);
|
|
3542
|
-
lines.push(prop.cssText);
|
|
3543
|
-
}
|
|
3544
|
-
for (const block of allArbitraryCssBlocks) {
|
|
3545
|
-
lines.push(annotateArbitraryCssBlock(block.cssText));
|
|
3546
|
-
}
|
|
3547
|
-
return lines.join("\n");
|
|
3597
|
+
return {
|
|
3598
|
+
rules: decorated.map((entry) => entry.rule),
|
|
3599
|
+
properties: allProperties,
|
|
3600
|
+
arbitraryCssBlocks: allArbitraryCssBlocks
|
|
3601
|
+
};
|
|
3548
3602
|
}
|
|
3549
3603
|
|
|
3550
3604
|
// src/plugin/transform-session.ts
|
|
@@ -3604,12 +3658,11 @@ function createTrussTransformSession(options) {
|
|
|
3604
3658
|
}
|
|
3605
3659
|
function collectCss() {
|
|
3606
3660
|
const mapping2 = ensureMapping();
|
|
3607
|
-
const
|
|
3661
|
+
const appCss = generateCssData(cssRegistry);
|
|
3608
3662
|
const allArbitrary = Array.from(arbitraryCssRegistry.entries()).sort((a, b) => compareClassNames(a[0], b[0])).map((entry) => entry[1]).join("\n\n");
|
|
3609
|
-
|
|
3610
|
-
const appCss = appCssParts.filter((part) => part.length > 0).join("\n");
|
|
3663
|
+
if (allArbitrary.length > 0) appCss.arbitraryCssBlocks.push({ cssText: allArbitrary });
|
|
3611
3664
|
const libs = loadLibraries();
|
|
3612
|
-
const body = libs.length === 0 ? appCss :
|
|
3665
|
+
const body = serializeTrussCss(libs.length === 0 ? appCss : mergeTrussCssData([...libs, appCss]));
|
|
3613
3666
|
if (body.length === 0) return "";
|
|
3614
3667
|
return `${rootSpacingPreludeCss(mapping2.increment)}
|
|
3615
3668
|
${body}`;
|
|
@@ -3618,7 +3671,7 @@ ${body}`;
|
|
|
3618
3671
|
return cssRegistry.size > 0 || arbitraryCssRegistry.size > 0 || libraryPaths.length > 0;
|
|
3619
3672
|
}
|
|
3620
3673
|
function collectTestCss() {
|
|
3621
|
-
return
|
|
3674
|
+
return createTestCssPayload(mergeTrussCssData(loadLibraries()));
|
|
3622
3675
|
}
|
|
3623
3676
|
function getArbitraryCss(sourcePath) {
|
|
3624
3677
|
return arbitraryCssRegistry.get(resolve2(sourcePath).replace(/\\/g, "/")) ?? "";
|
|
@@ -3687,6 +3740,8 @@ function loaderForPath(filePath) {
|
|
|
3687
3740
|
var VIRTUAL_CSS_PREFIX = "\0truss-css:";
|
|
3688
3741
|
var VIRTUAL_TEST_CSS_PREFIX = "\0truss-test-css:";
|
|
3689
3742
|
var CSS_TS_QUERY = "?truss-css";
|
|
3743
|
+
var RUNTIME_MODULE2 = "@homebound/truss/runtime";
|
|
3744
|
+
var INJECT_CSS_HELPER = "__injectTrussCSS";
|
|
3690
3745
|
var TRUSS_CSS_PLACEHOLDER = "__TRUSS_CSS_HASH__";
|
|
3691
3746
|
var VIRTUAL_CSS_ENDPOINT = "/virtual:truss.css";
|
|
3692
3747
|
var VIRTUAL_RUNTIME_ID = "virtual:truss:runtime";
|
|
@@ -3809,8 +3864,8 @@ function trussPlugin(opts) {
|
|
|
3809
3864
|
`;
|
|
3810
3865
|
}
|
|
3811
3866
|
if (id === RESOLVED_VIRTUAL_TEST_CSS_ID) {
|
|
3812
|
-
const
|
|
3813
|
-
|
|
3867
|
+
const payload = {
|
|
3868
|
+
...session.collectTestCss(),
|
|
3814
3869
|
source: "libraries",
|
|
3815
3870
|
order: 0,
|
|
3816
3871
|
prelude: rootSpacingPreludeCss(session.ensureMapping().increment)
|
|
@@ -3818,18 +3873,21 @@ function trussPlugin(opts) {
|
|
|
3818
3873
|
return `
|
|
3819
3874
|
import { __injectTrussCSS } from "@homebound/truss/runtime";
|
|
3820
3875
|
|
|
3821
|
-
__injectTrussCSS(${JSON.stringify(
|
|
3876
|
+
__injectTrussCSS(${JSON.stringify(payload)});
|
|
3822
3877
|
`;
|
|
3823
3878
|
}
|
|
3824
3879
|
if (id.startsWith(VIRTUAL_TEST_CSS_PREFIX)) {
|
|
3825
|
-
const sourcePath2 =
|
|
3880
|
+
const sourcePath2 = canonicalSourcePath(id.slice(VIRTUAL_TEST_CSS_PREFIX.length));
|
|
3826
3881
|
session.updateArbitraryCssRegistry(sourcePath2, readFileSync4(sourcePath2, "utf8"));
|
|
3827
|
-
const
|
|
3882
|
+
const payload = {
|
|
3883
|
+
arbitraryRules: splitArbitraryCss(session.getArbitraryCss(sourcePath2)),
|
|
3884
|
+
source: sourcePath2
|
|
3885
|
+
};
|
|
3828
3886
|
return `
|
|
3829
3887
|
import "${VIRTUAL_TEST_CSS_ID}";
|
|
3830
3888
|
import { __injectTrussCSS } from "@homebound/truss/runtime";
|
|
3831
3889
|
|
|
3832
|
-
__injectTrussCSS(${JSON.stringify(
|
|
3890
|
+
__injectTrussCSS(${JSON.stringify(payload)});
|
|
3833
3891
|
`;
|
|
3834
3892
|
}
|
|
3835
3893
|
if (!id.startsWith(VIRTUAL_CSS_PREFIX)) return null;
|
|
@@ -3851,32 +3909,8 @@ import "${VIRTUAL_TEST_CSS_ID}";` : rewrittenImports.code;
|
|
|
3851
3909
|
if (fileId.endsWith(".css.ts")) {
|
|
3852
3910
|
session.updateArbitraryCssRegistry(fileId, code);
|
|
3853
3911
|
if (isTest) {
|
|
3854
|
-
const css =
|
|
3855
|
-
|
|
3856
|
-
traverse(ast, {
|
|
3857
|
-
Program(path) {
|
|
3858
|
-
const inject = path.scope.generateUidIdentifier("injectTrussCSS");
|
|
3859
|
-
path.unshiftContainer(
|
|
3860
|
-
"body",
|
|
3861
|
-
t16.importDeclaration(
|
|
3862
|
-
[t16.importSpecifier(inject, t16.identifier("__injectTrussCSS"))],
|
|
3863
|
-
t16.stringLiteral("@homebound/truss/runtime")
|
|
3864
|
-
)
|
|
3865
|
-
);
|
|
3866
|
-
path.pushContainer(
|
|
3867
|
-
"body",
|
|
3868
|
-
t16.expressionStatement(
|
|
3869
|
-
t16.callExpression(inject, [
|
|
3870
|
-
t16.stringLiteral(css),
|
|
3871
|
-
t16.objectExpression([
|
|
3872
|
-
t16.objectProperty(t16.identifier("source"), t16.stringLiteral(resolve4(fileId).replace(/\\/g, "/")))
|
|
3873
|
-
])
|
|
3874
|
-
])
|
|
3875
|
-
)
|
|
3876
|
-
);
|
|
3877
|
-
}
|
|
3878
|
-
});
|
|
3879
|
-
return { code: generate(ast, { sourceFileName: fileId }).code, map: null };
|
|
3912
|
+
const css = session.getArbitraryCss(fileId);
|
|
3913
|
+
return { code: appendTestCssInjection(transformedCode, fileId, css), map: null };
|
|
3880
3914
|
}
|
|
3881
3915
|
return importsOnlyResult;
|
|
3882
3916
|
}
|
|
@@ -3938,6 +3972,30 @@ function stripQueryAndHash(id) {
|
|
|
3938
3972
|
function isNodeModulesFile(filePath) {
|
|
3939
3973
|
return filePath.replace(/\\/g, "/").includes("/node_modules/");
|
|
3940
3974
|
}
|
|
3975
|
+
function canonicalSourcePath(filePath) {
|
|
3976
|
+
return resolve4(filePath).replace(/\\/g, "/");
|
|
3977
|
+
}
|
|
3978
|
+
function appendTestCssInjection(code, fileId, css) {
|
|
3979
|
+
const ast = parseModule(code, fileId);
|
|
3980
|
+
let usedTopLevelNames = /* @__PURE__ */ new Set();
|
|
3981
|
+
traverse(ast, {
|
|
3982
|
+
Program(path) {
|
|
3983
|
+
usedTopLevelNames = new Set(Object.keys(path.scope.bindings));
|
|
3984
|
+
path.stop();
|
|
3985
|
+
}
|
|
3986
|
+
});
|
|
3987
|
+
const existing = findNamedImportBinding(ast, INJECT_CSS_HELPER, RUNTIME_MODULE2);
|
|
3988
|
+
const localName = existing ?? reservePreferredName(usedTopLevelNames, INJECT_CSS_HELPER);
|
|
3989
|
+
if (!existing) upsertNamedImports(ast, RUNTIME_MODULE2, [{ importedName: INJECT_CSS_HELPER, localName }]);
|
|
3990
|
+
ast.program.body.push(
|
|
3991
|
+
t16.expressionStatement(
|
|
3992
|
+
t16.callExpression(t16.identifier(localName), [
|
|
3993
|
+
t16.valueToNode({ arbitraryRules: splitArbitraryCss(css), source: canonicalSourcePath(fileId) })
|
|
3994
|
+
])
|
|
3995
|
+
)
|
|
3996
|
+
);
|
|
3997
|
+
return generate(ast, { sourceFileName: fileId }).code;
|
|
3998
|
+
}
|
|
3941
3999
|
export {
|
|
3942
4000
|
loadMapping,
|
|
3943
4001
|
trussEsbuildPlugin,
|