@clarify-labs/cli 0.6.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/output/cli.cjs +5 -4
- package/output/cli.cjs.map +1 -1
- package/output/cli.js +5 -4
- package/output/cli.js.map +1 -1
- package/output/core/config-schema.d.ts +25 -4
- package/output/core/search-language.d.ts +1 -0
- package/output/core/ssg.d.ts +1 -1
- package/output/core/temp-dir.d.ts +2 -0
- package/output/core/virtual-modules.d.ts +8 -1
- package/output/index.cjs +1 -1
- package/output/index.js +1 -1
- package/output/parsers/routes.d.ts +4 -2
- package/output/{plugin-DC2f5YAH.js → plugin-BNzlJ4o7.js} +413 -112
- package/output/plugin-BNzlJ4o7.js.map +1 -0
- package/output/{plugin-GTN_SQ7d.cjs → plugin-dzXRzjdX.cjs} +417 -110
- package/output/plugin-dzXRzjdX.cjs.map +1 -0
- package/output/plugins/openapi/virtual-modules.d.ts +1 -1
- package/output/plugins/search-index/index.d.ts +2 -0
- package/output/types.d.ts +7 -1
- package/package.json +5 -3
- package/output/plugin-DC2f5YAH.js.map +0 -1
- package/output/plugin-GTN_SQ7d.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { createReadStream, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
3
3
|
import mdxPlugin from "@mdx-js/rollup";
|
|
4
4
|
import tailwindcss from "@tailwindcss/vite";
|
|
@@ -11,9 +11,9 @@ import { markdownRemarkPlugins } from "@clarify-labs/renderer";
|
|
|
11
11
|
import { remark } from "remark";
|
|
12
12
|
import matter from "gray-matter";
|
|
13
13
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
14
15
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
15
16
|
import { z } from "zod";
|
|
16
|
-
import { tmpdir } from "node:os";
|
|
17
17
|
import { pathToFileURL } from "node:url";
|
|
18
18
|
import { build, loadConfigFromFile } from "vite";
|
|
19
19
|
import { createRequire } from "node:module";
|
|
@@ -232,8 +232,80 @@ function createContentArtifactsPlugin() {
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
//#endregion
|
|
235
|
+
//#region source/core/theme.ts
|
|
236
|
+
var clarifyThemePresets = {
|
|
237
|
+
default: {
|
|
238
|
+
preset: "default",
|
|
239
|
+
tokens: {
|
|
240
|
+
colors: {
|
|
241
|
+
primary: "#047857",
|
|
242
|
+
accent: "#0D9488",
|
|
243
|
+
background: "#ffffff",
|
|
244
|
+
foreground: "#111827",
|
|
245
|
+
surface: "#ffffff",
|
|
246
|
+
muted: "#64748b",
|
|
247
|
+
border: "rgb(15 23 42 / 0.12)",
|
|
248
|
+
codeBackground: "#f6fbf8"
|
|
249
|
+
},
|
|
250
|
+
radius: {
|
|
251
|
+
sm: "6px",
|
|
252
|
+
md: "10px",
|
|
253
|
+
lg: "14px",
|
|
254
|
+
xl: "18px"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
layout: { maxWidth: "82rem" },
|
|
258
|
+
editor: false
|
|
259
|
+
},
|
|
260
|
+
base: {
|
|
261
|
+
preset: "base",
|
|
262
|
+
tokens: {
|
|
263
|
+
colors: {
|
|
264
|
+
primary: "#18181b",
|
|
265
|
+
accent: "#52525b",
|
|
266
|
+
background: "#ffffff",
|
|
267
|
+
foreground: "#18181b",
|
|
268
|
+
surface: "#ffffff",
|
|
269
|
+
muted: "#71717a",
|
|
270
|
+
border: "rgb(24 24 27 / 0.12)",
|
|
271
|
+
codeBackground: "#f4f4f5"
|
|
272
|
+
},
|
|
273
|
+
radius: {
|
|
274
|
+
sm: "6px",
|
|
275
|
+
md: "8px",
|
|
276
|
+
lg: "12px",
|
|
277
|
+
xl: "16px"
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
layout: { maxWidth: "80rem" },
|
|
281
|
+
editor: false
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
function resolveThemeConfig(theme = {}) {
|
|
285
|
+
const preset = theme.preset ?? "default";
|
|
286
|
+
const presetTheme = clarifyThemePresets[preset];
|
|
287
|
+
return {
|
|
288
|
+
preset,
|
|
289
|
+
tokens: {
|
|
290
|
+
colors: {
|
|
291
|
+
...presetTheme.tokens.colors,
|
|
292
|
+
...theme.tokens?.colors
|
|
293
|
+
},
|
|
294
|
+
radius: {
|
|
295
|
+
...presetTheme.tokens.radius,
|
|
296
|
+
...theme.tokens?.radius
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
layout: {
|
|
300
|
+
...presetTheme.layout,
|
|
301
|
+
...theme.layout
|
|
302
|
+
},
|
|
303
|
+
editor: theme.editor ?? presetTheme.editor
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
235
307
|
//#region source/plugins/html-shell/index.ts
|
|
236
|
-
var
|
|
308
|
+
var THEME_STORAGE_KEY = "clarify:theme";
|
|
237
309
|
var REL_ICON_RE = /<link\s+[^>]*rel=["'][^"']*\bicon\b[^"']*["'][^>]*>/i;
|
|
238
310
|
function inferIconType(href) {
|
|
239
311
|
const path = href.split(/[?#]/, 1)[0]?.toLowerCase() ?? href.toLowerCase();
|
|
@@ -263,6 +335,62 @@ function createIconTags(icon) {
|
|
|
263
335
|
if (lightIcon === darkIcon) return [createIconTag(lightIcon)];
|
|
264
336
|
return [createIconTag(lightIcon, "(prefers-color-scheme: light)"), createIconTag(darkIcon, "(prefers-color-scheme: dark)")];
|
|
265
337
|
}
|
|
338
|
+
function matchesPresetTheme(theme) {
|
|
339
|
+
const preset = clarifyThemePresets[theme.preset];
|
|
340
|
+
return JSON.stringify({
|
|
341
|
+
tokens: theme.tokens,
|
|
342
|
+
layout: theme.layout
|
|
343
|
+
}) === JSON.stringify({
|
|
344
|
+
tokens: preset.tokens,
|
|
345
|
+
layout: preset.layout
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
function effectiveTheme(theme, resolvedTheme) {
|
|
349
|
+
if (resolvedTheme !== "dark" || !matchesPresetTheme(theme)) return theme;
|
|
350
|
+
return {
|
|
351
|
+
...theme,
|
|
352
|
+
tokens: {
|
|
353
|
+
...theme.tokens,
|
|
354
|
+
colors: {
|
|
355
|
+
...theme.tokens.colors,
|
|
356
|
+
background: "#09090b",
|
|
357
|
+
foreground: "#ffffff",
|
|
358
|
+
surface: "#18181b",
|
|
359
|
+
muted: "#a1a1aa",
|
|
360
|
+
border: "rgb(255 255 255 / 0.1)",
|
|
361
|
+
codeBackground: "#18181b"
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function resolveThemeColorValue(value, resolvedTheme) {
|
|
367
|
+
return typeof value === "string" ? value : value[resolvedTheme] ?? value.light ?? value.dark ?? "";
|
|
368
|
+
}
|
|
369
|
+
function themeToCssVariables(theme, resolvedTheme) {
|
|
370
|
+
const resolved = effectiveTheme(theme, resolvedTheme);
|
|
371
|
+
const { colors } = resolved.tokens;
|
|
372
|
+
const { radius } = resolved.tokens;
|
|
373
|
+
return {
|
|
374
|
+
"--clarify-theme-tokens-colors-primary": resolveThemeColorValue(colors.primary, resolvedTheme),
|
|
375
|
+
"--clarify-theme-tokens-colors-accent": resolveThemeColorValue(colors.accent, resolvedTheme),
|
|
376
|
+
"--clarify-theme-tokens-colors-background": resolveThemeColorValue(colors.background, resolvedTheme),
|
|
377
|
+
"--clarify-theme-tokens-colors-foreground": resolveThemeColorValue(colors.foreground, resolvedTheme),
|
|
378
|
+
"--clarify-theme-tokens-colors-surface": resolveThemeColorValue(colors.surface, resolvedTheme),
|
|
379
|
+
"--clarify-theme-tokens-colors-muted": resolveThemeColorValue(colors.muted, resolvedTheme),
|
|
380
|
+
"--clarify-theme-tokens-colors-border": resolveThemeColorValue(colors.border, resolvedTheme),
|
|
381
|
+
"--clarify-theme-tokens-colors-code-background": resolveThemeColorValue(colors.codeBackground, resolvedTheme),
|
|
382
|
+
"--clarify-theme-tokens-radius-sm": radius.sm,
|
|
383
|
+
"--clarify-theme-tokens-radius-md": radius.md,
|
|
384
|
+
"--clarify-theme-tokens-radius-lg": radius.lg,
|
|
385
|
+
"--clarify-theme-tokens-radius-xl": radius.xl,
|
|
386
|
+
"--clarify-theme-layout-max-width": resolved.layout.maxWidth
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
function themeBootstrapScript(theme) {
|
|
390
|
+
const darkVariables = themeToCssVariables(theme, "dark");
|
|
391
|
+
const lightVariables = themeToCssVariables(theme, "light");
|
|
392
|
+
return `(function(){try{var e=localStorage.getItem(${JSON.stringify(THEME_STORAGE_KEY)});var t=e==='dark'||e==='light'||e==='system'?e:'system';var r=t==='system'?window.matchMedia('(prefers-color-scheme: dark)').matches:t==='dark';var v=r?${JSON.stringify(darkVariables)}:${JSON.stringify(lightVariables)};var s=document.documentElement.style;for(var k in v)s.setProperty(k,v[k]);document.documentElement.classList.toggle('dark',r);document.documentElement.style.colorScheme=r?'dark':'light'}catch(e){}})();`;
|
|
393
|
+
}
|
|
266
394
|
function createHtmlShellPlugin() {
|
|
267
395
|
return {
|
|
268
396
|
name: "clarify:html-shell",
|
|
@@ -273,7 +401,7 @@ function createHtmlShellPlugin() {
|
|
|
273
401
|
...REL_ICON_RE.test(input.html) ? [] : createIconTags(ctx.projectConfig.favicon ?? ctx.projectConfig.logo),
|
|
274
402
|
{
|
|
275
403
|
tag: "script",
|
|
276
|
-
children:
|
|
404
|
+
children: themeBootstrapScript(ctx.projectConfig.theme),
|
|
277
405
|
injectTo: "head-prepend"
|
|
278
406
|
},
|
|
279
407
|
{
|
|
@@ -356,13 +484,14 @@ function basePathFromRef(ref) {
|
|
|
356
484
|
const withoutExtension = ref.replace(/\.mdx?$/, "").replace(/\.openapi\.(json|yaml|yml)$/, "");
|
|
357
485
|
return normalizePath(withoutExtension === "index" ? "/" : withoutExtension.replace(/\/index$/, ""));
|
|
358
486
|
}
|
|
359
|
-
function openAPIPagePathFromRef(ref, tagFilter) {
|
|
487
|
+
function openAPIPagePathFromRef(ref, tagFilter, explicitPath) {
|
|
488
|
+
if (explicitPath) return normalizePath(explicitPath);
|
|
360
489
|
const basePath = basePathFromRef(ref);
|
|
361
490
|
if (!tagFilter?.length) return basePath;
|
|
362
491
|
return normalizePath(`${basePath}/${openAPITagsPathSegment(tagFilter)}`);
|
|
363
492
|
}
|
|
364
|
-
function routePathFromRef(ref) {
|
|
365
|
-
return basePathFromRef(ref);
|
|
493
|
+
function routePathFromRef(ref, explicitPath) {
|
|
494
|
+
return explicitPath ? normalizePath(explicitPath) : basePathFromRef(ref);
|
|
366
495
|
}
|
|
367
496
|
function virtualModuleIdFromRef(ref) {
|
|
368
497
|
return "virtual:clarify-page/" + ref.replace(/\.mdx?$/, "").replace(/\.openapi\.(json|yaml|yml)$/, "").replace(/\/+/g, "/");
|
|
@@ -416,6 +545,18 @@ function frontmatterKeywords(frontmatter) {
|
|
|
416
545
|
const keywords = Array.isArray(value) ? value.filter((item) => typeof item === "string") : typeof value === "string" ? value.split(",").map((keyword) => keyword.trim()).filter(Boolean) : [];
|
|
417
546
|
return keywords.length > 0 ? keywords : void 0;
|
|
418
547
|
}
|
|
548
|
+
function withAlternates$2(route, routes, i18n) {
|
|
549
|
+
const basePath = route.basePath ?? route.path;
|
|
550
|
+
const routeByLocaleAndBase = new Map(routes.map((route) => [`${route.locale ?? ""}:${route.basePath ?? route.path}`, route]));
|
|
551
|
+
const alternates = Object.fromEntries(i18n.locales.flatMap((locale) => {
|
|
552
|
+
const alternate = routeByLocaleAndBase.get(`${locale.code}:${basePath}`);
|
|
553
|
+
return alternate ? [[locale.code, alternate.path]] : [];
|
|
554
|
+
}));
|
|
555
|
+
return {
|
|
556
|
+
...route,
|
|
557
|
+
alternates
|
|
558
|
+
};
|
|
559
|
+
}
|
|
419
560
|
function buildNavigation(routes) {
|
|
420
561
|
const root = [];
|
|
421
562
|
for (const route of routes) {
|
|
@@ -447,11 +588,13 @@ function resolvePageItem(item) {
|
|
|
447
588
|
if ("openapi" in item) return {
|
|
448
589
|
openapiRef: item.openapi,
|
|
449
590
|
openapiTagFilter: item.filter?.tags,
|
|
591
|
+
path: item.path,
|
|
450
592
|
title: item.title,
|
|
451
593
|
icon: item.icon
|
|
452
594
|
};
|
|
453
595
|
return {
|
|
454
596
|
pageRef: item.page,
|
|
597
|
+
path: item.path,
|
|
455
598
|
redirect: item.redirect,
|
|
456
599
|
title: item.title,
|
|
457
600
|
icon: item.icon
|
|
@@ -465,6 +608,41 @@ function firstNavigationPath(nodes) {
|
|
|
465
608
|
}
|
|
466
609
|
return "/";
|
|
467
610
|
}
|
|
611
|
+
function collectExplicitPagePathItems(tabs) {
|
|
612
|
+
const items = [];
|
|
613
|
+
for (const tab of tabs ?? []) {
|
|
614
|
+
if (!tab.pages || tab.pages === "FileTree") continue;
|
|
615
|
+
for (const group of tab.pages) for (const item of group.pages) if (typeof item !== "string" && "page" in item && item.path) items.push({
|
|
616
|
+
pageRef: item.page,
|
|
617
|
+
path: item.path
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
return items;
|
|
621
|
+
}
|
|
622
|
+
function applyConfiguredPageRoutePaths(routes, tabs, i18n) {
|
|
623
|
+
const pageItems = collectExplicitPagePathItems(tabs);
|
|
624
|
+
if (!pageItems.length) return routes;
|
|
625
|
+
const additions = [];
|
|
626
|
+
const existingKeys = new Set(routes.map((route) => `${route.locale ?? ""}:${route.basePath ?? route.path}`));
|
|
627
|
+
for (const item of pageItems) {
|
|
628
|
+
const sourceBasePath = routePathFromRef(item.pageRef);
|
|
629
|
+
const targetBasePath = routePathFromRef(item.pageRef, item.path);
|
|
630
|
+
if (sourceBasePath === targetBasePath) continue;
|
|
631
|
+
for (const route of routes) {
|
|
632
|
+
if (route.kind !== "mdx" || (route.basePath ?? route.path) !== sourceBasePath) continue;
|
|
633
|
+
const key = `${route.locale ?? ""}:${targetBasePath}`;
|
|
634
|
+
if (existingKeys.has(key)) continue;
|
|
635
|
+
existingKeys.add(key);
|
|
636
|
+
additions.push({
|
|
637
|
+
...route,
|
|
638
|
+
path: route.locale && i18n ? localizedRoutePath(targetBasePath, route.locale, i18n) : targetBasePath,
|
|
639
|
+
basePath: targetBasePath
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const nextRoutes = [...routes, ...additions];
|
|
644
|
+
return i18n ? nextRoutes.map((route) => withAlternates$2(route, nextRoutes, i18n)) : nextRoutes;
|
|
645
|
+
}
|
|
468
646
|
function buildNavigationFromPagesConfig(routes, config) {
|
|
469
647
|
if (!config || config === "FileTree") return buildNavigation(routes);
|
|
470
648
|
return buildNavigationFromConfig(routes, config);
|
|
@@ -485,9 +663,9 @@ function buildNavigationFromConfig(routes, config) {
|
|
|
485
663
|
const routeMap = new Map(routes.map((r) => [r.path, r]));
|
|
486
664
|
return config.map((group) => {
|
|
487
665
|
const children = group.pages.map((item) => {
|
|
488
|
-
const { pageRef, openapiRef, openapiTagFilter, redirect, title, icon } = resolvePageItem(item);
|
|
666
|
+
const { pageRef, openapiRef, openapiTagFilter, path: explicitPath, redirect, title, icon } = resolvePageItem(item);
|
|
489
667
|
if (openapiRef) {
|
|
490
|
-
const path = openAPIPagePathFromRef(openapiRef, openapiTagFilter);
|
|
668
|
+
const path = openAPIPagePathFromRef(openapiRef, openapiTagFilter, explicitPath);
|
|
491
669
|
const route = routeMap.get(path);
|
|
492
670
|
return {
|
|
493
671
|
path,
|
|
@@ -497,10 +675,10 @@ function buildNavigationFromConfig(routes, config) {
|
|
|
497
675
|
};
|
|
498
676
|
}
|
|
499
677
|
const ref = pageRef ?? "";
|
|
500
|
-
const path = ref
|
|
678
|
+
const path = routePathFromRef(ref, explicitPath);
|
|
501
679
|
const route = routeMap.get(path);
|
|
502
680
|
return {
|
|
503
|
-
path: redirect ? redirect : path,
|
|
681
|
+
path: redirect ? normalizePath(redirect) : path,
|
|
504
682
|
title: resolveLocalizedText(title, "", "") ?? route?.title ?? kebabToTitle$1(path.split("/").pop() ?? ref),
|
|
505
683
|
icon,
|
|
506
684
|
sections: route?.sections ? navigationSections(route.sections) : void 0
|
|
@@ -529,13 +707,13 @@ function buildLocalizedNavigationForLocale(routes, config, locale, i18n) {
|
|
|
529
707
|
const routeMap = new Map(routes.map((route) => [route.basePath ?? route.path, route]));
|
|
530
708
|
return config.map((group) => {
|
|
531
709
|
const children = group.pages.map((item) => {
|
|
532
|
-
const { pageRef, openapiRef, openapiTagFilter, redirect, title, icon } = resolvePageItem(item);
|
|
710
|
+
const { pageRef, openapiRef, openapiTagFilter, path: explicitPath, redirect, title, icon } = resolvePageItem(item);
|
|
533
711
|
const ref = openapiRef ?? pageRef ?? "";
|
|
534
|
-
const basePath = openapiRef ? openAPIPagePathFromRef(openapiRef, openapiTagFilter) :
|
|
712
|
+
const basePath = openapiRef ? openAPIPagePathFromRef(openapiRef, openapiTagFilter, explicitPath) : routePathFromRef(ref, explicitPath);
|
|
535
713
|
const route = routeMap.get(basePath);
|
|
536
714
|
const path = route?.path ?? localizedRoutePath(basePath, locale, i18n);
|
|
537
715
|
return {
|
|
538
|
-
path: (redirect ? localizedRoutePath(
|
|
716
|
+
path: (redirect ? localizedRoutePath(routePathFromRef(redirect), locale, i18n) : void 0) ?? path,
|
|
539
717
|
title: resolveLocalizedText(title, locale, i18n.defaultLocale) ?? route?.title ?? kebabToTitle$1(basePath.split("/").pop() ?? ref),
|
|
540
718
|
icon,
|
|
541
719
|
sections: route?.sections ? navigationSections(route.sections) : void 0
|
|
@@ -700,8 +878,10 @@ function generateRoutesModule(routes, resolvedNavigation, projectConfig, mode =
|
|
|
700
878
|
const navigation = resolvedNavigation ?? (projectConfig?.tabs ? projectConfig.i18n ? buildLocalizedNavigationFromTabsConfig(routes, projectConfig.tabs, projectConfig.i18n) ?? {} : buildNavigationFromTabsConfig(routes, projectConfig.tabs) : buildNavigation(routes));
|
|
701
879
|
return `${imports}\n\nexport const routes = [\n${routesArray}\n];\n\nexport const navigation = ${JSON.stringify(navigation, null, 2)};\n`;
|
|
702
880
|
}
|
|
703
|
-
function createRuntimeModule() {
|
|
704
|
-
return "
|
|
881
|
+
function createRuntimeModule(options = {}) {
|
|
882
|
+
return `${options.footerComponentSource === "path" && options.imports?.footerComponent ? `import FooterComponent from ${moduleSpecifier(options.imports.footerComponent)};` : ""}
|
|
883
|
+
export const openApis = {};
|
|
884
|
+
export const footerComponent = ${options.footerComponentSource === "path" ? "FooterComponent" : "undefined"};`;
|
|
705
885
|
}
|
|
706
886
|
function createClientEntryModule(options = {}) {
|
|
707
887
|
return `
|
|
@@ -709,16 +889,22 @@ import '@clarify-labs/renderer/style.css';
|
|
|
709
889
|
import { render } from '@clarify-labs/renderer/client';
|
|
710
890
|
import { routes, navigation } from '${VIRTUAL_ROUTES}';
|
|
711
891
|
import { config } from '${VIRTUAL_CONFIG}';
|
|
712
|
-
import { openApis } from '${VIRTUAL_RUNTIME}';
|
|
713
|
-
render({ config, routes, navigation, openApis, themeEditor: ${JSON.stringify(options.themeEditor ?? false)} });`;
|
|
892
|
+
import { openApis, footerComponent } from '${VIRTUAL_RUNTIME}';
|
|
893
|
+
render({ config, routes, navigation, openApis, footerComponent, themeEditor: ${JSON.stringify(options.themeEditor ?? false)} });`;
|
|
714
894
|
}
|
|
715
895
|
function buildVirtualModules(args) {
|
|
716
896
|
const modules = /* @__PURE__ */ new Map();
|
|
717
897
|
const clientEntryModule = createClientEntryModule({ themeEditor: args.themeEditor });
|
|
898
|
+
const footerComponent = args.projectConfig.footer;
|
|
899
|
+
const footerComponentSource = typeof footerComponent === "string" ? "path" : void 0;
|
|
900
|
+
const footerComponentImport = typeof footerComponent === "string" ? footerComponent : void 0;
|
|
718
901
|
modules.set(VIRTUAL_CONFIG, generateConfigModule(args.projectConfig, args.generateOptions));
|
|
719
902
|
modules.set(VIRTUAL_ROUTES, generateRoutesModule(args.routes, args.navigation, args.projectConfig, "client"));
|
|
720
903
|
modules.set(VIRTUAL_SERVER_ROUTES, generateRoutesModule(args.routes, args.navigation, args.projectConfig, "server"));
|
|
721
|
-
modules.set(VIRTUAL_RUNTIME, createRuntimeModule(
|
|
904
|
+
modules.set(VIRTUAL_RUNTIME, createRuntimeModule({
|
|
905
|
+
footerComponentSource,
|
|
906
|
+
imports: { footerComponent: footerComponentImport }
|
|
907
|
+
}));
|
|
722
908
|
modules.set(VIRTUAL_CLIENT_ENTRY, clientEntryModule);
|
|
723
909
|
modules.set(RESOLVED_CLIENT_ENTRY, clientEntryModule);
|
|
724
910
|
for (const route of args.routes) modules.set(route.virtualModuleId, `export { default } from ${moduleSpecifier(route.filePath)};`);
|
|
@@ -727,8 +913,12 @@ function buildVirtualModules(args) {
|
|
|
727
913
|
//#endregion
|
|
728
914
|
//#region source/plugins/openapi/virtual-modules.ts
|
|
729
915
|
var openApiRegistryModuleId = VIRTUAL_RUNTIME;
|
|
730
|
-
function generateOpenAPIRegistryModule(openApis) {
|
|
731
|
-
|
|
916
|
+
function generateOpenAPIRegistryModule(openApis, runtimeModule = "") {
|
|
917
|
+
const openApisExport = `export const openApis = ${JSON.stringify(openApis)};`;
|
|
918
|
+
const openApisPlaceholder = /export const openApis = \{\};?/;
|
|
919
|
+
if (!runtimeModule) return openApisExport;
|
|
920
|
+
if (openApisPlaceholder.test(runtimeModule)) return runtimeModule.replace(openApisPlaceholder, openApisExport);
|
|
921
|
+
return runtimeModule;
|
|
732
922
|
}
|
|
733
923
|
function generateOpenAPIModule(spec, tagFilter) {
|
|
734
924
|
return `import { createElement } from 'react';
|
|
@@ -766,7 +956,7 @@ function collectOpenAPIPageItems(config) {
|
|
|
766
956
|
const items = [];
|
|
767
957
|
function visitPages(pages) {
|
|
768
958
|
if (!pages || pages === "FileTree") return;
|
|
769
|
-
for (const group of pages) for (const item of group.pages) if (typeof item !== "string" && "openapi" in item && item.filter?.tags?.length) items.push(item);
|
|
959
|
+
for (const group of pages) for (const item of group.pages) if (typeof item !== "string" && "openapi" in item && (item.path || item.filter?.tags?.length)) items.push(item);
|
|
770
960
|
}
|
|
771
961
|
for (const tab of config.tabs ?? []) visitPages(tab.pages);
|
|
772
962
|
return items;
|
|
@@ -783,28 +973,31 @@ function withAlternates$1(route, routes, i18n) {
|
|
|
783
973
|
alternates
|
|
784
974
|
};
|
|
785
975
|
}
|
|
786
|
-
function
|
|
976
|
+
function virtualModuleIdFromPath(path) {
|
|
977
|
+
return `virtual:clarify-page/${path.replace(/^\/+/, "") || "index"}`;
|
|
978
|
+
}
|
|
979
|
+
function createConfiguredOpenAPIRoutes(routes, config) {
|
|
787
980
|
const pageItems = collectOpenAPIPageItems(config);
|
|
788
981
|
if (!pageItems.length) return routes;
|
|
789
982
|
const additions = [];
|
|
790
983
|
const existingKeys = new Set(routes.map((route) => `${route.locale ?? ""}:${route.basePath ?? route.path}`));
|
|
791
984
|
for (const item of pageItems) {
|
|
792
985
|
const tagFilter = item.filter?.tags?.filter(Boolean);
|
|
793
|
-
if (!tagFilter?.length) continue;
|
|
794
986
|
const sourceBasePath = openAPIPagePathFromRef(item.openapi);
|
|
795
|
-
const
|
|
987
|
+
const targetBasePath = openAPIPagePathFromRef(item.openapi, tagFilter, item.path);
|
|
988
|
+
if (sourceBasePath === targetBasePath && !tagFilter?.length) continue;
|
|
796
989
|
for (const route of routes) {
|
|
797
990
|
if (route.kind !== "openapi" || (route.basePath ?? route.path) !== sourceBasePath) continue;
|
|
798
|
-
const key = `${route.locale ?? ""}:${
|
|
991
|
+
const key = `${route.locale ?? ""}:${targetBasePath}`;
|
|
799
992
|
if (existingKeys.has(key)) continue;
|
|
800
993
|
existingKeys.add(key);
|
|
801
994
|
additions.push({
|
|
802
995
|
...route,
|
|
803
|
-
path: route.locale && config.i18n ? localizedRoutePath(
|
|
804
|
-
basePath:
|
|
996
|
+
path: route.locale && config.i18n ? localizedRoutePath(targetBasePath, route.locale, config.i18n) : targetBasePath,
|
|
997
|
+
basePath: targetBasePath,
|
|
805
998
|
title: route.title,
|
|
806
|
-
virtualModuleId:
|
|
807
|
-
openapiTagFilter: tagFilter
|
|
999
|
+
virtualModuleId: virtualModuleIdFromPath(targetBasePath),
|
|
1000
|
+
openapiTagFilter: tagFilter?.length ? tagFilter : void 0
|
|
808
1001
|
});
|
|
809
1002
|
}
|
|
810
1003
|
}
|
|
@@ -822,7 +1015,7 @@ function createOpenAPIPlugin() {
|
|
|
822
1015
|
}),
|
|
823
1016
|
"routes:discovered": async (routes, ctx) => {
|
|
824
1017
|
for (const key of Object.keys(specs)) delete specs[key];
|
|
825
|
-
const nextRoutes =
|
|
1018
|
+
const nextRoutes = createConfiguredOpenAPIRoutes(routes, ctx.projectConfig);
|
|
826
1019
|
const specByFilePath = /* @__PURE__ */ new Map();
|
|
827
1020
|
for (const route of nextRoutes.filter((route) => route.kind === "openapi")) {
|
|
828
1021
|
const specFromCache = specByFilePath.get(route.filePath);
|
|
@@ -853,7 +1046,7 @@ function createOpenAPIPlugin() {
|
|
|
853
1046
|
return nextRoutes;
|
|
854
1047
|
},
|
|
855
1048
|
"modules:before": (modules, ctx) => {
|
|
856
|
-
modules.set(openApiRegistryModuleId, generateOpenAPIRegistryModule(Object.fromEntries(Object.entries(specs).map(([moduleId, entry]) => [moduleId, entry.spec]))));
|
|
1049
|
+
modules.set(openApiRegistryModuleId, generateOpenAPIRegistryModule(Object.fromEntries(Object.entries(specs).map(([moduleId, entry]) => [moduleId, entry.spec])), modules.get(openApiRegistryModuleId)));
|
|
857
1050
|
for (const [moduleId, entry] of Object.entries(specs)) modules.set(moduleId, generateOpenAPIModule(entry.spec, entry.tagFilter));
|
|
858
1051
|
for (const route of ctx.routes.filter((route) => route.kind === "openapi" && route.diagnostic)) if (route.diagnostic) modules.set(route.virtualModuleId, generateOpenAPIErrorModule(route.diagnostic));
|
|
859
1052
|
return modules;
|
|
@@ -862,6 +1055,180 @@ function createOpenAPIPlugin() {
|
|
|
862
1055
|
};
|
|
863
1056
|
}
|
|
864
1057
|
//#endregion
|
|
1058
|
+
//#region source/core/search-language.ts
|
|
1059
|
+
function toPagefindLanguage(locale) {
|
|
1060
|
+
return locale?.trim().replace(/_/g, "-").split("-").filter(Boolean).join("-").toLowerCase() || "en";
|
|
1061
|
+
}
|
|
1062
|
+
//#endregion
|
|
1063
|
+
//#region source/core/temp-dir.ts
|
|
1064
|
+
function createClarifyTempDir(name) {
|
|
1065
|
+
return mkdtempSync(join(tmpdir(), `clarify-${name}-`));
|
|
1066
|
+
}
|
|
1067
|
+
function removeClarifyTempDir(path) {
|
|
1068
|
+
if (!path) return;
|
|
1069
|
+
rmSync(path, {
|
|
1070
|
+
recursive: true,
|
|
1071
|
+
force: true
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
//#endregion
|
|
1075
|
+
//#region source/plugins/search-index/index.ts
|
|
1076
|
+
var pagefindContentTypes = {
|
|
1077
|
+
".css": "text/css; charset=utf-8",
|
|
1078
|
+
".js": "text/javascript; charset=utf-8",
|
|
1079
|
+
".json": "application/json; charset=utf-8",
|
|
1080
|
+
".wasm": "application/wasm"
|
|
1081
|
+
};
|
|
1082
|
+
function assertNoPagefindErrors(action, errors) {
|
|
1083
|
+
if (!errors?.length) return;
|
|
1084
|
+
throw new Error(`[clarify] Pagefind ${action} failed:\n${errors.join("\n")}`);
|
|
1085
|
+
}
|
|
1086
|
+
async function generatePagefindIndex(options) {
|
|
1087
|
+
const pagefind = await import("pagefind");
|
|
1088
|
+
const { errors, index } = await pagefind.createIndex({
|
|
1089
|
+
excludeSelectors: [
|
|
1090
|
+
"[data-pagefind-ignore]",
|
|
1091
|
+
"script",
|
|
1092
|
+
"style",
|
|
1093
|
+
"svg"
|
|
1094
|
+
],
|
|
1095
|
+
includeCharacters: "._-/#:@",
|
|
1096
|
+
keepIndexUrl: false,
|
|
1097
|
+
verbose: false,
|
|
1098
|
+
writePlayground: false
|
|
1099
|
+
});
|
|
1100
|
+
assertNoPagefindErrors("createIndex", errors);
|
|
1101
|
+
if (!index) throw new Error("[clarify] Pagefind did not create an index.");
|
|
1102
|
+
try {
|
|
1103
|
+
const addResult = await index.addDirectory({
|
|
1104
|
+
path: options.sourceRoot ?? options.outputRoot,
|
|
1105
|
+
glob: "**/*.html"
|
|
1106
|
+
});
|
|
1107
|
+
assertNoPagefindErrors("addDirectory", addResult.errors);
|
|
1108
|
+
assertNoPagefindErrors("writeFiles", (await index.writeFiles({ outputPath: join(options.outputRoot, "pagefind") })).errors);
|
|
1109
|
+
return addResult.page_count;
|
|
1110
|
+
} finally {
|
|
1111
|
+
await index.deleteIndex();
|
|
1112
|
+
await pagefind.close();
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function routeSearchContent(route) {
|
|
1116
|
+
return [
|
|
1117
|
+
route.title,
|
|
1118
|
+
route.description,
|
|
1119
|
+
route.keywords?.join(" "),
|
|
1120
|
+
route.sections?.map((section) => section.title).join(" "),
|
|
1121
|
+
route.content
|
|
1122
|
+
].filter(Boolean).join("\n\n");
|
|
1123
|
+
}
|
|
1124
|
+
async function generateDevSearchIndex(ctx, root) {
|
|
1125
|
+
const pagefind = await import("pagefind");
|
|
1126
|
+
const { errors, index } = await pagefind.createIndex({
|
|
1127
|
+
includeCharacters: "._-/#:@",
|
|
1128
|
+
keepIndexUrl: false,
|
|
1129
|
+
verbose: false,
|
|
1130
|
+
writePlayground: false
|
|
1131
|
+
});
|
|
1132
|
+
assertNoPagefindErrors("createIndex", errors);
|
|
1133
|
+
if (!index) throw new Error("[clarify] Pagefind did not create an index.");
|
|
1134
|
+
try {
|
|
1135
|
+
let pageCount = 0;
|
|
1136
|
+
for (const route of ctx.routes) {
|
|
1137
|
+
const content = routeSearchContent(route);
|
|
1138
|
+
if (!content.trim()) continue;
|
|
1139
|
+
const result = await index.addCustomRecord({
|
|
1140
|
+
url: route.path,
|
|
1141
|
+
content,
|
|
1142
|
+
language: toPagefindLanguage(route.locale ?? ctx.projectConfig.i18n?.defaultLocale),
|
|
1143
|
+
meta: { title: route.title }
|
|
1144
|
+
});
|
|
1145
|
+
assertNoPagefindErrors(`addCustomRecord ${route.path}`, result.errors);
|
|
1146
|
+
pageCount += 1;
|
|
1147
|
+
}
|
|
1148
|
+
assertNoPagefindErrors("writeFiles", (await index.writeFiles({ outputPath: join(root, "pagefind") })).errors);
|
|
1149
|
+
console.log(`[clarify] Dev search index generated for ${pageCount} pages.`);
|
|
1150
|
+
} finally {
|
|
1151
|
+
await index.deleteIndex();
|
|
1152
|
+
await pagefind.close();
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
function normalizeDevPagefindPath(rawUrl, routePrefix) {
|
|
1156
|
+
const pathname = rawUrl?.split("?")[0];
|
|
1157
|
+
if (!pathname) return void 0;
|
|
1158
|
+
const normalizedPrefix = routePrefix && routePrefix !== "/" ? `/${routePrefix.replace(/^\/+|\/+$/g, "")}` : "";
|
|
1159
|
+
const pagefindPath = normalizedPrefix && pathname.startsWith(`${normalizedPrefix}/pagefind/`) ? pathname.slice(normalizedPrefix.length) : pathname;
|
|
1160
|
+
return pagefindPath.startsWith("/pagefind/") ? pagefindPath : void 0;
|
|
1161
|
+
}
|
|
1162
|
+
function serveDevPagefind(server, getRoot, ctx) {
|
|
1163
|
+
server.middlewares.use((req, res, next) => {
|
|
1164
|
+
const root = getRoot();
|
|
1165
|
+
const pagefindPath = normalizeDevPagefindPath(req.url, ctx.projectConfig.routePrefix);
|
|
1166
|
+
if (!root || !pagefindPath) {
|
|
1167
|
+
next();
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
const filePath = join(root, pagefindPath);
|
|
1171
|
+
const relativePath = relative(root, filePath);
|
|
1172
|
+
if (relativePath.startsWith("..") || relativePath === "" || !existsSync(filePath)) {
|
|
1173
|
+
next();
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
const contentType = pagefindContentTypes[extname(filePath)] ?? "application/octet-stream";
|
|
1177
|
+
res.setHeader("Content-Type", contentType);
|
|
1178
|
+
createReadStream(filePath).pipe(res);
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
function createSearchIndexPlugin() {
|
|
1182
|
+
return {
|
|
1183
|
+
name: "clarify:search-index",
|
|
1184
|
+
hooks: {
|
|
1185
|
+
async "dev:configureServer"(server, ctx) {
|
|
1186
|
+
let currentRoot;
|
|
1187
|
+
const staleRoots = /* @__PURE__ */ new Set();
|
|
1188
|
+
const replaceDevIndex = async () => {
|
|
1189
|
+
const nextRoot = createClarifyTempDir("pagefind");
|
|
1190
|
+
await generateDevSearchIndex(ctx, nextRoot);
|
|
1191
|
+
const previousRoot = currentRoot;
|
|
1192
|
+
currentRoot = nextRoot;
|
|
1193
|
+
if (previousRoot) {
|
|
1194
|
+
staleRoots.add(previousRoot);
|
|
1195
|
+
setTimeout(() => {
|
|
1196
|
+
staleRoots.delete(previousRoot);
|
|
1197
|
+
removeClarifyTempDir(previousRoot);
|
|
1198
|
+
}, 3e4).unref?.();
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
serveDevPagefind(server, () => currentRoot, ctx);
|
|
1202
|
+
await replaceDevIndex();
|
|
1203
|
+
let regenerateTimer;
|
|
1204
|
+
const regenerate = (filePath) => {
|
|
1205
|
+
if (!/\.(md|mdx|json|ya?ml)$/i.test(filePath)) return;
|
|
1206
|
+
if (regenerateTimer) clearTimeout(regenerateTimer);
|
|
1207
|
+
regenerateTimer = setTimeout(() => {
|
|
1208
|
+
replaceDevIndex().catch((err) => {
|
|
1209
|
+
console.error("[clarify] Failed to regenerate dev search index:", err);
|
|
1210
|
+
});
|
|
1211
|
+
}, 100);
|
|
1212
|
+
};
|
|
1213
|
+
server.watcher.on("add", regenerate);
|
|
1214
|
+
server.watcher.on("change", regenerate);
|
|
1215
|
+
server.watcher.on("unlink", regenerate);
|
|
1216
|
+
server.httpServer?.once("close", () => {
|
|
1217
|
+
if (regenerateTimer) clearTimeout(regenerateTimer);
|
|
1218
|
+
removeClarifyTempDir(currentRoot);
|
|
1219
|
+
for (const staleRoot of staleRoots) removeClarifyTempDir(staleRoot);
|
|
1220
|
+
});
|
|
1221
|
+
},
|
|
1222
|
+
async "build:done"(ctx) {
|
|
1223
|
+
const outputDirectory = ctx.generateOptions.outputDirectory;
|
|
1224
|
+
if (!outputDirectory) return;
|
|
1225
|
+
const pageCount = await generatePagefindIndex({ outputRoot: resolve(ctx.generateOptions.projectRoot, outputDirectory) });
|
|
1226
|
+
console.log(`[clarify] Search index generated for ${pageCount} pages.`);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
//#endregion
|
|
865
1232
|
//#region source/plugins/seo/artifacts.ts
|
|
866
1233
|
function trimTrailingSlash(value) {
|
|
867
1234
|
return value.replace(/\/+$/, "");
|
|
@@ -957,7 +1324,8 @@ function createBuiltinPlugins(options = {}) {
|
|
|
957
1324
|
createOpenAPIPlugin(),
|
|
958
1325
|
createSourceLinksPlugin(),
|
|
959
1326
|
createContentArtifactsPlugin(),
|
|
960
|
-
createSeoPlugin()
|
|
1327
|
+
createSeoPlugin(),
|
|
1328
|
+
createSearchIndexPlugin()
|
|
961
1329
|
];
|
|
962
1330
|
if (options.htmlShell ?? true) plugins.push(createHtmlShellPlugin());
|
|
963
1331
|
return plugins;
|
|
@@ -1015,11 +1383,12 @@ var clarifyBannerConfigSchema = z.object({
|
|
|
1015
1383
|
content: clarifyLocalizedTextSchema,
|
|
1016
1384
|
dismissible: z.boolean().optional()
|
|
1017
1385
|
});
|
|
1018
|
-
var
|
|
1386
|
+
var clarifyFooterLinksConfigSchema = z.object({
|
|
1019
1387
|
links: z.array(clarifyNavbarLinkSchema).optional(),
|
|
1020
1388
|
socials: z.record(z.string(), z.string()).optional(),
|
|
1021
1389
|
copyright: clarifyLocalizedTextSchema.optional()
|
|
1022
|
-
});
|
|
1390
|
+
}).strict();
|
|
1391
|
+
var clarifyFooterConfigSchema = z.union([clarifyFooterLinksConfigSchema, z.string()]);
|
|
1023
1392
|
var clarifySourceConfigSchema = z.object({
|
|
1024
1393
|
repository: z.string(),
|
|
1025
1394
|
branch: z.string().optional(),
|
|
@@ -1029,12 +1398,14 @@ var clarifyPagesItemSchema = z.union([
|
|
|
1029
1398
|
z.string(),
|
|
1030
1399
|
z.object({
|
|
1031
1400
|
page: z.string(),
|
|
1401
|
+
path: z.string().optional(),
|
|
1032
1402
|
title: clarifyLocalizedTextSchema.optional(),
|
|
1033
1403
|
icon: z.string().optional(),
|
|
1034
1404
|
redirect: z.string().optional()
|
|
1035
1405
|
}),
|
|
1036
1406
|
z.object({
|
|
1037
1407
|
openapi: z.string(),
|
|
1408
|
+
path: z.string().optional(),
|
|
1038
1409
|
icon: z.string().optional(),
|
|
1039
1410
|
title: clarifyLocalizedTextSchema.optional(),
|
|
1040
1411
|
filter: z.object({ tags: z.array(z.string()).optional() }).optional()
|
|
@@ -1101,78 +1472,6 @@ var clarifyProjectConfigSchema = z.object({
|
|
|
1101
1472
|
tabs: clarifyTabsConfigSchema.optional()
|
|
1102
1473
|
});
|
|
1103
1474
|
//#endregion
|
|
1104
|
-
//#region source/core/theme.ts
|
|
1105
|
-
var clarifyThemePresets = {
|
|
1106
|
-
default: {
|
|
1107
|
-
preset: "default",
|
|
1108
|
-
tokens: {
|
|
1109
|
-
colors: {
|
|
1110
|
-
primary: "#047857",
|
|
1111
|
-
accent: "#0D9488",
|
|
1112
|
-
background: "#ffffff",
|
|
1113
|
-
foreground: "#111827",
|
|
1114
|
-
surface: "#ffffff",
|
|
1115
|
-
muted: "#64748b",
|
|
1116
|
-
border: "rgb(15 23 42 / 0.12)",
|
|
1117
|
-
codeBackground: "#f6fbf8"
|
|
1118
|
-
},
|
|
1119
|
-
radius: {
|
|
1120
|
-
sm: "6px",
|
|
1121
|
-
md: "10px",
|
|
1122
|
-
lg: "14px",
|
|
1123
|
-
xl: "18px"
|
|
1124
|
-
}
|
|
1125
|
-
},
|
|
1126
|
-
layout: { maxWidth: "82rem" },
|
|
1127
|
-
editor: false
|
|
1128
|
-
},
|
|
1129
|
-
base: {
|
|
1130
|
-
preset: "base",
|
|
1131
|
-
tokens: {
|
|
1132
|
-
colors: {
|
|
1133
|
-
primary: "#18181b",
|
|
1134
|
-
accent: "#52525b",
|
|
1135
|
-
background: "#ffffff",
|
|
1136
|
-
foreground: "#18181b",
|
|
1137
|
-
surface: "#ffffff",
|
|
1138
|
-
muted: "#71717a",
|
|
1139
|
-
border: "rgb(24 24 27 / 0.12)",
|
|
1140
|
-
codeBackground: "#f4f4f5"
|
|
1141
|
-
},
|
|
1142
|
-
radius: {
|
|
1143
|
-
sm: "6px",
|
|
1144
|
-
md: "8px",
|
|
1145
|
-
lg: "12px",
|
|
1146
|
-
xl: "16px"
|
|
1147
|
-
}
|
|
1148
|
-
},
|
|
1149
|
-
layout: { maxWidth: "80rem" },
|
|
1150
|
-
editor: false
|
|
1151
|
-
}
|
|
1152
|
-
};
|
|
1153
|
-
function resolveThemeConfig(theme = {}) {
|
|
1154
|
-
const preset = theme.preset ?? "default";
|
|
1155
|
-
const presetTheme = clarifyThemePresets[preset];
|
|
1156
|
-
return {
|
|
1157
|
-
preset,
|
|
1158
|
-
tokens: {
|
|
1159
|
-
colors: {
|
|
1160
|
-
...presetTheme.tokens.colors,
|
|
1161
|
-
...theme.tokens?.colors
|
|
1162
|
-
},
|
|
1163
|
-
radius: {
|
|
1164
|
-
...presetTheme.tokens.radius,
|
|
1165
|
-
...theme.tokens?.radius
|
|
1166
|
-
}
|
|
1167
|
-
},
|
|
1168
|
-
layout: {
|
|
1169
|
-
...presetTheme.layout,
|
|
1170
|
-
...theme.layout
|
|
1171
|
-
},
|
|
1172
|
-
editor: theme.editor ?? presetTheme.editor
|
|
1173
|
-
};
|
|
1174
|
-
}
|
|
1175
|
-
//#endregion
|
|
1176
1475
|
//#region source/core/config.ts
|
|
1177
1476
|
function formatIssuePath(path) {
|
|
1178
1477
|
return path.reduce((result, segment) => {
|
|
@@ -1339,6 +1638,7 @@ async function resolveClarifySite(options = {}, resolveOptions = {}) {
|
|
|
1339
1638
|
};
|
|
1340
1639
|
let routes = await discoverRoutes(root, contentRoot, plugins, ctx);
|
|
1341
1640
|
routes = await runHooks(plugins, "routes:discovered", routes, ctx);
|
|
1641
|
+
routes = applyConfiguredPageRoutePaths(routes, projectConfig.tabs, projectConfig.i18n);
|
|
1342
1642
|
const defaultNavigation = projectConfig.tabs ? projectConfig.i18n ? buildLocalizedNavigationFromTabsConfig(routes, projectConfig.tabs, projectConfig.i18n) ?? {} : buildNavigationFromTabsConfig(routes, projectConfig.tabs) : buildNavigation(routes);
|
|
1343
1643
|
const resolved = await runHooks(plugins, "routes:resolved", {
|
|
1344
1644
|
routes,
|
|
@@ -1465,13 +1765,13 @@ function routeOutputFiles(outputDirectory, route) {
|
|
|
1465
1765
|
var SSR_ENTRY_CODE = `import { renderToHTML } from '@clarify-labs/renderer/server';
|
|
1466
1766
|
import { routes, navigation } from 'virtual:clarify-routes/server';
|
|
1467
1767
|
import { config } from 'virtual:clarify-config';
|
|
1468
|
-
import { openApis } from 'virtual:clarify-runtime';
|
|
1768
|
+
import { openApis, footerComponent } from 'virtual:clarify-runtime';
|
|
1469
1769
|
|
|
1470
1770
|
export function render(url) {
|
|
1471
|
-
return renderToHTML({ config, routes, navigation, openApis, url, themeEditor: config.theme.editor });
|
|
1771
|
+
return renderToHTML({ config, routes, navigation, openApis, footerComponent, url, themeEditor: config.theme.editor });
|
|
1472
1772
|
}`;
|
|
1473
1773
|
function createTempEntryFile(content) {
|
|
1474
|
-
const entryPath = join(
|
|
1774
|
+
const entryPath = join(createClarifyTempDir("ssr"), "entry-server.ts");
|
|
1475
1775
|
writeFileSync(entryPath, content, "utf-8");
|
|
1476
1776
|
return entryPath;
|
|
1477
1777
|
}
|
|
@@ -1511,6 +1811,7 @@ async function renderSSGRoutes(routes, projectConfig, outputDirectory, ssrBundle
|
|
|
1511
1811
|
//#endregion
|
|
1512
1812
|
//#region source/core/user-config.ts
|
|
1513
1813
|
function defineConfig(config) {
|
|
1814
|
+
validateProjectConfig(config);
|
|
1514
1815
|
return config;
|
|
1515
1816
|
}
|
|
1516
1817
|
var CONFIG_FILENAMES = [
|
|
@@ -1761,6 +2062,6 @@ function clarifyPlugin(options = {}) {
|
|
|
1761
2062
|
].flat().filter(Boolean);
|
|
1762
2063
|
}
|
|
1763
2064
|
//#endregion
|
|
1764
|
-
export { resolveClarifySite as a, createClarifyRuntimeAliases as i, defineConfig as n, loadClarifyConfig as r, clarifyPlugin as t };
|
|
2065
|
+
export { resolveClarifySite as a, createClarifyRuntimeAliases as i, defineConfig as n, createClarifyTempDir as o, loadClarifyConfig as r, clarifyPlugin as t };
|
|
1765
2066
|
|
|
1766
|
-
//# sourceMappingURL=plugin-
|
|
2067
|
+
//# sourceMappingURL=plugin-BNzlJ4o7.js.map
|