@reckona/mreact-router 0.0.201 → 0.0.202

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/cloudflare.d.ts.map +1 -1
  3. package/dist/adapters/cloudflare.js +51 -4
  4. package/dist/adapters/cloudflare.js.map +1 -1
  5. package/dist/adapters/node.d.ts +7 -0
  6. package/dist/adapters/node.d.ts.map +1 -1
  7. package/dist/adapters/node.js +7 -1
  8. package/dist/adapters/node.js.map +1 -1
  9. package/dist/adapters/static.d.ts.map +1 -1
  10. package/dist/adapters/static.js +14 -3
  11. package/dist/adapters/static.js.map +1 -1
  12. package/dist/build.d.ts +3 -0
  13. package/dist/build.d.ts.map +1 -1
  14. package/dist/build.js +42 -5
  15. package/dist/build.js.map +1 -1
  16. package/dist/built-runtime.d.ts +4 -1
  17. package/dist/built-runtime.d.ts.map +1 -1
  18. package/dist/built-runtime.js.map +1 -1
  19. package/dist/cache.d.ts +26 -0
  20. package/dist/cache.d.ts.map +1 -1
  21. package/dist/cache.js +78 -12
  22. package/dist/cache.js.map +1 -1
  23. package/dist/cli-options.d.ts +4 -0
  24. package/dist/cli-options.d.ts.map +1 -1
  25. package/dist/cli-options.js +17 -0
  26. package/dist/cli-options.js.map +1 -1
  27. package/dist/cli.js +2 -1
  28. package/dist/cli.js.map +1 -1
  29. package/dist/node-server.d.ts +6 -0
  30. package/dist/node-server.d.ts.map +1 -1
  31. package/dist/node-server.js +19 -1
  32. package/dist/node-server.js.map +1 -1
  33. package/dist/prerender-entry.d.ts +5 -0
  34. package/dist/prerender-entry.d.ts.map +1 -0
  35. package/dist/prerender-entry.js +41 -0
  36. package/dist/prerender-entry.js.map +1 -0
  37. package/dist/render.d.ts +13 -0
  38. package/dist/render.d.ts.map +1 -1
  39. package/dist/render.js +139 -87
  40. package/dist/render.js.map +1 -1
  41. package/dist/request-header-tracking.d.ts +44 -0
  42. package/dist/request-header-tracking.d.ts.map +1 -0
  43. package/dist/request-header-tracking.js +116 -0
  44. package/dist/request-header-tracking.js.map +1 -0
  45. package/dist/route-source.d.ts +16 -0
  46. package/dist/route-source.d.ts.map +1 -1
  47. package/dist/route-source.js +55 -1
  48. package/dist/route-source.js.map +1 -1
  49. package/dist/security-headers.d.ts +16 -0
  50. package/dist/security-headers.d.ts.map +1 -1
  51. package/dist/security-headers.js +37 -0
  52. package/dist/security-headers.js.map +1 -1
  53. package/dist/serve.d.ts +7 -0
  54. package/dist/serve.d.ts.map +1 -1
  55. package/dist/serve.js +94 -28
  56. package/dist/serve.js.map +1 -1
  57. package/package.json +11 -11
  58. package/src/adapters/cloudflare.ts +81 -9
  59. package/src/adapters/node.ts +14 -1
  60. package/src/adapters/static.ts +18 -5
  61. package/src/build.ts +71 -4
  62. package/src/built-runtime.ts +2 -2
  63. package/src/cache.ts +117 -11
  64. package/src/cli-options.ts +24 -0
  65. package/src/cli.ts +5 -0
  66. package/src/node-server.ts +27 -1
  67. package/src/prerender-entry.ts +56 -0
  68. package/src/render.ts +188 -98
  69. package/src/request-header-tracking.ts +161 -0
  70. package/src/route-source.ts +71 -0
  71. package/src/security-headers.ts +41 -0
  72. package/src/serve.ts +133 -30
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Observes request inputs read by application code during a render.
3
+ *
4
+ * The shared route cache is keyed on the app directory, route path, pathname
5
+ * and query only. A render that reads a request header therefore produces HTML
6
+ * that is only correct for that header value, and storing it would serve one
7
+ * visitor's variant to the next: `accept-language` mixes locales, `user-agent`
8
+ * mixes mobile and desktop shells, and `cf-connecting-ip` or `referer` disclose
9
+ * one visitor's data to another. Reads are observed rather than inferred from
10
+ * the source so that headers read through helper modules are covered too.
11
+ *
12
+ * Only the request handed to application code is tracked. Router internals keep
13
+ * using the original request, so their own header reads never mark a route as
14
+ * header dependent.
15
+ *
16
+ * Reconstructing the request with `new Request(request)` copies headers from
17
+ * internal slots that no interception can reach. Application contexts therefore
18
+ * mark access when their lazy `request` property is retrieved, before opaque
19
+ * helpers can reconstruct it. `render.ts` also uses conservative source closure
20
+ * analysis so a previously stored entry cannot bypass the runtime observation.
21
+ */
22
+ export interface TrackedHeaderRequest {
23
+ /** Marks application access to the Request before it can escape tracking. */
24
+ markRequestAccess(): void;
25
+ /** Returns true once application code has observed request-specific input. */
26
+ requestDependent(): boolean;
27
+ /** The request to hand to loaders, metadata functions and components. */
28
+ request: Request;
29
+ }
30
+ /**
31
+ * Wraps a request so that header reads performed through it are recorded.
32
+ *
33
+ * Falls back to reporting every request as header dependent when the request
34
+ * cannot be cloned, so an unexpected runtime never silently enables sharing.
35
+ */
36
+ export declare function trackRequestHeaderReads(request: Request): TrackedHeaderRequest;
37
+ /**
38
+ * Adds an enumerable Request property that records application access before
39
+ * opaque code can copy native Request internal slots.
40
+ */
41
+ export declare function withTrackedRequest<T extends object>(values: T, request: Request, tracked: TrackedHeaderRequest | undefined): T & {
42
+ request: Request;
43
+ };
44
+ //# sourceMappingURL=request-header-tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-header-tracking.d.ts","sourceRoot":"","sources":["../src/request-header-tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,iBAAiB,IAAI,IAAI,CAAC;IAC1B,8EAA8E;IAC9E,gBAAgB,IAAI,OAAO,CAAC;IAC5B,yEAAyE;IACzE,OAAO,EAAE,OAAO,CAAC;CAClB;AAaD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAqF9E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,oBAAoB,GAAG,SAAS,GACxC,CAAC,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAkB1B"}
@@ -0,0 +1,116 @@
1
+ const HEADER_READ_METHODS = new Set([
2
+ "entries",
3
+ "forEach",
4
+ "get",
5
+ "getSetCookie",
6
+ "has",
7
+ "keys",
8
+ "values",
9
+ Symbol.iterator,
10
+ ]);
11
+ /**
12
+ * Wraps a request so that header reads performed through it are recorded.
13
+ *
14
+ * Falls back to reporting every request as header dependent when the request
15
+ * cannot be cloned, so an unexpected runtime never silently enables sharing.
16
+ */
17
+ export function trackRequestHeaderReads(request) {
18
+ let readAny = false;
19
+ let tracked;
20
+ try {
21
+ // Cloning a request that carries a body would tee its stream and buffer
22
+ // whichever half goes unread. Only bodyless requests are worth tracking:
23
+ // a request with a body is reported as header dependent so that its
24
+ // response is never shared.
25
+ if (request.body !== null) {
26
+ return {
27
+ markRequestAccess() { },
28
+ requestDependent: () => true,
29
+ request,
30
+ };
31
+ }
32
+ tracked = request.clone();
33
+ }
34
+ catch {
35
+ return {
36
+ markRequestAccess() { },
37
+ requestDependent: () => true,
38
+ request,
39
+ };
40
+ }
41
+ const originalHeaders = tracked.headers;
42
+ const originalUrl = tracked.url;
43
+ const headers = new Proxy(originalHeaders, {
44
+ get(target, property) {
45
+ const value = Reflect.get(target, property, target);
46
+ if (typeof value !== "function" || !HEADER_READ_METHODS.has(property)) {
47
+ return value;
48
+ }
49
+ return (...args) => {
50
+ readAny = true;
51
+ return Reflect.apply(value, target, args);
52
+ };
53
+ },
54
+ });
55
+ // Origin/host are not part of the route cache key. Treat any URL observation
56
+ // as request dependence so a multi-host process cannot replay one tenant's
57
+ // absolute URLs to another. Path and query reads are conservatively included.
58
+ Object.defineProperty(tracked, "url", {
59
+ configurable: true,
60
+ get: () => {
61
+ readAny = true;
62
+ return originalUrl;
63
+ },
64
+ });
65
+ // Shadow the prototype getter on a real Request so that `fetch(request)`,
66
+ // `request.json()` and instanceof checks keep working in every runtime.
67
+ // Taking a reference counts as a read on its own: a caller that reached for
68
+ // the headers is assumed to depend on them, which keeps the decision closed
69
+ // when the reference escapes into code this module cannot observe.
70
+ Object.defineProperty(tracked, "headers", {
71
+ configurable: true,
72
+ get: () => {
73
+ readAny = true;
74
+ return headers;
75
+ },
76
+ });
77
+ // `clone()` copies headers from internal slots rather than through the
78
+ // property above, so an unshadowed clone would hand back untracked headers.
79
+ Object.defineProperty(tracked, "clone", {
80
+ configurable: true,
81
+ value: () => {
82
+ readAny = true;
83
+ return Request.prototype.clone.call(tracked);
84
+ },
85
+ writable: true,
86
+ });
87
+ return {
88
+ markRequestAccess: () => {
89
+ readAny = true;
90
+ },
91
+ requestDependent: () => readAny,
92
+ request: tracked,
93
+ };
94
+ }
95
+ /**
96
+ * Adds an enumerable Request property that records application access before
97
+ * opaque code can copy native Request internal slots.
98
+ */
99
+ export function withTrackedRequest(values, request, tracked) {
100
+ const context = values;
101
+ let currentRequest = request;
102
+ Object.defineProperty(context, "request", {
103
+ configurable: true,
104
+ enumerable: true,
105
+ get() {
106
+ tracked?.markRequestAccess();
107
+ return currentRequest;
108
+ },
109
+ set(value) {
110
+ tracked?.markRequestAccess();
111
+ currentRequest = value;
112
+ },
113
+ });
114
+ return context;
115
+ }
116
+ //# sourceMappingURL=request-header-tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-header-tracking.js","sourceRoot":"","sources":["../src/request-header-tracking.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Observes request inputs read by application code during a render.\n *\n * The shared route cache is keyed on the app directory, route path, pathname\n * and query only. A render that reads a request header therefore produces HTML\n * that is only correct for that header value, and storing it would serve one\n * visitor's variant to the next: `accept-language` mixes locales, `user-agent`\n * mixes mobile and desktop shells, and `cf-connecting-ip` or `referer` disclose\n * one visitor's data to another. Reads are observed rather than inferred from\n * the source so that headers read through helper modules are covered too.\n *\n * Only the request handed to application code is tracked. Router internals keep\n * using the original request, so their own header reads never mark a route as\n * header dependent.\n *\n * Reconstructing the request with `new Request(request)` copies headers from\n * internal slots that no interception can reach. Application contexts therefore\n * mark access when their lazy `request` property is retrieved, before opaque\n * helpers can reconstruct it. `render.ts` also uses conservative source closure\n * analysis so a previously stored entry cannot bypass the runtime observation.\n */\nexport interface TrackedHeaderRequest {\n /** Marks application access to the Request before it can escape tracking. */\n markRequestAccess(): void;\n /** Returns true once application code has observed request-specific input. */\n requestDependent(): boolean;\n /** The request to hand to loaders, metadata functions and components. */\n request: Request;\n}\n\nconst HEADER_READ_METHODS = new Set<string | symbol>([\n \"entries\",\n \"forEach\",\n \"get\",\n \"getSetCookie\",\n \"has\",\n \"keys\",\n \"values\",\n Symbol.iterator,\n]);\n\n/**\n * Wraps a request so that header reads performed through it are recorded.\n *\n * Falls back to reporting every request as header dependent when the request\n * cannot be cloned, so an unexpected runtime never silently enables sharing.\n */\nexport function trackRequestHeaderReads(request: Request): TrackedHeaderRequest {\n let readAny = false;\n\n let tracked: Request;\n try {\n // Cloning a request that carries a body would tee its stream and buffer\n // whichever half goes unread. Only bodyless requests are worth tracking:\n // a request with a body is reported as header dependent so that its\n // response is never shared.\n if (request.body !== null) {\n return {\n markRequestAccess() {},\n requestDependent: () => true,\n request,\n };\n }\n\n tracked = request.clone();\n } catch {\n return {\n markRequestAccess() {},\n requestDependent: () => true,\n request,\n };\n }\n\n const originalHeaders = tracked.headers;\n const originalUrl = tracked.url;\n const headers = new Proxy(originalHeaders, {\n get(target, property) {\n const value = Reflect.get(target, property, target);\n\n if (typeof value !== \"function\" || !HEADER_READ_METHODS.has(property)) {\n return value;\n }\n\n return (...args: unknown[]): unknown => {\n readAny = true;\n return Reflect.apply(value as (...callArgs: unknown[]) => unknown, target, args);\n };\n },\n });\n\n // Origin/host are not part of the route cache key. Treat any URL observation\n // as request dependence so a multi-host process cannot replay one tenant's\n // absolute URLs to another. Path and query reads are conservatively included.\n Object.defineProperty(tracked, \"url\", {\n configurable: true,\n get: () => {\n readAny = true;\n return originalUrl;\n },\n });\n\n // Shadow the prototype getter on a real Request so that `fetch(request)`,\n // `request.json()` and instanceof checks keep working in every runtime.\n // Taking a reference counts as a read on its own: a caller that reached for\n // the headers is assumed to depend on them, which keeps the decision closed\n // when the reference escapes into code this module cannot observe.\n Object.defineProperty(tracked, \"headers\", {\n configurable: true,\n get: () => {\n readAny = true;\n return headers;\n },\n });\n\n // `clone()` copies headers from internal slots rather than through the\n // property above, so an unshadowed clone would hand back untracked headers.\n Object.defineProperty(tracked, \"clone\", {\n configurable: true,\n value: (): Request => {\n readAny = true;\n return Request.prototype.clone.call(tracked);\n },\n writable: true,\n });\n\n return {\n markRequestAccess: () => {\n readAny = true;\n },\n requestDependent: () => readAny,\n request: tracked,\n };\n}\n\n/**\n * Adds an enumerable Request property that records application access before\n * opaque code can copy native Request internal slots.\n */\nexport function withTrackedRequest<T extends object>(\n values: T,\n request: Request,\n tracked: TrackedHeaderRequest | undefined,\n): T & { request: Request } {\n const context = values as T & { request: Request };\n let currentRequest = request;\n\n Object.defineProperty(context, \"request\", {\n configurable: true,\n enumerable: true,\n get() {\n tracked?.markRequestAccess();\n return currentRequest;\n },\n set(value: Request) {\n tracked?.markRequestAccess();\n currentRequest = value;\n },\n });\n\n return context;\n}\n"]}
@@ -22,6 +22,22 @@ export declare function routeClosureMayUseAwaitBoundary(options: {
22
22
  seen?: Set<string> | undefined;
23
23
  source: string;
24
24
  }): boolean;
