vinext 0.0.47 → 0.0.48

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 (263) hide show
  1. package/README.md +1 -1
  2. package/dist/build/layout-classification.js +3 -1
  3. package/dist/build/layout-classification.js.map +1 -1
  4. package/dist/build/prerender.js +10 -10
  5. package/dist/build/prerender.js.map +1 -1
  6. package/dist/build/report.d.ts +8 -4
  7. package/dist/build/report.js +17 -7
  8. package/dist/build/report.js.map +1 -1
  9. package/dist/build/run-prerender.d.ts +5 -0
  10. package/dist/build/run-prerender.js +4 -1
  11. package/dist/build/run-prerender.js.map +1 -1
  12. package/dist/build/server-manifest.js +2 -7
  13. package/dist/build/server-manifest.js.map +1 -1
  14. package/dist/build/standalone.js +3 -5
  15. package/dist/build/standalone.js.map +1 -1
  16. package/dist/check.js +45 -29
  17. package/dist/check.js.map +1 -1
  18. package/dist/cli-args.d.ts +3 -1
  19. package/dist/cli-args.js +18 -1
  20. package/dist/cli-args.js.map +1 -1
  21. package/dist/cli.js +9 -1
  22. package/dist/cli.js.map +1 -1
  23. package/dist/config/config-matchers.js +46 -37
  24. package/dist/config/config-matchers.js.map +1 -1
  25. package/dist/deploy.d.ts +18 -2
  26. package/dist/deploy.js +47 -4
  27. package/dist/deploy.js.map +1 -1
  28. package/dist/entries/app-rsc-entry.js +11 -9
  29. package/dist/entries/app-rsc-entry.js.map +1 -1
  30. package/dist/entries/app-rsc-manifest.js +4 -1
  31. package/dist/entries/app-rsc-manifest.js.map +1 -1
  32. package/dist/entries/pages-client-entry.js +3 -2
  33. package/dist/entries/pages-client-entry.js.map +1 -1
  34. package/dist/entries/pages-server-entry.js +14 -59
  35. package/dist/entries/pages-server-entry.js.map +1 -1
  36. package/dist/entries/runtime-entry-module.d.ts +12 -3
  37. package/dist/entries/runtime-entry-module.js +15 -4
  38. package/dist/entries/runtime-entry-module.js.map +1 -1
  39. package/dist/index.js +12 -7
  40. package/dist/index.js.map +1 -1
  41. package/dist/plugins/og-assets.js +15 -16
  42. package/dist/plugins/og-assets.js.map +1 -1
  43. package/dist/plugins/rsc-client-shim-excludes.d.ts +2 -1
  44. package/dist/plugins/rsc-client-shim-excludes.js +10 -1
  45. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
  46. package/dist/routing/app-route-graph.d.ts +90 -4
  47. package/dist/routing/app-route-graph.js +210 -7
  48. package/dist/routing/app-route-graph.js.map +1 -1
  49. package/dist/routing/app-router.d.ts +15 -3
  50. package/dist/routing/app-router.js +20 -23
  51. package/dist/routing/app-router.js.map +1 -1
  52. package/dist/routing/file-matcher.d.ts +3 -1
  53. package/dist/routing/file-matcher.js +6 -1
  54. package/dist/routing/file-matcher.js.map +1 -1
  55. package/dist/routing/pages-router.js +10 -19
  56. package/dist/routing/pages-router.js.map +1 -1
  57. package/dist/routing/route-matching.d.ts +28 -0
  58. package/dist/routing/route-matching.js +44 -0
  59. package/dist/routing/route-matching.js.map +1 -0
  60. package/dist/routing/route-pattern.js +4 -1
  61. package/dist/routing/route-pattern.js.map +1 -1
  62. package/dist/routing/route-trie.d.ts +8 -0
  63. package/dist/routing/route-trie.js +12 -1
  64. package/dist/routing/route-trie.js.map +1 -1
  65. package/dist/routing/route-validation.js +3 -4
  66. package/dist/routing/route-validation.js.map +1 -1
  67. package/dist/routing/utils.d.ts +8 -1
  68. package/dist/routing/utils.js +25 -2
  69. package/dist/routing/utils.js.map +1 -1
  70. package/dist/server/app-browser-entry.js +66 -49
  71. package/dist/server/app-browser-entry.js.map +1 -1
  72. package/dist/server/app-browser-navigation-controller.d.ts +7 -5
  73. package/dist/server/app-browser-navigation-controller.js +43 -35
  74. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  75. package/dist/server/app-browser-state.d.ts +33 -15
  76. package/dist/server/app-browser-state.js +52 -59
  77. package/dist/server/app-browser-state.js.map +1 -1
  78. package/dist/server/app-browser-visible-commit.d.ts +68 -0
  79. package/dist/server/app-browser-visible-commit.js +182 -0
  80. package/dist/server/app-browser-visible-commit.js.map +1 -0
  81. package/dist/server/app-client-reference-preloader.d.ts +15 -0
  82. package/dist/server/app-client-reference-preloader.js +46 -0
  83. package/dist/server/app-client-reference-preloader.js.map +1 -0
  84. package/dist/server/app-elements-wire.d.ts +130 -0
  85. package/dist/server/app-elements-wire.js +205 -0
  86. package/dist/server/app-elements-wire.js.map +1 -0
  87. package/dist/server/app-elements.d.ts +2 -84
  88. package/dist/server/app-elements.js +3 -102
  89. package/dist/server/app-elements.js.map +1 -1
  90. package/dist/server/app-fallback-renderer.d.ts +1 -1
  91. package/dist/server/app-middleware.d.ts +2 -1
  92. package/dist/server/app-middleware.js +34 -11
  93. package/dist/server/app-middleware.js.map +1 -1
  94. package/dist/server/app-page-boundary-render.d.ts +1 -1
  95. package/dist/server/app-page-boundary-render.js +8 -5
  96. package/dist/server/app-page-boundary-render.js.map +1 -1
  97. package/dist/server/app-page-boundary.js +2 -1
  98. package/dist/server/app-page-boundary.js.map +1 -1
  99. package/dist/server/app-page-cache.d.ts +1 -0
  100. package/dist/server/app-page-cache.js +8 -13
  101. package/dist/server/app-page-cache.js.map +1 -1
  102. package/dist/server/app-page-dispatch.d.ts +2 -1
  103. package/dist/server/app-page-dispatch.js +18 -10
  104. package/dist/server/app-page-dispatch.js.map +1 -1
  105. package/dist/server/app-page-element-builder.d.ts +1 -1
  106. package/dist/server/app-page-element-builder.js +8 -5
  107. package/dist/server/app-page-element-builder.js.map +1 -1
  108. package/dist/server/app-page-execution.d.ts +23 -5
  109. package/dist/server/app-page-execution.js +39 -24
  110. package/dist/server/app-page-execution.js.map +1 -1
  111. package/dist/server/app-page-head.js +2 -1
  112. package/dist/server/app-page-head.js.map +1 -1
  113. package/dist/server/app-page-method.js +2 -5
  114. package/dist/server/app-page-method.js.map +1 -1
  115. package/dist/server/app-page-probe.d.ts +1 -1
  116. package/dist/server/app-page-probe.js +5 -1
  117. package/dist/server/app-page-probe.js.map +1 -1
  118. package/dist/server/app-page-render.d.ts +1 -1
  119. package/dist/server/app-page-render.js +38 -3
  120. package/dist/server/app-page-render.js.map +1 -1
  121. package/dist/server/app-page-request.d.ts +0 -1
  122. package/dist/server/app-page-request.js +7 -10
  123. package/dist/server/app-page-request.js.map +1 -1
  124. package/dist/server/app-page-response.js +3 -2
  125. package/dist/server/app-page-response.js.map +1 -1
  126. package/dist/server/app-page-route-wiring.d.ts +5 -2
  127. package/dist/server/app-page-route-wiring.js +15 -12
  128. package/dist/server/app-page-route-wiring.js.map +1 -1
  129. package/dist/server/app-page-stream.d.ts +7 -0
  130. package/dist/server/app-page-stream.js +9 -2
  131. package/dist/server/app-page-stream.js.map +1 -1
  132. package/dist/server/app-prerender-endpoints.js +3 -2
  133. package/dist/server/app-prerender-endpoints.js.map +1 -1
  134. package/dist/server/app-route-handler-cache.js +2 -1
  135. package/dist/server/app-route-handler-cache.js.map +1 -1
  136. package/dist/server/app-route-handler-dispatch.js +6 -5
  137. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  138. package/dist/server/app-route-handler-policy.js +13 -13
  139. package/dist/server/app-route-handler-policy.js.map +1 -1
  140. package/dist/server/app-route-handler-response.js +2 -1
  141. package/dist/server/app-route-handler-response.js.map +1 -1
  142. package/dist/server/app-route-handler-runtime.d.ts +9 -1
  143. package/dist/server/app-route-handler-runtime.js +11 -1
  144. package/dist/server/app-route-handler-runtime.js.map +1 -1
  145. package/dist/server/app-router-entry.js +9 -4
  146. package/dist/server/app-router-entry.js.map +1 -1
  147. package/dist/server/app-rsc-cache-busting.d.ts +34 -0
  148. package/dist/server/app-rsc-cache-busting.js +137 -0
  149. package/dist/server/app-rsc-cache-busting.js.map +1 -0
  150. package/dist/server/app-rsc-handler.js +22 -11
  151. package/dist/server/app-rsc-handler.js.map +1 -1
  152. package/dist/server/app-rsc-request-normalization.d.ts +4 -2
  153. package/dist/server/app-rsc-request-normalization.js +10 -6
  154. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  155. package/dist/server/app-rsc-response-finalizer.js +1 -1
  156. package/dist/server/app-rsc-route-matching.js +8 -4
  157. package/dist/server/app-rsc-route-matching.js.map +1 -1
  158. package/dist/server/app-segment-config.js +4 -0
  159. package/dist/server/app-segment-config.js.map +1 -1
  160. package/dist/server/app-server-action-execution.js +43 -51
  161. package/dist/server/app-server-action-execution.js.map +1 -1
  162. package/dist/server/app-ssr-entry.js +21 -20
  163. package/dist/server/app-ssr-entry.js.map +1 -1
  164. package/dist/server/artifact-compatibility.d.ts +44 -0
  165. package/dist/server/artifact-compatibility.js +82 -0
  166. package/dist/server/artifact-compatibility.js.map +1 -0
  167. package/dist/server/cache-proof.d.ts +200 -0
  168. package/dist/server/cache-proof.js +342 -0
  169. package/dist/server/cache-proof.js.map +1 -0
  170. package/dist/server/dev-origin-check.js +8 -4
  171. package/dist/server/dev-origin-check.js.map +1 -1
  172. package/dist/server/dev-server.js +1 -6
  173. package/dist/server/dev-server.js.map +1 -1
  174. package/dist/server/http-error-responses.d.ts +67 -0
  175. package/dist/server/http-error-responses.js +77 -0
  176. package/dist/server/http-error-responses.js.map +1 -0
  177. package/dist/server/image-optimization.js +2 -1
  178. package/dist/server/image-optimization.js.map +1 -1
  179. package/dist/server/metadata-route-response.js +6 -5
  180. package/dist/server/metadata-route-response.js.map +1 -1
  181. package/dist/server/metadata-routes.d.ts +1 -0
  182. package/dist/server/metadata-routes.js +6 -0
  183. package/dist/server/metadata-routes.js.map +1 -1
  184. package/dist/server/middleware-matcher.js +2 -2
  185. package/dist/server/middleware-matcher.js.map +1 -1
  186. package/dist/server/middleware-response-headers.js +21 -0
  187. package/dist/server/middleware-response-headers.js.map +1 -1
  188. package/dist/server/middleware-runtime.js +3 -3
  189. package/dist/server/middleware-runtime.js.map +1 -1
  190. package/dist/server/navigation-trace.d.ts +33 -0
  191. package/dist/server/navigation-trace.js +35 -0
  192. package/dist/server/navigation-trace.js.map +1 -0
  193. package/dist/server/next-error-digest.d.ts +44 -0
  194. package/dist/server/next-error-digest.js +40 -0
  195. package/dist/server/next-error-digest.js.map +1 -0
  196. package/dist/server/pages-api-route.js +2 -1
  197. package/dist/server/pages-api-route.js.map +1 -1
  198. package/dist/server/pages-node-compat.js +4 -16
  199. package/dist/server/pages-node-compat.js.map +1 -1
  200. package/dist/server/pages-page-response.d.ts +2 -8
  201. package/dist/server/pages-page-response.js +44 -14
  202. package/dist/server/pages-page-response.js.map +1 -1
  203. package/dist/server/prod-server.d.ts +6 -0
  204. package/dist/server/prod-server.js +28 -21
  205. package/dist/server/prod-server.js.map +1 -1
  206. package/dist/server/request-pipeline.d.ts +42 -1
  207. package/dist/server/request-pipeline.js +97 -17
  208. package/dist/server/request-pipeline.js.map +1 -1
  209. package/dist/shims/cache-runtime.d.ts +2 -2
  210. package/dist/shims/cache-runtime.js +3 -6
  211. package/dist/shims/cache-runtime.js.map +1 -1
  212. package/dist/shims/cache.js +3 -5
  213. package/dist/shims/cache.js.map +1 -1
  214. package/dist/shims/fetch-cache.js +2 -3
  215. package/dist/shims/fetch-cache.js.map +1 -1
  216. package/dist/shims/head-state.js +2 -3
  217. package/dist/shims/head-state.js.map +1 -1
  218. package/dist/shims/headers.js +4 -44
  219. package/dist/shims/headers.js.map +1 -1
  220. package/dist/shims/i18n-state.js +2 -3
  221. package/dist/shims/i18n-state.js.map +1 -1
  222. package/dist/shims/internal/als-registry.d.ts +15 -0
  223. package/dist/shims/internal/als-registry.js +55 -0
  224. package/dist/shims/internal/als-registry.js.map +1 -0
  225. package/dist/shims/internal/cookie-serialize.d.ts +46 -0
  226. package/dist/shims/internal/cookie-serialize.js +51 -0
  227. package/dist/shims/internal/cookie-serialize.js.map +1 -0
  228. package/dist/shims/link.js +31 -26
  229. package/dist/shims/link.js.map +1 -1
  230. package/dist/shims/metadata.d.ts +26 -1
  231. package/dist/shims/metadata.js +94 -4
  232. package/dist/shims/metadata.js.map +1 -1
  233. package/dist/shims/navigation-state.js +2 -3
  234. package/dist/shims/navigation-state.js.map +1 -1
  235. package/dist/shims/navigation.d.ts +2 -7
  236. package/dist/shims/navigation.js +44 -36
  237. package/dist/shims/navigation.js.map +1 -1
  238. package/dist/shims/request-context.js +2 -4
  239. package/dist/shims/request-context.js.map +1 -1
  240. package/dist/shims/router-state.js +2 -3
  241. package/dist/shims/router-state.js.map +1 -1
  242. package/dist/shims/router.js +2 -2
  243. package/dist/shims/router.js.map +1 -1
  244. package/dist/shims/server.js +5 -30
  245. package/dist/shims/server.js.map +1 -1
  246. package/dist/shims/slot.d.ts +1 -1
  247. package/dist/shims/slot.js +5 -4
  248. package/dist/shims/slot.js.map +1 -1
  249. package/dist/shims/thenable-params.d.ts +5 -2
  250. package/dist/shims/thenable-params.js +26 -6
  251. package/dist/shims/thenable-params.js.map +1 -1
  252. package/dist/shims/unified-request-context.js +2 -14
  253. package/dist/shims/unified-request-context.js.map +1 -1
  254. package/dist/utils/base-path.d.ts +7 -1
  255. package/dist/utils/base-path.js +12 -1
  256. package/dist/utils/base-path.js.map +1 -1
  257. package/dist/utils/safe-json-file.d.ts +18 -0
  258. package/dist/utils/safe-json-file.js +25 -0
  259. package/dist/utils/safe-json-file.js.map +1 -0
  260. package/dist/utils/text-stream.d.ts +29 -0
  261. package/dist/utils/text-stream.js +66 -0
  262. package/dist/utils/text-stream.js.map +1 -0
  263. package/package.json +5 -5
