@plumeria/utils 19.2.14 → 19.2.15

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/parser.d.ts CHANGED
@@ -43,6 +43,7 @@ export declare function traverse(node: Module | JSXExpression, visitor: {
43
43
  }) => void;
44
44
  }): void;
45
45
  export declare function objectExpressionToObject(node: ObjectExpression, staticTable: StaticTable, keyframesHashTable: KeyframesHashTable, viewTransitionHashTable: ViewTransitionHashTable, createThemeHashTable: CreateThemeHashTable, createThemeObjectTable: CreateThemeObjectTable, createHashTable: CreateHashTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable, resolveVariable?: (name: string) => any): CSSObject;
46
+ export declare function collectLocalConstNodes(ast: Module): Map<string, any>;
46
47
  export declare function collectLocalConsts(ast: Module): Record<string, any>;
47
48
  export declare function resolveThemeSelector(node: Expression, staticTable: StaticTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable): string;
48
49
  export declare function resolveFileError(actualPath: string, importedName: string): {
package/dist/parser.js CHANGED
@@ -39,6 +39,7 @@ exports.resolveOriginError = resolveOriginError;
39
39
  exports.resolveComponentKey = resolveComponentKey;
40
40
  exports.traverse = traverse;
41
41
  exports.objectExpressionToObject = objectExpressionToObject;
42
+ exports.collectLocalConstNodes = collectLocalConstNodes;
42
43
  exports.collectLocalConsts = collectLocalConsts;
43
44
  exports.resolveThemeSelector = resolveThemeSelector;
44
45
  exports.resolveFileError = resolveFileError;
@@ -343,8 +344,7 @@ function objectExpressionToObject(node, staticTable, keyframesHashTable, viewTra
343
344
  });
344
345
  return obj;
345
346
  }
