@fragments-sdk/cli 0.15.10 → 0.16.0

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.
Files changed (78) hide show
  1. package/dist/bin.js +896 -787
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-6SQPP47U.js → chunk-77AAP6R6.js} +532 -31
  4. package/dist/chunk-77AAP6R6.js.map +1 -0
  5. package/dist/{chunk-5JF26E55.js → chunk-ACFVKMVZ.js} +11 -11
  6. package/dist/{chunk-BJE3425I.js → chunk-ACX7YWZW.js} +2 -2
  7. package/dist/{chunk-ONUP6Z4W.js → chunk-G6UVWMFU.js} +8 -8
  8. package/dist/{chunk-2WXKALIG.js → chunk-OZZ4SVZX.js} +2 -2
  9. package/dist/{chunk-32LIWN2P.js → chunk-SJFSG7QF.js} +582 -261
  10. package/dist/chunk-SJFSG7QF.js.map +1 -0
  11. package/dist/{chunk-HQ6A6DTV.js → chunk-XRADMHMV.js} +315 -1089
  12. package/dist/chunk-XRADMHMV.js.map +1 -0
  13. package/dist/core/index.js +53 -1
  14. package/dist/{create-EXURTBKK.js → create-3ZFYQB3T.js} +2 -2
  15. package/dist/{doctor-BDPMYYE6.js → doctor-4IDUM7HI.js} +2 -2
  16. package/dist/{generate-PVOLUAAC.js → generate-VNUUWVWQ.js} +4 -4
  17. package/dist/{govern-scan-DW4QUAYD.js → govern-scan-HTACKYPF.js} +158 -120
  18. package/dist/govern-scan-HTACKYPF.js.map +1 -0
  19. package/dist/index.js +6 -7
  20. package/dist/index.js.map +1 -1
  21. package/dist/{init-SSGUSP7Z.js → init-PXFRAQ64.js} +5 -5
  22. package/dist/mcp-bin.js +2 -2
  23. package/dist/{scan-PKSYSTRR.js → scan-L4GWGEZX.js} +5 -6
  24. package/dist/{scan-generate-VY27PIOX.js → scan-generate-74EYSAGH.js} +4 -4
  25. package/dist/{service-QJGWUIVL.js → service-VELQHEWV.js} +12 -14
  26. package/dist/{snapshot-WIJMEIFT.js → snapshot-DT4B6DPR.js} +2 -2
  27. package/dist/{static-viewer-7QIBQZRC.js → static-viewer-E4OJWFDJ.js} +3 -3
  28. package/dist/{test-64Z5BKBA.js → test-QJY2QO4X.js} +3 -3
  29. package/dist/{token-normalizer-TEPOVBPV.js → token-normalizer-56H4242J.js} +2 -2
  30. package/dist/{tokens-NZWFQIAB.js → tokens-K6URXFPK.js} +7 -8
  31. package/dist/{tokens-NZWFQIAB.js.map → tokens-K6URXFPK.js.map} +1 -1
  32. package/dist/{tokens-generate-5JQSJ27E.js → tokens-generate-EL6IN536.js} +2 -2
  33. package/package.json +7 -6
  34. package/src/bin.ts +49 -88
  35. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.contract.json +1 -1
  36. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.contract.json +1 -1
  37. package/src/commands/__tests__/context-cloud.test.ts +291 -0
  38. package/src/commands/__tests__/govern-scan.test.ts +185 -0
  39. package/src/commands/__tests__/govern.test.ts +1 -0
  40. package/src/commands/context-cloud.ts +355 -0
  41. package/src/commands/govern-scan-report.ts +170 -0
  42. package/src/commands/govern-scan.ts +42 -147
  43. package/src/commands/govern.ts +0 -157
  44. package/dist/chunk-32LIWN2P.js.map +0 -1
  45. package/dist/chunk-6SQPP47U.js.map +0 -1
  46. package/dist/chunk-HQ6A6DTV.js.map +0 -1
  47. package/dist/chunk-MHIBEEW4.js +0 -511
  48. package/dist/chunk-MHIBEEW4.js.map +0 -1
  49. package/dist/govern-scan-DW4QUAYD.js.map +0 -1
  50. package/dist/init-cloud-3DNKPWFB.js +0 -304
  51. package/dist/init-cloud-3DNKPWFB.js.map +0 -1
  52. package/dist/node-37AUE74M.js +0 -65
  53. package/dist/push-contracts-WY32TFP6.js +0 -84
  54. package/dist/push-contracts-WY32TFP6.js.map +0 -1
  55. package/dist/static-viewer-7QIBQZRC.js.map +0 -1
  56. package/dist/token-parser-32KOIOFN.js +0 -22
  57. package/dist/token-parser-32KOIOFN.js.map +0 -1
  58. package/dist/tokens-push-HY3KO36V.js +0 -148
  59. package/dist/tokens-push-HY3KO36V.js.map +0 -1
  60. package/src/commands/init-cloud.ts +0 -382
  61. package/src/commands/push-contracts.ts +0 -112
  62. package/src/commands/tokens-push.ts +0 -199
  63. /package/dist/{chunk-5JF26E55.js.map → chunk-ACFVKMVZ.js.map} +0 -0
  64. /package/dist/{chunk-BJE3425I.js.map → chunk-ACX7YWZW.js.map} +0 -0
  65. /package/dist/{chunk-ONUP6Z4W.js.map → chunk-G6UVWMFU.js.map} +0 -0
  66. /package/dist/{chunk-2WXKALIG.js.map → chunk-OZZ4SVZX.js.map} +0 -0
  67. /package/dist/{create-EXURTBKK.js.map → create-3ZFYQB3T.js.map} +0 -0
  68. /package/dist/{doctor-BDPMYYE6.js.map → doctor-4IDUM7HI.js.map} +0 -0
  69. /package/dist/{generate-PVOLUAAC.js.map → generate-VNUUWVWQ.js.map} +0 -0
  70. /package/dist/{init-SSGUSP7Z.js.map → init-PXFRAQ64.js.map} +0 -0
  71. /package/dist/{node-37AUE74M.js.map → scan-L4GWGEZX.js.map} +0 -0
  72. /package/dist/{scan-generate-VY27PIOX.js.map → scan-generate-74EYSAGH.js.map} +0 -0
  73. /package/dist/{scan-PKSYSTRR.js.map → service-VELQHEWV.js.map} +0 -0
  74. /package/dist/{snapshot-WIJMEIFT.js.map → snapshot-DT4B6DPR.js.map} +0 -0
  75. /package/dist/{service-QJGWUIVL.js.map → static-viewer-E4OJWFDJ.js.map} +0 -0
  76. /package/dist/{test-64Z5BKBA.js.map → test-QJY2QO4X.js.map} +0 -0
  77. /package/dist/{token-normalizer-TEPOVBPV.js.map → token-normalizer-56H4242J.js.map} +0 -0
  78. /package/dist/{tokens-generate-5JQSJ27E.js.map → tokens-generate-EL6IN536.js.map} +0 -0
@@ -2,7 +2,7 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import {
3
3
  BRAND,
4
4
  fragmentsConfigSchema
5
- } from "./chunk-32LIWN2P.js";
5
+ } from "./chunk-SJFSG7QF.js";
6
6
 
7
7
  // src/core/config.ts
8
8
  import { existsSync } from "fs";
@@ -132,7 +132,6 @@ async function discoverBlockFiles(configDir, exclude) {
132
132
  absolutePath: resolve2(configDir, relativePath)
133
133
  }));
134
134
  }
