@plumeria/compiler 18.4.2 → 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 +262 -97
  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,18 +129,12 @@ 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
- if (utils_1.t.isObjectExpression(expr)) {
93
- const object = (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);
94
- if (object)
95
- results.push(object);
96
- }
97
- else if (utils_1.t.isMemberExpression(expr)) {
137
+ if (utils_1.t.isMemberExpression(expr)) {
98
138
  const memberExpr = expr;
99
139
  if (utils_1.t.isIdentifier(memberExpr.object)) {
100
140
  const variableName = memberExpr.object.value;
@@ -160,6 +200,25 @@ function extractStylesFromExpression(expression, ctx) {
160
200
  }
161
201
  }
162
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
+ }
163
222
  else if (utils_1.t.isConditionalExpression(expr)) {
164
223
  const condExpr = expr;
165
224
  results.push(...extractStylesFromExpression(condExpr.consequent, ctx));
@@ -186,7 +245,7 @@ function compileCSS(options) {
186
245
  exclude: exclude,
187
246
  sort: true,
188
247
  });
189
- const scannedTables = (0, utils_1.scanAll)();
248
+ const scannedTables = (0, utils_1.scanAll)(cwd);
190
249
  const processFile = (filePath) => {
191
250
  const resourcePath = path.resolve(cwd, filePath);
192
251
  const source = fs.readFileSync(resourcePath, 'utf-8');
@@ -359,6 +418,7 @@ function compileCSS(options) {
359
418
  mergedVariantsTable[key] = variantsImportMap[key];
360
419
  }
361
420
  const ctx = {
421
+ resourcePath,
362
422
  mergedStaticTable,
363
423
  mergedKeyframesTable,
364
424
  mergedViewTransitionTable,
@@ -375,15 +435,17 @@ function compileCSS(options) {
375
435
  };
376
436
  const componentParamNames = new Set();
377
437
  const addFirstParamName = (fn) => {
378
- const p = fn.params[0];
438
+ const first = fn.params[0];
439
+ const p = unwrapPatternDefault(first?.pat ?? first);
379
440
  if (utils_1.t.isIdentifier(p)) {
380
441
  componentParamNames.add(p.value);
381
442
  }
382
- else if (typeof p === 'object' &&
383
- p !== null &&
384
- 'pat' in p &&
385
- utils_1.t.isIdentifier(p.pat)) {
386
- 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
+ }
387
449
  }
388
450
  };
389
451
  for (const node of ast.body) {
@@ -407,18 +469,43 @@ function compileCSS(options) {
407
469
  }
408
470
  }
409
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
+ };
410
500
  for (const node of ast.body) {
411
501
  const statement = unwrapExport(node);
412
502
  if (isFunctionNode(statement)) {
413
- components.push({
414
- name: statement.identifier?.value ?? 'default',
415
- node: statement,
416
- });
503
+ addComponent(statement.identifier?.value ?? 'default', statement);
417
504
  }
418
505
  else if (statement?.type === 'CallExpression') {
419
506
  const fn = componentFunctionOf(statement);
420
507
  if (fn)
421
- components.push({ name: 'default', node: fn });
508
+ addComponent('default', fn);
422
509
  }
423
510
  else if (utils_1.t.isVariableDeclaration(statement)) {
424
511
  for (const decl of statement.declarations) {
@@ -426,7 +513,7 @@ function compileCSS(options) {
426
513
  continue;
427
514
  const fn = componentFunctionOf(decl.init);
428
515
  if (fn)
429
- components.push({ name: decl.id.value, node: fn });
516
+ addComponent(decl.id.value, fn);
430
517
  }
431
518
  }
432
519
  }
@@ -439,14 +526,26 @@ function compileCSS(options) {
439
526
  };
440
527
  const extractAndProcessConditionals = (args) => {
441
528
  args.forEach((arg) => {
442
- if (utils_1.t.isIdentifier(arg.expression) &&
443
- localStyleAliases[arg.expression.value]) {
444
- arg.expression = localStyleAliases[arg.expression.value];
445
- }
529
+ arg.expression = resolveLocalStyleAlias(localStyleAliases, arg.expression);
446
530
  });
447
531
  const conditionals = [];
448
532
  let baseStyle = {};
449
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
+ }
450
549
  if (utils_1.t.isObjectExpression(expr)) {
451
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);
452
551
  }
@@ -495,9 +594,7 @@ function compileCSS(options) {
495
594
  }
496
595
  return null;
497
596
  };
