@idealyst/tooling 1.2.30 → 1.2.31

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.
@@ -32,37 +32,57 @@ var analyzer_exports = {};
32
32
  __export(analyzer_exports, {
33
33
  analyzeComponents: () => analyzeComponents,
34
34
  analyzeTheme: () => analyzeTheme,
35
+ analyzeThemeSource: () => analyzeThemeSource,
35
36
  loadThemeKeys: () => loadThemeKeys,
36
- resetThemeCache: () => resetThemeCache
37
+ resetThemeCache: () => resetThemeCache,
38
+ toBabelThemeKeys: () => toBabelThemeKeys
37
39
  });
38
40
  module.exports = __toCommonJS(analyzer_exports);
39
41
 
40
42
  // src/analyzer/component-analyzer.ts
43
+ var ts3 = __toESM(require("typescript"), 1);
44
+ var fs3 = __toESM(require("fs"), 1);
45
+ var path3 = __toESM(require("path"), 1);
46
+
47
+ // src/analyzer/theme-analyzer.ts
41
48
  var ts2 = __toESM(require("typescript"), 1);
42
49
  var fs2 = __toESM(require("fs"), 1);
43
50
  var path2 = __toESM(require("path"), 1);
44
51
 
45
- // src/analyzer/theme-analyzer.ts
52
+ // src/analyzer/theme-source-analyzer.ts
46
53
  var ts = __toESM(require("typescript"), 1);
47
54
  var fs = __toESM(require("fs"), 1);
48
55
  var path = __toESM(require("path"), 1);
