@plumeria/compiler 18.5.0 → 18.5.2
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 +269 -91
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -65,6 +65,56 @@ const componentFunctionOf = (node) => {
|
|
|
65
65
|
}
|
|
66
66
|
return undefined;
|
|
67
67
|
};
|
|
68
|
+
const unwrapPatternDefault = (pattern) => pattern?.type === 'AssignmentPattern' ? pattern.left : pattern;
|
|
69
|
+
const resolveLocalStyleAlias = (aliases, expression) => {
|
|
70
|
+
let current = expression;
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
while (utils_1.t.isIdentifier(current)) {
|
|
73
|
+
const name = current.value;
|
|
74
|
+
if (seen.has(name))
|
|
75
|
+
break;
|
|
76
|
+
seen.add(name);
|
|
77
|
+
const candidates = aliases[name];
|
|
78
|
+
if (!candidates || candidates.length === 0)
|
|
79
|
+
break;
|
|
80
|
+
const candidate = candidates.find((candidate) => candidate.context === current.ctxt);
|
|
81
|
+
if (!candidate)
|
|
82
|
+
break;
|
|
83
|
+
current = candidate.expression;
|
|
84
|
+
}
|
|
85
|
+
return current;
|
|
86
|
+
};
|
|
87
|
+
const destructuredPropAliases = (fn) => {
|
|
88
|
+
const aliases = new Map();
|
|
89
|
+
const first = fn.params[0];
|
|
90
|
+
const pattern = unwrapPatternDefault(first?.pat ?? first);
|
|
91
|
+
if (pattern?.type !== 'ObjectPattern')
|
|
92
|
+
return aliases;
|
|
93
|
+
for (const item of pattern.properties ?? []) {
|
|
94
|
+
if (item.type !== 'KeyValuePatternProperty')
|
|
95
|
+
continue;
|
|
96
|
+
const local = unwrapPatternDefault(item.value);
|
|
97
|
+
const key = item.key;
|
|
98
|
+
if (!utils_1.t.isIdentifier(local))
|
|
99
|
+
continue;
|
|
100
|
+
if (!utils_1.t.isIdentifier(key) && !utils_1.t.isStringLiteral(key))
|
|
101
|
+
continue;
|
|
102
|
+
const name = String(key.value);
|
|
103
|
+
if (name !== local.value)
|
|
104
|
+
aliases.set(local.value, name);
|
|
105
|
+
}
|
|
106
|
+
return aliases;
|
|
107
|
+
};
|
|
108
|
+
const sourceOf = (node, sourceBuffer, baseByteOffset) => sourceBuffer
|
|
109
|
+
.subarray(node.span.start - baseByteOffset, node.span.end - baseByteOffset)
|
|
110
|
+
.toString('utf-8');
|
|
111
|
+
const isNoOpStyle = (node) => utils_1.t.isNullLiteral(node) ||
|
|
112
|
+
(utils_1.t.isBooleanLiteral(node) && node.value === false) ||
|
|
113
|
+
(utils_1.t.isIdentifier(node) && node.value === 'undefined');
|
|
114
|
+
const propDefaultError = (source, fileName) => new Error(`[plumeria] A style prop default must be a defined style: "${source}". ` +
|
|
115
|
+
`Apply a conditional or dynamic style where the element is styled. (${fileName})`);
|
|
116
|
+
const spreadStyleError = (source, fileName) => new Error(`[plumeria] Spread elements in a style array are not supported: "...${source}". ` +
|
|
117
|
+
`List each style explicitly. (${fileName})`);
|
|
68
118
|
const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
|
|
69
119
|
node.type === 'NumericLiteral' ||
|
|
70
120
|
node.type === 'BooleanLiteral' ||
|
|
@@ -83,10 +133,9 @@ const dynamicTablesOf = (ctx) => ({
|
|
|
83
133
|
});
|
|
84
134
|
function extractStylesFromExpression(expression, ctx) {
|
|
85
135
|
let expr = expression;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
ctx.localStyleAliases
|
|
89
|
-
expr = ctx.localStyleAliases[expr.value];
|
|
136
|
+
expr = (0, utils_1.unwrapExpression)(expr);
|
|
137
|
+
if (ctx.localStyleAliases) {
|
|
138
|
+
expr = resolveLocalStyleAlias(ctx.localStyleAliases, expr);
|
|
90
139
|
}
|
|
91
140
|
const results = [];
|
|
92
141
|
if (utils_1.t.isMemberExpression(expr)) {
|
|
@@ -155,6 +204,25 @@ function extractStylesFromExpression(expression, ctx) {
|
|
|
155
204
|
}
|
|
156
205
|
}
|
|
157
206
|
}
|
|
207
|
+
else if (expr.type === 'ArrayExpression') {
|
|
208
|
+
const spreads = [];
|
|
209
|
+
const elementStyles = [];
|
|
210
|
+
for (const element of expr.elements ?? []) {
|
|
211
|
+
if (!element)
|
|
212
|
+
continue;
|
|
213
|
+
if (element.spread) {
|
|
214
|
+
spreads.push(element.expression);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
elementStyles.push(...extractStylesFromExpression(element.expression, ctx));
|
|
218
|
+
}
|
|
219
|
+
for (const spread of spreads) {
|
|
220
|
+
if (elementStyles.length > 0 ||
|
|
221
|
+
extractStylesFromExpression(spread, ctx).length > 0)
|
|
222
|
+
throw spreadStyleError(sourceOf(spread, ctx.sourceBuffer, ctx.baseByteOffset), path.basename(ctx.resourcePath));
|
|
223
|
+
}
|
|
224
|
+
results.push(...elementStyles);
|
|
225
|
+
}
|
|
158
226
|
else if (utils_1.t.isConditionalExpression(expr)) {
|
|
159
227
|
const condExpr = expr;
|
|
160
228
|
results.push(...extractStylesFromExpression(condExpr.consequent, ctx));
|
|
@@ -181,7 +249,7 @@ function compileCSS(options) {
|
|
|
181
249
|
exclude: exclude,
|
|
182
250
|
sort: true,
|
|
183
251
|
});
|
|
184
|
-
const scannedTables = (0, utils_1.scanAll)();
|
|
252
|
+
const scannedTables = (0, utils_1.scanAll)(cwd);
|
|
185
253
|
const processFile = (filePath) => {
|
|
186
254
|
const resourcePath = path.resolve(cwd, filePath);
|
|
187
255
|
const source = fs.readFileSync(resourcePath, 'utf-8');
|
|
@@ -354,6 +422,7 @@ function compileCSS(options) {
|
|
|
354
422
|
mergedVariantsTable[key] = variantsImportMap[key];
|
|
355
423
|
}
|
|
356
424
|
const ctx = {
|
|
425
|
+
resourcePath,
|
|
357
426
|
mergedStaticTable,
|
|
358
427
|
mergedKeyframesTable,
|
|
359
428
|
mergedViewTransitionTable,
|
|
@@ -370,15 +439,17 @@ function compileCSS(options) {
|
|
|
370
439
|
};
|
|
371
440
|
const componentParamNames = new Set();
|
|
372
441
|
const addFirstParamName = (fn) => {
|
|
373
|
-
const
|
|
442
|
+
const first = fn.params[0];
|
|
443
|
+
const p = unwrapPatternDefault(first?.pat ?? first);
|
|
374
444
|
if (utils_1.t.isIdentifier(p)) {
|
|
375
445
|
componentParamNames.add(p.value);
|
|
376
446
|
}
|
|
377
|
-
else if (
|
|
378
|
-
p
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
447
|
+
else if (p?.type === 'ObjectPattern') {
|
|
448
|
+
for (const item of p.properties ?? []) {
|
|
449
|
+
if (item.type === 'RestElement' && utils_1.t.isIdentifier(item.argument)) {
|
|
450
|
+
componentParamNames.add(item.argument.value);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
382
453
|
}
|
|
383
454
|
};
|
|
384
455
|
for (const node of ast.body) {
|
|
@@ -402,18 +473,43 @@ function compileCSS(options) {
|
|
|
402
473
|
}
|
|
403
474
|
}
|
|
404
475
|
const components = [];
|
|
476
|
+
const propAliases = new Map();
|
|
477
|
+
const propDefaults = new Map();
|
|
478
|
+
const declaredProps = new Map();
|
|
479
|
+
const addComponent = (name, fn) => {
|
|
480
|
+
components.push({ name, node: fn });
|
|
481
|
+
const first = fn.params[0];
|
|
482
|
+
const pattern = unwrapPatternDefault(first?.pat ?? first);
|
|
483
|
+
const defaults = new Map();
|
|
484
|
+
for (const item of pattern?.properties ?? []) {
|
|
485
|
+
if (item.type === 'AssignmentPatternProperty' && item.value)
|
|
486
|
+
defaults.set(item.key.value, item.value);
|
|
487
|
+
if (item.type === 'KeyValuePatternProperty' &&
|
|
488
|
+
item.value?.type === 'AssignmentPattern')
|
|
489
|
+
defaults.set(item.key.value, item.value.right);
|
|
490
|
+
}
|
|
491
|
+
propDefaults.set(name, defaults);
|
|
492
|
+
const aliases = destructuredPropAliases(fn);
|
|
493
|
+
if (aliases.size > 0)
|
|
494
|
+
propAliases.set(name, aliases);
|
|
495
|
+
const declared = new Set();
|
|
496
|
+
for (const item of pattern?.properties ?? []) {
|
|
497
|
+
const key = item.key;
|
|
498
|
+
if (utils_1.t.isIdentifier(key) || utils_1.t.isStringLiteral(key))
|
|
499
|
+
declared.add(String(key.value));
|
|
500
|
+
}
|
|
501
|
+
if (declared.size > 0)
|
|
502
|
+
declaredProps.set(name, declared);
|
|
503
|
+
};
|
|
405
504
|
for (const node of ast.body) {
|
|
406
505
|
const statement = unwrapExport(node);
|
|
407
506
|
if (isFunctionNode(statement)) {
|
|
408
|
-
|
|
409
|
-
name: statement.identifier?.value ?? 'default',
|
|
410
|
-
node: statement,
|
|
411
|
-
});
|
|
507
|
+
addComponent(statement.identifier?.value ?? 'default', statement);
|
|
412
508
|
}
|
|
413
509
|
else if (statement?.type === 'CallExpression') {
|
|
414
510
|
const fn = componentFunctionOf(statement);
|
|
415
511
|
if (fn)
|
|
416
|
-
|
|
512
|
+
addComponent('default', fn);
|
|
417
513
|
}
|
|
418
514
|
else if (utils_1.t.isVariableDeclaration(statement)) {
|
|
419
515
|
for (const decl of statement.declarations) {
|
|
@@ -421,7 +517,7 @@ function compileCSS(options) {
|
|
|
421
517
|
continue;
|
|
422
518
|
const fn = componentFunctionOf(decl.init);
|
|
423
519
|
if (fn)
|
|
424
|
-
|
|
520
|
+
addComponent(decl.id.value, fn);
|
|
425
521
|
}
|
|
426
522
|
}
|
|
427
523
|
}
|
|
@@ -434,14 +530,26 @@ function compileCSS(options) {
|
|
|
434
530
|
};
|
|
435
531
|
const extractAndProcessConditionals = (args) => {
|
|
436
532
|
args.forEach((arg) => {
|
|
437
|
-
|
|
438
|
-
localStyleAliases[arg.expression.value]) {
|
|
439
|
-
arg.expression = localStyleAliases[arg.expression.value];
|
|
440
|
-
}
|
|
533
|
+
arg.expression = resolveLocalStyleAlias(localStyleAliases, arg.expression);
|
|
441
534
|
});
|
|
442
535
|
const conditionals = [];
|
|
443
536
|
let baseStyle = {};
|
|
444
537
|
const resolveStyleObject = (expr) => {
|
|
538
|
+
expr = resolveLocalStyleAlias(localStyleAliases, (0, utils_1.unwrapExpression)(expr));
|
|
539
|
+
if (expr.type === 'ArrayExpression') {
|
|
540
|
+
let merged = {};
|
|
541
|
+
for (const element of expr.elements ?? []) {
|
|
542
|
+
if (!element)
|
|
543
|
+
continue;
|
|
544
|
+
if (element.spread)
|
|
545
|
+
throw spreadStyleError(getSource(element.expression), path.basename(resourcePath));
|
|
546
|
+
const style = resolveStyleObject(element.expression);
|
|
547
|
+
if (!style)
|
|
548
|
+
return null;
|
|
549
|
+
merged = (0, utils_1.deepMerge)(merged, style);
|
|
550
|
+
}
|
|
551
|
+
return merged;
|
|
552
|
+
}
|
|
445
553
|
if (utils_1.t.isObjectExpression(expr)) {
|
|
446
554
|
return (0, utils_1.objectExpressionToObject)(expr, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
|
|
447
555
|
}
|
|
@@ -490,9 +598,7 @@ function compileCSS(options) {
|
|
|
490
598
|
}
|
|
491
599
|
return null;
|
|
492
600
|
};
|
|
493
|
-
const getSource = (node) => ctx.sourceBuffer
|
|
494
|
-
.subarray(node.span.start - ctx.baseByteOffset, node.span.end - ctx.baseByteOffset)
|
|
495
|
-
.toString('utf-8');
|
|
601
|
+
const getSource = (node) => sourceOf(node, ctx.sourceBuffer, ctx.baseByteOffset);
|
|
496
602
|
const assertResolvable = (node) => {
|
|
497
603
|
if (utils_1.t.isIdentifier(node) && node.value === 'undefined')
|
|
498
604
|
return;
|
|
@@ -555,7 +661,14 @@ function compileCSS(options) {
|
|
|
555
661
|
if (callArgs.some((a) => a.spread))
|
|
556
662
|
return null;
|
|
557
663
|
const tempStaticTable = { ...ctx.mergedStaticTable };
|
|
664
|
+
const providedParams = new Set();
|
|
558
665
|
const runtime = [];
|
|
666
|
+
const resolveObjectArg = (argExpr) => (0, utils_1.objectExpressionToObject)({
|
|
667
|
+
...argExpr,
|
|
668
|
+
properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
|
|
669
|
+
(prop.type === 'KeyValueProperty' &&
|
|
670
|
+
isStaticArgValue(prop.value))),
|
|
671
|
+
}, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
|
|
559
672
|
if (func.named) {
|
|
560
673
|
const argExpr = callArgs[0]?.expression;
|
|
561
674
|
if (callArgs.length > 1 ||
|
|
@@ -572,9 +685,9 @@ function compileCSS(options) {
|
|
|
572
685
|
given.set(String(prop.key.value), prop.value);
|
|
573
686
|
}
|
|
574
687
|
});
|
|
575
|
-
const argObj =
|
|
576
|
-
? {}
|
|
577
|
-
:
|
|
688
|
+
const argObj = argExpr
|
|
689
|
+
? (resolveObjectArg(argExpr) ?? {})
|
|
690
|
+
: {};
|
|
578
691
|
func.named.forEach(({ key, local }) => {
|
|
579
692
|
const source = given.get(key);
|
|
580
693
|
if (!source) {
|
|
@@ -582,18 +695,22 @@ function compileCSS(options) {
|
|
|
582
695
|
return;
|
|
583
696
|
throw new Error(`[plumeria] ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.\n`);
|
|
584
697
|
}
|
|
585
|
-
if (isStaticArgValue(source) && argObj[key] !== undefined)
|
|
698
|
+
if (isStaticArgValue(source) && argObj[key] !== undefined) {
|
|
586
699
|
tempStaticTable[local] = argObj[key];
|
|
700
|
+
providedParams.add(local);
|
|
701
|
+
}
|
|
587
702
|
else
|
|
588
703
|
runtime.push(local);
|
|
589
704
|
});
|
|
590
705
|
}
|
|
591
706
|
else if (callArgs.length === 1 &&
|
|
592
707
|
callArgs[0].expression.type === 'ObjectExpression') {
|
|
593
|
-
const argObj = (
|
|
708
|
+
const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
|
|
594
709
|
func.params.forEach((p) => {
|
|
595
|
-
if (argObj[p] !== undefined)
|
|
710
|
+
if (argObj[p] !== undefined) {
|
|
596
711
|
tempStaticTable[p] = argObj[p];
|
|
712
|
+
providedParams.add(p);
|
|
713
|
+
}
|
|
597
714
|
});
|
|
598
715
|
}
|
|
599
716
|
else {
|
|
@@ -604,13 +721,88 @@ function compileCSS(options) {
|
|
|
604
721
|
runtime.push(p);
|
|
605
722
|
});
|
|
606
723
|
}
|
|
607
|
-
const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx));
|
|
724
|
+
const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
|
|
608
725
|
if (!resolved)
|
|
609
726
|
return null;
|
|
610
727
|
const { style } = resolved;
|
|
611
728
|
return style;
|
|
612
729
|
};
|
|
730
|
+
const collectPropStyles = (expr) => {
|
|
731
|
+
const isParamMember = utils_1.t.isMemberExpression(expr) &&
|
|
732
|
+
utils_1.t.isIdentifier(expr.object) &&
|
|
733
|
+
componentParamNames.has(expr.object.value) &&
|
|
734
|
+
utils_1.t.isIdentifier(expr.property);
|
|
735
|
+
if (!utils_1.t.isIdentifier(expr) && !isParamMember)
|
|
736
|
+
return false;
|
|
737
|
+
const paramObject = isParamMember
|
|
738
|
+
? expr.object.value
|
|
739
|
+
: undefined;
|
|
740
|
+
const isPropsMember = Boolean(paramObject &&
|
|
741
|
+
ctx.localCreateStyles[paramObject] === undefined &&
|
|
742
|
+
ctx.mergedCreateTable[paramObject] === undefined);
|
|
743
|
+
const varName = utils_1.t.isIdentifier(expr)
|
|
744
|
+
? expr.value
|
|
745
|
+
: expr.property.value;
|
|
746
|
+
const owner = ownerComponentOf(expr);
|
|
747
|
+
const propName = (utils_1.t.isIdentifier(expr) && owner
|
|
748
|
+
? propAliases.get(owner)?.get(varName)
|
|
749
|
+
: undefined) ?? varName;
|
|
750
|
+
const possibilities = [];
|
|
751
|
+
if (owner) {
|
|
752
|
+
const entries = ctx.scannedTables.componentPropsTable?.[`${resourcePath}-${owner}`]?.[propName];
|
|
753
|
+
if (entries)
|
|
754
|
+
possibilities.push(...entries);
|
|
755
|
+
}
|
|
756
|
+
if (possibilities.length === 0) {
|
|
757
|
+
const filePrefix = `${resourcePath}-`;
|
|
758
|
+
for (const key of Object.keys(ctx.scannedTables.componentPropsTable || {})) {
|
|
759
|
+
if (!key.startsWith(filePrefix))
|
|
760
|
+
continue;
|
|
761
|
+
const entries = ctx.scannedTables.componentPropsTable?.[key]?.[propName];
|
|
762
|
+
if (entries)
|
|
763
|
+
possibilities.push(...entries);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
const fallback = owner && propDefaults.get(owner)?.get(propName);
|
|
767
|
+
if (fallback && !isNoOpStyle((0, utils_1.unwrapExpression)(fallback))) {
|
|
768
|
+
const style = resolveStyleObject(fallback);
|
|
769
|
+
if (!style)
|
|
770
|
+
throw propDefaultError(getSource(fallback), path.basename(resourcePath));
|
|
771
|
+
processStyle(style);
|
|
772
|
+
}
|
|
773
|
+
if (possibilities.length > 0) {
|
|
774
|
+
const uniqueEntries = [];
|
|
775
|
+
possibilities.forEach((entry) => {
|
|
776
|
+
if (!uniqueEntries.some((x) => x.key === entry.key)) {
|
|
777
|
+
uniqueEntries.push(entry);
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
uniqueEntries.forEach((entry) => {
|
|
781
|
+
if (entry.styleObj && Object.keys(entry.styleObj).length > 0) {
|
|
782
|
+
processStyle(entry.styleObj);
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
return true;
|
|
786
|
+
}
|
|
787
|
+
if (fallback)
|
|
788
|
+
return true;
|
|
789
|
+
return Boolean(isPropsMember || (owner && declaredProps.get(owner)?.has(propName)));
|
|
790
|
+
};
|
|
613
791
|
const collectConditions = (node, currentTestStrings = []) => {
|
|
792
|
+
node = resolveLocalStyleAlias(localStyleAliases, (0, utils_1.unwrapExpression)(node));
|
|
793
|
+
if (node.type === 'ArrayExpression') {
|
|
794
|
+
let handled = true;
|
|
795
|
+
for (const element of node.elements ?? []) {
|
|
796
|
+
if (!element)
|
|
797
|
+
continue;
|
|
798
|
+
if (element.spread)
|
|
799
|
+
throw spreadStyleError(getSource(element.expression), path.basename(resourcePath));
|
|
800
|
+
handled =
|
|
801
|
+
collectConditions(element.expression, currentTestStrings) &&
|
|
802
|
+
handled;
|
|
803
|
+
}
|
|
804
|
+
return handled;
|
|
805
|
+
}
|
|
614
806
|
if (node.type === 'ConditionalExpression') {
|
|
615
807
|
const testSource = getSource(node.test);
|
|
616
808
|
if (currentTestStrings.length === 0) {
|
|
@@ -647,6 +839,8 @@ function compileCSS(options) {
|
|
|
647
839
|
else if (node.type === 'ParenthesisExpression') {
|
|
648
840
|
return collectConditions(node.expression, currentTestStrings);
|
|
649
841
|
}
|
|
842
|
+
if (collectPropStyles(node))
|
|
843
|
+
return true;
|
|
650
844
|
const staticStyle = resolveStyleObject(node) ?? resolveDynamicCall(node);
|
|
651
845
|
if (staticStyle) {
|
|
652
846
|
if (currentTestStrings.length === 0) {
|
|
@@ -681,46 +875,8 @@ function compileCSS(options) {
|
|
|
681
875
|
};
|
|
682
876
|
for (const arg of args) {
|
|
683
877
|
const expr = arg.expression;
|
|
684
|
-
if (
|
|
685
|
-
|
|
686
|
-
utils_1.t.isIdentifier(expr.object) &&
|
|
687
|
-
componentParamNames.has(expr.object.value) &&
|
|
688
|
-
utils_1.t.isIdentifier(expr.property))) {
|
|
689
|
-
const varName = utils_1.t.isIdentifier(expr)
|
|
690
|
-
? expr.value
|
|
691
|
-
: expr.property.value;
|
|
692
|
-
const owner = ownerComponentOf(expr);
|
|
693
|
-
const propPossibilities = [];
|
|
694
|
-
if (owner) {
|
|
695
|
-
const entries = ctx.scannedTables.componentPropsTable?.[`${resourcePath}-${owner}`]?.[varName];
|
|
696
|
-
if (entries)
|
|
697
|
-
propPossibilities.push(...entries);
|
|
698
|
-
}
|
|
699
|
-
if (propPossibilities.length === 0) {
|
|
700
|
-
const filePrefix = `${resourcePath}-`;
|
|
701
|
-
for (const key of Object.keys(ctx.scannedTables.componentPropsTable || {})) {
|
|
702
|
-
if (!key.startsWith(filePrefix))
|
|
703
|
-
continue;
|
|
704
|
-
const entries = ctx.scannedTables.componentPropsTable?.[key]?.[varName];
|
|
705
|
-
if (entries)
|
|
706
|
-
propPossibilities.push(...entries);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
if (propPossibilities.length > 0) {
|
|
710
|
-
const uniqueEntries = [];
|
|
711
|
-
propPossibilities.forEach((entry) => {
|
|
712
|
-
if (!uniqueEntries.some((x) => x.key === entry.key)) {
|
|
713
|
-
uniqueEntries.push(entry);
|
|
714
|
-
}
|
|
715
|
-
});
|
|
716
|
-
uniqueEntries.forEach((entry) => {
|
|
717
|
-
if (entry.styleObj && Object.keys(entry.styleObj).length > 0) {
|
|
718
|
-
processStyle(entry.styleObj);
|
|
719
|
-
}
|
|
720
|
-
});
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
878
|
+
if (collectPropStyles(expr))
|
|
879
|
+
continue;
|
|
724
880
|
const dynamicStyle = resolveDynamicCall(expr);
|
|
725
881
|
if (dynamicStyle) {
|
|
726
882
|
baseStyle = (0, utils_1.deepMerge)(baseStyle, dynamicStyle);
|
|
@@ -789,6 +945,10 @@ function compileCSS(options) {
|
|
|
789
945
|
throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
|
|
790
946
|
`Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
|
|
791
947
|
}
|
|
948
|
+
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
949
|
+
throw new Error(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports ` +
|
|
950
|
+
`nesting at-rules such as @media, @container, @supports, @layer, and @scope. (${path.basename(resourcePath)})`);
|
|
951
|
+
}
|
|
792
952
|
const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
|
|
793
953
|
const hash = (0, utils_1.themeHashOf)(selector, obj);
|
|
794
954
|
ctx.scannedTables.createThemeObjectTable[hash] = obj;
|
|
@@ -817,7 +977,7 @@ function compileCSS(options) {
|
|
|
817
977
|
(0, utils_1.traverse)(ast, {
|
|
818
978
|
VariableDeclarator({ node }) {
|
|
819
979
|
if (utils_1.t.isIdentifier(node.id) && node.init) {
|
|
820
|
-
const init = node.init;
|
|
980
|
+
const init = (0, utils_1.unwrapExpression)(node.init);
|
|
821
981
|
if (utils_1.t.isCallExpression(init)) {
|
|
822
982
|
const callee = init.callee;
|
|
823
983
|
let pName;
|
|
@@ -832,17 +992,18 @@ function compileCSS(options) {
|
|
|
832
992
|
pName = plumeriaAliases[callee.value];
|
|
833
993
|
}
|
|
834
994
|
const isTheme = pName === 'createTheme';
|
|
995
|
+
const definitionArg = pName === 'createTheme'
|
|
996
|
+
? init.arguments[1]?.expression
|
|
997
|
+
: init.arguments[0]?.expression;
|
|
998
|
+
const unwrappedDefinitionArg = definitionArg
|
|
999
|
+
? (0, utils_1.unwrapExpression)(definitionArg)
|
|
1000
|
+
: undefined;
|
|
835
1001
|
if (pName &&
|
|
836
|
-
|
|
837
|
-
(
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
init.arguments.length >= 2 &&
|
|
842
|
-
utils_1.t.isObjectExpression(init.arguments[1].expression)))) {
|
|
843
|
-
const arg = isTheme
|
|
844
|
-
? init.arguments[1].expression
|
|
845
|
-
: init.arguments[0].expression;
|
|
1002
|
+
unwrappedDefinitionArg &&
|
|
1003
|
+
utils_1.t.isObjectExpression(unwrappedDefinitionArg) &&
|
|
1004
|
+
((!isTheme && init.arguments.length === 1) ||
|
|
1005
|
+
(isTheme && init.arguments.length >= 2))) {
|
|
1006
|
+
const arg = unwrappedDefinitionArg;
|
|
846
1007
|
const resolveVariable = (name) => ctx.localCreateStyles[name]?.obj ||
|
|
847
1008
|
(ctx.mergedCreateThemeHashTable[name]
|
|
848
1009
|
? ctx.scannedTables.createAtomicMapTable[ctx.mergedCreateThemeHashTable[name]]
|
|
@@ -865,6 +1026,10 @@ function compileCSS(options) {
|
|
|
865
1026
|
throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
|
|
866
1027
|
`Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
|
|
867
1028
|
}
|
|
1029
|
+
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
1030
|
+
throw new Error(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports ` +
|
|
1031
|
+
`nesting at-rules such as @media, @container, @supports, @layer, and @scope. (${path.basename(resourcePath)})`);
|
|
1032
|
+
}
|
|
868
1033
|
const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
|
|
869
1034
|
const hash = (0, utils_1.themeHashOf)(selector, obj);
|
|
870
1035
|
const uKey = `${resourcePath}-${node.id.value}`;
|
|
@@ -902,7 +1067,10 @@ function compileCSS(options) {
|
|
|
902
1067
|
const objName = init.object.value;
|
|
903
1068
|
if (ctx.localCreateStyles[objName] !== undefined ||
|
|
904
1069
|
ctx.mergedCreateTable[objName] !== undefined) {
|
|
905
|
-
localStyleAliases[node.id.value]
|
|
1070
|
+
(localStyleAliases[node.id.value] ??= []).push({
|
|
1071
|
+
expression: init,
|
|
1072
|
+
context: node.id.ctxt,
|
|
1073
|
+
});
|
|
906
1074
|
}
|
|
907
1075
|
}
|
|
908
1076
|
}
|
|
@@ -944,9 +1112,7 @@ function compileCSS(options) {
|
|
|
944
1112
|
if (value.expression.type === 'JSXEmptyExpression')
|
|
945
1113
|
return;
|
|
946
1114
|
let expr = value.expression;
|
|
947
|
-
|
|
948
|
-
expr = localStyleAliases[expr.value];
|
|
949
|
-
}
|
|
1115
|
+
expr = resolveLocalStyleAlias(localStyleAliases, expr);
|
|
950
1116
|
extractStylesFromExpression(expr, ctx).forEach(processStyle);
|
|
951
1117
|
});
|
|
952
1118
|
},
|
|
@@ -960,11 +1126,23 @@ function compileCSS(options) {
|
|
|
960
1126
|
if (node.value.expression.type === 'JSXEmptyExpression')
|
|
961
1127
|
return;
|
|
962
1128
|
const expr = node.value.expression;
|
|
963
|
-
const args =
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1129
|
+
const args = [];
|
|
1130
|
+
const addArgs = (node) => {
|
|
1131
|
+
node = (0, utils_1.unwrapExpression)(node);
|
|
1132
|
+
if (node.type === 'ArrayExpression') {
|
|
1133
|
+
for (const element of node.elements ?? []) {
|
|
1134
|
+
if (!element)
|
|
1135
|
+
continue;
|
|
1136
|
+
if (element.spread)
|
|
1137
|
+
throw spreadStyleError(sourceOf(element.expression, sourceBuffer, baseByteOffset), path.basename(resourcePath));
|
|
1138
|
+
addArgs(element.expression);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
else {
|
|
1142
|
+
args.push({ expression: node });
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
addArgs(expr);
|
|
968
1146
|
extractAndProcessConditionals(args);
|
|
969
1147
|
},
|
|
970
1148
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumeria/compiler",
|
|
3
|
-
"version": "18.5.
|
|
3
|
+
"version": "18.5.2",
|
|
4
4
|
"description": "Plumeria swc based compiler for statically extracting css",
|
|
5
5
|
"author": "Refirst 11",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dist/"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@plumeria/utils": "^18.5.
|
|
24
|
+
"@plumeria/utils": "^18.5.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@rust-gear/glob": "1.1.1",
|