498
- const getSource = (node) => ctx.sourceBuffer
499
- .subarray(node.span.start - ctx.baseByteOffset, node.span.end - ctx.baseByteOffset)
500
- .toString('utf-8');
597
+ const getSource = (node) => sourceOf(node, ctx.sourceBuffer, ctx.baseByteOffset);
501
598
  const assertResolvable = (node) => {
502
599
  if (utils_1.t.isIdentifier(node) && node.value === 'undefined')
503
600
  return;
@@ -560,7 +657,14 @@ function compileCSS(options) {
560
657
  if (callArgs.some((a) => a.spread))
561
658
  return null;
562
659
  const tempStaticTable = { ...ctx.mergedStaticTable };
660
+ const providedParams = new Set();
563
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);
564
668
  if (func.named) {
565
669
  const argExpr = callArgs[0]?.expression;
566
670
  if (callArgs.length > 1 ||
@@ -577,9 +681,9 @@ function compileCSS(options) {
577
681
  given.set(String(prop.key.value), prop.value);
578
682
  }
579
683
  });
580
- const argObj = !argExpr
581
- ? {}
582
- : ((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
+ : {};
583
687
  func.named.forEach(({ key, local }) => {
584
688
  const source = given.get(key);
585
689
  if (!source) {
@@ -587,18 +691,22 @@ function compileCSS(options) {
587
691
  return;
588
692
  throw new Error(`[plumeria] ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.\n`);
589
693
  }
590
- if (isStaticArgValue(source) && argObj[key] !== undefined)
694
+ if (isStaticArgValue(source) && argObj[key] !== undefined) {
591
695
  tempStaticTable[local] = argObj[key];
696
+ providedParams.add(local);
697
+ }
592
698
  else
593
699
  runtime.push(local);
594
700
  });
595
701
  }
596
702
  else if (callArgs.length === 1 &&
597
703
  callArgs[0].expression.type === 'ObjectExpression') {
598
- 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) ?? {};
599
705
  func.params.forEach((p) => {
600
- if (argObj[p] !== undefined)
706
+ if (argObj[p] !== undefined) {
601
707
  tempStaticTable[p] = argObj[p];
708
+ providedParams.add(p);
709
+ }
602
710
  });
603
711
  }
604
712
  else {
@@ -609,13 +717,84 @@ function compileCSS(options) {
609
717
  runtime.push(p);
610
718
  });
611
719
  }
612
- const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx));
720
+ const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
613
721
  if (!resolved)
614
722
  return null;
615
723
  const { style } = resolved;
616
724
  return style;
