blume 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cli/index.js +319 -91
- package/dist/cli/index.js.map +18 -18
- package/dist/types/ai/component-markdown.d.ts +12 -1
- package/dist/types/core/config-input.d.ts +18 -8
- package/dist/types/core/schema.d.ts +38 -24
- package/dist/types/core/types.d.ts +14 -0
- package/dist/types/markdown/themes.d.ts +21 -0
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/configuration/ai.mdx +2 -2
- package/docs/configuration/index.mdx +1 -1
- package/docs/configuration/seo.mdx +16 -0
- package/docs/content/components.mdx +1 -1
- package/docs/content/navigation.mdx +4 -0
- package/docs/content/syntax.mdx +14 -0
- package/docs/reference/cli.mdx +1 -1
- package/docs/reference/frontmatter.mdx +2 -0
- package/package.json +2 -1
- package/src/ai/component-markdown.ts +39 -11
- package/src/ai/llms.ts +4 -2
- package/src/ai/markdown.ts +5 -1
- package/src/astro/generate.ts +121 -32
- package/src/astro/pages.ts +21 -5
- package/src/astro/templates.ts +70 -7
- package/src/audit/checks/llms.ts +4 -1
- package/src/cli/commands/build.ts +13 -1
- package/src/cli/prepare.ts +10 -2
- package/src/components/content/Component.astro +99 -6
- package/src/components/content/diff.ts +53 -4
- package/src/components/layout/RootLayout.astro +9 -1
- package/src/components/layout/nav-utils.ts +18 -7
- package/src/core/config-input.ts +18 -8
- package/src/core/diagnostics.ts +2 -0
- package/src/core/graph.ts +23 -4
- package/src/core/navigation.ts +180 -21
- package/src/core/project-graph.ts +54 -28
- package/src/core/schema.ts +39 -2
- package/src/core/sources/github-releases.ts +65 -2
- package/src/core/types.ts +14 -0
- package/src/markdown/index.ts +3 -0
- package/src/markdown/inline-code.ts +1 -1
- package/src/markdown/themes.ts +7 -2
- package/src/markdown/twoslash.ts +60 -0
- package/src/registry/eject.ts +3 -1
- /package/docs/{03-faq.mdx → 07-faq.mdx} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -308,12 +308,14 @@ var DOCS_PATHS = {
|
|
|
308
308
|
BLUME_CONTENT_ROOT_MISSING: DOCS_CONTENT_SOURCES,
|
|
309
309
|
BLUME_DEAD_LINK: DOCS_REFERENCE_CLI,
|
|
310
310
|
BLUME_DUPLICATE_ROUTE: DOCS_CONTENT_NAVIGATION,
|
|
311
|
+
BLUME_DUPLICATE_SIDEBAR_ORDER: DOCS_CONTENT_NAVIGATION,
|
|
311
312
|
BLUME_FRONTMATTER_INVALID: "/docs/reference/frontmatter",
|
|
312
313
|
BLUME_META_INVALID: "/docs/content/meta",
|
|
313
314
|
BLUME_META_LOAD_FAILED: "/docs/content/meta",
|
|
314
315
|
BLUME_MISSING_SECRET: DOCS_DEPLOYMENT,
|
|
315
316
|
BLUME_NAV_DUPLICATE_LABEL: DOCS_CONTENT_NAVIGATION,
|
|
316
317
|
BLUME_NAV_HIDDEN_IN_SIDEBAR: DOCS_CONTENT_NAVIGATION,
|
|
318
|
+
BLUME_NAV_INDEX_TITLE_MISMATCH: DOCS_CONTENT_NAVIGATION,
|
|
317
319
|
BLUME_NAV_MISSING_PAGE: DOCS_CONTENT_NAVIGATION,
|
|
318
320
|
BLUME_NODE_VERSION: "/docs/quickstart",
|
|
319
321
|
BLUME_SERVER_FEATURE_REQUIRED: DOCS_DEPLOYMENT,
|
|
@@ -2301,7 +2303,7 @@ var llmsChecks = {
|
|
|
2301
2303
|
continue;
|
|
2302
2304
|
}
|
|
2303
2305
|
listed.add(path);
|
|
2304
|
-
if (!context.byUrl.has(path)) {
|
|
2306
|
+
if (!context.byUrl.has(path) && !context.files.has(path)) {
|
|
2305
2307
|
found.push(finding("BLUME_AUDIT_LLMS_TXT_STALE_ENTRY", { file: llms.file, line: entry.line, url: entry.url }, `llms.txt lists ${path}, which the build does not serve.`));
|
|
2306
2308
|
}
|
|
2307
2309
|
}
|
|
@@ -3531,9 +3533,7 @@ var astroConfigTemplate = (options) => {
|
|
|
3531
3533
|
];
|
|
3532
3534
|
const blumeImport = `import { ${blumeImports.join(", ")} } from "blume/astro";
|
|
3533
3535
|
`;
|
|
3534
|
-
const
|
|
3535
|
-
`;
|
|
3536
|
-
const twoslashTransformer = "transformerTwoslash({ explicitTrigger: true }), ";
|
|
3536
|
+
const twoslashTransformer = "blumeTwoslashTransformer(), ";
|
|
3537
3537
|
const deployBase = normalizeBasePath(deployment.base);
|
|
3538
3538
|
const integrations = [
|
|
3539
3539
|
`mdx({ processor: blumeMdxProcessor(${JSON.stringify({
|
|
@@ -3557,8 +3557,8 @@ var astroConfigTemplate = (options) => {
|
|
|
3557
3557
|
${defineConfigImport}
|
|
3558
3558
|
import mdx from "@astrojs/mdx";
|
|
3559
3559
|
import tailwindcss from "@tailwindcss/vite";
|
|
3560
|
-
import { blumeMarkdownProcessor, blumeMdxProcessor, blumeShikiTransformers } from "blume/markdown";
|
|
3561
|
-
${
|
|
3560
|
+
import { blumeMarkdownProcessor, blumeMdxProcessor, blumeShikiTransformers, blumeTwoslashTransformer } from "blume/markdown";
|
|
3561
|
+
${reactImport}${vueImport}${svelteImport}${blumeImport}${adapterImport}
|
|
3562
3562
|
export default defineConfig({
|
|
3563
3563
|
root: ${JSON.stringify(context.outDir)},
|
|
3564
3564
|
srcDir: ${JSON.stringify(`${context.outDir}/src`)},
|
|
@@ -3986,7 +3986,9 @@ import data from "blume:data";
|
|
|
3986
3986
|
export const prerender = true;
|
|
3987
3987
|
|
|
3988
3988
|
// Custom (non-content) pages opted into a generated card, baked in at build.
|
|
3989
|
-
|
|
3989
|
+
// The annotation keeps the empty-array case from being an implicit any[]
|
|
3990
|
+
// (ts(7034)) under a strict tsconfig.
|
|
3991
|
+
const customRoutes: { slug: string; title: string }[] = ${JSON.stringify(customRoutes)};
|
|
3990
3992
|
|
|
3991
3993
|
export function getStaticPaths() {
|
|
3992
3994
|
const seen = new Set<string>();
|
|
@@ -4651,9 +4653,16 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
|
|
|
4651
4653
|
</PageLayout>
|
|
4652
4654
|
`;
|
|
4653
4655
|
var islandDirective = (spec) => spec.client === "only" ? `client:only="${spec.framework}"` : `client:${spec.client}`;
|
|
4656
|
+
var wrapperPropsType = (name) => `type Props = typeof ${name} extends (
|
|
4657
|
+
props: infer P extends object,
|
|
4658
|
+
...rest: never[]
|
|
4659
|
+
) => unknown
|
|
4660
|
+
? P
|
|
4661
|
+
: Record<string, unknown>;`;
|
|
4654
4662
|
var islandWrapperTemplate = (spec) => `---
|
|
4655
4663
|
// Generated by Blume. Do not edit.
|
|
4656
4664
|
import Island from ${JSON.stringify(spec.file)};
|
|
4665
|
+
${wrapperPropsType("Island")}
|
|
4657
4666
|
---
|
|
4658
4667
|
<Island ${islandDirective(spec)} {...Astro.props}><slot /></Island>
|
|
4659
4668
|
`;
|
|
@@ -4684,6 +4693,7 @@ var exampleSlug = (path) => path.replaceAll(/[^a-zA-Z0-9]/gu, (char) => `_${(cha
|
|
|
4684
4693
|
var exampleWrapperTemplate = (spec) => `---
|
|
4685
4694
|
// Generated by Blume. Do not edit.
|
|
4686
4695
|
import Example from ${JSON.stringify(spec.file)};
|
|
4696
|
+
${wrapperPropsType("Example")}
|
|
4687
4697
|
---
|
|
4688
4698
|
<Example ${exampleDirective(spec)}{...Astro.props}><slot /></Example>
|
|
4689
4699
|
`;
|
|
@@ -4760,7 +4770,42 @@ const Example = entry.Component;
|
|
|
4760
4770
|
<!-- Flex + margin:auto centers the example and, unlike place-items, keeps
|
|
4761
4771
|
the top edge reachable when the example outgrows the frame. -->
|
|
4762
4772
|
<body style="display:flex;min-height:100svh;padding:1.5rem">
|
|
4763
|
-
<div style="margin:auto"><Example /></div>
|
|
4773
|
+
<div data-blume-example style="margin:auto"><Example /></div>
|
|
4774
|
+
<script is:inline>
|
|
4775
|
+
(() => {
|
|
4776
|
+
// Report the example's rendered height so the embedding docs page can
|
|
4777
|
+
// size the preview pane to the content. The wrapper is observed rather
|
|
4778
|
+
// than the body: the body stretches to the frame's own height, so it
|
|
4779
|
+
// would only echo the pane back. Direct opens have no distinct parent
|
|
4780
|
+
// and skip out; the frame is same-origin with the docs page (see the
|
|
4781
|
+
// theme sync above), so the origin is pinned on both ends.
|
|
4782
|
+
if (window.parent === window) {
|
|
4783
|
+
return;
|
|
4784
|
+
}
|
|
4785
|
+
const wrapper = document.querySelector("[data-blume-example]");
|
|
4786
|
+
if (!wrapper) {
|
|
4787
|
+
return;
|
|
4788
|
+
}
|
|
4789
|
+
// The body's padding frames the example; fold it into the report so
|
|
4790
|
+
// the parent can apply the number as-is. Read from the live value —
|
|
4791
|
+
// the user's examples.css is injected after Blume's defaults precisely
|
|
4792
|
+
// so their tokens win, so a root font-size override must be honored
|
|
4793
|
+
// rather than assuming 1.5rem is 48px.
|
|
4794
|
+
const bodyStyle = getComputedStyle(document.body);
|
|
4795
|
+
const paddingPx =
|
|
4796
|
+
parseFloat(bodyStyle.paddingTop) + parseFloat(bodyStyle.paddingBottom);
|
|
4797
|
+
new ResizeObserver(() => {
|
|
4798
|
+
window.parent.postMessage(
|
|
4799
|
+
{
|
|
4800
|
+
height:
|
|
4801
|
+
Math.ceil(wrapper.getBoundingClientRect().height) + paddingPx,
|
|
4802
|
+
type: "blume:example-height",
|
|
4803
|
+
},
|
|
4804
|
+
window.location.origin
|
|
4805
|
+
);
|
|
4806
|
+
}).observe(wrapper);
|
|
4807
|
+
})();
|
|
4808
|
+
</script>
|
|
4764
4809
|
</body>
|
|
4765
4810
|
</html>
|
|
4766
4811
|
`;
|
|
@@ -7879,7 +7924,8 @@ var ogConfigSchema = z2.strictObject({
|
|
|
7879
7924
|
enabled: z2.boolean().optional(),
|
|
7880
7925
|
fonts: z2.array(ogFontSchema).optional(),
|
|
7881
7926
|
logo: z2.string().optional(),
|
|
7882
|
-
palette: ogPaletteSchema.optional()
|
|
7927
|
+
palette: ogPaletteSchema.optional(),
|
|
7928
|
+
titles: z2.record(z2.string(), z2.string()).optional()
|
|
7883
7929
|
});
|
|
7884
7930
|
var rssConfigSchema = z2.strictObject({
|
|
7885
7931
|
enabled: z2.boolean().default(true),
|
|
@@ -7916,9 +7962,23 @@ var githubConfigSchema = z2.strictObject({
|
|
|
7916
7962
|
owner: z2.string(),
|
|
7917
7963
|
repo: z2.string()
|
|
7918
7964
|
});
|
|
7965
|
+
var codeThemeSchema = z2.custom((value) => {
|
|
7966
|
+
if (typeof value === "string") {
|
|
7967
|
+
return true;
|
|
7968
|
+
}
|
|
7969
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7970
|
+
return false;
|
|
7971
|
+
}
|
|
7972
|
+
const theme = value;
|
|
7973
|
+
const settingsValid = theme.settings === undefined || Array.isArray(theme.settings);
|
|
7974
|
+
const tokenColorsValid = theme.tokenColors === undefined || Array.isArray(theme.tokenColors);
|
|
7975
|
+
const colorsValid = theme.colors === undefined || typeof theme.colors === "object" && theme.colors !== null && !Array.isArray(theme.colors);
|
|
7976
|
+
const hasContent = theme.settings !== undefined || theme.tokenColors !== undefined || theme.colors !== undefined;
|
|
7977
|
+
return settingsValid && tokenColorsValid && colorsValid && hasContent;
|
|
7978
|
+
}, "Expected a Shiki theme name or custom theme object");
|
|
7919
7979
|
var codeBlockThemeSchema = z2.strictObject({
|
|
7920
|
-
dark:
|
|
7921
|
-
light:
|
|
7980
|
+
dark: codeThemeSchema.default("github-dark"),
|
|
7981
|
+
light: codeThemeSchema.default("github-light")
|
|
7922
7982
|
});
|
|
7923
7983
|
var codeBlocksConfigSchema = z2.strictObject({
|
|
7924
7984
|
theme: codeBlockThemeSchema.default({})
|
|
@@ -8383,19 +8443,23 @@ var ensureGroup = (parent, rawSegment) => {
|
|
|
8383
8443
|
};
|
|
8384
8444
|
var pageOrder = (page, filename) => {
|
|
8385
8445
|
if (page.meta.sidebar.order !== undefined) {
|
|
8386
|
-
return page.meta.sidebar.order;
|
|
8446
|
+
return { order: page.meta.sidebar.order, orderIsAuthored: true };
|
|
8387
8447
|
}
|
|
8388
8448
|
if (isIndexStem(filename.replace(extname(filename), ""))) {
|
|
8389
|
-
return Number.NEGATIVE_INFINITY;
|
|
8449
|
+
return { order: Number.NEGATIVE_INFINITY, orderIsAuthored: false };
|
|
8390
8450
|
}
|
|
8391
8451
|
if (page.contentType === "changelog") {
|
|
8392
8452
|
const iso = page.meta.date ?? page.meta.changelog?.date;
|
|
8393
8453
|
const time = iso ? Date.parse(iso) : Number.NaN;
|
|
8394
8454
|
if (!Number.isNaN(time)) {
|
|
8395
|
-
return -time;
|
|
8455
|
+
return { order: -time, orderIsAuthored: false };
|
|
8396
8456
|
}
|
|
8397
8457
|
}
|
|
8398
|
-
|
|
8458
|
+
const order = numericOrder(filename);
|
|
8459
|
+
return {
|
|
8460
|
+
order,
|
|
8461
|
+
orderIsAuthored: page.contentType !== "changelog" && Number.isFinite(order)
|
|
8462
|
+
};
|
|
8399
8463
|
};
|
|
8400
8464
|
var metaKey = (path, metaPrefix) => {
|
|
8401
8465
|
if (!metaPrefix) {
|
|
@@ -8416,6 +8480,9 @@ var applyFolderMeta = (group, folderMeta, sharedMeta, metaPrefix) => {
|
|
|
8416
8480
|
const position = rank.get(child.key);
|
|
8417
8481
|
if (position !== undefined) {
|
|
8418
8482
|
child.order = position;
|
|
8483
|
+
if (child.kind === "page") {
|
|
8484
|
+
child.orderIsAuthored = true;
|
|
8485
|
+
}
|
|
8419
8486
|
}
|
|
8420
8487
|
}
|
|
8421
8488
|
}
|
|
@@ -8426,7 +8493,56 @@ var applyFolderMeta = (group, folderMeta, sharedMeta, metaPrefix) => {
|
|
|
8426
8493
|
}
|
|
8427
8494
|
}
|
|
8428
8495
|
};
|
|
8429
|
-
var
|
|
8496
|
+
var indexTitleMismatchDiagnostic = (page, folderPath, folderMeta, sharedMeta, metaPrefix) => {
|
|
8497
|
+
if (!page.meta.title || page.fallback || folderPath === "") {
|
|
8498
|
+
return;
|
|
8499
|
+
}
|
|
8500
|
+
const meta = folderMeta.get(metaKey(folderPath, metaPrefix)) ?? sharedMeta.get(folderPath);
|
|
8501
|
+
if (!meta?.title || meta.title === page.title) {
|
|
8502
|
+
return;
|
|
8503
|
+
}
|
|
8504
|
+
return {
|
|
8505
|
+
code: "BLUME_NAV_INDEX_TITLE_MISMATCH",
|
|
8506
|
+
file: page.sourcePath ?? page.id,
|
|
8507
|
+
message: `Index page "${page.navPath}" has title "${page.title}", but its folder's meta.title is "${meta.title}" — the sidebar shows the folder title while the page's own <title>/heading still say "${page.title}".`,
|
|
8508
|
+
severity: "warning",
|
|
8509
|
+
suggestion: `Update the page's frontmatter title to match ("${meta.title}"), or leave it if the divergence is intentional.`
|
|
8510
|
+
};
|
|
8511
|
+
};
|
|
8512
|
+
var isAuthoredOrder = (node) => node.kind === "group" || node.orderIsAuthored;
|
|
8513
|
+
var duplicateOrderDiagnostics = (nodes) => {
|
|
8514
|
+
const byOrder = new Map;
|
|
8515
|
+
for (const node of nodes) {
|
|
8516
|
+
if (!Number.isFinite(node.order) || !isAuthoredOrder(node)) {
|
|
8517
|
+
continue;
|
|
8518
|
+
}
|
|
8519
|
+
const tied = byOrder.get(node.order);
|
|
8520
|
+
if (tied) {
|
|
8521
|
+
tied.push(node);
|
|
8522
|
+
} else {
|
|
8523
|
+
byOrder.set(node.order, [node]);
|
|
8524
|
+
}
|
|
8525
|
+
}
|
|
8526
|
+
const diagnostics = [];
|
|
8527
|
+
for (const [order, tied] of byOrder) {
|
|
8528
|
+
if (tied.length > 1) {
|
|
8529
|
+
const names = tied.map((node) => `"${node.label}"`);
|
|
8530
|
+
const list2 = names.length > 2 ? `${names.slice(0, -1).join(", ")}, and ${names.at(-1)}` : names.join(" and ");
|
|
8531
|
+
const verb = tied.length > 2 ? "all have" : "both have";
|
|
8532
|
+
const file = tied.find((node) => node.kind === "page")?.file;
|
|
8533
|
+
diagnostics.push({
|
|
8534
|
+
code: "BLUME_DUPLICATE_SIDEBAR_ORDER",
|
|
8535
|
+
file,
|
|
8536
|
+
message: `${list2} ${verb} sidebar order ${order}; falling back to alphabetical order.`,
|
|
8537
|
+
severity: "warning",
|
|
8538
|
+
suggestion: "Give each item a distinct sidebar.order (or folder meta order)."
|
|
8539
|
+
});
|
|
8540
|
+
}
|
|
8541
|
+
}
|
|
8542
|
+
return diagnostics;
|
|
8543
|
+
};
|
|
8544
|
+
var sortNodes = (nodes, diagnostics) => {
|
|
8545
|
+
diagnostics.push(...duplicateOrderDiagnostics(nodes));
|
|
8430
8546
|
nodes.sort((a, b) => {
|
|
8431
8547
|
if (a.order !== b.order) {
|
|
8432
8548
|
return a.order - b.order;
|
|
@@ -8435,7 +8551,7 @@ var sortNodes = (nodes) => {
|
|
|
8435
8551
|
});
|
|
8436
8552
|
for (const node of nodes) {
|
|
8437
8553
|
if (node.kind === "group") {
|
|
8438
|
-
sortNodes(node.children);
|
|
8554
|
+
sortNodes(node.children, diagnostics);
|
|
8439
8555
|
}
|
|
8440
8556
|
}
|
|
8441
8557
|
};
|
|
@@ -8483,16 +8599,22 @@ var toNavNode = (node, display) => {
|
|
|
8483
8599
|
path: node.routePath
|
|
8484
8600
|
};
|
|
8485
8601
|
};
|
|
8486
|
-
var buildFileSystemSidebar = (pages, folderMeta, sharedMeta, metaPrefix, display, tabPaths) => {
|
|
8602
|
+
var buildFileSystemSidebar = (pages, folderMeta, sharedMeta, metaPrefix, display, tabPaths, diagnostics = []) => {
|
|
8487
8603
|
const root = createGroup("", "", "", 0);
|
|
8488
8604
|
for (const page of pages) {
|
|
8489
|
-
if (page.meta.sidebar.hidden) {
|
|
8490
|
-
continue;
|
|
8491
|
-
}
|
|
8492
8605
|
const parts = page.navPath.split("/");
|
|
8493
8606
|
const filename = parts.at(-1) ?? page.navPath;
|
|
8494
8607
|
const stem = filename.replace(extname(filename), "");
|
|
8495
8608
|
const dirs = parts.slice(0, -1);
|
|
8609
|
+
if (isIndexStem(stem)) {
|
|
8610
|
+
const diagnostic = indexTitleMismatchDiagnostic(page, dirs.join("/"), folderMeta, sharedMeta, metaPrefix);
|
|
8611
|
+
if (diagnostic) {
|
|
8612
|
+
diagnostics.push(diagnostic);
|
|
8613
|
+
}
|
|
8614
|
+
}
|
|
8615
|
+
if (page.meta.sidebar.hidden) {
|
|
8616
|
+
continue;
|
|
8617
|
+
}
|
|
8496
8618
|
const routeSegments = page.route.split("/").filter(Boolean);
|
|
8497
8619
|
const folderParts = isIndexStem(stem) ? routeSegments : routeSegments.slice(0, -1);
|
|
8498
8620
|
const routeDirCount = dirs.filter((dir) => !GROUP_FOLDER.test(dir)).length;
|
|
@@ -8506,21 +8628,24 @@ var buildFileSystemSidebar = (pages, folderMeta, sharedMeta, metaPrefix, display
|
|
|
8506
8628
|
}
|
|
8507
8629
|
parent.routePath ??= `/${folderParts.slice(0, consumed).join("/")}`;
|
|
8508
8630
|
}
|
|
8631
|
+
const { order, orderIsAuthored } = pageOrder(page, filename);
|
|
8509
8632
|
parent.children.push({
|
|
8510
8633
|
badge: page.meta.sidebar.badge,
|
|
8511
8634
|
deprecated: page.meta.deprecated || undefined,
|
|
8512
8635
|
description: page.description,
|
|
8636
|
+
file: page.sourcePath,
|
|
8513
8637
|
icon: page.meta.sidebar.icon,
|
|
8514
8638
|
key: segmentKey(stem),
|
|
8515
8639
|
kind: "page",
|
|
8516
8640
|
label: page.meta.sidebar.label ?? page.title,
|
|
8517
|
-
order
|
|
8641
|
+
order,
|
|
8642
|
+
orderIsAuthored,
|
|
8518
8643
|
pageId: page.id,
|
|
8519
8644
|
route: page.route
|
|
8520
8645
|
});
|
|
8521
8646
|
}
|
|
8522
8647
|
applyFolderMeta(root, folderMeta, sharedMeta, metaPrefix);
|
|
8523
|
-
sortNodes(root.children);
|
|
8648
|
+
sortNodes(root.children, diagnostics);
|
|
8524
8649
|
hoistPages(root.children, display === "flat");
|
|
8525
8650
|
hoistTabSections(root.children, tabPaths, display === "flat");
|
|
8526
8651
|
return root.children.map((child) => toNavNode(child, display));
|
|
@@ -8662,19 +8787,21 @@ var buildNavigation = (pages, options) => {
|
|
|
8662
8787
|
}
|
|
8663
8788
|
}
|
|
8664
8789
|
}
|
|
8790
|
+
const rootTabPath = withBasePath(basePath, options.localizedRoot ?? "/");
|
|
8665
8791
|
if (options.sidebar) {
|
|
8666
8792
|
const sidebar2 = buildConfigSidebar(options.sidebar, byRoute, display, basePath);
|
|
8667
8793
|
return {
|
|
8668
8794
|
featured,
|
|
8795
|
+
root: rootTabPath,
|
|
8669
8796
|
selectors,
|
|
8670
8797
|
sidebar: sidebar2,
|
|
8671
8798
|
tabs: withTabHrefs(tabs, sidebar2)
|
|
8672
8799
|
};
|
|
8673
8800
|
}
|
|
8674
|
-
const
|
|
8675
|
-
const sidebar = buildFileSystemSidebar(pages, options.folderMeta, sharedFolderMeta, metaPrefix, display, new Set(tabs.flatMap((tab) => tab.path === rootTabPath ? [] : [tab.path])));
|
|
8801
|
+
const sidebar = buildFileSystemSidebar(pages, options.folderMeta, sharedFolderMeta, metaPrefix, display, new Set(tabs.flatMap((tab) => tab.path === rootTabPath ? [] : [tab.path])), options.diagnostics);
|
|
8676
8802
|
return {
|
|
8677
8803
|
featured,
|
|
8804
|
+
root: rootTabPath,
|
|
8678
8805
|
selectors,
|
|
8679
8806
|
sidebar,
|
|
8680
8807
|
tabs: withTabHrefs(tabs, sidebar)
|
|
@@ -8711,6 +8838,7 @@ var localePagesFor = (code, real, fallback, fallbackByKey, i18n, basePath) => {
|
|
|
8711
8838
|
if (!present.has(key)) {
|
|
8712
8839
|
filled.push({
|
|
8713
8840
|
...source,
|
|
8841
|
+
fallback: true,
|
|
8714
8842
|
locale: code,
|
|
8715
8843
|
route: withBasePath(basePath, localizeRoute(key, code, i18n))
|
|
8716
8844
|
});
|
|
@@ -8718,7 +8846,7 @@ var localePagesFor = (code, real, fallback, fallbackByKey, i18n, basePath) => {
|
|
|
8718
8846
|
}
|
|
8719
8847
|
return [...real, ...filled];
|
|
8720
8848
|
};
|
|
8721
|
-
var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n) => {
|
|
8849
|
+
var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n, diagnostics) => {
|
|
8722
8850
|
const localizePath = (path) => path.startsWith("/") ? localizeRoute(path, code, i18n) : path;
|
|
8723
8851
|
const tabs = options.navigation.tabs?.map((tab) => ({
|
|
8724
8852
|
...tab,
|
|
@@ -8732,6 +8860,7 @@ var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n
|
|
|
8732
8860
|
const localePages = localePagesFor(code, real, fallback, fallbackByKey, i18n, options.basePath ?? "");
|
|
8733
8861
|
return buildNavigation(localePages, {
|
|
8734
8862
|
basePath: options.basePath ?? "",
|
|
8863
|
+
diagnostics,
|
|
8735
8864
|
display: options.navigation.sidebar.display,
|
|
8736
8865
|
featured: options.navigation.featured,
|
|
8737
8866
|
folderMeta: options.folderMeta,
|
|
@@ -8744,7 +8873,7 @@ var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n
|
|
|
8744
8873
|
tabs
|
|
8745
8874
|
});
|
|
8746
8875
|
};
|
|
8747
|
-
var buildI18nNavigation = (pages, options, i18n) => {
|
|
8876
|
+
var buildI18nNavigation = (pages, options, i18n, diagnostics) => {
|
|
8748
8877
|
const fallback = resolveFallbackLocale(i18n);
|
|
8749
8878
|
const fallbackByKey = new Map;
|
|
8750
8879
|
if (fallback) {
|
|
@@ -8755,8 +8884,19 @@ var buildI18nNavigation = (pages, options, i18n) => {
|
|
|
8755
8884
|
}
|
|
8756
8885
|
}
|
|
8757
8886
|
const navigationByLocale = {};
|
|
8887
|
+
const seen = new Set;
|
|
8758
8888
|
for (const { code } of i18n.locales) {
|
|
8759
|
-
|
|
8889
|
+
const localeDiagnostics = [];
|
|
8890
|
+
navigationByLocale[code] = buildLocaleNavigation(code, pages, fallback, fallbackByKey, options, i18n, localeDiagnostics);
|
|
8891
|
+
for (const diagnostic of localeDiagnostics) {
|
|
8892
|
+
const key = `${diagnostic.code}
|
|
8893
|
+
${diagnostic.file ?? ""}
|
|
8894
|
+
${diagnostic.message}`;
|
|
8895
|
+
if (!seen.has(key)) {
|
|
8896
|
+
seen.add(key);
|
|
8897
|
+
diagnostics.push(diagnostic);
|
|
8898
|
+
}
|
|
8899
|
+
}
|
|
8760
8900
|
}
|
|
8761
8901
|
const navigation = navigationByLocale[i18n.defaultLocale] ?? {
|
|
8762
8902
|
featured: [],
|
|
@@ -8769,9 +8909,10 @@ var buildI18nNavigation = (pages, options, i18n) => {
|
|
|
8769
8909
|
var buildContentGraph = (pages, options) => {
|
|
8770
8910
|
const { diagnostics, routes } = collectRoutes(pages);
|
|
8771
8911
|
const { i18n } = options;
|
|
8772
|
-
const { navigation, navigationByLocale } = i18n ? buildI18nNavigation(pages, options, i18n) : {
|
|
8912
|
+
const { navigation, navigationByLocale } = i18n ? buildI18nNavigation(pages, options, i18n, diagnostics) : {
|
|
8773
8913
|
navigation: buildNavigation(pages, {
|
|
8774
8914
|
basePath: options.basePath ?? "",
|
|
8915
|
+
diagnostics,
|
|
8775
8916
|
display: options.navigation.sidebar.display,
|
|
8776
8917
|
featured: options.navigation.featured,
|
|
8777
8918
|
folderMeta: options.folderMeta,
|
|
@@ -9939,6 +10080,34 @@ var PER_PAGE = 100;
|
|
|
9939
10080
|
var LEADING_V = /^v/iu;
|
|
9940
10081
|
var NON_SLUG3 = /[^a-z0-9]+/gu;
|
|
9941
10082
|
var EDGE_DASHES = /^-+|-+$/gu;
|
|
10083
|
+
var DESCRIPTION_MAX = 160;
|
|
10084
|
+
var DESCRIPTION_MIN = 110;
|
|
10085
|
+
var CODE_FENCE2 = /```[\s\S]*?```/gu;
|
|
10086
|
+
var HEADING_LINE = /^#{1,6}\s.*$/gmu;
|
|
10087
|
+
var LIST_MARK = /^\s*(?:[-*+]|\d+[.)])\s+/u;
|
|
10088
|
+
var CHANGESET_HASH = /^[0-9a-f]{7,40}:\s+/u;
|
|
10089
|
+
var IMAGE = /!\[[^\]]*\]\([^)]*\)/gu;
|
|
10090
|
+
var LINK = /\[(?<text>[^\]]*)\]\([^)]*\)/gu;
|
|
10091
|
+
var INLINE_CODE2 = /`(?<code>[^`]+)`/gu;
|
|
10092
|
+
var HTML_OR_JSX = /<\/?[a-zA-Z][^\n<>]*>|<\/?>/gu;
|
|
10093
|
+
var MARKDOWN_PUNCT = /[*_~>]+/gu;
|
|
10094
|
+
var WHITESPACE2 = /\s+/gu;
|
|
10095
|
+
var TRAILING_FRAGMENT = /[\s,;:.—–-]+$/u;
|
|
10096
|
+
var releaseDescription = (body) => {
|
|
10097
|
+
const text = body.replaceAll(CODE_FENCE2, " ").replaceAll(HEADING_LINE, "").split(`
|
|
10098
|
+
`).map((line) => line.replace(LIST_MARK, "").replace(CHANGESET_HASH, "")).join(`
|
|
10099
|
+
`).replaceAll(IMAGE, " ").replaceAll(LINK, "$<text>").replaceAll(INLINE_CODE2, "$<code>").replaceAll(HTML_OR_JSX, " ").replaceAll(MARKDOWN_PUNCT, " ").replaceAll(WHITESPACE2, " ").trim();
|
|
10100
|
+
if (!text) {
|
|
10101
|
+
return;
|
|
10102
|
+
}
|
|
10103
|
+
if (text.length <= DESCRIPTION_MAX) {
|
|
10104
|
+
return text;
|
|
10105
|
+
}
|
|
10106
|
+
const slice = text.slice(0, DESCRIPTION_MAX - 1);
|
|
10107
|
+
const boundary = slice.lastIndexOf(" ");
|
|
10108
|
+
const head = (boundary >= DESCRIPTION_MIN ? slice.slice(0, boundary) : slice).replace(TRAILING_FRAGMENT, "");
|
|
10109
|
+
return `${head}…`;
|
|
10110
|
+
};
|
|
9942
10111
|
var slugifyTag = (tag) => tag.toLowerCase().replaceAll(NON_SLUG3, "-").replaceAll(EDGE_DASHES, "");
|
|
9943
10112
|
var githubHeaders = () => {
|
|
9944
10113
|
const headers = new Headers({ Accept: "application/vnd.github+json" });
|
|
@@ -9956,9 +10125,11 @@ var releaseToEntry = (release) => {
|
|
|
9956
10125
|
const body = (release.body ?? "").replaceAll(`\r
|
|
9957
10126
|
`, `
|
|
9958
10127
|
`).trim();
|
|
10128
|
+
const description = releaseDescription(body);
|
|
9959
10129
|
const data = {
|
|
9960
10130
|
changelog: { category, version },
|
|
9961
10131
|
date,
|
|
10132
|
+
...description ? { seo: { description } } : {},
|
|
9962
10133
|
title,
|
|
9963
10134
|
type: "changelog"
|
|
9964
10135
|
};
|
|
@@ -10940,6 +11111,34 @@ var entryIdDiagnostics = (pages, collectionBase) => {
|
|
|
10940
11111
|
}
|
|
10941
11112
|
return diagnostics;
|
|
10942
11113
|
};
|
|
11114
|
+
var normalizeLoadedEntries = (loaded, config) => {
|
|
11115
|
+
const frontmatterExtend = Object.keys(config.frontmatter.extend).length > 0 ? config.frontmatter.extend : undefined;
|
|
11116
|
+
const pages = [];
|
|
11117
|
+
const allDiagnostics = [];
|
|
11118
|
+
let droppedPages = 0;
|
|
11119
|
+
for (const { source, entries, diagnostics } of loaded) {
|
|
11120
|
+
allDiagnostics.push(...diagnostics);
|
|
11121
|
+
for (const entry of entries) {
|
|
11122
|
+
const normalized = normalizeEntry(entry, {
|
|
11123
|
+
basePath: config.basePath,
|
|
11124
|
+
defaultType: config.content.defaultType,
|
|
11125
|
+
frontmatterExtend,
|
|
11126
|
+
i18n: config.i18n,
|
|
11127
|
+
source: {
|
|
11128
|
+
name: source.name,
|
|
11129
|
+
prefix: source.prefix,
|
|
11130
|
+
staged: source.staged
|
|
11131
|
+
}
|
|
11132
|
+
});
|
|
11133
|
+
if (normalized.pages.length === 0 && normalized.diagnostics.length > 0) {
|
|
11134
|
+
droppedPages += 1;
|
|
11135
|
+
}
|
|
11136
|
+
pages.push(...normalized.pages);
|
|
11137
|
+
allDiagnostics.push(...normalized.diagnostics);
|
|
11138
|
+
}
|
|
11139
|
+
}
|
|
11140
|
+
return { diagnostics: allDiagnostics, droppedPages, pages };
|
|
11141
|
+
};
|
|
10943
11142
|
var scanProject = async (root, options = {}) => {
|
|
10944
11143
|
const mode = options.mode ?? "dev";
|
|
10945
11144
|
const preview = options.preview ?? false;
|
|
@@ -10964,27 +11163,11 @@ var scanProject = async (root, options = {}) => {
|
|
|
10964
11163
|
Promise.all(sources.map(async (source) => ({ source, ...await source.load() }))),
|
|
10965
11164
|
discoverFolderMeta(metaSources, { localeDirs })
|
|
10966
11165
|
]);
|
|
10967
|
-
const
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
for (const entry of entries) {
|
|
10973
|
-
const normalized = normalizeEntry(entry, {
|
|
10974
|
-
basePath: config.basePath,
|
|
10975
|
-
defaultType: config.content.defaultType,
|
|
10976
|
-
frontmatterExtend,
|
|
10977
|
-
i18n: config.i18n,
|
|
10978
|
-
source: {
|
|
10979
|
-
name: source.name,
|
|
10980
|
-
prefix: source.prefix,
|
|
10981
|
-
staged: source.staged
|
|
10982
|
-
}
|
|
10983
|
-
});
|
|
10984
|
-
allPages.push(...normalized.pages);
|
|
10985
|
-
contentDiagnostics.push(...normalized.diagnostics);
|
|
10986
|
-
}
|
|
10987
|
-
}
|
|
11166
|
+
const {
|
|
11167
|
+
diagnostics: contentDiagnostics,
|
|
11168
|
+
droppedPages,
|
|
11169
|
+
pages: allPages
|
|
11170
|
+
} = normalizeLoadedEntries(loaded, config);
|
|
10988
11171
|
const pages = mode === "build" && !preview ? allPages.filter((page) => !page.meta.draft) : allPages;
|
|
10989
11172
|
const lastModified = resolveLastModifiedConfig(config.lastModified);
|
|
10990
11173
|
if (lastModified.enabled && lastModified.source === "git") {
|
|
@@ -11016,6 +11199,7 @@ var scanProject = async (root, options = {}) => {
|
|
|
11016
11199
|
...graph.diagnostics,
|
|
11017
11200
|
...i18nWarnings
|
|
11018
11201
|
],
|
|
11202
|
+
droppedPages,
|
|
11019
11203
|
graph,
|
|
11020
11204
|
manifest,
|
|
11021
11205
|
mode,
|
|
@@ -11390,15 +11574,15 @@ var parseYouTubeId = (input) => {
|
|
|
11390
11574
|
};
|
|
11391
11575
|
|
|
11392
11576
|
// src/ai/component-markdown.ts
|
|
11393
|
-
var evaluateExpression = (raw) => {
|
|
11577
|
+
var evaluateExpression = (raw, frontmatter) => {
|
|
11394
11578
|
try {
|
|
11395
|
-
const value = new Function(`"use strict"; return (${raw});`)();
|
|
11579
|
+
const value = new Function("frontmatter", `"use strict"; return (${raw});`)(frontmatter);
|
|
11396
11580
|
return { ok: true, value };
|
|
11397
11581
|
} catch {
|
|
11398
11582
|
return { ok: false, value: undefined };
|
|
11399
11583
|
}
|
|
11400
11584
|
};
|
|
11401
|
-
var readProps = (node) => {
|
|
11585
|
+
var readProps = (node, frontmatter) => {
|
|
11402
11586
|
const props = {};
|
|
11403
11587
|
let lossy = false;
|
|
11404
11588
|
for (const attribute of node.attributes ?? []) {
|
|
@@ -11411,7 +11595,7 @@ var readProps = (node) => {
|
|
|
11411
11595
|
} else if (typeof attribute.value === "string") {
|
|
11412
11596
|
props[attribute.name] = attribute.value;
|
|
11413
11597
|
} else {
|
|
11414
|
-
const result = evaluateExpression(attribute.value.value);
|
|
11598
|
+
const result = evaluateExpression(attribute.value.value, frontmatter);
|
|
11415
11599
|
if (result.ok) {
|
|
11416
11600
|
props[attribute.name] = result.value;
|
|
11417
11601
|
} else {
|
|
@@ -11578,12 +11762,13 @@ var renderChildren2 = (walk, node) => {
|
|
|
11578
11762
|
return dedent(spliced).trim();
|
|
11579
11763
|
};
|
|
11580
11764
|
var serializeElement = (serializer, walk, node) => serializer({
|
|
11581
|
-
...readProps(node),
|
|
11765
|
+
...readProps(node, walk.frontmatter),
|
|
11582
11766
|
childComponents: (name) => (node.children ?? []).filter((child) => isJsxElement(child) && child.name === name).map((child) => ({
|
|
11583
|
-
...readProps(child),
|
|
11767
|
+
...readProps(child, walk.frontmatter),
|
|
11584
11768
|
children: renderChildren2(walk, child)
|
|
11585
11769
|
})),
|
|
11586
|
-
children: renderChildren2(walk, node)
|
|
11770
|
+
children: renderChildren2(walk, node),
|
|
11771
|
+
frontmatter: walk.frontmatter ?? {}
|
|
11587
11772
|
});
|
|
11588
11773
|
var collectSplices = (walk, nodes, out) => {
|
|
11589
11774
|
for (const node of nodes) {
|
|
@@ -11602,7 +11787,7 @@ var collectSplices = (walk, nodes, out) => {
|
|
|
11602
11787
|
collectSplices(walk, node.children ?? [], out);
|
|
11603
11788
|
}
|
|
11604
11789
|
};
|
|
11605
|
-
var downlevelComponents = (source, components) => {
|
|
11790
|
+
var downlevelComponents = (source, components, frontmatter) => {
|
|
11606
11791
|
const custom = components && Object.keys(components).length > 0;
|
|
11607
11792
|
const registry2 = custom ? { ...SERIALIZERS, ...components } : SERIALIZERS;
|
|
11608
11793
|
const hint = custom ? componentHint(registry2) : BUILT_IN_HINT;
|
|
@@ -11616,7 +11801,7 @@ var downlevelComponents = (source, components) => {
|
|
|
11616
11801
|
return source;
|
|
11617
11802
|
}
|
|
11618
11803
|
const splices = [];
|
|
11619
|
-
collectSplices({ registry: registry2, source }, tree.children ?? [], splices);
|
|
11804
|
+
collectSplices({ frontmatter, registry: registry2, source }, tree.children ?? [], splices);
|
|
11620
11805
|
return splices.length > 0 ? applySplices(source, splices) : source;
|
|
11621
11806
|
};
|
|
11622
11807
|
|
|
@@ -11746,7 +11931,8 @@ var buildFull = async (project) => {
|
|
|
11746
11931
|
const pages = eligiblePages(project).toSorted((a, b) => a.route.localeCompare(b.route));
|
|
11747
11932
|
const sections = await Promise.all(pages.map(async (page) => {
|
|
11748
11933
|
const raw = await readEntryText(project, page);
|
|
11749
|
-
const
|
|
11934
|
+
const parsed = frontmatter_default(raw);
|
|
11935
|
+
const body = downlevelComponents(applyAgentVisibility(parsed.content), config.ai.markdownComponents, parsed.data).trim();
|
|
11750
11936
|
const url = pageUrl(page.route, config.deployment.site, normalizeBasePath(config.deployment.base));
|
|
11751
11937
|
return [`# ${page.title}`, `Source: ${url}`, "", body].join(`
|
|
11752
11938
|
`);
|
|
@@ -11920,7 +12106,11 @@ var hasGeneratedChangelog = (project, userPages) => {
|
|
|
11920
12106
|
return (hasChangelog || hasChangelogSource) && !routeIsTaken(userPages, project.graph.pages, "/changelog");
|
|
11921
12107
|
};
|
|
11922
12108
|
var humanizeSegment = (segment) => segment.split(/[-_]/u).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
11923
|
-
var customOgRoutes = (pages, siteTitle) => {
|
|
12109
|
+
var customOgRoutes = (pages, siteTitle, titles = {}) => {
|
|
12110
|
+
const overrides = new Map(Object.entries(titles).map(([route, title]) => [
|
|
12111
|
+
`/${route.split("/").filter(Boolean).join("/")}`,
|
|
12112
|
+
title
|
|
12113
|
+
]));
|
|
11924
12114
|
const seen = new Set;
|
|
11925
12115
|
const routes = [];
|
|
11926
12116
|
const collectRoute = (pattern) => {
|
|
@@ -11934,7 +12124,10 @@ var customOgRoutes = (pages, siteTitle) => {
|
|
|
11934
12124
|
}
|
|
11935
12125
|
seen.add(slug);
|
|
11936
12126
|
const last = segments.at(-1);
|
|
11937
|
-
routes.push({
|
|
12127
|
+
routes.push({
|
|
12128
|
+
slug,
|
|
12129
|
+
title: overrides.get(`/${segments.join("/")}`) ?? (last ? humanizeSegment(last) : siteTitle)
|
|
12130
|
+
});
|
|
11938
12131
|
};
|
|
11939
12132
|
for (const { pattern } of pages) {
|
|
11940
12133
|
collectRoute(pattern);
|
|
@@ -12006,25 +12199,25 @@ var buildSearchIndex = async (outDir) => {
|
|
|
12006
12199
|
};
|
|
12007
12200
|
|
|
12008
12201
|
// src/search/documents.ts
|
|
12009
|
-
var
|
|
12010
|
-
var
|
|
12011
|
-
var
|
|
12012
|
-
var
|
|
12013
|
-
var
|
|
12202
|
+
var CODE_FENCE3 = /```[\s\S]*?```/gu;
|
|
12203
|
+
var INLINE_CODE3 = /`(?<code>[^`]+)`/gu;
|
|
12204
|
+
var HTML_OR_JSX2 = /<\/?[a-zA-Z][^\n<>]*>|<\/?>/gu;
|
|
12205
|
+
var IMAGE2 = /!\[[^\]]*\]\([^)]*\)/gu;
|
|
12206
|
+
var LINK2 = /\[(?<text>[^\]]*)\]\([^)]*\)/gu;
|
|
12014
12207
|
var HEADING_MARK = /^#{1,6}\s+/gmu;
|
|
12015
|
-
var
|
|
12016
|
-
var
|
|
12208
|
+
var MARKDOWN_PUNCT2 = /[*_~>]+/gu;
|
|
12209
|
+
var WHITESPACE3 = /\s+/gu;
|
|
12017
12210
|
var toPlainText = (markdown) => {
|
|
12018
|
-
const withoutBlocks = markdown.replaceAll(
|
|
12211
|
+
const withoutBlocks = markdown.replaceAll(CODE_FENCE3, " ").replaceAll(IMAGE2, " ").replaceAll(LINK2, "$<text>");
|
|
12019
12212
|
const pieces = [];
|
|
12020
12213
|
let cursor = 0;
|
|
12021
|
-
for (const match of withoutBlocks.matchAll(
|
|
12214
|
+
for (const match of withoutBlocks.matchAll(INLINE_CODE3)) {
|
|
12022
12215
|
const start = match.index ?? 0;
|
|
12023
|
-
pieces.push(withoutBlocks.slice(cursor, start).replaceAll(
|
|
12216
|
+
pieces.push(withoutBlocks.slice(cursor, start).replaceAll(HTML_OR_JSX2, " "), match.groups?.code ?? "");
|
|
12024
12217
|
cursor = start + match[0].length;
|
|
12025
12218
|
}
|
|
12026
|
-
pieces.push(withoutBlocks.slice(cursor).replaceAll(
|
|
12027
|
-
return pieces.join("").replaceAll(HEADING_MARK, "").replaceAll(
|
|
12219
|
+
pieces.push(withoutBlocks.slice(cursor).replaceAll(HTML_OR_JSX2, " "));
|
|
12220
|
+
return pieces.join("").replaceAll(HEADING_MARK, "").replaceAll(MARKDOWN_PUNCT2, " ").replaceAll(WHITESPACE3, " ").trim();
|
|
12028
12221
|
};
|
|
12029
12222
|
var buildCrumbIndex = (sidebar) => {
|
|
12030
12223
|
const index = new Map;
|
|
@@ -12346,6 +12539,7 @@ import {
|
|
|
12346
12539
|
lstat,
|
|
12347
12540
|
mkdir as mkdir6,
|
|
12348
12541
|
readFile as readFile14,
|
|
12542
|
+
realpath,
|
|
12349
12543
|
rename,
|
|
12350
12544
|
rm as rm2,
|
|
12351
12545
|
symlink,
|
|
@@ -12389,7 +12583,7 @@ var buildRawMarkdown = async (project) => {
|
|
|
12389
12583
|
};
|
|
12390
12584
|
const entries = await Promise.all(project.manifest.routes.map(async (route) => {
|
|
12391
12585
|
const source = applyAgentVisibility(await readRoute(route));
|
|
12392
|
-
const md = downlevelComponents(source, project.config.ai.markdownComponents);
|
|
12586
|
+
const md = downlevelComponents(source, project.config.ai.markdownComponents, frontmatter_default(source).data);
|
|
12393
12587
|
const entry = md === source ? { mdx: source } : { md, mdx: source };
|
|
12394
12588
|
return [route.path, entry];
|
|
12395
12589
|
}));
|
|
@@ -14261,10 +14455,11 @@ var resolvedAstroPath = (fromDir) => {
|
|
|
14261
14455
|
dir = parent;
|
|
14262
14456
|
}
|
|
14263
14457
|
};
|
|
14264
|
-
var
|
|
14265
|
-
|
|
14266
|
-
|
|
14267
|
-
|
|
14458
|
+
var depsCandidates = (pkgDir) => [
|
|
14459
|
+
join26(pkgDir, "node_modules"),
|
|
14460
|
+
dirname9(pkgDir)
|
|
14461
|
+
];
|
|
14462
|
+
var candidateHolding = (pkgDir, ...segments) => depsCandidates(pkgDir).find((dir) => existsSync14(join26(dir, ...segments))) ?? null;
|
|
14268
14463
|
var linkDepsJunction = async (link, depsDir) => {
|
|
14269
14464
|
let existing;
|
|
14270
14465
|
try {
|
|
@@ -14298,18 +14493,43 @@ var astroConflictWarning = (blumeAstroPkg, shadowAstroPkg) => {
|
|
|
14298
14493
|
const pin = blume ?? "<Blume's astro version>";
|
|
14299
14494
|
return `Astro version conflict: another dependency hoisted ${versions} to the project root, so @astrojs/mdx binds to the wrong copy and the build fails on a missing export (e.g. "chunkToString"). A single symlink can't reconcile a split install — pin Blume's Astro by adding a package.json "overrides" (npm/bun/pnpm) or "resolutions" (yarn) entry { "astro": "${pin}" }, then reinstall. Run \`npm ls astro\` to find the dependency pulling the older copy.`;
|
|
14300
14495
|
};
|
|
14496
|
+
var dropStaleDepsLink = async (link, pkgDir) => {
|
|
14497
|
+
let existing;
|
|
14498
|
+
try {
|
|
14499
|
+
existing = await lstat(link);
|
|
14500
|
+
} catch {
|
|
14501
|
+
return;
|
|
14502
|
+
}
|
|
14503
|
+
if (!existing.isSymbolicLink()) {
|
|
14504
|
+
return;
|
|
14505
|
+
}
|
|
14506
|
+
let linkedBlume;
|
|
14507
|
+
let runningBlume;
|
|
14508
|
+
try {
|
|
14509
|
+
linkedBlume = await realpath(join26(link, "blume"));
|
|
14510
|
+
runningBlume = await realpath(pkgDir);
|
|
14511
|
+
} catch {
|
|
14512
|
+
return;
|
|
14513
|
+
}
|
|
14514
|
+
if (linkedBlume !== runningBlume) {
|
|
14515
|
+
await rm2(link, { force: true });
|
|
14516
|
+
}
|
|
14517
|
+
};
|
|
14301
14518
|
var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
14302
|
-
const
|
|
14303
|
-
if (!
|
|
14519
|
+
const astroDir = candidateHolding(pkgDir, "astro");
|
|
14520
|
+
if (!astroDir) {
|
|
14304
14521
|
return null;
|
|
14305
14522
|
}
|
|
14306
|
-
const
|
|
14523
|
+
const mdxDir = candidateHolding(pkgDir, "@astrojs", "mdx");
|
|
14524
|
+
const blumeAstro = resolveAstroPackageJson(astroDir);
|
|
14525
|
+
await dropStaleDepsLink(join26(outDir, "node_modules"), pkgDir);
|
|
14307
14526
|
const outDirAstro = resolvedAstroPath(outDir);
|
|
14308
|
-
|
|
14527
|
+
const astroCorrect = blumeAstro !== null && outDirAstro === blumeAstro;
|
|
14528
|
+
if (astroCorrect && mdxDir === astroDir) {
|
|
14309
14529
|
return null;
|
|
14310
14530
|
}
|
|
14311
|
-
if (
|
|
14312
|
-
await linkDepsJunction(join26(outDir, "node_modules"),
|
|
14531
|
+
if (mdxDir && (mdxDir === astroDir || astroCorrect)) {
|
|
14532
|
+
await linkDepsJunction(join26(outDir, "node_modules"), mdxDir);
|
|
14313
14533
|
return null;
|
|
14314
14534
|
}
|
|
14315
14535
|
return astroConflictWarning(blumeAstro, outDirAstro);
|
|
@@ -14807,7 +15027,7 @@ var generateRuntime = async (project) => {
|
|
|
14807
15027
|
const needsVue = frameworks.has("vue");
|
|
14808
15028
|
const needsSvelte = frameworks.has("svelte");
|
|
14809
15029
|
const reactCompilerPath = resolveReactCompiler(config, needsReact);
|
|
14810
|
-
const ogRoutes = customOgRoutes(pages, config.title);
|
|
15030
|
+
const ogRoutes = customOgRoutes(pages, config.title, config.seo.og.titles);
|
|
14811
15031
|
const mcp = planMcp(project, srcDir, pages);
|
|
14812
15032
|
pages.push(...mcp.discoveryPages);
|
|
14813
15033
|
const hasStaged = staged.size > 0;
|
|
@@ -15104,12 +15324,13 @@ var prepareProject = async (options) => {
|
|
|
15104
15324
|
}
|
|
15105
15325
|
}
|
|
15106
15326
|
const hadErrors = reportDiagnostics(project.diagnostics, options.root);
|
|
15327
|
+
const dropped = project.droppedPages > 0 ? `${project.droppedPages} page(s) failed frontmatter validation and were dropped from the site. ` : "";
|
|
15107
15328
|
if (hadErrors && options.strict) {
|
|
15108
|
-
logger.error(
|
|
15329
|
+
logger.error(`Aborting due to errors. ${dropped}Fix the diagnostics above, or pass --no-strict to continue despite them.`);
|
|
15109
15330
|
process.exit(1);
|
|
15110
15331
|
}
|
|
15111
15332
|
if (hasErrors(project.diagnostics) && !options.strict) {
|
|
15112
|
-
logger.warn(
|
|
15333
|
+
logger.warn(`Continuing despite errors. ${dropped}Use --strict to fail instead.`);
|
|
15113
15334
|
}
|
|
15114
15335
|
const { warnings } = await generateRuntime(project);
|
|
15115
15336
|
for (const warning of warnings) {
|
|
@@ -15307,6 +15528,9 @@ var publishBuildArtifacts = async (project, distDir, args) => {
|
|
|
15307
15528
|
].join(`
|
|
15308
15529
|
`));
|
|
15309
15530
|
await runClientAssetChecks(distDir, args);
|
|
15531
|
+
if (project.droppedPages > 0) {
|
|
15532
|
+
logger.warn(`${project.droppedPages} page(s) failed frontmatter validation and are missing from this build.`);
|
|
15533
|
+
}
|
|
15310
15534
|
logger.success(`Built to ${distDir}`);
|
|
15311
15535
|
};
|
|
15312
15536
|
var buildCommand = defineCommand3({
|
|
@@ -15343,7 +15567,11 @@ var buildCommand = defineCommand3({
|
|
|
15343
15567
|
description: "Include drafts and unpublished CMS content.",
|
|
15344
15568
|
type: "boolean"
|
|
15345
15569
|
},
|
|
15346
|
-
strict: {
|
|
15570
|
+
strict: {
|
|
15571
|
+
default: true,
|
|
15572
|
+
description: "Fail on error diagnostics (default; pass --no-strict to build anyway, dropping pages that fail validation).",
|
|
15573
|
+
type: "boolean"
|
|
15574
|
+
}
|
|
15347
15575
|
},
|
|
15348
15576
|
meta: {
|
|
15349
15577
|
description: "Build the docs site for production.",
|
|
@@ -16032,7 +16260,7 @@ var eject = async (root) => {
|
|
|
16032
16260
|
}
|
|
16033
16261
|
if (config.seo.og.enabled) {
|
|
16034
16262
|
files.push({
|
|
16035
|
-
content: ogEndpointTemplate(customOgRoutes(pages, config.title)),
|
|
16263
|
+
content: ogEndpointTemplate(customOgRoutes(pages, config.title, config.seo.og.titles)),
|
|
16036
16264
|
path: join31(srcDir, "pages", "og", "[...slug].png.ts")
|
|
16037
16265
|
});
|
|
16038
16266
|
}
|
|
@@ -17071,5 +17299,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
17071
17299
|
});
|
|
17072
17300
|
runMain(main);
|
|
17073
17301
|
|
|
17074
|
-
//# debugId=
|
|
17302
|
+
//# debugId=7D02660AA9B8797064756E2164756E21
|
|
17075
17303
|
//# sourceMappingURL=index.js.map
|