@@ -0,0 +1,200 @@
1
+ import { AppRouteSemanticIds } from "../routing/app-route-graph.js";
2
+
3
+ //#region src/server/cache-proof.d.ts
4
+ declare const CACHE_PROOF_MODEL_SCHEMA_VERSION = 0;
5
+ type CacheProofModelSchemaVersion = 0;
6
+ type CacheProofRejectionCode = "CP_MODEL_DISABLED" | "CP_DIMENSION_COUNT_EXCEEDED" | "CP_DIMENSION_NAME_MISSING" | "CP_DIMENSION_NAME_TOO_LONG" | "CP_DIMENSION_VALUE_COUNT_EXCEEDED" | "CP_DIMENSION_VALUE_TOO_LONG" | "CP_DIMENSION_VALUES_MISSING" | "CP_ENCODED_VARIANT_TOO_LONG" | "CP_INVALID_VARIANT_BUDGET" | "CP_ROUTE_VARIANT_CEILING_EXCEEDED" | "CP_UNSAFE_PUBLIC_DIMENSION" | "CP_BOUNDARY_OUTCOME_MISMATCH" | "CP_BOUNDARY_OUTCOME_UNKNOWN";
7
+ type CacheProofTraceFieldValue = string | number | boolean | null | readonly string[];
8
+ type CacheProofTraceFields = Readonly<Record<string, CacheProofTraceFieldValue>>;
9
+ type CacheProofBreakerFallbackMode = "renderFresh" | "privateUncacheable";
10
+ type CacheProofFallbackScope = "affectedOutput" | "route";
11
+ type CacheProofBreakerFallback = Readonly<{
12
+ kind: "breakerFallback";
13
+ code: CacheProofRejectionCode;
14
+ mode: CacheProofBreakerFallbackMode;
15
+ scope: CacheProofFallbackScope;
16
+ fields: CacheProofTraceFields;
17
+ }>;
18
+ type CacheVariantBudget = Readonly<{
19
+ maxDimensionCount: number;
20
+ maxDimensionNameLength: number;
21
+ maxDimensionValueLength: number;
22
+ maxEncodedLength: number;
23
+ maxValuesPerDimension: number;
24
+ maxVariantsPerRoute: number;
25
+ }>;
26
+ declare const DEFAULT_CACHE_VARIANT_BUDGET: {
27
+ maxDimensionCount: number;
28
+ maxDimensionNameLength: number;
29
+ maxDimensionValueLength: number;
30
+ maxEncodedLength: number;
31
+ maxValuesPerDimension: number;
32
+ maxVariantsPerRoute: number;
33
+ };
34
+ type CacheVariantDimensionSource = "auth" | "cookie" | "custom" | "draft-mode" | "header" | "interception" | "mounted-slots" | "params" | "route" | "search" | "session";
35
+ type CacheVariantDimensionPrivacy = "internal" | "private" | "public";
36
+ type CacheVariantDimensionInput = Readonly<{
37
+ name: string;
38
+ privacy: CacheVariantDimensionPrivacy;
39
+ source: CacheVariantDimensionSource;
40
+ values: readonly string[];
41
+ }>;
42
+ type CacheVariantDimension = Readonly<{
43
+ encoded: string;
44
+ name: string;
45
+ privacy: CacheVariantDimensionPrivacy;
46
+ source: CacheVariantDimensionSource;
47
+ valueCount: number;
48
+ valueHashes: readonly string[];
49
+ }>;
50
+ type CacheProofOutputScope = Readonly<{
51
+ kind: "app-html";
52
+ renderEpoch: string | null;
53
+ rootBoundaryId: string | null;
54
+ routeId: string;
55
+ }> | Readonly<{
56
+ kind: "app-rsc";
57
+ mountedSlotsFingerprint: string | null;
58
+ renderEpoch: string | null;
59
+ rootBoundaryId: string | null;
60
+ routeId: string;
61
+ }> | Readonly<{
62
+ kind: "layout";
63
+ layoutId: string;
64
+ rootBoundaryId: string | null;
65
+ routeId: string;
66
+ }> | Readonly<{
67
+ kind: "page";
68
+ pageId: string;
69
+ rootBoundaryId: string | null;
70
+ routeId: string;
71
+ }> | Readonly<{
72
+ kind: "route-handler";
73
+ routeHandlerId: string;
74
+ routeId: string;
75
+ }> | Readonly<{
76
+ kind: "slot";
77
+ rootBoundaryId: string | null;
78
+ routeId: string;
79
+ slotId: string;
80
+ }> | Readonly<{
81
+ kind: "template";
82
+ rootBoundaryId: string | null;
83
+ routeId: string;
84
+ templateId: string;
85
+ }>;
86
+ type CacheVariant = Readonly<{
87
+ budget: CacheVariantBudget;
88
+ cacheKey: string;
89
+ dimensions: readonly CacheVariantDimension[];
90
+ encodedLength: number;
91
+ output: CacheProofOutputScope;
92
+ schemaVersion: CacheProofModelSchemaVersion;
93
+ }>;
94
+ type BuildCacheVariantInput = Readonly<{
95
+ budget: CacheVariantBudget;
96
+ dimensions: readonly CacheVariantDimensionInput[];
97
+ existingVariantCount: number;
98
+ output: CacheProofOutputScope;
99
+ }>;
100
+ type BuildCacheVariantResult = Readonly<{
101
+ kind: "variant";
102
+ variant: CacheVariant;
103
+ }> | Readonly<{
104
+ kind: "breakerFallback";
105
+ fallback: CacheProofBreakerFallback;
106
+ }>;
107
+ type AppRouteCacheProofGraphScopeInput = Readonly<{
108
+ ids: AppRouteSemanticIds;
109
+ }>;
110
+ type AppRouteCacheProofGraphScope = Readonly<{
111
+ layoutIds: readonly string[];
112
+ pageId: string | null;
113
+ routeHandlerId: string | null;
114
+ routeId: string;
115
+ slotIds: readonly string[];
116
+ templateIds: readonly string[];
117
+ }>;
118
+ type BoundaryOutcome = Readonly<{
119
+ kind: "error";
120
+ digest?: string;
121
+ }> | Readonly<{
122
+ kind: "forbidden";
123
+ }> | Readonly<{
124
+ kind: "globalError";
125
+ digest?: string;
126
+ }> | Readonly<{
127
+ kind: "notFound";
128
+ }> | Readonly<{
129
+ kind: "redirect";
130
+ location: string;
131
+ status: number;
132
+ }> | Readonly<{
133
+ kind: "success";
134
+ }> | Readonly<{
135
+ kind: "unauthorized";
136
+ }> | Readonly<{
137
+ kind: "unknown";
138
+ }>;
139
+ type BoundaryOutcomeCompatibility = Readonly<{
140
+ kind: "compatible";
141
+ outcome: BoundaryOutcome;
142
+ reason: "CP_BOUNDARY_OUTCOME_MATCH";
143
+ }> | Readonly<{
144
+ candidate: BoundaryOutcome;
145
+ expected: BoundaryOutcome;
146
+ fallback: CacheProofBreakerFallback;
147
+ kind: "incompatible";
148
+ }>;
149
+ type RenderObservationCompleteness = "complete" | "partial" | "unknown";
150
+ type RenderCacheability = "private" | "public" | "uncacheable" | "unknown";
151
+ type RenderRequestApiKind = "connection" | "cookies" | "draftMode" | "headers" | "params" | "searchParams";
152
+ type RenderRequestApiStatus = "notObserved" | "observed" | "unknown";
153
+ type RenderRequestApiObservation = Readonly<{
154
+ kind: RenderRequestApiKind;
155
+ status: RenderRequestApiStatus;
156
+ }>;
157
+ type RenderObservation = Readonly<{
158
+ boundaryOutcome: BoundaryOutcome;
159
+ cacheTags: readonly string[];
160
+ cacheability: RenderCacheability;
161
+ completeness: RenderObservationCompleteness;
162
+ dynamicFetches: readonly string[];
163
+ output: CacheProofOutputScope;
164
+ pathTags: readonly string[];
165
+ requestApis: readonly RenderRequestApiObservation[];
166
+ schemaVersion: CacheProofModelSchemaVersion;
167
+ }>;
168
+ type BuildRenderObservationInput = Readonly<{
169
+ boundaryOutcome: BoundaryOutcome;
170
+ cacheTags: readonly string[];
171
+ cacheability: RenderCacheability;
172
+ completeness: RenderObservationCompleteness;
173
+ dynamicFetches: readonly string[];
174
+ output: CacheProofOutputScope;
175
+ pathTags: readonly string[];
176
+ requestApis: readonly RenderRequestApiObservation[];
177
+ }>;
178
+ type DisabledCacheProofDecision = Readonly<{
179
+ canReuse: false;
180
+ fallback: CacheProofBreakerFallback;
181
+ kind: "disabled";
182
+ observation: RenderObservation;
183
+ variant: CacheVariant;
184
+ }>;
185
+ type CreateDisabledCacheProofDecisionInput = Readonly<{
186
+ observation: RenderObservation;
187
+ variant: CacheVariant;
188
+ }>;
189
+ declare function createAppRouteCacheProofGraphScope(route: AppRouteCacheProofGraphScopeInput): AppRouteCacheProofGraphScope;
190
+ declare function buildCacheVariant(input: BuildCacheVariantInput): BuildCacheVariantResult;
191
+ declare function buildBoundaryOutcomeCompatibility(input: {
192
+ candidate: BoundaryOutcome;
193
+ expected: BoundaryOutcome;
194
+ }): BoundaryOutcomeCompatibility;
195
+ declare function buildRenderObservation(input: BuildRenderObservationInput): RenderObservation;
196
+ declare function hasCompleteNegativeRequestApiProof(observation: RenderObservation, requiredApis: readonly RenderRequestApiKind[]): boolean;
197
+ declare function createDisabledCacheProofDecision(input: CreateDisabledCacheProofDecisionInput): DisabledCacheProofDecision;
198
+ //#endregion
199
+ export { AppRouteCacheProofGraphScope, AppRouteCacheProofGraphScopeInput, BoundaryOutcome, BoundaryOutcomeCompatibility, BuildCacheVariantInput, BuildCacheVariantResult, BuildRenderObservationInput, CACHE_PROOF_MODEL_SCHEMA_VERSION, CacheProofBreakerFallback, CacheProofBreakerFallbackMode, CacheProofFallbackScope, CacheProofModelSchemaVersion, CacheProofOutputScope, CacheProofRejectionCode, CacheProofTraceFieldValue, CacheProofTraceFields, CacheVariant, CacheVariantBudget, CacheVariantDimension, CacheVariantDimensionInput, CacheVariantDimensionPrivacy, CacheVariantDimensionSource, CreateDisabledCacheProofDecisionInput, DEFAULT_CACHE_VARIANT_BUDGET, DisabledCacheProofDecision, RenderCacheability, RenderObservation, RenderObservationCompleteness, RenderRequestApiKind, RenderRequestApiObservation, RenderRequestApiStatus, buildBoundaryOutcomeCompatibility, buildCacheVariant, buildRenderObservation, createAppRouteCacheProofGraphScope, createDisabledCacheProofDecision, hasCompleteNegativeRequestApiProof };
200
+ //# sourceMappingURL=cache-proof.d.ts.map
@@ -0,0 +1,342 @@
1
+ import { fnv1a64 } from "../utils/hash.js";
2
+ //#region src/server/cache-proof.ts
3
+ const CACHE_PROOF_MODEL_SCHEMA_VERSION = 0;
4
+ const DEFAULT_CACHE_VARIANT_BUDGET = {
5
+ maxDimensionCount: 8,
6
+ maxDimensionNameLength: 64,
7
+ maxDimensionValueLength: 256,
8
+ maxEncodedLength: 1024,
9
+ maxValuesPerDimension: 8,
10
+ maxVariantsPerRoute: 64
11
+ };
12
+ const PUBLIC_UNSAFE_DIMENSION_SOURCES = new Set([
13
+ "auth",
14
+ "cookie",
15
+ "draft-mode",
16
+ "header",
17
+ "session"
18
+ ]);
19
+ function buildBreakerFallback(code, fields = {}, mode = "renderFresh", scope = "affectedOutput") {
20
+ return {
21
+ kind: "breakerFallback",
22
+ code,
23
+ mode,
24
+ scope,
25
+ fields
26
+ };
27
+ }
28
+ function sortedUnique(values) {
29
+ return [...new Set(values)].sort();
30
+ }
31
+ function normalizeDimensionName(name) {
32
+ return name.trim().toLowerCase();
33
+ }
34
+ function redactValue(value) {
35
+ return `h:${fnv1a64(value)}`;
36
+ }
37
+ function sortedUniqueRedacted(values) {
38
+ return sortedUnique(sortedUnique(values).map(redactValue));
39
+ }
40
+ function encodeParts(parts) {
41
+ return JSON.stringify(parts);
42
+ }
43
+ function compareDimensions(a, b) {
44
+ return a.source.localeCompare(b.source) || a.name.localeCompare(b.name) || a.privacy.localeCompare(b.privacy);
45
+ }
46
+ function encodeNullable(value) {
47
+ return value;
48
+ }
49
+ function assertNever(value) {
50
+ throw new Error(`Unhandled cache proof variant: ${String(value)}`);
51
+ }
52
+ function encodeOutputScope(output) {
53
+ switch (output.kind) {
54
+ case "app-html": return encodeParts([
55
+ output.kind,
56
+ output.routeId,
57
+ encodeNullable(output.rootBoundaryId),
58
+ encodeNullable(output.renderEpoch)
59
+ ]);
60
+ case "app-rsc": return encodeParts([
61
+ output.kind,
62
+ output.routeId,
63
+ encodeNullable(output.rootBoundaryId),
64
+ encodeNullable(output.renderEpoch),
65
+ encodeNullable(output.mountedSlotsFingerprint)
66
+ ]);
67
+ case "layout": return encodeParts([
68
+ output.kind,
69
+ output.routeId,
70
+ output.layoutId,
71
+ encodeNullable(output.rootBoundaryId)
72
+ ]);
73
+ case "page": return encodeParts([
74
+ output.kind,
75
+ output.routeId,
76
+ output.pageId,
77
+ encodeNullable(output.rootBoundaryId)
78
+ ]);
79
+ case "route-handler": return encodeParts([
80
+ output.kind,
81
+ output.routeId,
82
+ output.routeHandlerId
83
+ ]);
84
+ case "slot": return encodeParts([
85
+ output.kind,
86
+ output.routeId,
87
+ output.slotId,
88
+ encodeNullable(output.rootBoundaryId)
89
+ ]);
90
+ case "template": return encodeParts([
91
+ output.kind,
92
+ output.routeId,
93
+ output.templateId,
94
+ encodeNullable(output.rootBoundaryId)
95
+ ]);
96
+ default: return assertNever(output);
97
+ }
98
+ }
99
+ function validateBudgetNumber(name, value) {
100
+ if (Number.isInteger(value) && value >= 0) return null;
101
+ return buildBreakerFallback("CP_INVALID_VARIANT_BUDGET", { budgetField: name });
102
+ }
103
+ function validateBudget(budget) {
104
+ return validateBudgetNumber("maxDimensionCount", budget.maxDimensionCount) ?? validateBudgetNumber("maxDimensionNameLength", budget.maxDimensionNameLength) ?? validateBudgetNumber("maxDimensionValueLength", budget.maxDimensionValueLength) ?? validateBudgetNumber("maxEncodedLength", budget.maxEncodedLength) ?? validateBudgetNumber("maxValuesPerDimension", budget.maxValuesPerDimension) ?? validateBudgetNumber("maxVariantsPerRoute", budget.maxVariantsPerRoute);
105
+ }
106
+ function buildDimension(input, budget) {
107
+ const name = normalizeDimensionName(input.name);
108
+ if (name.length === 0) return buildBreakerFallback("CP_DIMENSION_NAME_MISSING", { source: input.source });
109
+ if (name.length > budget.maxDimensionNameLength) return buildBreakerFallback("CP_DIMENSION_NAME_TOO_LONG", {
110
+ maxLength: budget.maxDimensionNameLength,
111
+ nameHash: redactValue(name),
112
+ source: input.source
113
+ });
114
+ if (input.privacy === "public" && PUBLIC_UNSAFE_DIMENSION_SOURCES.has(input.source)) return buildBreakerFallback("CP_UNSAFE_PUBLIC_DIMENSION", {
115
+ name,
116
+ source: input.source
117
+ }, "privateUncacheable");
118
+ const values = sortedUnique(input.values);
119
+ if (values.length === 0) return buildBreakerFallback("CP_DIMENSION_VALUES_MISSING", {
120
+ name,
121
+ source: input.source
122
+ });
123
+ if (values.length > budget.maxValuesPerDimension) return buildBreakerFallback("CP_DIMENSION_VALUE_COUNT_EXCEEDED", {
124
+ maxValues: budget.maxValuesPerDimension,
125
+ name,
126
+ source: input.source,
127
+ valueCount: values.length
128
+ });
129
+ for (const value of values) if (value.length > budget.maxDimensionValueLength) return buildBreakerFallback("CP_DIMENSION_VALUE_TOO_LONG", {
130
+ maxLength: budget.maxDimensionValueLength,
131
+ name,
132
+ source: input.source,
133
+ valueHash: redactValue(value)
134
+ });
135
+ const valueHashes = values.map(redactValue);
136
+ return {
137
+ encoded: encodeParts([
138
+ input.source,
139
+ input.privacy,
140
+ name,
141
+ valueHashes
142
+ ]),
143
+ name,
144
+ privacy: input.privacy,
145
+ source: input.source,
146
+ valueCount: valueHashes.length,
147
+ valueHashes
148
+ };
149
+ }
150
+ function isCacheProofBreakerFallback(value) {
151
+ return "code" in value;
152
+ }
153
+ function getDimensionBucket(bySource, source, privacy) {
154
+ const existingByPrivacy = bySource.get(source);
155
+ const byPrivacy = existingByPrivacy ?? /* @__PURE__ */ new Map();
156
+ if (!existingByPrivacy) bySource.set(source, byPrivacy);
157
+ const existingByName = byPrivacy.get(privacy);
158
+ const byName = existingByName ?? /* @__PURE__ */ new Map();
159
+ if (!existingByName) byPrivacy.set(privacy, byName);
160
+ return byName;
161
+ }
162
+ function mergeDimensionInputs(dimensions) {
163
+ const bySource = /* @__PURE__ */ new Map();
164
+ const orderedDimensions = [];
165
+ for (const dimension of dimensions) {
166
+ const name = normalizeDimensionName(dimension.name);
167
+ const bucket = getDimensionBucket(bySource, dimension.source, dimension.privacy);
168
+ const existing = bucket.get(name);
169
+ if (existing) {
170
+ existing.values.push(...dimension.values);
171
+ continue;
172
+ }
173
+ const accumulator = {
174
+ name,
175
+ privacy: dimension.privacy,
176
+ source: dimension.source,
177
+ values: [...dimension.values]
178
+ };
179
+ bucket.set(name, accumulator);
180
+ orderedDimensions.push(accumulator);
181
+ }
182
+ return orderedDimensions;
183
+ }
184
+ function createAppRouteCacheProofGraphScope(route) {
185
+ return {
186
+ routeId: route.ids.route,
187
+ pageId: route.ids.page,
188
+ routeHandlerId: route.ids.routeHandler,
189
+ layoutIds: [...route.ids.layouts],
190
+ templateIds: [...route.ids.templates],
191
+ slotIds: sortedUnique(Object.values(route.ids.slots))
192
+ };
193
+ }
194
+ function buildCacheVariant(input) {
195
+ const budgetFallback = validateBudget(input.budget);
196
+ if (budgetFallback) return {
197
+ kind: "breakerFallback",
198
+ fallback: budgetFallback
199
+ };
200
+ if (input.existingVariantCount >= input.budget.maxVariantsPerRoute) return {
201
+ kind: "breakerFallback",
202
+ fallback: buildBreakerFallback("CP_ROUTE_VARIANT_CEILING_EXCEEDED", {
203
+ existingVariantCount: input.existingVariantCount,
204
+ maxVariantsPerRoute: input.budget.maxVariantsPerRoute,
205
+ routeId: input.output.routeId
206
+ }, "privateUncacheable", "route")
207
+ };
208
+ const dimensionInputs = mergeDimensionInputs(input.dimensions);
209
+ if (dimensionInputs.length > input.budget.maxDimensionCount) return {
210
+ kind: "breakerFallback",
211
+ fallback: buildBreakerFallback("CP_DIMENSION_COUNT_EXCEEDED", {
212
+ dimensionCount: dimensionInputs.length,
213
+ maxDimensionCount: input.budget.maxDimensionCount,
214
+ routeId: input.output.routeId
215
+ })
216
+ };
217
+ const dimensions = [];
218
+ for (const dimensionInput of dimensionInputs) {
219
+ const dimension = buildDimension(dimensionInput, input.budget);
220
+ if (isCacheProofBreakerFallback(dimension)) return {
221
+ kind: "breakerFallback",
222
+ fallback: dimension
223
+ };
224
+ dimensions.push(dimension);
225
+ }
226
+ dimensions.sort(compareDimensions);
227
+ const encoded = [
228
+ `schema:0`,
229
+ encodeOutputScope(input.output),
230
+ ...dimensions.map((dimension) => dimension.encoded)
231
+ ].join("|");
232
+ if (encoded.length > input.budget.maxEncodedLength) return {
233
+ kind: "breakerFallback",
234
+ fallback: buildBreakerFallback("CP_ENCODED_VARIANT_TOO_LONG", {
235
+ encodedHash: redactValue(encoded),
236
+ encodedLength: encoded.length,
237
+ maxEncodedLength: input.budget.maxEncodedLength,
238
+ routeId: input.output.routeId
239
+ })
240
+ };
241
+ return {
242
+ kind: "variant",
243
+ variant: {
244
+ schemaVersion: 0,
245
+ cacheKey: `cp0:${fnv1a64(encoded)}`,
246
+ output: input.output,
247
+ dimensions,
248
+ encodedLength: encoded.length,
249
+ budget: { ...input.budget }
250
+ }
251
+ };
252
+ }
253
+ function boundaryOutcomesMatch(expected, candidate) {
254
+ switch (expected.kind) {
255
+ case "error": return candidate.kind === "error" && (expected.digest ?? "") === (candidate.digest ?? "");
256
+ case "forbidden": return candidate.kind === "forbidden";
257
+ case "globalError": return candidate.kind === "globalError" && (expected.digest ?? "") === (candidate.digest ?? "");
258
+ case "notFound": return candidate.kind === "notFound";
259
+ case "redirect": return candidate.kind === "redirect" && expected.status === candidate.status && expected.location === candidate.location;
260
+ case "success": return candidate.kind === "success";
261
+ case "unauthorized": return candidate.kind === "unauthorized";
262
+ case "unknown": return false;
263
+ default: return assertNever(expected);
264
+ }
265
+ }
266
+ function buildBoundaryOutcomeCompatibility(input) {
267
+ if (input.expected.kind === "unknown" || input.candidate.kind === "unknown") return {
268
+ kind: "incompatible",
269
+ expected: input.expected,
270
+ candidate: input.candidate,
271
+ fallback: buildBreakerFallback("CP_BOUNDARY_OUTCOME_UNKNOWN", {
272
+ candidateKind: input.candidate.kind,
273
+ expectedKind: input.expected.kind
274
+ })
275
+ };
276
+ if (boundaryOutcomesMatch(input.expected, input.candidate)) return {
277
+ kind: "compatible",
278
+ outcome: input.candidate,
279
+ reason: "CP_BOUNDARY_OUTCOME_MATCH"
280
+ };
281
+ return {
282
+ kind: "incompatible",
283
+ expected: input.expected,
284
+ candidate: input.candidate,
285
+ fallback: buildBreakerFallback("CP_BOUNDARY_OUTCOME_MISMATCH", {
286
+ candidateKind: input.candidate.kind,
287
+ expectedKind: input.expected.kind
288
+ })
289
+ };
290
+ }
291
+ function requestApiStatusRank(status) {
292
+ switch (status) {
293
+ case "notObserved": return 0;
294
+ case "unknown": return 1;
295
+ case "observed": return 2;
296
+ default: return assertNever(status);
297
+ }
298
+ }
299
+ function normalizeRequestApiObservations(observations) {
300
+ const byKind = /* @__PURE__ */ new Map();
301
+ for (const observation of observations) {
302
+ const current = byKind.get(observation.kind);
303
+ if (current === void 0 || requestApiStatusRank(observation.status) > requestApiStatusRank(current)) byKind.set(observation.kind, observation.status);
304
+ }
305
+ return [...byKind.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([kind, status]) => ({
306
+ kind,
307
+ status
308
+ }));
309
+ }
310
+ function buildRenderObservation(input) {
311
+ return {
312
+ schemaVersion: 0,
313
+ output: input.output,
314
+ completeness: input.completeness,
315
+ boundaryOutcome: input.boundaryOutcome,
316
+ requestApis: normalizeRequestApiObservations(input.requestApis),
317
+ dynamicFetches: sortedUniqueRedacted(input.dynamicFetches),
318
+ cacheTags: sortedUnique(input.cacheTags),
319
+ pathTags: sortedUnique(input.pathTags),
320
+ cacheability: input.cacheability
321
+ };
322
+ }
323
+ function hasCompleteNegativeRequestApiProof(observation, requiredApis) {
324
+ if (observation.completeness !== "complete") return false;
325
+ const statuses = /* @__PURE__ */ new Map();
326
+ for (const requestApi of observation.requestApis) statuses.set(requestApi.kind, requestApi.status);
327
+ for (const api of requiredApis) if (statuses.get(api) !== "notObserved") return false;
328
+ return true;
329
+ }
330
+ function createDisabledCacheProofDecision(input) {
331
+ return {
332
+ kind: "disabled",
333
+ canReuse: false,
334
+ variant: input.variant,
335
+ observation: input.observation,
336
+ fallback: buildBreakerFallback("CP_MODEL_DISABLED")
337
+ };
338
+ }
339
+ //#endregion
340
+ export { CACHE_PROOF_MODEL_SCHEMA_VERSION, DEFAULT_CACHE_VARIANT_BUDGET, buildBoundaryOutcomeCompatibility, buildCacheVariant, buildRenderObservation, createAppRouteCacheProofGraphScope, createDisabledCacheProofDecision, hasCompleteNegativeRequestApiProof };
341
+
342
+ //# sourceMappingURL=cache-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-proof.js","names":[],"sources":["../../src/server/cache-proof.ts"],"sourcesContent":["import type { AppRouteSemanticIds } from \"../routing/app-route-graph.js\";\nimport { fnv1a64 } from \"../utils/hash.js\";\n\nexport const CACHE_PROOF_MODEL_SCHEMA_VERSION = 0;\nexport type CacheProofModelSchemaVersion = 0;\n\nexport type CacheProofRejectionCode =\n | \"CP_MODEL_DISABLED\"\n | \"CP_DIMENSION_COUNT_EXCEEDED\"\n | \"CP_DIMENSION_NAME_MISSING\"\n | \"CP_DIMENSION_NAME_TOO_LONG\"\n | \"CP_DIMENSION_VALUE_COUNT_EXCEEDED\"\n | \"CP_DIMENSION_VALUE_TOO_LONG\"\n | \"CP_DIMENSION_VALUES_MISSING\"\n | \"CP_ENCODED_VARIANT_TOO_LONG\"\n | \"CP_INVALID_VARIANT_BUDGET\"\n | \"CP_ROUTE_VARIANT_CEILING_EXCEEDED\"\n | \"CP_UNSAFE_PUBLIC_DIMENSION\"\n | \"CP_BOUNDARY_OUTCOME_MISMATCH\"\n | \"CP_BOUNDARY_OUTCOME_UNKNOWN\";\n\nexport type CacheProofTraceFieldValue = string | number | boolean | null | readonly string[];\n\nexport type CacheProofTraceFields = Readonly<Record<string, CacheProofTraceFieldValue>>;\n\nexport type CacheProofBreakerFallbackMode = \"renderFresh\" | \"privateUncacheable\";\nexport type CacheProofFallbackScope = \"affectedOutput\" | \"route\";\n\nexport type CacheProofBreakerFallback = Readonly<{\n kind: \"breakerFallback\";\n code: CacheProofRejectionCode;\n mode: CacheProofBreakerFallbackMode;\n scope: CacheProofFallbackScope;\n fields: CacheProofTraceFields;\n}>;\n\nexport type CacheVariantBudget = Readonly<{\n maxDimensionCount: number;\n maxDimensionNameLength: number;\n maxDimensionValueLength: number;\n maxEncodedLength: number;\n maxValuesPerDimension: number;\n maxVariantsPerRoute: number;\n}>;\n\nexport const DEFAULT_CACHE_VARIANT_BUDGET = {\n maxDimensionCount: 8,\n maxDimensionNameLength: 64,\n maxDimensionValueLength: 256,\n maxEncodedLength: 1024,\n maxValuesPerDimension: 8,\n maxVariantsPerRoute: 64,\n} satisfies CacheVariantBudget;\n\nexport type CacheVariantDimensionSource =\n | \"auth\"\n | \"cookie\"\n | \"custom\"\n | \"draft-mode\"\n | \"header\"\n | \"interception\"\n | \"mounted-slots\"\n | \"params\"\n | \"route\"\n | \"search\"\n | \"session\";\n\nexport type CacheVariantDimensionPrivacy = \"internal\" | \"private\" | \"public\";\n\nexport type CacheVariantDimensionInput = Readonly<{\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n values: readonly string[];\n}>;\n\nexport type CacheVariantDimension = Readonly<{\n encoded: string;\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n valueCount: number;\n valueHashes: readonly string[];\n}>;\n\nexport type CacheProofOutputScope =\n | Readonly<{\n kind: \"app-html\";\n renderEpoch: string | null;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"app-rsc\";\n mountedSlotsFingerprint: string | null;\n renderEpoch: string | null;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"layout\";\n layoutId: string;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"page\";\n pageId: string;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"route-handler\";\n routeHandlerId: string;\n routeId: string;\n }>\n | Readonly<{\n kind: \"slot\";\n rootBoundaryId: string | null;\n routeId: string;\n slotId: string;\n }>\n | Readonly<{\n kind: \"template\";\n rootBoundaryId: string | null;\n routeId: string;\n templateId: string;\n }>;\n\nexport type CacheVariant = Readonly<{\n budget: CacheVariantBudget;\n cacheKey: string;\n dimensions: readonly CacheVariantDimension[];\n encodedLength: number;\n output: CacheProofOutputScope;\n schemaVersion: CacheProofModelSchemaVersion;\n}>;\n\nexport type BuildCacheVariantInput = Readonly<{\n budget: CacheVariantBudget;\n dimensions: readonly CacheVariantDimensionInput[];\n existingVariantCount: number;\n output: CacheProofOutputScope;\n}>;\n\nexport type BuildCacheVariantResult =\n | Readonly<{ kind: \"variant\"; variant: CacheVariant }>\n | Readonly<{ kind: \"breakerFallback\"; fallback: CacheProofBreakerFallback }>;\n\nexport type AppRouteCacheProofGraphScopeInput = Readonly<{\n ids: AppRouteSemanticIds;\n}>;\n\nexport type AppRouteCacheProofGraphScope = Readonly<{\n layoutIds: readonly string[];\n pageId: string | null;\n routeHandlerId: string | null;\n routeId: string;\n slotIds: readonly string[];\n templateIds: readonly string[];\n}>;\n\nexport type BoundaryOutcome =\n | Readonly<{ kind: \"error\"; digest?: string }>\n | Readonly<{ kind: \"forbidden\" }>\n | Readonly<{ kind: \"globalError\"; digest?: string }>\n | Readonly<{ kind: \"notFound\" }>\n | Readonly<{ kind: \"redirect\"; location: string; status: number }>\n | Readonly<{ kind: \"success\" }>\n | Readonly<{ kind: \"unauthorized\" }>\n | Readonly<{ kind: \"unknown\" }>;\n\nexport type BoundaryOutcomeCompatibility =\n | Readonly<{\n kind: \"compatible\";\n outcome: BoundaryOutcome;\n reason: \"CP_BOUNDARY_OUTCOME_MATCH\";\n }>\n | Readonly<{\n candidate: BoundaryOutcome;\n expected: BoundaryOutcome;\n fallback: CacheProofBreakerFallback;\n kind: \"incompatible\";\n }>;\n\nexport type RenderObservationCompleteness = \"complete\" | \"partial\" | \"unknown\";\nexport type RenderCacheability = \"private\" | \"public\" | \"uncacheable\" | \"unknown\";\nexport type RenderRequestApiKind =\n | \"connection\"\n | \"cookies\"\n | \"draftMode\"\n | \"headers\"\n | \"params\"\n | \"searchParams\";\nexport type RenderRequestApiStatus = \"notObserved\" | \"observed\" | \"unknown\";\n\nexport type RenderRequestApiObservation = Readonly<{\n kind: RenderRequestApiKind;\n status: RenderRequestApiStatus;\n}>;\n\nexport type RenderObservation = Readonly<{\n boundaryOutcome: BoundaryOutcome;\n cacheTags: readonly string[];\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n dynamicFetches: readonly string[];\n output: CacheProofOutputScope;\n pathTags: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n schemaVersion: CacheProofModelSchemaVersion;\n}>;\n\nexport type BuildRenderObservationInput = Readonly<{\n boundaryOutcome: BoundaryOutcome;\n cacheTags: readonly string[];\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n dynamicFetches: readonly string[];\n output: CacheProofOutputScope;\n pathTags: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n}>;\n\nexport type DisabledCacheProofDecision = Readonly<{\n canReuse: false;\n fallback: CacheProofBreakerFallback;\n kind: \"disabled\";\n observation: RenderObservation;\n variant: CacheVariant;\n}>;\n\nexport type CreateDisabledCacheProofDecisionInput = Readonly<{\n observation: RenderObservation;\n variant: CacheVariant;\n}>;\n\nconst PUBLIC_UNSAFE_DIMENSION_SOURCES: ReadonlySet<CacheVariantDimensionSource> = new Set([\n \"auth\",\n \"cookie\",\n \"draft-mode\",\n \"header\",\n \"session\",\n]);\n\ntype CacheVariantDimensionAccumulator = {\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n values: string[];\n};\n\ntype DimensionAccumulatorByName = Map<string, CacheVariantDimensionAccumulator>;\ntype DimensionAccumulatorByPrivacy = Map<CacheVariantDimensionPrivacy, DimensionAccumulatorByName>;\ntype DimensionAccumulatorBySource = Map<CacheVariantDimensionSource, DimensionAccumulatorByPrivacy>;\n\nfunction buildBreakerFallback(\n code: CacheProofRejectionCode,\n fields: CacheProofTraceFields = {},\n mode: CacheProofBreakerFallbackMode = \"renderFresh\",\n scope: CacheProofFallbackScope = \"affectedOutput\",\n): CacheProofBreakerFallback {\n return {\n kind: \"breakerFallback\",\n code,\n mode,\n scope,\n fields,\n };\n}\n\nfunction sortedUnique(values: readonly string[]): string[] {\n return [...new Set(values)].sort();\n}\n\nfunction normalizeDimensionName(name: string): string {\n return name.trim().toLowerCase();\n}\n\nfunction redactValue(value: string): string {\n return `h:${fnv1a64(value)}`;\n}\n\nfunction sortedUniqueRedacted(values: readonly string[]): string[] {\n return sortedUnique(sortedUnique(values).map(redactValue));\n}\n\nfunction encodeParts(parts: readonly unknown[]): string {\n return JSON.stringify(parts);\n}\n\nfunction compareDimensions(a: CacheVariantDimension, b: CacheVariantDimension): number {\n return (\n a.source.localeCompare(b.source) ||\n a.name.localeCompare(b.name) ||\n a.privacy.localeCompare(b.privacy)\n );\n}\n\nfunction encodeNullable(value: string | null): string | null {\n return value;\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled cache proof variant: ${String(value)}`);\n}\n\nfunction encodeOutputScope(output: CacheProofOutputScope): string {\n switch (output.kind) {\n case \"app-html\":\n return encodeParts([\n output.kind,\n output.routeId,\n encodeNullable(output.rootBoundaryId),\n encodeNullable(output.renderEpoch),\n ]);\n case \"app-rsc\":\n return encodeParts([\n output.kind,\n output.routeId,\n encodeNullable(output.rootBoundaryId),\n encodeNullable(output.renderEpoch),\n encodeNullable(output.mountedSlotsFingerprint),\n ]);\n case \"layout\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.layoutId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"page\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.pageId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"route-handler\":\n return encodeParts([output.kind, output.routeId, output.routeHandlerId]);\n case \"slot\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.slotId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"template\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.templateId,\n encodeNullable(output.rootBoundaryId),\n ]);\n default:\n return assertNever(output);\n }\n}\n\nfunction validateBudgetNumber(name: string, value: number): CacheProofBreakerFallback | null {\n if (Number.isInteger(value) && value >= 0) return null;\n return buildBreakerFallback(\"CP_INVALID_VARIANT_BUDGET\", {\n budgetField: name,\n });\n}\n\nfunction validateBudget(budget: CacheVariantBudget): CacheProofBreakerFallback | null {\n return (\n validateBudgetNumber(\"maxDimensionCount\", budget.maxDimensionCount) ??\n validateBudgetNumber(\"maxDimensionNameLength\", budget.maxDimensionNameLength) ??\n validateBudgetNumber(\"maxDimensionValueLength\", budget.maxDimensionValueLength) ??\n validateBudgetNumber(\"maxEncodedLength\", budget.maxEncodedLength) ??\n validateBudgetNumber(\"maxValuesPerDimension\", budget.maxValuesPerDimension) ??\n validateBudgetNumber(\"maxVariantsPerRoute\", budget.maxVariantsPerRoute)\n );\n}\n\nfunction buildDimension(\n input: CacheVariantDimensionInput,\n budget: CacheVariantBudget,\n): CacheVariantDimension | CacheProofBreakerFallback {\n const name = normalizeDimensionName(input.name);\n if (name.length === 0) {\n return buildBreakerFallback(\"CP_DIMENSION_NAME_MISSING\", {\n source: input.source,\n });\n }\n if (name.length > budget.maxDimensionNameLength) {\n return buildBreakerFallback(\"CP_DIMENSION_NAME_TOO_LONG\", {\n maxLength: budget.maxDimensionNameLength,\n nameHash: redactValue(name),\n source: input.source,\n });\n }\n if (input.privacy === \"public\" && PUBLIC_UNSAFE_DIMENSION_SOURCES.has(input.source)) {\n return buildBreakerFallback(\n \"CP_UNSAFE_PUBLIC_DIMENSION\",\n {\n name,\n source: input.source,\n },\n \"privateUncacheable\",\n );\n }\n\n const values = sortedUnique(input.values);\n if (values.length === 0) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUES_MISSING\", {\n name,\n source: input.source,\n });\n }\n if (values.length > budget.maxValuesPerDimension) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUE_COUNT_EXCEEDED\", {\n maxValues: budget.maxValuesPerDimension,\n name,\n source: input.source,\n valueCount: values.length,\n });\n }\n for (const value of values) {\n if (value.length > budget.maxDimensionValueLength) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUE_TOO_LONG\", {\n maxLength: budget.maxDimensionValueLength,\n name,\n source: input.source,\n valueHash: redactValue(value),\n });\n }\n }\n\n const valueHashes = values.map(redactValue);\n const encoded = encodeParts([input.source, input.privacy, name, valueHashes]);\n\n return {\n encoded,\n name,\n privacy: input.privacy,\n source: input.source,\n valueCount: valueHashes.length,\n valueHashes,\n };\n}\n\nfunction isCacheProofBreakerFallback(\n value: CacheVariantDimension | CacheProofBreakerFallback,\n): value is CacheProofBreakerFallback {\n return \"code\" in value;\n}\n\nfunction getDimensionBucket(\n bySource: DimensionAccumulatorBySource,\n source: CacheVariantDimensionSource,\n privacy: CacheVariantDimensionPrivacy,\n): DimensionAccumulatorByName {\n const existingByPrivacy = bySource.get(source);\n const byPrivacy = existingByPrivacy ?? new Map();\n if (!existingByPrivacy) {\n bySource.set(source, byPrivacy);\n }\n\n const existingByName = byPrivacy.get(privacy);\n const byName = existingByName ?? new Map();\n if (!existingByName) {\n byPrivacy.set(privacy, byName);\n }\n\n return byName;\n}\n\nfunction mergeDimensionInputs(\n dimensions: readonly CacheVariantDimensionInput[],\n): CacheVariantDimensionInput[] {\n const bySource: DimensionAccumulatorBySource = new Map();\n const orderedDimensions: CacheVariantDimensionAccumulator[] = [];\n\n for (const dimension of dimensions) {\n const name = normalizeDimensionName(dimension.name);\n const bucket = getDimensionBucket(bySource, dimension.source, dimension.privacy);\n const existing = bucket.get(name);\n if (existing) {\n existing.values.push(...dimension.values);\n continue;\n }\n const accumulator = {\n name,\n privacy: dimension.privacy,\n source: dimension.source,\n values: [...dimension.values],\n };\n bucket.set(name, accumulator);\n orderedDimensions.push(accumulator);\n }\n\n return orderedDimensions;\n}\n\nexport function createAppRouteCacheProofGraphScope(\n route: AppRouteCacheProofGraphScopeInput,\n): AppRouteCacheProofGraphScope {\n return {\n routeId: route.ids.route,\n pageId: route.ids.page,\n routeHandlerId: route.ids.routeHandler,\n layoutIds: [...route.ids.layouts],\n templateIds: [...route.ids.templates],\n slotIds: sortedUnique(Object.values(route.ids.slots)),\n };\n}\n\nexport function buildCacheVariant(input: BuildCacheVariantInput): BuildCacheVariantResult {\n const budgetFallback = validateBudget(input.budget);\n if (budgetFallback) {\n return {\n kind: \"breakerFallback\",\n fallback: budgetFallback,\n };\n }\n if (input.existingVariantCount >= input.budget.maxVariantsPerRoute) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\n \"CP_ROUTE_VARIANT_CEILING_EXCEEDED\",\n {\n existingVariantCount: input.existingVariantCount,\n maxVariantsPerRoute: input.budget.maxVariantsPerRoute,\n routeId: input.output.routeId,\n },\n \"privateUncacheable\",\n \"route\",\n ),\n };\n }\n const dimensionInputs = mergeDimensionInputs(input.dimensions);\n if (dimensionInputs.length > input.budget.maxDimensionCount) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\"CP_DIMENSION_COUNT_EXCEEDED\", {\n dimensionCount: dimensionInputs.length,\n maxDimensionCount: input.budget.maxDimensionCount,\n routeId: input.output.routeId,\n }),\n };\n }\n\n const dimensions: CacheVariantDimension[] = [];\n for (const dimensionInput of dimensionInputs) {\n const dimension = buildDimension(dimensionInput, input.budget);\n if (isCacheProofBreakerFallback(dimension)) {\n return {\n kind: \"breakerFallback\",\n fallback: dimension,\n };\n }\n dimensions.push(dimension);\n }\n dimensions.sort(compareDimensions);\n\n const encoded = [\n `schema:${CACHE_PROOF_MODEL_SCHEMA_VERSION}`,\n encodeOutputScope(input.output),\n ...dimensions.map((dimension) => dimension.encoded),\n ].join(\"|\");\n\n if (encoded.length > input.budget.maxEncodedLength) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\"CP_ENCODED_VARIANT_TOO_LONG\", {\n encodedHash: redactValue(encoded),\n encodedLength: encoded.length,\n maxEncodedLength: input.budget.maxEncodedLength,\n routeId: input.output.routeId,\n }),\n };\n }\n\n return {\n kind: \"variant\",\n variant: {\n schemaVersion: CACHE_PROOF_MODEL_SCHEMA_VERSION,\n cacheKey: `cp0:${fnv1a64(encoded)}`,\n output: input.output,\n dimensions,\n encodedLength: encoded.length,\n budget: { ...input.budget },\n },\n };\n}\n\nfunction boundaryOutcomesMatch(expected: BoundaryOutcome, candidate: BoundaryOutcome): boolean {\n switch (expected.kind) {\n case \"error\":\n return candidate.kind === \"error\" && (expected.digest ?? \"\") === (candidate.digest ?? \"\");\n case \"forbidden\":\n return candidate.kind === \"forbidden\";\n case \"globalError\":\n return (\n candidate.kind === \"globalError\" && (expected.digest ?? \"\") === (candidate.digest ?? \"\")\n );\n case \"notFound\":\n return candidate.kind === \"notFound\";\n case \"redirect\":\n return (\n candidate.kind === \"redirect\" &&\n expected.status === candidate.status &&\n expected.location === candidate.location\n );\n case \"success\":\n return candidate.kind === \"success\";\n case \"unauthorized\":\n return candidate.kind === \"unauthorized\";\n case \"unknown\":\n return false;\n default:\n return assertNever(expected);\n }\n}\n\nexport function buildBoundaryOutcomeCompatibility(input: {\n candidate: BoundaryOutcome;\n expected: BoundaryOutcome;\n}): BoundaryOutcomeCompatibility {\n if (input.expected.kind === \"unknown\" || input.candidate.kind === \"unknown\") {\n return {\n kind: \"incompatible\",\n expected: input.expected,\n candidate: input.candidate,\n fallback: buildBreakerFallback(\"CP_BOUNDARY_OUTCOME_UNKNOWN\", {\n candidateKind: input.candidate.kind,\n expectedKind: input.expected.kind,\n }),\n };\n }\n\n if (boundaryOutcomesMatch(input.expected, input.candidate)) {\n return {\n kind: \"compatible\",\n outcome: input.candidate,\n reason: \"CP_BOUNDARY_OUTCOME_MATCH\",\n };\n }\n\n return {\n kind: \"incompatible\",\n expected: input.expected,\n candidate: input.candidate,\n fallback: buildBreakerFallback(\"CP_BOUNDARY_OUTCOME_MISMATCH\", {\n candidateKind: input.candidate.kind,\n expectedKind: input.expected.kind,\n }),\n };\n}\n\nfunction requestApiStatusRank(status: RenderRequestApiStatus): number {\n switch (status) {\n case \"notObserved\":\n return 0;\n case \"unknown\":\n return 1;\n case \"observed\":\n return 2;\n default:\n return assertNever(status);\n }\n}\n\nfunction normalizeRequestApiObservations(\n observations: readonly RenderRequestApiObservation[],\n): RenderRequestApiObservation[] {\n const byKind = new Map<RenderRequestApiKind, RenderRequestApiStatus>();\n for (const observation of observations) {\n const current = byKind.get(observation.kind);\n if (\n current === undefined ||\n requestApiStatusRank(observation.status) > requestApiStatusRank(current)\n ) {\n byKind.set(observation.kind, observation.status);\n }\n }\n\n return [...byKind.entries()]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([kind, status]) => ({ kind, status }));\n}\n\nexport function buildRenderObservation(input: BuildRenderObservationInput): RenderObservation {\n return {\n schemaVersion: CACHE_PROOF_MODEL_SCHEMA_VERSION,\n output: input.output,\n completeness: input.completeness,\n boundaryOutcome: input.boundaryOutcome,\n requestApis: normalizeRequestApiObservations(input.requestApis),\n dynamicFetches: sortedUniqueRedacted(input.dynamicFetches),\n cacheTags: sortedUnique(input.cacheTags),\n pathTags: sortedUnique(input.pathTags),\n cacheability: input.cacheability,\n };\n}\n\nexport function hasCompleteNegativeRequestApiProof(\n observation: RenderObservation,\n requiredApis: readonly RenderRequestApiKind[],\n): boolean {\n if (observation.completeness !== \"complete\") return false;\n\n const statuses = new Map<RenderRequestApiKind, RenderRequestApiStatus>();\n for (const requestApi of observation.requestApis) {\n statuses.set(requestApi.kind, requestApi.status);\n }\n\n for (const api of requiredApis) {\n if (statuses.get(api) !== \"notObserved\") return false;\n }\n return true;\n}\n\nexport function createDisabledCacheProofDecision(\n input: CreateDisabledCacheProofDecisionInput,\n): DisabledCacheProofDecision {\n return {\n kind: \"disabled\",\n canReuse: false,\n variant: input.variant,\n observation: input.observation,\n fallback: buildBreakerFallback(\"CP_MODEL_DISABLED\"),\n };\n}\n"],"mappings":"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"}
@@ -96,12 +96,16 @@ function generateDevOriginCheckCode(allowedDevOrigins) {
96
96
  const __allowedDevOrigins = ${JSON.stringify(allowedDevOrigins ?? [])};
97
97
  const __safeDevHosts = ["localhost", "127.0.0.1", "[::1]"];
98
98
 
99
+ function __forbidden() {
100
+ return new Response("Forbidden", { status: 403, headers: { "Content-Type": "text/plain" } });
101
+ }
102
+
99
103
  function __validateDevRequestOrigin(request) {
100
104
  // Check Sec-Fetch headers (catches <script> tag exfiltration)
101
105
  if (request.headers.get("sec-fetch-mode") === "no-cors" &&
102
106
  request.headers.get("sec-fetch-site") === "cross-site") {
103
107
  console.warn("[vinext] Blocked cross-site no-cors request to " + new URL(request.url).pathname);
104
- return new Response("Forbidden", { status: 403, headers: { "Content-Type": "text/plain" } });
108
+ return __forbidden();
105
109
  }
106
110
 
107
111
  const origin = request.headers.get("origin");
@@ -111,7 +115,7 @@ function __validateDevRequestOrigin(request) {
111
115
  if (origin === "null") {
112
116
  if (!__allowedDevOrigins.includes("null")) {
113
117
  console.warn("[vinext] Blocked request with Origin: null. Add \\"null\\" to allowedDevOrigins to allow sandboxed contexts.");
114
- return new Response("Forbidden", { status: 403, headers: { "Content-Type": "text/plain" } });
118
+ return __forbidden();
115
119
  }
116
120
  return null;
117
121
  }
@@ -120,7 +124,7 @@ function __validateDevRequestOrigin(request) {
120
124
  try {
121
125
  originHostname = new URL(origin).hostname.toLowerCase();
122
126
  } catch {
123
- return new Response("Forbidden", { status: 403, headers: { "Content-Type": "text/plain" } });
127
+ return __forbidden();
124
128
  }
125
129
 
126
130
  // Allow localhost, 127.0.0.1, [::1], and *.localhost
@@ -144,7 +148,7 @@ function __validateDevRequestOrigin(request) {
144
148
  \`[vinext] Blocked cross-origin request from "\${origin}" to \${new URL(request.url).pathname}. \` +
145
149
  \`To allow this origin, add it to allowedDevOrigins in next.config.js.\`
146
150
  );
147
- return new Response("Forbidden", { status: 403, headers: { "Content-Type": "text/plain" } });
151
+ return __forbidden();
148
152
  }
149
153
  `;
150
154
  }