vinext 1.0.0-beta.1 → 1.0.0-beta.2

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 (175) hide show
  1. package/README.md +4 -1
  2. package/dist/build/client-build-config.js +1 -0
  3. package/dist/build/report.d.ts +8 -1
  4. package/dist/build/report.js +12 -2
  5. package/dist/check.js +15 -2
  6. package/dist/cli.js +3 -2
  7. package/dist/config/config-matchers.d.ts +13 -37
  8. package/dist/config/config-matchers.js +31 -121
  9. package/dist/config/next-config.d.ts +3 -2
  10. package/dist/config/next-config.js +3 -1
  11. package/dist/config/request-context.d.ts +14 -0
  12. package/dist/config/request-context.js +26 -0
  13. package/dist/entries/app-rsc-entry.js +27 -9
  14. package/dist/entries/app-rsc-manifest.js +17 -0
  15. package/dist/entries/pages-server-entry.js +3 -2
  16. package/dist/index.js +82 -58
  17. package/dist/init.d.ts +6 -4
  18. package/dist/init.js +20 -22
  19. package/dist/plugins/og-assets.js +1 -1
  20. package/dist/routing/app-route-graph.d.ts +13 -5
  21. package/dist/routing/app-route-graph.js +59 -13
  22. package/dist/routing/app-router.js +12 -6
  23. package/dist/routing/file-matcher.d.ts +11 -22
  24. package/dist/routing/file-matcher.js +21 -33
  25. package/dist/routing/pages-router.js +23 -29
  26. package/dist/routing/route-matching.d.ts +14 -1
  27. package/dist/routing/route-matching.js +13 -1
  28. package/dist/routing/route-pattern.d.ts +2 -1
  29. package/dist/routing/route-pattern.js +7 -4
  30. package/dist/routing/route-trie.d.ts +5 -1
  31. package/dist/routing/route-trie.js +5 -2
  32. package/dist/server/app-browser-entry.js +7 -6
  33. package/dist/server/app-browser-history-controller.d.ts +1 -1
  34. package/dist/server/app-browser-history-controller.js +3 -3
  35. package/dist/server/app-browser-navigation-controller.js +1 -1
  36. package/dist/server/app-browser-state.js +1 -1
  37. package/dist/server/app-browser-visible-commit.js +1 -1
  38. package/dist/server/app-fallback-renderer.d.ts +3 -0
  39. package/dist/server/app-fallback-renderer.js +4 -2
  40. package/dist/server/app-middleware.js +2 -1
  41. package/dist/server/app-page-boundary-render.d.ts +12 -1
  42. package/dist/server/app-page-boundary-render.js +84 -2
  43. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  44. package/dist/server/app-page-cache.d.ts +1 -1
  45. package/dist/server/app-page-dispatch.d.ts +11 -2
  46. package/dist/server/app-page-dispatch.js +14 -17
  47. package/dist/server/app-page-element-builder.d.ts +7 -2
  48. package/dist/server/app-page-element-builder.js +112 -27
  49. package/dist/server/app-page-head.d.ts +54 -2
  50. package/dist/server/app-page-head.js +164 -78
  51. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  52. package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
  53. package/dist/server/app-page-render.d.ts +2 -2
  54. package/dist/server/app-page-render.js +1 -1
  55. package/dist/server/app-page-request.d.ts +12 -0
  56. package/dist/server/app-page-request.js +133 -13
  57. package/dist/server/app-page-route-wiring.d.ts +9 -0
  58. package/dist/server/app-page-route-wiring.js +43 -3
  59. package/dist/server/app-post-middleware-context.d.ts +1 -1
  60. package/dist/server/app-post-middleware-context.js +1 -1
  61. package/dist/server/app-route-handler-dispatch.js +31 -17
  62. package/dist/server/app-route-handler-execution.d.ts +6 -1
  63. package/dist/server/app-route-handler-execution.js +42 -16
  64. package/dist/server/app-route-handler-policy.d.ts +2 -0
  65. package/dist/server/app-route-handler-policy.js +3 -3
  66. package/dist/server/app-route-module-loader.d.ts +3 -1
  67. package/dist/server/app-route-module-loader.js +1 -0
  68. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  69. package/dist/server/app-rsc-errors.d.ts +1 -1
  70. package/dist/server/app-rsc-errors.js +12 -2
  71. package/dist/server/app-rsc-handler.d.ts +10 -5
  72. package/dist/server/app-rsc-handler.js +52 -24
  73. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  74. package/dist/server/app-rsc-request-normalization.js +8 -2
  75. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  76. package/dist/server/app-rsc-response-finalizer.js +5 -11
  77. package/dist/server/app-rsc-route-matching.d.ts +20 -0
  78. package/dist/server/app-rsc-route-matching.js +87 -11
  79. package/dist/server/app-segment-config.js +13 -3
  80. package/dist/server/app-server-action-execution.d.ts +3 -1
  81. package/dist/server/app-server-action-execution.js +9 -7
  82. package/dist/server/app-ssr-entry.js +2 -2
  83. package/dist/server/app-ssr-stream.d.ts +1 -7
  84. package/dist/server/app-ssr-stream.js +2 -10
  85. package/dist/server/config-headers.d.ts +24 -0
  86. package/dist/server/config-headers.js +52 -0
  87. package/dist/server/dev-initial-server-error.d.ts +1 -1
  88. package/dist/server/dev-server.js +29 -13
  89. package/dist/server/isr-cache.d.ts +1 -1
  90. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  91. package/dist/server/middleware-matcher-pattern.js +219 -0
  92. package/dist/server/middleware-matcher.d.ts +2 -7
  93. package/dist/server/middleware-matcher.js +13 -60
  94. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  95. package/dist/server/middleware-path-to-regexp.js +228 -0
  96. package/dist/server/middleware-runtime.js +4 -3
  97. package/dist/server/middleware.d.ts +1 -1
  98. package/dist/server/middleware.js +2 -1
  99. package/dist/server/pages-data-route.d.ts +11 -1
  100. package/dist/server/pages-data-route.js +16 -1
  101. package/dist/server/pages-get-initial-props.d.ts +15 -2
  102. package/dist/server/pages-get-initial-props.js +16 -6
  103. package/dist/server/pages-page-data.d.ts +3 -1
  104. package/dist/server/pages-page-data.js +16 -7
  105. package/dist/server/pages-page-handler.d.ts +4 -2
  106. package/dist/server/pages-page-handler.js +16 -17
  107. package/dist/server/pages-page-response.js +1 -1
  108. package/dist/server/pages-readiness.d.ts +3 -3
  109. package/dist/server/pages-request-pipeline.d.ts +1 -0
  110. package/dist/server/pages-request-pipeline.js +25 -11
  111. package/dist/server/pages-router-entry.js +6 -0
  112. package/dist/server/prerender-route-params.js +2 -2
  113. package/dist/server/prod-server.d.ts +1 -4
  114. package/dist/server/prod-server.js +36 -23
  115. package/dist/server/request-pipeline.d.ts +15 -29
  116. package/dist/server/request-pipeline.js +24 -59
  117. package/dist/server/rsc-stream-hints.js +122 -18
  118. package/dist/shims/app.d.ts +1 -1
  119. package/dist/shims/cache-request-state.d.ts +27 -1
  120. package/dist/shims/cache-request-state.js +60 -1
  121. package/dist/shims/cache-runtime.d.ts +12 -1
  122. package/dist/shims/cache-runtime.js +22 -7
  123. package/dist/shims/cache.d.ts +5 -5
  124. package/dist/shims/cache.js +26 -10
  125. package/dist/shims/document.d.ts +42 -83
  126. package/dist/shims/document.js +62 -53
  127. package/dist/shims/dynamic.d.ts +5 -25
  128. package/dist/shims/dynamic.js +29 -8
  129. package/dist/shims/error.d.ts +1 -1
  130. package/dist/shims/error.js +1 -1
  131. package/dist/shims/fetch-cache.js +12 -3
  132. package/dist/shims/font-google-base.d.ts +11 -4
  133. package/dist/shims/font-local.d.ts +10 -3
  134. package/dist/shims/head.d.ts +13 -2
  135. package/dist/shims/head.js +3 -3
  136. package/dist/shims/headers.d.ts +28 -31
  137. package/dist/shims/headers.js +109 -49
  138. package/dist/shims/image.d.ts +27 -37
  139. package/dist/shims/image.js +21 -14
  140. package/dist/shims/internal/cookie-serialize.d.ts +3 -1
  141. package/dist/shims/internal/cookie-serialize.js +3 -1
  142. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  143. package/dist/shims/internal/utils.d.ts +3 -3
  144. package/dist/shims/legacy-image.d.ts +3 -37
  145. package/dist/shims/legacy-image.js +6 -16
  146. package/dist/shims/link.d.ts +15 -22
  147. package/dist/shims/link.js +20 -11
  148. package/dist/shims/navigation-context-state.d.ts +1 -1
  149. package/dist/shims/navigation.d.ts +7 -3
  150. package/dist/shims/navigation.js +24 -13
  151. package/dist/shims/navigation.react-server.js +1 -1
  152. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  153. package/dist/shims/next-shims-public.d.ts +1 -0
  154. package/dist/shims/public-shim-map.json.js +103 -0
  155. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  156. package/dist/shims/readonly-url-search-params.js +3 -3
  157. package/dist/shims/request-state-types.d.ts +1 -1
  158. package/dist/shims/router.d.ts +55 -21
  159. package/dist/shims/router.js +162 -37
  160. package/dist/shims/script.d.ts +6 -10
  161. package/dist/shims/script.js +6 -3
  162. package/dist/shims/server.d.ts +45 -22
  163. package/dist/shims/server.js +44 -5
  164. package/dist/shims/unified-request-context.d.ts +1 -1
  165. package/dist/shims/unified-request-context.js +2 -0
  166. package/dist/shims/url-safety.d.ts +1 -1
  167. package/dist/shims/url-safety.js +2 -2
  168. package/dist/typegen.d.ts +8 -2
  169. package/dist/typegen.js +76 -15
  170. package/dist/utils/domain-locale.d.ts +2 -2
  171. package/dist/utils/external-url.d.ts +5 -0
  172. package/dist/utils/external-url.js +7 -0
  173. package/dist/utils/regex-safety.d.ts +8 -0
  174. package/dist/utils/regex-safety.js +737 -0
  175. package/package.json +13 -2