617
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
+ };
618
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
+ }
619
798
  if (node.type === 'ConditionalExpression') {
620
799
  const testSource = getSource(node.test);
621
800
  if (currentTestStrings.length === 0) {
@@ -652,6 +831,8 @@ function compileCSS(options) {
652
831
  else if (node.type === 'ParenthesisExpression') {
653
832
  return collectConditions(node.expression, currentTestStrings);
654
833
  }
834
+ if (collectPropStyles(node))
835
+ return true;
655
836
  const staticStyle = resolveStyleObject(node) ?? resolveDynamicCall(node);
656
837
  if (staticStyle) {
657
838
  if (currentTestStrings.length === 0) {
@@ -686,46 +867,8 @@ function compileCSS(options) {
686
867
  };
687
868
  for (const arg of args) {
688
869
  const expr = arg.expression;
689
- if (utils_1.t.isIdentifier(expr) ||
690
- (utils_1.t.isMemberExpression(expr) &&
691
- utils_1.t.isIdentifier(expr.object) &&
692
- componentParamNames.has(expr.object.value) &&
693
- utils_1.t.isIdentifier(expr.property))) {
694
- const varName = utils_1.t.isIdentifier(expr)
695
- ? expr.value
696
- : expr.property.value;
697
- const owner = ownerComponentOf(expr);
698
- const propPossibilities = [];
699
- if (owner) {
700
- const entries = ctx.scannedTables.componentPropsTable?.[`${resourcePath}-${owner}`]?.[varName];
701
- if (entries)
702
- propPossibilities.push(...entries);
703
- }
704
- if (propPossibilities.length === 0) {
705
- const filePrefix = `${resourcePath}-`;
706
- for (const key of Object.keys(ctx.scannedTables.componentPropsTable || {})) {
707
- if (!key.startsWith(filePrefix))
708
- continue;
709
- const entries = ctx.scannedTables.componentPropsTable?.[key]?.[varName];
710
- if (entries)
711
- propPossibilities.push(...entries);
712
- }
713
- }
714
- if (propPossibilities.length > 0) {
715
- const uniqueEntries = [];
716
- propPossibilities.forEach((entry) => {
717
- if (!uniqueEntries.some((x) => x.key === entry.key)) {
718
- uniqueEntries.push(entry);
719
- }
720
- });
721
- uniqueEntries.forEach((entry) => {
722
- if (entry.styleObj && Object.keys(entry.styleObj).length > 0) {
723
- processStyle(entry.styleObj);
724
- }
725
- });
726
- continue;
727
- }
728
- }
870
+ if (collectPropStyles(expr))
871
+ continue;
729
872
  const dynamicStyle = resolveDynamicCall(expr);
730
873
  if (dynamicStyle) {
731
874
  baseStyle = (0, utils_1.deepMerge)(baseStyle, dynamicStyle);
@@ -794,6 +937,10 @@ function compileCSS(options) {
794
937
  throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
795
938
  `Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
796
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
+ }
797
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);
798
945
  const hash = (0, utils_1.themeHashOf)(selector, obj);
799
946
  ctx.scannedTables.createThemeObjectTable[hash] = obj;
@@ -822,7 +969,7 @@ function compileCSS(options) {
822
969
  (0, utils_1.traverse)(ast, {
823
970
  VariableDeclarator({ node }) {
824
971
  if (utils_1.t.isIdentifier(node.id) && node.init) {
825
- const init = node.init;
972
+ const init = (0, utils_1.unwrapExpression)(node.init);
826
973
  if (utils_1.t.isCallExpression(init)) {
827
974
  const callee = init.callee;
828
975
  let pName;
@@ -837,17 +984,18 @@ function compileCSS(options) {
837
984
  pName = plumeriaAliases[callee.value];
838
985
  }
839
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;
840
993
  if (pName &&
841
- init.arguments.length > 0 &&
842
- ((!isTheme &&
843
- init.arguments.length === 1 &&
844
- utils_1.t.isObjectExpression(init.arguments[0].expression)) ||
845
- (isTheme &&
846
- init.arguments.length >= 2 &&
847
- utils_1.t.isObjectExpression(init.arguments[1].expression)))) {
848
- const arg = isTheme
849
- ? init.arguments[1].expression
850
- : 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;
851
999
  const resolveVariable = (name) => ctx.localCreateStyles[name]?.obj ||
852
1000
  (ctx.mergedCreateThemeHashTable[name]
853
1001
  ? ctx.scannedTables.createAtomicMapTable[ctx.mergedCreateThemeHashTable[name]]
@@ -870,6 +1018,10 @@ function compileCSS(options) {
870
1018
  throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
871
1019
  `Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
872
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
+ }
873
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);
874
1026
  const hash = (0, utils_1.themeHashOf)(selector, obj);
875
1027
  const uKey = `${resourcePath}-${node.id.value}`;
@@ -907,7 +1059,10 @@ function compileCSS(options) {
907
1059
  const objName = init.object.value;
908
1060
  if (ctx.localCreateStyles[objName] !== undefined ||
909
1061
  ctx.mergedCreateTable[objName] !== undefined) {
910
- localStyleAliases[node.id.value] = init;
1062
+ (localStyleAliases[node.id.value] ??= []).push({
1063
+ expression: init,
1064
+ context: node.id.ctxt,
1065
+ });
911
1066
  }
912
1067
  }
913
1068
  }
@@ -949,9 +1104,7 @@ function compileCSS(options) {
949
1104
  if (value.expression.type === 'JSXEmptyExpression')
950
1105
  return;
951
1106
  let expr = value.expression;
952
- if (utils_1.t.isIdentifier(expr) && localStyleAliases[expr.value]) {
953
- expr = localStyleAliases[expr.value];
954
- }
1107
+ expr = resolveLocalStyleAlias(localStyleAliases, expr);
955
1108
  extractStylesFromExpression(expr, ctx).forEach(processStyle);
956
1109
  });
957
1110
  },
@@ -965,11 +1118,23 @@ function compileCSS(options) {
965
1118
  if (node.value.expression.type === 'JSXEmptyExpression')
966
1119
  return;
967
1120
  const expr = node.value.expression;
968
- const args = expr.type === 'ArrayExpression'
969
- ? expr.elements
970
- .filter((el) => el !== undefined)
971
- .map((el) => ({ expression: el.expression }))
972
- : [{ 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);
973
1138
  extractAndProcessConditionals(args);
974
1139
  },
975
1140
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/compiler",
3
- "version": "18.4.2",
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.4.2"
24
+ "@plumeria/utils": "^18.5.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@rust-gear/glob": "1.1.1",