From 38496f721bcb14494688b2aade9e148b5fd36537 Mon Sep 17 00:00:00 2001
From: Edoardo Ranghieri <edoardo@ranghieri.com>
Date: Thu, 18 Jul 2024 14:33:24 +0200
Subject: [PATCH] fix: implementation of modular built-in multi validation
 system

---
 apps/playground/src/lib/safe-action.ts        |  2 ++
 packages/next-safe-action/package.json        |  6 ++++-
 .../src/__tests__/action-callbacks.test.ts    |  2 ++
 .../bind-args-validation-errors.test.ts       |  7 ++++-
 .../combined-validation-errors.test.ts        |  7 ++++-
 .../src/__tests__/happy-path.test.ts          |  5 +++-
 .../src/__tests__/metadata.test.ts            |  2 ++
 .../src/__tests__/middleware.test.ts          |  3 +++
 .../src/__tests__/server-error.test.ts        |  4 +++
 .../src/__tests__/validation-errors.test.ts   |  8 +++++-
 .../next-safe-action/src/action-builder.ts    |  2 +-
 .../types.ts                                  |  0
 .../libs => adapters}/zod.ts                  |  2 +-
 packages/next-safe-action/src/hooks-utils.ts  |  2 +-
 packages/next-safe-action/src/hooks.ts        |  2 +-
 packages/next-safe-action/src/hooks.types.ts  |  2 +-
 packages/next-safe-action/src/index.ts        | 27 ++++++++-----------
 packages/next-safe-action/src/index.types.ts  |  4 +--
 .../src/safe-action-client.ts                 |  2 +-
 .../next-safe-action/src/stateful-hooks.ts    |  2 +-
 .../src/validation-adapters/index.ts          |  3 ---
 .../next-safe-action/src/validation-errors.ts |  2 +-
 .../src/validation-errors.types.ts            |  2 +-
 packages/next-safe-action/tsup.config.ts      |  2 +-
 24 files changed, 64 insertions(+), 36 deletions(-)
 rename packages/next-safe-action/src/{validation-adapters => adapters}/types.ts (100%)
 rename packages/next-safe-action/src/{validation-adapters/libs => adapters}/zod.ts (89%)
 delete mode 100644 packages/next-safe-action/src/validation-adapters/index.ts

diff --git a/apps/playground/src/lib/safe-action.ts b/apps/playground/src/lib/safe-action.ts
index 83723938..f53569d5 100644
--- a/apps/playground/src/lib/safe-action.ts
+++ b/apps/playground/src/lib/safe-action.ts
@@ -2,11 +2,13 @@ import {
 	DEFAULT_SERVER_ERROR_MESSAGE,
 	createSafeActionClient,
 } from "next-safe-action";
+import { zodAdapter } from "next-safe-action/adapters/zod";
 import { z } from "zod";
 
 export class ActionError extends Error {}
 
 export const action = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	// You can provide a custom logging function, otherwise the lib will use `console.error`
 	// as the default logging system. If you want to disable server errors logging,
 	// just pass an empty Promise.
diff --git a/packages/next-safe-action/package.json b/packages/next-safe-action/package.json
index 335af90b..83b298d4 100644
--- a/packages/next-safe-action/package.json
+++ b/packages/next-safe-action/package.json
@@ -12,7 +12,8 @@
 	"exports": {
 		".": "./dist/index.mjs",
 		"./hooks": "./dist/hooks.mjs",
-		"./stateful-hooks": "./dist/stateful-hooks.mjs"
+		"./stateful-hooks": "./dist/stateful-hooks.mjs",
+		"./adapters/*": "./dist/adapters/*.mjs"
 	},
 	"typesVersions": {
 		"*": {
@@ -24,6 +25,9 @@
 			],
 			"stateful-hooks": [
 				"./dist/stateful-hooks.d.mts"
+			],
+			"adapters/*": [
+				"./dist/adapters/*.d.mts"
 			]
 		}
 	},
