@pandacss/parser 0.3.2 → 0.5.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.
@@ -0,0 +1,78 @@
1
+ import * as ts_morph from 'ts-morph';
2
+ import { ProjectOptions as ProjectOptions$1 } from 'ts-morph';
3
+ import { ResultItem, RecipeConfig, PandaHookable } from '@pandacss/types';
4
+
5
+ declare class ParserResult {
6
+ jsx: Set<ResultItem>;
7
+ css: Set<ResultItem>;
8
+ cva: Set<ResultItem>;
9
+ recipe: Map<string, Set<ResultItem>>;
10
+ pattern: Map<string, Set<ResultItem>>;
11
+ filePath: string | undefined;
12
+ set(name: 'cva' | 'css', result: ResultItem): void;
13
+ setCva(result: ResultItem): void;
14
+ setJsx(result: ResultItem): void;
15
+ setPattern(name: string, result: ResultItem): void;
16
+ setRecipe(name: string, result: ResultItem): void;
17
+ isEmpty(): boolean;
18
+ setFilePath(filePath: string): this;
19
+ toArray(): ResultItem[];
20
+ toJSON(): {
21
+ css: ResultItem[];
22
+ cva: ResultItem[];
23
+ recipe: {
24
+ [k: string]: ResultItem[];
25
+ };
26
+ pattern: {
27
+ [k: string]: ResultItem[];
28
+ };
29
+ jsx: ResultItem[];
30
+ };
31
+ merge(result: ParserResult): this;
32
+ static fromJSON(json: string): ParserResult;
33
+ }
34
+ declare const createParserResult: () => ParserResult;
35
+
36
+ type ParserPatternNode = {
37
+ name: string;
38
+ type: 'pattern';
39
+ props?: string[];
40
+ baseName: string;
41
+ };
42
+ type ParserRecipeNode = {
43
+ name: string;
44
+ type: 'recipe';
45
+ props: string[];
46
+ baseName: string;
47
+ jsx: RecipeConfig['jsx'];
48
+ };
49
+ type ParserNodeOptions = ParserPatternNode | ParserRecipeNode;
50
+ type ParserOptions = {
51
+ importMap: Record<'css' | 'recipe' | 'pattern' | 'jsx', string>;
52
+ jsx?: {
53
+ factory: string;
54
+ nodes: ParserNodeOptions[];
55
+ isStyleProp: (prop: string) => boolean;
56
+ };
57
+ getRecipeName: (tagName: string) => string;
58
+ getRecipeByName: (name: string) => RecipeConfig | undefined;
59
+ };
60
+
61
+ type ProjectOptions = Partial<ProjectOptions$1> & {
62
+ readFile: (filePath: string) => string;
63
+ getFiles: () => string[];
64
+ hooks: PandaHookable;
65
+ parserOptions: ParserOptions;
66
+ };
67
+ declare const createProject: ({ getFiles, readFile, parserOptions, hooks, ...projectOptions }: ProjectOptions) => {
68
+ getSourceFile: (filePath: string) => ts_morph.SourceFile | undefined;
69
+ removeSourceFile: (filePath: string) => void;
70
+ createSourceFile: (filePath: string) => ts_morph.SourceFile;
71
+ addSourceFile: (filePath: string, content: string) => ts_morph.SourceFile;
72
+ parseSourceFile: (filePath: string) => ParserResult | undefined;
73
+ reloadSourceFile: (filePath: string) => ts_morph.FileSystemRefreshResult | undefined;
74
+ reloadSourceFiles: () => void;
75
+ };
76
+ type Project = ReturnType<typeof createProject>;
77
+
78
+ export { ParserResult, Project, ProjectOptions, createParserResult, createProject };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -87,7 +97,7 @@ function getImportDeclarations(file, options) {
87
97
  }
88
98
 
89
99
  // src/parser-result.ts
