0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

Actions: expose utility types (#11438)

* feat: expose ACTION_ERROR_CODES util

* feat: expose ActionHandler util type

* chore: changeset
This commit is contained in:
Ben Holmes 2024-07-10 08:02:10 -04:00 committed by GitHub
parent 0d6f3563a5
commit 619f07db70
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 41 additions and 29 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Exposes utility types from `astro:actions` for the `defineAction` handler (`ActionHandler`) and the `ActionError` code (`ActionErrorCode`).

View file

@ -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>,
TAccept extends ActionAccept,
TInputSchema extends ActionInputSchema<TAccept>,
TAction extends ActionClient<unknown, TAccept, TInputSchema>,
>(
action: TAction

View file

@ -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 Accept | undefined> = T extends 'form'
export type ActionAccept = 'form' | 'json';
export type ActionInputSchema<T extends ActionAccept | undefined> = T extends 'form'
? z.AnyZodObject | z.ZodType<FormData>
: z.ZodType;
type Handler<TInputSchema, TOutput> = TInputSchema extends z.ZodType
export type ActionHandler<TInputSchema, TOutput> = TInputSchema extends z.ZodType
? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput>
: (input: any, context: ActionAPIContext) => MaybePromise<TOutput>;
@ -23,8 +23,8 @@ export type ActionReturnType<T extends Handler<any, any>> = Awaited<ReturnType<T
export type ActionClient<
TOutput,
TAccept extends Accept | undefined,
TInputSchema extends InputSchema<TAccept> | undefined,
TAccept extends ActionAccept | undefined,
TInputSchema extends ActionInputSchema<TAccept> | undefined,
> = TInputSchema extends z.ZodType
? ((
input: TAccept extends 'form' ? FormData : z.input<TInputSchema>
@ -46,8 +46,8 @@ export type ActionClient<
export function defineAction<
TOutput,
TAccept extends Accept | undefined = undefined,
TInputSchema extends InputSchema<Accept> | undefined = TAccept extends 'form'
TAccept extends ActionAccept | undefined = undefined,
TInputSchema extends ActionInputSchema<ActionAccept> | undefined = TAccept extends 'form'
? // If `input` is omitted, default to `FormData` for forms and `any` for JSON.
z.ZodType<FormData>
: undefined,
@ -58,7 +58,7 @@ export function defineAction<
}: {
input?: TInputSchema;
accept?: TAccept;
handler: Handler<TInputSchema, TOutput>;
handler: ActionHandler<TInputSchema, TOutput>;
}): ActionClient<TOutput, TAccept, TInputSchema> {
const serverHandler =
accept === 'form'
@ -73,8 +73,8 @@ export function defineAction<
return serverHandler as ActionClient<TOutput, TAccept, TInputSchema>;
}
function getFormServerHandler<TOutput, TInputSchema extends InputSchema<'form'>>(
handler: Handler<TInputSchema, TOutput>,
function getFormServerHandler<TOutput, TInputSchema extends ActionInputSchema<'form'>>(
handler: ActionHandler<TInputSchema, TOutput>,
inputSchema?: TInputSchema
) {
return async (unparsedInput: unknown): Promise<Awaited<TOutput>> => {
@ -95,8 +95,8 @@ function getFormServerHandler<TOutput, TInputSchema extends InputSchema<'form'>>
};
}
function getJsonServerHandler<TOutput, TInputSchema extends InputSchema<'json'>>(
handler: Handler<TInputSchema, TOutput>,
function getJsonServerHandler<TOutput, TInputSchema extends ActionInputSchema<'json'>>(
handler: ActionHandler<TInputSchema, TOutput>,
inputSchema?: TInputSchema
) {
return async (unparsedInput: unknown): Promise<Awaited<TOutput>> => {

View file

@ -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<ActionErrorCode, number> = {
// Implemented from tRPC error code table