blodemd 0.0.15 → 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 (286) hide show
  1. package/README.md +26 -1
  2. package/dist/cli.mjs +217 -217
  3. package/dist/cli.mjs.map +1 -1
  4. package/package.json +3 -36
  5. package/dev-server/app/[[...slug]]/page.tsx +0 -140
  6. package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
  7. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
  8. package/dev-server/app/blodemd-dev/version/route.ts +0 -14
  9. package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
  10. package/dev-server/app/error.tsx +0 -24
  11. package/dev-server/app/favicon.ico +0 -0
  12. package/dev-server/app/globals.css +0 -4
  13. package/dev-server/app/layout.tsx +0 -38
  14. package/dev-server/app/not-found.tsx +0 -18
  15. package/dev-server/app/search/route.ts +0 -17
  16. package/dev-server/components/dev-reload-script.tsx +0 -86
  17. package/dev-server/components/providers.tsx +0 -15
  18. package/dev-server/lib/dev-state.ts +0 -8
  19. package/dev-server/lib/local-content-source.ts +0 -103
  20. package/dev-server/lib/local-runtime.tsx +0 -555
  21. package/dev-server/next-env.d.ts +0 -5
  22. package/dev-server/next.config.js +0 -54
  23. package/dev-server/package.json +0 -61
  24. package/dev-server/postcss.config.mjs +0 -7
  25. package/dev-server/public/glide-variable.woff2 +0 -0
  26. package/dev-server/tsconfig.json +0 -50
  27. package/docs/app/globals.css +0 -471
  28. package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
  29. package/docs/components/api/api-playground.tsx +0 -467
  30. package/docs/components/api/api-reference.tsx +0 -157
  31. package/docs/components/content/collection-index.tsx +0 -114
  32. package/docs/components/docs/contextual-menu.tsx +0 -495
  33. package/docs/components/docs/copy-page-menu.tsx +0 -364
  34. package/docs/components/docs/doc-header.tsx +0 -223
  35. package/docs/components/docs/doc-shell.tsx +0 -355
  36. package/docs/components/docs/doc-sidebar.tsx +0 -256
  37. package/docs/components/docs/doc-toc.tsx +0 -46
  38. package/docs/components/docs/mobile-nav.tsx +0 -195
  39. package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
  40. package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
  41. package/docs/components/git/repo-picker.tsx +0 -529
  42. package/docs/components/icons/doc-icon.tsx +0 -96
  43. package/docs/components/mdx/accordion.tsx +0 -83
  44. package/docs/components/mdx/agent-instructions.tsx +0 -17
  45. package/docs/components/mdx/badge.tsx +0 -79
  46. package/docs/components/mdx/callout.tsx +0 -88
  47. package/docs/components/mdx/card.tsx +0 -110
  48. package/docs/components/mdx/code-block.tsx +0 -80
  49. package/docs/components/mdx/code-group.tsx +0 -203
  50. package/docs/components/mdx/color.tsx +0 -87
  51. package/docs/components/mdx/columns.tsx +0 -25
  52. package/docs/components/mdx/expandable.tsx +0 -45
  53. package/docs/components/mdx/field-layout.tsx +0 -77
  54. package/docs/components/mdx/frame.tsx +0 -23
  55. package/docs/components/mdx/get-text-content.ts +0 -18
  56. package/docs/components/mdx/icon.tsx +0 -12
  57. package/docs/components/mdx/iframe.tsx +0 -62
  58. package/docs/components/mdx/index.tsx +0 -121
  59. package/docs/components/mdx/installer.tsx +0 -20
  60. package/docs/components/mdx/panel.tsx +0 -11
  61. package/docs/components/mdx/param-field.tsx +0 -56
  62. package/docs/components/mdx/preview.tsx +0 -36
  63. package/docs/components/mdx/prompt.tsx +0 -63
  64. package/docs/components/mdx/request-example.tsx +0 -27
  65. package/docs/components/mdx/response-field.tsx +0 -42
  66. package/docs/components/mdx/steps.tsx +0 -92
  67. package/docs/components/mdx/tabs.tsx +0 -193
  68. package/docs/components/mdx/tile.tsx +0 -43
  69. package/docs/components/mdx/tooltip.tsx +0 -71
  70. package/docs/components/mdx/tree.tsx +0 -120
  71. package/docs/components/mdx/type-table.tsx +0 -71
  72. package/docs/components/mdx/update.tsx +0 -44
  73. package/docs/components/mdx/video.tsx +0 -45
  74. package/docs/components/mdx/view.tsx +0 -66
  75. package/docs/components/posthog-provider.tsx +0 -42
  76. package/docs/components/providers.tsx +0 -15
  77. package/docs/components/tenant-analytics.tsx +0 -49
  78. package/docs/components/third-parties.tsx +0 -32
  79. package/docs/components/ui/badge.tsx +0 -61
  80. package/docs/components/ui/breadcrumb.tsx +0 -112
  81. package/docs/components/ui/button-group.tsx +0 -83
  82. package/docs/components/ui/button.tsx +0 -65
  83. package/docs/components/ui/card.tsx +0 -92
  84. package/docs/components/ui/command.tsx +0 -167
  85. package/docs/components/ui/copy-button.tsx +0 -129
  86. package/docs/components/ui/dialog.tsx +0 -146
  87. package/docs/components/ui/field.tsx +0 -237
  88. package/docs/components/ui/input.tsx +0 -23
  89. package/docs/components/ui/kbd.tsx +0 -98
  90. package/docs/components/ui/label.tsx +0 -22
  91. package/docs/components/ui/morph-icon.tsx +0 -79
  92. package/docs/components/ui/popover.tsx +0 -267
  93. package/docs/components/ui/search-dialog.tsx +0 -431
  94. package/docs/components/ui/search.tsx +0 -101
  95. package/docs/components/ui/separator.tsx +0 -26
  96. package/docs/components/ui/sheet.tsx +0 -133
  97. package/docs/components/ui/sidebar.tsx +0 -758
  98. package/docs/components/ui/skeleton.tsx +0 -11
  99. package/docs/components/ui/switch.tsx +0 -32
  100. package/docs/components/ui/tabs.tsx +0 -138
  101. package/docs/components/ui/theme-toggle.tsx +0 -62
  102. package/docs/components/ui/tooltip.tsx +0 -53
  103. package/docs/components/web-mcp.tsx +0 -115
  104. package/docs/lib/agent-skills.ts +0 -48
  105. package/docs/lib/api-client.ts +0 -72
  106. package/docs/lib/config.ts +0 -6
  107. package/docs/lib/content-root.ts +0 -33
  108. package/docs/lib/content-source.ts +0 -70
  109. package/docs/lib/contextual-options.ts +0 -222
  110. package/docs/lib/dashboard-session.ts +0 -167
  111. package/docs/lib/db.ts +0 -13
  112. package/docs/lib/docs-collection.ts +0 -7
  113. package/docs/lib/docs-runtime.tsx +0 -745
  114. package/docs/lib/edge-config.ts +0 -95
  115. package/docs/lib/env.ts +0 -23
  116. package/docs/lib/etag.ts +0 -22
  117. package/docs/lib/github-install.ts +0 -33
  118. package/docs/lib/llms-full.ts +0 -82
  119. package/docs/lib/marketing-markdown.ts +0 -79
  120. package/docs/lib/marketing-site.ts +0 -31
  121. package/docs/lib/mdx.ts +0 -98
  122. package/docs/lib/navigation.ts +0 -288
  123. package/docs/lib/openapi-proxy.ts +0 -88
  124. package/docs/lib/openapi.ts +0 -158
  125. package/docs/lib/platform-config.ts +0 -6
  126. package/docs/lib/project-authz.ts +0 -46
  127. package/docs/lib/routes.ts +0 -103
  128. package/docs/lib/server-cache.ts +0 -83
  129. package/docs/lib/shiki.ts +0 -44
  130. package/docs/lib/supabase.ts +0 -37
  131. package/docs/lib/tenancy.ts +0 -364
  132. package/docs/lib/tenant-headers.ts +0 -43
  133. package/docs/lib/tenant-static.ts +0 -705
  134. package/docs/lib/tenant-utility-context.ts +0 -62
  135. package/docs/lib/tenants.ts +0 -72
  136. package/docs/lib/theme.ts +0 -29
  137. package/docs/lib/time-ago.ts +0 -24
  138. package/docs/lib/toc.ts +0 -2
  139. package/docs/lib/use-mobile.ts +0 -19
  140. package/docs/lib/use-tab-observer.ts +0 -71
  141. package/docs/lib/utils.ts +0 -5
  142. package/packages/@repo/common/dist/index.d.ts +0 -16
  143. package/packages/@repo/common/dist/index.d.ts.map +0 -1
  144. package/packages/@repo/common/dist/index.js +0 -84
  145. package/packages/@repo/common/package.json +0 -34
  146. package/packages/@repo/common/src/index.ts +0 -101
  147. package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
  148. package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
  149. package/packages/@repo/contracts/dist/analytics.js +0 -18
  150. package/packages/@repo/contracts/dist/dates.d.ts +0 -4
  151. package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
  152. package/packages/@repo/contracts/dist/dates.js +0 -2
  153. package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
  154. package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
  155. package/packages/@repo/contracts/dist/deployment.js +0 -46
  156. package/packages/@repo/contracts/dist/domain.d.ts +0 -94
  157. package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
  158. package/packages/@repo/contracts/dist/domain.js +0 -36
  159. package/packages/@repo/contracts/dist/git.d.ts +0 -28
  160. package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
  161. package/packages/@repo/contracts/dist/git.js +0 -24
  162. package/packages/@repo/contracts/dist/ids.d.ts +0 -14
  163. package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
  164. package/packages/@repo/contracts/dist/ids.js +0 -11
  165. package/packages/@repo/contracts/dist/index.d.ts +0 -11
  166. package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
  167. package/packages/@repo/contracts/dist/index.js +0 -12
  168. package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
  169. package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
  170. package/packages/@repo/contracts/dist/pagination.js +0 -15
  171. package/packages/@repo/contracts/dist/project.d.ts +0 -42
  172. package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
  173. package/packages/@repo/contracts/dist/project.js +0 -25
  174. package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
  175. package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
  176. package/packages/@repo/contracts/dist/tenant.js +0 -58
  177. package/packages/@repo/contracts/dist/user.d.ts +0 -9
  178. package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
  179. package/packages/@repo/contracts/dist/user.js +0 -9
  180. package/packages/@repo/contracts/package.json +0 -37
  181. package/packages/@repo/contracts/src/analytics.ts +0 -33
  182. package/packages/@repo/contracts/src/dates.ts +0 -4
  183. package/packages/@repo/contracts/src/deployment.ts +0 -73
  184. package/packages/@repo/contracts/src/domain.ts +0 -51
  185. package/packages/@repo/contracts/src/git.ts +0 -31
  186. package/packages/@repo/contracts/src/ids.ts +0 -23
  187. package/packages/@repo/contracts/src/index.ts +0 -12
  188. package/packages/@repo/contracts/src/pagination.ts +0 -21
  189. package/packages/@repo/contracts/src/project.ts +0 -32
  190. package/packages/@repo/contracts/src/tenant.ts +0 -94
  191. package/packages/@repo/contracts/src/user.ts +0 -12
  192. package/packages/@repo/models/dist/docs-config.d.ts +0 -961
  193. package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
  194. package/packages/@repo/models/dist/docs-config.js +0 -531
  195. package/packages/@repo/models/dist/index.d.ts +0 -3
  196. package/packages/@repo/models/dist/index.d.ts.map +0 -1
  197. package/packages/@repo/models/dist/index.js +0 -3
  198. package/packages/@repo/models/dist/tenant.d.ts +0 -37
  199. package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
  200. package/packages/@repo/models/dist/tenant.js +0 -1
  201. package/packages/@repo/models/package.json +0 -37
  202. package/packages/@repo/models/src/docs-config.ts +0 -629
  203. package/packages/@repo/models/src/index.ts +0 -3
  204. package/packages/@repo/models/src/tenant.ts +0 -44
  205. package/packages/@repo/prebuild/dist/index.d.ts +0 -2
  206. package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
  207. package/packages/@repo/prebuild/dist/index.js +0 -2
  208. package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
  209. package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
  210. package/packages/@repo/prebuild/dist/openapi.js +0 -86
  211. package/packages/@repo/prebuild/package.json +0 -39
  212. package/packages/@repo/prebuild/src/index.ts +0 -2
  213. package/packages/@repo/prebuild/src/openapi.ts +0 -154
  214. package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
  215. package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
  216. package/packages/@repo/previewing/dist/blob-source.js +0 -128
  217. package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
  218. package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
  219. package/packages/@repo/previewing/dist/config-loader.js +0 -231
  220. package/packages/@repo/previewing/dist/constants.d.ts +0 -15
  221. package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
  222. package/packages/@repo/previewing/dist/constants.js +0 -14
  223. package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
  224. package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
  225. package/packages/@repo/previewing/dist/content-index.js +0 -291
  226. package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
  227. package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
  228. package/packages/@repo/previewing/dist/content-source.js +0 -1
  229. package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
  230. package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
  231. package/packages/@repo/previewing/dist/fs-source.js +0 -71
  232. package/packages/@repo/previewing/dist/index.d.ts +0 -16
  233. package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
  234. package/packages/@repo/previewing/dist/index.js +0 -13
  235. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
  236. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
  237. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
  238. package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
  239. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
  240. package/packages/@repo/previewing/dist/markdown/format.js +0 -43
  241. package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
  242. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
  243. package/packages/@repo/previewing/dist/markdown/links.js +0 -31
  244. package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
  245. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
  246. package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
  247. package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
  248. package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
  249. package/packages/@repo/previewing/dist/search-index.js +0 -23
  250. package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
  251. package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
  252. package/packages/@repo/previewing/dist/serialization.js +0 -108
  253. package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
  254. package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
  255. package/packages/@repo/previewing/dist/toc-index.js +0 -53
  256. package/packages/@repo/previewing/dist/types.d.ts +0 -92
  257. package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
  258. package/packages/@repo/previewing/dist/types.js +0 -1
  259. package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
  260. package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
  261. package/packages/@repo/previewing/dist/utility-index.js +0 -201
  262. package/packages/@repo/previewing/package.json +0 -41
  263. package/packages/@repo/previewing/src/blob-source.ts +0 -185
  264. package/packages/@repo/previewing/src/config-loader.ts +0 -316
  265. package/packages/@repo/previewing/src/constants.ts +0 -16
  266. package/packages/@repo/previewing/src/content-index.ts +0 -384
  267. package/packages/@repo/previewing/src/content-source.ts +0 -12
  268. package/packages/@repo/previewing/src/fs-source.ts +0 -103
  269. package/packages/@repo/previewing/src/index.ts +0 -71
  270. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
  271. package/packages/@repo/previewing/src/markdown/format.ts +0 -63
  272. package/packages/@repo/previewing/src/markdown/links.ts +0 -46
  273. package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
  274. package/packages/@repo/previewing/src/search-index.ts +0 -38
  275. package/packages/@repo/previewing/src/serialization.ts +0 -191
  276. package/packages/@repo/previewing/src/toc-index.ts +0 -72
  277. package/packages/@repo/previewing/src/types.ts +0 -105
  278. package/packages/@repo/previewing/src/utility-index.ts +0 -304
  279. package/packages/@repo/validation/dist/index.d.ts +0 -12
  280. package/packages/@repo/validation/dist/index.d.ts.map +0 -1
  281. package/packages/@repo/validation/dist/index.js +0 -30
  282. package/packages/@repo/validation/package.json +0 -38
  283. package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
  284. package/packages/@repo/validation/src/index.ts +0 -59
  285. package/scripts/prepare-package.mjs +0 -53
  286. package/scripts/repo-packages.mjs +0 -8
