jamdesk 1.0.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 (435) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +323 -0
  3. package/bin/jamdesk.js +76 -0
  4. package/dist/__tests__/integration/deprecated-components.integration.test.d.ts +8 -0
  5. package/dist/__tests__/integration/deprecated-components.integration.test.d.ts.map +1 -0
  6. package/dist/__tests__/integration/deprecated-components.integration.test.js +165 -0
  7. package/dist/__tests__/integration/deprecated-components.integration.test.js.map +1 -0
  8. package/dist/__tests__/integration/migrate.integration.test.d.ts +2 -0
  9. package/dist/__tests__/integration/migrate.integration.test.d.ts.map +1 -0
  10. package/dist/__tests__/integration/migrate.integration.test.js +64 -0
  11. package/dist/__tests__/integration/migrate.integration.test.js.map +1 -0
  12. package/dist/__tests__/integration/prepublish.integration.test.d.ts +2 -0
  13. package/dist/__tests__/integration/prepublish.integration.test.d.ts.map +1 -0
  14. package/dist/__tests__/integration/prepublish.integration.test.js +27 -0
  15. package/dist/__tests__/integration/prepublish.integration.test.js.map +1 -0
  16. package/dist/__tests__/integration/validate.integration.test.d.ts +2 -0
  17. package/dist/__tests__/integration/validate.integration.test.d.ts.map +1 -0
  18. package/dist/__tests__/integration/validate.integration.test.js +56 -0
  19. package/dist/__tests__/integration/validate.integration.test.js.map +1 -0
  20. package/dist/__tests__/unit/deploy-templates.test.d.ts +2 -0
  21. package/dist/__tests__/unit/deploy-templates.test.d.ts.map +1 -0
  22. package/dist/__tests__/unit/deploy-templates.test.js +124 -0
  23. package/dist/__tests__/unit/deploy-templates.test.js.map +1 -0
  24. package/dist/__tests__/unit/deprecated-components-sync.test.d.ts +2 -0
  25. package/dist/__tests__/unit/deprecated-components-sync.test.d.ts.map +1 -0
  26. package/dist/__tests__/unit/deprecated-components-sync.test.js +69 -0
  27. package/dist/__tests__/unit/deprecated-components-sync.test.js.map +1 -0
  28. package/dist/__tests__/unit/deps-sync.test.d.ts +14 -0
  29. package/dist/__tests__/unit/deps-sync.test.d.ts.map +1 -0
  30. package/dist/__tests__/unit/deps-sync.test.js +166 -0
  31. package/dist/__tests__/unit/deps-sync.test.js.map +1 -0
  32. package/dist/__tests__/unit/docs-config.test.d.ts +2 -0
  33. package/dist/__tests__/unit/docs-config.test.d.ts.map +1 -0
  34. package/dist/__tests__/unit/docs-config.test.js +288 -0
  35. package/dist/__tests__/unit/docs-config.test.js.map +1 -0
  36. package/dist/__tests__/unit/errors.test.d.ts +2 -0
  37. package/dist/__tests__/unit/errors.test.d.ts.map +1 -0
  38. package/dist/__tests__/unit/errors.test.js +27 -0
  39. package/dist/__tests__/unit/errors.test.js.map +1 -0
  40. package/dist/__tests__/unit/extract-hooks.test.d.ts +5 -0
  41. package/dist/__tests__/unit/extract-hooks.test.d.ts.map +1 -0
  42. package/dist/__tests__/unit/extract-hooks.test.js +205 -0
  43. package/dist/__tests__/unit/extract-hooks.test.js.map +1 -0
  44. package/dist/__tests__/unit/frontmatter-sync.test.d.ts +8 -0
  45. package/dist/__tests__/unit/frontmatter-sync.test.d.ts.map +1 -0
  46. package/dist/__tests__/unit/frontmatter-sync.test.js +26 -0
  47. package/dist/__tests__/unit/frontmatter-sync.test.js.map +1 -0
  48. package/dist/__tests__/unit/mdx-validator.test.d.ts +2 -0
  49. package/dist/__tests__/unit/mdx-validator.test.d.ts.map +1 -0
  50. package/dist/__tests__/unit/mdx-validator.test.js +264 -0
  51. package/dist/__tests__/unit/mdx-validator.test.js.map +1 -0
  52. package/dist/__tests__/unit/migrate-convert.test.d.ts +2 -0
  53. package/dist/__tests__/unit/migrate-convert.test.d.ts.map +1 -0
  54. package/dist/__tests__/unit/migrate-convert.test.js +297 -0
  55. package/dist/__tests__/unit/migrate-convert.test.js.map +1 -0
  56. package/dist/__tests__/unit/migrate-detect.test.d.ts +2 -0
  57. package/dist/__tests__/unit/migrate-detect.test.d.ts.map +1 -0
  58. package/dist/__tests__/unit/migrate-detect.test.js +35 -0
  59. package/dist/__tests__/unit/migrate-detect.test.js.map +1 -0
  60. package/dist/__tests__/unit/migrate-mdx.test.d.ts +2 -0
  61. package/dist/__tests__/unit/migrate-mdx.test.d.ts.map +1 -0
  62. package/dist/__tests__/unit/migrate-mdx.test.js +158 -0
  63. package/dist/__tests__/unit/migrate-mdx.test.js.map +1 -0
  64. package/dist/__tests__/unit/openapi.test.d.ts +2 -0
  65. package/dist/__tests__/unit/openapi.test.d.ts.map +1 -0
  66. package/dist/__tests__/unit/openapi.test.js +52 -0
  67. package/dist/__tests__/unit/openapi.test.js.map +1 -0
  68. package/dist/__tests__/unit/package-config.test.d.ts +2 -0
  69. package/dist/__tests__/unit/package-config.test.d.ts.map +1 -0
  70. package/dist/__tests__/unit/package-config.test.js +63 -0
  71. package/dist/__tests__/unit/package-config.test.js.map +1 -0
  72. package/dist/__tests__/unit/port.test.d.ts +2 -0
  73. package/dist/__tests__/unit/port.test.d.ts.map +1 -0
  74. package/dist/__tests__/unit/port.test.js +20 -0
  75. package/dist/__tests__/unit/port.test.js.map +1 -0
  76. package/dist/__tests__/unit/vendored-sync.test.d.ts +14 -0
  77. package/dist/__tests__/unit/vendored-sync.test.d.ts.map +1 -0
  78. package/dist/__tests__/unit/vendored-sync.test.js +90 -0
  79. package/dist/__tests__/unit/vendored-sync.test.js.map +1 -0
  80. package/dist/commands/broken-links.d.ts +11 -0
  81. package/dist/commands/broken-links.d.ts.map +1 -0
  82. package/dist/commands/broken-links.js +95 -0
  83. package/dist/commands/broken-links.js.map +1 -0
  84. package/dist/commands/clean.d.ts +7 -0
  85. package/dist/commands/clean.d.ts.map +1 -0
  86. package/dist/commands/clean.js +59 -0
  87. package/dist/commands/clean.js.map +1 -0
  88. package/dist/commands/deploy/cloudflare.d.ts +12 -0
  89. package/dist/commands/deploy/cloudflare.d.ts.map +1 -0
  90. package/dist/commands/deploy/cloudflare.js +409 -0
  91. package/dist/commands/deploy/cloudflare.js.map +1 -0
  92. package/dist/commands/deploy/templates.d.ts +23 -0
  93. package/dist/commands/deploy/templates.d.ts.map +1 -0
  94. package/dist/commands/deploy/templates.js +179 -0
  95. package/dist/commands/deploy/templates.js.map +1 -0
  96. package/dist/commands/deploy/types.d.ts +19 -0
  97. package/dist/commands/deploy/types.d.ts.map +1 -0
  98. package/dist/commands/deploy/types.js +5 -0
  99. package/dist/commands/deploy/types.js.map +1 -0
  100. package/dist/commands/dev.d.ts +14 -0
  101. package/dist/commands/dev.d.ts.map +1 -0
  102. package/dist/commands/dev.js +817 -0
  103. package/dist/commands/dev.js.map +1 -0
  104. package/dist/commands/doctor.d.ts +7 -0
  105. package/dist/commands/doctor.d.ts.map +1 -0
  106. package/dist/commands/doctor.js +159 -0
  107. package/dist/commands/doctor.js.map +1 -0
  108. package/dist/commands/init.d.ts +7 -0
  109. package/dist/commands/init.d.ts.map +1 -0
  110. package/dist/commands/init.js +96 -0
  111. package/dist/commands/init.js.map +1 -0
  112. package/dist/commands/migrate/convert-mdx.d.ts +50 -0
  113. package/dist/commands/migrate/convert-mdx.d.ts.map +1 -0
  114. package/dist/commands/migrate/convert-mdx.js +108 -0
  115. package/dist/commands/migrate/convert-mdx.js.map +1 -0
  116. package/dist/commands/migrate/convert.d.ts +80 -0
  117. package/dist/commands/migrate/convert.d.ts.map +1 -0
  118. package/dist/commands/migrate/convert.js +158 -0
  119. package/dist/commands/migrate/convert.js.map +1 -0
  120. package/dist/commands/migrate/detect.d.ts +31 -0
  121. package/dist/commands/migrate/detect.d.ts.map +1 -0
  122. package/dist/commands/migrate/detect.js +62 -0
  123. package/dist/commands/migrate/detect.js.map +1 -0
  124. package/dist/commands/migrate/extract-hooks.d.ts +71 -0
  125. package/dist/commands/migrate/extract-hooks.d.ts.map +1 -0
  126. package/dist/commands/migrate/extract-hooks.js +473 -0
  127. package/dist/commands/migrate/extract-hooks.js.map +1 -0
  128. package/dist/commands/migrate/index.d.ts +17 -0
  129. package/dist/commands/migrate/index.d.ts.map +1 -0
  130. package/dist/commands/migrate/index.js +282 -0
  131. package/dist/commands/migrate/index.js.map +1 -0
  132. package/dist/commands/migrate/prompts.d.ts +22 -0
  133. package/dist/commands/migrate/prompts.d.ts.map +1 -0
  134. package/dist/commands/migrate/prompts.js +67 -0
  135. package/dist/commands/migrate/prompts.js.map +1 -0
  136. package/dist/commands/migrate/types.d.ts +22 -0
  137. package/dist/commands/migrate/types.d.ts.map +1 -0
  138. package/dist/commands/migrate/types.js +26 -0
  139. package/dist/commands/migrate/types.js.map +1 -0
  140. package/dist/commands/openapi-check.d.ts +11 -0
  141. package/dist/commands/openapi-check.d.ts.map +1 -0
  142. package/dist/commands/openapi-check.js +88 -0
  143. package/dist/commands/openapi-check.js.map +1 -0
  144. package/dist/commands/rename.d.ts +10 -0
  145. package/dist/commands/rename.d.ts.map +1 -0
  146. package/dist/commands/rename.js +125 -0
  147. package/dist/commands/rename.js.map +1 -0
  148. package/dist/commands/update.d.ts +10 -0
  149. package/dist/commands/update.d.ts.map +1 -0
  150. package/dist/commands/update.js +57 -0
  151. package/dist/commands/update.js.map +1 -0
  152. package/dist/commands/validate.d.ts +12 -0
  153. package/dist/commands/validate.d.ts.map +1 -0
  154. package/dist/commands/validate.js +163 -0
  155. package/dist/commands/validate.js.map +1 -0
  156. package/dist/index.d.ts +9 -0
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +334 -0
  159. package/dist/index.js.map +1 -0
  160. package/dist/lib/config.d.ts +7 -0
  161. package/dist/lib/config.d.ts.map +1 -0
  162. package/dist/lib/config.js +18 -0
  163. package/dist/lib/config.js.map +1 -0
  164. package/dist/lib/deprecated-components.d.ts +72 -0
  165. package/dist/lib/deprecated-components.d.ts.map +1 -0
  166. package/dist/lib/deprecated-components.js +138 -0
  167. package/dist/lib/deprecated-components.js.map +1 -0
  168. package/dist/lib/deps.d.ts +17 -0
  169. package/dist/lib/deps.d.ts.map +1 -0
  170. package/dist/lib/deps.js +186 -0
  171. package/dist/lib/deps.js.map +1 -0
  172. package/dist/lib/docs-config.d.ts +67 -0
  173. package/dist/lib/docs-config.d.ts.map +1 -0
  174. package/dist/lib/docs-config.js +294 -0
  175. package/dist/lib/docs-config.js.map +1 -0
  176. package/dist/lib/errors.d.ts +23 -0
  177. package/dist/lib/errors.d.ts.map +1 -0
  178. package/dist/lib/errors.js +32 -0
  179. package/dist/lib/errors.js.map +1 -0
  180. package/dist/lib/frontmatter-utils.d.ts +25 -0
  181. package/dist/lib/frontmatter-utils.d.ts.map +1 -0
  182. package/dist/lib/frontmatter-utils.js +64 -0
  183. package/dist/lib/frontmatter-utils.js.map +1 -0
  184. package/dist/lib/mdx-validator.d.ts +27 -0
  185. package/dist/lib/mdx-validator.d.ts.map +1 -0
  186. package/dist/lib/mdx-validator.js +148 -0
  187. package/dist/lib/mdx-validator.js.map +1 -0
  188. package/dist/lib/navigation-validator.d.ts +31 -0
  189. package/dist/lib/navigation-validator.d.ts.map +1 -0
  190. package/dist/lib/navigation-validator.js +75 -0
  191. package/dist/lib/navigation-validator.js.map +1 -0
  192. package/dist/lib/normalize-config.d.ts +57 -0
  193. package/dist/lib/normalize-config.d.ts.map +1 -0
  194. package/dist/lib/normalize-config.js +63 -0
  195. package/dist/lib/normalize-config.js.map +1 -0
  196. package/dist/lib/openapi/cache.d.ts +40 -0
  197. package/dist/lib/openapi/cache.d.ts.map +1 -0
  198. package/dist/lib/openapi/cache.js +76 -0
  199. package/dist/lib/openapi/cache.js.map +1 -0
  200. package/dist/lib/openapi/errors.d.ts +36 -0
  201. package/dist/lib/openapi/errors.d.ts.map +1 -0
  202. package/dist/lib/openapi/errors.js +162 -0
  203. package/dist/lib/openapi/errors.js.map +1 -0
  204. package/dist/lib/openapi/index.d.ts +10 -0
  205. package/dist/lib/openapi/index.d.ts.map +1 -0
  206. package/dist/lib/openapi/index.js +12 -0
  207. package/dist/lib/openapi/index.js.map +1 -0
  208. package/dist/lib/openapi/types.d.ts +198 -0
  209. package/dist/lib/openapi/types.d.ts.map +1 -0
  210. package/dist/lib/openapi/types.js +8 -0
  211. package/dist/lib/openapi/types.js.map +1 -0
  212. package/dist/lib/openapi/validator.d.ts +45 -0
  213. package/dist/lib/openapi/validator.d.ts.map +1 -0
  214. package/dist/lib/openapi/validator.js +128 -0
  215. package/dist/lib/openapi/validator.js.map +1 -0
  216. package/dist/lib/openapi.d.ts +7 -0
  217. package/dist/lib/openapi.d.ts.map +1 -0
  218. package/dist/lib/openapi.js +7 -0
  219. package/dist/lib/openapi.js.map +1 -0
  220. package/dist/lib/output.d.ts +14 -0
  221. package/dist/lib/output.d.ts.map +1 -0
  222. package/dist/lib/output.js +19 -0
  223. package/dist/lib/output.js.map +1 -0
  224. package/dist/lib/path-security.d.ts +23 -0
  225. package/dist/lib/path-security.d.ts.map +1 -0
  226. package/dist/lib/path-security.js +35 -0
  227. package/dist/lib/path-security.js.map +1 -0
  228. package/dist/lib/port.d.ts +18 -0
  229. package/dist/lib/port.d.ts.map +1 -0
  230. package/dist/lib/port.js +65 -0
  231. package/dist/lib/port.js.map +1 -0
  232. package/dist/lib/spinner.d.ts +4 -0
  233. package/dist/lib/spinner.d.ts.map +1 -0
  234. package/dist/lib/spinner.js +16 -0
  235. package/dist/lib/spinner.js.map +1 -0
  236. package/dist/lib/version.d.ts +2 -0
  237. package/dist/lib/version.d.ts.map +1 -0
  238. package/dist/lib/version.js +49 -0
  239. package/dist/lib/version.js.map +1 -0
  240. package/dist/utils/update-checker.d.ts +34 -0
  241. package/dist/utils/update-checker.d.ts.map +1 -0
  242. package/dist/utils/update-checker.js +142 -0
  243. package/dist/utils/update-checker.js.map +1 -0
  244. package/package.json +125 -0
  245. package/templates/docs.json +11 -0
  246. package/templates/introduction.mdx +19 -0
  247. package/templates/quickstart.mdx +20 -0
  248. package/vendored/app/[[...slug]]/error.tsx +103 -0
  249. package/vendored/app/[[...slug]]/page.tsx +690 -0
  250. package/vendored/app/api/assets/[...path]/route.ts +78 -0
  251. package/vendored/app/api/ev/route.ts +61 -0
  252. package/vendored/app/api/isr-health/route.ts +66 -0
  253. package/vendored/app/api/mcp/[project]/route.ts +435 -0
  254. package/vendored/app/api/og/route.tsx +167 -0
  255. package/vendored/app/api/r2/[project]/[...path]/route.ts +214 -0
  256. package/vendored/app/api/revalidate/route.ts +76 -0
  257. package/vendored/app/globals.css +37 -0
  258. package/vendored/app/layout.tsx +571 -0
  259. package/vendored/app/not-found.tsx +47 -0
  260. package/vendored/components/CodeBlockCopyButton.tsx +146 -0
  261. package/vendored/components/HeaderLinkCopy.tsx +135 -0
  262. package/vendored/components/errors/NotFoundContent.tsx +147 -0
  263. package/vendored/components/layout/LayoutWrapper.tsx +128 -0
  264. package/vendored/components/mdx/Accordion.tsx +91 -0
  265. package/vendored/components/mdx/ApiCodePanel.tsx +51 -0
  266. package/vendored/components/mdx/ApiEndpoint.tsx +104 -0
  267. package/vendored/components/mdx/ApiPage.tsx +379 -0
  268. package/vendored/components/mdx/Badge.tsx +169 -0
  269. package/vendored/components/mdx/Callouts.tsx +140 -0
  270. package/vendored/components/mdx/Card.tsx +214 -0
  271. package/vendored/components/mdx/CodeGroup.tsx +136 -0
  272. package/vendored/components/mdx/Color.tsx +244 -0
  273. package/vendored/components/mdx/Columns.tsx +37 -0
  274. package/vendored/components/mdx/Expandable.tsx +37 -0
  275. package/vendored/components/mdx/Frame.tsx +51 -0
  276. package/vendored/components/mdx/Icon.tsx +132 -0
  277. package/vendored/components/mdx/Latex.tsx +75 -0
  278. package/vendored/components/mdx/MDXComponents.tsx +414 -0
  279. package/vendored/components/mdx/Mermaid.tsx +35 -0
  280. package/vendored/components/mdx/MermaidInner.tsx +342 -0
  281. package/vendored/components/mdx/OpenApiEndpoint.tsx +971 -0
  282. package/vendored/components/mdx/Panel.tsx +26 -0
  283. package/vendored/components/mdx/PanelWrapper.tsx +100 -0
  284. package/vendored/components/mdx/ParamField.tsx +75 -0
  285. package/vendored/components/mdx/RequestExample.tsx +91 -0
  286. package/vendored/components/mdx/ResponseExample.tsx +145 -0
  287. package/vendored/components/mdx/ResponseField.tsx +109 -0
  288. package/vendored/components/mdx/Steps.tsx +173 -0
  289. package/vendored/components/mdx/Table.tsx +352 -0
  290. package/vendored/components/mdx/Tabs.tsx +147 -0
  291. package/vendored/components/mdx/Tile.tsx +127 -0
  292. package/vendored/components/mdx/Tooltip.tsx +111 -0
  293. package/vendored/components/mdx/Tree.tsx +484 -0
  294. package/vendored/components/mdx/Update.tsx +90 -0
  295. package/vendored/components/mdx/View.tsx +354 -0
  296. package/vendored/components/mdx/YouTube.tsx +35 -0
  297. package/vendored/components/mdx/ZoomableImage.tsx +83 -0
  298. package/vendored/components/navigation/Breadcrumb.tsx +241 -0
  299. package/vendored/components/navigation/DefaultLogo.tsx +81 -0
  300. package/vendored/components/navigation/Header.tsx +512 -0
  301. package/vendored/components/navigation/LanguageSelector.tsx +249 -0
  302. package/vendored/components/navigation/PageNavigation.tsx +174 -0
  303. package/vendored/components/navigation/Sidebar.tsx +713 -0
  304. package/vendored/components/navigation/SocialFooter.tsx +186 -0
  305. package/vendored/components/navigation/TableOfContents.tsx +435 -0
  306. package/vendored/components/navigation/TabsNav.tsx +182 -0
  307. package/vendored/components/search/LazySearchModal.tsx +19 -0
  308. package/vendored/components/search/SearchModal.tsx +573 -0
  309. package/vendored/components/snippets/ProjectSnippets.tsx +4 -0
  310. package/vendored/components/theme/ThemeProvider.tsx +31 -0
  311. package/vendored/components/theme/ThemeToggle.tsx +134 -0
  312. package/vendored/components/ui/CodePanel.tsx +517 -0
  313. package/vendored/components/ui/CodePanelModal.tsx +342 -0
  314. package/vendored/contexts/TabSyncContext.tsx +30 -0
  315. package/vendored/hooks/useFocusTrap.ts +42 -0
  316. package/vendored/hooks/useHashNavigation.ts +39 -0
  317. package/vendored/hooks/useShikiHighlight.ts +101 -0
  318. package/vendored/lib/analytics-client.ts +77 -0
  319. package/vendored/lib/build/cache.ts +138 -0
  320. package/vendored/lib/build/error-parser.ts +690 -0
  321. package/vendored/lib/build/estimation.ts +113 -0
  322. package/vendored/lib/build/index.ts +17 -0
  323. package/vendored/lib/build/page-file-map.ts +48 -0
  324. package/vendored/lib/build/r2-upload.ts +179 -0
  325. package/vendored/lib/cache-keys.ts +117 -0
  326. package/vendored/lib/code-utils.ts +42 -0
  327. package/vendored/lib/content-loader.ts +176 -0
  328. package/vendored/lib/deprecated-components.ts +185 -0
  329. package/vendored/lib/docs-isr.ts +180 -0
  330. package/vendored/lib/docs-types.ts +874 -0
  331. package/vendored/lib/docs.ts +203 -0
  332. package/vendored/lib/domain-helpers.ts +107 -0
  333. package/vendored/lib/email-notifier.ts +102 -0
  334. package/vendored/lib/email-templates/build-failure.tsx +193 -0
  335. package/vendored/lib/email-templates/components/base-layout.tsx +150 -0
  336. package/vendored/lib/email-templates/components/error-box.tsx +88 -0
  337. package/vendored/lib/email-templates/components/info-row.tsx +63 -0
  338. package/vendored/lib/email-templates/index.ts +13 -0
  339. package/vendored/lib/empty-polyfill.js +3 -0
  340. package/vendored/lib/extract-highlights.ts +124 -0
  341. package/vendored/lib/fonts.ts +227 -0
  342. package/vendored/lib/frontmatter-utils.ts +77 -0
  343. package/vendored/lib/fs-utils.ts +20 -0
  344. package/vendored/lib/git-utils.ts +87 -0
  345. package/vendored/lib/health-checks.ts +224 -0
  346. package/vendored/lib/icon-utils.ts +492 -0
  347. package/vendored/lib/infer-page-type.ts +14 -0
  348. package/vendored/lib/isr-build-executor.ts +185 -0
  349. package/vendored/lib/language-icons.ts +152 -0
  350. package/vendored/lib/language-utils.ts +338 -0
  351. package/vendored/lib/latex-config.ts +64 -0
  352. package/vendored/lib/link-prefix-context.tsx +32 -0
  353. package/vendored/lib/logger.ts +63 -0
  354. package/vendored/lib/mcp-search.ts +255 -0
  355. package/vendored/lib/mdx-inline-components.ts +155 -0
  356. package/vendored/lib/mdx.ts +100 -0
  357. package/vendored/lib/middleware-helpers.ts +519 -0
  358. package/vendored/lib/navigation-resolver.ts +621 -0
  359. package/vendored/lib/navigation-utils.ts +103 -0
  360. package/vendored/lib/normalize-config.ts +94 -0
  361. package/vendored/lib/openapi/cache.ts +92 -0
  362. package/vendored/lib/openapi/code-examples.ts +389 -0
  363. package/vendored/lib/openapi/errors.ts +253 -0
  364. package/vendored/lib/openapi/generator.ts +230 -0
  365. package/vendored/lib/openapi/index.ts +84 -0
  366. package/vendored/lib/openapi/parser.ts +474 -0
  367. package/vendored/lib/openapi/types.ts +232 -0
  368. package/vendored/lib/openapi/validator.ts +156 -0
  369. package/vendored/lib/openapi-isr.ts +121 -0
  370. package/vendored/lib/page-isr-helpers.ts +137 -0
  371. package/vendored/lib/path-safety.ts +130 -0
  372. package/vendored/lib/paths.ts +35 -0
  373. package/vendored/lib/preprocess-mdx.ts +951 -0
  374. package/vendored/lib/process-mdx-with-exports.ts +75 -0
  375. package/vendored/lib/project-resolver.ts +165 -0
  376. package/vendored/lib/r2-content.ts +60 -0
  377. package/vendored/lib/r2-manifest.ts +84 -0
  378. package/vendored/lib/recent-searches.ts +41 -0
  379. package/vendored/lib/recma-compound-components.ts +84 -0
  380. package/vendored/lib/redirect-compiler.ts +160 -0
  381. package/vendored/lib/redirect-matcher.ts +296 -0
  382. package/vendored/lib/redis.ts +23 -0
  383. package/vendored/lib/rehype-class-to-classname.ts +31 -0
  384. package/vendored/lib/rehype-code-meta.ts +275 -0
  385. package/vendored/lib/rehype-nozoom-to-data.ts +45 -0
  386. package/vendored/lib/remark-extract-exports.ts +104 -0
  387. package/vendored/lib/resilience.ts +260 -0
  388. package/vendored/lib/revalidation-helpers.ts +200 -0
  389. package/vendored/lib/revalidation-trigger.ts +150 -0
  390. package/vendored/lib/screenshot-capture.ts +229 -0
  391. package/vendored/lib/search-client.ts +91 -0
  392. package/vendored/lib/search-suggestions.ts +38 -0
  393. package/vendored/lib/search.ts +158 -0
  394. package/vendored/lib/seo.ts +264 -0
  395. package/vendored/lib/shiki-client.ts +131 -0
  396. package/vendored/lib/shiki-config.ts +289 -0
  397. package/vendored/lib/shiki-css-theme.ts +46 -0
  398. package/vendored/lib/shiki-highlighter.ts +62 -0
  399. package/vendored/lib/shiki-transformers.ts +337 -0
  400. package/vendored/lib/slack-notifier.ts +248 -0
  401. package/vendored/lib/snippet-compiler-isr.ts +114 -0
  402. package/vendored/lib/snippet-loader-isr.ts +276 -0
  403. package/vendored/lib/static-artifacts.ts +375 -0
  404. package/vendored/lib/static-file-route.ts +72 -0
  405. package/vendored/lib/tracking-script.ts +19 -0
  406. package/vendored/lib/typography-config.ts +42 -0
  407. package/vendored/lib/validate-config.ts +268 -0
  408. package/vendored/next.config.js +45 -0
  409. package/vendored/postcss.config.js +6 -0
  410. package/vendored/schema/README.md +28 -0
  411. package/vendored/schema/docs-schema.json +4631 -0
  412. package/vendored/scripts/build-project.cjs +174 -0
  413. package/vendored/scripts/build-search-index.cjs +347 -0
  414. package/vendored/scripts/compile-snippets.cjs +488 -0
  415. package/vendored/scripts/copy-files.cjs +295 -0
  416. package/vendored/scripts/dev-project.cjs +534 -0
  417. package/vendored/scripts/enhance-navigation.cjs +354 -0
  418. package/vendored/scripts/validate-links.cjs +423 -0
  419. package/vendored/shared/constants.ts +6 -0
  420. package/vendored/shared/index.ts +19 -0
  421. package/vendored/shared/logger.ts +62 -0
  422. package/vendored/shared/memory-monitor.ts +190 -0
  423. package/vendored/shared/navigation-validator.ts +101 -0
  424. package/vendored/shared/path-security.ts +39 -0
  425. package/vendored/shared/status-reporter.ts +199 -0
  426. package/vendored/shared/timer.ts +51 -0
  427. package/vendored/shared/types.ts +102 -0
  428. package/vendored/tailwind.config.ts +39 -0
  429. package/vendored/themes/base.css +1311 -0
  430. package/vendored/themes/index.ts +119 -0
  431. package/vendored/themes/jam/variables.css +835 -0
  432. package/vendored/themes/nebula/variables.css +282 -0
  433. package/vendored/themes/pulsar/variables.css +1009 -0
  434. package/vendored/themes/types.ts +89 -0
  435. package/vendored/tsconfig.json +48 -0
