From 60fe112b3de93609d24b02b943d76d9ae7b8ab25 Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Tue, 9 Jul 2024 16:35:28 -0400 Subject: [PATCH] Fix: Actions `accept` type completions (#11436) * fix: `accept` type completions * chore: changeset * Edit: fix -> fixes astro:actions Co-authored-by: Florian Lefebvre * feat(test): accept types --------- Co-authored-by: bholmesdev Co-authored-by: Florian Lefebvre --- .changeset/swift-cows-walk.md | 5 +++ .../src/actions/runtime/virtual/server.ts | 6 +-- .../astro/test/types/define-action-accept.ts | 45 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 .changeset/swift-cows-walk.md create mode 100644 packages/astro/test/types/define-action-accept.ts diff --git a/.changeset/swift-cows-walk.md b/.changeset/swift-cows-walk.md new file mode 100644 index 0000000000..212d0417e6 --- /dev/null +++ b/.changeset/swift-cows-walk.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fixes `astro:actions` autocompletion for the `defineAction` `accept` property diff --git a/packages/astro/src/actions/runtime/virtual/server.ts b/packages/astro/src/actions/runtime/virtual/server.ts index 4d3745a687..500336f754 100644 --- a/packages/astro/src/actions/runtime/virtual/server.ts +++ b/packages/astro/src/actions/runtime/virtual/server.ts @@ -11,7 +11,7 @@ export { z } from 'zod'; export const getApiContext = _getApiContext; export type Accept = 'form' | 'json'; -export type InputSchema = T extends 'form' +export type InputSchema = T extends 'form' ? z.AnyZodObject | z.ZodType : z.ZodType; @@ -21,7 +21,7 @@ type Handler = TInputSchema extends z.ZodType export type ActionClient< TOutput, - TAccept extends Accept, + TAccept extends Accept | undefined, TInputSchema extends InputSchema | undefined, > = TInputSchema extends z.ZodType ? (( @@ -44,7 +44,7 @@ export type ActionClient< export function defineAction< TOutput, - TAccept extends Accept = 'json', + TAccept extends Accept | undefined = undefined, TInputSchema extends InputSchema | undefined = TAccept extends 'form' ? // If `input` is omitted, default to `FormData` for forms and `any` for JSON. z.ZodType diff --git a/packages/astro/test/types/define-action-accept.ts b/packages/astro/test/types/define-action-accept.ts new file mode 100644 index 0000000000..c9a9ca315a --- /dev/null +++ b/packages/astro/test/types/define-action-accept.ts @@ -0,0 +1,45 @@ +import { describe, it } from 'node:test'; +import { expectTypeOf } from 'expect-type'; +import { defineAction } from '../../dist/actions/runtime/virtual/server.js'; +import { z } from '../../zod.mjs'; + +describe('defineAction accept', () => { + it('accepts type `any` when input is omitted with accept json', async () => { + const action = defineAction({ + handler: () => {}, + }); + expectTypeOf(action).parameter(0).toBeAny(); + expectTypeOf(action).parameter(0).not.toEqualTypeOf(); + + const jsonAction = defineAction({ + accept: 'json', + handler: () => {}, + }); + expectTypeOf(jsonAction).parameter(0).toBeAny(); + expectTypeOf(jsonAction).parameter(0).not.toEqualTypeOf(); + }); + it('accepts type `FormData` when input is omitted with accept form', async () => { + const action = defineAction({ + accept: 'form', + handler: () => {}, + }); + expectTypeOf(action).parameter(0).toEqualTypeOf(); + }); + + it('accept type safe values for input with accept json', async () => { + const action = defineAction({ + input: z.object({ name: z.string() }), + handler: () => {}, + }); + expectTypeOf(action).parameter(0).toEqualTypeOf<{ name: string }>(); + }); + + it('accepts type `FormData` for all inputs with accept form', async () => { + const action = defineAction({ + accept: 'form', + input: z.object({ name: z.string() }), + handler: () => {}, + }); + expectTypeOf(action).parameter(0).toEqualTypeOf(); + }); +});