@tokenoftrust/storefront-runner 2.2.97 → 2.2.98
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.98",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
@@ -44,6 +44,7 @@ import { assetContentType } from "./tenant-assets.js";
|
|
|
44
44
|
import { formatHtmlCacheControl } from "./html-cache-policy.js";
|
|
45
45
|
import { NATIVE_GA4_SANDBOX_ASSET_PATH } from "./integration/native-ga4-sandbox-asset.mjs";
|
|
46
46
|
import { CONTENT_NAMED_ASSET_PREFIXES } from "./content-named-asset-prefixes.mjs";
|
|
47
|
+
import { resolveRedirect } from "./publication-redirects.mjs";
|
|
47
48
|
|
|
48
49
|
// ---------------------------------------------------------------------------
|
|
49
50
|
// R2 seam — same structural subset tenant-assets.ts uses (no workers-types dep)
|
|
@@ -189,41 +190,15 @@ function isManifestRedirectRule(value: string): boolean {
|
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* `publication-redirects.mjs` and the CloudFront function — the three are held together by
|
|
195
|
-
* `tests/fixtures/redirect-match-cases.json`.
|
|
196
|
-
*/
|
|
197
|
-
function ruleLocation(to: string, capture: string): string | null {
|
|
198
|
-
const location = to.endsWith("/*") ? `${to.slice(0, -1)}${capture}` : to;
|
|
199
|
-
return location.startsWith("/") && !location.startsWith("//") && !location.includes("\\")
|
|
200
|
-
? location
|
|
201
|
-
: null;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* The redirect the manifest declares for `pathname`, as a location, or null. An exact entry wins
|
|
206
|
-
* outright; otherwise the rule with the longest directory that the trailing-slash form of the path
|
|
207
|
-
* starts with decides — and when its location is unusable there is no redirect.
|
|
193
|
+
* The redirect the manifest declares for `pathname`, as a location, or null — the redirect
|
|
194
|
+
* contract's own matcher (`publication-redirects.mjs`), so this plane cannot answer differently.
|
|
208
195
|
*/
|
|
209
196
|
function staticBundleRedirectLocation(
|
|
210
197
|
redirects: StaticBundleManifest["redirects"],
|
|
211
198
|
pathname: string,
|
|
212
199
|
): string | null {
|
|
213
200
|
if (!redirects?.length) return null;
|
|
214
|
-
|
|
215
|
-
? pathname
|
|
216
|
-
: pathname.endsWith("/") ? pathname : `${pathname}/`;
|
|
217
|
-
let rule: { from: string; to: string } | null = null;
|
|
218
|
-
for (const redirect of redirects) {
|
|
219
|
-
if (redirect.from.endsWith("/*")) {
|
|
220
|
-
const dir = redirect.from.slice(0, -1);
|
|
221
|
-
if (path.startsWith(dir) && (rule === null || dir.length > rule.from.length - 1)) rule = redirect;
|
|
222
|
-
} else if (redirect.from === pathname || redirect.from === path) {
|
|
223
|
-
return redirect.to;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return rule === null ? null : ruleLocation(rule.to, path.slice(rule.from.length - 1));
|
|
201
|
+
return resolveRedirect(redirects, pathname)?.location ?? null;
|
|
227
202
|
}
|
|
228
203
|
|
|
229
204
|
function isManifestRedirectDestination(value: string): boolean {
|
|
@@ -1386,21 +1386,24 @@ if (isMain) {
|
|
|
1386
1386
|
})()
|
|
1387
1387
|
: baseline;
|
|
1388
1388
|
const { ok, findings } = result;
|
|
1389
|
+
// exitCode, never exit(): a report written to a pipe is flushed asynchronously, and exit() cuts a
|
|
1390
|
+
// large one off mid-JSON for whoever parses it.
|
|
1389
1391
|
if (asJson) {
|
|
1390
1392
|
console.log(JSON.stringify({ ok, findings }, null, 2));
|
|
1391
|
-
process.
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1393
|
+
process.exitCode = ok ? 0 : 1;
|
|
1394
|
+
} else {
|
|
1395
|
+
const errors = findings.filter((f) => f.level === ERROR);
|
|
1396
|
+
const warns = findings.filter((f) => f.level === WARN);
|
|
1397
|
+
console.log(`\ntot validate${profile ? ` --profile ${profile}` : ""} — ${tenantId ?? dir}\n`);
|
|
1398
|
+
// Named, grouped callouts FIRST — see printLoudAdvisories above.
|
|
1399
|
+
printLoudAdvisories(findings, { log: (s) => console.log(s) });
|
|
1400
|
+
for (const f of findings) {
|
|
1401
|
+
const tag = f.level === ERROR ? "✗" : "⚠";
|
|
1402
|
+
console.log(` ${tag} [${f.rule}] ${f.file}\n ${f.message}${f.fix ? `\n → ${f.fix}` : ""}`);
|
|
1403
|
+
}
|
|
1404
|
+
console.log(
|
|
1405
|
+
`\n${errors.length === 0 ? "✔" : "✖"} ${errors.length} error(s), ${warns.length} warning(s).\n`,
|
|
1406
|
+
);
|
|
1407
|
+
process.exitCode = errors.length === 0 ? 0 : 1;
|
|
1408
|
+
}
|
|
1406
1409
|
}
|