@styleframe/transpiler 1.0.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/.tsbuildinfo +1 -0
- package/CHANGELOG.md +12 -0
- package/package.json +43 -0
- package/src/constants.ts +4 -0
- package/src/consume/at-rule.test.ts +339 -0
- package/src/consume/at-rule.ts +34 -0
- package/src/consume/consume.test.ts +259 -0
- package/src/consume/consume.ts +60 -0
- package/src/consume/container.test.ts +501 -0
- package/src/consume/container.ts +73 -0
- package/src/consume/css.test.ts +184 -0
- package/src/consume/css.ts +17 -0
- package/src/consume/declarations.test.ts +210 -0
- package/src/consume/declarations.ts +17 -0
- package/src/consume/index.ts +12 -0
- package/src/consume/primitive.test.ts +52 -0
- package/src/consume/primitive.ts +16 -0
- package/src/consume/ref.test.ts +84 -0
- package/src/consume/ref.ts +22 -0
- package/src/consume/root.test.ts +353 -0
- package/src/consume/root.ts +19 -0
- package/src/consume/selector.test.ts +441 -0
- package/src/consume/selector.ts +17 -0
- package/src/consume/theme.test.ts +215 -0
- package/src/consume/theme.ts +15 -0
- package/src/consume/utility.test.ts +696 -0
- package/src/consume/utility.ts +31 -0
- package/src/consume/variable.test.ts +197 -0
- package/src/consume/variable.ts +20 -0
- package/src/defaults.ts +21 -0
- package/src/generator/genAtRuleQuery.test.ts +148 -0
- package/src/generator/genAtRuleQuery.ts +3 -0
- package/src/generator/genDeclaration.test.ts +283 -0
- package/src/generator/genDeclaration.ts +9 -0
- package/src/generator/genDeclarationsBlock.test.ts +278 -0
- package/src/generator/genDeclarationsBlock.ts +7 -0
- package/src/generator/genDeclareVariable.test.ts +323 -0
- package/src/generator/genDeclareVariable.ts +6 -0
- package/src/generator/genInlineAtRule.test.ts +351 -0
- package/src/generator/genInlineAtRule.ts +5 -0
- package/src/generator/genReferenceVariable.test.ts +392 -0
- package/src/generator/genReferenceVariable.ts +5 -0
- package/src/generator/genSafePropertyName.test.ts +489 -0
- package/src/generator/genSafePropertyName.ts +5 -0
- package/src/generator/genSafeVariableName.test.ts +358 -0
- package/src/generator/genSafeVariableName.ts +21 -0
- package/src/generator/genSelector.test.ts +357 -0
- package/src/generator/genSelector.ts +5 -0
- package/src/generator/index.ts +9 -0
- package/src/index.ts +6 -0
- package/src/transpile.test.ts +825 -0
- package/src/transpile.ts +21 -0
- package/src/types.ts +15 -0
- package/src/utils.ts +18 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +7 -0
- package/vite.config.ts +5 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { genInlineAtRule } from "./genInlineAtRule";
|
|
3
|
+
|
|
4
|
+
describe("genInlineAtRule", () => {
|
|
5
|
+
it("should generate a basic import rule", () => {
|
|
6
|
+
const result = genInlineAtRule("import", "url('styles.css')");
|
|
7
|
+
expect(result).toBe("@import url('styles.css');");
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("should generate a charset rule", () => {
|
|
11
|
+
const result = genInlineAtRule("charset", '"UTF-8"');
|
|
12
|
+
expect(result).toBe('@charset "UTF-8";');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should generate a namespace rule", () => {
|
|
16
|
+
const result = genInlineAtRule(
|
|
17
|
+
"namespace",
|
|
18
|
+
"url(http://www.w3.org/1999/xhtml)",
|
|
19
|
+
);
|
|
20
|
+
expect(result).toBe("@namespace url(http://www.w3.org/1999/xhtml);");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should generate a namespace rule with prefix", () => {
|
|
24
|
+
const result = genInlineAtRule(
|
|
25
|
+
"namespace",
|
|
26
|
+
"svg url(http://www.w3.org/2000/svg)",
|
|
27
|
+
);
|
|
28
|
+
expect(result).toBe("@namespace svg url(http://www.w3.org/2000/svg);");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should generate an import rule with media query", () => {
|
|
32
|
+
const result = genInlineAtRule("import", "url('print.css') print");
|
|
33
|
+
expect(result).toBe("@import url('print.css') print;");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should generate an import rule with complex media query", () => {
|
|
37
|
+
const result = genInlineAtRule(
|
|
38
|
+
"import",
|
|
39
|
+
"url('mobile.css') screen and (max-width: 768px)",
|
|
40
|
+
);
|
|
41
|
+
expect(result).toBe(
|
|
42
|
+
"@import url('mobile.css') screen and (max-width: 768px);",
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("should generate an import rule with supports condition", () => {
|
|
47
|
+
const result = genInlineAtRule(
|
|
48
|
+
"import",
|
|
49
|
+
"url('grid.css') supports(display: grid)",
|
|
50
|
+
);
|
|
51
|
+
expect(result).toBe("@import url('grid.css') supports(display: grid);");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should generate an import rule with layer", () => {
|
|
55
|
+
const result = genInlineAtRule(
|
|
56
|
+
"import",
|
|
57
|
+
"url('utilities.css') layer(utilities)",
|
|
58
|
+
);
|
|
59
|
+
expect(result).toBe("@import url('utilities.css') layer(utilities);");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should handle import with relative path", () => {
|
|
63
|
+
const result = genInlineAtRule("import", "'./components/button.css'");
|
|
64
|
+
expect(result).toBe("@import './components/button.css';");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should handle import with absolute path", () => {
|
|
68
|
+
const result = genInlineAtRule("import", "'/styles/global.css'");
|
|
69
|
+
expect(result).toBe("@import '/styles/global.css';");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should handle import from node_modules", () => {
|
|
73
|
+
const result = genInlineAtRule("import", "'normalize.css'");
|
|
74
|
+
expect(result).toBe("@import 'normalize.css';");
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should handle import with HTTP URL", () => {
|
|
78
|
+
const result = genInlineAtRule(
|
|
79
|
+
"import",
|
|
80
|
+
"url('http://example.com/style.css')",
|
|
81
|
+
);
|
|
82
|
+
expect(result).toBe("@import url('http://example.com/style.css');");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should handle import with HTTPS URL", () => {
|
|
86
|
+
const result = genInlineAtRule(
|
|
87
|
+
"import",
|
|
88
|
+
"url('https://fonts.googleapis.com/css')",
|
|
89
|
+
);
|
|
90
|
+
expect(result).toBe("@import url('https://fonts.googleapis.com/css');");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("should handle import with data URI", () => {
|
|
94
|
+
const result = genInlineAtRule(
|
|
95
|
+
"import",
|
|
96
|
+
"url('data:text/css,body{margin:0}')",
|
|
97
|
+
);
|
|
98
|
+
expect(result).toBe("@import url('data:text/css,body{margin:0}');");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should handle charset with different encodings", () => {
|
|
102
|
+
const result = genInlineAtRule("charset", '"ISO-8859-1"');
|
|
103
|
+
expect(result).toBe('@charset "ISO-8859-1";');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should handle namespace with default namespace", () => {
|
|
107
|
+
const result = genInlineAtRule(
|
|
108
|
+
"namespace",
|
|
109
|
+
"url(http://www.w3.org/1999/xhtml)",
|
|
110
|
+
);
|
|
111
|
+
expect(result).toBe("@namespace url(http://www.w3.org/1999/xhtml);");
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("should handle namespace with XML namespace", () => {
|
|
115
|
+
const result = genInlineAtRule(
|
|
116
|
+
"namespace",
|
|
117
|
+
"xml url(http://www.w3.org/XML/1998/namespace)",
|
|
118
|
+
);
|
|
119
|
+
expect(result).toBe(
|
|
120
|
+
"@namespace xml url(http://www.w3.org/XML/1998/namespace);",
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should handle empty rule string", () => {
|
|
125
|
+
const result = genInlineAtRule("import", "");
|
|
126
|
+
expect(result).toBe("@import;");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("should handle whitespace in rule string", () => {
|
|
130
|
+
const result = genInlineAtRule("import", " url('styles.css') ");
|
|
131
|
+
expect(result).toBe("@import url('styles.css') ;");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should handle layer statement", () => {
|
|
135
|
+
const result = genInlineAtRule("layer", "reset");
|
|
136
|
+
expect(result).toBe("@layer reset;");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should handle layer with multiple layers", () => {
|
|
140
|
+
const result = genInlineAtRule("layer", "reset, base, utilities");
|
|
141
|
+
expect(result).toBe("@layer reset, base, utilities;");
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("should handle property rule (although typically used with blocks)", () => {
|
|
145
|
+
const result = genInlineAtRule("property", "--my-color");
|
|
146
|
+
expect(result).toBe("@property --my-color;");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("should handle counter-style (although typically used with blocks)", () => {
|
|
150
|
+
const result = genInlineAtRule("counter-style", "custom-counter");
|
|
151
|
+
expect(result).toBe("@counter-style custom-counter;");
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("should handle vendor-prefixed at-rules", () => {
|
|
155
|
+
const result = genInlineAtRule("-webkit-keyframes", "bounce");
|
|
156
|
+
expect(result).toBe("@-webkit-keyframes bounce;");
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("should handle import with multiple conditions", () => {
|
|
160
|
+
const result = genInlineAtRule(
|
|
161
|
+
"import",
|
|
162
|
+
"url('styles.css') screen and (min-width: 768px) and (orientation: landscape)",
|
|
163
|
+
);
|
|
164
|
+
expect(result).toBe(
|
|
165
|
+
"@import url('styles.css') screen and (min-width: 768px) and (orientation: landscape);",
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("should handle import with nested parentheses", () => {
|
|
170
|
+
const result = genInlineAtRule(
|
|
171
|
+
"import",
|
|
172
|
+
"url('modern.css') supports((display: grid) and (gap: 1rem))",
|
|
173
|
+
);
|
|
174
|
+
expect(result).toBe(
|
|
175
|
+
"@import url('modern.css') supports((display: grid) and (gap: 1rem));",
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("should handle import with layer and supports", () => {
|
|
180
|
+
const result = genInlineAtRule(
|
|
181
|
+
"import",
|
|
182
|
+
"url('framework.css') layer(framework) supports(display: flex)",
|
|
183
|
+
);
|
|
184
|
+
expect(result).toBe(
|
|
185
|
+
"@import url('framework.css') layer(framework) supports(display: flex);",
|
|
186
|
+
);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("should preserve exact spacing in complex rules", () => {
|
|
190
|
+
const result = genInlineAtRule(
|
|
191
|
+
"import",
|
|
192
|
+
"url('responsive.css') screen and (min-width: 768px)",
|
|
193
|
+
);
|
|
194
|
+
expect(result).toBe(
|
|
195
|
+
"@import url('responsive.css') screen and (min-width: 768px);",
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("should handle import with query parameters in URL", () => {
|
|
200
|
+
const result = genInlineAtRule(
|
|
201
|
+
"import",
|
|
202
|
+
"url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap')",
|
|
203
|
+
);
|
|
204
|
+
expect(result).toBe(
|
|
205
|
+
"@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');",
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("should handle import with hash in URL", () => {
|
|
210
|
+
const result = genInlineAtRule("import", "url('styles.css#section')");
|
|
211
|
+
expect(result).toBe("@import url('styles.css#section');");
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("should handle import with special characters in filename", () => {
|
|
215
|
+
const result = genInlineAtRule("import", "url('my-styles_v2.0.css')");
|
|
216
|
+
expect(result).toBe("@import url('my-styles_v2.0.css');");
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("should handle namespace with custom prefix", () => {
|
|
220
|
+
const result = genInlineAtRule(
|
|
221
|
+
"namespace",
|
|
222
|
+
"custom url(http://custom.namespace.com)",
|
|
223
|
+
);
|
|
224
|
+
expect(result).toBe("@namespace custom url(http://custom.namespace.com);");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it("should handle import with base64 encoded data URI", () => {
|
|
228
|
+
const result = genInlineAtRule(
|
|
229
|
+
"import",
|
|
230
|
+
"url('data:text/css;base64,Ym9keSB7IG1hcmdpbjogMDsgfQ==')",
|
|
231
|
+
);
|
|
232
|
+
expect(result).toBe(
|
|
233
|
+
"@import url('data:text/css;base64,Ym9keSB7IG1hcmdpbjogMDsgfQ==');",
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("should handle import with UTF-8 encoded data URI", () => {
|
|
238
|
+
const result = genInlineAtRule(
|
|
239
|
+
"import",
|
|
240
|
+
"url('data:text/css;charset=utf-8,body%20%7B%20margin%3A%200%3B%20%7D')",
|
|
241
|
+
);
|
|
242
|
+
expect(result).toBe(
|
|
243
|
+
"@import url('data:text/css;charset=utf-8,body%20%7B%20margin%3A%200%3B%20%7D');",
|
|
244
|
+
);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("should handle import with single quotes", () => {
|
|
248
|
+
const result = genInlineAtRule("import", "'styles.css'");
|
|
249
|
+
expect(result).toBe("@import 'styles.css';");
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("should handle import with double quotes", () => {
|
|
253
|
+
const result = genInlineAtRule("import", '"styles.css"');
|
|
254
|
+
expect(result).toBe('@import "styles.css";');
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("should handle import without quotes (bare URL)", () => {
|
|
258
|
+
const result = genInlineAtRule("import", "styles.css");
|
|
259
|
+
expect(result).toBe("@import styles.css;");
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it("should handle layer with nested layer names", () => {
|
|
263
|
+
const result = genInlineAtRule("layer", "framework.components.buttons");
|
|
264
|
+
expect(result).toBe("@layer framework.components.buttons;");
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it("should handle import with print media type", () => {
|
|
268
|
+
const result = genInlineAtRule("import", "'print.css' print");
|
|
269
|
+
expect(result).toBe("@import 'print.css' print;");
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it("should handle import with screen media type", () => {
|
|
273
|
+
const result = genInlineAtRule("import", "'screen.css' screen");
|
|
274
|
+
expect(result).toBe("@import 'screen.css' screen;");
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it("should handle import with all media type", () => {
|
|
278
|
+
const result = genInlineAtRule("import", "'all.css' all");
|
|
279
|
+
expect(result).toBe("@import 'all.css' all;");
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it("should handle import with speech media type", () => {
|
|
283
|
+
const result = genInlineAtRule("import", "'speech.css' speech");
|
|
284
|
+
expect(result).toBe("@import 'speech.css' speech;");
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it("should handle import with media feature queries", () => {
|
|
288
|
+
const result = genInlineAtRule(
|
|
289
|
+
"import",
|
|
290
|
+
"'dark.css' (prefers-color-scheme: dark)",
|
|
291
|
+
);
|
|
292
|
+
expect(result).toBe("@import 'dark.css' (prefers-color-scheme: dark);");
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("should handle import with reduced motion query", () => {
|
|
296
|
+
const result = genInlineAtRule(
|
|
297
|
+
"import",
|
|
298
|
+
"'animations.css' (prefers-reduced-motion: no-preference)",
|
|
299
|
+
);
|
|
300
|
+
expect(result).toBe(
|
|
301
|
+
"@import 'animations.css' (prefers-reduced-motion: no-preference);",
|
|
302
|
+
);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("should handle import with high contrast query", () => {
|
|
306
|
+
const result = genInlineAtRule(
|
|
307
|
+
"import",
|
|
308
|
+
"'high-contrast.css' (prefers-contrast: high)",
|
|
309
|
+
);
|
|
310
|
+
expect(result).toBe(
|
|
311
|
+
"@import 'high-contrast.css' (prefers-contrast: high);",
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it("should handle import with orientation query", () => {
|
|
316
|
+
const result = genInlineAtRule(
|
|
317
|
+
"import",
|
|
318
|
+
"'landscape.css' (orientation: landscape)",
|
|
319
|
+
);
|
|
320
|
+
expect(result).toBe("@import 'landscape.css' (orientation: landscape);");
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("should handle import with aspect ratio query", () => {
|
|
324
|
+
const result = genInlineAtRule(
|
|
325
|
+
"import",
|
|
326
|
+
"'wide.css' (min-aspect-ratio: 16/9)",
|
|
327
|
+
);
|
|
328
|
+
expect(result).toBe("@import 'wide.css' (min-aspect-ratio: 16/9);");
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it("should handle import with resolution query", () => {
|
|
332
|
+
const result = genInlineAtRule(
|
|
333
|
+
"import",
|
|
334
|
+
"'retina.css' (min-resolution: 2dppx)",
|
|
335
|
+
);
|
|
336
|
+
expect(result).toBe("@import 'retina.css' (min-resolution: 2dppx);");
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("should handle import with not operator", () => {
|
|
340
|
+
const result = genInlineAtRule(
|
|
341
|
+
"import",
|
|
342
|
+
"'desktop.css' not (max-width: 768px)",
|
|
343
|
+
);
|
|
344
|
+
expect(result).toBe("@import 'desktop.css' not (max-width: 768px);");
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it("should handle import with only operator", () => {
|
|
348
|
+
const result = genInlineAtRule("import", "'screen.css' only screen");
|
|
349
|
+
expect(result).toBe("@import 'screen.css' only screen;");
|
|
350
|
+
});
|
|
351
|
+
});
|