@lownoise-studio/rendershield 0.3.1 → 1.1.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/CHANGELOG.md +73 -32
- package/CONTRIBUTING.md +41 -0
- package/README.md +227 -144
- package/SECURITY.md +25 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +39 -26
- package/dist/cli.js.map +1 -1
- package/dist/cliArgs.d.ts +8 -0
- package/dist/cliArgs.d.ts.map +1 -0
- package/dist/cliArgs.js +56 -0
- package/dist/cliArgs.js.map +1 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +12 -11
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +8 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/verify.d.ts +33 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +202 -117
- package/dist/commands/verify.js.map +1 -1
- package/dist/configPath.d.ts +7 -0
- package/dist/configPath.d.ts.map +1 -0
- package/dist/configPath.js +8 -0
- package/dist/configPath.js.map +1 -0
- package/dist/core/generateRobots.d.ts +3 -0
- package/dist/core/generateRobots.d.ts.map +1 -0
- package/dist/core/generateSitemap.d.ts +3 -0
- package/dist/core/generateSitemap.d.ts.map +1 -0
- package/dist/core/generateWorker.d.ts +3 -0
- package/dist/core/generateWorker.d.ts.map +1 -0
- package/dist/core/generateWorker.js +75 -75
- package/dist/core/generateWorker.js.map +1 -1
- package/dist/core/listOutputRoutes.d.ts +4 -0
- package/dist/core/listOutputRoutes.d.ts.map +1 -0
- package/dist/core/listOutputRoutes.js +40 -0
- package/dist/core/listOutputRoutes.js.map +1 -0
- package/dist/core/loadConfig.d.ts +5 -0
- package/dist/core/loadConfig.d.ts.map +1 -0
- package/dist/core/loadConfig.js +108 -58
- package/dist/core/loadConfig.js.map +1 -1
- package/dist/core/loadMarkdown.d.ts +3 -0
- package/dist/core/loadMarkdown.d.ts.map +1 -0
- package/dist/core/loadMarkdown.js +4 -3
- package/dist/core/loadMarkdown.js.map +1 -1
- package/dist/core/renderHtml.d.ts +3 -0
- package/dist/core/renderHtml.d.ts.map +1 -0
- package/dist/core/renderHtml.js +25 -10
- package/dist/core/renderHtml.js.map +1 -1
- package/dist/core/validateOutput.d.ts +28 -0
- package/dist/core/validateOutput.d.ts.map +1 -0
- package/dist/core/validateOutput.js +7 -1
- package/dist/core/validateOutput.js.map +1 -1
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +24 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/docs/CONFIG.md +70 -0
- package/docs/deploy-cloudflare.md +40 -14
- package/package.json +25 -2
- package/rendershield.config.schema.json +100 -0
- package/src/cli.ts +96 -75
- package/src/cliArgs.ts +71 -0
- package/src/commands/build.ts +200 -185
- package/src/commands/init.ts +8 -8
- package/src/commands/verify.ts +451 -236
- package/src/configPath.ts +17 -0
- package/src/core/generateWorker.ts +97 -97
- package/src/core/listOutputRoutes.ts +51 -0
- package/src/core/loadConfig.ts +282 -173
- package/src/core/loadMarkdown.ts +9 -3
- package/src/core/renderHtml.ts +36 -12
- package/src/core/validateOutput.ts +335 -328
- package/src/errors.ts +48 -0
- package/src/index.ts +43 -0
- package/src/types.ts +5 -2
package/dist/commands/verify.js
CHANGED
|
@@ -1,52 +1,16 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { loadConfig } from "../core/loadConfig.js";
|
|
4
|
-
import {
|
|
4
|
+
import { listPrerenderIndexFiles, indexHtmlPathToRoute, } from "../core/listOutputRoutes.js";
|
|
5
|
+
import { checkPrerenderContract, } from "../core/validateOutput.js";
|
|
6
|
+
import { renderShieldError } from "../errors.js";
|
|
5
7
|
function joinUrl(base, routePath) {
|
|
6
8
|
const b = base.endsWith("/") ? base.slice(0, -1) : base;
|
|
7
9
|
const p = routePath.startsWith("/") ? routePath : `/${routePath}`;
|
|
8
10
|
return b + p;
|
|
9
11
|
}
|
|
10
|
-
async function findFirstIndexHtml(outDirAbs) {
|
|
11
|
-
const stack = [outDirAbs];
|
|
12
|
-
while (stack.length > 0) {
|
|
13
|
-
const current = stack.pop();
|
|
14
|
-
let entries;
|
|
15
|
-
try {
|
|
16
|
-
entries = await fs.readdir(current, { withFileTypes: true });
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
22
|
-
for (const entry of entries) {
|
|
23
|
-
const full = path.join(current, entry.name);
|
|
24
|
-
if (entry.isDirectory()) {
|
|
25
|
-
stack.push(full);
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
if (entry.isFile() && entry.name.toLowerCase() === "index.html") {
|
|
29
|
-
// Ignore index.html at the output root; prefer a routed page like
|
|
30
|
-
// <section>/<slug>/index.html (or deeper).
|
|
31
|
-
const rel = path.relative(outDirAbs, full);
|
|
32
|
-
const parts = rel.split(path.sep).filter(Boolean);
|
|
33
|
-
if (parts.length >= 2)
|
|
34
|
-
return full;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
function indexHtmlPathToRoute(outDirAbs, indexPathAbs) {
|
|
41
|
-
const rel = path.relative(outDirAbs, indexPathAbs);
|
|
42
|
-
// rel: <section>/<slug>/index.html
|
|
43
|
-
const noFile = rel.replace(/index\.html$/i, "");
|
|
44
|
-
const normalized = noFile.split(path.sep).join("/").replace(/\/+$/, "");
|
|
45
|
-
return "/" + normalized.replace(/^\/+/, "");
|
|
46
|
-
}
|
|
47
12
|
const BOT_UA = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
|
|
48
13
|
const HUMAN_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
|
|
49
|
-
/** Heuristic: likely SPA shell if body has almost no visible content and no article. */
|
|
50
14
|
function looksLikeSpaShell(html) {
|
|
51
15
|
const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
52
16
|
const bodyHtml = bodyMatch ? bodyMatch[1] : html;
|
|
@@ -67,64 +31,187 @@ function looksLikeSpaShell(html) {
|
|
|
67
31
|
}
|
|
68
32
|
return { likely: false };
|
|
69
33
|
}
|
|
70
|
-
export async function cmdVerify(cwd = process.cwd(), options) {
|
|
71
|
-
if (options
|
|
72
|
-
|
|
73
|
-
|
|
34
|
+
export async function cmdVerify(cwd = process.cwd(), options = {}) {
|
|
35
|
+
if (options.prod || options.prodUrl) {
|
|
36
|
+
return runVerifyProdMode(cwd, options);
|
|
37
|
+
}
|
|
38
|
+
if (options.check) {
|
|
39
|
+
return runLocalCheckMode(cwd, options);
|
|
40
|
+
}
|
|
41
|
+
if (options.all) {
|
|
42
|
+
throw renderShieldError("CLI_INVALID_ARGS", "verify --all requires --check (local) or --prod (production). Example: rendershield verify --all --check");
|
|
43
|
+
}
|
|
44
|
+
return runLocalSmoke(cwd, options);
|
|
45
|
+
}
|
|
46
|
+
async function runVerifyProdMode(cwd, options) {
|
|
47
|
+
const cfg = await loadConfig(cwd, options);
|
|
48
|
+
const outDirAbs = path.join(cwd, cfg.output.outDir);
|
|
49
|
+
if (options.all) {
|
|
50
|
+
await assertOutputExists(outDirAbs, cfg.output.outDir);
|
|
51
|
+
const indexFiles = await listPrerenderIndexFiles(outDirAbs);
|
|
52
|
+
if (indexFiles.length === 0) {
|
|
53
|
+
throw renderShieldError("VERIFY_FAILED", `No prerendered pages found inside: ${cfg.output.outDir}/. Run: rendershield build`, { outDir: cfg.output.outDir });
|
|
54
|
+
}
|
|
55
|
+
return runVerifyProdAll(cfg, cwd, outDirAbs, indexFiles);
|
|
74
56
|
}
|
|
75
|
-
|
|
57
|
+
if (!options.prodUrl) {
|
|
58
|
+
throw renderShieldError("CLI_INVALID_ARGS", "verify --prod requires a URL, or use --prod --all to check every route from build output.");
|
|
59
|
+
}
|
|
60
|
+
const single = await fetchAndVerifyProd(options.prodUrl.startsWith("http") ? options.prodUrl : `https://${options.prodUrl}`);
|
|
61
|
+
return { mode: "prod", ok: true, pages: [single] };
|
|
62
|
+
}
|
|
63
|
+
async function runLocalCheckMode(cwd, options) {
|
|
64
|
+
const cfg = await loadConfig(cwd, options);
|
|
76
65
|
const outDirAbs = path.join(cwd, cfg.output.outDir);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!firstIndex) {
|
|
91
|
-
console.log(`
|
|
92
|
-
RenderShield verify
|
|
93
|
-
|
|
94
|
-
No prerendered pages found inside: ${cfg.output.outDir}/
|
|
95
|
-
|
|
96
|
-
Run:
|
|
97
|
-
node dist/cli.js build
|
|
98
|
-
`);
|
|
99
|
-
return;
|
|
66
|
+
await assertOutputExists(outDirAbs, cfg.output.outDir);
|
|
67
|
+
const indexFiles = await listPrerenderIndexFiles(outDirAbs);
|
|
68
|
+
if (indexFiles.length === 0) {
|
|
69
|
+
throw renderShieldError("VERIFY_FAILED", `No prerendered pages found inside: ${cfg.output.outDir}/. Run: rendershield build`, { outDir: cfg.output.outDir });
|
|
70
|
+
}
|
|
71
|
+
if (options.all) {
|
|
72
|
+
return runLocalCheckAll(cwd, cfg, outDirAbs, indexFiles);
|
|
73
|
+
}
|
|
74
|
+
return runLocalCheckOne(cwd, cfg, outDirAbs, indexFiles[0]);
|
|
75
|
+
}
|
|
76
|
+
async function assertOutputExists(outDirAbs, outDir) {
|
|
77
|
+
if (!(await fs.pathExists(outDirAbs))) {
|
|
78
|
+
throw renderShieldError("VERIFY_FAILED", `No prerender output directory found: ${outDir}/. Run: rendershield build`, { outDir });
|
|
100
79
|
}
|
|
80
|
+
}
|
|
81
|
+
async function runLocalSmoke(cwd, options) {
|
|
82
|
+
const cfg = await loadConfig(cwd, options);
|
|
83
|
+
const outDirAbs = path.join(cwd, cfg.output.outDir);
|
|
84
|
+
await assertOutputExists(outDirAbs, cfg.output.outDir);
|
|
85
|
+
const indexFiles = await listPrerenderIndexFiles(outDirAbs);
|
|
86
|
+
if (indexFiles.length === 0) {
|
|
87
|
+
throw renderShieldError("VERIFY_FAILED", `No prerendered pages found inside: ${cfg.output.outDir}/. Run: rendershield build`, { outDir: cfg.output.outDir });
|
|
88
|
+
}
|
|
89
|
+
const firstIndex = indexFiles[0];
|
|
101
90
|
const routePath = indexHtmlPathToRoute(outDirAbs, firstIndex);
|
|
102
91
|
const url = joinUrl(cfg.site.canonicalBase, routePath);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
92
|
+
const outputFile = path.relative(cwd, firstIndex);
|
|
93
|
+
console.log(`
|
|
94
|
+
RenderShield verify
|
|
95
|
+
|
|
96
|
+
Using:
|
|
97
|
+
canonicalBase: ${cfg.site.canonicalBase}
|
|
98
|
+
routePath: ${routePath}
|
|
99
|
+
output file: ${outputFile}
|
|
100
|
+
pages in output: ${indexFiles.length} (showing first; use --all --check to validate all)
|
|
101
|
+
|
|
102
|
+
Smoke tests:
|
|
103
|
+
|
|
104
|
+
1) Human (usually SPA shell):
|
|
105
|
+
curl -s ${url} | grep -i "<title>"
|
|
106
|
+
|
|
107
|
+
2) Bot (should see prerendered, route-specific title):
|
|
108
|
+
curl -s -H "User-Agent: Googlebot" ${url} | grep -i "<title>"
|
|
109
|
+
|
|
110
|
+
3) Debug headers (Worker must be routed + proxy ON):
|
|
111
|
+
curl -I -H "User-Agent: GPTBot" ${url}
|
|
112
|
+
|
|
113
|
+
Expected: x-rendershield: bot-hit (proves Worker served prerender to bot).
|
|
114
|
+
If debugHeaders enabled: X-Bot-Detected, X-Prerender, X-Final-Path.
|
|
115
|
+
|
|
116
|
+
Tip: rendershield verify --check validates built HTML without fetching production.
|
|
117
|
+
`);
|
|
118
|
+
return {
|
|
119
|
+
mode: "local",
|
|
120
|
+
canonicalBase: cfg.site.canonicalBase,
|
|
121
|
+
checked: false,
|
|
122
|
+
ok: true,
|
|
123
|
+
pages: [{ routePath, outputFile, url }],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async function runLocalCheckOne(cwd, cfg, outDirAbs, indexPath) {
|
|
127
|
+
const page = await checkLocalPage(cwd, outDirAbs, indexPath, cfg.site.canonicalBase);
|
|
128
|
+
const ok = page.contract?.ok ?? false;
|
|
129
|
+
console.log(`
|
|
130
|
+
RenderShield verify --check
|
|
131
|
+
Route: ${page.routePath}
|
|
132
|
+
File: ${page.outputFile}
|
|
133
|
+
Contract: ${ok ? "PASS" : "FAIL"}
|
|
134
|
+
${!ok && page.contract ? page.contract.missing.map((m) => ` - ${m}`).join("\n") : ""}
|
|
135
|
+
`);
|
|
136
|
+
if (!ok) {
|
|
137
|
+
throw renderShieldError("VERIFY_FAILED", `Built HTML failed contract for ${page.routePath}. Missing: ${page.contract?.missing.join("; ")}`, { routePath: page.routePath, missing: page.contract?.missing });
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
mode: "local",
|
|
141
|
+
canonicalBase: cfg.site.canonicalBase,
|
|
142
|
+
checked: true,
|
|
143
|
+
ok: true,
|
|
144
|
+
pages: [page],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
async function runLocalCheckAll(cwd, cfg, outDirAbs, indexFiles) {
|
|
148
|
+
const pages = [];
|
|
149
|
+
const failures = [];
|
|
150
|
+
for (const indexPath of indexFiles) {
|
|
151
|
+
const page = await checkLocalPage(cwd, outDirAbs, indexPath, cfg.site.canonicalBase);
|
|
152
|
+
pages.push(page);
|
|
153
|
+
if (!page.contract?.ok) {
|
|
154
|
+
failures.push(`${page.routePath}: ${page.contract?.missing.join("; ") ?? "contract failed"}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
console.log(`
|
|
158
|
+
RenderShield verify --all --check
|
|
159
|
+
Pages: ${pages.length}
|
|
160
|
+
${pages
|
|
161
|
+
.map((p) => ` ${p.contract?.ok ? "PASS" : "FAIL"} ${p.routePath}`)
|
|
162
|
+
.join("\n")}
|
|
124
163
|
`);
|
|
164
|
+
if (failures.length > 0) {
|
|
165
|
+
throw renderShieldError("VERIFY_FAILED", `Built HTML failed contract on ${failures.length} page(s). ${failures.join(" | ")}`, { failures });
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
mode: "local",
|
|
169
|
+
canonicalBase: cfg.site.canonicalBase,
|
|
170
|
+
checked: true,
|
|
171
|
+
ok: true,
|
|
172
|
+
pages,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
async function checkLocalPage(cwd, outDirAbs, indexPath, canonicalBase) {
|
|
176
|
+
const html = await fs.readFile(indexPath, "utf8");
|
|
177
|
+
const routePath = indexHtmlPathToRoute(outDirAbs, indexPath);
|
|
178
|
+
const outputFile = path.relative(cwd, indexPath);
|
|
179
|
+
const contract = checkPrerenderContract(html, {
|
|
180
|
+
routePath,
|
|
181
|
+
outFile: outputFile,
|
|
182
|
+
});
|
|
183
|
+
return {
|
|
184
|
+
routePath,
|
|
185
|
+
outputFile,
|
|
186
|
+
url: joinUrl(canonicalBase, routePath),
|
|
187
|
+
contract,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async function runVerifyProdAll(cfg, _cwd, outDirAbs, indexFiles) {
|
|
191
|
+
const pages = [];
|
|
192
|
+
const failures = [];
|
|
193
|
+
for (const indexPath of indexFiles) {
|
|
194
|
+
const routePath = indexHtmlPathToRoute(outDirAbs, indexPath);
|
|
195
|
+
const prodUrl = joinUrl(cfg.site.canonicalBase, routePath);
|
|
196
|
+
try {
|
|
197
|
+
const result = await fetchAndVerifyProd(prodUrl);
|
|
198
|
+
pages.push(result);
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
202
|
+
failures.push(`${routePath}: ${msg}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
console.log(`
|
|
206
|
+
RenderShield verify --prod --all
|
|
207
|
+
Checked ${pages.length} URL(s) from build output.
|
|
208
|
+
`);
|
|
209
|
+
if (failures.length > 0) {
|
|
210
|
+
throw renderShieldError("VERIFY_FAILED", `Production verify failed for ${failures.length} route(s). ${failures.join(" | ")}`, { failures });
|
|
211
|
+
}
|
|
212
|
+
return { mode: "prod", ok: true, pages };
|
|
125
213
|
}
|
|
126
|
-
async function
|
|
127
|
-
const normalizedUrl = url.startsWith("http") ? url : `https://${url}`;
|
|
214
|
+
async function fetchAndVerifyProd(normalizedUrl) {
|
|
128
215
|
let botHtml;
|
|
129
216
|
let humanHtml;
|
|
130
217
|
let botStatus;
|
|
@@ -149,46 +236,44 @@ async function runVerifyProd(url) {
|
|
|
149
236
|
}
|
|
150
237
|
catch (err) {
|
|
151
238
|
const msg = err instanceof Error ? err.message : String(err);
|
|
152
|
-
throw
|
|
239
|
+
throw renderShieldError("VERIFY_FAILED", `verify --prod: failed to fetch ${normalizedUrl}. ${msg}`, { url: normalizedUrl });
|
|
153
240
|
}
|
|
154
|
-
// Prove routing: Worker must set x-rendershield: bot-hit for bot requests. No inference.
|
|
155
|
-
const routingOk = xRenderShield === "bot-hit";
|
|
156
241
|
if (xRenderShield === "bot-fallback") {
|
|
157
|
-
throw
|
|
158
|
-
`Prerender origin returned non-200; Worker fell back to SPA
|
|
242
|
+
throw renderShieldError("VERIFY_FAILED", `verify --prod: bot request received x-rendershield: bot-fallback for ${normalizedUrl}. ` +
|
|
243
|
+
`Prerender origin returned non-200; Worker fell back to SPA.`, { url: normalizedUrl, xRenderShield });
|
|
159
244
|
}
|
|
160
|
-
if (
|
|
245
|
+
if (xRenderShield !== "bot-hit") {
|
|
161
246
|
const hint = xRenderShield == null
|
|
162
|
-
? " If no Worker is deployed, use verify
|
|
247
|
+
? " If no Worker is deployed, use verify --check for local/build output."
|
|
163
248
|
: "";
|
|
164
|
-
throw
|
|
165
|
-
`Got: ${xRenderShield ?? "(missing)"}
|
|
249
|
+
throw renderShieldError("VERIFY_FAILED", `verify --prod: expected x-rendershield: bot-hit for ${normalizedUrl}. ` +
|
|
250
|
+
`Got: ${xRenderShield ?? "(missing)"}.${hint}`, { url: normalizedUrl, xRenderShield });
|
|
166
251
|
}
|
|
167
252
|
const contract = checkPrerenderContract(botHtml, {
|
|
168
253
|
routePath: normalizedUrl,
|
|
169
254
|
outFile: normalizedUrl,
|
|
170
255
|
});
|
|
171
256
|
const humanSpa = looksLikeSpaShell(humanHtml);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
${humanSpa.likely ? `Likely SPA shell: ${humanSpa.reason ?? "unknown"}` : "Has substantial content (not a minimal SPA shell)."}
|
|
257
|
+
console.log(`
|
|
258
|
+
RenderShield verify --prod
|
|
259
|
+
URL: ${normalizedUrl}
|
|
260
|
+
|
|
261
|
+
Fetch:
|
|
262
|
+
Bot (Googlebot): ${botStatus} (${botHtml.length} bytes) x-rendershield: ${xRenderShield}
|
|
263
|
+
Human (Chrome): ${humanStatus} (${humanHtml.length} bytes)
|
|
264
|
+
|
|
265
|
+
Routing: x-rendershield: bot-hit
|
|
266
|
+
|
|
267
|
+
Bot contract:
|
|
268
|
+
${contract.ok ? "PASS" : "FAIL"}
|
|
269
|
+
${contract.missing.length > 0 ? contract.missing.map((m) => ` - ${m}`).join("\n") : ""}
|
|
270
|
+
|
|
271
|
+
Human response:
|
|
272
|
+
${humanSpa.likely ? `Likely SPA shell: ${humanSpa.reason ?? "unknown"}` : "Has substantial content."}
|
|
189
273
|
`);
|
|
190
274
|
if (!contract.ok) {
|
|
191
|
-
throw
|
|
275
|
+
throw renderShieldError("VERIFY_FAILED", `Production URL did not satisfy bot contract: ${normalizedUrl}. Missing: ${contract.missing.join("; ")}`, { url: normalizedUrl, missing: contract.missing });
|
|
192
276
|
}
|
|
277
|
+
return { url: normalizedUrl, contract };
|
|
193
278
|
}
|
|
194
279
|
//# sourceMappingURL=verify.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,sBAAsB,GAEvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,SAAS,OAAO,CAAC,IAAY,EAAE,SAAiB;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,MAAM,GACV,0EAA0E,CAAC;AAC7E,MAAM,QAAQ,GACZ,iHAAiH,CAAC;AAEpH,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,MAAM,QAAQ,GAAG,QAAQ;SACtB,OAAO,CAAC,6BAA6B,EAAE,GAAG,CAAC;SAC3C,OAAO,CAAC,2BAA2B,EAAE,GAAG,CAAC;SACzC,OAAO,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9E,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,yBAAyB,IAAI,CAAC,MAAM,4BAA4B,EAAE,CAAC;IACpG,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IAC7E,CAAC;IACD,MAAM,QAAQ,GAAG,mFAAmF,CAAC,IAAI,CACvG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAC1B,CAAC;IACF,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,qDAAqD,EAAE,CAAC;IACzF,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAiCD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,EACnB,UAAyB,EAAE;IAE3B,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,OAAO,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,iBAAiB,CACrB,kBAAkB,EAClB,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,GAAW,EACX,OAAsB;IAEtB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEpD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAC5D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,iBAAiB,CACrB,eAAe,EACf,sCAAsC,GAAG,CAAC,MAAM,CAAC,MAAM,4BAA4B,EACnF,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAC9B,CAAC;QACJ,CAAC;QACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,iBAAiB,CACrB,kBAAkB,EAClB,2FAA2F,CAC5F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,CAAC,OAAO,EAAE,CACpF,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,GAAW,EACX,OAAsB;IAEtB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvD,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,iBAAiB,CACrB,eAAe,EACf,sCAAsC,GAAG,CAAC,MAAM,CAAC,MAAM,4BAA4B,EACnF,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAC9B,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,SAAiB,EAAE,MAAc;IACjE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,iBAAiB,CACrB,eAAe,EACf,wCAAwC,MAAM,4BAA4B,EAC1E,EAAE,MAAM,EAAE,CACX,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,GAAW,EACX,OAAsB;IAEtB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvD,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,iBAAiB,CACrB,eAAe,EACf,sCAAsC,GAAG,CAAC,MAAM,CAAC,MAAM,4BAA4B,EACnF,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAC9B,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC;;;;mBAIK,GAAG,CAAC,IAAI,CAAC,aAAa;mBACtB,SAAS;mBACT,UAAU;qBACR,UAAU,CAAC,MAAM;;;;;YAK1B,GAAG;;;uCAGwB,GAAG;;;oCAGN,GAAG;;;;;;CAMtC,CAAC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa;QACrC,OAAO,EAAE,KAAK;QACd,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,GAAW,EACX,GAA2C,EAC3C,SAAiB,EACjB,SAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrF,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,KAAK,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC;;SAEL,IAAI,CAAC,SAAS;SACd,IAAI,CAAC,UAAU;YACZ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;EAC9B,CAAC,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;CACpF,CAAC,CAAC;IAED,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,iBAAiB,CACrB,eAAe,EACf,kCAAkC,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACjG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa;QACrC,OAAO,EAAE,IAAI;QACb,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,CAAC,IAAI,CAAC;KACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,GAAW,EACX,GAA2C,EAC3C,SAAiB,EACjB,UAAoB;IAEpB,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CACX,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,EAAE,CAC/E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC;;SAEL,KAAK,CAAC,MAAM;EACnB,KAAK;SACJ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;SACnE,IAAI,CAAC,IAAI,CAAC;CACZ,CAAC,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,iBAAiB,CACrB,eAAe,EACf,iCAAiC,QAAQ,CAAC,MAAM,aAAa,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EACnF,EAAE,QAAQ,EAAE,CACb,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa;QACrC,OAAO,EAAE,IAAI;QACb,EAAE,EAAE,IAAI;QACR,KAAK;KACN,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,GAAW,EACX,SAAiB,EACjB,SAAiB,EACjB,aAAqB;IAErB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,EAAE;QAC5C,SAAS;QACT,OAAO,EAAE,UAAU;KACpB,CAAC,CAAC;IACH,OAAO;QACL,SAAS;QACT,UAAU;QACV,GAAG,EAAE,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC;QACtC,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,GAA2C,EAC3C,IAAY,EACZ,SAAiB,EACjB,UAAoB;IAEpB,MAAM,KAAK,GAA8B,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,KAAK,GAAG,EAAE,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC;;UAEJ,KAAK,CAAC,MAAM;CACrB,CAAC,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,iBAAiB,CACrB,eAAe,EACf,gCAAgC,QAAQ,CAAC,MAAM,cAAc,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EACnF,EAAE,QAAQ,EAAE,CACb,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,aAAqB;IAErB,IAAI,OAAe,CAAC;IACpB,IAAI,SAAiB,CAAC;IACtB,IAAI,SAAiB,CAAC;IACtB,IAAI,WAAmB,CAAC;IACxB,IAAI,aAA4B,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC3C,KAAK,CAAC,aAAa,EAAE;gBACnB,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE;gBACjC,QAAQ,EAAE,QAAQ;aACnB,CAAC;YACF,KAAK,CAAC,aAAa,EAAE;gBACnB,OAAO,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE;gBACnC,QAAQ,EAAE,QAAQ;aACnB,CAAC;SACH,CAAC,CAAC;QAEH,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QAC1B,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC9B,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACrD,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,iBAAiB,CACrB,eAAe,EACf,kCAAkC,aAAa,KAAK,GAAG,EAAE,EACzD,EAAE,GAAG,EAAE,aAAa,EAAE,CACvB,CAAC;IACJ,CAAC;IAED,IAAI,aAAa,KAAK,cAAc,EAAE,CAAC;QACrC,MAAM,iBAAiB,CACrB,eAAe,EACf,wEAAwE,aAAa,IAAI;YACvF,6DAA6D,EAC/D,EAAE,GAAG,EAAE,aAAa,EAAE,aAAa,EAAE,CACtC,CAAC;IACJ,CAAC;IACD,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,aAAa,IAAI,IAAI;YAChC,CAAC,CAAC,uEAAuE;YACzE,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,iBAAiB,CACrB,eAAe,EACf,uDAAuD,aAAa,IAAI;YACtE,QAAQ,aAAa,IAAI,WAAW,IAAI,IAAI,EAAE,EAChD,EAAE,GAAG,EAAE,aAAa,EAAE,aAAa,EAAE,CACtC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,EAAE;QAC/C,SAAS,EAAE,aAAa;QACxB,OAAO,EAAE,aAAa;KACvB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE9C,OAAO,CAAC,GAAG,CAAC;;OAEP,aAAa;;;uBAGG,SAAS,MAAM,OAAO,CAAC,MAAM,4BAA4B,aAAa;uBACtE,WAAW,MAAM,SAAS,CAAC,MAAM;;;;;IAKpD,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;EAC/B,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;;;IAGnF,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,QAAQ,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,0BAA0B;CACrG,CAAC,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,iBAAiB,CACrB,eAAe,EACf,gDAAgD,aAAa,cAAc,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACxG,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAClD,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const DEFAULT_CONFIG_NAME = "rendershield.config.json";
|
|
2
|
+
export type CommandOptions = {
|
|
3
|
+
/** Relative to cwd, or absolute. Defaults to rendershield.config.json in cwd. */
|
|
4
|
+
configPath?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function resolveConfigFile(cwd: string, configPath?: string): string;
|
|
7
|
+
//# sourceMappingURL=configPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configPath.d.ts","sourceRoot":"","sources":["../src/configPath.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAE9D,MAAM,MAAM,cAAc,GAAG;IAC3B,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,UAAU,SAAsB,GAC/B,MAAM,CAIR"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export const DEFAULT_CONFIG_NAME = "rendershield.config.json";
|
|
3
|
+
export function resolveConfigFile(cwd, configPath = DEFAULT_CONFIG_NAME) {
|
|
4
|
+
return path.isAbsolute(configPath)
|
|
5
|
+
? configPath
|
|
6
|
+
: path.join(cwd, configPath);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=configPath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configPath.js","sourceRoot":"","sources":["../src/configPath.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAO9D,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,UAAU,GAAG,mBAAmB;IAEhC,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAChC,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateRobots.d.ts","sourceRoot":"","sources":["../../src/core/generateRobots.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAejE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateSitemap.d.ts","sourceRoot":"","sources":["../../src/core/generateSitemap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAiB9D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAoBvF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateWorker.d.ts","sourceRoot":"","sources":["../../src/core/generateWorker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAejD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAgFhE"}
|
|
@@ -14,81 +14,81 @@ function jsStringArray(arr) {
|
|
|
14
14
|
export function generateWorkerJs(cfg) {
|
|
15
15
|
const patterns = cfg.worker.botUserAgentPatterns.map((p) => p.toLowerCase());
|
|
16
16
|
const rewriteBases = cfg.worker.rewriteRouteBases;
|
|
17
|
-
return `/**
|
|
18
|
-
* RenderShield Worker (generated) v${VERSION}
|
|
19
|
-
* Serves prerendered /index.html to bots on selected route bases.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
const BOT_SUBSTRINGS = ${jsStringArray(patterns)};
|
|
23
|
-
const REWRITE_BASES = ${jsStringArray(rewriteBases)};
|
|
24
|
-
|
|
25
|
-
function isBot(ua) {
|
|
26
|
-
const s = (ua || "").toLowerCase();
|
|
27
|
-
return BOT_SUBSTRINGS.some((sub) => s.includes(sub));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function shouldRewrite(pathname) {
|
|
31
|
-
return REWRITE_BASES.some((base) => pathname.startsWith(base));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function toIndexHtml(pathname) {
|
|
35
|
-
let p = pathname;
|
|
36
|
-
if (!p.endsWith("/")) p += "/";
|
|
37
|
-
return p + "index.html";
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default {
|
|
41
|
-
async fetch(request, env, ctx) {
|
|
42
|
-
const url = new URL(request.url);
|
|
43
|
-
const ua = request.headers.get("User-Agent") || "";
|
|
44
|
-
const bot = isBot(ua);
|
|
45
|
-
|
|
46
|
-
const isGetLike = request.method === "GET" || request.method === "HEAD";
|
|
47
|
-
const rewrite = bot && isGetLike && shouldRewrite(url.pathname);
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
if (!rewrite) {
|
|
51
|
-
const passResp = await fetch(request);
|
|
52
|
-
const out = new Response(passResp.body, passResp);
|
|
53
|
-
out.headers.set("x-rendershield", "pass-through");
|
|
54
|
-
return out;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const origin = ${JSON.stringify(cfg.worker.
|
|
58
|
-
const finalPath = toIndexHtml(url.pathname);
|
|
59
|
-
const originUrl = origin + finalPath + url.search;
|
|
60
|
-
|
|
61
|
-
const headers = new Headers();
|
|
62
|
-
headers.set("Accept", "text/html");
|
|
63
|
-
headers.set("User-Agent", ua);
|
|
64
|
-
|
|
65
|
-
const resp = await fetch(originUrl, { method: "GET", headers });
|
|
66
|
-
|
|
67
|
-
if (!resp.ok) {
|
|
68
|
-
const fallbackUrl = origin + url.pathname + url.search;
|
|
69
|
-
const fb = await fetch(fallbackUrl, { method: "GET", headers });
|
|
70
|
-
const out = new Response(fb.body, fb);
|
|
71
|
-
out.headers.set("x-rendershield", "bot-fallback");
|
|
72
|
-
${cfg.worker.debugHeaders ? `out.headers.set("X-Bot-Detected", "true");
|
|
73
|
-
out.headers.set("X-Prerender-Fallback", "true");
|
|
74
|
-
out.headers.set("X-Requested-Path", url.pathname);` : ""}
|
|
75
|
-
return out;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const out = new Response(resp.body, resp);
|
|
79
|
-
out.headers.set("x-rendershield", "bot-hit");
|
|
80
|
-
${cfg.worker.debugHeaders ? `out.headers.set("X-Bot-Detected", "true");
|
|
81
|
-
out.headers.set("X-Prerender", "true");
|
|
82
|
-
out.headers.set("X-Final-Path", finalPath);` : ""}
|
|
83
|
-
return out;
|
|
84
|
-
} catch (err) {
|
|
85
|
-
return new Response("Service temporarily unavailable.", {
|
|
86
|
-
status: 500,
|
|
87
|
-
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
};
|
|
17
|
+
return `/**
|
|
18
|
+
* RenderShield Worker (generated) v${VERSION}
|
|
19
|
+
* Serves prerendered /index.html to bots on selected route bases.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const BOT_SUBSTRINGS = ${jsStringArray(patterns)};
|
|
23
|
+
const REWRITE_BASES = ${jsStringArray(rewriteBases)};
|
|
24
|
+
|
|
25
|
+
function isBot(ua) {
|
|
26
|
+
const s = (ua || "").toLowerCase();
|
|
27
|
+
return BOT_SUBSTRINGS.some((sub) => s.includes(sub));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function shouldRewrite(pathname) {
|
|
31
|
+
return REWRITE_BASES.some((base) => pathname.startsWith(base));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function toIndexHtml(pathname) {
|
|
35
|
+
let p = pathname;
|
|
36
|
+
if (!p.endsWith("/")) p += "/";
|
|
37
|
+
return p + "index.html";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default {
|
|
41
|
+
async fetch(request, env, ctx) {
|
|
42
|
+
const url = new URL(request.url);
|
|
43
|
+
const ua = request.headers.get("User-Agent") || "";
|
|
44
|
+
const bot = isBot(ua);
|
|
45
|
+
|
|
46
|
+
const isGetLike = request.method === "GET" || request.method === "HEAD";
|
|
47
|
+
const rewrite = bot && isGetLike && shouldRewrite(url.pathname);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
if (!rewrite) {
|
|
51
|
+
const passResp = await fetch(request);
|
|
52
|
+
const out = new Response(passResp.body, passResp);
|
|
53
|
+
out.headers.set("x-rendershield", "pass-through");
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const origin = ${JSON.stringify(cfg.worker.spaOrigin)};
|
|
58
|
+
const finalPath = toIndexHtml(url.pathname);
|
|
59
|
+
const originUrl = origin + finalPath + url.search;
|
|
60
|
+
|
|
61
|
+
const headers = new Headers();
|
|
62
|
+
headers.set("Accept", "text/html");
|
|
63
|
+
headers.set("User-Agent", ua);
|
|
64
|
+
|
|
65
|
+
const resp = await fetch(originUrl, { method: "GET", headers });
|
|
66
|
+
|
|
67
|
+
if (!resp.ok) {
|
|
68
|
+
const fallbackUrl = origin + url.pathname + url.search;
|
|
69
|
+
const fb = await fetch(fallbackUrl, { method: "GET", headers });
|
|
70
|
+
const out = new Response(fb.body, fb);
|
|
71
|
+
out.headers.set("x-rendershield", "bot-fallback");
|
|
72
|
+
${cfg.worker.debugHeaders ? `out.headers.set("X-Bot-Detected", "true");
|
|
73
|
+
out.headers.set("X-Prerender-Fallback", "true");
|
|
74
|
+
out.headers.set("X-Requested-Path", url.pathname);` : ""}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const out = new Response(resp.body, resp);
|
|
79
|
+
out.headers.set("x-rendershield", "bot-hit");
|
|
80
|
+
${cfg.worker.debugHeaders ? `out.headers.set("X-Bot-Detected", "true");
|
|
81
|
+
out.headers.set("X-Prerender", "true");
|
|
82
|
+
out.headers.set("X-Final-Path", finalPath);` : ""}
|
|
83
|
+
return out;
|
|
84
|
+
} catch (err) {
|
|
85
|
+
return new Response("Service temporarily unavailable.", {
|
|
86
|
+
status: 500,
|
|
87
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
92
|
`;
|
|
93
93
|
}
|
|
94
94
|
//# sourceMappingURL=generateWorker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateWorker.js","sourceRoot":"","sources":["../../src/core/generateWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,IAAI,OAAO,GAAG,OAAO,CAAC;AACtB,IAAI,CAAC;IACH,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAyB,CAAC;IAClE,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;AACnC,CAAC;AAAC,MAAM,CAAC;IACP,OAAO,GAAG,SAAS,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CAAC,GAAa;IAClC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAuB;IACtD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7E,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAElD,OAAO;sCAC6B,OAAO;;;;yBAIpB,aAAa,CAAC,QAAQ,CAAC;wBACxB,aAAa,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAkC5B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"generateWorker.js","sourceRoot":"","sources":["../../src/core/generateWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,IAAI,OAAO,GAAG,OAAO,CAAC;AACtB,IAAI,CAAC;IACH,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAyB,CAAC;IAClE,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;AACnC,CAAC;AAAC,MAAM,CAAC;IACP,OAAO,GAAG,SAAS,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CAAC,GAAa;IAClC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAuB;IACtD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7E,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAElD,OAAO;sCAC6B,OAAO;;;;yBAIpB,aAAa,CAAC,QAAQ,CAAC;wBACxB,aAAa,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAkC5B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;UAejD,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;;2DAEuB,CAAC,CAAC,CAAC,EAAE;;;;;;QAMxD,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;;kDAEgB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;CAUtD,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** All routed index.html files under outDir (excludes bare outDir/index.html). */
|
|
2
|
+
export declare function listPrerenderIndexFiles(outDirAbs: string): Promise<string[]>;
|
|
3
|
+
export declare function indexHtmlPathToRoute(outDirAbs: string, indexPathAbs: string): string;
|
|
4
|
+
//# sourceMappingURL=listOutputRoutes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listOutputRoutes.d.ts","sourceRoot":"","sources":["../../src/core/listOutputRoutes.ts"],"names":[],"mappings":"AAGA,kFAAkF;AAClF,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAkCnB;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,MAAM,CAKR"}
|