svedocs 0.1.0-beta.10

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/LICENSE +5 -0
  2. package/README.md +85 -0
  3. package/dist/ai/openai-compatible.d.ts +13 -0
  4. package/dist/ai/openai-compatible.d.ts.map +1 -0
  5. package/dist/ai/openai-compatible.js +92 -0
  6. package/dist/ai/providers.d.ts +20 -0
  7. package/dist/ai/providers.d.ts.map +1 -0
  8. package/dist/ai/providers.js +185 -0
  9. package/dist/ai/rate-limit.d.ts +18 -0
  10. package/dist/ai/rate-limit.d.ts.map +1 -0
  11. package/dist/ai/rate-limit.js +52 -0
  12. package/dist/ai/response.d.ts +4 -0
  13. package/dist/ai/response.d.ts.map +1 -0
  14. package/dist/ai/response.js +151 -0
  15. package/dist/ai/runtime.d.ts +32 -0
  16. package/dist/ai/runtime.d.ts.map +1 -0
  17. package/dist/ai/runtime.js +111 -0
  18. package/dist/ai/types.d.ts +93 -0
  19. package/dist/ai/types.d.ts.map +1 -0
  20. package/dist/ai/types.js +1 -0
  21. package/dist/ai.d.ts +7 -0
  22. package/dist/ai.d.ts.map +1 -0
  23. package/dist/ai.js +6 -0
  24. package/dist/ambient.d.ts +5 -0
  25. package/dist/cloudflare.d.ts +29 -0
  26. package/dist/cloudflare.d.ts.map +1 -0
  27. package/dist/cloudflare.js +149 -0
  28. package/dist/config.d.ts +373 -0
  29. package/dist/config.d.ts.map +1 -0
  30. package/dist/config.js +299 -0
  31. package/dist/core/checks.d.ts +4 -0
  32. package/dist/core/checks.d.ts.map +1 -0
  33. package/dist/core/checks.js +267 -0
  34. package/dist/core/config.d.ts +6 -0
  35. package/dist/core/config.d.ts.map +1 -0
  36. package/dist/core/config.js +178 -0
  37. package/dist/core/content.d.ts +7 -0
  38. package/dist/core/content.d.ts.map +1 -0
  39. package/dist/core/content.js +340 -0
  40. package/dist/core/i18n.d.ts +5 -0
  41. package/dist/core/i18n.d.ts.map +1 -0
  42. package/dist/core/i18n.js +117 -0
  43. package/dist/core/links.d.ts +5 -0
  44. package/dist/core/links.d.ts.map +1 -0
  45. package/dist/core/links.js +60 -0
  46. package/dist/core/messages.d.ts +149 -0
  47. package/dist/core/messages.d.ts.map +1 -0
  48. package/dist/core/messages.js +163 -0
  49. package/dist/core/navigation.d.ts +5 -0
  50. package/dist/core/navigation.d.ts.map +1 -0
  51. package/dist/core/navigation.js +144 -0
  52. package/dist/core/routes.d.ts +36 -0
  53. package/dist/core/routes.d.ts.map +1 -0
  54. package/dist/core/routes.js +152 -0
  55. package/dist/core/search.d.ts +5 -0
  56. package/dist/core/search.d.ts.map +1 -0
  57. package/dist/core/search.js +41 -0
  58. package/dist/core/types.d.ts +468 -0
  59. package/dist/core/types.d.ts.map +1 -0
  60. package/dist/core/types.js +4 -0
  61. package/dist/core/utils.d.ts +13 -0
  62. package/dist/core/utils.d.ts.map +1 -0
  63. package/dist/core/utils.js +60 -0
  64. package/dist/core.d.ts +9 -0
  65. package/dist/core.d.ts.map +1 -0
  66. package/dist/core.js +8 -0
  67. package/dist/index.d.ts +6 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +3 -0
  70. package/dist/mdx/ast.d.ts +32 -0
  71. package/dist/mdx/ast.d.ts.map +1 -0
  72. package/dist/mdx/ast.js +148 -0
  73. package/dist/mdx/code.d.ts +17 -0
  74. package/dist/mdx/code.d.ts.map +1 -0
  75. package/dist/mdx/code.js +327 -0
  76. package/dist/mdx/compile.d.ts +29 -0
  77. package/dist/mdx/compile.d.ts.map +1 -0
  78. package/dist/mdx/compile.js +59 -0
  79. package/dist/mdx/diff.d.ts +9 -0
  80. package/dist/mdx/diff.d.ts.map +1 -0
  81. package/dist/mdx/diff.js +171 -0
  82. package/dist/mdx/headings.d.ts +4 -0
  83. package/dist/mdx/headings.d.ts.map +1 -0
  84. package/dist/mdx/headings.js +42 -0
  85. package/dist/mdx/links.d.ts +4 -0
  86. package/dist/mdx/links.d.ts.map +1 -0
  87. package/dist/mdx/links.js +144 -0
  88. package/dist/mdx/utils.d.ts +10 -0
  89. package/dist/mdx/utils.d.ts.map +1 -0
  90. package/dist/mdx/utils.js +64 -0
  91. package/dist/og/image.d.ts +25 -0
  92. package/dist/og/image.d.ts.map +1 -0
  93. package/dist/og/image.js +224 -0
  94. package/dist/og/metadata.d.ts +7 -0
  95. package/dist/og/metadata.d.ts.map +1 -0
  96. package/dist/og/metadata.js +198 -0
  97. package/dist/og/response.d.ts +4 -0
  98. package/dist/og/response.d.ts.map +1 -0
  99. package/dist/og/response.js +49 -0
  100. package/dist/og/rss.d.ts +4 -0
  101. package/dist/og/rss.d.ts.map +1 -0
  102. package/dist/og/rss.js +96 -0
  103. package/dist/og/sitemap.d.ts +7 -0
  104. package/dist/og/sitemap.d.ts.map +1 -0
  105. package/dist/og/sitemap.js +90 -0
  106. package/dist/og/types.d.ts +65 -0
  107. package/dist/og/types.d.ts.map +1 -0
  108. package/dist/og/types.js +1 -0
  109. package/dist/og.d.ts +6 -0
  110. package/dist/og.d.ts.map +1 -0
  111. package/dist/og.js +5 -0
  112. package/dist/routes.d.ts +2 -0
  113. package/dist/routes.d.ts.map +1 -0
  114. package/dist/routes.js +1 -0
  115. package/dist/search/algolia.d.ts +10 -0
  116. package/dist/search/algolia.d.ts.map +1 -0
  117. package/dist/search/algolia.js +82 -0
  118. package/dist/search/cloudflare-sync.d.ts +5 -0
  119. package/dist/search/cloudflare-sync.d.ts.map +1 -0
  120. package/dist/search/cloudflare-sync.js +169 -0
  121. package/dist/search/cloudflare.d.ts +11 -0
  122. package/dist/search/cloudflare.d.ts.map +1 -0
  123. package/dist/search/cloudflare.js +126 -0
  124. package/dist/search/local.d.ts +9 -0
  125. package/dist/search/local.d.ts.map +1 -0
  126. package/dist/search/local.js +165 -0
  127. package/dist/search/runtime.d.ts +41 -0
  128. package/dist/search/runtime.d.ts.map +1 -0
  129. package/dist/search/runtime.js +152 -0
  130. package/dist/search/types.d.ts +172 -0
  131. package/dist/search/types.d.ts.map +1 -0
  132. package/dist/search/types.js +1 -0
  133. package/dist/search/typesense.d.ts +11 -0
  134. package/dist/search/typesense.d.ts.map +1 -0
  135. package/dist/search/typesense.js +91 -0
  136. package/dist/search/utils.d.ts +11 -0
  137. package/dist/search/utils.d.ts.map +1 -0
  138. package/dist/search/utils.js +93 -0
  139. package/dist/search.d.ts +8 -0
  140. package/dist/search.d.ts.map +1 -0
  141. package/dist/search.js +7 -0
  142. package/dist/svelte.d.ts +27 -0
  143. package/dist/svelte.d.ts.map +1 -0
  144. package/dist/svelte.js +45 -0
  145. package/dist/testing.d.ts +3 -0
  146. package/dist/testing.d.ts.map +1 -0
  147. package/dist/testing.js +23 -0
  148. package/dist/theme/Article.svelte +145 -0
  149. package/dist/theme/Article.svelte.d.ts +36 -0
  150. package/dist/theme/Article.svelte.d.ts.map +1 -0
  151. package/dist/theme/AskAiPanel.svelte +241 -0
  152. package/dist/theme/AskAiPanel.svelte.d.ts +31 -0
  153. package/dist/theme/AskAiPanel.svelte.d.ts.map +1 -0
  154. package/dist/theme/Brand.svelte +19 -0
  155. package/dist/theme/Brand.svelte.d.ts +22 -0
  156. package/dist/theme/Brand.svelte.d.ts.map +1 -0
  157. package/dist/theme/Button.svelte +34 -0
  158. package/dist/theme/Button.svelte.d.ts +41 -0
  159. package/dist/theme/Button.svelte.d.ts.map +1 -0
  160. package/dist/theme/Checkbox.svelte +63 -0
  161. package/dist/theme/Checkbox.svelte.d.ts +45 -0
  162. package/dist/theme/Checkbox.svelte.d.ts.map +1 -0
  163. package/dist/theme/CodeBlock.svelte +6 -0
  164. package/dist/theme/CodeBlock.svelte.d.ts +22 -0
  165. package/dist/theme/CodeBlock.svelte.d.ts.map +1 -0
  166. package/dist/theme/DocPage.svelte +15 -0
  167. package/dist/theme/DocPage.svelte.d.ts +33 -0
  168. package/dist/theme/DocPage.svelte.d.ts.map +1 -0
  169. package/dist/theme/DocsApp.svelte +194 -0
  170. package/dist/theme/DocsApp.svelte.d.ts +60 -0
  171. package/dist/theme/DocsApp.svelte.d.ts.map +1 -0
  172. package/dist/theme/DocsLayout.svelte +99 -0
  173. package/dist/theme/DocsLayout.svelte.d.ts +39 -0
  174. package/dist/theme/DocsLayout.svelte.d.ts.map +1 -0
  175. package/dist/theme/DocsShell.svelte +91 -0
  176. package/dist/theme/DocsShell.svelte.d.ts +34 -0
  177. package/dist/theme/DocsShell.svelte.d.ts.map +1 -0
  178. package/dist/theme/ErrorPage.svelte +113 -0
  179. package/dist/theme/ErrorPage.svelte.d.ts +34 -0
  180. package/dist/theme/ErrorPage.svelte.d.ts.map +1 -0
  181. package/dist/theme/FloatingToolbar.svelte +8 -0
  182. package/dist/theme/FloatingToolbar.svelte.d.ts +22 -0
  183. package/dist/theme/FloatingToolbar.svelte.d.ts.map +1 -0
  184. package/dist/theme/Footer.svelte +18 -0
  185. package/dist/theme/Footer.svelte.d.ts +24 -0
  186. package/dist/theme/Footer.svelte.d.ts.map +1 -0
  187. package/dist/theme/FooterLinks.svelte +37 -0
  188. package/dist/theme/FooterLinks.svelte.d.ts +22 -0
  189. package/dist/theme/FooterLinks.svelte.d.ts.map +1 -0
  190. package/dist/theme/FormField.svelte +41 -0
  191. package/dist/theme/FormField.svelte.d.ts +35 -0
  192. package/dist/theme/FormField.svelte.d.ts.map +1 -0
  193. package/dist/theme/HomePage.svelte +284 -0
  194. package/dist/theme/HomePage.svelte.d.ts +65 -0
  195. package/dist/theme/HomePage.svelte.d.ts.map +1 -0
  196. package/dist/theme/Input.svelte +36 -0
  197. package/dist/theme/Input.svelte.d.ts +34 -0
  198. package/dist/theme/Input.svelte.d.ts.map +1 -0
  199. package/dist/theme/LayoutShell.svelte +120 -0
  200. package/dist/theme/LayoutShell.svelte.d.ts +43 -0
  201. package/dist/theme/LayoutShell.svelte.d.ts.map +1 -0
  202. package/dist/theme/LocalizedLink.svelte +21 -0
  203. package/dist/theme/LocalizedLink.svelte.d.ts +38 -0
  204. package/dist/theme/LocalizedLink.svelte.d.ts.map +1 -0
  205. package/dist/theme/MobileNav.svelte +20 -0
  206. package/dist/theme/MobileNav.svelte.d.ts +26 -0
  207. package/dist/theme/MobileNav.svelte.d.ts.map +1 -0
  208. package/dist/theme/Navbar.svelte +69 -0
  209. package/dist/theme/Navbar.svelte.d.ts +29 -0
  210. package/dist/theme/Navbar.svelte.d.ts.map +1 -0
  211. package/dist/theme/PageLayout.svelte +49 -0
  212. package/dist/theme/PageLayout.svelte.d.ts +34 -0
  213. package/dist/theme/PageLayout.svelte.d.ts.map +1 -0
  214. package/dist/theme/PageShell.svelte +98 -0
  215. package/dist/theme/PageShell.svelte.d.ts +35 -0
  216. package/dist/theme/PageShell.svelte.d.ts.map +1 -0
  217. package/dist/theme/PageTools.svelte +87 -0
  218. package/dist/theme/PageTools.svelte.d.ts +25 -0
  219. package/dist/theme/PageTools.svelte.d.ts.map +1 -0
  220. package/dist/theme/RenderError.svelte +62 -0
  221. package/dist/theme/RenderError.svelte.d.ts +31 -0
  222. package/dist/theme/RenderError.svelte.d.ts.map +1 -0
  223. package/dist/theme/RootLayout.svelte +274 -0
  224. package/dist/theme/RootLayout.svelte.d.ts +47 -0
  225. package/dist/theme/RootLayout.svelte.d.ts.map +1 -0
  226. package/dist/theme/RouteRenderError.svelte +53 -0
  227. package/dist/theme/RouteRenderError.svelte.d.ts +34 -0
  228. package/dist/theme/RouteRenderError.svelte.d.ts.map +1 -0
  229. package/dist/theme/SafeRenderError.svelte +49 -0
  230. package/dist/theme/SafeRenderError.svelte.d.ts +33 -0
  231. package/dist/theme/SafeRenderError.svelte.d.ts.map +1 -0
  232. package/dist/theme/ScopeSwitcher.svelte +107 -0
  233. package/dist/theme/ScopeSwitcher.svelte.d.ts +26 -0
  234. package/dist/theme/ScopeSwitcher.svelte.d.ts.map +1 -0
  235. package/dist/theme/SearchDialog.svelte +200 -0
  236. package/dist/theme/SearchDialog.svelte.d.ts +31 -0
  237. package/dist/theme/SearchDialog.svelte.d.ts.map +1 -0
  238. package/dist/theme/Select.svelte +37 -0
  239. package/dist/theme/Select.svelte.d.ts +42 -0
  240. package/dist/theme/Select.svelte.d.ts.map +1 -0
  241. package/dist/theme/SidebarTree.svelte +148 -0
  242. package/dist/theme/SidebarTree.svelte.d.ts +24 -0
  243. package/dist/theme/SidebarTree.svelte.d.ts.map +1 -0
  244. package/dist/theme/SocialNav.svelte +17 -0
  245. package/dist/theme/SocialNav.svelte.d.ts +22 -0
  246. package/dist/theme/SocialNav.svelte.d.ts.map +1 -0
  247. package/dist/theme/TableOfContents.svelte +73 -0
  248. package/dist/theme/TableOfContents.svelte.d.ts +25 -0
  249. package/dist/theme/TableOfContents.svelte.d.ts.map +1 -0
  250. package/dist/theme/Textarea.svelte +33 -0
  251. package/dist/theme/Textarea.svelte.d.ts +33 -0
  252. package/dist/theme/Textarea.svelte.d.ts.map +1 -0
  253. package/dist/theme/ThemeInit.svelte +16 -0
  254. package/dist/theme/ThemeInit.svelte.d.ts +23 -0
  255. package/dist/theme/ThemeInit.svelte.d.ts.map +1 -0
  256. package/dist/theme/ThemeToggle.svelte +37 -0
  257. package/dist/theme/ThemeToggle.svelte.d.ts +23 -0
  258. package/dist/theme/ThemeToggle.svelte.d.ts.map +1 -0
  259. package/dist/theme/TopNav.svelte +23 -0
  260. package/dist/theme/TopNav.svelte.d.ts +22 -0
  261. package/dist/theme/TopNav.svelte.d.ts.map +1 -0
  262. package/dist/theme/base.css +240 -0
  263. package/dist/theme/defaults.d.ts +4 -0
  264. package/dist/theme/defaults.d.ts.map +1 -0
  265. package/dist/theme/defaults.js +55 -0
  266. package/dist/theme/forms.d.ts +4 -0
  267. package/dist/theme/forms.d.ts.map +1 -0
  268. package/dist/theme/forms.js +3 -0
  269. package/dist/theme/headless.d.ts +62 -0
  270. package/dist/theme/headless.d.ts.map +1 -0
  271. package/dist/theme/headless.js +1064 -0
  272. package/dist/theme/index.d.ts +41 -0
  273. package/dist/theme/index.d.ts.map +1 -0
  274. package/dist/theme/index.js +38 -0
  275. package/dist/theme/portal.d.ts +6 -0
  276. package/dist/theme/portal.d.ts.map +1 -0
  277. package/dist/theme/portal.js +59 -0
  278. package/dist/theme/styles.css +4232 -0
  279. package/dist/theme/types.d.ts +363 -0
  280. package/dist/theme/types.d.ts.map +1 -0
  281. package/dist/theme/types.js +1 -0
  282. package/dist/virtual.d.ts +65 -0
  283. package/dist/vite.d.ts +16 -0
  284. package/dist/vite.d.ts.map +1 -0
  285. package/dist/vite.js +386 -0
  286. package/package.json +132 -0
