@idealyst/tooling 1.2.30 → 1.2.32

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.
@@ -34,35 +34,53 @@ __export(vite_plugin_exports, {
34
34
  idealystDocsPlugin: () => idealystDocsPlugin
35
35
  });
36
36
  module.exports = __toCommonJS(vite_plugin_exports);
37
+ var fs4 = __toESM(require("fs"), 1);
38
+ var path4 = __toESM(require("path"), 1);
39
+
40
+ // src/analyzer/component-analyzer.ts
41
+ var ts3 = __toESM(require("typescript"), 1);
37
42
  var fs3 = __toESM(require("fs"), 1);
38
43
  var path3 = __toESM(require("path"), 1);
39
44
 
40
- // src/analyzer/component-analyzer.ts
45
+ // src/analyzer/theme-analyzer.ts
41
46
  var ts2 = __toESM(require("typescript"), 1);
42
47
  var fs2 = __toESM(require("fs"), 1);
43
48
  var path2 = __toESM(require("path"), 1);
44
49
 
45
- // src/analyzer/theme-analyzer.ts
50
+ // src/analyzer/theme-source-analyzer.ts
46
51
  var ts = __toESM(require("typescript"), 1);
47
52
  var fs = __toESM(require("fs"), 1);
48
53
  var path = __toESM(require("path"), 1);
