server-act 0.0.4
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/.eslintrc.json +11 -0
- package/.prettierrc.json +15 -0
- package/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +13 -0
- package/README.md +57 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +140 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +103 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
- package/src/index.test.ts +21 -0
- package/src/index.ts +65 -0
- package/tsconfig.json +27 -0
- package/tsup.config.ts +11 -0
package/.eslintrc.json
ADDED
package/.prettierrc.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"arrowParens": "always",
|
|
3
|
+
"bracketSpacing": false,
|
|
4
|
+
"htmlWhitespaceSensitivity": "css",
|
|
5
|
+
"insertPragma": false,
|
|
6
|
+
"bracketSameLine": false,
|
|
7
|
+
"jsxSingleQuote": false,
|
|
8
|
+
"printWidth": 120,
|
|
9
|
+
"proseWrap": "preserve",
|
|
10
|
+
"quoteProps": "as-needed",
|
|
11
|
+
"semi": true,
|
|
12
|
+
"singleQuote": true,
|
|
13
|
+
"trailingComma": "all",
|
|
14
|
+
"useTabs": false
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
> server-act@0.0.4 build /home/runner/work/server-act/server-act/packages/server-act
|
|
3
|
+
> tsup
|
|
4
|
+
|
|
5
|
+
[34mCLI[39m Building entry: ./src/index.ts
|
|
6
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
+
[34mCLI[39m tsup v6.7.0
|
|
8
|
+
[34mCLI[39m Using tsup config: /home/runner/work/server-act/server-act/packages/server-act/tsup.config.ts
|
|
9
|
+
[34mCLI[39m Target: node14
|
|
10
|
+
[34mCLI[39m Cleaning output folder
|
|
11
|
+
[34mESM[39m Build start
|
|
12
|
+
[34mCJS[39m Build start
|
|
13
|
+
[32mCJS[39m [1mdist/index.js [22m[32m4.95 KB[39m
|
|
14
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m7.71 KB[39m
|
|
15
|
+
[32mCJS[39m ⚡️ Build success in 25ms
|
|
16
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m3.36 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m7.66 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 25ms
|
|
19
|
+
[34mDTS[39m Build start
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 690ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m956.00 B[39m
|
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Server-Act
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
A simple React server action builder that provides input validation with zod.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# npm
|
|
11
|
+
npm install server-act zod
|
|
12
|
+
|
|
13
|
+
# yarn
|
|
14
|
+
yarn add server-act zod
|
|
15
|
+
|
|
16
|
+
# pnpm
|
|
17
|
+
pnpm add server-act zod
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// action.ts
|
|
24
|
+
"use server";
|
|
25
|
+
|
|
26
|
+
import { serverAct } from "server-act";
|
|
27
|
+
|
|
28
|
+
const sayHelloAction = serverAct
|
|
29
|
+
.input(
|
|
30
|
+
z.object({
|
|
31
|
+
name: z.string(),
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
.action(async ({ name }) => {
|
|
35
|
+
return `Hello, ${name}`;
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
// client-component.tsx
|
|
41
|
+
"use client";
|
|
42
|
+
|
|
43
|
+
import { sayHelloAction } from "./action";
|
|
44
|
+
|
|
45
|
+
export const ClientComponent = () => {
|
|
46
|
+
const onClick = () => {
|
|
47
|
+
const message = await sayHelloAction({ name: "John" });
|
|
48
|
+
console.log(message); // Hello, John
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
<button onClick={onClick}>Trigger action</button>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const unsetMarker: unique symbol;
|
|
4
|
+
type UnsetMarker = typeof unsetMarker;
|
|
5
|
+
type OptionalizeUndefined<T> = undefined extends T ? [param?: T] : [param: T];
|
|
6
|
+
type InferParserType<TParser, TType extends 'in' | 'out'> = TParser extends UnsetMarker ? undefined : TParser extends z.ZodType ? TParser[TType extends 'in' ? '_input' : '_output'] : never;
|
|
7
|
+
type ActionParams<TInput = unknown> = {
|
|
8
|
+
_input: TInput;
|
|
9
|
+
};
|
|
10
|
+
type ActionBuilder<TParams extends ActionParams> = {
|
|
11
|
+
input: <TParser extends z.ZodType>(input: TParser) => ActionBuilder<{
|
|
12
|
+
_input: TParser;
|
|
13
|
+
}>;
|
|
14
|
+
action: <TOutput>(action: (params: {
|
|
15
|
+
input: InferParserType<TParams['_input'], 'out'>;
|
|
16
|
+
}) => Promise<TOutput>) => (...[input]: OptionalizeUndefined<InferParserType<TParams['_input'], 'in'>>) => Promise<TOutput>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Server action builder
|
|
20
|
+
*/
|
|
21
|
+
declare const serverAct: ActionBuilder<{
|
|
22
|
+
_input: UnsetMarker;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
export { serverAct };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
serverAct: () => serverAct
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(src_exports);
|
|
36
|
+
|
|
37
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/ValidationError.js
|
|
38
|
+
var zod = __toESM(require("zod"));
|
|
39
|
+
|
|
40
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/joinPath.js
|
|
41
|
+
var identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
|
|
42
|
+
function joinPath(path) {
|
|
43
|
+
if (path.length === 1) {
|
|
44
|
+
return path[0].toString();
|
|
45
|
+
}
|
|
46
|
+
return path.reduce((acc, item) => {
|
|
47
|
+
if (typeof item === "number") {
|
|
48
|
+
return acc + "[" + item.toString() + "]";
|
|
49
|
+
}
|
|
50
|
+
if (item.includes('"')) {
|
|
51
|
+
return acc + '["' + escapeQuotes(item) + '"]';
|
|
52
|
+
}
|
|
53
|
+
if (!identifierRegex.test(item)) {
|
|
54
|
+
return acc + '["' + item + '"]';
|
|
55
|
+
}
|
|
56
|
+
const separator = acc.length === 0 ? "" : ".";
|
|
57
|
+
return acc + separator + item;
|
|
58
|
+
}, "");
|
|
59
|
+
}
|
|
60
|
+
function escapeQuotes(str) {
|
|
61
|
+
return str.replace(/"/g, '\\"');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/NonEmptyArray.js
|
|
65
|
+
function isNonEmptyArray(value) {
|
|
66
|
+
return value.length !== 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/ValidationError.js
|
|
70
|
+
var ValidationError = class extends Error {
|
|
71
|
+
details;
|
|
72
|
+
name;
|
|
73
|
+
constructor(message, details = []) {
|
|
74
|
+
super(message);
|
|
75
|
+
this.details = details;
|
|
76
|
+
this.name = "ZodValidationError";
|
|
77
|
+
}
|
|
78
|
+
toString() {
|
|
79
|
+
return this.message;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
function fromZodIssue(issue, issueSeparator, unionSeparator) {
|
|
83
|
+
if (issue.code === "invalid_union") {
|
|
84
|
+
return issue.unionErrors.reduce((acc, zodError) => {
|
|
85
|
+
const newIssues = zodError.issues.map((issue2) => fromZodIssue(issue2, issueSeparator, unionSeparator)).join(issueSeparator);
|
|
86
|
+
if (!acc.includes(newIssues)) {
|
|
87
|
+
acc.push(newIssues);
|
|
88
|
+
}
|
|
89
|
+
return acc;
|
|
90
|
+
}, []).join(unionSeparator);
|
|
91
|
+
}
|
|
92
|
+
if (isNonEmptyArray(issue.path)) {
|
|
93
|
+
if (issue.path.length === 1) {
|
|
94
|
+
const identifier = issue.path[0];
|
|
95
|
+
if (typeof identifier === "number") {
|
|
96
|
+
return `${issue.message} at index ${identifier}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return `${issue.message} at "${joinPath(issue.path)}"`;
|
|
100
|
+
}
|
|
101
|
+
return issue.message;
|
|
102
|
+
}
|
|
103
|
+
function fromZodError(zodError, options = {}) {
|
|
104
|
+
const { maxIssuesInMessage = 99, issueSeparator = "; ", unionSeparator = ", or ", prefixSeparator = ": ", prefix = "Validation error" } = options;
|
|
105
|
+
const reason = zodError.errors.slice(0, maxIssuesInMessage).map((issue) => fromZodIssue(issue, issueSeparator, unionSeparator)).join(issueSeparator);
|
|
106
|
+
const message = reason ? [prefix, reason].join(prefixSeparator) : prefix;
|
|
107
|
+
return new ValidationError(message, zodError.errors);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/index.ts
|
|
111
|
+
var unsetMarker = Symbol("unsetMarker");
|
|
112
|
+
var createNewServerActionBuilder = (def) => {
|
|
113
|
+
return createServerActionBuilder(def);
|
|
114
|
+
};
|
|
115
|
+
var createServerActionBuilder = (initDef = {}) => {
|
|
116
|
+
const _def = {
|
|
117
|
+
input: void 0,
|
|
118
|
+
...initDef
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
input: (input) => createNewServerActionBuilder({ ..._def, input }),
|
|
122
|
+
action: (action) => {
|
|
123
|
+
return async (input) => {
|
|
124
|
+
if (_def.input) {
|
|
125
|
+
const result = _def.input.safeParse(input);
|
|
126
|
+
if (!result.success) {
|
|
127
|
+
throw fromZodError(result.error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return await action({ input });
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
var serverAct = createServerActionBuilder();
|
|
136
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
137
|
+
0 && (module.exports = {
|
|
138
|
+
serverAct
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/ValidationError.js","../../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/joinPath.js","../../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/NonEmptyArray.js"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {type z} from 'zod';\nimport {fromZodError} from 'zod-validation-error';\n\nconst unsetMarker = Symbol('unsetMarker');\ntype UnsetMarker = typeof unsetMarker;\n\ntype OptionalizeUndefined<T> = undefined extends T ? [param?: T] : [param: T];\n\ntype InferParserType<TParser, TType extends 'in' | 'out'> = TParser extends UnsetMarker\n ? undefined\n : TParser extends z.ZodType\n ? TParser[TType extends 'in' ? '_input' : '_output']\n : never;\n\ntype ActionParams<TInput = unknown> = {\n _input: TInput;\n};\n\ntype ActionBuilder<TParams extends ActionParams> = {\n input: <TParser extends z.ZodType>(input: TParser) => ActionBuilder<{_input: TParser}>;\n action: <TOutput>(\n action: (params: {input: InferParserType<TParams['_input'], 'out'>}) => Promise<TOutput>,\n ) => (...[input]: OptionalizeUndefined<InferParserType<TParams['_input'], 'in'>>) => Promise<TOutput>;\n};\ntype AnyActionBuilder = ActionBuilder<any>;\n\ntype ActionBuilderDef<TParams extends ActionParams<any>> = {\n input: TParams['_input'];\n};\ntype AnyActionBuilderDef = ActionBuilderDef<any>;\n\nconst createNewServerActionBuilder = (def: Partial<AnyActionBuilderDef>) => {\n return createServerActionBuilder(def);\n};\n\nconst createServerActionBuilder = (\n initDef: Partial<AnyActionBuilderDef> = {},\n): ActionBuilder<{\n _input: UnsetMarker;\n}> => {\n const _def: ActionBuilderDef<{_input: z.ZodType | undefined}> = {\n input: undefined,\n ...initDef,\n };\n return {\n input: (input) => createNewServerActionBuilder({..._def, input}) as AnyActionBuilder,\n action: (action) => {\n return async (input) => {\n if (_def.input) {\n const result = _def.input.safeParse(input);\n if (!result.success) {\n throw fromZodError(result.error);\n }\n }\n return await action({input});\n };\n },\n };\n};\n\n/**\n * Server action builder\n */\nexport const serverAct = createServerActionBuilder();\n","import * as zod from 'zod';\nimport { joinPath } from './utils/joinPath';\nimport { isNonEmptyArray } from './utils/NonEmptyArray';\nexport class ValidationError extends Error {\n details;\n name;\n constructor(message, details = []) {\n super(message);\n this.details = details;\n this.name = 'ZodValidationError';\n }\n toString() {\n return this.message;\n }\n}\nfunction fromZodIssue(issue, issueSeparator, unionSeparator) {\n if (issue.code === 'invalid_union') {\n return issue.unionErrors\n .reduce((acc, zodError) => {\n const newIssues = zodError.issues\n .map((issue) => fromZodIssue(issue, issueSeparator, unionSeparator))\n .join(issueSeparator);\n if (!acc.includes(newIssues)) {\n acc.push(newIssues);\n }\n return acc;\n }, [])\n .join(unionSeparator);\n }\n if (isNonEmptyArray(issue.path)) {\n if (issue.path.length === 1) {\n const identifier = issue.path[0];\n if (typeof identifier === 'number') {\n return `${issue.message} at index ${identifier}`;\n }\n }\n return `${issue.message} at \"${joinPath(issue.path)}\"`;\n }\n return issue.message;\n}\nexport function fromZodError(zodError, options = {}) {\n const { maxIssuesInMessage = 99, issueSeparator = '; ', unionSeparator = ', or ', prefixSeparator = ': ', prefix = 'Validation error', } = options;\n const reason = zodError.errors\n .slice(0, maxIssuesInMessage)\n .map((issue) => fromZodIssue(issue, issueSeparator, unionSeparator))\n .join(issueSeparator);\n const message = reason ? [prefix, reason].join(prefixSeparator) : prefix;\n return new ValidationError(message, zodError.errors);\n}\nexport const toValidationError = (options = {}) => (err) => {\n if (err instanceof zod.ZodError) {\n return fromZodError(err, options);\n }\n if (err instanceof Error) {\n return err;\n }\n return new Error('Unknown error');\n};\nexport function isValidationError(err) {\n return err instanceof ValidationError;\n}\nexport function isValidationErrorLike(err) {\n return err instanceof Error && err.name === 'ZodValidationError';\n}\n","const identifierRegex = /[$_\\p{ID_Start}][$\\u200c\\u200d\\p{ID_Continue}]*/u;\nexport function joinPath(path) {\n if (path.length === 1) {\n return path[0].toString();\n }\n return path.reduce((acc, item) => {\n if (typeof item === 'number') {\n return acc + '[' + item.toString() + ']';\n }\n if (item.includes('\"')) {\n return acc + '[\"' + escapeQuotes(item) + '\"]';\n }\n if (!identifierRegex.test(item)) {\n return acc + '[\"' + item + '\"]';\n }\n const separator = acc.length === 0 ? '' : '.';\n return acc + separator + item;\n }, '');\n}\nfunction escapeQuotes(str) {\n return str.replace(/\"/g, '\\\\\"');\n}\n","export function isNonEmptyArray(value) {\n return value.length !== 0;\n}\n"],"mappings":"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","names":["issue"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/ValidationError.js
|
|
2
|
+
import * as zod from "zod";
|
|
3
|
+
|
|
4
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/joinPath.js
|
|
5
|
+
var identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
|
|
6
|
+
function joinPath(path) {
|
|
7
|
+
if (path.length === 1) {
|
|
8
|
+
return path[0].toString();
|
|
9
|
+
}
|
|
10
|
+
return path.reduce((acc, item) => {
|
|
11
|
+
if (typeof item === "number") {
|
|
12
|
+
return acc + "[" + item.toString() + "]";
|
|
13
|
+
}
|
|
14
|
+
if (item.includes('"')) {
|
|
15
|
+
return acc + '["' + escapeQuotes(item) + '"]';
|
|
16
|
+
}
|
|
17
|
+
if (!identifierRegex.test(item)) {
|
|
18
|
+
return acc + '["' + item + '"]';
|
|
19
|
+
}
|
|
20
|
+
const separator = acc.length === 0 ? "" : ".";
|
|
21
|
+
return acc + separator + item;
|
|
22
|
+
}, "");
|
|
23
|
+
}
|
|
24
|
+
function escapeQuotes(str) {
|
|
25
|
+
return str.replace(/"/g, '\\"');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/NonEmptyArray.js
|
|
29
|
+
function isNonEmptyArray(value) {
|
|
30
|
+
return value.length !== 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/ValidationError.js
|
|
34
|
+
var ValidationError = class extends Error {
|
|
35
|
+
details;
|
|
36
|
+
name;
|
|
37
|
+
constructor(message, details = []) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.details = details;
|
|
40
|
+
this.name = "ZodValidationError";
|
|
41
|
+
}
|
|
42
|
+
toString() {
|
|
43
|
+
return this.message;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function fromZodIssue(issue, issueSeparator, unionSeparator) {
|
|
47
|
+
if (issue.code === "invalid_union") {
|
|
48
|
+
return issue.unionErrors.reduce((acc, zodError) => {
|
|
49
|
+
const newIssues = zodError.issues.map((issue2) => fromZodIssue(issue2, issueSeparator, unionSeparator)).join(issueSeparator);
|
|
50
|
+
if (!acc.includes(newIssues)) {
|
|
51
|
+
acc.push(newIssues);
|
|
52
|
+
}
|
|
53
|
+
return acc;
|
|
54
|
+
}, []).join(unionSeparator);
|
|
55
|
+
}
|
|
56
|
+
if (isNonEmptyArray(issue.path)) {
|
|
57
|
+
if (issue.path.length === 1) {
|
|
58
|
+
const identifier = issue.path[0];
|
|
59
|
+
if (typeof identifier === "number") {
|
|
60
|
+
return `${issue.message} at index ${identifier}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return `${issue.message} at "${joinPath(issue.path)}"`;
|
|
64
|
+
}
|
|
65
|
+
return issue.message;
|
|
66
|
+
}
|
|
67
|
+
function fromZodError(zodError, options = {}) {
|
|
68
|
+
const { maxIssuesInMessage = 99, issueSeparator = "; ", unionSeparator = ", or ", prefixSeparator = ": ", prefix = "Validation error" } = options;
|
|
69
|
+
const reason = zodError.errors.slice(0, maxIssuesInMessage).map((issue) => fromZodIssue(issue, issueSeparator, unionSeparator)).join(issueSeparator);
|
|
70
|
+
const message = reason ? [prefix, reason].join(prefixSeparator) : prefix;
|
|
71
|
+
return new ValidationError(message, zodError.errors);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/index.ts
|
|
75
|
+
var unsetMarker = Symbol("unsetMarker");
|
|
76
|
+
var createNewServerActionBuilder = (def) => {
|
|
77
|
+
return createServerActionBuilder(def);
|
|
78
|
+
};
|
|
79
|
+
var createServerActionBuilder = (initDef = {}) => {
|
|
80
|
+
const _def = {
|
|
81
|
+
input: void 0,
|
|
82
|
+
...initDef
|
|
83
|
+
};
|
|
84
|
+
return {
|
|
85
|
+
input: (input) => createNewServerActionBuilder({ ..._def, input }),
|
|
86
|
+
action: (action) => {
|
|
87
|
+
return async (input) => {
|
|
88
|
+
if (_def.input) {
|
|
89
|
+
const result = _def.input.safeParse(input);
|
|
90
|
+
if (!result.success) {
|
|
91
|
+
throw fromZodError(result.error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return await action({ input });
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
var serverAct = createServerActionBuilder();
|
|
100
|
+
export {
|
|
101
|
+
serverAct
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/ValidationError.js","../../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/joinPath.js","../../../node_modules/.pnpm/zod-validation-error@1.3.0_zod@3.21.4/node_modules/zod-validation-error/dist/esm/utils/NonEmptyArray.js","../src/index.ts"],"sourcesContent":["import * as zod from 'zod';\nimport { joinPath } from './utils/joinPath';\nimport { isNonEmptyArray } from './utils/NonEmptyArray';\nexport class ValidationError extends Error {\n details;\n name;\n constructor(message, details = []) {\n super(message);\n this.details = details;\n this.name = 'ZodValidationError';\n }\n toString() {\n return this.message;\n }\n}\nfunction fromZodIssue(issue, issueSeparator, unionSeparator) {\n if (issue.code === 'invalid_union') {\n return issue.unionErrors\n .reduce((acc, zodError) => {\n const newIssues = zodError.issues\n .map((issue) => fromZodIssue(issue, issueSeparator, unionSeparator))\n .join(issueSeparator);\n if (!acc.includes(newIssues)) {\n acc.push(newIssues);\n }\n return acc;\n }, [])\n .join(unionSeparator);\n }\n if (isNonEmptyArray(issue.path)) {\n if (issue.path.length === 1) {\n const identifier = issue.path[0];\n if (typeof identifier === 'number') {\n return `${issue.message} at index ${identifier}`;\n }\n }\n return `${issue.message} at \"${joinPath(issue.path)}\"`;\n }\n return issue.message;\n}\nexport function fromZodError(zodError, options = {}) {\n const { maxIssuesInMessage = 99, issueSeparator = '; ', unionSeparator = ', or ', prefixSeparator = ': ', prefix = 'Validation error', } = options;\n const reason = zodError.errors\n .slice(0, maxIssuesInMessage)\n .map((issue) => fromZodIssue(issue, issueSeparator, unionSeparator))\n .join(issueSeparator);\n const message = reason ? [prefix, reason].join(prefixSeparator) : prefix;\n return new ValidationError(message, zodError.errors);\n}\nexport const toValidationError = (options = {}) => (err) => {\n if (err instanceof zod.ZodError) {\n return fromZodError(err, options);\n }\n if (err instanceof Error) {\n return err;\n }\n return new Error('Unknown error');\n};\nexport function isValidationError(err) {\n return err instanceof ValidationError;\n}\nexport function isValidationErrorLike(err) {\n return err instanceof Error && err.name === 'ZodValidationError';\n}\n","const identifierRegex = /[$_\\p{ID_Start}][$\\u200c\\u200d\\p{ID_Continue}]*/u;\nexport function joinPath(path) {\n if (path.length === 1) {\n return path[0].toString();\n }\n return path.reduce((acc, item) => {\n if (typeof item === 'number') {\n return acc + '[' + item.toString() + ']';\n }\n if (item.includes('\"')) {\n return acc + '[\"' + escapeQuotes(item) + '\"]';\n }\n if (!identifierRegex.test(item)) {\n return acc + '[\"' + item + '\"]';\n }\n const separator = acc.length === 0 ? '' : '.';\n return acc + separator + item;\n }, '');\n}\nfunction escapeQuotes(str) {\n return str.replace(/\"/g, '\\\\\"');\n}\n","export function isNonEmptyArray(value) {\n return value.length !== 0;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {type z} from 'zod';\nimport {fromZodError} from 'zod-validation-error';\n\nconst unsetMarker = Symbol('unsetMarker');\ntype UnsetMarker = typeof unsetMarker;\n\ntype OptionalizeUndefined<T> = undefined extends T ? [param?: T] : [param: T];\n\ntype InferParserType<TParser, TType extends 'in' | 'out'> = TParser extends UnsetMarker\n ? undefined\n : TParser extends z.ZodType\n ? TParser[TType extends 'in' ? '_input' : '_output']\n : never;\n\ntype ActionParams<TInput = unknown> = {\n _input: TInput;\n};\n\ntype ActionBuilder<TParams extends ActionParams> = {\n input: <TParser extends z.ZodType>(input: TParser) => ActionBuilder<{_input: TParser}>;\n action: <TOutput>(\n action: (params: {input: InferParserType<TParams['_input'], 'out'>}) => Promise<TOutput>,\n ) => (...[input]: OptionalizeUndefined<InferParserType<TParams['_input'], 'in'>>) => Promise<TOutput>;\n};\ntype AnyActionBuilder = ActionBuilder<any>;\n\ntype ActionBuilderDef<TParams extends ActionParams<any>> = {\n input: TParams['_input'];\n};\ntype AnyActionBuilderDef = ActionBuilderDef<any>;\n\nconst createNewServerActionBuilder = (def: Partial<AnyActionBuilderDef>) => {\n return createServerActionBuilder(def);\n};\n\nconst createServerActionBuilder = (\n initDef: Partial<AnyActionBuilderDef> = {},\n): ActionBuilder<{\n _input: UnsetMarker;\n}> => {\n const _def: ActionBuilderDef<{_input: z.ZodType | undefined}> = {\n input: undefined,\n ...initDef,\n };\n return {\n input: (input) => createNewServerActionBuilder({..._def, input}) as AnyActionBuilder,\n action: (action) => {\n return async (input) => {\n if (_def.input) {\n const result = _def.input.safeParse(input);\n if (!result.success) {\n throw fromZodError(result.error);\n }\n }\n return await action({input});\n };\n },\n };\n};\n\n/**\n * Server action builder\n */\nexport const serverAct = createServerActionBuilder();\n"],"mappings":"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","names":["issue"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "server-act",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"homepage": "https://github.com/chungweileong94/server-act#readme",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/chungweileong94/server-act.git"
|
|
8
|
+
},
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/chungweileong94/server-act/issues"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"module": "dist/index.mjs",
|
|
14
|
+
"types": "dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"next",
|
|
25
|
+
"nextjs",
|
|
26
|
+
"react",
|
|
27
|
+
"react server component",
|
|
28
|
+
"react server action",
|
|
29
|
+
"rsc",
|
|
30
|
+
"server component",
|
|
31
|
+
"server action",
|
|
32
|
+
"action"
|
|
33
|
+
],
|
|
34
|
+
"author": "chungweileong94",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"eslint": "^8.39.0",
|
|
38
|
+
"eslint-config-whiteroom": "^3.1.0",
|
|
39
|
+
"prettier": "^2.8.8",
|
|
40
|
+
"tsup": "^6.7.0",
|
|
41
|
+
"typescript": "^5.0.4",
|
|
42
|
+
"zod": "^3.21.4",
|
|
43
|
+
"zod-validation-error": "^1.3.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"typescript": "^5.0.4",
|
|
47
|
+
"zod": "^3.21.4"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsup",
|
|
51
|
+
"test": "vitest run",
|
|
52
|
+
"lint": "eslint src --ext .ts"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {test, expect} from 'vitest';
|
|
2
|
+
import z from 'zod';
|
|
3
|
+
|
|
4
|
+
import {serverAct} from '.';
|
|
5
|
+
|
|
6
|
+
test('should able to create action without input', async () => {
|
|
7
|
+
const action = serverAct.action(async () => Promise.resolve('bar'));
|
|
8
|
+
await expect(action()).resolves.toBe('bar');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('should able to create action with input', async () => {
|
|
12
|
+
const action = serverAct.input(z.string()).action(async () => Promise.resolve('bar'));
|
|
13
|
+
await expect(action('foo')).resolves.toBe('bar');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('should throw error if the input is invalid', async () => {
|
|
17
|
+
const action = serverAct.input(z.string()).action(async () => Promise.resolve('bar'));
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
await expect(action(1)).rejects.toThrowError();
|
|
21
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import {type z} from 'zod';
|
|
3
|
+
import {fromZodError} from 'zod-validation-error';
|
|
4
|
+
|
|
5
|
+
const unsetMarker = Symbol('unsetMarker');
|
|
6
|
+
type UnsetMarker = typeof unsetMarker;
|
|
7
|
+
|
|
8
|
+
type OptionalizeUndefined<T> = undefined extends T ? [param?: T] : [param: T];
|
|
9
|
+
|
|
10
|
+
type InferParserType<TParser, TType extends 'in' | 'out'> = TParser extends UnsetMarker
|
|
11
|
+
? undefined
|
|
12
|
+
: TParser extends z.ZodType
|
|
13
|
+
? TParser[TType extends 'in' ? '_input' : '_output']
|
|
14
|
+
: never;
|
|
15
|
+
|
|
16
|
+
type ActionParams<TInput = unknown> = {
|
|
17
|
+
_input: TInput;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type ActionBuilder<TParams extends ActionParams> = {
|
|
21
|
+
input: <TParser extends z.ZodType>(input: TParser) => ActionBuilder<{_input: TParser}>;
|
|
22
|
+
action: <TOutput>(
|
|
23
|
+
action: (params: {input: InferParserType<TParams['_input'], 'out'>}) => Promise<TOutput>,
|
|
24
|
+
) => (...[input]: OptionalizeUndefined<InferParserType<TParams['_input'], 'in'>>) => Promise<TOutput>;
|
|
25
|
+
};
|
|
26
|
+
type AnyActionBuilder = ActionBuilder<any>;
|
|
27
|
+
|
|
28
|
+
type ActionBuilderDef<TParams extends ActionParams<any>> = {
|
|
29
|
+
input: TParams['_input'];
|
|
30
|
+
};
|
|
31
|
+
type AnyActionBuilderDef = ActionBuilderDef<any>;
|
|
32
|
+
|
|
33
|
+
const createNewServerActionBuilder = (def: Partial<AnyActionBuilderDef>) => {
|
|
34
|
+
return createServerActionBuilder(def);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const createServerActionBuilder = (
|
|
38
|
+
initDef: Partial<AnyActionBuilderDef> = {},
|
|
39
|
+
): ActionBuilder<{
|
|
40
|
+
_input: UnsetMarker;
|
|
41
|
+
}> => {
|
|
42
|
+
const _def: ActionBuilderDef<{_input: z.ZodType | undefined}> = {
|
|
43
|
+
input: undefined,
|
|
44
|
+
...initDef,
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
input: (input) => createNewServerActionBuilder({..._def, input}) as AnyActionBuilder,
|
|
48
|
+
action: (action) => {
|
|
49
|
+
return async (input) => {
|
|
50
|
+
if (_def.input) {
|
|
51
|
+
const result = _def.input.safeParse(input);
|
|
52
|
+
if (!result.success) {
|
|
53
|
+
throw fromZodError(result.error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return await action({input});
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Server action builder
|
|
64
|
+
*/
|
|
65
|
+
export const serverAct = createServerActionBuilder();
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"display": "Strictest",
|
|
4
|
+
"_version": "2.0.0",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"lib": [
|
|
7
|
+
"ES2020"
|
|
8
|
+
],
|
|
9
|
+
"moduleResolution": "nodenext",
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"strict": true,
|
|
12
|
+
"allowUnusedLabels": false,
|
|
13
|
+
"allowUnreachableCode": false,
|
|
14
|
+
"exactOptionalPropertyTypes": true,
|
|
15
|
+
"noFallthroughCasesInSwitch": true,
|
|
16
|
+
"noImplicitOverride": true,
|
|
17
|
+
"noImplicitReturns": true,
|
|
18
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
19
|
+
"noUncheckedIndexedAccess": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"checkJs": true,
|
|
23
|
+
"esModuleInterop": true,
|
|
24
|
+
"skipLibCheck": true,
|
|
25
|
+
"forceConsistentCasingInFileNames": true
|
|
26
|
+
}
|
|
27
|
+
}
|