135
- var discoverRecipeFiles = discoverBlockFiles;
136
135
  async function discoverFragmentFiles(config, configDir) {
137
136
  const defaultExcludes = [
138
137
  "**/*.test.stories.*",
@@ -323,55 +322,6 @@ async function discoverComponentsFromBarrel(barrelPath, configDir) {
323
322
  }
324
323
  return components;
325
324
  }
326
- var DEFAULT_TOKEN_PATTERNS = [
327
- "src/**/tokens/**/_variables.scss",
328
- "src/**/tokens/**/variables.scss",
329
- "src/**/styles/**/variables.scss",
330
- "src/**/styles/**/tokens.scss",
331
- "src/**/styles/**/variables.css",
332
- "src/**/theme/**/_variables.scss",
333
- "src/**/theme/**/tokens.css",
334
- // DTCG token files
335
- "**/*.tokens.json",
336
- "**/*.tokens"
337
- ];
338
- async function discoverTokenFiles(configDir, patterns, exclude) {
339
- const searchPatterns = patterns && patterns.length > 0 ? patterns : DEFAULT_TOKEN_PATTERNS;
340
- const files = await fg(searchPatterns, {
341
- cwd: configDir,
342
- ignore: exclude ?? ["**/node_modules/**", "**/dist/**"],
343
- absolute: false
344
- });
345
- return files.map((relativePath) => ({
346
- relativePath,
347
- absolutePath: resolve2(configDir, relativePath)
348
- }));
349
- }
350
- async function discoverInstalledFragments(projectRoot) {
351
- const pkgJsonPath = resolve2(projectRoot, "package.json");
352
- if (!existsSync2(pkgJsonPath)) return [];
353
- const pkgJson = JSON.parse(await readFile(pkgJsonPath, "utf-8"));
354
- const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
355
- const results = [];
356
- for (const depName of Object.keys(allDeps)) {
357
- const depDir = resolve2(projectRoot, "node_modules", depName);
358
- const depPkgPath = resolve2(depDir, "package.json");
359
- if (!existsSync2(depPkgPath)) continue;
360
- const depPkg = JSON.parse(await readFile(depPkgPath, "utf-8"));
361
- if (!depPkg.fragments) continue;
362
- const files = await fg(
363
- [`src/**/*${BRAND.fileExtension}`, "src/**/*.stories.tsx"],
364
- { cwd: depDir, ignore: ["**/node_modules/**"], absolute: false }
365
- );
366
- for (const rel of files) {
367
- results.push({
368
- relativePath: `${depName}/${rel}`,
369
- absolutePath: resolve2(depDir, rel)
370
- });
371
- }
372
- }
373
- return results;
374
- }
375
325
  async function discoverAllComponents(configDir, options = {}) {
376
326
  const componentsMap = /* @__PURE__ */ new Map();
377
327
  const sourceComponents = await discoverComponentsFromSource(
@@ -395,9 +345,270 @@ async function discoverAllComponents(configDir, options = {}) {
395
345
  return Array.from(componentsMap.values()).sort((a, b) => a.name.localeCompare(b.name));
396
346
  }
397
347
 
348
+ // src/core/generators/typescript-extractor.ts
349
+ import ts from "typescript";
350
+ import { readFileSync } from "fs";
351
+ function extractPropsFromFile(filePath) {
352
+ const sourceText = readFileSync(filePath, "utf-8");
353
+ return extractPropsFromSource(sourceText, filePath);
354
+ }
355
+ function extractPropsFromSource(sourceText, fileName = "component.tsx") {
356
+ const sourceFile = ts.createSourceFile(
357
+ fileName,
358
+ sourceText,
359
+ ts.ScriptTarget.Latest,
360
+ true,
361
+ fileName.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS
362
+ );
363
+ const result = {
364
+ componentName: "",
365
+ props: {},
366
+ exports: [],
367
+ imports: []
368
+ };
369
+ const propsInterfaces = /* @__PURE__ */ new Map();
370
+ const componentExports = [];
371
+ const defaultExports = /* @__PURE__ */ new Set();
372
+ const importedModules = [];
373
+ ts.forEachChild(sourceFile, (node) => {
374
+ if (ts.isImportDeclaration(node)) {
375
+ const moduleSpecifier = node.moduleSpecifier;
376
+ if (ts.isStringLiteral(moduleSpecifier)) {
377
+ importedModules.push(moduleSpecifier.text);
378
+ }
379
+ }
380
+ if (ts.isInterfaceDeclaration(node)) {
381
+ const name = node.name.text;
382
+ if (name.endsWith("Props")) {
383
+ propsInterfaces.set(name, node);
384
+ }
385
+ }
386
+ if (ts.isTypeAliasDeclaration(node)) {
387
+ const name = node.name.text;
388
+ if (name.endsWith("Props")) {
389
+ propsInterfaces.set(name, node);
390
+ }
391
+ }
392
+ if (ts.isFunctionDeclaration(node) && node.name) {
393
+ const hasExport = node.modifiers?.some(
394
+ (m) => m.kind === ts.SyntaxKind.ExportKeyword
395
+ );
396
+ const hasDefault = node.modifiers?.some(
397
+ (m) => m.kind === ts.SyntaxKind.DefaultKeyword
398
+ );
399
+ if (hasExport) {
400
+ componentExports.push(node.name.text);
401
+ if (hasDefault) {
402
+ defaultExports.add(node.name.text);
403
+ }
404
+ }
405
+ }
406
+ if (ts.isVariableStatement(node)) {
407
+ const hasExport = node.modifiers?.some(
408
+ (m) => m.kind === ts.SyntaxKind.ExportKeyword
409
+ );
410
+ if (hasExport) {
411
+ for (const decl of node.declarationList.declarations) {
412
+ if (ts.isIdentifier(decl.name)) {
413
+ componentExports.push(decl.name.text);
414
+ }
415
+ }
416
+ }
417
+ }
418
+ if (ts.isExportDeclaration(node) && node.exportClause) {
419
+ if (ts.isNamedExports(node.exportClause)) {
420
+ for (const element of node.exportClause.elements) {
421
+ componentExports.push(element.name.text);
422
+ }
423
+ }
424
+ }
425
+ });
426
+ result.exports = componentExports;
427
+ result.imports = importedModules;
428
+ const mainComponent = componentExports.find(
429
+ (name) => /^[A-Z]/.test(name) && !name.endsWith("Props")
430
+ );
431
+ if (!mainComponent) {
432
+ return null;
433
+ }
434
+ result.componentName = mainComponent;
435
+ result.isDefaultExport = defaultExports.has(mainComponent);
436
+ const propsInterfaceName = `${mainComponent}Props`;
437
+ const propsInterface = propsInterfaces.get(propsInterfaceName);
438
+ if (propsInterface) {
439
+ result.propsInterfaceName = propsInterfaceName;
440
+ result.props = extractPropsFromInterface(propsInterface, sourceFile);
441
+ }
442
+ return result;
443
+ }
444
+ function extractPropsFromInterface(node, sourceFile) {
445
+ const props = {};
446
+ if (ts.isInterfaceDeclaration(node)) {
447
+ for (const member of node.members) {
448
+ if (ts.isPropertySignature(member) && member.name) {
449
+ const propName = member.name.getText(sourceFile);
450
+ const prop = extractPropFromMember(member, sourceFile);
451
+ if (prop) {
452
+ props[propName] = prop;
453
+ }
454
+ }
455
+ }
456
+ }
457
+ if (ts.isTypeAliasDeclaration(node)) {
458
+ const typeNode = node.type;
459
+ if (ts.isTypeLiteralNode(typeNode)) {
460
+ for (const member of typeNode.members) {
461
+ if (ts.isPropertySignature(member) && member.name) {
462
+ const propName = member.name.getText(sourceFile);
463
+ const prop = extractPropFromMember(member, sourceFile);
464
+ if (prop) {
465
+ props[propName] = prop;
466
+ }
467
+ }
468
+ }
469
+ }
470
+ }
471
+ return props;
472
+ }
473
+ function extractPropFromMember(member, sourceFile) {
474
+ const entry = {};
475
+ entry.required = !member.questionToken;
476
+ if (member.type) {
477
+ const typeInfo = parseTypeNode(member.type, sourceFile);
478
+ entry.type = typeInfo.type;
479
+ entry.typeKind = typeInfo.typeKind;
480
+ if (typeInfo.options) {
481
+ entry.options = typeInfo.options;
482
+ }
483
+ }
484
+ const jsDocComment = getJSDocComment(member);
485
+ if (jsDocComment) {
486
+ entry.description = jsDocComment;
487
+ }
488
+ const defaultValue = getJSDocDefault(member);
489
+ if (defaultValue !== void 0) {
490
+ entry.default = defaultValue;
491
+ }
492
+ return entry;
493
+ }
494
+ function parseTypeNode(typeNode, sourceFile) {
495
+ if (typeNode.kind === ts.SyntaxKind.StringKeyword) {
496
+ return { type: "string", typeKind: "string" };
497
+ }
498
+ if (typeNode.kind === ts.SyntaxKind.NumberKeyword) {
499
+ return { type: "number", typeKind: "number" };
500
+ }
501
+ if (typeNode.kind === ts.SyntaxKind.BooleanKeyword) {
502
+ return { type: "boolean", typeKind: "boolean" };
503
+ }
504
+ if (ts.isUnionTypeNode(typeNode)) {
505
+ const options = [];
506
+ let allLiterals = true;
507
+ for (const subType of typeNode.types) {
508
+ if (ts.isLiteralTypeNode(subType)) {
509
+ if (ts.isStringLiteral(subType.literal)) {
510
+ options.push(subType.literal.text);
511
+ } else if (subType.literal.kind === ts.SyntaxKind.TrueKeyword) {
512
+ options.push("true");
513
+ } else if (subType.literal.kind === ts.SyntaxKind.FalseKeyword) {
514
+ options.push("false");
515
+ } else {
516
+ allLiterals = false;
517
+ }
518
+ } else {
519
+ allLiterals = false;
520
+ }
521
+ }
522
+ if (allLiterals && options.length > 0) {
523
+ return {
524
+ type: options.map((o) => `"${o}"`).join(" | "),
525
+ typeKind: "enum",
526
+ options
527
+ };
528
+ }
529
+ return {
530
+ type: typeNode.getText(sourceFile),
531
+ typeKind: "union"
532
+ };
533
+ }
534
+ if (ts.isFunctionTypeNode(typeNode)) {
535
+ return {
536
+ type: typeNode.getText(sourceFile),
537
+ typeKind: "function"
538
+ };
539
+ }
540
+ if (ts.isArrayTypeNode(typeNode)) {
541
+ return {
542
+ type: typeNode.getText(sourceFile),
543
+ typeKind: "array"
544
+ };
545
+ }
546
+ if (ts.isTypeReferenceNode(typeNode)) {
547
+ const typeName = typeNode.typeName.getText(sourceFile);
548
+ if (typeName === "ReactNode" || typeName === "React.ReactNode") {
549
+ return { type: "ReactNode", typeKind: "node" };
550
+ }
551
+ if (typeName === "ReactElement" || typeName === "React.ReactElement") {
552
+ return { type: "ReactElement", typeKind: "element" };
553
+ }
554
+ if (typeName === "JSX.Element") {
555
+ return { type: "JSX.Element", typeKind: "element" };
556
+ }
557
+ return {
558
+ type: typeNode.getText(sourceFile),
559
+ typeKind: "object"
560
+ };
561
+ }
562
+ if (ts.isTypeLiteralNode(typeNode)) {
563
+ return {
564
+ type: typeNode.getText(sourceFile),
565
+ typeKind: "object"
566
+ };
567
+ }
568
+ return {
569
+ type: typeNode.getText(sourceFile),
570
+ typeKind: "unknown"
571
+ };
572
+ }
573
+ function getJSDocComment(node) {
574
+ const jsDocTags = ts.getJSDocTags(node);
575
+ const jsDoc = node.jsDoc;
576
+ if (jsDoc && jsDoc.length > 0) {
577
+ const comment = jsDoc[0].comment;
578
+ if (typeof comment === "string") {
579
+ return comment;
580
+ }
581
+ if (Array.isArray(comment)) {
582
+ return comment.map((c) => typeof c === "string" ? c : c.text).join("");
583
+ }
584
+ }
585
+ return void 0;
586
+ }
587
+ function getJSDocDefault(node) {
588
+ const jsDocTags = ts.getJSDocTags(node);
589
+ for (const tag of jsDocTags) {
590
+ if (tag.tagName.text === "default") {
591
+ const comment = tag.comment;
592
+ if (typeof comment === "string") {
593
+ try {
594
+ return JSON.parse(comment);
595
+ } catch {
596
+ return comment;
597
+ }
598
+ }
599
+ }
600
+ }
601
+ return void 0;
602
+ }
603
+
604
+ // src/core/generators/registry.ts
605
+ import { readFileSync as readFileSync2 } from "fs";
606
+ import { relative, dirname as dirname3, basename as basename2, join } from "path";
607
+ import fg2 from "fast-glob";
608
+
398
609
  // src/core/loader.ts
399
610
  import { unlink } from "fs/promises";
400
- import { dirname as dirname3, basename as basename2, join } from "path";
611
+ import { dirname as dirname4, basename as basename3, join as join2 } from "path";
401
612
  import { pathToFileURL } from "url";
402
613
  import { build } from "esbuild";
403
614
  var DEFINE_FRAGMENT_SHIM = `
@@ -458,9 +669,9 @@ async function loadFragmentFile(absolutePath) {
458
669
  const module = await import(fileUrl);
459
670
  return unwrapFragmentExport(module.default ?? null);
460
671
  }
461
- const sourceDir = dirname3(absolutePath);
462
- const baseName = basename2(absolutePath, `.${ext}`);
463
- const tempFile = join(sourceDir, `.${baseName}.fragments-temp-${Date.now()}.mjs`);
672
+ const sourceDir = dirname4(absolutePath);
673
+ const baseName = basename3(absolutePath, `.${ext}`);
674
+ const tempFile = join2(sourceDir, `.${baseName}.fragments-temp-${Date.now()}.mjs`);
464
675
  try {
465
676
  await build({
466
677
  entryPoints: [absolutePath],
@@ -510,38 +721,17 @@ async function loadFragmentFile(absolutePath) {
510
721
  }
511
722
  }
512
723
  }
513
- async function loadFragmentFiles(absolutePaths) {
514
- const results = /* @__PURE__ */ new Map();
515
- await Promise.all(
516
- absolutePaths.map(async (path) => {
517
- try {
518
- const fragment = await loadFragmentFile(path);
519
- if (fragment) {
520
- results.set(path, fragment);
521
- } else {
522
- results.set(path, new Error("No default export found"));
523
- }
524
- } catch (error) {
525
- results.set(
526
- path,
527
- error instanceof Error ? error : new Error(String(error))
528
- );
529
- }
530
- })
531
- );
532
- return results;
533
- }
534
724
 
535
725
  // src/core/parser.ts
536
- import ts from "typescript";
726
+ import ts2 from "typescript";
537
727
  function parseFragmentFile(fileContent, filePath) {
538
728
  const warnings = [];
539
- const sourceFile = ts.createSourceFile(
729
+ const sourceFile = ts2.createSourceFile(
540
730
  filePath ?? "fragment.tsx",
541
731
  fileContent,
542
- ts.ScriptTarget.Latest,
732
+ ts2.ScriptTarget.Latest,
543
733
  true,
544
- ts.ScriptKind.TSX
734
+ ts2.ScriptKind.TSX
545
735
  );
546
736
  const imports = extractImports(sourceFile);
547
737
  const defineFragmentCall = findDefineFragmentCall(sourceFile);
@@ -559,7 +749,7 @@ function parseFragmentFile(fileContent, filePath) {
559
749
  };
560
750
  }
561
751
  const arg = defineFragmentCall.arguments[0];
562
- if (!arg || !ts.isObjectLiteralExpression(arg)) {
752
+ if (!arg || !ts2.isObjectLiteralExpression(arg)) {
563
753
  warnings.push("defineFragment() argument is not an object literal");
564
754
  return {
565
755
  componentImport: null,
@@ -575,7 +765,7 @@ function parseFragmentFile(fileContent, filePath) {
575
765
  const componentProp = findProperty(arg, "component");
576
766
  let componentName = null;
577
767
  let componentImport = null;
578
- if (componentProp && ts.isIdentifier(componentProp)) {
768
+ if (componentProp && ts2.isIdentifier(componentProp)) {
579
769
  componentName = componentProp.text;
580
770
  componentImport = imports.get(componentName) ?? null;
581
771
  }
@@ -601,10 +791,10 @@ function parseFragmentFile(fileContent, filePath) {
601
791
  }
602
792
  function extractImports(sourceFile) {
603
793
  const imports = /* @__PURE__ */ new Map();
604
- ts.forEachChild(sourceFile, (node) => {
605
- if (ts.isImportDeclaration(node)) {
794
+ ts2.forEachChild(sourceFile, (node) => {
795
+ if (ts2.isImportDeclaration(node)) {
606
796
  const moduleSpecifier = node.moduleSpecifier;
607
- if (ts.isStringLiteral(moduleSpecifier)) {
797
+ if (ts2.isStringLiteral(moduleSpecifier)) {
608
798
  const modulePath = moduleSpecifier.text;
609
799
  const importClause = node.importClause;
610
800
  if (importClause) {
@@ -612,7 +802,7 @@ function extractImports(sourceFile) {
612
802
  imports.set(importClause.name.text, modulePath);
613
803
  }
614
804
  const namedBindings = importClause.namedBindings;
615
- if (namedBindings && ts.isNamedImports(namedBindings)) {
805
+ if (namedBindings && ts2.isNamedImports(namedBindings)) {
616
806
  for (const element of namedBindings.elements) {
617
807
  imports.set(element.name.text, modulePath);
618
808
  }
@@ -626,23 +816,23 @@ function extractImports(sourceFile) {
626
816
  function findDefineFragmentCall(sourceFile) {
627
817
  let result = null;
628
818
  function visit(node) {
629
- if (ts.isCallExpression(node)) {
819
+ if (ts2.isCallExpression(node)) {
630
820
  const expression = node.expression;
631
- if (ts.isIdentifier(expression) && expression.text === "defineFragment") {
821
+ if (ts2.isIdentifier(expression) && expression.text === "defineFragment") {
632
822
  result = node;
633
823
  return;
634
824
  }
635
825
  }
636
- ts.forEachChild(node, visit);
826
+ ts2.forEachChild(node, visit);
637
827
  }
638
828
  visit(sourceFile);
639
829
  return result;
640
830
  }
641
831
  function findProperty(obj, name) {
642
832
  for (const prop of obj.properties) {
643
- if (ts.isPropertyAssignment(prop)) {
833
+ if (ts2.isPropertyAssignment(prop)) {
644
834
  const propName = prop.name;
645
- if (ts.isIdentifier(propName) && propName.text === name) {
835
+ if (ts2.isIdentifier(propName) && propName.text === name) {
646
836
  return prop.initializer;
647
837
  }
648
838
  }
@@ -651,7 +841,7 @@ function findProperty(obj, name) {
651
841
  }
652
842
  function extractMeta(arg, warnings) {
653
843
  const metaProp = findProperty(arg, "meta");
654
- if (!metaProp || !ts.isObjectLiteralExpression(metaProp)) {
844
+ if (!metaProp || !ts2.isObjectLiteralExpression(metaProp)) {
655
845
  warnings.push("No meta object found");
656
846
  return {};
657
847
  }
@@ -671,7 +861,7 @@ function extractMeta(arg, warnings) {
671
861
  const tags = extractStringArray(metaProp, "tags");
672
862
  if (tags.length > 0) meta.tags = tags;
673
863
  const depsProp = findProperty(metaProp, "dependencies");
674
- if (depsProp && ts.isArrayLiteralExpression(depsProp)) {
864
+ if (depsProp && ts2.isArrayLiteralExpression(depsProp)) {
675
865
  const deps = extractLiteralValue(depsProp);
676
866
  if (Array.isArray(deps) && deps.length > 0) {
677
867
  meta.dependencies = deps;
@@ -681,7 +871,7 @@ function extractMeta(arg, warnings) {
681
871
  }
682
872
  function extractUsage(arg, warnings) {
683
873
  const usageProp = findProperty(arg, "usage");
684
- if (!usageProp || !ts.isObjectLiteralExpression(usageProp)) {
874
+ if (!usageProp || !ts2.isObjectLiteralExpression(usageProp)) {
685
875
  return { when: [], whenNot: [] };
686
876
  }
687
877
  return {
@@ -693,15 +883,15 @@ function extractUsage(arg, warnings) {
693
883
  }
694
884
  function extractProps(arg, warnings) {
695
885
  const propsProp = findProperty(arg, "props");
696
- if (!propsProp || !ts.isObjectLiteralExpression(propsProp)) {
886
+ if (!propsProp || !ts2.isObjectLiteralExpression(propsProp)) {
697
887
  return {};
698
888
  }
699
889
  const props = {};
700
890
  for (const prop of propsProp.properties) {
701
- if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
891
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
702
892
  const propName = prop.name.text;
703
893
  const propValue = prop.initializer;
704
- if (ts.isObjectLiteralExpression(propValue)) {
894
+ if (ts2.isObjectLiteralExpression(propValue)) {
705
895
  props[propName] = extractPropDefinition(propValue);
706
896
  }
707
897
  }
@@ -728,12 +918,12 @@ function extractPropDefinition(obj) {
728
918
  }
729
919
  function extractVariants(arg, sourceFile, warnings) {
730
920
  const variantsProp = findProperty(arg, "variants");
731
- if (!variantsProp || !ts.isArrayLiteralExpression(variantsProp)) {
921
+ if (!variantsProp || !ts2.isArrayLiteralExpression(variantsProp)) {
732
922
  return [];
733
923
  }
734
924
  const variants = [];
735
925
  for (const element of variantsProp.elements) {
736
- if (ts.isObjectLiteralExpression(element)) {
926
+ if (ts2.isObjectLiteralExpression(element)) {
737
927
  const name = extractStringProperty(element, "name");
738
928
  const description = extractStringProperty(element, "description");
739
929
  if (name) {
@@ -742,7 +932,7 @@ function extractVariants(arg, sourceFile, warnings) {
742
932
  description: description ?? ""
743
933
  };
744
934
  const codeProp = findProperty(element, "code");
745
- if (codeProp && (ts.isStringLiteral(codeProp) || ts.isNoSubstitutionTemplateLiteral(codeProp))) {
935
+ if (codeProp && (ts2.isStringLiteral(codeProp) || ts2.isNoSubstitutionTemplateLiteral(codeProp))) {
746
936
  variant.code = codeProp.text;
747
937
  }
748
938
  const renderProp = findProperty(element, "render");
@@ -754,7 +944,7 @@ function extractVariants(arg, sourceFile, warnings) {
754
944
  variant.figma = figma;
755
945
  }
756
946
  const argsProp = findProperty(element, "args");
757
- if (argsProp && ts.isObjectLiteralExpression(argsProp)) {
947
+ if (argsProp && ts2.isObjectLiteralExpression(argsProp)) {
758
948
  const argsValue = extractLiteralValue(argsProp);
759
949
  if (argsValue && typeof argsValue === "object" && !Array.isArray(argsValue)) {
760
950
  variant.args = argsValue;
@@ -793,7 +983,7 @@ function dedent(str) {
793
983
  }).join("\n");
794
984
  }
795
985
  function extractRenderCode(renderProp, sourceFile) {
796
- if (ts.isArrowFunction(renderProp)) {
986
+ if (ts2.isArrowFunction(renderProp)) {
797
987
  const body = renderProp.body;
798
988
  const start = body.getStart(sourceFile);
799
989
  const end = body.getEnd();
@@ -808,12 +998,12 @@ function extractRenderCode(renderProp, sourceFile) {
808
998
  }
809
999
  function extractRelations(arg, warnings) {
810
1000
  const relationsProp = findProperty(arg, "relations");
811
- if (!relationsProp || !ts.isArrayLiteralExpression(relationsProp)) {
1001
+ if (!relationsProp || !ts2.isArrayLiteralExpression(relationsProp)) {
812
1002
  return [];
813
1003
  }
814
1004
  const relations = [];
815
1005
  for (const element of relationsProp.elements) {
816
- if (ts.isObjectLiteralExpression(element)) {
1006
+ if (ts2.isObjectLiteralExpression(element)) {
817
1007
  const component = extractStringProperty(element, "component");
818
1008
  const relationship = extractStringProperty(element, "relationship");
819
1009
  const note = extractStringProperty(element, "note");
@@ -830,7 +1020,7 @@ function extractRelations(arg, warnings) {
830
1020
  }
831
1021
  function extractAIMetadata(arg, warnings) {
832
1022
  const aiProp = findProperty(arg, "ai");
833
- if (!aiProp || !ts.isObjectLiteralExpression(aiProp)) {
1023
+ if (!aiProp || !ts2.isObjectLiteralExpression(aiProp)) {
834
1024
  return void 0;
835
1025
  }
836
1026
  const ai = {};
@@ -857,7 +1047,7 @@ function extractAIMetadata(arg, warnings) {
857
1047
  }
858
1048
  function extractContractMetadata(arg) {
859
1049
  const contractProp = findProperty(arg, "contract");
860
- if (!contractProp || !ts.isObjectLiteralExpression(contractProp)) {
1050
+ if (!contractProp || !ts2.isObjectLiteralExpression(contractProp)) {
861
1051
  return void 0;
862
1052
  }
863
1053
  const contract = {};
@@ -876,10 +1066,10 @@ function extractContractMetadata(arg) {
876
1066
  }
877
1067
  function extractStringProperty(obj, name) {
878
1068
  const prop = findProperty(obj, name);
879
- if (prop && ts.isStringLiteral(prop)) {
1069
+ if (prop && ts2.isStringLiteral(prop)) {
880
1070
  return prop.text;
881
1071
  }
882
- if (prop && ts.isNoSubstitutionTemplateLiteral(prop)) {
1072
+ if (prop && ts2.isNoSubstitutionTemplateLiteral(prop)) {
883
1073
  return prop.text;
884
1074
  }
885
1075
  return null;
@@ -887,49 +1077,49 @@ function extractStringProperty(obj, name) {
887
1077
  function extractBooleanProperty(obj, name) {
888
1078
  const prop = findProperty(obj, name);
889
1079
  if (prop) {
890
- if (prop.kind === ts.SyntaxKind.TrueKeyword) return true;
891
- if (prop.kind === ts.SyntaxKind.FalseKeyword) return false;
1080
+ if (prop.kind === ts2.SyntaxKind.TrueKeyword) return true;
1081
+ if (prop.kind === ts2.SyntaxKind.FalseKeyword) return false;
892
1082
  }
893
1083
  return null;
894
1084
  }
895
1085
  function extractStringArray(obj, name) {
896
1086
  const prop = findProperty(obj, name);
897
- if (!prop || !ts.isArrayLiteralExpression(prop)) {
1087
+ if (!prop || !ts2.isArrayLiteralExpression(prop)) {
898
1088
  return [];
899
1089
  }
900
1090
  const result = [];
901
1091
  for (const element of prop.elements) {
902
- if (ts.isStringLiteral(element)) {
1092
+ if (ts2.isStringLiteral(element)) {
903
1093
  result.push(element.text);
904
- } else if (ts.isNoSubstitutionTemplateLiteral(element)) {
1094
+ } else if (ts2.isNoSubstitutionTemplateLiteral(element)) {
905
1095
  result.push(element.text);
906
1096
  }
907
1097
  }
908
1098
  return result;
909
1099
  }
910
1100
  function extractLiteralValue(expr) {
911
- if (ts.isStringLiteral(expr)) {
1101
+ if (ts2.isStringLiteral(expr)) {
912
1102
  return expr.text;
913
1103
  }
914
- if (ts.isNumericLiteral(expr)) {
1104
+ if (ts2.isNumericLiteral(expr)) {
915
1105
  return Number(expr.text);
916
1106
  }
917
- if (expr.kind === ts.SyntaxKind.TrueKeyword) {
1107
+ if (expr.kind === ts2.SyntaxKind.TrueKeyword) {
918
1108
  return true;
919
1109
  }
920
- if (expr.kind === ts.SyntaxKind.FalseKeyword) {
1110
+ if (expr.kind === ts2.SyntaxKind.FalseKeyword) {
921
1111
  return false;
922
1112
  }
923
- if (expr.kind === ts.SyntaxKind.NullKeyword) {
1113
+ if (expr.kind === ts2.SyntaxKind.NullKeyword) {
924
1114
  return null;
925
1115
  }
926
- if (ts.isArrayLiteralExpression(expr)) {
1116
+ if (ts2.isArrayLiteralExpression(expr)) {
927
1117
  return expr.elements.map(extractLiteralValue);
928
1118
  }
929
- if (ts.isObjectLiteralExpression(expr)) {
1119
+ if (ts2.isObjectLiteralExpression(expr)) {
930
1120
  const obj = {};
931
1121
  for (const prop of expr.properties) {
932
- if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
1122
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.name)) {
933
1123
  obj[prop.name.text] = extractLiteralValue(prop.initializer);
934
1124
  }
935
1125
  }
@@ -939,988 +1129,24 @@ function extractLiteralValue(expr) {
939
1129
  }
940
1130
 
941
1131
  // src/core/previewLoader.ts
942
- import { existsSync as existsSync3 } from "fs";
943
- import { join as join2, resolve as resolve3 } from "path";
944
- var PREVIEW_FILES = [
945
- "preview.tsx",
946
- "preview.ts",
947
- "preview.jsx",
948
- "preview.js"
949
- ];
950
- function findPreviewConfigPath(storybookDir) {
951
- for (const fileName of PREVIEW_FILES) {
952
- const filePath = join2(storybookDir, fileName);
953
- if (existsSync3(filePath)) {
954
- return filePath;
955
- }
956
- }
957
- return null;
958
- }
959
- function findStorybookDir(projectRoot) {
960
- const possiblePaths = [
961
- join2(projectRoot, ".storybook"),
962
- join2(projectRoot, "storybook")
963
- ];
964
- for (const dir of possiblePaths) {
965
- if (existsSync3(dir)) {
966
- return dir;
967
- }
968
- }
969
- return null;
970
- }
971
- async function loadPreviewConfig(previewPath) {
972
- try {
973
- const fileUrl = new URL(`file://${resolve3(previewPath)}`);
974
- const module = await import(fileUrl.href);
975
- const config = {
976
- decorators: module.decorators ?? module.default?.decorators ?? [],
977
- parameters: module.parameters ?? module.default?.parameters ?? {},
978
- globalTypes: module.globalTypes ?? module.default?.globalTypes ?? {},
979
- args: module.args ?? module.default?.args ?? {},
980
- argTypes: module.argTypes ?? module.default?.argTypes ?? {},
981
- loaders: module.loaders ?? module.default?.loaders ?? []
982
- };
983
- return config;
984
- } catch (error) {
985
- console.warn(
986
- `[Fragments] Failed to load preview config from ${previewPath}:`,
987
- error instanceof Error ? error.message : error
988
- );
989
- return {};
990
- }
991
- }
992
- async function autoLoadPreviewConfig(projectRoot) {
993
- const storybookDir = findStorybookDir(projectRoot);
994
- if (!storybookDir) {
995
- return {};
996
- }
997
- const previewPath = findPreviewConfigPath(storybookDir);
998
- if (!previewPath) {
999
- return {};
1000
- }
1001
- return loadPreviewConfig(previewPath);
1002
- }
1003
- function generatePreviewModule(previewPath) {
1004
- if (!previewPath) {
1005
- return `
1006
- export const decorators = [];
1007
- export const parameters = {};
1008
- export const globalTypes = {};
1009
- export const args = {};
1010
- export const argTypes = {};
1011
- export const loaders = [];
1012
-
1013
- export default {
1014
- decorators,
1015
- parameters,
1016
- globalTypes,
1017
- args,
1018
- argTypes,
1019
- loaders,
1020
- };
1021
- `;
1022
- }
1023
- return `
1024
- import * as preview from "${previewPath}";
1025
-
1026
- export const decorators = preview.decorators ?? preview.default?.decorators ?? [];
1027
- export const parameters = preview.parameters ?? preview.default?.parameters ?? {};
1028
- export const globalTypes = preview.globalTypes ?? preview.default?.globalTypes ?? {};
1029
- export const args = preview.args ?? preview.default?.args ?? {};
1030
- export const argTypes = preview.argTypes ?? preview.default?.argTypes ?? {};
1031
- export const loaders = preview.loaders ?? preview.default?.loaders ?? [];
1032
-
1033
- export default {
1034
- decorators,
1035
- parameters,
1036
- globalTypes,
1037
- args,
1038
- argTypes,
1039
- loaders,
1040
- };
1041
- `;
1042
- }
1043
-
1044
- // src/core/generators/typescript-extractor.ts
1045
- import ts2 from "typescript";
1046
- import { readFileSync } from "fs";
1047
- function extractPropsFromFile(filePath) {
1048
- const sourceText = readFileSync(filePath, "utf-8");
1049
- return extractPropsFromSource(sourceText, filePath);
1050
- }
1051
- function extractPropsFromSource(sourceText, fileName = "component.tsx") {
1052
- const sourceFile = ts2.createSourceFile(
1053
- fileName,
1054
- sourceText,
1055
- ts2.ScriptTarget.Latest,
1056
- true,
1057
- fileName.endsWith(".tsx") ? ts2.ScriptKind.TSX : ts2.ScriptKind.TS
1058
- );
1059
- const result = {
1060
- componentName: "",
1061
- props: {},
1062
- exports: [],
1063
- imports: []
1064
- };
1065
- const propsInterfaces = /* @__PURE__ */ new Map();
1066
- const componentExports = [];
1067
- const defaultExports = /* @__PURE__ */ new Set();
1068
- const importedModules = [];
1069
- ts2.forEachChild(sourceFile, (node) => {
1070
- if (ts2.isImportDeclaration(node)) {
1071
- const moduleSpecifier = node.moduleSpecifier;
1072
- if (ts2.isStringLiteral(moduleSpecifier)) {
1073
- importedModules.push(moduleSpecifier.text);
1074
- }
1075
- }
1076
- if (ts2.isInterfaceDeclaration(node)) {
1077
- const name = node.name.text;
1078
- if (name.endsWith("Props")) {
1079
- propsInterfaces.set(name, node);
1080
- }
1081
- }
1082
- if (ts2.isTypeAliasDeclaration(node)) {
1083
- const name = node.name.text;
1084
- if (name.endsWith("Props")) {
1085
- propsInterfaces.set(name, node);
1086
- }
1087
- }
1088
- if (ts2.isFunctionDeclaration(node) && node.name) {
1089
- const hasExport = node.modifiers?.some(
1090
- (m) => m.kind === ts2.SyntaxKind.ExportKeyword
1091
- );
1092
- const hasDefault = node.modifiers?.some(
1093
- (m) => m.kind === ts2.SyntaxKind.DefaultKeyword
1094
- );
1095
- if (hasExport) {
1096
- componentExports.push(node.name.text);
1097
- if (hasDefault) {
1098
- defaultExports.add(node.name.text);
1099
- }
1100
- }
1101
- }
1102
- if (ts2.isVariableStatement(node)) {
1103
- const hasExport = node.modifiers?.some(
1104
- (m) => m.kind === ts2.SyntaxKind.ExportKeyword
1105
- );
1106
- if (hasExport) {
1107
- for (const decl of node.declarationList.declarations) {
1108
- if (ts2.isIdentifier(decl.name)) {
1109
- componentExports.push(decl.name.text);
1110
- }
1111
- }
1112
- }
1113
- }
1114
- if (ts2.isExportDeclaration(node) && node.exportClause) {
1115
- if (ts2.isNamedExports(node.exportClause)) {
1116
- for (const element of node.exportClause.elements) {
1117
- componentExports.push(element.name.text);
1118
- }
1119
- }
1120
- }
1121
- });
1122
- result.exports = componentExports;
1123
- result.imports = importedModules;
1124
- const mainComponent = componentExports.find(
1125
- (name) => /^[A-Z]/.test(name) && !name.endsWith("Props")
1126
- );
1127
- if (!mainComponent) {
1128
- return null;
1129
- }
1130
- result.componentName = mainComponent;
1131
- result.isDefaultExport = defaultExports.has(mainComponent);
1132
- const propsInterfaceName = `${mainComponent}Props`;
1133
- const propsInterface = propsInterfaces.get(propsInterfaceName);
1134
- if (propsInterface) {
1135
- result.propsInterfaceName = propsInterfaceName;
1136
- result.props = extractPropsFromInterface(propsInterface, sourceFile);
1137
- }
1138
- return result;
1139
- }
1140
- function extractPropsFromInterface(node, sourceFile) {
1141
- const props = {};
1142
- if (ts2.isInterfaceDeclaration(node)) {
1143
- for (const member of node.members) {
1144
- if (ts2.isPropertySignature(member) && member.name) {
1145
- const propName = member.name.getText(sourceFile);
1146
- const prop = extractPropFromMember(member, sourceFile);
1147
- if (prop) {
1148
- props[propName] = prop;
1149
- }
1150
- }
1151
- }
1152
- }
1153
- if (ts2.isTypeAliasDeclaration(node)) {
1154
- const typeNode = node.type;
1155
- if (ts2.isTypeLiteralNode(typeNode)) {
1156
- for (const member of typeNode.members) {
1157
- if (ts2.isPropertySignature(member) && member.name) {
1158
- const propName = member.name.getText(sourceFile);
1159
- const prop = extractPropFromMember(member, sourceFile);
1160
- if (prop) {
1161
- props[propName] = prop;
1162
- }
1163
- }
1164
- }
1165
- }
1166
- }
1167
- return props;
1168
- }
1169
- function extractPropFromMember(member, sourceFile) {
1170
- const entry = {};
1171
- entry.required = !member.questionToken;
1172
- if (member.type) {
1173
- const typeInfo = parseTypeNode(member.type, sourceFile);
1174
- entry.type = typeInfo.type;
1175
- entry.typeKind = typeInfo.typeKind;
1176
- if (typeInfo.options) {
1177
- entry.options = typeInfo.options;
1178
- }
1179
- }
1180
- const jsDocComment = getJSDocComment(member);
1181
- if (jsDocComment) {
1182
- entry.description = jsDocComment;
1183
- }
1184
- const defaultValue = getJSDocDefault(member);
1185
- if (defaultValue !== void 0) {
1186
- entry.default = defaultValue;
1187
- }
1188
- return entry;
1189
- }
1190
- function parseTypeNode(typeNode, sourceFile) {
1191
- if (typeNode.kind === ts2.SyntaxKind.StringKeyword) {
1192
- return { type: "string", typeKind: "string" };
1193
- }
1194
- if (typeNode.kind === ts2.SyntaxKind.NumberKeyword) {
1195
- return { type: "number", typeKind: "number" };
1196
- }
1197
- if (typeNode.kind === ts2.SyntaxKind.BooleanKeyword) {
1198
- return { type: "boolean", typeKind: "boolean" };
1199
- }
1200
- if (ts2.isUnionTypeNode(typeNode)) {
1201
- const options = [];
1202
- let allLiterals = true;
1203
- for (const subType of typeNode.types) {
1204
- if (ts2.isLiteralTypeNode(subType)) {
1205
- if (ts2.isStringLiteral(subType.literal)) {
1206
- options.push(subType.literal.text);
1207
- } else if (subType.literal.kind === ts2.SyntaxKind.TrueKeyword) {
1208
- options.push("true");
1209
- } else if (subType.literal.kind === ts2.SyntaxKind.FalseKeyword) {
1210
- options.push("false");
1211
- } else {
1212
- allLiterals = false;
1213
- }
1214
- } else {
1215
- allLiterals = false;
1216
- }
1217
- }
1218
- if (allLiterals && options.length > 0) {
1219
- return {
1220
- type: options.map((o) => `"${o}"`).join(" | "),
1221
- typeKind: "enum",
1222
- options
1223
- };
1224
- }
1225
- return {
1226
- type: typeNode.getText(sourceFile),
1227
- typeKind: "union"
1228
- };
1229
- }
1230
- if (ts2.isFunctionTypeNode(typeNode)) {
1231
- return {
1232
- type: typeNode.getText(sourceFile),
1233
- typeKind: "function"
1234
- };
1235
- }
1236
- if (ts2.isArrayTypeNode(typeNode)) {
1237
- return {
1238
- type: typeNode.getText(sourceFile),
1239
- typeKind: "array"
1240
- };
1241
- }
1242
- if (ts2.isTypeReferenceNode(typeNode)) {
1243
- const typeName = typeNode.typeName.getText(sourceFile);
1244
- if (typeName === "ReactNode" || typeName === "React.ReactNode") {
1245
- return { type: "ReactNode", typeKind: "node" };
1246
- }
1247
- if (typeName === "ReactElement" || typeName === "React.ReactElement") {
1248
- return { type: "ReactElement", typeKind: "element" };
1249
- }
1250
- if (typeName === "JSX.Element") {
1251
- return { type: "JSX.Element", typeKind: "element" };
1252
- }
1253
- return {
1254
- type: typeNode.getText(sourceFile),
1255
- typeKind: "object"
1256
- };
1257
- }
1258
- if (ts2.isTypeLiteralNode(typeNode)) {
1259
- return {
1260
- type: typeNode.getText(sourceFile),
1261
- typeKind: "object"
1262
- };
1263
- }
1264
- return {
1265
- type: typeNode.getText(sourceFile),
1266
- typeKind: "unknown"
1267
- };
1268
- }
1269
- function getJSDocComment(node) {
1270
- const jsDocTags = ts2.getJSDocTags(node);
1271
- const jsDoc = node.jsDoc;
1272
- if (jsDoc && jsDoc.length > 0) {
1273
- const comment = jsDoc[0].comment;
1274
- if (typeof comment === "string") {
1275
- return comment;
1276
- }
1277
- if (Array.isArray(comment)) {
1278
- return comment.map((c) => typeof c === "string" ? c : c.text).join("");
1279
- }
1280
- }
1281
- return void 0;
1282
- }
1283
- function getJSDocDefault(node) {
1284
- const jsDocTags = ts2.getJSDocTags(node);
1285
- for (const tag of jsDocTags) {
1286
- if (tag.tagName.text === "default") {
1287
- const comment = tag.comment;
1288
- if (typeof comment === "string") {
1289
- try {
1290
- return JSON.parse(comment);
1291
- } catch {
1292
- return comment;
1293
- }
1294
- }
1295
- }
1296
- }
1297
- return void 0;
1298
- }
1299
-
1300
- // src/core/generators/registry.ts
1301
- import { readFileSync as readFileSync2 } from "fs";
1302
- import { relative, dirname as dirname4, basename as basename3, join as join3 } from "path";
1303
- import fg2 from "fast-glob";
1304
- async function generateRegistry(options) {
1305
- const {
1306
- projectRoot,
1307
- componentPatterns = ["src/**/*.tsx", "src/**/*.ts"],
1308
- storyPatterns = ["src/**/*.stories.tsx", "src/**/*.stories.ts"],
1309
- fragmentsDir = join3(projectRoot, BRAND.dataDir),
1310
- registryOptions = {}
1311
- } = options;
1312
- const {
1313
- requireStory = false,
1314
- publicOnly = false,
1315
- categoryDepth = 1,
1316
- includeProps = false,
1317
- embedFragments = false
1318
- } = registryOptions;
1319
- const errors = [];
1320
- const warnings = [];
1321
- const storyFiles = await fg2(storyPatterns, {
1322
- cwd: projectRoot,
1323
- ignore: ["**/node_modules/**"],
1324
- absolute: true
1325
- });
1326
- const storyMap = /* @__PURE__ */ new Map();
1327
- for (const storyPath of storyFiles) {
1328
- const storyDir = dirname4(storyPath);
1329
- const storyBase = basename3(storyPath).replace(/\.stories\.(tsx?|jsx?)$/, "");
1330
- storyMap.set(`${storyDir}/${storyBase}`, storyPath);
1331
- }
1332
- const componentFiles = await fg2(componentPatterns, {
1333
- cwd: projectRoot,
1334
- ignore: [
1335
- "**/node_modules/**",
1336
- "**/*.stories.*",
1337
- "**/*.test.*",
1338
- "**/*.spec.*",
1339
- "**/*.d.ts"
1340
- ],
1341
- absolute: true
1342
- });
1343
- const fragmentPattern = join3(
1344
- BRAND.dataDir,
1345
- BRAND.componentsDir,
1346
- `*${BRAND.fileExtension}`
1347
- );
1348
- const fragmentFiles = await fg2(fragmentPattern, {
1349
- cwd: projectRoot,
1350
- absolute: true
1351
- });
1352
- const fragmentMap = /* @__PURE__ */ new Map();
1353
- for (const fragmentPath of fragmentFiles) {
1354
- const fragmentName = basename3(fragmentPath).replace(BRAND.fileExtension, "");
1355
- try {
1356
- const content = readFileSync2(fragmentPath, "utf-8");
1357
- const fragment = JSON.parse(content);
1358
- fragmentMap.set(fragmentName, {
1359
- path: relative(projectRoot, fragmentPath),
1360
- fragment
1361
- });
1362
- } catch (e) {
1363
- errors.push({
1364
- file: fragmentPath,
1365
- error: `Failed to parse fragment: ${e instanceof Error ? e.message : String(e)}`
1366
- });
1367
- }
1368
- }
1369
- const components = {};
1370
- const indexComponents = {};
1371
- const categories = {};
1372
- for (const filePath of componentFiles) {
1373
- try {
1374
- const extracted = extractPropsFromFile(filePath);
1375
- if (!extracted || !extracted.componentName) {
1376
- continue;
1377
- }
1378
- const componentName = extracted.componentName;
1379
- const relativePath = relative(projectRoot, filePath);
1380
- if (publicOnly && !extracted.exports.includes(componentName)) {
1381
- continue;
1382
- }
1383
- const componentDir = dirname4(filePath);
1384
- const baseNameWithoutExt = basename3(filePath).replace(/\.(tsx?|jsx?)$/, "");
1385
- const storyPath = storyMap.get(`${componentDir}/${baseNameWithoutExt}`);
1386
- if (requireStory && !storyPath) {
1387
- continue;
1388
- }
1389
- const fragmentData = fragmentMap.get(componentName);
1390
- const category = fragmentData?.fragment?.meta?.status ? void 0 : getCategoryFromPath(relativePath, categoryDepth);
1391
- const hasEnrichment = fragmentData ? hasRealEnrichment(fragmentData.fragment) : false;
1392
- const entry = {
1393
- path: relativePath
1394
- };
1395
- if (storyPath) {
1396
- entry.storyPath = relative(projectRoot, storyPath);
1397
- }
1398
- if (fragmentData) {
1399
- entry.fragmentPath = fragmentData.path;
1400
- if (hasEnrichment) {
1401
- entry.hasEnrichment = true;
1402
- }
1403
- if (fragmentData.fragment.description) {
1404
- entry.description = fragmentData.fragment.description;
1405
- }
1406
- if (fragmentData.fragment.meta?.status) {
1407
- entry.status = fragmentData.fragment.meta.status;
1408
- }
1409
- if (embedFragments) {
1410
- entry.fragment = fragmentData.fragment;
1411
- }
1412
- }
1413
- if (category) {
1414
- entry.category = category;
1415
- if (!categories[category]) {
1416
- categories[category] = [];
1417
- }
1418
- categories[category].push(componentName);
1419
- }
1420
- if (includeProps && extracted.props) {
1421
- entry.props = extracted.props;
1422
- }
1423
- if (extracted.exports.length > 1) {
1424
- entry.exports = extracted.exports;
1425
- }
1426
- components[componentName] = entry;
1427
- indexComponents[componentName] = relativePath;
1428
- } catch (e) {
1429
- errors.push({
1430
- file: filePath,
1431
- error: `Failed to extract component: ${e instanceof Error ? e.message : String(e)}`
1432
- });
1433
- }
1434
- }
1435
- const componentCount = Object.keys(components).length;
1436
- const registry = {
1437
- $schema: "https://fragments.dev/schema/registry-v1.json",
1438
- version: "1.0",
1439
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1440
- componentCount,
1441
- components,
1442
- categories
1443
- };
1444
- const index = {
1445
- version: "1.0",
1446
- generatedAt: registry.generatedAt,
1447
- components: indexComponents,
1448
- categories
1449
- };
1450
- return { registry, index, errors, warnings };
1451
- }
1452
- function getCategoryFromPath(relativePath, depth = 1) {
1453
- const parts = relativePath.split("/");
1454
- const componentsIndex = parts.findIndex((p) => p === "components");
1455
- if (componentsIndex === -1) {
1456
- return void 0;
1457
- }
1458
- const afterComponents = parts.slice(componentsIndex + 1);
1459
- if (afterComponents.length <= 1) {
1460
- return void 0;
1461
- }
1462
- const folderName = afterComponents[0];
1463
- const fileName = afterComponents[afterComponents.length - 1].replace(/\.(tsx?|jsx?)$/, "");
1464
- if (afterComponents.length === 2 && folderName === fileName) {
1465
- return void 0;
1466
- }
1467
- const categoryParts = afterComponents.slice(0, Math.min(depth, afterComponents.length - 1));
1468
- const lastCategoryPart = categoryParts[categoryParts.length - 1];
1469
- if (lastCategoryPart === fileName) {
1470
- categoryParts.pop();
1471
- }
1472
- if (categoryParts.length === 0) {
1473
- return void 0;
1474
- }
1475
- return categoryParts.join("/");
1476
- }
1477
- function hasRealEnrichment(fragment) {
1478
- if (fragment.description && fragment.description.length > 20) {
1479
- return true;
1480
- }
1481
- if (fragment.usage?.when && fragment.usage.when.length > 0) {
1482
- return true;
1483
- }
1484
- if (fragment.usage?.doNot && fragment.usage.doNot.length > 0) {
1485
- return true;
1486
- }
1487
- if (fragment.usage?.patterns && fragment.usage.patterns.length > 0) {
1488
- return true;
1489
- }
1490
- if (fragment.accessibility?.requirements && fragment.accessibility.requirements.length > 0) {
1491
- return true;
1492
- }
1493
- if (fragment.figma?.nodeId || fragment.figma?.variants) {
1494
- return true;
1495
- }
1496
- if (fragment.related?.similar && fragment.related.similar.length > 0) {
1497
- return true;
1498
- }
1499
- return false;
1500
- }
1501
- function resolveComponentPath(componentName, registry) {
1502
- const entry = registry.components[componentName];
1503
- return entry?.path;
1504
- }
1505
- function getComponentsByCategory(category, registry) {
1506
- return registry.categories?.[category] || [];
1507
- }
1508
-
1509
- // src/core/generators/context.ts
1510
- function generateContextMd(registry, options = {}) {
1511
- const {
1512
- format = "markdown",
1513
- compact = false,
1514
- include = { props: true, relations: true, code: false }
1515
- } = options;
1516
- if (format === "json") {
1517
- return generateJsonContext(registry, include, compact);
1518
- }
1519
- return generateMarkdownContext(registry, include, compact);
1520
- }
1521
- function generateMarkdownContext(registry, include, compact) {
1522
- const lines = [];
1523
- const componentNames = Object.keys(registry.components).sort();
1524
- const componentCount = componentNames.length;
1525
- lines.push("# Component Library Context");
1526
- lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]} | Components: ${componentCount}`);
1527
- lines.push("");
1528
- lines.push("## Quick Reference");
1529
- lines.push("");
1530
- lines.push("| Component | Path | Category | Status |");
1531
- lines.push("|-----------|------|----------|--------|");
1532
- for (const name of componentNames) {
1533
- const entry = registry.components[name];
1534
- const status = entry.status || "stable";
1535
- const category = entry.category || "-";
1536
- lines.push(`| ${name} | ${entry.path} | ${category} | ${status} |`);
1537
- }
1538
- lines.push("");
1539
- if (compact) {
1540
- const content2 = lines.join("\n");
1541
- return {
1542
- content: content2,
1543
- tokenEstimate: estimateTokens(content2),
1544
- componentCount
1545
- };
1546
- }
1547
- lines.push("---");
1548
- lines.push("");
1549
- for (const name of componentNames) {
1550
- const entry = registry.components[name];
1551
- const fragment = entry.fragment;
1552
- lines.push(`## ${name}`);
1553
- lines.push(`**Path:** \`${entry.path}\``);
1554
- if (entry.category) {
1555
- lines.push(`**Category:** ${entry.category} | **Status:** ${entry.status || "stable"}`);
1556
- }
1557
- lines.push("");
1558
- if (entry.description || fragment?.description) {
1559
- lines.push("### Description");
1560
- lines.push(entry.description || fragment?.description || "");
1561
- lines.push("");
1562
- }
1563
- if (fragment?.usage) {
1564
- if (fragment.usage.when && fragment.usage.when.length > 0) {
1565
- lines.push("### When to Use");
1566
- for (const when of fragment.usage.when) {
1567
- lines.push(`- ${when}`);
1568
- }
1569
- lines.push("");
1570
- }
1571
- if (fragment.usage.doNot && fragment.usage.doNot.length > 0) {
1572
- lines.push("### Do Not");
1573
- for (const doNotItem of fragment.usage.doNot) {
1574
- if (typeof doNotItem === "string") {
1575
- lines.push(`- ${doNotItem}`);
1576
- } else {
1577
- const item = doNotItem;
1578
- if (item.instead) {
1579
- const alternativePath = resolveComponentPath2(item.instead, registry);
1580
- if (alternativePath) {
1581
- lines.push(`- ${item.text} \u2192 use **${item.instead}** (\`${alternativePath}\`)`);
1582
- } else {
1583
- lines.push(`- ${item.text} \u2192 use **${item.instead}**`);
1584
- }
1585
- } else {
1586
- lines.push(`- ${item.text}`);
1587
- }
1588
- }
1589
- }
1590
- lines.push("");
1591
- }
1592
- if (include.code && fragment.usage.patterns && fragment.usage.patterns.length > 0) {
1593
- lines.push("### Patterns");
1594
- for (const pattern of fragment.usage.patterns) {
1595
- lines.push(`**${pattern.name}**`);
1596
- if (pattern.description) {
1597
- lines.push(pattern.description);
1598
- }
1599
- lines.push("```tsx");
1600
- lines.push(pattern.code);
1601
- lines.push("```");
1602
- lines.push("");
1603
- }
1604
- }
1605
- }
1606
- if (include.props && entry.props && Object.keys(entry.props).length > 0) {
1607
- lines.push("### Props");
1608
- lines.push("| Prop | Type | Default | Description |");
1609
- lines.push("|------|------|---------|-------------|");
1610
- for (const [propName, prop] of Object.entries(entry.props)) {
1611
- const type = formatPropType(prop);
1612
- const defaultVal = prop.default !== void 0 ? `\`${JSON.stringify(prop.default)}\`` : "-";
1613
- const desc = prop.description || "-";
1614
- const required = prop.required ? " (required)" : "";
1615
- lines.push(`| ${propName}${required} | ${type} | ${defaultVal} | ${desc} |`);
1616
- }
1617
- lines.push("");
1618
- }
1619
- if (fragment?.accessibility) {
1620
- lines.push("### Accessibility");
1621
- if (fragment.accessibility.role) {
1622
- lines.push(`**Role:** ${fragment.accessibility.role}`);
1623
- }
1624
- if (fragment.accessibility.requirements && fragment.accessibility.requirements.length > 0) {
1625
- for (const req of fragment.accessibility.requirements) {
1626
- lines.push(`- ${req}`);
1627
- }
1628
- }
1629
- if (fragment.accessibility.keyboard) {
1630
- lines.push("");
1631
- lines.push("**Keyboard:**");
1632
- for (const [key, action] of Object.entries(fragment.accessibility.keyboard)) {
1633
- lines.push(`- \`${key}\`: ${action}`);
1634
- }
1635
- }
1636
- lines.push("");
1637
- }
1638
- if (include.relations && fragment?.related) {
1639
- lines.push("### Related");
1640
- if (fragment.related.similar && fragment.related.similar.length > 0) {
1641
- const resolved = fragment.related.similar.map((comp) => {
1642
- const path = resolveComponentPath2(comp, registry);
1643
- return path ? `${comp} (\`${path}\`)` : comp;
1644
- });
1645
- lines.push(`- **Similar:** ${resolved.join(", ")}`);
1646
- }
1647
- if (fragment.related.composedWith && fragment.related.composedWith.length > 0) {
1648
- const resolved = fragment.related.composedWith.map((comp) => {
1649
- const path = resolveComponentPath2(comp, registry);
1650
- return path ? `${comp} (\`${path}\`)` : comp;
1651
- });
1652
- lines.push(`- **Composed with:** ${resolved.join(", ")}`);
1653
- }
1654
- if (fragment.related.usedIn && fragment.related.usedIn.length > 0) {
1655
- const resolved = fragment.related.usedIn.map((comp) => {
1656
- const path = resolveComponentPath2(comp, registry);
1657
- return path ? `${comp} (\`${path}\`)` : comp;
1658
- });
1659
- lines.push(`- **Used in:** ${resolved.join(", ")}`);
1660
- }
1661
- lines.push("");
1662
- }
1663
- lines.push("---");
1664
- lines.push("");
1665
- }
1666
- const content = lines.join("\n");
1667
- return {
1668
- content,
1669
- tokenEstimate: estimateTokens(content),
1670
- componentCount
1671
- };
1672
- }
1673
- function generateJsonContext(registry, include, compact) {
1674
- const componentNames = Object.keys(registry.components).sort();
1675
- const componentCount = componentNames.length;
1676
- const components = {};
1677
- for (const name of componentNames) {
1678
- const entry = registry.components[name];
1679
- const fragment = entry.fragment;
1680
- const component = {
1681
- path: entry.path
1682
- };
1683
- if (entry.category) component.category = entry.category;
1684
- if (entry.status) component.status = entry.status;
1685
- if (entry.description || fragment?.description) {
1686
- component.description = entry.description || fragment?.description;
1687
- }
1688
- if (!compact && fragment?.usage) {
1689
- if (fragment.usage.when && fragment.usage.when.length > 0) {
1690
- component.whenToUse = fragment.usage.when;
1691
- }
1692
- if (fragment.usage.doNot && fragment.usage.doNot.length > 0) {
1693
- component.doNot = fragment.usage.doNot.map((item) => {
1694
- if (typeof item === "string") {
1695
- return { text: item };
1696
- }
1697
- const doNotItem = item;
1698
- const result = {
1699
- text: doNotItem.text
1700
- };
1701
- if (doNotItem.instead) {
1702
- result.instead = doNotItem.instead;
1703
- result.insteadPath = resolveComponentPath2(doNotItem.instead, registry);
1704
- }
1705
- return result;
1706
- });
1707
- }
1708
- }
1709
- if (!compact && include.props && entry.props) {
1710
- component.props = {};
1711
- for (const [propName, prop] of Object.entries(entry.props)) {
1712
- component.props[propName] = {
1713
- type: formatPropType(prop)
1714
- };
1715
- if (prop.required) component.props[propName].required = true;
1716
- if (prop.default !== void 0) component.props[propName].default = prop.default;
1717
- if (prop.description) component.props[propName].description = prop.description;
1718
- }
1719
- }
1720
- if (!compact && include.relations && fragment?.related) {
1721
- component.related = {};
1722
- if (fragment.related.similar) {
1723
- component.related.similar = fragment.related.similar.map((name2) => ({
1724
- name: name2,
1725
- path: resolveComponentPath2(name2, registry)
1726
- }));
1727
- }
1728
- if (fragment.related.composedWith) {
1729
- component.related.composedWith = fragment.related.composedWith.map((name2) => ({
1730
- name: name2,
1731
- path: resolveComponentPath2(name2, registry)
1732
- }));
1733
- }
1734
- if (fragment.related.usedIn) {
1735
- component.related.usedIn = fragment.related.usedIn.map((name2) => ({
1736
- name: name2,
1737
- path: resolveComponentPath2(name2, registry)
1738
- }));
1739
- }
1740
- }
1741
- components[name] = component;
1742
- }
1743
- const output = {
1744
- version: "1.0",
1745
- generatedAt: registry.generatedAt,
1746
- componentCount,
1747
- categories: registry.categories,
1748
- components
1749
- };
1750
- const content = JSON.stringify(output, null, 2);
1751
- return {
1752
- content,
1753
- tokenEstimate: estimateTokens(content),
1754
- componentCount
1755
- };
1756
- }
1757
- function resolveComponentPath2(componentName, registry) {
1758
- return registry.components[componentName]?.path;
1759
- }
1760
- function formatPropType(prop) {
1761
- if (prop.options && prop.options.length > 0) {
1762
- return prop.options.map((o) => `"${o}"`).join(" \\| ");
1763
- }
1764
- return prop.type || "unknown";
1765
- }
1766
- function estimateTokens(text) {
1767
- return Math.ceil(text.length / 4);
1768
- }
1132
+ import { existsSync as existsSync4 } from "fs";
1133
+ import { join as join3, resolve as resolve3 } from "path";
1769
1134
 
