@nifrajs/web 5.0.0 → 5.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.
Files changed (109) hide show
  1. package/README.md +8 -0
  2. package/dist/client.d.ts +5 -5
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +25 -15
  5. package/dist/client.js.map +1 -1
  6. package/dist/dev-port.d.ts +3 -2
  7. package/dist/dev-port.d.ts.map +1 -1
  8. package/dist/dev-port.js +2 -6
  9. package/dist/dev-port.js.map +1 -1
  10. package/dist/index.d.ts +3 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/internal/package-entries.d.ts +34 -0
  15. package/dist/internal/package-entries.d.ts.map +1 -0
  16. package/dist/internal/package-entries.js +324 -0
  17. package/dist/internal/package-entries.js.map +1 -0
  18. package/dist/internal/page-execution.d.ts.map +1 -1
  19. package/dist/internal/page-execution.js +60 -6
  20. package/dist/internal/page-execution.js.map +1 -1
  21. package/dist/internal/parity.d.ts.map +1 -1
  22. package/dist/internal/parity.js +15 -2
  23. package/dist/internal/parity.js.map +1 -1
  24. package/dist/internal/private-env.d.ts +8 -0
  25. package/dist/internal/private-env.d.ts.map +1 -1
  26. package/dist/internal/private-env.js +25 -10
  27. package/dist/internal/private-env.js.map +1 -1
  28. package/dist/internal/render-document.d.ts +4 -44
  29. package/dist/internal/render-document.d.ts.map +1 -1
  30. package/dist/internal/render-document.js +23 -58
  31. package/dist/internal/render-document.js.map +1 -1
  32. package/dist/internal/route-path.d.ts +6 -0
  33. package/dist/internal/route-path.d.ts.map +1 -1
  34. package/dist/internal/route-path.js +11 -0
  35. package/dist/internal/route-path.js.map +1 -1
  36. package/dist/internal/secret-scan.d.ts.map +1 -1
  37. package/dist/internal/secret-scan.js +103 -1
  38. package/dist/internal/secret-scan.js.map +1 -1
  39. package/dist/internal/web-app.d.ts +4 -2
  40. package/dist/internal/web-app.d.ts.map +1 -1
  41. package/dist/internal/web-app.js +8 -3
  42. package/dist/internal/web-app.js.map +1 -1
  43. package/dist/internal/without-query.d.ts +4 -0
  44. package/dist/internal/without-query.d.ts.map +1 -0
  45. package/dist/internal/without-query.js +9 -0
  46. package/dist/internal/without-query.js.map +1 -0
  47. package/dist/internal/zone-graph.d.ts.map +1 -1
  48. package/dist/internal/zone-graph.js +17 -6
  49. package/dist/internal/zone-graph.js.map +1 -1
  50. package/dist/isr.d.ts +1 -1
  51. package/dist/isr.d.ts.map +1 -1
  52. package/dist/isr.js +15 -2
  53. package/dist/isr.js.map +1 -1
  54. package/dist/manifest.d.ts +9 -0
  55. package/dist/manifest.d.ts.map +1 -1
  56. package/dist/manifest.js +1 -0
  57. package/dist/manifest.js.map +1 -1
  58. package/dist/plugins/vite-leak-guard.d.ts +6 -0
  59. package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
  60. package/dist/plugins/vite-leak-guard.js +80 -7
  61. package/dist/plugins/vite-leak-guard.js.map +1 -1
  62. package/dist/plugins/vite-zone-guard.d.ts.map +1 -1
  63. package/dist/plugins/vite-zone-guard.js +17 -21
  64. package/dist/plugins/vite-zone-guard.js.map +1 -1
  65. package/dist/plugins/zone-guard.d.ts.map +1 -1
  66. package/dist/plugins/zone-guard.js +44 -3
  67. package/dist/plugins/zone-guard.js.map +1 -1
  68. package/dist/prerender.d.ts +5 -1
  69. package/dist/prerender.d.ts.map +1 -1
  70. package/dist/prerender.js +41 -19
  71. package/dist/prerender.js.map +1 -1
  72. package/dist/render-seam.d.ts +23 -2
  73. package/dist/render-seam.d.ts.map +1 -1
  74. package/dist/render-seam.js.map +1 -1
  75. package/dist/router.d.ts.map +1 -1
  76. package/dist/router.js +9 -5
  77. package/dist/router.js.map +1 -1
  78. package/dist/seo.d.ts +49 -0
  79. package/dist/seo.d.ts.map +1 -0
  80. package/dist/seo.js +48 -0
  81. package/dist/seo.js.map +1 -0
  82. package/dist/zones.d.ts +30 -8
  83. package/dist/zones.d.ts.map +1 -1
  84. package/dist/zones.js +185 -46
  85. package/dist/zones.js.map +1 -1
  86. package/package.json +8 -3
  87. package/src/client.ts +27 -15
  88. package/src/dev-port.ts +4 -10
  89. package/src/index.ts +2 -4
  90. package/src/internal/package-entries.ts +331 -0
  91. package/src/internal/page-execution.ts +67 -6
  92. package/src/internal/parity.ts +15 -2
  93. package/src/internal/private-env.ts +27 -13
  94. package/src/internal/render-document.ts +40 -78
  95. package/src/internal/route-path.ts +16 -0
  96. package/src/internal/secret-scan.ts +101 -1
  97. package/src/internal/web-app.ts +10 -5
  98. package/src/internal/without-query.ts +8 -0
  99. package/src/internal/zone-graph.ts +19 -6
  100. package/src/isr.ts +13 -2
  101. package/src/manifest.ts +10 -0
  102. package/src/plugins/vite-leak-guard.ts +99 -7
  103. package/src/plugins/vite-zone-guard.ts +21 -19
  104. package/src/plugins/zone-guard.ts +41 -2
  105. package/src/prerender.ts +39 -18
  106. package/src/render-seam.ts +28 -2
  107. package/src/router.ts +9 -5
  108. package/src/seo.ts +68 -0
  109. package/src/zones.ts +237 -52
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Per-entry package sides: `"nifra": { "environment": { ".": "backend", "./react": "frontend" } }`.
3
+ *
4
+ * An import names an entry, and that entry's side decides it. A path names no entry, so a file is owned
5
+ * by every mapped entry that reaches it inside the package: the entry's targets under any export
6
+ * condition, followed through relative imports. A stage that sees only paths decides by those owners;
7
+ * which entry an import may name is decided where the import is written, from its specifier.
8
+ */
9
+ import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
10
+ import { dirname, extname, join, relative } from "node:path";
11
+ import { tokenize } from "./private-env.js";
12
+ import { withoutQuery } from "./without-query.js";
13
+ const SIDES = new Set(["frontend", "backend", "shared", "library"]);
14
+ const isSide = (value) => typeof value === "string" && SIDES.has(value);
15
+ /** A manifest's `nifra.environment`. A string naming no side declares nothing, as it always has. */
16
+ export function parseEnvironment(value) {
17
+ if (isSide(value))
18
+ return { kind: "package", side: value };
19
+ if (typeof value !== "object" || value === null || Array.isArray(value))
20
+ return { kind: "none" };
21
+ const entries = {};
22
+ for (const [key, side] of Object.entries(value)) {
23
+ if (key !== "." && !key.startsWith("./"))
24
+ return {
25
+ kind: "invalid",
26
+ problem: `key "${key}" must be "." or a subpath starting with "./"`,
27
+ };
28
+ if (key.indexOf("*") !== key.lastIndexOf("*"))
29
+ return { kind: "invalid", problem: `key "${key}" may hold one "*"` };
30
+ if (!isSide(side))
31
+ return {
32
+ kind: "invalid",
33
+ problem: `"${key}" must be one of frontend, backend, shared, library`,
34
+ };
35
+ entries[key] = side;
36
+ }
37
+ return Object.keys(entries).length === 0
38
+ ? {
39
+ kind: "invalid",
40
+ problem: 'maps no entry; give each export subpath (".", "./react") a side',
41
+ }
42
+ : { kind: "entries", entries };
43
+ }
44
+ /**
45
+ * The mapped key that decides `subpath`: the exact key, else the `*` pattern with the longest prefix,
46
+ * then the longest key, where `*` matches at least one character - as Node matches `exports`.
47
+ */
48
+ export function entryKey(entries, subpath) {
49
+ if (Object.hasOwn(entries, subpath))
50
+ return subpath;
51
+ let best;
52
+ for (const key of Object.keys(entries)) {
53
+ const star = key.indexOf("*");
54
+ if (star === -1 || subpath.length < key.length)
55
+ continue;
56
+ if (!subpath.startsWith(key.slice(0, star)) || !subpath.endsWith(key.slice(star + 1)))
57
+ continue;
58
+ const bestStar = best?.indexOf("*") ?? -1;
59
+ if (best === undefined || star > bestStar || (star === bestStar && key.length > best.length))
60
+ best = key;
61
+ }
62
+ return best;
63
+ }
64
+ const isFile = (path) => statSync(path, { throwIfNoEntry: false })?.isFile() ?? false;
65
+ const real = (path) => {
66
+ try {
67
+ return realpathSync.native(path).replaceAll("\\", "/");
68
+ }
69
+ catch {
70
+ return path.replaceAll("\\", "/");
71
+ }
72
+ };
73
+ const SCRIPT = /\.(?:[cm]?[jt]sx?|svelte|vue)$/;
74
+ const STYLESHEET = /\.(?:css|scss|sass|less|styl)$/;
75
+ const DECLARATION = /\.d\.[cm]?ts$/;
76
+ const PROBE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
77
+ /** A TypeScript source imports its sibling by the extension it compiles to. */
78
+ const SOURCE_TWINS = {
79
+ ".js": [".ts", ".tsx"],
80
+ ".jsx": [".tsx"],
81
+ ".mjs": [".mts"],
82
+ ".cjs": [".cts"],
83
+ };
84
+ function probe(base) {
85
+ if (isFile(base))
86
+ return base;
87
+ const extension = extname(base);
88
+ for (const twin of SOURCE_TWINS[extension] ?? []) {
89
+ const candidate = `${base.slice(0, -extension.length)}${twin}`;
90
+ if (isFile(candidate))
91
+ return candidate;
92
+ }
93
+ for (const candidate of PROBE_EXTENSIONS.map((ext) => `${base}${ext}`)) {
94
+ if (isFile(candidate))
95
+ return candidate;
96
+ }
97
+ for (const candidate of PROBE_EXTENSIONS.map((ext) => join(base, `index${ext}`))) {
98
+ if (isFile(candidate))
99
+ return candidate;
100
+ }
101
+ return undefined;
102
+ }
103
+ const CLAUSE_PUNCT = new Set(["{", "}", ",", "*"]);
104
+ const isPunct = (token, value) => token?.kind === "punct" && token.value === value;
105
+ const isId = (token, value) => token?.kind === "id" && token.value === value;
106
+ /**
107
+ * Whether the `import`/`export` clause ending at the `from` token `at` binds only types: `import type`,
108
+ * `export type`, or a `{ }` list whose every specifier is `type`. Such an edge grants no ownership - a
109
+ * backend file a frontend entry merely types against stays backend. `import { type A }` survives as
110
+ * `import {}` under Vite with `verbatimModuleSyntax`; dropping it then fails closed, since the guard
111
+ * judges that load by the file's remaining owners.
112
+ */
113
+ function typeOnlyClause(tokens, at) {
114
+ let start = at - 1;
115
+ for (; start >= 0; start--) {
116
+ const token = tokens[start];
117
+ if (isId(token, "import") || isId(token, "export"))
118
+ break;
119
+ if (token?.kind !== "id" && !(token?.kind === "punct" && CLAUSE_PUNCT.has(token.value)))
120
+ return false;
121
+ }
122
+ if (start < 0)
123
+ return false;
124
+ const clause = tokens.slice(start + 1, at);
125
+ // `import type from "./x"` and `import type, { a } from` bind a default import named `type`.
126
+ if (isId(clause[0], "type"))
127
+ return clause.length > 1 && !isPunct(clause[1], ",");
128
+ if (!isPunct(clause[0], "{") || !isPunct(clause.at(-1), "}"))
129
+ return false;
130
+ const specifiers = [[]];
131
+ for (const token of clause.slice(1, -1)) {
132
+ if (isPunct(token, ","))
133
+ specifiers.push([]);
134
+ else
135
+ specifiers.at(-1)?.push(token);
136
+ }
137
+ const named = specifiers.filter((specifier) => specifier.length > 0);
138
+ // `{ type as x }` imports a value named `type`; `{ type A }` and `{ type A as B }` import types.
139
+ return (named.length > 0 &&
140
+ named.every((specifier) => isId(specifier[0], "type") &&
141
+ (specifier.length === 2 || (specifier.length === 4 && isId(specifier[2], "as")))));
142
+ }
143
+ /** The relative specifiers a module loads: imports, re-exports, `import()`s, `require`s and
144
+ * `new URL()`s (a worker or an asset beside it). A clause binding only types loads nothing. */
145
+ function relativeImports(code) {
146
+ const tokens = tokenize(code);
147
+ const found = [];
148
+ for (let i = 0; i < tokens.length; i++) {
149
+ const token = tokens[i];
150
+ if (token?.kind !== "id")
151
+ continue;
152
+ const previous = tokens[i - 1];
153
+ if (previous?.kind === "punct" && previous.value === ".")
154
+ continue;
155
+ let next = tokens[i + 1];
156
+ const call = next?.kind === "punct" && next.value === "(";
157
+ const url = token.value === "URL" && previous?.kind === "id" && previous.value === "new";
158
+ if (token.value === "require" || url || (token.value === "import" && call)) {
159
+ if (!call)
160
+ continue;
161
+ next = tokens[i + 2];
162
+ }
163
+ else if (token.value !== "from" && token.value !== "import")
164
+ continue;
165
+ if (next?.kind !== "string" || !/^\.\.?\//.test(next.value))
166
+ continue;
167
+ if (token.value === "from" && typeOnlyClause(tokens, i))
168
+ continue;
169
+ found.push(next.value);
170
+ }
171
+ return found;
172
+ }
173
+ /** What a stylesheet pulls in beside it: `@import`s and `url()`s that name no scheme or root. */
174
+ function stylesheetImports(code) {
175
+ const text = code.replace(/\/\*[\s\S]*?\*\//g, "");
176
+ const found = [];
177
+ for (const match of text.matchAll(/@import\s+(?:url\(\s*)?["']?([^"'()\s;]+)|url\(\s*["']?([^"'()\s]+)/g)) {
178
+ const reference = match[1] ?? match[2] ?? "";
179
+ if (reference !== "" && !/^(?:[a-z][\w+.-]*:|\/|#|~)/i.test(reference))
180
+ found.push(reference);
181
+ }
182
+ return found;
183
+ }
184
+ /** Every string target of an export value, under every condition. */
185
+ function targetsOf(value) {
186
+ if (typeof value === "string")
187
+ return value.startsWith("./") ? [value] : [];
188
+ if (Array.isArray(value))
189
+ return value.flatMap(targetsOf);
190
+ if (typeof value === "object" && value !== null)
191
+ return Object.values(value).flatMap(targetsOf);
192
+ return [];
193
+ }
194
+ /** `exports` as subpath entries; without it, the root is `main`/`module`/`browser` and any file a subpath. */
195
+ function exportEntries(manifest, entries) {
196
+ const exports = manifest.exports;
197
+ if (exports === undefined || exports === null) {
198
+ const roots = [manifest.main, manifest.module, manifest.browser]
199
+ .filter((root) => typeof root === "string")
200
+ .map((root) => (root.startsWith("./") ? root : `./${root}`));
201
+ return [
202
+ [".", roots.length > 0 ? roots : ["./index.js"]],
203
+ ...Object.keys(entries)
204
+ .filter((key) => key !== ".")
205
+ .map((key) => [key, [key]]),
206
+ ];
207
+ }
208
+ if (typeof exports !== "object" || Array.isArray(exports))
209
+ return [[".", targetsOf(exports)]];
210
+ const keys = Object.keys(exports);
211
+ if (keys.length === 0 || !keys.every((key) => key.startsWith(".")))
212
+ return [[".", targetsOf(exports)]];
213
+ return Object.entries(exports).map(([key, value]) => [key, targetsOf(value)]);
214
+ }
215
+ /** Every file under `dir`, outside `node_modules`. */
216
+ function filesUnder(dir) {
217
+ let names;
218
+ try {
219
+ names = readdirSync(dir, { recursive: true, encoding: "utf8" });
220
+ }
221
+ catch {
222
+ return [];
223
+ }
224
+ return names
225
+ .filter((name) => !/(?:^|[\\/])node_modules(?:[\\/]|$)/.test(name))
226
+ .map((name) => join(dir, name))
227
+ .filter(isFile);
228
+ }
229
+ /** Which mapped entries reach each file of the package at `dir` (a real path). */
230
+ export function entryOwnership(dir, manifest, entries) {
231
+ const owners = new Map();
232
+ const unmapped = new Set();
233
+ const queue = [];
234
+ const reach = (path, side) => {
235
+ const file = real(path);
236
+ if (!file.startsWith(`${dir}/`) || file.slice(dir.length).includes("/node_modules/"))
237
+ return;
238
+ const sides = owners.get(file) ?? new Set();
239
+ if (sides.has(side))
240
+ return;
241
+ sides.add(side);
242
+ owners.set(file, sides);
243
+ queue.push([file, side]);
244
+ };
245
+ const sideOf = (subpath, exportKey = subpath) => {
246
+ const key = entryKey(entries, subpath);
247
+ if (key === undefined)
248
+ unmapped.add(exportKey);
249
+ return key === undefined ? undefined : entries[key];
250
+ };
251
+ for (const [key, targets] of exportEntries(manifest, entries)) {
252
+ const star = key.indexOf("*");
253
+ if (star === -1) {
254
+ const side = sideOf(key);
255
+ if (side === undefined)
256
+ continue;
257
+ for (const target of targets) {
258
+ const file = target.includes("*") ? undefined : probe(join(dir, target));
259
+ if (file !== undefined)
260
+ reach(file, side);
261
+ }
262
+ continue;
263
+ }
264
+ // A pattern entry: each file a target pattern matches is the subpath its `*` spells.
265
+ for (const target of targets) {
266
+ const at = target.indexOf("*");
267
+ if (at === -1)
268
+ continue;
269
+ const prefix = target.slice(0, at);
270
+ const suffix = target.slice(at + 1);
271
+ for (const file of filesUnder(join(dir, prefix.slice(0, prefix.lastIndexOf("/") + 1)))) {
272
+ const path = `./${relative(dir, file).replaceAll("\\", "/")}`;
273
+ if (path.length <= prefix.length + suffix.length)
274
+ continue;
275
+ if (!path.startsWith(prefix) || !path.endsWith(suffix))
276
+ continue;
277
+ const matched = path.slice(prefix.length, path.length - suffix.length);
278
+ const side = sideOf(`${key.slice(0, star)}${matched}${key.slice(star + 1)}`, key);
279
+ if (side !== undefined)
280
+ reach(file, side);
281
+ }
282
+ }
283
+ }
284
+ const imports = new Map();
285
+ for (const [file, side] of queue) {
286
+ const script = SCRIPT.test(file) && !DECLARATION.test(file);
287
+ if (!script && !STYLESHEET.test(file))
288
+ continue;
289
+ let specifiers = imports.get(file);
290
+ if (specifiers === undefined) {
291
+ try {
292
+ const code = readFileSync(file, "utf8");
293
+ specifiers = script ? relativeImports(code) : stylesheetImports(code);
294
+ }
295
+ catch {
296
+ specifiers = [];
297
+ }
298
+ imports.set(file, specifiers);
299
+ }
300
+ for (const specifier of specifiers) {
301
+ const found = probe(join(dirname(file), withoutQuery(specifier)));
302
+ if (found !== undefined)
303
+ reach(found, side);
304
+ }
305
+ }
306
+ return { owners, unmapped: [...unmapped].sort() };
307
+ }
308
+ /**
309
+ * The `package.json` of the installed package `name`, as Node finds it: the nearest
310
+ * `node_modules/<name>` at or above `fromDir`.
311
+ */
312
+ export function installedManifest(fromDir, name) {
313
+ let dir = fromDir;
314
+ for (;;) {
315
+ const manifest = join(dir, "node_modules", name, "package.json");
316
+ if (isFile(manifest))
317
+ return manifest;
318
+ const parent = dirname(dir);
319
+ if (parent === dir)
320
+ return undefined;
321
+ dir = parent;
322
+ }
323
+ }
324
+ //# sourceMappingURL=package-entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-entries.js","sourceRoot":"","sources":["../../src/internal/package-entries.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"page-execution.d.ts","sourceRoot":"","sources":["../../src/internal/page-execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"page-execution.d.ts","sourceRoot":"","sources":["../../src/internal/page-execution.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { NIFRA_BACKEND_BIND_PLATFORM, NIFRA_PLATFORM_CLIENT_IP_DERIVED, } from "@nifrajs/core/mount";
2
- import { status as statusResult } from "@nifrajs/core/server";
2
+ import { isSameOriginForm, status as statusResult, } from "@nifrajs/core/server";
3
3
  import { boundaryDescriptors, resolveStaticBoundaries, startDynamicBoundaries, } from "../boundary.js";
4
4
  import { DEFAULT_CSS_LOADING, normalizeCssLoading } from "../css-contract.js";
5
5
  import { defer, ndjsonStream, prepareDeferred } from "../deferred.js";
@@ -92,9 +92,12 @@ function appTarget(location, requestUrl) {
92
92
  catch {
93
93
  return location; // the browser fails on it the same way when it loads it
94
94
  }
95
- return target.origin === new URL(requestUrl).origin
96
- ? target.pathname + target.search + target.hash
97
- : location;
95
+ if (target.origin !== new URL(requestUrl).origin)
96
+ return location;
97
+ // A path starting `//` (from `/.//host`) is a protocol-relative URL to whoever resolves it next.
98
+ return target.pathname.startsWith("//")
99
+ ? target.href
100
+ : target.pathname + target.search + target.hash;
98
101
  }
99
102
  /**
100
103
  * Own the page request program behind one private seam.
@@ -213,6 +216,23 @@ export function createPageRequestExecutor(options) {
213
216
  throw tagLayoutError(value, route.layoutIds[index]);
214
217
  return value;
215
218
  };
219
+ // Development only. A layout loader that refuses access reads as a guard, and is not one: a client
220
+ // navigation can skip it and an action below it runs without it.
221
+ const warnsUngatedRefusal = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
222
+ const warnedUngated = new Set();
223
+ const warnUngatedRefusal = (layoutId, outcome) => {
224
+ if (warnedUngated.has(layoutId))
225
+ return;
226
+ // notFound() and gone() say the record is missing, which a layout may decide without guarding.
227
+ const refusesAccess = isStatusSignal(outcome)
228
+ ? outcome.status === 401 || outcome.status === 403
229
+ : isControlFlow(outcome);
230
+ if (!refusesAccess)
231
+ return;
232
+ warnedUngated.add(layoutId);
233
+ const file = manifest.layouts?.[layoutId]?.file ?? layoutId;
234
+ console.warn(`[nifra/web] the loader in "${file}" refused a request, but that layout is not a gate. A client navigation that keeps the layout on screen can skip its loader, and an action below it runs without it, so it does not protect the pages under it. Export \`gate = true\` from that file, or move the check into middleware. (Shown in development only.)`);
235
+ };
216
236
  /**
217
237
  * Run layout loaders, awaiting gates before starting the page loader and retaining only safe data.
218
238
  * `gated` carries gates that already ran for this request, so none runs twice.
@@ -263,18 +283,31 @@ export function createPageRequestExecutor(options) {
263
283
  // assimilation: property-presence and prototype probes are unsafe for proxies.
264
284
  if (value !== null && (typeof value === "object" || typeof value === "function")) {
265
285
  pending.push((async () => {
286
+ let settled;
266
287
  try {
267
- results[index] = await value;
288
+ settled = await value;
268
289
  }
269
290
  catch (err) {
291
+ if (warnsUngatedRefusal)
292
+ warnUngatedRefusal(layoutId, err);
270
293
  throw tagLayoutError(err, layoutId);
271
294
  }
295
+ // A returned redirect or Response refuses exactly as a thrown one: kept as layout data,
296
+ // it would ship beside the page loader's data.
297
+ if (isControlFlow(settled)) {
298
+ if (warnsUngatedRefusal)
299
+ warnUngatedRefusal(layoutId, settled);
300
+ throw tagLayoutError(settled, layoutId);
301
+ }
302
+ results[index] = settled;
272
303
  })());
273
304
  }
274
305
  else
275
306
  results[index] = value;
276
307
  }
277
308
  catch (err) {
309
+ if (warnsUngatedRefusal)
310
+ warnUngatedRefusal(layoutId, err);
278
311
  // Preserve a synchronous throw as a pending layout failure, just like the async lane.
279
312
  pending.push(Promise.reject(tagLayoutError(err, layoutId)));
280
313
  }
@@ -1063,6 +1096,28 @@ export function createPageRequestExecutor(options) {
1063
1096
  headers: { allow: "GET", "content-type": "text/plain; charset=utf-8" },
1064
1097
  });
1065
1098
  }
1099
+ const isDataRequest = c.req.headers.get(DATA_HEADER) !== null;
1100
+ // Before anything runs: a form posts cross-site without a preflight and carries the visitor's
1101
+ // cookies, so an action is a CSRF target unless its route names the origins it accepts.
1102
+ const origin = c.req.headers.get("origin");
1103
+ const allowedOrigins = mod.allowedOrigins;
1104
+ const allowed = allowedOrigins === undefined
1105
+ ? origin === null ||
1106
+ isSameOriginForm(origin, c.req.headers.get("sec-fetch-site"), c.req)
1107
+ : typeof allowedOrigins === "function"
1108
+ ? allowedOrigins(origin) === true
1109
+ : origin !== null && allowedOrigins.includes(origin);
1110
+ if (!allowed) {
1111
+ return isDataRequest
1112
+ ? Response.json({ ok: false, error: "forbidden_origin" }, { status: 403, headers: { "cache-control": PRIVATE_NO_STORE } })
1113
+ : new Response("Forbidden", {
1114
+ status: 403,
1115
+ headers: {
1116
+ "content-type": "text/plain; charset=utf-8",
1117
+ "cache-control": PRIVATE_NO_STORE,
1118
+ },
1119
+ });
1120
+ }
1066
1121
  const requestApi = apiFor(c);
1067
1122
  const actionContext = {
1068
1123
  params: c.params,
@@ -1074,7 +1129,6 @@ export function createPageRequestExecutor(options) {
1074
1129
  search: loaderSearch(mod.searchSchema, c.req),
1075
1130
  set: controls.scope(ACTION_SCOPE),
1076
1131
  };
1077
- const isDataRequest = c.req.headers.get(DATA_HEADER) !== null;
1078
1132
  let gated;
1079
1133
  let result;
1080
1134
  try {