@wular/pnext 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/bin/pnext +1 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/css.md +13 -9
- package/reference/dev.md +1 -1
- package/reference/metadata.md +7 -7
- package/reference/navigation.md +35 -28
- package/reference/performance.md +70 -70
- package/reference/rendering.md +17 -17
- package/reference/routing.md +17 -17
- package/reference/typegen.md +12 -8
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +113 -109
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +49 -52
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +71 -63
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +88 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +794 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +17 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +1988 -1992
- package/src/{api → client}/router/types.ts +93 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +69 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2076 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +69 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +952 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +425 -404
- package/src/styles.d.ts +9 -0
- package/src/types.ts +320 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
package/src/cli/index.ts
CHANGED
|
@@ -1,117 +1,120 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { existsSync, statSync } from 'node:fs'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import { markBoot } from './boot
|
|
5
|
-
import { commandBinaryName, nameEsbuildProcess, namedBunBinary } from './named-bin'
|
|
2
|
+
import { existsSync, statSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { markBoot } from './boot/trace'
|
|
5
|
+
import { commandBinaryName, nameEsbuildProcess, namedBunBinary } from './boot/named-bin'
|
|
6
6
|
|
|
7
|
-
const [, , command, ...args] = process.argv
|
|
8
|
-
markBoot('cli:entry')
|
|
7
|
+
const [, , command, ...args] = process.argv
|
|
8
|
+
markBoot('cli:entry')
|
|
9
9
|
|
|
10
10
|
// A no-op once we already run under the command's name; otherwise it creates
|
|
11
11
|
// the hardlink so bin/pnext can exec it directly from the next run on.
|
|
12
|
-
namedBunBinary(commandBinaryName(command))
|
|
12
|
+
namedBunBinary(commandBinaryName(command))
|
|
13
13
|
|
|
14
14
|
// Before any command lazily imports esbuild, which captures the binary path on
|
|
15
15
|
// module load.
|
|
16
|
-
nameEsbuildProcess()
|
|
17
|
-
markBoot('cli:naming')
|
|
16
|
+
nameEsbuildProcess()
|
|
17
|
+
markBoot('cli:naming')
|
|
18
18
|
|
|
19
19
|
try {
|
|
20
20
|
if (command === 'dev') {
|
|
21
|
-
const { dev } = await import('./dev')
|
|
21
|
+
const { dev } = await import('./dev')
|
|
22
22
|
await dev({
|
|
23
23
|
root: positionalRoot(args),
|
|
24
24
|
port: optionNumber(args, '--port'),
|
|
25
25
|
hostname: optionString(args, '--hostname'),
|
|
26
|
-
})
|
|
26
|
+
})
|
|
27
27
|
} else if (command === 'build') {
|
|
28
|
-
const { buildProject } = await import('./build')
|
|
28
|
+
const { buildProject } = await import('./build')
|
|
29
29
|
await buildProject(positionalRoot(args), {
|
|
30
30
|
adapter: adapterOption(args),
|
|
31
31
|
verbose: args.includes('--verbose'),
|
|
32
32
|
debugBuildPaths: optionString(args, '--debug-build-paths'),
|
|
33
33
|
buildMode: buildModeOption(args),
|
|
34
34
|
debugPrerender: args.includes('--debug-prerender'),
|
|
35
|
-
})
|
|
35
|
+
})
|
|
36
36
|
// A live CSS worker thread races Bun's exit teardown (Linux: silent exit 1
|
|
37
37
|
// after a successful build); stop it before force-exiting.
|
|
38
|
-
await (await import('../css/build')).stopCssWorker()
|
|
38
|
+
await (await import('../css/build')).stopCssWorker()
|
|
39
39
|
// Nothing here keeps the event loop alive on success, but a project's
|
|
40
40
|
// next.config can (e.g. a stray setInterval) and Next's own `next build`
|
|
41
41
|
// force-exits regardless of such handles. Do the same so `build` always
|
|
42
42
|
// terminates once buildProject resolves.
|
|
43
|
-
process.exit(0)
|
|
43
|
+
process.exit(0)
|
|
44
44
|
} else if (command === 'start') {
|
|
45
|
-
const root = positionalRoot(args)
|
|
45
|
+
const root = positionalRoot(args)
|
|
46
46
|
// The build emits src/cli/start.ts prebundled into one file; parsing that
|
|
47
47
|
// instead of walking the framework's source graph is most of `start`'s
|
|
48
48
|
// spawn→first-200. Absent (no build yet, custom outDir) → source path.
|
|
49
|
-
const { prebuiltServerEntry } = await import('./
|
|
50
|
-
const prebuilt = prebuiltServerEntry(root)
|
|
49
|
+
const { prebuiltServerEntry } = await import('./serve/entry')
|
|
50
|
+
const prebuilt = prebuiltServerEntry(root)
|
|
51
51
|
const { start } = prebuilt
|
|
52
52
|
? ((await import(prebuilt)) as typeof import('./start'))
|
|
53
|
-
: await import('./start')
|
|
53
|
+
: await import('./start')
|
|
54
54
|
await start({
|
|
55
55
|
root,
|
|
56
56
|
port: optionNumber(args, '--port'),
|
|
57
57
|
hostname: optionString(args, '--hostname'),
|
|
58
|
-
})
|
|
58
|
+
})
|
|
59
59
|
} else if (command === 'analyze') {
|
|
60
|
-
const { analyzeProject } = await import('./analyze')
|
|
61
|
-
const { route, root } = analyzePositionals(args)
|
|
60
|
+
const { analyzeProject } = await import('./analyze')
|
|
61
|
+
const { route, root } = analyzePositionals(args)
|
|
62
62
|
const result = await analyzeProject(root, {
|
|
63
63
|
compression: analyzeCompression(args),
|
|
64
64
|
route,
|
|
65
|
-
})
|
|
65
|
+
})
|
|
66
66
|
if (args.includes('--json')) {
|
|
67
|
-
console.log(JSON.stringify(result, null, 2))
|
|
67
|
+
console.log(JSON.stringify(result, null, 2))
|
|
68
68
|
} else {
|
|
69
|
-
const { printAnalyzeResult } = await import('./analyze
|
|
70
|
-
printAnalyzeResult(result, { route, files: args.includes('--files') })
|
|
69
|
+
const { printAnalyzeResult } = await import('./analyze')
|
|
70
|
+
printAnalyzeResult(result, { route, files: args.includes('--files') })
|
|
71
71
|
}
|
|
72
72
|
} else if (command === 'typegen') {
|
|
73
|
-
const { typegenProject } = await import('
|
|
74
|
-
const result = await typegenProject(positionalRoot(args))
|
|
73
|
+
const { typegenProject } = await import('./typegen')
|
|
74
|
+
const result = await typegenProject(positionalRoot(args))
|
|
75
75
|
console.log(
|
|
76
76
|
`Generated ${result.routes} route types, ${result.aliases} aliases, and ${result.checks} checks at ${result.file}`,
|
|
77
|
-
)
|
|
77
|
+
)
|
|
78
78
|
// Like `next typegen`, exit even when the loaded next.config leaves open
|
|
79
79
|
// handles (timers/connections) alive — a one-shot command must not hang.
|
|
80
|
-
process.exit(0)
|
|
80
|
+
process.exit(0)
|
|
81
81
|
} else if (command === 'create') {
|
|
82
|
-
const { createApp } = await import('./create')
|
|
83
|
-
await createApp(positionals(args)[0], { install: !args.includes('--no-install') })
|
|
84
|
-
process.exit(0)
|
|
82
|
+
const { createApp } = await import('./create')
|
|
83
|
+
await createApp(positionals(args)[0], { install: !args.includes('--no-install') })
|
|
84
|
+
process.exit(0)
|
|
85
85
|
} else if (command === 'migrate') {
|
|
86
|
-
const { migrateApp } = await import('./migrate')
|
|
87
|
-
const code = await migrateApp(positionalRoot(args), { dryRun: args.includes('--dry-run') })
|
|
88
|
-
process.exit(code)
|
|
86
|
+
const { migrateApp } = await import('./migrate/run')
|
|
87
|
+
const code = await migrateApp(positionalRoot(args), { dryRun: args.includes('--dry-run') })
|
|
88
|
+
process.exit(code)
|
|
89
89
|
} else {
|
|
90
|
-
printHelp()
|
|
91
|
-
process.exit(command ? 1 : 0)
|
|
90
|
+
printHelp()
|
|
91
|
+
process.exit(command ? 1 : 0)
|
|
92
92
|
}
|
|
93
93
|
} catch (error) {
|
|
94
|
-
const formatted = formatCliError(error)
|
|
94
|
+
const formatted = formatCliError(error)
|
|
95
95
|
// A blank formatted message exits 1 with no explanation; fall back to the
|
|
96
96
|
// raw error so the failure is never silent.
|
|
97
|
-
if (formatted.message.trim()) console.error(formatted.message)
|
|
98
|
-
else
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
if (formatted.message.trim()) console.error(formatted.message)
|
|
98
|
+
else
|
|
99
|
+
console.error(
|
|
100
|
+
error instanceof Error ? (error.stack ?? `${error.name}: ${error.message}`) : String(error),
|
|
101
|
+
)
|
|
102
|
+
if (formatted.trace) console.log(`\n${formatted.trace}`)
|
|
103
|
+
process.exit(1)
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
function formatCliError(error: unknown) {
|
|
104
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
105
|
-
const traceStart = message.indexOf('\npnext client import trace for route ')
|
|
106
|
-
if (traceStart === -1) return { message }
|
|
107
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
108
|
+
const traceStart = message.indexOf('\npnext client import trace for route ')
|
|
109
|
+
if (traceStart === -1) return { message }
|
|
107
110
|
return {
|
|
108
111
|
message: message.slice(0, traceStart),
|
|
109
112
|
trace: message.slice(traceStart + 1),
|
|
110
|
-
}
|
|
113
|
+
}
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
function positionalRoot(args: string[]) {
|
|
114
|
-
return positionals(args)[0]
|
|
117
|
+
return positionals(args)[0]
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
// The analyze command takes optional [route] and [directory] positionals. A
|
|
@@ -119,27 +122,27 @@ function positionalRoot(args: string[]) {
|
|
|
119
122
|
// that looks like a project root — system directories like /home or /run
|
|
120
123
|
// collide with real route names.
|
|
121
124
|
function analyzePositionals(args: string[]) {
|
|
122
|
-
let route: string | undefined
|
|
123
|
-
let root: string | undefined
|
|
125
|
+
let route: string | undefined
|
|
126
|
+
let root: string | undefined
|
|
124
127
|
for (const arg of positionals(args)) {
|
|
125
|
-
if (!route && arg.startsWith('/') && !isProjectDirectory(arg)) route = arg
|
|
126
|
-
else root ??= arg
|
|
128
|
+
if (!route && arg.startsWith('/') && !isProjectDirectory(arg)) route = arg
|
|
129
|
+
else root ??= arg
|
|
127
130
|
}
|
|
128
|
-
return { route, root }
|
|
131
|
+
return { route, root }
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
function isProjectDirectory(candidate: string) {
|
|
132
|
-
if (!isDirectory(candidate)) return false
|
|
135
|
+
if (!isDirectory(candidate)) return false
|
|
133
136
|
return ['package.json', '.pnext', 'app', path.join('src', 'app')].some(entry =>
|
|
134
137
|
existsSync(path.join(candidate, entry)),
|
|
135
|
-
)
|
|
138
|
+
)
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
function positionals(args: string[]) {
|
|
139
|
-
const out: string[] = []
|
|
142
|
+
const out: string[] = []
|
|
140
143
|
for (let index = 0; index < args.length; index += 1) {
|
|
141
|
-
const arg = args[index]
|
|
142
|
-
if (!arg) continue
|
|
144
|
+
const arg = args[index]
|
|
145
|
+
if (!arg) continue
|
|
143
146
|
if (
|
|
144
147
|
arg === '--port' ||
|
|
145
148
|
arg === '--adapter' ||
|
|
@@ -147,36 +150,36 @@ function positionals(args: string[]) {
|
|
|
147
150
|
arg === '--debug-build-paths' ||
|
|
148
151
|
arg === '--experimental-build-mode'
|
|
149
152
|
) {
|
|
150
|
-
index += 1
|
|
151
|
-
continue
|
|
153
|
+
index += 1
|
|
154
|
+
continue
|
|
152
155
|
}
|
|
153
|
-
if (!arg.startsWith('--')) out.push(arg)
|
|
156
|
+
if (!arg.startsWith('--')) out.push(arg)
|
|
154
157
|
}
|
|
155
|
-
return out
|
|
158
|
+
return out
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
function isDirectory(candidate: string) {
|
|
159
162
|
try {
|
|
160
|
-
return statSync(candidate).isDirectory()
|
|
163
|
+
return statSync(candidate).isDirectory()
|
|
161
164
|
} catch {
|
|
162
|
-
return false
|
|
165
|
+
return false
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
168
|
|
|
166
169
|
function optionNumber(args: string[], name: string) {
|
|
167
|
-
const index = args.indexOf(name)
|
|
168
|
-
if (index === -1) return undefined
|
|
169
|
-
const value = args[index + 1]
|
|
170
|
-
return value ? Number(value) : undefined
|
|
170
|
+
const index = args.indexOf(name)
|
|
171
|
+
if (index === -1) return undefined
|
|
172
|
+
const value = args[index + 1]
|
|
173
|
+
return value ? Number(value) : undefined
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
function optionString(args: string[], name: string) {
|
|
174
177
|
// Accept both `--name value` and `--name=value`.
|
|
175
|
-
const inline = args.find(arg => arg.startsWith(`${name}=`))
|
|
176
|
-
if (inline !== undefined) return inline.slice(name.length + 1)
|
|
177
|
-
const index = args.indexOf(name)
|
|
178
|
-
if (index === -1) return undefined
|
|
179
|
-
return args[index + 1]
|
|
178
|
+
const inline = args.find(arg => arg.startsWith(`${name}=`))
|
|
179
|
+
if (inline !== undefined) return inline.slice(name.length + 1)
|
|
180
|
+
const index = args.indexOf(name)
|
|
181
|
+
if (index === -1) return undefined
|
|
182
|
+
return args[index + 1]
|
|
180
183
|
}
|
|
181
184
|
|
|
182
185
|
/**
|
|
@@ -186,27 +189,27 @@ function optionString(args: string[], name: string) {
|
|
|
186
189
|
* the standard full build (idempotent over a prior `compile` run).
|
|
187
190
|
*/
|
|
188
191
|
function buildModeOption(args: string[]): 'compile' | 'generate' | undefined {
|
|
189
|
-
const value = optionString(args, '--experimental-build-mode')
|
|
190
|
-
if (value === 'compile' || value === 'generate') return value
|
|
192
|
+
const value = optionString(args, '--experimental-build-mode')
|
|
193
|
+
if (value === 'compile' || value === 'generate') return value
|
|
191
194
|
if (value !== undefined) {
|
|
192
195
|
console.error(
|
|
193
196
|
`error: option '--experimental-build-mode <mode>' argument '${value}' is invalid. Expected 'compile' or 'generate'.`,
|
|
194
|
-
)
|
|
195
|
-
process.exit(1)
|
|
197
|
+
)
|
|
198
|
+
process.exit(1)
|
|
196
199
|
}
|
|
197
|
-
return undefined
|
|
200
|
+
return undefined
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
function adapterOption(args: string[]) {
|
|
201
|
-
const index = args.indexOf('--adapter')
|
|
202
|
-
if (index === -1) return undefined
|
|
203
|
-
const adapter = args[index + 1]
|
|
204
|
-
if (adapter === 'vercel') return adapter
|
|
205
|
-
throw new Error(`Unsupported adapter: ${adapter ?? ''}`)
|
|
204
|
+
const index = args.indexOf('--adapter')
|
|
205
|
+
if (index === -1) return undefined
|
|
206
|
+
const adapter = args[index + 1]
|
|
207
|
+
if (adapter === 'vercel') return adapter
|
|
208
|
+
throw new Error(`Unsupported adapter: ${adapter ?? ''}`)
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
function analyzeCompression(args: string[]) {
|
|
209
|
-
return args.includes('--brotli') ? 'brotli' : 'gzip'
|
|
212
|
+
return args.includes('--brotli') ? 'brotli' : 'gzip'
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
function printHelp() {
|
|
@@ -216,5 +219,5 @@ pnext start [directory] [--port 3000] [--hostname 127.0.0.1]
|
|
|
216
219
|
pnext analyze [route] [directory] [--brotli] [--files] [--json]
|
|
217
220
|
pnext typegen [directory]
|
|
218
221
|
pnext create <directory> [--no-install]
|
|
219
|
-
pnext migrate [directory] [--dry-run]`)
|
|
222
|
+
pnext migrate [directory] [--dry-run]`)
|
|
220
223
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// package.json rewriting: scripts and dependencies. Structured edit only —
|
|
2
2
|
// JSON.parse -> mutate -> stringify, which preserves key insertion order.
|
|
3
3
|
|
|
4
|
-
import { readFile, writeFile } from 'node:fs/promises'
|
|
5
|
-
import path from 'node:path'
|
|
6
|
-
import
|
|
4
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import { pnextVersionRange } from '../../utils/fs'
|
|
7
|
+
import type { MigrationResult } from './report'
|
|
7
8
|
|
|
8
|
-
const SEPARATORS = new Set(['&&', '||', ';', '|', '&'])
|
|
9
|
-
const MAPPED_SUBCOMMANDS = new Set(['dev', 'build', 'start', 'typegen'])
|
|
10
|
-
const DROPPED_FLAGS = new Set(['--turbo', '--turbopack'])
|
|
9
|
+
const SEPARATORS = new Set(['&&', '||', ';', '|', '&'])
|
|
10
|
+
const MAPPED_SUBCOMMANDS = new Set(['dev', 'build', 'start', 'typegen'])
|
|
11
|
+
const DROPPED_FLAGS = new Set(['--turbo', '--turbopack'])
|
|
11
12
|
|
|
12
|
-
type Json = Record<string, unknown
|
|
13
|
+
type Json = Record<string, unknown>
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Rewrite `next` only where it is a command word: the first token of the
|
|
@@ -17,64 +18,64 @@ type Json = Record<string, unknown>;
|
|
|
17
18
|
* `nextron build` or `npx next-sitemap` are never touched.
|
|
18
19
|
*/
|
|
19
20
|
export function rewriteScript(script: string): { script: string; reports: string[] } {
|
|
20
|
-
const tokens = script.split(/\s+/).filter(Boolean)
|
|
21
|
-
const reports: string[] = []
|
|
22
|
-
const out: string[] = []
|
|
23
|
-
let commandStart = true
|
|
24
|
-
let changed = false
|
|
21
|
+
const tokens = script.split(/\s+/).filter(Boolean)
|
|
22
|
+
const reports: string[] = []
|
|
23
|
+
const out: string[] = []
|
|
24
|
+
let commandStart = true
|
|
25
|
+
let changed = false
|
|
25
26
|
|
|
26
27
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
27
|
-
const token = tokens[index]
|
|
28
|
+
const token = tokens[index]!
|
|
28
29
|
if (SEPARATORS.has(token)) {
|
|
29
|
-
out.push(token)
|
|
30
|
-
commandStart = true
|
|
31
|
-
continue
|
|
30
|
+
out.push(token)
|
|
31
|
+
commandStart = true
|
|
32
|
+
continue
|
|
32
33
|
}
|
|
33
34
|
// Env-var prefixes (NODE_OPTIONS=x next dev) don't end the command position.
|
|
34
35
|
if (commandStart && /^[A-Za-z_][A-Za-z0-9_]*=/.test(token)) {
|
|
35
|
-
out.push(token)
|
|
36
|
-
continue
|
|
36
|
+
out.push(token)
|
|
37
|
+
continue
|
|
37
38
|
}
|
|
38
39
|
if (!commandStart || token !== 'next') {
|
|
39
|
-
out.push(token)
|
|
40
|
-
commandStart = false
|
|
41
|
-
continue
|
|
40
|
+
out.push(token)
|
|
41
|
+
commandStart = false
|
|
42
|
+
continue
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
let end = index + 1
|
|
45
|
-
while (end < tokens.length && !SEPARATORS.has(tokens[end]!)) end += 1
|
|
46
|
-
const subcommand = tokens[index + 1]
|
|
47
|
-
const rest = tokens.slice(index + 2, end)
|
|
45
|
+
let end = index + 1
|
|
46
|
+
while (end < tokens.length && !SEPARATORS.has(tokens[end]!)) end += 1
|
|
47
|
+
const subcommand = tokens[index + 1]
|
|
48
|
+
const rest = tokens.slice(index + 2, end)
|
|
48
49
|
|
|
49
50
|
if (subcommand && MAPPED_SUBCOMMANDS.has(subcommand)) {
|
|
50
|
-
out.push('pnext', subcommand, ...translateFlags(subcommand, rest))
|
|
51
|
-
changed = true
|
|
51
|
+
out.push('pnext', subcommand, ...translateFlags(subcommand, rest))
|
|
52
|
+
changed = true
|
|
52
53
|
} else if (subcommand === 'lint') {
|
|
53
|
-
out.push(...tokens.slice(index, end))
|
|
54
|
-
reports.push('`next lint` left as-is — pnext has no lint command; run eslint directly.')
|
|
54
|
+
out.push(...tokens.slice(index, end))
|
|
55
|
+
reports.push('`next lint` left as-is — pnext has no lint command; run eslint directly.')
|
|
55
56
|
} else {
|
|
56
|
-
out.push(...tokens.slice(index, end))
|
|
57
|
-
const command = subcommand ? `next ${subcommand}` : 'next'
|
|
58
|
-
reports.push(`\`${command}\` has no pnext equivalent — left as-is.`)
|
|
57
|
+
out.push(...tokens.slice(index, end))
|
|
58
|
+
const command = subcommand ? `next ${subcommand}` : 'next'
|
|
59
|
+
reports.push(`\`${command}\` has no pnext equivalent — left as-is.`)
|
|
59
60
|
}
|
|
60
|
-
index = end - 1
|
|
61
|
-
commandStart = false
|
|
61
|
+
index = end - 1
|
|
62
|
+
commandStart = false
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
return { script: changed ? out.join(' ') : script, reports }
|
|
65
|
+
return { script: changed ? out.join(' ') : script, reports }
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
function translateFlags(subcommand: string, rest: string[]) {
|
|
68
|
-
const out: string[] = []
|
|
69
|
+
const out: string[] = []
|
|
69
70
|
for (const flag of rest) {
|
|
70
|
-
if (DROPPED_FLAGS.has(flag)) continue
|
|
71
|
+
if (DROPPED_FLAGS.has(flag)) continue
|
|
71
72
|
if (flag === '-p' && (subcommand === 'dev' || subcommand === 'start')) {
|
|
72
|
-
out.push('--port')
|
|
73
|
-
continue
|
|
73
|
+
out.push('--port')
|
|
74
|
+
continue
|
|
74
75
|
}
|
|
75
|
-
out.push(flag)
|
|
76
|
+
out.push(flag)
|
|
76
77
|
}
|
|
77
|
-
return out
|
|
78
|
+
return out
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
export async function migratePackageJson(
|
|
@@ -83,18 +84,18 @@ export async function migratePackageJson(
|
|
|
83
84
|
result: MigrationResult,
|
|
84
85
|
dryRun: boolean,
|
|
85
86
|
) {
|
|
86
|
-
const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined
|
|
87
|
+
const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined
|
|
87
88
|
if (scripts) {
|
|
88
|
-
const rewritten: string[] = []
|
|
89
|
+
const rewritten: string[] = []
|
|
89
90
|
for (const [name, value] of Object.entries(scripts)) {
|
|
90
|
-
if (typeof value !== 'string') continue
|
|
91
|
-
const { script, reports } = rewriteScript(value)
|
|
91
|
+
if (typeof value !== 'string') continue
|
|
92
|
+
const { script, reports } = rewriteScript(value)
|
|
92
93
|
if (script !== value) {
|
|
93
|
-
scripts[name] = script
|
|
94
|
-
rewritten.push(`${name}: ${value} → ${script}`)
|
|
94
|
+
scripts[name] = script
|
|
95
|
+
rewritten.push(`${name}: ${value} → ${script}`)
|
|
95
96
|
}
|
|
96
97
|
for (const detail of reports) {
|
|
97
|
-
result.reports.push({ title: `package.json script "${name}"`, detail })
|
|
98
|
+
result.reports.push({ title: `package.json script "${name}"`, detail })
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
if (rewritten.length > 0) {
|
|
@@ -102,82 +103,83 @@ export async function migratePackageJson(
|
|
|
102
103
|
file: 'package.json',
|
|
103
104
|
description: `scripts rewritten (${rewritten.length})`,
|
|
104
105
|
details: rewritten,
|
|
105
|
-
})
|
|
106
|
+
})
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
const dependencies = ensureObject(pkg, 'dependencies')
|
|
110
|
-
const devDependencies = ensureObject(pkg, 'devDependencies')
|
|
110
|
+
const dependencies = ensureObject(pkg, 'dependencies')
|
|
111
|
+
const devDependencies = ensureObject(pkg, 'devDependencies')
|
|
111
112
|
|
|
112
113
|
for (const [field, bucket] of [
|
|
113
114
|
['dependencies', dependencies],
|
|
114
115
|
['devDependencies', devDependencies],
|
|
115
116
|
] as const) {
|
|
116
117
|
if ('next' in bucket) {
|
|
117
|
-
delete bucket.next
|
|
118
|
+
delete bucket.next
|
|
118
119
|
result.edits.push({
|
|
119
120
|
file: 'package.json',
|
|
120
121
|
description: 'next removed',
|
|
121
122
|
details: [`next removed from ${field}`],
|
|
122
|
-
})
|
|
123
|
+
})
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
if (!('@wular/pnext' in devDependencies) && !('@wular/pnext' in dependencies)) {
|
|
126
|
-
|
|
127
|
+
const versionRange = pnextVersionRange()
|
|
128
|
+
devDependencies['@wular/pnext'] = versionRange
|
|
127
129
|
result.edits.push({
|
|
128
130
|
file: 'package.json',
|
|
129
131
|
description: '@wular/pnext added',
|
|
130
|
-
details: [
|
|
131
|
-
})
|
|
132
|
+
details: [`devDependencies: @wular/pnext ${versionRange}`],
|
|
133
|
+
})
|
|
132
134
|
}
|
|
133
135
|
if (!('preact' in dependencies) && !('preact' in devDependencies)) {
|
|
134
|
-
dependencies.preact = '^10'
|
|
136
|
+
dependencies.preact = '^10'
|
|
135
137
|
result.edits.push({
|
|
136
138
|
file: 'package.json',
|
|
137
139
|
description: 'preact added',
|
|
138
140
|
details: ['dependencies: preact ^10 (react/react-dom kept — compat aliases them)'],
|
|
139
|
-
})
|
|
141
|
+
})
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
const leftovers = [...Object.keys(dependencies), ...Object.keys(devDependencies)].filter(
|
|
143
145
|
name => name === 'eslint-config-next' || name.startsWith('@next/'),
|
|
144
|
-
)
|
|
146
|
+
)
|
|
145
147
|
if (leftovers.length > 0) {
|
|
146
148
|
result.reports.push({
|
|
147
149
|
title: 'Next-specific packages still installed',
|
|
148
150
|
detail: 'Optional cleanup — these are unused under pnext. See reference/compat.md.',
|
|
149
151
|
files: leftovers,
|
|
150
|
-
})
|
|
152
|
+
})
|
|
151
153
|
}
|
|
152
154
|
|
|
153
|
-
pruneEmpty(pkg, 'dependencies')
|
|
154
|
-
pruneEmpty(pkg, 'devDependencies')
|
|
155
|
+
pruneEmpty(pkg, 'dependencies')
|
|
156
|
+
pruneEmpty(pkg, 'devDependencies')
|
|
155
157
|
|
|
156
158
|
if (!dryRun) {
|
|
157
|
-
await writeFile(path.join(root, 'package.json'), `${JSON.stringify(pkg, null, 2)}\n`)
|
|
159
|
+
await writeFile(path.join(root, 'package.json'), `${JSON.stringify(pkg, null, 2)}\n`)
|
|
158
160
|
}
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
export async function readPackageJson(root: string): Promise<Json | undefined> {
|
|
162
164
|
try {
|
|
163
|
-
const parsed = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')) as unknown
|
|
164
|
-
return isObject(parsed) ? parsed : undefined
|
|
165
|
+
const parsed = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')) as unknown
|
|
166
|
+
return isObject(parsed) ? parsed : undefined
|
|
165
167
|
} catch {
|
|
166
|
-
return undefined
|
|
168
|
+
return undefined
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
function isObject(value: unknown): value is Json {
|
|
171
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
173
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
// Create the bucket in place so an existing key keeps its position.
|
|
175
177
|
function ensureObject(pkg: Json, key: string): Json {
|
|
176
|
-
if (!isObject(pkg[key])) pkg[key] = {}
|
|
177
|
-
return pkg[key] as Json
|
|
178
|
+
if (!isObject(pkg[key])) pkg[key] = {}
|
|
179
|
+
return pkg[key] as Json
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
function pruneEmpty(pkg: Json, key: string) {
|
|
181
|
-
const value = pkg[key]
|
|
182
|
-
if (isObject(value) && Object.keys(value).length === 0) delete pkg[key]
|
|
183
|
+
const value = pkg[key]
|
|
184
|
+
if (isObject(value) && Object.keys(value).length === 0) delete pkg[key]
|
|
183
185
|
}
|
|
@@ -3,78 +3,77 @@
|
|
|
3
3
|
// hand. The body of the output is identical under --dry-run — only the header
|
|
4
4
|
// says whether anything was written.
|
|
5
5
|
|
|
6
|
-
import { bold, cyan, dim, green } from '../../utils/ansi'
|
|
6
|
+
import { bold, cyan, dim, green } from '../../utils/ansi'
|
|
7
7
|
|
|
8
8
|
/** Amber for warnings — ansi.ts has no yellow, so hand-roll the same shape. */
|
|
9
|
-
const amber = (value: string) =>
|
|
10
|
-
process.stdout.isTTY ? `\x1b[38;5;214m${value}\x1b[39m` : value;
|
|
9
|
+
const amber = (value: string) => (process.stdout.isTTY ? `\x1b[38;5;214m${value}\x1b[39m` : value)
|
|
11
10
|
|
|
12
11
|
export interface Edit {
|
|
13
|
-
file: string
|
|
12
|
+
file: string
|
|
14
13
|
/** Short phrase joined into the file's summary line. */
|
|
15
|
-
description: string
|
|
14
|
+
description: string
|
|
16
15
|
/** Dim lines printed under the summary. */
|
|
17
|
-
details?: string[]
|
|
16
|
+
details?: string[]
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export interface ReportItem {
|
|
21
|
-
title: string
|
|
22
|
-
detail: string
|
|
23
|
-
files?: string[]
|
|
20
|
+
title: string
|
|
21
|
+
detail: string
|
|
22
|
+
files?: string[]
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
export interface MigrationResult {
|
|
27
|
-
edits: Edit[]
|
|
28
|
-
reports: ReportItem[]
|
|
26
|
+
edits: Edit[]
|
|
27
|
+
reports: ReportItem[]
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export function emptyResult(): MigrationResult {
|
|
32
|
-
return { edits: [], reports: [] }
|
|
31
|
+
return { edits: [], reports: [] }
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
export function printHeader(root: string, dryRun: boolean) {
|
|
36
|
-
const suffix = dryRun ? 'dry run, nothing will be written' : root
|
|
37
|
-
console.log(`\n${cyan('▲')} ${bold('pnext migrate')} ${dim(`— ${suffix}`)}`)
|
|
35
|
+
const suffix = dryRun ? 'dry run, nothing will be written' : root
|
|
36
|
+
console.log(`\n${cyan('▲')} ${bold('pnext migrate')} ${dim(`— ${suffix}`)}`)
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
export function printResult(result: MigrationResult, options: { install: string }) {
|
|
41
|
-
const lines: string[] = []
|
|
40
|
+
const lines: string[] = []
|
|
42
41
|
|
|
43
|
-
lines.push(`\n${bold('Changes')}`)
|
|
42
|
+
lines.push(`\n${bold('Changes')}`)
|
|
44
43
|
if (result.edits.length === 0) {
|
|
45
|
-
lines.push(` ${dim('nothing to change')}`)
|
|
44
|
+
lines.push(` ${dim('nothing to change')}`)
|
|
46
45
|
}
|
|
47
46
|
for (const [file, edits] of groupByFile(result.edits)) {
|
|
48
47
|
lines.push(
|
|
49
48
|
`${green('✓')} ${bold(file)} ${dim(`— ${edits.map(edit => edit.description).join(', ')}`)}`,
|
|
50
|
-
)
|
|
49
|
+
)
|
|
51
50
|
for (const edit of edits) {
|
|
52
|
-
for (const detail of edit.details ?? []) lines.push(` ${dim(detail)}`)
|
|
51
|
+
for (const detail of edit.details ?? []) lines.push(` ${dim(detail)}`)
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
lines.push(`\n${bold('Review')}${result.reports.length > 0 ? ` (${result.reports.length})` : ''}`)
|
|
55
|
+
lines.push(`\n${bold('Review')}${result.reports.length > 0 ? ` (${result.reports.length})` : ''}`)
|
|
57
56
|
if (result.reports.length === 0) {
|
|
58
|
-
lines.push(` ${dim('nothing flagged')}`)
|
|
57
|
+
lines.push(` ${dim('nothing flagged')}`)
|
|
59
58
|
}
|
|
60
59
|
for (const item of result.reports) {
|
|
61
|
-
lines.push(`${amber('!')} ${bold(item.title)}`)
|
|
62
|
-
lines.push(` ${dim(item.detail)}`)
|
|
63
|
-
for (const file of item.files ?? []) lines.push(` ${dim(`· ${file}`)}`)
|
|
60
|
+
lines.push(`${amber('!')} ${bold(item.title)}`)
|
|
61
|
+
lines.push(` ${dim(item.detail)}`)
|
|
62
|
+
for (const file of item.files ?? []) lines.push(` ${dim(`· ${file}`)}`)
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
lines.push(`\n${bold('Next steps')}`)
|
|
67
|
-
lines.push(` Run ${cyan(options.install)} to install the new dependencies.`)
|
|
68
|
-
lines.push(` ${cyan('pnext dev')} to start the app.`)
|
|
69
|
-
console.log(lines.join('\n'))
|
|
65
|
+
lines.push(`\n${bold('Next steps')}`)
|
|
66
|
+
lines.push(` Run ${cyan(options.install)} to install the new dependencies.`)
|
|
67
|
+
lines.push(` ${cyan('pnext dev')} to start the app.`)
|
|
68
|
+
console.log(lines.join('\n'))
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
function groupByFile(edits: Edit[]) {
|
|
73
|
-
const grouped = new Map<string, Edit[]>()
|
|
72
|
+
const grouped = new Map<string, Edit[]>()
|
|
74
73
|
for (const edit of edits) {
|
|
75
|
-
const bucket = grouped.get(edit.file)
|
|
76
|
-
if (bucket) bucket.push(edit)
|
|
77
|
-
else grouped.set(edit.file, [edit])
|
|
74
|
+
const bucket = grouped.get(edit.file)
|
|
75
|
+
if (bucket) bucket.push(edit)
|
|
76
|
+
else grouped.set(edit.file, [edit])
|
|
78
77
|
}
|
|
79
|
-
return grouped
|
|
78
|
+
return grouped
|
|
80
79
|
}
|