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.
Files changed (45) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/loaders/cssloader.cjs +649 -0
  6. package/dist/loaders/cssloader.cjs.map +1 -0
  7. package/dist/loaders/cssloader.d.cts +3 -0
  8. package/dist/loaders/cssloader.d.ts +3 -0
  9. package/dist/loaders/cssloader.js +616 -0
  10. package/dist/loaders/cssloader.js.map +1 -0
  11. package/dist/loaders/tsloader.cjs +844 -0
  12. package/dist/loaders/tsloader.cjs.map +1 -0
  13. package/dist/loaders/tsloader.d.cts +6 -0
  14. package/dist/loaders/tsloader.d.ts +6 -0
  15. package/dist/loaders/tsloader.js +820 -0
  16. package/dist/loaders/tsloader.js.map +1 -0
  17. package/{withYak → dist/withYak}/index.cjs +14 -7
  18. package/dist/withYak/index.cjs.map +1 -0
  19. package/{withYak → dist/withYak}/index.d.cts +2 -2
  20. package/dist/withYak/index.d.ts +37 -0
  21. package/dist/withYak/index.js +68 -0
  22. package/dist/withYak/index.js.map +1 -0
  23. package/loaders/__tests__/classifier.test.ts +99 -93
  24. package/loaders/__tests__/cssloader.test.ts +1 -1
  25. package/loaders/__tests__/getCssName.test.ts +1 -1
  26. package/loaders/__tests__/tsloader.test.ts +1 -1
  27. package/loaders/{babel-yak-plugin.cjs → babel-yak-plugin.ts} +69 -68
  28. package/loaders/{cssloader.cjs → cssloader.ts} +73 -97
  29. package/loaders/lib/{appendCssUnitToExpressionValue.cjs → appendCssUnitToExpressionValue.ts} +7 -10
  30. package/loaders/lib/{getConstantValues.cjs → getConstantValues.ts} +10 -17
  31. package/loaders/lib/{getCssName.cjs → getCssName.ts} +19 -31
  32. package/loaders/lib/{getStyledComponentName.cjs → getStyledComponentName.ts} +7 -10
  33. package/loaders/lib/{getYakImports.cjs → getYakImports.ts} +4 -10
  34. package/loaders/lib/{hash.cjs → hash.ts} +3 -5
  35. package/loaders/lib/{localIdent.cjs → localIdent.ts} +5 -7
  36. package/loaders/lib/{quasiClassifier.cjs → quasiClassifier.ts} +7 -16
  37. package/loaders/lib/{replaceQuasiExpressionTokens.cjs → replaceQuasiExpressionTokens.ts} +27 -26
  38. package/loaders/lib/{stripCssComments.cjs → stripCssComments.ts} +3 -9
  39. package/loaders/{tsloader.cjs → tsloader.ts} +11 -15
  40. package/package.json +12 -21
  41. package/runtime/__tests__/attrs.test.tsx +4 -14
  42. package/runtime/__tests__/styled.test.tsx +25 -6
  43. package/runtime/styled.tsx +5 -5
  44. package/withYak/index.ts +43 -34
  45. 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