@codemonster-ru/vue-ssg-core 1.2.0 → 1.3.1
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/index.d.ts +5 -2
- package/dist/index.js +161 -22
- package/dist/index.js.map +1 -1
- package/dist/playground.d.ts +38 -0
- package/dist/playground.js +175 -0
- package/dist/playground.js.map +1 -0
- package/package.json +9 -4
package/dist/index.d.ts
CHANGED
|
@@ -159,12 +159,15 @@ type DocsContentBlock = {
|
|
|
159
159
|
language: string;
|
|
160
160
|
} | {
|
|
161
161
|
type: 'playground';
|
|
162
|
-
files
|
|
163
|
-
entry
|
|
162
|
+
files?: Record<string, string>;
|
|
163
|
+
entry?: string;
|
|
164
164
|
framework?: DocsPlaygroundFramework;
|
|
165
165
|
autorun?: boolean;
|
|
166
166
|
showCode?: boolean;
|
|
167
167
|
height?: number | string;
|
|
168
|
+
demoId?: string;
|
|
169
|
+
demoImport?: string;
|
|
170
|
+
renderMode?: 'sandbox' | 'vue-module' | 'component';
|
|
168
171
|
} | {
|
|
169
172
|
type: 'list';
|
|
170
173
|
ordered: boolean;
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
createRouter,
|
|
8
8
|
createWebHistory
|
|
9
9
|
} from "vue-router";
|
|
10
|
+
var isClientAppMounted = false;
|
|
11
|
+
var hashScrollWaitMs = 4e3;
|
|
12
|
+
var hashScrollStabilizeFrames = 10;
|
|
10
13
|
async function documentReady() {
|
|
11
14
|
if (typeof document === "undefined" || document.readyState !== "loading") {
|
|
12
15
|
return;
|
|
@@ -18,6 +21,83 @@ async function documentReady() {
|
|
|
18
21
|
async function nextFrame() {
|
|
19
22
|
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
20
23
|
}
|
|
24
|
+
function getHashTargetElement(hash) {
|
|
25
|
+
if (typeof document === "undefined") {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const id = decodeURIComponent(hash.replace(/^#/, ""));
|
|
29
|
+
return id ? document.getElementById(id) : null;
|
|
30
|
+
}
|
|
31
|
+
function getHashScrollPosition(hash) {
|
|
32
|
+
if (typeof window === "undefined") {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const targetElement = getHashTargetElement(hash);
|
|
36
|
+
if (!targetElement) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const top = targetElement.getBoundingClientRect().top + window.scrollY - getStickyOffsetTop();
|
|
40
|
+
return {
|
|
41
|
+
left: 0,
|
|
42
|
+
top: Math.max(0, top)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function waitForHashTarget(hash) {
|
|
46
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined" || !document.body) {
|
|
47
|
+
return Promise.resolve(null);
|
|
48
|
+
}
|
|
49
|
+
const initialTarget = getHashTargetElement(hash);
|
|
50
|
+
if (initialTarget) {
|
|
51
|
+
return Promise.resolve(initialTarget);
|
|
52
|
+
}
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
let observer = null;
|
|
55
|
+
const stop = (target) => {
|
|
56
|
+
window.clearTimeout(timeout);
|
|
57
|
+
window.clearInterval(interval);
|
|
58
|
+
observer?.disconnect();
|
|
59
|
+
resolve(target);
|
|
60
|
+
};
|
|
61
|
+
const findTarget = () => {
|
|
62
|
+
const target = getHashTargetElement(hash);
|
|
63
|
+
if (target) {
|
|
64
|
+
stop(target);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const timeout = window.setTimeout(() => {
|
|
68
|
+
stop(null);
|
|
69
|
+
}, hashScrollWaitMs);
|
|
70
|
+
const interval = window.setInterval(findTarget, 50);
|
|
71
|
+
observer = new MutationObserver(findTarget);
|
|
72
|
+
observer.observe(document.body, {
|
|
73
|
+
childList: true,
|
|
74
|
+
subtree: true
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function scrollToHash(hash, behavior = "smooth") {
|
|
79
|
+
await nextFrame();
|
|
80
|
+
await nextFrame();
|
|
81
|
+
const target = await waitForHashTarget(hash);
|
|
82
|
+
if (!target || typeof window === "undefined") {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
for (let attempt = 0; attempt < hashScrollStabilizeFrames; attempt += 1) {
|
|
86
|
+
const position = getHashScrollPosition(hash);
|
|
87
|
+
if (!position) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
window.scrollTo({
|
|
91
|
+
...position,
|
|
92
|
+
behavior: attempt === 0 ? behavior : "auto"
|
|
93
|
+
});
|
|
94
|
+
await nextFrame();
|
|
95
|
+
if (attempt >= 2 && Math.abs(window.scrollY - position.top) < 2) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
21
101
|
function isVisibleElement(element) {
|
|
22
102
|
return Boolean(element && element.offsetParent !== null);
|
|
23
103
|
}
|
|
@@ -68,10 +148,39 @@ function ensureHistoryState() {
|
|
|
68
148
|
current
|
|
69
149
|
);
|
|
70
150
|
}
|
|
151
|
+
function useManualScrollRestoration() {
|
|
152
|
+
if (typeof window === "undefined" || !("scrollRestoration" in window.history)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
window.history.scrollRestoration = "manual";
|
|
156
|
+
}
|
|
157
|
+
function setRootVisibility(rootContainer, visible) {
|
|
158
|
+
if (typeof document === "undefined") {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const root = document.querySelector(rootContainer);
|
|
162
|
+
if (!root) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
root.style.visibility = visible ? "" : "hidden";
|
|
166
|
+
}
|
|
167
|
+
function hasHydratableRoot(rootContainer) {
|
|
168
|
+
if (typeof document === "undefined") {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const root = document.querySelector(rootContainer);
|
|
172
|
+
return Boolean(root && root.innerHTML.trim().length > 0);
|
|
173
|
+
}
|
|
71
174
|
function createViteSsgApp(App, routerOptions, fn, options) {
|
|
72
|
-
const {
|
|
175
|
+
const {
|
|
176
|
+
hydration = true,
|
|
177
|
+
rootContainer = "#app",
|
|
178
|
+
transformState,
|
|
179
|
+
useHead = true
|
|
180
|
+
} = options ?? {};
|
|
73
181
|
async function createSsgApp(routePath) {
|
|
74
|
-
const
|
|
182
|
+
const shouldHydrate = import.meta.env.SSR || hydration && hasHydratableRoot(rootContainer);
|
|
183
|
+
const app = shouldHydrate ? createSSRApp(App) : createApp(App);
|
|
75
184
|
let head;
|
|
76
185
|
if (useHead) {
|
|
77
186
|
head = import.meta.env.SSR ? createServerHead() : createClientHead();
|
|
@@ -80,22 +189,15 @@ function createViteSsgApp(App, routerOptions, fn, options) {
|
|
|
80
189
|
const router = createRouter({
|
|
81
190
|
history: import.meta.env.SSR ? createMemoryHistory(routerOptions.base) : createWebHistory(routerOptions.base),
|
|
82
191
|
scrollBehavior: async (to, _from, savedPosition) => {
|
|
192
|
+
if (!isClientAppMounted) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
83
195
|
if (savedPosition) {
|
|
84
196
|
return savedPosition;
|
|
85
197
|
}
|
|
86
198
|
if (to.hash) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
await nextFrame();
|
|
90
|
-
const targetElement = document.querySelector(targetHash);
|
|
91
|
-
if (targetElement) {
|
|
92
|
-
const top = targetElement.getBoundingClientRect().top + window.scrollY - getStickyOffsetTop();
|
|
93
|
-
return {
|
|
94
|
-
left: 0,
|
|
95
|
-
top: Math.max(0, top),
|
|
96
|
-
behavior: "smooth"
|
|
97
|
-
};
|
|
98
|
-
}
|
|
199
|
+
const scrolled = await scrollToHash(to.hash);
|
|
200
|
+
return scrolled ? false : { left: 0, top: 0 };
|
|
99
201
|
}
|
|
100
202
|
return { left: 0, top: 0 };
|
|
101
203
|
},
|
|
@@ -118,6 +220,7 @@ function createViteSsgApp(App, routerOptions, fn, options) {
|
|
|
118
220
|
};
|
|
119
221
|
if (!import.meta.env.SSR) {
|
|
120
222
|
await documentReady();
|
|
223
|
+
useManualScrollRestoration();
|
|
121
224
|
ensureHistoryState();
|
|
122
225
|
context.initialState = transformState?.(getInitialState()) ?? getInitialState();
|
|
123
226
|
}
|
|
@@ -144,9 +247,20 @@ function createViteSsgApp(App, routerOptions, fn, options) {
|
|
|
144
247
|
if (!import.meta.env.SSR) {
|
|
145
248
|
;
|
|
146
249
|
(async () => {
|
|
250
|
+
const hasInitialHash = Boolean(window.location.hash);
|
|
251
|
+
if (hasInitialHash) {
|
|
252
|
+
setRootVisibility(rootContainer, false);
|
|
253
|
+
}
|
|
147
254
|
const { app, router } = await createSsgApp();
|
|
148
255
|
await router.isReady();
|
|
149
256
|
app.mount(rootContainer, true);
|
|
257
|
+
isClientAppMounted = true;
|
|
258
|
+
if (window.location.hash) {
|
|
259
|
+
await scrollToHash(window.location.hash, "auto");
|
|
260
|
+
}
|
|
261
|
+
if (hasInitialHash) {
|
|
262
|
+
setRootVisibility(rootContainer, true);
|
|
263
|
+
}
|
|
150
264
|
})();
|
|
151
265
|
}
|
|
152
266
|
return createSsgApp;
|
|
@@ -273,6 +387,8 @@ function parsePlaygroundSourceHeader(text, sourcePath) {
|
|
|
273
387
|
const framework = frameworkRaw || "vanilla";
|
|
274
388
|
const heightRaw = metadata.get("height");
|
|
275
389
|
const entry = metadata.get("entry");
|
|
390
|
+
const modeRaw = metadata.get("mode");
|
|
391
|
+
const renderMode = modeRaw === "component" ? "component" : "sandbox";
|
|
276
392
|
if (!entry) {
|
|
277
393
|
throw new Error(`[docs] Invalid playground-src in ${sourcePath}: "entry" is required`);
|
|
278
394
|
}
|
|
@@ -289,7 +405,8 @@ function parsePlaygroundSourceHeader(text, sourcePath) {
|
|
|
289
405
|
return {
|
|
290
406
|
framework,
|
|
291
407
|
entry,
|
|
292
|
-
height
|
|
408
|
+
height,
|
|
409
|
+
renderMode
|
|
293
410
|
};
|
|
294
411
|
}
|
|
295
412
|
function parsePlaygroundSourcePayload(rawSource, sourcePath) {
|
|
@@ -315,7 +432,7 @@ function parsePlaygroundSourcePayload(rawSource, sourcePath) {
|
|
|
315
432
|
if (!metadataToken) {
|
|
316
433
|
throw new Error(`[docs] Invalid playground-src in ${sourcePath}: missing header metadata`);
|
|
317
434
|
}
|
|
318
|
-
const { framework, height, entry } = parsePlaygroundSourceHeader(metadataToken.text, sourcePath);
|
|
435
|
+
const { framework, height, entry, renderMode } = parsePlaygroundSourceHeader(metadataToken.text, sourcePath);
|
|
319
436
|
const files = {};
|
|
320
437
|
for (const codeToken of codeTokens) {
|
|
321
438
|
const lang = codeToken.lang?.trim() ?? "";
|
|
@@ -338,7 +455,8 @@ function parsePlaygroundSourcePayload(rawSource, sourcePath) {
|
|
|
338
455
|
files,
|
|
339
456
|
entry,
|
|
340
457
|
framework,
|
|
341
|
-
height
|
|
458
|
+
height,
|
|
459
|
+
renderMode
|
|
342
460
|
};
|
|
343
461
|
}
|
|
344
462
|
function isStringRecord(value) {
|
|
@@ -358,8 +476,10 @@ function parsePlaygroundPayload(rawSource) {
|
|
|
358
476
|
return null;
|
|
359
477
|
}
|
|
360
478
|
const data = parsed;
|
|
361
|
-
const files = isStringRecord(data.files) ? data.files :
|
|
362
|
-
|
|
479
|
+
const files = isStringRecord(data.files) ? data.files : void 0;
|
|
480
|
+
const demoId = typeof data.demoId === "string" && data.demoId.trim() ? data.demoId.trim() : void 0;
|
|
481
|
+
const demoImport = typeof data.demoImport === "string" && data.demoImport.trim() ? data.demoImport.trim() : void 0;
|
|
482
|
+
if ((!files || Object.keys(files).length === 0) && !demoId && !demoImport) {
|
|
363
483
|
return null;
|
|
364
484
|
}
|
|
365
485
|
return {
|
|
@@ -368,7 +488,9 @@ function parsePlaygroundPayload(rawSource) {
|
|
|
368
488
|
framework: data.framework === "vanilla" || data.framework === "vue" || data.framework === "html" ? data.framework : void 0,
|
|
369
489
|
autorun: typeof data.autorun === "boolean" ? data.autorun : void 0,
|
|
370
490
|
showCode: typeof data.showCode === "boolean" ? data.showCode : void 0,
|
|
371
|
-
height: typeof data.height === "number" || typeof data.height === "string" ? data.height : void 0
|
|
491
|
+
height: typeof data.height === "number" || typeof data.height === "string" ? data.height : void 0,
|
|
492
|
+
demoId,
|
|
493
|
+
demoImport
|
|
372
494
|
};
|
|
373
495
|
}
|
|
374
496
|
function parsePlaygroundCodeBlock(token) {
|
|
@@ -380,6 +502,21 @@ function parsePlaygroundCodeBlock(token) {
|
|
|
380
502
|
if (!payload) {
|
|
381
503
|
return null;
|
|
382
504
|
}
|
|
505
|
+
if (payload.demoId || payload.demoImport) {
|
|
506
|
+
return {
|
|
507
|
+
type: "playground",
|
|
508
|
+
framework: payload.framework ?? "vue",
|
|
509
|
+
autorun: payload.autorun,
|
|
510
|
+
showCode: payload.showCode,
|
|
511
|
+
height: payload.height,
|
|
512
|
+
demoId: payload.demoId,
|
|
513
|
+
demoImport: payload.demoImport,
|
|
514
|
+
renderMode: "vue-module"
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
if (!payload.files || Object.keys(payload.files).length === 0) {
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
383
520
|
const entry = payload.entry && payload.files[payload.entry] ? payload.entry : Object.keys(payload.files)[0];
|
|
384
521
|
return {
|
|
385
522
|
type: "playground",
|
|
@@ -388,7 +525,8 @@ function parsePlaygroundCodeBlock(token) {
|
|
|
388
525
|
framework: payload.framework,
|
|
389
526
|
autorun: payload.autorun,
|
|
390
527
|
showCode: payload.showCode,
|
|
391
|
-
height: payload.height
|
|
528
|
+
height: payload.height,
|
|
529
|
+
renderMode: "sandbox"
|
|
392
530
|
};
|
|
393
531
|
}
|
|
394
532
|
function parsePlaygroundSourceCodeBlock(token, sourcePath) {
|
|
@@ -402,7 +540,8 @@ function parsePlaygroundSourceCodeBlock(token, sourcePath) {
|
|
|
402
540
|
files: payload.files,
|
|
403
541
|
entry: payload.entry,
|
|
404
542
|
framework: payload.framework,
|
|
405
|
-
height: payload.height
|
|
543
|
+
height: payload.height,
|
|
544
|
+
renderMode: payload.renderMode ?? "sandbox"
|
|
406
545
|
};
|
|
407
546
|
}
|
|
408
547
|
function renderMarkdown(markdown, tocLevels, sourcePath) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/createViteSsgApp.ts","../src/docsContent.ts","../src/routes.ts","../src/config.ts"],"sourcesContent":["import { createHead as createClientHead } from '@unhead/vue/client'\nimport { createHead as createServerHead } from '@unhead/vue/server'\nimport { createApp, createSSRApp, type Component } from 'vue'\nimport {\n createMemoryHistory,\n createRouter,\n createWebHistory,\n type RouteRecordRaw,\n type Router\n} from 'vue-router'\n\ntype CreateViteSsgContext = {\n app: ReturnType<typeof createApp>\n head: ReturnType<typeof createClientHead> | ReturnType<typeof createServerHead> | undefined\n initialState: Record<string, unknown>\n isClient: boolean\n onSSRAppRendered: (cb: () => void | Promise<void>) => void\n routePath?: string\n router: Router\n routes: RouteRecordRaw[]\n transformState?: (state: Record<string, unknown>) => Record<string, unknown>\n triggerOnSSRAppRendered: () => Promise<void[]>\n}\n\ntype CreateViteSsgOptions = {\n hydration?: boolean\n rootContainer?: string\n useHead?: boolean\n transformState?: (state: Record<string, unknown>) => Record<string, unknown>\n}\n\nasync function documentReady(): Promise<void> {\n if (typeof document === 'undefined' || document.readyState !== 'loading') {\n return\n }\n\n await new Promise<void>((resolve) => {\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true })\n })\n}\n\nasync function nextFrame(): Promise<void> {\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))\n}\n\nfunction isVisibleElement(element: HTMLElement | null): element is HTMLElement {\n return Boolean(element && element.offsetParent !== null)\n}\n\nfunction getStickyOffsetTop(): number {\n if (typeof document === 'undefined') {\n return 0\n }\n\n const header = document.querySelector<HTMLElement>('.vf-document-layout__header')\n const layoutSubheader = document.querySelector<HTMLElement>('.vf-document-layout__subheader')\n const contentSubheader = document.querySelector<HTMLElement>('.vf-document-layout__content-subheader')\n const topGap = 16\n let offset = topGap\n\n if (isVisibleElement(header)) {\n offset += header.getBoundingClientRect().height\n }\n\n if (isVisibleElement(layoutSubheader)) {\n offset += layoutSubheader.getBoundingClientRect().height\n }\n\n if (isVisibleElement(contentSubheader)) {\n offset += contentSubheader.getBoundingClientRect().height\n }\n\n return offset\n}\n\nfunction getInitialState(): Record<string, unknown> {\n if (typeof window === 'undefined') {\n return {}\n }\n\n return ((window as Window & { __INITIAL_STATE__?: Record<string, unknown> }).__INITIAL_STATE__ ?? {})\n}\n\nfunction ensureHistoryState(): void {\n if (typeof window === 'undefined') {\n return\n }\n\n if (window.history.state) {\n return\n }\n\n const current = `${window.location.pathname}${window.location.search}${window.location.hash}`\n\n window.history.replaceState(\n {\n back: null,\n current,\n forward: null,\n position: window.history.length - 1,\n replaced: true,\n scroll: null\n },\n '',\n current\n )\n}\n\nexport function createViteSsgApp(\n App: Component,\n routerOptions: { base?: string; routes: RouteRecordRaw[] },\n fn?: (context: CreateViteSsgContext) => Promise<void> | void,\n options?: CreateViteSsgOptions\n) {\n const { rootContainer = '#app', transformState, useHead = true } = options ?? {}\n\n async function createSsgApp(routePath?: string): Promise<CreateViteSsgContext> {\n const app = import.meta.env.SSR || options?.hydration ? createSSRApp(App) : createApp(App)\n let head: CreateViteSsgContext['head']\n\n if (useHead) {\n head = import.meta.env.SSR ? createServerHead() : createClientHead()\n app.use(head)\n }\n\n const router = createRouter({\n history: import.meta.env.SSR\n ? createMemoryHistory(routerOptions.base)\n : createWebHistory(routerOptions.base),\n scrollBehavior: async (to, _from, savedPosition) => {\n if (savedPosition) {\n return savedPosition\n }\n\n if (to.hash) {\n const targetHash = decodeURIComponent(to.hash)\n\n await nextFrame()\n await nextFrame()\n\n const targetElement = document.querySelector<HTMLElement>(targetHash)\n\n if (targetElement) {\n const top = targetElement.getBoundingClientRect().top + window.scrollY - getStickyOffsetTop()\n\n return {\n left: 0,\n top: Math.max(0, top),\n behavior: 'smooth'\n }\n }\n }\n\n return { left: 0, top: 0 }\n },\n ...routerOptions\n })\n\n const appRenderCallbacks: Array<() => void | Promise<void>> = []\n const onSSRAppRendered = import.meta.env.SSR\n ? (cb: () => void | Promise<void>) => appRenderCallbacks.push(cb)\n : () => undefined\n const triggerOnSSRAppRendered = () => Promise.all(appRenderCallbacks.map((cb) => cb()))\n\n const context: CreateViteSsgContext = {\n app,\n head,\n initialState: {},\n isClient: !import.meta.env.SSR,\n onSSRAppRendered,\n routePath,\n router,\n routes: routerOptions.routes,\n transformState,\n triggerOnSSRAppRendered\n }\n\n if (!import.meta.env.SSR) {\n await documentReady()\n ensureHistoryState()\n context.initialState = transformState?.(getInitialState()) ?? getInitialState()\n }\n\n await fn?.(context)\n app.use(router)\n\n let entryRoutePath: string | undefined\n let isFirstRoute = true\n\n router.beforeEach((to) => {\n if (isFirstRoute || (entryRoutePath && entryRoutePath === to.path)) {\n isFirstRoute = false\n entryRoutePath = to.path\n to.meta.state = context.initialState\n }\n\n return true\n })\n\n if (import.meta.env.SSR) {\n const route = context.routePath ?? '/'\n await router.push(route)\n await router.isReady()\n context.initialState = (router.currentRoute.value.meta.state as Record<string, unknown>) || {}\n }\n\n return context\n }\n\n if (!import.meta.env.SSR) {\n ;(async () => {\n const { app, router } = await createSsgApp()\n await router.isReady()\n app.mount(rootContainer, true)\n })()\n }\n\n return createSsgApp\n}\n","import { Parser, type Tokens, marked } from 'marked'\nimport GithubSlugger from 'github-slugger'\nimport type { VfNavMenuItem, VfTableOfContentsItem } from '@codemonster-ru/vueforge-core'\nimport type {\n DocsComponentsConfig,\n DocsConfig,\n DocsFooterConfig,\n DocsHeaderNavConfig,\n DocsHomeConfig,\n DocsLayoutConfig,\n DocsSiteConfig\n} from './config'\n\nexport type DocsTableAlign = 'left' | 'center' | 'right' | null\nexport type DocsPlaygroundFramework = 'vanilla' | 'vue' | 'html'\n\nexport type DocsContentBlock =\n | {\n type: 'heading'\n depth: 1 | 2 | 3 | 4 | 5 | 6\n id: string\n html: string\n }\n | {\n type: 'paragraph'\n html: string\n }\n | {\n type: 'code'\n code: string\n language: string\n }\n | {\n type: 'playground'\n files: Record<string, string>\n entry: string\n framework?: DocsPlaygroundFramework\n autorun?: boolean\n showCode?: boolean\n height?: number | string\n }\n | {\n type: 'list'\n ordered: boolean\n items: string[]\n }\n | {\n type: 'blockquote'\n html: string\n }\n | {\n type: 'table'\n header: string[]\n rows: string[][]\n align: DocsTableAlign[]\n }\n | {\n type: 'html'\n html: string\n }\n\nexport interface DocsPage {\n id: string\n path: string\n sourcePath: string\n isIndexPage: boolean\n title: string\n navTitle: string\n description?: string\n order: number\n section: string[]\n blocks: DocsContentBlock[]\n tableOfContents: VfTableOfContentsItem[]\n}\n\ninterface Frontmatter {\n title?: string\n navTitle?: string\n description?: string\n order?: number\n}\n\ninterface NavNode {\n label: string\n order: number\n value?: string\n path?: string\n isPage?: boolean\n isIndexPage?: boolean\n children: Map<string, NavNode>\n}\n\ntype TokensList = Tokens.Generic[]\n\nexport interface ResolveDocsContentInput {\n docsConfig: DocsConfig\n markdownFiles: Record<string, string>\n}\n\nexport interface ResolvedDocsContent {\n docsPages: DocsPage[]\n docsSidebar: VfNavMenuItem[]\n docsSite: DocsSiteConfig\n docsLayout: Required<DocsLayoutConfig>\n docsFooter: DocsFooterConfig\n docsHome: Required<DocsHomeConfig>\n docsHeaderNav: Required<DocsHeaderNavConfig>\n docsComponents: DocsComponentsConfig\n docsSiteTitle: string\n docsScrollOffset: number\n getDocsPageByPath: (pathname: string) => DocsPage\n}\n\nfunction parseFrontmatter(source: string): { data: Frontmatter; content: string } {\n if (!source.startsWith('---\\n')) {\n return { data: {}, content: source }\n }\n\n const frontmatterEnd = source.indexOf('\\n---\\n', 4)\n\n if (frontmatterEnd === -1) {\n return { data: {}, content: source }\n }\n\n const rawFrontmatter = source.slice(4, frontmatterEnd)\n const content = source.slice(frontmatterEnd + 5)\n const data: Frontmatter = {}\n\n for (const line of rawFrontmatter.split('\\n')) {\n const separatorIndex = line.indexOf(':')\n\n if (separatorIndex === -1) {\n continue\n }\n\n const key = line.slice(0, separatorIndex).trim()\n const rawValue = line.slice(separatorIndex + 1).trim()\n const normalizedValue = rawValue.replace(/^['\"]|['\"]$/g, '')\n\n if (key === 'order') {\n const numericValue = Number(normalizedValue)\n data.order = Number.isFinite(numericValue) ? numericValue : 0\n continue\n }\n\n if (key === 'title' || key === 'navTitle' || key === 'description') {\n data[key] = normalizedValue\n }\n }\n\n return { data, content }\n}\n\nfunction toTitleCase(value: string): string {\n return value\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (letter) => letter.toUpperCase())\n}\n\nfunction normalizeDocPath(sourcePath: string): string {\n const relativePath = sourcePath.replace(/^.*\\/(?:content|docs)\\//, '').replace(/\\.md$/, '')\n\n if (relativePath === 'index') {\n return '/'\n }\n\n if (relativePath.endsWith('/index')) {\n return `/${relativePath.replace(/\\/index$/, '')}`\n }\n\n return `/${relativePath}`\n}\n\nfunction isIndexSourcePath(sourcePath: string): boolean {\n return sourcePath.replace(/\\\\/g, '/').replace(/\\.md$/, '').endsWith('/index')\n}\n\nfunction normalizeMarkdownLinkHref(href: string): string {\n if (\n href.startsWith('#') ||\n href.startsWith('//') ||\n /^[a-z][a-z\\d+.-]*:/i.test(href)\n ) {\n return href\n }\n\n const match = href.match(/^([^?#]*)([?#].*)?$/)\n\n if (!match) {\n return href\n }\n\n const [, pathname, suffix = ''] = match\n\n if (!/\\.(?:md|mdx)$/i.test(pathname)) {\n return href\n }\n\n const extensionlessPathname = pathname.replace(/\\.(?:md|mdx)$/i, '')\n let normalizedPathname = extensionlessPathname\n\n if (extensionlessPathname === 'index' || extensionlessPathname === './index') {\n normalizedPathname = '.'\n } else if (extensionlessPathname.endsWith('/index')) {\n normalizedPathname = extensionlessPathname.replace(/\\/index$/, '')\n }\n\n return `${normalizedPathname}${suffix}`\n}\n\nfunction normalizeMarkdownLinks(tokens: TokensList): void {\n for (const token of tokens) {\n if (token.type === 'link' && typeof token.href === 'string') {\n token.href = normalizeMarkdownLinkHref(token.href)\n }\n\n if ('tokens' in token && Array.isArray(token.tokens)) {\n normalizeMarkdownLinks(token.tokens as TokensList)\n }\n\n if (token.type === 'list' && Array.isArray(token.items)) {\n for (const item of token.items) {\n normalizeMarkdownLinks(item.tokens as TokensList)\n }\n }\n }\n}\n\nfunction toValueFromPath(path: string): string {\n return path === '/' ? 'index' : path.replace(/^\\//, '').replace(/\\//g, '-')\n}\n\nfunction renderInline(tokens: Tokens.Generic[] | undefined): string {\n return Parser.parseInline(tokens ?? [])\n}\n\nfunction renderBlockTokens(tokens: TokensList | undefined): string {\n return Parser.parse(tokens ?? [])\n}\n\nfunction renderListItemTokens(tokens: TokensList | undefined): string {\n return Parser.parse(tokens ?? [])\n}\n\nfunction normalizeTableAlign(align: Array<string | null | undefined>): DocsTableAlign[] {\n return align.map((value) => {\n if (value === 'left' || value === 'center' || value === 'right') {\n return value\n }\n\n return null\n })\n}\n\ninterface PlaygroundPayload {\n files: Record<string, string>\n entry?: string\n framework?: DocsPlaygroundFramework\n autorun?: boolean\n showCode?: boolean\n height?: number | string\n}\n\ninterface PlaygroundSrcPayload {\n files: Record<string, string>\n entry: string\n framework?: DocsPlaygroundFramework\n height?: number\n}\n\nfunction parsePlaygroundSourceHeader(text: string, sourcePath: string): {\n framework?: DocsPlaygroundFramework\n height?: number\n entry: string\n} {\n const lines = text\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n const metadata = new Map<string, string>()\n\n for (const line of lines) {\n const separatorIndex = line.indexOf(':')\n\n if (separatorIndex === -1) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: expected \"key: value\", got \"${line}\"`)\n }\n\n const key = line.slice(0, separatorIndex).trim()\n const value = line.slice(separatorIndex + 1).trim()\n\n metadata.set(key, value)\n }\n\n const frameworkRaw = metadata.get('framework')\n const framework = frameworkRaw || 'vanilla'\n const heightRaw = metadata.get('height')\n const entry = metadata.get('entry')\n\n if (!entry) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: \"entry\" is required`)\n }\n\n if (framework !== 'vanilla' && framework !== 'vue' && framework !== 'html') {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: unsupported framework \"${framework}\"`)\n }\n\n let height: number | undefined\n\n if (heightRaw !== undefined) {\n height = Number(heightRaw)\n\n if (!Number.isFinite(height)) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: \"height\" must be a number`)\n }\n }\n\n return {\n framework,\n entry,\n height\n }\n}\n\nfunction parsePlaygroundSourcePayload(rawSource: string, sourcePath: string): PlaygroundSrcPayload {\n const nestedTokens = marked.lexer(rawSource) as TokensList\n let metadataToken: Tokens.Paragraph | null = null\n const codeTokens: Tokens.Code[] = []\n\n for (const token of nestedTokens) {\n if (token.type === 'space') {\n continue\n }\n\n if (!metadataToken) {\n if (token.type !== 'paragraph') {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: header metadata must be the first block`)\n }\n\n metadataToken = token as Tokens.Paragraph\n continue\n }\n\n if (token.type !== 'code') {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: only code fences are allowed after header`)\n }\n\n codeTokens.push(token as Tokens.Code)\n }\n\n if (!metadataToken) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: missing header metadata`)\n }\n\n const { framework, height, entry } = parsePlaygroundSourceHeader(metadataToken.text, sourcePath)\n const files: Record<string, string> = {}\n\n for (const codeToken of codeTokens) {\n const lang = codeToken.lang?.trim() ?? ''\n const fileMatch = lang.match(/(?:^|\\s)file=([^\\s]+)/)\n\n if (!fileMatch?.[1]) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: each code fence must define \"file=/path\"`)\n }\n\n const filePath = fileMatch[1]\n const content = codeToken.text.endsWith('\\n') ? codeToken.text : `${codeToken.text}\\n`\n files[filePath] = content\n }\n\n if (Object.keys(files).length === 0) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: at least one file fence is required`)\n }\n\n if (!files[entry]) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: entry \"${entry}\" is not present in files`)\n }\n\n return {\n files,\n entry,\n framework,\n height\n }\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string')\n}\n\nfunction parsePlaygroundPayload(rawSource: string): PlaygroundPayload | null {\n let parsed: unknown\n\n try {\n parsed = JSON.parse(rawSource)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null\n }\n\n const data = parsed as {\n files?: unknown\n entry?: unknown\n framework?: unknown\n autorun?: unknown\n showCode?: unknown\n height?: unknown\n }\n\n const files = isStringRecord(data.files) ? data.files : null\n\n if (!files || Object.keys(files).length === 0) {\n return null\n }\n\n return {\n files,\n entry: typeof data.entry === 'string' ? data.entry : undefined,\n framework:\n data.framework === 'vanilla' || data.framework === 'vue' || data.framework === 'html'\n ? data.framework\n : undefined,\n autorun: typeof data.autorun === 'boolean' ? data.autorun : undefined,\n showCode: typeof data.showCode === 'boolean' ? data.showCode : undefined,\n height:\n typeof data.height === 'number' || typeof data.height === 'string' ? data.height : undefined\n }\n}\n\nfunction parsePlaygroundCodeBlock(token: Tokens.Code): DocsContentBlock | null {\n const language = token.lang?.trim().toLowerCase()\n\n if (language !== 'playground' && language !== 'vf-playground') {\n return null\n }\n\n const payload = parsePlaygroundPayload(token.text)\n\n if (!payload) {\n return null\n }\n\n const entry = payload.entry && payload.files[payload.entry]\n ? payload.entry\n : Object.keys(payload.files)[0]\n\n return {\n type: 'playground',\n files: payload.files,\n entry,\n framework: payload.framework,\n autorun: payload.autorun,\n showCode: payload.showCode,\n height: payload.height\n }\n}\n\nfunction parsePlaygroundSourceCodeBlock(token: Tokens.Code, sourcePath: string): DocsContentBlock | null {\n const language = token.lang?.trim().toLowerCase()\n\n if (language !== 'playground-src' && language !== 'vf-playground-src') {\n return null\n }\n\n const payload = parsePlaygroundSourcePayload(token.text, sourcePath)\n\n return {\n type: 'playground',\n files: payload.files,\n entry: payload.entry,\n framework: payload.framework,\n height: payload.height\n }\n}\n\nfunction renderMarkdown(markdown: string, tocLevels: Set<number>, sourcePath: string): {\n blocks: DocsContentBlock[]\n tableOfContents: VfTableOfContentsItem[]\n} {\n const tokens = marked.lexer(markdown) as TokensList\n normalizeMarkdownLinks(tokens)\n const headingSlugger = new GithubSlugger()\n const tableOfContents: VfTableOfContentsItem[] = []\n const blocks: DocsContentBlock[] = []\n\n for (const token of tokens) {\n switch (token.type) {\n case 'space':\n break\n case 'heading': {\n const id = headingSlugger.slug(token.text)\n const html = renderInline(token.tokens)\n\n blocks.push({\n type: 'heading',\n depth: token.depth as 1 | 2 | 3 | 4 | 5 | 6,\n id,\n html\n })\n\n if (tocLevels.has(token.depth)) {\n tableOfContents.push({\n id,\n label: token.text,\n level: token.depth - 1\n })\n }\n break\n }\n case 'paragraph':\n blocks.push({\n type: 'paragraph',\n html: renderInline(token.tokens)\n })\n break\n case 'code':\n {\n const playgroundSourceBlock = parsePlaygroundSourceCodeBlock(token as Tokens.Code, sourcePath)\n\n if (playgroundSourceBlock) {\n blocks.push(playgroundSourceBlock)\n break\n }\n\n const playgroundBlock = parsePlaygroundCodeBlock(token as Tokens.Code)\n\n if (playgroundBlock) {\n blocks.push(playgroundBlock)\n break\n }\n }\n blocks.push({\n type: 'code',\n code: token.text,\n language: token.lang?.trim() || 'text'\n })\n break\n case 'list':\n blocks.push({\n type: 'list',\n ordered: token.ordered,\n items: token.items.map((item: Tokens.ListItem) => renderListItemTokens(item.tokens))\n })\n break\n case 'blockquote':\n blocks.push({\n type: 'blockquote',\n html: renderBlockTokens(token.tokens)\n })\n break\n case 'table':\n blocks.push({\n type: 'table',\n header: token.header.map((cell: Tokens.TableCell) => renderInline(cell.tokens)),\n rows: token.rows.map((row: Tokens.TableCell[]) => row.map((cell) => renderInline(cell.tokens))),\n align: normalizeTableAlign(token.align)\n })\n break\n default:\n blocks.push({\n type: 'html',\n html: renderBlockTokens([token])\n })\n break\n }\n }\n\n return { blocks, tableOfContents }\n}\n\nfunction getFirstHeadingText(markdown: string): string | undefined {\n const tokens = marked.lexer(markdown) as TokensList\n const heading = tokens.find((token): token is Tokens.Heading => token.type === 'heading' && token.depth === 1)\n\n return heading?.text.trim() || undefined\n}\n\nfunction parsePage(sourcePath: string, source: string, tocLevels: Set<number>): DocsPage {\n const { data: frontmatter, content } = parseFrontmatter(source)\n const path = normalizeDocPath(sourcePath)\n const pathSegments = path === '/' ? [] : path.replace(/^\\//, '').split('/')\n const isIndexPage = isIndexSourcePath(sourcePath)\n const section = isIndexPage ? pathSegments : pathSegments.slice(0, -1)\n const filename = pathSegments[pathSegments.length - 1] ?? 'index'\n const fallbackTitle = isIndexPage ? (getFirstHeadingText(content) ?? 'Overview') : toTitleCase(filename)\n const title = frontmatter.title?.trim() || fallbackTitle\n const navTitle = frontmatter.navTitle?.trim() || (isIndexPage ? 'Overview' : title)\n const { blocks, tableOfContents } = renderMarkdown(content, tocLevels, sourcePath)\n const id = isIndexPage && path !== '/' ? `${toValueFromPath(path)}-index` : toValueFromPath(path)\n\n return {\n id,\n path,\n sourcePath,\n isIndexPage,\n title,\n navTitle,\n description: frontmatter.description?.trim(),\n order: frontmatter.order ?? 0,\n section,\n blocks,\n tableOfContents\n }\n}\n\nfunction sortNodes(nodes: NavNode[]): NavNode[] {\n return [...nodes].sort((left, right) => {\n if (left.order !== right.order) {\n return left.order - right.order\n }\n\n const leftIndexPriority = left.isIndexPage ? 0 : 1\n const rightIndexPriority = right.isIndexPage ? 0 : 1\n\n if (leftIndexPriority !== rightIndexPriority) {\n return leftIndexPriority - rightIndexPriority\n }\n\n return left.label.localeCompare(right.label)\n })\n}\n\nfunction getPageNavKey(page: DocsPage): string {\n if (page.isIndexPage) {\n return 'index'\n }\n\n return page.path.split('/').filter(Boolean).at(-1) ?? page.id\n}\n\nfunction buildSidebar(pages: DocsPage[], docsConfig: DocsConfig): VfNavMenuItem[] {\n const root = new Map<string, NavNode>()\n\n for (const page of pages) {\n let current = root\n let currentPath = ''\n\n for (const segment of page.section) {\n currentPath = `${currentPath}/${segment}`\n const sectionConfig = docsConfig.sectionLabels?.[segment]\n\n if (!current.has(segment)) {\n current.set(segment, {\n label: sectionConfig?.label ?? toTitleCase(segment),\n order: sectionConfig?.order ?? 1_000,\n value: toValueFromPath(currentPath),\n path: currentPath,\n isPage: false,\n children: new Map()\n })\n }\n\n current = current.get(segment)!.children\n }\n\n const pageKey = getPageNavKey(page)\n const existingPageNode = current.get(pageKey)\n\n current.set(pageKey, {\n label: page.navTitle,\n order: page.order,\n value: page.id,\n path: page.path,\n isPage: true,\n isIndexPage: page.isIndexPage,\n children: existingPageNode?.children ?? new Map()\n })\n }\n\n const toItems = (nodes: Map<string, NavNode>): VfNavMenuItem[] =>\n sortNodes([...nodes.values()]).map((node) => {\n const item: VfNavMenuItem = {\n value: node.value ?? toValueFromPath(node.path ?? node.label),\n label: node.label\n }\n\n const children = toItems(node.children)\n\n if (node.path && node.isPage) {\n item.to = node.path\n }\n\n if (children.length > 0) {\n if (item.to) {\n const branchValue = `${item.value}-section`\n\n item.children = [\n {\n value: item.value,\n label: 'Overview',\n to: item.to\n },\n ...children\n ]\n item.value = branchValue\n delete item.to\n } else {\n item.children = children\n }\n }\n\n return item\n })\n\n return toItems(root)\n}\n\nexport function resolveDocsContent({ docsConfig, markdownFiles }: ResolveDocsContentInput): ResolvedDocsContent {\n const tocLevels = new Set(docsConfig.toc?.levels ?? [2, 3, 4])\n\n const docsPages = Object.entries(markdownFiles)\n .map(([sourcePath, source]) => parsePage(sourcePath, source, tocLevels))\n .filter((page) => page.path !== '/')\n .sort((left, right) => left.path.localeCompare(right.path))\n\n const docsSidebar = buildSidebar(docsPages, docsConfig)\n const docsSite: DocsSiteConfig = {\n title: docsConfig.site?.title ?? docsConfig.title ?? 'docs',\n description: docsConfig.site?.description,\n githubUrl: docsConfig.site?.githubUrl,\n homeTo: docsConfig.site?.homeTo ?? '/',\n favicon: docsConfig.site?.favicon,\n logo: docsConfig.site?.logo,\n logoLabel: docsConfig.site?.logoLabel\n }\n const docsLayout: Required<DocsLayoutConfig> = {\n variant: docsConfig.layout?.variant ?? 'sidebar-content-aside',\n fillViewport: docsConfig.layout?.fillViewport ?? true,\n stickyHeader: docsConfig.layout?.stickyHeader ?? true,\n stickySidebar: docsConfig.layout?.stickySidebar ?? true,\n stickyAside: docsConfig.layout?.stickyAside ?? true,\n edgeNotches: docsConfig.layout?.edgeNotches ?? false,\n hideSidebarOnMobile: docsConfig.layout?.hideSidebarOnMobile ?? true,\n hideAsideOnMobile: docsConfig.layout?.hideAsideOnMobile ?? true\n }\n const docsFooter: DocsFooterConfig = {\n left: docsConfig.footer?.left ?? 'Codemonster documentation',\n right: docsConfig.footer?.right\n }\n const docsHome: Required<DocsHomeConfig> = {\n enabled: docsConfig.home?.enabled ?? true,\n title: docsConfig.home?.title ?? 'Build docs fast',\n description: docsConfig.home?.description ?? 'Write markdown, keep the same UI stack, and ship clean developer docs.',\n showGrid: docsConfig.home?.showGrid ?? true,\n primaryAction: docsConfig.home?.primaryAction ?? {\n label: 'Get Started',\n to: '/guide/installation'\n },\n secondaryAction: docsConfig.home?.secondaryAction ?? {\n label: 'View on GitHub',\n href: docsConfig.site?.githubUrl\n }\n }\n const docsHeaderNav: Required<DocsHeaderNavConfig> = {\n items: docsConfig.headerNav?.items ?? [],\n ariaLabel: docsConfig.headerNav?.ariaLabel ?? 'Header navigation'\n }\n const docsComponents: DocsComponentsConfig = docsConfig.components ?? {}\n const docsSiteTitle = docsSite.title\n const docsScrollOffset = docsConfig.toc?.scrollOffset ?? 96\n\n function getDocsPageByPath(pathname: string): DocsPage {\n const normalizedPath = pathname === '/' ? '/' : pathname.replace(/\\/$/, '')\n\n return docsPages.find((page) => page.path === normalizedPath) ?? docsPages[0]\n }\n\n return {\n docsPages,\n docsSidebar,\n docsSite,\n docsLayout,\n docsFooter,\n docsHome,\n docsHeaderNav,\n docsComponents,\n docsSiteTitle,\n docsScrollOffset,\n getDocsPageByPath\n }\n}\n","import type { Component } from 'vue'\nimport type { RouteRecordRaw } from 'vue-router'\nimport type { DocsPage } from './docsContent'\n\nexport interface CreateDocsRoutesInput {\n docsPages: DocsPage[]\n homeEnabled: boolean\n homeComponent: Component\n pageComponent: Component\n notFoundComponent?: Component\n}\n\nexport function createDocsRoutes({\n docsPages,\n homeEnabled,\n homeComponent,\n pageComponent,\n notFoundComponent\n}: CreateDocsRoutesInput): RouteRecordRaw[] {\n const docsPageRoutes: RouteRecordRaw[] = docsPages.map((page) => ({\n path: page.path,\n name: page.id,\n component: pageComponent\n }))\n\n const docsLandingRoute = [...docsPages].sort((left, right) => {\n if (left.order !== right.order) {\n return left.order - right.order\n }\n\n return left.path.localeCompare(right.path)\n })[0]\n\n const rootRoute: RouteRecordRaw = homeEnabled\n ? {\n path: '/',\n name: 'home',\n component: homeComponent\n }\n : docsLandingRoute\n ? {\n path: '/',\n name: 'home',\n redirect: docsLandingRoute.path\n }\n : {\n path: '/',\n name: 'home',\n component: homeComponent\n }\n\n const routes: RouteRecordRaw[] = [rootRoute, ...docsPageRoutes]\n\n if (notFoundComponent) {\n routes.push({\n path: '/:pathMatch(.*)*',\n name: 'not-found',\n component: notFoundComponent\n })\n }\n\n return routes\n}\n","import type { Component } from 'vue'\nimport type { VfNavMenuItem, VfTableOfContentsItem } from '@codemonster-ru/vueforge-core'\n\nexport interface DocsSectionConfig {\n label?: string\n order?: number\n}\n\nexport interface DocsTocConfig {\n levels?: number[]\n scrollOffset?: number\n}\n\nexport interface DocsSiteLogoConfig {\n src?: string\n component?: Component\n alt?: string\n width?: number | string\n height?: number | string\n}\n\nexport interface DocsHomeActionConfig {\n label: string\n to?: string\n href?: string\n}\n\nexport interface DocsHomeConfig {\n enabled?: boolean\n title?: string\n description?: string\n showGrid?: boolean\n primaryAction?: DocsHomeActionConfig\n secondaryAction?: DocsHomeActionConfig\n}\n\nexport interface DocsHeaderNavConfig {\n items?: VfNavMenuItem[]\n ariaLabel?: string\n}\n\nexport type DocsLayoutVariant =\n | 'content'\n | 'sidebar-content'\n | 'sidebar-content-aside'\n\nexport interface DocsSiteConfig {\n title: string\n description?: string\n githubUrl?: string\n homeTo?: string\n favicon?: string\n logo?: DocsSiteLogoConfig\n logoLabel?: string\n}\n\nexport interface DocsLayoutConfig {\n variant?: DocsLayoutVariant\n fillViewport?: boolean\n stickyHeader?: boolean\n stickySidebar?: boolean\n stickyAside?: boolean\n edgeNotches?: boolean\n hideSidebarOnMobile?: boolean\n hideAsideOnMobile?: boolean\n}\n\nexport interface DocsFooterConfig {\n left?: string\n right?: string\n}\n\nexport interface DocsPageMeta {\n title: string\n path: string\n}\n\nexport interface DocsHeaderProps {\n site: DocsSiteConfig\n}\n\nexport interface DocsBrandProps {\n site: DocsSiteConfig\n}\n\nexport interface DocsFooterProps {\n site: DocsSiteConfig\n}\n\nexport interface DocsHeaderNavProps {\n site: DocsSiteConfig\n items: VfNavMenuItem[]\n activeValue?: string\n}\n\nexport interface DocsSidebarProps {\n site: DocsSiteConfig\n page: DocsPageMeta\n items: VfNavMenuItem[]\n}\n\nexport interface DocsAsideProps {\n site: DocsSiteConfig\n page: DocsPageMeta\n items: VfTableOfContentsItem[]\n}\n\nexport interface DocsLayoutProps {\n site: DocsSiteConfig\n page: DocsPageMeta\n layout: Required<DocsLayoutConfig>\n sidebarItems: VfNavMenuItem[]\n tocItems: VfTableOfContentsItem[]\n}\n\nexport interface DocsComponentsConfig {\n Brand?: Component\n Home?: Component\n Header?: Component\n HeaderNav?: Component\n Footer?: Component\n SidebarTop?: Component\n SidebarBottom?: Component\n AsideTop?: Component\n AsideBottom?: Component\n Layout?: Component\n}\n\nexport interface DocsConfig {\n title?: string\n site?: Partial<DocsSiteConfig>\n home?: DocsHomeConfig\n headerNav?: DocsHeaderNavConfig\n layout?: DocsLayoutConfig\n footer?: DocsFooterConfig\n components?: DocsComponentsConfig\n sectionLabels?: Record<string, DocsSectionConfig>\n toc?: DocsTocConfig\n}\n\nexport function defineDocsConfig(config: DocsConfig): DocsConfig {\n return config\n}\n"],"mappings":";AAAA,SAAS,cAAc,wBAAwB;AAC/C,SAAS,cAAc,wBAAwB;AAC/C,SAAS,WAAW,oBAAoC;AACxD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAsBP,eAAe,gBAA+B;AAC5C,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,WAAW;AACxE;AAAA,EACF;AAEA,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,aAAS,iBAAiB,oBAAoB,MAAM,QAAQ,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EAC/E,CAAC;AACH;AAEA,eAAe,YAA2B;AACxC,QAAM,IAAI,QAAc,CAAC,YAAY,sBAAsB,MAAM,QAAQ,CAAC,CAAC;AAC7E;AAEA,SAAS,iBAAiB,SAAqD;AAC7E,SAAO,QAAQ,WAAW,QAAQ,iBAAiB,IAAI;AACzD;AAEA,SAAS,qBAA6B;AACpC,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,SAAS,cAA2B,6BAA6B;AAChF,QAAM,kBAAkB,SAAS,cAA2B,gCAAgC;AAC5F,QAAM,mBAAmB,SAAS,cAA2B,wCAAwC;AACrG,QAAM,SAAS;AACf,MAAI,SAAS;AAEb,MAAI,iBAAiB,MAAM,GAAG;AAC5B,cAAU,OAAO,sBAAsB,EAAE;AAAA,EAC3C;AAEA,MAAI,iBAAiB,eAAe,GAAG;AACrC,cAAU,gBAAgB,sBAAsB,EAAE;AAAA,EACpD;AAEA,MAAI,iBAAiB,gBAAgB,GAAG;AACtC,cAAU,iBAAiB,sBAAsB,EAAE;AAAA,EACrD;AAEA,SAAO;AACT;AAEA,SAAS,kBAA2C;AAClD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,CAAC;AAAA,EACV;AAEA,SAAS,OAAoE,qBAAqB,CAAC;AACrG;AAEA,SAAS,qBAA2B;AAClC,MAAI,OAAO,WAAW,aAAa;AACjC;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,OAAO;AACxB;AAAA,EACF;AAEA,QAAM,UAAU,GAAG,OAAO,SAAS,QAAQ,GAAG,OAAO,SAAS,MAAM,GAAG,OAAO,SAAS,IAAI;AAE3F,SAAO,QAAQ;AAAA,IACb;AAAA,MACE,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,MACT,UAAU,OAAO,QAAQ,SAAS;AAAA,MAClC,UAAU;AAAA,MACV,QAAQ;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,iBACd,KACA,eACA,IACA,SACA;AACA,QAAM,EAAE,gBAAgB,QAAQ,gBAAgB,UAAU,KAAK,IAAI,WAAW,CAAC;AAE/E,iBAAe,aAAa,WAAmD;AAC7E,UAAM,MAAM,YAAY,IAAI,OAAO,SAAS,YAAY,aAAa,GAAG,IAAI,UAAU,GAAG;AACzF,QAAI;AAEJ,QAAI,SAAS;AACX,aAAO,YAAY,IAAI,MAAM,iBAAiB,IAAI,iBAAiB;AACnE,UAAI,IAAI,IAAI;AAAA,IACd;AAEA,UAAM,SAAS,aAAa;AAAA,MAC1B,SAAS,YAAY,IAAI,MACrB,oBAAoB,cAAc,IAAI,IACtC,iBAAiB,cAAc,IAAI;AAAA,MACvC,gBAAgB,OAAO,IAAI,OAAO,kBAAkB;AAClD,YAAI,eAAe;AACjB,iBAAO;AAAA,QACT;AAEA,YAAI,GAAG,MAAM;AACX,gBAAM,aAAa,mBAAmB,GAAG,IAAI;AAE7C,gBAAM,UAAU;AAChB,gBAAM,UAAU;AAEhB,gBAAM,gBAAgB,SAAS,cAA2B,UAAU;AAEpE,cAAI,eAAe;AACjB,kBAAM,MAAM,cAAc,sBAAsB,EAAE,MAAM,OAAO,UAAU,mBAAmB;AAE5F,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,KAAK,KAAK,IAAI,GAAG,GAAG;AAAA,cACpB,UAAU;AAAA,YACZ;AAAA,UACF;AAAA,QACF;AAEA,eAAO,EAAE,MAAM,GAAG,KAAK,EAAE;AAAA,MAC3B;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAED,UAAM,qBAAwD,CAAC;AAC/D,UAAM,mBAAmB,YAAY,IAAI,MACrC,CAAC,OAAmC,mBAAmB,KAAK,EAAE,IAC9D,MAAM;AACV,UAAM,0BAA0B,MAAM,QAAQ,IAAI,mBAAmB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;AAEtF,UAAM,UAAgC;AAAA,MACpC;AAAA,MACA;AAAA,MACA,cAAc,CAAC;AAAA,MACf,UAAU,CAAC,YAAY,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,cAAc;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAEA,QAAI,CAAC,YAAY,IAAI,KAAK;AACxB,YAAM,cAAc;AACpB,yBAAmB;AACnB,cAAQ,eAAe,iBAAiB,gBAAgB,CAAC,KAAK,gBAAgB;AAAA,IAChF;AAEA,UAAM,KAAK,OAAO;AAClB,QAAI,IAAI,MAAM;AAEd,QAAI;AACJ,QAAI,eAAe;AAEnB,WAAO,WAAW,CAAC,OAAO;AACxB,UAAI,gBAAiB,kBAAkB,mBAAmB,GAAG,MAAO;AAClE,uBAAe;AACf,yBAAiB,GAAG;AACpB,WAAG,KAAK,QAAQ,QAAQ;AAAA,MAC1B;AAEA,aAAO;AAAA,IACT,CAAC;AAED,QAAI,YAAY,IAAI,KAAK;AACvB,YAAM,QAAQ,QAAQ,aAAa;AACnC,YAAM,OAAO,KAAK,KAAK;AACvB,YAAM,OAAO,QAAQ;AACrB,cAAQ,eAAgB,OAAO,aAAa,MAAM,KAAK,SAAqC,CAAC;AAAA,IAC/F;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,YAAY,IAAI,KAAK;AACxB;AAAC,KAAC,YAAY;AACZ,YAAM,EAAE,KAAK,OAAO,IAAI,MAAM,aAAa;AAC3C,YAAM,OAAO,QAAQ;AACrB,UAAI,MAAM,eAAe,IAAI;AAAA,IAC/B,GAAG;AAAA,EACL;AAEA,SAAO;AACT;;;AC1NA,SAAS,QAAqB,cAAc;AAC5C,OAAO,mBAAmB;AAgH1B,SAAS,iBAAiB,QAAwD;AAChF,MAAI,CAAC,OAAO,WAAW,OAAO,GAAG;AAC/B,WAAO,EAAE,MAAM,CAAC,GAAG,SAAS,OAAO;AAAA,EACrC;AAEA,QAAM,iBAAiB,OAAO,QAAQ,WAAW,CAAC;AAElD,MAAI,mBAAmB,IAAI;AACzB,WAAO,EAAE,MAAM,CAAC,GAAG,SAAS,OAAO;AAAA,EACrC;AAEA,QAAM,iBAAiB,OAAO,MAAM,GAAG,cAAc;AACrD,QAAM,UAAU,OAAO,MAAM,iBAAiB,CAAC;AAC/C,QAAM,OAAoB,CAAC;AAE3B,aAAW,QAAQ,eAAe,MAAM,IAAI,GAAG;AAC7C,UAAM,iBAAiB,KAAK,QAAQ,GAAG;AAEvC,QAAI,mBAAmB,IAAI;AACzB;AAAA,IACF;AAEA,UAAM,MAAM,KAAK,MAAM,GAAG,cAAc,EAAE,KAAK;AAC/C,UAAM,WAAW,KAAK,MAAM,iBAAiB,CAAC,EAAE,KAAK;AACrD,UAAM,kBAAkB,SAAS,QAAQ,gBAAgB,EAAE;AAE3D,QAAI,QAAQ,SAAS;AACnB,YAAM,eAAe,OAAO,eAAe;AAC3C,WAAK,QAAQ,OAAO,SAAS,YAAY,IAAI,eAAe;AAC5D;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,QAAQ,cAAc,QAAQ,eAAe;AAClE,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,QAAQ;AACzB;AAEA,SAAS,YAAY,OAAuB;AAC1C,SAAO,MACJ,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,CAAC,WAAW,OAAO,YAAY,CAAC;AACtD;AAEA,SAAS,iBAAiB,YAA4B;AACpD,QAAM,eAAe,WAAW,QAAQ,2BAA2B,EAAE,EAAE,QAAQ,SAAS,EAAE;AAE1F,MAAI,iBAAiB,SAAS;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,SAAS,QAAQ,GAAG;AACnC,WAAO,IAAI,aAAa,QAAQ,YAAY,EAAE,CAAC;AAAA,EACjD;AAEA,SAAO,IAAI,YAAY;AACzB;AAEA,SAAS,kBAAkB,YAA6B;AACtD,SAAO,WAAW,QAAQ,OAAO,GAAG,EAAE,QAAQ,SAAS,EAAE,EAAE,SAAS,QAAQ;AAC9E;AAEA,SAAS,0BAA0B,MAAsB;AACvD,MACE,KAAK,WAAW,GAAG,KACnB,KAAK,WAAW,IAAI,KACpB,sBAAsB,KAAK,IAAI,GAC/B;AACA,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,KAAK,MAAM,qBAAqB;AAE9C,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,EAAE,UAAU,SAAS,EAAE,IAAI;AAElC,MAAI,CAAC,iBAAiB,KAAK,QAAQ,GAAG;AACpC,WAAO;AAAA,EACT;AAEA,QAAM,wBAAwB,SAAS,QAAQ,kBAAkB,EAAE;AACnE,MAAI,qBAAqB;AAEzB,MAAI,0BAA0B,WAAW,0BAA0B,WAAW;AAC5E,yBAAqB;AAAA,EACvB,WAAW,sBAAsB,SAAS,QAAQ,GAAG;AACnD,yBAAqB,sBAAsB,QAAQ,YAAY,EAAE;AAAA,EACnE;AAEA,SAAO,GAAG,kBAAkB,GAAG,MAAM;AACvC;AAEA,SAAS,uBAAuB,QAA0B;AACxD,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,UAAU;AAC3D,YAAM,OAAO,0BAA0B,MAAM,IAAI;AAAA,IACnD;AAEA,QAAI,YAAY,SAAS,MAAM,QAAQ,MAAM,MAAM,GAAG;AACpD,6BAAuB,MAAM,MAAoB;AAAA,IACnD;AAEA,QAAI,MAAM,SAAS,UAAU,MAAM,QAAQ,MAAM,KAAK,GAAG;AACvD,iBAAW,QAAQ,MAAM,OAAO;AAC9B,+BAAuB,KAAK,MAAoB;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,MAAsB;AAC7C,SAAO,SAAS,MAAM,UAAU,KAAK,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG;AAC5E;AAEA,SAAS,aAAa,QAA8C;AAClE,SAAO,OAAO,YAAY,UAAU,CAAC,CAAC;AACxC;AAEA,SAAS,kBAAkB,QAAwC;AACjE,SAAO,OAAO,MAAM,UAAU,CAAC,CAAC;AAClC;AAEA,SAAS,qBAAqB,QAAwC;AACpE,SAAO,OAAO,MAAM,UAAU,CAAC,CAAC;AAClC;AAEA,SAAS,oBAAoB,OAA2D;AACtF,SAAO,MAAM,IAAI,CAAC,UAAU;AAC1B,QAAI,UAAU,UAAU,UAAU,YAAY,UAAU,SAAS;AAC/D,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAkBA,SAAS,4BAA4B,MAAc,YAIjD;AACA,QAAM,QAAQ,KACX,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO;AACjB,QAAM,WAAW,oBAAI,IAAoB;AAEzC,aAAW,QAAQ,OAAO;AACxB,UAAM,iBAAiB,KAAK,QAAQ,GAAG;AAEvC,QAAI,mBAAmB,IAAI;AACzB,YAAM,IAAI,MAAM,oCAAoC,UAAU,iCAAiC,IAAI,GAAG;AAAA,IACxG;AAEA,UAAM,MAAM,KAAK,MAAM,GAAG,cAAc,EAAE,KAAK;AAC/C,UAAM,QAAQ,KAAK,MAAM,iBAAiB,CAAC,EAAE,KAAK;AAElD,aAAS,IAAI,KAAK,KAAK;AAAA,EACzB;AAEA,QAAM,eAAe,SAAS,IAAI,WAAW;AAC7C,QAAM,YAAY,gBAAgB;AAClC,QAAM,YAAY,SAAS,IAAI,QAAQ;AACvC,QAAM,QAAQ,SAAS,IAAI,OAAO;AAElC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,oCAAoC,UAAU,uBAAuB;AAAA,EACvF;AAEA,MAAI,cAAc,aAAa,cAAc,SAAS,cAAc,QAAQ;AAC1E,UAAM,IAAI,MAAM,oCAAoC,UAAU,4BAA4B,SAAS,GAAG;AAAA,EACxG;AAEA,MAAI;AAEJ,MAAI,cAAc,QAAW;AAC3B,aAAS,OAAO,SAAS;AAEzB,QAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,YAAM,IAAI,MAAM,oCAAoC,UAAU,6BAA6B;AAAA,IAC7F;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,6BAA6B,WAAmB,YAA0C;AACjG,QAAM,eAAe,OAAO,MAAM,SAAS;AAC3C,MAAI,gBAAyC;AAC7C,QAAM,aAA4B,CAAC;AAEnC,aAAW,SAAS,cAAc;AAChC,QAAI,MAAM,SAAS,SAAS;AAC1B;AAAA,IACF;AAEA,QAAI,CAAC,eAAe;AAClB,UAAI,MAAM,SAAS,aAAa;AAC9B,cAAM,IAAI,MAAM,oCAAoC,UAAU,2CAA2C;AAAA,MAC3G;AAEA,sBAAgB;AAChB;AAAA,IACF;AAEA,QAAI,MAAM,SAAS,QAAQ;AACzB,YAAM,IAAI,MAAM,oCAAoC,UAAU,6CAA6C;AAAA,IAC7G;AAEA,eAAW,KAAK,KAAoB;AAAA,EACtC;AAEA,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,oCAAoC,UAAU,2BAA2B;AAAA,EAC3F;AAEA,QAAM,EAAE,WAAW,QAAQ,MAAM,IAAI,4BAA4B,cAAc,MAAM,UAAU;AAC/F,QAAM,QAAgC,CAAC;AAEvC,aAAW,aAAa,YAAY;AAClC,UAAM,OAAO,UAAU,MAAM,KAAK,KAAK;AACvC,UAAM,YAAY,KAAK,MAAM,uBAAuB;AAEpD,QAAI,CAAC,YAAY,CAAC,GAAG;AACnB,YAAM,IAAI,MAAM,oCAAoC,UAAU,4CAA4C;AAAA,IAC5G;AAEA,UAAM,WAAW,UAAU,CAAC;AAC5B,UAAM,UAAU,UAAU,KAAK,SAAS,IAAI,IAAI,UAAU,OAAO,GAAG,UAAU,IAAI;AAAA;AAClF,UAAM,QAAQ,IAAI;AAAA,EACpB;AAEA,MAAI,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,oCAAoC,UAAU,uCAAuC;AAAA,EACvG;AAEA,MAAI,CAAC,MAAM,KAAK,GAAG;AACjB,UAAM,IAAI,MAAM,oCAAoC,UAAU,YAAY,KAAK,2BAA2B;AAAA,EAC5G;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,eAAe,OAAiD;AACvE,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,OAAO,KAAK,EAAE,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AACxE;AAEA,SAAS,uBAAuB,WAA6C;AAC3E,MAAI;AAEJ,MAAI;AACF,aAAS,KAAK,MAAM,SAAS;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,WAAO;AAAA,EACT;AAEA,QAAM,OAAO;AASb,QAAM,QAAQ,eAAe,KAAK,KAAK,IAAI,KAAK,QAAQ;AAExD,MAAI,CAAC,SAAS,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,IACrD,WACE,KAAK,cAAc,aAAa,KAAK,cAAc,SAAS,KAAK,cAAc,SAC3E,KAAK,YACL;AAAA,IACN,SAAS,OAAO,KAAK,YAAY,YAAY,KAAK,UAAU;AAAA,IAC5D,UAAU,OAAO,KAAK,aAAa,YAAY,KAAK,WAAW;AAAA,IAC/D,QACE,OAAO,KAAK,WAAW,YAAY,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAAA,EACvF;AACF;AAEA,SAAS,yBAAyB,OAA6C;AAC7E,QAAM,WAAW,MAAM,MAAM,KAAK,EAAE,YAAY;AAEhD,MAAI,aAAa,gBAAgB,aAAa,iBAAiB;AAC7D,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,uBAAuB,MAAM,IAAI;AAEjD,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,QAAQ,SAAS,QAAQ,MAAM,QAAQ,KAAK,IACtD,QAAQ,QACR,OAAO,KAAK,QAAQ,KAAK,EAAE,CAAC;AAEhC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,QAAQ;AAAA,IACf;AAAA,IACA,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,QAAQ,QAAQ;AAAA,EAClB;AACF;AAEA,SAAS,+BAA+B,OAAoB,YAA6C;AACvG,QAAM,WAAW,MAAM,MAAM,KAAK,EAAE,YAAY;AAEhD,MAAI,aAAa,oBAAoB,aAAa,qBAAqB;AACrE,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,6BAA6B,MAAM,MAAM,UAAU;AAEnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,EAClB;AACF;AAEA,SAAS,eAAe,UAAkB,WAAwB,YAGhE;AACA,QAAM,SAAS,OAAO,MAAM,QAAQ;AACpC,yBAAuB,MAAM;AAC7B,QAAM,iBAAiB,IAAI,cAAc;AACzC,QAAM,kBAA2C,CAAC;AAClD,QAAM,SAA6B,CAAC;AAEpC,aAAW,SAAS,QAAQ;AAC1B,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH;AAAA,MACF,KAAK,WAAW;AACd,cAAM,KAAK,eAAe,KAAK,MAAM,IAAI;AACzC,cAAM,OAAO,aAAa,MAAM,MAAM;AAEtC,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,OAAO,MAAM;AAAA,UACb;AAAA,UACA;AAAA,QACF,CAAC;AAED,YAAI,UAAU,IAAI,MAAM,KAAK,GAAG;AAC9B,0BAAgB,KAAK;AAAA,YACnB;AAAA,YACA,OAAO,MAAM;AAAA,YACb,OAAO,MAAM,QAAQ;AAAA,UACvB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM,aAAa,MAAM,MAAM;AAAA,QACjC,CAAC;AACD;AAAA,MACF,KAAK;AACH;AACE,gBAAM,wBAAwB,+BAA+B,OAAsB,UAAU;AAE7F,cAAI,uBAAuB;AACzB,mBAAO,KAAK,qBAAqB;AACjC;AAAA,UACF;AAEA,gBAAM,kBAAkB,yBAAyB,KAAoB;AAErE,cAAI,iBAAiB;AACnB,mBAAO,KAAK,eAAe;AAC3B;AAAA,UACF;AAAA,QACF;AACA,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM,MAAM;AAAA,UACZ,UAAU,MAAM,MAAM,KAAK,KAAK;AAAA,QAClC,CAAC;AACD;AAAA,MACF,KAAK;AACH,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,SAAS,MAAM;AAAA,UACf,OAAO,MAAM,MAAM,IAAI,CAAC,SAA0B,qBAAqB,KAAK,MAAM,CAAC;AAAA,QACrF,CAAC;AACD;AAAA,MACF,KAAK;AACH,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM,kBAAkB,MAAM,MAAM;AAAA,QACtC,CAAC;AACD;AAAA,MACF,KAAK;AACH,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,QAAQ,MAAM,OAAO,IAAI,CAAC,SAA2B,aAAa,KAAK,MAAM,CAAC;AAAA,UAC9E,MAAM,MAAM,KAAK,IAAI,CAAC,QAA4B,IAAI,IAAI,CAAC,SAAS,aAAa,KAAK,MAAM,CAAC,CAAC;AAAA,UAC9F,OAAO,oBAAoB,MAAM,KAAK;AAAA,QACxC,CAAC;AACD;AAAA,MACF;AACE,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM,kBAAkB,CAAC,KAAK,CAAC;AAAA,QACjC,CAAC;AACD;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,gBAAgB;AACnC;AAEA,SAAS,oBAAoB,UAAsC;AACjE,QAAM,SAAS,OAAO,MAAM,QAAQ;AACpC,QAAM,UAAU,OAAO,KAAK,CAAC,UAAmC,MAAM,SAAS,aAAa,MAAM,UAAU,CAAC;AAE7G,SAAO,SAAS,KAAK,KAAK,KAAK;AACjC;AAEA,SAAS,UAAU,YAAoB,QAAgB,WAAkC;AACvF,QAAM,EAAE,MAAM,aAAa,QAAQ,IAAI,iBAAiB,MAAM;AAC9D,QAAM,OAAO,iBAAiB,UAAU;AACxC,QAAM,eAAe,SAAS,MAAM,CAAC,IAAI,KAAK,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG;AAC1E,QAAM,cAAc,kBAAkB,UAAU;AAChD,QAAM,UAAU,cAAc,eAAe,aAAa,MAAM,GAAG,EAAE;AACrE,QAAM,WAAW,aAAa,aAAa,SAAS,CAAC,KAAK;AAC1D,QAAM,gBAAgB,cAAe,oBAAoB,OAAO,KAAK,aAAc,YAAY,QAAQ;AACvG,QAAM,QAAQ,YAAY,OAAO,KAAK,KAAK;AAC3C,QAAM,WAAW,YAAY,UAAU,KAAK,MAAM,cAAc,aAAa;AAC7E,QAAM,EAAE,QAAQ,gBAAgB,IAAI,eAAe,SAAS,WAAW,UAAU;AACjF,QAAM,KAAK,eAAe,SAAS,MAAM,GAAG,gBAAgB,IAAI,CAAC,WAAW,gBAAgB,IAAI;AAEhG,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,YAAY,aAAa,KAAK;AAAA,IAC3C,OAAO,YAAY,SAAS;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,UAAU,OAA6B;AAC9C,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,UAAU;AACtC,QAAI,KAAK,UAAU,MAAM,OAAO;AAC9B,aAAO,KAAK,QAAQ,MAAM;AAAA,IAC5B;AAEA,UAAM,oBAAoB,KAAK,cAAc,IAAI;AACjD,UAAM,qBAAqB,MAAM,cAAc,IAAI;AAEnD,QAAI,sBAAsB,oBAAoB;AAC5C,aAAO,oBAAoB;AAAA,IAC7B;AAEA,WAAO,KAAK,MAAM,cAAc,MAAM,KAAK;AAAA,EAC7C,CAAC;AACH;AAEA,SAAS,cAAc,MAAwB;AAC7C,MAAI,KAAK,aAAa;AACpB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE,KAAK,KAAK;AAC7D;AAEA,SAAS,aAAa,OAAmB,YAAyC;AAChF,QAAM,OAAO,oBAAI,IAAqB;AAEtC,aAAW,QAAQ,OAAO;AACxB,QAAI,UAAU;AACd,QAAI,cAAc;AAElB,eAAW,WAAW,KAAK,SAAS;AAClC,oBAAc,GAAG,WAAW,IAAI,OAAO;AACvC,YAAM,gBAAgB,WAAW,gBAAgB,OAAO;AAExD,UAAI,CAAC,QAAQ,IAAI,OAAO,GAAG;AACzB,gBAAQ,IAAI,SAAS;AAAA,UACnB,OAAO,eAAe,SAAS,YAAY,OAAO;AAAA,UAClD,OAAO,eAAe,SAAS;AAAA,UAC/B,OAAO,gBAAgB,WAAW;AAAA,UAClC,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,UAAU,oBAAI,IAAI;AAAA,QACpB,CAAC;AAAA,MACH;AAEA,gBAAU,QAAQ,IAAI,OAAO,EAAG;AAAA,IAClC;AAEA,UAAM,UAAU,cAAc,IAAI;AAClC,UAAM,mBAAmB,QAAQ,IAAI,OAAO;AAE5C,YAAQ,IAAI,SAAS;AAAA,MACnB,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,QAAQ;AAAA,MACR,aAAa,KAAK;AAAA,MAClB,UAAU,kBAAkB,YAAY,oBAAI,IAAI;AAAA,IAClD,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,CAAC,UACf,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS;AAC3C,UAAM,OAAsB;AAAA,MAC1B,OAAO,KAAK,SAAS,gBAAgB,KAAK,QAAQ,KAAK,KAAK;AAAA,MAC5D,OAAO,KAAK;AAAA,IACd;AAEA,UAAM,WAAW,QAAQ,KAAK,QAAQ;AAEtC,QAAI,KAAK,QAAQ,KAAK,QAAQ;AAC5B,WAAK,KAAK,KAAK;AAAA,IACjB;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,UAAI,KAAK,IAAI;AACX,cAAM,cAAc,GAAG,KAAK,KAAK;AAEjC,aAAK,WAAW;AAAA,UACd;AAAA,YACE,OAAO,KAAK;AAAA,YACZ,OAAO;AAAA,YACP,IAAI,KAAK;AAAA,UACX;AAAA,UACA,GAAG;AAAA,QACL;AACA,aAAK,QAAQ;AACb,eAAO,KAAK;AAAA,MACd,OAAO;AACL,aAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAEH,SAAO,QAAQ,IAAI;AACrB;AAEO,SAAS,mBAAmB,EAAE,YAAY,cAAc,GAAiD;AAC9G,QAAM,YAAY,IAAI,IAAI,WAAW,KAAK,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;AAE7D,QAAM,YAAY,OAAO,QAAQ,aAAa,EAC3C,IAAI,CAAC,CAAC,YAAY,MAAM,MAAM,UAAU,YAAY,QAAQ,SAAS,CAAC,EACtE,OAAO,CAAC,SAAS,KAAK,SAAS,GAAG,EAClC,KAAK,CAAC,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;AAE5D,QAAM,cAAc,aAAa,WAAW,UAAU;AACtD,QAAM,WAA2B;AAAA,IAC/B,OAAO,WAAW,MAAM,SAAS,WAAW,SAAS;AAAA,IACrD,aAAa,WAAW,MAAM;AAAA,IAC9B,WAAW,WAAW,MAAM;AAAA,IAC5B,QAAQ,WAAW,MAAM,UAAU;AAAA,IACnC,SAAS,WAAW,MAAM;AAAA,IAC1B,MAAM,WAAW,MAAM;AAAA,IACvB,WAAW,WAAW,MAAM;AAAA,EAC9B;AACA,QAAM,aAAyC;AAAA,IAC7C,SAAS,WAAW,QAAQ,WAAW;AAAA,IACvC,cAAc,WAAW,QAAQ,gBAAgB;AAAA,IACjD,cAAc,WAAW,QAAQ,gBAAgB;AAAA,IACjD,eAAe,WAAW,QAAQ,iBAAiB;AAAA,IACnD,aAAa,WAAW,QAAQ,eAAe;AAAA,IAC/C,aAAa,WAAW,QAAQ,eAAe;AAAA,IAC/C,qBAAqB,WAAW,QAAQ,uBAAuB;AAAA,IAC/D,mBAAmB,WAAW,QAAQ,qBAAqB;AAAA,EAC7D;AACA,QAAM,aAA+B;AAAA,IACnC,MAAM,WAAW,QAAQ,QAAQ;AAAA,IACjC,OAAO,WAAW,QAAQ;AAAA,EAC5B;AACA,QAAM,WAAqC;AAAA,IACzC,SAAS,WAAW,MAAM,WAAW;AAAA,IACrC,OAAO,WAAW,MAAM,SAAS;AAAA,IACjC,aAAa,WAAW,MAAM,eAAe;AAAA,IAC7C,UAAU,WAAW,MAAM,YAAY;AAAA,IACvC,eAAe,WAAW,MAAM,iBAAiB;AAAA,MAC/C,OAAO;AAAA,MACP,IAAI;AAAA,IACN;AAAA,IACA,iBAAiB,WAAW,MAAM,mBAAmB;AAAA,MACnD,OAAO;AAAA,MACP,MAAM,WAAW,MAAM;AAAA,IACzB;AAAA,EACF;AACA,QAAM,gBAA+C;AAAA,IACnD,OAAO,WAAW,WAAW,SAAS,CAAC;AAAA,IACvC,WAAW,WAAW,WAAW,aAAa;AAAA,EAChD;AACA,QAAM,iBAAuC,WAAW,cAAc,CAAC;AACvE,QAAM,gBAAgB,SAAS;AAC/B,QAAM,mBAAmB,WAAW,KAAK,gBAAgB;AAEzD,WAAS,kBAAkB,UAA4B;AACrD,UAAM,iBAAiB,aAAa,MAAM,MAAM,SAAS,QAAQ,OAAO,EAAE;AAE1E,WAAO,UAAU,KAAK,CAAC,SAAS,KAAK,SAAS,cAAc,KAAK,UAAU,CAAC;AAAA,EAC9E;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACvwBO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4C;AAC1C,QAAM,iBAAmC,UAAU,IAAI,CAAC,UAAU;AAAA,IAChE,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,WAAW;AAAA,EACb,EAAE;AAEF,QAAM,mBAAmB,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,UAAU;AAC5D,QAAI,KAAK,UAAU,MAAM,OAAO;AAC9B,aAAO,KAAK,QAAQ,MAAM;AAAA,IAC5B;AAEA,WAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAAA,EAC3C,CAAC,EAAE,CAAC;AAEJ,QAAM,YAA4B,cAC9B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,EACb,IACA,mBACE;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,iBAAiB;AAAA,EAC7B,IACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AAEN,QAAM,SAA2B,CAAC,WAAW,GAAG,cAAc;AAE9D,MAAI,mBAAmB;AACrB,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC8EO,SAAS,iBAAiB,QAAgC;AAC/D,SAAO;AACT;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/createViteSsgApp.ts","../src/docsContent.ts","../src/routes.ts","../src/config.ts"],"sourcesContent":["import { createHead as createClientHead } from '@unhead/vue/client'\nimport { createHead as createServerHead } from '@unhead/vue/server'\nimport { createApp, createSSRApp, type Component } from 'vue'\nimport {\n createMemoryHistory,\n createRouter,\n createWebHistory,\n type RouteRecordRaw,\n type Router\n} from 'vue-router'\n\ntype CreateViteSsgContext = {\n app: ReturnType<typeof createApp>\n head: ReturnType<typeof createClientHead> | ReturnType<typeof createServerHead> | undefined\n initialState: Record<string, unknown>\n isClient: boolean\n onSSRAppRendered: (cb: () => void | Promise<void>) => void\n routePath?: string\n router: Router\n routes: RouteRecordRaw[]\n transformState?: (state: Record<string, unknown>) => Record<string, unknown>\n triggerOnSSRAppRendered: () => Promise<void[]>\n}\n\ntype CreateViteSsgOptions = {\n hydration?: boolean\n rootContainer?: string\n useHead?: boolean\n transformState?: (state: Record<string, unknown>) => Record<string, unknown>\n}\n\nlet isClientAppMounted = false\nconst hashScrollWaitMs = 4000\nconst hashScrollStabilizeFrames = 10\n\nasync function documentReady(): Promise<void> {\n if (typeof document === 'undefined' || document.readyState !== 'loading') {\n return\n }\n\n await new Promise<void>((resolve) => {\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true })\n })\n}\n\nasync function nextFrame(): Promise<void> {\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))\n}\n\nfunction getHashTargetElement(hash: string): HTMLElement | null {\n if (typeof document === 'undefined') {\n return null\n }\n\n const id = decodeURIComponent(hash.replace(/^#/, ''))\n\n return id ? document.getElementById(id) : null\n}\n\nfunction getHashScrollPosition(hash: string): { left: number; top: number } | null {\n if (typeof window === 'undefined') {\n return null\n }\n\n const targetElement = getHashTargetElement(hash)\n\n if (!targetElement) {\n return null\n }\n\n const top = targetElement.getBoundingClientRect().top + window.scrollY - getStickyOffsetTop()\n\n return {\n left: 0,\n top: Math.max(0, top)\n }\n}\n\nfunction waitForHashTarget(hash: string): Promise<HTMLElement | null> {\n if (\n typeof document === 'undefined'\n || typeof MutationObserver === 'undefined'\n || !document.body\n ) {\n return Promise.resolve(null)\n }\n\n const initialTarget = getHashTargetElement(hash)\n\n if (initialTarget) {\n return Promise.resolve(initialTarget)\n }\n\n return new Promise((resolve) => {\n let observer: MutationObserver | null = null\n\n const stop = (target: HTMLElement | null) => {\n window.clearTimeout(timeout)\n window.clearInterval(interval)\n observer?.disconnect()\n resolve(target)\n }\n\n const findTarget = () => {\n const target = getHashTargetElement(hash)\n\n if (target) {\n stop(target)\n }\n }\n\n const timeout = window.setTimeout(() => {\n stop(null)\n }, hashScrollWaitMs)\n\n const interval = window.setInterval(findTarget, 50)\n observer = new MutationObserver(findTarget)\n\n observer.observe(document.body, {\n childList: true,\n subtree: true\n })\n })\n}\n\nasync function scrollToHash(hash: string, behavior: ScrollBehavior = 'smooth'): Promise<boolean> {\n await nextFrame()\n await nextFrame()\n\n const target = await waitForHashTarget(hash)\n\n if (!target || typeof window === 'undefined') {\n return false\n }\n\n for (let attempt = 0; attempt < hashScrollStabilizeFrames; attempt += 1) {\n const position = getHashScrollPosition(hash)\n\n if (!position) {\n return false\n }\n\n window.scrollTo({\n ...position,\n behavior: attempt === 0 ? behavior : 'auto'\n })\n\n await nextFrame()\n\n if (attempt >= 2 && Math.abs(window.scrollY - position.top) < 2) {\n return true\n }\n }\n\n return true\n}\n\nfunction isVisibleElement(element: HTMLElement | null): element is HTMLElement {\n return Boolean(element && element.offsetParent !== null)\n}\n\nfunction getStickyOffsetTop(): number {\n if (typeof document === 'undefined') {\n return 0\n }\n\n const header = document.querySelector<HTMLElement>('.vf-document-layout__header')\n const layoutSubheader = document.querySelector<HTMLElement>('.vf-document-layout__subheader')\n const contentSubheader = document.querySelector<HTMLElement>('.vf-document-layout__content-subheader')\n const topGap = 16\n let offset = topGap\n\n if (isVisibleElement(header)) {\n offset += header.getBoundingClientRect().height\n }\n\n if (isVisibleElement(layoutSubheader)) {\n offset += layoutSubheader.getBoundingClientRect().height\n }\n\n if (isVisibleElement(contentSubheader)) {\n offset += contentSubheader.getBoundingClientRect().height\n }\n\n return offset\n}\n\nfunction getInitialState(): Record<string, unknown> {\n if (typeof window === 'undefined') {\n return {}\n }\n\n return ((window as Window & { __INITIAL_STATE__?: Record<string, unknown> }).__INITIAL_STATE__ ?? {})\n}\n\nfunction ensureHistoryState(): void {\n if (typeof window === 'undefined') {\n return\n }\n\n if (window.history.state) {\n return\n }\n\n const current = `${window.location.pathname}${window.location.search}${window.location.hash}`\n\n window.history.replaceState(\n {\n back: null,\n current,\n forward: null,\n position: window.history.length - 1,\n replaced: true,\n scroll: null\n },\n '',\n current\n )\n}\n\nfunction useManualScrollRestoration(): void {\n if (typeof window === 'undefined' || !('scrollRestoration' in window.history)) {\n return\n }\n\n window.history.scrollRestoration = 'manual'\n}\n\nfunction setRootVisibility(rootContainer: string, visible: boolean): void {\n if (typeof document === 'undefined') {\n return\n }\n\n const root = document.querySelector<HTMLElement>(rootContainer)\n\n if (!root) {\n return\n }\n\n root.style.visibility = visible ? '' : 'hidden'\n}\n\nfunction hasHydratableRoot(rootContainer: string): boolean {\n if (typeof document === 'undefined') {\n return false\n }\n\n const root = document.querySelector<HTMLElement>(rootContainer)\n\n return Boolean(root && root.innerHTML.trim().length > 0)\n}\n\nexport function createViteSsgApp(\n App: Component,\n routerOptions: { base?: string; routes: RouteRecordRaw[] },\n fn?: (context: CreateViteSsgContext) => Promise<void> | void,\n options?: CreateViteSsgOptions\n) {\n const {\n hydration = true,\n rootContainer = '#app',\n transformState,\n useHead = true\n } = options ?? {}\n\n async function createSsgApp(routePath?: string): Promise<CreateViteSsgContext> {\n const shouldHydrate = import.meta.env.SSR || (hydration && hasHydratableRoot(rootContainer))\n const app = shouldHydrate ? createSSRApp(App) : createApp(App)\n let head: CreateViteSsgContext['head']\n\n if (useHead) {\n head = import.meta.env.SSR ? createServerHead() : createClientHead()\n app.use(head)\n }\n\n const router = createRouter({\n history: import.meta.env.SSR\n ? createMemoryHistory(routerOptions.base)\n : createWebHistory(routerOptions.base),\n scrollBehavior: async (to, _from, savedPosition) => {\n if (!isClientAppMounted) {\n return false\n }\n\n if (savedPosition) {\n return savedPosition\n }\n\n if (to.hash) {\n const scrolled = await scrollToHash(to.hash)\n return scrolled ? false : { left: 0, top: 0 }\n }\n\n return { left: 0, top: 0 }\n },\n ...routerOptions\n })\n\n const appRenderCallbacks: Array<() => void | Promise<void>> = []\n const onSSRAppRendered = import.meta.env.SSR\n ? (cb: () => void | Promise<void>) => appRenderCallbacks.push(cb)\n : () => undefined\n const triggerOnSSRAppRendered = () => Promise.all(appRenderCallbacks.map((cb) => cb()))\n\n const context: CreateViteSsgContext = {\n app,\n head,\n initialState: {},\n isClient: !import.meta.env.SSR,\n onSSRAppRendered,\n routePath,\n router,\n routes: routerOptions.routes,\n transformState,\n triggerOnSSRAppRendered\n }\n\n if (!import.meta.env.SSR) {\n await documentReady()\n useManualScrollRestoration()\n ensureHistoryState()\n context.initialState = transformState?.(getInitialState()) ?? getInitialState()\n }\n\n await fn?.(context)\n app.use(router)\n\n let entryRoutePath: string | undefined\n let isFirstRoute = true\n\n router.beforeEach((to) => {\n if (isFirstRoute || (entryRoutePath && entryRoutePath === to.path)) {\n isFirstRoute = false\n entryRoutePath = to.path\n to.meta.state = context.initialState\n }\n\n return true\n })\n\n if (import.meta.env.SSR) {\n const route = context.routePath ?? '/'\n await router.push(route)\n await router.isReady()\n context.initialState = (router.currentRoute.value.meta.state as Record<string, unknown>) || {}\n }\n\n return context\n }\n\n if (!import.meta.env.SSR) {\n ;(async () => {\n const hasInitialHash = Boolean(window.location.hash)\n\n if (hasInitialHash) {\n setRootVisibility(rootContainer, false)\n }\n\n const { app, router } = await createSsgApp()\n await router.isReady()\n app.mount(rootContainer, true)\n isClientAppMounted = true\n\n if (window.location.hash) {\n await scrollToHash(window.location.hash, 'auto')\n }\n\n if (hasInitialHash) {\n setRootVisibility(rootContainer, true)\n }\n })()\n }\n\n return createSsgApp\n}\n","import { Parser, type Tokens, marked } from 'marked'\nimport GithubSlugger from 'github-slugger'\nimport type { VfNavMenuItem, VfTableOfContentsItem } from '@codemonster-ru/vueforge-core'\nimport type {\n DocsComponentsConfig,\n DocsConfig,\n DocsFooterConfig,\n DocsHeaderNavConfig,\n DocsHomeConfig,\n DocsLayoutConfig,\n DocsSiteConfig\n} from './config'\n\nexport type DocsTableAlign = 'left' | 'center' | 'right' | null\nexport type DocsPlaygroundFramework = 'vanilla' | 'vue' | 'html'\n\nexport type DocsContentBlock =\n | {\n type: 'heading'\n depth: 1 | 2 | 3 | 4 | 5 | 6\n id: string\n html: string\n }\n | {\n type: 'paragraph'\n html: string\n }\n | {\n type: 'code'\n code: string\n language: string\n }\n | {\n type: 'playground'\n files?: Record<string, string>\n entry?: string\n framework?: DocsPlaygroundFramework\n autorun?: boolean\n showCode?: boolean\n height?: number | string\n demoId?: string\n demoImport?: string\n renderMode?: 'sandbox' | 'vue-module' | 'component'\n }\n | {\n type: 'list'\n ordered: boolean\n items: string[]\n }\n | {\n type: 'blockquote'\n html: string\n }\n | {\n type: 'table'\n header: string[]\n rows: string[][]\n align: DocsTableAlign[]\n }\n | {\n type: 'html'\n html: string\n }\n\nexport interface DocsPage {\n id: string\n path: string\n sourcePath: string\n isIndexPage: boolean\n title: string\n navTitle: string\n description?: string\n order: number\n section: string[]\n blocks: DocsContentBlock[]\n tableOfContents: VfTableOfContentsItem[]\n}\n\ninterface Frontmatter {\n title?: string\n navTitle?: string\n description?: string\n order?: number\n}\n\ninterface NavNode {\n label: string\n order: number\n value?: string\n path?: string\n isPage?: boolean\n isIndexPage?: boolean\n children: Map<string, NavNode>\n}\n\ntype TokensList = Tokens.Generic[]\n\nexport interface ResolveDocsContentInput {\n docsConfig: DocsConfig\n markdownFiles: Record<string, string>\n}\n\nexport interface ResolvedDocsContent {\n docsPages: DocsPage[]\n docsSidebar: VfNavMenuItem[]\n docsSite: DocsSiteConfig\n docsLayout: Required<DocsLayoutConfig>\n docsFooter: DocsFooterConfig\n docsHome: Required<DocsHomeConfig>\n docsHeaderNav: Required<DocsHeaderNavConfig>\n docsComponents: DocsComponentsConfig\n docsSiteTitle: string\n docsScrollOffset: number\n getDocsPageByPath: (pathname: string) => DocsPage\n}\n\nfunction parseFrontmatter(source: string): { data: Frontmatter; content: string } {\n if (!source.startsWith('---\\n')) {\n return { data: {}, content: source }\n }\n\n const frontmatterEnd = source.indexOf('\\n---\\n', 4)\n\n if (frontmatterEnd === -1) {\n return { data: {}, content: source }\n }\n\n const rawFrontmatter = source.slice(4, frontmatterEnd)\n const content = source.slice(frontmatterEnd + 5)\n const data: Frontmatter = {}\n\n for (const line of rawFrontmatter.split('\\n')) {\n const separatorIndex = line.indexOf(':')\n\n if (separatorIndex === -1) {\n continue\n }\n\n const key = line.slice(0, separatorIndex).trim()\n const rawValue = line.slice(separatorIndex + 1).trim()\n const normalizedValue = rawValue.replace(/^['\"]|['\"]$/g, '')\n\n if (key === 'order') {\n const numericValue = Number(normalizedValue)\n data.order = Number.isFinite(numericValue) ? numericValue : 0\n continue\n }\n\n if (key === 'title' || key === 'navTitle' || key === 'description') {\n data[key] = normalizedValue\n }\n }\n\n return { data, content }\n}\n\nfunction toTitleCase(value: string): string {\n return value\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (letter) => letter.toUpperCase())\n}\n\nfunction normalizeDocPath(sourcePath: string): string {\n const relativePath = sourcePath.replace(/^.*\\/(?:content|docs)\\//, '').replace(/\\.md$/, '')\n\n if (relativePath === 'index') {\n return '/'\n }\n\n if (relativePath.endsWith('/index')) {\n return `/${relativePath.replace(/\\/index$/, '')}`\n }\n\n return `/${relativePath}`\n}\n\nfunction isIndexSourcePath(sourcePath: string): boolean {\n return sourcePath.replace(/\\\\/g, '/').replace(/\\.md$/, '').endsWith('/index')\n}\n\nfunction normalizeMarkdownLinkHref(href: string): string {\n if (\n href.startsWith('#') ||\n href.startsWith('//') ||\n /^[a-z][a-z\\d+.-]*:/i.test(href)\n ) {\n return href\n }\n\n const match = href.match(/^([^?#]*)([?#].*)?$/)\n\n if (!match) {\n return href\n }\n\n const [, pathname, suffix = ''] = match\n\n if (!/\\.(?:md|mdx)$/i.test(pathname)) {\n return href\n }\n\n const extensionlessPathname = pathname.replace(/\\.(?:md|mdx)$/i, '')\n let normalizedPathname = extensionlessPathname\n\n if (extensionlessPathname === 'index' || extensionlessPathname === './index') {\n normalizedPathname = '.'\n } else if (extensionlessPathname.endsWith('/index')) {\n normalizedPathname = extensionlessPathname.replace(/\\/index$/, '')\n }\n\n return `${normalizedPathname}${suffix}`\n}\n\nfunction normalizeMarkdownLinks(tokens: TokensList): void {\n for (const token of tokens) {\n if (token.type === 'link' && typeof token.href === 'string') {\n token.href = normalizeMarkdownLinkHref(token.href)\n }\n\n if ('tokens' in token && Array.isArray(token.tokens)) {\n normalizeMarkdownLinks(token.tokens as TokensList)\n }\n\n if (token.type === 'list' && Array.isArray(token.items)) {\n for (const item of token.items) {\n normalizeMarkdownLinks(item.tokens as TokensList)\n }\n }\n }\n}\n\nfunction toValueFromPath(path: string): string {\n return path === '/' ? 'index' : path.replace(/^\\//, '').replace(/\\//g, '-')\n}\n\nfunction renderInline(tokens: Tokens.Generic[] | undefined): string {\n return Parser.parseInline(tokens ?? [])\n}\n\nfunction renderBlockTokens(tokens: TokensList | undefined): string {\n return Parser.parse(tokens ?? [])\n}\n\nfunction renderListItemTokens(tokens: TokensList | undefined): string {\n return Parser.parse(tokens ?? [])\n}\n\nfunction normalizeTableAlign(align: Array<string | null | undefined>): DocsTableAlign[] {\n return align.map((value) => {\n if (value === 'left' || value === 'center' || value === 'right') {\n return value\n }\n\n return null\n })\n}\n\ninterface PlaygroundPayload {\n files?: Record<string, string>\n entry?: string\n framework?: DocsPlaygroundFramework\n autorun?: boolean\n showCode?: boolean\n height?: number | string\n demoId?: string\n demoImport?: string\n}\n\ninterface PlaygroundSrcPayload {\n files: Record<string, string>\n entry: string\n framework?: DocsPlaygroundFramework\n height?: number\n renderMode?: 'sandbox' | 'component'\n}\n\nfunction parsePlaygroundSourceHeader(text: string, sourcePath: string): {\n framework?: DocsPlaygroundFramework\n height?: number\n entry: string\n renderMode: 'sandbox' | 'component'\n} {\n const lines = text\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n const metadata = new Map<string, string>()\n\n for (const line of lines) {\n const separatorIndex = line.indexOf(':')\n\n if (separatorIndex === -1) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: expected \"key: value\", got \"${line}\"`)\n }\n\n const key = line.slice(0, separatorIndex).trim()\n const value = line.slice(separatorIndex + 1).trim()\n\n metadata.set(key, value)\n }\n\n const frameworkRaw = metadata.get('framework')\n const framework = frameworkRaw || 'vanilla'\n const heightRaw = metadata.get('height')\n const entry = metadata.get('entry')\n const modeRaw = metadata.get('mode')\n const renderMode = modeRaw === 'component' ? 'component' : 'sandbox'\n\n if (!entry) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: \"entry\" is required`)\n }\n\n if (framework !== 'vanilla' && framework !== 'vue' && framework !== 'html') {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: unsupported framework \"${framework}\"`)\n }\n\n let height: number | undefined\n\n if (heightRaw !== undefined) {\n height = Number(heightRaw)\n\n if (!Number.isFinite(height)) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: \"height\" must be a number`)\n }\n }\n\n return {\n framework,\n entry,\n height,\n renderMode\n }\n}\n\nfunction parsePlaygroundSourcePayload(rawSource: string, sourcePath: string): PlaygroundSrcPayload {\n const nestedTokens = marked.lexer(rawSource) as TokensList\n let metadataToken: Tokens.Paragraph | null = null\n const codeTokens: Tokens.Code[] = []\n\n for (const token of nestedTokens) {\n if (token.type === 'space') {\n continue\n }\n\n if (!metadataToken) {\n if (token.type !== 'paragraph') {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: header metadata must be the first block`)\n }\n\n metadataToken = token as Tokens.Paragraph\n continue\n }\n\n if (token.type !== 'code') {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: only code fences are allowed after header`)\n }\n\n codeTokens.push(token as Tokens.Code)\n }\n\n if (!metadataToken) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: missing header metadata`)\n }\n\n const { framework, height, entry, renderMode } = parsePlaygroundSourceHeader(metadataToken.text, sourcePath)\n const files: Record<string, string> = {}\n\n for (const codeToken of codeTokens) {\n const lang = codeToken.lang?.trim() ?? ''\n const fileMatch = lang.match(/(?:^|\\s)file=([^\\s]+)/)\n\n if (!fileMatch?.[1]) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: each code fence must define \"file=/path\"`)\n }\n\n const filePath = fileMatch[1]\n const content = codeToken.text.endsWith('\\n') ? codeToken.text : `${codeToken.text}\\n`\n files[filePath] = content\n }\n\n if (Object.keys(files).length === 0) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: at least one file fence is required`)\n }\n\n if (!files[entry]) {\n throw new Error(`[docs] Invalid playground-src in ${sourcePath}: entry \"${entry}\" is not present in files`)\n }\n\n return {\n files,\n entry,\n framework,\n height,\n renderMode\n }\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string')\n}\n\nfunction parsePlaygroundPayload(rawSource: string): PlaygroundPayload | null {\n let parsed: unknown\n\n try {\n parsed = JSON.parse(rawSource)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null\n }\n\n const data = parsed as {\n files?: unknown\n entry?: unknown\n framework?: unknown\n autorun?: unknown\n showCode?: unknown\n height?: unknown\n demoId?: unknown\n demoImport?: unknown\n }\n\n const files = isStringRecord(data.files) ? data.files : undefined\n const demoId = typeof data.demoId === 'string' && data.demoId.trim()\n ? data.demoId.trim()\n : undefined\n const demoImport = typeof data.demoImport === 'string' && data.demoImport.trim()\n ? data.demoImport.trim()\n : undefined\n\n if ((!files || Object.keys(files).length === 0) && !demoId && !demoImport) {\n return null\n }\n\n return {\n files,\n entry: typeof data.entry === 'string' ? data.entry : undefined,\n framework:\n data.framework === 'vanilla' || data.framework === 'vue' || data.framework === 'html'\n ? data.framework\n : undefined,\n autorun: typeof data.autorun === 'boolean' ? data.autorun : undefined,\n showCode: typeof data.showCode === 'boolean' ? data.showCode : undefined,\n height:\n typeof data.height === 'number' || typeof data.height === 'string' ? data.height : undefined,\n demoId,\n demoImport\n }\n}\n\nfunction parsePlaygroundCodeBlock(token: Tokens.Code): DocsContentBlock | null {\n const language = token.lang?.trim().toLowerCase()\n\n if (language !== 'playground' && language !== 'vf-playground') {\n return null\n }\n\n const payload = parsePlaygroundPayload(token.text)\n\n if (!payload) {\n return null\n }\n\n if (payload.demoId || payload.demoImport) {\n return {\n type: 'playground',\n framework: payload.framework ?? 'vue',\n autorun: payload.autorun,\n showCode: payload.showCode,\n height: payload.height,\n demoId: payload.demoId,\n demoImport: payload.demoImport,\n renderMode: 'vue-module'\n }\n }\n\n if (!payload.files || Object.keys(payload.files).length === 0) {\n return null\n }\n\n const entry = payload.entry && payload.files[payload.entry]\n ? payload.entry\n : Object.keys(payload.files)[0]\n\n return {\n type: 'playground',\n files: payload.files,\n entry,\n framework: payload.framework,\n autorun: payload.autorun,\n showCode: payload.showCode,\n height: payload.height,\n renderMode: 'sandbox'\n }\n}\n\nfunction parsePlaygroundSourceCodeBlock(token: Tokens.Code, sourcePath: string): DocsContentBlock | null {\n const language = token.lang?.trim().toLowerCase()\n\n if (language !== 'playground-src' && language !== 'vf-playground-src') {\n return null\n }\n\n const payload = parsePlaygroundSourcePayload(token.text, sourcePath)\n\n return {\n type: 'playground',\n files: payload.files,\n entry: payload.entry,\n framework: payload.framework,\n height: payload.height,\n renderMode: payload.renderMode ?? 'sandbox'\n }\n}\n\nfunction renderMarkdown(markdown: string, tocLevels: Set<number>, sourcePath: string): {\n blocks: DocsContentBlock[]\n tableOfContents: VfTableOfContentsItem[]\n} {\n const tokens = marked.lexer(markdown) as TokensList\n normalizeMarkdownLinks(tokens)\n const headingSlugger = new GithubSlugger()\n const tableOfContents: VfTableOfContentsItem[] = []\n const blocks: DocsContentBlock[] = []\n\n for (const token of tokens) {\n switch (token.type) {\n case 'space':\n break\n case 'heading': {\n const id = headingSlugger.slug(token.text)\n const html = renderInline(token.tokens)\n\n blocks.push({\n type: 'heading',\n depth: token.depth as 1 | 2 | 3 | 4 | 5 | 6,\n id,\n html\n })\n\n if (tocLevels.has(token.depth)) {\n tableOfContents.push({\n id,\n label: token.text,\n level: token.depth - 1\n })\n }\n break\n }\n case 'paragraph':\n blocks.push({\n type: 'paragraph',\n html: renderInline(token.tokens)\n })\n break\n case 'code':\n {\n const playgroundSourceBlock = parsePlaygroundSourceCodeBlock(token as Tokens.Code, sourcePath)\n\n if (playgroundSourceBlock) {\n blocks.push(playgroundSourceBlock)\n break\n }\n\n const playgroundBlock = parsePlaygroundCodeBlock(token as Tokens.Code)\n\n if (playgroundBlock) {\n blocks.push(playgroundBlock)\n break\n }\n }\n blocks.push({\n type: 'code',\n code: token.text,\n language: token.lang?.trim() || 'text'\n })\n break\n case 'list':\n blocks.push({\n type: 'list',\n ordered: token.ordered,\n items: token.items.map((item: Tokens.ListItem) => renderListItemTokens(item.tokens))\n })\n break\n case 'blockquote':\n blocks.push({\n type: 'blockquote',\n html: renderBlockTokens(token.tokens)\n })\n break\n case 'table':\n blocks.push({\n type: 'table',\n header: token.header.map((cell: Tokens.TableCell) => renderInline(cell.tokens)),\n rows: token.rows.map((row: Tokens.TableCell[]) => row.map((cell) => renderInline(cell.tokens))),\n align: normalizeTableAlign(token.align)\n })\n break\n default:\n blocks.push({\n type: 'html',\n html: renderBlockTokens([token])\n })\n break\n }\n }\n\n return { blocks, tableOfContents }\n}\n\nfunction getFirstHeadingText(markdown: string): string | undefined {\n const tokens = marked.lexer(markdown) as TokensList\n const heading = tokens.find((token): token is Tokens.Heading => token.type === 'heading' && token.depth === 1)\n\n return heading?.text.trim() || undefined\n}\n\nfunction parsePage(sourcePath: string, source: string, tocLevels: Set<number>): DocsPage {\n const { data: frontmatter, content } = parseFrontmatter(source)\n const path = normalizeDocPath(sourcePath)\n const pathSegments = path === '/' ? [] : path.replace(/^\\//, '').split('/')\n const isIndexPage = isIndexSourcePath(sourcePath)\n const section = isIndexPage ? pathSegments : pathSegments.slice(0, -1)\n const filename = pathSegments[pathSegments.length - 1] ?? 'index'\n const fallbackTitle = isIndexPage ? (getFirstHeadingText(content) ?? 'Overview') : toTitleCase(filename)\n const title = frontmatter.title?.trim() || fallbackTitle\n const navTitle = frontmatter.navTitle?.trim() || (isIndexPage ? 'Overview' : title)\n const { blocks, tableOfContents } = renderMarkdown(content, tocLevels, sourcePath)\n const id = isIndexPage && path !== '/' ? `${toValueFromPath(path)}-index` : toValueFromPath(path)\n\n return {\n id,\n path,\n sourcePath,\n isIndexPage,\n title,\n navTitle,\n description: frontmatter.description?.trim(),\n order: frontmatter.order ?? 0,\n section,\n blocks,\n tableOfContents\n }\n}\n\nfunction sortNodes(nodes: NavNode[]): NavNode[] {\n return [...nodes].sort((left, right) => {\n if (left.order !== right.order) {\n return left.order - right.order\n }\n\n const leftIndexPriority = left.isIndexPage ? 0 : 1\n const rightIndexPriority = right.isIndexPage ? 0 : 1\n\n if (leftIndexPriority !== rightIndexPriority) {\n return leftIndexPriority - rightIndexPriority\n }\n\n return left.label.localeCompare(right.label)\n })\n}\n\nfunction getPageNavKey(page: DocsPage): string {\n if (page.isIndexPage) {\n return 'index'\n }\n\n return page.path.split('/').filter(Boolean).at(-1) ?? page.id\n}\n\nfunction buildSidebar(pages: DocsPage[], docsConfig: DocsConfig): VfNavMenuItem[] {\n const root = new Map<string, NavNode>()\n\n for (const page of pages) {\n let current = root\n let currentPath = ''\n\n for (const segment of page.section) {\n currentPath = `${currentPath}/${segment}`\n const sectionConfig = docsConfig.sectionLabels?.[segment]\n\n if (!current.has(segment)) {\n current.set(segment, {\n label: sectionConfig?.label ?? toTitleCase(segment),\n order: sectionConfig?.order ?? 1_000,\n value: toValueFromPath(currentPath),\n path: currentPath,\n isPage: false,\n children: new Map()\n })\n }\n\n current = current.get(segment)!.children\n }\n\n const pageKey = getPageNavKey(page)\n const existingPageNode = current.get(pageKey)\n\n current.set(pageKey, {\n label: page.navTitle,\n order: page.order,\n value: page.id,\n path: page.path,\n isPage: true,\n isIndexPage: page.isIndexPage,\n children: existingPageNode?.children ?? new Map()\n })\n }\n\n const toItems = (nodes: Map<string, NavNode>): VfNavMenuItem[] =>\n sortNodes([...nodes.values()]).map((node) => {\n const item: VfNavMenuItem = {\n value: node.value ?? toValueFromPath(node.path ?? node.label),\n label: node.label\n }\n\n const children = toItems(node.children)\n\n if (node.path && node.isPage) {\n item.to = node.path\n }\n\n if (children.length > 0) {\n if (item.to) {\n const branchValue = `${item.value}-section`\n\n item.children = [\n {\n value: item.value,\n label: 'Overview',\n to: item.to\n },\n ...children\n ]\n item.value = branchValue\n delete item.to\n } else {\n item.children = children\n }\n }\n\n return item\n })\n\n return toItems(root)\n}\n\nexport function resolveDocsContent({ docsConfig, markdownFiles }: ResolveDocsContentInput): ResolvedDocsContent {\n const tocLevels = new Set(docsConfig.toc?.levels ?? [2, 3, 4])\n\n const docsPages = Object.entries(markdownFiles)\n .map(([sourcePath, source]) => parsePage(sourcePath, source, tocLevels))\n .filter((page) => page.path !== '/')\n .sort((left, right) => left.path.localeCompare(right.path))\n\n const docsSidebar = buildSidebar(docsPages, docsConfig)\n const docsSite: DocsSiteConfig = {\n title: docsConfig.site?.title ?? docsConfig.title ?? 'docs',\n description: docsConfig.site?.description,\n githubUrl: docsConfig.site?.githubUrl,\n homeTo: docsConfig.site?.homeTo ?? '/',\n favicon: docsConfig.site?.favicon,\n logo: docsConfig.site?.logo,\n logoLabel: docsConfig.site?.logoLabel\n }\n const docsLayout: Required<DocsLayoutConfig> = {\n variant: docsConfig.layout?.variant ?? 'sidebar-content-aside',\n fillViewport: docsConfig.layout?.fillViewport ?? true,\n stickyHeader: docsConfig.layout?.stickyHeader ?? true,\n stickySidebar: docsConfig.layout?.stickySidebar ?? true,\n stickyAside: docsConfig.layout?.stickyAside ?? true,\n edgeNotches: docsConfig.layout?.edgeNotches ?? false,\n hideSidebarOnMobile: docsConfig.layout?.hideSidebarOnMobile ?? true,\n hideAsideOnMobile: docsConfig.layout?.hideAsideOnMobile ?? true\n }\n const docsFooter: DocsFooterConfig = {\n left: docsConfig.footer?.left ?? 'Codemonster documentation',\n right: docsConfig.footer?.right\n }\n const docsHome: Required<DocsHomeConfig> = {\n enabled: docsConfig.home?.enabled ?? true,\n title: docsConfig.home?.title ?? 'Build docs fast',\n description: docsConfig.home?.description ?? 'Write markdown, keep the same UI stack, and ship clean developer docs.',\n showGrid: docsConfig.home?.showGrid ?? true,\n primaryAction: docsConfig.home?.primaryAction ?? {\n label: 'Get Started',\n to: '/guide/installation'\n },\n secondaryAction: docsConfig.home?.secondaryAction ?? {\n label: 'View on GitHub',\n href: docsConfig.site?.githubUrl\n }\n }\n const docsHeaderNav: Required<DocsHeaderNavConfig> = {\n items: docsConfig.headerNav?.items ?? [],\n ariaLabel: docsConfig.headerNav?.ariaLabel ?? 'Header navigation'\n }\n const docsComponents: DocsComponentsConfig = docsConfig.components ?? {}\n const docsSiteTitle = docsSite.title\n const docsScrollOffset = docsConfig.toc?.scrollOffset ?? 96\n\n function getDocsPageByPath(pathname: string): DocsPage {\n const normalizedPath = pathname === '/' ? '/' : pathname.replace(/\\/$/, '')\n\n return docsPages.find((page) => page.path === normalizedPath) ?? docsPages[0]\n }\n\n return {\n docsPages,\n docsSidebar,\n docsSite,\n docsLayout,\n docsFooter,\n docsHome,\n docsHeaderNav,\n docsComponents,\n docsSiteTitle,\n docsScrollOffset,\n getDocsPageByPath\n }\n}\n","import type { Component } from 'vue'\nimport type { RouteRecordRaw } from 'vue-router'\nimport type { DocsPage } from './docsContent'\n\nexport interface CreateDocsRoutesInput {\n docsPages: DocsPage[]\n homeEnabled: boolean\n homeComponent: Component\n pageComponent: Component\n notFoundComponent?: Component\n}\n\nexport function createDocsRoutes({\n docsPages,\n homeEnabled,\n homeComponent,\n pageComponent,\n notFoundComponent\n}: CreateDocsRoutesInput): RouteRecordRaw[] {\n const docsPageRoutes: RouteRecordRaw[] = docsPages.map((page) => ({\n path: page.path,\n name: page.id,\n component: pageComponent\n }))\n\n const docsLandingRoute = [...docsPages].sort((left, right) => {\n if (left.order !== right.order) {\n return left.order - right.order\n }\n\n return left.path.localeCompare(right.path)\n })[0]\n\n const rootRoute: RouteRecordRaw = homeEnabled\n ? {\n path: '/',\n name: 'home',\n component: homeComponent\n }\n : docsLandingRoute\n ? {\n path: '/',\n name: 'home',\n redirect: docsLandingRoute.path\n }\n : {\n path: '/',\n name: 'home',\n component: homeComponent\n }\n\n const routes: RouteRecordRaw[] = [rootRoute, ...docsPageRoutes]\n\n if (notFoundComponent) {\n routes.push({\n path: '/:pathMatch(.*)*',\n name: 'not-found',\n component: notFoundComponent\n })\n }\n\n return routes\n}\n","import type { Component } from 'vue'\nimport type { VfNavMenuItem, VfTableOfContentsItem } from '@codemonster-ru/vueforge-core'\n\nexport interface DocsSectionConfig {\n label?: string\n order?: number\n}\n\nexport interface DocsTocConfig {\n levels?: number[]\n scrollOffset?: number\n}\n\nexport interface DocsSiteLogoConfig {\n src?: string\n component?: Component\n alt?: string\n width?: number | string\n height?: number | string\n}\n\nexport interface DocsHomeActionConfig {\n label: string\n to?: string\n href?: string\n}\n\nexport interface DocsHomeConfig {\n enabled?: boolean\n title?: string\n description?: string\n showGrid?: boolean\n primaryAction?: DocsHomeActionConfig\n secondaryAction?: DocsHomeActionConfig\n}\n\nexport interface DocsHeaderNavConfig {\n items?: VfNavMenuItem[]\n ariaLabel?: string\n}\n\nexport type DocsLayoutVariant =\n | 'content'\n | 'sidebar-content'\n | 'sidebar-content-aside'\n\nexport interface DocsSiteConfig {\n title: string\n description?: string\n githubUrl?: string\n homeTo?: string\n favicon?: string\n logo?: DocsSiteLogoConfig\n logoLabel?: string\n}\n\nexport interface DocsLayoutConfig {\n variant?: DocsLayoutVariant\n fillViewport?: boolean\n stickyHeader?: boolean\n stickySidebar?: boolean\n stickyAside?: boolean\n edgeNotches?: boolean\n hideSidebarOnMobile?: boolean\n hideAsideOnMobile?: boolean\n}\n\nexport interface DocsFooterConfig {\n left?: string\n right?: string\n}\n\nexport interface DocsPageMeta {\n title: string\n path: string\n}\n\nexport interface DocsHeaderProps {\n site: DocsSiteConfig\n}\n\nexport interface DocsBrandProps {\n site: DocsSiteConfig\n}\n\nexport interface DocsFooterProps {\n site: DocsSiteConfig\n}\n\nexport interface DocsHeaderNavProps {\n site: DocsSiteConfig\n items: VfNavMenuItem[]\n activeValue?: string\n}\n\nexport interface DocsSidebarProps {\n site: DocsSiteConfig\n page: DocsPageMeta\n items: VfNavMenuItem[]\n}\n\nexport interface DocsAsideProps {\n site: DocsSiteConfig\n page: DocsPageMeta\n items: VfTableOfContentsItem[]\n}\n\nexport interface DocsLayoutProps {\n site: DocsSiteConfig\n page: DocsPageMeta\n layout: Required<DocsLayoutConfig>\n sidebarItems: VfNavMenuItem[]\n tocItems: VfTableOfContentsItem[]\n}\n\nexport interface DocsComponentsConfig {\n Brand?: Component\n Home?: Component\n Header?: Component\n HeaderNav?: Component\n Footer?: Component\n SidebarTop?: Component\n SidebarBottom?: Component\n AsideTop?: Component\n AsideBottom?: Component\n Layout?: Component\n}\n\nexport interface DocsConfig {\n title?: string\n site?: Partial<DocsSiteConfig>\n home?: DocsHomeConfig\n headerNav?: DocsHeaderNavConfig\n layout?: DocsLayoutConfig\n footer?: DocsFooterConfig\n components?: DocsComponentsConfig\n sectionLabels?: Record<string, DocsSectionConfig>\n toc?: DocsTocConfig\n}\n\nexport function defineDocsConfig(config: DocsConfig): DocsConfig {\n return config\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
interface MarkdownComponentPlayground {
|
|
2
|
+
entry: string;
|
|
3
|
+
files: Record<string, string>;
|
|
4
|
+
id: string;
|
|
5
|
+
source: string;
|
|
6
|
+
}
|
|
7
|
+
interface MarkdownComponentPlaygroundOptions {
|
|
8
|
+
contentRoot: string;
|
|
9
|
+
generatedRegistryPath: string;
|
|
10
|
+
virtualPrefix?: string;
|
|
11
|
+
}
|
|
12
|
+
interface MarkdownComponentPlaygroundRegistryOptions {
|
|
13
|
+
generatedRegistryPath: string;
|
|
14
|
+
virtualPrefix?: string;
|
|
15
|
+
}
|
|
16
|
+
declare const DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX = "virtual:docs-markdown-playground/";
|
|
17
|
+
declare function walkMarkdownFiles(rootDir: string): string[];
|
|
18
|
+
declare function hashPlaygroundSource(source: string): string;
|
|
19
|
+
declare function parsePlaygroundSourceOptions(source: string): Record<string, string>;
|
|
20
|
+
declare function parsePlaygroundSourceFiles(source: string): Record<string, string>;
|
|
21
|
+
declare function collectMarkdownComponentPlaygrounds(contentRoot: string): MarkdownComponentPlayground[];
|
|
22
|
+
declare function writeMarkdownComponentPlaygroundRegistry(demos: MarkdownComponentPlayground[], options: MarkdownComponentPlaygroundRegistryOptions): void;
|
|
23
|
+
declare function createMarkdownComponentPlaygroundPlugin(demos: MarkdownComponentPlayground[], virtualPrefix?: string): {
|
|
24
|
+
name: string;
|
|
25
|
+
resolveId(id: string): string | null;
|
|
26
|
+
load(id: string): string | null;
|
|
27
|
+
};
|
|
28
|
+
declare function createMarkdownComponentPlaygrounds(options: MarkdownComponentPlaygroundOptions): {
|
|
29
|
+
demos: MarkdownComponentPlayground[];
|
|
30
|
+
plugin: {
|
|
31
|
+
name: string;
|
|
32
|
+
resolveId(id: string): string | null;
|
|
33
|
+
load(id: string): string | null;
|
|
34
|
+
};
|
|
35
|
+
virtualPrefix: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX, type MarkdownComponentPlayground, type MarkdownComponentPlaygroundOptions, type MarkdownComponentPlaygroundRegistryOptions, collectMarkdownComponentPlaygrounds, createMarkdownComponentPlaygroundPlugin, createMarkdownComponentPlaygrounds, hashPlaygroundSource, parsePlaygroundSourceFiles, parsePlaygroundSourceOptions, walkMarkdownFiles, writeMarkdownComponentPlaygroundRegistry };
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// src/playground.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { dirname, extname, join, relative } from "path";
|
|
4
|
+
var DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX = "virtual:docs-markdown-playground/";
|
|
5
|
+
function walkMarkdownFiles(rootDir) {
|
|
6
|
+
if (!fs.existsSync(rootDir)) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const files = [];
|
|
10
|
+
const stack = [rootDir];
|
|
11
|
+
while (stack.length > 0) {
|
|
12
|
+
const current = stack.pop();
|
|
13
|
+
for (const entry of fs.readdirSync(current)) {
|
|
14
|
+
const fullPath = join(current, entry);
|
|
15
|
+
const info = fs.statSync(fullPath);
|
|
16
|
+
if (info.isDirectory()) {
|
|
17
|
+
stack.push(fullPath);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (extname(fullPath) === ".md") {
|
|
21
|
+
files.push(fullPath);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return files;
|
|
26
|
+
}
|
|
27
|
+
function hashPlaygroundSource(source) {
|
|
28
|
+
let hash = 2166136261;
|
|
29
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
30
|
+
hash ^= source.charCodeAt(index);
|
|
31
|
+
hash = Math.imul(hash, 16777619);
|
|
32
|
+
}
|
|
33
|
+
return (hash >>> 0).toString(36);
|
|
34
|
+
}
|
|
35
|
+
function parsePlaygroundSourceOptions(source) {
|
|
36
|
+
const options = {};
|
|
37
|
+
const firstFileFenceIndex = source.search(/^```/m);
|
|
38
|
+
const header = firstFileFenceIndex >= 0 ? source.slice(0, firstFileFenceIndex) : source;
|
|
39
|
+
for (const line of header.split("\n")) {
|
|
40
|
+
const match = line.match(/^([a-zA-Z0-9_-]+):\s*(.+)$/);
|
|
41
|
+
if (match?.[1] && match[2]) {
|
|
42
|
+
options[match[1]] = match[2].trim();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return options;
|
|
46
|
+
}
|
|
47
|
+
function parsePlaygroundSourceFiles(source) {
|
|
48
|
+
const files = {};
|
|
49
|
+
const fileFenceRe = /^```([a-zA-Z0-9_-]+)\s+file=(\S+)\s*\n([\s\S]*?)\n```/gm;
|
|
50
|
+
let match;
|
|
51
|
+
while ((match = fileFenceRe.exec(source)) !== null) {
|
|
52
|
+
if (match[2] && typeof match[3] === "string") {
|
|
53
|
+
files[match[2]] = match[3];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return files;
|
|
57
|
+
}
|
|
58
|
+
function collectMarkdownComponentPlaygrounds(contentRoot) {
|
|
59
|
+
const demos = /* @__PURE__ */ new Map();
|
|
60
|
+
const playgroundBlockRe = /^````playground-src\s*\n([\s\S]*?)\n````/gm;
|
|
61
|
+
for (const filePath of walkMarkdownFiles(contentRoot)) {
|
|
62
|
+
const markdown = fs.readFileSync(filePath, "utf8");
|
|
63
|
+
let match;
|
|
64
|
+
while ((match = playgroundBlockRe.exec(markdown)) !== null) {
|
|
65
|
+
const blockSource = match[1];
|
|
66
|
+
if (!blockSource) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const options = parsePlaygroundSourceOptions(blockSource);
|
|
70
|
+
const entry = options.entry;
|
|
71
|
+
if (options.mode !== "component" || !entry?.endsWith(".vue")) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const files = parsePlaygroundSourceFiles(blockSource);
|
|
75
|
+
const source = files[entry];
|
|
76
|
+
if (typeof source !== "string") {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`[docs] Markdown component playground in ${relative(process.cwd(), filePath)} uses entry "${entry}", but that file was not found in the playground block.`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const id = hashPlaygroundSource(source);
|
|
82
|
+
demos.set(id, {
|
|
83
|
+
entry,
|
|
84
|
+
files,
|
|
85
|
+
id,
|
|
86
|
+
source
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return [...demos.values()].sort((left, right) => left.id.localeCompare(right.id));
|
|
91
|
+
}
|
|
92
|
+
function toMarkdownImportVarName(demoId) {
|
|
93
|
+
return `MarkdownPlayground${demoId.replace(/[^a-zA-Z0-9_$]/g, "_")}Demo`;
|
|
94
|
+
}
|
|
95
|
+
function writeMarkdownComponentPlaygroundRegistry(demos, options) {
|
|
96
|
+
const virtualPrefix = options.virtualPrefix ?? DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX;
|
|
97
|
+
const lines = [];
|
|
98
|
+
lines.push("// This file is auto-generated by vue-ssg markdown playground scanner. Do not edit manually.");
|
|
99
|
+
lines.push("import type { Component } from 'vue'");
|
|
100
|
+
lines.push("");
|
|
101
|
+
for (const demo of demos) {
|
|
102
|
+
lines.push(`import ${toMarkdownImportVarName(demo.id)} from '${virtualPrefix}${demo.id}.vue'`);
|
|
103
|
+
}
|
|
104
|
+
lines.push("");
|
|
105
|
+
lines.push("export const docsVirtualPlaygroundRegistry: Record<string, Component> = {");
|
|
106
|
+
for (const demo of demos) {
|
|
107
|
+
lines.push(` '${demo.id}': ${toMarkdownImportVarName(demo.id)},`);
|
|
108
|
+
}
|
|
109
|
+
lines.push("}");
|
|
110
|
+
lines.push("");
|
|
111
|
+
lines.push("export const docsVirtualPlaygroundSourceRegistry: Record<string, string> = {");
|
|
112
|
+
for (const demo of demos) {
|
|
113
|
+
lines.push(` '${demo.id}': ${JSON.stringify(demo.source)},`);
|
|
114
|
+
}
|
|
115
|
+
lines.push("}");
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push("export const docsVirtualPlaygroundSourceFileRegistry: Record<string, string> = {");
|
|
118
|
+
for (const demo of demos) {
|
|
119
|
+
lines.push(` '${demo.id}': ${JSON.stringify(demo.entry)},`);
|
|
120
|
+
}
|
|
121
|
+
lines.push("}");
|
|
122
|
+
lines.push("");
|
|
123
|
+
lines.push("export const docsVirtualPlaygroundSourceLanguageRegistry: Record<string, string> = {");
|
|
124
|
+
for (const demo of demos) {
|
|
125
|
+
lines.push(` '${demo.id}': 'vue',`);
|
|
126
|
+
}
|
|
127
|
+
lines.push("}");
|
|
128
|
+
lines.push("");
|
|
129
|
+
fs.mkdirSync(dirname(options.generatedRegistryPath), { recursive: true });
|
|
130
|
+
fs.writeFileSync(options.generatedRegistryPath, lines.join("\n"), "utf8");
|
|
131
|
+
}
|
|
132
|
+
function createMarkdownComponentPlaygroundPlugin(demos, virtualPrefix = DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX) {
|
|
133
|
+
const sourceById = new Map(demos.map((demo) => [demo.id, demo.source]));
|
|
134
|
+
return {
|
|
135
|
+
name: "vue-ssg-markdown-component-playgrounds",
|
|
136
|
+
resolveId(id) {
|
|
137
|
+
if (id.startsWith(virtualPrefix)) {
|
|
138
|
+
return id;
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
},
|
|
142
|
+
load(id) {
|
|
143
|
+
if (!id.startsWith(virtualPrefix)) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const demoId = id.slice(virtualPrefix.length).replace(/\.vue$/, "");
|
|
147
|
+
return sourceById.get(demoId) ?? null;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function createMarkdownComponentPlaygrounds(options) {
|
|
152
|
+
const virtualPrefix = options.virtualPrefix ?? DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX;
|
|
153
|
+
const demos = collectMarkdownComponentPlaygrounds(options.contentRoot);
|
|
154
|
+
writeMarkdownComponentPlaygroundRegistry(demos, {
|
|
155
|
+
generatedRegistryPath: options.generatedRegistryPath,
|
|
156
|
+
virtualPrefix
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
demos,
|
|
160
|
+
plugin: createMarkdownComponentPlaygroundPlugin(demos, virtualPrefix),
|
|
161
|
+
virtualPrefix
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX,
|
|
166
|
+
collectMarkdownComponentPlaygrounds,
|
|
167
|
+
createMarkdownComponentPlaygroundPlugin,
|
|
168
|
+
createMarkdownComponentPlaygrounds,
|
|
169
|
+
hashPlaygroundSource,
|
|
170
|
+
parsePlaygroundSourceFiles,
|
|
171
|
+
parsePlaygroundSourceOptions,
|
|
172
|
+
walkMarkdownFiles,
|
|
173
|
+
writeMarkdownComponentPlaygroundRegistry
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=playground.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/playground.ts"],"sourcesContent":["import fs from 'node:fs'\nimport { dirname, extname, join, relative } from 'node:path'\n\nexport interface MarkdownComponentPlayground {\n entry: string\n files: Record<string, string>\n id: string\n source: string\n}\n\nexport interface MarkdownComponentPlaygroundOptions {\n contentRoot: string\n generatedRegistryPath: string\n virtualPrefix?: string\n}\n\nexport interface MarkdownComponentPlaygroundRegistryOptions {\n generatedRegistryPath: string\n virtualPrefix?: string\n}\n\nexport const DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX = 'virtual:docs-markdown-playground/'\n\nexport function walkMarkdownFiles(rootDir: string): string[] {\n if (!fs.existsSync(rootDir)) {\n return []\n }\n\n const files: string[] = []\n const stack = [rootDir]\n\n while (stack.length > 0) {\n const current = stack.pop()!\n for (const entry of fs.readdirSync(current)) {\n const fullPath = join(current, entry)\n const info = fs.statSync(fullPath)\n if (info.isDirectory()) {\n stack.push(fullPath)\n continue\n }\n\n if (extname(fullPath) === '.md') {\n files.push(fullPath)\n }\n }\n }\n\n return files\n}\n\nexport function hashPlaygroundSource(source: string): string {\n let hash = 2166136261\n for (let index = 0; index < source.length; index += 1) {\n hash ^= source.charCodeAt(index)\n hash = Math.imul(hash, 16777619)\n }\n\n return (hash >>> 0).toString(36)\n}\n\nexport function parsePlaygroundSourceOptions(source: string): Record<string, string> {\n const options: Record<string, string> = {}\n const firstFileFenceIndex = source.search(/^```/m)\n const header = firstFileFenceIndex >= 0 ? source.slice(0, firstFileFenceIndex) : source\n\n for (const line of header.split('\\n')) {\n const match = line.match(/^([a-zA-Z0-9_-]+):\\s*(.+)$/)\n if (match?.[1] && match[2]) {\n options[match[1]] = match[2].trim()\n }\n }\n\n return options\n}\n\nexport function parsePlaygroundSourceFiles(source: string): Record<string, string> {\n const files: Record<string, string> = {}\n const fileFenceRe = /^```([a-zA-Z0-9_-]+)\\s+file=(\\S+)\\s*\\n([\\s\\S]*?)\\n```/gm\n let match: RegExpExecArray | null\n\n while ((match = fileFenceRe.exec(source)) !== null) {\n if (match[2] && typeof match[3] === 'string') {\n files[match[2]] = match[3]\n }\n }\n\n return files\n}\n\nexport function collectMarkdownComponentPlaygrounds(contentRoot: string): MarkdownComponentPlayground[] {\n const demos = new Map<string, MarkdownComponentPlayground>()\n const playgroundBlockRe = /^````playground-src\\s*\\n([\\s\\S]*?)\\n````/gm\n\n for (const filePath of walkMarkdownFiles(contentRoot)) {\n const markdown = fs.readFileSync(filePath, 'utf8')\n let match: RegExpExecArray | null\n\n while ((match = playgroundBlockRe.exec(markdown)) !== null) {\n const blockSource = match[1]\n if (!blockSource) {\n continue\n }\n\n const options = parsePlaygroundSourceOptions(blockSource)\n const entry = options.entry\n if (options.mode !== 'component' || !entry?.endsWith('.vue')) {\n continue\n }\n\n const files = parsePlaygroundSourceFiles(blockSource)\n const source = files[entry]\n if (typeof source !== 'string') {\n throw new Error(\n `[docs] Markdown component playground in ${relative(process.cwd(), filePath)} uses entry \"${entry}\", but that file was not found in the playground block.`\n )\n }\n\n const id = hashPlaygroundSource(source)\n demos.set(id, {\n entry,\n files,\n id,\n source\n })\n }\n }\n\n return [...demos.values()].sort((left, right) => left.id.localeCompare(right.id))\n}\n\nfunction toMarkdownImportVarName(demoId: string): string {\n return `MarkdownPlayground${demoId.replace(/[^a-zA-Z0-9_$]/g, '_')}Demo`\n}\n\nexport function writeMarkdownComponentPlaygroundRegistry(\n demos: MarkdownComponentPlayground[],\n options: MarkdownComponentPlaygroundRegistryOptions\n): void {\n const virtualPrefix = options.virtualPrefix ?? DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX\n const lines: string[] = []\n lines.push('// This file is auto-generated by vue-ssg markdown playground scanner. Do not edit manually.')\n lines.push(\"import type { Component } from 'vue'\")\n lines.push('')\n\n for (const demo of demos) {\n lines.push(`import ${toMarkdownImportVarName(demo.id)} from '${virtualPrefix}${demo.id}.vue'`)\n }\n\n lines.push('')\n lines.push('export const docsVirtualPlaygroundRegistry: Record<string, Component> = {')\n for (const demo of demos) {\n lines.push(` '${demo.id}': ${toMarkdownImportVarName(demo.id)},`)\n }\n lines.push('}')\n lines.push('')\n lines.push('export const docsVirtualPlaygroundSourceRegistry: Record<string, string> = {')\n for (const demo of demos) {\n lines.push(` '${demo.id}': ${JSON.stringify(demo.source)},`)\n }\n lines.push('}')\n lines.push('')\n lines.push(\"export const docsVirtualPlaygroundSourceFileRegistry: Record<string, string> = {\")\n for (const demo of demos) {\n lines.push(` '${demo.id}': ${JSON.stringify(demo.entry)},`)\n }\n lines.push('}')\n lines.push('')\n lines.push(\"export const docsVirtualPlaygroundSourceLanguageRegistry: Record<string, string> = {\")\n for (const demo of demos) {\n lines.push(` '${demo.id}': 'vue',`)\n }\n lines.push('}')\n lines.push('')\n\n fs.mkdirSync(dirname(options.generatedRegistryPath), { recursive: true })\n fs.writeFileSync(options.generatedRegistryPath, lines.join('\\n'), 'utf8')\n}\n\nexport function createMarkdownComponentPlaygroundPlugin(\n demos: MarkdownComponentPlayground[],\n virtualPrefix = DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX\n) {\n const sourceById = new Map(demos.map((demo) => [demo.id, demo.source]))\n\n return {\n name: 'vue-ssg-markdown-component-playgrounds',\n resolveId(id: string) {\n if (id.startsWith(virtualPrefix)) {\n return id\n }\n\n return null\n },\n load(id: string) {\n if (!id.startsWith(virtualPrefix)) {\n return null\n }\n\n const demoId = id\n .slice(virtualPrefix.length)\n .replace(/\\.vue$/, '')\n\n return sourceById.get(demoId) ?? null\n }\n }\n}\n\nexport function createMarkdownComponentPlaygrounds(options: MarkdownComponentPlaygroundOptions) {\n const virtualPrefix = options.virtualPrefix ?? DEFAULT_MARKDOWN_COMPONENT_PLAYGROUND_PREFIX\n const demos = collectMarkdownComponentPlaygrounds(options.contentRoot)\n\n writeMarkdownComponentPlaygroundRegistry(demos, {\n generatedRegistryPath: options.generatedRegistryPath,\n virtualPrefix\n })\n\n return {\n demos,\n plugin: createMarkdownComponentPlaygroundPlugin(demos, virtualPrefix),\n virtualPrefix\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemonster-ru/vue-ssg-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Core APIs for Codemonster SSG apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vue",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
".": {
|
|
32
32
|
"types": "./dist/index.d.ts",
|
|
33
33
|
"import": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./playground": {
|
|
36
|
+
"types": "./dist/playground.d.ts",
|
|
37
|
+
"import": "./dist/playground.js"
|
|
34
38
|
}
|
|
35
39
|
},
|
|
36
40
|
"files": [
|
|
@@ -45,12 +49,13 @@
|
|
|
45
49
|
"prepublishOnly": "npm run typecheck && npm run build"
|
|
46
50
|
},
|
|
47
51
|
"peerDependencies": {
|
|
52
|
+
"@unhead/vue": "^2.1.13",
|
|
48
53
|
"vue": "^3.5.0",
|
|
49
|
-
"vue-router": "^4.0.0 || ^5.0.0"
|
|
50
|
-
"@unhead/vue": "^2.0.0"
|
|
54
|
+
"vue-router": "^4.0.0 || ^5.0.0"
|
|
51
55
|
},
|
|
52
56
|
"dependencies": {
|
|
53
|
-
"@codemonster-ru/vueforge-core": "^1.
|
|
57
|
+
"@codemonster-ru/vueforge-core": "^1.18.7",
|
|
58
|
+
"@unhead/vue": "^2.1.13",
|
|
54
59
|
"github-slugger": "^2.0.0",
|
|
55
60
|
"marked": "^17.0.5"
|
|
56
61
|
},
|