diff --git a/packages/next-safe-action/src/__tests__/action-callbacks.test.ts b/packages/next-safe-action/src/__tests__/action-callbacks.test.ts
index c865af2e..84fb3d63 100644
--- a/packages/next-safe-action/src/__tests__/action-callbacks.test.ts
+++ b/packages/next-safe-action/src/__tests__/action-callbacks.test.ts
@@ -4,8 +4,10 @@ import assert from "node:assert";
 import { test } from "node:test";
 import { z } from "zod";
 import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient, returnValidationErrors } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 const ac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defineMetadataSchema() {
 		return z.object({
 			actionName: z.string(),
diff --git a/packages/next-safe-action/src/__tests__/bind-args-validation-errors.test.ts b/packages/next-safe-action/src/__tests__/bind-args-validation-errors.test.ts
index 9ec1efa9..0fce6388 100644
--- a/packages/next-safe-action/src/__tests__/bind-args-validation-errors.test.ts
+++ b/packages/next-safe-action/src/__tests__/bind-args-validation-errors.test.ts
@@ -4,10 +4,13 @@ import assert from "node:assert";
 import { test } from "node:test";
 import { z } from "zod";
 import { createSafeActionClient, flattenBindArgsValidationErrors, formatBindArgsValidationErrors } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 // Default client tests.
 
-const dac = createSafeActionClient();
+const dac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
+});
 
 test("action with invalid bind args input gives back an object with correct `bindArgsValidationErrors` (default formatted shape)", async () => {
 	const bindArgsSchemas: [age: z.ZodNumber, userId: z.ZodString, product: z.ZodObject<{ id: z.ZodString }>] = [
@@ -87,6 +90,7 @@ test("action with invalid bind args input gives back an object with correct `bin
 // Formatted shape tests (same as default).
 
 const foac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defaultValidationErrorsShape: "formatted",
 });
 
@@ -168,6 +172,7 @@ test("action with invalid bind args input gives back an object with correct `bin
 // Flattened shape tests.
 
 const flac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defaultValidationErrorsShape: "flattened",
 });
 
diff --git a/packages/next-safe-action/src/__tests__/combined-validation-errors.test.ts b/packages/next-safe-action/src/__tests__/combined-validation-errors.test.ts
index d44c944d..1b7f3403 100644
--- a/packages/next-safe-action/src/__tests__/combined-validation-errors.test.ts
+++ b/packages/next-safe-action/src/__tests__/combined-validation-errors.test.ts
@@ -10,10 +10,13 @@ import {
 	formatBindArgsValidationErrors,
 	formatValidationErrors,
 } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 // Default client tests.
 
-const dac = createSafeActionClient();
+const dac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
+});
 
 test("action with invalid bind args input and valid main input gives back an object with correct `bindArgsValidationErrors` (default formatted shape)", async () => {
 	const schema = z.object({
@@ -110,6 +113,7 @@ test("action with invalid bind args input and invalid main input gives back an o
 // Formatted shape tests (same as default).
 
 const foac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defaultValidationErrorsShape: "formatted",
 });
 
@@ -209,6 +213,7 @@ test("action with invalid bind args input and valid main input gives back an obj
 // Flattened shape tests.
 
 const flac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defaultValidationErrorsShape: "flattened",
 });
 
diff --git a/packages/next-safe-action/src/__tests__/happy-path.test.ts b/packages/next-safe-action/src/__tests__/happy-path.test.ts
index 32f207b6..c3f368bd 100644
--- a/packages/next-safe-action/src/__tests__/happy-path.test.ts
+++ b/packages/next-safe-action/src/__tests__/happy-path.test.ts
@@ -4,8 +4,11 @@ import assert from "node:assert";
 import { test } from "node:test";
 import { z } from "zod";
 import { createSafeActionClient } from "..";
+import { zodAdapter } from "../adapters/zod";
 
-const ac = createSafeActionClient();
+const ac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
+});
 
 test("action with no input schema returns empty object", async () => {
 	const action = ac.action(async () => {
diff --git a/packages/next-safe-action/src/__tests__/metadata.test.ts b/packages/next-safe-action/src/__tests__/metadata.test.ts
index 554f86e4..a9f6fbea 100644
--- a/packages/next-safe-action/src/__tests__/metadata.test.ts
+++ b/packages/next-safe-action/src/__tests__/metadata.test.ts
@@ -4,8 +4,10 @@ import assert from "node:assert";
 import { test } from "node:test";
 import { z } from "zod";
 import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 const ac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	handleServerErrorLog() {}, // disable server errors logging for these tests
 	defineMetadataSchema() {
 		return z.object({
diff --git a/packages/next-safe-action/src/__tests__/middleware.test.ts b/packages/next-safe-action/src/__tests__/middleware.test.ts
index c7cac88e..60ba0ae5 100644
--- a/packages/next-safe-action/src/__tests__/middleware.test.ts
+++ b/packages/next-safe-action/src/__tests__/middleware.test.ts
@@ -9,8 +9,10 @@ import {
 	formatValidationErrors,
 	returnValidationErrors,
 } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 const ac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	handleServerErrorLog() {}, // disable server errors logging for these tests
 	handleReturnedServerError(e) {
 		return {
@@ -292,6 +294,7 @@ test("server validation errors in execution result from middleware are correct",
 // Flattened validation errors shape.
 
 const flac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	handleServerErrorLog() {}, // disable server errors logging for these tests
 	defaultValidationErrorsShape: "flattened",
 });
diff --git a/packages/next-safe-action/src/__tests__/server-error.test.ts b/packages/next-safe-action/src/__tests__/server-error.test.ts
index 25e0306d..bdc79f8c 100644
--- a/packages/next-safe-action/src/__tests__/server-error.test.ts
+++ b/packages/next-safe-action/src/__tests__/server-error.test.ts
@@ -3,6 +3,7 @@
 import assert from "node:assert";
 import { test } from "node:test";
 import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 class ActionError extends Error {
 	constructor(message: string) {
@@ -11,6 +12,7 @@ class ActionError extends Error {
 }
 
 const ac1 = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	handleServerErrorLog: () => {}, // disable server errors logging for these tests
 	handleReturnedServerError(e) {
 		if (e instanceof ActionError) {
@@ -93,6 +95,7 @@ test("known error occurred in middleware function is unmasked", async () => {
 
 // Server error is an object with a 'message' property.
 const ac2 = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	handleServerErrorLog: () => {}, // disable server errors logging for these tests
 	handleReturnedServerError(e) {
 		return {
@@ -138,6 +141,7 @@ test("error occurred in middleware function has the correct shape defined by `ha
 
 // Rethrow all server errors.
 const ac3 = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	handleServerErrorLog: () => {}, // disable server errors logging for these tests
 	handleReturnedServerError(e) {
 		throw e;
diff --git a/packages/next-safe-action/src/__tests__/validation-errors.test.ts b/packages/next-safe-action/src/__tests__/validation-errors.test.ts
index 2910fd86..25e83adf 100644
--- a/packages/next-safe-action/src/__tests__/validation-errors.test.ts
+++ b/packages/next-safe-action/src/__tests__/validation-errors.test.ts
@@ -4,10 +4,13 @@ import assert from "node:assert";
 import { test } from "node:test";
 import { z } from "zod";
 import { createSafeActionClient, flattenValidationErrors, formatValidationErrors, returnValidationErrors } from "..";
+import { zodAdapter } from "../adapters/zod";
 
 // Default client tests.
 
-const dac = createSafeActionClient();
+const dac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
+});
 
 test("action with invalid input gives back an object with correct `validationErrors` (default formatted shape)", async () => {
 	const schema = z.object({
@@ -144,6 +147,7 @@ test("action with invalid input gives back an object with correct `validationErr
 // Formatted shape tests (same as default).
 
 const foac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defaultValidationErrorsShape: "formatted",
 });
 
@@ -282,6 +286,7 @@ test("action with invalid input gives back an object with correct `validationErr
 // Flattened shape tests.
 
 const flac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	defaultValidationErrorsShape: "flattened",
 });
 
@@ -537,6 +542,7 @@ test("action with errors set via `returnValidationErrors` gives back an object w
 // `throwValidationErrors` tests.
 
 const tveac = createSafeActionClient({
+	validationAdapter: zodAdapter(),
 	throwValidationErrors: true,
 });
 
diff --git a/packages/next-safe-action/src/action-builder.ts b/packages/next-safe-action/src/action-builder.ts
index 407e1bbb..113c76d0 100644
--- a/packages/next-safe-action/src/action-builder.ts
+++ b/packages/next-safe-action/src/action-builder.ts
@@ -1,6 +1,7 @@
 import { isNotFoundError } from "next/dist/client/components/not-found.js";
 import { isRedirectError } from "next/dist/client/components/redirect.js";
 import type {} from "zod";
+import type { Infer, InferArray, InferIn, InferInArray, Schema, ValidationAdapter } from "./adapters/types";
 import type {
 	MiddlewareFn,
 	MiddlewareResult,
@@ -13,7 +14,6 @@ import type {
 	StateServerCodeFn,
 } from "./index.types";
 import { ActionMetadataError, DEFAULT_SERVER_ERROR_MESSAGE, isError } from "./utils";
-import type { Infer, InferArray, InferIn, InferInArray, Schema, ValidationAdapter } from "./validation-adapters";
 import { ActionValidationError, buildValidationErrors } from "./validation-errors";
 import type {
 	BindArgsValidationErrors,
diff --git a/packages/next-safe-action/src/validation-adapters/types.ts b/packages/next-safe-action/src/adapters/types.ts
similarity index 100%
rename from packages/next-safe-action/src/validation-adapters/types.ts
rename to packages/next-safe-action/src/adapters/types.ts
diff --git a/packages/next-safe-action/src/validation-adapters/libs/zod.ts b/packages/next-safe-action/src/adapters/zod.ts
similarity index 89%
rename from packages/next-safe-action/src/validation-adapters/libs/zod.ts
rename to packages/next-safe-action/src/adapters/zod.ts
index e0103ba1..64197708 100644
--- a/packages/next-safe-action/src/validation-adapters/libs/zod.ts
+++ b/packages/next-safe-action/src/adapters/zod.ts
@@ -1,5 +1,5 @@
 import type { z } from "zod";
-import type { Infer, ValidationAdapter } from "../types";
+import type { Infer, ValidationAdapter } from "./types";
 
 class ZodAdapter implements ValidationAdapter {
 	async validate<S extends z.ZodType>(schema: S, data: unknown) {
diff --git a/packages/next-safe-action/src/hooks-utils.ts b/packages/next-safe-action/src/hooks-utils.ts
index 25c83460..c1190ab0 100644
--- a/packages/next-safe-action/src/hooks-utils.ts
+++ b/packages/next-safe-action/src/hooks-utils.ts
@@ -1,8 +1,8 @@
 import * as React from "react";
 import {} from "react/experimental";
 import type {} from "zod";
+import type { InferIn, Schema } from "./adapters/types";
 import type { HookActionStatus, HookCallbacks, HookResult } from "./hooks.types";
-import type { InferIn, Schema } from "./validation-adapters";
 
 export const getActionStatus = <
 	ServerError,
diff --git a/packages/next-safe-action/src/hooks.ts b/packages/next-safe-action/src/hooks.ts
index 60f42743..bfef56e6 100644
--- a/packages/next-safe-action/src/hooks.ts
+++ b/packages/next-safe-action/src/hooks.ts
@@ -6,10 +6,10 @@ import * as React from "react";
 import * as ReactDOM from "react-dom";
 import {} from "react/experimental";
 import type {} from "zod";
+import type { InferIn, Schema } from "./adapters/types";
 import { getActionShorthandStatusObject, getActionStatus, useActionCallbacks } from "./hooks-utils";
 import type { HookCallbacks, HookResult, HookSafeActionFn } from "./hooks.types";
 import { isError } from "./utils";
-import type { InferIn, Schema } from "./validation-adapters";
 
 // HOOKS
 
diff --git a/packages/next-safe-action/src/hooks.types.ts b/packages/next-safe-action/src/hooks.types.ts
index 549c3a36..f285d5d5 100644
--- a/packages/next-safe-action/src/hooks.types.ts
+++ b/packages/next-safe-action/src/hooks.types.ts
@@ -1,6 +1,6 @@
+import type { InferIn, Schema } from "./adapters/types";
 import type { SafeActionResult } from "./index.types";
 import type { MaybePromise, Prettify } from "./utils.types";
-import type { InferIn, Schema } from "./validation-adapters";
 
 /**
  * Type of `result` object returned by `useAction`, `useOptimisticAction` and `useStateAction` hooks.
diff --git a/packages/next-safe-action/src/index.ts b/packages/next-safe-action/src/index.ts
index ea431d5b..1b777c18 100644
--- a/packages/next-safe-action/src/index.ts
+++ b/packages/next-safe-action/src/index.ts
@@ -1,7 +1,7 @@
+import type { Infer, Schema } from "./adapters/types";
 import type { DVES, SafeActionClientOpts } from "./index.types";
 import { SafeActionClient } from "./safe-action-client";
 import { DEFAULT_SERVER_ERROR_MESSAGE } from "./utils";
-import type { Infer, Schema } from "./validation-adapters";
 import {
 	flattenBindArgsValidationErrors,
 	flattenValidationErrors,
@@ -25,7 +25,7 @@ export type * from "./validation-errors.types";
 /**
  * Create a new safe action client.
  * Note: this client only works with Zod as the validation library.
- * @param createOpts Optional initialization options
+ * @param createOpts Initialization options
  *
  * {@link https://next-safe-action.dev/docs/safe-action-client/initialization-options See docs for more information}
  */
@@ -34,12 +34,12 @@ export const createSafeActionClient = <
 	ServerError = string,
 	MetadataSchema extends Schema | undefined = undefined,
 >(
-	createOpts?: SafeActionClientOpts<ServerError, MetadataSchema, ODVES>
+	createOpts: SafeActionClientOpts<ServerError, MetadataSchema, ODVES>
 ) => {
 	// If server log function is not provided, default to `console.error` for logging
 	// server error messages.
 	const handleServerErrorLog =
-		createOpts?.handleServerErrorLog ||
+		createOpts.handleServerErrorLog ||
 		(((originalError: Error) => {
 			console.error("Action error:", originalError.message);
 		}) as unknown as NonNullable<SafeActionClientOpts<ServerError, MetadataSchema, ODVES>["handleServerErrorLog"]>);
@@ -48,32 +48,27 @@ export const createSafeActionClient = <
 	// messages returned on the client.
 	// Otherwise mask the error and use a generic message.
 	const handleReturnedServerError =
-		createOpts?.handleReturnedServerError ||
+		createOpts.handleReturnedServerError ||
 		((() => DEFAULT_SERVER_ERROR_MESSAGE) as unknown as NonNullable<
 			SafeActionClientOpts<ServerError, MetadataSchema, ODVES>["handleReturnedServerError"]
 		>);
 
-	// FIXME: require validation adapter
-	if (!createOpts?.validationAdapter) {
-		throw new Error("Validation adapter is required");
-	}
-
 	return new SafeActionClient({
 		middlewareFns: [async ({ next }) => next({ ctx: undefined })],
 		handleServerErrorLog,
 		handleReturnedServerError,
 		schemaFn: undefined,
 		bindArgsSchemas: [],
-		validationAdapter: createOpts.validationAdapter(),
+		validationAdapter: createOpts.validationAdapter,
 		ctxType: undefined,
-		metadataSchema: (createOpts?.defineMetadataSchema?.() ?? undefined) as MetadataSchema,
+		metadataSchema: (createOpts.defineMetadataSchema?.() ?? undefined) as MetadataSchema,
 		metadata: undefined as MetadataSchema extends Schema ? Infer<MetadataSchema> : undefined,
-		defaultValidationErrorsShape: (createOpts?.defaultValidationErrorsShape ?? "formatted") as ODVES,
-		throwValidationErrors: Boolean(createOpts?.throwValidationErrors),
+		defaultValidationErrorsShape: (createOpts.defaultValidationErrorsShape ?? "formatted") as ODVES,
+		throwValidationErrors: Boolean(createOpts.throwValidationErrors),
 		handleValidationErrorsShape:
-			createOpts?.defaultValidationErrorsShape === "flattened" ? flattenValidationErrors : formatValidationErrors,
+			createOpts.defaultValidationErrorsShape === "flattened" ? flattenValidationErrors : formatValidationErrors,
 		handleBindArgsValidationErrorsShape:
-			createOpts?.defaultValidationErrorsShape === "flattened"
+			createOpts.defaultValidationErrorsShape === "flattened"
 				? flattenBindArgsValidationErrors
 				: formatBindArgsValidationErrors,
 	});
diff --git a/packages/next-safe-action/src/index.types.ts b/packages/next-safe-action/src/index.types.ts
index 5286d2ac..ce0fb6b0 100644
--- a/packages/next-safe-action/src/index.types.ts
+++ b/packages/next-safe-action/src/index.types.ts
@@ -1,5 +1,5 @@
+import type { Infer, InferArray, InferIn, InferInArray, Schema, ValidationAdapter } from "./adapters/types";
 import type { MaybePromise, Prettify } from "./utils.types";
-import type { Infer, InferArray, InferIn, InferInArray, Schema, ValidationAdapter } from "./validation-adapters";
 import type { BindArgsValidationErrors, ValidationErrors } from "./validation-errors.types";
 
 /**
@@ -26,7 +26,7 @@ export type SafeActionClientOpts<
 	MetadataSchema extends Schema | undefined,
 	ODVES extends DVES | undefined,
 > = {
-	validationAdapter: () => ValidationAdapter;
+	validationAdapter: ValidationAdapter;
 	defineMetadataSchema?: () => MetadataSchema;
 	handleReturnedServerError?: (
 		error: Error,
diff --git a/packages/next-safe-action/src/safe-action-client.ts b/packages/next-safe-action/src/safe-action-client.ts
index b1fb82af..f0938437 100644
--- a/packages/next-safe-action/src/safe-action-client.ts
+++ b/packages/next-safe-action/src/safe-action-client.ts
@@ -1,5 +1,6 @@
 import type {} from "zod";
 import { actionBuilder } from "./action-builder";
+import type { Infer, Schema, ValidationAdapter } from "./adapters/types";
 import type {
 	DVES,
 	MiddlewareFn,
@@ -8,7 +9,6 @@ import type {
 	ServerCodeFn,
 	StateServerCodeFn,
 } from "./index.types";
-import type { Infer, Schema, ValidationAdapter } from "./validation-adapters";
 import type {
 	BindArgsValidationErrors,
 	FlattenedBindArgsValidationErrors,
diff --git a/packages/next-safe-action/src/stateful-hooks.ts b/packages/next-safe-action/src/stateful-hooks.ts
index b020b9d5..7cc27398 100644
--- a/packages/next-safe-action/src/stateful-hooks.ts
+++ b/packages/next-safe-action/src/stateful-hooks.ts
@@ -4,9 +4,9 @@ import * as React from "react";
 import * as ReactDOM from "react-dom";
 import {} from "react/experimental";
 import type {} from "zod";
+import type { InferIn, Schema } from "./adapters/types";
 import { getActionShorthandStatusObject, getActionStatus, useActionCallbacks } from "./hooks-utils";
 import type { HookCallbacks, HookSafeStateActionFn } from "./hooks.types";
-import type { InferIn, Schema } from "./validation-adapters";
 /**
  * Use the stateful action from a Client Component via hook. Used for actions defined with [`stateAction`](https://next-safe-action.dev/docs/safe-action-client/instance-methods#action--stateaction).
  * @param safeActionFn The action function
diff --git a/packages/next-safe-action/src/validation-adapters/index.ts b/packages/next-safe-action/src/validation-adapters/index.ts
deleted file mode 100644
index eade091c..00000000
--- a/packages/next-safe-action/src/validation-adapters/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { zodAdapter } from "./libs/zod";
-
-export * from "./types";
diff --git a/packages/next-safe-action/src/validation-errors.ts b/packages/next-safe-action/src/validation-errors.ts
index 6c134b64..2252cc18 100644
--- a/packages/next-safe-action/src/validation-errors.ts
+++ b/packages/next-safe-action/src/validation-errors.ts
@@ -1,6 +1,6 @@
 /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
 
-import type { Schema } from "./validation-adapters";
+import type { Schema } from "./adapters/types";
 import type {
 	FlattenedBindArgsValidationErrors,
 	FlattenedValidationErrors,
diff --git a/packages/next-safe-action/src/validation-errors.types.ts b/packages/next-safe-action/src/validation-errors.types.ts
index 9c92571d..9288800f 100644
--- a/packages/next-safe-action/src/validation-errors.types.ts
+++ b/packages/next-safe-action/src/validation-errors.types.ts
@@ -1,5 +1,5 @@
+import type { Infer, Schema } from "./adapters/types";
 import type { Prettify } from "./utils.types";
-import type { Infer, Schema } from "./validation-adapters";
 
 export type ValidationIssue = {
 	message: string;
diff --git a/packages/next-safe-action/tsup.config.ts b/packages/next-safe-action/tsup.config.ts
index 006872e9..cf5c4d13 100644
--- a/packages/next-safe-action/tsup.config.ts
+++ b/packages/next-safe-action/tsup.config.ts
@@ -1,7 +1,7 @@
 import { defineConfig } from "tsup";
 
 export default defineConfig({
-	entry: ["src/*.ts", "src/validation-adapters/**/*.ts"],
+	entry: ["src/*.ts", "src/adapters/*.ts"],
 	bundle: false,
 	format: ["esm"],
 	clean: true,