specra 0.1.13 → 0.2.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 (276) hide show
  1. package/LICENSE.MD +25 -4
  2. package/README.md +67 -58
  3. package/config/specra.config.schema.json +16 -0
  4. package/config/svelte-config.js +63 -0
  5. package/dist/api-parser.types.d.ts +59 -0
  6. package/dist/api-parser.types.js +5 -0
  7. package/dist/api.types.d.ts +137 -0
  8. package/dist/api.types.js +5 -0
  9. package/dist/category.d.ts +21 -0
  10. package/dist/category.js +48 -0
  11. package/dist/components/ConfigProvider.svelte +13 -0
  12. package/dist/components/ConfigProvider.svelte.d.ts +31 -0
  13. package/dist/components/docs/Accordion.svelte +18 -0
  14. package/dist/components/docs/Accordion.svelte.d.ts +10 -0
  15. package/dist/components/docs/AccordionItem.svelte +41 -0
  16. package/dist/components/docs/AccordionItem.svelte.d.ts +10 -0
  17. package/dist/components/docs/Badge.svelte +28 -0
  18. package/dist/components/docs/Badge.svelte.d.ts +9 -0
  19. package/dist/components/docs/Breadcrumb.svelte +80 -0
  20. package/dist/components/docs/Breadcrumb.svelte.d.ts +8 -0
  21. package/dist/components/docs/Callout.svelte +96 -0
  22. package/dist/components/docs/Callout.svelte.d.ts +10 -0
  23. package/dist/components/docs/Card.svelte +63 -0
  24. package/dist/components/docs/Card.svelte.d.ts +12 -0
  25. package/dist/components/docs/CardGrid.svelte +24 -0
  26. package/dist/components/docs/CardGrid.svelte.d.ts +8 -0
  27. package/dist/components/docs/CategoryIndex.svelte +110 -0
  28. package/dist/components/docs/CategoryIndex.svelte.d.ts +29 -0
  29. package/dist/components/docs/CodeBlock.svelte +172 -0
  30. package/dist/components/docs/CodeBlock.svelte.d.ts +8 -0
  31. package/dist/components/docs/Column.svelte +25 -0
  32. package/dist/components/docs/Column.svelte.d.ts +8 -0
  33. package/dist/components/docs/Columns.svelte +38 -0
  34. package/dist/components/docs/Columns.svelte.d.ts +13 -0
  35. package/dist/components/docs/DevModeBadge.svelte +15 -0
  36. package/dist/components/docs/DevModeBadge.svelte.d.ts +18 -0
  37. package/dist/components/docs/DocBadge.svelte +28 -0
  38. package/dist/components/docs/DocBadge.svelte.d.ts +9 -0
  39. package/dist/components/docs/DocLayout.svelte +107 -0
  40. package/dist/components/docs/DocLayout.svelte.d.ts +32 -0
  41. package/dist/components/docs/DocLoading.svelte +53 -0
  42. package/dist/components/docs/DocLoading.svelte.d.ts +18 -0
  43. package/dist/components/docs/DocMetadata.svelte +106 -0
  44. package/dist/components/docs/DocMetadata.svelte.d.ts +18 -0
  45. package/dist/components/docs/DocNavigation.svelte +56 -0
  46. package/dist/components/docs/DocNavigation.svelte.d.ts +12 -0
  47. package/dist/components/docs/DocTags.svelte +22 -0
  48. package/dist/components/docs/DocTags.svelte.d.ts +6 -0
  49. package/dist/components/docs/DraftBadge.svelte +10 -0
  50. package/dist/components/docs/DraftBadge.svelte.d.ts +18 -0
  51. package/dist/components/docs/Footer.svelte +72 -0
  52. package/dist/components/docs/Footer.svelte.d.ts +7 -0
  53. package/dist/components/docs/Frame.svelte +27 -0
  54. package/dist/components/docs/Frame.svelte.d.ts +9 -0
  55. package/dist/components/docs/Header.svelte +123 -0
  56. package/dist/components/docs/Header.svelte.d.ts +9 -0
  57. package/dist/components/docs/HeaderWithMenu.svelte +34 -0
  58. package/dist/components/docs/HeaderWithMenu.svelte.d.ts +17 -0
  59. package/dist/components/docs/HotReloadIndicator.svelte +44 -0
  60. package/dist/components/docs/HotReloadIndicator.svelte.d.ts +3 -0
  61. package/dist/components/docs/Icon.svelte +103 -0
  62. package/dist/components/docs/Icon.svelte.d.ts +11 -0
  63. package/dist/components/docs/Image.svelte +88 -0
  64. package/dist/components/docs/Image.svelte.d.ts +11 -0
  65. package/dist/components/docs/ImageCard.svelte +91 -0
  66. package/dist/components/docs/ImageCard.svelte.d.ts +12 -0
  67. package/dist/components/docs/ImageCardGrid.svelte +25 -0
  68. package/dist/components/docs/ImageCardGrid.svelte.d.ts +8 -0
  69. package/dist/components/docs/LayoutProviders.svelte +57 -0
  70. package/dist/components/docs/LayoutProviders.svelte.d.ts +9 -0
  71. package/dist/components/docs/Logo.svelte +25 -0
  72. package/dist/components/docs/Logo.svelte.d.ts +11 -0
  73. package/dist/components/docs/Math.svelte +54 -0
  74. package/dist/components/docs/Math.svelte.d.ts +7 -0
  75. package/dist/components/docs/MdxContent.svelte +41 -0
  76. package/dist/components/docs/MdxHotReload.svelte +78 -0
  77. package/dist/components/docs/MdxHotReload.svelte.d.ts +9 -0
  78. package/dist/components/docs/MdxLayout.svelte +16 -0
  79. package/dist/components/docs/MdxLayout.svelte.d.ts +6 -0
  80. package/dist/components/docs/Mermaid.svelte +88 -0
  81. package/dist/components/docs/Mermaid.svelte.d.ts +7 -0
  82. package/dist/components/docs/MobileDocLayout.svelte +211 -0
  83. package/dist/components/docs/MobileDocLayout.svelte.d.ts +35 -0
  84. package/dist/components/docs/MobileSidebar.svelte +122 -0
  85. package/dist/components/docs/MobileSidebar.svelte.d.ts +31 -0
  86. package/dist/components/docs/MobileSidebarWrapper.svelte +122 -0
  87. package/dist/components/docs/MobileSidebarWrapper.svelte.d.ts +32 -0
  88. package/dist/components/docs/NotFoundContent.svelte +40 -0
  89. package/dist/components/docs/NotFoundContent.svelte.d.ts +6 -0
  90. package/dist/components/docs/SearchHighlight.svelte +116 -0
  91. package/dist/components/docs/SearchHighlight.svelte.d.ts +3 -0
  92. package/dist/components/docs/SearchModal.svelte +239 -0
  93. package/dist/components/docs/SearchModal.svelte.d.ts +9 -0
  94. package/dist/components/docs/Sidebar.svelte +69 -0
  95. package/dist/components/docs/Sidebar.svelte.d.ts +31 -0
  96. package/dist/components/docs/SidebarMenuItems.svelte +344 -0
  97. package/dist/components/docs/SidebarMenuItems.svelte.d.ts +33 -0
  98. package/dist/components/docs/SidebarSkeleton.svelte +50 -0
  99. package/dist/components/docs/SidebarSkeleton.svelte.d.ts +18 -0
  100. package/dist/components/docs/SiteBanner.svelte +92 -0
  101. package/dist/components/docs/SiteBanner.svelte.d.ts +7 -0
  102. package/dist/components/docs/Step.svelte +44 -0
  103. package/dist/components/docs/Step.svelte.d.ts +8 -0
  104. package/dist/components/docs/Steps.svelte +15 -0
  105. package/dist/components/docs/Steps.svelte.d.ts +7 -0
  106. package/dist/components/docs/Tab.svelte +40 -0
  107. package/dist/components/docs/Tab.svelte.d.ts +8 -0
  108. package/dist/components/docs/TabGroups.svelte +183 -0
  109. package/dist/components/docs/TabGroups.svelte.d.ts +25 -0
  110. package/dist/components/docs/TableOfContents.svelte +100 -0
  111. package/dist/components/docs/TableOfContents.svelte.d.ts +9 -0
  112. package/dist/components/docs/Tabs.svelte +69 -0
  113. package/dist/components/docs/Tabs.svelte.d.ts +8 -0
  114. package/dist/components/docs/ThemeToggle.svelte +16 -0
  115. package/dist/components/docs/ThemeToggle.svelte.d.ts +18 -0
  116. package/dist/components/docs/Tooltip.svelte +44 -0
  117. package/dist/components/docs/Tooltip.svelte.d.ts +10 -0
  118. package/dist/components/docs/VersionSwitcher.svelte +95 -0
  119. package/dist/components/docs/VersionSwitcher.svelte.d.ts +7 -0
  120. package/dist/components/docs/Video.svelte +84 -0
  121. package/dist/components/docs/Video.svelte.d.ts +12 -0
  122. package/dist/components/docs/api/ApiEndpoint.svelte +61 -0
  123. package/dist/components/docs/api/ApiEndpoint.svelte.d.ts +11 -0
  124. package/dist/components/docs/api/ApiParams.svelte +80 -0
  125. package/dist/components/docs/api/ApiParams.svelte.d.ts +14 -0
  126. package/dist/components/docs/api/ApiPlayground.svelte +259 -0
  127. package/dist/components/docs/api/ApiPlayground.svelte.d.ts +16 -0
  128. package/dist/components/docs/api/ApiReference.svelte +278 -0
  129. package/dist/components/docs/api/ApiReference.svelte.d.ts +23 -0
  130. package/dist/components/docs/api/ApiResponse.svelte +66 -0
  131. package/dist/components/docs/api/ApiResponse.svelte.d.ts +9 -0
  132. package/dist/components/docs/api/index.d.ts +5 -0
  133. package/dist/components/docs/api/index.js +5 -0
  134. package/dist/components/docs/componentTextProps.d.ts +3 -0
  135. package/dist/components/docs/componentTextProps.js +61 -0
  136. package/dist/components/docs/index.d.ts +54 -0
  137. package/dist/components/docs/index.js +56 -0
  138. package/dist/components/global/VersionNotFound.svelte +48 -0
  139. package/dist/components/global/VersionNotFound.svelte.d.ts +7 -0
  140. package/dist/components/global/index.d.ts +1 -0
  141. package/dist/components/global/index.js +1 -0
  142. package/dist/components/index.d.ts +6 -822
  143. package/dist/components/index.js +11 -3854
  144. package/dist/components/ui/Badge.svelte +48 -0
  145. package/dist/components/ui/Badge.svelte.d.ts +15 -0
  146. package/dist/components/ui/Button.svelte +58 -0
  147. package/dist/components/ui/Button.svelte.d.ts +17 -0
  148. package/dist/components/ui/Dialog.svelte +16 -0
  149. package/dist/components/ui/Dialog.svelte.d.ts +9 -0
  150. package/dist/components/ui/DialogClose.svelte +16 -0
  151. package/dist/components/ui/DialogClose.svelte.d.ts +9 -0
  152. package/dist/components/ui/DialogContent.svelte +43 -0
  153. package/dist/components/ui/DialogContent.svelte.d.ts +10 -0
  154. package/dist/components/ui/DialogDescription.svelte +21 -0
  155. package/dist/components/ui/DialogDescription.svelte.d.ts +9 -0
  156. package/dist/components/ui/DialogFooter.svelte +20 -0
  157. package/dist/components/ui/DialogFooter.svelte.d.ts +9 -0
  158. package/dist/components/ui/DialogHeader.svelte +20 -0
  159. package/dist/components/ui/DialogHeader.svelte.d.ts +9 -0
  160. package/dist/components/ui/DialogTitle.svelte +21 -0
  161. package/dist/components/ui/DialogTitle.svelte.d.ts +9 -0
  162. package/dist/components/ui/Input.svelte +23 -0
  163. package/dist/components/ui/Input.svelte.d.ts +8 -0
  164. package/dist/components/ui/Textarea.svelte +19 -0
  165. package/dist/components/ui/Textarea.svelte.d.ts +7 -0
  166. package/dist/components/ui/index.d.ts +11 -0
  167. package/dist/components/ui/index.js +11 -0
  168. package/dist/config.d.ts +8 -0
  169. package/dist/config.js +9 -0
  170. package/dist/config.schema.json +471 -0
  171. package/dist/config.server.d.ts +46 -0
  172. package/dist/config.server.js +149 -0
  173. package/dist/{mdx-ColN3Cyg.d.mts → config.types.d.ts} +22 -75
  174. package/dist/config.types.js +39 -0
  175. package/dist/dev-utils.d.ts +29 -0
  176. package/dist/dev-utils.js +63 -0
  177. package/dist/index.d.ts +19 -4
  178. package/dist/index.js +25 -4861
  179. package/dist/mdx-cache.d.ts +41 -0
  180. package/dist/mdx-cache.js +160 -0
  181. package/dist/mdx-components.js +50 -1931
  182. package/dist/mdx-security.d.ts +76 -0
  183. package/dist/mdx-security.js +217 -0
  184. package/dist/mdx.d.ts +73 -0
  185. package/dist/mdx.js +1099 -0
  186. package/dist/middleware/index.d.ts +1 -0
  187. package/dist/middleware/index.js +2 -0
  188. package/dist/middleware/security.d.ts +22 -47
  189. package/dist/middleware/security.js +111 -137
  190. package/dist/parsers/base-parser.d.ts +14 -0
  191. package/dist/parsers/base-parser.js +1 -0
  192. package/dist/parsers/index.d.ts +16 -0
  193. package/dist/parsers/index.js +51 -0
  194. package/dist/parsers/openapi-parser.d.ts +18 -0
  195. package/dist/parsers/openapi-parser.js +209 -0
  196. package/dist/parsers/postman-parser.d.ts +20 -0
  197. package/dist/parsers/postman-parser.js +260 -0
  198. package/dist/parsers/specra-parser.d.ts +10 -0
  199. package/dist/parsers/specra-parser.js +18 -0
  200. package/dist/redirects.d.ts +12 -0
  201. package/dist/redirects.js +30 -0
  202. package/dist/remark-code-meta.d.ts +6 -0
  203. package/dist/remark-code-meta.js +21 -0
  204. package/dist/sidebar-utils.d.ts +59 -0
  205. package/dist/sidebar-utils.js +144 -0
  206. package/dist/stores/config.d.ts +20 -0
  207. package/dist/stores/config.js +45 -0
  208. package/dist/stores/index.d.ts +4 -0
  209. package/dist/stores/index.js +4 -0
  210. package/dist/stores/sidebar.d.ts +7 -0
  211. package/dist/stores/sidebar.js +12 -0
  212. package/dist/stores/tabs.d.ts +6 -0
  213. package/dist/stores/tabs.js +41 -0
  214. package/dist/stores/theme.d.ts +7 -0
  215. package/dist/stores/theme.js +75 -0
  216. package/dist/{styles.css → styles/globals.css} +136 -6
  217. package/dist/toc.d.ts +9 -0
  218. package/dist/toc.js +15 -0
  219. package/dist/utils.d.ts +13 -0
  220. package/dist/utils.js +30 -0
  221. package/package.json +47 -90
  222. package/dist/app/api/mdx-watch/route.d.mts +0 -10
  223. package/dist/app/api/mdx-watch/route.d.ts +0 -10
  224. package/dist/app/api/mdx-watch/route.js +0 -118
  225. package/dist/app/api/mdx-watch/route.js.map +0 -1
  226. package/dist/app/api/mdx-watch/route.mjs +0 -91
  227. package/dist/app/api/mdx-watch/route.mjs.map +0 -1
  228. package/dist/chunk-6S3EJVEO.mjs +0 -259
  229. package/dist/chunk-6S3EJVEO.mjs.map +0 -1
  230. package/dist/chunk-BE7EROIW.mjs +0 -212
  231. package/dist/chunk-BE7EROIW.mjs.map +0 -1
  232. package/dist/chunk-CWHRZHZO.mjs +0 -168
  233. package/dist/chunk-CWHRZHZO.mjs.map +0 -1
  234. package/dist/chunk-D5VDVYFY.mjs +0 -1325
  235. package/dist/chunk-D5VDVYFY.mjs.map +0 -1
  236. package/dist/chunk-WMCO2UX5.mjs +0 -585
  237. package/dist/chunk-WMCO2UX5.mjs.map +0 -1
  238. package/dist/chunk-XEMGCPZZ.mjs +0 -475
  239. package/dist/chunk-XEMGCPZZ.mjs.map +0 -1
  240. package/dist/components/index.d.mts +0 -822
  241. package/dist/components/index.js.map +0 -1
  242. package/dist/components/index.mjs +0 -3741
  243. package/dist/components/index.mjs.map +0 -1
  244. package/dist/index.d.mts +0 -4
  245. package/dist/index.js.map +0 -1
  246. package/dist/index.mjs +0 -1897
  247. package/dist/index.mjs.map +0 -1
  248. package/dist/layouts/index.d.mts +0 -34
  249. package/dist/layouts/index.d.ts +0 -34
  250. package/dist/layouts/index.js +0 -453
  251. package/dist/layouts/index.js.map +0 -1
  252. package/dist/layouts/index.mjs +0 -173
  253. package/dist/layouts/index.mjs.map +0 -1
  254. package/dist/lib/index.d.mts +0 -583
  255. package/dist/lib/index.d.ts +0 -583
  256. package/dist/lib/index.js +0 -1595
  257. package/dist/lib/index.js.map +0 -1
  258. package/dist/lib/index.mjs +0 -111
  259. package/dist/lib/index.mjs.map +0 -1
  260. package/dist/mdx-ColN3Cyg.d.ts +0 -352
  261. package/dist/mdx-components.d.mts +0 -86
  262. package/dist/mdx-components.d.ts +0 -86
  263. package/dist/mdx-components.js.map +0 -1
  264. package/dist/mdx-components.mjs +0 -206
  265. package/dist/mdx-components.mjs.map +0 -1
  266. package/dist/middleware/security.d.mts +0 -82
  267. package/dist/middleware/security.js.map +0 -1
  268. package/dist/middleware/security.mjs +0 -84
  269. package/dist/middleware/security.mjs.map +0 -1
  270. package/dist/styles.css.map +0 -1
  271. package/dist/styles.d.mts +0 -2
  272. package/dist/styles.d.ts +0 -2
  273. package/dist/styles.js +0 -2
  274. package/dist/styles.js.map +0 -1
  275. package/dist/styles.mjs +0 -1
  276. package/dist/styles.mjs.map +0 -1
