blume 0.6.7 → 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/dist/cli/index.js +1179 -738
- package/dist/cli/index.js.map +52 -51
- package/dist/types/core/base-path.d.ts +38 -0
- package/dist/types/core/config-input.d.ts +74 -10
- package/dist/types/core/config.d.ts +3 -2
- package/dist/types/core/data.d.ts +2 -0
- package/dist/types/core/i18n-ui.d.ts +1 -3
- package/dist/types/core/schema.d.ts +95 -52
- package/dist/types/core/sources/types.d.ts +2 -0
- package/dist/types/core/types.d.ts +6 -1
- package/docs/02-deployment.mdx +16 -1
- package/docs/03-faq.mdx +8 -8
- package/docs/configuration/index.mdx +6 -0
- package/docs/content/components.mdx +29 -2
- package/docs/content/islands.mdx +8 -0
- package/docs/content/syntax.mdx +13 -0
- package/package.json +2 -1
- package/src/ai/agent-readability.ts +7 -2
- package/src/ai/ask.ts +12 -7
- package/src/ai/llms.ts +15 -4
- package/src/ai/mcp/data.ts +8 -4
- package/src/ai/mcp/server.ts +3 -0
- package/src/astro/component-slots.ts +5 -3
- package/src/astro/examples.ts +12 -7
- package/src/astro/generate.ts +317 -144
- package/src/astro/index.ts +5 -1
- package/src/astro/integration.ts +8 -4
- package/src/astro/islands.ts +11 -5
- package/src/astro/markdown-negotiation.ts +1 -1
- package/src/astro/pages.ts +8 -3
- package/src/astro/templates.ts +166 -19
- package/src/cli/commands/build.ts +32 -19
- package/src/cli/commands/dev.ts +48 -15
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/validate.ts +1 -0
- package/src/cli/dev-lock.ts +26 -15
- package/src/cli/required-secrets.ts +2 -1
- package/src/components/content/CodeBlock.astro +3 -0
- package/src/components/content/Component.astro +30 -16
- package/src/components/content/Diff.astro +3 -1
- package/src/components/content/auto-type-table.ts +18 -8
- package/src/components/content/diff.ts +12 -6
- package/src/components/content/mermaid-element.ts +3 -0
- package/src/components/index.ts +23 -1
- package/src/components/islands/ask-ai.tsx +12 -6
- package/src/components/islands/base-path.ts +28 -0
- package/src/components/islands/hooks.ts +16 -1
- package/src/components/layout/Banner.astro +2 -1
- package/src/components/layout/Breadcrumbs.astro +2 -1
- package/src/components/layout/Favicon.astro +3 -2
- package/src/components/layout/Header.astro +2 -1
- package/src/components/layout/LanguageSwitcher.astro +2 -1
- package/src/components/layout/Logo.astro +2 -1
- package/src/components/layout/NavSelector.astro +2 -1
- package/src/components/layout/NavTree.astro +5 -4
- package/src/components/layout/PageFeedback.astro +4 -1
- package/src/components/layout/PageLayout.astro +9 -4
- package/src/components/layout/Pagination.astro +3 -2
- package/src/components/layout/RootLayout.astro +7 -4
- package/src/components/layout/Search.astro +13 -5
- package/src/components/layout/nav-utils.ts +18 -10
- package/src/components/layout/search/pagefind.ts +3 -0
- package/src/components/layout/toc-element.ts +7 -1
- package/src/components/openapi/RequestPanel.astro +7 -1
- package/src/components/openapi/snippets.ts +25 -11
- package/src/core/base-path.ts +70 -0
- package/src/core/component-overrides.ts +103 -74
- package/src/core/config-input.ts +81 -15
- package/src/core/config.ts +5 -3
- package/src/core/content.ts +2 -0
- package/src/core/data.ts +2 -0
- package/src/core/diagnostics.ts +54 -34
- package/src/core/gitignore.ts +4 -1
- package/src/core/graph.ts +156 -88
- package/src/core/i18n-ui.ts +18 -3
- package/src/core/last-modified.ts +2 -0
- package/src/core/links.ts +38 -18
- package/src/core/manifest.ts +62 -45
- package/src/core/nav-diagnostics.ts +1 -1
- package/src/core/navigation.ts +116 -55
- package/src/core/project-graph.ts +10 -9
- package/src/core/schema.ts +572 -621
- package/src/core/sources/github-releases.ts +2 -1
- package/src/core/sources/mdx-remote.ts +58 -54
- package/src/core/sources/normalize.ts +116 -73
- package/src/core/sources/notion.ts +19 -10
- package/src/core/sources/types.ts +2 -0
- package/src/core/tsconfig-aliases.ts +59 -30
- package/src/core/types.ts +6 -1
- package/src/deploy/redirects.ts +18 -0
- package/src/deploy/robots.ts +6 -1
- package/src/deploy/rss.ts +10 -3
- package/src/deploy/sitemap.ts +14 -10
- package/src/markdown/base-links.ts +58 -0
- package/src/markdown/code-title.ts +11 -14
- package/src/markdown/index.ts +34 -9
- package/src/markdown/inline-code.ts +7 -2
- package/src/markdown/themes.ts +24 -0
- package/src/openapi/model.ts +3 -1
- package/src/openapi/references.ts +41 -17
- package/src/openapi/render-mdx.ts +11 -6
- package/src/openapi/scalar.ts +32 -16
- package/src/registry/eject.ts +64 -8
- package/src/search/build.ts +3 -0
- package/src/search/documents.ts +2 -2
- package/src/search/sync/typesense.ts +6 -4
- package/src/seo/jsonld.ts +16 -6
- package/src/theme/entry.ts +85 -20
package/dist/cli/index.js
CHANGED
|
@@ -293,34 +293,38 @@ class BlumeError extends Error {
|
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
var DOCS_BASE = "https://useblume.dev";
|
|
296
|
+
var DOCS_DEPLOYMENT = "/docs/deployment";
|
|
297
|
+
var DOCS_REFERENCE_CLI = "/docs/reference/cli";
|
|
298
|
+
var DOCS_CONTENT_SOURCES = "/docs/content/sources";
|
|
299
|
+
var DOCS_CONTENT_NAVIGATION = "/docs/content/navigation";
|
|
296
300
|
var DOCS_PATHS = {
|
|
297
|
-
BLUME_ADAPTER_REQUIRED:
|
|
298
|
-
BLUME_ASSETS_UNCHECKED:
|
|
299
|
-
BLUME_ASSET_FETCH_FAILED:
|
|
300
|
-
BLUME_BROKEN_ANCHOR:
|
|
301
|
-
BLUME_BROKEN_ASSET:
|
|
302
|
-
BLUME_BROKEN_LINK:
|
|
301
|
+
BLUME_ADAPTER_REQUIRED: DOCS_DEPLOYMENT,
|
|
302
|
+
BLUME_ASSETS_UNCHECKED: DOCS_REFERENCE_CLI,
|
|
303
|
+
BLUME_ASSET_FETCH_FAILED: DOCS_CONTENT_SOURCES,
|
|
304
|
+
BLUME_BROKEN_ANCHOR: DOCS_REFERENCE_CLI,
|
|
305
|
+
BLUME_BROKEN_ASSET: DOCS_REFERENCE_CLI,
|
|
306
|
+
BLUME_BROKEN_LINK: DOCS_REFERENCE_CLI,
|
|
303
307
|
BLUME_CONFIG_INVALID: "/docs/configuration",
|
|
304
308
|
BLUME_CONFIG_LOAD_FAILED: "/docs/configuration",
|
|
305
|
-
BLUME_CONTENT_ROOT_MISSING:
|
|
306
|
-
BLUME_DEAD_LINK:
|
|
307
|
-
BLUME_DUPLICATE_ROUTE:
|
|
309
|
+
BLUME_CONTENT_ROOT_MISSING: DOCS_CONTENT_SOURCES,
|
|
310
|
+
BLUME_DEAD_LINK: DOCS_REFERENCE_CLI,
|
|
311
|
+
BLUME_DUPLICATE_ROUTE: DOCS_CONTENT_NAVIGATION,
|
|
308
312
|
BLUME_FRONTMATTER_INVALID: "/docs/reference/frontmatter",
|
|
309
313
|
BLUME_META_INVALID: "/docs/content/meta",
|
|
310
314
|
BLUME_META_LOAD_FAILED: "/docs/content/meta",
|
|
311
|
-
BLUME_MISSING_SECRET:
|
|
312
|
-
BLUME_NAV_DUPLICATE_LABEL:
|
|
313
|
-
BLUME_NAV_HIDDEN_IN_SIDEBAR:
|
|
314
|
-
BLUME_NAV_MISSING_PAGE:
|
|
315
|
+
BLUME_MISSING_SECRET: DOCS_DEPLOYMENT,
|
|
316
|
+
BLUME_NAV_DUPLICATE_LABEL: DOCS_CONTENT_NAVIGATION,
|
|
317
|
+
BLUME_NAV_HIDDEN_IN_SIDEBAR: DOCS_CONTENT_NAVIGATION,
|
|
318
|
+
BLUME_NAV_MISSING_PAGE: DOCS_CONTENT_NAVIGATION,
|
|
315
319
|
BLUME_NODE_VERSION: "/docs/quickstart",
|
|
316
|
-
BLUME_SERVER_FEATURE_REQUIRED:
|
|
317
|
-
BLUME_SOURCE_FETCH_FAILED:
|
|
318
|
-
BLUME_SOURCE_MISCONFIGURED:
|
|
319
|
-
BLUME_SOURCE_OFFLINE:
|
|
320
|
-
BLUME_SOURCE_SDK_MISSING:
|
|
321
|
-
BLUME_SOURCE_UNAVAILABLE:
|
|
320
|
+
BLUME_SERVER_FEATURE_REQUIRED: DOCS_DEPLOYMENT,
|
|
321
|
+
BLUME_SOURCE_FETCH_FAILED: DOCS_CONTENT_SOURCES,
|
|
322
|
+
BLUME_SOURCE_MISCONFIGURED: DOCS_CONTENT_SOURCES,
|
|
323
|
+
BLUME_SOURCE_OFFLINE: DOCS_CONTENT_SOURCES,
|
|
324
|
+
BLUME_SOURCE_SDK_MISSING: DOCS_CONTENT_SOURCES,
|
|
325
|
+
BLUME_SOURCE_UNAVAILABLE: DOCS_CONTENT_SOURCES,
|
|
322
326
|
BLUME_UNKNOWN_COMPONENT: "/docs/configuration/customization",
|
|
323
|
-
BLUME_UNKNOWN_ICON:
|
|
327
|
+
BLUME_UNKNOWN_ICON: DOCS_CONTENT_NAVIGATION
|
|
324
328
|
};
|
|
325
329
|
var resolveDocsUrl = (code) => {
|
|
326
330
|
const path = DOCS_PATHS[code];
|
|
@@ -329,21 +333,30 @@ var resolveDocsUrl = (code) => {
|
|
|
329
333
|
var enrichDiagnostic = (diagnostic) => diagnostic.docsUrl ? diagnostic : { ...diagnostic, docsUrl: resolveDocsUrl(diagnostic.code) };
|
|
330
334
|
var REGEXP_SPECIAL = /[$()*+.?[\\\]^{|}]/gu;
|
|
331
335
|
var escapeRegExp = (value) => value.replaceAll(REGEXP_SPECIAL, String.raw`\$&`);
|
|
336
|
+
var stepSegment = (source, segment, cursor) => {
|
|
337
|
+
if (typeof segment !== "string") {
|
|
338
|
+
return { index: -1, next: cursor, stop: false };
|
|
339
|
+
}
|
|
340
|
+
const matcher = new RegExp(`(?<![\\w$])${escapeRegExp(segment)}\\s*[:=]`, "gu");
|
|
341
|
+
matcher.lastIndex = cursor;
|
|
342
|
+
const match = matcher.exec(source);
|
|
343
|
+
if (!match) {
|
|
344
|
+
return { index: -1, next: cursor, stop: true };
|
|
345
|
+
}
|
|
346
|
+
return { index: match.index, next: matcher.lastIndex, stop: false };
|
|
347
|
+
};
|
|
332
348
|
var locatePath = (source, path) => {
|
|
333
349
|
let cursor = 0;
|
|
334
350
|
let found = -1;
|
|
335
351
|
for (const segment of path) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
const matcher = new RegExp(`(?<![\\w$])${escapeRegExp(segment)}\\s*[:=]`, "gu");
|
|
340
|
-
matcher.lastIndex = cursor;
|
|
341
|
-
const match = matcher.exec(source);
|
|
342
|
-
if (!match) {
|
|
352
|
+
const step = stepSegment(source, segment, cursor);
|
|
353
|
+
if (step.stop) {
|
|
343
354
|
break;
|
|
344
355
|
}
|
|
345
|
-
|
|
346
|
-
|
|
356
|
+
cursor = step.next;
|
|
357
|
+
if (step.index >= 0) {
|
|
358
|
+
found = step.index;
|
|
359
|
+
}
|
|
347
360
|
}
|
|
348
361
|
if (found < 0) {
|
|
349
362
|
return;
|
|
@@ -519,6 +532,34 @@ import { build } from "astro";
|
|
|
519
532
|
import { defineCommand as defineCommand2 } from "citty";
|
|
520
533
|
import { join as join24 } from "pathe";
|
|
521
534
|
|
|
535
|
+
// src/core/base-path.ts
|
|
536
|
+
var normalizeBasePath = (input) => {
|
|
537
|
+
if (!input) {
|
|
538
|
+
return "";
|
|
539
|
+
}
|
|
540
|
+
const trimmed = input.trim().replaceAll(/^\/+|\/+$/gu, "").replaceAll(/\/{2,}/gu, "/");
|
|
541
|
+
return trimmed === "" ? "" : `/${trimmed}`;
|
|
542
|
+
};
|
|
543
|
+
var isInternalPath = (target) => target.startsWith("/") && !target.startsWith("//");
|
|
544
|
+
var withBasePath = (basePath, route) => {
|
|
545
|
+
if (!basePath || !isInternalPath(route)) {
|
|
546
|
+
return route;
|
|
547
|
+
}
|
|
548
|
+
if (route === basePath || route.startsWith(`${basePath}/`)) {
|
|
549
|
+
return route;
|
|
550
|
+
}
|
|
551
|
+
return route === "/" ? basePath : `${basePath}${route}`;
|
|
552
|
+
};
|
|
553
|
+
var stripBasePath = (basePath, route) => {
|
|
554
|
+
if (!basePath) {
|
|
555
|
+
return route;
|
|
556
|
+
}
|
|
557
|
+
if (route === basePath) {
|
|
558
|
+
return "/";
|
|
559
|
+
}
|
|
560
|
+
return route.startsWith(`${basePath}/`) ? route.slice(basePath.length) : route;
|
|
561
|
+
};
|
|
562
|
+
|
|
522
563
|
// src/deploy/xml.ts
|
|
523
564
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
524
565
|
|
|
@@ -540,6 +581,8 @@ var buildRssFeeds = (project) => {
|
|
|
540
581
|
return [];
|
|
541
582
|
}
|
|
542
583
|
const base = site.replace(/\/$/u, "");
|
|
584
|
+
const deployBase = normalizeBasePath(config.deployment.base);
|
|
585
|
+
const rootLink = `${base}${deployBase}`;
|
|
543
586
|
const feeds = [];
|
|
544
587
|
for (const type of rss.types) {
|
|
545
588
|
const pages = project.graph.pages.filter((page) => page.contentType === type && !(page.meta.draft || page.meta.sidebar.hidden));
|
|
@@ -549,13 +592,13 @@ var buildRssFeeds = (project) => {
|
|
|
549
592
|
const items = pages.map((page) => ({
|
|
550
593
|
date: pageDate(page),
|
|
551
594
|
description: page.description,
|
|
552
|
-
link: encodeURI(`${base}${page.route}`),
|
|
595
|
+
link: encodeURI(`${base}${withBasePath(deployBase, page.route)}`),
|
|
553
596
|
title: page.title
|
|
554
597
|
})).toSorted((a, b) => (b.date?.getTime() ?? 0) - (a.date?.getTime() ?? 0)).slice(0, rss.limit);
|
|
555
598
|
feeds.push({
|
|
556
599
|
description: config.description,
|
|
557
600
|
items,
|
|
558
|
-
link:
|
|
601
|
+
link: rootLink,
|
|
559
602
|
path: `/${type}/rss.xml`,
|
|
560
603
|
title: `${config.title} — ${capitalize(type)}`,
|
|
561
604
|
type
|
|
@@ -581,11 +624,12 @@ ${parts.join(`
|
|
|
581
624
|
</item>`;
|
|
582
625
|
};
|
|
583
626
|
var renderRssFeed = (feed) => {
|
|
627
|
+
const feedSelfHref = `${feed.link}${feed.path}`;
|
|
584
628
|
const channel = [
|
|
585
629
|
` <title>${escapeXml(feed.title)}</title>`,
|
|
586
630
|
` <link>${escapeXml(feed.link)}</link>`,
|
|
587
631
|
` <description>${escapeXml(feed.description ?? feed.title)}</description>`,
|
|
588
|
-
` <atom:link href="${escapeXml(
|
|
632
|
+
` <atom:link href="${escapeXml(feedSelfHref)}" rel="self" type="application/rss+xml" />`
|
|
589
633
|
];
|
|
590
634
|
const items = feed.items.map(renderItem).join(`
|
|
591
635
|
`);
|
|
@@ -618,7 +662,8 @@ var buildAgentReadability = (project) => {
|
|
|
618
662
|
return null;
|
|
619
663
|
}
|
|
620
664
|
const site = config.deployment.site ?? null;
|
|
621
|
-
const
|
|
665
|
+
const deployBase = normalizeBasePath(config.deployment.base);
|
|
666
|
+
const abs = (path) => site ? `${site.replace(/\/+$/u, "")}${withBasePath(deployBase, path)}` : path;
|
|
622
667
|
const artifacts = {
|
|
623
668
|
markdown: {
|
|
624
669
|
contentNegotiation: "text/markdown",
|
|
@@ -700,11 +745,11 @@ var readEntryText = async (ctx, page) => {
|
|
|
700
745
|
};
|
|
701
746
|
|
|
702
747
|
// src/ai/llms.ts
|
|
703
|
-
var pageUrl = (route, site) => {
|
|
748
|
+
var pageUrl = (route, site, base = "") => {
|
|
704
749
|
if (!site) {
|
|
705
750
|
return route;
|
|
706
751
|
}
|
|
707
|
-
return `${site.replace(/\/$/u, "")}${route}`;
|
|
752
|
+
return `${site.replace(/\/$/u, "")}${withBasePath(base, route)}`;
|
|
708
753
|
};
|
|
709
754
|
var orderedPages = (project) => [...project.graph.pages].filter((page) => !page.meta.draft).sort((a, b) => a.route.localeCompare(b.route));
|
|
710
755
|
var buildIndex = (project) => {
|
|
@@ -716,7 +761,7 @@ var buildIndex = (project) => {
|
|
|
716
761
|
}
|
|
717
762
|
lines.push("", "## Docs", "");
|
|
718
763
|
for (const page of orderedPages(project)) {
|
|
719
|
-
const url = pageUrl(page.route, site);
|
|
764
|
+
const url = pageUrl(page.route, site, normalizeBasePath(config.deployment.base));
|
|
720
765
|
const summary = page.description ? `: ${page.description}` : "";
|
|
721
766
|
lines.push(`- [${page.title}](${url})${summary}`);
|
|
722
767
|
}
|
|
@@ -730,7 +775,7 @@ var buildFull = async (project) => {
|
|
|
730
775
|
const sections = await Promise.all(pages.map(async (page) => {
|
|
731
776
|
const raw = await readEntryText(project, page);
|
|
732
777
|
const body = frontmatter_default(raw).content.trim();
|
|
733
|
-
const url = pageUrl(page.route, config.deployment.site);
|
|
778
|
+
const url = pageUrl(page.route, config.deployment.site, normalizeBasePath(config.deployment.base));
|
|
734
779
|
return [`# ${page.title}`, `Source: ${url}`, "", body].join(`
|
|
735
780
|
`);
|
|
736
781
|
}));
|
|
@@ -761,7 +806,10 @@ var ensureGitignore = async (root, entries) => {
|
|
|
761
806
|
const path = join5(root, ".gitignore");
|
|
762
807
|
const existing = existsSync3(path) ? await readFile3(path, "utf-8") : "";
|
|
763
808
|
const present = new Set(existing.split(`
|
|
764
|
-
`).
|
|
809
|
+
`).flatMap((line) => {
|
|
810
|
+
const key = gitignoreKey(line);
|
|
811
|
+
return key ? [key] : [];
|
|
812
|
+
}));
|
|
765
813
|
const added = entries.filter((entry) => !present.has(gitignoreKey(entry)));
|
|
766
814
|
if (added.length === 0) {
|
|
767
815
|
return [];
|
|
@@ -881,6 +929,11 @@ var surfaceAdapterOutput = async (config, context) => {
|
|
|
881
929
|
};
|
|
882
930
|
|
|
883
931
|
// src/deploy/redirects.ts
|
|
932
|
+
var applyBaseToRedirects = (redirects, basePath) => basePath ? redirects.map((redirect) => ({
|
|
933
|
+
...redirect,
|
|
934
|
+
from: withBasePath(basePath, redirect.from),
|
|
935
|
+
to: withBasePath(basePath, redirect.to)
|
|
936
|
+
})) : redirects;
|
|
884
937
|
var buildNetlifyRedirects = (redirects) => `${redirects.map((redirect) => `${redirect.from} ${redirect.to} ${redirect.status}`).join(`
|
|
885
938
|
`)}
|
|
886
939
|
`;
|
|
@@ -925,7 +978,8 @@ var buildRobots = (project) => {
|
|
|
925
978
|
lines.push("Allow: /");
|
|
926
979
|
const { site } = config.deployment;
|
|
927
980
|
if (site && config.seo.sitemap) {
|
|
928
|
-
|
|
981
|
+
const sitemapPath = withBasePath(normalizeBasePath(config.deployment.base), "/sitemap.xml");
|
|
982
|
+
lines.push("", `Sitemap: ${site.replace(/\/$/u, "")}${sitemapPath}`);
|
|
929
983
|
}
|
|
930
984
|
return `${lines.join(`
|
|
931
985
|
`)}
|
|
@@ -946,7 +1000,16 @@ var buildSitemap = (project) => {
|
|
|
946
1000
|
return null;
|
|
947
1001
|
}
|
|
948
1002
|
const base = site.replace(/\/$/u, "");
|
|
949
|
-
const
|
|
1003
|
+
const deployBase = normalizeBasePath(project.config.deployment.base);
|
|
1004
|
+
const urls = [];
|
|
1005
|
+
for (const page of project.graph.pages) {
|
|
1006
|
+
if (page.meta.draft || page.meta.sidebar.hidden || page.meta.seo.noindex) {
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
const loc = escapeXml(encodeURI(`${base}${withBasePath(deployBase, page.route)}`));
|
|
1010
|
+
urls.push(` <url><loc>${loc}</loc>${lastmodTag(page.lastModified)}</url>`);
|
|
1011
|
+
}
|
|
1012
|
+
urls.sort();
|
|
950
1013
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
951
1014
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
952
1015
|
${urls.join(`
|
|
@@ -2736,6 +2799,44 @@ var i18nDiagnostics = (pages, i18n) => {
|
|
|
2736
2799
|
// src/core/manifest.ts
|
|
2737
2800
|
var MANIFEST_VERSION = 1;
|
|
2738
2801
|
var contentIndexable = (page, config) => !page.meta.search.exclude && (!page.meta.sidebar.hidden || config.search.indexing.includeHiddenPages);
|
|
2802
|
+
var buildFallbackRoutes = (graph, i18n, alternatesByKey, basePath) => {
|
|
2803
|
+
const fallback = resolveFallbackLocale(i18n);
|
|
2804
|
+
if (!fallback) {
|
|
2805
|
+
return [];
|
|
2806
|
+
}
|
|
2807
|
+
const fallbackPages = new Map(graph.pages.flatMap((page) => page.locale === fallback ? [[page.translationKey, page]] : []));
|
|
2808
|
+
const routes = [];
|
|
2809
|
+
for (const { code } of i18n.locales) {
|
|
2810
|
+
if (code === fallback) {
|
|
2811
|
+
continue;
|
|
2812
|
+
}
|
|
2813
|
+
const present = new Set(graph.pages.flatMap((page) => page.locale === code ? [page.translationKey] : []));
|
|
2814
|
+
for (const [key, source] of fallbackPages) {
|
|
2815
|
+
if (present.has(key)) {
|
|
2816
|
+
continue;
|
|
2817
|
+
}
|
|
2818
|
+
routes.push({
|
|
2819
|
+
alternates: alternatesByKey.get(key) ?? [],
|
|
2820
|
+
collection: source.collection ?? "docs",
|
|
2821
|
+
contentType: source.contentType,
|
|
2822
|
+
draft: source.meta.draft,
|
|
2823
|
+
editUrl: source.editUrl,
|
|
2824
|
+
entryId: source.entryId ?? source.source.ref,
|
|
2825
|
+
fallback: true,
|
|
2826
|
+
hidden: source.meta.sidebar.hidden,
|
|
2827
|
+
id: source.id,
|
|
2828
|
+
indexable: false,
|
|
2829
|
+
lastModified: source.lastModified,
|
|
2830
|
+
locale: code,
|
|
2831
|
+
path: withBasePath(basePath, localizeRoute(key, code, i18n)),
|
|
2832
|
+
source: source.source,
|
|
2833
|
+
sourcePath: source.sourcePath,
|
|
2834
|
+
title: source.title
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
return routes;
|
|
2839
|
+
};
|
|
2739
2840
|
var buildManifest = (options) => {
|
|
2740
2841
|
const { context, config, graph } = options;
|
|
2741
2842
|
const searchEnabled = config.search.provider !== "none";
|
|
@@ -2766,39 +2867,7 @@ var buildManifest = (options) => {
|
|
|
2766
2867
|
title: page.title
|
|
2767
2868
|
}));
|
|
2768
2869
|
if (i18n) {
|
|
2769
|
-
|
|
2770
|
-
if (fallback) {
|
|
2771
|
-
const fallbackPages = new Map(graph.pages.filter((page) => page.locale === fallback).map((page) => [page.translationKey, page]));
|
|
2772
|
-
for (const { code } of i18n.locales) {
|
|
2773
|
-
if (code === fallback) {
|
|
2774
|
-
continue;
|
|
2775
|
-
}
|
|
2776
|
-
const present = new Set(graph.pages.filter((page) => page.locale === code).map((page) => page.translationKey));
|
|
2777
|
-
for (const [key, source] of fallbackPages) {
|
|
2778
|
-
if (present.has(key)) {
|
|
2779
|
-
continue;
|
|
2780
|
-
}
|
|
2781
|
-
routes.push({
|
|
2782
|
-
alternates: alternatesByKey.get(key) ?? [],
|
|
2783
|
-
collection: source.collection ?? "docs",
|
|
2784
|
-
contentType: source.contentType,
|
|
2785
|
-
draft: source.meta.draft,
|
|
2786
|
-
editUrl: source.editUrl,
|
|
2787
|
-
entryId: source.entryId ?? source.source.ref,
|
|
2788
|
-
fallback: true,
|
|
2789
|
-
hidden: source.meta.sidebar.hidden,
|
|
2790
|
-
id: source.id,
|
|
2791
|
-
indexable: false,
|
|
2792
|
-
lastModified: source.lastModified,
|
|
2793
|
-
locale: code,
|
|
2794
|
-
path: localizeRoute(key, code, i18n),
|
|
2795
|
-
source: source.source,
|
|
2796
|
-
sourcePath: source.sourcePath,
|
|
2797
|
-
title: source.title
|
|
2798
|
-
});
|
|
2799
|
-
}
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2870
|
+
routes.push(...buildFallbackRoutes(graph, i18n, alternatesByKey, config.basePath));
|
|
2802
2871
|
}
|
|
2803
2872
|
routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
2804
2873
|
return {
|
|
@@ -2826,8 +2895,7 @@ var toPlainText = (markdown) => {
|
|
|
2826
2895
|
let cursor = 0;
|
|
2827
2896
|
for (const match of withoutBlocks.matchAll(INLINE_CODE)) {
|
|
2828
2897
|
const start = match.index ?? 0;
|
|
2829
|
-
pieces.push(withoutBlocks.slice(cursor, start).replaceAll(HTML_OR_JSX, " "));
|
|
2830
|
-
pieces.push(match.groups?.code ?? "");
|
|
2898
|
+
pieces.push(withoutBlocks.slice(cursor, start).replaceAll(HTML_OR_JSX, " "), match.groups?.code ?? "");
|
|
2831
2899
|
cursor = start + match[0].length;
|
|
2832
2900
|
}
|
|
2833
2901
|
pieces.push(withoutBlocks.slice(cursor).replaceAll(HTML_OR_JSX, " "));
|
|
@@ -2961,7 +3029,12 @@ var syncTypesense = async (records, config) => {
|
|
|
2961
3029
|
]
|
|
2962
3030
|
});
|
|
2963
3031
|
const collection = client.collections(config.collection);
|
|
2964
|
-
|
|
3032
|
+
let exists = true;
|
|
3033
|
+
try {
|
|
3034
|
+
await collection.retrieve();
|
|
3035
|
+
} catch {
|
|
3036
|
+
exists = false;
|
|
3037
|
+
}
|
|
2965
3038
|
if (exists) {
|
|
2966
3039
|
await collection.delete();
|
|
2967
3040
|
}
|
|
@@ -3124,23 +3197,25 @@ var ownsLock = (outDir) => {
|
|
|
3124
3197
|
return false;
|
|
3125
3198
|
}
|
|
3126
3199
|
};
|
|
3127
|
-
var
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
if (existing && existing.pid !== process.pid) {
|
|
3139
|
-
throw new DevLockHeldError(existing);
|
|
3140
|
-
}
|
|
3141
|
-
rmSync(lockPath(outDir), { force: true });
|
|
3200
|
+
var tryClaimLock = (outDir, port) => {
|
|
3201
|
+
try {
|
|
3202
|
+
writeFileSync(lockPath(outDir), lockPayload(port), { flag: "wx" });
|
|
3203
|
+
return true;
|
|
3204
|
+
} catch (error) {
|
|
3205
|
+
if (error.code !== "EEXIST") {
|
|
3206
|
+
throw error;
|
|
3207
|
+
}
|
|
3208
|
+
const existing = readDevLock(outDir);
|
|
3209
|
+
if (existing && existing.pid !== process.pid) {
|
|
3210
|
+
throw new DevLockHeldError(existing);
|
|
3142
3211
|
}
|
|
3212
|
+
rmSync(lockPath(outDir), { force: true });
|
|
3213
|
+
return false;
|
|
3143
3214
|
}
|
|
3215
|
+
};
|
|
3216
|
+
var acquireDevLock = (outDir, port) => {
|
|
3217
|
+
mkdirSync(outDir, { recursive: true });
|
|
3218
|
+
while (!tryClaimLock(outDir, port)) {}
|
|
3144
3219
|
let released = false;
|
|
3145
3220
|
return () => {
|
|
3146
3221
|
if (released) {
|
|
@@ -3180,7 +3255,7 @@ import {
|
|
|
3180
3255
|
writeFile as writeFile6
|
|
3181
3256
|
} from "node:fs/promises";
|
|
3182
3257
|
import { createRequire as createRequire5 } from "node:module";
|
|
3183
|
-
import { pathToFileURL as
|
|
3258
|
+
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
3184
3259
|
import { basename as basename2, dirname as dirname8, join as join22, normalize as normalize3, relative as relative8 } from "pathe";
|
|
3185
3260
|
import { glob as glob5 } from "tinyglobby";
|
|
3186
3261
|
|
|
@@ -3203,20 +3278,22 @@ var buildAskData = async (project) => {
|
|
|
3203
3278
|
};
|
|
3204
3279
|
|
|
3205
3280
|
// src/ai/ask.ts
|
|
3281
|
+
var OPENAI_COMPATIBLE = "openai-compatible";
|
|
3282
|
+
var OPENAI_COMPATIBLE_DEP = "@ai-sdk/openai-compatible";
|
|
3206
3283
|
var ASK_PRESETS = {
|
|
3207
3284
|
inkeep: {
|
|
3208
3285
|
apiKeyEnv: "INKEEP_API_KEY",
|
|
3209
3286
|
baseUrl: "https://api.inkeep.com/v1",
|
|
3210
|
-
kind:
|
|
3287
|
+
kind: OPENAI_COMPATIBLE,
|
|
3211
3288
|
name: "inkeep",
|
|
3212
|
-
runtimeDep:
|
|
3289
|
+
runtimeDep: OPENAI_COMPATIBLE_DEP
|
|
3213
3290
|
},
|
|
3214
3291
|
llmgateway: {
|
|
3215
3292
|
apiKeyEnv: "LLMGATEWAY_API_KEY",
|
|
3216
3293
|
baseUrl: "https://api.llmgateway.io/v1",
|
|
3217
|
-
kind:
|
|
3294
|
+
kind: OPENAI_COMPATIBLE,
|
|
3218
3295
|
name: "llmgateway",
|
|
3219
|
-
runtimeDep:
|
|
3296
|
+
runtimeDep: OPENAI_COMPATIBLE_DEP
|
|
3220
3297
|
},
|
|
3221
3298
|
openrouter: {
|
|
3222
3299
|
apiKeyEnv: "OPENROUTER_API_KEY",
|
|
@@ -3240,9 +3317,9 @@ var resolveAskBackend = (ask) => {
|
|
|
3240
3317
|
return {
|
|
3241
3318
|
apiKeyEnv,
|
|
3242
3319
|
baseUrl: ask?.baseUrl ?? preset?.baseUrl ?? "",
|
|
3243
|
-
kind:
|
|
3320
|
+
kind: OPENAI_COMPATIBLE,
|
|
3244
3321
|
model,
|
|
3245
|
-
name: preset?.name ??
|
|
3322
|
+
name: preset?.name ?? OPENAI_COMPATIBLE
|
|
3246
3323
|
};
|
|
3247
3324
|
};
|
|
3248
3325
|
var askBackendRuntimeDep = (ask) => {
|
|
@@ -3250,7 +3327,7 @@ var askBackendRuntimeDep = (ask) => {
|
|
|
3250
3327
|
if (provider === "gateway") {
|
|
3251
3328
|
return;
|
|
3252
3329
|
}
|
|
3253
|
-
return ASK_PRESETS[provider]?.runtimeDep ??
|
|
3330
|
+
return ASK_PRESETS[provider]?.runtimeDep ?? OPENAI_COMPATIBLE_DEP;
|
|
3254
3331
|
};
|
|
3255
3332
|
|
|
3256
3333
|
// src/ai/markdown.ts
|
|
@@ -3276,14 +3353,20 @@ var buildMcpData = async (project) => {
|
|
|
3276
3353
|
buildRawMarkdown(project)
|
|
3277
3354
|
]);
|
|
3278
3355
|
const descriptionById = new Map(graph.pages.map((page) => [page.id, page.description]));
|
|
3279
|
-
const routes =
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3356
|
+
const routes = [];
|
|
3357
|
+
for (const route of manifest.routes) {
|
|
3358
|
+
if (route.hidden) {
|
|
3359
|
+
continue;
|
|
3360
|
+
}
|
|
3361
|
+
routes.push({
|
|
3362
|
+
contentType: route.contentType,
|
|
3363
|
+
description: descriptionById.get(route.id),
|
|
3364
|
+
indexable: route.indexable,
|
|
3365
|
+
lastModified: route.lastModified ?? null,
|
|
3366
|
+
route: route.path,
|
|
3367
|
+
title: route.title
|
|
3368
|
+
});
|
|
3369
|
+
}
|
|
3287
3370
|
return {
|
|
3288
3371
|
documents: documents.map((doc) => ({
|
|
3289
3372
|
content: doc.content,
|
|
@@ -3424,6 +3507,7 @@ import { existsSync as existsSync7 } from "node:fs";
|
|
|
3424
3507
|
import { dirname as dirname5, extname, isAbsolute as isAbsolute2, resolve as resolve3 } from "pathe";
|
|
3425
3508
|
import ts from "typescript";
|
|
3426
3509
|
var GROUPS = ["mdx", "layout", "islands"];
|
|
3510
|
+
var GROUP_SET = new Set(GROUPS);
|
|
3427
3511
|
var FRAMEWORK_BY_EXT = {
|
|
3428
3512
|
jsx: "react",
|
|
3429
3513
|
svelte: "svelte",
|
|
@@ -3459,29 +3543,32 @@ var emptyAnalysis = () => ({
|
|
|
3459
3543
|
warnings: []
|
|
3460
3544
|
});
|
|
3461
3545
|
var propName = (name) => ts.isIdentifier(name) || ts.isStringLiteral(name) ? name.text : undefined;
|
|
3546
|
+
var addImportBindings = (map, statement) => {
|
|
3547
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
3548
|
+
return;
|
|
3549
|
+
}
|
|
3550
|
+
const specifier = statement.moduleSpecifier.text;
|
|
3551
|
+
const clause = statement.importClause;
|
|
3552
|
+
if (!clause) {
|
|
3553
|
+
return;
|
|
3554
|
+
}
|
|
3555
|
+
if (clause.name) {
|
|
3556
|
+
map.set(clause.name.text, { imported: "default", specifier });
|
|
3557
|
+
}
|
|
3558
|
+
const named = clause.namedBindings;
|
|
3559
|
+
if (named && ts.isNamedImports(named)) {
|
|
3560
|
+
for (const element of named.elements) {
|
|
3561
|
+
map.set(element.name.text, {
|
|
3562
|
+
imported: (element.propertyName ?? element.name).text,
|
|
3563
|
+
specifier
|
|
3564
|
+
});
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
};
|
|
3462
3568
|
var collectImports = (sourceFile) => {
|
|
3463
3569
|
const map = new Map;
|
|
3464
3570
|
for (const statement of sourceFile.statements) {
|
|
3465
|
-
|
|
3466
|
-
continue;
|
|
3467
|
-
}
|
|
3468
|
-
const specifier = statement.moduleSpecifier.text;
|
|
3469
|
-
const clause = statement.importClause;
|
|
3470
|
-
if (!clause) {
|
|
3471
|
-
continue;
|
|
3472
|
-
}
|
|
3473
|
-
if (clause.name) {
|
|
3474
|
-
map.set(clause.name.text, { imported: "default", specifier });
|
|
3475
|
-
}
|
|
3476
|
-
const named = clause.namedBindings;
|
|
3477
|
-
if (named && ts.isNamedImports(named)) {
|
|
3478
|
-
for (const element of named.elements) {
|
|
3479
|
-
map.set(element.name.text, {
|
|
3480
|
-
imported: (element.propertyName ?? element.name).text,
|
|
3481
|
-
specifier
|
|
3482
|
-
});
|
|
3483
|
-
}
|
|
3484
|
-
}
|
|
3571
|
+
addImportBindings(map, statement);
|
|
3485
3572
|
}
|
|
3486
3573
|
return map;
|
|
3487
3574
|
};
|
|
@@ -3539,33 +3626,36 @@ var resolveIdentifier = (name, imports, dir) => {
|
|
|
3539
3626
|
const binding = imports.get(name);
|
|
3540
3627
|
return binding ? toImport(binding.specifier, binding.imported, dir) : null;
|
|
3541
3628
|
};
|
|
3629
|
+
var applyDescriptorProperty = (descriptor, property, imports, dir) => {
|
|
3630
|
+
if (ts.isShorthandPropertyAssignment(property)) {
|
|
3631
|
+
if (property.name.text === "component") {
|
|
3632
|
+
descriptor.hadComponent = true;
|
|
3633
|
+
descriptor.source = resolveIdentifier(property.name.text, imports, dir);
|
|
3634
|
+
}
|
|
3635
|
+
return;
|
|
3636
|
+
}
|
|
3637
|
+
if (!ts.isPropertyAssignment(property)) {
|
|
3638
|
+
return;
|
|
3639
|
+
}
|
|
3640
|
+
const name = propName(property.name);
|
|
3641
|
+
const init = property.initializer;
|
|
3642
|
+
if (name === "component") {
|
|
3643
|
+
descriptor.hadComponent = true;
|
|
3644
|
+
if (ts.isStringLiteral(init)) {
|
|
3645
|
+
descriptor.source = toImport(init.text, "default", dir);
|
|
3646
|
+
} else if (ts.isIdentifier(init)) {
|
|
3647
|
+
descriptor.source = resolveIdentifier(init.text, imports, dir);
|
|
3648
|
+
}
|
|
3649
|
+
} else if (name === "client" && ts.isStringLiteral(init) && HYDRATION_MODES.has(init.text)) {
|
|
3650
|
+
descriptor.client = init.text;
|
|
3651
|
+
} else if (name === "media" && ts.isStringLiteral(init)) {
|
|
3652
|
+
descriptor.media = init.text;
|
|
3653
|
+
}
|
|
3654
|
+
};
|
|
3542
3655
|
var readDescriptor = (object, imports, dir) => {
|
|
3543
3656
|
const descriptor = { hadComponent: false, source: null };
|
|
3544
3657
|
for (const property of object.properties) {
|
|
3545
|
-
|
|
3546
|
-
if (property.name.text === "component") {
|
|
3547
|
-
descriptor.hadComponent = true;
|
|
3548
|
-
descriptor.source = resolveIdentifier(property.name.text, imports, dir);
|
|
3549
|
-
}
|
|
3550
|
-
continue;
|
|
3551
|
-
}
|
|
3552
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
3553
|
-
continue;
|
|
3554
|
-
}
|
|
3555
|
-
const name = propName(property.name);
|
|
3556
|
-
const init = property.initializer;
|
|
3557
|
-
if (name === "component") {
|
|
3558
|
-
descriptor.hadComponent = true;
|
|
3559
|
-
if (ts.isStringLiteral(init)) {
|
|
3560
|
-
descriptor.source = toImport(init.text, "default", dir);
|
|
3561
|
-
} else if (ts.isIdentifier(init)) {
|
|
3562
|
-
descriptor.source = resolveIdentifier(init.text, imports, dir);
|
|
3563
|
-
}
|
|
3564
|
-
} else if (name === "client" && ts.isStringLiteral(init) && HYDRATION_MODES.has(init.text)) {
|
|
3565
|
-
descriptor.client = init.text;
|
|
3566
|
-
} else if (name === "media" && ts.isStringLiteral(init)) {
|
|
3567
|
-
descriptor.media = init.text;
|
|
3568
|
-
}
|
|
3658
|
+
applyDescriptorProperty(descriptor, property, imports, dir);
|
|
3569
3659
|
}
|
|
3570
3660
|
return descriptor;
|
|
3571
3661
|
};
|
|
@@ -3648,6 +3738,22 @@ var normalizeEntry = (entry, group, imports, dir, warnings) => {
|
|
|
3648
3738
|
}
|
|
3649
3739
|
return { identifier: false, key, source: null };
|
|
3650
3740
|
};
|
|
3741
|
+
var collectGroupOverrides = (property, imports, dir, result) => {
|
|
3742
|
+
if (!ts.isPropertyAssignment(property)) {
|
|
3743
|
+
return;
|
|
3744
|
+
}
|
|
3745
|
+
const name = propName(property.name);
|
|
3746
|
+
if (!(name && GROUP_SET.has(name)) || !ts.isObjectLiteralExpression(property.initializer)) {
|
|
3747
|
+
return;
|
|
3748
|
+
}
|
|
3749
|
+
const group = name;
|
|
3750
|
+
for (const entry of property.initializer.properties) {
|
|
3751
|
+
const normalized = normalizeEntry(entry, group, imports, dir, result.warnings);
|
|
3752
|
+
if (normalized) {
|
|
3753
|
+
result[group].push(normalized);
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
};
|
|
3651
3757
|
var analyzeComponentOverrides = (source, filePath) => {
|
|
3652
3758
|
const result = emptyAnalysis();
|
|
3653
3759
|
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, filePath.endsWith("tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
|
|
@@ -3658,20 +3764,7 @@ var analyzeComponentOverrides = (source, filePath) => {
|
|
|
3658
3764
|
const imports = collectImports(sourceFile);
|
|
3659
3765
|
const dir = dirname5(filePath);
|
|
3660
3766
|
for (const property of object.properties) {
|
|
3661
|
-
|
|
3662
|
-
continue;
|
|
3663
|
-
}
|
|
3664
|
-
const name = propName(property.name);
|
|
3665
|
-
if (!(name && GROUPS.includes(name)) || !ts.isObjectLiteralExpression(property.initializer)) {
|
|
3666
|
-
continue;
|
|
3667
|
-
}
|
|
3668
|
-
const group = name;
|
|
3669
|
-
for (const entry of property.initializer.properties) {
|
|
3670
|
-
const normalized = normalizeEntry(entry, group, imports, dir, result.warnings);
|
|
3671
|
-
if (normalized) {
|
|
3672
|
-
result[group].push(normalized);
|
|
3673
|
-
}
|
|
3674
|
-
}
|
|
3767
|
+
collectGroupOverrides(property, imports, dir, result);
|
|
3675
3768
|
}
|
|
3676
3769
|
return result;
|
|
3677
3770
|
};
|
|
@@ -3739,7 +3832,8 @@ var uiStringsObject = z.object({
|
|
|
3739
3832
|
}).default({})
|
|
3740
3833
|
});
|
|
3741
3834
|
var uiStringsSchema = uiStringsObject.default({});
|
|
3742
|
-
var
|
|
3835
|
+
var EN_UI_INPUT = Object.fromEntries(Object.keys(uiStringsObject.shape).map((group) => [group, {}]));
|
|
3836
|
+
var EN_UI = uiStringsObject.parse(EN_UI_INPUT);
|
|
3743
3837
|
var uiStringsOverrideSchema = z.record(z.string(), z.record(z.string(), z.string()));
|
|
3744
3838
|
var uiLocaleOverridesSchema = z.record(z.string(), uiStringsOverrideSchema);
|
|
3745
3839
|
var mergeUI = (base, override) => {
|
|
@@ -3916,7 +4010,7 @@ var duplicateLabelDiagnostics = (navigation) => {
|
|
|
3916
4010
|
return diagnostics;
|
|
3917
4011
|
};
|
|
3918
4012
|
var hiddenInSidebarDiagnostics = (navigation, pages) => {
|
|
3919
|
-
const hidden = new Set(pages.
|
|
4013
|
+
const hidden = new Set(pages.flatMap((page) => page.meta.sidebar.hidden ? [page.id] : []));
|
|
3920
4014
|
if (hidden.size === 0) {
|
|
3921
4015
|
return [];
|
|
3922
4016
|
}
|
|
@@ -4005,26 +4099,34 @@ var resolveReferences = (config) => [
|
|
|
4005
4099
|
];
|
|
4006
4100
|
var referenceTabs = (config) => resolveReferences(config).map((ref) => ({
|
|
4007
4101
|
label: ref.label,
|
|
4008
|
-
path: ref.route
|
|
4102
|
+
path: ref.renderer === "blume" ? withBasePath(config.basePath, ref.route) : ref.route
|
|
4009
4103
|
}));
|
|
4104
|
+
var blumeReferenceOf = (ref, seen, usedSlugs) => {
|
|
4105
|
+
if (ref.kind !== "openapi" || ref.renderer !== "blume") {
|
|
4106
|
+
return null;
|
|
4107
|
+
}
|
|
4108
|
+
if (seen.has(ref.route)) {
|
|
4109
|
+
return null;
|
|
4110
|
+
}
|
|
4111
|
+
seen.add(ref.route);
|
|
4112
|
+
let { slug } = ref;
|
|
4113
|
+
let n = 2;
|
|
4114
|
+
while (usedSlugs.has(slug)) {
|
|
4115
|
+
slug = `${ref.slug}-${n}`;
|
|
4116
|
+
n += 1;
|
|
4117
|
+
}
|
|
4118
|
+
usedSlugs.add(slug);
|
|
4119
|
+
return slug === ref.slug ? ref : { ...ref, slug };
|
|
4120
|
+
};
|
|
4010
4121
|
var blumeReferences = (config) => {
|
|
4011
4122
|
const seen = new Set;
|
|
4012
4123
|
const usedSlugs = new Set;
|
|
4013
4124
|
const result = [];
|
|
4014
4125
|
for (const ref of resolveReferences(config)) {
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
if (seen.has(ref.route)) {
|
|
4019
|
-
continue;
|
|
4020
|
-
}
|
|
4021
|
-
seen.add(ref.route);
|
|
4022
|
-
let { slug } = ref;
|
|
4023
|
-
for (let n = 2;usedSlugs.has(slug); n += 1) {
|
|
4024
|
-
slug = `${ref.slug}-${n}`;
|
|
4126
|
+
const accepted = blumeReferenceOf(ref, seen, usedSlugs);
|
|
4127
|
+
if (accepted) {
|
|
4128
|
+
result.push(accepted);
|
|
4025
4129
|
}
|
|
4026
|
-
usedSlugs.add(slug);
|
|
4027
|
-
result.push(slug === ref.slug ? ref : { ...ref, slug });
|
|
4028
4130
|
}
|
|
4029
4131
|
return result;
|
|
4030
4132
|
};
|
|
@@ -4138,6 +4240,7 @@ var isOperation = (value) => typeof value === "object" && value !== null;
|
|
|
4138
4240
|
var extractOperations = (document, baseRoute) => {
|
|
4139
4241
|
const operations = [];
|
|
4140
4242
|
const tagOrder = [];
|
|
4243
|
+
const tagsSeen = new Set;
|
|
4141
4244
|
const tagMeta = new Map((document.tags ?? []).map((tag) => [tag.name, tag.description ?? ""]));
|
|
4142
4245
|
const seen = new Set;
|
|
4143
4246
|
for (const [path, rawItem] of Object.entries(document.paths ?? {})) {
|
|
@@ -4152,7 +4255,8 @@ var extractOperations = (document, baseRoute) => {
|
|
|
4152
4255
|
}
|
|
4153
4256
|
const tag = operation.tags?.[0] ?? UNTAGGED;
|
|
4154
4257
|
const tagSlug = slugify2(tag) || "operations";
|
|
4155
|
-
if (!
|
|
4258
|
+
if (!tagsSeen.has(tag)) {
|
|
4259
|
+
tagsSeen.add(tag);
|
|
4156
4260
|
tagOrder.push(tag);
|
|
4157
4261
|
}
|
|
4158
4262
|
let key = operationKey(method, path, operation.operationId);
|
|
@@ -4376,13 +4480,20 @@ var overviewMdx = (spec) => {
|
|
|
4376
4480
|
});
|
|
4377
4481
|
}
|
|
4378
4482
|
}
|
|
4379
|
-
const tagSections =
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4483
|
+
const tagSections = [];
|
|
4484
|
+
for (const tag of sections) {
|
|
4485
|
+
if (!operations.some((operation) => operation.tagSlug === tag.slug)) {
|
|
4486
|
+
continue;
|
|
4487
|
+
}
|
|
4488
|
+
const description = tag.description.trim() ? [mdxSafe(tag.description.trim())] : [];
|
|
4489
|
+
tagSections.push([
|
|
4490
|
+
`## ${mdxSafe(tag.name)}`,
|
|
4491
|
+
...description,
|
|
4492
|
+
`<ApiTagOperations source="${spec.slug}" tag="${tag.slug}" />`
|
|
4493
|
+
].join(`
|
|
4384
4494
|
|
|
4385
4495
|
`));
|
|
4496
|
+
}
|
|
4386
4497
|
return {
|
|
4387
4498
|
body: [
|
|
4388
4499
|
withDescription(spec.description, `<ApiOverview source="${spec.slug}" />`),
|
|
@@ -4603,7 +4714,8 @@ var releaseToEntry = (release) => {
|
|
|
4603
4714
|
};
|
|
4604
4715
|
const raw = frontmatter_default.stringify(`${body}
|
|
4605
4716
|
`, data);
|
|
4606
|
-
const
|
|
4717
|
+
const fallbackRef = `release-${release.id}`;
|
|
4718
|
+
const ref = `${slugifyTag(release.tag_name) || fallbackRef}.md`;
|
|
4607
4719
|
return {
|
|
4608
4720
|
body: { format: "md", text: body },
|
|
4609
4721
|
data,
|
|
@@ -4686,42 +4798,36 @@ var githubReleasesSource = (options, ctx) => {
|
|
|
4686
4798
|
// src/core/sources/mdx-remote.ts
|
|
4687
4799
|
var REGEX_SPECIAL = /[.*+?^${}()|[\]\\]/u;
|
|
4688
4800
|
var escapeChar = (char) => REGEX_SPECIAL.test(char) ? `\\${char}` : char;
|
|
4801
|
+
var globToken = (pattern, i) => {
|
|
4802
|
+
const char = pattern[i] ?? "";
|
|
4803
|
+
if (char === "*") {
|
|
4804
|
+
if (pattern[i + 1] === "*") {
|
|
4805
|
+
if (pattern[i + 2] === "/") {
|
|
4806
|
+
return { next: i + 3, source: "(?:.*/)?" };
|
|
4807
|
+
}
|
|
4808
|
+
return { next: i + 2, source: ".*" };
|
|
4809
|
+
}
|
|
4810
|
+
return { next: i + 1, source: "[^/]*" };
|
|
4811
|
+
}
|
|
4812
|
+
if (char === "?") {
|
|
4813
|
+
return { next: i + 1, source: "[^/]" };
|
|
4814
|
+
}
|
|
4815
|
+
if (char === "{") {
|
|
4816
|
+
const end = pattern.indexOf("}", i);
|
|
4817
|
+
if (end !== -1) {
|
|
4818
|
+
const options = pattern.slice(i + 1, end).split(",").map((part) => [...part].map(escapeChar).join("")).join("|");
|
|
4819
|
+
return { next: end + 1, source: `(?:${options})` };
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4822
|
+
return { next: i + 1, source: escapeChar(char) };
|
|
4823
|
+
};
|
|
4689
4824
|
var globToRegExp = (pattern) => {
|
|
4690
4825
|
let source = "";
|
|
4691
4826
|
let i = 0;
|
|
4692
4827
|
while (i < pattern.length) {
|
|
4693
|
-
const
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
i += 2;
|
|
4697
|
-
if (pattern[i] === "/") {
|
|
4698
|
-
i += 1;
|
|
4699
|
-
source += "(?:.*/)?";
|
|
4700
|
-
} else {
|
|
4701
|
-
source += ".*";
|
|
4702
|
-
}
|
|
4703
|
-
continue;
|
|
4704
|
-
}
|
|
4705
|
-
source += "[^/]*";
|
|
4706
|
-
i += 1;
|
|
4707
|
-
continue;
|
|
4708
|
-
}
|
|
4709
|
-
if (char === "?") {
|
|
4710
|
-
source += "[^/]";
|
|
4711
|
-
i += 1;
|
|
4712
|
-
continue;
|
|
4713
|
-
}
|
|
4714
|
-
if (char === "{") {
|
|
4715
|
-
const end = pattern.indexOf("}", i);
|
|
4716
|
-
if (end !== -1) {
|
|
4717
|
-
const options = pattern.slice(i + 1, end).split(",").map((part) => [...part].map(escapeChar).join("")).join("|");
|
|
4718
|
-
source += `(?:${options})`;
|
|
4719
|
-
i = end + 1;
|
|
4720
|
-
continue;
|
|
4721
|
-
}
|
|
4722
|
-
}
|
|
4723
|
-
source += escapeChar(char);
|
|
4724
|
-
i += 1;
|
|
4828
|
+
const token = globToken(pattern, i);
|
|
4829
|
+
source += token.source;
|
|
4830
|
+
i = token.next;
|
|
4725
4831
|
}
|
|
4726
4832
|
return new RegExp(`^${source}$`, "u");
|
|
4727
4833
|
};
|
|
@@ -4750,11 +4856,22 @@ var enumerateGithub = async (github, include, doFetch) => {
|
|
|
4750
4856
|
}
|
|
4751
4857
|
const body = await res.json();
|
|
4752
4858
|
const prefix = base ? `${base}/` : "";
|
|
4753
|
-
const refs = (body.tree ?? []).
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4859
|
+
const refs = (body.tree ?? []).flatMap((node) => {
|
|
4860
|
+
if (!(node.type === "blob" && node.path.startsWith(prefix))) {
|
|
4861
|
+
return [];
|
|
4862
|
+
}
|
|
4863
|
+
const rel = node.path.slice(prefix.length);
|
|
4864
|
+
if (!matchesInclude(rel, include)) {
|
|
4865
|
+
return [];
|
|
4866
|
+
}
|
|
4867
|
+
return [
|
|
4868
|
+
{
|
|
4869
|
+
editUrl: `https://github.com/${owner}/${repo}/edit/${ref}/${prefix}${rel}`,
|
|
4870
|
+
fetchUrl: `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${prefix}${rel}`,
|
|
4871
|
+
ref: rel
|
|
4872
|
+
}
|
|
4873
|
+
];
|
|
4874
|
+
});
|
|
4758
4875
|
return { refs, truncated: body.truncated === true };
|
|
4759
4876
|
};
|
|
4760
4877
|
var mdxRemoteSource = (options, ctx) => {
|
|
@@ -4767,11 +4884,7 @@ var mdxRemoteSource = (options, ctx) => {
|
|
|
4767
4884
|
}
|
|
4768
4885
|
if (options.files && options.url) {
|
|
4769
4886
|
const base = options.url.replace(/\/$/u, "");
|
|
4770
|
-
const refs = options.files.
|
|
4771
|
-
editUrl: `${base}/${ref}`,
|
|
4772
|
-
fetchUrl: `${base}/${ref}`,
|
|
4773
|
-
ref
|
|
4774
|
-
}));
|
|
4887
|
+
const refs = options.files.flatMap((ref) => matchesInclude(ref, options.include) ? [{ editUrl: `${base}/${ref}`, fetchUrl: `${base}/${ref}`, ref }] : []);
|
|
4775
4888
|
return { refs, truncated: false };
|
|
4776
4889
|
}
|
|
4777
4890
|
throw new BlumeError({
|
|
@@ -5068,32 +5181,33 @@ var configuredCssVars = (fonts) => buildFontEntries(fonts).map((entry) => entry.
|
|
|
5068
5181
|
|
|
5069
5182
|
// src/core/schema.ts
|
|
5070
5183
|
var iconName = z2.string().min(1);
|
|
5184
|
+
var DEFAULT_CONTENT_GLOB = "**/*.{md,mdx}";
|
|
5071
5185
|
var hydrationMode = z2.enum(["load", "idle", "visible", "media", "only"]);
|
|
5072
5186
|
var dateSchema = z2.union([z2.string(), z2.date()]).transform((value) => value instanceof Date ? value.toISOString() : value);
|
|
5073
|
-
var sidebarMetaSchema = z2.
|
|
5187
|
+
var sidebarMetaSchema = z2.strictObject({
|
|
5074
5188
|
badge: z2.string().optional(),
|
|
5075
5189
|
hidden: z2.boolean().default(false),
|
|
5076
5190
|
icon: iconName.optional(),
|
|
5077
5191
|
label: z2.string().optional(),
|
|
5078
5192
|
order: z2.number().optional()
|
|
5079
|
-
})
|
|
5080
|
-
var seoMetaSchema = z2.
|
|
5193
|
+
});
|
|
5194
|
+
var seoMetaSchema = z2.strictObject({
|
|
5081
5195
|
canonical: z2.string().url().optional(),
|
|
5082
5196
|
description: z2.string().optional(),
|
|
5083
5197
|
image: z2.string().optional(),
|
|
5084
5198
|
noindex: z2.boolean().default(false),
|
|
5085
5199
|
title: z2.string().optional()
|
|
5086
|
-
})
|
|
5087
|
-
var searchMetaSchema = z2.
|
|
5200
|
+
});
|
|
5201
|
+
var searchMetaSchema = z2.strictObject({
|
|
5088
5202
|
boost: z2.number().optional(),
|
|
5089
5203
|
exclude: z2.boolean().default(false),
|
|
5090
5204
|
tags: z2.array(z2.string()).optional()
|
|
5091
|
-
})
|
|
5092
|
-
var changelogMetaSchema = z2.
|
|
5205
|
+
});
|
|
5206
|
+
var changelogMetaSchema = z2.strictObject({
|
|
5093
5207
|
category: z2.string().optional(),
|
|
5094
5208
|
date: dateSchema.optional(),
|
|
5095
5209
|
version: z2.string().optional()
|
|
5096
|
-
})
|
|
5210
|
+
});
|
|
5097
5211
|
var authorSchema = z2.union([
|
|
5098
5212
|
z2.string(),
|
|
5099
5213
|
z2.object({
|
|
@@ -5101,9 +5215,9 @@ var authorSchema = z2.union([
|
|
|
5101
5215
|
image: z2.string().optional(),
|
|
5102
5216
|
name: z2.string(),
|
|
5103
5217
|
url: z2.string().optional()
|
|
5104
|
-
}).
|
|
5218
|
+
}).catchall(z2.unknown())
|
|
5105
5219
|
]);
|
|
5106
|
-
var pageMetaBaseSchema = z2.
|
|
5220
|
+
var pageMetaBaseSchema = z2.strictObject({
|
|
5107
5221
|
authors: z2.union([authorSchema, z2.array(authorSchema)]).optional(),
|
|
5108
5222
|
changelog: changelogMetaSchema.optional(),
|
|
5109
5223
|
date: dateSchema.optional(),
|
|
@@ -5120,72 +5234,72 @@ var pageMetaBaseSchema = z2.object({
|
|
|
5120
5234
|
slug: z2.string().optional(),
|
|
5121
5235
|
title: z2.string().optional(),
|
|
5122
5236
|
type: z2.string().optional()
|
|
5123
|
-
})
|
|
5237
|
+
});
|
|
5124
5238
|
var pageMetaSchema = pageMetaBaseSchema;
|
|
5125
5239
|
var sidebarDisplaySchema = z2.enum(["flat", "group", "page"]);
|
|
5126
|
-
var folderMetaSchema = z2.
|
|
5240
|
+
var folderMetaSchema = z2.strictObject({
|
|
5127
5241
|
collapsed: z2.boolean().optional(),
|
|
5128
5242
|
icon: iconName.optional(),
|
|
5129
5243
|
order: z2.number().optional(),
|
|
5130
5244
|
pages: z2.array(z2.string()).optional(),
|
|
5131
5245
|
title: z2.string().optional()
|
|
5132
|
-
})
|
|
5246
|
+
});
|
|
5133
5247
|
var logoImageSchema = z2.union([
|
|
5134
5248
|
z2.string(),
|
|
5135
|
-
z2.
|
|
5249
|
+
z2.strictObject({
|
|
5136
5250
|
alt: z2.string().optional(),
|
|
5137
5251
|
dark: z2.string().optional(),
|
|
5138
5252
|
light: z2.string().optional()
|
|
5139
|
-
})
|
|
5253
|
+
})
|
|
5140
5254
|
]);
|
|
5141
5255
|
var logoConfigSchema = z2.union([
|
|
5142
5256
|
z2.string(),
|
|
5143
|
-
z2.
|
|
5257
|
+
z2.strictObject({
|
|
5144
5258
|
href: z2.string().optional(),
|
|
5145
5259
|
image: logoImageSchema.optional(),
|
|
5146
5260
|
text: z2.string().optional()
|
|
5147
|
-
})
|
|
5261
|
+
})
|
|
5148
5262
|
]);
|
|
5149
5263
|
var bannerConfigSchema = z2.union([
|
|
5150
5264
|
z2.string(),
|
|
5151
|
-
z2.
|
|
5265
|
+
z2.strictObject({
|
|
5152
5266
|
content: z2.string(),
|
|
5153
5267
|
dismissible: z2.boolean().default(false),
|
|
5154
5268
|
id: z2.string().optional(),
|
|
5155
|
-
link: z2.
|
|
5156
|
-
})
|
|
5269
|
+
link: z2.strictObject({ href: z2.string(), text: z2.string() }).optional()
|
|
5270
|
+
})
|
|
5157
5271
|
]);
|
|
5158
|
-
var filesystemSourceSchema = z2.
|
|
5272
|
+
var filesystemSourceSchema = z2.strictObject({
|
|
5159
5273
|
exclude: z2.array(z2.string()).default(["**/_*", "**/.*"]),
|
|
5160
|
-
include: z2.array(z2.string()).default([
|
|
5274
|
+
include: z2.array(z2.string()).default([DEFAULT_CONTENT_GLOB]),
|
|
5161
5275
|
prefix: z2.string().optional(),
|
|
5162
5276
|
root: z2.string().default("docs"),
|
|
5163
5277
|
type: z2.literal("filesystem")
|
|
5164
|
-
})
|
|
5165
|
-
var mdxRemoteSourceSchema = z2.
|
|
5278
|
+
});
|
|
5279
|
+
var mdxRemoteSourceSchema = z2.strictObject({
|
|
5166
5280
|
files: z2.array(z2.string()).optional(),
|
|
5167
|
-
github: z2.
|
|
5281
|
+
github: z2.strictObject({
|
|
5168
5282
|
owner: z2.string(),
|
|
5169
5283
|
path: z2.string().default(""),
|
|
5170
5284
|
ref: z2.string().default("main"),
|
|
5171
5285
|
repo: z2.string()
|
|
5172
|
-
}).
|
|
5173
|
-
include: z2.array(z2.string()).default([
|
|
5286
|
+
}).optional(),
|
|
5287
|
+
include: z2.array(z2.string()).default([DEFAULT_CONTENT_GLOB]),
|
|
5174
5288
|
pollInterval: z2.number().positive().optional(),
|
|
5175
5289
|
prefix: z2.string().optional(),
|
|
5176
5290
|
type: z2.literal("mdx-remote"),
|
|
5177
5291
|
url: z2.string().optional()
|
|
5178
|
-
})
|
|
5292
|
+
});
|
|
5179
5293
|
var sanitySourceSchema = z2.object({
|
|
5180
5294
|
apiVersion: z2.string().optional(),
|
|
5181
5295
|
dataset: z2.string(),
|
|
5182
|
-
fields: z2.
|
|
5296
|
+
fields: z2.strictObject({
|
|
5183
5297
|
body: z2.string().optional(),
|
|
5184
5298
|
description: z2.string().optional(),
|
|
5185
5299
|
lastModified: z2.string().optional(),
|
|
5186
5300
|
slug: z2.string().optional(),
|
|
5187
5301
|
title: z2.string().optional()
|
|
5188
|
-
}).
|
|
5302
|
+
}).optional(),
|
|
5189
5303
|
pollInterval: z2.number().positive().optional(),
|
|
5190
5304
|
prefix: z2.string().optional(),
|
|
5191
5305
|
projectId: z2.string(),
|
|
@@ -5196,17 +5310,17 @@ var notionSourceSchema = z2.object({
|
|
|
5196
5310
|
database: z2.string(),
|
|
5197
5311
|
pollInterval: z2.number().positive().optional(),
|
|
5198
5312
|
prefix: z2.string().optional(),
|
|
5199
|
-
properties: z2.
|
|
5313
|
+
properties: z2.strictObject({
|
|
5200
5314
|
description: z2.string().optional(),
|
|
5201
5315
|
order: z2.string().optional(),
|
|
5202
5316
|
slug: z2.string().optional(),
|
|
5203
5317
|
status: z2.string().optional(),
|
|
5204
5318
|
title: z2.string().optional()
|
|
5205
|
-
}).
|
|
5319
|
+
}).optional(),
|
|
5206
5320
|
publishedValue: z2.string().optional(),
|
|
5207
5321
|
type: z2.literal("notion")
|
|
5208
5322
|
});
|
|
5209
|
-
var githubReleasesSourceSchema = z2.
|
|
5323
|
+
var githubReleasesSourceSchema = z2.strictObject({
|
|
5210
5324
|
drafts: z2.boolean().optional(),
|
|
5211
5325
|
limit: z2.number().positive().optional(),
|
|
5212
5326
|
owner: z2.string(),
|
|
@@ -5215,7 +5329,7 @@ var githubReleasesSourceSchema = z2.object({
|
|
|
5215
5329
|
prereleases: z2.boolean().optional(),
|
|
5216
5330
|
repo: z2.string(),
|
|
5217
5331
|
type: z2.literal("github-releases")
|
|
5218
|
-
})
|
|
5332
|
+
});
|
|
5219
5333
|
var customSourceSchema = z2.object({
|
|
5220
5334
|
source: z2.custom((val) => typeof val === "object" && val !== null && typeof val.load === "function" && typeof val.name === "string", { message: "custom source must be a ContentSource (with name + load)" }),
|
|
5221
5335
|
type: z2.literal("custom")
|
|
@@ -5228,42 +5342,42 @@ var contentSourceSchema = z2.discriminatedUnion("type", [
|
|
|
5228
5342
|
notionSourceSchema,
|
|
5229
5343
|
customSourceSchema
|
|
5230
5344
|
]);
|
|
5231
|
-
var contentConfigSchema = z2.
|
|
5345
|
+
var contentConfigSchema = z2.strictObject({
|
|
5232
5346
|
defaultType: z2.string().default("doc"),
|
|
5233
5347
|
exclude: z2.array(z2.string()).default(["**/_*", "**/.*"]),
|
|
5234
|
-
include: z2.array(z2.string()).default([
|
|
5348
|
+
include: z2.array(z2.string()).default([DEFAULT_CONTENT_GLOB]),
|
|
5235
5349
|
pages: z2.string().default("pages"),
|
|
5236
5350
|
root: z2.string().default("docs"),
|
|
5237
5351
|
sources: z2.array(contentSourceSchema).optional()
|
|
5238
|
-
})
|
|
5239
|
-
var navTabSchema = z2.
|
|
5352
|
+
});
|
|
5353
|
+
var navTabSchema = z2.strictObject({
|
|
5240
5354
|
icon: iconName.optional(),
|
|
5241
|
-
items: z2.array(z2.
|
|
5355
|
+
items: z2.array(z2.strictObject({
|
|
5242
5356
|
description: z2.string().optional(),
|
|
5243
5357
|
icon: iconName.optional(),
|
|
5244
5358
|
label: z2.string(),
|
|
5245
5359
|
path: z2.string(),
|
|
5246
5360
|
tag: z2.string().optional()
|
|
5247
|
-
})
|
|
5361
|
+
})).optional(),
|
|
5248
5362
|
label: z2.string(),
|
|
5249
5363
|
path: z2.string()
|
|
5250
|
-
})
|
|
5251
|
-
var navSelectorItemSchema = z2.
|
|
5364
|
+
});
|
|
5365
|
+
var navSelectorItemSchema = z2.strictObject({
|
|
5252
5366
|
description: z2.string().optional(),
|
|
5253
5367
|
icon: iconName.optional(),
|
|
5254
5368
|
label: z2.string(),
|
|
5255
5369
|
path: z2.string(),
|
|
5256
5370
|
tag: z2.string().optional()
|
|
5257
|
-
})
|
|
5258
|
-
var navSelectorSchema = z2.
|
|
5371
|
+
});
|
|
5372
|
+
var navSelectorSchema = z2.strictObject({
|
|
5259
5373
|
items: z2.array(navSelectorItemSchema).default([]),
|
|
5260
5374
|
kind: z2.enum(["dropdown", "language", "product", "version"]),
|
|
5261
5375
|
label: z2.string()
|
|
5262
|
-
})
|
|
5376
|
+
});
|
|
5263
5377
|
var directoryModeSchema = z2.enum(["accordion", "card", "none"]);
|
|
5264
5378
|
var sidebarItemSchema = z2.lazy(() => z2.union([
|
|
5265
5379
|
z2.string(),
|
|
5266
|
-
z2.
|
|
5380
|
+
z2.strictObject({
|
|
5267
5381
|
badge: z2.string().optional(),
|
|
5268
5382
|
collapsed: z2.boolean().optional(),
|
|
5269
5383
|
directory: directoryModeSchema.optional(),
|
|
@@ -5273,52 +5387,60 @@ var sidebarItemSchema = z2.lazy(() => z2.union([
|
|
|
5273
5387
|
items: z2.array(sidebarItemSchema).optional(),
|
|
5274
5388
|
label: z2.string(),
|
|
5275
5389
|
root: z2.string().optional()
|
|
5276
|
-
})
|
|
5390
|
+
})
|
|
5277
5391
|
]));
|
|
5278
|
-
var fontSlug = z2.string().
|
|
5279
|
-
|
|
5280
|
-
|
|
5392
|
+
var fontSlug = z2.string().superRefine((value, ctx) => {
|
|
5393
|
+
if (!isFontSlug(value)) {
|
|
5394
|
+
ctx.addIssue({
|
|
5395
|
+
code: z2.ZodIssueCode.custom,
|
|
5396
|
+
message: `Unknown font "${value}". Supported fonts: ${FONT_SLUGS.join(", ")}.`
|
|
5397
|
+
});
|
|
5398
|
+
}
|
|
5399
|
+
});
|
|
5281
5400
|
var perModeValueSchema = z2.union([
|
|
5282
5401
|
z2.string(),
|
|
5283
|
-
z2.
|
|
5402
|
+
z2.strictObject({
|
|
5403
|
+
dark: z2.string().optional(),
|
|
5404
|
+
light: z2.string().optional()
|
|
5405
|
+
})
|
|
5284
5406
|
]).optional().transform((value) => typeof value === "string" ? { dark: value, light: value } : value);
|
|
5285
|
-
var themeConfigSchema = z2.
|
|
5407
|
+
var themeConfigSchema = z2.strictObject({
|
|
5286
5408
|
accent: z2.union([
|
|
5287
5409
|
z2.string(),
|
|
5288
|
-
z2.
|
|
5410
|
+
z2.strictObject({ dark: z2.string(), light: z2.string() })
|
|
5289
5411
|
]).default("blue").transform((value) => typeof value === "string" ? { dark: value, light: value } : value),
|
|
5290
5412
|
action: z2.string().optional(),
|
|
5291
5413
|
background: perModeValueSchema,
|
|
5292
5414
|
backgroundImage: perModeValueSchema,
|
|
5293
|
-
fonts: z2.
|
|
5415
|
+
fonts: z2.strictObject({
|
|
5294
5416
|
body: fontSlug.default("inter"),
|
|
5295
5417
|
display: fontSlug.default("inter-tight"),
|
|
5296
5418
|
mono: fontSlug.default("ibm-plex-mono")
|
|
5297
|
-
}).
|
|
5419
|
+
}).default({}),
|
|
5298
5420
|
layout: z2.enum(["sidebar"]).default("sidebar"),
|
|
5299
5421
|
mode: z2.enum(["system", "light", "dark"]).default("system"),
|
|
5300
5422
|
radius: z2.enum(["none", "sm", "md", "lg"]).default("md")
|
|
5301
|
-
})
|
|
5302
|
-
var algoliaSearchSchema = z2.
|
|
5423
|
+
});
|
|
5424
|
+
var algoliaSearchSchema = z2.strictObject({
|
|
5303
5425
|
appId: z2.string(),
|
|
5304
5426
|
indexName: z2.string(),
|
|
5305
5427
|
searchApiKey: z2.string()
|
|
5306
|
-
})
|
|
5307
|
-
var oramaCloudSearchSchema = z2.
|
|
5428
|
+
});
|
|
5429
|
+
var oramaCloudSearchSchema = z2.strictObject({
|
|
5308
5430
|
apiKey: z2.string(),
|
|
5309
5431
|
endpoint: z2.string(),
|
|
5310
5432
|
indexId: z2.string().optional()
|
|
5311
|
-
})
|
|
5312
|
-
var typesenseSearchSchema = z2.
|
|
5433
|
+
});
|
|
5434
|
+
var typesenseSearchSchema = z2.strictObject({
|
|
5313
5435
|
collection: z2.string(),
|
|
5314
5436
|
host: z2.string(),
|
|
5315
5437
|
port: z2.number().int().positive().optional(),
|
|
5316
5438
|
protocol: z2.enum(["http", "https"]).optional(),
|
|
5317
5439
|
searchApiKey: z2.string()
|
|
5318
|
-
})
|
|
5319
|
-
var mixedbreadSearchSchema = z2.
|
|
5440
|
+
});
|
|
5441
|
+
var mixedbreadSearchSchema = z2.strictObject({
|
|
5320
5442
|
storeId: z2.string()
|
|
5321
|
-
})
|
|
5443
|
+
});
|
|
5322
5444
|
var searchProviders = [
|
|
5323
5445
|
"orama",
|
|
5324
5446
|
"pagefind",
|
|
@@ -5335,16 +5457,16 @@ var PROVIDER_CONFIG_KEY = {
|
|
|
5335
5457
|
"orama-cloud": "oramaCloud",
|
|
5336
5458
|
typesense: "typesense"
|
|
5337
5459
|
};
|
|
5338
|
-
var searchConfigSchema = z2.
|
|
5460
|
+
var searchConfigSchema = z2.strictObject({
|
|
5339
5461
|
algolia: algoliaSearchSchema.optional(),
|
|
5340
|
-
indexing: z2.
|
|
5462
|
+
indexing: z2.strictObject({
|
|
5341
5463
|
includeHiddenPages: z2.boolean().default(false)
|
|
5342
|
-
}).
|
|
5464
|
+
}).default({}),
|
|
5343
5465
|
mixedbread: mixedbreadSearchSchema.optional(),
|
|
5344
5466
|
oramaCloud: oramaCloudSearchSchema.optional(),
|
|
5345
5467
|
provider: z2.enum(searchProviders).default("orama"),
|
|
5346
5468
|
typesense: typesenseSearchSchema.optional()
|
|
5347
|
-
}).
|
|
5469
|
+
}).superRefine((value, ctx) => {
|
|
5348
5470
|
const field = PROVIDER_CONFIG_KEY[value.provider];
|
|
5349
5471
|
if (field && !value[field]) {
|
|
5350
5472
|
ctx.addIssue({
|
|
@@ -5361,18 +5483,18 @@ var askAiProviders = [
|
|
|
5361
5483
|
"inkeep",
|
|
5362
5484
|
"openai-compatible"
|
|
5363
5485
|
];
|
|
5364
|
-
var aiConfigSchema = z2.
|
|
5365
|
-
ask: z2.
|
|
5486
|
+
var aiConfigSchema = z2.strictObject({
|
|
5487
|
+
ask: z2.strictObject({
|
|
5366
5488
|
apiKeyEnv: z2.string().optional(),
|
|
5367
5489
|
baseUrl: z2.string().url().optional(),
|
|
5368
5490
|
enabled: z2.boolean().default(false),
|
|
5369
5491
|
model: z2.string().default("openai/gpt-5.5"),
|
|
5370
5492
|
provider: z2.enum(askAiProviders).default("gateway"),
|
|
5371
|
-
suggestions: z2.array(z2.
|
|
5493
|
+
suggestions: z2.array(z2.strictObject({
|
|
5372
5494
|
icon: iconName.optional(),
|
|
5373
5495
|
label: z2.string().min(1)
|
|
5374
|
-
})
|
|
5375
|
-
}).
|
|
5496
|
+
})).default([])
|
|
5497
|
+
}).superRefine((value, ctx) => {
|
|
5376
5498
|
if (value.provider === "openai-compatible" && !value.baseUrl) {
|
|
5377
5499
|
ctx.addIssue({
|
|
5378
5500
|
code: z2.ZodIssueCode.custom,
|
|
@@ -5382,51 +5504,51 @@ var aiConfigSchema = z2.object({
|
|
|
5382
5504
|
}
|
|
5383
5505
|
}).optional(),
|
|
5384
5506
|
llmsTxt: z2.boolean().default(true)
|
|
5385
|
-
})
|
|
5386
|
-
var featuredLinkSchema = z2.
|
|
5507
|
+
});
|
|
5508
|
+
var featuredLinkSchema = z2.strictObject({
|
|
5387
5509
|
href: z2.string(),
|
|
5388
5510
|
icon: iconName.optional(),
|
|
5389
5511
|
label: z2.string()
|
|
5390
|
-
})
|
|
5391
|
-
var navigationConfigSchema = z2.
|
|
5512
|
+
});
|
|
5513
|
+
var navigationConfigSchema = z2.strictObject({
|
|
5392
5514
|
featured: z2.array(featuredLinkSchema).default([]),
|
|
5393
5515
|
repo: z2.boolean().default(true),
|
|
5394
5516
|
selectors: z2.array(navSelectorSchema).default([]),
|
|
5395
5517
|
sidebar: z2.union([
|
|
5396
5518
|
z2.array(sidebarItemSchema),
|
|
5397
|
-
z2.
|
|
5519
|
+
z2.strictObject({
|
|
5398
5520
|
display: sidebarDisplaySchema.default("flat"),
|
|
5399
5521
|
items: z2.array(sidebarItemSchema).optional()
|
|
5400
|
-
})
|
|
5522
|
+
})
|
|
5401
5523
|
]).default({}).transform((value) => Array.isArray(value) ? { display: "flat", items: value } : value),
|
|
5402
5524
|
tabs: z2.array(navTabSchema).optional()
|
|
5403
|
-
})
|
|
5525
|
+
});
|
|
5404
5526
|
var exportConfigSchema = z2.union([
|
|
5405
5527
|
z2.boolean(),
|
|
5406
|
-
z2.
|
|
5528
|
+
z2.strictObject({
|
|
5407
5529
|
epub: z2.boolean().default(false),
|
|
5408
5530
|
pdf: z2.boolean().default(false)
|
|
5409
|
-
})
|
|
5531
|
+
})
|
|
5410
5532
|
]).transform((value) => typeof value === "boolean" ? { epub: value, pdf: value } : value);
|
|
5411
|
-
var mcpConfigSchema = z2.
|
|
5533
|
+
var mcpConfigSchema = z2.strictObject({
|
|
5412
5534
|
enabled: z2.boolean().default(false),
|
|
5413
5535
|
instructions: z2.string().optional(),
|
|
5414
5536
|
name: z2.string().optional(),
|
|
5415
5537
|
route: z2.string().default("/mcp")
|
|
5416
|
-
})
|
|
5417
|
-
var localeSchema = z2.
|
|
5538
|
+
});
|
|
5539
|
+
var localeSchema = z2.strictObject({
|
|
5418
5540
|
code: z2.string().min(1),
|
|
5419
5541
|
dir: z2.enum(["ltr", "rtl"]).default("ltr"),
|
|
5420
5542
|
label: z2.string()
|
|
5421
|
-
})
|
|
5422
|
-
var i18nConfigSchema = z2.
|
|
5543
|
+
});
|
|
5544
|
+
var i18nConfigSchema = z2.strictObject({
|
|
5423
5545
|
defaultLocale: z2.string().default("en"),
|
|
5424
5546
|
fallbackLocale: z2.string().nullable().optional(),
|
|
5425
5547
|
hideDefaultLocalePrefix: z2.boolean().default(true),
|
|
5426
5548
|
locales: z2.array(localeSchema).min(1),
|
|
5427
5549
|
parser: z2.enum(["dir", "dot"]).default("dir"),
|
|
5428
5550
|
ui: uiLocaleOverridesSchema.optional()
|
|
5429
|
-
}).
|
|
5551
|
+
}).superRefine((value, ctx) => {
|
|
5430
5552
|
const codes = new Set(value.locales.map((locale) => locale.code));
|
|
5431
5553
|
if (!codes.has(value.defaultLocale)) {
|
|
5432
5554
|
ctx.addIssue({
|
|
@@ -5443,46 +5565,46 @@ var i18nConfigSchema = z2.object({
|
|
|
5443
5565
|
});
|
|
5444
5566
|
}
|
|
5445
5567
|
});
|
|
5446
|
-
var analyticsScriptSchema = z2.
|
|
5568
|
+
var analyticsScriptSchema = z2.strictObject({
|
|
5447
5569
|
attributes: z2.record(z2.string(), z2.string()).optional(),
|
|
5448
5570
|
content: z2.string().optional(),
|
|
5449
5571
|
src: z2.string().optional(),
|
|
5450
5572
|
strategy: z2.enum(["async", "defer"]).optional()
|
|
5451
|
-
}).
|
|
5573
|
+
}).refine((value) => Boolean(value.src) !== Boolean(value.content), {
|
|
5452
5574
|
message: "An analytics script must set exactly one of `src` or `content`."
|
|
5453
5575
|
});
|
|
5454
|
-
var analyticsConfigSchema = z2.
|
|
5455
|
-
posthog: z2.
|
|
5576
|
+
var analyticsConfigSchema = z2.strictObject({
|
|
5577
|
+
posthog: z2.strictObject({
|
|
5456
5578
|
host: z2.string().optional(),
|
|
5457
5579
|
key: z2.string()
|
|
5458
|
-
}).
|
|
5580
|
+
}).optional(),
|
|
5459
5581
|
scripts: z2.array(analyticsScriptSchema).optional(),
|
|
5460
5582
|
vercel: z2.boolean().optional()
|
|
5461
|
-
})
|
|
5462
|
-
var deploymentConfigSchema = z2.
|
|
5583
|
+
});
|
|
5584
|
+
var deploymentConfigSchema = z2.strictObject({
|
|
5463
5585
|
adapter: z2.enum(["vercel", "node", "netlify", "cloudflare"]).nullable().default(null),
|
|
5464
5586
|
base: z2.string().optional(),
|
|
5465
5587
|
output: z2.enum(["static", "server"]).default("static"),
|
|
5466
5588
|
site: z2.string().url().optional()
|
|
5467
|
-
})
|
|
5468
|
-
var redirectSchema = z2.
|
|
5589
|
+
});
|
|
5590
|
+
var redirectSchema = z2.strictObject({
|
|
5469
5591
|
from: z2.string(),
|
|
5470
5592
|
status: z2.union([z2.literal(301), z2.literal(302), z2.literal(307), z2.literal(308)]).default(301),
|
|
5471
5593
|
to: z2.string()
|
|
5472
|
-
})
|
|
5473
|
-
var ogConfigSchema = z2.
|
|
5594
|
+
});
|
|
5595
|
+
var ogConfigSchema = z2.strictObject({
|
|
5474
5596
|
enabled: z2.boolean().optional()
|
|
5475
|
-
})
|
|
5476
|
-
var rssConfigSchema = z2.
|
|
5597
|
+
});
|
|
5598
|
+
var rssConfigSchema = z2.strictObject({
|
|
5477
5599
|
enabled: z2.boolean().default(true),
|
|
5478
5600
|
limit: z2.number().int().positive().default(50),
|
|
5479
5601
|
types: z2.array(z2.string()).default(["blog", "changelog"])
|
|
5480
|
-
})
|
|
5481
|
-
var contentSignalsObjectSchema = z2.
|
|
5602
|
+
});
|
|
5603
|
+
var contentSignalsObjectSchema = z2.strictObject({
|
|
5482
5604
|
aiInput: z2.boolean().default(true),
|
|
5483
5605
|
aiTrain: z2.boolean().default(true),
|
|
5484
5606
|
search: z2.boolean().default(true)
|
|
5485
|
-
})
|
|
5607
|
+
});
|
|
5486
5608
|
var contentSignalsSchema = z2.union([z2.boolean(), contentSignalsObjectSchema]).transform((value) => {
|
|
5487
5609
|
if (value === true) {
|
|
5488
5610
|
return contentSignalsObjectSchema.parse({});
|
|
@@ -5492,7 +5614,7 @@ var contentSignalsSchema = z2.union([z2.boolean(), contentSignalsObjectSchema]).
|
|
|
5492
5614
|
}
|
|
5493
5615
|
return value;
|
|
5494
5616
|
});
|
|
5495
|
-
var seoConfigSchema = z2.
|
|
5617
|
+
var seoConfigSchema = z2.strictObject({
|
|
5496
5618
|
agentReadability: z2.boolean().default(true),
|
|
5497
5619
|
contentSignals: contentSignalsSchema.default(true),
|
|
5498
5620
|
og: ogConfigSchema.default({}),
|
|
@@ -5500,40 +5622,50 @@ var seoConfigSchema = z2.object({
|
|
|
5500
5622
|
rss: rssConfigSchema.default({}),
|
|
5501
5623
|
sitemap: z2.boolean().default(true),
|
|
5502
5624
|
structuredData: z2.boolean().default(true)
|
|
5503
|
-
})
|
|
5504
|
-
var githubConfigSchema = z2.
|
|
5625
|
+
});
|
|
5626
|
+
var githubConfigSchema = z2.strictObject({
|
|
5505
5627
|
branch: z2.string().default("main"),
|
|
5506
5628
|
dir: z2.string().optional(),
|
|
5507
5629
|
owner: z2.string(),
|
|
5508
5630
|
repo: z2.string()
|
|
5509
|
-
})
|
|
5510
|
-
var codeBlockThemeSchema = z2.
|
|
5631
|
+
});
|
|
5632
|
+
var codeBlockThemeSchema = z2.strictObject({
|
|
5511
5633
|
dark: z2.string().default("github-dark"),
|
|
5512
5634
|
light: z2.string().default("github-light")
|
|
5513
|
-
})
|
|
5514
|
-
var codeBlocksConfigSchema = z2.
|
|
5635
|
+
});
|
|
5636
|
+
var codeBlocksConfigSchema = z2.strictObject({
|
|
5515
5637
|
theme: codeBlockThemeSchema.default({})
|
|
5516
|
-
})
|
|
5638
|
+
});
|
|
5639
|
+
var examplesConfigSchema = z2.union([
|
|
5640
|
+
z2.string(),
|
|
5641
|
+
z2.strictObject({
|
|
5642
|
+
css: z2.string().optional(),
|
|
5643
|
+
source: z2.string().default("examples")
|
|
5644
|
+
})
|
|
5645
|
+
]).transform((value) => typeof value === "string" ? { source: value } : value);
|
|
5517
5646
|
var lastModifiedConfigSchema = z2.union([
|
|
5518
5647
|
z2.boolean(),
|
|
5519
|
-
z2.
|
|
5648
|
+
z2.strictObject({ type: z2.enum(["git", "frontmatter"]).default("git") })
|
|
5520
5649
|
]);
|
|
5521
|
-
var codeConfigSchema = z2.
|
|
5650
|
+
var codeConfigSchema = z2.strictObject({
|
|
5522
5651
|
icons: z2.boolean().default(true),
|
|
5523
5652
|
wrap: z2.boolean().default(false)
|
|
5524
|
-
})
|
|
5525
|
-
var markdownConfigSchema = z2.
|
|
5653
|
+
});
|
|
5654
|
+
var markdownConfigSchema = z2.strictObject({
|
|
5526
5655
|
code: codeConfigSchema.default({}),
|
|
5527
5656
|
codeBlocks: codeBlocksConfigSchema.default({}),
|
|
5528
5657
|
headingAnchors: z2.boolean().default(true),
|
|
5529
5658
|
imageZoom: z2.boolean().default(true)
|
|
5530
|
-
})
|
|
5531
|
-
var
|
|
5659
|
+
});
|
|
5660
|
+
var reactConfigSchema = z2.strictObject({
|
|
5661
|
+
compiler: z2.boolean().default(true)
|
|
5662
|
+
});
|
|
5663
|
+
var openapiSourceSchema = z2.strictObject({
|
|
5532
5664
|
label: z2.string().optional(),
|
|
5533
5665
|
route: z2.string().optional(),
|
|
5534
5666
|
spec: z2.string()
|
|
5535
|
-
})
|
|
5536
|
-
var openapiConfigSchema = z2.
|
|
5667
|
+
});
|
|
5668
|
+
var openapiConfigSchema = z2.strictObject({
|
|
5537
5669
|
codeSamples: z2.array(z2.string()).default(["curl", "js", "python"]),
|
|
5538
5670
|
enabled: z2.boolean().default(false),
|
|
5539
5671
|
expandSchemas: z2.boolean().default(false),
|
|
@@ -5542,20 +5674,20 @@ var openapiConfigSchema = z2.object({
|
|
|
5542
5674
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
5543
5675
|
spec: z2.string().optional(),
|
|
5544
5676
|
theme: z2.string().optional()
|
|
5545
|
-
})
|
|
5546
|
-
var asyncapiConfigSchema = z2.
|
|
5677
|
+
});
|
|
5678
|
+
var asyncapiConfigSchema = z2.strictObject({
|
|
5547
5679
|
enabled: z2.boolean().default(false),
|
|
5548
5680
|
route: z2.string().default("/events"),
|
|
5549
5681
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
5550
5682
|
spec: z2.string().optional(),
|
|
5551
5683
|
theme: z2.string().optional()
|
|
5552
|
-
})
|
|
5684
|
+
});
|
|
5553
5685
|
var tocConfigSchema = z2.union([
|
|
5554
5686
|
z2.boolean(),
|
|
5555
|
-
z2.
|
|
5687
|
+
z2.strictObject({
|
|
5556
5688
|
maxHeadingLevel: z2.number().int().min(1).max(6).optional(),
|
|
5557
5689
|
minHeadingLevel: z2.number().int().min(1).max(6).optional()
|
|
5558
|
-
})
|
|
5690
|
+
})
|
|
5559
5691
|
]).default(true).transform((value) => {
|
|
5560
5692
|
if (typeof value === "boolean") {
|
|
5561
5693
|
return { enabled: value, maxLevel: 3, minLevel: 2 };
|
|
@@ -5566,15 +5698,16 @@ var tocConfigSchema = z2.union([
|
|
|
5566
5698
|
minLevel: value.minHeadingLevel ?? 2
|
|
5567
5699
|
};
|
|
5568
5700
|
});
|
|
5569
|
-
var blumeConfigSchema = z2.
|
|
5701
|
+
var blumeConfigSchema = z2.strictObject({
|
|
5570
5702
|
ai: aiConfigSchema.default({}),
|
|
5571
5703
|
analytics: analyticsConfigSchema.optional(),
|
|
5572
5704
|
asyncapi: asyncapiConfigSchema.default({}),
|
|
5573
5705
|
banner: bannerConfigSchema.optional(),
|
|
5706
|
+
basePath: z2.string().optional().transform((value) => normalizeBasePath(value)),
|
|
5574
5707
|
content: contentConfigSchema.default({}),
|
|
5575
5708
|
deployment: deploymentConfigSchema.default({}),
|
|
5576
5709
|
description: z2.string().optional(),
|
|
5577
|
-
examples:
|
|
5710
|
+
examples: examplesConfigSchema.default("examples"),
|
|
5578
5711
|
export: exportConfigSchema.default(false),
|
|
5579
5712
|
feedback: z2.boolean().default(true),
|
|
5580
5713
|
github: githubConfigSchema.optional(),
|
|
@@ -5585,13 +5718,14 @@ var blumeConfigSchema = z2.object({
|
|
|
5585
5718
|
mcp: mcpConfigSchema.default({}),
|
|
5586
5719
|
navigation: navigationConfigSchema.default({}),
|
|
5587
5720
|
openapi: openapiConfigSchema.default({}),
|
|
5721
|
+
react: reactConfigSchema.default({}),
|
|
5588
5722
|
redirects: z2.array(redirectSchema).default([]),
|
|
5589
5723
|
search: searchConfigSchema.default({}),
|
|
5590
5724
|
seo: seoConfigSchema.default({}),
|
|
5591
5725
|
theme: themeConfigSchema.default({}),
|
|
5592
5726
|
title: z2.string().default("Documentation"),
|
|
5593
5727
|
toc: tocConfigSchema
|
|
5594
|
-
})
|
|
5728
|
+
});
|
|
5595
5729
|
|
|
5596
5730
|
// src/core/sources/normalize.ts
|
|
5597
5731
|
var NUMERIC_PREFIX = /^\d+[-_.]/u;
|
|
@@ -5601,55 +5735,83 @@ var stripNumericPrefix = (segment) => segment.replace(NUMERIC_PREFIX, "");
|
|
|
5601
5735
|
var groupLabel = (segment) => segment.match(GROUP_FOLDER)?.groups?.label ?? null;
|
|
5602
5736
|
var slugify3 = (text) => text.toLowerCase().trim().replaceAll(/[^\w\s-]/gu, "").replaceAll(/[\s_]+/gu, "-").replaceAll(/-+/gu, "-").replaceAll(/^-|-$/gu, "");
|
|
5603
5737
|
var titleCase = (value) => value.split(WORD_SPLIT).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
5738
|
+
var addRouteSegment = (part, segments, groups) => {
|
|
5739
|
+
if (part === "") {
|
|
5740
|
+
return;
|
|
5741
|
+
}
|
|
5742
|
+
const group = groupLabel(part);
|
|
5743
|
+
if (group !== null) {
|
|
5744
|
+
groups.push(group);
|
|
5745
|
+
return;
|
|
5746
|
+
}
|
|
5747
|
+
const clean = stripNumericPrefix(part);
|
|
5748
|
+
if (clean === "index") {
|
|
5749
|
+
return;
|
|
5750
|
+
}
|
|
5751
|
+
segments.push(clean);
|
|
5752
|
+
};
|
|
5604
5753
|
var mapRoute = (relativePath) => {
|
|
5605
5754
|
const withoutExt = relativePath.slice(0, relativePath.length - extname4(relativePath).length);
|
|
5606
5755
|
const rawParts = withoutExt.split("/");
|
|
5607
5756
|
const segments = [];
|
|
5608
5757
|
const groups = [];
|
|
5609
5758
|
for (const part of rawParts) {
|
|
5610
|
-
|
|
5611
|
-
continue;
|
|
5612
|
-
}
|
|
5613
|
-
const group = groupLabel(part);
|
|
5614
|
-
if (group !== null) {
|
|
5615
|
-
groups.push(group);
|
|
5616
|
-
continue;
|
|
5617
|
-
}
|
|
5618
|
-
const clean = stripNumericPrefix(part);
|
|
5619
|
-
if (clean === "index") {
|
|
5620
|
-
continue;
|
|
5621
|
-
}
|
|
5622
|
-
segments.push(clean);
|
|
5759
|
+
addRouteSegment(part, segments, groups);
|
|
5623
5760
|
}
|
|
5624
5761
|
const route = segments.length === 0 ? "/" : `/${segments.join("/")}`;
|
|
5625
5762
|
return { groups, route, segments };
|
|
5626
5763
|
};
|
|
5627
5764
|
var CODE_FENCE2 = /^```/u;
|
|
5628
5765
|
var ATX_HEADING = /^(?<hashes>#{1,6})\s+(?<text>.+?)(?:\s+#+)?\s*$/u;
|
|
5766
|
+
var scanHeadingLine = (line, inFence, slugger, headings) => {
|
|
5767
|
+
if (CODE_FENCE2.test(line.trimStart())) {
|
|
5768
|
+
return !inFence;
|
|
5769
|
+
}
|
|
5770
|
+
if (inFence) {
|
|
5771
|
+
return inFence;
|
|
5772
|
+
}
|
|
5773
|
+
const match = line.match(ATX_HEADING);
|
|
5774
|
+
if (match?.groups) {
|
|
5775
|
+
const depth = match.groups.hashes?.length ?? 1;
|
|
5776
|
+
const text = (match.groups.text ?? "").trim();
|
|
5777
|
+
headings.push({ depth, slug: slugger.slug(text), text });
|
|
5778
|
+
}
|
|
5779
|
+
return inFence;
|
|
5780
|
+
};
|
|
5629
5781
|
var extractHeadings = (body) => {
|
|
5630
5782
|
const headings = [];
|
|
5631
5783
|
const slugger = new GithubSlugger;
|
|
5632
5784
|
let inFence = false;
|
|
5633
5785
|
for (const line of body.split(`
|
|
5634
5786
|
`)) {
|
|
5635
|
-
|
|
5636
|
-
inFence = !inFence;
|
|
5637
|
-
continue;
|
|
5638
|
-
}
|
|
5639
|
-
if (inFence) {
|
|
5640
|
-
continue;
|
|
5641
|
-
}
|
|
5642
|
-
const match = line.match(ATX_HEADING);
|
|
5643
|
-
if (match?.groups) {
|
|
5644
|
-
const depth = match.groups.hashes?.length ?? 1;
|
|
5645
|
-
const text = (match.groups.text ?? "").trim();
|
|
5646
|
-
headings.push({ depth, slug: slugger.slug(text), text });
|
|
5647
|
-
}
|
|
5787
|
+
inFence = scanHeadingLine(line, inFence, slugger, headings);
|
|
5648
5788
|
}
|
|
5649
5789
|
return headings;
|
|
5650
5790
|
};
|
|
5651
5791
|
var MD_LINK = /\[[^\]]*\]\((?<target>[^)\s]+)(?:\s+"[^"]*")?\)/gu;
|
|
5652
5792
|
var INLINE_CODE2 = /`[^`]*`/gu;
|
|
5793
|
+
var scanLinkLine = (line, lineNumber, inFence, links) => {
|
|
5794
|
+
if (CODE_FENCE2.test(line.trimStart())) {
|
|
5795
|
+
return !inFence;
|
|
5796
|
+
}
|
|
5797
|
+
if (inFence) {
|
|
5798
|
+
return inFence;
|
|
5799
|
+
}
|
|
5800
|
+
const masked = line.replaceAll(INLINE_CODE2, (span) => " ".repeat(span.length));
|
|
5801
|
+
for (const match of masked.matchAll(MD_LINK)) {
|
|
5802
|
+
const target = match.groups?.target;
|
|
5803
|
+
if (target === undefined || match.index === undefined) {
|
|
5804
|
+
continue;
|
|
5805
|
+
}
|
|
5806
|
+
const targetOffset = match.index + match[0].indexOf("](") + "](".length;
|
|
5807
|
+
links.push({
|
|
5808
|
+
column: targetOffset + 1,
|
|
5809
|
+
line: lineNumber,
|
|
5810
|
+
target
|
|
5811
|
+
});
|
|
5812
|
+
}
|
|
5813
|
+
return inFence;
|
|
5814
|
+
};
|
|
5653
5815
|
var extractLinks = (body) => {
|
|
5654
5816
|
const links = [];
|
|
5655
5817
|
let inFence = false;
|
|
@@ -5657,50 +5819,34 @@ var extractLinks = (body) => {
|
|
|
5657
5819
|
for (const line of body.split(`
|
|
5658
5820
|
`)) {
|
|
5659
5821
|
lineNumber += 1;
|
|
5660
|
-
|
|
5661
|
-
inFence = !inFence;
|
|
5662
|
-
continue;
|
|
5663
|
-
}
|
|
5664
|
-
if (inFence) {
|
|
5665
|
-
continue;
|
|
5666
|
-
}
|
|
5667
|
-
const masked = line.replaceAll(INLINE_CODE2, (span) => " ".repeat(span.length));
|
|
5668
|
-
for (const match of masked.matchAll(MD_LINK)) {
|
|
5669
|
-
const target = match.groups?.target;
|
|
5670
|
-
if (target === undefined || match.index === undefined) {
|
|
5671
|
-
continue;
|
|
5672
|
-
}
|
|
5673
|
-
const targetOffset = match.index + match[0].indexOf("](") + "](".length;
|
|
5674
|
-
links.push({
|
|
5675
|
-
column: targetOffset + 1,
|
|
5676
|
-
line: lineNumber,
|
|
5677
|
-
target
|
|
5678
|
-
});
|
|
5679
|
-
}
|
|
5822
|
+
inFence = scanLinkLine(line, lineNumber, inFence, links);
|
|
5680
5823
|
}
|
|
5681
5824
|
return links;
|
|
5682
5825
|
};
|
|
5683
5826
|
var DOUBLE_QUOTED = /"[^"]*"/gu;
|
|
5684
5827
|
var JSX_OPEN = /<(?<tag>[A-Z][A-Za-z0-9]*)/gu;
|
|
5828
|
+
var scanTagLine = (line, inFence, tags) => {
|
|
5829
|
+
if (CODE_FENCE2.test(line.trimStart())) {
|
|
5830
|
+
return !inFence;
|
|
5831
|
+
}
|
|
5832
|
+
if (inFence) {
|
|
5833
|
+
return inFence;
|
|
5834
|
+
}
|
|
5835
|
+
const clean = line.replaceAll(INLINE_CODE2, "").replaceAll(DOUBLE_QUOTED, "");
|
|
5836
|
+
for (const match of clean.matchAll(JSX_OPEN)) {
|
|
5837
|
+
const tag = match.groups?.tag;
|
|
5838
|
+
if (tag) {
|
|
5839
|
+
tags.add(tag);
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
return inFence;
|
|
5843
|
+
};
|
|
5685
5844
|
var extractComponentTags = (body) => {
|
|
5686
5845
|
const tags = new Set;
|
|
5687
5846
|
let inFence = false;
|
|
5688
5847
|
for (const line of body.split(`
|
|
5689
5848
|
`)) {
|
|
5690
|
-
|
|
5691
|
-
inFence = !inFence;
|
|
5692
|
-
continue;
|
|
5693
|
-
}
|
|
5694
|
-
if (inFence) {
|
|
5695
|
-
continue;
|
|
5696
|
-
}
|
|
5697
|
-
const clean = line.replaceAll(INLINE_CODE2, "").replaceAll(DOUBLE_QUOTED, "");
|
|
5698
|
-
for (const match of clean.matchAll(JSX_OPEN)) {
|
|
5699
|
-
const tag = match.groups?.tag;
|
|
5700
|
-
if (tag) {
|
|
5701
|
-
tags.add(tag);
|
|
5702
|
-
}
|
|
5703
|
-
}
|
|
5849
|
+
inFence = scanTagLine(line, inFence, tags);
|
|
5704
5850
|
}
|
|
5705
5851
|
return [...tags];
|
|
5706
5852
|
};
|
|
@@ -5776,7 +5922,7 @@ var normalizeEntry2 = (entry, ctx) => {
|
|
|
5776
5922
|
const pages = locales.map((locale) => ({
|
|
5777
5923
|
...base,
|
|
5778
5924
|
locale,
|
|
5779
|
-
route: i18n ? localizeRoute(logicalRoute, locale, i18n) : logicalRoute
|
|
5925
|
+
route: withBasePath(ctx.basePath ?? "", i18n ? localizeRoute(logicalRoute, locale, i18n) : logicalRoute)
|
|
5780
5926
|
}));
|
|
5781
5927
|
return { diagnostics: [], pages };
|
|
5782
5928
|
};
|
|
@@ -5961,7 +6107,10 @@ ${indented}`;
|
|
|
5961
6107
|
|
|
5962
6108
|
${nested}`;
|
|
5963
6109
|
}));
|
|
5964
|
-
const pairs = blocks.
|
|
6110
|
+
const pairs = blocks.flatMap((block, i) => {
|
|
6111
|
+
const text = parts[i] ?? "";
|
|
6112
|
+
return text ? [{ block, text }] : [];
|
|
6113
|
+
});
|
|
5965
6114
|
return pairs.map((pair, i) => {
|
|
5966
6115
|
if (i === 0) {
|
|
5967
6116
|
return pair.text;
|
|
@@ -6033,14 +6182,15 @@ ${nested}`;
|
|
|
6033
6182
|
}
|
|
6034
6183
|
};
|
|
6035
6184
|
};
|
|
6185
|
+
const queryDatabase = (client, cursor) => withNotionRetry(() => client.databases.query({
|
|
6186
|
+
database_id: options.database,
|
|
6187
|
+
start_cursor: cursor
|
|
6188
|
+
}));
|
|
6036
6189
|
const load2 = async (refresh = ctx?.refresh ?? true) => {
|
|
6037
6190
|
const assetDiagnostics = [];
|
|
6038
6191
|
const result = await loadWithCache(options.name, cache, async () => {
|
|
6039
6192
|
const client = await resolveClient();
|
|
6040
|
-
const pages = await collectAll((cursor) =>
|
|
6041
|
-
database_id: options.database,
|
|
6042
|
-
start_cursor: cursor
|
|
6043
|
-
})));
|
|
6193
|
+
const pages = await collectAll((cursor) => queryDatabase(client, cursor));
|
|
6044
6194
|
const built = await Promise.all(pages.map((page) => toEntry2(client, page)));
|
|
6045
6195
|
for (const item of built) {
|
|
6046
6196
|
assetDiagnostics.push(...item.diagnostics);
|
|
@@ -6404,38 +6554,53 @@ import { existsSync as existsSync10, readFileSync as readFileSync4, statSync } f
|
|
|
6404
6554
|
import { createRequire as createRequire3 } from "node:module";
|
|
6405
6555
|
import { pathToFileURL } from "node:url";
|
|
6406
6556
|
import { dirname as dirname6, isAbsolute as isAbsolute6, join as join17, resolve as resolve6 } from "pathe";
|
|
6557
|
+
var scanJsonChar = (text, index, inString) => {
|
|
6558
|
+
const char = text[index];
|
|
6559
|
+
if (inString) {
|
|
6560
|
+
if (char === "\\") {
|
|
6561
|
+
return {
|
|
6562
|
+
append: char + (text[index + 1] ?? ""),
|
|
6563
|
+
inString: true,
|
|
6564
|
+
next: index + 2
|
|
6565
|
+
};
|
|
6566
|
+
}
|
|
6567
|
+
return { append: char ?? "", inString: char !== '"', next: index + 1 };
|
|
6568
|
+
}
|
|
6569
|
+
if (char === '"') {
|
|
6570
|
+
return { append: char, inString: true, next: index + 1 };
|
|
6571
|
+
}
|
|
6572
|
+
if (char === "/" && text[index + 1] === "/") {
|
|
6573
|
+
const newline = text.indexOf(`
|
|
6574
|
+
`, index + 2);
|
|
6575
|
+
return {
|
|
6576
|
+
append: "",
|
|
6577
|
+
inString: false,
|
|
6578
|
+
next: newline === -1 ? text.length : newline
|
|
6579
|
+
};
|
|
6580
|
+
}
|
|
6581
|
+
if (char === "/" && text[index + 1] === "*") {
|
|
6582
|
+
const end = text.indexOf("*/", index + 2);
|
|
6583
|
+
return {
|
|
6584
|
+
append: "",
|
|
6585
|
+
inString: false,
|
|
6586
|
+
next: end === -1 ? text.length : end + 2
|
|
6587
|
+
};
|
|
6588
|
+
}
|
|
6589
|
+
return { append: char ?? "", inString: false, next: index + 1 };
|
|
6590
|
+
};
|
|
6407
6591
|
var stripJsonComments = (text) => {
|
|
6408
6592
|
let out = "";
|
|
6409
6593
|
let inString = false;
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
continue;
|
|
6421
|
-
}
|
|
6422
|
-
if (char === '"') {
|
|
6423
|
-
inString = true;
|
|
6424
|
-
out += char;
|
|
6425
|
-
continue;
|
|
6426
|
-
}
|
|
6427
|
-
if (char === "/" && text[index + 1] === "/") {
|
|
6428
|
-
const newline = text.indexOf(`
|
|
6429
|
-
`, index + 2);
|
|
6430
|
-
index = newline === -1 ? text.length : newline - 1;
|
|
6431
|
-
continue;
|
|
6432
|
-
}
|
|
6433
|
-
if (char === "/" && text[index + 1] === "*") {
|
|
6434
|
-
const end = text.indexOf("*/", index + 2);
|
|
6435
|
-
index = end === -1 ? text.length : end + 1;
|
|
6436
|
-
continue;
|
|
6437
|
-
}
|
|
6438
|
-
out += char;
|
|
6594
|
+
let index = 0;
|
|
6595
|
+
while (index < text.length) {
|
|
6596
|
+
const {
|
|
6597
|
+
append,
|
|
6598
|
+
inString: nextInString,
|
|
6599
|
+
next
|
|
6600
|
+
} = scanJsonChar(text, index, inString);
|
|
6601
|
+
out += append;
|
|
6602
|
+
inString = nextInString;
|
|
6603
|
+
index = next;
|
|
6439
6604
|
}
|
|
6440
6605
|
return out;
|
|
6441
6606
|
};
|
|
@@ -6466,10 +6631,10 @@ var resolveExtends = (spec, fromDir) => {
|
|
|
6466
6631
|
return candidates.find(isFile) ?? null;
|
|
6467
6632
|
}
|
|
6468
6633
|
try {
|
|
6469
|
-
const
|
|
6634
|
+
const requireFromDir = createRequire3(pathToFileURL(join17(fromDir, "_.js")).href);
|
|
6470
6635
|
for (const sub of [`${spec}/tsconfig.json`, spec]) {
|
|
6471
6636
|
try {
|
|
6472
|
-
return
|
|
6637
|
+
return requireFromDir.resolve(sub);
|
|
6473
6638
|
} catch {}
|
|
6474
6639
|
}
|
|
6475
6640
|
} catch {}
|
|
@@ -6542,6 +6707,7 @@ import { isAbsolute as isAbsolute8, join as join19 } from "pathe";
|
|
|
6542
6707
|
|
|
6543
6708
|
// src/astro/templates.ts
|
|
6544
6709
|
import { existsSync as existsSync11, readFileSync as readFileSync5 } from "node:fs";
|
|
6710
|
+
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
6545
6711
|
import { dirname as dirname7, isAbsolute as isAbsolute7, join as join18, relative as relative5 } from "pathe";
|
|
6546
6712
|
var WORKSPACE_MARKERS = [
|
|
6547
6713
|
".git",
|
|
@@ -6632,11 +6798,13 @@ var RENDER_EXTERNAL_DEPS = [
|
|
|
6632
6798
|
var renderUserAliases = (aliases) => Object.entries(aliases ?? {}).toSorted(([a], [b]) => b.length - a.length).map(([find, replacement]) => `
|
|
6633
6799
|
${JSON.stringify(find)}: ${JSON.stringify(replacement)},`).join("");
|
|
6634
6800
|
var astroOutDir = (context) => context.distDir ?? `${context.root}/dist`;
|
|
6801
|
+
var reactIntegration = (compilerPath) => compilerPath ? `react({ babel: { plugins: [[${JSON.stringify(compilerPath)}, { target: "19" }]] } })` : "react()";
|
|
6635
6802
|
var astroConfigTemplate = (options) => {
|
|
6636
6803
|
const { context, config, needsReact, pages, dataPath, themePath } = options;
|
|
6637
6804
|
const {
|
|
6638
6805
|
contentRoutes,
|
|
6639
6806
|
examplesPath,
|
|
6807
|
+
examplesThemePath,
|
|
6640
6808
|
needsSvelte,
|
|
6641
6809
|
needsVue,
|
|
6642
6810
|
openapiPath,
|
|
@@ -6663,8 +6831,9 @@ var astroConfigTemplate = (options) => {
|
|
|
6663
6831
|
prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix
|
|
6664
6832
|
}
|
|
6665
6833
|
})},` : "";
|
|
6666
|
-
const
|
|
6667
|
-
|
|
6834
|
+
const basedRedirects = applyBaseToRedirects(config.redirects, config.basePath);
|
|
6835
|
+
const redirectsOption = basedRedirects.length > 0 ? `
|
|
6836
|
+
redirects: ${JSON.stringify(Object.fromEntries(basedRedirects.map((redirect) => [
|
|
6668
6837
|
redirect.from,
|
|
6669
6838
|
{ destination: redirect.to, status: redirect.status }
|
|
6670
6839
|
])))},` : "";
|
|
@@ -6678,18 +6847,21 @@ var astroConfigTemplate = (options) => {
|
|
|
6678
6847
|
` : "";
|
|
6679
6848
|
const svelteImport = needsSvelte ? `import svelte from "@astrojs/svelte";
|
|
6680
6849
|
` : "";
|
|
6681
|
-
const blumeImport = `import { blumeIntegration, prerenderDepsPlugin } from "blume/astro";
|
|
6850
|
+
const blumeImport = `import { blumeIntegration, prerenderDepsPlugin, serverAppResolvePlugin } from "blume/astro";
|
|
6682
6851
|
`;
|
|
6683
6852
|
const twoslashImport = `import { transformerTwoslash } from "@shikijs/twoslash";
|
|
6684
6853
|
`;
|
|
6685
6854
|
const twoslashTransformer = "transformerTwoslash({ explicitTrigger: true }), ";
|
|
6855
|
+
const contentLinkBase = normalizeBasePath(deployment.base) + config.basePath;
|
|
6686
6856
|
const integrations = [
|
|
6687
6857
|
`mdx({ processor: blumeMdxProcessor(${JSON.stringify({
|
|
6858
|
+
basePath: contentLinkBase,
|
|
6859
|
+
codeThemes: config.markdown.codeBlocks.theme,
|
|
6688
6860
|
headingAnchors: config.markdown.headingAnchors
|
|
6689
6861
|
})}) })`
|
|
6690
6862
|
];
|
|
6691
6863
|
if (needsReact) {
|
|
6692
|
-
integrations.push(
|
|
6864
|
+
integrations.push(reactIntegration(options.reactCompilerPath));
|
|
6693
6865
|
}
|
|
6694
6866
|
if (needsVue) {
|
|
6695
6867
|
integrations.push("vue()");
|
|
@@ -6713,12 +6885,14 @@ export default defineConfig({
|
|
|
6713
6885
|
integrations: [${integrations.join(", ")}],
|
|
6714
6886
|
markdown: {
|
|
6715
6887
|
processor: blumeMarkdownProcessor(${JSON.stringify({
|
|
6888
|
+
basePath: contentLinkBase,
|
|
6889
|
+
codeThemes: config.markdown.codeBlocks.theme,
|
|
6716
6890
|
headingAnchors: config.markdown.headingAnchors
|
|
6717
6891
|
})}),
|
|
6718
6892
|
shikiConfig: {
|
|
6719
6893
|
themes: {
|
|
6720
|
-
light:
|
|
6721
|
-
dark:
|
|
6894
|
+
light: ${JSON.stringify(config.markdown.codeBlocks.theme.light)},
|
|
6895
|
+
dark: ${JSON.stringify(config.markdown.codeBlocks.theme.dark)},
|
|
6722
6896
|
},
|
|
6723
6897
|
defaultColor: false,
|
|
6724
6898
|
transformers: [${twoslashTransformer}...blumeShikiTransformers(${JSON.stringify({ icons: config.markdown.code.icons })})],
|
|
@@ -6726,7 +6900,7 @@ export default defineConfig({
|
|
|
6726
6900
|
},
|
|
6727
6901
|
devToolbar: { enabled: false },
|
|
6728
6902
|
vite: {
|
|
6729
|
-
plugins: [tailwindcss(), prerenderDepsPlugin()],
|
|
6903
|
+
plugins: [tailwindcss(), prerenderDepsPlugin(), serverAppResolvePlugin()],
|
|
6730
6904
|
// Blume's render-time deps are forced external on both build environments so
|
|
6731
6905
|
// native bindings resolve at runtime and isolated linkers don't bundle
|
|
6732
6906
|
// symlinked store copies (which would surface their children as unresolvable
|
|
@@ -6747,6 +6921,7 @@ export default defineConfig({
|
|
|
6747
6921
|
alias: {
|
|
6748
6922
|
"blume:data": ${JSON.stringify(dataPath)},
|
|
6749
6923
|
"blume:examples": ${JSON.stringify(examplesPath)},
|
|
6924
|
+
"blume:examples-theme": ${JSON.stringify(examplesThemePath)},
|
|
6750
6925
|
"blume:openapi": ${JSON.stringify(openapiPath)},
|
|
6751
6926
|
"blume:search-client": ${JSON.stringify(searchClientPath)},
|
|
6752
6927
|
"blume:theme": ${JSON.stringify(themePath)},${userAliasLines}
|
|
@@ -6771,6 +6946,7 @@ export default defineConfig({
|
|
|
6771
6946
|
`;
|
|
6772
6947
|
};
|
|
6773
6948
|
var stagedContentDir = (outDir) => join18(outDir, "content");
|
|
6949
|
+
var astroGlobBase = (base) => isAbsolute7(base) ? pathToFileURL2(base).href : base;
|
|
6774
6950
|
var contentConfigTemplate = (options) => {
|
|
6775
6951
|
const { context, config } = options;
|
|
6776
6952
|
const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);
|
|
@@ -6783,14 +6959,14 @@ var contentConfigTemplate = (options) => {
|
|
|
6783
6959
|
const docsPattern = filesystem ? [
|
|
6784
6960
|
...includeGlobs,
|
|
6785
6961
|
...(excludeGlobs ?? []).map((pattern) => `!${pattern}`),
|
|
6786
|
-
...BLUME_IGNORE_DIRS.
|
|
6962
|
+
...BLUME_IGNORE_DIRS.flatMap((dir) => dir === ".blume" ? [] : [`!**/${dir}/**`]),
|
|
6787
6963
|
...outDirIgnore
|
|
6788
6964
|
] : [];
|
|
6789
6965
|
const stagedBlock = options.staged ? `
|
|
6790
6966
|
const staged = defineCollection({
|
|
6791
6967
|
loader: glob({
|
|
6792
6968
|
pattern: ["**/*.{md,mdx}"],
|
|
6793
|
-
base: ${JSON.stringify(stagedBase)},
|
|
6969
|
+
base: ${JSON.stringify(astroGlobBase(stagedBase))},
|
|
6794
6970
|
generateId: ({ entry }) => entry,
|
|
6795
6971
|
}),
|
|
6796
6972
|
});
|
|
@@ -6802,7 +6978,7 @@ import { glob } from "astro/loaders";
|
|
|
6802
6978
|
const docs = defineCollection({
|
|
6803
6979
|
loader: glob({
|
|
6804
6980
|
pattern: ${JSON.stringify(docsPattern)},
|
|
6805
|
-
base: ${JSON.stringify(collectionBase)},
|
|
6981
|
+
base: ${JSON.stringify(astroGlobBase(collectionBase))},
|
|
6806
6982
|
generateId: ({ entry }) => entry,
|
|
6807
6983
|
}),
|
|
6808
6984
|
});
|
|
@@ -7178,6 +7354,7 @@ var catchAllPageTemplate = (options) => {
|
|
|
7178
7354
|
// Generated by Blume. Do not edit.
|
|
7179
7355
|
import { getEntry, render } from "astro:content";
|
|
7180
7356
|
import RootLayout from "blume/components/layout/RootLayout.astro";
|
|
7357
|
+
import { withBase } from "blume/components/islands/base-path.ts";
|
|
7181
7358
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
7182
7359
|
${askImport}
|
|
7183
7360
|
import Accordion from "blume/components/content/Accordion.astro";
|
|
@@ -7303,13 +7480,16 @@ const ogPath = data.config.og.enabled
|
|
|
7303
7480
|
? \`/og/\${route === "/" ? "index" : route.slice(1)}.png\`
|
|
7304
7481
|
: null;
|
|
7305
7482
|
const ogRel = seo.image ?? ogPath;
|
|
7306
|
-
//
|
|
7307
|
-
//
|
|
7483
|
+
// Absolute URLs also carry the deployment base (the page is served under it):
|
|
7484
|
+
// \`site + base + path\`. Only absolutize root-relative paths: \`seo.image\` may be
|
|
7485
|
+
// an external URL, which passes through verbatim (mirrors PageLayout).
|
|
7308
7486
|
const ogImage =
|
|
7309
|
-
ogRel && base && ogRel.startsWith("/") ? \`\${base}\${ogRel}\` : ogRel;
|
|
7487
|
+
ogRel && base && ogRel.startsWith("/") ? \`\${base}\${withBase(ogRel)}\` : ogRel;
|
|
7310
7488
|
|
|
7489
|
+
const basedRoute = withBase(route);
|
|
7311
7490
|
const canonical =
|
|
7312
|
-
seo.canonical ??
|
|
7491
|
+
seo.canonical ??
|
|
7492
|
+
(base ? \`\${base}\${basedRoute === "/" ? "" : basedRoute}\` : null);
|
|
7313
7493
|
|
|
7314
7494
|
// Locale resolution. With i18n on, pick the active locale's nav + dictionary,
|
|
7315
7495
|
// build hreflang alternates, and derive the language-switcher targets.
|
|
@@ -7342,7 +7522,10 @@ const contentLocale =
|
|
|
7342
7522
|
const contentDir = i18n
|
|
7343
7523
|
? (i18n.locales.find((l) => l.code === contentLocale)?.dir ?? "ltr")
|
|
7344
7524
|
: "ltr";
|
|
7345
|
-
const absolute = (path) =>
|
|
7525
|
+
const absolute = (path) => {
|
|
7526
|
+
const p = withBase(path);
|
|
7527
|
+
return base + (p === "/" ? "" : p);
|
|
7528
|
+
};
|
|
7346
7529
|
|
|
7347
7530
|
const localeAlternates =
|
|
7348
7531
|
i18n && base
|
|
@@ -7697,9 +7880,12 @@ import Example from ${JSON.stringify(spec.file)};
|
|
|
7697
7880
|
---
|
|
7698
7881
|
<Example ${exampleDirective(spec)}{...Astro.props}><slot /></Example>
|
|
7699
7882
|
`;
|
|
7700
|
-
var
|
|
7883
|
+
var examplesRouteBase = (basePath) => `${basePath}/blume-examples`;
|
|
7884
|
+
var exampleMapTemplate = (specs, basePath) => {
|
|
7885
|
+
const base = `export const examplesBase = ${JSON.stringify(examplesRouteBase(basePath))};`;
|
|
7701
7886
|
if (specs.length === 0) {
|
|
7702
7887
|
return `// Generated by Blume. Do not edit.
|
|
7888
|
+
${base}
|
|
7703
7889
|
export const examples = {};
|
|
7704
7890
|
`;
|
|
7705
7891
|
}
|
|
@@ -7709,11 +7895,65 @@ export const examples = {};
|
|
|
7709
7895
|
`);
|
|
7710
7896
|
return `// Generated by Blume. Do not edit.
|
|
7711
7897
|
${imports}
|
|
7898
|
+
${base}
|
|
7712
7899
|
export const examples = {
|
|
7713
7900
|
${entries}
|
|
7714
7901
|
};
|
|
7715
7902
|
`;
|
|
7716
7903
|
};
|
|
7904
|
+
var examplesPageTemplate = () => `---
|
|
7905
|
+
// Generated by Blume. Do not edit.
|
|
7906
|
+
import { examples } from "blume:examples";
|
|
7907
|
+
import "blume:examples-theme";
|
|
7908
|
+
|
|
7909
|
+
// Prerendered even in server output, like docs content.
|
|
7910
|
+
export const prerender = true;
|
|
7911
|
+
|
|
7912
|
+
export const getStaticPaths = () =>
|
|
7913
|
+
Object.keys(examples).map((path) => ({ params: { path } }));
|
|
7914
|
+
|
|
7915
|
+
const { path } = Astro.params;
|
|
7916
|
+
const entry = examples[path];
|
|
7917
|
+
const Example = entry.Component;
|
|
7918
|
+
---
|
|
7919
|
+
|
|
7920
|
+
<html lang="en">
|
|
7921
|
+
<head>
|
|
7922
|
+
<meta charset="utf-8" />
|
|
7923
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7924
|
+
<meta name="robots" content="noindex" />
|
|
7925
|
+
<title>{path}</title>
|
|
7926
|
+
<script is:inline>
|
|
7927
|
+
(() => {
|
|
7928
|
+
const root = document.documentElement;
|
|
7929
|
+
const apply = (theme) => {
|
|
7930
|
+
root.dataset.theme = theme;
|
|
7931
|
+
root.classList.toggle("dark", theme === "dark");
|
|
7932
|
+
};
|
|
7933
|
+
const stored = () =>
|
|
7934
|
+
localStorage.getItem("blume-theme") ??
|
|
7935
|
+
(matchMedia("(prefers-color-scheme: dark)").matches
|
|
7936
|
+
? "dark"
|
|
7937
|
+
: "light");
|
|
7938
|
+
try {
|
|
7939
|
+
const host = window.parent.document.documentElement;
|
|
7940
|
+
apply(host.dataset.theme ?? stored());
|
|
7941
|
+
new MutationObserver(() => {
|
|
7942
|
+
apply(host.dataset.theme ?? stored());
|
|
7943
|
+
}).observe(host, { attributeFilter: ["data-theme"] });
|
|
7944
|
+
} catch {
|
|
7945
|
+
apply(stored());
|
|
7946
|
+
}
|
|
7947
|
+
})();
|
|
7948
|
+
</script>
|
|
7949
|
+
</head>
|
|
7950
|
+
<!-- Flex + margin:auto centers the example and, unlike place-items, keeps
|
|
7951
|
+
the top edge reachable when the example outgrows the frame. -->
|
|
7952
|
+
<body style="display:flex;min-height:100svh;padding:1.5rem">
|
|
7953
|
+
<div style="margin:auto"><Example /></div>
|
|
7954
|
+
</body>
|
|
7955
|
+
</html>
|
|
7956
|
+
`;
|
|
7717
7957
|
var envTemplate = () => `/// <reference path="../.astro/types.d.ts" />
|
|
7718
7958
|
/// <reference types="astro/client" />
|
|
7719
7959
|
|
|
@@ -7862,25 +8102,31 @@ var specConfiguration = async (spec, root) => {
|
|
|
7862
8102
|
};
|
|
7863
8103
|
}
|
|
7864
8104
|
};
|
|
8105
|
+
var acceptScalarReference = (ref, seen, contentRoutes, warnings) => {
|
|
8106
|
+
if (ref.renderer !== "scalar") {
|
|
8107
|
+
return null;
|
|
8108
|
+
}
|
|
8109
|
+
if (seen.has(ref.route)) {
|
|
8110
|
+
warnings.push(`Two API reference sources resolve to ${ref.route}; keeping the first.`);
|
|
8111
|
+
return null;
|
|
8112
|
+
}
|
|
8113
|
+
if (contentRoutes.has(ref.route)) {
|
|
8114
|
+
warnings.push(`API reference route ${ref.route} collides with a content page; skipping the reference there.`);
|
|
8115
|
+
return null;
|
|
8116
|
+
}
|
|
8117
|
+
seen.add(ref.route);
|
|
8118
|
+
return ref;
|
|
8119
|
+
};
|
|
7865
8120
|
var buildReferenceFiles = async (options) => {
|
|
7866
8121
|
const { config, root, contentRoutes } = options;
|
|
7867
8122
|
const warnings = [];
|
|
7868
8123
|
const seen = new Set;
|
|
7869
8124
|
const accepted = [];
|
|
7870
8125
|
for (const ref of resolveReferences(config)) {
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
if (seen.has(ref.route)) {
|
|
7875
|
-
warnings.push(`Two API reference sources resolve to ${ref.route}; keeping the first.`);
|
|
7876
|
-
continue;
|
|
8126
|
+
const next = acceptScalarReference(ref, seen, contentRoutes, warnings);
|
|
8127
|
+
if (next) {
|
|
8128
|
+
accepted.push(next);
|
|
7877
8129
|
}
|
|
7878
|
-
if (contentRoutes.has(ref.route)) {
|
|
7879
|
-
warnings.push(`API reference route ${ref.route} collides with a content page; skipping the reference there.`);
|
|
7880
|
-
continue;
|
|
7881
|
-
}
|
|
7882
|
-
seen.add(ref.route);
|
|
7883
|
-
accepted.push(ref);
|
|
7884
8130
|
}
|
|
7885
8131
|
const built = await Promise.all(accepted.map(async (ref) => ({
|
|
7886
8132
|
ref,
|
|
@@ -7910,18 +8156,9 @@ var buildReferenceFiles = async (options) => {
|
|
|
7910
8156
|
};
|
|
7911
8157
|
|
|
7912
8158
|
// src/theme/entry.ts
|
|
7913
|
-
var
|
|
7914
|
-
@
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
/* Scan Blume's components and the user's project for utility classes. */
|
|
7918
|
-
${options.sources.map((source) => `@source "${source}";`).join(`
|
|
7919
|
-
`)}
|
|
7920
|
-
|
|
7921
|
-
/* Dark mode is driven by data-theme on the <html> element. */
|
|
7922
|
-
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
7923
|
-
|
|
7924
|
-
:root {
|
|
8159
|
+
var DARK_VARIANT = `/* Dark mode is driven by data-theme on the <html> element. */
|
|
8160
|
+
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));`;
|
|
8161
|
+
var TOKEN_DEFAULTS = `:root {
|
|
7925
8162
|
--blume-background: oklch(1 0 0);
|
|
7926
8163
|
--blume-background-image: none;
|
|
7927
8164
|
--blume-background-image-repeat: no-repeat;
|
|
@@ -7999,9 +8236,8 @@ ${options.sources.map((source) => `@source "${source}";`).join(`
|
|
|
7999
8236
|
--blume-code-remove-border: oklch(0.7 0.2 22 / 0.7);
|
|
8000
8237
|
--blume-code-word: oklch(0.7 0.14 255 / 0.22);
|
|
8001
8238
|
--blume-code-word-border: oklch(0.7 0.14 255 / 0.55);
|
|
8002
|
-
}
|
|
8003
|
-
|
|
8004
|
-
@theme inline {
|
|
8239
|
+
}`;
|
|
8240
|
+
var THEME_MAPPING = `@theme inline {
|
|
8005
8241
|
--color-background: var(--blume-background);
|
|
8006
8242
|
--color-foreground: var(--blume-foreground);
|
|
8007
8243
|
--color-muted: var(--blume-muted);
|
|
@@ -8016,7 +8252,20 @@ ${options.sources.map((source) => `@source "${source}";`).join(`
|
|
|
8016
8252
|
--font-sans: var(--blume-font-body);
|
|
8017
8253
|
--font-mono: var(--blume-font-mono);
|
|
8018
8254
|
--font-display: var(--blume-font-display);
|
|
8019
|
-
}
|
|
8255
|
+
}`;
|
|
8256
|
+
var tailwindEntryTemplate = (options) => `/* Generated by Blume. Do not edit. */
|
|
8257
|
+
@import "tailwindcss";
|
|
8258
|
+
@plugin "@tailwindcss/typography";
|
|
8259
|
+
|
|
8260
|
+
/* Scan Blume's components and the user's project for utility classes. */
|
|
8261
|
+
${options.sources.map((source) => `@source "${source}";`).join(`
|
|
8262
|
+
`)}
|
|
8263
|
+
|
|
8264
|
+
${DARK_VARIANT}
|
|
8265
|
+
|
|
8266
|
+
${TOKEN_DEFAULTS}
|
|
8267
|
+
|
|
8268
|
+
${THEME_MAPPING}
|
|
8020
8269
|
|
|
8021
8270
|
@layer base {
|
|
8022
8271
|
/* Nothing refuses to shrink below its intrinsic content width. This global
|
|
@@ -8561,6 +8810,33 @@ ${options.twoslashCss ?? ""}
|
|
|
8561
8810
|
${options.configTokens}
|
|
8562
8811
|
${options.userTheme}
|
|
8563
8812
|
`;
|
|
8813
|
+
var examplesEntryTemplate = (options) => `/* Generated by Blume. Do not edit. */
|
|
8814
|
+
@import "tailwindcss";
|
|
8815
|
+
|
|
8816
|
+
/* Scan the example files and the project sources they import. */
|
|
8817
|
+
${options.sources.map((source) => `@source "${source}";`).join(`
|
|
8818
|
+
`)}
|
|
8819
|
+
|
|
8820
|
+
${DARK_VARIANT}
|
|
8821
|
+
|
|
8822
|
+
${TOKEN_DEFAULTS}
|
|
8823
|
+
|
|
8824
|
+
${THEME_MAPPING}
|
|
8825
|
+
|
|
8826
|
+
/* Frame defaults: readable text in both modes, transparent so the docs pane's
|
|
8827
|
+
surface shows through. Base layer, so any user/example CSS wins. */
|
|
8828
|
+
@layer base {
|
|
8829
|
+
body {
|
|
8830
|
+
background: transparent;
|
|
8831
|
+
color: var(--blume-foreground);
|
|
8832
|
+
}
|
|
8833
|
+
}
|
|
8834
|
+
|
|
8835
|
+
/* Token overrides: config first, then the configured examples css (highest
|
|
8836
|
+
priority) — the place for shadcn variables and other component tokens. */
|
|
8837
|
+
${options.configTokens}
|
|
8838
|
+
${options.userCss}
|
|
8839
|
+
`;
|
|
8564
8840
|
|
|
8565
8841
|
// src/theme/twoslash.ts
|
|
8566
8842
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
@@ -8640,6 +8916,7 @@ export const mdxComponents = {};
|
|
|
8640
8916
|
export const layoutOverrides = {};
|
|
8641
8917
|
`;
|
|
8642
8918
|
var attributeValue = (value) => value.replaceAll(/["\n\r]/gu, " ").trim();
|
|
8919
|
+
var CLIENT_LOAD = "client:load";
|
|
8643
8920
|
var directiveFor = (override) => {
|
|
8644
8921
|
const framework = override.source?.framework;
|
|
8645
8922
|
switch (override.client) {
|
|
@@ -8650,13 +8927,13 @@ var directiveFor = (override) => {
|
|
|
8650
8927
|
return "client:visible";
|
|
8651
8928
|
}
|
|
8652
8929
|
case "media": {
|
|
8653
|
-
return override.media ? `client:media="${attributeValue(override.media)}"` :
|
|
8930
|
+
return override.media ? `client:media="${attributeValue(override.media)}"` : CLIENT_LOAD;
|
|
8654
8931
|
}
|
|
8655
8932
|
case "only": {
|
|
8656
|
-
return framework ? `client:only="${attributeValue(framework)}"` :
|
|
8933
|
+
return framework ? `client:only="${attributeValue(framework)}"` : CLIENT_LOAD;
|
|
8657
8934
|
}
|
|
8658
8935
|
default: {
|
|
8659
|
-
return
|
|
8936
|
+
return CLIENT_LOAD;
|
|
8660
8937
|
}
|
|
8661
8938
|
}
|
|
8662
8939
|
};
|
|
@@ -8779,30 +9056,33 @@ var discoverIslands = async (root) => {
|
|
|
8779
9056
|
const islands = [];
|
|
8780
9057
|
const warnings = [];
|
|
8781
9058
|
const seen = new Map;
|
|
8782
|
-
|
|
9059
|
+
const collectIsland = (file, source) => {
|
|
8783
9060
|
const base = basename(file);
|
|
8784
9061
|
const ext = base.match(ISLAND_FILE)?.groups?.ext;
|
|
8785
9062
|
const framework = ext ? FRAMEWORK_BY_EXT2[ext] : undefined;
|
|
8786
9063
|
if (!framework) {
|
|
8787
|
-
|
|
9064
|
+
return;
|
|
8788
9065
|
}
|
|
8789
9066
|
const name = base.replace(ISLAND_FILE, "");
|
|
8790
9067
|
if (!/^[A-Z][A-Za-z0-9_]*$/u.test(name)) {
|
|
8791
9068
|
warnings.push(`Island "${file}" must have a PascalCase identifier filename to be used in MDX (letters, digits, and underscores only, e.g. Counter.tsx → <Counter />); skipping it.`);
|
|
8792
|
-
|
|
9069
|
+
return;
|
|
8793
9070
|
}
|
|
8794
9071
|
const existing = seen.get(name);
|
|
8795
9072
|
if (existing) {
|
|
8796
9073
|
warnings.push(`Two islands both resolve to <${name}> ("${existing}" and "${file}"); ignoring the second. Give them distinct filenames.`);
|
|
8797
|
-
|
|
9074
|
+
return;
|
|
8798
9075
|
}
|
|
8799
9076
|
seen.set(name, file);
|
|
8800
9077
|
islands.push({
|
|
8801
|
-
client: readClientMode(
|
|
9078
|
+
client: readClientMode(source, file, warnings),
|
|
8802
9079
|
file,
|
|
8803
9080
|
framework,
|
|
8804
9081
|
name
|
|
8805
9082
|
});
|
|
9083
|
+
};
|
|
9084
|
+
for (const [index, file] of files.entries()) {
|
|
9085
|
+
collectIsland(file, sources[index] ?? "");
|
|
8806
9086
|
}
|
|
8807
9087
|
return { islands, warnings };
|
|
8808
9088
|
};
|
|
@@ -8821,9 +9101,6 @@ var GLOB_MAGIC = /[!*?[\]{}]/u;
|
|
|
8821
9101
|
var splitGlobBase = (pattern) => {
|
|
8822
9102
|
const segments = pattern.split("/");
|
|
8823
9103
|
const firstMagic = segments.findIndex((segment) => GLOB_MAGIC.test(segment));
|
|
8824
|
-
if (firstMagic === -1) {
|
|
8825
|
-
return { base: pattern, rest: "" };
|
|
8826
|
-
}
|
|
8827
9104
|
return {
|
|
8828
9105
|
base: segments.slice(0, firstMagic).join("/"),
|
|
8829
9106
|
rest: segments.slice(firstMagic).join("/")
|
|
@@ -8842,20 +9119,19 @@ var discoverExamples = async (root, pattern = "examples") => {
|
|
|
8842
9119
|
const examples = [];
|
|
8843
9120
|
const warnings = [];
|
|
8844
9121
|
const seen = new Map;
|
|
8845
|
-
|
|
9122
|
+
const collectExample = (file, source) => {
|
|
8846
9123
|
const ext = file.match(EXAMPLE_FILE)?.groups?.ext;
|
|
8847
9124
|
const framework = ext ? FRAMEWORK_BY_EXT3[ext] : undefined;
|
|
8848
9125
|
if (!(ext && framework)) {
|
|
8849
|
-
|
|
9126
|
+
return;
|
|
8850
9127
|
}
|
|
8851
9128
|
const path = relative6(dir, file).slice(0, -(ext.length + 1));
|
|
8852
9129
|
const existing = seen.get(path);
|
|
8853
9130
|
if (existing) {
|
|
8854
9131
|
warnings.push(`Two examples both resolve to "${path}" ("${existing}" and "${file}"); ignoring the second. Give them distinct paths.`);
|
|
8855
|
-
|
|
9132
|
+
return;
|
|
8856
9133
|
}
|
|
8857
9134
|
seen.set(path, file);
|
|
8858
|
-
const source = sources[index] ?? "";
|
|
8859
9135
|
examples.push({
|
|
8860
9136
|
client: framework === "astro" ? undefined : readClientMode(source, file, warnings),
|
|
8861
9137
|
file,
|
|
@@ -8864,6 +9140,9 @@ var discoverExamples = async (root, pattern = "examples") => {
|
|
|
8864
9140
|
path,
|
|
8865
9141
|
source
|
|
8866
9142
|
});
|
|
9143
|
+
};
|
|
9144
|
+
for (const [index, file] of files.entries()) {
|
|
9145
|
+
collectExample(file, sources[index] ?? "");
|
|
8867
9146
|
}
|
|
8868
9147
|
return { examples, warnings };
|
|
8869
9148
|
};
|
|
@@ -8895,18 +9174,21 @@ var humanizeSegment = (segment) => segment.split(/[-_]/u).filter(Boolean).map((w
|
|
|
8895
9174
|
var customOgRoutes = (pages, siteTitle) => {
|
|
8896
9175
|
const seen = new Set;
|
|
8897
9176
|
const routes = [];
|
|
8898
|
-
|
|
9177
|
+
const collectRoute = (pattern) => {
|
|
8899
9178
|
const segments = pattern.split("/").filter(Boolean);
|
|
8900
9179
|
if (segments.some((part) => PRIVATE_SEGMENT.test(part) || part.includes("["))) {
|
|
8901
|
-
|
|
9180
|
+
return;
|
|
8902
9181
|
}
|
|
8903
9182
|
const slug = segments.length === 0 ? "index" : segments.join("/");
|
|
8904
9183
|
if (seen.has(slug)) {
|
|
8905
|
-
|
|
9184
|
+
return;
|
|
8906
9185
|
}
|
|
8907
9186
|
seen.add(slug);
|
|
8908
9187
|
const last = segments.at(-1);
|
|
8909
9188
|
routes.push({ slug, title: last ? humanizeSegment(last) : siteTitle });
|
|
9189
|
+
};
|
|
9190
|
+
for (const { pattern } of pages) {
|
|
9191
|
+
collectRoute(pattern);
|
|
8910
9192
|
}
|
|
8911
9193
|
return routes;
|
|
8912
9194
|
};
|
|
@@ -8915,15 +9197,28 @@ var customOgRoutes = (pages, siteTitle) => {
|
|
|
8915
9197
|
var BLUME_SRC = join22(packageRoot(), "src");
|
|
8916
9198
|
var canResolveFrom = (fromDir, spec) => {
|
|
8917
9199
|
try {
|
|
8918
|
-
createRequire5(
|
|
9200
|
+
createRequire5(pathToFileURL3(join22(fromDir, "_.js")).href).resolve(spec);
|
|
8919
9201
|
return true;
|
|
8920
9202
|
} catch {
|
|
8921
9203
|
return false;
|
|
8922
9204
|
}
|
|
8923
9205
|
};
|
|
9206
|
+
var resolveReactCompiler = (config, needsReact) => {
|
|
9207
|
+
if (!(needsReact && config.react.compiler)) {
|
|
9208
|
+
return null;
|
|
9209
|
+
}
|
|
9210
|
+
try {
|
|
9211
|
+
return createRequire5(pathToFileURL3(join22(packageRoot(), "_.js")).href).resolve("babel-plugin-react-compiler");
|
|
9212
|
+
} catch {
|
|
9213
|
+
return null;
|
|
9214
|
+
}
|
|
9215
|
+
};
|
|
9216
|
+
var reactCompilerWarnings = (config, needsReact, compilerPath) => needsReact && config.react.compiler && !compilerPath ? [
|
|
9217
|
+
"React Compiler is enabled but `babel-plugin-react-compiler` could not be resolved; falling back to an uncompiled build. Reinstall Blume, or set `react: { compiler: false }` to silence this."
|
|
9218
|
+
] : [];
|
|
8924
9219
|
var resolvedAstroPath = (fromDir) => {
|
|
8925
9220
|
try {
|
|
8926
|
-
const pkg = createRequire5(
|
|
9221
|
+
const pkg = createRequire5(pathToFileURL3(join22(fromDir, "_.js")).href).resolve("astro/package.json");
|
|
8927
9222
|
return realpathSync(pkg);
|
|
8928
9223
|
} catch {
|
|
8929
9224
|
return null;
|
|
@@ -8934,7 +9229,12 @@ var blumeDepsDir = (pkgDir = packageRoot()) => {
|
|
|
8934
9229
|
return candidates.find((dir) => existsSync12(join22(dir, "astro"))) ?? null;
|
|
8935
9230
|
};
|
|
8936
9231
|
var linkDepsJunction = async (link, depsDir) => {
|
|
8937
|
-
|
|
9232
|
+
let existing;
|
|
9233
|
+
try {
|
|
9234
|
+
existing = await lstat(link);
|
|
9235
|
+
} catch {
|
|
9236
|
+
existing = null;
|
|
9237
|
+
}
|
|
8938
9238
|
if (existing) {
|
|
8939
9239
|
if (!existing.isSymbolicLink()) {
|
|
8940
9240
|
return;
|
|
@@ -8991,6 +9291,17 @@ var islandFrameworkWarnings = (frameworks, root) => {
|
|
|
8991
9291
|
}
|
|
8992
9292
|
return warnings;
|
|
8993
9293
|
};
|
|
9294
|
+
var examplesCssFile = (root, config) => config.examples.css ? join22(root, config.examples.css) : null;
|
|
9295
|
+
var writeExamplesPreview = async (options) => {
|
|
9296
|
+
const { config, hasExamples, root, srcDir, write } = options;
|
|
9297
|
+
if (hasExamples) {
|
|
9298
|
+
await write(join22(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
|
|
9299
|
+
}
|
|
9300
|
+
const cssFile = examplesCssFile(root, config);
|
|
9301
|
+
return cssFile && !existsSync12(cssFile) ? [
|
|
9302
|
+
`examples.css points at "${config.examples.css}", which doesn't exist; previews render without it.`
|
|
9303
|
+
] : [];
|
|
9304
|
+
};
|
|
8994
9305
|
var readOptional = async (path) => {
|
|
8995
9306
|
if (!path) {
|
|
8996
9307
|
return "";
|
|
@@ -9045,7 +9356,14 @@ var pruneOrphans = async (srcDir, written) => {
|
|
|
9045
9356
|
cwd: srcDir,
|
|
9046
9357
|
onlyFiles: true
|
|
9047
9358
|
});
|
|
9048
|
-
|
|
9359
|
+
const removals = [];
|
|
9360
|
+
for (const path of existing) {
|
|
9361
|
+
const normalized = normalize3(path);
|
|
9362
|
+
if (!written.has(normalized)) {
|
|
9363
|
+
removals.push(rm2(normalized, { force: true }));
|
|
9364
|
+
}
|
|
9365
|
+
}
|
|
9366
|
+
await Promise.all(removals);
|
|
9049
9367
|
};
|
|
9050
9368
|
var collectStaged = (project) => {
|
|
9051
9369
|
const staged = new Map;
|
|
@@ -9165,7 +9483,8 @@ var buildRuntimeData = (project) => {
|
|
|
9165
9483
|
return null;
|
|
9166
9484
|
}
|
|
9167
9485
|
const rel = relative8(context.root, sourcePath).split("\\").join("/");
|
|
9168
|
-
|
|
9486
|
+
const editPath = github?.dir ? `${github.dir}/${rel}` : rel;
|
|
9487
|
+
return `${editBase}/${editPath}`;
|
|
9169
9488
|
};
|
|
9170
9489
|
const { i18n } = config;
|
|
9171
9490
|
const withReferenceTabs = (nav) => ({
|
|
@@ -9199,6 +9518,7 @@ var buildRuntimeData = (project) => {
|
|
|
9199
9518
|
appleIcon: resolveAppleIcon(project),
|
|
9200
9519
|
ask: config.ai.ask?.enabled ? { suggestions: config.ai.ask.suggestions } : null,
|
|
9201
9520
|
banner: resolveBanner(config),
|
|
9521
|
+
codeThemes: config.markdown.codeBlocks.theme,
|
|
9202
9522
|
codeWrap: config.markdown.code.wrap,
|
|
9203
9523
|
description: config.description,
|
|
9204
9524
|
favicon: resolveFavicon(project),
|
|
@@ -9352,6 +9672,7 @@ var generateRuntime = async (project) => {
|
|
|
9352
9672
|
const themePath = join22(srcDir, "generated", "app.css");
|
|
9353
9673
|
const searchClientPath = join22(srcDir, "generated", "search-client.ts");
|
|
9354
9674
|
const examplesPath = join22(srcDir, "generated", "examples.ts");
|
|
9675
|
+
const examplesThemePath = join22(srcDir, "generated", "examples.css");
|
|
9355
9676
|
const openapiPath = join22(srcDir, "generated", "openapi.json");
|
|
9356
9677
|
const written = new Set;
|
|
9357
9678
|
const write = (path, content) => {
|
|
@@ -9367,21 +9688,25 @@ var generateRuntime = async (project) => {
|
|
|
9367
9688
|
detectedReact,
|
|
9368
9689
|
usesMath,
|
|
9369
9690
|
userTheme,
|
|
9691
|
+
userExamplesCss,
|
|
9370
9692
|
islandDiscovery,
|
|
9371
|
-
exampleDiscovery
|
|
9693
|
+
exampleDiscovery,
|
|
9694
|
+
componentSlots
|
|
9372
9695
|
] = await Promise.all([
|
|
9373
9696
|
context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),
|
|
9374
9697
|
detectNeedsReact(context.root),
|
|
9375
9698
|
detectUsesMath(context.root),
|
|
9376
9699
|
readOptional(context.themeFile),
|
|
9700
|
+
readOptional(examplesCssFile(context.root, config)),
|
|
9377
9701
|
discoverIslands(context.root),
|
|
9378
|
-
discoverExamples(context.root, config.examples)
|
|
9702
|
+
discoverExamples(context.root, config.examples.source),
|
|
9703
|
+
buildComponentSlots(context.componentsFile)
|
|
9379
9704
|
]);
|
|
9380
9705
|
const {
|
|
9381
9706
|
plan: slotPlan,
|
|
9382
9707
|
tags: overrideTags,
|
|
9383
9708
|
warnings: overrideWarnings
|
|
9384
|
-
} =
|
|
9709
|
+
} = componentSlots;
|
|
9385
9710
|
const frameworks = new Set([
|
|
9386
9711
|
...islandDiscovery.islands.map((island) => island.framework),
|
|
9387
9712
|
...exampleDiscovery.examples.map((example) => example.framework),
|
|
@@ -9390,63 +9715,73 @@ var generateRuntime = async (project) => {
|
|
|
9390
9715
|
const needsReact = detectedReact || askEnabled || frameworks.has("react");
|
|
9391
9716
|
const needsVue = frameworks.has("vue");
|
|
9392
9717
|
const needsSvelte = frameworks.has("svelte");
|
|
9718
|
+
const reactCompilerPath = resolveReactCompiler(config, needsReact);
|
|
9393
9719
|
const ogRoutes = customOgRoutes(pages, config.title);
|
|
9394
9720
|
const mcp = planMcp(project, srcDir, pages);
|
|
9395
9721
|
pages.push(...mcp.discoveryPages);
|
|
9396
9722
|
const staged = collectStaged(project);
|
|
9397
9723
|
const hasStaged = staged.size > 0;
|
|
9398
9724
|
const hasFilesystemSource = project.sources.some((source) => !source.staged);
|
|
9399
|
-
const structural = await Promise.all([
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9725
|
+
const [structural] = await Promise.all([
|
|
9726
|
+
Promise.all([
|
|
9727
|
+
write(join22(out, "astro.config.mjs"), astroConfigTemplate({
|
|
9728
|
+
aliases: resolveTsconfigAliases(context.root),
|
|
9729
|
+
config,
|
|
9730
|
+
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
9731
|
+
context,
|
|
9732
|
+
dataPath,
|
|
9733
|
+
examplesPath,
|
|
9734
|
+
examplesThemePath,
|
|
9735
|
+
needsReact,
|
|
9736
|
+
needsSvelte,
|
|
9737
|
+
needsVue,
|
|
9738
|
+
openapiPath,
|
|
9739
|
+
pages,
|
|
9740
|
+
reactCompilerPath,
|
|
9741
|
+
searchClientPath,
|
|
9742
|
+
themePath
|
|
9743
|
+
})),
|
|
9744
|
+
write(join22(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
|
|
9745
|
+
write(join22(out, "tsconfig.json"), runtimeTsconfigTemplate()),
|
|
9746
|
+
write(join22(srcDir, "env.d.ts"), envTemplate()),
|
|
9747
|
+
write(join22(srcDir, "content.config.ts"), contentConfigTemplate({
|
|
9748
|
+
collection: resolveDocsCollection(config, context),
|
|
9749
|
+
config,
|
|
9750
|
+
context,
|
|
9751
|
+
filesystem: hasFilesystemSource,
|
|
9752
|
+
staged: hasStaged
|
|
9753
|
+
})),
|
|
9754
|
+
write(join22(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
|
|
9755
|
+
askEnabled,
|
|
9756
|
+
exportEpub,
|
|
9757
|
+
exportPdf,
|
|
9758
|
+
mathEnabled: usesMath,
|
|
9759
|
+
needsReact
|
|
9760
|
+
})),
|
|
9761
|
+
write(join22(srcDir, "generated", "components.ts"), slotPlan.module),
|
|
9762
|
+
write(join22(srcDir, "generated", "islands.ts"), islandMapTemplate(islandDiscovery.islands)),
|
|
9763
|
+
write(join22(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples, config.basePath)),
|
|
9764
|
+
write(examplesThemePath, examplesEntryTemplate({
|
|
9765
|
+
configTokens: buildThemeCss(config.theme),
|
|
9766
|
+
sources: [`${context.root}/**/*.{astro,jsx,svelte,ts,tsx,vue}`],
|
|
9767
|
+
userCss: userExamplesCss
|
|
9768
|
+
})),
|
|
9769
|
+
write(themePath, tailwindEntryTemplate({
|
|
9770
|
+
configTokens: `${buildThemeCss(config.theme)}${buildFontsCss(config.theme.fonts)}`,
|
|
9771
|
+
sources: [
|
|
9772
|
+
`${BLUME_SRC}/**/*.{astro,ts,tsx}`,
|
|
9773
|
+
`${context.root}/**/*.{astro,mdx,ts,tsx}`
|
|
9774
|
+
],
|
|
9775
|
+
twoslashCss: twoslashCss(),
|
|
9776
|
+
userTheme
|
|
9777
|
+
}))
|
|
9778
|
+
]),
|
|
9779
|
+
Promise.all(islandDiscovery.islands.map((island) => write(join22(srcDir, "generated", "islands", `${island.name}.astro`), islandWrapperTemplate(island)))),
|
|
9780
|
+
Promise.all(slotPlan.wrappers.map((wrapper) => write(join22(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content))),
|
|
9781
|
+
Promise.all(exampleDiscovery.examples.map((example) => write(join22(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example)))),
|
|
9782
|
+
writeAskFiles(project, srcDir, write),
|
|
9783
|
+
writeMcpFiles(project, mcp, write)
|
|
9444
9784
|
]);
|
|
9445
|
-
await Promise.all(islandDiscovery.islands.map((island) => write(join22(srcDir, "generated", "islands", `${island.name}.astro`), islandWrapperTemplate(island))));
|
|
9446
|
-
await Promise.all(slotPlan.wrappers.map((wrapper) => write(join22(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content)));
|
|
9447
|
-
await Promise.all(exampleDiscovery.examples.map((example) => write(join22(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example))));
|
|
9448
|
-
await writeAskFiles(project, srcDir, write);
|
|
9449
|
-
await writeMcpFiles(project, mcp, write);
|
|
9450
9785
|
if (config.seo.og.enabled) {
|
|
9451
9786
|
await write(join22(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes));
|
|
9452
9787
|
}
|
|
@@ -9459,8 +9794,17 @@ var generateRuntime = async (project) => {
|
|
|
9459
9794
|
staged: hasStaged
|
|
9460
9795
|
}));
|
|
9461
9796
|
}
|
|
9462
|
-
|
|
9463
|
-
|
|
9797
|
+
const [examplesWarnings] = await Promise.all([
|
|
9798
|
+
writeExamplesPreview({
|
|
9799
|
+
config,
|
|
9800
|
+
hasExamples: exampleDiscovery.examples.length > 0,
|
|
9801
|
+
root: context.root,
|
|
9802
|
+
srcDir,
|
|
9803
|
+
write
|
|
9804
|
+
}),
|
|
9805
|
+
writeNotFoundPage(write, srcDir, pages, project.graph.pages),
|
|
9806
|
+
write(searchClientPath, searchClientTemplate(config))
|
|
9807
|
+
]);
|
|
9464
9808
|
if (servesStaticIndex(config.search.provider)) {
|
|
9465
9809
|
const documents = await buildSearchDocuments(project);
|
|
9466
9810
|
await write(join22(srcDir, "generated", "search.json"), `${JSON.stringify(documents)}
|
|
@@ -9488,9 +9832,11 @@ var generateRuntime = async (project) => {
|
|
|
9488
9832
|
}
|
|
9489
9833
|
const warnings = [
|
|
9490
9834
|
...depsLinkWarning ? [depsLinkWarning] : [],
|
|
9835
|
+
...reactCompilerWarnings(config, needsReact, reactCompilerPath),
|
|
9491
9836
|
...mcp.warnings,
|
|
9492
9837
|
...islandDiscovery.warnings,
|
|
9493
9838
|
...exampleDiscovery.warnings,
|
|
9839
|
+
...examplesWarnings,
|
|
9494
9840
|
...overrideWarnings
|
|
9495
9841
|
];
|
|
9496
9842
|
const navTargetRoutes = new Set([
|
|
@@ -9522,13 +9868,15 @@ var generateRuntime = async (project) => {
|
|
|
9522
9868
|
warnings.push(...references.warnings);
|
|
9523
9869
|
await Promise.all(references.files.map((file) => write(join22(srcDir, "pages", file.pagePath), file.content)));
|
|
9524
9870
|
}
|
|
9525
|
-
await write(join22(srcDir, "generated", "data.json"), buildRuntimeData(project));
|
|
9526
9871
|
const openApiSource2 = project.sources.find(isOpenApiSource);
|
|
9527
|
-
await
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
`)
|
|
9531
|
-
|
|
9872
|
+
await Promise.all([
|
|
9873
|
+
write(join22(srcDir, "generated", "data.json"), buildRuntimeData(project)),
|
|
9874
|
+
write(openapiPath, `${JSON.stringify(openApiSource2 ? openApiSource2.openApiData() : {})}
|
|
9875
|
+
`),
|
|
9876
|
+
write(join22(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
|
|
9877
|
+
`),
|
|
9878
|
+
writeStagedContent(out, staged)
|
|
9879
|
+
]);
|
|
9532
9880
|
await pruneOrphans(srcDir, written);
|
|
9533
9881
|
return { structuralChange: structural.some(Boolean), warnings };
|
|
9534
9882
|
};
|
|
@@ -9620,12 +9968,13 @@ var loadConfig = async (root, options = {}) => {
|
|
|
9620
9968
|
message: "Invalid Blume config.",
|
|
9621
9969
|
severity: "error"
|
|
9622
9970
|
};
|
|
9971
|
+
const moreIssues = rest.map((d) => ` - ${d.message}`).join(`
|
|
9972
|
+
`);
|
|
9623
9973
|
throw new BlumeError(rest.length > 0 ? {
|
|
9624
9974
|
...primary,
|
|
9625
9975
|
message: `${primary.message}
|
|
9626
9976
|
${rest.length} more config issue(s):
|
|
9627
|
-
${
|
|
9628
|
-
`)}`
|
|
9977
|
+
${moreIssues}`
|
|
9629
9978
|
} : primary);
|
|
9630
9979
|
}
|
|
9631
9980
|
const config = applyDeploymentEnv(parsed.data);
|
|
@@ -9650,7 +9999,7 @@ var WORD_SPLIT2 = /[-_]/u;
|
|
|
9650
9999
|
var humanize = (segment) => segment.replace(NUMERIC_PREFIX2, "").split(WORD_SPLIT2).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
9651
10000
|
var numericOrder = (segment) => {
|
|
9652
10001
|
const value = segment.match(NUMERIC_PREFIX2)?.groups?.order;
|
|
9653
|
-
return value ?
|
|
10002
|
+
return value ? Math.trunc(Number(value)) : Number.POSITIVE_INFINITY;
|
|
9654
10003
|
};
|
|
9655
10004
|
var segmentKey = (raw) => {
|
|
9656
10005
|
const group = raw.match(GROUP_FOLDER2)?.groups?.label;
|
|
@@ -9828,101 +10177,130 @@ var normalizeRef = (ref) => {
|
|
|
9828
10177
|
const trimmed = withSlash.endsWith("/index") ? withSlash.slice(0, -"/index".length) : withSlash;
|
|
9829
10178
|
return trimmed === "" ? "/" : trimmed;
|
|
9830
10179
|
};
|
|
9831
|
-
var routeForRef = (ref, byRoute) => {
|
|
10180
|
+
var routeForRef = (ref, byRoute, basePath) => {
|
|
9832
10181
|
if (!ref) {
|
|
9833
10182
|
return;
|
|
9834
10183
|
}
|
|
9835
10184
|
const normalized = normalizeRef(ref);
|
|
9836
|
-
return byRoute.get(normalized)?.route ?? normalized;
|
|
10185
|
+
return byRoute.get(normalized)?.route ?? withBasePath(basePath, normalized);
|
|
9837
10186
|
};
|
|
9838
|
-
var
|
|
10187
|
+
var configItemToNode = (item, byRoute, basePath) => {
|
|
10188
|
+
if (typeof item === "string") {
|
|
10189
|
+
const page = byRoute.get(normalizeRef(item));
|
|
10190
|
+
if (!page) {
|
|
10191
|
+
return null;
|
|
10192
|
+
}
|
|
10193
|
+
return {
|
|
10194
|
+
badge: page.meta.sidebar.badge,
|
|
10195
|
+
deprecated: page.meta.deprecated || undefined,
|
|
10196
|
+
description: page.description,
|
|
10197
|
+
icon: page.meta.sidebar.icon,
|
|
10198
|
+
kind: "page",
|
|
10199
|
+
label: page.meta.sidebar.label ?? page.title,
|
|
10200
|
+
pageId: page.id,
|
|
10201
|
+
route: page.route
|
|
10202
|
+
};
|
|
10203
|
+
}
|
|
10204
|
+
if (item.root) {
|
|
10205
|
+
const page = byRoute.get(normalizeRef(item.root));
|
|
10206
|
+
return {
|
|
10207
|
+
badge: item.badge,
|
|
10208
|
+
deprecated: page?.meta.deprecated || undefined,
|
|
10209
|
+
icon: item.icon,
|
|
10210
|
+
kind: "page",
|
|
10211
|
+
label: item.label,
|
|
10212
|
+
pageId: page?.id ?? "",
|
|
10213
|
+
route: page?.route ?? withBasePath(basePath, normalizeRef(item.root))
|
|
10214
|
+
};
|
|
10215
|
+
}
|
|
10216
|
+
if (item.href) {
|
|
10217
|
+
return {
|
|
10218
|
+
badge: item.badge,
|
|
10219
|
+
icon: item.icon,
|
|
10220
|
+
kind: "page",
|
|
10221
|
+
label: item.label,
|
|
10222
|
+
pageId: "",
|
|
10223
|
+
route: withBasePath(basePath, item.href)
|
|
10224
|
+
};
|
|
10225
|
+
}
|
|
10226
|
+
return null;
|
|
10227
|
+
};
|
|
10228
|
+
var buildConfigSidebar = (items, byRoute, display, basePath) => {
|
|
9839
10229
|
const nodes = [];
|
|
9840
10230
|
for (const item of items) {
|
|
9841
|
-
if (typeof item
|
|
9842
|
-
const page = byRoute.get(normalizeRef(item));
|
|
9843
|
-
if (page) {
|
|
9844
|
-
nodes.push({
|
|
9845
|
-
badge: page.meta.sidebar.badge,
|
|
9846
|
-
deprecated: page.meta.deprecated || undefined,
|
|
9847
|
-
description: page.description,
|
|
9848
|
-
icon: page.meta.sidebar.icon,
|
|
9849
|
-
kind: "page",
|
|
9850
|
-
label: page.meta.sidebar.label ?? page.title,
|
|
9851
|
-
pageId: page.id,
|
|
9852
|
-
route: page.route
|
|
9853
|
-
});
|
|
9854
|
-
}
|
|
9855
|
-
continue;
|
|
9856
|
-
}
|
|
9857
|
-
if (item.items) {
|
|
10231
|
+
if (typeof item !== "string" && item.items) {
|
|
9858
10232
|
nodes.push({
|
|
9859
10233
|
badge: item.badge,
|
|
9860
|
-
children: buildConfigSidebar(item.items, byRoute, display),
|
|
10234
|
+
children: buildConfigSidebar(item.items, byRoute, display, basePath),
|
|
9861
10235
|
collapsed: item.collapsed,
|
|
9862
10236
|
directory: item.directory,
|
|
9863
10237
|
display: item.display ?? display,
|
|
9864
10238
|
icon: item.icon,
|
|
9865
10239
|
kind: "group",
|
|
9866
10240
|
label: item.label,
|
|
9867
|
-
route: routeForRef(item.root, byRoute)
|
|
10241
|
+
route: routeForRef(item.root, byRoute, basePath)
|
|
9868
10242
|
});
|
|
9869
10243
|
continue;
|
|
9870
10244
|
}
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
nodes.push(
|
|
9874
|
-
badge: item.badge,
|
|
9875
|
-
deprecated: page?.meta.deprecated || undefined,
|
|
9876
|
-
icon: item.icon,
|
|
9877
|
-
kind: "page",
|
|
9878
|
-
label: item.label,
|
|
9879
|
-
pageId: page?.id ?? "",
|
|
9880
|
-
route: page?.route ?? normalizeRef(item.root)
|
|
9881
|
-
});
|
|
9882
|
-
continue;
|
|
9883
|
-
}
|
|
9884
|
-
if (item.href) {
|
|
9885
|
-
nodes.push({
|
|
9886
|
-
badge: item.badge,
|
|
9887
|
-
icon: item.icon,
|
|
9888
|
-
kind: "page",
|
|
9889
|
-
label: item.label,
|
|
9890
|
-
pageId: "",
|
|
9891
|
-
route: item.href
|
|
9892
|
-
});
|
|
10245
|
+
const node = configItemToNode(item, byRoute, basePath);
|
|
10246
|
+
if (node) {
|
|
10247
|
+
nodes.push(node);
|
|
9893
10248
|
}
|
|
9894
10249
|
}
|
|
9895
10250
|
return nodes;
|
|
9896
10251
|
};
|
|
9897
10252
|
var buildNavigation = (pages, options) => {
|
|
9898
|
-
const
|
|
9899
|
-
const selectors = options.selectors ?? [];
|
|
9900
|
-
const tabs = options.tabs ?? [];
|
|
10253
|
+
const basePath = options.basePath ?? "";
|
|
9901
10254
|
const display = options.display ?? "flat";
|
|
9902
10255
|
const metaPrefix = options.metaPrefix ?? "";
|
|
9903
10256
|
const sharedFolderMeta = options.sharedFolderMeta ?? new Map;
|
|
10257
|
+
const rebasePath = (item) => ({
|
|
10258
|
+
...item,
|
|
10259
|
+
path: withBasePath(basePath, item.path)
|
|
10260
|
+
});
|
|
10261
|
+
const featured = basePath ? (options.featured ?? []).map((link) => ({
|
|
10262
|
+
...link,
|
|
10263
|
+
href: withBasePath(basePath, link.href)
|
|
10264
|
+
})) : options.featured ?? [];
|
|
10265
|
+
const selectors = basePath ? (options.selectors ?? []).map((selector) => ({
|
|
10266
|
+
...selector,
|
|
10267
|
+
items: selector.items.map(rebasePath)
|
|
10268
|
+
})) : options.selectors ?? [];
|
|
10269
|
+
const tabs = basePath ? (options.tabs ?? []).map((tab) => ({
|
|
10270
|
+
...tab,
|
|
10271
|
+
items: tab.items?.map(rebasePath),
|
|
10272
|
+
path: withBasePath(basePath, tab.path)
|
|
10273
|
+
})) : options.tabs ?? [];
|
|
9904
10274
|
const byRoute = new Map(pages.map((page) => [
|
|
9905
10275
|
options.refByLogical ? page.translationKey : page.route,
|
|
9906
10276
|
page
|
|
9907
10277
|
]));
|
|
10278
|
+
if (basePath && !options.refByLogical) {
|
|
10279
|
+
for (const page of pages) {
|
|
10280
|
+
const bare = stripBasePath(basePath, page.route);
|
|
10281
|
+
if (!byRoute.has(bare)) {
|
|
10282
|
+
byRoute.set(bare, page);
|
|
10283
|
+
}
|
|
10284
|
+
}
|
|
10285
|
+
}
|
|
9908
10286
|
if (options.sidebar) {
|
|
9909
10287
|
return {
|
|
9910
10288
|
featured,
|
|
9911
10289
|
selectors,
|
|
9912
|
-
sidebar: buildConfigSidebar(options.sidebar, byRoute, display),
|
|
10290
|
+
sidebar: buildConfigSidebar(options.sidebar, byRoute, display, basePath),
|
|
9913
10291
|
tabs
|
|
9914
10292
|
};
|
|
9915
10293
|
}
|
|
9916
10294
|
return {
|
|
9917
10295
|
featured,
|
|
9918
10296
|
selectors,
|
|
9919
|
-
sidebar: buildFileSystemSidebar(pages, options.folderMeta, sharedFolderMeta, metaPrefix, display, new Set(tabs.
|
|
10297
|
+
sidebar: buildFileSystemSidebar(pages, options.folderMeta, sharedFolderMeta, metaPrefix, display, new Set(tabs.flatMap((tab) => tab.path === "/" ? [] : [tab.path]))),
|
|
9920
10298
|
tabs
|
|
9921
10299
|
};
|
|
9922
10300
|
};
|
|
9923
10301
|
|
|
9924
10302
|
// src/core/graph.ts
|
|
9925
|
-
var
|
|
10303
|
+
var collectRoutes = (pages) => {
|
|
9926
10304
|
const routes = new Map;
|
|
9927
10305
|
const diagnostics = [];
|
|
9928
10306
|
for (const page of pages) {
|
|
@@ -9939,60 +10317,73 @@ var buildContentGraph = (pages, options) => {
|
|
|
9939
10317
|
}
|
|
9940
10318
|
routes.set(page.route, page.id);
|
|
9941
10319
|
}
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
if (
|
|
9946
|
-
|
|
9947
|
-
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
10320
|
+
return { diagnostics, routes };
|
|
10321
|
+
};
|
|
10322
|
+
var localePagesFor = (code, real, fallback, fallbackByKey, i18n, basePath) => {
|
|
10323
|
+
if (!(fallback && code !== fallback)) {
|
|
10324
|
+
return real;
|
|
10325
|
+
}
|
|
10326
|
+
const present = new Set(real.map((page) => page.translationKey));
|
|
10327
|
+
const filled = [];
|
|
10328
|
+
for (const [key, source] of fallbackByKey) {
|
|
10329
|
+
if (!present.has(key)) {
|
|
10330
|
+
filled.push({
|
|
10331
|
+
...source,
|
|
10332
|
+
locale: code,
|
|
10333
|
+
route: withBasePath(basePath, localizeRoute(key, code, i18n))
|
|
10334
|
+
});
|
|
9954
10335
|
}
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
10336
|
+
}
|
|
10337
|
+
return [...real, ...filled];
|
|
10338
|
+
};
|
|
10339
|
+
var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n) => {
|
|
10340
|
+
const tabs = options.navigation.tabs?.map((tab) => ({
|
|
10341
|
+
...tab,
|
|
10342
|
+
path: tab.path.startsWith("/") ? localizeRoute(tab.path, code, i18n) : tab.path
|
|
10343
|
+
}));
|
|
10344
|
+
const real = pages.filter((page) => page.locale === code);
|
|
10345
|
+
const localePages = localePagesFor(code, real, fallback, fallbackByKey, i18n, options.basePath ?? "");
|
|
10346
|
+
return buildNavigation(localePages, {
|
|
10347
|
+
basePath: options.basePath ?? "",
|
|
10348
|
+
display: options.navigation.sidebar.display,
|
|
10349
|
+
featured: options.navigation.featured,
|
|
10350
|
+
folderMeta: options.folderMeta,
|
|
10351
|
+
metaPrefix: i18n.parser === "dir" && code !== i18n.defaultLocale ? code : "",
|
|
10352
|
+
refByLogical: true,
|
|
10353
|
+
selectors: options.navigation.selectors,
|
|
10354
|
+
sharedFolderMeta: options.sharedFolderMeta,
|
|
10355
|
+
sidebar: options.navigation.sidebar.items,
|
|
10356
|
+
tabs
|
|
10357
|
+
});
|
|
10358
|
+
};
|
|
10359
|
+
var buildI18nNavigation = (pages, options, i18n) => {
|
|
10360
|
+
const fallback = resolveFallbackLocale(i18n);
|
|
10361
|
+
const fallbackByKey = new Map;
|
|
10362
|
+
if (fallback) {
|
|
10363
|
+
for (const page of pages) {
|
|
10364
|
+
if (page.locale === fallback) {
|
|
10365
|
+
fallbackByKey.set(page.translationKey, page);
|
|
9975
10366
|
}
|
|
9976
|
-
navigationByLocale[code] = buildNavigation(localePages, {
|
|
9977
|
-
display: options.navigation.sidebar.display,
|
|
9978
|
-
featured: options.navigation.featured,
|
|
9979
|
-
folderMeta: options.folderMeta,
|
|
9980
|
-
metaPrefix: i18n.parser === "dir" && code !== i18n.defaultLocale ? code : "",
|
|
9981
|
-
refByLogical: true,
|
|
9982
|
-
selectors: options.navigation.selectors,
|
|
9983
|
-
sharedFolderMeta: options.sharedFolderMeta,
|
|
9984
|
-
sidebar: options.navigation.sidebar.items,
|
|
9985
|
-
tabs
|
|
9986
|
-
});
|
|
9987
10367
|
}
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
10368
|
+
}
|
|
10369
|
+
const navigationByLocale = {};
|
|
10370
|
+
for (const { code } of i18n.locales) {
|
|
10371
|
+
navigationByLocale[code] = buildLocaleNavigation(code, pages, fallback, fallbackByKey, options, i18n);
|
|
10372
|
+
}
|
|
10373
|
+
const navigation = navigationByLocale[i18n.defaultLocale] ?? {
|
|
10374
|
+
featured: [],
|
|
10375
|
+
selectors: [],
|
|
10376
|
+
sidebar: [],
|
|
10377
|
+
tabs: []
|
|
10378
|
+
};
|
|
10379
|
+
return { navigation, navigationByLocale };
|
|
10380
|
+
};
|
|
10381
|
+
var buildContentGraph = (pages, options) => {
|
|
10382
|
+
const { diagnostics, routes } = collectRoutes(pages);
|
|
10383
|
+
const { i18n } = options;
|
|
10384
|
+
const { navigation, navigationByLocale } = i18n ? buildI18nNavigation(pages, options, i18n) : {
|
|
10385
|
+
navigation: buildNavigation(pages, {
|
|
10386
|
+
basePath: options.basePath ?? "",
|
|
9996
10387
|
display: options.navigation.sidebar.display,
|
|
9997
10388
|
featured: options.navigation.featured,
|
|
9998
10389
|
folderMeta: options.folderMeta,
|
|
@@ -10000,10 +10391,10 @@ var buildContentGraph = (pages, options) => {
|
|
|
10000
10391
|
sharedFolderMeta: options.sharedFolderMeta,
|
|
10001
10392
|
sidebar: options.navigation.sidebar.items,
|
|
10002
10393
|
tabs: options.navigation.tabs
|
|
10003
|
-
})
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
diagnostics.push(...validateNavStructure(navigation, pages));
|
|
10394
|
+
}),
|
|
10395
|
+
navigationByLocale: {}
|
|
10396
|
+
};
|
|
10397
|
+
diagnostics.push(...validateNavIcons(navigation), ...validateNavStructure(navigation, pages));
|
|
10007
10398
|
return {
|
|
10008
10399
|
diagnostics,
|
|
10009
10400
|
navigation,
|
|
@@ -10200,11 +10591,8 @@ var scanProject = async (root, options = {}) => {
|
|
|
10200
10591
|
for (const source of sources) {
|
|
10201
10592
|
source.validate?.();
|
|
10202
10593
|
}
|
|
10203
|
-
const metaSources = sources.
|
|
10204
|
-
|
|
10205
|
-
root: source.contentRoot ?? ""
|
|
10206
|
-
}));
|
|
10207
|
-
const localeDirs = config.i18n && config.i18n.parser === "dir" ? config.i18n.locales.map((locale) => locale.code).filter((code) => code !== config.i18n?.defaultLocale) : undefined;
|
|
10594
|
+
const metaSources = sources.flatMap((source) => source.staged || !source.contentRoot ? [] : [{ prefix: source.prefix, root: source.contentRoot }]);
|
|
10595
|
+
const localeDirs = config.i18n && config.i18n.parser === "dir" ? config.i18n.locales.flatMap((locale) => locale.code === config.i18n?.defaultLocale ? [] : [locale.code]) : undefined;
|
|
10208
10596
|
const [loaded, folderMeta] = await Promise.all([
|
|
10209
10597
|
Promise.all(sources.map(async (source) => ({ source, ...await source.load() }))),
|
|
10210
10598
|
discoverFolderMeta(metaSources, { localeDirs })
|
|
@@ -10215,6 +10603,7 @@ var scanProject = async (root, options = {}) => {
|
|
|
10215
10603
|
contentDiagnostics.push(...diagnostics);
|
|
10216
10604
|
for (const entry of entries) {
|
|
10217
10605
|
const normalized = normalizeEntry2(entry, {
|
|
10606
|
+
basePath: config.basePath,
|
|
10218
10607
|
defaultType: config.content.defaultType,
|
|
10219
10608
|
i18n: config.i18n,
|
|
10220
10609
|
source: {
|
|
@@ -10239,6 +10628,7 @@ var scanProject = async (root, options = {}) => {
|
|
|
10239
10628
|
}
|
|
10240
10629
|
}
|
|
10241
10630
|
const graph = buildContentGraph(pages, {
|
|
10631
|
+
basePath: config.basePath,
|
|
10242
10632
|
folderMeta: folderMeta.meta,
|
|
10243
10633
|
i18n: config.i18n,
|
|
10244
10634
|
navigation: config.navigation,
|
|
@@ -10358,9 +10748,10 @@ var checkRequiredSecrets = (config) => {
|
|
|
10358
10748
|
if (process.env[env]) {
|
|
10359
10749
|
return;
|
|
10360
10750
|
}
|
|
10751
|
+
const noteSuffix = note ? ` (${note})` : "";
|
|
10361
10752
|
diagnostics.push({
|
|
10362
10753
|
code: "BLUME_MISSING_SECRET",
|
|
10363
|
-
message: `${feature} is enabled but ${env} is not set${
|
|
10754
|
+
message: `${feature} is enabled but ${env} is not set${noteSuffix}.`,
|
|
10364
10755
|
severity: "warning",
|
|
10365
10756
|
suggestion: `Set ${env} in .env.local for local dev, or in your host's environment for production.`
|
|
10366
10757
|
});
|
|
@@ -10432,17 +10823,20 @@ var prepareProject = async (options) => {
|
|
|
10432
10823
|
|
|
10433
10824
|
// src/cli/commands/build.ts
|
|
10434
10825
|
var ADAPTERS = ["vercel", "node", "netlify", "cloudflare"];
|
|
10826
|
+
var BUDGET_JS = "budget-js";
|
|
10827
|
+
var BUDGET_CSS = "budget-css";
|
|
10435
10828
|
var validateBudgetFlags = (args) => {
|
|
10436
|
-
for (const flag of [
|
|
10829
|
+
for (const flag of [BUDGET_JS, BUDGET_CSS]) {
|
|
10437
10830
|
const value = args[flag];
|
|
10438
|
-
|
|
10831
|
+
const parsed = Number(value);
|
|
10832
|
+
if (value !== undefined && (Number.isNaN(parsed) || parsed <= 0)) {
|
|
10439
10833
|
logger.error(`Invalid --${flag} "${value}" (expected a positive number of kB).`);
|
|
10440
10834
|
process.exit(1);
|
|
10441
10835
|
}
|
|
10442
10836
|
}
|
|
10443
10837
|
};
|
|
10444
10838
|
var emitRedirectFiles = async (config, distDir) => {
|
|
10445
|
-
const
|
|
10839
|
+
const redirects = applyBaseToRedirects(config.redirects, config.basePath);
|
|
10446
10840
|
if (redirects.length === 0 || config.deployment.output !== "static") {
|
|
10447
10841
|
return;
|
|
10448
10842
|
}
|
|
@@ -10454,7 +10848,13 @@ var emitRedirectFiles = async (config, distDir) => {
|
|
|
10454
10848
|
await Promise.all(platformFiles.map((file) => existsSync15(join24(distDir, file.name)) ? Promise.resolve() : writeFile7(join24(distDir, file.name), file.content, "utf-8")));
|
|
10455
10849
|
logger.success(`Emitted redirect files for ${redirects.length} redirect(s)`);
|
|
10456
10850
|
};
|
|
10457
|
-
var formatBytes = (bytes) =>
|
|
10851
|
+
var formatBytes = (bytes) => {
|
|
10852
|
+
if (bytes < 1024) {
|
|
10853
|
+
return `${bytes} B`;
|
|
10854
|
+
}
|
|
10855
|
+
const digits = bytes < 1024 * 100 ? 1 : 0;
|
|
10856
|
+
return `${(bytes / 1024).toFixed(digits)} kB`;
|
|
10857
|
+
};
|
|
10458
10858
|
var astroAssets = async (distDir, ext) => {
|
|
10459
10859
|
const astroDir = join24(distDir, "_astro");
|
|
10460
10860
|
if (!existsSync15(astroDir)) {
|
|
@@ -10486,8 +10886,8 @@ var reportBundleSizes = async (distDir) => {
|
|
|
10486
10886
|
};
|
|
10487
10887
|
var enforceBudget = async (distDir, args) => {
|
|
10488
10888
|
const checks = [
|
|
10489
|
-
...args[
|
|
10490
|
-
...args[
|
|
10889
|
+
...args[BUDGET_JS] ? [{ ext: "js", limitKb: Number(args[BUDGET_JS]), name: "JavaScript" }] : [],
|
|
10890
|
+
...args[BUDGET_CSS] ? [{ ext: "css", limitKb: Number(args[BUDGET_CSS]), name: "CSS" }] : []
|
|
10491
10891
|
];
|
|
10492
10892
|
if (checks.length === 0) {
|
|
10493
10893
|
return "skip";
|
|
@@ -10578,11 +10978,11 @@ var buildCommand = defineCommand2({
|
|
|
10578
10978
|
description: "Base path the site is served under (e.g. /docs).",
|
|
10579
10979
|
type: "string"
|
|
10580
10980
|
},
|
|
10581
|
-
|
|
10981
|
+
[BUDGET_CSS]: {
|
|
10582
10982
|
description: "Fail if total client CSS exceeds this many kB.",
|
|
10583
10983
|
type: "string"
|
|
10584
10984
|
},
|
|
10585
|
-
|
|
10985
|
+
[BUDGET_JS]: {
|
|
10586
10986
|
description: "Fail if total client JavaScript exceeds this many kB.",
|
|
10587
10987
|
type: "string"
|
|
10588
10988
|
},
|
|
@@ -10718,14 +11118,20 @@ import { defineCommand as defineCommand4 } from "citty";
|
|
|
10718
11118
|
var overlayServer = null;
|
|
10719
11119
|
var overlayChannel = () => overlayServer?.ws ?? overlayServer?.hot;
|
|
10720
11120
|
var showBlumeErrorOverlay = (diagnostics) => {
|
|
10721
|
-
const errors =
|
|
11121
|
+
const errors = [];
|
|
11122
|
+
for (const diagnostic of diagnostics) {
|
|
11123
|
+
if (diagnostic.severity === "error") {
|
|
11124
|
+
errors.push(enrichDiagnostic(diagnostic));
|
|
11125
|
+
}
|
|
11126
|
+
}
|
|
10722
11127
|
const channel = overlayChannel();
|
|
10723
11128
|
if (errors.length === 0 || !channel) {
|
|
10724
11129
|
return;
|
|
10725
11130
|
}
|
|
10726
11131
|
const body = errors.map((diagnostic) => {
|
|
11132
|
+
const lineSuffix = diagnostic.line ? `:${diagnostic.line}` : "";
|
|
10727
11133
|
const where = diagnostic.file ? `
|
|
10728
|
-
at ${diagnostic.file}${
|
|
11134
|
+
at ${diagnostic.file}${lineSuffix}` : "";
|
|
10729
11135
|
const fix = diagnostic.suggestion ? `
|
|
10730
11136
|
fix: ${diagnostic.suggestion}` : "";
|
|
10731
11137
|
const docs = diagnostic.docsUrl ? `
|
|
@@ -10785,6 +11191,8 @@ var coalescedRunner = (task) => {
|
|
|
10785
11191
|
};
|
|
10786
11192
|
|
|
10787
11193
|
// src/cli/commands/dev.ts
|
|
11194
|
+
var routeSignature = (routes) => routes.map((route) => `${route.path} ${route.entryId}`).toSorted().join(`
|
|
11195
|
+
`);
|
|
10788
11196
|
var devCommand = defineCommand4({
|
|
10789
11197
|
args: {
|
|
10790
11198
|
"content-dir": {
|
|
@@ -10835,21 +11243,19 @@ var devCommand = defineCommand4({
|
|
|
10835
11243
|
root,
|
|
10836
11244
|
strict: args.strict
|
|
10837
11245
|
});
|
|
10838
|
-
const
|
|
11246
|
+
const createServer = (listenPort, open) => dev({
|
|
10839
11247
|
logLevel: args.debug ? "debug" : "info",
|
|
10840
11248
|
root: project.context.outDir,
|
|
10841
|
-
server: {
|
|
10842
|
-
host: args.host ?? false,
|
|
10843
|
-
open: args.open ?? false,
|
|
10844
|
-
port: explicitPort
|
|
10845
|
-
}
|
|
11249
|
+
server: { host: args.host ?? false, open, port: listenPort }
|
|
10846
11250
|
});
|
|
11251
|
+
let server = await createServer(explicitPort, args.open ?? false);
|
|
10847
11252
|
const boundPort = server.address.port;
|
|
10848
11253
|
if (boundPort !== port) {
|
|
10849
11254
|
updateDevLockPort(outDir, boundPort);
|
|
10850
11255
|
devServerUrl = `http://localhost:${boundPort}`;
|
|
10851
11256
|
}
|
|
10852
11257
|
showBlumeErrorOverlay(project.diagnostics);
|
|
11258
|
+
let lastSignature = routeSignature(project.manifest.routes);
|
|
10853
11259
|
const runRegenerate = coalescedRunner(async () => {
|
|
10854
11260
|
try {
|
|
10855
11261
|
const next = await scanProject(root, {
|
|
@@ -10858,7 +11264,16 @@ var devCommand = defineCommand4({
|
|
|
10858
11264
|
overrides,
|
|
10859
11265
|
preview
|
|
10860
11266
|
});
|
|
10861
|
-
|
|
11267
|
+
const nextSignature = routeSignature(next.manifest.routes);
|
|
11268
|
+
const structural = nextSignature !== lastSignature;
|
|
11269
|
+
lastSignature = nextSignature;
|
|
11270
|
+
if (structural) {
|
|
11271
|
+
await server.stop();
|
|
11272
|
+
await generateRuntime(next);
|
|
11273
|
+
server = await createServer(boundPort, false);
|
|
11274
|
+
} else {
|
|
11275
|
+
await generateRuntime(next);
|
|
11276
|
+
}
|
|
10862
11277
|
showBlumeErrorOverlay(next.diagnostics);
|
|
10863
11278
|
} catch (error) {
|
|
10864
11279
|
logger.error(`Regeneration failed: ${error.message}`);
|
|
@@ -10916,8 +11331,8 @@ var minSupportedNode = () => {
|
|
|
10916
11331
|
}
|
|
10917
11332
|
};
|
|
10918
11333
|
var versionBelow = (current, minimum) => {
|
|
10919
|
-
const a = current.split(".").map((part) =>
|
|
10920
|
-
const b = minimum.split(".").map((part) =>
|
|
11334
|
+
const a = current.split(".").map((part) => Math.trunc(Number(part)));
|
|
11335
|
+
const b = minimum.split(".").map((part) => Math.trunc(Number(part)));
|
|
10921
11336
|
for (let i = 0;i < 3; i += 1) {
|
|
10922
11337
|
const delta = (a[i] ?? 0) - (b[i] ?? 0);
|
|
10923
11338
|
if (delta !== 0) {
|
|
@@ -11008,7 +11423,7 @@ import { join as join28, relative as relative13 } from "pathe";
|
|
|
11008
11423
|
import { existsSync as existsSync17 } from "node:fs";
|
|
11009
11424
|
import { cp as cp2, mkdir as mkdir7, readFile as readFile12, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
|
|
11010
11425
|
import { join as join27, relative as relative12 } from "pathe";
|
|
11011
|
-
var
|
|
11426
|
+
var toPosix = (path) => path.split("\\").join("/");
|
|
11012
11427
|
var ejectOpenApiData = (project) => {
|
|
11013
11428
|
const source = project.sources.find(isOpenApiSource);
|
|
11014
11429
|
return source ? source.openApiData() : {};
|
|
@@ -11034,6 +11449,13 @@ var askFiles = async (project, srcDir, genDir) => {
|
|
|
11034
11449
|
}
|
|
11035
11450
|
return files;
|
|
11036
11451
|
};
|
|
11452
|
+
var readExamplesCss = (root, css) => css && existsSync17(join27(root, css)) ? readFile12(join27(root, css), "utf-8") : Promise.resolve("");
|
|
11453
|
+
var examplesPreviewFiles = (srcDir, basePath, hasExamples) => hasExamples ? [
|
|
11454
|
+
{
|
|
11455
|
+
content: examplesPageTemplate(),
|
|
11456
|
+
path: join27(srcDir, "pages", ...basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro")
|
|
11457
|
+
}
|
|
11458
|
+
] : [];
|
|
11037
11459
|
var eject = async (root) => {
|
|
11038
11460
|
const project = await scanProject(root, { mode: "build" });
|
|
11039
11461
|
const { context, config } = project;
|
|
@@ -11047,6 +11469,7 @@ var eject = async (root) => {
|
|
|
11047
11469
|
needsReactRaw,
|
|
11048
11470
|
usesMath,
|
|
11049
11471
|
userTheme,
|
|
11472
|
+
userExamplesCss,
|
|
11050
11473
|
rawMarkdown,
|
|
11051
11474
|
islands,
|
|
11052
11475
|
examples
|
|
@@ -11055,9 +11478,10 @@ var eject = async (root) => {
|
|
|
11055
11478
|
detectNeedsReact(root),
|
|
11056
11479
|
detectUsesMath(root),
|
|
11057
11480
|
context.themeFile ? readFile12(context.themeFile, "utf-8") : Promise.resolve(""),
|
|
11481
|
+
readExamplesCss(root, config.examples.css),
|
|
11058
11482
|
buildRawMarkdown(project),
|
|
11059
11483
|
discoverIslands(root),
|
|
11060
|
-
discoverExamples(root, config.examples)
|
|
11484
|
+
discoverExamples(root, config.examples.source)
|
|
11061
11485
|
]);
|
|
11062
11486
|
const frameworks = new Set([
|
|
11063
11487
|
...islands.islands.map((island) => island.framework),
|
|
@@ -11068,13 +11492,13 @@ var eject = async (root) => {
|
|
|
11068
11492
|
const needsSvelte = frameworks.has("svelte");
|
|
11069
11493
|
const relContext = {
|
|
11070
11494
|
...context,
|
|
11071
|
-
contentRoot:
|
|
11495
|
+
contentRoot: toPosix(relative12(root, context.contentRoot)),
|
|
11072
11496
|
outDir: ".",
|
|
11073
11497
|
root: "."
|
|
11074
11498
|
};
|
|
11075
|
-
const componentsImport = context.componentsFile ? `../../${
|
|
11499
|
+
const componentsImport = context.componentsFile ? `../../${toPosix(relative12(root, context.componentsFile))}` : null;
|
|
11076
11500
|
const relPages = pages.map((page) => ({
|
|
11077
|
-
entrypoint:
|
|
11501
|
+
entrypoint: toPosix(relative12(root, page.entrypoint)),
|
|
11078
11502
|
pattern: page.pattern
|
|
11079
11503
|
}));
|
|
11080
11504
|
const staged = collectStaged(project);
|
|
@@ -11088,6 +11512,7 @@ var eject = async (root) => {
|
|
|
11088
11512
|
context: relContext,
|
|
11089
11513
|
dataPath: "./src/generated/data.json",
|
|
11090
11514
|
examplesPath: "./src/generated/examples.ts",
|
|
11515
|
+
examplesThemePath: "./src/generated/examples.css",
|
|
11091
11516
|
needsReact,
|
|
11092
11517
|
needsSvelte,
|
|
11093
11518
|
needsVue,
|
|
@@ -11132,9 +11557,17 @@ var eject = async (root) => {
|
|
|
11132
11557
|
path: join27(genDir, "islands.ts")
|
|
11133
11558
|
},
|
|
11134
11559
|
{
|
|
11135
|
-
content: exampleMapTemplate(examples.examples),
|
|
11560
|
+
content: exampleMapTemplate(examples.examples, config.basePath),
|
|
11136
11561
|
path: join27(genDir, "examples.ts")
|
|
11137
11562
|
},
|
|
11563
|
+
{
|
|
11564
|
+
content: examplesEntryTemplate({
|
|
11565
|
+
configTokens: buildThemeCss(config.theme),
|
|
11566
|
+
sources: ["../../**/*.{astro,jsx,svelte,ts,tsx,vue}"],
|
|
11567
|
+
userCss: userExamplesCss
|
|
11568
|
+
}),
|
|
11569
|
+
path: join27(genDir, "examples.css")
|
|
11570
|
+
},
|
|
11138
11571
|
{
|
|
11139
11572
|
content: tailwindEntryTemplate({
|
|
11140
11573
|
configTokens: buildThemeCss(config.theme),
|
|
@@ -11234,7 +11667,7 @@ var eject = async (root) => {
|
|
|
11234
11667
|
})), ...examples.examples.map((example) => ({
|
|
11235
11668
|
content: exampleWrapperTemplate(example),
|
|
11236
11669
|
path: join27(genDir, "examples", `${exampleSlug(example.path)}.astro`)
|
|
11237
|
-
})));
|
|
11670
|
+
})), ...examplesPreviewFiles(srcDir, config.basePath, examples.examples.length > 0));
|
|
11238
11671
|
for (const [entryId, content] of staged) {
|
|
11239
11672
|
files.push({ content, path: join27(root, stagedDir, entryId) });
|
|
11240
11673
|
}
|
|
@@ -11621,20 +12054,23 @@ var isIndexPage = (page2) => {
|
|
|
11621
12054
|
const ref = page2.source?.ref ?? page2.sourcePath ?? "";
|
|
11622
12055
|
return /^index\.(?:md|mdx)$/iu.test(basename5(ref));
|
|
11623
12056
|
};
|
|
12057
|
+
var applyRelativePart = (segments, part) => {
|
|
12058
|
+
if (part === "" || part === ".") {
|
|
12059
|
+
return;
|
|
12060
|
+
}
|
|
12061
|
+
if (part === "..") {
|
|
12062
|
+
segments.pop();
|
|
12063
|
+
return;
|
|
12064
|
+
}
|
|
12065
|
+
segments.push(part);
|
|
12066
|
+
};
|
|
11624
12067
|
var resolveRelative = (pageRoute, target, isIndex) => {
|
|
11625
12068
|
const segments = pageRoute.split("/").filter(Boolean);
|
|
11626
12069
|
if (!isIndex) {
|
|
11627
12070
|
segments.pop();
|
|
11628
12071
|
}
|
|
11629
12072
|
for (const part of target.split("/")) {
|
|
11630
|
-
|
|
11631
|
-
continue;
|
|
11632
|
-
}
|
|
11633
|
-
if (part === "..") {
|
|
11634
|
-
segments.pop();
|
|
11635
|
-
continue;
|
|
11636
|
-
}
|
|
11637
|
-
segments.push(part);
|
|
12073
|
+
applyRelativePart(segments, part);
|
|
11638
12074
|
}
|
|
11639
12075
|
return `/${segments.join("/")}`;
|
|
11640
12076
|
};
|
|
@@ -11667,15 +12103,16 @@ var checkAnchor = (route, fragment, site, ctx) => {
|
|
|
11667
12103
|
};
|
|
11668
12104
|
};
|
|
11669
12105
|
var checkPathLink = (resolved, fragment, target, site, ctx) => {
|
|
11670
|
-
const route = toRoute(resolved);
|
|
12106
|
+
const route = toRoute(withBasePath(ctx.basePath, resolved));
|
|
11671
12107
|
if (ctx.routes.has(route)) {
|
|
11672
12108
|
return fragment ? checkAnchor(route, fragment, site, ctx) : null;
|
|
11673
12109
|
}
|
|
11674
12110
|
if (ctx.redirects.has(route)) {
|
|
11675
12111
|
return null;
|
|
11676
12112
|
}
|
|
11677
|
-
|
|
11678
|
-
|
|
12113
|
+
const assetPath = stripBasePath(ctx.basePath, resolved);
|
|
12114
|
+
if (FILE_EXT.test(assetPath) && !DOC_EXT.test(assetPath)) {
|
|
12115
|
+
if (assetIsPresent(assetPath, ctx)) {
|
|
11679
12116
|
return null;
|
|
11680
12117
|
}
|
|
11681
12118
|
if (ctx.publicDir === null) {
|
|
@@ -11684,9 +12121,9 @@ var checkPathLink = (resolved, fragment, target, site, ctx) => {
|
|
|
11684
12121
|
return {
|
|
11685
12122
|
...site,
|
|
11686
12123
|
code: "BLUME_BROKEN_ASSET",
|
|
11687
|
-
message: `Asset ${
|
|
12124
|
+
message: `Asset ${assetPath} was not found in the public directory.`,
|
|
11688
12125
|
severity: "warning",
|
|
11689
|
-
suggestion: `Add the file at public${
|
|
12126
|
+
suggestion: `Add the file at public${assetPath} or fix the link.`
|
|
11690
12127
|
};
|
|
11691
12128
|
}
|
|
11692
12129
|
return {
|
|
@@ -11721,7 +12158,8 @@ var request = async (url, method) => {
|
|
|
11721
12158
|
};
|
|
11722
12159
|
var probe = async (url) => {
|
|
11723
12160
|
const head = await request(url, "HEAD");
|
|
11724
|
-
const
|
|
12161
|
+
const unreachable = !head.ok && head.status === undefined && !head.timedOut;
|
|
12162
|
+
const retry = head.status === STATUS_METHOD_NOT_ALLOWED || head.status === STATUS_NOT_IMPLEMENTED || unreachable;
|
|
11725
12163
|
return retry ? await request(url, "GET") : head;
|
|
11726
12164
|
};
|
|
11727
12165
|
var gradeExternal = (result) => {
|
|
@@ -11802,10 +12240,12 @@ var classifyLink = (page2, link, ctx, onExternal) => {
|
|
|
11802
12240
|
return checkPathLink(resolved, fragment, target, site, ctx);
|
|
11803
12241
|
};
|
|
11804
12242
|
var validateLinks = async (graph, options) => {
|
|
12243
|
+
const basePath = options.basePath ?? "";
|
|
11805
12244
|
const ctx = {
|
|
11806
12245
|
anchors: buildAnchorIndex(graph.pages),
|
|
12246
|
+
basePath,
|
|
11807
12247
|
publicDir: options.publicDir,
|
|
11808
|
-
redirects: new Set((options.redirects ?? []).map((redirect) => toRoute(redirect.from))),
|
|
12248
|
+
redirects: new Set((options.redirects ?? []).map((redirect) => toRoute(withBasePath(basePath, redirect.from)))),
|
|
11809
12249
|
routes: new Set(graph.routes.keys())
|
|
11810
12250
|
};
|
|
11811
12251
|
const diagnostics = [];
|
|
@@ -11862,6 +12302,7 @@ var validateCommand = defineCommand10({
|
|
|
11862
12302
|
diagnostics.push(...project.diagnostics);
|
|
11863
12303
|
const publicDir = join33(root, "public");
|
|
11864
12304
|
diagnostics.push(...await validateLinks(project.graph, {
|
|
12305
|
+
basePath: project.config.basePath,
|
|
11865
12306
|
checkExternal: Boolean(args.external),
|
|
11866
12307
|
publicDir: existsSync21(publicDir) ? publicDir : null,
|
|
11867
12308
|
redirects: project.config.redirects
|
|
@@ -11923,5 +12364,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
11923
12364
|
});
|
|
11924
12365
|
runMain(main);
|
|
11925
12366
|
|
|
11926
|
-
//# debugId=
|
|
12367
|
+
//# debugId=8E29DA45BB5B37C564756E2164756E21
|
|
11927
12368
|
//# sourceMappingURL=index.js.map
|