49
- function analyzeTheme(themePath, verbose = false) {
56
+ function analyzeThemeSource(themePath, options = {}) {
50
57
  const resolvedPath = path.resolve(themePath);
58
+ const verbose = options.verbose ?? false;
59
+ const aliases = options.aliases ?? {};
60
+ const log = (...args) => {
61
+ if (verbose) console.log("[theme-source-analyzer]", ...args);
62
+ };
51
63
  if (!fs.existsSync(resolvedPath)) {
52
64
  throw new Error(`Theme file not found: ${resolvedPath}`);
53
65
  }
54
- const log = (...args) => {
55
- if (verbose) console.log("[theme-analyzer]", ...args);
56
- };
57
66
  log("Analyzing theme file:", resolvedPath);
58
- const program = ts.createProgram([resolvedPath], {
67
+ const configPath = ts.findConfigFile(path.dirname(resolvedPath), ts.sys.fileExists, "tsconfig.json");
68
+ let compilerOptions = {
59
69
  target: ts.ScriptTarget.ES2020,
60
70
  module: ts.ModuleKind.ESNext,
71
+ moduleResolution: ts.ModuleResolutionKind.Node10,
61
72
  strict: true,
62
73
  esModuleInterop: true,
63
74
  skipLibCheck: true,
64
- allowSyntheticDefaultImports: true
65
- });
75
+ allowSyntheticDefaultImports: true,
76
+ resolveJsonModule: true
77
+ };
78
+ if (configPath) {
79
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
80
+ if (!configFile.error) {
81
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
82
+ compilerOptions = { ...compilerOptions, ...parsed.options };
83
+ }
84
+ }
85
+ const program = ts.createProgram([resolvedPath], compilerOptions);
66
86
  const sourceFile = program.getSourceFile(resolvedPath);
67
87
  if (!sourceFile) {
68
88
  throw new Error(`Failed to parse theme file: ${resolvedPath}`);
@@ -70,7 +90,9 @@ function analyzeTheme(themePath, verbose = false) {
70
90
  const ctx = {
71
91
  program,
72
92
  typeChecker: program.getTypeChecker(),
73
- verbose
93
+ verbose,
94
+ aliases,
95
+ analyzedFiles: /* @__PURE__ */ new Set([resolvedPath])
74
96
  };
75
97
  const values = {
76
98
  intents: [],
@@ -93,13 +115,377 @@ function analyzeTheme(themePath, verbose = false) {
93
115
  const localName = element.name.text;
94
116
  const importedName = element.propertyName?.text ?? localName;
95
117
  imports.set(localName, { source, imported: importedName });
118
+ log(` Import: ${localName} from '${source}'`);
96
119
  }
97
120
  }
98
121
  }
99
122
  });
123
+ function resolveImportPath(source, fromFile) {
124
+ for (const [aliasPrefix, aliasPath] of Object.entries(ctx.aliases)) {
125
+ if (source === aliasPrefix || source.startsWith(aliasPrefix + "/")) {
126
+ const remainder = source.slice(aliasPrefix.length);
127
+ let resolved = aliasPath + remainder;
128
+ if (!path.isAbsolute(resolved)) {
129
+ resolved = path.resolve(path.dirname(fromFile), resolved);
130
+ }
131
+ return resolved;
132
+ }
133
+ }
134
+ if (source.startsWith(".")) {
135
+ return path.resolve(path.dirname(fromFile), source);
136
+ }
137
+ try {
138
+ return require.resolve(source, { paths: [path.dirname(fromFile)] });
139
+ } catch {
140
+ return null;
141
+ }
142
+ }
143
+ function findThemeFile(basePath, preferDark) {
144
+ const themeFileName = preferDark ? "darkTheme" : "lightTheme";
145
+ const candidates = [
146
+ basePath,
147
+ `${basePath}.ts`,
148
+ `${basePath}.tsx`,
149
+ path.join(basePath, "src", `${themeFileName}.ts`),
150
+ path.join(basePath, `${themeFileName}.ts`),
151
+ path.join(basePath, "src", "index.ts"),
152
+ path.join(basePath, "index.ts")
153
+ ];
154
+ for (const candidate of candidates) {
155
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
156
+ return candidate;
157
+ }
158
+ }
159
+ return null;
160
+ }
161
+ function analyzeBaseTheme2(varName) {
162
+ const importInfo = imports.get(varName);
163
+ if (!importInfo) {
164
+ log(`Could not find import for base theme: ${varName}`);
165
+ return;
166
+ }
167
+ log(`Analyzing base theme '${varName}' from '${importInfo.source}'`);
168
+ const resolvedBase = resolveImportPath(importInfo.source, resolvedPath);
169
+ if (!resolvedBase) {
170
+ log(`Could not resolve import path: ${importInfo.source}`);
171
+ return;
172
+ }
173
+ const preferDark = varName.toLowerCase().includes("dark");
174
+ const themeFile = findThemeFile(resolvedBase, preferDark);
175
+ if (!themeFile) {
176
+ log(`Could not find theme file for: ${resolvedBase}`);
177
+ return;
178
+ }
179
+ if (ctx.analyzedFiles.has(themeFile)) {
180
+ log(`Already analyzed: ${themeFile}`);
181
+ return;
182
+ }
183
+ ctx.analyzedFiles.add(themeFile);
184
+ log(`Recursively analyzing: ${themeFile}`);
185
+ const baseValues = analyzeThemeSource(themeFile, { verbose, aliases });
186
+ mergeThemeValues(values, baseValues, false);
187
+ }
188
+ function traceBuilderCalls(node, calls = []) {
189
+ if (!ts.isPropertyAccessExpression(node.expression)) {
190
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
191
+ const fnName = node.expression.text;
192
+ if (fnName === "fromTheme" && node.arguments.length > 0) {
193
+ const arg = node.arguments[0];
194
+ if (ts.isIdentifier(arg)) {
195
+ return { calls, baseThemeVar: arg.text };
196
+ }
197
+ }
198
+ }
199
+ return { calls, baseThemeVar: null };
200
+ }
201
+ const methodName = node.expression.name.text;
202
+ calls.unshift({ method: methodName, args: node.arguments });
203
+ const obj = node.expression.expression;
204
+ if (ts.isCallExpression(obj)) {
205
+ return traceBuilderCalls(obj, calls);
206
+ }
207
+ return { calls, baseThemeVar: null };
208
+ }
209
+ function getStringValue2(node) {
210
+ if (!node) return null;
211
+ if (ts.isStringLiteral(node)) return node.text;
212
+ if (ts.isIdentifier(node)) return node.text;
213
+ if (ts.isNoSubstitutionTemplateLiteral(node)) return node.text;
214
+ return null;
215
+ }
216
+ function getObjectKeys2(node) {
217
+ return node.properties.filter((prop) => ts.isPropertyAssignment(prop)).map((prop) => {
218
+ if (ts.isIdentifier(prop.name)) return prop.name.text;
219
+ if (ts.isStringLiteral(prop.name)) return prop.name.text;
220
+ return null;
221
+ }).filter((k) => k !== null);
222
+ }
223
+ function processCalls(calls) {
224
+ log(`Processing ${calls.length} builder method calls`);
225
+ for (const { method, args } of calls) {
226
+ switch (method) {
227
+ case "addIntent": {
228
+ const name = getStringValue2(args[0]);
229
+ if (name && !values.intents.includes(name)) {
230
+ values.intents.push(name);
231
+ log(` Found intent: ${name}`);
232
+ }
233
+ break;
234
+ }
235
+ case "addRadius": {
236
+ const name = getStringValue2(args[0]);
237
+ if (name && !values.radii.includes(name)) {
238
+ values.radii.push(name);
239
+ log(` Found radius: ${name}`);
240
+ }
241
+ break;
242
+ }
243
+ case "addShadow": {
244
+ const name = getStringValue2(args[0]);
245
+ if (name && !values.shadows.includes(name)) {
246
+ values.shadows.push(name);
247
+ log(` Found shadow: ${name}`);
248
+ }
249
+ break;
250
+ }
251
+ case "addBreakpoint": {
252
+ const name = getStringValue2(args[0]);
253
+ if (name && !values.breakpoints.includes(name)) {
254
+ values.breakpoints.push(name);
255
+ log(` Found breakpoint: ${name}`);
256
+ }
257
+ break;
258
+ }
259
+ case "setBreakpoints": {
260
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
261
+ const keys = getObjectKeys2(args[0]);
262
+ for (const key of keys) {
263
+ if (!values.breakpoints.includes(key)) {
264
+ values.breakpoints.push(key);
265
+ }
266
+ }
267
+ log(` Found breakpoints: ${values.breakpoints.join(", ")}`);
268
+ }
269
+ break;
270
+ }
271
+ case "setSizes": {
272
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
273
+ for (const prop of args[0].properties) {
274
+ if (ts.isPropertyAssignment(prop)) {
275
+ let componentName = null;
276
+ if (ts.isIdentifier(prop.name)) {
277
+ componentName = prop.name.text;
278
+ } else if (ts.isStringLiteral(prop.name)) {
279
+ componentName = prop.name.text;
280
+ }
281
+ if (componentName && ts.isObjectLiteralExpression(prop.initializer)) {
282
+ const sizeKeys = getObjectKeys2(prop.initializer);
283
+ values.sizes[componentName] = sizeKeys;
284
+ log(` Found sizes for ${componentName}: ${sizeKeys.join(", ")}`);
285
+ if (componentName === "typography") {
286
+ for (const key of sizeKeys) {
287
+ if (!values.typography.includes(key)) {
288
+ values.typography.push(key);
289
+ }
290
+ }
291
+ }
292
+ }
293
+ }
294
+ }
295
+ } else if (args[0] && ts.isPropertyAccessExpression(args[0])) {
296
+ const propAccess = args[0];
297
+ if (ts.isIdentifier(propAccess.expression) && propAccess.name.text === "sizes") {
298
+ const themeVarName = propAccess.expression.text;
299
+ log(` Found sizes reference: ${themeVarName}.sizes`);
300
+ const importInfo = imports.get(themeVarName);
301
+ if (importInfo) {
302
+ log(` Resolving sizes from imported theme: ${importInfo.source}`);
303
+ const resolvedBase = resolveImportPath(importInfo.source, resolvedPath);
304
+ if (resolvedBase) {
305
+ const preferDark = themeVarName.toLowerCase().includes("dark");
306
+ const themeFile = findThemeFile(resolvedBase, preferDark);
307
+ if (themeFile && !ctx.analyzedFiles.has(themeFile)) {
308
+ ctx.analyzedFiles.add(themeFile);
309
+ const baseValues = analyzeThemeSource(themeFile, { verbose, aliases });
310
+ for (const [comp, sizes] of Object.entries(baseValues.sizes)) {
311
+ if (!values.sizes[comp]) {
312
+ values.sizes[comp] = sizes;
313
+ log(` Inherited sizes for ${comp}: ${sizes.join(", ")}`);
314
+ }
315
+ }
316
+ for (const typo of baseValues.typography) {
317
+ if (!values.typography.includes(typo)) {
318
+ values.typography.push(typo);
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+ break;
327
+ }
328
+ case "setColors": {
329
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
330
+ for (const prop of args[0].properties) {
331
+ if (ts.isPropertyAssignment(prop)) {
332
+ let colorType = null;
333
+ if (ts.isIdentifier(prop.name)) {
334
+ colorType = prop.name.text;
335
+ } else if (ts.isStringLiteral(prop.name)) {
336
+ colorType = prop.name.text;
337
+ }
338
+ if (colorType && ts.isObjectLiteralExpression(prop.initializer)) {
339
+ const colorKeys = getObjectKeys2(prop.initializer);
340
+ switch (colorType) {
341
+ case "surface":
342
+ values.surfaceColors = colorKeys;
343
+ log(` Found surface colors: ${colorKeys.join(", ")}`);
344
+ break;
345
+ case "text":
346
+ values.textColors = colorKeys;
347
+ log(` Found text colors: ${colorKeys.join(", ")}`);
348
+ break;
349
+ case "border":
350
+ values.borderColors = colorKeys;
351
+ log(` Found border colors: ${colorKeys.join(", ")}`);
352
+ break;
353
+ }
354
+ }
355
+ }
356
+ }
357
+ }
358
+ break;
359
+ }
360
+ case "build":
361
+ break;
362
+ default:
363
+ log(` Skipping unknown method: ${method}`);
364
+ }
365
+ }
366
+ }
100
367
  function processBuilderChain(node) {
101
368
  if (!ts.isCallExpression(node)) return;
102
- if (ts.isPropertyAccessExpression(node.expression)) {
369
+ if (ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "build") {
370
+ log("Found .build() call, tracing chain...");
371
+ const { calls, baseThemeVar } = traceBuilderCalls(node);
372
+ if (baseThemeVar) {
373
+ log(`Found fromTheme(${baseThemeVar})`);
374
+ analyzeBaseTheme2(baseThemeVar);
375
+ }
376
+ processCalls(calls);
377
+ return;
378
+ }
379
+ ts.forEachChild(node, processBuilderChain);
380
+ }
381
+ ts.forEachChild(sourceFile, (node) => {
382
+ if (ts.isVariableStatement(node)) {
383
+ for (const decl of node.declarationList.declarations) {
384
+ if (decl.initializer) {
385
+ processBuilderChain(decl.initializer);
386
+ }
387
+ }
388
+ }
389
+ if (ts.isExportAssignment(node)) {
390
+ processBuilderChain(node.expression);
391
+ }
392
+ });
393
+ log("Analysis complete:");
394
+ log(` Intents: ${values.intents.join(", ")}`);
395
+ log(` Radii: ${values.radii.join(", ")}`);
396
+ log(` Shadows: ${values.shadows.join(", ")}`);
397
+ log(` Breakpoints: ${values.breakpoints.join(", ")}`);
398
+ log(` Typography: ${values.typography.join(", ")}`);
399
+ log(` Size components: ${Object.keys(values.sizes).join(", ")}`);
400
+ return values;
401
+ }
402
+ function mergeThemeValues(target, source, sourceOverrides) {
403
+ const mergeArrays = (targetArr, sourceArr) => {
404
+ for (const item of sourceArr) {
405
+ if (!targetArr.includes(item)) {
406
+ targetArr.push(item);
407
+ }
408
+ }
409
+ };
410
+ mergeArrays(target.intents, source.intents);
411
+ mergeArrays(target.radii, source.radii);
412
+ mergeArrays(target.shadows, source.shadows);
413
+ mergeArrays(target.breakpoints, source.breakpoints);
414
+ mergeArrays(target.typography, source.typography);
415
+ mergeArrays(target.surfaceColors, source.surfaceColors);
416
+ mergeArrays(target.textColors, source.textColors);
417
+ mergeArrays(target.borderColors, source.borderColors);
418
+ for (const [component, sizes] of Object.entries(source.sizes)) {
419
+ if (sourceOverrides || !target.sizes[component]) {
420
+ target.sizes[component] = sizes;
421
+ }
422
+ }
423
+ }
424
+ function toBabelThemeKeys(values) {
425
+ return {
426
+ intents: values.intents,
427
+ sizes: values.sizes,
428
+ radii: values.radii,
429
+ shadows: values.shadows,
430
+ typography: values.typography
431
+ };
432
+ }
433
+
434
+ // src/analyzer/theme-analyzer.ts
435
+ function analyzeTheme(themePath, verbose = false) {
436
+ const resolvedPath = path2.resolve(themePath);
437
+ if (!fs2.existsSync(resolvedPath)) {
438
+ throw new Error(`Theme file not found: ${resolvedPath}`);
439
+ }
440
+ const log = (...args) => {
441
+ if (verbose) console.log("[theme-analyzer]", ...args);
442
+ };
443
+ log("Analyzing theme file:", resolvedPath);
444
+ const program = ts2.createProgram([resolvedPath], {
445
+ target: ts2.ScriptTarget.ES2020,
446
+ module: ts2.ModuleKind.ESNext,
447
+ strict: true,
448
+ esModuleInterop: true,
449
+ skipLibCheck: true,
450
+ allowSyntheticDefaultImports: true
451
+ });
452
+ const sourceFile = program.getSourceFile(resolvedPath);
453
+ if (!sourceFile) {
454
+ throw new Error(`Failed to parse theme file: ${resolvedPath}`);
455
+ }
456
+ const ctx = {
457
+ program,
458
+ typeChecker: program.getTypeChecker(),
459
+ verbose
460
+ };
461
+ const values = {
462
+ intents: [],
463
+ sizes: {},
464
+ radii: [],
465
+ shadows: [],
466
+ breakpoints: [],
467
+ typography: [],
468
+ surfaceColors: [],
469
+ textColors: [],
470
+ borderColors: []
471
+ };
472
+ const imports = /* @__PURE__ */ new Map();
473
+ ts2.forEachChild(sourceFile, (node) => {
474
+ if (ts2.isImportDeclaration(node)) {
475
+ const source = node.moduleSpecifier.text;
476
+ const clause = node.importClause;
477
+ if (clause?.namedBindings && ts2.isNamedImports(clause.namedBindings)) {
478
+ for (const element of clause.namedBindings.elements) {
479
+ const localName = element.name.text;
480
+ const importedName = element.propertyName?.text ?? localName;
481
+ imports.set(localName, { source, imported: importedName });
482
+ }
483
+ }
484
+ }
485
+ });
486
+ function processBuilderChain(node) {
487
+ if (!ts2.isCallExpression(node)) return;
488
+ if (ts2.isPropertyAccessExpression(node.expression)) {
103
489
  const methodName = node.expression.name.text;
104
490
  if (methodName === "build") {
105
491
  const calls = traceBuilderCalls(node);
@@ -107,15 +493,15 @@ function analyzeTheme(themePath, verbose = false) {
107
493
  return;
108
494
  }
109
495
  }
110
- ts.forEachChild(node, processBuilderChain);
496
+ ts2.forEachChild(node, processBuilderChain);
111
497
  }
112
498
  function traceBuilderCalls(node, calls = []) {
113
- if (!ts.isPropertyAccessExpression(node.expression)) {
114
- if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
499
+ if (!ts2.isPropertyAccessExpression(node.expression)) {
500
+ if (ts2.isCallExpression(node) && ts2.isIdentifier(node.expression)) {
115
501
  const fnName = node.expression.text;
116
502
  if (fnName === "fromTheme" && node.arguments.length > 0) {
117
503
  const arg = node.arguments[0];
118
- if (ts.isIdentifier(arg)) {
504
+ if (ts2.isIdentifier(arg)) {
119
505
  analyzeBaseTheme(arg.text, imports, values, ctx);
120
506
  }
121
507
  }
@@ -125,7 +511,7 @@ function analyzeTheme(themePath, verbose = false) {
125
511
  const methodName = node.expression.name.text;
126
512
  calls.unshift({ method: methodName, args: node.arguments });
127
513
  const obj = node.expression.expression;
128
- if (ts.isCallExpression(obj)) {
514
+ if (ts2.isCallExpression(obj)) {
129
515
  return traceBuilderCalls(obj, calls);
130
516
  }
131
517
  return calls;
@@ -159,11 +545,11 @@ function analyzeTheme(themePath, verbose = false) {
159
545
  break;
160
546
  }
161
547
  case "setSizes": {
162
- if (args[0] && ts.isObjectLiteralExpression(args[0])) {
548
+ if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
163
549
  for (const prop of args[0].properties) {
164
- if (ts.isPropertyAssignment(prop)) {
550
+ if (ts2.isPropertyAssignment(prop)) {
165
551
  const componentName = getPropertyName(prop.name);
166
- if (componentName && ts.isObjectLiteralExpression(prop.initializer)) {
552
+ if (componentName && ts2.isObjectLiteralExpression(prop.initializer)) {
167
553
  values.sizes[componentName] = getObjectKeys(prop.initializer);
168
554
  log(" Found sizes for", componentName + ":", values.sizes[componentName]);
169
555
  }
@@ -173,18 +559,18 @@ function analyzeTheme(themePath, verbose = false) {
173
559
  break;
174
560
  }
175
561
  case "setBreakpoints": {
176
- if (args[0] && ts.isObjectLiteralExpression(args[0])) {
562
+ if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
177
563
  values.breakpoints = getObjectKeys(args[0]);
178
564
  log(" Found breakpoints:", values.breakpoints);
179
565
  }
180
566
  break;
181
567
  }
182
568
  case "setColors": {
183
- if (args[0] && ts.isObjectLiteralExpression(args[0])) {
569
+ if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
184
570
  for (const prop of args[0].properties) {
185
- if (ts.isPropertyAssignment(prop)) {
571
+ if (ts2.isPropertyAssignment(prop)) {
186
572
  const colorType = getPropertyName(prop.name);
187
- if (ts.isObjectLiteralExpression(prop.initializer)) {
573
+ if (ts2.isObjectLiteralExpression(prop.initializer)) {
188
574
  const keys = getObjectKeys(prop.initializer);
189
575
  switch (colorType) {
190
576
  case "surface":
@@ -213,15 +599,15 @@ function analyzeTheme(themePath, verbose = false) {
213
599
  }
214
600
  }
215
601
  }
216
- ts.forEachChild(sourceFile, (node) => {
217
- if (ts.isVariableStatement(node)) {
602
+ ts2.forEachChild(sourceFile, (node) => {
603
+ if (ts2.isVariableStatement(node)) {
218
604
  for (const decl of node.declarationList.declarations) {
219
605
  if (decl.initializer) {
220
606
  processBuilderChain(decl.initializer);
221
607
  }
222
608
  }
223
609
  }
224
- if (ts.isExportAssignment(node)) {
610
+ if (ts2.isExportAssignment(node)) {
225
611
  processBuilderChain(node.expression);
226
612
  }
227
613
  });
@@ -242,9 +628,30 @@ function analyzeBaseTheme(varName, imports, values, ctx) {
242
628
  }
243
629
  log("Base theme", varName, "imported from", importInfo.source);
244
630
  if (importInfo.source === "@idealyst/theme" || importInfo.source.includes("@idealyst/theme")) {
245
- const defaultValues = getDefaultThemeValues();
246
- mergeThemeValues(values, defaultValues);
631
+ const aliasPath = packageAliases["@idealyst/theme"];
632
+ if (aliasPath) {
633
+ const themeFileName = varName.toLowerCase().includes("dark") ? "darkTheme.ts" : "lightTheme.ts";
634
+ const themePath = path2.join(aliasPath, "src", themeFileName);
635
+ if (fs2.existsSync(themePath)) {
636
+ log(`Analyzing @idealyst/theme from source: ${themePath}`);
637
+ try {
638
+ const sourceValues = analyzeThemeSource(themePath, {
639
+ verbose: ctx.verbose,
640
+ aliases: packageAliases
641
+ });
642
+ mergeThemeValues2(values, sourceValues);
643
+ log("Successfully extracted values from source");
644
+ return;
645
+ } catch (err) {
646
+ log("Failed to analyze source, falling back to defaults:", err.message);
647
+ }
648
+ } else {
649
+ log(`Theme file not found at alias path: ${themePath}`);
650
+ }
651
+ }
247
652
  log("Using default @idealyst/theme values");
653
+ const defaultValues = getDefaultThemeValues();
654
+ mergeThemeValues2(values, defaultValues);
248
655
  return;
249
656
  }
250
657
  log("Skipping base theme analysis for:", importInfo.source);
@@ -254,6 +661,7 @@ function getDefaultThemeValues() {
254
661
  intents: ["primary", "success", "danger", "warning", "neutral", "info"],
255
662
  sizes: {
256
663
  button: ["xs", "sm", "md", "lg", "xl"],
664
+ iconButton: ["xs", "sm", "md", "lg", "xl"],
257
665
  chip: ["xs", "sm", "md", "lg", "xl"],
258
666
  badge: ["xs", "sm", "md", "lg", "xl"],
259
667
  icon: ["xs", "sm", "md", "lg", "xl"],
@@ -267,6 +675,7 @@ function getDefaultThemeValues() {
267
675
  progress: ["xs", "sm", "md", "lg", "xl"],
268
676
  accordion: ["xs", "sm", "md", "lg", "xl"],
269
677
  activityIndicator: ["xs", "sm", "md", "lg", "xl"],
678
+ alert: ["xs", "sm", "md", "lg", "xl"],
270
679
  breadcrumb: ["xs", "sm", "md", "lg", "xl"],
271
680
  list: ["xs", "sm", "md", "lg", "xl"],
272
681
  menu: ["xs", "sm", "md", "lg", "xl"],
@@ -287,7 +696,7 @@ function getDefaultThemeValues() {
287
696
  borderColors: ["primary", "secondary", "tertiary", "disabled"]
288
697
  };
289
698
  }
290
- function mergeThemeValues(target, source) {
699
+ function mergeThemeValues2(target, source) {
291
700
  target.intents.push(...source.intents.filter((k) => !target.intents.includes(k)));
292
701
  target.radii.push(...source.radii.filter((k) => !target.radii.includes(k)));
293
702
  target.shadows.push(...source.shadows.filter((k) => !target.shadows.includes(k)));
@@ -304,32 +713,58 @@ function mergeThemeValues(target, source) {
304
713
  }
305
714
  function getStringValue(node) {
306
715
  if (!node) return null;
307
- if (ts.isStringLiteral(node)) return node.text;
308
- if (ts.isIdentifier(node)) return node.text;
716
+ if (ts2.isStringLiteral(node)) return node.text;
717
+ if (ts2.isIdentifier(node)) return node.text;
309
718
  return null;
310
719
  }
311
720
  function getPropertyName(node) {
312
- if (ts.isIdentifier(node)) return node.text;
313
- if (ts.isStringLiteral(node)) return node.text;
721
+ if (ts2.isIdentifier(node)) return node.text;
722
+ if (ts2.isStringLiteral(node)) return node.text;
314
723
  return null;
315
724
  }
316
725
  function getObjectKeys(node) {
317
- return node.properties.filter(ts.isPropertyAssignment).map((prop) => getPropertyName(prop.name)).filter((k) => k !== null);
726
+ return node.properties.filter(ts2.isPropertyAssignment).map((prop) => getPropertyName(prop.name)).filter((k) => k !== null);
318
727
  }
319
728
  var themeKeysCache = null;
320
729
  var themeLoadAttempted = false;
730
+ var packageAliases = {};
731
+ function resolveWithAliases(source, fromDir) {
732
+ for (const [aliasPrefix, aliasPath] of Object.entries(packageAliases)) {
733
+ if (source === aliasPrefix || source.startsWith(aliasPrefix + "/")) {
734
+ const remainder = source.slice(aliasPrefix.length);
735
+ let resolved = aliasPath + remainder;
736
+ if (!path2.isAbsolute(resolved)) {
737
+ resolved = path2.resolve(fromDir, resolved);
738
+ }
739
+ return resolved;
740
+ }
741
+ }
742
+ return null;
743
+ }
321
744
  function loadThemeKeys(opts, rootDir, _babelTypes, verboseMode = false) {
322
745
  if (themeLoadAttempted && themeKeysCache) {
323
746
  return themeKeysCache;
324
747
  }
325
748
  themeLoadAttempted = true;
749
+ if (opts.aliases && typeof opts.aliases === "object") {
750
+ packageAliases = opts.aliases;
751
+ if (verboseMode) {
752
+ console.log("[idealyst-plugin] Configured aliases:", packageAliases);
753
+ }
754
+ }
326
755
  const themePath = opts.themePath;
327
756
  if (!themePath) {
328
757
  throw new Error(
329
758
  '[idealyst-plugin] themePath is required!\nAdd it to your babel config:\n ["@idealyst/theme/plugin", { themePath: "./src/theme/styles.ts" }]'
330
759
  );
331
760
  }
332
- const resolvedPath = themePath.startsWith(".") ? path.resolve(rootDir, themePath) : themePath;
761
+ let resolvedPath;
762
+ const aliasResolved = resolveWithAliases(themePath, rootDir);
763
+ if (aliasResolved && fs2.existsSync(aliasResolved)) {
764
+ resolvedPath = aliasResolved;
765
+ } else {
766
+ resolvedPath = themePath.startsWith(".") ? path2.resolve(rootDir, themePath) : themePath;
767
+ }
333
768
  if (verboseMode) {
334
769
  console.log("[idealyst-plugin] Analyzing theme file via @idealyst/tooling:", resolvedPath);
335
770
  }
@@ -364,14 +799,14 @@ function analyzeComponents(options) {
364
799
  const registry = {};
365
800
  const themeValues = analyzeTheme(themePath, false);
366
801
  for (const componentPath of componentPaths) {
367
- const resolvedPath = path2.resolve(componentPath);
368
- if (!fs2.existsSync(resolvedPath)) {
802
+ const resolvedPath = path3.resolve(componentPath);
803
+ if (!fs3.existsSync(resolvedPath)) {
369
804
  console.warn(`[component-analyzer] Path not found: ${resolvedPath}`);
370
805
  continue;
371
806
  }
372
807
  const componentDirs = findComponentDirs(resolvedPath);
373
808
  for (const dir of componentDirs) {
374
- const componentName = path2.basename(dir);
809
+ const componentName = path3.basename(dir);
375
810
  if (include && !include.includes(componentName)) continue;
376
811
  if (exclude && exclude.includes(componentName)) continue;
377
812
  if (!includeInternal && componentName.startsWith("_")) continue;
@@ -385,12 +820,12 @@ function analyzeComponents(options) {
385
820
  }
386
821
  function findComponentDirs(basePath) {
387
822
  const dirs = [];
388
- const entries = fs2.readdirSync(basePath, { withFileTypes: true });
823
+ const entries = fs3.readdirSync(basePath, { withFileTypes: true });
389
824
  for (const entry of entries) {
390
825
  if (!entry.isDirectory()) continue;
391
- const dirPath = path2.join(basePath, entry.name);
392
- const hasIndex = fs2.existsSync(path2.join(dirPath, "index.ts"));
393
- const hasTypes = fs2.existsSync(path2.join(dirPath, "types.ts"));
826
+ const dirPath = path3.join(basePath, entry.name);
827
+ const hasIndex = fs3.existsSync(path3.join(dirPath, "index.ts"));
828
+ const hasTypes = fs3.existsSync(path3.join(dirPath, "types.ts"));
394
829
  if (hasIndex || hasTypes) {
395
830
  dirs.push(dirPath);
396
831
  }
@@ -398,14 +833,14 @@ function findComponentDirs(basePath) {
398
833
  return dirs;
399
834
  }
400
835
  function analyzeComponentDir(dir, componentName, themeValues) {
401
- const tsFiles = fs2.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx")).map((f) => path2.join(dir, f));
836
+ const tsFiles = fs3.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx")).map((f) => path3.join(dir, f));
402
837
  if (tsFiles.length === 0) {
403
838
  return null;
404
839
  }
405
- const program = ts2.createProgram(tsFiles, {
406
- target: ts2.ScriptTarget.ES2020,
407
- module: ts2.ModuleKind.ESNext,
408
- jsx: ts2.JsxEmit.React,
840
+ const program = ts3.createProgram(tsFiles, {
841
+ target: ts3.ScriptTarget.ES2020,
842
+ module: ts3.ModuleKind.ESNext,
843
+ jsx: ts3.JsxEmit.React,
409
844
  strict: true,
410
845
  esModuleInterop: true,
411
846
  skipLibCheck: true
@@ -418,12 +853,12 @@ function analyzeComponentDir(dir, componentName, themeValues) {
418
853
  for (const filePath of tsFiles) {
419
854
  const sourceFile = program.getSourceFile(filePath);
420
855
  if (!sourceFile) continue;
421
- ts2.forEachChild(sourceFile, (node) => {
422
- if (ts2.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
856
+ ts3.forEachChild(sourceFile, (node) => {
857
+ if (ts3.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
423
858
  propsInterface = node;
424
859
  interfaceDescription = getJSDocDescription(node);
425
860
  }
426
- if (ts2.isTypeAliasDeclaration(node) && node.name.text === propsInterfaceName) {
861
+ if (ts3.isTypeAliasDeclaration(node) && node.name.text === propsInterfaceName) {
427
862
  propsInterface = node;
428
863
  interfaceDescription = getJSDocDescription(node);
429
864
  }
@@ -435,8 +870,8 @@ function analyzeComponentDir(dir, componentName, themeValues) {
435
870
  for (const filePath of tsFiles) {
436
871
  const sourceFile = program.getSourceFile(filePath);
437
872
  if (!sourceFile) continue;
438
- ts2.forEachChild(sourceFile, (node) => {
439
- if ((ts2.isInterfaceDeclaration(node) || ts2.isTypeAliasDeclaration(node)) && node.name.text === altName) {
873
+ ts3.forEachChild(sourceFile, (node) => {
874
+ if ((ts3.isInterfaceDeclaration(node) || ts3.isTypeAliasDeclaration(node)) && node.name.text === altName) {
440
875
  propsInterface = node;
441
876
  interfaceDescription = getJSDocDescription(node);
442
877
  }
@@ -468,32 +903,32 @@ function analyzeComponentDir(dir, componentName, themeValues) {
468
903
  description,
469
904
  props,
470
905
  category,
471
- filePath: path2.relative(process.cwd(), dir),
906
+ filePath: path3.relative(process.cwd(), dir),
472
907
  sampleProps
473
908
  };
474
909
  }
475
910
  function extractSampleProps(dir) {
476
- const docsPath = path2.join(dir, "docs.ts");
477
- if (!fs2.existsSync(docsPath)) {
911
+ const docsPath = path3.join(dir, "docs.ts");
912
+ if (!fs3.existsSync(docsPath)) {
478
913
  return void 0;
479
914
  }
480
915
  try {
481
- const content = fs2.readFileSync(docsPath, "utf-8");
482
- const sourceFile = ts2.createSourceFile(
916
+ const content = fs3.readFileSync(docsPath, "utf-8");
917
+ const sourceFile = ts3.createSourceFile(
483
918
  "docs.ts",
484
919
  content,
485
- ts2.ScriptTarget.ES2020,
920
+ ts3.ScriptTarget.ES2020,
486
921
  true,
487
- ts2.ScriptKind.TS
922
+ ts3.ScriptKind.TS
488
923
  );
489
924
  let samplePropsNode = null;
490
- ts2.forEachChild(sourceFile, (node) => {
491
- if (ts2.isVariableStatement(node)) {
492
- const isExported = node.modifiers?.some((m) => m.kind === ts2.SyntaxKind.ExportKeyword);
925
+ ts3.forEachChild(sourceFile, (node) => {
926
+ if (ts3.isVariableStatement(node)) {
927
+ const isExported = node.modifiers?.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
493
928
  if (isExported) {
494
929
  for (const decl of node.declarationList.declarations) {
495
- if (ts2.isIdentifier(decl.name) && decl.name.text === "sampleProps" && decl.initializer) {
496
- if (ts2.isObjectLiteralExpression(decl.initializer)) {
930
+ if (ts3.isIdentifier(decl.name) && decl.name.text === "sampleProps" && decl.initializer) {
931
+ if (ts3.isObjectLiteralExpression(decl.initializer)) {
497
932
  samplePropsNode = decl.initializer;
498
933
  }
499
934
  }
@@ -507,13 +942,13 @@ function extractSampleProps(dir) {
507
942
  const result = {};
508
943
  const propsNode = samplePropsNode;
509
944
  for (const prop of propsNode.properties) {
510
- if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
945
+ if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
511
946
  const propName = prop.name.text;
512
- if (propName === "props" && ts2.isObjectLiteralExpression(prop.initializer)) {
947
+ if (propName === "props" && ts3.isObjectLiteralExpression(prop.initializer)) {
513
948
  result.props = extractObjectLiteral(prop.initializer, content);
514
949
  } else if (propName === "children") {
515
950
  result.children = prop.initializer.getText(sourceFile);
516
- } else if (propName === "state" && ts2.isObjectLiteralExpression(prop.initializer)) {
951
+ } else if (propName === "state" && ts3.isObjectLiteralExpression(prop.initializer)) {
517
952
  result.state = extractObjectLiteral(prop.initializer, content);
518
953
  }
519
954
  }
@@ -527,20 +962,20 @@ function extractSampleProps(dir) {
527
962
  function extractObjectLiteral(node, sourceContent) {
528
963
  const result = {};
529
964
  for (const prop of node.properties) {
530
- if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
965
+ if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
531
966
  const key = prop.name.text;
532
967
  const init = prop.initializer;
533
- if (ts2.isStringLiteral(init)) {
968
+ if (ts3.isStringLiteral(init)) {
534
969
  result[key] = init.text;
535
- } else if (ts2.isNumericLiteral(init)) {
970
+ } else if (ts3.isNumericLiteral(init)) {
536
971
  result[key] = Number(init.text);
537
- } else if (init.kind === ts2.SyntaxKind.TrueKeyword) {
972
+ } else if (init.kind === ts3.SyntaxKind.TrueKeyword) {
538
973
  result[key] = true;
539
- } else if (init.kind === ts2.SyntaxKind.FalseKeyword) {
974
+ } else if (init.kind === ts3.SyntaxKind.FalseKeyword) {
540
975
  result[key] = false;
541
- } else if (ts2.isArrayLiteralExpression(init)) {
976
+ } else if (ts3.isArrayLiteralExpression(init)) {
542
977
  result[key] = extractArrayLiteral(init, sourceContent);
543
- } else if (ts2.isObjectLiteralExpression(init)) {
978
+ } else if (ts3.isObjectLiteralExpression(init)) {
544
979
  result[key] = extractObjectLiteral(init, sourceContent);
545
980
  } else {
546
981
  result[key] = init.getText();
@@ -552,17 +987,17 @@ function extractObjectLiteral(node, sourceContent) {
552
987
  function extractArrayLiteral(node, sourceContent) {
553
988
  const result = [];
554
989
  for (const element of node.elements) {
555
- if (ts2.isStringLiteral(element)) {
990
+ if (ts3.isStringLiteral(element)) {
556
991
  result.push(element.text);
557
- } else if (ts2.isNumericLiteral(element)) {
992
+ } else if (ts3.isNumericLiteral(element)) {
558
993
  result.push(Number(element.text));
559
- } else if (element.kind === ts2.SyntaxKind.TrueKeyword) {
994
+ } else if (element.kind === ts3.SyntaxKind.TrueKeyword) {
560
995
  result.push(true);
561
- } else if (element.kind === ts2.SyntaxKind.FalseKeyword) {
996
+ } else if (element.kind === ts3.SyntaxKind.FalseKeyword) {
562
997
  result.push(false);
563
- } else if (ts2.isObjectLiteralExpression(element)) {
998
+ } else if (ts3.isObjectLiteralExpression(element)) {
564
999
  result.push(extractObjectLiteral(element, sourceContent));
565
- } else if (ts2.isArrayLiteralExpression(element)) {
1000
+ } else if (ts3.isArrayLiteralExpression(element)) {
566
1001
  result.push(extractArrayLiteral(element, sourceContent));
567
1002
  } else {
568
1003
  result.push(element.getText());
@@ -577,8 +1012,8 @@ function analyzeProperty(symbol, typeChecker, themeValues) {
577
1012
  const declaration = declarations[0];
578
1013
  const type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration);
579
1014
  const typeString = typeChecker.typeToString(type);
580
- const description = ts2.displayPartsToString(symbol.getDocumentationComment(typeChecker)) || void 0;
581
- const required = !(symbol.flags & ts2.SymbolFlags.Optional);
1015
+ const description = ts3.displayPartsToString(symbol.getDocumentationComment(typeChecker)) || void 0;
1016
+ const required = !(symbol.flags & ts3.SymbolFlags.Optional);
582
1017
  const values = extractPropValues(type, typeString, typeChecker, themeValues);
583
1018
  const defaultValue = extractDefaultValue(symbol);
584
1019
  return {
@@ -619,7 +1054,7 @@ function extractDefaultValue(symbol) {
619
1054
  const tags = symbol.getJsDocTags();
620
1055
  for (const tag of tags) {
621
1056
  if (tag.name === "default" && tag.text) {
622
- const value = ts2.displayPartsToString(tag.text);
1057
+ const value = ts3.displayPartsToString(tag.text);
623
1058
  try {
624
1059
  return JSON.parse(value);
625
1060
  } catch {
@@ -724,7 +1159,9 @@ function inferCategory(componentName) {
724
1159
  0 && (module.exports = {
725
1160
  analyzeComponents,
726
1161
  analyzeTheme,
1162
+ analyzeThemeSource,
727
1163
  loadThemeKeys,
728
- resetThemeCache
1164
+ resetThemeCache,
1165
+ toBabelThemeKeys
729
1166
  });
730
1167
  //# sourceMappingURL=index.cjs.map