@fragments-sdk/cli 0.10.1 → 0.12.1

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 (223) hide show
  1. package/dist/ai-client-I6MDWNYA.js +21 -0
  2. package/dist/bin.js +292 -367
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-PW7QTQA6.js → chunk-4OC7FTJB.js} +2 -2
  5. package/dist/{chunk-HRFUSSZI.js → chunk-AM4MRTMN.js} +2 -2
  6. package/dist/{chunk-5G3VZH43.js → chunk-GVDSFQ4E.js} +281 -351
  7. package/dist/chunk-GVDSFQ4E.js.map +1 -0
  8. package/dist/chunk-JJ2VRTBU.js +626 -0
  9. package/dist/chunk-JJ2VRTBU.js.map +1 -0
  10. package/dist/{chunk-D5PYOXEI.js → chunk-LVWFOLUZ.js} +148 -13
  11. package/dist/{chunk-D5PYOXEI.js.map → chunk-LVWFOLUZ.js.map} +1 -1
  12. package/dist/{chunk-WXSR2II7.js → chunk-OQKMEFOS.js} +58 -6
  13. package/dist/chunk-OQKMEFOS.js.map +1 -0
  14. package/dist/chunk-SXTKFDCR.js +104 -0
  15. package/dist/chunk-SXTKFDCR.js.map +1 -0
  16. package/dist/chunk-T5OMVL7E.js +443 -0
  17. package/dist/chunk-T5OMVL7E.js.map +1 -0
  18. package/dist/{chunk-ZM4ZQZWZ.js → chunk-TPWGL2XS.js} +39 -37
  19. package/dist/chunk-TPWGL2XS.js.map +1 -0
  20. package/dist/{chunk-OQO55NKV.js → chunk-WFS63PCW.js} +85 -11
  21. package/dist/chunk-WFS63PCW.js.map +1 -0
  22. package/dist/core/index.js +9 -1
  23. package/dist/{discovery-NEOY4MPN.js → discovery-ZJQSXF56.js} +3 -3
  24. package/dist/{generate-FBHSXR3D.js → generate-RJFS2JWA.js} +4 -4
  25. package/dist/index.js +7 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/init-ZSX3NRCZ.js +636 -0
  28. package/dist/init-ZSX3NRCZ.js.map +1 -0
  29. package/dist/mcp-bin.js +2 -2
  30. package/dist/{scan-CJF2DOQW.js → scan-3PMCJ4RB.js} +6 -6
  31. package/dist/scan-generate-SYU4PYZD.js +1115 -0
  32. package/dist/scan-generate-SYU4PYZD.js.map +1 -0
  33. package/dist/{service-TQYWY65E.js → service-VMGNJZ42.js} +3 -3
  34. package/dist/snapshot-XOISO2IS.js +139 -0
  35. package/dist/snapshot-XOISO2IS.js.map +1 -0
  36. package/dist/{static-viewer-NUBFPKWH.js → static-viewer-5GXH2MGE.js} +3 -3
  37. package/dist/static-viewer-5GXH2MGE.js.map +1 -0
  38. package/dist/{test-Z5LVO724.js → test-SI4NSHQX.js} +4 -4
  39. package/dist/{tokens-CE46OTMD.js → tokens-T6SIVUT5.js} +5 -5
  40. package/dist/{viewer-DNMNC5VS.js → viewer-7ZEAFBVN.js} +80 -58
  41. package/dist/viewer-7ZEAFBVN.js.map +1 -0
  42. package/package.json +6 -14
  43. package/src/ai-client.ts +156 -0
  44. package/src/bin.ts +74 -2
  45. package/src/build.ts +95 -33
  46. package/src/commands/__tests__/drift-sync.test.ts +252 -0
  47. package/src/commands/__tests__/scan-generate.test.ts +497 -45
  48. package/src/commands/enhance.ts +11 -35
  49. package/src/commands/init.ts +296 -193
  50. package/src/commands/scan-generate.ts +740 -139
  51. package/src/commands/scan.ts +37 -32
  52. package/src/commands/setup.ts +143 -52
  53. package/src/commands/snapshot.ts +197 -0
  54. package/src/commands/sync.ts +357 -0
  55. package/src/commands/validate.ts +43 -1
  56. package/src/core/component-extractor.test.ts +282 -0
  57. package/src/core/component-extractor.ts +1030 -0
  58. package/src/core/discovery.ts +93 -7
  59. package/src/service/enhance/props-extractor.ts +235 -13
  60. package/src/validators.ts +236 -0
  61. package/src/viewer/__tests__/viewer-integration.test.ts +85 -74
  62. package/src/viewer/server.ts +37 -22
  63. package/src/viewer/vite-plugin.ts +25 -9
  64. package/dist/chunk-5G3VZH43.js.map +0 -1
  65. package/dist/chunk-OQO55NKV.js.map +0 -1
  66. package/dist/chunk-WXSR2II7.js.map +0 -1
  67. package/dist/chunk-ZM4ZQZWZ.js.map +0 -1
  68. package/dist/init-NDQXUWDU.js +0 -796
  69. package/dist/init-NDQXUWDU.js.map +0 -1
  70. package/dist/scan-generate-SJAN5MVI.js +0 -691
  71. package/dist/scan-generate-SJAN5MVI.js.map +0 -1
  72. package/dist/viewer-DNMNC5VS.js.map +0 -1
  73. package/src/ai.ts +0 -266
  74. package/src/commands/init-framework.ts +0 -414
  75. package/src/mcp/bin.ts +0 -36
  76. package/src/migrate/bin.ts +0 -114
  77. package/src/theme/index.ts +0 -77
  78. package/src/viewer/__tests__/a11y-fixes.test.ts +0 -358
  79. package/src/viewer/__tests__/jsx-parser.test.ts +0 -502
  80. package/src/viewer/__tests__/render-utils.test.ts +0 -232
  81. package/src/viewer/__tests__/style-utils.test.ts +0 -404
  82. package/src/viewer/assets/fragments-logo.ts +0 -4
  83. package/src/viewer/assets/fragments_logo.png +0 -0
  84. package/src/viewer/bin.ts +0 -86
  85. package/src/viewer/cli/health.ts +0 -256
  86. package/src/viewer/cli/index.ts +0 -33
  87. package/src/viewer/cli/scan.ts +0 -124
  88. package/src/viewer/cli/utils.ts +0 -174
  89. package/src/viewer/components/AccessibilityPanel.tsx +0 -1457
  90. package/src/viewer/components/ActionCapture.tsx +0 -172
  91. package/src/viewer/components/ActionsPanel.tsx +0 -332
  92. package/src/viewer/components/AllVariantsPreview.tsx +0 -78
  93. package/src/viewer/components/App.tsx +0 -582
  94. package/src/viewer/components/BottomPanel.tsx +0 -288
  95. package/src/viewer/components/CodePanel.naming.test.tsx +0 -59
  96. package/src/viewer/components/CodePanel.tsx +0 -118
  97. package/src/viewer/components/CommandPalette.tsx +0 -392
  98. package/src/viewer/components/ComponentDocView.tsx +0 -164
  99. package/src/viewer/components/ComponentGraph.tsx +0 -380
  100. package/src/viewer/components/ComponentHeader.tsx +0 -88
  101. package/src/viewer/components/ContractPanel.tsx +0 -241
  102. package/src/viewer/components/EmptyVariantMessage.tsx +0 -54
  103. package/src/viewer/components/ErrorBoundary.tsx +0 -97
  104. package/src/viewer/components/FigmaEmbed.tsx +0 -238
  105. package/src/viewer/components/FragmentEditor.tsx +0 -525
  106. package/src/viewer/components/FragmentRenderer.tsx +0 -61
  107. package/src/viewer/components/HeaderSearch.tsx +0 -24
  108. package/src/viewer/components/HealthDashboard.tsx +0 -441
  109. package/src/viewer/components/HmrStatusIndicator.tsx +0 -61
  110. package/src/viewer/components/Icons.tsx +0 -479
  111. package/src/viewer/components/InteractionsPanel.tsx +0 -757
  112. package/src/viewer/components/IsolatedPreviewFrame.tsx +0 -346
  113. package/src/viewer/components/IsolatedRender.tsx +0 -113
  114. package/src/viewer/components/KeyboardShortcutsHelp.tsx +0 -53
  115. package/src/viewer/components/LandingPage.tsx +0 -421
  116. package/src/viewer/components/Layout.tsx +0 -27
  117. package/src/viewer/components/LeftSidebar.tsx +0 -472
  118. package/src/viewer/components/LoadErrorMessage.tsx +0 -102
  119. package/src/viewer/components/MultiViewportPreview.tsx +0 -522
  120. package/src/viewer/components/NoVariantsMessage.tsx +0 -59
  121. package/src/viewer/components/PanelShell.tsx +0 -161
  122. package/src/viewer/components/PerformancePanel.tsx +0 -304
  123. package/src/viewer/components/PreviewArea.tsx +0 -472
  124. package/src/viewer/components/PreviewAside.tsx +0 -168
  125. package/src/viewer/components/PreviewFrameHost.tsx +0 -303
  126. package/src/viewer/components/PreviewPane.tsx +0 -149
  127. package/src/viewer/components/PreviewToolbar.tsx +0 -80
  128. package/src/viewer/components/PropsEditor.tsx +0 -506
  129. package/src/viewer/components/PropsTable.tsx +0 -111
  130. package/src/viewer/components/RelationsSection.tsx +0 -88
  131. package/src/viewer/components/ResizablePanel.tsx +0 -271
  132. package/src/viewer/components/RightSidebar.tsx +0 -102
  133. package/src/viewer/components/RuntimeToolsRegistrar.tsx +0 -17
  134. package/src/viewer/components/ScreenshotButton.tsx +0 -90
  135. package/src/viewer/components/Sidebar.tsx +0 -169
  136. package/src/viewer/components/SkeletonLoader.tsx +0 -161
  137. package/src/viewer/components/ThemeProvider.tsx +0 -42
  138. package/src/viewer/components/Toast.tsx +0 -3
  139. package/src/viewer/components/TokenStylePanel.tsx +0 -699
  140. package/src/viewer/components/TopToolbar.tsx +0 -159
  141. package/src/viewer/components/UsageSection.tsx +0 -95
  142. package/src/viewer/components/VariantMatrix.tsx +0 -388
  143. package/src/viewer/components/VariantRenderer.tsx +0 -131
  144. package/src/viewer/components/VariantTabs.tsx +0 -40
  145. package/src/viewer/components/ViewerHeader.tsx +0 -69
  146. package/src/viewer/components/ViewerStateSync.tsx +0 -52
  147. package/src/viewer/components/ViewportSelector.tsx +0 -172
  148. package/src/viewer/components/WebMCPDevTools.tsx +0 -503
  149. package/src/viewer/components/WebMCPIntegration.tsx +0 -47
  150. package/src/viewer/components/WebMCPStatusIndicator.tsx +0 -60
  151. package/src/viewer/components/_future/CreatePage.tsx +0 -836
  152. package/src/viewer/components/viewer-utils.ts +0 -16
  153. package/src/viewer/composition-renderer.ts +0 -381
  154. package/src/viewer/constants/index.ts +0 -1
  155. package/src/viewer/constants/ui.ts +0 -166
  156. package/src/viewer/entry.tsx +0 -335
  157. package/src/viewer/hooks/index.ts +0 -2
  158. package/src/viewer/hooks/useA11yCache.ts +0 -383
  159. package/src/viewer/hooks/useA11yService.ts +0 -364
  160. package/src/viewer/hooks/useActions.ts +0 -138
  161. package/src/viewer/hooks/useAppState.ts +0 -147
  162. package/src/viewer/hooks/useCompiledFragments.ts +0 -42
  163. package/src/viewer/hooks/useFigmaIntegration.ts +0 -132
  164. package/src/viewer/hooks/useHmrStatus.ts +0 -109
  165. package/src/viewer/hooks/useKeyboardShortcuts.ts +0 -270
  166. package/src/viewer/hooks/usePreviewBridge.ts +0 -347
  167. package/src/viewer/hooks/useScrollSpy.ts +0 -78
  168. package/src/viewer/hooks/useUrlState.ts +0 -318
  169. package/src/viewer/hooks/useViewSettings.ts +0 -111
  170. package/src/viewer/index.html +0 -28
  171. package/src/viewer/intelligence/healthReport.ts +0 -505
  172. package/src/viewer/intelligence/styleDrift.ts +0 -340
  173. package/src/viewer/intelligence/usageScanner.ts +0 -309
  174. package/src/viewer/jsx-parser.ts +0 -486
  175. package/src/viewer/preview-frame-entry.tsx +0 -25
  176. package/src/viewer/preview-frame.html +0 -125
  177. package/src/viewer/public/favicon.ico +0 -0
  178. package/src/viewer/render-template.html +0 -68
  179. package/src/viewer/styles/globals.css +0 -278
  180. package/src/viewer/types/a11y.ts +0 -197
  181. package/src/viewer/utils/a11y-fixes.ts +0 -509
  182. package/src/viewer/utils/actionExport.ts +0 -372
  183. package/src/viewer/utils/colorSchemes.ts +0 -201
  184. package/src/viewer/utils/detectRelationships.ts +0 -256
  185. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +0 -10
  186. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +0 -2
  187. package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +0 -274
  188. package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +0 -129
  189. package/src/viewer/vendor/shared/src/DocsPageAsideHost.tsx +0 -89
  190. package/src/viewer/vendor/shared/src/DocsPageShell.tsx +0 -124
  191. package/src/viewer/vendor/shared/src/DocsSearchCommand.tsx +0 -99
  192. package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +0 -66
  193. package/src/viewer/vendor/shared/src/PropsTable.module.scss +0 -68
  194. package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +0 -2
  195. package/src/viewer/vendor/shared/src/PropsTable.tsx +0 -76
  196. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +0 -114
  197. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +0 -2
  198. package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +0 -137
  199. package/src/viewer/vendor/shared/src/docs-data/index.ts +0 -32
  200. package/src/viewer/vendor/shared/src/docs-data/mcp-configs.ts +0 -72
  201. package/src/viewer/vendor/shared/src/docs-data/palettes.ts +0 -75
  202. package/src/viewer/vendor/shared/src/docs-data/setup-examples.ts +0 -55
  203. package/src/viewer/vendor/shared/src/docs-layout.scss +0 -28
  204. package/src/viewer/vendor/shared/src/docs-layout.scss.d.ts +0 -2
  205. package/src/viewer/vendor/shared/src/index.ts +0 -34
  206. package/src/viewer/vendor/shared/src/types.ts +0 -53
  207. package/src/viewer/webmcp/__tests__/analytics.test.ts +0 -108
  208. package/src/viewer/webmcp/analytics.ts +0 -165
  209. package/src/viewer/webmcp/index.ts +0 -3
  210. package/src/viewer/webmcp/posthog-bridge.ts +0 -39
  211. package/src/viewer/webmcp/runtime-tools.ts +0 -152
  212. package/src/viewer/webmcp/scan-utils.ts +0 -135
  213. package/src/viewer/webmcp/use-tool-analytics.ts +0 -69
  214. package/src/viewer/webmcp/viewer-state.ts +0 -45
  215. /package/dist/{discovery-NEOY4MPN.js.map → ai-client-I6MDWNYA.js.map} +0 -0
  216. /package/dist/{chunk-PW7QTQA6.js.map → chunk-4OC7FTJB.js.map} +0 -0
  217. /package/dist/{chunk-HRFUSSZI.js.map → chunk-AM4MRTMN.js.map} +0 -0
  218. /package/dist/{scan-CJF2DOQW.js.map → discovery-ZJQSXF56.js.map} +0 -0
  219. /package/dist/{generate-FBHSXR3D.js.map → generate-RJFS2JWA.js.map} +0 -0
  220. /package/dist/{service-TQYWY65E.js.map → scan-3PMCJ4RB.js.map} +0 -0
  221. /package/dist/{static-viewer-NUBFPKWH.js.map → service-VMGNJZ42.js.map} +0 -0
  222. /package/dist/{test-Z5LVO724.js.map → test-SI4NSHQX.js.map} +0 -0
  223. /package/dist/{tokens-CE46OTMD.js.map → tokens-T6SIVUT5.js.map} +0 -0
