@plumeria/unplugin 15.1.3 → 16.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.
Files changed (3) hide show
  1. package/dist/core.js +256 -49
  2. package/dist/core.mjs +257 -50
  3. package/package.json +2 -2
package/dist/core.js CHANGED
@@ -171,6 +171,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
171
171
  const createThemeImportMap = {};
172
172
  const createStaticImportMap = {};
173
173
  const plumeriaAliases = {};
174
+ const localImports = {};
174
175
  (0, utils_1.traverse)(ast, {
175
176
  ImportDeclaration({ node }) {
176
177
  const sourcePath = node.source.value;
@@ -199,6 +200,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
199
200
  : specifier.local.value;
200
201
  const localName = specifier.local.value;
201
202
  const uniqueKey = `${actualPath}-${importedName}`;
203
+ localImports[localName] = { actualPath, importedName };
202
204
  if (scannedTables.staticTable[uniqueKey]) {
203
205
  importMap[localName] = scannedTables.staticTable[uniqueKey];
204
206
  }
@@ -314,6 +316,19 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
314
316
  mergedCreateStaticHashTable[key] = createStaticImportMap[key];
315
317
  }
316
318
  const localCreateStyles = {};
319
+ const localStyleAliases = {};
320
+ const checkStyleAliasAssignment = (decl) => {
321
+ if (!utils_1.t.isIdentifier(decl.id) || !decl.init)
322
+ return;
323
+ const init = decl.init;
324
+ if (utils_1.t.isMemberExpression(init) && utils_1.t.isIdentifier(init.object)) {
325
+ const objName = init.object.value;
326
+ if (localCreateStyles[objName] !== undefined ||
327
+ mergedCreateTable[objName] !== undefined) {
328
+ localStyleAliases[decl.id.value] = init;
329
+ }
330
+ }
331
+ };
317
332
  const replacements = [];
318
333
  const processedDecls = new Set();
319
334
  const idSpans = new Set();
@@ -429,42 +444,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
429
444
  }
430
445
  }
431
446
  }
432
- else if (propName === 'variants' &&
433
- utils_1.t.isObjectExpression(init.arguments[0].expression)) {
434
- if (utils_1.t.isIdentifier(node.id)) {
435
- idSpans.add(node.id.span.start);
436
- }
437
- const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable, (name) => {
438
- if (localCreateStyles[name]) {
439
- return localCreateStyles[name].obj;
440
- }
441
- if (mergedCreateTable[name]) {
442
- const hash = mergedCreateTable[name];
443
- if (scannedTables.createObjectTable[hash]) {
444
- return scannedTables.createObjectTable[hash];
445
- }
446
- }
447
- return undefined;
448
- });
449
- const { hashMap } = (0, utils_1.processVariants)(obj);
450
- if (utils_1.t.isIdentifier(node.id)) {
451
- localCreateStyles[node.id.value] = {
452
- name: node.id.value,
453
- type: 'variant',
454
- obj,
455
- hashMap,
456
- isExported,
457
- initSpan: {
458
- start: init.span.start - baseByteOffset,
459
- end: init.span.end - baseByteOffset,
460
- },
461
- declSpan: {
462
- start: declSpan.start - baseByteOffset,
463
- end: declSpan.end - baseByteOffset,
464
- },
465
- };
466
- }
467
- }
468
447
  else if (propName === 'createTheme' &&
469
448
  init.arguments.length >= 2 &&
470
449
  utils_1.t.isObjectExpression(init.arguments[1].expression)) {
@@ -592,6 +571,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
592
571
  node.declaration.declarations.forEach((decl) => {
593
572
  checkVariantAssignment(decl);
594
573
  registerStyle(decl, node.span, true);
574
+ checkStyleAliasAssignment(decl);
595
575
  });
596
576
  }
597
577
  },
@@ -601,6 +581,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
601
581
  node.declarations.forEach((decl) => {
602
582
  checkVariantAssignment(decl);
603
583
  registerStyle(decl, node.span, false);
584
+ checkStyleAliasAssignment(decl);
604
585
  });
605
586
  },
606
587
  CallExpression({ node }) {
@@ -686,6 +667,42 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
686
667
  },
687
668
  });
688
669
  const jsxOpeningElementMap = new Map();
670
+ const componentParamNames = new Set();
671
+ for (const node of ast.body) {
672
+ let declarations = [];
673
+ if (utils_1.t.isVariableDeclaration(node)) {
674
+ declarations = node.declarations;
675
+ }
676
+ else if (utils_1.t.isExportDeclaration(node) &&
677
+ utils_1.t.isVariableDeclaration(node.declaration)) {
678
+ declarations = node.declaration.declarations;
679
+ }
680
+ for (const decl of declarations) {
681
+ if (!utils_1.t.isIdentifier(decl.id) || !decl.init)
682
+ continue;
683
+ const init = decl.init;
684
+ if (init.type !== 'ArrowFunctionExpression' &&
685
+ init.type !== 'FunctionExpression')
686
+ continue;
687
+ if (init.params.length > 0) {
688
+ const p = init.params[0];
689
+ if (utils_1.t.isIdentifier(p)) {
690
+ componentParamNames.add(p.value);
691
+ }
692
+ else if (p.pat && utils_1.t.isIdentifier(p.pat)) {
693
+ componentParamNames.add(p.pat.value);
694
+ }
695
+ }
696
+ }
697
+ }
698
+ const excludeSubtreeSpans = (n) => {
699
+ if (!n || typeof n !== 'object')
700
+ return;
701
+ if (n.span) {
702
+ excludedSpans.add(n.span.start);
703
+ }
704
+ Object.values(n).forEach((val) => excludeSubtreeSpans(val));
705
+ };
689
706
  const getSource = (node) => {
690
707
  const start = node.span.start - baseByteOffset;
691
708
  const end = node.span.end - baseByteOffset;
@@ -699,7 +716,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
699
716
  utils_1.t.isIdentifier(expr.object) &&
700
717
  (utils_1.t.isIdentifier(expr.property) || expr.property.type === 'Computed')) {
701
718
  if (expr.property.type === 'Computed')
702
- return {};
719
+ return null;
703
720
  const varName = expr.object.value;
704
721
  const propName = expr.property.value;
705
722
  const styleInfo = localCreateStyles[varName];
@@ -736,6 +753,12 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
736
753
  return null;
737
754
  };
738
755
  const buildClassParts = (args, dynamicClassParts = [], existingClass = '') => {
756
+ args.forEach((arg) => {
757
+ const expr = arg.expression;
758
+ if (utils_1.t.isIdentifier(expr) && localStyleAliases[expr.value]) {
759
+ arg.expression = localStyleAliases[expr.value];
760
+ }
761
+ });
739
762
  const conditionals = [];
740
763
  let groupIdCounter = 0;
741
764
  let baseStyle = {};
@@ -758,6 +781,17 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
758
781
  }
759
782
  return null;
760
783
  };
784
+ const resolveCreateObject = (varName) => {
785
+ const localStyle = localCreateStyles[varName];
786
+ if (localStyle?.type === 'create')
787
+ return localStyle.obj;
788
+ let hash = scannedTables.createHashTable[`${resourcePath}-${varName}`];
789
+ if (!hash)
790
+ hash = mergedCreateTable[varName];
791
+ if (hash && scannedTables.createObjectTable[hash])
792
+ return scannedTables.createObjectTable[hash];
793
+ return null;
794
+ };
761
795
  const collectConditions = (node, currentTestStrings = []) => {
762
796
  const staticStyle = resolveStyleObject(node);
763
797
  if (staticStyle) {
@@ -816,6 +850,49 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
816
850
  };
817
851
  for (const arg of args) {
818
852
  const expr = arg.expression;
853
+ if (utils_1.t.isIdentifier(expr) ||
854
+ (utils_1.t.isMemberExpression(expr) &&
855
+ utils_1.t.isIdentifier(expr.object) &&
856
+ componentParamNames.has(expr.object.value) &&
857
+ utils_1.t.isIdentifier(expr.property))) {
858
+ const varName = utils_1.t.isIdentifier(expr)
859
+ ? expr.value
860
+ : expr.property.value;
861
+ const testLHS = utils_1.t.isIdentifier(expr) ? varName : getSource(expr);
862
+ let propPossibilities;
863
+ for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
864
+ if (key.startsWith(`${resourcePath}-`)) {
865
+ if (scannedTables.componentPropsTable?.[key]?.[varName]) {
866
+ propPossibilities =
867
+ scannedTables.componentPropsTable?.[key]?.[varName];
868
+ break;
869
+ }
870
+ }
871
+ }
872
+ if (propPossibilities && propPossibilities.length > 0) {
873
+ const currentGroupId = ++groupIdCounter;
874
+ const uniqueEntries = [];
875
+ propPossibilities.forEach((entry) => {
876
+ if (!uniqueEntries.some((x) => x.index === entry.index)) {
877
+ uniqueEntries.push(entry);
878
+ }
879
+ });
880
+ uniqueEntries.forEach((entry) => {
881
+ conditionals.push({
882
+ test: expr,
883
+ testLHS,
884
+ testString: `${testLHS} === ${entry.index}`,
885
+ truthy: entry.styleObj,
886
+ falsy: {},
887
+ groupId: currentGroupId,
888
+ groupName: undefined,
889
+ valueName: String(entry.index),
890
+ varName,
891
+ });
892
+ });
893
+ continue;
894
+ }
895
+ }
819
896
  if (utils_1.t.isCallExpression(expr) && utils_1.t.isIdentifier(expr.callee)) {
820
897
  const varName = expr.callee.value;
821
898
  const uniqueKey = `${resourcePath}-${varName}`;
@@ -947,6 +1024,31 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
947
1024
  continue;
948
1025
  }
949
1026
  }
1027
+ if (utils_1.t.isMemberExpression(expr) &&
1028
+ utils_1.t.isIdentifier(expr.object) &&
1029
+ expr.property.type === 'Computed') {
1030
+ const varName = expr.object.value;
1031
+ const styleObj = resolveCreateObject(varName);
1032
+ if (styleObj) {
1033
+ const dynExpr = expr.property.expression;
1034
+ const dynSource = getSource(dynExpr);
1035
+ const currentGroupId = ++groupIdCounter;
1036
+ Object.entries(styleObj).forEach(([optionName, style]) => {
1037
+ conditionals.push({
1038
+ test: dynExpr,
1039
+ testLHS: dynSource,
1040
+ testString: `${dynSource} === '${optionName}'`,
1041
+ truthy: style,
1042
+ falsy: {},
1043
+ groupId: currentGroupId,
1044
+ groupName: undefined,
1045
+ valueName: optionName,
1046
+ varName,
1047
+ });
1048
+ });
1049
+ continue;
1050
+ }
1051
+ }
950
1052
  const handled = collectConditions(expr);
951
1053
  if (handled)
952
1054
  continue;
@@ -1174,13 +1276,56 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1174
1276
  };
1175
1277
  (0, utils_1.traverse)(ast, {
1176
1278
  JSXOpeningElement({ node }) {
1177
- jsxOpeningElementMap.set(node.span.start, node.attributes);
1279
+ let tagName = '';
1280
+ if (node.name.type === 'Identifier') {
1281
+ tagName = node.name.value;
1282
+ }
1283
+ jsxOpeningElementMap.set(node.span.start, {
1284
+ tagName,
1285
+ attributes: node.attributes,
1286
+ });
1178
1287
  },
1179
1288
  MemberExpression({ node }) {
1180
- if (utils_1.t.isIdentifier(node.object) && utils_1.t.isIdentifier(node.property)) {
1289
+ if (utils_1.t.isIdentifier(node.object) &&
1290
+ (utils_1.t.isIdentifier(node.property) || node.property.type === 'Computed')) {
1181
1291
  const varName = node.object.value;
1182
- const propName = node.property.value;
1183
1292
  const uniqueKey = `${resourcePath}-${varName}`;
1293
+ if (node.property.type === 'Computed') {
1294
+ const dynExpr = node.property.expression;
1295
+ const dynSource = getSource(dynExpr);
1296
+ const localStyle = localCreateStyles[varName];
1297
+ let hashMap;
1298
+ if (localStyle) {
1299
+ hashMap = localStyle.hashMap;
1300
+ }
1301
+ else {
1302
+ let hash = scannedTables.createHashTable[uniqueKey];
1303
+ if (!hash) {
1304
+ hash = mergedCreateTable[varName];
1305
+ }
1306
+ if (hash) {
1307
+ const obj = scannedTables.createObjectTable[hash];
1308
+ const atomicMap = scannedTables.createAtomicMapTable[hash];
1309
+ if (obj && atomicMap) {
1310
+ hashMap = {};
1311
+ Object.keys(obj).forEach((key) => {
1312
+ if (atomicMap[key]) {
1313
+ hashMap[key] = atomicMap[key];
1314
+ }
1315
+ });
1316
+ }
1317
+ }
1318
+ }
1319
+ if (hashMap) {
1320
+ replacements.push({
1321
+ start: node.span.start - baseByteOffset,
1322
+ end: node.span.end - baseByteOffset,
1323
+ content: `((${JSON.stringify(hashMap)})[${dynSource}] || {})`,
1324
+ });
1325
+ }
1326
+ return;
1327
+ }
1328
+ const propName = node.property.value;
1184
1329
  const localStyle = localCreateStyles[varName];
1185
1330
  if (localStyle && localStyle.type === 'create') {
1186
1331
  const atomMap = localStyle.hashMap[propName];
@@ -1327,9 +1472,65 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1327
1472
  }
1328
1473
  },
1329
1474
  JSXAttribute({ node }) {
1330
- if (node.name.type !== 'Identifier' ||
1331
- node.name.value !== 'styleName')
1475
+ if (node.name.type !== 'Identifier')
1332
1476
  return;
1477
+ const attrName = node.name.value;
1478
+ if (attrName !== 'styleName') {
1479
+ let parentTagName = '';
1480
+ for (const [, val] of jsxOpeningElementMap) {
1481
+ const found = val.attributes
1482
+ .filter((a) => a.type === 'JSXAttribute')
1483
+ .find((a) => a.span.start === node.span.start);
1484
+ if (found) {
1485
+ parentTagName = val.tagName;
1486
+ break;
1487
+ }
1488
+ }
1489
+ if (parentTagName &&
1490
+ parentTagName[0] === parentTagName[0].toUpperCase()) {
1491
+ let compKey;
1492
+ const imported = localImports[parentTagName];
1493
+ if (imported) {
1494
+ compKey = `${imported.actualPath}-${imported.importedName}`;
1495
+ }
1496
+ else {
1497
+ compKey = `${resourcePath}-${parentTagName}`;
1498
+ }
1499
+ const list = scannedTables.componentPropsTable?.[compKey]?.[attrName];
1500
+ if (list &&
1501
+ node.value &&
1502
+ node.value.type === 'JSXExpressionContainer') {
1503
+ const expr = node.value.expression;
1504
+ (0, utils_1.traverse)(expr, {
1505
+ MemberExpression({ node: subNode }) {
1506
+ const entry = list.find((x) => x.spanStart === subNode.span.start &&
1507
+ x.filePath === resourcePath);
1508
+ if (entry) {
1509
+ replacements.push({
1510
+ start: subNode.span.start - baseByteOffset,
1511
+ end: subNode.span.end - baseByteOffset,
1512
+ content: String(entry.index),
1513
+ });
1514
+ excludeSubtreeSpans(subNode);
1515
+ }
1516
+ },
1517
+ ArrayExpression({ node: subNode }) {
1518
+ const entry = list.find((x) => x.spanStart === subNode.span.start &&
1519
+ x.filePath === resourcePath);
1520
+ if (entry) {
1521
+ replacements.push({
1522
+ start: subNode.span.start - baseByteOffset,
1523
+ end: subNode.span.end - baseByteOffset,
1524
+ content: String(entry.index),
1525
+ });
1526
+ excludeSubtreeSpans(subNode);
1527
+ }
1528
+ },
1529
+ });
1530
+ }
1531
+ }
1532
+ return;
1533
+ }
1333
1534
  if (!node.value || node.value.type !== 'JSXExpressionContainer')
1334
1535
  return;
1335
1536
  const expr = node.value.expression;
@@ -1341,12 +1542,12 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1341
1542
  const dynamicClassParts = [];
1342
1543
  const dynamicStyleParts = [];
1343
1544
  let attributes = [];
1344
- for (const [, attrs] of jsxOpeningElementMap) {
1345
- const found = attrs
1545
+ for (const [, val] of jsxOpeningElementMap) {
1546
+ const found = val.attributes
1346
1547
  .filter((a) => a.type === 'JSXAttribute')
1347
1548
  .find((a) => a.span.start === node.span.start);
1348
1549
  if (found) {
1349
- attributes = attrs;
1550
+ attributes = val.attributes;
1350
1551
  break;
1351
1552
  }
1352
1553
  }
@@ -1615,10 +1816,16 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1615
1816
  map: null,
1616
1817
  };
1617
1818
  }
1618
- return {
1619
- code: transformedSource,
1620
- map: null,
1621
- };
1819
+ else {
1820
+ const targetIndex = targets.findIndex((t) => t.id === id);
1821
+ if (targetIndex !== -1) {
1822
+ targets.splice(targetIndex, 1);
1823
+ }
1824
+ return {
1825
+ code: transformedSource,
1826
+ map: null,
1827
+ };
1828
+ }
1622
1829
  },
1623
1830
  };
1624
1831
  };
package/dist/core.mjs CHANGED
@@ -2,7 +2,7 @@ import { createFilter } from '@rollup/pluginutils';
2
2
  import { parseSync } from '@swc/core';
3
3
  import * as path from 'path';
4
4
  import { applyCssValue, genBase36Hash, exceptionCamelCase, camelToKebabCase, isAtRule, } from 'zss-engine';
5
- import { traverse, getStyleRecords, collectLocalConsts, objectExpressionToObject, t, extractOndemandStyles, deepMerge, scanAll, resolveImportPath, processVariants, getLeadingCommentLength, optimizer, } from '@plumeria/utils';
5
+ import { traverse, getStyleRecords, collectLocalConsts, objectExpressionToObject, t, extractOndemandStyles, deepMerge, scanAll, resolveImportPath, getLeadingCommentLength, optimizer, } from '@plumeria/utils';
6
6
  export const TARGET_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx'];
7
7
  export const EXTENSION_PATTERN = /\.(ts|tsx|js|jsx)$/;
8
8
  export const unpluginFactory = (options = {}, unpluginMeta) => {
@@ -135,6 +135,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
135
135
  const createThemeImportMap = {};
136
136
  const createStaticImportMap = {};
137
137
  const plumeriaAliases = {};
138
+ const localImports = {};
138
139
  traverse(ast, {
139
140
  ImportDeclaration({ node }) {
140
141
  const sourcePath = node.source.value;
@@ -163,6 +164,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
163
164
  : specifier.local.value;
164
165
  const localName = specifier.local.value;
165
166
  const uniqueKey = `${actualPath}-${importedName}`;
167
+ localImports[localName] = { actualPath, importedName };
166
168
  if (scannedTables.staticTable[uniqueKey]) {
167
169
  importMap[localName] = scannedTables.staticTable[uniqueKey];
168
170
  }
@@ -278,6 +280,19 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
278
280
  mergedCreateStaticHashTable[key] = createStaticImportMap[key];
279
281
  }
280
282
  const localCreateStyles = {};
283
+ const localStyleAliases = {};
284
+ const checkStyleAliasAssignment = (decl) => {
285
+ if (!t.isIdentifier(decl.id) || !decl.init)
286
+ return;
287
+ const init = decl.init;
288
+ if (t.isMemberExpression(init) && t.isIdentifier(init.object)) {
289
+ const objName = init.object.value;
290
+ if (localCreateStyles[objName] !== undefined ||
291
+ mergedCreateTable[objName] !== undefined) {
292
+ localStyleAliases[decl.id.value] = init;
293
+ }
294
+ }
295
+ };
281
296
  const replacements = [];
282
297
  const processedDecls = new Set();
283
298
  const idSpans = new Set();
@@ -393,42 +408,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
393
408
  }
394
409
  }
395
410
  }
396
- else if (propName === 'variants' &&
397
- t.isObjectExpression(init.arguments[0].expression)) {
398
- if (t.isIdentifier(node.id)) {
399
- idSpans.add(node.id.span.start);
400
- }
401
- const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable, (name) => {
402
- if (localCreateStyles[name]) {
403
- return localCreateStyles[name].obj;
404
- }
405
- if (mergedCreateTable[name]) {
406
- const hash = mergedCreateTable[name];
407
- if (scannedTables.createObjectTable[hash]) {
408
- return scannedTables.createObjectTable[hash];
409
- }
410
- }
411
- return undefined;
412
- });
413
- const { hashMap } = processVariants(obj);
414
- if (t.isIdentifier(node.id)) {
415
- localCreateStyles[node.id.value] = {
416
- name: node.id.value,
417
- type: 'variant',
418
- obj,
419
- hashMap,
420
- isExported,
421
- initSpan: {
422
- start: init.span.start - baseByteOffset,
423
- end: init.span.end - baseByteOffset,
424
- },
425
- declSpan: {
426
- start: declSpan.start - baseByteOffset,
427
- end: declSpan.end - baseByteOffset,
428
- },
429
- };
430
- }
431
- }
432
411
  else if (propName === 'createTheme' &&
433
412
  init.arguments.length >= 2 &&
434
413
  t.isObjectExpression(init.arguments[1].expression)) {
@@ -556,6 +535,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
556
535
  node.declaration.declarations.forEach((decl) => {
557
536
  checkVariantAssignment(decl);
558
537
  registerStyle(decl, node.span, true);
538
+ checkStyleAliasAssignment(decl);
559
539
  });
560
540
  }
561
541
  },
@@ -565,6 +545,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
565
545
  node.declarations.forEach((decl) => {
566
546
  checkVariantAssignment(decl);
567
547
  registerStyle(decl, node.span, false);
548
+ checkStyleAliasAssignment(decl);
568
549
  });
569
550
  },
570
551
  CallExpression({ node }) {
@@ -650,6 +631,42 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
650
631
  },
651
632
  });
652
633
  const jsxOpeningElementMap = new Map();
634
+ const componentParamNames = new Set();
635
+ for (const node of ast.body) {
636
+ let declarations = [];
637
+ if (t.isVariableDeclaration(node)) {
638
+ declarations = node.declarations;
639
+ }
640
+ else if (t.isExportDeclaration(node) &&
641
+ t.isVariableDeclaration(node.declaration)) {
642
+ declarations = node.declaration.declarations;
643
+ }
644
+ for (const decl of declarations) {
645
+ if (!t.isIdentifier(decl.id) || !decl.init)
646
+ continue;
647
+ const init = decl.init;
648
+ if (init.type !== 'ArrowFunctionExpression' &&
649
+ init.type !== 'FunctionExpression')
650
+ continue;
651
+ if (init.params.length > 0) {
652
+ const p = init.params[0];
653
+ if (t.isIdentifier(p)) {
654
+ componentParamNames.add(p.value);
655
+ }
656
+ else if (p.pat && t.isIdentifier(p.pat)) {
657
+ componentParamNames.add(p.pat.value);
658
+ }
659
+ }
660
+ }
661
+ }
662
+ const excludeSubtreeSpans = (n) => {
663
+ if (!n || typeof n !== 'object')
664
+ return;
665
+ if (n.span) {
666
+ excludedSpans.add(n.span.start);
667
+ }
668
+ Object.values(n).forEach((val) => excludeSubtreeSpans(val));
669
+ };
653
670
  const getSource = (node) => {
654
671
  const start = node.span.start - baseByteOffset;
655
672
  const end = node.span.end - baseByteOffset;
@@ -663,7 +680,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
663
680
  t.isIdentifier(expr.object) &&
664
681
  (t.isIdentifier(expr.property) || expr.property.type === 'Computed')) {
665
682
  if (expr.property.type === 'Computed')
666
- return {};
683
+ return null;
667
684
  const varName = expr.object.value;
668
685
  const propName = expr.property.value;
669
686
  const styleInfo = localCreateStyles[varName];
@@ -700,6 +717,12 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
700
717
  return null;
701
718
  };
