blume 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1137 -722
- package/dist/cli/index.js.map +28 -23
- package/dist/types/core/data.d.ts +2 -0
- package/dist/types/core/project.d.ts +12 -2
- package/dist/types/core/schema.d.ts +154 -15
- package/dist/types/core/types.d.ts +7 -0
- package/docs/advanced/api-reference.mdx +33 -23
- package/docs/advanced/bridge.mdx +74 -0
- package/docs/advanced/meta.ts +8 -1
- package/docs/advanced/migrate.mdx +119 -0
- package/docs/configuration/index.mdx +1 -1
- package/docs/content/components.mdx +55 -2
- package/docs/content/i18n.mdx +1 -1
- package/docs/content/syntax.mdx +2 -2
- package/docs/index.mdx +2 -2
- package/docs/reference/cli.mdx +29 -1
- package/docs/reference/frontmatter.mdx +5 -0
- package/package.json +11 -1
- package/src/astro/generate.ts +18 -8
- package/src/astro/templates.ts +28 -4
- package/src/cli/commands/build.ts +107 -63
- package/src/cli/commands/check.ts +20 -0
- package/src/cli/dev-lock.ts +13 -5
- package/src/cli/prepare.ts +3 -0
- package/src/components/BlumePage.astro +6 -0
- package/src/components/Icon.astro +13 -10
- package/src/components/content/ApiField.astro +75 -0
- package/src/components/content/ParamField.astro +39 -0
- package/src/components/content/RequestField.astro +23 -0
- package/src/components/content/ResponseField.astro +23 -0
- package/src/components/content/Step.astro +1 -1
- package/src/components/layout/Breadcrumbs.astro +7 -2
- package/src/components/layout/NavTree.astro +24 -8
- package/src/components/layout/RootLayout.astro +56 -34
- package/src/components/layout/Search.astro +1 -1
- package/src/components/openapi/ApiOverview.astro +84 -0
- package/src/components/openapi/MethodBadge.astro +28 -0
- package/src/components/openapi/Operation.astro +140 -0
- package/src/components/openapi/ParametersTable.astro +97 -0
- package/src/components/openapi/RequestBody.astro +58 -0
- package/src/components/openapi/RequestPanel.astro +169 -0
- package/src/components/openapi/Responses.astro +91 -0
- package/src/components/openapi/SchemaProperty.astro +118 -0
- package/src/components/openapi/SchemaTable.astro +86 -0
- package/src/components/openapi/helpers.ts +238 -0
- package/src/components/openapi/panel.ts +59 -0
- package/src/components/openapi/snippets.ts +201 -0
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/data.ts +2 -0
- package/src/core/project-graph.ts +5 -1
- package/src/core/project.ts +25 -3
- package/src/core/schema.ts +47 -6
- package/src/core/sources/mintlify.ts +1 -1
- package/src/core/sources/resolve.ts +28 -6
- package/src/core/types.ts +7 -0
- package/src/migrate/mintlify/config.ts +153 -1
- package/src/migrate/mintlify/content.ts +8 -2
- package/src/migrate/mintlify/index.ts +58 -1
- package/src/openapi/model.ts +174 -0
- package/src/openapi/parse.ts +48 -0
- package/src/openapi/references.ts +164 -0
- package/src/openapi/render-mdx.ts +76 -0
- package/src/openapi/scalar.ts +15 -103
- package/src/openapi/source.ts +140 -0
- package/src/registry/eject.ts +15 -2
- package/src/theme/chrome-icons.ts +22 -0
- package/src/theme/icons.ts +151 -161
package/dist/cli/index.js
CHANGED
|
@@ -513,11 +513,11 @@ Next steps:
|
|
|
513
513
|
});
|
|
514
514
|
|
|
515
515
|
// src/cli/commands/build.ts
|
|
516
|
-
import { existsSync as
|
|
517
|
-
import { readdir, stat, writeFile as
|
|
516
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
517
|
+
import { readdir, stat, writeFile as writeFile7 } from "node:fs/promises";
|
|
518
518
|
import { build } from "astro";
|
|
519
519
|
import { defineCommand as defineCommand2 } from "citty";
|
|
520
|
-
import { join as
|
|
520
|
+
import { join as join28 } from "pathe";
|
|
521
521
|
|
|
522
522
|
// src/core/frontmatter.ts
|
|
523
523
|
import baseMatter from "gray-matter";
|
|
@@ -608,6 +608,29 @@ var buildLlmsFiles = async (project) => ({
|
|
|
608
608
|
index: buildIndex(project)
|
|
609
609
|
});
|
|
610
610
|
|
|
611
|
+
// src/core/gitignore.ts
|
|
612
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
613
|
+
import { readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
614
|
+
import { join as join5 } from "pathe";
|
|
615
|
+
var gitignoreKey = (line) => line.trim().replace(/\/+$/u, "");
|
|
616
|
+
var ensureGitignore = async (root, entries) => {
|
|
617
|
+
const path = join5(root, ".gitignore");
|
|
618
|
+
const existing = existsSync3(path) ? await readFile3(path, "utf-8") : "";
|
|
619
|
+
const present = new Set(existing.split(`
|
|
620
|
+
`).map(gitignoreKey).filter(Boolean));
|
|
621
|
+
const added = entries.filter((entry) => !present.has(gitignoreKey(entry)));
|
|
622
|
+
if (added.length === 0) {
|
|
623
|
+
return [];
|
|
624
|
+
}
|
|
625
|
+
const gap = existing.length > 0 && !existing.endsWith(`
|
|
626
|
+
`) ? `
|
|
627
|
+
` : "";
|
|
628
|
+
await writeFile2(path, `${existing}${gap}${added.join(`
|
|
629
|
+
`)}
|
|
630
|
+
`, "utf-8");
|
|
631
|
+
return added;
|
|
632
|
+
};
|
|
633
|
+
|
|
611
634
|
// src/search/providers.ts
|
|
612
635
|
var SEARCH_PROVIDERS = {
|
|
613
636
|
algolia: {
|
|
@@ -739,7 +762,7 @@ ${urls.join(`
|
|
|
739
762
|
};
|
|
740
763
|
|
|
741
764
|
// src/search/build.ts
|
|
742
|
-
import { join as
|
|
765
|
+
import { join as join6 } from "pathe";
|
|
743
766
|
var buildSearchIndex = async (outDir) => {
|
|
744
767
|
const pagefind = await import("pagefind");
|
|
745
768
|
const { index } = await pagefind.createIndex({});
|
|
@@ -747,7 +770,7 @@ var buildSearchIndex = async (outDir) => {
|
|
|
747
770
|
throw new Error("Failed to create Pagefind index.");
|
|
748
771
|
}
|
|
749
772
|
const result = await index.addDirectory({ path: outDir });
|
|
750
|
-
await index.writeFiles({ outputPath:
|
|
773
|
+
await index.writeFiles({ outputPath: join6(outDir, "pagefind") });
|
|
751
774
|
await pagefind.close();
|
|
752
775
|
return result.page_count;
|
|
753
776
|
};
|
|
@@ -2791,17 +2814,59 @@ var syncSearchProvider = async (project, reporter) => {
|
|
|
2791
2814
|
|
|
2792
2815
|
// src/cli/dev-lock.ts
|
|
2793
2816
|
import {
|
|
2794
|
-
existsSync as
|
|
2817
|
+
existsSync as existsSync5,
|
|
2795
2818
|
mkdirSync,
|
|
2796
2819
|
readFileSync as readFileSync2,
|
|
2797
2820
|
rmSync,
|
|
2798
2821
|
writeFileSync
|
|
2799
2822
|
} from "node:fs";
|
|
2800
|
-
import { join as
|
|
2801
|
-
|
|
2823
|
+
import { join as join8 } from "pathe";
|
|
2824
|
+
|
|
2825
|
+
// src/core/project.ts
|
|
2826
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
2827
|
+
import { isAbsolute, join as join7, resolve as resolve2 } from "pathe";
|
|
2828
|
+
var CONFIG_FILENAMES = [
|
|
2829
|
+
"blume.config.ts",
|
|
2830
|
+
"blume.config.mjs",
|
|
2831
|
+
"blume.config.js"
|
|
2832
|
+
];
|
|
2833
|
+
var THEME_FILENAMES = ["theme.css"];
|
|
2834
|
+
var COMPONENTS_FILENAMES = ["components.tsx", "components.ts"];
|
|
2835
|
+
var firstExisting = (root, names) => {
|
|
2836
|
+
for (const name of names) {
|
|
2837
|
+
const candidate = join7(root, name);
|
|
2838
|
+
if (existsSync4(candidate)) {
|
|
2839
|
+
return candidate;
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2842
|
+
return null;
|
|
2843
|
+
};
|
|
2844
|
+
var findConfigFile = (root) => firstExisting(root, CONFIG_FILENAMES);
|
|
2845
|
+
var resolveRuntimeDir = (root, runtimeDir = ".blume") => isAbsolute(runtimeDir) ? runtimeDir : join7(resolve2(root), runtimeDir);
|
|
2846
|
+
var resolveProjectContext = (root, config, options) => {
|
|
2847
|
+
const absoluteRoot = resolve2(root);
|
|
2848
|
+
const contentRoot = isAbsolute(config.content.root) ? config.content.root : join7(absoluteRoot, config.content.root);
|
|
2849
|
+
const pagesPath = join7(absoluteRoot, config.content.pages);
|
|
2850
|
+
const pagesRoot = existsSync4(pagesPath) ? pagesPath : null;
|
|
2851
|
+
const outDir = resolveRuntimeDir(absoluteRoot, options?.runtimeDir);
|
|
2852
|
+
const distDir = options?.runtimeDir ? join7(outDir, "dist") : join7(absoluteRoot, "dist");
|
|
2853
|
+
return {
|
|
2854
|
+
componentsFile: firstExisting(absoluteRoot, COMPONENTS_FILENAMES),
|
|
2855
|
+
configFile: findConfigFile(absoluteRoot),
|
|
2856
|
+
contentRoot,
|
|
2857
|
+
distDir,
|
|
2858
|
+
outDir,
|
|
2859
|
+
pagesRoot,
|
|
2860
|
+
root: absoluteRoot,
|
|
2861
|
+
themeFile: firstExisting(absoluteRoot, THEME_FILENAMES)
|
|
2862
|
+
};
|
|
2863
|
+
};
|
|
2864
|
+
|
|
2865
|
+
// src/cli/dev-lock.ts
|
|
2866
|
+
var lockPath = (outDir) => join8(outDir, "dev.lock");
|
|
2802
2867
|
var isDevLocked = (outDir) => {
|
|
2803
2868
|
const path = lockPath(outDir);
|
|
2804
|
-
if (!
|
|
2869
|
+
if (!existsSync5(path)) {
|
|
2805
2870
|
return false;
|
|
2806
2871
|
}
|
|
2807
2872
|
const pid = Number.parseInt(readFileSync2(path, "utf-8").trim(), 10);
|
|
@@ -2826,33 +2891,33 @@ var acquireDevLock = (outDir) => {
|
|
|
2826
2891
|
}
|
|
2827
2892
|
released = true;
|
|
2828
2893
|
try {
|
|
2829
|
-
if (
|
|
2894
|
+
if (existsSync5(path) && readFileSync2(path, "utf-8").trim() === String(process.pid)) {
|
|
2830
2895
|
rmSync(path, { force: true });
|
|
2831
2896
|
}
|
|
2832
2897
|
} catch {}
|
|
2833
2898
|
};
|
|
2834
2899
|
};
|
|
2835
|
-
var refuseIfDevRunning = (root, action) => {
|
|
2836
|
-
if (isDevLocked(
|
|
2837
|
-
logger.error(`A \`blume dev\` server is running against .blume; ${action} would corrupt it. Stop the dev server
|
|
2900
|
+
var refuseIfDevRunning = (root, action, runtimeDir) => {
|
|
2901
|
+
if (isDevLocked(resolveRuntimeDir(root, runtimeDir))) {
|
|
2902
|
+
logger.error(`A \`blume dev\` server is running against .blume; ${action} would corrupt it. Stop the dev server, or re-run with --isolated to build/verify against .blume-verify without touching it.`);
|
|
2838
2903
|
process.exit(1);
|
|
2839
2904
|
}
|
|
2840
2905
|
};
|
|
2841
2906
|
|
|
2842
2907
|
// src/astro/generate.ts
|
|
2843
|
-
import { existsSync as
|
|
2908
|
+
import { existsSync as existsSync9, readFileSync as readFileSync6, realpathSync } from "node:fs";
|
|
2844
2909
|
import {
|
|
2845
2910
|
lstat,
|
|
2846
|
-
mkdir as
|
|
2847
|
-
readFile as
|
|
2911
|
+
mkdir as mkdir3,
|
|
2912
|
+
readFile as readFile10,
|
|
2848
2913
|
rename,
|
|
2849
2914
|
rm,
|
|
2850
2915
|
symlink,
|
|
2851
|
-
writeFile as
|
|
2916
|
+
writeFile as writeFile4
|
|
2852
2917
|
} from "node:fs/promises";
|
|
2853
|
-
import { createRequire as
|
|
2918
|
+
import { createRequire as createRequire5 } from "node:module";
|
|
2854
2919
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
2855
|
-
import { basename as basename2, dirname as dirname7, join as
|
|
2920
|
+
import { basename as basename2, dirname as dirname7, join as join17, normalize as normalize3, relative as relative6 } from "pathe";
|
|
2856
2921
|
import { glob as glob4 } from "tinyglobby";
|
|
2857
2922
|
|
|
2858
2923
|
// src/ai/ask-data.ts
|
|
@@ -2924,7 +2989,7 @@ var askBackendRuntimeDep = (ask) => {
|
|
|
2924
2989
|
};
|
|
2925
2990
|
|
|
2926
2991
|
// src/ai/markdown.ts
|
|
2927
|
-
import { readFile as
|
|
2992
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
2928
2993
|
var buildRawMarkdown = async (project) => {
|
|
2929
2994
|
const pageById = new Map(project.graph.pages.map((page) => [page.id, page]));
|
|
2930
2995
|
const readRoute = async (route) => {
|
|
@@ -2932,7 +2997,7 @@ var buildRawMarkdown = async (project) => {
|
|
|
2932
2997
|
if (page) {
|
|
2933
2998
|
return await readEntryText(project, page);
|
|
2934
2999
|
}
|
|
2935
|
-
return route.sourcePath ? await
|
|
3000
|
+
return route.sourcePath ? await readFile4(route.sourcePath, "utf-8") : "";
|
|
2936
3001
|
};
|
|
2937
3002
|
const entries = await Promise.all(project.manifest.routes.map(async (route) => [route.path, await readRoute(route)]));
|
|
2938
3003
|
return Object.fromEntries(entries);
|
|
@@ -3029,6 +3094,7 @@ var buildMcpServerCard = (input) => ({
|
|
|
3029
3094
|
var BUILTIN_MDX_TAGS = new Set([
|
|
3030
3095
|
"Accordion",
|
|
3031
3096
|
"AccordionItem",
|
|
3097
|
+
"ApiOverview",
|
|
3032
3098
|
"AutoTypeTable",
|
|
3033
3099
|
"Badge",
|
|
3034
3100
|
"Callout",
|
|
@@ -3047,8 +3113,12 @@ var BUILTIN_MDX_TAGS = new Set([
|
|
|
3047
3113
|
"GithubInfo",
|
|
3048
3114
|
"Icon",
|
|
3049
3115
|
"Math",
|
|
3116
|
+
"Operation",
|
|
3050
3117
|
"Panel",
|
|
3118
|
+
"ParamField",
|
|
3051
3119
|
"Prompt",
|
|
3120
|
+
"RequestField",
|
|
3121
|
+
"ResponseField",
|
|
3052
3122
|
"Step",
|
|
3053
3123
|
"Steps",
|
|
3054
3124
|
"Tab",
|
|
@@ -3087,8 +3157,8 @@ var validateUsedComponents = (pages, extraTags, registryNames) => {
|
|
|
3087
3157
|
};
|
|
3088
3158
|
|
|
3089
3159
|
// src/core/component-overrides.ts
|
|
3090
|
-
import { existsSync as
|
|
3091
|
-
import { dirname as dirname4, extname, isAbsolute, resolve as
|
|
3160
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
3161
|
+
import { dirname as dirname4, extname, isAbsolute as isAbsolute2, resolve as resolve3 } from "pathe";
|
|
3092
3162
|
import ts from "typescript";
|
|
3093
3163
|
var GROUPS = ["mdx", "layout", "islands"];
|
|
3094
3164
|
var FRAMEWORK_BY_EXT = {
|
|
@@ -3176,18 +3246,18 @@ var findDefaultExportObject = (sourceFile) => {
|
|
|
3176
3246
|
var probeExtension = (base) => {
|
|
3177
3247
|
for (const extension of COMPONENT_EXTS) {
|
|
3178
3248
|
const candidate = `${base}.${extension}`;
|
|
3179
|
-
if (
|
|
3249
|
+
if (existsSync6(candidate)) {
|
|
3180
3250
|
return candidate;
|
|
3181
3251
|
}
|
|
3182
3252
|
}
|
|
3183
3253
|
return null;
|
|
3184
3254
|
};
|
|
3185
3255
|
var toImport = (specifier, imported, dir) => {
|
|
3186
|
-
const relative4 = specifier.startsWith(".") ||
|
|
3256
|
+
const relative4 = specifier.startsWith(".") || isAbsolute2(specifier);
|
|
3187
3257
|
let path = specifier;
|
|
3188
3258
|
let extension = extname(specifier).slice(1).toLowerCase();
|
|
3189
3259
|
if (relative4) {
|
|
3190
|
-
const absolute =
|
|
3260
|
+
const absolute = isAbsolute2(specifier) ? specifier : resolve3(dir, specifier);
|
|
3191
3261
|
if (extension) {
|
|
3192
3262
|
path = absolute;
|
|
3193
3263
|
} else {
|
|
@@ -3435,147 +3505,104 @@ var resolveUIStrings = (locale, options) => {
|
|
|
3435
3505
|
};
|
|
3436
3506
|
|
|
3437
3507
|
// src/theme/icons.ts
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
"
|
|
3444
|
-
|
|
3445
|
-
"
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
"
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
"
|
|
3473
|
-
|
|
3474
|
-
"
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
}
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
"fa-linkedin": "linkedin",
|
|
3502
|
-
"fa-x-twitter": "brand-x",
|
|
3503
|
-
"file-lines": "file",
|
|
3504
|
-
javascript: "js",
|
|
3505
|
-
"panel-left-open": "panel-left",
|
|
3506
|
-
"panel-right-open": "panel-right",
|
|
3507
|
-
times: "x",
|
|
3508
|
-
"x-twitter": "brand-x"
|
|
3509
|
-
};
|
|
3510
|
-
var libraryPrefixes = [
|
|
3511
|
-
"fa-brands",
|
|
3512
|
-
"fa-duotone",
|
|
3513
|
-
"fa-light",
|
|
3514
|
-
"fa-regular",
|
|
3515
|
-
"fa-sharp-solid",
|
|
3516
|
-
"fa-solid",
|
|
3517
|
-
"fa-thin",
|
|
3518
|
-
"fa",
|
|
3519
|
-
"fab",
|
|
3520
|
-
"fad",
|
|
3521
|
-
"fal",
|
|
3522
|
-
"far",
|
|
3523
|
-
"fas",
|
|
3524
|
-
"fat",
|
|
3525
|
-
"lucide",
|
|
3526
|
-
"tabler",
|
|
3527
|
-
"ti"
|
|
3528
|
-
];
|
|
3529
|
-
var normalizedIconName = (name) => name.trim().toLowerCase().replaceAll(/[\s_]+/gu, "-");
|
|
3530
|
-
var isString = (value) => typeof value === "string";
|
|
3531
|
-
var withoutLibraryPrefix = (name) => {
|
|
3532
|
-
let normalized = normalizedIconName(name).replaceAll(/^icon-/gu, "");
|
|
3533
|
-
let changed = true;
|
|
3534
|
-
while (changed) {
|
|
3535
|
-
changed = false;
|
|
3536
|
-
for (const prefix of libraryPrefixes) {
|
|
3537
|
-
if (normalized.startsWith(`${prefix}-`)) {
|
|
3538
|
-
normalized = normalized.slice(prefix.length + 1);
|
|
3539
|
-
changed = true;
|
|
3540
|
-
}
|
|
3541
|
-
if (normalized.startsWith(`${prefix}:`)) {
|
|
3542
|
-
normalized = normalized.slice(prefix.length + 1);
|
|
3543
|
-
changed = true;
|
|
3544
|
-
}
|
|
3545
|
-
}
|
|
3508
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
3509
|
+
import { getIconData, iconToSVG } from "@iconify/utils";
|
|
3510
|
+
var requireJson = createRequire2(import.meta.url);
|
|
3511
|
+
var loadSet = (pkg) => requireJson(pkg);
|
|
3512
|
+
var SETS = {
|
|
3513
|
+
"fa6-brands": loadSet("@iconify-json/fa6-brands/icons.json"),
|
|
3514
|
+
"fa6-regular": loadSet("@iconify-json/fa6-regular/icons.json"),
|
|
3515
|
+
"fa6-solid": loadSet("@iconify-json/fa6-solid/icons.json"),
|
|
3516
|
+
lucide: loadSet("@iconify-json/lucide/icons.json"),
|
|
3517
|
+
tabler: loadSet("@iconify-json/tabler/icons.json")
|
|
3518
|
+
};
|
|
3519
|
+
var DEFAULT_SET = "lucide";
|
|
3520
|
+
var LIBRARY_SETS = {
|
|
3521
|
+
fa: "fa6-solid",
|
|
3522
|
+
"font-awesome": "fa6-solid",
|
|
3523
|
+
fontawesome: "fa6-solid",
|
|
3524
|
+
lucide: "lucide",
|
|
3525
|
+
tabler: "tabler"
|
|
3526
|
+
};
|
|
3527
|
+
var ICON_TYPE_SETS = {
|
|
3528
|
+
brands: "fa6-brands",
|
|
3529
|
+
duotone: "fa6-solid",
|
|
3530
|
+
light: "fa6-solid",
|
|
3531
|
+
regular: "fa6-regular",
|
|
3532
|
+
"sharp-solid": "fa6-solid",
|
|
3533
|
+
solid: "fa6-solid",
|
|
3534
|
+
thin: "fa6-solid"
|
|
3535
|
+
};
|
|
3536
|
+
var PREFIX_SETS = {
|
|
3537
|
+
...LIBRARY_SETS,
|
|
3538
|
+
fa: "fa6-solid",
|
|
3539
|
+
"fa-brands": "fa6-brands",
|
|
3540
|
+
"fa-regular": "fa6-regular",
|
|
3541
|
+
"fa-solid": "fa6-solid",
|
|
3542
|
+
"fa6-brands": "fa6-brands",
|
|
3543
|
+
"fa6-regular": "fa6-regular",
|
|
3544
|
+
"fa6-solid": "fa6-solid",
|
|
3545
|
+
fab: "fa6-brands",
|
|
3546
|
+
far: "fa6-regular",
|
|
3547
|
+
fas: "fa6-solid",
|
|
3548
|
+
ti: "tabler"
|
|
3549
|
+
};
|
|
3550
|
+
var normalize = (name) => name.trim().toLowerCase().replaceAll(/[\s_]+/gu, "-");
|
|
3551
|
+
var setFor = (options) => {
|
|
3552
|
+
if (options.iconType) {
|
|
3553
|
+
const set = ICON_TYPE_SETS[normalize(options.iconType)];
|
|
3554
|
+
if (set) {
|
|
3555
|
+
return set;
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
if (options.library) {
|
|
3559
|
+
const set = LIBRARY_SETS[normalize(options.library)];
|
|
3560
|
+
if (set) {
|
|
3561
|
+
return set;
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
return DEFAULT_SET;
|
|
3565
|
+
};
|
|
3566
|
+
var fromSet = (setName, iconName) => {
|
|
3567
|
+
const set = SETS[setName];
|
|
3568
|
+
const data = set && getIconData(set, iconName);
|
|
3569
|
+
if (!data) {
|
|
3570
|
+
return null;
|
|
3546
3571
|
}
|
|
3547
|
-
|
|
3572
|
+
const { attributes, body } = iconToSVG(data, { height: "auto" });
|
|
3573
|
+
return { body, name: iconName, viewBox: attributes.viewBox };
|
|
3548
3574
|
};
|
|
3549
|
-
var
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
const
|
|
3553
|
-
const
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
iconAliases[stripped]
|
|
3559
|
-
].filter(isString);
|
|
3560
|
-
for (const candidate of candidates) {
|
|
3561
|
-
const markup = icons[candidate];
|
|
3562
|
-
if (markup) {
|
|
3563
|
-
return { markup, name: candidate };
|
|
3575
|
+
var fromFaSet = (setName, name) => fromSet(setName, name) ?? fromSet("fa6-brands", name);
|
|
3576
|
+
var resolveInSet = (setName, name) => setName.startsWith("fa6-") ? fromFaSet(setName, name) : fromSet(setName, name);
|
|
3577
|
+
var resolveIcon = (name, options = {}) => {
|
|
3578
|
+
const normalized = normalize(name);
|
|
3579
|
+
const colon = normalized.indexOf(":");
|
|
3580
|
+
if (colon > 0) {
|
|
3581
|
+
const setName = PREFIX_SETS[normalized.slice(0, colon)];
|
|
3582
|
+
if (setName) {
|
|
3583
|
+
return resolveInSet(setName, normalized.slice(colon + 1));
|
|
3564
3584
|
}
|
|
3565
3585
|
}
|
|
3566
|
-
return
|
|
3586
|
+
return resolveInSet(setFor(options), normalized);
|
|
3587
|
+
};
|
|
3588
|
+
var hasIcon = (name, options = {}) => {
|
|
3589
|
+
if (resolveIcon(name, options)) {
|
|
3590
|
+
return true;
|
|
3591
|
+
}
|
|
3592
|
+
const normalized = normalize(name);
|
|
3593
|
+
const bare = normalized.includes(":") ? normalized.slice(normalized.indexOf(":") + 1) : normalized;
|
|
3594
|
+
return Object.values(SETS).some((set) => getIconData(set, bare) !== null);
|
|
3567
3595
|
};
|
|
3568
|
-
var hasIcon = (name, iconType) => resolveIcon(name, iconType) !== null;
|
|
3569
3596
|
|
|
3570
3597
|
// src/core/nav-diagnostics.ts
|
|
3571
3598
|
var IMAGE_ICON = /^(?:https?:\/\/|data:image\/|\/|\.{1,2}\/)|\.(?:avif|gif|jpe?g|png|svg|webp)$/iu;
|
|
3572
3599
|
var isAssetIcon = (value) => value.startsWith("<") || IMAGE_ICON.test(value);
|
|
3573
3600
|
var flattenNodes = (nodes) => nodes.flatMap((node) => node.kind === "group" ? [node, ...flattenNodes(node.children)] : [node]);
|
|
3574
3601
|
var collectIcons = (navigation) => {
|
|
3575
|
-
const
|
|
3602
|
+
const icons = [];
|
|
3576
3603
|
const push = (icon, where) => {
|
|
3577
3604
|
if (icon) {
|
|
3578
|
-
|
|
3605
|
+
icons.push({ icon, where });
|
|
3579
3606
|
}
|
|
3580
3607
|
};
|
|
3581
3608
|
for (const tab of navigation.tabs) {
|
|
@@ -3598,7 +3625,7 @@ var collectIcons = (navigation) => {
|
|
|
3598
3625
|
push(node.icon, `"${node.label}"`);
|
|
3599
3626
|
}
|
|
3600
3627
|
}
|
|
3601
|
-
return
|
|
3628
|
+
return icons;
|
|
3602
3629
|
};
|
|
3603
3630
|
var validateNavIcons = (navigation) => {
|
|
3604
3631
|
const seen = new Set;
|
|
@@ -3708,10 +3735,10 @@ var validateNavStructure = (navigation, pages) => [
|
|
|
3708
3735
|
];
|
|
3709
3736
|
|
|
3710
3737
|
// src/core/tsconfig-aliases.ts
|
|
3711
|
-
import { existsSync as
|
|
3712
|
-
import { createRequire as
|
|
3738
|
+
import { existsSync as existsSync7, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
3739
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
3713
3740
|
import { pathToFileURL } from "node:url";
|
|
3714
|
-
import { dirname as dirname5, isAbsolute as
|
|
3741
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join9, resolve as resolve4 } from "pathe";
|
|
3715
3742
|
var stripJsonComments = (text) => {
|
|
3716
3743
|
let out = "";
|
|
3717
3744
|
let inString = false;
|
|
@@ -3765,16 +3792,16 @@ var isFile = (path) => {
|
|
|
3765
3792
|
}
|
|
3766
3793
|
};
|
|
3767
3794
|
var resolveExtends = (spec, fromDir) => {
|
|
3768
|
-
if (spec.startsWith(".") ||
|
|
3769
|
-
const candidates = spec.endsWith(".json") ? [
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3795
|
+
if (spec.startsWith(".") || isAbsolute3(spec)) {
|
|
3796
|
+
const candidates = spec.endsWith(".json") ? [resolve4(fromDir, spec)] : [
|
|
3797
|
+
resolve4(fromDir, `${spec}.json`),
|
|
3798
|
+
resolve4(fromDir, spec, "tsconfig.json"),
|
|
3799
|
+
resolve4(fromDir, spec)
|
|
3773
3800
|
];
|
|
3774
3801
|
return candidates.find(isFile) ?? null;
|
|
3775
3802
|
}
|
|
3776
3803
|
try {
|
|
3777
|
-
const require_ =
|
|
3804
|
+
const require_ = createRequire3(pathToFileURL(join9(fromDir, "_.js")).href);
|
|
3778
3805
|
for (const sub of [`${spec}/tsconfig.json`, spec]) {
|
|
3779
3806
|
try {
|
|
3780
3807
|
return require_.resolve(sub);
|
|
@@ -3784,7 +3811,7 @@ var resolveExtends = (spec, fromDir) => {
|
|
|
3784
3811
|
return null;
|
|
3785
3812
|
};
|
|
3786
3813
|
var loadPaths = (file, seen) => {
|
|
3787
|
-
if (seen.has(file) || !
|
|
3814
|
+
if (seen.has(file) || !existsSync7(file)) {
|
|
3788
3815
|
return null;
|
|
3789
3816
|
}
|
|
3790
3817
|
seen.add(file);
|
|
@@ -3796,7 +3823,7 @@ var loadPaths = (file, seen) => {
|
|
|
3796
3823
|
if (options.paths && typeof options.paths === "object") {
|
|
3797
3824
|
const baseUrl = typeof options.baseUrl === "string" ? options.baseUrl : ".";
|
|
3798
3825
|
return {
|
|
3799
|
-
baseDir:
|
|
3826
|
+
baseDir: resolve4(dirname5(file), baseUrl),
|
|
3800
3827
|
paths: options.paths
|
|
3801
3828
|
};
|
|
3802
3829
|
}
|
|
@@ -3823,10 +3850,10 @@ var toAlias = (key, value, baseDir) => {
|
|
|
3823
3850
|
if (find === "" || find === "*") {
|
|
3824
3851
|
return null;
|
|
3825
3852
|
}
|
|
3826
|
-
return { find, replacement:
|
|
3853
|
+
return { find, replacement: resolve4(baseDir, target) };
|
|
3827
3854
|
};
|
|
3828
3855
|
var resolveTsconfigAliases = (root) => {
|
|
3829
|
-
const entry = ["tsconfig.json", "jsconfig.json"].map((name) =>
|
|
3856
|
+
const entry = ["tsconfig.json", "jsconfig.json"].map((name) => join9(root, name)).find((file) => existsSync7(file));
|
|
3830
3857
|
if (!entry) {
|
|
3831
3858
|
return {};
|
|
3832
3859
|
}
|
|
@@ -3922,19 +3949,97 @@ ${items}
|
|
|
3922
3949
|
`;
|
|
3923
3950
|
};
|
|
3924
3951
|
|
|
3952
|
+
// src/openapi/references.ts
|
|
3953
|
+
var NON_SLUG = /[^a-z0-9]+/gu;
|
|
3954
|
+
var SLUG_EDGES = /^-+|-+$/gu;
|
|
3955
|
+
var ROUTE_EDGES = /^\/+|\/+$/gu;
|
|
3956
|
+
var TRAILING_SLASH = /\/+$/u;
|
|
3957
|
+
var slugify = (text) => text.toLowerCase().replace(NON_SLUG, "-").replace(SLUG_EDGES, "");
|
|
3958
|
+
var normalizeRoute = (route) => {
|
|
3959
|
+
const trimmed = route.trim();
|
|
3960
|
+
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
3961
|
+
const noTrailing = withSlash.replace(TRAILING_SLASH, "");
|
|
3962
|
+
return noTrailing === "" ? "/" : noTrailing;
|
|
3963
|
+
};
|
|
3964
|
+
var routeSlug = (route) => slugify(route.replace(ROUTE_EDGES, "")) || "reference";
|
|
3965
|
+
var sourcesOf = (block) => {
|
|
3966
|
+
const sources = [...block.sources];
|
|
3967
|
+
if (block.spec) {
|
|
3968
|
+
sources.unshift({ spec: block.spec });
|
|
3969
|
+
}
|
|
3970
|
+
return sources;
|
|
3971
|
+
};
|
|
3972
|
+
var referencesFor = (kind, block, defaultLabel, renderer, display) => {
|
|
3973
|
+
if (!block.enabled) {
|
|
3974
|
+
return [];
|
|
3975
|
+
}
|
|
3976
|
+
const sources = sourcesOf(block);
|
|
3977
|
+
const base = normalizeRoute(block.route);
|
|
3978
|
+
return sources.map((source, index) => {
|
|
3979
|
+
const label = source.label ?? (sources.length > 1 ? `${defaultLabel} ${index + 1}` : defaultLabel);
|
|
3980
|
+
let route;
|
|
3981
|
+
if (source.route) {
|
|
3982
|
+
route = normalizeRoute(source.route);
|
|
3983
|
+
} else if (sources.length === 1) {
|
|
3984
|
+
route = base;
|
|
3985
|
+
} else {
|
|
3986
|
+
const suffix = source.label ? slugify(source.label) : "";
|
|
3987
|
+
route = normalizeRoute(`${base}/${suffix || index + 1}`);
|
|
3988
|
+
}
|
|
3989
|
+
return {
|
|
3990
|
+
display,
|
|
3991
|
+
kind,
|
|
3992
|
+
label,
|
|
3993
|
+
renderer,
|
|
3994
|
+
route,
|
|
3995
|
+
slug: routeSlug(route),
|
|
3996
|
+
spec: source.spec,
|
|
3997
|
+
theme: block.theme
|
|
3998
|
+
};
|
|
3999
|
+
});
|
|
4000
|
+
};
|
|
4001
|
+
var NO_DISPLAY = { codeSamples: [], expandSchemas: false };
|
|
4002
|
+
var resolveReferences = (config) => [
|
|
4003
|
+
...referencesFor("openapi", config.openapi, "API Reference", config.openapi.renderer, {
|
|
4004
|
+
codeSamples: config.openapi.codeSamples,
|
|
4005
|
+
expandSchemas: config.openapi.expandSchemas
|
|
4006
|
+
}),
|
|
4007
|
+
...referencesFor("asyncapi", config.asyncapi, "Events", "scalar", NO_DISPLAY)
|
|
4008
|
+
];
|
|
4009
|
+
var referenceTabs = (config) => resolveReferences(config).map((ref) => ({
|
|
4010
|
+
label: ref.label,
|
|
4011
|
+
path: ref.route
|
|
4012
|
+
}));
|
|
4013
|
+
var blumeReferences = (config) => {
|
|
4014
|
+
const seen = new Set;
|
|
4015
|
+
const result = [];
|
|
4016
|
+
for (const ref of resolveReferences(config)) {
|
|
4017
|
+
if (ref.kind !== "openapi" || ref.renderer !== "blume") {
|
|
4018
|
+
continue;
|
|
4019
|
+
}
|
|
4020
|
+
if (seen.has(ref.route)) {
|
|
4021
|
+
continue;
|
|
4022
|
+
}
|
|
4023
|
+
seen.add(ref.route);
|
|
4024
|
+
result.push(ref);
|
|
4025
|
+
}
|
|
4026
|
+
return result;
|
|
4027
|
+
};
|
|
4028
|
+
var hasScalarReferences = (config) => resolveReferences(config).some((ref) => ref.renderer === "scalar");
|
|
4029
|
+
|
|
3925
4030
|
// src/openapi/scalar.ts
|
|
3926
|
-
import { readFile as
|
|
3927
|
-
import { isAbsolute as
|
|
4031
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
4032
|
+
import { isAbsolute as isAbsolute4, join as join12 } from "pathe";
|
|
3928
4033
|
|
|
3929
4034
|
// src/astro/templates.ts
|
|
3930
|
-
import { existsSync as
|
|
3931
|
-
import { dirname as dirname6, join as
|
|
4035
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
4036
|
+
import { dirname as dirname6, join as join11 } from "pathe";
|
|
3932
4037
|
|
|
3933
4038
|
// src/core/assets.ts
|
|
3934
|
-
import { join as
|
|
4039
|
+
import { join as join10 } from "pathe";
|
|
3935
4040
|
var resolveAssetMounts = (root, assets) => assets.map((entry) => {
|
|
3936
4041
|
const rel = entry.replace(/^[./]+/u, "").replaceAll(/\.\.\/?/gu, "").replace(/\/+$/u, "");
|
|
3937
|
-
return { dir:
|
|
4042
|
+
return { dir: join10(root, rel), url: `/${rel}` };
|
|
3938
4043
|
});
|
|
3939
4044
|
|
|
3940
4045
|
// src/theme/fonts.ts
|
|
@@ -4093,7 +4198,7 @@ var WORKSPACE_MARKERS = [
|
|
|
4093
4198
|
"yarn.lock"
|
|
4094
4199
|
];
|
|
4095
4200
|
var hasWorkspacesField = (pkgPath) => {
|
|
4096
|
-
if (!
|
|
4201
|
+
if (!existsSync8(pkgPath)) {
|
|
4097
4202
|
return false;
|
|
4098
4203
|
}
|
|
4099
4204
|
try {
|
|
@@ -4103,7 +4208,7 @@ var hasWorkspacesField = (pkgPath) => {
|
|
|
4103
4208
|
return false;
|
|
4104
4209
|
}
|
|
4105
4210
|
};
|
|
4106
|
-
var hasWorkspaceMarker = (dir) => hasWorkspacesField(
|
|
4211
|
+
var hasWorkspaceMarker = (dir) => hasWorkspacesField(join11(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync8(join11(dir, marker)));
|
|
4107
4212
|
var findWorkspaceRoot = (start) => {
|
|
4108
4213
|
let dir = start;
|
|
4109
4214
|
for (;; ) {
|
|
@@ -4138,7 +4243,7 @@ var runtimeDependencies = (options) => {
|
|
|
4138
4243
|
if (needsSvelte) {
|
|
4139
4244
|
deps.push("@astrojs/svelte");
|
|
4140
4245
|
}
|
|
4141
|
-
if (config
|
|
4246
|
+
if (hasScalarReferences(config)) {
|
|
4142
4247
|
deps.push("@scalar/astro");
|
|
4143
4248
|
}
|
|
4144
4249
|
deps.push(...searchProviderMeta(config.search.provider).runtimeDeps);
|
|
@@ -4171,6 +4276,7 @@ var RENDER_EXTERNAL_DEPS = [
|
|
|
4171
4276
|
];
|
|
4172
4277
|
var renderUserAliases = (aliases) => Object.entries(aliases ?? {}).toSorted(([a], [b]) => b.length - a.length).map(([find, replacement]) => `
|
|
4173
4278
|
${JSON.stringify(find)}: ${JSON.stringify(replacement)},`).join("");
|
|
4279
|
+
var astroOutDir = (context) => context.distDir ?? `${context.root}/dist`;
|
|
4174
4280
|
var astroConfigTemplate = (options) => {
|
|
4175
4281
|
const { context, config, needsReact, pages, dataPath, themePath } = options;
|
|
4176
4282
|
const {
|
|
@@ -4178,6 +4284,7 @@ var astroConfigTemplate = (options) => {
|
|
|
4178
4284
|
examplesPath,
|
|
4179
4285
|
needsSvelte,
|
|
4180
4286
|
needsVue,
|
|
4287
|
+
openapiPath,
|
|
4181
4288
|
searchClientPath
|
|
4182
4289
|
} = options;
|
|
4183
4290
|
const { deployment } = config;
|
|
@@ -4248,7 +4355,7 @@ ${twoslashImport}${reactImport}${vueImport}${svelteImport}${blumeImport}${adapte
|
|
|
4248
4355
|
export default defineConfig({
|
|
4249
4356
|
root: ${JSON.stringify(context.outDir)},
|
|
4250
4357
|
srcDir: ${JSON.stringify(`${context.outDir}/src`)},
|
|
4251
|
-
outDir: ${JSON.stringify(
|
|
4358
|
+
outDir: ${JSON.stringify(astroOutDir(context))},
|
|
4252
4359
|
publicDir: ${JSON.stringify(`${context.root}/public`)},
|
|
4253
4360
|
output: ${JSON.stringify(deployment.output)},${adapterOption}${siteOption}${baseOption}${redirectsOption}${i18nOption}${fontsOption}
|
|
4254
4361
|
integrations: [${integrations.join(", ")}],
|
|
@@ -4281,6 +4388,7 @@ export default defineConfig({
|
|
|
4281
4388
|
alias: {
|
|
4282
4389
|
"blume:data": ${JSON.stringify(dataPath)},
|
|
4283
4390
|
"blume:examples": ${JSON.stringify(examplesPath)},
|
|
4391
|
+
"blume:openapi": ${JSON.stringify(openapiPath)},
|
|
4284
4392
|
"blume:search-client": ${JSON.stringify(searchClientPath)},
|
|
4285
4393
|
"blume:theme": ${JSON.stringify(themePath)},${userAliasLines}
|
|
4286
4394
|
},
|
|
@@ -4294,7 +4402,7 @@ export default defineConfig({
|
|
|
4294
4402
|
});
|
|
4295
4403
|
`;
|
|
4296
4404
|
};
|
|
4297
|
-
var stagedContentDir = (outDir) =>
|
|
4405
|
+
var stagedContentDir = (outDir) => join11(outDir, "content");
|
|
4298
4406
|
var contentConfigTemplate = (options) => {
|
|
4299
4407
|
const { context, config } = options;
|
|
4300
4408
|
const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);
|
|
@@ -4700,7 +4808,10 @@ import FileTree from "blume/components/content/FileTree.astro";
|
|
|
4700
4808
|
import Frame from "blume/components/content/Frame.astro";
|
|
4701
4809
|
import GithubInfo from "blume/components/content/GithubInfo.astro";
|
|
4702
4810
|
import Panel from "blume/components/content/Panel.astro";
|
|
4811
|
+
import ParamField from "blume/components/content/ParamField.astro";
|
|
4703
4812
|
import Prompt from "blume/components/content/Prompt.astro";
|
|
4813
|
+
import RequestField from "blume/components/content/RequestField.astro";
|
|
4814
|
+
import ResponseField from "blume/components/content/ResponseField.astro";
|
|
4704
4815
|
import Step from "blume/components/content/Step.astro";
|
|
4705
4816
|
import Steps from "blume/components/content/Steps.astro";
|
|
4706
4817
|
import Tab from "blume/components/content/Tab.astro";
|
|
@@ -4714,6 +4825,8 @@ import TypeTable from "blume/components/content/TypeTable.astro";
|
|
|
4714
4825
|
import Visibility from "blume/components/content/Visibility.astro";
|
|
4715
4826
|
import YouTube from "blume/components/content/YouTube.astro";
|
|
4716
4827
|
import Icon from "blume/components/Icon.astro";
|
|
4828
|
+
import ApiOverview from "blume/components/openapi/ApiOverview.astro";
|
|
4829
|
+
import Operation from "blume/components/openapi/Operation.astro";
|
|
4717
4830
|
${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";
|
|
4718
4831
|
import { islandComponents } from "../generated/islands.ts";
|
|
4719
4832
|
import data from "../generated/data.json";
|
|
@@ -4730,6 +4843,7 @@ export const prerender = true;
|
|
|
4730
4843
|
const components = {
|
|
4731
4844
|
Accordion,
|
|
4732
4845
|
AccordionItem,
|
|
4846
|
+
ApiOverview,
|
|
4733
4847
|
AutoTypeTable,
|
|
4734
4848
|
Badge,
|
|
4735
4849
|
Callout,
|
|
@@ -4747,8 +4861,12 @@ const components = {
|
|
|
4747
4861
|
Frame,
|
|
4748
4862
|
GithubInfo,
|
|
4749
4863
|
Icon,
|
|
4864
|
+
Operation,
|
|
4750
4865
|
Panel,
|
|
4866
|
+
ParamField,
|
|
4751
4867
|
Prompt,
|
|
4868
|
+
RequestField,
|
|
4869
|
+
ResponseField,
|
|
4752
4870
|
Step,
|
|
4753
4871
|
Steps,
|
|
4754
4872
|
Tab,
|
|
@@ -5148,6 +5266,11 @@ declare module "blume:data" {
|
|
|
5148
5266
|
export default data;
|
|
5149
5267
|
}
|
|
5150
5268
|
|
|
5269
|
+
declare module "blume:openapi" {
|
|
5270
|
+
const specs: import("blume/openapi/model.ts").OpenApiData;
|
|
5271
|
+
export default specs;
|
|
5272
|
+
}
|
|
5273
|
+
|
|
5151
5274
|
declare module "blume:search-client" {
|
|
5152
5275
|
export const createSearch: () =>
|
|
5153
5276
|
| import("blume/components/layout/search/types.ts").SearchFn
|
|
@@ -5262,57 +5385,11 @@ ${dark}`;
|
|
|
5262
5385
|
|
|
5263
5386
|
// src/openapi/scalar.ts
|
|
5264
5387
|
var URL_SPEC = /^https?:\/\//u;
|
|
5265
|
-
var
|
|
5266
|
-
var SLUG_EDGES = /^-+|-+$/gu;
|
|
5267
|
-
var ROUTE_EDGES = /^\/+|\/+$/gu;
|
|
5268
|
-
var TRAILING_SLASH = /\/+$/u;
|
|
5269
|
-
var slugify = (text) => text.toLowerCase().replace(NON_SLUG, "-").replace(SLUG_EDGES, "");
|
|
5270
|
-
var normalizeRoute = (route) => {
|
|
5271
|
-
const trimmed = route.trim();
|
|
5272
|
-
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
5273
|
-
const noTrailing = withSlash.replace(TRAILING_SLASH, "");
|
|
5274
|
-
return noTrailing === "" ? "/" : noTrailing;
|
|
5275
|
-
};
|
|
5388
|
+
var ROUTE_EDGES2 = /^\/+|\/+$/gu;
|
|
5276
5389
|
var referencePagePath = (route) => {
|
|
5277
|
-
const segments = route.replace(
|
|
5390
|
+
const segments = route.replace(ROUTE_EDGES2, "");
|
|
5278
5391
|
return `${segments === "" ? "index" : segments}.astro`;
|
|
5279
5392
|
};
|
|
5280
|
-
var sourcesOf = (block) => {
|
|
5281
|
-
const sources = [...block.sources];
|
|
5282
|
-
if (block.spec) {
|
|
5283
|
-
sources.unshift({ spec: block.spec });
|
|
5284
|
-
}
|
|
5285
|
-
return sources;
|
|
5286
|
-
};
|
|
5287
|
-
var referencesFor = (kind, block, defaultLabel) => {
|
|
5288
|
-
if (!block.enabled) {
|
|
5289
|
-
return [];
|
|
5290
|
-
}
|
|
5291
|
-
const sources = sourcesOf(block);
|
|
5292
|
-
const base = normalizeRoute(block.route);
|
|
5293
|
-
return sources.map((source, index) => {
|
|
5294
|
-
const label = source.label ?? (sources.length > 1 ? `${defaultLabel} ${index + 1}` : defaultLabel);
|
|
5295
|
-
let route;
|
|
5296
|
-
if (source.route) {
|
|
5297
|
-
route = normalizeRoute(source.route);
|
|
5298
|
-
} else if (sources.length === 1) {
|
|
5299
|
-
route = base;
|
|
5300
|
-
} else {
|
|
5301
|
-
const suffix = source.label ? slugify(source.label) : "";
|
|
5302
|
-
route = normalizeRoute(`${base}/${suffix || index + 1}`);
|
|
5303
|
-
}
|
|
5304
|
-
return { kind, label, route, spec: source.spec, theme: block.theme };
|
|
5305
|
-
});
|
|
5306
|
-
};
|
|
5307
|
-
var resolveReferences = (config) => [
|
|
5308
|
-
...referencesFor("openapi", config.openapi, "API Reference"),
|
|
5309
|
-
...referencesFor("asyncapi", config.asyncapi, "Events")
|
|
5310
|
-
];
|
|
5311
|
-
var referenceTabs = (config) => resolveReferences(config).map((ref) => ({
|
|
5312
|
-
label: ref.label,
|
|
5313
|
-
path: ref.route
|
|
5314
|
-
}));
|
|
5315
|
-
var hasReferences = (config) => config.openapi.enabled || config.asyncapi.enabled;
|
|
5316
5393
|
var darkModeConfig = (mode) => {
|
|
5317
5394
|
if (mode === "dark") {
|
|
5318
5395
|
return { darkMode: true };
|
|
@@ -5337,9 +5414,9 @@ var specConfiguration = async (spec, root) => {
|
|
|
5337
5414
|
if (URL_SPEC.test(spec)) {
|
|
5338
5415
|
return { config: { url: spec } };
|
|
5339
5416
|
}
|
|
5340
|
-
const absolute =
|
|
5417
|
+
const absolute = isAbsolute4(spec) ? spec : join12(root, spec);
|
|
5341
5418
|
try {
|
|
5342
|
-
return { config: { content: await
|
|
5419
|
+
return { config: { content: await readFile5(absolute, "utf-8") } };
|
|
5343
5420
|
} catch {
|
|
5344
5421
|
return {
|
|
5345
5422
|
config: { url: spec },
|
|
@@ -5353,6 +5430,9 @@ var buildReferenceFiles = async (options) => {
|
|
|
5353
5430
|
const seen = new Set;
|
|
5354
5431
|
const accepted = [];
|
|
5355
5432
|
for (const ref of resolveReferences(config)) {
|
|
5433
|
+
if (ref.renderer !== "scalar") {
|
|
5434
|
+
continue;
|
|
5435
|
+
}
|
|
5356
5436
|
if (seen.has(ref.route)) {
|
|
5357
5437
|
warnings.push(`Two API reference sources resolve to ${ref.route}; keeping the first.`);
|
|
5358
5438
|
continue;
|
|
@@ -5373,22 +5453,300 @@ var buildReferenceFiles = async (options) => {
|
|
|
5373
5453
|
if (spec.warning) {
|
|
5374
5454
|
warnings.push(spec.warning);
|
|
5375
5455
|
}
|
|
5376
|
-
const pagePath = referencePagePath(ref.route);
|
|
5377
|
-
const depth = pagePath.split("/").length - 1;
|
|
5378
|
-
files.push({
|
|
5379
|
-
content: scalarReferenceTemplate({
|
|
5380
|
-
configuration: {
|
|
5381
|
-
...spec.config,
|
|
5382
|
-
...themeConfiguration(config, ref.theme)
|
|
5383
|
-
},
|
|
5384
|
-
dataImport: `${"../".repeat(depth + 1)}generated/data.json`,
|
|
5385
|
-
route: ref.route,
|
|
5386
|
-
title: ref.label
|
|
5387
|
-
}),
|
|
5388
|
-
pagePath
|
|
5389
|
-
});
|
|
5390
|
-
}
|
|
5391
|
-
return { files, warnings };
|
|
5456
|
+
const pagePath = referencePagePath(ref.route);
|
|
5457
|
+
const depth = pagePath.split("/").length - 1;
|
|
5458
|
+
files.push({
|
|
5459
|
+
content: scalarReferenceTemplate({
|
|
5460
|
+
configuration: {
|
|
5461
|
+
...spec.config,
|
|
5462
|
+
...themeConfiguration(config, ref.theme)
|
|
5463
|
+
},
|
|
5464
|
+
dataImport: `${"../".repeat(depth + 1)}generated/data.json`,
|
|
5465
|
+
route: ref.route,
|
|
5466
|
+
title: ref.label
|
|
5467
|
+
}),
|
|
5468
|
+
pagePath
|
|
5469
|
+
});
|
|
5470
|
+
}
|
|
5471
|
+
return { files, warnings };
|
|
5472
|
+
};
|
|
5473
|
+
|
|
5474
|
+
// src/core/sources/cache.ts
|
|
5475
|
+
import { mkdir as mkdir2, readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
|
|
5476
|
+
import { join as join13 } from "pathe";
|
|
5477
|
+
var hashText = (text) => {
|
|
5478
|
+
let hash = 5381;
|
|
5479
|
+
for (let i = 0;i < text.length; i += 1) {
|
|
5480
|
+
hash = (hash * 33 + (text.codePointAt(i) ?? 0)) % 2147483647;
|
|
5481
|
+
}
|
|
5482
|
+
return hash.toString(36);
|
|
5483
|
+
};
|
|
5484
|
+
var entriesDigest = (entries) => hashText(entries.map((entry) => `${entry.ref}:${entry.hash ?? hashText(entry.body.text)}`).join("|"));
|
|
5485
|
+
var pollingWatch = (load2, intervalSeconds) => (onChange) => {
|
|
5486
|
+
let last = "";
|
|
5487
|
+
const tick = async () => {
|
|
5488
|
+
try {
|
|
5489
|
+
const { entries } = await load2();
|
|
5490
|
+
const next = entriesDigest(entries);
|
|
5491
|
+
if (last && next !== last) {
|
|
5492
|
+
onChange();
|
|
5493
|
+
}
|
|
5494
|
+
last = next;
|
|
5495
|
+
} catch {}
|
|
5496
|
+
};
|
|
5497
|
+
const timer = setInterval(() => {
|
|
5498
|
+
tick();
|
|
5499
|
+
}, intervalSeconds * 1000);
|
|
5500
|
+
return () => clearInterval(timer);
|
|
5501
|
+
};
|
|
5502
|
+
var snapshotCache = (cacheDir) => {
|
|
5503
|
+
const file = join13(cacheDir, "entries.json");
|
|
5504
|
+
return {
|
|
5505
|
+
read: async () => {
|
|
5506
|
+
try {
|
|
5507
|
+
return JSON.parse(await readFile6(file, "utf-8"));
|
|
5508
|
+
} catch {
|
|
5509
|
+
return [];
|
|
5510
|
+
}
|
|
5511
|
+
},
|
|
5512
|
+
write: async (entries) => {
|
|
5513
|
+
try {
|
|
5514
|
+
await mkdir2(cacheDir, { recursive: true });
|
|
5515
|
+
await writeFile3(file, `${JSON.stringify(entries)}
|
|
5516
|
+
`, "utf-8");
|
|
5517
|
+
} catch {}
|
|
5518
|
+
}
|
|
5519
|
+
};
|
|
5520
|
+
};
|
|
5521
|
+
var loadWithCache = async (name, cache, fetchEntries, refresh = true) => {
|
|
5522
|
+
if (!refresh) {
|
|
5523
|
+
const cached3 = await cache.read();
|
|
5524
|
+
if (cached3.length > 0) {
|
|
5525
|
+
return { diagnostics: [], entries: cached3 };
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
try {
|
|
5529
|
+
const entries = await fetchEntries();
|
|
5530
|
+
await cache.write(entries);
|
|
5531
|
+
return { diagnostics: [], entries };
|
|
5532
|
+
} catch (error) {
|
|
5533
|
+
const fallback = await cache.read();
|
|
5534
|
+
if (fallback.length > 0) {
|
|
5535
|
+
const diagnostic = {
|
|
5536
|
+
code: "BLUME_SOURCE_OFFLINE",
|
|
5537
|
+
message: `Source "${name}" could not be fetched (${error.message}); served ${fallback.length} cached entries.`,
|
|
5538
|
+
severity: "warning"
|
|
5539
|
+
};
|
|
5540
|
+
return { diagnostics: [diagnostic], entries: fallback };
|
|
5541
|
+
}
|
|
5542
|
+
throw new BlumeError({
|
|
5543
|
+
code: "BLUME_SOURCE_FETCH_FAILED",
|
|
5544
|
+
message: `Source "${name}" failed to load and no cache is available: ${error.message}`,
|
|
5545
|
+
severity: "error"
|
|
5546
|
+
});
|
|
5547
|
+
}
|
|
5548
|
+
};
|
|
5549
|
+
|
|
5550
|
+
// src/openapi/model.ts
|
|
5551
|
+
var NON_SLUG2 = /[^a-z0-9]+/gu;
|
|
5552
|
+
var SLUG_EDGES2 = /^-+|-+$/gu;
|
|
5553
|
+
var slugify2 = (text) => text.toLowerCase().replace(NON_SLUG2, "-").replace(SLUG_EDGES2, "");
|
|
5554
|
+
var HTTP_METHODS = [
|
|
5555
|
+
"get",
|
|
5556
|
+
"put",
|
|
5557
|
+
"post",
|
|
5558
|
+
"delete",
|
|
5559
|
+
"options",
|
|
5560
|
+
"head",
|
|
5561
|
+
"patch",
|
|
5562
|
+
"trace"
|
|
5563
|
+
];
|
|
5564
|
+
var UNTAGGED = "Operations";
|
|
5565
|
+
var operationKey = (method, path, operationId) => {
|
|
5566
|
+
const fromId = operationId ? slugify2(operationId) : "";
|
|
5567
|
+
return fromId || slugify2(`${method}-${path}`);
|
|
5568
|
+
};
|
|
5569
|
+
var isOperation = (value) => typeof value === "object" && value !== null;
|
|
5570
|
+
var extractOperations = (document, baseRoute) => {
|
|
5571
|
+
const operations = [];
|
|
5572
|
+
const tagOrder = [];
|
|
5573
|
+
const tagMeta = new Map((document.tags ?? []).map((tag) => [tag.name, tag.description ?? ""]));
|
|
5574
|
+
const seen = new Set;
|
|
5575
|
+
for (const [path, rawItem] of Object.entries(document.paths ?? {})) {
|
|
5576
|
+
const item = rawItem;
|
|
5577
|
+
if (!item || "$ref" in item) {
|
|
5578
|
+
continue;
|
|
5579
|
+
}
|
|
5580
|
+
for (const method of HTTP_METHODS) {
|
|
5581
|
+
const operation = item[method];
|
|
5582
|
+
if (!isOperation(operation)) {
|
|
5583
|
+
continue;
|
|
5584
|
+
}
|
|
5585
|
+
const tag = operation.tags?.[0] ?? UNTAGGED;
|
|
5586
|
+
const tagSlug = slugify2(tag) || "operations";
|
|
5587
|
+
if (!tagOrder.includes(tag)) {
|
|
5588
|
+
tagOrder.push(tag);
|
|
5589
|
+
}
|
|
5590
|
+
let key = operationKey(method, path, operation.operationId);
|
|
5591
|
+
while (seen.has(key)) {
|
|
5592
|
+
key = `${key}-${method}`;
|
|
5593
|
+
}
|
|
5594
|
+
seen.add(key);
|
|
5595
|
+
operations.push({
|
|
5596
|
+
deprecated: operation.deprecated ?? false,
|
|
5597
|
+
description: operation.description ?? "",
|
|
5598
|
+
key,
|
|
5599
|
+
method,
|
|
5600
|
+
operationId: operation.operationId,
|
|
5601
|
+
path,
|
|
5602
|
+
route: `${baseRoute}/${tagSlug}/${key}`,
|
|
5603
|
+
summary: operation.summary ?? "",
|
|
5604
|
+
tag,
|
|
5605
|
+
tagSlug
|
|
5606
|
+
});
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
const tags = tagOrder.map((name) => ({
|
|
5610
|
+
description: tagMeta.get(name) ?? "",
|
|
5611
|
+
name,
|
|
5612
|
+
slug: slugify2(name) || "operations"
|
|
5613
|
+
}));
|
|
5614
|
+
return { operations, tags };
|
|
5615
|
+
};
|
|
5616
|
+
|
|
5617
|
+
// src/openapi/parse.ts
|
|
5618
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
5619
|
+
import { normalize as normalize2, upgrade } from "@scalar/openapi-parser";
|
|
5620
|
+
import { isAbsolute as isAbsolute5, join as join14 } from "pathe";
|
|
5621
|
+
var URL_SPEC2 = /^https?:\/\//u;
|
|
5622
|
+
var readSpecText = async (spec, root) => {
|
|
5623
|
+
if (URL_SPEC2.test(spec)) {
|
|
5624
|
+
const response = await fetch(spec);
|
|
5625
|
+
if (!response.ok) {
|
|
5626
|
+
throw new Error(`${spec} -> ${response.status} ${response.statusText}`);
|
|
5627
|
+
}
|
|
5628
|
+
return await response.text();
|
|
5629
|
+
}
|
|
5630
|
+
const absolute = isAbsolute5(spec) ? spec : join14(root, spec);
|
|
5631
|
+
return await readFile7(absolute, "utf-8");
|
|
5632
|
+
};
|
|
5633
|
+
var parseSpec = async (spec, root) => {
|
|
5634
|
+
const text = await readSpecText(spec, root);
|
|
5635
|
+
const normalized = normalize2(text);
|
|
5636
|
+
const { specification } = upgrade(normalized);
|
|
5637
|
+
return { document: specification, warnings: [] };
|
|
5638
|
+
};
|
|
5639
|
+
|
|
5640
|
+
// src/openapi/render-mdx.ts
|
|
5641
|
+
var MDX_UNSAFE = /[<>{}]/gu;
|
|
5642
|
+
var ENTITIES = {
|
|
5643
|
+
"<": "<",
|
|
5644
|
+
">": ">",
|
|
5645
|
+
"{": "{",
|
|
5646
|
+
"}": "}"
|
|
5647
|
+
};
|
|
5648
|
+
var mdxSafe = (text) => text.replace(MDX_UNSAFE, (char) => ENTITIES[char] ?? char);
|
|
5649
|
+
var withDescription = (description, component) => description.trim() ? `${mdxSafe(description.trim())}
|
|
5650
|
+
|
|
5651
|
+
${component}` : component;
|
|
5652
|
+
var operationMdx = (spec, operation) => {
|
|
5653
|
+
const method = operation.method.toUpperCase();
|
|
5654
|
+
const title = operation.summary || `${method} ${operation.path}`;
|
|
5655
|
+
const description = operation.description.trim() === operation.summary.trim() ? "" : operation.description;
|
|
5656
|
+
return {
|
|
5657
|
+
body: withDescription(description, `<Operation source="${spec.slug}" id="${operation.key}" />`),
|
|
5658
|
+
data: {
|
|
5659
|
+
...operation.deprecated ? { deprecated: true } : {},
|
|
5660
|
+
search: { tags: [operation.tag, method] },
|
|
5661
|
+
sidebar: { badge: method, label: operation.summary || operation.path },
|
|
5662
|
+
title,
|
|
5663
|
+
type: "openapi-operation"
|
|
5664
|
+
}
|
|
5665
|
+
};
|
|
5666
|
+
};
|
|
5667
|
+
var overviewMdx = (spec) => ({
|
|
5668
|
+
body: withDescription(spec.description, `<ApiOverview source="${spec.slug}" />`),
|
|
5669
|
+
data: {
|
|
5670
|
+
sidebar: { label: "Overview" },
|
|
5671
|
+
title: spec.title || spec.label
|
|
5672
|
+
}
|
|
5673
|
+
});
|
|
5674
|
+
|
|
5675
|
+
// src/openapi/source.ts
|
|
5676
|
+
var isOpenApiSource = (source) => source.kind === "openapi-source";
|
|
5677
|
+
var routeToRef = (route) => route.replace(/^\/+/u, "");
|
|
5678
|
+
var toEntry = (rendered, ref) => {
|
|
5679
|
+
const raw = frontmatter_default.stringify(`${rendered.body}
|
|
5680
|
+
`, rendered.data);
|
|
5681
|
+
return {
|
|
5682
|
+
body: { format: "mdx", text: rendered.body },
|
|
5683
|
+
data: rendered.data,
|
|
5684
|
+
hash: hashText(raw),
|
|
5685
|
+
raw,
|
|
5686
|
+
ref
|
|
5687
|
+
};
|
|
5688
|
+
};
|
|
5689
|
+
var specEntries = (spec, operations) => {
|
|
5690
|
+
const entries = operations.map((operation) => toEntry(operationMdx(spec, operation), `${routeToRef(operation.route)}.mdx`));
|
|
5691
|
+
entries.push(toEntry(overviewMdx(spec), `${routeToRef(spec.route)}/index.mdx`));
|
|
5692
|
+
return entries;
|
|
5693
|
+
};
|
|
5694
|
+
var openApiSource = (references, ctx) => {
|
|
5695
|
+
let parsed = {};
|
|
5696
|
+
const loadReference = async (reference) => {
|
|
5697
|
+
try {
|
|
5698
|
+
const { document } = await parseSpec(reference.spec, ctx.projectRoot);
|
|
5699
|
+
const { operations, tags } = extractOperations(document, reference.route);
|
|
5700
|
+
const info = document.info ?? { title: reference.label, version: "" };
|
|
5701
|
+
const spec = {
|
|
5702
|
+
codeSamples: reference.display.codeSamples,
|
|
5703
|
+
description: info.description ?? "",
|
|
5704
|
+
document,
|
|
5705
|
+
expandSchemas: reference.display.expandSchemas,
|
|
5706
|
+
label: reference.label,
|
|
5707
|
+
operations: Object.fromEntries(operations.map((operation) => [operation.key, operation])),
|
|
5708
|
+
route: reference.route,
|
|
5709
|
+
slug: reference.slug,
|
|
5710
|
+
tags,
|
|
5711
|
+
title: info.title ?? reference.label,
|
|
5712
|
+
version: info.version ?? ""
|
|
5713
|
+
};
|
|
5714
|
+
return {
|
|
5715
|
+
entries: specEntries(spec, operations),
|
|
5716
|
+
slug: reference.slug,
|
|
5717
|
+
spec
|
|
5718
|
+
};
|
|
5719
|
+
} catch (error) {
|
|
5720
|
+
return {
|
|
5721
|
+
code: "BLUME_OPENAPI_UNAVAILABLE",
|
|
5722
|
+
message: `Could not load OpenAPI spec "${reference.spec}" for ${reference.route} (${error.message}); its reference pages were skipped.`,
|
|
5723
|
+
severity: "warning"
|
|
5724
|
+
};
|
|
5725
|
+
}
|
|
5726
|
+
};
|
|
5727
|
+
const load2 = async () => {
|
|
5728
|
+
const results = await Promise.all(references.map(loadReference));
|
|
5729
|
+
const entries = [];
|
|
5730
|
+
const diagnostics = [];
|
|
5731
|
+
const data = {};
|
|
5732
|
+
for (const result of results) {
|
|
5733
|
+
if ("severity" in result) {
|
|
5734
|
+
diagnostics.push(result);
|
|
5735
|
+
continue;
|
|
5736
|
+
}
|
|
5737
|
+
data[result.slug] = result.spec;
|
|
5738
|
+
entries.push(...result.entries);
|
|
5739
|
+
}
|
|
5740
|
+
parsed = data;
|
|
5741
|
+
return { diagnostics, entries };
|
|
5742
|
+
};
|
|
5743
|
+
return {
|
|
5744
|
+
kind: "openapi-source",
|
|
5745
|
+
load: load2,
|
|
5746
|
+
name: "openapi",
|
|
5747
|
+
openApiData: () => parsed,
|
|
5748
|
+
staged: true
|
|
5749
|
+
};
|
|
5392
5750
|
};
|
|
5393
5751
|
|
|
5394
5752
|
// src/theme/entry.ts
|
|
@@ -6011,8 +6369,8 @@ ${options.userTheme}
|
|
|
6011
6369
|
|
|
6012
6370
|
// src/theme/twoslash.ts
|
|
6013
6371
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
6014
|
-
import { createRequire as
|
|
6015
|
-
var require2 =
|
|
6372
|
+
import { createRequire as createRequire4 } from "node:module";
|
|
6373
|
+
var require2 = createRequire4(import.meta.url);
|
|
6016
6374
|
var OVERRIDES = `
|
|
6017
6375
|
/* Twoslash: theme the rich renderer with Blume tokens. */
|
|
6018
6376
|
:root {
|
|
@@ -6174,13 +6532,13 @@ export const layoutOverrides = { ...(overrides.layout ?? {})${layoutEntries.leng
|
|
|
6174
6532
|
};
|
|
6175
6533
|
|
|
6176
6534
|
// src/astro/examples.ts
|
|
6177
|
-
import { readFile as
|
|
6178
|
-
import { join as
|
|
6535
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
6536
|
+
import { join as join16, relative as relative4 } from "pathe";
|
|
6179
6537
|
import { glob as glob2 } from "tinyglobby";
|
|
6180
6538
|
|
|
6181
6539
|
// src/astro/islands.ts
|
|
6182
|
-
import { readFile as
|
|
6183
|
-
import { basename, join as
|
|
6540
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
6541
|
+
import { basename, join as join15 } from "pathe";
|
|
6184
6542
|
import { glob } from "tinyglobby";
|
|
6185
6543
|
var DEFAULT_CLIENT = "visible";
|
|
6186
6544
|
var VALID_MODES = new Set([
|
|
@@ -6209,14 +6567,14 @@ var readClientMode = (source, file, warnings) => {
|
|
|
6209
6567
|
return mode;
|
|
6210
6568
|
};
|
|
6211
6569
|
var discoverIslands = async (root) => {
|
|
6212
|
-
const dir =
|
|
6570
|
+
const dir = join15(root, "islands");
|
|
6213
6571
|
const matches = await glob(["**/*.{jsx,svelte,tsx,vue}"], {
|
|
6214
6572
|
absolute: true,
|
|
6215
6573
|
cwd: dir,
|
|
6216
6574
|
onlyFiles: true
|
|
6217
6575
|
});
|
|
6218
6576
|
const files = matches.toSorted();
|
|
6219
|
-
const sources = await Promise.all(files.map((file) =>
|
|
6577
|
+
const sources = await Promise.all(files.map((file) => readFile8(file, "utf-8")));
|
|
6220
6578
|
const islands = [];
|
|
6221
6579
|
const warnings = [];
|
|
6222
6580
|
const seen = new Map;
|
|
@@ -6272,14 +6630,14 @@ var splitGlobBase = (pattern) => {
|
|
|
6272
6630
|
};
|
|
6273
6631
|
var discoverExamples = async (root, pattern = "examples") => {
|
|
6274
6632
|
const { base, rest } = GLOB_MAGIC.test(pattern) ? splitGlobBase(pattern) : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };
|
|
6275
|
-
const dir =
|
|
6633
|
+
const dir = join16(root, base);
|
|
6276
6634
|
const matches = await glob2([rest], {
|
|
6277
6635
|
absolute: true,
|
|
6278
6636
|
cwd: dir,
|
|
6279
6637
|
onlyFiles: true
|
|
6280
6638
|
});
|
|
6281
6639
|
const files = matches.toSorted();
|
|
6282
|
-
const sources = await Promise.all(files.map((file) =>
|
|
6640
|
+
const sources = await Promise.all(files.map((file) => readFile9(file, "utf-8")));
|
|
6283
6641
|
const examples = [];
|
|
6284
6642
|
const warnings = [];
|
|
6285
6643
|
const seen = new Map;
|
|
@@ -6353,10 +6711,10 @@ var customOgRoutes = (pages, siteTitle) => {
|
|
|
6353
6711
|
};
|
|
6354
6712
|
|
|
6355
6713
|
// src/astro/generate.ts
|
|
6356
|
-
var BLUME_SRC =
|
|
6714
|
+
var BLUME_SRC = join17(packageRoot(), "src");
|
|
6357
6715
|
var canResolveFrom = (fromDir, spec) => {
|
|
6358
6716
|
try {
|
|
6359
|
-
|
|
6717
|
+
createRequire5(pathToFileURL2(join17(fromDir, "_.js")).href).resolve(spec);
|
|
6360
6718
|
return true;
|
|
6361
6719
|
} catch {
|
|
6362
6720
|
return false;
|
|
@@ -6364,15 +6722,15 @@ var canResolveFrom = (fromDir, spec) => {
|
|
|
6364
6722
|
};
|
|
6365
6723
|
var resolvedAstroPath = (fromDir) => {
|
|
6366
6724
|
try {
|
|
6367
|
-
const pkg =
|
|
6725
|
+
const pkg = createRequire5(pathToFileURL2(join17(fromDir, "_.js")).href).resolve("astro/package.json");
|
|
6368
6726
|
return realpathSync(pkg);
|
|
6369
6727
|
} catch {
|
|
6370
6728
|
return null;
|
|
6371
6729
|
}
|
|
6372
6730
|
};
|
|
6373
6731
|
var blumeDepsDir = (pkgDir = packageRoot()) => {
|
|
6374
|
-
const candidates = [
|
|
6375
|
-
return candidates.find((dir) =>
|
|
6732
|
+
const candidates = [join17(pkgDir, "node_modules"), dirname7(pkgDir)];
|
|
6733
|
+
return candidates.find((dir) => existsSync9(join17(dir, "astro"))) ?? null;
|
|
6376
6734
|
};
|
|
6377
6735
|
var linkDepsJunction = async (link, depsDir) => {
|
|
6378
6736
|
const existing = await lstat(link).catch(() => null);
|
|
@@ -6382,7 +6740,7 @@ var linkDepsJunction = async (link, depsDir) => {
|
|
|
6382
6740
|
}
|
|
6383
6741
|
await rm(link, { force: true });
|
|
6384
6742
|
}
|
|
6385
|
-
await
|
|
6743
|
+
await mkdir3(dirname7(link), { recursive: true });
|
|
6386
6744
|
await symlink(depsDir, link, "junction");
|
|
6387
6745
|
};
|
|
6388
6746
|
var readPkgVersion = (pkgJsonPath) => {
|
|
@@ -6412,8 +6770,8 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
|
6412
6770
|
if (blumeAstro && outDirAstro === blumeAstro) {
|
|
6413
6771
|
return null;
|
|
6414
6772
|
}
|
|
6415
|
-
if (
|
|
6416
|
-
await linkDepsJunction(
|
|
6773
|
+
if (existsSync9(join17(depsDir, "@astrojs", "mdx"))) {
|
|
6774
|
+
await linkDepsJunction(join17(outDir, "node_modules"), depsDir);
|
|
6417
6775
|
return null;
|
|
6418
6776
|
}
|
|
6419
6777
|
return astroConflictWarning(blumeAstro, outDirAstro);
|
|
@@ -6437,7 +6795,7 @@ var readOptional = async (path) => {
|
|
|
6437
6795
|
return "";
|
|
6438
6796
|
}
|
|
6439
6797
|
try {
|
|
6440
|
-
return await
|
|
6798
|
+
return await readFile10(path, "utf-8");
|
|
6441
6799
|
} catch {
|
|
6442
6800
|
return "";
|
|
6443
6801
|
}
|
|
@@ -6453,16 +6811,16 @@ var detectNeedsReact = async (root) => {
|
|
|
6453
6811
|
var writeIfChanged = async (path, content) => {
|
|
6454
6812
|
let existing = null;
|
|
6455
6813
|
try {
|
|
6456
|
-
existing = await
|
|
6814
|
+
existing = await readFile10(path, "utf-8");
|
|
6457
6815
|
} catch {
|
|
6458
6816
|
existing = null;
|
|
6459
6817
|
}
|
|
6460
6818
|
if (existing === content) {
|
|
6461
6819
|
return false;
|
|
6462
6820
|
}
|
|
6463
|
-
await
|
|
6821
|
+
await mkdir3(dirname7(path), { recursive: true });
|
|
6464
6822
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
6465
|
-
await
|
|
6823
|
+
await writeFile4(tmp, content, "utf-8");
|
|
6466
6824
|
try {
|
|
6467
6825
|
await rename(tmp, path);
|
|
6468
6826
|
} catch (error) {
|
|
@@ -6477,7 +6835,7 @@ var pruneOrphans = async (srcDir, written) => {
|
|
|
6477
6835
|
cwd: srcDir,
|
|
6478
6836
|
onlyFiles: true
|
|
6479
6837
|
});
|
|
6480
|
-
await Promise.all(existing.map((path) =>
|
|
6838
|
+
await Promise.all(existing.map((path) => normalize3(path)).filter((path) => !written.has(path)).map((path) => rm(path, { force: true })));
|
|
6481
6839
|
};
|
|
6482
6840
|
var collectStaged = (project) => {
|
|
6483
6841
|
const staged = new Map;
|
|
@@ -6492,11 +6850,11 @@ var writeStagedContent = async (out, staged) => {
|
|
|
6492
6850
|
const contentDir = stagedContentDir(out);
|
|
6493
6851
|
const written = new Set;
|
|
6494
6852
|
await Promise.all([...staged].map(async ([entryId, text]) => {
|
|
6495
|
-
const path =
|
|
6496
|
-
written.add(
|
|
6853
|
+
const path = join17(contentDir, entryId);
|
|
6854
|
+
written.add(normalize3(path));
|
|
6497
6855
|
await writeIfChanged(path, text);
|
|
6498
6856
|
}));
|
|
6499
|
-
if (
|
|
6857
|
+
if (existsSync9(contentDir)) {
|
|
6500
6858
|
await pruneOrphans(contentDir, written);
|
|
6501
6859
|
}
|
|
6502
6860
|
};
|
|
@@ -6513,9 +6871,9 @@ var resolveLogo = (project) => {
|
|
|
6513
6871
|
if (light && light === dark && light.toLowerCase().endsWith(".svg")) {
|
|
6514
6872
|
const rel = light.replace(/^\//u, "");
|
|
6515
6873
|
const file = [
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
].find((path) =>
|
|
6874
|
+
join17(project.context.root, "public", rel),
|
|
6875
|
+
join17(project.context.root, rel)
|
|
6876
|
+
].find((path) => existsSync9(path));
|
|
6519
6877
|
if (file) {
|
|
6520
6878
|
return { alt, href, svg: readFileSync6(file, "utf-8") };
|
|
6521
6879
|
}
|
|
@@ -6543,7 +6901,7 @@ var faviconType = (name) => {
|
|
|
6543
6901
|
};
|
|
6544
6902
|
var inlineDataUri = (file, type) => `data:${type};base64,${readFileSync6(file).toString("base64")}`;
|
|
6545
6903
|
var defaultFavicon = () => ({
|
|
6546
|
-
href: inlineDataUri(
|
|
6904
|
+
href: inlineDataUri(join17(BLUME_SRC, "assets", "icon.png"), "image/png"),
|
|
6547
6905
|
type: "image/png"
|
|
6548
6906
|
});
|
|
6549
6907
|
var APPLE_ICON_CANDIDATES = [
|
|
@@ -6555,13 +6913,13 @@ var APPLE_ICON_CANDIDATES = [
|
|
|
6555
6913
|
var resolveIconFile = (project, candidates) => {
|
|
6556
6914
|
const { root } = project.context;
|
|
6557
6915
|
for (const name of candidates) {
|
|
6558
|
-
if (
|
|
6916
|
+
if (existsSync9(join17(root, "public", name))) {
|
|
6559
6917
|
return { href: `/${name}`, type: faviconType(name) };
|
|
6560
6918
|
}
|
|
6561
6919
|
}
|
|
6562
6920
|
for (const name of candidates) {
|
|
6563
|
-
const file =
|
|
6564
|
-
if (
|
|
6921
|
+
const file = join17(root, name);
|
|
6922
|
+
if (existsSync9(file)) {
|
|
6565
6923
|
const type = faviconType(name);
|
|
6566
6924
|
return { href: inlineDataUri(file, type ?? "image/x-icon"), type };
|
|
6567
6925
|
}
|
|
@@ -6643,6 +7001,7 @@ var buildRuntimeData = (project) => {
|
|
|
6643
7001
|
label
|
|
6644
7002
|
}))
|
|
6645
7003
|
} : null,
|
|
7004
|
+
icons: config.icons,
|
|
6646
7005
|
imageZoom: config.markdown.imageZoom,
|
|
6647
7006
|
logo: resolveLogo(project),
|
|
6648
7007
|
mcp: config.mcp.enabled ? { name: config.mcp.name ?? config.title, route: config.mcp.route } : null,
|
|
@@ -6689,7 +7048,7 @@ var buildRuntimeData = (project) => {
|
|
|
6689
7048
|
var planMcp = (project, srcDir) => {
|
|
6690
7049
|
const { config } = project;
|
|
6691
7050
|
const { route } = config.mcp;
|
|
6692
|
-
const dir =
|
|
7051
|
+
const dir = join17(srcDir, "blume-mcp");
|
|
6693
7052
|
const base = {
|
|
6694
7053
|
dir,
|
|
6695
7054
|
discoveryPages: [],
|
|
@@ -6713,11 +7072,11 @@ var planMcp = (project, srcDir) => {
|
|
|
6713
7072
|
...base,
|
|
6714
7073
|
discoveryPages: [
|
|
6715
7074
|
{
|
|
6716
|
-
entrypoint:
|
|
7075
|
+
entrypoint: join17(dir, "discovery.ts"),
|
|
6717
7076
|
pattern: "/.well-known/mcp.json"
|
|
6718
7077
|
},
|
|
6719
7078
|
{
|
|
6720
|
-
entrypoint:
|
|
7079
|
+
entrypoint: join17(dir, "server-card.ts"),
|
|
6721
7080
|
pattern: "/.well-known/mcp/server-card.json"
|
|
6722
7081
|
}
|
|
6723
7082
|
],
|
|
@@ -6736,11 +7095,11 @@ var writeMcpFiles = async (project, plan, write) => {
|
|
|
6736
7095
|
version: data.version
|
|
6737
7096
|
};
|
|
6738
7097
|
await Promise.all([
|
|
6739
|
-
write(
|
|
7098
|
+
write(join17(plan.srcDir, "generated", "mcp-data.json"), `${JSON.stringify(data)}
|
|
6740
7099
|
`),
|
|
6741
|
-
write(
|
|
6742
|
-
write(
|
|
6743
|
-
write(
|
|
7100
|
+
write(join17(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate(plan.route)),
|
|
7101
|
+
write(join17(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
|
|
7102
|
+
write(join17(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
|
|
6744
7103
|
]);
|
|
6745
7104
|
};
|
|
6746
7105
|
var writeAskFiles = async (project, srcDir, write) => {
|
|
@@ -6750,16 +7109,16 @@ var writeAskFiles = async (project, srcDir, write) => {
|
|
|
6750
7109
|
}
|
|
6751
7110
|
const grounded = ask.provider !== "inkeep";
|
|
6752
7111
|
if (grounded) {
|
|
6753
|
-
await write(
|
|
7112
|
+
await write(join17(srcDir, "generated", "ask-data.json"), `${JSON.stringify(await buildAskData(project))}
|
|
6754
7113
|
`);
|
|
6755
7114
|
}
|
|
6756
|
-
await write(
|
|
7115
|
+
await write(join17(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(resolveAskBackend(ask), grounded));
|
|
6757
7116
|
};
|
|
6758
7117
|
var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
|
|
6759
7118
|
if (routeIsTaken(pages, contentPages, "/404")) {
|
|
6760
7119
|
return;
|
|
6761
7120
|
}
|
|
6762
|
-
await write(
|
|
7121
|
+
await write(join17(srcDir, "pages", "404.astro"), notFoundPageTemplate());
|
|
6763
7122
|
};
|
|
6764
7123
|
var shouldGenerateChangelog = (project) => {
|
|
6765
7124
|
const hasChangelog = project.graph.pages.some((page) => page.contentType === "changelog" && !(page.meta.draft || page.meta.sidebar.hidden));
|
|
@@ -6768,7 +7127,7 @@ var shouldGenerateChangelog = (project) => {
|
|
|
6768
7127
|
return (hasChangelog || hasChangelogSource) && !changelogRouteTaken;
|
|
6769
7128
|
};
|
|
6770
7129
|
var buildComponentSlots = async (componentsFile) => {
|
|
6771
|
-
const analysis = componentsFile ? analyzeComponentOverrides(await
|
|
7130
|
+
const analysis = componentsFile ? analyzeComponentOverrides(await readFile10(componentsFile, "utf-8"), componentsFile) : null;
|
|
6772
7131
|
return {
|
|
6773
7132
|
plan: planComponentSlots(componentsFile, analysis),
|
|
6774
7133
|
tags: analysis ? [...analysis.mdx, ...analysis.islands].map((entry) => entry.key) : [],
|
|
@@ -6778,14 +7137,15 @@ var buildComponentSlots = async (componentsFile) => {
|
|
|
6778
7137
|
var generateRuntime = async (project) => {
|
|
6779
7138
|
const { context, config } = project;
|
|
6780
7139
|
const out = context.outDir;
|
|
6781
|
-
const srcDir =
|
|
6782
|
-
const dataPath =
|
|
6783
|
-
const themePath =
|
|
6784
|
-
const searchClientPath =
|
|
6785
|
-
const examplesPath =
|
|
7140
|
+
const srcDir = join17(out, "src");
|
|
7141
|
+
const dataPath = join17(srcDir, "generated", "data.json");
|
|
7142
|
+
const themePath = join17(srcDir, "generated", "app.css");
|
|
7143
|
+
const searchClientPath = join17(srcDir, "generated", "search-client.ts");
|
|
7144
|
+
const examplesPath = join17(srcDir, "generated", "examples.ts");
|
|
7145
|
+
const openapiPath = join17(srcDir, "generated", "openapi.json");
|
|
6786
7146
|
const written = new Set;
|
|
6787
7147
|
const write = (path, content) => {
|
|
6788
|
-
written.add(
|
|
7148
|
+
written.add(normalize3(path));
|
|
6789
7149
|
return writeIfChanged(path, content);
|
|
6790
7150
|
};
|
|
6791
7151
|
const depsLinkWarning = await ensureDepsLink(out);
|
|
@@ -6818,7 +7178,7 @@ var generateRuntime = async (project) => {
|
|
|
6818
7178
|
const staged = collectStaged(project);
|
|
6819
7179
|
const hasStaged = staged.size > 0;
|
|
6820
7180
|
const structural = await Promise.all([
|
|
6821
|
-
write(
|
|
7181
|
+
write(join17(out, "astro.config.mjs"), astroConfigTemplate({
|
|
6822
7182
|
aliases: resolveTsconfigAliases(context.root),
|
|
6823
7183
|
config,
|
|
6824
7184
|
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
@@ -6828,24 +7188,25 @@ var generateRuntime = async (project) => {
|
|
|
6828
7188
|
needsReact,
|
|
6829
7189
|
needsSvelte,
|
|
6830
7190
|
needsVue,
|
|
7191
|
+
openapiPath,
|
|
6831
7192
|
pages,
|
|
6832
7193
|
searchClientPath,
|
|
6833
7194
|
themePath
|
|
6834
7195
|
})),
|
|
6835
|
-
write(
|
|
6836
|
-
write(
|
|
6837
|
-
write(
|
|
6838
|
-
write(
|
|
6839
|
-
write(
|
|
7196
|
+
write(join17(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
|
|
7197
|
+
write(join17(out, "tsconfig.json"), runtimeTsconfigTemplate()),
|
|
7198
|
+
write(join17(srcDir, "env.d.ts"), envTemplate()),
|
|
7199
|
+
write(join17(srcDir, "content.config.ts"), contentConfigTemplate({ config, context, staged: hasStaged })),
|
|
7200
|
+
write(join17(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
|
|
6840
7201
|
askEnabled,
|
|
6841
7202
|
exportEpub,
|
|
6842
7203
|
exportPdf,
|
|
6843
7204
|
mathEnabled: config.markdown.math,
|
|
6844
7205
|
needsReact
|
|
6845
7206
|
})),
|
|
6846
|
-
write(
|
|
6847
|
-
write(
|
|
6848
|
-
write(
|
|
7207
|
+
write(join17(srcDir, "generated", "components.ts"), slotPlan.module),
|
|
7208
|
+
write(join17(srcDir, "generated", "islands.ts"), islandMapTemplate(islandDiscovery.islands)),
|
|
7209
|
+
write(join17(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples)),
|
|
6849
7210
|
write(themePath, tailwindEntryTemplate({
|
|
6850
7211
|
configTokens: `${buildThemeCss(config.theme)}${buildFontsCss(config.theme.fonts)}`,
|
|
6851
7212
|
sources: [
|
|
@@ -6856,16 +7217,16 @@ var generateRuntime = async (project) => {
|
|
|
6856
7217
|
userTheme
|
|
6857
7218
|
}))
|
|
6858
7219
|
]);
|
|
6859
|
-
await Promise.all(islandDiscovery.islands.map((island) => write(
|
|
6860
|
-
await Promise.all(slotPlan.wrappers.map((wrapper) => write(
|
|
6861
|
-
await Promise.all(exampleDiscovery.examples.map((example) => write(
|
|
7220
|
+
await Promise.all(islandDiscovery.islands.map((island) => write(join17(srcDir, "generated", "islands", `${island.name}.astro`), islandWrapperTemplate(island))));
|
|
7221
|
+
await Promise.all(slotPlan.wrappers.map((wrapper) => write(join17(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content)));
|
|
7222
|
+
await Promise.all(exampleDiscovery.examples.map((example) => write(join17(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example))));
|
|
6862
7223
|
await writeAskFiles(project, srcDir, write);
|
|
6863
7224
|
await writeMcpFiles(project, mcp, write);
|
|
6864
7225
|
if (config.seo.og.enabled) {
|
|
6865
|
-
await write(
|
|
7226
|
+
await write(join17(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes));
|
|
6866
7227
|
}
|
|
6867
7228
|
if (shouldGenerateChangelog(project)) {
|
|
6868
|
-
await write(
|
|
7229
|
+
await write(join17(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
|
|
6869
7230
|
askEnabled,
|
|
6870
7231
|
exportEpub,
|
|
6871
7232
|
exportPdf,
|
|
@@ -6877,27 +7238,27 @@ var generateRuntime = async (project) => {
|
|
|
6877
7238
|
await write(searchClientPath, searchClientTemplate(config));
|
|
6878
7239
|
if (servesStaticIndex(config.search.provider)) {
|
|
6879
7240
|
const documents = await buildSearchDocuments(project);
|
|
6880
|
-
await write(
|
|
7241
|
+
await write(join17(srcDir, "generated", "search.json"), `${JSON.stringify(documents)}
|
|
6881
7242
|
`);
|
|
6882
|
-
await write(
|
|
7243
|
+
await write(join17(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
|
|
6883
7244
|
}
|
|
6884
7245
|
if (config.search.provider === "mixedbread") {
|
|
6885
|
-
await write(
|
|
7246
|
+
await write(join17(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""));
|
|
6886
7247
|
}
|
|
6887
7248
|
const rawMarkdown = await buildRawMarkdown(project);
|
|
6888
7249
|
await Promise.all([
|
|
6889
|
-
write(
|
|
7250
|
+
write(join17(srcDir, "generated", "raw-markdown.json"), `${JSON.stringify(rawMarkdown)}
|
|
6890
7251
|
`),
|
|
6891
|
-
write(
|
|
6892
|
-
write(
|
|
7252
|
+
write(join17(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate()),
|
|
7253
|
+
write(join17(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate())
|
|
6893
7254
|
]);
|
|
6894
7255
|
const feeds = buildRssFeeds(project);
|
|
6895
7256
|
if (feeds.length > 0) {
|
|
6896
7257
|
const feedXml = Object.fromEntries(feeds.map((feed) => [feed.type, renderRssFeed(feed)]));
|
|
6897
7258
|
await Promise.all([
|
|
6898
|
-
write(
|
|
7259
|
+
write(join17(srcDir, "generated", "rss.json"), `${JSON.stringify(feedXml)}
|
|
6899
7260
|
`),
|
|
6900
|
-
write(
|
|
7261
|
+
write(join17(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate())
|
|
6901
7262
|
]);
|
|
6902
7263
|
}
|
|
6903
7264
|
const warnings = [
|
|
@@ -6927,17 +7288,20 @@ var generateRuntime = async (project) => {
|
|
|
6927
7288
|
}
|
|
6928
7289
|
}
|
|
6929
7290
|
warnings.push(...islandFrameworkWarnings(frameworks, context.root));
|
|
6930
|
-
if (
|
|
7291
|
+
if (hasScalarReferences(config)) {
|
|
6931
7292
|
const references = await buildReferenceFiles({
|
|
6932
7293
|
config,
|
|
6933
7294
|
contentRoutes: new Set(project.graph.pages.map((page) => page.route)),
|
|
6934
7295
|
root: context.root
|
|
6935
7296
|
});
|
|
6936
7297
|
warnings.push(...references.warnings);
|
|
6937
|
-
await Promise.all(references.files.map((file) => write(
|
|
7298
|
+
await Promise.all(references.files.map((file) => write(join17(srcDir, "pages", file.pagePath), file.content)));
|
|
6938
7299
|
}
|
|
6939
|
-
await write(
|
|
6940
|
-
|
|
7300
|
+
await write(join17(srcDir, "generated", "data.json"), buildRuntimeData(project));
|
|
7301
|
+
const openApiSource2 = project.sources.find(isOpenApiSource);
|
|
7302
|
+
await write(openapiPath, `${JSON.stringify(openApiSource2 ? openApiSource2.openApiData() : {})}
|
|
7303
|
+
`);
|
|
7304
|
+
await write(join17(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
|
|
6941
7305
|
`);
|
|
6942
7306
|
await writeStagedContent(out, staged);
|
|
6943
7307
|
await pruneOrphans(srcDir, written);
|
|
@@ -6945,12 +7309,12 @@ var generateRuntime = async (project) => {
|
|
|
6945
7309
|
};
|
|
6946
7310
|
|
|
6947
7311
|
// src/core/config.ts
|
|
6948
|
-
import { existsSync as
|
|
7312
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
6949
7313
|
|
|
6950
7314
|
// src/core/bridge.ts
|
|
6951
|
-
import { existsSync as
|
|
6952
|
-
import { readFile as
|
|
6953
|
-
import { join as
|
|
7315
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
7316
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
7317
|
+
import { join as join18 } from "pathe";
|
|
6954
7318
|
|
|
6955
7319
|
// src/migrate/mintlify/assets.ts
|
|
6956
7320
|
var assetRefs = (config) => {
|
|
@@ -6985,8 +7349,8 @@ var assetSegments = (config) => {
|
|
|
6985
7349
|
};
|
|
6986
7350
|
|
|
6987
7351
|
// src/migrate/mintlify/config.ts
|
|
6988
|
-
import { readFile as
|
|
6989
|
-
import { dirname as dirname8, relative as relative7, resolve as
|
|
7352
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
7353
|
+
import { dirname as dirname8, relative as relative7, resolve as resolve5 } from "pathe";
|
|
6990
7354
|
var MINTLIFY_DEFAULT_IGNORES = [
|
|
6991
7355
|
"**/_*",
|
|
6992
7356
|
"**/.*",
|
|
@@ -7027,7 +7391,7 @@ var isInsideRoot = (root, candidate) => {
|
|
|
7027
7391
|
};
|
|
7028
7392
|
var readJsonFile = async (file) => {
|
|
7029
7393
|
try {
|
|
7030
|
-
return JSON.parse(await
|
|
7394
|
+
return JSON.parse(await readFile11(file, "utf-8"));
|
|
7031
7395
|
} catch (error) {
|
|
7032
7396
|
throw new BlumeError({
|
|
7033
7397
|
code: "BLUME_MINTLIFY_CONFIG_INVALID",
|
|
@@ -7047,7 +7411,7 @@ var resolveRefs = async (value, options) => {
|
|
|
7047
7411
|
}
|
|
7048
7412
|
const ref = asString(object.$ref);
|
|
7049
7413
|
if (ref) {
|
|
7050
|
-
const refFile =
|
|
7414
|
+
const refFile = resolve5(dirname8(options.file), ref);
|
|
7051
7415
|
if (!isInsideRoot(options.root, refFile)) {
|
|
7052
7416
|
throw new BlumeError({
|
|
7053
7417
|
code: "BLUME_MINTLIFY_REF_OUTSIDE_ROOT",
|
|
@@ -7403,13 +7767,15 @@ var mintlifySelectors = (spec) => {
|
|
|
7403
7767
|
};
|
|
7404
7768
|
var mintignorePatterns = async (root) => {
|
|
7405
7769
|
try {
|
|
7406
|
-
const raw = await
|
|
7770
|
+
const raw = await readFile11(resolve5(root, ".mintignore"), "utf-8");
|
|
7407
7771
|
return raw.split(`
|
|
7408
7772
|
`).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).filter((line) => !line.startsWith("!")).map((line) => line.endsWith("/") ? `${line}**` : line);
|
|
7409
7773
|
} catch {
|
|
7410
7774
|
return [];
|
|
7411
7775
|
}
|
|
7412
7776
|
};
|
|
7777
|
+
var REDIRECT_PARAM = /:(?<name>[A-Za-z_]\w*)(?<modifier>[*+?])?/gu;
|
|
7778
|
+
var toAstroRedirectPath = (path) => path.replaceAll(REDIRECT_PARAM, (_match, name, modifier) => modifier === "*" || modifier === "+" ? `[...${name}]` : `[${name}]`);
|
|
7413
7779
|
var mintlifyRedirects = (spec) => asArray(spec.redirects).flatMap((redirect) => {
|
|
7414
7780
|
const object = asObject(redirect);
|
|
7415
7781
|
if (!object) {
|
|
@@ -7420,8 +7786,72 @@ var mintlifyRedirects = (spec) => asArray(spec.redirects).flatMap((redirect) =>
|
|
|
7420
7786
|
if (!from || !to) {
|
|
7421
7787
|
return [];
|
|
7422
7788
|
}
|
|
7423
|
-
return [{ from, to }];
|
|
7789
|
+
return [{ from: toAstroRedirectPath(from), to: toAstroRedirectPath(to) }];
|
|
7424
7790
|
});
|
|
7791
|
+
var openapiRouteFromDirectory = (value) => {
|
|
7792
|
+
const directory = normalizeDirectory(asString(value) ?? "");
|
|
7793
|
+
return directory.length > 0 ? `/${directory}` : undefined;
|
|
7794
|
+
};
|
|
7795
|
+
var openapiSourcesFromValue = (value, context) => {
|
|
7796
|
+
if (typeof value === "string") {
|
|
7797
|
+
if (value.length === 0 || API_ENDPOINT_REF.test(value)) {
|
|
7798
|
+
return [];
|
|
7799
|
+
}
|
|
7800
|
+
return [
|
|
7801
|
+
withoutUndefined({
|
|
7802
|
+
label: context.label,
|
|
7803
|
+
route: context.route,
|
|
7804
|
+
spec: value
|
|
7805
|
+
})
|
|
7806
|
+
];
|
|
7807
|
+
}
|
|
7808
|
+
if (Array.isArray(value)) {
|
|
7809
|
+
return value.flatMap((item) => openapiSourcesFromValue(item, context));
|
|
7810
|
+
}
|
|
7811
|
+
const object = asObject(value);
|
|
7812
|
+
if (!object) {
|
|
7813
|
+
return [];
|
|
7814
|
+
}
|
|
7815
|
+
return openapiSourcesFromValue(object.source ?? object.openapi, {
|
|
7816
|
+
label: context.label,
|
|
7817
|
+
route: openapiRouteFromDirectory(object.directory) ?? context.route
|
|
7818
|
+
});
|
|
7819
|
+
};
|
|
7820
|
+
var mintlifyOpenapi = (spec) => {
|
|
7821
|
+
const drafts = [];
|
|
7822
|
+
const visit = (node) => {
|
|
7823
|
+
if (Array.isArray(node)) {
|
|
7824
|
+
for (const item of node) {
|
|
7825
|
+
visit(item);
|
|
7826
|
+
}
|
|
7827
|
+
return;
|
|
7828
|
+
}
|
|
7829
|
+
const object = asObject(node);
|
|
7830
|
+
if (!object) {
|
|
7831
|
+
return;
|
|
7832
|
+
}
|
|
7833
|
+
if (hasOwn(object, "openapi")) {
|
|
7834
|
+
drafts.push(...openapiSourcesFromValue(object.openapi, {
|
|
7835
|
+
label: labelForNavItem(object)
|
|
7836
|
+
}));
|
|
7837
|
+
}
|
|
7838
|
+
for (const children of childNavigationArrays(object)) {
|
|
7839
|
+
visit(children);
|
|
7840
|
+
}
|
|
7841
|
+
};
|
|
7842
|
+
visit(spec.navigation);
|
|
7843
|
+
drafts.push(...openapiSourcesFromValue(spec.openapi, {}));
|
|
7844
|
+
drafts.push(...openapiSourcesFromValue(asObject(spec.api)?.openapi, {}));
|
|
7845
|
+
const seen = new Set;
|
|
7846
|
+
const sources = drafts.flatMap((draft) => {
|
|
7847
|
+
if (seen.has(draft.spec)) {
|
|
7848
|
+
return [];
|
|
7849
|
+
}
|
|
7850
|
+
seen.add(draft.spec);
|
|
7851
|
+
return [draft];
|
|
7852
|
+
});
|
|
7853
|
+
return sources.length > 0 ? { enabled: true, sources } : undefined;
|
|
7854
|
+
};
|
|
7425
7855
|
var mintlifyLogo = (value) => {
|
|
7426
7856
|
if (typeof value === "string") {
|
|
7427
7857
|
return value;
|
|
@@ -7453,6 +7883,12 @@ var mintlifyFavicon = (value) => {
|
|
|
7453
7883
|
}
|
|
7454
7884
|
return withoutUndefined({ dark, light });
|
|
7455
7885
|
};
|
|
7886
|
+
var mintlifyIcons = (value) => {
|
|
7887
|
+
const library = asString(asObject(value)?.library);
|
|
7888
|
+
return {
|
|
7889
|
+
library: library === "lucide" || library === "tabler" ? library : "fontawesome"
|
|
7890
|
+
};
|
|
7891
|
+
};
|
|
7456
7892
|
var mintlifyBanner = (value) => {
|
|
7457
7893
|
const object = asObject(value);
|
|
7458
7894
|
const content = object ? asString(object.content) : undefined;
|
|
@@ -7543,6 +7979,27 @@ var mintlifyMarkdown = (value, styling) => {
|
|
|
7543
7979
|
schema: object?.schema === false ? false : undefined
|
|
7544
7980
|
});
|
|
7545
7981
|
};
|
|
7982
|
+
var FAMILY_TO_SLUG = Object.fromEntries(Object.entries(GOOGLE_FONTS).map(([slug, def]) => [
|
|
7983
|
+
def.family.toLowerCase(),
|
|
7984
|
+
slug
|
|
7985
|
+
]));
|
|
7986
|
+
var fontSlugForFamily = (value) => {
|
|
7987
|
+
const family = asString(value);
|
|
7988
|
+
return family ? FAMILY_TO_SLUG[family.toLowerCase()] : undefined;
|
|
7989
|
+
};
|
|
7990
|
+
var mintlifyFonts = (value) => {
|
|
7991
|
+
const object = asObject(value);
|
|
7992
|
+
if (!object) {
|
|
7993
|
+
return;
|
|
7994
|
+
}
|
|
7995
|
+
const heading = asObject(object.heading);
|
|
7996
|
+
const body = asObject(object.body);
|
|
7997
|
+
const fonts = withoutUndefined({
|
|
7998
|
+
body: fontSlugForFamily(body?.family) ?? fontSlugForFamily(object.family),
|
|
7999
|
+
display: fontSlugForFamily(heading?.family) ?? fontSlugForFamily(object.family)
|
|
8000
|
+
});
|
|
8001
|
+
return Object.keys(fonts).length > 0 ? fonts : undefined;
|
|
8002
|
+
};
|
|
7546
8003
|
var mintlifySeo = (value) => {
|
|
7547
8004
|
const object = asObject(value);
|
|
7548
8005
|
const metatags = asObject(object?.metatags);
|
|
@@ -7554,8 +8011,8 @@ var mintlifySeo = (value) => {
|
|
|
7554
8011
|
};
|
|
7555
8012
|
};
|
|
7556
8013
|
var loadMintlifyConfig = async (root, file) => {
|
|
7557
|
-
const projectRoot =
|
|
7558
|
-
const configFile =
|
|
8014
|
+
const projectRoot = resolve5(root);
|
|
8015
|
+
const configFile = resolve5(file);
|
|
7559
8016
|
const spec = asObject(await resolveRefs(await readJsonFile(configFile), {
|
|
7560
8017
|
file: configFile,
|
|
7561
8018
|
root: projectRoot,
|
|
@@ -7588,6 +8045,7 @@ var loadMintlifyConfig = async (root, file) => {
|
|
|
7588
8045
|
},
|
|
7589
8046
|
description: asString(spec.description),
|
|
7590
8047
|
favicon: mintlifyFavicon(spec.favicon),
|
|
8048
|
+
icons: mintlifyIcons(spec.icons),
|
|
7591
8049
|
logo: mintlifyLogo(spec.logo),
|
|
7592
8050
|
markdown: mintlifyMarkdown(spec.markdown, styling),
|
|
7593
8051
|
navigation: {
|
|
@@ -7597,6 +8055,7 @@ var loadMintlifyConfig = async (root, file) => {
|
|
|
7597
8055
|
sidebarVariants: await mintlifySidebarVariants(spec),
|
|
7598
8056
|
tabs: mintlifyTabs(spec)
|
|
7599
8057
|
},
|
|
8058
|
+
openapi: mintlifyOpenapi(spec),
|
|
7600
8059
|
redirects: mintlifyRedirects(spec),
|
|
7601
8060
|
search: {
|
|
7602
8061
|
indexing: {
|
|
@@ -7614,6 +8073,7 @@ var loadMintlifyConfig = async (root, file) => {
|
|
|
7614
8073
|
backgroundDecoration: mintlifyBackgroundDecoration(spec.background),
|
|
7615
8074
|
backgroundImage: backgroundImage.light,
|
|
7616
8075
|
backgroundImageDark: backgroundImage.dark,
|
|
8076
|
+
fonts: mintlifyFonts(spec.fonts ?? spec.font),
|
|
7617
8077
|
mode: appearance.default === "light" || appearance.default === "dark" || appearance.default === "system" ? appearance.default : "system",
|
|
7618
8078
|
strict: appearance.strict === true
|
|
7619
8079
|
},
|
|
@@ -7651,12 +8111,12 @@ var mintlifyI18n = (spec) => {
|
|
|
7651
8111
|
// src/core/bridge.ts
|
|
7652
8112
|
var MINTLIFY_CONFIG_FILES = ["docs.json", "mint.json"];
|
|
7653
8113
|
var detectMintlifyBridge = async (root) => {
|
|
7654
|
-
const configFile = MINTLIFY_CONFIG_FILES.map((name) =>
|
|
8114
|
+
const configFile = MINTLIFY_CONFIG_FILES.map((name) => join18(root, name)).find((candidate) => existsSync10(candidate));
|
|
7655
8115
|
if (!configFile) {
|
|
7656
8116
|
return null;
|
|
7657
8117
|
}
|
|
7658
8118
|
const config = await loadMintlifyConfig(root, configFile);
|
|
7659
|
-
const spec = JSON.parse(await
|
|
8119
|
+
const spec = JSON.parse(await readFile12(configFile, "utf-8"));
|
|
7660
8120
|
const i18n = mintlifyI18n(spec);
|
|
7661
8121
|
if (i18n) {
|
|
7662
8122
|
config.i18n = i18n;
|
|
@@ -7667,7 +8127,7 @@ var detectMintlifyBridge = async (root) => {
|
|
|
7667
8127
|
const variables = config.variables ?? {};
|
|
7668
8128
|
const root_ = config.content?.root ?? ".";
|
|
7669
8129
|
const exclude = config.content?.exclude ?? [];
|
|
7670
|
-
const assets = assetSegments(config).filter((segment) => segment !== "public" &&
|
|
8130
|
+
const assets = assetSegments(config).filter((segment) => segment !== "public" && existsSync10(join18(root, segment)));
|
|
7671
8131
|
return {
|
|
7672
8132
|
configFile,
|
|
7673
8133
|
raw: {
|
|
@@ -7741,42 +8201,6 @@ var createModuleLoader = () => {
|
|
|
7741
8201
|
};
|
|
7742
8202
|
};
|
|
7743
8203
|
|
|
7744
|
-
// src/core/project.ts
|
|
7745
|
-
import { existsSync as existsSync9 } from "node:fs";
|
|
7746
|
-
import { isAbsolute as isAbsolute4, join as join15, resolve as resolve5 } from "pathe";
|
|
7747
|
-
var CONFIG_FILENAMES = [
|
|
7748
|
-
"blume.config.ts",
|
|
7749
|
-
"blume.config.mjs",
|
|
7750
|
-
"blume.config.js"
|
|
7751
|
-
];
|
|
7752
|
-
var THEME_FILENAMES = ["theme.css"];
|
|
7753
|
-
var COMPONENTS_FILENAMES = ["components.tsx", "components.ts"];
|
|
7754
|
-
var firstExisting = (root, names) => {
|
|
7755
|
-
for (const name of names) {
|
|
7756
|
-
const candidate = join15(root, name);
|
|
7757
|
-
if (existsSync9(candidate)) {
|
|
7758
|
-
return candidate;
|
|
7759
|
-
}
|
|
7760
|
-
}
|
|
7761
|
-
return null;
|
|
7762
|
-
};
|
|
7763
|
-
var findConfigFile = (root) => firstExisting(root, CONFIG_FILENAMES);
|
|
7764
|
-
var resolveProjectContext = (root, config) => {
|
|
7765
|
-
const absoluteRoot = resolve5(root);
|
|
7766
|
-
const contentRoot = isAbsolute4(config.content.root) ? config.content.root : join15(absoluteRoot, config.content.root);
|
|
7767
|
-
const pagesPath = join15(absoluteRoot, config.content.pages);
|
|
7768
|
-
const pagesRoot = existsSync9(pagesPath) ? pagesPath : null;
|
|
7769
|
-
return {
|
|
7770
|
-
componentsFile: firstExisting(absoluteRoot, COMPONENTS_FILENAMES),
|
|
7771
|
-
configFile: findConfigFile(absoluteRoot),
|
|
7772
|
-
contentRoot,
|
|
7773
|
-
outDir: join15(absoluteRoot, ".blume"),
|
|
7774
|
-
pagesRoot,
|
|
7775
|
-
root: absoluteRoot,
|
|
7776
|
-
themeFile: firstExisting(absoluteRoot, THEME_FILENAMES)
|
|
7777
|
-
};
|
|
7778
|
-
};
|
|
7779
|
-
|
|
7780
8204
|
// src/core/schema.ts
|
|
7781
8205
|
import { z as z2 } from "zod";
|
|
7782
8206
|
var iconName = z2.string().min(1);
|
|
@@ -7806,7 +8230,17 @@ var changelogMetaSchema = z2.object({
|
|
|
7806
8230
|
date: dateSchema.optional(),
|
|
7807
8231
|
version: z2.string().optional()
|
|
7808
8232
|
}).strict();
|
|
8233
|
+
var authorSchema = z2.union([
|
|
8234
|
+
z2.string(),
|
|
8235
|
+
z2.object({
|
|
8236
|
+
avatar: z2.string().optional(),
|
|
8237
|
+
image: z2.string().optional(),
|
|
8238
|
+
name: z2.string(),
|
|
8239
|
+
url: z2.string().optional()
|
|
8240
|
+
}).passthrough()
|
|
8241
|
+
]);
|
|
7809
8242
|
var pageMetaBaseSchema = z2.object({
|
|
8243
|
+
authors: z2.union([authorSchema, z2.array(authorSchema)]).optional(),
|
|
7810
8244
|
changelog: changelogMetaSchema.optional(),
|
|
7811
8245
|
date: dateSchema.optional(),
|
|
7812
8246
|
deprecated: z2.boolean().default(false),
|
|
@@ -8247,7 +8681,10 @@ var openapiSourceSchema = z2.object({
|
|
|
8247
8681
|
spec: z2.string()
|
|
8248
8682
|
}).strict();
|
|
8249
8683
|
var openapiConfigSchema = z2.object({
|
|
8684
|
+
codeSamples: z2.array(z2.string()).default(["curl", "js", "python"]),
|
|
8250
8685
|
enabled: z2.boolean().default(false),
|
|
8686
|
+
expandSchemas: z2.boolean().default(false),
|
|
8687
|
+
renderer: z2.enum(["blume", "scalar"]).default("blume"),
|
|
8251
8688
|
route: z2.string().default("/reference"),
|
|
8252
8689
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
8253
8690
|
spec: z2.string().optional(),
|
|
@@ -8276,6 +8713,9 @@ var tocConfigSchema = z2.union([
|
|
|
8276
8713
|
minLevel: value.minHeadingLevel ?? 2
|
|
8277
8714
|
};
|
|
8278
8715
|
});
|
|
8716
|
+
var iconsConfigSchema = z2.object({
|
|
8717
|
+
library: z2.enum(["lucide", "fontawesome", "tabler"]).default("lucide")
|
|
8718
|
+
}).strict();
|
|
8279
8719
|
var blumeConfigSchema = z2.object({
|
|
8280
8720
|
ai: aiConfigSchema.default({}),
|
|
8281
8721
|
analytics: analyticsConfigSchema.optional(),
|
|
@@ -8290,6 +8730,7 @@ var blumeConfigSchema = z2.object({
|
|
|
8290
8730
|
feedback: z2.boolean().default(true),
|
|
8291
8731
|
github: githubConfigSchema.optional(),
|
|
8292
8732
|
i18n: i18nConfigSchema.optional(),
|
|
8733
|
+
icons: iconsConfigSchema.default({}),
|
|
8293
8734
|
lastModified: lastModifiedConfigSchema.default(false),
|
|
8294
8735
|
logo: logoConfigSchema.optional(),
|
|
8295
8736
|
markdown: markdownConfigSchema.default({}),
|
|
@@ -8331,7 +8772,7 @@ var loadConfig = async (root, options = {}) => {
|
|
|
8331
8772
|
const sourceFile = bridge?.configFile ?? configFile;
|
|
8332
8773
|
const parsed = blumeConfigSchema.safeParse(raw ?? {});
|
|
8333
8774
|
if (!parsed.success) {
|
|
8334
|
-
const source = sourceFile &&
|
|
8775
|
+
const source = sourceFile && existsSync11(sourceFile) ? readFileSync7(sourceFile, "utf-8") : undefined;
|
|
8335
8776
|
const diagnostics = diagnosticsFromZod(parsed.error, {
|
|
8336
8777
|
code: "BLUME_CONFIG_INVALID",
|
|
8337
8778
|
file: sourceFile ?? undefined,
|
|
@@ -8808,7 +9249,7 @@ var discoverFolderMeta = async (contentRoot) => {
|
|
|
8808
9249
|
};
|
|
8809
9250
|
|
|
8810
9251
|
// src/core/sources/normalize.ts
|
|
8811
|
-
import { existsSync as
|
|
9252
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
|
|
8812
9253
|
import GithubSlugger from "github-slugger";
|
|
8813
9254
|
import { extname as extname4 } from "pathe";
|
|
8814
9255
|
var NUMERIC_PREFIX2 = /^\d+[-_.]/u;
|
|
@@ -8816,7 +9257,7 @@ var GROUP_FOLDER2 = /^\((?<label>.+)\)$/u;
|
|
|
8816
9257
|
var WORD_SPLIT2 = /[-_]/u;
|
|
8817
9258
|
var stripNumericPrefix = (segment) => segment.replace(NUMERIC_PREFIX2, "");
|
|
8818
9259
|
var groupLabel = (segment) => segment.match(GROUP_FOLDER2)?.groups?.label ?? null;
|
|
8819
|
-
var
|
|
9260
|
+
var slugify3 = (text) => text.toLowerCase().trim().replaceAll(/[^\w\s-]/gu, "").replaceAll(/[\s_]+/gu, "-").replaceAll(/-+/gu, "-").replaceAll(/^-|-$/gu, "");
|
|
8820
9261
|
var titleCase = (value) => value.split(WORD_SPLIT2).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
8821
9262
|
var mapRoute = (relativePath) => {
|
|
8822
9263
|
const withoutExt = relativePath.slice(0, relativePath.length - extname4(relativePath).length);
|
|
@@ -8934,7 +9375,7 @@ var normalizeEntry2 = (entry, ctx) => {
|
|
|
8934
9375
|
const ext = format === "mdx" ? ".mdx" : ".md";
|
|
8935
9376
|
const result = pageMetaSchema.safeParse(entry.data);
|
|
8936
9377
|
if (!result.success) {
|
|
8937
|
-
const source = entry.raw ?? (entry.sourcePath &&
|
|
9378
|
+
const source = entry.raw ?? (entry.sourcePath && existsSync12(entry.sourcePath) ? readFileSync8(entry.sourcePath, "utf-8") : undefined);
|
|
8938
9379
|
return {
|
|
8939
9380
|
diagnostics: diagnosticsFromZod(result.error, {
|
|
8940
9381
|
code: "BLUME_FRONTMATTER_INVALID",
|
|
@@ -8983,15 +9424,15 @@ var normalizeEntry2 = (entry, ctx) => {
|
|
|
8983
9424
|
};
|
|
8984
9425
|
|
|
8985
9426
|
// src/core/sources/resolve.ts
|
|
8986
|
-
import { join as
|
|
9427
|
+
import { join as join26 } from "pathe";
|
|
8987
9428
|
|
|
8988
9429
|
// src/core/sources/filesystem.ts
|
|
8989
|
-
import { existsSync as
|
|
8990
|
-
import { readFile as
|
|
8991
|
-
import { extname as extname5, isAbsolute as
|
|
9430
|
+
import { existsSync as existsSync13, watch as fsWatch } from "node:fs";
|
|
9431
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
9432
|
+
import { extname as extname5, isAbsolute as isAbsolute6, join as join19, relative as relative10, resolve as resolve6 } from "pathe";
|
|
8992
9433
|
import { glob as glob6 } from "tinyglobby";
|
|
8993
9434
|
var filesystemSource = (options) => {
|
|
8994
|
-
const contentRoot =
|
|
9435
|
+
const contentRoot = isAbsolute6(options.root) ? options.root : join19(resolve6(options.projectRoot), options.root);
|
|
8995
9436
|
const load2 = async () => {
|
|
8996
9437
|
const files = await glob6(options.include, {
|
|
8997
9438
|
absolute: true,
|
|
@@ -9001,7 +9442,7 @@ var filesystemSource = (options) => {
|
|
|
9001
9442
|
});
|
|
9002
9443
|
files.sort();
|
|
9003
9444
|
const entries = await Promise.all(files.map(async (file) => {
|
|
9004
|
-
const source = await
|
|
9445
|
+
const source = await readFile13(file, "utf-8");
|
|
9005
9446
|
const ext = extname5(file).toLowerCase();
|
|
9006
9447
|
const format = ext === ".mdx" ? "mdx" : "md";
|
|
9007
9448
|
const parsed = frontmatter_default(source);
|
|
@@ -9015,7 +9456,7 @@ var filesystemSource = (options) => {
|
|
|
9015
9456
|
return { diagnostics: [], entries };
|
|
9016
9457
|
};
|
|
9017
9458
|
const validate = () => {
|
|
9018
|
-
if (!
|
|
9459
|
+
if (!existsSync13(contentRoot)) {
|
|
9019
9460
|
throw new BlumeError({
|
|
9020
9461
|
code: options.missingCode ?? "BLUME_CONTENT_ROOT_MISSING",
|
|
9021
9462
|
file: contentRoot,
|
|
@@ -9026,7 +9467,7 @@ var filesystemSource = (options) => {
|
|
|
9026
9467
|
}
|
|
9027
9468
|
};
|
|
9028
9469
|
const watch = (onChange) => {
|
|
9029
|
-
if (!
|
|
9470
|
+
if (!existsSync13(contentRoot)) {
|
|
9030
9471
|
return () => {};
|
|
9031
9472
|
}
|
|
9032
9473
|
const watcher = fsWatch(contentRoot, { recursive: true }, onChange);
|
|
@@ -9037,97 +9478,21 @@ var filesystemSource = (options) => {
|
|
|
9037
9478
|
load: load2,
|
|
9038
9479
|
name: options.name,
|
|
9039
9480
|
prefix: options.prefix,
|
|
9040
|
-
read: (ref) =>
|
|
9481
|
+
read: (ref) => readFile13(join19(contentRoot, ref), "utf-8"),
|
|
9041
9482
|
staged: false,
|
|
9042
9483
|
validate,
|
|
9043
9484
|
watch
|
|
9044
9485
|
};
|
|
9045
9486
|
};
|
|
9046
9487
|
|
|
9047
|
-
// src/core/sources/cache.ts
|
|
9048
|
-
import { mkdir as mkdir3, readFile as readFile11, writeFile as writeFile3 } from "node:fs/promises";
|
|
9049
|
-
import { join as join17 } from "pathe";
|
|
9050
|
-
var hashText = (text) => {
|
|
9051
|
-
let hash = 5381;
|
|
9052
|
-
for (let i = 0;i < text.length; i += 1) {
|
|
9053
|
-
hash = (hash * 33 + (text.codePointAt(i) ?? 0)) % 2147483647;
|
|
9054
|
-
}
|
|
9055
|
-
return hash.toString(36);
|
|
9056
|
-
};
|
|
9057
|
-
var entriesDigest = (entries) => hashText(entries.map((entry) => `${entry.ref}:${entry.hash ?? hashText(entry.body.text)}`).join("|"));
|
|
9058
|
-
var pollingWatch = (load2, intervalSeconds) => (onChange) => {
|
|
9059
|
-
let last = "";
|
|
9060
|
-
const tick = async () => {
|
|
9061
|
-
try {
|
|
9062
|
-
const { entries } = await load2();
|
|
9063
|
-
const next = entriesDigest(entries);
|
|
9064
|
-
if (last && next !== last) {
|
|
9065
|
-
onChange();
|
|
9066
|
-
}
|
|
9067
|
-
last = next;
|
|
9068
|
-
} catch {}
|
|
9069
|
-
};
|
|
9070
|
-
const timer = setInterval(() => {
|
|
9071
|
-
tick();
|
|
9072
|
-
}, intervalSeconds * 1000);
|
|
9073
|
-
return () => clearInterval(timer);
|
|
9074
|
-
};
|
|
9075
|
-
var snapshotCache = (cacheDir) => {
|
|
9076
|
-
const file = join17(cacheDir, "entries.json");
|
|
9077
|
-
return {
|
|
9078
|
-
read: async () => {
|
|
9079
|
-
try {
|
|
9080
|
-
return JSON.parse(await readFile11(file, "utf-8"));
|
|
9081
|
-
} catch {
|
|
9082
|
-
return [];
|
|
9083
|
-
}
|
|
9084
|
-
},
|
|
9085
|
-
write: async (entries) => {
|
|
9086
|
-
try {
|
|
9087
|
-
await mkdir3(cacheDir, { recursive: true });
|
|
9088
|
-
await writeFile3(file, `${JSON.stringify(entries)}
|
|
9089
|
-
`, "utf-8");
|
|
9090
|
-
} catch {}
|
|
9091
|
-
}
|
|
9092
|
-
};
|
|
9093
|
-
};
|
|
9094
|
-
var loadWithCache = async (name, cache, fetchEntries, refresh = true) => {
|
|
9095
|
-
if (!refresh) {
|
|
9096
|
-
const cached3 = await cache.read();
|
|
9097
|
-
if (cached3.length > 0) {
|
|
9098
|
-
return { diagnostics: [], entries: cached3 };
|
|
9099
|
-
}
|
|
9100
|
-
}
|
|
9101
|
-
try {
|
|
9102
|
-
const entries = await fetchEntries();
|
|
9103
|
-
await cache.write(entries);
|
|
9104
|
-
return { diagnostics: [], entries };
|
|
9105
|
-
} catch (error) {
|
|
9106
|
-
const fallback = await cache.read();
|
|
9107
|
-
if (fallback.length > 0) {
|
|
9108
|
-
const diagnostic = {
|
|
9109
|
-
code: "BLUME_SOURCE_OFFLINE",
|
|
9110
|
-
message: `Source "${name}" could not be fetched (${error.message}); served ${fallback.length} cached entries.`,
|
|
9111
|
-
severity: "warning"
|
|
9112
|
-
};
|
|
9113
|
-
return { diagnostics: [diagnostic], entries: fallback };
|
|
9114
|
-
}
|
|
9115
|
-
throw new BlumeError({
|
|
9116
|
-
code: "BLUME_SOURCE_FETCH_FAILED",
|
|
9117
|
-
message: `Source "${name}" failed to load and no cache is available: ${error.message}`,
|
|
9118
|
-
severity: "error"
|
|
9119
|
-
});
|
|
9120
|
-
}
|
|
9121
|
-
};
|
|
9122
|
-
|
|
9123
9488
|
// src/core/sources/github-releases.ts
|
|
9124
9489
|
var DEFAULT_BASE_URL = "https://api.github.com";
|
|
9125
9490
|
var DEFAULT_LIMIT = 100;
|
|
9126
9491
|
var PER_PAGE = 100;
|
|
9127
9492
|
var LEADING_V = /^v/iu;
|
|
9128
|
-
var
|
|
9493
|
+
var NON_SLUG3 = /[^a-z0-9]+/gu;
|
|
9129
9494
|
var EDGE_DASHES = /^-+|-+$/gu;
|
|
9130
|
-
var slugifyTag = (tag) => tag.toLowerCase().replaceAll(
|
|
9495
|
+
var slugifyTag = (tag) => tag.toLowerCase().replaceAll(NON_SLUG3, "-").replaceAll(EDGE_DASHES, "");
|
|
9131
9496
|
var githubHeaders = () => {
|
|
9132
9497
|
const headers = new Headers({ Accept: "application/vnd.github+json" });
|
|
9133
9498
|
const token = process.env.GITHUB_TOKEN;
|
|
@@ -9390,25 +9755,25 @@ var mdxRemoteSource = (options, ctx) => {
|
|
|
9390
9755
|
};
|
|
9391
9756
|
|
|
9392
9757
|
// src/core/sources/mintlify.ts
|
|
9393
|
-
import { existsSync as
|
|
9394
|
-
import { readFile as
|
|
9395
|
-
import { isAbsolute as
|
|
9758
|
+
import { existsSync as existsSync15, watch as fsWatch2 } from "node:fs";
|
|
9759
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
9760
|
+
import { isAbsolute as isAbsolute8, join as join22, relative as relative14, resolve as resolve8 } from "pathe";
|
|
9396
9761
|
import { glob as glob7 } from "tinyglobby";
|
|
9397
9762
|
|
|
9398
9763
|
// src/migrate/shared.ts
|
|
9399
|
-
import { existsSync as
|
|
9400
|
-
import { readFile as
|
|
9401
|
-
import { isAbsolute as
|
|
9764
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
9765
|
+
import { readFile as readFile14, writeFile as writeFile5 } from "node:fs/promises";
|
|
9766
|
+
import { isAbsolute as isAbsolute7, join as join20, relative as relative11 } from "pathe";
|
|
9402
9767
|
var isInsideRoot2 = (root, candidate) => {
|
|
9403
9768
|
const rel = relative11(root, candidate);
|
|
9404
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
9769
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute7(rel);
|
|
9405
9770
|
};
|
|
9406
9771
|
var writeBlumeConfig = async (root, config) => {
|
|
9407
9772
|
const body = `import { defineConfig } from "blume";
|
|
9408
9773
|
|
|
9409
9774
|
export default defineConfig(${JSON.stringify(config, null, 2)});
|
|
9410
9775
|
`;
|
|
9411
|
-
await
|
|
9776
|
+
await writeFile5(join20(root, "blume.config.ts"), body, "utf-8");
|
|
9412
9777
|
};
|
|
9413
9778
|
var BLUME_SCRIPTS = {
|
|
9414
9779
|
build: "blume build",
|
|
@@ -9416,13 +9781,13 @@ var BLUME_SCRIPTS = {
|
|
|
9416
9781
|
start: "blume preview"
|
|
9417
9782
|
};
|
|
9418
9783
|
var rewriteFrameworkScripts = async (root, cli, remove) => {
|
|
9419
|
-
const pkgPath =
|
|
9420
|
-
if (!
|
|
9784
|
+
const pkgPath = join20(root, "package.json");
|
|
9785
|
+
if (!existsSync14(pkgPath)) {
|
|
9421
9786
|
return false;
|
|
9422
9787
|
}
|
|
9423
9788
|
let pkg;
|
|
9424
9789
|
try {
|
|
9425
|
-
pkg = JSON.parse(await
|
|
9790
|
+
pkg = JSON.parse(await readFile14(pkgPath, "utf-8"));
|
|
9426
9791
|
} catch {
|
|
9427
9792
|
return false;
|
|
9428
9793
|
}
|
|
@@ -9445,12 +9810,12 @@ var rewriteFrameworkScripts = async (root, cli, remove) => {
|
|
|
9445
9810
|
}
|
|
9446
9811
|
if (changed) {
|
|
9447
9812
|
pkg.scripts = next;
|
|
9448
|
-
await
|
|
9813
|
+
await writeFile5(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
9449
9814
|
`, "utf-8");
|
|
9450
9815
|
}
|
|
9451
9816
|
return changed;
|
|
9452
9817
|
};
|
|
9453
|
-
var leftoverFiles = (root, candidates) => candidates.filter((candidate) =>
|
|
9818
|
+
var leftoverFiles = (root, candidates) => candidates.filter((candidate) => existsSync14(join20(root, candidate)));
|
|
9454
9819
|
var attribute = (attrs, name) => {
|
|
9455
9820
|
const match = attrs.match(new RegExp(`\\b${name}=(?:"(?<dq>[^"]*)"|'(?<sq>[^']*)')`, "u"));
|
|
9456
9821
|
return match?.groups?.dq ?? match?.groups?.sq;
|
|
@@ -9847,7 +10212,7 @@ var isLiteralObject = (value) => typeof value === "object" && value !== null &&
|
|
|
9847
10212
|
var asLiteralArray = (value) => Array.isArray(value) ? value : undefined;
|
|
9848
10213
|
|
|
9849
10214
|
// src/migrate/mintlify/content.ts
|
|
9850
|
-
import { dirname as dirname10, join as
|
|
10215
|
+
import { dirname as dirname10, join as join21, relative as relative12 } from "pathe";
|
|
9851
10216
|
var CALLOUT_DIRECTIVES = {
|
|
9852
10217
|
Check: "success",
|
|
9853
10218
|
Danger: "danger",
|
|
@@ -9883,7 +10248,7 @@ var rewriteSnippetImports = (source, options) => {
|
|
|
9883
10248
|
if (/\.mdx?$/u.test(importSource)) {
|
|
9884
10249
|
return "";
|
|
9885
10250
|
}
|
|
9886
|
-
const target =
|
|
10251
|
+
const target = join21(options.root, importSource.replace(/^\/+/u, ""));
|
|
9887
10252
|
components.push(importSource.replace(/^\/+/u, ""));
|
|
9888
10253
|
let rel = relative12(dirname10(options.filePath), target);
|
|
9889
10254
|
if (!rel.startsWith(".")) {
|
|
@@ -9893,7 +10258,7 @@ var rewriteSnippetImports = (source, options) => {
|
|
|
9893
10258
|
});
|
|
9894
10259
|
return { components, source: next };
|
|
9895
10260
|
};
|
|
9896
|
-
var UNSUPPORTED_COMPONENTS = ["
|
|
10261
|
+
var UNSUPPORTED_COMPONENTS = ["Update"];
|
|
9897
10262
|
var unsupportedMintlifyComponents = (source) => UNSUPPORTED_COMPONENTS.filter((name) => new RegExp(`<${name}\\b`, "u").test(source));
|
|
9898
10263
|
|
|
9899
10264
|
// src/migrate/mintlify/frontmatter.ts
|
|
@@ -10164,9 +10529,9 @@ var rewriteMintlifyMarkdownSnippets = async (source, options) => {
|
|
|
10164
10529
|
throw new Error(snippetCycleMessage(options.root, file, options.trail ?? []));
|
|
10165
10530
|
}
|
|
10166
10531
|
seen.add(file);
|
|
10167
|
-
const
|
|
10532
|
+
const readFile15 = options.readFile ?? readFileFromDisk;
|
|
10168
10533
|
try {
|
|
10169
|
-
const raw = await
|
|
10534
|
+
const raw = await readFile15(file);
|
|
10170
10535
|
const content = frontmatter_default(raw).content.trim();
|
|
10171
10536
|
const transformed = await rewriteMintlifyMarkdownSnippets(content, {
|
|
10172
10537
|
...options,
|
|
@@ -10207,7 +10572,7 @@ var rewriteMintlifyMarkdownSnippets = async (source, options) => {
|
|
|
10207
10572
|
return await inlineAt(0, source);
|
|
10208
10573
|
};
|
|
10209
10574
|
var rewriteMintlifySnippetVariables = async (source, options) => {
|
|
10210
|
-
const
|
|
10575
|
+
const readFile15 = options.readFile ?? readFileFromDisk;
|
|
10211
10576
|
const inlineImport = async (current, variableImport) => {
|
|
10212
10577
|
const file = resolveSnippetPath({
|
|
10213
10578
|
filePath: options.filePath,
|
|
@@ -10217,7 +10582,7 @@ var rewriteMintlifySnippetVariables = async (source, options) => {
|
|
|
10217
10582
|
if (!file) {
|
|
10218
10583
|
return current;
|
|
10219
10584
|
}
|
|
10220
|
-
const exports = collectStringExports(frontmatter_default(await
|
|
10585
|
+
const exports = collectStringExports(frontmatter_default(await readFile15(file)).content);
|
|
10221
10586
|
let next = current;
|
|
10222
10587
|
for (const name of variableImport.names) {
|
|
10223
10588
|
const value = exports.get(name.imported);
|
|
@@ -10295,7 +10660,7 @@ var MINTLIFY_SOURCE_IGNORES = [
|
|
|
10295
10660
|
"snippets/**"
|
|
10296
10661
|
];
|
|
10297
10662
|
var mintlifySource = (options) => {
|
|
10298
|
-
const contentRoot =
|
|
10663
|
+
const contentRoot = isAbsolute8(options.root) ? options.root : join22(resolve8(options.projectRoot), options.root);
|
|
10299
10664
|
const ignore = [...new Set([...options.exclude, ...MINTLIFY_SOURCE_IGNORES])];
|
|
10300
10665
|
const transform = (raw, file) => transformMintlifyContent(raw, {
|
|
10301
10666
|
filePath: file,
|
|
@@ -10312,7 +10677,7 @@ var mintlifySource = (options) => {
|
|
|
10312
10677
|
files.sort();
|
|
10313
10678
|
const unsupported = new Set;
|
|
10314
10679
|
const entries = await Promise.all(files.map(async (file) => {
|
|
10315
|
-
const result = await transform(await
|
|
10680
|
+
const result = await transform(await readFile15(file, "utf-8"), file);
|
|
10316
10681
|
for (const name of result.unsupported) {
|
|
10317
10682
|
unsupported.add(name);
|
|
10318
10683
|
}
|
|
@@ -10328,14 +10693,14 @@ var mintlifySource = (options) => {
|
|
|
10328
10693
|
const diagnostics = unsupported.size > 0 ? [
|
|
10329
10694
|
{
|
|
10330
10695
|
code: "BLUME_MINTLIFY_UNSUPPORTED",
|
|
10331
|
-
message: `Mintlify components without a Blume equivalent were left as-is: ${[...unsupported].toSorted().join(", ")}.
|
|
10696
|
+
message: `Mintlify components without a Blume equivalent were left as-is: ${[...unsupported].toSorted().join(", ")}. Replace them by hand or provide a matching component.`,
|
|
10332
10697
|
severity: "warning"
|
|
10333
10698
|
}
|
|
10334
10699
|
] : [];
|
|
10335
10700
|
return { diagnostics, entries };
|
|
10336
10701
|
};
|
|
10337
10702
|
const validate = () => {
|
|
10338
|
-
if (!
|
|
10703
|
+
if (!existsSync15(contentRoot)) {
|
|
10339
10704
|
throw new BlumeError({
|
|
10340
10705
|
code: "BLUME_CONTENT_ROOT_MISSING",
|
|
10341
10706
|
file: contentRoot,
|
|
@@ -10347,11 +10712,11 @@ var mintlifySource = (options) => {
|
|
|
10347
10712
|
};
|
|
10348
10713
|
const watch = (onChange) => {
|
|
10349
10714
|
const disposers = [];
|
|
10350
|
-
if (
|
|
10715
|
+
if (existsSync15(contentRoot)) {
|
|
10351
10716
|
const watcher = fsWatch2(contentRoot, { recursive: true }, onChange);
|
|
10352
10717
|
disposers.push(() => watcher.close());
|
|
10353
10718
|
}
|
|
10354
|
-
if (options.configFile &&
|
|
10719
|
+
if (options.configFile && existsSync15(options.configFile)) {
|
|
10355
10720
|
const watcher = fsWatch2(options.configFile, onChange);
|
|
10356
10721
|
disposers.push(() => watcher.close());
|
|
10357
10722
|
}
|
|
@@ -10362,8 +10727,8 @@ var mintlifySource = (options) => {
|
|
|
10362
10727
|
};
|
|
10363
10728
|
};
|
|
10364
10729
|
const read = async (ref) => {
|
|
10365
|
-
const file =
|
|
10366
|
-
const result = await transform(await
|
|
10730
|
+
const file = join22(contentRoot, ref);
|
|
10731
|
+
const result = await transform(await readFile15(file, "utf-8"), file);
|
|
10367
10732
|
return result.content;
|
|
10368
10733
|
};
|
|
10369
10734
|
return {
|
|
@@ -10380,11 +10745,11 @@ var mintlifySource = (options) => {
|
|
|
10380
10745
|
|
|
10381
10746
|
// src/core/sources/notion.ts
|
|
10382
10747
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
10383
|
-
import { join as
|
|
10748
|
+
import { join as join24 } from "pathe";
|
|
10384
10749
|
|
|
10385
10750
|
// src/core/sources/assets.ts
|
|
10386
|
-
import { mkdir as mkdir4, writeFile as
|
|
10387
|
-
import { extname as extname6, join as
|
|
10751
|
+
import { mkdir as mkdir4, writeFile as writeFile6 } from "node:fs/promises";
|
|
10752
|
+
import { extname as extname6, join as join23 } from "pathe";
|
|
10388
10753
|
var MD_IMAGE = /!\[(?<alt>[^\]]*)\]\((?<url>[^)\s]+)\)/gu;
|
|
10389
10754
|
var REMOTE = /^https?:\/\//u;
|
|
10390
10755
|
var SAFE_EXT = /^\.[a-z0-9]+$/iu;
|
|
@@ -10413,7 +10778,7 @@ var materializeAssets = async (markdown, ctx) => {
|
|
|
10413
10778
|
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
10414
10779
|
const file = `${hashText(url)}${extFor(url)}`;
|
|
10415
10780
|
await mkdir4(ctx.assetsDir, { recursive: true });
|
|
10416
|
-
await
|
|
10781
|
+
await writeFile6(join23(ctx.assetsDir, file), bytes);
|
|
10417
10782
|
rewrites.set(url, `${ctx.assetsBaseUrl}/${file}`);
|
|
10418
10783
|
} catch (error) {
|
|
10419
10784
|
diagnostics.push({
|
|
@@ -10529,8 +10894,8 @@ ${text}
|
|
|
10529
10894
|
};
|
|
10530
10895
|
var notionSource = (options, ctx) => {
|
|
10531
10896
|
const props = options.properties ?? {};
|
|
10532
|
-
const cache = snapshotCache(ctx?.cacheDir ??
|
|
10533
|
-
const assetsDir = ctx?.assetsDir ??
|
|
10897
|
+
const cache = snapshotCache(ctx?.cacheDir ?? join24(".blume", "cache", options.name));
|
|
10898
|
+
const assetsDir = ctx?.assetsDir ?? join24(".blume", "public", "blume-assets", options.name);
|
|
10534
10899
|
const assetsBaseUrl = ctx?.assetsBaseUrl ?? `/blume-assets/${options.name}`;
|
|
10535
10900
|
let snapshot = new Map;
|
|
10536
10901
|
const resolveClient = async () => {
|
|
@@ -10635,10 +11000,10 @@ ${rendered.join(`
|
|
|
10635
11000
|
data.sidebar = { order };
|
|
10636
11001
|
}
|
|
10637
11002
|
const slugProp = richToMarkdown(page.properties[props.slug ?? "Slug"]?.rich_text);
|
|
10638
|
-
const slug =
|
|
11003
|
+
const slug = slugify3(slugProp || title) || page.id;
|
|
10639
11004
|
return { data, slug };
|
|
10640
11005
|
};
|
|
10641
|
-
const
|
|
11006
|
+
const toEntry2 = async (client, page) => {
|
|
10642
11007
|
const { data, slug } = frontmatter(page);
|
|
10643
11008
|
const mdx = await renderBlocks(client, await childrenOf(client, page.id));
|
|
10644
11009
|
const assets = await materializeAssets(mdx, {
|
|
@@ -10667,7 +11032,7 @@ ${rendered.join(`
|
|
|
10667
11032
|
database_id: options.database,
|
|
10668
11033
|
start_cursor: cursor
|
|
10669
11034
|
})));
|
|
10670
|
-
const built = await Promise.all(pages.map((page) =>
|
|
11035
|
+
const built = await Promise.all(pages.map((page) => toEntry2(client, page)));
|
|
10671
11036
|
for (const item of built) {
|
|
10672
11037
|
assetDiagnostics.push(...item.diagnostics);
|
|
10673
11038
|
}
|
|
@@ -10698,7 +11063,7 @@ ${rendered.join(`
|
|
|
10698
11063
|
};
|
|
10699
11064
|
|
|
10700
11065
|
// src/core/sources/sanity.ts
|
|
10701
|
-
import { join as
|
|
11066
|
+
import { join as join25 } from "pathe";
|
|
10702
11067
|
|
|
10703
11068
|
// src/core/sources/portable-text.ts
|
|
10704
11069
|
var HEADING_STYLES = {
|
|
@@ -10837,11 +11202,11 @@ var resolveClient = async (options, preview) => {
|
|
|
10837
11202
|
};
|
|
10838
11203
|
var sanitySource = (options, ctx) => {
|
|
10839
11204
|
const fields = options.fields ?? {};
|
|
10840
|
-
const cache = snapshotCache(ctx?.cacheDir ??
|
|
11205
|
+
const cache = snapshotCache(ctx?.cacheDir ?? join25(".blume", "cache", options.name));
|
|
10841
11206
|
let snapshot = new Map;
|
|
10842
|
-
const
|
|
11207
|
+
const toEntry2 = (doc) => {
|
|
10843
11208
|
const slugValue = asString2(getPath(doc, fields.slug ?? "slug.current")) ?? asString2(doc._id) ?? "untitled";
|
|
10844
|
-
const slug =
|
|
11209
|
+
const slug = slugify3(slugValue) || slugify3(asString2(doc._id) ?? "") || "untitled";
|
|
10845
11210
|
const data = {};
|
|
10846
11211
|
const title = asString2(getPath(doc, fields.title ?? "title"));
|
|
10847
11212
|
const description = asString2(getPath(doc, fields.description ?? "description"));
|
|
@@ -10873,7 +11238,7 @@ var sanitySource = (options, ctx) => {
|
|
|
10873
11238
|
const result = await loadWithCache(options.name, cache, async () => {
|
|
10874
11239
|
const client = await resolveClient(options, ctx?.preview ?? false);
|
|
10875
11240
|
const docs = await client.fetch(options.query);
|
|
10876
|
-
return docs.map(
|
|
11241
|
+
return docs.map(toEntry2);
|
|
10877
11242
|
}, ctx?.refresh ?? true);
|
|
10878
11243
|
snapshot = new Map(result.entries.map((entry) => [entry.ref, entry]));
|
|
10879
11244
|
return result;
|
|
@@ -10912,8 +11277,8 @@ var uniqueNamer = () => {
|
|
|
10912
11277
|
};
|
|
10913
11278
|
var sourceContext = (context, name, runtime) => ({
|
|
10914
11279
|
assetsBaseUrl: `/blume-assets/${name}`,
|
|
10915
|
-
assetsDir:
|
|
10916
|
-
cacheDir:
|
|
11280
|
+
assetsDir: join26(context.outDir, "public", "blume-assets", name),
|
|
11281
|
+
cacheDir: join26(context.outDir, "cache", name),
|
|
10917
11282
|
mode: runtime.mode,
|
|
10918
11283
|
preview: runtime.preview,
|
|
10919
11284
|
projectRoot: context.root,
|
|
@@ -10995,7 +11360,7 @@ var baseName = (def) => {
|
|
|
10995
11360
|
}
|
|
10996
11361
|
return def.prefix ?? def.type;
|
|
10997
11362
|
};
|
|
10998
|
-
var
|
|
11363
|
+
var contentSources = (config, context, runtime) => {
|
|
10999
11364
|
const defs = config.content.sources;
|
|
11000
11365
|
if (!defs || defs.length === 0) {
|
|
11001
11366
|
return [
|
|
@@ -11011,6 +11376,14 @@ var resolveSources = (config, context, runtime) => {
|
|
|
11011
11376
|
const nameFor = uniqueNamer();
|
|
11012
11377
|
return defs.map((def) => buildSource(def, nameFor(baseName(def)), context, runtime));
|
|
11013
11378
|
};
|
|
11379
|
+
var resolveSources = (config, context, runtime) => {
|
|
11380
|
+
const sources = contentSources(config, context, runtime);
|
|
11381
|
+
const references = blumeReferences(config);
|
|
11382
|
+
if (references.length > 0) {
|
|
11383
|
+
sources.push(openApiSource(references, sourceContext(context, "openapi", runtime)));
|
|
11384
|
+
}
|
|
11385
|
+
return sources;
|
|
11386
|
+
};
|
|
11014
11387
|
|
|
11015
11388
|
// src/core/project-graph.ts
|
|
11016
11389
|
var applyConfigOverrides = (config, overrides) => {
|
|
@@ -11039,7 +11412,9 @@ var scanProject = async (root, options = {}) => {
|
|
|
11039
11412
|
});
|
|
11040
11413
|
const { bridge } = configResult;
|
|
11041
11414
|
const config = applyConfigOverrides(configResult.config, options.overrides);
|
|
11042
|
-
const context = resolveProjectContext(root, config
|
|
11415
|
+
const context = resolveProjectContext(root, config, {
|
|
11416
|
+
runtimeDir: options.runtimeDir
|
|
11417
|
+
});
|
|
11043
11418
|
const sources = resolveSources(config, context, {
|
|
11044
11419
|
mode,
|
|
11045
11420
|
preview,
|
|
@@ -11107,8 +11482,8 @@ var scanProject = async (root, options = {}) => {
|
|
|
11107
11482
|
};
|
|
11108
11483
|
|
|
11109
11484
|
// src/cli/env.ts
|
|
11110
|
-
import { existsSync as
|
|
11111
|
-
import { dirname as dirname12, join as
|
|
11485
|
+
import { existsSync as existsSync16, readFileSync as readFileSync9 } from "node:fs";
|
|
11486
|
+
import { dirname as dirname12, join as join27, resolve as resolve9 } from "pathe";
|
|
11112
11487
|
var ENV_LINE = /^\s*(?:export\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?<value>.*?)\s*$/u;
|
|
11113
11488
|
var DOUBLE_QUOTED2 = /^"(?<body>[\s\S]*)"$/u;
|
|
11114
11489
|
var SINGLE_QUOTED = /^'(?<body>[\s\S]*)'$/u;
|
|
@@ -11146,7 +11521,7 @@ var applyEnv = (parsed) => {
|
|
|
11146
11521
|
};
|
|
11147
11522
|
var loadFile = (path) => {
|
|
11148
11523
|
try {
|
|
11149
|
-
if (
|
|
11524
|
+
if (existsSync16(path)) {
|
|
11150
11525
|
applyEnv(parseEnv(readFileSync9(path, "utf-8")));
|
|
11151
11526
|
}
|
|
11152
11527
|
} catch {}
|
|
@@ -11155,10 +11530,10 @@ var loadEnvFiles = (startDir) => {
|
|
|
11155
11530
|
let dir = resolve9(startDir);
|
|
11156
11531
|
let done = false;
|
|
11157
11532
|
while (!done) {
|
|
11158
|
-
loadFile(
|
|
11159
|
-
loadFile(
|
|
11533
|
+
loadFile(join27(dir, ".env.local"));
|
|
11534
|
+
loadFile(join27(dir, ".env"));
|
|
11160
11535
|
const parent = dirname12(dir);
|
|
11161
|
-
done =
|
|
11536
|
+
done = existsSync16(join27(dir, ".git")) || parent === dir;
|
|
11162
11537
|
dir = parent;
|
|
11163
11538
|
}
|
|
11164
11539
|
};
|
|
@@ -11231,7 +11606,8 @@ var prepareProject = async (options) => {
|
|
|
11231
11606
|
mode: options.mode,
|
|
11232
11607
|
overrides: options.overrides,
|
|
11233
11608
|
preview: options.preview,
|
|
11234
|
-
refresh: options.refresh
|
|
11609
|
+
refresh: options.refresh,
|
|
11610
|
+
runtimeDir: options.runtimeDir
|
|
11235
11611
|
});
|
|
11236
11612
|
} catch (error) {
|
|
11237
11613
|
if (error instanceof BlumeError) {
|
|
@@ -11287,24 +11663,24 @@ var emitRedirectFiles = async (config, distDir) => {
|
|
|
11287
11663
|
if (redirects.length === 0 || config.deployment.output !== "static") {
|
|
11288
11664
|
return;
|
|
11289
11665
|
}
|
|
11290
|
-
await
|
|
11666
|
+
await writeFile7(join28(distDir, "blume-redirects.json"), buildRedirectManifest(redirects), "utf-8");
|
|
11291
11667
|
const platformFiles = [
|
|
11292
11668
|
{ content: buildNetlifyRedirects(redirects), name: "_redirects" },
|
|
11293
11669
|
{ content: buildVercelConfig(redirects), name: "vercel.json" }
|
|
11294
11670
|
];
|
|
11295
|
-
await Promise.all(platformFiles.map((file) =>
|
|
11671
|
+
await Promise.all(platformFiles.map((file) => existsSync17(join28(distDir, file.name)) ? Promise.resolve() : writeFile7(join28(distDir, file.name), file.content, "utf-8")));
|
|
11296
11672
|
logger.success(`Emitted redirect files for ${redirects.length} redirect(s)`);
|
|
11297
11673
|
};
|
|
11298
11674
|
var formatBytes = (bytes) => bytes < 1024 ? `${bytes} B` : `${(bytes / 1024).toFixed(bytes < 1024 * 100 ? 1 : 0)} kB`;
|
|
11299
11675
|
var astroAssets = async (distDir, ext) => {
|
|
11300
|
-
const astroDir =
|
|
11301
|
-
if (!
|
|
11676
|
+
const astroDir = join28(distDir, "_astro");
|
|
11677
|
+
if (!existsSync17(astroDir)) {
|
|
11302
11678
|
return [];
|
|
11303
11679
|
}
|
|
11304
11680
|
const entries = await readdir(astroDir);
|
|
11305
11681
|
const files = entries.filter((name) => name.endsWith(`.${ext}`));
|
|
11306
11682
|
const sized = await Promise.all(files.map(async (name) => {
|
|
11307
|
-
const info = await stat(
|
|
11683
|
+
const info = await stat(join28(astroDir, name));
|
|
11308
11684
|
return { name, size: info.size };
|
|
11309
11685
|
}));
|
|
11310
11686
|
return sized.toSorted((a, b) => b.size - a.size);
|
|
@@ -11346,6 +11722,58 @@ var enforceBudget = async (distDir, args) => {
|
|
|
11346
11722
|
}
|
|
11347
11723
|
return passed ? "pass" : "fail";
|
|
11348
11724
|
};
|
|
11725
|
+
var publishBuildArtifacts = async (project, distDir, args) => {
|
|
11726
|
+
if (project.config.search.provider === "pagefind") {
|
|
11727
|
+
logger.start("Building search index");
|
|
11728
|
+
const indexed = await buildSearchIndex(distDir);
|
|
11729
|
+
logger.success(`Indexed ${indexed} page(s) for search`);
|
|
11730
|
+
}
|
|
11731
|
+
await syncSearchProvider(project, {
|
|
11732
|
+
start: (message) => logger.start(message),
|
|
11733
|
+
success: (message) => logger.success(message),
|
|
11734
|
+
warn: (message) => logger.warn(message)
|
|
11735
|
+
});
|
|
11736
|
+
if (project.config.ai.llmsTxt) {
|
|
11737
|
+
const { index, full } = await buildLlmsFiles(project);
|
|
11738
|
+
await Promise.all([
|
|
11739
|
+
writeFile7(join28(distDir, "llms.txt"), index, "utf-8"),
|
|
11740
|
+
writeFile7(join28(distDir, "llms-full.txt"), full, "utf-8")
|
|
11741
|
+
]);
|
|
11742
|
+
logger.success("Generated llms.txt and llms-full.txt");
|
|
11743
|
+
}
|
|
11744
|
+
const sitemap = buildSitemap(project);
|
|
11745
|
+
if (sitemap && !existsSync17(join28(distDir, "sitemap.xml"))) {
|
|
11746
|
+
await writeFile7(join28(distDir, "sitemap.xml"), sitemap, "utf-8");
|
|
11747
|
+
logger.success("Generated sitemap.xml");
|
|
11748
|
+
}
|
|
11749
|
+
const robots = buildRobots(project);
|
|
11750
|
+
if (robots && !existsSync17(join28(distDir, "robots.txt"))) {
|
|
11751
|
+
await writeFile7(join28(distDir, "robots.txt"), robots, "utf-8");
|
|
11752
|
+
logger.success("Generated robots.txt");
|
|
11753
|
+
}
|
|
11754
|
+
await emitRedirectFiles(project.config, distDir);
|
|
11755
|
+
const { config } = project;
|
|
11756
|
+
const features = serverFeatures(config);
|
|
11757
|
+
logger.box([
|
|
11758
|
+
`Output ${config.deployment.output}`,
|
|
11759
|
+
`Adapter ${config.deployment.adapter ?? "none"}`,
|
|
11760
|
+
`Site ${config.deployment.site ?? "not set"}`,
|
|
11761
|
+
`Search ${config.search.provider}`,
|
|
11762
|
+
`Redirects ${config.redirects.length}`,
|
|
11763
|
+
`Sitemap ${sitemap ? "yes" : "no (set deployment.site)"}`,
|
|
11764
|
+
`Robots ${robots ? "yes" : "no"}`,
|
|
11765
|
+
`LLM files ${config.ai.llmsTxt ? "yes" : "no"}`,
|
|
11766
|
+
`Server features ${features.length > 0 ? features.join(", ") : "none"}`
|
|
11767
|
+
].join(`
|
|
11768
|
+
`));
|
|
11769
|
+
if (args.analyze) {
|
|
11770
|
+
await reportBundleSizes(distDir);
|
|
11771
|
+
}
|
|
11772
|
+
if (await enforceBudget(distDir, args) === "fail") {
|
|
11773
|
+
process.exit(1);
|
|
11774
|
+
}
|
|
11775
|
+
logger.success(`Built to ${distDir}`);
|
|
11776
|
+
};
|
|
11349
11777
|
var buildCommand = defineCommand2({
|
|
11350
11778
|
args: {
|
|
11351
11779
|
adapter: {
|
|
@@ -11368,6 +11796,10 @@ var buildCommand = defineCommand2({
|
|
|
11368
11796
|
description: "Fail if total client JavaScript exceeds this many kB.",
|
|
11369
11797
|
type: "string"
|
|
11370
11798
|
},
|
|
11799
|
+
isolated: {
|
|
11800
|
+
description: "Build into an isolated .blume-verify runtime (and its own dist) so a running dev server and the real dist/ are untouched. For verifying changes while `blume dev` runs.",
|
|
11801
|
+
type: "boolean"
|
|
11802
|
+
},
|
|
11371
11803
|
output: {
|
|
11372
11804
|
description: "Output mode: static | server.",
|
|
11373
11805
|
type: "string"
|
|
@@ -11384,7 +11816,11 @@ var buildCommand = defineCommand2({
|
|
|
11384
11816
|
},
|
|
11385
11817
|
async run({ args }) {
|
|
11386
11818
|
const root = process.cwd();
|
|
11387
|
-
|
|
11819
|
+
const runtimeDir = args.isolated ? ".blume-verify" : process.env.BLUME_RUNTIME_DIR;
|
|
11820
|
+
refuseIfDevRunning(root, "building", runtimeDir);
|
|
11821
|
+
if (args.isolated) {
|
|
11822
|
+
await ensureGitignore(root, [".blume-verify/"]);
|
|
11823
|
+
}
|
|
11388
11824
|
if (args.output && args.output !== "static" && args.output !== "server") {
|
|
11389
11825
|
logger.error(`Invalid --output "${args.output}" (use static | server).`);
|
|
11390
11826
|
process.exit(1);
|
|
@@ -11403,6 +11839,7 @@ var buildCommand = defineCommand2({
|
|
|
11403
11839
|
},
|
|
11404
11840
|
preview: args.preview,
|
|
11405
11841
|
root,
|
|
11842
|
+
runtimeDir,
|
|
11406
11843
|
strict: args.strict
|
|
11407
11844
|
});
|
|
11408
11845
|
logger.start(`Building ${project.graph.pages.length} page(s) (${project.config.deployment.output} output)`);
|
|
@@ -11410,68 +11847,27 @@ var buildCommand = defineCommand2({
|
|
|
11410
11847
|
logLevel: "info",
|
|
11411
11848
|
root: project.context.outDir
|
|
11412
11849
|
});
|
|
11413
|
-
const distDir =
|
|
11414
|
-
if (
|
|
11415
|
-
logger.
|
|
11416
|
-
|
|
11417
|
-
logger.success(`Indexed ${indexed} page(s) for search`);
|
|
11418
|
-
}
|
|
11419
|
-
await syncSearchProvider(project, {
|
|
11420
|
-
start: (message) => logger.start(message),
|
|
11421
|
-
success: (message) => logger.success(message),
|
|
11422
|
-
warn: (message) => logger.warn(message)
|
|
11423
|
-
});
|
|
11424
|
-
if (project.config.ai.llmsTxt) {
|
|
11425
|
-
const { index, full } = await buildLlmsFiles(project);
|
|
11426
|
-
await Promise.all([
|
|
11427
|
-
writeFile6(join26(distDir, "llms.txt"), index, "utf-8"),
|
|
11428
|
-
writeFile6(join26(distDir, "llms-full.txt"), full, "utf-8")
|
|
11429
|
-
]);
|
|
11430
|
-
logger.success("Generated llms.txt and llms-full.txt");
|
|
11431
|
-
}
|
|
11432
|
-
const sitemap = buildSitemap(project);
|
|
11433
|
-
if (sitemap && !existsSync16(join26(distDir, "sitemap.xml"))) {
|
|
11434
|
-
await writeFile6(join26(distDir, "sitemap.xml"), sitemap, "utf-8");
|
|
11435
|
-
logger.success("Generated sitemap.xml");
|
|
11436
|
-
}
|
|
11437
|
-
const robots = buildRobots(project);
|
|
11438
|
-
if (robots && !existsSync16(join26(distDir, "robots.txt"))) {
|
|
11439
|
-
await writeFile6(join26(distDir, "robots.txt"), robots, "utf-8");
|
|
11440
|
-
logger.success("Generated robots.txt");
|
|
11441
|
-
}
|
|
11442
|
-
await emitRedirectFiles(project.config, distDir);
|
|
11443
|
-
const { config } = project;
|
|
11444
|
-
const features = serverFeatures(config);
|
|
11445
|
-
logger.box([
|
|
11446
|
-
`Output ${config.deployment.output}`,
|
|
11447
|
-
`Adapter ${config.deployment.adapter ?? "none"}`,
|
|
11448
|
-
`Site ${config.deployment.site ?? "not set"}`,
|
|
11449
|
-
`Search ${config.search.provider}`,
|
|
11450
|
-
`Redirects ${config.redirects.length}`,
|
|
11451
|
-
`Sitemap ${sitemap ? "yes" : "no (set deployment.site)"}`,
|
|
11452
|
-
`Robots ${robots ? "yes" : "no"}`,
|
|
11453
|
-
`LLM files ${config.ai.llmsTxt ? "yes" : "no"}`,
|
|
11454
|
-
`Server features ${features.length > 0 ? features.join(", ") : "none"}`
|
|
11455
|
-
].join(`
|
|
11456
|
-
`));
|
|
11457
|
-
if (args.analyze) {
|
|
11458
|
-
await reportBundleSizes(distDir);
|
|
11459
|
-
}
|
|
11460
|
-
if (await enforceBudget(distDir, args) === "fail") {
|
|
11461
|
-
process.exit(1);
|
|
11850
|
+
const distDir = project.context.distDir ?? join28(root, "dist");
|
|
11851
|
+
if (runtimeDir) {
|
|
11852
|
+
logger.success(`Isolated build OK — output at ${distDir} (not published).`);
|
|
11853
|
+
return;
|
|
11462
11854
|
}
|
|
11463
|
-
|
|
11855
|
+
await publishBuildArtifacts(project, distDir, args);
|
|
11464
11856
|
}
|
|
11465
11857
|
});
|
|
11466
11858
|
|
|
11467
11859
|
// src/cli/commands/check.ts
|
|
11468
|
-
import { existsSync as
|
|
11860
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
11469
11861
|
import { check } from "@astrojs/check";
|
|
11470
11862
|
import { sync } from "astro";
|
|
11471
11863
|
import { defineCommand as defineCommand3 } from "citty";
|
|
11472
|
-
import { join as
|
|
11864
|
+
import { join as join29 } from "pathe";
|
|
11473
11865
|
var checkCommand = defineCommand3({
|
|
11474
11866
|
args: {
|
|
11867
|
+
isolated: {
|
|
11868
|
+
description: "Type-check in an isolated .blume-verify runtime so a running dev server is untouched. For verifying changes while `blume dev` runs.",
|
|
11869
|
+
type: "boolean"
|
|
11870
|
+
},
|
|
11475
11871
|
preview: {
|
|
11476
11872
|
description: "Include drafts and unpublished CMS content.",
|
|
11477
11873
|
type: "boolean"
|
|
@@ -11487,21 +11883,27 @@ var checkCommand = defineCommand3({
|
|
|
11487
11883
|
},
|
|
11488
11884
|
async run({ args }) {
|
|
11489
11885
|
const root = process.cwd();
|
|
11886
|
+
const runtimeDir = args.isolated ? ".blume-verify" : process.env.BLUME_RUNTIME_DIR;
|
|
11887
|
+
refuseIfDevRunning(root, "checking", runtimeDir);
|
|
11888
|
+
if (args.isolated) {
|
|
11889
|
+
await ensureGitignore(root, [".blume-verify/"]);
|
|
11890
|
+
}
|
|
11490
11891
|
const project = await prepareProject({
|
|
11491
11892
|
mode: "build",
|
|
11492
11893
|
preview: args.preview,
|
|
11493
11894
|
root,
|
|
11895
|
+
runtimeDir,
|
|
11494
11896
|
strict: args.strict
|
|
11495
11897
|
});
|
|
11496
11898
|
const { outDir } = project.context;
|
|
11497
11899
|
await sync({ logLevel: "warn", root: outDir });
|
|
11498
|
-
const tsconfig =
|
|
11900
|
+
const tsconfig = join29(root, "tsconfig.json");
|
|
11499
11901
|
logger.start(`Type-checking ${project.graph.pages.length} page(s)`);
|
|
11500
11902
|
const failed = await check({
|
|
11501
11903
|
minimumFailingSeverity: "error",
|
|
11502
11904
|
minimumSeverity: "hint",
|
|
11503
11905
|
root: outDir,
|
|
11504
|
-
tsconfig:
|
|
11906
|
+
tsconfig: existsSync18(tsconfig) ? tsconfig : undefined,
|
|
11505
11907
|
watch: false
|
|
11506
11908
|
});
|
|
11507
11909
|
if (failed) {
|
|
@@ -11518,7 +11920,7 @@ import { dev } from "astro";
|
|
|
11518
11920
|
import { defineCommand as defineCommand4 } from "citty";
|
|
11519
11921
|
|
|
11520
11922
|
// src/astro/static-assets.ts
|
|
11521
|
-
import { extname as extname7, join as
|
|
11923
|
+
import { extname as extname7, join as join30, relative as relative15, resolve as resolve10, sep } from "pathe";
|
|
11522
11924
|
|
|
11523
11925
|
// src/astro/integration.ts
|
|
11524
11926
|
var overlayServer = null;
|
|
@@ -11744,15 +12146,19 @@ var doctorCommand = defineCommand5({
|
|
|
11744
12146
|
});
|
|
11745
12147
|
|
|
11746
12148
|
// src/cli/commands/eject.ts
|
|
11747
|
-
import { readFile as
|
|
12149
|
+
import { readFile as readFile17, writeFile as writeFile9 } from "node:fs/promises";
|
|
11748
12150
|
import { defineCommand as defineCommand6 } from "citty";
|
|
11749
|
-
import { join as
|
|
12151
|
+
import { join as join32, relative as relative17 } from "pathe";
|
|
11750
12152
|
|
|
11751
12153
|
// src/registry/eject.ts
|
|
11752
|
-
import { existsSync as
|
|
11753
|
-
import { cp, mkdir as mkdir5, readFile as
|
|
11754
|
-
import { join as
|
|
12154
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
12155
|
+
import { cp, mkdir as mkdir5, readFile as readFile16, rm as rm2, writeFile as writeFile8 } from "node:fs/promises";
|
|
12156
|
+
import { join as join31, relative as relative16 } from "pathe";
|
|
11755
12157
|
var POSIX = (path) => path.split("\\").join("/");
|
|
12158
|
+
var ejectOpenApiData = (project) => {
|
|
12159
|
+
const source = project.sources.find(isOpenApiSource);
|
|
12160
|
+
return source ? source.openApiData() : {};
|
|
12161
|
+
};
|
|
11756
12162
|
var askFiles = async (project, srcDir, genDir) => {
|
|
11757
12163
|
const { ask } = project.config.ai;
|
|
11758
12164
|
if (!ask?.enabled) {
|
|
@@ -11762,14 +12168,14 @@ var askFiles = async (project, srcDir, genDir) => {
|
|
|
11762
12168
|
const files = [
|
|
11763
12169
|
{
|
|
11764
12170
|
content: askEndpointTemplate(resolveAskBackend(ask), grounded),
|
|
11765
|
-
path:
|
|
12171
|
+
path: join31(srcDir, "pages", "api", "ask.ts")
|
|
11766
12172
|
}
|
|
11767
12173
|
];
|
|
11768
12174
|
if (grounded) {
|
|
11769
12175
|
files.push({
|
|
11770
12176
|
content: `${JSON.stringify(await buildAskData(project))}
|
|
11771
12177
|
`,
|
|
11772
|
-
path:
|
|
12178
|
+
path: join31(genDir, "ask-data.json")
|
|
11773
12179
|
});
|
|
11774
12180
|
}
|
|
11775
12181
|
return files;
|
|
@@ -11777,15 +12183,15 @@ var askFiles = async (project, srcDir, genDir) => {
|
|
|
11777
12183
|
var eject = async (root) => {
|
|
11778
12184
|
const project = await scanProject(root, { mode: "build" });
|
|
11779
12185
|
const { context, config } = project;
|
|
11780
|
-
const srcDir =
|
|
11781
|
-
const genDir =
|
|
12186
|
+
const srcDir = join31(root, "src");
|
|
12187
|
+
const genDir = join31(srcDir, "generated");
|
|
11782
12188
|
const askEnabled = config.ai.ask?.enabled ?? false;
|
|
11783
12189
|
const exportPdf = config.export.pdf;
|
|
11784
12190
|
const exportEpub = config.export.epub;
|
|
11785
12191
|
const [pages, needsReactRaw, userTheme, rawMarkdown, islands, examples] = await Promise.all([
|
|
11786
12192
|
context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),
|
|
11787
12193
|
detectNeedsReact(root),
|
|
11788
|
-
context.themeFile ?
|
|
12194
|
+
context.themeFile ? readFile16(context.themeFile, "utf-8") : Promise.resolve(""),
|
|
11789
12195
|
buildRawMarkdown(project),
|
|
11790
12196
|
discoverIslands(root),
|
|
11791
12197
|
discoverExamples(root, config.examples)
|
|
@@ -11822,18 +12228,19 @@ var eject = async (root) => {
|
|
|
11822
12228
|
needsReact,
|
|
11823
12229
|
needsSvelte,
|
|
11824
12230
|
needsVue,
|
|
12231
|
+
openapiPath: "./src/generated/openapi.json",
|
|
11825
12232
|
pages: relPages,
|
|
11826
12233
|
searchClientPath: "./src/generated/search-client.ts",
|
|
11827
12234
|
themePath: "./src/generated/app.css"
|
|
11828
12235
|
}),
|
|
11829
|
-
path:
|
|
12236
|
+
path: join31(root, "astro.config.mjs")
|
|
11830
12237
|
},
|
|
11831
12238
|
{
|
|
11832
12239
|
content: runtimeTsconfigTemplate(),
|
|
11833
|
-
path:
|
|
12240
|
+
path: join31(root, "tsconfig.json"),
|
|
11834
12241
|
skipIfExists: true
|
|
11835
12242
|
},
|
|
11836
|
-
{ content: envTemplate(), path:
|
|
12243
|
+
{ content: envTemplate(), path: join31(srcDir, "env.d.ts") },
|
|
11837
12244
|
{
|
|
11838
12245
|
content: contentConfigTemplate({
|
|
11839
12246
|
config,
|
|
@@ -11841,7 +12248,7 @@ var eject = async (root) => {
|
|
|
11841
12248
|
staged: hasStaged,
|
|
11842
12249
|
stagedBase: stagedDir
|
|
11843
12250
|
}),
|
|
11844
|
-
path:
|
|
12251
|
+
path: join31(srcDir, "content.config.ts")
|
|
11845
12252
|
},
|
|
11846
12253
|
{
|
|
11847
12254
|
content: catchAllPageTemplate({
|
|
@@ -11851,19 +12258,19 @@ var eject = async (root) => {
|
|
|
11851
12258
|
mathEnabled: config.markdown.math,
|
|
11852
12259
|
needsReact
|
|
11853
12260
|
}),
|
|
11854
|
-
path:
|
|
12261
|
+
path: join31(srcDir, "pages", "[...slug].astro")
|
|
11855
12262
|
},
|
|
11856
12263
|
{
|
|
11857
12264
|
content: planComponentSlots(componentsImport, null).module,
|
|
11858
|
-
path:
|
|
12265
|
+
path: join31(genDir, "components.ts")
|
|
11859
12266
|
},
|
|
11860
12267
|
{
|
|
11861
12268
|
content: islandMapTemplate(islands.islands),
|
|
11862
|
-
path:
|
|
12269
|
+
path: join31(genDir, "islands.ts")
|
|
11863
12270
|
},
|
|
11864
12271
|
{
|
|
11865
12272
|
content: exampleMapTemplate(examples.examples),
|
|
11866
|
-
path:
|
|
12273
|
+
path: join31(genDir, "examples.ts")
|
|
11867
12274
|
},
|
|
11868
12275
|
{
|
|
11869
12276
|
content: tailwindEntryTemplate({
|
|
@@ -11875,21 +12282,26 @@ var eject = async (root) => {
|
|
|
11875
12282
|
twoslashCss: twoslashCss(),
|
|
11876
12283
|
userTheme
|
|
11877
12284
|
}),
|
|
11878
|
-
path:
|
|
12285
|
+
path: join31(genDir, "app.css")
|
|
12286
|
+
},
|
|
12287
|
+
{ content: buildRuntimeData(project), path: join31(genDir, "data.json") },
|
|
12288
|
+
{
|
|
12289
|
+
content: `${JSON.stringify(ejectOpenApiData(project))}
|
|
12290
|
+
`,
|
|
12291
|
+
path: join31(genDir, "openapi.json")
|
|
11879
12292
|
},
|
|
11880
|
-
{ content: buildRuntimeData(project), path: join29(genDir, "data.json") },
|
|
11881
12293
|
{
|
|
11882
12294
|
content: `${JSON.stringify(rawMarkdown)}
|
|
11883
12295
|
`,
|
|
11884
|
-
path:
|
|
12296
|
+
path: join31(genDir, "raw-markdown.json")
|
|
11885
12297
|
},
|
|
11886
12298
|
{
|
|
11887
12299
|
content: rawMarkdownEndpointTemplate(),
|
|
11888
|
-
path:
|
|
12300
|
+
path: join31(srcDir, "pages", "[...slug].md.ts")
|
|
11889
12301
|
},
|
|
11890
12302
|
{
|
|
11891
12303
|
content: rawMarkdownEndpointTemplate(),
|
|
11892
|
-
path:
|
|
12304
|
+
path: join31(srcDir, "pages", "[...slug].mdx.ts")
|
|
11893
12305
|
}
|
|
11894
12306
|
];
|
|
11895
12307
|
if (askEnabled) {
|
|
@@ -11898,34 +12310,34 @@ var eject = async (root) => {
|
|
|
11898
12310
|
if (config.seo.og.enabled) {
|
|
11899
12311
|
files.push({
|
|
11900
12312
|
content: ogEndpointTemplate(customOgRoutes(pages, config.title)),
|
|
11901
|
-
path:
|
|
12313
|
+
path: join31(srcDir, "pages", "og", "[...slug].png.ts")
|
|
11902
12314
|
});
|
|
11903
12315
|
}
|
|
11904
12316
|
if (!routeIsTaken(pages, project.graph.pages, "/404")) {
|
|
11905
12317
|
files.push({
|
|
11906
12318
|
content: notFoundPageTemplate(),
|
|
11907
|
-
path:
|
|
12319
|
+
path: join31(srcDir, "pages", "404.astro")
|
|
11908
12320
|
});
|
|
11909
12321
|
}
|
|
11910
12322
|
files.push({
|
|
11911
12323
|
content: searchClientTemplate(config),
|
|
11912
|
-
path:
|
|
12324
|
+
path: join31(genDir, "search-client.ts")
|
|
11913
12325
|
});
|
|
11914
12326
|
if (servesStaticIndex(config.search.provider)) {
|
|
11915
12327
|
const documents = await buildSearchDocuments(project);
|
|
11916
12328
|
files.push({
|
|
11917
12329
|
content: `${JSON.stringify(documents)}
|
|
11918
12330
|
`,
|
|
11919
|
-
path:
|
|
12331
|
+
path: join31(genDir, "search.json")
|
|
11920
12332
|
}, {
|
|
11921
12333
|
content: searchEndpointTemplate(),
|
|
11922
|
-
path:
|
|
12334
|
+
path: join31(srcDir, "pages", "blume-search.json.ts")
|
|
11923
12335
|
});
|
|
11924
12336
|
}
|
|
11925
12337
|
if (config.search.provider === "mixedbread") {
|
|
11926
12338
|
files.push({
|
|
11927
12339
|
content: mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""),
|
|
11928
|
-
path:
|
|
12340
|
+
path: join31(srcDir, "pages", "api", "search.ts")
|
|
11929
12341
|
});
|
|
11930
12342
|
}
|
|
11931
12343
|
const feeds = buildRssFeeds(project);
|
|
@@ -11934,13 +12346,13 @@ var eject = async (root) => {
|
|
|
11934
12346
|
files.push({
|
|
11935
12347
|
content: `${JSON.stringify(feedXml)}
|
|
11936
12348
|
`,
|
|
11937
|
-
path:
|
|
12349
|
+
path: join31(genDir, "rss.json")
|
|
11938
12350
|
}, {
|
|
11939
12351
|
content: rssEndpointTemplate(),
|
|
11940
|
-
path:
|
|
12352
|
+
path: join31(srcDir, "pages", "[section]", "rss.xml.ts")
|
|
11941
12353
|
});
|
|
11942
12354
|
}
|
|
11943
|
-
if (
|
|
12355
|
+
if (hasScalarReferences(config)) {
|
|
11944
12356
|
const references = await buildReferenceFiles({
|
|
11945
12357
|
config,
|
|
11946
12358
|
contentRoutes: new Set(project.graph.pages.map((page) => page.route)),
|
|
@@ -11949,28 +12361,28 @@ var eject = async (root) => {
|
|
|
11949
12361
|
for (const file of references.files) {
|
|
11950
12362
|
files.push({
|
|
11951
12363
|
content: file.content,
|
|
11952
|
-
path:
|
|
12364
|
+
path: join31(srcDir, "pages", file.pagePath)
|
|
11953
12365
|
});
|
|
11954
12366
|
}
|
|
11955
12367
|
}
|
|
11956
12368
|
files.push(...islands.islands.map((island) => ({
|
|
11957
12369
|
content: islandWrapperTemplate(island),
|
|
11958
|
-
path:
|
|
12370
|
+
path: join31(genDir, "islands", `${island.name}.astro`)
|
|
11959
12371
|
})), ...examples.examples.map((example) => ({
|
|
11960
12372
|
content: exampleWrapperTemplate(example),
|
|
11961
|
-
path:
|
|
12373
|
+
path: join31(genDir, "examples", `${exampleSlug(example.path)}.astro`)
|
|
11962
12374
|
})));
|
|
11963
12375
|
for (const [entryId, content] of staged) {
|
|
11964
|
-
files.push({ content, path:
|
|
12376
|
+
files.push({ content, path: join31(root, stagedDir, entryId) });
|
|
11965
12377
|
}
|
|
11966
|
-
const written = files.filter((file) => !(file.skipIfExists &&
|
|
12378
|
+
const written = files.filter((file) => !(file.skipIfExists && existsSync19(file.path)));
|
|
11967
12379
|
await Promise.all(written.map(async (file) => {
|
|
11968
|
-
await mkdir5(
|
|
11969
|
-
await
|
|
12380
|
+
await mkdir5(join31(file.path, ".."), { recursive: true });
|
|
12381
|
+
await writeFile8(file.path, file.content, "utf-8");
|
|
11970
12382
|
}));
|
|
11971
|
-
const assetsSrc =
|
|
11972
|
-
if (
|
|
11973
|
-
await cp(assetsSrc,
|
|
12383
|
+
const assetsSrc = join31(context.outDir, "public", "blume-assets");
|
|
12384
|
+
if (existsSync19(assetsSrc)) {
|
|
12385
|
+
await cp(assetsSrc, join31(root, "public", "blume-assets"), {
|
|
11974
12386
|
recursive: true
|
|
11975
12387
|
});
|
|
11976
12388
|
}
|
|
@@ -11980,10 +12392,10 @@ var eject = async (root) => {
|
|
|
11980
12392
|
|
|
11981
12393
|
// src/cli/commands/eject.ts
|
|
11982
12394
|
var updatePackageScripts = async (root) => {
|
|
11983
|
-
const pkgPath =
|
|
12395
|
+
const pkgPath = join32(root, "package.json");
|
|
11984
12396
|
let pkg;
|
|
11985
12397
|
try {
|
|
11986
|
-
pkg = JSON.parse(await
|
|
12398
|
+
pkg = JSON.parse(await readFile17(pkgPath, "utf-8"));
|
|
11987
12399
|
} catch {
|
|
11988
12400
|
return;
|
|
11989
12401
|
}
|
|
@@ -11994,7 +12406,7 @@ var updatePackageScripts = async (root) => {
|
|
|
11994
12406
|
dev: "astro dev",
|
|
11995
12407
|
preview: "astro preview"
|
|
11996
12408
|
};
|
|
11997
|
-
await
|
|
12409
|
+
await writeFile9(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
11998
12410
|
`, "utf-8");
|
|
11999
12411
|
};
|
|
12000
12412
|
var ejectCommand = defineCommand6({
|
|
@@ -12033,32 +12445,7 @@ The blume package remains importable.`);
|
|
|
12033
12445
|
import { existsSync as existsSync20 } from "node:fs";
|
|
12034
12446
|
import { mkdir as mkdir6, writeFile as writeFile10 } from "node:fs/promises";
|
|
12035
12447
|
import { defineCommand as defineCommand7 } from "citty";
|
|
12036
|
-
import { basename as basename4, dirname as dirname13, isAbsolute as
|
|
12037
|
-
|
|
12038
|
-
// src/core/gitignore.ts
|
|
12039
|
-
import { existsSync as existsSync19 } from "node:fs";
|
|
12040
|
-
import { readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
|
|
12041
|
-
import { join as join31 } from "pathe";
|
|
12042
|
-
var gitignoreKey = (line) => line.trim().replace(/\/+$/u, "");
|
|
12043
|
-
var ensureGitignore = async (root, entries) => {
|
|
12044
|
-
const path = join31(root, ".gitignore");
|
|
12045
|
-
const existing = existsSync19(path) ? await readFile16(path, "utf-8") : "";
|
|
12046
|
-
const present = new Set(existing.split(`
|
|
12047
|
-
`).map(gitignoreKey).filter(Boolean));
|
|
12048
|
-
const added = entries.filter((entry) => !present.has(gitignoreKey(entry)));
|
|
12049
|
-
if (added.length === 0) {
|
|
12050
|
-
return [];
|
|
12051
|
-
}
|
|
12052
|
-
const gap = existing.length > 0 && !existing.endsWith(`
|
|
12053
|
-
`) ? `
|
|
12054
|
-
` : "";
|
|
12055
|
-
await writeFile9(path, `${existing}${gap}${added.join(`
|
|
12056
|
-
`)}
|
|
12057
|
-
`, "utf-8");
|
|
12058
|
-
return added;
|
|
12059
|
-
};
|
|
12060
|
-
|
|
12061
|
-
// src/cli/commands/init.ts
|
|
12448
|
+
import { basename as basename4, dirname as dirname13, isAbsolute as isAbsolute9, join as join33, relative as relative18 } from "pathe";
|
|
12062
12449
|
var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
|
|
12063
12450
|
var packageTemplate = (name, version) => `{
|
|
12064
12451
|
"name": ${JSON.stringify(name)},
|
|
@@ -12106,7 +12493,7 @@ var STARTERS = {
|
|
|
12106
12493
|
files: (dir) => [
|
|
12107
12494
|
{
|
|
12108
12495
|
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`."),
|
|
12109
|
-
path:
|
|
12496
|
+
path: join33(dir, "index.mdx")
|
|
12110
12497
|
}
|
|
12111
12498
|
]
|
|
12112
12499
|
},
|
|
@@ -12121,7 +12508,7 @@ var STARTERS = {
|
|
|
12121
12508
|
files: (dir) => [
|
|
12122
12509
|
{
|
|
12123
12510
|
content: page("Introduction", "Welcome to your new Blume docs.", "# Introduction\n\nWrite your docs here, and log releases under `changelog/`."),
|
|
12124
|
-
path:
|
|
12511
|
+
path: join33(dir, "index.mdx")
|
|
12125
12512
|
},
|
|
12126
12513
|
{
|
|
12127
12514
|
content: `---
|
|
@@ -12132,7 +12519,7 @@ date: 2026-01-01
|
|
|
12132
12519
|
|
|
12133
12520
|
The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries beside it.
|
|
12134
12521
|
`,
|
|
12135
|
-
path:
|
|
12522
|
+
path: join33(dir, "changelog", "v1-0-0.mdx")
|
|
12136
12523
|
}
|
|
12137
12524
|
]
|
|
12138
12525
|
},
|
|
@@ -12145,7 +12532,7 @@ The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries besid
|
|
|
12145
12532
|
Welcome to **Blume** — markdown-first docs powered by Astro and Vite.
|
|
12146
12533
|
|
|
12147
12534
|
Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
|
|
12148
|
-
path:
|
|
12535
|
+
path: join33(dir, "index.mdx")
|
|
12149
12536
|
}
|
|
12150
12537
|
]
|
|
12151
12538
|
},
|
|
@@ -12156,11 +12543,11 @@ Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
|
|
|
12156
12543
|
content: page("Introduction", "Get started with the SDK.", `# Introduction
|
|
12157
12544
|
|
|
12158
12545
|
Install the SDK and make your first call. See [Installation](/installation).`),
|
|
12159
|
-
path:
|
|
12546
|
+
path: join33(dir, "index.mdx")
|
|
12160
12547
|
},
|
|
12161
12548
|
{
|
|
12162
12549
|
content: page("Installation", "Install the SDK.", "# Installation\n\n```package-install\nyour-sdk\n```"),
|
|
12163
|
-
path:
|
|
12550
|
+
path: join33(dir, "installation.mdx")
|
|
12164
12551
|
}
|
|
12165
12552
|
]
|
|
12166
12553
|
}
|
|
@@ -12207,7 +12594,7 @@ var initCommand = defineCommand7({
|
|
|
12207
12594
|
async run({ args }) {
|
|
12208
12595
|
const root = process.cwd();
|
|
12209
12596
|
const contentDir = args["content-dir"] ?? "docs";
|
|
12210
|
-
if (
|
|
12597
|
+
if (isAbsolute9(contentDir) || relative18(root, join33(root, contentDir)).startsWith("..")) {
|
|
12211
12598
|
logger.error(`Invalid --content-dir "${contentDir}" (must be a path inside the project).`);
|
|
12212
12599
|
process.exit(1);
|
|
12213
12600
|
}
|
|
@@ -12222,9 +12609,9 @@ var initCommand = defineCommand7({
|
|
|
12222
12609
|
process.exit(1);
|
|
12223
12610
|
}
|
|
12224
12611
|
const starter = STARTERS[template];
|
|
12225
|
-
const createdPackage = await writeFileSafe(
|
|
12226
|
-
await writeFileSafe(
|
|
12227
|
-
await Promise.all(starter.files(contentDir).map((file) => writeFileSafe(
|
|
12612
|
+
const createdPackage = await writeFileSafe(join33(root, "package.json"), packageTemplate(toPackageName(basename4(root)), getBlumeVersion()));
|
|
12613
|
+
await writeFileSafe(join33(root, "blume.config.ts"), starter.config);
|
|
12614
|
+
await Promise.all(starter.files(contentDir).map((file) => writeFileSafe(join33(root, file.path), file.content)));
|
|
12228
12615
|
const ignored = await ensureGitignore(root, [".blume/", "dist/"]);
|
|
12229
12616
|
if (ignored.length > 0) {
|
|
12230
12617
|
logger.success(`Added ${ignored.join(", ")} to .gitignore`);
|
|
@@ -12266,14 +12653,14 @@ import { defineCommand as defineCommand8 } from "citty";
|
|
|
12266
12653
|
|
|
12267
12654
|
// src/migrate/fumadocs/index.ts
|
|
12268
12655
|
import { existsSync as existsSync24 } from "node:fs";
|
|
12269
|
-
import { mkdir as mkdir8, readFile as
|
|
12270
|
-
import { dirname as dirname16, join as
|
|
12656
|
+
import { mkdir as mkdir8, readFile as readFile19, rename as rename3, rm as rm3, writeFile as writeFile12 } from "node:fs/promises";
|
|
12657
|
+
import { dirname as dirname16, join as join36, relative as relative19 } from "pathe";
|
|
12271
12658
|
import { glob as glob8 } from "tinyglobby";
|
|
12272
12659
|
|
|
12273
12660
|
// src/migrate/fumadocs/config.ts
|
|
12274
12661
|
import { existsSync as existsSync21 } from "node:fs";
|
|
12275
|
-
import { readFile as
|
|
12276
|
-
import { basename as basename5, dirname as dirname14, join as
|
|
12662
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
12663
|
+
import { basename as basename5, dirname as dirname14, join as join34 } from "pathe";
|
|
12277
12664
|
var SOURCE_FILES = [
|
|
12278
12665
|
"lib/source.ts",
|
|
12279
12666
|
"app/source.ts",
|
|
@@ -12303,7 +12690,7 @@ var GENERIC_NAMES = new Set([
|
|
|
12303
12690
|
var gitRepoRoot = (start) => {
|
|
12304
12691
|
let dir = start;
|
|
12305
12692
|
for (;; ) {
|
|
12306
|
-
if (existsSync21(
|
|
12693
|
+
if (existsSync21(join34(dir, ".git"))) {
|
|
12307
12694
|
return dir;
|
|
12308
12695
|
}
|
|
12309
12696
|
const parent = dirname14(dir);
|
|
@@ -12315,12 +12702,12 @@ var gitRepoRoot = (start) => {
|
|
|
12315
12702
|
};
|
|
12316
12703
|
var bareName = (name) => name.includes("/") ? name.slice(name.lastIndexOf("/") + 1) : name;
|
|
12317
12704
|
var readTitle = async (root) => {
|
|
12318
|
-
const packageJson =
|
|
12705
|
+
const packageJson = join34(root, "package.json");
|
|
12319
12706
|
if (!existsSync21(packageJson)) {
|
|
12320
12707
|
return "Documentation";
|
|
12321
12708
|
}
|
|
12322
12709
|
try {
|
|
12323
|
-
const parsed = JSON.parse(await
|
|
12710
|
+
const parsed = JSON.parse(await readFile18(packageJson, "utf-8"));
|
|
12324
12711
|
const { name } = parsed;
|
|
12325
12712
|
if (typeof name !== "string" || !name.trim()) {
|
|
12326
12713
|
return "Documentation";
|
|
@@ -12341,11 +12728,11 @@ var readTitle = async (root) => {
|
|
|
12341
12728
|
};
|
|
12342
12729
|
var scrapeBaseUrl = async (root) => {
|
|
12343
12730
|
for (const candidate of SOURCE_FILES) {
|
|
12344
|
-
const file =
|
|
12731
|
+
const file = join34(root, candidate);
|
|
12345
12732
|
if (!existsSync21(file)) {
|
|
12346
12733
|
continue;
|
|
12347
12734
|
}
|
|
12348
|
-
const base = BASE_URL.exec(await
|
|
12735
|
+
const base = BASE_URL.exec(await readFile18(file, "utf-8"))?.groups?.base;
|
|
12349
12736
|
if (base) {
|
|
12350
12737
|
return base;
|
|
12351
12738
|
}
|
|
@@ -12620,7 +13007,7 @@ var normalizeFumadocsPageMeta = (value) => {
|
|
|
12620
13007
|
// src/migrate/fumadocs/groups.ts
|
|
12621
13008
|
import { existsSync as existsSync23, statSync as statSync2 } from "node:fs";
|
|
12622
13009
|
import { mkdir as mkdir7, rename as rename2, writeFile as writeFile11 } from "node:fs/promises";
|
|
12623
|
-
import { basename as basename6, join as
|
|
13010
|
+
import { basename as basename6, join as join35 } from "pathe";
|
|
12624
13011
|
|
|
12625
13012
|
// src/migrate/fumadocs/meta.ts
|
|
12626
13013
|
var SEPARATOR = /^---(?<label>.*)---$/u;
|
|
@@ -12765,16 +13152,16 @@ var isDirectory = (path) => {
|
|
|
12765
13152
|
}
|
|
12766
13153
|
};
|
|
12767
13154
|
var resolveEntry = (docsDir, name) => {
|
|
12768
|
-
if (!isInsideRoot2(docsDir,
|
|
13155
|
+
if (!isInsideRoot2(docsDir, join35(docsDir, name))) {
|
|
12769
13156
|
return null;
|
|
12770
13157
|
}
|
|
12771
13158
|
for (const ext of PAGE_EXTS) {
|
|
12772
|
-
const file =
|
|
13159
|
+
const file = join35(docsDir, `${name}${ext}`);
|
|
12773
13160
|
if (existsSync23(file)) {
|
|
12774
13161
|
return { kind: "file", path: file };
|
|
12775
13162
|
}
|
|
12776
13163
|
}
|
|
12777
|
-
const folder =
|
|
13164
|
+
const folder = join35(docsDir, name);
|
|
12778
13165
|
return isDirectory(folder) ? { kind: "folder", path: folder } : null;
|
|
12779
13166
|
};
|
|
12780
13167
|
var humanize2 = (name) => name.split(WORD_SPLIT3).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
@@ -12809,7 +13196,7 @@ var moveItemIntoGroup = async (item, docsDir, groupDir, label, warnings) => {
|
|
|
12809
13196
|
warnings.push(`Sidebar entry "${item.name}" in section "${label}" matched no page or folder; skipped.`);
|
|
12810
13197
|
return null;
|
|
12811
13198
|
}
|
|
12812
|
-
const dest =
|
|
13199
|
+
const dest = join35(groupDir, basename6(resolved.path));
|
|
12813
13200
|
if (existsSync23(dest)) {
|
|
12814
13201
|
warnings.push(`Skipped moving "${item.name}" into section "${label}" (target already exists).`);
|
|
12815
13202
|
return null;
|
|
@@ -12837,7 +13224,7 @@ var reshapeSection = async (section, docsDir, order, warnings) => {
|
|
|
12837
13224
|
}
|
|
12838
13225
|
return;
|
|
12839
13226
|
}
|
|
12840
|
-
const groupDir =
|
|
13227
|
+
const groupDir = join35(docsDir, `(${section.label})`);
|
|
12841
13228
|
const sectionKeys = [];
|
|
12842
13229
|
for (const item of section.items) {
|
|
12843
13230
|
const key = await moveItemIntoGroup(item, docsDir, groupDir, section.label, warnings);
|
|
@@ -12850,7 +13237,7 @@ var reshapeSection = async (section, docsDir, order, warnings) => {
|
|
|
12850
13237
|
}
|
|
12851
13238
|
order.push(section.label);
|
|
12852
13239
|
if (sectionKeys.length > 1) {
|
|
12853
|
-
await writeFile11(
|
|
13240
|
+
await writeFile11(join35(groupDir, "meta.ts"), renderMetaModule({ pages: sectionKeys }), "utf-8");
|
|
12854
13241
|
}
|
|
12855
13242
|
};
|
|
12856
13243
|
var reshapeFumadocsGroups = async (structure, docsDir) => {
|
|
@@ -12883,7 +13270,7 @@ var FUMADOCS_LEFTOVERS = [
|
|
|
12883
13270
|
];
|
|
12884
13271
|
var movePage = async (abs, base, root) => {
|
|
12885
13272
|
const rel = relative19(base, abs);
|
|
12886
|
-
const dest =
|
|
13273
|
+
const dest = join36(root, "docs", rel);
|
|
12887
13274
|
if (existsSync24(dest)) {
|
|
12888
13275
|
return {
|
|
12889
13276
|
includeWarnings: [],
|
|
@@ -12893,7 +13280,7 @@ var movePage = async (abs, base, root) => {
|
|
|
12893
13280
|
unsupported: []
|
|
12894
13281
|
};
|
|
12895
13282
|
}
|
|
12896
|
-
const raw = await
|
|
13283
|
+
const raw = await readFile19(abs, "utf-8");
|
|
12897
13284
|
const included = await inlineFumadocsIncludes(raw, {
|
|
12898
13285
|
filePath: abs,
|
|
12899
13286
|
root: base
|
|
@@ -12930,12 +13317,12 @@ var writeMeta = async (dest, meta, rel, warnings) => {
|
|
|
12930
13317
|
};
|
|
12931
13318
|
var convertMeta = async (abs, base, root) => {
|
|
12932
13319
|
const rel = relative19(base, abs);
|
|
12933
|
-
const raw = await
|
|
13320
|
+
const raw = await readFile19(abs, "utf-8");
|
|
12934
13321
|
let parsed;
|
|
12935
13322
|
try {
|
|
12936
13323
|
parsed = JSON.parse(raw);
|
|
12937
13324
|
} catch {
|
|
12938
|
-
const dest2 =
|
|
13325
|
+
const dest2 = join36(root, "docs", rel);
|
|
12939
13326
|
if (existsSync24(dest2)) {
|
|
12940
13327
|
return [`Skipped ${rel} (target already exists)`];
|
|
12941
13328
|
}
|
|
@@ -12946,8 +13333,8 @@ var convertMeta = async (abs, base, root) => {
|
|
|
12946
13333
|
];
|
|
12947
13334
|
}
|
|
12948
13335
|
const dir = dirname16(rel) === "." ? "" : dirname16(rel);
|
|
12949
|
-
const docsDir =
|
|
12950
|
-
const dest =
|
|
13336
|
+
const docsDir = join36(root, "docs", dir);
|
|
13337
|
+
const dest = join36(docsDir, "meta.ts");
|
|
12951
13338
|
const structure = parseFumadocsPages(parsed.pages);
|
|
12952
13339
|
if (structure.hasSections && !existsSync24(dest)) {
|
|
12953
13340
|
const self = translateFumadocsSelfMeta(parsed);
|
|
@@ -12996,7 +13383,7 @@ var summarizePages = (results) => {
|
|
|
12996
13383
|
};
|
|
12997
13384
|
};
|
|
12998
13385
|
var cleanupSourceDirs = async (root) => {
|
|
12999
|
-
const docs =
|
|
13386
|
+
const docs = join36(root, "content", "docs");
|
|
13000
13387
|
if (existsSync24(docs)) {
|
|
13001
13388
|
const remaining = await glob8(["**/*"], { cwd: docs, dot: true });
|
|
13002
13389
|
if (remaining.length > 0) {
|
|
@@ -13006,7 +13393,7 @@ var cleanupSourceDirs = async (root) => {
|
|
|
13006
13393
|
}
|
|
13007
13394
|
await rm3(docs, { force: true, recursive: true });
|
|
13008
13395
|
}
|
|
13009
|
-
const content =
|
|
13396
|
+
const content = join36(root, "content");
|
|
13010
13397
|
if (existsSync24(content)) {
|
|
13011
13398
|
const remaining = await glob8(["**/*"], { cwd: content, dot: true });
|
|
13012
13399
|
if (remaining.length === 0) {
|
|
@@ -13017,7 +13404,7 @@ var cleanupSourceDirs = async (root) => {
|
|
|
13017
13404
|
};
|
|
13018
13405
|
var migrateFumadocsProject = async (root) => {
|
|
13019
13406
|
const { config, warnings: configWarnings } = await loadFumadocsConfig(root);
|
|
13020
|
-
const base =
|
|
13407
|
+
const base = join36(root, SOURCE_DIR);
|
|
13021
13408
|
if (!existsSync24(base)) {
|
|
13022
13409
|
await writeBlumeConfig(root, config);
|
|
13023
13410
|
return {
|
|
@@ -13077,9 +13464,32 @@ var migrateFumadocsProject = async (root) => {
|
|
|
13077
13464
|
|
|
13078
13465
|
// src/migrate/mintlify/index.ts
|
|
13079
13466
|
import { existsSync as existsSync25 } from "node:fs";
|
|
13080
|
-
import { mkdir as mkdir9, readFile as
|
|
13081
|
-
import { dirname as dirname17, join as
|
|
13467
|
+
import { mkdir as mkdir9, readFile as readFile20, rename as rename4, rm as rm4, stat as stat2, writeFile as writeFile13 } from "node:fs/promises";
|
|
13468
|
+
import { dirname as dirname17, join as join37 } from "pathe";
|
|
13082
13469
|
import { glob as glob9 } from "tinyglobby";
|
|
13470
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
13471
|
+
var hasFontFamily = (value) => {
|
|
13472
|
+
const object = asRecord(value);
|
|
13473
|
+
if (!object) {
|
|
13474
|
+
return false;
|
|
13475
|
+
}
|
|
13476
|
+
const named = (child) => typeof asRecord(child)?.family === "string";
|
|
13477
|
+
return typeof object.family === "string" || named(object.heading) || named(object.body);
|
|
13478
|
+
};
|
|
13479
|
+
var droppedChromeWarnings = (spec, config) => {
|
|
13480
|
+
const warnings = [];
|
|
13481
|
+
const navbar = asRecord(spec.navbar);
|
|
13482
|
+
if (navbar && (navbar.links || navbar.primary)) {
|
|
13483
|
+
warnings.push("Header links (navbar.links/navbar.primary) have no blume.config equivalent and were dropped; re-add them with navigation.tabs or a Header layout override.");
|
|
13484
|
+
}
|
|
13485
|
+
if (asRecord(spec.footer)?.socials) {
|
|
13486
|
+
warnings.push("Footer social links (footer.socials) have no blume.config equivalent and were dropped; add them with a Footer layout override.");
|
|
13487
|
+
}
|
|
13488
|
+
if (hasFontFamily(spec.fonts ?? spec.font) && !config.theme?.fonts) {
|
|
13489
|
+
warnings.push("docs.json font family isn't in Blume's curated Google Fonts set; set theme.fonts to a supported slug or add @font-face rules in theme.css.");
|
|
13490
|
+
}
|
|
13491
|
+
return warnings;
|
|
13492
|
+
};
|
|
13083
13493
|
var prune = (value) => {
|
|
13084
13494
|
if (Array.isArray(value)) {
|
|
13085
13495
|
return value.map(prune);
|
|
@@ -13108,13 +13518,13 @@ var writeBlumeConfig2 = async (root, config) => {
|
|
|
13108
13518
|
|
|
13109
13519
|
export default defineConfig(${JSON.stringify(prune(config), null, 2)});
|
|
13110
13520
|
`;
|
|
13111
|
-
await writeFile13(
|
|
13521
|
+
await writeFile13(join37(root, "blume.config.ts"), body, "utf-8");
|
|
13112
13522
|
};
|
|
13113
13523
|
var relocateAssets = async (root, segments) => {
|
|
13114
13524
|
const served = [];
|
|
13115
13525
|
const moved = [];
|
|
13116
13526
|
for (const segment of segments) {
|
|
13117
|
-
const source =
|
|
13527
|
+
const source = join37(root, segment);
|
|
13118
13528
|
if (!existsSync25(source) || segment === "public") {
|
|
13119
13529
|
continue;
|
|
13120
13530
|
}
|
|
@@ -13123,11 +13533,11 @@ var relocateAssets = async (root, segments) => {
|
|
|
13123
13533
|
served.push(segment);
|
|
13124
13534
|
continue;
|
|
13125
13535
|
}
|
|
13126
|
-
const dest =
|
|
13536
|
+
const dest = join37(root, "public", segment);
|
|
13127
13537
|
if (existsSync25(dest)) {
|
|
13128
13538
|
continue;
|
|
13129
13539
|
}
|
|
13130
|
-
await mkdir9(
|
|
13540
|
+
await mkdir9(join37(root, "public"), { recursive: true });
|
|
13131
13541
|
await rename4(source, dest);
|
|
13132
13542
|
moved.push(segment);
|
|
13133
13543
|
}
|
|
@@ -13148,7 +13558,7 @@ var applyRelocatedAssets = (config, assets, warnings) => {
|
|
|
13148
13558
|
}
|
|
13149
13559
|
};
|
|
13150
13560
|
var cleanupSnippets = async (root, kept, warnings) => {
|
|
13151
|
-
const dir =
|
|
13561
|
+
const dir = join37(root, "snippets");
|
|
13152
13562
|
if (!existsSync25(dir)) {
|
|
13153
13563
|
return;
|
|
13154
13564
|
}
|
|
@@ -13169,11 +13579,11 @@ var cleanupSnippets = async (root, kept, warnings) => {
|
|
|
13169
13579
|
};
|
|
13170
13580
|
var migrateMintlifyProject = async (root) => {
|
|
13171
13581
|
const warnings = [];
|
|
13172
|
-
const configFile = existsSync25(
|
|
13582
|
+
const configFile = existsSync25(join37(root, "docs.json")) ? join37(root, "docs.json") : join37(root, "mint.json");
|
|
13173
13583
|
let config;
|
|
13174
13584
|
if (existsSync25(configFile)) {
|
|
13175
13585
|
config = await loadMintlifyConfig(root, configFile);
|
|
13176
|
-
const spec = JSON.parse(await
|
|
13586
|
+
const spec = JSON.parse(await readFile20(configFile, "utf-8"));
|
|
13177
13587
|
const i18n = mintlifyI18n(spec);
|
|
13178
13588
|
if (i18n) {
|
|
13179
13589
|
config.i18n = i18n;
|
|
@@ -13182,6 +13592,11 @@ var migrateMintlifyProject = async (root) => {
|
|
|
13182
13592
|
}
|
|
13183
13593
|
warnings.push(`Mapped ${i18n.locales.length} languages to i18n.locales (default: ${i18n.defaultLocale}); review the locale labels.`);
|
|
13184
13594
|
}
|
|
13595
|
+
const openapiSources = config.openapi?.sources ?? [];
|
|
13596
|
+
if (openapiSources.length > 0) {
|
|
13597
|
+
warnings.push(`Mapped ${openapiSources.length} OpenAPI spec source(s) to openapi.sources (native reference renderer); verify each spec path or URL resolves.`);
|
|
13598
|
+
}
|
|
13599
|
+
warnings.push(...droppedChromeWarnings(spec, config));
|
|
13185
13600
|
} else {
|
|
13186
13601
|
warnings.push("No docs.json or mint.json found; writing a default config.");
|
|
13187
13602
|
config = { content: { root: "." }, title: "Documentation" };
|
|
@@ -13204,7 +13619,7 @@ var migrateMintlifyProject = async (root) => {
|
|
|
13204
13619
|
const unsupported = new Set;
|
|
13205
13620
|
const keptComponents = new Set;
|
|
13206
13621
|
for (const file of files) {
|
|
13207
|
-
const raw = await
|
|
13622
|
+
const raw = await readFile20(file, "utf-8");
|
|
13208
13623
|
const result = await transformMintlifyContent(raw, {
|
|
13209
13624
|
filePath: file,
|
|
13210
13625
|
root,
|
|
@@ -13239,7 +13654,7 @@ var migrateMintlifyProject = async (root) => {
|
|
|
13239
13654
|
warnings.push(`Dropped unsupported page frontmatter keys: ${[...removedKeys].join(", ")}.`);
|
|
13240
13655
|
}
|
|
13241
13656
|
if (unsupported.size > 0) {
|
|
13242
|
-
warnings.push(`Components without a Blume equivalent need manual review
|
|
13657
|
+
warnings.push(`Components without a Blume equivalent need manual review: ${[...unsupported].join(", ")}.`);
|
|
13243
13658
|
}
|
|
13244
13659
|
warnings.push("Review blume.config.ts; navigation, theme, and chrome were mapped from docs.json.");
|
|
13245
13660
|
return { moved, warnings };
|
|
@@ -13247,8 +13662,8 @@ var migrateMintlifyProject = async (root) => {
|
|
|
13247
13662
|
|
|
13248
13663
|
// src/migrate/nextra/index.ts
|
|
13249
13664
|
import { existsSync as existsSync26 } from "node:fs";
|
|
13250
|
-
import { mkdir as mkdir10, readFile as
|
|
13251
|
-
import { basename as basename7, dirname as dirname18, extname as extname8, join as
|
|
13665
|
+
import { mkdir as mkdir10, readFile as readFile21, rename as rename5, rm as rm5, writeFile as writeFile14 } from "node:fs/promises";
|
|
13666
|
+
import { basename as basename7, dirname as dirname18, extname as extname8, join as join38, relative as relative20 } from "pathe";
|
|
13252
13667
|
import { glob as glob10 } from "tinyglobby";
|
|
13253
13668
|
|
|
13254
13669
|
// src/migrate/nextra/content.ts
|
|
@@ -13530,7 +13945,7 @@ var planMetas = (metas, index) => {
|
|
|
13530
13945
|
plan.metaByDir.set(dir, conversion.folderMeta);
|
|
13531
13946
|
plan.consumedMetas.push(meta.abs);
|
|
13532
13947
|
for (const [slug, title] of Object.entries(conversion.folderTitles)) {
|
|
13533
|
-
plan.folderTitleByDir.set(normalizeDir(
|
|
13948
|
+
plan.folderTitleByDir.set(normalizeDir(join38(dir, slug)), title);
|
|
13534
13949
|
}
|
|
13535
13950
|
for (const [slug, label] of Object.entries(conversion.pageLabels)) {
|
|
13536
13951
|
const pageAbs = index.pagesByDir.get(dir)?.get(slug);
|
|
@@ -13555,11 +13970,11 @@ var planMetas = (metas, index) => {
|
|
|
13555
13970
|
};
|
|
13556
13971
|
var movePage2 = async (abs, options) => {
|
|
13557
13972
|
const rel = relative20(options.base, abs);
|
|
13558
|
-
const dest =
|
|
13973
|
+
const dest = join38(options.root, "docs", rel);
|
|
13559
13974
|
if (existsSync26(dest)) {
|
|
13560
13975
|
return { moved: 0, removed: [], skipped: rel, unsupported: [] };
|
|
13561
13976
|
}
|
|
13562
|
-
const raw = await
|
|
13977
|
+
const raw = await readFile21(abs, "utf-8");
|
|
13563
13978
|
const text = rewriteNextraCallouts(stripNextraImports(raw));
|
|
13564
13979
|
const unsupported = unsupportedNextraComponents(text);
|
|
13565
13980
|
const parsed = frontmatter_default(text);
|
|
@@ -13608,7 +14023,7 @@ var writeFolderMetas = async (root, plan) => {
|
|
|
13608
14023
|
if (Object.keys(finalMeta).length === 0) {
|
|
13609
14024
|
return;
|
|
13610
14025
|
}
|
|
13611
|
-
const dest =
|
|
14026
|
+
const dest = join38(root, "docs", dir, "meta.ts");
|
|
13612
14027
|
await mkdir10(dirname18(dest), { recursive: true });
|
|
13613
14028
|
await writeFile14(dest, `import { defineMeta } from "blume";
|
|
13614
14029
|
|
|
@@ -13619,7 +14034,7 @@ export default defineMeta(${JSON.stringify(finalMeta, null, 2)});
|
|
|
13619
14034
|
var relocateUnparseableMetas = async (root, metas) => {
|
|
13620
14035
|
const warnings = [];
|
|
13621
14036
|
await Promise.all(metas.map(async ({ abs, rel }) => {
|
|
13622
|
-
const dest =
|
|
14037
|
+
const dest = join38(root, "docs", rel);
|
|
13623
14038
|
if (existsSync26(dest)) {
|
|
13624
14039
|
warnings.push(`Skipped ${rel} (target already exists)`);
|
|
13625
14040
|
return;
|
|
@@ -13632,7 +14047,7 @@ var relocateUnparseableMetas = async (root, metas) => {
|
|
|
13632
14047
|
};
|
|
13633
14048
|
var buildConfig = (tabs) => tabs.length > 0 ? { navigation: { tabs }, title: "Documentation" } : { title: "Documentation" };
|
|
13634
14049
|
var migrateNextraProject = async (root) => {
|
|
13635
|
-
const sourceDir = SOURCE_DIRS.find((dir) => existsSync26(
|
|
14050
|
+
const sourceDir = SOURCE_DIRS.find((dir) => existsSync26(join38(root, dir)));
|
|
13636
14051
|
if (!sourceDir) {
|
|
13637
14052
|
await writeBlumeConfig(root, { title: "Documentation" });
|
|
13638
14053
|
return {
|
|
@@ -13642,7 +14057,7 @@ var migrateNextraProject = async (root) => {
|
|
|
13642
14057
|
]
|
|
13643
14058
|
};
|
|
13644
14059
|
}
|
|
13645
|
-
const base =
|
|
14060
|
+
const base = join38(root, sourceDir);
|
|
13646
14061
|
const pageFiles = await glob10([PAGE_GLOB2], {
|
|
13647
14062
|
absolute: true,
|
|
13648
14063
|
cwd: base,
|
|
@@ -13657,7 +14072,7 @@ var migrateNextraProject = async (root) => {
|
|
|
13657
14072
|
const metas = await Promise.all(metaFiles.map(async (abs) => ({
|
|
13658
14073
|
abs,
|
|
13659
14074
|
ext: extname8(abs),
|
|
13660
|
-
raw: await
|
|
14075
|
+
raw: await readFile21(abs, "utf-8"),
|
|
13661
14076
|
rel: relative20(base, abs)
|
|
13662
14077
|
})));
|
|
13663
14078
|
const plan = planMetas(metas, index);
|
|
@@ -13684,14 +14099,14 @@ var migrateNextraProject = async (root) => {
|
|
|
13684
14099
|
|
|
13685
14100
|
// src/migrate/starlight/index.ts
|
|
13686
14101
|
import { existsSync as existsSync28 } from "node:fs";
|
|
13687
|
-
import { readFile as
|
|
13688
|
-
import { join as
|
|
14102
|
+
import { readFile as readFile23, writeFile as writeFile15 } from "node:fs/promises";
|
|
14103
|
+
import { join as join40 } from "pathe";
|
|
13689
14104
|
import { glob as glob11 } from "tinyglobby";
|
|
13690
14105
|
|
|
13691
14106
|
// src/migrate/starlight/config.ts
|
|
13692
14107
|
import { existsSync as existsSync27 } from "node:fs";
|
|
13693
|
-
import { readFile as
|
|
13694
|
-
import { join as
|
|
14108
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
14109
|
+
import { join as join39 } from "pathe";
|
|
13695
14110
|
var CONFIG_FILES = [
|
|
13696
14111
|
"astro.config.mjs",
|
|
13697
14112
|
"astro.config.mts",
|
|
@@ -13722,7 +14137,7 @@ var extractStarlightOptions = (source) => {
|
|
|
13722
14137
|
return isLiteralObject(parsed) ? parsed : "unparseable";
|
|
13723
14138
|
};
|
|
13724
14139
|
var loadStarlightConfig = async (root) => {
|
|
13725
|
-
const file = CONFIG_FILES.map((name) =>
|
|
14140
|
+
const file = CONFIG_FILES.map((name) => join39(root, name)).find((path) => existsSync27(path));
|
|
13726
14141
|
if (!file) {
|
|
13727
14142
|
return {
|
|
13728
14143
|
options: {},
|
|
@@ -13731,7 +14146,7 @@ var loadStarlightConfig = async (root) => {
|
|
|
13731
14146
|
]
|
|
13732
14147
|
};
|
|
13733
14148
|
}
|
|
13734
|
-
const source = await
|
|
14149
|
+
const source = await readFile22(file, "utf-8");
|
|
13735
14150
|
const result = extractStarlightOptions(source);
|
|
13736
14151
|
if (result === "missing") {
|
|
13737
14152
|
return {
|
|
@@ -14129,7 +14544,7 @@ var starlightI18n = (options) => {
|
|
|
14129
14544
|
// src/migrate/starlight/index.ts
|
|
14130
14545
|
var CONTENT_DIR = "src/content/docs";
|
|
14131
14546
|
var transformPage = async (file) => {
|
|
14132
|
-
const raw = await
|
|
14547
|
+
const raw = await readFile23(file, "utf-8");
|
|
14133
14548
|
let text = stripStarlightImports(raw);
|
|
14134
14549
|
text = rewriteStarlightAsides(text);
|
|
14135
14550
|
text = rewriteStarlightComponents(text);
|
|
@@ -14151,7 +14566,7 @@ var migrateStarlightProject = async (root) => {
|
|
|
14151
14566
|
config.i18n = i18n;
|
|
14152
14567
|
warnings.push(`Mapped ${i18n.locales.length} locale(s) to i18n (default: ${i18n.defaultLocale}); review the locale labels.`);
|
|
14153
14568
|
}
|
|
14154
|
-
const base =
|
|
14569
|
+
const base = join40(root, CONTENT_DIR);
|
|
14155
14570
|
if (!existsSync28(base)) {
|
|
14156
14571
|
await writeBlumeConfig(root, config);
|
|
14157
14572
|
return {
|
|
@@ -14243,7 +14658,7 @@ var migrateCommand = defineCommand8({
|
|
|
14243
14658
|
import { existsSync as existsSync29 } from "node:fs";
|
|
14244
14659
|
import { preview } from "astro";
|
|
14245
14660
|
import { defineCommand as defineCommand9 } from "citty";
|
|
14246
|
-
import { join as
|
|
14661
|
+
import { join as join41 } from "pathe";
|
|
14247
14662
|
var previewCommand = defineCommand9({
|
|
14248
14663
|
args: {
|
|
14249
14664
|
host: { description: "Network host to bind.", type: "string" },
|
|
@@ -14257,7 +14672,7 @@ var previewCommand = defineCommand9({
|
|
|
14257
14672
|
const root = process.cwd();
|
|
14258
14673
|
const { config } = await loadConfig(root);
|
|
14259
14674
|
const context = resolveProjectContext(root, config);
|
|
14260
|
-
if (!existsSync29(
|
|
14675
|
+
if (!existsSync29(join41(context.outDir, "astro.config.mjs"))) {
|
|
14261
14676
|
logger.error("No build found. Run `blume build` first.");
|
|
14262
14677
|
process.exit(1);
|
|
14263
14678
|
}
|
|
@@ -14275,7 +14690,7 @@ var previewCommand = defineCommand9({
|
|
|
14275
14690
|
// src/cli/commands/sync.ts
|
|
14276
14691
|
import { rm as rm6 } from "node:fs/promises";
|
|
14277
14692
|
import { defineCommand as defineCommand10 } from "citty";
|
|
14278
|
-
import { join as
|
|
14693
|
+
import { join as join42 } from "pathe";
|
|
14279
14694
|
var syncCommand = defineCommand10({
|
|
14280
14695
|
args: {
|
|
14281
14696
|
force: {
|
|
@@ -14297,7 +14712,7 @@ var syncCommand = defineCommand10({
|
|
|
14297
14712
|
if (args.force) {
|
|
14298
14713
|
const { config } = await loadConfig(root);
|
|
14299
14714
|
const context = resolveProjectContext(root, config);
|
|
14300
|
-
await rm6(
|
|
14715
|
+
await rm6(join42(context.outDir, "cache"), { force: true, recursive: true });
|
|
14301
14716
|
logger.info("Cleared source cache.");
|
|
14302
14717
|
}
|
|
14303
14718
|
await prepareProject({
|
|
@@ -14314,11 +14729,11 @@ var syncCommand = defineCommand10({
|
|
|
14314
14729
|
// src/cli/commands/validate.ts
|
|
14315
14730
|
import { existsSync as existsSync31 } from "node:fs";
|
|
14316
14731
|
import { defineCommand as defineCommand11 } from "citty";
|
|
14317
|
-
import { join as
|
|
14732
|
+
import { join as join44 } from "pathe";
|
|
14318
14733
|
|
|
14319
14734
|
// src/core/links.ts
|
|
14320
14735
|
import { existsSync as existsSync30 } from "node:fs";
|
|
14321
|
-
import { basename as basename8, join as
|
|
14736
|
+
import { basename as basename8, join as join43 } from "pathe";
|
|
14322
14737
|
var HTTP = /^https?:\/\//iu;
|
|
14323
14738
|
var PROTOCOL_RELATIVE = /^\/\//u;
|
|
14324
14739
|
var SCHEME = /^[a-z][a-z0-9+.-]*:/iu;
|
|
@@ -14331,10 +14746,10 @@ var STATUS_GONE = 410;
|
|
|
14331
14746
|
var STATUS_METHOD_NOT_ALLOWED = 405;
|
|
14332
14747
|
var STATUS_NOT_IMPLEMENTED = 501;
|
|
14333
14748
|
var assetIsPresent = (resolved, ctx) => {
|
|
14334
|
-
if (ctx.publicDir && existsSync30(
|
|
14749
|
+
if (ctx.publicDir && existsSync30(join43(ctx.publicDir, resolved))) {
|
|
14335
14750
|
return true;
|
|
14336
14751
|
}
|
|
14337
|
-
return ctx.assetMounts.some((mount) => (resolved === mount.url || resolved.startsWith(`${mount.url}/`)) && existsSync30(
|
|
14752
|
+
return ctx.assetMounts.some((mount) => (resolved === mount.url || resolved.startsWith(`${mount.url}/`)) && existsSync30(join43(mount.dir, resolved.slice(mount.url.length))));
|
|
14338
14753
|
};
|
|
14339
14754
|
var isIndexPage = (page2) => {
|
|
14340
14755
|
const ref = page2.source?.ref ?? page2.sourcePath ?? "";
|
|
@@ -14579,7 +14994,7 @@ var validateCommand = defineCommand11({
|
|
|
14579
14994
|
try {
|
|
14580
14995
|
const project = await scanProject(root, { mode: "build" });
|
|
14581
14996
|
diagnostics.push(...project.diagnostics);
|
|
14582
|
-
const publicDir =
|
|
14997
|
+
const publicDir = join44(root, "public");
|
|
14583
14998
|
diagnostics.push(...await validateLinks(project.graph, {
|
|
14584
14999
|
assetMounts: resolveAssetMounts(root, project.config.content.assets),
|
|
14585
15000
|
checkExternal: Boolean(args.external),
|
|
@@ -14644,5 +15059,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
14644
15059
|
});
|
|
14645
15060
|
runMain(main);
|
|
14646
15061
|
|
|
14647
|
-
//# debugId=
|
|
15062
|
+
//# debugId=432F59E1AFBFB0A064756E2164756E21
|
|
14648
15063
|
//# sourceMappingURL=index.js.map
|