server-act 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/server-act.svg)](https://badge.fury.io/js/server-act)
4
4
 
5
- A simple React server action builder that provides input validation with zod.
5
+ A simple React server action builder that provides input validation.
6
+
7
+ You can use any validation library that supports [Standard Schema](https://standardschema.dev/).
6
8
 
7
9
  ## Installation
8
10
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,9 @@
1
- import { z } from 'zod';
1
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
+
3
+ declare function getFormErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>): {
4
+ messages: string[];
5
+ fieldErrors: Record<string, string[]>;
6
+ };
2
7
 
3
8
  declare const unsetMarker: unique symbol;
4
9
  type UnsetMarker = typeof unsetMarker;
@@ -7,7 +12,7 @@ type Prettify<T> = {
7
12
  [P in keyof T]: T[P];
8
13
  } & {};
9
14
  type SanitizeFunctionParam<T extends (param: any) => any> = T extends (param: infer P) => infer R ? Equals<P, undefined> extends true ? () => R : Equals<P, P | undefined> extends true ? (param?: P) => R : (param: P) => R : never;
10
- type InferParserType<T, TType extends "in" | "out"> = T extends z.ZodEffects<infer I, any, any> ? I[TType extends "in" ? "_input" : "_output"] : T extends z.ZodType ? T[TType extends "in" ? "_input" : "_output"] : never;
15
+ type InferParserType<T, TType extends "in" | "out"> = T extends StandardSchemaV1 ? TType extends "in" ? StandardSchemaV1.InferInput<T> : StandardSchemaV1.InferOutput<T> : never;
11
16
  type InferInputType<T, TType extends "in" | "out"> = T extends UnsetMarker ? undefined : InferParserType<T, TType>;
12
17
  type InferContextType<T> = T extends UnsetMarker ? undefined : T;
13
18
  interface ActionParams<TInput = unknown, TContext = unknown> {
@@ -25,7 +30,7 @@ interface ActionBuilder<TParams extends ActionParams> {
25
30
  /**
26
31
  * Input validation for the action.
27
32
  */
28
- input: <TParser extends z.ZodType>(input: ((params: {
33
+ input: <TParser extends StandardSchemaV1>(input: ((params: {
29
34
  ctx: InferContextType<TParams["_context"]>;
30
35
  }) => Promise<TParser> | TParser) | TParser) => Omit<ActionBuilder<{
31
36
  _input: TParser;
@@ -50,8 +55,8 @@ interface ActionBuilder<TParams extends ActionParams> {
50
55
  formErrors?: undefined;
51
56
  } | {
52
57
  input?: undefined;
53
- formErrors: z.ZodError<InferInputType<TParams["_input"], "in">>;
54
- })>) => Promise<TState>) => (prevState: TState | TPrevState, formData: FormData) => Promise<TState | TPrevState>;
58
+ formErrors: ReturnType<typeof getFormErrors>;
59
+ })>) => Promise<TState>) => (prevState: TState | TPrevState, formData: InferInputType<TParams["_input"], "in">) => Promise<TState | TPrevState>;
55
60
  }
56
61
  /**
57
62
  * Server action builder
package/dist/index.d.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { z } from 'zod';
1
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
+
3
+ declare function getFormErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>): {
4
+ messages: string[];
5
+ fieldErrors: Record<string, string[]>;
6
+ };
2
7
 
3
8
  declare const unsetMarker: unique symbol;
4
9
  type UnsetMarker = typeof unsetMarker;
@@ -7,7 +12,7 @@ type Prettify<T> = {
7
12
  [P in keyof T]: T[P];
8
13
  } & {};
9
14
  type SanitizeFunctionParam<T extends (param: any) => any> = T extends (param: infer P) => infer R ? Equals<P, undefined> extends true ? () => R : Equals<P, P | undefined> extends true ? (param?: P) => R : (param: P) => R : never;
10
- type InferParserType<T, TType extends "in" | "out"> = T extends z.ZodEffects<infer I, any, any> ? I[TType extends "in" ? "_input" : "_output"] : T extends z.ZodType ? T[TType extends "in" ? "_input" : "_output"] : never;
15
+ type InferParserType<T, TType extends "in" | "out"> = T extends StandardSchemaV1 ? TType extends "in" ? StandardSchemaV1.InferInput<T> : StandardSchemaV1.InferOutput<T> : never;
11
16
  type InferInputType<T, TType extends "in" | "out"> = T extends UnsetMarker ? undefined : InferParserType<T, TType>;
12
17
  type InferContextType<T> = T extends UnsetMarker ? undefined : T;
13
18
  interface ActionParams<TInput = unknown, TContext = unknown> {
@@ -25,7 +30,7 @@ interface ActionBuilder<TParams extends ActionParams> {
25
30
  /**
26
31
  * Input validation for the action.
27
32
  */
