@bagelink/blox 1.15.529 → 1.15.533
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/api/types.d.ts +1 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/{shard-runner-BrakAYOw.js → shard-runner-DFZAHrwJ.js} +35 -10
- package/dist/{shard-runner-B_obJ3aA.cjs → shard-runner-DTkniXr1.cjs} +35 -10
- package/dist/ssg/build-request.d.ts +4 -0
- package/dist/ssg/build-request.d.ts.map +1 -1
- package/dist/ssg/cli.cjs +13 -2
- package/dist/ssg/cli.mjs +13 -2
- package/dist/ssg/index.cjs +5 -1
- package/dist/ssg/index.d.ts +3 -1
- package/dist/ssg/index.d.ts.map +1 -1
- package/dist/ssg/index.mjs +18 -14
- package/dist/ssg/prerender.d.ts.map +1 -1
- package/dist/ssg/seo.d.ts +10 -0
- package/dist/ssg/seo.d.ts.map +1 -1
- package/dist/ssg/shard-runner.d.ts.map +1 -1
- package/dist/ssg/validate-output.d.ts +6 -0
- package/dist/ssg/validate-output.d.ts.map +1 -0
- package/dist/{prerender-M2VjuOlc.js → validate-output-C-RpYkvf.js} +202 -25
- package/dist/{prerender-BKt6NiaM.cjs → validate-output-C3NhyFsU.cjs} +185 -8
- package/package.json +1 -1
package/dist/api/types.d.ts
CHANGED
package/dist/api/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
5
|
-
import { f as fetchCmsSiteData, g as generateSitemapXml } from "./
|
|
5
|
+
import { f as fetchCmsSiteData, s as splitSitemapPathsByLocale, l as localeSitemapPath, g as generateSitemapXml, b as generateSitemapIndexXml } from "./validate-output-C-RpYkvf.js";
|
|
6
6
|
const AUTO_SHARD_CAP = Number(process.env.BLOX_SSG_SHARD_CAP) || 6;
|
|
7
7
|
const PREFETCH_BUDGET = Number(process.env.BLOX_SSG_PREFETCH_BUDGET) || 24;
|
|
8
8
|
function resolveShardCount(shards) {
|
|
@@ -58,7 +58,7 @@ function runShard(index, total, paths, opts, llmPartsDir, routePartsDir, siteDat
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
async function runSharded(opts) {
|
|
61
|
-
var _a;
|
|
61
|
+
var _a, _b;
|
|
62
62
|
const total = resolveShardCount(opts.shards);
|
|
63
63
|
const fs = await import("node:fs/promises");
|
|
64
64
|
const paths = [...opts.extraPaths];
|
|
@@ -109,7 +109,7 @@ async function runSharded(opts) {
|
|
|
109
109
|
}
|
|
110
110
|
if (process.env.BLOX_SSG_LLM !== "0") {
|
|
111
111
|
try {
|
|
112
|
-
const { mergeLlmParts } = await import("./
|
|
112
|
+
const { mergeLlmParts } = await import("./validate-output-C-RpYkvf.js").then((n) => n.z);
|
|
113
113
|
const mergeWebsite = website;
|
|
114
114
|
const partFiles = Array.from({ length: total }, (_, i) => path.join(llmPartsDir, `part.${i}.json`));
|
|
115
115
|
const { pages } = await mergeLlmParts({
|
|
@@ -131,13 +131,38 @@ async function runSharded(opts) {
|
|
|
131
131
|
const canonicalBase = (((_a = website.seo) == null ? void 0 : _a.canonical_base_url) || website.domain || "").replace(/\/$/, "");
|
|
132
132
|
const indexableRoutes = [...byUrl.values()].filter((route) => !route.noindex);
|
|
133
133
|
if (canonicalBase && indexableRoutes.length > 0) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
const lastmod = Object.fromEntries(
|
|
135
|
+
indexableRoutes.flatMap((route) => route.lastmod ? [[route.url, route.lastmod]] : [])
|
|
136
|
+
);
|
|
137
|
+
const renderedPaths = indexableRoutes.map((route) => route.url);
|
|
138
|
+
if (((_b = website.seo) == null ? void 0 : _b.sitemap_split_by_locale) !== false) {
|
|
139
|
+
const pathsByLocale = splitSitemapPathsByLocale({
|
|
140
|
+
renderedPaths,
|
|
141
|
+
defaultLocale: website.default_locale,
|
|
142
|
+
supportedLocales: website.supported_locales
|
|
143
|
+
});
|
|
144
|
+
const sitemapPaths = [];
|
|
145
|
+
for (const [locale, localePaths] of pathsByLocale) {
|
|
146
|
+
const sitemapPath = localeSitemapPath(locale);
|
|
147
|
+
await fs.writeFile(path.resolve("dist", sitemapPath.slice(1)), generateSitemapXml({
|
|
148
|
+
renderedPaths: localePaths,
|
|
149
|
+
canonicalBase,
|
|
150
|
+
lastmod
|
|
151
|
+
}), "utf8");
|
|
152
|
+
sitemapPaths.push(sitemapPath);
|
|
153
|
+
}
|
|
154
|
+
await fs.writeFile(
|
|
155
|
+
path.resolve("dist", "sitemap.xml"),
|
|
156
|
+
generateSitemapIndexXml({ canonicalBase, sitemapPaths }),
|
|
157
|
+
"utf8"
|
|
158
|
+
);
|
|
159
|
+
} else {
|
|
160
|
+
await fs.writeFile(path.resolve("dist", "sitemap.xml"), generateSitemapXml({
|
|
161
|
+
renderedPaths,
|
|
162
|
+
canonicalBase,
|
|
163
|
+
lastmod
|
|
164
|
+
}), "utf8");
|
|
165
|
+
}
|
|
141
166
|
}
|
|
142
167
|
await fs.rm(routePartsDir, { recursive: true, force: true });
|
|
143
168
|
await fs.rm(siteDataFile, { force: true }).catch(() => {
|
|
@@ -26,7 +26,7 @@ const node_child_process = require("node:child_process");
|
|
|
26
26
|
const os = require("node:os");
|
|
27
27
|
const path = require("node:path");
|
|
28
28
|
const process = require("node:process");
|
|
29
|
-
const llmArtifacts = require("./
|
|
29
|
+
const llmArtifacts = require("./validate-output-C3NhyFsU.cjs");
|
|
30
30
|
const AUTO_SHARD_CAP = Number(process.env.BLOX_SSG_SHARD_CAP) || 6;
|
|
31
31
|
const PREFETCH_BUDGET = Number(process.env.BLOX_SSG_PREFETCH_BUDGET) || 24;
|
|
32
32
|
function resolveShardCount(shards) {
|
|
@@ -82,7 +82,7 @@ function runShard(index, total, paths, opts, llmPartsDir, routePartsDir, siteDat
|
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
async function runSharded(opts) {
|
|
85
|
-
var _a;
|
|
85
|
+
var _a, _b;
|
|
86
86
|
const total = resolveShardCount(opts.shards);
|
|
87
87
|
const fs = await import("node:fs/promises");
|
|
88
88
|
const paths = [...opts.extraPaths];
|
|
@@ -133,7 +133,7 @@ async function runSharded(opts) {
|
|
|
133
133
|
}
|
|
134
134
|
if (process.env.BLOX_SSG_LLM !== "0") {
|
|
135
135
|
try {
|
|
136
|
-
const { mergeLlmParts } = await Promise.resolve().then(() => require("./
|
|
136
|
+
const { mergeLlmParts } = await Promise.resolve().then(() => require("./validate-output-C3NhyFsU.cjs")).then((n) => n.llmArtifacts);
|
|
137
137
|
const mergeWebsite = website;
|
|
138
138
|
const partFiles = Array.from({ length: total }, (_, i) => path.join(llmPartsDir, `part.${i}.json`));
|
|
139
139
|
const { pages } = await mergeLlmParts({
|
|
@@ -155,13 +155,38 @@ async function runSharded(opts) {
|
|
|
155
155
|
const canonicalBase = (((_a = website.seo) == null ? void 0 : _a.canonical_base_url) || website.domain || "").replace(/\/$/, "");
|
|
156
156
|
const indexableRoutes = [...byUrl.values()].filter((route) => !route.noindex);
|
|
157
157
|
if (canonicalBase && indexableRoutes.length > 0) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
158
|
+
const lastmod = Object.fromEntries(
|
|
159
|
+
indexableRoutes.flatMap((route) => route.lastmod ? [[route.url, route.lastmod]] : [])
|
|
160
|
+
);
|
|
161
|
+
const renderedPaths = indexableRoutes.map((route) => route.url);
|
|
162
|
+
if (((_b = website.seo) == null ? void 0 : _b.sitemap_split_by_locale) !== false) {
|
|
163
|
+
const pathsByLocale = llmArtifacts.splitSitemapPathsByLocale({
|
|
164
|
+
renderedPaths,
|
|
165
|
+
defaultLocale: website.default_locale,
|
|
166
|
+
supportedLocales: website.supported_locales
|
|
167
|
+
});
|
|
168
|
+
const sitemapPaths = [];
|
|
169
|
+
for (const [locale, localePaths] of pathsByLocale) {
|
|
170
|
+
const sitemapPath = llmArtifacts.localeSitemapPath(locale);
|
|
171
|
+
await fs.writeFile(path.resolve("dist", sitemapPath.slice(1)), llmArtifacts.generateSitemapXml({
|
|
172
|
+
renderedPaths: localePaths,
|
|
173
|
+
canonicalBase,
|
|
174
|
+
lastmod
|
|
175
|
+
}), "utf8");
|
|
176
|
+
sitemapPaths.push(sitemapPath);
|
|
177
|
+
}
|
|
178
|
+
await fs.writeFile(
|
|
179
|
+
path.resolve("dist", "sitemap.xml"),
|
|
180
|
+
llmArtifacts.generateSitemapIndexXml({ canonicalBase, sitemapPaths }),
|
|
181
|
+
"utf8"
|
|
182
|
+
);
|
|
183
|
+
} else {
|
|
184
|
+
await fs.writeFile(path.resolve("dist", "sitemap.xml"), llmArtifacts.generateSitemapXml({
|
|
185
|
+
renderedPaths,
|
|
186
|
+
canonicalBase,
|
|
187
|
+
lastmod
|
|
188
|
+
}), "utf8");
|
|
189
|
+
}
|
|
165
190
|
}
|
|
166
191
|
await fs.rm(routePartsDir, { recursive: true, force: true });
|
|
167
192
|
await fs.rm(siteDataFile, { force: true }).catch(() => {
|
|
@@ -7,6 +7,10 @@ export interface BloxBuildRequestOptions {
|
|
|
7
7
|
tokenScheme?: string;
|
|
8
8
|
/** Additional build-only headers. */
|
|
9
9
|
headers?: HeadersInit;
|
|
10
|
+
/** Total attempts for transient network, 429, and 5xx failures. @default 4 */
|
|
11
|
+
retryAttempts?: number;
|
|
12
|
+
/** Initial retry delay in milliseconds; doubles per attempt. @default 500 */
|
|
13
|
+
retryBaseMs?: number;
|
|
10
14
|
}
|
|
11
15
|
export declare class BloxBuildResponseError extends Error {
|
|
12
16
|
readonly status: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request.d.ts","sourceRoot":"","sources":["../../src/ssg/build-request.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACvC,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"build-request.d.ts","sourceRoot":"","sources":["../../src/ssg/build-request.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACvC,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,sBAAuB,SAAQ,KAAK;aAE/B,MAAM,EAAE,MAAM;aACd,GAAG,EAAE,MAAM;gBADX,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EAC3B,UAAU,EAAE,MAAM;CAKnB;AAMD,uFAAuF;AACvF,wBAAgB,0BAA0B,CACzC,SAAS,GAAE,uBAA4B,GACrC,uBAAuB,CAWzB;AAMD,gFAAgF;AAChF,wBAAsB,gBAAgB,CACrC,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,uBAA4B,GACnC,OAAO,CAAC,QAAQ,CAAC,CAiCnB;AAED,sEAAsE;AACtE,wBAAsB,aAAa,CAAC,CAAC,EACpC,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,uBAA4B,GACnC,OAAO,CAAC,CAAC,CAAC,CAQZ"}
|
package/dist/ssg/cli.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
const process = require("node:process");
|
|
4
4
|
const fs = require("node:fs/promises");
|
|
5
|
-
const llmArtifacts = require("../
|
|
5
|
+
const llmArtifacts = require("../validate-output-C3NhyFsU.cjs");
|
|
6
6
|
function installFetchTimeout() {
|
|
7
7
|
const ms = Number(process.env.BLOX_SSG_FETCH_TIMEOUT_MS) || 2e4;
|
|
8
8
|
const original = globalThis.fetch;
|
|
@@ -56,6 +56,7 @@ async function main() {
|
|
|
56
56
|
let shardsOpt = null;
|
|
57
57
|
let routesCmd = "";
|
|
58
58
|
let siteDataFile = "";
|
|
59
|
+
let validateOutDir = "";
|
|
59
60
|
const passthroughArgs = [];
|
|
60
61
|
const excludePaths = ["/_blox_preview"];
|
|
61
62
|
for (const a of argv) {
|
|
@@ -71,6 +72,10 @@ async function main() {
|
|
|
71
72
|
routesCmd = a.slice("--routes-cmd=".length);
|
|
72
73
|
} else if (a.startsWith("--site-data=")) {
|
|
73
74
|
siteDataFile = a.slice("--site-data=".length);
|
|
75
|
+
} else if (a === "--validate") {
|
|
76
|
+
validateOutDir = "dist";
|
|
77
|
+
} else if (a.startsWith("--validate=")) {
|
|
78
|
+
validateOutDir = a.slice("--validate=".length);
|
|
74
79
|
} else if (a.startsWith("--shard=")) {
|
|
75
80
|
const [i, n] = a.slice("--shard=".length).split("/").map(Number);
|
|
76
81
|
if (Number.isInteger(i) && Number.isInteger(n) && n > 0 && i >= 0 && i < n) {
|
|
@@ -95,6 +100,7 @@ Options:
|
|
|
95
100
|
--shard=<i/n> (internal) Render only this shard's slice — set by --shards.
|
|
96
101
|
--routes-cmd=<cmd> Shell command whose stdout (whitespace-separated) is the
|
|
97
102
|
route list. For router-driven sites with no CMS pages.
|
|
103
|
+
--validate[=dir] Validate generated SSG assets (default directory: dist).
|
|
98
104
|
--help, -h Show this help
|
|
99
105
|
|
|
100
106
|
Environment:
|
|
@@ -120,10 +126,15 @@ Environment:
|
|
|
120
126
|
extraPaths.push(a);
|
|
121
127
|
}
|
|
122
128
|
}
|
|
129
|
+
if (validateOutDir) {
|
|
130
|
+
await llmArtifacts.validateSsgOutput({ outDir: validateOutDir });
|
|
131
|
+
console.log(`[blox-ssg] validated output in ${validateOutDir}`);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
123
134
|
if (shardsOpt !== null || routesCmd) {
|
|
124
135
|
const { apiBase: apiBase2, websiteName: configWebsiteName2 } = await resolveApiBase(mode);
|
|
125
136
|
const websiteName2 = process.env.WEBSITE_NAME ?? configWebsiteName2 ?? "default";
|
|
126
|
-
const { runSharded } = await Promise.resolve().then(() => require("../shard-runner-
|
|
137
|
+
const { runSharded } = await Promise.resolve().then(() => require("../shard-runner-DTkniXr1.cjs"));
|
|
127
138
|
const code = await runSharded({
|
|
128
139
|
shards: shardsOpt ?? "auto",
|
|
129
140
|
mode,
|
package/dist/ssg/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
|
-
import { u as uploadBloxManifest, p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../
|
|
4
|
+
import { v as validateSsgOutput, u as uploadBloxManifest, p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../validate-output-C-RpYkvf.js";
|
|
5
5
|
function installFetchTimeout() {
|
|
6
6
|
const ms = Number(process.env.BLOX_SSG_FETCH_TIMEOUT_MS) || 2e4;
|
|
7
7
|
const original = globalThis.fetch;
|
|
@@ -55,6 +55,7 @@ async function main() {
|
|
|
55
55
|
let shardsOpt = null;
|
|
56
56
|
let routesCmd = "";
|
|
57
57
|
let siteDataFile = "";
|
|
58
|
+
let validateOutDir = "";
|
|
58
59
|
const passthroughArgs = [];
|
|
59
60
|
const excludePaths = ["/_blox_preview"];
|
|
60
61
|
for (const a of argv) {
|
|
@@ -70,6 +71,10 @@ async function main() {
|
|
|
70
71
|
routesCmd = a.slice("--routes-cmd=".length);
|
|
71
72
|
} else if (a.startsWith("--site-data=")) {
|
|
72
73
|
siteDataFile = a.slice("--site-data=".length);
|
|
74
|
+
} else if (a === "--validate") {
|
|
75
|
+
validateOutDir = "dist";
|
|
76
|
+
} else if (a.startsWith("--validate=")) {
|
|
77
|
+
validateOutDir = a.slice("--validate=".length);
|
|
73
78
|
} else if (a.startsWith("--shard=")) {
|
|
74
79
|
const [i, n] = a.slice("--shard=".length).split("/").map(Number);
|
|
75
80
|
if (Number.isInteger(i) && Number.isInteger(n) && n > 0 && i >= 0 && i < n) {
|
|
@@ -94,6 +99,7 @@ Options:
|
|
|
94
99
|
--shard=<i/n> (internal) Render only this shard's slice — set by --shards.
|
|
95
100
|
--routes-cmd=<cmd> Shell command whose stdout (whitespace-separated) is the
|
|
96
101
|
route list. For router-driven sites with no CMS pages.
|
|
102
|
+
--validate[=dir] Validate generated SSG assets (default directory: dist).
|
|
97
103
|
--help, -h Show this help
|
|
98
104
|
|
|
99
105
|
Environment:
|
|
@@ -119,10 +125,15 @@ Environment:
|
|
|
119
125
|
extraPaths.push(a);
|
|
120
126
|
}
|
|
121
127
|
}
|
|
128
|
+
if (validateOutDir) {
|
|
129
|
+
await validateSsgOutput({ outDir: validateOutDir });
|
|
130
|
+
console.log(`[blox-ssg] validated output in ${validateOutDir}`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
122
133
|
if (shardsOpt !== null || routesCmd) {
|
|
123
134
|
const { apiBase: apiBase2, websiteName: configWebsiteName2 } = await resolveApiBase(mode);
|
|
124
135
|
const websiteName2 = process.env.WEBSITE_NAME ?? configWebsiteName2 ?? "default";
|
|
125
|
-
const { runSharded } = await import("../shard-runner-
|
|
136
|
+
const { runSharded } = await import("../shard-runner-DFZAHrwJ.js");
|
|
126
137
|
const code = await runSharded({
|
|
127
138
|
shards: shardsOpt ?? "auto",
|
|
128
139
|
mode,
|
package/dist/ssg/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
25
|
-
const llmArtifacts = require("../
|
|
25
|
+
const llmArtifacts = require("../validate-output-C3NhyFsU.cjs");
|
|
26
26
|
const ssg_client = require("./client.cjs");
|
|
27
27
|
const pinia = require("pinia");
|
|
28
28
|
const vue = require("vue");
|
|
@@ -268,14 +268,18 @@ exports.generateLlmsFullTxt = llmArtifacts.generateLlmsFullTxt;
|
|
|
268
268
|
exports.generateLlmsTxt = llmArtifacts.generateLlmsTxt;
|
|
269
269
|
exports.generateNetlifyRedirects = llmArtifacts.generateNetlifyRedirects;
|
|
270
270
|
exports.generateRobotsTxt = llmArtifacts.generateRobotsTxt;
|
|
271
|
+
exports.generateSitemapIndexXml = llmArtifacts.generateSitemapIndexXml;
|
|
271
272
|
exports.generateSitemapXml = llmArtifacts.generateSitemapXml;
|
|
272
273
|
exports.getBloxBuildRequestOptions = llmArtifacts.getBloxBuildRequestOptions;
|
|
273
274
|
exports.getSiteIconFlags = llmArtifacts.getSiteIconFlags;
|
|
275
|
+
exports.localeSitemapPath = llmArtifacts.localeSitemapPath;
|
|
274
276
|
exports.mergeLlmParts = llmArtifacts.mergeLlmParts;
|
|
275
277
|
exports.polyfillBloxSsgGlobals = llmArtifacts.polyfillBloxSsgGlobals;
|
|
276
278
|
exports.prerender = llmArtifacts.prerender;
|
|
277
279
|
exports.resolveManifestProvenance = llmArtifacts.resolveManifestProvenance;
|
|
280
|
+
exports.splitSitemapPathsByLocale = llmArtifacts.splitSitemapPathsByLocale;
|
|
278
281
|
exports.uploadBloxManifest = llmArtifacts.uploadBloxManifest;
|
|
282
|
+
exports.validateSsgOutput = llmArtifacts.validateSsgOutput;
|
|
279
283
|
exports.BLOX_COLLECTIONS_WINDOW_KEY = ssg_client.BLOX_COLLECTIONS_WINDOW_KEY;
|
|
280
284
|
exports.BLOX_DATA_WINDOW_KEY = ssg_client.BLOX_DATA_WINDOW_KEY;
|
|
281
285
|
exports.BLOX_PAGE_SEO_WINDOW_KEY = ssg_client.BLOX_PAGE_SEO_WINDOW_KEY;
|
package/dist/ssg/index.d.ts
CHANGED
|
@@ -22,11 +22,13 @@ export { prerender } from './prerender';
|
|
|
22
22
|
export type { PrerenderOptions, PrerenderResult, RenderContext, RenderResult } from './prerender';
|
|
23
23
|
export { renderBloxSsgPage } from './render-resolved-page';
|
|
24
24
|
export type { BloxSsgRouterLike } from './render-resolved-page';
|
|
25
|
-
export { buildPageHead, buildSiteHead, generateNetlifyRedirects, generateRobotsTxt, generateSitemapXml, getSiteIconFlags } from './seo';
|
|
25
|
+
export { buildPageHead, buildSiteHead, generateNetlifyRedirects, generateRobotsTxt, generateSitemapIndexXml, generateSitemapXml, getSiteIconFlags, localeSitemapPath, splitSitemapPathsByLocale } from './seo';
|
|
26
26
|
export type { RedirectEntry, SeoPageData } from './seo';
|
|
27
27
|
export { buildJsonLd, extractPageText, generateLlmsFullTxt, generateLlmsTxt, mergeLlmParts } from './llm-artifacts';
|
|
28
28
|
export type { LlmArtifactsConfig, LlmPageEntry } from './llm-artifacts';
|
|
29
29
|
export { installBloxStateCache } from './state-cache';
|
|
30
30
|
export { resolveManifestProvenance, uploadBloxManifest } from './manifest-upload';
|
|
31
31
|
export type { ManifestProvenance, ManifestUpload } from './manifest-upload';
|
|
32
|
+
export { validateSsgOutput } from './validate-output';
|
|
33
|
+
export type { ValidateSsgOutputOptions } from './validate-output';
|
|
32
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ssg/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ssg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACvE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AACrH,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACrG;;;;;;;;;;GAUG;AACH,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAC5J,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ssg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACvE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AACrH,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACrG;;;;;;;;;;GAUG;AACH,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAC5J,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,OAAO,CAAA;AAC9M,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACnH,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACjF,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA"}
|
package/dist/ssg/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as buildPageHead, d as primaryContextEntry, e as buildJsonLd, h as extractPageText, B as BloxBuildResponseError, i as bloxBuildJson } from "../validate-output-C-RpYkvf.js";
|
|
2
|
+
import { j, k, m, f, n, o, q, r, b, g, t, w, l, x, p, a, y, s, u, v } from "../validate-output-C-RpYkvf.js";
|
|
3
3
|
import { BLOX_STATE_WINDOW_KEY, BLOX_WEBSITE_ID_WINDOW_KEY } from "./client.mjs";
|
|
4
4
|
import { BLOX_COLLECTIONS_WINDOW_KEY, BLOX_DATA_WINDOW_KEY, BLOX_PAGE_SEO_WINDOW_KEY, getCollectionCache, getEmbeddedWebsiteId, installBloxStateCache, installCollectionCache } from "./client.mjs";
|
|
5
5
|
import { createPinia } from "pinia";
|
|
@@ -241,29 +241,33 @@ export {
|
|
|
241
241
|
BLOX_WEBSITE_ID_WINDOW_KEY,
|
|
242
242
|
BloxBuildResponseError,
|
|
243
243
|
bloxBuildJson,
|
|
244
|
-
|
|
244
|
+
j as bloxBuildRequest,
|
|
245
245
|
buildJsonLd,
|
|
246
246
|
buildPageHead,
|
|
247
|
-
|
|
247
|
+
k as buildSiteHead,
|
|
248
248
|
createBloxSSREntry,
|
|
249
249
|
extractPageText,
|
|
250
|
-
|
|
250
|
+
m as fetchCmsPrerenderPaths,
|
|
251
251
|
f as fetchCmsSiteData,
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
n as generateLlmsFullTxt,
|
|
253
|
+
o as generateLlmsTxt,
|
|
254
|
+
q as generateNetlifyRedirects,
|
|
255
|
+
r as generateRobotsTxt,
|
|
256
|
+
b as generateSitemapIndexXml,
|
|
256
257
|
g as generateSitemapXml,
|
|
257
|
-
|
|
258
|
+
t as getBloxBuildRequestOptions,
|
|
258
259
|
getCollectionCache,
|
|
259
260
|
getEmbeddedWebsiteId,
|
|
260
|
-
|
|
261
|
+
w as getSiteIconFlags,
|
|
261
262
|
installBloxStateCache,
|
|
262
263
|
installCollectionCache,
|
|
263
|
-
|
|
264
|
+
l as localeSitemapPath,
|
|
265
|
+
x as mergeLlmParts,
|
|
264
266
|
p as polyfillBloxSsgGlobals,
|
|
265
267
|
a as prerender,
|
|
266
268
|
renderBloxSsgPage,
|
|
267
|
-
|
|
268
|
-
|
|
269
|
+
y as resolveManifestProvenance,
|
|
270
|
+
s as splitSitemapPathsByLocale,
|
|
271
|
+
u as uploadBloxManifest,
|
|
272
|
+
v as validateSsgOutput
|
|
269
273
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../src/ssg/prerender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../src/ssg/prerender.ts"],"names":[],"mappings":"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"}
|
package/dist/ssg/seo.d.ts
CHANGED
|
@@ -67,6 +67,16 @@ export declare function generateSitemapXml(options: {
|
|
|
67
67
|
/** Per-path last-modified ISO timestamps (path → ISO). Emits <lastmod>. */
|
|
68
68
|
lastmod?: Record<string, string>;
|
|
69
69
|
}): string;
|
|
70
|
+
export declare function generateSitemapIndexXml(options: {
|
|
71
|
+
canonicalBase: string;
|
|
72
|
+
sitemapPaths: string[];
|
|
73
|
+
}): string;
|
|
74
|
+
export declare function splitSitemapPathsByLocale(options: {
|
|
75
|
+
renderedPaths: string[];
|
|
76
|
+
defaultLocale: string;
|
|
77
|
+
supportedLocales: string[];
|
|
78
|
+
}): Map<string, string[]>;
|
|
79
|
+
export declare function localeSitemapPath(locale: string): string;
|
|
70
80
|
export declare function generateRobotsTxt(options: {
|
|
71
81
|
robotsTxt?: string | null;
|
|
72
82
|
canonicalBase?: string;
|
package/dist/ssg/seo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/ssg/seo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAOzE,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAWlG;AAED,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,WAAW,GAAG,IAAI,CAAA;IAChC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACnC,CAAA;IACD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,MAAM,CAiHT;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAwCjE;AAMD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC3C,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/ssg/seo.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shard-runner.d.ts","sourceRoot":"","sources":["../../src/ssg/shard-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,MAAM,WAAW,kBAAkB;IAClC,qDAAqD;IACrD,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAA;IACnB,iFAAiF;IACjF,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,8FAA8F;IAC9F,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AA4ED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"shard-runner.d.ts","sourceRoot":"","sources":["../../src/ssg/shard-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,MAAM,WAAW,kBAAkB;IAClC,qDAAqD;IACrD,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAA;IACnB,iFAAiF;IACjF,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,8FAA8F;IAC9F,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AA4ED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+I1E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-output.d.ts","sourceRoot":"","sources":["../../src/ssg/validate-output.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,wBAAwB;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDxF"}
|
|
@@ -21,9 +21,14 @@ function getBloxBuildRequestOptions(overrides = {}) {
|
|
|
21
21
|
token: overrides.token ?? env("BLOX_BUILD_TOKEN"),
|
|
22
22
|
tokenHeader: overrides.tokenHeader ?? env("BLOX_BUILD_TOKEN_HEADER") ?? "Authorization",
|
|
23
23
|
tokenScheme: overrides.tokenScheme ?? env("BLOX_BUILD_TOKEN_SCHEME") ?? "Bearer",
|
|
24
|
-
headers: overrides.headers
|
|
24
|
+
headers: overrides.headers,
|
|
25
|
+
retryAttempts: overrides.retryAttempts ?? (Number(env("BLOX_BUILD_RETRY_ATTEMPTS")) || 4),
|
|
26
|
+
retryBaseMs: overrides.retryBaseMs ?? (Number(env("BLOX_BUILD_RETRY_MS")) || 500)
|
|
25
27
|
};
|
|
26
28
|
}
|
|
29
|
+
function sleep(ms) {
|
|
30
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
31
|
+
}
|
|
27
32
|
async function bloxBuildRequest(input, init = {}, options = {}) {
|
|
28
33
|
const config = getBloxBuildRequestOptions(options);
|
|
29
34
|
const headers = new Headers(config.headers);
|
|
@@ -34,7 +39,28 @@ async function bloxBuildRequest(input, init = {}, options = {}) {
|
|
|
34
39
|
config.tokenScheme ? `${config.tokenScheme} ${config.token}` : config.token
|
|
35
40
|
);
|
|
36
41
|
}
|
|
37
|
-
|
|
42
|
+
const attempts = Math.max(1, config.retryAttempts ?? 4);
|
|
43
|
+
const retryBaseMs = Math.max(0, config.retryBaseMs ?? 500);
|
|
44
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(input, { ...init, headers });
|
|
47
|
+
const transient = response.status === 429 || response.status >= 500;
|
|
48
|
+
if (response.ok || !transient || attempt === attempts) return response;
|
|
49
|
+
const delay = retryBaseMs * 2 ** (attempt - 1);
|
|
50
|
+
console.warn(
|
|
51
|
+
`[blox-build] retry ${attempt}/${attempts} after HTTP ${response.status} in ${delay}ms`
|
|
52
|
+
);
|
|
53
|
+
if (delay) await sleep(delay);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (attempt === attempts) throw error;
|
|
56
|
+
const delay = retryBaseMs * 2 ** (attempt - 1);
|
|
57
|
+
console.warn(
|
|
58
|
+
`[blox-build] retry ${attempt}/${attempts} after ${error.message} in ${delay}ms`
|
|
59
|
+
);
|
|
60
|
+
if (delay) await sleep(delay);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error("Blox build request exhausted retries");
|
|
38
64
|
}
|
|
39
65
|
async function bloxBuildJson(input, init = {}, options = {}) {
|
|
40
66
|
const response = await bloxBuildRequest(input, init, options);
|
|
@@ -409,8 +435,9 @@ function generateSitemapXml(options) {
|
|
|
409
435
|
const mod = lastmod[p];
|
|
410
436
|
const modLine = mod ? `
|
|
411
437
|
<lastmod>${esc(mod)}</lastmod>` : "";
|
|
438
|
+
const loc = p === "/" ? base : base + p;
|
|
412
439
|
return ` <url>
|
|
413
|
-
<loc>${esc(
|
|
440
|
+
<loc>${esc(loc)}</loc>${modLine}
|
|
414
441
|
<changefreq>${changefreq}</changefreq>
|
|
415
442
|
<priority>${priority}</priority>
|
|
416
443
|
</url>`;
|
|
@@ -421,6 +448,35 @@ ${urls.join("\n")}
|
|
|
421
448
|
</urlset>
|
|
422
449
|
`;
|
|
423
450
|
}
|
|
451
|
+
function generateSitemapIndexXml(options) {
|
|
452
|
+
const base = options.canonicalBase.replace(/\/$/, "");
|
|
453
|
+
const sitemaps = options.sitemapPaths.map((path2) => ` <sitemap>
|
|
454
|
+
<loc>${esc(base + path2)}</loc>
|
|
455
|
+
</sitemap>`);
|
|
456
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
457
|
+
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
458
|
+
${sitemaps.join("\n")}
|
|
459
|
+
</sitemapindex>
|
|
460
|
+
`;
|
|
461
|
+
}
|
|
462
|
+
function splitSitemapPathsByLocale(options) {
|
|
463
|
+
const locales = new Set(options.supportedLocales);
|
|
464
|
+
const pathsByLocale = /* @__PURE__ */ new Map();
|
|
465
|
+
for (const path2 of options.renderedPaths) {
|
|
466
|
+
const firstSegment = path2.replace(/^\//, "").split("/")[0];
|
|
467
|
+
const locale = firstSegment && firstSegment !== options.defaultLocale && locales.has(firstSegment) ? firstSegment : options.defaultLocale;
|
|
468
|
+
const paths = pathsByLocale.get(locale) ?? [];
|
|
469
|
+
paths.push(path2);
|
|
470
|
+
pathsByLocale.set(locale, paths);
|
|
471
|
+
}
|
|
472
|
+
return pathsByLocale;
|
|
473
|
+
}
|
|
474
|
+
function localeSitemapPath(locale) {
|
|
475
|
+
if (!/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/.test(locale)) {
|
|
476
|
+
throw new Error(`Invalid sitemap locale: ${locale}`);
|
|
477
|
+
}
|
|
478
|
+
return `/sitemap-${locale}.xml`;
|
|
479
|
+
}
|
|
424
480
|
function generateRobotsTxt(options) {
|
|
425
481
|
const { robotsTxt, canonicalBase, noindex } = options;
|
|
426
482
|
if (noindex) {
|
|
@@ -746,7 +802,7 @@ async function prerender({
|
|
|
746
802
|
collections = {},
|
|
747
803
|
llm = {}
|
|
748
804
|
} = {}) {
|
|
749
|
-
var _a, _b;
|
|
805
|
+
var _a, _b, _c;
|
|
750
806
|
const absRoot = path.resolve(root);
|
|
751
807
|
const absClient = path.resolve(absRoot, clientOutDir);
|
|
752
808
|
const absServerEntry = path.resolve(absRoot, serverEntry);
|
|
@@ -899,15 +955,43 @@ async function prerender({
|
|
|
899
955
|
if (writeSharedAssets) {
|
|
900
956
|
const sitemapPaths = rendered.filter((p) => !noindexPaths.has(p));
|
|
901
957
|
if (canonicalBase && sitemapPaths.length > 0) {
|
|
902
|
-
|
|
903
|
-
|
|
958
|
+
if (((_b = website == null ? void 0 : website.seo) == null ? void 0 : _b.sitemap_split_by_locale) !== false) {
|
|
959
|
+
const pathsByLocale = splitSitemapPathsByLocale({
|
|
960
|
+
renderedPaths: sitemapPaths,
|
|
961
|
+
defaultLocale: (website == null ? void 0 : website.default_locale) ?? "en",
|
|
962
|
+
supportedLocales: (website == null ? void 0 : website.supported_locales) ?? [(website == null ? void 0 : website.default_locale) ?? "en"]
|
|
963
|
+
});
|
|
964
|
+
const sitemapFiles = [];
|
|
965
|
+
for (const [locale, localePaths] of pathsByLocale) {
|
|
966
|
+
const sitemapPath = localeSitemapPath(locale);
|
|
967
|
+
await fs.writeFile(
|
|
968
|
+
path.join(absClient, sitemapPath.slice(1)),
|
|
969
|
+
generateSitemapXml({ renderedPaths: localePaths, canonicalBase, lastmod }),
|
|
970
|
+
"utf8"
|
|
971
|
+
);
|
|
972
|
+
sitemapFiles.push(sitemapPath);
|
|
973
|
+
}
|
|
974
|
+
await fs.writeFile(
|
|
975
|
+
path.join(absClient, "sitemap.xml"),
|
|
976
|
+
generateSitemapIndexXml({ canonicalBase, sitemapPaths: sitemapFiles }),
|
|
977
|
+
"utf8"
|
|
978
|
+
);
|
|
979
|
+
console.log(` Generated sitemap.xml (${sitemapFiles.length} locales, ${sitemapPaths.length} URLs)`);
|
|
980
|
+
} else {
|
|
981
|
+
await fs.writeFile(
|
|
982
|
+
path.join(absClient, "sitemap.xml"),
|
|
983
|
+
generateSitemapXml({ renderedPaths: sitemapPaths, canonicalBase, lastmod }),
|
|
984
|
+
"utf8"
|
|
985
|
+
);
|
|
986
|
+
console.log(` Generated sitemap.xml (${sitemapPaths.length} URLs)`);
|
|
987
|
+
}
|
|
904
988
|
const skipped = noindexPaths.size > 0 ? ` (${noindexPaths.size} noindex excluded)` : "";
|
|
905
|
-
console.log(`
|
|
989
|
+
if (skipped) console.log(` Sitemap exclusions:${skipped}`);
|
|
906
990
|
}
|
|
907
991
|
const robotsTxt = generateRobotsTxt({
|
|
908
992
|
robotsTxt: website == null ? void 0 : website.robots_txt,
|
|
909
993
|
canonicalBase,
|
|
910
|
-
noindex: (
|
|
994
|
+
noindex: (_c = website == null ? void 0 : website.seo) == null ? void 0 : _c.noindex
|
|
911
995
|
});
|
|
912
996
|
await fs.writeFile(path.join(absClient, "robots.txt"), robotsTxt, "utf8");
|
|
913
997
|
console.log(" Generated robots.txt");
|
|
@@ -1087,28 +1171,121 @@ function discoverInternalLinks(html) {
|
|
|
1087
1171
|
}
|
|
1088
1172
|
return [...out];
|
|
1089
1173
|
}
|
|
1174
|
+
const sitemapUrl = /<url>\s*<loc>[^<]+<\/loc>/m;
|
|
1175
|
+
const sitemapIndexEntry = /<sitemap>\s*<loc>[^<]+<\/loc>/gm;
|
|
1176
|
+
const sitemapLoc = /<loc>([^<]+)<\/loc>/;
|
|
1177
|
+
const loadingShell = /class=["'][^"']*\bblox-initial-loading\b/;
|
|
1178
|
+
const embeddedCmsState = /\b__BLOX_(?:STATE|DATA)__\b/;
|
|
1179
|
+
async function validateSsgOutput(options) {
|
|
1180
|
+
const outDir = path.resolve(options.outDir);
|
|
1181
|
+
const failures = [];
|
|
1182
|
+
const requiredFiles = options.requireFiles ?? [
|
|
1183
|
+
"robots.txt",
|
|
1184
|
+
"_redirects",
|
|
1185
|
+
"sitemap.xml",
|
|
1186
|
+
"llms.txt",
|
|
1187
|
+
"llms-full.txt"
|
|
1188
|
+
];
|
|
1189
|
+
const htmlFiles = await collectHtmlFiles(outDir);
|
|
1190
|
+
let hydratedFiles = 0;
|
|
1191
|
+
for (const file of htmlFiles) {
|
|
1192
|
+
const name = path.relative(outDir, file);
|
|
1193
|
+
const html = await fs.readFile(file, "utf8");
|
|
1194
|
+
if (embeddedCmsState.test(html)) hydratedFiles += 1;
|
|
1195
|
+
if (!/<title>[^<]+<\/title>/i.test(html)) failures.push(`${name}: missing page title`);
|
|
1196
|
+
if (!/<link\s[^>]*rel=["']canonical["'][^>]*>/i.test(html)) {
|
|
1197
|
+
failures.push(`${name}: missing canonical URL`);
|
|
1198
|
+
}
|
|
1199
|
+
if (!/<html[^>]*\slang=["'][^"']+["']/i.test(html)) failures.push(`${name}: missing html lang`);
|
|
1200
|
+
if (loadingShell.test(html) && !embeddedCmsState.test(html)) {
|
|
1201
|
+
failures.push(`${name}: contains only the Blox loading shell`);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (!htmlFiles.length) failures.push("output contains no HTML files");
|
|
1205
|
+
if (!hydratedFiles) failures.push("output contains no prerendered Blox hydration state");
|
|
1206
|
+
for (const required of requiredFiles) {
|
|
1207
|
+
try {
|
|
1208
|
+
const content = await fs.readFile(path.join(outDir, required), "utf8");
|
|
1209
|
+
if (required === "robots.txt" && /^Disallow:\s*\/\s*$/im.test(content)) {
|
|
1210
|
+
failures.push("robots.txt blocks the entire site");
|
|
1211
|
+
}
|
|
1212
|
+
if (required === "llms.txt" && !/^- \[[^\]]+\]\([^)]+\)/m.test(content)) {
|
|
1213
|
+
failures.push("llms.txt contains no page links");
|
|
1214
|
+
}
|
|
1215
|
+
if (required === "sitemap.xml") {
|
|
1216
|
+
failures.push(...await validateSitemap(outDir, content));
|
|
1217
|
+
}
|
|
1218
|
+
} catch {
|
|
1219
|
+
failures.push(`missing ${required}`);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (failures.length) {
|
|
1223
|
+
throw new Error(`Invalid Blox SSG output:
|
|
1224
|
+
${failures.map((item) => ` - ${item}`).join("\n")}`);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
async function collectHtmlFiles(directory) {
|
|
1228
|
+
const entries = await fs.readdir(directory, { withFileTypes: true });
|
|
1229
|
+
const files = await Promise.all(entries.map(async (entry) => {
|
|
1230
|
+
const child = path.join(directory, entry.name);
|
|
1231
|
+
if (entry.isDirectory() && entry.name !== "server") return collectHtmlFiles(child);
|
|
1232
|
+
return entry.isFile() && entry.name.endsWith(".html") ? [child] : [];
|
|
1233
|
+
}));
|
|
1234
|
+
return files.flat();
|
|
1235
|
+
}
|
|
1236
|
+
async function validateSitemap(outDir, content) {
|
|
1237
|
+
var _a;
|
|
1238
|
+
if (sitemapUrl.test(content)) return [];
|
|
1239
|
+
const failures = [];
|
|
1240
|
+
const entries = content.match(sitemapIndexEntry) ?? [];
|
|
1241
|
+
if (!entries.length) return ["sitemap.xml contains neither page URLs nor child sitemaps"];
|
|
1242
|
+
let childUrlCount = 0;
|
|
1243
|
+
for (const entry of entries) {
|
|
1244
|
+
const loc = (_a = entry.match(sitemapLoc)) == null ? void 0 : _a[1];
|
|
1245
|
+
if (!loc) continue;
|
|
1246
|
+
const pathname = new URL(loc).pathname.replace(/^\/+/, "");
|
|
1247
|
+
const childPath = path.resolve(outDir, pathname);
|
|
1248
|
+
if (!childPath.startsWith(`${outDir}${path.sep}`)) {
|
|
1249
|
+
failures.push(`child sitemap escapes output directory: ${pathname}`);
|
|
1250
|
+
continue;
|
|
1251
|
+
}
|
|
1252
|
+
try {
|
|
1253
|
+
const child = await fs.readFile(childPath, "utf8");
|
|
1254
|
+
if (!sitemapUrl.test(child)) failures.push(`${pathname} contains no page URLs`);
|
|
1255
|
+
else childUrlCount += (child.match(/<url>/g) ?? []).length;
|
|
1256
|
+
} catch {
|
|
1257
|
+
failures.push(`missing child sitemap ${pathname}`);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
if (!childUrlCount) failures.push("sitemap index child files contain no page URLs");
|
|
1261
|
+
return failures;
|
|
1262
|
+
}
|
|
1090
1263
|
export {
|
|
1091
1264
|
BloxBuildResponseError as B,
|
|
1092
1265
|
prerender as a,
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1266
|
+
generateSitemapIndexXml as b,
|
|
1267
|
+
buildPageHead as c,
|
|
1268
|
+
primaryContextEntry as d,
|
|
1269
|
+
buildJsonLd as e,
|
|
1097
1270
|
fetchCmsSiteData as f,
|
|
1098
1271
|
generateSitemapXml as g,
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1272
|
+
extractPageText as h,
|
|
1273
|
+
bloxBuildJson as i,
|
|
1274
|
+
bloxBuildRequest as j,
|
|
1275
|
+
buildSiteHead as k,
|
|
1276
|
+
localeSitemapPath as l,
|
|
1277
|
+
fetchCmsPrerenderPaths as m,
|
|
1278
|
+
generateLlmsFullTxt as n,
|
|
1279
|
+
generateLlmsTxt as o,
|
|
1107
1280
|
polyfillBloxSsgGlobals as p,
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1281
|
+
generateNetlifyRedirects as q,
|
|
1282
|
+
generateRobotsTxt as r,
|
|
1283
|
+
splitSitemapPathsByLocale as s,
|
|
1284
|
+
getBloxBuildRequestOptions as t,
|
|
1112
1285
|
uploadBloxManifest as u,
|
|
1113
|
-
|
|
1286
|
+
validateSsgOutput as v,
|
|
1287
|
+
getSiteIconFlags as w,
|
|
1288
|
+
mergeLlmParts as x,
|
|
1289
|
+
resolveManifestProvenance as y,
|
|
1290
|
+
llmArtifacts as z
|
|
1114
1291
|
};
|
|
@@ -44,9 +44,14 @@ function getBloxBuildRequestOptions(overrides = {}) {
|
|
|
44
44
|
token: overrides.token ?? env("BLOX_BUILD_TOKEN"),
|
|
45
45
|
tokenHeader: overrides.tokenHeader ?? env("BLOX_BUILD_TOKEN_HEADER") ?? "Authorization",
|
|
46
46
|
tokenScheme: overrides.tokenScheme ?? env("BLOX_BUILD_TOKEN_SCHEME") ?? "Bearer",
|
|
47
|
-
headers: overrides.headers
|
|
47
|
+
headers: overrides.headers,
|
|
48
|
+
retryAttempts: overrides.retryAttempts ?? (Number(env("BLOX_BUILD_RETRY_ATTEMPTS")) || 4),
|
|
49
|
+
retryBaseMs: overrides.retryBaseMs ?? (Number(env("BLOX_BUILD_RETRY_MS")) || 500)
|
|
48
50
|
};
|
|
49
51
|
}
|
|
52
|
+
function sleep(ms) {
|
|
53
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
54
|
+
}
|
|
50
55
|
async function bloxBuildRequest(input, init = {}, options = {}) {
|
|
51
56
|
const config = getBloxBuildRequestOptions(options);
|
|
52
57
|
const headers = new Headers(config.headers);
|
|
@@ -57,7 +62,28 @@ async function bloxBuildRequest(input, init = {}, options = {}) {
|
|
|
57
62
|
config.tokenScheme ? `${config.tokenScheme} ${config.token}` : config.token
|
|
58
63
|
);
|
|
59
64
|
}
|
|
60
|
-
|
|
65
|
+
const attempts = Math.max(1, config.retryAttempts ?? 4);
|
|
66
|
+
const retryBaseMs = Math.max(0, config.retryBaseMs ?? 500);
|
|
67
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
68
|
+
try {
|
|
69
|
+
const response = await fetch(input, { ...init, headers });
|
|
70
|
+
const transient = response.status === 429 || response.status >= 500;
|
|
71
|
+
if (response.ok || !transient || attempt === attempts) return response;
|
|
72
|
+
const delay = retryBaseMs * 2 ** (attempt - 1);
|
|
73
|
+
console.warn(
|
|
74
|
+
`[blox-build] retry ${attempt}/${attempts} after HTTP ${response.status} in ${delay}ms`
|
|
75
|
+
);
|
|
76
|
+
if (delay) await sleep(delay);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (attempt === attempts) throw error;
|
|
79
|
+
const delay = retryBaseMs * 2 ** (attempt - 1);
|
|
80
|
+
console.warn(
|
|
81
|
+
`[blox-build] retry ${attempt}/${attempts} after ${error.message} in ${delay}ms`
|
|
82
|
+
);
|
|
83
|
+
if (delay) await sleep(delay);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
throw new Error("Blox build request exhausted retries");
|
|
61
87
|
}
|
|
62
88
|
async function bloxBuildJson(input, init = {}, options = {}) {
|
|
63
89
|
const response = await bloxBuildRequest(input, init, options);
|
|
@@ -432,8 +458,9 @@ function generateSitemapXml(options) {
|
|
|
432
458
|
const mod = lastmod[p];
|
|
433
459
|
const modLine = mod ? `
|
|
434
460
|
<lastmod>${esc(mod)}</lastmod>` : "";
|
|
461
|
+
const loc = p === "/" ? base : base + p;
|
|
435
462
|
return ` <url>
|
|
436
|
-
<loc>${esc(
|
|
463
|
+
<loc>${esc(loc)}</loc>${modLine}
|
|
437
464
|
<changefreq>${changefreq}</changefreq>
|
|
438
465
|
<priority>${priority}</priority>
|
|
439
466
|
</url>`;
|
|
@@ -444,6 +471,35 @@ ${urls.join("\n")}
|
|
|
444
471
|
</urlset>
|
|
445
472
|
`;
|
|
446
473
|
}
|
|
474
|
+
function generateSitemapIndexXml(options) {
|
|
475
|
+
const base = options.canonicalBase.replace(/\/$/, "");
|
|
476
|
+
const sitemaps = options.sitemapPaths.map((path2) => ` <sitemap>
|
|
477
|
+
<loc>${esc(base + path2)}</loc>
|
|
478
|
+
</sitemap>`);
|
|
479
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
480
|
+
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
481
|
+
${sitemaps.join("\n")}
|
|
482
|
+
</sitemapindex>
|
|
483
|
+
`;
|
|
484
|
+
}
|
|
485
|
+
function splitSitemapPathsByLocale(options) {
|
|
486
|
+
const locales = new Set(options.supportedLocales);
|
|
487
|
+
const pathsByLocale = /* @__PURE__ */ new Map();
|
|
488
|
+
for (const path2 of options.renderedPaths) {
|
|
489
|
+
const firstSegment = path2.replace(/^\//, "").split("/")[0];
|
|
490
|
+
const locale = firstSegment && firstSegment !== options.defaultLocale && locales.has(firstSegment) ? firstSegment : options.defaultLocale;
|
|
491
|
+
const paths = pathsByLocale.get(locale) ?? [];
|
|
492
|
+
paths.push(path2);
|
|
493
|
+
pathsByLocale.set(locale, paths);
|
|
494
|
+
}
|
|
495
|
+
return pathsByLocale;
|
|
496
|
+
}
|
|
497
|
+
function localeSitemapPath(locale) {
|
|
498
|
+
if (!/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/.test(locale)) {
|
|
499
|
+
throw new Error(`Invalid sitemap locale: ${locale}`);
|
|
500
|
+
}
|
|
501
|
+
return `/sitemap-${locale}.xml`;
|
|
502
|
+
}
|
|
447
503
|
function generateRobotsTxt(options) {
|
|
448
504
|
const { robotsTxt, canonicalBase, noindex } = options;
|
|
449
505
|
if (noindex) {
|
|
@@ -769,7 +825,7 @@ async function prerender({
|
|
|
769
825
|
collections = {},
|
|
770
826
|
llm = {}
|
|
771
827
|
} = {}) {
|
|
772
|
-
var _a, _b;
|
|
828
|
+
var _a, _b, _c;
|
|
773
829
|
const absRoot = path.resolve(root);
|
|
774
830
|
const absClient = path.resolve(absRoot, clientOutDir);
|
|
775
831
|
const absServerEntry = path.resolve(absRoot, serverEntry);
|
|
@@ -922,15 +978,43 @@ async function prerender({
|
|
|
922
978
|
if (writeSharedAssets) {
|
|
923
979
|
const sitemapPaths = rendered.filter((p) => !noindexPaths.has(p));
|
|
924
980
|
if (canonicalBase && sitemapPaths.length > 0) {
|
|
925
|
-
|
|
926
|
-
|
|
981
|
+
if (((_b = website == null ? void 0 : website.seo) == null ? void 0 : _b.sitemap_split_by_locale) !== false) {
|
|
982
|
+
const pathsByLocale = splitSitemapPathsByLocale({
|
|
983
|
+
renderedPaths: sitemapPaths,
|
|
984
|
+
defaultLocale: (website == null ? void 0 : website.default_locale) ?? "en",
|
|
985
|
+
supportedLocales: (website == null ? void 0 : website.supported_locales) ?? [(website == null ? void 0 : website.default_locale) ?? "en"]
|
|
986
|
+
});
|
|
987
|
+
const sitemapFiles = [];
|
|
988
|
+
for (const [locale, localePaths] of pathsByLocale) {
|
|
989
|
+
const sitemapPath = localeSitemapPath(locale);
|
|
990
|
+
await fs.writeFile(
|
|
991
|
+
path.join(absClient, sitemapPath.slice(1)),
|
|
992
|
+
generateSitemapXml({ renderedPaths: localePaths, canonicalBase, lastmod }),
|
|
993
|
+
"utf8"
|
|
994
|
+
);
|
|
995
|
+
sitemapFiles.push(sitemapPath);
|
|
996
|
+
}
|
|
997
|
+
await fs.writeFile(
|
|
998
|
+
path.join(absClient, "sitemap.xml"),
|
|
999
|
+
generateSitemapIndexXml({ canonicalBase, sitemapPaths: sitemapFiles }),
|
|
1000
|
+
"utf8"
|
|
1001
|
+
);
|
|
1002
|
+
console.log(` Generated sitemap.xml (${sitemapFiles.length} locales, ${sitemapPaths.length} URLs)`);
|
|
1003
|
+
} else {
|
|
1004
|
+
await fs.writeFile(
|
|
1005
|
+
path.join(absClient, "sitemap.xml"),
|
|
1006
|
+
generateSitemapXml({ renderedPaths: sitemapPaths, canonicalBase, lastmod }),
|
|
1007
|
+
"utf8"
|
|
1008
|
+
);
|
|
1009
|
+
console.log(` Generated sitemap.xml (${sitemapPaths.length} URLs)`);
|
|
1010
|
+
}
|
|
927
1011
|
const skipped = noindexPaths.size > 0 ? ` (${noindexPaths.size} noindex excluded)` : "";
|
|
928
|
-
console.log(`
|
|
1012
|
+
if (skipped) console.log(` Sitemap exclusions:${skipped}`);
|
|
929
1013
|
}
|
|
930
1014
|
const robotsTxt = generateRobotsTxt({
|
|
931
1015
|
robotsTxt: website == null ? void 0 : website.robots_txt,
|
|
932
1016
|
canonicalBase,
|
|
933
|
-
noindex: (
|
|
1017
|
+
noindex: (_c = website == null ? void 0 : website.seo) == null ? void 0 : _c.noindex
|
|
934
1018
|
});
|
|
935
1019
|
await fs.writeFile(path.join(absClient, "robots.txt"), robotsTxt, "utf8");
|
|
936
1020
|
console.log(" Generated robots.txt");
|
|
@@ -1110,6 +1194,95 @@ function discoverInternalLinks(html) {
|
|
|
1110
1194
|
}
|
|
1111
1195
|
return [...out];
|
|
1112
1196
|
}
|
|
1197
|
+
const sitemapUrl = /<url>\s*<loc>[^<]+<\/loc>/m;
|
|
1198
|
+
const sitemapIndexEntry = /<sitemap>\s*<loc>[^<]+<\/loc>/gm;
|
|
1199
|
+
const sitemapLoc = /<loc>([^<]+)<\/loc>/;
|
|
1200
|
+
const loadingShell = /class=["'][^"']*\bblox-initial-loading\b/;
|
|
1201
|
+
const embeddedCmsState = /\b__BLOX_(?:STATE|DATA)__\b/;
|
|
1202
|
+
async function validateSsgOutput(options) {
|
|
1203
|
+
const outDir = path.resolve(options.outDir);
|
|
1204
|
+
const failures = [];
|
|
1205
|
+
const requiredFiles = options.requireFiles ?? [
|
|
1206
|
+
"robots.txt",
|
|
1207
|
+
"_redirects",
|
|
1208
|
+
"sitemap.xml",
|
|
1209
|
+
"llms.txt",
|
|
1210
|
+
"llms-full.txt"
|
|
1211
|
+
];
|
|
1212
|
+
const htmlFiles = await collectHtmlFiles(outDir);
|
|
1213
|
+
let hydratedFiles = 0;
|
|
1214
|
+
for (const file of htmlFiles) {
|
|
1215
|
+
const name = path.relative(outDir, file);
|
|
1216
|
+
const html = await fs.readFile(file, "utf8");
|
|
1217
|
+
if (embeddedCmsState.test(html)) hydratedFiles += 1;
|
|
1218
|
+
if (!/<title>[^<]+<\/title>/i.test(html)) failures.push(`${name}: missing page title`);
|
|
1219
|
+
if (!/<link\s[^>]*rel=["']canonical["'][^>]*>/i.test(html)) {
|
|
1220
|
+
failures.push(`${name}: missing canonical URL`);
|
|
1221
|
+
}
|
|
1222
|
+
if (!/<html[^>]*\slang=["'][^"']+["']/i.test(html)) failures.push(`${name}: missing html lang`);
|
|
1223
|
+
if (loadingShell.test(html) && !embeddedCmsState.test(html)) {
|
|
1224
|
+
failures.push(`${name}: contains only the Blox loading shell`);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
if (!htmlFiles.length) failures.push("output contains no HTML files");
|
|
1228
|
+
if (!hydratedFiles) failures.push("output contains no prerendered Blox hydration state");
|
|
1229
|
+
for (const required of requiredFiles) {
|
|
1230
|
+
try {
|
|
1231
|
+
const content = await fs.readFile(path.join(outDir, required), "utf8");
|
|
1232
|
+
if (required === "robots.txt" && /^Disallow:\s*\/\s*$/im.test(content)) {
|
|
1233
|
+
failures.push("robots.txt blocks the entire site");
|
|
1234
|
+
}
|
|
1235
|
+
if (required === "llms.txt" && !/^- \[[^\]]+\]\([^)]+\)/m.test(content)) {
|
|
1236
|
+
failures.push("llms.txt contains no page links");
|
|
1237
|
+
}
|
|
1238
|
+
if (required === "sitemap.xml") {
|
|
1239
|
+
failures.push(...await validateSitemap(outDir, content));
|
|
1240
|
+
}
|
|
1241
|
+
} catch {
|
|
1242
|
+
failures.push(`missing ${required}`);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
if (failures.length) {
|
|
1246
|
+
throw new Error(`Invalid Blox SSG output:
|
|
1247
|
+
${failures.map((item) => ` - ${item}`).join("\n")}`);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
async function collectHtmlFiles(directory) {
|
|
1251
|
+
const entries = await fs.readdir(directory, { withFileTypes: true });
|
|
1252
|
+
const files = await Promise.all(entries.map(async (entry) => {
|
|
1253
|
+
const child = path.join(directory, entry.name);
|
|
1254
|
+
if (entry.isDirectory() && entry.name !== "server") return collectHtmlFiles(child);
|
|
1255
|
+
return entry.isFile() && entry.name.endsWith(".html") ? [child] : [];
|
|
1256
|
+
}));
|
|
1257
|
+
return files.flat();
|
|
1258
|
+
}
|
|
1259
|
+
async function validateSitemap(outDir, content) {
|
|
1260
|
+
var _a;
|
|
1261
|
+
if (sitemapUrl.test(content)) return [];
|
|
1262
|
+
const failures = [];
|
|
1263
|
+
const entries = content.match(sitemapIndexEntry) ?? [];
|
|
1264
|
+
if (!entries.length) return ["sitemap.xml contains neither page URLs nor child sitemaps"];
|
|
1265
|
+
let childUrlCount = 0;
|
|
1266
|
+
for (const entry of entries) {
|
|
1267
|
+
const loc = (_a = entry.match(sitemapLoc)) == null ? void 0 : _a[1];
|
|
1268
|
+
if (!loc) continue;
|
|
1269
|
+
const pathname = new URL(loc).pathname.replace(/^\/+/, "");
|
|
1270
|
+
const childPath = path.resolve(outDir, pathname);
|
|
1271
|
+
if (!childPath.startsWith(`${outDir}${path.sep}`)) {
|
|
1272
|
+
failures.push(`child sitemap escapes output directory: ${pathname}`);
|
|
1273
|
+
continue;
|
|
1274
|
+
}
|
|
1275
|
+
try {
|
|
1276
|
+
const child = await fs.readFile(childPath, "utf8");
|
|
1277
|
+
if (!sitemapUrl.test(child)) failures.push(`${pathname} contains no page URLs`);
|
|
1278
|
+
else childUrlCount += (child.match(/<url>/g) ?? []).length;
|
|
1279
|
+
} catch {
|
|
1280
|
+
failures.push(`missing child sitemap ${pathname}`);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
if (!childUrlCount) failures.push("sitemap index child files contain no page URLs");
|
|
1284
|
+
return failures;
|
|
1285
|
+
}
|
|
1113
1286
|
exports.BloxBuildResponseError = BloxBuildResponseError;
|
|
1114
1287
|
exports.bloxBuildJson = bloxBuildJson;
|
|
1115
1288
|
exports.bloxBuildRequest = bloxBuildRequest;
|
|
@@ -1123,13 +1296,17 @@ exports.generateLlmsFullTxt = generateLlmsFullTxt;
|
|
|
1123
1296
|
exports.generateLlmsTxt = generateLlmsTxt;
|
|
1124
1297
|
exports.generateNetlifyRedirects = generateNetlifyRedirects;
|
|
1125
1298
|
exports.generateRobotsTxt = generateRobotsTxt;
|
|
1299
|
+
exports.generateSitemapIndexXml = generateSitemapIndexXml;
|
|
1126
1300
|
exports.generateSitemapXml = generateSitemapXml;
|
|
1127
1301
|
exports.getBloxBuildRequestOptions = getBloxBuildRequestOptions;
|
|
1128
1302
|
exports.getSiteIconFlags = getSiteIconFlags;
|
|
1129
1303
|
exports.llmArtifacts = llmArtifacts;
|
|
1304
|
+
exports.localeSitemapPath = localeSitemapPath;
|
|
1130
1305
|
exports.mergeLlmParts = mergeLlmParts;
|
|
1131
1306
|
exports.polyfillBloxSsgGlobals = polyfillBloxSsgGlobals;
|
|
1132
1307
|
exports.prerender = prerender;
|
|
1133
1308
|
exports.primaryContextEntry = primaryContextEntry;
|
|
1134
1309
|
exports.resolveManifestProvenance = resolveManifestProvenance;
|
|
1310
|
+
exports.splitSitemapPathsByLocale = splitSitemapPathsByLocale;
|
|
1135
1311
|
exports.uploadBloxManifest = uploadBloxManifest;
|
|
1312
|
+
exports.validateSsgOutput = validateSsgOutput;
|
package/package.json
CHANGED