Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: built-in support for multiple validation libraries #202

Merged
merged 28 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4464bcb
refactor: support just Zod as validation library
TheEdoRan Jul 2, 2024
9f7d293
Merge branch 'main' into experimental
TheEdoRan Jul 2, 2024
1dac2a1
refactor: move util types to separate file
TheEdoRan Jul 2, 2024
5abefa1
Merge branch 'main' into experimental
TheEdoRan Jul 12, 2024
21dff3a
Merge branch 'main' into experimental
TheEdoRan Jul 12, 2024
59d6c1f
Merge branch 'main' into experimental
TheEdoRan Jul 12, 2024
6d6ec34
build: don't bundle files
TheEdoRan Jul 15, 2024
a148550
refactor(hooks): export `useStateAction` from `/hooks` path
TheEdoRan Jul 15, 2024
10143bb
refactor: set up built-in multi validation system
TheEdoRan Jul 16, 2024
7f2a4f7
build: include validation adapters source files
TheEdoRan Jul 16, 2024
02d3caf
feat: use modular built-in multi validation system
TheEdoRan Jul 16, 2024
38496f7
fix: implementation of modular built-in multi validation system
TheEdoRan Jul 18, 2024
fff996c
feat: wip Valibot adapter
TheEdoRan Jul 18, 2024
22fa774
fix(types): add generic `validate` function for adapters
TheEdoRan Jul 19, 2024
52d09b7
build: update to TypeScript 5.5
TheEdoRan Jul 19, 2024
9c7d191
fix(types): `Schema` adapter detection
TheEdoRan Jul 19, 2024
eb8c7d8
refactor(types): rename `Exists` to `IfInstalled`
TheEdoRan Jul 19, 2024
9eb9ff1
refactor(types): combine `GenericSchema` and `GenericSchemaAsync` typ…
TheEdoRan Jul 19, 2024
bdf42f1
refactor(types): move adapter types out of adapters/ directory
TheEdoRan Jul 19, 2024
3c18fd3
feat(validation): add Yup adapter
TheEdoRan Jul 19, 2024
6e04a2c
refactor(types): move adapters types back to adapters/ directory
TheEdoRan Jul 19, 2024
b61c9cd
refactor(types): separate valibot generic schema types
TheEdoRan Jul 19, 2024
555390f
fix(validation): yup validation errors paths
TheEdoRan Jul 19, 2024
7940d10
refactor(validation): use Zod adapter by default
TheEdoRan Jul 19, 2024
fcfb25a
docs: remove TypeSchema related note
TheEdoRan Jul 19, 2024
c3aba3b
chore(website): add validation libraries support recipe
TheEdoRan Jul 19, 2024
99cba74
refactor: check server validation errors with `ActionServerValidation…
TheEdoRan Jul 20, 2024
9c181eb
chore(website): add `validationAdapter` documentation in initializati…
TheEdoRan Jul 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
"zod-form-data": "^2.0.2"
},
"devDependencies": {
"@types/node": "^20.12.10",
"@types/node": "^20.14.11",
"@types/react": "^18.3.1",
"@types/react-dom": "18.3.0",
"autoprefixer": "10.4.19",
"eslint": "^8.57.0",
"eslint-config-next": "15.0.0-canary.25",
"postcss": "8.4.38",
"tailwindcss": "3.4.3",
"typescript": "^5.4.5"
"typescript": "^5.5.3"
}
}
2 changes: 2 additions & 0 deletions apps/playground/src/lib/safe-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
33 changes: 18 additions & 15 deletions packages/next-safe-action/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@
],
"exports": {
".": "./dist/index.mjs",
"./typeschema": "./dist/typeschema.mjs",
"./hooks": "./dist/hooks.mjs",
"./stateful-hooks": "./dist/stateful-hooks.mjs"
"./stateful-hooks": "./dist/stateful-hooks.mjs",
"./adapters/*": "./dist/adapters/*.mjs"
},
"typesVersions": {
"*": {
".": [
"./dist/index.d.mts"
],
"typeschema": [
"./dist/typeschema.d.mts"
],
"hooks": [
"./dist/hooks.d.mts"
],
"stateful-hooks": [
"./dist/stateful-hooks.d.mts"
],
"adapters/*": [
"./dist/adapters/*.d.mts"
]
}
},
Expand All @@ -43,7 +43,7 @@
],
"scripts": {
"lint": "tsc && prettier --write . && eslint .",
"test": "node --import tsx --test ./src/__tests__/*.test.ts ./src/__tests__/typeschema/*.test.ts",
"test": "node --import tsx --test ./src/__tests__/*.test.ts",
"build": "tsup",
"deploy": "semantic-release"
},
Expand All @@ -67,10 +67,9 @@
},
"devDependencies": {
"@eslint/js": "^9.2.0",
"@types/node": "^20.12.10",
"@types/node": "^20.14.11",
"@types/react": "^18.3.1",
"@types/react-dom": "18.3.0",
"@typeschema/core": "^0.13.2",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-define-config": "^2.1.0",
Expand All @@ -82,26 +81,30 @@
"semantic-release": "^23.0.8",
"tsup": "^8.0.2",
"tsx": "^4.11.2",
"typescript": "^5.4.5",
"typescript-eslint": "^7.8.0"
"typescript": "^5.5.3",
"typescript-eslint": "^7.8.0",
"valibot": "^0.36.0",
"yup": "^1.4.0",
"zod": "^3.23.6"
},
"peerDependencies": {
"next": ">= 14.0.0",
"react": ">= 18.2.0",
"react-dom": ">= 18.2.0",
"zod": ">= 3.0.0"
"valibot": ">= 0.36.0",
"zod": ">= 3.0.0",
"yup": ">= 1.0.0"
},
"peerDependenciesMeta": {
"zod": {
"optional": true
},
"valibot": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "https://github.com/TheEdoRan/next-safe-action.git"
},
"dependencies": {
"@typeschema/main": "^0.13.10",
"@typeschema/zod": "^0.13.3"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }>] = [
Expand Down Expand Up @@ -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",
});

Expand Down Expand Up @@ -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",
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -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",
});

Expand Down Expand Up @@ -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",
});

Expand Down
5 changes: 4 additions & 1 deletion packages/next-safe-action/src/__tests__/happy-path.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/next-safe-action/src/__tests__/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
3 changes: 3 additions & 0 deletions packages/next-safe-action/src/__tests__/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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",
});
Expand Down
4 changes: 4 additions & 0 deletions packages/next-safe-action/src/__tests__/server-error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
Loading