25
+ /**
26
+ * Conservatively detects route closures that may consume Request inputs which
27
+ * are not represented by the shared route cache key.
28
+ *
29
+ * This deliberately over-approximates: a false positive disables shared HTML
30
+ * reuse, while a false negative can disclose one request's rendered values to
31
+ * another. Local server imports are traversed so helpers that reconstruct a
32
+ * Request from its internal slots are covered before cache lookup.
33
+ */
34
+ export declare function routeClosureMayUseRequestInput(options: {
35
+ filename: string;
36
+ files: RouteSourceLookup;
37
+ projectRoot: string;
38
+ seen?: Set<string> | undefined;
39
+ source: string;
40
+ }): boolean;
25
41
  export declare function hasPrerenderExport(code: string, filename?: string | undefined): boolean;
26
42
  export declare function hasGenerateStaticParamsExport(code: string, filename?: string | undefined): boolean;
27
43
  export declare function hasLoaderExport(code: string, filename?: string | undefined): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"route-source.d.ts","sourceRoot":"","sources":["../src/route-source.ts"],"names":[],"mappings":"AAuCA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM3F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAa/F;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,GAAG,MAAM,CAKT;AAED,wBAAgB,qCAAqC,CAAC,KAAK,EAAE;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,GAAG,MAAM,CAST;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE1F;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUhG;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAU/F;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUjG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM3F;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAExF;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAuDV;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEvF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAElG;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEpF;AA+CD,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"route-source.d.ts","sourceRoot":"","sources":["../src/route-source.ts"],"names":[],"mappings":"AAwCA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM3F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAa/F;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,GAAG,MAAM,CAKT;AAED,wBAAgB,qCAAqC,CAAC,KAAK,EAAE;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,GAAG,MAAM,CAST;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE1F;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUhG;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAU/F;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUjG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM3F;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAExF;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAuDV;AAID;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAmDV;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEvF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAElG;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEpF;AA+CD,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { dirname, isAbsolute, join } from "node:path";
