next-yak 0.0.35 → 0.0.39
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.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loaders/cssloader.cjs +649 -0
- package/dist/loaders/cssloader.cjs.map +1 -0
- package/dist/loaders/cssloader.d.cts +3 -0
- package/dist/loaders/cssloader.d.ts +3 -0
- package/dist/loaders/cssloader.js +616 -0
- package/dist/loaders/cssloader.js.map +1 -0
- package/dist/loaders/tsloader.cjs +844 -0
- package/dist/loaders/tsloader.cjs.map +1 -0
- package/dist/loaders/tsloader.d.cts +6 -0
- package/dist/loaders/tsloader.d.ts +6 -0
- package/dist/loaders/tsloader.js +820 -0
- package/dist/loaders/tsloader.js.map +1 -0
- package/{withYak → dist/withYak}/index.cjs +14 -7
- package/dist/withYak/index.cjs.map +1 -0
- package/{withYak → dist/withYak}/index.d.cts +2 -2
- package/dist/withYak/index.d.ts +37 -0
- package/dist/withYak/index.js +68 -0
- package/dist/withYak/index.js.map +1 -0
- package/loaders/__tests__/classifier.test.ts +99 -93
- package/loaders/__tests__/cssloader.test.ts +1 -1
- package/loaders/__tests__/getCssName.test.ts +1 -1
- package/loaders/__tests__/tsloader.test.ts +1 -1
- package/loaders/{babel-yak-plugin.cjs → babel-yak-plugin.ts} +69 -68
- package/loaders/{cssloader.cjs → cssloader.ts} +73 -97
- package/loaders/lib/{appendCssUnitToExpressionValue.cjs → appendCssUnitToExpressionValue.ts} +7 -10
- package/loaders/lib/{getConstantValues.cjs → getConstantValues.ts} +10 -17
- package/loaders/lib/{getCssName.cjs → getCssName.ts} +19 -31
- package/loaders/lib/{getStyledComponentName.cjs → getStyledComponentName.ts} +7 -10
- package/loaders/lib/{getYakImports.cjs → getYakImports.ts} +4 -10
- package/loaders/lib/{hash.cjs → hash.ts} +3 -5
- package/loaders/lib/{localIdent.cjs → localIdent.ts} +5 -7
- package/loaders/lib/{quasiClassifier.cjs → quasiClassifier.ts} +7 -16
- package/loaders/lib/{replaceQuasiExpressionTokens.cjs → replaceQuasiExpressionTokens.ts} +27 -26
- package/loaders/lib/{stripCssComments.cjs → stripCssComments.ts} +3 -9
- package/loaders/{tsloader.cjs → tsloader.ts} +11 -15
- package/package.json +12 -21
- package/runtime/__tests__/attrs.test.tsx +4 -14
- package/runtime/__tests__/styled.test.tsx +25 -6
- package/runtime/styled.tsx +5 -5
- package/withYak/index.ts +43 -34
- package/withYak/index.cjs.map +0 -1
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
// loaders/lib/getYakImports.ts
|
|
2
|
+
var getYakImports = (code) => {
|
|
3
|
+
const codeWithoutComments = code.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
4
|
+
const allImports = codeWithoutComments.matchAll(
|
|
5
|
+
/(^|\n|;)\s*import\s+(?:(\w+(?:\s+as\s+\w+)?)\s*,?\s*)?(?:{([^}]*)})?\s+from\s+["']([^'"]+\.yak)["'](;|\n)/g
|
|
6
|
+
);
|
|
7
|
+
return [...allImports].map(([, , defaultImport, namedImports, from]) => {
|
|
8
|
+
const imports = namedImports?.split(",").map((namedImport) => {
|
|
9
|
+
const [importedName, localName = importedName] = namedImport.replace(/^type\s+/, "").trim().split(/\s+as\s+/);
|
|
10
|
+
return { localName, importedName };
|
|
11
|
+
}) ?? [];
|
|
12
|
+
if (defaultImport) {
|
|
13
|
+
imports.push(parseDefaultImport(defaultImport));
|
|
14
|
+
}
|
|
15
|
+
return { imports, from };
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
function parseDefaultImport(defaultImport) {
|
|
19
|
+
const defaultImportArray = defaultImport.split(/\s+as\s+/);
|
|
20
|
+
return {
|
|
21
|
+
localName: defaultImportArray[1] ?? defaultImportArray[0],
|
|
22
|
+
importedName: defaultImportArray[0]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
var getYakImports_default = getYakImports;
|
|
26
|
+
|
|
27
|
+
// loaders/cssloader.ts
|
|
28
|
+
import babel from "@babel/core";
|
|
29
|
+
|
|
30
|
+
// loaders/lib/stripCssComments.ts
|
|
31
|
+
function stripCssComments(cssString) {
|
|
32
|
+
let isInsideString = false;
|
|
33
|
+
let currentCharacter = "";
|
|
34
|
+
let comment = "";
|
|
35
|
+
let returnValue = "";
|
|
36
|
+
for (let index = 0; index < cssString.length; index++) {
|
|
37
|
+
currentCharacter = cssString[index];
|
|
38
|
+
if (cssString[index - 1] !== "\\" && (currentCharacter === '"' || currentCharacter === "'")) {
|
|
39
|
+
if (isInsideString === currentCharacter) {
|
|
40
|
+
isInsideString = false;
|
|
41
|
+
} else if (!isInsideString) {
|
|
42
|
+
isInsideString = currentCharacter;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!isInsideString && currentCharacter === "/" && cssString[index + 1] === "*") {
|
|
46
|
+
let index2 = index + 2;
|
|
47
|
+
for (; index2 < cssString.length; index2++) {
|
|
48
|
+
if (cssString[index2] === "*" && cssString[index2 + 1] === "/") {
|
|
49
|
+
if (cssString[index2 + 2] === "\n") {
|
|
50
|
+
index2++;
|
|
51
|
+
} else if (cssString[index2 + 2] + cssString[index2 + 3] === "\r\n") {
|
|
52
|
+
index2 += 2;
|
|
53
|
+
}
|
|
54
|
+
comment = "";
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
comment += cssString[index2];
|
|
58
|
+
}
|
|
59
|
+
index = index2 + 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
returnValue += currentCharacter;
|
|
63
|
+
}
|
|
64
|
+
return returnValue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// loaders/lib/quasiClassifier.ts
|
|
68
|
+
function quasiClassifier(quasiValue, currentNestingScopes) {
|
|
69
|
+
const trimmedCssString = stripCssComments(quasiValue).trim();
|
|
70
|
+
if (trimmedCssString === "") {
|
|
71
|
+
return {
|
|
72
|
+
empty: true,
|
|
73
|
+
unknownSelector: false,
|
|
74
|
+
insideCssValue: false,
|
|
75
|
+
currentNestingScopes
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
let isInsideString = false;
|
|
79
|
+
let currentCharacter = "";
|
|
80
|
+
let newNestingLevel = [...currentNestingScopes];
|
|
81
|
+
let currentSelector = "";
|
|
82
|
+
for (let index = 0; index < trimmedCssString.length; index++) {
|
|
83
|
+
currentCharacter = trimmedCssString[index];
|
|
84
|
+
if (trimmedCssString[index - 1] !== "\\" && (currentCharacter === '"' || currentCharacter === "'")) {
|
|
85
|
+
if (isInsideString === currentCharacter) {
|
|
86
|
+
isInsideString = false;
|
|
87
|
+
} else if (!isInsideString) {
|
|
88
|
+
isInsideString = currentCharacter;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (isInsideString) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (currentCharacter === "{") {
|
|
95
|
+
const selector = currentSelector.trim();
|
|
96
|
+
if (selector !== "") {
|
|
97
|
+
newNestingLevel.push(selector);
|
|
98
|
+
}
|
|
99
|
+
currentSelector = "";
|
|
100
|
+
} else if (currentCharacter === "}") {
|
|
101
|
+
newNestingLevel.pop();
|
|
102
|
+
currentSelector = "";
|
|
103
|
+
} else if (currentCharacter === ";") {
|
|
104
|
+
currentSelector = "";
|
|
105
|
+
} else {
|
|
106
|
+
currentSelector += currentCharacter;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
empty: false,
|
|
111
|
+
unknownSelector: trimmedCssString[0] === "{" || trimmedCssString[0] === ",",
|
|
112
|
+
insideCssValue: currentCharacter !== "{" && currentCharacter !== "}" && currentCharacter !== ";",
|
|
113
|
+
currentNestingScopes: newNestingLevel
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// loaders/lib/localIdent.ts
|
|
118
|
+
function localIdent(variableName, i, kind) {
|
|
119
|
+
switch (kind) {
|
|
120
|
+
case "selector":
|
|
121
|
+
return `.${variableName}${i === null ? "" : `_${i}`}`;
|
|
122
|
+
case "className":
|
|
123
|
+
case "animation":
|
|
124
|
+
return `${variableName}${i === null ? "" : `_${i}`}`;
|
|
125
|
+
case "keyframes":
|
|
126
|
+
return `@keyframes ${variableName}${i === null ? "" : `_${i}`}`;
|
|
127
|
+
default:
|
|
128
|
+
throw new Error("unknown kind");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// loaders/lib/replaceQuasiExpressionTokens.ts
|
|
133
|
+
function replaceTokensInQuasiExpressions(quasi, replacer, t) {
|
|
134
|
+
for (let i = quasi.expressions.length - 1; i >= 0; i--) {
|
|
135
|
+
const expression = quasi.expressions[i];
|
|
136
|
+
const parts = getExpressionParts(expression, t);
|
|
137
|
+
const replacement = parts && replacer(parts[0]);
|
|
138
|
+
const replacementValue = replacement && getReplacementValue(replacement, parts);
|
|
139
|
+
if (replacementValue !== false && replacementValue !== null) {
|
|
140
|
+
replaceExpressionAndMergeQuasis(quasi, i, replacementValue);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function replaceExpressionAndMergeQuasis(quasi, expressionIndex, replacement) {
|
|
145
|
+
const stringReplacement = typeof replacement === "string" ? replacement : replacement == null ? "" : JSON.stringify(replacement);
|
|
146
|
+
quasi.expressions.splice(expressionIndex, 1);
|
|
147
|
+
quasi.quasis[expressionIndex].value.raw += stringReplacement + quasi.quasis[expressionIndex + 1].value.raw;
|
|
148
|
+
quasi.quasis[expressionIndex].value.cooked += stringReplacement + quasi.quasis[expressionIndex + 1].value.cooked;
|
|
149
|
+
quasi.quasis.splice(expressionIndex + 1, 1);
|
|
150
|
+
}
|
|
151
|
+
function getExpressionParts(expression, t) {
|
|
152
|
+
let currentExpression = expression;
|
|
153
|
+
const tokens = [];
|
|
154
|
+
while (currentExpression) {
|
|
155
|
+
if (t.isIdentifier(currentExpression)) {
|
|
156
|
+
tokens.unshift(currentExpression.name);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
if (t.isMemberExpression(currentExpression)) {
|
|
160
|
+
if (currentExpression.computed === false && t.isIdentifier(currentExpression.property)) {
|
|
161
|
+
tokens.unshift(currentExpression.property.name);
|
|
162
|
+
} else if (t.isStringLiteral(currentExpression.property)) {
|
|
163
|
+
tokens.unshift(currentExpression.property.value);
|
|
164
|
+
} else if (t.isNumericLiteral(currentExpression.property)) {
|
|
165
|
+
tokens.unshift(String(currentExpression.property.value));
|
|
166
|
+
} else {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
currentExpression = currentExpression.object;
|
|
170
|
+
} else if (t.isCallExpression(currentExpression)) {
|
|
171
|
+
if (!t.isExpression(currentExpression.callee)) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
currentExpression = currentExpression.callee;
|
|
175
|
+
} else {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return tokens;
|
|
180
|
+
}
|
|
181
|
+
function getReplacementValue(replacement, parts) {
|
|
182
|
+
let currentReplacement = replacement;
|
|
183
|
+
for (let i = 1; i < parts.length; i++) {
|
|
184
|
+
const part = parts[i];
|
|
185
|
+
if (currentReplacement == null || typeof currentReplacement !== "object") {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
currentReplacement = currentReplacement[part];
|
|
189
|
+
}
|
|
190
|
+
return currentReplacement;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// loaders/lib/getStyledComponentName.ts
|
|
194
|
+
var getStyledComponentName = (taggedTemplateExpressionPath) => {
|
|
195
|
+
const variableDeclaratorPath = taggedTemplateExpressionPath.findParent(
|
|
196
|
+
(path) => path.isVariableDeclarator()
|
|
197
|
+
);
|
|
198
|
+
if (!variableDeclaratorPath || !("id" in variableDeclaratorPath.node) || variableDeclaratorPath.node.id?.type !== "Identifier") {
|
|
199
|
+
throw new Error(
|
|
200
|
+
"Could not find variable declaration for styled component at " + taggedTemplateExpressionPath.node.loc
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return variableDeclaratorPath.node.id.name;
|
|
204
|
+
};
|
|
205
|
+
var getStyledComponentName_default = getStyledComponentName;
|
|
206
|
+
|
|
207
|
+
// loaders/lib/getCssName.ts
|
|
208
|
+
function extractConditions(path) {
|
|
209
|
+
const conditions = [];
|
|
210
|
+
const visitedNodes = /* @__PURE__ */ new Set();
|
|
211
|
+
const getConditions = (node, previousNode, isNegated = false) => {
|
|
212
|
+
if (visitedNodes.has(node))
|
|
213
|
+
return;
|
|
214
|
+
visitedNodes.add(node);
|
|
215
|
+
if (node.type === "LogicalExpression") {
|
|
216
|
+
if (node.operator === "&&") {
|
|
217
|
+
getConditions(node.right, previousNode, isNegated);
|
|
218
|
+
conditions.push("and");
|
|
219
|
+
getConditions(node.left, previousNode, isNegated);
|
|
220
|
+
} else if (node.operator === "||") {
|
|
221
|
+
getConditions(node.right, previousNode, isNegated);
|
|
222
|
+
conditions.push("or");
|
|
223
|
+
getConditions(node.left, previousNode, isNegated);
|
|
224
|
+
}
|
|
225
|
+
} else if (node.type === "ConditionalExpression") {
|
|
226
|
+
conditions.push("and");
|
|
227
|
+
getConditions(node.test, previousNode, node.alternate === previousNode);
|
|
228
|
+
} else if (node.type === "UnaryExpression" && node.operator === "!") {
|
|
229
|
+
getConditions(node.argument, previousNode, !isNegated);
|
|
230
|
+
} else if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "Boolean") {
|
|
231
|
+
getConditions(node.arguments[0], previousNode, isNegated);
|
|
232
|
+
} else if (node.type === "Identifier") {
|
|
233
|
+
conditions.push((isNegated ? "not_" : "") + node.name);
|
|
234
|
+
} else if (node.type === "MemberExpression") {
|
|
235
|
+
conditions.push(
|
|
236
|
+
(isNegated ? "not_" : "") + getMemberExpressionName(node)
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
let currentPath = path;
|
|
241
|
+
let previousPath = path;
|
|
242
|
+
while (currentPath) {
|
|
243
|
+
getConditions(currentPath.node, previousPath.node);
|
|
244
|
+
previousPath = currentPath;
|
|
245
|
+
currentPath = currentPath.parentPath;
|
|
246
|
+
}
|
|
247
|
+
if (conditions[0] === "or" || conditions[0] === "and") {
|
|
248
|
+
conditions.shift();
|
|
249
|
+
}
|
|
250
|
+
return conditions.reverse();
|
|
251
|
+
}
|
|
252
|
+
var getStyledComponentName2 = (taggedTemplateExpressionPath) => {
|
|
253
|
+
const variableDeclaratorPath = taggedTemplateExpressionPath.findParent(
|
|
254
|
+
(path) => path.isVariableDeclarator()
|
|
255
|
+
);
|
|
256
|
+
if (!variableDeclaratorPath || !("id" in variableDeclaratorPath.node) || variableDeclaratorPath.node.id?.type !== "Identifier") {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
return variableDeclaratorPath.node.id.name;
|
|
260
|
+
};
|
|
261
|
+
function getMemberExpressionName(node) {
|
|
262
|
+
if (!node.object || !node.property || node.object.type !== "Identifier" && node.object.type !== "MemberExpression") {
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
265
|
+
const objectName = node.object.type === "Identifier" ? node.object.name : getMemberExpressionName(node.object);
|
|
266
|
+
const property = node.property;
|
|
267
|
+
let propertyName = "";
|
|
268
|
+
if (property.type === "Identifier") {
|
|
269
|
+
propertyName = property.name;
|
|
270
|
+
} else if (property.type === "StringLiteral") {
|
|
271
|
+
propertyName = property.value;
|
|
272
|
+
}
|
|
273
|
+
if (!propertyName) {
|
|
274
|
+
return "";
|
|
275
|
+
}
|
|
276
|
+
return objectName + propertyName[0].toUpperCase() + propertyName.slice(1);
|
|
277
|
+
}
|
|
278
|
+
function getCssName(literal) {
|
|
279
|
+
const conditions = extractConditions(literal);
|
|
280
|
+
if (conditions.length === 0) {
|
|
281
|
+
const mixinName = getStyledComponentName2(literal);
|
|
282
|
+
return mixinName ? mixinName : "yak";
|
|
283
|
+
}
|
|
284
|
+
return conditions.join("_").replace(/\$/g, "");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// loaders/lib/hash.ts
|
|
288
|
+
function murmurhash2_32_gc(str) {
|
|
289
|
+
let l = str.length;
|
|
290
|
+
let h = l;
|
|
291
|
+
let i = 0;
|
|
292
|
+
let k;
|
|
293
|
+
while (l >= 4) {
|
|
294
|
+
k = str.charCodeAt(i) & 255 | (str.charCodeAt(++i) & 255) << 8 | (str.charCodeAt(++i) & 255) << 16 | (str.charCodeAt(++i) & 255) << 24;
|
|
295
|
+
k = (k & 65535) * 1540483477 + (((k >>> 16) * 1540483477 & 65535) << 16);
|
|
296
|
+
k ^= k >>> 24;
|
|
297
|
+
k = (k & 65535) * 1540483477 + (((k >>> 16) * 1540483477 & 65535) << 16);
|
|
298
|
+
h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16) ^ k;
|
|
299
|
+
l -= 4;
|
|
300
|
+
++i;
|
|
301
|
+
}
|
|
302
|
+
switch (l) {
|
|
303
|
+
case 3:
|
|
304
|
+
h ^= (str.charCodeAt(i + 2) & 255) << 16;
|
|
305
|
+
case 2:
|
|
306
|
+
h ^= (str.charCodeAt(i + 1) & 255) << 8;
|
|
307
|
+
case 1:
|
|
308
|
+
h ^= str.charCodeAt(i) & 255;
|
|
309
|
+
h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16);
|
|
310
|
+
}
|
|
311
|
+
h ^= h >>> 13;
|
|
312
|
+
h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16);
|
|
313
|
+
h ^= h >>> 15;
|
|
314
|
+
return (h >>> 0).toString(36);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// loaders/cssloader.ts
|
|
318
|
+
import { relative } from "path";
|
|
319
|
+
|
|
320
|
+
// loaders/lib/getConstantValues.ts
|
|
321
|
+
var getConstantName = (expression, t) => {
|
|
322
|
+
if (t.isIdentifier(expression)) {
|
|
323
|
+
return expression.name;
|
|
324
|
+
} else if (t.isMemberExpression(expression) && t.isIdentifier(expression.object)) {
|
|
325
|
+
return expression.object.name;
|
|
326
|
+
} else if (t.isCallExpression(expression) && t.isIdentifier(expression.callee)) {
|
|
327
|
+
return expression.callee.name;
|
|
328
|
+
} else if (t.isCallExpression(expression) && t.isMemberExpression(expression.callee) && t.isIdentifier(expression.callee.object)) {
|
|
329
|
+
return expression.callee.object.name;
|
|
330
|
+
} else {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
function getConstantValues(path, t) {
|
|
335
|
+
const topLevelConstBindings = /* @__PURE__ */ new Map();
|
|
336
|
+
const bindings = Object.entries(path.scope.bindings);
|
|
337
|
+
for (const [name, binding] of bindings) {
|
|
338
|
+
if (binding.kind === "module") {
|
|
339
|
+
topLevelConstBindings.set(name, null);
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (binding.kind === "let" || binding.kind === "var" || binding.kind === "const") {
|
|
343
|
+
if (!("init" in binding.path.node) || t.isFunctionDeclaration(binding.path.node.init) || t.isArrowFunctionExpression(binding.path.node.init)) {
|
|
344
|
+
topLevelConstBindings.set(name, null);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
const value = binding.path.node.init;
|
|
348
|
+
topLevelConstBindings.set(
|
|
349
|
+
name,
|
|
350
|
+
t.isStringLiteral(value) || t.isNumericLiteral(value) ? value.value : null
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return topLevelConstBindings;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// loaders/cssloader.ts
|
|
358
|
+
async function cssLoader(source) {
|
|
359
|
+
const { rootContext, resourcePath } = this;
|
|
360
|
+
const isYakFile = /\.yak\.(j|t)sx?$/.test(resourcePath.matches);
|
|
361
|
+
const importedYakConstants = isYakFile ? [] : getYakImports_default(source);
|
|
362
|
+
const replaces = {};
|
|
363
|
+
await Promise.all(
|
|
364
|
+
importedYakConstants.map(async ({ imports, from }) => {
|
|
365
|
+
const constantValues = await this.importModule(from, {
|
|
366
|
+
layer: "yak-importModule"
|
|
367
|
+
});
|
|
368
|
+
imports.forEach(({ localName, importedName }) => {
|
|
369
|
+
replaces[localName] = constantValues[importedName];
|
|
370
|
+
});
|
|
371
|
+
})
|
|
372
|
+
);
|
|
373
|
+
const ast = babel.parseSync(source, {
|
|
374
|
+
filename: this.resourcePath,
|
|
375
|
+
configFile: false,
|
|
376
|
+
plugins: [
|
|
377
|
+
[
|
|
378
|
+
"@babel/plugin-syntax-typescript",
|
|
379
|
+
{ isTSX: this.resourcePath.endsWith(".tsx") }
|
|
380
|
+
]
|
|
381
|
+
]
|
|
382
|
+
});
|
|
383
|
+
if (ast === null) {
|
|
384
|
+
return "";
|
|
385
|
+
}
|
|
386
|
+
const { types: t } = babel;
|
|
387
|
+
const localVarNames = {
|
|
388
|
+
css: void 0,
|
|
389
|
+
styled: void 0,
|
|
390
|
+
attrs: "attrs",
|
|
391
|
+
keyframes: void 0
|
|
392
|
+
};
|
|
393
|
+
const cssParts = /* @__PURE__ */ new Map();
|
|
394
|
+
let index = 0;
|
|
395
|
+
let varIndex = 0;
|
|
396
|
+
let hashedFile = null;
|
|
397
|
+
const variableNameToStyledClassName = /* @__PURE__ */ new Map();
|
|
398
|
+
let topLevelConstBindings = /* @__PURE__ */ new Map();
|
|
399
|
+
babel.traverse(ast, {
|
|
400
|
+
Program(path) {
|
|
401
|
+
topLevelConstBindings = getConstantValues(path, t);
|
|
402
|
+
},
|
|
403
|
+
ImportDeclaration(path) {
|
|
404
|
+
const node = path.node;
|
|
405
|
+
if (node.source.value !== "next-yak") {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
node.specifiers.forEach((specifier) => {
|
|
409
|
+
if (!("imported" in specifier) || !specifier.imported || !t.isIdentifier(specifier.imported)) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
const importSpecifier = (
|
|
413
|
+
/** @type {babel.types.Identifier} */
|
|
414
|
+
specifier.imported
|
|
415
|
+
);
|
|
416
|
+
const localSpecifier = specifier.local || importSpecifier;
|
|
417
|
+
if (importSpecifier.name === "styled" || importSpecifier.name === "css" || importSpecifier.name === "keyframes") {
|
|
418
|
+
localVarNames[importSpecifier.name] = localSpecifier.name;
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
},
|
|
422
|
+
/**
|
|
423
|
+
* @param {import("@babel/core").NodePath<import("@babel/types").TaggedTemplateExpression>} path
|
|
424
|
+
*/
|
|
425
|
+
TaggedTemplateExpression(path) {
|
|
426
|
+
const tag = path.node.tag;
|
|
427
|
+
const isCssLiteral = t.isIdentifier(tag) && /** @type {babel.types.Identifier} */
|
|
428
|
+
tag.name === localVarNames.css;
|
|
429
|
+
const isKeyFrameLiteral = t.isIdentifier(tag) && /** @type {babel.types.Identifier} */
|
|
430
|
+
tag.name === localVarNames.keyframes;
|
|
431
|
+
const isStyledLiteral = t.isMemberExpression(tag) && t.isIdentifier(
|
|
432
|
+
/** @type {babel.types.MemberExpression} */
|
|
433
|
+
tag.object
|
|
434
|
+
) && /** @type {babel.types.Identifier} */
|
|
435
|
+
/** @type {babel.types.MemberExpression} */
|
|
436
|
+
tag.object.name === localVarNames.styled;
|
|
437
|
+
const isStyledCall = t.isCallExpression(tag) && t.isIdentifier(
|
|
438
|
+
/** @type {babel.types.CallExpression} */
|
|
439
|
+
tag.callee
|
|
440
|
+
) && /** @type {babel.types.Identifier} */
|
|
441
|
+
/** @type {babel.types.CallExpression} */
|
|
442
|
+
tag.callee.name === localVarNames.styled;
|
|
443
|
+
const isAttrsCall = t.isCallExpression(tag) && t.isMemberExpression(tag.callee) && tag.callee.property.name === "attrs";
|
|
444
|
+
if (!isCssLiteral && !isKeyFrameLiteral && !isStyledLiteral && !isStyledCall && !isAttrsCall) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
replaceTokensInQuasiExpressions(
|
|
448
|
+
path.node.quasi,
|
|
449
|
+
(name) => {
|
|
450
|
+
if (name in replaces) {
|
|
451
|
+
return replaces[name];
|
|
452
|
+
}
|
|
453
|
+
if (variableNameToStyledClassName.has(name)) {
|
|
454
|
+
return variableNameToStyledClassName.get(name);
|
|
455
|
+
}
|
|
456
|
+
return false;
|
|
457
|
+
},
|
|
458
|
+
t
|
|
459
|
+
);
|
|
460
|
+
const parentLocation = getClosestTemplateLiteralExpressionParentPath(
|
|
461
|
+
path,
|
|
462
|
+
localVarNames
|
|
463
|
+
);
|
|
464
|
+
const variableName = isStyledLiteral || isStyledCall || isAttrsCall || isKeyFrameLiteral ? getStyledComponentName_default(path) : isCssLiteral ? getCssName(path) : null;
|
|
465
|
+
const literalSelector = localIdent(
|
|
466
|
+
variableName || "_yak",
|
|
467
|
+
variableName && !isCssLiteral ? null : index++,
|
|
468
|
+
isKeyFrameLiteral ? "keyframes" : "selector"
|
|
469
|
+
);
|
|
470
|
+
const currentCssParts = {
|
|
471
|
+
quasiCode: [],
|
|
472
|
+
cssPartExpressions: [],
|
|
473
|
+
selector: !parentLocation ? literalSelector : `&:where(${literalSelector})`,
|
|
474
|
+
hasParent: Boolean(parentLocation)
|
|
475
|
+
};
|
|
476
|
+
const parentCssParts = parentLocation && cssParts.get(
|
|
477
|
+
parentLocation.parent
|
|
478
|
+
);
|
|
479
|
+
cssParts.set(path, currentCssParts);
|
|
480
|
+
if (parentCssParts) {
|
|
481
|
+
parentCssParts.cssPartExpressions[parentLocation.currentIndex] ||= [];
|
|
482
|
+
parentCssParts.cssPartExpressions[parentLocation.currentIndex].push(
|
|
483
|
+
currentCssParts
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
const quasis = path.node.quasi.quasis;
|
|
487
|
+
const quasiTypes = quasis.map(
|
|
488
|
+
(quasi) => quasiClassifier(quasi.value.raw, [])
|
|
489
|
+
);
|
|
490
|
+
let wasInsideCssValue = false;
|
|
491
|
+
let removeCssUnit = false;
|
|
492
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
493
|
+
const quasi = quasis[i];
|
|
494
|
+
const expression = path.node.quasi.expressions[i];
|
|
495
|
+
const type = quasiTypes[i];
|
|
496
|
+
let code = unEscapeCssCode(quasi.value.raw);
|
|
497
|
+
if (removeCssUnit) {
|
|
498
|
+
code = code.replace(/^([a-z]+|%)/i, "");
|
|
499
|
+
removeCssUnit = false;
|
|
500
|
+
}
|
|
501
|
+
if (expression && (type.unknownSelector || type.insideCssValue || type.empty && wasInsideCssValue)) {
|
|
502
|
+
wasInsideCssValue = true;
|
|
503
|
+
if (!hashedFile) {
|
|
504
|
+
const relativePath = relative(rootContext, resourcePath);
|
|
505
|
+
hashedFile = murmurhash2_32_gc(relativePath);
|
|
506
|
+
}
|
|
507
|
+
const variableName2 = t.isExpression(expression) && getConstantName(expression, t);
|
|
508
|
+
const variableConstValue = variableName2 && topLevelConstBindings.get(variableName2);
|
|
509
|
+
if (variableConstValue === null || variableConstValue === void 0) {
|
|
510
|
+
currentCssParts.quasiCode.push({
|
|
511
|
+
insideCssValue: true,
|
|
512
|
+
code: code + // replace the expression with a css variable
|
|
513
|
+
`var(--\u{1F9AC}${hashedFile}${varIndex++})`
|
|
514
|
+
});
|
|
515
|
+
removeCssUnit = true;
|
|
516
|
+
} else {
|
|
517
|
+
currentCssParts.quasiCode.push({
|
|
518
|
+
insideCssValue: true,
|
|
519
|
+
code: code + String(variableConstValue)
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
} else {
|
|
523
|
+
wasInsideCssValue = false;
|
|
524
|
+
currentCssParts.quasiCode.push({
|
|
525
|
+
code,
|
|
526
|
+
insideCssValue: false
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (variableName && (isStyledLiteral || isStyledCall || isAttrsCall)) {
|
|
531
|
+
variableNameToStyledClassName.set(variableName, literalSelector);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
const rootCssParts = [...cssParts.values()].filter(
|
|
536
|
+
({ hasParent }) => !hasParent
|
|
537
|
+
);
|
|
538
|
+
return mergeCssPartExpression(rootCssParts).trim();
|
|
539
|
+
}
|
|
540
|
+
var unEscapeCssCode = (code) => code.replace(/\\\\/gi, "\\");
|
|
541
|
+
var getClosestTemplateLiteralExpressionParentPath = (path, { css, styled }) => {
|
|
542
|
+
let grandChild = path;
|
|
543
|
+
let child = path;
|
|
544
|
+
let parent = path.parentPath;
|
|
545
|
+
const t = babel.types;
|
|
546
|
+
while (parent) {
|
|
547
|
+
if (t.isTaggedTemplateExpression(parent.node)) {
|
|
548
|
+
const tag = parent.node.tag;
|
|
549
|
+
const isCssLiteral = t.isIdentifier(tag) && /** @type {babel.types.Identifier} */
|
|
550
|
+
tag.name === css;
|
|
551
|
+
const isStyledLiteral = t.isMemberExpression(tag) && t.isIdentifier(
|
|
552
|
+
/** @type {babel.types.MemberExpression} */
|
|
553
|
+
tag.object
|
|
554
|
+
) && /** @type {babel.types.Identifier} */
|
|
555
|
+
/** @type {babel.types.MemberExpression} */
|
|
556
|
+
tag.object.name === styled;
|
|
557
|
+
const isStyledCall = t.isCallExpression(tag) && t.isIdentifier(
|
|
558
|
+
/** @type {babel.types.CallExpression} */
|
|
559
|
+
tag.callee
|
|
560
|
+
) && /** @type {babel.types.Identifier} */
|
|
561
|
+
/** @type {babel.types.CallExpression} */
|
|
562
|
+
tag.callee.name === styled;
|
|
563
|
+
const isAttrsCall = t.isCallExpression(tag) && t.isMemberExpression(tag.callee) && tag.callee.property.name === "attrs";
|
|
564
|
+
if (isCssLiteral || isStyledLiteral || isStyledCall || isAttrsCall) {
|
|
565
|
+
if (!t.isTemplateLiteral(child.node) || !t.isExpression(grandChild.node)) {
|
|
566
|
+
throw new Error("Broken AST");
|
|
567
|
+
}
|
|
568
|
+
const currentIndex = child.node.expressions.indexOf(grandChild.node);
|
|
569
|
+
return {
|
|
570
|
+
parent: (
|
|
571
|
+
/** @type {import("@babel/core").NodePath<import("@babel/types").TaggedTemplateExpression>} */
|
|
572
|
+
parent
|
|
573
|
+
),
|
|
574
|
+
currentIndex
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
if (!parent.parentPath) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
grandChild = child;
|
|
582
|
+
child = parent;
|
|
583
|
+
parent = parent.parentPath;
|
|
584
|
+
}
|
|
585
|
+
return null;
|
|
586
|
+
};
|
|
587
|
+
var mergeCssPartExpression = (cssPartExpression, level = 0) => {
|
|
588
|
+
let css = "";
|
|
589
|
+
for (const { quasiCode, cssPartExpressions, selector } of cssPartExpression) {
|
|
590
|
+
let cssPart = "";
|
|
591
|
+
for (let i = 0; i < quasiCode.length; i++) {
|
|
592
|
+
const quasi = quasiCode[i];
|
|
593
|
+
cssPart += trimNewLines(quasi.code);
|
|
594
|
+
const childCssParts = cssPartExpressions[i];
|
|
595
|
+
if (childCssParts) {
|
|
596
|
+
cssPart += `
|
|
597
|
+
${trimNewLines(
|
|
598
|
+
mergeCssPartExpression(childCssParts, level + 1)
|
|
599
|
+
)}
|
|
600
|
+
`;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const indent = quasiCode[0]?.code.match(/^\n( |\t)(\s*)/)?.[2] ?? " ".repeat(level);
|
|
604
|
+
const hasCss = Boolean(cssPart.trim());
|
|
605
|
+
css += !hasCss ? "" : `${indent}${selector} {
|
|
606
|
+
${trimNewLines(cssPart)}
|
|
607
|
+
${indent}}
|
|
608
|
+
`;
|
|
609
|
+
}
|
|
610
|
+
return css;
|
|
611
|
+
};
|
|
612
|
+
var trimNewLines = (str) => str.replace(/^\s*\n+|\s+$/g, "");
|
|
613
|
+
export {
|
|
614
|
+
cssLoader as default
|
|
615
|
+
};
|
|
616
|
+
//# sourceMappingURL=cssloader.js.map
|