@@ -1,384 +0,0 @@
1
- import path from "node:path";
2
-
3
- import { normalizePath } from "@repo/common";
4
- import type {
5
- CollectionConfig,
6
- ContentType,
7
- FrontmatterByType,
8
- PageMode,
9
- SiteConfig,
10
- } from "@repo/models";
11
- import { PageModeSchema } from "@repo/models";
12
- import { validateFrontmatter } from "@repo/validation";
13
-
14
- import type { ContentSource } from "./content-source.js";
15
- import { parseFrontmatter } from "./markdown/format.js";
16
- import type { ContentEntry, ContentIndex, PageMetadata } from "./types.js";
17
-
18
- const validModes = new Set<string>(PageModeSchema.options);
19
-
20
- export const buildPageMetadataMap = (
21
- index: ContentIndex
22
- ): Map<string, PageMetadata> => {
23
- const map = new Map<string, PageMetadata>();
24
- for (const entry of index.entries) {
25
- if (entry.kind !== "entry") {
26
- continue;
27
- }
28
- const fm = entry.frontmatter as Record<string, unknown>;
29
- const meta: PageMetadata = {
30
- title: entry.title,
31
- };
32
- if (typeof fm.sidebarTitle === "string") {
33
- meta.sidebarTitle = fm.sidebarTitle;
34
- }
35
- if (typeof fm.icon === "string") {
36
- meta.icon = fm.icon;
37
- }
38
- if (typeof fm.iconType === "string") {
39
- meta.iconType = fm.iconType;
40
- }
41
- if (typeof fm.tag === "string") {
42
- meta.tag = fm.tag;
43
- }
44
- if (typeof fm.hidden === "boolean") {
45
- meta.hidden = fm.hidden;
46
- }
47
- if (typeof fm.deprecated === "boolean") {
48
- meta.deprecated = fm.deprecated;
49
- }
50
- if (typeof fm.url === "string") {
51
- meta.url = fm.url;
52
- }
53
- if (typeof fm.mode === "string" && validModes.has(fm.mode)) {
54
- meta.mode = fm.mode as PageMode;
55
- }
56
- if (typeof fm.noindex === "boolean") {
57
- meta.noindex = fm.noindex;
58
- }
59
- if (typeof fm.hideFooterPagination === "boolean") {
60
- meta.hideFooterPagination = fm.hideFooterPagination;
61
- }
62
- if (typeof fm.hideApiMarker === "boolean") {
63
- meta.hideApiMarker = fm.hideApiMarker;
64
- }
65
- if (Array.isArray(fm.keywords)) {
66
- meta.keywords = fm.keywords as string[];
67
- }
68
- map.set(entry.slug, meta);
69
- }
70
- return map;
71
- };
72
-
73
- const DOC_FILE_EXTENSION_REGEX = /\.(mdx|md)$/;
74
- const INDEX_SUFFIX = "/index";
75
-
76
- const titleFromSlug = (slug: string) => {
77
- const clean = slug.replaceAll("-", " ").split("/").pop() ?? slug;
78
- if (clean === "index") {
79
- return "Overview";
80
- }
81
- return clean.replaceAll(/\b\w/g, (char) => char.toUpperCase());
82
- };
83
-
84
- const slugFromFile = (relativePath: string) => {
85
- const clean = normalizePath(relativePath);
86
- const withoutExt = clean.replace(DOC_FILE_EXTENSION_REGEX, "");
87
- if (withoutExt.endsWith(INDEX_SUFFIX)) {
88
- const trimmed = withoutExt.slice(0, -INDEX_SUFFIX.length);
89
- return trimmed.length ? trimmed : "index";
90
- }
91
- return withoutExt.length ? withoutExt : "index";
92
- };
93
-
94
- const listContentFiles = async (source: ContentSource, directory: string) => {
95
- const files = await source.listFiles(directory);
96
- return files.filter((file: string) => DOC_FILE_EXTENSION_REGEX.test(file));
97
- };
98
-
99
- const sortDefaults: Record<
100
- ContentType,
101
- { field: "date" | "order" | "title" | "price"; direction: "asc" | "desc" }
102
- > = {
103
- blog: { direction: "desc", field: "date" },
104
- courses: { direction: "asc", field: "order" },
105
- docs: { direction: "asc", field: "title" },
106
- forms: { direction: "asc", field: "title" },
107
- notes: { direction: "desc", field: "date" },
108
- products: { direction: "asc", field: "title" },
109
- sheets: { direction: "asc", field: "title" },
110
- site: { direction: "asc", field: "title" },
111
- slides: { direction: "asc", field: "title" },
112
- todos: { direction: "desc", field: "date" },
113
- };
114
-
115
- const normalizeSortValue = (value: unknown) => {
116
- if (typeof value === "number") {
117
- return value;
118
- }
119
- if (typeof value === "string") {
120
- const timestamp = Date.parse(value);
121
- if (!Number.isNaN(timestamp)) {
122
- return timestamp;
123
- }
124
- return value.toLowerCase();
125
- }
126
- return null;
127
- };
128
-
129
- const compareValues = (a: unknown, b: unknown, direction: "asc" | "desc") => {
130
- const left = normalizeSortValue(a);
131
- const right = normalizeSortValue(b);
132
- if (left === null && right === null) {
133
- return 0;
134
- }
135
- if (left === null) {
136
- return 1;
137
- }
138
- if (right === null) {
139
- return -1;
140
- }
141
- const multiplier = direction === "desc" ? -1 : 1;
142
- if (typeof left === "number" && typeof right === "number") {
143
- return (left - right) * multiplier;
144
- }
145
- if (left < right) {
146
- return -1 * multiplier;
147
- }
148
- if (left > right) {
149
- return 1 * multiplier;
150
- }
151
- return 0;
152
- };
153
-
154
- const autoIndexTypes = new Set<ContentType>([
155
- "blog",
156
- "courses",
157
- "products",
158
- "notes",
159
- "forms",
160
- "sheets",
161
- "slides",
162
- "todos",
163
- ]);
164
-
165
- const getCollectionIndex = (
166
- collection: CollectionConfig,
167
- slugPrefix: string
168
- ) => {
169
- if (collection.index) {
170
- return collection.index;
171
- }
172
- if (autoIndexTypes.has(collection.type)) {
173
- const slug = slugPrefix || collection.id;
174
- return {
175
- slug,
176
- title: titleFromSlug(slug),
177
- };
178
- }
179
- return null;
180
- };
181
-
182
- const addEntry = (
183
- entry: ContentEntry,
184
- index: ContentIndex,
185
- errors: string[]
186
- ) => {
187
- if (index.bySlug.has(entry.slug)) {
188
- errors.push(`slug "${entry.slug}" is defined more than once`);
189
- return;
190
- }
191
- index.entries.push(entry);
192
- index.bySlug.set(entry.slug, entry);
193
- };
194
-
195
- const resolveEntrySlug = (relativeSlug: string, slugPrefix: string) => {
196
- if (!slugPrefix) {
197
- return relativeSlug;
198
- }
199
-
200
- if (relativeSlug === "index") {
201
- return slugPrefix;
202
- }
203
-
204
- return normalizePath(`${slugPrefix}/${relativeSlug}`);
205
- };
206
-
207
- const buildEntryFromFile = async ({
208
- collection,
209
- errors,
210
- file,
211
- root,
212
- slugPrefix,
213
- source,
214
- }: {
215
- collection: CollectionConfig;
216
- errors: string[];
217
- file: string;
218
- root: string;
219
- slugPrefix: string;
220
- source: ContentSource;
221
- }): Promise<Extract<ContentEntry, { kind: "entry" }> | null> => {
222
- const sourcePath = root
223
- ? normalizePath(path.join(root, file))
224
- : normalizePath(file);
225
-
226
- let entrySource = "";
227
- try {
228
- entrySource = await source.readFile(sourcePath);
229
- } catch (error) {
230
- errors.push(
231
- error instanceof Error ? error.message : `Failed to read ${sourcePath}`
232
- );
233
- return null;
234
- }
235
-
236
- const { frontmatter } = parseFrontmatter(entrySource);
237
- const frontmatterResult = validateFrontmatter(collection.type, frontmatter);
238
- if (!frontmatterResult.success) {
239
- for (const issue of frontmatterResult.errors) {
240
- errors.push(`${sourcePath}: ${issue}`);
241
- }
242
- }
243
-
244
- const resolvedFrontmatter = frontmatterResult.success
245
- ? frontmatterResult.data
246
- : (frontmatter as FrontmatterByType[ContentType]);
247
- const relativeSlug = slugFromFile(file);
248
- const slug = resolveEntrySlug(relativeSlug, slugPrefix);
249
- const title =
250
- typeof resolvedFrontmatter?.title === "string"
251
- ? resolvedFrontmatter.title
252
- : titleFromSlug(slug);
253
- const description =
254
- typeof resolvedFrontmatter?.description === "string"
255
- ? resolvedFrontmatter.description
256
- : undefined;
257
-
258
- const hidden =
259
- typeof resolvedFrontmatter?.hidden === "boolean"
260
- ? resolvedFrontmatter.hidden
261
- : undefined;
262
-
263
- return {
264
- collectionId: collection.id,
265
- description,
266
- frontmatter: resolvedFrontmatter,
267
- hidden: hidden || undefined,
268
- kind: "entry",
269
- relativePath: sourcePath,
270
- slug,
271
- sourcePath,
272
- title,
273
- type: collection.type,
274
- };
275
- };
276
-
277
- export const buildContentIndex = async (
278
- source: ContentSource,
279
- config: SiteConfig
280
- ): Promise<ContentIndex> => {
281
- const errors: string[] = [];
282
- const index: ContentIndex = {
283
- byCollection: new Map<string, ContentEntry[]>(),
284
- bySlug: new Map<string, ContentEntry>(),
285
- entries: [],
286
- errors,
287
- };
288
-
289
- for (const collection of config.collections) {
290
- const root = normalizePath(collection.root ?? "");
291
- const slugPrefix = normalizePath(collection.slugPrefix ?? "");
292
- let files: string[] = [];
293
- try {
294
- files = await listContentFiles(source, root);
295
- } catch (error) {
296
- errors.push(
297
- error instanceof Error ? error.message : `Failed to read ${root || "."}`
298
- );
299
- continue;
300
- }
301
-
302
- const collectionEntries: ContentEntry[] = [];
303
-
304
- const resolvedEntries = await Promise.all(
305
- files.map(
306
- async (file) =>
307
- await buildEntryFromFile({
308
- collection,
309
- errors,
310
- file,
311
- root,
312
- slugPrefix,
313
- source,
314
- })
315
- )
316
- );
317
-
318
- for (const entry of resolvedEntries) {
319
- if (!entry) {
320
- continue;
321
- }
322
-
323
- collectionEntries.push(entry);
324
- addEntry(entry, index, errors);
325
- }
326
-
327
- const sortConfig = {
328
- ...sortDefaults[collection.type],
329
- ...collection.sort,
330
- };
331
- const sortField = sortConfig.field ?? "title";
332
- const sortDirection = sortConfig.direction ?? "asc";
333
- collectionEntries.sort((left, right) => {
334
- const leftValue =
335
- left.kind === "entry"
336
- ? (left.frontmatter as Record<string, unknown>)[sortField]
337
- : undefined;
338
- const rightValue =
339
- right.kind === "entry"
340
- ? (right.frontmatter as Record<string, unknown>)[sortField]
341
- : undefined;
342
- return compareValues(leftValue, rightValue, sortDirection);
343
- });
344
-
345
- index.byCollection.set(collection.id, collectionEntries);
346
-
347
- const collectionIndex = getCollectionIndex(collection, slugPrefix);
348
- if (collectionIndex) {
349
- const indexEntry: ContentEntry = {
350
- collectionId: collection.id,
351
- description: collectionIndex.description,
352
- kind: "index",
353
- slug: collectionIndex.slug,
354
- title: collectionIndex.title ?? titleFromSlug(collectionIndex.slug),
355
- type: collection.type,
356
- };
357
- addEntry(indexEntry, index, errors);
358
- }
359
- }
360
-
361
- return index;
362
- };
363
-
364
- export const shouldIncludeSearchEntry = (
365
- entry: ContentEntry,
366
- pageMetadataMap: Map<string, PageMetadata>,
367
- config: SiteConfig
368
- ) => {
369
- const pageMeta = pageMetadataMap.get(entry.slug);
370
-
371
- if (pageMeta?.hidden || pageMeta?.noindex) {
372
- return false;
373
- }
374
-
375
- if (
376
- config.seo?.indexing !== "all" &&
377
- entry.kind === "entry" &&
378
- entry.hidden === true
379
- ) {
380
- return false;
381
- }
382
-
383
- return true;
384
- };
@@ -1,12 +0,0 @@
1
- export interface CompiledMdxResult {
2
- compiledSource: string;
3
- version: number;
4
- }
5
-
6
- export interface ContentSource {
7
- readFile(relativePath: string): Promise<string>;
8
- listFiles(directory: string): Promise<string[]>;
9
- exists(relativePath: string): Promise<boolean>;
10
- resolveUrl?(relativePath: string): Promise<string | null> | string | null;
11
- readCompiledMdx?(relativePath: string): Promise<CompiledMdxResult | null>;
12
- }
@@ -1,103 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
-
4
- import { normalizePath, shouldIgnoreRootDocsFile } from "@repo/common";
5
-
6
- import type { ContentSource } from "./content-source.js";
7
-
8
- const IGNORED_DIRECTORIES = new Set(["app", "lib", "node_modules", "public"]);
9
-
10
- const isNotFoundError = (error: unknown) =>
11
- Boolean(
12
- error &&
13
- typeof error === "object" &&
14
- "code" in error &&
15
- (error as { code?: string }).code === "ENOENT"
16
- );
17
-
18
- const isWithinRoot = (root: string, candidate: string) =>
19
- candidate === root || candidate.startsWith(`${root}${path.sep}`);
20
-
21
- const resolveWithinRoot = (root: string, relativePath: string) => {
22
- const normalized = normalizePath(relativePath);
23
- const absolutePath = path.resolve(root, normalized);
24
-
25
- if (!isWithinRoot(root, absolutePath)) {
26
- throw new Error(`Path "${relativePath}" escapes the content source root.`);
27
- }
28
-
29
- return absolutePath;
30
- };
31
-
32
- const walkFiles = async (
33
- directory: string,
34
- prefix: string
35
- ): Promise<string[]> => {
36
- const entries = await fs.readdir(directory, { withFileTypes: true });
37
- const files: string[] = [];
38
-
39
- for (const entry of entries) {
40
- if (entry.name.startsWith(".")) {
41
- continue;
42
- }
43
-
44
- const absolutePath = path.join(directory, entry.name);
45
- const relativePath = prefix ? path.join(prefix, entry.name) : entry.name;
46
-
47
- if (entry.isDirectory()) {
48
- if (IGNORED_DIRECTORIES.has(entry.name)) {
49
- continue;
50
- }
51
- files.push(...(await walkFiles(absolutePath, relativePath)));
52
- continue;
53
- }
54
-
55
- if (entry.isFile()) {
56
- if (!prefix && shouldIgnoreRootDocsFile(entry.name)) {
57
- continue;
58
- }
59
- files.push(normalizePath(relativePath));
60
- }
61
- }
62
-
63
- return files;
64
- };
65
-
66
- export class FsContentSource implements ContentSource {
67
- private readonly root: string;
68
-
69
- constructor(root: string) {
70
- this.root = path.resolve(root);
71
- }
72
-
73
- async readFile(relativePath: string): Promise<string> {
74
- return await fs.readFile(
75
- resolveWithinRoot(this.root, relativePath),
76
- "utf8"
77
- );
78
- }
79
-
80
- async listFiles(directory: string): Promise<string[]> {
81
- return await walkFiles(resolveWithinRoot(this.root, directory), "");
82
- }
83
-
84
- async exists(relativePath: string): Promise<boolean> {
85
- try {
86
- await fs.access(resolveWithinRoot(this.root, relativePath));
87
- return true;
88
- } catch (error) {
89
- if (isNotFoundError(error)) {
90
- return false;
91
- }
92
- throw error;
93
- }
94
- }
95
-
96
- // oxlint-disable-next-line eslint/class-methods-use-this
97
- resolveUrl(): string | null {
98
- return null;
99
- }
100
- }
101
-
102
- export const createFsSource = (root: string): ContentSource =>
103
- new FsContentSource(root);
@@ -1,71 +0,0 @@
1
- export { BlobContentSource, createBlobSource } from "./blob-source.js";
2
- export {
3
- getDocsCollection,
4
- getDocsCollectionWithNavigation,
5
- getDocsNavigation,
6
- loadSiteConfig,
7
- } from "./config-loader.js";
8
- export {
9
- LEGACY_PROJECT_NAME_FALLBACK_WARNING,
10
- PREBUILT_INDEX_PATH,
11
- PREBUILT_OPENAPI_INDEX_PATH,
12
- PREBUILT_SEARCH_INDEX_PATH,
13
- PREBUILT_TOC_INDEX_PATH,
14
- PREBUILT_UTILITY_INDEX_PATH,
15
- PREBUILT_UTILITY_LLMS_FULL_PATH,
16
- PREBUILT_UTILITY_LLMS_PATH,
17
- PREBUILT_UTILITY_LLMS_SEGMENT_PREFIX,
18
- PREBUILT_UTILITY_SITEMAP_PATH,
19
- PREBUILT_UTILITY_SKILLS_INDEX_PATH,
20
- PREBUILT_UTILITY_SKILLS_MD_PREFIX,
21
- UTILITY_DOCS_ROOT_TOKEN,
22
- } from "./constants.js";
23
- export { buildContentIndex, buildPageMetadataMap } from "./content-index.js";
24
- export type { CompiledMdxResult, ContentSource } from "./content-source.js";
25
- export { createFsSource, FsContentSource } from "./fs-source.js";
26
- export {
27
- prepareLlmsFullContent,
28
- toAgentMarkdown,
29
- } from "./markdown/agent-markdown.js";
30
- export {
31
- formatMarkdownPage,
32
- formatMarkdownPageSection,
33
- stripFrontmatter,
34
- } from "./markdown/format.js";
35
- export {
36
- absolutiseInternalLinks,
37
- sanitizePlaceholderUrls,
38
- } from "./markdown/links.js";
39
- export { formatOpenApiPageContent } from "./openapi-pages.js";
40
- export { buildSearchIndex } from "./search-index.js";
41
- export {
42
- loadPrebuiltContentIndex,
43
- loadPrebuiltOpenApiIndex,
44
- loadPrebuiltSearchIndex,
45
- loadPrebuiltTocIndex,
46
- loadPrebuiltUtilityIndex,
47
- serializeContentIndex,
48
- serializeOpenApiIndex,
49
- serializeSearchIndex,
50
- serializeTocIndex,
51
- serializeUtilityIndex,
52
- } from "./serialization.js";
53
- export { buildTocIndex, extractToc } from "./toc-index.js";
54
- export type {
55
- ContentEntry,
56
- ContentIndex,
57
- PageMetadata,
58
- PrebuiltOpenApiEntry,
59
- SearchIndexItem,
60
- SiteConfigResult,
61
- TocItem,
62
- UtilityArtifact,
63
- UtilityIndex,
64
- UtilityPage,
65
- UtilitySegment,
66
- } from "./types.js";
67
- export {
68
- buildUtilityArtifacts,
69
- buildUtilityIndex,
70
- getPrebuiltUtilityLlmPagePath,
71
- } from "./utility-index.js";