@qzsy/vinext 0.1.9 → 0.1.11
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.
package/dist/deploy.js
CHANGED
|
@@ -378,7 +378,7 @@ import { fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath
|
|
|
378
378
|
import type { PagesPipelineDeps } from "vinext/server/pages-request-pipeline";
|
|
379
379
|
import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath } from "vinext/server/image-optimization";
|
|
380
380
|
import type { ImageConfig } from "vinext/server/image-optimization";
|
|
381
|
-
import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, isOpenRedirectShaped } from "vinext/server/request-pipeline";
|
|
381
|
+
import { bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, isOpenRedirectShaped } from "vinext/server/request-pipeline";
|
|
382
382
|
import { notFoundStaticAssetResponse } from "vinext/server/http-error-responses";
|
|
383
383
|
import { assetPrefixPathname, isNextStaticPath } from "vinext/utils/asset-prefix";
|
|
384
384
|
import { hasBasePath, stripBasePath } from "vinext/utils/base-path";
|
|
@@ -452,6 +452,7 @@ export default {
|
|
|
452
452
|
// forged to influence routing or impersonate internal state.
|
|
453
453
|
// Request.headers is immutable in Workers, so build a clean copy.
|
|
454
454
|
{
|
|
455
|
+
request = await bufferRequestBodyForHeaderClone(request);
|
|
455
456
|
const filteredHeaders = filterInternalHeaders(request.headers);
|
|
456
457
|
request = cloneRequestWithHeaders(request, filteredHeaders);
|
|
457
458
|
}
|
package/dist/index.js
CHANGED
|
@@ -341,6 +341,22 @@ const _fontGoogleShimPath = resolveShimModulePath(_shimsDir, "font-google");
|
|
|
341
341
|
const _appBrowserServerActionClientPath = resolveShimModulePath(normalizePathSeparators(path.resolve(__dirname, "server")), "app-browser-server-action-client");
|
|
342
342
|
const _appRscHandlerPath = resolveShimModulePath(normalizePathSeparators(path.resolve(__dirname, "server")), "app-rsc-handler");
|
|
343
343
|
const _canExternalizeAppRscHandler = _appRscHandlerPath.endsWith(".js");
|
|
344
|
+
const _defaultImageLoaderShimPath = resolveShimModulePath(_shimsDir, "default-image-loader");
|
|
345
|
+
/** Absolute path to `images.loaderFile` when configured; set in vinext:config. */
|
|
346
|
+
let _imageLoaderFile;
|
|
347
|
+
function isImageShimModule(importer) {
|
|
348
|
+
if (!importer) return false;
|
|
349
|
+
const normalized = normalizePathSeparators(importer.split("?")[0]);
|
|
350
|
+
return /\/shims\/image\.(tsx?|jsx?)$/.test(normalized);
|
|
351
|
+
}
|
|
352
|
+
function isDefaultImageLoaderRequest(id, importer) {
|
|
353
|
+
const cleanId = id.startsWith("\0") ? id.slice(1) : id;
|
|
354
|
+
const normalizedId = normalizePathSeparators(cleanId.split("?")[0]);
|
|
355
|
+
if (normalizedId === normalizePathSeparators(_defaultImageLoaderShimPath)) return true;
|
|
356
|
+
if (/\/shims\/default-image-loader\.(tsx?|jsx?)$/.test(normalizedId)) return true;
|
|
357
|
+
if (isImageShimModule(importer) && (cleanId === "./default-image-loader.js" || cleanId === "./default-image-loader" || cleanId === "./default-image-loader.ts" || cleanId === "./default-image-loader.tsx")) return true;
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
344
360
|
function isValidExportIdentifier(name) {
|
|
345
361
|
return /^[$A-Z_a-z][$\w]*$/.test(name);
|
|
346
362
|
}
|
|
@@ -623,6 +639,16 @@ function vinext(options = {}) {
|
|
|
623
639
|
serverOnlyShimPath: resolveShimModulePath(shimsDir, "server-only")
|
|
624
640
|
}),
|
|
625
641
|
dataUrlCssPlugin(),
|
|
642
|
+
{
|
|
643
|
+
name: "vinext:image-loader-file",
|
|
644
|
+
enforce: "pre",
|
|
645
|
+
resolveId: {
|
|
646
|
+
filter: { id: /default-image-loader/ },
|
|
647
|
+
handler(id, importer) {
|
|
648
|
+
if (_imageLoaderFile && isDefaultImageLoaderRequest(id, importer)) return _imageLoaderFile;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
},
|
|
626
652
|
{
|
|
627
653
|
name: "vinext:config",
|
|
628
654
|
enforce: "pre",
|
|
@@ -827,9 +853,7 @@ function vinext(options = {}) {
|
|
|
827
853
|
overlay: false
|
|
828
854
|
};
|
|
829
855
|
const cssModulesOverride = config.css?.modules === false || typeof config.css?.modules === "object" && "Loader" in config.css.modules ? {} : { modules: { Loader: sassComposesLoader.Loader } };
|
|
830
|
-
|
|
831
|
-
const imageLoaderFile = nextConfig.images?.loaderFile;
|
|
832
|
-
const imageLoaderAlias = imageLoaderFile != null ? { [defaultImageLoaderShimPath]: imageLoaderFile } : {};
|
|
856
|
+
_imageLoaderFile = nextConfig.images?.loaderFile;
|
|
833
857
|
const viteConfig = {
|
|
834
858
|
appType: "custom",
|
|
835
859
|
build: {
|
|
@@ -877,8 +901,7 @@ function vinext(options = {}) {
|
|
|
877
901
|
alias: {
|
|
878
902
|
...tsconfigPathAliases,
|
|
879
903
|
...nextConfig.aliases,
|
|
880
|
-
...nextShimMap
|
|
881
|
-
...imageLoaderAlias
|
|
904
|
+
...nextShimMap
|
|
882
905
|
},
|
|
883
906
|
dedupe: [
|
|
884
907
|
"react",
|
|
@@ -922,10 +945,10 @@ function vinext(options = {}) {
|
|
|
922
945
|
const incomingInclude = config.optimizeDeps?.include ?? [];
|
|
923
946
|
const depOptimizeAliasPlugin = {
|
|
924
947
|
name: "vinext:dep-optimize-alias",
|
|
925
|
-
resolveId(id) {
|
|
948
|
+
resolveId(id, importer) {
|
|
926
949
|
const shimBase = _reactServerShims.get(id);
|
|
927
950
|
if (shimBase !== void 0) return resolveShimModulePath(shimsDir, shimBase);
|
|
928
|
-
if (
|
|
951
|
+
if (_imageLoaderFile && isDefaultImageLoaderRequest(id, importer)) return _imageLoaderFile;
|
|
929
952
|
}
|
|
930
953
|
};
|
|
931
954
|
const depOptimizeNodeEnvOptions = getDepOptimizeNodeEnvOptions(viteMajorVersion, nodeEnvDefine);
|
|
@@ -3,7 +3,7 @@ import { runWithExecutionContext } from "../shims/request-context.js";
|
|
|
3
3
|
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "./headers.js";
|
|
4
4
|
import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
5
5
|
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
6
|
-
import { cloneRequestWithHeaders, filterInternalHeaders } from "./request-pipeline.js";
|
|
6
|
+
import { bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, filterInternalHeaders } from "./request-pipeline.js";
|
|
7
7
|
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
8
8
|
import { resolveStaticAssetSignal } from "./worker-utils.js";
|
|
9
9
|
import { readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
@@ -26,6 +26,7 @@ async function handleRequest(request, env, ctx) {
|
|
|
26
26
|
}
|
|
27
27
|
if (isNextStaticPath(url.pathname, __workerBasePath, __workerAssetPathPrefix)) return notFoundStaticAssetResponse();
|
|
28
28
|
{
|
|
29
|
+
request = await bufferRequestBodyForHeaderClone(request);
|
|
29
30
|
const prerenderRouteParamsPayload = readTrustedPrerenderRouteParams(request);
|
|
30
31
|
const filteredHeaders = filterInternalHeaders(request.headers);
|
|
31
32
|
const prerenderRouteParamsHeader = serializePrerenderRouteParamsHeader(prerenderRouteParamsPayload);
|
|
@@ -4,7 +4,7 @@ import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
|
4
4
|
import { ACTION_REVALIDATED_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "./headers.js";
|
|
5
5
|
import { isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
6
6
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
7
|
-
import { applyConfigHeadersToResponse, cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, resolvePublicFileRoute } from "./request-pipeline.js";
|
|
7
|
+
import { applyConfigHeadersToResponse, bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, resolvePublicFileRoute } from "./request-pipeline.js";
|
|
8
8
|
import { headersContextFromRequest } from "../shims/headers.js";
|
|
9
9
|
import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
10
10
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
@@ -18,10 +18,10 @@ import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./page
|
|
|
18
18
|
import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
19
19
|
import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
|
|
20
20
|
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
21
|
+
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
21
22
|
import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
|
|
22
23
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
23
24
|
import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
|
|
24
|
-
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
25
25
|
import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
|
|
26
26
|
import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
|
|
27
27
|
import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
|
|
@@ -488,6 +488,7 @@ function createAppRscHandler(options) {
|
|
|
488
488
|
return async function appRscHandler(rawRequest, ctx) {
|
|
489
489
|
options.registerCacheAdapters();
|
|
490
490
|
await options.ensureInstrumentation?.();
|
|
491
|
+
rawRequest = await bufferRequestBodyForHeaderClone(rawRequest);
|
|
491
492
|
const mwCtx = rawRequest.headers.get(VINEXT_MW_CTX_HEADER);
|
|
492
493
|
const hasDataRequestHeader = rawRequest.headers.get("x-nextjs-data") === "1";
|
|
493
494
|
const pagesDataUrl = new URL(rawRequest.url);
|
|
@@ -161,6 +161,18 @@ 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
|
+
/**
|
|
165
|
+
* Materialize the request body before header/url cloning.
|
|
166
|
+
*
|
|
167
|
+
* `cloneRequestWithHeaders` / `cloneRequestWithUrl` can lose a streaming body
|
|
168
|
+
* on Node/undici when the input is a foreign Request or when the underlying
|
|
169
|
+
* stream was partially consumed. Server actions and route handlers both rely on
|
|
170
|
+
* the body surviving internal header filtering, so we read it once up front
|
|
171
|
+
* and rebuild a fresh Request for the rest of the pipeline.
|
|
172
|
+
*
|
|
173
|
+
* Multipart bodies are left streaming so FormData parsing still works.
|
|
174
|
+
*/
|
|
175
|
+
declare function bufferRequestBodyForHeaderClone(request: Request): Promise<Request>;
|
|
164
176
|
/**
|
|
165
177
|
* Clone a Request while overriding headers, preserving metadata when possible.
|
|
166
178
|
*
|
|
@@ -184,4 +196,4 @@ declare function cloneRequestWithHeaders(request: Request, headers: Headers): Re
|
|
|
184
196
|
*/
|
|
185
197
|
declare function cloneRequestWithUrl(request: Request, url: string): Request;
|
|
186
198
|
//#endregion
|
|
187
|
-
export { HeaderRecord, INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
|
|
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 };
|
|
@@ -365,6 +365,56 @@ function getRequestCf(request) {
|
|
|
365
365
|
const cf = Reflect.get(request, "cf");
|
|
366
366
|
return cf === void 0 ? void 0 : cf;
|
|
367
367
|
}
|
|
368
|
+
const METHODS_THAT_MAY_HAVE_BODY = new Set([
|
|
369
|
+
"POST",
|
|
370
|
+
"PUT",
|
|
371
|
+
"PATCH",
|
|
372
|
+
"DELETE"
|
|
373
|
+
]);
|
|
374
|
+
/**
|
|
375
|
+
* Materialize the request body before header/url cloning.
|
|
376
|
+
*
|
|
377
|
+
* `cloneRequestWithHeaders` / `cloneRequestWithUrl` can lose a streaming body
|
|
378
|
+
* on Node/undici when the input is a foreign Request or when the underlying
|
|
379
|
+
* stream was partially consumed. Server actions and route handlers both rely on
|
|
380
|
+
* the body surviving internal header filtering, so we read it once up front
|
|
381
|
+
* and rebuild a fresh Request for the rest of the pipeline.
|
|
382
|
+
*
|
|
383
|
+
* Multipart bodies are left streaming so FormData parsing still works.
|
|
384
|
+
*/
|
|
385
|
+
async function bufferRequestBodyForHeaderClone(request) {
|
|
386
|
+
if (!METHODS_THAT_MAY_HAVE_BODY.has(request.method.toUpperCase())) return request;
|
|
387
|
+
if (request.body === null) return request;
|
|
388
|
+
if ((request.headers.get("content-type") ?? "").startsWith("multipart/form-data")) return request;
|
|
389
|
+
try {
|
|
390
|
+
const bytes = await request.arrayBuffer();
|
|
391
|
+
const init = {
|
|
392
|
+
method: request.method,
|
|
393
|
+
headers: request.headers,
|
|
394
|
+
body: bytes,
|
|
395
|
+
redirect: request.redirect,
|
|
396
|
+
referrer: request.referrer,
|
|
397
|
+
referrerPolicy: request.referrerPolicy,
|
|
398
|
+
signal: request.signal,
|
|
399
|
+
credentials: request.credentials,
|
|
400
|
+
integrity: request.integrity,
|
|
401
|
+
keepalive: request.keepalive,
|
|
402
|
+
mode: request.mode,
|
|
403
|
+
cache: request.cache
|
|
404
|
+
};
|
|
405
|
+
if (bytes.byteLength > 0) init.duplex = "half";
|
|
406
|
+
const buffered = new Request(request.url, init);
|
|
407
|
+
const cf = getRequestCf(request);
|
|
408
|
+
if (cf !== void 0) Object.defineProperty(buffered, "cf", {
|
|
409
|
+
value: cf,
|
|
410
|
+
enumerable: true,
|
|
411
|
+
configurable: true
|
|
412
|
+
});
|
|
413
|
+
return buffered;
|
|
414
|
+
} catch {
|
|
415
|
+
return request;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
368
418
|
/**
|
|
369
419
|
* Clone a Request while overriding headers, preserving metadata when possible.
|
|
370
420
|
*
|
|
@@ -444,4 +494,4 @@ function cloneRequestWithUrl(request, url) {
|
|
|
444
494
|
return cloned;
|
|
445
495
|
}
|
|
446
496
|
//#endregion
|
|
447
|
-
export { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
|
|
497
|
+
export { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, applyConfigHeadersToHeaderRecord, applyConfigHeadersToResponse, bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
|