blume 1.0.2 → 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 +37 -0
- package/dist/cli/index.js +496 -295
- package/dist/cli/index.js.map +18 -17
- package/dist/types/core/config-input.d.ts +44 -22
- package/dist/types/core/config.d.ts +3 -3
- 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 +502 -384
- 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/advanced/custom-pages.mdx +2 -0
- package/docs/configuration/ai.mdx +6 -4
- package/docs/configuration/index.mdx +6 -8
- package/docs/configuration/seo.mdx +20 -1
- package/docs/content/components.mdx +26 -5
- 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/ai/agent-readability.ts +3 -3
- package/src/ai/mcp/data.ts +2 -2
- package/src/astro/component-slots.ts +3 -2
- package/src/astro/generate.ts +97 -30
- package/src/astro/templates.ts +140 -53
- package/src/blume-modules.d.ts +6 -0
- package/src/components/content/Callout.astro +8 -2
- package/src/components/content/Prompt.astro +25 -13
- package/src/components/layout/Header.astro +19 -10
- package/src/components/layout/Logo.astro +13 -1
- package/src/components/layout/PageFeedback.astro +1 -1
- package/src/components/layout/PageLayout.astro +11 -11
- package/src/components/layout/Pagination.astro +6 -6
- package/src/components/layout/ReferenceLayout.astro +1 -0
- package/src/components/layout/RootLayout.astro +10 -11
- package/src/components/layout/Search.astro +1 -1
- package/src/components/layout/nav-utils.ts +9 -7
- package/src/core/config-input.ts +47 -27
- package/src/core/config.ts +3 -3
- package/src/core/data.ts +9 -1
- package/src/core/navigation.ts +55 -13
- package/src/core/schema.ts +32 -15
- package/src/core/server-features.ts +1 -1
- package/src/core/sources/watch.ts +5 -0
- package/src/core/types.ts +10 -0
- package/src/deploy/adapter-output.ts +11 -1
- 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/registry/eject.ts +11 -5
- 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) => {
|
|
@@ -676,10 +676,10 @@ var buildAgentReadability = (project) => {
|
|
|
676
676
|
artifacts.llmsFullTxt = abs("/llms-full.txt");
|
|
677
677
|
artifacts.llmsTxt = abs("/llms.txt");
|
|
678
678
|
}
|
|
679
|
-
if (config.mcp.enabled) {
|
|
679
|
+
if (config.ai.mcp.enabled) {
|
|
680
680
|
artifacts.mcp = {
|
|
681
681
|
discovery: abs("/.well-known/mcp.json"),
|
|
682
|
-
url: abs(config.mcp.route)
|
|
682
|
+
url: abs(config.ai.mcp.route)
|
|
683
683
|
};
|
|
684
684
|
}
|
|
685
685
|
if (config.ai.ask?.enabled) {
|
|
@@ -697,7 +697,7 @@ var buildAgentReadability = (project) => {
|
|
|
697
697
|
artifacts,
|
|
698
698
|
description: config.description,
|
|
699
699
|
generator: version ? `blume@${version}` : undefined,
|
|
700
|
-
name: config.mcp.name ?? config.title,
|
|
700
|
+
name: config.ai.mcp.name ?? config.title,
|
|
701
701
|
site
|
|
702
702
|
};
|
|
703
703
|
const usage = usagePolicy(config.seo.contentSignals);
|
|
@@ -1225,7 +1225,7 @@ var serverFeatures = (config) => {
|
|
|
1225
1225
|
if (config.ai.ask?.enabled) {
|
|
1226
1226
|
features.push("Ask AI");
|
|
1227
1227
|
}
|
|
1228
|
-
if (config.mcp.enabled) {
|
|
1228
|
+
if (config.ai.mcp.enabled) {
|
|
1229
1229
|
features.push("MCP server");
|
|
1230
1230
|
}
|
|
1231
1231
|
if (searchProviderMeta(config.search.provider).requiresServer) {
|
|
@@ -1269,7 +1269,7 @@ var surfaceAdapterOutput = async (config, context) => {
|
|
|
1269
1269
|
}
|
|
1270
1270
|
await mkdir2(dirname4(to), { recursive: true });
|
|
1271
1271
|
await rm(to, { force: true, recursive: true });
|
|
1272
|
-
await cp(from, to, { recursive: true });
|
|
1272
|
+
await cp(from, to, { recursive: true, verbatimSymlinks: true });
|
|
1273
1273
|
await rm(from, { force: true, recursive: true });
|
|
1274
1274
|
return { from, ignore: `${rel.split("/")[0]}/`, moved: true, to };
|
|
1275
1275
|
};
|
|
@@ -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
|
|
@@ -4117,8 +4117,8 @@ var buildMcpData = async (project) => {
|
|
|
4117
4117
|
route: doc.route,
|
|
4118
4118
|
title: doc.title
|
|
4119
4119
|
})),
|
|
4120
|
-
instructions: config.mcp.instructions,
|
|
4121
|
-
name: config.mcp.name ?? config.title,
|
|
4120
|
+
instructions: config.ai.mcp.instructions,
|
|
4121
|
+
name: config.ai.mcp.name ?? config.title,
|
|
4122
4122
|
navigation: graph.navigation,
|
|
4123
4123
|
pages,
|
|
4124
4124
|
routes,
|
|
@@ -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",
|
|
@@ -6377,6 +6375,12 @@ var askAiProviders = [
|
|
|
6377
6375
|
"inkeep",
|
|
6378
6376
|
"openai-compatible"
|
|
6379
6377
|
];
|
|
6378
|
+
var mcpConfigSchema = z2.strictObject({
|
|
6379
|
+
enabled: z2.boolean().default(false),
|
|
6380
|
+
instructions: z2.string().optional(),
|
|
6381
|
+
name: z2.string().optional(),
|
|
6382
|
+
route: z2.string().default("/mcp").transform(normalizeRoute)
|
|
6383
|
+
});
|
|
6380
6384
|
var aiConfigSchema = z2.strictObject({
|
|
6381
6385
|
ask: z2.strictObject({
|
|
6382
6386
|
apiKeyEnv: z2.string().optional(),
|
|
@@ -6406,7 +6410,8 @@ var aiConfigSchema = z2.strictObject({
|
|
|
6406
6410
|
]).default(true).transform((value) => typeof value === "boolean" ? { enabled: value, openapi: true } : value),
|
|
6407
6411
|
markdownComponents: z2.record(z2.string(), z2.custom((value) => typeof value === "function", {
|
|
6408
6412
|
message: "Expected a serializer function."
|
|
6409
|
-
})).default({})
|
|
6413
|
+
})).default({}),
|
|
6414
|
+
mcp: mcpConfigSchema.default({})
|
|
6410
6415
|
});
|
|
6411
6416
|
var featuredLinkSchema = z2.strictObject({
|
|
6412
6417
|
href: z2.string(),
|
|
@@ -6424,7 +6429,7 @@ var navigationConfigSchema = z2.strictObject({
|
|
|
6424
6429
|
items: z2.array(sidebarItemSchema).optional()
|
|
6425
6430
|
})
|
|
6426
6431
|
]).default({}).transform((value) => Array.isArray(value) ? { display: "flat", items: value } : value),
|
|
6427
|
-
tabs: z2.array(navTabSchema).
|
|
6432
|
+
tabs: z2.array(navTabSchema).default([])
|
|
6428
6433
|
});
|
|
6429
6434
|
var exportConfigSchema = z2.union([
|
|
6430
6435
|
z2.boolean(),
|
|
@@ -6433,12 +6438,6 @@ var exportConfigSchema = z2.union([
|
|
|
6433
6438
|
pdf: z2.boolean().default(false)
|
|
6434
6439
|
})
|
|
6435
6440
|
]).transform((value) => typeof value === "boolean" ? { epub: value, pdf: value } : value);
|
|
6436
|
-
var mcpConfigSchema = z2.strictObject({
|
|
6437
|
-
enabled: z2.boolean().default(false),
|
|
6438
|
-
instructions: z2.string().optional(),
|
|
6439
|
-
name: z2.string().optional(),
|
|
6440
|
-
route: z2.string().default("/mcp").transform(normalizeRoute)
|
|
6441
|
-
});
|
|
6442
6441
|
var localeSchema = z2.strictObject({
|
|
6443
6442
|
code: z2.string().min(1),
|
|
6444
6443
|
dir: z2.enum(["ltr", "rtl"]).default("ltr"),
|
|
@@ -6499,8 +6498,18 @@ var xConfigSchema = z2.strictObject({
|
|
|
6499
6498
|
creator: xHandleSchema,
|
|
6500
6499
|
handle: xHandleSchema
|
|
6501
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
|
+
});
|
|
6502
6509
|
var ogConfigSchema = z2.strictObject({
|
|
6503
|
-
enabled: z2.boolean().optional()
|
|
6510
|
+
enabled: z2.boolean().optional(),
|
|
6511
|
+
logo: z2.string().optional(),
|
|
6512
|
+
palette: ogPaletteSchema.optional()
|
|
6504
6513
|
});
|
|
6505
6514
|
var rssConfigSchema = z2.strictObject({
|
|
6506
6515
|
enabled: z2.boolean().default(true),
|
|
@@ -6625,7 +6634,6 @@ var blumeConfigSchema = z2.strictObject({
|
|
|
6625
6634
|
lastModified: lastModifiedConfigSchema.default(false),
|
|
6626
6635
|
logo: logoConfigSchema.optional(),
|
|
6627
6636
|
markdown: markdownConfigSchema.default({}),
|
|
6628
|
-
mcp: mcpConfigSchema.default({}),
|
|
6629
6637
|
navigation: navigationConfigSchema.default({}),
|
|
6630
6638
|
openapi: openapiConfigSchema.default({}),
|
|
6631
6639
|
react: reactConfigSchema.default({}),
|
|
@@ -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"];
|
|
@@ -7748,6 +7788,7 @@ var reactIntegration = (compilerPath) => compilerPath ? `react({ babel: { plugin
|
|
|
7748
7788
|
var astroConfigTemplate = (options) => {
|
|
7749
7789
|
const { context, config, needsReact, pages, dataPath, themePath } = options;
|
|
7750
7790
|
const {
|
|
7791
|
+
askPath,
|
|
7751
7792
|
contentRoutes,
|
|
7752
7793
|
examplesPath,
|
|
7753
7794
|
examplesThemePath,
|
|
@@ -7762,7 +7803,15 @@ var astroConfigTemplate = (options) => {
|
|
|
7762
7803
|
const fsAllow = [...new Set([findWorkspaceRoot(context.root), context.root])];
|
|
7763
7804
|
const adapterImport = server && deployment.adapter ? `import adapter from "${ADAPTER_IMPORTS[deployment.adapter]}";
|
|
7764
7805
|
` : "";
|
|
7765
|
-
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
|
+
})();
|
|
7766
7815
|
const adapterOption = server && deployment.adapter ? `
|
|
7767
7816
|
adapter: adapter(${adapterArgs}),` : "";
|
|
7768
7817
|
const siteOption = deployment.site ? `
|
|
@@ -7849,6 +7898,18 @@ export default defineConfig({
|
|
|
7849
7898
|
devToolbar: { enabled: false },
|
|
7850
7899
|
vite: {
|
|
7851
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"] },
|
|
7852
7913
|
// Blume's render-time deps are forced external on both build environments so
|
|
7853
7914
|
// native bindings resolve at runtime and isolated linkers don't bundle
|
|
7854
7915
|
// symlinked store copies (which would surface their children as unresolvable
|
|
@@ -7867,6 +7928,7 @@ export default defineConfig({
|
|
|
7867
7928
|
},
|
|
7868
7929
|
resolve: {
|
|
7869
7930
|
alias: {
|
|
7931
|
+
"blume:ask": ${JSON.stringify(askPath)},
|
|
7870
7932
|
"blume:data": ${JSON.stringify(dataPath)},
|
|
7871
7933
|
"blume:examples": ${JSON.stringify(examplesPath)},
|
|
7872
7934
|
"blume:examples-theme": ${JSON.stringify(examplesThemePath)},
|
|
@@ -7886,14 +7948,14 @@ export default defineConfig({
|
|
|
7886
7948
|
// self-hosted fonts) -- pure noise the loader logs as "No entry type
|
|
7887
7949
|
// found". Vite appends this to its default ignores.
|
|
7888
7950
|
watch: {
|
|
7889
|
-
ignored: ${JSON.stringify([
|
|
7951
|
+
ignored: ${JSON.stringify([join19(context.outDir, ".astro", "**")])},
|
|
7890
7952
|
},
|
|
7891
7953
|
},
|
|
7892
7954
|
},
|
|
7893
7955
|
});
|
|
7894
7956
|
`;
|
|
7895
7957
|
};
|
|
7896
|
-
var stagedContentDir = (outDir) =>
|
|
7958
|
+
var stagedContentDir = (outDir) => join19(outDir, "content");
|
|
7897
7959
|
var astroGlobBase = (base) => isAbsolute7(base) ? pathToFileURL2(base).href : base;
|
|
7898
7960
|
var contentConfigTemplate = (options) => {
|
|
7899
7961
|
const { context, config } = options;
|
|
@@ -8038,6 +8100,22 @@ ${setup}
|
|
|
8038
8100
|
${handler}
|
|
8039
8101
|
`;
|
|
8040
8102
|
};
|
|
8103
|
+
var askComponentTemplate = (askEnabled) => askEnabled ? `---
|
|
8104
|
+
// Generated by Blume. Do not edit.
|
|
8105
|
+
import AskAI from "blume/components/islands/AskAI.astro";
|
|
8106
|
+
import data from "blume:data";
|
|
8107
|
+
|
|
8108
|
+
const { strings } = Astro.props;
|
|
8109
|
+
---
|
|
8110
|
+
|
|
8111
|
+
<AskAI strings={strings ?? data.ui.ask} suggestions={data.config.ask?.suggestions ?? []} />
|
|
8112
|
+
` : `---
|
|
8113
|
+
// Generated by Blume. Do not edit.
|
|
8114
|
+
// Ask AI is off (\`ai.ask.enabled\`), so the header's Ask trigger renders nothing.
|
|
8115
|
+
// Deliberately imports no React island, keeping the JSX renderer out of projects
|
|
8116
|
+
// that don't need it.
|
|
8117
|
+
---
|
|
8118
|
+
`;
|
|
8041
8119
|
var searchEndpointTemplate = () => `// Generated by Blume. Do not edit.
|
|
8042
8120
|
import documents from "../generated/search.json";
|
|
8043
8121
|
|
|
@@ -8160,9 +8238,10 @@ export function getStaticPaths() {
|
|
|
8160
8238
|
}));
|
|
8161
8239
|
}
|
|
8162
8240
|
|
|
8163
|
-
export function GET({ props }) {
|
|
8164
|
-
const
|
|
8165
|
-
|
|
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 ?? "")'} : "", {
|
|
8166
8245
|
headers: { "Content-Type": "text/markdown; charset=utf-8" },
|
|
8167
8246
|
});
|
|
8168
8247
|
}
|
|
@@ -8206,15 +8285,16 @@ export function getStaticPaths() {
|
|
|
8206
8285
|
}));
|
|
8207
8286
|
}
|
|
8208
8287
|
|
|
8209
|
-
export function GET({ props }) {
|
|
8210
|
-
|
|
8288
|
+
export function GET({ props }: { props: { section: string } }) {
|
|
8289
|
+
const bySection = feeds as Record<string, string>;
|
|
8290
|
+
return new Response(bySection[props.section] ?? "", {
|
|
8211
8291
|
headers: { "Content-Type": "application/rss+xml; charset=utf-8" },
|
|
8212
8292
|
});
|
|
8213
8293
|
}
|
|
8214
8294
|
`;
|
|
8215
8295
|
var ogEndpointTemplate = (customRoutes = []) => `// Generated by Blume. Do not edit.
|
|
8216
8296
|
import { renderOgImage } from "blume/og";
|
|
8217
|
-
import data from "
|
|
8297
|
+
import data from "blume:data";
|
|
8218
8298
|
|
|
8219
8299
|
export const prerender = true;
|
|
8220
8300
|
|
|
@@ -8222,9 +8302,9 @@ export const prerender = true;
|
|
|
8222
8302
|
const customRoutes = ${JSON.stringify(customRoutes)};
|
|
8223
8303
|
|
|
8224
8304
|
export function getStaticPaths() {
|
|
8225
|
-
const seen = new Set();
|
|
8226
|
-
const paths = [];
|
|
8227
|
-
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) => {
|
|
8228
8308
|
if (seen.has(slug)) {
|
|
8229
8309
|
return;
|
|
8230
8310
|
}
|
|
@@ -8257,17 +8337,18 @@ const siteHost = (() => {
|
|
|
8257
8337
|
}
|
|
8258
8338
|
})();
|
|
8259
8339
|
|
|
8260
|
-
export async function GET({ props }) {
|
|
8340
|
+
export async function GET({ props }: { props: { title: string } }) {
|
|
8261
8341
|
const png = await renderOgImage({
|
|
8262
|
-
accent: data.config.theme.accent.light,
|
|
8342
|
+
accent: data.config.og.palette?.accent ?? data.config.theme.accent.light,
|
|
8263
8343
|
brand: data.config.title,
|
|
8264
8344
|
description: data.config.description,
|
|
8265
|
-
logo: data.config.logo
|
|
8345
|
+
logo: data.config.og.logo,
|
|
8346
|
+
palette: data.config.og.palette,
|
|
8266
8347
|
repo: repoSlug,
|
|
8267
8348
|
site: siteHost,
|
|
8268
8349
|
title: props.title,
|
|
8269
8350
|
});
|
|
8270
|
-
return new Response(png, {
|
|
8351
|
+
return new Response(new Uint8Array(png), {
|
|
8271
8352
|
headers: {
|
|
8272
8353
|
"Cache-Control": "public, max-age=31536000, immutable",
|
|
8273
8354
|
"Content-Type": "image/png",
|
|
@@ -8317,10 +8398,6 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
|
|
|
8317
8398
|
</ReferenceLayout>
|
|
8318
8399
|
`;
|
|
8319
8400
|
var catchAllPageTemplate = (options) => {
|
|
8320
|
-
const askImport = options.askEnabled ? `import AskAI from "blume/components/islands/AskAI.astro";
|
|
8321
|
-
` : "";
|
|
8322
|
-
const askSlot = options.askEnabled ? `
|
|
8323
|
-
<AskAI slot="ask" strings={ui.ask} suggestions={data.config.ask?.suggestions ?? []} />` : "";
|
|
8324
8401
|
const mathImport = options.mathEnabled ? `import Math from "blume/components/content/Math.astro";
|
|
8325
8402
|
` : "";
|
|
8326
8403
|
const mathEntry = options.mathEnabled ? `Math,
|
|
@@ -8330,10 +8407,10 @@ var catchAllPageTemplate = (options) => {
|
|
|
8330
8407
|
return `---
|
|
8331
8408
|
// Generated by Blume. Do not edit.
|
|
8332
8409
|
import { getEntry, render } from "astro:content";
|
|
8410
|
+
import type { CollectionKey } from "astro:content";
|
|
8333
8411
|
import RootLayout from "blume/components/layout/RootLayout.astro";
|
|
8334
8412
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
8335
8413
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
8336
|
-
${askImport}
|
|
8337
8414
|
import Accordion from "blume/components/content/Accordion.astro";
|
|
8338
8415
|
import AccordionItem from "blume/components/content/AccordionItem.astro";
|
|
8339
8416
|
import AutoTypeTable from "blume/components/content/AutoTypeTable.astro";
|
|
@@ -8374,7 +8451,7 @@ import ApiTagOperations from "blume/components/openapi/ApiTagOperations.astro";
|
|
|
8374
8451
|
import Operation from "blume/components/openapi/Operation.astro";
|
|
8375
8452
|
${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";
|
|
8376
8453
|
import { islandComponents } from "../generated/islands.ts";
|
|
8377
|
-
import data from "
|
|
8454
|
+
import data from "blume:data";
|
|
8378
8455
|
|
|
8379
8456
|
const Color = Object.assign(ColorRoot, { Item: ColorItem, Row: ColorRow });
|
|
8380
8457
|
const Tree = Object.assign(TreeRoot, { File: TreeFile, Folder: TreeFolder });
|
|
@@ -8443,7 +8520,7 @@ export function getStaticPaths() {
|
|
|
8443
8520
|
}
|
|
8444
8521
|
|
|
8445
8522
|
const { entryId, collection, route, title, indexable, editUrl, lastModified, locale, alternates, fallback } = Astro.props;
|
|
8446
|
-
const entry = await getEntry(collection, entryId);
|
|
8523
|
+
const entry = await getEntry(collection as CollectionKey, entryId);
|
|
8447
8524
|
if (!entry) {
|
|
8448
8525
|
return new Response(null, { status: 404 });
|
|
8449
8526
|
}
|
|
@@ -8478,18 +8555,18 @@ const canonical =
|
|
|
8478
8555
|
// Locale resolution. With i18n on, pick the active locale's nav + dictionary,
|
|
8479
8556
|
// build hreflang alternates, and derive the language-switcher targets.
|
|
8480
8557
|
const i18n = data.config.i18n;
|
|
8481
|
-
const localePrefix = (codeArg) =>
|
|
8558
|
+
const localePrefix = (codeArg: string) =>
|
|
8482
8559
|
i18n && codeArg === i18n.defaultLocale && i18n.hideDefaultLocalePrefix
|
|
8483
8560
|
? ""
|
|
8484
8561
|
: \`/\${codeArg}\`;
|
|
8485
|
-
const localizeRoute = (logical, codeArg) => {
|
|
8562
|
+
const localizeRoute = (logical: string, codeArg: string) => {
|
|
8486
8563
|
const prefix = localePrefix(codeArg);
|
|
8487
8564
|
if (!prefix) {
|
|
8488
8565
|
return logical;
|
|
8489
8566
|
}
|
|
8490
8567
|
return logical === "/" ? prefix : \`\${prefix}\${logical}\`;
|
|
8491
8568
|
};
|
|
8492
|
-
const stripLocale = (path, codeArg) => {
|
|
8569
|
+
const stripLocale = (path: string, codeArg: string) => {
|
|
8493
8570
|
const prefix = localePrefix(codeArg);
|
|
8494
8571
|
return prefix && path.startsWith(prefix) ? path.slice(prefix.length) || "/" : path;
|
|
8495
8572
|
};
|
|
@@ -8506,7 +8583,7 @@ const contentLocale =
|
|
|
8506
8583
|
const contentDir = i18n
|
|
8507
8584
|
? (i18n.locales.find((l) => l.code === contentLocale)?.dir ?? "ltr")
|
|
8508
8585
|
: "ltr";
|
|
8509
|
-
const absolute = (path) => {
|
|
8586
|
+
const absolute = (path: string) => {
|
|
8510
8587
|
const p = withBase(path);
|
|
8511
8588
|
return base + (p === "/" ? "" : p);
|
|
8512
8589
|
};
|
|
@@ -8570,7 +8647,6 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
8570
8647
|
canonical={canonical}
|
|
8571
8648
|
editUrl={editUrl}
|
|
8572
8649
|
feedback={data.config.feedback}
|
|
8573
|
-
askEnabled={${options.askEnabled}}
|
|
8574
8650
|
exportPdf={${options.exportPdf}}
|
|
8575
8651
|
exportEpub={${options.exportEpub}}
|
|
8576
8652
|
feeds={data.feeds}
|
|
@@ -8580,7 +8656,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
8580
8656
|
lastModified={lastModified}
|
|
8581
8657
|
noindex={seo.noindex}
|
|
8582
8658
|
structuredDataEnabled={data.config.structuredData}
|
|
8583
|
-
|
|
8659
|
+
>
|
|
8584
8660
|
<h1>{title}</h1>
|
|
8585
8661
|
{frontmatter.description && <p class="text-lg text-muted-foreground">{frontmatter.description}</p>}
|
|
8586
8662
|
<Content components={components} />
|
|
@@ -8588,10 +8664,6 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
8588
8664
|
`;
|
|
8589
8665
|
};
|
|
8590
8666
|
var changelogIndexTemplate = (options) => {
|
|
8591
|
-
const askImport = options.askEnabled ? `import AskAI from "blume/components/islands/AskAI.astro";
|
|
8592
|
-
` : "";
|
|
8593
|
-
const askSlot = options.askEnabled ? `
|
|
8594
|
-
<AskAI slot="ask" strings={data.ui.ask} suggestions={data.config.ask?.suggestions ?? []} />` : "";
|
|
8595
8667
|
const clientData = options.needsReact ? `
|
|
8596
8668
|
clientData={{ config: data.config, navigation: data.navigation, page: { route: "/changelog", title: pageTitle } }}` : "";
|
|
8597
8669
|
const stagedSpread = options.staged ? `
|
|
@@ -8604,14 +8676,15 @@ import Update from "blume/components/content/Update.astro";
|
|
|
8604
8676
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
8605
8677
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
8606
8678
|
import { layoutOverrides } from "../generated/components.ts";
|
|
8607
|
-
|
|
8679
|
+
import data from "blume:data";
|
|
8608
8680
|
|
|
8609
8681
|
export const prerender = true;
|
|
8610
8682
|
|
|
8611
|
-
const entryDate = (entry
|
|
8612
|
-
|
|
8683
|
+
const entryDate = (entry: {
|
|
8684
|
+
data: { date?: string | null; changelog?: { date?: string | null } | null };
|
|
8685
|
+
}) => entry.data.date ?? entry.data.changelog?.date ?? null;
|
|
8613
8686
|
|
|
8614
|
-
const toTime = (value) => {
|
|
8687
|
+
const toTime = (value: string | null | undefined) => {
|
|
8615
8688
|
if (!value) {
|
|
8616
8689
|
return 0;
|
|
8617
8690
|
}
|
|
@@ -8619,7 +8692,7 @@ const toTime = (value) => {
|
|
|
8619
8692
|
return Number.isNaN(date.getTime()) ? 0 : date.getTime();
|
|
8620
8693
|
};
|
|
8621
8694
|
|
|
8622
|
-
const formatDate = (value) => {
|
|
8695
|
+
const formatDate = (value: string | null | undefined) => {
|
|
8623
8696
|
if (!value) {
|
|
8624
8697
|
return;
|
|
8625
8698
|
}
|
|
@@ -8632,14 +8705,14 @@ const formatDate = (value) => {
|
|
|
8632
8705
|
}).format(date);
|
|
8633
8706
|
};
|
|
8634
8707
|
|
|
8635
|
-
const slugify = (text) =>
|
|
8708
|
+
const slugify = (text: string) =>
|
|
8636
8709
|
text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") ||
|
|
8637
8710
|
"update";
|
|
8638
8711
|
|
|
8639
8712
|
// The major of a version's embedded semver (\`1.2.3\` -> 1, \`pkg@2.0.0\` -> 2), or
|
|
8640
8713
|
// null when there is no full major.minor.patch to key on. Drives the changelog's
|
|
8641
8714
|
// group-by-major pagination, so it tolerates the scoped tags monorepos publish.
|
|
8642
|
-
const majorVersion = (version) => {
|
|
8715
|
+
const majorVersion = (version: string | null | undefined) => {
|
|
8643
8716
|
const match = /(\\d+)\\.\\d+\\.\\d+/.exec(String(version ?? ""));
|
|
8644
8717
|
return match ? Number(match[1]) : null;
|
|
8645
8718
|
};
|
|
@@ -8671,7 +8744,7 @@ const items = await Promise.all(
|
|
|
8671
8744
|
return {
|
|
8672
8745
|
Content: (await render(entry)).Content,
|
|
8673
8746
|
date: formatDate(entryDate(entry)),
|
|
8674
|
-
href: routeByEntry.get(entry.id) ??
|
|
8747
|
+
href: routeByEntry.get(entry.id) ?? undefined,
|
|
8675
8748
|
id: slugify(label),
|
|
8676
8749
|
label,
|
|
8677
8750
|
major: majorVersion(entry.data.changelog?.version),
|
|
@@ -8700,7 +8773,9 @@ for (const item of items) {
|
|
|
8700
8773
|
// semver and they span more than one major line. Older majors then collapse
|
|
8701
8774
|
// into groups the reader reveals one at a time; otherwise the timeline is flat.
|
|
8702
8775
|
const majors = items.every((item) => item.major !== null)
|
|
8703
|
-
? [...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)
|
|
8704
8779
|
: [];
|
|
8705
8780
|
const paginate = majors.length > 1;
|
|
8706
8781
|
const majorGroups = majors.map((major) => ({
|
|
@@ -8773,14 +8848,13 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
8773
8848
|
ogImage={null}
|
|
8774
8849
|
x={data.config.x}
|
|
8775
8850
|
canonical={canonical}
|
|
8776
|
-
askEnabled={${options.askEnabled}}
|
|
8777
8851
|
exportPdf={${options.exportPdf}}
|
|
8778
8852
|
exportEpub={${options.exportEpub}}
|
|
8779
8853
|
feeds={data.feeds}
|
|
8780
8854
|
siteUrl={data.config.site}
|
|
8781
8855
|
noindex={false}
|
|
8782
8856
|
structuredDataEnabled={data.config.structuredData}
|
|
8783
|
-
|
|
8857
|
+
>
|
|
8784
8858
|
<h1>{changelogTitle}</h1>
|
|
8785
8859
|
{
|
|
8786
8860
|
items.length === 0 ? (
|
|
@@ -8839,7 +8913,7 @@ var notFoundPageTemplate = () => `---
|
|
|
8839
8913
|
// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
|
|
8840
8914
|
import PageLayout from "blume/components/layout/PageLayout.astro";
|
|
8841
8915
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
8842
|
-
import data from "
|
|
8916
|
+
import data from "blume:data";
|
|
8843
8917
|
|
|
8844
8918
|
export const prerender = true;
|
|
8845
8919
|
|
|
@@ -8956,7 +9030,10 @@ export const getStaticPaths = () =>
|
|
|
8956
9030
|
Object.keys(examples).map((path) => ({ params: { path } }));
|
|
8957
9031
|
|
|
8958
9032
|
const { path } = Astro.params;
|
|
8959
|
-
const entry = examples[path];
|
|
9033
|
+
const entry = path ? examples[path] : undefined;
|
|
9034
|
+
if (!entry) {
|
|
9035
|
+
return new Response(null, { status: 404 });
|
|
9036
|
+
}
|
|
8960
9037
|
const Example = entry.Component;
|
|
8961
9038
|
---
|
|
8962
9039
|
|
|
@@ -9000,11 +9077,24 @@ const Example = entry.Component;
|
|
|
9000
9077
|
var envTemplate = () => `/// <reference path="../.astro/types.d.ts" />
|
|
9001
9078
|
/// <reference types="astro/client" />
|
|
9002
9079
|
|
|
9080
|
+
declare module "blume:ask" {
|
|
9081
|
+
const Ask: typeof import("blume/components/islands/AskAI.astro").default;
|
|
9082
|
+
export default Ask;
|
|
9083
|
+
}
|
|
9084
|
+
|
|
9003
9085
|
declare module "blume:data" {
|
|
9004
9086
|
const data: import("blume").BlumeData;
|
|
9005
9087
|
export default data;
|
|
9006
9088
|
}
|
|
9007
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
|
+
|
|
9008
9098
|
declare module "blume:openapi" {
|
|
9009
9099
|
const specs: import("blume/openapi/model.ts").OpenApiData;
|
|
9010
9100
|
export default specs;
|
|
@@ -9135,7 +9225,7 @@ var specConfiguration = async (spec, root) => {
|
|
|
9135
9225
|
if (URL_SPEC2.test(spec)) {
|
|
9136
9226
|
return { config: { url: spec } };
|
|
9137
9227
|
}
|
|
9138
|
-
const absolute = isAbsolute8(spec) ? spec :
|
|
9228
|
+
const absolute = isAbsolute8(spec) ? spec : join20(root, spec);
|
|
9139
9229
|
try {
|
|
9140
9230
|
return { config: { content: await readFile8(absolute, "utf-8") } };
|
|
9141
9231
|
} catch {
|
|
@@ -9201,6 +9291,13 @@ var buildReferenceFiles = async (options) => {
|
|
|
9201
9291
|
// src/theme/entry.ts
|
|
9202
9292
|
var DARK_VARIANT = `/* Dark mode is driven by data-theme on the <html> element. */
|
|
9203
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
|
+
}`;
|
|
9204
9301
|
var TOKEN_DEFAULTS = `:root {
|
|
9205
9302
|
--blume-background: oklch(1 0 0);
|
|
9206
9303
|
--blume-background-image: none;
|
|
@@ -9306,6 +9403,8 @@ ${options.sources.map((source) => `@source "${source}";`).join(`
|
|
|
9306
9403
|
|
|
9307
9404
|
${DARK_VARIANT}
|
|
9308
9405
|
|
|
9406
|
+
${COLOR_SCHEME_DEFAULTS}
|
|
9407
|
+
|
|
9309
9408
|
${TOKEN_DEFAULTS}
|
|
9310
9409
|
|
|
9311
9410
|
${THEME_MAPPING}
|
|
@@ -9551,13 +9650,16 @@ blume-diff {
|
|
|
9551
9650
|
|
|
9552
9651
|
/* Language icon (simple-icons) sits at the header's left edge; the label shifts
|
|
9553
9652
|
right to make room. Injected at build time by the language-icon transformer.
|
|
9554
|
-
|
|
9555
|
-
|
|
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. */
|
|
9556
9658
|
.blume-lang-icon {
|
|
9557
9659
|
display: none;
|
|
9558
9660
|
}
|
|
9559
9661
|
|
|
9560
|
-
.prose > :where(pre[data-icon]) > .blume-lang-icon {
|
|
9662
|
+
.prose > :where(pre[data-language][data-icon]) > .blume-lang-icon {
|
|
9561
9663
|
color: var(--blume-muted-foreground);
|
|
9562
9664
|
display: block;
|
|
9563
9665
|
height: 0.875rem;
|
|
@@ -9567,7 +9669,7 @@ blume-diff {
|
|
|
9567
9669
|
width: 0.875rem;
|
|
9568
9670
|
}
|
|
9569
9671
|
|
|
9570
|
-
.prose > :where(pre[data-icon])::before {
|
|
9672
|
+
.prose > :where(pre[data-language][data-icon])::before {
|
|
9571
9673
|
padding-left: 2.5rem;
|
|
9572
9674
|
}
|
|
9573
9675
|
|
|
@@ -9618,11 +9720,40 @@ blume-diff {
|
|
|
9618
9720
|
font-size: 0.8125rem;
|
|
9619
9721
|
}
|
|
9620
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
|
+
|
|
9621
9751
|
/* GFM renders cells as <td><code> directly, which the descendant form alone
|
|
9622
9752
|
never matches (a cell is not its own descendant). */
|
|
9623
9753
|
.prose :where(td, th) > code,
|
|
9624
9754
|
.prose :where(td, th) :not(pre) > code {
|
|
9625
|
-
|
|
9755
|
+
overflow-wrap: break-word;
|
|
9756
|
+
white-space: normal;
|
|
9626
9757
|
}
|
|
9627
9758
|
|
|
9628
9759
|
blume-tabs pre,
|
|
@@ -9862,6 +9993,8 @@ ${options.sources.map((source) => `@source "${source}";`).join(`
|
|
|
9862
9993
|
|
|
9863
9994
|
${DARK_VARIANT}
|
|
9864
9995
|
|
|
9996
|
+
${COLOR_SCHEME_DEFAULTS}
|
|
9997
|
+
|
|
9865
9998
|
${TOKEN_DEFAULTS}
|
|
9866
9999
|
|
|
9867
10000
|
${THEME_MAPPING}
|
|
@@ -9882,7 +10015,7 @@ ${options.userCss}
|
|
|
9882
10015
|
`;
|
|
9883
10016
|
|
|
9884
10017
|
// src/theme/twoslash.ts
|
|
9885
|
-
import { readFileSync as
|
|
10018
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
9886
10019
|
import { createRequire as createRequire4 } from "node:module";
|
|
9887
10020
|
var require2 = createRequire4(import.meta.url);
|
|
9888
10021
|
var OVERRIDES = `
|
|
@@ -9949,14 +10082,15 @@ var OVERRIDES = `
|
|
|
9949
10082
|
`;
|
|
9950
10083
|
var twoslashCss = () => {
|
|
9951
10084
|
const file = require2.resolve("@shikijs/twoslash/style-rich.css");
|
|
9952
|
-
return `${
|
|
10085
|
+
return `${readFileSync7(file, "utf-8")}
|
|
9953
10086
|
${OVERRIDES}`;
|
|
9954
10087
|
};
|
|
9955
10088
|
|
|
9956
10089
|
// src/astro/component-slots.ts
|
|
9957
10090
|
var EMPTY_MODULE = `// Generated by Blume. Do not edit.
|
|
9958
|
-
|
|
9959
|
-
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> = {};
|
|
9960
10094
|
`;
|
|
9961
10095
|
var attributeValue = (value) => value.replaceAll(/["\n\r]/gu, " ").trim();
|
|
9962
10096
|
var CLIENT_LOAD = "client:load";
|
|
@@ -10054,12 +10188,12 @@ export const layoutOverrides = { ...(overrides.layout ?? {})${layoutEntries.leng
|
|
|
10054
10188
|
|
|
10055
10189
|
// src/astro/examples.ts
|
|
10056
10190
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
10057
|
-
import { join as
|
|
10191
|
+
import { join as join22, relative as relative7 } from "pathe";
|
|
10058
10192
|
import { glob as glob4 } from "tinyglobby";
|
|
10059
10193
|
|
|
10060
10194
|
// src/astro/islands.ts
|
|
10061
10195
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
10062
|
-
import { basename, join as
|
|
10196
|
+
import { basename, join as join21 } from "pathe";
|
|
10063
10197
|
import { glob as glob3 } from "tinyglobby";
|
|
10064
10198
|
var DEFAULT_CLIENT = "visible";
|
|
10065
10199
|
var VALID_MODES = new Set([
|
|
@@ -10088,7 +10222,7 @@ var readClientMode = (source, file, warnings) => {
|
|
|
10088
10222
|
return mode;
|
|
10089
10223
|
};
|
|
10090
10224
|
var discoverIslands = async (root) => {
|
|
10091
|
-
const dir =
|
|
10225
|
+
const dir = join21(root, "islands");
|
|
10092
10226
|
const matches = await glob3(["**/*.{jsx,svelte,tsx,vue}"], {
|
|
10093
10227
|
absolute: true,
|
|
10094
10228
|
cwd: dir,
|
|
@@ -10151,7 +10285,7 @@ var splitGlobBase = (pattern) => {
|
|
|
10151
10285
|
};
|
|
10152
10286
|
var discoverExamples = async (root, pattern = "examples") => {
|
|
10153
10287
|
const { base, rest } = GLOB_MAGIC.test(pattern) ? splitGlobBase(pattern) : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };
|
|
10154
|
-
const dir =
|
|
10288
|
+
const dir = join22(root, base);
|
|
10155
10289
|
const matches = await glob4([rest], {
|
|
10156
10290
|
absolute: true,
|
|
10157
10291
|
cwd: dir,
|
|
@@ -10191,10 +10325,10 @@ var discoverExamples = async (root, pattern = "examples") => {
|
|
|
10191
10325
|
};
|
|
10192
10326
|
|
|
10193
10327
|
// src/astro/generate.ts
|
|
10194
|
-
var BLUME_SRC =
|
|
10328
|
+
var BLUME_SRC = join23(packageRoot(), "src");
|
|
10195
10329
|
var canResolveFrom = (fromDir, spec) => {
|
|
10196
10330
|
try {
|
|
10197
|
-
createRequire5(pathToFileURL3(
|
|
10331
|
+
createRequire5(pathToFileURL3(join23(fromDir, "_.js")).href).resolve(spec);
|
|
10198
10332
|
return true;
|
|
10199
10333
|
} catch {
|
|
10200
10334
|
return false;
|
|
@@ -10205,7 +10339,7 @@ var resolveReactCompiler = (config, needsReact) => {
|
|
|
10205
10339
|
return null;
|
|
10206
10340
|
}
|
|
10207
10341
|
try {
|
|
10208
|
-
return createRequire5(pathToFileURL3(
|
|
10342
|
+
return createRequire5(pathToFileURL3(join23(packageRoot(), "_.js")).href).resolve("babel-plugin-react-compiler");
|
|
10209
10343
|
} catch {
|
|
10210
10344
|
return null;
|
|
10211
10345
|
}
|
|
@@ -10215,15 +10349,15 @@ var reactCompilerWarnings = (config, needsReact, compilerPath) => needsReact &&
|
|
|
10215
10349
|
] : [];
|
|
10216
10350
|
var resolvedAstroPath = (fromDir) => {
|
|
10217
10351
|
try {
|
|
10218
|
-
const pkg = createRequire5(pathToFileURL3(
|
|
10352
|
+
const pkg = createRequire5(pathToFileURL3(join23(fromDir, "_.js")).href).resolve("astro/package.json");
|
|
10219
10353
|
return realpathSync(pkg);
|
|
10220
10354
|
} catch {
|
|
10221
10355
|
return null;
|
|
10222
10356
|
}
|
|
10223
10357
|
};
|
|
10224
10358
|
var blumeDepsDir = (pkgDir = packageRoot()) => {
|
|
10225
|
-
const candidates = [
|
|
10226
|
-
return candidates.find((dir) =>
|
|
10359
|
+
const candidates = [join23(pkgDir, "node_modules"), dirname8(pkgDir)];
|
|
10360
|
+
return candidates.find((dir) => existsSync13(join23(dir, "astro"))) ?? null;
|
|
10227
10361
|
};
|
|
10228
10362
|
var linkDepsJunction = async (link, depsDir) => {
|
|
10229
10363
|
let existing;
|
|
@@ -10246,7 +10380,7 @@ var readPkgVersion = (pkgJsonPath) => {
|
|
|
10246
10380
|
return null;
|
|
10247
10381
|
}
|
|
10248
10382
|
try {
|
|
10249
|
-
return JSON.parse(
|
|
10383
|
+
return JSON.parse(readFileSync8(pkgJsonPath, "utf-8")).version ?? null;
|
|
10250
10384
|
} catch {
|
|
10251
10385
|
return null;
|
|
10252
10386
|
}
|
|
@@ -10268,8 +10402,8 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
|
10268
10402
|
if (blumeAstro && outDirAstro === blumeAstro) {
|
|
10269
10403
|
return null;
|
|
10270
10404
|
}
|
|
10271
|
-
if (
|
|
10272
|
-
await linkDepsJunction(
|
|
10405
|
+
if (existsSync13(join23(depsDir, "@astrojs", "mdx"))) {
|
|
10406
|
+
await linkDepsJunction(join23(outDir, "node_modules"), depsDir);
|
|
10273
10407
|
return null;
|
|
10274
10408
|
}
|
|
10275
10409
|
return astroConflictWarning(blumeAstro, outDirAstro);
|
|
@@ -10301,14 +10435,14 @@ var deploymentAdapterWarnings = (deployment, root) => {
|
|
|
10301
10435
|
}
|
|
10302
10436
|
return [];
|
|
10303
10437
|
};
|
|
10304
|
-
var examplesCssFile = (root, config) => config.examples.css ?
|
|
10438
|
+
var examplesCssFile = (root, config) => config.examples.css ? join23(root, config.examples.css) : null;
|
|
10305
10439
|
var writeExamplesPreview = async (options) => {
|
|
10306
10440
|
const { config, hasExamples, root, srcDir, write } = options;
|
|
10307
10441
|
if (hasExamples) {
|
|
10308
|
-
await write(
|
|
10442
|
+
await write(join23(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
|
|
10309
10443
|
}
|
|
10310
10444
|
const cssFile = examplesCssFile(root, config);
|
|
10311
|
-
return cssFile && !
|
|
10445
|
+
return cssFile && !existsSync13(cssFile) ? [
|
|
10312
10446
|
`examples.css points at "${config.examples.css}", which doesn't exist; previews render without it.`
|
|
10313
10447
|
] : [];
|
|
10314
10448
|
};
|
|
@@ -10337,7 +10471,7 @@ var detectUsesMath = async (root, staged = []) => {
|
|
|
10337
10471
|
ignore: ["**/node_modules/**", "**/.blume/**", "**/dist/**"],
|
|
10338
10472
|
onlyFiles: true
|
|
10339
10473
|
});
|
|
10340
|
-
const contents = await Promise.all(files.map((file) => readOptional(
|
|
10474
|
+
const contents = await Promise.all(files.map((file) => readOptional(join23(root, file))));
|
|
10341
10475
|
return [...contents, ...staged].some(containsMath);
|
|
10342
10476
|
};
|
|
10343
10477
|
var writeIfChanged = async (path, content) => {
|
|
@@ -10389,14 +10523,46 @@ var writeStagedContent = async (out, staged) => {
|
|
|
10389
10523
|
const contentDir = stagedContentDir(out);
|
|
10390
10524
|
const written = new Set;
|
|
10391
10525
|
await Promise.all([...staged].map(async ([entryId, text]) => {
|
|
10392
|
-
const path =
|
|
10526
|
+
const path = join23(contentDir, entryId);
|
|
10393
10527
|
written.add(normalize3(path));
|
|
10394
10528
|
await writeIfChanged(path, text);
|
|
10395
10529
|
}));
|
|
10396
|
-
if (
|
|
10530
|
+
if (existsSync13(contentDir)) {
|
|
10397
10531
|
await pruneOrphans(contentDir, written);
|
|
10398
10532
|
}
|
|
10399
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
|
+
};
|
|
10400
10566
|
var resolveLogo = (project) => {
|
|
10401
10567
|
const { logo } = project.config;
|
|
10402
10568
|
if (!logo) {
|
|
@@ -10409,17 +10575,15 @@ var resolveLogo = (project) => {
|
|
|
10409
10575
|
const dark = image?.dark ?? image?.light;
|
|
10410
10576
|
const alt = image?.alt ?? "";
|
|
10411
10577
|
const brandHref = href ?? "/";
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
join22(project.context.root, rel)
|
|
10417
|
-
].find((path) => existsSync12(path));
|
|
10418
|
-
if (file) {
|
|
10419
|
-
return { alt, href: brandHref, svg: readFileSync7(file, "utf-8"), text };
|
|
10420
|
-
}
|
|
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 };
|
|
10421
10582
|
}
|
|
10422
|
-
|
|
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 };
|
|
10423
10587
|
};
|
|
10424
10588
|
var FAVICON_CANDIDATES = [
|
|
10425
10589
|
"icon.svg",
|
|
@@ -10440,9 +10604,9 @@ var faviconType = (name) => {
|
|
|
10440
10604
|
const ext = name.split(".").pop()?.toLowerCase();
|
|
10441
10605
|
return ext ? FAVICON_TYPES[ext] : undefined;
|
|
10442
10606
|
};
|
|
10443
|
-
var inlineDataUri = (file, type) => `data:${type};base64,${
|
|
10607
|
+
var inlineDataUri = (file, type) => `data:${type};base64,${readFileSync8(file).toString("base64")}`;
|
|
10444
10608
|
var defaultFavicon = () => ({
|
|
10445
|
-
href: inlineDataUri(
|
|
10609
|
+
href: inlineDataUri(join23(BLUME_SRC, "assets", "icon.png"), "image/png"),
|
|
10446
10610
|
type: "image/png"
|
|
10447
10611
|
});
|
|
10448
10612
|
var APPLE_ICON_CANDIDATES = [
|
|
@@ -10454,13 +10618,13 @@ var APPLE_ICON_CANDIDATES = [
|
|
|
10454
10618
|
var resolveIconFile = (project, candidates) => {
|
|
10455
10619
|
const { root } = project.context;
|
|
10456
10620
|
for (const name of candidates) {
|
|
10457
|
-
if (
|
|
10621
|
+
if (existsSync13(join23(root, "public", name))) {
|
|
10458
10622
|
return { href: `/${name}`, type: faviconType(name) };
|
|
10459
10623
|
}
|
|
10460
10624
|
}
|
|
10461
10625
|
for (const name of candidates) {
|
|
10462
|
-
const file =
|
|
10463
|
-
if (
|
|
10626
|
+
const file = join23(root, name);
|
|
10627
|
+
if (existsSync13(file)) {
|
|
10464
10628
|
const type = faviconType(name);
|
|
10465
10629
|
return { href: inlineDataUri(file, type ?? "image/x-icon"), type };
|
|
10466
10630
|
}
|
|
@@ -10489,6 +10653,8 @@ var buildRuntimeData = (project) => {
|
|
|
10489
10653
|
const { github } = config;
|
|
10490
10654
|
const repoUrl = github ? `https://github.com/${github.owner}/${github.repo}` : null;
|
|
10491
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;
|
|
10492
10658
|
const editUrlFor = (sourcePath) => {
|
|
10493
10659
|
if (!(editBase && sourcePath)) {
|
|
10494
10660
|
return null;
|
|
@@ -10498,10 +10664,9 @@ var buildRuntimeData = (project) => {
|
|
|
10498
10664
|
return `${editBase}/${editPath}`;
|
|
10499
10665
|
};
|
|
10500
10666
|
const { i18n } = config;
|
|
10501
|
-
const
|
|
10667
|
+
const withRepoUrl = (nav) => ({
|
|
10502
10668
|
...nav,
|
|
10503
|
-
repoUrl: config.navigation.repo && repoUrl ? repoUrl : null
|
|
10504
|
-
tabs: [...nav.tabs, ...referenceTabs(config)]
|
|
10669
|
+
repoUrl: config.navigation.repo && repoUrl ? repoUrl : null
|
|
10505
10670
|
});
|
|
10506
10671
|
const uiByLocale = i18n ? Object.fromEntries(i18n.locales.map(({ code }) => [
|
|
10507
10672
|
code,
|
|
@@ -10516,7 +10681,7 @@ var buildRuntimeData = (project) => {
|
|
|
10516
10681
|
}) : EN_UI;
|
|
10517
10682
|
const navigationByLocale = i18n ? Object.fromEntries(i18n.locales.map(({ code }) => [
|
|
10518
10683
|
code,
|
|
10519
|
-
|
|
10684
|
+
withRepoUrl(graph.navigationByLocale[code] ?? {
|
|
10520
10685
|
featured: [],
|
|
10521
10686
|
selectors: [],
|
|
10522
10687
|
sidebar: [],
|
|
@@ -10546,9 +10711,16 @@ var buildRuntimeData = (project) => {
|
|
|
10546
10711
|
}))
|
|
10547
10712
|
} : null,
|
|
10548
10713
|
imageZoom: config.markdown.imageZoom,
|
|
10549
|
-
logo
|
|
10550
|
-
mcp: config.mcp.enabled ? {
|
|
10551
|
-
|
|
10714
|
+
logo,
|
|
10715
|
+
mcp: config.ai.mcp.enabled ? {
|
|
10716
|
+
name: config.ai.mcp.name ?? config.title,
|
|
10717
|
+
route: config.ai.mcp.route
|
|
10718
|
+
} : null,
|
|
10719
|
+
og: {
|
|
10720
|
+
enabled: config.seo.og.enabled ?? false,
|
|
10721
|
+
logo: ogLogo,
|
|
10722
|
+
palette: config.seo.og.palette
|
|
10723
|
+
},
|
|
10552
10724
|
repoUrl,
|
|
10553
10725
|
search: {
|
|
10554
10726
|
enabled: config.search.provider !== "none",
|
|
@@ -10566,7 +10738,7 @@ var buildRuntimeData = (project) => {
|
|
|
10566
10738
|
title: feed.title
|
|
10567
10739
|
})),
|
|
10568
10740
|
fontCssVars: configuredCssVars(config.theme.fonts),
|
|
10569
|
-
navigation:
|
|
10741
|
+
navigation: withRepoUrl(graph.navigation),
|
|
10570
10742
|
navigationByLocale,
|
|
10571
10743
|
routes: manifest.routes.map((route) => ({
|
|
10572
10744
|
alternates: route.alternates,
|
|
@@ -10591,8 +10763,8 @@ var buildRuntimeData = (project) => {
|
|
|
10591
10763
|
};
|
|
10592
10764
|
var planMcp = (project, srcDir, userPages) => {
|
|
10593
10765
|
const { config } = project;
|
|
10594
|
-
const { route } = config.mcp;
|
|
10595
|
-
const dir =
|
|
10766
|
+
const { route } = config.ai.mcp;
|
|
10767
|
+
const dir = join23(srcDir, "blume-mcp");
|
|
10596
10768
|
const base = {
|
|
10597
10769
|
dir,
|
|
10598
10770
|
discoveryPages: [],
|
|
@@ -10601,14 +10773,14 @@ var planMcp = (project, srcDir, userPages) => {
|
|
|
10601
10773
|
srcDir,
|
|
10602
10774
|
warnings: []
|
|
10603
10775
|
};
|
|
10604
|
-
if (!config.mcp.enabled) {
|
|
10776
|
+
if (!config.ai.mcp.enabled) {
|
|
10605
10777
|
return base;
|
|
10606
10778
|
}
|
|
10607
10779
|
if (routeIsTaken(userPages, project.graph.pages, route)) {
|
|
10608
10780
|
return {
|
|
10609
10781
|
...base,
|
|
10610
10782
|
warnings: [
|
|
10611
|
-
`MCP server route "${route}" is already used by a content or custom page; the MCP server was not generated. Set a different "mcp.route" in blume.config.ts.`
|
|
10783
|
+
`MCP server route "${route}" is already used by a content or custom page; the MCP server was not generated. Set a different "ai.mcp.route" in blume.config.ts.`
|
|
10612
10784
|
]
|
|
10613
10785
|
};
|
|
10614
10786
|
}
|
|
@@ -10616,11 +10788,11 @@ var planMcp = (project, srcDir, userPages) => {
|
|
|
10616
10788
|
...base,
|
|
10617
10789
|
discoveryPages: [
|
|
10618
10790
|
{
|
|
10619
|
-
entrypoint:
|
|
10791
|
+
entrypoint: join23(dir, "discovery.ts"),
|
|
10620
10792
|
pattern: "/.well-known/mcp.json"
|
|
10621
10793
|
},
|
|
10622
10794
|
{
|
|
10623
|
-
entrypoint:
|
|
10795
|
+
entrypoint: join23(dir, "server-card.ts"),
|
|
10624
10796
|
pattern: "/.well-known/mcp/server-card.json"
|
|
10625
10797
|
}
|
|
10626
10798
|
],
|
|
@@ -10640,11 +10812,11 @@ var writeMcpFiles = async (project, plan, write) => {
|
|
|
10640
10812
|
version: data.version
|
|
10641
10813
|
};
|
|
10642
10814
|
await Promise.all([
|
|
10643
|
-
write(
|
|
10815
|
+
write(join23(plan.srcDir, "generated", "mcp-data.json"), `${JSON.stringify(data)}
|
|
10644
10816
|
`),
|
|
10645
|
-
write(
|
|
10646
|
-
write(
|
|
10647
|
-
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)))
|
|
10648
10820
|
]);
|
|
10649
10821
|
};
|
|
10650
10822
|
var writeAskFiles = async (project, srcDir, write) => {
|
|
@@ -10654,16 +10826,16 @@ var writeAskFiles = async (project, srcDir, write) => {
|
|
|
10654
10826
|
}
|
|
10655
10827
|
const grounded = ask.provider !== "inkeep";
|
|
10656
10828
|
if (grounded) {
|
|
10657
|
-
await write(
|
|
10829
|
+
await write(join23(srcDir, "generated", "ask-data.json"), `${JSON.stringify(await buildAskData(project))}
|
|
10658
10830
|
`);
|
|
10659
10831
|
}
|
|
10660
|
-
await write(
|
|
10832
|
+
await write(join23(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(resolveAskBackend(ask), grounded));
|
|
10661
10833
|
};
|
|
10662
10834
|
var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
|
|
10663
10835
|
if (routeIsTaken(pages, contentPages, "/404")) {
|
|
10664
10836
|
return;
|
|
10665
10837
|
}
|
|
10666
|
-
await write(
|
|
10838
|
+
await write(join23(srcDir, "pages", "404.astro"), notFoundPageTemplate());
|
|
10667
10839
|
};
|
|
10668
10840
|
var buildComponentSlots = async (componentsFile) => {
|
|
10669
10841
|
const analysis = componentsFile ? analyzeComponentOverrides(await readFile11(componentsFile, "utf-8"), componentsFile) : null;
|
|
@@ -10676,13 +10848,14 @@ var buildComponentSlots = async (componentsFile) => {
|
|
|
10676
10848
|
var generateRuntime = async (project) => {
|
|
10677
10849
|
const { context, config } = project;
|
|
10678
10850
|
const out = context.outDir;
|
|
10679
|
-
const srcDir =
|
|
10680
|
-
const
|
|
10681
|
-
const
|
|
10682
|
-
const
|
|
10683
|
-
const
|
|
10684
|
-
const
|
|
10685
|
-
const
|
|
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");
|
|
10686
10859
|
const written = new Set;
|
|
10687
10860
|
const write = (path, content) => {
|
|
10688
10861
|
written.add(normalize3(path));
|
|
@@ -10733,8 +10906,9 @@ var generateRuntime = async (project) => {
|
|
|
10733
10906
|
const hasFilesystemSource = project.sources.some((source) => !source.staged);
|
|
10734
10907
|
const [structural] = await Promise.all([
|
|
10735
10908
|
Promise.all([
|
|
10736
|
-
write(
|
|
10909
|
+
write(join23(out, "astro.config.mjs"), astroConfigTemplate({
|
|
10737
10910
|
aliases: resolveTsconfigAliases(context.root),
|
|
10911
|
+
askPath,
|
|
10738
10912
|
config,
|
|
10739
10913
|
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
10740
10914
|
context,
|
|
@@ -10750,26 +10924,26 @@ var generateRuntime = async (project) => {
|
|
|
10750
10924
|
searchClientPath,
|
|
10751
10925
|
themePath
|
|
10752
10926
|
})),
|
|
10753
|
-
write(
|
|
10754
|
-
write(
|
|
10755
|
-
write(
|
|
10756
|
-
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({
|
|
10757
10931
|
collection: resolveDocsCollection(config, context),
|
|
10758
10932
|
config,
|
|
10759
10933
|
context,
|
|
10760
10934
|
filesystem: hasFilesystemSource,
|
|
10761
10935
|
staged: hasStaged
|
|
10762
10936
|
})),
|
|
10763
|
-
write(
|
|
10764
|
-
askEnabled,
|
|
10937
|
+
write(join23(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
|
|
10765
10938
|
exportEpub,
|
|
10766
10939
|
exportPdf,
|
|
10767
10940
|
mathEnabled: usesMath,
|
|
10768
10941
|
needsReact
|
|
10769
10942
|
})),
|
|
10770
|
-
write(
|
|
10771
|
-
write(
|
|
10772
|
-
write(
|
|
10943
|
+
write(askPath, askComponentTemplate(askEnabled)),
|
|
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)),
|
|
10773
10947
|
write(examplesThemePath, examplesEntryTemplate({
|
|
10774
10948
|
configTokens: buildThemeCss(config.theme),
|
|
10775
10949
|
sources: [`${context.root}/**/*.{astro,jsx,svelte,ts,tsx,vue}`],
|
|
@@ -10785,18 +10959,17 @@ var generateRuntime = async (project) => {
|
|
|
10785
10959
|
userTheme
|
|
10786
10960
|
}))
|
|
10787
10961
|
]),
|
|
10788
|
-
Promise.all(islandDiscovery.islands.map((island) => write(
|
|
10789
|
-
Promise.all(slotPlan.wrappers.map((wrapper) => write(
|
|
10790
|
-
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)))),
|
|
10791
10965
|
writeAskFiles(project, srcDir, write),
|
|
10792
10966
|
writeMcpFiles(project, mcp, write)
|
|
10793
10967
|
]);
|
|
10794
10968
|
if (config.seo.og.enabled) {
|
|
10795
|
-
await write(
|
|
10969
|
+
await write(join23(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes));
|
|
10796
10970
|
}
|
|
10797
10971
|
if (hasGeneratedChangelog(project, pages)) {
|
|
10798
|
-
await write(
|
|
10799
|
-
askEnabled,
|
|
10972
|
+
await write(join23(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
|
|
10800
10973
|
exportEpub,
|
|
10801
10974
|
exportPdf,
|
|
10802
10975
|
needsReact,
|
|
@@ -10816,27 +10989,27 @@ var generateRuntime = async (project) => {
|
|
|
10816
10989
|
]);
|
|
10817
10990
|
if (servesStaticIndex(config.search.provider)) {
|
|
10818
10991
|
const documents = await buildSearchDocuments(project);
|
|
10819
|
-
await write(
|
|
10992
|
+
await write(join23(srcDir, "generated", "search.json"), `${JSON.stringify(documents)}
|
|
10820
10993
|
`);
|
|
10821
|
-
await write(
|
|
10994
|
+
await write(join23(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
|
|
10822
10995
|
}
|
|
10823
10996
|
if (config.search.provider === "mixedbread") {
|
|
10824
|
-
await write(
|
|
10997
|
+
await write(join23(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""));
|
|
10825
10998
|
}
|
|
10826
10999
|
const rawMarkdown = await buildRawMarkdown(project);
|
|
10827
11000
|
await Promise.all([
|
|
10828
|
-
write(
|
|
11001
|
+
write(join23(srcDir, "generated", "raw-markdown.json"), `${JSON.stringify(rawMarkdown)}
|
|
10829
11002
|
`),
|
|
10830
|
-
write(
|
|
10831
|
-
write(
|
|
11003
|
+
write(join23(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate("md")),
|
|
11004
|
+
write(join23(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate("mdx"))
|
|
10832
11005
|
]);
|
|
10833
11006
|
const feeds = buildRssFeeds(project);
|
|
10834
11007
|
if (feeds.length > 0) {
|
|
10835
11008
|
const feedXml = Object.fromEntries(feeds.map((feed) => [feed.type, renderRssFeed(feed)]));
|
|
10836
11009
|
await Promise.all([
|
|
10837
|
-
write(
|
|
11010
|
+
write(join23(srcDir, "generated", "rss.json"), `${JSON.stringify(feedXml)}
|
|
10838
11011
|
`),
|
|
10839
|
-
write(
|
|
11012
|
+
write(join23(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate())
|
|
10840
11013
|
]);
|
|
10841
11014
|
}
|
|
10842
11015
|
const warnings = [
|
|
@@ -10851,7 +11024,7 @@ var generateRuntime = async (project) => {
|
|
|
10851
11024
|
const navTargetRoutes = new Set([
|
|
10852
11025
|
...project.graph.routes.keys(),
|
|
10853
11026
|
...pages.map((page) => page.pattern),
|
|
10854
|
-
...
|
|
11027
|
+
...referenceRoutes(config)
|
|
10855
11028
|
]);
|
|
10856
11029
|
if (hasGeneratedChangelog(project, pages)) {
|
|
10857
11030
|
navTargetRoutes.add("/changelog");
|
|
@@ -10875,14 +11048,14 @@ var generateRuntime = async (project) => {
|
|
|
10875
11048
|
root: context.root
|
|
10876
11049
|
});
|
|
10877
11050
|
warnings.push(...references.warnings);
|
|
10878
|
-
await Promise.all(references.files.map((file) => write(
|
|
11051
|
+
await Promise.all(references.files.map((file) => write(join23(srcDir, "pages", file.pagePath), file.content)));
|
|
10879
11052
|
}
|
|
10880
11053
|
const openApiSource2 = project.sources.find(isOpenApiSource);
|
|
10881
11054
|
await Promise.all([
|
|
10882
|
-
write(
|
|
11055
|
+
write(join23(srcDir, "generated", "data.json"), buildRuntimeData(project)),
|
|
10883
11056
|
write(openapiPath, `${JSON.stringify(openApiSource2 ? openApiSource2.openApiData() : {})}
|
|
10884
11057
|
`),
|
|
10885
|
-
write(
|
|
11058
|
+
write(join23(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
|
|
10886
11059
|
`),
|
|
10887
11060
|
writeStagedContent(out, staged)
|
|
10888
11061
|
]);
|
|
@@ -10894,7 +11067,7 @@ var generateRuntime = async (project) => {
|
|
|
10894
11067
|
import { relative as relative11 } from "pathe";
|
|
10895
11068
|
|
|
10896
11069
|
// src/core/config.ts
|
|
10897
|
-
import { existsSync as
|
|
11070
|
+
import { existsSync as existsSync14, readFileSync as readFileSync9 } from "node:fs";
|
|
10898
11071
|
|
|
10899
11072
|
// src/core/deployment-env.ts
|
|
10900
11073
|
var toUrl = (value) => {
|
|
@@ -10964,7 +11137,7 @@ var loadConfig = async (root, options = {}) => {
|
|
|
10964
11137
|
}
|
|
10965
11138
|
const parsed = blumeConfigSchema.safeParse(raw ?? {});
|
|
10966
11139
|
if (!parsed.success) {
|
|
10967
|
-
const source = configFile &&
|
|
11140
|
+
const source = configFile && existsSync14(configFile) ? readFileSync9(configFile, "utf-8") : undefined;
|
|
10968
11141
|
const diagnostics = diagnosticsFromZod(parsed.error, {
|
|
10969
11142
|
code: "BLUME_CONFIG_INVALID",
|
|
10970
11143
|
file: configFile ?? undefined,
|
|
@@ -11259,6 +11432,29 @@ var buildConfigSidebar = (items, byRoute, display, basePath) => {
|
|
|
11259
11432
|
}
|
|
11260
11433
|
return nodes;
|
|
11261
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
|
+
});
|
|
11262
11458
|
var buildNavigation = (pages, options) => {
|
|
11263
11459
|
const basePath = options.basePath ?? "";
|
|
11264
11460
|
const display = options.display ?? "flat";
|
|
@@ -11294,19 +11490,21 @@ var buildNavigation = (pages, options) => {
|
|
|
11294
11490
|
}
|
|
11295
11491
|
}
|
|
11296
11492
|
if (options.sidebar) {
|
|
11493
|
+
const sidebar2 = buildConfigSidebar(options.sidebar, byRoute, display, basePath);
|
|
11297
11494
|
return {
|
|
11298
11495
|
featured,
|
|
11299
11496
|
selectors,
|
|
11300
|
-
sidebar:
|
|
11301
|
-
tabs: tabs2
|
|
11497
|
+
sidebar: sidebar2,
|
|
11498
|
+
tabs: withTabHrefs(tabs2, sidebar2)
|
|
11302
11499
|
};
|
|
11303
11500
|
}
|
|
11304
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])));
|
|
11305
11503
|
return {
|
|
11306
11504
|
featured,
|
|
11307
11505
|
selectors,
|
|
11308
|
-
sidebar
|
|
11309
|
-
tabs: tabs2
|
|
11506
|
+
sidebar,
|
|
11507
|
+
tabs: withTabHrefs(tabs2, sidebar)
|
|
11310
11508
|
};
|
|
11311
11509
|
};
|
|
11312
11510
|
|
|
@@ -11675,8 +11873,8 @@ var scanProject = async (root, options = {}) => {
|
|
|
11675
11873
|
};
|
|
11676
11874
|
|
|
11677
11875
|
// src/cli/env.ts
|
|
11678
|
-
import { existsSync as
|
|
11679
|
-
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";
|
|
11680
11878
|
var ENV_LINE = /^\s*(?:export\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?<value>.*?)\s*$/u;
|
|
11681
11879
|
var DOUBLE_QUOTED2 = /^"(?<body>[\s\S]*)"$/u;
|
|
11682
11880
|
var SINGLE_QUOTED = /^'(?<body>[\s\S]*)'$/u;
|
|
@@ -11722,8 +11920,8 @@ var applyEnv = (parsed) => {
|
|
|
11722
11920
|
};
|
|
11723
11921
|
var loadFile = (path) => {
|
|
11724
11922
|
try {
|
|
11725
|
-
if (
|
|
11726
|
-
applyEnv(parseEnv(
|
|
11923
|
+
if (existsSync15(path)) {
|
|
11924
|
+
applyEnv(parseEnv(readFileSync10(path, "utf-8")));
|
|
11727
11925
|
}
|
|
11728
11926
|
} catch {}
|
|
11729
11927
|
};
|
|
@@ -11731,10 +11929,10 @@ var loadEnvFiles = (startDir) => {
|
|
|
11731
11929
|
let dir = resolve7(startDir);
|
|
11732
11930
|
let done = false;
|
|
11733
11931
|
while (!done) {
|
|
11734
|
-
loadFile(
|
|
11735
|
-
loadFile(
|
|
11932
|
+
loadFile(join24(dir, ".env.local"));
|
|
11933
|
+
loadFile(join24(dir, ".env"));
|
|
11736
11934
|
const parent = dirname10(dir);
|
|
11737
|
-
done =
|
|
11935
|
+
done = existsSync15(join24(dir, ".git")) || parent === dir;
|
|
11738
11936
|
dir = parent;
|
|
11739
11937
|
}
|
|
11740
11938
|
};
|
|
@@ -11869,12 +12067,12 @@ var emitRedirectFiles = async (config, distDir) => {
|
|
|
11869
12067
|
if (redirects.length === 0 || config.deployment.output !== "static") {
|
|
11870
12068
|
return;
|
|
11871
12069
|
}
|
|
11872
|
-
await writeFile7(
|
|
12070
|
+
await writeFile7(join25(distDir, "blume-redirects.json"), buildRedirectManifest(redirects), "utf-8");
|
|
11873
12071
|
const platformFiles = [
|
|
11874
12072
|
{ content: buildNetlifyRedirects(redirects), name: "_redirects" },
|
|
11875
12073
|
{ content: buildVercelConfig(redirects), name: "vercel.json" }
|
|
11876
12074
|
];
|
|
11877
|
-
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")));
|
|
11878
12076
|
logger.success(`Emitted redirect files for ${redirects.length} redirect(s)`);
|
|
11879
12077
|
};
|
|
11880
12078
|
var formatBytes = (bytes) => {
|
|
@@ -11885,14 +12083,14 @@ var formatBytes = (bytes) => {
|
|
|
11885
12083
|
return `${(bytes / 1024).toFixed(digits)} kB`;
|
|
11886
12084
|
};
|
|
11887
12085
|
var astroAssets = async (distDir, ext) => {
|
|
11888
|
-
const astroDir =
|
|
11889
|
-
if (!
|
|
12086
|
+
const astroDir = join25(distDir, "_astro");
|
|
12087
|
+
if (!existsSync16(astroDir)) {
|
|
11890
12088
|
return [];
|
|
11891
12089
|
}
|
|
11892
12090
|
const entries = await readdir(astroDir);
|
|
11893
12091
|
const files = entries.filter((name) => name.endsWith(`.${ext}`));
|
|
11894
12092
|
const sized = await Promise.all(files.map(async (name) => {
|
|
11895
|
-
const info = await stat(
|
|
12093
|
+
const info = await stat(join25(astroDir, name));
|
|
11896
12094
|
return { name, size: info.size };
|
|
11897
12095
|
}));
|
|
11898
12096
|
return sized.toSorted((a, b) => b.size - a.size);
|
|
@@ -11945,26 +12143,26 @@ var runClientAssetChecks = async (staticDir, args) => {
|
|
|
11945
12143
|
var isolatedOutputDir = (config, context) => {
|
|
11946
12144
|
const { adapter, output } = config.deployment;
|
|
11947
12145
|
if (output === "server" && adapter === "vercel") {
|
|
11948
|
-
return
|
|
12146
|
+
return join25(context.outDir, ".vercel", "output");
|
|
11949
12147
|
}
|
|
11950
|
-
return context.distDir ??
|
|
12148
|
+
return context.distDir ?? join25(context.outDir, "dist");
|
|
11951
12149
|
};
|
|
11952
12150
|
var isolatedStaticDir = (config, context) => {
|
|
11953
12151
|
const { adapter, output } = config.deployment;
|
|
11954
12152
|
const outputDir = isolatedOutputDir(config, context);
|
|
11955
12153
|
if (output === "server" && adapter === "vercel") {
|
|
11956
|
-
return
|
|
12154
|
+
return join25(outputDir, "static");
|
|
11957
12155
|
}
|
|
11958
12156
|
if (output === "server" && adapter === "node") {
|
|
11959
|
-
return
|
|
12157
|
+
return join25(outputDir, "client");
|
|
11960
12158
|
}
|
|
11961
12159
|
return outputDir;
|
|
11962
12160
|
};
|
|
11963
12161
|
var publishLlmsFiles = async (project, distDir) => {
|
|
11964
|
-
const indexPath =
|
|
11965
|
-
const fullPath =
|
|
11966
|
-
const writeIndex = !
|
|
11967
|
-
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);
|
|
11968
12166
|
if (!(writeIndex || writeFull)) {
|
|
11969
12167
|
return;
|
|
11970
12168
|
}
|
|
@@ -11997,18 +12195,18 @@ var publishBuildArtifacts = async (project, distDir, args) => {
|
|
|
11997
12195
|
await publishLlmsFiles(project, distDir);
|
|
11998
12196
|
}
|
|
11999
12197
|
const sitemap = buildSitemap(project);
|
|
12000
|
-
if (sitemap && !
|
|
12001
|
-
await writeFile7(
|
|
12198
|
+
if (sitemap && !existsSync16(join25(distDir, "sitemap.xml"))) {
|
|
12199
|
+
await writeFile7(join25(distDir, "sitemap.xml"), sitemap, "utf-8");
|
|
12002
12200
|
logger.success("Generated sitemap.xml");
|
|
12003
12201
|
}
|
|
12004
12202
|
const robots = buildRobots(project);
|
|
12005
|
-
if (robots && !
|
|
12006
|
-
await writeFile7(
|
|
12203
|
+
if (robots && !existsSync16(join25(distDir, "robots.txt"))) {
|
|
12204
|
+
await writeFile7(join25(distDir, "robots.txt"), robots, "utf-8");
|
|
12007
12205
|
logger.success("Generated robots.txt");
|
|
12008
12206
|
}
|
|
12009
12207
|
const agentReadability = buildAgentReadability(project);
|
|
12010
|
-
if (agentReadability && !
|
|
12011
|
-
await writeFile7(
|
|
12208
|
+
if (agentReadability && !existsSync16(join25(distDir, "agent-readability.json"))) {
|
|
12209
|
+
await writeFile7(join25(distDir, "agent-readability.json"), `${JSON.stringify(agentReadability, null, 2)}
|
|
12012
12210
|
`, "utf-8");
|
|
12013
12211
|
logger.success("Generated agent-readability.json");
|
|
12014
12212
|
}
|
|
@@ -12120,11 +12318,11 @@ var buildCommand = defineCommand2({
|
|
|
12120
12318
|
});
|
|
12121
12319
|
|
|
12122
12320
|
// src/cli/commands/check.ts
|
|
12123
|
-
import { existsSync as
|
|
12321
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
12124
12322
|
import { check } from "@astrojs/check";
|
|
12125
12323
|
import { sync } from "astro";
|
|
12126
12324
|
import { defineCommand as defineCommand3 } from "citty";
|
|
12127
|
-
import { join as
|
|
12325
|
+
import { join as join26 } from "pathe";
|
|
12128
12326
|
var checkCommand = defineCommand3({
|
|
12129
12327
|
args: {
|
|
12130
12328
|
isolated: {
|
|
@@ -12160,13 +12358,13 @@ var checkCommand = defineCommand3({
|
|
|
12160
12358
|
});
|
|
12161
12359
|
const { outDir } = project.context;
|
|
12162
12360
|
await sync({ logLevel: "warn", root: outDir });
|
|
12163
|
-
const tsconfig =
|
|
12361
|
+
const tsconfig = join26(root, "tsconfig.json");
|
|
12164
12362
|
logger.start(`Type-checking ${project.graph.pages.length} page(s)`);
|
|
12165
12363
|
const failed = await check({
|
|
12166
12364
|
minimumFailingSeverity: "error",
|
|
12167
12365
|
minimumSeverity: "hint",
|
|
12168
12366
|
root: outDir,
|
|
12169
|
-
tsconfig:
|
|
12367
|
+
tsconfig: existsSync17(tsconfig) ? tsconfig : undefined,
|
|
12170
12368
|
watch: false
|
|
12171
12369
|
});
|
|
12172
12370
|
if (failed) {
|
|
@@ -12386,14 +12584,14 @@ var devCommand = defineCommand4({
|
|
|
12386
12584
|
});
|
|
12387
12585
|
|
|
12388
12586
|
// src/cli/commands/doctor.ts
|
|
12389
|
-
import { readFileSync as
|
|
12587
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
12390
12588
|
import { defineCommand as defineCommand5 } from "citty";
|
|
12391
|
-
import { join as
|
|
12589
|
+
import { join as join27 } from "pathe";
|
|
12392
12590
|
var FALLBACK_MIN_NODE = "22.12.0";
|
|
12393
12591
|
var LEADING_RANGE = /^[^\d]*/u;
|
|
12394
12592
|
var minSupportedNode = () => {
|
|
12395
12593
|
try {
|
|
12396
|
-
const pkg = JSON.parse(
|
|
12594
|
+
const pkg = JSON.parse(readFileSync11(join27(packageRoot(), "package.json"), "utf-8"));
|
|
12397
12595
|
const range = pkg.engines?.node ?? "";
|
|
12398
12596
|
return range.replace(LEADING_RANGE, "") || FALLBACK_MIN_NODE;
|
|
12399
12597
|
} catch {
|
|
@@ -12489,17 +12687,17 @@ import { defineCommand as defineCommand6 } from "citty";
|
|
|
12489
12687
|
import { relative as relative14 } from "pathe";
|
|
12490
12688
|
|
|
12491
12689
|
// src/registry/eject.ts
|
|
12492
|
-
import { existsSync as
|
|
12690
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
12493
12691
|
import { cp as cp2, mkdir as mkdir7, readFile as readFile12, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
|
|
12494
|
-
import { join as
|
|
12692
|
+
import { join as join28, relative as relative12 } from "pathe";
|
|
12495
12693
|
var toPosix = (path) => path.split("\\").join("/");
|
|
12496
12694
|
var LOCAL_BLUME_SOURCE = "../../node_modules/blume/src/**/*.{astro,ts,tsx}";
|
|
12497
12695
|
var blumeSourceGlob = (root, genDir, resolveBlumeRoot = packageRoot) => {
|
|
12498
|
-
if (
|
|
12696
|
+
if (existsSync18(join28(root, "node_modules", "blume"))) {
|
|
12499
12697
|
return LOCAL_BLUME_SOURCE;
|
|
12500
12698
|
}
|
|
12501
12699
|
try {
|
|
12502
|
-
const src =
|
|
12700
|
+
const src = join28(resolveBlumeRoot(), "src");
|
|
12503
12701
|
return `${toPosix(relative12(genDir, src))}/**/*.{astro,ts,tsx}`;
|
|
12504
12702
|
} catch {
|
|
12505
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.');
|
|
@@ -12519,19 +12717,19 @@ var askFiles = async (project, srcDir, genDir) => {
|
|
|
12519
12717
|
const files = [
|
|
12520
12718
|
{
|
|
12521
12719
|
content: askEndpointTemplate(resolveAskBackend(ask), grounded),
|
|
12522
|
-
path:
|
|
12720
|
+
path: join28(srcDir, "pages", "api", "ask.ts")
|
|
12523
12721
|
}
|
|
12524
12722
|
];
|
|
12525
12723
|
if (grounded) {
|
|
12526
12724
|
files.push({
|
|
12527
12725
|
content: `${JSON.stringify(await buildAskData(project))}
|
|
12528
12726
|
`,
|
|
12529
|
-
path:
|
|
12727
|
+
path: join28(genDir, "ask-data.json")
|
|
12530
12728
|
});
|
|
12531
12729
|
}
|
|
12532
12730
|
return files;
|
|
12533
12731
|
};
|
|
12534
|
-
var hostsMcp = (project, userPages) => project.config.mcp.enabled && !routeIsTaken(userPages, project.graph.pages, project.config.mcp.route);
|
|
12732
|
+
var hostsMcp = (project, userPages) => project.config.ai.mcp.enabled && !routeIsTaken(userPages, project.graph.pages, project.config.ai.mcp.route);
|
|
12535
12733
|
var mcpDiscoveryPages = (project, userPages) => hostsMcp(project, userPages) ? [
|
|
12536
12734
|
{
|
|
12537
12735
|
entrypoint: "src/blume-mcp/discovery.ts",
|
|
@@ -12546,7 +12744,7 @@ var mcpFiles = async (project, userPages, srcDir, genDir) => {
|
|
|
12546
12744
|
if (!hostsMcp(project, userPages)) {
|
|
12547
12745
|
return [];
|
|
12548
12746
|
}
|
|
12549
|
-
const { route } = project.config.mcp;
|
|
12747
|
+
const { route } = project.config.ai.mcp;
|
|
12550
12748
|
const data = await buildMcpData(project);
|
|
12551
12749
|
const discoveryInput = {
|
|
12552
12750
|
base: data.base,
|
|
@@ -12559,19 +12757,19 @@ var mcpFiles = async (project, userPages, srcDir, genDir) => {
|
|
|
12559
12757
|
{
|
|
12560
12758
|
content: `${JSON.stringify(data)}
|
|
12561
12759
|
`,
|
|
12562
|
-
path:
|
|
12760
|
+
path: join28(genDir, "mcp-data.json")
|
|
12563
12761
|
},
|
|
12564
12762
|
{
|
|
12565
12763
|
content: mcpEndpointTemplate(route),
|
|
12566
|
-
path:
|
|
12764
|
+
path: join28(srcDir, "pages", mcpPageFile(route))
|
|
12567
12765
|
},
|
|
12568
12766
|
{
|
|
12569
12767
|
content: staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput)),
|
|
12570
|
-
path:
|
|
12768
|
+
path: join28(srcDir, "blume-mcp", "discovery.ts")
|
|
12571
12769
|
},
|
|
12572
12770
|
{
|
|
12573
12771
|
content: staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)),
|
|
12574
|
-
path:
|
|
12772
|
+
path: join28(srcDir, "blume-mcp", "server-card.ts")
|
|
12575
12773
|
}
|
|
12576
12774
|
];
|
|
12577
12775
|
};
|
|
@@ -12584,22 +12782,22 @@ var changelogFiles = (project, userPages, srcDir, options) => {
|
|
|
12584
12782
|
return [
|
|
12585
12783
|
{
|
|
12586
12784
|
content: changelogIndexTemplate(options),
|
|
12587
|
-
path:
|
|
12785
|
+
path: join28(srcDir, "pages", "changelog.astro")
|
|
12588
12786
|
}
|
|
12589
12787
|
];
|
|
12590
12788
|
};
|
|
12591
|
-
var readExamplesCss = (root, css) => css &&
|
|
12789
|
+
var readExamplesCss = (root, css) => css && existsSync18(join28(root, css)) ? readFile12(join28(root, css), "utf-8") : Promise.resolve("");
|
|
12592
12790
|
var examplesPreviewFiles = (srcDir, basePath, hasExamples) => hasExamples ? [
|
|
12593
12791
|
{
|
|
12594
12792
|
content: examplesPageTemplate(),
|
|
12595
|
-
path:
|
|
12793
|
+
path: join28(srcDir, "pages", ...basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro")
|
|
12596
12794
|
}
|
|
12597
12795
|
] : [];
|
|
12598
12796
|
var eject = async (root) => {
|
|
12599
12797
|
const project = await scanProject(root, { mode: "build" });
|
|
12600
12798
|
const { context, config } = project;
|
|
12601
|
-
const srcDir =
|
|
12602
|
-
const genDir =
|
|
12799
|
+
const srcDir = join28(root, "src");
|
|
12800
|
+
const genDir = join28(srcDir, "generated");
|
|
12603
12801
|
const askEnabled = config.ai.ask?.enabled ?? false;
|
|
12604
12802
|
const exportPdf = config.export.pdf;
|
|
12605
12803
|
const exportEpub = config.export.epub;
|
|
@@ -12649,6 +12847,7 @@ var eject = async (root) => {
|
|
|
12649
12847
|
const files = [
|
|
12650
12848
|
{
|
|
12651
12849
|
content: astroConfigTemplate({
|
|
12850
|
+
askPath: "./src/generated/Ask.astro",
|
|
12652
12851
|
config,
|
|
12653
12852
|
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
12654
12853
|
context: relContext,
|
|
@@ -12663,14 +12862,14 @@ var eject = async (root) => {
|
|
|
12663
12862
|
searchClientPath: "./src/generated/search-client.ts",
|
|
12664
12863
|
themePath: "./src/generated/app.css"
|
|
12665
12864
|
}),
|
|
12666
|
-
path:
|
|
12865
|
+
path: join28(root, "astro.config.mjs")
|
|
12667
12866
|
},
|
|
12668
12867
|
{
|
|
12669
12868
|
content: runtimeTsconfigTemplate(),
|
|
12670
|
-
path:
|
|
12869
|
+
path: join28(root, "tsconfig.json"),
|
|
12671
12870
|
skipIfExists: true
|
|
12672
12871
|
},
|
|
12673
|
-
{ content: envTemplate(), path:
|
|
12872
|
+
{ content: envTemplate(), path: join28(srcDir, "env.d.ts") },
|
|
12674
12873
|
{
|
|
12675
12874
|
content: contentConfigTemplate({
|
|
12676
12875
|
config,
|
|
@@ -12678,29 +12877,28 @@ var eject = async (root) => {
|
|
|
12678
12877
|
staged: hasStaged,
|
|
12679
12878
|
stagedBase: stagedDir
|
|
12680
12879
|
}),
|
|
12681
|
-
path:
|
|
12880
|
+
path: join28(srcDir, "content.config.ts")
|
|
12682
12881
|
},
|
|
12683
12882
|
{
|
|
12684
12883
|
content: catchAllPageTemplate({
|
|
12685
|
-
askEnabled,
|
|
12686
12884
|
exportEpub,
|
|
12687
12885
|
exportPdf,
|
|
12688
12886
|
mathEnabled: usesMath,
|
|
12689
12887
|
needsReact
|
|
12690
12888
|
}),
|
|
12691
|
-
path:
|
|
12889
|
+
path: join28(srcDir, "pages", "[...slug].astro")
|
|
12692
12890
|
},
|
|
12693
12891
|
{
|
|
12694
12892
|
content: planComponentSlots(componentsImport, null).module,
|
|
12695
|
-
path:
|
|
12893
|
+
path: join28(genDir, "components.ts")
|
|
12696
12894
|
},
|
|
12697
12895
|
{
|
|
12698
12896
|
content: islandMapTemplate(islands.islands),
|
|
12699
|
-
path:
|
|
12897
|
+
path: join28(genDir, "islands.ts")
|
|
12700
12898
|
},
|
|
12701
12899
|
{
|
|
12702
12900
|
content: exampleMapTemplate(examples.examples, config.basePath),
|
|
12703
|
-
path:
|
|
12901
|
+
path: join28(genDir, "examples.ts")
|
|
12704
12902
|
},
|
|
12705
12903
|
{
|
|
12706
12904
|
content: examplesEntryTemplate({
|
|
@@ -12708,7 +12906,7 @@ var eject = async (root) => {
|
|
|
12708
12906
|
sources: ["../../**/*.{astro,jsx,svelte,ts,tsx,vue}"],
|
|
12709
12907
|
userCss: userExamplesCss
|
|
12710
12908
|
}),
|
|
12711
|
-
path:
|
|
12909
|
+
path: join28(genDir, "examples.css")
|
|
12712
12910
|
},
|
|
12713
12911
|
{
|
|
12714
12912
|
content: tailwindEntryTemplate({
|
|
@@ -12720,26 +12918,30 @@ var eject = async (root) => {
|
|
|
12720
12918
|
twoslashCss: twoslashCss(),
|
|
12721
12919
|
userTheme
|
|
12722
12920
|
}),
|
|
12723
|
-
path:
|
|
12921
|
+
path: join28(genDir, "app.css")
|
|
12922
|
+
},
|
|
12923
|
+
{ content: buildRuntimeData(project), path: join28(genDir, "data.json") },
|
|
12924
|
+
{
|
|
12925
|
+
content: askComponentTemplate(askEnabled),
|
|
12926
|
+
path: join28(genDir, "Ask.astro")
|
|
12724
12927
|
},
|
|
12725
|
-
{ content: buildRuntimeData(project), path: join27(genDir, "data.json") },
|
|
12726
12928
|
{
|
|
12727
12929
|
content: `${JSON.stringify(ejectOpenApiData(project))}
|
|
12728
12930
|
`,
|
|
12729
|
-
path:
|
|
12931
|
+
path: join28(genDir, "openapi.json")
|
|
12730
12932
|
},
|
|
12731
12933
|
{
|
|
12732
12934
|
content: `${JSON.stringify(rawMarkdown)}
|
|
12733
12935
|
`,
|
|
12734
|
-
path:
|
|
12936
|
+
path: join28(genDir, "raw-markdown.json")
|
|
12735
12937
|
},
|
|
12736
12938
|
{
|
|
12737
12939
|
content: rawMarkdownEndpointTemplate("md"),
|
|
12738
|
-
path:
|
|
12940
|
+
path: join28(srcDir, "pages", "[...slug].md.ts")
|
|
12739
12941
|
},
|
|
12740
12942
|
{
|
|
12741
12943
|
content: rawMarkdownEndpointTemplate("mdx"),
|
|
12742
|
-
path:
|
|
12944
|
+
path: join28(srcDir, "pages", "[...slug].mdx.ts")
|
|
12743
12945
|
}
|
|
12744
12946
|
];
|
|
12745
12947
|
if (askEnabled) {
|
|
@@ -12748,11 +12950,10 @@ var eject = async (root) => {
|
|
|
12748
12950
|
if (config.seo.og.enabled) {
|
|
12749
12951
|
files.push({
|
|
12750
12952
|
content: ogEndpointTemplate(customOgRoutes(pages, config.title)),
|
|
12751
|
-
path:
|
|
12953
|
+
path: join28(srcDir, "pages", "og", "[...slug].png.ts")
|
|
12752
12954
|
});
|
|
12753
12955
|
}
|
|
12754
12956
|
files.push(...await mcpFiles(project, pages, srcDir, genDir), ...changelogFiles(project, pages, srcDir, {
|
|
12755
|
-
askEnabled,
|
|
12756
12957
|
exportEpub,
|
|
12757
12958
|
exportPdf,
|
|
12758
12959
|
needsReact,
|
|
@@ -12761,28 +12962,28 @@ var eject = async (root) => {
|
|
|
12761
12962
|
if (!routeIsTaken(pages, project.graph.pages, "/404")) {
|
|
12762
12963
|
files.push({
|
|
12763
12964
|
content: notFoundPageTemplate(),
|
|
12764
|
-
path:
|
|
12965
|
+
path: join28(srcDir, "pages", "404.astro")
|
|
12765
12966
|
});
|
|
12766
12967
|
}
|
|
12767
12968
|
files.push({
|
|
12768
12969
|
content: searchClientTemplate(config),
|
|
12769
|
-
path:
|
|
12970
|
+
path: join28(genDir, "search-client.ts")
|
|
12770
12971
|
});
|
|
12771
12972
|
if (servesStaticIndex(config.search.provider)) {
|
|
12772
12973
|
const documents = await buildSearchDocuments(project);
|
|
12773
12974
|
files.push({
|
|
12774
12975
|
content: `${JSON.stringify(documents)}
|
|
12775
12976
|
`,
|
|
12776
|
-
path:
|
|
12977
|
+
path: join28(genDir, "search.json")
|
|
12777
12978
|
}, {
|
|
12778
12979
|
content: searchEndpointTemplate(),
|
|
12779
|
-
path:
|
|
12980
|
+
path: join28(srcDir, "pages", "blume-search.json.ts")
|
|
12780
12981
|
});
|
|
12781
12982
|
}
|
|
12782
12983
|
if (config.search.provider === "mixedbread") {
|
|
12783
12984
|
files.push({
|
|
12784
12985
|
content: mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""),
|
|
12785
|
-
path:
|
|
12986
|
+
path: join28(srcDir, "pages", "api", "search.ts")
|
|
12786
12987
|
});
|
|
12787
12988
|
}
|
|
12788
12989
|
const feeds = buildRssFeeds(project);
|
|
@@ -12791,10 +12992,10 @@ var eject = async (root) => {
|
|
|
12791
12992
|
files.push({
|
|
12792
12993
|
content: `${JSON.stringify(feedXml)}
|
|
12793
12994
|
`,
|
|
12794
|
-
path:
|
|
12995
|
+
path: join28(genDir, "rss.json")
|
|
12795
12996
|
}, {
|
|
12796
12997
|
content: rssEndpointTemplate(),
|
|
12797
|
-
path:
|
|
12998
|
+
path: join28(srcDir, "pages", "[section]", "rss.xml.ts")
|
|
12798
12999
|
});
|
|
12799
13000
|
}
|
|
12800
13001
|
const warnings = [];
|
|
@@ -12808,28 +13009,28 @@ var eject = async (root) => {
|
|
|
12808
13009
|
for (const file of references.files) {
|
|
12809
13010
|
files.push({
|
|
12810
13011
|
content: file.content,
|
|
12811
|
-
path:
|
|
13012
|
+
path: join28(srcDir, "pages", file.pagePath)
|
|
12812
13013
|
});
|
|
12813
13014
|
}
|
|
12814
13015
|
}
|
|
12815
13016
|
files.push(...islands.islands.map((island) => ({
|
|
12816
13017
|
content: islandWrapperTemplate(island),
|
|
12817
|
-
path:
|
|
13018
|
+
path: join28(genDir, "islands", `${island.name}.astro`)
|
|
12818
13019
|
})), ...examples.examples.map((example) => ({
|
|
12819
13020
|
content: exampleWrapperTemplate(example),
|
|
12820
|
-
path:
|
|
13021
|
+
path: join28(genDir, "examples", `${exampleSlug(example.path)}.astro`)
|
|
12821
13022
|
})), ...examplesPreviewFiles(srcDir, config.basePath, examples.examples.length > 0));
|
|
12822
13023
|
for (const [entryId, content] of staged) {
|
|
12823
|
-
files.push({ content, path:
|
|
13024
|
+
files.push({ content, path: join28(root, stagedDir, entryId) });
|
|
12824
13025
|
}
|
|
12825
|
-
const written = files.filter((file) => !(file.skipIfExists &&
|
|
13026
|
+
const written = files.filter((file) => !(file.skipIfExists && existsSync18(file.path)));
|
|
12826
13027
|
await Promise.all(written.map(async (file) => {
|
|
12827
|
-
await mkdir7(
|
|
13028
|
+
await mkdir7(join28(file.path, ".."), { recursive: true });
|
|
12828
13029
|
await writeFile8(file.path, file.content, "utf-8");
|
|
12829
13030
|
}));
|
|
12830
|
-
const assetsSrc =
|
|
12831
|
-
if (
|
|
12832
|
-
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"), {
|
|
12833
13034
|
recursive: true
|
|
12834
13035
|
});
|
|
12835
13036
|
}
|
|
@@ -12839,7 +13040,7 @@ var eject = async (root) => {
|
|
|
12839
13040
|
|
|
12840
13041
|
// src/cli/eject-scripts.ts
|
|
12841
13042
|
import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
|
|
12842
|
-
import { join as
|
|
13043
|
+
import { join as join29 } from "pathe";
|
|
12843
13044
|
var droppedArtifactNotices = (config) => {
|
|
12844
13045
|
const notices = [];
|
|
12845
13046
|
if (config.search.provider === "pagefind") {
|
|
@@ -12866,7 +13067,7 @@ var droppedArtifactNotices = (config) => {
|
|
|
12866
13067
|
return notices;
|
|
12867
13068
|
};
|
|
12868
13069
|
var updatePackageScripts = async (root) => {
|
|
12869
|
-
const pkgPath =
|
|
13070
|
+
const pkgPath = join29(root, "package.json");
|
|
12870
13071
|
let pkg;
|
|
12871
13072
|
try {
|
|
12872
13073
|
pkg = JSON.parse(await readFile13(pkgPath, "utf-8"));
|
|
@@ -12885,9 +13086,9 @@ var updatePackageScripts = async (root) => {
|
|
|
12885
13086
|
};
|
|
12886
13087
|
|
|
12887
13088
|
// src/cli/init/scaffold.ts
|
|
12888
|
-
import { existsSync as
|
|
13089
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
12889
13090
|
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
12890
|
-
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";
|
|
12891
13092
|
|
|
12892
13093
|
// src/core/package-json.ts
|
|
12893
13094
|
var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
|
|
@@ -12946,7 +13147,7 @@ var STARTERS = {
|
|
|
12946
13147
|
files: (dir) => [
|
|
12947
13148
|
{
|
|
12948
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`."),
|
|
12949
|
-
path:
|
|
13150
|
+
path: join30(dir, "index.mdx")
|
|
12950
13151
|
}
|
|
12951
13152
|
]
|
|
12952
13153
|
},
|
|
@@ -12961,7 +13162,7 @@ var STARTERS = {
|
|
|
12961
13162
|
files: (dir) => [
|
|
12962
13163
|
{
|
|
12963
13164
|
content: page("Introduction", "Welcome to your new Blume docs.", "# Introduction\n\nWrite your docs here, and log releases under `changelog/`."),
|
|
12964
|
-
path:
|
|
13165
|
+
path: join30(dir, "index.mdx")
|
|
12965
13166
|
},
|
|
12966
13167
|
{
|
|
12967
13168
|
content: `---
|
|
@@ -12972,7 +13173,7 @@ date: 2026-01-01
|
|
|
12972
13173
|
|
|
12973
13174
|
The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries beside it.
|
|
12974
13175
|
`,
|
|
12975
|
-
path:
|
|
13176
|
+
path: join30(dir, "changelog", "v1-0-0.mdx")
|
|
12976
13177
|
}
|
|
12977
13178
|
]
|
|
12978
13179
|
},
|
|
@@ -12985,7 +13186,7 @@ The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries besid
|
|
|
12985
13186
|
Welcome to **Blume** — markdown-first docs powered by Astro and Vite.
|
|
12986
13187
|
|
|
12987
13188
|
Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
|
|
12988
|
-
path:
|
|
13189
|
+
path: join30(dir, "index.mdx")
|
|
12989
13190
|
}
|
|
12990
13191
|
]
|
|
12991
13192
|
},
|
|
@@ -12996,11 +13197,11 @@ Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
|
|
|
12996
13197
|
content: page("Introduction", "Get started with the SDK.", `# Introduction
|
|
12997
13198
|
|
|
12998
13199
|
Install the SDK and make your first call. See [Installation](/installation).`),
|
|
12999
|
-
path:
|
|
13200
|
+
path: join30(dir, "index.mdx")
|
|
13000
13201
|
},
|
|
13001
13202
|
{
|
|
13002
13203
|
content: page("Installation", "Install the SDK.", "# Installation\n\n```package-install\nyour-sdk\n```"),
|
|
13003
|
-
path:
|
|
13204
|
+
path: join30(dir, "installation.mdx")
|
|
13004
13205
|
}
|
|
13005
13206
|
]
|
|
13006
13207
|
}
|
|
@@ -13015,7 +13216,7 @@ var detectPackageManager = (userAgent) => {
|
|
|
13015
13216
|
const name = userAgent?.split("/")[0];
|
|
13016
13217
|
return name !== undefined && PACKAGE_MANAGERS.includes(name) ? name : "npm";
|
|
13017
13218
|
};
|
|
13018
|
-
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;
|
|
13019
13220
|
var titleize = (raw) => {
|
|
13020
13221
|
const words = raw.replaceAll(/[-_.]+/gu, " ").split(/\s+/u).filter(Boolean);
|
|
13021
13222
|
return words.length === 0 ? "My Docs" : words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
@@ -13098,17 +13299,17 @@ var buildPlan = (root, answers) => {
|
|
|
13098
13299
|
const files = [
|
|
13099
13300
|
{
|
|
13100
13301
|
content: blumePackageJson(toPackageName(basename4(root)), extraDepsFor(answers.sources)),
|
|
13101
|
-
path:
|
|
13302
|
+
path: join30(root, "package.json")
|
|
13102
13303
|
},
|
|
13103
|
-
{ content: buildConfig(answers), path:
|
|
13304
|
+
{ content: buildConfig(answers), path: join30(root, "blume.config.ts") }
|
|
13104
13305
|
];
|
|
13105
13306
|
if (answers.sources.length === 0 || answers.sources.includes("filesystem")) {
|
|
13106
|
-
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) })));
|
|
13107
13308
|
}
|
|
13108
13309
|
return files;
|
|
13109
13310
|
};
|
|
13110
13311
|
var writeFileSafe = async (file, log) => {
|
|
13111
|
-
if (
|
|
13312
|
+
if (existsSync19(file.path)) {
|
|
13112
13313
|
log.info(`Skipped existing ${file.path}`);
|
|
13113
13314
|
return false;
|
|
13114
13315
|
}
|
|
@@ -13415,10 +13616,10 @@ var initCommand = defineCommand7({
|
|
|
13415
13616
|
});
|
|
13416
13617
|
|
|
13417
13618
|
// src/cli/commands/preview.ts
|
|
13418
|
-
import { existsSync as
|
|
13619
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
13419
13620
|
import { preview } from "astro";
|
|
13420
13621
|
import { defineCommand as defineCommand8 } from "citty";
|
|
13421
|
-
import { join as
|
|
13622
|
+
import { join as join31 } from "pathe";
|
|
13422
13623
|
var previewCommand = defineCommand8({
|
|
13423
13624
|
args: {
|
|
13424
13625
|
host: { description: "Network host to bind.", type: "string" },
|
|
@@ -13432,7 +13633,7 @@ var previewCommand = defineCommand8({
|
|
|
13432
13633
|
const root = process.cwd();
|
|
13433
13634
|
const { config } = await loadConfig(root);
|
|
13434
13635
|
const context = resolveProjectContext(root, config);
|
|
13435
|
-
if (!
|
|
13636
|
+
if (!existsSync20(join31(context.outDir, "astro.config.mjs"))) {
|
|
13436
13637
|
logger.error("No build found. Run `blume build` first.");
|
|
13437
13638
|
process.exit(1);
|
|
13438
13639
|
}
|
|
@@ -13450,7 +13651,7 @@ var previewCommand = defineCommand8({
|
|
|
13450
13651
|
// src/cli/commands/sync.ts
|
|
13451
13652
|
import { rm as rm4 } from "node:fs/promises";
|
|
13452
13653
|
import { defineCommand as defineCommand9 } from "citty";
|
|
13453
|
-
import { join as
|
|
13654
|
+
import { join as join32 } from "pathe";
|
|
13454
13655
|
var syncCommand = defineCommand9({
|
|
13455
13656
|
args: {
|
|
13456
13657
|
force: {
|
|
@@ -13472,7 +13673,7 @@ var syncCommand = defineCommand9({
|
|
|
13472
13673
|
if (args.force) {
|
|
13473
13674
|
const { config } = await loadConfig(root);
|
|
13474
13675
|
const context = resolveProjectContext(root, config);
|
|
13475
|
-
await rm4(
|
|
13676
|
+
await rm4(join32(context.outDir, "cache"), { force: true, recursive: true });
|
|
13476
13677
|
logger.info("Cleared source cache.");
|
|
13477
13678
|
}
|
|
13478
13679
|
const lock = readDevLock(resolveRuntimeDir(root));
|
|
@@ -13490,13 +13691,13 @@ var syncCommand = defineCommand9({
|
|
|
13490
13691
|
});
|
|
13491
13692
|
|
|
13492
13693
|
// src/cli/commands/validate.ts
|
|
13493
|
-
import { existsSync as
|
|
13694
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
13494
13695
|
import { defineCommand as defineCommand10 } from "citty";
|
|
13495
|
-
import { join as
|
|
13696
|
+
import { join as join34 } from "pathe";
|
|
13496
13697
|
|
|
13497
13698
|
// src/core/links.ts
|
|
13498
|
-
import { existsSync as
|
|
13499
|
-
import { basename as basename6, join as
|
|
13699
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
13700
|
+
import { basename as basename6, join as join33 } from "pathe";
|
|
13500
13701
|
var HTTP = /^https?:\/\//iu;
|
|
13501
13702
|
var PROTOCOL_RELATIVE = /^\/\//u;
|
|
13502
13703
|
var SCHEME = /^[a-z][a-z0-9+.-]*:/iu;
|
|
@@ -13515,7 +13716,7 @@ var STATUS_NOT_FOUND = 404;
|
|
|
13515
13716
|
var STATUS_GONE = 410;
|
|
13516
13717
|
var STATUS_METHOD_NOT_ALLOWED = 405;
|
|
13517
13718
|
var STATUS_NOT_IMPLEMENTED = 501;
|
|
13518
|
-
var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null &&
|
|
13719
|
+
var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null && existsSync21(join33(ctx.publicDir, resolved));
|
|
13519
13720
|
var NUMERIC_PREFIX3 = /^\d+[-_.]/u;
|
|
13520
13721
|
var isIndexPage = (page2) => /^index\.(?:md|mdx)$/iu.test(basename6(page2.navPath).replace(NUMERIC_PREFIX3, ""));
|
|
13521
13722
|
var applyRelativePart = (segments, part) => {
|
|
@@ -13781,12 +13982,12 @@ var validateCommand = defineCommand10({
|
|
|
13781
13982
|
});
|
|
13782
13983
|
extraRoutes.push(...manifest.routes.flatMap((route) => route.fallback ? [route.path] : []));
|
|
13783
13984
|
}
|
|
13784
|
-
const publicDir =
|
|
13985
|
+
const publicDir = join34(root, "public");
|
|
13785
13986
|
diagnostics.push(...await validateLinks(project.graph, {
|
|
13786
13987
|
basePath: project.config.basePath,
|
|
13787
13988
|
checkExternal: Boolean(args.external),
|
|
13788
13989
|
extraRoutes,
|
|
13789
|
-
publicDir:
|
|
13990
|
+
publicDir: existsSync22(publicDir) ? publicDir : null,
|
|
13790
13991
|
redirects: project.config.redirects
|
|
13791
13992
|
}));
|
|
13792
13993
|
} catch (error) {
|
|
@@ -13847,5 +14048,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
13847
14048
|
});
|
|
13848
14049
|
runMain(main);
|
|
13849
14050
|
|
|
13850
|
-
//# debugId=
|
|
14051
|
+
//# debugId=E383A1CFB1E8864864756E2164756E21
|
|
13851
14052
|
//# sourceMappingURL=index.js.map
|