vinext 0.0.14 → 0.0.16
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 +6 -0
- package/dist/cli.js +21 -11
- package/dist/cli.js.map +1 -1
- package/dist/config/config-matchers.d.ts +4 -1
- package/dist/config/config-matchers.d.ts.map +1 -1
- package/dist/config/config-matchers.js +11 -1
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +2 -0
- package/dist/config/next-config.d.ts.map +1 -1
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +2 -0
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -59
- package/dist/index.js.map +1 -1
- package/dist/server/app-dev-server.d.ts.map +1 -1
- package/dist/server/app-dev-server.js +29 -13
- package/dist/server/app-dev-server.js.map +1 -1
- package/dist/server/middleware.d.ts +23 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +44 -10
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/prod-server.d.ts.map +1 -1
- package/dist/server/prod-server.js +30 -4
- package/dist/server/prod-server.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts.map +1 -1
- package/dist/shims/fetch-cache.js +73 -41
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +68 -0
- package/dist/shims/font-google-base.d.ts.map +1 -0
- package/dist/shims/font-google-base.js +365 -0
- package/dist/shims/font-google-base.js.map +1 -0
- package/dist/shims/font-google.d.ts +2 -121
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.generated.d.ts +1925 -0
- package/dist/shims/font-google.generated.d.ts.map +1 -0
- package/dist/shims/font-google.generated.js +1928 -0
- package/dist/shims/font-google.generated.js.map +1 -0
- package/dist/shims/font-google.js +2 -386
- package/dist/shims/font-google.js.map +1 -1
- package/dist/shims/form.d.ts.map +1 -1
- package/dist/shims/form.js +32 -0
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/link.d.ts.map +1 -1
- package/dist/shims/link.js +11 -0
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/url-safety.d.ts +8 -0
- package/dist/shims/url-safety.d.ts.map +1 -0
- package/dist/shims/url-safety.js +16 -0
- package/dist/shims/url-safety.js.map +1 -0
- package/dist/utils/project.d.ts.map +1 -1
- package/dist/utils/project.js +4 -0
- package/dist/utils/project.js.map +1 -1
- package/package.json +2 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* before routing. Runs in Node (not Edge Runtime), per the vinext design.
|
|
6
6
|
*
|
|
7
7
|
* In Next.js 16, proxy.ts replaces middleware.ts:
|
|
8
|
-
* - proxy.ts: default export function, runs on Node.js runtime
|
|
8
|
+
* - proxy.ts: default export OR named `proxy` function, runs on Node.js runtime
|
|
9
9
|
* - middleware.ts: deprecated but still supported for Edge runtime use cases
|
|
10
10
|
*
|
|
11
11
|
* The proxy/middleware receives a NextRequest and can:
|
|
@@ -18,6 +18,28 @@
|
|
|
18
18
|
* Supports the `config.matcher` export for path filtering.
|
|
19
19
|
*/
|
|
20
20
|
import type { ViteDevServer } from "vite";
|
|
21
|
+
/**
|
|
22
|
+
* Determine whether a middleware/proxy file path refers to a proxy file.
|
|
23
|
+
* proxy.ts files accept `proxy` or `default` exports.
|
|
24
|
+
* middleware.ts files accept `middleware` or `default` exports.
|
|
25
|
+
*
|
|
26
|
+
* Matches Next.js behavior where each file type only accepts its own
|
|
27
|
+
* named export or a default export:
|
|
28
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts
|
|
29
|
+
*/
|
|
30
|
+
export declare function isProxyFile(filePath: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the middleware/proxy handler function from a module's exports.
|
|
33
|
+
* Matches Next.js behavior: for proxy files, check `proxy` then `default`;
|
|
34
|
+
* for middleware files, check `middleware` then `default`.
|
|
35
|
+
*
|
|
36
|
+
* Throws if the file exists but doesn't export a valid function, matching
|
|
37
|
+
* Next.js's ProxyMissingExportError behavior.
|
|
38
|
+
*
|
|
39
|
+
* @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts
|
|
40
|
+
* @see https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveMiddlewareHandler(mod: Record<string, unknown>, filePath: string): Function;
|
|
21
43
|
/**
|
|
22
44
|
* Find the proxy or middleware file in the project root.
|
|
23
45
|
* Checks for proxy.ts (Next.js 16) first, then falls back to middleware.ts.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAO1C;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,QAAQ,EAAE,MAAM,GACf,QAAQ,CAeV;AA0BD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqB9D;AAED,qDAAqD;AACrD,KAAK,aAAa,GACd,MAAM,GACN,MAAM,EAAE,GACR;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAA;CAAE,EAAE,CAAC;AAE1F;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,aAAa,GAAG,SAAS,GACjC,OAAO,CAqBT;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAkCvE;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,QAAQ,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,gBAAgB,CAAC,CAuH3B"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* before routing. Runs in Node (not Edge Runtime), per the vinext design.
|
|
6
6
|
*
|
|
7
7
|
* In Next.js 16, proxy.ts replaces middleware.ts:
|
|
8
|
-
* - proxy.ts: default export function, runs on Node.js runtime
|
|
8
|
+
* - proxy.ts: default export OR named `proxy` function, runs on Node.js runtime
|
|
9
9
|
* - middleware.ts: deprecated but still supported for Edge runtime use cases
|
|
10
10
|
*
|
|
11
11
|
* The proxy/middleware receives a NextRequest and can:
|
|
@@ -22,6 +22,42 @@ import path from "node:path";
|
|
|
22
22
|
import { NextRequest } from "../shims/server.js";
|
|
23
23
|
import { safeRegExp } from "../config/config-matchers.js";
|
|
24
24
|
import { normalizePath } from "./normalize-path.js";
|
|
25
|
+
/**
|
|
26
|
+
* Determine whether a middleware/proxy file path refers to a proxy file.
|
|
27
|
+
* proxy.ts files accept `proxy` or `default` exports.
|
|
28
|
+
* middleware.ts files accept `middleware` or `default` exports.
|
|
29
|
+
*
|
|
30
|
+
* Matches Next.js behavior where each file type only accepts its own
|
|
31
|
+
* named export or a default export:
|
|
32
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts
|
|
33
|
+
*/
|
|
34
|
+
export function isProxyFile(filePath) {
|
|
35
|
+
const base = path.basename(filePath).replace(/\.\w+$/, "");
|
|
36
|
+
return base === "proxy";
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the middleware/proxy handler function from a module's exports.
|
|
40
|
+
* Matches Next.js behavior: for proxy files, check `proxy` then `default`;
|
|
41
|
+
* for middleware files, check `middleware` then `default`.
|
|
42
|
+
*
|
|
43
|
+
* Throws if the file exists but doesn't export a valid function, matching
|
|
44
|
+
* Next.js's ProxyMissingExportError behavior.
|
|
45
|
+
*
|
|
46
|
+
* @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts
|
|
47
|
+
* @see https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts
|
|
48
|
+
*/
|
|
49
|
+
export function resolveMiddlewareHandler(mod, filePath) {
|
|
50
|
+
const isProxy = isProxyFile(filePath);
|
|
51
|
+
const handler = isProxy
|
|
52
|
+
? (mod.proxy ?? mod.default)
|
|
53
|
+
: (mod.middleware ?? mod.default);
|
|
54
|
+
if (typeof handler !== "function") {
|
|
55
|
+
const fileType = isProxy ? "Proxy" : "Middleware";
|
|
56
|
+
const expectedExport = isProxy ? "proxy" : "middleware";
|
|
57
|
+
throw new Error(`The ${fileType} file "${filePath}" must export a function named \`${expectedExport}\` or a \`default\` function.`);
|
|
58
|
+
}
|
|
59
|
+
return handler;
|
|
60
|
+
}
|
|
25
61
|
/**
|
|
26
62
|
* Possible proxy/middleware file names.
|
|
27
63
|
* proxy.ts (Next.js 16) is checked first, then middleware.ts (deprecated).
|
|
@@ -62,7 +98,7 @@ export function findMiddlewareFile(root) {
|
|
|
62
98
|
const fullPath = path.join(root, file);
|
|
63
99
|
if (fs.existsSync(fullPath)) {
|
|
64
100
|
console.warn("[vinext] middleware.ts is deprecated in Next.js 16. " +
|
|
65
|
-
"Rename to proxy.ts and export a default function.");
|
|
101
|
+
"Rename to proxy.ts and export a default or named proxy function.");
|
|
66
102
|
return fullPath;
|
|
67
103
|
}
|
|
68
104
|
}
|
|
@@ -153,12 +189,10 @@ export function matchPattern(pathname, pattern) {
|
|
|
153
189
|
export async function runMiddleware(server, middlewarePath, request) {
|
|
154
190
|
// Load the middleware module via Vite's SSR module loader
|
|
155
191
|
const mod = await server.ssrLoadModule(middlewarePath);
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return { continue: true };
|
|
161
|
-
}
|
|
192
|
+
// Resolve the handler based on file type (proxy.ts vs middleware.ts).
|
|
193
|
+
// Throws if the file doesn't export a valid function, matching Next.js behavior.
|
|
194
|
+
// https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts
|
|
195
|
+
const middlewareFn = resolveMiddlewareHandler(mod, middlewarePath);
|
|
162
196
|
// Check matcher config
|
|
163
197
|
const config = mod.config;
|
|
164
198
|
const matcher = config?.matcher;
|
|
@@ -215,7 +249,7 @@ export async function runMiddleware(server, middlewarePath, request) {
|
|
|
215
249
|
for (const [key, value] of response.headers) {
|
|
216
250
|
if (key !== "x-middleware-next" &&
|
|
217
251
|
key !== "x-middleware-rewrite") {
|
|
218
|
-
responseHeaders.
|
|
252
|
+
responseHeaders.append(key, value);
|
|
219
253
|
}
|
|
220
254
|
}
|
|
221
255
|
return { continue: true, responseHeaders };
|
|
@@ -238,7 +272,7 @@ export async function runMiddleware(server, middlewarePath, request) {
|
|
|
238
272
|
const responseHeaders = new Headers();
|
|
239
273
|
for (const [key, value] of response.headers) {
|
|
240
274
|
if (key !== "x-middleware-rewrite") {
|
|
241
|
-
responseHeaders.
|
|
275
|
+
responseHeaders.append(key, value);
|
|
242
276
|
}
|
|
243
277
|
}
|
|
244
278
|
// Parse the rewrite URL — may be absolute or relative
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * proxy.ts / middleware.ts runner\n *\n * Loads and executes the user's proxy.ts (Next.js 16) or middleware.ts file\n * before routing. Runs in Node (not Edge Runtime), per the vinext design.\n *\n * In Next.js 16, proxy.ts replaces middleware.ts:\n * - proxy.ts: default export function, runs on Node.js runtime\n * - middleware.ts: deprecated but still supported for Edge runtime use cases\n *\n * The proxy/middleware receives a NextRequest and can:\n * - Return NextResponse.next() to continue to the route\n * - Return NextResponse.redirect() to redirect\n * - Return NextResponse.rewrite() to rewrite the URL\n * - Set/modify headers and cookies\n * - Return a Response directly (e.g., for auth guards)\n *\n * Supports the `config.matcher` export for path filtering.\n */\n\nimport type { ViteDevServer } from \"vite\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { NextRequest } from \"../shims/server.js\";\nimport { safeRegExp } from \"../config/config-matchers.js\";\nimport { normalizePath } from \"./normalize-path.js\";\n\n/**\n * Possible proxy/middleware file names.\n * proxy.ts (Next.js 16) is checked first, then middleware.ts (deprecated).\n */\nconst PROXY_FILES = [\n \"proxy.ts\",\n \"proxy.js\",\n \"proxy.mjs\",\n \"src/proxy.ts\",\n \"src/proxy.js\",\n \"src/proxy.mjs\",\n];\n\nconst MIDDLEWARE_FILES = [\n \"middleware.ts\",\n \"middleware.tsx\",\n \"middleware.js\",\n \"middleware.mjs\",\n \"src/middleware.ts\",\n \"src/middleware.tsx\",\n \"src/middleware.js\",\n \"src/middleware.mjs\",\n];\n\n/**\n * Find the proxy or middleware file in the project root.\n * Checks for proxy.ts (Next.js 16) first, then falls back to middleware.ts.\n * If middleware.ts is found, logs a deprecation warning.\n */\nexport function findMiddlewareFile(root: string): string | null {\n // Check proxy.ts first (Next.js 16 replacement for middleware.ts)\n for (const file of PROXY_FILES) {\n const fullPath = path.join(root, file);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n // Fall back to middleware.ts (deprecated in Next.js 16)\n for (const file of MIDDLEWARE_FILES) {\n const fullPath = path.join(root, file);\n if (fs.existsSync(fullPath)) {\n console.warn(\n \"[vinext] middleware.ts is deprecated in Next.js 16. \" +\n \"Rename to proxy.ts and export a default function.\",\n );\n return fullPath;\n }\n }\n return null;\n}\n\n/** Matcher pattern from middleware config export. */\ntype MatcherConfig =\n | string\n | string[]\n | { source: string; regexp?: string; locale?: boolean; has?: any[]; missing?: any[] }[];\n\n/**\n * Check if a pathname matches the middleware matcher config.\n * If no matcher is configured, middleware runs on all paths\n * except static files and internal Next.js paths.\n */\nexport function matchesMiddleware(\n pathname: string,\n matcher: MatcherConfig | undefined,\n): boolean {\n if (!matcher) {\n // Next.js default: middleware runs on ALL paths when no matcher is configured.\n // Users opt out of specific paths by configuring a matcher pattern.\n return true;\n }\n\n const patterns: string[] = [];\n if (typeof matcher === \"string\") {\n patterns.push(matcher);\n } else if (Array.isArray(matcher)) {\n for (const m of matcher) {\n if (typeof m === \"string\") {\n patterns.push(m);\n } else if (m && typeof m === \"object\" && \"source\" in m) {\n patterns.push(m.source);\n }\n }\n }\n\n return patterns.some((pattern) => matchPattern(pathname, pattern));\n}\n\n/**\n * Match a single pattern against a pathname.\n * Supports Next.js matcher patterns:\n * /about -> exact match\n * /dashboard/:path* -> prefix match with params\n * /api/:path+ -> one or more segments\n * /((?!api|_next).*) -> regex patterns\n */\nexport function matchPattern(pathname: string, pattern: string): boolean {\n // Handle regex patterns (starts with /)\n if (pattern.includes(\"(\") || pattern.includes(\"\\\\\")) {\n const re = safeRegExp(\"^\" + pattern + \"$\");\n if (re) return re.test(pathname);\n // Fall through to simple matching\n }\n\n // Convert Next.js path patterns to regex in a single pass.\n // Matches /:param*, /:param+, :param, dots, and literal text.\n // Param names may contain hyphens (e.g. [[...sign-in]]).\n let regexStr = \"\";\n const tokenRe = /\\/:([\\w-]+)\\*|\\/:([\\w-]+)\\+|:([\\w-]+)|[.]|[^/:.]+|./g;\n let tok: RegExpExecArray | null;\n while ((tok = tokenRe.exec(pattern)) !== null) {\n if (tok[1] !== undefined) {\n // /:param* → optionally match slash + zero or more segments\n regexStr += \"(?:/.*)?\";\n } else if (tok[2] !== undefined) {\n // /:param+ → match slash + one or more segments\n regexStr += \"(?:/.+)\";\n } else if (tok[3] !== undefined) {\n // :param → match one segment\n regexStr += \"([^/]+)\";\n } else if (tok[0] === \".\") {\n regexStr += \"\\\\.\";\n } else {\n regexStr += tok[0];\n }\n }\n\n const re = safeRegExp(\"^\" + regexStr + \"$\");\n if (re) return re.test(pathname);\n return pathname === pattern;\n}\n\n/** Result of running middleware. */\nexport interface MiddlewareResult {\n /** Whether to continue to the route handler. */\n continue: boolean;\n /** If set, redirect to this URL. */\n redirectUrl?: string;\n /** HTTP status for redirect (default 307). */\n redirectStatus?: number;\n /** If set, rewrite to this URL (internal). */\n rewriteUrl?: string;\n /** HTTP status for rewrite (e.g. 403 from NextResponse.rewrite(url, { status: 403 })). */\n rewriteStatus?: number;\n /** Headers to set on the response. */\n responseHeaders?: Headers;\n /** If the middleware returned a full Response, use it directly. */\n response?: Response;\n}\n\n/**\n * Load and execute middleware for a given request.\n *\n * @param server - Vite dev server (for SSR module loading)\n * @param middlewarePath - Absolute path to the middleware file\n * @param request - The incoming Request object\n * @returns Middleware result describing what action to take\n */\nexport async function runMiddleware(\n server: ViteDevServer,\n middlewarePath: string,\n request: Request,\n): Promise<MiddlewareResult> {\n // Load the middleware module via Vite's SSR module loader\n const mod = await server.ssrLoadModule(middlewarePath);\n\n // Accept: default export, named \"proxy\" (Next.js 16), or named \"middleware\"\n const middlewareFn = mod.default ?? mod.proxy ?? mod.middleware;\n if (typeof middlewareFn !== \"function\") {\n // No proxy/middleware function exported — continue as normal\n return { continue: true };\n }\n\n // Check matcher config\n const config = mod.config;\n const matcher = config?.matcher;\n const url = new URL(request.url);\n\n // Normalize the pathname before middleware matching to prevent bypasses\n // via percent-encoding (/%61dmin → /admin) or double slashes (/dashboard//settings).\n let decodedPathname: string;\n try {\n decodedPathname = decodeURIComponent(url.pathname);\n } catch {\n // Malformed percent-encoding (e.g. /%E0%A4%A) — return 400 instead of throwing.\n return { continue: false, response: new Response(\"Bad Request\", { status: 400 }) };\n }\n const normalizedPathname = normalizePath(decodedPathname);\n\n if (!matchesMiddleware(normalizedPathname, matcher)) {\n return { continue: true };\n }\n\n // Construct a new Request with the fully decoded + normalized pathname so\n // middleware always sees the same canonical path that the router uses.\n let mwRequest = request;\n if (normalizedPathname !== url.pathname) {\n const mwUrl = new URL(url);\n mwUrl.pathname = normalizedPathname;\n mwRequest = new Request(mwUrl, request);\n }\n\n // Wrap in NextRequest so middleware gets .nextUrl, .cookies, .geo, .ip, etc.\n const nextRequest = mwRequest instanceof NextRequest ? mwRequest : new NextRequest(mwRequest);\n\n // Execute the middleware\n let response: Response | undefined;\n try {\n response = await middlewareFn(nextRequest);\n } catch (e: any) {\n console.error(\"[vinext] Middleware error:\", e);\n const message =\n process.env.NODE_ENV === \"production\"\n ? \"Internal Server Error\"\n : \"Middleware Error: \" + (e?.message ?? String(e));\n return {\n continue: false,\n response: new Response(message, {\n status: 500,\n }),\n };\n }\n\n // No response = continue\n if (!response) {\n return { continue: true };\n }\n\n // Check for x-middleware-next header (NextResponse.next())\n if (response.headers.get(\"x-middleware-next\") === \"1\") {\n // Continue to the route, but apply any headers the middleware set\n const responseHeaders = new Headers();\n for (const [key, value] of response.headers) {\n if (\n key !== \"x-middleware-next\" &&\n key !== \"x-middleware-rewrite\"\n ) {\n responseHeaders.set(key, value);\n }\n }\n return { continue: true, responseHeaders };\n }\n\n // Check for redirect (3xx status)\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get(\"Location\") ?? response.headers.get(\"location\");\n if (location) {\n return {\n continue: false,\n redirectUrl: location,\n redirectStatus: response.status,\n };\n }\n }\n\n // Check for rewrite (x-middleware-rewrite header)\n const rewriteUrl = response.headers.get(\"x-middleware-rewrite\");\n if (rewriteUrl) {\n // Continue to the route but with a rewritten URL\n const responseHeaders = new Headers();\n for (const [key, value] of response.headers) {\n if (key !== \"x-middleware-rewrite\") {\n responseHeaders.set(key, value);\n }\n }\n // Parse the rewrite URL — may be absolute or relative\n let rewritePath: string;\n try {\n const rewriteParsed = new URL(rewriteUrl, request.url);\n rewritePath = rewriteParsed.pathname + rewriteParsed.search;\n } catch {\n rewritePath = rewriteUrl;\n }\n return {\n continue: true,\n rewriteUrl: rewritePath,\n rewriteStatus: response.status !== 200 ? response.status : undefined,\n responseHeaders,\n };\n }\n\n // Middleware returned a full Response (e.g., blocking, custom body)\n return { continue: false, response };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * proxy.ts / middleware.ts runner\n *\n * Loads and executes the user's proxy.ts (Next.js 16) or middleware.ts file\n * before routing. Runs in Node (not Edge Runtime), per the vinext design.\n *\n * In Next.js 16, proxy.ts replaces middleware.ts:\n * - proxy.ts: default export OR named `proxy` function, runs on Node.js runtime\n * - middleware.ts: deprecated but still supported for Edge runtime use cases\n *\n * The proxy/middleware receives a NextRequest and can:\n * - Return NextResponse.next() to continue to the route\n * - Return NextResponse.redirect() to redirect\n * - Return NextResponse.rewrite() to rewrite the URL\n * - Set/modify headers and cookies\n * - Return a Response directly (e.g., for auth guards)\n *\n * Supports the `config.matcher` export for path filtering.\n */\n\nimport type { ViteDevServer } from \"vite\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { NextRequest } from \"../shims/server.js\";\nimport { safeRegExp } from \"../config/config-matchers.js\";\nimport { normalizePath } from \"./normalize-path.js\";\n\n/**\n * Determine whether a middleware/proxy file path refers to a proxy file.\n * proxy.ts files accept `proxy` or `default` exports.\n * middleware.ts files accept `middleware` or `default` exports.\n *\n * Matches Next.js behavior where each file type only accepts its own\n * named export or a default export:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts\n */\nexport function isProxyFile(filePath: string): boolean {\n const base = path.basename(filePath).replace(/\\.\\w+$/, \"\");\n return base === \"proxy\";\n}\n\n/**\n * Resolve the middleware/proxy handler function from a module's exports.\n * Matches Next.js behavior: for proxy files, check `proxy` then `default`;\n * for middleware files, check `middleware` then `default`.\n *\n * Throws if the file exists but doesn't export a valid function, matching\n * Next.js's ProxyMissingExportError behavior.\n *\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts\n * @see https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts\n */\nexport function resolveMiddlewareHandler(\n mod: Record<string, unknown>,\n filePath: string,\n): Function {\n const isProxy = isProxyFile(filePath);\n const handler = isProxy\n ? (mod.proxy ?? mod.default)\n : (mod.middleware ?? mod.default);\n\n if (typeof handler !== \"function\") {\n const fileType = isProxy ? \"Proxy\" : \"Middleware\";\n const expectedExport = isProxy ? \"proxy\" : \"middleware\";\n throw new Error(\n `The ${fileType} file \"${filePath}\" must export a function named \\`${expectedExport}\\` or a \\`default\\` function.`,\n );\n }\n\n return handler as Function;\n}\n\n/**\n * Possible proxy/middleware file names.\n * proxy.ts (Next.js 16) is checked first, then middleware.ts (deprecated).\n */\nconst PROXY_FILES = [\n \"proxy.ts\",\n \"proxy.js\",\n \"proxy.mjs\",\n \"src/proxy.ts\",\n \"src/proxy.js\",\n \"src/proxy.mjs\",\n];\n\nconst MIDDLEWARE_FILES = [\n \"middleware.ts\",\n \"middleware.tsx\",\n \"middleware.js\",\n \"middleware.mjs\",\n \"src/middleware.ts\",\n \"src/middleware.tsx\",\n \"src/middleware.js\",\n \"src/middleware.mjs\",\n];\n\n/**\n * Find the proxy or middleware file in the project root.\n * Checks for proxy.ts (Next.js 16) first, then falls back to middleware.ts.\n * If middleware.ts is found, logs a deprecation warning.\n */\nexport function findMiddlewareFile(root: string): string | null {\n // Check proxy.ts first (Next.js 16 replacement for middleware.ts)\n for (const file of PROXY_FILES) {\n const fullPath = path.join(root, file);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n // Fall back to middleware.ts (deprecated in Next.js 16)\n for (const file of MIDDLEWARE_FILES) {\n const fullPath = path.join(root, file);\n if (fs.existsSync(fullPath)) {\n console.warn(\n \"[vinext] middleware.ts is deprecated in Next.js 16. \" +\n \"Rename to proxy.ts and export a default or named proxy function.\",\n );\n return fullPath;\n }\n }\n return null;\n}\n\n/** Matcher pattern from middleware config export. */\ntype MatcherConfig =\n | string\n | string[]\n | { source: string; regexp?: string; locale?: boolean; has?: any[]; missing?: any[] }[];\n\n/**\n * Check if a pathname matches the middleware matcher config.\n * If no matcher is configured, middleware runs on all paths\n * except static files and internal Next.js paths.\n */\nexport function matchesMiddleware(\n pathname: string,\n matcher: MatcherConfig | undefined,\n): boolean {\n if (!matcher) {\n // Next.js default: middleware runs on ALL paths when no matcher is configured.\n // Users opt out of specific paths by configuring a matcher pattern.\n return true;\n }\n\n const patterns: string[] = [];\n if (typeof matcher === \"string\") {\n patterns.push(matcher);\n } else if (Array.isArray(matcher)) {\n for (const m of matcher) {\n if (typeof m === \"string\") {\n patterns.push(m);\n } else if (m && typeof m === \"object\" && \"source\" in m) {\n patterns.push(m.source);\n }\n }\n }\n\n return patterns.some((pattern) => matchPattern(pathname, pattern));\n}\n\n/**\n * Match a single pattern against a pathname.\n * Supports Next.js matcher patterns:\n * /about -> exact match\n * /dashboard/:path* -> prefix match with params\n * /api/:path+ -> one or more segments\n * /((?!api|_next).*) -> regex patterns\n */\nexport function matchPattern(pathname: string, pattern: string): boolean {\n // Handle regex patterns (starts with /)\n if (pattern.includes(\"(\") || pattern.includes(\"\\\\\")) {\n const re = safeRegExp(\"^\" + pattern + \"$\");\n if (re) return re.test(pathname);\n // Fall through to simple matching\n }\n\n // Convert Next.js path patterns to regex in a single pass.\n // Matches /:param*, /:param+, :param, dots, and literal text.\n // Param names may contain hyphens (e.g. [[...sign-in]]).\n let regexStr = \"\";\n const tokenRe = /\\/:([\\w-]+)\\*|\\/:([\\w-]+)\\+|:([\\w-]+)|[.]|[^/:.]+|./g;\n let tok: RegExpExecArray | null;\n while ((tok = tokenRe.exec(pattern)) !== null) {\n if (tok[1] !== undefined) {\n // /:param* → optionally match slash + zero or more segments\n regexStr += \"(?:/.*)?\";\n } else if (tok[2] !== undefined) {\n // /:param+ → match slash + one or more segments\n regexStr += \"(?:/.+)\";\n } else if (tok[3] !== undefined) {\n // :param → match one segment\n regexStr += \"([^/]+)\";\n } else if (tok[0] === \".\") {\n regexStr += \"\\\\.\";\n } else {\n regexStr += tok[0];\n }\n }\n\n const re = safeRegExp(\"^\" + regexStr + \"$\");\n if (re) return re.test(pathname);\n return pathname === pattern;\n}\n\n/** Result of running middleware. */\nexport interface MiddlewareResult {\n /** Whether to continue to the route handler. */\n continue: boolean;\n /** If set, redirect to this URL. */\n redirectUrl?: string;\n /** HTTP status for redirect (default 307). */\n redirectStatus?: number;\n /** If set, rewrite to this URL (internal). */\n rewriteUrl?: string;\n /** HTTP status for rewrite (e.g. 403 from NextResponse.rewrite(url, { status: 403 })). */\n rewriteStatus?: number;\n /** Headers to set on the response. */\n responseHeaders?: Headers;\n /** If the middleware returned a full Response, use it directly. */\n response?: Response;\n}\n\n/**\n * Load and execute middleware for a given request.\n *\n * @param server - Vite dev server (for SSR module loading)\n * @param middlewarePath - Absolute path to the middleware file\n * @param request - The incoming Request object\n * @returns Middleware result describing what action to take\n */\nexport async function runMiddleware(\n server: ViteDevServer,\n middlewarePath: string,\n request: Request,\n): Promise<MiddlewareResult> {\n // Load the middleware module via Vite's SSR module loader\n const mod = await server.ssrLoadModule(middlewarePath);\n\n // Resolve the handler based on file type (proxy.ts vs middleware.ts).\n // Throws if the file doesn't export a valid function, matching Next.js behavior.\n // https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts\n const middlewareFn = resolveMiddlewareHandler(mod, middlewarePath);\n\n // Check matcher config\n const config = mod.config;\n const matcher = config?.matcher;\n const url = new URL(request.url);\n\n // Normalize the pathname before middleware matching to prevent bypasses\n // via percent-encoding (/%61dmin → /admin) or double slashes (/dashboard//settings).\n let decodedPathname: string;\n try {\n decodedPathname = decodeURIComponent(url.pathname);\n } catch {\n // Malformed percent-encoding (e.g. /%E0%A4%A) — return 400 instead of throwing.\n return { continue: false, response: new Response(\"Bad Request\", { status: 400 }) };\n }\n const normalizedPathname = normalizePath(decodedPathname);\n\n if (!matchesMiddleware(normalizedPathname, matcher)) {\n return { continue: true };\n }\n\n // Construct a new Request with the fully decoded + normalized pathname so\n // middleware always sees the same canonical path that the router uses.\n let mwRequest = request;\n if (normalizedPathname !== url.pathname) {\n const mwUrl = new URL(url);\n mwUrl.pathname = normalizedPathname;\n mwRequest = new Request(mwUrl, request);\n }\n\n // Wrap in NextRequest so middleware gets .nextUrl, .cookies, .geo, .ip, etc.\n const nextRequest = mwRequest instanceof NextRequest ? mwRequest : new NextRequest(mwRequest);\n\n // Execute the middleware\n let response: Response | undefined;\n try {\n response = await middlewareFn(nextRequest);\n } catch (e: any) {\n console.error(\"[vinext] Middleware error:\", e);\n const message =\n process.env.NODE_ENV === \"production\"\n ? \"Internal Server Error\"\n : \"Middleware Error: \" + (e?.message ?? String(e));\n return {\n continue: false,\n response: new Response(message, {\n status: 500,\n }),\n };\n }\n\n // No response = continue\n if (!response) {\n return { continue: true };\n }\n\n // Check for x-middleware-next header (NextResponse.next())\n if (response.headers.get(\"x-middleware-next\") === \"1\") {\n // Continue to the route, but apply any headers the middleware set\n const responseHeaders = new Headers();\n for (const [key, value] of response.headers) {\n if (\n key !== \"x-middleware-next\" &&\n key !== \"x-middleware-rewrite\"\n ) {\n responseHeaders.append(key, value);\n }\n }\n return { continue: true, responseHeaders };\n }\n\n // Check for redirect (3xx status)\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get(\"Location\") ?? response.headers.get(\"location\");\n if (location) {\n return {\n continue: false,\n redirectUrl: location,\n redirectStatus: response.status,\n };\n }\n }\n\n // Check for rewrite (x-middleware-rewrite header)\n const rewriteUrl = response.headers.get(\"x-middleware-rewrite\");\n if (rewriteUrl) {\n // Continue to the route but with a rewritten URL\n const responseHeaders = new Headers();\n for (const [key, value] of response.headers) {\n if (key !== \"x-middleware-rewrite\") {\n responseHeaders.append(key, value);\n }\n }\n // Parse the rewrite URL — may be absolute or relative\n let rewritePath: string;\n try {\n const rewriteParsed = new URL(rewriteUrl, request.url);\n rewritePath = rewriteParsed.pathname + rewriteParsed.search;\n } catch {\n rewritePath = rewriteUrl;\n }\n return {\n continue: true,\n rewriteUrl: rewritePath,\n rewriteStatus: response.status !== 200 ? response.status : undefined,\n responseHeaders,\n };\n }\n\n // Middleware returned a full Response (e.g., blocking, custom body)\n return { continue: false, response };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prod-server.d.ts","sourceRoot":"","sources":["../../src/server/prod-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAuBpF,MAAM,WAAW,iBAAiB;IAChC,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,mDAAmD;AACnD,QAAA,MAAM,kBAAkB,aAetB,CAAC;AAEH,0GAA0G;AAC1G,QAAA,MAAM,kBAAkB,OAAO,CAAC;AAEhC;;;GAGG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAQjF;AAoBD;;;GAGG;AACH,iBAAS,cAAc,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACzC,QAAQ,GAAE,OAAc,GACvB,IAAI,CAkCN;AA0FD;;;;;;;;;;;GAWG;AACH,iBAAS,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED,4EAA4E;AAC5E,QAAA,MAAM,YAAY,EAAE,GAAG,CAAC,MAAM,CAK7B,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,UAAU,SAAkE,CAAC;AAEnF;;GAEG;AACH,iBAAS,gBAAgB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAmCvD;AA+ED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,iBAAsB,sFA6BpE;
|
|
1
|
+
{"version":3,"file":"prod-server.d.ts","sourceRoot":"","sources":["../../src/server/prod-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAuBpF,MAAM,WAAW,iBAAiB;IAChC,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,mDAAmD;AACnD,QAAA,MAAM,kBAAkB,aAetB,CAAC;AAEH,0GAA0G;AAC1G,QAAA,MAAM,kBAAkB,OAAO,CAAC;AAEhC;;;GAGG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAQjF;AAoBD;;;GAGG;AACH,iBAAS,cAAc,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACzC,QAAQ,GAAE,OAAc,GACvB,IAAI,CAkCN;AA0FD;;;;;;;;;;;GAWG;AACH,iBAAS,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED,4EAA4E;AAC5E,QAAA,MAAM,YAAY,EAAE,GAAG,CAAC,MAAM,CAK7B,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,UAAU,SAAkE,CAAC;AAEnF;;GAEG;AACH,iBAAS,gBAAgB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAmCvD;AA+ED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,iBAAsB,sFA6BpE;AAigBD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -652,15 +652,41 @@ async function startPagesRouterServer(options) {
|
|
|
652
652
|
if (result.response) {
|
|
653
653
|
// Use arrayBuffer() to handle binary response bodies correctly
|
|
654
654
|
const body = Buffer.from(await result.response.arrayBuffer());
|
|
655
|
-
|
|
655
|
+
// Preserve multi-value headers (especially Set-Cookie) by
|
|
656
|
+
// using getSetCookie() for cookies and forEach for the rest.
|
|
657
|
+
const respHeaders = {};
|
|
658
|
+
result.response.headers.forEach((value, key) => {
|
|
659
|
+
if (key.toLowerCase() === "set-cookie")
|
|
660
|
+
return; // handled below
|
|
661
|
+
respHeaders[key] = value;
|
|
662
|
+
});
|
|
663
|
+
const setCookies = result.response.headers.getSetCookie?.() ?? [];
|
|
664
|
+
if (setCookies.length > 0)
|
|
665
|
+
respHeaders["set-cookie"] = setCookies;
|
|
666
|
+
res.writeHead(result.response.status, respHeaders);
|
|
656
667
|
res.end(body);
|
|
657
668
|
return;
|
|
658
669
|
}
|
|
659
670
|
}
|
|
660
|
-
// Collect middleware response headers to merge into final response
|
|
671
|
+
// Collect middleware response headers to merge into final response.
|
|
672
|
+
// Use an array for Set-Cookie to preserve multiple values.
|
|
661
673
|
if (result.responseHeaders) {
|
|
662
674
|
for (const [key, value] of result.responseHeaders) {
|
|
663
|
-
|
|
675
|
+
if (key.toLowerCase() === "set-cookie") {
|
|
676
|
+
const existing = middlewareHeaders[key];
|
|
677
|
+
if (Array.isArray(existing)) {
|
|
678
|
+
existing.push(value);
|
|
679
|
+
}
|
|
680
|
+
else if (existing) {
|
|
681
|
+
middlewareHeaders[key] = [existing, value];
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
middlewareHeaders[key] = [value];
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
middlewareHeaders[key] = value;
|
|
689
|
+
}
|
|
664
690
|
}
|
|
665
691
|
}
|
|
666
692
|
// Apply middleware rewrite
|
|
@@ -690,7 +716,7 @@ async function startPagesRouterServer(options) {
|
|
|
690
716
|
let resolvedPathname = resolvedUrl.split("?")[0];
|
|
691
717
|
// ── 5. Apply custom headers from next.config.js ───────────────
|
|
692
718
|
if (configHeaders.length) {
|
|
693
|
-
const matched = matchHeaders(resolvedPathname, configHeaders);
|
|
719
|
+
const matched = matchHeaders(resolvedPathname, configHeaders, reqCtx);
|
|
694
720
|
for (const h of matched) {
|
|
695
721
|
middlewareHeaders[h.key.toLowerCase()] = h.value;
|
|
696
722
|
}
|