@qzsy/vinext 0.1.87 → 0.1.89

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.
@@ -17,15 +17,15 @@ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscR
17
17
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
18
18
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
19
19
  import "../client/instrumentation-client.js";
20
+ import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
21
+ import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot } from "./app-browser-action-result.js";
22
+ import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
20
23
  import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
21
24
  import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
22
25
  import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
23
26
  import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
24
27
  import { navigationPlanner } from "./navigation-planner.js";
25
28
  import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
26
- import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
27
- import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot } from "./app-browser-action-result.js";
28
- import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
29
29
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
30
30
  import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
31
31
  import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
@@ -1,8 +1,8 @@
1
1
  import { stripBasePath } from "../utils/base-path.js";
2
2
  import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
3
3
  import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
4
- import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
5
4
  import { shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
5
+ import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
6
6
  import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
7
7
  import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
8
8
  import { startTransition, useInsertionEffect, useLayoutEffect } from "react";
@@ -1,4 +1,4 @@
1
- import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER } from "./headers.js";
1
+ import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, VINEXT_ACTION_BODY_HEADER } from "./headers.js";
2
2
  import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
3
3
  import { AppElementsWire } from "./app-elements-wire.js";
4
4
  import "./app-elements.js";
@@ -51,6 +51,13 @@ var ServerActionRedirectError = class extends Error {
51
51
  this.digest = `NEXT_REDIRECT;${redirectType};${encodeURIComponent(redirectHref)};${target.status};`;
52
52
  }
53
53
  };
54
+ function encodeActionBodyHeader(body) {
55
+ const bytes = new TextEncoder().encode(body);
56
+ if (bytes.byteLength > 6e3) return null;
57
+ let binary = "";
58
+ for (const byte of bytes) binary += String.fromCharCode(byte);
59
+ return btoa(binary);
60
+ }
54
61
  async function invokeClientServerAction(id, args, actionInitiation, deps) {
55
62
  deps.syncServerActionHttpFallbackHead(null);
56
63
  const temporaryReferences = createTemporaryReferenceSet();
@@ -62,6 +69,10 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
62
69
  elements: actionInitiation.routerState.elements,
63
70
  previousNextUrl: actionInitiation.routerState.previousNextUrl
64
71
  }).headers;