702
719
  const buildClassParts = (args, dynamicClassParts = [], existingClass = '') => {
720
+ args.forEach((arg) => {
721
+ const expr = arg.expression;
722
+ if (t.isIdentifier(expr) && localStyleAliases[expr.value]) {
723
+ arg.expression = localStyleAliases[expr.value];
724
+ }
725
+ });
703
726
  const conditionals = [];
704
727
  let groupIdCounter = 0;
705
728
  let baseStyle = {};
@@ -722,6 +745,17 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
722
745
  }
723
746
  return null;
724
747
  };
748
+ const resolveCreateObject = (varName) => {
749
+ const localStyle = localCreateStyles[varName];
750
+ if (localStyle?.type === 'create')
751
+ return localStyle.obj;
752
+ let hash = scannedTables.createHashTable[`${resourcePath}-${varName}`];
753
+ if (!hash)
754
+ hash = mergedCreateTable[varName];
755
+ if (hash && scannedTables.createObjectTable[hash])
756
+ return scannedTables.createObjectTable[hash];
757
+ return null;
758
+ };
725
759
  const collectConditions = (node, currentTestStrings = []) => {
726
760
  const staticStyle = resolveStyleObject(node);
727
761
  if (staticStyle) {
@@ -780,6 +814,49 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
780
814
  };
781
815
  for (const arg of args) {
782
816
  const expr = arg.expression;
817
+ if (t.isIdentifier(expr) ||
818
+ (t.isMemberExpression(expr) &&
819
+ t.isIdentifier(expr.object) &&
820
+ componentParamNames.has(expr.object.value) &&
821
+ t.isIdentifier(expr.property))) {
822
+ const varName = t.isIdentifier(expr)
823
+ ? expr.value
824
+ : expr.property.value;
825
+ const testLHS = t.isIdentifier(expr) ? varName : getSource(expr);
826
+ let propPossibilities;
827
+ for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
828
+ if (key.startsWith(`${resourcePath}-`)) {
829
+ if (scannedTables.componentPropsTable?.[key]?.[varName]) {
830
+ propPossibilities =
831
+ scannedTables.componentPropsTable?.[key]?.[varName];
832
+ break;
833
+ }
834
+ }
835
+ }
836
+ if (propPossibilities && propPossibilities.length > 0) {
837
+ const currentGroupId = ++groupIdCounter;
838
+ const uniqueEntries = [];
839
+ propPossibilities.forEach((entry) => {
840
+ if (!uniqueEntries.some((x) => x.index === entry.index)) {
841
+ uniqueEntries.push(entry);
842
+ }
843
+ });
844
+ uniqueEntries.forEach((entry) => {
845
+ conditionals.push({
846
+ test: expr,
847
+ testLHS,
848
+ testString: `${testLHS} === ${entry.index}`,
849
+ truthy: entry.styleObj,
850
+ falsy: {},
851
+ groupId: currentGroupId,
852
+ groupName: undefined,
853
+ valueName: String(entry.index),
854
+ varName,
855
+ });
856
+ });
857
+ continue;
858
+ }
859
+ }
783
860
  if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
784
861
  const varName = expr.callee.value;
785
862
  const uniqueKey = `${resourcePath}-${varName}`;
@@ -911,6 +988,31 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
911
988
  continue;
912
989
  }
