@plumeria/turbopack-loader 13.2.3 → 14.1.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/dist/index.js +80 -7
- package/dist/split-css-rules.d.ts +1 -0
- package/dist/split-css-rules.js +71 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ const fs = __importStar(require("fs"));
|
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
40
|
const zss_engine_1 = require("zss-engine");
|
|
41
41
|
const utils_1 = require("@plumeria/utils");
|
|
42
|
+
const split_css_rules_1 = require("./split-css-rules");
|
|
42
43
|
let lastValidCss = '';
|
|
43
44
|
async function loader(source) {
|
|
44
45
|
const callback = this.async();
|
|
@@ -69,6 +70,25 @@ async function loader(source) {
|
|
|
69
70
|
const sourceBuffer = Buffer.from(source, 'utf-8');
|
|
70
71
|
const leadingBytes = Buffer.byteLength(source.slice(0, leadingLen), 'utf-8');
|
|
71
72
|
const baseByteOffset = ast.span.start - leadingBytes;
|
|
73
|
+
const throwCompilationError = (message, node) => {
|
|
74
|
+
let suffix = '';
|
|
75
|
+
if (node) {
|
|
76
|
+
const offset = node.span.start - baseByteOffset;
|
|
77
|
+
let line = 1;
|
|
78
|
+
let colStart = 0;
|
|
79
|
+
for (let i = 0; i < offset && i < sourceBuffer.length; i++) {
|
|
80
|
+
if (sourceBuffer[i] === 10) {
|
|
81
|
+
line++;
|
|
82
|
+
colStart = i + 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const col = offset - colStart + 1;
|
|
86
|
+
suffix = ` (${path.basename(resourcePath)}:${line}:${col})`;
|
|
87
|
+
}
|
|
88
|
+
const err = new Error(`${message}${suffix}`);
|
|
89
|
+
err.stack = err.message;
|
|
90
|
+
throw err;
|
|
91
|
+
};
|
|
72
92
|
for (const node of ast.body) {
|
|
73
93
|
if (node.type === 'ImportDeclaration') {
|
|
74
94
|
const sourcePath = node.source.value;
|
|
@@ -257,7 +277,7 @@ async function loader(source) {
|
|
|
257
277
|
if ((localCreateStyles[varName] &&
|
|
258
278
|
localCreateStyles[varName].type === 'variant') ||
|
|
259
279
|
mergedVariantsTable[varName]) {
|
|
260
|
-
|
|
280
|
+
throwCompilationError(`Plumeria: Assigning the return value of css.variants() to a variable is not supported.\nPlease pass the variant function directly to styleName or css.use(). Found assignment to: ${utils_1.t.isIdentifier(decl.id) ? decl.id.value : 'unknown'}`, init);
|
|
261
281
|
}
|
|
262
282
|
}
|
|
263
283
|
};
|
|
@@ -410,7 +430,7 @@ async function loader(source) {
|
|
|
410
430
|
selector = selectorExpr.value;
|
|
411
431
|
}
|
|
412
432
|
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
413
|
-
|
|
433
|
+
throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
|
|
414
434
|
}
|
|
415
435
|
const obj = (0, utils_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
416
436
|
const hash = (0, zss_engine_1.genBase36Hash)({ _themeSelector: selector, ...obj }, 1, 8);
|
|
@@ -591,7 +611,7 @@ async function loader(source) {
|
|
|
591
611
|
selector = selectorExpr.value;
|
|
592
612
|
}
|
|
593
613
|
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
594
|
-
|
|
614
|
+
throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
|
|
595
615
|
}
|
|
596
616
|
const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
597
617
|
const hash = (0, zss_engine_1.genBase36Hash)({ _themeSelector: selector, ...obj }, 1, 8);
|
|
@@ -672,6 +692,24 @@ async function loader(source) {
|
|
|
672
692
|
let groupIdCounter = 0;
|
|
673
693
|
let baseStyle = {};
|
|
674
694
|
let isOptimizable = true;
|
|
695
|
+
const getRootIdentifier = (node) => {
|
|
696
|
+
if (utils_1.t.isIdentifier(node)) {
|
|
697
|
+
return node.value;
|
|
698
|
+
}
|
|
699
|
+
if (utils_1.t.isMemberExpression(node)) {
|
|
700
|
+
return getRootIdentifier(node.object);
|
|
701
|
+
}
|
|
702
|
+
if (utils_1.t.isCallExpression(node)) {
|
|
703
|
+
const callee = node.callee;
|
|
704
|
+
if (callee.type !== 'Super' && callee.type !== 'Import') {
|
|
705
|
+
return getRootIdentifier(callee);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
if (node.type === 'ParenthesisExpression') {
|
|
709
|
+
return getRootIdentifier(node.expression);
|
|
710
|
+
}
|
|
711
|
+
return null;
|
|
712
|
+
};
|
|
675
713
|
const collectConditions = (node, currentTestStrings = []) => {
|
|
676
714
|
const staticStyle = resolveStyleObject(node);
|
|
677
715
|
if (staticStyle) {
|
|
@@ -742,6 +780,21 @@ async function loader(source) {
|
|
|
742
780
|
variantObj = localCreateStyles[varName].obj;
|
|
743
781
|
if (variantObj) {
|
|
744
782
|
const callArgs = expr.arguments;
|
|
783
|
+
const hasSpread = callArgs.some((a) => {
|
|
784
|
+
if (a.spread)
|
|
785
|
+
return true;
|
|
786
|
+
if (a.expression.type === 'ObjectExpression') {
|
|
787
|
+
return a.expression.properties.some((p) => p.type === 'SpreadElement');
|
|
788
|
+
}
|
|
789
|
+
return false;
|
|
790
|
+
});
|
|
791
|
+
if (hasSpread) {
|
|
792
|
+
throwCompilationError(`Plumeria: Spread operator in ${getSource(expr)} is not supported. ` +
|
|
793
|
+
`Please pass specific variant options directly.`, expr);
|
|
794
|
+
}
|
|
795
|
+
if (callArgs.length !== 1) {
|
|
796
|
+
throwCompilationError(`Plumeria: Variant function "${varName}" expects exactly 1 argument, found ${callArgs.length}.`, expr);
|
|
797
|
+
}
|
|
745
798
|
if (callArgs.length === 1 && !callArgs[0].spread) {
|
|
746
799
|
const arg = callArgs[0].expression;
|
|
747
800
|
if (arg.type === 'ObjectExpression') {
|
|
@@ -848,6 +901,17 @@ async function loader(source) {
|
|
|
848
901
|
const handled = collectConditions(expr);
|
|
849
902
|
if (handled)
|
|
850
903
|
continue;
|
|
904
|
+
if (utils_1.t.isMemberExpression(expr) || utils_1.t.isIdentifier(expr)) {
|
|
905
|
+
const rootId = getRootIdentifier(expr);
|
|
906
|
+
const isPlumeriaStyle = rootId &&
|
|
907
|
+
((localCreateStyles[rootId] !== undefined &&
|
|
908
|
+
localCreateStyles[rootId].type !== 'constant') ||
|
|
909
|
+
mergedCreateTable[rootId] !== undefined ||
|
|
910
|
+
mergedVariantsTable[rootId] !== undefined);
|
|
911
|
+
if (!isPlumeriaStyle) {
|
|
912
|
+
throwCompilationError(`Plumeria: Dynamic or unresolvable style object "${getSource(expr)}" is not supported.`, expr);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
851
915
|
isOptimizable = false;
|
|
852
916
|
break;
|
|
853
917
|
}
|
|
@@ -1420,7 +1484,7 @@ async function loader(source) {
|
|
|
1420
1484
|
const propKey = callee.property.value;
|
|
1421
1485
|
const styleInfo = localCreateStyles[varName];
|
|
1422
1486
|
if (styleInfo?.functions?.[propKey]) {
|
|
1423
|
-
|
|
1487
|
+
throwCompilationError(`Plumeria: css.use(${getSource(expr)}) does not support dynamic function keys.`, expr);
|
|
1424
1488
|
}
|
|
1425
1489
|
}
|
|
1426
1490
|
const { classParts, isOptimizable, baseStyle } = buildClassParts(args);
|
|
@@ -1477,15 +1541,24 @@ async function loader(source) {
|
|
|
1477
1541
|
return callback(null, transformedSource);
|
|
1478
1542
|
}
|
|
1479
1543
|
if (extractedSheets.length > 0 && process.env.NODE_ENV === 'development') {
|
|
1480
|
-
const newCss = optInCSS + '\n';
|
|
1481
1544
|
let currentCss = '';
|
|
1482
1545
|
try {
|
|
1483
1546
|
currentCss = fs.readFileSync(VIRTUAL_FILE_PATH, 'utf-8');
|
|
1484
1547
|
}
|
|
1485
1548
|
catch (e) {
|
|
1486
1549
|
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1550
|
+
const currentRules = (0, split_css_rules_1.splitCssRules)(currentCss);
|
|
1551
|
+
const newRules = (0, split_css_rules_1.splitCssRules)(optInCSS);
|
|
1552
|
+
const ruleSet = new Set(currentRules);
|
|
1553
|
+
let hasNewRule = false;
|
|
1554
|
+
for (const rule of newRules) {
|
|
1555
|
+
if (!ruleSet.has(rule)) {
|
|
1556
|
+
ruleSet.add(rule);
|
|
1557
|
+
hasNewRule = true;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
if (hasNewRule || isThemeCSS) {
|
|
1561
|
+
const nextCss = Array.from(ruleSet).join('\n\n') + '\n';
|
|
1489
1562
|
fs.writeFileSync(VIRTUAL_FILE_PATH, nextCss, 'utf-8');
|
|
1490
1563
|
lastValidCss = nextCss;
|
|
1491
1564
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function splitCssRules(css: string): string[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.splitCssRules = splitCssRules;
|
|
4
|
+
function splitCssRules(css) {
|
|
5
|
+
const rules = [];
|
|
6
|
+
let currentRule = '';
|
|
7
|
+
let depth = 0;
|
|
8
|
+
let inComment = false;
|
|
9
|
+
let inString = null;
|
|
10
|
+
for (let i = 0; i < css.length; i++) {
|
|
11
|
+
const char = css[i];
|
|
12
|
+
const nextChar = css[i + 1];
|
|
13
|
+
if (inComment) {
|
|
14
|
+
currentRule += char;
|
|
15
|
+
if (char === '*' && nextChar === '/') {
|
|
16
|
+
currentRule += '/';
|
|
17
|
+
i++;
|
|
18
|
+
inComment = false;
|
|
19
|
+
}
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (char === '/' && nextChar === '*') {
|
|
23
|
+
currentRule += '/*';
|
|
24
|
+
i++;
|
|
25
|
+
inComment = true;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (inString) {
|
|
29
|
+
currentRule += char;
|
|
30
|
+
if (char === '\\') {
|
|
31
|
+
if (nextChar) {
|
|
32
|
+
currentRule += nextChar;
|
|
33
|
+
i++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (char === inString) {
|
|
37
|
+
inString = null;
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (char === '"' || char === "'") {
|
|
42
|
+
currentRule += char;
|
|
43
|
+
inString = char;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
currentRule += char;
|
|
47
|
+
if (char === '{') {
|
|
48
|
+
depth++;
|
|
49
|
+
}
|
|
50
|
+
else if (char === '}') {
|
|
51
|
+
depth--;
|
|
52
|
+
if (depth === 0) {
|
|
53
|
+
const trimmed = currentRule.trim();
|
|
54
|
+
if (trimmed)
|
|
55
|
+
rules.push(trimmed);
|
|
56
|
+
currentRule = '';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (char === ';' && depth === 0) {
|
|
60
|
+
const trimmed = currentRule.trim();
|
|
61
|
+
if (trimmed)
|
|
62
|
+
rules.push(trimmed);
|
|
63
|
+
currentRule = '';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const trimmed = currentRule.trim();
|
|
67
|
+
if (trimmed && depth === 0) {
|
|
68
|
+
rules.push(trimmed);
|
|
69
|
+
}
|
|
70
|
+
return rules;
|
|
71
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumeria/turbopack-loader",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.1.0",
|
|
4
4
|
"description": "Plumeria Turbopack-loader",
|
|
5
5
|
"author": "Refirst 11",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"zero-virtual.css"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@plumeria/utils": "^
|
|
25
|
+
"@plumeria/utils": "^14.1.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@swc/core": "1.15.41",
|