49
- function analyzeTheme(themePath, verbose = false) {
54
+ function analyzeThemeSource(themePath, options = {}) {
50
55
  const resolvedPath = path.resolve(themePath);
56
+ const verbose = options.verbose ?? false;
57
+ const aliases = options.aliases ?? {};
58
+ const log = (...args) => {
59
+ if (verbose) console.log("[theme-source-analyzer]", ...args);
60
+ };
51
61
  if (!fs.existsSync(resolvedPath)) {
52
62
  throw new Error(`Theme file not found: ${resolvedPath}`);
53
63
  }
54
- const log = (...args) => {
55
- if (verbose) console.log("[theme-analyzer]", ...args);
56
- };
57
64
  log("Analyzing theme file:", resolvedPath);
58
- const program = ts.createProgram([resolvedPath], {
65
+ const configPath = ts.findConfigFile(path.dirname(resolvedPath), ts.sys.fileExists, "tsconfig.json");
66
+ let compilerOptions = {
59
67
  target: ts.ScriptTarget.ES2020,
60
68
  module: ts.ModuleKind.ESNext,
69
+ moduleResolution: ts.ModuleResolutionKind.Node10,
61
70
  strict: true,
62
71
  esModuleInterop: true,
63
72
  skipLibCheck: true,
64
- allowSyntheticDefaultImports: true
65
- });
73
+ allowSyntheticDefaultImports: true,
74
+ resolveJsonModule: true
75
+ };
76
+ if (configPath) {
77
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
78
+ if (!configFile.error) {
79
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
80
+ compilerOptions = { ...compilerOptions, ...parsed.options };
81
+ }
82
+ }
83
+ const program = ts.createProgram([resolvedPath], compilerOptions);
66
84
  const sourceFile = program.getSourceFile(resolvedPath);
67
85
  if (!sourceFile) {
68
86
  throw new Error(`Failed to parse theme file: ${resolvedPath}`);
@@ -70,7 +88,9 @@ function analyzeTheme(themePath, verbose = false) {
70
88
  const ctx = {
71
89
  program,
72
90
  typeChecker: program.getTypeChecker(),
73
- verbose
91
+ verbose,
92
+ aliases,
93
+ analyzedFiles: /* @__PURE__ */ new Set([resolvedPath])
74
94
  };
75
95
  const values = {
76
96
  intents: [],
@@ -93,13 +113,368 @@ function analyzeTheme(themePath, verbose = false) {
93
113
  const localName = element.name.text;
94
114
  const importedName = element.propertyName?.text ?? localName;
95
115
  imports.set(localName, { source, imported: importedName });
116
+ log(` Import: ${localName} from '${source}'`);
96
117
  }
97
118
  }
98
119
  }
99
120
  });
121
+ function resolveImportPath(source, fromFile) {
122
+ for (const [aliasPrefix, aliasPath] of Object.entries(ctx.aliases)) {
123
+ if (source === aliasPrefix || source.startsWith(aliasPrefix + "/")) {
124
+ const remainder = source.slice(aliasPrefix.length);
125
+ let resolved = aliasPath + remainder;
126
+ if (!path.isAbsolute(resolved)) {
127
+ resolved = path.resolve(path.dirname(fromFile), resolved);
128
+ }
129
+ return resolved;
130
+ }
131
+ }
132
+ if (source.startsWith(".")) {
133
+ return path.resolve(path.dirname(fromFile), source);
134
+ }
135
+ try {
136
+ return require.resolve(source, { paths: [path.dirname(fromFile)] });
137
+ } catch {
138
+ return null;
139
+ }
140
+ }
141
+ function findThemeFile(basePath, preferDark) {
142
+ const themeFileName = preferDark ? "darkTheme" : "lightTheme";
143
+ const candidates = [
144
+ basePath,
145
+ `${basePath}.ts`,
146
+ `${basePath}.tsx`,
147
+ path.join(basePath, "src", `${themeFileName}.ts`),
148
+ path.join(basePath, `${themeFileName}.ts`),
149
+ path.join(basePath, "src", "index.ts"),
150
+ path.join(basePath, "index.ts")
151
+ ];
152
+ for (const candidate of candidates) {
153
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
154
+ return candidate;
155
+ }
156
+ }
157
+ return null;
158
+ }
159
+ function analyzeBaseTheme2(varName) {
160
+ const importInfo = imports.get(varName);
161
+ if (!importInfo) {
162
+ log(`Could not find import for base theme: ${varName}`);
163
+ return;
164
+ }
165
+ log(`Analyzing base theme '${varName}' from '${importInfo.source}'`);
166
+ const resolvedBase = resolveImportPath(importInfo.source, resolvedPath);
167
+ if (!resolvedBase) {
168
+ log(`Could not resolve import path: ${importInfo.source}`);
169
+ return;
170
+ }
171
+ const preferDark = varName.toLowerCase().includes("dark");
172
+ const themeFile = findThemeFile(resolvedBase, preferDark);
173
+ if (!themeFile) {
174
+ log(`Could not find theme file for: ${resolvedBase}`);
175
+ return;
176
+ }
177
+ if (ctx.analyzedFiles.has(themeFile)) {
178
+ log(`Already analyzed: ${themeFile}`);
179
+ return;
180
+ }
181
+ ctx.analyzedFiles.add(themeFile);
182
+ log(`Recursively analyzing: ${themeFile}`);
183
+ const baseValues = analyzeThemeSource(themeFile, { verbose, aliases });
184
+ mergeThemeValues(values, baseValues, false);
185
+ }
186
+ function traceBuilderCalls(node, calls = []) {
187
+ if (!ts.isPropertyAccessExpression(node.expression)) {
188
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
189
+ const fnName = node.expression.text;
190
+ if (fnName === "fromTheme" && node.arguments.length > 0) {
191
+ const arg = node.arguments[0];
192
+ if (ts.isIdentifier(arg)) {
193
+ return { calls, baseThemeVar: arg.text };
194
+ }
195
+ }
196
+ }
197
+ return { calls, baseThemeVar: null };
198
+ }
199
+ const methodName = node.expression.name.text;
200
+ calls.unshift({ method: methodName, args: node.arguments });
201
+ const obj = node.expression.expression;
202
+ if (ts.isCallExpression(obj)) {
203
+ return traceBuilderCalls(obj, calls);
204
+ }
205
+ return { calls, baseThemeVar: null };
206
+ }
207
+ function getStringValue2(node) {
208
+ if (!node) return null;
209
+ if (ts.isStringLiteral(node)) return node.text;
210
+ if (ts.isIdentifier(node)) return node.text;
211
+ if (ts.isNoSubstitutionTemplateLiteral(node)) return node.text;
212
+ return null;
213
+ }
214
+ function getObjectKeys2(node) {
215
+ return node.properties.filter((prop) => ts.isPropertyAssignment(prop)).map((prop) => {
216
+ if (ts.isIdentifier(prop.name)) return prop.name.text;
217
+ if (ts.isStringLiteral(prop.name)) return prop.name.text;
218
+ return null;
219
+ }).filter((k) => k !== null);
220
+ }
221
+ function processCalls(calls) {
222
+ log(`Processing ${calls.length} builder method calls`);
223
+ for (const { method, args } of calls) {
224
+ switch (method) {
225
+ case "addIntent": {
226
+ const name = getStringValue2(args[0]);
227
+ if (name && !values.intents.includes(name)) {
228
+ values.intents.push(name);
229
+ log(` Found intent: ${name}`);
230
+ }
231
+ break;
232
+ }
233
+ case "addRadius": {
234
+ const name = getStringValue2(args[0]);
235
+ if (name && !values.radii.includes(name)) {
236
+ values.radii.push(name);
237
+ log(` Found radius: ${name}`);
238
+ }
239
+ break;
240
+ }
241
+ case "addShadow": {
242
+ const name = getStringValue2(args[0]);
243
+ if (name && !values.shadows.includes(name)) {
244
+ values.shadows.push(name);
245
+ log(` Found shadow: ${name}`);
246
+ }
247
+ break;
248
+ }
249
+ case "addBreakpoint": {
250
+ const name = getStringValue2(args[0]);
251
+ if (name && !values.breakpoints.includes(name)) {
252
+ values.breakpoints.push(name);
253
+ log(` Found breakpoint: ${name}`);
254
+ }
255
+ break;
256
+ }
257
+ case "setBreakpoints": {
258
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
259
+ const keys = getObjectKeys2(args[0]);
260
+ for (const key of keys) {
261
+ if (!values.breakpoints.includes(key)) {
262
+ values.breakpoints.push(key);
263
+ }
264
+ }
265
+ log(` Found breakpoints: ${values.breakpoints.join(", ")}`);
266
+ }
267
+ break;
268
+ }
269
+ case "setSizes": {
270
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
271
+ for (const prop of args[0].properties) {
272
+ if (ts.isPropertyAssignment(prop)) {
273
+ let componentName = null;
274
+ if (ts.isIdentifier(prop.name)) {
275
+ componentName = prop.name.text;
276
+ } else if (ts.isStringLiteral(prop.name)) {
277
+ componentName = prop.name.text;
278
+ }
279
+ if (componentName && ts.isObjectLiteralExpression(prop.initializer)) {
280
+ const sizeKeys = getObjectKeys2(prop.initializer);
281
+ values.sizes[componentName] = sizeKeys;
282
+ log(` Found sizes for ${componentName}: ${sizeKeys.join(", ")}`);
283
+ if (componentName === "typography") {
284
+ for (const key of sizeKeys) {
285
+ if (!values.typography.includes(key)) {
286
+ values.typography.push(key);
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+ }
293
+ } else if (args[0] && ts.isPropertyAccessExpression(args[0])) {
294
+ const propAccess = args[0];
295
+ if (ts.isIdentifier(propAccess.expression) && propAccess.name.text === "sizes") {
296
+ const themeVarName = propAccess.expression.text;
297
+ log(` Found sizes reference: ${themeVarName}.sizes`);
298
+ const importInfo = imports.get(themeVarName);
299
+ if (importInfo) {
300
+ log(` Resolving sizes from imported theme: ${importInfo.source}`);
301
+ const resolvedBase = resolveImportPath(importInfo.source, resolvedPath);
302
+ if (resolvedBase) {
303
+ const preferDark = themeVarName.toLowerCase().includes("dark");
304
+ const themeFile = findThemeFile(resolvedBase, preferDark);
305
+ if (themeFile && !ctx.analyzedFiles.has(themeFile)) {
306
+ ctx.analyzedFiles.add(themeFile);
307
+ const baseValues = analyzeThemeSource(themeFile, { verbose, aliases });
308
+ for (const [comp, sizes] of Object.entries(baseValues.sizes)) {
309
+ if (!values.sizes[comp]) {
310
+ values.sizes[comp] = sizes;
311
+ log(` Inherited sizes for ${comp}: ${sizes.join(", ")}`);
312
+ }
313
+ }
314
+ for (const typo of baseValues.typography) {
315
+ if (!values.typography.includes(typo)) {
316
+ values.typography.push(typo);
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ break;
325
+ }
326
+ case "setColors": {
327
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
328
+ for (const prop of args[0].properties) {
329
+ if (ts.isPropertyAssignment(prop)) {
330
+ let colorType = null;
331
+ if (ts.isIdentifier(prop.name)) {
332
+ colorType = prop.name.text;
333
+ } else if (ts.isStringLiteral(prop.name)) {
334
+ colorType = prop.name.text;
335
+ }
336
+ if (colorType && ts.isObjectLiteralExpression(prop.initializer)) {
337
+ const colorKeys = getObjectKeys2(prop.initializer);
338
+ switch (colorType) {
339
+ case "surface":
340
+ values.surfaceColors = colorKeys;
341
+ log(` Found surface colors: ${colorKeys.join(", ")}`);
342
+ break;
343
+ case "text":
344
+ values.textColors = colorKeys;
345
+ log(` Found text colors: ${colorKeys.join(", ")}`);
346
+ break;
347
+ case "border":
348
+ values.borderColors = colorKeys;
349
+ log(` Found border colors: ${colorKeys.join(", ")}`);
350
+ break;
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ break;
357
+ }
358
+ case "build":
359
+ break;
360
+ default:
361
+ log(` Skipping unknown method: ${method}`);
362
+ }
363
+ }
364
+ }
100
365
  function processBuilderChain(node) {
101
366
  if (!ts.isCallExpression(node)) return;
102
- if (ts.isPropertyAccessExpression(node.expression)) {
367
+ if (ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "build") {
368
+ log("Found .build() call, tracing chain...");
369
+ const { calls, baseThemeVar } = traceBuilderCalls(node);
370
+ if (baseThemeVar) {
371
+ log(`Found fromTheme(${baseThemeVar})`);
372
+ analyzeBaseTheme2(baseThemeVar);
373
+ }
374
+ processCalls(calls);
375
+ return;
376
+ }
377
+ ts.forEachChild(node, processBuilderChain);
378
+ }
379
+ ts.forEachChild(sourceFile, (node) => {
380
+ if (ts.isVariableStatement(node)) {
381
+ for (const decl of node.declarationList.declarations) {
382
+ if (decl.initializer) {
383
+ processBuilderChain(decl.initializer);
384
+ }
385
+ }
386
+ }
387
+ if (ts.isExportAssignment(node)) {
388
+ processBuilderChain(node.expression);
389
+ }
390
+ });
391
+ log("Analysis complete:");
392
+ log(` Intents: ${values.intents.join(", ")}`);
393
+ log(` Radii: ${values.radii.join(", ")}`);
394
+ log(` Shadows: ${values.shadows.join(", ")}`);
395
+ log(` Breakpoints: ${values.breakpoints.join(", ")}`);
396
+ log(` Typography: ${values.typography.join(", ")}`);
397
+ log(` Size components: ${Object.keys(values.sizes).join(", ")}`);
398
+ return values;
399
+ }
400
+ function mergeThemeValues(target, source, sourceOverrides) {
401
+ const mergeArrays = (targetArr, sourceArr) => {
402
+ for (const item of sourceArr) {
403
+ if (!targetArr.includes(item)) {
404
+ targetArr.push(item);
405
+ }
406
+ }
407
+ };
408
+ mergeArrays(target.intents, source.intents);
409
+ mergeArrays(target.radii, source.radii);
410
+ mergeArrays(target.shadows, source.shadows);
411
+ mergeArrays(target.breakpoints, source.breakpoints);
412
+ mergeArrays(target.typography, source.typography);
413
+ mergeArrays(target.surfaceColors, source.surfaceColors);
414
+ mergeArrays(target.textColors, source.textColors);
415
+ mergeArrays(target.borderColors, source.borderColors);
416
+ for (const [component, sizes] of Object.entries(source.sizes)) {
417
+ if (sourceOverrides || !target.sizes[component]) {
418
+ target.sizes[component] = sizes;
419
+ }
420
+ }
421
+ }
422
+
423
+ // src/analyzer/theme-analyzer.ts
424
+ function analyzeTheme(themePath, verbose = false) {
425
+ const resolvedPath = path2.resolve(themePath);
426
+ if (!fs2.existsSync(resolvedPath)) {
427
+ throw new Error(`Theme file not found: ${resolvedPath}`);
428
+ }
429
+ const log = (...args) => {
430
+ if (verbose) console.log("[theme-analyzer]", ...args);
431
+ };
432
+ log("Analyzing theme file:", resolvedPath);
433
+ const program = ts2.createProgram([resolvedPath], {
434
+ target: ts2.ScriptTarget.ES2020,
435
+ module: ts2.ModuleKind.ESNext,
436
+ strict: true,
437
+ esModuleInterop: true,
438
+ skipLibCheck: true,
439
+ allowSyntheticDefaultImports: true
440
+ });
441
+ const sourceFile = program.getSourceFile(resolvedPath);
442
+ if (!sourceFile) {
443
+ throw new Error(`Failed to parse theme file: ${resolvedPath}`);
444
+ }
445
+ const ctx = {
446
+ program,
447
+ typeChecker: program.getTypeChecker(),
448
+ verbose
449
+ };
450
+ const values = {
451
+ intents: [],
452
+ sizes: {},
453
+ radii: [],
454
+ shadows: [],
455
+ breakpoints: [],
456
+ typography: [],
457
+ surfaceColors: [],
458
+ textColors: [],
459
+ borderColors: []
460
+ };
461
+ const imports = /* @__PURE__ */ new Map();
462
+ ts2.forEachChild(sourceFile, (node) => {
463
+ if (ts2.isImportDeclaration(node)) {
464
+ const source = node.moduleSpecifier.text;
465
+ const clause = node.importClause;
466
+ if (clause?.namedBindings && ts2.isNamedImports(clause.namedBindings)) {
467
+ for (const element of clause.namedBindings.elements) {
468
+ const localName = element.name.text;
469
+ const importedName = element.propertyName?.text ?? localName;
470
+ imports.set(localName, { source, imported: importedName });
471
+ }
472
+ }
473
+ }
474
+ });
475
+ function processBuilderChain(node) {
476
+ if (!ts2.isCallExpression(node)) return;
477
+ if (ts2.isPropertyAccessExpression(node.expression)) {
103
478
  const methodName = node.expression.name.text;
104
479
  if (methodName === "build") {
105
480
  const calls = traceBuilderCalls(node);
@@ -107,15 +482,15 @@ function analyzeTheme(themePath, verbose = false) {
107
482
  return;
108
483
  }
109
484
  }
110
- ts.forEachChild(node, processBuilderChain);
485
+ ts2.forEachChild(node, processBuilderChain);
111
486
  }
112
487
  function traceBuilderCalls(node, calls = []) {
113
- if (!ts.isPropertyAccessExpression(node.expression)) {
114
- if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
488
+ if (!ts2.isPropertyAccessExpression(node.expression)) {
489
+ if (ts2.isCallExpression(node) && ts2.isIdentifier(node.expression)) {
115
490
  const fnName = node.expression.text;
116
491
  if (fnName === "fromTheme" && node.arguments.length > 0) {
117
492
  const arg = node.arguments[0];
118
- if (ts.isIdentifier(arg)) {
493
+ if (ts2.isIdentifier(arg)) {
119
494
  analyzeBaseTheme(arg.text, imports, values, ctx);
120
495
  }
121
496
  }
@@ -125,7 +500,7 @@ function analyzeTheme(themePath, verbose = false) {
125
500
  const methodName = node.expression.name.text;
126
501
  calls.unshift({ method: methodName, args: node.arguments });
127
502
  const obj = node.expression.expression;
128
- if (ts.isCallExpression(obj)) {
503
+ if (ts2.isCallExpression(obj)) {
129
504
  return traceBuilderCalls(obj, calls);
130
505
  }
131
506
  return calls;
@@ -159,11 +534,11 @@ function analyzeTheme(themePath, verbose = false) {
159
534
  break;
160
535
  }
161
536
  case "setSizes": {
162
- if (args[0] && ts.isObjectLiteralExpression(args[0])) {
537
+ if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
163
538
  for (const prop of args[0].properties) {
164
- if (ts.isPropertyAssignment(prop)) {
539
+ if (ts2.isPropertyAssignment(prop)) {
165
540
  const componentName = getPropertyName(prop.name);
166
- if (componentName && ts.isObjectLiteralExpression(prop.initializer)) {
541
+ if (componentName && ts2.isObjectLiteralExpression(prop.initializer)) {
167
542
  values.sizes[componentName] = getObjectKeys(prop.initializer);
168
543
  log(" Found sizes for", componentName + ":", values.sizes[componentName]);
169
544
  }
@@ -173,18 +548,18 @@ function analyzeTheme(themePath, verbose = false) {
173
548
  break;
174
549
  }
175
550
  case "setBreakpoints": {
176
- if (args[0] && ts.isObjectLiteralExpression(args[0])) {
551
+ if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
177
552
  values.breakpoints = getObjectKeys(args[0]);
178
553
  log(" Found breakpoints:", values.breakpoints);
179
554
  }
180
555
  break;
181
556
  }
182
557
  case "setColors": {
183
- if (args[0] && ts.isObjectLiteralExpression(args[0])) {
558
+ if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
184
559
  for (const prop of args[0].properties) {
185
- if (ts.isPropertyAssignment(prop)) {
560
+ if (ts2.isPropertyAssignment(prop)) {
186
561
  const colorType = getPropertyName(prop.name);
187
- if (ts.isObjectLiteralExpression(prop.initializer)) {
562
+ if (ts2.isObjectLiteralExpression(prop.initializer)) {
188
563
  const keys = getObjectKeys(prop.initializer);
189
564
  switch (colorType) {
190
565
  case "surface":
@@ -213,15 +588,15 @@ function analyzeTheme(themePath, verbose = false) {
213
588
  }
214
589
  }
215
590
  }
216
- ts.forEachChild(sourceFile, (node) => {
217
- if (ts.isVariableStatement(node)) {
591
+ ts2.forEachChild(sourceFile, (node) => {
592
+ if (ts2.isVariableStatement(node)) {
218
593
  for (const decl of node.declarationList.declarations) {
219
594
  if (decl.initializer) {
220
595
  processBuilderChain(decl.initializer);
221
596
  }
222
597
  }
223
598
  }
224
- if (ts.isExportAssignment(node)) {
599
+ if (ts2.isExportAssignment(node)) {
225
600
  processBuilderChain(node.expression);
226
601
  }
227
602
  });
@@ -242,9 +617,30 @@ function analyzeBaseTheme(varName, imports, values, ctx) {
242
617
  }
243
618
  log("Base theme", varName, "imported from", importInfo.source);
244
619
  if (importInfo.source === "@idealyst/theme" || importInfo.source.includes("@idealyst/theme")) {
245
- const defaultValues = getDefaultThemeValues();
246
- mergeThemeValues(values, defaultValues);
620
+ const aliasPath = packageAliases["@idealyst/theme"];
621
+ if (aliasPath) {
622
+ const themeFileName = varName.toLowerCase().includes("dark") ? "darkTheme.ts" : "lightTheme.ts";
623
+ const themePath = path2.join(aliasPath, "src", themeFileName);
624
+ if (fs2.existsSync(themePath)) {
625
+ log(`Analyzing @idealyst/theme from source: ${themePath}`);
626
+ try {
627
+ const sourceValues = analyzeThemeSource(themePath, {
628
+ verbose: ctx.verbose,
629
+ aliases: packageAliases
630
+ });
631
+ mergeThemeValues2(values, sourceValues);
632
+ log("Successfully extracted values from source");
633
+ return;
634
+ } catch (err) {
635
+ log("Failed to analyze source, falling back to defaults:", err.message);
636
+ }
637
+ } else {
638
+ log(`Theme file not found at alias path: ${themePath}`);
639
+ }
640
+ }
247
641
  log("Using default @idealyst/theme values");
642
+ const defaultValues = getDefaultThemeValues();
643
+ mergeThemeValues2(values, defaultValues);
248
644
  return;
249
645
  }
250
646
  log("Skipping base theme analysis for:", importInfo.source);
@@ -254,6 +650,7 @@ function getDefaultThemeValues() {
254
650
  intents: ["primary", "success", "danger", "warning", "neutral", "info"],
255
651
  sizes: {
256
652
  button: ["xs", "sm", "md", "lg", "xl"],
653
+ iconButton: ["xs", "sm", "md", "lg", "xl"],
257
654
  chip: ["xs", "sm", "md", "lg", "xl"],
258
655
  badge: ["xs", "sm", "md", "lg", "xl"],
259
656
  icon: ["xs", "sm", "md", "lg", "xl"],
@@ -267,6 +664,7 @@ function getDefaultThemeValues() {
267
664
  progress: ["xs", "sm", "md", "lg", "xl"],
268
665
  accordion: ["xs", "sm", "md", "lg", "xl"],
269
666
  activityIndicator: ["xs", "sm", "md", "lg", "xl"],
667
+ alert: ["xs", "sm", "md", "lg", "xl"],
270
668
  breadcrumb: ["xs", "sm", "md", "lg", "xl"],
271
669
  list: ["xs", "sm", "md", "lg", "xl"],
272
670
  menu: ["xs", "sm", "md", "lg", "xl"],
@@ -287,7 +685,7 @@ function getDefaultThemeValues() {
287
685
  borderColors: ["primary", "secondary", "tertiary", "disabled"]
288
686
  };
289
687
  }
290
- function mergeThemeValues(target, source) {
688
+ function mergeThemeValues2(target, source) {
291
689
  target.intents.push(...source.intents.filter((k) => !target.intents.includes(k)));
292
690
  target.radii.push(...source.radii.filter((k) => !target.radii.includes(k)));
293
691
  target.shadows.push(...source.shadows.filter((k) => !target.shadows.includes(k)));
@@ -304,18 +702,19 @@ function mergeThemeValues(target, source) {
304
702
  }
305
703
  function getStringValue(node) {
306
704
  if (!node) return null;
307
- if (ts.isStringLiteral(node)) return node.text;
308
- if (ts.isIdentifier(node)) return node.text;
705
+ if (ts2.isStringLiteral(node)) return node.text;
706
+ if (ts2.isIdentifier(node)) return node.text;
309
707
  return null;
310
708
  }
311
709
  function getPropertyName(node) {
312
- if (ts.isIdentifier(node)) return node.text;
313
- if (ts.isStringLiteral(node)) return node.text;
710
+ if (ts2.isIdentifier(node)) return node.text;
711
+ if (ts2.isStringLiteral(node)) return node.text;
314
712
  return null;
315
713
  }
316
714
  function getObjectKeys(node) {
317
- return node.properties.filter(ts.isPropertyAssignment).map((prop) => getPropertyName(prop.name)).filter((k) => k !== null);
715
+ return node.properties.filter(ts2.isPropertyAssignment).map((prop) => getPropertyName(prop.name)).filter((k) => k !== null);
318
716
  }
717
+ var packageAliases = {};
319
718
 
320
719
  // src/analyzer/component-analyzer.ts
321
720
  function analyzeComponents(options) {
@@ -323,14 +722,14 @@ function analyzeComponents(options) {
323
722
  const registry = {};
324
723
  const themeValues = analyzeTheme(themePath, false);
325
724
  for (const componentPath of componentPaths) {
326
- const resolvedPath = path2.resolve(componentPath);
327
- if (!fs2.existsSync(resolvedPath)) {
725
+ const resolvedPath = path3.resolve(componentPath);
726
+ if (!fs3.existsSync(resolvedPath)) {
328
727
  console.warn(`[component-analyzer] Path not found: ${resolvedPath}`);
329
728
  continue;
330
729
  }
331
730
  const componentDirs = findComponentDirs(resolvedPath);
332
731
  for (const dir of componentDirs) {
333
- const componentName = path2.basename(dir);
732
+ const componentName = path3.basename(dir);
334
733
  if (include && !include.includes(componentName)) continue;
335
734
  if (exclude && exclude.includes(componentName)) continue;
336
735
  if (!includeInternal && componentName.startsWith("_")) continue;
@@ -344,12 +743,12 @@ function analyzeComponents(options) {
344
743
  }
345
744
  function findComponentDirs(basePath) {
346
745
  const dirs = [];
347
- const entries = fs2.readdirSync(basePath, { withFileTypes: true });
746
+ const entries = fs3.readdirSync(basePath, { withFileTypes: true });
348
747
  for (const entry of entries) {
349
748
  if (!entry.isDirectory()) continue;
350
- const dirPath = path2.join(basePath, entry.name);
351
- const hasIndex = fs2.existsSync(path2.join(dirPath, "index.ts"));
352
- const hasTypes = fs2.existsSync(path2.join(dirPath, "types.ts"));
749
+ const dirPath = path3.join(basePath, entry.name);
750
+ const hasIndex = fs3.existsSync(path3.join(dirPath, "index.ts"));
751
+ const hasTypes = fs3.existsSync(path3.join(dirPath, "types.ts"));
353
752
  if (hasIndex || hasTypes) {
354
753
  dirs.push(dirPath);
355
754
  }
@@ -357,14 +756,14 @@ function findComponentDirs(basePath) {
357
756
  return dirs;
358
757
  }
359
758
  function analyzeComponentDir(dir, componentName, themeValues) {
360
- const tsFiles = fs2.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx")).map((f) => path2.join(dir, f));
759
+ const tsFiles = fs3.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx")).map((f) => path3.join(dir, f));
361
760
  if (tsFiles.length === 0) {
362
761
  return null;
363
762
  }
364
- const program = ts2.createProgram(tsFiles, {
365
- target: ts2.ScriptTarget.ES2020,
366
- module: ts2.ModuleKind.ESNext,
367
- jsx: ts2.JsxEmit.React,
763
+ const program = ts3.createProgram(tsFiles, {
764
+ target: ts3.ScriptTarget.ES2020,
765
+ module: ts3.ModuleKind.ESNext,
766
+ jsx: ts3.JsxEmit.React,
368
767
  strict: true,
369
768
  esModuleInterop: true,
370
769
  skipLibCheck: true
@@ -377,12 +776,12 @@ function analyzeComponentDir(dir, componentName, themeValues) {
377
776
  for (const filePath of tsFiles) {
378
777
  const sourceFile = program.getSourceFile(filePath);
379
778
  if (!sourceFile) continue;
380
- ts2.forEachChild(sourceFile, (node) => {
381
- if (ts2.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
779
+ ts3.forEachChild(sourceFile, (node) => {
780
+ if (ts3.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
382
781
  propsInterface = node;
383
782
  interfaceDescription = getJSDocDescription(node);
384
783
  }
385
- if (ts2.isTypeAliasDeclaration(node) && node.name.text === propsInterfaceName) {
784
+ if (ts3.isTypeAliasDeclaration(node) && node.name.text === propsInterfaceName) {
386
785
  propsInterface = node;
387
786
  interfaceDescription = getJSDocDescription(node);
388
787
  }
@@ -394,8 +793,8 @@ function analyzeComponentDir(dir, componentName, themeValues) {
394
793
  for (const filePath of tsFiles) {
395
794
  const sourceFile = program.getSourceFile(filePath);
396
795
  if (!sourceFile) continue;
397
- ts2.forEachChild(sourceFile, (node) => {
398
- if ((ts2.isInterfaceDeclaration(node) || ts2.isTypeAliasDeclaration(node)) && node.name.text === altName) {
796
+ ts3.forEachChild(sourceFile, (node) => {
797
+ if ((ts3.isInterfaceDeclaration(node) || ts3.isTypeAliasDeclaration(node)) && node.name.text === altName) {
399
798
  propsInterface = node;
400
799
  interfaceDescription = getJSDocDescription(node);
401
800
  }
@@ -427,32 +826,32 @@ function analyzeComponentDir(dir, componentName, themeValues) {
427
826
  description,
428
827
  props,
429
828
  category,
430
- filePath: path2.relative(process.cwd(), dir),
829
+ filePath: path3.relative(process.cwd(), dir),
431
830
  sampleProps
432
831
  };
433
832
  }
434
833
  function extractSampleProps(dir) {
435
- const docsPath = path2.join(dir, "docs.ts");
436
- if (!fs2.existsSync(docsPath)) {
834
+ const docsPath = path3.join(dir, "docs.ts");
835
+ if (!fs3.existsSync(docsPath)) {
437
836
  return void 0;
438
837
  }
439
838
  try {
440
- const content = fs2.readFileSync(docsPath, "utf-8");
441
- const sourceFile = ts2.createSourceFile(
839
+ const content = fs3.readFileSync(docsPath, "utf-8");
840
+ const sourceFile = ts3.createSourceFile(
442
841
  "docs.ts",
443
842
  content,
444
- ts2.ScriptTarget.ES2020,
843
+ ts3.ScriptTarget.ES2020,
445
844
  true,
446
- ts2.ScriptKind.TS
845
+ ts3.ScriptKind.TS
447
846
  );
448
847
  let samplePropsNode = null;
449
- ts2.forEachChild(sourceFile, (node) => {
450
- if (ts2.isVariableStatement(node)) {
451
- const isExported = node.modifiers?.some((m) => m.kind === ts2.SyntaxKind.ExportKeyword);
848
+ ts3.forEachChild(sourceFile, (node) => {
849
+ if (ts3.isVariableStatement(node)) {
850
+ const isExported = node.modifiers?.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
452
851
  if (isExported) {
453
852
  for (const decl of node.declarationList.declarations) {
454
- if (ts2.isIdentifier(decl.name) && decl.name.text === "sampleProps" && decl.initializer) {
455
- if (ts2.isObjectLiteralExpression(decl.initializer)) {
853
+ if (ts3.isIdentifier(decl.name) && decl.name.text === "sampleProps" && decl.initializer) {
854
+ if (ts3.isObjectLiteralExpression(decl.initializer)) {
456
855
  samplePropsNode = decl.initializer;
457
856
  }
458
857
  }
@@ -466,13 +865,13 @@ function extractSampleProps(dir) {
466
865
  const result = {};
467
866
  const propsNode = samplePropsNode;
468
867
  for (const prop of propsNode.properties) {
469
- if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
868
+ if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
470
869
  const propName = prop.name.text;
471
- if (propName === "props" && ts2.isObjectLiteralExpression(prop.initializer)) {
870
+ if (propName === "props" && ts3.isObjectLiteralExpression(prop.initializer)) {
472
871
  result.props = extractObjectLiteral(prop.initializer, content);
473
872
  } else if (propName === "children") {
474
873
  result.children = prop.initializer.getText(sourceFile);
475
- } else if (propName === "state" && ts2.isObjectLiteralExpression(prop.initializer)) {
874
+ } else if (propName === "state" && ts3.isObjectLiteralExpression(prop.initializer)) {
476
875
  result.state = extractObjectLiteral(prop.initializer, content);
477
876
  }
478
877
  }
@@ -486,20 +885,20 @@ function extractSampleProps(dir) {
486
885
  function extractObjectLiteral(node, sourceContent) {
487
886
  const result = {};
488
887
  for (const prop of node.properties) {
489
- if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
888
+ if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
490
889
  const key = prop.name.text;
491
890
  const init = prop.initializer;
492
- if (ts2.isStringLiteral(init)) {
891
+ if (ts3.isStringLiteral(init)) {
493
892
  result[key] = init.text;
494
- } else if (ts2.isNumericLiteral(init)) {
893
+ } else if (ts3.isNumericLiteral(init)) {
495
894
  result[key] = Number(init.text);
496
- } else if (init.kind === ts2.SyntaxKind.TrueKeyword) {
895
+ } else if (init.kind === ts3.SyntaxKind.TrueKeyword) {
497
896
  result[key] = true;
498
- } else if (init.kind === ts2.SyntaxKind.FalseKeyword) {
897
+ } else if (init.kind === ts3.SyntaxKind.FalseKeyword) {
499
898
  result[key] = false;
500
- } else if (ts2.isArrayLiteralExpression(init)) {
899
+ } else if (ts3.isArrayLiteralExpression(init)) {
501
900
  result[key] = extractArrayLiteral(init, sourceContent);
502
- } else if (ts2.isObjectLiteralExpression(init)) {
901
+ } else if (ts3.isObjectLiteralExpression(init)) {
503
902
  result[key] = extractObjectLiteral(init, sourceContent);
504
903
  } else {
505
904
  result[key] = init.getText();
@@ -511,17 +910,17 @@ function extractObjectLiteral(node, sourceContent) {
511
910
  function extractArrayLiteral(node, sourceContent) {
512
911
  const result = [];
513
912
  for (const element of node.elements) {
514
- if (ts2.isStringLiteral(element)) {
913
+ if (ts3.isStringLiteral(element)) {
515
914
  result.push(element.text);
516
- } else if (ts2.isNumericLiteral(element)) {
915
+ } else if (ts3.isNumericLiteral(element)) {
517
916
  result.push(Number(element.text));
518
- } else if (element.kind === ts2.SyntaxKind.TrueKeyword) {
917
+ } else if (element.kind === ts3.SyntaxKind.TrueKeyword) {
519
918
  result.push(true);
520
- } else if (element.kind === ts2.SyntaxKind.FalseKeyword) {
919
+ } else if (element.kind === ts3.SyntaxKind.FalseKeyword) {
521
920
  result.push(false);
522
- } else if (ts2.isObjectLiteralExpression(element)) {
921
+ } else if (ts3.isObjectLiteralExpression(element)) {
523
922
  result.push(extractObjectLiteral(element, sourceContent));
524
- } else if (ts2.isArrayLiteralExpression(element)) {
923
+ } else if (ts3.isArrayLiteralExpression(element)) {
525
924
  result.push(extractArrayLiteral(element, sourceContent));
526
925
  } else {
527
926
  result.push(element.getText());
@@ -536,8 +935,8 @@ function analyzeProperty(symbol, typeChecker, themeValues) {
536
935
  const declaration = declarations[0];
537
936
  const type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration);
538
937
  const typeString = typeChecker.typeToString(type);
539
- const description = ts2.displayPartsToString(symbol.getDocumentationComment(typeChecker)) || void 0;
540
- const required = !(symbol.flags & ts2.SymbolFlags.Optional);
938
+ const description = ts3.displayPartsToString(symbol.getDocumentationComment(typeChecker)) || void 0;
939
+ const required = !(symbol.flags & ts3.SymbolFlags.Optional);
541
940
  const values = extractPropValues(type, typeString, typeChecker, themeValues);
542
941
  const defaultValue = extractDefaultValue(symbol);
543
942
  return {
@@ -578,7 +977,7 @@ function extractDefaultValue(symbol) {
578
977
  const tags = symbol.getJsDocTags();
579
978
  for (const tag of tags) {
580
979
  if (tag.name === "default" && tag.text) {
581
- const value = ts2.displayPartsToString(tag.text);
980
+ const value = ts3.displayPartsToString(tag.text);
582
981
  try {
583
982
  return JSON.parse(value);
584
983
  } catch {
@@ -698,11 +1097,11 @@ function idealystDocsPlugin(options) {
698
1097
  log("Components found:", Object.keys(registry));
699
1098
  }
700
1099
  if (output === "file" && outputPath) {
701
- const outputDir = path3.dirname(outputPath);
702
- if (!fs3.existsSync(outputDir)) {
703
- fs3.mkdirSync(outputDir, { recursive: true });
1100
+ const outputDir = path4.dirname(outputPath);
1101
+ if (!fs4.existsSync(outputDir)) {
1102
+ fs4.mkdirSync(outputDir, { recursive: true });
704
1103
  }
705
- fs3.writeFileSync(
1104
+ fs4.writeFileSync(
706
1105
  outputPath,
707
1106
  `// Auto-generated by @idealyst/tooling - DO NOT EDIT
708
1107
  export const componentRegistry = ${JSON.stringify(registry, null, 2)} as const;
@@ -773,8 +1172,8 @@ export const componentRegistry = ${JSON.stringify(registry, null, 2)} as const;
773
1172
  },
774
1173
  // Regenerate on component file changes
775
1174
  handleHotUpdate({ file, server }) {
776
- const isComponentFile = options.componentPaths.some((p) => file.includes(path3.resolve(p))) && (file.endsWith(".ts") || file.endsWith(".tsx"));
777
- const isThemeFile = file.includes(path3.resolve(options.themePath));
1175
+ const isComponentFile = options.componentPaths.some((p) => file.includes(path4.resolve(p))) && (file.endsWith(".ts") || file.endsWith(".tsx"));
1176
+ const isThemeFile = file.includes(path4.resolve(options.themePath));
778
1177
  if (isComponentFile || isThemeFile) {
779
1178
  log(`File changed: ${file}, regenerating registry...`);
780
1179
  registry = null;