@pandacss/parser 0.0.0-dev-20230413133612 → 0.0.0-dev-20230413135202

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -16,7 +16,6 @@ type ParserOptions = {
16
16
  isStyleProp: (prop: string) => boolean;
17
17
  };
18
18
  };
19
- type ParserMode = 'box-extractor' | 'internal';
20
19
 
21
20
  type ProjectOptions = Partial<ProjectOptions$1> & {
22
21
  readFile: (filePath: string) => string;
@@ -27,10 +26,10 @@ declare const createProject: ({ getFiles, readFile, parserOptions, ...projectOpt
27
26
  getSourceFile: (filePath: string) => ts_morph.SourceFile | undefined;
28
27
  removeSourceFile: (filePath: string) => void;
29
28
  createSourceFile: (filePath: string) => ts_morph.SourceFile;
30
- parseSourceFile: (filePath: string, properties: string[], mode?: ParserMode) => _pandacss_types.ParserResult | undefined;
29
+ parseSourceFile: (filePath: string, properties: string[]) => _pandacss_types.ParserResult | undefined;
31
30
  reloadSourceFile: (filePath: string) => ts_morph.FileSystemRefreshResult | undefined;
32
31
  reloadSourceFiles: () => void;
33
32
  };
34
33
  type Project = ReturnType<typeof createProject>;
35
34
 
36
- export { ParserMode, Project, ProjectOptions, createProject };
35
+ export { Project, ProjectOptions, createProject };
package/dist/index.js CHANGED
@@ -26,124 +26,19 @@ module.exports = __toCommonJS(src_exports);
26
26
 
27
27
  // src/project.ts
28
28
  var import_lil_fp = require("lil-fp");
29
- var import_ts_morph5 = require("ts-morph");
29
+ var import_ts_morph2 = require("ts-morph");
30
30
 
31
31
  // src/parser.ts
32
32
  var import_extractor = require("@pandacss/extractor");
33
33
  var import_logger = require("@pandacss/logger");
34
34
  var import_shared2 = require("@pandacss/shared");
35
- var import_ts_morph4 = require("ts-morph");
36
- var import_ts_pattern3 = require("ts-pattern");
37
-
38
- // src/call-expression.ts
39
- var import_ts_morph2 = require("ts-morph");
40
-
41
- // src/literal.ts
42
35
  var import_ts_morph = require("ts-morph");
43
36
  var import_ts_pattern = require("ts-pattern");
44
37
 
45
- // src/strip-quotes.ts
46
- function stripQuotes(q) {
47
- const quoteStart = `'|"|\u2018|\u201C|\u2039|\xAB`;
48
- const quoteEnd = `'|"|\u2019|\u201D|\u203A|\xBB`;
49
- if (typeof q !== "string")
50
- throw new Error(`input was '${typeof q}' and not of type 'string'`);
51
- if (!q.length)
52
- throw new Error(`input was empty`);
53
- let s = q;
54
- let t = s.length;
55
- if (s.charAt(0).match(new RegExp(quoteStart))) {
56
- s = s.substring(1, t--);
57
- }
58
- if (s.charAt(--t).match(new RegExp(quoteEnd))) {
59
- s = s.substring(0, t);
60
- }
61
- return s;
62
- }
63
-
64
- // src/literal.ts
65
- function isPrimitiveLiteral(node) {
66
- return import_ts_morph.Node.isStringLiteral(node) || import_ts_morph.Node.isNumericLiteral(node) || import_ts_morph.Node.isTrueLiteral(node) || import_ts_morph.Node.isFalseLiteral(node);
67
- }
68
- function extractValue(value) {
69
- return (0, import_ts_pattern.match)(value).when(
70
- (node) => import_ts_morph.Node.isStringLiteral(node) || import_ts_morph.Node.isNoSubstitutionTemplateLiteral(node),
71
- (value2) => {
72
- return value2.getLiteralValue().replaceAll(/[\n\s]+/g, " ");
73
- }
74
- ).when(isPrimitiveLiteral, (value2) => {
75
- return value2.getLiteralValue();
76
- }).when(import_ts_morph.Node.isNullLiteral, () => {
77
- return null;
78
- }).when(import_ts_morph.Node.isObjectLiteralExpression, (value2) => {
79
- return extractObjectLiteral(value2);
80
- }).when(import_ts_morph.Node.isArrayLiteralExpression, (value2) => {
81
- return extractArrayLiteral(value2);
82
- }).otherwise(() => {
83
- return void 0;
84
- });
85
- }
86
- function extractObjectLiteral(node) {
87
- const data = {};
88
- const properties = node.getProperties();
89
- for (const property of properties) {
90
- if (import_ts_morph.Node.isPropertyAssignment(property)) {
91
- const key = stripQuotes(property.getName());
92
- const value = property.getInitializer();
93
- const returnValue = extractValue(value);
94
- if (returnValue !== void 0) {
95
- data[key] = returnValue;
96
- }
97
- }
98
- }
99
- return data;
100
- }
101
- function extractArrayLiteral(node) {
102
- const result = [];
103
- node.forEachChild((child) => {
104
- (0, import_ts_pattern.match)(child).when(isPrimitiveLiteral, (child2) => {
105
- result.push(child2.getLiteralValue());
106
- }).when(import_ts_morph.Node.isUndefinedKeyword, () => {
107
- result.push(void 0);
108
- }).when(import_ts_morph.Node.isNullLiteral, () => {
109
- result.push(null);
110
- }).when(import_ts_morph.Node.isObjectLiteralExpression, (child2) => {
111
- result.push(extractObjectLiteral(child2));
112
- }).when(import_ts_morph.Node.isArrayLiteralExpression, (child2) => {
113
- result.push(extractArrayLiteral(child2));
114
- }).otherwise(() => {
115
- });
116
- });
117
- return result;
118
- }
119
-
120
- // src/call-expression.ts
121
- function visitCallExpressions(file, options) {
122
- const { match: match4, fn } = options;
123
- const callExpressions = file.getDescendantsOfKind(import_ts_morph2.ts.SyntaxKind.CallExpression);
124
- for (const node of callExpressions) {
125
- const expr = node.getExpression();
126
- const name = expr.getText();
127
- if (!match4(name)) {
128
- continue;
129
- }
130
- const args = node.getArguments();
131
- if (args.length === 0) {
132
- fn({ name, data: {} });
133
- continue;
134
- }
135
- args.forEach((arg) => {
136
- if (import_ts_morph2.Node.isObjectLiteralExpression(arg)) {
137
- fn({ name, data: extractObjectLiteral(arg) });
138
- }
139
- });
140
- }
141
- }
142
-
143
38
  // src/import.ts
144
39
  var import_shared = require("@pandacss/shared");
145
40
  function getImportDeclarations(file, options) {
146
- const { match: match4 } = options;
41
+ const { match: match2 } = options;
147
42
  const result = [];
148
43
  file.getImportDeclarations().forEach((node) => {
149
44
  const source = node.getModuleSpecifierValue();
@@ -153,7 +48,7 @@ function getImportDeclarations(file, options) {
153
48
  specifiers.forEach((specifier) => {
154
49
  const name = specifier.getNameNode().getText();
155
50
  const alias = specifier.getAliasNode()?.getText() || name;
156
- if (!match4({ id: name, mod: source }))
51
+ if (!match2({ id: name, mod: source }))
157
52
  return;
158
53
  result.push({ name, alias, mod: source });
159
54
  });
@@ -182,49 +77,6 @@ function getImportDeclarations(file, options) {
182
77
  };
183
78
  }
184
79
 
185
- // src/jsx-element.ts
186
- var import_ts_morph3 = require("ts-morph");
187
- var import_ts_pattern2 = require("ts-pattern");
188
- function visitJsxElement(file, options) {
189
- const { match: matchProp, fn } = options;
190
- const elements = [
191
- ...file.getDescendantsOfKind(import_ts_morph3.ts.SyntaxKind.JsxOpeningElement),
192
- ...file.getDescendantsOfKind(import_ts_morph3.ts.SyntaxKind.JsxSelfClosingElement)
193
- ];
194
- for (const node of elements) {
195
- const tag = node.getTagNameNode().getText();
196
- if (!tag || !matchProp.tag(tag)) {
197
- continue;
198
- }
199
- const props = node.getAttributes();
200
- const data = {};
201
- for (const prop of props) {
202
- if (!import_ts_morph3.Node.isJsxAttribute(prop)) {
203
- continue;
204
- }
205
- const name = prop.getName();
206
- const value = prop.getInitializer();
207
- if (!tag || !matchProp.prop({ tag, name })) {
208
- continue;
209
- }
210
- (0, import_ts_pattern2.match)(value).when(import_ts_morph3.Node.isStringLiteral, (value2) => {
211
- data[name] = value2.getLiteralValue().replaceAll(/[\n\s]+/g, " ");
212
- }).when(import_ts_morph3.Node.isJsxExpression, (value2) => {
213
- const expr = value2.getExpression();
214
- const returnValue = extractValue(expr);
215
- if (returnValue !== void 0) {
216
- data[name] = returnValue;
217
- }
218
- }).otherwise(() => {
219
- if (!value) {
220
- data[name] = true;
221
- }
222
- });
223
- }
224
- fn({ name: tag, data });
225
- }
226
- }
227
-
228
80
  // src/parser-result.ts
229
81
  var createParserResult = () => ({
230
82
  jsx: /* @__PURE__ */ new Set(),
@@ -266,7 +118,7 @@ var combineResult = (unboxed) => {
266
118
  return [...unboxed.conditions, unboxed.raw, ...unboxed.spreadConditions];
267
119
  };
268
120
  function createParser(options) {
269
- return function parse(sourceFile, confProperties, mode = "internal") {
121
+ return function parse(sourceFile, confProperties) {
270
122
  if (!sourceFile)
271
123
  return;
272
124
  const filePath = sourceFile.getFilePath();
@@ -297,194 +149,145 @@ function createParser(options) {
297
149
  const jsxFactoryAlias = jsx ? imports.getAlias(jsx.factory) : "panda";
298
150
  const jsxPatternNodes = new RegExp(`(${jsx?.nodes.map((node) => node.type === "pattern" && node.name).join("|")})$`);
299
151
  const jsxRecipeNodes = new RegExp(`(${jsx?.nodes.map((node) => node.type === "recipe" && node.name).join("|")})$`);
300
- if (mode === "box-extractor") {
301
- const recipes = /* @__PURE__ */ new Map();
302
- imports.value.forEach((importDeclaration) => {
303
- const { name, alias } = importDeclaration;
304
- const isRecipe = isValidRecipe(name);
305
- if (isRecipe) {
306
- recipes.set(alias, true);
307
- }
308
- });
309
- const functions = /* @__PURE__ */ new Map();
310
- const components = /* @__PURE__ */ new Map();
311
- const propertiesMap = new Map(confProperties.map((prop) => [prop, true]));
312
- const cvaAlias = imports.getAlias("cva");
313
- const cssAlias = imports.getAlias("css");
314
- if (options.jsx) {
315
- options.jsx.nodes.forEach((node) => {
316
- const properties = node.props ? new Map(propertiesMap) : propertiesMap;
317
- const alias = imports.getAlias(node.name);
318
- node.props?.forEach((prop) => properties.set(prop, true));
319
- functions.set(node.baseName, properties);
320
- functions.set(alias, properties);
321
- components.set(alias, properties);
322
- });
152
+ const recipes = /* @__PURE__ */ new Map();
153
+ imports.value.forEach((importDeclaration) => {
154
+ const { name, alias } = importDeclaration;
155
+ const isRecipe = isValidRecipe(name);
156
+ if (isRecipe) {
157
+ recipes.set(alias, true);
323
158
  }
324
- const matchTag = (0, import_shared2.memo)((tagName) => {
325
- return components.has(tagName) || isUpperCase(tagName) || tagName.startsWith(jsxFactoryAlias);
326
- });
327
- const matchTagProp = (0, import_shared2.memo)((tagName, propName) => {
328
- if (propertiesMap.size === 0)
329
- return true;
330
- return Boolean(components.get(tagName)?.get(propName)) || propertiesMap.has(propName);
331
- });
332
- const matchFn = (0, import_shared2.memo)((fnName) => {
333
- if (recipes.has(fnName))
334
- return true;
335
- if (fnName === cvaAlias || fnName === cssAlias || fnName.startsWith(jsxFactoryAlias))
336
- return true;
337
- return Boolean(functions.get(fnName));
159
+ });
160
+ const functions = /* @__PURE__ */ new Map();
161
+ const components = /* @__PURE__ */ new Map();
162
+ const propertiesMap = new Map(confProperties.map((prop) => [prop, true]));
163
+ const cvaAlias = imports.getAlias("cva");
164
+ const cssAlias = imports.getAlias("css");
165
+ if (options.jsx) {
166
+ options.jsx.nodes.forEach((node) => {
167
+ const properties = node.props ? new Map(propertiesMap) : propertiesMap;
168
+ const alias = imports.getAlias(node.name);
169
+ node.props?.forEach((prop) => properties.set(prop, true));
170
+ functions.set(node.baseName, properties);
171
+ functions.set(alias, properties);
172
+ components.set(alias, properties);
338
173
  });
339
- const matchFnProp = (0, import_shared2.memo)((fnName, propName) => {
340
- if (propertiesMap.size === 0)
341
- return true;
342
- if (recipes.has(fnName))
343
- return true;
344
- if (fnName === cvaAlias)
345
- return true;
346
- if (fnName.startsWith(jsxFactoryAlias))
174
+ }
175
+ const matchTag = (0, import_shared2.memo)((tagName) => {
176
+ return components.has(tagName) || isUpperCase(tagName) || tagName.startsWith(jsxFactoryAlias);
177
+ });
178
+ const matchTagProp = (0, import_shared2.memo)((tagName, propName) => {
179
+ if (propertiesMap.size === 0)
180
+ return true;
181
+ return Boolean(components.get(tagName)?.get(propName)) || propertiesMap.has(propName);
182
+ });
183
+ const matchFn = (0, import_shared2.memo)((fnName) => {
184
+ if (recipes.has(fnName))
185
+ return true;
186
+ if (fnName === cvaAlias || fnName === cssAlias || fnName.startsWith(jsxFactoryAlias))
187
+ return true;
188
+ return Boolean(functions.get(fnName));
189
+ });
190
+ const matchFnProp = (0, import_shared2.memo)((fnName, propName) => {
191
+ if (propertiesMap.size === 0)
192
+ return true;
193
+ if (recipes.has(fnName))
194
+ return true;
195
+ if (fnName === cvaAlias)
196
+ return true;
197
+ if (fnName.startsWith(jsxFactoryAlias))
198
+ return true;
199
+ if (fnName === cssAlias)
200
+ return Boolean(propertiesMap.get(propName) || propName === "selectors");
201
+ return Boolean(functions.get(fnName)?.get(propName));
202
+ });
203
+ const measure = import_logger.logger.time.debug(`Tokens extracted from ${filePath}`);
204
+ const extractResultByName = (0, import_extractor.extract)({
205
+ ast: sourceFile,
206
+ components: {
207
+ matchTag: (prop) => matchTag(prop.tagName),
208
+ matchProp: (prop) => matchTagProp(prop.tagName, prop.propName)
209
+ },
210
+ functions: {
211
+ matchFn: (prop) => matchFn(prop.fnName),
212
+ matchProp: (prop) => matchFnProp(prop.fnName, prop.propName),
213
+ matchArg: (prop) => {
214
+ if (prop.fnName === jsxFactoryAlias && prop.index === 1 && import_ts_morph.Node.isIdentifier(prop.argNode))
215
+ return false;
347
216
  return true;
348
- if (fnName === cssAlias)
349
- return Boolean(propertiesMap.get(propName) || propName === "selectors");
350
- return Boolean(functions.get(fnName)?.get(propName));
351
- });
352
- const measure2 = import_logger.logger.time.debug(`Tokens extracted from ${filePath}`);
353
- const extractResultByName = (0, import_extractor.extract)({
354
- ast: sourceFile,
355
- components: {
356
- matchTag: (prop) => matchTag(prop.tagName),
357
- matchProp: (prop) => matchTagProp(prop.tagName, prop.propName)
358
- },
359
- functions: {
360
- matchFn: (prop) => matchFn(prop.fnName),
361
- matchProp: (prop) => matchFnProp(prop.fnName, prop.propName),
362
- matchArg: (prop) => {
363
- if (prop.fnName === jsxFactoryAlias && prop.index === 1 && import_ts_morph4.Node.isIdentifier(prop.argNode))
364
- return false;
365
- return true;
366
- }
367
- },
368
- flags: { skipTraverseFiles: true }
369
- });
370
- measure2();
371
- extractResultByName.forEach((result, alias) => {
372
- const name = imports.getName(alias);
373
- import_logger.logger.debug(`ast:${name}`, { filePath, result, alias });
374
- if (result.kind === "function") {
375
- (0, import_ts_pattern3.match)(name).when(css.match, (name2) => {
376
- result.queryList.forEach((query) => {
377
- collector.set(name2, {
378
- name: name2,
379
- box: query.box.value[0],
380
- data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
381
- });
382
- });
383
- }).when(isValidPattern, (name2) => {
384
- result.queryList.forEach((query) => {
385
- collector.setPattern(name2, {
386
- name: name2,
387
- box: query.box.value[0],
388
- data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
389
- });
217
+ }
218
+ },
219
+ flags: { skipTraverseFiles: true }
220
+ });
221
+ measure();
222
+ extractResultByName.forEach((result, alias) => {
223
+ const name = imports.getName(alias);
224
+ import_logger.logger.debug(`ast:${name}`, { filePath, result, alias });
225
+ if (result.kind === "function") {
226
+ (0, import_ts_pattern.match)(name).when(css.match, (name2) => {
227
+ result.queryList.forEach((query) => {
228
+ collector.set(name2, {
229
+ name: name2,
230
+ box: query.box.value[0],
231
+ data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
390
232
  });
391
- }).when(isValidRecipe, (name2) => {
392
- result.queryList.forEach((query) => {
393
- collector.setRecipe(name2, {
394
- name: name2,
395
- box: query.box.value[0],
396
- data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
397
- });
233
+ });
234
+ }).when(isValidPattern, (name2) => {
235
+ result.queryList.forEach((query) => {
236
+ collector.setPattern(name2, {
237
+ name: name2,
238
+ box: query.box.value[0],
239
+ data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
398
240
  });
399
- }).when(isValidStyleFn, () => {
400
- result.queryList.forEach((query) => {
401
- collector.setCva({
402
- name,
403
- box: query.box,
404
- data: combineResult((0, import_extractor.unbox)(query.box))
405
- });
241
+ });
242
+ }).when(isValidRecipe, (name2) => {
243
+ result.queryList.forEach((query) => {
244
+ collector.setRecipe(name2, {
245
+ name: name2,
246
+ box: query.box.value[0],
247
+ data: combineResult((0, import_extractor.unbox)(query.box.value[0]))
406
248
  });
407
- }).otherwise(() => {
408
249
  });
409
- } else if (result.kind === "component") {
250
+ }).when(isValidStyleFn, () => {
410
251
  result.queryList.forEach((query) => {
411
- let type;
412
- const data = combineResult((0, import_extractor.unbox)(query.box));
413
- import_logger.logger.debug(`ast:jsx:${name}`, { filePath, result: data });
414
- if (jsx && name.startsWith(jsxFactoryAlias)) {
415
- type = "jsx-factory";
416
- } else if (jsxPatternNodes.test(name)) {
417
- type = "pattern";
418
- } else if (jsxRecipeNodes.test(name)) {
419
- type = "recipe";
420
- } else {
421
- type = "jsx";
422
- }
423
- collector.jsx.add({
424
- // from "panda.*" -> "panda.button"
252
+ collector.setCva({
425
253
  name,
426
254
  box: query.box,
427
- type,
428
- data
255
+ data: combineResult((0, import_extractor.unbox)(query.box))
429
256
  });
430
257
  });
431
- }
432
- });
433
- return collector;
434
- }
435
- const measure = import_logger.logger.time.debug(`Tokens extracted & collected from ${filePath}`);
436
- visitCallExpressions(sourceFile, {
437
- match: (0, import_shared2.memo)((name) => imports.match(name)),
438
- fn({ name: _name, data }) {
439
- const name = imports.getName(_name);
440
- const [css2] = importRegex;
441
- const result = { name, data };
442
- import_logger.logger.debug(`ast:${name}`, { filePath, result });
443
- (0, import_ts_pattern3.match)(name).when(css2.match, (name2) => {
444
- collector.set(name2, result);
445
- }).when(isValidPattern, (name2) => {
446
- collector.setPattern(name2, result);
447
- }).when(isValidRecipe, (name2) => {
448
- collector.setRecipe(name2, result);
449
- }).when(isValidStyleFn, () => {
450
- collector.setCva(result);
451
258
  }).otherwise(() => {
452
259
  });
260
+ } else if (result.kind === "component") {
261
+ result.queryList.forEach((query) => {
262
+ let type;
263
+ const data = combineResult((0, import_extractor.unbox)(query.box));
264
+ import_logger.logger.debug(`ast:jsx:${name}`, { filePath, result: data });
265
+ if (jsx && name.startsWith(jsxFactoryAlias)) {
266
+ type = "jsx-factory";
267
+ } else if (jsxPatternNodes.test(name)) {
268
+ type = "pattern";
269
+ } else if (jsxRecipeNodes.test(name)) {
270
+ type = "recipe";
271
+ } else {
272
+ type = "jsx";
273
+ }
274
+ collector.jsx.add({
275
+ // from "panda.*" -> "panda.button"
276
+ name,
277
+ box: query.box,
278
+ type,
279
+ data
280
+ });
281
+ });
453
282
  }
454
283
  });
455
- visitJsxElement(sourceFile, {
456
- match: {
457
- tag: (0, import_shared2.memo)((name) => {
458
- return name.startsWith(jsxFactoryAlias) || isUpperCase(name);
459
- }),
460
- prop: ({ tag, name }) => {
461
- const node = jsx?.nodes.find((n) => n.name === tag);
462
- return !!jsx?.isStyleProp(name) || !!node?.props?.includes(name);
463
- }
464
- },
465
- fn({ name, data }) {
466
- let type;
467
- import_logger.logger.debug(`ast:jsx:${name}`, { filePath, result: data });
468
- if (jsx && name.startsWith(jsxFactoryAlias)) {
469
- type = "jsx-factory";
470
- } else if (jsxPatternNodes.test(name)) {
471
- type = "pattern";
472
- } else if (jsxRecipeNodes.test(name)) {
473
- type = "recipe";
474
- } else {
475
- type = "jsx";
476
- }
477
- collector.jsx.add({ type, name, data });
478
- }
479
- });
480
- measure();
481
284
  return collector;
482
285
  };
483
286
  }
484
287
  var isUpperCase = (value) => value[0] === value[0].toUpperCase();
485
288
 
486
289
  // src/project.ts
487
- var createTsProject = (options) => new import_ts_morph5.Project({
290
+ var createTsProject = (options) => new import_ts_morph2.Project({
488
291
  skipAddingFilesFromTsConfig: true,
489
292
  skipFileDependencyResolution: true,
490
293
  skipLoadingLibFiles: true,
@@ -510,10 +313,10 @@ var createProject = ({ getFiles, readFile, parserOptions, ...projectOptions }) =
510
313
  },
511
314
  createSourceFile: (filePath) => project.createSourceFile(filePath, readFile(filePath), {
512
315
  overwrite: true,
513
- scriptKind: import_ts_morph5.ScriptKind.TSX
316
+ scriptKind: import_ts_morph2.ScriptKind.TSX
514
317
  }),
515
- parseSourceFile: (filePath, properties, mode = "box-extractor") => {
516
- return parser(project.getSourceFile(filePath), properties, mode);
318
+ parseSourceFile: (filePath, properties) => {
319
+ return parser(project.getSourceFile(filePath), properties);
517
320
  }
518
321
  })),
519
322
  (0, import_lil_fp.tap)(({ createSourceFile }) => {
package/dist/index.mjs CHANGED
@@ -6,120 +6,13 @@ import { Project as TsProject, ScriptKind } from "ts-morph";
6
6
  import { extract, unbox } from "@pandacss/extractor";
7
7
  import { logger } from "@pandacss/logger";
8
8
  import { memo as memo2 } from "@pandacss/shared";
9
- import { Node as Node4 } from "ts-morph";
10
- import { match as match3 } from "ts-pattern";
11
-
12
- // src/call-expression.ts
13
- import { Node as Node2, ts } from "ts-morph";
14
-
15
- // src/literal.ts
16
- import {
17
- Node
18
- } from "ts-morph";
9
+ import { Node } from "ts-morph";
19
10
  import { match } from "ts-pattern";
20
11
 
21
- // src/strip-quotes.ts
22
- function stripQuotes(q) {
23
- const quoteStart = `'|"|\u2018|\u201C|\u2039|\xAB`;
24
- const quoteEnd = `'|"|\u2019|\u201D|\u203A|\xBB`;
25
- if (typeof q !== "string")
26
- throw new Error(`input was '${typeof q}' and not of type 'string'`);
27
- if (!q.length)
28
- throw new Error(`input was empty`);
29
- let s = q;
30
- let t = s.length;
31
- if (s.charAt(0).match(new RegExp(quoteStart))) {
32
- s = s.substring(1, t--);
33
- }
34
- if (s.charAt(--t).match(new RegExp(quoteEnd))) {
35
- s = s.substring(0, t);
36
- }
37
- return s;
38
- }
39
-
40
- // src/literal.ts
41
- function isPrimitiveLiteral(node) {
42
- return Node.isStringLiteral(node) || Node.isNumericLiteral(node) || Node.isTrueLiteral(node) || Node.isFalseLiteral(node);
43
- }
44
- function extractValue(value) {
45
- return match(value).when(
46
- (node) => Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node),
47
- (value2) => {
48
- return value2.getLiteralValue().replaceAll(/[\n\s]+/g, " ");
49
- }
50
- ).when(isPrimitiveLiteral, (value2) => {
51
- return value2.getLiteralValue();
52
- }).when(Node.isNullLiteral, () => {
53
- return null;
54
- }).when(Node.isObjectLiteralExpression, (value2) => {
55
- return extractObjectLiteral(value2);
56
- }).when(Node.isArrayLiteralExpression, (value2) => {
57
- return extractArrayLiteral(value2);
58
- }).otherwise(() => {
59
- return void 0;
60
- });
61
- }
62
- function extractObjectLiteral(node) {
63
- const data = {};
64
- const properties = node.getProperties();
65
- for (const property of properties) {
66
- if (Node.isPropertyAssignment(property)) {
67
- const key = stripQuotes(property.getName());
68
- const value = property.getInitializer();
69
- const returnValue = extractValue(value);
70
- if (returnValue !== void 0) {
71
- data[key] = returnValue;
72
- }
73
- }
74
- }
75
- return data;
76
- }
77
- function extractArrayLiteral(node) {
78
- const result = [];
79
- node.forEachChild((child) => {
80
- match(child).when(isPrimitiveLiteral, (child2) => {
81
- result.push(child2.getLiteralValue());
82
- }).when(Node.isUndefinedKeyword, () => {
83
- result.push(void 0);
84
- }).when(Node.isNullLiteral, () => {
85
- result.push(null);
86
- }).when(Node.isObjectLiteralExpression, (child2) => {
87
- result.push(extractObjectLiteral(child2));
88
- }).when(Node.isArrayLiteralExpression, (child2) => {
89
- result.push(extractArrayLiteral(child2));
90
- }).otherwise(() => {
91
- });
92
- });
93
- return result;
94
- }
95
-
96
- // src/call-expression.ts
97
- function visitCallExpressions(file, options) {
98
- const { match: match4, fn } = options;
99
- const callExpressions = file.getDescendantsOfKind(ts.SyntaxKind.CallExpression);
100
- for (const node of callExpressions) {
101
- const expr = node.getExpression();
102
- const name = expr.getText();
103
- if (!match4(name)) {
104
- continue;
105
- }
106
- const args = node.getArguments();
107
- if (args.length === 0) {
108
- fn({ name, data: {} });
109
- continue;
110
- }
111
- args.forEach((arg) => {
112
- if (Node2.isObjectLiteralExpression(arg)) {
113
- fn({ name, data: extractObjectLiteral(arg) });
114
- }
115
- });
116
- }
117
- }
118
-
119
12
  // src/import.ts
120
13
  import { memo } from "@pandacss/shared";
121
14
  function getImportDeclarations(file, options) {
122
- const { match: match4 } = options;
15
+ const { match: match2 } = options;
123
16
  const result = [];
124
17
  file.getImportDeclarations().forEach((node) => {
125
18
  const source = node.getModuleSpecifierValue();
@@ -129,7 +22,7 @@ function getImportDeclarations(file, options) {
129
22
  specifiers.forEach((specifier) => {
130
23
  const name = specifier.getNameNode().getText();
131
24
  const alias = specifier.getAliasNode()?.getText() || name;
132
- if (!match4({ id: name, mod: source }))
25
+ if (!match2({ id: name, mod: source }))
133
26
  return;
134
27
  result.push({ name, alias, mod: source });
135
28
  });
@@ -158,49 +51,6 @@ function getImportDeclarations(file, options) {
158
51
  };
159
52
  }
160
53
 
161
- // src/jsx-element.ts
162
- import { Node as Node3, ts as ts2 } from "ts-morph";
163
- import { match as match2 } from "ts-pattern";
164
- function visitJsxElement(file, options) {
165
- const { match: matchProp, fn } = options;
166
- const elements = [
167
- ...file.getDescendantsOfKind(ts2.SyntaxKind.JsxOpeningElement),
168
- ...file.getDescendantsOfKind(ts2.SyntaxKind.JsxSelfClosingElement)
169
- ];
170
- for (const node of elements) {
171
- const tag = node.getTagNameNode().getText();
172
- if (!tag || !matchProp.tag(tag)) {
173
- continue;
174
- }
175
- const props = node.getAttributes();
176
- const data = {};
177
- for (const prop of props) {
178
- if (!Node3.isJsxAttribute(prop)) {
179
- continue;
180
- }
181
- const name = prop.getName();
182
- const value = prop.getInitializer();
183
- if (!tag || !matchProp.prop({ tag, name })) {
184
- continue;
185
- }
186
- match2(value).when(Node3.isStringLiteral, (value2) => {
187
- data[name] = value2.getLiteralValue().replaceAll(/[\n\s]+/g, " ");
188
- }).when(Node3.isJsxExpression, (value2) => {
189
- const expr = value2.getExpression();
190
- const returnValue = extractValue(expr);
191
- if (returnValue !== void 0) {
192
- data[name] = returnValue;
193
- }
194
- }).otherwise(() => {
195
- if (!value) {
196
- data[name] = true;
197
- }
198
- });
199
- }
200
- fn({ name: tag, data });
201
- }
202
- }
203
-
204
54
  // src/parser-result.ts
205
55
  var createParserResult = () => ({
206
56
  jsx: /* @__PURE__ */ new Set(),
@@ -242,7 +92,7 @@ var combineResult = (unboxed) => {
242
92
  return [...unboxed.conditions, unboxed.raw, ...unboxed.spreadConditions];
243
93
  };
244
94
  function createParser(options) {
245
- return function parse(sourceFile, confProperties, mode = "internal") {
95
+ return function parse(sourceFile, confProperties) {
246
96
  if (!sourceFile)
247
97
  return;
248
98
  const filePath = sourceFile.getFilePath();
@@ -273,187 +123,138 @@ function createParser(options) {
273
123
  const jsxFactoryAlias = jsx ? imports.getAlias(jsx.factory) : "panda";
274
124
  const jsxPatternNodes = new RegExp(`(${jsx?.nodes.map((node) => node.type === "pattern" && node.name).join("|")})$`);
275
125
  const jsxRecipeNodes = new RegExp(`(${jsx?.nodes.map((node) => node.type === "recipe" && node.name).join("|")})$`);
276
- if (mode === "box-extractor") {
277
- const recipes = /* @__PURE__ */ new Map();
278
- imports.value.forEach((importDeclaration) => {
279
- const { name, alias } = importDeclaration;
280
- const isRecipe = isValidRecipe(name);
281
- if (isRecipe) {
282
- recipes.set(alias, true);
283
- }
284
- });
285
- const functions = /* @__PURE__ */ new Map();
286
- const components = /* @__PURE__ */ new Map();
287
- const propertiesMap = new Map(confProperties.map((prop) => [prop, true]));
288
- const cvaAlias = imports.getAlias("cva");
289
- const cssAlias = imports.getAlias("css");
290
- if (options.jsx) {
291
- options.jsx.nodes.forEach((node) => {
292
- const properties = node.props ? new Map(propertiesMap) : propertiesMap;
293
- const alias = imports.getAlias(node.name);
294
- node.props?.forEach((prop) => properties.set(prop, true));
295
- functions.set(node.baseName, properties);
296
- functions.set(alias, properties);
297
- components.set(alias, properties);
298
- });
126
+ const recipes = /* @__PURE__ */ new Map();
127
+ imports.value.forEach((importDeclaration) => {
128
+ const { name, alias } = importDeclaration;
129
+ const isRecipe = isValidRecipe(name);
130
+ if (isRecipe) {
131
+ recipes.set(alias, true);
299
132
  }
300
- const matchTag = memo2((tagName) => {
301
- return components.has(tagName) || isUpperCase(tagName) || tagName.startsWith(jsxFactoryAlias);
302
- });
303
- const matchTagProp = memo2((tagName, propName) => {
304
- if (propertiesMap.size === 0)
305
- return true;
306
- return Boolean(components.get(tagName)?.get(propName)) || propertiesMap.has(propName);
307
- });
308
- const matchFn = memo2((fnName) => {
309
- if (recipes.has(fnName))
310
- return true;
311
- if (fnName === cvaAlias || fnName === cssAlias || fnName.startsWith(jsxFactoryAlias))
312
- return true;
313
- return Boolean(functions.get(fnName));
133
+ });
134
+ const functions = /* @__PURE__ */ new Map();
135
+ const components = /* @__PURE__ */ new Map();
136
+ const propertiesMap = new Map(confProperties.map((prop) => [prop, true]));
137
+ const cvaAlias = imports.getAlias("cva");
138
+ const cssAlias = imports.getAlias("css");
139
+ if (options.jsx) {
140
+ options.jsx.nodes.forEach((node) => {
141
+ const properties = node.props ? new Map(propertiesMap) : propertiesMap;
142
+ const alias = imports.getAlias(node.name);
143
+ node.props?.forEach((prop) => properties.set(prop, true));
144
+ functions.set(node.baseName, properties);
145
+ functions.set(alias, properties);
146
+ components.set(alias, properties);
314
147
  });
315
- const matchFnProp = memo2((fnName, propName) => {
316
- if (propertiesMap.size === 0)
317
- return true;
318
- if (recipes.has(fnName))
319
- return true;
320
- if (fnName === cvaAlias)
321
- return true;
322
- if (fnName.startsWith(jsxFactoryAlias))
148
+ }
149
+ const matchTag = memo2((tagName) => {
150
+ return components.has(tagName) || isUpperCase(tagName) || tagName.startsWith(jsxFactoryAlias);
151
+ });
152
+ const matchTagProp = memo2((tagName, propName) => {
153
+ if (propertiesMap.size === 0)
154
+ return true;
155
+ return Boolean(components.get(tagName)?.get(propName)) || propertiesMap.has(propName);
156
+ });
157
+ const matchFn = memo2((fnName) => {
158
+ if (recipes.has(fnName))
159
+ return true;
160
+ if (fnName === cvaAlias || fnName === cssAlias || fnName.startsWith(jsxFactoryAlias))
161
+ return true;
162
+ return Boolean(functions.get(fnName));
163
+ });
164
+ const matchFnProp = memo2((fnName, propName) => {
165
+ if (propertiesMap.size === 0)
166
+ return true;
167
+ if (recipes.has(fnName))
168
+ return true;
169
+ if (fnName === cvaAlias)
170
+ return true;
171
+ if (fnName.startsWith(jsxFactoryAlias))
172
+ return true;
173
+ if (fnName === cssAlias)
174
+ return Boolean(propertiesMap.get(propName) || propName === "selectors");
175
+ return Boolean(functions.get(fnName)?.get(propName));
176
+ });
177
+ const measure = logger.time.debug(`Tokens extracted from ${filePath}`);
178
+ const extractResultByName = extract({
179
+ ast: sourceFile,
180
+ components: {
181
+ matchTag: (prop) => matchTag(prop.tagName),
182
+ matchProp: (prop) => matchTagProp(prop.tagName, prop.propName)
183
+ },
184
+ functions: {
185
+ matchFn: (prop) => matchFn(prop.fnName),
186
+ matchProp: (prop) => matchFnProp(prop.fnName, prop.propName),
187
+ matchArg: (prop) => {
188
+ if (prop.fnName === jsxFactoryAlias && prop.index === 1 && Node.isIdentifier(prop.argNode))
189
+ return false;
323
190
  return true;
324
- if (fnName === cssAlias)
325
- return Boolean(propertiesMap.get(propName) || propName === "selectors");
326
- return Boolean(functions.get(fnName)?.get(propName));
327
- });
328
- const measure2 = logger.time.debug(`Tokens extracted from ${filePath}`);
329
- const extractResultByName = extract({
330
- ast: sourceFile,
331
- components: {
332
- matchTag: (prop) => matchTag(prop.tagName),
333
- matchProp: (prop) => matchTagProp(prop.tagName, prop.propName)
334
- },
335
- functions: {
336
- matchFn: (prop) => matchFn(prop.fnName),
337
- matchProp: (prop) => matchFnProp(prop.fnName, prop.propName),
338
- matchArg: (prop) => {
339
- if (prop.fnName === jsxFactoryAlias && prop.index === 1 && Node4.isIdentifier(prop.argNode))
340
- return false;
341
- return true;
342
- }
343
- },
344
- flags: { skipTraverseFiles: true }
345
- });
346
- measure2();
347
- extractResultByName.forEach((result, alias) => {
348
- const name = imports.getName(alias);
349
- logger.debug(`ast:${name}`, { filePath, result, alias });
350
- if (result.kind === "function") {
351
- match3(name).when(css.match, (name2) => {
352
- result.queryList.forEach((query) => {
353
- collector.set(name2, {
354
- name: name2,
355
- box: query.box.value[0],
356
- data: combineResult(unbox(query.box.value[0]))
357
- });
358
- });
359
- }).when(isValidPattern, (name2) => {
360
- result.queryList.forEach((query) => {
361
- collector.setPattern(name2, {
362
- name: name2,
363
- box: query.box.value[0],
364
- data: combineResult(unbox(query.box.value[0]))
365
- });
191
+ }
192
+ },
193
+ flags: { skipTraverseFiles: true }
194
+ });
195
+ measure();
196
+ extractResultByName.forEach((result, alias) => {
197
+ const name = imports.getName(alias);
198
+ logger.debug(`ast:${name}`, { filePath, result, alias });
199
+ if (result.kind === "function") {
200
+ match(name).when(css.match, (name2) => {
201
+ result.queryList.forEach((query) => {
202
+ collector.set(name2, {
203
+ name: name2,
204
+ box: query.box.value[0],
205
+ data: combineResult(unbox(query.box.value[0]))
366
206
  });
367
- }).when(isValidRecipe, (name2) => {
368
- result.queryList.forEach((query) => {
369
- collector.setRecipe(name2, {
370
- name: name2,
371
- box: query.box.value[0],
372
- data: combineResult(unbox(query.box.value[0]))
373
- });
207
+ });
208
+ }).when(isValidPattern, (name2) => {
209
+ result.queryList.forEach((query) => {
210
+ collector.setPattern(name2, {
211
+ name: name2,
212
+ box: query.box.value[0],
213
+ data: combineResult(unbox(query.box.value[0]))
374
214
  });
375
- }).when(isValidStyleFn, () => {
376
- result.queryList.forEach((query) => {
377
- collector.setCva({
378
- name,
379
- box: query.box,
380
- data: combineResult(unbox(query.box))
381
- });
215
+ });
216
+ }).when(isValidRecipe, (name2) => {
217
+ result.queryList.forEach((query) => {
218
+ collector.setRecipe(name2, {
219
+ name: name2,
220
+ box: query.box.value[0],
221
+ data: combineResult(unbox(query.box.value[0]))
382
222
  });
383
- }).otherwise(() => {
384
223
  });
385
- } else if (result.kind === "component") {
224
+ }).when(isValidStyleFn, () => {
386
225
  result.queryList.forEach((query) => {
387
- let type;
388
- const data = combineResult(unbox(query.box));
389
- logger.debug(`ast:jsx:${name}`, { filePath, result: data });
390
- if (jsx && name.startsWith(jsxFactoryAlias)) {
391
- type = "jsx-factory";
392
- } else if (jsxPatternNodes.test(name)) {
393
- type = "pattern";
394
- } else if (jsxRecipeNodes.test(name)) {
395
- type = "recipe";
396
- } else {
397
- type = "jsx";
398
- }
399
- collector.jsx.add({
400
- // from "panda.*" -> "panda.button"
226
+ collector.setCva({
401
227
  name,
402
228
  box: query.box,
403
- type,
404
- data
229
+ data: combineResult(unbox(query.box))
405
230
  });
406
231
  });
407
- }
408
- });
409
- return collector;
410
- }
411
- const measure = logger.time.debug(`Tokens extracted & collected from ${filePath}`);
412
- visitCallExpressions(sourceFile, {
413
- match: memo2((name) => imports.match(name)),
414
- fn({ name: _name, data }) {
415
- const name = imports.getName(_name);
416
- const [css2] = importRegex;
417
- const result = { name, data };
418
- logger.debug(`ast:${name}`, { filePath, result });
419
- match3(name).when(css2.match, (name2) => {
420
- collector.set(name2, result);
421
- }).when(isValidPattern, (name2) => {
422
- collector.setPattern(name2, result);
423
- }).when(isValidRecipe, (name2) => {
424
- collector.setRecipe(name2, result);
425
- }).when(isValidStyleFn, () => {
426
- collector.setCva(result);
427
232
  }).otherwise(() => {
428
233
  });
234
+ } else if (result.kind === "component") {
235
+ result.queryList.forEach((query) => {
236
+ let type;
237
+ const data = combineResult(unbox(query.box));
238
+ logger.debug(`ast:jsx:${name}`, { filePath, result: data });
239
+ if (jsx && name.startsWith(jsxFactoryAlias)) {
240
+ type = "jsx-factory";
241
+ } else if (jsxPatternNodes.test(name)) {
242
+ type = "pattern";
243
+ } else if (jsxRecipeNodes.test(name)) {
244
+ type = "recipe";
245
+ } else {
246
+ type = "jsx";
247
+ }
248
+ collector.jsx.add({
249
+ // from "panda.*" -> "panda.button"
250
+ name,
251
+ box: query.box,
252
+ type,
253
+ data
254
+ });
255
+ });
429
256
  }
430
257
  });
431
- visitJsxElement(sourceFile, {
432
- match: {
433
- tag: memo2((name) => {
434
- return name.startsWith(jsxFactoryAlias) || isUpperCase(name);
435
- }),
436
- prop: ({ tag, name }) => {
437
- const node = jsx?.nodes.find((n) => n.name === tag);
438
- return !!jsx?.isStyleProp(name) || !!node?.props?.includes(name);
439
- }
440
- },
441
- fn({ name, data }) {
442
- let type;
443
- logger.debug(`ast:jsx:${name}`, { filePath, result: data });
444
- if (jsx && name.startsWith(jsxFactoryAlias)) {
445
- type = "jsx-factory";
446
- } else if (jsxPatternNodes.test(name)) {
447
- type = "pattern";
448
- } else if (jsxRecipeNodes.test(name)) {
449
- type = "recipe";
450
- } else {
451
- type = "jsx";
452
- }
453
- collector.jsx.add({ type, name, data });
454
- }
455
- });
456
- measure();
457
258
  return collector;
458
259
  };
459
260
  }
@@ -488,8 +289,8 @@ var createProject = ({ getFiles, readFile, parserOptions, ...projectOptions }) =
488
289
  overwrite: true,
489
290
  scriptKind: ScriptKind.TSX
490
291
  }),
491
- parseSourceFile: (filePath, properties, mode = "box-extractor") => {
492
- return parser(project.getSourceFile(filePath), properties, mode);
292
+ parseSourceFile: (filePath, properties) => {
293
+ return parser(project.getSourceFile(filePath), properties);
493
294
  }
494
295
  })),
495
296
  tap(({ createSourceFile }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandacss/parser",
3
- "version": "0.0.0-dev-20230413133612",
3
+ "version": "0.0.0-dev-20230413135202",
4
4
  "description": "The static parser for panda css",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -14,14 +14,14 @@
14
14
  "lil-fp": "1.4.5",
15
15
  "ts-morph": "18.0.0",
16
16
  "ts-pattern": "4.2.2",
17
- "@pandacss/extractor": "0.0.0-dev-20230413133612",
18
- "@pandacss/is-valid-prop": "0.0.0-dev-20230413133612",
19
- "@pandacss/logger": "0.0.0-dev-20230413133612",
20
- "@pandacss/shared": "0.0.0-dev-20230413133612",
21
- "@pandacss/types": "0.0.0-dev-20230413133612"
17
+ "@pandacss/extractor": "0.0.0-dev-20230413135202",
18
+ "@pandacss/is-valid-prop": "0.0.0-dev-20230413135202",
19
+ "@pandacss/logger": "0.0.0-dev-20230413135202",
20
+ "@pandacss/shared": "0.0.0-dev-20230413135202",
21
+ "@pandacss/types": "0.0.0-dev-20230413135202"
22
22
  },
23
23
  "devDependencies": {
24
- "@pandacss/fixture": "0.0.0-dev-20230413133612"
24
+ "@pandacss/fixture": "0.0.0-dev-20230413135202"
25
25
  },
26
26
  "files": [
27
27
  "dist"