From 619f07db701ebab2d2f2598dd2dcf93ba1e5719c Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Wed, 10 Jul 2024 08:02:10 -0400 Subject: [PATCH] Actions: expose utility types (#11438) * feat: expose ACTION_ERROR_CODES util * feat: expose ActionHandler util type * chore: changeset --- .changeset/plenty-socks-talk.md | 5 +++ packages/astro/src/@types/astro.ts | 10 ++++-- .../src/actions/runtime/virtual/server.ts | 24 +++++++------- .../src/actions/runtime/virtual/shared.ts | 31 ++++++++++--------- 4 files changed, 41 insertions(+), 29 deletions(-) create mode 100644 .changeset/plenty-socks-talk.md diff --git a/.changeset/plenty-socks-talk.md b/.changeset/plenty-socks-talk.md new file mode 100644 index 000000000000..2749228dd952 --- /dev/null +++ b/.changeset/plenty-socks-talk.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Exposes utility types from `astro:actions` for the `defineAction` handler (`ActionHandler`) and the `ActionError` code (`ActionErrorCode`). diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index da0dcc9b6e9c..9a7a774c3c53 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -11,7 +11,11 @@ import type { import type * as babel from '@babel/core'; import type * as rollup from 'rollup'; import type * as vite from 'vite'; -import type { Accept, ActionClient, InputSchema } from '../actions/runtime/virtual/server.js'; +import type { + ActionAccept, + ActionClient, + ActionInputSchema, +} from '../actions/runtime/virtual/server.js'; import type { RemotePattern } from '../assets/utils/remotePattern.js'; import type { AssetsPrefix, SerializedSSRManifest } from '../core/app/types.js'; import type { PageBuildData } from '../core/build/types.js'; @@ -2764,8 +2768,8 @@ interface AstroSharedContext< * Get action result on the server when using a form POST. */ getActionResult: < - TAccept extends Accept, - TInputSchema extends InputSchema, + TAccept extends ActionAccept, + TInputSchema extends ActionInputSchema, TAction extends ActionClient, >( action: TAction diff --git a/packages/astro/src/actions/runtime/virtual/server.ts b/packages/astro/src/actions/runtime/virtual/server.ts index c034be8bc8d8..8f0d6e111dbf 100644 --- a/packages/astro/src/actions/runtime/virtual/server.ts +++ b/packages/astro/src/actions/runtime/virtual/server.ts @@ -10,12 +10,12 @@ export { z } from 'zod'; /** @deprecated Access context from the second `handler()` parameter. */ export const getApiContext = _getApiContext; -export type Accept = 'form' | 'json'; -export type InputSchema = T extends 'form' +export type ActionAccept = 'form' | 'json'; +export type ActionInputSchema = T extends 'form' ? z.AnyZodObject | z.ZodType : z.ZodType; -type Handler = TInputSchema extends z.ZodType +export type ActionHandler = TInputSchema extends z.ZodType ? (input: z.infer, context: ActionAPIContext) => MaybePromise : (input: any, context: ActionAPIContext) => MaybePromise; @@ -23,8 +23,8 @@ export type ActionReturnType> = Awaited | undefined, + TAccept extends ActionAccept | undefined, + TInputSchema extends ActionInputSchema | undefined, > = TInputSchema extends z.ZodType ? (( input: TAccept extends 'form' ? FormData : z.input @@ -46,8 +46,8 @@ export type ActionClient< export function defineAction< TOutput, - TAccept extends Accept | undefined = undefined, - TInputSchema extends InputSchema | undefined = TAccept extends 'form' + TAccept extends ActionAccept | undefined = undefined, + TInputSchema extends ActionInputSchema | undefined = TAccept extends 'form' ? // If `input` is omitted, default to `FormData` for forms and `any` for JSON. z.ZodType : undefined, @@ -58,7 +58,7 @@ export function defineAction< }: { input?: TInputSchema; accept?: TAccept; - handler: Handler; + handler: ActionHandler; }): ActionClient { const serverHandler = accept === 'form' @@ -73,8 +73,8 @@ export function defineAction< return serverHandler as ActionClient; } -function getFormServerHandler>( - handler: Handler, +function getFormServerHandler>( + handler: ActionHandler, inputSchema?: TInputSchema ) { return async (unparsedInput: unknown): Promise> => { @@ -95,8 +95,8 @@ function getFormServerHandler> }; } -function getJsonServerHandler>( - handler: Handler, +function getJsonServerHandler>( + handler: ActionHandler, inputSchema?: TInputSchema ) { return async (unparsedInput: unknown): Promise> => { diff --git a/packages/astro/src/actions/runtime/virtual/shared.ts b/packages/astro/src/actions/runtime/virtual/shared.ts index 94a22f7ca388..10ed75aa5174 100644 --- a/packages/astro/src/actions/runtime/virtual/shared.ts +++ b/packages/astro/src/actions/runtime/virtual/shared.ts @@ -1,20 +1,23 @@ import type { z } from 'zod'; import type { ErrorInferenceObject, MaybePromise } from '../utils.js'; -type ActionErrorCode = - | 'BAD_REQUEST' - | 'UNAUTHORIZED' - | 'FORBIDDEN' - | 'NOT_FOUND' - | 'TIMEOUT' - | 'CONFLICT' - | 'PRECONDITION_FAILED' - | 'PAYLOAD_TOO_LARGE' - | 'UNSUPPORTED_MEDIA_TYPE' - | 'UNPROCESSABLE_CONTENT' - | 'TOO_MANY_REQUESTS' - | 'CLIENT_CLOSED_REQUEST' - | 'INTERNAL_SERVER_ERROR'; +export const ACTION_ERROR_CODES = [ + 'BAD_REQUEST', + 'UNAUTHORIZED', + 'FORBIDDEN', + 'NOT_FOUND', + 'TIMEOUT', + 'CONFLICT', + 'PRECONDITION_FAILED', + 'PAYLOAD_TOO_LARGE', + 'UNSUPPORTED_MEDIA_TYPE', + 'UNPROCESSABLE_CONTENT', + 'TOO_MANY_REQUESTS', + 'CLIENT_CLOSED_REQUEST', + 'INTERNAL_SERVER_ERROR', +] as const; + +export type ActionErrorCode = (typeof ACTION_ERROR_CODES)[number]; const codeToStatusMap: Record = { // Implemented from tRPC error code table