72
+ if (process.env.NODE_ENV !== "production" && typeof body === "string") {
73
+ const actionBodyHeader = encodeActionBodyHeader(body);
74
+ if (actionBodyHeader !== null) headers.set(VINEXT_ACTION_BODY_HEADER, actionBodyHeader);
75
+ }
65
76
  const fetchResponse = await fetch(createServerActionRequestUrl(actionInitiation.path), {
66
77
  method: "POST",
67
78
  headers,
@@ -6,12 +6,12 @@ import { AppElementsWire } from "./app-elements-wire.js";
6
6
  import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
7
7
  import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
8
8
  import { createCacheEntryReuseProof } from "./cache-proof.js";
9
+ import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
9
10
  import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
10
11
  import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
11
12
  import { verifyOperationTokenForCommit } from "./operation-token.js";
12
13
  import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
13
14
  import { createSnapshotPathAndSearch } from "../shims/navigation.js";
14
- import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
15
15
  //#region src/server/app-browser-state.ts
16
16
  const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
17
17
  const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "visited-cache" };
@@ -1,8 +1,8 @@
1
1
  import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
2
2
  import "./app-elements.js";
3
3
  import { mergeElements } from "../shims/slot.js";
4
- import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
5
4
  import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
5
+ import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
6
6
  import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
7
7
  //#region src/server/app-browser-visible-commit.ts
8
8
  const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
@@ -1,6 +1,6 @@
1
1
  import { isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
2
- import { runWithRootParamsUsage } from "../shims/root-params.js";
3
2
  import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
3
+ import { runWithRootParamsUsage } from "../shims/root-params.js";
4
4
  import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, finalizeRouteHandlerResponse, markRouteHandlerCacheMiss } from "./app-route-handler-response.js";
5
5
  import { createTrackedAppRouteRequest, markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
6
6
  import { createStaticGenerationHeadersContext, getAppRouteStaticGenerationErrorMessage } from "./app-static-generation.js";
@@ -19,11 +19,11 @@ import "./app-page-response.js";
19
19
  import { parseNextHttpErrorDigest } from "./next-error-digest.js";
20
20
  import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
21
21
  import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
22
- import { pickRootParams, setRootParams } from "../shims/root-params.js";
23
22
  import { flattenErrorCauses } from "../utils/error-cause.js";
24
23
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
25
24
  import { buildPageCacheTags } from "./implicit-tags.js";
26
25
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
26
+ import { pickRootParams, setRootParams } from "../shims/root-params.js";
27
27
  import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
28
28
  import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
29
29
  import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
@@ -1,9 +1,9 @@
1
1
  import { splitPathSegments } from "../routing/utils.js";
2
2
  import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
3
- import { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER } from "./headers.js";
3
+ import { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, VINEXT_ACTION_BODY_HEADER } from "./headers.js";
4
4
  import { isExternalUrl } from "../config/config-matchers.js";
5
5
  import { internalServerErrorResponse, payloadTooLargeResponse } from "./http-error-responses.js";
6
- import { validateCsrfOrigin, validateServerActionPayload } from "./request-pipeline.js";
6
+ import { readRawNodeRequestBytes, validateCsrfOrigin, validateServerActionPayload } from "./request-pipeline.js";
7
7
  import { APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI } from "./app-rsc-render-mode.js";
8
8
  import { headersContextFromRequest, isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
9
9
  import { getAndClearActionRevalidationKind } from "../shims/cache-request-state.js";
@@ -14,13 +14,13 @@ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityI
14
14
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
15
15
  import { applyEdgeRuntimeHeader } from "./app-page-response.js";
16
16
  import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
17
- import { createRootParamsUsageController, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage } from "../shims/root-params.js";
18
17
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
19
18
  import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
20
19
  import "./app-page-stream.js";
21
20
  import { buildAppPageTags } from "./implicit-tags.js";
22
21
  import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
23
22
  import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
23
+ import { createRootParamsUsageController, pickRootParams, runWithRootParamsScope, runWithRootParamsUsage } from "../shims/root-params.js";
24
24
  import { getSetCookieName } from "./cookie-utils.js";
25
25
  import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
26
26
  //#region src/server/app-server-action-execution.ts
@@ -186,11 +186,31 @@ function getServerActionFailureMessage(error) {
186
186
  function validateServerActionArgs(args) {
187
187
  if (args.length > SERVER_ACTION_ARGS_LIMIT) throw new Error(`Server Action arguments list is too long (${args.length}). Maximum allowed is ${SERVER_ACTION_ARGS_LIMIT}.`);
188
188
  }
189
+ function decodeBase64Utf8(value) {
190
+ const binary = atob(value);
191
+ const bytes = new Uint8Array(binary.length);
192
+ for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
193
+ return new TextDecoder().decode(bytes);
194
+ }
189
195
  async function readActionBodyWithLimit(request, maxBytes) {
190
- if (!request.body) return "";
191
- return readStreamAsTextWithLimit(request.body, maxBytes, () => {
192
- throw new Error("Request body too large");
193
- });
196
+ const actionBodyHeader = process.env.NODE_ENV === "production" ? null : request.headers.get(VINEXT_ACTION_BODY_HEADER);
197
+ if (actionBodyHeader) {
198
+ const restored = decodeBase64Utf8(actionBodyHeader);
199
+ if (new TextEncoder().encode(restored).byteLength > maxBytes) throw new Error("Request body too large");
200
+ return restored;
201
+ }
202
+ const contentLength = Number(request.headers.get("content-length") ?? "0");
203
+ if (request.body && !request.bodyUsed) {
204
+ const body = await readStreamAsTextWithLimit(request.body, maxBytes, () => {
205
+ throw new Error("Request body too large");
206
+ });
207
+ if (body.length > 0 || contentLength === 0) return body;
208
+ }
209
+ if (contentLength > 0) {
210
+ const rawBody = await readRawNodeRequestBytes(request, maxBytes);
211
+ if (rawBody !== null && rawBody.byteLength > 0) return new TextDecoder().decode(rawBody);
212
+ }
213
+ return "";
194
214
  }
195
215
  async function readActionFormDataWithLimit(request, maxBytes) {
196
216
  if (!request.body) return new FormData();
@@ -17,12 +17,12 @@ import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.
17
17
  import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
18
18
  import { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform } from "./app-ssr-stream.js";
19
19
  import { setPagesClientAssets } from "./pages-client-assets.js";
20
- import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
21
- import { runWithRootParamsScope } from "../shims/root-params.js";
22
20
  import { createInitialBfcacheMaps } from "./app-bfcache-identity.js";
23
21
  import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
24
22
  import { createClientReferencePreloader } from "./app-client-reference-preloader.js";
25
23
  import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
24
+ import { runWithRootParamsScope } from "../shims/root-params.js";
25
+ import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
26
26
  import { renderBeforeInteractiveInlineScripts } from "./before-interactive-head.js";
27
27
  import { createInitialDevServerErrorScript } from "./dev-initial-server-error.js";
28
28
  import { ssrAppRouterInstance } from "./app-ssr-router-instance.js";
@@ -21,6 +21,8 @@ declare const VINEXT_STATIC_FILE_HEADER = "x-vinext-static-file";
21
21
  declare const VINEXT_TIMING_HEADER = "x-vinext-timing";
22
22
  /** Dev-only server action log payload (JSON). Stripped before the response reaches the client. */
23
23
  declare const VINEXT_ACTION_LOG_HEADER = "x-vinext-action-log";
24
+ /** Small string Server Action body side-channel used when dev Request cloning drops the stream. */
25
+ declare const VINEXT_ACTION_BODY_HEADER = "x-vinext-action-body";
24
26
  /** Internal endpoint used to evaluate App Router generateStaticParams exports. */
25
27
  declare const VINEXT_PRERENDER_STATIC_PARAMS_PATH = "/__vinext/prerender/static-params";
26
28
  /** Internal endpoint used to evaluate Pages Router getStaticPaths exports. */
@@ -103,4 +105,4 @@ declare const INTERNAL_HEADERS: string[];
103
105
  /** Vinext-only internal headers stripped alongside Next.js protocol internals. */
104
106
  declare const VINEXT_INTERNAL_HEADERS: string[];
105
107
  //#endregion
106
- export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_ACTION_LOG_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
108
+ export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_ACTION_BODY_HEADER, VINEXT_ACTION_LOG_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
@@ -20,6 +20,8 @@ const VINEXT_STATIC_FILE_HEADER = "x-vinext-static-file";
20
20
  const VINEXT_TIMING_HEADER = "x-vinext-timing";
21
21
  /** Dev-only server action log payload (JSON). Stripped before the response reaches the client. */
22
22
  const VINEXT_ACTION_LOG_HEADER = "x-vinext-action-log";
23
+ /** Small string Server Action body side-channel used when dev Request cloning drops the stream. */
24
+ const VINEXT_ACTION_BODY_HEADER = "x-vinext-action-body";
23
25
  /** Internal endpoint used to evaluate App Router generateStaticParams exports. */
24
26
  const VINEXT_PRERENDER_STATIC_PARAMS_PATH = "/__vinext/prerender/static-params";
25
27
  /** Internal endpoint used to evaluate Pages Router getStaticPaths exports. */
@@ -124,4 +126,4 @@ const INTERNAL_HEADERS = [
124
126
  /** Vinext-only internal headers stripped alongside Next.js protocol internals. */
125
127
  const VINEXT_INTERNAL_HEADERS = [VINEXT_PRERENDER_ROUTE_PARAMS_HEADER];
126
128
  //#endregion
127
- export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_ACTION_LOG_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
129
+ export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_ACTION_BODY_HEADER, VINEXT_ACTION_LOG_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
@@ -161,6 +161,7 @@ declare function processMiddlewareHeaders(headers: Headers): void;
161
161
  * @returns A new Headers with internal framework headers removed
162
162
  */
163
163
  declare function filterInternalHeaders(headers: Headers): Headers;
164
+ declare function readRawNodeRequestBytes(request: Request, maxBytes?: number): Promise<Uint8Array | null>;
164
165
  /**
165
166
  * Materialize the request body before header/url cloning.
166
167
  *
@@ -196,4 +197,4 @@ declare function cloneRequestWithHeaders(request: Request, headers: Headers): Re
196
197
  */
197
198
  declare function cloneRequestWithUrl(request: Request, url: string): Request;
198
199
  //#endregion
199
- export { HeaderRecord, INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
200
+ export { HeaderRecord, INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, readRawNodeRequestBytes, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
@@ -366,6 +366,44 @@ function getRequestCf(request) {
366
366
  const cf = Reflect.get(request, "cf");
367
367
  return cf === void 0 ? void 0 : cf;
368
368
  }
369
+ function getRawNodeRequest(request) {
370
+ const raw = Reflect.get(request, "_request");
371
+ return raw === void 0 ? void 0 : raw;
372
+ }
373
+ function copyPrivateRequestMetadata(source, target) {
374
+ const cf = getRequestCf(source);
375
+ if (cf !== void 0) Object.defineProperty(target, "cf", {
376
+ value: cf,
377
+ enumerable: true,
378
+ configurable: true
379
+ });
380
+ const rawRequest = getRawNodeRequest(source);
381
+ if (rawRequest !== void 0) Object.defineProperty(target, "_request", {
382
+ value: rawRequest,
383
+ enumerable: true,
384
+ configurable: true
385
+ });
386
+ }
387
+ async function readRawNodeRequestBytes(request, maxBytes) {
388
+ const rawRequest = getRawNodeRequest(request);
389
+ if (!rawRequest || typeof rawRequest !== "object" || typeof rawRequest[Symbol.asyncIterator] !== "function") return null;
390
+ const encoder = new TextEncoder();
391
+ const chunks = [];
392
+ let totalSize = 0;
393
+ for await (const chunk of rawRequest) {
394
+ const bytes = typeof chunk === "string" ? encoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk);
395
+ totalSize += bytes.byteLength;
396
+ if (maxBytes !== void 0 && totalSize > maxBytes) throw new Error("Request body too large");
397
+ chunks.push(bytes);
398
+ }
399
+ const combined = new Uint8Array(totalSize);
400
+ let offset = 0;
401
+ for (const chunk of chunks) {
402
+ combined.set(chunk, offset);
403
+ offset += chunk.byteLength;
404
+ }
405
+ return combined;
406
+ }
369
407
  const METHODS_THAT_MAY_HAVE_BODY = new Set([
370
408
  "POST",
371
409
  "PUT",
@@ -388,7 +426,10 @@ async function bufferRequestBodyForHeaderClone(request) {
388
426
  if (request.body === null) return request;
389
427
  if ((request.headers.get("content-type") ?? "").startsWith("multipart/form-data")) return request;
390
428
  try {
391
- const bytes = await request.arrayBuffer();
429
+ const contentLength = Number(request.headers.get("content-length") ?? "0");
430
+ const rawBytes = contentLength > 0 ? await readRawNodeRequestBytes(request) : null;
431
+ const bytes = rawBytes && rawBytes.byteLength > 0 ? rawBytes : await request.clone().arrayBuffer();
432
+ if (bytes.byteLength === 0 && contentLength > 0) return request;
392
433
  const init = {
393
434
  method: request.method,
394
435
  headers: request.headers,
@@ -405,12 +446,7 @@ async function bufferRequestBodyForHeaderClone(request) {
405
446
  };
406
447
  if (bytes.byteLength > 0) init.duplex = "half";
407
448
  const buffered = new Request(request.url, init);
408
- const cf = getRequestCf(request);
409
- if (cf !== void 0) Object.defineProperty(buffered, "cf", {
410
- value: cf,
411
- enumerable: true,
412
- configurable: true
413
- });
449
+ copyPrivateRequestMetadata(request, buffered);
414
450
  return buffered;
415
451
  } catch {
416
452
  return request;
@@ -427,12 +463,15 @@ async function bufferRequestBodyForHeaderClone(request) {
427
463
  function cloneRequestWithHeaders(request, headers) {
428
464
  let cloned;
429
465
  try {
466
+ if (request.body) throw new Error("clone with body may drop stream");
430
467
  cloned = new Request(request, { headers });
431
468
  } catch {
469
+ const hasReadableBody = Boolean(request.body && !request.bodyUsed);
470
+ const bodySource = hasReadableBody ? request.clone() : request;
432
471
  const init = {
433
472
  method: request.method,
434
473
  headers,
435
- body: request.body ?? void 0,
474
+ body: hasReadableBody ? bodySource.body ?? void 0 : void 0,
436
475
  redirect: request.redirect,
437
476
  signal: request.signal,
438
477
  integrity: request.integrity,
@@ -442,15 +481,10 @@ function cloneRequestWithHeaders(request, headers) {
442
481
  referrer: request.referrer,
443
482
  referrerPolicy: request.referrerPolicy
444
483
  };
445
- if (request.body) init.duplex = "half";
484
+ if (hasReadableBody) init.duplex = "half";
446
485
  cloned = new Request(request.url, init);
447
486
  }
448
- const cf = getRequestCf(request);
449
- if (cf !== void 0) Object.defineProperty(cloned, "cf", {
450
- value: cf,
451
- enumerable: true,
452
- configurable: true
453
- });
487
+ copyPrivateRequestMetadata(request, cloned);
454
488
  return cloned;
455
489
  }
456
490
  /**
@@ -468,12 +502,15 @@ function cloneRequestWithHeaders(request, headers) {
468
502
  function cloneRequestWithUrl(request, url) {
469
503
  let cloned;
470
504
  try {
505
+ if (request.body) throw new Error("clone with body may drop stream");
471
506
  cloned = new Request(url, request);
472
507
  } catch {
508
+ const hasReadableBody = Boolean(request.body && !request.bodyUsed);
509
+ const bodySource = hasReadableBody ? request.clone() : request;
473
510
  const init = {
474
511
  method: request.method,
475
512
  headers: request.headers,
476
- body: request.body ?? void 0,
513
+ body: hasReadableBody ? bodySource.body ?? void 0 : void 0,
477
514
  redirect: request.redirect,
478
515
  signal: request.signal,
479
516
  integrity: request.integrity,
@@ -483,16 +520,11 @@ function cloneRequestWithUrl(request, url) {
483
520
  referrer: request.referrer,
484
521
  referrerPolicy: request.referrerPolicy
485
522
  };
486
- if (request.body) init.duplex = "half";
523
+ if (hasReadableBody) init.duplex = "half";
487
524
  cloned = new Request(url, init);
488
525
  }
489
- const cf = getRequestCf(request);
490
- if (cf !== void 0) Object.defineProperty(cloned, "cf", {
491
- value: cf,
492
- enumerable: true,
493
- configurable: true
494
- });
526
+ copyPrivateRequestMetadata(request, cloned);
495
527
  return cloned;
496
528
  }
497
529
  //#endregion
498
- export { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
530
+ export { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, readRawNodeRequestBytes, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
@@ -50,7 +50,7 @@ declare class RedirectErrorBoundary extends React.Component<{
50
50
  children?: React.ReactNode;
51
51
  });
52
52
  static getDerivedStateFromError(error: unknown): RedirectBoundaryState;
53
- render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
53
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
54
54
  }
55
55
  declare function RedirectBoundary({
56
56
  children
@@ -70,7 +70,7 @@ declare class ErrorBoundaryInner extends React.Component<ErrorBoundaryInnerProps
70
70
  componentDidMount(): void;
71
71
  componentWillUnmount(): void;
72
72
  reset: () => void;
73
- render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
73
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
74
74
  }
75
75
  declare function ErrorBoundary({
76
76
  fallback,
@@ -118,7 +118,7 @@ declare class ForbiddenBoundaryInner extends React.Component<ForbiddenBoundaryIn
118
118
  constructor(props: ForbiddenBoundaryInnerProps);
119
119
  static getDerivedStateFromProps(props: ForbiddenBoundaryInnerProps, state: ForbiddenBoundaryState): ForbiddenBoundaryState | null;
120
120
  static getDerivedStateFromError(error: unknown): Partial<ForbiddenBoundaryState>;
121
- render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
121
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
122
122
  }
123
123
  declare function ForbiddenBoundary({
124
124
  fallback,
@@ -142,7 +142,7 @@ declare class UnauthorizedBoundaryInner extends React.Component<UnauthorizedBoun
142
142
  constructor(props: UnauthorizedBoundaryInnerProps);
143
143
  static getDerivedStateFromProps(props: UnauthorizedBoundaryInnerProps, state: UnauthorizedBoundaryState): UnauthorizedBoundaryState | null;
144
144
  static getDerivedStateFromError(error: unknown): Partial<UnauthorizedBoundaryState>;
145
- render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
145
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
146
146
  }
147
147
  declare function UnauthorizedBoundary({
148
148
  fallback,
@@ -1,8 +1,8 @@
1
1
  import { GLOBAL_ACCESSORS_KEY, ServerInsertedHTMLContext, _registerStateAccessors, clearServerInsertedHTML, flushServerInsertedHTML, getLayoutSegmentContext, getNavigationContext, renderServerInsertedHTML, setNavigationContext } from "./navigation-context-state.js";
2
2
  import { BailoutToCSRError, DynamicServerError, HTTP_ERROR_FALLBACK_ERROR_CODE, RedirectType, forbidden, getAccessFallbackHTTPStatus, isBailoutToCSRError, isDynamicServerError, isHTTPAccessFallbackError, isNextRouterError, isRedirectError, notFound, permanentRedirect, redirect, unauthorized, unstable_rethrow } from "./navigation-errors.js";
3
3
  import "./navigation-server.js";
4
- import { throwClientHookError } from "./client-hook-error.js";
5
4
  import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
5
+ import { throwClientHookError } from "./client-hook-error.js";
6
6
  //#region src/shims/navigation.react-server.ts
7
7
  function usePathname() {
8
8
  throwClientHookError("usePathname()");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzsy/vinext",
3
- "version": "0.1.87",
3
+ "version": "0.1.89",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {