From 87868a2db2303bb20657a4e19fc2e9b151f7ceb6 Mon Sep 17 00:00:00 2001 From: Edoardo Ranghieri Date: Mon, 12 Aug 2024 04:33:26 +0200 Subject: [PATCH] feat(middleware): support standalone middleware definition via exported `createMiddleware` function --- packages/next-safe-action/src/index.ts | 2 +- packages/next-safe-action/src/utils.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/next-safe-action/src/index.ts b/packages/next-safe-action/src/index.ts index 7c6756c1..967caa29 100644 --- a/packages/next-safe-action/src/index.ts +++ b/packages/next-safe-action/src/index.ts @@ -10,7 +10,7 @@ import { formatValidationErrors, } from "./validation-errors"; -export { ActionMetadataError, DEFAULT_SERVER_ERROR_MESSAGE } from "./utils"; +export { ActionMetadataError, createMiddleware, DEFAULT_SERVER_ERROR_MESSAGE } from "./utils"; export { ActionValidationError, flattenBindArgsValidationErrors, diff --git a/packages/next-safe-action/src/utils.ts b/packages/next-safe-action/src/utils.ts index c923c9ec..aaa41115 100644 --- a/packages/next-safe-action/src/utils.ts +++ b/packages/next-safe-action/src/utils.ts @@ -1,3 +1,5 @@ +import type { MiddlewareFn } from "./index.types"; + export const DEFAULT_SERVER_ERROR_MESSAGE = "Something went wrong while executing the operation."; export const isError = (error: unknown): error is Error => error instanceof Error; @@ -28,3 +30,23 @@ export class ActionMetadataError extends Error { this.name = "ActionMetadataError"; } } + +/** + * Creates a standalone middleware function. It accepts a generic object with optional `serverError`, `ctx` and `metadata` + * properties, if you need one or all of them to be typed. The type for each property that is passed as generic is the + * **minimum** shape required to define the middleware function, but it can also be larger than that. + * + * {@link https://next-safe-action.dev/docs/safe-action-client/middleware#create-standalone-middleware-with-createmiddleware See docs for more information} + */ +export const createMiddleware = () => { + return { + define: ( + middlewareFn: MiddlewareFn< + BaseData extends { serverError: infer SE } ? SE : any, + BaseData extends { metadata: infer MD } ? MD : any, + BaseData extends { ctx: infer Ctx extends object } ? Ctx : object, + NextCtx + > + ) => middlewareFn, + }; +};