Skip to content

Commit 231bc00

Browse files
committed
feat(metadata): type check passing metadata to actions
If a metadata schema is provided via `defineMetadataSchema` init function, and the `metadata` method is not used before `action`/`stateAction` method, now an error will inform the user that the type is incomplete.
1 parent e7d2772 commit 231bc00

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

packages/next-safe-action/src/action-builder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function actionBuilder<
4242
OS extends StandardSchemaV1 | undefined = undefined, // output schema
4343
const BAS extends readonly StandardSchemaV1[] = [],
4444
CVE = undefined,
45-
>(args: SafeActionClientArgs<ServerError, ODVES, MetadataSchema, MD, Ctx, ISF, IS, OS, BAS, CVE>) {
45+
>(args: SafeActionClientArgs<ServerError, ODVES, MetadataSchema, MD, true, Ctx, ISF, IS, OS, BAS, CVE>) {
4646
const bindArgsSchemas = args.bindArgsSchemas ?? [];
4747

4848
function buildAction({ withState }: { withState: false }): {

packages/next-safe-action/src/index.types.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export type SafeActionClientArgs<
3838
ODVES extends DVES | undefined, // override default validation errors shape
3939
MetadataSchema extends StandardSchemaV1 | undefined = undefined,
4040
MD = InferOutputOrDefault<MetadataSchema, undefined>, // metadata type (inferred from metadata schema)
41+
MDProvided extends boolean = MetadataSchema extends undefined ? true : false,
4142
Ctx extends object = {},
4243
ISF extends (() => Promise<StandardSchemaV1>) | undefined = undefined, // input schema function
4344
IS extends StandardSchemaV1 | undefined = ISF extends Function ? Awaited<ReturnType<ISF>> : undefined, // input schema
@@ -48,6 +49,7 @@ export type SafeActionClientArgs<
4849
middlewareFns: MiddlewareFn<ServerError, any, any, any>[];
4950
metadataSchema: MetadataSchema;
5051
metadata: MD;
52+
metadataProvided?: MDProvided;
5153
inputSchemaFn: ISF;
5254
outputSchema: OS;
5355
bindArgsSchemas: BAS;
@@ -295,7 +297,7 @@ export type InferMiddlewareFnNextCtx<T> =
295297
* Infer the context type of a safe action client or middleware function.
296298
*/
297299
export type InferCtx<T> = T extends
298-
| SafeActionClient<any, any, any, any, infer Ctx extends object, any, any, any, any, any>
300+
| SafeActionClient<any, any, any, any, false, infer Ctx extends object, any, any, any, any, any>
299301
| MiddlewareFn<any, any, infer Ctx extends object, any>
300302
? Ctx
301303
: never;
@@ -304,7 +306,7 @@ export type InferCtx<T> = T extends
304306
* Infer the metadata type of a safe action client or middleware function.
305307
*/
306308
export type InferMetadata<T> = T extends
307-
| SafeActionClient<any, any, any, infer MD, any, any, any, any, any, any>
309+
| SafeActionClient<any, any, any, infer MD, false, any, any, any, any, any, any>
308310
| MiddlewareFn<any, infer MD, any, any>
309311
? MD
310312
: never;
@@ -313,7 +315,7 @@ export type InferMetadata<T> = T extends
313315
* Infer the server error type from a safe action client or a middleware function or a safe action function.
314316
*/
315317
export type InferServerError<T> = T extends
316-
| SafeActionClient<infer ServerError, any, any, any, any, any, any, any, any, any>
318+
| SafeActionClient<infer ServerError, any, any, any, any, any, any, any, any, any, any>
317319
| MiddlewareFn<infer ServerError, any, any, any>
318320
| SafeActionFn<infer ServerError, any, any, any, any>
319321
| SafeStateActionFn<infer ServerError, any, any, any, any>

packages/next-safe-action/src/safe-action-client.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,19 @@ export class SafeActionClient<
1919
ODVES extends DVES | undefined, // override default validation errors shape
2020
MetadataSchema extends StandardSchemaV1 | undefined = undefined,
2121
MD = InferOutputOrDefault<MetadataSchema, undefined>, // metadata type (inferred from metadata schema)
22+
MDProvided extends boolean = MetadataSchema extends undefined ? true : false,
2223
Ctx extends object = {},
2324
ISF extends (() => Promise<StandardSchemaV1>) | undefined = undefined, // input schema function
2425
IS extends StandardSchemaV1 | undefined = ISF extends Function ? Awaited<ReturnType<ISF>> : undefined, // input schema
2526
OS extends StandardSchemaV1 | undefined = undefined, // output schema
2627
const BAS extends readonly StandardSchemaV1[] = [],
2728
CVE = undefined,
2829
> {
29-
readonly #args: SafeActionClientArgs<ServerError, ODVES, MetadataSchema, MD, Ctx, ISF, IS, OS, BAS, CVE>;
30+
readonly #args: SafeActionClientArgs<ServerError, ODVES, MetadataSchema, MD, MDProvided, Ctx, ISF, IS, OS, BAS, CVE>;
3031

31-
constructor(args: SafeActionClientArgs<ServerError, ODVES, MetadataSchema, MD, Ctx, ISF, IS, OS, BAS, CVE>) {
32+
constructor(
33+
args: SafeActionClientArgs<ServerError, ODVES, MetadataSchema, MD, MDProvided, Ctx, ISF, IS, OS, BAS, CVE>
34+
) {
3235
this.#args = args;
3336
}
3437

@@ -56,6 +59,7 @@ export class SafeActionClient<
5659
return new SafeActionClient({
5760
...this.#args,
5861
metadata: data,
62+
metadataProvided: true,
5963
});
6064
}
6165

@@ -141,6 +145,9 @@ export class SafeActionClient<
141145
* {@link https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction See docs for more information}
142146
*/
143147
action<Data extends InferOutputOrDefault<OS, any>>(
148+
this: MDProvided extends true
149+
? SafeActionClient<ServerError, ODVES, MetadataSchema, MD, MDProvided, Ctx, ISF, IS, OS, BAS, CVE>
150+
: never,
144151
serverCodeFn: ServerCodeFn<MD, Ctx, IS, BAS, Data>,
145152
utils?: SafeActionUtils<ServerError, MD, Ctx, IS, BAS, CVE, Data>
146153
) {
@@ -156,6 +163,9 @@ export class SafeActionClient<
156163
* {@link https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction See docs for more information}
157164
*/
158165
stateAction<Data extends InferOutputOrDefault<OS, any>>(
166+
this: MDProvided extends true
167+
? SafeActionClient<ServerError, ODVES, MetadataSchema, MD, MDProvided, Ctx, ISF, IS, OS, BAS, CVE>
168+
: never,
159169
serverCodeFn: StateServerCodeFn<ServerError, MD, Ctx, IS, BAS, CVE, Data>,
160170
utils?: SafeActionUtils<ServerError, MD, Ctx, IS, BAS, CVE, Data>
161171
) {

0 commit comments

Comments
 (0)