diff options
author | 2025-03-27 07:33:06 +0000 | |
---|---|---|
committer | 2025-03-27 07:33:06 +0000 | |
commit | 06de673375f2339eb1bf8eda03d79177598979a9 (patch) | |
tree | 783d5ed7fc647f0db6a95d32f702ae4e245c01cc | |
parent | b33cc17f37b6f7bd1af06c9debcc8f7a7916eedc (diff) | |
download | astro-06de673375f2339eb1bf8eda03d79177598979a9.tar.gz astro-06de673375f2339eb1bf8eda03d79177598979a9.tar.zst astro-06de673375f2339eb1bf8eda03d79177598979a9.zip |
refactor(actions): use `Omit` to avoid leaking types to shared context (#13429)
* wip
* fix(actions): avoid mutation of action context
* chore: revert changes
* add changeset
* Update .changeset/calm-beans-roll.md
Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
---------
Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
-rw-r--r-- | .changeset/calm-beans-roll.md | 5 | ||||
-rw-r--r-- | packages/astro/src/actions/runtime/utils.ts | 31 | ||||
-rw-r--r-- | packages/astro/src/core/errors/errors-data.ts | 2 | ||||
-rw-r--r-- | packages/astro/src/core/render-context.ts | 12 | ||||
-rw-r--r-- | packages/astro/src/types/public/context.ts | 2 |
5 files changed, 41 insertions, 11 deletions
diff --git a/.changeset/calm-beans-roll.md b/.changeset/calm-beans-roll.md new file mode 100644 index 000000000..ac00de5d6 --- /dev/null +++ b/.changeset/calm-beans-roll.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +The `ActionAPIContext.rewrite` method is deprecated and will be removed in a future major version of Astro diff --git a/packages/astro/src/actions/runtime/utils.ts b/packages/astro/src/actions/runtime/utils.ts index 35c750055..496c9fdc9 100644 --- a/packages/astro/src/actions/runtime/utils.ts +++ b/packages/astro/src/actions/runtime/utils.ts @@ -1,4 +1,4 @@ -import type { APIContext } from '../../types/public/context.js'; +import type {APIContext, AstroSharedContext} from '../../types/public/context.js'; import type { SerializedActionResult } from './virtual/shared.js'; export type ActionPayload = { @@ -22,10 +22,33 @@ export function hasContentType(contentType: string, expected: string[]) { return expected.some((t) => type === t); } -export type ActionAPIContext = Omit< +export type ActionAPIContext = Pick< APIContext, - 'getActionResult' | 'callAction' | 'props' | 'redirect' ->; + | 'rewrite' + | 'request' + | 'url' + | 'isPrerendered' + | 'locals' + | 'clientAddress' + | 'cookies' + | 'currentLocale' + | 'generator' + | 'routePattern' + | 'site' + | 'params' + | 'preferredLocale' + | 'preferredLocaleList' + | 'originPathname' + | 'session' +> & { + // TODO: remove in Astro 6.0 + /** + * @deprecated + * The use of `rewrite` in Actions is deprecated + */ + rewrite: AstroSharedContext['rewrite'] +} + export type MaybePromise<T> = T | Promise<T>; /** diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index f8c2bc8f1..69e26d6cd 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -72,7 +72,7 @@ export const ClientAddressNotAvailable = { export const PrerenderClientAddressNotAvailable = { name: 'PrerenderClientAddressNotAvailable', title: '`Astro.clientAddress` cannot be used inside prerendered routes.', - message: `\`Astro.clientAddress\` cannot be used inside prerendered routes`, + message: (name: string) => `\`Astro.clientAddress\` cannot be used inside prerendered route ${name}`, } satisfies ErrorData; /** * @docs diff --git a/packages/astro/src/core/render-context.ts b/packages/astro/src/core/render-context.ts index c051ead98..7a6510b5d 100644 --- a/packages/astro/src/core/render-context.ts +++ b/packages/astro/src/core/render-context.ts @@ -71,7 +71,7 @@ export class RenderContext { * A safety net in case of loops */ counter = 0; - + static async create({ locals = {}, middleware, @@ -282,6 +282,7 @@ export class RenderContext { createAPIContext(props: APIContext['props'], context: ActionAPIContext): APIContext { const redirect = (path: string, status = 302) => new Response(null, { status, headers: { Location: path } }); + Reflect.set(context, apiContextRoutesSymbol, this.pipeline); return Object.assign(context, { @@ -302,9 +303,7 @@ export class RenderContext { // This case isn't valid because when building for SSR, the prerendered route disappears from the server output because it becomes an HTML file, // so Astro can't retrieve it from the emitted manifest. if ( - this.pipeline.serverLike === true && - this.routeData.prerender === false && - routeData.prerender === true + this.pipeline.serverLike && !this.routeData.prerender && routeData.prerender ) { throw new AstroError({ ...ForbiddenRewrite, @@ -573,7 +572,10 @@ export class RenderContext { const { pipeline, request, routeData, clientAddress } = this; if (routeData.prerender) { - throw new AstroError(AstroErrorData.PrerenderClientAddressNotAvailable); + throw new AstroError({ + ...AstroErrorData.PrerenderClientAddressNotAvailable, + message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component), + }); } if (clientAddress) { diff --git a/packages/astro/src/types/public/context.ts b/packages/astro/src/types/public/context.ts index 594376dee..8fb1bc451 100644 --- a/packages/astro/src/types/public/context.ts +++ b/packages/astro/src/types/public/context.ts @@ -247,7 +247,7 @@ export interface AstroGlobalPartial { } // Shared types between `Astro` global and API context object -interface AstroSharedContext< +export interface AstroSharedContext< Props extends Record<string, any> = Record<string, any>, RouteParams extends Record<string, string | undefined> = Record<string, string | undefined>, > { |