346
- function collectLocalConsts(ast) {
347
- const localConsts = {};
347
+ function collectLocalConstNodes(ast) {
348
348
  const decls = new Map();
349
349
  for (const node of ast.body) {
350
350
  let declarations = [];
@@ -363,6 +363,11 @@ function collectLocalConsts(ast) {
363
363
  }
364
364
  }
365
365
  }
366
+ return decls;
367
+ }
368
+ function collectLocalConsts(ast) {
369
+ const localConsts = {};
370
+ const decls = collectLocalConstNodes(ast);
366
371
  const visiting = new Set();
367
372
  function resolveValue(name) {
368
373
  if (localConsts[name] !== undefined)
package/dist/transform.js CHANGED
@@ -38,6 +38,42 @@ const core_1 = require("@swc/core");
38
38
  const path = __importStar(require("path"));
39
39
  const zss_engine_1 = require("zss-engine");
40
40
  const parser_1 = require("./parser");
41
+ const unresolvableValue_1 = require("./unresolvableValue");
42
+ const spreadValues = (tables, constNodes) => {
43
+ const spread = (prop) => {
44
+ let values;
45
+ try {
46
+ values = (0, parser_1.objectExpressionToObject)({ properties: [prop] }, ...tables);
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ const argument = prop.arguments;
52
+ const declared = argument?.type === 'Identifier'
53
+ ? constNodes.get(argument.value)
54
+ : undefined;
55
+ const source = declared && parser_1.t.isObjectExpression(declared) ? declared : undefined;
56
+ return { values, source };
57
+ };
58
+ const resolvesValue = (value) => {
59
+ try {
60
+ const probe = (0, parser_1.objectExpressionToObject)({
61
+ properties: [
62
+ {
63
+ type: 'KeyValueProperty',
64
+ key: { type: 'Identifier', value: '__probe' },
65
+ value,
66
+ },
67
+ ],
68
+ }, ...tables);
69
+ return '__probe' in probe;
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ };
75
+ return { spread, resolvesValue };
76
+ };
41
77
  const create_1 = require("./create");
42
78
  const dynamicKey_1 = require("./dynamicKey");
43
79
  const escalation_1 = require("./escalation");
@@ -309,6 +345,7 @@ const transformSource = async (env) => {
309
345
  return records;
310
346
  };
311
347
  const localConsts = (0, parser_1.collectLocalConsts)(ast);
348
+ const localConstNodes = (0, parser_1.collectLocalConstNodes)(ast);
312
349
  const importMap = {};
313
350
  const keyframesImportMap = {};
314
351
  const viewTransitionImportMap = {};
@@ -582,6 +619,16 @@ const transformSource = async (env) => {
582
619
  if (propName === 'create' &&
583
620
  parser_1.t.isObjectExpression(init.arguments[0].expression)) {
584
621
  const obj = (0, parser_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
622
+ (0, unresolvableValue_1.assertNoDroppedValues)(init.arguments[0].expression, obj, spreadValues([
623
+ mergedStaticTable,
624
+ mergedKeyframesTable,
625
+ mergedViewTransitionTable,
626
+ mergedCreateThemeHashTable,
627
+ scannedTables.createThemeObjectTable,
628
+ mergedCreateTable,
629
+ mergedCreateStaticHashTable,
630
+ scannedTables.createStaticObjectTable,
631
+ ], localConstNodes));
585
632
  if (obj) {
586
633
  const hashMap = {};
587
634
  Object.entries(obj).forEach(([key, style]) => {
@@ -632,6 +679,16 @@ const transformSource = async (env) => {
632
679
  throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
633
680
  }
634
681
  const obj = (0, parser_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
682
+ (0, unresolvableValue_1.assertNoDroppedValues)(init.arguments[1].expression, obj, spreadValues([
683
+ mergedStaticTable,
684
+ mergedKeyframesTable,
685
+ mergedViewTransitionTable,
686
+ mergedCreateThemeHashTable,
687
+ scannedTables.createThemeObjectTable,
688
+ mergedCreateTable,
689
+ mergedCreateStaticHashTable,
690
+ scannedTables.createStaticObjectTable,
691
+ ], localConstNodes));
635
692
  const hash = (0, createTheme_1.themeHashOf)(selector, obj);
636
693
  if (parser_1.t.isIdentifier(node.id)) {
637
694
  const uniqueKey = `${resourcePath}-${node.id.value}`;
@@ -670,6 +727,16 @@ const transformSource = async (env) => {
670
727
  idSpans.add(node.id.span.start);
671
728
  }
672
729
  const obj = (0, parser_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
730
+ (0, unresolvableValue_1.assertNoDroppedValues)(init.arguments[0].expression, obj, spreadValues([
731
+ mergedStaticTable,
732
+ mergedKeyframesTable,
733
+ mergedViewTransitionTable,
734
+ mergedCreateThemeHashTable,
735
+ scannedTables.createThemeObjectTable,
736
+ mergedCreateTable,
737
+ mergedCreateStaticHashTable,
738
+ scannedTables.createStaticObjectTable,
739
+ ], localConstNodes));
673
740
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
674
741
  if (parser_1.t.isIdentifier(node.id)) {
675
742
  const uniqueKey = `${resourcePath}-${node.id.value}`;
@@ -782,6 +849,16 @@ const transformSource = async (env) => {
782
849
  const expr = args[0].expression;
783
850
  if (parser_1.t.isObjectExpression(expr)) {
784
851
  const obj = (0, parser_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
852
+ (0, unresolvableValue_1.assertNoDroppedValues)(expr, obj, spreadValues([
853
+ mergedStaticTable,
854
+ mergedKeyframesTable,
855
+ mergedViewTransitionTable,
856
+ mergedCreateThemeHashTable,
857
+ scannedTables.createThemeObjectTable,
858
+ mergedCreateTable,
859
+ mergedCreateStaticHashTable,
860
+ scannedTables.createStaticObjectTable,
861
+ ], localConstNodes));
785
862
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
786
863
  scannedTables.keyframesObjectTable[hash] = obj;
787
864
  replacements.push({
@@ -795,6 +872,16 @@ const transformSource = async (env) => {
795
872
  args.length > 0 &&
796
873
  parser_1.t.isObjectExpression(args[0].expression)) {
797
874
  const obj = (0, parser_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
875
+ (0, unresolvableValue_1.assertNoDroppedValues)(args[0].expression, obj, spreadValues([
876
+ mergedStaticTable,
877
+ mergedKeyframesTable,
878
+ mergedViewTransitionTable,
879
+ mergedCreateThemeHashTable,
880
+ scannedTables.createThemeObjectTable,
881
+ mergedCreateTable,
882
+ mergedCreateStaticHashTable,
883
+ scannedTables.createStaticObjectTable,
884
+ ], localConstNodes));
798
885
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
799
886
  scannedTables.viewTransitionObjectTable[hash] = obj;
800
887
  replacements.push({
@@ -816,6 +903,16 @@ const transformSource = async (env) => {
816
903
  throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
817
904
  }
818
905
  const obj = (0, parser_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
906
+ (0, unresolvableValue_1.assertNoDroppedValues)(args[1].expression, obj, spreadValues([
907
+ mergedStaticTable,
908
+ mergedKeyframesTable,
909
+ mergedViewTransitionTable,
910
+ mergedCreateThemeHashTable,
911
+ scannedTables.createThemeObjectTable,
912
+ mergedCreateTable,
913
+ mergedCreateStaticHashTable,
914
+ scannedTables.createStaticObjectTable,
915
+ ], localConstNodes));
819
916
  const hash = (0, createTheme_1.themeHashOf)(selector, obj);
820
917
  scannedTables.createThemeObjectTable[hash] = obj;
821
918
  if (scannedTables.createThemeSelectorTable) {
@@ -826,6 +923,16 @@ const transformSource = async (env) => {
826
923
  args.length > 0 &&
827
924
  parser_1.t.isObjectExpression(args[0].expression)) {
828
925
  const obj = (0, parser_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
926
+ (0, unresolvableValue_1.assertNoDroppedValues)(args[0].expression, obj, spreadValues([
927
+ mergedStaticTable,
928
+ mergedKeyframesTable,
929
+ mergedViewTransitionTable,
930
+ mergedCreateThemeHashTable,
931
+ scannedTables.createThemeObjectTable,
932
+ mergedCreateTable,
933
+ mergedCreateStaticHashTable,
934
+ scannedTables.createStaticObjectTable,
935
+ ], localConstNodes));
829
936
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
830
937
  scannedTables.createStaticObjectTable[hash] = obj;
831
938
  }
@@ -0,0 +1,14 @@
1
+ import type { ObjectExpression, SpreadElement } from '@swc/core';
2
+ type SourceObject = ObjectExpression;
3
+ type StaticValues = Record<string, unknown>;
4
+ type SpreadInfo = {
5
+ values: StaticValues;
6
+ source?: SourceObject;
7
+ };
8
+ type ResolveSpread = (prop: SpreadElement) => SpreadInfo | null;
9
+ export type StyleContext = {
10
+ spread: ResolveSpread;
11
+ resolvesValue: (value: unknown) => boolean;
12
+ };
13
+ export declare const assertNoDroppedValues: (node: SourceObject, resolved: StaticValues | null | undefined, context?: StyleContext, ignore?: Set<string>) => void;
14
+ export {};
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertNoDroppedValues = void 0;
4
+ const keyValue = (key) => {
5
+ if (!key || typeof key !== 'object' || !('value' in key))
6
+ return;
7
+ const value = key.value;
8
+ return typeof value === 'string' || typeof value === 'number'
9
+ ? value
10
+ : undefined;
11
+ };
12
+ const unresolvableValue = (key, node) => new Error(`[plumeria] Cannot resolve the value of "${key}" at build time (${node.type}). ` +
13
+ `Values in css.create must be statically known; pass a runtime value through the ` +
14
+ `function form, css.create({ name: (value) => ({ ... }) }).`);
15
+ const overwrittenLater = (properties, index, key, context) => {
16
+ for (let i = index + 1; i < properties.length; i++) {
17
+ const later = properties[i];
18
+ if (later.type === 'SpreadElement') {
19
+ const provided = context?.spread(later);
20
+ if (!provided)
21
+ return true;
22
+ if (String(key) in provided.values)
23
+ return true;
24
+ continue;
25
+ }
26
+ if (later.type === 'KeyValueProperty' && keyValue(later.key) === key)
27
+ return true;
28
+ }
29
+ return false;
30
+ };
31
+ const RUNTIME_ONLY = new Set([
32
+ 'CallExpression',
33
+ 'NewExpression',
34
+ 'AwaitExpression',
35
+ 'TaggedTemplateExpression',
36
+ 'YieldExpression',
37
+ ]);
38
+ const readsAnyOf = (node, names) => {
39
+ if (!node || typeof node !== 'object')
40
+ return false;
41
+ const value = node;
42
+ if (value.type === 'Identifier' && typeof value.value === 'string')
43
+ return names.has(value.value);
44
+ for (const key of Object.keys(value)) {
45
+ if (key === 'span')
46
+ continue;
47
+ const child = value[key];
48
+ if (Array.isArray(child)) {
49
+ for (const item of child)
50
+ if (readsAnyOf(item, names))
51
+ return true;
52
+ }
53
+ else if (readsAnyOf(child, names))
54
+ return true;
55
+ }
56
+ return false;
57
+ };
58
+ const parameterNames = (func) => {
59
+ const names = new Set();
60
+ const add = (pattern) => {
61
+ if (!pattern || typeof pattern !== 'object')
62
+ return;
63
+ if (pattern.type === 'Identifier' && typeof pattern.value === 'string')
64
+ names.add(pattern.value);
65
+ for (const key of ['pat', 'left', 'argument', 'value', 'key'])
66
+ if (pattern[key])
67
+ add(pattern[key]);
68
+ for (const key of ['properties', 'elements'])
69
+ if (Array.isArray(pattern[key]))
70
+ pattern[key].forEach(add);
71
+ };
72
+ (func.params ?? []).forEach((param) => add(param?.pat ?? param));
73
+ return names;
74
+ };
75
+ const assertStyleFunction = (func, context) => {
76
+ const params = parameterNames(func);
77
+ const body = func.body;
78
+ const returned = body?.type === 'ObjectExpression'
79
+ ? body
80
+ : body?.type === 'ParenthesisExpression' &&
81
+ body.expression?.type === 'ObjectExpression'
82
+ ? body.expression
83
+ : null;
84
+ if (!returned)
85
+ return;
86
+ const walk = (object) => {
87
+ const properties = object.properties ?? [];
88
+ for (let index = 0; index < properties.length; index++) {
89
+ const prop = properties[index];
90
+ if (prop.type !== 'KeyValueProperty')
91
+ continue;
92
+ const key = keyValue(prop.key);
93
+ if ((typeof key === 'string' || typeof key === 'number') &&
94
+ overwrittenLater(properties, index, key, context))
95
+ continue;
96
+ const value = prop.value;
97
+ if (!value)
98
+ continue;
99
+ if (value.type === 'ObjectExpression') {
100
+ walk(value);
101
+ continue;
102
+ }
103
+ if (RUNTIME_ONLY.has(value.type) && !readsAnyOf(value, params))
104
+ throw unresolvableValue(key ?? '', value);
105
+ if ((value.type === 'Identifier' || value.type === 'MemberExpression') &&
106
+ context &&
107
+ !readsAnyOf(value, params) &&
108
+ !context.resolvesValue(value))
109
+ throw unresolvableValue(key ?? '', value);
110
+ }
111
+ };
112
+ walk(returned);
113
+ };
114
+ const keysSuppliedAfter = (properties, index, context) => {
115
+ const keys = new Set();
116
+ for (let i = index + 1; i < properties.length; i++) {
117
+ const later = properties[i];
118
+ if (later.type === 'SpreadElement') {
119
+ const provided = context?.spread(later);
120
+ if (!provided)
121
+ return null;
122
+ for (const name of Object.keys(provided.values))
123
+ keys.add(name);
124
+ continue;
125
+ }
126
+ if (later.type !== 'KeyValueProperty')
127
+ continue;
128
+ const key = keyValue(later.key);
129
+ if (typeof key !== 'string' && typeof key !== 'number')
130
+ return null;
131
+ keys.add(String(key));
132
+ }
133
+ return keys;
134
+ };
135
+ const assertNoDroppedValues = (node, resolved, context, ignore) => {
136
+ if (!resolved)
137
+ return;
138
+ for (let index = 0; index < node.properties.length; index++) {
139
+ const prop = node.properties[index];
140
+ if (prop.type === 'SpreadElement') {
141
+ const provided = context?.spread(prop);
142
+ if (!provided?.source)
143
+ continue;
144
+ const replaced = keysSuppliedAfter(node.properties, index, context);
145
+ if (replaced)
146
+ (0, exports.assertNoDroppedValues)(provided.source, provided.values, context, replaced);
147
+ continue;
148
+ }
149
+ if (prop.type !== 'KeyValueProperty')
150
+ continue;
151
+ const key = keyValue(prop.key);
152
+ if (typeof key !== 'string' && typeof key !== 'number')
153
+ continue;
154
+ if (ignore?.has(String(key)))
155
+ continue;
156
+ if (overwrittenLater(node.properties, index, key, context))
157
+ continue;
158
+ const value = prop.value;
159
+ if (!value)
160
+ continue;
161
+ if (value.type === 'ArrowFunctionExpression' ||
162
+ value.type === 'FunctionExpression') {
163
+ assertStyleFunction(value, context);
164
+ continue;
165
+ }
166
+ if (value.type === 'NullLiteral')
167
+ continue;
168
+ if (!(key in resolved))
169
+ throw unresolvableValue(key, value);
170
+ if (value.type === 'ObjectExpression') {
171
+ const nested = resolved[key];
172
+ if (nested && typeof nested === 'object')
173
+ (0, exports.assertNoDroppedValues)(value, nested, context);
174
+ }
175
+ }
176
+ };
177
+ exports.assertNoDroppedValues = assertNoDroppedValues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/utils",
3
- "version": "19.2.14",
3
+ "version": "19.2.15",
4
4
  "description": "Plumeria Utils",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",