28
- input: <TParser extends z.ZodType>(input: ((params: {
33
+ input: <TParser extends StandardSchemaV1>(input: ((params: {
29
34
  ctx: InferContextType<TParams["_context"]>;
30
35
  }) => Promise<TParser> | TParser) | TParser) => Omit<ActionBuilder<{
31
36
  _input: TParser;
@@ -50,8 +55,8 @@ interface ActionBuilder<TParams extends ActionParams> {
50
55
  formErrors?: undefined;
51
56
  } | {
52
57
  input?: undefined;
53
- formErrors: z.ZodError<InferInputType<TParams["_input"], "in">>;
54
- })>) => Promise<TState>) => (prevState: TState | TPrevState, formData: FormData) => Promise<TState | TPrevState>;
58
+ formErrors: ReturnType<typeof getFormErrors>;
59
+ })>) => Promise<TState>) => (prevState: TState | TPrevState, formData: InferInputType<TParams["_input"], "in">) => Promise<TState | TPrevState>;
55
60
  }
56
61
  /**
57
62
  * Server action builder
package/dist/index.js CHANGED
@@ -1,5 +1,70 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
+ var utils = require('@standard-schema/utils');
4
+
5
+ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
6
+ try {
7
+ var info = gen[key](arg);
8
+ var value = info.value;
9
+ } catch (error) {
10
+ reject(error);
11
+ return;
12
+ }
13
+ if (info.done) {
14
+ resolve(value);
15
+ } else {
16
+ Promise.resolve(value).then(_next, _throw);
17
+ }
18
+ }
19
+ function _async_to_generator$1(fn) {
20
+ return function() {
21
+ var self = this, args = arguments;
22
+ return new Promise(function(resolve, reject) {
23
+ var gen = fn.apply(self, args);
24
+ function _next(value) {
25
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
26
+ }
27
+ function _throw(err) {
28
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
29
+ }
30
+ _next(undefined);
31
+ });
32
+ };
33
+ }
34
+ function standardValidate(schema, input) {
35
+ return _standardValidate.apply(this, arguments);
36
+ }
37
+ function _standardValidate() {
38
+ _standardValidate = _async_to_generator$1(function*(schema, input) {
39
+ let result = schema["~standard"].validate(input);
40
+ if (result instanceof Promise) result = yield result;
41
+ return result;
42
+ });
43
+ return _standardValidate.apply(this, arguments);
44
+ }
45
+ function getFormErrors(issues) {
46
+ const messages = [];
47
+ const fieldErrors = {};
48
+ for (const issue of issues){
49
+ const dotPath = utils.getDotPath(issue);
50
+ if (dotPath) {
51
+ if (fieldErrors[dotPath]) {
52
+ fieldErrors[dotPath].push(issue.message);
53
+ } else {
54
+ fieldErrors[dotPath] = [
55
+ issue.message
56
+ ];
57
+ }
58
+ } else {
59
+ messages.push(issue.message);
60
+ }
61
+ }
62
+ return {
63
+ messages,
64
+ fieldErrors
65
+ };
66
+ }
67
+
3
68
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
4
69
  try {
5
70
  var info = gen[key](arg);
@@ -66,14 +131,14 @@ function createServerActionBuilder(initDef = {}) {
66
131
  const inputSchema = typeof _def.input === "function" ? yield _def.input({
67
132
  ctx
68
133
  }) : _def.input;
69
- const result = yield inputSchema.safeParseAsync(input);
70
- if (!result.success) {
71
- console.error("❌ Input validation error:", result.error.errors);
72
- throw new Error("Input validation error");
134
+ const result = yield standardValidate(inputSchema, input);
135
+ if (result.issues) {
136
+ throw new utils.SchemaError(result.issues);
73
137
  }
138
+ // biome-ignore lint/suspicious/noExplicitAny: It's fine
74
139
  return yield action({
75
140
  ctx,
76
- input: result.data
141
+ input: result.value
77
142
  });
78
143
  }
79
144
  return yield action({
@@ -83,26 +148,28 @@ function createServerActionBuilder(initDef = {}) {
83
148
  });
84
149
  },
85
150
  formAction: (action)=>{
151
+ // biome-ignore lint/suspicious/noExplicitAny: Intended
86
152
  return /*#__PURE__*/ _async_to_generator(function*(prevState, formData) {
87
153
  const ctx = yield _def.middleware == null ? void 0 : _def.middleware.call(_def);
88
154
  if (_def.input) {
89
155
  const inputSchema = typeof _def.input === "function" ? yield _def.input({
90
156
  ctx
91
157
  }) : _def.input;
92
- const result = yield inputSchema.safeParseAsync(formData);
93
- if (!result.success) {
158
+ const result = yield standardValidate(inputSchema, formData);
159
+ if (result.issues) {
94
160
  return yield action({
95
161
  ctx,
96
162
  prevState,
97
163
  formData,
98
- formErrors: result.error
164
+ formErrors: getFormErrors(result.issues)
99
165
  });
100
166
  }
101
167
  return yield action({
102
168
  ctx,
103
169
  prevState,
104
170
  formData,
105
- input: result.data
171
+ // biome-ignore lint/suspicious/noExplicitAny: It's fine
172
+ input: result.value
106
173
  });
107
174
  }
108
175
  return yield action({
package/dist/index.mjs CHANGED
@@ -1,3 +1,68 @@
1
+ import { getDotPath, SchemaError } from '@standard-schema/utils';
2
+
3
+ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
4
+ try {
5
+ var info = gen[key](arg);
6
+ var value = info.value;
7
+ } catch (error) {
8
+ reject(error);
9
+ return;
10
+ }
11
+ if (info.done) {
12
+ resolve(value);
13
+ } else {
14
+ Promise.resolve(value).then(_next, _throw);
15
+ }
16
+ }
17
+ function _async_to_generator$1(fn) {
18
+ return function() {
19
+ var self = this, args = arguments;
20
+ return new Promise(function(resolve, reject) {
21
+ var gen = fn.apply(self, args);
22
+ function _next(value) {
23
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
24
+ }
25
+ function _throw(err) {
26
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
27
+ }
28
+ _next(undefined);
29
+ });
30
+ };
31
+ }
32
+ function standardValidate(schema, input) {
33
+ return _standardValidate.apply(this, arguments);
34
+ }
35
+ function _standardValidate() {
36
+ _standardValidate = _async_to_generator$1(function*(schema, input) {
37
+ let result = schema["~standard"].validate(input);
38
+ if (result instanceof Promise) result = yield result;
39
+ return result;
40
+ });
41
+ return _standardValidate.apply(this, arguments);
42
+ }
43
+ function getFormErrors(issues) {
44
+ const messages = [];
45
+ const fieldErrors = {};
46
+ for (const issue of issues){
47
+ const dotPath = getDotPath(issue);
48
+ if (dotPath) {
49
+ if (fieldErrors[dotPath]) {
50
+ fieldErrors[dotPath].push(issue.message);
51
+ } else {
52
+ fieldErrors[dotPath] = [
53
+ issue.message
54
+ ];
55
+ }
56
+ } else {
57
+ messages.push(issue.message);
58
+ }
59
+ }
60
+ return {
61
+ messages,
62
+ fieldErrors
63
+ };
64
+ }
65
+
1
66
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
67
  try {
3
68
  var info = gen[key](arg);
@@ -64,14 +129,14 @@ function createServerActionBuilder(initDef = {}) {
64
129
  const inputSchema = typeof _def.input === "function" ? yield _def.input({
65
130
  ctx
66
131
  }) : _def.input;
67
- const result = yield inputSchema.safeParseAsync(input);
68
- if (!result.success) {
69
- console.error("❌ Input validation error:", result.error.errors);
70
- throw new Error("Input validation error");
132
+ const result = yield standardValidate(inputSchema, input);
133
+ if (result.issues) {
134
+ throw new SchemaError(result.issues);
71
135
  }
136
+ // biome-ignore lint/suspicious/noExplicitAny: It's fine
72
137
  return yield action({
73
138
  ctx,
74
- input: result.data
139
+ input: result.value
75
140
  });
76
141
  }
77
142
  return yield action({
@@ -81,26 +146,28 @@ function createServerActionBuilder(initDef = {}) {
81
146
  });
82
147
  },
83
148
  formAction: (action)=>{
149
+ // biome-ignore lint/suspicious/noExplicitAny: Intended
84
150
  return /*#__PURE__*/ _async_to_generator(function*(prevState, formData) {
85
151
  const ctx = yield _def.middleware == null ? void 0 : _def.middleware.call(_def);
86
152
  if (_def.input) {
87
153
  const inputSchema = typeof _def.input === "function" ? yield _def.input({
88
154
  ctx
89
155
  }) : _def.input;
90
- const result = yield inputSchema.safeParseAsync(formData);
91
- if (!result.success) {
156
+ const result = yield standardValidate(inputSchema, formData);
157
+ if (result.issues) {
92
158
  return yield action({
93
159
  ctx,
94
160
  prevState,
95
161
  formData,
96
- formErrors: result.error
162
+ formErrors: getFormErrors(result.issues)
97
163
  });
98
164
  }
99
165
  return yield action({
100
166
  ctx,
101
167
  prevState,
102
168
  formData,
103
- input: result.data
169
+ // biome-ignore lint/suspicious/noExplicitAny: It's fine
170
+ input: result.value
104
171
  });
105
172
  }
106
173
  return yield action({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "server-act",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "homepage": "https://github.com/chungweileong94/server-act#readme",
5
5
  "author": "chungweileong94",
6
6
  "license": "MIT",
@@ -43,21 +43,33 @@
43
43
  "server action",
44
44
  "action"
45
45
  ],
46
- "devDependencies": {
47
- "bunchee": "^5.1.2",
48
- "typescript": "^5.4.5",
49
- "zod": "^3.22.2",
50
- "zod-form-data": "^2.0.2"
46
+ "dependencies": {
47
+ "@standard-schema/spec": "^1.0.0",
48
+ "@standard-schema/utils": "^0.3.0"
51
49
  },
52
50
  "peerDependencies": {
53
51
  "typescript": ">=5.0.0",
54
- "zod": "^3.22.2"
52
+ "valibot": "^1.0.0",
53
+ "zod": "^3.24.0"
55
54
  },
56
55
  "peerDependenciesMeta": {
57
56
  "typescript": {
58
57
  "optional": true
58
+ },
59
+ "zod": {
60
+ "optional": true
61
+ },
62
+ "valibot": {
63
+ "optional": true
59
64
  }
60
65
  },
66
+ "devDependencies": {
67
+ "bunchee": "^6.2.0",
68
+ "typescript": "^5.6.3",
69
+ "valibot": "1.0.0-rc.0",
70
+ "zod": "^3.24.2",
71
+ "zod-form-data": "^2.0.2"
72
+ },
61
73
  "scripts": {
62
74
  "build": "bunchee",
63
75
  "dev": "bunchee -w",