913
990
  }
991
+ if (t.isMemberExpression(expr) &&
992
+ t.isIdentifier(expr.object) &&
993
+ expr.property.type === 'Computed') {
994
+ const varName = expr.object.value;
995
+ const styleObj = resolveCreateObject(varName);
996
+ if (styleObj) {
997
+ const dynExpr = expr.property.expression;
998
+ const dynSource = getSource(dynExpr);
999
+ const currentGroupId = ++groupIdCounter;
1000
+ Object.entries(styleObj).forEach(([optionName, style]) => {
1001
+ conditionals.push({
1002
+ test: dynExpr,
1003
+ testLHS: dynSource,
1004
+ testString: `${dynSource} === '${optionName}'`,
1005
+ truthy: style,
1006
+ falsy: {},
1007
+ groupId: currentGroupId,
1008
+ groupName: undefined,
1009
+ valueName: optionName,
1010
+ varName,
1011
+ });
1012
+ });
1013
+ continue;
1014
+ }
1015
+ }
914
1016
  const handled = collectConditions(expr);
915
1017
  if (handled)
916
1018
  continue;
@@ -1138,13 +1240,56 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1138
1240
  };
1139
1241
  traverse(ast, {
1140
1242
  JSXOpeningElement({ node }) {
1141
- jsxOpeningElementMap.set(node.span.start, node.attributes);
1243
+ let tagName = '';
1244
+ if (node.name.type === 'Identifier') {
1245
+ tagName = node.name.value;
1246
+ }
1247
+ jsxOpeningElementMap.set(node.span.start, {
1248
+ tagName,
1249
+ attributes: node.attributes,
1250
+ });
1142
1251
  },
1143
1252
  MemberExpression({ node }) {
1144
- if (t.isIdentifier(node.object) && t.isIdentifier(node.property)) {
1253
+ if (t.isIdentifier(node.object) &&
1254
+ (t.isIdentifier(node.property) || node.property.type === 'Computed')) {
1145
1255
  const varName = node.object.value;
1146
- const propName = node.property.value;
1147
1256
  const uniqueKey = `${resourcePath}-${varName}`;
1257
+ if (node.property.type === 'Computed') {
1258
+ const dynExpr = node.property.expression;
1259
+ const dynSource = getSource(dynExpr);
1260
+ const localStyle = localCreateStyles[varName];
1261
+ let hashMap;
1262
+ if (localStyle) {
1263
+ hashMap = localStyle.hashMap;
1264
+ }
1265
+ else {
1266
+ let hash = scannedTables.createHashTable[uniqueKey];
1267
+ if (!hash) {
1268
+ hash = mergedCreateTable[varName];
1269
+ }
1270
+ if (hash) {
1271
+ const obj = scannedTables.createObjectTable[hash];
1272
+ const atomicMap = scannedTables.createAtomicMapTable[hash];
1273
+ if (obj && atomicMap) {
1274
+ hashMap = {};
1275
+ Object.keys(obj).forEach((key) => {
1276
+ if (atomicMap[key]) {
1277
+ hashMap[key] = atomicMap[key];
1278
+ }
1279
+ });
1280
+ }
1281
+ }
1282
+ }
1283
+ if (hashMap) {
1284
+ replacements.push({
1285
+ start: node.span.start - baseByteOffset,
1286
+ end: node.span.end - baseByteOffset,
1287
+ content: `((${JSON.stringify(hashMap)})[${dynSource}] || {})`,
1288
+ });
1289
+ }
1290
+ return;
1291
+ }
1292
+ const propName = node.property.value;
1148
1293
  const localStyle = localCreateStyles[varName];
1149
1294
  if (localStyle && localStyle.type === 'create') {
1150
1295
  const atomMap = localStyle.hashMap[propName];
@@ -1291,9 +1436,65 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1291
1436
  }
1292
1437
  },
1293
1438
  JSXAttribute({ node }) {
1294
- if (node.name.type !== 'Identifier' ||
1295
- node.name.value !== 'styleName')
1439
+ if (node.name.type !== 'Identifier')
1296
1440
  return;
1441
+ const attrName = node.name.value;
1442
+ if (attrName !== 'styleName') {
1443
+ let parentTagName = '';
1444
+ for (const [, val] of jsxOpeningElementMap) {
1445
+ const found = val.attributes
1446
+ .filter((a) => a.type === 'JSXAttribute')
1447
+ .find((a) => a.span.start === node.span.start);
1448
+ if (found) {
1449
+ parentTagName = val.tagName;
1450
+ break;
1451
+ }
1452
+ }
1453
+ if (parentTagName &&
1454
+ parentTagName[0] === parentTagName[0].toUpperCase()) {
1455
+ let compKey;
1456
+ const imported = localImports[parentTagName];
1457
+ if (imported) {
1458
+ compKey = `${imported.actualPath}-${imported.importedName}`;
1459
+ }
1460
+ else {
1461
+ compKey = `${resourcePath}-${parentTagName}`;
1462
+ }
1463
+ const list = scannedTables.componentPropsTable?.[compKey]?.[attrName];
1464
+ if (list &&
1465
+ node.value &&
1466
+ node.value.type === 'JSXExpressionContainer') {
1467
+ const expr = node.value.expression;
1468
+ traverse(expr, {
1469
+ MemberExpression({ node: subNode }) {
1470
+ const entry = list.find((x) => x.spanStart === subNode.span.start &&
1471
+ x.filePath === resourcePath);
1472
+ if (entry) {
1473
+ replacements.push({
1474
+ start: subNode.span.start - baseByteOffset,
1475
+ end: subNode.span.end - baseByteOffset,
1476
+ content: String(entry.index),
1477
+ });
1478
+ excludeSubtreeSpans(subNode);
1479
+ }
1480
+ },
1481
+ ArrayExpression({ node: subNode }) {
1482
+ const entry = list.find((x) => x.spanStart === subNode.span.start &&
1483
+ x.filePath === resourcePath);
1484
+ if (entry) {
1485
+ replacements.push({
1486
+ start: subNode.span.start - baseByteOffset,
1487
+ end: subNode.span.end - baseByteOffset,
1488
+ content: String(entry.index),
1489
+ });
1490
+ excludeSubtreeSpans(subNode);
1491
+ }
1492
+ },
1493
+ });
1494
+ }
1495
+ }
1496
+ return;
1497
+ }
1297
1498
  if (!node.value || node.value.type !== 'JSXExpressionContainer')
1298
1499
  return;
1299
1500
  const expr = node.value.expression;
@@ -1305,12 +1506,12 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1305
1506
  const dynamicClassParts = [];
1306
1507
  const dynamicStyleParts = [];
1307
1508
  let attributes = [];
1308
- for (const [, attrs] of jsxOpeningElementMap) {
1309
- const found = attrs
1509
+ for (const [, val] of jsxOpeningElementMap) {
1510
+ const found = val.attributes
1310
1511
  .filter((a) => a.type === 'JSXAttribute')
1311
1512
  .find((a) => a.span.start === node.span.start);
1312
1513
  if (found) {
1313
- attributes = attrs;
1514
+ attributes = val.attributes;
1314
1515
  break;
1315
1516
  }
1316
1517
  }
@@ -1579,10 +1780,16 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1579
1780
  map: null,
1580
1781
  };
1581
1782
  }
1582
- return {
1583
- code: transformedSource,
1584
- map: null,
1585
- };
1783
+ else {
1784
+ const targetIndex = targets.findIndex((t) => t.id === id);
1785
+ if (targetIndex !== -1) {
1786
+ targets.splice(targetIndex, 1);
1787
+ }
1788
+ return {
1789
+ code: transformedSource,
1790
+ map: null,
1791
+ };
1792
+ }
1586
1793
  },
1587
1794
  };
1588
1795
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "15.1.3",
3
+ "version": "16.1.0",
4
4
  "description": "Universal Plumeria plugin for various build tools",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -89,7 +89,7 @@
89
89
  "dependencies": {
90
90
  "@rollup/pluginutils": "^5.4.0",
91
91
  "unplugin": "^3.0.0",
92
- "@plumeria/utils": "^15.1.3"
92
+ "@plumeria/utils": "^16.1.0"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@swc/core": "1.15.43",