@@ -0,0 +1,626 @@
1
+ import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
+
3
+ // src/core/component-extractor.ts
4
+ import ts from "typescript";
5
+ import { readFileSync } from "fs";
6
+ import { resolve, dirname } from "path";
7
+ function createComponentExtractor(tsconfigPath) {
8
+ let projectVersion = 0;
9
+ const fileVersions = /* @__PURE__ */ new Map();
10
+ const fileSnapshots = /* @__PURE__ */ new Map();
11
+ const rootDir = tsconfigPath ? dirname(resolve(tsconfigPath)) : process.cwd();
12
+ const parsedCommandLine = tsconfigPath ? parseTsConfig(tsconfigPath) : inferCompilerOptions(rootDir);
13
+ const scriptFileNames = new Set(parsedCommandLine.fileNames);
14
+ const host = {
15
+ getProjectVersion: () => projectVersion.toString(),
16
+ getScriptVersion: (fileName) => (fileVersions.get(fileName) ?? 0).toString(),
17
+ getScriptSnapshot: (fileName) => {
18
+ const cached = fileSnapshots.get(fileName);
19
+ if (cached) return cached;
20
+ let text;
21
+ try {
22
+ text = readFileSync(fileName, "utf-8");
23
+ } catch {
24
+ return void 0;
25
+ }
26
+ const snapshot = ts.ScriptSnapshot.fromString(text);
27
+ fileSnapshots.set(fileName, snapshot);
28
+ return snapshot;
29
+ },
30
+ getScriptFileNames: () => [...scriptFileNames],
31
+ getCompilationSettings: () => parsedCommandLine.options,
32
+ getCurrentDirectory: () => rootDir,
33
+ getDefaultLibFileName: ts.getDefaultLibFilePath,
34
+ fileExists: ts.sys.fileExists,
35
+ readFile: ts.sys.readFile,
36
+ readDirectory: ts.sys.readDirectory,
37
+ directoryExists: ts.sys.directoryExists,
38
+ getDirectories: ts.sys.getDirectories
39
+ };
40
+ const languageService = ts.createLanguageService(host, ts.createDocumentRegistry());
41
+ function ensureFile(filePath) {
42
+ const resolved = resolve(filePath);
43
+ if (!scriptFileNames.has(resolved)) {
44
+ scriptFileNames.add(resolved);
45
+ projectVersion++;
46
+ }
47
+ }
48
+ function getChecker() {
49
+ const program = languageService.getProgram();
50
+ if (!program) throw new Error("Failed to get program from LanguageService");
51
+ return program.getTypeChecker();
52
+ }
53
+ function getSourceFile(filePath) {
54
+ return languageService.getProgram()?.getSourceFile(resolve(filePath));
55
+ }
56
+ return {
57
+ extract(filePath, exportName) {
58
+ const resolved = resolve(filePath);
59
+ ensureFile(resolved);
60
+ const sourceFile = getSourceFile(resolved);
61
+ if (!sourceFile) return null;
62
+ const checker = getChecker();
63
+ const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
64
+ if (!moduleSymbol) return null;
65
+ const exports = checker.getExportsOfModule(moduleSymbol);
66
+ const targetName = exportName ?? findPrimaryExport(exports, sourceFile);
67
+ if (!targetName) return null;
68
+ const exportSymbol = exports.find((s) => s.getName() === targetName);
69
+ if (!exportSymbol) return null;
70
+ const component = resolveExportedComponent(checker, exportSymbol, sourceFile);
71
+ if (!component) return null;
72
+ return buildComponentMeta(checker, component, resolved, sourceFile, exports);
73
+ },
74
+ extractAll(filePath) {
75
+ const resolved = resolve(filePath);
76
+ ensureFile(resolved);
77
+ const sourceFile = getSourceFile(resolved);
78
+ if (!sourceFile) return [];
79
+ const checker = getChecker();
80
+ const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
81
+ if (!moduleSymbol) return [];
82
+ const exports = checker.getExportsOfModule(moduleSymbol);
83
+ const results = [];
84
+ for (const exportSymbol of exports) {
85
+ const name = exportSymbol.getName();
86
+ if (!/^[A-Z]/.test(name)) continue;
87
+ const component = resolveExportedComponent(checker, exportSymbol, sourceFile);
88
+ if (!component) continue;
89
+ const meta = buildComponentMeta(checker, component, resolved, sourceFile, exports);
90
+ if (meta) results.push(meta);
91
+ }
92
+ return results;
93
+ },
94
+ invalidate(filePath) {
95
+ const resolved = resolve(filePath);
96
+ fileVersions.set(resolved, (fileVersions.get(resolved) ?? 0) + 1);
97
+ fileSnapshots.delete(resolved);
98
+ projectVersion++;
99
+ },
100
+ dispose() {
101
+ languageService.dispose();
102
+ fileSnapshots.clear();
103
+ fileVersions.clear();
104
+ }
105
+ };
106
+ }
107
+ function parseTsConfig(tsconfigPath) {
108
+ const resolved = resolve(tsconfigPath);
109
+ const configFile = ts.readConfigFile(resolved, ts.sys.readFile);
110
+ if (configFile.error) {
111
+ throw new Error(`Failed to read tsconfig: ${ts.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`);
112
+ }
113
+ return ts.parseJsonConfigFileContent(
114
+ configFile.config,
115
+ ts.sys,
116
+ dirname(resolved),
117
+ void 0,
118
+ resolved
119
+ );
120
+ }
121
+ function inferCompilerOptions(rootDir) {
122
+ return {
123
+ options: {
124
+ target: ts.ScriptTarget.ES2022,
125
+ module: ts.ModuleKind.ESNext,
126
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
127
+ jsx: ts.JsxEmit.ReactJSX,
128
+ allowSyntheticDefaultImports: true,
129
+ esModuleInterop: true,
130
+ skipLibCheck: true,
131
+ strict: false,
132
+ noEmit: true
133
+ },
134
+ fileNames: [],
135
+ errors: []
136
+ };
137
+ }
138
+ function findPrimaryExport(exports, sourceFile) {
139
+ const defaultExport = exports.find((s) => s.getName() === "default");
140
+ if (defaultExport) return "default";
141
+ for (const s of exports) {
142
+ if (/^[A-Z][a-zA-Z0-9]*$/.test(s.getName())) {
143
+ return s.getName();
144
+ }
145
+ }
146
+ return null;
147
+ }
148
+ function resolveExportedComponent(checker, exportSymbol, sourceFile) {
149
+ const name = exportSymbol.getName();
150
+ let symbol = exportSymbol;
151
+ if (symbol.flags & ts.SymbolFlags.Alias) {
152
+ symbol = checker.getAliasedSymbol(symbol);
153
+ }
154
+ const declarations = symbol.getDeclarations();
155
+ if (!declarations || declarations.length === 0) return null;
156
+ const declaration = declarations[0];
157
+ if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
158
+ return resolveFromExpression(checker, name, declaration.initializer, declaration, sourceFile);
159
+ }
160
+ if (ts.isFunctionDeclaration(declaration)) {
161
+ const propsType = extractPropsFromFunctionLike(checker, declaration);
162
+ return propsType ? { name, propsType, componentNode: declaration, compoundParts: null } : null;
163
+ }
164
+ if (ts.isExportAssignment(declaration) && declaration.expression) {
165
+ return resolveFromExpression(checker, name, declaration.expression, null, sourceFile);
166
+ }
167
+ return null;
168
+ }
169
+ function resolveFromExpression(checker, name, expression, variableDecl, sourceFile) {
170
+ expression = unwrapExpression(expression);
171
+ if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)) {
172
+ const propsType = extractPropsFromFunctionLike(checker, expression);
173
+ return propsType ? { name, propsType, componentNode: expression, compoundParts: null } : null;
174
+ }
175
+ if (ts.isCallExpression(expression)) {
176
+ return resolveCallExpression(checker, name, expression, variableDecl, sourceFile);
177
+ }
178
+ if (ts.isIdentifier(expression)) {
179
+ const sym = checker.getSymbolAtLocation(expression);
180
+ if (sym) {
181
+ const decls = sym.getDeclarations();
182
+ if (decls && decls.length > 0) {
183
+ const decl = decls[0];
184
+ if (ts.isVariableDeclaration(decl) && decl.initializer) {
185
+ return resolveFromExpression(checker, name, decl.initializer, decl, sourceFile);
186
+ }
187
+ if (ts.isFunctionDeclaration(decl)) {
188
+ const propsType = extractPropsFromFunctionLike(checker, decl);
189
+ return propsType ? { name, propsType, componentNode: decl, compoundParts: null } : null;
190
+ }
191
+ }
192
+ }
193
+ }
194
+ if (variableDecl?.type && ts.isTypeReferenceNode(variableDecl.type)) {
195
+ const typeName = variableDecl.type.typeName.getText(sourceFile);
196
+ if (typeName.includes("FC") || typeName.includes("FunctionComponent")) {
197
+ const typeArg = variableDecl.type.typeArguments?.[0];
198
+ if (typeArg) {
199
+ const propsType = checker.getTypeFromTypeNode(typeArg);
200
+ return { name, propsType, componentNode: expression, compoundParts: null };
201
+ }
202
+ }
203
+ }
204
+ return null;
205
+ }
206
+ function resolveCallExpression(checker, name, call, variableDecl, sourceFile) {
207
+ const callee = call.expression;
208
+ if (isObjectAssignCall(callee, sourceFile)) {
209
+ return resolveObjectAssign(checker, name, call, sourceFile);
210
+ }
211
+ if (isForwardRefCall(callee)) {
212
+ return resolveForwardRef(checker, name, call, sourceFile);
213
+ }
214
+ if (isMemoCall(callee)) {
215
+ const innerArg = call.arguments[0];
216
+ if (innerArg) {
217
+ return resolveFromExpression(checker, name, innerArg, variableDecl, sourceFile);
218
+ }
219
+ }
220
+ return null;
221
+ }
222
+ function resolveObjectAssign(checker, name, call, sourceFile) {
223
+ if (call.arguments.length < 2) return null;
224
+ const rootExpr = call.arguments[0];
225
+ const rootResult = resolveFromExpression(checker, name, rootExpr, null, sourceFile);
226
+ const subsArg = call.arguments[1];
227
+ const compoundParts = /* @__PURE__ */ new Map();
228
+ if (ts.isObjectLiteralExpression(subsArg)) {
229
+ for (const prop of subsArg.properties) {
230
+ let subName = null;
231
+ let subExpression = null;
232
+ if (ts.isShorthandPropertyAssignment(prop)) {
233
+ subName = prop.name.text;
234
+ const sym = checker.getSymbolAtLocation(prop.name);
235
+ if (sym) {
236
+ const subPropsType = extractPropsFromComponentSymbol(checker, sym);
237
+ if (subPropsType) {
238
+ compoundParts.set(subName, subPropsType);
239
+ }
240
+ }
241
+ } else if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
242
+ subName = prop.name.text;
243
+ subExpression = prop.initializer;
244
+ if (subExpression) {
245
+ const subType = extractPropsFromExpression(checker, subExpression, sourceFile);
246
+ if (subType) {
247
+ compoundParts.set(subName, subType);
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ return {
254
+ name,
255
+ propsType: rootResult?.propsType ?? null,
256
+ componentNode: rootResult?.componentNode ?? rootExpr,
257
+ compoundParts: compoundParts.size > 0 ? compoundParts : null
258
+ };
259
+ }
260
+ function extractPropsFromComponentSymbol(checker, symbol) {
261
+ let sym = symbol;
262
+ if (sym.flags & ts.SymbolFlags.Alias) {
263
+ sym = checker.getAliasedSymbol(sym);
264
+ }
265
+ const decls = sym.getDeclarations();
266
+ if (!decls || decls.length === 0) return null;
267
+ const decl = decls[0];
268
+ if (ts.isFunctionDeclaration(decl)) {
269
+ return extractPropsFromFunctionLike(checker, decl);
270
+ }
271
+ if (ts.isVariableDeclaration(decl) && decl.initializer) {
272
+ return extractPropsFromExpressionDeep(checker, decl);
273
+ }
274
+ return null;
275
+ }
276
+ function extractPropsFromExpression(checker, expr, sourceFile) {
277
+ expr = unwrapExpression(expr);
278
+ if (ts.isIdentifier(expr)) {
279
+ const sym = checker.getSymbolAtLocation(expr);
280
+ if (sym) return extractPropsFromComponentSymbol(checker, sym);
281
+ }
282
+ if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {
283
+ return extractPropsFromFunctionLike(checker, expr);
284
+ }
285
+ if (ts.isCallExpression(expr)) {
286
+ if (isForwardRefCall(expr.expression)) {
287
+ const typeArg = expr.typeArguments?.[1];
288
+ if (typeArg) return checker.getTypeFromTypeNode(typeArg);
289
+ const innerArg = expr.arguments[0];
290
+ if (innerArg && (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg))) {
291
+ return extractPropsFromFunctionLike(checker, innerArg);
292
+ }
293
+ }
294
+ if (isMemoCall(expr.expression) && expr.arguments[0]) {
295
+ return extractPropsFromExpression(checker, expr.arguments[0], sourceFile);
296
+ }
297
+ }
298
+ return null;
299
+ }
300
+ function extractPropsFromExpressionDeep(checker, decl) {
301
+ if (!decl.initializer) return null;
302
+ let expr = unwrapExpression(decl.initializer);
303
+ if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {
304
+ return extractPropsFromFunctionLike(checker, expr);
305
+ }
306
+ if (ts.isCallExpression(expr)) {
307
+ if (isForwardRefCall(expr.expression)) {
308
+ const typeArg = expr.typeArguments?.[1];
309
+ if (typeArg) return checker.getTypeFromTypeNode(typeArg);
310
+ const innerArg = expr.arguments[0];
311
+ if (innerArg && (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg))) {
312
+ return extractPropsFromFunctionLike(checker, innerArg);
313
+ }
314
+ }
315
+ if (isMemoCall(expr.expression) && expr.arguments[0]) {
316
+ return extractPropsFromExpressionDeep(checker, {
317
+ ...decl,
318
+ initializer: expr.arguments[0]
319
+ });
320
+ }
321
+ }
322
+ return null;
323
+ }
324
+ function resolveForwardRef(checker, name, call, sourceFile) {
325
+ const propsTypeArg = call.typeArguments?.[1];
326
+ if (propsTypeArg) {
327
+ const propsType = checker.getTypeFromTypeNode(propsTypeArg);
328
+ const innerArg2 = call.arguments[0];
329
+ const componentNode = innerArg2 && (ts.isArrowFunction(innerArg2) || ts.isFunctionExpression(innerArg2)) ? innerArg2 : null;
330
+ return { name, propsType, componentNode, compoundParts: null };
331
+ }
332
+ const innerArg = call.arguments[0];
333
+ if (innerArg) {
334
+ if (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg)) {
335
+ const propsType = extractPropsFromFunctionLike(checker, innerArg);
336
+ return propsType ? { name, propsType, componentNode: innerArg, compoundParts: null } : null;
337
+ }
338
+ if (ts.isIdentifier(innerArg)) {
339
+ const sym = checker.getSymbolAtLocation(innerArg);
340
+ if (sym) {
341
+ const propsType = extractPropsFromComponentSymbol(checker, sym);
342
+ if (propsType) return { name, propsType, componentNode: innerArg, compoundParts: null };
343
+ }
344
+ }
345
+ }
346
+ return null;
347
+ }
348
+ function extractPropsFromFunctionLike(checker, func) {
349
+ const firstParam = func.parameters[0];
350
+ if (!firstParam) return null;
351
+ if (firstParam.type) {
352
+ return checker.getTypeFromTypeNode(firstParam.type);
353
+ }
354
+ const paramSymbol = checker.getSymbolAtLocation(firstParam.name);
355
+ if (paramSymbol) {
356
+ return checker.getTypeOfSymbolAtLocation(paramSymbol, firstParam);
357
+ }
358
+ return null;
359
+ }
360
+ function buildComponentMeta(checker, component, filePath, sourceFile, moduleExports) {
361
+ const props = {};
362
+ const sourceFilePath = toPosixPath(sourceFile.fileName);
363
+ if (component.propsType) {
364
+ extractPropsFromType(checker, component.propsType, props, sourceFilePath);
365
+ }
366
+ const defaults = component.componentNode ? extractDefaultValues(component.componentNode) : {};
367
+ for (const [propName, defaultVal] of Object.entries(defaults)) {
368
+ if (props[propName]) {
369
+ props[propName].default = defaultVal;
370
+ }
371
+ }
372
+ let composition = null;
373
+ if (component.compoundParts && component.compoundParts.size > 0) {
374
+ const parts = [];
375
+ for (const [partName, partType] of component.compoundParts) {
376
+ const partProps = {};
377
+ extractPropsFromType(checker, partType, partProps, sourceFilePath);
378
+ parts.push({ name: partName, props: partProps });
379
+ }
380
+ composition = {
381
+ pattern: "compound",
382
+ parts,
383
+ required: []
384
+ // Could be inferred from usage patterns
385
+ };
386
+ }
387
+ let description = "";
388
+ const componentSymbol = moduleExports.find((s) => s.getName() === component.name);
389
+ if (componentSymbol) {
390
+ description = extractJSDocDescription(checker, componentSymbol);
391
+ }
392
+ const exportNames = moduleExports.filter((s) => /^[A-Z]/.test(s.getName())).map((s) => s.getName());
393
+ const dependencies = extractDependencies(sourceFile);
394
+ return {
395
+ name: component.name,
396
+ filePath,
397
+ description,
398
+ props,
399
+ composition,
400
+ exports: exportNames,
401
+ dependencies
402
+ };
403
+ }
404
+ function extractPropsFromType(checker, propsType, result, sourceFilePath) {
405
+ for (const symbol of checker.getPropertiesOfType(propsType)) {
406
+ const propName = symbol.getName();
407
+ if (propName.startsWith("_") || propName.startsWith("$")) continue;
408
+ if (propName === "key" || propName === "ref") continue;
409
+ const declarations = symbol.getDeclarations() ?? [];
410
+ const isLocal = declarations.some(
411
+ (d) => toPosixPath(d.getSourceFile().fileName) === sourceFilePath
412
+ );
413
+ const referenceNode = declarations[0];
414
+ if (!referenceNode) continue;
415
+ const propType = checker.getTypeOfSymbolAtLocation(symbol, referenceNode);
416
+ const serialized = serializePropType(checker, propType);
417
+ const description = ts.displayPartsToString(symbol.getDocumentationComment(checker)).trim();
418
+ const required = (symbol.flags & ts.SymbolFlags.Optional) === 0;
419
+ let jsDocDefault;
420
+ const jsDocTags = symbol.getJsDocTags(checker);
421
+ const defaultTag = jsDocTags.find((t) => t.name === "default");
422
+ if (defaultTag?.text) {
423
+ jsDocDefault = ts.displayPartsToString(defaultTag.text).trim();
424
+ }
425
+ result[propName] = {
426
+ name: propName,
427
+ type: serialized.type,
428
+ typeKind: serialized.typeKind,
429
+ values: serialized.values,
430
+ default: jsDocDefault,
431
+ description: description || void 0,
432
+ required,
433
+ source: isLocal ? "local" : "inherited"
434
+ };
435
+ }
436
+ }
437
+ function serializePropType(checker, type) {
438
+ const aliasSymbol = type.aliasSymbol;
439
+ if (aliasSymbol) {
440
+ const aliasName = aliasSymbol.getName();
441
+ if (aliasName === "ReactNode") {
442
+ return { type: "ReactNode", typeKind: "node" };
443
+ }
444
+ if (aliasName === "ReactElement") {
445
+ return { type: "ReactElement", typeKind: "element" };
446
+ }
447
+ }
448
+ if (type.isUnion()) {
449
+ const nonNullableTypes = type.types.filter(
450
+ (t) => !(t.flags & ts.TypeFlags.Undefined || t.flags & ts.TypeFlags.Null || t.flags & ts.TypeFlags.Void)
451
+ );
452
+ if (nonNullableTypes.length === 1) {
453
+ return serializePropType(checker, nonNullableTypes[0]);
454
+ }
455
+ if (nonNullableTypes.length > 0 && nonNullableTypes.every((t) => t.isStringLiteral())) {
456
+ const values = nonNullableTypes.map((t) => t.value);
457
+ return {
458
+ type: values.map((v) => `"${v}"`).join(" | "),
459
+ typeKind: "enum",
460
+ values
461
+ };
462
+ }
463
+ if (nonNullableTypes.every((t) => isBooleanLike(t))) {
464
+ return { type: "boolean", typeKind: "boolean" };
465
+ }
466
+ const typeStr2 = checker.typeToString(type, void 0, ts.TypeFormatFlags.NoTruncation);
467
+ return { type: typeStr2, typeKind: "union" };
468
+ }
469
+ const typeStr = checker.typeToString(type, void 0, ts.TypeFormatFlags.NoTruncation);
470
+ if (typeStr.includes("ReactNode")) {
471
+ return { type: "ReactNode", typeKind: "node" };
472
+ }
473
+ if (typeStr.includes("ReactElement") || typeStr.includes("JSX.Element")) {
474
+ return { type: "ReactElement", typeKind: "element" };
475
+ }
476
+ if (type.getCallSignatures().length > 0) {
477
+ return { type: typeStr, typeKind: "function" };
478
+ }
479
+ if (type.flags & ts.TypeFlags.String) return { type: "string", typeKind: "string" };
480
+ if (type.flags & ts.TypeFlags.Number) return { type: "number", typeKind: "number" };
481
+ if (type.flags & ts.TypeFlags.Boolean || type.flags & ts.TypeFlags.BooleanLiteral) {
482
+ return { type: "boolean", typeKind: "boolean" };
483
+ }
484
+ if (type.isStringLiteral()) {
485
+ return { type: `"${type.value}"`, typeKind: "enum", values: [type.value] };
486
+ }
487
+ if (checker.isArrayType(type) || checker.isTupleType(type)) {
488
+ return { type: typeStr, typeKind: "array" };
489
+ }
490
+ if (type.flags & ts.TypeFlags.Object) {
491
+ return { type: typeStr, typeKind: "object" };
492
+ }
493
+ return { type: typeStr, typeKind: "custom" };
494
+ }
495
+ function extractDefaultValues(node) {
496
+ const defaults = {};
497
+ let funcNode = null;
498
+ if (ts.isFunctionDeclaration(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
499
+ funcNode = node;
500
+ }
501
+ if (!funcNode?.parameters?.length) return defaults;
502
+ const firstParam = funcNode.parameters[0];
503
+ if (!ts.isObjectBindingPattern(firstParam.name)) return defaults;
504
+ for (const element of firstParam.name.elements) {
505
+ let propName = null;
506
+ if (element.propertyName) {
507
+ if (ts.isIdentifier(element.propertyName) || ts.isStringLiteral(element.propertyName)) {
508
+ propName = element.propertyName.text;
509
+ }
510
+ } else if (ts.isIdentifier(element.name)) {
511
+ propName = element.name.text;
512
+ }
513
+ if (!propName || !element.initializer) continue;
514
+ const value = readLiteralValue(element.initializer);
515
+ if (value !== void 0) {
516
+ defaults[propName] = value;
517
+ }
518
+ }
519
+ return defaults;
520
+ }
521
+ function readLiteralValue(expression) {
522
+ if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) {
523
+ return expression.text;
524
+ }
525
+ if (ts.isNumericLiteral(expression)) {
526
+ return expression.text;
527
+ }
528
+ if (expression.kind === ts.SyntaxKind.TrueKeyword) return "true";
529
+ if (expression.kind === ts.SyntaxKind.FalseKeyword) return "false";
530
+ if (expression.kind === ts.SyntaxKind.NullKeyword) return "null";
531
+ if (ts.isPrefixUnaryExpression(expression) && expression.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(expression.operand)) {
532
+ return `-${expression.operand.text}`;
533
+ }
534
+ return void 0;
535
+ }
536
+ function extractJSDocDescription(checker, symbol) {
537
+ let sym = symbol;
538
+ if (sym.flags & ts.SymbolFlags.Alias) {
539
+ sym = checker.getAliasedSymbol(sym);
540
+ }
541
+ const docComment = ts.displayPartsToString(sym.getDocumentationComment(checker)).trim();
542
+ if (docComment) return docComment;
543
+ const decls = sym.getDeclarations();
544
+ if (decls) {
545
+ for (const decl of decls) {
546
+ const sourceFile = decl.getSourceFile();
547
+ for (const stmt of sourceFile.statements) {
548
+ if ((ts.isInterfaceDeclaration(stmt) || ts.isTypeAliasDeclaration(stmt)) && stmt.name.text === `${symbol.getName()}Props`) {
549
+ const propsDoc = ts.displayPartsToString(
550
+ checker.getSymbolAtLocation(stmt.name)?.getDocumentationComment(checker) ?? []
551
+ ).trim();
552
+ if (propsDoc) return propsDoc;
553
+ }
554
+ }
555
+ }
556
+ }
557
+ return "";
558
+ }
559
+ function extractDependencies(sourceFile) {
560
+ const deps = [];
561
+ for (const stmt of sourceFile.statements) {
562
+ if (!ts.isImportDeclaration(stmt)) continue;
563
+ if (!ts.isStringLiteral(stmt.moduleSpecifier)) continue;
564
+ const modulePath = stmt.moduleSpecifier.text;
565
+ if (!modulePath.startsWith(".") && !modulePath.startsWith("/")) continue;
566
+ const clause = stmt.importClause;
567
+ if (!clause) continue;
568
+ if (clause.name && /^[A-Z]/.test(clause.name.text)) {
569
+ deps.push(clause.name.text);
570
+ }
571
+ if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {
572
+ for (const element of clause.namedBindings.elements) {
573
+ if (/^[A-Z]/.test(element.name.text)) {
574
+ deps.push(element.name.text);
575
+ }
576
+ }
577
+ }
578
+ }
579
+ return deps;
580
+ }
581
+ function unwrapExpression(expr) {
582
+ while (true) {
583
+ if (ts.isParenthesizedExpression(expr)) {
584
+ expr = expr.expression;
585
+ } else if (ts.isAsExpression(expr) || ts.isTypeAssertionExpression(expr)) {
586
+ expr = expr.expression;
587
+ } else {
588
+ return expr;
589
+ }
590
+ }
591
+ }
592
+ function isObjectAssignCall(callee, sourceFile) {
593
+ if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.expression) && callee.expression.text === "Object" && callee.name.text === "assign") {
594
+ return true;
595
+ }
596
+ return false;
597
+ }
598
+ function isForwardRefCall(callee) {
599
+ if (ts.isPropertyAccessExpression(callee) && callee.name.text === "forwardRef") {
600
+ return true;
601
+ }
602
+ if (ts.isIdentifier(callee) && callee.text === "forwardRef") {
603
+ return true;
604
+ }
605
+ return false;
606
+ }
607
+ function isMemoCall(callee) {
608
+ if (ts.isPropertyAccessExpression(callee) && callee.name.text === "memo") {
609
+ return true;
610
+ }
611
+ if (ts.isIdentifier(callee) && callee.text === "memo") {
612
+ return true;
613
+ }
614
+ return false;
615
+ }
616
+ function isBooleanLike(type) {
617
+ return (type.flags & ts.TypeFlags.BooleanLike) !== 0 || type.flags === ts.TypeFlags.BooleanLiteral;
618
+ }
619
+ function toPosixPath(filePath) {
620
+ return filePath.replace(/\\/g, "/");
621
+ }
622
+
623
+ export {
624
+ createComponentExtractor
625
+ };
626
+ //# sourceMappingURL=chunk-JJ2VRTBU.js.map