@@ -1,585 +0,0 @@
1
- import {
2
- sanitizePath,
3
- validateMDXSecurity,
4
- validatePathWithinDirectory
5
- } from "./chunk-BE7EROIW.mjs";
6
- import {
7
- buildSidebarStructure,
8
- getConfig,
9
- sortSidebarGroups,
10
- sortSidebarItems
11
- } from "./chunk-6S3EJVEO.mjs";
12
-
13
- // src/lib/mdx.ts
14
- import fs2 from "fs";
15
- import path2 from "path";
16
- import matter from "gray-matter";
17
-
18
- // src/lib/category.ts
19
- import fs from "fs";
20
- import path from "path";
21
- var DOCS_DIR = path.join(process.cwd(), "docs");
22
- function getCategoryConfig(folderPath) {
23
- try {
24
- const categoryPath = path.join(folderPath, "_category_.json");
25
- if (!fs.existsSync(categoryPath)) {
26
- return null;
27
- }
28
- const content = fs.readFileSync(categoryPath, "utf8");
29
- return JSON.parse(content);
30
- } catch (error) {
31
- console.error(`Error reading category config from ${folderPath}:`, error);
32
- return null;
33
- }
34
- }
35
- function getAllCategoryConfigs(version) {
36
- const configs = /* @__PURE__ */ new Map();
37
- const versionDir = path.join(DOCS_DIR, version);
38
- if (!fs.existsSync(versionDir)) {
39
- return configs;
40
- }
41
- function scanDirectory(dir, relativePath = "") {
42
- const entries = fs.readdirSync(dir, { withFileTypes: true });
43
- for (const entry of entries) {
44
- if (entry.isDirectory()) {
45
- const fullPath = path.join(dir, entry.name);
46
- const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
47
- const config = getCategoryConfig(fullPath);
48
- if (config) {
49
- configs.set(relPath, config);
50
- }
51
- scanDirectory(fullPath, relPath);
52
- }
53
- }
54
- }
55
- scanDirectory(versionDir);
56
- return configs;
57
- }
58
-
59
- // src/lib/mdx.ts
60
- var DOCS_DIR2 = path2.join(process.cwd(), "docs");
61
- function calculateReadingTime(content) {
62
- const words = content.trim().split(/\s+/).length;
63
- const minutes = Math.ceil(words / 200);
64
- return { minutes, words };
65
- }
66
- function getVersions() {
67
- try {
68
- const versions = fs2.readdirSync(DOCS_DIR2);
69
- return versions.filter((v) => fs2.statSync(path2.join(DOCS_DIR2, v)).isDirectory());
70
- } catch (error) {
71
- return ["v1.0.0"];
72
- }
73
- }
74
- function findMdxFiles(dir, baseDir = dir) {
75
- const files = [];
76
- try {
77
- const entries = fs2.readdirSync(dir, { withFileTypes: true });
78
- for (const entry of entries) {
79
- const fullPath = path2.join(dir, entry.name);
80
- if (entry.isDirectory()) {
81
- files.push(...findMdxFiles(fullPath, baseDir));
82
- } else if (entry.isFile() && entry.name.endsWith(".mdx")) {
83
- const relativePath = path2.relative(baseDir, fullPath).replace(/\\/g, "/");
84
- files.push(relativePath);
85
- }
86
- }
87
- } catch (error) {
88
- console.error(`Error reading directory ${dir}:`, error);
89
- }
90
- return files;
91
- }
92
- function readDocFromFile(filePath, originalSlug) {
93
- try {
94
- if (!fs2.existsSync(filePath)) {
95
- return null;
96
- }
97
- if (!validatePathWithinDirectory(filePath, DOCS_DIR2)) {
98
- console.error(`[Security] Path traversal attempt blocked: ${filePath}`);
99
- return null;
100
- }
101
- const fileContents = fs2.readFileSync(filePath, "utf8");
102
- const { data, content } = matter(fileContents);
103
- const securityCheck = validateMDXSecurity(content, {
104
- strictMode: process.env.NODE_ENV === "production",
105
- blockDangerousPatterns: true
106
- });
107
- if (!securityCheck.valid) {
108
- console.error(`[Security] MDX validation failed for ${filePath}:`, securityCheck.issues);
109
- if (process.env.NODE_ENV === "production") {
110
- return null;
111
- }
112
- console.warn("[Security] Continuing in development mode with sanitized content");
113
- }
114
- const safeContent = securityCheck.sanitized || content;
115
- const { minutes, words } = calculateReadingTime(safeContent);
116
- let finalSlug = originalSlug;
117
- if (data.slug) {
118
- const customSlug = data.slug.replace(/^\//, "");
119
- const parts = originalSlug.split("/");
120
- if (parts.length > 1) {
121
- parts[parts.length - 1] = customSlug;
122
- finalSlug = parts.join("/");
123
- } else {
124
- finalSlug = customSlug;
125
- }
126
- }
127
- return {
128
- slug: finalSlug,
129
- filePath: originalSlug,
130
- // Keep original file path for sidebar
131
- title: data.title || originalSlug,
132
- meta: {
133
- ...data,
134
- content: safeContent,
135
- reading_time: minutes,
136
- word_count: words
137
- },
138
- content: safeContent
139
- };
140
- } catch (error) {
141
- console.error(`Error reading file ${filePath}:`, error);
142
- return null;
143
- }
144
- }
145
- function getI18nConfig() {
146
- const config = getConfig();
147
- const i18n = config.features?.i18n;
148
- if (!i18n) return null;
149
- if (typeof i18n === "boolean") {
150
- return i18n ? {
151
- defaultLocale: "en",
152
- locales: ["en"],
153
- localeNames: { en: "English" }
154
- } : null;
155
- }
156
- return i18n;
157
- }
158
- async function getDocBySlug(slug, version = "v1.0.0", locale) {
159
- try {
160
- const sanitizedVersion = sanitizePath(version);
161
- let sanitizedSlug = sanitizePath(slug);
162
- const i18nConfig = getI18nConfig();
163
- let detectedLocale = locale || i18nConfig?.defaultLocale;
164
- if (i18nConfig) {
165
- const parts = sanitizedSlug.split("/");
166
- if (parts.length > 0 && i18nConfig.locales.includes(parts[0])) {
167
- detectedLocale = parts[0];
168
- sanitizedSlug = parts.slice(1).join("/");
169
- if (sanitizedSlug === "") sanitizedSlug = "index";
170
- }
171
- }
172
- const targetLocale = detectedLocale;
173
- const isDefaultLocale = targetLocale === i18nConfig?.defaultLocale;
174
- const basePath = path2.join(DOCS_DIR2, sanitizedVersion);
175
- if (targetLocale) {
176
- const localizedPath = path2.join(basePath, `${sanitizedSlug}.${targetLocale}.mdx`);
177
- const doc2 = readDocFromFile(localizedPath, sanitizedSlug);
178
- if (doc2) {
179
- doc2.slug = i18nConfig ? `${targetLocale}/${sanitizedSlug}` : sanitizedSlug;
180
- doc2.meta.locale = targetLocale;
181
- return doc2;
182
- }
183
- }
184
- const defaultPath = path2.join(basePath, `${sanitizedSlug}.mdx`);
185
- const doc = readDocFromFile(defaultPath, sanitizedSlug);
186
- if (doc) {
187
- if (isDefaultLocale || !i18nConfig) {
188
- const usePrefix = i18nConfig && (i18nConfig.prefixDefault || targetLocale !== i18nConfig.defaultLocale);
189
- if (usePrefix && targetLocale) {
190
- doc.slug = `${targetLocale}/${doc.slug}`;
191
- }
192
- doc.meta.locale = targetLocale || "en";
193
- return doc;
194
- }
195
- }
196
- return null;
197
- } catch (error) {
198
- console.error(`Error reading doc ${slug}:`, error);
199
- return null;
200
- }
201
- }
202
- async function getAllDocs(version = "v1.0.0", locale) {
203
- try {
204
- const versionDir = path2.join(DOCS_DIR2, version);
205
- if (!fs2.existsSync(versionDir)) {
206
- return [];
207
- }
208
- const i18nConfig = getI18nConfig();
209
- const targetLocale = locale || i18nConfig?.defaultLocale || "en";
210
- const mdxFiles = findMdxFiles(versionDir);
211
- const categoryConfigs = getAllCategoryConfigs(version);
212
- const docs = await Promise.all(
213
- mdxFiles.map(async (file) => {
214
- let originalFilePath = file.replace(/\.mdx$/, "");
215
- let isLocalized = false;
216
- let fileLocale = i18nConfig?.defaultLocale || "en";
217
- if (i18nConfig) {
218
- const parts = originalFilePath.split(".");
219
- const lastPart = parts[parts.length - 1];
220
- if (i18nConfig.locales.includes(lastPart)) {
221
- fileLocale = lastPart;
222
- isLocalized = true;
223
- originalFilePath = parts.slice(0, -1).join(".");
224
- }
225
- }
226
- const doc = await getDocBySlug(originalFilePath, version, isLocalized ? fileLocale : void 0);
227
- if (!doc) return null;
228
- doc.filePath = originalFilePath;
229
- const folderPath = path2.dirname(originalFilePath).replace(/\\/g, "/");
230
- if (folderPath !== ".") {
231
- const categoryConfig = categoryConfigs.get(folderPath);
232
- if (categoryConfig) {
233
- doc.categoryLabel = categoryConfig.label;
234
- doc.categoryPosition = categoryConfig.position ?? categoryConfig.sidebar_position;
235
- doc.categoryCollapsible = categoryConfig.collapsible;
236
- doc.categoryCollapsed = categoryConfig.collapsed;
237
- doc.categoryIcon = categoryConfig.icon;
238
- doc.categoryTabGroup = categoryConfig.tab_group;
239
- }
240
- }
241
- return doc;
242
- })
243
- );
244
- const isDevelopment3 = process.env.NODE_ENV === "development";
245
- const uniqueDocs = /* @__PURE__ */ new Map();
246
- const validDocs = docs.filter((doc) => doc !== null && (isDevelopment3 || !doc.meta.draft));
247
- validDocs.forEach((doc) => {
248
- if (locale === "all") {
249
- uniqueDocs.set(doc.slug, doc);
250
- return;
251
- }
252
- let logicalSlug = doc.slug;
253
- if (i18nConfig) {
254
- const parts = logicalSlug.split("/");
255
- if (i18nConfig.locales.includes(parts[0])) {
256
- logicalSlug = parts.slice(1).join("/");
257
- }
258
- }
259
- const existing = uniqueDocs.get(logicalSlug);
260
- if (!existing) {
261
- if (doc.meta.locale === targetLocale) {
262
- uniqueDocs.set(logicalSlug, doc);
263
- } else if (doc.meta.locale === i18nConfig?.defaultLocale) {
264
- uniqueDocs.set(logicalSlug, doc);
265
- }
266
- } else {
267
- if (doc.meta.locale === targetLocale && existing.meta.locale !== targetLocale) {
268
- uniqueDocs.set(logicalSlug, doc);
269
- }
270
- }
271
- });
272
- return Array.from(uniqueDocs.values()).sort((a, b) => {
273
- const orderA = a.meta.sidebar_position ?? a.meta.order ?? 999;
274
- const orderB = b.meta.sidebar_position ?? b.meta.order ?? 999;
275
- return orderA - orderB;
276
- });
277
- } catch (error) {
278
- console.error(`Error getting all docs for version ${version}:`, error);
279
- return [];
280
- }
281
- }
282
- function flattenSidebarOrder(rootGroups, standalone) {
283
- const flatDocs = [];
284
- const flattenGroup = (group) => {
285
- const sortedChildren = sortSidebarGroups(group.children);
286
- const sortedItems = sortSidebarItems(group.items);
287
- const merged = [
288
- ...sortedChildren.map(([, childGroup]) => ({
289
- type: "group",
290
- group: childGroup,
291
- position: childGroup.position
292
- })),
293
- ...sortedItems.map((doc) => ({
294
- type: "item",
295
- doc,
296
- position: doc.meta.sidebar_position ?? doc.meta.order ?? 999
297
- }))
298
- ];
299
- merged.sort((a, b) => a.position - b.position);
300
- merged.forEach((item) => {
301
- if (item.type === "group") {
302
- flattenGroup(item.group);
303
- } else {
304
- flatDocs.push(item.doc);
305
- }
306
- });
307
- };
308
- sortSidebarItems(standalone).forEach((doc) => {
309
- flatDocs.push(doc);
310
- });
311
- const sortedRootGroups = sortSidebarGroups(rootGroups);
312
- sortedRootGroups.forEach(([, group]) => {
313
- flattenGroup(group);
314
- });
315
- return flatDocs;
316
- }
317
- function getAdjacentDocs(currentSlug, allDocs) {
318
- const { rootGroups, standalone } = buildSidebarStructure(allDocs);
319
- const orderedDocs = flattenSidebarOrder(rootGroups, standalone);
320
- const currentIndex = orderedDocs.findIndex((doc) => doc.slug === currentSlug);
321
- if (currentIndex === -1) {
322
- return {};
323
- }
324
- const currentDoc = orderedDocs[currentIndex];
325
- const currentTabGroup = currentDoc.meta?.tab_group || currentDoc.categoryTabGroup;
326
- const filteredDocs = orderedDocs.filter((doc) => {
327
- const docTabGroup = doc.meta?.tab_group || doc.categoryTabGroup;
328
- if (currentTabGroup) {
329
- return docTabGroup === currentTabGroup;
330
- }
331
- return !docTabGroup;
332
- });
333
- const filteredIndex = filteredDocs.findIndex((doc) => doc.slug === currentSlug);
334
- if (filteredIndex === -1) {
335
- return {};
336
- }
337
- return {
338
- previous: filteredIndex > 0 ? filteredDocs[filteredIndex - 1] : void 0,
339
- next: filteredIndex < filteredDocs.length - 1 ? filteredDocs[filteredIndex + 1] : void 0
340
- };
341
- }
342
- function extractTableOfContents(content) {
343
- const headingRegex = /^(#{2,3})\s+(.+)$/gm;
344
- const toc = [];
345
- let match;
346
- while ((match = headingRegex.exec(content)) !== null) {
347
- const level = match[1].length;
348
- const text = match[2];
349
- const id = text.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/^-|-$/g, "");
350
- toc.push({ id, title: text, level });
351
- }
352
- return toc;
353
- }
354
- function isCategoryPage(slug, allDocs) {
355
- return allDocs.some((doc) => {
356
- const parts = doc.slug.split("/");
357
- const docParent = parts.slice(0, -1).join("/");
358
- return docParent === slug && doc.slug !== slug;
359
- });
360
- }
361
-
362
- // src/lib/mdx-cache.ts
363
- import { watch } from "fs";
364
- import { join } from "path";
365
-
366
- // src/lib/dev-utils.ts
367
- var isDevelopment = process.env.NODE_ENV === "development";
368
- var PerfTimer = class {
369
- constructor(label) {
370
- this.label = label;
371
- this.startTime = isDevelopment ? performance.now() : 0;
372
- }
373
- end() {
374
- if (!isDevelopment) return;
375
- const duration = performance.now() - this.startTime;
376
- const color = duration > 1e3 ? "\x1B[31m" : duration > 500 ? "\x1B[33m" : "\x1B[32m";
377
- const reset = "\x1B[0m";
378
- console.log(`${color}\u23F1\uFE0F ${this.label}: ${duration.toFixed(2)}ms${reset}`);
379
- }
380
- };
381
- function logFsOperation(operation, path3, details) {
382
- if (!isDevelopment) return;
383
- console.log(`\u{1F4C1} [FS] ${operation}: ${path3}`, details || "");
384
- }
385
- function logCacheOperation(operation, key) {
386
- if (!isDevelopment) return;
387
- const emoji = operation === "hit" ? "\u2705" : operation === "miss" ? "\u274C" : "\u{1F504}";
388
- console.log(`${emoji} [Cache] ${operation}: ${key}`);
389
- }
390
- function logMemoryUsage(label) {
391
- if (!isDevelopment) return;
392
- const used = process.memoryUsage();
393
- const prefix = label ? `[${label}] ` : "";
394
- console.log(`\u{1F4BE} ${prefix}Memory Usage:`, {
395
- rss: `${Math.round(used.rss / 1024 / 1024)}MB`,
396
- heapTotal: `${Math.round(used.heapTotal / 1024 / 1024)}MB`,
397
- heapUsed: `${Math.round(used.heapUsed / 1024 / 1024)}MB`
398
- });
399
- }
400
- function debugLog(label, data) {
401
- if (!isDevelopment) return;
402
- console.log(`
403
- \u{1F50D} ${label}:`);
404
- console.dir(data, { depth: null, colors: true });
405
- console.log("");
406
- }
407
-
408
- // src/lib/mdx-cache.ts
409
- var isDevelopment2 = process.env.NODE_ENV === "development";
410
- var versionsCache = {
411
- data: null,
412
- timestamp: 0
413
- };
414
- var allDocsCache = /* @__PURE__ */ new Map();
415
- var docBySlugCache = /* @__PURE__ */ new Map();
416
- var CACHE_TTL = isDevelopment2 ? 5e3 : 6e4;
417
- var watchersInitialized = false;
418
- function initializeWatchers() {
419
- if (!isDevelopment2 || watchersInitialized) return;
420
- watchersInitialized = true;
421
- const docsPath = join(process.cwd(), "docs");
422
- try {
423
- watch(docsPath, { recursive: true }, (eventType, filename) => {
424
- if (!filename) return;
425
- if (filename.endsWith(".mdx") || filename.endsWith(".json")) {
426
- const parts = filename.split(/[/\\]/);
427
- const version = parts[0];
428
- allDocsCache.delete(version);
429
- const cacheKeysToDelete = [];
430
- docBySlugCache.forEach((_, key) => {
431
- if (key.startsWith(`${version}:`)) {
432
- cacheKeysToDelete.push(key);
433
- }
434
- });
435
- cacheKeysToDelete.forEach((key) => docBySlugCache.delete(key));
436
- if (eventType === "rename") {
437
- versionsCache.data = null;
438
- }
439
- console.log(`[MDX Cache] Invalidated cache for: ${filename}`);
440
- }
441
- });
442
- console.log("[MDX Cache] File watchers initialized");
443
- } catch (error) {
444
- console.error("[MDX Cache] Failed to initialize watchers:", error);
445
- }
446
- }
447
- function isCacheValid(timestamp) {
448
- return Date.now() - timestamp < CACHE_TTL;
449
- }
450
- function getCachedVersions() {
451
- initializeWatchers();
452
- if (versionsCache.data && isCacheValid(versionsCache.timestamp)) {
453
- logCacheOperation("hit", "versions");
454
- return versionsCache.data;
455
- }
456
- logCacheOperation("miss", "versions");
457
- const timer = new PerfTimer("getVersions");
458
- const versions = getVersions();
459
- timer.end();
460
- versionsCache.data = versions;
461
- versionsCache.timestamp = Date.now();
462
- return versions;
463
- }
464
- async function getCachedAllDocs(version = "v1.0.0", locale) {
465
- initializeWatchers();
466
- const cacheKey = locale ? `${version}:${locale}` : version;
467
- const cached = allDocsCache.get(cacheKey);
468
- if (cached && isCacheValid(cached.timestamp)) {
469
- logCacheOperation("hit", `getAllDocs:${cacheKey}`);
470
- return cached.data;
471
- }
472
- logCacheOperation("miss", `getAllDocs:${cacheKey}`);
473
- const timer = new PerfTimer(`getAllDocs(${cacheKey})`);
474
- const docs = await getAllDocs(version, locale);
475
- timer.end();
476
- allDocsCache.set(cacheKey, {
477
- data: docs,
478
- timestamp: Date.now()
479
- });
480
- return docs;
481
- }
482
- async function getCachedDocBySlug(slug, version = "v1.0.0") {
483
- initializeWatchers();
484
- const cacheKey = `${version}:${slug}`;
485
- const cached = docBySlugCache.get(cacheKey);
486
- if (cached && isCacheValid(cached.timestamp)) {
487
- logCacheOperation("hit", `getDocBySlug:${cacheKey}`);
488
- return cached.data;
489
- }
490
- logCacheOperation("miss", `getDocBySlug:${cacheKey}`);
491
- const timer = new PerfTimer(`getDocBySlug(${slug})`);
492
- const doc = await getDocBySlug(slug, version);
493
- timer.end();
494
- docBySlugCache.set(cacheKey, {
495
- data: doc,
496
- timestamp: Date.now()
497
- });
498
- return doc;
499
- }
500
- function clearAllCaches() {
501
- versionsCache.data = null;
502
- allDocsCache.clear();
503
- docBySlugCache.clear();
504
- console.log("[MDX Cache] All caches cleared");
505
- }
506
- function getCacheStats() {
507
- return {
508
- versions: {
509
- cached: versionsCache.data !== null,
510
- age: versionsCache.timestamp ? Date.now() - versionsCache.timestamp : 0
511
- },
512
- allDocs: {
513
- entries: allDocsCache.size,
514
- versions: Array.from(allDocsCache.keys())
515
- },
516
- docBySlug: {
517
- entries: docBySlugCache.size
518
- }
519
- };
520
- }
521
-
522
- // src/lib/toc.ts
523
- function extractHeadings(html) {
524
- const headingRegex = /<h([2-3])[^>]*id="([^"]*)"[^>]*>(.*?)<\/h\1>/g;
525
- const toc = [];
526
- let match;
527
- while ((match = headingRegex.exec(html)) !== null) {
528
- const level = Number.parseInt(match[1]);
529
- const id = match[2];
530
- const title = match[3].replace(/<[^>]*>/g, "");
531
- toc.push({ id, title, level });
532
- }
533
- return toc;
534
- }
535
-
536
- // src/lib/redirects.ts
537
- async function buildRedirectMappings() {
538
- const versions = getVersions();
539
- const redirects = [];
540
- for (const version of versions) {
541
- const docs = await getAllDocs(version);
542
- for (const doc of docs) {
543
- if (doc.meta.redirect_from && Array.isArray(doc.meta.redirect_from)) {
544
- for (const oldPath of doc.meta.redirect_from) {
545
- redirects.push({
546
- from: oldPath,
547
- to: `/docs/${version}/${doc.slug}`
548
- });
549
- }
550
- }
551
- }
552
- }
553
- return redirects;
554
- }
555
- async function findRedirect(path3) {
556
- const redirects = await buildRedirectMappings();
557
- const redirect = redirects.find((r) => r.from === path3);
558
- return redirect ? redirect.to : null;
559
- }
560
-
561
- export {
562
- getCategoryConfig,
563
- getAllCategoryConfigs,
564
- getVersions,
565
- getI18nConfig,
566
- getDocBySlug,
567
- getAllDocs,
568
- getAdjacentDocs,
569
- extractTableOfContents,
570
- isCategoryPage,
571
- PerfTimer,
572
- logFsOperation,
573
- logCacheOperation,
574
- logMemoryUsage,
575
- debugLog,
576
- getCachedVersions,
577
- getCachedAllDocs,
578
- getCachedDocBySlug,
579
- clearAllCaches,
580
- getCacheStats,
581
- extractHeadings,
582
- buildRedirectMappings,
583
- findRedirect
584
- };
585
- //# sourceMappingURL=chunk-WMCO2UX5.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/mdx.ts","../src/lib/category.ts","../src/lib/mdx-cache.ts","../src/lib/dev-utils.ts","../src/lib/toc.ts","../src/lib/redirects.ts"],"sourcesContent":["import fs from \"fs\"\nimport path from \"path\"\nimport matter from \"gray-matter\"\nimport { getAllCategoryConfigs } from \"./category\"\nimport { sortSidebarItems, sortSidebarGroups, buildSidebarStructure, type SidebarGroup } from \"./sidebar-utils\"\nimport { sanitizePath, validatePathWithinDirectory, validateMDXSecurity } from \"./mdx-security\"\nimport { getConfig } from \"./config\"\nimport { I18nConfig } from \"./config.types\"\n\nconst DOCS_DIR = path.join(process.cwd(), \"docs\")\n\n/**\n * Calculate reading time based on word count\n * Average reading speed: 200 words per minute\n */\nfunction calculateReadingTime(content: string): { minutes: number; words: number } {\n const words = content.trim().split(/\\s+/).length\n const minutes = Math.ceil(words / 200)\n return { minutes, words }\n}\n\nexport interface DocMeta {\n title: string\n description?: string\n slug?: string\n section?: string\n group?: string\n sidebar?: string\n order?: number\n sidebar_position?: number\n content?: string\n last_updated?: string\n draft?: boolean\n authors?: Array<{ id: string; name?: string }>\n tags?: string[]\n redirect_from?: string[]\n reading_time?: number\n word_count?: number\n icon?: string // Icon name for sidebar display (Lucide icon name)\n tab_group?: string // Tab group ID for organizing docs into tabs\n locale?: string // Locale of the document\n}\n\nexport interface Doc {\n slug: string\n filePath: string // Original file path for sidebar grouping\n title: string\n meta: DocMeta\n content: string\n categoryLabel?: string // Label from _category_.json\n categoryPosition?: number // Position from _category_.json\n categoryCollapsible?: boolean // Collapsible from _category_.json\n categoryCollapsed?: boolean // Default collapsed state from _category_.json\n categoryIcon?: string // Icon from _category_.json\n categoryTabGroup?: string // Tab group from _category_.json\n locale?: string // Locale of the document\n}\n\nexport interface TocItem {\n id: string\n title: string\n level: number\n}\n\nexport function getVersions(): string[] {\n try {\n const versions = fs.readdirSync(DOCS_DIR)\n return versions.filter((v) => fs.statSync(path.join(DOCS_DIR, v)).isDirectory())\n } catch (error) {\n return [\"v1.0.0\"]\n }\n}\n\n/**\n * Recursively find all MDX files in a directory\n */\nfunction findMdxFiles(dir: string, baseDir: string = dir): string[] {\n const files: string[] = []\n\n try {\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n\n if (entry.isDirectory()) {\n files.push(...findMdxFiles(fullPath, baseDir))\n } else if (entry.isFile() && entry.name.endsWith(\".mdx\")) {\n // Get relative path from base directory and normalize to forward slashes\n const relativePath = path.relative(baseDir, fullPath).replace(/\\\\/g, '/')\n files.push(relativePath)\n }\n }\n } catch (error) {\n console.error(`Error reading directory ${dir}:`, error)\n }\n\n return files\n}\n\n/**\n * Internal function to read a doc from file path\n */\nfunction readDocFromFile(filePath: string, originalSlug: string): Doc | null {\n try {\n if (!fs.existsSync(filePath)) {\n return null\n }\n\n // Validate path is within allowed directory\n if (!validatePathWithinDirectory(filePath, DOCS_DIR)) {\n console.error(`[Security] Path traversal attempt blocked: ${filePath}`)\n return null\n }\n\n const fileContents = fs.readFileSync(filePath, \"utf8\")\n const { data, content } = matter(fileContents)\n\n // Security: Validate MDX content for dangerous patterns\n const securityCheck = validateMDXSecurity(content, {\n strictMode: process.env.NODE_ENV === 'production',\n blockDangerousPatterns: true,\n })\n\n if (!securityCheck.valid) {\n console.error(`[Security] MDX validation failed for ${filePath}:`, securityCheck.issues)\n if (process.env.NODE_ENV === 'production') {\n return null\n }\n // In development, log warnings but continue\n console.warn('[Security] Continuing in development mode with sanitized content')\n }\n\n // Use sanitized content if available\n const safeContent = securityCheck.sanitized || content\n\n // Calculate reading time\n const { minutes, words } = calculateReadingTime(safeContent)\n\n // If custom slug provided, replace only the filename part, keep the folder structure\n let finalSlug = originalSlug\n if (data.slug) {\n const customSlug = data.slug.replace(/^\\//, '')\n const parts = originalSlug.split(\"/\")\n\n if (parts.length > 1) {\n // Keep folder structure, replace only filename\n parts[parts.length - 1] = customSlug\n finalSlug = parts.join(\"/\")\n } else {\n // Root level file, use custom slug as-is\n finalSlug = customSlug\n }\n }\n\n return {\n slug: finalSlug,\n filePath: originalSlug, // Keep original file path for sidebar\n title: data.title || originalSlug,\n meta: {\n ...data,\n content: safeContent,\n reading_time: minutes,\n word_count: words,\n } as DocMeta,\n content: safeContent,\n }\n } catch (error) {\n console.error(`Error reading file ${filePath}:`, error)\n return null\n }\n}\n\nexport function getI18nConfig(): I18nConfig | null {\n const config = getConfig()\n const i18n = config.features?.i18n\n\n if (!i18n) return null\n\n if (typeof i18n === 'boolean') {\n return i18n ? {\n defaultLocale: 'en',\n locales: ['en'],\n localeNames: { en: 'English' }\n } : null\n }\n\n return i18n\n}\n\nexport async function getDocBySlug(slug: string, version = \"v1.0.0\", locale?: string): Promise<Doc | null> {\n try {\n // Security: Sanitize and validate slug\n const sanitizedVersion = sanitizePath(version)\n let sanitizedSlug = sanitizePath(slug)\n\n // Get i18n config\n const i18nConfig = getI18nConfig()\n\n // Determine locale from slug if not provided\n let detectedLocale = locale || i18nConfig?.defaultLocale\n\n if (i18nConfig) {\n const parts = sanitizedSlug.split('/')\n if (parts.length > 0 && i18nConfig.locales.includes(parts[0])) {\n detectedLocale = parts[0]\n sanitizedSlug = parts.slice(1).join('/')\n if (sanitizedSlug === \"\") sanitizedSlug = \"index\"\n }\n }\n\n const targetLocale = detectedLocale\n const isDefaultLocale = targetLocale === i18nConfig?.defaultLocale\n\n // Try finding the file in this order:\n // 1. Localized extension: slug.locale.mdx (e.g. guide.fr.mdx)\n // 2. Default file: slug.mdx (only if using default locale and configured to fallback or strictly default)\n\n // Construct potential paths\n const basePath = path.join(DOCS_DIR, sanitizedVersion)\n\n // 1. Try localized file extension\n if (targetLocale) {\n const localizedPath = path.join(basePath, `${sanitizedSlug}.${targetLocale}.mdx`)\n const doc = readDocFromFile(localizedPath, sanitizedSlug) // Keep parsed slug\n if (doc) {\n doc.slug = i18nConfig ? `${targetLocale}/${sanitizedSlug}` : sanitizedSlug\n doc.meta.locale = targetLocale\n return doc\n }\n }\n\n // 2. Try default file\n const defaultPath = path.join(basePath, `${sanitizedSlug}.mdx`)\n const doc = readDocFromFile(defaultPath, sanitizedSlug)\n\n if (doc) {\n // If we found a default file but requested a specific locale using prefix, \n // we might want to return it but with the prefix in slug if we are doing fallback.\n // For now, strict mode: if I request /fr/guide and guide.fr.mdx is missing, \n // should I return guide.mdx? \n // Let's assume explicitly: Yes, but keep the URL /fr/guide ?? \n // No, typically you want 404 if translation missing, OR fallback.\n // Let's stick to: if explicit locale requested and file not found, we fall through to null eventually.\n // BUT if it matches default locale, we return it.\n\n if (isDefaultLocale || !i18nConfig) {\n // For default locale, we might want to prefix if prompt said \"add language to url\"\n // If i18n enabled and prefixDefault is true, ensure slug has prefix.\n // But existing behavior for default locale usually omits prefix.\n // If plan said: /en/docs/... then we probably want prefix even for default?\n // The config I added has `prefixDefault`. Checks that.\n\n const usePrefix = i18nConfig && (i18nConfig.prefixDefault || targetLocale !== i18nConfig.defaultLocale)\n\n if (usePrefix && targetLocale) {\n doc.slug = `${targetLocale}/${doc.slug}`\n }\n doc.meta.locale = targetLocale || 'en'\n return doc\n }\n }\n\n // If still not found, search all docs for a matching custom slug\n // This part is expensive and might need update for i18n, disabling for now or leaving as is for default locale\n // Ideally custom slugs should also be localized? \n // Let's rely on standard file resolution for now for i18n to ensure stability.\n\n return null\n } catch (error) {\n console.error(`Error reading doc ${slug}:`, error)\n return null\n }\n}\n\nexport async function getAllDocs(version = \"v1.0.0\", locale?: string): Promise<Doc[]> {\n try {\n const versionDir = path.join(DOCS_DIR, version)\n\n if (!fs.existsSync(versionDir)) {\n return []\n }\n\n // Get i18n config\n const i18nConfig = getI18nConfig()\n const targetLocale = locale || i18nConfig?.defaultLocale || 'en'\n\n const mdxFiles = findMdxFiles(versionDir)\n const categoryConfigs = getAllCategoryConfigs(version)\n\n const docs = await Promise.all(\n mdxFiles.map(async (file) => {\n // file contains path relative to version dir, e.g. \"getting-started/intro.mdx\" or \"intro.fr.mdx\"\n\n let originalFilePath = file.replace(/\\.mdx$/, \"\")\n\n // Handle localized files\n let isLocalized = false\n let fileLocale = i18nConfig?.defaultLocale || 'en'\n\n if (i18nConfig) {\n // Check for .<locale> suffix\n const parts = originalFilePath.split('.')\n const lastPart = parts[parts.length - 1]\n if (i18nConfig.locales.includes(lastPart)) {\n fileLocale = lastPart\n isLocalized = true\n originalFilePath = parts.slice(0, -1).join('.')\n }\n }\n\n // If we requested a specific locale, filter out others\n // If target is 'fr', we want intro.fr.mdx (if exists) OR intro.mdx (fallback? no, getAllDocs is usually for list)\n // Actually, for sidebar we want the \"best\" version of each doc for the current locale.\n\n // Strategy: Map all files to their logical slug, then group by slug and pick best locale.\n // But getAllDocs is async and parallel.\n\n // Simplified: Just process all files, returning the doc with its true locale.\n // Then filter/merge later? \n // No, current logic returns flat array.\n\n // Let's try to load the doc.\n const doc = await getDocBySlug(originalFilePath, version, isLocalized ? fileLocale : undefined)\n\n if (!doc) return null\n\n // Override filePath properties for sidebar grouping \n // (we want grouped by logical path, not physically localized path if possible)\n doc.filePath = originalFilePath // Use logical path (without .fr) for grouping\n\n const folderPath = path.dirname(originalFilePath).replace(/\\\\/g, '/')\n if (folderPath !== \".\") {\n const categoryConfig = categoryConfigs.get(folderPath)\n if (categoryConfig) {\n doc.categoryLabel = categoryConfig.label\n doc.categoryPosition = categoryConfig.position ?? categoryConfig.sidebar_position\n doc.categoryCollapsible = categoryConfig.collapsible\n doc.categoryCollapsed = categoryConfig.collapsed\n doc.categoryIcon = categoryConfig.icon\n doc.categoryTabGroup = categoryConfig.tab_group\n }\n }\n\n return doc\n }),\n )\n\n const isDevelopment = process.env.NODE_ENV === \"development\"\n\n // Create a map to track unique slugs and avoid duplicates, prioritizing target locale\n const uniqueDocs = new Map<string, Doc>()\n\n // Sort docs such that target locale comes first? No, we need to filter/merge.\n const validDocs = docs.filter((doc): doc is Doc => doc !== null && (isDevelopment || !doc.meta.draft))\n\n // Group by logical slug (we stored logical path in filePath, maybe use that?)\n // Actually doc.slug might differ if custom slug used.\n\n // If we have intro.mdx (en) and intro.fr.mdx (fr)\n // And targetLocale is 'fr'\n // We want the 'fr' one.\n\n validDocs.forEach(doc => {\n // If we want all docs (e.g. for static params generation), return everything unique by slug\n if (locale === 'all') {\n uniqueDocs.set(doc.slug, doc)\n return\n }\n\n // Identify logical slug. \n // If doc.slug already has prefix (e.g. fr/intro), stripped slug is 'intro'.\n let logicalSlug = doc.slug\n if (i18nConfig) {\n const parts = logicalSlug.split('/')\n if (i18nConfig.locales.includes(parts[0])) {\n logicalSlug = parts.slice(1).join('/')\n }\n }\n\n const existing = uniqueDocs.get(logicalSlug)\n\n if (!existing) {\n // If doc matches target locale or is default (and we allow default fallback), take it.\n // For now, take everything, filter later?\n // Better: Only add if it matches target locale OR is default and we don't have target yet.\n if (doc.meta.locale === targetLocale) {\n uniqueDocs.set(logicalSlug, doc)\n } else if (doc.meta.locale === i18nConfig?.defaultLocale) {\n uniqueDocs.set(logicalSlug, doc)\n }\n } else {\n // We have an existing entry. prefer targetLocale\n if (doc.meta.locale === targetLocale && existing.meta.locale !== targetLocale) {\n uniqueDocs.set(logicalSlug, doc)\n }\n }\n })\n\n return Array.from(uniqueDocs.values()).sort((a, b) => {\n const orderA = a.meta.sidebar_position ?? a.meta.order ?? 999\n const orderB = b.meta.sidebar_position ?? b.meta.order ?? 999\n return orderA - orderB\n })\n } catch (error) {\n console.error(`Error getting all docs for version ${version}:`, error)\n return []\n }\n}\n\n// export function getAdjacentDocs(currentSlug: string, allDocs: Doc[]): { previous?: Doc; next?: Doc } {\n// const currentIndex = allDocs.findIndex((doc) => doc.slug === currentSlug)\n\n// if (currentIndex === -1) {\n// return {}\n// }\n\n// return {\n// previous: currentIndex > 0 ? allDocs[currentIndex - 1] : undefined,\n// next: currentIndex < allDocs.length - 1 ? allDocs[currentIndex + 1] : undefined,\n// }\n// }\n\n// Flatten the sidebar structure into a linear order\nfunction flattenSidebarOrder(\n rootGroups: Record<string, SidebarGroup>,\n standalone: Doc[]\n): Doc[] {\n const flatDocs: Doc[] = []\n\n // Recursively flatten groups - intermix folders and files by position\n const flattenGroup = (group: SidebarGroup) => {\n const sortedChildren = sortSidebarGroups(group.children)\n const sortedItems = sortSidebarItems(group.items)\n\n // Merge child groups and items, then sort by position\n const merged: Array<{ type: 'group', group: SidebarGroup, position: number } | { type: 'item', doc: Doc, position: number }> = [\n ...sortedChildren.map(([, childGroup]) => ({\n type: 'group' as const,\n group: childGroup,\n position: childGroup.position\n })),\n ...sortedItems.map((doc) => ({\n type: 'item' as const,\n doc,\n position: doc.meta.sidebar_position ?? doc.meta.order ?? 999\n }))\n ]\n\n // Sort by position\n merged.sort((a, b) => a.position - b.position)\n\n // Process in sorted order\n merged.forEach((item) => {\n if (item.type === 'group') {\n flattenGroup(item.group)\n } else {\n flatDocs.push(item.doc)\n }\n })\n }\n\n // Add standalone items first\n sortSidebarItems(standalone).forEach((doc) => {\n flatDocs.push(doc)\n })\n\n // Then add all grouped items\n const sortedRootGroups = sortSidebarGroups(rootGroups)\n sortedRootGroups.forEach(([, group]) => {\n flattenGroup(group)\n })\n\n return flatDocs\n}\n\nexport function getAdjacentDocs(currentSlug: string, allDocs: Doc[]): { previous?: Doc; next?: Doc } {\n // Build the same sidebar structure\n const { rootGroups, standalone } = buildSidebarStructure(allDocs)\n\n // Flatten into the same order as shown in the sidebar\n const orderedDocs = flattenSidebarOrder(rootGroups, standalone)\n\n // Find current doc in the ordered list\n const currentIndex = orderedDocs.findIndex((doc) => doc.slug === currentSlug)\n\n if (currentIndex === -1) {\n return {}\n }\n\n const currentDoc = orderedDocs[currentIndex]\n\n // Get current doc's tab group (from meta or category)\n const currentTabGroup = currentDoc.meta?.tab_group || currentDoc.categoryTabGroup\n\n // Filter docs to match the current doc's tab group status\n // If current has a tab group, only show docs in the same tab group\n // If current has NO tab group, only show docs with NO tab group\n const filteredDocs = orderedDocs.filter((doc) => {\n const docTabGroup = doc.meta?.tab_group || doc.categoryTabGroup\n\n // If current doc has a tab group, only include docs with the same tab group\n if (currentTabGroup) {\n return docTabGroup === currentTabGroup\n }\n\n // If current doc has no tab group, only include docs with no tab group\n return !docTabGroup\n })\n\n // Find current doc's index within the filtered list\n const filteredIndex = filteredDocs.findIndex((doc) => doc.slug === currentSlug)\n\n if (filteredIndex === -1) {\n return {}\n }\n\n return {\n previous: filteredIndex > 0 ? filteredDocs[filteredIndex - 1] : undefined,\n next: filteredIndex < filteredDocs.length - 1 ? filteredDocs[filteredIndex + 1] : undefined,\n }\n}\n\nexport function extractTableOfContents(content: string): TocItem[] {\n const headingRegex = /^(#{2,3})\\s+(.+)$/gm\n const toc: TocItem[] = []\n let match\n\n while ((match = headingRegex.exec(content)) !== null) {\n const level = match[1].length\n const text = match[2]\n // Generate ID the same way rehype-slug does\n const id = text\n .toLowerCase()\n .replace(/\\s+/g, \"-\") // Replace spaces with hyphens first\n .replace(/[^a-z0-9-]/g, \"\") // Remove special chars (dots, slashes, etc)\n .replace(/^-|-$/g, \"\") // Remove leading/trailing hyphens\n\n toc.push({ id, title: text, level })\n }\n\n return toc\n}\n\n/**\n * Check if a slug represents a category (has child documents)\n */\nexport function isCategoryPage(slug: string, allDocs: Doc[]): boolean {\n return allDocs.some((doc) => {\n const parts = doc.slug.split(\"/\")\n const docParent = parts.slice(0, -1).join(\"/\")\n return docParent === slug && doc.slug !== slug\n })\n}\n\n\n","// Note: This file uses server-only APIs (fs, path) and should only be imported in Server Components\nimport fs from \"fs\"\nimport path from \"path\"\n\nexport interface CategoryConfig {\n label?: string\n position?: number\n sidebar_position?: number // Alternative naming for position\n link?: {\n type: \"generated-index\" | \"doc\"\n slug?: string\n }\n collapsed?: boolean\n collapsible?: boolean\n icon?: string // Icon name for sidebar display (Lucide icon name)\n tab_group?: string // Tab group ID for organizing categories into tabs\n}\n\nconst DOCS_DIR = path.join(process.cwd(), \"docs\")\n\n/**\n * Read category.json from a folder\n */\nexport function getCategoryConfig(folderPath: string): CategoryConfig | null {\n try {\n const categoryPath = path.join(folderPath, \"_category_.json\")\n\n if (!fs.existsSync(categoryPath)) {\n return null\n }\n\n const content = fs.readFileSync(categoryPath, \"utf8\")\n return JSON.parse(content) as CategoryConfig\n } catch (error) {\n console.error(`Error reading category config from ${folderPath}:`, error)\n return null\n }\n}\n\n/**\n * Get all category configs for a version\n */\nexport function getAllCategoryConfigs(version: string): Map<string, CategoryConfig> {\n const configs = new Map<string, CategoryConfig>()\n const versionDir = path.join(DOCS_DIR, version)\n\n if (!fs.existsSync(versionDir)) {\n return configs\n }\n\n function scanDirectory(dir: string, relativePath: string = \"\") {\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const fullPath = path.join(dir, entry.name)\n const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n\n const config = getCategoryConfig(fullPath)\n if (config) {\n configs.set(relPath, config)\n }\n\n // Recursively scan subdirectories\n scanDirectory(fullPath, relPath)\n }\n }\n }\n\n scanDirectory(versionDir)\n return configs\n}\n","/**\n * Caching layer for MDX operations to improve development performance\n *\n * This module provides in-memory caching for expensive file system operations\n * that occur during static generation. In development mode, caches are\n * invalidated automatically when files change.\n */\n\n// Note: This file uses server-only APIs (fs, path) and should only be imported in Server Components\nimport { Doc, getVersions, getAllDocs, getDocBySlug } from './mdx'\nimport { watch } from 'fs'\nimport { join } from 'path'\nimport { PerfTimer, logCacheOperation } from './dev-utils'\n\nconst isDevelopment = process.env.NODE_ENV === 'development'\n\n// Cache stores\nconst versionsCache = {\n data: null as string[] | null,\n timestamp: 0,\n}\n\nconst allDocsCache = new Map<string, {\n data: Doc[]\n timestamp: number\n}>()\n\nconst docBySlugCache = new Map<string, {\n data: Doc | null\n timestamp: number\n}>()\n\n// Cache TTL (time to live) in milliseconds\nconst CACHE_TTL = isDevelopment ? 5000 : 60000 // 5s in dev, 60s in prod\n\n// Track if we've set up file watchers\nlet watchersInitialized = false\n\n/**\n * Initialize file watchers to invalidate cache on changes\n * Only runs in development mode\n */\nfunction initializeWatchers() {\n if (!isDevelopment || watchersInitialized) return\n\n watchersInitialized = true\n const docsPath = join(process.cwd(), 'docs')\n\n try {\n watch(docsPath, { recursive: true }, (eventType, filename) => {\n if (!filename) return\n\n // Invalidate relevant caches when MDX or JSON files change\n if (filename.endsWith('.mdx') || filename.endsWith('.json')) {\n // Extract version from path\n const parts = filename.split(/[/\\\\]/)\n const version = parts[0]\n\n // Clear all docs cache for this version\n allDocsCache.delete(version)\n\n // Clear individual doc caches for this version\n const cacheKeysToDelete: string[] = []\n docBySlugCache.forEach((_, key) => {\n if (key.startsWith(`${version}:`)) {\n cacheKeysToDelete.push(key)\n }\n })\n cacheKeysToDelete.forEach(key => docBySlugCache.delete(key))\n\n // Clear versions cache if directory structure changed\n if (eventType === 'rename') {\n versionsCache.data = null\n }\n\n console.log(`[MDX Cache] Invalidated cache for: ${filename}`)\n }\n })\n\n console.log('[MDX Cache] File watchers initialized')\n } catch (error) {\n console.error('[MDX Cache] Failed to initialize watchers:', error)\n }\n}\n\n/**\n * Check if a cache entry is still valid\n */\nfunction isCacheValid(timestamp: number): boolean {\n return Date.now() - timestamp < CACHE_TTL\n}\n\n/**\n * Cached version of getVersions()\n */\nexport function getCachedVersions(): string[] {\n // Initialize watchers on first use\n initializeWatchers()\n\n if (versionsCache.data && isCacheValid(versionsCache.timestamp)) {\n logCacheOperation('hit', 'versions')\n return versionsCache.data\n }\n\n logCacheOperation('miss', 'versions')\n const timer = new PerfTimer('getVersions')\n const versions = getVersions()\n timer.end()\n\n versionsCache.data = versions\n versionsCache.timestamp = Date.now()\n\n return versions\n}\n\n/**\n * Cached version of getAllDocs()\n */\nexport async function getCachedAllDocs(version = 'v1.0.0', locale?: string): Promise<Doc[]> {\n // Initialize watchers on first use\n initializeWatchers()\n\n const cacheKey = locale ? `${version}:${locale}` : version\n const cached = allDocsCache.get(cacheKey)\n if (cached && isCacheValid(cached.timestamp)) {\n logCacheOperation('hit', `getAllDocs:${cacheKey}`)\n return cached.data\n }\n\n logCacheOperation('miss', `getAllDocs:${cacheKey}`)\n const timer = new PerfTimer(`getAllDocs(${cacheKey})`)\n const docs = await getAllDocs(version, locale)\n timer.end()\n\n allDocsCache.set(cacheKey, {\n data: docs,\n timestamp: Date.now(),\n })\n\n return docs\n}\n\n/**\n * Cached version of getDocBySlug()\n */\nexport async function getCachedDocBySlug(\n slug: string,\n version = 'v1.0.0'\n): Promise<Doc | null> {\n // Initialize watchers on first use\n initializeWatchers()\n\n const cacheKey = `${version}:${slug}`\n const cached = docBySlugCache.get(cacheKey)\n\n if (cached && isCacheValid(cached.timestamp)) {\n logCacheOperation('hit', `getDocBySlug:${cacheKey}`)\n return cached.data\n }\n\n logCacheOperation('miss', `getDocBySlug:${cacheKey}`)\n const timer = new PerfTimer(`getDocBySlug(${slug})`)\n const doc = await getDocBySlug(slug, version)\n timer.end()\n\n docBySlugCache.set(cacheKey, {\n data: doc,\n timestamp: Date.now(),\n })\n\n return doc\n}\n\n/**\n * Manually clear all caches\n * Useful for testing or when you want to force a refresh\n */\nexport function clearAllCaches() {\n versionsCache.data = null\n allDocsCache.clear()\n docBySlugCache.clear()\n console.log('[MDX Cache] All caches cleared')\n}\n\n/**\n * Get cache statistics for debugging\n */\nexport function getCacheStats() {\n return {\n versions: {\n cached: versionsCache.data !== null,\n age: versionsCache.timestamp ? Date.now() - versionsCache.timestamp : 0,\n },\n allDocs: {\n entries: allDocsCache.size,\n versions: Array.from(allDocsCache.keys()),\n },\n docBySlug: {\n entries: docBySlugCache.size,\n },\n }\n}\n","/**\n * Development utilities for debugging and performance monitoring\n * Only active in development mode\n */\n\nconst isDevelopment = process.env.NODE_ENV === 'development'\n\n/**\n * Performance timer for measuring operation duration\n */\nexport class PerfTimer {\n private startTime: number\n private label: string\n\n constructor(label: string) {\n this.label = label\n this.startTime = isDevelopment ? performance.now() : 0\n }\n\n end() {\n if (!isDevelopment) return\n\n const duration = performance.now() - this.startTime\n const color = duration > 1000 ? '\\x1b[31m' : duration > 500 ? '\\x1b[33m' : '\\x1b[32m'\n const reset = '\\x1b[0m'\n\n console.log(`${color}⏱️ ${this.label}: ${duration.toFixed(2)}ms${reset}`)\n }\n}\n\n/**\n * Log file system operations\n */\nexport function logFsOperation(operation: string, path: string, details?: any) {\n if (!isDevelopment) return\n\n console.log(`📁 [FS] ${operation}: ${path}`, details || '')\n}\n\n/**\n * Log cache operations\n */\nexport function logCacheOperation(operation: 'hit' | 'miss' | 'invalidate', key: string) {\n if (!isDevelopment) return\n\n const emoji = operation === 'hit' ? '✅' : operation === 'miss' ? '❌' : '🔄'\n console.log(`${emoji} [Cache] ${operation}: ${key}`)\n}\n\n/**\n * Memory usage reporter\n */\nexport function logMemoryUsage(label?: string) {\n if (!isDevelopment) return\n\n const used = process.memoryUsage()\n const prefix = label ? `[${label}] ` : ''\n\n console.log(`💾 ${prefix}Memory Usage:`, {\n rss: `${Math.round(used.rss / 1024 / 1024)}MB`,\n heapTotal: `${Math.round(used.heapTotal / 1024 / 1024)}MB`,\n heapUsed: `${Math.round(used.heapUsed / 1024 / 1024)}MB`,\n })\n}\n\n/**\n * Pretty print object for debugging\n */\nexport function debugLog(label: string, data: any) {\n if (!isDevelopment) return\n\n console.log(`\\n🔍 ${label}:`)\n console.dir(data, { depth: null, colors: true })\n console.log('')\n}\n","export interface TOCItem {\n id: string\n title: string\n level: number\n}\n\n/**\n * Extract headings from HTML string for table of contents\n */\nexport function extractHeadings(html: string): TOCItem[] {\n const headingRegex = /<h([2-3])[^>]*id=\"([^\"]*)\"[^>]*>(.*?)<\\/h\\1>/g\n const toc: TOCItem[] = []\n let match\n\n while ((match = headingRegex.exec(html)) !== null) {\n const level = Number.parseInt(match[1])\n const id = match[2]\n const title = match[3].replace(/<[^>]*>/g, \"\") // Strip HTML tags\n\n toc.push({ id, title, level })\n }\n\n return toc\n}\n","import { getAllDocs, getVersions } from \"./mdx\"\n\nexport interface RedirectMapping {\n from: string\n to: string\n}\n\n/**\n * Build redirect mappings from all docs' redirect_from frontmatter\n */\nexport async function buildRedirectMappings(): Promise<RedirectMapping[]> {\n const versions = getVersions()\n const redirects: RedirectMapping[] = []\n\n for (const version of versions) {\n const docs = await getAllDocs(version)\n \n for (const doc of docs) {\n if (doc.meta.redirect_from && Array.isArray(doc.meta.redirect_from)) {\n for (const oldPath of doc.meta.redirect_from) {\n redirects.push({\n from: oldPath,\n to: `/docs/${version}/${doc.slug}`,\n })\n }\n }\n }\n }\n\n return redirects\n}\n\n/**\n * Find redirect destination for a given path\n */\nexport async function findRedirect(path: string): Promise<string | null> {\n const redirects = await buildRedirectMappings()\n const redirect = redirects.find((r) => r.from === path)\n return redirect ? redirect.to : null\n}\n"],"mappings":"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","names":["fs","path","DOCS_DIR","path","fs","doc","isDevelopment","path","isDevelopment","path"]}