@takazudo/zudo-doc 0.2.21 → 0.2.22

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 (275) hide show
  1. package/bin/gen-z-index.mjs +164 -0
  2. package/bin/tags-audit-runner.ts +126 -0
  3. package/bin/tags-audit.mjs +64 -0
  4. package/dist/ai-chat-modal/index.d.ts +8 -0
  5. package/dist/ai-chat-modal/index.js +243 -0
  6. package/dist/body-foot-util/body-foot-util-area.d.ts +4 -8
  7. package/dist/body-foot-util/edit-link.d.ts +4 -8
  8. package/dist/body-foot-util/index.d.ts +4 -3
  9. package/dist/breadcrumb/breadcrumb.d.ts +5 -9
  10. package/dist/breadcrumb/find-path.d.ts +2 -5
  11. package/dist/breadcrumb/index.d.ts +4 -4
  12. package/dist/breadcrumb/types.d.ts +3 -5
  13. package/dist/category-nav/index.d.ts +86 -0
  14. package/dist/category-nav/index.js +44 -0
  15. package/dist/category-tree-nav/index.d.ts +65 -0
  16. package/dist/category-tree-nav/index.js +24 -0
  17. package/dist/code-group/index.d.ts +10 -0
  18. package/dist/code-group/index.js +37 -0
  19. package/dist/code-syntax/code-block-enhancer-script.d.ts +1 -3
  20. package/dist/code-syntax/code-block-enhancer.d.ts +3 -6
  21. package/dist/code-syntax/index.d.ts +9 -8
  22. package/dist/code-syntax/mermaid-init-script.d.ts +3 -5
  23. package/dist/code-syntax/mermaid-init.d.ts +4 -7
  24. package/dist/code-syntax/tabs-init-script.d.ts +1 -3
  25. package/dist/code-syntax/tabs-init.d.ts +3 -6
  26. package/dist/code-syntax/tabs.d.ts +4 -7
  27. package/dist/color-scheme-utils.d.ts +125 -0
  28. package/dist/color-scheme-utils.js +151 -0
  29. package/dist/compose-meta-title/index.d.ts +7 -0
  30. package/dist/compose-meta-title/index.js +10 -0
  31. package/dist/content/component-map.d.ts +13 -17
  32. package/dist/content/content-blockquote.d.ts +3 -6
  33. package/dist/content/content-code.d.ts +3 -6
  34. package/dist/content/content-code.js +1 -1
  35. package/dist/content/content-link.d.ts +3 -6
  36. package/dist/content/content-link.js +1 -1
  37. package/dist/content/content-ol.d.ts +3 -6
  38. package/dist/content/content-paragraph.d.ts +3 -6
  39. package/dist/content/content-strong.d.ts +3 -6
  40. package/dist/content/content-table.d.ts +3 -6
  41. package/dist/content/content-ul.d.ts +3 -6
  42. package/dist/content/heading-h2.d.ts +3 -6
  43. package/dist/content/heading-h3.d.ts +3 -6
  44. package/dist/content/heading-h4.d.ts +3 -6
  45. package/dist/content/index.d.ts +29 -13
  46. package/dist/content-admonition/index.d.ts +15 -0
  47. package/dist/content-admonition/index.js +14 -0
  48. package/dist/design-token-panel-bootstrap.d.ts +38 -0
  49. package/dist/design-token-panel-bootstrap.js +29 -0
  50. package/dist/desktop-sidebar-toggle-island/index.d.ts +5 -0
  51. package/dist/desktop-sidebar-toggle-island/index.js +62 -0
  52. package/dist/details/details.d.ts +3 -7
  53. package/dist/details/index.d.ts +2 -2
  54. package/dist/doc-body-end/index.d.ts +21 -0
  55. package/dist/doc-body-end/index.js +15 -0
  56. package/dist/doc-content-header/index.d.ts +69 -0
  57. package/dist/doc-content-header/index.js +49 -0
  58. package/dist/doc-history/index.d.ts +10 -0
  59. package/dist/doc-history/index.js +407 -0
  60. package/dist/doc-history-area/index.d.ts +84 -0
  61. package/dist/doc-history-area/index.js +76 -0
  62. package/dist/doc-metainfo-area/index.d.ts +46 -0
  63. package/dist/doc-metainfo-area/index.js +41 -0
  64. package/dist/doc-page-props/index.d.ts +93 -0
  65. package/dist/doc-page-props/index.js +0 -0
  66. package/dist/doc-page-renderer/index.d.ts +128 -0
  67. package/dist/doc-page-renderer/index.js +103 -0
  68. package/dist/doc-page-shell/index.d.ts +136 -0
  69. package/dist/doc-page-shell/index.js +127 -0
  70. package/dist/doc-pager/index.d.ts +25 -0
  71. package/dist/doc-pager/index.js +41 -0
  72. package/dist/doc-route-entries/index.d.ts +125 -0
  73. package/dist/doc-route-entries/index.js +76 -0
  74. package/dist/doc-route-paths/index.d.ts +54 -0
  75. package/dist/doc-route-paths/index.js +61 -0
  76. package/dist/doc-tags-area/index.d.ts +38 -0
  77. package/dist/doc-tags-area/index.js +30 -0
  78. package/dist/doclayout/anchors.d.ts +7 -9
  79. package/dist/doclayout/doc-layout-with-defaults.d.ts +16 -12
  80. package/dist/doclayout/doc-layout.d.ts +5 -9
  81. package/dist/doclayout/index.d.ts +6 -6
  82. package/dist/extract-headings/index.d.ts +43 -0
  83. package/dist/extract-headings/index.js +111 -0
  84. package/dist/factory-context/index.d.ts +80 -0
  85. package/dist/factory-context/index.js +0 -0
  86. package/dist/features.css +882 -0
  87. package/dist/footer/footer.d.ts +4 -8
  88. package/dist/footer/index.d.ts +13 -3
  89. package/dist/footer/types.d.ts +4 -6
  90. package/dist/footer-with-defaults/index.d.ts +63 -0
  91. package/dist/footer-with-defaults/index.js +128 -0
  92. package/dist/frontmatter-preview-data/index.d.ts +26 -0
  93. package/dist/frontmatter-preview-data/index.js +23 -0
  94. package/dist/github-helpers/index.d.ts +17 -0
  95. package/dist/github-helpers/index.js +16 -0
  96. package/dist/head/doc-head.d.ts +3 -6
  97. package/dist/head/index.d.ts +9 -5
  98. package/dist/head/og-tags.d.ts +4 -7
  99. package/dist/head/twitter-card.d.ts +3 -6
  100. package/dist/head/types.d.ts +1 -3
  101. package/dist/head-with-defaults/index.d.ts +49 -0
  102. package/dist/head-with-defaults/index.js +62 -0
  103. package/dist/header/header.d.ts +6 -10
  104. package/dist/header/index.d.ts +16 -6
  105. package/dist/header/nav-active.d.ts +5 -7
  106. package/dist/header/nav-overflow-script.d.ts +1 -3
  107. package/dist/header/right-items.d.ts +3 -6
  108. package/dist/header/types.d.ts +10 -12
  109. package/dist/header-with-defaults/index.d.ts +77 -0
  110. package/dist/header-with-defaults/index.js +163 -0
  111. package/dist/html-preview-wrapper/dedent.d.ts +1 -3
  112. package/dist/html-preview-wrapper/highlighted-code.d.ts +3 -7
  113. package/dist/html-preview-wrapper/html-preview-wrapper.d.ts +6 -10
  114. package/dist/html-preview-wrapper/html-preview.d.ts +5 -9
  115. package/dist/html-preview-wrapper/index.d.ts +8 -5
  116. package/dist/html-preview-wrapper/preflight.d.ts +1 -3
  117. package/dist/html-preview-wrapper/preview-base.d.ts +4 -8
  118. package/dist/i18n-version/index.d.ts +7 -5
  119. package/dist/i18n-version/language-switcher.d.ts +5 -8
  120. package/dist/i18n-version/types.d.ts +3 -5
  121. package/dist/i18n-version/version-banner.d.ts +4 -8
  122. package/dist/i18n-version/version-switcher.d.ts +7 -10
  123. package/dist/icons/index.d.ts +9 -13
  124. package/dist/image-enlarge/index.d.ts +13 -0
  125. package/dist/image-enlarge/index.js +176 -0
  126. package/dist/index.d.ts +26 -2
  127. package/dist/inline-version-switcher/index.d.ts +31 -0
  128. package/dist/inline-version-switcher/index.js +44 -0
  129. package/dist/integrations/claude-resources/escape-for-mdx.d.ts +1 -3
  130. package/dist/integrations/claude-resources/generate.d.ts +2 -4
  131. package/dist/integrations/claude-resources/index.d.ts +7 -10
  132. package/dist/integrations/doc-history/index.d.ts +21 -24
  133. package/dist/integrations/doc-history/pre-build.d.ts +7 -9
  134. package/dist/integrations/llms-txt/dev-middleware.d.ts +7 -11
  135. package/dist/integrations/llms-txt/emit.d.ts +2 -7
  136. package/dist/integrations/llms-txt/generate.d.ts +3 -8
  137. package/dist/integrations/llms-txt/index.d.ts +33 -8
  138. package/dist/integrations/llms-txt/load.d.ts +3 -7
  139. package/dist/integrations/llms-txt/strip.d.ts +2 -6
  140. package/dist/integrations/llms-txt/types.d.ts +9 -13
  141. package/dist/integrations/search-index/build-emitter.d.ts +4 -7
  142. package/dist/integrations/search-index/collect.d.ts +2 -5
  143. package/dist/integrations/search-index/dev-middleware.d.ts +5 -8
  144. package/dist/integrations/search-index/index.d.ts +7 -5
  145. package/dist/integrations/search-index/types.d.ts +5 -7
  146. package/dist/island-types/index.d.ts +44 -0
  147. package/dist/island-types/index.js +12 -0
  148. package/dist/locale-merge/index.d.ts +114 -0
  149. package/dist/locale-merge/index.js +27 -0
  150. package/dist/math-block/index.d.ts +18 -0
  151. package/dist/math-block/index.js +29 -0
  152. package/dist/md-utils/index.d.ts +6 -8
  153. package/dist/md-utils/index.js +2 -1
  154. package/dist/mdx-components/index.d.ts +46 -0
  155. package/dist/mdx-components/index.js +161 -0
  156. package/dist/mermaid-enlarge/index.d.ts +11 -0
  157. package/dist/mermaid-enlarge/index.js +290 -0
  158. package/dist/metainfo/doc-metainfo.d.ts +5 -9
  159. package/dist/metainfo/doc-tags.d.ts +7 -11
  160. package/dist/metainfo/frontmatter-preview.d.ts +8 -12
  161. package/dist/metainfo/index.d.ts +6 -4
  162. package/dist/nav-data-prep/index.d.ts +72 -0
  163. package/dist/nav-data-prep/index.js +34 -0
  164. package/dist/nav-indexing/category-nav.d.ts +4 -8
  165. package/dist/nav-indexing/category-tree-nav.d.ts +4 -8
  166. package/dist/nav-indexing/doc-card-grid.d.ts +4 -8
  167. package/dist/nav-indexing/docs-sitemap.d.ts +4 -8
  168. package/dist/nav-indexing/index.d.ts +37 -10
  169. package/dist/nav-indexing/nav-card-grid.d.ts +4 -8
  170. package/dist/nav-indexing/site-tree-nav-demo.d.ts +4 -8
  171. package/dist/nav-indexing/tag-nav.d.ts +6 -10
  172. package/dist/nav-indexing/types.d.ts +6 -8
  173. package/dist/nav-indexing/versions-page-content.d.ts +4 -8
  174. package/dist/nav-scope/index.d.ts +41 -0
  175. package/dist/nav-scope/index.js +41 -0
  176. package/dist/nav-source-cache/index.d.ts +13 -0
  177. package/dist/nav-source-cache/index.js +28 -0
  178. package/dist/nav-source-docs/index.d.ts +169 -0
  179. package/dist/nav-source-docs/index.js +123 -0
  180. package/dist/page-loading/index.d.ts +1 -2
  181. package/dist/page-loading/page-loading-overlay.d.ts +4 -8
  182. package/dist/plugins/claude-resources.d.ts +3 -0
  183. package/dist/plugins/claude-resources.js +27 -0
  184. package/dist/plugins/connect-adapter.d.ts +31 -0
  185. package/dist/plugins/connect-adapter.js +78 -0
  186. package/dist/plugins/doc-history.d.ts +3 -0
  187. package/dist/plugins/doc-history.js +54 -0
  188. package/dist/plugins/llms-txt.d.ts +3 -0
  189. package/dist/plugins/llms-txt.js +48 -0
  190. package/dist/plugins/plugin-utils.d.ts +17 -0
  191. package/dist/plugins/plugin-utils.js +11 -0
  192. package/dist/plugins/search-index.d.ts +3 -0
  193. package/dist/plugins/search-index.js +24 -0
  194. package/dist/preset.d.ts +152 -0
  195. package/dist/preset.js +169 -0
  196. package/dist/render-markdown/index.d.ts +5 -0
  197. package/dist/render-markdown/index.js +115 -0
  198. package/dist/robots.d.ts +36 -0
  199. package/dist/robots.js +17 -0
  200. package/dist/route-enumerators/index.d.ts +204 -0
  201. package/dist/route-enumerators/index.js +156 -0
  202. package/dist/safelist.css +1 -1
  203. package/dist/search-widget/index.d.ts +38 -0
  204. package/dist/search-widget/index.js +169 -0
  205. package/dist/search-widget-script/index.d.ts +18 -0
  206. package/dist/search-widget-script/index.js +465 -0
  207. package/dist/settings.d.ts +255 -0
  208. package/dist/settings.js +0 -0
  209. package/dist/sidebar/index.d.ts +21 -3
  210. package/dist/sidebar/sidebar.d.ts +5 -9
  211. package/dist/sidebar/types.d.ts +4 -6
  212. package/dist/sidebar-prepaint/index.d.ts +21 -0
  213. package/dist/sidebar-prepaint/index.js +23 -0
  214. package/dist/sidebar-resizer/index.d.ts +2 -6
  215. package/dist/sidebar-resizer/sidebar-resizer-init.d.ts +6 -10
  216. package/dist/sidebar-toggle-island/index.d.ts +13 -0
  217. package/dist/sidebar-toggle-island/index.js +122 -0
  218. package/dist/sidebar-tree/build-tree.d.ts +4 -8
  219. package/dist/sidebar-tree/category-meta.d.ts +3 -6
  220. package/dist/sidebar-tree/index.d.ts +18 -3
  221. package/dist/sidebar-tree/types.d.ts +6 -8
  222. package/dist/sidebar-tree-island/index.d.ts +13 -0
  223. package/dist/sidebar-tree-island/index.js +454 -0
  224. package/dist/sidebar-utils/index.d.ts +64 -0
  225. package/dist/sidebar-utils/index.js +88 -0
  226. package/dist/sidebar-with-defaults/index.d.ts +38 -0
  227. package/dist/sidebar-with-defaults/index.js +45 -0
  228. package/dist/site-tree-nav/index.d.ts +71 -0
  229. package/dist/site-tree-nav/index.js +36 -0
  230. package/dist/site-tree-nav-island/index.d.ts +11 -0
  231. package/dist/site-tree-nav-island/index.js +176 -0
  232. package/dist/slug/index.d.ts +4 -0
  233. package/dist/slug/index.js +19 -0
  234. package/dist/smart-break/index.d.ts +55 -0
  235. package/dist/{toc/smart-break.js → smart-break/index.js} +30 -3
  236. package/dist/tab-item/index.d.ts +2 -2
  237. package/dist/tab-item/tab-item.d.ts +6 -7
  238. package/dist/tag-helpers/index.d.ts +40 -0
  239. package/dist/tag-helpers/index.js +54 -0
  240. package/dist/tag-pages/index.d.ts +114 -0
  241. package/dist/tag-pages/index.js +146 -0
  242. package/dist/tags-audit.d.ts +107 -0
  243. package/dist/tags-audit.js +321 -0
  244. package/dist/theme/color-scheme-provider.d.ts +4 -8
  245. package/dist/theme/color-tweak-export-modal.d.ts +4 -7
  246. package/dist/theme/design-token-serde.d.ts +14 -17
  247. package/dist/theme/design-token-types.d.ts +4 -6
  248. package/dist/theme/iframe-bridge.d.ts +12 -14
  249. package/dist/theme/index.d.ts +7 -9
  250. package/dist/theme/theme-toggle.d.ts +3 -8
  251. package/dist/theme-toggle/color-scheme-sync.d.ts +5 -7
  252. package/dist/theme-toggle/index.d.ts +4 -8
  253. package/dist/toc/cx.d.ts +2 -3
  254. package/dist/toc/index.d.ts +8 -6
  255. package/dist/toc/mobile-toc.d.ts +5 -9
  256. package/dist/toc/mobile-toc.js +1 -1
  257. package/dist/toc/toc-title.d.ts +1 -3
  258. package/dist/toc/toc.d.ts +5 -9
  259. package/dist/toc/toc.js +1 -1
  260. package/dist/toc/types.d.ts +1 -3
  261. package/dist/toc/use-active-heading.d.ts +4 -7
  262. package/dist/transitions/index.d.ts +1 -1
  263. package/dist/transitions/page-events.d.ts +4 -6
  264. package/dist/tree-nav-shared/index.d.ts +22 -0
  265. package/dist/tree-nav-shared/index.js +66 -0
  266. package/dist/url-helpers/index.d.ts +37 -0
  267. package/dist/url-helpers/index.js +106 -0
  268. package/dist/url-normalizer/index.d.ts +39 -1
  269. package/dist/url-normalizer/normalize.d.ts +3 -5
  270. package/dist/use-modal-dialog/index.d.ts +70 -0
  271. package/dist/use-modal-dialog/index.js +73 -0
  272. package/dist/versions-page/index.d.ts +55 -0
  273. package/dist/versions-page/index.js +73 -0
  274. package/package.json +290 -10
  275. package/dist/toc/smart-break.d.ts +0 -27
