@plumeria/compiler 18.5.0 → 18.5.1

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.
Files changed (2) hide show
  1. package/dist/index.js +261 -91
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -65,6 +65,52 @@ 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
+ item.type !== 'AssignmentPatternProperty')
96
+ continue;
97
+ const key = item.key;
98
+ const local = unwrapPatternDefault(item.value) ?? key;
99
+ if (!utils_1.t.isIdentifier(local))
100
+ continue;
101
+ if (!utils_1.t.isIdentifier(key) && !utils_1.t.isStringLiteral(key))
102
+ continue;
103
+ const name = String(key.value);
104
+ if (name !== local.value)
105
+ aliases.set(local.value, name);
106
+ }
107
+ return aliases;
108
+ };
109
+ const sourceOf = (node, sourceBuffer, baseByteOffset) => sourceBuffer
110
+ .subarray(node.span.start - baseByteOffset, node.span.end - baseByteOffset)
111
+ .toString('utf-8');
112
+ const spreadStyleError = (source, fileName) => new Error(`[plumeria] Spread elements in a style array are not supported: "...${source}". ` +
113
+ `List each style explicitly. (${fileName})`);
68
114
  const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
69
115
  node.type === 'NumericLiteral' ||
70
116
  node.type === 'BooleanLiteral' ||
@@ -83,10 +129,9 @@ const dynamicTablesOf = (ctx) => ({
83
129
  });
