@wular/pnext 0.0.3 → 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 -1961
- 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 -1887
- 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} +152 -143
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +442 -186
- 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 +833 -848
- 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
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { networkInterfaces } from 'node:os'
|
|
2
|
-
import { bold, cyan, dim, green } from '
|
|
1
|
+
import { networkInterfaces } from 'node:os'
|
|
2
|
+
import { bold, cyan, dim, green } from '../../utils/ansi'
|
|
3
3
|
|
|
4
4
|
interface ReadyBanner {
|
|
5
5
|
/** Short mode label shown after the mark, e.g. "dev" or "production". */
|
|
6
|
-
mode: string
|
|
6
|
+
mode: string
|
|
7
7
|
/** The bind hostname, used to derive Local/Network URLs. */
|
|
8
|
-
hostname: string
|
|
9
|
-
port: number
|
|
8
|
+
hostname: string
|
|
9
|
+
port: number
|
|
10
10
|
/** Milliseconds to boot, when known (dev server startup). */
|
|
11
|
-
elapsedMs?: number
|
|
11
|
+
elapsedMs?: number
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -18,39 +18,39 @@ interface ReadyBanner {
|
|
|
18
18
|
*/
|
|
19
19
|
export function browserHost(hostname: string) {
|
|
20
20
|
// IPv6 binds present their bracketed loopback (Next prints http://[::1]:port).
|
|
21
|
-
if (hostname === '::' || hostname === '::1') return '[::1]'
|
|
22
|
-
if (['0.0.0.0', '127.0.0.1'].includes(hostname)) return 'localhost'
|
|
23
|
-
return hostname
|
|
21
|
+
if (hostname === '::' || hostname === '::1') return '[::1]'
|
|
22
|
+
if (['0.0.0.0', '127.0.0.1'].includes(hostname)) return 'localhost'
|
|
23
|
+
return hostname
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/** Print a Next.js-style "server ready" banner with local and network URLs. */
|
|
27
27
|
export function printServerReady({ mode, hostname, port, elapsedMs }: ReadyBanner) {
|
|
28
|
-
const rows: [string, string][] = [['Local:', cyan(`http://${browserHost(hostname)}:${port}`)]]
|
|
28
|
+
const rows: [string, string][] = [['Local:', cyan(`http://${browserHost(hostname)}:${port}`)]]
|
|
29
29
|
|
|
30
30
|
// When bound to all interfaces, surface the LAN address so it's reachable
|
|
31
31
|
// from other devices (phones, other machines) without hunting for the IP.
|
|
32
32
|
// Next prints the bracketed wildcard itself for IPv6 (`http://[::]:port`).
|
|
33
|
-
const lan = hostname === '::' ? '[::]' : wildcard(hostname) ? lanAddress() : undefined
|
|
34
|
-
if (lan) rows.push(['Network:', cyan(`http://${lan}:${port}`)])
|
|
33
|
+
const lan = hostname === '::' ? '[::]' : wildcard(hostname) ? lanAddress() : undefined
|
|
34
|
+
if (lan) rows.push(['Network:', cyan(`http://${lan}:${port}`)])
|
|
35
35
|
|
|
36
36
|
const ready =
|
|
37
37
|
elapsedMs === undefined
|
|
38
38
|
? `${green('✓')} ${bold('Ready')}`
|
|
39
|
-
: `${green('✓')} ${bold('Ready')} ${dim(`in ${Math.round(elapsedMs)}ms`)}
|
|
39
|
+
: `${green('✓')} ${bold('Ready')} ${dim(`in ${Math.round(elapsedMs)}ms`)}`
|
|
40
40
|
|
|
41
|
-
const pad = Math.max(...rows.map(([label]) => label.length))
|
|
42
|
-
console.log('')
|
|
43
|
-
console.log(`${cyan('▲')} ${bold('pnext')} ${dim(mode)}`)
|
|
41
|
+
const pad = Math.max(...rows.map(([label]) => label.length))
|
|
42
|
+
console.log('')
|
|
43
|
+
console.log(`${cyan('▲')} ${bold('pnext')} ${dim(mode)}`)
|
|
44
44
|
for (const [label, value] of rows) {
|
|
45
|
-
console.log(` ${dim('-')} ${dim(label.padEnd(pad))} ${value}`)
|
|
45
|
+
console.log(` ${dim('-')} ${dim(label.padEnd(pad))} ${value}`)
|
|
46
46
|
}
|
|
47
|
-
console.log('')
|
|
48
|
-
console.log(ready)
|
|
49
|
-
console.log('')
|
|
47
|
+
console.log('')
|
|
48
|
+
console.log(ready)
|
|
49
|
+
console.log('')
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function wildcard(hostname: string) {
|
|
53
|
-
return hostname === '0.0.0.0' || hostname === '::'
|
|
53
|
+
return hostname === '0.0.0.0' || hostname === '::'
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -63,67 +63,67 @@ export async function ensurePortFree(
|
|
|
63
63
|
hostname: string,
|
|
64
64
|
options: { attempts?: number; delayMs?: number } = {},
|
|
65
65
|
) {
|
|
66
|
-
const attempts = options.attempts ?? 1
|
|
67
|
-
const delayMs = options.delayMs ?? 300
|
|
66
|
+
const attempts = options.attempts ?? 1
|
|
67
|
+
const delayMs = options.delayMs ?? 300
|
|
68
68
|
const candidates =
|
|
69
|
-
wildcard(hostname) || hostname === 'localhost' ? ['127.0.0.1', '::1'] : [hostname]
|
|
69
|
+
wildcard(hostname) || hostname === 'localhost' ? ['127.0.0.1', '::1'] : [hostname]
|
|
70
70
|
|
|
71
71
|
for (const candidate of candidates) {
|
|
72
|
-
let inUse = await portInUse(candidate, port)
|
|
72
|
+
let inUse = await portInUse(candidate, port)
|
|
73
73
|
// A respawning server may race its predecessor's shutdown; give it a beat.
|
|
74
74
|
for (let attempt = 1; inUse && attempt < attempts; attempt += 1) {
|
|
75
|
-
await new Promise(resolve => setTimeout(resolve, delayMs))
|
|
76
|
-
inUse = await portInUse(candidate, port)
|
|
75
|
+
await new Promise(resolve => setTimeout(resolve, delayMs))
|
|
76
|
+
inUse = await portInUse(candidate, port)
|
|
77
77
|
}
|
|
78
78
|
if (inUse) {
|
|
79
79
|
throw new Error(
|
|
80
80
|
`Port ${port} is already in use on ${candidate} (another pnext dev/start or process). ` +
|
|
81
81
|
`Stop it or pass --port. To find it:` +
|
|
82
82
|
` lsof -nP -iTCP:${port} -sTCP:LISTEN`,
|
|
83
|
-
)
|
|
83
|
+
)
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
function portInUse(hostname: string, port: number) {
|
|
89
89
|
return new Promise<boolean>(resolve => {
|
|
90
|
-
const timer = setTimeout(() => resolve(false), 300)
|
|
90
|
+
const timer = setTimeout(() => resolve(false), 300)
|
|
91
91
|
Bun.connect({
|
|
92
92
|
hostname,
|
|
93
93
|
port,
|
|
94
94
|
socket: {
|
|
95
95
|
open(socket) {
|
|
96
|
-
clearTimeout(timer)
|
|
97
|
-
socket.end()
|
|
98
|
-
resolve(true)
|
|
96
|
+
clearTimeout(timer)
|
|
97
|
+
socket.end()
|
|
98
|
+
resolve(true)
|
|
99
99
|
},
|
|
100
100
|
data() {
|
|
101
101
|
// Only connectability matters; any payload is ignored.
|
|
102
102
|
},
|
|
103
103
|
connectError() {
|
|
104
|
-
clearTimeout(timer)
|
|
105
|
-
resolve(false)
|
|
104
|
+
clearTimeout(timer)
|
|
105
|
+
resolve(false)
|
|
106
106
|
},
|
|
107
107
|
error() {
|
|
108
|
-
clearTimeout(timer)
|
|
109
|
-
resolve(false)
|
|
108
|
+
clearTimeout(timer)
|
|
109
|
+
resolve(false)
|
|
110
110
|
},
|
|
111
111
|
},
|
|
112
112
|
}).catch(() => {
|
|
113
|
-
clearTimeout(timer)
|
|
114
|
-
resolve(false)
|
|
115
|
-
})
|
|
116
|
-
})
|
|
113
|
+
clearTimeout(timer)
|
|
114
|
+
resolve(false)
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/** First non-internal IPv4 address, or undefined when offline. */
|
|
120
120
|
function lanAddress() {
|
|
121
121
|
for (const addresses of Object.values(networkInterfaces())) {
|
|
122
122
|
for (const address of addresses ?? []) {
|
|
123
|
-
if (address.family === 'IPv4' && !address.internal) return address.address
|
|
123
|
+
if (address.family === 'IPv4' && !address.internal) return address.address
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
return undefined
|
|
126
|
+
return undefined
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
@@ -136,12 +136,12 @@ function lanAddress() {
|
|
|
136
136
|
*/
|
|
137
137
|
export function openBrowser(url: string) {
|
|
138
138
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
139
|
-
const browser = process.env.BROWSER
|
|
139
|
+
const browser = process.env.BROWSER
|
|
140
140
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
141
|
-
if (browser === 'none' || process.env.CI) return
|
|
141
|
+
if (browser === 'none' || process.env.CI) return
|
|
142
142
|
|
|
143
143
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
144
|
-
const browserArgs = process.env.BROWSER_ARGS?.split(/\s+/).filter(Boolean) ?? []
|
|
144
|
+
const browserArgs = process.env.BROWSER_ARGS?.split(/\s+/).filter(Boolean) ?? []
|
|
145
145
|
const command = browser
|
|
146
146
|
? process.platform === 'darwin'
|
|
147
147
|
? ['open', '-a', browser, ...browserArgs, url]
|
|
@@ -150,10 +150,10 @@ export function openBrowser(url: string) {
|
|
|
150
150
|
? ['open', url]
|
|
151
151
|
: process.platform === 'win32'
|
|
152
152
|
? ['cmd', '/c', 'start', '', url]
|
|
153
|
-
: ['xdg-open', url]
|
|
153
|
+
: ['xdg-open', url]
|
|
154
154
|
|
|
155
155
|
try {
|
|
156
|
-
Bun.spawn(command, { stdout: 'ignore', stderr: 'ignore', stdin: 'ignore' }).unref()
|
|
156
|
+
Bun.spawn(command, { stdout: 'ignore', stderr: 'ignore', stdin: 'ignore' }).unref()
|
|
157
157
|
} catch {
|
|
158
158
|
// ignore: opening a browser is a convenience, not a requirement
|
|
159
159
|
}
|
package/src/cli/start.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `pnext start`: the listen path only. Everything a request needs — renderer,
|
|
3
|
-
* routing, server runtime — lives in `./
|
|
3
|
+
* routing, server runtime — lives in `./serve/pipeline` and is imported
|
|
4
4
|
* dynamically once the port is bound, so neither the listen syscall nor the
|
|
5
5
|
* ready banner waits on parsing it (it is ~700 KB of the prebundled entry).
|
|
6
6
|
*/
|
|
7
|
-
import { readFile } from 'node:fs/promises'
|
|
8
|
-
import path from 'node:path'
|
|
9
|
-
import { loadConfig } from '../config'
|
|
10
|
-
import type { ResolvedConfig } from '../config'
|
|
11
|
-
import { bootstrapCompat } from '../compat-bootstrap'
|
|
12
|
-
import { getBuildExtensions } from '../extensions'
|
|
13
|
-
import { drainWorkUnits } from '../request/context'
|
|
14
|
-
import { markErrorLogged } from '../utils/error-log'
|
|
15
|
-
import { isPostpone } from '../
|
|
16
|
-
import { browserHost, ensurePortFree, openBrowser, printServerReady } from './serve
|
|
17
|
-
import type { BuildManifest } from '../types'
|
|
7
|
+
import { readFile } from 'node:fs/promises'
|
|
8
|
+
import path from 'node:path'
|
|
9
|
+
import { loadConfig } from '../config'
|
|
10
|
+
import type { ResolvedConfig } from '../config'
|
|
11
|
+
import { bootstrapCompat } from '../compat-bootstrap'
|
|
12
|
+
import { getBuildExtensions } from '../extensions'
|
|
13
|
+
import { drainWorkUnits } from '../request/context'
|
|
14
|
+
import { markErrorLogged } from '../utils/error-log'
|
|
15
|
+
import { isPostpone } from '../render/postpone'
|
|
16
|
+
import { browserHost, ensurePortFree, openBrowser, printServerReady } from './serve/ui'
|
|
17
|
+
import type { BuildManifest } from '../types'
|
|
18
18
|
|
|
19
19
|
interface StartOptions {
|
|
20
|
-
root?: string
|
|
21
|
-
port?: number
|
|
22
|
-
hostname?: string
|
|
20
|
+
root?: string
|
|
21
|
+
port?: number
|
|
22
|
+
hostname?: string
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
type RequestHandler = (request: Request) => Promise<Response
|
|
25
|
+
type RequestHandler = (request: Request) => Promise<Response>
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* The production request handler `pnext start` serves with. Exposed on its own
|
|
@@ -32,59 +32,58 @@ type RequestHandler = (request: Request) => Promise<Response>;
|
|
|
32
32
|
export async function createRequestHandler(
|
|
33
33
|
options: { root?: string; config?: ResolvedConfig; manifest?: BuildManifest } = {},
|
|
34
34
|
): Promise<RequestHandler> {
|
|
35
|
-
const { createRequestHandler: create } = await import('./
|
|
36
|
-
return create(options)
|
|
35
|
+
const { createRequestHandler: create } = await import('./serve/pipeline')
|
|
36
|
+
return create(options)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export async function maybeBuiltFile(
|
|
40
|
-
...args: Parameters<typeof import('./
|
|
40
|
+
...args: Parameters<typeof import('./serve/pipeline').maybeBuiltFile>
|
|
41
41
|
) {
|
|
42
|
-
const { maybeBuiltFile: impl } = await import('./
|
|
43
|
-
return impl(...args)
|
|
42
|
+
const { maybeBuiltFile: impl } = await import('./serve/pipeline')
|
|
43
|
+
return impl(...args)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export async function start(options: StartOptions = {}) {
|
|
47
|
-
const startedAt = Date.now()
|
|
48
|
-
const port = options.port ?? 3000
|
|
49
|
-
const hostname = options.hostname ?? 'localhost'
|
|
47
|
+
const startedAt = Date.now()
|
|
48
|
+
const port = options.port ?? 3000
|
|
49
|
+
const hostname = options.hostname ?? 'localhost'
|
|
50
50
|
// Export builds are not served by a production start (Next throws). Standalone builds still serve -
|
|
51
51
|
// Next only WARNS, pointing at the standalone launcher, and the launcher re-execs this path with
|
|
52
52
|
// `__NEXT_PRIVATE_STANDALONE_CONFIG` set to suppress that warning. Handle both before binding a
|
|
53
53
|
// port, matching Next's messages.
|
|
54
|
-
const config = await guardUnservableOutputMode(options.root)
|
|
54
|
+
const config = await guardUnservableOutputMode(options.root)
|
|
55
55
|
const manifest = JSON.parse(
|
|
56
56
|
await readFile(path.join(config.outPath, 'manifest.json'), 'utf8'),
|
|
57
|
-
) as BuildManifest
|
|
58
|
-
await ensurePortFree(port, hostname)
|
|
57
|
+
) as BuildManifest
|
|
58
|
+
await ensurePortFree(port, hostname)
|
|
59
59
|
|
|
60
60
|
// The pipeline import starts right after listen; a request that beats it
|
|
61
61
|
// simply awaits the same promise instead of racing a second import.
|
|
62
|
-
let handler: RequestHandler | undefined
|
|
63
|
-
let pending: Promise<RequestHandler> | undefined
|
|
62
|
+
let handler: RequestHandler | undefined
|
|
63
|
+
let pending: Promise<RequestHandler> | undefined
|
|
64
64
|
const ensureHandler = () =>
|
|
65
65
|
(pending ??= createRequestHandler({ root: options.root, config, manifest }).then(ready => {
|
|
66
|
-
handler = ready
|
|
67
|
-
return ready
|
|
68
|
-
}))
|
|
66
|
+
handler = ready
|
|
67
|
+
return ready
|
|
68
|
+
}))
|
|
69
69
|
|
|
70
70
|
const server = Bun.serve({
|
|
71
71
|
hostname,
|
|
72
72
|
port,
|
|
73
|
-
fetch: request =>
|
|
74
|
-
|
|
75
|
-
});
|
|
73
|
+
fetch: request => (handler ? handler(request) : ensureHandler().then(ready => ready(request))),
|
|
74
|
+
})
|
|
76
75
|
|
|
77
76
|
printServerReady({
|
|
78
77
|
mode: 'production',
|
|
79
78
|
hostname,
|
|
80
79
|
port: server.port ?? port,
|
|
81
80
|
elapsedMs: Date.now() - startedAt,
|
|
82
|
-
})
|
|
83
|
-
void ensureHandler().catch(() => undefined)
|
|
84
|
-
openBrowser(`http://${browserHost(hostname)}:${server.port ?? port}`)
|
|
85
|
-
installShutdownHandlers(server)
|
|
86
|
-
installProcessErrorHandlers()
|
|
87
|
-
return server
|
|
81
|
+
})
|
|
82
|
+
void ensureHandler().catch(() => undefined) // a real failure resurfaces on the request
|
|
83
|
+
openBrowser(`http://${browserHost(hostname)}:${server.port ?? port}`)
|
|
84
|
+
installShutdownHandlers(server)
|
|
85
|
+
installProcessErrorHandlers()
|
|
86
|
+
return server
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
// Next deliberately overrides the runtime's fatal-by-default handling of unhandled rejections and
|
|
@@ -97,16 +96,16 @@ export async function start(options: StartOptions = {}) {
|
|
|
97
96
|
// render site from being printed twice.
|
|
98
97
|
function installProcessErrorHandlers(): void {
|
|
99
98
|
const globalWithFlag = globalThis as typeof globalThis & {
|
|
100
|
-
__pnextProcessErrorHandlers?: boolean
|
|
101
|
-
}
|
|
102
|
-
if (globalWithFlag.__pnextProcessErrorHandlers) return
|
|
103
|
-
globalWithFlag.__pnextProcessErrorHandlers = true
|
|
99
|
+
__pnextProcessErrorHandlers?: boolean
|
|
100
|
+
}
|
|
101
|
+
if (globalWithFlag.__pnextProcessErrorHandlers) return
|
|
102
|
+
globalWithFlag.__pnextProcessErrorHandlers = true
|
|
104
103
|
const report = (reason: unknown) => {
|
|
105
|
-
if (isPostpone(reason)) return
|
|
106
|
-
if (markErrorLogged(reason)) console.error(reason)
|
|
107
|
-
}
|
|
108
|
-
process.on('unhandledRejection', report)
|
|
109
|
-
process.on('uncaughtException', report)
|
|
104
|
+
if (isPostpone(reason)) return
|
|
105
|
+
if (markErrorLogged(reason)) console.error(reason)
|
|
106
|
+
}
|
|
107
|
+
process.on('unhandledRejection', report)
|
|
108
|
+
process.on('uncaughtException', report)
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
// Next's output-mode handling on start: an export build throws (fatal - it is unservable), while a
|
|
@@ -114,24 +113,24 @@ function installProcessErrorHandlers(): void {
|
|
|
114
113
|
// `__NEXT_PRIVATE_STANDALONE_CONFIG` set. pnext mirrors that: load the compat config, read the output
|
|
115
114
|
// mode from the build-compat registry, and reproduce Next's exact messages.
|
|
116
115
|
async function guardUnservableOutputMode(root?: string): Promise<ResolvedConfig> {
|
|
117
|
-
const config = await loadConfig(root)
|
|
118
|
-
await bootstrapCompat(config)
|
|
119
|
-
const mode = getBuildExtensions().compat.nextOutputMode()
|
|
116
|
+
const config = await loadConfig(root)
|
|
117
|
+
await bootstrapCompat(config)
|
|
118
|
+
const mode = getBuildExtensions().compat.nextOutputMode()
|
|
120
119
|
if (mode === 'export') {
|
|
121
120
|
console.error(
|
|
122
121
|
'"next start" does not work with "output: export" configuration. ' +
|
|
123
122
|
'Use "npx serve@latest out" instead.',
|
|
124
|
-
)
|
|
125
|
-
process.exit(1)
|
|
123
|
+
)
|
|
124
|
+
process.exit(1)
|
|
126
125
|
}
|
|
127
126
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
128
127
|
if (mode === 'standalone' && !process.env.__NEXT_PRIVATE_STANDALONE_CONFIG) {
|
|
129
128
|
console.warn(
|
|
130
129
|
'"next start" does not work with "output: standalone" configuration. ' +
|
|
131
130
|
'Use "node .next/standalone/server.js" instead.',
|
|
132
|
-
)
|
|
131
|
+
)
|
|
133
132
|
}
|
|
134
|
-
return config
|
|
133
|
+
return config
|
|
135
134
|
}
|
|
136
135
|
|
|
137
136
|
// Graceful stop: quit accepting connections, wait for in-flight after() flushes (bounded), then exit
|
|
@@ -140,14 +139,14 @@ async function guardUnservableOutputMode(root?: string): Promise<ResolvedConfig>
|
|
|
140
139
|
// server receives it twice - with `once` the second delivery hit the default disposition and killed
|
|
141
140
|
// the process mid-drain.
|
|
142
141
|
function installShutdownHandlers(server: { stop(closeActiveConnections?: boolean): void }) {
|
|
143
|
-
let shuttingDown = false
|
|
142
|
+
let shuttingDown = false
|
|
144
143
|
const shutdown = async () => {
|
|
145
|
-
if (shuttingDown) return
|
|
146
|
-
shuttingDown = true
|
|
147
|
-
server.stop()
|
|
148
|
-
await drainWorkUnits()
|
|
149
|
-
process.exit(0)
|
|
150
|
-
}
|
|
151
|
-
process.on('SIGINT', shutdown)
|
|
152
|
-
process.on('SIGTERM', shutdown)
|
|
144
|
+
if (shuttingDown) return
|
|
145
|
+
shuttingDown = true
|
|
146
|
+
server.stop()
|
|
147
|
+
await drainWorkUnits()
|
|
148
|
+
process.exit(0)
|
|
149
|
+
}
|
|
150
|
+
process.on('SIGINT', shutdown)
|
|
151
|
+
process.on('SIGTERM', shutdown)
|
|
153
152
|
}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
import { readFile, rm, writeFile } from 'node:fs/promises'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import type { ResolvedConfig } from '
|
|
5
|
-
import { loadConfig } from '
|
|
6
|
-
import { ensureDir, toPosixPath } from '
|
|
7
|
-
import { scanRoutes } from '
|
|
8
|
-
import type { RouteManifestEntry } from '
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import { readFile, rm, writeFile } from 'node:fs/promises'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import type { ResolvedConfig } from '../config'
|
|
5
|
+
import { loadConfig } from '../config'
|
|
6
|
+
import { ensureDir, toPosixPath } from '../utils/fs'
|
|
7
|
+
import { scanRoutes } from '../routing/routes'
|
|
8
|
+
import type { RouteManifestEntry } from '../types'
|
|
9
9
|
|
|
10
10
|
export interface TypegenResult {
|
|
11
|
-
file: string
|
|
12
|
-
routes: number
|
|
13
|
-
checks: number
|
|
14
|
-
aliases: number
|
|
11
|
+
file: string
|
|
12
|
+
routes: number
|
|
13
|
+
checks: number
|
|
14
|
+
aliases: number
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export async function typegenProject(root?: string): Promise<TypegenResult> {
|
|
18
|
-
const config = await loadConfig(root)
|
|
19
|
-
const routes = await scanRoutes(config.appPath)
|
|
20
|
-
return writeTypegen(config, routes)
|
|
18
|
+
const config = await loadConfig(root)
|
|
19
|
+
const routes = await scanRoutes(config.appPath)
|
|
20
|
+
return writeTypegen(config, routes)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export async function writeTypegen(
|
|
24
24
|
config: ResolvedConfig,
|
|
25
25
|
allRoutes: RouteManifestEntry[],
|
|
26
26
|
): Promise<TypegenResult> {
|
|
27
|
-
const routes = allRoutes.filter(route => !route.interception && !route.synthetic)
|
|
28
|
-
const file = path.join(config.typesPath, 'pnext.gen.d.ts')
|
|
29
|
-
const source = typegenSource(routes)
|
|
30
|
-
await writeIfChanged(file, source)
|
|
31
|
-
const aliases = await writeRouteAliases(config, routes)
|
|
32
|
-
const checks = await writeChecks(config, routes)
|
|
33
|
-
return { file, routes: routes.length, checks, aliases }
|
|
27
|
+
const routes = allRoutes.filter(route => !route.interception && !route.synthetic)
|
|
28
|
+
const file = path.join(config.typesPath, 'pnext.gen.d.ts')
|
|
29
|
+
const source = typegenSource(routes)
|
|
30
|
+
await writeIfChanged(file, source)
|
|
31
|
+
const aliases = await writeRouteAliases(config, routes)
|
|
32
|
+
const checks = await writeChecks(config, routes)
|
|
33
|
+
return { file, routes: routes.length, checks, aliases }
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function typegenSource(routes: RouteManifestEntry[]) {
|
|
37
|
-
const entries = routes.map(route => routeEntry(route)).join('\n')
|
|
37
|
+
const entries = routes.map(route => routeEntry(route)).join('\n')
|
|
38
38
|
|
|
39
39
|
return `// This file is generated by PNext. Do not edit.
|
|
40
40
|
import '@wular/pnext';
|
|
@@ -44,7 +44,7 @@ declare module '@wular/pnext' {
|
|
|
44
44
|
${entries}
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
`
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function routeEntry(route: RouteManifestEntry) {
|
|
@@ -53,41 +53,41 @@ function routeEntry(route: RouteManifestEntry) {
|
|
|
53
53
|
params: ${paramsType(route)};
|
|
54
54
|
mode: '${route.mode}';
|
|
55
55
|
hydrated: ${route.client ? 'true' : 'false'};
|
|
56
|
-
}
|
|
56
|
+
};`
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
async function writeChecks(config: ResolvedConfig, routes: RouteManifestEntry[]) {
|
|
60
|
-
const checksDir = path.join(config.typesPath, 'checks')
|
|
61
|
-
await rm(checksDir, { recursive: true, force: true })
|
|
62
|
-
await ensureDir(checksDir)
|
|
60
|
+
const checksDir = path.join(config.typesPath, 'checks')
|
|
61
|
+
await rm(checksDir, { recursive: true, force: true })
|
|
62
|
+
await ensureDir(checksDir)
|
|
63
63
|
|
|
64
64
|
await Promise.all(
|
|
65
65
|
routes.map(route => {
|
|
66
|
-
const file = path.join(checksDir, `${route.id}.check.ts`)
|
|
67
|
-
return writeIfChanged(file, checkSource(checksDir, route))
|
|
66
|
+
const file = path.join(checksDir, `${route.id}.check.ts`)
|
|
67
|
+
return writeIfChanged(file, checkSource(checksDir, route))
|
|
68
68
|
}),
|
|
69
|
-
)
|
|
69
|
+
)
|
|
70
70
|
|
|
71
|
-
return routes.length
|
|
71
|
+
return routes.length
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
async function writeRouteAliases(config: ResolvedConfig, routes: RouteManifestEntry[]) {
|
|
75
|
-
const aliasesDir = path.join(config.typesPath, 'app')
|
|
76
|
-
await rm(aliasesDir, { recursive: true, force: true })
|
|
77
|
-
await ensureDir(aliasesDir)
|
|
75
|
+
const aliasesDir = path.join(config.typesPath, 'app')
|
|
76
|
+
await rm(aliasesDir, { recursive: true, force: true })
|
|
77
|
+
await ensureDir(aliasesDir)
|
|
78
78
|
|
|
79
79
|
await Promise.all(
|
|
80
80
|
routes.map(route => {
|
|
81
|
-
const file = path.join(aliasesDir, `${routeAliasPath(config, route)}.d.ts`)
|
|
82
|
-
return writeIfChanged(file, routeAliasSource(route))
|
|
81
|
+
const file = path.join(aliasesDir, `${routeAliasPath(config, route)}.d.ts`)
|
|
82
|
+
return writeIfChanged(file, routeAliasSource(route))
|
|
83
83
|
}),
|
|
84
|
-
)
|
|
84
|
+
)
|
|
85
85
|
|
|
86
|
-
return routes.length
|
|
86
|
+
return routes.length
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
function routeAliasSource(route: RouteManifestEntry) {
|
|
90
|
-
const routeType = routeKey(route.route)
|
|
90
|
+
const routeType = routeKey(route.route)
|
|
91
91
|
|
|
92
92
|
return `// This file is generated by PNext. Do not edit.
|
|
93
93
|
import type {
|
|
@@ -101,22 +101,22 @@ export type Params = PNextRouteParams<'${routeType}'>;
|
|
|
101
101
|
export type PageProps = PNextPageProps<'${routeType}'>;
|
|
102
102
|
export type RouteContext = PNextRouteContext<'${routeType}'>;
|
|
103
103
|
export type StaticParams = PNextStaticParams<'${routeType}'>;
|
|
104
|
-
|
|
104
|
+
`
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function routeAliasPath(config: ResolvedConfig, route: RouteManifestEntry) {
|
|
108
|
-
const relative = toPosixPath(path.relative(config.appPath, route.file))
|
|
109
|
-
const extension = path.extname(relative)
|
|
110
|
-
return relative.slice(0, -extension.length)
|
|
108
|
+
const relative = toPosixPath(path.relative(config.appPath, route.file))
|
|
109
|
+
const extension = path.extname(relative)
|
|
110
|
+
return relative.slice(0, -extension.length)
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
function checkSource(checksDir: string, route: RouteManifestEntry) {
|
|
114
|
-
const routeImport = routeImportPath(checksDir, route.file)
|
|
115
|
-
const routeType = routeKey(route.route)
|
|
114
|
+
const routeImport = routeImportPath(checksDir, route.file)
|
|
115
|
+
const routeType = routeKey(route.route)
|
|
116
116
|
const moduleType =
|
|
117
117
|
route.kind === 'page'
|
|
118
118
|
? `PNextPageModule<'${routeType}'>`
|
|
119
|
-
: `PNextRouteHandlerModule<'${routeType}'
|
|
119
|
+
: `PNextRouteHandlerModule<'${routeType}'>`
|
|
120
120
|
|
|
121
121
|
return `// This file is generated by PNext. Do not edit.
|
|
122
122
|
import type { PNextPageModule, PNextRouteHandlerModule } from '@wular/pnext/internal';
|
|
@@ -124,28 +124,28 @@ import * as routeModule from '${routeImport}';
|
|
|
124
124
|
|
|
125
125
|
const check: ${moduleType} = routeModule;
|
|
126
126
|
void check;
|
|
127
|
-
|
|
127
|
+
`
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
function routeImportPath(fromDir: string, file: string) {
|
|
131
|
-
const extension = path.extname(file)
|
|
132
|
-
const withoutExtension = file.slice(0, -extension.length)
|
|
133
|
-
const relative = toPosixPath(path.relative(fromDir, withoutExtension))
|
|
134
|
-
return relative.startsWith('.') ? relative : `./${relative}
|
|
131
|
+
const extension = path.extname(file)
|
|
132
|
+
const withoutExtension = file.slice(0, -extension.length)
|
|
133
|
+
const relative = toPosixPath(path.relative(fromDir, withoutExtension))
|
|
134
|
+
return relative.startsWith('.') ? relative : `./${relative}`
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
function routeKey(route: string) {
|
|
138
|
-
return route.replace(/:([a-zA-Z0-9_]+)\*/g, '[...$1]').replace(/:([a-zA-Z0-9_]+)/g, '[$1]')
|
|
138
|
+
return route.replace(/:([a-zA-Z0-9_]+)\*/g, '[...$1]').replace(/:([a-zA-Z0-9_]+)/g, '[$1]')
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function paramsType(route: RouteManifestEntry) {
|
|
142
|
-
const entries = route.params.map(param => `${JSON.stringify(param)}: string`)
|
|
143
|
-
if (route.catchAll) entries.push(`${JSON.stringify(route.catchAll)}: string[]`)
|
|
144
|
-
return entries.length > 0 ? `{ ${entries.join('; ')} }` : 'Record<string, never>'
|
|
142
|
+
const entries = route.params.map(param => `${JSON.stringify(param)}: string`)
|
|
143
|
+
if (route.catchAll) entries.push(`${JSON.stringify(route.catchAll)}: string[]`)
|
|
144
|
+
return entries.length > 0 ? `{ ${entries.join('; ')} }` : 'Record<string, never>'
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
async function writeIfChanged(file: string, source: string) {
|
|
148
|
-
if (existsSync(file) && (await readFile(file, 'utf8')) === source) return
|
|
149
|
-
await ensureDir(path.dirname(file))
|
|
150
|
-
await writeFile(file, source)
|
|
148
|
+
if (existsSync(file) && (await readFile(file, 'utf8')) === source) return
|
|
149
|
+
await ensureDir(path.dirname(file))
|
|
150
|
+
await writeFile(file, source)
|
|
151
151
|
}
|