@plumeria/utils 19.2.15 → 19.3.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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/parser.d.ts +2 -2
- package/dist/parser.js +54 -16
- package/dist/stylePropFilter.d.ts +2 -0
- package/dist/stylePropFilter.js +287 -0
- package/dist/transform.js +37 -37
- package/dist/unresolvableValue.d.ts +1 -0
- package/dist/unresolvableValue.js +4 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -20,3 +20,4 @@ export type { PropertyPolicy, PropertyPolicyOptions } from './propertyPolicy';
|
|
|
20
20
|
export { resolvePropertyPolicy, assertPropertyPolicy } from './propertyPolicy';
|
|
21
21
|
export type { TransformEnv, TransformOutput } from './transform';
|
|
22
22
|
export { transformSource } from './transform';
|
|
23
|
+
export { needsCompile } from './stylePropFilter';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformSource = exports.assertPropertyPolicy = exports.resolvePropertyPolicy = exports.DEFAULT_STYLE_PROP = exports.timedAsync = exports.timed = exports.tally = exports.measure = exports.mark = exports.profiling = exports.collectReferenceIdentifiers = exports.getLeadingCommentLength = exports.optimizer = exports.resolveImportPath = exports.themeHashOf = exports.getStateWeights = exports.getPseudoElement = exports.getSpecificity = exports.resolveDynamicStyle = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = exports.getStyleRecords = exports.resolveThemeSelector = exports.resolveComponentKey = exports.resolveExport = exports.getFileDependencies = exports.resolveFileError = exports.fileTableKeys = exports.scanOverlay = exports.scanAll = exports.deepMerge = exports.appendSheet = exports.extractOndemandStyles = exports.unwrapExpression = exports.resolveOriginError = exports.getRootIdentifier = exports.t = exports.traverse = exports.collectLocalConsts = exports.objectExpressionToObject = void 0;
|
|
3
|
+
exports.needsCompile = exports.transformSource = exports.assertPropertyPolicy = exports.resolvePropertyPolicy = exports.DEFAULT_STYLE_PROP = exports.timedAsync = exports.timed = exports.tally = exports.measure = exports.mark = exports.profiling = exports.collectReferenceIdentifiers = exports.getLeadingCommentLength = exports.optimizer = exports.resolveImportPath = exports.themeHashOf = exports.getStateWeights = exports.getPseudoElement = exports.getSpecificity = exports.resolveDynamicStyle = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = exports.getStyleRecords = exports.resolveThemeSelector = exports.resolveComponentKey = exports.resolveExport = exports.getFileDependencies = exports.resolveFileError = exports.fileTableKeys = exports.scanOverlay = exports.scanAll = exports.deepMerge = exports.appendSheet = exports.extractOndemandStyles = exports.unwrapExpression = exports.resolveOriginError = exports.getRootIdentifier = exports.t = exports.traverse = exports.collectLocalConsts = exports.objectExpressionToObject = void 0;
|
|
4
4
|
var parser_1 = require("./parser");
|
|
5
5
|
Object.defineProperty(exports, "objectExpressionToObject", { enumerable: true, get: function () { return parser_1.objectExpressionToObject; } });
|
|
6
6
|
Object.defineProperty(exports, "collectLocalConsts", { enumerable: true, get: function () { return parser_1.collectLocalConsts; } });
|
|
@@ -57,3 +57,5 @@ Object.defineProperty(exports, "resolvePropertyPolicy", { enumerable: true, get:
|
|
|
57
57
|
Object.defineProperty(exports, "assertPropertyPolicy", { enumerable: true, get: function () { return propertyPolicy_1.assertPropertyPolicy; } });
|
|
58
58
|
var transform_1 = require("./transform");
|
|
59
59
|
Object.defineProperty(exports, "transformSource", { enumerable: true, get: function () { return transform_1.transformSource; } });
|
|
60
|
+
var stylePropFilter_1 = require("./stylePropFilter");
|
|
61
|
+
Object.defineProperty(exports, "needsCompile", { enumerable: true, get: function () { return stylePropFilter_1.needsCompile; } });
|
package/dist/parser.d.ts
CHANGED
|
@@ -51,8 +51,8 @@ export declare function resolveFileError(actualPath: string, importedName: strin
|
|
|
51
51
|
message: string;
|
|
52
52
|
} | undefined;
|
|
53
53
|
export declare function fileTableKeys(filePath: string, tableName: string): ReadonlySet<string> | undefined;
|
|
54
|
-
export declare function scanOverlay(scanCwd?: string): Tables;
|
|
55
|
-
export declare function scanAll(scanCwd?: string): Tables;
|
|
54
|
+
export declare function scanOverlay(scanCwd?: string, styleProp?: string): Tables;
|
|
55
|
+
export declare function scanAll(scanCwd?: string, styleProp?: string): Tables;
|
|
56
56
|
export declare function getFileDependencies(filePath: string): string[];
|
|
57
57
|
export declare function resolveExport(filePath: string, exportName: string, visited?: Set<string>): {
|
|
58
58
|
filePath: string;
|
package/dist/parser.js
CHANGED
|
@@ -57,6 +57,8 @@ const fs = __importStar(require("fs"));
|
|
|
57
57
|
const rs = __importStar(require("@rust-gear/glob"));
|
|
58
58
|
const zss_engine_1 = require("zss-engine");
|
|
59
59
|
const viewTransition_1 = require("./viewTransition");
|
|
60
|
+
const constants_1 = require("./constants");
|
|
61
|
+
const stylePropFilter_1 = require("./stylePropFilter");
|
|
60
62
|
const create_1 = require("./create");
|
|
61
63
|
const dynamicKey_1 = require("./dynamicKey");
|
|
62
64
|
const resolver_1 = require("./resolver");
|
|
@@ -102,6 +104,35 @@ const getRootIdentifier = (node) => {
|
|
|
102
104
|
return null;
|
|
103
105
|
};
|
|
104
106
|
exports.getRootIdentifier = getRootIdentifier;
|
|
107
|
+
const EXPRESSION_KINDS = {
|
|
108
|
+
NullLiteral: 'null',
|
|
109
|
+
ObjectExpression: 'an object literal',
|
|
110
|
+
ArrayExpression: 'an array literal',
|
|
111
|
+
CallExpression: 'a function call',
|
|
112
|
+
NewExpression: 'a new expression',
|
|
113
|
+
ConditionalExpression: 'a conditional expression',
|
|
114
|
+
ArrowFunctionExpression: 'a function',
|
|
115
|
+
FunctionExpression: 'a function',
|
|
116
|
+
TaggedTemplateExpression: 'a tagged template',
|
|
117
|
+
AwaitExpression: 'an await expression',
|
|
118
|
+
};
|
|
119
|
+
const expressionLabel = (node) => {
|
|
120
|
+
node = unwrapExpression(node);
|
|
121
|
+
if (exports.t.isIdentifier(node))
|
|
122
|
+
return node.value;
|
|
123
|
+
if (exports.t.isStringLiteral(node))
|
|
124
|
+
return `'${node.value}'`;
|
|
125
|
+
if (exports.t.isNumericLiteral(node))
|
|
126
|
+
return String(node.value);
|
|
127
|
+
if (exports.t.isMemberExpression(node)) {
|
|
128
|
+
const property = node.property;
|
|
129
|
+
if (property.type === 'Identifier')
|
|
130
|
+
return `${expressionLabel(node.object)}.${property.value}`;
|
|
131
|
+
if (property.type === 'Computed')
|
|
132
|
+
return `${expressionLabel(node.object)}[${expressionLabel(property.expression)}]`;
|
|
133
|
+
}
|
|
134
|
+
return EXPRESSION_KINDS[node.type] ?? 'an expression';
|
|
135
|
+
};
|
|
105
136
|
const getNamespaceMember = (node, rootName) => {
|
|
106
137
|
node = unwrapExpression(node);
|
|
107
138
|
if (exports.t.isCallExpression(node)) {
|
|
@@ -278,7 +309,7 @@ function objectExpressionToObject(node, staticTable, keyframesHashTable, viewTra
|
|
|
278
309
|
[root]: resolved,
|
|
279
310
|
}));
|
|
280
311
|
if (member === undefined)
|
|
281
|
-
throw new Error(`[plumeria] Unknown style member
|
|
312
|
+
throw new Error(`[plumeria] Unknown style member: ${expressionLabel(val)} does not exist.`);
|
|
282
313
|
obj[key] = member;
|
|
283
314
|
return;
|
|
284
315
|
}
|
|
@@ -684,7 +715,7 @@ function evaluateTemplateLiteral(node, staticTable, keyframesHashTable, viewTran
|
|
|
684
715
|
const expr = node.expressions[i];
|
|
685
716
|
const evaluatedExpr = evaluateExpression(expr, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
686
717
|
if (evaluatedExpr === null || typeof evaluatedExpr === 'object')
|
|
687
|
-
throw new Error(
|
|
718
|
+
throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${expressionLabel(expr)} inside \${} must resolve to a string or number at build time.`);
|
|
688
719
|
result += String(evaluatedExpr);
|
|
689
720
|
}
|
|
690
721
|
}
|
|
@@ -752,7 +783,7 @@ function evaluateBinaryExpression(node, staticTable, keyframesHashTable, viewTra
|
|
|
752
783
|
const rightType = right === null ? 'null' : typeof right;
|
|
753
784
|
throw new Error(`[plumeria] Binary operator ${node.operator} requires ${expected} operands; received ${leftType} and ${rightType}.`);
|
|
754
785
|
}
|
|
755
|
-
throw new Error(`[plumeria] Unsupported binary operator: ${node.operator}
|
|
786
|
+
throw new Error(`[plumeria] Unsupported binary operator: ${node.operator}. Use arithmetic, bitwise, &&, ||, or ?? operators, which can be resolved at build time.`);
|
|
756
787
|
}
|
|
757
788
|
function evaluateCallExpression(node, staticTable) {
|
|
758
789
|
const callee = node.callee;
|
|
@@ -826,7 +857,7 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
826
857
|
return createStaticObjectTable[hash];
|
|
827
858
|
}
|
|
828
859
|
}
|
|
829
|
-
throw new Error(`[plumeria] Cannot resolve static value: ${node.value}
|
|
860
|
+
throw new Error(`[plumeria] Cannot resolve static value: ${node.value}. It must be a const holding a string or number, declared in this file or imported from a module plumeria can read.`);
|
|
830
861
|
}
|
|
831
862
|
if (exports.t.isMemberExpression(node)) {
|
|
832
863
|
const resolved = resolveStaticTableMemberExpression(node, staticTable);
|
|
@@ -841,7 +872,7 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
841
872
|
if (resolvedStatic !== undefined) {
|
|
842
873
|
return resolvedStatic;
|
|
843
874
|
}
|
|
844
|
-
throw new Error(
|
|
875
|
+
throw new Error(`[plumeria] Cannot resolve static member expression: ${expressionLabel(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
|
|
845
876
|
}
|
|
846
877
|
if (exports.t.isBinaryExpression(node)) {
|
|
847
878
|
return evaluateBinaryExpression(node, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
@@ -861,12 +892,12 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
861
892
|
if (node.operator === '~')
|
|
862
893
|
return ~value;
|
|
863
894
|
}
|
|
864
|
-
throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}
|
|
895
|
+
throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${expressionLabel(node.argument)} must resolve to a number at build time.`);
|
|
865
896
|
}
|
|
866
897
|
if (exports.t.isParenthesisExpression(node)) {
|
|
867
898
|
return evaluateExpression(node.expression, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
868
899
|
}
|
|
869
|
-
throw new Error(`[plumeria] Unsupported expression type: ${node.
|
|
900
|
+
throw new Error(`[plumeria] Unsupported expression type: ${expressionLabel(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
|
|
870
901
|
}
|
|
871
902
|
function resolveKeyframesTableMemberExpression(node, keyframesHashTable) {
|
|
872
903
|
if (exports.t.isIdentifier(node)) {
|
|
@@ -1043,6 +1074,7 @@ const globalAgregatedTables = {
|
|
|
1043
1074
|
let hasComputedOnce = false;
|
|
1044
1075
|
let resolutionConfigStamp;
|
|
1045
1076
|
let scannedCwd;
|
|
1077
|
+
let scannedStyleProp;
|
|
1046
1078
|
const objectTableOwners = new Map();
|
|
1047
1079
|
const fileObjectContributions = new Map();
|
|
1048
1080
|
const fileKeyContributions = new Map();
|
|
@@ -1204,35 +1236,38 @@ function statFile(filePath) {
|
|
|
1204
1236
|
throw e;
|
|
1205
1237
|
}
|
|
1206
1238
|
}
|
|
1207
|
-
function scanOverlay(scanCwd = process.cwd()) {
|
|
1239
|
+
function scanOverlay(scanCwd = process.cwd(), styleProp = constants_1.DEFAULT_STYLE_PROP) {
|
|
1208
1240
|
overlayScan = true;
|
|
1209
1241
|
try {
|
|
1210
|
-
return scanAll(scanCwd);
|
|
1242
|
+
return scanAll(scanCwd, styleProp);
|
|
1211
1243
|
}
|
|
1212
1244
|
finally {
|
|
1213
1245
|
overlayScan = false;
|
|
1214
1246
|
}
|
|
1215
1247
|
}
|
|
1216
|
-
function scanAll(scanCwd = process.cwd()) {
|
|
1248
|
+
function scanAll(scanCwd = process.cwd(), styleProp = constants_1.DEFAULT_STYLE_PROP) {
|
|
1217
1249
|
scanning = true;
|
|
1218
1250
|
statMemo.clear();
|
|
1219
1251
|
try {
|
|
1220
|
-
return runScan(scanCwd);
|
|
1252
|
+
return runScan(scanCwd, styleProp);
|
|
1221
1253
|
}
|
|
1222
1254
|
finally {
|
|
1223
1255
|
scanning = false;
|
|
1224
1256
|
statMemo.clear();
|
|
1225
1257
|
}
|
|
1226
1258
|
}
|
|
1227
|
-
function runScan(scanCwd
|
|
1259
|
+
function runScan(scanCwd, styleProp) {
|
|
1228
1260
|
const cwd = path.resolve(scanCwd);
|
|
1229
1261
|
if (hasComputedOnce &&
|
|
1230
1262
|
process.env.NODE_ENV === 'production' &&
|
|
1231
|
-
scannedCwd === cwd
|
|
1263
|
+
scannedCwd === cwd &&
|
|
1264
|
+
scannedStyleProp === styleProp) {
|
|
1232
1265
|
return snapshotTables();
|
|
1233
1266
|
}
|
|
1234
1267
|
const localTables = globalAgregatedTables;
|
|
1235
1268
|
scannedCwd = cwd;
|
|
1269
|
+
const stylePropChanged = scannedStyleProp !== undefined && scannedStyleProp !== styleProp;
|
|
1270
|
+
scannedStyleProp = styleProp;
|
|
1236
1271
|
const configPath = path.join(cwd, 'tsconfig.json');
|
|
1237
1272
|
let configStamp = configPath;
|
|
1238
1273
|
try {
|
|
@@ -1277,7 +1312,10 @@ function runScan(scanCwd = process.cwd()) {
|
|
|
1277
1312
|
try {
|
|
1278
1313
|
const stats = fs.statSync(filePath);
|
|
1279
1314
|
const cached = fileCache[filePath];
|
|
1280
|
-
if (resolutionChanged ||
|
|
1315
|
+
if (resolutionChanged ||
|
|
1316
|
+
stylePropChanged ||
|
|
1317
|
+
!cached ||
|
|
1318
|
+
cached.mtimeMs !== stats.mtimeMs) {
|
|
1281
1319
|
invalidated.add(filePath);
|
|
1282
1320
|
queue.push(filePath);
|
|
1283
1321
|
}
|
|
@@ -1360,7 +1398,7 @@ function runScan(scanCwd = process.cwd()) {
|
|
|
1360
1398
|
try {
|
|
1361
1399
|
const stats = fs.statSync(filePath);
|
|
1362
1400
|
const source = fs.readFileSync(filePath, 'utf8');
|
|
1363
|
-
if (!
|
|
1401
|
+
if (!(0, stylePropFilter_1.needsCompile)(source, styleProp, filePath)) {
|
|
1364
1402
|
updateDependencyEdges(filePath, fileCache[filePath]?.dependencies, undefined);
|
|
1365
1403
|
fileCache[filePath] = {
|
|
1366
1404
|
mtimeMs: stats.mtimeMs,
|
|
@@ -1686,7 +1724,7 @@ function runScan(scanCwd = process.cwd()) {
|
|
|
1686
1724
|
else if (method === 'createTheme') {
|
|
1687
1725
|
const selector = resolveThemeSelector(init.arguments[0].expression, scopedStaticTable, localCreateStaticHashTable, localCreateStaticObjectTable);
|
|
1688
1726
|
if (!selector)
|
|
1689
|
-
throw new Error('[plumeria] createTheme
|
|
1727
|
+
throw new Error('[plumeria] createTheme needs a non-empty selector it can read at build time. Pass a string literal such as ".dark", or a name this file declares as one.');
|
|
1690
1728
|
const hash = (0, createTheme_1.themeHashOf)(selector, obj);
|
|
1691
1729
|
localTables.createThemeObjectTable[hash] = obj;
|
|
1692
1730
|
localCreateThemeObjectTable[hash] = obj;
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.needsCompile = exports.usesStyleProp = void 0;
|
|
4
|
+
const CORE = '@plumeria/core';
|
|
5
|
+
const isIdentifierStart = (c) => (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 95 || c === 36;
|
|
6
|
+
const isNameChar = (c) => isIdentifierStart(c) || (c >= 48 && c <= 57) || c === 46 || c === 45;
|
|
7
|
+
const isSpace = (c) => c === 32 || (c >= 9 && c <= 13);
|
|
8
|
+
const EXPRESSION_BEFORE = new Set(Array.from('(,=:[!&|?{};+-*%<>~^', (c) => c.charCodeAt(0)));
|
|
9
|
+
const EXPRESSION_WORDS = new Set([
|
|
10
|
+
'return',
|
|
11
|
+
'yield',
|
|
12
|
+
'default',
|
|
13
|
+
'else',
|
|
14
|
+
'case',
|
|
15
|
+
'await',
|
|
16
|
+
'do',
|
|
17
|
+
'typeof',
|
|
18
|
+
'void',
|
|
19
|
+
'in',
|
|
20
|
+
'of',
|
|
21
|
+
'new',
|
|
22
|
+
'delete',
|
|
23
|
+
'throw',
|
|
24
|
+
]);
|
|
25
|
+
const MODE_CODE = 0;
|
|
26
|
+
const MODE_TAG = 1;
|
|
27
|
+
const MODE_CHILDREN = 2;
|
|
28
|
+
const skipTrivia = (source, start) => {
|
|
29
|
+
let i = start;
|
|
30
|
+
while (i < source.length) {
|
|
31
|
+
const c = source.charCodeAt(i);
|
|
32
|
+
if (isSpace(c)) {
|
|
33
|
+
i++;
|
|
34
|
+
}
|
|
35
|
+
else if (c === 47 && source.charCodeAt(i + 1) === 42) {
|
|
36
|
+
const end = source.indexOf('*/', i + 2);
|
|
37
|
+
if (end === -1)
|
|
38
|
+
return source.length;
|
|
39
|
+
i = end + 2;
|
|
40
|
+
}
|
|
41
|
+
else if (c === 47 && source.charCodeAt(i + 1) === 47) {
|
|
42
|
+
const end = source.indexOf('\n', i + 2);
|
|
43
|
+
if (end === -1)
|
|
44
|
+
return source.length;
|
|
45
|
+
i = end + 1;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return i;
|
|
52
|
+
};
|
|
53
|
+
const attributeAt = (source, index, name) => {
|
|
54
|
+
if (index > 0 && isNameChar(source.charCodeAt(index - 1)))
|
|
55
|
+
return false;
|
|
56
|
+
let i = skipTrivia(source, index + name.length);
|
|
57
|
+
if (source.charCodeAt(i) !== 61)
|
|
58
|
+
return false;
|
|
59
|
+
i = skipTrivia(source, i + 1);
|
|
60
|
+
return source.charCodeAt(i) === 123;
|
|
61
|
+
};
|
|
62
|
+
const hasAttributeCandidate = (source, name) => {
|
|
63
|
+
for (let i = source.indexOf(name); i !== -1; i = source.indexOf(name, i + 1)) {
|
|
64
|
+
if (attributeAt(source, i, name))
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
};
|
|
69
|
+
const wordBefore = (source, end) => {
|
|
70
|
+
let start = end;
|
|
71
|
+
while (start > 0 && isNameChar(source.charCodeAt(start - 1)))
|
|
72
|
+
start--;
|
|
73
|
+
return source.slice(start, end);
|
|
74
|
+
};
|
|
75
|
+
const closingQuote = (source, start, quote, multiline) => {
|
|
76
|
+
for (let i = start + 1; i < source.length; i++) {
|
|
77
|
+
const c = source.charCodeAt(i);
|
|
78
|
+
if (c === 92) {
|
|
79
|
+
i++;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (c === quote)
|
|
83
|
+
return i;
|
|
84
|
+
if (c === 10 && !multiline)
|
|
85
|
+
return -1;
|
|
86
|
+
}
|
|
87
|
+
return -1;
|
|
88
|
+
};
|
|
89
|
+
const writesAttribute = (source, name) => {
|
|
90
|
+
const first = name.charCodeAt(0);
|
|
91
|
+
const stack = [];
|
|
92
|
+
let mode = MODE_CODE;
|
|
93
|
+
let previous = 0;
|
|
94
|
+
let previousEnd = 0;
|
|
95
|
+
const leaveElement = () => {
|
|
96
|
+
mode = stack[stack.length - 1] === 'element' ? MODE_CHILDREN : MODE_CODE;
|
|
97
|
+
previous = 41;
|
|
98
|
+
};
|
|
99
|
+
const templateEnd = (from) => {
|
|
100
|
+
for (let i = from; i < source.length; i++) {
|
|
101
|
+
const c = source.charCodeAt(i);
|
|
102
|
+
if (c === 92) {
|
|
103
|
+
i++;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (c === 96)
|
|
107
|
+
return i;
|
|
108
|
+
if (c === 36 && source.charCodeAt(i + 1) === 123) {
|
|
109
|
+
stack.push('template');
|
|
110
|
+
return i + 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return -1;
|
|
114
|
+
};
|
|
115
|
+
for (let i = 0; i < source.length; i++) {
|
|
116
|
+
const c = source.charCodeAt(i);
|
|
117
|
+
if (c === first &&
|
|
118
|
+
source.startsWith(name, i) &&
|
|
119
|
+
attributeAt(source, i, name))
|
|
120
|
+
return true;
|
|
121
|
+
if (mode === MODE_TAG) {
|
|
122
|
+
if (c === 47 && source.charCodeAt(i + 1) === 42) {
|
|
123
|
+
const end = source.indexOf('*/', i + 2);
|
|
124
|
+
if (end === -1)
|
|
125
|
+
return true;
|
|
126
|
+
i = end + 1;
|
|
127
|
+
}
|
|
128
|
+
else if (c === 47 && source.charCodeAt(i + 1) === 47) {
|
|
129
|
+
const end = source.indexOf('\n', i + 2);
|
|
130
|
+
if (end === -1)
|
|
131
|
+
return true;
|
|
132
|
+
i = end;
|
|
133
|
+
}
|
|
134
|
+
else if (c === 47 && source.charCodeAt(i + 1) === 62) {
|
|
135
|
+
i++;
|
|
136
|
+
leaveElement();
|
|
137
|
+
}
|
|
138
|
+
else if (c === 62) {
|
|
139
|
+
stack.push('element');
|
|
140
|
+
mode = MODE_CHILDREN;
|
|
141
|
+
}
|
|
142
|
+
else if (c === 123) {
|
|
143
|
+
stack.push('attribute');
|
|
144
|
+
mode = MODE_CODE;
|
|
145
|
+
previous = 123;
|
|
146
|
+
}
|
|
147
|
+
else if (c === 34 || c === 39) {
|
|
148
|
+
const end = closingQuote(source, i, c, true);
|
|
149
|
+
if (end === -1)
|
|
150
|
+
return true;
|
|
151
|
+
i = end;
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (mode === MODE_CHILDREN) {
|
|
156
|
+
if (c === 123) {
|
|
157
|
+
stack.push('child');
|
|
158
|
+
mode = MODE_CODE;
|
|
159
|
+
previous = 123;
|
|
160
|
+
}
|
|
161
|
+
else if (c === 60) {
|
|
162
|
+
if (source.charCodeAt(i + 1) === 47) {
|
|
163
|
+
const end = source.indexOf('>', i);
|
|
164
|
+
if (end === -1)
|
|
165
|
+
return true;
|
|
166
|
+
i = end;
|
|
167
|
+
stack.pop();
|
|
168
|
+
leaveElement();
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
mode = MODE_TAG;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (isSpace(c))
|
|
177
|
+
continue;
|
|
178
|
+
if (c === 47 && source.charCodeAt(i + 1) === 47) {
|
|
179
|
+
const end = source.indexOf('\n', i);
|
|
180
|
+
if (end === -1)
|
|
181
|
+
return false;
|
|
182
|
+
i = end;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (c === 47 && source.charCodeAt(i + 1) === 42) {
|
|
186
|
+
const end = source.indexOf('*/', i + 2);
|
|
187
|
+
if (end === -1)
|
|
188
|
+
return true;
|
|
189
|
+
i = end + 1;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (c === 39 || c === 34) {
|
|
193
|
+
const end = closingQuote(source, i, c, false);
|
|
194
|
+
if (end === -1)
|
|
195
|
+
return true;
|
|
196
|
+
i = end;
|
|
197
|
+
previous = c;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (c === 96) {
|
|
201
|
+
const end = templateEnd(i + 1);
|
|
202
|
+
if (end === -1)
|
|
203
|
+
return true;
|
|
204
|
+
i = end;
|
|
205
|
+
previous = 96;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (c === 123) {
|
|
209
|
+
stack.push('brace');
|
|
210
|
+
previous = c;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (c === 125) {
|
|
214
|
+
const kind = stack.pop();
|
|
215
|
+
if (kind === 'template') {
|
|
216
|
+
const end = templateEnd(i + 1);
|
|
217
|
+
if (end === -1)
|
|
218
|
+
return true;
|
|
219
|
+
i = end;
|
|
220
|
+
previous = 96;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (kind === 'attribute') {
|
|
224
|
+
mode = MODE_TAG;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (kind === 'child') {
|
|
228
|
+
mode = MODE_CHILDREN;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (kind !== 'brace')
|
|
232
|
+
return true;
|
|
233
|
+
previous = c;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const afterUpdate = (previous === 43 || previous === 45) &&
|
|
237
|
+
source.charCodeAt(previousEnd - 2) === previous;
|
|
238
|
+
const expressionStart = previous === 0 ||
|
|
239
|
+
(EXPRESSION_BEFORE.has(previous) && !afterUpdate) ||
|
|
240
|
+
(isNameChar(previous) &&
|
|
241
|
+
EXPRESSION_WORDS.has(wordBefore(source, previousEnd)));
|
|
242
|
+
if (c === 47 && expressionStart) {
|
|
243
|
+
let end = i + 1;
|
|
244
|
+
let inClass = false;
|
|
245
|
+
for (; end < source.length; end++) {
|
|
246
|
+
const d = source.charCodeAt(end);
|
|
247
|
+
if (d === 92) {
|
|
248
|
+
end++;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (d === 10)
|
|
252
|
+
break;
|
|
253
|
+
if (d === 91)
|
|
254
|
+
inClass = true;
|
|
255
|
+
else if (d === 93)
|
|
256
|
+
inClass = false;
|
|
257
|
+
else if (d === 47 && !inClass)
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
if (source.charCodeAt(end) === 47) {
|
|
261
|
+
i = end;
|
|
262
|
+
previous = 41;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (c === 60 && expressionStart) {
|
|
267
|
+
const next = source.charCodeAt(i + 1);
|
|
268
|
+
if (isIdentifierStart(next) || next === 62) {
|
|
269
|
+
mode = MODE_TAG;
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
previous = c;
|
|
274
|
+
previousEnd = i + 1;
|
|
275
|
+
}
|
|
276
|
+
return false;
|
|
277
|
+
};
|
|
278
|
+
const usesStyleProp = (source, styleProp, filePath) => {
|
|
279
|
+
if (filePath.endsWith('.ts') || filePath.endsWith('.mts'))
|
|
280
|
+
return false;
|
|
281
|
+
if (!styleProp || !hasAttributeCandidate(source, styleProp))
|
|
282
|
+
return false;
|
|
283
|
+
return writesAttribute(source, styleProp);
|
|
284
|
+
};
|
|
285
|
+
exports.usesStyleProp = usesStyleProp;
|
|
286
|
+
const needsCompile = (source, styleProp, filePath) => source.includes(CORE) || (0, exports.usesStyleProp)(source, styleProp, filePath);
|
|
287
|
+
exports.needsCompile = needsCompile;
|
package/dist/transform.js
CHANGED
|
@@ -39,7 +39,7 @@ const path = __importStar(require("path"));
|
|
|
39
39
|
const zss_engine_1 = require("zss-engine");
|
|
40
40
|
const parser_1 = require("./parser");
|
|
41
41
|
const unresolvableValue_1 = require("./unresolvableValue");
|
|
42
|
-
const spreadValues = (tables, constNodes) => {
|
|
42
|
+
const spreadValues = (tables, constNodes, sourceOf) => {
|
|
43
43
|
const spread = (prop) => {
|
|
44
44
|
let values;
|
|
45
45
|
try {
|
|
@@ -72,7 +72,7 @@ const spreadValues = (tables, constNodes) => {
|
|
|
72
72
|
return false;
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
-
return { spread, resolvesValue };
|
|
75
|
+
return { spread, resolvesValue, sourceOf };
|
|
76
76
|
};
|
|
77
77
|
const create_1 = require("./create");
|
|
78
78
|
const dynamicKey_1 = require("./dynamicKey");
|
|
@@ -128,9 +128,9 @@ const destructuredPropAliases = (fn) => {
|
|
|
128
128
|
}
|
|
129
129
|
return aliases;
|
|
130
130
|
};
|
|
131
|
-
const propDefaultMessage = (source) => `
|
|
131
|
+
const propDefaultMessage = (source) => `[plumeria] A style prop default must be a defined style: "${source}". ` +
|
|
132
132
|
`Apply a conditional or dynamic style where the element is styled.`;
|
|
133
|
-
const spreadStyleMessage = (source) => `
|
|
133
|
+
const spreadStyleMessage = (source) => `[plumeria] Spread elements in a style array are not supported: "...${source}". ` +
|
|
134
134
|
`List each style explicitly.`;
|
|
135
135
|
const resolveLocalStyleAlias = (aliases, expression) => {
|
|
136
136
|
let current = expression;
|
|
@@ -196,6 +196,11 @@ const transformSource = async (env) => {
|
|
|
196
196
|
const sourceBuffer = Buffer.from(source, 'utf-8');
|
|
197
197
|
const leadingBytes = Buffer.byteLength(source.slice(0, leadingLen), 'utf-8');
|
|
198
198
|
const baseByteOffset = ast.span.start - leadingBytes;
|
|
199
|
+
const getSource = (node) => {
|
|
200
|
+
const start = node.span.start - baseByteOffset;
|
|
201
|
+
const end = node.span.end - baseByteOffset;
|
|
202
|
+
return sourceBuffer.subarray(start, end).toString('utf-8');
|
|
203
|
+
};
|
|
199
204
|
const throwCompilationError = (message, node) => {
|
|
200
205
|
let suffix = '';
|
|
201
206
|
if (node) {
|
|
@@ -232,16 +237,16 @@ const transformSource = async (env) => {
|
|
|
232
237
|
if (!isPlumeriaStyle) {
|
|
233
238
|
const failure = (0, parser_1.resolveOriginError)(node, rootId, localImports);
|
|
234
239
|
if (failure) {
|
|
235
|
-
throwCompilationError(`
|
|
240
|
+
throwCompilationError(`[plumeria] ${failure.message} (${path.basename(failure.filePath)})`);
|
|
236
241
|
}
|
|
237
|
-
throwCompilationError(`
|
|
242
|
+
throwCompilationError(`[plumeria] Dynamic or unresolvable style object "${getSource(node)}" is not supported.`, node);
|
|
238
243
|
}
|
|
239
244
|
}
|
|
240
245
|
};
|
|
241
|
-
const scannedTables = (0, parser_1.scanOverlay)();
|
|
246
|
+
const scannedTables = (0, parser_1.scanOverlay)(undefined, styleProp);
|
|
242
247
|
const ownFailure = (0, parser_1.resolveFileError)(baseId, '');
|
|
243
248
|
if (ownFailure)
|
|
244
|
-
throwCompilationError(`
|
|
249
|
+
throwCompilationError(`[plumeria] ${ownFailure.message}`);
|
|
245
250
|
for (const node of ast.body) {
|
|
246
251
|
if (node.type === 'ImportDeclaration') {
|
|
247
252
|
const sourcePath = node.source.value;
|
|
@@ -605,14 +610,14 @@ const transformSource = async (env) => {
|
|
|
605
610
|
if (propName && init && parser_1.t.isCallExpression(init)) {
|
|
606
611
|
if (['create', 'createTheme', 'createStatic'].includes(propName) &&
|
|
607
612
|
!topLevelDeclarators.has(node)) {
|
|
608
|
-
throwCompilationError(`
|
|
613
|
+
throwCompilationError(`[plumeria] css.${propName} must be assigned to a top-level variable so its styles can be resolved across files. Move this declaration outside the function or block.`, node);
|
|
609
614
|
}
|
|
610
615
|
if (['create', 'createTheme', 'createStatic'].includes(propName)) {
|
|
611
616
|
const argumentIndex = propName === 'createTheme' ? 1 : 0;
|
|
612
617
|
const argument = init.arguments[argumentIndex];
|
|
613
618
|
const object = argument && literalObjectArgument(argument.expression);
|
|
614
619
|
if (!object)
|
|
615
|
-
throwCompilationError(`
|
|
620
|
+
throwCompilationError(`[plumeria] css.${propName} needs a style object it can read at build time. Pass an object literal or a top-level constant containing one.`, init);
|
|
616
621
|
argument.expression = object;
|
|
617
622
|
registeredStyleCalls.add(init.span.start);
|
|
618
623
|
}
|
|
@@ -628,7 +633,7 @@ const transformSource = async (env) => {
|
|
|
628
633
|
mergedCreateTable,
|
|
629
634
|
mergedCreateStaticHashTable,
|
|
630
635
|
scannedTables.createStaticObjectTable,
|
|
631
|
-
], localConstNodes));
|
|
636
|
+
], localConstNodes, getSource));
|
|
632
637
|
if (obj) {
|
|
633
638
|
const hashMap = {};
|
|
634
639
|
Object.entries(obj).forEach(([key, style]) => {
|
|
@@ -672,11 +677,11 @@ const transformSource = async (env) => {
|
|
|
672
677
|
const selectorExpr = init.arguments[0].expression;
|
|
673
678
|
const selector = (0, parser_1.resolveThemeSelector)(selectorExpr, mergedStaticTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
|
|
674
679
|
if (!selector) {
|
|
675
|
-
throwCompilationError(`
|
|
680
|
+
throwCompilationError(`[plumeria] createTheme needs a selector it can read at build time. ` +
|
|
676
681
|
`Pass a string literal such as ".dark", or a name this file declares as one.`, selectorExpr);
|
|
677
682
|
}
|
|
678
683
|
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
679
|
-
throwCompilationError(`
|
|
684
|
+
throwCompilationError(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
|
|
680
685
|
}
|
|
681
686
|
const obj = (0, parser_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
|
|
682
687
|
(0, unresolvableValue_1.assertNoDroppedValues)(init.arguments[1].expression, obj, spreadValues([
|
|
@@ -688,7 +693,7 @@ const transformSource = async (env) => {
|
|
|
688
693
|
mergedCreateTable,
|
|
689
694
|
mergedCreateStaticHashTable,
|
|
690
695
|
scannedTables.createStaticObjectTable,
|
|
691
|
-
], localConstNodes));
|
|
696
|
+
], localConstNodes, getSource));
|
|
692
697
|
const hash = (0, createTheme_1.themeHashOf)(selector, obj);
|
|
693
698
|
if (parser_1.t.isIdentifier(node.id)) {
|
|
694
699
|
const uniqueKey = `${resourcePath}-${node.id.value}`;
|
|
@@ -736,7 +741,7 @@ const transformSource = async (env) => {
|
|
|
736
741
|
mergedCreateTable,
|
|
737
742
|
mergedCreateStaticHashTable,
|
|
738
743
|
scannedTables.createStaticObjectTable,
|
|
739
|
-
], localConstNodes));
|
|
744
|
+
], localConstNodes, getSource));
|
|
740
745
|
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
741
746
|
if (parser_1.t.isIdentifier(node.id)) {
|
|
742
747
|
const uniqueKey = `${resourcePath}-${node.id.value}`;
|
|
@@ -842,7 +847,7 @@ const transformSource = async (env) => {
|
|
|
842
847
|
if (propName) {
|
|
843
848
|
if (['create', 'createTheme', 'createStatic'].includes(propName) &&
|
|
844
849
|
!registeredStyleCalls.has(node.span.start)) {
|
|
845
|
-
throwCompilationError(`
|
|
850
|
+
throwCompilationError(`[plumeria] css.${propName} must be assigned to a named top-level variable. Destructuring, assignment statements, and default-exported calls cannot be compiled.`, node);
|
|
846
851
|
}
|
|
847
852
|
const args = node.arguments;
|
|
848
853
|
if (propName === 'keyframes' && args.length > 0) {
|
|
@@ -858,7 +863,7 @@ const transformSource = async (env) => {
|
|
|
858
863
|
mergedCreateTable,
|
|
859
864
|
mergedCreateStaticHashTable,
|
|
860
865
|
scannedTables.createStaticObjectTable,
|
|
861
|
-
], localConstNodes));
|
|
866
|
+
], localConstNodes, getSource));
|
|
862
867
|
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
863
868
|
scannedTables.keyframesObjectTable[hash] = obj;
|
|
864
869
|
replacements.push({
|
|
@@ -881,7 +886,7 @@ const transformSource = async (env) => {
|
|
|
881
886
|
mergedCreateTable,
|
|
882
887
|
mergedCreateStaticHashTable,
|
|
883
888
|
scannedTables.createStaticObjectTable,
|
|
884
|
-
], localConstNodes));
|
|
889
|
+
], localConstNodes, getSource));
|
|
885
890
|
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
886
891
|
scannedTables.viewTransitionObjectTable[hash] = obj;
|
|
887
892
|
replacements.push({
|
|
@@ -896,11 +901,11 @@ const transformSource = async (env) => {
|
|
|
896
901
|
const selectorExpr = args[0].expression;
|
|
897
902
|
const selector = (0, parser_1.resolveThemeSelector)(selectorExpr, mergedStaticTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
|
|
898
903
|
if (!selector) {
|
|
899
|
-
throwCompilationError(`
|
|
904
|
+
throwCompilationError(`[plumeria] createTheme needs a selector it can read at build time. ` +
|
|
900
905
|
`Pass a string literal such as ".dark", or a name this file declares as one.`, selectorExpr);
|
|
901
906
|
}
|
|
902
907
|
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
903
|
-
throwCompilationError(`
|
|
908
|
+
throwCompilationError(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
|
|
904
909
|
}
|
|
905
910
|
const obj = (0, parser_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
|
|
906
911
|
(0, unresolvableValue_1.assertNoDroppedValues)(args[1].expression, obj, spreadValues([
|
|
@@ -912,7 +917,7 @@ const transformSource = async (env) => {
|
|
|
912
917
|
mergedCreateTable,
|
|
913
918
|
mergedCreateStaticHashTable,
|
|
914
919
|
scannedTables.createStaticObjectTable,
|
|
915
|
-
], localConstNodes));
|
|
920
|
+
], localConstNodes, getSource));
|
|
916
921
|
const hash = (0, createTheme_1.themeHashOf)(selector, obj);
|
|
917
922
|
scannedTables.createThemeObjectTable[hash] = obj;
|
|
918
923
|
if (scannedTables.createThemeSelectorTable) {
|
|
@@ -932,7 +937,7 @@ const transformSource = async (env) => {
|
|
|
932
937
|
mergedCreateTable,
|
|
933
938
|
mergedCreateStaticHashTable,
|
|
934
939
|
scannedTables.createStaticObjectTable,
|
|
935
|
-
], localConstNodes));
|
|
940
|
+
], localConstNodes, getSource));
|
|
936
941
|
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
937
942
|
scannedTables.createStaticObjectTable[hash] = obj;
|
|
938
943
|
}
|
|
@@ -1008,11 +1013,6 @@ const transformSource = async (env) => {
|
|
|
1008
1013
|
}
|
|
1009
1014
|
Object.values(n).forEach((val) => excludeSubtreeSpans(val));
|
|
1010
1015
|
};
|
|
1011
|
-
const getSource = (node) => {
|
|
1012
|
-
const start = node.span.start - baseByteOffset;
|
|
1013
|
-
const end = node.span.end - baseByteOffset;
|
|
1014
|
-
return sourceBuffer.subarray(start, end).toString('utf-8');
|
|
1015
|
-
};
|
|
1016
1016
|
const isVisibleReference = (expr) => {
|
|
1017
1017
|
if (parser_1.t.isIdentifier(expr))
|
|
1018
1018
|
return referenceIdents.references.has(expr.span.start);
|
|
@@ -1148,7 +1148,7 @@ const transformSource = async (env) => {
|
|
|
1148
1148
|
const argExpr = callArgs[0]?.expression;
|
|
1149
1149
|
if (callArgs.length > 1 ||
|
|
1150
1150
|
(argExpr && argExpr.type !== 'ObjectExpression')) {
|
|
1151
|
-
throwCompilationError(`
|
|
1151
|
+
throwCompilationError(`[plumeria] ${getSource(expr)} takes one object argument, because ${callee.property.value} destructures its parameter.`, expr);
|
|
1152
1152
|
}
|
|
1153
1153
|
const given = new Map();
|
|
1154
1154
|
(argExpr?.properties ?? []).forEach((prop) => {
|
|
@@ -1168,7 +1168,7 @@ const transformSource = async (env) => {
|
|
|
1168
1168
|
if (!source) {
|
|
1169
1169
|
if (func.defaults?.[local])
|
|
1170
1170
|
return;
|
|
1171
|
-
return throwCompilationError(`
|
|
1171
|
+
return throwCompilationError(`[plumeria] ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.`, expr);
|
|
1172
1172
|
}
|
|
1173
1173
|
if (!forceRuntime &&
|
|
1174
1174
|
isStaticArgValue(source) &&
|
|
@@ -1387,7 +1387,7 @@ const transformSource = async (env) => {
|
|
|
1387
1387
|
const dynamic = resolveDynamicCall(node);
|
|
1388
1388
|
if (dynamic) {
|
|
1389
1389
|
if (!isStyleProp) {
|
|
1390
|
-
throwCompilationError(`
|
|
1390
|
+
throwCompilationError(`[plumeria] css.use(${getSource(node)}) does not support dynamic function keys.`, node);
|
|
1391
1391
|
}
|
|
1392
1392
|
branchStyle = dynamic.style;
|
|
1393
1393
|
dynamic.vars.forEach((v) => dynamicVars.push({
|
|
@@ -1516,7 +1516,7 @@ const transformSource = async (env) => {
|
|
|
1516
1516
|
}
|
|
1517
1517
|
const carriesVars = possibilities.some((entry) => entry.hasVars);
|
|
1518
1518
|
if (carriesVars && !isStyleProp) {
|
|
1519
|
-
throwCompilationError(`
|
|
1519
|
+
throwCompilationError(`[plumeria] "${varName}" carries a dynamic function key, and css.use() returns only a class name. ` +
|
|
1520
1520
|
`Apply it to ${styleProp} on the element instead.`, expr);
|
|
1521
1521
|
}
|
|
1522
1522
|
const gate = gates.length ? `(${gates.join(' && ')}) && ` : '';
|
|
@@ -2276,7 +2276,7 @@ const transformSource = async (env) => {
|
|
|
2276
2276
|
}
|
|
2277
2277
|
const { classParts, isOptimizable, baseStyle, dynamicVars, propVarSpreads, } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
|
|
2278
2278
|
if (!isOptimizable) {
|
|
2279
|
-
throwCompilationError(`
|
|
2279
|
+
throwCompilationError(`[plumeria] Dynamic or unresolvable style object "${getSource(expr)}" is not supported.`, expr);
|
|
2280
2280
|
}
|
|
2281
2281
|
const styleParts = [
|
|
2282
2282
|
...existingStyleParts,
|
|
@@ -2346,7 +2346,7 @@ const transformSource = async (env) => {
|
|
|
2346
2346
|
const propKey = callee.property.value;
|
|
2347
2347
|
const styleInfo = localCreateStyles[varName];
|
|
2348
2348
|
if (styleInfo?.functions?.[propKey]) {
|
|
2349
|
-
throwCompilationError(`
|
|
2349
|
+
throwCompilationError(`[plumeria] css.use(${getSource(expr)}) does not support dynamic function keys.`, expr);
|
|
2350
2350
|
}
|
|
2351
2351
|
}
|
|
2352
2352
|
const { classParts, isOptimizable } = buildClassParts(args);
|
|
@@ -2359,7 +2359,7 @@ const transformSource = async (env) => {
|
|
|
2359
2359
|
});
|
|
2360
2360
|
}
|
|
2361
2361
|
else {
|
|
2362
|
-
throwCompilationError(`
|
|
2362
|
+
throwCompilationError(`[plumeria] Dynamic or unresolvable style object "${getSource(node)}" is not supported.`, node);
|
|
2363
2363
|
}
|
|
2364
2364
|
},
|
|
2365
2365
|
});
|
|
@@ -2369,7 +2369,7 @@ const transformSource = async (env) => {
|
|
|
2369
2369
|
if (appliedStyleProps.has(`${name}:${propName}`)) {
|
|
2370
2370
|
continue;
|
|
2371
2371
|
}
|
|
2372
|
-
throwCompilationError(`
|
|
2372
|
+
throwCompilationError(`[plumeria] "${propName}" is a style received through a prop but is never applied ` +
|
|
2373
2373
|
`to ${styleProp} or css.use() here. Apply it on an element this component renders; ` +
|
|
2374
2374
|
`a style prop cannot be passed on to another component.`, node);
|
|
2375
2375
|
}
|
|
@@ -2379,7 +2379,7 @@ const transformSource = async (env) => {
|
|
|
2379
2379
|
if (!isDev || keys.length === 0) {
|
|
2380
2380
|
return JSON.stringify('');
|
|
2381
2381
|
}
|
|
2382
|
-
const head = JSON.stringify(`
|
|
2382
|
+
const head = JSON.stringify(`[plumeria] "${info.name}.`);
|
|
2383
2383
|
const tail = JSON.stringify(`" was read at runtime. The file that read it was not compiled ` +
|
|
2384
2384
|
`because it does not reference "@plumeria/core" — add ` +
|
|
2385
2385
|
`import '@plumeria/core'; to it (see the stack below). Defined in ` +
|
|
@@ -2410,7 +2410,7 @@ const transformSource = async (env) => {
|
|
|
2410
2410
|
const end = call.span.end - baseByteOffset;
|
|
2411
2411
|
const isResolved = replacements.some((r) => r.start <= start && r.end >= end);
|
|
2412
2412
|
if (!isResolved) {
|
|
2413
|
-
throwCompilationError(`
|
|
2413
|
+
throwCompilationError(`[plumeria] ${getSource(call)} is only supported in the ${styleProp} prop. ` +
|
|
2414
2414
|
`A dynamic style function resolves to a class name and a CSS variable on the element itself, ` +
|
|
2415
2415
|
`so it cannot be passed through another prop or read as a value.`, call);
|
|
2416
2416
|
}
|
|
@@ -9,6 +9,7 @@ type ResolveSpread = (prop: SpreadElement) => SpreadInfo | null;
|
|
|
9
9
|
export type StyleContext = {
|
|
10
10
|
spread: ResolveSpread;
|
|
11
11
|
resolvesValue: (value: unknown) => boolean;
|
|
12
|
+
sourceOf?: (node: unknown) => string;
|
|
12
13
|
};
|
|
13
14
|
export declare const assertNoDroppedValues: (node: SourceObject, resolved: StaticValues | null | undefined, context?: StyleContext, ignore?: Set<string>) => void;
|
|
14
15
|
export {};
|
|
@@ -9,7 +9,7 @@ const keyValue = (key) => {
|
|
|
9
9
|
? value
|
|
10
10
|
: undefined;
|
|
11
11
|
};
|
|
12
|
-
const unresolvableValue = (key, node) => new Error(`[plumeria] Cannot resolve the value of "${key}" at build time (${node.type}). ` +
|
|
12
|
+
const unresolvableValue = (key, node, context) => new Error(`[plumeria] Cannot resolve the value of "${key}" at build time (${context?.sourceOf?.(node) ?? node.type}). ` +
|
|
13
13
|
`Values in css.create must be statically known; pass a runtime value through the ` +
|
|
14
14
|
`function form, css.create({ name: (value) => ({ ... }) }).`);
|
|
15
15
|
const overwrittenLater = (properties, index, key, context) => {
|
|
@@ -101,12 +101,12 @@ const assertStyleFunction = (func, context) => {
|
|
|
101
101
|
continue;
|
|
102
102
|
}
|
|
103
103
|
if (RUNTIME_ONLY.has(value.type) && !readsAnyOf(value, params))
|
|
104
|
-
throw unresolvableValue(key ?? '', value);
|
|
104
|
+
throw unresolvableValue(key ?? '', value, context);
|
|
105
105
|
if ((value.type === 'Identifier' || value.type === 'MemberExpression') &&
|
|
106
106
|
context &&
|
|
107
107
|
!readsAnyOf(value, params) &&
|
|
108
108
|
!context.resolvesValue(value))
|
|
109
|
-
throw unresolvableValue(key ?? '', value);
|
|
109
|
+
throw unresolvableValue(key ?? '', value, context);
|
|
110
110
|
}
|
|
111
111
|
};
|
|
112
112
|
walk(returned);
|
|
@@ -166,7 +166,7 @@ const assertNoDroppedValues = (node, resolved, context, ignore) => {
|
|
|
166
166
|
if (value.type === 'NullLiteral')
|
|
167
167
|
continue;
|
|
168
168
|
if (!(key in resolved))
|
|
169
|
-
throw unresolvableValue(key, value);
|
|
169
|
+
throw unresolvableValue(key, value, context);
|
|
170
170
|
if (value.type === 'ObjectExpression') {
|
|
171
171
|
const nested = resolved[key];
|
|
172
172
|
if (nested && typeof nested === 'object')
|