vinext 0.0.23 → 0.0.25
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/README.md +24 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +3 -2
- package/dist/check.js.map +1 -1
- package/dist/client/entry.js +1 -1
- package/dist/client/entry.js.map +1 -1
- package/dist/config/config-matchers.d.ts +21 -0
- package/dist/config/config-matchers.d.ts.map +1 -1
- package/dist/config/config-matchers.js +59 -9
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +8 -2
- package/dist/config/next-config.d.ts.map +1 -1
- package/dist/config/next-config.js +90 -35
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts +10 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +140 -56
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +195 -25
- package/dist/index.js.map +1 -1
- package/dist/plugins/async-hooks-stub.d.ts +16 -0
- package/dist/plugins/async-hooks-stub.d.ts.map +1 -0
- package/dist/plugins/async-hooks-stub.js +45 -0
- package/dist/plugins/async-hooks-stub.js.map +1 -0
- package/dist/routing/app-router.d.ts +12 -6
- package/dist/routing/app-router.d.ts.map +1 -1
- package/dist/routing/app-router.js +19 -40
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/pages-router.d.ts.map +1 -1
- package/dist/routing/pages-router.js +3 -9
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/utils.d.ts +9 -0
- package/dist/routing/utils.d.ts.map +1 -1
- package/dist/routing/utils.js +10 -0
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.d.ts.map +1 -1
- package/dist/server/api-handler.js +6 -0
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-dev-server.d.ts +2 -2
- package/dist/server/app-dev-server.d.ts.map +1 -1
- package/dist/server/app-dev-server.js +294 -133
- package/dist/server/app-dev-server.js.map +1 -1
- package/dist/server/dev-module-runner.d.ts +84 -0
- package/dist/server/dev-module-runner.d.ts.map +1 -0
- package/dist/server/dev-module-runner.js +105 -0
- package/dist/server/dev-module-runner.js.map +1 -0
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/instrumentation.d.ts +52 -9
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/instrumentation.js +52 -15
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/middleware.d.ts +7 -3
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +16 -6
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/prod-server.d.ts +8 -2
- package/dist/server/prod-server.d.ts.map +1 -1
- package/dist/server/prod-server.js +56 -35
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/worker-utils.d.ts +15 -0
- package/dist/server/worker-utils.d.ts.map +1 -0
- package/dist/server/worker-utils.js +41 -0
- package/dist/server/worker-utils.js.map +1 -0
- package/dist/shims/cache.d.ts.map +1 -1
- package/dist/shims/cache.js +14 -2
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts.map +1 -1
- package/dist/shims/fetch-cache.js +139 -29
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/form.d.ts.map +1 -1
- package/dist/shims/form.js +2 -3
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/headers.d.ts +6 -0
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/headers.js +8 -0
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/layout-segment-context.d.ts +5 -4
- package/dist/shims/layout-segment-context.d.ts.map +1 -1
- package/dist/shims/layout-segment-context.js +6 -5
- package/dist/shims/layout-segment-context.js.map +1 -1
- package/dist/shims/link.d.ts.map +1 -1
- package/dist/shims/link.js +32 -17
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/navigation.d.ts +14 -11
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/shims/navigation.js +122 -102
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/router.d.ts.map +1 -1
- package/dist/shims/router.js +37 -21
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/server.d.ts +2 -0
- package/dist/shims/server.d.ts.map +1 -1
- package/dist/shims/server.js +4 -0
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/url-utils.d.ts +13 -0
- package/dist/shims/url-utils.d.ts.map +1 -0
- package/dist/shims/url-utils.js +28 -0
- package/dist/shims/url-utils.js.map +1 -0
- package/dist/utils/project.d.ts +13 -1
- package/dist/utils/project.d.ts.map +1 -1
- package/dist/utils/project.js +63 -13
- package/dist/utils/project.js.map +1 -1
- package/package.json +6 -1
package/dist/deploy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,OAAO,EACL,cAAc,IAAI,eAAe,EACjC,gBAAgB,IAAI,iBAAiB,
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,OAAO,EACL,cAAc,IAAI,eAAe,EACjC,gBAAgB,IAAI,iBAAiB,EAGtC,MAAM,oBAAoB,CAAC;AAO5B,MAAM,WAAW,aAAa;IAC5B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE;;;;;;;;;;;EAc7C;AAID,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,wCAAwC;IACxC,aAAa,EAAE,OAAO,CAAC;IACvB,4CAA4C;IAC5C,MAAM,EAAE,OAAO,CAAC;IAChB,+BAA+B;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAID,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAsGvD;AAwHD,mCAAmC;AACnC,eAAO,MAAM,cAAc,wBAAkB,CAAC;AAE9C,qCAAqC;AACrC,eAAO,MAAM,gBAAgB,0BAAoB,CAAC;AAIlD,sCAAsC;AACtC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAiChE;AAED,8CAA8C;AAC9C,wBAAgB,4BAA4B,IAAI,MAAM,CAoDrD;AAED,gDAAgD;AAChD,wBAAgB,8BAA8B,IAAI,MAAM,CA6TvD;AAED,6CAA6C;AAC7C,wBAAgB,2BAA2B,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAgDtE;AAED,+CAA+C;AAC/C,wBAAgB,6BAA6B,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAmCxE;AAID,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ9E;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW;AACjB,+DAA+D;AAC/D,aAAa,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAA6B,GAC1E,UAAU,EAAE,CA2Bd;AAoBD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAkBnE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,EAAE,CAkCrE;AAmCD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACzB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,kBAAkB,CAO3G;AA2CD,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA2HlE"}
|
package/dist/deploy.js
CHANGED
|
@@ -19,7 +19,7 @@ import { createRequire } from "node:module";
|
|
|
19
19
|
import { execFileSync } from "node:child_process";
|
|
20
20
|
import { parseArgs as nodeParseArgs } from "node:util";
|
|
21
21
|
import { createBuilder, build } from "vite";
|
|
22
|
-
import { ensureESModule as _ensureESModule, renameCJSConfigs as _renameCJSConfigs, detectPackageManager as _detectPackageManager, } from "./utils/project.js";
|
|
22
|
+
import { ensureESModule as _ensureESModule, renameCJSConfigs as _renameCJSConfigs, detectPackageManager as _detectPackageManager, findInNodeModules as _findInNodeModules, } from "./utils/project.js";
|
|
23
23
|
import { getReactUpgradeDeps } from "./init.js";
|
|
24
24
|
import { runTPR } from "./cloudflare/tpr.js";
|
|
25
25
|
import { loadDotenv } from "./config/dotenv.js";
|
|
@@ -69,10 +69,12 @@ export function detectProject(root) {
|
|
|
69
69
|
fs.existsSync(path.join(root, "wrangler.toml"));
|
|
70
70
|
const hasWorkerEntry = fs.existsSync(path.join(root, "worker", "index.ts")) ||
|
|
71
71
|
fs.existsSync(path.join(root, "worker", "index.js"));
|
|
72
|
-
// Check node_modules for installed packages
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
72
|
+
// Check node_modules for installed packages.
|
|
73
|
+
// Walk up ancestor directories so that monorepo-hoisted packages are found
|
|
74
|
+
// even when node_modules lives at the workspace root rather than app root.
|
|
75
|
+
const hasCloudflarePlugin = _findInNodeModules(root, "@cloudflare/vite-plugin") !== null;
|
|
76
|
+
const hasRscPlugin = _findInNodeModules(root, "@vitejs/plugin-rsc") !== null;
|
|
77
|
+
const hasWrangler = _findInNodeModules(root, ".bin/wrangler") !== null;
|
|
76
78
|
// Derive project name from package.json or directory name
|
|
77
79
|
let projectName = path.basename(root);
|
|
78
80
|
const pkgPath = path.join(root, "package.json");
|
|
@@ -365,6 +367,7 @@ import {
|
|
|
365
367
|
matchRewrite,
|
|
366
368
|
matchHeaders,
|
|
367
369
|
requestContextFromRequest,
|
|
370
|
+
applyMiddlewareRequestHeaders,
|
|
368
371
|
isExternalUrl,
|
|
369
372
|
proxyExternalRequest,
|
|
370
373
|
sanitizeDestination,
|
|
@@ -384,6 +387,11 @@ interface Env {
|
|
|
384
387
|
};
|
|
385
388
|
}
|
|
386
389
|
|
|
390
|
+
interface ExecutionContext {
|
|
391
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
392
|
+
passThroughOnException(): void;
|
|
393
|
+
}
|
|
394
|
+
|
|
387
395
|
// Extract config values (embedded at build time in the server entry)
|
|
388
396
|
const basePath: string = vinextConfig?.basePath ?? "";
|
|
389
397
|
const trailingSlash: boolean = vinextConfig?.trailingSlash ?? false;
|
|
@@ -397,7 +405,7 @@ const imageConfig: ImageConfig | undefined = vinextConfig?.images ? {
|
|
|
397
405
|
} : undefined;
|
|
398
406
|
|
|
399
407
|
export default {
|
|
400
|
-
async fetch(request: Request, env: Env): Promise<Response> {
|
|
408
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
401
409
|
try {
|
|
402
410
|
const url = new URL(request.url);
|
|
403
411
|
let pathname = url.pathname;
|
|
@@ -457,15 +465,19 @@ export default {
|
|
|
457
465
|
}
|
|
458
466
|
|
|
459
467
|
// Build request context for has/missing condition matching.
|
|
460
|
-
//
|
|
468
|
+
// headers and redirects run before middleware, so they use this
|
|
469
|
+
// pre-middleware snapshot. beforeFiles, afterFiles, and fallback
|
|
470
|
+
// rewrites run after middleware (App Router order), so they use
|
|
471
|
+
// postMwReqCtx created after x-middleware-request-* headers are
|
|
472
|
+
// unpacked into request.
|
|
461
473
|
const reqCtx = requestContextFromRequest(request);
|
|
462
474
|
|
|
463
475
|
// ── 3. Run middleware ──────────────────────────────────────────
|
|
464
476
|
let resolvedUrl = urlWithQuery;
|
|
465
|
-
const middlewareHeaders: Record<string, string> = {};
|
|
477
|
+
const middlewareHeaders: Record<string, string | string[]> = {};
|
|
466
478
|
let middlewareRewriteStatus: number | undefined;
|
|
467
479
|
if (typeof runMiddleware === "function") {
|
|
468
|
-
const result = await runMiddleware(request);
|
|
480
|
+
const result = await runMiddleware(request, ctx);
|
|
469
481
|
|
|
470
482
|
if (!result.continue) {
|
|
471
483
|
if (result.redirectUrl) {
|
|
@@ -479,10 +491,22 @@ export default {
|
|
|
479
491
|
}
|
|
480
492
|
}
|
|
481
493
|
|
|
482
|
-
// Collect middleware response headers to merge into final response
|
|
494
|
+
// Collect middleware response headers to merge into final response.
|
|
495
|
+
// Use an array for Set-Cookie to preserve multiple values.
|
|
483
496
|
if (result.responseHeaders) {
|
|
484
497
|
for (const [key, value] of result.responseHeaders) {
|
|
485
|
-
|
|
498
|
+
if (key === "set-cookie") {
|
|
499
|
+
const existing = middlewareHeaders[key];
|
|
500
|
+
if (Array.isArray(existing)) {
|
|
501
|
+
existing.push(value);
|
|
502
|
+
} else if (existing) {
|
|
503
|
+
middlewareHeaders[key] = [existing as string, value];
|
|
504
|
+
} else {
|
|
505
|
+
middlewareHeaders[key] = [value];
|
|
506
|
+
}
|
|
507
|
+
} else {
|
|
508
|
+
middlewareHeaders[key] = value;
|
|
509
|
+
}
|
|
486
510
|
}
|
|
487
511
|
}
|
|
488
512
|
|
|
@@ -495,49 +519,40 @@ export default {
|
|
|
495
519
|
middlewareRewriteStatus = result.rewriteStatus;
|
|
496
520
|
}
|
|
497
521
|
|
|
498
|
-
// Unpack x-middleware-request-* headers into the actual request
|
|
499
|
-
//
|
|
500
|
-
//
|
|
501
|
-
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
if (key.startsWith(mwReqPrefix)) {
|
|
505
|
-
const realName = key.slice(mwReqPrefix.length);
|
|
506
|
-
mwReqHeaders[realName] = middlewareHeaders[key];
|
|
507
|
-
delete middlewareHeaders[key];
|
|
508
|
-
} else if (key.startsWith("x-middleware-")) {
|
|
509
|
-
delete middlewareHeaders[key];
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
if (Object.keys(mwReqHeaders).length > 0) {
|
|
513
|
-
const newHeaders = new Headers(request.headers);
|
|
514
|
-
for (const [k, v] of Object.entries(mwReqHeaders)) {
|
|
515
|
-
newHeaders.set(k, v);
|
|
516
|
-
}
|
|
517
|
-
request = new Request(request.url, {
|
|
518
|
-
method: request.method,
|
|
519
|
-
headers: newHeaders,
|
|
520
|
-
body: request.body,
|
|
521
|
-
// @ts-expect-error -- duplex needed for streaming request bodies
|
|
522
|
-
duplex: request.body ? "half" : undefined,
|
|
523
|
-
});
|
|
524
|
-
}
|
|
522
|
+
// Unpack x-middleware-request-* headers into the actual request and strip
|
|
523
|
+
// all x-middleware-* internal signals. Rebuilds postMwReqCtx for use by
|
|
524
|
+
// beforeFiles, afterFiles, and fallback config rules (which run after
|
|
525
|
+
// middleware per the Next.js execution order).
|
|
526
|
+
const { postMwReqCtx, request: postMwReq } = applyMiddlewareRequestHeaders(middlewareHeaders, request);
|
|
527
|
+
request = postMwReq;
|
|
525
528
|
|
|
526
529
|
let resolvedPathname = resolvedUrl.split("?")[0];
|
|
527
530
|
|
|
528
531
|
// ── 4. Apply custom headers from next.config.js ───────────────
|
|
529
532
|
// Config headers are additive for multi-value headers (Vary,
|
|
530
533
|
// Set-Cookie) and override for everything else. Vary values are
|
|
531
|
-
// comma-joined per HTTP spec. Set-Cookie values are
|
|
532
|
-
//
|
|
533
|
-
//
|
|
534
|
+
// comma-joined per HTTP spec. Set-Cookie values are accumulated
|
|
535
|
+
// as arrays (RFC 6265 forbids comma-joining cookies).
|
|
536
|
+
// Middleware headers take precedence: skip config keys already set
|
|
537
|
+
// by middleware so middleware always wins for the same key.
|
|
534
538
|
if (configHeaders.length) {
|
|
535
539
|
const matched = matchHeaders(resolvedPathname, configHeaders, reqCtx);
|
|
536
540
|
for (const h of matched) {
|
|
537
541
|
const lk = h.key.toLowerCase();
|
|
538
|
-
if (
|
|
542
|
+
if (lk === "set-cookie") {
|
|
543
|
+
const existing = middlewareHeaders[lk];
|
|
544
|
+
if (Array.isArray(existing)) {
|
|
545
|
+
existing.push(h.value);
|
|
546
|
+
} else if (existing) {
|
|
547
|
+
middlewareHeaders[lk] = [existing as string, h.value];
|
|
548
|
+
} else {
|
|
549
|
+
middlewareHeaders[lk] = [h.value];
|
|
550
|
+
}
|
|
551
|
+
} else if (lk === "vary" && middlewareHeaders[lk]) {
|
|
539
552
|
middlewareHeaders[lk] += ", " + h.value;
|
|
540
|
-
} else {
|
|
553
|
+
} else if (!(lk in middlewareHeaders)) {
|
|
554
|
+
// Middleware headers take precedence: only set if middleware
|
|
555
|
+
// did not already place this key on the response.
|
|
541
556
|
middlewareHeaders[lk] = h.value;
|
|
542
557
|
}
|
|
543
558
|
}
|
|
@@ -561,7 +576,7 @@ export default {
|
|
|
561
576
|
|
|
562
577
|
// ��─ 6. Apply beforeFiles rewrites from next.config.js ─────────
|
|
563
578
|
if (configRewrites.beforeFiles?.length) {
|
|
564
|
-
const rewritten = matchRewrite(resolvedPathname, configRewrites.beforeFiles,
|
|
579
|
+
const rewritten = matchRewrite(resolvedPathname, configRewrites.beforeFiles, postMwReqCtx);
|
|
565
580
|
if (rewritten) {
|
|
566
581
|
if (isExternalUrl(rewritten)) {
|
|
567
582
|
return proxyExternalRequest(request, rewritten);
|
|
@@ -581,7 +596,7 @@ export default {
|
|
|
581
596
|
|
|
582
597
|
// ── 8. Apply afterFiles rewrites from next.config.js ──────────
|
|
583
598
|
if (configRewrites.afterFiles?.length) {
|
|
584
|
-
const rewritten = matchRewrite(resolvedPathname, configRewrites.afterFiles,
|
|
599
|
+
const rewritten = matchRewrite(resolvedPathname, configRewrites.afterFiles, postMwReqCtx);
|
|
585
600
|
if (rewritten) {
|
|
586
601
|
if (isExternalUrl(rewritten)) {
|
|
587
602
|
return proxyExternalRequest(request, rewritten);
|
|
@@ -598,7 +613,7 @@ export default {
|
|
|
598
613
|
|
|
599
614
|
// ── 10. Fallback rewrites (if SSR returned 404) ─────────────
|
|
600
615
|
if (response && response.status === 404 && configRewrites.fallback?.length) {
|
|
601
|
-
const fallbackRewrite = matchRewrite(resolvedPathname, configRewrites.fallback,
|
|
616
|
+
const fallbackRewrite = matchRewrite(resolvedPathname, configRewrites.fallback, postMwReqCtx);
|
|
602
617
|
if (fallbackRewrite) {
|
|
603
618
|
if (isExternalUrl(fallbackRewrite)) {
|
|
604
619
|
return proxyExternalRequest(request, fallbackRewrite);
|
|
@@ -622,19 +637,34 @@ export default {
|
|
|
622
637
|
|
|
623
638
|
/**
|
|
624
639
|
* Merge middleware/config headers into a response.
|
|
625
|
-
* Response headers take precedence over middleware headers
|
|
626
|
-
*
|
|
640
|
+
* Response headers take precedence over middleware headers for all headers
|
|
641
|
+
* except Set-Cookie, which is additive (both middleware and response cookies
|
|
642
|
+
* are preserved). Matches the behavior in prod-server.ts. Uses getSetCookie()
|
|
643
|
+
* to preserve multiple Set-Cookie values.
|
|
627
644
|
*/
|
|
628
645
|
function mergeHeaders(
|
|
629
646
|
response: Response,
|
|
630
|
-
extraHeaders: Record<string, string>,
|
|
647
|
+
extraHeaders: Record<string, string | string[]>,
|
|
631
648
|
statusOverride?: number,
|
|
632
649
|
): Response {
|
|
633
650
|
if (!Object.keys(extraHeaders).length && !statusOverride) return response;
|
|
634
|
-
|
|
635
|
-
//
|
|
636
|
-
const
|
|
637
|
-
|
|
651
|
+
const merged = new Headers();
|
|
652
|
+
// Middleware/config headers go in first (lower precedence)
|
|
653
|
+
for (const [k, v] of Object.entries(extraHeaders)) {
|
|
654
|
+
if (Array.isArray(v)) {
|
|
655
|
+
for (const item of v) merged.append(k, item);
|
|
656
|
+
} else {
|
|
657
|
+
merged.set(k, v);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
// Response headers overlay them (higher precedence), except Set-Cookie
|
|
661
|
+
// which is additive (both middleware and response cookies should be sent).
|
|
662
|
+
response.headers.forEach((v, k) => {
|
|
663
|
+
if (k === "set-cookie") return;
|
|
664
|
+
merged.set(k, v);
|
|
665
|
+
});
|
|
666
|
+
const responseCookies = response.headers.getSetCookie?.() ?? [];
|
|
667
|
+
for (const cookie of responseCookies) merged.append("set-cookie", cookie);
|
|
638
668
|
return new Response(response.body, {
|
|
639
669
|
status: statusOverride ?? response.status,
|
|
640
670
|
statusText: response.statusText,
|
|
@@ -752,8 +782,8 @@ _isResolvable = isPackageResolvable) {
|
|
|
752
782
|
}
|
|
753
783
|
}
|
|
754
784
|
if (info.hasMDX) {
|
|
755
|
-
// Check if @mdx-js/rollup is already installed
|
|
756
|
-
const hasMdxRollup =
|
|
785
|
+
// Check if @mdx-js/rollup is already installed (walk up for monorepo hoisting)
|
|
786
|
+
const hasMdxRollup = _findInNodeModules(info.root, "@mdx-js/rollup") !== null;
|
|
757
787
|
if (!hasMdxRollup) {
|
|
758
788
|
missing.push({ name: "@mdx-js/rollup", version: "latest" });
|
|
759
789
|
}
|
|
@@ -773,6 +803,35 @@ function installDeps(root, deps) {
|
|
|
773
803
|
});
|
|
774
804
|
}
|
|
775
805
|
const detectPackageManager = _detectPackageManager;
|
|
806
|
+
/**
|
|
807
|
+
* Check whether an existing vite.config file already imports and uses the
|
|
808
|
+
* Cloudflare Vite plugin. This is a heuristic text scan — it doesn't execute
|
|
809
|
+
* the config — so it may produce false negatives for unusual configurations.
|
|
810
|
+
*
|
|
811
|
+
* Returns true if `@cloudflare/vite-plugin` appears to be configured, false
|
|
812
|
+
* if it is missing (meaning the build will fail with "could not resolve
|
|
813
|
+
* virtual:vinext-rsc-entry").
|
|
814
|
+
*/
|
|
815
|
+
export function viteConfigHasCloudflarePlugin(root) {
|
|
816
|
+
const candidates = [
|
|
817
|
+
path.join(root, "vite.config.ts"),
|
|
818
|
+
path.join(root, "vite.config.js"),
|
|
819
|
+
path.join(root, "vite.config.mjs"),
|
|
820
|
+
];
|
|
821
|
+
for (const candidate of candidates) {
|
|
822
|
+
if (fs.existsSync(candidate)) {
|
|
823
|
+
try {
|
|
824
|
+
const content = fs.readFileSync(candidate, "utf-8");
|
|
825
|
+
return content.includes("@cloudflare/vite-plugin");
|
|
826
|
+
}
|
|
827
|
+
catch {
|
|
828
|
+
// unreadable — assume it might be fine
|
|
829
|
+
return true;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
776
835
|
export function getFilesToGenerate(info) {
|
|
777
836
|
const files = [];
|
|
778
837
|
if (!info.hasWranglerConfig) {
|
|
@@ -840,7 +899,10 @@ export function buildWranglerDeployArgs(options) {
|
|
|
840
899
|
return { args, env };
|
|
841
900
|
}
|
|
842
901
|
function runWranglerDeploy(root, options) {
|
|
843
|
-
|
|
902
|
+
// Walk up ancestor directories so the binary is found even when node_modules
|
|
903
|
+
// is hoisted to the workspace root in a monorepo.
|
|
904
|
+
const wranglerBin = _findInNodeModules(root, ".bin/wrangler") ??
|
|
905
|
+
path.join(root, "node_modules", ".bin", "wrangler"); // fallback for error message clarity
|
|
844
906
|
const execOpts = {
|
|
845
907
|
cwd: root,
|
|
846
908
|
stdio: "pipe",
|
|
@@ -925,6 +987,28 @@ export async function deploy(options) {
|
|
|
925
987
|
console.log();
|
|
926
988
|
writeGeneratedFiles(filesToGenerate);
|
|
927
989
|
}
|
|
990
|
+
// Warn if an existing vite.config.ts is missing the Cloudflare plugin.
|
|
991
|
+
// This is the most common cause of "could not resolve virtual:vinext-rsc-entry"
|
|
992
|
+
// errors — `vinext init` generates a minimal local-dev config without it.
|
|
993
|
+
if (info.hasViteConfig && !viteConfigHasCloudflarePlugin(root)) {
|
|
994
|
+
console.warn(`
|
|
995
|
+
Warning: your vite.config.ts does not appear to import @cloudflare/vite-plugin.
|
|
996
|
+
Cloudflare Workers deployment requires it. Add the plugin to your config:
|
|
997
|
+
|
|
998
|
+
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
999
|
+
|
|
1000
|
+
export default defineConfig({
|
|
1001
|
+
plugins: [
|
|
1002
|
+
vinext(),
|
|
1003
|
+
cloudflare(${info.isAppRouter ? `{
|
|
1004
|
+
viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
|
|
1005
|
+
}` : ""}),
|
|
1006
|
+
],
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
Or delete vite.config.ts and re-run \`vinext deploy\` to auto-generate it.
|
|
1010
|
+
`);
|
|
1011
|
+
}
|
|
928
1012
|
if (options.dryRun) {
|
|
929
1013
|
console.log("\n Dry run complete. Files generated but no build or deploy performed.\n");
|
|
930
1014
|
return;
|