blume 1.0.3 → 1.0.4
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 +29 -0
- package/dist/cli/index.js +441 -259
- package/dist/cli/index.js.map +12 -11
- package/dist/types/core/config-input.d.ts +27 -8
- package/dist/types/core/data.d.ts +12 -0
- package/dist/types/core/i18n-ui.d.ts +136 -136
- package/dist/types/core/schema.d.ts +420 -350
- package/dist/types/core/types.d.ts +10 -0
- package/dist/types/openapi/references.d.ts +12 -7
- package/docs/advanced/api-reference.mdx +11 -3
- package/docs/configuration/seo.mdx +20 -1
- package/docs/content/components.mdx +1 -2
- package/docs/content/navigation.mdx +10 -0
- package/docs/content/syntax.mdx +116 -4
- package/package.json +1 -1
- package/skills/blume-migrate/SKILL.md +170 -0
- package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +20 -0
- package/skills/blume-migrate/references/docusaurus.md +95 -0
- package/skills/blume-migrate/references/fumadocs.md +95 -0
- package/skills/blume-migrate/references/mintlify.md +155 -0
- package/skills/blume-migrate/references/monorepo.md +224 -0
- package/skills/blume-migrate/references/nextra.md +76 -0
- package/skills/blume-migrate/references/starlight.md +116 -0
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +466 -0
- package/src/astro/component-slots.ts +3 -2
- package/src/astro/generate.ts +82 -23
- package/src/astro/templates.ts +93 -34
- package/src/components/content/Callout.astro +8 -2
- package/src/components/content/Prompt.astro +25 -13
- package/src/components/layout/Header.astro +4 -8
- package/src/components/layout/Logo.astro +13 -1
- package/src/components/layout/PageFeedback.astro +1 -1
- package/src/components/layout/PageLayout.astro +4 -8
- package/src/components/layout/Pagination.astro +6 -6
- package/src/components/layout/RootLayout.astro +4 -8
- package/src/components/layout/Search.astro +1 -1
- package/src/components/layout/nav-utils.ts +9 -7
- package/src/core/config-input.ts +29 -8
- package/src/core/data.ts +9 -1
- package/src/core/navigation.ts +55 -13
- package/src/core/schema.ts +17 -1
- package/src/core/sources/watch.ts +5 -0
- package/src/core/types.ts +10 -0
- package/src/markdown/index.ts +2 -0
- package/src/markdown/language-icon.ts +2 -1
- package/src/markdown/table-wrap.ts +43 -0
- package/src/og/card.ts +39 -12
- package/src/og/index.ts +1 -1
- package/src/og/logo.ts +21 -0
- package/src/openapi/references.ts +19 -16
- package/src/theme/entry.ts +50 -5
package/dist/cli/index.js
CHANGED
|
@@ -525,11 +525,11 @@ Next steps:
|
|
|
525
525
|
});
|
|
526
526
|
|
|
527
527
|
// src/cli/commands/build.ts
|
|
528
|
-
import { existsSync as
|
|
528
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
529
529
|
import { readdir, stat, writeFile as writeFile7 } from "node:fs/promises";
|
|
530
530
|
import { build } from "astro";
|
|
531
531
|
import { defineCommand as defineCommand2 } from "citty";
|
|
532
|
-
import { join as
|
|
532
|
+
import { join as join25 } from "pathe";
|
|
533
533
|
|
|
534
534
|
// src/core/base-path.ts
|
|
535
535
|
var normalizeBasePath = (input) => {
|
|
@@ -3972,7 +3972,7 @@ var refuseIfDevRunning = (root, action, options = {}) => {
|
|
|
3972
3972
|
};
|
|
3973
3973
|
|
|
3974
3974
|
// src/astro/generate.ts
|
|
3975
|
-
import { existsSync as
|
|
3975
|
+
import { existsSync as existsSync13, readFileSync as readFileSync8, realpathSync } from "node:fs";
|
|
3976
3976
|
import {
|
|
3977
3977
|
lstat,
|
|
3978
3978
|
mkdir as mkdir6,
|
|
@@ -3984,7 +3984,7 @@ import {
|
|
|
3984
3984
|
} from "node:fs/promises";
|
|
3985
3985
|
import { createRequire as createRequire5 } from "node:module";
|
|
3986
3986
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
3987
|
-
import { basename as basename2, dirname as dirname8, join as
|
|
3987
|
+
import { basename as basename2, dirname as dirname8, join as join23, normalize as normalize3, relative as relative8 } from "pathe";
|
|
3988
3988
|
import { glob as glob5 } from "tinyglobby";
|
|
3989
3989
|
|
|
3990
3990
|
// src/ai/ask-data.ts
|
|
@@ -4899,10 +4899,7 @@ var resolveReferences = (config) => [
|
|
|
4899
4899
|
}, config.basePath),
|
|
4900
4900
|
...referencesFor("asyncapi", config.asyncapi, "Events", "scalar", NO_DISPLAY, config.basePath)
|
|
4901
4901
|
];
|
|
4902
|
-
var
|
|
4903
|
-
label: ref.label,
|
|
4904
|
-
path: ref.renderer === "blume" ? withBasePath(config.basePath, ref.route) : ref.route
|
|
4905
|
-
}));
|
|
4902
|
+
var referenceRoutes = (config) => resolveReferences(config).map((ref) => ref.renderer === "blume" ? withBasePath(config.basePath, ref.route) : ref.route);
|
|
4906
4903
|
var blumeReferenceOf = (ref, seen, usedSlugs) => {
|
|
4907
4904
|
if (ref.kind !== "openapi" || ref.renderer !== "blume") {
|
|
4908
4905
|
return null;
|
|
@@ -5480,6 +5477,7 @@ import { glob as glob2 } from "tinyglobby";
|
|
|
5480
5477
|
// src/core/sources/watch.ts
|
|
5481
5478
|
var BLUME_IGNORE_DIRS = [
|
|
5482
5479
|
".blume",
|
|
5480
|
+
".blume-verify",
|
|
5483
5481
|
".cache",
|
|
5484
5482
|
".git",
|
|
5485
5483
|
".next",
|
|
@@ -6431,7 +6429,7 @@ var navigationConfigSchema = z2.strictObject({
|
|
|
6431
6429
|
items: z2.array(sidebarItemSchema).optional()
|
|
6432
6430
|
})
|
|
6433
6431
|
]).default({}).transform((value) => Array.isArray(value) ? { display: "flat", items: value } : value),
|
|
6434
|
-
tabs: z2.array(navTabSchema).
|
|
6432
|
+
tabs: z2.array(navTabSchema).default([])
|
|
6435
6433
|
});
|
|
6436
6434
|
var exportConfigSchema = z2.union([
|
|
6437
6435
|
z2.boolean(),
|
|
@@ -6500,8 +6498,18 @@ var xConfigSchema = z2.strictObject({
|
|
|
6500
6498
|
creator: xHandleSchema,
|
|
6501
6499
|
handle: xHandleSchema
|
|
6502
6500
|
});
|
|
6501
|
+
var ogColorSchema = z2.string().regex(/^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/iu);
|
|
6502
|
+
var ogPaletteSchema = z2.strictObject({
|
|
6503
|
+
accent: ogColorSchema.optional(),
|
|
6504
|
+
background: ogColorSchema.optional(),
|
|
6505
|
+
border: ogColorSchema.optional(),
|
|
6506
|
+
foreground: ogColorSchema.optional(),
|
|
6507
|
+
muted: ogColorSchema.optional()
|
|
6508
|
+
});
|
|
6503
6509
|
var ogConfigSchema = z2.strictObject({
|
|
6504
|
-
enabled: z2.boolean().optional()
|
|
6510
|
+
enabled: z2.boolean().optional(),
|
|
6511
|
+
logo: z2.string().optional(),
|
|
6512
|
+
palette: ogPaletteSchema.optional()
|
|
6505
6513
|
});
|
|
6506
6514
|
var rssConfigSchema = z2.strictObject({
|
|
6507
6515
|
enabled: z2.boolean().default(true),
|
|
@@ -7646,14 +7654,29 @@ var resolveTsconfigAliases = (root) => {
|
|
|
7646
7654
|
return aliases;
|
|
7647
7655
|
};
|
|
7648
7656
|
|
|
7657
|
+
// src/og/logo.ts
|
|
7658
|
+
import { existsSync as existsSync11, readFileSync as readFileSync5 } from "node:fs";
|
|
7659
|
+
import { join as join18 } from "pathe";
|
|
7660
|
+
var resolveOgLogo = (project, source) => {
|
|
7661
|
+
if (!source?.toLowerCase().endsWith(".svg")) {
|
|
7662
|
+
return;
|
|
7663
|
+
}
|
|
7664
|
+
const relative6 = source.replace(/^\//u, "");
|
|
7665
|
+
const file = [
|
|
7666
|
+
join18(project.context.root, "public", relative6),
|
|
7667
|
+
join18(project.context.root, relative6)
|
|
7668
|
+
].find((path) => existsSync11(path));
|
|
7669
|
+
return file ? readFileSync5(file, "utf-8") : undefined;
|
|
7670
|
+
};
|
|
7671
|
+
|
|
7649
7672
|
// src/openapi/scalar.ts
|
|
7650
7673
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
7651
|
-
import { isAbsolute as isAbsolute8, join as
|
|
7674
|
+
import { isAbsolute as isAbsolute8, join as join20 } from "pathe";
|
|
7652
7675
|
|
|
7653
7676
|
// src/astro/templates.ts
|
|
7654
|
-
import { existsSync as
|
|
7677
|
+
import { existsSync as existsSync12, readFileSync as readFileSync6 } from "node:fs";
|
|
7655
7678
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
7656
|
-
import { dirname as dirname7, isAbsolute as isAbsolute7, join as
|
|
7679
|
+
import { dirname as dirname7, isAbsolute as isAbsolute7, join as join19, relative as relative6 } from "pathe";
|
|
7657
7680
|
var WORKSPACE_MARKERS = [
|
|
7658
7681
|
".git",
|
|
7659
7682
|
"bun.lock",
|
|
@@ -7664,17 +7687,17 @@ var WORKSPACE_MARKERS = [
|
|
|
7664
7687
|
"yarn.lock"
|
|
7665
7688
|
];
|
|
7666
7689
|
var hasWorkspacesField = (pkgPath) => {
|
|
7667
|
-
if (!
|
|
7690
|
+
if (!existsSync12(pkgPath)) {
|
|
7668
7691
|
return false;
|
|
7669
7692
|
}
|
|
7670
7693
|
try {
|
|
7671
|
-
const pkg = JSON.parse(
|
|
7694
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
|
|
7672
7695
|
return pkg.workspaces !== undefined;
|
|
7673
7696
|
} catch {
|
|
7674
7697
|
return false;
|
|
7675
7698
|
}
|
|
7676
7699
|
};
|
|
7677
|
-
var hasWorkspaceMarker = (dir) => hasWorkspacesField(
|
|
7700
|
+
var hasWorkspaceMarker = (dir) => hasWorkspacesField(join19(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync12(join19(dir, marker)));
|
|
7678
7701
|
var findWorkspaceRoot = (start) => {
|
|
7679
7702
|
let dir = start;
|
|
7680
7703
|
for (;; ) {
|
|
@@ -7697,6 +7720,23 @@ var ADAPTER_IMPORTS = {
|
|
|
7697
7720
|
var ADAPTER_OPTIONS = {
|
|
7698
7721
|
node: '{ mode: "standalone" }'
|
|
7699
7722
|
};
|
|
7723
|
+
var WRANGLER_CONFIG_FILES = [
|
|
7724
|
+
"wrangler.jsonc",
|
|
7725
|
+
"wrangler.json",
|
|
7726
|
+
"wrangler.toml"
|
|
7727
|
+
];
|
|
7728
|
+
var resolveCloudflareAdapterArgs = (context) => {
|
|
7729
|
+
const args = ['prerenderEnvironment: "node"'];
|
|
7730
|
+
const wranglerPath = WRANGLER_CONFIG_FILES.map((file) => join19(context.root, file)).find((file) => existsSync12(file));
|
|
7731
|
+
if (wranglerPath) {
|
|
7732
|
+
let configPath = relative6(context.outDir, wranglerPath);
|
|
7733
|
+
if (!configPath.startsWith(".") && !configPath.startsWith("/")) {
|
|
7734
|
+
configPath = `./${configPath}`;
|
|
7735
|
+
}
|
|
7736
|
+
args.push(`configPath: ${JSON.stringify(configPath)}`);
|
|
7737
|
+
}
|
|
7738
|
+
return `{ ${args.join(", ")} }`;
|
|
7739
|
+
};
|
|
7700
7740
|
var runtimeDependencies = (options) => {
|
|
7701
7741
|
const { config, needsReact, needsSvelte, needsVue } = options;
|
|
7702
7742
|
const deps = ["@astrojs/mdx"];
|
|
@@ -7763,7 +7803,15 @@ var astroConfigTemplate = (options) => {
|
|
|
7763
7803
|
const fsAllow = [...new Set([findWorkspaceRoot(context.root), context.root])];
|
|
7764
7804
|
const adapterImport = server && deployment.adapter ? `import adapter from "${ADAPTER_IMPORTS[deployment.adapter]}";
|
|
7765
7805
|
` : "";
|
|
7766
|
-
const adapterArgs =
|
|
7806
|
+
const adapterArgs = (() => {
|
|
7807
|
+
if (!server || !deployment.adapter) {
|
|
7808
|
+
return "";
|
|
7809
|
+
}
|
|
7810
|
+
if (deployment.adapter === "cloudflare") {
|
|
7811
|
+
return resolveCloudflareAdapterArgs(context);
|
|
7812
|
+
}
|
|
7813
|
+
return ADAPTER_OPTIONS[deployment.adapter] ?? "";
|
|
7814
|
+
})();
|
|
7767
7815
|
const adapterOption = server && deployment.adapter ? `
|
|
7768
7816
|
adapter: adapter(${adapterArgs}),` : "";
|
|
7769
7817
|
const siteOption = deployment.site ? `
|
|
@@ -7850,6 +7898,18 @@ export default defineConfig({
|
|
|
7850
7898
|
devToolbar: { enabled: false },
|
|
7851
7899
|
vite: {
|
|
7852
7900
|
plugins: [tailwindcss(), prerenderDepsPlugin(), serverAppResolvePlugin()],
|
|
7901
|
+
// Mermaid (lazy-loaded client-side for diagrams) statically imports dayjs as
|
|
7902
|
+
// CJS (\`dayjs/dayjs.min.js\`). In dev, an un-pre-bundled dependency is served
|
|
7903
|
+
// as raw ESM, and that UMD file exposes no \`default\` export, so mermaid
|
|
7904
|
+
// throws on load and diagrams render blank. Forcing mermaid through the dep
|
|
7905
|
+
// optimizer bundles dayjs with correct CJS interop. In a standalone install
|
|
7906
|
+
// Blume's dynamic \`import("mermaid")\` lives inside \`node_modules/blume\`,
|
|
7907
|
+
// which Vite's optimizer scan doesn't crawl, so mermaid is never discovered
|
|
7908
|
+
// on its own — hence the explicit include. mermaid resolves through the
|
|
7909
|
+
// \`blume\` package (it isn't a direct dep of the generated project), so the
|
|
7910
|
+
// nested \`blume > mermaid\` form is required. Production (Rollup) already
|
|
7911
|
+
// handles the interop, so this only affects dev.
|
|
7912
|
+
optimizeDeps: { include: ["blume > mermaid"] },
|
|
7853
7913
|
// Blume's render-time deps are forced external on both build environments so
|
|
7854
7914
|
// native bindings resolve at runtime and isolated linkers don't bundle
|
|
7855
7915
|
// symlinked store copies (which would surface their children as unresolvable
|
|
@@ -7888,14 +7948,14 @@ export default defineConfig({
|
|
|
7888
7948
|
// self-hosted fonts) -- pure noise the loader logs as "No entry type
|
|
7889
7949
|
// found". Vite appends this to its default ignores.
|
|
7890
7950
|
watch: {
|
|
7891
|
-
ignored: ${JSON.stringify([
|
|
7951
|
+
ignored: ${JSON.stringify([join19(context.outDir, ".astro", "**")])},
|
|
7892
7952
|
},
|
|
7893
7953
|
},
|
|
7894
7954
|
},
|
|
7895
7955
|
});
|
|
7896
7956
|
`;
|
|
7897
7957
|
};
|
|
7898
|
-
var stagedContentDir = (outDir) =>
|
|
7958
|
+
var stagedContentDir = (outDir) => join19(outDir, "content");
|
|
7899
7959
|
var astroGlobBase = (base) => isAbsolute7(base) ? pathToFileURL2(base).href : base;
|
|
7900
7960
|
var contentConfigTemplate = (options) => {
|
|
7901
7961
|
const { context, config } = options;
|
|
@@ -8178,9 +8238,10 @@ export function getStaticPaths() {
|
|
|
8178
8238
|
}));
|
|
8179
8239
|
}
|
|
8180
8240
|
|
|
8181
|
-
export function GET({ props }) {
|
|
8182
|
-
const
|
|
8183
|
-
|
|
8241
|
+
export function GET({ props }: { props: { route: string } }) {
|
|
8242
|
+
const entries = raw as Record<string, { md?: string; mdx?: string }>;
|
|
8243
|
+
const entry = entries[props.route];
|
|
8244
|
+
return new Response(entry ? ${kind === "md" ? '(entry.md ?? entry.mdx ?? "")' : '(entry.mdx ?? "")'} : "", {
|
|
8184
8245
|
headers: { "Content-Type": "text/markdown; charset=utf-8" },
|
|
8185
8246
|
});
|
|
8186
8247
|
}
|
|
@@ -8224,15 +8285,16 @@ export function getStaticPaths() {
|
|
|
8224
8285
|
}));
|
|
8225
8286
|
}
|
|
8226
8287
|
|
|
8227
|
-
export function GET({ props }) {
|
|
8228
|
-
|
|
8288
|
+
export function GET({ props }: { props: { section: string } }) {
|
|
8289
|
+
const bySection = feeds as Record<string, string>;
|
|
8290
|
+
return new Response(bySection[props.section] ?? "", {
|
|
8229
8291
|
headers: { "Content-Type": "application/rss+xml; charset=utf-8" },
|
|
8230
8292
|
});
|
|
8231
8293
|
}
|
|
8232
8294
|
`;
|
|
8233
8295
|
var ogEndpointTemplate = (customRoutes = []) => `// Generated by Blume. Do not edit.
|
|
8234
8296
|
import { renderOgImage } from "blume/og";
|
|
8235
|
-
import data from "
|
|
8297
|
+
import data from "blume:data";
|
|
8236
8298
|
|
|
8237
8299
|
export const prerender = true;
|
|
8238
8300
|
|
|
@@ -8240,9 +8302,9 @@ export const prerender = true;
|
|
|
8240
8302
|
const customRoutes = ${JSON.stringify(customRoutes)};
|
|
8241
8303
|
|
|
8242
8304
|
export function getStaticPaths() {
|
|
8243
|
-
const seen = new Set();
|
|
8244
|
-
const paths = [];
|
|
8245
|
-
const add = (slug, title) => {
|
|
8305
|
+
const seen = new Set<string>();
|
|
8306
|
+
const paths: { params: { slug: string }; props: { title: string } }[] = [];
|
|
8307
|
+
const add = (slug: string, title: string) => {
|
|
8246
8308
|
if (seen.has(slug)) {
|
|
8247
8309
|
return;
|
|
8248
8310
|
}
|
|
@@ -8275,17 +8337,18 @@ const siteHost = (() => {
|
|
|
8275
8337
|
}
|
|
8276
8338
|
})();
|
|
8277
8339
|
|
|
8278
|
-
export async function GET({ props }) {
|
|
8340
|
+
export async function GET({ props }: { props: { title: string } }) {
|
|
8279
8341
|
const png = await renderOgImage({
|
|
8280
|
-
accent: data.config.theme.accent.light,
|
|
8342
|
+
accent: data.config.og.palette?.accent ?? data.config.theme.accent.light,
|
|
8281
8343
|
brand: data.config.title,
|
|
8282
8344
|
description: data.config.description,
|
|
8283
|
-
logo: data.config.logo
|
|
8345
|
+
logo: data.config.og.logo,
|
|
8346
|
+
palette: data.config.og.palette,
|
|
8284
8347
|
repo: repoSlug,
|
|
8285
8348
|
site: siteHost,
|
|
8286
8349
|
title: props.title,
|
|
8287
8350
|
});
|
|
8288
|
-
return new Response(png, {
|
|
8351
|
+
return new Response(new Uint8Array(png), {
|
|
8289
8352
|
headers: {
|
|
8290
8353
|
"Cache-Control": "public, max-age=31536000, immutable",
|
|
8291
8354
|
"Content-Type": "image/png",
|
|
@@ -8344,6 +8407,7 @@ var catchAllPageTemplate = (options) => {
|
|
|
8344
8407
|
return `---
|
|
8345
8408
|
// Generated by Blume. Do not edit.
|
|
8346
8409
|
import { getEntry, render } from "astro:content";
|
|
8410
|
+
import type { CollectionKey } from "astro:content";
|
|
8347
8411
|
import RootLayout from "blume/components/layout/RootLayout.astro";
|
|
8348
8412
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
8349
8413
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
@@ -8387,7 +8451,7 @@ import ApiTagOperations from "blume/components/openapi/ApiTagOperations.astro";
|
|
|
8387
8451
|
import Operation from "blume/components/openapi/Operation.astro";
|
|
8388
8452
|
${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";
|
|
8389
8453
|
import { islandComponents } from "../generated/islands.ts";
|
|
8390
|
-
import data from "
|
|
8454
|
+
import data from "blume:data";
|
|
8391
8455
|
|
|
8392
8456
|
const Color = Object.assign(ColorRoot, { Item: ColorItem, Row: ColorRow });
|
|
8393
8457
|
const Tree = Object.assign(TreeRoot, { File: TreeFile, Folder: TreeFolder });
|
|
@@ -8456,7 +8520,7 @@ export function getStaticPaths() {
|
|
|
8456
8520
|
}
|
|
8457
8521
|
|
|
8458
8522
|
const { entryId, collection, route, title, indexable, editUrl, lastModified, locale, alternates, fallback } = Astro.props;
|
|
8459
|
-
const entry = await getEntry(collection, entryId);
|
|
8523
|
+
const entry = await getEntry(collection as CollectionKey, entryId);
|
|
8460
8524
|
if (!entry) {
|
|
8461
8525
|
return new Response(null, { status: 404 });
|
|
8462
8526
|
}
|
|
@@ -8491,18 +8555,18 @@ const canonical =
|
|
|
8491
8555
|
// Locale resolution. With i18n on, pick the active locale's nav + dictionary,
|
|
8492
8556
|
// build hreflang alternates, and derive the language-switcher targets.
|
|
8493
8557
|
const i18n = data.config.i18n;
|
|
8494
|
-
const localePrefix = (codeArg) =>
|
|
8558
|
+
const localePrefix = (codeArg: string) =>
|
|
8495
8559
|
i18n && codeArg === i18n.defaultLocale && i18n.hideDefaultLocalePrefix
|
|
8496
8560
|
? ""
|
|
8497
8561
|
: \`/\${codeArg}\`;
|
|
8498
|
-
const localizeRoute = (logical, codeArg) => {
|
|
8562
|
+
const localizeRoute = (logical: string, codeArg: string) => {
|
|
8499
8563
|
const prefix = localePrefix(codeArg);
|
|
8500
8564
|
if (!prefix) {
|
|
8501
8565
|
return logical;
|
|
8502
8566
|
}
|
|
8503
8567
|
return logical === "/" ? prefix : \`\${prefix}\${logical}\`;
|
|
8504
8568
|
};
|
|
8505
|
-
const stripLocale = (path, codeArg) => {
|
|
8569
|
+
const stripLocale = (path: string, codeArg: string) => {
|
|
8506
8570
|
const prefix = localePrefix(codeArg);
|
|
8507
8571
|
return prefix && path.startsWith(prefix) ? path.slice(prefix.length) || "/" : path;
|
|
8508
8572
|
};
|
|
@@ -8519,7 +8583,7 @@ const contentLocale =
|
|
|
8519
8583
|
const contentDir = i18n
|
|
8520
8584
|
? (i18n.locales.find((l) => l.code === contentLocale)?.dir ?? "ltr")
|
|
8521
8585
|
: "ltr";
|
|
8522
|
-
const absolute = (path) => {
|
|
8586
|
+
const absolute = (path: string) => {
|
|
8523
8587
|
const p = withBase(path);
|
|
8524
8588
|
return base + (p === "/" ? "" : p);
|
|
8525
8589
|
};
|
|
@@ -8612,14 +8676,15 @@ import Update from "blume/components/content/Update.astro";
|
|
|
8612
8676
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
8613
8677
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
8614
8678
|
import { layoutOverrides } from "../generated/components.ts";
|
|
8615
|
-
import data from "
|
|
8679
|
+
import data from "blume:data";
|
|
8616
8680
|
|
|
8617
8681
|
export const prerender = true;
|
|
8618
8682
|
|
|
8619
|
-
const entryDate = (entry
|
|
8620
|
-
|
|
8683
|
+
const entryDate = (entry: {
|
|
8684
|
+
data: { date?: string | null; changelog?: { date?: string | null } | null };
|
|
8685
|
+
}) => entry.data.date ?? entry.data.changelog?.date ?? null;
|
|
8621
8686
|
|
|
8622
|
-
const toTime = (value) => {
|
|
8687
|
+
const toTime = (value: string | null | undefined) => {
|
|
8623
8688
|
if (!value) {
|
|
8624
8689
|
return 0;
|
|
8625
8690
|
}
|
|
@@ -8627,7 +8692,7 @@ const toTime = (value) => {
|
|
|
8627
8692
|
return Number.isNaN(date.getTime()) ? 0 : date.getTime();
|
|
8628
8693
|
};
|
|
8629
8694
|
|
|
8630
|
-
const formatDate = (value) => {
|
|
8695
|
+
const formatDate = (value: string | null | undefined) => {
|
|
8631
8696
|
if (!value) {
|
|
8632
8697
|
return;
|
|
8633
8698
|
}
|
|
@@ -8640,14 +8705,14 @@ const formatDate = (value) => {
|
|
|
8640
8705
|
}).format(date);
|
|
8641
8706
|
};
|
|
8642
8707
|
|
|
8643
|
-
const slugify = (text) =>
|
|
8708
|
+
const slugify = (text: string) =>
|
|
8644
8709
|
text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") ||
|
|
8645
8710
|
"update";
|
|
8646
8711
|
|
|
8647
8712
|
// The major of a version's embedded semver (\`1.2.3\` -> 1, \`pkg@2.0.0\` -> 2), or
|
|
8648
8713
|
// null when there is no full major.minor.patch to key on. Drives the changelog's
|
|
8649
8714
|
// group-by-major pagination, so it tolerates the scoped tags monorepos publish.
|
|
8650
|
-
const majorVersion = (version) => {
|
|
8715
|
+
const majorVersion = (version: string | null | undefined) => {
|
|
8651
8716
|
const match = /(\\d+)\\.\\d+\\.\\d+/.exec(String(version ?? ""));
|
|
8652
8717
|
return match ? Number(match[1]) : null;
|
|
8653
8718
|
};
|
|
@@ -8679,7 +8744,7 @@ const items = await Promise.all(
|
|
|
8679
8744
|
return {
|
|
8680
8745
|
Content: (await render(entry)).Content,
|
|
8681
8746
|
date: formatDate(entryDate(entry)),
|
|
8682
|
-
href: routeByEntry.get(entry.id) ??
|
|
8747
|
+
href: routeByEntry.get(entry.id) ?? undefined,
|
|
8683
8748
|
id: slugify(label),
|
|
8684
8749
|
label,
|
|
8685
8750
|
major: majorVersion(entry.data.changelog?.version),
|
|
@@ -8708,7 +8773,9 @@ for (const item of items) {
|
|
|
8708
8773
|
// semver and they span more than one major line. Older majors then collapse
|
|
8709
8774
|
// into groups the reader reveals one at a time; otherwise the timeline is flat.
|
|
8710
8775
|
const majors = items.every((item) => item.major !== null)
|
|
8711
|
-
? [...new Set(items.map((item) => item.major))]
|
|
8776
|
+
? [...new Set(items.map((item) => item.major))]
|
|
8777
|
+
.filter((major): major is number => major !== null)
|
|
8778
|
+
.toSorted((a, b) => b - a)
|
|
8712
8779
|
: [];
|
|
8713
8780
|
const paginate = majors.length > 1;
|
|
8714
8781
|
const majorGroups = majors.map((major) => ({
|
|
@@ -8846,7 +8913,7 @@ var notFoundPageTemplate = () => `---
|
|
|
8846
8913
|
// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
|
|
8847
8914
|
import PageLayout from "blume/components/layout/PageLayout.astro";
|
|
8848
8915
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
8849
|
-
import data from "
|
|
8916
|
+
import data from "blume:data";
|
|
8850
8917
|
|
|
8851
8918
|
export const prerender = true;
|
|
8852
8919
|
|
|
@@ -8963,7 +9030,10 @@ export const getStaticPaths = () =>
|
|
|
8963
9030
|
Object.keys(examples).map((path) => ({ params: { path } }));
|
|
8964
9031
|
|
|
8965
9032
|
const { path } = Astro.params;
|
|
8966
|
-
const entry = examples[path];
|
|
9033
|
+
const entry = path ? examples[path] : undefined;
|
|
9034
|
+
if (!entry) {
|
|
9035
|
+
return new Response(null, { status: 404 });
|
|
9036
|
+
}
|
|
8967
9037
|
const Example = entry.Component;
|
|
8968
9038
|
---
|
|
8969
9039
|
|
|
@@ -9017,6 +9087,14 @@ declare module "blume:data" {
|
|
|
9017
9087
|
export default data;
|
|
9018
9088
|
}
|
|
9019
9089
|
|
|
9090
|
+
declare module "blume:examples" {
|
|
9091
|
+
type Examples = typeof import("./generated/examples.ts").examples;
|
|
9092
|
+
export const examples: Record<string, Examples[keyof Examples]>;
|
|
9093
|
+
export const examplesBase: string;
|
|
9094
|
+
}
|
|
9095
|
+
|
|
9096
|
+
declare module "blume:examples-theme";
|
|
9097
|
+
|
|
9020
9098
|
declare module "blume:openapi" {
|
|
9021
9099
|
const specs: import("blume/openapi/model.ts").OpenApiData;
|
|
9022
9100
|
export default specs;
|
|
@@ -9147,7 +9225,7 @@ var specConfiguration = async (spec, root) => {
|
|
|
9147
9225
|
if (URL_SPEC2.test(spec)) {
|
|
9148
9226
|
return { config: { url: spec } };
|
|
9149
9227
|
}
|
|
9150
|
-
const absolute = isAbsolute8(spec) ? spec :
|
|
9228
|
+
const absolute = isAbsolute8(spec) ? spec : join20(root, spec);
|
|
9151
9229
|
try {
|
|
9152
9230
|
return { config: { content: await readFile8(absolute, "utf-8") } };
|
|
9153
9231
|
} catch {
|
|
@@ -9213,6 +9291,13 @@ var buildReferenceFiles = async (options) => {
|
|
|
9213
9291
|
// src/theme/entry.ts
|
|
9214
9292
|
var DARK_VARIANT = `/* Dark mode is driven by data-theme on the <html> element. */
|
|
9215
9293
|
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));`;
|
|
9294
|
+
var COLOR_SCHEME_DEFAULTS = `:root {
|
|
9295
|
+
color-scheme: light;
|
|
9296
|
+
}
|
|
9297
|
+
|
|
9298
|
+
:root[data-theme="dark"] {
|
|
9299
|
+
color-scheme: dark;
|
|
9300
|
+
}`;
|
|
9216
9301
|
var TOKEN_DEFAULTS = `:root {
|
|
9217
9302
|
--blume-background: oklch(1 0 0);
|
|
9218
9303
|
--blume-background-image: none;
|
|
@@ -9318,6 +9403,8 @@ ${options.sources.map((source) => `@source "${source}";`).join(`
|
|
|
9318
9403
|
|
|
9319
9404
|
${DARK_VARIANT}
|
|
9320
9405
|
|
|
9406
|
+
${COLOR_SCHEME_DEFAULTS}
|
|
9407
|
+
|
|
9321
9408
|
${TOKEN_DEFAULTS}
|
|
9322
9409
|
|
|
9323
9410
|
${THEME_MAPPING}
|
|
@@ -9563,13 +9650,16 @@ blume-diff {
|
|
|
9563
9650
|
|
|
9564
9651
|
/* Language icon (simple-icons) sits at the header's left edge; the label shifts
|
|
9565
9652
|
right to make room. Injected at build time by the language-icon transformer.
|
|
9566
|
-
|
|
9567
|
-
|
|
9653
|
+
The icon is gated on data-language (the header bar), not just data-icon: the
|
|
9654
|
+
transformer runs whenever icons are on, but a header-less standalone
|
|
9655
|
+
CodeBlock (no title) never gets data-language, so without this gate the
|
|
9656
|
+
absolutely-positioned icon would overlap the first code line. Fenced code
|
|
9657
|
+
and titled blocks always have a header, so the icon shows there. */
|
|
9568
9658
|
.blume-lang-icon {
|
|
9569
9659
|
display: none;
|
|
9570
9660
|
}
|
|
9571
9661
|
|
|
9572
|
-
.prose > :where(pre[data-icon]) > .blume-lang-icon {
|
|
9662
|
+
.prose > :where(pre[data-language][data-icon]) > .blume-lang-icon {
|
|
9573
9663
|
color: var(--blume-muted-foreground);
|
|
9574
9664
|
display: block;
|
|
9575
9665
|
height: 0.875rem;
|
|
@@ -9579,7 +9669,7 @@ blume-diff {
|
|
|
9579
9669
|
width: 0.875rem;
|
|
9580
9670
|
}
|
|
9581
9671
|
|
|
9582
|
-
.prose > :where(pre[data-icon])::before {
|
|
9672
|
+
.prose > :where(pre[data-language][data-icon])::before {
|
|
9583
9673
|
padding-left: 2.5rem;
|
|
9584
9674
|
}
|
|
9585
9675
|
|
|
@@ -9630,11 +9720,40 @@ blume-diff {
|
|
|
9630
9720
|
font-size: 0.8125rem;
|
|
9631
9721
|
}
|
|
9632
9722
|
|
|
9723
|
+
/* Scroll wide tables in place; the wrapper is added by the blume:table-wrap hast
|
|
9724
|
+
plugin. The border+radius frames the scroll viewport so a clipped wide table
|
|
9725
|
+
reads as scrollable rather than cut off, and carries the table's vertical
|
|
9726
|
+
rhythm (the inner table's own margin is zeroed so it fills the frame). */
|
|
9727
|
+
.blume-table-scroll {
|
|
9728
|
+
overflow-x: auto;
|
|
9729
|
+
-webkit-overflow-scrolling: touch;
|
|
9730
|
+
margin: 1.5rem 0;
|
|
9731
|
+
border: 1px solid var(--blume-border);
|
|
9732
|
+
border-radius: var(--blume-radius);
|
|
9733
|
+
}
|
|
9734
|
+
.blume-table-scroll > table {
|
|
9735
|
+
margin: 0;
|
|
9736
|
+
}
|
|
9737
|
+
/* Restore inner padding on every cell. Typography zeroes the first/last cell's
|
|
9738
|
+
inline padding so a borderless table aligns to the prose margin; inside the
|
|
9739
|
+
framed wrapper that leaves edge text touching the border. The :is() selector
|
|
9740
|
+
outweighs Typography's :where()-scoped rules so the outer columns get it too. */
|
|
9741
|
+
.blume-table-scroll :is(th, td) {
|
|
9742
|
+
padding: 0.5rem 0.75rem;
|
|
9743
|
+
}
|
|
9744
|
+
/* Keep column labels on one line so a two-word header does not wrap into a
|
|
9745
|
+
ragged stack; the table just scrolls a little wider instead. Body cells keep
|
|
9746
|
+
wrapping so a wide table stays a scroll away, not an endless horizontal run. */
|
|
9747
|
+
.blume-table-scroll th {
|
|
9748
|
+
white-space: nowrap;
|
|
9749
|
+
}
|
|
9750
|
+
|
|
9633
9751
|
/* GFM renders cells as <td><code> directly, which the descendant form alone
|
|
9634
9752
|
never matches (a cell is not its own descendant). */
|
|
9635
9753
|
.prose :where(td, th) > code,
|
|
9636
9754
|
.prose :where(td, th) :not(pre) > code {
|
|
9637
|
-
|
|
9755
|
+
overflow-wrap: break-word;
|
|
9756
|
+
white-space: normal;
|
|
9638
9757
|
}
|
|
9639
9758
|
|
|
9640
9759
|
blume-tabs pre,
|
|
@@ -9874,6 +9993,8 @@ ${options.sources.map((source) => `@source "${source}";`).join(`
|
|
|
9874
9993
|
|
|
9875
9994
|
${DARK_VARIANT}
|
|
9876
9995
|
|
|
9996
|
+
${COLOR_SCHEME_DEFAULTS}
|
|
9997
|
+
|
|
9877
9998
|
${TOKEN_DEFAULTS}
|
|
9878
9999
|
|
|
9879
10000
|
${THEME_MAPPING}
|
|
@@ -9894,7 +10015,7 @@ ${options.userCss}
|
|
|
9894
10015
|
`;
|
|
9895
10016
|
|
|
9896
10017
|
// src/theme/twoslash.ts
|
|
9897
|
-
import { readFileSync as
|
|
10018
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
9898
10019
|
import { createRequire as createRequire4 } from "node:module";
|
|
9899
10020
|
var require2 = createRequire4(import.meta.url);
|
|
9900
10021
|
var OVERRIDES = `
|
|
@@ -9961,14 +10082,15 @@ var OVERRIDES = `
|
|
|
9961
10082
|
`;
|
|
9962
10083
|
var twoslashCss = () => {
|
|
9963
10084
|
const file = require2.resolve("@shikijs/twoslash/style-rich.css");
|
|
9964
|
-
return `${
|
|
10085
|
+
return `${readFileSync7(file, "utf-8")}
|
|
9965
10086
|
${OVERRIDES}`;
|
|
9966
10087
|
};
|
|
9967
10088
|
|
|
9968
10089
|
// src/astro/component-slots.ts
|
|
9969
10090
|
var EMPTY_MODULE = `// Generated by Blume. Do not edit.
|
|
9970
|
-
|
|
9971
|
-
export const
|
|
10091
|
+
import type { ComponentOverride } from "blume/core/define-components.ts";
|
|
10092
|
+
export const mdxComponents: Record<string, ComponentOverride> = {};
|
|
10093
|
+
export const layoutOverrides: Record<string, ComponentOverride> = {};
|
|
9972
10094
|
`;
|
|
9973
10095
|
var attributeValue = (value) => value.replaceAll(/["\n\r]/gu, " ").trim();
|
|
9974
10096
|
var CLIENT_LOAD = "client:load";
|
|
@@ -10066,12 +10188,12 @@ export const layoutOverrides = { ...(overrides.layout ?? {})${layoutEntries.leng
|
|
|
10066
10188
|
|
|
10067
10189
|
// src/astro/examples.ts
|
|
10068
10190
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
10069
|
-
import { join as
|
|
10191
|
+
import { join as join22, relative as relative7 } from "pathe";
|
|
10070
10192
|
import { glob as glob4 } from "tinyglobby";
|
|
10071
10193
|
|
|
10072
10194
|
// src/astro/islands.ts
|
|
10073
10195
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
10074
|
-
import { basename, join as
|
|
10196
|
+
import { basename, join as join21 } from "pathe";
|
|
10075
10197
|
import { glob as glob3 } from "tinyglobby";
|
|
10076
10198
|
var DEFAULT_CLIENT = "visible";
|
|
10077
10199
|
var VALID_MODES = new Set([
|
|
@@ -10100,7 +10222,7 @@ var readClientMode = (source, file, warnings) => {
|
|
|
10100
10222
|
return mode;
|
|
10101
10223
|
};
|
|
10102
10224
|
var discoverIslands = async (root) => {
|
|
10103
|
-
const dir =
|
|
10225
|
+
const dir = join21(root, "islands");
|
|
10104
10226
|
const matches = await glob3(["**/*.{jsx,svelte,tsx,vue}"], {
|
|
10105
10227
|
absolute: true,
|
|
10106
10228
|
cwd: dir,
|
|
@@ -10163,7 +10285,7 @@ var splitGlobBase = (pattern) => {
|
|
|
10163
10285
|
};
|
|
10164
10286
|
var discoverExamples = async (root, pattern = "examples") => {
|
|
10165
10287
|
const { base, rest } = GLOB_MAGIC.test(pattern) ? splitGlobBase(pattern) : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };
|
|
10166
|
-
const dir =
|
|
10288
|
+
const dir = join22(root, base);
|
|
10167
10289
|
const matches = await glob4([rest], {
|
|
10168
10290
|
absolute: true,
|
|
10169
10291
|
cwd: dir,
|
|
@@ -10203,10 +10325,10 @@ var discoverExamples = async (root, pattern = "examples") => {
|
|
|
10203
10325
|
};
|
|
10204
10326
|
|
|
10205
10327
|
// src/astro/generate.ts
|
|
10206
|
-
var BLUME_SRC =
|
|
10328
|
+
var BLUME_SRC = join23(packageRoot(), "src");
|
|
10207
10329
|
var canResolveFrom = (fromDir, spec) => {
|
|
10208
10330
|
try {
|
|
10209
|
-
createRequire5(pathToFileURL3(
|
|
10331
|
+
createRequire5(pathToFileURL3(join23(fromDir, "_.js")).href).resolve(spec);
|
|
10210
10332
|
return true;
|
|
10211
10333
|
} catch {
|
|
10212
10334
|
return false;
|
|
@@ -10217,7 +10339,7 @@ var resolveReactCompiler = (config, needsReact) => {
|
|
|
10217
10339
|
return null;
|
|
10218
10340
|
}
|
|
10219
10341
|
try {
|
|
10220
|
-
return createRequire5(pathToFileURL3(
|
|
10342
|
+
return createRequire5(pathToFileURL3(join23(packageRoot(), "_.js")).href).resolve("babel-plugin-react-compiler");
|
|
10221
10343
|
} catch {
|
|
10222
10344
|
return null;
|
|
10223
10345
|
}
|
|
@@ -10227,15 +10349,15 @@ var reactCompilerWarnings = (config, needsReact, compilerPath) => needsReact &&
|
|
|
10227
10349
|
] : [];
|
|
10228
10350
|
var resolvedAstroPath = (fromDir) => {
|
|
10229
10351
|
try {
|
|
10230
|
-
const pkg = createRequire5(pathToFileURL3(
|
|
10352
|
+
const pkg = createRequire5(pathToFileURL3(join23(fromDir, "_.js")).href).resolve("astro/package.json");
|
|
10231
10353
|
return realpathSync(pkg);
|
|
10232
10354
|
} catch {
|
|
10233
10355
|
return null;
|
|
10234
10356
|
}
|
|
10235
10357
|
};
|
|
10236
10358
|
var blumeDepsDir = (pkgDir = packageRoot()) => {
|
|
10237
|
-
const candidates = [
|
|
10238
|
-
return candidates.find((dir) =>
|
|
10359
|
+
const candidates = [join23(pkgDir, "node_modules"), dirname8(pkgDir)];
|
|
10360
|
+
return candidates.find((dir) => existsSync13(join23(dir, "astro"))) ?? null;
|
|
10239
10361
|
};
|
|
10240
10362
|
var linkDepsJunction = async (link, depsDir) => {
|
|
10241
10363
|
let existing;
|
|
@@ -10258,7 +10380,7 @@ var readPkgVersion = (pkgJsonPath) => {
|
|
|
10258
10380
|
return null;
|
|
10259
10381
|
}
|
|
10260
10382
|
try {
|
|
10261
|
-
return JSON.parse(
|
|
10383
|
+
return JSON.parse(readFileSync8(pkgJsonPath, "utf-8")).version ?? null;
|
|
10262
10384
|
} catch {
|
|
10263
10385
|
return null;
|
|
10264
10386
|
}
|
|
@@ -10280,8 +10402,8 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
|
10280
10402
|
if (blumeAstro && outDirAstro === blumeAstro) {
|
|
10281
10403
|
return null;
|
|
10282
10404
|
}
|
|
10283
|
-
if (
|
|
10284
|
-
await linkDepsJunction(
|
|
10405
|
+
if (existsSync13(join23(depsDir, "@astrojs", "mdx"))) {
|
|
10406
|
+
await linkDepsJunction(join23(outDir, "node_modules"), depsDir);
|
|
10285
10407
|
return null;
|
|
10286
10408
|
}
|
|
10287
10409
|
return astroConflictWarning(blumeAstro, outDirAstro);
|
|
@@ -10313,14 +10435,14 @@ var deploymentAdapterWarnings = (deployment, root) => {
|
|
|
10313
10435
|
}
|
|
10314
10436
|
return [];
|
|
10315
10437
|
};
|
|
10316
|
-
var examplesCssFile = (root, config) => config.examples.css ?
|
|
10438
|
+
var examplesCssFile = (root, config) => config.examples.css ? join23(root, config.examples.css) : null;
|
|
10317
10439
|
var writeExamplesPreview = async (options) => {
|
|
10318
10440
|
const { config, hasExamples, root, srcDir, write } = options;
|
|
10319
10441
|
if (hasExamples) {
|
|
10320
|
-
await write(
|
|
10442
|
+
await write(join23(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
|
|
10321
10443
|
}
|
|
10322
10444
|
const cssFile = examplesCssFile(root, config);
|
|
10323
|
-
return cssFile && !
|
|
10445
|
+
return cssFile && !existsSync13(cssFile) ? [
|
|
10324
10446
|
`examples.css points at "${config.examples.css}", which doesn't exist; previews render without it.`
|
|
10325
10447
|
] : [];
|
|
10326
10448
|
};
|
|
@@ -10349,7 +10471,7 @@ var detectUsesMath = async (root, staged = []) => {
|
|
|
10349
10471
|
ignore: ["**/node_modules/**", "**/.blume/**", "**/dist/**"],
|
|
10350
10472
|
onlyFiles: true
|
|
10351
10473
|
});
|
|
10352
|
-
const contents = await Promise.all(files.map((file) => readOptional(
|
|
10474
|
+
const contents = await Promise.all(files.map((file) => readOptional(join23(root, file))));
|
|
10353
10475
|
return [...contents, ...staged].some(containsMath);
|
|
10354
10476
|
};
|
|
10355
10477
|
var writeIfChanged = async (path, content) => {
|
|
@@ -10401,14 +10523,46 @@ var writeStagedContent = async (out, staged) => {
|
|
|
10401
10523
|
const contentDir = stagedContentDir(out);
|
|
10402
10524
|
const written = new Set;
|
|
10403
10525
|
await Promise.all([...staged].map(async ([entryId, text]) => {
|
|
10404
|
-
const path =
|
|
10526
|
+
const path = join23(contentDir, entryId);
|
|
10405
10527
|
written.add(normalize3(path));
|
|
10406
10528
|
await writeIfChanged(path, text);
|
|
10407
10529
|
}));
|
|
10408
|
-
if (
|
|
10530
|
+
if (existsSync13(contentDir)) {
|
|
10409
10531
|
await pruneOrphans(contentDir, written);
|
|
10410
10532
|
}
|
|
10411
10533
|
};
|
|
10534
|
+
var SVG_ROOT = /<svg\b(?<attributes>[^>]*)>/u;
|
|
10535
|
+
var SVG_WIDTH = /\bwidth\s*=\s*["'](?<value>[^"']+)["']/u;
|
|
10536
|
+
var SVG_HEIGHT = /\bheight\s*=\s*["'](?<value>[^"']+)["']/u;
|
|
10537
|
+
var SVG_LENGTH = /^\s*(?<value>[\d.]+)(?:px)?\s*$/u;
|
|
10538
|
+
var SVG_VIEW_BOX = /\bviewBox\s*=\s*["'][\d.-]+[\s,]+[\d.-]+[\s,]+(?<width>[\d.]+)[\s,]+(?<height>[\d.]+)["']/u;
|
|
10539
|
+
var parseSvgLength = (value) => {
|
|
10540
|
+
const length = Number(value?.match(SVG_LENGTH)?.groups?.value);
|
|
10541
|
+
return length > 0 ? length : undefined;
|
|
10542
|
+
};
|
|
10543
|
+
var svgDimensions = (svg) => {
|
|
10544
|
+
const attributes = svg?.match(SVG_ROOT)?.groups?.attributes;
|
|
10545
|
+
const width = parseSvgLength(attributes?.match(SVG_WIDTH)?.groups?.value);
|
|
10546
|
+
const height = parseSvgLength(attributes?.match(SVG_HEIGHT)?.groups?.value);
|
|
10547
|
+
if (width && height) {
|
|
10548
|
+
return { height, width };
|
|
10549
|
+
}
|
|
10550
|
+
const viewBox = attributes?.match(SVG_VIEW_BOX);
|
|
10551
|
+
const viewBoxWidth = Number(viewBox?.groups?.width);
|
|
10552
|
+
const viewBoxHeight = Number(viewBox?.groups?.height);
|
|
10553
|
+
return viewBoxWidth > 0 && viewBoxHeight > 0 ? { height: viewBoxHeight, width: viewBoxWidth } : undefined;
|
|
10554
|
+
};
|
|
10555
|
+
var readLogoSvg = (project, source) => {
|
|
10556
|
+
if (!source?.toLowerCase().endsWith(".svg")) {
|
|
10557
|
+
return;
|
|
10558
|
+
}
|
|
10559
|
+
const rel = source.replace(/^\//u, "");
|
|
10560
|
+
const file = [
|
|
10561
|
+
join23(project.context.root, "public", rel),
|
|
10562
|
+
join23(project.context.root, rel)
|
|
10563
|
+
].find((path) => existsSync13(path));
|
|
10564
|
+
return file ? readFileSync8(file, "utf-8") : undefined;
|
|
10565
|
+
};
|
|
10412
10566
|
var resolveLogo = (project) => {
|
|
10413
10567
|
const { logo } = project.config;
|
|
10414
10568
|
if (!logo) {
|
|
@@ -10421,17 +10575,15 @@ var resolveLogo = (project) => {
|
|
|
10421
10575
|
const dark = image?.dark ?? image?.light;
|
|
10422
10576
|
const alt = image?.alt ?? "";
|
|
10423
10577
|
const brandHref = href ?? "/";
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
join22(project.context.root, rel)
|
|
10429
|
-
].find((path) => existsSync12(path));
|
|
10430
|
-
if (file) {
|
|
10431
|
-
return { alt, href: brandHref, svg: readFileSync7(file, "utf-8"), text };
|
|
10432
|
-
}
|
|
10578
|
+
const lightSvg = readLogoSvg(project, light);
|
|
10579
|
+
const darkSvg = dark === light ? lightSvg : readLogoSvg(project, dark);
|
|
10580
|
+
if (light && light === dark && lightSvg) {
|
|
10581
|
+
return { alt, href: brandHref, svg: lightSvg, text };
|
|
10433
10582
|
}
|
|
10434
|
-
|
|
10583
|
+
const lightDimensions = svgDimensions(lightSvg);
|
|
10584
|
+
const darkDimensions = svgDimensions(darkSvg);
|
|
10585
|
+
const dimensions = lightDimensions || darkDimensions ? { dark: darkDimensions, light: lightDimensions } : undefined;
|
|
10586
|
+
return { alt, dark, dimensions, href: brandHref, light, text };
|
|
10435
10587
|
};
|
|
10436
10588
|
var FAVICON_CANDIDATES = [
|
|
10437
10589
|
"icon.svg",
|
|
@@ -10452,9 +10604,9 @@ var faviconType = (name) => {
|
|
|
10452
10604
|
const ext = name.split(".").pop()?.toLowerCase();
|
|
10453
10605
|
return ext ? FAVICON_TYPES[ext] : undefined;
|
|
10454
10606
|
};
|
|
10455
|
-
var inlineDataUri = (file, type) => `data:${type};base64,${
|
|
10607
|
+
var inlineDataUri = (file, type) => `data:${type};base64,${readFileSync8(file).toString("base64")}`;
|
|
10456
10608
|
var defaultFavicon = () => ({
|
|
10457
|
-
href: inlineDataUri(
|
|
10609
|
+
href: inlineDataUri(join23(BLUME_SRC, "assets", "icon.png"), "image/png"),
|
|
10458
10610
|
type: "image/png"
|
|
10459
10611
|
});
|
|
10460
10612
|
var APPLE_ICON_CANDIDATES = [
|
|
@@ -10466,13 +10618,13 @@ var APPLE_ICON_CANDIDATES = [
|
|
|
10466
10618
|
var resolveIconFile = (project, candidates) => {
|
|
10467
10619
|
const { root } = project.context;
|
|
10468
10620
|
for (const name of candidates) {
|
|
10469
|
-
if (
|
|
10621
|
+
if (existsSync13(join23(root, "public", name))) {
|
|
10470
10622
|
return { href: `/${name}`, type: faviconType(name) };
|
|
10471
10623
|
}
|
|
10472
10624
|
}
|
|
10473
10625
|
for (const name of candidates) {
|
|
10474
|
-
const file =
|
|
10475
|
-
if (
|
|
10626
|
+
const file = join23(root, name);
|
|
10627
|
+
if (existsSync13(file)) {
|
|
10476
10628
|
const type = faviconType(name);
|
|
10477
10629
|
return { href: inlineDataUri(file, type ?? "image/x-icon"), type };
|
|
10478
10630
|
}
|
|
@@ -10501,6 +10653,8 @@ var buildRuntimeData = (project) => {
|
|
|
10501
10653
|
const { github } = config;
|
|
10502
10654
|
const repoUrl = github ? `https://github.com/${github.owner}/${github.repo}` : null;
|
|
10503
10655
|
const editBase = github ? `${repoUrl}/edit/${github.branch}` : null;
|
|
10656
|
+
const logo = resolveLogo(project);
|
|
10657
|
+
const ogLogo = config.seo.og.logo ? resolveOgLogo(project, config.seo.og.logo) : logo?.svg;
|
|
10504
10658
|
const editUrlFor = (sourcePath) => {
|
|
10505
10659
|
if (!(editBase && sourcePath)) {
|
|
10506
10660
|
return null;
|
|
@@ -10510,10 +10664,9 @@ var buildRuntimeData = (project) => {
|
|
|
10510
10664
|
return `${editBase}/${editPath}`;
|
|
10511
10665
|
};
|
|
10512
10666
|
const { i18n } = config;
|
|
10513
|
-
const
|
|
10667
|
+
const withRepoUrl = (nav) => ({
|
|
10514
10668
|
...nav,
|
|
10515
|
-
repoUrl: config.navigation.repo && repoUrl ? repoUrl : null
|
|
10516
|
-
tabs: [...nav.tabs, ...referenceTabs(config)]
|
|
10669
|
+
repoUrl: config.navigation.repo && repoUrl ? repoUrl : null
|
|
10517
10670
|
});
|
|
10518
10671
|
const uiByLocale = i18n ? Object.fromEntries(i18n.locales.map(({ code }) => [
|
|
10519
10672
|
code,
|
|
@@ -10528,7 +10681,7 @@ var buildRuntimeData = (project) => {
|
|
|
10528
10681
|
}) : EN_UI;
|
|
10529
10682
|
const navigationByLocale = i18n ? Object.fromEntries(i18n.locales.map(({ code }) => [
|
|
10530
10683
|
code,
|
|
10531
|
-
|
|
10684
|
+
withRepoUrl(graph.navigationByLocale[code] ?? {
|
|
10532
10685
|
featured: [],
|
|
10533
10686
|
selectors: [],
|
|
10534
10687
|
sidebar: [],
|
|
@@ -10558,12 +10711,16 @@ var buildRuntimeData = (project) => {
|
|
|
10558
10711
|
}))
|
|
10559
10712
|
} : null,
|
|
10560
10713
|
imageZoom: config.markdown.imageZoom,
|
|
10561
|
-
logo
|
|
10714
|
+
logo,
|
|
10562
10715
|
mcp: config.ai.mcp.enabled ? {
|
|
10563
10716
|
name: config.ai.mcp.name ?? config.title,
|
|
10564
10717
|
route: config.ai.mcp.route
|
|
10565
10718
|
} : null,
|
|
10566
|
-
og: {
|
|
10719
|
+
og: {
|
|
10720
|
+
enabled: config.seo.og.enabled ?? false,
|
|
10721
|
+
logo: ogLogo,
|
|
10722
|
+
palette: config.seo.og.palette
|
|
10723
|
+
},
|
|
10567
10724
|
repoUrl,
|
|
10568
10725
|
search: {
|
|
10569
10726
|
enabled: config.search.provider !== "none",
|
|
@@ -10581,7 +10738,7 @@ var buildRuntimeData = (project) => {
|
|
|
10581
10738
|
title: feed.title
|
|
10582
10739
|
})),
|
|
10583
10740
|
fontCssVars: configuredCssVars(config.theme.fonts),
|
|
10584
|
-
navigation:
|
|
10741
|
+
navigation: withRepoUrl(graph.navigation),
|
|
10585
10742
|
navigationByLocale,
|
|
10586
10743
|
routes: manifest.routes.map((route) => ({
|
|
10587
10744
|
alternates: route.alternates,
|
|
@@ -10607,7 +10764,7 @@ var buildRuntimeData = (project) => {
|
|
|
10607
10764
|
var planMcp = (project, srcDir, userPages) => {
|
|
10608
10765
|
const { config } = project;
|
|
10609
10766
|
const { route } = config.ai.mcp;
|
|
10610
|
-
const dir =
|
|
10767
|
+
const dir = join23(srcDir, "blume-mcp");
|
|
10611
10768
|
const base = {
|
|
10612
10769
|
dir,
|
|
10613
10770
|
discoveryPages: [],
|
|
@@ -10631,11 +10788,11 @@ var planMcp = (project, srcDir, userPages) => {
|
|
|
10631
10788
|
...base,
|
|
10632
10789
|
discoveryPages: [
|
|
10633
10790
|
{
|
|
10634
|
-
entrypoint:
|
|
10791
|
+
entrypoint: join23(dir, "discovery.ts"),
|
|
10635
10792
|
pattern: "/.well-known/mcp.json"
|
|
10636
10793
|
},
|
|
10637
10794
|
{
|
|
10638
|
-
entrypoint:
|
|
10795
|
+
entrypoint: join23(dir, "server-card.ts"),
|
|
10639
10796
|
pattern: "/.well-known/mcp/server-card.json"
|
|
10640
10797
|
}
|
|
10641
10798
|
],
|
|
@@ -10655,11 +10812,11 @@ var writeMcpFiles = async (project, plan, write) => {
|
|
|
10655
10812
|
version: data.version
|
|
10656
10813
|
};
|
|
10657
10814
|
await Promise.all([
|
|
10658
|
-
write(
|
|
10815
|
+
write(join23(plan.srcDir, "generated", "mcp-data.json"), `${JSON.stringify(data)}
|
|
10659
10816
|
`),
|
|
10660
|
-
write(
|
|
10661
|
-
write(
|
|
10662
|
-
write(
|
|
10817
|
+
write(join23(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate(plan.route)),
|
|
10818
|
+
write(join23(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
|
|
10819
|
+
write(join23(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
|
|
10663
10820
|
]);
|
|
10664
10821
|
};
|
|
10665
10822
|
var writeAskFiles = async (project, srcDir, write) => {
|
|
@@ -10669,16 +10826,16 @@ var writeAskFiles = async (project, srcDir, write) => {
|
|
|
10669
10826
|
}
|
|
10670
10827
|
const grounded = ask.provider !== "inkeep";
|
|
10671
10828
|
if (grounded) {
|
|
10672
|
-
await write(
|
|
10829
|
+
await write(join23(srcDir, "generated", "ask-data.json"), `${JSON.stringify(await buildAskData(project))}
|
|
10673
10830
|
`);
|
|
10674
10831
|
}
|
|
10675
|
-
await write(
|
|
10832
|
+
await write(join23(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(resolveAskBackend(ask), grounded));
|
|
10676
10833
|
};
|
|
10677
10834
|
var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
|
|
10678
10835
|
if (routeIsTaken(pages, contentPages, "/404")) {
|
|
10679
10836
|
return;
|
|
10680
10837
|
}
|
|
10681
|
-
await write(
|
|
10838
|
+
await write(join23(srcDir, "pages", "404.astro"), notFoundPageTemplate());
|
|
10682
10839
|
};
|
|
10683
10840
|
var buildComponentSlots = async (componentsFile) => {
|
|
10684
10841
|
const analysis = componentsFile ? analyzeComponentOverrides(await readFile11(componentsFile, "utf-8"), componentsFile) : null;
|
|
@@ -10691,14 +10848,14 @@ var buildComponentSlots = async (componentsFile) => {
|
|
|
10691
10848
|
var generateRuntime = async (project) => {
|
|
10692
10849
|
const { context, config } = project;
|
|
10693
10850
|
const out = context.outDir;
|
|
10694
|
-
const srcDir =
|
|
10695
|
-
const askPath =
|
|
10696
|
-
const dataPath =
|
|
10697
|
-
const themePath =
|
|
10698
|
-
const searchClientPath =
|
|
10699
|
-
const examplesPath =
|
|
10700
|
-
const examplesThemePath =
|
|
10701
|
-
const openapiPath =
|
|
10851
|
+
const srcDir = join23(out, "src");
|
|
10852
|
+
const askPath = join23(srcDir, "generated", "Ask.astro");
|
|
10853
|
+
const dataPath = join23(srcDir, "generated", "data.json");
|
|
10854
|
+
const themePath = join23(srcDir, "generated", "app.css");
|
|
10855
|
+
const searchClientPath = join23(srcDir, "generated", "search-client.ts");
|
|
10856
|
+
const examplesPath = join23(srcDir, "generated", "examples.ts");
|
|
10857
|
+
const examplesThemePath = join23(srcDir, "generated", "examples.css");
|
|
10858
|
+
const openapiPath = join23(srcDir, "generated", "openapi.json");
|
|
10702
10859
|
const written = new Set;
|
|
10703
10860
|
const write = (path, content) => {
|
|
10704
10861
|
written.add(normalize3(path));
|
|
@@ -10749,7 +10906,7 @@ var generateRuntime = async (project) => {
|
|
|
10749
10906
|
const hasFilesystemSource = project.sources.some((source) => !source.staged);
|
|
10750
10907
|
const [structural] = await Promise.all([
|
|
10751
10908
|
Promise.all([
|
|
10752
|
-
write(
|
|
10909
|
+
write(join23(out, "astro.config.mjs"), astroConfigTemplate({
|
|
10753
10910
|
aliases: resolveTsconfigAliases(context.root),
|
|
10754
10911
|
askPath,
|
|
10755
10912
|
config,
|
|
@@ -10767,26 +10924,26 @@ var generateRuntime = async (project) => {
|
|
|
10767
10924
|
searchClientPath,
|
|
10768
10925
|
themePath
|
|
10769
10926
|
})),
|
|
10770
|
-
write(
|
|
10771
|
-
write(
|
|
10772
|
-
write(
|
|
10773
|
-
write(
|
|
10927
|
+
write(join23(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
|
|
10928
|
+
write(join23(out, "tsconfig.json"), runtimeTsconfigTemplate()),
|
|
10929
|
+
write(join23(srcDir, "env.d.ts"), envTemplate()),
|
|
10930
|
+
write(join23(srcDir, "content.config.ts"), contentConfigTemplate({
|
|
10774
10931
|
collection: resolveDocsCollection(config, context),
|
|
10775
10932
|
config,
|
|
10776
10933
|
context,
|
|
10777
10934
|
filesystem: hasFilesystemSource,
|
|
10778
10935
|
staged: hasStaged
|
|
10779
10936
|
})),
|
|
10780
|
-
write(
|
|
10937
|
+
write(join23(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
|
|
10781
10938
|
exportEpub,
|
|
10782
10939
|
exportPdf,
|
|
10783
10940
|
mathEnabled: usesMath,
|
|
10784
10941
|
needsReact
|
|
10785
10942
|
})),
|
|
10786
10943
|
write(askPath, askComponentTemplate(askEnabled)),
|
|
10787
|
-
write(
|
|
10788
|
-
write(
|
|
10789
|
-
write(
|
|
10944
|
+
write(join23(srcDir, "generated", "components.ts"), slotPlan.module),
|
|
10945
|
+
write(join23(srcDir, "generated", "islands.ts"), islandMapTemplate(islandDiscovery.islands)),
|
|
10946
|
+
write(join23(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples, config.basePath)),
|
|
10790
10947
|
write(examplesThemePath, examplesEntryTemplate({
|
|
10791
10948
|
configTokens: buildThemeCss(config.theme),
|
|
10792
10949
|
sources: [`${context.root}/**/*.{astro,jsx,svelte,ts,tsx,vue}`],
|
|
@@ -10802,17 +10959,17 @@ var generateRuntime = async (project) => {
|
|
|
10802
10959
|
userTheme
|
|
10803
10960
|
}))
|
|
10804
10961
|
]),
|
|
10805
|
-
Promise.all(islandDiscovery.islands.map((island) => write(
|
|
10806
|
-
Promise.all(slotPlan.wrappers.map((wrapper) => write(
|
|
10807
|
-
Promise.all(exampleDiscovery.examples.map((example) => write(
|
|
10962
|
+
Promise.all(islandDiscovery.islands.map((island) => write(join23(srcDir, "generated", "islands", `${island.name}.astro`), islandWrapperTemplate(island)))),
|
|
10963
|
+
Promise.all(slotPlan.wrappers.map((wrapper) => write(join23(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content))),
|
|
10964
|
+
Promise.all(exampleDiscovery.examples.map((example) => write(join23(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example)))),
|
|
10808
10965
|
writeAskFiles(project, srcDir, write),
|
|
10809
10966
|
writeMcpFiles(project, mcp, write)
|
|
10810
10967
|
]);
|
|
10811
10968
|
if (config.seo.og.enabled) {
|
|
10812
|
-
await write(
|
|
10969
|
+
await write(join23(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes));
|
|
10813
10970
|
}
|
|
10814
10971
|
if (hasGeneratedChangelog(project, pages)) {
|
|
10815
|
-
await write(
|
|
10972
|
+
await write(join23(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
|
|
10816
10973
|
exportEpub,
|
|
10817
10974
|
exportPdf,
|
|
10818
10975
|
needsReact,
|
|
@@ -10832,27 +10989,27 @@ var generateRuntime = async (project) => {
|
|
|
10832
10989
|
]);
|
|
10833
10990
|
if (servesStaticIndex(config.search.provider)) {
|
|
10834
10991
|
const documents = await buildSearchDocuments(project);
|
|
10835
|
-
await write(
|
|
10992
|
+
await write(join23(srcDir, "generated", "search.json"), `${JSON.stringify(documents)}
|
|
10836
10993
|
`);
|
|
10837
|
-
await write(
|
|
10994
|
+
await write(join23(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
|
|
10838
10995
|
}
|
|
10839
10996
|
if (config.search.provider === "mixedbread") {
|
|
10840
|
-
await write(
|
|
10997
|
+
await write(join23(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""));
|
|
10841
10998
|
}
|
|
10842
10999
|
const rawMarkdown = await buildRawMarkdown(project);
|
|
10843
11000
|
await Promise.all([
|
|
10844
|
-
write(
|
|
11001
|
+
write(join23(srcDir, "generated", "raw-markdown.json"), `${JSON.stringify(rawMarkdown)}
|
|
10845
11002
|
`),
|
|
10846
|
-
write(
|
|
10847
|
-
write(
|
|
11003
|
+
write(join23(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate("md")),
|
|
11004
|
+
write(join23(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate("mdx"))
|
|
10848
11005
|
]);
|
|
10849
11006
|
const feeds = buildRssFeeds(project);
|
|
10850
11007
|
if (feeds.length > 0) {
|
|
10851
11008
|
const feedXml = Object.fromEntries(feeds.map((feed) => [feed.type, renderRssFeed(feed)]));
|
|
10852
11009
|
await Promise.all([
|
|
10853
|
-
write(
|
|
11010
|
+
write(join23(srcDir, "generated", "rss.json"), `${JSON.stringify(feedXml)}
|
|
10854
11011
|
`),
|
|
10855
|
-
write(
|
|
11012
|
+
write(join23(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate())
|
|
10856
11013
|
]);
|
|
10857
11014
|
}
|
|
10858
11015
|
const warnings = [
|
|
@@ -10867,7 +11024,7 @@ var generateRuntime = async (project) => {
|
|
|
10867
11024
|
const navTargetRoutes = new Set([
|
|
10868
11025
|
...project.graph.routes.keys(),
|
|
10869
11026
|
...pages.map((page) => page.pattern),
|
|
10870
|
-
...
|
|
11027
|
+
...referenceRoutes(config)
|
|
10871
11028
|
]);
|
|
10872
11029
|
if (hasGeneratedChangelog(project, pages)) {
|
|
10873
11030
|
navTargetRoutes.add("/changelog");
|
|
@@ -10891,14 +11048,14 @@ var generateRuntime = async (project) => {
|
|
|
10891
11048
|
root: context.root
|
|
10892
11049
|
});
|
|
10893
11050
|
warnings.push(...references.warnings);
|
|
10894
|
-
await Promise.all(references.files.map((file) => write(
|
|
11051
|
+
await Promise.all(references.files.map((file) => write(join23(srcDir, "pages", file.pagePath), file.content)));
|
|
10895
11052
|
}
|
|
10896
11053
|
const openApiSource2 = project.sources.find(isOpenApiSource);
|
|
10897
11054
|
await Promise.all([
|
|
10898
|
-
write(
|
|
11055
|
+
write(join23(srcDir, "generated", "data.json"), buildRuntimeData(project)),
|
|
10899
11056
|
write(openapiPath, `${JSON.stringify(openApiSource2 ? openApiSource2.openApiData() : {})}
|
|
10900
11057
|
`),
|
|
10901
|
-
write(
|
|
11058
|
+
write(join23(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
|
|
10902
11059
|
`),
|
|
10903
11060
|
writeStagedContent(out, staged)
|
|
10904
11061
|
]);
|
|
@@ -10910,7 +11067,7 @@ var generateRuntime = async (project) => {
|
|
|
10910
11067
|
import { relative as relative11 } from "pathe";
|
|
10911
11068
|
|
|
10912
11069
|
// src/core/config.ts
|
|
10913
|
-
import { existsSync as
|
|
11070
|
+
import { existsSync as existsSync14, readFileSync as readFileSync9 } from "node:fs";
|
|
10914
11071
|
|
|
10915
11072
|
// src/core/deployment-env.ts
|
|
10916
11073
|
var toUrl = (value) => {
|
|
@@ -10980,7 +11137,7 @@ var loadConfig = async (root, options = {}) => {
|
|
|
10980
11137
|
}
|
|
10981
11138
|
const parsed = blumeConfigSchema.safeParse(raw ?? {});
|
|
10982
11139
|
if (!parsed.success) {
|
|
10983
|
-
const source = configFile &&
|
|
11140
|
+
const source = configFile && existsSync14(configFile) ? readFileSync9(configFile, "utf-8") : undefined;
|
|
10984
11141
|
const diagnostics = diagnosticsFromZod(parsed.error, {
|
|
10985
11142
|
code: "BLUME_CONFIG_INVALID",
|
|
10986
11143
|
file: configFile ?? undefined,
|
|
@@ -11275,6 +11432,29 @@ var buildConfigSidebar = (items, byRoute, display, basePath) => {
|
|
|
11275
11432
|
}
|
|
11276
11433
|
return nodes;
|
|
11277
11434
|
};
|
|
11435
|
+
var resolveTabHref = (sidebar, path) => {
|
|
11436
|
+
let first;
|
|
11437
|
+
const walk = (nodes) => {
|
|
11438
|
+
for (const node of nodes) {
|
|
11439
|
+
const { route } = node;
|
|
11440
|
+
if (route === path) {
|
|
11441
|
+
return true;
|
|
11442
|
+
}
|
|
11443
|
+
if (first === undefined && route !== undefined && route.startsWith(`${path}/`)) {
|
|
11444
|
+
first = route;
|
|
11445
|
+
}
|
|
11446
|
+
if (node.kind === "group" && walk(node.children)) {
|
|
11447
|
+
return true;
|
|
11448
|
+
}
|
|
11449
|
+
}
|
|
11450
|
+
return false;
|
|
11451
|
+
};
|
|
11452
|
+
return walk(sidebar) ? path : first ?? path;
|
|
11453
|
+
};
|
|
11454
|
+
var withTabHrefs = (tabs2, sidebar) => tabs2.map((tab) => {
|
|
11455
|
+
const href = resolveTabHref(sidebar, tab.path);
|
|
11456
|
+
return href === tab.path ? tab : { ...tab, href };
|
|
11457
|
+
});
|
|
11278
11458
|
var buildNavigation = (pages, options) => {
|
|
11279
11459
|
const basePath = options.basePath ?? "";
|
|
11280
11460
|
const display = options.display ?? "flat";
|
|
@@ -11310,19 +11490,21 @@ var buildNavigation = (pages, options) => {
|
|
|
11310
11490
|
}
|
|
11311
11491
|
}
|
|
11312
11492
|
if (options.sidebar) {
|
|
11493
|
+
const sidebar2 = buildConfigSidebar(options.sidebar, byRoute, display, basePath);
|
|
11313
11494
|
return {
|
|
11314
11495
|
featured,
|
|
11315
11496
|
selectors,
|
|
11316
|
-
sidebar:
|
|
11317
|
-
tabs: tabs2
|
|
11497
|
+
sidebar: sidebar2,
|
|
11498
|
+
tabs: withTabHrefs(tabs2, sidebar2)
|
|
11318
11499
|
};
|
|
11319
11500
|
}
|
|
11320
11501
|
const rootTabPath = withBasePath(basePath, options.localizedRoot ?? "/");
|
|
11502
|
+
const sidebar = buildFileSystemSidebar(pages, options.folderMeta, sharedFolderMeta, metaPrefix, display, new Set(tabs2.flatMap((tab) => tab.path === rootTabPath ? [] : [tab.path])));
|
|
11321
11503
|
return {
|
|
11322
11504
|
featured,
|
|
11323
11505
|
selectors,
|
|
11324
|
-
sidebar
|
|
11325
|
-
tabs: tabs2
|
|
11506
|
+
sidebar,
|
|
11507
|
+
tabs: withTabHrefs(tabs2, sidebar)
|
|
11326
11508
|
};
|
|
11327
11509
|
};
|
|
11328
11510
|
|
|
@@ -11691,8 +11873,8 @@ var scanProject = async (root, options = {}) => {
|
|
|
11691
11873
|
};
|
|
11692
11874
|
|
|
11693
11875
|
// src/cli/env.ts
|
|
11694
|
-
import { existsSync as
|
|
11695
|
-
import { dirname as dirname10, join as
|
|
11876
|
+
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "node:fs";
|
|
11877
|
+
import { dirname as dirname10, join as join24, resolve as resolve7 } from "pathe";
|
|
11696
11878
|
var ENV_LINE = /^\s*(?:export\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?<value>.*?)\s*$/u;
|
|
11697
11879
|
var DOUBLE_QUOTED2 = /^"(?<body>[\s\S]*)"$/u;
|
|
11698
11880
|
var SINGLE_QUOTED = /^'(?<body>[\s\S]*)'$/u;
|
|
@@ -11738,8 +11920,8 @@ var applyEnv = (parsed) => {
|
|
|
11738
11920
|
};
|
|
11739
11921
|
var loadFile = (path) => {
|
|
11740
11922
|
try {
|
|
11741
|
-
if (
|
|
11742
|
-
applyEnv(parseEnv(
|
|
11923
|
+
if (existsSync15(path)) {
|
|
11924
|
+
applyEnv(parseEnv(readFileSync10(path, "utf-8")));
|
|
11743
11925
|
}
|
|
11744
11926
|
} catch {}
|
|
11745
11927
|
};
|
|
@@ -11747,10 +11929,10 @@ var loadEnvFiles = (startDir) => {
|
|
|
11747
11929
|
let dir = resolve7(startDir);
|
|
11748
11930
|
let done = false;
|
|
11749
11931
|
while (!done) {
|
|
11750
|
-
loadFile(
|
|
11751
|
-
loadFile(
|
|
11932
|
+
loadFile(join24(dir, ".env.local"));
|
|
11933
|
+
loadFile(join24(dir, ".env"));
|
|
11752
11934
|
const parent = dirname10(dir);
|
|
11753
|
-
done =
|
|
11935
|
+
done = existsSync15(join24(dir, ".git")) || parent === dir;
|
|
11754
11936
|
dir = parent;
|
|
11755
11937
|
}
|
|
11756
11938
|
};
|
|
@@ -11885,12 +12067,12 @@ var emitRedirectFiles = async (config, distDir) => {
|
|
|
11885
12067
|
if (redirects.length === 0 || config.deployment.output !== "static") {
|
|
11886
12068
|
return;
|
|
11887
12069
|
}
|
|
11888
|
-
await writeFile7(
|
|
12070
|
+
await writeFile7(join25(distDir, "blume-redirects.json"), buildRedirectManifest(redirects), "utf-8");
|
|
11889
12071
|
const platformFiles = [
|
|
11890
12072
|
{ content: buildNetlifyRedirects(redirects), name: "_redirects" },
|
|
11891
12073
|
{ content: buildVercelConfig(redirects), name: "vercel.json" }
|
|
11892
12074
|
];
|
|
11893
|
-
await Promise.all(platformFiles.map((file) =>
|
|
12075
|
+
await Promise.all(platformFiles.map((file) => existsSync16(join25(distDir, file.name)) ? Promise.resolve() : writeFile7(join25(distDir, file.name), file.content, "utf-8")));
|
|
11894
12076
|
logger.success(`Emitted redirect files for ${redirects.length} redirect(s)`);
|
|
11895
12077
|
};
|
|
11896
12078
|
var formatBytes = (bytes) => {
|
|
@@ -11901,14 +12083,14 @@ var formatBytes = (bytes) => {
|
|
|
11901
12083
|
return `${(bytes / 1024).toFixed(digits)} kB`;
|
|
11902
12084
|
};
|
|
11903
12085
|
var astroAssets = async (distDir, ext) => {
|
|
11904
|
-
const astroDir =
|
|
11905
|
-
if (!
|
|
12086
|
+
const astroDir = join25(distDir, "_astro");
|
|
12087
|
+
if (!existsSync16(astroDir)) {
|
|
11906
12088
|
return [];
|
|
11907
12089
|
}
|
|
11908
12090
|
const entries = await readdir(astroDir);
|
|
11909
12091
|
const files = entries.filter((name) => name.endsWith(`.${ext}`));
|
|
11910
12092
|
const sized = await Promise.all(files.map(async (name) => {
|
|
11911
|
-
const info = await stat(
|
|
12093
|
+
const info = await stat(join25(astroDir, name));
|
|
11912
12094
|
return { name, size: info.size };
|
|
11913
12095
|
}));
|
|
11914
12096
|
return sized.toSorted((a, b) => b.size - a.size);
|
|
@@ -11961,26 +12143,26 @@ var runClientAssetChecks = async (staticDir, args) => {
|
|
|
11961
12143
|
var isolatedOutputDir = (config, context) => {
|
|
11962
12144
|
const { adapter, output } = config.deployment;
|
|
11963
12145
|
if (output === "server" && adapter === "vercel") {
|
|
11964
|
-
return
|
|
12146
|
+
return join25(context.outDir, ".vercel", "output");
|
|
11965
12147
|
}
|
|
11966
|
-
return context.distDir ??
|
|
12148
|
+
return context.distDir ?? join25(context.outDir, "dist");
|
|
11967
12149
|
};
|
|
11968
12150
|
var isolatedStaticDir = (config, context) => {
|
|
11969
12151
|
const { adapter, output } = config.deployment;
|
|
11970
12152
|
const outputDir = isolatedOutputDir(config, context);
|
|
11971
12153
|
if (output === "server" && adapter === "vercel") {
|
|
11972
|
-
return
|
|
12154
|
+
return join25(outputDir, "static");
|
|
11973
12155
|
}
|
|
11974
12156
|
if (output === "server" && adapter === "node") {
|
|
11975
|
-
return
|
|
12157
|
+
return join25(outputDir, "client");
|
|
11976
12158
|
}
|
|
11977
12159
|
return outputDir;
|
|
11978
12160
|
};
|
|
11979
12161
|
var publishLlmsFiles = async (project, distDir) => {
|
|
11980
|
-
const indexPath =
|
|
11981
|
-
const fullPath =
|
|
11982
|
-
const writeIndex = !
|
|
11983
|
-
const writeFull = !
|
|
12162
|
+
const indexPath = join25(distDir, "llms.txt");
|
|
12163
|
+
const fullPath = join25(distDir, "llms-full.txt");
|
|
12164
|
+
const writeIndex = !existsSync16(indexPath);
|
|
12165
|
+
const writeFull = !existsSync16(fullPath);
|
|
11984
12166
|
if (!(writeIndex || writeFull)) {
|
|
11985
12167
|
return;
|
|
11986
12168
|
}
|
|
@@ -12013,18 +12195,18 @@ var publishBuildArtifacts = async (project, distDir, args) => {
|
|
|
12013
12195
|
await publishLlmsFiles(project, distDir);
|
|
12014
12196
|
}
|
|
12015
12197
|
const sitemap = buildSitemap(project);
|
|
12016
|
-
if (sitemap && !
|
|
12017
|
-
await writeFile7(
|
|
12198
|
+
if (sitemap && !existsSync16(join25(distDir, "sitemap.xml"))) {
|
|
12199
|
+
await writeFile7(join25(distDir, "sitemap.xml"), sitemap, "utf-8");
|
|
12018
12200
|
logger.success("Generated sitemap.xml");
|
|
12019
12201
|
}
|
|
12020
12202
|
const robots = buildRobots(project);
|
|
12021
|
-
if (robots && !
|
|
12022
|
-
await writeFile7(
|
|
12203
|
+
if (robots && !existsSync16(join25(distDir, "robots.txt"))) {
|
|
12204
|
+
await writeFile7(join25(distDir, "robots.txt"), robots, "utf-8");
|
|
12023
12205
|
logger.success("Generated robots.txt");
|
|
12024
12206
|
}
|
|
12025
12207
|
const agentReadability = buildAgentReadability(project);
|
|
12026
|
-
if (agentReadability && !
|
|
12027
|
-
await writeFile7(
|
|
12208
|
+
if (agentReadability && !existsSync16(join25(distDir, "agent-readability.json"))) {
|
|
12209
|
+
await writeFile7(join25(distDir, "agent-readability.json"), `${JSON.stringify(agentReadability, null, 2)}
|
|
12028
12210
|
`, "utf-8");
|
|
12029
12211
|
logger.success("Generated agent-readability.json");
|
|
12030
12212
|
}
|
|
@@ -12136,11 +12318,11 @@ var buildCommand = defineCommand2({
|
|
|
12136
12318
|
});
|
|
12137
12319
|
|
|
12138
12320
|
// src/cli/commands/check.ts
|
|
12139
|
-
import { existsSync as
|
|
12321
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
12140
12322
|
import { check } from "@astrojs/check";
|
|
12141
12323
|
import { sync } from "astro";
|
|
12142
12324
|
import { defineCommand as defineCommand3 } from "citty";
|
|
12143
|
-
import { join as
|
|
12325
|
+
import { join as join26 } from "pathe";
|
|
12144
12326
|
var checkCommand = defineCommand3({
|
|
12145
12327
|
args: {
|
|
12146
12328
|
isolated: {
|
|
@@ -12176,13 +12358,13 @@ var checkCommand = defineCommand3({
|
|
|
12176
12358
|
});
|
|
12177
12359
|
const { outDir } = project.context;
|
|
12178
12360
|
await sync({ logLevel: "warn", root: outDir });
|
|
12179
|
-
const tsconfig =
|
|
12361
|
+
const tsconfig = join26(root, "tsconfig.json");
|
|
12180
12362
|
logger.start(`Type-checking ${project.graph.pages.length} page(s)`);
|
|
12181
12363
|
const failed = await check({
|
|
12182
12364
|
minimumFailingSeverity: "error",
|
|
12183
12365
|
minimumSeverity: "hint",
|
|
12184
12366
|
root: outDir,
|
|
12185
|
-
tsconfig:
|
|
12367
|
+
tsconfig: existsSync17(tsconfig) ? tsconfig : undefined,
|
|
12186
12368
|
watch: false
|
|
12187
12369
|
});
|
|
12188
12370
|
if (failed) {
|
|
@@ -12402,14 +12584,14 @@ var devCommand = defineCommand4({
|
|
|
12402
12584
|
});
|
|
12403
12585
|
|
|
12404
12586
|
// src/cli/commands/doctor.ts
|
|
12405
|
-
import { readFileSync as
|
|
12587
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
12406
12588
|
import { defineCommand as defineCommand5 } from "citty";
|
|
12407
|
-
import { join as
|
|
12589
|
+
import { join as join27 } from "pathe";
|
|
12408
12590
|
var FALLBACK_MIN_NODE = "22.12.0";
|
|
12409
12591
|
var LEADING_RANGE = /^[^\d]*/u;
|
|
12410
12592
|
var minSupportedNode = () => {
|
|
12411
12593
|
try {
|
|
12412
|
-
const pkg = JSON.parse(
|
|
12594
|
+
const pkg = JSON.parse(readFileSync11(join27(packageRoot(), "package.json"), "utf-8"));
|
|
12413
12595
|
const range = pkg.engines?.node ?? "";
|
|
12414
12596
|
return range.replace(LEADING_RANGE, "") || FALLBACK_MIN_NODE;
|
|
12415
12597
|
} catch {
|
|
@@ -12505,17 +12687,17 @@ import { defineCommand as defineCommand6 } from "citty";
|
|
|
12505
12687
|
import { relative as relative14 } from "pathe";
|
|
12506
12688
|
|
|
12507
12689
|
// src/registry/eject.ts
|
|
12508
|
-
import { existsSync as
|
|
12690
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
12509
12691
|
import { cp as cp2, mkdir as mkdir7, readFile as readFile12, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
|
|
12510
|
-
import { join as
|
|
12692
|
+
import { join as join28, relative as relative12 } from "pathe";
|
|
12511
12693
|
var toPosix = (path) => path.split("\\").join("/");
|
|
12512
12694
|
var LOCAL_BLUME_SOURCE = "../../node_modules/blume/src/**/*.{astro,ts,tsx}";
|
|
12513
12695
|
var blumeSourceGlob = (root, genDir, resolveBlumeRoot = packageRoot) => {
|
|
12514
|
-
if (
|
|
12696
|
+
if (existsSync18(join28(root, "node_modules", "blume"))) {
|
|
12515
12697
|
return LOCAL_BLUME_SOURCE;
|
|
12516
12698
|
}
|
|
12517
12699
|
try {
|
|
12518
|
-
const src =
|
|
12700
|
+
const src = join28(resolveBlumeRoot(), "src");
|
|
12519
12701
|
return `${toPosix(relative12(genDir, src))}/**/*.{astro,ts,tsx}`;
|
|
12520
12702
|
} catch {
|
|
12521
12703
|
console.warn('blume: could not locate the installed blume package; src/generated/app.css keeps its default `@source "../../node_modules/blume/..."` glob. If blume is hoisted elsewhere, point that glob at its install location or Blume\'s utility classes will be missing.');
|
|
@@ -12535,14 +12717,14 @@ var askFiles = async (project, srcDir, genDir) => {
|
|
|
12535
12717
|
const files = [
|
|
12536
12718
|
{
|
|
12537
12719
|
content: askEndpointTemplate(resolveAskBackend(ask), grounded),
|
|
12538
|
-
path:
|
|
12720
|
+
path: join28(srcDir, "pages", "api", "ask.ts")
|
|
12539
12721
|
}
|
|
12540
12722
|
];
|
|
12541
12723
|
if (grounded) {
|
|
12542
12724
|
files.push({
|
|
12543
12725
|
content: `${JSON.stringify(await buildAskData(project))}
|
|
12544
12726
|
`,
|
|
12545
|
-
path:
|
|
12727
|
+
path: join28(genDir, "ask-data.json")
|
|
12546
12728
|
});
|
|
12547
12729
|
}
|
|
12548
12730
|
return files;
|
|
@@ -12575,19 +12757,19 @@ var mcpFiles = async (project, userPages, srcDir, genDir) => {
|
|
|
12575
12757
|
{
|
|
12576
12758
|
content: `${JSON.stringify(data)}
|
|
12577
12759
|
`,
|
|
12578
|
-
path:
|
|
12760
|
+
path: join28(genDir, "mcp-data.json")
|
|
12579
12761
|
},
|
|
12580
12762
|
{
|
|
12581
12763
|
content: mcpEndpointTemplate(route),
|
|
12582
|
-
path:
|
|
12764
|
+
path: join28(srcDir, "pages", mcpPageFile(route))
|
|
12583
12765
|
},
|
|
12584
12766
|
{
|
|
12585
12767
|
content: staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput)),
|
|
12586
|
-
path:
|
|
12768
|
+
path: join28(srcDir, "blume-mcp", "discovery.ts")
|
|
12587
12769
|
},
|
|
12588
12770
|
{
|
|
12589
12771
|
content: staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)),
|
|
12590
|
-
path:
|
|
12772
|
+
path: join28(srcDir, "blume-mcp", "server-card.ts")
|
|
12591
12773
|
}
|
|
12592
12774
|
];
|
|
12593
12775
|
};
|
|
@@ -12600,22 +12782,22 @@ var changelogFiles = (project, userPages, srcDir, options) => {
|
|
|
12600
12782
|
return [
|
|
12601
12783
|
{
|
|
12602
12784
|
content: changelogIndexTemplate(options),
|
|
12603
|
-
path:
|
|
12785
|
+
path: join28(srcDir, "pages", "changelog.astro")
|
|
12604
12786
|
}
|
|
12605
12787
|
];
|
|
12606
12788
|
};
|
|
12607
|
-
var readExamplesCss = (root, css) => css &&
|
|
12789
|
+
var readExamplesCss = (root, css) => css && existsSync18(join28(root, css)) ? readFile12(join28(root, css), "utf-8") : Promise.resolve("");
|
|
12608
12790
|
var examplesPreviewFiles = (srcDir, basePath, hasExamples) => hasExamples ? [
|
|
12609
12791
|
{
|
|
12610
12792
|
content: examplesPageTemplate(),
|
|
12611
|
-
path:
|
|
12793
|
+
path: join28(srcDir, "pages", ...basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro")
|
|
12612
12794
|
}
|
|
12613
12795
|
] : [];
|
|
12614
12796
|
var eject = async (root) => {
|
|
12615
12797
|
const project = await scanProject(root, { mode: "build" });
|
|
12616
12798
|
const { context, config } = project;
|
|
12617
|
-
const srcDir =
|
|
12618
|
-
const genDir =
|
|
12799
|
+
const srcDir = join28(root, "src");
|
|
12800
|
+
const genDir = join28(srcDir, "generated");
|
|
12619
12801
|
const askEnabled = config.ai.ask?.enabled ?? false;
|
|
12620
12802
|
const exportPdf = config.export.pdf;
|
|
12621
12803
|
const exportEpub = config.export.epub;
|
|
@@ -12680,14 +12862,14 @@ var eject = async (root) => {
|
|
|
12680
12862
|
searchClientPath: "./src/generated/search-client.ts",
|
|
12681
12863
|
themePath: "./src/generated/app.css"
|
|
12682
12864
|
}),
|
|
12683
|
-
path:
|
|
12865
|
+
path: join28(root, "astro.config.mjs")
|
|
12684
12866
|
},
|
|
12685
12867
|
{
|
|
12686
12868
|
content: runtimeTsconfigTemplate(),
|
|
12687
|
-
path:
|
|
12869
|
+
path: join28(root, "tsconfig.json"),
|
|
12688
12870
|
skipIfExists: true
|
|
12689
12871
|
},
|
|
12690
|
-
{ content: envTemplate(), path:
|
|
12872
|
+
{ content: envTemplate(), path: join28(srcDir, "env.d.ts") },
|
|
12691
12873
|
{
|
|
12692
12874
|
content: contentConfigTemplate({
|
|
12693
12875
|
config,
|
|
@@ -12695,7 +12877,7 @@ var eject = async (root) => {
|
|
|
12695
12877
|
staged: hasStaged,
|
|
12696
12878
|
stagedBase: stagedDir
|
|
12697
12879
|
}),
|
|
12698
|
-
path:
|
|
12880
|
+
path: join28(srcDir, "content.config.ts")
|
|
12699
12881
|
},
|
|
12700
12882
|
{
|
|
12701
12883
|
content: catchAllPageTemplate({
|
|
@@ -12704,19 +12886,19 @@ var eject = async (root) => {
|
|
|
12704
12886
|
mathEnabled: usesMath,
|
|
12705
12887
|
needsReact
|
|
12706
12888
|
}),
|
|
12707
|
-
path:
|
|
12889
|
+
path: join28(srcDir, "pages", "[...slug].astro")
|
|
12708
12890
|
},
|
|
12709
12891
|
{
|
|
12710
12892
|
content: planComponentSlots(componentsImport, null).module,
|
|
12711
|
-
path:
|
|
12893
|
+
path: join28(genDir, "components.ts")
|
|
12712
12894
|
},
|
|
12713
12895
|
{
|
|
12714
12896
|
content: islandMapTemplate(islands.islands),
|
|
12715
|
-
path:
|
|
12897
|
+
path: join28(genDir, "islands.ts")
|
|
12716
12898
|
},
|
|
12717
12899
|
{
|
|
12718
12900
|
content: exampleMapTemplate(examples.examples, config.basePath),
|
|
12719
|
-
path:
|
|
12901
|
+
path: join28(genDir, "examples.ts")
|
|
12720
12902
|
},
|
|
12721
12903
|
{
|
|
12722
12904
|
content: examplesEntryTemplate({
|
|
@@ -12724,7 +12906,7 @@ var eject = async (root) => {
|
|
|
12724
12906
|
sources: ["../../**/*.{astro,jsx,svelte,ts,tsx,vue}"],
|
|
12725
12907
|
userCss: userExamplesCss
|
|
12726
12908
|
}),
|
|
12727
|
-
path:
|
|
12909
|
+
path: join28(genDir, "examples.css")
|
|
12728
12910
|
},
|
|
12729
12911
|
{
|
|
12730
12912
|
content: tailwindEntryTemplate({
|
|
@@ -12736,30 +12918,30 @@ var eject = async (root) => {
|
|
|
12736
12918
|
twoslashCss: twoslashCss(),
|
|
12737
12919
|
userTheme
|
|
12738
12920
|
}),
|
|
12739
|
-
path:
|
|
12921
|
+
path: join28(genDir, "app.css")
|
|
12740
12922
|
},
|
|
12741
|
-
{ content: buildRuntimeData(project), path:
|
|
12923
|
+
{ content: buildRuntimeData(project), path: join28(genDir, "data.json") },
|
|
12742
12924
|
{
|
|
12743
12925
|
content: askComponentTemplate(askEnabled),
|
|
12744
|
-
path:
|
|
12926
|
+
path: join28(genDir, "Ask.astro")
|
|
12745
12927
|
},
|
|
12746
12928
|
{
|
|
12747
12929
|
content: `${JSON.stringify(ejectOpenApiData(project))}
|
|
12748
12930
|
`,
|
|
12749
|
-
path:
|
|
12931
|
+
path: join28(genDir, "openapi.json")
|
|
12750
12932
|
},
|
|
12751
12933
|
{
|
|
12752
12934
|
content: `${JSON.stringify(rawMarkdown)}
|
|
12753
12935
|
`,
|
|
12754
|
-
path:
|
|
12936
|
+
path: join28(genDir, "raw-markdown.json")
|
|
12755
12937
|
},
|
|
12756
12938
|
{
|
|
12757
12939
|
content: rawMarkdownEndpointTemplate("md"),
|
|
12758
|
-
path:
|
|
12940
|
+
path: join28(srcDir, "pages", "[...slug].md.ts")
|
|
12759
12941
|
},
|
|
12760
12942
|
{
|
|
12761
12943
|
content: rawMarkdownEndpointTemplate("mdx"),
|
|
12762
|
-
path:
|
|
12944
|
+
path: join28(srcDir, "pages", "[...slug].mdx.ts")
|
|
12763
12945
|
}
|
|
12764
12946
|
];
|
|
12765
12947
|
if (askEnabled) {
|
|
@@ -12768,7 +12950,7 @@ var eject = async (root) => {
|
|
|
12768
12950
|
if (config.seo.og.enabled) {
|
|
12769
12951
|
files.push({
|
|
12770
12952
|
content: ogEndpointTemplate(customOgRoutes(pages, config.title)),
|
|
12771
|
-
path:
|
|
12953
|
+
path: join28(srcDir, "pages", "og", "[...slug].png.ts")
|
|
12772
12954
|
});
|
|
12773
12955
|
}
|
|
12774
12956
|
files.push(...await mcpFiles(project, pages, srcDir, genDir), ...changelogFiles(project, pages, srcDir, {
|
|
@@ -12780,28 +12962,28 @@ var eject = async (root) => {
|
|
|
12780
12962
|
if (!routeIsTaken(pages, project.graph.pages, "/404")) {
|
|
12781
12963
|
files.push({
|
|
12782
12964
|
content: notFoundPageTemplate(),
|
|
12783
|
-
path:
|
|
12965
|
+
path: join28(srcDir, "pages", "404.astro")
|
|
12784
12966
|
});
|
|
12785
12967
|
}
|
|
12786
12968
|
files.push({
|
|
12787
12969
|
content: searchClientTemplate(config),
|
|
12788
|
-
path:
|
|
12970
|
+
path: join28(genDir, "search-client.ts")
|
|
12789
12971
|
});
|
|
12790
12972
|
if (servesStaticIndex(config.search.provider)) {
|
|
12791
12973
|
const documents = await buildSearchDocuments(project);
|
|
12792
12974
|
files.push({
|
|
12793
12975
|
content: `${JSON.stringify(documents)}
|
|
12794
12976
|
`,
|
|
12795
|
-
path:
|
|
12977
|
+
path: join28(genDir, "search.json")
|
|
12796
12978
|
}, {
|
|
12797
12979
|
content: searchEndpointTemplate(),
|
|
12798
|
-
path:
|
|
12980
|
+
path: join28(srcDir, "pages", "blume-search.json.ts")
|
|
12799
12981
|
});
|
|
12800
12982
|
}
|
|
12801
12983
|
if (config.search.provider === "mixedbread") {
|
|
12802
12984
|
files.push({
|
|
12803
12985
|
content: mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""),
|
|
12804
|
-
path:
|
|
12986
|
+
path: join28(srcDir, "pages", "api", "search.ts")
|
|
12805
12987
|
});
|
|
12806
12988
|
}
|
|
12807
12989
|
const feeds = buildRssFeeds(project);
|
|
@@ -12810,10 +12992,10 @@ var eject = async (root) => {
|
|
|
12810
12992
|
files.push({
|
|
12811
12993
|
content: `${JSON.stringify(feedXml)}
|
|
12812
12994
|
`,
|
|
12813
|
-
path:
|
|
12995
|
+
path: join28(genDir, "rss.json")
|
|
12814
12996
|
}, {
|
|
12815
12997
|
content: rssEndpointTemplate(),
|
|
12816
|
-
path:
|
|
12998
|
+
path: join28(srcDir, "pages", "[section]", "rss.xml.ts")
|
|
12817
12999
|
});
|
|
12818
13000
|
}
|
|
12819
13001
|
const warnings = [];
|
|
@@ -12827,28 +13009,28 @@ var eject = async (root) => {
|
|
|
12827
13009
|
for (const file of references.files) {
|
|
12828
13010
|
files.push({
|
|
12829
13011
|
content: file.content,
|
|
12830
|
-
path:
|
|
13012
|
+
path: join28(srcDir, "pages", file.pagePath)
|
|
12831
13013
|
});
|
|
12832
13014
|
}
|
|
12833
13015
|
}
|
|
12834
13016
|
files.push(...islands.islands.map((island) => ({
|
|
12835
13017
|
content: islandWrapperTemplate(island),
|
|
12836
|
-
path:
|
|
13018
|
+
path: join28(genDir, "islands", `${island.name}.astro`)
|
|
12837
13019
|
})), ...examples.examples.map((example) => ({
|
|
12838
13020
|
content: exampleWrapperTemplate(example),
|
|
12839
|
-
path:
|
|
13021
|
+
path: join28(genDir, "examples", `${exampleSlug(example.path)}.astro`)
|
|
12840
13022
|
})), ...examplesPreviewFiles(srcDir, config.basePath, examples.examples.length > 0));
|
|
12841
13023
|
for (const [entryId, content] of staged) {
|
|
12842
|
-
files.push({ content, path:
|
|
13024
|
+
files.push({ content, path: join28(root, stagedDir, entryId) });
|
|
12843
13025
|
}
|
|
12844
|
-
const written = files.filter((file) => !(file.skipIfExists &&
|
|
13026
|
+
const written = files.filter((file) => !(file.skipIfExists && existsSync18(file.path)));
|
|
12845
13027
|
await Promise.all(written.map(async (file) => {
|
|
12846
|
-
await mkdir7(
|
|
13028
|
+
await mkdir7(join28(file.path, ".."), { recursive: true });
|
|
12847
13029
|
await writeFile8(file.path, file.content, "utf-8");
|
|
12848
13030
|
}));
|
|
12849
|
-
const assetsSrc =
|
|
12850
|
-
if (
|
|
12851
|
-
await cp2(assetsSrc,
|
|
13031
|
+
const assetsSrc = join28(context.outDir, "public", "blume-assets");
|
|
13032
|
+
if (existsSync18(assetsSrc)) {
|
|
13033
|
+
await cp2(assetsSrc, join28(root, "public", "blume-assets"), {
|
|
12852
13034
|
recursive: true
|
|
12853
13035
|
});
|
|
12854
13036
|
}
|
|
@@ -12858,7 +13040,7 @@ var eject = async (root) => {
|
|
|
12858
13040
|
|
|
12859
13041
|
// src/cli/eject-scripts.ts
|
|
12860
13042
|
import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
|
|
12861
|
-
import { join as
|
|
13043
|
+
import { join as join29 } from "pathe";
|
|
12862
13044
|
var droppedArtifactNotices = (config) => {
|
|
12863
13045
|
const notices = [];
|
|
12864
13046
|
if (config.search.provider === "pagefind") {
|
|
@@ -12885,7 +13067,7 @@ var droppedArtifactNotices = (config) => {
|
|
|
12885
13067
|
return notices;
|
|
12886
13068
|
};
|
|
12887
13069
|
var updatePackageScripts = async (root) => {
|
|
12888
|
-
const pkgPath =
|
|
13070
|
+
const pkgPath = join29(root, "package.json");
|
|
12889
13071
|
let pkg;
|
|
12890
13072
|
try {
|
|
12891
13073
|
pkg = JSON.parse(await readFile13(pkgPath, "utf-8"));
|
|
@@ -12904,9 +13086,9 @@ var updatePackageScripts = async (root) => {
|
|
|
12904
13086
|
};
|
|
12905
13087
|
|
|
12906
13088
|
// src/cli/init/scaffold.ts
|
|
12907
|
-
import { existsSync as
|
|
13089
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
12908
13090
|
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
12909
|
-
import { basename as basename4, dirname as dirname11, isAbsolute as isAbsolute9, join as
|
|
13091
|
+
import { basename as basename4, dirname as dirname11, isAbsolute as isAbsolute9, join as join30, relative as relative13 } from "pathe";
|
|
12910
13092
|
|
|
12911
13093
|
// src/core/package-json.ts
|
|
12912
13094
|
var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
|
|
@@ -12965,7 +13147,7 @@ var STARTERS = {
|
|
|
12965
13147
|
files: (dir) => [
|
|
12966
13148
|
{
|
|
12967
13149
|
content: page("API Reference", "Explore the API.", "# API Reference\n\nYour OpenAPI spec renders at [`/api`](/api). Point `openapi.sources` at your own spec in `blume.config.ts`."),
|
|
12968
|
-
path:
|
|
13150
|
+
path: join30(dir, "index.mdx")
|
|
12969
13151
|
}
|
|
12970
13152
|
]
|
|
12971
13153
|
},
|
|
@@ -12980,7 +13162,7 @@ var STARTERS = {
|
|
|
12980
13162
|
files: (dir) => [
|
|
12981
13163
|
{
|
|
12982
13164
|
content: page("Introduction", "Welcome to your new Blume docs.", "# Introduction\n\nWrite your docs here, and log releases under `changelog/`."),
|
|
12983
|
-
path:
|
|
13165
|
+
path: join30(dir, "index.mdx")
|
|
12984
13166
|
},
|
|
12985
13167
|
{
|
|
12986
13168
|
content: `---
|
|
@@ -12991,7 +13173,7 @@ date: 2026-01-01
|
|
|
12991
13173
|
|
|
12992
13174
|
The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries beside it.
|
|
12993
13175
|
`,
|
|
12994
|
-
path:
|
|
13176
|
+
path: join30(dir, "changelog", "v1-0-0.mdx")
|
|
12995
13177
|
}
|
|
12996
13178
|
]
|
|
12997
13179
|
},
|
|
@@ -13004,7 +13186,7 @@ The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries besid
|
|
|
13004
13186
|
Welcome to **Blume** — markdown-first docs powered by Astro and Vite.
|
|
13005
13187
|
|
|
13006
13188
|
Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
|
|
13007
|
-
path:
|
|
13189
|
+
path: join30(dir, "index.mdx")
|
|
13008
13190
|
}
|
|
13009
13191
|
]
|
|
13010
13192
|
},
|
|
@@ -13015,11 +13197,11 @@ Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
|
|
|
13015
13197
|
content: page("Introduction", "Get started with the SDK.", `# Introduction
|
|
13016
13198
|
|
|
13017
13199
|
Install the SDK and make your first call. See [Installation](/installation).`),
|
|
13018
|
-
path:
|
|
13200
|
+
path: join30(dir, "index.mdx")
|
|
13019
13201
|
},
|
|
13020
13202
|
{
|
|
13021
13203
|
content: page("Installation", "Install the SDK.", "# Installation\n\n```package-install\nyour-sdk\n```"),
|
|
13022
|
-
path:
|
|
13204
|
+
path: join30(dir, "installation.mdx")
|
|
13023
13205
|
}
|
|
13024
13206
|
]
|
|
13025
13207
|
}
|
|
@@ -13034,7 +13216,7 @@ var detectPackageManager = (userAgent) => {
|
|
|
13034
13216
|
const name = userAgent?.split("/")[0];
|
|
13035
13217
|
return name !== undefined && PACKAGE_MANAGERS.includes(name) ? name : "npm";
|
|
13036
13218
|
};
|
|
13037
|
-
var validateContentDir = (root, dir) => isAbsolute9(dir) || relative13(root,
|
|
13219
|
+
var validateContentDir = (root, dir) => isAbsolute9(dir) || relative13(root, join30(root, dir)).startsWith("..") ? "Must be a relative path inside the project." : undefined;
|
|
13038
13220
|
var titleize = (raw) => {
|
|
13039
13221
|
const words = raw.replaceAll(/[-_.]+/gu, " ").split(/\s+/u).filter(Boolean);
|
|
13040
13222
|
return words.length === 0 ? "My Docs" : words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
@@ -13117,17 +13299,17 @@ var buildPlan = (root, answers) => {
|
|
|
13117
13299
|
const files = [
|
|
13118
13300
|
{
|
|
13119
13301
|
content: blumePackageJson(toPackageName(basename4(root)), extraDepsFor(answers.sources)),
|
|
13120
|
-
path:
|
|
13302
|
+
path: join30(root, "package.json")
|
|
13121
13303
|
},
|
|
13122
|
-
{ content: buildConfig(answers), path:
|
|
13304
|
+
{ content: buildConfig(answers), path: join30(root, "blume.config.ts") }
|
|
13123
13305
|
];
|
|
13124
13306
|
if (answers.sources.length === 0 || answers.sources.includes("filesystem")) {
|
|
13125
|
-
files.push(...STARTERS[answers.template].files(answers.contentDir).map((file) => ({ ...file, path:
|
|
13307
|
+
files.push(...STARTERS[answers.template].files(answers.contentDir).map((file) => ({ ...file, path: join30(root, file.path) })));
|
|
13126
13308
|
}
|
|
13127
13309
|
return files;
|
|
13128
13310
|
};
|
|
13129
13311
|
var writeFileSafe = async (file, log) => {
|
|
13130
|
-
if (
|
|
13312
|
+
if (existsSync19(file.path)) {
|
|
13131
13313
|
log.info(`Skipped existing ${file.path}`);
|
|
13132
13314
|
return false;
|
|
13133
13315
|
}
|
|
@@ -13434,10 +13616,10 @@ var initCommand = defineCommand7({
|
|
|
13434
13616
|
});
|
|
13435
13617
|
|
|
13436
13618
|
// src/cli/commands/preview.ts
|
|
13437
|
-
import { existsSync as
|
|
13619
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
13438
13620
|
import { preview } from "astro";
|
|
13439
13621
|
import { defineCommand as defineCommand8 } from "citty";
|
|
13440
|
-
import { join as
|
|
13622
|
+
import { join as join31 } from "pathe";
|
|
13441
13623
|
var previewCommand = defineCommand8({
|
|
13442
13624
|
args: {
|
|
13443
13625
|
host: { description: "Network host to bind.", type: "string" },
|
|
@@ -13451,7 +13633,7 @@ var previewCommand = defineCommand8({
|
|
|
13451
13633
|
const root = process.cwd();
|
|
13452
13634
|
const { config } = await loadConfig(root);
|
|
13453
13635
|
const context = resolveProjectContext(root, config);
|
|
13454
|
-
if (!
|
|
13636
|
+
if (!existsSync20(join31(context.outDir, "astro.config.mjs"))) {
|
|
13455
13637
|
logger.error("No build found. Run `blume build` first.");
|
|
13456
13638
|
process.exit(1);
|
|
13457
13639
|
}
|
|
@@ -13469,7 +13651,7 @@ var previewCommand = defineCommand8({
|
|
|
13469
13651
|
// src/cli/commands/sync.ts
|
|
13470
13652
|
import { rm as rm4 } from "node:fs/promises";
|
|
13471
13653
|
import { defineCommand as defineCommand9 } from "citty";
|
|
13472
|
-
import { join as
|
|
13654
|
+
import { join as join32 } from "pathe";
|
|
13473
13655
|
var syncCommand = defineCommand9({
|
|
13474
13656
|
args: {
|
|
13475
13657
|
force: {
|
|
@@ -13491,7 +13673,7 @@ var syncCommand = defineCommand9({
|
|
|
13491
13673
|
if (args.force) {
|
|
13492
13674
|
const { config } = await loadConfig(root);
|
|
13493
13675
|
const context = resolveProjectContext(root, config);
|
|
13494
|
-
await rm4(
|
|
13676
|
+
await rm4(join32(context.outDir, "cache"), { force: true, recursive: true });
|
|
13495
13677
|
logger.info("Cleared source cache.");
|
|
13496
13678
|
}
|
|
13497
13679
|
const lock = readDevLock(resolveRuntimeDir(root));
|
|
@@ -13509,13 +13691,13 @@ var syncCommand = defineCommand9({
|
|
|
13509
13691
|
});
|
|
13510
13692
|
|
|
13511
13693
|
// src/cli/commands/validate.ts
|
|
13512
|
-
import { existsSync as
|
|
13694
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
13513
13695
|
import { defineCommand as defineCommand10 } from "citty";
|
|
13514
|
-
import { join as
|
|
13696
|
+
import { join as join34 } from "pathe";
|
|
13515
13697
|
|
|
13516
13698
|
// src/core/links.ts
|
|
13517
|
-
import { existsSync as
|
|
13518
|
-
import { basename as basename6, join as
|
|
13699
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
13700
|
+
import { basename as basename6, join as join33 } from "pathe";
|
|
13519
13701
|
var HTTP = /^https?:\/\//iu;
|
|
13520
13702
|
var PROTOCOL_RELATIVE = /^\/\//u;
|
|
13521
13703
|
var SCHEME = /^[a-z][a-z0-9+.-]*:/iu;
|
|
@@ -13534,7 +13716,7 @@ var STATUS_NOT_FOUND = 404;
|
|
|
13534
13716
|
var STATUS_GONE = 410;
|
|
13535
13717
|
var STATUS_METHOD_NOT_ALLOWED = 405;
|
|
13536
13718
|
var STATUS_NOT_IMPLEMENTED = 501;
|
|
13537
|
-
var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null &&
|
|
13719
|
+
var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null && existsSync21(join33(ctx.publicDir, resolved));
|
|
13538
13720
|
var NUMERIC_PREFIX3 = /^\d+[-_.]/u;
|
|
13539
13721
|
var isIndexPage = (page2) => /^index\.(?:md|mdx)$/iu.test(basename6(page2.navPath).replace(NUMERIC_PREFIX3, ""));
|
|
13540
13722
|
var applyRelativePart = (segments, part) => {
|
|
@@ -13800,12 +13982,12 @@ var validateCommand = defineCommand10({
|
|
|
13800
13982
|
});
|
|
13801
13983
|
extraRoutes.push(...manifest.routes.flatMap((route) => route.fallback ? [route.path] : []));
|
|
13802
13984
|
}
|
|
13803
|
-
const publicDir =
|
|
13985
|
+
const publicDir = join34(root, "public");
|
|
13804
13986
|
diagnostics.push(...await validateLinks(project.graph, {
|
|
13805
13987
|
basePath: project.config.basePath,
|
|
13806
13988
|
checkExternal: Boolean(args.external),
|
|
13807
13989
|
extraRoutes,
|
|
13808
|
-
publicDir:
|
|
13990
|
+
publicDir: existsSync22(publicDir) ? publicDir : null,
|
|
13809
13991
|
redirects: project.config.redirects
|
|
13810
13992
|
}));
|
|
13811
13993
|
} catch (error) {
|
|
@@ -13866,5 +14048,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
13866
14048
|
});
|
|
13867
14049
|
runMain(main);
|
|
13868
14050
|
|
|
13869
|
-
//# debugId=
|
|
14051
|
+
//# debugId=E383A1CFB1E8864864756E2164756E21
|
|
13870
14052
|
//# sourceMappingURL=index.js.map
|