2
- import { collectFormActionExpressionReferences, collectTopLevelValueExportNames, collectJsxComponentRootNames, collectStaticImportReferences, demoteTopLevelExportDeclarations, hasModuleDirective, hasTopLevelExportDeclaration, stripTopLevelExportDeclarations, stripUnusedStaticValueImports, } from "@reckona/mreact-compiler";
2
+ import { collectIdentifierReferenceNames, collectFormActionExpressionReferences, collectTopLevelValueExportNames, collectJsxComponentRootNames, collectStaticImportReferences, demoteTopLevelExportDeclarations, hasModuleDirective, hasTopLevelExportDeclaration, stripTopLevelExportDeclarations, stripUnusedStaticValueImports, } from "@reckona/mreact-compiler";
3
3
  import { sourceModuleCandidates } from "./source-modules.js";
4
4
  const routeModuleExportNames = [
5
5
  "auth",
@@ -135,6 +135,60 @@ export function routeClosureMayUseAwaitBoundary(options) {
135
135
  seen.delete(options.filename);
136
136
  }
137
137
  }
138
+ const REQUEST_INPUT_IDENTIFIERS = new Set(["fetch", "request", "Request"]);
139
+ /**
140
+ * Conservatively detects route closures that may consume Request inputs which
141
+ * are not represented by the shared route cache key.
142
+ *
143
+ * This deliberately over-approximates: a false positive disables shared HTML
144
+ * reuse, while a false negative can disclose one request's rendered values to
145
+ * another. Local server imports are traversed so helpers that reconstruct a
146
+ * Request from its internal slots are covered before cache lookup.
147
+ */
148
+ export function routeClosureMayUseRequestInput(options) {
149
+ const seen = options.seen ?? new Set();
150
+ if (seen.has(options.filename)) {
151
+ return false;
152
+ }
153
+ seen.add(options.filename);
154
+ try {
155
+ if (hasModuleDirective({ code: options.source, directive: "use client" })) {
156
+ return false;
157
+ }
158
+ const sourceFilename = sourceFilenameForCompiler(options.projectRoot, options.filename);
159
+ if (collectIdentifierReferenceNames({
160
+ code: options.source,
161
+ filename: sourceFilename,
162
+ }).some((name) => REQUEST_INPUT_IDENTIFIERS.has(name))) {
163
+ return true;
164
+ }
165
+ for (const reference of collectStaticImportReferences({
166
+ code: options.source,
167
+ filename: sourceFilename,
168
+ })) {
169
+ const resolved = resolveLocalSourceImport(options.files, options.filename, reference.source);
170
+ if (resolved !== undefined &&
171
+ routeClosureMayUseRequestInput({
172
+ filename: resolved.filename,
173
+ files: options.files,
174
+ projectRoot: options.projectRoot,
175
+ seen,
176
+ source: resolved.source,
177
+ })) {
178
+ return true;
179
+ }
180
+ }
181
+ return false;
182
+ }
183
+ catch {
184
+ // An analysis parser mismatch must not turn an unknown route into a shared
185
+ // cache candidate. The normal compiler still reports actual source errors.
186
+ return true;
187
+ }
188
+ finally {
189
+ seen.delete(options.filename);
190
+ }
191
+ }
138
192
  export function hasPrerenderExport(code, filename) {
139
193
  return hasTopLevelExportDeclaration({ code, filename, names: ["prerender"] });
140
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route-source.js","sourceRoot":"","sources":["../src/route-source.ts"],"names":[],"mappings":"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","sourcesContent":["import { dirname, isAbsolute, join } from \"node:path\";\nimport {\n collectFormActionExpressionReferences,\n collectTopLevelValueExportNames,\n collectJsxComponentRootNames,\n collectStaticImportReferences,\n demoteTopLevelExportDeclarations,\n hasModuleDirective,\n hasTopLevelExportDeclaration,\n stripTopLevelExportDeclarations,\n stripUnusedStaticValueImports,\n} from \"@reckona/mreact-compiler\";\nimport type { StaticImportReference } from \"@reckona/mreact-compiler\";\nimport { sourceModuleCandidates } from \"./source-modules.js\";\n\nconst routeModuleExportNames = [\n \"auth\",\n \"generateStaticParams\",\n \"loader\",\n \"middleware\",\n \"prerender\",\n \"revalidate\",\n \"stream\",\n] as const;\nconst routeClientOnlyExportNames = [\n ...routeModuleExportNames,\n \"generateMetadata\",\n \"metadata\",\n] as const;\nconst routeRequestRenderExportNames = [\"default\", \"slots\"] as const;\nconst routeRenderExportNames = new Set<string>([\"default\", \"slots\"]);\nconst routeRequestExportNames = new Set<string>([\n ...routeClientOnlyExportNames,\n \"generateMetadata\",\n \"metadata\",\n]);\nconst routeLoaderOnlyExportNames = new Set<string>([\"loader\"]);\nconst routeMetadataOnlyExportNames = new Set<string>([\"generateMetadata\", \"metadata\"]);\n\nexport function stripRouteModuleExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(stripTopLevelExportDeclarations({\n code,\n filename,\n names: routeModuleExportNames,\n }), routeRenderExportNames, filename);\n}\n\nexport function stripRouteClientOnlyExports(code: string, filename?: string | undefined): string {\n return stripUnusedStaticValueImports({\n code: demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: routeClientOnlyExportNames,\n }),\n routeRenderExportNames,\n filename,\n ),\n filename,\n });\n}\n\nexport function stripRouteClientSource(input: {\n code: string;\n filename?: string | undefined;\n}): string {\n return stripRouteClientFormActionExpressions({\n code: stripRouteClientOnlyExports(input.code, input.filename),\n filename: input.filename,\n });\n}\n\nexport function stripRouteClientFormActionExpressions(input: {\n code: string;\n filename?: string | undefined;\n}): string {\n const references = collectFormActionExpressionReferences(input);\n let code = input.code;\n\n for (const reference of [...references].reverse()) {\n code = `${code.slice(0, reference.expressionStart)}undefined${code.slice(reference.expressionEnd)}`;\n }\n\n return code;\n}\n\nexport function stripRouteBuildExports(code: string, filename?: string | undefined): string {\n return stripRouteClientOnlyExports(code, filename);\n}\n\nexport function stripRouteRequestOnlyExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: routeRequestRenderExportNames,\n }),\n routeRequestExportNames,\n filename,\n );\n}\n\nexport function stripRouteLoaderOnlyExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: [\"auth\", \"default\", \"generateMetadata\", \"generateStaticParams\", \"metadata\", \"middleware\", \"prerender\", \"revalidate\", \"slots\", \"stream\"],\n }),\n routeLoaderOnlyExportNames,\n filename,\n );\n}\n\nexport function stripRouteMetadataOnlyExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: [\"auth\", \"default\", \"generateStaticParams\", \"loader\", \"middleware\", \"prerender\", \"revalidate\", \"slots\", \"stream\"],\n }),\n routeMetadataOnlyExportNames,\n filename,\n );\n}\n\nexport function stripRouteConfigExports(code: string, filename?: string | undefined): string {\n return stripTopLevelExportDeclarations({\n code,\n filename,\n names: [\"auth\", \"prerender\", \"revalidate\", \"stream\"],\n });\n}\n\nexport function isStreamRouteSource(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"stream\"] });\n}\n\nexport function mayUseAwaitBoundarySource(code: string): boolean {\n return collectJsxComponentRootNames({ code }).includes(\"Await\");\n}\n\nexport function routeClosureMayUseAwaitBoundary(options: {\n filename: string;\n files: RouteSourceLookup;\n projectRoot: string;\n seen?: Set<string> | undefined;\n source: string;\n}): boolean {\n const seen = options.seen ?? new Set<string>();\n if (\n seen.has(options.filename) ||\n hasModuleDirective({ code: options.source, directive: \"use client\" })\n ) {\n return false;\n }\n\n seen.add(options.filename);\n\n try {\n if (mayUseAwaitBoundarySource(options.source)) {\n return true;\n }\n\n const sourceFilename = sourceFilenameForCompiler(options.projectRoot, options.filename);\n const jsxComponentRoots = new Set(\n collectJsxComponentRootNames({\n code: options.source,\n filename: sourceFilename,\n }),\n );\n\n for (const reference of collectStaticImportReferences({\n code: options.source,\n filename: sourceFilename,\n })) {\n if (!isRenderedStaticImportReference(reference, jsxComponentRoots)) {\n continue;\n }\n\n const resolved = resolveLocalSourceImport(options.files, options.filename, reference.source);\n\n if (resolved === undefined) {\n continue;\n }\n\n if (\n routeClosureMayUseAwaitBoundary({\n filename: resolved.filename,\n files: options.files,\n projectRoot: options.projectRoot,\n seen,\n source: resolved.source,\n })\n ) {\n return true;\n }\n }\n\n return false;\n } finally {\n seen.delete(options.filename);\n }\n}\n\nexport function hasPrerenderExport(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"prerender\"] });\n}\n\nexport function hasGenerateStaticParamsExport(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"generateStaticParams\"] });\n}\n\nexport function hasLoaderExport(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"loader\"] });\n}\n\nfunction demoteRouteHelperExports(\n code: string,\n preservedExportNames: ReadonlySet<string> = routeRenderExportNames,\n filename?: string | undefined,\n): string {\n const helperNames = collectTopLevelValueExportNames({ code, filename })\n .filter((name) => !preservedExportNames.has(name) && startsLowercase(name));\n\n return helperNames.length === 0\n ? code\n : demoteTopLevelExportDeclarations({ code, filename, names: helperNames });\n}\n\nfunction startsLowercase(value: string): boolean {\n return /^[a-z]/.test(value);\n}\n\nfunction isRenderedStaticImportReference(\n reference: StaticImportReference,\n jsxComponentRoots: ReadonlySet<string>,\n): boolean {\n return reference.localNames.some((localName) => jsxComponentRoots.has(localName));\n}\n\nfunction resolveLocalSourceImport(\n files: RouteSourceLookup,\n importer: string,\n specifier: string,\n): { filename: string; source: string } | undefined {\n if (!specifier.startsWith(\".\")) {\n return undefined;\n }\n\n const base = join(dirname(importer), specifier);\n\n for (const candidate of sourceModuleCandidates(base)) {\n const source = readRouteSourceLookup(files, candidate);\n if (source !== undefined) {\n return { filename: candidate, source };\n }\n }\n\n return undefined;\n}\n\ntype RouteSourceLookup = Record<string, string> | ((file: string) => string | undefined);\n\nfunction readRouteSourceLookup(files: RouteSourceLookup, file: string): string | undefined {\n return typeof files === \"function\" ? files(file) : files[file];\n}\n\nfunction sourceFilenameForCompiler(projectRoot: string, filename: string): string {\n return isAbsolute(filename) ? filename : join(projectRoot, filename);\n}\n"]}
1
+ {"version":3,"file":"route-source.js","sourceRoot":"","sources":["../src/route-source.ts"],"names":[],"mappings":"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","sourcesContent":["import { dirname, isAbsolute, join } from \"node:path\";\nimport {\n collectIdentifierReferenceNames,\n collectFormActionExpressionReferences,\n collectTopLevelValueExportNames,\n collectJsxComponentRootNames,\n collectStaticImportReferences,\n demoteTopLevelExportDeclarations,\n hasModuleDirective,\n hasTopLevelExportDeclaration,\n stripTopLevelExportDeclarations,\n stripUnusedStaticValueImports,\n} from \"@reckona/mreact-compiler\";\nimport type { StaticImportReference } from \"@reckona/mreact-compiler\";\nimport { sourceModuleCandidates } from \"./source-modules.js\";\n\nconst routeModuleExportNames = [\n \"auth\",\n \"generateStaticParams\",\n \"loader\",\n \"middleware\",\n \"prerender\",\n \"revalidate\",\n \"stream\",\n] as const;\nconst routeClientOnlyExportNames = [\n ...routeModuleExportNames,\n \"generateMetadata\",\n \"metadata\",\n] as const;\nconst routeRequestRenderExportNames = [\"default\", \"slots\"] as const;\nconst routeRenderExportNames = new Set<string>([\"default\", \"slots\"]);\nconst routeRequestExportNames = new Set<string>([\n ...routeClientOnlyExportNames,\n \"generateMetadata\",\n \"metadata\",\n]);\nconst routeLoaderOnlyExportNames = new Set<string>([\"loader\"]);\nconst routeMetadataOnlyExportNames = new Set<string>([\"generateMetadata\", \"metadata\"]);\n\nexport function stripRouteModuleExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(stripTopLevelExportDeclarations({\n code,\n filename,\n names: routeModuleExportNames,\n }), routeRenderExportNames, filename);\n}\n\nexport function stripRouteClientOnlyExports(code: string, filename?: string | undefined): string {\n return stripUnusedStaticValueImports({\n code: demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: routeClientOnlyExportNames,\n }),\n routeRenderExportNames,\n filename,\n ),\n filename,\n });\n}\n\nexport function stripRouteClientSource(input: {\n code: string;\n filename?: string | undefined;\n}): string {\n return stripRouteClientFormActionExpressions({\n code: stripRouteClientOnlyExports(input.code, input.filename),\n filename: input.filename,\n });\n}\n\nexport function stripRouteClientFormActionExpressions(input: {\n code: string;\n filename?: string | undefined;\n}): string {\n const references = collectFormActionExpressionReferences(input);\n let code = input.code;\n\n for (const reference of [...references].reverse()) {\n code = `${code.slice(0, reference.expressionStart)}undefined${code.slice(reference.expressionEnd)}`;\n }\n\n return code;\n}\n\nexport function stripRouteBuildExports(code: string, filename?: string | undefined): string {\n return stripRouteClientOnlyExports(code, filename);\n}\n\nexport function stripRouteRequestOnlyExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: routeRequestRenderExportNames,\n }),\n routeRequestExportNames,\n filename,\n );\n}\n\nexport function stripRouteLoaderOnlyExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: [\"auth\", \"default\", \"generateMetadata\", \"generateStaticParams\", \"metadata\", \"middleware\", \"prerender\", \"revalidate\", \"slots\", \"stream\"],\n }),\n routeLoaderOnlyExportNames,\n filename,\n );\n}\n\nexport function stripRouteMetadataOnlyExports(code: string, filename?: string | undefined): string {\n return demoteRouteHelperExports(\n stripTopLevelExportDeclarations({\n code,\n filename,\n names: [\"auth\", \"default\", \"generateStaticParams\", \"loader\", \"middleware\", \"prerender\", \"revalidate\", \"slots\", \"stream\"],\n }),\n routeMetadataOnlyExportNames,\n filename,\n );\n}\n\nexport function stripRouteConfigExports(code: string, filename?: string | undefined): string {\n return stripTopLevelExportDeclarations({\n code,\n filename,\n names: [\"auth\", \"prerender\", \"revalidate\", \"stream\"],\n });\n}\n\nexport function isStreamRouteSource(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"stream\"] });\n}\n\nexport function mayUseAwaitBoundarySource(code: string): boolean {\n return collectJsxComponentRootNames({ code }).includes(\"Await\");\n}\n\nexport function routeClosureMayUseAwaitBoundary(options: {\n filename: string;\n files: RouteSourceLookup;\n projectRoot: string;\n seen?: Set<string> | undefined;\n source: string;\n}): boolean {\n const seen = options.seen ?? new Set<string>();\n if (\n seen.has(options.filename) ||\n hasModuleDirective({ code: options.source, directive: \"use client\" })\n ) {\n return false;\n }\n\n seen.add(options.filename);\n\n try {\n if (mayUseAwaitBoundarySource(options.source)) {\n return true;\n }\n\n const sourceFilename = sourceFilenameForCompiler(options.projectRoot, options.filename);\n const jsxComponentRoots = new Set(\n collectJsxComponentRootNames({\n code: options.source,\n filename: sourceFilename,\n }),\n );\n\n for (const reference of collectStaticImportReferences({\n code: options.source,\n filename: sourceFilename,\n })) {\n if (!isRenderedStaticImportReference(reference, jsxComponentRoots)) {\n continue;\n }\n\n const resolved = resolveLocalSourceImport(options.files, options.filename, reference.source);\n\n if (resolved === undefined) {\n continue;\n }\n\n if (\n routeClosureMayUseAwaitBoundary({\n filename: resolved.filename,\n files: options.files,\n projectRoot: options.projectRoot,\n seen,\n source: resolved.source,\n })\n ) {\n return true;\n }\n }\n\n return false;\n } finally {\n seen.delete(options.filename);\n }\n}\n\nconst REQUEST_INPUT_IDENTIFIERS = new Set([\"fetch\", \"request\", \"Request\"]);\n\n/**\n * Conservatively detects route closures that may consume Request inputs which\n * are not represented by the shared route cache key.\n *\n * This deliberately over-approximates: a false positive disables shared HTML\n * reuse, while a false negative can disclose one request's rendered values to\n * another. Local server imports are traversed so helpers that reconstruct a\n * Request from its internal slots are covered before cache lookup.\n */\nexport function routeClosureMayUseRequestInput(options: {\n filename: string;\n files: RouteSourceLookup;\n projectRoot: string;\n seen?: Set<string> | undefined;\n source: string;\n}): boolean {\n const seen = options.seen ?? new Set<string>();\n if (seen.has(options.filename)) {\n return false;\n }\n\n seen.add(options.filename);\n\n try {\n if (hasModuleDirective({ code: options.source, directive: \"use client\" })) {\n return false;\n }\n\n const sourceFilename = sourceFilenameForCompiler(options.projectRoot, options.filename);\n if (\n collectIdentifierReferenceNames({\n code: options.source,\n filename: sourceFilename,\n }).some((name) => REQUEST_INPUT_IDENTIFIERS.has(name))\n ) {\n return true;\n }\n\n for (const reference of collectStaticImportReferences({\n code: options.source,\n filename: sourceFilename,\n })) {\n const resolved = resolveLocalSourceImport(options.files, options.filename, reference.source);\n\n if (\n resolved !== undefined &&\n routeClosureMayUseRequestInput({\n filename: resolved.filename,\n files: options.files,\n projectRoot: options.projectRoot,\n seen,\n source: resolved.source,\n })\n ) {\n return true;\n }\n }\n\n return false;\n } catch {\n // An analysis parser mismatch must not turn an unknown route into a shared\n // cache candidate. The normal compiler still reports actual source errors.\n return true;\n } finally {\n seen.delete(options.filename);\n }\n}\n\nexport function hasPrerenderExport(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"prerender\"] });\n}\n\nexport function hasGenerateStaticParamsExport(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"generateStaticParams\"] });\n}\n\nexport function hasLoaderExport(code: string, filename?: string | undefined): boolean {\n return hasTopLevelExportDeclaration({ code, filename, names: [\"loader\"] });\n}\n\nfunction demoteRouteHelperExports(\n code: string,\n preservedExportNames: ReadonlySet<string> = routeRenderExportNames,\n filename?: string | undefined,\n): string {\n const helperNames = collectTopLevelValueExportNames({ code, filename })\n .filter((name) => !preservedExportNames.has(name) && startsLowercase(name));\n\n return helperNames.length === 0\n ? code\n : demoteTopLevelExportDeclarations({ code, filename, names: helperNames });\n}\n\nfunction startsLowercase(value: string): boolean {\n return /^[a-z]/.test(value);\n}\n\nfunction isRenderedStaticImportReference(\n reference: StaticImportReference,\n jsxComponentRoots: ReadonlySet<string>,\n): boolean {\n return reference.localNames.some((localName) => jsxComponentRoots.has(localName));\n}\n\nfunction resolveLocalSourceImport(\n files: RouteSourceLookup,\n importer: string,\n specifier: string,\n): { filename: string; source: string } | undefined {\n if (!specifier.startsWith(\".\")) {\n return undefined;\n }\n\n const base = join(dirname(importer), specifier);\n\n for (const candidate of sourceModuleCandidates(base)) {\n const source = readRouteSourceLookup(files, candidate);\n if (source !== undefined) {\n return { filename: candidate, source };\n }\n }\n\n return undefined;\n}\n\ntype RouteSourceLookup = Record<string, string> | ((file: string) => string | undefined);\n\nfunction readRouteSourceLookup(files: RouteSourceLookup, file: string): string | undefined {\n return typeof files === \"function\" ? files(file) : files[file];\n}\n\nfunction sourceFilenameForCompiler(projectRoot: string, filename: string): string {\n return isAbsolute(filename) ? filename : join(projectRoot, filename);\n}\n"]}
@@ -3,4 +3,20 @@ export declare function routeSecurityHeaders(options: {
3
3
  request: Request;
4
4
  security: RouteSecurityHeaders | undefined;
5
5
  }): Record<string, string>;
