@takazudo/zudo-doc 5.5.2 → 5.6.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.
- package/CHANGELOG.md +36 -0
- package/README.md +39 -0
- package/dist/chrome/derive.d.ts +46 -0
- package/dist/chrome/derive.js +6 -2
- package/dist/config-assertions/index.d.ts +31 -0
- package/dist/config-assertions/index.js +24 -0
- package/dist/config.d.ts +23 -2
- package/dist/config.js +3 -0
- package/dist/current-path/index.d.ts +27 -0
- package/dist/current-path/index.js +11 -0
- package/dist/design-token-panel-bootstrap.d.ts +89 -23
- package/dist/design-token-panel-bootstrap.js +19 -6
- package/dist/doc-page-props/index.d.ts +5 -67
- package/dist/doc-route-entries/index.d.ts +10 -95
- package/dist/doc-route-entries/index.js +1 -78
- package/dist/doc-route-paths/index.d.ts +1 -1
- package/dist/head-with-defaults/index.d.ts +3 -1
- package/dist/head-with-defaults/index.js +76 -4
- package/dist/header/nav-active.d.ts +28 -0
- package/dist/header/nav-active.js +2 -1
- package/dist/header/nav-overflow-script.js +30 -17
- package/dist/header-with-defaults/index.js +11 -2
- package/dist/i18n-version/language-switcher.d.ts +6 -0
- package/dist/i18n-version/language-switcher.js +3 -1
- package/dist/i18n-version/version-switcher.d.ts +6 -0
- package/dist/i18n-version/version-switcher.js +3 -1
- package/dist/nav-source-docs/index.d.ts +7 -11
- package/dist/plugins/route-pages-candidates.d.ts +19 -0
- package/dist/plugins/route-pages-candidates.js +17 -0
- package/dist/plugins/routes.d.ts +46 -0
- package/dist/plugins/routes.js +72 -18
- package/dist/preset.d.ts +12 -1
- package/dist/preset.js +2 -0
- package/dist/route-context/index.js +2 -2
- package/dist/routes/_chrome.d.ts +1 -1
- package/dist/routes/_chrome.js +4 -0
- package/dist/routes/_context.d.ts +3 -3
- package/dist/routes/_design-token-panel-bootstrap.d.ts +18 -0
- package/dist/routes/_design-token-panel-bootstrap.js +11 -0
- package/dist/routes/_docs-helpers.d.ts +1 -36
- package/dist/routes/_docs-helpers.js +0 -138
- package/dist/safelist.css +1 -1
- package/dist/search-widget-script/generated-script.d.ts +8 -0
- package/dist/search-widget-script/generated-script.js +465 -0
- package/dist/search-widget-script/index.d.ts +1 -18
- package/dist/search-widget-script/index.js +1 -443
- package/dist/settings.d.ts +82 -1
- package/dist/sidebar-tree/category-meta.d.ts +9 -0
- package/dist/sidebar-tree/category-meta.js +21 -12
- package/dist/sidebar-tree-island/index.d.ts +8 -1
- package/dist/sidebar-tree-island/index.js +16 -14
- package/dist/site-schema/doc-route-entries.d.ts +89 -0
- package/dist/site-schema/doc-route-entries.js +83 -0
- package/dist/site-schema/index.d.ts +17 -0
- package/dist/site-schema/index.js +46 -0
- package/dist/site-schema/nav-tree.d.ts +28 -0
- package/dist/site-schema/nav-tree.js +138 -0
- package/dist/site-schema/types.d.ts +97 -0
- package/dist/site-schema/types.js +0 -0
- package/dist/theme/theme-pack-provider.d.ts +34 -3
- package/dist/theme/theme-pack-provider.js +30 -2
- package/eject/header/nav-active.ts +13 -1
- package/eject/header/nav-overflow-script.ts +30 -17
- package/eject/sidebar-tree-island/index.tsx +44 -20
- package/package.json +22 -12
- package/routes-src/_chrome.tsx +21 -9
- package/routes-src/_design-token-panel-bootstrap.tsx +63 -0
- package/routes-src/_docs-helpers.ts +18 -225
- package/routes-src/_virtual.d.ts +5 -2
- package/virtual-modules.d.ts +5 -2
|
@@ -1,37 +1,28 @@
|
|
|
1
|
-
// routes/_docs-helpers —
|
|
2
|
-
//
|
|
1
|
+
// routes/_docs-helpers — the content bridge for the package-owned route
|
|
2
|
+
// entrypoints (epic Package-First Finale #2356, A1 #2361).
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// `
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// alias — the "+ package `docs` helpers" note in the ADR's host-dep table.
|
|
4
|
+
// WHAT IS LEFT HERE: `stableDocs`, and only `stableDocs`. It is the one piece
|
|
5
|
+
// of this module that cannot be browser-safe — it imports `@takazudo/zfb/content`
|
|
6
|
+
// directly (NOT the host `zfb/content` tsconfig alias — Decision 2) to anchor
|
|
7
|
+
// the bridged + draft-filtered array on the build snapshot, so repeat callers
|
|
8
|
+
// within a build get the SAME instance and the nav-tree / doc-route memos
|
|
9
|
+
// short-circuit (the content bridge — Decision 5).
|
|
11
10
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// `
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
11
|
+
// WHAT MOVED: every pure nav helper this file used to define — `buildNavTree`,
|
|
12
|
+
// `groupSatelliteNodes`, `findNode`, `firstRoutedHref`, `collectAutoIndexNodes`,
|
|
13
|
+
// `buildBreadcrumbs`, `isNavVisible` — now lives in `../site-schema/nav-tree.js`
|
|
14
|
+
// (#3395); import them from there, not from here. Cutting them loose is what
|
|
15
|
+
// lets `createDocRouteEntries` reach `buildBreadcrumbs` without dragging
|
|
16
|
+
// `@takazudo/zfb/content` into an otherwise browser-safe graph. This module
|
|
17
|
+
// deliberately re-exports NOTHING: a second import path for the nav helpers
|
|
18
|
+
// through this file would put them one hop from the `@takazudo/zfb/content`
|
|
19
|
+
// edge this file exists to carry.
|
|
21
20
|
|
|
22
21
|
import {
|
|
23
22
|
getCollection,
|
|
24
23
|
getContentSnapshot,
|
|
25
24
|
} from "@takazudo/zfb/content";
|
|
26
|
-
import {
|
|
27
|
-
buildSidebarTree,
|
|
28
|
-
type CategoryMeta,
|
|
29
|
-
type SidebarNode,
|
|
30
|
-
} from "@takazudo/zudo-doc/sidebar-tree";
|
|
31
|
-
import { toRouteSlug } from "@takazudo/zudo-doc/slug";
|
|
32
|
-
import type { DocNavNode, DocPageEntry, DocPageFrontmatter } from "@takazudo/zudo-doc/doc-page-props";
|
|
33
|
-
|
|
34
|
-
export type { CategoryMeta, DocNavNode, DocPageEntry };
|
|
25
|
+
import type { DocPageEntry, DocPageFrontmatter } from "@takazudo/zudo-doc/doc-page-props";
|
|
35
26
|
|
|
36
27
|
// ---------------------------------------------------------------------------
|
|
37
28
|
// Content bridge — snapshot-anchored stable docs (Decision 5)
|
|
@@ -64,201 +55,3 @@ export function stableDocs(collectionName: string): DocPageEntry[] {
|
|
|
64
55
|
docsByAnchor.set(anchor, built);
|
|
65
56
|
return built;
|
|
66
57
|
}
|
|
67
|
-
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
// Nav-tree helpers — ported from src/utils/docs.ts onto buildSidebarTree
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
|
|
72
|
-
/** Filter predicate: true when a doc should appear in navigation. */
|
|
73
|
-
export function isNavVisible(doc: DocPageEntry): boolean {
|
|
74
|
-
return !doc.data.unlisted && !doc.data.standalone;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** A docs-href builder: `(slug, locale) => url`. */
|
|
78
|
-
export type BuildHref = (slug: string, locale: string) => string;
|
|
79
|
-
|
|
80
|
-
export interface BuildNavTreeOptions {
|
|
81
|
-
buildHref?: BuildHref;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function toNavNode(node: SidebarNode): DocNavNode {
|
|
85
|
-
return {
|
|
86
|
-
slug: node.id,
|
|
87
|
-
label: node.label,
|
|
88
|
-
description: node.description,
|
|
89
|
-
position: node.sidebar_position ?? 999,
|
|
90
|
-
href: node.href,
|
|
91
|
-
hasPage: node.hasPage,
|
|
92
|
-
children: node.children.map(toNavNode),
|
|
93
|
-
sortOrder: node.sortOrder ?? "asc",
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** Last entry whose package-derived slug is empty ("") — the entry the shared
|
|
98
|
-
* builder skips. Last one wins (mirrors the host builder's overwrite). */
|
|
99
|
-
function findRootIndexDoc(docs: DocPageEntry[]): DocPageEntry | undefined {
|
|
100
|
-
let found: DocPageEntry | undefined;
|
|
101
|
-
for (const d of docs) {
|
|
102
|
-
const slug = d.data.slug ?? toRouteSlug(d.slug);
|
|
103
|
-
if (slug === "") found = d;
|
|
104
|
-
}
|
|
105
|
-
return found;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function toRootNavNode(
|
|
109
|
-
doc: DocPageEntry,
|
|
110
|
-
locale: string,
|
|
111
|
-
buildHref: BuildHref,
|
|
112
|
-
categoryMeta?: Map<string, CategoryMeta>,
|
|
113
|
-
): DocNavNode {
|
|
114
|
-
const meta = categoryMeta?.get("");
|
|
115
|
-
const noPage = doc.data.category_no_page ?? meta?.noPage;
|
|
116
|
-
const sortOrder =
|
|
117
|
-
(doc.data.category_sort_order as "asc" | "desc" | undefined) ?? meta?.sortOrder ?? "asc";
|
|
118
|
-
return {
|
|
119
|
-
slug: "",
|
|
120
|
-
label:
|
|
121
|
-
(doc.data.sidebar_label as string | undefined) ??
|
|
122
|
-
doc.data.title ??
|
|
123
|
-
meta?.label ??
|
|
124
|
-
"",
|
|
125
|
-
description: doc.data.description ?? meta?.description,
|
|
126
|
-
position: (doc.data.sidebar_position as number | undefined) ?? meta?.position ?? 999,
|
|
127
|
-
href: noPage ? undefined : buildHref("", locale),
|
|
128
|
-
hasPage: noPage !== true,
|
|
129
|
-
children: [],
|
|
130
|
-
sortOrder,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Build a recursive navigation tree from a flat doc collection. Delegates tree
|
|
136
|
-
* construction to the shared `buildSidebarTree`; keeps the host-side concerns
|
|
137
|
-
* (DocNavNode shape, root-index node synthesis). `buildHref` parameterizes the
|
|
138
|
-
* href space (default: the injected `docsUrl`). Unlike the host copy this drops
|
|
139
|
-
* the LRU / identity caches — the snapshot-anchored `stableDocs` already makes
|
|
140
|
-
* the input arrays identity-stable so the factory-level `memoizeDerived` short-
|
|
141
|
-
* circuits per build.
|
|
142
|
-
*/
|
|
143
|
-
export function buildNavTree(
|
|
144
|
-
docs: DocPageEntry[],
|
|
145
|
-
locale: string,
|
|
146
|
-
categoryMeta: Map<string, CategoryMeta> | undefined,
|
|
147
|
-
buildHref: BuildHref,
|
|
148
|
-
options?: BuildNavTreeOptions,
|
|
149
|
-
): DocNavNode[] {
|
|
150
|
-
const href: BuildHref = options?.buildHref ?? buildHref;
|
|
151
|
-
const sidebarTree = buildSidebarTree(
|
|
152
|
-
docs,
|
|
153
|
-
locale,
|
|
154
|
-
{
|
|
155
|
-
categoryMeta,
|
|
156
|
-
buildHref: (slug, loc) => href(slug, loc),
|
|
157
|
-
// Host call sites own visibility; disable the builder's default filter so
|
|
158
|
-
// breadcrumb (unfiltered) and nav (pre-filtered) paths are unchanged.
|
|
159
|
-
isNavVisible: () => true,
|
|
160
|
-
},
|
|
161
|
-
);
|
|
162
|
-
const result = sidebarTree.map(toNavNode);
|
|
163
|
-
|
|
164
|
-
const rootDoc = findRootIndexDoc(docs);
|
|
165
|
-
if (rootDoc) {
|
|
166
|
-
result.push(toRootNavNode(rootDoc, locale, href, categoryMeta));
|
|
167
|
-
result.sort((a, b) => {
|
|
168
|
-
const posCompare = a.position - b.position;
|
|
169
|
-
if (posCompare !== 0) return posCompare;
|
|
170
|
-
return a.slug.localeCompare(b.slug);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
return result;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/** Group "satellite" nodes (slug-prefix siblings) under their primary node. */
|
|
177
|
-
export function groupSatelliteNodes(tree: DocNavNode[], prefixes: string[]): DocNavNode[] {
|
|
178
|
-
const result = [...tree];
|
|
179
|
-
for (const prefix of prefixes) {
|
|
180
|
-
const primaryIdx = result.findIndex((n) => n.slug === prefix);
|
|
181
|
-
if (primaryIdx < 0) continue;
|
|
182
|
-
const primary = result[primaryIdx];
|
|
183
|
-
if (!primary) continue;
|
|
184
|
-
const satelliteIdxs: number[] = [];
|
|
185
|
-
for (let i = 0; i < result.length; i++) {
|
|
186
|
-
const node = result[i];
|
|
187
|
-
if (node && i !== primaryIdx && node.slug.startsWith(`${prefix}-`)) {
|
|
188
|
-
satelliteIdxs.push(i);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
if (satelliteIdxs.length === 0) continue;
|
|
192
|
-
const extraChildren: DocNavNode[] = [];
|
|
193
|
-
for (const idx of satelliteIdxs) {
|
|
194
|
-
const node = result[idx];
|
|
195
|
-
if (node) extraChildren.push(node);
|
|
196
|
-
}
|
|
197
|
-
result[primaryIdx] = { ...primary, children: [...primary.children, ...extraChildren] };
|
|
198
|
-
for (const idx of satelliteIdxs.reverse()) result.splice(idx, 1);
|
|
199
|
-
}
|
|
200
|
-
return result;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/** Find a node by slug anywhere in the tree. */
|
|
204
|
-
export function findNode(nodes: DocNavNode[], slug: string): DocNavNode | undefined {
|
|
205
|
-
for (const node of nodes) {
|
|
206
|
-
if (node.slug === slug) return node;
|
|
207
|
-
const found = findNode(node.children, slug);
|
|
208
|
-
if (found) return found;
|
|
209
|
-
}
|
|
210
|
-
return undefined;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/** Href of the first routed descendant, walking children depth-first. */
|
|
214
|
-
export function firstRoutedHref(node: DocNavNode): string | undefined {
|
|
215
|
-
for (const child of node.children) {
|
|
216
|
-
if (child.hasPage && child.href) return child.href;
|
|
217
|
-
const nested = firstRoutedHref(child);
|
|
218
|
-
if (nested) return nested;
|
|
219
|
-
}
|
|
220
|
-
return undefined;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** Collect all category nodes that have children but no page (no index.mdx). */
|
|
224
|
-
export function collectAutoIndexNodes(nodes: DocNavNode[]): DocNavNode[] {
|
|
225
|
-
const result: DocNavNode[] = [];
|
|
226
|
-
for (const node of nodes) {
|
|
227
|
-
if (!node.hasPage && node.children.length > 0 && node.href) result.push(node);
|
|
228
|
-
result.push(...collectAutoIndexNodes(node.children));
|
|
229
|
-
}
|
|
230
|
-
return result;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export interface BreadcrumbItem {
|
|
234
|
-
label: string;
|
|
235
|
-
href?: string;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/** Build breadcrumb trail by walking the nav tree. `homeHref` is the locale
|
|
239
|
-
* docs root (injected). `hrefFor` optionally remaps intermediate crumbs into
|
|
240
|
-
* a versioned URL space. */
|
|
241
|
-
export function buildBreadcrumbs(
|
|
242
|
-
tree: DocNavNode[],
|
|
243
|
-
slug: string,
|
|
244
|
-
homeHref: string,
|
|
245
|
-
hrefFor?: (slug: string) => string,
|
|
246
|
-
): BreadcrumbItem[] {
|
|
247
|
-
const parts = slug.split("/");
|
|
248
|
-
const crumbs: BreadcrumbItem[] = [{ label: "", href: homeHref }];
|
|
249
|
-
let nodes = tree;
|
|
250
|
-
for (let i = 0; i < parts.length; i++) {
|
|
251
|
-
const partialSlug = parts.slice(0, i + 1).join("/");
|
|
252
|
-
const node = nodes.find((n) => n.slug === partialSlug);
|
|
253
|
-
if (!node) break;
|
|
254
|
-
const isLast = i === parts.length - 1;
|
|
255
|
-
const href = isLast
|
|
256
|
-
? undefined
|
|
257
|
-
: hrefFor && node.href !== undefined
|
|
258
|
-
? hrefFor(node.slug)
|
|
259
|
-
: node.href;
|
|
260
|
-
crumbs.push({ label: node.label, href });
|
|
261
|
-
nodes = node.children;
|
|
262
|
-
}
|
|
263
|
-
return crumbs;
|
|
264
|
-
}
|
package/routes-src/_virtual.d.ts
CHANGED
|
@@ -57,8 +57,11 @@ declare module "virtual:zudo-doc-chrome-bindings" {
|
|
|
57
57
|
// …)`, #2658). No on-disk source — materialised at build, either as a
|
|
58
58
|
// re-export of the host's `settings.designTokenPanelConfigModule` file or as
|
|
59
59
|
// a re-export of the package default (`@takazudo/zudo-doc/design-token-panel-config`)
|
|
60
|
-
// when the setting is absent.
|
|
61
|
-
//
|
|
60
|
+
// when the setting is absent. Since #3396 its SOLE importer is the
|
|
61
|
+
// routes-only wrapper `./_design-token-panel-bootstrap.tsx` — the generic
|
|
62
|
+
// `design-token-panel-bootstrap.tsx` binds the package default directly, so
|
|
63
|
+
// `@takazudo/zudo-doc/chrome` bundles without the routes plugin. See
|
|
64
|
+
// `plugins/routes.ts` and that bootstrap module for the full contract.
|
|
62
65
|
//
|
|
63
66
|
// Typed via an inline `import(...)` type (not a top-level import, for the
|
|
64
67
|
// same ambient-module-declaration reason as `chromeBindings` above) — see
|
package/virtual-modules.d.ts
CHANGED
|
@@ -70,8 +70,11 @@ declare module "virtual:zudo-doc-chrome-bindings" {
|
|
|
70
70
|
// …)`, #2658). No on-disk source — materialised at build, either as a
|
|
71
71
|
// re-export of the host's `settings.designTokenPanelConfigModule` file or as
|
|
72
72
|
// a re-export of the package default (`@takazudo/zudo-doc/design-token-panel-config`)
|
|
73
|
-
// when the setting is absent.
|
|
74
|
-
//
|
|
73
|
+
// when the setting is absent. Since #3396 its SOLE importer is the
|
|
74
|
+
// routes-only wrapper `./_design-token-panel-bootstrap.tsx` — the generic
|
|
75
|
+
// `design-token-panel-bootstrap.tsx` binds the package default directly, so
|
|
76
|
+
// `@takazudo/zudo-doc/chrome` bundles without the routes plugin. See
|
|
77
|
+
// `plugins/routes.ts` and that bootstrap module for the full contract.
|
|
75
78
|
//
|
|
76
79
|
// Typed via an inline `import(...)` type (not a top-level import, for the
|
|
77
80
|
// same ambient-module-declaration reason as `chromeBindings` above) — see
|