From d9d326e3de565e84b865d73607fc1bd8ea97fb5b Mon Sep 17 00:00:00 2001 From: Edoardo Ranghieri Date: Sun, 18 Aug 2024 15:53:40 +0200 Subject: [PATCH] feat(middleware): make `createMiddleware` function stable Rename exported `experimental_createMiddleware` function to `createMiddleware`, making it stable API. --- .../src/__tests__/middleware.test.ts | 4 ++-- packages/next-safe-action/src/index.ts | 2 +- website/docs/safe-action-client/middleware.md | 14 +++++++------- website/docs/types/infer-types.md | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/next-safe-action/src/__tests__/middleware.test.ts b/packages/next-safe-action/src/__tests__/middleware.test.ts index 0c66815e..f1a7bc74 100644 --- a/packages/next-safe-action/src/__tests__/middleware.test.ts +++ b/packages/next-safe-action/src/__tests__/middleware.test.ts @@ -4,8 +4,8 @@ import assert from "node:assert"; import { test } from "node:test"; import { z } from "zod"; import { + createMiddleware, createSafeActionClient, - experimental_createMiddleware, formatBindArgsValidationErrors, formatValidationErrors, returnValidationErrors, @@ -397,7 +397,7 @@ test("overridden formatted validation errors in execution result from middleware }); test("standalone middleware extends context", async () => { - const myMiddleware = experimental_createMiddleware<{ ctx: { foo: string } }>().define(async ({ next }) => { + const myMiddleware = createMiddleware<{ ctx: { foo: string } }>().define(async ({ next }) => { return next({ ctx: { baz: "qux" } }); }); diff --git a/packages/next-safe-action/src/index.ts b/packages/next-safe-action/src/index.ts index e3eb1030..b40e2417 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 { createMiddleware as experimental_createMiddleware } from "./middleware"; +export { createMiddleware } from "./middleware"; export { ActionMetadataError, DEFAULT_SERVER_ERROR_MESSAGE } from "./utils"; export { ActionValidationError, diff --git a/website/docs/safe-action-client/middleware.md b/website/docs/safe-action-client/middleware.md index 0b0536b8..4d463b54 100644 --- a/website/docs/safe-action-client/middleware.md +++ b/website/docs/safe-action-client/middleware.md @@ -243,17 +243,17 @@ export const testAction = actionClient ## Create standalone middleware :::info -Experimental feature +Since version 7.7.0, this API is stable, so it was renamed from `experimental_createMiddleware` to `createMiddleware`. ::: -Starting from version 7.6.0, you can create standalone middleware functions using the built-in `experimental_createMiddleware()` function. It's labeled as experimental because the API could change in the future, but it's perfectly fine to use it, as it's a pretty simple function that just wraps the creation of middleware. +Starting from version 7.6.0, you can create standalone middleware functions using the built-in `createMiddleware()` function. Thanks to this feature, and the previously mentioned [context extension](#extend-context), you can now define standalone middleware functions and even publish them as packages, if you want to. -Here's how to use `experimental_createMiddleware()`: +Here's how to use `createMiddleware()`: ```typescript title="src/lib/safe-action.ts" -import { createSafeActionClient, experimental_createMiddleware } from "next-safe-action"; +import { createSafeActionClient, createMiddleware } from "next-safe-action"; import { z } from "zod"; export const actionClient = createSafeActionClient({ @@ -268,14 +268,14 @@ export const actionClient = createSafeActionClient({ }); // This middleware works with any client. -const myMiddleware1 = experimental_createMiddleware().define(async ({ next }) => { +const myMiddleware1 = createMiddleware().define(async ({ next }) => { // Do something useful here... return next({ ctx: { baz: "qux" } }); }); // This middleware works with clients that at minimum have `ctx.foo`, `metadata.actionName` // and `serverError.message` properties. More information below. * -const myMiddleware2 = experimental_createMiddleware<{ +const myMiddleware2 = createMiddleware<{ ctx: { foo: string }; // [1] metadata: { actionName: string }; // [2] serverError: { message: string } // [3] @@ -290,4 +290,4 @@ export const actionClientWithMyMiddleware = actionClient.use(myMiddleware1).use( An action defined using the `actionClientWithMyMiddleware` will contain `foo`, `baz` and `john` in its context. -\* Note that you can pass, **but not required to**, an object with two generic properties to the `experimental_createMiddleware()` function: `ctx` \[1\], `metadata` \[2\] and `serverError` \[3\]. Those keys are optional, and you should only provide them if you want your middleware to require **at minimum** the shape you passed in as generic. By doing that, following the above example, you can then access `ctx.foo` and `metadata.actionName` in the middleware you're defining, and by awaiting the `next` function you'll see that `serverError` is an object with the `message` property. If you pass a middleware that requires those properties to a client that doesn't have them, you'll get an error in `use()` method. \ No newline at end of file +\* Note that you can pass, **but not required to**, an object with two generic properties to the `createMiddleware()` function: `ctx` \[1\], `metadata` \[2\] and `serverError` \[3\]. Those keys are optional, and you should only provide them if you want your middleware to require **at minimum** the shape you passed in as generic. By doing that, following the above example, you can then access `ctx.foo` and `metadata.actionName` in the middleware you're defining, and by awaiting the `next` function you'll see that `serverError` is an object with the `message` property. If you pass a middleware that requires those properties to a client that doesn't have them, you'll get an error in `use()` method. \ No newline at end of file diff --git a/website/docs/types/infer-types.md b/website/docs/types/infer-types.md index 2cd2134a..7f9953f8 100644 --- a/website/docs/types/infer-types.md +++ b/website/docs/types/infer-types.md @@ -11,11 +11,11 @@ Suppose we have declared this safe action client: ```typescript title="src/lib/safe-action.ts" import { z } from "zod"; -import { createSafeActionClient, experimental_createMiddleware } from "next-safe-action"; +import { createSafeActionClient, createMiddleware } from "next-safe-action"; import { getSessionData } from "@/services/auth" // Here we declare a standalone auth middleware. -export const authMiddleware = experimental_createMiddleware<{ +export const authMiddleware = createMiddleware<{ ctx: { sessionToken: string }; metadata: { actionName: string }; }>().define(async ({ ctx, next }) => {