6
+ /**
7
+ * Returns the configured Strict-Transport-Security value regardless of scheme.
8
+ *
9
+ * `routeSecurityHeaders` only emits the header for secure requests, so callers
10
+ * that persist a response across requests need the configured value on its own:
11
+ * the scheme of the request that happened to produce the response must not
12
+ * decide what later requests receive.
13
+ *
14
+ * An invalid value yields `undefined` rather than throwing. This runs on every
15
+ * render that may be cached, including plain ones that would never emit the
16
+ * header, and reporting the configuration error is `routeSecurityHeaders`'s
17
+ * job on the request that actually emits it.
18
+ */
19
+ export declare function configuredHstsHeader(security: RouteSecurityHeaders | undefined): string | undefined;
20
+ /** Returns whether HSTS is configured but cannot be serialized safely. */
21
+ export declare function hasInvalidConfiguredHsts(security: RouteSecurityHeaders | undefined): boolean;
6
22
  //# sourceMappingURL=security-headers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQvD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC5C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA+CzB"}
1
+ {"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQvD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC5C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA+CzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAUpB;AAED,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,GAAG,OAAO,CAW5F"}
@@ -44,6 +44,43 @@ export function routeSecurityHeaders(options) {
44
44
  }
45
45
  return headers;
46
46
  }