84
130
  function extractStylesFromExpression(expression, ctx) {
85
131
  let expr = expression;
86
- if (ctx.localStyleAliases &&
87
- utils_1.t.isIdentifier(expr) &&
88
- ctx.localStyleAliases[expr.value]) {
89
- expr = ctx.localStyleAliases[expr.value];
132
+ expr = (0, utils_1.unwrapExpression)(expr);
133
+ if (ctx.localStyleAliases) {
134
+ expr = resolveLocalStyleAlias(ctx.localStyleAliases, expr);
90
135
  }
91
136
  const results = [];
92
137
  if (utils_1.t.isMemberExpression(expr)) {
@@ -155,6 +200,25 @@ function extractStylesFromExpression(expression, ctx) {
155
200
  }
156
201
  }
157
202
  }
203
+ else if (expr.type === 'ArrayExpression') {
204
+ const spreads = [];
205
+ const elementStyles = [];
206
+ for (const element of expr.elements ?? []) {
207
+ if (!element)
208
+ continue;
209
+ if (element.spread) {
210
+ spreads.push(element.expression);
211
+ continue;
212
+ }
213
+ elementStyles.push(...extractStylesFromExpression(element.expression, ctx));
214
+ }
215
+ for (const spread of spreads) {
216
+ if (elementStyles.length > 0 ||
217
+ extractStylesFromExpression(spread, ctx).length > 0)
218
+ throw spreadStyleError(sourceOf(spread, ctx.sourceBuffer, ctx.baseByteOffset), path.basename(ctx.resourcePath));
219
+ }
220
+ results.push(...elementStyles);
221
+ }
158
222
  else if (utils_1.t.isConditionalExpression(expr)) {
159
223
  const condExpr = expr;
160
224
  results.push(...extractStylesFromExpression(condExpr.consequent, ctx));
@@ -181,7 +245,7 @@ function compileCSS(options) {
181
245
  exclude: exclude,
182
246
  sort: true,
183
247
  });
184
- const scannedTables = (0, utils_1.scanAll)();
248
+ const scannedTables = (0, utils_1.scanAll)(cwd);
185
249
  const processFile = (filePath) => {
186
250
  const resourcePath = path.resolve(cwd, filePath);
187
251
  const source = fs.readFileSync(resourcePath, 'utf-8');
@@ -354,6 +418,7 @@ function compileCSS(options) {
354
418
  mergedVariantsTable[key] = variantsImportMap[key];
355
419
  }
356
420
  const ctx = {
421
+ resourcePath,
357
422
  mergedStaticTable,
358
423
  mergedKeyframesTable,
359
424
  mergedViewTransitionTable,
@@ -370,15 +435,17 @@ function compileCSS(options) {
370
435
  };
371
436
  const componentParamNames = new Set();
372
437
  const addFirstParamName = (fn) => {
373
- const p = fn.params[0];
438
+ const first = fn.params[0];
439
+ const p = unwrapPatternDefault(first?.pat ?? first);
374
440
  if (utils_1.t.isIdentifier(p)) {
375
441
  componentParamNames.add(p.value);
376
442
  }
377
- else if (typeof p === 'object' &&
378
- p !== null &&
379
- 'pat' in p &&
380
- utils_1.t.isIdentifier(p.pat)) {
381
- componentParamNames.add(p.pat.value);
443
+ else if (p?.type === 'ObjectPattern') {
444
+ for (const item of p.properties ?? []) {
445
+ if (item.type === 'RestElement' && utils_1.t.isIdentifier(item.argument)) {
446
+ componentParamNames.add(item.argument.value);
447
+ }
448
+ }
382
449
  }
383
450
  };
384
451
  for (const node of ast.body) {
@@ -402,18 +469,43 @@ function compileCSS(options) {
402
469
  }
403
470
  }
404
471
  const components = [];
472
+ const propAliases = new Map();
473
+ const propDefaults = new Map();
474
+ const declaredProps = new Map();
475
+ const addComponent = (name, fn) => {
476
+ components.push({ name, node: fn });
477
+ const first = fn.params[0];
478
+ const pattern = unwrapPatternDefault(first?.pat ?? first);
479
+ const defaults = new Map();
480
+ for (const item of pattern?.properties ?? []) {
481
+ if (item.type === 'AssignmentPatternProperty' && item.value)
482
+ defaults.set(item.key.value, item.value);
483
+ if (item.type === 'KeyValuePatternProperty' &&
484
+ item.value?.type === 'AssignmentPattern')
485
+ defaults.set(item.key.value, item.value.right);
486
+ }
487
+ propDefaults.set(name, defaults);
488
+ const aliases = destructuredPropAliases(fn);
489
+ if (aliases.size > 0)
490
+ propAliases.set(name, aliases);
491
+ const declared = new Set();
492
+ for (const item of pattern?.properties ?? []) {
493
+ const key = item.key;
494
+ if (utils_1.t.isIdentifier(key) || utils_1.t.isStringLiteral(key))
495
+ declared.add(String(key.value));
496
+ }
497
+ if (declared.size > 0)
498
+ declaredProps.set(name, declared);
499
+ };
405
500
  for (const node of ast.body) {
406
501
  const statement = unwrapExport(node);
407
502
  if (isFunctionNode(statement)) {
408
- components.push({
409
- name: statement.identifier?.value ?? 'default',
410
- node: statement,
411
- });
503
+ addComponent(statement.identifier?.value ?? 'default', statement);
412
504
  }
413
505
  else if (statement?.type === 'CallExpression') {
414
506
  const fn = componentFunctionOf(statement);
415
507
  if (fn)
416
- components.push({ name: 'default', node: fn });
508
+ addComponent('default', fn);
417
509
  }
418
510
  else if (utils_1.t.isVariableDeclaration(statement)) {
419
511
  for (const decl of statement.declarations) {
@@ -421,7 +513,7 @@ function compileCSS(options) {
421
513
  continue;
422
514
  const fn = componentFunctionOf(decl.init);
423
515
  if (fn)
424
- components.push({ name: decl.id.value, node: fn });
516
+ addComponent(decl.id.value, fn);
425
517
  }
426
518
  }
427
519
  }
@@ -434,14 +526,26 @@ function compileCSS(options) {
434
526
  };
435
527
  const extractAndProcessConditionals = (args) => {
436
528
  args.forEach((arg) => {
437
- if (utils_1.t.isIdentifier(arg.expression) &&
438
- localStyleAliases[arg.expression.value]) {
439
- arg.expression = localStyleAliases[arg.expression.value];
440
- }
529
+ arg.expression = resolveLocalStyleAlias(localStyleAliases, arg.expression);
441
530
  });
442
531
  const conditionals = [];
443
532
  let baseStyle = {};
444
533
  const resolveStyleObject = (expr) => {
534
+ expr = resolveLocalStyleAlias(localStyleAliases, (0, utils_1.unwrapExpression)(expr));
535
+ if (expr.type === 'ArrayExpression') {
536
+ let merged = {};
537
+ for (const element of expr.elements ?? []) {
538
+ if (!element)
539
+ continue;
540
+ if (element.spread)
541
+ throw spreadStyleError(getSource(element.expression), path.basename(resourcePath));
542
+ const style = resolveStyleObject(element.expression);
543
+ if (!style)
544
+ return null;
545
+ merged = (0, utils_1.deepMerge)(merged, style);
546
+ }
547
+ return merged;
548
+ }
445
549
  if (utils_1.t.isObjectExpression(expr)) {
446
550
  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
551
  }
@@ -490,9 +594,7 @@ function compileCSS(options) {
490
594
  }
491
595
  return null;
492
596
  };
493
- const getSource = (node) => ctx.sourceBuffer
494
- .subarray(node.span.start - ctx.baseByteOffset, node.span.end - ctx.baseByteOffset)
495
- .toString('utf-8');
597
+ const getSource = (node) => sourceOf(node, ctx.sourceBuffer, ctx.baseByteOffset);
496
598
  const assertResolvable = (node) => {
497
599
  if (utils_1.t.isIdentifier(node) && node.value === 'undefined')
498
600
  return;
@@ -555,7 +657,14 @@ function compileCSS(options) {
555
657
  if (callArgs.some((a) => a.spread))
556
658
  return null;
557
659
  const tempStaticTable = { ...ctx.mergedStaticTable };
660
+ const providedParams = new Set();
558
661
  const runtime = [];
662
+ const resolveObjectArg = (argExpr) => (0, utils_1.objectExpressionToObject)({
663
+ ...argExpr,
664
+ properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
665
+ (prop.type === 'KeyValueProperty' &&
666
+ isStaticArgValue(prop.value))),
667
+ }, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
559
668
  if (func.named) {
560
669
  const argExpr = callArgs[0]?.expression;
561
670
  if (callArgs.length > 1 ||
@@ -572,9 +681,9 @@ function compileCSS(options) {
572
681
  given.set(String(prop.key.value), prop.value);
573
682
  }
574
683
  });
575
- const argObj = !argExpr
576
- ? {}
577
- : ((0, utils_1.objectExpressionToObject)(argExpr, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable) ?? {});
684
+ const argObj = argExpr
685
+ ? (resolveObjectArg(argExpr) ?? {})
686
+ : {};
578
687
  func.named.forEach(({ key, local }) => {
579
688
  const source = given.get(key);
580
689
  if (!source) {
@@ -582,18 +691,22 @@ function compileCSS(options) {
582
691
  return;
583
692
  throw new Error(`[plumeria] ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.\n`);
584
693
  }
585
- if (isStaticArgValue(source) && argObj[key] !== undefined)
694
+ if (isStaticArgValue(source) && argObj[key] !== undefined) {
586
695
  tempStaticTable[local] = argObj[key];
696
+ providedParams.add(local);
697
+ }
587
698
  else
588
699
  runtime.push(local);
589
700
  });
590
701
  }
591
702
  else if (callArgs.length === 1 &&
592
703
  callArgs[0].expression.type === 'ObjectExpression') {
593
- const argObj = (0, utils_1.objectExpressionToObject)(callArgs[0].expression, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
704
+ const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
594
705
  func.params.forEach((p) => {
595
- if (argObj[p] !== undefined)
706
+ if (argObj[p] !== undefined) {
596
707
  tempStaticTable[p] = argObj[p];
708
+ providedParams.add(p);
709
+ }
597
710
  });
598
711
  }
599
712
  else {
@@ -604,13 +717,84 @@ function compileCSS(options) {
604
717
  runtime.push(p);
605
718
  });
606
719
  }
607
- const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx));
720
+ const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
608
721
  if (!resolved)
609
722
  return null;
610
723
  const { style } = resolved;
611
724
  return style;
612
725
  };
726
+ const collectPropStyles = (expr) => {
727
+ const isParamMember = utils_1.t.isMemberExpression(expr) &&
728
+ utils_1.t.isIdentifier(expr.object) &&
729
+ componentParamNames.has(expr.object.value) &&
730
+ utils_1.t.isIdentifier(expr.property);
731
+ if (!utils_1.t.isIdentifier(expr) && !isParamMember)
732
+ return false;
733
+ const paramObject = isParamMember
734
+ ? expr.object.value
735
+ : undefined;
736
+ const isPropsMember = Boolean(paramObject &&
737
+ ctx.localCreateStyles[paramObject] === undefined &&
738
+ ctx.mergedCreateTable[paramObject] === undefined);
739
+ const varName = utils_1.t.isIdentifier(expr)
740
+ ? expr.value
741
+ : expr.property.value;
742
+ const owner = ownerComponentOf(expr);
743
+ const propName = (utils_1.t.isIdentifier(expr) && owner
744
+ ? propAliases.get(owner)?.get(varName)
745
+ : undefined) ?? varName;
746
+ const possibilities = [];
747
+ if (owner) {
748
+ const entries = ctx.scannedTables.componentPropsTable?.[`${resourcePath}-${owner}`]?.[propName];
749
+ if (entries)
750
+ possibilities.push(...entries);
751
+ }
752
+ if (possibilities.length === 0) {
753
+ const filePrefix = `${resourcePath}-`;
754
+ for (const key of Object.keys(ctx.scannedTables.componentPropsTable || {})) {
755
+ if (!key.startsWith(filePrefix))
756
+ continue;
757
+ const entries = ctx.scannedTables.componentPropsTable?.[key]?.[propName];
758
+ if (entries)
759
+ possibilities.push(...entries);
760
+ }
761
+ }
762
+ const fallback = owner && propDefaults.get(owner)?.get(propName);
763
+ if (fallback)
764
+ collectConditions(fallback);
765
+ if (possibilities.length > 0) {
766
+ const uniqueEntries = [];
767
+ possibilities.forEach((entry) => {
768
+ if (!uniqueEntries.some((x) => x.key === entry.key)) {
769
+ uniqueEntries.push(entry);
770
+ }
771
+ });
772
+ uniqueEntries.forEach((entry) => {
773
+ if (entry.styleObj && Object.keys(entry.styleObj).length > 0) {
774
+ processStyle(entry.styleObj);
775
+ }
776
+ });
777
+ return true;
778
+ }
779
+ if (fallback)
780
+ return true;
781
+ return Boolean(isPropsMember || (owner && declaredProps.get(owner)?.has(propName)));
782
+ };
613
783
  const collectConditions = (node, currentTestStrings = []) => {
784
+ node = resolveLocalStyleAlias(localStyleAliases, (0, utils_1.unwrapExpression)(node));
785
+ if (node.type === 'ArrayExpression') {
786
+ let handled = true;
787
+ for (const element of node.elements ?? []) {
788
+ if (!element)
789
+ continue;
790
+ if (element.spread)
791
+ throw spreadStyleError(getSource(element.expression), path.basename(resourcePath));
792
+ handled =
793
+ collectConditions(element.expression, currentTestStrings) &&
794
+ handled;
795
+ }
796
+ return handled;
797
+ }
614
798
  if (node.type === 'ConditionalExpression') {
615
799
  const testSource = getSource(node.test);
616
800
  if (currentTestStrings.length === 0) {
@@ -647,6 +831,8 @@ function compileCSS(options) {
647
831
  else if (node.type === 'ParenthesisExpression') {
648
832
  return collectConditions(node.expression, currentTestStrings);
649
833
  }
834
+ if (collectPropStyles(node))
835
+ return true;
650
836
  const staticStyle = resolveStyleObject(node) ?? resolveDynamicCall(node);
651
837
  if (staticStyle) {
652
838
  if (currentTestStrings.length === 0) {
@@ -681,46 +867,8 @@ function compileCSS(options) {
681
867
  };
682
868
  for (const arg of args) {
683
869
  const expr = arg.expression;
684
- if (utils_1.t.isIdentifier(expr) ||
685
- (utils_1.t.isMemberExpression(expr) &&
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
- }
870
+ if (collectPropStyles(expr))
871
+ continue;
724
872
  const dynamicStyle = resolveDynamicCall(expr);
725
873
  if (dynamicStyle) {
726
874
  baseStyle = (0, utils_1.deepMerge)(baseStyle, dynamicStyle);
@@ -789,6 +937,10 @@ function compileCSS(options) {
789
937
  throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
790
938
  `Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
791
939
  }
940
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
941
+ throw new Error(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports ` +
942
+ `nesting at-rules such as @media, @container, @supports, @layer, and @scope. (${path.basename(resourcePath)})`);
943
+ }
792
944
  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
945
  const hash = (0, utils_1.themeHashOf)(selector, obj);
794
946
  ctx.scannedTables.createThemeObjectTable[hash] = obj;
@@ -817,7 +969,7 @@ function compileCSS(options) {
817
969
  (0, utils_1.traverse)(ast, {
818
970
  VariableDeclarator({ node }) {
819
971
  if (utils_1.t.isIdentifier(node.id) && node.init) {
820
- const init = node.init;
972
+ const init = (0, utils_1.unwrapExpression)(node.init);
821
973
  if (utils_1.t.isCallExpression(init)) {
822
974
  const callee = init.callee;
823
975
  let pName;
@@ -832,17 +984,18 @@ function compileCSS(options) {
832
984
  pName = plumeriaAliases[callee.value];
833
985
  }
834
986
  const isTheme = pName === 'createTheme';
987
+ const definitionArg = pName === 'createTheme'
988
+ ? init.arguments[1]?.expression
989
+ : init.arguments[0]?.expression;
990
+ const unwrappedDefinitionArg = definitionArg
991
+ ? (0, utils_1.unwrapExpression)(definitionArg)
992
+ : undefined;
835
993
  if (pName &&
836
- init.arguments.length > 0 &&
837
- ((!isTheme &&
838
- init.arguments.length === 1 &&
839
- utils_1.t.isObjectExpression(init.arguments[0].expression)) ||
840
- (isTheme &&
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;
994
+ unwrappedDefinitionArg &&
995
+ utils_1.t.isObjectExpression(unwrappedDefinitionArg) &&
996
+ ((!isTheme && init.arguments.length === 1) ||
997
+ (isTheme && init.arguments.length >= 2))) {
998
+ const arg = unwrappedDefinitionArg;
846
999
  const resolveVariable = (name) => ctx.localCreateStyles[name]?.obj ||
847
1000
  (ctx.mergedCreateThemeHashTable[name]
848
1001
  ? ctx.scannedTables.createAtomicMapTable[ctx.mergedCreateThemeHashTable[name]]
@@ -865,6 +1018,10 @@ function compileCSS(options) {
865
1018
  throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
866
1019
  `Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
867
1020
  }
1021
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
1022
+ throw new Error(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports ` +
1023
+ `nesting at-rules such as @media, @container, @supports, @layer, and @scope. (${path.basename(resourcePath)})`);
1024
+ }
868
1025
  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
1026
  const hash = (0, utils_1.themeHashOf)(selector, obj);
870
1027
  const uKey = `${resourcePath}-${node.id.value}`;
@@ -902,7 +1059,10 @@ function compileCSS(options) {
902
1059
  const objName = init.object.value;
903
1060
  if (ctx.localCreateStyles[objName] !== undefined ||
904
1061
  ctx.mergedCreateTable[objName] !== undefined) {
905
- localStyleAliases[node.id.value] = init;
1062
+ (localStyleAliases[node.id.value] ??= []).push({
1063
+ expression: init,
1064
+ context: node.id.ctxt,
1065
+ });
906
1066
  }
907
1067
  }
908
1068
  }
@@ -944,9 +1104,7 @@ function compileCSS(options) {
944
1104
  if (value.expression.type === 'JSXEmptyExpression')
945
1105
  return;
946
1106
  let expr = value.expression;
947
- if (utils_1.t.isIdentifier(expr) && localStyleAliases[expr.value]) {
948
- expr = localStyleAliases[expr.value];
949
- }
1107
+ expr = resolveLocalStyleAlias(localStyleAliases, expr);
950
1108
  extractStylesFromExpression(expr, ctx).forEach(processStyle);
951
1109
  });
952
1110
  },
@@ -960,11 +1118,23 @@ function compileCSS(options) {
960
1118
  if (node.value.expression.type === 'JSXEmptyExpression')
961
1119
  return;
962
1120
  const expr = node.value.expression;
963
- const args = expr.type === 'ArrayExpression'
964
- ? expr.elements
965
- .filter((el) => el !== undefined)
966
- .map((el) => ({ expression: el.expression }))
967
- : [{ expression: expr }];
1121
+ const args = [];
1122
+ const addArgs = (node) => {
1123
+ node = (0, utils_1.unwrapExpression)(node);
1124
+ if (node.type === 'ArrayExpression') {
1125
+ for (const element of node.elements ?? []) {
1126
+ if (!element)
1127
+ continue;
1128
+ if (element.spread)
1129
+ throw spreadStyleError(sourceOf(element.expression, sourceBuffer, baseByteOffset), path.basename(resourcePath));
1130
+ addArgs(element.expression);
1131
+ }
1132
+ }
1133
+ else {
1134
+ args.push({ expression: node });
1135
+ }
1136
+ };
1137
+ addArgs(expr);
968
1138
  extractAndProcessConditionals(args);
969
1139
  },
970
1140
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/compiler",
3
- "version": "18.5.0",
3
+ "version": "18.5.1",
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.0"
24
+ "@plumeria/utils": "^18.5.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@rust-gear/glob": "1.1.1",