90
- var ParserResult = class {
100
+ var ParserResult = class _ParserResult {
91
101
  jsx = /* @__PURE__ */ new Set();
92
102
  css = /* @__PURE__ */ new Set();
93
103
  cva = /* @__PURE__ */ new Set();
@@ -152,7 +162,7 @@ var ParserResult = class {
152
162
  }
153
163
  static fromJSON(json) {
154
164
  const data = JSON.parse(json);
155
- const result = new ParserResult();
165
+ const result = new _ParserResult();
156
166
  result.css = new Set(data.css);
157
167
  result.cva = new Set(data.cva);
158
168
  result.recipe = new Map(Object.entries(data.recipe));
@@ -165,6 +175,8 @@ var createParserResult = () => new ParserResult();
165
175
 
166
176
  // src/parser.ts
167
177
  var isNodeRecipe = (node) => node.type === "recipe";
178
+ var cvaProps = ["compoundVariants", "defaultVariants", "variants", "base"];
179
+ var isCva = (map) => cvaProps.some((prop) => map.has(prop));
168
180
  function createImportMatcher(mod, values) {
169
181
  const regex = values ? new RegExp(`^(${values.join("|")})$`) : /.*/;
170
182
  return {
@@ -178,10 +190,10 @@ function createImportMatcher(mod, values) {
178
190
  var combineResult = (unboxed) => {
179
191
  return [...unboxed.conditions, unboxed.raw, ...unboxed.spreadConditions];
180
192
  };
181
- var fallback = (box) => ({
193
+ var fallback = (box2) => ({
182
194
  value: void 0,
183
- getNode: () => box.getNode(),
184
- getStack: () => box.getStack()
195
+ getNode: () => box2.getNode(),
196
+ getStack: () => box2.getStack()
185
197
  });
186
198
  var defaultEnv = { preset: "NONE" };
187
199
  function createParser(options) {
@@ -194,7 +206,7 @@ function createParser(options) {
194
206
  if (jsx) {
195
207
  importRegex.push(createImportMatcher(importMap.jsx, [jsx.factory, ...jsx.nodes.map((node) => node.name)]));
196
208
  }
197
- return function parse(sourceFile) {
209
+ return function parse3(sourceFile) {
198
210
  if (!sourceFile)
199
211
  return;
200
212
  const filePath = sourceFile.getFilePath();
@@ -212,6 +224,7 @@ function createParser(options) {
212
224
  const isValidPattern = imports.createMatch(importMap.pattern);
213
225
  const isValidRecipe = imports.createMatch(importMap.recipe);
214
226
  const isValidStyleFn = (name) => name === jsx?.factory;
227
+ const isFactory = (name) => jsx && name.startsWith(jsx.factory);
215
228
  const jsxFactoryAlias = jsx ? imports.getAlias(jsx.factory) : "panda";
216
229
  const jsxPatternNodes = new RegExp(
217
230
  `^(${jsx?.nodes.map((node) => node.type === "pattern" && node.name).join("|")})$`
@@ -299,6 +312,9 @@ function createParser(options) {
299
312
  return true;
300
313
  }
301
314
  },
315
+ taggedTemplates: {
316
+ matchTaggedTemplate: (tag) => matchFn(tag.fnName)
317
+ },
302
318
  getEvaluateOptions: (node) => ({ node, environment: defaultEnv }),
303
319
  flags: { skipTraverseFiles: true }
304
320
  });
@@ -309,35 +325,86 @@ function createParser(options) {
309
325
  if (result.kind === "function") {
310
326
  (0, import_ts_pattern.match)(name).when(css.match, (name2) => {
311
327
  result.queryList.forEach((query) => {
312
- collector.set(name2, {
313
- name: name2,
314
- box: query.box.value[0] ?? fallback(query.box),
315
- data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
316
- });
328
+ if (query.kind === "call-expression") {
329
+ collector.set(name2, {
330
+ name: name2,
331
+ box: query.box.value[0] ?? fallback(query.box),
332
+ data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
333
+ });
334
+ } else if (query.kind === "tagged-template") {
335
+ const obj = (0, import_shared2.astish)(query.box.value);
336
+ collector.set(name2, {
337
+ name: name2,
338
+ box: query.box ?? fallback(query.box),
339
+ data: [obj]
340
+ });
341
+ }
317
342
  });
318
343
  }).when(isValidPattern, (name2) => {
319
344
  result.queryList.forEach((query) => {
320
- collector.setPattern(name2, {
321
- name: name2,
322
- box: query.box.value[0] ?? fallback(query.box),
323
- data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
324
- });
345
+ if (query.kind === "call-expression") {
346
+ collector.setPattern(name2, {
347
+ name: name2,
348
+ box: query.box.value[0] ?? fallback(query.box),
349
+ data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
350
+ });
351
+ }
325
352
  });
326
353
  }).when(isValidRecipe, (name2) => {
327
354
  result.queryList.forEach((query) => {
328
- collector.setRecipe(name2, {
329
- name: name2,
330
- box: query.box.value[0] ?? fallback(query.box),
331
- data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
332
- });
355
+ if (query.kind === "call-expression") {
356
+ collector.setRecipe(name2, {
357
+ name: name2,
358
+ box: query.box.value[0] ?? fallback(query.box),
359
+ data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
360
+ });
361
+ }
333
362
  });
334
363
  }).when(isValidStyleFn, () => {
335
364
  result.queryList.forEach((query) => {
336
- collector.setCva({
337
- name,
338
- box: query.box.value[1] ?? fallback(query.box),
339
- data: combineResult((0, import_extractor.unbox)(query.box.value[1]))
340
- });
365
+ if (query.kind === "call-expression" && query.box.value[1]) {
366
+ const map = query.box.value[1];
367
+ const result2 = {
368
+ name,
369
+ box: map ?? fallback(query.box),
370
+ data: combineResult((0, import_extractor.unbox)(map))
371
+ };
372
+ if (import_extractor.box.isMap(map) && isCva(map.value)) {
373
+ collector.setCva(result2);
374
+ } else {
375
+ collector.set("css", result2);
376
+ }
377
+ } else if (query.kind === "tagged-template") {
378
+ const obj = (0, import_shared2.astish)(query.box.value);
379
+ collector.set("css", {
380
+ name,
381
+ box: query.box ?? fallback(query.box),
382
+ data: [obj]
383
+ });
384
+ }
385
+ });
386
+ }).when(isFactory, (name2) => {
387
+ result.queryList.forEach((query) => {
388
+ if (query.kind === "call-expression") {
389
+ const map = query.box.value[0];
390
+ const result2 = {
391
+ name: name2,
392
+ box: map ?? fallback(query.box),
393
+ data: combineResult((0, import_extractor.unbox)(map))
394
+ };
395
+ if (import_extractor.box.isMap(map) && isCva(map.value)) {
396
+ collector.setCva(result2);
397
+ } else {
398
+ collector.set("css", result2);
399
+ }
400
+ } else if (query.kind === "tagged-template") {
401
+ const obj = (0, import_shared2.astish)(query.box.value);
402
+ collector.set("css", {
403
+ name: name2,
404
+ box: query.box ?? fallback(query.box),
405
+ data: [obj]
406
+ });
407
+ }
341
408
  });
342
409
  }).otherwise(() => {
343
410
  });
@@ -371,6 +438,88 @@ function createParser(options) {
371
438
  }
372
439
  var isUpperCase = (value) => value[0] === value[0]?.toUpperCase();
373
440
 
441
+ // src/vue-to-tsx.ts
442
+ var import_compiler_sfc = require("@vue/compiler-sfc");
443
+ var import_magic_string = __toESM(require("magic-string"));
444
+ var NodeTypes = {
445
+ ROOT: 0,
446
+ ELEMENT: 1,
447
+ TEXT: 2,
448
+ COMMENT: 3,
449
+ SIMPLE_EXPRESSION: 4,
450
+ INTERPOLATION: 5,
451
+ ATTRIBUTE: 6,
452
+ DIRECTIVE: 7,
453
+ COMPOUND_EXPRESSION: 8,
454
+ IF: 9,
455
+ IF_BRANCH: 10,
456
+ FOR: 11,
457
+ TEXT_CALL: 12,
458
+ VNODE_CALL: 13,
459
+ JS_CALL_EXPRESSION: 14,
460
+ JS_OBJECT_EXPRESSION: 15,
461
+ JS_PROPERTY: 16,
462
+ JS_ARRAY_EXPRESSION: 17,
463
+ JS_FUNCTION_EXPRESSION: 18,
464
+ JS_CONDITIONAL_EXPRESSION: 19,
465
+ JS_CACHE_EXPRESSION: 20,
466
+ JS_BLOCK_STATEMENT: 21,
467
+ JS_TEMPLATE_LITERAL: 22,
468
+ JS_IF_STATEMENT: 23,
469
+ JS_ASSIGNMENT_EXPRESSION: 24,
470
+ JS_SEQUENCE_EXPRESSION: 25,
471
+ JS_RETURN_STATEMENT: 26
472
+ };
473
+ var vueToTsx = (code) => {
474
+ try {
475
+ const parsed = (0, import_compiler_sfc.parse)(code);
476
+ const fileStr = new import_magic_string.default(code);
477
+ parsed.descriptor.template.ast.children.forEach((node) => {
478
+ if (node.type === NodeTypes.ELEMENT) {
479
+ node.props.forEach((prop) => {
480
+ if (prop.type === NodeTypes.DIRECTIVE && prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION) {
481
+ fileStr.update(prop.loc.start.offset, prop.loc.end.offset, `${prop.arg.content}={${prop.exp.content}}`);
482
+ }
483
+ });
484
+ }
485
+ });
486
+ const templateStart = code.indexOf("<template");
487
+ const templateEnd = code.indexOf("</template>") + "</template>".length;
488
+ const scriptContent = (parsed.descriptor.scriptSetup ?? parsed.descriptor.script)?.content + "\n";
489
+ const transformed = new import_magic_string.default(
490
+ `${scriptContent}
491
+ const render = ${fileStr.snip(templateStart, templateEnd).toString()}`
492
+ );
493
+ return transformed.toString();
494
+ } catch (err) {
495
+ return "";
496
+ }
497
+ };
498
+
499
+ // src/svelte-to-tsx.ts
500
+ var svelte = __toESM(require("svelte/compiler"));
501
+ var import_magic_string2 = __toESM(require("magic-string"));
502
+ var svelteToTsx = (code) => {
503
+ try {
504
+ const parsed = svelte.parse(code);
505
+ const fileStr = new import_magic_string2.default(code);
506
+ if (parsed.instance && parsed.instance.content) {
507
+ const content = parsed.instance.content;
508
+ fileStr.update(parsed.instance.start, parsed.instance.end, code.slice(content.start, content.end));
509
+ }
510
+ const moduleContext = parsed.module ? fileStr.snip(parsed.module.start, parsed.module.end) : "";
511
+ const scriptContent = parsed.instance ? fileStr.snip(parsed.instance.start, parsed.instance.end) : "";
512
+ const templateContent = parsed.html.children?.map((child) => fileStr.snip(child.start, child.end)).join("").trimStart() ?? "";
513
+ const transformed = new import_magic_string2.default(
514
+ `${moduleContext + "\n"}${scriptContent + "\n"}
515
+ const render = <div>${templateContent}</div>`
516
+ );
517
+ return transformed.toString().trim();
518
+ } catch (err) {
519
+ return "";
520
+ }
521
+ };
522
+
374
523
  // src/project.ts
375
524
  var createTsProject = (options) => new import_ts_morph2.Project({
376
525
  skipAddingFilesFromTsConfig: true,
@@ -416,6 +565,10 @@ var createProject = ({ getFiles, readFile, parserOptions, hooks, ...projectOptio
416
565
  if (!sourceFile)
417
566
  return;
418
567
  const content = sourceFile.getText();
568
+ const transformed = transformFile(filePath, content);
569
+ if (content !== transformed) {
570
+ sourceFile.replaceWithText(transformed);
571
+ }
419
572
  hooks.callHook("parser:before", filePath, content);
420
573
  const result = parser(sourceFile)?.setFilePath(filePath);
421
574
  hooks.callHook("parser:after", filePath, result);
@@ -440,6 +593,15 @@ var createProject = ({ getFiles, readFile, parserOptions, hooks, ...projectOptio
440
593
  })),
441
594
  import_lil_fp.Obj.omit(["project", "parser"])
442
595
  );
596
+ var transformFile = (filePath, content) => {
597
+ if (filePath.endsWith(".vue")) {
598
+ return vueToTsx(content);
599
+ }
600
+ if (filePath.endsWith(".svelte")) {
601
+ return svelteToTsx(content);
602
+ }
603
+ return content;
604
+ };
443
605
  // Annotate the CommonJS export names for ESM import in node:
444
606
  0 && (module.exports = {
445
607
  ParserResult,
package/dist/index.mjs CHANGED
@@ -3,9 +3,9 @@ import { Obj, pipe, tap } from "lil-fp";
3
3
  import { Project as TsProject, ScriptKind } from "ts-morph";
4
4
 
5
5
  // src/parser.ts
6
- import { extract, unbox } from "@pandacss/extractor";
6
+ import { extract, unbox, box } from "@pandacss/extractor";
7
7
  import { logger } from "@pandacss/logger";
8
- import { memo as memo2 } from "@pandacss/shared";
8
+ import { astish, memo as memo2 } from "@pandacss/shared";
9
9
  import { Node } from "ts-morph";
10
10
  import { match } from "ts-pattern";
11
11
 
@@ -59,7 +59,7 @@ function getImportDeclarations(file, options) {
59
59
  }
60
60
 
61
61
  // src/parser-result.ts
62
- var ParserResult = class {
62
+ var ParserResult = class _ParserResult {
63
63
  jsx = /* @__PURE__ */ new Set();
64
64
  css = /* @__PURE__ */ new Set();
65
65
  cva = /* @__PURE__ */ new Set();
@@ -124,7 +124,7 @@ var ParserResult = class {
124
124
  }
125
125
  static fromJSON(json) {
126
126
  const data = JSON.parse(json);
127
- const result = new ParserResult();
127
+ const result = new _ParserResult();
128
128
  result.css = new Set(data.css);
129
129
  result.cva = new Set(data.cva);
130
130
  result.recipe = new Map(Object.entries(data.recipe));
@@ -137,6 +137,8 @@ var createParserResult = () => new ParserResult();
137
137
 
138
138
  // src/parser.ts
139
139
  var isNodeRecipe = (node) => node.type === "recipe";
140
+ var cvaProps = ["compoundVariants", "defaultVariants", "variants", "base"];
141
+ var isCva = (map) => cvaProps.some((prop) => map.has(prop));
140
142
  function createImportMatcher(mod, values) {
141
143
  const regex = values ? new RegExp(`^(${values.join("|")})$`) : /.*/;
142
144
  return {
@@ -150,10 +152,10 @@ function createImportMatcher(mod, values) {
150
152
  var combineResult = (unboxed) => {
151
153
  return [...unboxed.conditions, unboxed.raw, ...unboxed.spreadConditions];
152
154
  };
153
- var fallback = (box) => ({
155
+ var fallback = (box2) => ({
154
156
  value: void 0,
155
- getNode: () => box.getNode(),
156
- getStack: () => box.getStack()
157
+ getNode: () => box2.getNode(),
158
+ getStack: () => box2.getStack()
157
159
  });
158
160
  var defaultEnv = { preset: "NONE" };
159
161
  function createParser(options) {
@@ -166,7 +168,7 @@ function createParser(options) {
166
168
  if (jsx) {
167
169
  importRegex.push(createImportMatcher(importMap.jsx, [jsx.factory, ...jsx.nodes.map((node) => node.name)]));
168
170
  }
169
- return function parse(sourceFile) {
171
+ return function parse3(sourceFile) {
170
172
  if (!sourceFile)
171
173
  return;
172
174
  const filePath = sourceFile.getFilePath();
@@ -184,6 +186,7 @@ function createParser(options) {
184
186
  const isValidPattern = imports.createMatch(importMap.pattern);
185
187
  const isValidRecipe = imports.createMatch(importMap.recipe);
186
188
  const isValidStyleFn = (name) => name === jsx?.factory;
189
+ const isFactory = (name) => jsx && name.startsWith(jsx.factory);
187
190
  const jsxFactoryAlias = jsx ? imports.getAlias(jsx.factory) : "panda";
188
191
  const jsxPatternNodes = new RegExp(
189
192
  `^(${jsx?.nodes.map((node) => node.type === "pattern" && node.name).join("|")})$`
@@ -271,6 +274,9 @@ function createParser(options) {
271
274
  return true;
272
275
  }
273
276
  },
277
+ taggedTemplates: {
278
+ matchTaggedTemplate: (tag) => matchFn(tag.fnName)
279
+ },
274
280
  getEvaluateOptions: (node) => ({ node, environment: defaultEnv }),
275
281
  flags: { skipTraverseFiles: true }
276
282
  });
@@ -281,35 +287,86 @@ function createParser(options) {
281
287
  if (result.kind === "function") {
282
288
  match(name).when(css.match, (name2) => {
283
289
  result.queryList.forEach((query) => {
284
- collector.set(name2, {
285
- name: name2,
286
- box: query.box.value[0] ?? fallback(query.box),
287
- data: combineResult(unbox(query.box.value[0]))
288
- });
290
+ if (query.kind === "call-expression") {
291
+ collector.set(name2, {
292
+ name: name2,
293
+ box: query.box.value[0] ?? fallback(query.box),
294
+ data: combineResult(unbox(query.box.value[0]))
295
+ });
296
+ } else if (query.kind === "tagged-template") {
297
+ const obj = astish(query.box.value);
298
+ collector.set(name2, {
299
+ name: name2,
300
+ box: query.box ?? fallback(query.box),
301
+ data: [obj]
302
+ });
303
+ }
289
304
  });
290
305
  }).when(isValidPattern, (name2) => {
291
306
  result.queryList.forEach((query) => {
292
- collector.setPattern(name2, {
293
- name: name2,
294
- box: query.box.value[0] ?? fallback(query.box),
295
- data: combineResult(unbox(query.box.value[0]))
296
- });
307
+ if (query.kind === "call-expression") {
308
+ collector.setPattern(name2, {
309
+ name: name2,
310
+ box: query.box.value[0] ?? fallback(query.box),
311
+ data: combineResult(unbox(query.box.value[0]))
312
+ });
313
+ }
297
314
  });
298
315
  }).when(isValidRecipe, (name2) => {
299
316
  result.queryList.forEach((query) => {
300
- collector.setRecipe(name2, {
301
- name: name2,
302
- box: query.box.value[0] ?? fallback(query.box),
303
- data: combineResult(unbox(query.box.value[0]))
304
- });
317
+ if (query.kind === "call-expression") {
318
+ collector.setRecipe(name2, {
319
+ name: name2,
320
+ box: query.box.value[0] ?? fallback(query.box),
321
+ data: combineResult(unbox(query.box.value[0]))
322
+ });
323
+ }
305
324
  });
306
325
  }).when(isValidStyleFn, () => {
307
326
  result.queryList.forEach((query) => {
308
- collector.setCva({
309
- name,
310
- box: query.box.value[1] ?? fallback(query.box),
311
- data: combineResult(unbox(query.box.value[1]))
312
- });
327
+ if (query.kind === "call-expression" && query.box.value[1]) {
328
+ const map = query.box.value[1];
329
+ const result2 = {
330
+ name,
331
+ box: map ?? fallback(query.box),
332
+ data: combineResult(unbox(map))
333
+ };
334
+ if (box.isMap(map) && isCva(map.value)) {
335
+ collector.setCva(result2);
336
+ } else {
337
+ collector.set("css", result2);
338
+ }
339
+ } else if (query.kind === "tagged-template") {
340
+ const obj = astish(query.box.value);
341
+ collector.set("css", {
342
+ name,
343
+ box: query.box ?? fallback(query.box),
344
+ data: [obj]
345
+ });
346
+ }
347
+ });
348
+ }).when(isFactory, (name2) => {
349
+ result.queryList.forEach((query) => {
350
+ if (query.kind === "call-expression") {
351
+ const map = query.box.value[0];
352
+ const result2 = {
353
+ name: name2,
354
+ box: map ?? fallback(query.box),
355
+ data: combineResult(unbox(map))
356
+ };
357
+ if (box.isMap(map) && isCva(map.value)) {
358
+ collector.setCva(result2);
359
+ } else {
360
+ collector.set("css", result2);
361
+ }
362
+ } else if (query.kind === "tagged-template") {
363
+ const obj = astish(query.box.value);
364
+ collector.set("css", {
365
+ name: name2,
366
+ box: query.box ?? fallback(query.box),
367
+ data: [obj]
368
+ });
369
+ }
313
370
  });
314
371
  }).otherwise(() => {
315
372
  });
@@ -343,6 +400,88 @@ function createParser(options) {
343
400
  }
344
401
  var isUpperCase = (value) => value[0] === value[0]?.toUpperCase();
345
402
 
403
+ // src/vue-to-tsx.ts
404
+ import { parse } from "@vue/compiler-sfc";
405
+ import MagicString from "magic-string";
406
+ var NodeTypes = {
407
+ ROOT: 0,
408
+ ELEMENT: 1,
409
+ TEXT: 2,
410
+ COMMENT: 3,
411
+ SIMPLE_EXPRESSION: 4,
412
+ INTERPOLATION: 5,
413
+ ATTRIBUTE: 6,
414
+ DIRECTIVE: 7,
415
+ COMPOUND_EXPRESSION: 8,
416
+ IF: 9,
417
+ IF_BRANCH: 10,
418
+ FOR: 11,
419
+ TEXT_CALL: 12,
420
+ VNODE_CALL: 13,
421
+ JS_CALL_EXPRESSION: 14,
422
+ JS_OBJECT_EXPRESSION: 15,
423
+ JS_PROPERTY: 16,
424
+ JS_ARRAY_EXPRESSION: 17,
425
+ JS_FUNCTION_EXPRESSION: 18,
426
+ JS_CONDITIONAL_EXPRESSION: 19,
427
+ JS_CACHE_EXPRESSION: 20,
428
+ JS_BLOCK_STATEMENT: 21,
429
+ JS_TEMPLATE_LITERAL: 22,
430
+ JS_IF_STATEMENT: 23,
431
+ JS_ASSIGNMENT_EXPRESSION: 24,
432
+ JS_SEQUENCE_EXPRESSION: 25,
433
+ JS_RETURN_STATEMENT: 26
434
+ };
435
+ var vueToTsx = (code) => {
436
+ try {
437
+ const parsed = parse(code);
438
+ const fileStr = new MagicString(code);
439
+ parsed.descriptor.template.ast.children.forEach((node) => {
440
+ if (node.type === NodeTypes.ELEMENT) {
441
+ node.props.forEach((prop) => {
442
+ if (prop.type === NodeTypes.DIRECTIVE && prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION) {
443
+ fileStr.update(prop.loc.start.offset, prop.loc.end.offset, `${prop.arg.content}={${prop.exp.content}}`);
444
+ }
445
+ });
446
+ }
447
+ });
448
+ const templateStart = code.indexOf("<template");
449
+ const templateEnd = code.indexOf("</template>") + "</template>".length;
450
+ const scriptContent = (parsed.descriptor.scriptSetup ?? parsed.descriptor.script)?.content + "\n";
451
+ const transformed = new MagicString(
452
+ `${scriptContent}
453
+ const render = ${fileStr.snip(templateStart, templateEnd).toString()}`
454
+ );
455
+ return transformed.toString();
456
+ } catch (err) {
457
+ return "";
458
+ }
459
+ };
460
+
461
+ // src/svelte-to-tsx.ts
462
+ import * as svelte from "svelte/compiler";
463
+ import MagicString2 from "magic-string";
464
+ var svelteToTsx = (code) => {
465
+ try {
466
+ const parsed = svelte.parse(code);
467
+ const fileStr = new MagicString2(code);
468
+ if (parsed.instance && parsed.instance.content) {
469
+ const content = parsed.instance.content;
470
+ fileStr.update(parsed.instance.start, parsed.instance.end, code.slice(content.start, content.end));
471
+ }
472
+ const moduleContext = parsed.module ? fileStr.snip(parsed.module.start, parsed.module.end) : "";
473
+ const scriptContent = parsed.instance ? fileStr.snip(parsed.instance.start, parsed.instance.end) : "";
474
+ const templateContent = parsed.html.children?.map((child) => fileStr.snip(child.start, child.end)).join("").trimStart() ?? "";
475
+ const transformed = new MagicString2(
476
+ `${moduleContext + "\n"}${scriptContent + "\n"}
477
+ const render = <div>${templateContent}</div>`
478
+ );
479
+ return transformed.toString().trim();
480
+ } catch (err) {
481
+ return "";
482
+ }
483
+ };
484
+
346
485
  // src/project.ts
347
486
  var createTsProject = (options) => new TsProject({
348
487
  skipAddingFilesFromTsConfig: true,
@@ -388,6 +527,10 @@ var createProject = ({ getFiles, readFile, parserOptions, hooks, ...projectOptio
388
527
  if (!sourceFile)
389
528
  return;
390
529
  const content = sourceFile.getText();
530
+ const transformed = transformFile(filePath, content);
531
+ if (content !== transformed) {
532
+ sourceFile.replaceWithText(transformed);
533
+ }
391
534
  hooks.callHook("parser:before", filePath, content);
392
535
  const result = parser(sourceFile)?.setFilePath(filePath);
393
536
  hooks.callHook("parser:after", filePath, result);
@@ -412,6 +555,15 @@ var createProject = ({ getFiles, readFile, parserOptions, hooks, ...projectOptio
412
555
  })),
413
556
  Obj.omit(["project", "parser"])
414
557
  );
558
+ var transformFile = (filePath, content) => {
559
+ if (filePath.endsWith(".vue")) {
560
+ return vueToTsx(content);
561
+ }
562
+ if (filePath.endsWith(".svelte")) {
563
+ return svelteToTsx(content);
564
+ }
565
+ return content;
566
+ };
415
567
  export {
416
568
  ParserResult,
417
569
  createParserResult,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandacss/parser",
3
- "version": "0.3.2",
3
+ "version": "0.5.0",
4
4
  "description": "The static parser for panda css",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -11,19 +11,22 @@
11
11
  "access": "public"
12
12
  },
13
13
  "dependencies": {
14
+ "@vue/compiler-sfc": "^3.3.4",
14
15
  "lil-fp": "1.4.5",
16
+ "magic-string": "^0.30.0",
17
+ "svelte": "^4.0.0",
15
18
  "ts-morph": "18.0.0",
16
19
  "ts-pattern": "4.3.0",
17
- "@pandacss/extractor": "0.3.2",
18
- "@pandacss/is-valid-prop": "0.3.2",
19
- "@pandacss/logger": "0.3.2",
20
- "@pandacss/shared": "0.3.2",
21
- "@pandacss/types": "0.3.2"
20
+ "@pandacss/extractor": "0.5.0",
21
+ "@pandacss/is-valid-prop": "0.5.0",
22
+ "@pandacss/logger": "0.5.0",
23
+ "@pandacss/shared": "0.5.0",
24
+ "@pandacss/types": "0.5.0"
22
25
  },
23
26
  "devDependencies": {
24
27
  "hookable": "5.5.3",
25
- "@pandacss/fixture": "0.3.2",
26
- "@pandacss/generator": "0.3.2"
28
+ "@pandacss/fixture": "0.5.0",
29
+ "@pandacss/generator": "0.5.0"
27
30
  },
28
31
  "files": [
29
32
  "dist"