vinext 0.0.15 → 0.0.17
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 +13 -7
- package/dist/config/config-matchers.d.ts.map +1 -1
- package/dist/config/config-matchers.js +18 -9
- 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 +3 -1
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -62
- package/dist/index.js.map +1 -1
- package/dist/routing/app-router.d.ts.map +1 -1
- package/dist/routing/app-router.js +3 -2
- 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 +2 -1
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/server/app-dev-server.d.ts.map +1 -1
- package/dist/server/app-dev-server.js +43 -9
- 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 +42 -8
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/prod-server.js +1 -1
- 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/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
package/dist/index.js
CHANGED
|
@@ -5,12 +5,12 @@ import { createSSRHandler } from "./server/dev-server.js";
|
|
|
5
5
|
import { handleApiRoute } from "./server/api-handler.js";
|
|
6
6
|
import { generateRscEntry, generateSsrEntry, generateBrowserEntry, } from "./server/app-dev-server.js";
|
|
7
7
|
import { loadNextConfig, resolveNextConfig, } from "./config/next-config.js";
|
|
8
|
-
import { findMiddlewareFile, runMiddleware } from "./server/middleware.js";
|
|
8
|
+
import { findMiddlewareFile, isProxyFile, runMiddleware } from "./server/middleware.js";
|
|
9
9
|
import { generateSafeRegExpCode, generateMiddlewareMatcherCode, generateNormalizePathCode } from "./server/middleware-codegen.js";
|
|
10
10
|
import { normalizePath } from "./server/normalize-path.js";
|
|
11
11
|
import { findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
|
|
12
12
|
import { validateDevRequest } from "./server/dev-origin-check.js";
|
|
13
|
-
import { safeRegExp,
|
|
13
|
+
import { safeRegExp, isExternalUrl, proxyExternalRequest, parseCookies, matchHeaders, matchRedirect, matchRewrite, } from "./config/config-matchers.js";
|
|
14
14
|
import { scanMetadataFiles } from "./server/metadata-routes.js";
|
|
15
15
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
16
16
|
import MagicString from "magic-string";
|
|
@@ -18,6 +18,7 @@ import path from "node:path";
|
|
|
18
18
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
19
19
|
import { createRequire } from "node:module";
|
|
20
20
|
import fs from "node:fs";
|
|
21
|
+
import commonjs from "vite-plugin-commonjs";
|
|
21
22
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
22
23
|
/**
|
|
23
24
|
* Fetch Google Fonts CSS, download .woff2 files, cache locally, and return
|
|
@@ -493,6 +494,7 @@ export default function vinext(options = {}) {
|
|
|
493
494
|
let middlewarePath = null;
|
|
494
495
|
let instrumentationPath = null;
|
|
495
496
|
let hasCloudflarePlugin = false;
|
|
497
|
+
let hasNitroPlugin = false;
|
|
496
498
|
// Resolve shim paths - works both from source (.ts) and built (.js)
|
|
497
499
|
const shimsDir = path.resolve(__dirname, "shims");
|
|
498
500
|
// Shim alias map — populated in config(), used by resolveId() for .js variants
|
|
@@ -568,8 +570,15 @@ ${generateSafeRegExpCode("es5")}
|
|
|
568
570
|
${generateMiddlewareMatcherCode("es5")}
|
|
569
571
|
|
|
570
572
|
export async function runMiddleware(request) {
|
|
571
|
-
var
|
|
572
|
-
|
|
573
|
+
var isProxy = ${middlewarePath ? JSON.stringify(isProxyFile(middlewarePath)) : "false"};
|
|
574
|
+
var middlewareFn = isProxy
|
|
575
|
+
? (middlewareModule.proxy ?? middlewareModule.default)
|
|
576
|
+
: (middlewareModule.middleware ?? middlewareModule.default);
|
|
577
|
+
if (typeof middlewareFn !== "function") {
|
|
578
|
+
var fileType = isProxy ? "Proxy" : "Middleware";
|
|
579
|
+
var expectedExport = isProxy ? "proxy" : "middleware";
|
|
580
|
+
throw new Error("The " + fileType + " file must export a function named \`" + expectedExport + "\` or a \`default\` function.");
|
|
581
|
+
}
|
|
573
582
|
|
|
574
583
|
var config = middlewareModule.config;
|
|
575
584
|
var matcher = config && config.matcher;
|
|
@@ -606,9 +615,13 @@ export async function runMiddleware(request) {
|
|
|
606
615
|
if (response.headers.get("x-middleware-next") === "1") {
|
|
607
616
|
var rHeaders = new Headers();
|
|
608
617
|
for (var [key, value] of response.headers) {
|
|
609
|
-
//
|
|
610
|
-
//
|
|
611
|
-
|
|
618
|
+
// Keep x-middleware-request-* headers so the production server can
|
|
619
|
+
// apply middleware-request header overrides before stripping internals
|
|
620
|
+
// from the final client response.
|
|
621
|
+
if (
|
|
622
|
+
!key.startsWith("x-middleware-") ||
|
|
623
|
+
key.startsWith("x-middleware-request-")
|
|
624
|
+
) rHeaders.append(key, value);
|
|
612
625
|
}
|
|
613
626
|
return { continue: true, responseHeaders: rHeaders };
|
|
614
627
|
}
|
|
@@ -621,7 +634,9 @@ export async function runMiddleware(request) {
|
|
|
621
634
|
var rewriteUrl = response.headers.get("x-middleware-rewrite");
|
|
622
635
|
if (rewriteUrl) {
|
|
623
636
|
var rwHeaders = new Headers();
|
|
624
|
-
for (var [k, v] of response.headers) {
|
|
637
|
+
for (var [k, v] of response.headers) {
|
|
638
|
+
if (!k.startsWith("x-middleware-") || k.startsWith("x-middleware-request-")) rwHeaders.append(k, v);
|
|
639
|
+
}
|
|
625
640
|
var rewritePath;
|
|
626
641
|
try { var parsed = new URL(rewriteUrl, request.url); rewritePath = parsed.pathname + parsed.search; }
|
|
627
642
|
catch { rewritePath = rewriteUrl; }
|
|
@@ -1534,6 +1549,9 @@ hydrate();
|
|
|
1534
1549
|
// Resolve tsconfig paths/baseUrl aliases so real-world Next.js repos
|
|
1535
1550
|
// that use @/*, #/*, or baseUrl imports work out of the box.
|
|
1536
1551
|
tsconfigPaths(),
|
|
1552
|
+
// Transform CJS require()/module.exports to ESM before other plugins
|
|
1553
|
+
// analyze imports (RSC directive scanning, shim resolution, etc.)
|
|
1554
|
+
commonjs(),
|
|
1537
1555
|
{
|
|
1538
1556
|
name: "vinext:config",
|
|
1539
1557
|
enforce: "pre",
|
|
@@ -1664,6 +1682,7 @@ hydrate();
|
|
|
1664
1682
|
}
|
|
1665
1683
|
flattenPlugins(config.plugins ?? []);
|
|
1666
1684
|
hasCloudflarePlugin = pluginsFlat.some((p) => p && typeof p === "object" && typeof p.name === "string" && (p.name === "vite-plugin-cloudflare" || p.name.startsWith("vite-plugin-cloudflare:")));
|
|
1685
|
+
hasNitroPlugin = pluginsFlat.some((p) => p && typeof p === "object" && typeof p.name === "string" && (p.name === "nitro" || p.name.startsWith("nitro:")));
|
|
1667
1686
|
// Resolve PostCSS string plugin names that Vite can't handle.
|
|
1668
1687
|
// Next.js projects commonly use array-form plugins like
|
|
1669
1688
|
// `plugins: ["@tailwindcss/postcss"]` which postcss-load-config
|
|
@@ -1715,7 +1734,7 @@ hydrate();
|
|
|
1715
1734
|
// In multi-env builds, manualChunks must only be set per-environment
|
|
1716
1735
|
// (on the client env), not globally — otherwise it leaks into RSC/SSR
|
|
1717
1736
|
// environments where it can cause asset resolution issues.
|
|
1718
|
-
const isMultiEnv = hasAppDir || hasCloudflarePlugin;
|
|
1737
|
+
const isMultiEnv = hasAppDir || hasCloudflarePlugin || hasNitroPlugin;
|
|
1719
1738
|
const viteConfig = {
|
|
1720
1739
|
// Disable Vite's default HTML serving - we handle all routing
|
|
1721
1740
|
appType: "custom",
|
|
@@ -1777,8 +1796,8 @@ hydrate();
|
|
|
1777
1796
|
},
|
|
1778
1797
|
// Externalize React packages from SSR transform — they are CJS and
|
|
1779
1798
|
// must be loaded natively by Node, not through Vite's ESM evaluator.
|
|
1780
|
-
// Skip when targeting
|
|
1781
|
-
...(hasCloudflarePlugin ? {} : {
|
|
1799
|
+
// Skip when targeting bundled runtimes (Cloudflare/Nitro bundle everything).
|
|
1800
|
+
...(hasCloudflarePlugin || hasNitroPlugin ? {} : {
|
|
1782
1801
|
ssr: {
|
|
1783
1802
|
external: ["react", "react-dom", "react-dom/server"],
|
|
1784
1803
|
},
|
|
@@ -1829,14 +1848,14 @@ hydrate();
|
|
|
1829
1848
|
];
|
|
1830
1849
|
viteConfig.environments = {
|
|
1831
1850
|
rsc: {
|
|
1832
|
-
...(hasCloudflarePlugin ? {} : {
|
|
1851
|
+
...(hasCloudflarePlugin || hasNitroPlugin ? {} : {
|
|
1833
1852
|
resolve: {
|
|
1834
1853
|
// Externalize native/heavy packages so the RSC environment
|
|
1835
1854
|
// loads them natively via Node rather than through Vite's
|
|
1836
1855
|
// ESM module evaluator (which can't handle native addons).
|
|
1837
1856
|
// Note: Do NOT externalize react/react-dom here — they must
|
|
1838
1857
|
// be bundled with the "react-server" condition for RSC.
|
|
1839
|
-
// Skip when targeting Cloudflare
|
|
1858
|
+
// Skip when targeting bundled runtimes (Cloudflare/Nitro).
|
|
1840
1859
|
external: [
|
|
1841
1860
|
"satori",
|
|
1842
1861
|
"@resvg/resvg-js",
|
|
@@ -1870,11 +1889,15 @@ hydrate();
|
|
|
1870
1889
|
client: {
|
|
1871
1890
|
optimizeDeps: {
|
|
1872
1891
|
exclude: ["vinext"],
|
|
1873
|
-
//
|
|
1874
|
-
//
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1892
|
+
// React packages aren't crawled from app/ source files,
|
|
1893
|
+
// so must be pre-included to avoid late discovery (#25).
|
|
1894
|
+
include: [
|
|
1895
|
+
"react",
|
|
1896
|
+
"react-dom",
|
|
1897
|
+
"react-dom/client",
|
|
1898
|
+
"react/jsx-runtime",
|
|
1899
|
+
"react/jsx-dev-runtime",
|
|
1900
|
+
],
|
|
1878
1901
|
},
|
|
1879
1902
|
build: {
|
|
1880
1903
|
// When targeting Cloudflare Workers, enable manifest generation
|
|
@@ -2297,13 +2320,25 @@ hydrate();
|
|
|
2297
2320
|
req.__vinextRewriteStatus = result.rewriteStatus;
|
|
2298
2321
|
}
|
|
2299
2322
|
}
|
|
2323
|
+
// Build request context once for has/missing condition checks
|
|
2324
|
+
// across headers, redirects, and rewrites.
|
|
2325
|
+
const reqUrl = new URL(url, `http://${req.headers.host || "localhost"}`);
|
|
2326
|
+
const reqCtxHeaders = new Headers(Object.fromEntries(Object.entries(req.headers)
|
|
2327
|
+
.filter(([, v]) => v !== undefined)
|
|
2328
|
+
.map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v)])));
|
|
2329
|
+
const reqCtx = {
|
|
2330
|
+
headers: reqCtxHeaders,
|
|
2331
|
+
cookies: parseCookies(reqCtxHeaders.get("cookie")),
|
|
2332
|
+
query: reqUrl.searchParams,
|
|
2333
|
+
host: reqCtxHeaders.get("host") ?? reqUrl.host,
|
|
2334
|
+
};
|
|
2300
2335
|
// Apply custom headers from next.config.js
|
|
2301
2336
|
if (nextConfig?.headers.length) {
|
|
2302
|
-
applyHeaders(pathname, res, nextConfig.headers);
|
|
2337
|
+
applyHeaders(pathname, res, nextConfig.headers, reqCtx);
|
|
2303
2338
|
}
|
|
2304
2339
|
// Apply redirects from next.config.js
|
|
2305
2340
|
if (nextConfig?.redirects.length) {
|
|
2306
|
-
const redirected = applyRedirects(pathname, res, nextConfig.redirects);
|
|
2341
|
+
const redirected = applyRedirects(pathname, res, nextConfig.redirects, reqCtx);
|
|
2307
2342
|
if (redirected)
|
|
2308
2343
|
return;
|
|
2309
2344
|
}
|
|
@@ -2311,7 +2346,7 @@ hydrate();
|
|
|
2311
2346
|
let resolvedUrl = url;
|
|
2312
2347
|
if (nextConfig?.rewrites.beforeFiles.length) {
|
|
2313
2348
|
resolvedUrl =
|
|
2314
|
-
applyRewrites(pathname, nextConfig.rewrites.beforeFiles) ??
|
|
2349
|
+
applyRewrites(pathname, nextConfig.rewrites.beforeFiles, reqCtx) ??
|
|
2315
2350
|
url;
|
|
2316
2351
|
}
|
|
2317
2352
|
// External rewrite from beforeFiles — proxy to external URL
|
|
@@ -2338,7 +2373,7 @@ hydrate();
|
|
|
2338
2373
|
// *resolved* pathname. Next.js applies these when route matching succeeds
|
|
2339
2374
|
// but allows overriding with rewrites.
|
|
2340
2375
|
if (nextConfig?.rewrites.afterFiles.length) {
|
|
2341
|
-
const afterRewrite = applyRewrites(resolvedUrl.split("?")[0], nextConfig.rewrites.afterFiles);
|
|
2376
|
+
const afterRewrite = applyRewrites(resolvedUrl.split("?")[0], nextConfig.rewrites.afterFiles, reqCtx);
|
|
2342
2377
|
if (afterRewrite)
|
|
2343
2378
|
resolvedUrl = afterRewrite;
|
|
2344
2379
|
}
|
|
@@ -2357,7 +2392,7 @@ hydrate();
|
|
|
2357
2392
|
}
|
|
2358
2393
|
// No route matched — try fallback rewrites
|
|
2359
2394
|
if (nextConfig?.rewrites.fallback.length) {
|
|
2360
|
-
const fallbackRewrite = applyRewrites(resolvedUrl.split("?")[0], nextConfig.rewrites.fallback);
|
|
2395
|
+
const fallbackRewrite = applyRewrites(resolvedUrl.split("?")[0], nextConfig.rewrites.fallback, reqCtx);
|
|
2361
2396
|
if (fallbackRewrite) {
|
|
2362
2397
|
// External fallback rewrite — proxy to external URL
|
|
2363
2398
|
if (isExternalUrl(fallbackRewrite)) {
|
|
@@ -3172,22 +3207,14 @@ function sanitizeDestinationLocal(dest) {
|
|
|
3172
3207
|
* Apply redirect rules from next.config.js.
|
|
3173
3208
|
* Returns true if a redirect was applied.
|
|
3174
3209
|
*/
|
|
3175
|
-
function applyRedirects(pathname, res, redirects) {
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
dest = dest.replace(`:${key}`, value);
|
|
3184
|
-
}
|
|
3185
|
-
// Sanitize to prevent open redirect via protocol-relative URLs
|
|
3186
|
-
dest = sanitizeDestinationLocal(dest);
|
|
3187
|
-
res.writeHead(redirect.permanent ? 308 : 307, { Location: dest });
|
|
3188
|
-
res.end();
|
|
3189
|
-
return true;
|
|
3190
|
-
}
|
|
3210
|
+
function applyRedirects(pathname, res, redirects, ctx) {
|
|
3211
|
+
const result = matchRedirect(pathname, redirects, ctx);
|
|
3212
|
+
if (result) {
|
|
3213
|
+
// Sanitize to prevent open redirect via protocol-relative URLs
|
|
3214
|
+
const dest = sanitizeDestinationLocal(result.destination);
|
|
3215
|
+
res.writeHead(result.permanent ? 308 : 307, { Location: dest });
|
|
3216
|
+
res.end();
|
|
3217
|
+
return true;
|
|
3191
3218
|
}
|
|
3192
3219
|
return false;
|
|
3193
3220
|
}
|
|
@@ -3254,35 +3281,21 @@ async function proxyExternalRewriteNode(req, res, externalUrl) {
|
|
|
3254
3281
|
* Apply rewrite rules from next.config.js.
|
|
3255
3282
|
* Returns the rewritten URL or null if no rewrite matched.
|
|
3256
3283
|
*/
|
|
3257
|
-
function applyRewrites(pathname, rewrites) {
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
for (const [key, value] of Object.entries(params)) {
|
|
3263
|
-
dest = dest.replace(`:${key}*`, value);
|
|
3264
|
-
dest = dest.replace(`:${key}+`, value);
|
|
3265
|
-
dest = dest.replace(`:${key}`, value);
|
|
3266
|
-
}
|
|
3267
|
-
// Sanitize to prevent open redirect via protocol-relative URLs
|
|
3268
|
-
dest = sanitizeDestinationLocal(dest);
|
|
3269
|
-
return dest;
|
|
3270
|
-
}
|
|
3284
|
+
function applyRewrites(pathname, rewrites, ctx) {
|
|
3285
|
+
const dest = matchRewrite(pathname, rewrites, ctx);
|
|
3286
|
+
if (dest) {
|
|
3287
|
+
// Sanitize to prevent open redirect via protocol-relative URLs
|
|
3288
|
+
return sanitizeDestinationLocal(dest);
|
|
3271
3289
|
}
|
|
3272
3290
|
return null;
|
|
3273
3291
|
}
|
|
3274
3292
|
/**
|
|
3275
3293
|
* Apply custom header rules from next.config.js.
|
|
3276
3294
|
*/
|
|
3277
|
-
function applyHeaders(pathname, res, headers) {
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
if (sourceRegex && sourceRegex.test(pathname)) {
|
|
3282
|
-
for (const header of rule.headers) {
|
|
3283
|
-
res.setHeader(header.key, header.value);
|
|
3284
|
-
}
|
|
3285
|
-
}
|
|
3295
|
+
function applyHeaders(pathname, res, headers, ctx) {
|
|
3296
|
+
const matched = matchHeaders(pathname, headers, ctx);
|
|
3297
|
+
for (const header of matched) {
|
|
3298
|
+
res.setHeader(header.key, header.value);
|
|
3286
3299
|
}
|
|
3287
3300
|
}
|
|
3288
3301
|
/**
|