@rankingcoach/vanguard 1.3.0 → 1.4.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 (361) hide show
  1. package/dist/icons/Icon-tools-active-1.svg +3 -0
  2. package/dist/icons/Icon-tools-active.svg +3 -0
  3. package/dist/index-AMPMMidnightParser.js +1 -1
  4. package/dist/index-AMPMParser.js +1 -1
  5. package/dist/index-Accordion2.js +1 -1
  6. package/dist/index-AccordionDetails.js +1 -1
  7. package/dist/index-AccordionSummary.js +1 -1
  8. package/dist/index-AppBar2.js +1 -1
  9. package/dist/index-Autocomplete2.js +1 -1
  10. package/dist/index-Backdrop.js +1 -1
  11. package/dist/index-BasePopper.js +1 -1
  12. package/dist/index-Box.js +1 -1
  13. package/dist/index-Button2.js +1 -1
  14. package/dist/index-ButtonBase.js +1 -1
  15. package/dist/index-CSSTransition.js +1 -1
  16. package/dist/index-Calendar.js +20 -20
  17. package/dist/index-CalendarPicker.js +1 -1
  18. package/dist/index-Chip.js +1 -1
  19. package/dist/index-ClickAwayListener.js +1 -1
  20. package/dist/index-ClockPicker.js +1 -1
  21. package/dist/index-Collapse2.js +1 -1
  22. package/dist/index-ControlledValuePlugin.js +1 -1
  23. package/dist/index-CreditCard.js +1 -1
  24. package/dist/index-DateInput.js +1 -1
  25. package/dist/index-DateParser.js +1 -1
  26. package/dist/index-DatePicker2.js +1 -1
  27. package/dist/index-DateRange2.js +7 -7
  28. package/dist/index-DateRangePicker2.js +1 -1
  29. package/dist/index-DayCell.js +7 -7
  30. package/dist/index-DayOfYearParser.js +1 -1
  31. package/dist/index-DayParser.js +1 -1
  32. package/dist/index-DayPeriodParser.js +1 -1
  33. package/dist/index-DefaultPropsProvider.js +1 -1
  34. package/dist/index-DefaultPropsProvider2.js +1 -1
  35. package/dist/index-DefaultValuePlugin.js +1 -1
  36. package/dist/index-DefinedRange.js +1 -1
  37. package/dist/index-DesktopDatePicker.js +1 -1
  38. package/dist/index-Dialog.js +1 -1
  39. package/dist/index-DialogActions.js +1 -1
  40. package/dist/index-DialogContent.js +1 -1
  41. package/dist/index-Drawer2.js +1 -1
  42. package/dist/index-EraParser.js +1 -1
  43. package/dist/index-ExtendedYearParser.js +1 -1
  44. package/dist/index-Fade.js +1 -1
  45. package/dist/index-FilledInput.js +1 -1
  46. package/dist/index-FocusTrap.js +1 -1
  47. package/dist/index-FormControl2.js +1 -1
  48. package/dist/index-FormHelperText.js +1 -1
  49. package/dist/index-FormLabel.js +1 -1
  50. package/dist/index-FractionOfSecondParser.js +1 -1
  51. package/dist/index-GlobalStyles.js +1 -1
  52. package/dist/index-GlobalStyles2.js +1 -1
  53. package/dist/index-GlobalStyles3.js +1 -1
  54. package/dist/index-Grid.js +1 -1
  55. package/dist/index-Grow.js +1 -1
  56. package/dist/index-Hour0To11Parser.js +1 -1
  57. package/dist/index-Hour0to23Parser.js +1 -1
  58. package/dist/index-Hour1To24Parser.js +1 -1
  59. package/dist/index-Hour1to12Parser.js +1 -1
  60. package/dist/index-HyperlinkPlugin.js +1 -1
  61. package/dist/index-ISODayParser.js +1 -1
  62. package/dist/index-ISOTimezoneParser.js +1 -1
  63. package/dist/index-ISOTimezoneWithZParser.js +1 -1
  64. package/dist/index-ISOWeekParser.js +1 -1
  65. package/dist/index-ISOWeekYearParser.js +1 -1
  66. package/dist/index-Icon-tools-active-1.svg.js +4 -0
  67. package/dist/index-Icon-tools-active.svg.js +4 -0
  68. package/dist/index-IconButton2.js +1 -1
  69. package/dist/index-Input2.js +1 -1
  70. package/dist/index-InputAdornment.js +1 -1
  71. package/dist/index-InputBase.js +48 -43
  72. package/dist/index-InputBase2.js +1 -1
  73. package/dist/index-InputLabel.js +1 -1
  74. package/dist/index-InputRangeField.js +1 -1
  75. package/dist/index-KeywordNode.js +1 -1
  76. package/dist/index-KeywordPlugin.js +1 -1
  77. package/dist/index-LinearProgress.js +1 -1
  78. package/dist/index-List2.js +1 -1
  79. package/dist/index-ListSubheader.js +1 -1
  80. package/dist/index-LocalDayParser.js +1 -1
  81. package/dist/index-LocalWeekParser.js +1 -1
  82. package/dist/index-LocalWeekYearParser.js +1 -1
  83. package/dist/index-LocalizationProvider.js +1 -1
  84. package/dist/index-LoginButton.js +1 -1
  85. package/dist/index-Menu.js +1 -1
  86. package/dist/index-MenuItem.js +1 -1
  87. package/dist/index-MenuList.js +1 -1
  88. package/dist/index-MinuteParser.js +1 -1
  89. package/dist/index-MobileDatePicker.js +1 -1
  90. package/dist/index-Modal2.js +1 -1
  91. package/dist/index-Month.js +10 -10
  92. package/dist/index-MonthParser.js +1 -1
  93. package/dist/index-MonthPicker.js +1 -1
  94. package/dist/index-NativeSelectInput.js +1 -1
  95. package/dist/index-NotchedOutline.js +1 -1
  96. package/dist/index-OnChangeContentPlugin.js +1 -1
  97. package/dist/index-OnFocusOnBlurPlugin.js +1 -1
  98. package/dist/index-OutlinedInput.js +1 -1
  99. package/dist/index-Paper.js +1 -1
  100. package/dist/index-Parser2.js +314 -255
  101. package/dist/index-Parser3.js +129 -2
  102. package/dist/index-PickersDay.js +1 -1
  103. package/dist/index-Popover2.js +1 -1
  104. package/dist/index-Popper.js +1 -1
  105. package/dist/index-Portal.js +1 -1
  106. package/dist/index-PropTypes.js +1 -1
  107. package/dist/index-QuarterParser.js +1 -1
  108. package/dist/index-Ripple.js +1 -1
  109. package/dist/index-RtlProvider.js +1 -1
  110. package/dist/index-ScrollbarSize.js +1 -1
  111. package/dist/index-SecondParser.js +1 -1
  112. package/dist/index-Select2.js +1 -1
  113. package/dist/index-SelectInput2.js +1 -1
  114. package/dist/index-Skeleton2.js +1 -1
  115. package/dist/index-Slide.js +1 -1
  116. package/dist/index-Slider2.js +1 -1
  117. package/dist/index-SliderValueLabel.js +1 -1
  118. package/dist/index-Snackbar2.js +1 -1
  119. package/dist/index-SnackbarContent.js +1 -1
  120. package/dist/index-StandAloneLocalDayParser.js +1 -1
  121. package/dist/index-StandAloneMonthParser.js +1 -1
  122. package/dist/index-StandAloneQuarterParser.js +1 -1
  123. package/dist/index-StyledEngineProvider.js +1 -1
  124. package/dist/index-StyledSVG2.js +1 -1
  125. package/dist/index-SvgIcon.js +1 -1
  126. package/dist/index-Tab2.js +1 -1
  127. package/dist/index-TabScrollButton.js +1 -1
  128. package/dist/index-Tabs2.js +1 -1
  129. package/dist/index-Text.js +18 -18
  130. package/dist/index-TextField.js +1 -1
  131. package/dist/index-TextHighlighted.js +23 -19
  132. package/dist/index-TextareaAutosize.js +1 -1
  133. package/dist/index-TimestampMillisecondsParser.js +1 -1
  134. package/dist/index-TimestampSecondsParser.js +1 -1
  135. package/dist/index-ToggleButton2.js +1 -1
  136. package/dist/index-ToggleButtonGroup2.js +1 -1
  137. package/dist/index-Tokenizer.js +411 -334
  138. package/dist/index-Tokenizer2.js +139 -2
  139. package/dist/index-Toolbar2.js +1 -1
  140. package/dist/index-Tooltip.js +1 -1
  141. package/dist/index-TouchRipple.js +1 -1
  142. package/dist/index-Transition.js +1 -1
  143. package/dist/index-TransitionGroup.js +1 -1
  144. package/dist/index-Typography.js +1 -1
  145. package/dist/index-YearParser.js +1 -1
  146. package/dist/index-YearPicker.js +1 -1
  147. package/dist/index-_virtual12.js +1 -1
  148. package/dist/index-_virtual15.js +2 -5
  149. package/dist/index-_virtual16.js +5 -3
  150. package/dist/index-_virtual17.js +5 -2
  151. package/dist/index-_virtual18.js +2 -7
  152. package/dist/index-_virtual19.js +4 -4
  153. package/dist/index-_virtual21.js +2 -2
  154. package/dist/index-_virtual22.js +2 -2
  155. package/dist/index-_virtual23.js +2 -3
  156. package/dist/index-_virtual24.js +2 -2
  157. package/dist/index-_virtual25.js +2 -2
  158. package/dist/index-_virtual26.js +2 -2
  159. package/dist/index-_virtual27.js +2 -2
  160. package/dist/index-_virtual28.js +2 -2
  161. package/dist/index-_virtual30.js +2 -2
  162. package/dist/index-_virtual31.js +2 -2
  163. package/dist/index-_virtual32.js +3 -2
  164. package/dist/index-_virtual34.js +2 -2
  165. package/dist/index-_virtual35.js +2 -4
  166. package/dist/index-_virtual36.js +1 -1
  167. package/dist/index-_virtual37.js +1 -1
  168. package/dist/index-_virtual38.js +1 -1
  169. package/dist/index-_virtual39.js +1 -1
  170. package/dist/index-_virtual40.js +1 -1
  171. package/dist/index-_virtual41.js +4 -2
  172. package/dist/index-_virtual42.js +2 -4
  173. package/dist/index-_virtual43.js +1 -1
  174. package/dist/index-_virtual44.js +1 -1
  175. package/dist/index-_virtual45.js +1 -1
  176. package/dist/index-_virtual46.js +1 -1
  177. package/dist/index-_virtual47.js +1 -1
  178. package/dist/index-_virtual48.js +1 -1
  179. package/dist/index-_virtual49.js +1 -1
  180. package/dist/index-_virtual50.js +1 -1
  181. package/dist/index-_virtual51.js +1 -1
  182. package/dist/index-_virtual52.js +1 -1
  183. package/dist/index-_virtual53.js +1 -1
  184. package/dist/index-_virtual54.js +1 -1
  185. package/dist/index-_virtual55.js +1 -1
  186. package/dist/index-_virtual56.js +1 -1
  187. package/dist/index-_virtual57.js +1 -1
  188. package/dist/index-_virtual58.js +4 -2
  189. package/dist/index-_virtual60.js +2 -4
  190. package/dist/index-_virtual61.js +1 -1
  191. package/dist/index-_virtual62.js +4 -2
  192. package/dist/index-_virtual63.js +2 -2
  193. package/dist/index-_virtual66.js +2 -2
  194. package/dist/index-_virtual67.js +2 -4
  195. package/dist/index-_virtual68.js +4 -2
  196. package/dist/index-_virtual74.js +1 -1
  197. package/dist/index-_virtual76.js +2 -2
  198. package/dist/index-_virtual77.js +4 -2
  199. package/dist/index-_virtual78.js +1 -1
  200. package/dist/index-_virtual79.js +1 -1
  201. package/dist/index-_virtual80.js +1 -1
  202. package/dist/index-_virtual81.js +1 -1
  203. package/dist/index-_virtual82.js +1 -1
  204. package/dist/index-_virtual83.js +1 -1
  205. package/dist/index-_virtual84.js +1 -1
  206. package/dist/index-_virtual85.js +2 -4
  207. package/dist/index-_virtual86.js +2 -2
  208. package/dist/index-applyInternationalSeparatorStyle.js +1 -1
  209. package/dist/index-attributes-to-props.js +1 -1
  210. package/dist/index-cjs.js +19 -75
  211. package/dist/index-colorManipulator3.js +2 -2
  212. package/dist/index-constants.js +38 -8
  213. package/dist/index-constants2.js +8 -38
  214. package/dist/index-createExtensionPattern.js +1 -1
  215. package/dist/index-createStyled2.js +6 -6
  216. package/dist/index-decode-data-html.js +5 -11
  217. package/dist/index-decode-data-xml.js +5 -11
  218. package/dist/index-decode.js +263 -216
  219. package/dist/index-decode_codepoint.js +43 -53
  220. package/dist/index-defaultRanges.js +10 -10
  221. package/dist/index-dist5.js +1 -1
  222. package/dist/index-elementAcceptingRef.js +1 -1
  223. package/dist/index-elementTypeAcceptingRef.js +1 -1
  224. package/dist/index-emotion-cache.browser.esm.js +2 -2
  225. package/dist/index-escape.js +43 -48
  226. package/dist/index-esm2.js +108 -129
  227. package/dist/index-esm3.js +12 -301
  228. package/dist/index-esm4.js +135 -17
  229. package/dist/index-esm5.js +303 -0
  230. package/dist/index-esm6.js +21 -0
  231. package/dist/index-esm7.js +102 -0
  232. package/dist/index-exenv.js +1 -1
  233. package/dist/index-extractCountryCallingCode.js +1 -1
  234. package/dist/index-extractPhoneContext.js +1 -1
  235. package/dist/index-foreignNames.js +101 -108
  236. package/dist/index-helpers3.js +1 -1
  237. package/dist/index-http.store.js +1 -1
  238. package/dist/index-isViablePhoneNumber.js +1 -1
  239. package/dist/index-keycode.js +1 -1
  240. package/dist/index-lib.js +2 -2
  241. package/dist/index-lib2.js +424 -111
  242. package/dist/index-lib3.js +14 -433
  243. package/dist/index-lib4.js +120 -14
  244. package/dist/index-lib5.js +10 -69
  245. package/dist/index-mpd-parser.es.js +1 -1
  246. package/dist/index-node.js +1 -1
  247. package/dist/index-node2.js +1 -1
  248. package/dist/index-parse2.js +1 -1
  249. package/dist/index-parse3.js +122 -20
  250. package/dist/index-refType.js +1 -1
  251. package/dist/index-responsivePropType.js +1 -1
  252. package/dist/index-sanitize-html.js +91 -48
  253. package/dist/index-stripIddPrefix.js +1 -1
  254. package/dist/index-style-to-object.js +1 -1
  255. package/dist/index-text-animate-words-style.js +12 -12
  256. package/dist/index-tiny-emitter.js +1 -1
  257. package/dist/index-use-dynamic-import.js +2 -0
  258. package/dist/index-useHyperlinkEditor.js +1 -1
  259. package/dist/index-useLexicalToolbar.js +1 -1
  260. package/dist/index-useRteAiAssistant-selection.js +5 -5
  261. package/dist/index-useThemeWithoutDefault3.js +1 -1
  262. package/dist/index-utilities.js +1 -1
  263. package/dist/index-utilities2.js +1 -1
  264. package/dist/index-utils2.js +1 -1
  265. package/dist/index-utils6.js +7 -7
  266. package/dist/index.js +428 -426
  267. package/dist/types/core/RichTextEditor/stories/RichTextEditorStory.story.d.ts +2 -0
  268. package/dist/types/core/RichTextEditor/stories/RichTextEditorWithXSSAttackStory.story.d.ts +2 -0
  269. package/dist/types/core/RichTextEditor/stories/_RichTextEditor.default.d.ts +4 -0
  270. package/dist/types/core/RichTextEditor/stories/bootstrap/richtexteditor.test.slice.d.ts +1 -0
  271. package/dist/types/core/TextHighlighted/stories/TextHighlightedStory.story.d.ts +2 -0
  272. package/dist/types/core/TextHighlighted/stories/TextHighlightedStory2.story.d.ts +2 -0
  273. package/dist/types/core/TextHighlighted/stories/TextHighlightedWithEmphasisStory.story.d.ts +2 -0
  274. package/dist/types/core/TextHighlighted/stories/TextHighlightedWithXSSAttackStory.story.d.ts +2 -0
  275. package/dist/types/core/TextHighlighted/stories/_TextHighlighted.default.d.ts +7 -0
  276. package/dist/types/core/_internal/InputBase/stories/HighlightLengthExceededTest.story.d.ts +2 -0
  277. package/dist/types/core/_internal/InputBase/stories/HighlightUrlTest.story.d.ts +2 -0
  278. package/dist/types/core/_internal/InputBase/stories/HighlightWordsTest.story.d.ts +2 -0
  279. package/dist/types/helpers/sanitize-html.d.ts +18 -3
  280. package/dist/types/index.d.ts +2 -0
  281. package/dist/vanguard-asset-analysis.json +1 -1
  282. package/dist-wordpress/Icon-tools-active-1-B-9tOuX0.mjs +4 -0
  283. package/dist-wordpress/Icon-tools-active-t9IjG2pg.mjs +4 -0
  284. package/dist-wordpress/index.js +23653 -22245
  285. package/package.json +5 -2
  286. package/scripts/check-meta-coverage.js +117 -0
  287. package/scripts/generate-exports-props.js +855 -0
  288. package/dist/index-Parser5.js +0 -131
  289. package/dist/index-Tokenizer3.js +0 -141
  290. package/dist/index-_virtual87.js +0 -4
  291. package/dist/index-_virtual88.js +0 -4
  292. package/dist/index-_virtual89.js +0 -4
  293. package/dist/index-_virtual90.js +0 -4
  294. package/dist/index-_virtual91.js +0 -4
  295. package/dist/index-at-rule.js +0 -22
  296. package/dist/index-cjs2.js +0 -23
  297. package/dist/index-comment.js +0 -16
  298. package/dist/index-container.js +0 -223
  299. package/dist/index-css-syntax-error.js +0 -56
  300. package/dist/index-declaration.js +0 -19
  301. package/dist/index-decode-data-html2.js +0 -4
  302. package/dist/index-decode-data-xml2.js +0 -4
  303. package/dist/index-decode2.js +0 -4
  304. package/dist/index-decode_codepoint2.js +0 -4
  305. package/dist/index-document3.js +0 -23
  306. package/dist/index-encode-html.js +0 -15
  307. package/dist/index-encode-html2.js +0 -4
  308. package/dist/index-encode.js +0 -49
  309. package/dist/index-encode2.js +0 -4
  310. package/dist/index-escape-string-regexp.js +0 -11
  311. package/dist/index-escape2.js +0 -4
  312. package/dist/index-feeds.js +0 -92
  313. package/dist/index-feeds2.js +0 -4
  314. package/dist/index-foreignNames2.js +0 -4
  315. package/dist/index-fromJSON.js +0 -46
  316. package/dist/index-helpers4.js +0 -54
  317. package/dist/index-helpers5.js +0 -4
  318. package/dist/index-input3.js +0 -139
  319. package/dist/index-is-plain-object.js +0 -17
  320. package/dist/index-is-plain-object2.js +0 -4
  321. package/dist/index-lazy-result.js +0 -343
  322. package/dist/index-legacy.js +0 -75
  323. package/dist/index-legacy2.js +0 -4
  324. package/dist/index-lib6.js +0 -13
  325. package/dist/index-lib7.js +0 -43
  326. package/dist/index-lib8.js +0 -147
  327. package/dist/index-lib9.js +0 -90
  328. package/dist/index-list3.js +0 -25
  329. package/dist/index-manipulation.js +0 -61
  330. package/dist/index-manipulation2.js +0 -4
  331. package/dist/index-map-generator.js +0 -171
  332. package/dist/index-no-work-result.js +0 -94
  333. package/dist/index-node4.js +0 -259
  334. package/dist/index-non-secure.js +0 -20
  335. package/dist/index-parse-srcset.js +0 -71
  336. package/dist/index-parse-srcset2.js +0 -4
  337. package/dist/index-parse4.js +0 -127
  338. package/dist/index-parser4.js +0 -322
  339. package/dist/index-picocolors.browser.js +0 -13
  340. package/dist/index-picocolors.browser2.js +0 -4
  341. package/dist/index-postcss.js +0 -46
  342. package/dist/index-previous-map.js +0 -92
  343. package/dist/index-processor.js +0 -43
  344. package/dist/index-querying.js +0 -63
  345. package/dist/index-querying2.js +0 -4
  346. package/dist/index-result.js +0 -30
  347. package/dist/index-root.js +0 -38
  348. package/dist/index-rule.js +0 -24
  349. package/dist/index-sanitize-html2.js +0 -672
  350. package/dist/index-stringifier.js +0 -196
  351. package/dist/index-stringify.js +0 -14
  352. package/dist/index-stringify2.js +0 -36
  353. package/dist/index-stringify3.js +0 -4
  354. package/dist/index-symbols.js +0 -8
  355. package/dist/index-symbols2.js +0 -4
  356. package/dist/index-tokenize.js +0 -114
  357. package/dist/index-traversal.js +0 -48
  358. package/dist/index-traversal2.js +0 -4
  359. package/dist/index-warn-once.js +0 -12
  360. package/dist/index-warning2.js +0 -25
  361. /package/dist/{index-Parser6.js → index-Parser4.js} +0 -0