1770
1135
  // src/core/importAnalyzer.ts
1771
1136
  import ts3 from "typescript";
1772
1137
  import { readFileSync as readFileSync3 } from "fs";
1773
1138
  import { dirname as dirname5, basename as basename4 } from "path";
1774
- function extractComponentNameFromPath(filePath) {
1775
- const fileName = basename4(filePath);
1776
- if (fileName === "index.tsx" || fileName === "index.ts" || fileName === "index.jsx" || fileName === "index.js") {
1777
- const parentDir = basename4(dirname5(filePath));
1778
- return parentDir;
1779
- }
1780
- return fileName.replace(/\.(tsx?|jsx?)$/, "").replace(/\.stories$/, "").replace(/\.fragment$/, "").replace(/\.fragment$/, "");
1781
- }
1782
- function isComponentImportPath(importPath) {
1783
- if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
1784
- return false;
1785
- }
1786
- const skipPatterns = [
1787
- /\/hooks\//,
1788
- /\/utils\//,
1789
- /\/helpers\//,
1790
- /\/lib\//,
1791
- /\/types\//,
1792
- /\/constants\//,
1793
- /\/styles\//,
1794
- /\/context\//,
1795
- /\.css$/,
1796
- /\.scss$/,
1797
- /\.less$/,
1798
- /\.json$/
1799
- ];
1800
- for (const pattern of skipPatterns) {
1801
- if (pattern.test(importPath)) {
1802
- return false;
1803
- }
1804
- }
1805
- return true;
1806
- }
1807
- function isPascalCase(name) {
1808
- return /^[A-Z][a-zA-Z0-9]*$/.test(name);
1809
- }
1810
- function analyzeFileImports(filePath) {
1811
- const componentName = extractComponentNameFromPath(filePath);
1812
- const imports = [];
1813
- let sourceText;
1814
- try {
1815
- sourceText = readFileSync3(filePath, "utf-8");
1816
- } catch {
1817
- return { filePath, componentName, imports };
1818
- }
1819
- const sourceFile = ts3.createSourceFile(
1820
- filePath,
1821
- sourceText,
1822
- ts3.ScriptTarget.Latest,
1823
- true,
1824
- filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ? ts3.ScriptKind.TSX : ts3.ScriptKind.TS
1825
- );
1826
- ts3.forEachChild(sourceFile, (node) => {
1827
- if (ts3.isImportDeclaration(node)) {
1828
- const moduleSpecifier = node.moduleSpecifier;
1829
- if (!ts3.isStringLiteral(moduleSpecifier)) return;
1830
- const importPath = moduleSpecifier.text;
1831
- if (!isComponentImportPath(importPath)) return;
1832
- const importClause = node.importClause;
1833
- if (!importClause) return;
1834
- if (importClause.name) {
1835
- const name = importClause.name.text;
1836
- if (isPascalCase(name)) {
1837
- imports.push({
1838
- name,
1839
- path: importPath,
1840
- isDefault: true,
1841
- isNamespace: false
1842
- });
1843
- }
1844
- }
1845
- const namedBindings = importClause.namedBindings;
1846
- if (namedBindings) {
1847
- if (ts3.isNamedImports(namedBindings)) {
1848
- for (const element of namedBindings.elements) {
1849
- const name = element.name.text;
1850
- if (isPascalCase(name)) {
1851
- imports.push({
1852
- name,
1853
- path: importPath,
1854
- isDefault: false,
1855
- isNamespace: false
1856
- });
1857
- }
1858
- }
1859
- } else if (ts3.isNamespaceImport(namedBindings)) {
1860
- const name = namedBindings.name.text;
1861
- imports.push({
1862
- name,
1863
- path: importPath,
1864
- isDefault: false,
1865
- isNamespace: true
1866
- });
1867
- }
1868
- }
1869
- }
1870
- });
1871
- return { filePath, componentName, imports };
1872
- }
1873
- function buildImportGraph(filePaths) {
1874
- const importedBy = /* @__PURE__ */ new Map();
1875
- for (const filePath of filePaths) {
1876
- const result = analyzeFileImports(filePath);
1877
- for (const imp of result.imports) {
1878
- if (imp.isNamespace) continue;
1879
- const importedComponent = imp.name;
1880
- const importingComponent = result.componentName;
1881
- if (importedComponent === importingComponent) continue;
1882
- const existing = importedBy.get(importedComponent) || [];
1883
- if (!existing.includes(importingComponent)) {
1884
- existing.push(importingComponent);
1885
- importedBy.set(importedComponent, existing);
1886
- }
1887
- }
1888
- }
1889
- return importedBy;
1890
- }
1891
- function getImportedBy(componentName, importGraph) {
1892
- return importGraph.get(componentName) || [];
1893
- }
1894
1139
 