@@ -0,0 +1,244 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext, type ReactNode } from 'react';
4
+
5
+ type ColorValue = string | { light: string; dark: string };
6
+
7
+ interface ColorItemProps {
8
+ name?: string;
9
+ value: ColorValue;
10
+ }
11
+
12
+ interface ColorRowProps {
13
+ title?: string;
14
+ children: ReactNode;
15
+ }
16
+
17
+ interface ColorProps {
18
+ variant?: 'compact' | 'table';
19
+ children: ReactNode;
20
+ }
21
+
22
+ // Context to pass variant down to children
23
+ const ColorContext = createContext<{ variant: 'compact' | 'table' }>({ variant: 'compact' });
24
+
25
+ /**
26
+ * Parse a color string and return RGB values
27
+ * Supports: hex (#RGB, #RRGGBB, #RRGGBBAA), rgb(), rgba()
28
+ */
29
+ function parseColor(color: string): { r: number; g: number; b: number } | null {
30
+ const trimmed = color.trim().toLowerCase();
31
+
32
+ // Handle hex colors
33
+ if (trimmed.startsWith('#')) {
34
+ const hex = trimmed.slice(1);
35
+ let r: number, g: number, b: number;
36
+
37
+ if (hex.length === 3 || hex.length === 4) {
38
+ // #RGB or #RGBA
39
+ r = parseInt(hex[0] + hex[0], 16);
40
+ g = parseInt(hex[1] + hex[1], 16);
41
+ b = parseInt(hex[2] + hex[2], 16);
42
+ } else if (hex.length === 6 || hex.length === 8) {
43
+ // #RRGGBB or #RRGGBBAA
44
+ r = parseInt(hex.slice(0, 2), 16);
45
+ g = parseInt(hex.slice(2, 4), 16);
46
+ b = parseInt(hex.slice(4, 6), 16);
47
+ } else {
48
+ return null;
49
+ }
50
+
51
+ if (isNaN(r) || isNaN(g) || isNaN(b)) return null;
52
+ return { r, g, b };
53
+ }
54
+
55
+ // Handle rgb() and rgba()
56
+ const rgbMatch = trimmed.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
57
+ if (rgbMatch) {
58
+ return {
59
+ r: parseInt(rgbMatch[1], 10),
60
+ g: parseInt(rgbMatch[2], 10),
61
+ b: parseInt(rgbMatch[3], 10),
62
+ };
63
+ }
64
+
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * Calculate relative luminance and determine if text should be light or dark
70
+ * Uses WCAG formula for contrast
71
+ */
72
+ function shouldUseLightText(color: string): boolean {
73
+ const rgb = parseColor(color);
74
+ if (!rgb) return false;
75
+
76
+ // Calculate relative luminance using WCAG formula
77
+ const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {
78
+ const normalized = c / 255;
79
+ return normalized <= 0.03928
80
+ ? normalized / 12.92
81
+ : Math.pow((normalized + 0.055) / 1.055, 2.4);
82
+ });
83
+
84
+ const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
85
+ return luminance < 0.5;
86
+ }
87
+
88
+ /**
89
+ * Get display value for a color (for showing in the UI)
90
+ */
91
+ function getDisplayValue(value: ColorValue): string {
92
+ if (typeof value === 'string') {
93
+ return value;
94
+ }
95
+ return value.light;
96
+ }
97
+
98
+ /**
99
+ * ColorItem - Individual color swatch
100
+ */
101
+ export function ColorItem({ name, value }: ColorItemProps) {
102
+ const { variant } = useContext(ColorContext);
103
+ const isThemeAware = typeof value === 'object';
104
+ const displayValue = getDisplayValue(value);
105
+
106
+ // CSS variables for theme-aware colors
107
+ const cssVars = isThemeAware
108
+ ? ({
109
+ '--color-swatch-light': value.light,
110
+ '--color-swatch-dark': value.dark,
111
+ } as React.CSSProperties)
112
+ : {};
113
+
114
+ const swatchColor = isThemeAware ? 'var(--color-swatch-light)' : value;
115
+ const lightTextOnLight = isThemeAware ? shouldUseLightText(value.light) : shouldUseLightText(value as string);
116
+ const lightTextOnDark = isThemeAware ? shouldUseLightText(value.dark) : lightTextOnLight;
117
+
118
+ if (variant === 'table') {
119
+ return (
120
+ <div
121
+ className="color-item-table flex items-center gap-3 py-2 px-3 border-b border-[var(--color-border)] last:border-b-0 cursor-pointer"
122
+ style={cssVars}
123
+ data-copy-text={displayValue}
124
+ title="Click to copy"
125
+ >
126
+ {/* Color swatch */}
127
+ <div
128
+ className="color-swatch w-8 h-8 rounded-md border border-black/10 flex-shrink-0"
129
+ style={{ backgroundColor: swatchColor }}
130
+ />
131
+ {/* Name */}
132
+ <span className="color-name flex-1 text-sm font-medium text-[var(--color-text-primary)]">
133
+ {name}
134
+ </span>
135
+ {/* Value */}
136
+ <code className="color-value text-xs font-mono text-[var(--color-text-secondary)]">
137
+ {displayValue}
138
+ </code>
139
+ {/* Copy icon */}
140
+ <i className="fa-regular fa-copy text-xs text-[var(--color-text-muted)]" aria-hidden="true" />
141
+ </div>
142
+ );
143
+ }
144
+
145
+ // Compact variant
146
+ return (
147
+ <div
148
+ className="color-item-compact flex flex-col rounded-lg overflow-hidden border border-[var(--color-border)] cursor-pointer"
149
+ style={cssVars}
150
+ data-copy-text={displayValue}
151
+ title="Click to copy"
152
+ >
153
+ {/* Color swatch area */}
154
+ <div
155
+ className="color-swatch h-20 flex items-end justify-start p-2"
156
+ style={{ backgroundColor: swatchColor }}
157
+ >
158
+ {isThemeAware && (
159
+ <span
160
+ className="color-theme-indicator text-xs px-1.5 py-0.5 rounded bg-black/20"
161
+ style={{
162
+ color: lightTextOnLight ? '#fff' : '#000',
163
+ }}
164
+ >
165
+ Theme
166
+ </span>
167
+ )}
168
+ </div>
169
+ {/* Info area */}
170
+ <div className="color-info p-3 bg-[var(--color-bg-primary)]">
171
+ {name && (
172
+ <div className="color-name text-sm font-medium text-[var(--color-text-primary)] mb-1">
173
+ {name}
174
+ </div>
175
+ )}
176
+ <code className="color-value text-xs font-mono text-[var(--color-text-secondary)]">
177
+ {displayValue}
178
+ </code>
179
+ </div>
180
+ </div>
181
+ );
182
+ }
183
+
184
+ /**
185
+ * ColorRow - Group of colors with a title (for table variant)
186
+ */
187
+ export function ColorRow({ title, children }: ColorRowProps) {
188
+ return (
189
+ <div className="color-row mb-4 last:mb-0">
190
+ {title && (
191
+ <div className="color-row-title text-sm font-semibold text-[var(--color-text-primary)] mb-2 px-3">
192
+ {title}
193
+ </div>
194
+ )}
195
+ <div className="color-row-items rounded-lg border border-[var(--color-border)] overflow-hidden">
196
+ {children}
197
+ </div>
198
+ </div>
199
+ );
200
+ }
201
+
202
+ /**
203
+ * Color - Container component for displaying color palettes
204
+ *
205
+ * @example Compact variant (grid layout)
206
+ * <Color variant="compact">
207
+ * <Color.Item name="Primary" value="#3b82f6" />
208
+ * <Color.Item name="Secondary" value="#6366f1" />
209
+ * </Color>
210
+ *
211
+ * @example Table variant (grouped rows)
212
+ * <Color variant="table">
213
+ * <Color.Row title="Primary Colors">
214
+ * <Color.Item name="Blue" value="#3b82f6" />
215
+ * </Color.Row>
216
+ * </Color>
217
+ *
218
+ * @example Theme-aware colors
219
+ * <Color.Item name="Background" value={{ light: "#ffffff", dark: "#000000" }} />
220
+ */
221
+ export function Color({ variant = 'compact', children }: ColorProps) {
222
+ const isCompact = variant === 'compact';
223
+
224
+ return (
225
+ <ColorContext.Provider value={{ variant }}>
226
+ <div
227
+ className={`color-palette my-6 not-prose ${
228
+ isCompact ? 'grid gap-4' : ''
229
+ }`}
230
+ style={
231
+ isCompact
232
+ ? { gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))' }
233
+ : undefined
234
+ }
235
+ >
236
+ {children}
237
+ </div>
238
+ </ColorContext.Provider>
239
+ );
240
+ }
241
+
242
+ // Attach sub-components
243
+ Color.Item = ColorItem;
244
+ Color.Row = ColorRow;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+
3
+ interface ColumnsProps {
4
+ children: React.ReactNode;
5
+ /** The number of columns per row. Accepts values from 1 to 4. Default: 2 */
6
+ cols?: number;
7
+ className?: string;
8
+ }
9
+
10
+ /**
11
+ * Columns component for displaying multiple Card components together in a responsive grid.
12
+ * The grid automatically adapts to smaller screens.
13
+ *
14
+ * @example
15
+ * <Columns cols={2}>
16
+ * <Card title="Get started">Set up your project</Card>
17
+ * <Card title="API reference">Explore endpoints</Card>
18
+ * </Columns>
19
+ */
20
+ // Responsive grid classes: mobile (1 col), tablet (2 cols max), desktop (full count)
21
+ const GRID_CLASSES: Record<number, string> = {
22
+ 1: 'grid-cols-1',
23
+ 2: 'grid-cols-1 md:grid-cols-2',
24
+ 3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
25
+ 4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
26
+ };
27
+
28
+ export function Columns({ children, cols = 2, className = '' }: ColumnsProps) {
29
+ const gridCols = Math.min(Math.max(cols, 1), 4);
30
+ const responsiveClass = GRID_CLASSES[gridCols];
31
+
32
+ return (
33
+ <div className={`grid gap-4 my-4 not-prose [&>*]:my-0 [&>div]:my-0 [&>a]:my-0 ${responsiveClass} ${className}`.trim()}>
34
+ {children}
35
+ </div>
36
+ );
37
+ }
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+
5
+ interface ExpandableProps {
6
+ title: string;
7
+ children: React.ReactNode;
8
+ defaultOpen?: boolean;
9
+ }
10
+
11
+ /**
12
+ * Expandable component - a collapsible section.
13
+ * Component for expandable content.
14
+ */
15
+ export function Expandable({ title, children, defaultOpen = false }: ExpandableProps) {
16
+ const [isOpen, setIsOpen] = useState(defaultOpen);
17
+
18
+ return (
19
+ <div className="border border-[var(--color-border)] rounded-lg my-4 overflow-hidden not-prose">
20
+ <button
21
+ className="w-full px-4 py-3 flex items-center gap-2 text-left bg-theme-bg-secondary hover:bg-theme-bg-tertiary transition-colors"
22
+ onClick={() => setIsOpen(!isOpen)}
23
+ >
24
+ <span className="font-medium text-theme-text-primary capitalize">{title}</span>
25
+ <i
26
+ className={`fa-solid fa-chevron-right text-[10px] text-[var(--color-text-muted)] transition-transform ${isOpen ? 'rotate-90' : ''}`}
27
+ aria-hidden="true"
28
+ />
29
+ </button>
30
+ {isOpen && (
31
+ <div className="px-4 py-3 border-t border-[var(--color-border)] text-sm leading-relaxed [&>p]:m-0 [&>p]:mb-3 [&>p:last-child]:mb-0 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&>ul]:my-2 [&>ul]:ml-4 [&>ul]:list-disc [&>ol]:my-2 [&>ol]:ml-4 [&>ol]:list-decimal [&>li]:mb-1 [&>strong]:font-semibold [&>a]:text-[var(--color-accent)] [&>a]:underline">
32
+ {children}
33
+ </div>
34
+ )}
35
+ </div>
36
+ );
37
+ }
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+
5
+ interface FrameProps {
6
+ children: React.ReactNode;
7
+ caption?: string;
8
+ }
9
+
10
+ /**
11
+ * Frame component - wraps content in a styled frame.
12
+ * Component for framed content/images.
13
+ */
14
+ export function Frame({ children, caption }: FrameProps) {
15
+ const [isDark, setIsDark] = useState(false);
16
+
17
+ useEffect(() => {
18
+ // Check initial theme
19
+ setIsDark(document.documentElement.classList.contains('dark'));
20
+
21
+ // Watch for theme changes
22
+ const observer = new MutationObserver(() => {
23
+ setIsDark(document.documentElement.classList.contains('dark'));
24
+ });
25
+
26
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
27
+
28
+ return () => observer.disconnect();
29
+ }, []);
30
+
31
+ return (
32
+ <figure className="my-6">
33
+ <div
34
+ className="frame-content rounded-lg overflow-x-auto p-2 [&_img]:!my-0 [&_img]:!rounded-md [&_p]:!my-0"
35
+ style={{
36
+ backgroundColor: isDark ? '#0f1419' : '#f8f9fa',
37
+ boxShadow: isDark
38
+ ? 'inset 0 0 0 0.5px rgba(107, 114, 128, 0.3)'
39
+ : 'inset 0 0 0 0.5px rgba(209, 213, 219, 0.8)'
40
+ }}
41
+ >
42
+ {children}
43
+ </div>
44
+ {caption && (
45
+ <figcaption className="mt-2 text-sm text-center text-theme-text-tertiary">
46
+ {caption}
47
+ </figcaption>
48
+ )}
49
+ </figure>
50
+ );
51
+ }
@@ -0,0 +1,132 @@
1
+ import { getIconClass } from '@/lib/icon-utils';
2
+
3
+ interface IconProps {
4
+ /**
5
+ * The icon to display. Options:
6
+ * - Font Awesome icon name (e.g., "flag", "circle-xmark")
7
+ * - URL to external icon (e.g., "https://example.com/icon.svg")
8
+ * - Path to icon file (e.g., "/images/icon.svg")
9
+ */
10
+ icon: string | React.ReactElement;
11
+ /** Font Awesome icon style */
12
+ iconType?: 'regular' | 'solid' | 'light' | 'thin' | 'sharp-solid' | 'duotone' | 'brands';
13
+ /** Color as hex code (#FF5733) or named color (red, blue, etc.) */
14
+ color?: string;
15
+ /** Size in pixels (default: 16) */
16
+ size?: number;
17
+ /** Custom CSS class */
18
+ className?: string;
19
+ }
20
+
21
+ /**
22
+ * Get color style from color prop
23
+ */
24
+ function getColorStyle(color?: string): { style?: React.CSSProperties; className?: string } {
25
+ if (!color) return {};
26
+
27
+ // Hex code - use inline style
28
+ if (color.startsWith('#')) {
29
+ return { style: { color } };
30
+ }
31
+
32
+ // Named colors - map to Tailwind classes
33
+ const colorMap: Record<string, string> = {
34
+ 'red': 'text-red-500',
35
+ 'blue': 'text-blue-500',
36
+ 'green': 'text-green-500',
37
+ 'yellow': 'text-yellow-500',
38
+ 'orange': 'text-orange-500',
39
+ 'purple': 'text-purple-500',
40
+ 'pink': 'text-pink-500',
41
+ 'gray': 'text-gray-400',
42
+ 'grey': 'text-gray-400',
43
+ 'white': 'text-white',
44
+ 'black': 'text-black',
45
+ 'primary': 'text-theme-accent',
46
+ };
47
+
48
+ if (colorMap[color.toLowerCase()]) {
49
+ return { className: colorMap[color.toLowerCase()] };
50
+ }
51
+
52
+ // Try as direct color value
53
+ return { style: { color } };
54
+ }
55
+
56
+ /**
57
+ * Icon component for rendering icons in MDX content.
58
+ * Supports Font Awesome icons via CSS, SVG elements, URLs, and file paths.
59
+ *
60
+ * @example
61
+ * // Font Awesome icon by name
62
+ * <Icon icon="flag" size={32} />
63
+ *
64
+ * // Font Awesome with style
65
+ * <Icon icon="circle-xmark" iconType="solid" color="red" />
66
+ *
67
+ * // Hex color
68
+ * <Icon icon="repeat" color="#FF5733" />
69
+ *
70
+ * // External URL
71
+ * <Icon icon="https://example.com/icon.svg" size={24} />
72
+ *
73
+ * // Local file path
74
+ * <Icon icon="/images/custom-icon.svg" size={24} />
75
+ *
76
+ * // Inline SVG (JSX)
77
+ * <Icon icon={<svg viewBox="0 0 24 24"><path d="..."/></svg>} />
78
+ *
79
+ */
80
+ export function Icon({ icon, iconType = 'solid', color, size = 16, className }: IconProps) {
81
+ const { style: colorStyle, className: colorClass } = getColorStyle(color);
82
+ const combinedClassName = `inline-block ${colorClass || ''} ${className || ''}`.trim();
83
+ const sizeStyle = { width: size, height: size };
84
+
85
+ // Case 1: JSX SVG element passed directly
86
+ if (typeof icon !== 'string') {
87
+ // It's a React element (SVG)
88
+ return (
89
+ <span
90
+ className={combinedClassName}
91
+ style={{ ...sizeStyle, ...colorStyle, display: 'inline-flex', alignItems: 'center' }}
92
+ >
93
+ {icon}
94
+ </span>
95
+ );
96
+ }
97
+
98
+ // Case 2: URL to external icon
99
+ if (icon.startsWith('http://') || icon.startsWith('https://')) {
100
+ return (
101
+ <img
102
+ src={icon}
103
+ alt=""
104
+ className={combinedClassName}
105
+ style={{ ...sizeStyle, ...colorStyle }}
106
+ />
107
+ );
108
+ }
109
+
110
+ // Case 3: Local file path (starts with / or ./)
111
+ if (icon.startsWith('/') || icon.startsWith('./')) {
112
+ return (
113
+ <img
114
+ src={icon}
115
+ alt=""
116
+ className={combinedClassName}
117
+ style={{ ...sizeStyle, ...colorStyle }}
118
+ />
119
+ );
120
+ }
121
+
122
+ // Case 4: Font Awesome icon via CSS class
123
+ const faClass = getIconClass(icon);
124
+
125
+ return (
126
+ <i
127
+ className={`${faClass} ${combinedClassName}`}
128
+ style={{ ...sizeStyle, ...colorStyle }}
129
+ aria-hidden="true"
130
+ />
131
+ );
132
+ }
@@ -0,0 +1,75 @@
1
+ import katex from 'katex';
2
+ import type { ReactNode } from 'react';
3
+
4
+ interface LatexProps {
5
+ children: ReactNode;
6
+ block?: boolean;
7
+ }
8
+
9
+ /**
10
+ * Latex component for rendering mathematical equations using KaTeX.
11
+ *
12
+ * Supports two modes:
13
+ * - Inline (default): Renders within text flow
14
+ * - Block: Centered display mode for standalone equations
15
+ *
16
+ * Security: Uses dangerouslySetInnerHTML with KaTeX output. This is safe
17
+ * because KaTeX only processes LaTeX math syntax (not arbitrary HTML).
18
+ * KaTeX is designed to be XSS-safe and is widely used by documentation platforms.
19
+ *
20
+ * @example
21
+ * // Inline math
22
+ * <Latex>E = mc^2</Latex>
23
+ *
24
+ * // Block/display math
25
+ * <Latex block>
26
+ * \int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
27
+ * </Latex>
28
+ */
29
+ export function Latex({ children, block = false }: LatexProps) {
30
+ // Convert children to string - handles string, array, or other ReactNode types
31
+ const latex = extractLatexString(children);
32
+
33
+ try {
34
+ // KaTeX.renderToString is safe - it only parses LaTeX math syntax,
35
+ // not arbitrary HTML. Invalid LaTeX produces error messages, not XSS.
36
+ const html = katex.renderToString(latex, {
37
+ displayMode: block,
38
+ throwOnError: false, // Render error message instead of throwing
39
+ errorColor: '#cc0000',
40
+ trust: false, // Don't allow potentially dangerous commands like \url
41
+ strict: 'warn', // Log warnings for unsupported commands
42
+ });
43
+
44
+ return (
45
+ <span
46
+ className={block ? 'katex-display block my-4 text-center overflow-x-auto' : 'katex-inline'}
47
+ dangerouslySetInnerHTML={{ __html: html }}
48
+ />
49
+ );
50
+ } catch (error) {
51
+ // Fallback for truly unexpected errors
52
+ console.error('[Latex] Rendering error:', error);
53
+ return (
54
+ <span className="text-red-500 font-mono text-sm bg-red-50 dark:bg-red-950 px-1 rounded">
55
+ LaTeX Error: {latex.slice(0, 50)}{latex.length > 50 ? '...' : ''}
56
+ </span>
57
+ );
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Extract a string from ReactNode children.
63
+ * Handles strings, arrays, and stringifies other types.
64
+ */
65
+ function extractLatexString(children: ReactNode): string {
66
+ if (typeof children === 'string') {
67
+ return children;
68
+ }
69
+ if (Array.isArray(children)) {
70
+ return children.map(child =>
71
+ typeof child === 'string' ? child : String(child ?? '')
72
+ ).join('');
73
+ }
74
+ return String(children ?? '');
75
+ }