@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,5 +1,5 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
2
|
-
import path from 'node:path'
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import path from 'node:path'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Stable, deterministic id for a server action export. This id is the wire
|
|
@@ -16,13 +16,8 @@ import path from 'node:path';
|
|
|
16
16
|
* as-is (already-relative paths pass through unchanged).
|
|
17
17
|
*/
|
|
18
18
|
export function actionId(filePath: string, exportName: string, root?: string): string {
|
|
19
|
-
const key = workspaceRelative(filePath, root)
|
|
20
|
-
return createHash('sha256')
|
|
21
|
-
.update(key)
|
|
22
|
-
.update('\0')
|
|
23
|
-
.update(exportName)
|
|
24
|
-
.digest('hex')
|
|
25
|
-
.slice(0, 12);
|
|
19
|
+
const key = workspaceRelative(filePath, root)
|
|
20
|
+
return createHash('sha256').update(key).update('\0').update(exportName).digest('hex').slice(0, 12)
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
/**
|
|
@@ -30,10 +25,10 @@ export function actionId(filePath: string, exportName: string, root?: string): s
|
|
|
30
25
|
* the registry and detection share one notion of a module's identity.
|
|
31
26
|
*/
|
|
32
27
|
export function workspaceRelative(filePath: string, root?: string): string {
|
|
33
|
-
const rel = root ? path.relative(root, filePath) : filePath
|
|
34
|
-
return toPosix(rel)
|
|
28
|
+
const rel = root ? path.relative(root, filePath) : filePath
|
|
29
|
+
return toPosix(rel)
|
|
35
30
|
}
|
|
36
31
|
|
|
37
32
|
function toPosix(value: string): string {
|
|
38
|
-
return value.split(path.sep).join('/')
|
|
33
|
+
return value.split(path.sep).join('/')
|
|
39
34
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
export { actionId, workspaceRelative } from './ids'
|
|
1
|
+
export { actionId, workspaceRelative } from './ids'
|
|
2
2
|
export {
|
|
3
3
|
moduleLevelUseServer,
|
|
4
4
|
inlineUseServerFunctions,
|
|
5
5
|
moduleActionExports,
|
|
6
6
|
type InlineAction,
|
|
7
|
-
} from './detect'
|
|
7
|
+
} from './detect'
|
|
8
8
|
export {
|
|
9
9
|
registerActionModule,
|
|
10
10
|
lookupAction,
|
|
11
11
|
allActions,
|
|
12
12
|
clearActions,
|
|
13
13
|
type ActionEntry,
|
|
14
|
-
} from './registry'
|
|
14
|
+
} from './registry'
|
|
15
15
|
export {
|
|
16
16
|
createInstanceScope,
|
|
17
17
|
registerActionInstance,
|
|
@@ -20,15 +20,15 @@ export {
|
|
|
20
20
|
instanceActionRouteId,
|
|
21
21
|
clearActionInstances,
|
|
22
22
|
type InstanceScope,
|
|
23
|
-
} from './instances'
|
|
24
|
-
export { runAction, DEFAULT_BODY_LIMIT_BYTES, type RunActionOptions } from './endpoint'
|
|
23
|
+
} from './instances'
|
|
24
|
+
export { runAction, DEFAULT_BODY_LIMIT_BYTES, type RunActionOptions } from './endpoint'
|
|
25
25
|
export {
|
|
26
26
|
serveAction,
|
|
27
27
|
isActionRequest,
|
|
28
28
|
isProgressiveActionRequest,
|
|
29
29
|
type ServeActionOptions,
|
|
30
|
-
} from './serve'
|
|
31
|
-
export { clientStubSource, type ClientStubModule } from './client-stub'
|
|
30
|
+
} from './serve'
|
|
31
|
+
export { clientStubSource, type ClientStubModule } from './client-stub'
|
|
32
32
|
export {
|
|
33
33
|
ACTION_ID_HEADER,
|
|
34
34
|
ACTION_ID_FIELD,
|
|
@@ -38,4 +38,4 @@ export {
|
|
|
38
38
|
ACTION_NOT_FOUND_HEADER,
|
|
39
39
|
PROP_ACTION_MARKER,
|
|
40
40
|
type ActionSuccessBody,
|
|
41
|
-
} from './protocol'
|
|
41
|
+
} from './protocol'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Runtime registry for INLINE server actions: functions with a 'use server' body directive that cross
|
|
@@ -18,16 +18,16 @@ import { createHash } from 'node:crypto';
|
|
|
18
18
|
* only work because of the re-render path.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
const instances = new Map<string, (...args: unknown[]) => unknown>()
|
|
21
|
+
const instances = new Map<string, (...args: unknown[]) => unknown>()
|
|
22
22
|
|
|
23
23
|
/** Per-render dedup state; create one per page render and thread it through. */
|
|
24
24
|
export interface InstanceScope {
|
|
25
|
-
routeId: string
|
|
26
|
-
counts: Map<string, number
|
|
25
|
+
routeId: string
|
|
26
|
+
counts: Map<string, number>
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export function createInstanceScope(routeId: string): InstanceScope {
|
|
30
|
-
return { routeId, counts: new Map() }
|
|
30
|
+
return { routeId, counts: new Map() }
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -36,37 +36,37 @@ export function createInstanceScope(routeId: string): InstanceScope {
|
|
|
36
36
|
* occurrence index) overwrites the previous render's instance.
|
|
37
37
|
*/
|
|
38
38
|
export function registerActionInstance(scope: InstanceScope, fn: unknown): string {
|
|
39
|
-
const callable = fn as (...args: unknown[]) => unknown
|
|
40
|
-
const hash = sourceHash(callable)
|
|
41
|
-
const index = scope.counts.get(hash) ?? 0
|
|
42
|
-
scope.counts.set(hash, index + 1)
|
|
43
|
-
const id = `i:${scope.routeId}:${hash}:${index}
|
|
44
|
-
instances.set(id, callable)
|
|
45
|
-
return id
|
|
39
|
+
const callable = fn as (...args: unknown[]) => unknown
|
|
40
|
+
const hash = sourceHash(callable)
|
|
41
|
+
const index = scope.counts.get(hash) ?? 0
|
|
42
|
+
scope.counts.set(hash, index + 1)
|
|
43
|
+
const id = `i:${scope.routeId}:${hash}:${index}`
|
|
44
|
+
instances.set(id, callable)
|
|
45
|
+
return id
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/** Live instance for an id, if this process has rendered it. */
|
|
49
49
|
export function lookupActionInstance(id: string) {
|
|
50
|
-
return instances.get(id)
|
|
50
|
+
return instances.get(id)
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function isInstanceActionId(id: string) {
|
|
54
|
-
return id.startsWith('i:')
|
|
54
|
+
return id.startsWith('i:')
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/** Route id encoded in an instance action id, for the re-render fallback. */
|
|
58
58
|
export function instanceActionRouteId(id: string): string | undefined {
|
|
59
|
-
if (!isInstanceActionId(id)) return undefined
|
|
59
|
+
if (!isInstanceActionId(id)) return undefined
|
|
60
60
|
// i:<routeId>:<hash>:<n> — routeId may itself contain ':'? Route ids are
|
|
61
61
|
// path-derived and never contain ':', so a simple split is safe; hash and n
|
|
62
62
|
// are the last two segments.
|
|
63
|
-
const parts = id.split(':')
|
|
64
|
-
if (parts.length < 4) return undefined
|
|
65
|
-
return parts.slice(1, -2).join(':')
|
|
63
|
+
const parts = id.split(':')
|
|
64
|
+
if (parts.length < 4) return undefined
|
|
65
|
+
return parts.slice(1, -2).join(':')
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export function clearActionInstances() {
|
|
69
|
-
instances.clear()
|
|
69
|
+
instances.clear()
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
@@ -78,15 +78,15 @@ export function clearActionInstances() {
|
|
|
78
78
|
* wire id, so skewed ids produce the failed-to-find flow exactly like Next.
|
|
79
79
|
*/
|
|
80
80
|
export interface TaggedActionFunction {
|
|
81
|
-
(...args: unknown[]): unknown
|
|
82
|
-
$$id?: string
|
|
83
|
-
$$pnextAssignedId?: string
|
|
84
|
-
$$pnextInlineAction?: true
|
|
81
|
+
(...args: unknown[]): unknown
|
|
82
|
+
$$id?: string
|
|
83
|
+
$$pnextAssignedId?: string
|
|
84
|
+
$$pnextInlineAction?: true
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
declare global {
|
|
88
|
-
var __pnextTagInlineAction: ((fn: unknown, id: string) => void) | undefined
|
|
89
|
-
var __pnextMarkInlineAction: (<T>(fn: T) => T) | undefined
|
|
88
|
+
var __pnextTagInlineAction: ((fn: unknown, id: string) => void) | undefined
|
|
89
|
+
var __pnextMarkInlineAction: (<T>(fn: T) => T) | undefined
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/**
|
|
@@ -97,48 +97,48 @@ declare global {
|
|
|
97
97
|
* separates it from a plain client handler at serialization time.
|
|
98
98
|
*/
|
|
99
99
|
globalThis.__pnextMarkInlineAction = <T>(fn: T): T => {
|
|
100
|
-
if (typeof fn === 'function') (fn as TaggedActionFunction).$$pnextInlineAction = true
|
|
101
|
-
return fn
|
|
102
|
-
}
|
|
100
|
+
if (typeof fn === 'function') (fn as TaggedActionFunction).$$pnextInlineAction = true
|
|
101
|
+
return fn
|
|
102
|
+
}
|
|
103
103
|
|
|
104
104
|
/** True for a compile-marked anonymous inline 'use server' function. */
|
|
105
105
|
export function isMarkedInlineAction(fn: unknown): boolean {
|
|
106
|
-
return typeof fn === 'function' && (fn as TaggedActionFunction).$$pnextInlineAction === true
|
|
106
|
+
return typeof fn === 'function' && (fn as TaggedActionFunction).$$pnextInlineAction === true
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
globalThis.__pnextTagInlineAction = (fn: unknown, id: string) => {
|
|
110
|
-
if (typeof fn !== 'function') return
|
|
111
|
-
const tagged = fn as TaggedActionFunction
|
|
112
|
-
instances.set(id, tagged)
|
|
113
|
-
tagged.$$pnextAssignedId = id
|
|
110
|
+
if (typeof fn !== 'function') return
|
|
111
|
+
const tagged = fn as TaggedActionFunction
|
|
112
|
+
instances.set(id, tagged)
|
|
113
|
+
tagged.$$pnextAssignedId = id
|
|
114
114
|
if (!('$$id' in tagged)) {
|
|
115
|
-
Object.defineProperty(tagged, '$$id', { value: id, configurable: true, writable: true })
|
|
115
|
+
Object.defineProperty(tagged, '$$id', { value: id, configurable: true, writable: true })
|
|
116
116
|
}
|
|
117
|
-
}
|
|
117
|
+
}
|
|
118
118
|
|
|
119
119
|
/** Caller-overridden $$id (version-skew simulation) wins as the wire id. */
|
|
120
120
|
export function overriddenActionId(fn: unknown): string | undefined {
|
|
121
|
-
if (typeof fn !== 'function') return undefined
|
|
122
|
-
const tagged = fn as TaggedActionFunction
|
|
121
|
+
if (typeof fn !== 'function') return undefined
|
|
122
|
+
const tagged = fn as TaggedActionFunction
|
|
123
123
|
if (typeof tagged.$$id === 'string' && tagged.$$id !== tagged.$$pnextAssignedId) {
|
|
124
|
-
return tagged.$$id
|
|
124
|
+
return tagged.$$id
|
|
125
125
|
}
|
|
126
|
-
return undefined
|
|
126
|
+
return undefined
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/** Stable assigned id for a compile-tagged module-scope inline action. */
|
|
130
130
|
export function assignedInlineActionId(fn: unknown): string | undefined {
|
|
131
|
-
if (typeof fn !== 'function') return undefined
|
|
132
|
-
const tagged = fn as TaggedActionFunction
|
|
133
|
-
return typeof tagged.$$pnextAssignedId === 'string' ? tagged.$$pnextAssignedId : undefined
|
|
131
|
+
if (typeof fn !== 'function') return undefined
|
|
132
|
+
const tagged = fn as TaggedActionFunction
|
|
133
|
+
return typeof tagged.$$pnextAssignedId === 'string' ? tagged.$$pnextAssignedId : undefined
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
function sourceHash(fn: (...args: unknown[]) => unknown) {
|
|
137
|
-
let source = ''
|
|
137
|
+
let source = ''
|
|
138
138
|
try {
|
|
139
|
-
source = String(fn)
|
|
139
|
+
source = String(fn)
|
|
140
140
|
} catch {
|
|
141
|
-
source = 'opaque'
|
|
141
|
+
source = 'opaque'
|
|
142
142
|
}
|
|
143
|
-
return createHash('sha256').update(source).digest('hex').slice(0, 10)
|
|
143
|
+
return createHash('sha256').update(source).digest('hex').slice(0, 10)
|
|
144
144
|
}
|
|
@@ -7,80 +7,79 @@
|
|
|
7
7
|
// sandboxed iframe) are treated as the literal host 'null'. A missing origin is
|
|
8
8
|
// allowed (handcrafted request; can't carry unwilling credentials).
|
|
9
9
|
|
|
10
|
-
import { getNextConfig } from '../next/config-loader'
|
|
10
|
+
import { getNextConfig } from '../next/config-loader'
|
|
11
11
|
|
|
12
|
-
export const INVALID_ORIGIN_MESSAGE = 'Invalid Server Actions request.'
|
|
12
|
+
export const INVALID_ORIGIN_MESSAGE = 'Invalid Server Actions request.'
|
|
13
13
|
|
|
14
14
|
/** Read experimental.serverActions.allowedOrigins (also the top-level key). */
|
|
15
15
|
export function allowedOrigins(): string[] {
|
|
16
|
-
const config = getNextConfig()
|
|
17
|
-
const top = (config.serverActions as { allowedOrigins?: unknown } | undefined)?.allowedOrigins
|
|
16
|
+
const config = getNextConfig()
|
|
17
|
+
const top = (config.serverActions as { allowedOrigins?: unknown } | undefined)?.allowedOrigins
|
|
18
18
|
const experimental = config.experimental as
|
|
19
|
-
|
|
20
|
-
| undefined;
|
|
19
|
+
{ serverActions?: { allowedOrigins?: unknown } | boolean } | undefined
|
|
21
20
|
const exp =
|
|
22
21
|
experimental && typeof experimental.serverActions === 'object'
|
|
23
22
|
? experimental.serverActions.allowedOrigins
|
|
24
|
-
: undefined
|
|
25
|
-
const list = top ?? exp
|
|
26
|
-
return Array.isArray(list) ? list.filter((v): v is string => typeof v === 'string') : []
|
|
23
|
+
: undefined
|
|
24
|
+
const list = top ?? exp
|
|
25
|
+
return Array.isArray(list) ? list.filter((v): v is string => typeof v === 'string') : []
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
function firstHeaderValue(value: string | null): string | undefined {
|
|
30
|
-
if (value === null) return undefined
|
|
31
|
-
return value.split(',')[0]?.trim() || undefined
|
|
29
|
+
if (value === null) return undefined
|
|
30
|
+
return value.split(',')[0]?.trim() || undefined
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
/** Request host used to compare against the origin (x-forwarded-host > host). */
|
|
35
34
|
function requestHost(headers: Headers): string | undefined {
|
|
36
|
-
return firstHeaderValue(headers.get('x-forwarded-host')) ?? headers.get('host') ?? undefined
|
|
35
|
+
return firstHeaderValue(headers.get('x-forwarded-host')) ?? headers.get('host') ?? undefined
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
function originHost(headers: Headers): string | undefined {
|
|
40
|
-
const origin = headers.get('origin')
|
|
41
|
-
if (origin === null) return undefined
|
|
42
|
-
if (origin === 'null') return 'null'
|
|
39
|
+
const origin = headers.get('origin')
|
|
40
|
+
if (origin === null) return undefined
|
|
41
|
+
if (origin === 'null') return 'null'
|
|
43
42
|
try {
|
|
44
|
-
return new URL(origin).host
|
|
43
|
+
return new URL(origin).host
|
|
45
44
|
} catch {
|
|
46
|
-
return undefined
|
|
45
|
+
return undefined
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
function matchWildcardDomain(domain: string, pattern: string): boolean {
|
|
51
|
-
const normalizedDomain = domain.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
52
|
-
const normalizedPattern = pattern.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
53
|
-
const domainParts = normalizedDomain.split('.')
|
|
54
|
-
const patternParts = normalizedPattern.split('.')
|
|
55
|
-
if (patternParts.length < 1) return false
|
|
56
|
-
if (domainParts.length < patternParts.length) return false
|
|
50
|
+
const normalizedDomain = domain.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
51
|
+
const normalizedPattern = pattern.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
52
|
+
const domainParts = normalizedDomain.split('.')
|
|
53
|
+
const patternParts = normalizedPattern.split('.')
|
|
54
|
+
if (patternParts.length < 1) return false
|
|
55
|
+
if (domainParts.length < patternParts.length) return false
|
|
57
56
|
if (patternParts.length === 1 && (patternParts[0] === '*' || patternParts[0] === '**')) {
|
|
58
|
-
return false
|
|
57
|
+
return false
|
|
59
58
|
}
|
|
60
59
|
while (patternParts.length) {
|
|
61
|
-
const patternPart = patternParts.pop()
|
|
62
|
-
const domainPart = domainParts.pop()
|
|
63
|
-
if (patternPart === '') return false
|
|
60
|
+
const patternPart = patternParts.pop()
|
|
61
|
+
const domainPart = domainParts.pop()
|
|
62
|
+
if (patternPart === '') return false
|
|
64
63
|
if (patternPart === '*') {
|
|
65
|
-
if (domainPart) continue
|
|
66
|
-
return false
|
|
64
|
+
if (domainPart) continue
|
|
65
|
+
return false
|
|
67
66
|
}
|
|
68
67
|
if (patternPart === '**') {
|
|
69
|
-
if (patternParts.length > 0) return false
|
|
70
|
-
return domainPart !== undefined
|
|
68
|
+
if (patternParts.length > 0) return false
|
|
69
|
+
return domainPart !== undefined
|
|
71
70
|
}
|
|
72
|
-
if (domainPart !== patternPart) return false
|
|
71
|
+
if (domainPart !== patternPart) return false
|
|
73
72
|
}
|
|
74
|
-
return domainParts.length === 0
|
|
73
|
+
return domainParts.length === 0
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
function isCsrfOriginAllowed(originDomain: string, origins: string[]): boolean {
|
|
78
|
-
const normalizedOrigin = originDomain.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
77
|
+
const normalizedOrigin = originDomain.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
79
78
|
return origins.some(allowed => {
|
|
80
|
-
if (!allowed) return false
|
|
81
|
-
const normalizedAllowed = allowed.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
82
|
-
return normalizedAllowed === normalizedOrigin || matchWildcardDomain(originDomain, allowed)
|
|
83
|
-
})
|
|
79
|
+
if (!allowed) return false
|
|
80
|
+
const normalizedAllowed = allowed.replace(/[A-Z]/g, c => c.toLowerCase())
|
|
81
|
+
return normalizedAllowed === normalizedOrigin || matchWildcardDomain(originDomain, allowed)
|
|
82
|
+
})
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
/**
|
|
@@ -89,21 +88,21 @@ function isCsrfOriginAllowed(originDomain: string, origins: string[]): boolean {
|
|
|
89
88
|
* with the "Invalid Server Actions request." error. Logs the mismatch like Next.
|
|
90
89
|
*/
|
|
91
90
|
export function isActionOriginAllowed(request: Request): boolean {
|
|
92
|
-
const headers = request.headers
|
|
93
|
-
const oHost = originHost(headers)
|
|
94
|
-
if (oHost === undefined) return true
|
|
95
|
-
const host = requestHost(headers)
|
|
96
|
-
if (host !== undefined && oHost === host) return true
|
|
97
|
-
if (isCsrfOriginAllowed(oHost, allowedOrigins())) return true
|
|
91
|
+
const headers = request.headers
|
|
92
|
+
const oHost = originHost(headers)
|
|
93
|
+
if (oHost === undefined) return true
|
|
94
|
+
const host = requestHost(headers)
|
|
95
|
+
if (host !== undefined && oHost === host) return true
|
|
96
|
+
if (isCsrfOriginAllowed(oHost, allowedOrigins())) return true
|
|
98
97
|
if (host) {
|
|
99
|
-
const hostType = headers.has('x-forwarded-host') ? 'x-forwarded-host' : 'host'
|
|
98
|
+
const hostType = headers.has('x-forwarded-host') ? 'x-forwarded-host' : 'host'
|
|
100
99
|
console.error(
|
|
101
100
|
`\`${hostType}\` header with value \`${host}\` does not match \`origin\` header with value \`${oHost}\` from a forwarded Server Actions request. Aborting the action.`,
|
|
102
|
-
)
|
|
101
|
+
)
|
|
103
102
|
} else {
|
|
104
103
|
console.error(
|
|
105
104
|
'`x-forwarded-host` or `host` headers are not provided. One of these is needed to compare the `origin` header from a forwarded Server Actions request. Aborting the action.',
|
|
106
|
-
)
|
|
105
|
+
)
|
|
107
106
|
}
|
|
108
|
-
return false
|
|
107
|
+
return false
|
|
109
108
|
}
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/** Header carrying the action id from client -> server. Mirrors Next's name. */
|
|
15
|
-
export const ACTION_ID_HEADER = 'next-action'
|
|
15
|
+
export const ACTION_ID_HEADER = 'next-action'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Response header set on a redirect result so the client can distinguish a
|
|
19
19
|
* framework redirect (soft-navigable) from an arbitrary 303 it should follow.
|
|
20
20
|
*/
|
|
21
|
-
export const ACTION_REDIRECT_HEADER = 'x-action-redirect'
|
|
21
|
+
export const ACTION_REDIRECT_HEADER = 'x-action-redirect'
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Response header telling the client to soft-refresh the current route after a
|
|
@@ -26,13 +26,13 @@ export const ACTION_REDIRECT_HEADER = 'x-action-redirect';
|
|
|
26
26
|
* revalidateTag) or mutated cookies, mirroring when Next invalidates its
|
|
27
27
|
* client router cache.
|
|
28
28
|
*/
|
|
29
|
-
export const ACTION_REFRESH_HEADER = 'x-pnext-action-refresh'
|
|
29
|
+
export const ACTION_REFRESH_HEADER = 'x-pnext-action-refresh'
|
|
30
30
|
|
|
31
31
|
/** Next's public action revalidation header. `1` means static+dynamic invalidated. */
|
|
32
|
-
export const NEXT_ACTION_REVALIDATED_HEADER = 'x-action-revalidated'
|
|
32
|
+
export const NEXT_ACTION_REVALIDATED_HEADER = 'x-action-revalidated'
|
|
33
33
|
|
|
34
34
|
/** Response header marking a notFound() result (body is the 404 page HTML). */
|
|
35
|
-
export const ACTION_NOT_FOUND_HEADER = 'x-pnext-action-not-found'
|
|
35
|
+
export const ACTION_NOT_FOUND_HEADER = 'x-pnext-action-not-found'
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Next's own action-not-found marker (`x-nextjs-action-not-found`). Set on the
|
|
@@ -40,10 +40,10 @@ export const ACTION_NOT_FOUND_HEADER = 'x-pnext-action-not-found';
|
|
|
40
40
|
* no-server-actions suite observe it; distinct from ACTION_NOT_FOUND_HEADER,
|
|
41
41
|
* which drives the client's 404-page swap for a notFound() result.
|
|
42
42
|
*/
|
|
43
|
-
export const NEXT_ACTION_NOT_FOUND_HEADER = 'x-nextjs-action-not-found'
|
|
43
|
+
export const NEXT_ACTION_NOT_FOUND_HEADER = 'x-nextjs-action-not-found'
|
|
44
44
|
|
|
45
45
|
/** Response header carrying redirect(location, RedirectType.replace) intent. */
|
|
46
|
-
export const REDIRECT_TYPE_HEADER = 'x-pnext-redirect-type'
|
|
46
|
+
export const REDIRECT_TYPE_HEADER = 'x-pnext-redirect-type'
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Response header carrying the boundary digest of a masked action error. Next
|
|
@@ -53,10 +53,10 @@ export const REDIRECT_TYPE_HEADER = 'x-pnext-redirect-type';
|
|
|
53
53
|
* same deterministic scheme as the render boundary digest (error-serialize.ts),
|
|
54
54
|
* so it matches the `digest: '<digest>'` line printed to the server log.
|
|
55
55
|
*/
|
|
56
|
-
export const ACTION_ERROR_DIGEST_HEADER = 'x-pnext-action-error-digest'
|
|
56
|
+
export const ACTION_ERROR_DIGEST_HEADER = 'x-pnext-action-error-digest'
|
|
57
57
|
|
|
58
58
|
/** Argument marker for a server-action function reference passed as an arg. */
|
|
59
|
-
export const ARG_ACTION_MARKER = '$$pnext_action_ref'
|
|
59
|
+
export const ARG_ACTION_MARKER = '$$pnext_action_ref'
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Hidden form field carrying the action id for no-JS progressive enhancement, emitted in
|
|
@@ -65,7 +65,7 @@ export const ARG_ACTION_MARKER = '$$pnext_action_ref';
|
|
|
65
65
|
* instead so it is unambiguous regardless of DOM order: the form-level field renders LAST inside
|
|
66
66
|
* client-island forms, so a shared field name could not tell the two apart.
|
|
67
67
|
*/
|
|
68
|
-
export const ACTION_ID_FIELD = '$pnext_action_id'
|
|
68
|
+
export const ACTION_ID_FIELD = '$pnext_action_id'
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Field name a `<button formAction>` submitter carries its action id under, submitted only when it is
|
|
@@ -73,42 +73,42 @@ export const ACTION_ID_FIELD = '$pnext_action_id';
|
|
|
73
73
|
* surrounding form's default without relying on field order - a no-JS submit has no `event.submitter`
|
|
74
74
|
* to disambiguate them.
|
|
75
75
|
*/
|
|
76
|
-
export const SUBMIT_ACTION_ID_FIELD = '$pnext_submit_action_id'
|
|
76
|
+
export const SUBMIT_ACTION_ID_FIELD = '$pnext_submit_action_id'
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* Multipart field name carrying the JSON-encoded argument list when a call
|
|
80
80
|
* mixes JSON args with FormData/File values (e.g. bound args ahead of a form
|
|
81
81
|
* submission). Slots reference the other multipart parts.
|
|
82
82
|
*/
|
|
83
|
-
export const ACTION_ARGS_FIELD = '$pnext_args'
|
|
83
|
+
export const ACTION_ARGS_FIELD = '$pnext_args'
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* Hidden form field carrying a useActionState form's CURRENT state (JSON) for
|
|
87
87
|
* no-JS progressive submissions. The server runs `action(state, formData)` and
|
|
88
88
|
* re-renders the page with the result as the form's new state.
|
|
89
89
|
*/
|
|
90
|
-
export const FORM_STATE_FIELD = '$pnext_form_state'
|
|
90
|
+
export const FORM_STATE_FIELD = '$pnext_form_state'
|
|
91
91
|
|
|
92
92
|
/** Marker key for a FormData argument slot inside ACTION_ARGS_FIELD JSON. */
|
|
93
|
-
export const ARG_FORMDATA_MARKER = '$$pnext_fd'
|
|
93
|
+
export const ARG_FORMDATA_MARKER = '$$pnext_fd'
|
|
94
94
|
|
|
95
95
|
/** Marker key for a File argument slot inside ACTION_ARGS_FIELD JSON. */
|
|
96
|
-
export const ARG_FILE_MARKER = '$$pnext_file'
|
|
96
|
+
export const ARG_FILE_MARKER = '$$pnext_file'
|
|
97
97
|
|
|
98
98
|
/** Prefix for multipart parts belonging to a FormData argument slot. */
|
|
99
|
-
export const ARG_FORMDATA_PREFIX = '$pnext_fd_'
|
|
99
|
+
export const ARG_FORMDATA_PREFIX = '$pnext_fd_'
|
|
100
100
|
|
|
101
101
|
/** Prefix for multipart parts holding a File argument slot. */
|
|
102
|
-
export const ARG_FILE_PREFIX = '$pnext_file_'
|
|
102
|
+
export const ARG_FILE_PREFIX = '$pnext_file_'
|
|
103
103
|
|
|
104
104
|
/** Serialized-prop marker for a server-action function passed to an island. */
|
|
105
|
-
export const PROP_ACTION_MARKER = '$$pnextAction'
|
|
105
|
+
export const PROP_ACTION_MARKER = '$$pnextAction'
|
|
106
106
|
|
|
107
107
|
/** Maximum action argument list length, mirroring Next's guard. */
|
|
108
|
-
export const MAX_ACTION_ARGS = 1000
|
|
108
|
+
export const MAX_ACTION_ARGS = 1000
|
|
109
109
|
|
|
110
110
|
export function tooManyArgsMessage(count: number) {
|
|
111
|
-
return `Server Action arguments list is too long (${count}). Maximum allowed is ${MAX_ACTION_ARGS}
|
|
111
|
+
return `Server Action arguments list is too long (${count}). Maximum allowed is ${MAX_ACTION_ARGS}.`
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
@@ -117,9 +117,9 @@ export function tooManyArgsMessage(count: number) {
|
|
|
117
117
|
* prod builds send it as the text/plain error body and the client throws it as the Error message.
|
|
118
118
|
*/
|
|
119
119
|
export const MASKED_ACTION_ERROR =
|
|
120
|
-
'Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.'
|
|
120
|
+
'Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.'
|
|
121
121
|
|
|
122
122
|
/** JSON success envelope: { data } (application/json, status 200). */
|
|
123
123
|
export interface ActionSuccessBody {
|
|
124
|
-
data: unknown
|
|
124
|
+
data: unknown
|
|
125
125
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { actionId } from './ids'
|
|
1
|
+
import { actionId } from './ids'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* In-process registry mapping a stable actionId -> the module + export that
|
|
@@ -11,20 +11,20 @@ import { actionId } from './ids';
|
|
|
11
11
|
|
|
12
12
|
export interface ActionEntry {
|
|
13
13
|
/** actionId(filePath, exportName, root) — the wire id. */
|
|
14
|
-
id: string
|
|
14
|
+
id: string
|
|
15
15
|
/** Module path the wiring agent will hand to importModule(). */
|
|
16
|
-
modulePath: string
|
|
16
|
+
modulePath: string
|
|
17
17
|
/** Named export within the module implementing the action. */
|
|
18
|
-
exportName: string
|
|
18
|
+
exportName: string
|
|
19
19
|
/**
|
|
20
20
|
* The SOURCE file the id was computed from (workspace-relative when the registration passed `root`,
|
|
21
21
|
* otherwise as given). Used to decide whether a POSTed route's module graph contains the action -
|
|
22
22
|
* Next's "forwarded action" discrimination, see serve.ts isForwardedAction.
|
|
23
23
|
*/
|
|
24
|
-
filePath: string
|
|
24
|
+
filePath: string
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const registry = new Map<string, ActionEntry>()
|
|
27
|
+
const registry = new Map<string, ActionEntry>()
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Register every action export of a module. `filePath` identifies the module for
|
|
@@ -40,35 +40,35 @@ export function registerActionModule(
|
|
|
40
40
|
exportNames: readonly string[],
|
|
41
41
|
options: { root?: string; modulePath?: string } = {},
|
|
42
42
|
): ActionEntry[] {
|
|
43
|
-
const modulePath = options.modulePath ?? filePath
|
|
44
|
-
const entries: ActionEntry[] = []
|
|
43
|
+
const modulePath = options.modulePath ?? filePath
|
|
44
|
+
const entries: ActionEntry[] = []
|
|
45
45
|
for (const exportName of exportNames) {
|
|
46
|
-
const id = actionId(filePath, exportName, options.root)
|
|
47
|
-
const entry: ActionEntry = { id, modulePath, exportName, filePath }
|
|
48
|
-
registry.set(id, entry)
|
|
49
|
-
entries.push(entry)
|
|
46
|
+
const id = actionId(filePath, exportName, options.root)
|
|
47
|
+
const entry: ActionEntry = { id, modulePath, exportName, filePath }
|
|
48
|
+
registry.set(id, entry)
|
|
49
|
+
entries.push(entry)
|
|
50
50
|
}
|
|
51
|
-
return entries
|
|
51
|
+
return entries
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/** Resolve an action id to its module + export, or undefined if unknown. */
|
|
55
55
|
export function lookupAction(id: string): { modulePath: string; exportName: string } | undefined {
|
|
56
|
-
const entry = registry.get(id)
|
|
57
|
-
if (!entry) return undefined
|
|
58
|
-
return { modulePath: entry.modulePath, exportName: entry.exportName }
|
|
56
|
+
const entry = registry.get(id)
|
|
57
|
+
if (!entry) return undefined
|
|
58
|
+
return { modulePath: entry.modulePath, exportName: entry.exportName }
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/** The source file a registered action id was computed from, or undefined. */
|
|
62
62
|
export function lookupActionSource(id: string): string | undefined {
|
|
63
|
-
return registry.get(id)?.filePath
|
|
63
|
+
return registry.get(id)?.filePath
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/** Snapshot of all registered actions. */
|
|
67
67
|
export function allActions(): ActionEntry[] {
|
|
68
|
-
return [...registry.values()]
|
|
68
|
+
return [...registry.values()]
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/** Clear the registry (test/rebuild support). */
|
|
72
72
|
export function clearActions(): void {
|
|
73
|
-
registry.clear()
|
|
73
|
+
registry.clear()
|
|
74
74
|
}
|