@idealyst/tooling 1.2.25 → 1.2.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,802 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/vite-plugin.ts
31
+ var vite_plugin_exports = {};
32
+ __export(vite_plugin_exports, {
33
+ generateComponentRegistry: () => generateComponentRegistry,
34
+ idealystDocsPlugin: () => idealystDocsPlugin
35
+ });
36
+ module.exports = __toCommonJS(vite_plugin_exports);
37
+ var fs3 = __toESM(require("fs"), 1);
38
+ var path3 = __toESM(require("path"), 1);
39
+
40
+ // src/analyzer/component-analyzer.ts
41
+ var ts2 = __toESM(require("typescript"), 1);
42
+ var fs2 = __toESM(require("fs"), 1);
43
+ var path2 = __toESM(require("path"), 1);
44
+
45
+ // src/analyzer/theme-analyzer.ts
46
+ var ts = __toESM(require("typescript"), 1);
47
+ var fs = __toESM(require("fs"), 1);
48
+ var path = __toESM(require("path"), 1);
49
+ function analyzeTheme(themePath, verbose = false) {
50
+ const resolvedPath = path.resolve(themePath);
51
+ if (!fs.existsSync(resolvedPath)) {
52
+ throw new Error(`Theme file not found: ${resolvedPath}`);
53
+ }
54
+ const log = (...args) => {
55
+ if (verbose) console.log("[theme-analyzer]", ...args);
56
+ };
57
+ log("Analyzing theme file:", resolvedPath);
58
+ const program = ts.createProgram([resolvedPath], {
59
+ target: ts.ScriptTarget.ES2020,
60
+ module: ts.ModuleKind.ESNext,
61
+ strict: true,
62
+ esModuleInterop: true,
63
+ skipLibCheck: true,
64
+ allowSyntheticDefaultImports: true
65
+ });
66
+ const sourceFile = program.getSourceFile(resolvedPath);
67
+ if (!sourceFile) {
68
+ throw new Error(`Failed to parse theme file: ${resolvedPath}`);
69
+ }
70
+ const ctx = {
71
+ program,
72
+ typeChecker: program.getTypeChecker(),
73
+ verbose
74
+ };
75
+ const values = {
76
+ intents: [],
77
+ sizes: {},
78
+ radii: [],
79
+ shadows: [],
80
+ breakpoints: [],
81
+ typography: [],
82
+ surfaceColors: [],
83
+ textColors: [],
84
+ borderColors: []
85
+ };
86
+ const imports = /* @__PURE__ */ new Map();
87
+ ts.forEachChild(sourceFile, (node) => {
88
+ if (ts.isImportDeclaration(node)) {
89
+ const source = node.moduleSpecifier.text;
90
+ const clause = node.importClause;
91
+ if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
92
+ for (const element of clause.namedBindings.elements) {
93
+ const localName = element.name.text;
94
+ const importedName = element.propertyName?.text ?? localName;
95
+ imports.set(localName, { source, imported: importedName });
96
+ }
97
+ }
98
+ }
99
+ });
100
+ function processBuilderChain(node) {
101
+ if (!ts.isCallExpression(node)) return;
102
+ if (ts.isPropertyAccessExpression(node.expression)) {
103
+ const methodName = node.expression.name.text;
104
+ if (methodName === "build") {
105
+ const calls = traceBuilderCalls(node);
106
+ processCalls(calls);
107
+ return;
108
+ }
109
+ }
110
+ ts.forEachChild(node, processBuilderChain);
111
+ }
112
+ function traceBuilderCalls(node, calls = []) {
113
+ if (!ts.isPropertyAccessExpression(node.expression)) {
114
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
115
+ const fnName = node.expression.text;
116
+ if (fnName === "fromTheme" && node.arguments.length > 0) {
117
+ const arg = node.arguments[0];
118
+ if (ts.isIdentifier(arg)) {
119
+ analyzeBaseTheme(arg.text, imports, values, ctx);
120
+ }
121
+ }
122
+ }
123
+ return calls;
124
+ }
125
+ const methodName = node.expression.name.text;
126
+ calls.unshift({ method: methodName, args: node.arguments });
127
+ const obj = node.expression.expression;
128
+ if (ts.isCallExpression(obj)) {
129
+ return traceBuilderCalls(obj, calls);
130
+ }
131
+ return calls;
132
+ }
133
+ function processCalls(calls) {
134
+ log("Processing", calls.length, "builder method calls");
135
+ for (const { method, args } of calls) {
136
+ switch (method) {
137
+ case "addIntent": {
138
+ const name = getStringValue(args[0]);
139
+ if (name && !values.intents.includes(name)) {
140
+ values.intents.push(name);
141
+ log(" Found intent:", name);
142
+ }
143
+ break;
144
+ }
145
+ case "addRadius": {
146
+ const name = getStringValue(args[0]);
147
+ if (name && !values.radii.includes(name)) {
148
+ values.radii.push(name);
149
+ log(" Found radius:", name);
150
+ }
151
+ break;
152
+ }
153
+ case "addShadow": {
154
+ const name = getStringValue(args[0]);
155
+ if (name && !values.shadows.includes(name)) {
156
+ values.shadows.push(name);
157
+ log(" Found shadow:", name);
158
+ }
159
+ break;
160
+ }
161
+ case "setSizes": {
162
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
163
+ for (const prop of args[0].properties) {
164
+ if (ts.isPropertyAssignment(prop)) {
165
+ const componentName = getPropertyName(prop.name);
166
+ if (componentName && ts.isObjectLiteralExpression(prop.initializer)) {
167
+ values.sizes[componentName] = getObjectKeys(prop.initializer);
168
+ log(" Found sizes for", componentName + ":", values.sizes[componentName]);
169
+ }
170
+ }
171
+ }
172
+ }
173
+ break;
174
+ }
175
+ case "setBreakpoints": {
176
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
177
+ values.breakpoints = getObjectKeys(args[0]);
178
+ log(" Found breakpoints:", values.breakpoints);
179
+ }
180
+ break;
181
+ }
182
+ case "setColors": {
183
+ if (args[0] && ts.isObjectLiteralExpression(args[0])) {
184
+ for (const prop of args[0].properties) {
185
+ if (ts.isPropertyAssignment(prop)) {
186
+ const colorType = getPropertyName(prop.name);
187
+ if (ts.isObjectLiteralExpression(prop.initializer)) {
188
+ const keys = getObjectKeys(prop.initializer);
189
+ switch (colorType) {
190
+ case "surface":
191
+ values.surfaceColors = keys;
192
+ log(" Found surface colors:", keys);
193
+ break;
194
+ case "text":
195
+ values.textColors = keys;
196
+ log(" Found text colors:", keys);
197
+ break;
198
+ case "border":
199
+ values.borderColors = keys;
200
+ log(" Found border colors:", keys);
201
+ break;
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ break;
208
+ }
209
+ case "build":
210
+ break;
211
+ default:
212
+ log(" Skipping unknown method:", method);
213
+ }
214
+ }
215
+ }
216
+ ts.forEachChild(sourceFile, (node) => {
217
+ if (ts.isVariableStatement(node)) {
218
+ for (const decl of node.declarationList.declarations) {
219
+ if (decl.initializer) {
220
+ processBuilderChain(decl.initializer);
221
+ }
222
+ }
223
+ }
224
+ if (ts.isExportAssignment(node)) {
225
+ processBuilderChain(node.expression);
226
+ }
227
+ });
228
+ if (values.sizes["typography"]) {
229
+ values.typography = values.sizes["typography"];
230
+ }
231
+ log("Extracted theme values:", values);
232
+ return values;
233
+ }
234
+ function analyzeBaseTheme(varName, imports, values, ctx) {
235
+ const log = (...args) => {
236
+ if (ctx.verbose) console.log("[theme-analyzer]", ...args);
237
+ };
238
+ const importInfo = imports.get(varName);
239
+ if (!importInfo) {
240
+ log("Could not find import for base theme:", varName);
241
+ return;
242
+ }
243
+ log("Base theme", varName, "imported from", importInfo.source);
244
+ if (importInfo.source === "@idealyst/theme" || importInfo.source.includes("@idealyst/theme")) {
245
+ const defaultValues = getDefaultThemeValues();
246
+ mergeThemeValues(values, defaultValues);
247
+ log("Using default @idealyst/theme values");
248
+ return;
249
+ }
250
+ log("Skipping base theme analysis for:", importInfo.source);
251
+ }
252
+ function getDefaultThemeValues() {
253
+ return {
254
+ intents: ["primary", "success", "error", "warning", "neutral", "info"],
255
+ sizes: {
256
+ button: ["xs", "sm", "md", "lg", "xl"],
257
+ chip: ["xs", "sm", "md", "lg", "xl"],
258
+ badge: ["xs", "sm", "md", "lg", "xl"],
259
+ icon: ["xs", "sm", "md", "lg", "xl"],
260
+ input: ["xs", "sm", "md", "lg", "xl"],
261
+ radioButton: ["xs", "sm", "md", "lg", "xl"],
262
+ select: ["xs", "sm", "md", "lg", "xl"],
263
+ slider: ["xs", "sm", "md", "lg", "xl"],
264
+ switch: ["xs", "sm", "md", "lg", "xl"],
265
+ textarea: ["xs", "sm", "md", "lg", "xl"],
266
+ avatar: ["xs", "sm", "md", "lg", "xl"],
267
+ progress: ["xs", "sm", "md", "lg", "xl"],
268
+ accordion: ["xs", "sm", "md", "lg", "xl"],
269
+ activityIndicator: ["xs", "sm", "md", "lg", "xl"],
270
+ breadcrumb: ["xs", "sm", "md", "lg", "xl"],
271
+ list: ["xs", "sm", "md", "lg", "xl"],
272
+ menu: ["xs", "sm", "md", "lg", "xl"],
273
+ text: ["xs", "sm", "md", "lg", "xl"],
274
+ tabBar: ["xs", "sm", "md", "lg", "xl"],
275
+ table: ["xs", "sm", "md", "lg", "xl"],
276
+ tooltip: ["xs", "sm", "md", "lg", "xl"],
277
+ view: ["xs", "sm", "md", "lg", "xl"],
278
+ // Typography sizes for Text component's $typography iterator
279
+ typography: ["h1", "h2", "h3", "h4", "h5", "h6", "subtitle1", "subtitle2", "body1", "body2", "caption"]
280
+ },
281
+ radii: ["none", "xs", "sm", "md", "lg", "xl"],
282
+ shadows: ["none", "sm", "md", "lg", "xl"],
283
+ breakpoints: ["xs", "sm", "md", "lg", "xl"],
284
+ typography: ["h1", "h2", "h3", "h4", "h5", "h6", "subtitle1", "subtitle2", "body1", "body2", "caption"],
285
+ surfaceColors: ["screen", "primary", "secondary", "tertiary", "inverse", "inverse-secondary", "inverse-tertiary"],
286
+ textColors: ["primary", "secondary", "tertiary", "inverse", "inverse-secondary", "inverse-tertiary"],
287
+ borderColors: ["primary", "secondary", "tertiary", "disabled"]
288
+ };
289
+ }
290
+ function mergeThemeValues(target, source) {
291
+ target.intents.push(...source.intents.filter((k) => !target.intents.includes(k)));
292
+ target.radii.push(...source.radii.filter((k) => !target.radii.includes(k)));
293
+ target.shadows.push(...source.shadows.filter((k) => !target.shadows.includes(k)));
294
+ target.breakpoints.push(...source.breakpoints.filter((k) => !target.breakpoints.includes(k)));
295
+ target.typography.push(...source.typography.filter((k) => !target.typography.includes(k)));
296
+ target.surfaceColors.push(...source.surfaceColors.filter((k) => !target.surfaceColors.includes(k)));
297
+ target.textColors.push(...source.textColors.filter((k) => !target.textColors.includes(k)));
298
+ target.borderColors.push(...source.borderColors.filter((k) => !target.borderColors.includes(k)));
299
+ for (const [comp, sizes] of Object.entries(source.sizes)) {
300
+ if (!target.sizes[comp]) {
301
+ target.sizes[comp] = sizes;
302
+ }
303
+ }
304
+ }
305
+ function getStringValue(node) {
306
+ if (!node) return null;
307
+ if (ts.isStringLiteral(node)) return node.text;
308
+ if (ts.isIdentifier(node)) return node.text;
309
+ return null;
310
+ }
311
+ function getPropertyName(node) {
312
+ if (ts.isIdentifier(node)) return node.text;
313
+ if (ts.isStringLiteral(node)) return node.text;
314
+ return null;
315
+ }
316
+ function getObjectKeys(node) {
317
+ return node.properties.filter(ts.isPropertyAssignment).map((prop) => getPropertyName(prop.name)).filter((k) => k !== null);
318
+ }
319
+
320
+ // src/analyzer/component-analyzer.ts
321
+ function analyzeComponents(options) {
322
+ const { componentPaths, themePath, include, exclude, includeInternal = false } = options;
323
+ const registry = {};
324
+ const themeValues = analyzeTheme(themePath, false);
325
+ for (const componentPath of componentPaths) {
326
+ const resolvedPath = path2.resolve(componentPath);
327
+ if (!fs2.existsSync(resolvedPath)) {
328
+ console.warn(`[component-analyzer] Path not found: ${resolvedPath}`);
329
+ continue;
330
+ }
331
+ const componentDirs = findComponentDirs(resolvedPath);
332
+ for (const dir of componentDirs) {
333
+ const componentName = path2.basename(dir);
334
+ if (include && !include.includes(componentName)) continue;
335
+ if (exclude && exclude.includes(componentName)) continue;
336
+ if (!includeInternal && componentName.startsWith("_")) continue;
337
+ const definition = analyzeComponentDir(dir, componentName, themeValues);
338
+ if (definition) {
339
+ registry[componentName] = definition;
340
+ }
341
+ }
342
+ }
343
+ return registry;
344
+ }
345
+ function findComponentDirs(basePath) {
346
+ const dirs = [];
347
+ const entries = fs2.readdirSync(basePath, { withFileTypes: true });
348
+ for (const entry of entries) {
349
+ 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"));
353
+ if (hasIndex || hasTypes) {
354
+ dirs.push(dirPath);
355
+ }
356
+ }
357
+ return dirs;
358
+ }
359
+ 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));
361
+ if (tsFiles.length === 0) {
362
+ return null;
363
+ }
364
+ const program = ts2.createProgram(tsFiles, {
365
+ target: ts2.ScriptTarget.ES2020,
366
+ module: ts2.ModuleKind.ESNext,
367
+ jsx: ts2.JsxEmit.React,
368
+ strict: true,
369
+ esModuleInterop: true,
370
+ skipLibCheck: true
371
+ });
372
+ const typeChecker = program.getTypeChecker();
373
+ const propsInterfaceName = `${componentName}Props`;
374
+ const altNames = [`${componentName}ComponentProps`, "Props"];
375
+ let propsInterface = null;
376
+ let interfaceDescription;
377
+ for (const filePath of tsFiles) {
378
+ const sourceFile = program.getSourceFile(filePath);
379
+ if (!sourceFile) continue;
380
+ ts2.forEachChild(sourceFile, (node) => {
381
+ if (ts2.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
382
+ propsInterface = node;
383
+ interfaceDescription = getJSDocDescription(node);
384
+ }
385
+ if (ts2.isTypeAliasDeclaration(node) && node.name.text === propsInterfaceName) {
386
+ propsInterface = node;
387
+ interfaceDescription = getJSDocDescription(node);
388
+ }
389
+ });
390
+ if (propsInterface) break;
391
+ }
392
+ if (!propsInterface) {
393
+ for (const altName of altNames) {
394
+ for (const filePath of tsFiles) {
395
+ const sourceFile = program.getSourceFile(filePath);
396
+ if (!sourceFile) continue;
397
+ ts2.forEachChild(sourceFile, (node) => {
398
+ if ((ts2.isInterfaceDeclaration(node) || ts2.isTypeAliasDeclaration(node)) && node.name.text === altName) {
399
+ propsInterface = node;
400
+ interfaceDescription = getJSDocDescription(node);
401
+ }
402
+ });
403
+ if (propsInterface) break;
404
+ }
405
+ if (propsInterface) break;
406
+ }
407
+ }
408
+ if (!propsInterface) {
409
+ return null;
410
+ }
411
+ const props = {};
412
+ if (propsInterface) {
413
+ const type = typeChecker.getTypeAtLocation(propsInterface);
414
+ const properties = type.getProperties();
415
+ for (const prop of properties) {
416
+ const propDef = analyzeProperty(prop, typeChecker, themeValues);
417
+ if (propDef && !isInternalProp(propDef.name)) {
418
+ props[propDef.name] = propDef;
419
+ }
420
+ }
421
+ }
422
+ const description = interfaceDescription;
423
+ const category = inferCategory(componentName);
424
+ const sampleProps = extractSampleProps(dir);
425
+ return {
426
+ name: componentName,
427
+ description,
428
+ props,
429
+ category,
430
+ filePath: path2.relative(process.cwd(), dir),
431
+ sampleProps
432
+ };
433
+ }
434
+ function extractSampleProps(dir) {
435
+ const docsPath = path2.join(dir, "docs.ts");
436
+ if (!fs2.existsSync(docsPath)) {
437
+ return void 0;
438
+ }
439
+ try {
440
+ const content = fs2.readFileSync(docsPath, "utf-8");
441
+ const sourceFile = ts2.createSourceFile(
442
+ "docs.ts",
443
+ content,
444
+ ts2.ScriptTarget.ES2020,
445
+ true,
446
+ ts2.ScriptKind.TS
447
+ );
448
+ 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);
452
+ if (isExported) {
453
+ 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)) {
456
+ samplePropsNode = decl.initializer;
457
+ }
458
+ }
459
+ }
460
+ }
461
+ }
462
+ });
463
+ if (!samplePropsNode) {
464
+ return void 0;
465
+ }
466
+ const result = {};
467
+ const propsNode = samplePropsNode;
468
+ for (const prop of propsNode.properties) {
469
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
470
+ const propName = prop.name.text;
471
+ if (propName === "props" && ts2.isObjectLiteralExpression(prop.initializer)) {
472
+ result.props = extractObjectLiteral(prop.initializer, content);
473
+ } else if (propName === "children") {
474
+ result.children = prop.initializer.getText(sourceFile);
475
+ } else if (propName === "state" && ts2.isObjectLiteralExpression(prop.initializer)) {
476
+ result.state = extractObjectLiteral(prop.initializer, content);
477
+ }
478
+ }
479
+ }
480
+ return Object.keys(result).length > 0 ? result : void 0;
481
+ } catch (e) {
482
+ console.warn(`[component-analyzer] Error reading docs.ts in ${dir}:`, e);
483
+ return void 0;
484
+ }
485
+ }
486
+ function extractObjectLiteral(node, sourceContent) {
487
+ const result = {};
488
+ for (const prop of node.properties) {
489
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
490
+ const key = prop.name.text;
491
+ const init = prop.initializer;
492
+ if (ts2.isStringLiteral(init)) {
493
+ result[key] = init.text;
494
+ } else if (ts2.isNumericLiteral(init)) {
495
+ result[key] = Number(init.text);
496
+ } else if (init.kind === ts2.SyntaxKind.TrueKeyword) {
497
+ result[key] = true;
498
+ } else if (init.kind === ts2.SyntaxKind.FalseKeyword) {
499
+ result[key] = false;
500
+ } else if (ts2.isArrayLiteralExpression(init)) {
501
+ result[key] = extractArrayLiteral(init, sourceContent);
502
+ } else if (ts2.isObjectLiteralExpression(init)) {
503
+ result[key] = extractObjectLiteral(init, sourceContent);
504
+ } else {
505
+ result[key] = init.getText();
506
+ }
507
+ }
508
+ }
509
+ return result;
510
+ }
511
+ function extractArrayLiteral(node, sourceContent) {
512
+ const result = [];
513
+ for (const element of node.elements) {
514
+ if (ts2.isStringLiteral(element)) {
515
+ result.push(element.text);
516
+ } else if (ts2.isNumericLiteral(element)) {
517
+ result.push(Number(element.text));
518
+ } else if (element.kind === ts2.SyntaxKind.TrueKeyword) {
519
+ result.push(true);
520
+ } else if (element.kind === ts2.SyntaxKind.FalseKeyword) {
521
+ result.push(false);
522
+ } else if (ts2.isObjectLiteralExpression(element)) {
523
+ result.push(extractObjectLiteral(element, sourceContent));
524
+ } else if (ts2.isArrayLiteralExpression(element)) {
525
+ result.push(extractArrayLiteral(element, sourceContent));
526
+ } else {
527
+ result.push(element.getText());
528
+ }
529
+ }
530
+ return result;
531
+ }
532
+ function analyzeProperty(symbol, typeChecker, themeValues) {
533
+ const name = symbol.getName();
534
+ const declarations = symbol.getDeclarations();
535
+ if (!declarations || declarations.length === 0) return null;
536
+ const declaration = declarations[0];
537
+ const type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration);
538
+ const typeString = typeChecker.typeToString(type);
539
+ const description = ts2.displayPartsToString(symbol.getDocumentationComment(typeChecker)) || void 0;
540
+ const required = !(symbol.flags & ts2.SymbolFlags.Optional);
541
+ const values = extractPropValues(type, typeString, typeChecker, themeValues);
542
+ const defaultValue = extractDefaultValue(symbol);
543
+ return {
544
+ name,
545
+ type: simplifyTypeName(typeString),
546
+ values: values.length > 0 ? values : void 0,
547
+ default: defaultValue,
548
+ description,
549
+ required
550
+ };
551
+ }
552
+ function extractPropValues(type, typeString, _typeChecker, themeValues) {
553
+ if (typeString === "Intent" || typeString.includes("Intent")) {
554
+ return themeValues.intents;
555
+ }
556
+ if (typeString === "Size" || typeString.includes("Size")) {
557
+ return ["xs", "sm", "md", "lg", "xl"];
558
+ }
559
+ if (type.isUnion()) {
560
+ const values = [];
561
+ for (const unionType of type.types) {
562
+ if (unionType.isStringLiteral()) {
563
+ values.push(unionType.value);
564
+ } else if (unionType.intrinsicName === "true") {
565
+ values.push("true");
566
+ } else if (unionType.intrinsicName === "false") {
567
+ values.push("false");
568
+ }
569
+ }
570
+ if (values.length > 0) return values;
571
+ }
572
+ if (typeString === "boolean") {
573
+ return ["true", "false"];
574
+ }
575
+ return [];
576
+ }
577
+ function extractDefaultValue(symbol) {
578
+ const tags = symbol.getJsDocTags();
579
+ for (const tag of tags) {
580
+ if (tag.name === "default" && tag.text) {
581
+ const value = ts2.displayPartsToString(tag.text);
582
+ try {
583
+ return JSON.parse(value);
584
+ } catch {
585
+ return value;
586
+ }
587
+ }
588
+ }
589
+ return void 0;
590
+ }
591
+ function getJSDocDescription(node) {
592
+ const jsDocs = node.jsDoc;
593
+ if (!jsDocs || jsDocs.length === 0) return void 0;
594
+ const firstDoc = jsDocs[0];
595
+ if (firstDoc.comment) {
596
+ if (typeof firstDoc.comment === "string") {
597
+ return firstDoc.comment;
598
+ }
599
+ return firstDoc.comment.map((c) => c.text || "").join("");
600
+ }
601
+ return void 0;
602
+ }
603
+ function simplifyTypeName(typeString) {
604
+ typeString = typeString.replace(/import\([^)]+\)\./g, "");
605
+ if (typeString.includes("ReactNode")) return "ReactNode";
606
+ if (typeString.includes("StyleProp")) return "Style";
607
+ return typeString;
608
+ }
609
+ function isInternalProp(name) {
610
+ const internalProps = [
611
+ "ref",
612
+ "key",
613
+ "children",
614
+ "style",
615
+ "testID",
616
+ "nativeID",
617
+ "accessible",
618
+ "accessibilityActions",
619
+ "accessibilityComponentType",
620
+ "accessibilityElementsHidden",
621
+ "accessibilityHint",
622
+ "accessibilityIgnoresInvertColors",
623
+ "accessibilityLabel",
624
+ "accessibilityLabelledBy",
625
+ "accessibilityLanguage",
626
+ "accessibilityLiveRegion",
627
+ "accessibilityRole",
628
+ "accessibilityState",
629
+ "accessibilityTraits",
630
+ "accessibilityValue",
631
+ "accessibilityViewIsModal",
632
+ "collapsable",
633
+ "focusable",
634
+ "hasTVPreferredFocus",
635
+ "hitSlop",
636
+ "importantForAccessibility",
637
+ "needsOffscreenAlphaCompositing",
638
+ "onAccessibilityAction",
639
+ "onAccessibilityEscape",
640
+ "onAccessibilityTap",
641
+ "onLayout",
642
+ "onMagicTap",
643
+ "onMoveShouldSetResponder",
644
+ "onMoveShouldSetResponderCapture",
645
+ "onResponderEnd",
646
+ "onResponderGrant",
647
+ "onResponderMove",
648
+ "onResponderReject",
649
+ "onResponderRelease",
650
+ "onResponderStart",
651
+ "onResponderTerminate",
652
+ "onResponderTerminationRequest",
653
+ "onStartShouldSetResponder",
654
+ "onStartShouldSetResponderCapture",
655
+ "pointerEvents",
656
+ "removeClippedSubviews",
657
+ "renderToHardwareTextureAndroid",
658
+ "shouldRasterizeIOS",
659
+ "tvParallaxMagnification",
660
+ "tvParallaxProperties",
661
+ "tvParallaxShiftDistanceX",
662
+ "tvParallaxShiftDistanceY",
663
+ "tvParallaxTiltAngle"
664
+ ];
665
+ return internalProps.includes(name) || name.startsWith("accessibility");
666
+ }
667
+ function inferCategory(componentName) {
668
+ const formComponents = ["Button", "Input", "Checkbox", "Select", "Switch", "RadioButton", "Slider", "TextArea"];
669
+ const displayComponents = ["Text", "Card", "Badge", "Chip", "Avatar", "Icon", "Skeleton", "Alert", "Tooltip"];
670
+ const layoutComponents = ["View", "Screen", "Divider"];
671
+ const navigationComponents = ["TabBar", "Breadcrumb", "Menu", "List", "Link"];
672
+ const overlayComponents = ["Dialog", "Popover", "Modal"];
673
+ const dataComponents = ["Table", "Progress", "Accordion"];
674
+ if (formComponents.includes(componentName)) return "form";
675
+ if (displayComponents.includes(componentName)) return "display";
676
+ if (layoutComponents.includes(componentName)) return "layout";
677
+ if (navigationComponents.includes(componentName)) return "navigation";
678
+ if (overlayComponents.includes(componentName)) return "overlay";
679
+ if (dataComponents.includes(componentName)) return "data";
680
+ return "display";
681
+ }
682
+
683
+ // src/vite-plugin.ts
684
+ function idealystDocsPlugin(options) {
685
+ let registry = null;
686
+ const { debug = false, output, outputPath } = options;
687
+ const log = (...args) => {
688
+ if (debug) console.log("[idealyst-docs]", ...args);
689
+ };
690
+ function generateRegistry() {
691
+ log("Generating component registry...");
692
+ log("Component paths:", options.componentPaths);
693
+ log("Theme path:", options.themePath);
694
+ try {
695
+ registry = analyzeComponents(options);
696
+ log(`Generated registry with ${Object.keys(registry).length} components`);
697
+ if (debug) {
698
+ log("Components found:", Object.keys(registry));
699
+ }
700
+ if (output === "file" && outputPath) {
701
+ const outputDir = path3.dirname(outputPath);
702
+ if (!fs3.existsSync(outputDir)) {
703
+ fs3.mkdirSync(outputDir, { recursive: true });
704
+ }
705
+ fs3.writeFileSync(
706
+ outputPath,
707
+ `// Auto-generated by @idealyst/tooling - DO NOT EDIT
708
+ export const componentRegistry = ${JSON.stringify(registry, null, 2)} as const;
709
+ `
710
+ );
711
+ log(`Wrote registry to ${outputPath}`);
712
+ }
713
+ return registry;
714
+ } catch (error) {
715
+ console.error("[idealyst-docs] Error generating registry:", error);
716
+ return {};
717
+ }
718
+ }
719
+ return {
720
+ name: "idealyst-docs",
721
+ // Transform @idealyst/tooling to inject the actual registry
722
+ transform(code, id) {
723
+ const isToolingIndex = id.includes("@idealyst/tooling") && id.endsWith("index.ts");
724
+ const isToolingSrc = id.includes("/packages/tooling/src/index.ts");
725
+ if (isToolingIndex || isToolingSrc) {
726
+ console.log(`[idealyst-docs] Transforming tooling index: ${id}`);
727
+ if (!registry) {
728
+ registry = generateRegistry();
729
+ }
730
+ let transformed = code;
731
+ transformed = transformed.replace(
732
+ /export const componentRegistry\s*=\s*\{\s*\};?/,
733
+ `export const componentRegistry = ${JSON.stringify(registry, null, 2)};`
734
+ );
735
+ log(`Code transformed: ${code !== transformed}`);
736
+ transformed = transformed.replace(
737
+ /export const componentNames\s*=\s*\[\s*\];?/,
738
+ `export const componentNames = ${JSON.stringify(Object.keys(registry))};`
739
+ );
740
+ transformed = transformed.replace(
741
+ /export function getComponentsByCategory\(category\)\s*\{[\s\S]*?^\}/m,
742
+ `export function getComponentsByCategory(category) {
743
+ return Object.entries(componentRegistry)
744
+ .filter(([_, def]) => def.category === category)
745
+ .map(([name]) => name);
746
+ }`
747
+ );
748
+ transformed = transformed.replace(
749
+ /export function getPropConfig\(componentName\)\s*\{[\s\S]*?^\}/m,
750
+ `export function getPropConfig(componentName) {
751
+ const def = componentRegistry[componentName];
752
+ if (!def) return {};
753
+ return Object.entries(def.props).reduce((acc, [key, prop]) => {
754
+ if (prop.values && prop.values.length > 0) {
755
+ acc[key] = { type: 'select', options: prop.values, default: prop.default };
756
+ } else if (prop.type === 'boolean') {
757
+ acc[key] = { type: 'boolean', default: prop.default ?? false };
758
+ } else if (prop.type === 'string') {
759
+ acc[key] = { type: 'text', default: prop.default ?? '' };
760
+ } else if (prop.type === 'number') {
761
+ acc[key] = { type: 'number', default: prop.default ?? 0 };
762
+ }
763
+ return acc;
764
+ }, {});
765
+ }`
766
+ );
767
+ return {
768
+ code: transformed,
769
+ map: null
770
+ };
771
+ }
772
+ return null;
773
+ },
774
+ // Regenerate on component file changes
775
+ 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));
778
+ if (isComponentFile || isThemeFile) {
779
+ log(`File changed: ${file}, regenerating registry...`);
780
+ registry = null;
781
+ const toolingMods = Array.from(server.moduleGraph.idToModuleMap.values()).filter((m) => m.id && (m.id.includes("@idealyst/tooling") || m.id.includes("/packages/tooling/src/index")));
782
+ toolingMods.forEach((m) => server.moduleGraph.invalidateModule(m));
783
+ if (toolingMods.length > 0) {
784
+ return toolingMods;
785
+ }
786
+ }
787
+ },
788
+ // Generate on build
789
+ buildStart() {
790
+ registry = generateRegistry();
791
+ }
792
+ };
793
+ }
794
+ function generateComponentRegistry(options) {
795
+ return analyzeComponents(options);
796
+ }
797
+ // Annotate the CommonJS export names for ESM import in node:
798
+ 0 && (module.exports = {
799
+ generateComponentRegistry,
800
+ idealystDocsPlugin
801
+ });
802
+ //# sourceMappingURL=vite-plugin.cjs.map