Skip to content

Commit baff76b

Browse files
authored
feat: built-in support for multiple validation libraries (#202)
Make use of built-in modular support for multiple validation libraries, instead of TypeSchema.
1 parent e00829a commit baff76b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+612
-2817
lines changed

apps/playground/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
"zod-form-data": "^2.0.2"
2222
},
2323
"devDependencies": {
24-
"@types/node": "^20.12.10",
24+
"@types/node": "^20.14.11",
2525
"@types/react": "^18.3.1",
2626
"@types/react-dom": "18.3.0",
2727
"autoprefixer": "10.4.19",
2828
"eslint": "^8.57.0",
2929
"eslint-config-next": "15.0.0-canary.25",
3030
"postcss": "8.4.38",
3131
"tailwindcss": "3.4.3",
32-
"typescript": "^5.4.5"
32+
"typescript": "^5.5.3"
3333
}
3434
}

apps/playground/src/lib/safe-action.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import {
22
DEFAULT_SERVER_ERROR_MESSAGE,
33
createSafeActionClient,
44
} from "next-safe-action";
5+
import { zodAdapter } from "next-safe-action/adapters/zod";
56
import { z } from "zod";
67

78
export class ActionError extends Error {}
89

910
export const action = createSafeActionClient({
11+
validationAdapter: zodAdapter(),
1012
// You can provide a custom logging function, otherwise the lib will use `console.error`
1113
// as the default logging system. If you want to disable server errors logging,
1214
// just pass an empty Promise.

packages/next-safe-action/package.json

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@
1111
],
1212
"exports": {
1313
".": "./dist/index.mjs",
14-
"./typeschema": "./dist/typeschema.mjs",
1514
"./hooks": "./dist/hooks.mjs",
16-
"./stateful-hooks": "./dist/stateful-hooks.mjs"
15+
"./stateful-hooks": "./dist/stateful-hooks.mjs",
16+
"./adapters/*": "./dist/adapters/*.mjs"
1717
},
1818
"typesVersions": {
1919
"*": {
2020
".": [
2121
"./dist/index.d.mts"
2222
],
23-
"typeschema": [
24-
"./dist/typeschema.d.mts"
25-
],
2623
"hooks": [
2724
"./dist/hooks.d.mts"
2825
],
2926
"stateful-hooks": [
3027
"./dist/stateful-hooks.d.mts"
28+
],
29+
"adapters/*": [
30+
"./dist/adapters/*.d.mts"
3131
]
3232
}
3333
},
@@ -43,7 +43,7 @@
4343
],
4444
"scripts": {
4545
"lint": "tsc && prettier --write . && eslint .",
46-
"test": "node --import tsx --test ./src/__tests__/*.test.ts ./src/__tests__/typeschema/*.test.ts",
46+
"test": "node --import tsx --test ./src/__tests__/*.test.ts",
4747
"build": "tsup",
4848
"deploy": "semantic-release"
4949
},
@@ -67,10 +67,9 @@
6767
},
6868
"devDependencies": {
6969
"@eslint/js": "^9.2.0",
70-
"@types/node": "^20.12.10",
70+
"@types/node": "^20.14.11",
7171
"@types/react": "^18.3.1",
7272
"@types/react-dom": "18.3.0",
73-
"@typeschema/core": "^0.13.2",
7473
"eslint": "^8.57.0",
7574
"eslint-config-prettier": "^9.1.0",
7675
"eslint-define-config": "^2.1.0",
@@ -82,26 +81,30 @@
8281
"semantic-release": "^23.0.8",
8382
"tsup": "^8.0.2",
8483
"tsx": "^4.11.2",
85-
"typescript": "^5.4.5",
86-
"typescript-eslint": "^7.8.0"
84+
"typescript": "^5.5.3",
85+
"typescript-eslint": "^7.8.0",
86+
"valibot": "^0.36.0",
87+
"yup": "^1.4.0",
88+
"zod": "^3.23.6"
8789
},
8890
"peerDependencies": {
8991
"next": ">= 14.0.0",
9092
"react": ">= 18.2.0",
9193
"react-dom": ">= 18.2.0",
92-
"zod": ">= 3.0.0"
94+
"valibot": ">= 0.36.0",
95+
"zod": ">= 3.0.0",
96+
"yup": ">= 1.0.0"
9397
},
9498
"peerDependenciesMeta": {
9599
"zod": {
96100
"optional": true
101+
},
102+
"valibot": {
103+
"optional": true
97104
}
98105
},
99106
"repository": {
100107
"type": "git",
101108
"url": "https://github.com/TheEdoRan/next-safe-action.git"
102-
},
103-
"dependencies": {
104-
"@typeschema/main": "^0.13.10",
105-
"@typeschema/zod": "^0.13.3"
106109
}
107110
}

packages/next-safe-action/src/__tests__/action-callbacks.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import assert from "node:assert";
44
import { test } from "node:test";
55
import { z } from "zod";
66
import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient, returnValidationErrors } from "..";
7+
import { zodAdapter } from "../adapters/zod";
78

