@idealyst/tooling 1.2.29 → 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.
- package/dist/analyzer/index.cjs +522 -85
- package/dist/analyzer/index.cjs.map +1 -1
- package/dist/analyzer/index.d.cts +21 -44
- package/dist/analyzer/index.d.ts +21 -44
- package/dist/analyzer/index.js +526 -84
- package/dist/analyzer/index.js.map +1 -1
- package/dist/index.cjs +528 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +535 -104
- package/dist/index.js.map +1 -1
- package/dist/theme-analyzer-C1lprK5o.d.cts +66 -0
- package/dist/theme-analyzer-vmhko10Q.d.ts +66 -0
- package/dist/{types-CrlxbLFJ.d.cts → types-CnxJMLD8.d.cts} +1 -1
- package/dist/{types-CrlxbLFJ.d.ts → types-CnxJMLD8.d.ts} +1 -1
- package/dist/vite-plugin.cjs +488 -89
- package/dist/vite-plugin.cjs.map +1 -1
- package/dist/vite-plugin.d.cts +1 -1
- package/dist/vite-plugin.d.ts +1 -1
- package/dist/vite-plugin.js +495 -89
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -80,31 +80,49 @@ __export(src_exports, {
|
|
|
80
80
|
module.exports = __toCommonJS(src_exports);
|
|
81
81
|
|
|
82
82
|
// src/analyzer/component-analyzer.ts
|
|
83
|
+
var ts3 = __toESM(require("typescript"), 1);
|
|
84
|
+
var fs3 = __toESM(require("fs"), 1);
|
|
85
|
+
var path3 = __toESM(require("path"), 1);
|
|
86
|
+
|
|
87
|
+
// src/analyzer/theme-analyzer.ts
|
|
83
88
|
var ts2 = __toESM(require("typescript"), 1);
|
|
84
89
|
var fs2 = __toESM(require("fs"), 1);
|
|
85
90
|
var path2 = __toESM(require("path"), 1);
|
|
86
91
|
|
|
87
|
-
// src/analyzer/theme-analyzer.ts
|
|
92
|
+
// src/analyzer/theme-source-analyzer.ts
|
|
88
93
|
var ts = __toESM(require("typescript"), 1);
|
|
89
94
|
var fs = __toESM(require("fs"), 1);
|
|
90
95
|
var path = __toESM(require("path"), 1);
|
|
91
|
-
function
|
|
96
|
+
function analyzeThemeSource(themePath, options = {}) {
|
|
92
97
|
const resolvedPath = path.resolve(themePath);
|
|
98
|
+
const verbose = options.verbose ?? false;
|
|
99
|
+
const aliases = options.aliases ?? {};
|
|
100
|
+
const log = (...args) => {
|
|
101
|
+
if (verbose) console.log("[theme-source-analyzer]", ...args);
|
|
102
|
+
};
|
|
93
103
|
if (!fs.existsSync(resolvedPath)) {
|
|
94
104
|
throw new Error(`Theme file not found: ${resolvedPath}`);
|
|
95
105
|
}
|
|
96
|
-
const log = (...args) => {
|
|
97
|
-
if (verbose) console.log("[theme-analyzer]", ...args);
|
|
98
|
-
};
|
|
99
106
|
log("Analyzing theme file:", resolvedPath);
|
|
100
|
-
const
|
|
107
|
+
const configPath = ts.findConfigFile(path.dirname(resolvedPath), ts.sys.fileExists, "tsconfig.json");
|
|
108
|
+
let compilerOptions = {
|
|
101
109
|
target: ts.ScriptTarget.ES2020,
|
|
102
110
|
module: ts.ModuleKind.ESNext,
|
|
111
|
+
moduleResolution: ts.ModuleResolutionKind.Node10,
|
|
103
112
|
strict: true,
|
|
104
113
|
esModuleInterop: true,
|
|
105
114
|
skipLibCheck: true,
|
|
106
|
-
allowSyntheticDefaultImports: true
|
|
107
|
-
|
|
115
|
+
allowSyntheticDefaultImports: true,
|
|
116
|
+
resolveJsonModule: true
|
|
117
|
+
};
|
|
118
|
+
if (configPath) {
|
|
119
|
+
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
120
|
+
if (!configFile.error) {
|
|
121
|
+
const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
|
|
122
|
+
compilerOptions = { ...compilerOptions, ...parsed.options };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const program = ts.createProgram([resolvedPath], compilerOptions);
|
|
108
126
|
const sourceFile = program.getSourceFile(resolvedPath);
|
|
109
127
|
if (!sourceFile) {
|
|
110
128
|
throw new Error(`Failed to parse theme file: ${resolvedPath}`);
|
|
@@ -112,7 +130,9 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
112
130
|
const ctx = {
|
|
113
131
|
program,
|
|
114
132
|
typeChecker: program.getTypeChecker(),
|
|
115
|
-
verbose
|
|
133
|
+
verbose,
|
|
134
|
+
aliases,
|
|
135
|
+
analyzedFiles: /* @__PURE__ */ new Set([resolvedPath])
|
|
116
136
|
};
|
|
117
137
|
const values = {
|
|
118
138
|
intents: [],
|
|
@@ -135,13 +155,368 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
135
155
|
const localName = element.name.text;
|
|
136
156
|
const importedName = element.propertyName?.text ?? localName;
|
|
137
157
|
imports.set(localName, { source, imported: importedName });
|
|
158
|
+
log(` Import: ${localName} from '${source}'`);
|
|
138
159
|
}
|
|
139
160
|
}
|
|
140
161
|
}
|
|
141
162
|
});
|
|
163
|
+
function resolveImportPath(source, fromFile) {
|
|
164
|
+
for (const [aliasPrefix, aliasPath] of Object.entries(ctx.aliases)) {
|
|
165
|
+
if (source === aliasPrefix || source.startsWith(aliasPrefix + "/")) {
|
|
166
|
+
const remainder = source.slice(aliasPrefix.length);
|
|
167
|
+
let resolved = aliasPath + remainder;
|
|
168
|
+
if (!path.isAbsolute(resolved)) {
|
|
169
|
+
resolved = path.resolve(path.dirname(fromFile), resolved);
|
|
170
|
+
}
|
|
171
|
+
return resolved;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (source.startsWith(".")) {
|
|
175
|
+
return path.resolve(path.dirname(fromFile), source);
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
return require.resolve(source, { paths: [path.dirname(fromFile)] });
|
|
179
|
+
} catch {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function findThemeFile(basePath, preferDark) {
|
|
184
|
+
const themeFileName = preferDark ? "darkTheme" : "lightTheme";
|
|
185
|
+
const candidates = [
|
|
186
|
+
basePath,
|
|
187
|
+
`${basePath}.ts`,
|
|
188
|
+
`${basePath}.tsx`,
|
|
189
|
+
path.join(basePath, "src", `${themeFileName}.ts`),
|
|
190
|
+
path.join(basePath, `${themeFileName}.ts`),
|
|
191
|
+
path.join(basePath, "src", "index.ts"),
|
|
192
|
+
path.join(basePath, "index.ts")
|
|
193
|
+
];
|
|
194
|
+
for (const candidate of candidates) {
|
|
195
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
196
|
+
return candidate;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
function analyzeBaseTheme2(varName) {
|
|
202
|
+
const importInfo = imports.get(varName);
|
|
203
|
+
if (!importInfo) {
|
|
204
|
+
log(`Could not find import for base theme: ${varName}`);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
log(`Analyzing base theme '${varName}' from '${importInfo.source}'`);
|
|
208
|
+
const resolvedBase = resolveImportPath(importInfo.source, resolvedPath);
|
|
209
|
+
if (!resolvedBase) {
|
|
210
|
+
log(`Could not resolve import path: ${importInfo.source}`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const preferDark = varName.toLowerCase().includes("dark");
|
|
214
|
+
const themeFile = findThemeFile(resolvedBase, preferDark);
|
|
215
|
+
if (!themeFile) {
|
|
216
|
+
log(`Could not find theme file for: ${resolvedBase}`);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (ctx.analyzedFiles.has(themeFile)) {
|
|
220
|
+
log(`Already analyzed: ${themeFile}`);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
ctx.analyzedFiles.add(themeFile);
|
|
224
|
+
log(`Recursively analyzing: ${themeFile}`);
|
|
225
|
+
const baseValues = analyzeThemeSource(themeFile, { verbose, aliases });
|
|
226
|
+
mergeThemeValues(values, baseValues, false);
|
|
227
|
+
}
|
|
228
|
+
function traceBuilderCalls(node, calls = []) {
|
|
229
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
230
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
|
|
231
|
+
const fnName = node.expression.text;
|
|
232
|
+
if (fnName === "fromTheme" && node.arguments.length > 0) {
|
|
233
|
+
const arg = node.arguments[0];
|
|
234
|
+
if (ts.isIdentifier(arg)) {
|
|
235
|
+
return { calls, baseThemeVar: arg.text };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return { calls, baseThemeVar: null };
|
|
240
|
+
}
|
|
241
|
+
const methodName = node.expression.name.text;
|
|
242
|
+
calls.unshift({ method: methodName, args: node.arguments });
|
|
243
|
+
const obj = node.expression.expression;
|
|
244
|
+
if (ts.isCallExpression(obj)) {
|
|
245
|
+
return traceBuilderCalls(obj, calls);
|
|
246
|
+
}
|
|
247
|
+
return { calls, baseThemeVar: null };
|
|
248
|
+
}
|
|
249
|
+
function getStringValue2(node) {
|
|
250
|
+
if (!node) return null;
|
|
251
|
+
if (ts.isStringLiteral(node)) return node.text;
|
|
252
|
+
if (ts.isIdentifier(node)) return node.text;
|
|
253
|
+
if (ts.isNoSubstitutionTemplateLiteral(node)) return node.text;
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
function getObjectKeys2(node) {
|
|
257
|
+
return node.properties.filter((prop) => ts.isPropertyAssignment(prop)).map((prop) => {
|
|
258
|
+
if (ts.isIdentifier(prop.name)) return prop.name.text;
|
|
259
|
+
if (ts.isStringLiteral(prop.name)) return prop.name.text;
|
|
260
|
+
return null;
|
|
261
|
+
}).filter((k) => k !== null);
|
|
262
|
+
}
|
|
263
|
+
function processCalls(calls) {
|
|
264
|
+
log(`Processing ${calls.length} builder method calls`);
|
|
265
|
+
for (const { method, args } of calls) {
|
|
266
|
+
switch (method) {
|
|
267
|
+
case "addIntent": {
|
|
268
|
+
const name = getStringValue2(args[0]);
|
|
269
|
+
if (name && !values.intents.includes(name)) {
|
|
270
|
+
values.intents.push(name);
|
|
271
|
+
log(` Found intent: ${name}`);
|
|
272
|
+
}
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case "addRadius": {
|
|
276
|
+
const name = getStringValue2(args[0]);
|
|
277
|
+
if (name && !values.radii.includes(name)) {
|
|
278
|
+
values.radii.push(name);
|
|
279
|
+
log(` Found radius: ${name}`);
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case "addShadow": {
|
|
284
|
+
const name = getStringValue2(args[0]);
|
|
285
|
+
if (name && !values.shadows.includes(name)) {
|
|
286
|
+
values.shadows.push(name);
|
|
287
|
+
log(` Found shadow: ${name}`);
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case "addBreakpoint": {
|
|
292
|
+
const name = getStringValue2(args[0]);
|
|
293
|
+
if (name && !values.breakpoints.includes(name)) {
|
|
294
|
+
values.breakpoints.push(name);
|
|
295
|
+
log(` Found breakpoint: ${name}`);
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
case "setBreakpoints": {
|
|
300
|
+
if (args[0] && ts.isObjectLiteralExpression(args[0])) {
|
|
301
|
+
const keys = getObjectKeys2(args[0]);
|
|
302
|
+
for (const key of keys) {
|
|
303
|
+
if (!values.breakpoints.includes(key)) {
|
|
304
|
+
values.breakpoints.push(key);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
log(` Found breakpoints: ${values.breakpoints.join(", ")}`);
|
|
308
|
+
}
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
case "setSizes": {
|
|
312
|
+
if (args[0] && ts.isObjectLiteralExpression(args[0])) {
|
|
313
|
+
for (const prop of args[0].properties) {
|
|
314
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
315
|
+
let componentName = null;
|
|
316
|
+
if (ts.isIdentifier(prop.name)) {
|
|
317
|
+
componentName = prop.name.text;
|
|
318
|
+
} else if (ts.isStringLiteral(prop.name)) {
|
|
319
|
+
componentName = prop.name.text;
|
|
320
|
+
}
|
|
321
|
+
if (componentName && ts.isObjectLiteralExpression(prop.initializer)) {
|
|
322
|
+
const sizeKeys = getObjectKeys2(prop.initializer);
|
|
323
|
+
values.sizes[componentName] = sizeKeys;
|
|
324
|
+
log(` Found sizes for ${componentName}: ${sizeKeys.join(", ")}`);
|
|
325
|
+
if (componentName === "typography") {
|
|
326
|
+
for (const key of sizeKeys) {
|
|
327
|
+
if (!values.typography.includes(key)) {
|
|
328
|
+
values.typography.push(key);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
} else if (args[0] && ts.isPropertyAccessExpression(args[0])) {
|
|
336
|
+
const propAccess = args[0];
|
|
337
|
+
if (ts.isIdentifier(propAccess.expression) && propAccess.name.text === "sizes") {
|
|
338
|
+
const themeVarName = propAccess.expression.text;
|
|
339
|
+
log(` Found sizes reference: ${themeVarName}.sizes`);
|
|
340
|
+
const importInfo = imports.get(themeVarName);
|
|
341
|
+
if (importInfo) {
|
|
342
|
+
log(` Resolving sizes from imported theme: ${importInfo.source}`);
|
|
343
|
+
const resolvedBase = resolveImportPath(importInfo.source, resolvedPath);
|
|
344
|
+
if (resolvedBase) {
|
|
345
|
+
const preferDark = themeVarName.toLowerCase().includes("dark");
|
|
346
|
+
const themeFile = findThemeFile(resolvedBase, preferDark);
|
|
347
|
+
if (themeFile && !ctx.analyzedFiles.has(themeFile)) {
|
|
348
|
+
ctx.analyzedFiles.add(themeFile);
|
|
349
|
+
const baseValues = analyzeThemeSource(themeFile, { verbose, aliases });
|
|
350
|
+
for (const [comp, sizes] of Object.entries(baseValues.sizes)) {
|
|
351
|
+
if (!values.sizes[comp]) {
|
|
352
|
+
values.sizes[comp] = sizes;
|
|
353
|
+
log(` Inherited sizes for ${comp}: ${sizes.join(", ")}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
for (const typo of baseValues.typography) {
|
|
357
|
+
if (!values.typography.includes(typo)) {
|
|
358
|
+
values.typography.push(typo);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
case "setColors": {
|
|
369
|
+
if (args[0] && ts.isObjectLiteralExpression(args[0])) {
|
|
370
|
+
for (const prop of args[0].properties) {
|
|
371
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
372
|
+
let colorType = null;
|
|
373
|
+
if (ts.isIdentifier(prop.name)) {
|
|
374
|
+
colorType = prop.name.text;
|
|
375
|
+
} else if (ts.isStringLiteral(prop.name)) {
|
|
376
|
+
colorType = prop.name.text;
|
|
377
|
+
}
|
|
378
|
+
if (colorType && ts.isObjectLiteralExpression(prop.initializer)) {
|
|
379
|
+
const colorKeys = getObjectKeys2(prop.initializer);
|
|
380
|
+
switch (colorType) {
|
|
381
|
+
case "surface":
|
|
382
|
+
values.surfaceColors = colorKeys;
|
|
383
|
+
log(` Found surface colors: ${colorKeys.join(", ")}`);
|
|
384
|
+
break;
|
|
385
|
+
case "text":
|
|
386
|
+
values.textColors = colorKeys;
|
|
387
|
+
log(` Found text colors: ${colorKeys.join(", ")}`);
|
|
388
|
+
break;
|
|
389
|
+
case "border":
|
|
390
|
+
values.borderColors = colorKeys;
|
|
391
|
+
log(` Found border colors: ${colorKeys.join(", ")}`);
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
case "build":
|
|
401
|
+
break;
|
|
402
|
+
default:
|
|
403
|
+
log(` Skipping unknown method: ${method}`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
142
407
|
function processBuilderChain(node) {
|
|
143
408
|
if (!ts.isCallExpression(node)) return;
|
|
144
|
-
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
409
|
+
if (ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "build") {
|
|
410
|
+
log("Found .build() call, tracing chain...");
|
|
411
|
+
const { calls, baseThemeVar } = traceBuilderCalls(node);
|
|
412
|
+
if (baseThemeVar) {
|
|
413
|
+
log(`Found fromTheme(${baseThemeVar})`);
|
|
414
|
+
analyzeBaseTheme2(baseThemeVar);
|
|
415
|
+
}
|
|
416
|
+
processCalls(calls);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
ts.forEachChild(node, processBuilderChain);
|
|
420
|
+
}
|
|
421
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
422
|
+
if (ts.isVariableStatement(node)) {
|
|
423
|
+
for (const decl of node.declarationList.declarations) {
|
|
424
|
+
if (decl.initializer) {
|
|
425
|
+
processBuilderChain(decl.initializer);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (ts.isExportAssignment(node)) {
|
|
430
|
+
processBuilderChain(node.expression);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
log("Analysis complete:");
|
|
434
|
+
log(` Intents: ${values.intents.join(", ")}`);
|
|
435
|
+
log(` Radii: ${values.radii.join(", ")}`);
|
|
436
|
+
log(` Shadows: ${values.shadows.join(", ")}`);
|
|
437
|
+
log(` Breakpoints: ${values.breakpoints.join(", ")}`);
|
|
438
|
+
log(` Typography: ${values.typography.join(", ")}`);
|
|
439
|
+
log(` Size components: ${Object.keys(values.sizes).join(", ")}`);
|
|
440
|
+
return values;
|
|
441
|
+
}
|
|
442
|
+
function mergeThemeValues(target, source, sourceOverrides) {
|
|
443
|
+
const mergeArrays = (targetArr, sourceArr) => {
|
|
444
|
+
for (const item of sourceArr) {
|
|
445
|
+
if (!targetArr.includes(item)) {
|
|
446
|
+
targetArr.push(item);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
mergeArrays(target.intents, source.intents);
|
|
451
|
+
mergeArrays(target.radii, source.radii);
|
|
452
|
+
mergeArrays(target.shadows, source.shadows);
|
|
453
|
+
mergeArrays(target.breakpoints, source.breakpoints);
|
|
454
|
+
mergeArrays(target.typography, source.typography);
|
|
455
|
+
mergeArrays(target.surfaceColors, source.surfaceColors);
|
|
456
|
+
mergeArrays(target.textColors, source.textColors);
|
|
457
|
+
mergeArrays(target.borderColors, source.borderColors);
|
|
458
|
+
for (const [component, sizes] of Object.entries(source.sizes)) {
|
|
459
|
+
if (sourceOverrides || !target.sizes[component]) {
|
|
460
|
+
target.sizes[component] = sizes;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// src/analyzer/theme-analyzer.ts
|
|
466
|
+
function analyzeTheme(themePath, verbose = false) {
|
|
467
|
+
const resolvedPath = path2.resolve(themePath);
|
|
468
|
+
if (!fs2.existsSync(resolvedPath)) {
|
|
469
|
+
throw new Error(`Theme file not found: ${resolvedPath}`);
|
|
470
|
+
}
|
|
471
|
+
const log = (...args) => {
|
|
472
|
+
if (verbose) console.log("[theme-analyzer]", ...args);
|
|
473
|
+
};
|
|
474
|
+
log("Analyzing theme file:", resolvedPath);
|
|
475
|
+
const program = ts2.createProgram([resolvedPath], {
|
|
476
|
+
target: ts2.ScriptTarget.ES2020,
|
|
477
|
+
module: ts2.ModuleKind.ESNext,
|
|
478
|
+
strict: true,
|
|
479
|
+
esModuleInterop: true,
|
|
480
|
+
skipLibCheck: true,
|
|
481
|
+
allowSyntheticDefaultImports: true
|
|
482
|
+
});
|
|
483
|
+
const sourceFile = program.getSourceFile(resolvedPath);
|
|
484
|
+
if (!sourceFile) {
|
|
485
|
+
throw new Error(`Failed to parse theme file: ${resolvedPath}`);
|
|
486
|
+
}
|
|
487
|
+
const ctx = {
|
|
488
|
+
program,
|
|
489
|
+
typeChecker: program.getTypeChecker(),
|
|
490
|
+
verbose
|
|
491
|
+
};
|
|
492
|
+
const values = {
|
|
493
|
+
intents: [],
|
|
494
|
+
sizes: {},
|
|
495
|
+
radii: [],
|
|
496
|
+
shadows: [],
|
|
497
|
+
breakpoints: [],
|
|
498
|
+
typography: [],
|
|
499
|
+
surfaceColors: [],
|
|
500
|
+
textColors: [],
|
|
501
|
+
borderColors: []
|
|
502
|
+
};
|
|
503
|
+
const imports = /* @__PURE__ */ new Map();
|
|
504
|
+
ts2.forEachChild(sourceFile, (node) => {
|
|
505
|
+
if (ts2.isImportDeclaration(node)) {
|
|
506
|
+
const source = node.moduleSpecifier.text;
|
|
507
|
+
const clause = node.importClause;
|
|
508
|
+
if (clause?.namedBindings && ts2.isNamedImports(clause.namedBindings)) {
|
|
509
|
+
for (const element of clause.namedBindings.elements) {
|
|
510
|
+
const localName = element.name.text;
|
|
511
|
+
const importedName = element.propertyName?.text ?? localName;
|
|
512
|
+
imports.set(localName, { source, imported: importedName });
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
function processBuilderChain(node) {
|
|
518
|
+
if (!ts2.isCallExpression(node)) return;
|
|
519
|
+
if (ts2.isPropertyAccessExpression(node.expression)) {
|
|
145
520
|
const methodName = node.expression.name.text;
|
|
146
521
|
if (methodName === "build") {
|
|
147
522
|
const calls = traceBuilderCalls(node);
|
|
@@ -149,15 +524,15 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
149
524
|
return;
|
|
150
525
|
}
|
|
151
526
|
}
|
|
152
|
-
|
|
527
|
+
ts2.forEachChild(node, processBuilderChain);
|
|
153
528
|
}
|
|
154
529
|
function traceBuilderCalls(node, calls = []) {
|
|
155
|
-
if (!
|
|
156
|
-
if (
|
|
530
|
+
if (!ts2.isPropertyAccessExpression(node.expression)) {
|
|
531
|
+
if (ts2.isCallExpression(node) && ts2.isIdentifier(node.expression)) {
|
|
157
532
|
const fnName = node.expression.text;
|
|
158
533
|
if (fnName === "fromTheme" && node.arguments.length > 0) {
|
|
159
534
|
const arg = node.arguments[0];
|
|
160
|
-
if (
|
|
535
|
+
if (ts2.isIdentifier(arg)) {
|
|
161
536
|
analyzeBaseTheme(arg.text, imports, values, ctx);
|
|
162
537
|
}
|
|
163
538
|
}
|
|
@@ -167,7 +542,7 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
167
542
|
const methodName = node.expression.name.text;
|
|
168
543
|
calls.unshift({ method: methodName, args: node.arguments });
|
|
169
544
|
const obj = node.expression.expression;
|
|
170
|
-
if (
|
|
545
|
+
if (ts2.isCallExpression(obj)) {
|
|
171
546
|
return traceBuilderCalls(obj, calls);
|
|
172
547
|
}
|
|
173
548
|
return calls;
|
|
@@ -201,11 +576,11 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
201
576
|
break;
|
|
202
577
|
}
|
|
203
578
|
case "setSizes": {
|
|
204
|
-
if (args[0] &&
|
|
579
|
+
if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
|
|
205
580
|
for (const prop of args[0].properties) {
|
|
206
|
-
if (
|
|
581
|
+
if (ts2.isPropertyAssignment(prop)) {
|
|
207
582
|
const componentName = getPropertyName(prop.name);
|
|
208
|
-
if (componentName &&
|
|
583
|
+
if (componentName && ts2.isObjectLiteralExpression(prop.initializer)) {
|
|
209
584
|
values.sizes[componentName] = getObjectKeys(prop.initializer);
|
|
210
585
|
log(" Found sizes for", componentName + ":", values.sizes[componentName]);
|
|
211
586
|
}
|
|
@@ -215,18 +590,18 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
215
590
|
break;
|
|
216
591
|
}
|
|
217
592
|
case "setBreakpoints": {
|
|
218
|
-
if (args[0] &&
|
|
593
|
+
if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
|
|
219
594
|
values.breakpoints = getObjectKeys(args[0]);
|
|
220
595
|
log(" Found breakpoints:", values.breakpoints);
|
|
221
596
|
}
|
|
222
597
|
break;
|
|
223
598
|
}
|
|
224
599
|
case "setColors": {
|
|
225
|
-
if (args[0] &&
|
|
600
|
+
if (args[0] && ts2.isObjectLiteralExpression(args[0])) {
|
|
226
601
|
for (const prop of args[0].properties) {
|
|
227
|
-
if (
|
|
602
|
+
if (ts2.isPropertyAssignment(prop)) {
|
|
228
603
|
const colorType = getPropertyName(prop.name);
|
|
229
|
-
if (
|
|
604
|
+
if (ts2.isObjectLiteralExpression(prop.initializer)) {
|
|
230
605
|
const keys = getObjectKeys(prop.initializer);
|
|
231
606
|
switch (colorType) {
|
|
232
607
|
case "surface":
|
|
@@ -255,15 +630,15 @@ function analyzeTheme(themePath, verbose = false) {
|
|
|
255
630
|
}
|
|
256
631
|
}
|
|
257
632
|
}
|
|
258
|
-
|
|
259
|
-
if (
|
|
633
|
+
ts2.forEachChild(sourceFile, (node) => {
|
|
634
|
+
if (ts2.isVariableStatement(node)) {
|
|
260
635
|
for (const decl of node.declarationList.declarations) {
|
|
261
636
|
if (decl.initializer) {
|
|
262
637
|
processBuilderChain(decl.initializer);
|
|
263
638
|
}
|
|
264
639
|
}
|
|
265
640
|
}
|
|
266
|
-
if (
|
|
641
|
+
if (ts2.isExportAssignment(node)) {
|
|
267
642
|
processBuilderChain(node.expression);
|
|
268
643
|
}
|
|
269
644
|
});
|
|
@@ -284,18 +659,40 @@ function analyzeBaseTheme(varName, imports, values, ctx) {
|
|
|
284
659
|
}
|
|
285
660
|
log("Base theme", varName, "imported from", importInfo.source);
|
|
286
661
|
if (importInfo.source === "@idealyst/theme" || importInfo.source.includes("@idealyst/theme")) {
|
|
287
|
-
const
|
|
288
|
-
|
|
662
|
+
const aliasPath = packageAliases["@idealyst/theme"];
|
|
663
|
+
if (aliasPath) {
|
|
664
|
+
const themeFileName = varName.toLowerCase().includes("dark") ? "darkTheme.ts" : "lightTheme.ts";
|
|
665
|
+
const themePath = path2.join(aliasPath, "src", themeFileName);
|
|
666
|
+
if (fs2.existsSync(themePath)) {
|
|
667
|
+
log(`Analyzing @idealyst/theme from source: ${themePath}`);
|
|
668
|
+
try {
|
|
669
|
+
const sourceValues = analyzeThemeSource(themePath, {
|
|
670
|
+
verbose: ctx.verbose,
|
|
671
|
+
aliases: packageAliases
|
|
672
|
+
});
|
|
673
|
+
mergeThemeValues2(values, sourceValues);
|
|
674
|
+
log("Successfully extracted values from source");
|
|
675
|
+
return;
|
|
676
|
+
} catch (err) {
|
|
677
|
+
log("Failed to analyze source, falling back to defaults:", err.message);
|
|
678
|
+
}
|
|
679
|
+
} else {
|
|
680
|
+
log(`Theme file not found at alias path: ${themePath}`);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
289
683
|
log("Using default @idealyst/theme values");
|
|
684
|
+
const defaultValues = getDefaultThemeValues();
|
|
685
|
+
mergeThemeValues2(values, defaultValues);
|
|
290
686
|
return;
|
|
291
687
|
}
|
|
292
688
|
log("Skipping base theme analysis for:", importInfo.source);
|
|
293
689
|
}
|
|
294
690
|
function getDefaultThemeValues() {
|
|
295
691
|
return {
|
|
296
|
-
intents: ["primary", "success", "
|
|
692
|
+
intents: ["primary", "success", "danger", "warning", "neutral", "info"],
|
|
297
693
|
sizes: {
|
|
298
694
|
button: ["xs", "sm", "md", "lg", "xl"],
|
|
695
|
+
iconButton: ["xs", "sm", "md", "lg", "xl"],
|
|
299
696
|
chip: ["xs", "sm", "md", "lg", "xl"],
|
|
300
697
|
badge: ["xs", "sm", "md", "lg", "xl"],
|
|
301
698
|
icon: ["xs", "sm", "md", "lg", "xl"],
|
|
@@ -309,6 +706,7 @@ function getDefaultThemeValues() {
|
|
|
309
706
|
progress: ["xs", "sm", "md", "lg", "xl"],
|
|
310
707
|
accordion: ["xs", "sm", "md", "lg", "xl"],
|
|
311
708
|
activityIndicator: ["xs", "sm", "md", "lg", "xl"],
|
|
709
|
+
alert: ["xs", "sm", "md", "lg", "xl"],
|
|
312
710
|
breadcrumb: ["xs", "sm", "md", "lg", "xl"],
|
|
313
711
|
list: ["xs", "sm", "md", "lg", "xl"],
|
|
314
712
|
menu: ["xs", "sm", "md", "lg", "xl"],
|
|
@@ -329,7 +727,7 @@ function getDefaultThemeValues() {
|
|
|
329
727
|
borderColors: ["primary", "secondary", "tertiary", "disabled"]
|
|
330
728
|
};
|
|
331
729
|
}
|
|
332
|
-
function
|
|
730
|
+
function mergeThemeValues2(target, source) {
|
|
333
731
|
target.intents.push(...source.intents.filter((k) => !target.intents.includes(k)));
|
|
334
732
|
target.radii.push(...source.radii.filter((k) => !target.radii.includes(k)));
|
|
335
733
|
target.shadows.push(...source.shadows.filter((k) => !target.shadows.includes(k)));
|
|
@@ -346,32 +744,58 @@ function mergeThemeValues(target, source) {
|
|
|
346
744
|
}
|
|
347
745
|
function getStringValue(node) {
|
|
348
746
|
if (!node) return null;
|
|
349
|
-
if (
|
|
350
|
-
if (
|
|
747
|
+
if (ts2.isStringLiteral(node)) return node.text;
|
|
748
|
+
if (ts2.isIdentifier(node)) return node.text;
|
|
351
749
|
return null;
|
|
352
750
|
}
|
|
353
751
|
function getPropertyName(node) {
|
|
354
|
-
if (
|
|
355
|
-
if (
|
|
752
|
+
if (ts2.isIdentifier(node)) return node.text;
|
|
753
|
+
if (ts2.isStringLiteral(node)) return node.text;
|
|
356
754
|
return null;
|
|
357
755
|
}
|
|
358
756
|
function getObjectKeys(node) {
|
|
359
|
-
return node.properties.filter(
|
|
757
|
+
return node.properties.filter(ts2.isPropertyAssignment).map((prop) => getPropertyName(prop.name)).filter((k) => k !== null);
|
|
360
758
|
}
|
|
361
759
|
var themeKeysCache = null;
|
|
362
760
|
var themeLoadAttempted = false;
|
|
761
|
+
var packageAliases = {};
|
|
762
|
+
function resolveWithAliases(source, fromDir) {
|
|
763
|
+
for (const [aliasPrefix, aliasPath] of Object.entries(packageAliases)) {
|
|
764
|
+
if (source === aliasPrefix || source.startsWith(aliasPrefix + "/")) {
|
|
765
|
+
const remainder = source.slice(aliasPrefix.length);
|
|
766
|
+
let resolved = aliasPath + remainder;
|
|
767
|
+
if (!path2.isAbsolute(resolved)) {
|
|
768
|
+
resolved = path2.resolve(fromDir, resolved);
|
|
769
|
+
}
|
|
770
|
+
return resolved;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
363
775
|
function loadThemeKeys(opts, rootDir, _babelTypes, verboseMode = false) {
|
|
364
776
|
if (themeLoadAttempted && themeKeysCache) {
|
|
365
777
|
return themeKeysCache;
|
|
366
778
|
}
|
|
367
779
|
themeLoadAttempted = true;
|
|
780
|
+
if (opts.aliases && typeof opts.aliases === "object") {
|
|
781
|
+
packageAliases = opts.aliases;
|
|
782
|
+
if (verboseMode) {
|
|
783
|
+
console.log("[idealyst-plugin] Configured aliases:", packageAliases);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
368
786
|
const themePath = opts.themePath;
|
|
369
787
|
if (!themePath) {
|
|
370
788
|
throw new Error(
|
|
371
789
|
'[idealyst-plugin] themePath is required!\nAdd it to your babel config:\n ["@idealyst/theme/plugin", { themePath: "./src/theme/styles.ts" }]'
|
|
372
790
|
);
|
|
373
791
|
}
|
|
374
|
-
|
|
792
|
+
let resolvedPath;
|
|
793
|
+
const aliasResolved = resolveWithAliases(themePath, rootDir);
|
|
794
|
+
if (aliasResolved && fs2.existsSync(aliasResolved)) {
|
|
795
|
+
resolvedPath = aliasResolved;
|
|
796
|
+
} else {
|
|
797
|
+
resolvedPath = themePath.startsWith(".") ? path2.resolve(rootDir, themePath) : themePath;
|
|
798
|
+
}
|
|
375
799
|
if (verboseMode) {
|
|
376
800
|
console.log("[idealyst-plugin] Analyzing theme file via @idealyst/tooling:", resolvedPath);
|
|
377
801
|
}
|
|
@@ -406,14 +830,14 @@ function analyzeComponents(options) {
|
|
|
406
830
|
const registry = {};
|
|
407
831
|
const themeValues = analyzeTheme(themePath, false);
|
|
408
832
|
for (const componentPath of componentPaths) {
|
|
409
|
-
const resolvedPath =
|
|
410
|
-
if (!
|
|
833
|
+
const resolvedPath = path3.resolve(componentPath);
|
|
834
|
+
if (!fs3.existsSync(resolvedPath)) {
|
|
411
835
|
console.warn(`[component-analyzer] Path not found: ${resolvedPath}`);
|
|
412
836
|
continue;
|
|
413
837
|
}
|
|
414
838
|
const componentDirs = findComponentDirs(resolvedPath);
|
|
415
839
|
for (const dir of componentDirs) {
|
|
416
|
-
const componentName =
|
|
840
|
+
const componentName = path3.basename(dir);
|
|
417
841
|
if (include && !include.includes(componentName)) continue;
|
|
418
842
|
if (exclude && exclude.includes(componentName)) continue;
|
|
419
843
|
if (!includeInternal && componentName.startsWith("_")) continue;
|
|
@@ -427,12 +851,12 @@ function analyzeComponents(options) {
|
|
|
427
851
|
}
|
|
428
852
|
function findComponentDirs(basePath) {
|
|
429
853
|
const dirs = [];
|
|
430
|
-
const entries =
|
|
854
|
+
const entries = fs3.readdirSync(basePath, { withFileTypes: true });
|
|
431
855
|
for (const entry of entries) {
|
|
432
856
|
if (!entry.isDirectory()) continue;
|
|
433
|
-
const dirPath =
|
|
434
|
-
const hasIndex =
|
|
435
|
-
const hasTypes =
|
|
857
|
+
const dirPath = path3.join(basePath, entry.name);
|
|
858
|
+
const hasIndex = fs3.existsSync(path3.join(dirPath, "index.ts"));
|
|
859
|
+
const hasTypes = fs3.existsSync(path3.join(dirPath, "types.ts"));
|
|
436
860
|
if (hasIndex || hasTypes) {
|
|
437
861
|
dirs.push(dirPath);
|
|
438
862
|
}
|
|
@@ -440,14 +864,14 @@ function findComponentDirs(basePath) {
|
|
|
440
864
|
return dirs;
|
|
441
865
|
}
|
|
442
866
|
function analyzeComponentDir(dir, componentName, themeValues) {
|
|
443
|
-
const tsFiles =
|
|
867
|
+
const tsFiles = fs3.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx")).map((f) => path3.join(dir, f));
|
|
444
868
|
if (tsFiles.length === 0) {
|
|
445
869
|
return null;
|
|
446
870
|
}
|
|
447
|
-
const program =
|
|
448
|
-
target:
|
|
449
|
-
module:
|
|
450
|
-
jsx:
|
|
871
|
+
const program = ts3.createProgram(tsFiles, {
|
|
872
|
+
target: ts3.ScriptTarget.ES2020,
|
|
873
|
+
module: ts3.ModuleKind.ESNext,
|
|
874
|
+
jsx: ts3.JsxEmit.React,
|
|
451
875
|
strict: true,
|
|
452
876
|
esModuleInterop: true,
|
|
453
877
|
skipLibCheck: true
|
|
@@ -460,12 +884,12 @@ function analyzeComponentDir(dir, componentName, themeValues) {
|
|
|
460
884
|
for (const filePath of tsFiles) {
|
|
461
885
|
const sourceFile = program.getSourceFile(filePath);
|
|
462
886
|
if (!sourceFile) continue;
|
|
463
|
-
|
|
464
|
-
if (
|
|
887
|
+
ts3.forEachChild(sourceFile, (node) => {
|
|
888
|
+
if (ts3.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
|
|
465
889
|
propsInterface = node;
|
|
466
890
|
interfaceDescription = getJSDocDescription(node);
|
|
467
891
|
}
|
|
468
|
-
if (
|
|
892
|
+
if (ts3.isTypeAliasDeclaration(node) && node.name.text === propsInterfaceName) {
|
|
469
893
|
propsInterface = node;
|
|
470
894
|
interfaceDescription = getJSDocDescription(node);
|
|
471
895
|
}
|
|
@@ -477,8 +901,8 @@ function analyzeComponentDir(dir, componentName, themeValues) {
|
|
|
477
901
|
for (const filePath of tsFiles) {
|
|
478
902
|
const sourceFile = program.getSourceFile(filePath);
|
|
479
903
|
if (!sourceFile) continue;
|
|
480
|
-
|
|
481
|
-
if ((
|
|
904
|
+
ts3.forEachChild(sourceFile, (node) => {
|
|
905
|
+
if ((ts3.isInterfaceDeclaration(node) || ts3.isTypeAliasDeclaration(node)) && node.name.text === altName) {
|
|
482
906
|
propsInterface = node;
|
|
483
907
|
interfaceDescription = getJSDocDescription(node);
|
|
484
908
|
}
|
|
@@ -510,32 +934,32 @@ function analyzeComponentDir(dir, componentName, themeValues) {
|
|
|
510
934
|
description,
|
|
511
935
|
props,
|
|
512
936
|
category,
|
|
513
|
-
filePath:
|
|
937
|
+
filePath: path3.relative(process.cwd(), dir),
|
|
514
938
|
sampleProps
|
|
515
939
|
};
|
|
516
940
|
}
|
|
517
941
|
function extractSampleProps(dir) {
|
|
518
|
-
const docsPath =
|
|
519
|
-
if (!
|
|
942
|
+
const docsPath = path3.join(dir, "docs.ts");
|
|
943
|
+
if (!fs3.existsSync(docsPath)) {
|
|
520
944
|
return void 0;
|
|
521
945
|
}
|
|
522
946
|
try {
|
|
523
|
-
const content =
|
|
524
|
-
const sourceFile =
|
|
947
|
+
const content = fs3.readFileSync(docsPath, "utf-8");
|
|
948
|
+
const sourceFile = ts3.createSourceFile(
|
|
525
949
|
"docs.ts",
|
|
526
950
|
content,
|
|
527
|
-
|
|
951
|
+
ts3.ScriptTarget.ES2020,
|
|
528
952
|
true,
|
|
529
|
-
|
|
953
|
+
ts3.ScriptKind.TS
|
|
530
954
|
);
|
|
531
955
|
let samplePropsNode = null;
|
|
532
|
-
|
|
533
|
-
if (
|
|
534
|
-
const isExported = node.modifiers?.some((m) => m.kind ===
|
|
956
|
+
ts3.forEachChild(sourceFile, (node) => {
|
|
957
|
+
if (ts3.isVariableStatement(node)) {
|
|
958
|
+
const isExported = node.modifiers?.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
|
|
535
959
|
if (isExported) {
|
|
536
960
|
for (const decl of node.declarationList.declarations) {
|
|
537
|
-
if (
|
|
538
|
-
if (
|
|
961
|
+
if (ts3.isIdentifier(decl.name) && decl.name.text === "sampleProps" && decl.initializer) {
|
|
962
|
+
if (ts3.isObjectLiteralExpression(decl.initializer)) {
|
|
539
963
|
samplePropsNode = decl.initializer;
|
|
540
964
|
}
|
|
541
965
|
}
|
|
@@ -549,13 +973,13 @@ function extractSampleProps(dir) {
|
|
|
549
973
|
const result = {};
|
|
550
974
|
const propsNode = samplePropsNode;
|
|
551
975
|
for (const prop of propsNode.properties) {
|
|
552
|
-
if (
|
|
976
|
+
if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
|
|
553
977
|
const propName = prop.name.text;
|
|
554
|
-
if (propName === "props" &&
|
|
978
|
+
if (propName === "props" && ts3.isObjectLiteralExpression(prop.initializer)) {
|
|
555
979
|
result.props = extractObjectLiteral(prop.initializer, content);
|
|
556
980
|
} else if (propName === "children") {
|
|
557
981
|
result.children = prop.initializer.getText(sourceFile);
|
|
558
|
-
} else if (propName === "state" &&
|
|
982
|
+
} else if (propName === "state" && ts3.isObjectLiteralExpression(prop.initializer)) {
|
|
559
983
|
result.state = extractObjectLiteral(prop.initializer, content);
|
|
560
984
|
}
|
|
561
985
|
}
|
|
@@ -569,20 +993,20 @@ function extractSampleProps(dir) {
|
|
|
569
993
|
function extractObjectLiteral(node, sourceContent) {
|
|
570
994
|
const result = {};
|
|
571
995
|
for (const prop of node.properties) {
|
|
572
|
-
if (
|
|
996
|
+
if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
|
|
573
997
|
const key = prop.name.text;
|
|
574
998
|
const init = prop.initializer;
|
|
575
|
-
if (
|
|
999
|
+
if (ts3.isStringLiteral(init)) {
|
|
576
1000
|
result[key] = init.text;
|
|
577
|
-
} else if (
|
|
1001
|
+
} else if (ts3.isNumericLiteral(init)) {
|
|
578
1002
|
result[key] = Number(init.text);
|
|
579
|
-
} else if (init.kind ===
|
|
1003
|
+
} else if (init.kind === ts3.SyntaxKind.TrueKeyword) {
|
|
580
1004
|
result[key] = true;
|
|
581
|
-
} else if (init.kind ===
|
|
1005
|
+
} else if (init.kind === ts3.SyntaxKind.FalseKeyword) {
|
|
582
1006
|
result[key] = false;
|
|
583
|
-
} else if (
|
|
1007
|
+
} else if (ts3.isArrayLiteralExpression(init)) {
|
|
584
1008
|
result[key] = extractArrayLiteral(init, sourceContent);
|
|
585
|
-
} else if (
|
|
1009
|
+
} else if (ts3.isObjectLiteralExpression(init)) {
|
|
586
1010
|
result[key] = extractObjectLiteral(init, sourceContent);
|
|
587
1011
|
} else {
|
|
588
1012
|
result[key] = init.getText();
|
|
@@ -594,17 +1018,17 @@ function extractObjectLiteral(node, sourceContent) {
|
|
|
594
1018
|
function extractArrayLiteral(node, sourceContent) {
|
|
595
1019
|
const result = [];
|
|
596
1020
|
for (const element of node.elements) {
|
|
597
|
-
if (
|
|
1021
|
+
if (ts3.isStringLiteral(element)) {
|
|
598
1022
|
result.push(element.text);
|
|
599
|
-
} else if (
|
|
1023
|
+
} else if (ts3.isNumericLiteral(element)) {
|
|
600
1024
|
result.push(Number(element.text));
|
|
601
|
-
} else if (element.kind ===
|
|
1025
|
+
} else if (element.kind === ts3.SyntaxKind.TrueKeyword) {
|
|
602
1026
|
result.push(true);
|
|
603
|
-
} else if (element.kind ===
|
|
1027
|
+
} else if (element.kind === ts3.SyntaxKind.FalseKeyword) {
|
|
604
1028
|
result.push(false);
|
|
605
|
-
} else if (
|
|
1029
|
+
} else if (ts3.isObjectLiteralExpression(element)) {
|
|
606
1030
|
result.push(extractObjectLiteral(element, sourceContent));
|
|
607
|
-
} else if (
|
|
1031
|
+
} else if (ts3.isArrayLiteralExpression(element)) {
|
|
608
1032
|
result.push(extractArrayLiteral(element, sourceContent));
|
|
609
1033
|
} else {
|
|
610
1034
|
result.push(element.getText());
|
|
@@ -619,8 +1043,8 @@ function analyzeProperty(symbol, typeChecker, themeValues) {
|
|
|
619
1043
|
const declaration = declarations[0];
|
|
620
1044
|
const type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
621
1045
|
const typeString = typeChecker.typeToString(type);
|
|
622
|
-
const description =
|
|
623
|
-
const required = !(symbol.flags &
|
|
1046
|
+
const description = ts3.displayPartsToString(symbol.getDocumentationComment(typeChecker)) || void 0;
|
|
1047
|
+
const required = !(symbol.flags & ts3.SymbolFlags.Optional);
|
|
624
1048
|
const values = extractPropValues(type, typeString, typeChecker, themeValues);
|
|
625
1049
|
const defaultValue = extractDefaultValue(symbol);
|
|
626
1050
|
return {
|
|
@@ -661,7 +1085,7 @@ function extractDefaultValue(symbol) {
|
|
|
661
1085
|
const tags = symbol.getJsDocTags();
|
|
662
1086
|
for (const tag of tags) {
|
|
663
1087
|
if (tag.name === "default" && tag.text) {
|
|
664
|
-
const value =
|
|
1088
|
+
const value = ts3.displayPartsToString(tag.text);
|
|
665
1089
|
try {
|
|
666
1090
|
return JSON.parse(value);
|
|
667
1091
|
} catch {
|
|
@@ -764,8 +1188,8 @@ function inferCategory(componentName) {
|
|
|
764
1188
|
}
|
|
765
1189
|
|
|
766
1190
|
// src/vite-plugin.ts
|
|
767
|
-
var
|
|
768
|
-
var
|
|
1191
|
+
var fs4 = __toESM(require("fs"), 1);
|
|
1192
|
+
var path4 = __toESM(require("path"), 1);
|
|
769
1193
|
function idealystDocsPlugin(options) {
|
|
770
1194
|
let registry = null;
|
|
771
1195
|
const { debug = false, output, outputPath } = options;
|
|
@@ -783,11 +1207,11 @@ function idealystDocsPlugin(options) {
|
|
|
783
1207
|
log("Components found:", Object.keys(registry));
|
|
784
1208
|
}
|
|
785
1209
|
if (output === "file" && outputPath) {
|
|
786
|
-
const outputDir =
|
|
787
|
-
if (!
|
|
788
|
-
|
|
1210
|
+
const outputDir = path4.dirname(outputPath);
|
|
1211
|
+
if (!fs4.existsSync(outputDir)) {
|
|
1212
|
+
fs4.mkdirSync(outputDir, { recursive: true });
|
|
789
1213
|
}
|
|
790
|
-
|
|
1214
|
+
fs4.writeFileSync(
|
|
791
1215
|
outputPath,
|
|
792
1216
|
`// Auto-generated by @idealyst/tooling - DO NOT EDIT
|
|
793
1217
|
export const componentRegistry = ${JSON.stringify(registry, null, 2)} as const;
|
|
@@ -858,8 +1282,8 @@ export const componentRegistry = ${JSON.stringify(registry, null, 2)} as const;
|
|
|
858
1282
|
},
|
|
859
1283
|
// Regenerate on component file changes
|
|
860
1284
|
handleHotUpdate({ file, server }) {
|
|
861
|
-
const isComponentFile2 = options.componentPaths.some((p) => file.includes(
|
|
862
|
-
const isThemeFile = file.includes(
|
|
1285
|
+
const isComponentFile2 = options.componentPaths.some((p) => file.includes(path4.resolve(p))) && (file.endsWith(".ts") || file.endsWith(".tsx"));
|
|
1286
|
+
const isThemeFile = file.includes(path4.resolve(options.themePath));
|
|
863
1287
|
if (isComponentFile2 || isThemeFile) {
|
|
864
1288
|
log(`File changed: ${file}, regenerating registry...`);
|
|
865
1289
|
registry = null;
|
|
@@ -881,7 +1305,7 @@ function generateComponentRegistry(options) {
|
|
|
881
1305
|
}
|
|
882
1306
|
|
|
883
1307
|
// src/utils/fileClassifier.ts
|
|
884
|
-
var
|
|
1308
|
+
var path5 = __toESM(require("path"), 1);
|
|
885
1309
|
var EXTENSION_PATTERNS = [
|
|
886
1310
|
// Platform-specific component files
|
|
887
1311
|
{ pattern: /\.web\.(tsx|jsx)$/, type: "web" },
|
|
@@ -905,7 +1329,7 @@ var EXCLUDED_PATTERNS = [
|
|
|
905
1329
|
/index\.(ts|tsx|js|jsx)$/
|
|
906
1330
|
];
|
|
907
1331
|
function classifyFile(filePath) {
|
|
908
|
-
const fileName =
|
|
1332
|
+
const fileName = path5.basename(filePath);
|
|
909
1333
|
for (const pattern of EXCLUDED_PATTERNS) {
|
|
910
1334
|
if (pattern.test(fileName)) {
|
|
911
1335
|
return "other";
|
|
@@ -936,12 +1360,12 @@ function getExpectedPlatform(filePath) {
|
|
|
936
1360
|
return null;
|
|
937
1361
|
}
|
|
938
1362
|
function getBaseName(filePath) {
|
|
939
|
-
const fileName =
|
|
1363
|
+
const fileName = path5.basename(filePath);
|
|
940
1364
|
return fileName.replace(/\.(web|native|ios|android)\.(tsx|jsx|ts|js)$/, "").replace(/\.styles?\.(tsx|jsx|ts|js)$/, "").replace(/\.types?\.(tsx|ts)$/, "").replace(/\.(tsx|jsx|ts|js)$/, "");
|
|
941
1365
|
}
|
|
942
1366
|
|
|
943
1367
|
// src/utils/importParser.ts
|
|
944
|
-
var
|
|
1368
|
+
var ts4 = __toESM(require("typescript"), 1);
|
|
945
1369
|
|
|
946
1370
|
// src/rules/reactNativePrimitives.ts
|
|
947
1371
|
var REACT_NATIVE_SOURCES = [
|
|
@@ -1425,19 +1849,19 @@ function getPlatformForSource(source, options) {
|
|
|
1425
1849
|
}
|
|
1426
1850
|
function parseImports(sourceCode, filePath = "unknown.tsx", options) {
|
|
1427
1851
|
const imports = [];
|
|
1428
|
-
const sourceFile =
|
|
1852
|
+
const sourceFile = ts4.createSourceFile(
|
|
1429
1853
|
filePath,
|
|
1430
1854
|
sourceCode,
|
|
1431
|
-
|
|
1855
|
+
ts4.ScriptTarget.Latest,
|
|
1432
1856
|
true,
|
|
1433
|
-
filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ?
|
|
1857
|
+
filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ? ts4.ScriptKind.TSX : ts4.ScriptKind.TS
|
|
1434
1858
|
);
|
|
1435
1859
|
const visit = (node) => {
|
|
1436
|
-
if (
|
|
1860
|
+
if (ts4.isImportDeclaration(node)) {
|
|
1437
1861
|
const importInfo = parseImportDeclaration(node, sourceFile, options);
|
|
1438
1862
|
imports.push(...importInfo);
|
|
1439
1863
|
}
|
|
1440
|
-
if (
|
|
1864
|
+
if (ts4.isCallExpression(node) && ts4.isIdentifier(node.expression) && node.expression.text === "require" && node.arguments.length === 1 && ts4.isStringLiteral(node.arguments[0])) {
|
|
1441
1865
|
const source = node.arguments[0].text;
|
|
1442
1866
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(
|
|
1443
1867
|
node.getStart()
|
|
@@ -1453,14 +1877,14 @@ function parseImports(sourceCode, filePath = "unknown.tsx", options) {
|
|
|
1453
1877
|
isTypeOnly: false
|
|
1454
1878
|
});
|
|
1455
1879
|
}
|
|
1456
|
-
|
|
1880
|
+
ts4.forEachChild(node, visit);
|
|
1457
1881
|
};
|
|
1458
1882
|
visit(sourceFile);
|
|
1459
1883
|
return imports;
|
|
1460
1884
|
}
|
|
1461
1885
|
function parseImportDeclaration(node, sourceFile, options) {
|
|
1462
1886
|
const imports = [];
|
|
1463
|
-
if (!
|
|
1887
|
+
if (!ts4.isStringLiteral(node.moduleSpecifier)) {
|
|
1464
1888
|
return imports;
|
|
1465
1889
|
}
|
|
1466
1890
|
const source = node.moduleSpecifier.text;
|
|
@@ -1487,7 +1911,7 @@ function parseImportDeclaration(node, sourceFile, options) {
|
|
|
1487
1911
|
}
|
|
1488
1912
|
const namedBindings = importClause.namedBindings;
|
|
1489
1913
|
if (namedBindings) {
|
|
1490
|
-
if (
|
|
1914
|
+
if (ts4.isNamespaceImport(namedBindings)) {
|
|
1491
1915
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(
|
|
1492
1916
|
namedBindings.name.getStart()
|
|
1493
1917
|
);
|
|
@@ -1501,7 +1925,7 @@ function parseImportDeclaration(node, sourceFile, options) {
|
|
|
1501
1925
|
isNamespace: true,
|
|
1502
1926
|
isTypeOnly
|
|
1503
1927
|
});
|
|
1504
|
-
} else if (
|
|
1928
|
+
} else if (ts4.isNamedImports(namedBindings)) {
|
|
1505
1929
|
for (const element of namedBindings.elements) {
|
|
1506
1930
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(
|
|
1507
1931
|
element.name.getStart()
|