@reckona/mreact-router 0.0.97 → 0.0.99
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/README.md +4 -0
- package/dist/actions.d.ts +7 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +26 -2
- package/dist/actions.js.map +1 -1
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +10 -7
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/build.d.ts +38 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +1087 -304
- package/dist/build.js.map +1 -1
- package/dist/bundle-pipeline.d.ts +7 -0
- package/dist/bundle-pipeline.d.ts.map +1 -1
- package/dist/bundle-pipeline.js +121 -87
- package/dist/bundle-pipeline.js.map +1 -1
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +10 -8
- package/dist/cache.js.map +1 -1
- package/dist/cli-options.d.ts +1 -0
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +16 -0
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +6 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +113 -8
- package/dist/client.js.map +1 -1
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +7 -3
- package/dist/csrf.js.map +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +18 -1
- package/dist/http.js.map +1 -1
- package/dist/import-policy.d.ts.map +1 -1
- package/dist/import-policy.js +7 -3
- package/dist/import-policy.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/link.d.ts +5 -2
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +92 -3
- package/dist/link.js.map +1 -1
- package/dist/logger.d.ts +7 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/module-runner.d.ts +2 -0
- package/dist/module-runner.d.ts.map +1 -1
- package/dist/module-runner.js +1 -0
- package/dist/module-runner.js.map +1 -1
- package/dist/native-route-matcher.d.ts +2 -1
- package/dist/native-route-matcher.d.ts.map +1 -1
- package/dist/native-route-matcher.js +13 -2
- package/dist/native-route-matcher.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +117 -2
- package/dist/render.js.map +1 -1
- package/dist/route-source.d.ts +4 -4
- package/dist/route-source.d.ts.map +1 -1
- package/dist/route-source.js +8 -8
- package/dist/route-source.js.map +1 -1
- package/dist/route-styles.d.ts +6 -0
- package/dist/route-styles.d.ts.map +1 -1
- package/dist/route-styles.js +10 -1
- package/dist/route-styles.js.map +1 -1
- package/dist/serve.d.ts +5 -0
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +7 -4
- package/dist/serve.js.map +1 -1
- package/package.json +11 -11
- package/src/actions.ts +42 -2
- package/src/adapters/aws-lambda.ts +33 -16
- package/src/build.ts +1578 -397
- package/src/bundle-pipeline.ts +136 -88
- package/src/cache.ts +13 -8
- package/src/cli-options.ts +20 -0
- package/src/cli.ts +1 -0
- package/src/client.ts +145 -14
- package/src/csrf.ts +8 -3
- package/src/http.ts +21 -1
- package/src/import-policy.ts +8 -3
- package/src/index.ts +5 -0
- package/src/link.ts +129 -8
- package/src/logger.ts +9 -1
- package/src/module-runner.ts +4 -0
- package/src/native-route-matcher.ts +13 -2
- package/src/render.ts +177 -2
- package/src/route-source.ts +8 -8
- package/src/route-styles.ts +17 -1
- package/src/serve.ts +11 -6
package/README.md
CHANGED
|
@@ -149,6 +149,8 @@ export default function Page() {
|
|
|
149
149
|
|
|
150
150
|
Route metadata is composed from parent layouts before the matched page. CSP directives are additive by default through `metadata.csp.directives`, but route-local metadata may replace inherited directives with `metadata.csp.replace`, remove inherited directives with `metadata.csp.remove`, or disable CSP for the route with `metadata.csp.disable = true`. These overrides are applied after inherited directives so the matched page has the final say for vendor callbacks, embedded checkout pages, and other narrowly scoped policy exceptions.
|
|
151
151
|
|
|
152
|
+
When `metadata.csp.nonce` is set, the CSP serializer appends that nonce to `script-src` and `style-src` only when those directives are present. A nonce on `style-src` disables the browser's implicit allowance for inline styles, so JSX-rendered `<style>` blocks must also carry a matching nonce or move to an external stylesheet. Use `metadata.head` for route-owned inline styles that need the framework nonce, for example `{ tag: "style", nonce: true, content: "body{color:red}" }`. If you only need script hardening, set `script-src` and leave `style-src` unset.
|
|
153
|
+
|
|
152
154
|
Rendered routes include conservative default response headers: `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, and `Permissions-Policy: camera=(), microphone=(), geolocation=()`. Use `metadata.security` to opt out of a default, override a policy, add `X-Frame-Options`, or enable HSTS for HTTPS requests. Security header values are validated before they are emitted.
|
|
153
155
|
|
|
154
156
|
Root app files can define crawler and install metadata without adding route handlers. `robots.ts`, `sitemap.ts`, and `manifest.ts` serve `/robots.txt`, `/sitemap.xml`, and `/manifest.webmanifest`; static `robots.txt`, `sitemap.xml`, `manifest.webmanifest`, `favicon.ico`, `icon.*`, `apple-icon.*`, and `opengraph-image.*` files are copied as public assets during builds. Route-local `opengraph-image.tsx` / `.ts` / `.jsx` / `.js` modules serve `/<route>/opengraph-image`, receive `{ params, request }`, may return a `Response`, string, or bytes, and are used as the default `og:image` when the page does not set one explicitly. Static files take precedence over generated metadata routes for the same URL, and icon files are also used as fallback route metadata when a page does not define its own icon or OpenGraph image.
|
|
@@ -345,6 +347,8 @@ For Lambda deployments, build with `mreact-router build --target=aws-lambda` or
|
|
|
345
347
|
|
|
346
348
|
Package Lambda deployments with `mreact-router package aws-lambda --from .mreact --out .lambda` instead of pointing deployment tooling at the full project checkout. AWS Lambda enforces a 250 MB unzipped deployment package limit, and the runtime only needs `.mreact/`, `mreact-handler.mjs`, `package.json` / lockfiles, and production `node_modules`; `src/`, tests, dev dependencies, build caches, and Vite/Vitest/Playwright tooling are not required. `mreact-router build --target=aws-lambda` keeps compiled server route artifacts in `.mreact/server/server-modules/*.json` instead of embedding them in one large server manifest, writes compiled module bodies as hashed `.mjs` files, and keeps request/control artifacts separate from render artifacts so loader redirects do not read page render bundles. `createAwsLambdaRequestHandler()` treats `outDir` as read-only and materializes generated runtime files under `/tmp/mreact-router/<hash>/runtime` by default, with a `node_modules` symlink back to the deployed package root. Direct `createAwsLambdaRequestHandler()` and `createAwsLambdaStreamingRequestHandler()` handlers start only middleware and shared runtime preload in the background by default, so all-route preload work does not compete with the first user request. If a request arrives before preload finishes, middleware is resolved first, middleware responses or redirects return without loading the matched page artifact, and continuing requests load only the matched route's artifact closure. Static middleware `config.matcher` and `config.id` values are checked before importing the middleware module, so unmatched health checks and route-local middleware skips avoid evaluating heavyweight middleware dependencies. Route request artifacts omit page render exports, and built loader and route metadata artifacts are split, so loader redirects do not evaluate page-only or metadata-only dependencies before render or metadata is needed. Loader redirects settle before page component server transforms and render imports for non-stream routes and stream routes without a loading boundary. Prefer `await createPreloadedAwsLambdaRequestHandler()` in Node 24 ESM Lambda handlers when first-request latency matters: it waits for the full preload during Lambda initialization by default, increasing `Init Duration` but making the first handler invocation much closer to warm steady-state. Pass `runtimeDir` only when you need to control that writable cache location. With pnpm, run `pnpm --dir .lambda install --prod --frozen-lockfile --ignore-scripts --config.node-linker=hoisted`. pnpm's default isolated linker is symlink-heavy, so verify the artifact's symlink count with `find .lambda -type l | wc -l` and measure actual file bytes in addition to `du -sh .lambda` before upload. Packages listed in the generated import policy must also be installed in that production artifact.
|
|
347
349
|
|
|
350
|
+
When a deployment needs custom adapter options such as `serverActions.authorize`, `onResponse`, `errorHandler`, or `allowedHosts`, create an app handler and package it with `mreact-router package aws-lambda --from .mreact --out .lambda --handler src/lambda.ts`. The package command bundles that handler into `.lambda/mreact-handler.mjs`, resolves app-local TypeScript imports with Vite-style extensionless paths, and keeps package imports external so production `node_modules` remains the runtime dependency boundary. If the handler imports the same app server modules that routes also import, those modules are compiled into the handler bundle separately from the mreact route artifacts; use `getServerRuntimeState()` for state that must be shared through the router runtime instead of relying on module singletons.
|
|
351
|
+
|
|
348
352
|
Configure `allowedHosts` for production Lambda deployments so absolute URLs, redirects, cache keys, and metadata cannot be derived from attacker-controlled Host input. The Lambda adapter uses `Host` by default and only reads `x-forwarded-host` when `hostPolicy: "trusted-proxy"` is set. It also ignores `x-forwarded-proto` unless `trustForwardedProto: true` is configured, deriving the request scheme from the Lambda event protocol when available and otherwise defaulting to HTTPS.
|
|
349
353
|
|
|
350
354
|
Use the Lambda `preload` option to tune that trade-off. Direct handlers default to `"middleware"` so cold starts do not kick off all route module imports in parallel with the first request. `createPreloadedAwsLambdaRequestHandler()` and `createPreloadedAwsLambdaStreamingRequestHandler()` default to `"all"` because the work is awaited during Lambda initialization instead of racing user traffic. Set `preload: "none"` to disable background preload, `preload: "all"` only when you have measured that all-route background preload helps the deployed function, `preload: { mode: "hot-routes", routes: ["/", "/dashboard"] }` with `createPreloadedAwsLambdaRequestHandler()` to await selected route closures including render modules during Lambda initialization, or `preload: { mode: "hot-route-requests", routes: ["/", "/login"] }` to warm only middleware plus selected route loader/server-route request modules without evaluating page/layout render modules. For direct handlers that cannot use top-level async initialization, add `wait: "before-render"` to an object preload strategy to let page-rendering invocations wait for the already-started preload after loader redirects have had a chance to return; add `wait: "first-request"` only when the first invocation can pay the full preload cost. Lambda request timing reports `first-request` waits as `preloadWaitMs`, and render timing reports `before-render` waits as `preloadWaitMs`.
|
package/dist/actions.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { type ServerActionHandlerOptions, type ServerActionReplayStore, type ServerActionRequestReference } from "@reckona/mreact-server";
|
|
2
2
|
import { type AppRouterCache } from "./cache.js";
|
|
3
3
|
import { type AppRouterImportPolicy } from "./import-policy.js";
|
|
4
|
+
import { type RequestCookies } from "./navigation.js";
|
|
4
5
|
export { createFormCsrfToken, formCsrfCookie, formCsrfFieldName, serverActionCookie, validateFormCsrf, } from "./csrf.js";
|
|
5
6
|
import { type ServerActionInferenceDiagnostic } from "./server-action-inference.js";
|
|
7
|
+
export interface ServerActionContext {
|
|
8
|
+
clientIp?: string | undefined;
|
|
9
|
+
cookies: RequestCookies;
|
|
10
|
+
headers: Headers;
|
|
11
|
+
request: Request;
|
|
12
|
+
}
|
|
6
13
|
declare class BoundedReplayStore {
|
|
7
14
|
private readonly ttlMs;
|
|
8
15
|
private readonly maxEntries;
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,0BAA0B,EAE/B,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EAElC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,KAAK,cAAc,EAAyB,MAAM,YAAY,CAAC;AAExE,OAAO,EAAqC,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,8BAA8B,CAAC;AAgCtC,cAAM,kBAAkB;IAIpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJ7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;gBAGlC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM;IAGrC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAU3B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAqBxB,IAAI,IAAI,MAAM;CAGf;AAUD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,wBAAgB,wBAAwB,IAAI,kBAAkB,CAE7D;AAED,MAAM,WAAW,4BAA4B;IAC3C,cAAc,CAAC,EAAE,SAAS,4BAA4B,EAAE,GAAG,SAAS,CAAC;IACrE,SAAS,CAAC,EAAE,0BAA0B,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,WAAW,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACnD;AAED,MAAM,WAAW,4BAA6B,SAAQ,4BAA4B;IAChF,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,+BAA+B,EAAE,GAAG,SAAS,CAAC;IAK5D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;CACzB;AAQD,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,wBAAsB,yBAAyB,CAAC,OAAO,EAAE;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,SAAS,2BAA2B,EAAE,GAAG,SAAS,CAAC;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4DhC;AA0BD,wBAAsB,2BAA2B,CAAC,OAAO,EAAE;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;CAC1D,GAAG,OAAO,CAAC,QAAQ,CAAC,CAMpB;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/actions.js
CHANGED
|
@@ -8,6 +8,7 @@ import { bundleRouterModule } from "./bundle-pipeline.js";
|
|
|
8
8
|
import { withRouteCacheContext } from "./cache.js";
|
|
9
9
|
import { fileImportMetaUrlPlugin, importAppRouterSourceModule } from "./module-runner.js";
|
|
10
10
|
import { createAppRouterImportPolicyPlugin } from "./import-policy.js";
|
|
11
|
+
import { cookies } from "./navigation.js";
|
|
11
12
|
export { createFormCsrfToken, formCsrfCookie, formCsrfFieldName, serverActionCookie, validateFormCsrf, } from "./csrf.js";
|
|
12
13
|
import { formCsrfFieldName, readExistingFormCsrfToken, validateFormCsrf, } from "./csrf.js";
|
|
13
14
|
import { collectRuntimeInferredServerActions, } from "./server-action-inference.js";
|
|
@@ -18,7 +19,7 @@ const formFieldModuleId = "__mreact_module_id";
|
|
|
18
19
|
const formFieldExportName = "__mreact_export_name";
|
|
19
20
|
const formFieldNonce = "__mreact_action_nonce";
|
|
20
21
|
const formFieldActionToken = "__mreact_action_token";
|
|
21
|
-
const actionTokenSecret = process.env.MREACT_SERVER_ACTION_SECRET ??
|
|
22
|
+
const actionTokenSecret = process.env.MREACT_SERVER_ACTION_SECRET ?? defaultActionTokenSecret();
|
|
22
23
|
// Bounded default replay store for form-action nonces. The previous
|
|
23
24
|
// implementation was an unbounded Set that grew with every successful
|
|
24
25
|
// submission (Issue 069). Production callers should still pass a shared
|
|
@@ -40,6 +41,12 @@ const DEFAULT_REPLAY_TTL_MS = 10 * 60 * 1000;
|
|
|
40
41
|
const DEFAULT_REPLAY_MAX_ENTRIES = 50_000;
|
|
41
42
|
const DEFAULT_ACTION_BODY_MAX_BYTES = 10 * 1024 * 1024;
|
|
42
43
|
let warnedUnrestrictedServerActions = false;
|
|
44
|
+
function defaultActionTokenSecret() {
|
|
45
|
+
if (isProductionEnvironment()) {
|
|
46
|
+
console.warn("mreact-router: MREACT_SERVER_ACTION_SECRET is not set. Inferred server action tokens use a per-process secret and may fail across multiple production instances.");
|
|
47
|
+
}
|
|
48
|
+
return randomBytes(32).toString("base64url");
|
|
49
|
+
}
|
|
43
50
|
class BoundedReplayStore {
|
|
44
51
|
ttlMs;
|
|
45
52
|
maxEntries;
|
|
@@ -282,7 +289,7 @@ async function dispatchServerActionRequestWithoutCacheContext(options) {
|
|
|
282
289
|
return authorizationResponse;
|
|
283
290
|
}
|
|
284
291
|
try {
|
|
285
|
-
const value = await action(actionFormData);
|
|
292
|
+
const value = await action(actionFormData, createServerActionContext(options.request));
|
|
286
293
|
if (value instanceof Response) {
|
|
287
294
|
return value;
|
|
288
295
|
}
|
|
@@ -295,6 +302,23 @@ async function dispatchServerActionRequestWithoutCacheContext(options) {
|
|
|
295
302
|
return jsonResponse({ ok: false, error: error instanceof Error ? error.message : String(error) }, 500);
|
|
296
303
|
}
|
|
297
304
|
}
|
|
305
|
+
function createServerActionContext(request) {
|
|
306
|
+
const clientIp = clientIpFromRequest(request);
|
|
307
|
+
return {
|
|
308
|
+
...(clientIp === undefined ? {} : { clientIp }),
|
|
309
|
+
cookies: cookies(request),
|
|
310
|
+
headers: request.headers,
|
|
311
|
+
request,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function clientIpFromRequest(request) {
|
|
315
|
+
const forwarded = request.headers.get("x-forwarded-for")?.split(",")[0]?.trim();
|
|
316
|
+
if (forwarded !== undefined && forwarded !== "") {
|
|
317
|
+
return forwarded;
|
|
318
|
+
}
|
|
319
|
+
const realIp = request.headers.get("x-real-ip")?.trim();
|
|
320
|
+
return realIp === "" ? undefined : realIp;
|
|
321
|
+
}
|
|
298
322
|
function validateServerActionBodySize(request, maxBodyBytes) {
|
|
299
323
|
if (!Number.isFinite(maxBodyBytes) || maxBodyBytes < 0) {
|
|
300
324
|
return undefined;
|
package/dist/actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { access, readdir, readFile } from \"node:fs/promises\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n collectFormActionExpressionReferences,\n hasModuleDirective,\n} from \"@reckona/mreact-compiler\";\nimport {\n createServerActionHandler,\n type ServerActionHandlerOptions,\n type ServerActionRegistry,\n type ServerActionReplayStore,\n type ServerActionRequestReference,\n type ServerActionValidationResult,\n} from \"@reckona/mreact-server\";\nimport { bundleRouterModule, type RouterCompatBuildApi } from \"./bundle-pipeline.js\";\nimport { type AppRouterCache, withRouteCacheContext } from \"./cache.js\";\nimport { fileImportMetaUrlPlugin, importAppRouterSourceModule } from \"./module-runner.js\";\nimport { createAppRouterImportPolicyPlugin, type AppRouterImportPolicy } from \"./import-policy.js\";\nexport {\n createFormCsrfToken,\n formCsrfCookie,\n formCsrfFieldName,\n serverActionCookie,\n validateFormCsrf,\n} from \"./csrf.js\";\nimport {\n formCsrfFieldName,\n readExistingFormCsrfToken,\n validateFormCsrf,\n} from \"./csrf.js\";\nimport {\n collectRuntimeInferredServerActions,\n type ServerActionInferenceDiagnostic,\n} from \"./server-action-inference.js\";\n\nfunction isProductionEnvironment(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\nconst formFieldModuleId = \"__mreact_module_id\";\nconst formFieldExportName = \"__mreact_export_name\";\nconst formFieldNonce = \"__mreact_action_nonce\";\nconst formFieldActionToken = \"__mreact_action_token\";\nconst actionTokenSecret = process.env.MREACT_SERVER_ACTION_SECRET ?? randomBytes(32).toString(\"base64url\");\n// Bounded default replay store for form-action nonces. The previous\n// implementation was an unbounded Set that grew with every successful\n// submission (Issue 069). Production callers should still pass a shared\n// store (Redis / KV) via `serverActions.replayStore` for multi-instance\n// deployments -- this default only guarantees replay protection within\n// a single process and is the safe fallback for dev / single-node setups.\n//\n// Retention model:\n// - TTL: 10 minutes. Form nonces are minted at SSR time and the user\n// has to submit before the cookie's SameSite=Lax window anyway; this\n// is generous for any realistic submit cadence.\n// - Max size: 50_000 entries. Old entries are evicted FIFO once the cap\n// is reached so a flood cannot trigger OOM.\n//\n// Both bounds are intentional defaults -- tight enough that a single\n// process cannot leak unbounded RSS, loose enough that legitimate\n// traffic does not trip false-positive 409s.\nconst DEFAULT_REPLAY_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_REPLAY_MAX_ENTRIES = 50_000;\nconst DEFAULT_ACTION_BODY_MAX_BYTES = 10 * 1024 * 1024;\nlet warnedUnrestrictedServerActions = false;\n\nclass BoundedReplayStore {\n private readonly entries = new Map<string, number>();\n\n constructor(\n private readonly ttlMs: number,\n private readonly maxEntries: number,\n ) {}\n\n has(value: string): boolean {\n const expiresAt = this.entries.get(value);\n if (expiresAt === undefined) return false;\n if (expiresAt < Date.now()) {\n this.entries.delete(value);\n return false;\n }\n return true;\n }\n\n add(value: string): void {\n const now = Date.now();\n // Cheap opportunistic sweep: drop the oldest expired entries first,\n // then enforce the hard cap with FIFO eviction.\n if (this.entries.size >= this.maxEntries) {\n for (const [key, expiresAt] of this.entries) {\n if (expiresAt < now) {\n this.entries.delete(key);\n }\n if (this.entries.size < this.maxEntries) break;\n }\n while (this.entries.size >= this.maxEntries) {\n const oldest = this.entries.keys().next().value;\n if (oldest === undefined) break;\n this.entries.delete(oldest);\n }\n }\n this.entries.set(value, now + this.ttlMs);\n }\n\n // Exposed for tests; not part of the ServerActionReplayStore interface.\n size(): number {\n return this.entries.size;\n }\n}\n\nconst usedFormActionNonces = new BoundedReplayStore(\n DEFAULT_REPLAY_TTL_MS,\n DEFAULT_REPLAY_MAX_ENTRIES,\n);\n\n// Test helpers: drop all entries between cases / expose the bounded store\n// so tests can drive its eviction semantics directly. Not part of the\n// public surface (prefixed with `__`).\nexport function __clearDefaultReplayStore(): void {\n (usedFormActionNonces as unknown as { entries: Map<string, number> }).entries.clear();\n}\n\nexport function __readDefaultReplayStore(): BoundedReplayStore {\n return usedFormActionNonces;\n}\n\nexport interface AppRouterServerActionOptions {\n allowedActions?: readonly AppRouterAllowedServerAction[] | undefined;\n authorize?: ServerActionHandlerOptions[\"authorize\"] | undefined;\n maxBodyBytes?: number | undefined;\n replayStore?: ServerActionReplayStore | undefined;\n}\n\nexport interface AppRouterAllowedServerAction extends ServerActionRequestReference {\n inferred?: boolean | undefined;\n}\n\nexport interface PreparedRouteActions {\n actionNonce?: string;\n code: string;\n csrfToken?: string;\n diagnostics?: ServerActionInferenceDiagnostic[] | undefined;\n // True when the cookie should be (re)set on the response. False means\n // the incoming request already carried a valid CSRF cookie that the\n // render is reusing -- skipping Set-Cookie avoids cookie thrash across\n // concurrent tabs (Issue 070).\n csrfTokenIsNew?: boolean;\n hasFormActions: boolean;\n}\n\ninterface ActionReference {\n exportName: string;\n inferred: boolean;\n moduleId: string;\n}\n\nexport interface PreparedFormActionReference {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n exportName: string;\n inferred: boolean;\n moduleId: string;\n sourceHash: string;\n start: number;\n}\n\nconst inferredServerActionReferences = new Map<string, Map<string, Map<string, ActionReference>>>();\n\nexport async function prepareRouteServerActions(options: {\n appDir: string;\n code: string;\n formActionReferences?: readonly PreparedFormActionReference[] | undefined;\n pageFile: string;\n request?: Request | undefined;\n}): Promise<PreparedRouteActions> {\n if (options.formActionReferences !== undefined && options.formActionReferences.length === 0) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return { code: options.code, hasFormActions: false };\n }\n\n if (!hasFormActionCandidate(options.code, options.pageFile)) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return { code: options.code, hasFormActions: false };\n }\n\n const inference =\n options.formActionReferences === undefined\n ? await collectImportedServerActions(options)\n : {\n diagnostics: [],\n references: formActionReferenceMap(options.code, options.formActionReferences),\n };\n const { diagnostics, references } = inference;\n\n if (references.size === 0) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return diagnostics.length === 0\n ? { code: options.code, hasFormActions: false }\n : { code: options.code, diagnostics, hasFormActions: false };\n }\n\n // Reuse the existing CSRF token when the browser already sent one.\n // Rotating the cookie on every render (Issue 070) broke concurrent\n // forms because the older tab's hidden input no longer matched the\n // cookie value. The actionNonce stays per-render -- that is the field\n // tied to a specific submission via replay protection.\n const existingToken = readExistingFormCsrfToken(options.request);\n const csrfToken = existingToken ?? randomUUID();\n const csrfTokenIsNew = existingToken === undefined;\n const actionNonce = randomUUID();\n const lowered = lowerFormActions({\n actionNonce,\n code: options.code,\n csrfToken,\n references,\n });\n\n if (lowered === options.code) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return diagnostics.length === 0\n ? { code: options.code, hasFormActions: false }\n : { code: options.code, diagnostics, hasFormActions: false };\n }\n\n replaceInferredServerActionReferences(options.appDir, options.pageFile, references);\n\n return {\n actionNonce,\n code: lowered,\n csrfToken,\n csrfTokenIsNew,\n diagnostics,\n hasFormActions: true,\n };\n}\n\nfunction formActionReferenceMap(\n code: string,\n references: readonly PreparedFormActionReference[],\n): Map<string, ActionReference> {\n const sourceHash = formActionSourceHash(code);\n\n return new Map(\n references\n .filter((reference) => reference.sourceHash === sourceHash)\n .map((reference) => [\n formActionOccurrenceKey(reference),\n {\n exportName: reference.exportName,\n inferred: reference.inferred,\n moduleId: reference.moduleId,\n },\n ]),\n );\n}\n\nfunction hasFormActionCandidate(code: string, filename: string): boolean {\n return collectFormActionExpressionReferences({ code, filename }).length > 0;\n}\n\nexport async function dispatchServerActionRequest(options: {\n appDir: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n request: Request;\n routeCache?: AppRouterCache | undefined;\n serverActionCacheVersion?: string | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n}): Promise<Response> {\n const { revalidatedPaths, value } = await withRouteCacheContext(options.routeCache, () =>\n dispatchServerActionRequestWithoutCacheContext(options),\n );\n\n return withRevalidationHeader(value, revalidatedPaths);\n}\n\nasync function dispatchServerActionRequestWithoutCacheContext(options: {\n appDir: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n request: Request;\n serverActionCacheVersion?: string | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n}): Promise<Response> {\n // Validate everything we can statically before touching the filesystem\n // / bundler. A flood of malformed POSTs must not pay the registry-load\n // cost (Issue 067).\n if (options.request.method !== \"POST\") {\n return jsonResponse({ ok: false, error: \"Method not allowed.\" }, 405);\n }\n\n const bodySizeResponse = validateServerActionBodySize(\n options.request,\n options.serverActions?.maxBodyBytes ?? DEFAULT_ACTION_BODY_MAX_BYTES,\n );\n if (bodySizeResponse !== undefined) {\n return bodySizeResponse;\n }\n\n const originResponse = validateServerActionRequestOrigin(options.request);\n if (originResponse !== undefined) {\n return originResponse;\n }\n\n const contentType = options.request.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n // JSON path delegates CSRF/replay to createServerActionHandler. The\n // registry is still needed here, but the handler short-circuits on\n // CSRF mismatch before invoking the action.\n let registry: ServerActionRegistry;\n try {\n registry = await loadServerActionRegistry({\n appDir: options.appDir,\n cacheVersion: options.serverActionCacheVersion,\n importPolicy: options.importPolicy,\n });\n } catch (error) {\n return jsonResponse(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n\n const replayStore = options.serverActions?.replayStore ?? usedFormActionNonces;\n warnIfUnrestrictedServerActions(options.serverActions?.allowedActions);\n const handle = createServerActionHandler(jsonServerActionRegistry({\n allowedActions: options.serverActions?.allowedActions,\n appDir: options.appDir,\n registry,\n }), {\n ...(options.serverActions?.authorize === undefined\n ? {}\n : { authorize: options.serverActions.authorize }),\n ...(options.serverActions?.allowedActions === undefined\n ? {}\n : { allowedActions: jsonAllowedServerActions(options.serverActions.allowedActions) }),\n csrf: true,\n maxBodyBytes: options.serverActions?.maxBodyBytes ?? DEFAULT_ACTION_BODY_MAX_BYTES,\n replayProtection: { seen: replayStore },\n });\n\n return handle(options.request);\n }\n\n if (\n !contentType.includes(\"application/x-www-form-urlencoded\") &&\n !contentType.includes(\"multipart/form-data\")\n ) {\n return jsonResponse({ ok: false, error: \"Unsupported server action content type.\" }, 415);\n }\n\n const formData = await options.request.formData();\n const csrfResponse = validateFormCsrf(options.request, formData);\n\n if (csrfResponse !== undefined) {\n return csrfResponse;\n }\n\n const moduleId = stringFormValue(formData.get(formFieldModuleId));\n const exportName = stringFormValue(formData.get(formFieldExportName));\n const nonce = stringFormValue(formData.get(formFieldNonce));\n\n if (moduleId === undefined || exportName === undefined || nonce === undefined) {\n return jsonResponse({ ok: false, error: \"Invalid server action reference.\" }, 400);\n }\n\n if (!isAllowedServerAction({ moduleId, exportName }, options.serverActions?.allowedActions)) {\n return jsonResponse({ ok: false, error: \"Unknown server action.\" }, 404);\n }\n\n if (\n isInferredServerActionReference({\n allowedActions: options.serverActions?.allowedActions,\n appDir: options.appDir,\n exportName,\n moduleId,\n }) &&\n !isValidFormActionToken({\n csrfToken: stringFormValue(formData.get(formCsrfFieldName)),\n exportName,\n moduleId,\n nonce,\n token: stringFormValue(formData.get(formFieldActionToken)),\n })\n ) {\n return jsonResponse({ ok: false, error: \"Unknown server action.\" }, 404);\n }\n\n const nonceResponse = validateFormNonce(\n formData,\n options.serverActions?.replayStore ?? usedFormActionNonces,\n );\n\n if (nonceResponse !== undefined) {\n return nonceResponse;\n }\n\n let registry: ServerActionRegistry;\n try {\n registry = await loadServerActionRegistry({\n appDir: options.appDir,\n cacheVersion: options.serverActionCacheVersion,\n importPolicy: options.importPolicy,\n });\n } catch (error) {\n return jsonResponse(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n\n const action = registry[`${moduleId}#${exportName}`];\n\n if (typeof action !== \"function\") {\n return jsonResponse({ ok: false, error: \"Unknown server action.\" }, 404);\n }\n\n const actionFormData = cleanActionFormData(formData);\n const authorizationResponse = await authorizeFormAction({\n args: [actionFormData],\n authorize: options.serverActions?.authorize,\n exportName,\n moduleId,\n request: options.request,\n });\n\n if (authorizationResponse !== undefined) {\n return authorizationResponse;\n }\n\n try {\n const value = await action(actionFormData);\n\n if (value instanceof Response) {\n return value;\n }\n\n if (value === undefined || value === null) {\n return redirectToFormReferer(options.request);\n }\n\n return jsonResponse({ ok: true, value }, 200);\n } catch (error) {\n return jsonResponse(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n}\n\nfunction validateServerActionBodySize(\n request: Request,\n maxBodyBytes: number,\n): Response | undefined {\n if (!Number.isFinite(maxBodyBytes) || maxBodyBytes < 0) {\n return undefined;\n }\n\n const contentLength = request.headers.get(\"content-length\");\n if (contentLength === null) {\n return undefined;\n }\n\n const bytes = Number(contentLength);\n if (!Number.isFinite(bytes) || bytes < 0) {\n return jsonResponse({ ok: false, error: \"Invalid Content-Length header.\" }, 400);\n }\n\n if (bytes > maxBodyBytes) {\n return jsonResponse({ ok: false, error: \"Server action request body is too large.\" }, 413);\n }\n\n return undefined;\n}\n\nfunction redirectToFormReferer(request: Request): Response {\n return new Response(null, {\n status: 303,\n headers: {\n location: sameOriginRefererPath(request) ?? \"/\",\n },\n });\n}\n\nfunction sameOriginRefererPath(request: Request): string | undefined {\n const referer = request.headers.get(\"referer\");\n\n if (referer === null) {\n return undefined;\n }\n\n try {\n const requestUrl = new URL(request.url);\n const refererUrl = new URL(referer, requestUrl);\n\n return refererUrl.origin === requestUrl.origin\n ? `${refererUrl.pathname}${refererUrl.search}`\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction withRevalidationHeader(response: Response, paths: string[]): Response {\n if (paths.length > 0) {\n response.headers.set(\"x-mreact-revalidate\", paths.join(\",\"));\n }\n\n return response;\n}\n\nasync function authorizeFormAction(options: {\n args: unknown[];\n authorize?: ServerActionHandlerOptions[\"authorize\"];\n exportName: string;\n moduleId: string;\n request: Request;\n}): Promise<Response | undefined> {\n const reference: ServerActionRequestReference = {\n exportName: options.exportName,\n moduleId: options.moduleId,\n };\n const authorizationResult = await options.authorize?.(options.request, reference, options.args);\n\n return authorizationResult !== undefined && authorizationResult !== true\n ? jsonResponse(\n {\n ok: false,\n error: authorizationError(authorizationResult),\n },\n 403,\n )\n : undefined;\n}\n\nfunction authorizationError(result: Exclude<ServerActionValidationResult, true>): string {\n return typeof result === \"string\" ? result : \"Server action not authorized.\";\n}\n\nfunction jsonAllowedServerActions(\n allowedActions: readonly AppRouterAllowedServerAction[],\n): ServerActionRequestReference[] {\n return allowedActions\n .filter((reference) => reference.inferred !== true)\n .map((reference) => ({\n exportName: reference.exportName,\n moduleId: reference.moduleId,\n }));\n}\n\nfunction jsonServerActionRegistry(options: {\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined;\n appDir: string;\n registry: ServerActionRegistry;\n}): ServerActionRegistry {\n const inferredKeys = new Set<string>();\n\n for (const reference of inferredServerActionReferencesForApp(options.appDir).values()) {\n inferredKeys.add(serverActionKey(reference));\n }\n\n for (const reference of options.allowedActions ?? []) {\n if (reference.inferred === true) {\n inferredKeys.add(serverActionKey(reference));\n }\n }\n\n if (inferredKeys.size === 0) {\n return options.registry;\n }\n\n const registry: ServerActionRegistry = {};\n\n for (const [key, value] of Object.entries(options.registry)) {\n if (!inferredKeys.has(key)) {\n registry[key] = value;\n }\n }\n\n return registry;\n}\n\nfunction serverActionKey(reference: ServerActionRequestReference): string {\n return `${reference.moduleId}#${reference.exportName}`;\n}\n\nfunction isAllowedServerAction(\n reference: ServerActionRequestReference,\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined,\n): boolean {\n if (allowedActions === undefined) {\n warnIfUnrestrictedServerActions(allowedActions);\n return true;\n }\n\n return allowedActions.some(\n (allowed) =>\n allowed.moduleId === reference.moduleId && allowed.exportName === reference.exportName,\n );\n}\n\nfunction warnIfUnrestrictedServerActions(\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined,\n): void {\n if (\n allowedActions !== undefined ||\n !isProductionEnvironment() ||\n warnedUnrestrictedServerActions\n ) {\n return;\n }\n\n warnedUnrestrictedServerActions = true;\n console.warn(\n \"[mreact] Server actions are running without an allowedActions manifest. Built app-router deployments generate this manifest automatically; direct production integrations should pass serverActions.allowedActions.\",\n );\n}\n\nfunction lowerFormActions(options: {\n actionNonce: string;\n code: string;\n csrfToken: string;\n references: Map<string, ActionReference>;\n}): string {\n let code = options.code;\n const formReferences = collectFormActionExpressionReferences({ code: options.code });\n\n for (const formReference of [...formReferences].reverse()) {\n const reference = options.references.get(formActionOccurrenceKey(formReference));\n\n if (reference === undefined) {\n continue;\n }\n\n const opening = code.slice(formReference.start, formReference.end);\n const loweredOpening = lowerFormActionOpening({\n actionNonce: options.actionNonce,\n csrfToken: options.csrfToken,\n opening,\n reference,\n referenceName: formReference.expression,\n });\n\n if (loweredOpening === opening) {\n continue;\n }\n\n code = `${code.slice(0, formReference.start)}${loweredOpening}${code.slice(formReference.end)}`;\n }\n\n return code;\n}\n\nfunction formActionOccurrenceKey(reference: {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n start: number;\n}): string {\n return [\n reference.start,\n reference.end,\n reference.expressionStart,\n reference.expressionEnd,\n reference.expression,\n ].join(\":\");\n}\n\nfunction formActionSourceHash(code: string): string {\n return createHash(\"sha256\").update(code).digest(\"base64url\");\n}\n\nfunction lowerFormActionOpening(options: {\n actionNonce: string;\n csrfToken: string;\n opening: string;\n reference: ActionReference;\n referenceName: string;\n}): string {\n const actionPattern = new RegExp(\n `^(?<prefix><form\\\\b[\\\\s\\\\S]*?)\\\\saction=\\\\{${escapeRegExp(options.referenceName)}\\\\}(?<suffix>[\\\\s\\\\S]*?)>$`,\n \"u\",\n );\n const match = options.opening.match(actionPattern);\n const prefix = match?.groups?.prefix;\n const suffix = match?.groups?.suffix;\n\n if (prefix === undefined || suffix === undefined) {\n return options.opening;\n }\n\n const attrs = `${prefix.slice(\"<form\".length)}${suffix}`.replace(\n /\\s+method=(?:\"[^\"]*\"|'[^']*'|\\{[^}]*\\})/g,\n \"\",\n );\n const hidden = [\n hiddenInput(formFieldModuleId, options.reference.moduleId),\n hiddenInput(formFieldExportName, options.reference.exportName),\n hiddenInput(formCsrfFieldName, options.csrfToken),\n hiddenInput(formFieldNonce, options.actionNonce),\n hiddenInput(\n formFieldActionToken,\n formActionToken({\n csrfToken: options.csrfToken,\n exportName: options.reference.exportName,\n moduleId: options.reference.moduleId,\n nonce: options.actionNonce,\n }),\n ),\n ].join(\"\");\n\n return `<form${attrs} method=\"post\" action=\"/_mreact/actions\">${hidden}`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction hiddenInput(name: string, value: string): string {\n return `<input type=\"hidden\" name=\"${escapeAttribute(name)}\" value=\"${escapeAttribute(value)}\" />`;\n}\n\nasync function collectImportedServerActions(options: {\n appDir: string;\n code: string;\n pageFile: string;\n}): Promise<{\n diagnostics: ServerActionInferenceDiagnostic[];\n references: Map<string, ActionReference>;\n}> {\n return await collectRuntimeInferredServerActions({\n appDir: options.appDir,\n code: options.code,\n fileSystem: {\n isUseServerFile,\n resolveSourceFile,\n },\n pageFile: options.pageFile,\n });\n}\n\nfunction isInferredServerActionReference(options: {\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined;\n appDir: string;\n exportName: string;\n moduleId: string;\n}): boolean {\n if (\n options.allowedActions?.some(\n (allowed) =>\n allowed.inferred === true &&\n allowed.moduleId === options.moduleId &&\n allowed.exportName === options.exportName,\n ) === true\n ) {\n return true;\n }\n\n return inferredServerActionReferencesForApp(options.appDir).has(\n `${options.moduleId}#${options.exportName}`,\n );\n}\n\nfunction formActionToken(options: {\n csrfToken: string;\n exportName: string;\n moduleId: string;\n nonce: string;\n}): string {\n return createHmac(\"sha256\", actionTokenSecret)\n .update(options.moduleId)\n .update(\"\\0\")\n .update(options.exportName)\n .update(\"\\0\")\n .update(options.csrfToken)\n .update(\"\\0\")\n .update(options.nonce)\n .digest(\"base64url\");\n}\n\nfunction isValidFormActionToken(options: {\n csrfToken: string | undefined;\n exportName: string;\n moduleId: string;\n nonce: string;\n token: string | undefined;\n}): boolean {\n if (options.csrfToken === undefined || options.token === undefined) {\n return false;\n }\n\n const expected = Buffer.from(\n formActionToken({\n csrfToken: options.csrfToken,\n exportName: options.exportName,\n moduleId: options.moduleId,\n nonce: options.nonce,\n }),\n );\n const actual = Buffer.from(options.token);\n\n return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n\nfunction replaceInferredServerActionReferences(\n appDir: string,\n pageFile: string,\n references: ReadonlyMap<string, ActionReference>,\n): void {\n const nextReferences = new Map(\n Array.from(references.values())\n .filter((reference) => reference.inferred)\n .map((reference) => [`${reference.moduleId}#${reference.exportName}`, reference]),\n );\n let appReferencesByPage = inferredServerActionReferences.get(appDir);\n const previousReferences = appReferencesByPage?.get(pageFile) ?? new Map();\n const changed = !sameActionReferenceKeys(previousReferences, nextReferences);\n\n if (!changed) {\n return;\n }\n\n if (nextReferences.size === 0) {\n appReferencesByPage?.delete(pageFile);\n if (appReferencesByPage?.size === 0) {\n inferredServerActionReferences.delete(appDir);\n }\n } else {\n if (appReferencesByPage === undefined) {\n appReferencesByPage = new Map();\n inferredServerActionReferences.set(appDir, appReferencesByPage);\n }\n appReferencesByPage.set(pageFile, nextReferences);\n }\n\n clearServerActionRegistryCacheForApp(appDir);\n}\n\n// Cache the (expensive) collect+bundle+evaluate work keyed by appDir +\n// caller-supplied version. Production callers pass the build-time hash\n// (serverModuleCacheVersion) so the registry is reused for the lifetime\n// of one deployment. Dev callers omit the version; the entry is then\n// keyed on \"dev\" so the work happens once per process — restarts handle\n// invalidation. Concurrent callers share a single in-flight promise.\nconst serverActionRegistryCache = new Map<string, Promise<ServerActionRegistry>>();\n\nasync function loadServerActionRegistry(options: {\n appDir: string;\n cacheVersion?: string | undefined;\n importPolicy?: AppRouterImportPolicy | undefined;\n}): Promise<ServerActionRegistry> {\n const cacheKey = `${options.appDir}::${options.cacheVersion ?? \"dev\"}`;\n const cached = serverActionRegistryCache.get(cacheKey);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const pending = buildServerActionRegistry(options).catch((error) => {\n // Drop the failed promise so a retry can re-run the load.\n serverActionRegistryCache.delete(cacheKey);\n throw error;\n });\n serverActionRegistryCache.set(cacheKey, pending);\n return pending;\n}\n\nasync function buildServerActionRegistry(options: {\n appDir: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n}): Promise<ServerActionRegistry> {\n const files = await collectFiles(options.appDir);\n const registry: ServerActionRegistry = {};\n const inferredReferences = inferredServerActionReferencesForApp(options.appDir);\n\n for (const file of files) {\n const moduleId = moduleIdForFile(options.appDir, file);\n const inferredExportNames = inferredExportNamesForModule(inferredReferences, moduleId);\n const useServerFile = await isUseServerFile(file);\n\n if (!useServerFile && inferredExportNames.size === 0) {\n continue;\n }\n\n const module = await importServerActionModule({\n appDir: options.appDir,\n file,\n importPolicy: options.importPolicy,\n });\n\n for (const [exportName, value] of Object.entries(module)) {\n if (typeof value === \"function\" && (useServerFile || inferredExportNames.has(exportName))) {\n registry[`${moduleId}#${exportName}`] = value as (...args: unknown[]) => unknown;\n }\n }\n }\n\n return registry;\n}\n\n// Exposed for tests that need a clean slate between cases (in-process state).\nexport function __clearServerActionRegistryCache(): void {\n serverActionRegistryCache.clear();\n inferredServerActionReferences.clear();\n}\n\nfunction clearServerActionRegistryCacheForApp(appDir: string): void {\n const prefix = `${appDir}::`;\n\n for (const key of serverActionRegistryCache.keys()) {\n if (key.startsWith(prefix)) {\n serverActionRegistryCache.delete(key);\n }\n }\n}\n\nfunction sameActionReferenceKeys(\n left: ReadonlyMap<string, ActionReference>,\n right: ReadonlyMap<string, ActionReference>,\n): boolean {\n if (left.size !== right.size) {\n return false;\n }\n\n for (const key of left.keys()) {\n if (!right.has(key)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction inferredServerActionReferencesForApp(appDir: string): Map<string, ActionReference> {\n const references = new Map<string, ActionReference>();\n const appReferencesByPage = inferredServerActionReferences.get(appDir);\n\n if (appReferencesByPage === undefined) {\n return references;\n }\n\n for (const pageReferences of appReferencesByPage.values()) {\n for (const [key, reference] of pageReferences) {\n references.set(key, reference);\n }\n }\n\n return references;\n}\n\nfunction inferredExportNamesForModule(\n references: ReadonlyMap<string, ActionReference>,\n moduleId: string,\n): Set<string> {\n const names = new Set<string>();\n\n for (const reference of references.values()) {\n if (reference.moduleId === moduleId) {\n names.add(reference.exportName);\n }\n }\n\n return names;\n}\n\nasync function importServerActionModule(options: {\n appDir: string;\n file: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n}): Promise<Record<string, unknown>> {\n const bundled = await bundleRouterModule({\n code: `export * from ${JSON.stringify(options.file)};`,\n filename: options.file,\n platform: \"node\",\n plugins: [\n fileImportMetaUrlPlugin(),\n serverActionRuntimePlugin(),\n createAppRouterImportPolicyPlugin({\n appDir: options.appDir,\n importPolicy: options.importPolicy,\n label: \"Server action\",\n }),\n ],\n });\n const code = bundled.code;\n\n if (code === undefined) {\n throw new Error(`Failed to compile server action module ${options.file}.`);\n }\n\n return importAppRouterSourceModule<Record<string, unknown>>({\n code,\n label: `server-action:${options.file}`,\n });\n}\n\nfunction serverActionRuntimePlugin() {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const cachePath = join(currentDir, currentDir.endsWith(`${sep}dist`) ? \"cache.js\" : \"cache.ts\");\n\n return {\n name: \"mreact-router-server-action-runtime\",\n setup(buildApi: RouterCompatBuildApi) {\n buildApi.onResolve({ filter: /^@reckona\\/mreact-router$/ }, () => ({\n namespace: \"mreact-router-server-api\",\n path: \"index\",\n }));\n buildApi.onLoad({ filter: /^index$/, namespace: \"mreact-router-server-api\" }, () => ({\n contents: `export { revalidatePath } from ${JSON.stringify(cachePath)};`,\n loader: \"ts\",\n resolveDir: dirname(cachePath),\n }));\n },\n };\n}\n\nasync function collectFiles(directory: string): Promise<string[]> {\n const entries = await readdir(directory, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const path = join(directory, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...(await collectFiles(path)));\n continue;\n }\n\n if (entry.isFile() && /\\.(?:mreact\\.tsx|tsx|ts)$/.test(entry.name)) {\n files.push(path);\n }\n }\n\n return files;\n}\n\nasync function resolveSourceFile(directory: string, source: string): Promise<string | undefined> {\n const base = join(directory, source);\n const tsEsmBase = /\\.[cm]?js$/.test(base) ? base.replace(/\\.[cm]?js$/, \"\") : undefined;\n const candidates = [\n base,\n ...(tsEsmBase === undefined\n ? []\n : [\n `${tsEsmBase}.ts`,\n `${tsEsmBase}.tsx`,\n `${tsEsmBase}.mreact.tsx`,\n join(tsEsmBase, \"index.ts\"),\n join(tsEsmBase, \"index.tsx\"),\n ]),\n `${base}.ts`,\n `${base}.tsx`,\n `${base}.mreact.tsx`,\n join(base, \"index.ts\"),\n join(base, \"index.tsx\"),\n ];\n\n for (const candidate of candidates) {\n try {\n await access(candidate);\n return candidate;\n } catch {\n // Try the next candidate.\n }\n }\n\n return undefined;\n}\n\nasync function isUseServerFile(file: string): Promise<boolean> {\n const code = await readFile(file, \"utf8\");\n\n return hasModuleDirective({ code, directive: \"use server\", filename: file });\n}\n\nfunction moduleIdForFile(appDir: string, file: string): string {\n return relative(appDir, file).split(sep).join(\"/\");\n}\n\nfunction validateServerActionRequestOrigin(request: Request): Response | undefined {\n if (!isProductionEnvironment()) {\n return undefined;\n }\n\n const expectedOrigin = new URL(request.url).origin;\n const origin = request.headers.get(\"origin\");\n\n if (origin !== null) {\n return origin === expectedOrigin\n ? undefined\n : jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n }\n\n const referer = request.headers.get(\"referer\");\n\n if (referer === null) {\n return jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n }\n\n try {\n return new URL(referer).origin === expectedOrigin\n ? undefined\n : jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n } catch {\n return jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n }\n}\n\nfunction validateFormNonce(\n formData: FormData,\n replayStore: ServerActionReplayStore,\n): Response | undefined {\n const nonce = stringFormValue(formData.get(formFieldNonce));\n\n if (nonce === undefined || nonce.length === 0) {\n return jsonResponse({ ok: false, error: \"Missing server action nonce.\" }, 400);\n }\n\n if (replayStore.has(nonce)) {\n return jsonResponse({ ok: false, error: \"Server action nonce was already used.\" }, 409);\n }\n\n replayStore.add(nonce);\n return undefined;\n}\n\nfunction cleanActionFormData(formData: FormData): FormData {\n const cleaned = new FormData();\n\n for (const [name, value] of formData.entries()) {\n if (\n name !== formFieldModuleId &&\n name !== formFieldExportName &&\n name !== formCsrfFieldName &&\n name !== formFieldNonce &&\n name !== formFieldActionToken\n ) {\n cleaned.append(name, value);\n }\n }\n\n return cleaned;\n}\n\nfunction stringFormValue(value: FormDataEntryValue | null): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction jsonResponse(payload: unknown, status: number): Response {\n return new Response(JSON.stringify(payload), {\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n status,\n });\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll('\"', \""\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { access, readdir, readFile } from \"node:fs/promises\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n collectFormActionExpressionReferences,\n hasModuleDirective,\n} from \"@reckona/mreact-compiler\";\nimport {\n createServerActionHandler,\n type ServerActionHandlerOptions,\n type ServerActionRegistry,\n type ServerActionReplayStore,\n type ServerActionRequestReference,\n type ServerActionValidationResult,\n} from \"@reckona/mreact-server\";\nimport { bundleRouterModule, type RouterCompatBuildApi } from \"./bundle-pipeline.js\";\nimport { type AppRouterCache, withRouteCacheContext } from \"./cache.js\";\nimport { fileImportMetaUrlPlugin, importAppRouterSourceModule } from \"./module-runner.js\";\nimport { createAppRouterImportPolicyPlugin, type AppRouterImportPolicy } from \"./import-policy.js\";\nimport { cookies, type RequestCookies } from \"./navigation.js\";\nexport {\n createFormCsrfToken,\n formCsrfCookie,\n formCsrfFieldName,\n serverActionCookie,\n validateFormCsrf,\n} from \"./csrf.js\";\nimport {\n formCsrfFieldName,\n readExistingFormCsrfToken,\n validateFormCsrf,\n} from \"./csrf.js\";\nimport {\n collectRuntimeInferredServerActions,\n type ServerActionInferenceDiagnostic,\n} from \"./server-action-inference.js\";\n\nfunction isProductionEnvironment(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\nconst formFieldModuleId = \"__mreact_module_id\";\nconst formFieldExportName = \"__mreact_export_name\";\nconst formFieldNonce = \"__mreact_action_nonce\";\nconst formFieldActionToken = \"__mreact_action_token\";\nconst actionTokenSecret = process.env.MREACT_SERVER_ACTION_SECRET ?? defaultActionTokenSecret();\n// Bounded default replay store for form-action nonces. The previous\n// implementation was an unbounded Set that grew with every successful\n// submission (Issue 069). Production callers should still pass a shared\n// store (Redis / KV) via `serverActions.replayStore` for multi-instance\n// deployments -- this default only guarantees replay protection within\n// a single process and is the safe fallback for dev / single-node setups.\n//\n// Retention model:\n// - TTL: 10 minutes. Form nonces are minted at SSR time and the user\n// has to submit before the cookie's SameSite=Lax window anyway; this\n// is generous for any realistic submit cadence.\n// - Max size: 50_000 entries. Old entries are evicted FIFO once the cap\n// is reached so a flood cannot trigger OOM.\n//\n// Both bounds are intentional defaults -- tight enough that a single\n// process cannot leak unbounded RSS, loose enough that legitimate\n// traffic does not trip false-positive 409s.\nconst DEFAULT_REPLAY_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_REPLAY_MAX_ENTRIES = 50_000;\nconst DEFAULT_ACTION_BODY_MAX_BYTES = 10 * 1024 * 1024;\nlet warnedUnrestrictedServerActions = false;\n\nexport interface ServerActionContext {\n clientIp?: string | undefined;\n cookies: RequestCookies;\n headers: Headers;\n request: Request;\n}\n\nfunction defaultActionTokenSecret(): string {\n if (isProductionEnvironment()) {\n console.warn(\n \"mreact-router: MREACT_SERVER_ACTION_SECRET is not set. Inferred server action tokens use a per-process secret and may fail across multiple production instances.\",\n );\n }\n\n return randomBytes(32).toString(\"base64url\");\n}\n\nclass BoundedReplayStore {\n private readonly entries = new Map<string, number>();\n\n constructor(\n private readonly ttlMs: number,\n private readonly maxEntries: number,\n ) {}\n\n has(value: string): boolean {\n const expiresAt = this.entries.get(value);\n if (expiresAt === undefined) return false;\n if (expiresAt < Date.now()) {\n this.entries.delete(value);\n return false;\n }\n return true;\n }\n\n add(value: string): void {\n const now = Date.now();\n // Cheap opportunistic sweep: drop the oldest expired entries first,\n // then enforce the hard cap with FIFO eviction.\n if (this.entries.size >= this.maxEntries) {\n for (const [key, expiresAt] of this.entries) {\n if (expiresAt < now) {\n this.entries.delete(key);\n }\n if (this.entries.size < this.maxEntries) break;\n }\n while (this.entries.size >= this.maxEntries) {\n const oldest = this.entries.keys().next().value;\n if (oldest === undefined) break;\n this.entries.delete(oldest);\n }\n }\n this.entries.set(value, now + this.ttlMs);\n }\n\n // Exposed for tests; not part of the ServerActionReplayStore interface.\n size(): number {\n return this.entries.size;\n }\n}\n\nconst usedFormActionNonces = new BoundedReplayStore(\n DEFAULT_REPLAY_TTL_MS,\n DEFAULT_REPLAY_MAX_ENTRIES,\n);\n\n// Test helpers: drop all entries between cases / expose the bounded store\n// so tests can drive its eviction semantics directly. Not part of the\n// public surface (prefixed with `__`).\nexport function __clearDefaultReplayStore(): void {\n (usedFormActionNonces as unknown as { entries: Map<string, number> }).entries.clear();\n}\n\nexport function __readDefaultReplayStore(): BoundedReplayStore {\n return usedFormActionNonces;\n}\n\nexport interface AppRouterServerActionOptions {\n allowedActions?: readonly AppRouterAllowedServerAction[] | undefined;\n authorize?: ServerActionHandlerOptions[\"authorize\"] | undefined;\n maxBodyBytes?: number | undefined;\n replayStore?: ServerActionReplayStore | undefined;\n}\n\nexport interface AppRouterAllowedServerAction extends ServerActionRequestReference {\n inferred?: boolean | undefined;\n}\n\nexport interface PreparedRouteActions {\n actionNonce?: string;\n code: string;\n csrfToken?: string;\n diagnostics?: ServerActionInferenceDiagnostic[] | undefined;\n // True when the cookie should be (re)set on the response. False means\n // the incoming request already carried a valid CSRF cookie that the\n // render is reusing -- skipping Set-Cookie avoids cookie thrash across\n // concurrent tabs (Issue 070).\n csrfTokenIsNew?: boolean;\n hasFormActions: boolean;\n}\n\ninterface ActionReference {\n exportName: string;\n inferred: boolean;\n moduleId: string;\n}\n\nexport interface PreparedFormActionReference {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n exportName: string;\n inferred: boolean;\n moduleId: string;\n sourceHash: string;\n start: number;\n}\n\nconst inferredServerActionReferences = new Map<string, Map<string, Map<string, ActionReference>>>();\n\nexport async function prepareRouteServerActions(options: {\n appDir: string;\n code: string;\n formActionReferences?: readonly PreparedFormActionReference[] | undefined;\n pageFile: string;\n request?: Request | undefined;\n}): Promise<PreparedRouteActions> {\n if (options.formActionReferences !== undefined && options.formActionReferences.length === 0) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return { code: options.code, hasFormActions: false };\n }\n\n if (!hasFormActionCandidate(options.code, options.pageFile)) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return { code: options.code, hasFormActions: false };\n }\n\n const inference =\n options.formActionReferences === undefined\n ? await collectImportedServerActions(options)\n : {\n diagnostics: [],\n references: formActionReferenceMap(options.code, options.formActionReferences),\n };\n const { diagnostics, references } = inference;\n\n if (references.size === 0) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return diagnostics.length === 0\n ? { code: options.code, hasFormActions: false }\n : { code: options.code, diagnostics, hasFormActions: false };\n }\n\n // Reuse the existing CSRF token when the browser already sent one.\n // Rotating the cookie on every render (Issue 070) broke concurrent\n // forms because the older tab's hidden input no longer matched the\n // cookie value. The actionNonce stays per-render -- that is the field\n // tied to a specific submission via replay protection.\n const existingToken = readExistingFormCsrfToken(options.request);\n const csrfToken = existingToken ?? randomUUID();\n const csrfTokenIsNew = existingToken === undefined;\n const actionNonce = randomUUID();\n const lowered = lowerFormActions({\n actionNonce,\n code: options.code,\n csrfToken,\n references,\n });\n\n if (lowered === options.code) {\n replaceInferredServerActionReferences(options.appDir, options.pageFile, new Map());\n return diagnostics.length === 0\n ? { code: options.code, hasFormActions: false }\n : { code: options.code, diagnostics, hasFormActions: false };\n }\n\n replaceInferredServerActionReferences(options.appDir, options.pageFile, references);\n\n return {\n actionNonce,\n code: lowered,\n csrfToken,\n csrfTokenIsNew,\n diagnostics,\n hasFormActions: true,\n };\n}\n\nfunction formActionReferenceMap(\n code: string,\n references: readonly PreparedFormActionReference[],\n): Map<string, ActionReference> {\n const sourceHash = formActionSourceHash(code);\n\n return new Map(\n references\n .filter((reference) => reference.sourceHash === sourceHash)\n .map((reference) => [\n formActionOccurrenceKey(reference),\n {\n exportName: reference.exportName,\n inferred: reference.inferred,\n moduleId: reference.moduleId,\n },\n ]),\n );\n}\n\nfunction hasFormActionCandidate(code: string, filename: string): boolean {\n return collectFormActionExpressionReferences({ code, filename }).length > 0;\n}\n\nexport async function dispatchServerActionRequest(options: {\n appDir: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n request: Request;\n routeCache?: AppRouterCache | undefined;\n serverActionCacheVersion?: string | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n}): Promise<Response> {\n const { revalidatedPaths, value } = await withRouteCacheContext(options.routeCache, () =>\n dispatchServerActionRequestWithoutCacheContext(options),\n );\n\n return withRevalidationHeader(value, revalidatedPaths);\n}\n\nasync function dispatchServerActionRequestWithoutCacheContext(options: {\n appDir: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n request: Request;\n serverActionCacheVersion?: string | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n}): Promise<Response> {\n // Validate everything we can statically before touching the filesystem\n // / bundler. A flood of malformed POSTs must not pay the registry-load\n // cost (Issue 067).\n if (options.request.method !== \"POST\") {\n return jsonResponse({ ok: false, error: \"Method not allowed.\" }, 405);\n }\n\n const bodySizeResponse = validateServerActionBodySize(\n options.request,\n options.serverActions?.maxBodyBytes ?? DEFAULT_ACTION_BODY_MAX_BYTES,\n );\n if (bodySizeResponse !== undefined) {\n return bodySizeResponse;\n }\n\n const originResponse = validateServerActionRequestOrigin(options.request);\n if (originResponse !== undefined) {\n return originResponse;\n }\n\n const contentType = options.request.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n // JSON path delegates CSRF/replay to createServerActionHandler. The\n // registry is still needed here, but the handler short-circuits on\n // CSRF mismatch before invoking the action.\n let registry: ServerActionRegistry;\n try {\n registry = await loadServerActionRegistry({\n appDir: options.appDir,\n cacheVersion: options.serverActionCacheVersion,\n importPolicy: options.importPolicy,\n });\n } catch (error) {\n return jsonResponse(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n\n const replayStore = options.serverActions?.replayStore ?? usedFormActionNonces;\n warnIfUnrestrictedServerActions(options.serverActions?.allowedActions);\n const handle = createServerActionHandler(jsonServerActionRegistry({\n allowedActions: options.serverActions?.allowedActions,\n appDir: options.appDir,\n registry,\n }), {\n ...(options.serverActions?.authorize === undefined\n ? {}\n : { authorize: options.serverActions.authorize }),\n ...(options.serverActions?.allowedActions === undefined\n ? {}\n : { allowedActions: jsonAllowedServerActions(options.serverActions.allowedActions) }),\n csrf: true,\n maxBodyBytes: options.serverActions?.maxBodyBytes ?? DEFAULT_ACTION_BODY_MAX_BYTES,\n replayProtection: { seen: replayStore },\n });\n\n return handle(options.request);\n }\n\n if (\n !contentType.includes(\"application/x-www-form-urlencoded\") &&\n !contentType.includes(\"multipart/form-data\")\n ) {\n return jsonResponse({ ok: false, error: \"Unsupported server action content type.\" }, 415);\n }\n\n const formData = await options.request.formData();\n const csrfResponse = validateFormCsrf(options.request, formData);\n\n if (csrfResponse !== undefined) {\n return csrfResponse;\n }\n\n const moduleId = stringFormValue(formData.get(formFieldModuleId));\n const exportName = stringFormValue(formData.get(formFieldExportName));\n const nonce = stringFormValue(formData.get(formFieldNonce));\n\n if (moduleId === undefined || exportName === undefined || nonce === undefined) {\n return jsonResponse({ ok: false, error: \"Invalid server action reference.\" }, 400);\n }\n\n if (!isAllowedServerAction({ moduleId, exportName }, options.serverActions?.allowedActions)) {\n return jsonResponse({ ok: false, error: \"Unknown server action.\" }, 404);\n }\n\n if (\n isInferredServerActionReference({\n allowedActions: options.serverActions?.allowedActions,\n appDir: options.appDir,\n exportName,\n moduleId,\n }) &&\n !isValidFormActionToken({\n csrfToken: stringFormValue(formData.get(formCsrfFieldName)),\n exportName,\n moduleId,\n nonce,\n token: stringFormValue(formData.get(formFieldActionToken)),\n })\n ) {\n return jsonResponse({ ok: false, error: \"Unknown server action.\" }, 404);\n }\n\n const nonceResponse = validateFormNonce(\n formData,\n options.serverActions?.replayStore ?? usedFormActionNonces,\n );\n\n if (nonceResponse !== undefined) {\n return nonceResponse;\n }\n\n let registry: ServerActionRegistry;\n try {\n registry = await loadServerActionRegistry({\n appDir: options.appDir,\n cacheVersion: options.serverActionCacheVersion,\n importPolicy: options.importPolicy,\n });\n } catch (error) {\n return jsonResponse(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n\n const action = registry[`${moduleId}#${exportName}`];\n\n if (typeof action !== \"function\") {\n return jsonResponse({ ok: false, error: \"Unknown server action.\" }, 404);\n }\n\n const actionFormData = cleanActionFormData(formData);\n const authorizationResponse = await authorizeFormAction({\n args: [actionFormData],\n authorize: options.serverActions?.authorize,\n exportName,\n moduleId,\n request: options.request,\n });\n\n if (authorizationResponse !== undefined) {\n return authorizationResponse;\n }\n\n try {\n const value = await action(actionFormData, createServerActionContext(options.request));\n\n if (value instanceof Response) {\n return value;\n }\n\n if (value === undefined || value === null) {\n return redirectToFormReferer(options.request);\n }\n\n return jsonResponse({ ok: true, value }, 200);\n } catch (error) {\n return jsonResponse(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n}\n\nfunction createServerActionContext(request: Request): ServerActionContext {\n const clientIp = clientIpFromRequest(request);\n\n return {\n ...(clientIp === undefined ? {} : { clientIp }),\n cookies: cookies(request),\n headers: request.headers,\n request,\n };\n}\n\nfunction clientIpFromRequest(request: Request): string | undefined {\n const forwarded = request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim();\n\n if (forwarded !== undefined && forwarded !== \"\") {\n return forwarded;\n }\n\n const realIp = request.headers.get(\"x-real-ip\")?.trim();\n return realIp === \"\" ? undefined : realIp;\n}\n\nfunction validateServerActionBodySize(\n request: Request,\n maxBodyBytes: number,\n): Response | undefined {\n if (!Number.isFinite(maxBodyBytes) || maxBodyBytes < 0) {\n return undefined;\n }\n\n const contentLength = request.headers.get(\"content-length\");\n if (contentLength === null) {\n return undefined;\n }\n\n const bytes = Number(contentLength);\n if (!Number.isFinite(bytes) || bytes < 0) {\n return jsonResponse({ ok: false, error: \"Invalid Content-Length header.\" }, 400);\n }\n\n if (bytes > maxBodyBytes) {\n return jsonResponse({ ok: false, error: \"Server action request body is too large.\" }, 413);\n }\n\n return undefined;\n}\n\nfunction redirectToFormReferer(request: Request): Response {\n return new Response(null, {\n status: 303,\n headers: {\n location: sameOriginRefererPath(request) ?? \"/\",\n },\n });\n}\n\nfunction sameOriginRefererPath(request: Request): string | undefined {\n const referer = request.headers.get(\"referer\");\n\n if (referer === null) {\n return undefined;\n }\n\n try {\n const requestUrl = new URL(request.url);\n const refererUrl = new URL(referer, requestUrl);\n\n return refererUrl.origin === requestUrl.origin\n ? `${refererUrl.pathname}${refererUrl.search}`\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction withRevalidationHeader(response: Response, paths: string[]): Response {\n if (paths.length > 0) {\n response.headers.set(\"x-mreact-revalidate\", paths.join(\",\"));\n }\n\n return response;\n}\n\nasync function authorizeFormAction(options: {\n args: unknown[];\n authorize?: ServerActionHandlerOptions[\"authorize\"];\n exportName: string;\n moduleId: string;\n request: Request;\n}): Promise<Response | undefined> {\n const reference: ServerActionRequestReference = {\n exportName: options.exportName,\n moduleId: options.moduleId,\n };\n const authorizationResult = await options.authorize?.(options.request, reference, options.args);\n\n return authorizationResult !== undefined && authorizationResult !== true\n ? jsonResponse(\n {\n ok: false,\n error: authorizationError(authorizationResult),\n },\n 403,\n )\n : undefined;\n}\n\nfunction authorizationError(result: Exclude<ServerActionValidationResult, true>): string {\n return typeof result === \"string\" ? result : \"Server action not authorized.\";\n}\n\nfunction jsonAllowedServerActions(\n allowedActions: readonly AppRouterAllowedServerAction[],\n): ServerActionRequestReference[] {\n return allowedActions\n .filter((reference) => reference.inferred !== true)\n .map((reference) => ({\n exportName: reference.exportName,\n moduleId: reference.moduleId,\n }));\n}\n\nfunction jsonServerActionRegistry(options: {\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined;\n appDir: string;\n registry: ServerActionRegistry;\n}): ServerActionRegistry {\n const inferredKeys = new Set<string>();\n\n for (const reference of inferredServerActionReferencesForApp(options.appDir).values()) {\n inferredKeys.add(serverActionKey(reference));\n }\n\n for (const reference of options.allowedActions ?? []) {\n if (reference.inferred === true) {\n inferredKeys.add(serverActionKey(reference));\n }\n }\n\n if (inferredKeys.size === 0) {\n return options.registry;\n }\n\n const registry: ServerActionRegistry = {};\n\n for (const [key, value] of Object.entries(options.registry)) {\n if (!inferredKeys.has(key)) {\n registry[key] = value;\n }\n }\n\n return registry;\n}\n\nfunction serverActionKey(reference: ServerActionRequestReference): string {\n return `${reference.moduleId}#${reference.exportName}`;\n}\n\nfunction isAllowedServerAction(\n reference: ServerActionRequestReference,\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined,\n): boolean {\n if (allowedActions === undefined) {\n warnIfUnrestrictedServerActions(allowedActions);\n return true;\n }\n\n return allowedActions.some(\n (allowed) =>\n allowed.moduleId === reference.moduleId && allowed.exportName === reference.exportName,\n );\n}\n\nfunction warnIfUnrestrictedServerActions(\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined,\n): void {\n if (\n allowedActions !== undefined ||\n !isProductionEnvironment() ||\n warnedUnrestrictedServerActions\n ) {\n return;\n }\n\n warnedUnrestrictedServerActions = true;\n console.warn(\n \"[mreact] Server actions are running without an allowedActions manifest. Built app-router deployments generate this manifest automatically; direct production integrations should pass serverActions.allowedActions.\",\n );\n}\n\nfunction lowerFormActions(options: {\n actionNonce: string;\n code: string;\n csrfToken: string;\n references: Map<string, ActionReference>;\n}): string {\n let code = options.code;\n const formReferences = collectFormActionExpressionReferences({ code: options.code });\n\n for (const formReference of [...formReferences].reverse()) {\n const reference = options.references.get(formActionOccurrenceKey(formReference));\n\n if (reference === undefined) {\n continue;\n }\n\n const opening = code.slice(formReference.start, formReference.end);\n const loweredOpening = lowerFormActionOpening({\n actionNonce: options.actionNonce,\n csrfToken: options.csrfToken,\n opening,\n reference,\n referenceName: formReference.expression,\n });\n\n if (loweredOpening === opening) {\n continue;\n }\n\n code = `${code.slice(0, formReference.start)}${loweredOpening}${code.slice(formReference.end)}`;\n }\n\n return code;\n}\n\nfunction formActionOccurrenceKey(reference: {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n start: number;\n}): string {\n return [\n reference.start,\n reference.end,\n reference.expressionStart,\n reference.expressionEnd,\n reference.expression,\n ].join(\":\");\n}\n\nfunction formActionSourceHash(code: string): string {\n return createHash(\"sha256\").update(code).digest(\"base64url\");\n}\n\nfunction lowerFormActionOpening(options: {\n actionNonce: string;\n csrfToken: string;\n opening: string;\n reference: ActionReference;\n referenceName: string;\n}): string {\n const actionPattern = new RegExp(\n `^(?<prefix><form\\\\b[\\\\s\\\\S]*?)\\\\saction=\\\\{${escapeRegExp(options.referenceName)}\\\\}(?<suffix>[\\\\s\\\\S]*?)>$`,\n \"u\",\n );\n const match = options.opening.match(actionPattern);\n const prefix = match?.groups?.prefix;\n const suffix = match?.groups?.suffix;\n\n if (prefix === undefined || suffix === undefined) {\n return options.opening;\n }\n\n const attrs = `${prefix.slice(\"<form\".length)}${suffix}`.replace(\n /\\s+method=(?:\"[^\"]*\"|'[^']*'|\\{[^}]*\\})/g,\n \"\",\n );\n const hidden = [\n hiddenInput(formFieldModuleId, options.reference.moduleId),\n hiddenInput(formFieldExportName, options.reference.exportName),\n hiddenInput(formCsrfFieldName, options.csrfToken),\n hiddenInput(formFieldNonce, options.actionNonce),\n hiddenInput(\n formFieldActionToken,\n formActionToken({\n csrfToken: options.csrfToken,\n exportName: options.reference.exportName,\n moduleId: options.reference.moduleId,\n nonce: options.actionNonce,\n }),\n ),\n ].join(\"\");\n\n return `<form${attrs} method=\"post\" action=\"/_mreact/actions\">${hidden}`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction hiddenInput(name: string, value: string): string {\n return `<input type=\"hidden\" name=\"${escapeAttribute(name)}\" value=\"${escapeAttribute(value)}\" />`;\n}\n\nasync function collectImportedServerActions(options: {\n appDir: string;\n code: string;\n pageFile: string;\n}): Promise<{\n diagnostics: ServerActionInferenceDiagnostic[];\n references: Map<string, ActionReference>;\n}> {\n return await collectRuntimeInferredServerActions({\n appDir: options.appDir,\n code: options.code,\n fileSystem: {\n isUseServerFile,\n resolveSourceFile,\n },\n pageFile: options.pageFile,\n });\n}\n\nfunction isInferredServerActionReference(options: {\n allowedActions: readonly AppRouterAllowedServerAction[] | undefined;\n appDir: string;\n exportName: string;\n moduleId: string;\n}): boolean {\n if (\n options.allowedActions?.some(\n (allowed) =>\n allowed.inferred === true &&\n allowed.moduleId === options.moduleId &&\n allowed.exportName === options.exportName,\n ) === true\n ) {\n return true;\n }\n\n return inferredServerActionReferencesForApp(options.appDir).has(\n `${options.moduleId}#${options.exportName}`,\n );\n}\n\nfunction formActionToken(options: {\n csrfToken: string;\n exportName: string;\n moduleId: string;\n nonce: string;\n}): string {\n return createHmac(\"sha256\", actionTokenSecret)\n .update(options.moduleId)\n .update(\"\\0\")\n .update(options.exportName)\n .update(\"\\0\")\n .update(options.csrfToken)\n .update(\"\\0\")\n .update(options.nonce)\n .digest(\"base64url\");\n}\n\nfunction isValidFormActionToken(options: {\n csrfToken: string | undefined;\n exportName: string;\n moduleId: string;\n nonce: string;\n token: string | undefined;\n}): boolean {\n if (options.csrfToken === undefined || options.token === undefined) {\n return false;\n }\n\n const expected = Buffer.from(\n formActionToken({\n csrfToken: options.csrfToken,\n exportName: options.exportName,\n moduleId: options.moduleId,\n nonce: options.nonce,\n }),\n );\n const actual = Buffer.from(options.token);\n\n return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n\nfunction replaceInferredServerActionReferences(\n appDir: string,\n pageFile: string,\n references: ReadonlyMap<string, ActionReference>,\n): void {\n const nextReferences = new Map(\n Array.from(references.values())\n .filter((reference) => reference.inferred)\n .map((reference) => [`${reference.moduleId}#${reference.exportName}`, reference]),\n );\n let appReferencesByPage = inferredServerActionReferences.get(appDir);\n const previousReferences = appReferencesByPage?.get(pageFile) ?? new Map();\n const changed = !sameActionReferenceKeys(previousReferences, nextReferences);\n\n if (!changed) {\n return;\n }\n\n if (nextReferences.size === 0) {\n appReferencesByPage?.delete(pageFile);\n if (appReferencesByPage?.size === 0) {\n inferredServerActionReferences.delete(appDir);\n }\n } else {\n if (appReferencesByPage === undefined) {\n appReferencesByPage = new Map();\n inferredServerActionReferences.set(appDir, appReferencesByPage);\n }\n appReferencesByPage.set(pageFile, nextReferences);\n }\n\n clearServerActionRegistryCacheForApp(appDir);\n}\n\n// Cache the (expensive) collect+bundle+evaluate work keyed by appDir +\n// caller-supplied version. Production callers pass the build-time hash\n// (serverModuleCacheVersion) so the registry is reused for the lifetime\n// of one deployment. Dev callers omit the version; the entry is then\n// keyed on \"dev\" so the work happens once per process — restarts handle\n// invalidation. Concurrent callers share a single in-flight promise.\nconst serverActionRegistryCache = new Map<string, Promise<ServerActionRegistry>>();\n\nasync function loadServerActionRegistry(options: {\n appDir: string;\n cacheVersion?: string | undefined;\n importPolicy?: AppRouterImportPolicy | undefined;\n}): Promise<ServerActionRegistry> {\n const cacheKey = `${options.appDir}::${options.cacheVersion ?? \"dev\"}`;\n const cached = serverActionRegistryCache.get(cacheKey);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const pending = buildServerActionRegistry(options).catch((error) => {\n // Drop the failed promise so a retry can re-run the load.\n serverActionRegistryCache.delete(cacheKey);\n throw error;\n });\n serverActionRegistryCache.set(cacheKey, pending);\n return pending;\n}\n\nasync function buildServerActionRegistry(options: {\n appDir: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n}): Promise<ServerActionRegistry> {\n const files = await collectFiles(options.appDir);\n const registry: ServerActionRegistry = {};\n const inferredReferences = inferredServerActionReferencesForApp(options.appDir);\n\n for (const file of files) {\n const moduleId = moduleIdForFile(options.appDir, file);\n const inferredExportNames = inferredExportNamesForModule(inferredReferences, moduleId);\n const useServerFile = await isUseServerFile(file);\n\n if (!useServerFile && inferredExportNames.size === 0) {\n continue;\n }\n\n const module = await importServerActionModule({\n appDir: options.appDir,\n file,\n importPolicy: options.importPolicy,\n });\n\n for (const [exportName, value] of Object.entries(module)) {\n if (typeof value === \"function\" && (useServerFile || inferredExportNames.has(exportName))) {\n registry[`${moduleId}#${exportName}`] = value as (...args: unknown[]) => unknown;\n }\n }\n }\n\n return registry;\n}\n\n// Exposed for tests that need a clean slate between cases (in-process state).\nexport function __clearServerActionRegistryCache(): void {\n serverActionRegistryCache.clear();\n inferredServerActionReferences.clear();\n}\n\nfunction clearServerActionRegistryCacheForApp(appDir: string): void {\n const prefix = `${appDir}::`;\n\n for (const key of serverActionRegistryCache.keys()) {\n if (key.startsWith(prefix)) {\n serverActionRegistryCache.delete(key);\n }\n }\n}\n\nfunction sameActionReferenceKeys(\n left: ReadonlyMap<string, ActionReference>,\n right: ReadonlyMap<string, ActionReference>,\n): boolean {\n if (left.size !== right.size) {\n return false;\n }\n\n for (const key of left.keys()) {\n if (!right.has(key)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction inferredServerActionReferencesForApp(appDir: string): Map<string, ActionReference> {\n const references = new Map<string, ActionReference>();\n const appReferencesByPage = inferredServerActionReferences.get(appDir);\n\n if (appReferencesByPage === undefined) {\n return references;\n }\n\n for (const pageReferences of appReferencesByPage.values()) {\n for (const [key, reference] of pageReferences) {\n references.set(key, reference);\n }\n }\n\n return references;\n}\n\nfunction inferredExportNamesForModule(\n references: ReadonlyMap<string, ActionReference>,\n moduleId: string,\n): Set<string> {\n const names = new Set<string>();\n\n for (const reference of references.values()) {\n if (reference.moduleId === moduleId) {\n names.add(reference.exportName);\n }\n }\n\n return names;\n}\n\nasync function importServerActionModule(options: {\n appDir: string;\n file: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n}): Promise<Record<string, unknown>> {\n const bundled = await bundleRouterModule({\n code: `export * from ${JSON.stringify(options.file)};`,\n filename: options.file,\n platform: \"node\",\n plugins: [\n fileImportMetaUrlPlugin(),\n serverActionRuntimePlugin(),\n createAppRouterImportPolicyPlugin({\n appDir: options.appDir,\n importPolicy: options.importPolicy,\n label: \"Server action\",\n }),\n ],\n });\n const code = bundled.code;\n\n if (code === undefined) {\n throw new Error(`Failed to compile server action module ${options.file}.`);\n }\n\n return importAppRouterSourceModule<Record<string, unknown>>({\n code,\n label: `server-action:${options.file}`,\n });\n}\n\nfunction serverActionRuntimePlugin() {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const cachePath = join(currentDir, currentDir.endsWith(`${sep}dist`) ? \"cache.js\" : \"cache.ts\");\n\n return {\n name: \"mreact-router-server-action-runtime\",\n setup(buildApi: RouterCompatBuildApi) {\n buildApi.onResolve({ filter: /^@reckona\\/mreact-router$/ }, () => ({\n namespace: \"mreact-router-server-api\",\n path: \"index\",\n }));\n buildApi.onLoad({ filter: /^index$/, namespace: \"mreact-router-server-api\" }, () => ({\n contents: `export { revalidatePath } from ${JSON.stringify(cachePath)};`,\n loader: \"ts\",\n resolveDir: dirname(cachePath),\n }));\n },\n };\n}\n\nasync function collectFiles(directory: string): Promise<string[]> {\n const entries = await readdir(directory, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const path = join(directory, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...(await collectFiles(path)));\n continue;\n }\n\n if (entry.isFile() && /\\.(?:mreact\\.tsx|tsx|ts)$/.test(entry.name)) {\n files.push(path);\n }\n }\n\n return files;\n}\n\nasync function resolveSourceFile(directory: string, source: string): Promise<string | undefined> {\n const base = join(directory, source);\n const tsEsmBase = /\\.[cm]?js$/.test(base) ? base.replace(/\\.[cm]?js$/, \"\") : undefined;\n const candidates = [\n base,\n ...(tsEsmBase === undefined\n ? []\n : [\n `${tsEsmBase}.ts`,\n `${tsEsmBase}.tsx`,\n `${tsEsmBase}.mreact.tsx`,\n join(tsEsmBase, \"index.ts\"),\n join(tsEsmBase, \"index.tsx\"),\n ]),\n `${base}.ts`,\n `${base}.tsx`,\n `${base}.mreact.tsx`,\n join(base, \"index.ts\"),\n join(base, \"index.tsx\"),\n ];\n\n for (const candidate of candidates) {\n try {\n await access(candidate);\n return candidate;\n } catch {\n // Try the next candidate.\n }\n }\n\n return undefined;\n}\n\nasync function isUseServerFile(file: string): Promise<boolean> {\n const code = await readFile(file, \"utf8\");\n\n return hasModuleDirective({ code, directive: \"use server\", filename: file });\n}\n\nfunction moduleIdForFile(appDir: string, file: string): string {\n return relative(appDir, file).split(sep).join(\"/\");\n}\n\nfunction validateServerActionRequestOrigin(request: Request): Response | undefined {\n if (!isProductionEnvironment()) {\n return undefined;\n }\n\n const expectedOrigin = new URL(request.url).origin;\n const origin = request.headers.get(\"origin\");\n\n if (origin !== null) {\n return origin === expectedOrigin\n ? undefined\n : jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n }\n\n const referer = request.headers.get(\"referer\");\n\n if (referer === null) {\n return jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n }\n\n try {\n return new URL(referer).origin === expectedOrigin\n ? undefined\n : jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n } catch {\n return jsonResponse({ ok: false, error: \"Origin not allowed.\" }, 403);\n }\n}\n\nfunction validateFormNonce(\n formData: FormData,\n replayStore: ServerActionReplayStore,\n): Response | undefined {\n const nonce = stringFormValue(formData.get(formFieldNonce));\n\n if (nonce === undefined || nonce.length === 0) {\n return jsonResponse({ ok: false, error: \"Missing server action nonce.\" }, 400);\n }\n\n if (replayStore.has(nonce)) {\n return jsonResponse({ ok: false, error: \"Server action nonce was already used.\" }, 409);\n }\n\n replayStore.add(nonce);\n return undefined;\n}\n\nfunction cleanActionFormData(formData: FormData): FormData {\n const cleaned = new FormData();\n\n for (const [name, value] of formData.entries()) {\n if (\n name !== formFieldModuleId &&\n name !== formFieldExportName &&\n name !== formCsrfFieldName &&\n name !== formFieldNonce &&\n name !== formFieldActionToken\n ) {\n cleaned.append(name, value);\n }\n }\n\n return cleaned;\n}\n\nfunction stringFormValue(value: FormDataEntryValue | null): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction jsonResponse(payload: unknown, status: number): Response {\n return new Response(JSON.stringify(payload), {\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n status,\n });\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll('\"', \""\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\");\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aws-lambda.d.ts","sourceRoot":"","sources":["../../src/adapters/aws-lambda.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"aws-lambda.d.ts","sourceRoot":"","sources":["../../src/adapters/aws-lambda.ts"],"names":[],"mappings":"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"}
|
|
@@ -78,15 +78,14 @@ function createAwsLambdaRequestHandlerFromRuntime(options, runtimeDirPromise, ru
|
|
|
78
78
|
const payload = options.errorHandler
|
|
79
79
|
? options.errorHandler(error)
|
|
80
80
|
: { body: "Internal Server Error", status: 500 };
|
|
81
|
-
|
|
82
|
-
body: payload.body,
|
|
81
|
+
const response = await applyAwsLambdaResponseHook(new Response(payload.body, {
|
|
83
82
|
headers: {
|
|
84
83
|
"content-type": "text/plain; charset=utf-8",
|
|
85
84
|
...payload.headers,
|
|
86
85
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
status: payload.status,
|
|
87
|
+
}), options, request);
|
|
88
|
+
return await responseToLambdaResult(response, phases);
|
|
90
89
|
}
|
|
91
90
|
};
|
|
92
91
|
}
|
|
@@ -252,17 +251,21 @@ function createAwsLambdaStreamingRequestHandlerFromRuntime(options, runtime, run
|
|
|
252
251
|
const payload = options.errorHandler
|
|
253
252
|
? options.errorHandler(error)
|
|
254
253
|
: { body: "Internal Server Error", status: 500 };
|
|
255
|
-
const response = new Response(payload.body, {
|
|
254
|
+
const response = await applyAwsLambdaResponseHook(new Response(payload.body, {
|
|
256
255
|
headers: {
|
|
257
256
|
"content-type": "text/plain; charset=utf-8",
|
|
258
257
|
...payload.headers,
|
|
259
258
|
},
|
|
260
259
|
status: payload.status,
|
|
261
|
-
});
|
|
260
|
+
}), options, request);
|
|
262
261
|
await streamResponseToLambda(response, responseStream, runtime, phases);
|
|
263
262
|
}
|
|
264
263
|
});
|
|
265
264
|
}
|
|
265
|
+
async function applyAwsLambdaResponseHook(response, options, request) {
|
|
266
|
+
const hooked = await options.onResponse?.(response, { request });
|
|
267
|
+
return hooked instanceof Response ? hooked : response;
|
|
268
|
+
}
|
|
266
269
|
async function prepareAwsLambdaRuntimeDir(options) {
|
|
267
270
|
const runtimeDir = options.runtimeDir ?? defaultAwsLambdaRuntimeDir(options.outDir);
|
|
268
271
|
await mkdir(runtimeDir, { recursive: true });
|