89
const ac = createSafeActionClient({
10+
validationAdapter: zodAdapter(),
911
defineMetadataSchema() {
1012
return z.object({
1113
actionName: z.string(),

packages/next-safe-action/src/__tests__/bind-args-validation-errors.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import assert from "node:assert";
44
import { test } from "node:test";
55
import { z } from "zod";
66
import { createSafeActionClient, flattenBindArgsValidationErrors, formatBindArgsValidationErrors } from "..";
7+
import { zodAdapter } from "../adapters/zod";
78

89
// Default client tests.
910

10-
const dac = createSafeActionClient();
11+
const dac = createSafeActionClient({
12+
validationAdapter: zodAdapter(),
13+
});
1114

1215
test("action with invalid bind args input gives back an object with correct `bindArgsValidationErrors` (default formatted shape)", async () => {
1316
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
8790
// Formatted shape tests (same as default).
8891

8992
const foac = createSafeActionClient({
93+
validationAdapter: zodAdapter(),
9094
defaultValidationErrorsShape: "formatted",
9195
});
9296

@@ -168,6 +172,7 @@ test("action with invalid bind args input gives back an object with correct `bin
168172
// Flattened shape tests.
169173

170174
const flac = createSafeActionClient({
175+
validationAdapter: zodAdapter(),
171176
defaultValidationErrorsShape: "flattened",
172177
});
173178

packages/next-safe-action/src/__tests__/combined-validation-errors.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ import {
1010
formatBindArgsValidationErrors,
1111
formatValidationErrors,
1212
} from "..";
13+
import { zodAdapter } from "../adapters/zod";
1314

1415
// Default client tests.
1516

16-
const dac = createSafeActionClient();
17+
const dac = createSafeActionClient({
18+
validationAdapter: zodAdapter(),
19+
});
1720

1821
test("action with invalid bind args input and valid main input gives back an object with correct `bindArgsValidationErrors` (default formatted shape)", async () => {
1922
const schema = z.object({
@@ -110,6 +113,7 @@ test("action with invalid bind args input and invalid main input gives back an o
110113
// Formatted shape tests (same as default).
111114

112115
const foac = createSafeActionClient({
116+
validationAdapter: zodAdapter(),
113117
defaultValidationErrorsShape: "formatted",
114118
});
115119

@@ -209,6 +213,7 @@ test("action with invalid bind args input and valid main input gives back an obj
209213
// Flattened shape tests.
210214

211215
const flac = createSafeActionClient({
216+
validationAdapter: zodAdapter(),
212217
defaultValidationErrorsShape: "flattened",
213218
});
214219

packages/next-safe-action/src/__tests__/happy-path.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import assert from "node:assert";
44
import { test } from "node:test";
55
import { z } from "zod";
66
import { createSafeActionClient } from "..";
7+
import { zodAdapter } from "../adapters/zod";
78

8-
const ac = createSafeActionClient();
9+
const ac = createSafeActionClient({
10+
validationAdapter: zodAdapter(),
11+
});
912

1013
test("action with no input schema returns empty object", async () => {
1114
const action = ac.action(async () => {

packages/next-safe-action/src/__tests__/metadata.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import assert from "node:assert";
44
import { test } from "node:test";
55
import { z } from "zod";
66
import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "..";
7+
import { zodAdapter } from "../adapters/zod";
78

89
const ac = createSafeActionClient({
10+
validationAdapter: zodAdapter(),
911
handleServerErrorLog() {}, // disable server errors logging for these tests
1012
defineMetadataSchema() {
1113
return z.object({

packages/next-safe-action/src/__tests__/middleware.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import {
99
formatValidationErrors,
1010
returnValidationErrors,
1111
} from "..";
12+
import { zodAdapter } from "../adapters/zod";
1213

1314
const ac = createSafeActionClient({
15+
validationAdapter: zodAdapter(),
1416
handleServerErrorLog() {}, // disable server errors logging for these tests
1517
handleReturnedServerError(e) {
1618
return {
@@ -292,6 +294,7 @@ test("server validation errors in execution result from middleware are correct",
292294
// Flattened validation errors shape.
293295

294296
const flac = createSafeActionClient({
297+
validationAdapter: zodAdapter(),
295298
handleServerErrorLog() {}, // disable server errors logging for these tests
296299
defaultValidationErrorsShape: "flattened",
297300
});

packages/next-safe-action/src/__tests__/server-error.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import assert from "node:assert";
44
import { test } from "node:test";
55
import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "..";
6+
import { zodAdapter } from "../adapters/zod";
67

78
class ActionError extends Error {
89
constructor(message: string) {
@@ -11,6 +12,7 @@ class ActionError extends Error {
1112
}
1213

1314
const ac1 = createSafeActionClient({
15+
validationAdapter: zodAdapter(),
1416
handleServerErrorLog: () => {}, // disable server errors logging for these tests
1517
handleReturnedServerError(e) {
1618
if (e instanceof ActionError) {
@@ -93,6 +95,7 @@ test("known error occurred in middleware function is unmasked", async () => {
9395

9496
// Server error is an object with a 'message' property.
9597
const ac2 = createSafeActionClient({
98+
validationAdapter: zodAdapter(),
9699
handleServerErrorLog: () => {}, // disable server errors logging for these tests
97100
handleReturnedServerError(e) {
98101
return {
@@ -138,6 +141,7 @@ test("error occurred in middleware function has the correct shape defined by `ha
138141

139142
// Rethrow all server errors.
140143
const ac3 = createSafeActionClient({
144+
validationAdapter: zodAdapter(),
141145
handleServerErrorLog: () => {}, // disable server errors logging for these tests
142146
handleReturnedServerError(e) {
143147
throw e;

0 commit comments

Comments
 (0)