@@ -0,0 +1,267 @@
1
+ import { access, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { checkLink, createLinkCheckContext } from './links.js';
4
+ import { findDuplicates, normalizePath } from './utils.js';
5
+ export async function checkSvedocsContent(manifest, projectRoot = process.cwd()) {
6
+ const issues = [];
7
+ const routeDuplicates = findDuplicates(manifest.pages.map((page) => page.routePath));
8
+ const canonicalDuplicates = findDuplicates(manifest.pages
9
+ .map((page) => page.seo.canonical)
10
+ .filter((canonical) => Boolean(canonical)));
11
+ if (manifest.config.build.mode === 'spa') {
12
+ issues.push({
13
+ code: 'spa-risk',
14
+ severity: 'warning',
15
+ message: 'SPA mode prerenders known pages, but server-only routes and provider bindings are unavailable on static hosts.'
16
+ });
17
+ }
18
+ if (manifest.config.seo.rss && !manifest.config.site.url) {
19
+ issues.push({
20
+ code: 'missing-site-url',
21
+ severity: 'warning',
22
+ message: 'site.url is required to generate absolute sitemap and RSS URLs for production.'
23
+ });
24
+ }
25
+ const sitemapPageCount = manifest.pages.filter((page) => (!page.hidden && !/(?:^|[\s,])(?:noindex|none)(?:$|[\s,])/i.test(page.seo.robots ?? ''))).length;
26
+ if (manifest.config.seo.sitemap && sitemapPageCount > 50_000) {
27
+ issues.push({
28
+ code: 'sitemap-url-limit',
29
+ severity: 'error',
30
+ message: `Sitemap contains ${sitemapPageCount} URLs; split it into sitemap index files before exceeding 50,000 URLs.`
31
+ });
32
+ }
33
+ for (const route of routeDuplicates) {
34
+ issues.push({
35
+ code: 'duplicate-route',
36
+ severity: 'error',
37
+ message: `Duplicate route path detected: ${route}`
38
+ });
39
+ }
40
+ for (const canonical of canonicalDuplicates) {
41
+ issues.push({
42
+ code: 'duplicate-canonical',
43
+ severity: 'error',
44
+ message: `Duplicate canonical URL detected: ${canonical}`
45
+ });
46
+ }
47
+ if (manifest.config.checks.translations) {
48
+ issues.push(...createMissingTranslationIssues(manifest));
49
+ }
50
+ const linkContext = createLinkCheckContext(manifest);
51
+ for (const page of manifest.pages) {
52
+ if (!page.description) {
53
+ issues.push({
54
+ code: 'missing-description',
55
+ severity: 'warning',
56
+ message: `${page.routePath} is missing a description for SEO and search excerpts.`,
57
+ pageId: page.id,
58
+ sourcePath: page.sourcePath
59
+ });
60
+ }
61
+ if (page.plainText && page.search.length === 0) {
62
+ issues.push({
63
+ code: 'empty-search',
64
+ severity: 'warning',
65
+ message: `${page.routePath} has content but produced no search records.`,
66
+ pageId: page.id,
67
+ sourcePath: page.sourcePath
68
+ });
69
+ }
70
+ for (const link of page.links) {
71
+ const issue = checkLink(page, link, linkContext)
72
+ ?? await checkAssetLink(projectRoot, page.sourcePath, link, manifest.config.checks.assets)
73
+ ?? await checkExternalLink(link, manifest.config.checks.externalLinks, page.id, page.sourcePath);
74
+ if (issue)
75
+ issues.push(issue);
76
+ }
77
+ }
78
+ return issues;
79
+ }
80
+ function createMissingTranslationIssues(manifest) {
81
+ const locales = manifest.config.i18n.locales.map((locale) => locale.code);
82
+ if (locales.length <= 1)
83
+ return [];
84
+ const groups = new Map();
85
+ for (const page of manifest.pages) {
86
+ if (page.hidden)
87
+ continue;
88
+ const key = `${page.kind}:${page.scopePath}`;
89
+ const group = groups.get(key) ?? [];
90
+ group.push(page);
91
+ groups.set(key, group);
92
+ }
93
+ const issues = [];
94
+ for (const pages of groups.values()) {
95
+ const present = new Set(pages.map((page) => page.locale).filter((locale) => Boolean(locale)));
96
+ const reference = pages[0];
97
+ if (!reference)
98
+ continue;
99
+ for (const locale of locales) {
100
+ if (present.has(locale))
101
+ continue;
102
+ issues.push({
103
+ code: 'missing-translation',
104
+ severity: 'warning',
105
+ message: `${reference.scopePath} is missing locale ${locale}.`,
106
+ pageId: reference.id,
107
+ sourcePath: reference.sourcePath
108
+ });
109
+ }
110
+ }
111
+ return issues;
112
+ }
113
+ export async function checkPackagePublication(packageRoot) {
114
+ const issues = [];
115
+ const packageJsonPath = path.join(packageRoot, 'package.json');
116
+ const pkg = JSON.parse(await readFile(packageJsonPath, 'utf8'));
117
+ if (!pkg.private && pkg.license !== 'MIT') {
118
+ issues.push({
119
+ code: 'package-license-missing',
120
+ severity: 'error',
121
+ message: 'package.json license must be MIT for public svedocs packages.'
122
+ });
123
+ }
124
+ if (!pkg.private && pkg.publishConfig?.access !== 'public') {
125
+ issues.push({
126
+ code: 'package-publish-access-missing',
127
+ severity: 'warning',
128
+ message: 'package.json publishConfig.access should be public before publishing.'
129
+ });
130
+ }
131
+ if (!pkg.private && pkg.publishConfig?.provenance !== true) {
132
+ issues.push({
133
+ code: 'package-provenance-missing',
134
+ severity: 'warning',
135
+ message: 'package.json publishConfig.provenance should be true for npm provenance.'
136
+ });
137
+ }
138
+ for (const target of extractBinTargets(pkg.bin)) {
139
+ if (!await fileExists(path.join(packageRoot, target))) {
140
+ issues.push({
141
+ code: 'package-bin-missing',
142
+ severity: 'error',
143
+ message: `package.json bin target is missing: ${target}.`
144
+ });
145
+ }
146
+ }
147
+ for (const [exportName, value] of Object.entries(pkg.exports ?? {})) {
148
+ const targets = extractExportTargets(value);
149
+ for (const target of targets) {
150
+ if (!await fileExists(path.join(packageRoot, target))) {
151
+ issues.push({
152
+ code: 'package-export-missing',
153
+ severity: 'error',
154
+ message: `${exportName} points to missing package export target ${target}.`
155
+ });
156
+ }
157
+ }
158
+ }
159
+ for (const file of pkg.files ?? []) {
160
+ if (!await fileExists(path.join(packageRoot, file))) {
161
+ issues.push({
162
+ code: 'package-file-missing',
163
+ severity: 'error',
164
+ message: `package.json files entry is missing: ${file}.`
165
+ });
166
+ }
167
+ }
168
+ return issues;
169
+ }
170
+ function extractBinTargets(bin) {
171
+ if (!bin)
172
+ return [];
173
+ if (typeof bin === 'string')
174
+ return [normalizePackageTarget(bin)];
175
+ return Object.values(bin).map(normalizePackageTarget);
176
+ }
177
+ async function checkAssetLink(projectRoot, sourcePath, link, enabled) {
178
+ if (!enabled || link.kind !== 'asset')
179
+ return undefined;
180
+ const pathname = splitHrefPath(link.href);
181
+ const candidates = pathname.startsWith('/')
182
+ ? [
183
+ path.join(projectRoot, 'static', pathname),
184
+ path.join(projectRoot, pathname)
185
+ ]
186
+ : [
187
+ path.join(projectRoot, path.posix.dirname(normalizePath(sourcePath)), pathname),
188
+ path.join(projectRoot, 'static', pathname)
189
+ ];
190
+ if (await anyFileExists(candidates))
191
+ return undefined;
192
+ return {
193
+ code: 'broken-asset',
194
+ severity: 'error',
195
+ message: `${sourcePath}:${link.line} references missing asset ${link.href}.`,
196
+ pageId: sourcePath,
197
+ sourcePath,
198
+ href: link.href
199
+ };
200
+ }
201
+ async function checkExternalLink(link, enabled, pageId, sourcePath) {
202
+ if (!enabled || link.kind !== 'external' || !/^https?:\/\//.test(link.href))
203
+ return undefined;
204
+ const controller = new AbortController();
205
+ const timeout = setTimeout(() => controller.abort(), 4_000);
206
+ try {
207
+ const response = await fetch(link.href, {
208
+ method: 'HEAD',
209
+ redirect: 'follow',
210
+ signal: controller.signal
211
+ });
212
+ if (response.ok || response.status === 405)
213
+ return undefined;
214
+ return {
215
+ code: 'external-link-unchecked',
216
+ severity: 'warning',
217
+ message: `${sourcePath}:${link.line} external link returned ${response.status}: ${link.href}.`,
218
+ pageId,
219
+ sourcePath,
220
+ href: link.href
221
+ };
222
+ }
223
+ catch {
224
+ return {
225
+ code: 'external-link-unchecked',
226
+ severity: 'warning',
227
+ message: `${sourcePath}:${link.line} external link could not be verified: ${link.href}.`,
228
+ pageId,
229
+ sourcePath,
230
+ href: link.href
231
+ };
232
+ }
233
+ finally {
234
+ clearTimeout(timeout);
235
+ }
236
+ }
237
+ function extractExportTargets(value) {
238
+ if (typeof value === 'string')
239
+ return [normalizePackageTarget(value)];
240
+ if (!value || typeof value !== 'object')
241
+ return [];
242
+ return Object.values(value).flatMap(extractExportTargets);
243
+ }
244
+ function normalizePackageTarget(target) {
245
+ return target.replace(/^\.\//, '');
246
+ }
247
+ function splitHrefPath(href) {
248
+ const [withoutHash = ''] = href.trim().split('#');
249
+ const [pathname = ''] = withoutHash.split('?');
250
+ return pathname;
251
+ }
252
+ async function anyFileExists(paths) {
253
+ for (const candidate of paths) {
254
+ if (await fileExists(candidate))
255
+ return true;
256
+ }
257
+ return false;
258
+ }
259
+ async function fileExists(filePath) {
260
+ try {
261
+ await access(filePath);
262
+ return true;
263
+ }
264
+ catch {
265
+ return false;
266
+ }
267
+ }
@@ -0,0 +1,6 @@
1
+ import type { SvedocsConfig } from '../config.js';
2
+ import type { SvedocsResolvedConfig } from './types.js';
3
+ export { defaultSvedocsMessages } from './i18n.js';
4
+ export declare function resolveSvedocsConfig(config?: SvedocsConfig): SvedocsResolvedConfig;
5
+ export declare function isResolvedConfig(config: SvedocsConfig | SvedocsResolvedConfig | undefined): config is SvedocsResolvedConfig;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEnD,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,aAAkB,GAAG,qBAAqB,CA8ItF;AA2BD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,qBAAqB,GAAG,SAAS,GAAG,MAAM,IAAI,qBAAqB,CAY3H"}
@@ -0,0 +1,178 @@
1
+ import { resolveSvedocsI18nConfig } from './i18n.js';
2
+ export { defaultSvedocsMessages } from './i18n.js';
3
+ export function resolveSvedocsConfig(config = {}) {
4
+ const contentRoot = config.content?.root ?? 'content';
5
+ const docsRoot = config.content?.docs ?? `${contentRoot}/docs`;
6
+ const pagesRoot = config.content?.pages ?? `${contentRoot}/pages`;
7
+ const search = config.search === false ? { enabled: false, provider: 'local', scope: 'current' } : {
8
+ enabled: config.search?.enabled ?? true,
9
+ provider: config.search?.provider ?? 'local',
10
+ scope: config.search?.scope ?? 'current'
11
+ };
12
+ const ai = config.ai === false ? {
13
+ enabled: false,
14
+ provider: 'mock',
15
+ scope: 'current',
16
+ label: 'Ask AI',
17
+ placeholder: 'Ask about the docs',
18
+ suggestions: [],
19
+ maxResults: 5
20
+ } : {
21
+ enabled: config.ai?.enabled ?? Boolean(config.ai?.provider),
22
+ provider: config.ai?.provider ?? 'mock',
23
+ scope: config.ai?.scope ?? 'current',
24
+ label: config.ai?.label ?? 'Ask AI',
25
+ placeholder: config.ai?.placeholder ?? 'Ask about the docs',
26
+ suggestions: config.ai?.suggestions ?? [],
27
+ maxResults: config.ai?.maxResults ?? 5,
28
+ ...(config.ai?.systemPrompt ? { systemPrompt: config.ai.systemPrompt } : {}),
29
+ ...(config.ai?.welcomeMessage ? { welcomeMessage: config.ai.welcomeMessage } : {})
30
+ };
31
+ const rss = resolveRssConfig(config);
32
+ return {
33
+ site: {
34
+ name: config.site?.name ?? 'svedocs',
35
+ title: config.site?.title ?? config.site?.name ?? 'svedocs',
36
+ description: config.site?.description ?? 'SvelteKit-native documentation framework.',
37
+ ...(config.site?.url ? { url: config.site.url } : {})
38
+ },
39
+ content: {
40
+ root: contentRoot,
41
+ docs: docsRoot,
42
+ pages: pagesRoot,
43
+ include: config.content?.include ?? [`${contentRoot}/**/*.{md,mdx,svx}`],
44
+ exclude: config.content?.exclude ?? [
45
+ '**/_*.{md,mdx,svx}',
46
+ '**/node_modules/**',
47
+ '**/dist/**',
48
+ '**/build/**',
49
+ '**/.svelte-kit/**'
50
+ ]
51
+ },
52
+ build: {
53
+ mode: config.build?.mode ?? 'edge'
54
+ },
55
+ theme: {
56
+ defaultMode: config.theme?.defaultMode ?? 'system',
57
+ palette: {
58
+ accent: config.theme?.palette?.accent ?? 'emerald',
59
+ neutral: config.theme?.palette?.neutral ?? 'zinc'
60
+ },
61
+ fonts: {
62
+ sans: config.theme?.fonts?.sans ?? '"IBM Plex Sans", "Avenir Next", sans-serif',
63
+ mono: config.theme?.fonts?.mono ?? '"JetBrains Mono", "SFMono-Regular", monospace',
64
+ display: config.theme?.fonts?.display ?? '"IBM Plex Sans", "Avenir Next", sans-serif'
65
+ },
66
+ radius: config.theme?.radius ?? '0px',
67
+ codeTheme: resolveCodeTheme(config.theme?.codeTheme),
68
+ code: {
69
+ lineNumbers: config.theme?.code?.lineNumbers ?? true,
70
+ wrap: config.theme?.code?.wrap ?? false,
71
+ copyButton: config.theme?.code?.copyButton ?? true
72
+ },
73
+ brand: {
74
+ label: config.theme?.brand?.label ?? config.site?.name ?? 'svedocs',
75
+ ...(config.theme?.brand?.labelKey ? { labelKey: config.theme.brand.labelKey } : {}),
76
+ href: config.theme?.brand?.href ?? '/',
77
+ ...(config.theme?.brand?.logo ? { logo: config.theme.brand.logo } : {}),
78
+ mark: config.theme?.brand?.mark ?? 'pixel'
79
+ },
80
+ nav: config.theme?.nav ?? [
81
+ { label: 'Docs', labelKey: 'nav.docs', href: '/docs' }
82
+ ],
83
+ social: config.theme?.social ?? [],
84
+ footer: config.theme?.footer === false
85
+ ? false
86
+ : {
87
+ text: config.theme?.footer?.text ?? `MIT licensed. Built with ${config.site?.name ?? 'svedocs'}.`,
88
+ links: config.theme?.footer?.links ?? []
89
+ },
90
+ home: {
91
+ kicker: config.theme?.home?.kicker ?? 'SvelteKit-native docs',
92
+ ...(config.theme?.home?.kickerKey ? { kickerKey: config.theme.home.kickerKey } : {}),
93
+ ...(config.theme?.home?.primaryAction ? { primaryAction: config.theme.home.primaryAction } : {}),
94
+ ...(config.theme?.home?.secondaryAction ? { secondaryAction: config.theme.home.secondaryAction } : {}),
95
+ visual: {
96
+ type: config.theme?.home?.visual?.type ?? 'pixel',
97
+ ...(config.theme?.home?.visual?.src ? { src: config.theme.home.visual.src } : {}),
98
+ alt: config.theme?.home?.visual?.alt ?? '',
99
+ ...(config.theme?.home?.visual?.altKey ? { altKey: config.theme.home.visual.altKey } : {})
100
+ }
101
+ }
102
+ },
103
+ search,
104
+ ai,
105
+ seo: {
106
+ sitemap: config.seo?.sitemap ?? true,
107
+ rss,
108
+ robots: config.seo?.robots ?? true,
109
+ ...(config.seo?.defaultAuthor ? { defaultAuthor: config.seo.defaultAuthor } : {}),
110
+ head: {
111
+ meta: config.seo?.head?.meta ?? [],
112
+ links: config.seo?.head?.links ?? [],
113
+ jsonLd: config.seo?.head?.jsonLd ?? config.seo?.head?.jsonld ?? config.seo?.head?.['json-ld'] ?? []
114
+ },
115
+ ogImage: config.seo?.ogImage === false
116
+ ? false
117
+ : {
118
+ template: config.seo?.ogImage?.template ?? 'default',
119
+ format: config.seo?.ogImage?.format ?? 'svg',
120
+ outDir: config.seo?.ogImage?.outDir ?? 'static/og',
121
+ renderer: config.seo?.ogImage?.renderer ?? 'svg'
122
+ }
123
+ },
124
+ source: {
125
+ ...(config.source?.editBaseUrl ? { editBaseUrl: config.source.editBaseUrl } : {})
126
+ },
127
+ cloudflare: {
128
+ compatibilityDate: config.cloudflare?.compatibilityDate ?? '2026-05-18',
129
+ aiSearch: {
130
+ binding: config.cloudflare?.aiSearch?.binding ?? 'SVEDOCS_AI_SEARCH',
131
+ instanceName: config.cloudflare?.aiSearch?.instanceName ?? 'svedocs',
132
+ ...(config.cloudflare?.aiSearch?.namespace ? { namespace: config.cloudflare.aiSearch.namespace } : {}),
133
+ remote: config.cloudflare?.aiSearch?.remote ?? false
134
+ }
135
+ },
136
+ checks: {
137
+ assets: config.checks?.assets ?? true,
138
+ externalLinks: config.checks?.externalLinks ?? false,
139
+ translations: config.checks?.translations ?? false,
140
+ },
141
+ i18n: resolveSvedocsI18nConfig(config)
142
+ };
143
+ }
144
+ function resolveRssConfig(config) {
145
+ const input = config.seo?.rss;
146
+ if (!input)
147
+ return false;
148
+ const options = typeof input === 'object' ? input : {};
149
+ return {
150
+ title: options.title ?? `${config.site?.name ?? 'svedocs'} RSS`,
151
+ description: options.description ?? config.site?.description ?? 'SvelteKit-native documentation updates.',
152
+ limit: options.limit ?? 50,
153
+ ...(options.locale ? { locale: options.locale } : {})
154
+ };
155
+ }
156
+ function resolveCodeTheme(input) {
157
+ if (typeof input === 'string') {
158
+ return {
159
+ light: input,
160
+ dark: input
161
+ };
162
+ }
163
+ return {
164
+ light: input?.light ?? 'github-light',
165
+ dark: input?.dark ?? 'github-dark'
166
+ };
167
+ }
168
+ export function isResolvedConfig(config) {
169
+ const candidate = config;
170
+ return Boolean(candidate
171
+ && Array.isArray(candidate.content?.include)
172
+ && Array.isArray(candidate.content?.exclude)
173
+ && typeof candidate.search?.enabled === 'boolean'
174
+ && typeof candidate.ai?.enabled === 'boolean'
175
+ && typeof candidate.theme?.fonts?.sans === 'string'
176
+ && typeof candidate.theme?.brand?.label === 'string'
177
+ && typeof candidate.cloudflare?.compatibilityDate === 'string');
178
+ }
@@ -0,0 +1,7 @@
1
+ import type { SvedocsConfig } from '../config.js';
2
+ import type { SvedocsContentManifest, SvedocsResolvedConfig } from './types.js';
3
+ export declare function loadSvedocsContent(options?: {
4
+ projectRoot?: string;
5
+ config?: SvedocsConfig | SvedocsResolvedConfig;
6
+ }): Promise<SvedocsContentManifest>;
7
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/core/content.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQlD,OAAO,KAAK,EAAE,sBAAsB,EAAe,qBAAqB,EAA0E,MAAM,YAAY,CAAC;AAYrK,wBAAsB,kBAAkB,CAAC,OAAO,GAAE;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAAC;CAC3C,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA0CvC"}