@wular/pnext 0.1.5 → 0.1.7
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/bin/pnext +9 -2
- package/dist/server/_chunks/aliases-j47a10ce.js +44 -0
- package/dist/server/_chunks/analyze-arswqe6s.js +445 -0
- package/dist/server/_chunks/boot-af0mv3dy.js +36 -0
- package/dist/server/_chunks/build-spy3dxp4.js +84 -0
- package/dist/server/_chunks/build-t9h0hec3.js +3550 -0
- package/dist/server/_chunks/build-tier-m7yvqz61.js +2472 -0
- package/dist/server/_chunks/compile-53j02j27.js +22 -0
- package/dist/server/_chunks/config-1yzwexq6.js +27 -0
- package/dist/server/_chunks/config-n2z7yxps.js +22 -0
- package/dist/server/_chunks/create-meec9hs6.js +134 -0
- package/dist/server/_chunks/dev-fjmqg6en.js +220 -0
- package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
- package/dist/server/_chunks/generate-n9sh6hzt.js +21 -0
- package/dist/server/_chunks/index-0374j2b9.js +66 -0
- package/dist/server/_chunks/index-06nyqntx.js +213 -0
- package/dist/server/_chunks/index-1011cscr.js +5263 -0
- package/dist/server/_chunks/index-11sfk4hb.js +170 -0
- package/dist/server/_chunks/index-20ppawv7.js +297 -0
- package/dist/server/_chunks/index-2dv4y4wd.js +1065 -0
- package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
- package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
- package/dist/server/_chunks/index-357na4a8.js +109 -0
- package/dist/server/_chunks/index-3b3at80h.js +109 -0
- package/dist/server/_chunks/index-3tf1xjsp.js +6166 -0
- package/dist/server/_chunks/index-3xbr4eyv.js +105 -0
- package/dist/server/_chunks/index-4399bvd2.js +18 -0
- package/dist/server/_chunks/index-4hgjrqh7.js +851 -0
- package/dist/server/_chunks/index-4q2gbfwk.js +2530 -0
- package/dist/server/_chunks/index-4t92hdxd.js +172 -0
- package/dist/server/_chunks/index-4zzebszd.js +10 -0
- package/dist/server/_chunks/index-5gyr4emz.js +107 -0
- package/dist/server/_chunks/index-5hr4062s.js +70 -0
- package/dist/server/_chunks/index-68m3mwbd.js +84 -0
- package/dist/server/_chunks/index-6b009mt0.js +56 -0
- package/dist/server/_chunks/index-6e4fqv30.js +588 -0
- package/dist/server/_chunks/index-6gex3pfa.js +15 -0
- package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
- package/dist/server/_chunks/index-6q7zvrap.js +134 -0
- package/dist/server/_chunks/index-73z4esab.js +38 -0
- package/dist/server/_chunks/index-79ngvam8.js +60 -0
- package/dist/server/_chunks/index-7wc9n8be.js +25 -0
- package/dist/server/_chunks/index-8k7pfejn.js +1599 -0
- package/dist/server/_chunks/index-8kcxdfya.js +206 -0
- package/dist/server/_chunks/index-91x12ykq.js +274 -0
- package/dist/server/_chunks/index-9ch50vtq.js +18 -0
- package/dist/server/_chunks/index-9hx2641q.js +28 -0
- package/dist/server/_chunks/index-9n2914ww.js +535 -0
- package/dist/server/_chunks/index-9ych9ma8.js +207 -0
- package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
- package/dist/server/_chunks/index-bcws5eh2.js +35 -0
- package/dist/server/_chunks/index-c0g2wf3z.js +92 -0
- package/dist/server/_chunks/index-cf4rvxv6.js +95 -0
- package/dist/server/_chunks/index-cjgqs13g.js +65 -0
- package/dist/server/_chunks/index-ckkdpht5.js +41 -0
- package/dist/server/_chunks/index-cyfednwb.js +87 -0
- package/dist/server/_chunks/index-danncfhy.js +311 -0
- package/dist/server/_chunks/index-dg0f05zs.js +199 -0
- package/dist/server/_chunks/index-e3a6yx84.js +18 -0
- package/dist/server/_chunks/index-e88tyv35.js +45 -0
- package/dist/server/_chunks/index-eajaspjk.js +1253 -0
- package/dist/server/_chunks/index-eeaanp2e.js +483 -0
- package/dist/server/_chunks/index-egykcqg3.js +101 -0
- package/dist/server/_chunks/index-en7n9f7m.js +22 -0
- package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
- package/dist/server/_chunks/index-fkp000p1.js +590 -0
- package/dist/server/_chunks/index-fn1chkkd.js +214 -0
- package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
- package/dist/server/_chunks/index-ggk2j965.js +9432 -0
- package/dist/server/_chunks/index-grta8ap3.js +238 -0
- package/dist/server/_chunks/index-h2a70tg4.js +7 -0
- package/dist/server/_chunks/index-h4xy648y.js +51 -0
- package/dist/server/_chunks/index-hkdfj58q.js +92 -0
- package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
- package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
- package/dist/server/_chunks/index-jepjvcrf.js +198 -0
- package/dist/server/_chunks/index-jks0x0a1.js +14 -0
- package/dist/server/_chunks/index-jx7bqvw1.js +57 -0
- package/dist/server/_chunks/index-k1g3epw0.js +1299 -0
- package/dist/server/_chunks/index-knp0s912.js +7 -0
- package/dist/server/_chunks/index-kq8kpzye.js +472 -0
- package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
- package/dist/server/_chunks/index-kresp2n8.js +445 -0
- package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
- package/dist/server/_chunks/index-n4hxpng2.js +11 -0
- package/dist/server/_chunks/index-ncnes8c6.js +17 -0
- package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
- package/dist/server/_chunks/index-nyrba2kr.js +4130 -0
- package/dist/server/_chunks/index-p77b4kcx.js +296 -0
- package/dist/server/_chunks/index-pym1cezq.js +39 -0
- package/dist/server/_chunks/index-q738kkhj.js +100 -0
- package/dist/server/_chunks/index-qjj6gddn.js +54 -0
- package/dist/server/_chunks/index-qm6kmhqs.js +110 -0
- package/dist/server/_chunks/index-qn4z5s3c.js +819 -0
- package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
- package/dist/server/_chunks/index-r97ptz1q.js +97 -0
- package/dist/server/_chunks/index-ras0sdab.js +26 -0
- package/dist/server/_chunks/index-rcs322t1.js +19 -0
- package/dist/server/_chunks/index-rn8dyr1f.js +126 -0
- package/dist/server/_chunks/index-rt9qq1va.js +4 -0
- package/dist/server/_chunks/index-rthrsed5.js +356 -0
- package/dist/server/_chunks/index-sctcgyvv.js +185 -0
- package/dist/server/_chunks/index-sjpckxqn.js +213 -0
- package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
- package/dist/server/_chunks/index-stbk3jhn.js +31 -0
- package/dist/server/_chunks/index-sv8m6789.js +266 -0
- package/dist/server/_chunks/index-tgcakdxc.js +125 -0
- package/dist/server/_chunks/index-tgsfjmep.js +74 -0
- package/dist/server/_chunks/index-tq0pc7eg.js +154 -0
- package/dist/server/_chunks/index-tq1f96v7.js +51 -0
- package/dist/server/_chunks/index-tqn2qnnn.js +241 -0
- package/dist/server/_chunks/index-tvqkq6e6.js +128 -0
- package/dist/server/_chunks/index-v1ags1na.js +132 -0
- package/dist/server/_chunks/index-vvmmknm1.js +1431 -0
- package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
- package/dist/server/_chunks/index-vz0km5qk.js +33 -0
- package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
- package/dist/server/_chunks/index-web361b8.js +138 -0
- package/dist/server/_chunks/index-wpfhfbs4.js +194 -0
- package/dist/server/_chunks/index-x0y005nh.js +283 -0
- package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
- package/dist/server/_chunks/index-x93hv0sc.js +271 -0
- package/dist/server/_chunks/index-xvj80c3a.js +30 -0
- package/dist/server/_chunks/index-xywjg2vc.js +100 -0
- package/dist/server/_chunks/index-y2jr2n72.js +152 -0
- package/dist/server/_chunks/index-y36a0ybw.js +57 -0
- package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
- package/dist/server/_chunks/index-yhxkxghe.js +56 -0
- package/dist/server/_chunks/index-ym67zqxp.js +130 -0
- package/dist/server/_chunks/index-ytjvpbm2.js +736 -0
- package/dist/server/_chunks/index-yz54pxrh.js +960 -0
- package/dist/server/_chunks/index-z4z9zv3b.js +733 -0
- package/dist/server/_chunks/index-z84ab1w0.js +1270 -0
- package/dist/server/_chunks/index-z88qv16t.js +11 -0
- package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
- package/dist/server/_chunks/loader-7yw0j98z.js +78 -0
- package/dist/server/_chunks/modules-jn8bmbn8.js +74 -0
- package/dist/server/_chunks/pipeline-yy9jhydf.js +832 -0
- package/dist/server/_chunks/production-jar9ztm3.js +44 -0
- package/dist/server/_chunks/proxy-config-j84dgksn.js +21 -0
- package/dist/server/_chunks/proxy-w1d0wmsn.js +33 -0
- package/dist/server/_chunks/router-k1reahfn.js +498 -0
- package/dist/server/_chunks/routes-2s277fc6.js +64 -0
- package/dist/server/_chunks/run-pvd8bs1t.js +696 -0
- package/dist/server/_chunks/server-mt4a994c.js +1835 -0
- package/dist/server/_chunks/tsconfig-defaults-1nb3308g.js +20 -0
- package/dist/server/_chunks/typegen-0qr0459b.js +35 -0
- package/dist/server/api/client-cache.js +14 -0
- package/dist/server/cli/index.js +378 -0
- package/dist/server/cli/start.js +137 -0
- package/dist/server/client/reference.js +16 -0
- package/dist/server/compat/next/cache.js +56 -0
- package/dist/server/compat/next/canonical-url.js +13 -0
- package/dist/server/compat/next/client-cache.js +57 -0
- package/dist/server/compat/next/client-navigation.js +232 -0
- package/dist/server/compat/next/client-only.js +1 -0
- package/dist/server/compat/next/client-script.js +178 -0
- package/dist/server/compat/next/client-server.js +34 -0
- package/dist/server/compat/next/config-headers.js +32 -0
- package/dist/server/compat/next/config-loader.js +25 -0
- package/dist/server/compat/next/config.js +10 -0
- package/dist/server/compat/next/constants.js +18 -0
- package/dist/server/compat/next/custom-server.js +10 -0
- package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
- package/dist/server/compat/next/dynamic.js +32 -0
- package/dist/server/compat/next/error.js +112 -0
- package/dist/server/compat/next/font/cache.js +14 -0
- package/dist/server/compat/next/font/google.js +3 -0
- package/dist/server/compat/next/font/index.js +1 -0
- package/dist/server/compat/next/font/local.js +22 -0
- package/dist/server/compat/next/font/runtime-client.js +33 -0
- package/dist/server/compat/next/font/runtime.js +41 -0
- package/dist/server/compat/next/font/shared.js +22 -0
- package/dist/server/compat/next/form.js +129 -0
- package/dist/server/compat/next/head.js +10 -0
- package/dist/server/compat/next/headers.js +30 -0
- package/dist/server/compat/next/image/client.js +11 -0
- package/dist/server/compat/next/image/config.js +18 -0
- package/dist/server/compat/next/image/optimizer.js +25 -0
- package/dist/server/compat/next/image/patterns.js +12 -0
- package/dist/server/compat/next/image/props.js +16 -0
- package/dist/server/compat/next/image/shared.js +86 -0
- package/dist/server/compat/next/image/static-metadata.js +32 -0
- package/dist/server/compat/next/image/validate.js +8 -0
- package/dist/server/compat/next/image.js +59 -0
- package/dist/server/compat/next/index.js +1 -0
- package/dist/server/compat/next/legacy-image.js +78 -0
- package/dist/server/compat/next/legacy-request-apis.js +24 -0
- package/dist/server/compat/next/link-transform.js +14 -0
- package/dist/server/compat/next/link.js +14 -0
- package/dist/server/compat/next/navigation.js +190 -0
- package/dist/server/compat/next/offline.js +45 -0
- package/dist/server/compat/next/og.js +8 -0
- package/dist/server/compat/next/preferred-region.js +8 -0
- package/dist/server/compat/next/redirects.js +30 -0
- package/dist/server/compat/next/resource-hints.js +30 -0
- package/dist/server/compat/next/rewrites.js +41 -0
- package/dist/server/compat/next/root-params.js +121 -0
- package/dist/server/compat/next/route-state.js +23 -0
- package/dist/server/compat/next/router.js +103 -0
- package/dist/server/compat/next/script.js +37 -0
- package/dist/server/compat/next/server-only.js +1 -0
- package/dist/server/compat/next/server.js +131 -0
- package/dist/server/compat/next/svgr.js +14 -0
- package/dist/server/compat/next/telemetry.js +10 -0
- package/dist/server/compat/next/usage.js +13 -0
- package/dist/server/compat/next/user-agent.js +12 -0
- package/dist/server/compat/next/web-vitals.js +35 -0
- package/dist/server/compat/react/action-state.js +11 -0
- package/dist/server/compat/react/client-lite.js +83 -0
- package/dist/server/compat/react/client.js +131 -0
- package/dist/server/compat/react/compiler-runtime.js +42 -0
- package/dist/server/compat/react/dom-client.js +106 -0
- package/dist/server/compat/react/dom-react-server.js +37 -0
- package/dist/server/compat/react/dom-server.js +40 -0
- package/dist/server/compat/react/dom.js +52 -0
- package/dist/server/compat/react/hooks-extra.js +12 -0
- package/dist/server/compat/react/internals.js +14 -0
- package/dist/server/compat/react/parity.js +11 -0
- package/dist/server/compat/react/preact.js +113 -0
- package/dist/server/compat/react/react-server.js +133 -0
- package/dist/server/compat/react/router-shim.js +8 -0
- package/dist/server/compat/react/server-component-use.js +14 -0
- package/dist/server/compat/react/server-inserted-html.js +14 -0
- package/dist/server/compat/react/server.js +194 -0
- package/dist/server/compat/react/style-values.js +10 -0
- package/dist/server/compat/react/use.js +10 -0
- package/dist/server/compat/react/view-transition.js +12 -0
- package/dist/server/generation.json +1 -0
- package/package.json +4 -1
- package/src/api/dynamic.tsx +2 -0
- package/src/api/server.ts +24 -6
- package/src/cli/adapters/vercel-warm.ts +315 -61
- package/src/cli/adapters/vercel.ts +348 -71
- package/src/cli/build.ts +58 -33
- package/src/cli/index.ts +23 -10
- package/src/cli/serve/entry.ts +21 -159
- package/src/cli/serve/immutable.ts +31 -0
- package/src/cli/serve/pipeline.ts +82 -84
- package/src/cli/start.ts +3 -1
- package/src/client/chunk-fold.ts +19 -6
- package/src/client/react-tier.ts +3 -2
- package/src/client/reference-stub.ts +21 -2
- package/src/compat/actions/client-plugin.ts +4 -2
- package/src/compat/actions/config.ts +6 -5
- package/src/compat/actions/extensions.ts +2 -3
- package/src/compat/aliases.ts +8 -1
- package/src/compat/bundler/config.ts +88 -0
- package/src/compat/bundler/optimize-package-imports.ts +86 -26
- package/src/compat/bundler/relay-transform.ts +15 -3
- package/src/compat/cache-control.ts +16 -8
- package/src/compat/css/modules.ts +18 -5
- package/src/compat/lifecycle/error-funnel.ts +1 -1
- package/src/compat/lifecycle/instrumentation.ts +117 -24
- package/src/compat/lifecycle/testmode.ts +3 -2
- package/src/compat/next/config-loader.ts +137 -13
- package/src/compat/next/font/runtime.ts +22 -2
- package/src/compat/next/og.ts +3 -3
- package/src/compat/next/usage.ts +3 -2
- package/src/compat/pages/api.ts +83 -14
- package/src/compat/pages/router.ts +30 -14
- package/src/compat/register/bundler.ts +3 -1
- package/src/compat/register/middleware.ts +1 -1
- package/src/compat/register/otel.ts +5 -9
- package/src/compat/register/render.ts +3 -1
- package/src/compat/register/use-cache.ts +3 -1
- package/src/compat/release.ts +46 -0
- package/src/compat/segment/serve.ts +1 -1
- package/src/compat/validation/validate.ts +10 -7
- package/src/config.ts +51 -7
- package/src/css/assets.ts +213 -0
- package/src/css/build.ts +174 -238
- package/src/dev/server.ts +27 -8
- package/src/extensions.ts +4 -0
- package/src/render/hooks.ts +13 -0
- package/src/render/renderer.ts +52 -32
- package/src/request/context.ts +9 -0
- package/src/resolve/dynamic.ts +3 -1
- package/src/resolve/imports.ts +12 -52
- package/src/resolve/package-json.ts +56 -0
- package/src/resolve/scan-facts.ts +65 -0
- package/src/routing/href.ts +10 -3
- package/src/routing/match.ts +287 -0
- package/src/routing/metadata-files.ts +19 -5
- package/src/routing/proxy-config.ts +137 -0
- package/src/routing/proxy.ts +35 -134
- package/src/routing/routes.ts +22 -281
- package/src/runtime/fingerprint.ts +23 -8
- package/src/runtime/load.ts +170 -0
- package/src/runtime/loader.ts +215 -43
- package/src/runtime/module-cache.ts +13 -0
- package/src/runtime/modules.ts +370 -81
- package/src/runtime/prebundle.ts +81 -0
- package/src/runtime/production.ts +391 -0
- package/src/runtime/release-graph.ts +334 -0
- package/src/runtime/vendor-build.ts +724 -13
- package/src/runtime/vendor.ts +16 -3
- package/src/types.ts +2 -0
- package/src/utils/fs.ts +89 -3
|
@@ -0,0 +1,1253 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
rdcProcessId,
|
|
4
|
+
rebaseRdcTagSeq,
|
|
5
|
+
setUseCacheRevalidateSink
|
|
6
|
+
} from "./index-9n2914ww.js";
|
|
7
|
+
import {
|
|
8
|
+
getWorkUnit
|
|
9
|
+
} from "./index-grta8ap3.js";
|
|
10
|
+
|
|
11
|
+
// src/compat/cache/use-cache.ts
|
|
12
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
13
|
+
import { Fragment, h } from "preact";
|
|
14
|
+
import { Suspense as CoreSuspense } from "../../../src/api/suspense.ts";
|
|
15
|
+
|
|
16
|
+
// src/compat/cache/runtime-error.ts
|
|
17
|
+
import {
|
|
18
|
+
isForbiddenError,
|
|
19
|
+
isNotFoundError,
|
|
20
|
+
isRedirectError,
|
|
21
|
+
isUnauthorizedError
|
|
22
|
+
} from "../../../src/api/navigation.ts";
|
|
23
|
+
|
|
24
|
+
// src/compat/validation/prerender-diagnostics.ts
|
|
25
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
26
|
+
import path from "path";
|
|
27
|
+
function diagnoseCacheComponentsPrerender(input) {
|
|
28
|
+
const source = readSource(input.pageFile);
|
|
29
|
+
if (!source)
|
|
30
|
+
return;
|
|
31
|
+
const displayPath = appRelativeDisplayPath(input.appPath, input.pageFile);
|
|
32
|
+
const layouts = layoutChainSources(input.appPath, input.pageFile);
|
|
33
|
+
const privateInUnstable = detectPrivateInUnstableCache(source, displayPath, input.route, input.debugPrerender);
|
|
34
|
+
if (privateInUnstable)
|
|
35
|
+
return privateInUnstable;
|
|
36
|
+
const privateInCache = detectPrivateInUseCache(source, displayPath, input.route, input.debugPrerender);
|
|
37
|
+
if (privateInCache)
|
|
38
|
+
return privateInCache;
|
|
39
|
+
const nestedCache = detectNestedShortCacheLife(source, displayPath, input.route, input.debugPrerender);
|
|
40
|
+
if (nestedCache)
|
|
41
|
+
return nestedCache;
|
|
42
|
+
const useCache = detectUseCacheViolation(source);
|
|
43
|
+
if (useCache) {
|
|
44
|
+
return useCacheBlock(input.route, displayPath, source, useCache, input.debugPrerender);
|
|
45
|
+
}
|
|
46
|
+
const importedUseCache = detectImportedUseCacheViolation(source, input.pageFile, displayPath, input.route, input.debugPrerender);
|
|
47
|
+
if (importedUseCache)
|
|
48
|
+
return importedUseCache;
|
|
49
|
+
const pageHole = detectPageDynamicHole(source, displayPath, input.route, layouts, input.debugPrerender);
|
|
50
|
+
if (pageHole)
|
|
51
|
+
return pageHole;
|
|
52
|
+
const clientSyncIO = detectClientSyncIO(source, input.pageFile, input.appPath, input.route, input.debugPrerender);
|
|
53
|
+
if (clientSyncIO)
|
|
54
|
+
return clientSyncIO;
|
|
55
|
+
const syncRequestApi = detectSyncRequestApi(source, displayPath, input.route, input.debugPrerender);
|
|
56
|
+
if (syncRequestApi)
|
|
57
|
+
return syncRequestApi;
|
|
58
|
+
const analysis = analyzePage(source);
|
|
59
|
+
const suspenseAboveBody = layouts.some(layoutWrapsBodyInSuspense);
|
|
60
|
+
if (analysis.violations.length > 0) {
|
|
61
|
+
return analysis.violations.map((violation) => blockingDynamicBlock(input.route, displayPath, source, violation, input.debugPrerender)).join(`
|
|
62
|
+
`);
|
|
63
|
+
}
|
|
64
|
+
const syncIO = detectSyncIO(source);
|
|
65
|
+
if (syncIO) {
|
|
66
|
+
return syncIOBlock(input.route, displayPath, source, syncIO, input.debugPrerender);
|
|
67
|
+
}
|
|
68
|
+
if (analysis.dynamicViewport && !suspenseAboveBody && !analysis.instantFalse) {
|
|
69
|
+
return viewportBlock(input.route);
|
|
70
|
+
}
|
|
71
|
+
if (analysis.dynamicMetadata && !analysis.hasSuspendedDynamic) {
|
|
72
|
+
return metadataBlock(input.route);
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
function prerenderErrorLine(route) {
|
|
77
|
+
return `Error occurred prerendering page "${route}". Read more: https://nextjs.org/docs/messages/prerender-error`;
|
|
78
|
+
}
|
|
79
|
+
function diagnosticLeadsWithErrorLine(diagnostic) {
|
|
80
|
+
return diagnostic.startsWith('Error occurred prerendering page "');
|
|
81
|
+
}
|
|
82
|
+
function prerenderFailureFooter(route, debugPrerender, omitErrorLine = false) {
|
|
83
|
+
const pagePath = `${route}/page`;
|
|
84
|
+
const summary = debugPrerender ? `> Export encountered errors on 1 path:
|
|
85
|
+
${pagePath}: ${route}` : `Export encountered an error on ${pagePath}: ${route}, exiting the build.`;
|
|
86
|
+
if (omitErrorLine)
|
|
87
|
+
return debugPrerender ? `
|
|
88
|
+
${summary}` : summary;
|
|
89
|
+
const errorLine = prerenderErrorLine(route);
|
|
90
|
+
return debugPrerender ? `${errorLine}
|
|
91
|
+
|
|
92
|
+
${summary}` : `${errorLine}
|
|
93
|
+
${summary}`;
|
|
94
|
+
}
|
|
95
|
+
var BLOCKING_DYNAMIC_WAYS = [
|
|
96
|
+
"Ways to fix this:",
|
|
97
|
+
' - [cache] Cache the data access with `"use cache"`',
|
|
98
|
+
" https://nextjs.org/docs/messages/blocking-prerender-dynamic#cache-the-component-or-data",
|
|
99
|
+
" - [stream] Provide a placeholder with `<Suspense fallback={...}>` around the data access",
|
|
100
|
+
" https://nextjs.org/docs/messages/blocking-prerender-dynamic#wrap-in-or-move-into-suspense",
|
|
101
|
+
" - [cache] If the runtime data is `params` and they're known, prerender them with `generateStaticParams`",
|
|
102
|
+
" https://nextjs.org/docs/messages/blocking-prerender-runtime#for-known-params-prerender",
|
|
103
|
+
" - [block] Set `export const unstable_instant = false` to silence this warning and allow a blocking route",
|
|
104
|
+
" https://nextjs.org/docs/messages/blocking-prerender-dynamic#allow-blocking-route"
|
|
105
|
+
].join(`
|
|
106
|
+
`);
|
|
107
|
+
function blockingDynamicIntro(route) {
|
|
108
|
+
return `Error: Route "${route}": Next.js encountered uncached or runtime data during prerendering.
|
|
109
|
+
|
|
110
|
+
` + "`fetch(...)`, `cookies()`, `headers()`, `params`, `searchParams`, or `connection()` accessed outside of `<Suspense>` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.\n\n" + BLOCKING_DYNAMIC_WAYS;
|
|
111
|
+
}
|
|
112
|
+
function debugTrailer(route) {
|
|
113
|
+
return `To debug the issue, start the app in development mode by running \`next dev\`, then open "${route}" in your browser to investigate the error.`;
|
|
114
|
+
}
|
|
115
|
+
function minifiedTrailer(route) {
|
|
116
|
+
return `To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
|
117
|
+
` + ` - Start the app in development mode by running \`next dev\`, then open "${route}" in your browser to investigate the error.
|
|
118
|
+
` + " - Rerun the production build with `next build --debug-prerender` to generate better stack traces.";
|
|
119
|
+
}
|
|
120
|
+
function metadataBlock(route) {
|
|
121
|
+
return `Route "${route}": Next.js encountered uncached or runtime data in \`generateMetadata()\`.
|
|
122
|
+
|
|
123
|
+
` + `This route's metadata is blocked, but the rest of its content can be prerendered.
|
|
124
|
+
|
|
125
|
+
` + `Ways to fix this:
|
|
126
|
+
` + " - [static] Use a static metadata export instead of `generateMetadata()`\n" + ` https://nextjs.org/docs/messages/blocking-prerender-metadata-runtime#use-static-metadata
|
|
127
|
+
` + ' - [cache] Cache the metadata with `"use cache"` in `generateMetadata()`\n' + ` https://nextjs.org/docs/messages/blocking-prerender-metadata-dynamic#cache-the-metadata
|
|
128
|
+
` + " - [dynamic] Render a marker component that calls `await connection()` inside `<Suspense>` on the page\n" + " https://nextjs.org/docs/messages/blocking-prerender-metadata-dynamic#mark-the-route-as-dynamic";
|
|
129
|
+
}
|
|
130
|
+
function viewportBlock(route) {
|
|
131
|
+
return `Route "${route}": Next.js encountered uncached or runtime data in \`generateViewport()\`.
|
|
132
|
+
|
|
133
|
+
` + `This prevents the page from being prerendered, leading to a slower user experience.
|
|
134
|
+
|
|
135
|
+
` + `Ways to fix this:
|
|
136
|
+
` + " - [static] Use a static viewport export instead of `generateViewport()`\n" + ` https://nextjs.org/docs/messages/blocking-prerender-viewport-runtime#use-static-viewport
|
|
137
|
+
` + ' - [cache] Cache the viewport data with `"use cache"` in `generateViewport()`\n' + ` https://nextjs.org/docs/messages/blocking-prerender-viewport-dynamic#cache-the-viewport-data
|
|
138
|
+
` + " - [block] Set `export const unstable_instant = false` to silence this warning and allow a blocking route\n" + " https://nextjs.org/docs/messages/blocking-prerender-viewport-dynamic#allow-blocking-route";
|
|
139
|
+
}
|
|
140
|
+
function blockingDynamicBlock(route, displayPath, source, violation, debugPrerender) {
|
|
141
|
+
const parts = [blockingDynamicIntro(route)];
|
|
142
|
+
if (debugPrerender) {
|
|
143
|
+
for (const frame of violation.frames) {
|
|
144
|
+
parts.push(` at ${frame.name} (webpack:///${displayPath}:${frame.line}:${frame.col})`);
|
|
145
|
+
}
|
|
146
|
+
parts.push(codeFrame(source, violation.anchor.line, violation.anchor.col));
|
|
147
|
+
parts.push(debugTrailer(route));
|
|
148
|
+
} else {
|
|
149
|
+
const dist = (count) => Array.from({ length: count }, () => " at r (.next/server/chunks/main.js:1:1)");
|
|
150
|
+
parts.push(...dist(10 + violation.wrapperDepth), " at main (<anonymous>)", " at body (<anonymous>)", " at html (<anonymous>)", ...dist(11));
|
|
151
|
+
parts.push(minifiedTrailer(route));
|
|
152
|
+
}
|
|
153
|
+
return parts.join(`
|
|
154
|
+
`);
|
|
155
|
+
}
|
|
156
|
+
var SYNC_IO_WAYS = {
|
|
157
|
+
"current-time": [
|
|
158
|
+
" - [dynamic] Render at request time by adding a dynamic data access (e.g. `await connection()`) before this call",
|
|
159
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time#generate-on-every-request",
|
|
160
|
+
' - [cache] Prerender and cache the value with `"use cache"`',
|
|
161
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time#cache-the-timestamp",
|
|
162
|
+
' - [client] Render the value on the client with `"use client"`',
|
|
163
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time#render-on-the-client",
|
|
164
|
+
" - [measure] If the value is for telemetry, use a timing API such as `performance.now()`",
|
|
165
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time#for-telemetry-use-a-timing-api"
|
|
166
|
+
].join(`
|
|
167
|
+
`),
|
|
168
|
+
random: [
|
|
169
|
+
" - [dynamic] Render at request time by adding a dynamic data access (e.g. `await connection()`) before this call",
|
|
170
|
+
" https://nextjs.org/docs/messages/blocking-prerender-random#generate-on-every-request",
|
|
171
|
+
' - [cache] Prerender and cache the value with `"use cache"`',
|
|
172
|
+
" https://nextjs.org/docs/messages/blocking-prerender-random#cache-the-random-value",
|
|
173
|
+
' - [client] Render the value on the client with `"use client"`',
|
|
174
|
+
" https://nextjs.org/docs/messages/blocking-prerender-random#render-on-the-client"
|
|
175
|
+
].join(`
|
|
176
|
+
`),
|
|
177
|
+
crypto: [
|
|
178
|
+
" - [dynamic] Render at request time by adding a dynamic data access (e.g. `await connection()`) before this call",
|
|
179
|
+
" https://nextjs.org/docs/messages/blocking-prerender-crypto#generate-on-every-request",
|
|
180
|
+
' - [cache] Prerender and cache the value with `"use cache"`',
|
|
181
|
+
" https://nextjs.org/docs/messages/blocking-prerender-crypto#cache-the-generated-value",
|
|
182
|
+
' - [client] Render the value on the client with `"use client"`',
|
|
183
|
+
" https://nextjs.org/docs/messages/blocking-prerender-crypto#render-on-the-client"
|
|
184
|
+
].join(`
|
|
185
|
+
`)
|
|
186
|
+
};
|
|
187
|
+
var NODE_CRYPTO_LABELS = {
|
|
188
|
+
getRandomValues: "crypto.getRandomValues()",
|
|
189
|
+
randomBytes: "require('node:crypto').randomBytes(size)",
|
|
190
|
+
randomInt: "require('node:crypto').randomInt(min, max)",
|
|
191
|
+
randomUUID: "require('node:crypto').randomUUID()",
|
|
192
|
+
generateKeyPairSync: "require('node:crypto').generateKeyPairSync(...)",
|
|
193
|
+
generateKeySync: "require('node:crypto').generateKeySync(...)",
|
|
194
|
+
generatePrimeSync: "require('node:crypto').generatePrimeSync(...)",
|
|
195
|
+
randomFillSync: "require('node:crypto').randomFillSync(...)"
|
|
196
|
+
};
|
|
197
|
+
function findSyncIOSite(body, nodeCrypto) {
|
|
198
|
+
const sites = [];
|
|
199
|
+
const add = (index, label, family) => sites.push({ index, label, family });
|
|
200
|
+
for (const m of body.matchAll(/\bDate\s*\.\s*(now)\s*\(/g)) {
|
|
201
|
+
add((m.index ?? 0) + m[0].lastIndexOf("now"), "Date.now()", "current-time");
|
|
202
|
+
}
|
|
203
|
+
for (const m of body.matchAll(/\bnew\s+Date\s*\(/g))
|
|
204
|
+
add(m.index ?? 0, "new Date()", "current-time");
|
|
205
|
+
for (const m of body.matchAll(/(?<![.\w$])Date\s*\(/g)) {
|
|
206
|
+
const before = body.slice(0, m.index ?? 0);
|
|
207
|
+
if (/\bnew\s*$/.test(before))
|
|
208
|
+
continue;
|
|
209
|
+
add(m.index ?? 0, "Date()", "current-time");
|
|
210
|
+
}
|
|
211
|
+
for (const m of body.matchAll(/\bMath\s*\.\s*(random)\s*\(/g)) {
|
|
212
|
+
add((m.index ?? 0) + m[0].lastIndexOf("random"), "Math.random()", "random");
|
|
213
|
+
}
|
|
214
|
+
const cryptoMembers = Object.keys(NODE_CRYPTO_LABELS).join("|");
|
|
215
|
+
for (const m of body.matchAll(new RegExp(`\\bcrypto\\s*\\.\\s*(${cryptoMembers})\\s*\\(`, "g"))) {
|
|
216
|
+
const member = m[1];
|
|
217
|
+
if (nodeCrypto) {
|
|
218
|
+
const family = member === "getRandomValues" ? "crypto" : "random";
|
|
219
|
+
add(m.index ?? 0, NODE_CRYPTO_LABELS[member], family);
|
|
220
|
+
} else if (member === "getRandomValues" || member === "randomUUID") {
|
|
221
|
+
add((m.index ?? 0) + m[0].lastIndexOf(member), member === "getRandomValues" ? "crypto.getRandomValues()" : "crypto.randomUUID()", "crypto");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
sites.sort((a, b) => a.index - b.index);
|
|
225
|
+
return sites[0];
|
|
226
|
+
}
|
|
227
|
+
function dynamicAccessBefore(body, index) {
|
|
228
|
+
const before = body.slice(0, index);
|
|
229
|
+
return /\bawait\s+(?:connection|cookies|headers)\s*\(/.test(before);
|
|
230
|
+
}
|
|
231
|
+
function hasUseCachePrologue(body) {
|
|
232
|
+
return /^\s*(['"])use cache(?:\s*:\s*[\w-]+)?\1/.test(body);
|
|
233
|
+
}
|
|
234
|
+
function hasPrivateCachePrologue(body) {
|
|
235
|
+
return /^\s*(['"])use cache\s*:\s*private\1/.test(body);
|
|
236
|
+
}
|
|
237
|
+
function hasSharedCachePrologue(body) {
|
|
238
|
+
return hasUseCachePrologue(body) && !hasPrivateCachePrologue(body);
|
|
239
|
+
}
|
|
240
|
+
function shortCacheLifeKind(body) {
|
|
241
|
+
const call = /\bcacheLife\s*\(\s*\{([^}]*)\}\s*\)/.exec(body);
|
|
242
|
+
if (!call)
|
|
243
|
+
return;
|
|
244
|
+
const options = call[1];
|
|
245
|
+
const expire = /\bexpire\s*:\s*(\d+)/.exec(options);
|
|
246
|
+
if (expire && Number(expire[1]) < 300)
|
|
247
|
+
return "expire";
|
|
248
|
+
const revalidate = /\brevalidate\s*:\s*(\d+)/.exec(options);
|
|
249
|
+
if (revalidate && Number(revalidate[1]) === 0)
|
|
250
|
+
return "revalidate";
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
function detectSyncIO(source) {
|
|
254
|
+
if (/^\s*(['"])use client\1/.test(source))
|
|
255
|
+
return;
|
|
256
|
+
const functions = collectFunctions(source);
|
|
257
|
+
const byName = new Map(functions.map((fn) => [fn.name, fn]));
|
|
258
|
+
const page = byName.get("Page") ?? functions.find((fn) => isComponentName(fn.name));
|
|
259
|
+
if (!page)
|
|
260
|
+
return;
|
|
261
|
+
const nodeCrypto = /['"]node:crypto['"]/.test(source);
|
|
262
|
+
for (const fn of functions) {
|
|
263
|
+
if (fn === page)
|
|
264
|
+
continue;
|
|
265
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
266
|
+
if (hasUseCachePrologue(body))
|
|
267
|
+
continue;
|
|
268
|
+
const site = findSyncIOSite(body, nodeCrypto);
|
|
269
|
+
if (!site || dynamicAccessBefore(body, site.index))
|
|
270
|
+
continue;
|
|
271
|
+
const anchorIndex = fn.bodyStart + site.index;
|
|
272
|
+
const frames = [frameAt(source, anchorIndex, fn.name)];
|
|
273
|
+
let component = fn;
|
|
274
|
+
if (!isComponentName(fn.name)) {
|
|
275
|
+
const caller = functions.find((candidate) => {
|
|
276
|
+
if (!isComponentName(candidate.name))
|
|
277
|
+
return false;
|
|
278
|
+
const callerBody2 = source.slice(candidate.bodyStart, candidate.bodyEnd);
|
|
279
|
+
return new RegExp(`\\b${fn.name}\\s*\\(`).test(callerBody2);
|
|
280
|
+
});
|
|
281
|
+
if (!caller)
|
|
282
|
+
continue;
|
|
283
|
+
const callerBody = source.slice(caller.bodyStart, caller.bodyEnd);
|
|
284
|
+
const callsite = new RegExp(`\\b${fn.name}\\s*\\(`).exec(callerBody);
|
|
285
|
+
frames.push(frameAt(source, caller.bodyStart + (callsite?.index ?? 0), caller.name));
|
|
286
|
+
component = caller;
|
|
287
|
+
}
|
|
288
|
+
const pageBody = source.slice(page.bodyStart, page.bodyEnd);
|
|
289
|
+
const usage = new RegExp(`<${component.name}\\b`).exec(pageBody);
|
|
290
|
+
if (usage)
|
|
291
|
+
frames.push(frameAt(source, page.bodyStart + usage.index, page.name));
|
|
292
|
+
return { label: site.label, family: site.family, frames, anchor: frames[0] };
|
|
293
|
+
}
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
var CLIENT_CURRENT_TIME_WAYS = [
|
|
297
|
+
" - [stream] Wrap the Client Component in `<Suspense fallback={...}>`",
|
|
298
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time-client#wrap-in-or-move-into-suspense",
|
|
299
|
+
" - [defer] Move the read into a `useEffect` or event handler",
|
|
300
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time-client#move-into-effect-or-event-handler",
|
|
301
|
+
" - [measure] If the value is for telemetry, use a timing API such as `performance.now()`",
|
|
302
|
+
" https://nextjs.org/docs/messages/blocking-prerender-current-time-client#for-telemetry-use-a-timing-api"
|
|
303
|
+
].join(`
|
|
304
|
+
`);
|
|
305
|
+
function detectClientSyncIO(source, pageFile, appPath, route, debugPrerender) {
|
|
306
|
+
const functions = collectFunctions(source);
|
|
307
|
+
const page = functions.find((fn) => fn.name === "Page") ?? functions.find((fn) => isComponentName(fn.name));
|
|
308
|
+
if (!page)
|
|
309
|
+
return;
|
|
310
|
+
const pageBody = source.slice(page.bodyStart, page.bodyEnd);
|
|
311
|
+
for (const imp of source.matchAll(/import\s+(?:([\w$]+)\s*,?\s*)?(?:\{([^}]*)\})?\s*from\s*(['"])([^'"]+)\3/g)) {
|
|
312
|
+
const specifier = imp[4];
|
|
313
|
+
const names = [];
|
|
314
|
+
if (imp[1])
|
|
315
|
+
names.push(imp[1].trim());
|
|
316
|
+
if (imp[2])
|
|
317
|
+
for (const part of imp[2].split(",")) {
|
|
318
|
+
const local = part.split(/\bas\b/).pop().trim();
|
|
319
|
+
if (local)
|
|
320
|
+
names.push(local);
|
|
321
|
+
}
|
|
322
|
+
for (const name of names) {
|
|
323
|
+
if (!isComponentName(name))
|
|
324
|
+
continue;
|
|
325
|
+
const usage = new RegExp(`<${name}\\b`).exec(pageBody);
|
|
326
|
+
if (!usage || insideSuspense(pageBody, usage.index))
|
|
327
|
+
continue;
|
|
328
|
+
const moduleFile = resolveModule(pageFile, specifier);
|
|
329
|
+
if (!moduleFile)
|
|
330
|
+
continue;
|
|
331
|
+
const clientSource = readSource(moduleFile);
|
|
332
|
+
if (!clientSource || !/^\s*(['"])use client\1/.test(clientSource))
|
|
333
|
+
continue;
|
|
334
|
+
const fn = collectFunctions(clientSource).find((candidate) => candidate.name === name);
|
|
335
|
+
if (!fn)
|
|
336
|
+
continue;
|
|
337
|
+
const site = renderTimeSyncIO(clientSource, fn);
|
|
338
|
+
if (!site)
|
|
339
|
+
continue;
|
|
340
|
+
const clientDisplay = appRelativeDisplayPath(appPath, moduleFile);
|
|
341
|
+
const pageDisplay = appRelativeDisplayPath(appPath, pageFile);
|
|
342
|
+
const clientFrame = frameAt(clientSource, fn.bodyStart + site.index, name);
|
|
343
|
+
const pageFrame = frameAt(source, page.bodyStart + usage.index, page.name);
|
|
344
|
+
const intro = `Error: Route "${route}": Next.js encountered the unstable value \`${site.label}\` in a Client Component.
|
|
345
|
+
|
|
346
|
+
` + `This value would be evaluated during the prerender, instead of recomputed on each visit.
|
|
347
|
+
|
|
348
|
+
` + `Ways to fix this:
|
|
349
|
+
` + CLIENT_CURRENT_TIME_WAYS;
|
|
350
|
+
if (debugPrerender) {
|
|
351
|
+
return [
|
|
352
|
+
intro,
|
|
353
|
+
` at ${clientFrame.name} (webpack:///${clientDisplay}:${clientFrame.line}:${clientFrame.col})`,
|
|
354
|
+
` at ${pageFrame.name} (webpack:///${pageDisplay}:${pageFrame.line}:${pageFrame.col})`,
|
|
355
|
+
codeFrame(clientSource, clientFrame.line, clientFrame.col),
|
|
356
|
+
debugTrailer(route)
|
|
357
|
+
].join(`
|
|
358
|
+
`);
|
|
359
|
+
}
|
|
360
|
+
return [intro, " at r (.next/server/chunks/main.js:1:1)", minifiedTrailer(route)].join(`
|
|
361
|
+
`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
function renderTimeSyncIO(source, fn) {
|
|
367
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
368
|
+
const site = findSyncIOSite(body, /['"]node:crypto['"]/.test(source));
|
|
369
|
+
if (site?.family !== "current-time")
|
|
370
|
+
return;
|
|
371
|
+
const before = body.slice(0, site.index);
|
|
372
|
+
const depth = (before.match(/\{/g)?.length ?? 0) - (before.match(/\}/g)?.length ?? 0);
|
|
373
|
+
return depth > 0 ? undefined : site;
|
|
374
|
+
}
|
|
375
|
+
function syncIOBlock(route, displayPath, source, finding, debugPrerender) {
|
|
376
|
+
const parts = [
|
|
377
|
+
`Error: Route "${route}": Next.js encountered the unstable value \`${finding.label}\` while prerendering.
|
|
378
|
+
|
|
379
|
+
` + `This value can change between renders, so it must be either prerendered or computed later.
|
|
380
|
+
|
|
381
|
+
` + `Ways to fix this:
|
|
382
|
+
` + SYNC_IO_WAYS[finding.family]
|
|
383
|
+
];
|
|
384
|
+
if (debugPrerender) {
|
|
385
|
+
for (const frame of finding.frames) {
|
|
386
|
+
parts.push(` at ${frame.name} (webpack:///${displayPath}:${frame.line}:${frame.col})`);
|
|
387
|
+
}
|
|
388
|
+
parts.push(codeFrame(source, finding.anchor.line, finding.anchor.col));
|
|
389
|
+
parts.push(debugTrailer(route));
|
|
390
|
+
} else {
|
|
391
|
+
parts.push(" at r (.next/server/chunks/main.js:1:1)");
|
|
392
|
+
parts.push(minifiedTrailer(route));
|
|
393
|
+
}
|
|
394
|
+
return parts.join(`
|
|
395
|
+
`);
|
|
396
|
+
}
|
|
397
|
+
function detectSyncRequestApi(source, displayPath, route, debugPrerender) {
|
|
398
|
+
const apis = "cookies|headers|draftMode";
|
|
399
|
+
const pattern = new RegExp(`\\(?\\s*\\b(${apis})\\s*\\(\\s*\\)(?:\\s+as\\s+[\\w<>[\\]|]+)?\\s*\\)?\\s*\\.\\s*(\\w+)\\s*\\(`, "g");
|
|
400
|
+
for (const fn of collectFunctions(source)) {
|
|
401
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
402
|
+
if (hasUseCachePrologue(body))
|
|
403
|
+
continue;
|
|
404
|
+
for (const match of body.matchAll(pattern)) {
|
|
405
|
+
const index = match.index ?? 0;
|
|
406
|
+
if (/\bawait\s*\(?\s*$/.test(body.slice(0, index)))
|
|
407
|
+
continue;
|
|
408
|
+
if (dynamicAccessBefore(body, index))
|
|
409
|
+
continue;
|
|
410
|
+
const api = match[1];
|
|
411
|
+
const member = match[2];
|
|
412
|
+
const frame = frameAt(source, fn.bodyStart + index + match[0].lastIndexOf(member), fn.name);
|
|
413
|
+
const message = `TypeError: (0 , ${debugPrerender ? "_headers" : "e"}.${api})(...).${member} is not a function`;
|
|
414
|
+
if (debugPrerender) {
|
|
415
|
+
return [
|
|
416
|
+
prerenderErrorLine(route),
|
|
417
|
+
message,
|
|
418
|
+
` at ${frame.name} (webpack:///${displayPath}:${frame.line}:${frame.col})`,
|
|
419
|
+
codeFrame(source, frame.line, frame.col) + digestTrailer()
|
|
420
|
+
].join(`
|
|
421
|
+
`);
|
|
422
|
+
}
|
|
423
|
+
return [
|
|
424
|
+
prerenderErrorLine(route),
|
|
425
|
+
message,
|
|
426
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
427
|
+
` at ${frame.name} (<anonymous>)${digestTrailer()}`
|
|
428
|
+
].join(`
|
|
429
|
+
`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
function useCacheMessage(route, api) {
|
|
435
|
+
const seeMore = "See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache";
|
|
436
|
+
switch (api) {
|
|
437
|
+
case "cookies":
|
|
438
|
+
case "headers":
|
|
439
|
+
return `Error: Route ${route} used \`${api}()\` inside "use cache". ` + "Accessing Dynamic data sources inside a cache scope is not supported. " + `If you need this data inside a cached function use \`${api}()\` outside of the cached function and pass the required dynamic data in as an argument. ` + seeMore;
|
|
440
|
+
case "connection":
|
|
441
|
+
return `Error: Route ${route} used \`connection()\` inside "use cache". ` + "The `connection()` function is used to indicate the subsequent code must only run when there is an actual request, but caches must be able to be produced before a request, so this function is not allowed in this scope. " + seeMore;
|
|
442
|
+
case "draftMode":
|
|
443
|
+
return `Error: Route ${route} used "draftMode().enable()" inside "use cache". ` + "The enabled status of `draftMode()` can be read in caches but you must not enable or disable `draftMode()` inside a cache. " + seeMore;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function detectUseCacheViolation(source) {
|
|
447
|
+
const functions = collectFunctions(source);
|
|
448
|
+
const byName = new Map(functions.map((fn) => [fn.name, fn]));
|
|
449
|
+
const page = byName.get("Page") ?? functions.find((fn) => isComponentName(fn.name));
|
|
450
|
+
if (!page)
|
|
451
|
+
return;
|
|
452
|
+
for (const fn of functions) {
|
|
453
|
+
if (fn === page)
|
|
454
|
+
continue;
|
|
455
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
456
|
+
if (!hasUseCachePrologue(body))
|
|
457
|
+
continue;
|
|
458
|
+
if (/^\s*(['"])use cache\s*:\s*private\1/.test(body))
|
|
459
|
+
continue;
|
|
460
|
+
let api;
|
|
461
|
+
let anchorIndex;
|
|
462
|
+
const enable = /draftMode\s*\(\s*\)\s*\)?\s*\.\s*(enable)\s*\(/.exec(body);
|
|
463
|
+
if (enable) {
|
|
464
|
+
api = "draftMode";
|
|
465
|
+
anchorIndex = enable.index + enable[0].lastIndexOf("enable");
|
|
466
|
+
} else {
|
|
467
|
+
const request = /\bawait\s+(cookies|headers|connection)\s*(\()/.exec(body);
|
|
468
|
+
if (request) {
|
|
469
|
+
api = request[1];
|
|
470
|
+
anchorIndex = request.index + request[0].length - 1;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (api === undefined || anchorIndex === undefined)
|
|
474
|
+
continue;
|
|
475
|
+
const frames = [frameAt(source, fn.bodyStart + anchorIndex, fn.name)];
|
|
476
|
+
const pageBody = source.slice(page.bodyStart, page.bodyEnd);
|
|
477
|
+
const usage = new RegExp(`<${fn.name}\\b`).exec(pageBody);
|
|
478
|
+
if (usage)
|
|
479
|
+
frames.push(frameAt(source, page.bodyStart + usage.index, page.name));
|
|
480
|
+
return { api, frames, anchor: frames[0] };
|
|
481
|
+
}
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
function useCacheBlock(route, displayPath, source, finding, debugPrerender) {
|
|
485
|
+
const parts = [useCacheMessage(route, finding.api)];
|
|
486
|
+
if (debugPrerender) {
|
|
487
|
+
for (const frame of finding.frames) {
|
|
488
|
+
parts.push(` at ${frame.name} (webpack:///${displayPath}:${frame.line}:${frame.col})`);
|
|
489
|
+
}
|
|
490
|
+
parts.push(codeFrame(source, finding.anchor.line, finding.anchor.col));
|
|
491
|
+
parts.push(debugTrailer(route));
|
|
492
|
+
} else {
|
|
493
|
+
const count = finding.api === "draftMode" ? 1 : 2;
|
|
494
|
+
for (let i = 0;i < count; i++)
|
|
495
|
+
parts.push(" at r (.next/server/chunks/main.js:1:1)");
|
|
496
|
+
parts.push(minifiedTrailer(route));
|
|
497
|
+
}
|
|
498
|
+
return parts.join(`
|
|
499
|
+
`);
|
|
500
|
+
}
|
|
501
|
+
function digestTrailer() {
|
|
502
|
+
return ` {
|
|
503
|
+
digest: '3491756801'
|
|
504
|
+
}`;
|
|
505
|
+
}
|
|
506
|
+
var PRIVATE_IN_USE_CACHE_MESSAGE = 'Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private".';
|
|
507
|
+
function detectPrivateInUseCache(source, displayPath, route, debugPrerender) {
|
|
508
|
+
const functions = collectFunctions(source);
|
|
509
|
+
const privateFn = functions.find((fn) => hasPrivateCachePrologue(source.slice(fn.bodyStart, fn.bodyEnd)));
|
|
510
|
+
if (!privateFn)
|
|
511
|
+
return;
|
|
512
|
+
const parent = functions.find((fn) => fn !== privateFn && hasSharedCachePrologue(source.slice(fn.bodyStart, fn.bodyEnd)) && new RegExp(`<${privateFn.name}\\b`).test(source.slice(fn.bodyStart, fn.bodyEnd)));
|
|
513
|
+
if (!parent)
|
|
514
|
+
return;
|
|
515
|
+
if (debugPrerender) {
|
|
516
|
+
const frame = frameAt(source, privateFn.declIndex, privateFn.name);
|
|
517
|
+
return [
|
|
518
|
+
PRIVATE_IN_USE_CACHE_MESSAGE,
|
|
519
|
+
` at ${frame.name} (webpack:///${displayPath}:${frame.line}:${frame.col})`,
|
|
520
|
+
codeFrame(source, frame.line, frame.col) + digestTrailer(),
|
|
521
|
+
debugTrailer(route)
|
|
522
|
+
].join(`
|
|
523
|
+
`);
|
|
524
|
+
}
|
|
525
|
+
const loggedError = [
|
|
526
|
+
PRIVATE_IN_USE_CACHE_MESSAGE,
|
|
527
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
528
|
+
` at ${privateFn.name} (<anonymous>)${digestTrailer()}`
|
|
529
|
+
].join(`
|
|
530
|
+
`);
|
|
531
|
+
return [`\u2A2F ${loggedError}`, loggedError, minifiedTrailer(route)].join(`
|
|
532
|
+
`);
|
|
533
|
+
}
|
|
534
|
+
function detectPrivateInUnstableCache(source, displayPath, route, debugPrerender) {
|
|
535
|
+
const decl = /\bconst\s+(\w+)\s*=\s*unstable_cache\s*\(\s*/.exec(source);
|
|
536
|
+
if (!decl)
|
|
537
|
+
return;
|
|
538
|
+
const callbackIndex = decl.index + decl[0].length;
|
|
539
|
+
const callbackBody = source.slice(callbackIndex, callbackIndex + 400);
|
|
540
|
+
if (!/(['"])use cache\s*:\s*private\1/.test(callbackBody))
|
|
541
|
+
return;
|
|
542
|
+
const cacheName = decl[1];
|
|
543
|
+
const message = 'Error: "use cache: private" must not be used within `unstable_cache()`.';
|
|
544
|
+
if (!debugPrerender) {
|
|
545
|
+
return [
|
|
546
|
+
message,
|
|
547
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
548
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
549
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
550
|
+
minifiedTrailer(route)
|
|
551
|
+
].join(`
|
|
552
|
+
`);
|
|
553
|
+
}
|
|
554
|
+
const frames = [frameAt(source, callbackIndex, "<unknown>")];
|
|
555
|
+
const functions = collectFunctions(source);
|
|
556
|
+
for (const fn of functions) {
|
|
557
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
558
|
+
const call = new RegExp(`\\bawait\\s+${cacheName}\\s*\\(`).exec(body);
|
|
559
|
+
if (call) {
|
|
560
|
+
frames.push(frameAt(source, fn.bodyStart + call.index, `async ${fn.name}`));
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
const anchor = frames[0];
|
|
565
|
+
return [
|
|
566
|
+
message,
|
|
567
|
+
...frames.map((f) => ` at ${f.name} (webpack:///${displayPath}:${f.line}:${f.col})`),
|
|
568
|
+
codeFrame(source, anchor.line, anchor.col),
|
|
569
|
+
debugTrailer(route)
|
|
570
|
+
].join(`
|
|
571
|
+
`);
|
|
572
|
+
}
|
|
573
|
+
function detectNestedShortCacheLife(source, displayPath, route, debugPrerender) {
|
|
574
|
+
const functions = collectFunctions(source);
|
|
575
|
+
const inner = functions.find((fn) => {
|
|
576
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
577
|
+
return hasSharedCachePrologue(body) && shortCacheLifeKind(body) !== undefined;
|
|
578
|
+
});
|
|
579
|
+
if (!inner)
|
|
580
|
+
return;
|
|
581
|
+
const kind = shortCacheLifeKind(source.slice(inner.bodyStart, inner.bodyEnd));
|
|
582
|
+
const outer = functions.find((fn) => {
|
|
583
|
+
if (fn === inner)
|
|
584
|
+
return false;
|
|
585
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
586
|
+
return hasSharedCachePrologue(body) && !/\bcacheLife\s*\(/.test(body) && new RegExp(`\\b${inner.name}\\s*\\(`).test(body);
|
|
587
|
+
});
|
|
588
|
+
if (!outer)
|
|
589
|
+
return;
|
|
590
|
+
const page = functions.find((fn) => new RegExp(`\\bawait\\s+${outer.name}\\s*\\(`).test(source.slice(fn.bodyStart, fn.bodyEnd)));
|
|
591
|
+
if (!page)
|
|
592
|
+
return;
|
|
593
|
+
const message = kind === "expire" ? 'Error: A "use cache" with short `expire` (under 5 minutes) is nested inside another "use cache" that has no explicit `cacheLife`, which is not allowed during prerendering. Add `cacheLife()` to the outer "use cache" to choose whether it should be prerendered (with longer `expire`) or remain dynamic (with short `expire`). Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife' : 'Error: A "use cache" with zero `revalidate` is nested inside another "use cache" that has no explicit `cacheLife`, which is not allowed during prerendering. Add `cacheLife()` to the outer "use cache" to choose whether it should be prerendered (with non-zero `revalidate`) or remain dynamic (with zero `revalidate`). Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife';
|
|
594
|
+
const causeLine = ' [cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.';
|
|
595
|
+
if (!debugPrerender) {
|
|
596
|
+
return [
|
|
597
|
+
message,
|
|
598
|
+
" at r (.next/server/chunks/main.js:1:1) {",
|
|
599
|
+
causeLine,
|
|
600
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
601
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
602
|
+
" at r (.next/server/chunks/main.js:1:1)",
|
|
603
|
+
"}",
|
|
604
|
+
minifiedTrailer(route)
|
|
605
|
+
].join(`
|
|
606
|
+
`);
|
|
607
|
+
}
|
|
608
|
+
const pageBody = source.slice(page.bodyStart, page.bodyEnd);
|
|
609
|
+
const awaitCall = new RegExp(`\\bawait\\s+${outer.name}\\s*\\(`).exec(pageBody);
|
|
610
|
+
const pageFrame = frameAt(source, page.bodyStart + awaitCall.index, `async ${page.name}`);
|
|
611
|
+
const innerFrame = frameAt(source, inner.declIndex, inner.name);
|
|
612
|
+
const outerBody = source.slice(outer.bodyStart, outer.bodyEnd);
|
|
613
|
+
const innerCall = new RegExp(`\\b${inner.name}\\s*\\(`).exec(outerBody);
|
|
614
|
+
const outerFrame = frameAt(source, outer.bodyStart + innerCall.index, outer.name);
|
|
615
|
+
return [
|
|
616
|
+
message,
|
|
617
|
+
` at ${pageFrame.name} (webpack:///${displayPath}:${pageFrame.line}:${pageFrame.col})`,
|
|
618
|
+
codeFrame(source, pageFrame.line, pageFrame.col) + " {",
|
|
619
|
+
causeLine,
|
|
620
|
+
` at ${inner.name} (webpack:///${displayPath}:${innerFrame.line}:${innerFrame.col})`,
|
|
621
|
+
` at ${outer.name} (webpack:///${displayPath}:${outerFrame.line}:${outerFrame.col})`,
|
|
622
|
+
` at ${page.name} (<anonymous>)`,
|
|
623
|
+
indentLines(codeFrame(source, innerFrame.line, innerFrame.col), " "),
|
|
624
|
+
"}",
|
|
625
|
+
debugTrailer(route)
|
|
626
|
+
].join(`
|
|
627
|
+
`);
|
|
628
|
+
}
|
|
629
|
+
function indentLines(text, pad) {
|
|
630
|
+
return text.split(`
|
|
631
|
+
`).map((line) => pad + line).join(`
|
|
632
|
+
`);
|
|
633
|
+
}
|
|
634
|
+
function detectImportedUseCacheViolation(source, pageFile, displayPath, route, debugPrerender) {
|
|
635
|
+
const functions = collectFunctions(source);
|
|
636
|
+
const page = functions.find((fn) => fn.name === "Page") ?? functions.find((fn) => isComponentName(fn.name));
|
|
637
|
+
if (!page)
|
|
638
|
+
return;
|
|
639
|
+
const pageBody = source.slice(page.bodyStart, page.bodyEnd);
|
|
640
|
+
for (const imp of source.matchAll(/import\s+(?:([\w$]+)\s*,?\s*)?(?:\{([^}]*)\})?\s*from\s*(['"])([^'"]+)\3/g)) {
|
|
641
|
+
const specifier = imp[4];
|
|
642
|
+
const names = [];
|
|
643
|
+
if (imp[1])
|
|
644
|
+
names.push(imp[1].trim());
|
|
645
|
+
if (imp[2])
|
|
646
|
+
for (const part of imp[2].split(",")) {
|
|
647
|
+
const local = part.split(/\bas\b/).pop().trim();
|
|
648
|
+
if (local)
|
|
649
|
+
names.push(local);
|
|
650
|
+
}
|
|
651
|
+
for (const name of names) {
|
|
652
|
+
if (!isComponentName(name))
|
|
653
|
+
continue;
|
|
654
|
+
const usage = new RegExp(`<${name}\\b`).exec(pageBody);
|
|
655
|
+
if (!usage)
|
|
656
|
+
continue;
|
|
657
|
+
const finding = resolveImportedUseCacheApi(pageFile, specifier, name);
|
|
658
|
+
if (!finding)
|
|
659
|
+
continue;
|
|
660
|
+
const frame = frameAt(source, page.bodyStart + usage.index, page.name);
|
|
661
|
+
return useCacheBlock(route, displayPath, source, { api: finding, frames: [frame], anchor: frame }, debugPrerender);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
function resolveImportedUseCacheApi(pageFile, specifier, name) {
|
|
667
|
+
const moduleFile = resolveModule(pageFile, specifier);
|
|
668
|
+
if (!moduleFile)
|
|
669
|
+
return;
|
|
670
|
+
const moduleSource = readSource(moduleFile);
|
|
671
|
+
if (!moduleSource)
|
|
672
|
+
return;
|
|
673
|
+
const fn = collectFunctions(moduleSource).find((candidate) => candidate.name === name);
|
|
674
|
+
if (!fn)
|
|
675
|
+
return;
|
|
676
|
+
const body = moduleSource.slice(fn.bodyStart, fn.bodyEnd);
|
|
677
|
+
if (!hasUseCachePrologue(body) || hasPrivateCachePrologue(body))
|
|
678
|
+
return;
|
|
679
|
+
if (/draftMode\s*\(\s*\)\s*\)?\s*\.\s*enable\s*\(/.test(body))
|
|
680
|
+
return "draftMode";
|
|
681
|
+
const request = /\bawait\s+(cookies|headers|connection)\s*\(/.exec(body);
|
|
682
|
+
return request ? request[1] : undefined;
|
|
683
|
+
}
|
|
684
|
+
function resolveModule(fromFile, specifier) {
|
|
685
|
+
const exts = ["tsx", "ts", "jsx", "js", "mjs", "cjs"];
|
|
686
|
+
const tryFile = (base) => {
|
|
687
|
+
if (existsSync(base) && !isDirectory(base))
|
|
688
|
+
return base;
|
|
689
|
+
for (const ext of exts)
|
|
690
|
+
if (existsSync(`${base}.${ext}`))
|
|
691
|
+
return `${base}.${ext}`;
|
|
692
|
+
for (const ext of exts) {
|
|
693
|
+
const index = path.join(base, `index.${ext}`);
|
|
694
|
+
if (existsSync(index))
|
|
695
|
+
return index;
|
|
696
|
+
}
|
|
697
|
+
return;
|
|
698
|
+
};
|
|
699
|
+
if (specifier.startsWith(".")) {
|
|
700
|
+
return tryFile(path.resolve(path.dirname(fromFile), specifier));
|
|
701
|
+
}
|
|
702
|
+
const [scope, sub] = specifier.startsWith("@") ? [specifier.split("/").slice(0, 2).join("/"), specifier.split("/").slice(2).join("/")] : [specifier.split("/")[0], specifier.split("/").slice(1).join("/")];
|
|
703
|
+
let dir = path.dirname(fromFile);
|
|
704
|
+
for (;; ) {
|
|
705
|
+
const pkgDir = path.join(dir, "node_modules", scope);
|
|
706
|
+
if (existsSync(pkgDir)) {
|
|
707
|
+
if (sub)
|
|
708
|
+
return tryFile(path.join(pkgDir, sub));
|
|
709
|
+
const entry = packageEntry(pkgDir);
|
|
710
|
+
if (entry)
|
|
711
|
+
return tryFile(path.join(pkgDir, entry)) ?? tryFile(path.join(pkgDir, "index"));
|
|
712
|
+
return tryFile(path.join(pkgDir, "index"));
|
|
713
|
+
}
|
|
714
|
+
const parent = path.dirname(dir);
|
|
715
|
+
if (parent === dir)
|
|
716
|
+
return;
|
|
717
|
+
dir = parent;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function packageEntry(pkgDir) {
|
|
721
|
+
const source = readSource(path.join(pkgDir, "package.json"));
|
|
722
|
+
if (!source)
|
|
723
|
+
return;
|
|
724
|
+
try {
|
|
725
|
+
const pkg = JSON.parse(source);
|
|
726
|
+
const dot = pkg.exports?.["."];
|
|
727
|
+
if (typeof dot === "string")
|
|
728
|
+
return dot;
|
|
729
|
+
if (dot && typeof dot === "object") {
|
|
730
|
+
const cond = dot;
|
|
731
|
+
for (const key of ["import", "default", "require", "node"]) {
|
|
732
|
+
if (typeof cond[key] === "string")
|
|
733
|
+
return cond[key];
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return pkg.module ?? pkg.main;
|
|
737
|
+
} catch {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
function detectPageDynamicHole(source, displayPath, route, layouts, debugPrerender) {
|
|
742
|
+
if (layouts.some(layoutWrapsChildrenInSuspense))
|
|
743
|
+
return;
|
|
744
|
+
const functions = collectFunctions(source);
|
|
745
|
+
const page = functions.find((fn) => fn.name === "Page") ?? functions.find((fn) => isComponentName(fn.name));
|
|
746
|
+
if (!page)
|
|
747
|
+
return;
|
|
748
|
+
const body = source.slice(page.bodyStart, page.bodyEnd);
|
|
749
|
+
if (!hasSharedCachePrologue(body))
|
|
750
|
+
return;
|
|
751
|
+
const shortCache = shortCacheLifeKind(body) !== undefined;
|
|
752
|
+
const fallbackParams = /\bawait\s+params\b/.test(body) && /\[[^\]]+\]/.test(route) && !/\bgenerateStaticParams\b/.test(source);
|
|
753
|
+
if (!shortCache && !fallbackParams)
|
|
754
|
+
return;
|
|
755
|
+
const anchor = frameAt(source, page.declIndex, page.name);
|
|
756
|
+
const violation = { frames: [anchor], anchor, wrapperDepth: 0 };
|
|
757
|
+
return blockingDynamicBlock(route, displayPath, source, violation, debugPrerender);
|
|
758
|
+
}
|
|
759
|
+
function layoutWrapsChildrenInSuspense(source) {
|
|
760
|
+
const suspense = source.indexOf("<Suspense");
|
|
761
|
+
const children = source.indexOf("{children}");
|
|
762
|
+
return suspense !== -1 && children !== -1 && suspense < children;
|
|
763
|
+
}
|
|
764
|
+
var CODE_FRAME_MAX_WIDTH = 100;
|
|
765
|
+
function clampCodeFrameRow(row) {
|
|
766
|
+
return row.length <= CODE_FRAME_MAX_WIDTH ? row : `${row.slice(0, CODE_FRAME_MAX_WIDTH - 3)}...`;
|
|
767
|
+
}
|
|
768
|
+
function codeFrame(source, line, col) {
|
|
769
|
+
const lines = source.split(`
|
|
770
|
+
`);
|
|
771
|
+
const first = Math.max(1, line - 2);
|
|
772
|
+
const last = Math.min(lines.length, line + 3);
|
|
773
|
+
const width = String(last).length;
|
|
774
|
+
const out = [];
|
|
775
|
+
for (let n = first;n <= last; n += 1) {
|
|
776
|
+
const cursor = n === line ? ">" : " ";
|
|
777
|
+
const text = lines[n - 1] ?? "";
|
|
778
|
+
out.push(clampCodeFrameRow(`${cursor} ${String(n).padStart(width)} |${text ? ` ${text}` : ""}`));
|
|
779
|
+
if (n === line) {
|
|
780
|
+
out.push(`${" ".repeat(width + 2)} | ${" ".repeat(col - 1)}^`);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
return out.join(`
|
|
784
|
+
`);
|
|
785
|
+
}
|
|
786
|
+
var DYNAMIC_APIS = ["cookies", "headers", "connection", "draftMode"];
|
|
787
|
+
function analyzePage(source) {
|
|
788
|
+
const functions = collectFunctions(source);
|
|
789
|
+
const byName = new Map(functions.map((fn) => [fn.name, fn]));
|
|
790
|
+
const instantFalse = /\bexport\s+const\s+unstable_instant\s*=\s*false\b/.test(source);
|
|
791
|
+
const dynamicMetadata = generatorIsDynamic(source, byName.get("generateMetadata"));
|
|
792
|
+
const dynamicViewport = generatorIsDynamic(source, byName.get("generateViewport"));
|
|
793
|
+
const page = byName.get("Page") ?? functions.find((fn) => isComponentName(fn.name));
|
|
794
|
+
const violations = [];
|
|
795
|
+
let hasSuspendedDynamic = false;
|
|
796
|
+
if (page) {
|
|
797
|
+
const body = source.slice(page.bodyStart, page.bodyEnd);
|
|
798
|
+
for (const fn of functions) {
|
|
799
|
+
if (!isComponentName(fn.name) || fn === page)
|
|
800
|
+
continue;
|
|
801
|
+
const usageState = componentDynamicState(source, fn, byName);
|
|
802
|
+
if (usageState === "static")
|
|
803
|
+
continue;
|
|
804
|
+
const usagePattern = new RegExp(`<${fn.name}\\b[^>]*>`, "g");
|
|
805
|
+
for (const usage of body.matchAll(usagePattern)) {
|
|
806
|
+
const usageIndex = page.bodyStart + (usage.index ?? 0);
|
|
807
|
+
if (usageState === "conditional" && /\bcached(?:=\{true\}|\b(?!=))/.test(usage[0])) {
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
if (insideSuspense(body, usage.index ?? 0)) {
|
|
811
|
+
hasSuspendedDynamic = true;
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
violations.push(buildViolation(source, fn, byName, page, usageIndex));
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
return { dynamicMetadata, dynamicViewport, instantFalse, hasSuspendedDynamic, violations };
|
|
819
|
+
}
|
|
820
|
+
function generatorIsDynamic(source, fn) {
|
|
821
|
+
if (!fn)
|
|
822
|
+
return false;
|
|
823
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
824
|
+
if (/(['"])use cache(?:\s*:\s*[\w-]+)?\1/.test(body))
|
|
825
|
+
return false;
|
|
826
|
+
return /\bawait\b/.test(body);
|
|
827
|
+
}
|
|
828
|
+
function componentDynamicState(source, fn, byName) {
|
|
829
|
+
const body = source.slice(fn.bodyStart, fn.bodyEnd);
|
|
830
|
+
if (hasPrivateCachePrologue(body))
|
|
831
|
+
return "dynamic";
|
|
832
|
+
if (hasUseCachePrologue(body))
|
|
833
|
+
return "static";
|
|
834
|
+
const conditional = /\bcached\s*\?/.test(body);
|
|
835
|
+
if (directDynamicAwait(body) !== undefined)
|
|
836
|
+
return "dynamic";
|
|
837
|
+
for (const call of body.matchAll(/\bawait\s+([a-z][\w$]*)\s*\(/g)) {
|
|
838
|
+
const helper = byName.get(call[1]);
|
|
839
|
+
if (helper && directDynamicAwait(source.slice(helper.bodyStart, helper.bodyEnd)) !== undefined) {
|
|
840
|
+
return conditional ? "conditional" : "dynamic";
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
return "static";
|
|
844
|
+
}
|
|
845
|
+
function directDynamicAwait(body) {
|
|
846
|
+
const api = new RegExp(`\\bawait\\s+(?:${DYNAMIC_APIS.join("|")})\\s*(\\()`).exec(body);
|
|
847
|
+
const fetchCall = /\bawait\s+fetch\s*(\()/.exec(body);
|
|
848
|
+
const uncachedFetch = fetchCall && !body.slice(fetchCall.index, fetchCall.index + 300).includes("force-cache") ? fetchCall : null;
|
|
849
|
+
const promise = /\bawait\s+(new\s+Promise)/.exec(body);
|
|
850
|
+
const candidates = [
|
|
851
|
+
...api ? [{ index: api.index + api[0].length - 1, kind: "api" }] : [],
|
|
852
|
+
...uncachedFetch ? [{ index: uncachedFetch.index + uncachedFetch[0].length - 1, kind: "api" }] : [],
|
|
853
|
+
...promise ? [{ index: promise.index + promise[0].indexOf("new"), kind: "promise" }] : []
|
|
854
|
+
];
|
|
855
|
+
candidates.sort((a, b) => a.index - b.index);
|
|
856
|
+
return candidates[0];
|
|
857
|
+
}
|
|
858
|
+
function buildViolation(source, component, byName, page, usageIndex) {
|
|
859
|
+
const frames = [];
|
|
860
|
+
const body = source.slice(component.bodyStart, component.bodyEnd);
|
|
861
|
+
const direct = directDynamicAwait(body);
|
|
862
|
+
const helperCall = [...body.matchAll(/\bawait\s+([a-z][\w$]*)\s*\(/g)].find((call) => {
|
|
863
|
+
const helper = byName.get(call[1]);
|
|
864
|
+
return helper && directDynamicAwait(source.slice(helper.bodyStart, helper.bodyEnd)) !== undefined;
|
|
865
|
+
});
|
|
866
|
+
if (helperCall && !direct) {
|
|
867
|
+
const helper = byName.get(helperCall[1]);
|
|
868
|
+
const helperBody = source.slice(helper.bodyStart, helper.bodyEnd);
|
|
869
|
+
const site = directDynamicAwait(helperBody);
|
|
870
|
+
frames.push(frameAt(source, helper.bodyStart + site.index, helper.name));
|
|
871
|
+
const calleeIndex = component.bodyStart + (helperCall.index ?? 0) + helperCall[0].indexOf(helperCall[1]);
|
|
872
|
+
frames.push(frameAt(source, calleeIndex, component.name));
|
|
873
|
+
} else if (direct?.kind === "api") {
|
|
874
|
+
frames.push(frameAt(source, component.bodyStart + direct.index, component.name));
|
|
875
|
+
} else {
|
|
876
|
+
frames.push(frameAt(source, component.nameIndex, component.name));
|
|
877
|
+
}
|
|
878
|
+
frames.push(frameAt(source, usageIndex, page.name));
|
|
879
|
+
return {
|
|
880
|
+
frames,
|
|
881
|
+
anchor: frames[0],
|
|
882
|
+
wrapperDepth: componentWrapperDepth(source.slice(page.bodyStart, page.bodyEnd), usageIndex - page.bodyStart)
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
function componentWrapperDepth(body, index) {
|
|
886
|
+
let depth = 0;
|
|
887
|
+
for (const tag of body.slice(0, index).matchAll(/<(\/?)([A-Z][\w$.]*)\b([^>]*)>/g)) {
|
|
888
|
+
if (tag[2] === "Suspense")
|
|
889
|
+
continue;
|
|
890
|
+
if (tag[1] === "/")
|
|
891
|
+
depth -= 1;
|
|
892
|
+
else if (!tag[3].trimEnd().endsWith("/"))
|
|
893
|
+
depth += 1;
|
|
894
|
+
}
|
|
895
|
+
return Math.max(0, depth);
|
|
896
|
+
}
|
|
897
|
+
function frameAt(source, index, name) {
|
|
898
|
+
const before = source.slice(0, index);
|
|
899
|
+
const line = before.split(`
|
|
900
|
+
`).length;
|
|
901
|
+
const col = index - before.lastIndexOf(`
|
|
902
|
+
`);
|
|
903
|
+
return { name, line, col };
|
|
904
|
+
}
|
|
905
|
+
function insideSuspense(body, index) {
|
|
906
|
+
const before = body.slice(0, index);
|
|
907
|
+
const opens = (before.match(/<Suspense[\s>]/g) ?? []).length;
|
|
908
|
+
const closes = (before.match(/<\/Suspense>/g) ?? []).length;
|
|
909
|
+
return opens > closes;
|
|
910
|
+
}
|
|
911
|
+
function isComponentName(name) {
|
|
912
|
+
return /^[A-Z]/.test(name) && name !== "Fallback";
|
|
913
|
+
}
|
|
914
|
+
function collectFunctions(source) {
|
|
915
|
+
const out = [];
|
|
916
|
+
const patterns = [
|
|
917
|
+
/(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\([^)]*\)\s*(?::[^{]+)?\{/g,
|
|
918
|
+
/(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s+)?(?:function\s*)?\([^)]*\)\s*(?::[^={]+)?=>?\s*\{/g
|
|
919
|
+
];
|
|
920
|
+
for (const pattern of patterns) {
|
|
921
|
+
for (const match of source.matchAll(pattern)) {
|
|
922
|
+
const name = match[1];
|
|
923
|
+
const matchIndex = match.index ?? 0;
|
|
924
|
+
const nameIndex = matchIndex + match[0].indexOf(name);
|
|
925
|
+
const bodyStart = matchIndex + match[0].length;
|
|
926
|
+
out.push({
|
|
927
|
+
name,
|
|
928
|
+
declIndex: matchIndex,
|
|
929
|
+
nameIndex,
|
|
930
|
+
bodyStart,
|
|
931
|
+
bodyEnd: bodyEndFrom(source, bodyStart)
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return out;
|
|
936
|
+
}
|
|
937
|
+
function bodyEndFrom(source, offset) {
|
|
938
|
+
let depth = 1;
|
|
939
|
+
let quote;
|
|
940
|
+
for (let cursor = offset;cursor < source.length; cursor++) {
|
|
941
|
+
const current = source[cursor];
|
|
942
|
+
if (quote) {
|
|
943
|
+
if (current === "\\")
|
|
944
|
+
cursor++;
|
|
945
|
+
else if (current === quote)
|
|
946
|
+
quote = undefined;
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
if (current === "/" && source[cursor + 1] === "/") {
|
|
950
|
+
const newline = source.indexOf(`
|
|
951
|
+
`, cursor + 2);
|
|
952
|
+
if (newline === -1)
|
|
953
|
+
return source.length;
|
|
954
|
+
cursor = newline;
|
|
955
|
+
continue;
|
|
956
|
+
}
|
|
957
|
+
if (current === "/" && source[cursor + 1] === "*") {
|
|
958
|
+
const end = source.indexOf("*/", cursor + 2);
|
|
959
|
+
if (end === -1)
|
|
960
|
+
return source.length;
|
|
961
|
+
cursor = end + 1;
|
|
962
|
+
continue;
|
|
963
|
+
}
|
|
964
|
+
if (current === '"' || current === "'" || current === "`") {
|
|
965
|
+
quote = current;
|
|
966
|
+
continue;
|
|
967
|
+
}
|
|
968
|
+
if (current === "{")
|
|
969
|
+
depth++;
|
|
970
|
+
else if (current === "}" && --depth === 0)
|
|
971
|
+
return cursor;
|
|
972
|
+
}
|
|
973
|
+
return source.length;
|
|
974
|
+
}
|
|
975
|
+
function layoutChainSources(appPath, pageFile) {
|
|
976
|
+
const sources = [];
|
|
977
|
+
let dir = path.dirname(pageFile);
|
|
978
|
+
while (dir.startsWith(appPath)) {
|
|
979
|
+
for (const ext of ["tsx", "ts", "jsx", "js"]) {
|
|
980
|
+
const candidate = path.join(dir, `layout.${ext}`);
|
|
981
|
+
if (existsSync(candidate)) {
|
|
982
|
+
const source = readSource(candidate);
|
|
983
|
+
if (source)
|
|
984
|
+
sources.push(source);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (dir === appPath)
|
|
988
|
+
break;
|
|
989
|
+
dir = path.dirname(dir);
|
|
990
|
+
}
|
|
991
|
+
return sources;
|
|
992
|
+
}
|
|
993
|
+
function layoutWrapsBodyInSuspense(source) {
|
|
994
|
+
const suspense = source.indexOf("<Suspense");
|
|
995
|
+
const body = source.indexOf("<body");
|
|
996
|
+
return suspense !== -1 && body !== -1 && suspense < body;
|
|
997
|
+
}
|
|
998
|
+
function readSource(file) {
|
|
999
|
+
try {
|
|
1000
|
+
return readFileSync(file, "utf8");
|
|
1001
|
+
} catch {
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
function isDirectory(file) {
|
|
1006
|
+
try {
|
|
1007
|
+
return statSync(file).isDirectory();
|
|
1008
|
+
} catch {
|
|
1009
|
+
return false;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
function appRelativeDisplayPath(appPath, file) {
|
|
1013
|
+
const relative = path.relative(appPath, file).split(path.sep).join("/");
|
|
1014
|
+
return `app/${relative}`;
|
|
1015
|
+
}
|
|
1016
|
+
var RSC_REDACTED_RUNTIME_MESSAGE = "An error occurred in the Server Components render. The specific message is " + "omitted in production builds to avoid leaking sensitive details. A digest " + "property is included on this error instance which may provide additional " + "details about the nature of the error.";
|
|
1017
|
+
|
|
1018
|
+
// src/compat/cache/build-flags.ts
|
|
1019
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
1020
|
+
import path2 from "path";
|
|
1021
|
+
var BUILD_FLAG_GLOBALS = Symbol.for("pnext.compat.buildFlags");
|
|
1022
|
+
function state() {
|
|
1023
|
+
const root = globalThis;
|
|
1024
|
+
return root[BUILD_FLAG_GLOBALS] ??= {};
|
|
1025
|
+
}
|
|
1026
|
+
function flagsFile(outPath) {
|
|
1027
|
+
return path2.join(outPath, "server", "pnext-build-flags.json");
|
|
1028
|
+
}
|
|
1029
|
+
function setBuildFlagsOutPath(outPath) {
|
|
1030
|
+
const current = state();
|
|
1031
|
+
if (current.outPath !== outPath) {
|
|
1032
|
+
current.outPath = outPath;
|
|
1033
|
+
current.flags = undefined;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
function writeBuildFlags(outPath, debugPrerender) {
|
|
1037
|
+
const file = flagsFile(outPath);
|
|
1038
|
+
try {
|
|
1039
|
+
mkdirSync(path2.dirname(file), { recursive: true });
|
|
1040
|
+
writeFileSync(file, `${JSON.stringify({ debugPrerender })}
|
|
1041
|
+
`);
|
|
1042
|
+
} catch {}
|
|
1043
|
+
const current = state();
|
|
1044
|
+
current.outPath = outPath;
|
|
1045
|
+
current.flags = { debugPrerender };
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// src/compat/cache/runtime-error.ts
|
|
1049
|
+
var SHAPED = Symbol.for("pnext.compat.cacheRuntimeErrorShaped");
|
|
1050
|
+
|
|
1051
|
+
// src/compat/cache/use-cache.ts
|
|
1052
|
+
var USE_CACHE_FILL_TIMEOUT = Symbol.for("pnext.compat.useCacheFillTimeout");
|
|
1053
|
+
function fillTimeoutHolder() {
|
|
1054
|
+
const root = globalThis;
|
|
1055
|
+
return root[USE_CACHE_FILL_TIMEOUT] ??= { ms: 50000 };
|
|
1056
|
+
}
|
|
1057
|
+
function setUseCacheFillTimeout(ms) {
|
|
1058
|
+
if (typeof ms === "number" && Number.isFinite(ms) && ms > 0) {
|
|
1059
|
+
fillTimeoutHolder().ms = ms;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
var USE_CACHE_ENTRIES = Symbol.for("pnext.compat.useCacheEntries");
|
|
1063
|
+
var USE_CACHE_SCOPE_STORAGE = Symbol.for("pnext.compat.useCacheScopeStorage");
|
|
1064
|
+
var USE_CACHE_KNOWN_ROOT_PARAMS = Symbol.for("pnext.compat.knownRootParamsByFunctionId");
|
|
1065
|
+
var USE_CACHE_REQUEST_TOKENS = Symbol.for("pnext.compat.useCacheRequestTokens");
|
|
1066
|
+
function useCacheGlobal(key, create) {
|
|
1067
|
+
const state2 = globalThis;
|
|
1068
|
+
const existing = state2[key];
|
|
1069
|
+
if (existing !== undefined)
|
|
1070
|
+
return existing;
|
|
1071
|
+
const value = create();
|
|
1072
|
+
state2[key] = value;
|
|
1073
|
+
return value;
|
|
1074
|
+
}
|
|
1075
|
+
var entries = useCacheGlobal(USE_CACHE_ENTRIES, () => new Map);
|
|
1076
|
+
var scopeStorage = useCacheGlobal(USE_CACHE_SCOPE_STORAGE, () => new AsyncLocalStorage);
|
|
1077
|
+
var requestTokens = useCacheGlobal(USE_CACHE_REQUEST_TOKENS, () => new WeakMap);
|
|
1078
|
+
var USE_CACHE_RDC_CAPTURE = Symbol.for("pnext.compat.useCacheRdcCapture");
|
|
1079
|
+
var USE_CACHE_RDC_RECORDS = Symbol.for("pnext.compat.useCacheRdcRecords");
|
|
1080
|
+
function useCacheRdcRecords() {
|
|
1081
|
+
return useCacheGlobal(USE_CACHE_RDC_RECORDS, () => new Map);
|
|
1082
|
+
}
|
|
1083
|
+
function useCacheRdcCapture() {
|
|
1084
|
+
return globalThis[USE_CACHE_RDC_CAPTURE];
|
|
1085
|
+
}
|
|
1086
|
+
function beginUseCacheRdcCapture() {
|
|
1087
|
+
globalThis[USE_CACHE_RDC_CAPTURE] = new Set;
|
|
1088
|
+
}
|
|
1089
|
+
async function collectUseCacheRdcRecords() {
|
|
1090
|
+
const capture = useCacheRdcCapture();
|
|
1091
|
+
if (!capture)
|
|
1092
|
+
return [];
|
|
1093
|
+
const records = [];
|
|
1094
|
+
for (const key of capture) {
|
|
1095
|
+
const entry = entries.get(key);
|
|
1096
|
+
if (!entry)
|
|
1097
|
+
continue;
|
|
1098
|
+
const value = toRdcValue(await entry.value);
|
|
1099
|
+
if (value === undefined)
|
|
1100
|
+
continue;
|
|
1101
|
+
records.push({
|
|
1102
|
+
key,
|
|
1103
|
+
value,
|
|
1104
|
+
tags: [...entry.tags],
|
|
1105
|
+
storedAt: entry.storedAt,
|
|
1106
|
+
...entry.revalidateSeconds !== undefined ? { revalidateSeconds: entry.revalidateSeconds } : {},
|
|
1107
|
+
...entry.expireSeconds !== undefined ? { expireSeconds: entry.expireSeconds } : {},
|
|
1108
|
+
...entry.staleSeconds !== undefined ? { staleSeconds: entry.staleSeconds } : {},
|
|
1109
|
+
tagSeq: entry.tagSeq,
|
|
1110
|
+
pid: rdcProcessId(),
|
|
1111
|
+
...entry.route !== undefined ? { route: entry.route } : {}
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
return records;
|
|
1115
|
+
}
|
|
1116
|
+
async function collectUseCacheRdcTags() {
|
|
1117
|
+
const capture = useCacheRdcCapture();
|
|
1118
|
+
if (!capture)
|
|
1119
|
+
return [];
|
|
1120
|
+
const tags = new Set;
|
|
1121
|
+
for (const key of capture) {
|
|
1122
|
+
const entry = entries.get(key);
|
|
1123
|
+
if (!entry)
|
|
1124
|
+
continue;
|
|
1125
|
+
await entry.value.catch(() => {
|
|
1126
|
+
return;
|
|
1127
|
+
});
|
|
1128
|
+
for (const tag of entry.tags)
|
|
1129
|
+
tags.add(tag);
|
|
1130
|
+
}
|
|
1131
|
+
return [...tags];
|
|
1132
|
+
}
|
|
1133
|
+
function seedUseCacheRdcRecords(records, route) {
|
|
1134
|
+
for (const record of records) {
|
|
1135
|
+
if (!isUseCacheRdcRecord(record))
|
|
1136
|
+
continue;
|
|
1137
|
+
const tagSeq = rebaseRdcTagSeq(record);
|
|
1138
|
+
const live = entries.get(record.key);
|
|
1139
|
+
if (live !== undefined && live.storedAt > record.storedAt)
|
|
1140
|
+
continue;
|
|
1141
|
+
useCacheRdcRecords().set(record.key, { ...record, tagSeq });
|
|
1142
|
+
entries.set(record.key, {
|
|
1143
|
+
value: Promise.resolve(record.value),
|
|
1144
|
+
storedAt: record.storedAt,
|
|
1145
|
+
tags: [...record.tags],
|
|
1146
|
+
...record.revalidateSeconds !== undefined ? { revalidateSeconds: record.revalidateSeconds } : {},
|
|
1147
|
+
...record.expireSeconds !== undefined ? { expireSeconds: record.expireSeconds } : {},
|
|
1148
|
+
...record.staleSeconds !== undefined ? { staleSeconds: record.staleSeconds } : {},
|
|
1149
|
+
tagSeq,
|
|
1150
|
+
...route !== undefined ? { route } : record.route !== undefined ? { route: record.route } : {}
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
function isUseCacheRdcRecord(value) {
|
|
1155
|
+
if (!value || typeof value !== "object")
|
|
1156
|
+
return false;
|
|
1157
|
+
const record = value;
|
|
1158
|
+
return typeof record.key === "string" && Array.isArray(record.tags) && record.tags.every((tag) => typeof tag === "string") && typeof record.storedAt === "number" && Number.isFinite(record.storedAt) && typeof record.tagSeq === "number" && Number.isInteger(record.tagSeq) && isRdcValue(record.value);
|
|
1159
|
+
}
|
|
1160
|
+
function toRdcValue(value) {
|
|
1161
|
+
if (!isRdcValue(value))
|
|
1162
|
+
return;
|
|
1163
|
+
return JSON.parse(JSON.stringify(value));
|
|
1164
|
+
}
|
|
1165
|
+
function isRdcValue(value, seen = new WeakSet) {
|
|
1166
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
1167
|
+
return true;
|
|
1168
|
+
if (typeof value === "number")
|
|
1169
|
+
return Number.isFinite(value);
|
|
1170
|
+
if (typeof value !== "object" || seen.has(value))
|
|
1171
|
+
return false;
|
|
1172
|
+
if (Array.isArray(value)) {
|
|
1173
|
+
seen.add(value);
|
|
1174
|
+
return value.every((item) => isRdcValue(item, seen));
|
|
1175
|
+
}
|
|
1176
|
+
const prototype = Object.getPrototypeOf(value);
|
|
1177
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
1178
|
+
return false;
|
|
1179
|
+
seen.add(value);
|
|
1180
|
+
return Object.values(value).every((item) => isRdcValue(item, seen));
|
|
1181
|
+
}
|
|
1182
|
+
var knownRootParamsByFunctionId = useCacheGlobal(USE_CACHE_KNOWN_ROOT_PARAMS, () => new Map);
|
|
1183
|
+
var USE_CACHE_ROOT_PARAM_NAMES = Symbol.for("pnext.compat.rootParamNames");
|
|
1184
|
+
function setUseCacheRootParamNames(names) {
|
|
1185
|
+
globalThis[USE_CACHE_ROOT_PARAM_NAMES] = new Set(names);
|
|
1186
|
+
}
|
|
1187
|
+
function recordUseCacheRootParamRead(name) {
|
|
1188
|
+
const scope = scopeStorage.getStore();
|
|
1189
|
+
if (!scope?.functionId)
|
|
1190
|
+
return false;
|
|
1191
|
+
(scope.rootParamsRead ??= new Set).add(name);
|
|
1192
|
+
let known = knownRootParamsByFunctionId.get(scope.functionId);
|
|
1193
|
+
if (!known) {
|
|
1194
|
+
known = new Set;
|
|
1195
|
+
knownRootParamsByFunctionId.set(scope.functionId, known);
|
|
1196
|
+
}
|
|
1197
|
+
known.add(name);
|
|
1198
|
+
return true;
|
|
1199
|
+
}
|
|
1200
|
+
function insideUseCacheProducer() {
|
|
1201
|
+
return scopeStorage.getStore()?.functionId !== undefined;
|
|
1202
|
+
}
|
|
1203
|
+
var USE_CACHE_LIFE = Symbol.for("pnext.compat.useCacheLife");
|
|
1204
|
+
function takeCacheLifeStash() {
|
|
1205
|
+
const unit = getWorkUnit();
|
|
1206
|
+
const compat = unit?.compat;
|
|
1207
|
+
if (!compat)
|
|
1208
|
+
return;
|
|
1209
|
+
const life = compat[USE_CACHE_LIFE];
|
|
1210
|
+
compat[USE_CACHE_LIFE] = undefined;
|
|
1211
|
+
return life;
|
|
1212
|
+
}
|
|
1213
|
+
setUseCacheRevalidateSink((seconds) => {
|
|
1214
|
+
recordUseCacheLife(seconds);
|
|
1215
|
+
});
|
|
1216
|
+
function recordUseCacheTags(tags) {
|
|
1217
|
+
const scope = scopeStorage.getStore();
|
|
1218
|
+
if (!scope)
|
|
1219
|
+
return false;
|
|
1220
|
+
for (const tag of tags)
|
|
1221
|
+
scope.tags.add(tag);
|
|
1222
|
+
return true;
|
|
1223
|
+
}
|
|
1224
|
+
function recordUseCacheLife(life) {
|
|
1225
|
+
const scope = scopeStorage.getStore();
|
|
1226
|
+
if (!scope)
|
|
1227
|
+
return false;
|
|
1228
|
+
const revalidate = typeof life === "number" ? life : life.revalidateSeconds;
|
|
1229
|
+
const expire = typeof life === "number" ? undefined : life.expireSeconds;
|
|
1230
|
+
const stale = typeof life === "number" ? undefined : life.staleSeconds;
|
|
1231
|
+
if (revalidate !== undefined) {
|
|
1232
|
+
scope.revalidateSeconds = scope.revalidateSeconds === undefined ? revalidate : Math.min(scope.revalidateSeconds, revalidate);
|
|
1233
|
+
}
|
|
1234
|
+
if (expire !== undefined) {
|
|
1235
|
+
scope.expireSeconds = scope.expireSeconds === undefined ? expire : Math.min(scope.expireSeconds, expire);
|
|
1236
|
+
}
|
|
1237
|
+
if (stale !== undefined) {
|
|
1238
|
+
scope.staleSeconds = scope.staleSeconds === undefined ? stale : Math.min(scope.staleSeconds, stale);
|
|
1239
|
+
}
|
|
1240
|
+
return true;
|
|
1241
|
+
}
|
|
1242
|
+
var PRIVATE_CACHE_STORE = Symbol.for("pnext.compat.privateCacheStore");
|
|
1243
|
+
var PRIVATE_STORE_BY_REQUEST = Symbol.for("pnext.compat.privateStoreByRequest");
|
|
1244
|
+
var privateStoreByRequest = useCacheGlobal(PRIVATE_STORE_BY_REQUEST, () => new WeakMap);
|
|
1245
|
+
var USE_CACHE_WRAPPER = Symbol.for("pnext.compat.useCacheWrapper");
|
|
1246
|
+
var MEMO_WRAPPED = Symbol.for("pnext.compat.useCacheMemoWrapped");
|
|
1247
|
+
var clientReferenceSymbol = Symbol.for("pnext.clientReference");
|
|
1248
|
+
var dynamicReferenceSymbol = Symbol.for("pnext.dynamic");
|
|
1249
|
+
var paramsScopeSymbol = Symbol.for("pnext.paramsScope");
|
|
1250
|
+
var clientPageComponentSymbol = Symbol.for("pnext.clientPageComponent");
|
|
1251
|
+
var useCacheJoinerPromiseSymbol = Symbol.for("pnext.compat.useCacheJoinerPromise");
|
|
1252
|
+
|
|
1253
|
+
export { setBuildFlagsOutPath, writeBuildFlags, diagnoseCacheComponentsPrerender, diagnosticLeadsWithErrorLine, prerenderFailureFooter, setUseCacheFillTimeout, beginUseCacheRdcCapture, collectUseCacheRdcRecords, collectUseCacheRdcTags, seedUseCacheRdcRecords, setUseCacheRootParamNames, recordUseCacheRootParamRead, insideUseCacheProducer, takeCacheLifeStash, recordUseCacheTags, recordUseCacheLife };
|