create-zudo-doc 1.3.0 → 2.0.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/dist/scaffold.d.ts +1 -1
- package/dist/scaffold.js +2 -2
- package/package.json +1 -1
- package/templates/base/pages/index.tsx +6 -4
- package/templates/base/pages/lib/_chrome.ts +166 -0
- package/templates/base/pages/lib/_doc-route-entries.ts +7 -51
- package/templates/base/pages/lib/_nav-source-docs.ts +9 -29
- package/templates/base/pages/lib/_route-context.ts +32 -0
- package/templates/base/src/config/tag-vocabulary-types.ts +4 -39
- package/templates/features/i18n/files/pages/[locale]/index.tsx +6 -4
- package/templates/base/pages/_mdx-components.ts +0 -106
- package/templates/base/pages/lib/_category-nav.tsx +0 -34
- package/templates/base/pages/lib/_category-tree-nav.tsx +0 -45
- package/templates/base/pages/lib/_compose-meta-title.ts +0 -25
- package/templates/base/pages/lib/_doc-body-end.tsx +0 -8
- package/templates/base/pages/lib/_doc-content-header.tsx +0 -17
- package/templates/base/pages/lib/_doc-history-area.tsx +0 -34
- package/templates/base/pages/lib/_doc-metainfo-area.tsx +0 -26
- package/templates/base/pages/lib/_doc-page-renderer.tsx +0 -31
- package/templates/base/pages/lib/_doc-page-shell.tsx +0 -29
- package/templates/base/pages/lib/_doc-pager.tsx +0 -9
- package/templates/base/pages/lib/_doc-route-paths.ts +0 -16
- package/templates/base/pages/lib/_doc-tags-area.tsx +0 -30
- package/templates/base/pages/lib/_footer-with-defaults.tsx +0 -58
- package/templates/base/pages/lib/_head-with-defaults.tsx +0 -22
- package/templates/base/pages/lib/_header-with-defaults.tsx +0 -45
- package/templates/base/pages/lib/_inline-version-switcher.tsx +0 -23
- package/templates/base/pages/lib/_math-block.tsx +0 -4
- package/templates/base/pages/lib/_nav-data-prep.ts +0 -118
- package/templates/base/pages/lib/_search-widget-script.ts +0 -2
- package/templates/base/pages/lib/_sidebar-prepaint.tsx +0 -11
- package/templates/base/pages/lib/_sidebar-with-defaults.tsx +0 -26
- package/templates/base/pages/lib/_site-tree-nav.tsx +0 -37
- package/templates/base/pages/lib/_toc-title.ts +0 -3
- package/templates/base/pages/lib/route-enumerators.ts +0 -58
- package/templates/base/src/components/tree-nav-shared.tsx +0 -71
- package/templates/base/src/utils/content-files.ts +0 -110
- package/templates/features/docTags/files/pages/lib/_tag-pages.tsx +0 -47
- package/templates/features/versioning/files/pages/lib/_versions-page.tsx +0 -33
package/dist/scaffold.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { getSecondaryLang };
|
|
|
11
11
|
*
|
|
12
12
|
* Bumped in lockstep by scripts/release-create-zudo-doc.sh.
|
|
13
13
|
*/
|
|
14
|
-
export declare const ZUDO_DOC_PIN = "^
|
|
14
|
+
export declare const ZUDO_DOC_PIN = "^2.0.0";
|
|
15
15
|
export declare function scaffold(choices: UserChoices): Promise<void>;
|
package/dist/scaffold.js
CHANGED
|
@@ -18,7 +18,7 @@ export { getSecondaryLang };
|
|
|
18
18
|
*
|
|
19
19
|
* Bumped in lockstep by scripts/release-create-zudo-doc.sh.
|
|
20
20
|
*/
|
|
21
|
-
export const ZUDO_DOC_PIN = "^
|
|
21
|
+
export const ZUDO_DOC_PIN = "^2.0.0";
|
|
22
22
|
/**
|
|
23
23
|
* Files in `templates/base/**` that must never be copied into a generated
|
|
24
24
|
* project. Each entry is matched against the path relative to `templates/base/`
|
|
@@ -570,7 +570,7 @@ function generatePackageJson(choices) {
|
|
|
570
570
|
// @takazudo/zudo-doc/integrations/doc-history which in turn imports
|
|
571
571
|
// @takazudo/zudo-doc-history-server/git-history. Without this dep the
|
|
572
572
|
// plugin host fails at init with ERR_MODULE_NOT_FOUND — W8A (#1739).
|
|
573
|
-
deps["@takazudo/zudo-doc-history-server"] = "^
|
|
573
|
+
deps["@takazudo/zudo-doc-history-server"] = "^2.0.0";
|
|
574
574
|
// tsx is no longer needed here: the relocated package plugin imports the
|
|
575
575
|
// runner directly (no `tsx -e` spawn) since the package ships compiled
|
|
576
576
|
// dist/ — package-first migration #2321 (#2337).
|
package/package.json
CHANGED
|
@@ -28,10 +28,12 @@ import type { JSX } from "preact";
|
|
|
28
28
|
import type { VNode } from "preact";
|
|
29
29
|
import { Island } from "@takazudo/zfb";
|
|
30
30
|
import { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
import {
|
|
32
|
+
FooterWithDefaults,
|
|
33
|
+
HeaderWithDefaults,
|
|
34
|
+
HeadWithDefaults,
|
|
35
|
+
composeMetaTitle,
|
|
36
|
+
} from "./lib/_chrome";
|
|
35
37
|
import { BodyEndIslands } from "./lib/_body-end-islands";
|
|
36
38
|
|
|
37
39
|
export const frontmatter = { title: "Home" };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
// Host chrome adapter — THE single host adapter for the page-chrome surface
|
|
4
|
+
// (epic Collapse Wiring Shells #2420; HOSTCOLLAPSE #2427 collapsed the former
|
|
5
|
+
// per-component `pages/lib/_*` chrome shells into this one module).
|
|
6
|
+
//
|
|
7
|
+
// It builds the host's REAL bindings ONCE and threads them through the public
|
|
8
|
+
// `createChrome(routeContext, hostBindings)` builder, then re-exports the wired
|
|
9
|
+
// page-chrome barrel (renderDocPage, HeaderWithDefaults, FooterWithDefaults,
|
|
10
|
+
// HeadWithDefaults, composeMetaTitle, …). Every doc route + homepage chrome
|
|
11
|
+
// import resolves here.
|
|
12
|
+
//
|
|
13
|
+
// - the reconstructed route context comes from the retained, vitest-safe
|
|
14
|
+
// `./_route-context` seam (settings + i18n + URL/nav/slug helpers +
|
|
15
|
+
// nav-source resolvers + route enumerators), fed the host content bridge
|
|
16
|
+
// (`stableDocs`) so the content read + nav enumeration stay byte-identical;
|
|
17
|
+
// - the genuinely host-bound slots (`hostBindings`): the real SearchWidget,
|
|
18
|
+
// git-history manifest, sidebars config, frontmatter renderers/builder,
|
|
19
|
+
// footer tag loader + vocabulary, body-end islands, DocHistory island, and
|
|
20
|
+
// the showcase MDX content overrides (`mdxExtras`).
|
|
21
|
+
//
|
|
22
|
+
// Island-scanner contract (load-bearing): this module MUST keep the STATIC
|
|
23
|
+
// imports of DocHistory (`@takazudo/zudo-doc/doc-history`), BodyEndIslands
|
|
24
|
+
// (`./_body-end-islands`) and PresetGeneratorFallback (`./_preset-generator`).
|
|
25
|
+
// After the collapse the only page→island import chain is
|
|
26
|
+
// `pages/docs/*.tsx → _chrome.ts → {DocHistory, BodyEndIslands, PresetGenerator}`;
|
|
27
|
+
// if any of these became a type-only or dynamic import the zfb island scanner
|
|
28
|
+
// would stop walking it and the marker/bundle would silently drop.
|
|
29
|
+
|
|
30
|
+
import type { ComponentChildren } from "preact";
|
|
31
|
+
import type { ChromeHostBindings } from "@takazudo/zudo-doc/factory-context";
|
|
32
|
+
|
|
33
|
+
import { createChrome } from "@takazudo/zudo-doc/chrome";
|
|
34
|
+
|
|
35
|
+
import { settings } from "@/config/settings";
|
|
36
|
+
import { defaultLocale } from "@/config/i18n";
|
|
37
|
+
import { tagVocabulary } from "@/config/tag-vocabulary";
|
|
38
|
+
import sidebars from "@/config/sidebars";
|
|
39
|
+
import { frontmatterRenderers } from "@/config/frontmatter-preview-renderers";
|
|
40
|
+
import { collectTags } from "@/utils/tags";
|
|
41
|
+
import { toRouteSlug } from "@/utils/slug";
|
|
42
|
+
import type { DocsEntry } from "@/types/docs-entry";
|
|
43
|
+
|
|
44
|
+
import { routeContext } from "./_route-context";
|
|
45
|
+
import { stableDocs, memoizeDerived } from "./_nav-source-cache";
|
|
46
|
+
import { mergeLocaleDocs } from "./locale-merge";
|
|
47
|
+
import { SearchWidget } from "./_search-widget";
|
|
48
|
+
import { BodyEndIslands as BodyEndIslandsSeam } from "./_body-end-islands";
|
|
49
|
+
import { buildFrontmatterPreviewEntries } from "./_frontmatter-preview-data";
|
|
50
|
+
import { DetailsWrapper } from "./_details";
|
|
51
|
+
import { PresetGeneratorFallback } from "./_preset-generator";
|
|
52
|
+
import { DocHistory } from "@takazudo/zudo-doc/doc-history";
|
|
53
|
+
import { HtmlPreviewWrapper, type HtmlPreviewWrapperProps } from "@takazudo/zudo-doc/html-preview-wrapper";
|
|
54
|
+
// SSR author + date metadata — `#doc-history-meta` is the build-time manifest
|
|
55
|
+
// alias (esbuild-inlined, no fs). Static import is load-bearing for the island
|
|
56
|
+
// scanner chain noted above.
|
|
57
|
+
import docHistoryMeta from "#doc-history-meta";
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Footer tag loader (host-side; moved verbatim from the former
|
|
61
|
+
// _chrome-context.ts / _footer-with-defaults.tsx). Reads collections via
|
|
62
|
+
// stableDocs / memoizeDerived and aggregates tags per locale. Threaded as
|
|
63
|
+
// hostBindings.loadTagsForLocale.
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
function loadTagsForLocale(lang: string) {
|
|
67
|
+
if (lang === defaultLocale) {
|
|
68
|
+
const baseDocs = stableDocs("docs");
|
|
69
|
+
return memoizeDerived([baseDocs], "footerTaglist;default", () => {
|
|
70
|
+
const docs: DocsEntry[] = baseDocs.filter(
|
|
71
|
+
(d) => !d.data.draft && !d.data.unlisted && !d.data.category_no_page,
|
|
72
|
+
);
|
|
73
|
+
const tagMap = collectTags(docs, (id, data) => data.slug ?? toRouteSlug(id));
|
|
74
|
+
return [...tagMap.values()].sort((a, b) => a.tag.localeCompare(b.tag, lang));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const baseDocs = stableDocs("docs");
|
|
78
|
+
const localeDocs = stableDocs(`docs-${lang}`);
|
|
79
|
+
return memoizeDerived([baseDocs, localeDocs], `footerTaglist;${lang}`, () => {
|
|
80
|
+
const result = mergeLocaleDocs({
|
|
81
|
+
baseDocs: baseDocs.filter((d) => !d.data.draft),
|
|
82
|
+
localeDocs: localeDocs.filter((d) => !d.data.draft),
|
|
83
|
+
applyDefaultLocaleOnlyFilter: true,
|
|
84
|
+
});
|
|
85
|
+
const docs: DocsEntry[] = result.docs.filter((d) => !d.data.category_no_page);
|
|
86
|
+
const tagMap = collectTags(docs, (id, data) => data.slug ?? toRouteSlug(id));
|
|
87
|
+
return [...tagMap.values()].sort((a, b) => a.tag.localeCompare(b.tag, lang));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Showcase MDX content overrides (host-bound; identical to the former
|
|
93
|
+
// pages/_mdx-components.ts `extras` block — kept in lockstep). Threaded via
|
|
94
|
+
// hostBindings.mdxExtras; the package factory merges them over its defaults.
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
/** MDX-tag stub: renders nothing (Preact null-vnode path). */
|
|
98
|
+
const MdxStub = (_props: unknown) => null;
|
|
99
|
+
|
|
100
|
+
/** SSR pass-through for `<Island when=…>` — renders children, ignores `when`. */
|
|
101
|
+
function IslandWrapper(props: {
|
|
102
|
+
when?: "load" | "idle" | "visible" | "media";
|
|
103
|
+
children?: ComponentChildren;
|
|
104
|
+
}): ComponentChildren {
|
|
105
|
+
return props.children ?? null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const HtmlPreviewWithGlobalConfig = (props: HtmlPreviewWrapperProps) =>
|
|
109
|
+
HtmlPreviewWrapper({ globalConfig: settings.htmlPreview ?? null, ...props });
|
|
110
|
+
|
|
111
|
+
const mdxExtras = {
|
|
112
|
+
HtmlPreview: HtmlPreviewWithGlobalConfig,
|
|
113
|
+
Details: DetailsWrapper,
|
|
114
|
+
SmartBreak: MdxStub,
|
|
115
|
+
Island: IslandWrapper,
|
|
116
|
+
PresetGenerator: PresetGeneratorFallback,
|
|
117
|
+
Avatar: MdxStub,
|
|
118
|
+
Button: MdxStub,
|
|
119
|
+
Card: MdxStub,
|
|
120
|
+
MyComponent: MdxStub,
|
|
121
|
+
PageLayout: MdxStub,
|
|
122
|
+
} as unknown as Record<string, (props: Record<string, unknown>) => unknown>;
|
|
123
|
+
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// The host's real bindings (the 10 ChromeHostBindings slots).
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
const hostBindings: ChromeHostBindings = {
|
|
129
|
+
SearchWidget: SearchWidget as ChromeHostBindings["SearchWidget"],
|
|
130
|
+
docHistoryMeta: docHistoryMeta as Record<string, unknown>,
|
|
131
|
+
sidebarsConfig: sidebars as unknown as Record<string, unknown>,
|
|
132
|
+
frontmatterRenderers: frontmatterRenderers as unknown as ChromeHostBindings["frontmatterRenderers"],
|
|
133
|
+
buildFrontmatterPreviewEntries:
|
|
134
|
+
buildFrontmatterPreviewEntries as unknown as ChromeHostBindings["buildFrontmatterPreviewEntries"],
|
|
135
|
+
loadTagsForLocale: loadTagsForLocale as unknown as ChromeHostBindings["loadTagsForLocale"],
|
|
136
|
+
tagVocabulary,
|
|
137
|
+
BodyEndIslands: BodyEndIslandsSeam as unknown as ChromeHostBindings["BodyEndIslands"],
|
|
138
|
+
DocHistory: DocHistory as unknown as ChromeHostBindings["DocHistory"],
|
|
139
|
+
mdxExtras: mdxExtras as ChromeHostBindings["mdxExtras"],
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Build the wired page-chrome surface ONCE from the route context + real host
|
|
144
|
+
// bindings, and re-export the barrel. Every omitted slot falls back to the
|
|
145
|
+
// package stub (byte-identical to the injected package-routes path); each REAL
|
|
146
|
+
// slot above overrides it.
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
const chrome = createChrome(routeContext, hostBindings);
|
|
150
|
+
|
|
151
|
+
export type { RenderDocPageOptions } from "@takazudo/zudo-doc/doc-page-renderer";
|
|
152
|
+
|
|
153
|
+
export const {
|
|
154
|
+
composeMetaTitle,
|
|
155
|
+
HeadWithDefaults,
|
|
156
|
+
HeaderWithDefaults,
|
|
157
|
+
FooterWithDefaults,
|
|
158
|
+
SidebarWithDefaults,
|
|
159
|
+
renderDocPage,
|
|
160
|
+
VersionsPageView,
|
|
161
|
+
collectTagMapForLocale,
|
|
162
|
+
TagDetailPageView,
|
|
163
|
+
TagsIndexPageView,
|
|
164
|
+
SiteTreeNavWrapper,
|
|
165
|
+
BodyEndIslands,
|
|
166
|
+
} = chrome;
|
|
@@ -1,54 +1,10 @@
|
|
|
1
|
-
// Thin
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// Thin shim — the memoized doc-route-entry builder rides on the unified
|
|
2
|
+
// ChromeContext now (epic Collapse Wiring Shells #2420, FACTORIES #2424).
|
|
3
|
+
// `createRouteContext` (in _chrome-context.ts) assembles `buildDocRouteEntries`
|
|
4
|
+
// as part of the route context; this module just re-exports it so the doc-route
|
|
5
|
+
// page files keep importing it from here unchanged.
|
|
5
6
|
|
|
6
|
-
import { createDocRouteEntries } from "@takazudo/zudo-doc/doc-route-entries";
|
|
7
|
-
import type {
|
|
8
|
-
DocPageEntry,
|
|
9
|
-
DocNavNode,
|
|
10
|
-
BreadcrumbItem,
|
|
11
|
-
} from "@takazudo/zudo-doc/doc-route-entries";
|
|
12
7
|
export type { DocRouteEntry, BuildDocRouteEntriesArgs } from "@takazudo/zudo-doc/doc-route-entries";
|
|
13
|
-
import {
|
|
14
|
-
buildNavTree,
|
|
15
|
-
buildBreadcrumbs,
|
|
16
|
-
collectAutoIndexNodes,
|
|
17
|
-
type NavNode,
|
|
18
|
-
type CategoryMeta,
|
|
19
|
-
} from "@/utils/docs";
|
|
20
|
-
import { getNavSectionForSlug, getNavSubtree } from "@/utils/nav-scope";
|
|
21
|
-
import { toRouteSlug, toSlugParams } from "@/utils/slug";
|
|
22
|
-
import type { DocsEntry } from "@/types/docs-entry";
|
|
23
|
-
import type { Locale } from "@/config/i18n";
|
|
24
|
-
import { extractHeadings } from "./_extract-headings";
|
|
8
|
+
import { routeContext } from "./_route-context";
|
|
25
9
|
|
|
26
|
-
export const { buildDocRouteEntries } =
|
|
27
|
-
// The factory describes its injected nav builders with the package's own
|
|
28
|
-
// structural counterparts (DocPageEntry / DocNavNode / Map<string, unknown>)
|
|
29
|
-
// and a plain `locale: string`. The host's buildNavTree / buildBreadcrumbs
|
|
30
|
-
// are typed against the concrete project types (DocsEntry / NavNode / the
|
|
31
|
-
// Locale union / Map<string, CategoryMeta>). They are runtime-identical, so
|
|
32
|
-
// the stub adapts them with thin wrappers that cast at the injection boundary
|
|
33
|
-
// where the host owns the type knowledge.
|
|
34
|
-
buildNavTree: (docs: DocPageEntry[], locale: string, categoryMeta: Map<string, unknown>) =>
|
|
35
|
-
buildNavTree(
|
|
36
|
-
docs as unknown as DocsEntry[],
|
|
37
|
-
locale as Locale,
|
|
38
|
-
categoryMeta as Map<string, CategoryMeta>,
|
|
39
|
-
) as DocNavNode[],
|
|
40
|
-
buildBreadcrumbs: (
|
|
41
|
-
tree: DocNavNode[],
|
|
42
|
-
slug: string,
|
|
43
|
-
locale: string,
|
|
44
|
-
urlFor?: (slug: string) => string,
|
|
45
|
-
): BreadcrumbItem[] =>
|
|
46
|
-
buildBreadcrumbs(tree as NavNode[], slug, locale as Locale, urlFor),
|
|
47
|
-
collectAutoIndexNodes: (tree: DocNavNode[]) =>
|
|
48
|
-
collectAutoIndexNodes(tree as NavNode[]) as DocNavNode[],
|
|
49
|
-
getNavSectionForSlug,
|
|
50
|
-
getNavSubtree,
|
|
51
|
-
toRouteSlug,
|
|
52
|
-
toSlugParams,
|
|
53
|
-
extractHeadings,
|
|
54
|
-
});
|
|
10
|
+
export const { buildDocRouteEntries } = routeContext;
|
|
@@ -1,37 +1,17 @@
|
|
|
1
|
-
// Thin
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// Thin shim — nav-source resolvers ride on the unified ChromeContext now
|
|
2
|
+
// (epic Collapse Wiring Shells #2420, FACTORIES #2424). The reconstructed
|
|
3
|
+
// `createRouteContext` (in _chrome-context.ts) builds the identity-stable
|
|
4
|
+
// nav-source API as part of the route context; this module just re-exports the
|
|
5
|
+
// bindings so the existing call sites (route files, nav wrappers, _nav-data-prep,
|
|
6
|
+
// route-enumerators) keep importing them from here unchanged.
|
|
5
7
|
|
|
6
|
-
import { createNavSourceDocs } from "@takazudo/zudo-doc/nav-source-docs";
|
|
7
8
|
export type { NavSourceDocs, NavSourceOptions } from "@takazudo/zudo-doc/nav-source-docs";
|
|
8
|
-
import {
|
|
9
|
-
import { settings } from "@/config/settings";
|
|
10
|
-
import { loadCategoryMeta, isNavVisible } from "@/utils/docs";
|
|
11
|
-
import { isDefaultLocaleOnlyPath } from "@/utils/base";
|
|
12
|
-
import { stableDocs } from "./_nav-source-cache";
|
|
9
|
+
import { routeContext } from "./_route-context";
|
|
13
10
|
|
|
14
|
-
const {
|
|
11
|
+
export const {
|
|
15
12
|
resolveNavSource,
|
|
16
13
|
resolveVersionedLocaleSource,
|
|
17
14
|
loadNavSourceDocs,
|
|
18
15
|
stableMergeCategoryMeta,
|
|
19
16
|
stableNavDocs,
|
|
20
|
-
} =
|
|
21
|
-
defaultLocale,
|
|
22
|
-
docsDir: settings.docsDir,
|
|
23
|
-
getVersions: () => settings.versions,
|
|
24
|
-
getLocaleConfig,
|
|
25
|
-
loadCategoryMeta,
|
|
26
|
-
isNavVisible,
|
|
27
|
-
isDefaultLocaleOnlyPath,
|
|
28
|
-
stableDocs,
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
export {
|
|
32
|
-
resolveNavSource,
|
|
33
|
-
resolveVersionedLocaleSource,
|
|
34
|
-
loadNavSourceDocs,
|
|
35
|
-
stableMergeCategoryMeta,
|
|
36
|
-
stableNavDocs,
|
|
37
|
-
};
|
|
17
|
+
} = routeContext;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Host route context — the reconstructed RouteContext (settings + i18n + URL
|
|
2
|
+
// helpers + nav/slug helpers + identity-stable nav-source resolvers + doc-route
|
|
3
|
+
// + route enumerators), built ONCE via the public `createRouteContext`
|
|
4
|
+
// (epic Collapse Wiring Shells #2420, FACTORIES #2424).
|
|
5
|
+
//
|
|
6
|
+
// Kept SEPARATE from `_chrome-context.ts` so the data shells (`_nav-source-docs`
|
|
7
|
+
// / `_doc-route-entries` / `route-enumerators`) — and the unit tests that import
|
|
8
|
+
// them — depend ONLY on this lightweight module, NOT on the chrome host bindings
|
|
9
|
+
// (which pull the build-time `#doc-history-meta` alias + island components that
|
|
10
|
+
// don't resolve under vitest).
|
|
11
|
+
//
|
|
12
|
+
// The host content bridge (`stableDocs`) is injected so the docs read + nav
|
|
13
|
+
// enumeration match the project's existing `pages/*` paths() exactly (host
|
|
14
|
+
// `bridgeDocsEntries` over the `zfb/content` snapshot), not the package default.
|
|
15
|
+
|
|
16
|
+
import { createRouteContext } from "@takazudo/zudo-doc/route-context";
|
|
17
|
+
import type { ColorScheme } from "@takazudo/zudo-doc/color-scheme-utils";
|
|
18
|
+
import { settings } from "@/config/settings";
|
|
19
|
+
import { translations } from "@/config/i18n";
|
|
20
|
+
import { tagVocabulary } from "@/config/tag-vocabulary";
|
|
21
|
+
import { colorSchemes } from "@/config/color-schemes";
|
|
22
|
+
import { stableDocs } from "./_nav-source-cache";
|
|
23
|
+
|
|
24
|
+
export const routeContext = createRouteContext(
|
|
25
|
+
{
|
|
26
|
+
settings,
|
|
27
|
+
translations,
|
|
28
|
+
tagVocabulary,
|
|
29
|
+
colorSchemes: colorSchemes as unknown as Record<string, ColorScheme>,
|
|
30
|
+
},
|
|
31
|
+
{ stableDocs },
|
|
32
|
+
);
|
|
@@ -1,39 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* free-form `string[]`. Identical to pre-vocabulary behaviour.
|
|
6
|
-
* - `"warn"` — `tags` schema stays free-form so builds pass, but the tag
|
|
7
|
-
* audit script (see Sub 2) reports unknown tags as warnings and
|
|
8
|
-
* exits non-zero under `--ci`.
|
|
9
|
-
* - `"strict"` — `tags` schema is tightened to `z.enum([...allowedIds])`, so
|
|
10
|
-
* unknown tags fail `pnpm check` / `pnpm build`.
|
|
11
|
-
*
|
|
12
|
-
* Orthogonal to `tagVocabulary` (the on/off switch for consulting the
|
|
13
|
-
* vocabulary file at runtime). See `settings-types.ts` for details.
|
|
14
|
-
*/
|
|
15
|
-
export type TagGovernanceMode = "off" | "warn" | "strict";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* A single entry in the tag vocabulary.
|
|
19
|
-
*
|
|
20
|
-
* - `id` — canonical tag id. What content files should ideally use.
|
|
21
|
-
* - `label` — optional human-readable label (falls back to `id`).
|
|
22
|
-
* - `description`— optional short description for tooling / tag index pages.
|
|
23
|
-
* - `group` — optional grouping key used by the grouped tag footer
|
|
24
|
-
* (e.g. `"type"`, `"level"`, `"topic"`).
|
|
25
|
-
* - `aliases` — alternate strings that content files may use. Alias
|
|
26
|
-
* resolution rewrites these to `id` before aggregation.
|
|
27
|
-
* - `deprecated` — `true` marks the tag as deprecated with no redirect: the
|
|
28
|
-
* canonical id is dropped from aggregation. Pass
|
|
29
|
-
* `{ redirect: "<other-id>" }` to rewrite this tag to another
|
|
30
|
-
* canonical id when it appears in content.
|
|
31
|
-
*/
|
|
32
|
-
export interface TagVocabularyEntry {
|
|
33
|
-
id: string;
|
|
34
|
-
label?: string;
|
|
35
|
-
description?: string;
|
|
36
|
-
group?: string;
|
|
37
|
-
aliases?: readonly string[];
|
|
38
|
-
deprecated?: boolean | { redirect?: string };
|
|
39
|
-
}
|
|
1
|
+
// Re-export from the shared package — canonical definitions live in
|
|
2
|
+
// @takazudo/zudo-doc/settings (epic #2321). Consumers that import from
|
|
3
|
+
// this local path continue to work unchanged.
|
|
4
|
+
export type { TagGovernanceMode, TagVocabularyEntry } from "@takazudo/zudo-doc/settings";
|
|
@@ -32,10 +32,12 @@ import type { VNode } from "preact";
|
|
|
32
32
|
import { Island } from "@takazudo/zfb";
|
|
33
33
|
import { SiteTreeNav } from "@takazudo/zudo-doc/site-tree-nav-island";
|
|
34
34
|
import { resolveNavSource } from "../lib/_nav-source-docs";
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
import {
|
|
36
|
+
FooterWithDefaults,
|
|
37
|
+
HeaderWithDefaults,
|
|
38
|
+
HeadWithDefaults,
|
|
39
|
+
composeMetaTitle,
|
|
40
|
+
} from "../lib/_chrome";
|
|
39
41
|
import { BodyEndIslands } from "../lib/_body-end-islands";
|
|
40
42
|
|
|
41
43
|
export const frontmatter = { title: "Home" };
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
// Project MDX-components assembly — thin wrapper over the package factory.
|
|
2
|
-
//
|
|
3
|
-
// The bulk of the components bag (htmlOverrides, admonitions, CodeGroup,
|
|
4
|
-
// Tabs/TabItem, MathBlock, the img base-rewrite, the enlargeable-`p` override)
|
|
5
|
-
// now ships from `@takazudo/zudo-doc/mdx-components` (package-first migration,
|
|
6
|
-
// epic #2321, S8 #2332). This file keeps ONLY what is genuinely project-bound:
|
|
7
|
-
//
|
|
8
|
-
// - the 4 locale-bound nav wrappers (CategoryNav / CategoryTreeNav /
|
|
9
|
-
// SiteTreeNav / SiteTreeNavDemo) — they depend on the project's content
|
|
10
|
-
// collections + nav-tree utilities, so they cannot live in the package.
|
|
11
|
-
// They are passed into the factory as `navData`; the factory injects the
|
|
12
|
-
// active `locale` so `/ja` resolves the JA collection (the load-bearing
|
|
13
|
-
// locale thread — a static global mdx-components slot would render the EN
|
|
14
|
-
// tree on every `/ja` page, which is why this stays a per-call factory).
|
|
15
|
-
// - project `extras` spread last: HtmlPreview (with the host's global
|
|
16
|
-
// config), Details, the Island SSR pass-through, the PresetGenerator SSR
|
|
17
|
-
// shell, and the pure-showcase stubs (Avatar/Button/Card/MyComponent/
|
|
18
|
-
// PageLayout) that appear only as illustrative MDX prose.
|
|
19
|
-
|
|
20
|
-
import type { ComponentChildren } from "preact";
|
|
21
|
-
import { createMdxComponents as createMdxComponentsBase } from "@takazudo/zudo-doc/mdx-components";
|
|
22
|
-
import { HtmlPreviewWrapper, type HtmlPreviewWrapperProps } from "@takazudo/zudo-doc/html-preview-wrapper";
|
|
23
|
-
import { defaultLocale, type Locale } from "@/config/i18n";
|
|
24
|
-
import { settings } from "@/config/settings";
|
|
25
|
-
import { CategoryNavWrapper } from "./lib/_category-nav";
|
|
26
|
-
import { CategoryTreeNavWrapper } from "./lib/_category-tree-nav";
|
|
27
|
-
import { SiteTreeNavWrapper } from "./lib/_site-tree-nav";
|
|
28
|
-
import { DetailsWrapper } from "./lib/_details";
|
|
29
|
-
import { PresetGeneratorFallback } from "./lib/_preset-generator";
|
|
30
|
-
|
|
31
|
-
const HtmlPreviewWithGlobalConfig = (props: HtmlPreviewWrapperProps) =>
|
|
32
|
-
HtmlPreviewWrapper({ globalConfig: settings.htmlPreview ?? null, ...props });
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* MDX-tag stub: renders nothing. Returning `null` keeps the rendered tree
|
|
36
|
-
* intact (Preact's null-vnode path) without leaking placeholder markup into
|
|
37
|
-
* the SSR output.
|
|
38
|
-
*/
|
|
39
|
-
const MdxStub = (_props: unknown) => null;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* SSR-pass-through wrapper for `<Island when="load|idle|visible">`.
|
|
43
|
-
*
|
|
44
|
-
* In the zfb build the zfb `<Island>` component is unavailable here, so the
|
|
45
|
-
* MDX corpus tag resolves to this binding instead. Rendering the children
|
|
46
|
-
* directly ensures server-renderable content nested inside `<Island>`
|
|
47
|
-
* (headings, paragraphs, etc.) appears in the SSR HTML. The `when` prop is
|
|
48
|
-
* ignored at render time — it is only meaningful to the zfb hydration runtime
|
|
49
|
-
* on the client, which reads `data-when` on the inner SSR-skip placeholder.
|
|
50
|
-
*/
|
|
51
|
-
function IslandWrapper(props: {
|
|
52
|
-
when?: "load" | "idle" | "visible" | "media";
|
|
53
|
-
children?: ComponentChildren;
|
|
54
|
-
}): ComponentChildren {
|
|
55
|
-
return props.children ?? null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Build a locale-aware MDX components map for the given locale.
|
|
60
|
-
*
|
|
61
|
-
* Delegates the package-resident components to the `@takazudo/zudo-doc`
|
|
62
|
-
* factory and supplies the project-bound pieces:
|
|
63
|
-
* - `navData`: the 4 locale-aware nav wrappers (the factory injects `lang`).
|
|
64
|
-
* - `extras`: HtmlPreview (host-configured), Details, Island pass-through,
|
|
65
|
-
* PresetGenerator SSR shell, and the showcase stubs.
|
|
66
|
-
*
|
|
67
|
-
* Page modules should call createMdxComponents(locale) — not the static
|
|
68
|
-
* mdxComponents export — so each render gets the locale-correct map.
|
|
69
|
-
*/
|
|
70
|
-
export function createMdxComponents(lang: Locale | string = defaultLocale) {
|
|
71
|
-
return createMdxComponentsBase({
|
|
72
|
-
settings,
|
|
73
|
-
locale: lang,
|
|
74
|
-
navData: {
|
|
75
|
-
CategoryNav: CategoryNavWrapper as unknown as (props: Record<string, unknown>) => unknown,
|
|
76
|
-
CategoryTreeNav: CategoryTreeNavWrapper as unknown as (props: Record<string, unknown>) => unknown,
|
|
77
|
-
SiteTreeNav: SiteTreeNavWrapper as unknown as (props: Record<string, unknown>) => unknown,
|
|
78
|
-
},
|
|
79
|
-
extras: {
|
|
80
|
-
HtmlPreview: HtmlPreviewWithGlobalConfig,
|
|
81
|
-
Details: DetailsWrapper,
|
|
82
|
-
// SmartBreak: corpus tag with no visual rendering — render nothing.
|
|
83
|
-
SmartBreak: MdxStub,
|
|
84
|
-
// Island: pass children through so server-renderable content nested
|
|
85
|
-
// inside <Island> appears in SSR HTML. See IslandWrapper comment above.
|
|
86
|
-
Island: IslandWrapper,
|
|
87
|
-
// PresetGenerator: SSR fallback shell that renders the 8 section headings;
|
|
88
|
-
// the interactive form hydrates client-side via the SSR-skip placeholder
|
|
89
|
-
// inside PresetGeneratorFallback (see pages/lib/_preset-generator.tsx).
|
|
90
|
-
PresetGenerator: PresetGeneratorFallback,
|
|
91
|
-
// Pure showcase placeholders — appear only inside MDX prose as
|
|
92
|
-
// illustrative examples, never implemented as real components.
|
|
93
|
-
Avatar: MdxStub,
|
|
94
|
-
Button: MdxStub,
|
|
95
|
-
Card: MdxStub,
|
|
96
|
-
MyComponent: MdxStub,
|
|
97
|
-
PageLayout: MdxStub,
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Static default-locale components map for backward compatibility.
|
|
104
|
-
* New page modules should call createMdxComponents(locale) instead.
|
|
105
|
-
*/
|
|
106
|
-
export const mdxComponents = createMdxComponents(defaultLocale);
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/** @jsxRuntime automatic */
|
|
2
|
-
/** @jsxImportSource preact */
|
|
3
|
-
// Thin stub — category-nav moved to the package (epic #2344, S8).
|
|
4
|
-
// Calls `createCategoryNavWrapper(deps)` from @takazudo/zudo-doc/category-nav
|
|
5
|
-
// with host singletons injected, then re-exports the resulting component so
|
|
6
|
-
// all existing call sites continue to work unchanged.
|
|
7
|
-
|
|
8
|
-
import { createCategoryNavWrapper } from "@takazudo/zudo-doc/category-nav";
|
|
9
|
-
import { buildNavTree, findNode, firstRoutedHref } from "@/utils/docs";
|
|
10
|
-
import { defaultLocale } from "@/config/i18n";
|
|
11
|
-
import { resolveNavSource } from "./_nav-source-docs";
|
|
12
|
-
|
|
13
|
-
export type { CategoryNavWrapperProps } from "@takazudo/zudo-doc/category-nav";
|
|
14
|
-
|
|
15
|
-
export const CategoryNavWrapper = createCategoryNavWrapper({
|
|
16
|
-
defaultLocale,
|
|
17
|
-
resolveNavSource: resolveNavSource as (
|
|
18
|
-
lang: string,
|
|
19
|
-
currentVersion: string | undefined,
|
|
20
|
-
options?: { applyDefaultLocaleOnlyFilter?: boolean; keepUnlisted?: boolean },
|
|
21
|
-
) => import("@takazudo/zudo-doc/category-nav").CategoryNavSource,
|
|
22
|
-
buildNavTree: buildNavTree as (
|
|
23
|
-
docs: unknown[],
|
|
24
|
-
locale: string,
|
|
25
|
-
categoryMeta: Map<string, unknown>,
|
|
26
|
-
) => import("@takazudo/zudo-doc/category-nav").CategoryNavNode[],
|
|
27
|
-
findNode: findNode as (
|
|
28
|
-
tree: import("@takazudo/zudo-doc/category-nav").CategoryNavNode[],
|
|
29
|
-
slug: string,
|
|
30
|
-
) => import("@takazudo/zudo-doc/category-nav").CategoryNavNode | undefined,
|
|
31
|
-
firstRoutedHref: firstRoutedHref as (
|
|
32
|
-
node: import("@takazudo/zudo-doc/category-nav").CategoryNavNode,
|
|
33
|
-
) => string | undefined,
|
|
34
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/** @jsxRuntime automatic */
|
|
2
|
-
/** @jsxImportSource preact */
|
|
3
|
-
// Thin stub — category-tree-nav moved to the package (epic #2344, S8).
|
|
4
|
-
// Calls `createCategoryTreeNavWrapper(deps)` from
|
|
5
|
-
// @takazudo/zudo-doc/category-tree-nav with host singletons injected,
|
|
6
|
-
// then re-exports the resulting component so all existing call sites continue
|
|
7
|
-
// to work unchanged.
|
|
8
|
-
|
|
9
|
-
import { createCategoryTreeNavWrapper } from "@takazudo/zudo-doc/category-tree-nav";
|
|
10
|
-
import type {
|
|
11
|
-
CategoryTreeNavNode,
|
|
12
|
-
CategoryTreeNavSource,
|
|
13
|
-
} from "@takazudo/zudo-doc/category-tree-nav";
|
|
14
|
-
import { buildNavTree, groupSatelliteNodes, findNode, type NavNode } from "@/utils/docs";
|
|
15
|
-
import { defaultLocale, type Locale } from "@/config/i18n";
|
|
16
|
-
import type { DocsEntry } from "@/types/docs-entry";
|
|
17
|
-
import type { CategoryMeta } from "@/utils/docs";
|
|
18
|
-
import { resolveNavSource } from "./_nav-source-docs";
|
|
19
|
-
|
|
20
|
-
export type { CategoryTreeNavWrapperProps } from "@takazudo/zudo-doc/category-tree-nav";
|
|
21
|
-
|
|
22
|
-
// The factory describes its injected nav helpers with the minimal
|
|
23
|
-
// CategoryTreeNavNode view (no `slug` / `position`), while the host helpers are
|
|
24
|
-
// typed against the full NavNode. At runtime the nodes are real NavNodes; the
|
|
25
|
-
// wrappers re-view them as the minimal type at the injection boundary (cast via
|
|
26
|
-
// `unknown` because NavNode is a structural supertype of CategoryTreeNavNode,
|
|
27
|
-
// so a direct cast is rejected as non-overlapping).
|
|
28
|
-
export const CategoryTreeNavWrapper = createCategoryTreeNavWrapper({
|
|
29
|
-
defaultLocale,
|
|
30
|
-
resolveNavSource: resolveNavSource as (
|
|
31
|
-
lang: string,
|
|
32
|
-
currentVersion: string | undefined,
|
|
33
|
-
options?: { applyDefaultLocaleOnlyFilter?: boolean; keepUnlisted?: boolean },
|
|
34
|
-
) => CategoryTreeNavSource,
|
|
35
|
-
buildNavTree: (docs: unknown[], locale: string, categoryMeta: Map<string, unknown>) =>
|
|
36
|
-
buildNavTree(
|
|
37
|
-
docs as DocsEntry[],
|
|
38
|
-
locale as Locale,
|
|
39
|
-
categoryMeta as Map<string, CategoryMeta>,
|
|
40
|
-
) as unknown as CategoryTreeNavNode[],
|
|
41
|
-
groupSatelliteNodes: (tree: CategoryTreeNavNode[], prefixes: string[]) =>
|
|
42
|
-
groupSatelliteNodes(tree as unknown as NavNode[], prefixes) as unknown as CategoryTreeNavNode[],
|
|
43
|
-
findNode: (tree: CategoryTreeNavNode[], slug: string) =>
|
|
44
|
-
findNode(tree as unknown as NavNode[], slug) as unknown as CategoryTreeNavNode | undefined,
|
|
45
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compose the canonical "<title> | <siteName>" page-title shape used by
|
|
3
|
-
* both <title> (emitted by DocLayout) and og:title (emitted by
|
|
4
|
-
* HeadWithDefaults).
|
|
5
|
-
*
|
|
6
|
-
* Why this exists: the legacy Astro layout synthesised this suffix
|
|
7
|
-
* inline. The zfb DocLayout shell intentionally renders only what the
|
|
8
|
-
* host passes as `title`, so the host has to compose the suffix itself.
|
|
9
|
-
* Centralising the composition in one helper keeps every host call
|
|
10
|
-
* site in sync and matches the SEO/UX-recognised shape the original
|
|
11
|
-
* site shipped (also asserted by smoke-seo.spec.ts).
|
|
12
|
-
*
|
|
13
|
-
* Edge cases:
|
|
14
|
-
* - When `title` is identical to `settings.siteName` (e.g. the home
|
|
15
|
-
* page already passes `settings.siteName` as the title), do NOT
|
|
16
|
-
* duplicate — return just the bare site name. Mirrors the legacy
|
|
17
|
-
* Astro behaviour.
|
|
18
|
-
* - When `siteName` is missing/empty (defensive — settings.ts always
|
|
19
|
-
* has it in practice), fall back to the bare title.
|
|
20
|
-
*
|
|
21
|
-
*/
|
|
22
|
-
import { createComposeMetaTitle } from "@takazudo/zudo-doc/compose-meta-title";
|
|
23
|
-
import { settings } from "@/config/settings";
|
|
24
|
-
|
|
25
|
-
export const composeMetaTitle = createComposeMetaTitle(settings.siteName);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/** @jsxRuntime automatic */
|
|
2
|
-
/** @jsxImportSource preact */
|
|
3
|
-
// Host thin-stub — see @takazudo/zudo-doc/doc-body-end (epic #2344, S7).
|
|
4
|
-
import { settings } from "@/config/settings";
|
|
5
|
-
import { createDocBodyEnd } from "@takazudo/zudo-doc/doc-body-end";
|
|
6
|
-
import { BodyEndIslands } from "./_body-end-islands";
|
|
7
|
-
|
|
8
|
-
export const DocBodyEnd = createDocBodyEnd({ settings, BodyEndIslands });
|