vinext 0.0.0 → 0.0.1

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 (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/build/static-export.d.ts +78 -0
  4. package/dist/build/static-export.d.ts.map +1 -0
  5. package/dist/build/static-export.js +553 -0
  6. package/dist/build/static-export.js.map +1 -0
  7. package/dist/check.d.ts +52 -0
  8. package/dist/check.d.ts.map +1 -0
  9. package/dist/check.js +483 -0
  10. package/dist/check.js.map +1 -0
  11. package/dist/cli.d.ts +15 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +565 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/client/entry.d.ts +2 -0
  16. package/dist/client/entry.d.ts.map +1 -0
  17. package/dist/client/entry.js +85 -0
  18. package/dist/client/entry.js.map +1 -0
  19. package/dist/cloudflare/index.d.ts +8 -0
  20. package/dist/cloudflare/index.d.ts.map +1 -0
  21. package/dist/cloudflare/index.js +8 -0
  22. package/dist/cloudflare/index.js.map +1 -0
  23. package/dist/cloudflare/kv-cache-handler.d.ts +68 -0
  24. package/dist/cloudflare/kv-cache-handler.d.ts.map +1 -0
  25. package/dist/cloudflare/kv-cache-handler.js +304 -0
  26. package/dist/cloudflare/kv-cache-handler.js.map +1 -0
  27. package/dist/cloudflare/tpr.d.ts +78 -0
  28. package/dist/cloudflare/tpr.d.ts.map +1 -0
  29. package/dist/cloudflare/tpr.js +672 -0
  30. package/dist/cloudflare/tpr.js.map +1 -0
  31. package/dist/config/config-matchers.d.ts +106 -0
  32. package/dist/config/config-matchers.d.ts.map +1 -0
  33. package/dist/config/config-matchers.js +499 -0
  34. package/dist/config/config-matchers.js.map +1 -0
  35. package/dist/config/next-config.d.ts +153 -0
  36. package/dist/config/next-config.d.ts.map +1 -0
  37. package/dist/config/next-config.js +274 -0
  38. package/dist/config/next-config.js.map +1 -0
  39. package/dist/deploy.d.ts +87 -0
  40. package/dist/deploy.d.ts.map +1 -0
  41. package/dist/deploy.js +644 -0
  42. package/dist/deploy.js.map +1 -0
  43. package/dist/index.d.ts +156 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +3287 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/init.d.ts +55 -0
  48. package/dist/init.d.ts.map +1 -0
  49. package/dist/init.js +201 -0
  50. package/dist/init.js.map +1 -0
  51. package/dist/routing/app-router.d.ts +96 -0
  52. package/dist/routing/app-router.d.ts.map +1 -0
  53. package/dist/routing/app-router.js +815 -0
  54. package/dist/routing/app-router.js.map +1 -0
  55. package/dist/routing/pages-router.d.ts +52 -0
  56. package/dist/routing/pages-router.d.ts.map +1 -0
  57. package/dist/routing/pages-router.js +239 -0
  58. package/dist/routing/pages-router.js.map +1 -0
  59. package/dist/server/api-handler.d.ts +18 -0
  60. package/dist/server/api-handler.d.ts.map +1 -0
  61. package/dist/server/api-handler.js +169 -0
  62. package/dist/server/api-handler.js.map +1 -0
  63. package/dist/server/app-dev-server.d.ts +42 -0
  64. package/dist/server/app-dev-server.d.ts.map +1 -0
  65. package/dist/server/app-dev-server.js +2718 -0
  66. package/dist/server/app-dev-server.js.map +1 -0
  67. package/dist/server/app-router-entry.d.ts +18 -0
  68. package/dist/server/app-router-entry.d.ts.map +1 -0
  69. package/dist/server/app-router-entry.js +34 -0
  70. package/dist/server/app-router-entry.js.map +1 -0
  71. package/dist/server/dev-server.d.ts +40 -0
  72. package/dist/server/dev-server.d.ts.map +1 -0
  73. package/dist/server/dev-server.js +758 -0
  74. package/dist/server/dev-server.js.map +1 -0
  75. package/dist/server/html.d.ts +22 -0
  76. package/dist/server/html.d.ts.map +1 -0
  77. package/dist/server/html.js +29 -0
  78. package/dist/server/html.js.map +1 -0
  79. package/dist/server/image-optimization.d.ts +56 -0
  80. package/dist/server/image-optimization.d.ts.map +1 -0
  81. package/dist/server/image-optimization.js +103 -0
  82. package/dist/server/image-optimization.js.map +1 -0
  83. package/dist/server/instrumentation.d.ts +68 -0
  84. package/dist/server/instrumentation.d.ts.map +1 -0
  85. package/dist/server/instrumentation.js +90 -0
  86. package/dist/server/instrumentation.js.map +1 -0
  87. package/dist/server/isr-cache.d.ts +61 -0
  88. package/dist/server/isr-cache.d.ts.map +1 -0
  89. package/dist/server/isr-cache.js +134 -0
  90. package/dist/server/isr-cache.js.map +1 -0
  91. package/dist/server/metadata-routes.d.ts +103 -0
  92. package/dist/server/metadata-routes.d.ts.map +1 -0
  93. package/dist/server/metadata-routes.js +270 -0
  94. package/dist/server/metadata-routes.js.map +1 -0
  95. package/dist/server/middleware.d.ts +77 -0
  96. package/dist/server/middleware.d.ts.map +1 -0
  97. package/dist/server/middleware.js +228 -0
  98. package/dist/server/middleware.js.map +1 -0
  99. package/dist/server/prod-server.d.ts +78 -0
  100. package/dist/server/prod-server.d.ts.map +1 -0
  101. package/dist/server/prod-server.js +712 -0
  102. package/dist/server/prod-server.js.map +1 -0
  103. package/dist/shims/amp.d.ts +17 -0
  104. package/dist/shims/amp.d.ts.map +1 -0
  105. package/dist/shims/amp.js +21 -0
  106. package/dist/shims/amp.js.map +1 -0
  107. package/dist/shims/app.d.ts +12 -0
  108. package/dist/shims/app.d.ts.map +1 -0
  109. package/dist/shims/app.js +2 -0
  110. package/dist/shims/app.js.map +1 -0
  111. package/dist/shims/cache-runtime.d.ts +68 -0
  112. package/dist/shims/cache-runtime.d.ts.map +1 -0
  113. package/dist/shims/cache-runtime.js +437 -0
  114. package/dist/shims/cache-runtime.js.map +1 -0
  115. package/dist/shims/cache.d.ts +243 -0
  116. package/dist/shims/cache.d.ts.map +1 -0
  117. package/dist/shims/cache.js +415 -0
  118. package/dist/shims/cache.js.map +1 -0
  119. package/dist/shims/client-only.d.ts +18 -0
  120. package/dist/shims/client-only.d.ts.map +1 -0
  121. package/dist/shims/client-only.js +18 -0
  122. package/dist/shims/client-only.js.map +1 -0
  123. package/dist/shims/config.d.ts +27 -0
  124. package/dist/shims/config.d.ts.map +1 -0
  125. package/dist/shims/config.js +30 -0
  126. package/dist/shims/config.js.map +1 -0
  127. package/dist/shims/constants.d.ts +13 -0
  128. package/dist/shims/constants.d.ts.map +1 -0
  129. package/dist/shims/constants.js +13 -0
  130. package/dist/shims/constants.js.map +1 -0
  131. package/dist/shims/document.d.ts +33 -0
  132. package/dist/shims/document.d.ts.map +1 -0
  133. package/dist/shims/document.js +32 -0
  134. package/dist/shims/document.js.map +1 -0
  135. package/dist/shims/dynamic.d.ts +33 -0
  136. package/dist/shims/dynamic.d.ts.map +1 -0
  137. package/dist/shims/dynamic.js +148 -0
  138. package/dist/shims/dynamic.js.map +1 -0
  139. package/dist/shims/error-boundary.d.ts +33 -0
  140. package/dist/shims/error-boundary.d.ts.map +1 -0
  141. package/dist/shims/error-boundary.js +88 -0
  142. package/dist/shims/error-boundary.js.map +1 -0
  143. package/dist/shims/error.d.ts +16 -0
  144. package/dist/shims/error.d.ts.map +1 -0
  145. package/dist/shims/error.js +45 -0
  146. package/dist/shims/error.js.map +1 -0
  147. package/dist/shims/fetch-cache.d.ts +61 -0
  148. package/dist/shims/fetch-cache.d.ts.map +1 -0
  149. package/dist/shims/fetch-cache.js +307 -0
  150. package/dist/shims/fetch-cache.js.map +1 -0
  151. package/dist/shims/font-google.d.ts +122 -0
  152. package/dist/shims/font-google.d.ts.map +1 -0
  153. package/dist/shims/font-google.js +387 -0
  154. package/dist/shims/font-google.js.map +1 -0
  155. package/dist/shims/font-local.d.ts +61 -0
  156. package/dist/shims/font-local.d.ts.map +1 -0
  157. package/dist/shims/font-local.js +303 -0
  158. package/dist/shims/font-local.js.map +1 -0
  159. package/dist/shims/form.d.ts +30 -0
  160. package/dist/shims/form.d.ts.map +1 -0
  161. package/dist/shims/form.js +78 -0
  162. package/dist/shims/form.js.map +1 -0
  163. package/dist/shims/head-state.d.ts +11 -0
  164. package/dist/shims/head-state.d.ts.map +1 -0
  165. package/dist/shims/head-state.js +47 -0
  166. package/dist/shims/head-state.js.map +1 -0
  167. package/dist/shims/head.d.ts +28 -0
  168. package/dist/shims/head.d.ts.map +1 -0
  169. package/dist/shims/head.js +148 -0
  170. package/dist/shims/head.js.map +1 -0
  171. package/dist/shims/headers.d.ts +150 -0
  172. package/dist/shims/headers.d.ts.map +1 -0
  173. package/dist/shims/headers.js +412 -0
  174. package/dist/shims/headers.js.map +1 -0
  175. package/dist/shims/image-config.d.ts +30 -0
  176. package/dist/shims/image-config.d.ts.map +1 -0
  177. package/dist/shims/image-config.js +91 -0
  178. package/dist/shims/image-config.js.map +1 -0
  179. package/dist/shims/image.d.ts +63 -0
  180. package/dist/shims/image.d.ts.map +1 -0
  181. package/dist/shims/image.js +284 -0
  182. package/dist/shims/image.js.map +1 -0
  183. package/dist/shims/internal/api-utils.d.ts +12 -0
  184. package/dist/shims/internal/api-utils.d.ts.map +1 -0
  185. package/dist/shims/internal/api-utils.js +7 -0
  186. package/dist/shims/internal/api-utils.js.map +1 -0
  187. package/dist/shims/internal/app-router-context.d.ts +21 -0
  188. package/dist/shims/internal/app-router-context.d.ts.map +1 -0
  189. package/dist/shims/internal/app-router-context.js +15 -0
  190. package/dist/shims/internal/app-router-context.js.map +1 -0
  191. package/dist/shims/internal/cookies.d.ts +9 -0
  192. package/dist/shims/internal/cookies.d.ts.map +1 -0
  193. package/dist/shims/internal/cookies.js +9 -0
  194. package/dist/shims/internal/cookies.js.map +1 -0
  195. package/dist/shims/internal/router-context.d.ts +2 -0
  196. package/dist/shims/internal/router-context.d.ts.map +1 -0
  197. package/dist/shims/internal/router-context.js +9 -0
  198. package/dist/shims/internal/router-context.js.map +1 -0
  199. package/dist/shims/internal/utils.d.ts +48 -0
  200. package/dist/shims/internal/utils.d.ts.map +1 -0
  201. package/dist/shims/internal/utils.js +35 -0
  202. package/dist/shims/internal/utils.js.map +1 -0
  203. package/dist/shims/internal/work-unit-async-storage.d.ts +12 -0
  204. package/dist/shims/internal/work-unit-async-storage.d.ts.map +1 -0
  205. package/dist/shims/internal/work-unit-async-storage.js +13 -0
  206. package/dist/shims/internal/work-unit-async-storage.js.map +1 -0
  207. package/dist/shims/layout-segment-context.d.ts +21 -0
  208. package/dist/shims/layout-segment-context.d.ts.map +1 -0
  209. package/dist/shims/layout-segment-context.js +27 -0
  210. package/dist/shims/layout-segment-context.js.map +1 -0
  211. package/dist/shims/legacy-image.d.ts +52 -0
  212. package/dist/shims/legacy-image.d.ts.map +1 -0
  213. package/dist/shims/legacy-image.js +46 -0
  214. package/dist/shims/legacy-image.js.map +1 -0
  215. package/dist/shims/link.d.ts +48 -0
  216. package/dist/shims/link.d.ts.map +1 -0
  217. package/dist/shims/link.js +395 -0
  218. package/dist/shims/link.js.map +1 -0
  219. package/dist/shims/metadata.d.ts +184 -0
  220. package/dist/shims/metadata.d.ts.map +1 -0
  221. package/dist/shims/metadata.js +472 -0
  222. package/dist/shims/metadata.js.map +1 -0
  223. package/dist/shims/navigation-state.d.ts +14 -0
  224. package/dist/shims/navigation-state.d.ts.map +1 -0
  225. package/dist/shims/navigation-state.js +77 -0
  226. package/dist/shims/navigation-state.js.map +1 -0
  227. package/dist/shims/navigation.d.ts +201 -0
  228. package/dist/shims/navigation.d.ts.map +1 -0
  229. package/dist/shims/navigation.js +672 -0
  230. package/dist/shims/navigation.js.map +1 -0
  231. package/dist/shims/og.d.ts +20 -0
  232. package/dist/shims/og.d.ts.map +1 -0
  233. package/dist/shims/og.js +19 -0
  234. package/dist/shims/og.js.map +1 -0
  235. package/dist/shims/router-state.d.ts +11 -0
  236. package/dist/shims/router-state.d.ts.map +1 -0
  237. package/dist/shims/router-state.js +56 -0
  238. package/dist/shims/router-state.js.map +1 -0
  239. package/dist/shims/router.d.ts +103 -0
  240. package/dist/shims/router.d.ts.map +1 -0
  241. package/dist/shims/router.js +536 -0
  242. package/dist/shims/router.js.map +1 -0
  243. package/dist/shims/script.d.ts +58 -0
  244. package/dist/shims/script.d.ts.map +1 -0
  245. package/dist/shims/script.js +163 -0
  246. package/dist/shims/script.js.map +1 -0
  247. package/dist/shims/server-only.d.ts +19 -0
  248. package/dist/shims/server-only.d.ts.map +1 -0
  249. package/dist/shims/server-only.js +19 -0
  250. package/dist/shims/server-only.js.map +1 -0
  251. package/dist/shims/server.d.ts +178 -0
  252. package/dist/shims/server.d.ts.map +1 -0
  253. package/dist/shims/server.js +377 -0
  254. package/dist/shims/server.js.map +1 -0
  255. package/dist/shims/web-vitals.d.ts +24 -0
  256. package/dist/shims/web-vitals.d.ts.map +1 -0
  257. package/dist/shims/web-vitals.js +17 -0
  258. package/dist/shims/web-vitals.js.map +1 -0
  259. package/dist/utils/hash.d.ts +6 -0
  260. package/dist/utils/hash.d.ts.map +1 -0
  261. package/dist/utils/hash.js +20 -0
  262. package/dist/utils/hash.js.map +1 -0
  263. package/dist/utils/project.d.ts +36 -0
  264. package/dist/utils/project.d.ts.map +1 -0
  265. package/dist/utils/project.js +112 -0
  266. package/dist/utils/project.js.map +1 -0
  267. package/dist/utils/query.d.ts +10 -0
  268. package/dist/utils/query.d.ts.map +1 -0
  269. package/dist/utils/query.js +27 -0
  270. package/dist/utils/query.js.map +1 -0
  271. package/package.json +65 -7
  272. package/index.js +0 -1
@@ -0,0 +1,412 @@
1
+ /**
2
+ * next/headers shim
3
+ *
4
+ * Provides cookies() and headers() functions for App Router Server Components.
5
+ * These read from a request context set by the RSC handler before rendering.
6
+ *
7
+ * In Next.js 15+, cookies() and headers() return Promises (async).
8
+ * We support both the sync (legacy) and async patterns.
9
+ */
10
+ import { AsyncLocalStorage } from "node:async_hooks";
11
+ // NOTE:
12
+ // - This shim can be loaded under multiple module specifiers in Vite's
13
+ // multi-environment setup (RSC/SSR). Store the AsyncLocalStorage on
14
+ // globalThis so `connection()` (next/server) and `consumeDynamicUsage()`
15
+ // (next/headers) always share it.
16
+ // - We use AsyncLocalStorage so concurrent requests don't stomp each other's
17
+ // headers/cookies/dynamic-usage state.
18
+ const _ALS_KEY = Symbol.for("vinext.nextHeadersShim.als");
19
+ const _FALLBACK_KEY = Symbol.for("vinext.nextHeadersShim.fallback");
20
+ const _g = globalThis;
21
+ const _als = (_g[_ALS_KEY] ??= new AsyncLocalStorage());
22
+ const _fallbackState = (_g[_FALLBACK_KEY] ??= {
23
+ headersContext: null,
24
+ dynamicUsageDetected: false,
25
+ pendingSetCookies: [],
26
+ draftModeCookieHeader: null,
27
+ });
28
+ function _enterWith(state) {
29
+ // Some non-Node runtimes/polyfills provide AsyncLocalStorage but not enterWith().
30
+ const enterWith = _als.enterWith;
31
+ if (typeof enterWith === "function") {
32
+ try {
33
+ enterWith.call(_als, state);
34
+ return;
35
+ }
36
+ catch {
37
+ // Fall through to best-effort fallback.
38
+ }
39
+ }
40
+ // Best-effort fallback: global state (not concurrency-safe).
41
+ _fallbackState.headersContext = state.headersContext;
42
+ _fallbackState.dynamicUsageDetected = state.dynamicUsageDetected;
43
+ _fallbackState.pendingSetCookies = state.pendingSetCookies;
44
+ _fallbackState.draftModeCookieHeader = state.draftModeCookieHeader;
45
+ }
46
+ function _getState() {
47
+ const state = _als.getStore();
48
+ return state ?? _fallbackState;
49
+ }
50
+ /**
51
+ * Dynamic usage flag — set when a component calls connection(), cookies(),
52
+ * headers(), or noStore() during rendering. When true, ISR caching is
53
+ * bypassed and the response gets Cache-Control: no-store.
54
+ */
55
+ // (stored on _state)
56
+ /**
57
+ * Mark the current render as requiring dynamic (uncached) rendering.
58
+ * Called by connection(), cookies(), headers(), and noStore().
59
+ */
60
+ export function markDynamicUsage() {
61
+ _getState().dynamicUsageDetected = true;
62
+ }
63
+ /**
64
+ * Check and reset the dynamic usage flag.
65
+ * Called by the server after rendering to decide on caching.
66
+ */
67
+ export function consumeDynamicUsage() {
68
+ const state = _getState();
69
+ const used = state.dynamicUsageDetected;
70
+ state.dynamicUsageDetected = false;
71
+ return used;
72
+ }
73
+ /**
74
+ * Set the headers/cookies context for the current RSC render.
75
+ * Called by the framework's RSC entry before rendering each request.
76
+ *
77
+ * NOTE: This uses enterWith() which only works reliably within the same
78
+ * synchronous call stack. For full async context propagation (needed for
79
+ * RSC streaming), use runWithHeadersContext() instead.
80
+ */
81
+ export function setHeadersContext(ctx) {
82
+ // Start of request: enter a fresh per-request store.
83
+ if (ctx !== null) {
84
+ _enterWith({
85
+ headersContext: ctx,
86
+ dynamicUsageDetected: false,
87
+ pendingSetCookies: [],
88
+ draftModeCookieHeader: null,
89
+ });
90
+ return;
91
+ }
92
+ // End of request cleanup: keep the store (so consumeDynamicUsage and
93
+ // cookie flushing can still run), but clear the request headers/cookies.
94
+ const state = _als.getStore();
95
+ if (state) {
96
+ state.headersContext = null;
97
+ }
98
+ else {
99
+ _fallbackState.headersContext = null;
100
+ }
101
+ }
102
+ /**
103
+ * Run a function with headers context, ensuring the context propagates
104
+ * through all async operations (including RSC streaming).
105
+ *
106
+ * IMPORTANT: RSC rendering is streaming - renderToReadableStream() returns
107
+ * immediately but component execution happens later when the stream is consumed.
108
+ * AsyncLocalStorage.run() only maintains context within the callback scope,
109
+ * so by the time components actually render, we'd be outside that scope.
110
+ *
111
+ * Solution: We use enterWith() to set persistent context AND update the
112
+ * fallback state. This way, even after run() returns, getStore() still
113
+ * returns the right state (via enterWith), and if that fails, we have
114
+ * the fallback. For single-request-at-a-time scenarios (dev mode), this
115
+ * works correctly. For concurrent requests, the ALS should work.
116
+ */
117
+ export function runWithHeadersContext(ctx, fn) {
118
+ const state = {
119
+ headersContext: ctx,
120
+ dynamicUsageDetected: false,
121
+ pendingSetCookies: [],
122
+ draftModeCookieHeader: null,
123
+ };
124
+ // Use enterWith to set persistent context for this async context
125
+ _enterWith(state);
126
+ // Also update fallback state directly for environments where ALS doesn't
127
+ // propagate correctly (this is not concurrency-safe but works for dev)
128
+ _fallbackState.headersContext = ctx;
129
+ _fallbackState.dynamicUsageDetected = false;
130
+ _fallbackState.pendingSetCookies = [];
131
+ _fallbackState.draftModeCookieHeader = null;
132
+ return fn();
133
+ }
134
+ /**
135
+ * Apply middleware-forwarded request headers to the current headers context.
136
+ *
137
+ * When Next.js middleware calls `NextResponse.next({ request: { headers } })`,
138
+ * the modified headers are encoded as `x-middleware-request-<name>` on the
139
+ * middleware response. This function unpacks those prefixed headers and
140
+ * replaces the corresponding entries on the live `HeadersContext` so that
141
+ * subsequent calls to `headers()` / `cookies()` see the middleware changes.
142
+ */
143
+ export function applyMiddlewareRequestHeaders(middlewareResponseHeaders) {
144
+ const state = _getState();
145
+ if (!state.headersContext)
146
+ return;
147
+ const ctx = state.headersContext;
148
+ const PREFIX = "x-middleware-request-";
149
+ for (const [key, value] of middlewareResponseHeaders) {
150
+ if (key.startsWith(PREFIX)) {
151
+ const realName = key.slice(PREFIX.length);
152
+ ctx.headers.set(realName, value);
153
+ }
154
+ }
155
+ // If middleware modified the cookie header, rebuild the cookies map.
156
+ const newCookieHeader = ctx.headers.get("cookie");
157
+ if (newCookieHeader !== null) {
158
+ ctx.cookies.clear();
159
+ for (const part of newCookieHeader.split(";")) {
160
+ const [k, ...rest] = part.split("=");
161
+ if (k) {
162
+ ctx.cookies.set(k.trim(), rest.join("=").trim());
163
+ }
164
+ }
165
+ }
166
+ }
167
+ /**
168
+ * Create a HeadersContext from a standard Request object.
169
+ */
170
+ export function headersContextFromRequest(request) {
171
+ const cookies = new Map();
172
+ const cookieHeader = request.headers.get("cookie") || "";
173
+ for (const part of cookieHeader.split(";")) {
174
+ const [key, ...rest] = part.split("=");
175
+ if (key) {
176
+ cookies.set(key.trim(), rest.join("=").trim());
177
+ }
178
+ }
179
+ return {
180
+ headers: request.headers,
181
+ cookies,
182
+ };
183
+ }
184
+ // ---------------------------------------------------------------------------
185
+ // Public API
186
+ // ---------------------------------------------------------------------------
187
+ /**
188
+ * Read-only Headers instance from the incoming request.
189
+ * Returns a Promise in Next.js 15+ style (but resolves synchronously since
190
+ * the context is already available).
191
+ */
192
+ export async function headers() {
193
+ const state = _getState();
194
+ if (!state.headersContext) {
195
+ throw new Error("headers() can only be called from a Server Component, Route Handler, " +
196
+ "or Server Action. Make sure you're not calling it from a Client Component.");
197
+ }
198
+ markDynamicUsage();
199
+ return state.headersContext.headers;
200
+ }
201
+ /**
202
+ * Cookie jar from the incoming request.
203
+ * Returns a ReadonlyRequestCookies-like object.
204
+ */
205
+ export async function cookies() {
206
+ const state = _getState();
207
+ if (!state.headersContext) {
208
+ throw new Error("cookies() can only be called from a Server Component, Route Handler, " +
209
+ "or Server Action.");
210
+ }
211
+ markDynamicUsage();
212
+ return new RequestCookies(state.headersContext.cookies);
213
+ }
214
+ // ---------------------------------------------------------------------------
215
+ // Writable cookie accumulator for Route Handlers / Server Actions
216
+ // ---------------------------------------------------------------------------
217
+ /** Accumulated Set-Cookie headers from cookies().set() / .delete() calls */
218
+ // (stored on _state)
219
+ /**
220
+ * Get and clear all pending Set-Cookie headers generated by cookies().set()/delete().
221
+ * Called by the framework after rendering to attach headers to the response.
222
+ */
223
+ export function getAndClearPendingCookies() {
224
+ const state = _getState();
225
+ const cookies = state.pendingSetCookies;
226
+ state.pendingSetCookies = [];
227
+ return cookies;
228
+ }
229
+ // Draft mode cookie name (matches Next.js convention)
230
+ const DRAFT_MODE_COOKIE = "__prerender_bypass";
231
+ // Draft mode secret — generated once at build time via Vite `define` so the
232
+ // __prerender_bypass cookie is consistent across all server instances (e.g.
233
+ // multiple Cloudflare Workers isolates).
234
+ function getDraftSecret() {
235
+ const secret = process.env.__VINEXT_DRAFT_SECRET;
236
+ if (!secret) {
237
+ throw new Error("[vinext] __VINEXT_DRAFT_SECRET is not defined. " +
238
+ "This should be set by the Vite plugin at build time.");
239
+ }
240
+ return secret;
241
+ }
242
+ // Store for Set-Cookie headers generated by draftMode().enable()/disable()
243
+ // (stored on _state)
244
+ /**
245
+ * Get any Set-Cookie header generated by draftMode().enable()/disable().
246
+ * Called by the framework after rendering to attach the header to the response.
247
+ */
248
+ export function getDraftModeCookieHeader() {
249
+ const state = _getState();
250
+ const header = state.draftModeCookieHeader;
251
+ state.draftModeCookieHeader = null;
252
+ return header;
253
+ }
254
+ /**
255
+ * Draft mode — check/toggle via a `__prerender_bypass` cookie.
256
+ *
257
+ * - `isEnabled`: true if the bypass cookie is present in the request
258
+ * - `enable()`: sets the bypass cookie (for Route Handlers)
259
+ * - `disable()`: clears the bypass cookie
260
+ */
261
+ export async function draftMode() {
262
+ const state = _getState();
263
+ const secret = getDraftSecret();
264
+ const isEnabled = state.headersContext
265
+ ? state.headersContext.cookies.get(DRAFT_MODE_COOKIE) === secret
266
+ : false;
267
+ return {
268
+ isEnabled,
269
+ enable() {
270
+ if (state.headersContext) {
271
+ state.headersContext.cookies.set(DRAFT_MODE_COOKIE, secret);
272
+ }
273
+ state.draftModeCookieHeader =
274
+ `${DRAFT_MODE_COOKIE}=${secret}; Path=/; HttpOnly; SameSite=Lax`;
275
+ },
276
+ disable() {
277
+ if (state.headersContext) {
278
+ state.headersContext.cookies.delete(DRAFT_MODE_COOKIE);
279
+ }
280
+ state.draftModeCookieHeader =
281
+ `${DRAFT_MODE_COOKIE}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`;
282
+ },
283
+ };
284
+ }
285
+ // ---------------------------------------------------------------------------
286
+ // Cookie name/value validation (RFC 6265)
287
+ // ---------------------------------------------------------------------------
288
+ /**
289
+ * RFC 6265 §4.1.1: cookie-name is a token (RFC 2616 §2.2).
290
+ * Allowed: any visible ASCII (0x21-0x7E) except separators: ()<>@,;:\"/[]?={}
291
+ */
292
+ const VALID_COOKIE_NAME_RE = /^[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]+$/;
293
+ function validateCookieName(name) {
294
+ if (!name || !VALID_COOKIE_NAME_RE.test(name)) {
295
+ throw new Error(`Invalid cookie name: ${JSON.stringify(name)}`);
296
+ }
297
+ }
298
+ /**
299
+ * Validate cookie attribute values (path, domain) to prevent injection
300
+ * via semicolons, newlines, or other control characters.
301
+ */
302
+ function validateCookieAttributeValue(value, attributeName) {
303
+ for (let i = 0; i < value.length; i++) {
304
+ const code = value.charCodeAt(i);
305
+ if (code <= 0x1F || code === 0x7F || value[i] === ";") {
306
+ throw new Error(`Invalid cookie ${attributeName} value: ${JSON.stringify(value)}`);
307
+ }
308
+ }
309
+ }
310
+ // ---------------------------------------------------------------------------
311
+ // RequestCookies implementation
312
+ // ---------------------------------------------------------------------------
313
+ class RequestCookies {
314
+ _cookies;
315
+ constructor(cookies) {
316
+ this._cookies = cookies;
317
+ }
318
+ get(name) {
319
+ const value = this._cookies.get(name);
320
+ if (value === undefined)
321
+ return undefined;
322
+ return { name, value };
323
+ }
324
+ getAll() {
325
+ const result = [];
326
+ for (const [name, value] of this._cookies) {
327
+ result.push({ name, value });
328
+ }
329
+ return result;
330
+ }
331
+ has(name) {
332
+ return this._cookies.has(name);
333
+ }
334
+ /**
335
+ * Set a cookie. In Route Handlers and Server Actions, this produces
336
+ * a Set-Cookie header on the response.
337
+ */
338
+ set(nameOrOptions, value, options) {
339
+ let cookieName;
340
+ let cookieValue;
341
+ let opts;
342
+ if (typeof nameOrOptions === "string") {
343
+ cookieName = nameOrOptions;
344
+ cookieValue = value ?? "";
345
+ opts = options;
346
+ }
347
+ else {
348
+ cookieName = nameOrOptions.name;
349
+ cookieValue = nameOrOptions.value;
350
+ opts = nameOrOptions;
351
+ }
352
+ validateCookieName(cookieName);
353
+ // Update the local cookie map
354
+ this._cookies.set(cookieName, cookieValue);
355
+ // Build Set-Cookie header string
356
+ const parts = [`${cookieName}=${encodeURIComponent(cookieValue)}`];
357
+ if (opts?.path) {
358
+ validateCookieAttributeValue(opts.path, "Path");
359
+ parts.push(`Path=${opts.path}`);
360
+ }
361
+ if (opts?.domain) {
362
+ validateCookieAttributeValue(opts.domain, "Domain");
363
+ parts.push(`Domain=${opts.domain}`);
364
+ }
365
+ if (opts?.maxAge !== undefined)
366
+ parts.push(`Max-Age=${opts.maxAge}`);
367
+ if (opts?.expires)
368
+ parts.push(`Expires=${opts.expires.toUTCString()}`);
369
+ if (opts?.httpOnly)
370
+ parts.push("HttpOnly");
371
+ if (opts?.secure)
372
+ parts.push("Secure");
373
+ if (opts?.sameSite)
374
+ parts.push(`SameSite=${opts.sameSite}`);
375
+ _getState().pendingSetCookies.push(parts.join("; "));
376
+ return this;
377
+ }
378
+ /**
379
+ * Delete a cookie by setting it with Max-Age=0.
380
+ */
381
+ delete(name) {
382
+ validateCookieName(name);
383
+ this._cookies.delete(name);
384
+ _getState().pendingSetCookies.push(`${name}=; Path=/; Max-Age=0`);
385
+ return this;
386
+ }
387
+ get size() {
388
+ return this._cookies.size;
389
+ }
390
+ [Symbol.iterator]() {
391
+ const entries = this._cookies.entries();
392
+ const iter = {
393
+ [Symbol.iterator]() { return iter; },
394
+ next() {
395
+ const { value, done } = entries.next();
396
+ if (done)
397
+ return { value: undefined, done: true };
398
+ const [name, val] = value;
399
+ return { value: [name, { name, value: val }], done: false };
400
+ },
401
+ };
402
+ return iter;
403
+ }
404
+ toString() {
405
+ const parts = [];
406
+ for (const [name, value] of this._cookies) {
407
+ parts.push(`${name}=${value}`);
408
+ }
409
+ return parts.join("; ");
410
+ }
411
+ }
412
+ //# sourceMappingURL=headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/shims/headers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Image remote pattern validation.
3
+ *
4
+ * Validates remote image URLs against the `images.remotePatterns` and
5
+ * `images.domains` config from next.config.js. This prevents SSRF and
6
+ * open-redirect attacks by blocking URLs that don't match any configured
7
+ * pattern.
8
+ *
9
+ * Pattern matching follows Next.js semantics:
10
+ * - `*` matches a single segment (subdomain in hostname, path segment in pathname)
11
+ * - `**` matches any number of segments
12
+ * - protocol, port, and search are matched exactly when specified
13
+ */
14
+ export interface RemotePattern {
15
+ protocol?: string;
16
+ hostname: string;
17
+ port?: string;
18
+ pathname?: string;
19
+ search?: string;
20
+ }
21
+ /**
22
+ * Check whether a URL matches a single remote pattern.
23
+ * Follows the same semantics as Next.js's matchRemotePattern().
24
+ */
25
+ export declare function matchRemotePattern(pattern: RemotePattern, url: URL): boolean;
26
+ /**
27
+ * Check whether a URL matches any configured remote pattern or legacy domain.
28
+ */
29
+ export declare function hasRemoteMatch(domains: string[], remotePatterns: RemotePattern[], url: URL): boolean;
30
+ //# sourceMappingURL=image-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-config.d.ts","sourceRoot":"","sources":["../../src/shims/image-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAwCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAkC5E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,aAAa,EAAE,EAC/B,GAAG,EAAE,GAAG,GACP,OAAO,CAKT"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Image remote pattern validation.
3
+ *
4
+ * Validates remote image URLs against the `images.remotePatterns` and
5
+ * `images.domains` config from next.config.js. This prevents SSRF and
6
+ * open-redirect attacks by blocking URLs that don't match any configured
7
+ * pattern.
8
+ *
9
+ * Pattern matching follows Next.js semantics:
10
+ * - `*` matches a single segment (subdomain in hostname, path segment in pathname)
11
+ * - `**` matches any number of segments
12
+ * - protocol, port, and search are matched exactly when specified
13
+ */
14
+ /**
15
+ * Convert a glob pattern (with `*` and `**`) to a RegExp.
16
+ *
17
+ * For hostnames, segments are separated by `.`:
18
+ * - `*` matches a single segment (no dots): [^.]+
19
+ * - `**` matches any number of segments: .+
20
+ *
21
+ * For pathnames, segments are separated by `/`:
22
+ * - `*` matches a single segment (no slashes): [^/]+
23
+ * - `**` matches any number of segments (including empty): .*
24
+ *
25
+ * Literal characters are escaped for regex safety.
26
+ */
27
+ function globToRegex(pattern, separator) {
28
+ // Split by ** first, then handle * within each part
29
+ let regexStr = "^";
30
+ const doubleStar = separator === "." ? ".+" : ".*";
31
+ const singleStar = separator === "." ? "[^.]+" : "[^/]+";
32
+ const parts = pattern.split("**");
33
+ for (let i = 0; i < parts.length; i++) {
34
+ if (i > 0) {
35
+ regexStr += doubleStar;
36
+ }
37
+ // Within each part, split by * and escape the literals
38
+ const subParts = parts[i].split("*");
39
+ for (let j = 0; j < subParts.length; j++) {
40
+ if (j > 0) {
41
+ regexStr += singleStar;
42
+ }
43
+ // Escape regex special chars in the literal portion
44
+ regexStr += subParts[j].replace(/[.+?^${}()|[\]\\]/g, "\\$&");
45
+ }
46
+ }
47
+ regexStr += "$";
48
+ return new RegExp(regexStr);
49
+ }
50
+ /**
51
+ * Check whether a URL matches a single remote pattern.
52
+ * Follows the same semantics as Next.js's matchRemotePattern().
53
+ */
54
+ export function matchRemotePattern(pattern, url) {
55
+ // Protocol check (strip trailing colon for comparison)
56
+ if (pattern.protocol !== undefined) {
57
+ if (pattern.protocol.replace(/:$/, "") !== url.protocol.replace(/:$/, "")) {
58
+ return false;
59
+ }
60
+ }
61
+ // Port check
62
+ if (pattern.port !== undefined) {
63
+ if (pattern.port !== url.port) {
64
+ return false;
65
+ }
66
+ }
67
+ // Hostname check (required field)
68
+ if (!globToRegex(pattern.hostname, ".").test(url.hostname)) {
69
+ return false;
70
+ }
71
+ // Search/query string check
72
+ if (pattern.search !== undefined) {
73
+ if (pattern.search !== url.search) {
74
+ return false;
75
+ }
76
+ }
77
+ // Pathname check — defaults to ** (match everything) if not specified
78
+ const pathnamePattern = pattern.pathname ?? "**";
79
+ if (!globToRegex(pathnamePattern, "/").test(url.pathname)) {
80
+ return false;
81
+ }
82
+ return true;
83
+ }
84
+ /**
85
+ * Check whether a URL matches any configured remote pattern or legacy domain.
86
+ */
87
+ export function hasRemoteMatch(domains, remotePatterns, url) {
88
+ return (domains.some((domain) => url.hostname === domain) ||
89
+ remotePatterns.some((p) => matchRemotePattern(p, url)));
90
+ }
91
+ //# sourceMappingURL=image-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-config.js","sourceRoot":"","sources":["../../src/shims/image-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * next/image shim
3
+ *
4
+ * Translates Next.js Image props to @unpic/react Image component.
5
+ * @unpic/react auto-detects CDN from URL and uses native transforms.
6
+ * For local images (relative paths), routes through `/_vinext/image`
7
+ * for server-side optimization (resize, format negotiation, quality).
8
+ *
9
+ * Remote images are validated against `images.remotePatterns` and
10
+ * `images.domains` from next.config.js. Unmatched URLs are blocked
11
+ * in production and warn in development, matching Next.js behavior.
12
+ */
13
+ import React from "react";
14
+ export interface StaticImageData {
15
+ src: string;
16
+ height: number;
17
+ width: number;
18
+ blurDataURL?: string;
19
+ }
20
+ interface ImageProps {
21
+ src: string | StaticImageData;
22
+ alt: string;
23
+ width?: number;
24
+ height?: number;
25
+ fill?: boolean;
26
+ priority?: boolean;
27
+ quality?: number;
28
+ placeholder?: "blur" | "empty";
29
+ blurDataURL?: string;
30
+ loader?: (params: {
31
+ src: string;
32
+ width: number;
33
+ quality?: number;
34
+ }) => string;
35
+ sizes?: string;
36
+ className?: string;
37
+ style?: React.CSSProperties;
38
+ onLoad?: React.ReactEventHandler<HTMLImageElement>;
39
+ onError?: React.ReactEventHandler<HTMLImageElement>;
40
+ onClick?: React.MouseEventHandler<HTMLImageElement>;
41
+ id?: string;
42
+ unoptimized?: boolean;
43
+ overrideSrc?: string;
44
+ loading?: "lazy" | "eager";
45
+ }
46
+ /**
47
+ * Build a `/_vinext/image` optimization URL.
48
+ *
49
+ * In production (Cloudflare Workers), the worker intercepts this path and uses
50
+ * the Images binding to resize/transcode on the fly. In dev, the Vite dev
51
+ * server handles it as a passthrough (serves the original file).
52
+ */
53
+ export declare function imageOptimizationUrl(src: string, width: number, quality?: number): string;
54
+ declare const Image: React.ForwardRefExoticComponent<ImageProps & React.RefAttributes<HTMLImageElement>>;
55
+ /**
56
+ * getImageProps — for advanced use cases (picture elements, background images).
57
+ * Returns the props that would be passed to the underlying <img> element.
58
+ */
59
+ export declare function getImageProps(props: ImageProps): {
60
+ props: React.ImgHTMLAttributes<HTMLImageElement>;
61
+ };
62
+ export default Image;
63
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/shims/image.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAyDD,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,MAAM,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACpD,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AA0CD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GAAG,MAAM,CAE7F;AAeD,QAAA,MAAM,KAAK,qFAoKT,CAAC;AAEH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG;IAChD,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;CAClD,CA4FA;AAED,eAAe,KAAK,CAAC"}