@reckona/mreact-router 0.0.202 → 0.0.204
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 +58 -11
- package/dist/actions.d.ts +8 -3
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +125 -45
- package/dist/actions.js.map +1 -1
- package/dist/adapters/aws-lambda.d.ts +15 -4
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +301 -63
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/adapters/cloudflare.d.ts +5 -2
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +35 -11
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/edge.d.ts +1 -1
- package/dist/adapters/edge.d.ts.map +1 -1
- package/dist/adapters/edge.js.map +1 -1
- package/dist/adapters/node.d.ts +5 -3
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js +2 -1
- package/dist/adapters/node.js.map +1 -1
- package/dist/adapters/static.d.ts.map +1 -1
- package/dist/adapters/static.js +24 -2
- package/dist/adapters/static.js.map +1 -1
- package/dist/build.d.ts +4 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +185 -13
- package/dist/build.js.map +1 -1
- package/dist/built-runtime.d.ts +2 -0
- package/dist/built-runtime.d.ts.map +1 -1
- package/dist/built-runtime.js +16 -0
- package/dist/built-runtime.js.map +1 -1
- package/dist/cache.d.ts +4 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +216 -17
- package/dist/cache.js.map +1 -1
- package/dist/cli-options.d.ts +3 -0
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +10 -2
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +14 -3
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +43 -3
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -2
- package/dist/config.js.map +1 -1
- package/dist/csp.d.ts +1 -0
- package/dist/csp.d.ts.map +1 -1
- package/dist/csp.js +9 -0
- package/dist/csp.js.map +1 -1
- package/dist/dehydrate-policy.d.ts +3 -0
- package/dist/dehydrate-policy.d.ts.map +1 -0
- package/dist/dehydrate-policy.js +16 -0
- package/dist/dehydrate-policy.js.map +1 -0
- package/dist/dev-server.d.ts +7 -2
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +120 -11
- package/dist/dev-server.js.map +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +147 -7
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +22 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +22 -8
- package/dist/logger.js.map +1 -1
- package/dist/metadata.d.ts +8 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +60 -22
- package/dist/metadata.js.map +1 -1
- package/dist/navigation-marker.d.ts +2 -0
- package/dist/navigation-marker.d.ts.map +1 -0
- package/dist/navigation-marker.js +357 -0
- package/dist/navigation-marker.js.map +1 -0
- package/dist/navigation-runtime.d.ts +1 -1
- package/dist/navigation-runtime.d.ts.map +1 -1
- package/dist/navigation-runtime.js +1 -1
- package/dist/navigation-runtime.js.map +1 -1
- package/dist/navigation.d.ts +1 -0
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +1 -1
- package/dist/navigation.js.map +1 -1
- package/dist/node-server.d.ts +5 -2
- package/dist/node-server.d.ts.map +1 -1
- package/dist/node-server.js +75 -6
- package/dist/node-server.js.map +1 -1
- package/dist/prerender-entry.d.ts +17 -1
- package/dist/prerender-entry.d.ts.map +1 -1
- package/dist/prerender-entry.js +98 -3
- package/dist/prerender-entry.js.map +1 -1
- package/dist/render.d.ts +16 -2
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +142 -135
- package/dist/render.js.map +1 -1
- package/dist/serve.d.ts +11 -2
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +67 -41
- package/dist/serve.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +52 -19
- package/dist/session.js.map +1 -1
- package/dist/upgrade.d.ts +59 -2
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +282 -1
- package/dist/upgrade.js.map +1 -1
- package/dist/vite-config.d.ts +2 -0
- package/dist/vite-config.d.ts.map +1 -1
- package/dist/vite-config.js +2 -0
- package/dist/vite-config.js.map +1 -1
- package/dist/vite.d.ts +4 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +117 -6
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
- package/src/actions.ts +146 -60
- package/src/adapters/aws-lambda.ts +426 -115
- package/src/adapters/cloudflare.ts +58 -12
- package/src/adapters/edge.ts +2 -0
- package/src/adapters/node.ts +8 -10
- package/src/adapters/static.ts +31 -2
- package/src/build.ts +217 -13
- package/src/built-runtime.ts +28 -0
- package/src/cache.ts +272 -19
- package/src/cli-options.ts +15 -2
- package/src/cli.ts +16 -2
- package/src/client.ts +47 -3
- package/src/config.ts +43 -6
- package/src/csp.ts +11 -0
- package/src/dehydrate-policy.ts +23 -0
- package/src/dev-server.ts +188 -15
- package/src/http.ts +172 -6
- package/src/index.ts +14 -1
- package/src/logger.ts +47 -10
- package/src/metadata.ts +125 -60
- package/src/navigation-marker.ts +423 -0
- package/src/navigation-runtime.ts +1 -0
- package/src/navigation.ts +1 -1
- package/src/node-server.ts +128 -22
- package/src/prerender-entry.ts +127 -5
- package/src/render.ts +859 -749
- package/src/serve.ts +112 -82
- package/src/session.ts +56 -25
- package/src/upgrade.ts +402 -3
- package/src/vite-config.ts +6 -0
- package/src/vite.ts +157 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AppRouterCache } from \"../cache.js\";\nimport { nodeRequestToWebRequest, sendResponse } from \"../http.js\";\nimport type { AppRouterServerActionOptions } from \"../actions.js\";\nimport type { AppRouterImportPolicy } from \"../import-policy.js\";\nimport {\n emitRouterLog,\n logDurationMs,\n logError,\n logNow,\n nodeRequestPath,\n requestLogFields,\n type AppRouterLogger,\n} from \"../logger.js\";\nimport type { AppRouterResponseHook } from \"../render.js\";\nimport type { RouterInstrumentation } from \"../trace.js\";\nimport { resolveNodeRequestProtocol } from \"../node-server.js\";\n\n/** Re-exports cache contracts used by Node handlers. */\nexport type { AppRouterCache, AppRouterCacheEntry } from \"../cache.js\";\n/** Re-exports server action contracts used by Node handlers. */\nexport type {\n AppRouterAllowedServerAction,\n AppRouterServerActionOptions,\n} from \"../actions.js\";\n/** Re-exports import policy contracts used by Node handlers. */\nexport type { AppRouterImportPolicy } from \"../import-policy.js\";\n/** Re-exports logger contracts used by Node handlers. */\nexport type {\n AppRouterCspInlineNonceWarningLogEvent,\n AppRouterLogger,\n AppRouterLogError,\n AppRouterLogEvent,\n AppRouterRenderTimingLogEvent,\n AppRouterRequestEndLogEvent,\n AppRouterRequestErrorLogEvent,\n AppRouterRequestStartLogEvent,\n AppRouterRequestTimingLogEvent,\n AppRouterRuntime,\n} from \"../logger.js\";\n/** Re-exports response hook contracts used by Node handlers. */\nexport type { AppRouterResponseHook, AppRouterResponseHookContext } from \"../render.js\";\n/** Re-exports build contracts referenced by Node handler options. */\nexport type { BuiltPrerenderedRoute } from \"../build.js\";\n/** Re-exports router instrumentation hooks and events for Node handlers. */\nexport type {\n RouterInstrumentation,\n RouterMiddlewareEndInstrumentationEvent,\n RouterMiddlewareInstrumentationEvent,\n RouterRequestEndInstrumentationEvent,\n RouterRequestInstrumentationEvent,\n RouterRouteEndInstrumentationEvent,\n RouterRouteInstrumentationEvent,\n RouterTraceContext,\n} from \"../trace.js\";\nimport {\n renderBuiltAppRequest,\n resolveRequestHost,\n warnIfImplicitHostTrust,\n type AppRouterPrerenderStore,\n type RequestHostPolicy,\n type ResponseSinkStrategy,\n} from \"../serve.js\";\n\n/** Re-exports request and rendering contracts used by Node handlers. */\nexport type {\n AppRouterPrerenderStore,\n RequestHostPolicy,\n ResponseSinkStrategy,\n} from \"../serve.js\";\n\n/**\n * Configures a Node request handler for built app-router output.\n */\nexport interface NodeRequestHandlerOptions {\n allowedHosts?: readonly string[] | undefined;\n errorHandler?:\n | ((error: unknown) => {\n body: string;\n headers?: Record<string, string>;\n status: number;\n })\n | undefined;\n hostPolicy?: RequestHostPolicy | undefined;\n hostname?: string | undefined;\n importPolicy?: AppRouterImportPolicy | undefined;\n instrumentation?: RouterInstrumentation | undefined;\n logger?: AppRouterLogger | undefined;\n onResponse?: AppRouterResponseHook | undefined;\n outDir: string;\n port?: number | undefined;\n prerenderStore?: AppRouterPrerenderStore | undefined;\n routeCache?: AppRouterCache | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n sinkStrategy?: ResponseSinkStrategy | undefined;\n /**\n * Trusts the first `X-Forwarded-Proto` value when the socket is not TLS.\n *\n * Defaults to `false`. Enable only behind a proxy that overwrites the header\n * and prevents untrusted clients from reaching the Node listener directly.\n */\n trustForwardedProto?: boolean | undefined;\n}\n\n/**\n * Handles one Node HTTP request/response pair for built app-router output.\n */\nexport type NodeRequestHandler = (\n incoming: IncomingMessage,\n outgoing: ServerResponse,\n) => Promise<void>;\n\n/**\n * Creates a Node `IncomingMessage`/`ServerResponse` handler for built app-router output.\n *\n * The handler converts Node requests to Web `Request` objects, enforces configured host trust, applies the built renderer, and writes the Web `Response` back to the Node socket.\n */\nexport function createNodeRequestHandler(options: NodeRequestHandlerOptions): NodeRequestHandler {\n warnIfImplicitHostTrust(options);\n\n return async (incoming, outgoing) => {\n const startedAt = logNow();\n const fallbackRequestFields = {\n method: incoming.method ?? \"GET\",\n path: nodeRequestPath(incoming.url),\n runtime: \"node\" as const,\n };\n\n try {\n const fallbackHost = `${options.hostname ?? \"127.0.0.1\"}:${options.port ?? 80}`;\n const host = resolveRequestHost({\n allowedHosts: options.allowedHosts,\n fallbackHost,\n hostPolicy: options.hostPolicy,\n rawHost: incoming.headers.host,\n });\n const protocol = resolveNodeRequestProtocol({\n encrypted: (incoming.socket as { encrypted?: boolean }).encrypted === true,\n forwardedProto: incoming.headers[\"x-forwarded-proto\"],\n trustForwardedProto: options.trustForwardedProto,\n });\n const request = nodeRequestToWebRequest(incoming, `${protocol}://${host}`);\n const logFields = requestLogFields(request, \"node\");\n emitRouterLog(options.logger, \"info\", {\n ...logFields,\n type: \"router:request:start\",\n });\n const response = await renderBuiltAppRequest({\n outDir: options.outDir,\n importPolicy: options.importPolicy,\n instrumentation: options.instrumentation,\n logger: options.logger,\n onResponse: options.onResponse,\n prerenderStore: options.prerenderStore,\n request,\n routeCache: options.routeCache,\n serverActions: options.serverActions,\n ...(options.sinkStrategy === undefined ? {} : { sinkStrategy: options.sinkStrategy }),\n });\n emitRouterLog(options.logger, \"info\", {\n ...logFields,\n durationMs: logDurationMs(startedAt),\n status: response.status,\n type: \"router:request:end\",\n });\n\n await sendResponse(outgoing, response);\n } catch (error) {\n emitRouterLog(options.logger, \"error\", {\n ...fallbackRequestFields,\n durationMs: logDurationMs(startedAt),\n error: logError(error),\n type: \"router:request:error\",\n });\n const payload = options.errorHandler\n ? options.errorHandler(error)\n : { body: \"Internal Server Error\", status: 500 };\n outgoing.statusCode = payload.status;\n outgoing.setHeader(\n \"content-type\",\n payload.headers?.[\"content-type\"] ?? \"text/plain; charset=utf-8\",\n );\n\n for (const [name, value] of Object.entries(payload.headers ?? {})) {\n if (name.toLowerCase() !== \"content-type\") {\n outgoing.setHeader(name, value);\n }\n }\n\n outgoing.end(payload.body);\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { DehydrateOptions } from \"@reckona/mreact-query\";\nimport type { AppRouterCache } from \"../cache.js\";\nimport { nodeRequestToWebRequest, sendResponse } from \"../http.js\";\nimport type { AppRouterServerActionOptions } from \"../actions.js\";\nimport type { AppRouterImportPolicy } from \"../import-policy.js\";\nimport {\n emitRouterLog,\n logDurationMs,\n logError,\n logNow,\n nodeRequestPath,\n requestLogFields,\n type AppRouterLogger,\n} from \"../logger.js\";\nimport type { AppRouterResponseHook } from \"../render.js\";\nimport type { RouterInstrumentation } from \"../trace.js\";\nimport { resolveNodeRequestProtocol } from \"../node-server.js\";\n\n/** Re-exports cache contracts used by Node handlers. */\nexport type { AppRouterCache, AppRouterCacheEntry } from \"../cache.js\";\n/** Re-exports server action contracts used by Node handlers. */\nexport type { AppRouterAllowedServerAction, AppRouterServerActionOptions } from \"../actions.js\";\n/** Re-exports import policy contracts used by Node handlers. */\nexport type { AppRouterImportPolicy } from \"../import-policy.js\";\n/** Re-exports logger contracts used by Node handlers. */\nexport type {\n AppRouterCspInlineNonceWarningLogEvent,\n AppRouterLogger,\n AppRouterLogError,\n AppRouterLogEvent,\n AppRouterRenderTimingLogEvent,\n AppRouterRequestEndLogEvent,\n AppRouterRequestErrorLogEvent,\n AppRouterRequestStartLogEvent,\n AppRouterRequestTimingLogEvent,\n AppRouterRuntime,\n AppRouterUpgradeErrorLogEvent,\n AppRouterUpgradeRejectedLogEvent,\n} from \"../logger.js\";\n/** Re-exports response hook contracts used by Node handlers. */\nexport type { AppRouterResponseHook, AppRouterResponseHookContext } from \"../render.js\";\n/** Re-exports build contracts referenced by Node handler options. */\nexport type { BuiltPrerenderedRoute } from \"../build.js\";\n/** Re-exports router instrumentation hooks and events for Node handlers. */\nexport type {\n RouterInstrumentation,\n RouterMiddlewareEndInstrumentationEvent,\n RouterMiddlewareInstrumentationEvent,\n RouterRequestEndInstrumentationEvent,\n RouterRequestInstrumentationEvent,\n RouterRouteEndInstrumentationEvent,\n RouterRouteInstrumentationEvent,\n RouterTraceContext,\n} from \"../trace.js\";\nimport {\n renderBuiltAppRequest,\n resolveRequestHost,\n warnIfImplicitHostTrust,\n type AppRouterPrerenderStore,\n type RequestHostPolicy,\n type ResponseSinkStrategy,\n} from \"../serve.js\";\n\n/** Re-exports request and rendering contracts used by Node handlers. */\nexport type { AppRouterPrerenderStore, RequestHostPolicy, ResponseSinkStrategy } from \"../serve.js\";\n\n/**\n * Configures a Node request handler for built app-router output.\n */\nexport interface NodeRequestHandlerOptions {\n allowedHosts?: readonly string[] | undefined;\n dehydrateOptions?: DehydrateOptions | undefined;\n errorHandler?:\n | ((error: unknown) => {\n body: string;\n headers?: Record<string, string>;\n status: number;\n })\n | undefined;\n hostPolicy?: RequestHostPolicy | undefined;\n hostname?: string | undefined;\n importPolicy?: AppRouterImportPolicy | undefined;\n instrumentation?: RouterInstrumentation | undefined;\n logger?: AppRouterLogger | undefined;\n onResponse?: AppRouterResponseHook | undefined;\n outDir: string;\n port?: number | undefined;\n prerenderStore?: AppRouterPrerenderStore | undefined;\n routeCache?: AppRouterCache | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n sinkStrategy?: ResponseSinkStrategy | undefined;\n /**\n * Trusts the first `X-Forwarded-Proto` value when the socket is not TLS.\n *\n * Defaults to `false`. Enable only behind a proxy that overwrites the header\n * and prevents untrusted clients from reaching the Node listener directly.\n */\n trustForwardedProto?: boolean | undefined;\n}\n\n/**\n * Handles one Node HTTP request/response pair for built app-router output.\n */\nexport type NodeRequestHandler = (\n incoming: IncomingMessage,\n outgoing: ServerResponse,\n) => Promise<void>;\n\n/**\n * Creates a Node `IncomingMessage`/`ServerResponse` handler for built app-router output.\n *\n * The handler converts Node requests to Web `Request` objects, enforces configured host trust, applies the built renderer, and writes the Web `Response` back to the Node socket.\n */\nexport function createNodeRequestHandler(options: NodeRequestHandlerOptions): NodeRequestHandler {\n warnIfImplicitHostTrust(options);\n\n return async (incoming, outgoing) => {\n const startedAt = logNow();\n const fallbackRequestFields = {\n method: incoming.method ?? \"GET\",\n path: nodeRequestPath(incoming.url),\n runtime: \"node\" as const,\n };\n\n try {\n const fallbackHost = `${options.hostname ?? \"127.0.0.1\"}:${options.port ?? 80}`;\n const host = resolveRequestHost({\n allowedHosts: options.allowedHosts,\n fallbackHost,\n hostPolicy: options.hostPolicy,\n rawHost: incoming.headers.host,\n });\n const protocol = resolveNodeRequestProtocol({\n encrypted: (incoming.socket as { encrypted?: boolean }).encrypted === true,\n forwardedProto: incoming.headers[\"x-forwarded-proto\"],\n trustForwardedProto: options.trustForwardedProto,\n });\n const request = nodeRequestToWebRequest(incoming, `${protocol}://${host}`, outgoing);\n const logFields = requestLogFields(request, \"node\");\n emitRouterLog(options.logger, \"info\", {\n ...logFields,\n type: \"router:request:start\",\n });\n const response = await renderBuiltAppRequest({\n dehydrateOptions: options.dehydrateOptions,\n outDir: options.outDir,\n importPolicy: options.importPolicy,\n instrumentation: options.instrumentation,\n logger: options.logger,\n onResponse: options.onResponse,\n prerenderStore: options.prerenderStore,\n request,\n routeCache: options.routeCache,\n serverActions: options.serverActions,\n ...(options.sinkStrategy === undefined ? {} : { sinkStrategy: options.sinkStrategy }),\n });\n emitRouterLog(options.logger, \"info\", {\n ...logFields,\n durationMs: logDurationMs(startedAt),\n status: response.status,\n type: \"router:request:end\",\n });\n\n await sendResponse(outgoing, response);\n } catch (error) {\n emitRouterLog(options.logger, \"error\", {\n ...fallbackRequestFields,\n durationMs: logDurationMs(startedAt),\n error: logError(error),\n type: \"router:request:error\",\n });\n const payload = options.errorHandler\n ? options.errorHandler(error)\n : { body: \"Internal Server Error\", status: 500 };\n outgoing.statusCode = payload.status;\n outgoing.setHeader(\n \"content-type\",\n payload.headers?.[\"content-type\"] ?? \"text/plain; charset=utf-8\",\n );\n\n for (const [name, value] of Object.entries(payload.headers ?? {})) {\n if (name.toLowerCase() !== \"content-type\") {\n outgoing.setHeader(name, value);\n }\n }\n\n outgoing.end(payload.body);\n }\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/adapters/static.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/adapters/static.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA6C/F"}
|
package/dist/adapters/static.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join, resolve, sep } from "node:path";
|
|
3
|
-
import { isCurrentPrerenderedRoute } from "../prerender-entry.js";
|
|
3
|
+
import { isCurrentPrerenderedRoute, validatedPrerenderedNavigationHtml, } from "../prerender-entry.js";
|
|
4
|
+
const staticNavigationBase = "/_mreact/navigation";
|
|
5
|
+
const staticNavigationMetadata = `<meta name="mreact-static-navigation" content="${staticNavigationBase}">`;
|
|
4
6
|
/**
|
|
5
7
|
* Exports prerendered app-router routes and client assets to a static filesystem directory.
|
|
6
8
|
*
|
|
@@ -56,8 +58,28 @@ async function writePrerenderedRoute(exportDir, route, entry) {
|
|
|
56
58
|
throw new Error(`Cannot export route ${route} with status ${entry.status}.`);
|
|
57
59
|
}
|
|
58
60
|
const file = routeToHtmlFile(exportDir, route);
|
|
61
|
+
const navigationHtml = validatedPrerenderedNavigationHtml(entry);
|
|
62
|
+
if (navigationHtml === undefined) {
|
|
63
|
+
throw new Error(`Cannot export route ${route} without a valid navigation variant.`);
|
|
64
|
+
}
|
|
65
|
+
const navigationFile = routeToHtmlFile(join(exportDir, staticNavigationBase), route);
|
|
59
66
|
await mkdir(dirname(file), { recursive: true });
|
|
60
|
-
await
|
|
67
|
+
await mkdir(dirname(navigationFile), { recursive: true });
|
|
68
|
+
await writeFile(file, withStaticNavigationMetadata(entry.html));
|
|
69
|
+
await writeFile(navigationFile, navigationHtml);
|
|
70
|
+
}
|
|
71
|
+
function withStaticNavigationMetadata(html) {
|
|
72
|
+
const head = /<head(?:\s[^>]*)?>/i.exec(html);
|
|
73
|
+
if (head?.index !== undefined) {
|
|
74
|
+
const insertion = head.index + head[0].length;
|
|
75
|
+
return `${html.slice(0, insertion)}${staticNavigationMetadata}${html.slice(insertion)}`;
|
|
76
|
+
}
|
|
77
|
+
const doctype = /^\s*<!doctype\s+html\s*>/i.exec(html);
|
|
78
|
+
if (doctype !== null) {
|
|
79
|
+
const insertion = doctype[0].length;
|
|
80
|
+
return `${html.slice(0, insertion)}${staticNavigationMetadata}${html.slice(insertion)}`;
|
|
81
|
+
}
|
|
82
|
+
return `${staticNavigationMetadata}${html}`;
|
|
61
83
|
}
|
|
62
84
|
function routeToHtmlFile(exportDir, route) {
|
|
63
85
|
const pathname = route.split("?")[0] ?? "/";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/adapters/static.ts"],"names":[],"mappings":"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","sourcesContent":["import { cp, mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve, sep } from \"node:path\";\nimport type { BuiltPrerenderedRoute, BuiltServerManifest } from \"../build.js\";\nimport { isCurrentPrerenderedRoute } from \"../prerender-entry.js\";\n\n/**\n * Configures static export from a built app-router output directory.\n */\nexport interface StaticExportOptions {\n exportDir: string;\n outDir: string;\n paths?: readonly string[] | undefined;\n}\n\n/**\n * Lists the routes written by a static app-router export.\n */\nexport interface StaticExportResult {\n routes: string[];\n}\n\n/**\n * Exports prerendered app-router routes and client assets to a static filesystem directory.\n *\n * Only routes present in the built prerender manifest can be exported; the export directory is removed and recreated, and route paths are checked to prevent traversal outside it.\n */\nexport async function exportStaticApp(options: StaticExportOptions): Promise<StaticExportResult> {\n const manifest = JSON.parse(\n await readFile(join(options.outDir, \"server\", \"manifest.json\"), \"utf8\"),\n ) as BuiltServerManifest;\n const clientManifest = JSON.parse(\n await readFile(join(options.outDir, \"client\", \"manifest.json\"), \"utf8\"),\n ) as { publicAssets?: readonly string[] };\n const prerenderedRoutes = manifest.prerenderedRoutes ?? {};\n const routes = [...(options.paths ?? Object.keys(prerenderedRoutes))].sort();\n const entries = routes.map((route): readonly [string, BuiltPrerenderedRoute] => {\n routeToHtmlFile(options.exportDir, route);\n const entry = prerenderedRoutes[route];\n\n if (entry === undefined) {\n throw new Error(`Cannot export non-prerendered route: ${route}`);\n }\n\n if (!isCurrentPrerenderedRoute(entry)) {\n throw new Error(`Cannot export invalid prerendered route: ${route}`);\n }\n\n if (entry.status < 200 || entry.status >= 300) {\n throw new Error(`Cannot export route ${route} with status ${entry.status}.`);\n }\n\n return [route, entry];\n });\n\n await rm(options.exportDir, { force: true, recursive: true });\n await mkdir(options.exportDir, { recursive: true });\n\n for (const [route, entry] of entries) {\n await writePrerenderedRoute(options.exportDir, route, entry);\n }\n\n await cp(join(options.outDir, \"client\"), join(options.exportDir, \"_mreact\", \"client\"), {\n recursive: true,\n });\n await copyPublicAssetsToExportRoot(\n join(options.outDir, \"client\"),\n options.exportDir,\n clientManifest.publicAssets ?? [],\n );\n\n return { routes };\n}\n\nasync function copyPublicAssetsToExportRoot(\n clientDir: string,\n exportDir: string,\n publicAssets: readonly string[],\n): Promise<void> {\n for (const asset of publicAssets) {\n if (\n !asset.startsWith(\"/\") ||\n asset.startsWith(\"//\") ||\n asset.includes(\"..\") ||\n asset === \"/_mreact\" ||\n asset.startsWith(\"/_mreact/\")\n ) {\n continue;\n }\n\n const relativeAsset = asset.slice(1);\n const destination = join(exportDir, relativeAsset);\n await mkdir(dirname(destination), { recursive: true });\n await cp(join(clientDir, relativeAsset), destination, { recursive: true });\n }\n}\n\nasync function writePrerenderedRoute(\n exportDir: string,\n route: string,\n entry: BuiltPrerenderedRoute,\n): Promise<void> {\n if (entry.status < 200 || entry.status >= 300) {\n throw new Error(`Cannot export route ${route} with status ${entry.status}.`);\n }\n\n const file = routeToHtmlFile(exportDir, route);\n await mkdir(dirname(file), { recursive: true });\n await writeFile(file, entry.html);\n}\n\nfunction routeToHtmlFile(exportDir: string, route: string): string {\n const pathname = route.split(\"?\")[0] ?? \"/\";\n const normalized = pathname.startsWith(\"/\") ? pathname.slice(1) : pathname;\n const relativeFile = normalized === \"\" ? \"index.html\" : join(normalized, \"index.html\");\n const root = resolve(exportDir);\n const file = resolve(root, relativeFile);\n\n if (file !== root && !file.startsWith(`${root}${sep}`)) {\n throw new Error(`unsafe static export route: ${route}`);\n }\n\n return file;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/adapters/static.ts"],"names":[],"mappings":"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","sourcesContent":["import { cp, mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve, sep } from \"node:path\";\nimport type { BuiltPrerenderedRoute, BuiltServerManifest } from \"../build.js\";\nimport {\n isCurrentPrerenderedRoute,\n validatedPrerenderedNavigationHtml,\n} from \"../prerender-entry.js\";\n\nconst staticNavigationBase = \"/_mreact/navigation\";\nconst staticNavigationMetadata = `<meta name=\"mreact-static-navigation\" content=\"${staticNavigationBase}\">`;\n\n/**\n * Configures static export from a built app-router output directory.\n */\nexport interface StaticExportOptions {\n exportDir: string;\n outDir: string;\n paths?: readonly string[] | undefined;\n}\n\n/**\n * Lists the routes written by a static app-router export.\n */\nexport interface StaticExportResult {\n routes: string[];\n}\n\n/**\n * Exports prerendered app-router routes and client assets to a static filesystem directory.\n *\n * Only routes present in the built prerender manifest can be exported; the export directory is removed and recreated, and route paths are checked to prevent traversal outside it.\n */\nexport async function exportStaticApp(options: StaticExportOptions): Promise<StaticExportResult> {\n const manifest = JSON.parse(\n await readFile(join(options.outDir, \"server\", \"manifest.json\"), \"utf8\"),\n ) as BuiltServerManifest;\n const clientManifest = JSON.parse(\n await readFile(join(options.outDir, \"client\", \"manifest.json\"), \"utf8\"),\n ) as { publicAssets?: readonly string[] };\n const prerenderedRoutes = manifest.prerenderedRoutes ?? {};\n const routes = [...(options.paths ?? Object.keys(prerenderedRoutes))].sort();\n const entries = routes.map((route): readonly [string, BuiltPrerenderedRoute] => {\n routeToHtmlFile(options.exportDir, route);\n const entry = prerenderedRoutes[route];\n\n if (entry === undefined) {\n throw new Error(`Cannot export non-prerendered route: ${route}`);\n }\n\n if (!isCurrentPrerenderedRoute(entry)) {\n throw new Error(`Cannot export invalid prerendered route: ${route}`);\n }\n\n if (entry.status < 200 || entry.status >= 300) {\n throw new Error(`Cannot export route ${route} with status ${entry.status}.`);\n }\n\n return [route, entry];\n });\n\n await rm(options.exportDir, { force: true, recursive: true });\n await mkdir(options.exportDir, { recursive: true });\n\n for (const [route, entry] of entries) {\n await writePrerenderedRoute(options.exportDir, route, entry);\n }\n\n await cp(join(options.outDir, \"client\"), join(options.exportDir, \"_mreact\", \"client\"), {\n recursive: true,\n });\n await copyPublicAssetsToExportRoot(\n join(options.outDir, \"client\"),\n options.exportDir,\n clientManifest.publicAssets ?? [],\n );\n\n return { routes };\n}\n\nasync function copyPublicAssetsToExportRoot(\n clientDir: string,\n exportDir: string,\n publicAssets: readonly string[],\n): Promise<void> {\n for (const asset of publicAssets) {\n if (\n !asset.startsWith(\"/\") ||\n asset.startsWith(\"//\") ||\n asset.includes(\"..\") ||\n asset === \"/_mreact\" ||\n asset.startsWith(\"/_mreact/\")\n ) {\n continue;\n }\n\n const relativeAsset = asset.slice(1);\n const destination = join(exportDir, relativeAsset);\n await mkdir(dirname(destination), { recursive: true });\n await cp(join(clientDir, relativeAsset), destination, { recursive: true });\n }\n}\n\nasync function writePrerenderedRoute(\n exportDir: string,\n route: string,\n entry: BuiltPrerenderedRoute,\n): Promise<void> {\n if (entry.status < 200 || entry.status >= 300) {\n throw new Error(`Cannot export route ${route} with status ${entry.status}.`);\n }\n\n const file = routeToHtmlFile(exportDir, route);\n const navigationHtml = validatedPrerenderedNavigationHtml(entry);\n if (navigationHtml === undefined) {\n throw new Error(`Cannot export route ${route} without a valid navigation variant.`);\n }\n const navigationFile = routeToHtmlFile(join(exportDir, staticNavigationBase), route);\n await mkdir(dirname(file), { recursive: true });\n await mkdir(dirname(navigationFile), { recursive: true });\n await writeFile(file, withStaticNavigationMetadata(entry.html));\n await writeFile(navigationFile, navigationHtml);\n}\n\nfunction withStaticNavigationMetadata(html: string): string {\n const head = /<head(?:\\s[^>]*)?>/i.exec(html);\n if (head?.index !== undefined) {\n const insertion = head.index + head[0].length;\n return `${html.slice(0, insertion)}${staticNavigationMetadata}${html.slice(insertion)}`;\n }\n\n const doctype = /^\\s*<!doctype\\s+html\\s*>/i.exec(html);\n if (doctype !== null) {\n const insertion = doctype[0].length;\n return `${html.slice(0, insertion)}${staticNavigationMetadata}${html.slice(insertion)}`;\n }\n\n return `${staticNavigationMetadata}${html}`;\n}\n\nfunction routeToHtmlFile(exportDir: string, route: string): string {\n const pathname = route.split(\"?\")[0] ?? \"/\";\n const normalized = pathname.startsWith(\"/\") ? pathname.slice(1) : pathname;\n const relativeFile = normalized === \"\" ? \"index.html\" : join(normalized, \"index.html\");\n const root = resolve(exportDir);\n const file = resolve(root, relativeFile);\n\n if (file !== root && !file.startsWith(`${root}${sep}`)) {\n throw new Error(`unsafe static export route: ${route}`);\n }\n\n return file;\n}\n"]}
|
package/dist/build.d.ts
CHANGED
|
@@ -109,6 +109,7 @@ export interface PackageCloudflarePagesArtifactOptions {
|
|
|
109
109
|
export interface BuiltServerManifest {
|
|
110
110
|
allowedSourceDirs?: readonly string[];
|
|
111
111
|
assetBaseUrl?: string;
|
|
112
|
+
dehydratePolicyModule?: string;
|
|
112
113
|
version: 1;
|
|
113
114
|
files: Record<string, string>;
|
|
114
115
|
prerenderedRoutes?: Record<string, BuiltPrerenderedRoute>;
|
|
@@ -172,9 +173,11 @@ export interface BuiltServerModuleOutput {
|
|
|
172
173
|
export interface BuiltPrerenderedRoute {
|
|
173
174
|
headers: Record<string, string>;
|
|
174
175
|
html: string;
|
|
176
|
+
navigationHtml?: string | undefined;
|
|
175
177
|
/** Identifies entries that satisfy the complete current prerender contract. */
|
|
176
|
-
schemaVersion?:
|
|
178
|
+
schemaVersion?: 4 | undefined;
|
|
177
179
|
status: number;
|
|
180
|
+
strictTransportSecurity?: string | undefined;
|
|
178
181
|
}
|
|
179
182
|
/**
|
|
180
183
|
* Builds an app-router project into server, client, and optional deployment-target artifacts.
|
package/dist/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
|
package/dist/build.js
CHANGED
|
@@ -9,13 +9,14 @@ import { collectStaticImportReferences, collectTopLevelValueExportNames, formatD
|
|
|
9
9
|
import { transformCompilerModuleContext } from "@reckona/mreact-compiler/internal";
|
|
10
10
|
import { compilerModuleContextForSource, collectClientRouteReferences, createClientRouteInferenceCache, detectAnchorElementUsage, detectClientNavigationOverride, formatClientRouteInferenceDiagnostic, inferClientRouteModule, navigationRuntimeLinkDisabledDiagnostic, resolveNavigationRuntime, } from "./client-route-inference.js";
|
|
11
11
|
import { createBoundaryReport } from "./boundaries.js";
|
|
12
|
-
import { buildClientRouteBatchOutput, buildNavigationRuntimeBundle, clientScriptForPath, routeIdForPath, } from "./navigation-runtime.js";
|
|
12
|
+
import { buildClientRouteBatchOutput, buildNavigationRuntimeBundle, clientScriptForPath, routeIdForPath, routeMarkerParts, } from "./navigation-runtime.js";
|
|
13
13
|
import { COMPAT_VENDOR_PLACEHOLDER_PREFIX, bundleAppRouterSourceModule, fileImportMetaUrlPlugin, importAppRouterSourceModule, resolveCompatVendorEntryFiles, sourceReferencesCompatVendorSpecifier, } from "./module-runner.js";
|
|
14
|
+
import { dehydrateOptionsFromModule } from "./dehydrate-policy.js";
|
|
14
15
|
import { compileRouteMatcherArtifact, scanAppRoutes } from "./routes.js";
|
|
15
16
|
import { appFileConventionForRootFilename } from "./file-conventions.js";
|
|
16
17
|
import { resolveAppRouterProjectOptions, resolveBuildTargets, } from "./config.js";
|
|
17
18
|
import { routeCachePolicyFromSource } from "./cache.js";
|
|
18
|
-
import { bundleMiddlewareModuleCode, renderAppRequest, } from "./render.js";
|
|
19
|
+
import { bundleMiddlewareModuleCode, prerenderVariantMarkerParts, renderAppRequest, } from "./render.js";
|
|
19
20
|
import { createAppRouterImportPolicyPlugin } from "./import-policy.js";
|
|
20
21
|
import { hasGenerateStaticParamsExport, hasLoaderExport, hasPrerenderExport, isStreamRouteSource, routeClosureMayUseAwaitBoundary, routeClosureMayUseRequestInput, stripRouteBuildExports, stripRouteClientOnlyExports, stripRouteClientSource, stripRouteLoaderOnlyExports, stripRouteMetadataOnlyExports, stripRouteRequestOnlyExports, } from "./route-source.js";
|
|
21
22
|
import { bundleRouterModule, bundleRouterModules, } from "./bundle-pipeline.js";
|
|
@@ -23,7 +24,7 @@ import { collectRouteCssFilesFromSources, collectSpecialBoundaryFiles } from "./
|
|
|
23
24
|
import { existingRouteShellCandidates } from "./route-shells.js";
|
|
24
25
|
import { sourceModuleCandidates } from "./source-modules.js";
|
|
25
26
|
import { collectBuildInferredServerActions } from "./server-action-inference.js";
|
|
26
|
-
import { isVisitorDependentResponse, PRERENDERED_ROUTE_SCHEMA_VERSION, } from "./prerender-entry.js";
|
|
27
|
+
import { isVisitorDependentResponse, PRERENDERED_ROUTE_SCHEMA_VERSION, storedPrerenderedRouteHeaders, } from "./prerender-entry.js";
|
|
27
28
|
import { prepareRouteServerActionPlaceholders } from "./actions.js";
|
|
28
29
|
import { viteDefineCacheKey, vitePluginsCacheKey } from "./vite-plugin-cache-key.js";
|
|
29
30
|
import { workspacePackageFile } from "./workspace-packages.js";
|
|
@@ -77,6 +78,9 @@ export async function buildApp(options) {
|
|
|
77
78
|
return await buildConcurrencyStorage.run(buildConcurrency, async () => await buildAppWithResolvedProject(options, project));
|
|
78
79
|
}
|
|
79
80
|
async function buildAppWithResolvedProject(options, project) {
|
|
81
|
+
if (options.dehydrateOptions !== undefined) {
|
|
82
|
+
throw new Error("buildApp dehydration policies must use dehydratePolicyModule so the same executable policy is available to prerendering and built runtimes.");
|
|
83
|
+
}
|
|
80
84
|
const timingSink = options.onBuildPhaseTiming;
|
|
81
85
|
const progressSink = options.onBuildProgress;
|
|
82
86
|
const shouldTrackBuildPhases = timingSink !== undefined || progressSink !== undefined;
|
|
@@ -178,6 +182,21 @@ async function buildAppWithResolvedProject(options, project) {
|
|
|
178
182
|
]);
|
|
179
183
|
});
|
|
180
184
|
}
|
|
185
|
+
const builtDehydratePolicy = project.dehydratePolicyModule === undefined
|
|
186
|
+
? undefined
|
|
187
|
+
: await buildDehydratePolicyModule({
|
|
188
|
+
define: viteDefine,
|
|
189
|
+
file: project.dehydratePolicyModule,
|
|
190
|
+
projectRoot: project.projectRoot,
|
|
191
|
+
vitePlugins,
|
|
192
|
+
});
|
|
193
|
+
const dehydratePolicyArtifact = builtDehydratePolicy === undefined
|
|
194
|
+
? undefined
|
|
195
|
+
: `dehydrate-policy.${hashText(builtDehydratePolicy.code).slice(0, 16)}.mjs`;
|
|
196
|
+
if (builtDehydratePolicy !== undefined && dehydratePolicyArtifact !== undefined) {
|
|
197
|
+
await writeFile(join(serverDir, dehydratePolicyArtifact), builtDehydratePolicy.code);
|
|
198
|
+
}
|
|
199
|
+
const dehydrateOptions = builtDehydratePolicy?.dehydrateOptions;
|
|
181
200
|
const publicAssets = shouldTrackBuildPhases === false
|
|
182
201
|
? await buildPublicAssetManifest(project, clientDir)
|
|
183
202
|
: await timeBuildPhase(timingSink, progressSink, "publicAssets", () => buildPublicAssetManifest(project, clientDir));
|
|
@@ -302,6 +321,7 @@ async function buildAppWithResolvedProject(options, project) {
|
|
|
302
321
|
assetBaseUrl: project.assetBaseUrl,
|
|
303
322
|
clientRoutes: clientManifestRoutes,
|
|
304
323
|
define: viteDefine,
|
|
324
|
+
dehydrateOptions,
|
|
305
325
|
project,
|
|
306
326
|
routes,
|
|
307
327
|
serverModules,
|
|
@@ -313,6 +333,7 @@ async function buildAppWithResolvedProject(options, project) {
|
|
|
313
333
|
assetBaseUrl: project.assetBaseUrl,
|
|
314
334
|
clientRoutes: clientManifestRoutes,
|
|
315
335
|
define: viteDefine,
|
|
336
|
+
dehydrateOptions,
|
|
316
337
|
project,
|
|
317
338
|
routes,
|
|
318
339
|
serverModules,
|
|
@@ -352,6 +373,9 @@ async function buildAppWithResolvedProject(options, project) {
|
|
|
352
373
|
const serverManifest = {
|
|
353
374
|
allowedSourceDirs: project.allowedSourceDirs.map((directory) => relative(project.projectRoot, directory)),
|
|
354
375
|
...(project.assetBaseUrl === undefined ? {} : { assetBaseUrl: project.assetBaseUrl }),
|
|
376
|
+
...(dehydratePolicyArtifact === undefined
|
|
377
|
+
? {}
|
|
378
|
+
: { dehydratePolicyModule: dehydratePolicyArtifact }),
|
|
355
379
|
version: 1,
|
|
356
380
|
routes: serverRoutes,
|
|
357
381
|
routeMatcher: compileRouteMatcherArtifact(serverRoutes),
|
|
@@ -446,7 +470,7 @@ async function buildAppWithResolvedProject(options, project) {
|
|
|
446
470
|
return { routes };
|
|
447
471
|
}
|
|
448
472
|
const incrementalBuildCacheFilename = "build-cache.json";
|
|
449
|
-
const incrementalBuildCacheVersion =
|
|
473
|
+
const incrementalBuildCacheVersion = 2;
|
|
450
474
|
async function createIncrementalBuildCacheFingerprint(options) {
|
|
451
475
|
if (options.vitePlugins !== undefined && options.vitePlugins.length > 0) {
|
|
452
476
|
return undefined;
|
|
@@ -481,6 +505,9 @@ async function createIncrementalBuildCacheFingerprint(options) {
|
|
|
481
505
|
assetBaseUrl: options.project.assetBaseUrl ?? null,
|
|
482
506
|
clientConsolePureFunctions: options.project.clientConsolePureFunctions ?? [],
|
|
483
507
|
clientSourceMaps: options.project.clientSourceMaps,
|
|
508
|
+
dehydratePolicyModule: options.project.dehydratePolicyModule === undefined
|
|
509
|
+
? null
|
|
510
|
+
: normalizeBuildInputPath(relative(options.project.projectRoot, options.project.dehydratePolicyModule)),
|
|
484
511
|
define,
|
|
485
512
|
nodeEnv: process.env.NODE_ENV ?? null,
|
|
486
513
|
publicAssetBaseUrl: options.project.publicAssetBaseUrl ?? null,
|
|
@@ -529,6 +556,9 @@ async function hasRequiredIncrementalBuildOutputs(outDir, buildTargets) {
|
|
|
529
556
|
return false;
|
|
530
557
|
}
|
|
531
558
|
for (const file of [
|
|
559
|
+
...(serverManifest.dehydratePolicyModule === undefined
|
|
560
|
+
? []
|
|
561
|
+
: [serverManifest.dehydratePolicyModule]),
|
|
532
562
|
...Object.values(serverManifest.serverModuleFiles ?? {}),
|
|
533
563
|
...Object.values(serverManifest.serverModuleRenderFiles ?? {}),
|
|
534
564
|
...Object.values(serverManifest.serverModuleRequestFiles ?? {}),
|
|
@@ -1570,6 +1600,28 @@ async function copyPublicAssetsInner(publicDir, relativeDir, outDir) {
|
|
|
1570
1600
|
function isReservedPublicAssetPath(pathname) {
|
|
1571
1601
|
return pathname === "/_mreact" || pathname.startsWith("/_mreact/");
|
|
1572
1602
|
}
|
|
1603
|
+
async function buildDehydratePolicyModule(options) {
|
|
1604
|
+
const source = await readFile(options.file, "utf8");
|
|
1605
|
+
const code = await bundleAppRouterSourceModule({
|
|
1606
|
+
code: source,
|
|
1607
|
+
define: options.define,
|
|
1608
|
+
label: `dehydrate-policy:${options.file}`,
|
|
1609
|
+
plugins: [fileImportMetaUrlPlugin()],
|
|
1610
|
+
resolveDir: dirname(options.file),
|
|
1611
|
+
root: options.projectRoot,
|
|
1612
|
+
sourcefile: options.file,
|
|
1613
|
+
vitePlugins: options.vitePlugins,
|
|
1614
|
+
});
|
|
1615
|
+
const policyModule = await importAppRouterSourceModule({
|
|
1616
|
+
code,
|
|
1617
|
+
label: `dehydrate-policy-runtime:${options.file}`,
|
|
1618
|
+
sourcefile: options.file,
|
|
1619
|
+
});
|
|
1620
|
+
return {
|
|
1621
|
+
code,
|
|
1622
|
+
dehydrateOptions: dehydrateOptionsFromModule(policyModule, `mreactRouter dehydratePolicyModule ${options.file}`),
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1573
1625
|
function isNodeError(error) {
|
|
1574
1626
|
return error instanceof Error && "code" in error;
|
|
1575
1627
|
}
|
|
@@ -1605,6 +1657,7 @@ async function prerenderStaticRoutes(options) {
|
|
|
1605
1657
|
for (const pathname of await prerenderPathsForRoute(route, analysis, options.vitePlugins)) {
|
|
1606
1658
|
const renderSignals = {
|
|
1607
1659
|
headerDependent: () => true,
|
|
1660
|
+
strictTransportSecurity: () => undefined,
|
|
1608
1661
|
};
|
|
1609
1662
|
const renderOptions = {
|
|
1610
1663
|
appDir: options.appDir,
|
|
@@ -1612,30 +1665,48 @@ async function prerenderStaticRoutes(options) {
|
|
|
1612
1665
|
clientScripts,
|
|
1613
1666
|
clientStyles,
|
|
1614
1667
|
define: options.define,
|
|
1668
|
+
dehydrateOptions: options.dehydrateOptions,
|
|
1615
1669
|
importPolicy,
|
|
1616
1670
|
navigationScripts,
|
|
1617
1671
|
request: new Request(`http://mreact.local${pathname}`),
|
|
1672
|
+
prerenderVariantCapture: !analysis.clientRoute,
|
|
1618
1673
|
renderSignals,
|
|
1619
1674
|
serverModuleCacheVersion,
|
|
1620
1675
|
serverModules: serverModuleMap,
|
|
1621
1676
|
vitePlugins: options.vitePlugins,
|
|
1622
1677
|
};
|
|
1623
1678
|
const response = await renderAppRequest(renderOptions);
|
|
1624
|
-
const
|
|
1679
|
+
const renderedHtml = await response.text();
|
|
1625
1680
|
if (renderSignals.headerDependent() || isVisitorDependentResponse(response)) {
|
|
1626
1681
|
continue;
|
|
1627
1682
|
}
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1683
|
+
let html = renderedHtml;
|
|
1684
|
+
let navigationHtml = renderedHtml;
|
|
1685
|
+
if (!analysis.clientRoute) {
|
|
1686
|
+
const capture = prerenderVariantMarkerParts(route.path);
|
|
1687
|
+
const start = renderedHtml.indexOf(capture.prefix);
|
|
1688
|
+
const end = renderedHtml.lastIndexOf(capture.suffix);
|
|
1689
|
+
if (start === -1 || end < start + capture.prefix.length) {
|
|
1690
|
+
throw new Error(`Failed to capture prerender response variants for ${pathname}.`);
|
|
1691
|
+
}
|
|
1692
|
+
const before = renderedHtml.slice(0, start);
|
|
1693
|
+
const content = renderedHtml.slice(start + capture.prefix.length, end);
|
|
1694
|
+
const after = renderedHtml.slice(end + capture.suffix.length);
|
|
1695
|
+
const navigationMarker = routeMarkerParts(route.path);
|
|
1696
|
+
html = `${before}${content}${after}`;
|
|
1697
|
+
navigationHtml = `${before}${navigationMarker.prefix}${content}${navigationMarker.suffix}${after}`;
|
|
1698
|
+
}
|
|
1699
|
+
const headers = storedPrerenderedRouteHeaders(response.headers);
|
|
1700
|
+
const strictTransportSecurity = renderSignals.strictTransportSecurity();
|
|
1632
1701
|
entries.push([
|
|
1633
1702
|
pathname,
|
|
1634
1703
|
{
|
|
1635
1704
|
headers,
|
|
1636
1705
|
html,
|
|
1706
|
+
navigationHtml,
|
|
1637
1707
|
schemaVersion: PRERENDERED_ROUTE_SCHEMA_VERSION,
|
|
1638
1708
|
status: response.status,
|
|
1709
|
+
...(strictTransportSecurity === undefined ? {} : { strictTransportSecurity }),
|
|
1639
1710
|
},
|
|
1640
1711
|
]);
|
|
1641
1712
|
}
|
|
@@ -2532,6 +2603,7 @@ function cloudflarePageRouteFacadeModuleSource(componentImport) {
|
|
|
2532
2603
|
const componentSlots = readComponentModuleExport(componentModule, "slots");
|
|
2533
2604
|
const componentGenerateMetadata = readComponentModuleExport(componentModule, "generateMetadata");
|
|
2534
2605
|
const componentMetadata = readComponentModuleExport(componentModule, "metadata");
|
|
2606
|
+
const componentSecurityHeadersApplied = readComponentModuleExport(componentModule, "__mreactSecurityHeadersApplied");
|
|
2535
2607
|
|
|
2536
2608
|
export function App(props) {
|
|
2537
2609
|
return renderCloudflareRouteComponent(props);
|
|
@@ -2546,6 +2618,7 @@ export const slots = componentSlots === undefined ? undefined : { ...componentSl
|
|
|
2546
2618
|
export const generateMetadata =
|
|
2547
2619
|
typeof componentGenerateMetadata === "function" ? componentGenerateMetadata : undefined;
|
|
2548
2620
|
export const metadata = componentMetadata;
|
|
2621
|
+
export const __mreactSecurityHeadersApplied = componentSecurityHeadersApplied === true;
|
|
2549
2622
|
|
|
2550
2623
|
function renderCloudflareRouteComponent(props) {
|
|
2551
2624
|
const routeComponent = resolveCloudflareRouteComponent();
|
|
@@ -3115,7 +3188,9 @@ ${cloudflareShellRuntimeSource()}`;
|
|
|
3115
3188
|
});
|
|
3116
3189
|
}
|
|
3117
3190
|
function cloudflareShellRuntimeSource() {
|
|
3118
|
-
return `
|
|
3191
|
+
return `export const __mreactSecurityHeadersApplied = true;
|
|
3192
|
+
|
|
3193
|
+
async function renderLayoutShells(shells, props, namedSlots) {
|
|
3119
3194
|
const slotContext = { consumedSlots: new Set(), namedSlots };
|
|
3120
3195
|
const rendered = [];
|
|
3121
3196
|
for (const shell of shells) {
|
|
@@ -3194,7 +3269,7 @@ function cloudflareHydrationMarkerParts(props) {
|
|
|
3194
3269
|
const escapedRouteId = escapeHtmlAttribute(routeId);
|
|
3195
3270
|
const propsJson = escapeScriptJson(JSON.stringify({
|
|
3196
3271
|
params: props.params,
|
|
3197
|
-
request: { url: props.request.url },
|
|
3272
|
+
request: { url: new URL(props.request.url).pathname },
|
|
3198
3273
|
data: props.data,
|
|
3199
3274
|
}));
|
|
3200
3275
|
const clientReferencesJson = route.clientReferenceManifest === undefined || route.clientReferenceManifest.length === 0
|
|
@@ -3376,7 +3451,41 @@ function validateOptionalHeadMetadata(value, path) {
|
|
|
3376
3451
|
}
|
|
3377
3452
|
}
|
|
3378
3453
|
}
|
|
3454
|
+
validateMetaRefreshHeadDescriptor(descriptor, descriptorPath);
|
|
3455
|
+
});
|
|
3456
|
+
}
|
|
3457
|
+
|
|
3458
|
+
function validateMetaRefreshHeadDescriptor(descriptor, path) {
|
|
3459
|
+
if (descriptor.tag !== "meta" || descriptor.attrs === undefined) {
|
|
3460
|
+
return;
|
|
3461
|
+
}
|
|
3462
|
+
const attrs = Object.entries(descriptor.attrs);
|
|
3463
|
+
const hasRefresh = attrs.some(([name, value]) => {
|
|
3464
|
+
const canonicalName = name.toLowerCase();
|
|
3465
|
+
return (canonicalName === "http-equiv" || canonicalName === "httpequiv")
|
|
3466
|
+
&& typeof value === "string"
|
|
3467
|
+
&& value.toLowerCase() === "refresh";
|
|
3379
3468
|
});
|
|
3469
|
+
if (!hasRefresh) {
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
for (const [name, value] of attrs) {
|
|
3473
|
+
if (name.toLowerCase() !== "content" || typeof value !== "string") {
|
|
3474
|
+
continue;
|
|
3475
|
+
}
|
|
3476
|
+
const match = /^[^;]*;\\s*url\\s*=\\s*([\\s\\S]+)$/iu.exec(value);
|
|
3477
|
+
if (match === null || match[1] === undefined) {
|
|
3478
|
+
continue;
|
|
3479
|
+
}
|
|
3480
|
+
let target = match[1].trim();
|
|
3481
|
+
const quote = target[0];
|
|
3482
|
+
if ((quote === String.fromCharCode(34) || quote === "'") && target[target.length - 1] === quote) {
|
|
3483
|
+
target = target.slice(1, -1).trim();
|
|
3484
|
+
}
|
|
3485
|
+
if (isUnsafeUrlValueForName("href", target)) {
|
|
3486
|
+
throw new Error(\`Invalid metadata field \${path}.attrs.\${name}: unsafe refresh URL value.\`);
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3380
3489
|
}
|
|
3381
3490
|
|
|
3382
3491
|
function validateHeadAttribute(name, value, path) {
|
|
@@ -3440,7 +3549,7 @@ function isUnsafeUrlValueForName(name, value) {
|
|
|
3440
3549
|
}
|
|
3441
3550
|
const scheme = match[1].toLowerCase();
|
|
3442
3551
|
if (scheme === "data" && (name === "src" || name === "poster")) {
|
|
3443
|
-
return !/^data:image\\/(?!svg\\+xml(?:[;,]|$))/i.test(canonical);
|
|
3552
|
+
return !/^data:image\\/(?!svg\\+xml\\s*(?:[;,]|$))/i.test(canonical);
|
|
3444
3553
|
}
|
|
3445
3554
|
return scheme === "javascript" || scheme === "data" || scheme === "vbscript" || scheme === "livescript" || scheme === "mhtml" || scheme === "file";
|
|
3446
3555
|
}
|
|
@@ -3617,17 +3726,63 @@ function routeSecurityHeaders(security, request) {
|
|
|
3617
3726
|
} else {
|
|
3618
3727
|
headers["referrer-policy"] = validateHeaderValue(security?.referrerPolicy ?? "strict-origin-when-cross-origin");
|
|
3619
3728
|
}
|
|
3729
|
+
if (security?.permissionsPolicy === null) {
|
|
3730
|
+
delete headers["permissions-policy"];
|
|
3731
|
+
} else {
|
|
3732
|
+
const permissionsPolicy = serializePermissionsPolicy(security?.permissionsPolicy);
|
|
3733
|
+
if (permissionsPolicy === undefined) {
|
|
3734
|
+
delete headers["permissions-policy"];
|
|
3735
|
+
} else {
|
|
3736
|
+
headers["permissions-policy"] = permissionsPolicy;
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3620
3739
|
if (security?.frameOptions === null) {
|
|
3621
3740
|
delete headers["x-frame-options"];
|
|
3622
3741
|
} else if (security?.frameOptions !== undefined) {
|
|
3623
3742
|
headers["x-frame-options"] = validateHeaderValue(security.frameOptions);
|
|
3624
3743
|
}
|
|
3625
3744
|
if (request.url.startsWith("https://") && security?.hsts !== undefined && security.hsts !== false && security.hsts !== null) {
|
|
3626
|
-
headers["strict-transport-security"] =
|
|
3745
|
+
headers["strict-transport-security"] = serializeHsts(security.hsts);
|
|
3627
3746
|
}
|
|
3628
3747
|
return headers;
|
|
3629
3748
|
}
|
|
3630
3749
|
|
|
3750
|
+
function serializeHsts(hsts) {
|
|
3751
|
+
if (hsts === false) {
|
|
3752
|
+
throw new TypeError("Invalid security header value for hsts.");
|
|
3753
|
+
}
|
|
3754
|
+
const maxAge = Math.trunc(hsts.maxAge);
|
|
3755
|
+
if (!Number.isFinite(maxAge) || maxAge < 0) {
|
|
3756
|
+
throw new TypeError("Invalid security header value for hsts.maxAge.");
|
|
3757
|
+
}
|
|
3758
|
+
const parts = [\`max-age=\${maxAge}\`];
|
|
3759
|
+
if (hsts.includeSubDomains === true) {
|
|
3760
|
+
parts.push("includeSubDomains");
|
|
3761
|
+
}
|
|
3762
|
+
if (hsts.preload === true) {
|
|
3763
|
+
parts.push("preload");
|
|
3764
|
+
}
|
|
3765
|
+
return parts.join("; ");
|
|
3766
|
+
}
|
|
3767
|
+
|
|
3768
|
+
function serializePermissionsPolicy(policy) {
|
|
3769
|
+
if (policy === undefined) {
|
|
3770
|
+
return "camera=(), microphone=(), geolocation=()";
|
|
3771
|
+
}
|
|
3772
|
+
const directives = [];
|
|
3773
|
+
for (const [directive, allowlist] of Object.entries(policy)) {
|
|
3774
|
+
if (allowlist === null || allowlist === undefined) {
|
|
3775
|
+
continue;
|
|
3776
|
+
}
|
|
3777
|
+
validateToken(directive, "permissionsPolicy directive");
|
|
3778
|
+
for (const value of allowlist) {
|
|
3779
|
+
validatePermissionAllowlistValue(value);
|
|
3780
|
+
}
|
|
3781
|
+
directives.push(\`\${directive}=(\${allowlist.join(" ")})\`);
|
|
3782
|
+
}
|
|
3783
|
+
return directives.length === 0 ? undefined : directives.join(", ");
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3631
3786
|
function validateHeaderValue(value) {
|
|
3632
3787
|
for (let index = 0; index < value.length; index += 1) {
|
|
3633
3788
|
const code = value.charCodeAt(index);
|
|
@@ -3638,6 +3793,22 @@ function validateHeaderValue(value) {
|
|
|
3638
3793
|
return value;
|
|
3639
3794
|
}
|
|
3640
3795
|
|
|
3796
|
+
function validateToken(value, label) {
|
|
3797
|
+
if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(value)) {
|
|
3798
|
+
throw new TypeError(\`Invalid security header value for \${label}: \${JSON.stringify(value)}\`);
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
|
|
3802
|
+
function validatePermissionAllowlistValue(value) {
|
|
3803
|
+
if (value === "self" || value === "*" || /^[A-Za-z][A-Za-z0-9+.-]*:$/.test(value)) {
|
|
3804
|
+
return;
|
|
3805
|
+
}
|
|
3806
|
+
if (/^https:\\/\\/[A-Za-z0-9.-]+(?::[0-9]+)?$/.test(value)) {
|
|
3807
|
+
return;
|
|
3808
|
+
}
|
|
3809
|
+
throw new TypeError(\`Invalid security header value for permissionsPolicy allowlist: \${JSON.stringify(value)}\`);
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3641
3812
|
function mergeRouteMetadata(metadata) {
|
|
3642
3813
|
if (metadata.length === 0) {
|
|
3643
3814
|
return undefined;
|
|
@@ -4359,6 +4530,7 @@ async function writeClientRouteBundles(options) {
|
|
|
4359
4530
|
clientNavigation: detectClientNavigationOverride(source) ??
|
|
4360
4531
|
(navigation || detectAnchorElementUsage(clientSource, route.file)),
|
|
4361
4532
|
routeMayUseOutOfOrderFragments: options.sourceAnalysis.byRouteFile.get(relative(options.projectRoot, route.file).split(sep).join("/"))?.streamRoute === true,
|
|
4533
|
+
restoreRequestUrl: options.sourceAnalysis.byRouteFile.get(relative(options.projectRoot, route.file).split(sep).join("/"))?.usesRequestInput === true,
|
|
4362
4534
|
cacheDir: options.cacheDir,
|
|
4363
4535
|
dropConsoleFunctions: options.clientConsolePureFunctions,
|
|
4364
4536
|
filename: route.file,
|