package/dist/preset.js ADDED
@@ -0,0 +1,169 @@
1
+ import { z } from "zod";
2
+ function zudoDocPreset({
3
+ settings,
4
+ buildDocsSchema,
5
+ directiveVocabulary
6
+ }) {
7
+ const docsSchemaJson = z.toJSONSchema(buildDocsSchema());
8
+ return {
9
+ collections: buildCollections(settings, docsSchemaJson),
10
+ plugins: buildPlugins(settings),
11
+ markdown: { features: buildMarkdownFeatures(settings, directiveVocabulary) },
12
+ // Dual-theme syntect (zfb >= 0.1.0-next.45). Theme names are SYNTECT
13
+ // built-ins, NOT Shiki names. Tokens emit `--shiki-light`/`--shiki-dark`
14
+ // CSS custom properties resolved by the host CSS via `light-dark()`, so
15
+ // code follows the in-page light/dark switch with zero client JS.
16
+ codeHighlight: {
17
+ themeLight: "base16-ocean.light",
18
+ themeDark: "base16-ocean.dark"
19
+ },
20
+ resolveMarkdownLinks: buildResolveMarkdownLinks(settings),
21
+ // Strip `.md` / `.mdx` from in-page `<a href>` so author-written
22
+ // `[label](./other.mdx)` references resolve to the rendered route URL.
23
+ stripMdExt: true,
24
+ trailingSlash: settings.trailingSlash
25
+ };
26
+ }
27
+ function buildCollections(settings, docsSchemaJson) {
28
+ const collections = [];
29
+ collections.push({ name: "docs", path: settings.docsDir, schema: docsSchemaJson });
30
+ for (const [code, config] of Object.entries(settings.locales)) {
31
+ collections.push({ name: `docs-${code}`, path: config.dir, schema: docsSchemaJson });
32
+ }
33
+ if (settings.versions) {
34
+ for (const version of settings.versions) {
35
+ collections.push({
36
+ name: `docs-v-${version.slug}`,
37
+ path: version.docsDir,
38
+ schema: docsSchemaJson
39
+ });
40
+ if (version.locales) {
41
+ for (const [code, config] of Object.entries(version.locales)) {
42
+ collections.push({
43
+ name: `docs-v-${version.slug}-${code}`,
44
+ path: config.dir,
45
+ schema: docsSchemaJson
46
+ });
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return collections;
52
+ }
53
+ function buildResolveMarkdownLinks(settings) {
54
+ return {
55
+ enabled: true,
56
+ dirs: [
57
+ { dir: settings.docsDir, routePrefix: "/docs/" },
58
+ ...Object.entries(settings.locales).map(([code, locale]) => ({
59
+ dir: locale.dir,
60
+ routePrefix: `/${code}/docs/`
61
+ })),
62
+ // Versioned collections: each version's EN dir + per-locale dirs.
63
+ ...settings.versions ? settings.versions.flatMap((version) => [
64
+ { dir: version.docsDir, routePrefix: `/v/${version.slug}/docs/` },
65
+ ...Object.entries(version.locales ?? {}).map(([code, locale]) => ({
66
+ dir: locale.dir,
67
+ routePrefix: `/v/${version.slug}/${code}/docs/`
68
+ }))
69
+ ]) : []
70
+ ],
71
+ onBrokenLinks: settings.onBrokenMarkdownLinks
72
+ };
73
+ }
74
+ function buildMarkdownFeatures(settings, directiveVocabulary) {
75
+ return {
76
+ // Former-Core directives (next.25 generic `directives` map). Keys are
77
+ // directive names, values are the JSX component names they resolve to
78
+ // (registered in the host's pages/_mdx-components.ts).
79
+ directives: { ...directiveVocabulary },
80
+ mermaid: settings.mermaid,
81
+ headingMarkerToc: true,
82
+ // Remaining opt-in features (#1804).
83
+ githubAlerts: true,
84
+ readingTime: true,
85
+ // owner/repo used to build `owner/repo#123`, `#123`, and SHA autolinks.
86
+ // Included only when settings.githubAutolinksRepo is set; omitted entirely
87
+ // for projects that don't configure a repo (restores old generated-project
88
+ // behaviour — zudo-doc#2321 Wave-0 correctness fix).
89
+ ...settings.githubAutolinksRepo ? { githubAutolinks: { repo: settings.githubAutolinksRepo } } : {},
90
+ codeEnrichment: {},
91
+ // codeTabs accepts the `true` shorthand; <CodeGroup> is registered host-side.
92
+ codeTabs: true,
93
+ // ruby — native `<ruby>` markup from `{base}^{ruby}` caret syntax.
94
+ ruby: true,
95
+ // tocExport — object-typed feature; `true` shorthand is rejected by the
96
+ // Rust loader, so pass `{}`.
97
+ tocExport: {},
98
+ imageDimensions: {},
99
+ // warn-only: failOnBroken=false never fails the build.
100
+ linkValidation: { failOnBroken: false },
101
+ // Heading-ID strategy is the single source of truth in settings, mirrored
102
+ // by the host TOC builder so anchors match the rendered IDs.
103
+ headingIds: { strategy: settings.headingIdStrategy }
104
+ };
105
+ }
106
+ function buildPlugins(settings) {
107
+ const localeArray = Object.entries(settings.locales).map(([code, locale]) => ({
108
+ code,
109
+ dir: locale.dir
110
+ }));
111
+ const localeRecord = Object.fromEntries(
112
+ Object.entries(settings.locales).map(([code, locale]) => [code, { dir: locale.dir }])
113
+ );
114
+ return [
115
+ ...settings.claudeResources ? [
116
+ {
117
+ name: "@takazudo/zudo-doc/plugins/claude-resources",
118
+ options: {
119
+ claudeDir: settings.claudeResources.claudeDir,
120
+ projectRoot: settings.claudeResources.projectRoot,
121
+ docsDir: settings.docsDir
122
+ }
123
+ }
124
+ ] : [],
125
+ ...settings.docHistory ? [
126
+ {
127
+ name: "@takazudo/zudo-doc/plugins/doc-history",
128
+ options: {
129
+ docsDir: settings.docsDir,
130
+ locales: localeRecord,
131
+ base: settings.base
132
+ }
133
+ }
134
+ ] : [],
135
+ {
136
+ name: "@takazudo/zudo-doc/plugins/search-index",
137
+ options: {
138
+ docsDir: settings.docsDir,
139
+ locales: localeRecord,
140
+ base: settings.base
141
+ }
142
+ },
143
+ ...settings.llmsTxt ? [
144
+ {
145
+ name: "@takazudo/zudo-doc/plugins/llms-txt",
146
+ options: {
147
+ siteName: settings.siteName,
148
+ siteDescription: settings.siteDescription,
149
+ base: settings.base,
150
+ siteUrl: settings.siteUrl,
151
+ defaultLocaleDir: settings.docsDir,
152
+ locales: localeArray
153
+ }
154
+ }
155
+ ] : [],
156
+ // copy-public stays a PROJECT-relative descriptor (NOT relocated in S3).
157
+ // Native zfb copy_public_dir is not yet validated for base="/", so the
158
+ // host plugin remains until that lands; deleted in place in a later epic.
159
+ {
160
+ name: "./plugins/copy-public-plugin.mjs",
161
+ options: {
162
+ publicDir: "public"
163
+ }
164
+ }
165
+ ];
166
+ }
167
+ export {
168
+ zudoDocPreset
169
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Lightweight markdown-to-HTML renderer for chat messages.
3
+ * Escapes HTML first, then applies markdown patterns — safe by construction.
4
+ */
5
+ export declare function renderMarkdown(src: string): string;
@@ -0,0 +1,115 @@
1
+ function escapeHtml(str) {
2
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3
+ }
4
+ const ALLOWED_LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
5
+ function unescapeHtml(str) {
6
+ return str.replace(/&quot;/g, '"').replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&amp;/g, "&");
7
+ }
8
+ function safeHref(rawCapturedUrl) {
9
+ const decoded = unescapeHtml(rawCapturedUrl);
10
+ let parsed;
11
+ try {
12
+ parsed = new URL(decoded);
13
+ } catch {
14
+ return null;
15
+ }
16
+ if (!ALLOWED_LINK_PROTOCOLS.has(parsed.protocol)) return null;
17
+ return escapeHtml(encodeURI(decoded));
18
+ }
19
+ function renderInline(text) {
20
+ const codeSpans = [];
21
+ let processed = text.replace(/`([^`]+)`/g, (_match, code) => {
22
+ const idx = codeSpans.length;
23
+ codeSpans.push(`<code>${code}</code>`);
24
+ return `%%CODE_${idx}%%`;
25
+ });
26
+ const boldSpans = [];
27
+ processed = processed.replace(/\*\*(.+?)\*\*/g, (_match, inner) => {
28
+ const idx = boldSpans.length;
29
+ boldSpans.push(`<strong>${inner}</strong>`);
30
+ return `%%BOLD_${idx}%%`;
31
+ }).replace(/__(.+?)__/g, (_match, inner) => {
32
+ const idx = boldSpans.length;
33
+ boldSpans.push(`<strong>${inner}</strong>`);
34
+ return `%%BOLD_${idx}%%`;
35
+ });
36
+ processed = processed.replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/(?<!\w)_(.+?)_(?!\w)/g, "<em>$1</em>").replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, (_match, label, url) => {
37
+ const href = safeHref(url);
38
+ if (href === null) return `[${label}](${url})`;
39
+ return `<a href="${href}" target="_blank" rel="noopener noreferrer">${label}</a>`;
40
+ });
41
+ processed = processed.replace(/%%BOLD_(\d+)%%/g, (_match, idx) => boldSpans[parseInt(idx, 10)] ?? "");
42
+ return processed.replace(/%%CODE_(\d+)%%/g, (_match, idx) => codeSpans[parseInt(idx, 10)] ?? "");
43
+ }
44
+ function renderListBlock(block, marker, tag) {
45
+ const parts = [];
46
+ let proseLines = [];
47
+ let listItems = [];
48
+ const flushProse = () => {
49
+ if (proseLines.length > 0) {
50
+ parts.push(`<p>${proseLines.map(renderInline).join("<br>")}</p>`);
51
+ proseLines = [];
52
+ }
53
+ };
54
+ const flushList = () => {
55
+ if (listItems.length > 0) {
56
+ parts.push(`<${tag}>${listItems.join("")}</${tag}>`);
57
+ listItems = [];
58
+ }
59
+ };
60
+ for (const rawLine of block.split("\n")) {
61
+ const line = rawLine.trim();
62
+ if (!line) continue;
63
+ if (marker.test(line)) {
64
+ flushProse();
65
+ listItems.push(`<li>${renderInline(line.replace(marker, ""))}</li>`);
66
+ } else {
67
+ flushList();
68
+ proseLines.push(line);
69
+ }
70
+ }
71
+ flushProse();
72
+ flushList();
73
+ return parts.join("");
74
+ }
75
+ function renderMarkdown(src) {
76
+ const escaped = escapeHtml(src);
77
+ const codeBlocks = [];
78
+ const withPlaceholders = escaped.replace(
79
+ /```(\w*)\n([\s\S]*?)```/g,
80
+ (_match, lang, code) => {
81
+ const idx = codeBlocks.length;
82
+ const langAttr = lang ? ` data-language="${lang}"` : "";
83
+ codeBlocks.push(`<pre${langAttr}><code>${code.trimEnd()}</code></pre>`);
84
+ return `
85
+ %%CODEBLOCK_${idx}%%
86
+ `;
87
+ }
88
+ );
89
+ const blocks = withPlaceholders.split(/\n{2,}/);
90
+ const rendered = blocks.map((block) => {
91
+ const trimmed = block.trim();
92
+ if (!trimmed) return "";
93
+ const cbMatch = trimmed.match(/^%%CODEBLOCK_(\d+)%%$/);
94
+ if (cbMatch) return codeBlocks[parseInt(cbMatch[1] ?? "0", 10)] ?? "";
95
+ if (/^[-*] /m.test(trimmed)) {
96
+ return renderListBlock(trimmed, /^[-*] /, "ul");
97
+ }
98
+ if (/^\d+\. /m.test(trimmed)) {
99
+ return renderListBlock(trimmed, /^\d+\. /, "ol");
100
+ }
101
+ const headingMatch = trimmed.match(/^(#{1,3}) (.+)$/);
102
+ if (headingMatch) {
103
+ const hashes = headingMatch[1] ?? "";
104
+ const headingText = headingMatch[2] ?? "";
105
+ const level = hashes.length;
106
+ return `<h${level + 3}>${renderInline(headingText)}</h${level + 3}>`;
107
+ }
108
+ const lines = trimmed.split("\n").map(renderInline).join("<br>");
109
+ return `<p>${lines}</p>`;
110
+ }).filter(Boolean).join("");
111
+ return rendered;
112
+ }
113
+ export {
114
+ renderMarkdown
115
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Public entry for `@takazudo/zudo-doc/robots`.
3
+ *
4
+ * Renders the content of `robots.txt` from project settings.
5
+ * Extracted from `pages/robots.txt.tsx` so the same logic can be
6
+ * consumed by both the showcase page and every `create-zudo-doc`
7
+ * scaffold without copy-drift.
8
+ *
9
+ * ## Usage
10
+ *
11
+ * ```ts
12
+ * import { renderRobots } from "@takazudo/zudo-doc/robots";
13
+ * import { settings } from "@/config/settings";
14
+ *
15
+ * export const contentType = "text/plain";
16
+ * export default () => renderRobots(settings);
17
+ * ```
18
+ */
19
+ /** Minimal settings shape consumed by renderRobots. */
20
+ export interface RobotsSettings {
21
+ /** When true, disallow all crawlers. */
22
+ noindex: boolean;
23
+ /** Base URL of the site, used to construct the Sitemap line. */
24
+ siteUrl?: string;
25
+ /** When true (and siteUrl is set), append a Sitemap: line. */
26
+ sitemap?: boolean;
27
+ }
28
+ /**
29
+ * Returns the plain-text content for `robots.txt` based on settings.
30
+ *
31
+ * - `noindex: true` → `Disallow: /` with no Sitemap line (advertising a
32
+ * sitemap while disallowing all crawlers is contradictory).
33
+ * - Otherwise → `Allow: /` with an optional `Sitemap:` line when both
34
+ * `siteUrl` and `sitemap` are truthy.
35
+ */
36
+ export declare function renderRobots(settings: RobotsSettings): string;
package/dist/robots.js ADDED
@@ -0,0 +1,17 @@
1
+ function renderRobots(settings) {
2
+ if (settings.noindex) {
3
+ return `User-agent: *
4
+ Disallow: /
5
+ `;
6
+ }
7
+ const siteUrlBase = (settings.siteUrl ?? "").replace(/\/$/, "");
8
+ const hasSitemapLine = siteUrlBase !== "" && settings.sitemap;
9
+ const sitemapLine = hasSitemapLine ? `Sitemap: ${siteUrlBase}/sitemap.xml
10
+ ` : "";
11
+ return `User-agent: *
12
+ Allow: /
13
+ ${sitemapLine}`;
14
+ }
15
+ export {
16
+ renderRobots
17
+ };
@@ -0,0 +1,204 @@
1
+ import type { NavSourceDocs } from "../nav-source-docs/index.js";
2
+ import type { DocPageEntry, DocNavNode } from "../doc-page-props/index.js";
3
+ export type { DocPageEntry, DocNavNode, NavSourceDocs };
4
+ /**
5
+ * Minimal docs entry shape needed for tag enumeration (no Content/module_specifier).
6
+ */
7
+ export interface DocsEntryForTags {
8
+ id: string;
9
+ data: {
10
+ slug?: string;
11
+ draft?: boolean;
12
+ unlisted?: boolean;
13
+ category_no_page?: boolean;
14
+ tags?: string[];
15
+ [key: string]: unknown;
16
+ };
17
+ }
18
+ /**
19
+ * Minimal version config shape needed for route enumeration.
20
+ */
21
+ export interface VersionConfigForEnum {
22
+ slug: string;
23
+ docsDir?: string;
24
+ locales?: Record<string, {
25
+ dir?: string;
26
+ }>;
27
+ }
28
+ /**
29
+ * Minimal tag info shape — only the keys the tag URL enumerator needs.
30
+ */
31
+ export interface TagInfoForEnum {
32
+ tag: string;
33
+ count: number;
34
+ }
35
+ /**
36
+ * Injected context for `createRouteEnumerators`.
37
+ *
38
+ * All host-specific singletons and utilities are passed in so the package
39
+ * factory never imports `@/` aliases.
40
+ */
41
+ export interface RouteEnumeratorsContext {
42
+ /** Default locale code. Host passes `defaultLocale` from `@/config/i18n`. */
43
+ defaultLocale: string;
44
+ /**
45
+ * Getter for all non-default locale codes.
46
+ * Host passes `() => Object.keys(settings.locales)`.
47
+ * Called per invocation so mutations to settings.locales are picked up.
48
+ */
49
+ getLocaleKeys: () => readonly string[];
50
+ /**
51
+ * Getter for the configured versions list (or false/undefined).
52
+ * Host passes `() => settings.versions`.
53
+ * Called per invocation so mutations to settings.versions are picked up.
54
+ */
55
+ getVersions: () => VersionConfigForEnum[] | false | undefined;
56
+ /**
57
+ * Getter for whether tag pages are enabled.
58
+ * Host passes `() => settings.docTags`.
59
+ */
60
+ getDocTags: () => boolean | undefined;
61
+ /** `docsUrl(slug, lang)` from `@/utils/base` (resolved with settings). */
62
+ docsUrl: (slug: string, lang?: string) => string;
63
+ /** `versionedDocsUrl(slug, versionSlug, lang)` from `@/utils/base`. */
64
+ versionedDocsUrl: (slug: string, versionSlug: string, lang?: string) => string;
65
+ /** `withBase(path)` from `@/utils/base`. */
66
+ withBase: (path: string) => string;
67
+ /**
68
+ * Load docs from a named collection.
69
+ * Host passes `loadDocs` from `pages/_data.ts`.
70
+ */
71
+ loadDocs: (collectionName: string) => DocsEntryForTags[];
72
+ /**
73
+ * Returns true for paths that are only shown in the default locale.
74
+ * Host passes `isDefaultLocaleOnlyPath` from `@/utils/base`.
75
+ */
76
+ isDefaultLocaleOnlyPath: (path: string) => boolean;
77
+ /**
78
+ * Collect tags from a docs array.
79
+ * Host passes `collectTags` from `@/utils/tags`.
80
+ */
81
+ collectTags: (docs: DocsEntryForTags[], slugFn: (id: string, data: {
82
+ slug?: string;
83
+ }) => string) => Map<string, TagInfoForEnum>;
84
+ /**
85
+ * Convert a content entry slug to a canonical route slug.
86
+ * Host passes `toRouteSlug` from `@/utils/slug`.
87
+ */
88
+ toRouteSlug: (id: string) => string;
89
+ /**
90
+ * Build the nav tree for a locale.
91
+ * Host passes `buildNavTree` from `@/utils/docs`.
92
+ */
93
+ buildNavTree: (docs: DocPageEntry[], locale: string, categoryMeta: Map<string, unknown>) => DocNavNode[];
94
+ /**
95
+ * Collect auto-generated index nodes.
96
+ * Host passes `collectAutoIndexNodes` from `@/utils/docs`.
97
+ */
98
+ collectAutoIndexNodes: (tree: DocNavNode[]) => DocNavNode[];
99
+ /**
100
+ * Resolve the identity-stable nav source for an EN/locale context.
101
+ * Host passes `resolveNavSource` from `pages/lib/_nav-source-docs.ts`.
102
+ */
103
+ resolveNavSource: (lang: string, currentVersion: string | undefined, options?: {
104
+ applyDefaultLocaleOnlyFilter?: boolean;
105
+ keepUnlisted?: boolean;
106
+ }) => NavSourceDocs;
107
+ /**
108
+ * Resolve the identity-stable nav source for a versioned non-default-locale
109
+ * context.
110
+ * Host passes `resolveVersionedLocaleSource` from `pages/lib/_nav-source-docs.ts`.
111
+ */
112
+ resolveVersionedLocaleSource: (versionSlug: string, versionDocsDir: string | undefined, lang: string, localeDir: string | undefined, options?: {
113
+ applyDefaultLocaleOnlyFilter?: boolean;
114
+ keepUnlisted?: boolean;
115
+ }) => NavSourceDocs;
116
+ /**
117
+ * Merge locale docs with base-locale fallbacks.
118
+ * Host passes `mergeLocaleDocs` from `pages/lib/locale-merge.ts`.
119
+ */
120
+ mergeLocaleDocs: (options: {
121
+ baseDocs: DocsEntryForTags[];
122
+ localeDocs: DocsEntryForTags[];
123
+ applyDefaultLocaleOnlyFilter?: boolean;
124
+ keepUnlisted?: boolean;
125
+ isDefaultLocaleOnlyPath?: (path: string) => boolean;
126
+ }) => {
127
+ docs: DocsEntryForTags[];
128
+ localeSlugSet: ReadonlySet<string>;
129
+ };
130
+ }
131
+ export interface RouteEnumeratorsAPI {
132
+ /**
133
+ * Enumerate all doc page URLs for a locale.
134
+ *
135
+ * For the default locale: loads the "docs" collection directly.
136
+ * For non-default locales: locale-first merge with EN fallback, with
137
+ * default-locale-only paths excluded. A nav-tree pass adds auto-generated
138
+ * category index pages.
139
+ */
140
+ enumerateDocsRoutes: (locale: string) => string[];
141
+ /**
142
+ * Enumerate tag-index and per-tag URLs for a locale.
143
+ *
144
+ * Returns `/docs/tags/` and `/docs/tags/{tag}/` for each unique tag.
145
+ */
146
+ enumerateTagsRoutes: (locale: string) => string[];
147
+ /**
148
+ * Enumerate doc URLs for a single (version, locale) combination.
149
+ *
150
+ * For the default locale: loads the versioned EN collection.
151
+ * For non-default locales: locale-first merge over the version's EN base.
152
+ */
153
+ enumerateVersionedRoutes: (version: VersionConfigForEnum, locale: string) => string[];
154
+ /**
155
+ * Compose all route enumerators into a deduped Map<url, lastmod>.
156
+ *
157
+ * Covers site root, default-locale docs + tags, per-locale docs + tags,
158
+ * versioned EN docs, and versioned locale docs.
159
+ */
160
+ enumerateAllRoutes: () => Map<string, string>;
161
+ }
162
+ /**
163
+ * Create the route-enumeration functions bound to the host's injected context.
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * // pages/lib/route-enumerators.ts (thin stub)
168
+ * import { createRouteEnumerators } from "@takazudo/zudo-doc/route-enumerators";
169
+ * import { settings } from "@/config/settings";
170
+ * import { defaultLocale } from "@/config/i18n";
171
+ * import { docsUrl, versionedDocsUrl, withBase, isDefaultLocaleOnlyPath } from "@/utils/base";
172
+ * import { buildNavTree, collectAutoIndexNodes } from "@/utils/docs";
173
+ * import { collectTags } from "@/utils/tags";
174
+ * import { toRouteSlug } from "@/utils/slug";
175
+ * import { loadDocs } from "../_data";
176
+ * import { resolveNavSource, resolveVersionedLocaleSource } from "./_nav-source-docs";
177
+ * import { mergeLocaleDocs } from "./locale-merge";
178
+ *
179
+ * export const {
180
+ * enumerateDocsRoutes,
181
+ * enumerateTagsRoutes,
182
+ * enumerateVersionedRoutes,
183
+ * enumerateAllRoutes,
184
+ * } = createRouteEnumerators({
185
+ * defaultLocale,
186
+ * getLocaleKeys: () => Object.keys(settings.locales),
187
+ * getVersions: () => settings.versions,
188
+ * getDocTags: () => settings.docTags,
189
+ * docsUrl,
190
+ * versionedDocsUrl,
191
+ * withBase,
192
+ * loadDocs,
193
+ * isDefaultLocaleOnlyPath,
194
+ * collectTags,
195
+ * toRouteSlug,
196
+ * buildNavTree,
197
+ * collectAutoIndexNodes,
198
+ * resolveNavSource,
199
+ * resolveVersionedLocaleSource,
200
+ * mergeLocaleDocs,
201
+ * });
202
+ * ```
203
+ */
204
+ export declare function createRouteEnumerators(ctx: RouteEnumeratorsContext): RouteEnumeratorsAPI;