@@ -0,0 +1,855 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate TypeScript type information for all exported components, hooks, and helpers.
4
+ *
5
+ * This script:
6
+ * 1. Parses src/index.ts to identify all value exports (skips types/interfaces)
7
+ * 2. Loads metadata from src/exports-meta/*.json for enrichment
8
+ * 3. Uses TypeScript Compiler API to extract type information
9
+ * 4. Generates JSON files with props, types, and metadata for MCP context
10
+ *
11
+ * Output: src/exports-props/*.json
12
+ *
13
+ * Usage: node scripts/generate-exports-props.js
14
+ */
15
+ const ts = require('typescript');
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const ROOT = path.resolve(__dirname, '..');
20
+ const INDEX = path.join(ROOT, 'src', 'index.ts');
21
+ const META_DIR = path.join(ROOT, 'src', 'exports-meta');
22
+ // output folder moved under `src` so MCP package can import generated files
23
+ const OUT_DIR = path.join(ROOT, 'src', 'exports-props');
24
+
25
+ function ensureOutDir() {
26
+ if (!fs.existsSync(OUT_DIR)) fs.mkdirSync(OUT_DIR, { recursive: true });
27
+ }
28
+
29
+ function log(...args) {
30
+ console.log('[generate-exports-props]', ...args);
31
+ }
32
+
33
+ /**
34
+ * Parse index.ts to extract all value (non-type) exports.
35
+ * Uses regex-based approach similar to check-meta-coverage.js for consistency.
36
+ */
37
+ function parseValueExportsFromIndex(indexPath) {
38
+ const content = fs.readFileSync(indexPath, 'utf8');
39
+ const lines = content.split('\n');
40
+ const exports = new Set();
41
+
42
+ // Regex to match "export { A, B, C } from ..." or "export { A } from ..."
43
+ const namedExportRegex = /export\s+\{\s*([^}]+)\s*\}\s+from/g;
44
+ // Regex to match "export const x = ..." or "export function x() ..." or "export class x ..."
45
+ const inlineExportRegex = /export\s+(const|function|class|let|var)\s+([a-zA-Z0-9_$]+)/g;
46
+
47
+ lines.forEach((line) => {
48
+ // Skip type exports
49
+ if (line.trim().startsWith('export type')) return;
50
+ if (line.trim().startsWith('export interface')) return;
51
+
52
+ // Handle named exports: export { A, B } from '...'
53
+ let match;
54
+ while ((match = namedExportRegex.exec(line)) !== null) {
55
+ const items = match[1].split(',').map((i) => i.trim().split(/\s+as\s+/)[0]);
56
+ items.forEach((item) => {
57
+ if (item && item !== 'type') {
58
+ exports.add(item);
59
+ }
60
+ });
61
+ }
62
+ namedExportRegex.lastIndex = 0; // Reset for next line
63
+
64
+ // Handle inline exports: export const X = ...
65
+ while ((match = inlineExportRegex.exec(line)) !== null) {
66
+ exports.add(match[2]);
67
+ }
68
+ inlineExportRegex.lastIndex = 0;
69
+ });
70
+
71
+ return Array.from(exports);
72
+ }
73
+
74
+ /**
75
+ * Load metadata files to classify exports and get additional context.
76
+ */
77
+ function loadMetadata() {
78
+ const metadata = new Map();
79
+ if (!fs.existsSync(META_DIR)) {
80
+ log('WARNING: Meta directory does not exist:', META_DIR);
81
+ return metadata;
82
+ }
83
+
84
+ const metaFiles = fs.readdirSync(META_DIR).filter((f) => f.endsWith('.json'));
85
+ log('Loading', metaFiles.length, 'metadata files from', META_DIR);
86
+
87
+ for (const file of metaFiles) {
88
+ const name = path.basename(file, '.json');
89
+ const filePath = path.join(META_DIR, file);
90
+ try {
91
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
92
+ metadata.set(name, data);
93
+ } catch (e) {
94
+ log('WARNING: Failed to parse metadata file', file, ':', e.message);
95
+ }
96
+ }
97
+
98
+ return metadata;
99
+ }
100
+
101
+ function createProgram() {
102
+ // Load project tsconfig so we analyze the whole project and can resolve types across files
103
+ try {
104
+ const configPath = ts.findConfigFile(ROOT, ts.sys.fileExists, 'tsconfig.json');
105
+ if (configPath) {
106
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
107
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
108
+ const rootNames = parsed.fileNames;
109
+ const options = parsed.options;
110
+ return ts.createProgram(rootNames, options);
111
+ }
112
+ } catch (e) {
113
+ console.warn('Could not load tsconfig, falling back to single-file program', e && e.message);
114
+ }
115
+
116
+ const options = {
117
+ target: ts.ScriptTarget.ESNext,
118
+ module: ts.ModuleKind.ESNext,
119
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
120
+ jsx: ts.JsxEmit.React,
121
+ allowJs: true,
122
+ skipLibCheck: true,
123
+ };
124
+ return ts.createProgram([INDEX], options);
125
+ }
126
+
127
+ function resolveModule(specifier, containingFile, options) {
128
+ const resolved = ts.resolveModuleName(specifier, containingFile, options, ts.sys);
129
+ return resolved.resolvedModule && resolved.resolvedModule.resolvedFileName;
130
+ }
131
+
132
+ function isSimpleConstant(decl) {
133
+ // treat as simple constant if it's a variable declared with const and initializer is literal (string/number/boolean/null)
134
+ if (!decl) return false;
135
+ if (decl.kind === ts.SyntaxKind.VariableDeclaration) {
136
+ const parent = decl.parent && decl.parent.parent; // VariableDeclarationList -> VariableStatement
137
+ const declList = decl.parent;
138
+ if (declList && declList.flags & ts.NodeFlags.Const) {
139
+ const init = decl.initializer;
140
+ if (!init) return false;
141
+ return (
142
+ init.kind === ts.SyntaxKind.StringLiteral ||
143
+ init.kind === ts.SyntaxKind.NumericLiteral ||
144
+ init.kind === ts.SyntaxKind.TrueKeyword ||
145
+ init.kind === ts.SyntaxKind.FalseKeyword ||
146
+ init.kind === ts.SyntaxKind.NullKeyword
147
+ );
148
+ }
149
+ }
150
+ return false;
151
+ }
152
+
153
+ function serializeType(checker, type) {
154
+ try {
155
+ return checker.typeToString(
156
+ type,
157
+ undefined,
158
+ ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType,
159
+ );
160
+ } catch (e) {
161
+ return String(type && type.symbol ? type.symbol.name : type);
162
+ }
163
+ }
164
+
165
+ function collectReferencedTypes(checker, type, out = {}, seen = new Set()) {
166
+ if (!type || seen.has(type.id)) return out;
167
+ seen.add(type.id);
168
+
169
+ // Helpers
170
+ function isIntrinsic(t) {
171
+ const F = ts.TypeFlags;
172
+ return !!(
173
+ t.flags &
174
+ (F.String |
175
+ F.StringLiteral |
176
+ F.Number |
177
+ F.NumberLiteral |
178
+ F.Boolean |
179
+ F.BooleanLiteral |
180
+ F.ESSymbol |
181
+ F.ESSymbolLike |
182
+ F.Null |
183
+ F.Undefined |
184
+ F.Void |
185
+ F.Any |
186
+ F.Unknown)
187
+ );
188
+ }
189
+ function isProjectSource(sf) {
190
+ if (!sf) return false;
191
+ if (sf.isDeclarationFile) return false; // skip lib and .d.ts files
192
+ const fn = sf.fileName;
193
+ if (!fn) return false;
194
+ if (fn.indexOf('node_modules') !== -1) return false;
195
+ // prefer files inside project root
196
+ return fn.startsWith(ROOT);
197
+ }
198
+
199
+ // Skip primitives and builtins to avoid huge noise (String/Array prototype methods etc)
200
+ try {
201
+ if (isIntrinsic(type)) return out;
202
+ } catch (e) {}
203
+
204
+ // If this type is a named symbol, capture a minimal snippet + source only when it's from project files
205
+ const typeSymbol = type.symbol || type.aliasSymbol || null;
206
+ if (typeSymbol && typeSymbol.getName && typeSymbol.declarations && typeSymbol.declarations.length) {
207
+ const name = typeSymbol.getName();
208
+ if (!out[name]) {
209
+ try {
210
+ const decl = typeSymbol.declarations[0];
211
+ const sf = decl.getSourceFile && decl.getSourceFile();
212
+ if (isProjectSource(sf)) {
213
+ const src = path.relative(ROOT, sf.fileName);
214
+ // get a short snippet (avoid dumping entire lib files)
215
+ let text = '';
216
+ try {
217
+ text = sf.text.substring(decl.pos, decl.end).trim().replace(/\s+/g, ' ');
218
+ if (text.length > 600) text = text.slice(0, 600) + '...';
219
+ } catch (e) {
220
+ text = name;
221
+ }
222
+ out[name] = { source: src, snippet: text };
223
+ }
224
+ } catch (e) {
225
+ out[typeSymbol.getName()] = { source: 'unknown', snippet: typeSymbol.getName() };
226
+ }
227
+ }
228
+ }
229
+
230
+ // Recurse into alias/type arguments
231
+ if (type.aliasTypeArguments && type.aliasTypeArguments.length) {
232
+ for (const ta of type.aliasTypeArguments) collectReferencedTypes(checker, ta, out, seen);
233
+ }
234
+ if (type.typeArguments && type.typeArguments.length) {
235
+ for (const ta of type.typeArguments) collectReferencedTypes(checker, ta, out, seen);
236
+ }
237
+
238
+ // If object-like, iterate properties but avoid recursing into builtins or declaration file types
239
+ const props = type.getProperties ? type.getProperties() : [];
240
+ for (const p of props) {
241
+ try {
242
+ const decl = p.valueDeclaration || (p.declarations && p.declarations[0]);
243
+ const pType = checker.getTypeOfSymbolAtLocation(p, decl || decl);
244
+ // if property's type is intrinsic or from .d.ts skip
245
+ const pDecl =
246
+ (pType && (pType.symbol || pType.aliasSymbol) && pType.symbol.declarations && pType.symbol.declarations[0]) ||
247
+ null;
248
+ const pSF = pDecl && pDecl.getSourceFile && pDecl.getSourceFile();
249
+ if (pSF && !isProjectSource(pSF)) continue;
250
+ if (isIntrinsic(pType)) continue;
251
+ collectReferencedTypes(checker, pType, out, seen);
252
+ } catch (e) {
253
+ /* ignore */
254
+ }
255
+ }
256
+
257
+ // signatures
258
+ if (type.getCallSignatures) {
259
+ for (const sig of type.getCallSignatures()) {
260
+ for (const param of sig.getParameters()) {
261
+ try {
262
+ const decl = param.valueDeclaration || (param.declarations && param.declarations[0]);
263
+ const pType = checker.getTypeOfSymbolAtLocation(param, decl || decl);
264
+ if (isIntrinsic(pType)) continue;
265
+ // skip params declared in .d.ts
266
+ const pDecl = (param && param.declarations && param.declarations[0]) || null;
267
+ const pSF = pDecl && pDecl.getSourceFile && pDecl.getSourceFile();
268
+ if (pSF && !isProjectSource(pSF)) continue;
269
+ collectReferencedTypes(checker, pType, out, seen);
270
+ } catch (e) {}
271
+ }
272
+ const ret = sig.getReturnType && sig.getReturnType();
273
+ if (ret && !isIntrinsic(ret)) {
274
+ const retDecl =
275
+ (ret &&
276
+ (ret.symbol || ret.aliasSymbol) &&
277
+ ret.symbol &&
278
+ ret.symbol.declarations &&
279
+ ret.symbol.declarations[0]) ||
280
+ null;
281
+ const rSF = retDecl && retDecl.getSourceFile && retDecl.getSourceFile();
282
+ if (!rSF || isProjectSource(rSF)) collectReferencedTypes(checker, ret, out, seen);
283
+ }
284
+ }
285
+ }
286
+
287
+ return out;
288
+ }
289
+
290
+ function findTypeAliasByName(program, checker, typeName, preferredDir) {
291
+ // Prefer same-directory declarations
292
+ const files = program.getSourceFiles();
293
+ let candidate = null;
294
+ for (const sf of files) {
295
+ if (sf.isDeclarationFile) continue;
296
+ if (preferredDir && !sf.fileName.startsWith(preferredDir)) continue;
297
+ for (const stmt of sf.statements) {
298
+ if (
299
+ (ts.isTypeAliasDeclaration(stmt) || ts.isInterfaceDeclaration(stmt)) &&
300
+ stmt.name &&
301
+ stmt.name.text === typeName
302
+ ) {
303
+ try {
304
+ if (ts.isTypeAliasDeclaration(stmt) && stmt.type) {
305
+ return checker.getTypeFromTypeNode(stmt.type);
306
+ }
307
+ return checker.getTypeAtLocation(stmt);
308
+ } catch (e) {}
309
+ }
310
+ }
311
+ // if not found in preferred dir, remember one as fallback
312
+ for (const stmt of sf.statements) {
313
+ if (
314
+ (ts.isTypeAliasDeclaration(stmt) || ts.isInterfaceDeclaration(stmt)) &&
315
+ stmt.name &&
316
+ stmt.name.text === typeName
317
+ ) {
318
+ try {
319
+ if (!candidate) candidate = checker.getTypeAtLocation(stmt);
320
+ } catch (e) {}
321
+ }
322
+ }
323
+ }
324
+ return candidate;
325
+ }
326
+
327
+ function findTypeDeclarationSnippet(program, checker, typeName, preferredDir) {
328
+ const files = program.getSourceFiles();
329
+ // Prefer same-directory declarations
330
+ for (const sf of files) {
331
+ if (sf.isDeclarationFile) continue;
332
+ if (preferredDir && !sf.fileName.startsWith(preferredDir)) continue;
333
+ for (const stmt of sf.statements) {
334
+ if (
335
+ (ts.isTypeAliasDeclaration(stmt) || ts.isInterfaceDeclaration(stmt) || ts.isEnumDeclaration(stmt)) &&
336
+ stmt.name &&
337
+ stmt.name.text === typeName
338
+ ) {
339
+ try {
340
+ const src = path.relative(ROOT, sf.fileName);
341
+ let text = stmt.getText().replace(/\s+/g, ' ');
342
+ if (text.length > 600) text = text.slice(0, 600) + '...';
343
+ return { source: src, snippet: text };
344
+ } catch (e) {}
345
+ }
346
+ }
347
+ }
348
+ // fallback: loose search across project files
349
+ for (const sf of files) {
350
+ if (sf.isDeclarationFile) continue;
351
+ for (const stmt of sf.statements) {
352
+ if (
353
+ (ts.isTypeAliasDeclaration(stmt) || ts.isInterfaceDeclaration(stmt) || ts.isEnumDeclaration(stmt)) &&
354
+ stmt.name &&
355
+ stmt.name.text === typeName
356
+ ) {
357
+ try {
358
+ const src = path.relative(ROOT, sf.fileName);
359
+ let text = stmt.getText().replace(/\s+/g, ' ');
360
+ if (text.length > 600) text = text.slice(0, 600) + '...';
361
+ return { source: src, snippet: text };
362
+ } catch (e) {}
363
+ }
364
+ }
365
+ }
366
+ return null;
367
+ }
368
+
369
+ function getPropsTypeForSymbol(checker, symbol, fromPath) {
370
+ if (!symbol) return null;
371
+
372
+ // If this is an alias (re-export), resolve to the original symbol so we can inspect the real declaration
373
+ try {
374
+ if (symbol.flags & ts.SymbolFlags.Alias) {
375
+ const aliased = checker.getAliasedSymbol(symbol);
376
+ if (aliased) symbol = aliased;
377
+ }
378
+ } catch (e) {
379
+ // ignore
380
+ }
381
+
382
+ const decl = symbol.valueDeclaration || (symbol.declarations && symbol.declarations[0]);
383
+ if (!decl) return null;
384
+
385
+ // If this declaration is an export specifier from a barrel file, try to resolve the original module
386
+ if (
387
+ decl.kind === ts.SyntaxKind.ExportSpecifier ||
388
+ (decl.getSourceFile && decl.getSourceFile().fileName && decl.getSourceFile().fileName.endsWith('/index.ts'))
389
+ ) {
390
+ try {
391
+ const sf = decl.getSourceFile();
392
+ // find export declarations that export this name and have a moduleSpecifier
393
+ const nameToFind = symbol.getName();
394
+ const exports = sf.statements.filter(
395
+ (s) => ts.isExportDeclaration(s) && s.moduleSpecifier && s.exportClause && ts.isNamedExports(s.exportClause),
396
+ );
397
+ for (const ed of exports) {
398
+ const named = ed.exportClause;
399
+ for (const el of named.elements) {
400
+ const exportedName = el.name && el.name.text;
401
+ const localName = el.propertyName ? el.propertyName.text : exportedName;
402
+ if (exportedName === nameToFind) {
403
+ const spec = ed.moduleSpecifier && ed.moduleSpecifier.text;
404
+ if (!spec) continue;
405
+ const resolved = resolveModule(spec, sf.fileName, program.getCompilerOptions());
406
+ if (!resolved) continue;
407
+ const targetSF = program.getSourceFile(resolved);
408
+ if (!targetSF) continue;
409
+ const moduleSymbol = checker.getSymbolAtLocation(targetSF);
410
+ if (!moduleSymbol) continue;
411
+ const exportsOfModule = checker.getExportsOfModule(moduleSymbol);
412
+ const sym = exportsOfModule.find(
413
+ (s) => s.getName() === (el.propertyName ? el.propertyName.text : exportedName),
414
+ );
415
+ if (sym) {
416
+ // recurse on resolved symbol
417
+ return getPropsTypeForSymbol(checker, sym, resolved);
418
+ }
419
+ }
420
+ }
421
+ }
422
+
423
+ // Fallback: attempt to find implementation file with the same name in this folder (e.g., Text.tsx)
424
+ try {
425
+ const dir = path.dirname(sf.fileName);
426
+ const candidates = [`${nameToFind}.tsx`, `${nameToFind}.ts`, `${nameToFind}.jsx`, `${nameToFind}.js`];
427
+ for (const c of candidates) {
428
+ const p = path.join(dir, c);
429
+ const targetSF2 = program.getSourceFile(p);
430
+ if (!targetSF2) continue;
431
+ const moduleSymbol2 = checker.getSymbolAtLocation(targetSF2);
432
+ if (!moduleSymbol2) continue;
433
+ const exportsOfModule2 = checker.getExportsOfModule(moduleSymbol2);
434
+ const sym2 = exportsOfModule2.find((s) => s.getName() === nameToFind);
435
+ if (sym2) return getPropsTypeForSymbol(checker, sym2, p);
436
+ }
437
+ } catch (e) {
438
+ // ignore
439
+ }
440
+ } catch (e) {
441
+ // ignore resolution errors
442
+ }
443
+ }
444
+
445
+ // If the declaration is a variable with an arrow/function initializer, inspect its parameters directly
446
+ if (decl.kind === ts.SyntaxKind.VariableDeclaration) {
447
+ const init = decl.initializer;
448
+ // handle direct function/arrow
449
+ if (init && (init.kind === ts.SyntaxKind.ArrowFunction || init.kind === ts.SyntaxKind.FunctionExpression)) {
450
+ const params = init.parameters || [];
451
+ if (params.length > 0) {
452
+ const firstParam = params[0];
453
+ if (firstParam.type) {
454
+ try {
455
+ return checker.getTypeFromTypeNode(firstParam.type);
456
+ } catch (e) {
457
+ // fall through to other heuristics
458
+ }
459
+ }
460
+ }
461
+ }
462
+
463
+ // handle forwardRef/memo and HOC patterns: variable initializer is a CallExpression
464
+ if (init && ts.isCallExpression(init)) {
465
+ const expr = init.expression;
466
+ // common patterns: React.forwardRef(Component), memo(Component)
467
+ if (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr)) {
468
+ const arg0 = init.arguments && init.arguments[0];
469
+ if (arg0 && (ts.isFunctionExpression(arg0) || ts.isArrowFunction(arg0))) {
470
+ const params = arg0.parameters || [];
471
+ if (params.length > 0) {
472
+ const firstParam = params[0];
473
+ if (firstParam.type) {
474
+ try {
475
+ return checker.getTypeFromTypeNode(firstParam.type);
476
+ } catch (e) {}
477
+ }
478
+ }
479
+ }
480
+
481
+ // if arg0 is an identifier, try to resolve its symbol
482
+ if (arg0 && ts.isIdentifier(arg0)) {
483
+ try {
484
+ const s = checker.getSymbolAtLocation(arg0);
485
+ if (s)
486
+ return getPropsTypeForSymbol(
487
+ checker,
488
+ s,
489
+ s.valueDeclaration && s.valueDeclaration.getSourceFile && s.valueDeclaration.getSourceFile().fileName,
490
+ );
491
+ } catch (e) {}
492
+ }
493
+ }
494
+ }
495
+ }
496
+
497
+ // If it's a function or has call signatures, use the first parameter type
498
+ const valueType = checker.getTypeOfSymbolAtLocation(symbol, decl);
499
+ const callSigs = valueType.getCallSignatures ? valueType.getCallSignatures() : [];
500
+ if (callSigs && callSigs.length) {
501
+ const sig = callSigs[0];
502
+ const params = sig.getParameters();
503
+ if (params.length > 0) {
504
+ try {
505
+ const first = params[0];
506
+ const pt = checker.getTypeOfSymbolAtLocation(
507
+ first,
508
+ first.valueDeclaration || (first.declarations && first.declarations[0]),
509
+ );
510
+ return pt;
511
+ } catch (e) {
512
+ // fallback
513
+ }
514
+ }
515
+ }
516
+
517
+ // If it's a class, check constructor
518
+ if (decl.kind === ts.SyntaxKind.ClassDeclaration) {
519
+ const classType = checker.getTypeAtLocation(decl);
520
+ const constructs = classType.getConstructSignatures();
521
+ if (constructs && constructs.length) {
522
+ const sig = constructs[0];
523
+ const params = sig.getParameters();
524
+ if (params.length > 0) {
525
+ try {
526
+ const pt = checker.getTypeOfSymbolAtLocation(
527
+ params[0],
528
+ params[0].valueDeclaration || (params[0].declarations && params[0].declarations[0]),
529
+ );
530
+ return pt;
531
+ } catch (e) {}
532
+ }
533
+ }
534
+ }
535
+
536
+ // Attempt to use alias type arguments (React.FC<P>)
537
+ if (valueType.aliasTypeArguments && valueType.aliasTypeArguments.length) {
538
+ return valueType.aliasTypeArguments[0];
539
+ }
540
+ if (valueType.typeArguments && valueType.typeArguments.length) {
541
+ return valueType.typeArguments[0];
542
+ }
543
+
544
+ // if the valueType itself is object with a single property named 'props', use that
545
+ const propsProp = valueType.getProperty && valueType.getProperty('props');
546
+ if (propsProp) {
547
+ try {
548
+ return checker.getTypeOfSymbolAtLocation(
549
+ propsProp,
550
+ propsProp.valueDeclaration || (propsProp.declarations && propsProp.declarations[0]),
551
+ );
552
+ } catch (e) {}
553
+ }
554
+
555
+ // As a last resort, try to find a type alias/interface named `${Name}Props` or `Props` in workspace (prefer same dir)
556
+ try {
557
+ const name = symbol.getName();
558
+ const dirPref = decl && decl.getSourceFile && path.dirname(decl.getSourceFile().fileName);
559
+ const byName = findTypeAliasByName(program, checker, `${name}Props`, dirPref);
560
+ if (byName) return byName;
561
+ // generic 'Props' in same dir
562
+ const byProps = findTypeAliasByName(program, checker, 'Props', dirPref);
563
+ if (byProps) return byProps;
564
+ } catch (e) {}
565
+
566
+ return null;
567
+ }
568
+
569
+ function main() {
570
+ log('Starting analysis of', INDEX);
571
+
572
+ // Step 1: Parse index.ts to get all value exports
573
+ const allExports = parseValueExportsFromIndex(INDEX);
574
+ log('Found', allExports.length, 'value exports in index.ts');
575
+
576
+ // Step 2: Load metadata to enrich context
577
+ const metadata = loadMetadata();
578
+ log('Loaded metadata for', metadata.size, 'items');
579
+
580
+ // Step 3: Create TypeScript program for type analysis
581
+ const program = createProgram();
582
+ const checker = program.getTypeChecker();
583
+ const sf = program.getSourceFile(INDEX);
584
+ if (!sf) {
585
+ console.error('Could not load', INDEX);
586
+ process.exit(1);
587
+ }
588
+
589
+ ensureOutDir();
590
+
591
+ // Step 4: Build a map of export name -> symbol for type extraction
592
+ const symbolMap = new Map();
593
+ const moduleSymbol = checker.getSymbolAtLocation(sf);
594
+ if (moduleSymbol) {
595
+ const exports = checker.getExportsOfModule(moduleSymbol);
596
+ for (const sym of exports) {
597
+ symbolMap.set(sym.getName(), sym);
598
+ }
599
+ }
600
+
601
+ log('Processing', allExports.length, 'exports...');
602
+
603
+ let processed = 0;
604
+ let skipped = 0;
605
+
606
+ for (const name of allExports) {
607
+ const symbol = symbolMap.get(name);
608
+ if (!symbol) {
609
+ log('WARNING: Could not find symbol for export:', name);
610
+ skipped++;
611
+ continue;
612
+ }
613
+
614
+ // Get the original declaration location
615
+ let from = INDEX;
616
+ try {
617
+ if (symbol.flags & ts.SymbolFlags.Alias) {
618
+ const aliased = checker.getAliasedSymbol(symbol);
619
+ if (aliased && aliased.declarations && aliased.declarations[0]) {
620
+ const decl = aliased.declarations[0];
621
+ const declSf = decl.getSourceFile && decl.getSourceFile();
622
+ if (declSf) from = declSf.fileName;
623
+ }
624
+ } else if (symbol.declarations && symbol.declarations[0]) {
625
+ const decl = symbol.declarations[0];
626
+ const declSf = decl.getSourceFile && decl.getSourceFile();
627
+ if (declSf) from = declSf.fileName;
628
+ }
629
+ } catch (e) {
630
+ // Keep default 'from' value
631
+ }
632
+ try {
633
+ // Skip type-only symbols (type/interface/enum)
634
+ const decl = symbol.declarations && symbol.declarations[0];
635
+ if (!decl) {
636
+ skipped++;
637
+ continue;
638
+ }
639
+ if (
640
+ decl.kind === ts.SyntaxKind.TypeAliasDeclaration ||
641
+ decl.kind === ts.SyntaxKind.InterfaceDeclaration ||
642
+ decl.kind === ts.SyntaxKind.EnumDeclaration
643
+ ) {
644
+ skipped++;
645
+ continue;
646
+ }
647
+
648
+ // Skip simple constants
649
+ if (isSimpleConstant(decl)) {
650
+ skipped++;
651
+ continue;
652
+ }
653
+
654
+ // Determine kind
655
+ let kind = 'value';
656
+ if (decl.kind === ts.SyntaxKind.FunctionDeclaration) kind = 'function';
657
+ else if (decl.kind === ts.SyntaxKind.ClassDeclaration) kind = 'class';
658
+ else if (decl.kind === ts.SyntaxKind.VariableDeclaration) kind = 'variable';
659
+
660
+ let propsType = getPropsTypeForSymbol(checker, symbol, from);
661
+
662
+ // Special-case: directly read `Props` from `src/core/Text/Text.types.tsx` for the `Text` component
663
+ try {
664
+ if (name === 'Text' && (!propsType || serializeType(checker, propsType) === 'any')) {
665
+ const candidates = [
666
+ path.join(ROOT, 'src', 'core', 'Text', 'Text.types.tsx'),
667
+ path.join(ROOT, 'src', 'core', 'Text', 'Text.types.ts'),
668
+ path.join(ROOT, 'src', 'core', 'Text', 'Text.types.jsx'),
669
+ path.join(ROOT, 'src', 'core', 'Text', 'Text.types.js'),
670
+ ];
671
+ for (const p of candidates) {
672
+ const sfTypes = program.getSourceFile(p);
673
+ if (!sfTypes) continue;
674
+ for (const stmt of sfTypes.statements) {
675
+ if (ts.isTypeAliasDeclaration(stmt) && stmt.name && stmt.name.text === 'Props') {
676
+ try {
677
+ const t = checker.getTypeFromTypeNode(stmt.type);
678
+ if (t) {
679
+ propsType = t;
680
+ break;
681
+ }
682
+ } catch {
683
+ // Ignore errors
684
+ }
685
+ }
686
+ }
687
+ if (propsType) break;
688
+ }
689
+ }
690
+ } catch {
691
+ // Ignore Text special-case errors
692
+ }
693
+
694
+ // If we couldn't infer props or it resolved to `any`, try to find an exported props type in the same module
695
+ try {
696
+ const serialized = propsType ? serializeType(checker, propsType) : null;
697
+ if ((!propsType || serialized === 'any' || serialized === 'unknown') && from) {
698
+ const targetSF = program.getSourceFile(from);
699
+ if (targetSF) {
700
+ const targetModuleSymbol = checker.getSymbolAtLocation(targetSF);
701
+ if (targetModuleSymbol) {
702
+ const exportsOfModule = checker.getExportsOfModule(targetModuleSymbol);
703
+ const candidateNames = [`${name}Props`, 'Props', `${name}Props`];
704
+ for (const cn of candidateNames) {
705
+ const tsym = exportsOfModule.find((s) => s.getName() === cn);
706
+ if (tsym) {
707
+ try {
708
+ let ttype = null;
709
+ try {
710
+ // resolve re-exports/aliases
711
+ if (tsym.flags & ts.SymbolFlags.Alias) {
712
+ try {
713
+ const aliased = checker.getAliasedSymbol(tsym);
714
+ if (aliased) tsym = aliased;
715
+ } catch (e) {}
716
+ }
717
+
718
+ const decl0 = tsym.declarations && tsym.declarations[0];
719
+ // If it's a type alias with an explicit type node, use that to get a concrete type
720
+ if (
721
+ decl0 &&
722
+ (decl0.kind === ts.SyntaxKind.TypeAliasDeclaration ||
723
+ decl0.kind === ts.SyntaxKind.InterfaceDeclaration)
724
+ ) {
725
+ try {
726
+ if (decl0.kind === ts.SyntaxKind.TypeAliasDeclaration && decl0.type) {
727
+ ttype = checker.getTypeFromTypeNode(decl0.type);
728
+ } else {
729
+ ttype = checker.getTypeAtLocation(decl0);
730
+ }
731
+ } catch (e) {
732
+ ttype = null;
733
+ }
734
+ }
735
+
736
+ // fallback to getDeclaredTypeOfSymbol or getTypeOfSymbolAtLocation
737
+ if (!ttype) {
738
+ try {
739
+ if (tsym.flags & ts.SymbolFlags.TypeAlias) {
740
+ ttype = checker.getDeclaredTypeOfSymbol(tsym);
741
+ } else {
742
+ ttype = checker.getTypeOfSymbolAtLocation(tsym, tsym.valueDeclaration || decl0);
743
+ }
744
+ } catch (e) {
745
+ ttype = null;
746
+ }
747
+ }
748
+ } catch {
749
+ ttype = null;
750
+ }
751
+ if (ttype) {
752
+ propsType = ttype;
753
+ break;
754
+ }
755
+ } catch {
756
+ // Ignore type resolution errors
757
+ }
758
+ }
759
+ }
760
+ }
761
+ }
762
+ }
763
+ } catch (e) {}
764
+
765
+ const props = propsType ? serializeType(checker, propsType) : null;
766
+
767
+ // Build expanded props as a map of propName -> { type: string, optional: boolean }
768
+ let expandedProps = null;
769
+ // collect type names referenced via import("...") so we can ensure they appear in referencedTypes
770
+ const importedTypeNames = new Set();
771
+ try {
772
+ if (propsType) {
773
+ const propsObj = {};
774
+ const propsSyms = propsType.getProperties ? propsType.getProperties() : [];
775
+ const importRegex = /import\(["'][^"']+["']\)\.([A-Za-z0-9_$]+)/g;
776
+ for (const ps of propsSyms) {
777
+ try {
778
+ const decl0 = ps.valueDeclaration || (ps.declarations && ps.declarations[0]);
779
+ const ptype = checker.getTypeOfSymbolAtLocation(ps, decl0 || decl);
780
+ let ptypeStr = serializeType(checker, ptype);
781
+ // detect and collect imported type names (import("...").Name)
782
+ let m;
783
+ while ((m = importRegex.exec(ptypeStr))) {
784
+ importedTypeNames.add(m[1]);
785
+ }
786
+ // shorten import("...").Name -> Name for readability
787
+ const ptypeStrShort = ptypeStr.replace(importRegex, '$1');
788
+ const optional = decl0 && !!decl0.questionToken;
789
+ propsObj[ps.getName()] = { type: ptypeStrShort, optional };
790
+ } catch (e) {
791
+ propsObj[ps.getName()] = { type: 'unknown', optional: false };
792
+ }
793
+ }
794
+ expandedProps = propsObj;
795
+ }
796
+ } catch (e) {
797
+ expandedProps = null;
798
+ }
799
+
800
+ const referenced = propsType ? collectReferencedTypes(checker, propsType) : {};
801
+
802
+ // Ensure any types referenced via import("...").Name in expandedProps are present in referencedTypes
803
+ try {
804
+ const dirPref = decl && decl.getSourceFile && decl.getSourceFile().fileName;
805
+ for (const tn of importedTypeNames) {
806
+ if (!referenced[tn]) {
807
+ const snippet = findTypeDeclarationSnippet(program, checker, tn, dirPref);
808
+ if (snippet) referenced[tn] = snippet;
809
+ else referenced[tn] = { source: 'unknown', snippet: tn };
810
+ }
811
+ }
812
+ } catch (e) {}
813
+
814
+ // Get metadata if available
815
+ const meta = metadata.get(name);
816
+
817
+ // Build output with metadata enrichment
818
+ const out = {
819
+ name,
820
+ from: path.relative(ROOT, from),
821
+ kind,
822
+ props: props,
823
+ referencedTypes: referenced,
824
+ expandedProps: expandedProps,
825
+ // Include metadata for MCP context
826
+ ...(meta && {
827
+ metadata: {
828
+ kind: meta.kind,
829
+ category: meta.category,
830
+ summary: meta.summary,
831
+ description: meta.description,
832
+ tags: meta.tags,
833
+ keywords: meta.keywords,
834
+ relatedComponents: meta.relatedComponents,
835
+ },
836
+ }),
837
+ };
838
+
839
+ fs.writeFileSync(path.join(OUT_DIR, `${name}.json`), JSON.stringify(out, null, 2), 'utf8');
840
+ processed++;
841
+ } catch (error) {
842
+ console.error('Error processing', name, ':', error.message);
843
+ skipped++;
844
+ }
845
+ }
846
+
847
+ log('✅ Processing complete!');
848
+ log(' - Processed:', processed);
849
+ log(' - Skipped:', skipped);
850
+ log(' - Output directory:', OUT_DIR);
851
+ }
852
+
853
+ if (require.main === module) main();
854
+
855
+ module.exports = { main };