vinext 0.1.0 → 0.1.2
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 +2 -5
- package/dist/build/assets-ignore.d.ts +32 -0
- package/dist/build/assets-ignore.js +48 -0
- package/dist/build/client-build-config.d.ts +33 -1
- package/dist/build/client-build-config.js +66 -1
- package/dist/check.js +4 -3
- package/dist/cli.js +2 -0
- package/dist/client/navigation-runtime.d.ts +11 -2
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/client/window-next.d.ts +6 -4
- package/dist/config/config-matchers.d.ts +31 -5
- package/dist/config/config-matchers.js +50 -3
- package/dist/config/next-config.d.ts +29 -3
- package/dist/config/next-config.js +32 -2
- package/dist/deploy.js +47 -304
- package/dist/entries/app-rsc-entry.d.ts +8 -2
- package/dist/entries/app-rsc-entry.js +61 -5
- package/dist/entries/app-rsc-manifest.js +20 -2
- package/dist/entries/pages-client-entry.js +1 -1
- package/dist/entries/pages-server-entry.js +16 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +233 -280
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +8 -4
- package/dist/plugins/optimize-imports.js +16 -12
- package/dist/plugins/postcss.js +18 -14
- package/dist/plugins/require-context.d.ts +6 -0
- package/dist/plugins/require-context.js +184 -0
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +35 -2
- package/dist/routing/app-route-graph.js +179 -8
- package/dist/routing/file-matcher.js +1 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +16 -1
- package/dist/server/api-handler.js +4 -0
- package/dist/server/app-browser-entry.js +155 -215
- package/dist/server/app-browser-error.d.ts +4 -1
- package/dist/server/app-browser-error.js +7 -1
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-interception-context.d.ts +2 -1
- package/dist/server/app-browser-interception-context.js +15 -2
- package/dist/server/app-browser-navigation-controller.d.ts +13 -2
- package/dist/server/app-browser-navigation-controller.js +83 -4
- package/dist/server/app-browser-popstate.d.ts +12 -3
- package/dist/server/app-browser-popstate.js +19 -4
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-state.d.ts +3 -0
- package/dist/server/app-browser-state.js +10 -10
- package/dist/server/app-browser-visible-commit.js +10 -8
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-history-state.d.ts +45 -1
- package/dist/server/app-history-state.js +109 -1
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +22 -1
- package/dist/server/app-page-boundary-render.d.ts +2 -1
- package/dist/server/app-page-boundary-render.js +45 -21
- package/dist/server/app-page-cache.js +9 -7
- package/dist/server/app-page-dispatch.d.ts +14 -0
- package/dist/server/app-page-dispatch.js +21 -6
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +58 -17
- package/dist/server/app-page-execution.d.ts +1 -1
- package/dist/server/app-page-execution.js +32 -17
- package/dist/server/app-page-render.d.ts +7 -1
- package/dist/server/app-page-render.js +11 -16
- package/dist/server/app-page-request.d.ts +9 -6
- package/dist/server/app-page-request.js +14 -10
- package/dist/server/app-page-response.d.ts +2 -2
- package/dist/server/app-page-response.js +2 -2
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +10 -8
- package/dist/server/app-page-stream.d.ts +37 -7
- package/dist/server/app-page-stream.js +36 -6
- package/dist/server/app-pages-bridge.d.ts +16 -0
- package/dist/server/app-pages-bridge.js +23 -3
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +2 -0
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.d.ts +1 -0
- package/dist/server/app-route-handler-runtime.js +15 -3
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +5 -4
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +20 -1
- package/dist/server/app-rsc-route-matching.js +29 -4
- package/dist/server/app-server-action-execution.d.ts +22 -1
- package/dist/server/app-server-action-execution.js +73 -12
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +19 -3
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +97 -43
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-cache.d.ts +37 -1
- package/dist/server/isr-cache.js +85 -1
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +62 -1
- package/dist/server/navigation-planner.js +193 -3
- package/dist/server/navigation-trace.d.ts +12 -2
- package/dist/server/navigation-trace.js +11 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +14 -3
- package/dist/server/pages-api-route.js +6 -1
- package/dist/server/pages-asset-tags.d.ts +15 -4
- package/dist/server/pages-asset-tags.js +18 -12
- package/dist/server/pages-data-route.js +5 -1
- package/dist/server/pages-node-compat.d.ts +5 -11
- package/dist/server/pages-node-compat.js +175 -118
- package/dist/server/pages-page-data.d.ts +38 -7
- package/dist/server/pages-page-data.js +64 -18
- package/dist/server/pages-page-handler.d.ts +10 -2
- package/dist/server/pages-page-handler.js +49 -20
- package/dist/server/pages-page-response.d.ts +55 -2
- package/dist/server/pages-page-response.js +74 -6
- package/dist/server/pages-readiness.d.ts +36 -0
- package/dist/server/pages-readiness.js +21 -0
- package/dist/server/pages-request-pipeline.d.ts +113 -0
- package/dist/server/pages-request-pipeline.js +230 -0
- package/dist/server/pages-revalidate.d.ts +15 -0
- package/dist/server/pages-revalidate.js +19 -0
- package/dist/server/prod-server.d.ts +45 -3
- package/dist/server/prod-server.js +182 -234
- package/dist/server/socket-error-backstop.d.ts +19 -1
- package/dist/server/socket-error-backstop.js +77 -4
- package/dist/shims/app-router-scroll.js +22 -4
- package/dist/shims/cache-runtime.js +39 -2
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +77 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +17 -7
- package/dist/shims/error-boundary.js +8 -1
- package/dist/shims/error.js +37 -11
- package/dist/shims/fetch-cache.d.ts +22 -1
- package/dist/shims/fetch-cache.js +28 -1
- package/dist/shims/hash-scroll.d.ts +1 -0
- package/dist/shims/hash-scroll.js +3 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +37 -1
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +10 -6
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/link-status-registry.d.ts +43 -0
- package/dist/shims/internal/link-status-registry.js +42 -0
- package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
- package/dist/shims/internal/route-pattern-for-warning.js +40 -0
- package/dist/shims/internal/utils.d.ts +1 -0
- package/dist/shims/link.js +20 -6
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +9 -18
- package/dist/shims/navigation.js +96 -23
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js +2 -0
- package/dist/shims/router.d.ts +6 -3
- package/dist/shims/router.js +156 -22
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +17 -1
- package/dist/shims/server.js +31 -6
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/client-build-manifest.d.ts +8 -1
- package/dist/utils/client-build-manifest.js +41 -6
- package/dist/utils/client-entry-manifest.d.ts +11 -0
- package/dist/utils/client-entry-manifest.js +29 -0
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +5 -1
- package/package.json +6 -2
package/dist/shims/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { splitPathSegments } from "../routing/utils.js";
|
|
2
|
-
import { stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
3
3
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
4
4
|
import { matchRoutePattern, routePatternParts } from "../routing/route-pattern.js";
|
|
5
5
|
import { isUnknownRecord } from "../utils/record.js";
|
|
@@ -247,15 +247,19 @@ function _registerRouterStateAccessors(accessors) {
|
|
|
247
247
|
function setSSRContext(ctx) {
|
|
248
248
|
_setSSRContextImpl(ctx);
|
|
249
249
|
}
|
|
250
|
+
const PAGES_NAVIGATION_NOTIFY_KEY = Symbol.for("vinext.navigation.pagesNavigationNotify");
|
|
250
251
|
let _cachedClientPagesNavCtx = null;
|
|
251
252
|
let _cachedClientPagesNavCtxKey = null;
|
|
252
|
-
function _buildClientPagesNavigationContext(routePattern, resolvedPath, searchString) {
|
|
253
|
-
const cacheKey = `${routePattern}|${resolvedPath}|${searchString}`;
|
|
253
|
+
function _buildClientPagesNavigationContext(routePattern, resolvedPath, searchString, isReady, nextData) {
|
|
254
|
+
const cacheKey = `${isReady ? "1" : "0"}|${routePattern}|${resolvedPath}|${searchString}`;
|
|
254
255
|
if (_cachedClientPagesNavCtxKey === cacheKey && _cachedClientPagesNavCtx) return _cachedClientPagesNavCtx;
|
|
256
|
+
const searchParams = isReady ? new URLSearchParams(searchString) : new URLSearchParams();
|
|
257
|
+
const params = isReady ? extractRouteParamsFromPath(routePattern, resolvedPath) ?? getRouteParamsFromQuery(routePattern, nextData?.query ?? {}) ?? {} : null;
|
|
258
|
+
const isAutoExportDynamic = nextData?.autoExport === true && extractRouteParamNames(routePattern).length > 0;
|
|
255
259
|
const ctx = {
|
|
256
|
-
pathname: resolvedPath,
|
|
257
|
-
searchParams
|
|
258
|
-
params
|
|
260
|
+
pathname: resolvePagesNavigationPathname(resolvedPath, nextData?.isFallback === true, isAutoExportDynamic, isReady),
|
|
261
|
+
searchParams,
|
|
262
|
+
params
|
|
259
263
|
};
|
|
260
264
|
_cachedClientPagesNavCtx = ctx;
|
|
261
265
|
_cachedClientPagesNavCtxKey = cacheKey;
|
|
@@ -284,27 +288,33 @@ function getPagesNavigationContext() {
|
|
|
284
288
|
if (!ssrCtx) return null;
|
|
285
289
|
const cached = _ssrPagesNavCtxCache.get(ssrCtx);
|
|
286
290
|
if (cached) return cached;
|
|
287
|
-
let
|
|
291
|
+
let searchString = "";
|
|
288
292
|
let resolvedPath;
|
|
289
293
|
try {
|
|
290
294
|
const url = new URL(ssrCtx.asPath, "http://_");
|
|
291
|
-
|
|
295
|
+
searchString = url.search;
|
|
292
296
|
resolvedPath = url.pathname;
|
|
293
297
|
} catch {
|
|
294
|
-
searchParams = new URLSearchParams();
|
|
295
298
|
resolvedPath = ssrCtx.pathname;
|
|
296
299
|
}
|
|
297
|
-
const
|
|
300
|
+
const isReady = ssrCtx.navigationIsReady ?? true;
|
|
301
|
+
const searchParams = isReady ? new URLSearchParams(searchString) : new URLSearchParams();
|
|
302
|
+
const params = isReady ? extractRouteParamsFromPath(ssrCtx.pathname, resolvedPath) ?? getRouteParamsFromQuery(ssrCtx.pathname, ssrCtx.query) ?? {} : null;
|
|
303
|
+
const isAutoExportDynamic = ssrCtx.nextData?.autoExport === true && extractRouteParamNames(ssrCtx.pathname).length > 0;
|
|
298
304
|
const ctx = {
|
|
299
|
-
pathname: resolvedPath,
|
|
305
|
+
pathname: resolvePagesNavigationPathname(resolvedPath, ssrCtx.isFallback === true, isAutoExportDynamic, isReady),
|
|
300
306
|
searchParams,
|
|
301
307
|
params
|
|
302
308
|
};
|
|
303
309
|
_ssrPagesNavCtxCache.set(ssrCtx, ctx);
|
|
304
310
|
return ctx;
|
|
305
311
|
}
|
|
312
|
+
if (!isPagesRouterDocumentActive()) return null;
|
|
306
313
|
const resolvedPath = stripBasePath(window.location.pathname, __basePath);
|
|
307
|
-
|
|
314
|
+
const nextData = window.__NEXT_DATA__;
|
|
315
|
+
const pattern = resolvePagesRoutePatternForPath(nextData?.page, resolvedPath);
|
|
316
|
+
if (!pattern) return null;
|
|
317
|
+
return _buildClientPagesNavigationContext(pattern, resolvedPath, window.location.search, isPagesRouterReady(), nextData);
|
|
308
318
|
}
|
|
309
319
|
/**
|
|
310
320
|
* Extract param names from a Next.js route pattern.
|
|
@@ -321,9 +331,52 @@ function extractRouteParamNames(pattern) {
|
|
|
321
331
|
for (const m of colonMatches) names.push(m[1]);
|
|
322
332
|
return names;
|
|
323
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Resolve the `pathname` snapshot for the Pages Router navigation context.
|
|
336
|
+
* Shared by the client and SSR branches of `getPagesNavigationContext` so both
|
|
337
|
+
* runtimes derive identical null-ness — diverging here would reintroduce a
|
|
338
|
+
* hydration mismatch. Returns `null` for a `getStaticPaths` fallback shell or a
|
|
339
|
+
* pre-ready auto-export dynamic route (the live path is published once the
|
|
340
|
+
* client router becomes ready).
|
|
341
|
+
*/
|
|
342
|
+
function resolvePagesNavigationPathname(resolvedPath, isFallback, isAutoExportDynamic, isReady) {
|
|
343
|
+
return isFallback || isAutoExportDynamic && !isReady ? null : resolvedPath;
|
|
344
|
+
}
|
|
345
|
+
let _cachedPagesRoutePatternKey = null;
|
|
346
|
+
let _cachedPagesRoutePattern;
|
|
347
|
+
function resolvePagesRoutePatternForPath(nextDataPage, resolvedPath) {
|
|
348
|
+
if (nextDataPage && extractRouteParamNames(nextDataPage).length > 0) return nextDataPage;
|
|
349
|
+
const cacheKey = `${nextDataPage ?? ""}|${resolvedPath}`;
|
|
350
|
+
if (_cachedPagesRoutePatternKey === cacheKey) return _cachedPagesRoutePattern;
|
|
351
|
+
let resolved = nextDataPage;
|
|
352
|
+
for (const pattern of window.__VINEXT_PAGE_PATTERNS__ ?? []) if (matchRoutePattern(splitPathSegments(resolvedPath), routePatternParts(pattern))) {
|
|
353
|
+
resolved = pattern;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
_cachedPagesRoutePatternKey = cacheKey;
|
|
357
|
+
_cachedPagesRoutePattern = resolved;
|
|
358
|
+
return resolved;
|
|
359
|
+
}
|
|
324
360
|
function extractRouteParamsFromPath(pattern, pathname) {
|
|
325
361
|
return matchRoutePattern(splitPathSegments(pathname), routePatternParts(pattern));
|
|
326
362
|
}
|
|
363
|
+
function getRouteParamsFromQuery(pattern, query) {
|
|
364
|
+
const names = extractRouteParamNames(pattern);
|
|
365
|
+
if (names.length === 0) return null;
|
|
366
|
+
const params = {};
|
|
367
|
+
let hasParam = false;
|
|
368
|
+
for (const name of names) {
|
|
369
|
+
const value = query[name];
|
|
370
|
+
if (typeof value === "string") {
|
|
371
|
+
params[name] = value;
|
|
372
|
+
hasParam = true;
|
|
373
|
+
} else if (Array.isArray(value)) {
|
|
374
|
+
params[name] = [...value];
|
|
375
|
+
hasParam = true;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return hasParam ? params : null;
|
|
379
|
+
}
|
|
327
380
|
function getRouteQueryFromNextData(nextData, resolvedPath) {
|
|
328
381
|
const routeQuery = {};
|
|
329
382
|
if (!nextData?.query || !nextData.page) return routeQuery;
|
|
@@ -372,6 +425,47 @@ function getPathnameAndQuery() {
|
|
|
372
425
|
asPath: resolvedPath + window.location.search + window.location.hash
|
|
373
426
|
};
|
|
374
427
|
}
|
|
428
|
+
function getPagesNavigationIsReadyFromSerializedState(routePattern, searchString, nextData) {
|
|
429
|
+
if (!routePattern) return true;
|
|
430
|
+
if (nextData?.gssp === true || nextData?.gip === true || nextData?.isExperimentalCompile === true || nextData?.appGip === true && nextData.gsp !== true) return true;
|
|
431
|
+
const autoExportDynamic = nextData?.autoExport === true && extractRouteParamNames(routePattern).length > 0;
|
|
432
|
+
const hasSearch = searchString.length > 0;
|
|
433
|
+
const hasRewrites = nextData?.__vinext?.hasRewrites === true;
|
|
434
|
+
return !autoExportDynamic && !hasSearch && !hasRewrites;
|
|
435
|
+
}
|
|
436
|
+
function shouldDeferInitialPagesRouterReady() {
|
|
437
|
+
if (typeof window === "undefined") return false;
|
|
438
|
+
const nextData = window.__NEXT_DATA__;
|
|
439
|
+
if (!nextData) return false;
|
|
440
|
+
return !getPagesNavigationIsReadyFromSerializedState(nextData.page, window.location.search, nextData);
|
|
441
|
+
}
|
|
442
|
+
let _pagesRouterReady = typeof window === "undefined" ? true : !shouldDeferInitialPagesRouterReady();
|
|
443
|
+
function isPagesRouterReady() {
|
|
444
|
+
return _pagesRouterReady;
|
|
445
|
+
}
|
|
446
|
+
function isPagesRouterDocumentActive() {
|
|
447
|
+
if (typeof window === "undefined") return true;
|
|
448
|
+
if (window.__VINEXT_PAGE_LOADERS__) return true;
|
|
449
|
+
if (window.next?.appDir === true) return false;
|
|
450
|
+
if (window.next?.router) return true;
|
|
451
|
+
return Boolean(window.__VINEXT_APP__ || window.__VINEXT_APP_LOADER__);
|
|
452
|
+
}
|
|
453
|
+
function markPagesRouterReady() {
|
|
454
|
+
if (typeof window === "undefined" || _pagesRouterReady) return false;
|
|
455
|
+
_pagesRouterReady = true;
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
function getRouterSnapshot() {
|
|
459
|
+
const isReady = typeof window === "undefined" ? _getSSRContext()?.navigationIsReady ?? true : isPagesRouterReady();
|
|
460
|
+
return {
|
|
461
|
+
...getPathnameAndQuery(),
|
|
462
|
+
isReady
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function notifyNextNavigationPagesContext() {
|
|
466
|
+
const notify = globalThis[PAGES_NAVIGATION_NOTIFY_KEY];
|
|
467
|
+
notify?.();
|
|
468
|
+
}
|
|
375
469
|
/**
|
|
376
470
|
* Error thrown when a navigation is superseded by a newer one.
|
|
377
471
|
* Matches Next.js's convention of an Error with `.cancelled = true`.
|
|
@@ -779,7 +873,7 @@ async function runNavigateClient(fullUrl, resolvedUrl, fetchUrl = fullUrl, optio
|
|
|
779
873
|
* and a set of navigation methods. Shared by the Pages Router context provider
|
|
780
874
|
* and tests so the public router shape stays in sync.
|
|
781
875
|
*/
|
|
782
|
-
function buildRouterValue(pathname, query, asPath, methods) {
|
|
876
|
+
function buildRouterValue(pathname, query, asPath, isReady, methods) {
|
|
783
877
|
const _ssrState = _getSSRContext();
|
|
784
878
|
const nextData = typeof window !== "undefined" ? window.__NEXT_DATA__ : void 0;
|
|
785
879
|
const locale = typeof window === "undefined" ? _ssrState?.locale : window.__VINEXT_LOCALE__;
|
|
@@ -796,7 +890,7 @@ function buildRouterValue(pathname, query, asPath, methods) {
|
|
|
796
890
|
locales,
|
|
797
891
|
defaultLocale,
|
|
798
892
|
domainLocales,
|
|
799
|
-
isReady
|
|
893
|
+
isReady,
|
|
800
894
|
isPreview: false,
|
|
801
895
|
isFallback: typeof window !== "undefined" ? nextData?.isFallback === true : _ssrState?.isFallback === true,
|
|
802
896
|
...methods,
|
|
@@ -815,6 +909,7 @@ function stripHash(url) {
|
|
|
815
909
|
}
|
|
816
910
|
/** Notify in-page listeners (e.g. useRouter hooks) that navigation occurred. */
|
|
817
911
|
function dispatchNavigateEvent() {
|
|
912
|
+
notifyNextNavigationPagesContext();
|
|
818
913
|
window.dispatchEvent(new CustomEvent("vinext:navigate"));
|
|
819
914
|
}
|
|
820
915
|
/**
|
|
@@ -922,6 +1017,14 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
|
|
|
922
1017
|
dispatchNavigateEvent();
|
|
923
1018
|
return true;
|
|
924
1019
|
}
|
|
1020
|
+
const appPath = getLocalPathname(resolved);
|
|
1021
|
+
const appPathNorm = appPath !== null ? removeTrailingSlash(appPath) : null;
|
|
1022
|
+
const appPathEntry = appPathNorm !== null ? getPagesRouterComponentsMap()[appPathNorm] : void 0;
|
|
1023
|
+
if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter) {
|
|
1024
|
+
if (mode === "push") window.location.assign(full);
|
|
1025
|
+
else window.location.replace(full);
|
|
1026
|
+
return new Promise(() => {});
|
|
1027
|
+
}
|
|
925
1028
|
if (mode === "push") saveScrollPosition();
|
|
926
1029
|
routerEvents.emit("routeChangeStart", resolved, { shallow });
|
|
927
1030
|
routerEvents.emit("beforeHistoryChange", resolved, { shallow });
|
|
@@ -984,15 +1087,25 @@ function useRouter() {
|
|
|
984
1087
|
return router;
|
|
985
1088
|
}
|
|
986
1089
|
function PagesRouterProvider({ children }) {
|
|
987
|
-
const [{ pathname, query, asPath }, setState] = useState(
|
|
1090
|
+
const [{ pathname, query, asPath, isReady }, setState] = useState(getRouterSnapshot);
|
|
988
1091
|
useEffect(() => {
|
|
989
1092
|
const onNavigate = ((_e) => {
|
|
990
|
-
setState(
|
|
1093
|
+
setState(getRouterSnapshot());
|
|
991
1094
|
});
|
|
992
1095
|
window.addEventListener("vinext:navigate", onNavigate);
|
|
993
|
-
|
|
1096
|
+
let cancelled = false;
|
|
1097
|
+
const readyTimer = window.setTimeout(() => {
|
|
1098
|
+
if (cancelled || !markPagesRouterReady()) return;
|
|
1099
|
+
setState(getRouterSnapshot());
|
|
1100
|
+
notifyNextNavigationPagesContext();
|
|
1101
|
+
}, 0);
|
|
1102
|
+
return () => {
|
|
1103
|
+
cancelled = true;
|
|
1104
|
+
window.clearTimeout(readyTimer);
|
|
1105
|
+
window.removeEventListener("vinext:navigate", onNavigate);
|
|
1106
|
+
};
|
|
994
1107
|
}, []);
|
|
995
|
-
const router = useMemo(() => buildRouterValue(pathname, query, asPath, {
|
|
1108
|
+
const router = useMemo(() => buildRouterValue(pathname, query, asPath, isReady, {
|
|
996
1109
|
push: Router.push,
|
|
997
1110
|
replace: Router.replace,
|
|
998
1111
|
back: Router.back,
|
|
@@ -1002,7 +1115,8 @@ function PagesRouterProvider({ children }) {
|
|
|
1002
1115
|
}), [
|
|
1003
1116
|
pathname,
|
|
1004
1117
|
query,
|
|
1005
|
-
asPath
|
|
1118
|
+
asPath,
|
|
1119
|
+
isReady
|
|
1006
1120
|
]);
|
|
1007
1121
|
const appRouter = useMemo(() => ({
|
|
1008
1122
|
bfcacheId: "0",
|
|
@@ -1215,8 +1329,9 @@ const Router = Object.defineProperties(RouterMethods, {
|
|
|
1215
1329
|
},
|
|
1216
1330
|
isReady: {
|
|
1217
1331
|
enumerable: true,
|
|
1218
|
-
|
|
1219
|
-
|
|
1332
|
+
get() {
|
|
1333
|
+
return isPagesRouterReady();
|
|
1334
|
+
}
|
|
1220
1335
|
},
|
|
1221
1336
|
isPreview: {
|
|
1222
1337
|
enumerable: true,
|
|
@@ -1231,8 +1346,27 @@ const Router = Object.defineProperties(RouterMethods, {
|
|
|
1231
1346
|
}
|
|
1232
1347
|
}
|
|
1233
1348
|
});
|
|
1349
|
+
for (const event of [
|
|
1350
|
+
"routeChangeStart",
|
|
1351
|
+
"beforeHistoryChange",
|
|
1352
|
+
"routeChangeComplete",
|
|
1353
|
+
"routeChangeError",
|
|
1354
|
+
"hashChangeStart",
|
|
1355
|
+
"hashChangeComplete"
|
|
1356
|
+
]) {
|
|
1357
|
+
const eventField = `on${event.charAt(0).toUpperCase()}${event.substring(1)}`;
|
|
1358
|
+
routerEvents.on(event, (...args) => {
|
|
1359
|
+
const handler = Router[eventField];
|
|
1360
|
+
if (typeof handler === "function") try {
|
|
1361
|
+
handler(...args);
|
|
1362
|
+
} catch (err) {
|
|
1363
|
+
console.error(`Error when running the Router event: ${eventField}`);
|
|
1364
|
+
console.error(err instanceof Error ? `${err.message}\n${err.stack}` : String(err));
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
1234
1368
|
if (typeof window !== "undefined") installWindowNext({ router: Router });
|
|
1235
1369
|
const _PAGES_NAVIGATION_ACCESSOR_KEY = Symbol.for("vinext.navigation.pagesNavigationContextAccessor");
|
|
1236
1370
|
globalThis[_PAGES_NAVIGATION_ACCESSOR_KEY] = getPagesNavigationContext;
|
|
1237
1371
|
//#endregion
|
|
1238
|
-
export { _registerRouterStateAccessors, applyNavigationLocale, Router as default, getPagesNavigationContext, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };
|
|
1372
|
+
export { _registerRouterStateAccessors, applyNavigationLocale, Router as default, getPagesNavigationContext, getPagesNavigationIsReadyFromSerializedState, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
3
|
//#region src/shims/script-nonce-context.d.ts
|
|
4
|
-
declare const ScriptNonceContext: React.Context<string | undefined
|
|
4
|
+
declare const ScriptNonceContext: React.Context<string | undefined> | null;
|
|
5
5
|
declare function ScriptNonceProvider(props: React.PropsWithChildren<{
|
|
6
6
|
nonce?: string;
|
|
7
7
|
}>): React.ReactElement;
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
//#region src/shims/script-nonce-context.tsx
|
|
3
|
-
const ScriptNonceContext = React.createContext(void 0);
|
|
3
|
+
const ScriptNonceContext = typeof React.createContext === "function" ? React.createContext(void 0) : null;
|
|
4
4
|
function ScriptNonceProvider(props) {
|
|
5
|
+
if (!ScriptNonceContext) return React.createElement(React.Fragment, null, props.children);
|
|
5
6
|
return React.createElement(ScriptNonceContext.Provider, { value: props.nonce }, props.children);
|
|
6
7
|
}
|
|
7
8
|
function withScriptNonce(element, nonce) {
|
|
8
|
-
if (!nonce) return element;
|
|
9
|
+
if (!nonce || !ScriptNonceContext) return element;
|
|
9
10
|
return React.createElement(ScriptNonceProvider, { nonce }, element);
|
|
10
11
|
}
|
|
12
|
+
function createScriptNonceHook(context) {
|
|
13
|
+
if (!context || typeof React.useContext !== "function") return function useScriptNonceFromContext() {};
|
|
14
|
+
return function useScriptNonceFromContext() {
|
|
15
|
+
return React.useContext(context);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const useScriptNonceFromContext = createScriptNonceHook(ScriptNonceContext);
|
|
11
19
|
function useScriptNonce() {
|
|
12
|
-
return
|
|
20
|
+
return useScriptNonceFromContext();
|
|
13
21
|
}
|
|
14
22
|
//#endregion
|
|
15
23
|
export { ScriptNonceContext, ScriptNonceProvider, useScriptNonce, withScriptNonce };
|
package/dist/shims/server.d.ts
CHANGED
|
@@ -91,13 +91,29 @@ type NextURLConfig = {
|
|
|
91
91
|
declare class NextURL {
|
|
92
92
|
/** Internal URL stores the pathname WITHOUT basePath or locale prefix. */
|
|
93
93
|
private _url;
|
|
94
|
+
/**
|
|
95
|
+
* The configured basePath (from nextConfig). May differ from the active
|
|
96
|
+
* `_basePath`: parsing only activates basePath when the URL's pathname
|
|
97
|
+
* actually carries the configured prefix.
|
|
98
|
+
*/
|
|
99
|
+
private _configBasePath;
|
|
94
100
|
private _basePath;
|
|
95
101
|
private _trailingSlash;
|
|
96
102
|
private _locale;
|
|
97
103
|
private _defaultLocale;
|
|
98
104
|
private _locales;
|
|
99
105
|
constructor(input: string | URL, base?: string | URL, config?: NextURLConfig);
|
|
100
|
-
/** Strip basePath prefix from the internal pathname.
|
|
106
|
+
/** Strip basePath prefix from the internal pathname.
|
|
107
|
+
* Mirrors Next.js's getNextPathnameInfo (re-run by NextURL.analyze() on
|
|
108
|
+
* every parse, including `href` reassignment): basePath is only considered
|
|
109
|
+
* active when the URL's pathname actually starts with the configured
|
|
110
|
+
* basePath prefix. If the pathname is outside the basePath, the active
|
|
111
|
+
* basePath is cleared to "" so that request.nextUrl.basePath reflects the
|
|
112
|
+
* actual URL rather than the config value; if a later `href` assignment
|
|
113
|
+
* moves the URL back inside the basePath, it is re-activated from the
|
|
114
|
+
* configured value. This matches the Next.js behavior tested by
|
|
115
|
+
* middleware-base-path's "should execute from absolute paths" case.
|
|
116
|
+
*/
|
|
101
117
|
private _stripBasePath;
|
|
102
118
|
/** Extract locale from pathname, stripping it from the internal URL. */
|
|
103
119
|
private _analyzeLocale;
|
package/dist/shims/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stripBasePath } from "../utils/base-path.js";
|
|
1
|
+
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { getRequestExecutionContext } from "./request-context.js";
|
|
3
3
|
import { MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER } from "../server/headers.js";
|
|
4
4
|
import { encodeMiddlewareRequestHeaders } from "../server/middleware-request-headers.js";
|
|
@@ -183,6 +183,12 @@ var NextResponse = class NextResponse extends Response {
|
|
|
183
183
|
var NextURL = class NextURL {
|
|
184
184
|
/** Internal URL stores the pathname WITHOUT basePath or locale prefix. */
|
|
185
185
|
_url;
|
|
186
|
+
/**
|
|
187
|
+
* The configured basePath (from nextConfig). May differ from the active
|
|
188
|
+
* `_basePath`: parsing only activates basePath when the URL's pathname
|
|
189
|
+
* actually carries the configured prefix.
|
|
190
|
+
*/
|
|
191
|
+
_configBasePath;
|
|
186
192
|
_basePath;
|
|
187
193
|
_trailingSlash;
|
|
188
194
|
_locale;
|
|
@@ -190,7 +196,8 @@ var NextURL = class NextURL {
|
|
|
190
196
|
_locales;
|
|
191
197
|
constructor(input, base, config) {
|
|
192
198
|
this._url = new URL(input.toString(), base);
|
|
193
|
-
this.
|
|
199
|
+
this._configBasePath = config?.basePath ?? "";
|
|
200
|
+
this._basePath = this._configBasePath;
|
|
194
201
|
this._trailingSlash = config?.nextConfig?.trailingSlash ?? false;
|
|
195
202
|
this._stripBasePath();
|
|
196
203
|
const i18n = config?.nextConfig?.i18n;
|
|
@@ -200,10 +207,25 @@ var NextURL = class NextURL {
|
|
|
200
207
|
this._analyzeLocale(this._locales);
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
|
-
/** Strip basePath prefix from the internal pathname.
|
|
210
|
+
/** Strip basePath prefix from the internal pathname.
|
|
211
|
+
* Mirrors Next.js's getNextPathnameInfo (re-run by NextURL.analyze() on
|
|
212
|
+
* every parse, including `href` reassignment): basePath is only considered
|
|
213
|
+
* active when the URL's pathname actually starts with the configured
|
|
214
|
+
* basePath prefix. If the pathname is outside the basePath, the active
|
|
215
|
+
* basePath is cleared to "" so that request.nextUrl.basePath reflects the
|
|
216
|
+
* actual URL rather than the config value; if a later `href` assignment
|
|
217
|
+
* moves the URL back inside the basePath, it is re-activated from the
|
|
218
|
+
* configured value. This matches the Next.js behavior tested by
|
|
219
|
+
* middleware-base-path's "should execute from absolute paths" case.
|
|
220
|
+
*/
|
|
204
221
|
_stripBasePath() {
|
|
205
|
-
if (!this.
|
|
206
|
-
|
|
222
|
+
if (!this._configBasePath) return;
|
|
223
|
+
if (!hasBasePath(this._url.pathname, this._configBasePath)) {
|
|
224
|
+
this._basePath = "";
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
this._basePath = this._configBasePath;
|
|
228
|
+
this._url.pathname = stripBasePath(this._url.pathname, this._configBasePath);
|
|
207
229
|
}
|
|
208
230
|
/** Extract locale from pathname, stripping it from the internal URL. */
|
|
209
231
|
_analyzeLocale(locales) {
|
|
@@ -655,10 +677,13 @@ function after(task) {
|
|
|
655
677
|
* and sets Cache-Control: no-store on the response.
|
|
656
678
|
*/
|
|
657
679
|
async function connection() {
|
|
658
|
-
const { markDynamicUsage, markRenderRequestApiUsage, throwIfInsideCacheScope } = await import("./headers.js");
|
|
680
|
+
const { getHeadersContext, markDynamicUsage, markRenderRequestApiUsage, suspendConnectionProbe, throwIfInsideCacheScope } = await import("./headers.js");
|
|
681
|
+
if (getHeadersContext()?.forceStatic) return;
|
|
659
682
|
markRenderRequestApiUsage("connection");
|
|
660
683
|
throwIfInsideCacheScope("connection()");
|
|
661
684
|
markDynamicUsage();
|
|
685
|
+
const pendingProbe = suspendConnectionProbe();
|
|
686
|
+
if (pendingProbe) await pendingProbe;
|
|
662
687
|
}
|
|
663
688
|
/**
|
|
664
689
|
* URLPattern re-export — used in middleware for route matching.
|
package/dist/shims/slot.js
CHANGED
|
@@ -23,7 +23,7 @@ const MAX_BFCACHE_SLOT_ENTRIES_WITH_CACHE_COMPONENTS = 3;
|
|
|
23
23
|
const MAX_BFCACHE_SLOT_ENTRIES_WITHOUT_CACHE_COMPONENTS = 1;
|
|
24
24
|
const BfcacheStateKeyMapContext = React$1.createContext(EMPTY_BFCACHE_STATE_KEYS);
|
|
25
25
|
function isCacheComponentsEnabled() {
|
|
26
|
-
return process.env.__NEXT_CACHE_COMPONENTS === "true";
|
|
26
|
+
return String(process.env.__NEXT_CACHE_COMPONENTS) === "true";
|
|
27
27
|
}
|
|
28
28
|
function getBfcacheSlotEntryLimit() {
|
|
29
29
|
return isCacheComponentsEnabled() ? MAX_BFCACHE_SLOT_ENTRIES_WITH_CACHE_COMPONENTS : MAX_BFCACHE_SLOT_ENTRIES_WITHOUT_CACHE_COMPONENTS;
|
|
@@ -18,6 +18,7 @@ function createRequestContext(opts) {
|
|
|
18
18
|
actionRevalidationKind: 0,
|
|
19
19
|
dynamicUsageDetected: false,
|
|
20
20
|
renderRequestApiUsage: /* @__PURE__ */ new Set(),
|
|
21
|
+
connectionProbe: null,
|
|
21
22
|
invalidDynamicUsageError: null,
|
|
22
23
|
pendingSetCookies: [],
|
|
23
24
|
draftModeCookieHeader: null,
|
package/dist/typegen.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { decodeRouteSegment, isInvisibleSegment } from "./routing/utils.js";
|
|
2
2
|
import { patternToNextFormat } from "./routing/route-validation.js";
|
|
3
3
|
import { compareStrings } from "./utils/compare.js";
|
|
4
|
+
import "./routing/app-route-graph.js";
|
|
4
5
|
import { appRouteGraph } from "./routing/app-router.js";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import fs from "node:fs/promises";
|
|
@@ -4,11 +4,18 @@ import { BuildManifestChunk } from "./lazy-chunks.js";
|
|
|
4
4
|
type ClientBuildManifest = Record<string, BuildManifestChunk>;
|
|
5
5
|
declare function readClientBuildManifest(manifestPath: string): ClientBuildManifest | undefined;
|
|
6
6
|
declare function findClientEntryFileFromManifest(buildManifest: ClientBuildManifest, assetBase: string): string | undefined;
|
|
7
|
+
declare function findPagesClientEntryFileFromManifest(buildManifest: ClientBuildManifest, assetBase: string): string | undefined;
|
|
7
8
|
declare function findClientEntryFile(options: {
|
|
8
9
|
buildManifest?: ClientBuildManifest;
|
|
9
10
|
clientDir: string;
|
|
10
11
|
assetsSubdir: string;
|
|
11
12
|
assetBase: string;
|
|
12
13
|
}): string | undefined;
|
|
14
|
+
declare function findPagesClientEntryFile(options: {
|
|
15
|
+
buildManifest?: ClientBuildManifest;
|
|
16
|
+
clientDir: string;
|
|
17
|
+
assetsSubdir: string;
|
|
18
|
+
assetBase: string;
|
|
19
|
+
}): string | undefined;
|
|
13
20
|
//#endregion
|
|
14
|
-
export { findClientEntryFile, findClientEntryFileFromManifest, readClientBuildManifest };
|
|
21
|
+
export { findClientEntryFile, findClientEntryFileFromManifest, findPagesClientEntryFile, findPagesClientEntryFileFromManifest, readClientBuildManifest };
|
|
@@ -3,7 +3,8 @@ import { manifestFileWithBase } from "./manifest-paths.js";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
//#region src/utils/client-build-manifest.ts
|
|
6
|
-
const
|
|
6
|
+
const PAGES_CLIENT_ENTRY_MARKERS = ["vinext-client-entry"];
|
|
7
|
+
const CLIENT_ENTRY_MARKERS = [...PAGES_CLIENT_ENTRY_MARKERS, "vinext-app-browser-entry"];
|
|
7
8
|
function readClientBuildManifest(manifestPath) {
|
|
8
9
|
if (!fs.existsSync(manifestPath)) return void 0;
|
|
9
10
|
try {
|
|
@@ -32,21 +33,55 @@ function readClientBuildManifest(manifestPath) {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
function findClientEntryFileFromManifest(buildManifest, assetBase) {
|
|
36
|
+
return findEntryFileFromManifest(buildManifest, assetBase, CLIENT_ENTRY_MARKERS, true);
|
|
37
|
+
}
|
|
38
|
+
function findPagesClientEntryFileFromManifest(buildManifest, assetBase) {
|
|
39
|
+
return findEntryFileFromManifest(buildManifest, assetBase, PAGES_CLIENT_ENTRY_MARKERS, false);
|
|
40
|
+
}
|
|
41
|
+
function findEntryFileFromManifest(buildManifest, assetBase, markers, fallbackToFirstEntry) {
|
|
35
42
|
const entries = Object.values(buildManifest).filter((entry) => entry.isEntry && entry.file);
|
|
36
|
-
|
|
43
|
+
for (const marker of markers) {
|
|
44
|
+
const markedEntry = entries.find((entry) => entry.file.includes(marker));
|
|
45
|
+
if (markedEntry) return manifestFileWithBase(markedEntry.file, assetBase);
|
|
46
|
+
}
|
|
47
|
+
const chosen = fallbackToFirstEntry ? entries[0] : void 0;
|
|
37
48
|
return chosen ? manifestFileWithBase(chosen.file, assetBase) : void 0;
|
|
38
49
|
}
|
|
50
|
+
function listFilesRecursive(dir) {
|
|
51
|
+
const out = [];
|
|
52
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
53
|
+
const full = path.join(dir, entry.name);
|
|
54
|
+
if (entry.isDirectory()) out.push(...listFilesRecursive(full));
|
|
55
|
+
else if (entry.isFile()) out.push(full);
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
39
59
|
function findClientEntryFileInAssetsDir(options) {
|
|
40
60
|
const assetsDir = path.join(options.clientDir, options.assetsSubdir);
|
|
41
61
|
if (!fs.existsSync(assetsDir)) return void 0;
|
|
42
|
-
const
|
|
43
|
-
|
|
62
|
+
const files = listFilesRecursive(assetsDir);
|
|
63
|
+
let entryFull;
|
|
64
|
+
for (const marker of options.markers) {
|
|
65
|
+
entryFull = files.find((file) => path.basename(file).includes(marker) && file.endsWith(".js"));
|
|
66
|
+
if (entryFull) break;
|
|
67
|
+
}
|
|
68
|
+
if (!entryFull) return void 0;
|
|
69
|
+
return manifestFileWithBase(path.relative(options.clientDir, entryFull).split(path.sep).join("/"), options.assetBase);
|
|
44
70
|
}
|
|
45
71
|
function findClientEntryFile(options) {
|
|
46
|
-
return (options.buildManifest ? findClientEntryFileFromManifest(options.buildManifest, options.assetBase) : void 0) ?? findClientEntryFileInAssetsDir(
|
|
72
|
+
return (options.buildManifest ? findClientEntryFileFromManifest(options.buildManifest, options.assetBase) : void 0) ?? findClientEntryFileInAssetsDir({
|
|
73
|
+
...options,
|
|
74
|
+
markers: CLIENT_ENTRY_MARKERS
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function findPagesClientEntryFile(options) {
|
|
78
|
+
return (options.buildManifest ? findPagesClientEntryFileFromManifest(options.buildManifest, options.assetBase) : void 0) ?? findClientEntryFileInAssetsDir({
|
|
79
|
+
...options,
|
|
80
|
+
markers: PAGES_CLIENT_ENTRY_MARKERS
|
|
81
|
+
});
|
|
47
82
|
}
|
|
48
83
|
function readStringArray(value) {
|
|
49
84
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
50
85
|
}
|
|
51
86
|
//#endregion
|
|
52
|
-
export { findClientEntryFile, findClientEntryFileFromManifest, readClientBuildManifest };
|
|
87
|
+
export { findClientEntryFile, findClientEntryFileFromManifest, findPagesClientEntryFile, findPagesClientEntryFileFromManifest, readClientBuildManifest };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/utils/client-entry-manifest.d.ts
|
|
2
|
+
declare const VINEXT_CLIENT_ENTRY_MANIFEST = "vinext-client-entry-manifest.json";
|
|
3
|
+
type ClientEntryManifest = {
|
|
4
|
+
pagesClientEntry?: string;
|
|
5
|
+
appBrowserEntry?: string;
|
|
6
|
+
};
|
|
7
|
+
declare function readClientEntryManifest(clientDir: string): ClientEntryManifest | undefined;
|
|
8
|
+
declare function findClientEntryFileFromVinextManifest(manifest: ClientEntryManifest | undefined, assetBase: string): string | undefined;
|
|
9
|
+
declare function findPagesClientEntryFileFromVinextManifest(manifest: ClientEntryManifest | undefined, assetBase: string): string | undefined;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ClientEntryManifest, VINEXT_CLIENT_ENTRY_MANIFEST, findClientEntryFileFromVinextManifest, findPagesClientEntryFileFromVinextManifest, readClientEntryManifest };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isUnknownRecord } from "./record.js";
|
|
2
|
+
import { manifestFileWithBase } from "./manifest-paths.js";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
//#region src/utils/client-entry-manifest.ts
|
|
6
|
+
const VINEXT_CLIENT_ENTRY_MANIFEST = "vinext-client-entry-manifest.json";
|
|
7
|
+
function readClientEntryManifest(clientDir) {
|
|
8
|
+
const manifestPath = path.join(clientDir, VINEXT_CLIENT_ENTRY_MANIFEST);
|
|
9
|
+
if (!fs.existsSync(manifestPath)) return void 0;
|
|
10
|
+
try {
|
|
11
|
+
const value = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
12
|
+
if (!isUnknownRecord(value)) return void 0;
|
|
13
|
+
const manifest = {};
|
|
14
|
+
if (typeof value.pagesClientEntry === "string") manifest.pagesClientEntry = value.pagesClientEntry;
|
|
15
|
+
if (typeof value.appBrowserEntry === "string") manifest.appBrowserEntry = value.appBrowserEntry;
|
|
16
|
+
return manifest.pagesClientEntry || manifest.appBrowserEntry ? manifest : void 0;
|
|
17
|
+
} catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function findClientEntryFileFromVinextManifest(manifest, assetBase) {
|
|
22
|
+
const entry = manifest?.pagesClientEntry ?? manifest?.appBrowserEntry;
|
|
23
|
+
return entry ? manifestFileWithBase(entry, assetBase) : void 0;
|
|
24
|
+
}
|
|
25
|
+
function findPagesClientEntryFileFromVinextManifest(manifest, assetBase) {
|
|
26
|
+
return manifest?.pagesClientEntry ? manifestFileWithBase(manifest.pagesClientEntry, assetBase) : void 0;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { VINEXT_CLIENT_ENTRY_MANIFEST, findClientEntryFileFromVinextManifest, findPagesClientEntryFileFromVinextManifest, readClientEntryManifest };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/utils/client-runtime-metadata.d.ts
|
|
2
|
+
type ClientRuntimeMetadata = {
|
|
3
|
+
clientEntryFile?: string;
|
|
4
|
+
lazyChunks?: string[];
|
|
5
|
+
dynamicPreloads?: Record<string, string[]>;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Read the client build manifest and compute runtime metadata used by
|
|
9
|
+
* Cloudflare worker entry injection and Node production server startup.
|
|
10
|
+
*
|
|
11
|
+
* - `lazyChunks` — chunks only reachable through dynamic `import()`, excluded
|
|
12
|
+
* from modulepreload hints.
|
|
13
|
+
* - `dynamicPreloads` — per-module JS/CSS files for rendered `next/dynamic()`
|
|
14
|
+
* boundaries, injected as preload links during SSR.
|
|
15
|
+
* - `clientEntryFile` — the client entry chunk filename (optional, only
|
|
16
|
+
* needed for Pages Router).
|
|
17
|
+
*
|
|
18
|
+
* All file paths are normalised with the configured `assetBase` (basePath)
|
|
19
|
+
* and `assetPrefix`.
|
|
20
|
+
*/
|
|
21
|
+
declare function computeClientRuntimeMetadata(opts: {
|
|
22
|
+
clientDir: string;
|
|
23
|
+
assetBase: string;
|
|
24
|
+
assetPrefix: string;
|
|
25
|
+
includeClientEntry?: boolean | "pages-client-entry";
|
|
26
|
+
}): ClientRuntimeMetadata;
|
|
27
|
+
/**
|
|
28
|
+
* Serialize runtime metadata into the `globalThis.__VINEXT_*` assignment script
|
|
29
|
+
* that the Cloudflare `closeBundle` hook prepends to the worker entry. Returns
|
|
30
|
+
* `""` when there is nothing to inject.
|
|
31
|
+
*
|
|
32
|
+
* Both the App Router and Pages Router closeBundle paths call this (and the
|
|
33
|
+
* deploy tests mirror it), so the injection shape stays in one place. The caller
|
|
34
|
+
* decides which fields to pass — e.g. App Router only forwards `clientEntryFile`
|
|
35
|
+
* for mixed app+pages builds (where `computeClientRuntimeMetadata` was asked for
|
|
36
|
+
* the Pages client entry); pure App Router leaves it undefined.
|
|
37
|
+
*/
|
|
38
|
+
declare function buildRuntimeGlobalsScript(input: {
|
|
39
|
+
clientEntryFile?: string | null;
|
|
40
|
+
ssrManifest?: Record<string, string[]> | null;
|
|
41
|
+
lazyChunks?: string[] | null;
|
|
42
|
+
dynamicPreloads?: Record<string, string[]> | null;
|
|
43
|
+
}): string;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { buildRuntimeGlobalsScript, computeClientRuntimeMetadata };
|