@@ -114,6 +114,52 @@ function markDynamicUsage() {
114
114
  const state = _getState();
115
115
  if (state.headersContext?.forceStatic) return;
116
116
  state.dynamicUsageDetected = true;
117
+ forEachConnectionProbeTarget(state, (target) => {
118
+ target.dynamicUsageDetected = true;
119
+ });
120
+ }
121
+ function forEachConnectionProbeTarget(state, visit) {
122
+ let target = state.connectionProbe?.dynamicUsageTarget ?? null;
123
+ const seen = /* @__PURE__ */ new Set([state]);
124
+ while (target && !seen.has(target)) {
125
+ seen.add(target);
126
+ visit(target);
127
+ target = target.connectionProbe?.dynamicUsageTarget ?? null;
128
+ }
129
+ }
130
+ function propagateInvalidDynamicUsageError(state, error) {
131
+ forEachConnectionProbeTarget(state, (target) => {
132
+ if (target.invalidDynamicUsageError == null) target.invalidDynamicUsageError = error;
133
+ });
134
+ }
135
+ /**
136
+ * Measure dynamic usage in a child async scope without clearing the parent.
137
+ * Concurrent work that already belongs to the request (such as deferred
138
+ * metadata) keeps writing to the parent state and therefore remains visible
139
+ * to the final cache policy.
140
+ */
141
+ async function runWithIsolatedDynamicUsage(fn) {
142
+ const runInChildState = async (childState) => {
143
+ return {
144
+ result: await fn(),
145
+ dynamicDetected: childState.dynamicUsageDetected
146
+ };
147
+ };
148
+ if (isInsideUnifiedScope()) {
149
+ let childState = null;
150
+ return await runWithUnifiedStateMutation((context) => {
151
+ context.dynamicUsageDetected = false;
152
+ childState = context;
153
+ }, () => {
154
+ if (!childState) throw new Error("Dynamic usage scope was not initialized");
155
+ return runInChildState(childState);
156
+ });
157
+ }
158
+ const childState = {
159
+ ..._getState(),
160
+ dynamicUsageDetected: false
161
+ };
162
+ return await _als.run(childState, () => runInChildState(childState));
117
163
  }