47
+ /**
48
+ * Returns the configured Strict-Transport-Security value regardless of scheme.
49
+ *
50
+ * `routeSecurityHeaders` only emits the header for secure requests, so callers
51
+ * that persist a response across requests need the configured value on its own:
52
+ * the scheme of the request that happened to produce the response must not
53
+ * decide what later requests receive.
54
+ *
55
+ * An invalid value yields `undefined` rather than throwing. This runs on every
56
+ * render that may be cached, including plain ones that would never emit the
57
+ * header, and reporting the configuration error is `routeSecurityHeaders`'s
58
+ * job on the request that actually emits it.
59
+ */
60
+ export function configuredHstsHeader(security) {
61
+ if (security?.hsts === undefined || security.hsts === false || security.hsts === null) {
62
+ return undefined;
63
+ }
64
+ try {
65
+ return serializeHsts(security.hsts);
66
+ }
67
+ catch {
68
+ return undefined;
69
+ }
70
+ }
71
+ /** Returns whether HSTS is configured but cannot be serialized safely. */
72
+ export function hasInvalidConfiguredHsts(security) {
73
+ if (security?.hsts === undefined || security.hsts === false || security.hsts === null) {
74
+ return false;
75
+ }
76
+ try {
77
+ serializeHsts(security.hsts);
78
+ return false;
79
+ }
80
+ catch {
81
+ return true;
82
+ }
83
+ }
47
84
  function serializeHsts(hsts) {
48
85
  if (hsts === false) {
49
86
  throw new TypeError("Invalid security header value for hsts.");
@@ -1 +1 @@
1
- {"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RouteSecurityHeaders } from \"./types.js\";\n\nconst DEFAULT_SECURITY_HEADERS = Object.freeze({\n \"permissions-policy\": \"camera=(), microphone=(), geolocation=()\",\n \"referrer-policy\": \"strict-origin-when-cross-origin\",\n \"x-content-type-options\": \"nosniff\",\n});\n\nexport function routeSecurityHeaders(options: {\n request: Request;\n security: RouteSecurityHeaders | undefined;\n}): Record<string, string> {\n const headers: Record<string, string> = { ...DEFAULT_SECURITY_HEADERS };\n const security = options.security;\n\n if (security?.contentTypeOptions === null) {\n delete headers[\"x-content-type-options\"];\n } else {\n headers[\"x-content-type-options\"] = validateHeaderValue(\n security?.contentTypeOptions ?? \"nosniff\",\n );\n }\n\n if (security?.referrerPolicy === null) {\n delete headers[\"referrer-policy\"];\n } else {\n headers[\"referrer-policy\"] = validateHeaderValue(\n security?.referrerPolicy ?? \"strict-origin-when-cross-origin\",\n );\n }\n\n if (security?.permissionsPolicy === null) {\n delete headers[\"permissions-policy\"];\n } else {\n const permissionsPolicy = serializePermissionsPolicy(security?.permissionsPolicy);\n if (permissionsPolicy === undefined) {\n delete headers[\"permissions-policy\"];\n } else {\n headers[\"permissions-policy\"] = permissionsPolicy;\n }\n }\n\n if (security?.frameOptions === null) {\n delete headers[\"x-frame-options\"];\n } else if (security?.frameOptions !== undefined) {\n headers[\"x-frame-options\"] = validateHeaderValue(security.frameOptions);\n }\n\n if (\n options.request.url.startsWith(\"https://\") &&\n security?.hsts !== undefined &&\n security.hsts !== false &&\n security.hsts !== null\n ) {\n headers[\"strict-transport-security\"] = serializeHsts(security.hsts);\n }\n\n return headers;\n}\n\nfunction serializeHsts(hsts: NonNullable<RouteSecurityHeaders[\"hsts\"]>): string {\n if (hsts === false) {\n throw new TypeError(\"Invalid security header value for hsts.\");\n }\n\n const maxAge = Math.trunc(hsts.maxAge);\n if (!Number.isFinite(maxAge) || maxAge < 0) {\n throw new TypeError(\"Invalid security header value for hsts.maxAge.\");\n }\n\n const parts = [`max-age=${maxAge}`];\n if (hsts.includeSubDomains === true) {\n parts.push(\"includeSubDomains\");\n }\n if (hsts.preload === true) {\n parts.push(\"preload\");\n }\n\n return parts.join(\"; \");\n}\n\nfunction serializePermissionsPolicy(\n policy: NonNullable<RouteSecurityHeaders[\"permissionsPolicy\"]> | undefined,\n): string | undefined {\n if (policy === undefined) {\n return DEFAULT_SECURITY_HEADERS[\"permissions-policy\"];\n }\n\n const directives: string[] = [];\n for (const [directive, allowlist] of Object.entries(policy)) {\n if (allowlist === null || allowlist === undefined) {\n continue;\n }\n\n validateToken(directive, \"permissionsPolicy directive\");\n for (const value of allowlist) {\n validatePermissionAllowlistValue(value);\n }\n directives.push(`${directive}=(${allowlist.join(\" \")})`);\n }\n\n return directives.length === 0 ? undefined : directives.join(\", \");\n}\n\nfunction validateHeaderValue(value: string): string {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code <= 0x1f || code === 0x7f) {\n throw new TypeError(`Invalid security header value: ${JSON.stringify(value)}`);\n }\n }\n\n return value;\n}\n\nfunction validateToken(value: string, label: string): void {\n if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(value)) {\n throw new TypeError(`Invalid security header value for ${label}: ${JSON.stringify(value)}`);\n }\n}\n\nfunction validatePermissionAllowlistValue(value: string): void {\n if (value === \"self\" || value === \"*\" || /^[A-Za-z][A-Za-z0-9+.-]*:$/.test(value)) {\n return;\n }\n\n if (/^https:\\/\\/[A-Za-z0-9.-]+(?::[0-9]+)?$/.test(value)) {\n return;\n }\n\n throw new TypeError(\n `Invalid security header value for permissionsPolicy allowlist: ${JSON.stringify(value)}`,\n );\n}\n"]}
1
+ {"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RouteSecurityHeaders } from \"./types.js\";\n\nconst DEFAULT_SECURITY_HEADERS = Object.freeze({\n \"permissions-policy\": \"camera=(), microphone=(), geolocation=()\",\n \"referrer-policy\": \"strict-origin-when-cross-origin\",\n \"x-content-type-options\": \"nosniff\",\n});\n\nexport function routeSecurityHeaders(options: {\n request: Request;\n security: RouteSecurityHeaders | undefined;\n}): Record<string, string> {\n const headers: Record<string, string> = { ...DEFAULT_SECURITY_HEADERS };\n const security = options.security;\n\n if (security?.contentTypeOptions === null) {\n delete headers[\"x-content-type-options\"];\n } else {\n headers[\"x-content-type-options\"] = validateHeaderValue(\n security?.contentTypeOptions ?? \"nosniff\",\n );\n }\n\n if (security?.referrerPolicy === null) {\n delete headers[\"referrer-policy\"];\n } else {\n headers[\"referrer-policy\"] = validateHeaderValue(\n security?.referrerPolicy ?? \"strict-origin-when-cross-origin\",\n );\n }\n\n if (security?.permissionsPolicy === null) {\n delete headers[\"permissions-policy\"];\n } else {\n const permissionsPolicy = serializePermissionsPolicy(security?.permissionsPolicy);\n if (permissionsPolicy === undefined) {\n delete headers[\"permissions-policy\"];\n } else {\n headers[\"permissions-policy\"] = permissionsPolicy;\n }\n }\n\n if (security?.frameOptions === null) {\n delete headers[\"x-frame-options\"];\n } else if (security?.frameOptions !== undefined) {\n headers[\"x-frame-options\"] = validateHeaderValue(security.frameOptions);\n }\n\n if (\n options.request.url.startsWith(\"https://\") &&\n security?.hsts !== undefined &&\n security.hsts !== false &&\n security.hsts !== null\n ) {\n headers[\"strict-transport-security\"] = serializeHsts(security.hsts);\n }\n\n return headers;\n}\n\n/**\n * Returns the configured Strict-Transport-Security value regardless of scheme.\n *\n * `routeSecurityHeaders` only emits the header for secure requests, so callers\n * that persist a response across requests need the configured value on its own:\n * the scheme of the request that happened to produce the response must not\n * decide what later requests receive.\n *\n * An invalid value yields `undefined` rather than throwing. This runs on every\n * render that may be cached, including plain ones that would never emit the\n * header, and reporting the configuration error is `routeSecurityHeaders`'s\n * job on the request that actually emits it.\n */\nexport function configuredHstsHeader(\n security: RouteSecurityHeaders | undefined,\n): string | undefined {\n if (security?.hsts === undefined || security.hsts === false || security.hsts === null) {\n return undefined;\n }\n\n try {\n return serializeHsts(security.hsts);\n } catch {\n return undefined;\n }\n}\n\n/** Returns whether HSTS is configured but cannot be serialized safely. */\nexport function hasInvalidConfiguredHsts(security: RouteSecurityHeaders | undefined): boolean {\n if (security?.hsts === undefined || security.hsts === false || security.hsts === null) {\n return false;\n }\n\n try {\n serializeHsts(security.hsts);\n return false;\n } catch {\n return true;\n }\n}\n\nfunction serializeHsts(hsts: NonNullable<RouteSecurityHeaders[\"hsts\"]>): string {\n if (hsts === false) {\n throw new TypeError(\"Invalid security header value for hsts.\");\n }\n\n const maxAge = Math.trunc(hsts.maxAge);\n if (!Number.isFinite(maxAge) || maxAge < 0) {\n throw new TypeError(\"Invalid security header value for hsts.maxAge.\");\n }\n\n const parts = [`max-age=${maxAge}`];\n if (hsts.includeSubDomains === true) {\n parts.push(\"includeSubDomains\");\n }\n if (hsts.preload === true) {\n parts.push(\"preload\");\n }\n\n return parts.join(\"; \");\n}\n\nfunction serializePermissionsPolicy(\n policy: NonNullable<RouteSecurityHeaders[\"permissionsPolicy\"]> | undefined,\n): string | undefined {\n if (policy === undefined) {\n return DEFAULT_SECURITY_HEADERS[\"permissions-policy\"];\n }\n\n const directives: string[] = [];\n for (const [directive, allowlist] of Object.entries(policy)) {\n if (allowlist === null || allowlist === undefined) {\n continue;\n }\n\n validateToken(directive, \"permissionsPolicy directive\");\n for (const value of allowlist) {\n validatePermissionAllowlistValue(value);\n }\n directives.push(`${directive}=(${allowlist.join(\" \")})`);\n }\n\n return directives.length === 0 ? undefined : directives.join(\", \");\n}\n\nfunction validateHeaderValue(value: string): string {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code <= 0x1f || code === 0x7f) {\n throw new TypeError(`Invalid security header value: ${JSON.stringify(value)}`);\n }\n }\n\n return value;\n}\n\nfunction validateToken(value: string, label: string): void {\n if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(value)) {\n throw new TypeError(`Invalid security header value for ${label}: ${JSON.stringify(value)}`);\n }\n}\n\nfunction validatePermissionAllowlistValue(value: string): void {\n if (value === \"self\" || value === \"*\" || /^[A-Za-z][A-Za-z0-9+.-]*:$/.test(value)) {\n return;\n }\n\n if (/^https:\\/\\/[A-Za-z0-9.-]+(?::[0-9]+)?$/.test(value)) {\n return;\n }\n\n throw new TypeError(\n `Invalid security header value for permissionsPolicy allowlist: ${JSON.stringify(value)}`,\n );\n}\n"]}
package/dist/serve.d.ts CHANGED
@@ -89,6 +89,13 @@ export interface StartServerOptions {
89
89
  serverActions?: AppRouterServerActionOptions | undefined;
90
90
  sinkStrategy?: ResponseSinkStrategy;
91
91
  onUpgrade?: HttpUpgradeHandler | undefined;
92
+ /**
93
+ * Trusts the first `X-Forwarded-Proto` value when the socket is not TLS.
94
+ *
95
+ * Defaults to `false`. Enable only behind a proxy that overwrites the header
96
+ * and prevents untrusted clients from reaching the Node listener directly.
97
+ */
98
+ trustForwardedProto?: boolean | undefined;
92
99
  }
93
100
  export declare function resolveRequestHost(options: {
94
101
  allowedHosts?: readonly string[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}