@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,696 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
latestPnextVersionRange
|
|
4
|
+
} from "./index-jx7bqvw1.js";
|
|
5
|
+
import {
|
|
6
|
+
pnextOptionalDependencyRange
|
|
7
|
+
} from "./index-20ppawv7.js";
|
|
8
|
+
import"./index-tqn2qnnn.js";
|
|
9
|
+
import {
|
|
10
|
+
bold,
|
|
11
|
+
cyan,
|
|
12
|
+
dim,
|
|
13
|
+
green
|
|
14
|
+
} from "./index-6kp9r0d9.js";
|
|
15
|
+
import {
|
|
16
|
+
__require
|
|
17
|
+
} from "./index-rt9qq1va.js";
|
|
18
|
+
|
|
19
|
+
// src/cli/migrate/run.ts
|
|
20
|
+
import { existsSync as existsSync3 } from "fs";
|
|
21
|
+
import { appendFile, readFile as readFile4, rm, writeFile as writeFile3 } from "fs/promises";
|
|
22
|
+
import path4 from "path";
|
|
23
|
+
|
|
24
|
+
// src/cli/migrate/package-json.ts
|
|
25
|
+
import { readFile, writeFile } from "fs/promises";
|
|
26
|
+
import path from "path";
|
|
27
|
+
var SEPARATORS = new Set(["&&", "||", ";", "|", "&"]);
|
|
28
|
+
var MAPPED_SUBCOMMANDS = new Set(["dev", "build", "start", "typegen"]);
|
|
29
|
+
var DROPPED_FLAGS = new Set(["--turbo", "--turbopack"]);
|
|
30
|
+
function rewriteScript(script) {
|
|
31
|
+
const tokens = script.split(/\s+/).filter(Boolean);
|
|
32
|
+
const reports = [];
|
|
33
|
+
const out = [];
|
|
34
|
+
let commandStart = true;
|
|
35
|
+
let changed = false;
|
|
36
|
+
for (let index = 0;index < tokens.length; index += 1) {
|
|
37
|
+
const token = tokens[index];
|
|
38
|
+
if (SEPARATORS.has(token)) {
|
|
39
|
+
out.push(token);
|
|
40
|
+
commandStart = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (commandStart && /^[A-Za-z_][A-Za-z0-9_]*=/.test(token)) {
|
|
44
|
+
out.push(token);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (!commandStart || token !== "next") {
|
|
48
|
+
out.push(token);
|
|
49
|
+
commandStart = false;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
let end = index + 1;
|
|
53
|
+
while (end < tokens.length && !SEPARATORS.has(tokens[end]))
|
|
54
|
+
end += 1;
|
|
55
|
+
const subcommand = tokens[index + 1];
|
|
56
|
+
const rest = tokens.slice(index + 2, end);
|
|
57
|
+
if (subcommand && MAPPED_SUBCOMMANDS.has(subcommand)) {
|
|
58
|
+
out.push("pnext", subcommand, ...translateFlags(subcommand, rest));
|
|
59
|
+
changed = true;
|
|
60
|
+
} else if (subcommand === "lint") {
|
|
61
|
+
out.push(...tokens.slice(index, end));
|
|
62
|
+
reports.push("`next lint` left as-is \u2014 pnext has no lint command; run eslint directly.");
|
|
63
|
+
} else {
|
|
64
|
+
out.push(...tokens.slice(index, end));
|
|
65
|
+
const command = subcommand ? `next ${subcommand}` : "next";
|
|
66
|
+
reports.push(`\`${command}\` has no pnext equivalent \u2014 left as-is.`);
|
|
67
|
+
}
|
|
68
|
+
index = end - 1;
|
|
69
|
+
commandStart = false;
|
|
70
|
+
}
|
|
71
|
+
return { script: changed ? out.join(" ") : script, reports };
|
|
72
|
+
}
|
|
73
|
+
function translateFlags(subcommand, rest) {
|
|
74
|
+
const out = [];
|
|
75
|
+
for (const flag of rest) {
|
|
76
|
+
if (DROPPED_FLAGS.has(flag))
|
|
77
|
+
continue;
|
|
78
|
+
if (flag === "-p" && (subcommand === "dev" || subcommand === "start")) {
|
|
79
|
+
out.push("--port");
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
out.push(flag);
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
async function migratePackageJson(root, pkg, result, dryRun) {
|
|
87
|
+
const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined;
|
|
88
|
+
if (scripts) {
|
|
89
|
+
const rewritten = [];
|
|
90
|
+
for (const [name, value] of Object.entries(scripts)) {
|
|
91
|
+
if (typeof value !== "string")
|
|
92
|
+
continue;
|
|
93
|
+
const { script, reports } = rewriteScript(value);
|
|
94
|
+
if (script !== value) {
|
|
95
|
+
scripts[name] = script;
|
|
96
|
+
rewritten.push(`${name}: ${value} \u2192 ${script}`);
|
|
97
|
+
}
|
|
98
|
+
for (const detail of reports) {
|
|
99
|
+
result.reports.push({ title: `package.json script "${name}"`, detail });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (rewritten.length > 0) {
|
|
103
|
+
result.edits.push({
|
|
104
|
+
file: "package.json",
|
|
105
|
+
description: `scripts rewritten (${rewritten.length})`,
|
|
106
|
+
details: rewritten
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const dependencies = ensureObject(pkg, "dependencies");
|
|
111
|
+
const devDependencies = ensureObject(pkg, "devDependencies");
|
|
112
|
+
for (const [field, bucket] of [
|
|
113
|
+
["dependencies", dependencies],
|
|
114
|
+
["devDependencies", devDependencies]
|
|
115
|
+
]) {
|
|
116
|
+
if ("next" in bucket) {
|
|
117
|
+
delete bucket.next;
|
|
118
|
+
result.edits.push({
|
|
119
|
+
file: "package.json",
|
|
120
|
+
description: "next removed",
|
|
121
|
+
details: [`next removed from ${field}`]
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!("@wular/pnext" in devDependencies) && !("@wular/pnext" in dependencies)) {
|
|
126
|
+
const versionRange = await latestPnextVersionRange("migrate");
|
|
127
|
+
devDependencies["@wular/pnext"] = versionRange;
|
|
128
|
+
result.edits.push({
|
|
129
|
+
file: "package.json",
|
|
130
|
+
description: "@wular/pnext added",
|
|
131
|
+
details: [`devDependencies: @wular/pnext ${versionRange}`]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const fontRange = pnextOptionalDependencyRange("next-font");
|
|
135
|
+
if (result.googleFontImports.length > 0 && fontRange && !("next-font" in dependencies) && !("next-font" in devDependencies)) {
|
|
136
|
+
dependencies["next-font"] = fontRange;
|
|
137
|
+
result.edits.push({
|
|
138
|
+
file: "package.json",
|
|
139
|
+
description: "next-font added",
|
|
140
|
+
details: [
|
|
141
|
+
`dependencies: next-font ${fontRange} (next/font/google metadata, used by ${result.googleFontImports.length} file${result.googleFontImports.length === 1 ? "" : "s"})`
|
|
142
|
+
]
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (!("preact" in dependencies) && !("preact" in devDependencies)) {
|
|
146
|
+
dependencies.preact = "^10";
|
|
147
|
+
result.edits.push({
|
|
148
|
+
file: "package.json",
|
|
149
|
+
description: "preact added",
|
|
150
|
+
details: ["dependencies: preact ^10 (react/react-dom kept \u2014 compat aliases them)"]
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const leftovers = [...Object.keys(dependencies), ...Object.keys(devDependencies)].filter((name) => name === "eslint-config-next" || name.startsWith("@next/"));
|
|
154
|
+
if (leftovers.length > 0) {
|
|
155
|
+
result.reports.push({
|
|
156
|
+
title: "Next-specific packages still installed",
|
|
157
|
+
detail: "Optional cleanup \u2014 these are unused under pnext. See https://pnext.dev/docs/compat.",
|
|
158
|
+
files: leftovers
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
pruneEmpty(pkg, "dependencies");
|
|
162
|
+
pruneEmpty(pkg, "devDependencies");
|
|
163
|
+
if (!dryRun) {
|
|
164
|
+
await writeFile(path.join(root, "package.json"), `${JSON.stringify(pkg, null, 2)}
|
|
165
|
+
`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async function readPackageJson(root) {
|
|
169
|
+
try {
|
|
170
|
+
const parsed = JSON.parse(await readFile(path.join(root, "package.json"), "utf8"));
|
|
171
|
+
return isObject(parsed) ? parsed : undefined;
|
|
172
|
+
} catch {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function isObject(value) {
|
|
177
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
178
|
+
}
|
|
179
|
+
function ensureObject(pkg, key) {
|
|
180
|
+
if (!isObject(pkg[key]))
|
|
181
|
+
pkg[key] = {};
|
|
182
|
+
return pkg[key];
|
|
183
|
+
}
|
|
184
|
+
function pruneEmpty(pkg, key) {
|
|
185
|
+
const value = pkg[key];
|
|
186
|
+
if (isObject(value) && Object.keys(value).length === 0)
|
|
187
|
+
delete pkg[key];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/cli/migrate/report.ts
|
|
191
|
+
var amber = (value) => process.stdout.isTTY ? `\x1B[38;5;214m${value}\x1B[39m` : value;
|
|
192
|
+
function emptyResult() {
|
|
193
|
+
return { edits: [], reports: [], syncRequestApis: [], googleFontImports: [] };
|
|
194
|
+
}
|
|
195
|
+
function printHeader(root, dryRun) {
|
|
196
|
+
const suffix = dryRun ? "dry run, nothing will be written" : root;
|
|
197
|
+
console.log(`
|
|
198
|
+
\u26A1 ${bold("pnext migrate")} ${dim(`\u2014 ${suffix}`)}`);
|
|
199
|
+
}
|
|
200
|
+
function printResult(result, options) {
|
|
201
|
+
const lines = [];
|
|
202
|
+
lines.push(`
|
|
203
|
+
${bold("Changes")}`);
|
|
204
|
+
if (result.edits.length === 0) {
|
|
205
|
+
lines.push(` ${dim("nothing to change")}`);
|
|
206
|
+
}
|
|
207
|
+
for (const [file, edits] of groupByFile(result.edits)) {
|
|
208
|
+
lines.push(`${green("\u2713")} ${bold(file)} ${dim(`\u2014 ${edits.map((edit) => edit.description).join(", ")}`)}`);
|
|
209
|
+
for (const edit of edits) {
|
|
210
|
+
for (const detail of edit.details ?? [])
|
|
211
|
+
lines.push(` ${dim(detail)}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
lines.push(`
|
|
215
|
+
${bold("Review")}${result.reports.length > 0 ? ` (${result.reports.length})` : ""}`);
|
|
216
|
+
if (result.reports.length === 0) {
|
|
217
|
+
lines.push(` ${dim("nothing flagged")}`);
|
|
218
|
+
}
|
|
219
|
+
for (const item of result.reports) {
|
|
220
|
+
lines.push(`${amber("!")} ${bold(item.title)}`);
|
|
221
|
+
lines.push(` ${dim(item.detail)}`);
|
|
222
|
+
for (const file of item.files ?? [])
|
|
223
|
+
lines.push(` ${dim(`\xB7 ${file}`)}`);
|
|
224
|
+
}
|
|
225
|
+
lines.push(`
|
|
226
|
+
${bold("Next steps")}`);
|
|
227
|
+
lines.push(` 1. Install the new dependencies: ${cyan(options.install)}`);
|
|
228
|
+
lines.push(` 2. Start the app: ${cyan("pnext dev")}`);
|
|
229
|
+
console.log(lines.join(`
|
|
230
|
+
`));
|
|
231
|
+
}
|
|
232
|
+
function groupByFile(edits) {
|
|
233
|
+
const grouped = new Map;
|
|
234
|
+
for (const edit of edits) {
|
|
235
|
+
const bucket = grouped.get(edit.file);
|
|
236
|
+
if (bucket)
|
|
237
|
+
bucket.push(edit);
|
|
238
|
+
else
|
|
239
|
+
grouped.set(edit.file, [edit]);
|
|
240
|
+
}
|
|
241
|
+
return grouped;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/cli/migrate/scan.ts
|
|
245
|
+
import { existsSync } from "fs";
|
|
246
|
+
import { readdir, readFile as readFile2 } from "fs/promises";
|
|
247
|
+
import path2 from "path";
|
|
248
|
+
var SKIP_DIRS = new Set(["node_modules", ".next", ".pnext", ".git", "dist", "build"]);
|
|
249
|
+
var LOADERS = {
|
|
250
|
+
".ts": "ts",
|
|
251
|
+
".tsx": "tsx",
|
|
252
|
+
".jsx": "jsx",
|
|
253
|
+
".js": "js",
|
|
254
|
+
".mjs": "js",
|
|
255
|
+
".cjs": "js"
|
|
256
|
+
};
|
|
257
|
+
var STREAMING_APIS = ["renderToReadableStream", "renderToPipeableStream"];
|
|
258
|
+
var CALL_THEN_ACCESS = /(await\s+)?\b([\w$]+)\s*\(\s*\)\s*(?:\.\s*([\w$]+)|\[)/g;
|
|
259
|
+
var NEXT_HEADERS_IMPORT = /import\s*\{([^}]*)\}\s*from\s*['"]next\/headers['"]/g;
|
|
260
|
+
var REQUEST_APIS = new Set(["cookies", "headers", "draftMode"]);
|
|
261
|
+
var PROMISE_METHODS = new Set(["then", "catch", "finally"]);
|
|
262
|
+
var SPECIAL_PAGES = ["_app", "_document", "_error"];
|
|
263
|
+
var SEGMENT_FILES = new Set(["page", "layout", "route", "template", "default"]);
|
|
264
|
+
var SEGMENT_HEADS = /export\s+default\s+(?:async\s+)?function\s*[\w$]*\s*\(|export\s+default\s+(?:async\s+)?\(|export\s+(?:async\s+)?function\s+generateMetadata\s*\(|export\s+const\s+generateMetadata\s*(?::[^=]*)?=\s*(?:async\s*)?\(/g;
|
|
265
|
+
var ROUTE_HANDLER_HEADS = /export\s+(?:async\s+)?function\s+(?:GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)\s*\(|export\s+const\s+(?:GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)\s*(?::[^=]*)?=\s*(?:async\s*)?\(/g;
|
|
266
|
+
var SYNC_PROPS = ["params", "searchParams"];
|
|
267
|
+
async function scanSources(root, result) {
|
|
268
|
+
const { SHIMMED_NEXT_DIST_PATHS } = await import("./aliases-j47a10ce.js");
|
|
269
|
+
const shimmed = new Set(SHIMMED_NEXT_DIST_PATHS);
|
|
270
|
+
const deepImports = [];
|
|
271
|
+
const streaming = [];
|
|
272
|
+
const headImports = [];
|
|
273
|
+
for await (const file of walk(root)) {
|
|
274
|
+
const loader = LOADERS[path2.extname(file)];
|
|
275
|
+
if (!loader)
|
|
276
|
+
continue;
|
|
277
|
+
const text = await readFile2(file, "utf8");
|
|
278
|
+
let specifiers;
|
|
279
|
+
try {
|
|
280
|
+
specifiers = new Bun.Transpiler({ loader }).scanImports(text).map((item) => item.path);
|
|
281
|
+
} catch {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const relative = path2.relative(root, file);
|
|
285
|
+
for (const specifier of specifiers) {
|
|
286
|
+
if (specifier.startsWith("next/dist/") && !shimmed.has(specifier.replace(/\.js$/, ""))) {
|
|
287
|
+
deepImports.push(`${relative} \u2192 ${specifier}`);
|
|
288
|
+
}
|
|
289
|
+
if (/^react-dom\/server(\.|\/|$)/.test(specifier) && STREAMING_APIS.some((api) => text.includes(api))) {
|
|
290
|
+
streaming.push(relative);
|
|
291
|
+
}
|
|
292
|
+
if (specifier === "next/head")
|
|
293
|
+
headImports.push(relative);
|
|
294
|
+
if (specifier === "next/font/google")
|
|
295
|
+
result.googleFontImports.push(relative);
|
|
296
|
+
}
|
|
297
|
+
if (readsRequestApiSynchronously(text) || readsSyncSegmentProps(file, text)) {
|
|
298
|
+
result.syncRequestApis.push(relative);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (deepImports.length > 0) {
|
|
302
|
+
result.reports.push({
|
|
303
|
+
title: "Unsupported next/dist/* deep imports",
|
|
304
|
+
detail: 'Only five next/dist paths are shimmed \u2014 replace these with public APIs. See https://pnext.dev/docs/compat ("Smaller surfaces").',
|
|
305
|
+
files: deepImports
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
if (streaming.length > 0) {
|
|
309
|
+
result.reports.push({
|
|
310
|
+
title: "react-dom/server streaming APIs",
|
|
311
|
+
detail: "preact/compat does not provide renderToReadableStream/renderToPipeableStream \u2014 use pnext rendering instead. See https://pnext.dev/docs/compat.",
|
|
312
|
+
files: [...new Set(streaming)]
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
if (headImports.length > 0) {
|
|
316
|
+
result.reports.push({
|
|
317
|
+
title: "next/head is ignored in the app router",
|
|
318
|
+
detail: "pnext ignores next/head in app-directory components (matching Next). Move these tags to metadata exports or the root layout <head>. See https://pnext.dev/docs/compat.",
|
|
319
|
+
files: [...new Set(headImports)]
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
scanSpecialPages(root, result);
|
|
323
|
+
await scanNextConfig(root, result);
|
|
324
|
+
}
|
|
325
|
+
function readsRequestApiSynchronously(text) {
|
|
326
|
+
const locals = new Set;
|
|
327
|
+
for (const match of text.matchAll(NEXT_HEADERS_IMPORT)) {
|
|
328
|
+
for (const binding of match[1].split(",")) {
|
|
329
|
+
const [imported, local] = binding.trim().split(/\s+as\s+/);
|
|
330
|
+
if (imported && REQUEST_APIS.has(imported))
|
|
331
|
+
locals.add(local ?? imported);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (locals.size === 0)
|
|
335
|
+
return false;
|
|
336
|
+
for (const match of text.matchAll(CALL_THEN_ACCESS)) {
|
|
337
|
+
if (match[1] || !locals.has(match[2]))
|
|
338
|
+
continue;
|
|
339
|
+
if (match[3] && PROMISE_METHODS.has(match[3]))
|
|
340
|
+
continue;
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
function readsSyncSegmentProps(file, text) {
|
|
346
|
+
const extension = path2.extname(file);
|
|
347
|
+
if (!SEGMENT_FILES.has(path2.basename(file, extension)))
|
|
348
|
+
return false;
|
|
349
|
+
return readsHeadProps(text, SEGMENT_HEADS, 0) || readsHeadProps(text, ROUTE_HANDLER_HEADS, 1);
|
|
350
|
+
}
|
|
351
|
+
function readsHeadProps(text, heads, index) {
|
|
352
|
+
for (const head of text.matchAll(heads)) {
|
|
353
|
+
const list = balanced(text, head.index + head[0].length - 1, "(", ")");
|
|
354
|
+
const parameter = (splitTopLevel(list)[index] ?? "").trim();
|
|
355
|
+
if (parameter && readsPropsSynchronously(parameter, text))
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
function readsPropsSynchronously(parameter, text) {
|
|
361
|
+
const colon = topLevelIndex(parameter, ":");
|
|
362
|
+
const binding = (colon < 0 ? parameter : parameter.slice(0, colon)).trim();
|
|
363
|
+
const annotation = colon < 0 ? "" : parameter.slice(colon + 1).trim();
|
|
364
|
+
const destructured = binding.startsWith("{") ? destructuredKeys(binding) : null;
|
|
365
|
+
for (const prop of SYNC_PROPS) {
|
|
366
|
+
if (destructured && !destructured.has(prop))
|
|
367
|
+
continue;
|
|
368
|
+
if (annotation) {
|
|
369
|
+
const declared = propertyType(annotation, text, prop);
|
|
370
|
+
if (declared && !/^Promise\s*</.test(declared))
|
|
371
|
+
return true;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (destructured) {
|
|
375
|
+
if (!new RegExp(`await\\s+${prop}\\b`).test(text))
|
|
376
|
+
return true;
|
|
377
|
+
} else if (/^[\w$]+$/.test(binding)) {
|
|
378
|
+
const reads = text.matchAll(new RegExp(`(await\\s+)?\\b${binding}\\.${prop}\\b`, "g"));
|
|
379
|
+
if ([...reads].some((read) => !read[1]))
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
function propertyType(annotation, text, prop) {
|
|
386
|
+
let body;
|
|
387
|
+
if (annotation.startsWith("{")) {
|
|
388
|
+
body = balanced(annotation, 0, "{", "}");
|
|
389
|
+
} else {
|
|
390
|
+
const name = /^[\w$]+/.exec(annotation)?.[0];
|
|
391
|
+
body = name ? localTypeBody(name, text) : undefined;
|
|
392
|
+
}
|
|
393
|
+
if (!body)
|
|
394
|
+
return;
|
|
395
|
+
return new RegExp(`(?:^|[{;,\\n])\\s*${prop}\\s*\\??\\s*:\\s*([^;,\\n]+)`).exec(body)?.[1]?.trim();
|
|
396
|
+
}
|
|
397
|
+
function localTypeBody(name, text) {
|
|
398
|
+
const declaration = new RegExp(`\\b(?:type|interface)\\s+${name}\\b`).exec(text);
|
|
399
|
+
if (!declaration)
|
|
400
|
+
return;
|
|
401
|
+
const open = text.indexOf("{", declaration.index);
|
|
402
|
+
if (open < 0 || /[;)]/.test(text.slice(declaration.index, open)))
|
|
403
|
+
return;
|
|
404
|
+
return balanced(text, open, "{", "}");
|
|
405
|
+
}
|
|
406
|
+
function destructuredKeys(binding) {
|
|
407
|
+
const keys = new Set;
|
|
408
|
+
for (const part of splitTopLevel(balanced(binding, 0, "{", "}"))) {
|
|
409
|
+
const key = /^\s*(?:\.\.\.)?([\w$]+)/.exec(part)?.[1];
|
|
410
|
+
if (key)
|
|
411
|
+
keys.add(key);
|
|
412
|
+
}
|
|
413
|
+
return keys;
|
|
414
|
+
}
|
|
415
|
+
function balanced(text, from, open, close) {
|
|
416
|
+
let depth = 0;
|
|
417
|
+
for (let i = from;i < text.length; i++) {
|
|
418
|
+
if (text[i] === open)
|
|
419
|
+
depth++;
|
|
420
|
+
else if (text[i] === close && --depth === 0)
|
|
421
|
+
return text.slice(from + 1, i);
|
|
422
|
+
}
|
|
423
|
+
return "";
|
|
424
|
+
}
|
|
425
|
+
function splitTopLevel(list) {
|
|
426
|
+
const parts = [];
|
|
427
|
+
let depth = 0;
|
|
428
|
+
let start = 0;
|
|
429
|
+
for (let i = 0;i < list.length; i++) {
|
|
430
|
+
const char = list[i];
|
|
431
|
+
if (char === "=" && list[i + 1] === ">")
|
|
432
|
+
i++;
|
|
433
|
+
else if ("({[<".includes(char))
|
|
434
|
+
depth++;
|
|
435
|
+
else if (")}]>".includes(char))
|
|
436
|
+
depth--;
|
|
437
|
+
else if (char === "," && depth === 0) {
|
|
438
|
+
parts.push(list.slice(start, i));
|
|
439
|
+
start = i + 1;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
parts.push(list.slice(start));
|
|
443
|
+
return parts;
|
|
444
|
+
}
|
|
445
|
+
function topLevelIndex(text, char) {
|
|
446
|
+
let depth = 0;
|
|
447
|
+
for (let i = 0;i < text.length; i++) {
|
|
448
|
+
const current = text[i];
|
|
449
|
+
if ("({[<".includes(current))
|
|
450
|
+
depth++;
|
|
451
|
+
else if (")}]>".includes(current))
|
|
452
|
+
depth--;
|
|
453
|
+
else if (current === char && depth === 0)
|
|
454
|
+
return i;
|
|
455
|
+
}
|
|
456
|
+
return -1;
|
|
457
|
+
}
|
|
458
|
+
function scanSpecialPages(root, result) {
|
|
459
|
+
const found = [];
|
|
460
|
+
for (const base of ["pages", path2.join("src", "pages")]) {
|
|
461
|
+
for (const name of SPECIAL_PAGES) {
|
|
462
|
+
for (const extension of [".tsx", ".ts", ".jsx", ".js"]) {
|
|
463
|
+
const relative = path2.join(base, `${name}${extension}`);
|
|
464
|
+
if (existsSync(path2.join(root, relative)))
|
|
465
|
+
found.push(relative);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (found.length === 0)
|
|
470
|
+
return;
|
|
471
|
+
result.reports.push({
|
|
472
|
+
title: "pages/_app, _document and _error are ignored",
|
|
473
|
+
detail: "Move this setup into the app-router root layout \u2014 pnext never loads these files. See https://pnext.dev/docs/compat.",
|
|
474
|
+
files: found
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
async function scanNextConfig(root, result) {
|
|
478
|
+
for (const name of ["next.config.ts", "next.config.js", "next.config.mjs", "next.config.cjs"]) {
|
|
479
|
+
const file = path2.join(root, name);
|
|
480
|
+
if (!existsSync(file))
|
|
481
|
+
continue;
|
|
482
|
+
const text = await readFile2(file, "utf8");
|
|
483
|
+
if (!text.includes("webpack:") && !text.includes("webpack("))
|
|
484
|
+
return;
|
|
485
|
+
const svgr = text.includes("@svgr/webpack");
|
|
486
|
+
result.reports.push({
|
|
487
|
+
title: `${name} defines a webpack function`,
|
|
488
|
+
detail: svgr ? "The webpack function is never executed; SVGR is auto-detected from @svgr/webpack, so SVG imports keep working. See https://pnext.dev/docs/compat." : "The webpack function is never executed \u2014 port any custom loaders/plugins to pnext config. See https://pnext.dev/docs/compat."
|
|
489
|
+
});
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
async function* walk(dir) {
|
|
494
|
+
let entries;
|
|
495
|
+
try {
|
|
496
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
497
|
+
} catch {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
for (const entry of entries) {
|
|
501
|
+
if (entry.isDirectory()) {
|
|
502
|
+
if (SKIP_DIRS.has(entry.name))
|
|
503
|
+
continue;
|
|
504
|
+
yield* walk(path2.join(dir, entry.name));
|
|
505
|
+
} else if (entry.isFile()) {
|
|
506
|
+
yield path2.join(dir, entry.name);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// src/cli/migrate/spinner.ts
|
|
512
|
+
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
513
|
+
async function withSpinner(label, run) {
|
|
514
|
+
if (!process.stdout.isTTY)
|
|
515
|
+
return run();
|
|
516
|
+
let frame = 0;
|
|
517
|
+
const timer = setInterval(() => {
|
|
518
|
+
process.stdout.write(`\r${FRAMES[frame % FRAMES.length]} ${label}`);
|
|
519
|
+
frame += 1;
|
|
520
|
+
}, 80);
|
|
521
|
+
try {
|
|
522
|
+
return await run();
|
|
523
|
+
} finally {
|
|
524
|
+
clearInterval(timer);
|
|
525
|
+
process.stdout.write("\r\x1B[2K");
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// src/cli/migrate/tsconfig.ts
|
|
530
|
+
import { existsSync as existsSync2 } from "fs";
|
|
531
|
+
import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
|
|
532
|
+
import path3 from "path";
|
|
533
|
+
var MANUAL_STEPS = 'remove { "name": "next" } from compilerOptions.plugins and replace ".next/types" includes with ".pnext/types/**/*.ts".';
|
|
534
|
+
async function migrateTsconfig(root, result, dryRun) {
|
|
535
|
+
const file = path3.join(root, "tsconfig.json");
|
|
536
|
+
if (!existsSync2(file))
|
|
537
|
+
return;
|
|
538
|
+
const text = await readFile3(file, "utf8");
|
|
539
|
+
let config;
|
|
540
|
+
try {
|
|
541
|
+
config = JSON.parse(text);
|
|
542
|
+
} catch {
|
|
543
|
+
result.reports.push({
|
|
544
|
+
title: "tsconfig.json has comments (JSONC) \u2014 not edited",
|
|
545
|
+
detail: `Apply by hand: ${MANUAL_STEPS}`
|
|
546
|
+
});
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
if (typeof config !== "object" || config === null)
|
|
550
|
+
return;
|
|
551
|
+
const changes = [];
|
|
552
|
+
const compilerOptions = config.compilerOptions;
|
|
553
|
+
if (isObject2(compilerOptions) && Array.isArray(compilerOptions.plugins)) {
|
|
554
|
+
const kept = compilerOptions.plugins.filter((plugin) => !(isObject2(plugin) && plugin.name === "next"));
|
|
555
|
+
if (kept.length !== compilerOptions.plugins.length) {
|
|
556
|
+
if (kept.length === 0)
|
|
557
|
+
delete compilerOptions.plugins;
|
|
558
|
+
else
|
|
559
|
+
compilerOptions.plugins = kept;
|
|
560
|
+
changes.push("next TypeScript plugin removed");
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (Array.isArray(config.include)) {
|
|
564
|
+
const seen = new Set;
|
|
565
|
+
const include = [];
|
|
566
|
+
let repointed = false;
|
|
567
|
+
for (const entry of config.include) {
|
|
568
|
+
if (typeof entry !== "string") {
|
|
569
|
+
include.push(entry);
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
const next = entry.includes(".next/types") || entry.includes(".next/dev/types") ? ".pnext/types/**/*.ts" : entry;
|
|
573
|
+
if (next !== entry)
|
|
574
|
+
repointed = true;
|
|
575
|
+
if (seen.has(next))
|
|
576
|
+
continue;
|
|
577
|
+
seen.add(next);
|
|
578
|
+
include.push(next);
|
|
579
|
+
}
|
|
580
|
+
if (repointed) {
|
|
581
|
+
config.include = include;
|
|
582
|
+
changes.push("type includes repointed at .pnext/types");
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (changes.length === 0)
|
|
586
|
+
return;
|
|
587
|
+
if (!dryRun)
|
|
588
|
+
await writeFile2(file, `${JSON.stringify(config, null, 2)}
|
|
589
|
+
`);
|
|
590
|
+
for (const change of changes) {
|
|
591
|
+
result.edits.push({ file: "tsconfig.json", description: change });
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
function isObject2(value) {
|
|
595
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/cli/migrate/run.ts
|
|
599
|
+
var NEXT_CONFIG_FILES = ["next.config.ts", "next.config.js", "next.config.mjs", "next.config.cjs"];
|
|
600
|
+
var PNEXT_CONFIG_FILES = ["pnext.config.ts", "pnext.config.js", "pnext.config.mjs"];
|
|
601
|
+
async function migrateApp(directory, options) {
|
|
602
|
+
const root = path4.resolve(directory ?? process.cwd());
|
|
603
|
+
const pkg = await readPackageJson(root);
|
|
604
|
+
const hasNextDependency = Boolean(pkg && (hasDependency(pkg.dependencies, "next") || hasDependency(pkg.devDependencies, "next")));
|
|
605
|
+
const hasNextConfig = NEXT_CONFIG_FILES.some((name) => existsSync3(path4.join(root, name)));
|
|
606
|
+
if (!hasNextDependency && !hasNextConfig) {
|
|
607
|
+
console.error(`${bold("Not a Next.js app")}: ${root}
|
|
608
|
+
` + ` - ${pkg ? 'package.json has no "next" dependency' : "no readable package.json"}
|
|
609
|
+
` + " - no next.config.{ts,js,mjs,cjs}");
|
|
610
|
+
return 1;
|
|
611
|
+
}
|
|
612
|
+
printHeader(root, options.dryRun);
|
|
613
|
+
const result = emptyResult();
|
|
614
|
+
await withSpinner("Scanning sources ...", () => scanSources(root, result));
|
|
615
|
+
if (pkg)
|
|
616
|
+
await migratePackageJson(root, pkg, result, options.dryRun);
|
|
617
|
+
await createPnextConfig(root, result, options.dryRun);
|
|
618
|
+
await migrateTsconfig(root, result, options.dryRun);
|
|
619
|
+
await removeNextEnv(root, result, options.dryRun);
|
|
620
|
+
await updateGitignore(root, result, options.dryRun);
|
|
621
|
+
printResult(result, { install: installCommand(root) });
|
|
622
|
+
return 0;
|
|
623
|
+
}
|
|
624
|
+
async function createPnextConfig(root, result, dryRun) {
|
|
625
|
+
const legacy = result.syncRequestApis.length > 0;
|
|
626
|
+
const existing = PNEXT_CONFIG_FILES.find((name) => existsSync3(path4.join(root, name)));
|
|
627
|
+
if (existing) {
|
|
628
|
+
result.reports.push({
|
|
629
|
+
title: `${existing} already exists`,
|
|
630
|
+
detail: "Make sure it sets compat: { next: true }. See https://pnext.dev/docs/compat."
|
|
631
|
+
});
|
|
632
|
+
if (legacy)
|
|
633
|
+
reportSyncRequestApis(result, existing);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (!dryRun) {
|
|
637
|
+
await writeFile3(path4.join(root, "pnext.config.ts"), legacy ? `export default {
|
|
638
|
+
` + ` compat: {
|
|
639
|
+
` + " // Sync cookies()/headers()/params still work; migrate to `await` and drop this.\n" + ` next: { legacyRequestAPIs: true },
|
|
640
|
+
` + ` },
|
|
641
|
+
` + `};
|
|
642
|
+
` : `export default { compat: { next: true } };
|
|
643
|
+
`);
|
|
644
|
+
}
|
|
645
|
+
result.edits.push({
|
|
646
|
+
file: "pnext.config.ts",
|
|
647
|
+
description: legacy ? "created with compat.next enabled (legacyRequestAPIs)" : "created with compat.next enabled"
|
|
648
|
+
});
|
|
649
|
+
if (legacy)
|
|
650
|
+
reportSyncRequestApis(result);
|
|
651
|
+
}
|
|
652
|
+
function reportSyncRequestApis(result, existingConfig) {
|
|
653
|
+
result.reports.push({
|
|
654
|
+
title: "Sync cookies()/headers()/params detected",
|
|
655
|
+
detail: existingConfig ? `Set compat: { next: { legacyRequestAPIs: true } } in ${existingConfig} to keep these working, then migrate to \`await\` and remove it. See https://pnext.dev/docs/compat` : "Enabled compat.next.legacyRequestAPIs; migrate to `await` and remove it. See https://pnext.dev/docs/compat",
|
|
656
|
+
files: [...new Set(result.syncRequestApis)]
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
async function removeNextEnv(root, result, dryRun) {
|
|
660
|
+
const file = path4.join(root, "next-env.d.ts");
|
|
661
|
+
if (!existsSync3(file))
|
|
662
|
+
return;
|
|
663
|
+
if (!dryRun)
|
|
664
|
+
await rm(file);
|
|
665
|
+
result.edits.push({ file: "next-env.d.ts", description: "deleted" });
|
|
666
|
+
}
|
|
667
|
+
async function updateGitignore(root, result, dryRun) {
|
|
668
|
+
const file = path4.join(root, ".gitignore");
|
|
669
|
+
if (!existsSync3(file))
|
|
670
|
+
return;
|
|
671
|
+
const text = await readFile4(file, "utf8");
|
|
672
|
+
if (text.split(/\r?\n/).some((line) => line.trim() === ".pnext/"))
|
|
673
|
+
return;
|
|
674
|
+
if (!dryRun)
|
|
675
|
+
await appendFile(file, `${text.endsWith(`
|
|
676
|
+
`) || text === "" ? "" : `
|
|
677
|
+
`}.pnext/
|
|
678
|
+
`);
|
|
679
|
+
result.edits.push({ file: ".gitignore", description: "appended .pnext/" });
|
|
680
|
+
}
|
|
681
|
+
function installCommand(root) {
|
|
682
|
+
if (existsSync3(path4.join(root, "bun.lock")) || existsSync3(path4.join(root, "bun.lockb"))) {
|
|
683
|
+
return "bun install";
|
|
684
|
+
}
|
|
685
|
+
if (existsSync3(path4.join(root, "pnpm-lock.yaml")))
|
|
686
|
+
return "pnpm install";
|
|
687
|
+
if (existsSync3(path4.join(root, "yarn.lock")))
|
|
688
|
+
return "yarn";
|
|
689
|
+
return "npm install";
|
|
690
|
+
}
|
|
691
|
+
function hasDependency(bucket, name) {
|
|
692
|
+
return typeof bucket === "object" && bucket !== null && name in bucket;
|
|
693
|
+
}
|
|
694
|
+
export {
|
|
695
|
+
migrateApp
|
|
696
|
+
};
|