118
164
  function markRenderRequestApiUsage(kind) {
119
165
  _getState().renderRequestApiUsage.add(kind);
@@ -123,13 +169,15 @@ function throwIfStaticGenerationAccessError() {
123
169
  if (accessError) throw accessError;
124
170
  }
125
171
  async function runWithConnectionProbe(fn) {
126
- const state = _getState();
127
- const previousProbe = state.connectionProbe;
172
+ const parentState = _getState();
173
+ const parentInvalidDynamicUsageError = parentState.invalidDynamicUsageError;
128
174
  let interruptProbe = () => {};
129
175
  const interrupted = new Promise((resolve) => {
130
176
  interruptProbe = () => resolve({ completed: false });
131
177
  });
132
178
  const probe = {
179
+ active: true,
180
+ dynamicUsageTarget: parentState,
133
181
  interrupted: false,
134
182
  interrupt() {
135
183
  if (probe.interrupted) return;
@@ -138,20 +186,39 @@ async function runWithConnectionProbe(fn) {
138
186
  },
139
187
  pending: new Promise(() => {})
140
188
  };
141
- state.connectionProbe = probe;
142
- try {
143
- const completed = Promise.resolve().then(fn).then((result) => ({
144
- completed: true,
145
- result
146
- }));
147
- return await Promise.race([completed, interrupted]);
148
- } finally {
149
- state.connectionProbe = previousProbe;
189
+ const runInChildState = async (childState) => {
190
+ try {
191
+ const completed = Promise.resolve().then(fn).then((result) => ({
192
+ completed: true,
193
+ result
194
+ }));
195
+ return await Promise.race([completed, interrupted]);
196
+ } finally {
197
+ probe.active = false;
198
+ childState.connectionProbe = parentState.connectionProbe ?? probe;
199
+ if (childState.dynamicUsageDetected) parentState.dynamicUsageDetected = true;
200
+ if (childState.invalidDynamicUsageError !== parentInvalidDynamicUsageError && parentState.invalidDynamicUsageError === parentInvalidDynamicUsageError) parentState.invalidDynamicUsageError = childState.invalidDynamicUsageError;
201
+ }
202
+ };
203
+ if (isInsideUnifiedScope()) {
204
+ let childState = null;
205
+ return await runWithUnifiedStateMutation((context) => {
206
+ context.connectionProbe = probe;
207
+ childState = context;
208
+ }, () => {
209
+ if (!childState) throw new Error("Connection probe scope was not initialized");
210
+ return runInChildState(childState);
211
+ });
150
212
  }
213
+ const childState = {
214
+ ...parentState,
215
+ connectionProbe: probe
216
+ };
217
+ return await _als.run(childState, () => runInChildState(childState));
151
218
  }
152
219
  function suspendConnectionProbe() {
153
220
  const probe = _getState().connectionProbe;
154
- if (!probe) return null;
221
+ if (!probe?.active) return null;
155
222
  probe.interrupt();
156
223
  return probe.pending;
157
224
  }
@@ -202,6 +269,7 @@ function throwIfInsideCacheScope(apiName) {
202
269
  if (cacheCtx) cacheCtx.invalidDynamicUsageError = error;
203
270
  const ctx = getRequestContext();
204
271
  if (ctx) ctx.invalidDynamicUsageError = error;
272
+ propagateInvalidDynamicUsageError(_getState(), error);
205
273
  } catch {}
206
274
  throw error;
207
275
  }
@@ -210,6 +278,7 @@ function throwIfInsideCacheScope(apiName) {
210
278
  try {
211
279
  const ctx = getRequestContext();
212
280
  if (ctx) ctx.invalidDynamicUsageError = error;
281
+ propagateInvalidDynamicUsageError(_getState(), error);
213
282
  } catch {}
214
283
  throw error;
215
284
  }
@@ -553,7 +622,7 @@ function headers() {
553
622
  * Cookie jar from the incoming request.
554
623
  * Returns a ReadonlyRequestCookies-like object.
555
624
  */
556
- function cookies() {
625
+ function cookiesImpl() {
557
626
  markRenderRequestApiUsage("cookies");
558
627
  try {
559
628
  throwIfInsideCacheScope("cookies()");
@@ -569,6 +638,9 @@ function cookies() {
569
638
  const cookieStore = _areCookiesMutableInCurrentPhase() ? _getMutableCookies(state.headersContext) : _getReadonlyCookies(state.headersContext);
570
639
  return _getOrCreateDecoratedRequestApiPromise(_decoratedCookiesPromises, cookieStore);
571
640
  }
641
+ function cookies() {
642
+ return cookiesImpl();
643
+ }
572
644
  /** Accumulated Set-Cookie headers from cookies().set() / .delete() calls */
573
645
  /**
574
646
  * Get and clear all pending Set-Cookie headers generated by cookies().set()/delete().
@@ -613,18 +685,26 @@ function isDraftModeRequest(request, draftModeSecret) {
613
685
  return parseEdgeRequestCookieHeader(cookieHeader).get(DRAFT_MODE_COOKIE) === validateDraftModeSecret(draftModeSecret);
614
686
  }
615
687
  /**
616
- * Read the active request's draft-mode state without recording request API usage.
617
- * Internal cache implementations use this to bypass persistent reads and writes,
618
- * matching Next.js's request-level `workStore.isDraftMode` guard.
688
+ * Read draft mode from the live request context without recording request API
689
+ * usage. `null` means there is no active request context, which lets framework
690
+ * callers fall back to an explicitly supplied request when needed.
619
691
  */
620
- function isDraftModeEnabled() {
692
+ function getActiveDraftModeState() {
621
693
  const context = _getState().headersContext;
622
- if (!context) return false;
694
+ if (!context) return null;
623
695
  if (context.draftModeEnabled !== void 0) return context.draftModeEnabled;
624
696
  const secret = context.draftModeSecret;
625
697
  if (secret === void 0) return false;
626
698
  return context.cookies.get(DRAFT_MODE_COOKIE) === validateDraftModeSecret(secret);
627
699
  }
700
+ /**
701
+ * Read the active request's draft-mode state without recording request API usage.
702
+ * Internal cache implementations use this to bypass persistent reads and writes,
703
+ * matching Next.js's request-level `workStore.isDraftMode` guard.
704
+ */
705
+ function isDraftModeEnabled() {
706
+ return getActiveDraftModeState() ?? false;
707
+ }
628
708
  function draftModeCookieAttributes() {
629
709
  if (typeof process !== "undefined" && process.env?.NODE_ENV === "development") return "Path=/; HttpOnly; SameSite=Lax";
630
710
  return "Path=/; HttpOnly; SameSite=None; Secure";
@@ -705,10 +785,6 @@ var RequestCookies = class {
705
785
  has(name) {
706
786
  return this._cookies.has(name);
707
787
  }
708
- /**
709
- * Set a cookie. In Route Handlers and Server Actions, this produces
710
- * a Set-Cookie header on the response.
711
- */
712
788
  set(nameOrOptions, value, options) {
713
789
  let cookieName;
714
790
  let cookieValue;
@@ -724,12 +800,14 @@ var RequestCookies = class {
724
800
  }
725
801
  validateCookieName(cookieName);
726
802
  this._cookies.set(cookieName, cookieValue);
727
- _getState().pendingSetCookies.push(serializeSetCookie(cookieName, cookieValue, opts));
803
+ const sameSite = opts?.sameSite === true ? "Strict" : typeof opts?.sameSite === "string" ? opts.sameSite[0].toUpperCase() + opts.sameSite.slice(1) : void 0;
804
+ _getState().pendingSetCookies.push(serializeSetCookie(cookieName, cookieValue, {
805
+ ...opts,
806
+ expires: typeof opts?.expires === "number" ? new Date(opts.expires) : opts?.expires,
807
+ sameSite
808
+ }));
728
809
  return this;
729
810
  }
730
- /**
731
- * Delete a cookie by emitting an expired Set-Cookie header.
732
- */
733
811
  delete(nameOrOptions) {
734
812
  const name = typeof nameOrOptions === "string" ? nameOrOptions : nameOrOptions.name;
735
813
  const path = typeof nameOrOptions === "string" ? "/" : nameOrOptions.path ?? "/";
@@ -748,28 +826,10 @@ var RequestCookies = class {
748
826
  return this._cookies.size;
749
827
  }
750
828
  [Symbol.iterator]() {
751
- const entries = this._cookies.entries();
752
- const iter = {
753
- [Symbol.iterator]() {
754
- return iter;
755
- },
756
- next() {
757
- const { value, done } = entries.next();
758
- if (done) return {
759
- value: void 0,
760
- done: true
761
- };
762
- const [name, val] = value;
763
- return {
764
- value: [name, {
765
- name,
766
- value: val
767
- }],
768
- done: false
769
- };
770
- }
771
- };
772
- return iter;
829
+ return new Map(Array.from(this._cookies, ([name, value]) => [name, {
830
+ name,
831
+ value
832
+ }])).entries();
773
833
  }
774
834
  toString() {
775
835
  const parts = [];
@@ -778,4 +838,4 @@ var RequestCookies = class {
778
838
  }
779
839
  };
780
840
  //#endregion
781
- export { applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, draftMode, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersAccessPhase, getHeadersContext, headers, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, markDynamicUsage, markRenderRequestApiUsage, peekDynamicUsage, peekRenderRequestApiUsage, runWithConnectionProbe, runWithHeadersContext, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
841
+ export { applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, draftMode, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersAccessPhase, getHeadersContext, headers, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, markDynamicUsage, markRenderRequestApiUsage, peekDynamicUsage, peekRenderRequestApiUsage, runWithConnectionProbe, runWithHeadersContext, runWithIsolatedDynamicUsage, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
@@ -1,40 +1,9 @@
1
1
  import React from "react";
2
+ import { ImageLoader, ImageProps as ImageProps$1, ImgProps, StaticImageData, StaticImport, StaticRequire } from "@vinext/types/next/upstream/dist/shared/lib/get-img-props";
2
3
 
3
4
  //#region src/shims/image.d.ts
4
- type StaticImageData = {
5
- src: string;
6
- height: number;
7
- width: number;
8
- blurDataURL?: string;
9
- };
10
- type ImageProps = {
11
- src: string | StaticImageData;
12
- alt: string;
13
- width?: number;
14
- height?: number;
15
- fill?: boolean;
16
- preload?: boolean;
17
- priority?: boolean;
18
- quality?: number;
19
- placeholder?: "blur" | "empty";
20
- blurDataURL?: string;
21
- loader?: (params: {
22
- src: string;
23
- width: number;
24
- quality?: number;
25
- }) => string;
26
- sizes?: string;
27
- className?: string;
28
- style?: React.CSSProperties;
29
- onLoad?: React.ReactEventHandler<HTMLImageElement>; /** @deprecated Use onLoad instead. Still supported for migration compat. */
30
- onLoadingComplete?: (img: HTMLImageElement) => void;
31
- onError?: React.ReactEventHandler<HTMLImageElement>;
32
- onClick?: React.MouseEventHandler<HTMLImageElement>;
33
- id?: string;
34
- unoptimized?: boolean;
35
- overrideSrc?: string;
36
- loading?: "lazy" | "eager";
37
- };
5
+ type ImageLoaderProps = Parameters<ImageLoader>[0];
6
+ type ImageProps = ImageProps$1;
38
7
  /**
39
8
  * Build a `/_next/image` optimization URL.
40
9
  *
@@ -43,13 +12,34 @@ type ImageProps = {
43
12
  * server handles it as a passthrough (serves the original file).
44
13
  */
45
14
  declare function imageOptimizationUrl(src: string, width: number, quality?: number): string;
46
- declare const Image: React.ForwardRefExoticComponent<ImageProps & React.RefAttributes<HTMLImageElement>>;
15
+ declare const Image: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "alt" | "height" | "loading" | "ref" | "src" | "srcSet" | "width"> & {
16
+ src: string | StaticImport;
17
+ alt: string;
18
+ width?: number | `${number}`;
19
+ height?: number | `${number}`;
20
+ fill?: boolean;
21
+ loader?: ImageLoader;
22
+ quality?: number | `${number}`;
23
+ preload?: boolean;
24
+ priority?: boolean;
25
+ loading?: "eager" | "lazy" | undefined;
26
+ placeholder?: import("@vinext/types/next/upstream/dist/shared/lib/get-img-props").PlaceholderValue;
27
+ blurDataURL?: string;
28
+ unoptimized?: boolean;
29
+ overrideSrc?: string;
30
+ onLoadingComplete?: import("@vinext/types/next/upstream/dist/shared/lib/get-img-props").OnLoadingComplete;
31
+ layout?: string;
32
+ objectFit?: string;
33
+ objectPosition?: string;
34
+ lazyBoundary?: string;
35
+ lazyRoot?: string;
36
+ } & React.RefAttributes<HTMLImageElement>>;
47
37
  /**
48
38
  * getImageProps — for advanced use cases (picture elements, background images).
49
39
  * Returns the props that would be passed to the underlying <img> element.
50
40
  */
51
41
  declare function getImageProps(props: ImageProps): {
52
- props: React.ImgHTMLAttributes<HTMLImageElement>;
42
+ props: ImgProps;
53
43
  };
54
44
  //#endregion
55
- export { StaticImageData, Image as default, getImageProps, imageOptimizationUrl };
45
+ export { type ImageLoader, ImageLoaderProps, ImageProps, type StaticImageData, type StaticRequire, Image as default, getImageProps, imageOptimizationUrl };
@@ -216,11 +216,15 @@ function getFillStyle(style, backgroundStyle) {
216
216
  * Shared by the Image component and getImageProps to keep behavior in sync.
217
217
  */
218
218
  function resolveImageSource(v) {
219
+ const staticData = typeof v.src === "object" && "default" in v.src ? v.src.default : v.src;
220
+ const src = typeof staticData === "string" ? staticData : staticData.src;
221
+ const sourceWidth = v.width ?? (typeof staticData === "object" ? staticData.width : void 0);
222
+ const sourceHeight = v.height ?? (typeof staticData === "object" ? staticData.height : void 0);
219
223
  return {
220
- src: typeof v.src === "string" ? v.src : v.src.src,
221
- width: v.width ?? (typeof v.src === "object" ? v.src.width : void 0),
222
- height: v.height ?? (typeof v.src === "object" ? v.src.height : void 0),
223
- blurDataURL: v.blurDataURL ?? (typeof v.src === "object" ? v.src.blurDataURL : void 0)
224
+ src,
225
+ width: typeof sourceWidth === "string" ? Number(sourceWidth) : sourceWidth,
226
+ height: typeof sourceHeight === "string" ? Number(sourceHeight) : sourceHeight,
227
+ blurDataURL: v.blurDataURL ?? (typeof staticData === "object" ? staticData.blurDataURL : void 0)
224
228
  };
225
229
  }
226
230
  /**
@@ -420,10 +424,11 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
420
424
  });
421
425
  }
422
426
  if (loader) {
427
+ const resolvedQuality = typeof quality === "string" ? Number(quality) : quality ?? 75;
423
428
  const resolvedSrc = loader({
424
429
  src,
425
430
  width: imgWidth ?? 0,
426
- quality: quality ?? 75
431
+ quality: resolvedQuality
427
432
  });
428
433
  preloadImageResource({
429
434
  shouldPreload,
@@ -513,7 +518,7 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
513
518
  });
514
519
  }
515
520
  }
516
- const imgQuality = quality ?? 75;
521
+ const imgQuality = typeof quality === "string" ? Number(quality) : quality ?? 75;
517
522
  const skipOptimization = isSvgUrl(src) && !__dangerouslyAllowSVG;
518
523
  const optimizedAttributes = imgWidth && !fill && !skipOptimization ? generateImageAttributes(src, imgWidth, imgQuality, sizes) : void 0;
519
524
  const srcSet = optimizedAttributes ? optimizedAttributes.srcSet : imgWidth && !fill ? RESPONSIVE_WIDTHS.filter((w) => w <= imgWidth * 2).map((w) => `${src} ${w}w`).join(", ") || `${src} ${imgWidth}w` : void 0;
@@ -577,7 +582,7 @@ function getImageProps(props) {
577
582
  backgroundRepeat: "no-repeat",
578
583
  backgroundPosition: "center"
579
584
  } : void 0;
580
- return { props: {
585
+ const imageProps = {
581
586
  src: renderedSrc,
582
587
  alt,
583
588
  width: fill ? void 0 : imgWidth,
@@ -586,13 +591,15 @@ function getImageProps(props) {
586
591
  fetchPriority: priority ? "high" : void 0,
587
592
  decoding: "async",
588
593
  className,
589
- "data-nimg": fill ? "fill" : "1",
590
594
  style: fill ? getFillStyle(style, blurStyle) : {
591
595
  ...blurStyle,
592
596
  ...style
593
597
  },
594
- ...rest
595
- } };
598
+ ...rest,
599
+ sizes: sizes ?? (fill ? "100vw" : void 0),
600
+ srcSet: void 0
601
+ };
602
+ return { props: Object.assign(imageProps, { "data-nimg": fill ? "fill" : "1" }) };
596
603
  }
597
604
  let blockedInProd = false;
598
605
  if (isRemoteUrl(src)) {
@@ -603,7 +610,7 @@ function getImageProps(props) {
603
610
  blockedInProd = true;
604
611
  }
605
612
  }
606
- const imgQuality = _quality ?? 75;
613
+ const imgQuality = typeof _quality === "string" ? Number(_quality) : _quality ?? 75;
607
614
  const resolvedSrc = blockedInProd ? "" : loader ? loader({
608
615
  src,
609
616
  width: imgWidth ?? 0,
@@ -620,7 +627,7 @@ function getImageProps(props) {
620
627
  backgroundRepeat: "no-repeat",
621
628
  backgroundPosition: "center"
622
629
  } : void 0;
623
- return { props: {
630
+ const imageProps = {
624
631
  src: optimizedSrc,
625
632
  alt,
626
633
  width: fill ? void 0 : imgWidth,
@@ -631,13 +638,13 @@ function getImageProps(props) {
631
638
  srcSet,
632
639
  sizes: sizes ?? (fill ? "100vw" : void 0),
633
640
  className,
634
- "data-nimg": fill ? "fill" : "1",
635
641
  style: fill ? getFillStyle(style, blurStyle) : {
636
642
  ...blurStyle,
637
643
  ...style
638
644
  },
639
645
  ...rest
640
- } };
646
+ };
647
+ return { props: Object.assign(imageProps, { "data-nimg": fill ? "fill" : "1" }) };
641
648
  }
642
649
  //#endregion
643
650
  export { Image as default, getImageProps, imageOptimizationUrl };
@@ -21,6 +21,8 @@ type SerializeSetCookieOptions = {
21
21
  httpOnly?: boolean;
22
22
  secure?: boolean;
23
23
  sameSite?: "Strict" | "Lax" | "None";
24
+ partitioned?: boolean;
25
+ priority?: "low" | "medium" | "high";
24
26
  };
25
27
  declare function validateCookieName(name: string): void;
26
28
  /**
@@ -35,7 +37,7 @@ declare function validateCookieAttributeValue(value: string, attributeName: stri
35
37
  * - Defaults `Path` to `/` (matching @edge-runtime/cookies and Next.js).
36
38
  * - Validates path/domain to reject control characters and semicolons.
37
39
  * - Emits attributes in the order: Path, Domain, Max-Age, Expires, HttpOnly,
38
- * Secure, SameSite.
40
+ * Secure, SameSite, Partitioned, Priority.
39
41
  *
40
42
  * The caller is responsible for validating the cookie name (typically before
41
43
  * mutating any internal state) via `validateCookieName`.
@@ -24,7 +24,7 @@ function validateCookieAttributeValue(value, attributeName) {
24
24
  * - Defaults `Path` to `/` (matching @edge-runtime/cookies and Next.js).
25
25
  * - Validates path/domain to reject control characters and semicolons.
26
26
  * - Emits attributes in the order: Path, Domain, Max-Age, Expires, HttpOnly,
27
- * Secure, SameSite.
27
+ * Secure, SameSite, Partitioned, Priority.
28
28
  *
29
29
  * The caller is responsible for validating the cookie name (typically before
30
30
  * mutating any internal state) via `validateCookieName`.
@@ -43,6 +43,8 @@ function serializeSetCookie(name, value, options) {
43
43
  if (options?.httpOnly) parts.push("HttpOnly");
44
44
  if (options?.secure) parts.push("Secure");
45
45
  if (options?.sameSite) parts.push(`SameSite=${options.sameSite}`);
46
+ if (options?.partitioned) parts.push("Partitioned");
47
+ if (options?.priority) parts.push(`Priority=${options.priority[0].toUpperCase()}${options.priority.slice(1)}`);
46
48
  return parts.join("; ");
47
49
  }
48
50
  //#endregion
@@ -1,4 +1,6 @@
1
- import { isExternalUrl, matchRewrite, parseCookies } from "../../config/config-matchers.js";
1
+ import { parseCookies } from "../../config/request-context.js";
2
+ import { isExternalUrl } from "../../utils/external-url.js";
3
+ import { matchRewrite } from "../../config/config-matchers.js";
2
4
  import { matchDirectHybridClientRoutes, resolveMatchedHybridClientRouteOwner, resolveSameOriginPathname } from "./hybrid-client-route-owner-direct.js";
3
5
  import { mergeRewriteQuery } from "../../utils/query.js";
4
6
  //#region src/shims/internal/hybrid-client-route-owner.ts
@@ -30,11 +30,11 @@ type NEXT_DATA = {
30
30
  locale?: string;
31
31
  locales?: string[];
32
32
  defaultLocale?: string;
33
- domainLocales?: Array<{
33
+ domainLocales?: ReadonlyArray<{
34
34
  domain: string;
35
35
  defaultLocale: string;
36
- locales?: string[];
37
- http?: boolean;
36
+ locales?: readonly string[];
37
+ http?: true;
38
38
  }>;
39
39
  scriptLoader?: unknown[];
40
40
  isPreview?: boolean;
@@ -1,41 +1,7 @@
1
1
  import React from "react";
2
+ import { ImageLoader, ImageLoaderProps, ImageProps } from "@vinext/types/next/upstream/dist/client/legacy/image";
2
3
 
3
4
  //#region src/shims/legacy-image.d.ts
4
- type LegacyImageProps = {
5
- src: string | {
6
- src: string;
7
- width: number;
8
- height: number;
9
- blurDataURL?: string;
10
- };
11
- alt: string;
12
- width?: number | string;
13
- height?: number | string; /** Legacy layout mode */
14
- layout?: "fixed" | "intrinsic" | "responsive" | "fill"; /** CSS object-fit (used with layout="fill") */
15
- objectFit?: React.CSSProperties["objectFit"]; /** CSS object-position (used with layout="fill") */
16
- objectPosition?: string;
17
- priority?: boolean;
18
- quality?: number;
19
- placeholder?: "blur" | "empty";
20
- blurDataURL?: string;
21
- loader?: (params: {
22
- src: string;
23
- width: number;
24
- quality?: number;
25
- }) => string;
26
- sizes?: string;
27
- className?: string;
28
- style?: React.CSSProperties;
29
- onLoad?: React.ReactEventHandler<HTMLImageElement>;
30
- onLoadingComplete?: (result: {
31
- naturalWidth: number;
32
- naturalHeight: number;
33
- }) => void;
34
- onError?: React.ReactEventHandler<HTMLImageElement>;
35
- loading?: "lazy" | "eager";
36
- unoptimized?: boolean;
37
- id?: string;
38
- };
39
- declare const LegacyImage: React.ForwardRefExoticComponent<LegacyImageProps & React.RefAttributes<HTMLImageElement>>;
5
+ declare function LegacyImage(props: ImageProps): React.ReactElement;
40
6
  //#endregion
41
- export { LegacyImage as default };
7
+ export { type ImageLoader, type ImageLoaderProps, type ImageProps, LegacyImage as default };
@@ -1,19 +1,9 @@
1
1
  import Image from "./image.js";
2
- import { forwardRef } from "react";
2
+ import "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  //#region src/shims/legacy-image.tsx
5
- /**
6
- * next/legacy/image shim
7
- *
8
- * Provides the pre-Next.js 13 Image component API with layout prop.
9
- * Translates legacy props (layout, objectFit, objectPosition) to the
10
- * modern Image component's fill/style props.
11
- *
12
- * This module is used by apps that ran the `next-image-to-legacy-image`
13
- * codemod when upgrading from Next.js 12.
14
- */
15
- const LegacyImage = forwardRef(function LegacyImage(props, ref) {
16
- const { layout = "intrinsic", objectFit, objectPosition, onLoadingComplete, onLoad, width, height, style, ...rest } = props;
5
+ function LegacyImage(props) {
6
+ const { layout = "intrinsic", objectFit, objectPosition, onLoadingComplete, onLoad, alt, width, height, style, lazyRoot: _lazyRoot, lazyBoundary: _lazyBoundary, ...rest } = props;
17
7
  const modernStyle = { ...style };
18
8
  if (objectFit) modernStyle.objectFit = objectFit;
19
9
  if (objectPosition) modernStyle.objectPosition = objectPosition;
@@ -26,7 +16,7 @@ const LegacyImage = forwardRef(function LegacyImage(props, ref) {
26
16
  onLoad?.(e);
27
17
  } : onLoad;
28
18
  if (layout === "fill") return /* @__PURE__ */ jsx(Image, {
29
- ref,
19
+ alt: alt ?? "",
30
20
  fill: true,
31
21
  style: modernStyle,
32
22
  onLoad: handleLoad,
@@ -37,13 +27,13 @@ const LegacyImage = forwardRef(function LegacyImage(props, ref) {
37
27
  modernStyle.height = "auto";
38
28
  }
39
29
  return /* @__PURE__ */ jsx(Image, {
40
- ref,
30
+ alt: alt ?? "",
41
31
  width: typeof width === "string" ? parseInt(width, 10) : width,
42
32
  height: typeof height === "string" ? parseInt(height, 10) : height,
43
33
  style: modernStyle,
44
34
  onLoad: handleLoad,
45
35
  ...rest
46
36
  });
47
- });
37
+ }
48
38
  //#endregion
49
39
  export { LegacyImage as default };
@@ -1,20 +1,11 @@
1
1
  import { VinextLinkPrefetchRoute } from "../client/vinext-next-data.js";
2
- import { UrlQuery } from "../utils/query.js";
2
+ import { UrlObject } from "node:url";
3
3
  import React, { AnchorHTMLAttributes } from "react";
4
4
 
5
5
  //#region src/shims/link.d.ts
6
- type NavigateEvent = {
7
- url: URL; /** Call to prevent the Link's default navigation (e.g. for View Transitions). */
8
- preventDefault(): void; /** Whether preventDefault() has been called. */
9
- defaultPrevented: boolean;
10
- };
11
- type LinkProps = {
12
- href: string | {
13
- pathname?: string;
14
- query?: UrlQuery;
15
- hash?: string;
16
- }; /** URL displayed in the browser (when href is a route pattern like /user/[id]) */
17
- as?: string; /** Replace the current history entry instead of pushing */
6
+ type LinkProps<_RouteInferType = unknown> = {
7
+ href: string | UrlObject; /** URL displayed in the browser (when href is a route pattern like /user/[id]) */
8
+ as?: string | UrlObject; /** Replace the current history entry instead of pushing */
18
9
  replace?: boolean; /** Prefetch the page in the background (App Router default: auto, Pages Router default: true) */
19
10
  prefetch?: boolean | "auto" | null;
20
11
  /**
@@ -40,7 +31,10 @@ type LinkProps = {
40
31
  */
41
32
  shallow?: boolean; /** Locale for i18n (used for locale-prefixed URLs) */
42
33
  locale?: string | false; /** Called before navigation happens (Next.js 16). Return value is ignored. */
43
- onNavigate?: (event: NavigateEvent) => void;
34
+ onNavigate?: (event: {
35
+ preventDefault(): void;
36
+ }) => void;
37
+ transitionTypes?: string[];
44
38
  children?: React.ReactNode;
45
39
  } & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href">;
46
40
  type LinkPrefetchMode = "disabled" | "auto" | "full" | "full-after-shell";
@@ -66,12 +60,8 @@ declare function resolveAutoAppRoutePrefetch(href: string): {
66
60
  shouldPrefetch: boolean;
67
61
  };
68
62
  declare const Link: React.ForwardRefExoticComponent<{
69
- href: string | {
70
- pathname?: string;
71
- query?: UrlQuery;
72
- hash?: string;
73
- }; /** URL displayed in the browser (when href is a route pattern like /user/[id]) */
74
- as?: string; /** Replace the current history entry instead of pushing */
63
+ href: string | UrlObject; /** URL displayed in the browser (when href is a route pattern like /user/[id]) */
64
+ as?: string | UrlObject; /** Replace the current history entry instead of pushing */
75
65
  replace?: boolean; /** Prefetch the page in the background (App Router default: auto, Pages Router default: true) */
76
66
  prefetch?: boolean | "auto" | null;
77
67
  /**
@@ -97,8 +87,11 @@ declare const Link: React.ForwardRefExoticComponent<{
97
87
  */
98
88
  shallow?: boolean; /** Locale for i18n (used for locale-prefixed URLs) */
99
89
  locale?: string | false; /** Called before navigation happens (Next.js 16). Return value is ignored. */
100
- onNavigate?: (event: NavigateEvent) => void;
90
+ onNavigate?: (event: {
91
+ preventDefault(): void;
92
+ }) => void;
93
+ transitionTypes?: string[];
101
94
  children?: React.ReactNode;
102
95
  } & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href"> & React.RefAttributes<HTMLAnchorElement>>;
103
96
  //#endregion
104
- export { canAutoPrefetchFullAppRoute, Link as default, resolveAutoAppRoutePrefetch, resolveLinkPrefetchMode, useLinkStatus };
97
+ export { LinkProps, canAutoPrefetchFullAppRoute, Link as default, resolveAutoAppRoutePrefetch, resolveLinkPrefetchMode, useLinkStatus };