vinext 1.0.0-beta.10 → 1.0.0-beta.12
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 +12 -12
- package/THIRD_PARTY_LICENSES.md +25 -0
- package/dist/_virtual/_rolldown/runtime.js +25 -0
- package/dist/build/prerender-paths.d.ts +4 -0
- package/dist/build/prerender-paths.js +64 -32
- package/dist/build/prerender.d.ts +1 -1
- package/dist/build/prerender.js +1 -1
- package/dist/cache/cache-adapters-virtual.d.ts +3 -3
- package/dist/cache/cache-adapters-virtual.js +14 -7
- package/dist/check.js +74 -18
- package/dist/client/dev-error-overlay.js +1 -1
- package/dist/config/next-config.d.ts +4 -0
- package/dist/config/next-config.js +151 -6
- package/dist/config/prerender.d.ts +2 -2
- package/dist/config/prerender.js +2 -2
- package/dist/config/server-external-packages.d.ts +13 -1
- package/dist/config/server-external-packages.js +37 -3
- package/dist/deps/.pnpm/ignore@5.3.2/deps/ignore/index.js +189 -0
- package/dist/deps/.pnpm/ua-parser-js@1.0.35/deps/ua-parser-js/src/ua-parser.js +1057 -0
- package/dist/entries/app-rsc-entry.d.ts +4 -0
- package/dist/entries/app-rsc-entry.js +128 -29
- package/dist/entries/app-rsc-manifest.d.ts +2 -0
- package/dist/entries/app-rsc-manifest.js +9 -3
- package/dist/entries/app-ssr-entry.js +8 -1
- package/dist/entries/pages-server-entry.d.ts +1 -0
- package/dist/entries/pages-server-entry.js +67 -20
- package/dist/index.js +144 -29
- package/dist/plugins/instrumentation-client.d.ts +2 -1
- package/dist/plugins/instrumentation-client.js +45 -9
- package/dist/plugins/optimize-imports.d.ts +2 -1
- package/dist/plugins/optimize-imports.js +3 -1
- package/dist/plugins/use-cache-callable.js +32 -6
- package/dist/server/api-handler.js +7 -5
- package/dist/server/app-browser-entry.js +5 -4
- package/dist/server/app-browser-error.js +1 -1
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +6 -6
- package/dist/server/app-fetch-tracing.d.ts +15 -0
- package/dist/server/app-fetch-tracing.js +38 -0
- package/dist/server/app-metadata-tracing.d.ts +12 -0
- package/dist/server/app-metadata-tracing.js +17 -0
- package/dist/server/app-page-boundary-render.d.ts +2 -1
- package/dist/server/app-page-boundary-render.js +8 -3
- package/dist/server/app-page-cache-finalizer.d.ts +3 -0
- package/dist/server/app-page-cache-finalizer.js +20 -4
- package/dist/server/app-page-cache-render.d.ts +2 -0
- package/dist/server/app-page-cache-render.js +16 -2
- package/dist/server/app-page-dispatch.d.ts +3 -1
- package/dist/server/app-page-dispatch.js +44 -15
- package/dist/server/app-page-element-builder.js +87 -55
- package/dist/server/app-page-head.d.ts +4 -0
- package/dist/server/app-page-head.js +22 -9
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +2 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +9 -2
- package/dist/server/app-page-render.d.ts +20 -3
- package/dist/server/app-page-render.js +82 -7
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +16 -12
- package/dist/server/app-page-route-wiring.js +16 -10
- package/dist/server/app-page-stream.d.ts +12 -0
- package/dist/server/app-page-stream.js +32 -5
- package/dist/server/app-page-tracing.d.ts +33 -0
- package/dist/server/app-page-tracing.js +49 -0
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-request-stage-independent-entry.js +19 -3
- package/dist/server/app-response-header-provenance.js +2 -1
- package/dist/server/app-response-stage-entry.js +24 -4
- package/dist/server/app-route-handler-cache.js +46 -34
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +18 -8
- package/dist/server/app-route-handler-execution.d.ts +7 -2
- package/dist/server/app-route-handler-execution.js +64 -14
- package/dist/server/app-router-entry.d.ts +2 -0
- package/dist/server/app-router-entry.js +25 -5
- package/dist/server/app-rsc-error-handler.d.ts +11 -4
- package/dist/server/app-rsc-error-handler.js +15 -6
- package/dist/server/app-rsc-errors.d.ts +6 -2
- package/dist/server/app-rsc-errors.js +5 -5
- package/dist/server/app-rsc-handler.d.ts +9 -1
- package/dist/server/app-rsc-handler.js +61 -17
- package/dist/server/app-rsc-response-stage.js +16 -7
- package/dist/server/app-server-action-execution.d.ts +6 -2
- package/dist/server/app-server-action-execution.js +66 -22
- package/dist/server/app-ssr-entry.d.ts +4 -0
- package/dist/server/app-ssr-entry.js +23 -9
- package/dist/server/app-ssr-stream.js +25 -6
- package/dist/server/app-worker-stages.d.ts +5 -1
- package/dist/server/app-worker-stages.js +4 -4
- package/dist/server/cacheability-request.js +8 -1
- package/dist/server/client-trace-metadata.d.ts +5 -1
- package/dist/server/client-trace-metadata.js +27 -15
- package/dist/server/cloudflare-workers-tracing.d.ts +1 -0
- package/dist/server/cloudflare-workers-tracing.js +8 -0
- package/dist/server/defer-until-stream-consumed.d.ts +1 -1
- package/dist/server/defer-until-stream-consumed.js +2 -1
- package/dist/server/dev-server.js +96 -52
- package/dist/server/framework-tracer.d.ts +46 -0
- package/dist/server/framework-tracer.js +125 -0
- package/dist/server/fully-buffered-response.d.ts +11 -0
- package/dist/server/fully-buffered-response.js +19 -0
- package/dist/server/headers.d.ts +6 -0
- package/dist/server/headers.js +11 -2
- package/dist/server/html.d.ts +0 -20
- package/dist/server/html.js +16 -1
- package/dist/server/instrumentation-runtime.d.ts +16 -19
- package/dist/server/instrumentation-runtime.js +26 -8
- package/dist/server/instrumentation.d.ts +18 -21
- package/dist/server/instrumentation.js +18 -23
- package/dist/server/isr-cache.d.ts +3 -1
- package/dist/server/isr-cache.js +6 -5
- package/dist/server/metadata-route-response.d.ts +1 -0
- package/dist/server/metadata-route-response.js +59 -1
- package/dist/server/middleware-runtime.js +27 -1
- package/dist/server/opentelemetry-api.d.ts +59 -0
- package/dist/server/opentelemetry-api.js +53 -0
- package/dist/server/opentelemetry-tracing.d.ts +5 -0
- package/dist/server/opentelemetry-tracing.js +83 -0
- package/dist/server/otel-tracer-extension.d.ts +5 -6
- package/dist/server/otel-tracer-extension.js +37 -36
- package/dist/server/pages-api-route.js +6 -6
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +37 -2
- package/dist/server/pages-client-assets.d.ts +7 -0
- package/dist/server/pages-document-initial-props.d.ts +1 -0
- package/dist/server/pages-document-initial-props.js +1 -1
- package/dist/server/pages-execution-tracing.d.ts +40 -0
- package/dist/server/pages-execution-tracing.js +80 -0
- package/dist/server/pages-page-data.js +9 -8
- package/dist/server/pages-page-handler.d.ts +2 -0
- package/dist/server/pages-page-handler.js +45 -19
- package/dist/server/pages-page-response.d.ts +5 -0
- package/dist/server/pages-page-response.js +43 -27
- package/dist/server/pages-request-pipeline.js +7 -1
- package/dist/server/pages-request-stage-entry.js +18 -1
- package/dist/server/pages-response-stage-entry.js +3 -1
- package/dist/server/pages-router-entry.js +9 -2
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -0
- package/dist/server/pregenerated-concrete-paths.js +10 -6
- package/dist/server/prerender-manifest.d.ts +1 -0
- package/dist/server/prerender-manifest.js +6 -3
- package/dist/server/prerender-work-unit-setup.js +4 -4
- package/dist/server/prod-server.d.ts +2 -1
- package/dist/server/prod-server.js +93 -11
- package/dist/server/request-tracing.d.ts +22 -0
- package/dist/server/request-tracing.js +180 -0
- package/dist/server/response-stage-cacheability.d.ts +1 -0
- package/dist/server/response-stage-cacheability.js +2 -1
- package/dist/server/response-stage-policy.js +2 -1
- package/dist/server/response-start-tracing.d.ts +14 -0
- package/dist/server/response-start-tracing.js +80 -0
- package/dist/server/rsc-stream-hints.d.ts +12 -0
- package/dist/server/rsc-stream-hints.js +70 -35
- package/dist/server/seed-cache.js +6 -6
- package/dist/server/tracer.d.ts +5 -0
- package/dist/server/tracer.js +13 -0
- package/dist/server/workers-tracing.d.ts +17 -0
- package/dist/server/workers-tracing.js +27 -0
- package/dist/shims/cache-runtime.js +12 -6
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cacheability-classification.d.ts +4 -0
- package/dist/shims/cacheability-classification.js +7 -1
- package/dist/shims/cdn-cache.d.ts +3 -0
- package/dist/shims/cdn-cache.js +7 -0
- package/dist/shims/constants.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +6 -2
- package/dist/shims/error-boundary.js +1 -1
- package/dist/shims/error.js +1 -1
- package/dist/shims/fetch-cache.d.ts +1 -0
- package/dist/shims/fetch-cache.js +37 -14
- package/dist/shims/head.js +1 -1
- package/dist/shims/image-config.js +2 -0
- package/dist/shims/navigation.js +2 -2
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/script-nonce-context.d.ts +4 -1
- package/dist/shims/script-nonce-context.js +15 -6
- package/dist/shims/server.d.ts +3 -34
- package/dist/shims/server.js +1 -19
- package/dist/shims/unified-request-context.d.ts +3 -16
- package/dist/shims/unified-request-context.js +2 -23
- package/dist/shims/user-agent.d.ts +31 -0
- package/dist/shims/user-agent.js +16 -0
- package/dist/utils/client-runtime-metadata.d.ts +6 -0
- package/dist/utils/client-runtime-metadata.js +16 -0
- package/dist/utils/lazy-chunks.js +1 -1
- package/dist/utils/navigation-signal.d.ts +1 -0
- package/dist/utils/navigation-signal.js +16 -1
- package/dist/utils/project.js +1 -1
- package/next-package.json +4 -0
- package/package.json +15 -2
package/README.md
CHANGED
|
@@ -4,9 +4,7 @@ Run Next.js applications on Vite, with Cloudflare Workers as the primary deploym
|
|
|
4
4
|
|
|
5
5
|
**Website:** [vinext.dev](https://vinext.dev)
|
|
6
6
|
|
|
7
|
-
**Documentation:**
|
|
8
|
-
|
|
9
|
-
- [Caching](docs/caching.md)
|
|
7
|
+
**Documentation:** [vinext.dev/docs](https://vinext.dev/docs)
|
|
10
8
|
|
|
11
9
|
> **Read the announcement:** [How we rebuilt Next.js with AI in one week](https://blog.cloudflare.com/vinext/)
|
|
12
10
|
|
|
@@ -122,7 +120,7 @@ Your existing `pages/`, `app/`, `next.config.js`, and `public/` directories work
|
|
|
122
120
|
|
|
123
121
|
Options: `-p / --port <port>`, `-H / --hostname <host>`, `--turbopack` (accepted, no-op).
|
|
124
122
|
|
|
125
|
-
`@vinext/cloudflare deploy` options: `--preview`, `--env <name>`, `--name <name>`, `--skip-build`, `--dry-run`, `--experimental-
|
|
123
|
+
`@vinext/cloudflare deploy` options: `--preview`, `--env <name>`, `--name <name>`, `--skip-build`, `--dry-run`, `--experimental-traffic-aware-warm-cache`.
|
|
126
124
|
|
|
127
125
|
`vinext init` prompts for a deployment target, defaulting to Cloudflare. Agents must ask the
|
|
128
126
|
user which target they want, then pass `--platform=cloudflare` or `--platform=node`.
|
|
@@ -335,20 +333,22 @@ For TypeScript types, generate them with `wrangler types` and the `env` import w
|
|
|
335
333
|
|
|
336
334
|
> **Note:** You do not need `getPlatformProxy()`, a custom worker entry with `fetch(request, env)`, or any other workaround. `cloudflare:workers` is the recommended way to access bindings in vinext.
|
|
337
335
|
|
|
338
|
-
#### Traffic-aware
|
|
336
|
+
#### Traffic-aware pre-warming (experimental)
|
|
339
337
|
|
|
340
|
-
|
|
338
|
+
Traffic-aware warming queries Cloudflare zone analytics at deploy time to select the routes that actually get traffic. Those routes then go through vinext's standard staged CDN pre-warming flow, including route resolution, cacheability checks, and promotion.
|
|
341
339
|
|
|
342
340
|
```bash
|
|
343
|
-
npx @vinext/cloudflare deploy --experimental-
|
|
344
|
-
vp exec vinext-cloudflare deploy --experimental-
|
|
345
|
-
npx @vinext/cloudflare deploy --experimental-
|
|
346
|
-
npx @vinext/cloudflare deploy --experimental-
|
|
347
|
-
npx @vinext/cloudflare deploy --experimental-
|
|
341
|
+
npx @vinext/cloudflare deploy --experimental-traffic-aware-warm-cache # Pre-warm routes covering 90% of traffic
|
|
342
|
+
vp exec vinext-cloudflare deploy --experimental-traffic-aware-warm-cache # Same, with Vite+
|
|
343
|
+
npx @vinext/cloudflare deploy --experimental-traffic-aware-warm-cache --traffic-aware-coverage 95 # More aggressive coverage
|
|
344
|
+
npx @vinext/cloudflare deploy --experimental-traffic-aware-warm-cache --traffic-aware-limit 500 # Cap at 500 routes
|
|
345
|
+
npx @vinext/cloudflare deploy --experimental-traffic-aware-warm-cache --traffic-aware-window 48 # Use 48h of analytics
|
|
348
346
|
```
|
|
349
347
|
|
|
350
348
|
Requires a custom domain (zone analytics are unavailable on `*.workers.dev`) and `CLOUDFLARE_API_TOKEN` with Zone.Analytics read permission.
|
|
351
349
|
|
|
350
|
+
The previous `--experimental-tpr` and `--tpr-*` names remain supported as aliases.
|
|
351
|
+
|
|
352
352
|
#### Custom Vite configuration
|
|
353
353
|
|
|
354
354
|
If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours. For Cloudflare Workers deployment with the App Router, configure `@cloudflare/vite-plugin` so the RSC environment runs in workerd:
|
|
@@ -598,7 +598,7 @@ Every `next/*` import is shimmed to a Vite-compatible implementation.
|
|
|
598
598
|
| Standalone output (`output: 'standalone'`) | ✅ | Generates `dist/standalone` with `server.js`, build artifacts, and runtime deps |
|
|
599
599
|
| `connection()` | ✅ | Forces dynamic rendering |
|
|
600
600
|
| `"use cache"` directive | ✅ | File-level and function-level. `cacheLife()` profiles, `cacheTag()`, stale-while-revalidate |
|
|
601
|
-
| `instrumentation.ts` | ✅ | `register()` and
|
|
601
|
+
| `instrumentation.ts` | ✅ | `register()`, `onRequestError()`, and [framework tracing](docs/tracing.mdx) |
|
|
602
602
|
| Route segment config | 🟡 | `revalidate`, `dynamic`, `dynamicParams`. `runtime` and `preferredRegion` are ignored |
|
|
603
603
|
|
|
604
604
|
### Configuration
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Third-party licenses
|
|
2
|
+
|
|
3
|
+
## ua-parser-js
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2012-2021 Faisal Salman <f@faisalman.com>
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
21
|
+
value: mod,
|
|
22
|
+
enumerable: true
|
|
23
|
+
}) : target, mod));
|
|
24
|
+
//#endregion
|
|
25
|
+
export { __commonJSMin, __toESM };
|
|
@@ -53,6 +53,10 @@ export declare const DEFAULT_REMOTE_PATH_DISCOVERY_RETRY_DELAY_MS = 1000;
|
|
|
53
53
|
export declare const DEFAULT_REMOTE_PATH_DISCOVERY_PHASE_TIMEOUT_MS = 120000;
|
|
54
54
|
type PrerenderPathDiscoveryOptions = {
|
|
55
55
|
root: string;
|
|
56
|
+
/** Additional concrete public paths to resolve through the route graph. */
|
|
57
|
+
candidatePaths?: readonly string[];
|
|
58
|
+
/** Resolve only candidate paths instead of enumerating dynamic route hooks. */
|
|
59
|
+
candidatePathsOnly?: boolean;
|
|
56
60
|
/** Fully resolved Next.js config. Loaded from disk when omitted. */
|
|
57
61
|
nextConfig?: ResolvedNextConfig;
|
|
58
62
|
appDir?: string | null;
|
|
@@ -270,6 +270,7 @@ async function collectPagesPaths(options) {
|
|
|
270
270
|
}
|
|
271
271
|
continue;
|
|
272
272
|
}
|
|
273
|
+
if (!options.enumerateDynamicPaths) continue;
|
|
273
274
|
if (type === "ssr") continue;
|
|
274
275
|
if (!options.baseUrl) continue;
|
|
275
276
|
try {
|
|
@@ -319,16 +320,31 @@ async function excludePagesApiWarmPaths(options) {
|
|
|
319
320
|
return matchRoute(pagesPathname, apiRoutes) === null;
|
|
320
321
|
});
|
|
321
322
|
}
|
|
322
|
-
async function
|
|
323
|
+
async function resolvePagesWarmRouteMetadata(options) {
|
|
323
324
|
const pageRoutes = await pagesRouter(options.pagesDir, options.pageExtensions);
|
|
324
|
-
|
|
325
|
+
const classifications = /* @__PURE__ */ new Map();
|
|
326
|
+
const dataPaths = [];
|
|
327
|
+
const routePatterns = {};
|
|
328
|
+
for (const pathname of options.paths) {
|
|
325
329
|
const pagesPathname = options.i18n ? extractLocaleFromUrl(pathname, options.i18n).url : pathname;
|
|
326
330
|
const match = matchRoute(pagesPathname, pageRoutes);
|
|
327
|
-
|
|
331
|
+
if (!match) continue;
|
|
332
|
+
routePatterns[pathname] = {
|
|
328
333
|
kind: "pages-page",
|
|
329
334
|
pattern: match.route.pattern
|
|
330
|
-
}
|
|
331
|
-
|
|
335
|
+
};
|
|
336
|
+
let classification = classifications.get(match.route.filePath);
|
|
337
|
+
if (!classification) {
|
|
338
|
+
classification = classifyPagesRoute(match.route.filePath);
|
|
339
|
+
classifications.set(match.route.filePath, classification);
|
|
340
|
+
}
|
|
341
|
+
const { hasServerSideProps, hasStaticProps } = classification;
|
|
342
|
+
if (hasServerSideProps || hasStaticProps) dataPaths.push(pathname);
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
dataPaths,
|
|
346
|
+
routePatterns
|
|
347
|
+
};
|
|
332
348
|
}
|
|
333
349
|
function localizePagesPath(pathname, locale, i18n) {
|
|
334
350
|
if (!i18n || !locale || locale === i18n.defaultLocale) return pathname;
|
|
@@ -364,8 +380,6 @@ async function collectAppPaths(options) {
|
|
|
364
380
|
const routes = await appRouter(options.appDir, options.pageExtensions);
|
|
365
381
|
const paths = [];
|
|
366
382
|
const seen = /* @__PURE__ */ new Set();
|
|
367
|
-
const loadingShellPaths = [];
|
|
368
|
-
const seenLoadingShellPaths = /* @__PURE__ */ new Set();
|
|
369
383
|
const routeHandlerPaths = [];
|
|
370
384
|
const seenRouteHandlerPaths = /* @__PURE__ */ new Set();
|
|
371
385
|
const fallbackRoutePatterns = [];
|
|
@@ -418,20 +432,19 @@ async function collectAppPaths(options) {
|
|
|
418
432
|
const { type } = classifyAppRoute(renderEntryPath, route.routePath, route.isDynamic);
|
|
419
433
|
if (type === "api") continue;
|
|
420
434
|
}
|
|
421
|
-
const hasMainTreeLoadingBoundary = appRouteHasMainTreeLoadingBoundary(route);
|
|
422
435
|
const addDiscoveredPath = (pathname) => {
|
|
423
436
|
if (isRouteHandler) {
|
|
424
437
|
addPath(routeHandlerPaths, seenRouteHandlerPaths, pathname);
|
|
425
438
|
return;
|
|
426
439
|
}
|
|
427
440
|
addPath(paths, seen, pathname);
|
|
428
|
-
if (hasMainTreeLoadingBoundary) addPath(loadingShellPaths, seenLoadingShellPaths, pathname);
|
|
429
441
|
};
|
|
430
442
|
if (!route.isDynamic) {
|
|
431
443
|
addDiscoveredPath(route.pattern);
|
|
432
444
|
addPath(nonDynamicPaths, seenNonDynamicPaths, route.pattern);
|
|
433
445
|
continue;
|
|
434
446
|
}
|
|
447
|
+
if (!options.enumerateDynamicPaths) continue;
|
|
435
448
|
requireNonEmptyStaticParams = options.cacheComponents && !isRouteHandler;
|
|
436
449
|
try {
|
|
437
450
|
const generateStaticParams = staticParamsMap[route.pattern];
|
|
@@ -502,7 +515,6 @@ async function collectAppPaths(options) {
|
|
|
502
515
|
}
|
|
503
516
|
return {
|
|
504
517
|
fallbackRoutePatterns,
|
|
505
|
-
loadingShellPaths,
|
|
506
518
|
nonDynamicPaths,
|
|
507
519
|
paths,
|
|
508
520
|
routeHandlerPaths
|
|
@@ -725,12 +737,8 @@ async function discoverPrerenderPathManifest(options) {
|
|
|
725
737
|
const seenPagesPaths = /* @__PURE__ */ new Set();
|
|
726
738
|
const discoveredPagesDataPaths = [];
|
|
727
739
|
const seenPagesDataPaths = /* @__PURE__ */ new Set();
|
|
728
|
-
const discoveredAppPaths = [];
|
|
729
|
-
const seenAppPaths = /* @__PURE__ */ new Set();
|
|
730
740
|
const discoveredRouteHandlerPaths = [];
|
|
731
741
|
const seenRouteHandlerPaths = /* @__PURE__ */ new Set();
|
|
732
|
-
const discoveredLoadingShellPaths = [];
|
|
733
|
-
const seenLoadingShellPaths = /* @__PURE__ */ new Set();
|
|
734
742
|
const discoveredNonDynamicPathSet = /* @__PURE__ */ new Set();
|
|
735
743
|
const fallbackRoutePatterns = [];
|
|
736
744
|
await withPrerenderEndpoints(async () => {
|
|
@@ -767,15 +775,12 @@ async function discoverPrerenderPathManifest(options) {
|
|
|
767
775
|
appDir,
|
|
768
776
|
baseUrl,
|
|
769
777
|
cacheComponents: config.cacheComponents,
|
|
778
|
+
enumerateDynamicPaths: options.candidatePathsOnly !== true,
|
|
770
779
|
pageExtensions: config.pageExtensions,
|
|
771
780
|
retryOptions: pathDiscoveryRetryOptions,
|
|
772
781
|
secretHeaders
|
|
773
782
|
});
|
|
774
|
-
for (const pathname of appPathResult.paths)
|
|
775
|
-
addPath(paths, seen, pathname);
|
|
776
|
-
addPath(discoveredAppPaths, seenAppPaths, pathname);
|
|
777
|
-
}
|
|
778
|
-
for (const pathname of appPathResult.loadingShellPaths) addPath(discoveredLoadingShellPaths, seenLoadingShellPaths, pathname);
|
|
783
|
+
for (const pathname of appPathResult.paths) addPath(paths, seen, pathname);
|
|
779
784
|
for (const pathname of appPathResult.routeHandlerPaths) addPath(discoveredRouteHandlerPaths, seenRouteHandlerPaths, pathname);
|
|
780
785
|
for (const pathname of appPathResult.nonDynamicPaths) discoveredNonDynamicPathSet.add(pathname);
|
|
781
786
|
fallbackRoutePatterns.push(...appPathResult.fallbackRoutePatterns);
|
|
@@ -783,6 +788,7 @@ async function discoverPrerenderPathManifest(options) {
|
|
|
783
788
|
if (pagesDir) {
|
|
784
789
|
const pagesPathResult = await collectPagesPaths({
|
|
785
790
|
baseUrl,
|
|
791
|
+
enumerateDynamicPaths: options.candidatePathsOnly !== true,
|
|
786
792
|
i18n: config.i18n,
|
|
787
793
|
pagesDir,
|
|
788
794
|
pageExtensions: config.pageExtensions,
|
|
@@ -801,6 +807,16 @@ async function discoverPrerenderPathManifest(options) {
|
|
|
801
807
|
if (prodServer) await new Promise((resolve) => prodServer.server.close(() => resolve()));
|
|
802
808
|
}
|
|
803
809
|
});
|
|
810
|
+
for (const publicPathname of options.candidatePaths ?? []) {
|
|
811
|
+
let pathname = normalizePathTrailingSlash(new URL(publicPathname, "http://vinext.local").pathname, false);
|
|
812
|
+
if (config.basePath) {
|
|
813
|
+
if (pathname === config.basePath) pathname = "/";
|
|
814
|
+
else if (pathname.startsWith(`${config.basePath}/`)) pathname = pathname.slice(config.basePath.length);
|
|
815
|
+
else continue;
|
|
816
|
+
}
|
|
817
|
+
addPath(paths, seen, pathname);
|
|
818
|
+
if (pagesDir) addPath(discoveredPagesPaths, seenPagesPaths, pathname);
|
|
819
|
+
}
|
|
804
820
|
const hasStagedRequestRouting = options.requestRouting === "uncached-stage";
|
|
805
821
|
const middlewarePath = hasStagedRequestRouting ? findMiddlewareConventionFile(root, appDir, pagesDir, config.pageExtensions) : null;
|
|
806
822
|
const configuredMatcher = middlewarePath ? extractMiddlewareMatcherConfig(middlewarePath) : void 0;
|
|
@@ -816,9 +832,20 @@ async function discoverPrerenderPathManifest(options) {
|
|
|
816
832
|
pageExtensions: config.pageExtensions,
|
|
817
833
|
paths: configuredPagesWarmPaths
|
|
818
834
|
}) : configuredPagesWarmPaths;
|
|
819
|
-
const discoveredPagesDataPathSet = new Set(discoveredPagesDataPaths);
|
|
820
835
|
const configuredCandidatePaths = paths.filter((pathname) => !excludedWarmPathSet.has(pathname));
|
|
821
836
|
const configuredRouteHandlerPaths = discoveredRouteHandlerPaths.filter((pathname) => !excludedWarmPathSet.has(pathname));
|
|
837
|
+
const pagesWarmMetadata = pagesDir ? await resolvePagesWarmRouteMetadata({
|
|
838
|
+
i18n: config.i18n,
|
|
839
|
+
pagesDir,
|
|
840
|
+
pageExtensions: config.pageExtensions,
|
|
841
|
+
paths: resolvedPagesWarmPaths
|
|
842
|
+
}) : {
|
|
843
|
+
dataPaths: [],
|
|
844
|
+
routePatterns: {}
|
|
845
|
+
};
|
|
846
|
+
for (const pathname of pagesWarmMetadata.dataPaths) addPath(discoveredPagesDataPaths, seenPagesDataPaths, pathname);
|
|
847
|
+
const discoveredPagesDataPathSet = new Set(discoveredPagesDataPaths);
|
|
848
|
+
const pagesOnlyWarmPaths = resolvedPagesWarmPaths.filter((pathname) => pagesWarmMetadata.routePatterns[pathname] !== void 0);
|
|
822
849
|
const appOwnedWarmPaths = appDir ? await resolveAppWarmPaths({
|
|
823
850
|
appDir,
|
|
824
851
|
i18n: config.i18n,
|
|
@@ -828,19 +855,24 @@ async function discoverPrerenderPathManifest(options) {
|
|
|
828
855
|
}) : {
|
|
829
856
|
appPaths: [],
|
|
830
857
|
appRoutePaths: [],
|
|
831
|
-
htmlPaths:
|
|
832
|
-
loadingShellPaths:
|
|
833
|
-
pagesPaths:
|
|
834
|
-
routePatterns:
|
|
835
|
-
|
|
836
|
-
pagesDir,
|
|
837
|
-
pageExtensions: config.pageExtensions,
|
|
838
|
-
paths: resolvedPagesWarmPaths
|
|
839
|
-
}) : {},
|
|
840
|
-
rscPaths: discoveredAppPaths
|
|
858
|
+
htmlPaths: pagesOnlyWarmPaths,
|
|
859
|
+
loadingShellPaths: [],
|
|
860
|
+
pagesPaths: pagesOnlyWarmPaths,
|
|
861
|
+
routePatterns: pagesWarmMetadata.routePatterns,
|
|
862
|
+
rscPaths: []
|
|
841
863
|
};
|
|
842
|
-
const
|
|
843
|
-
|
|
864
|
+
for (const pathname of configuredCandidatePaths) {
|
|
865
|
+
if (appOwnedWarmPaths.routePatterns[pathname] || !routeMayResolveWarmPathSet.has(pathname) && !requestStageMayTerminateWarmPathSet.has(pathname)) continue;
|
|
866
|
+
appOwnedWarmPaths.htmlPaths.push(pathname);
|
|
867
|
+
(appDir ? appOwnedWarmPaths.appPaths : appOwnedWarmPaths.pagesPaths).push(pathname);
|
|
868
|
+
if (appDir && routeMayResolveWarmPathSet.has(pathname)) appOwnedWarmPaths.rscPaths.push(pathname);
|
|
869
|
+
appOwnedWarmPaths.routePatterns[pathname] = {
|
|
870
|
+
kind: appDir ? "app-page" : "pages-page",
|
|
871
|
+
pattern: pathname
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
const warmPaths = appOwnedWarmPaths.htmlPaths;
|
|
875
|
+
const pagesOwnedWarmPaths = appOwnedWarmPaths.pagesPaths;
|
|
844
876
|
const resolvedPagesDataWarmPaths = pagesOwnedWarmPaths.filter((pathname) => discoveredPagesDataPathSet.has(pathname));
|
|
845
877
|
const pagesDataPaths = resolvedPagesDataWarmPaths.map((pathname) => buildPagesDataHref(config.basePath, config.buildId, localizePagesDataPath(pathname, config.i18n), ""));
|
|
846
878
|
const routePatterns = annotateCacheabilityProbeSafety(appOwnedWarmPaths.routePatterns, config, routeMayResolveWarmPathSet, requestStageMayTerminateWarmPathSet, (name) => name.trim().toLowerCase() === "cache-control" || options.isResponsePolicyHeader?.(name) === true);
|
|
@@ -41,7 +41,7 @@ export type PrerenderRouteResult = {
|
|
|
41
41
|
} | {
|
|
42
42
|
route: string;
|
|
43
43
|
status: "skipped";
|
|
44
|
-
reason: "ssr" | "dynamic" | "no-static-params" | "api" | "internal";
|
|
44
|
+
reason: "ssr" | "dynamic" | "no-static-params" | "empty-static-params" | "api" | "internal";
|
|
45
45
|
} | {
|
|
46
46
|
route: string;
|
|
47
47
|
status: "error";
|
package/dist/build/prerender.js
CHANGED
|
@@ -25,8 +25,8 @@ export type CdnCacheAdapterCapabilities = {
|
|
|
25
25
|
* variants when this guarantee is present.
|
|
26
26
|
*/
|
|
27
27
|
responseVary?: "verbatim";
|
|
28
|
-
/** Warm by observing
|
|
29
|
-
warmup?: "response-store";
|
|
28
|
+
/** Warm by observing framework `X-Vinext-Cache` admission instead of an edge-cache header. */
|
|
29
|
+
warmup?: "data-cache" | "response-store";
|
|
30
30
|
/**
|
|
31
31
|
* Rewrites and other request routing run before the shared response stage,
|
|
32
32
|
* and the resolved response-stage invocation participates in cache identity.
|
|
@@ -81,7 +81,7 @@ export type CacheAdapterDescriptor<O extends Record<string, unknown> = Record<st
|
|
|
81
81
|
};
|
|
82
82
|
export declare function hasVerbatimResponseVary(cache?: VinextCacheConfig | null): boolean;
|
|
83
83
|
export declare function supportsCanonicalRscWarmup(cache?: VinextCacheConfig | null): boolean;
|
|
84
|
-
export declare function
|
|
84
|
+
export declare function cacheWarmupStatusSource(cache?: VinextCacheConfig | null): "cloudflare" | "data-cache" | "vinext";
|
|
85
85
|
export declare function hasUncachedRequestRouting(cache?: VinextCacheConfig | null): boolean;
|
|
86
86
|
export declare function hasBuildIdentityResponseHeader(cache?: VinextCacheConfig | null): boolean;
|
|
87
87
|
export declare function requiresRouteCacheabilityProbeManifest(cache?: VinextCacheConfig | null): boolean;
|
|
@@ -22,14 +22,16 @@ function hasVerbatimResponseVary(cache) {
|
|
|
22
22
|
function supportsCanonicalRscWarmup(cache) {
|
|
23
23
|
return hasVerbatimResponseVary(cache);
|
|
24
24
|
}
|
|
25
|
-
function
|
|
26
|
-
|
|
25
|
+
function cacheWarmupStatusSource(cache) {
|
|
26
|
+
if (cache?.cdn?.capabilities?.warmup === "response-store") return "vinext";
|
|
27
|
+
if (!cache?.cdn?.adapter && cache?.data?.capabilities?.warmup === "data-cache") return "data-cache";
|
|
28
|
+
return "cloudflare";
|
|
27
29
|
}
|
|
28
30
|
function hasUncachedRequestRouting(cache) {
|
|
29
31
|
return cache?.cdn?.capabilities?.requestRouting === "uncached-stage";
|
|
30
32
|
}
|
|
31
33
|
function hasBuildIdentityResponseHeader(cache) {
|
|
32
|
-
return cache?.cdn?.capabilities?.buildIdentity === "response-header";
|
|
34
|
+
return cache?.cdn?.capabilities?.buildIdentity === "response-header" || !cache?.cdn?.adapter && cache?.data?.capabilities?.buildIdentity === "response-header";
|
|
33
35
|
}
|
|
34
36
|
function requiresRouteCacheabilityProbeManifest(cache) {
|
|
35
37
|
return cache?.cdn?.capabilities?.routeCacheability === "probe-manifest";
|
|
@@ -79,6 +81,7 @@ function inlineOptions(adapter, options) {
|
|
|
79
81
|
function generateCacheAdaptersModule(cache) {
|
|
80
82
|
const data = cache?.data;
|
|
81
83
|
const cdn = cache?.cdn;
|
|
84
|
+
const dataProvidesBuildIdentity = !cdn?.adapter && data?.capabilities?.buildIdentity === "response-header";
|
|
82
85
|
if (!data?.adapter && !cdn?.adapter) return [
|
|
83
86
|
"// vinext: no cache.cdn/cache.data adapter configured — registration is a no-op.",
|
|
84
87
|
"export function registerConfiguredCacheAdapters() {}",
|
|
@@ -92,16 +95,20 @@ function generateCacheAdaptersModule(cache) {
|
|
|
92
95
|
if (cdn?.adapter) {
|
|
93
96
|
lines.push(`import __vinextCdnAdapterFactory from ${JSON.stringify(cdn.adapter)};`);
|
|
94
97
|
lines.push(`import { registerCdnCacheAdapter } from "vinext/shims/cdn-cache-state";`);
|
|
95
|
-
}
|
|
98
|
+
} else if (dataProvidesBuildIdentity) lines.push(`import { DefaultCdnCacheAdapter } from "vinext/shims/cdn-cache";`, `import { registerCdnCacheAdapter } from "vinext/shims/cdn-cache-state";`);
|
|
96
99
|
lines.push("", "// A factory that throws (e.g. a missing binding on an incompatible runtime)", "// is logged and skipped so the default handler stays in place.", "function __vinextFormatAdapterError(error) {", " if (error instanceof Error && error.message) return error.message;", " try {", " return String(error);", " } catch {", " return '<unknown error>';", " }", "}", "", "let __vinextCacheAdaptersRegistered = false;", "", "export function registerConfiguredCacheAdapters(env) {", " if (typeof process !== 'undefined' && process.env?.__VINEXT_PRERENDER_PATH_DISCOVERY === '1') return;", " if (__vinextCacheAdaptersRegistered) return;", " __vinextCacheAdaptersRegistered = true;");
|
|
97
|
-
if (data?.adapter)
|
|
100
|
+
if (data?.adapter) {
|
|
101
|
+
lines.push(" try {", ` registerDataCacheHandler(() => __vinextDataAdapterFactory({ env, options: ${inlineOptions(data.adapter, data.options)} }));`);
|
|
102
|
+
if (dataProvidesBuildIdentity) lines.push(" registerCdnCacheAdapter(() => new DefaultCdnCacheAdapter(", " process.env.__VINEXT_RSC_BUILD_IDENTITY || process.env.__VINEXT_BUILD_ID,", " ));");
|
|
103
|
+
lines.push(" } catch (error) {", " console.warn(\"[vinext] failed to initialize the configured data cache adapter; using the default handler.\\n\" + __vinextFormatAdapterError(error));", " }");
|
|
104
|
+
}
|
|
98
105
|
if (cdn?.adapter) lines.push(" try {", ` registerCdnCacheAdapter(() => __vinextCdnAdapterFactory({ env, options: ${inlineOptions(cdn.adapter, cdn.options)} }));`, " } catch (error) {", " console.warn(\"[vinext] failed to initialize the configured CDN cache adapter; using the default adapter.\\n\" + __vinextFormatAdapterError(error));", " }");
|
|
99
106
|
lines.push("}", "");
|
|
100
107
|
return lines.join("\n");
|
|
101
108
|
}
|
|
102
109
|
/** Generate request-stage registration without importing a configured data adapter. */
|
|
103
110
|
function generateCdnCacheAdapterModule(cache) {
|
|
104
|
-
return `${generateCacheAdaptersModule(cache?.cdn ? { cdn: cache.cdn } : void 0)}export const hasConfiguredDataCache = ${Boolean(cache?.data?.adapter)};\n`;
|
|
111
|
+
return `${generateCacheAdaptersModule(cache?.cdn ? { cdn: cache.cdn } : void 0)}export const hasConfiguredDataCache = ${Boolean(cache?.data?.adapter)};\nexport const configuredCdnCacheAdapterOptions = ${inlineOptions(cache?.cdn?.adapter ?? "cdn", cache?.cdn?.options)};\n`;
|
|
105
112
|
}
|
|
106
113
|
//#endregion
|
|
107
|
-
export { VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, VIRTUAL_CACHE_ADAPTERS, VIRTUAL_CDN_CACHE_ADAPTER, findVinextCacheConfigInPlugins, generateCacheAdaptersModule, generateCdnCacheAdapterModule, hasBuildIdentityResponseHeader, hasUncachedRequestRouting, hasVerbatimResponseVary, isConfiguredCdnResponsePolicyHeader, loadVinextCacheConfigFromViteConfig, requiresRouteCacheabilityProbeManifest, supportsCanonicalRscWarmup
|
|
114
|
+
export { VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, VIRTUAL_CACHE_ADAPTERS, VIRTUAL_CDN_CACHE_ADAPTER, cacheWarmupStatusSource, findVinextCacheConfigInPlugins, generateCacheAdaptersModule, generateCdnCacheAdapterModule, hasBuildIdentityResponseHeader, hasUncachedRequestRouting, hasVerbatimResponseVary, isConfiguredCdnResponsePolicyHeader, loadVinextCacheConfigFromViteConfig, requiresRouteCacheabilityProbeManifest, supportsCanonicalRscWarmup };
|
package/dist/check.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { __toESM } from "./_virtual/_rolldown/runtime.js";
|
|
1
2
|
import path from "./deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
3
|
import { detectPackageManager, findDir } from "./utils/project.js";
|
|
4
|
+
import { require_ignore } from "./deps/.pnpm/ignore@5.3.2/deps/ignore/index.js";
|
|
3
5
|
import fs from "node:fs";
|
|
4
6
|
import { parseAst } from "vite";
|
|
5
7
|
//#region src/check.ts
|
|
@@ -9,6 +11,7 @@ import { parseAst } from "vite";
|
|
|
9
11
|
* Scans an existing Next.js app and produces a compatibility report
|
|
10
12
|
* showing what will work, what needs changes, and an overall score.
|
|
11
13
|
*/
|
|
14
|
+
var import_ignore = /* @__PURE__ */ __toESM(require_ignore(), 1);
|
|
12
15
|
/** Sort order for statuses: unsupported first, then partial, then supported. */
|
|
13
16
|
const STATUS_ORDER = {
|
|
14
17
|
unsupported: 0,
|
|
@@ -372,25 +375,69 @@ const LIBRARY_SUPPORT = {
|
|
|
372
375
|
detail: "works with D1 on Cloudflare Workers"
|
|
373
376
|
}
|
|
374
377
|
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
378
|
+
const IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
379
|
+
"node_modules",
|
|
380
|
+
".next",
|
|
381
|
+
"dist",
|
|
382
|
+
".git"
|
|
383
|
+
]);
|
|
384
|
+
const SOURCE_EXTENSIONS = [
|
|
379
385
|
".ts",
|
|
380
386
|
".tsx",
|
|
381
387
|
".js",
|
|
382
388
|
".jsx",
|
|
383
389
|
".mjs"
|
|
384
|
-
]
|
|
390
|
+
];
|
|
391
|
+
function readGitignoreRule(dir) {
|
|
392
|
+
const gitignore = path.join(dir, ".gitignore");
|
|
393
|
+
let stat;
|
|
394
|
+
try {
|
|
395
|
+
stat = fs.lstatSync(gitignore);
|
|
396
|
+
} catch {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
if (!stat.isFile()) return;
|
|
400
|
+
return {
|
|
401
|
+
dir,
|
|
402
|
+
matcher: (0, import_ignore.default)({ ignorecase: false }).add(fs.readFileSync(gitignore, "utf-8"))
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function ancestorGitignoreRules(root, dir) {
|
|
406
|
+
const rules = [];
|
|
407
|
+
let current = root;
|
|
408
|
+
for (const segment of path.relative(root, dir).split("/")) {
|
|
409
|
+
const rule = readGitignoreRule(current);
|
|
410
|
+
if (rule) rules.push(rule);
|
|
411
|
+
current = path.join(current, segment);
|
|
412
|
+
if (isGitignored(current, true, rules)) break;
|
|
413
|
+
}
|
|
414
|
+
return rules;
|
|
415
|
+
}
|
|
416
|
+
function isGitignored(fullPath, isDirectory, rules) {
|
|
417
|
+
let ignored = false;
|
|
418
|
+
for (const rule of rules) {
|
|
419
|
+
const relative = path.relative(rule.dir, fullPath) + (isDirectory ? "/" : "");
|
|
420
|
+
const result = rule.matcher.test(relative);
|
|
421
|
+
if (result.ignored) ignored = true;
|
|
422
|
+
else if (result.unignored) ignored = false;
|
|
423
|
+
}
|
|
424
|
+
return ignored;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Recursively find all source files in a directory.
|
|
428
|
+
*/
|
|
429
|
+
function findSourceFiles(dir, extensions = SOURCE_EXTENSIONS, inherited = []) {
|
|
385
430
|
const results = [];
|
|
386
431
|
if (!fs.existsSync(dir)) return results;
|
|
432
|
+
const localRule = readGitignoreRule(dir);
|
|
433
|
+
const rules = localRule ? [...inherited, localRule] : inherited;
|
|
387
434
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
388
435
|
for (const entry of entries) {
|
|
389
436
|
const fullPath = path.join(dir, entry.name);
|
|
390
|
-
if (entry.isDirectory())
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
437
|
+
if (entry.isDirectory() && IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
438
|
+
if (isGitignored(fullPath, entry.isDirectory(), rules)) continue;
|
|
439
|
+
if (entry.isDirectory()) results.push(...findSourceFiles(fullPath, extensions, rules));
|
|
440
|
+
else if (extensions.some((ext) => entry.name.endsWith(ext))) results.push(fullPath);
|
|
394
441
|
}
|
|
395
442
|
return results;
|
|
396
443
|
}
|
|
@@ -400,12 +447,13 @@ function findSourceFiles(dir, extensions = [
|
|
|
400
447
|
* rather than bundled into the vinext application, so reporting their imports
|
|
401
448
|
* or CJS globals as migration blockers produces false positives.
|
|
402
449
|
*/
|
|
450
|
+
function isRuntimeSourceFile(file) {
|
|
451
|
+
const basename = path.basename(file);
|
|
452
|
+
const isTestRunnerConfig = /^(?:jest|playwright|vitest)\.config\.[cm]?[jt]sx?$/.test(basename);
|
|
453
|
+
return !/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(basename) && !isTestRunnerConfig;
|
|
454
|
+
}
|
|
403
455
|
function findRuntimeSourceFiles(root) {
|
|
404
|
-
return findSourceFiles(root).filter(
|
|
405
|
-
const basename = path.basename(file);
|
|
406
|
-
const isTestRunnerConfig = /^(?:jest|playwright|vitest)\.config\.[cm]?[jt]sx?$/.test(basename);
|
|
407
|
-
return !/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(basename) && !isTestRunnerConfig;
|
|
408
|
-
});
|
|
456
|
+
return findSourceFiles(root).filter(isRuntimeSourceFile);
|
|
409
457
|
}
|
|
410
458
|
function isIdentStart(c) {
|
|
411
459
|
return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "_" || c === "$";
|
|
@@ -839,6 +887,14 @@ function checkLibraries(root) {
|
|
|
839
887
|
*/
|
|
840
888
|
function checkConventions(root) {
|
|
841
889
|
const items = [];
|
|
890
|
+
const sourceFiles = findSourceFiles(root);
|
|
891
|
+
const routeFiles = (dir) => {
|
|
892
|
+
const files = sourceFiles.filter((file) => file.startsWith(`${dir}/`));
|
|
893
|
+
if (files.length || !fs.lstatSync(dir).isSymbolicLink()) return files;
|
|
894
|
+
const rules = ancestorGitignoreRules(root, dir);
|
|
895
|
+
if (isGitignored(dir, true, rules)) return [];
|
|
896
|
+
return findSourceFiles(dir, SOURCE_EXTENSIONS, rules);
|
|
897
|
+
};
|
|
842
898
|
const pagesDir = findDir(root, "pages", "src/pages");
|
|
843
899
|
const appDirPath = findDir(root, "app", "src/app");
|
|
844
900
|
const hasProxy = fs.existsSync(path.join(root, "proxy.ts")) || fs.existsSync(path.join(root, "proxy.js"));
|
|
@@ -849,7 +905,7 @@ function checkConventions(root) {
|
|
|
849
905
|
name: isSrc ? "Pages Router (src/pages/)" : "Pages Router (pages/)",
|
|
850
906
|
status: "supported"
|
|
851
907
|
});
|
|
852
|
-
const pageFiles =
|
|
908
|
+
const pageFiles = routeFiles(pagesDir);
|
|
853
909
|
const pages = pageFiles.filter((f) => !f.includes("/api/") && !f.includes("_app") && !f.includes("_document") && !f.includes("_error"));
|
|
854
910
|
const apiRoutes = pageFiles.filter((f) => f.includes("/api/"));
|
|
855
911
|
items.push({
|
|
@@ -875,7 +931,7 @@ function checkConventions(root) {
|
|
|
875
931
|
name: isSrc ? "App Router (src/app/)" : "App Router (app/)",
|
|
876
932
|
status: "supported"
|
|
877
933
|
});
|
|
878
|
-
const appFiles =
|
|
934
|
+
const appFiles = routeFiles(appDirPath);
|
|
879
935
|
const pages = appFiles.filter((f) => isAppRouterFile(f, "page"));
|
|
880
936
|
const layouts = appFiles.filter((f) => isAppRouterFile(f, "layout"));
|
|
881
937
|
const routes = appFiles.filter((f) => f.endsWith("route.tsx") || f.endsWith("route.ts") || f.endsWith("route.js"));
|
|
@@ -928,11 +984,11 @@ function checkConventions(root) {
|
|
|
928
984
|
detail: "required for Vite — vinext init will add it automatically"
|
|
929
985
|
});
|
|
930
986
|
}
|
|
931
|
-
const
|
|
987
|
+
const runtimeSourceFiles = sourceFiles.filter(isRuntimeSourceFile);
|
|
932
988
|
const viewTransitionRegex = /import\s+\{[^}]*\bViewTransition\b[^}]*\}\s+from\s+['"]react['"]/;
|
|
933
989
|
const viewTransitionFiles = [];
|
|
934
990
|
const cjsGlobalFiles = [];
|
|
935
|
-
for (const file of
|
|
991
|
+
for (const file of runtimeSourceFiles) {
|
|
936
992
|
const content = fs.readFileSync(file, "utf-8");
|
|
937
993
|
const rel = path.relative(root, file);
|
|
938
994
|
if (viewTransitionRegex.test(content)) viewTransitionFiles.push(rel);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { VINEXT_DEV_ERROR_RECOVERY_EVENT } from "../utils/dev-error-recovery-event.js";
|
|
2
1
|
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
2
|
+
import { VINEXT_DEV_ERROR_RECOVERY_EVENT } from "../utils/dev-error-recovery-event.js";
|
|
3
3
|
import { VINEXT_ORIGINAL_STACK_TRACE_ENDPOINT } from "../utils/dev-stack-sourcemap-endpoint.js";
|
|
4
4
|
import { dismissOverlay, expandOverlay, getOverlaySnapshot, minimizeOverlay, reportToOverlay, setOverlayIndex, subscribeOverlay, updateOverlayErrorStack } from "./dev-error-overlay-store.js";
|
|
5
5
|
import { Fragment, useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
@@ -321,6 +321,10 @@ export type ResolvedNextConfig = {
|
|
|
321
321
|
resolveExtensions: string[] | null;
|
|
322
322
|
serverResolveExtensions: string[] | null;
|
|
323
323
|
instrumentationClientInject: string[];
|
|
324
|
+
/** Route manifest injected by Next.js-compatible instrumentation plugins. */
|
|
325
|
+
instrumentationClientRouteManifest: string | undefined;
|
|
326
|
+
/** Server globals injected into instrumentation.ts by wrapped webpack configs. */
|
|
327
|
+
instrumentationServerValueInjections: Record<string, unknown>;
|
|
324
328
|
cacheComponents: boolean;
|
|
325
329
|
appNavFailHandling: boolean;
|
|
326
330
|
/**
|