1895
1140
  export {
1896
1141
  findConfigFile,
1897
1142
  loadConfig,
1898
1143
  discoverBlockFiles,
1899
- discoverRecipeFiles,
1900
1144
  discoverFragmentFiles,
1901
1145
  discoverComponentFiles,
1902
1146
  extractComponentName,
1903
- discoverComponentsFromSource,
1904
- discoverComponentsFromBarrel,
1905
- discoverTokenFiles,
1906
- discoverInstalledFragments,
1907
1147
  discoverAllComponents,
1908
1148
  loadFragmentFile,
1909
- loadFragmentFiles,
1910
1149
  parseFragmentFile,
1911
- findPreviewConfigPath,
1912
- findStorybookDir,
1913
- loadPreviewConfig,
1914
- autoLoadPreviewConfig,
1915
- generatePreviewModule,
1916
- extractPropsFromFile,
1917
- extractPropsFromSource,
1918
- generateRegistry,
1919
- resolveComponentPath,
1920
- getComponentsByCategory,
1921
- generateContextMd,
1922
- analyzeFileImports,
1923
- buildImportGraph,
1924
- getImportedBy
1150
+ extractPropsFromFile
1925
1151
  };
1926
- //# sourceMappingURL=chunk-HQ6A6DTV.js.map
1152
+ //# sourceMappingURL=chunk-XRADMHMV.js.map