server-act 1.7.0 → 1.8.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 +69 -17
- package/dist/index.cjs +47 -15
- package/dist/index.d.cts +27 -7
- package/dist/index.d.mts +27 -7
- package/dist/index.mjs +45 -15
- package/dist/utils.cjs +2 -4
- package/dist/utils.mjs +1 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,12 +69,12 @@ import { serverAct } from "server-act";
|
|
|
69
69
|
import { z } from "zod";
|
|
70
70
|
|
|
71
71
|
export const sayHelloAction = serverAct
|
|
72
|
-
.
|
|
72
|
+
.use(({ next }) => {
|
|
73
73
|
const t = i18n();
|
|
74
74
|
const userId = "...";
|
|
75
|
-
return { t, userId };
|
|
75
|
+
return next({ ctx: { t, userId } });
|
|
76
76
|
})
|
|
77
|
-
.input((ctx) => {
|
|
77
|
+
.input(({ ctx }) => {
|
|
78
78
|
return z.object({
|
|
79
79
|
name: z.string().min(1, { message: ctx.t("form.name.required") }),
|
|
80
80
|
});
|
|
@@ -87,11 +87,12 @@ export const sayHelloAction = serverAct
|
|
|
87
87
|
|
|
88
88
|
#### Chaining Middlewares
|
|
89
89
|
|
|
90
|
-
You can chain multiple middlewares by calling `.
|
|
90
|
+
You can chain multiple middlewares by calling `.use(...)` repeatedly.
|
|
91
91
|
|
|
92
92
|
- Middlewares run in registration order.
|
|
93
|
-
- Each middleware receives the current `ctx` and
|
|
94
|
-
-
|
|
93
|
+
- Each middleware receives the current `ctx` and forwards additions with `next({ ctx })`.
|
|
94
|
+
- `next()` can be called without params when nothing needs to be added.
|
|
95
|
+
- `next({ ctx })` shallow-merges the provided keys into the current context.
|
|
95
96
|
- Later middleware values override earlier values for the same key.
|
|
96
97
|
- Errors thrown in middleware propagate and stop later middleware from running.
|
|
97
98
|
|
|
@@ -102,22 +103,73 @@ You can chain multiple middlewares by calling `.middleware(...)` repeatedly.
|
|
|
102
103
|
import { serverAct } from "server-act";
|
|
103
104
|
|
|
104
105
|
export const createGreetingAction = serverAct
|
|
105
|
-
.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
.
|
|
114
|
-
|
|
115
|
-
|
|
106
|
+
.use(({ next }) =>
|
|
107
|
+
next({
|
|
108
|
+
ctx: {
|
|
109
|
+
requestId: crypto.randomUUID(),
|
|
110
|
+
role: "user",
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
)
|
|
114
|
+
.use(({ ctx, next }) =>
|
|
115
|
+
next({
|
|
116
|
+
ctx: {
|
|
117
|
+
role: "admin", // overrides previous role
|
|
118
|
+
actorLabel: `${ctx.role}-actor`,
|
|
119
|
+
},
|
|
120
|
+
}),
|
|
121
|
+
)
|
|
122
|
+
.use(({ ctx, next }) =>
|
|
123
|
+
next({
|
|
124
|
+
ctx: {
|
|
125
|
+
trace: `${ctx.requestId}:${ctx.actorLabel}`,
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
)
|
|
116
129
|
.action(async ({ ctx }) => {
|
|
117
130
|
return `${ctx.role} -> ${ctx.trace}`;
|
|
118
131
|
});
|
|
119
132
|
```
|
|
120
133
|
|
|
134
|
+
#### Migrating From `.middleware()`
|
|
135
|
+
|
|
136
|
+
`.middleware()` is still supported for backward compatibility, but it is deprecated in favor of `.use()`.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const legacyAction = serverAct.middleware(({ ctx }) => ({
|
|
140
|
+
user: getUser(),
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
const nextStyleAction = serverAct.use(({ ctx, next }) =>
|
|
144
|
+
next({
|
|
145
|
+
ctx: {
|
|
146
|
+
user: getUser(),
|
|
147
|
+
},
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Reusable Middleware
|
|
153
|
+
|
|
154
|
+
Use `createServerActMiddleware` to define middleware once and reuse it across actions.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { createServerActMiddleware, serverAct } from "server-act";
|
|
158
|
+
|
|
159
|
+
const requestIdMiddleware = createServerActMiddleware(({ next }) =>
|
|
160
|
+
next({ ctx: { requestId: crypto.randomUUID() } }),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const traceMiddleware = createServerActMiddleware(({ ctx, next }) =>
|
|
164
|
+
next({ ctx: { trace: `${ctx.requestId}-trace` } }),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
export const action = serverAct
|
|
168
|
+
.use(requestIdMiddleware)
|
|
169
|
+
.use(traceMiddleware)
|
|
170
|
+
.action(async ({ ctx }) => `${ctx.requestId}:${ctx.trace}`);
|
|
171
|
+
```
|
|
172
|
+
|
|
121
173
|
### `useActionState` Support
|
|
122
174
|
|
|
123
175
|
> `useActionState` Documentation:
|
package/dist/index.cjs
CHANGED
|
@@ -1,21 +1,41 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
1
2
|
let _standard_schema_utils = require("@standard-schema/utils");
|
|
2
|
-
|
|
3
3
|
//#region src/internal/middleware.ts
|
|
4
|
+
function normalizeCtx(ctx) {
|
|
5
|
+
return ctx && typeof ctx === "object" ? { ...ctx } : {};
|
|
6
|
+
}
|
|
4
7
|
/**
|
|
5
8
|
* Executes an array of middleware functions with the given initial context.
|
|
6
9
|
*/
|
|
7
10
|
async function executeMiddlewares(middlewares, initialCtx) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
const executeAt = async (index, ctx) => {
|
|
12
|
+
const entry = middlewares[index];
|
|
13
|
+
if (!entry) return ctx;
|
|
14
|
+
if (entry.kind === "legacy") {
|
|
15
|
+
const result = await entry.middleware({ ctx });
|
|
16
|
+
const nextCtx = result && typeof result === "object" ? {
|
|
17
|
+
...ctx,
|
|
18
|
+
...result
|
|
19
|
+
} : ctx;
|
|
20
|
+
return await executeAt(index + 1, nextCtx);
|
|
21
|
+
}
|
|
22
|
+
let nextCalled = false;
|
|
23
|
+
const result = await entry.middleware({
|
|
24
|
+
ctx,
|
|
25
|
+
next: async (opts) => {
|
|
26
|
+
nextCalled = true;
|
|
27
|
+
const nextCtx = opts?.ctx ? {
|
|
28
|
+
...ctx,
|
|
29
|
+
...opts.ctx
|
|
30
|
+
} : ctx;
|
|
31
|
+
return await executeAt(index + 1, nextCtx);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
if (!nextCalled) throw new Error(".use() middleware must call next()");
|
|
35
|
+
return normalizeCtx(result);
|
|
36
|
+
};
|
|
37
|
+
return await executeAt(0, normalizeCtx(initialCtx));
|
|
17
38
|
}
|
|
18
|
-
|
|
19
39
|
//#endregion
|
|
20
40
|
//#region src/internal/schema.ts
|
|
21
41
|
async function standardValidate(schema, input) {
|
|
@@ -37,12 +57,14 @@ function getInputErrors(issues) {
|
|
|
37
57
|
fieldErrors
|
|
38
58
|
};
|
|
39
59
|
}
|
|
40
|
-
|
|
41
60
|
//#endregion
|
|
42
61
|
//#region src/index.ts
|
|
43
62
|
function createNewServerActionBuilder(def) {
|
|
44
63
|
return createServerActionBuilder(def);
|
|
45
64
|
}
|
|
65
|
+
function createServerActMiddleware(middleware) {
|
|
66
|
+
return middleware;
|
|
67
|
+
}
|
|
46
68
|
function createServerActionBuilder(initDef = {}) {
|
|
47
69
|
const _def = {
|
|
48
70
|
input: void 0,
|
|
@@ -52,8 +74,18 @@ function createServerActionBuilder(initDef = {}) {
|
|
|
52
74
|
return {
|
|
53
75
|
middleware: (middleware) => createNewServerActionBuilder({
|
|
54
76
|
..._def,
|
|
55
|
-
middleware: [..._def.middleware,
|
|
77
|
+
middleware: [..._def.middleware, {
|
|
78
|
+
kind: "legacy",
|
|
79
|
+
middleware
|
|
80
|
+
}]
|
|
56
81
|
}),
|
|
82
|
+
use: ((middleware) => createNewServerActionBuilder({
|
|
83
|
+
..._def,
|
|
84
|
+
middleware: [..._def.middleware, {
|
|
85
|
+
kind: "use",
|
|
86
|
+
middleware
|
|
87
|
+
}]
|
|
88
|
+
})),
|
|
57
89
|
input: (input) => createNewServerActionBuilder({
|
|
58
90
|
..._def,
|
|
59
91
|
input
|
|
@@ -136,6 +168,6 @@ function createServerActionBuilder(initDef = {}) {
|
|
|
136
168
|
* Server action builder
|
|
137
169
|
*/
|
|
138
170
|
const serverAct = createServerActionBuilder();
|
|
139
|
-
|
|
140
171
|
//#endregion
|
|
141
|
-
exports.
|
|
172
|
+
exports.createServerActMiddleware = createServerActMiddleware;
|
|
173
|
+
exports.serverAct = serverAct;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
|
|
3
3
|
//#region src/internal/middleware.d.ts
|
|
4
|
-
type
|
|
4
|
+
type LegacyMiddlewareFunction<TContext, TReturn> = (params: {
|
|
5
5
|
ctx: TContext;
|
|
6
6
|
}) => Promise<TReturn> | TReturn;
|
|
7
|
+
type MiddlewareContext = Record<string, unknown>;
|
|
8
|
+
type Prettify$1<T> = { [P in keyof T]: T[P] } & {};
|
|
9
|
+
type MiddlewareNextFunction<TContext extends MiddlewareContext> = <TAddedContext extends MiddlewareContext>(opts?: {
|
|
10
|
+
ctx?: TAddedContext;
|
|
11
|
+
}) => Promise<Prettify$1<TContext & TAddedContext>>;
|
|
12
|
+
type UseMiddlewareFunction<TContext extends MiddlewareContext, TNextContext extends MiddlewareContext> = (params: {
|
|
13
|
+
ctx: TContext;
|
|
14
|
+
next: MiddlewareNextFunction<TContext>;
|
|
15
|
+
}) => Promise<TNextContext> | TNextContext;
|
|
7
16
|
//#endregion
|
|
8
17
|
//#region src/internal/schema.d.ts
|
|
9
18
|
declare function getInputErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>): {
|
|
@@ -15,6 +24,7 @@ declare function getInputErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>):
|
|
|
15
24
|
declare const unsetMarker: unique symbol;
|
|
16
25
|
type UnsetMarker = typeof unsetMarker;
|
|
17
26
|
type RemoveUnsetMarker<T> = T extends UnsetMarker ? undefined : T;
|
|
27
|
+
type NormalizeContext<T> = RemoveUnsetMarker<T> extends Record<string, unknown> ? RemoveUnsetMarker<T> : {};
|
|
18
28
|
type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
|
|
19
29
|
type Prettify<T> = { [P in keyof T]: T[P] } & {};
|
|
20
30
|
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;
|
|
@@ -30,16 +40,25 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
30
40
|
*
|
|
31
41
|
* Chaining multiple middlewares is possible, each middleware receives context from previous middlewares
|
|
32
42
|
* and returns additional context that gets merged.
|
|
43
|
+
*
|
|
44
|
+
* @deprecated Use `.use()` instead.
|
|
33
45
|
*/
|
|
34
|
-
middleware: <TNewContext>(middleware:
|
|
46
|
+
middleware: <TNewContext>(middleware: LegacyMiddlewareFunction<NormalizeContext<TParams["_context"]>, TNewContext>) => ActionBuilder<{
|
|
35
47
|
_input: TParams["_input"];
|
|
36
48
|
_context: TParams["_context"] extends UnsetMarker ? TNewContext : Prettify<TParams["_context"] & TNewContext>;
|
|
37
49
|
}>;
|
|
50
|
+
/**
|
|
51
|
+
* tRPC-style middleware that forwards context via `next()`.
|
|
52
|
+
*/
|
|
53
|
+
use: <TNextContext extends Record<string, unknown>>(middleware: UseMiddlewareFunction<NormalizeContext<TParams["_context"]>, TNextContext>) => ActionBuilder<{
|
|
54
|
+
_input: TParams["_input"];
|
|
55
|
+
_context: TNextContext;
|
|
56
|
+
}>;
|
|
38
57
|
/**
|
|
39
58
|
* Input validation for the action.
|
|
40
59
|
*/
|
|
41
60
|
input: <TParser extends StandardSchemaV1>(input: ((params: {
|
|
42
|
-
ctx:
|
|
61
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
43
62
|
}) => Promise<TParser> | TParser) | TParser) => Omit<ActionBuilder<{
|
|
44
63
|
_input: TParser;
|
|
45
64
|
_context: TParams["_context"];
|
|
@@ -48,14 +67,14 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
48
67
|
* Create an action.
|
|
49
68
|
*/
|
|
50
69
|
action: <TOutput>(action: (params: {
|
|
51
|
-
ctx:
|
|
70
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
52
71
|
input: InferInputType<TParams["_input"], "out">;
|
|
53
72
|
}) => Promise<TOutput>) => SanitizeFunctionParam<(input: InferInputType<TParams["_input"], "in">) => Promise<TOutput>>;
|
|
54
73
|
/**
|
|
55
74
|
* Create an action for React `useActionState`
|
|
56
75
|
*/
|
|
57
76
|
stateAction: <TState, TPrevState = UnsetMarker>(action: (params: Prettify<{
|
|
58
|
-
ctx:
|
|
77
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
59
78
|
prevState: RemoveUnsetMarker<TPrevState>;
|
|
60
79
|
rawInput: InferInputType<TParams["_input"], "in">;
|
|
61
80
|
} & ({
|
|
@@ -71,7 +90,7 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
71
90
|
* @deprecated Use `stateAction` instead.
|
|
72
91
|
*/
|
|
73
92
|
formAction: <TState, TPrevState = UnsetMarker>(action: (params: Prettify<{
|
|
74
|
-
ctx:
|
|
93
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
75
94
|
prevState: RemoveUnsetMarker<TPrevState>;
|
|
76
95
|
formData: FormData;
|
|
77
96
|
} & ({
|
|
@@ -82,6 +101,7 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
82
101
|
formErrors: ReturnType<typeof getInputErrors>;
|
|
83
102
|
})>) => Promise<TState>) => (prevState: TState | RemoveUnsetMarker<TPrevState>, formData: InferInputType<TParams["_input"], "in">) => Promise<TState | RemoveUnsetMarker<TPrevState>>;
|
|
84
103
|
}
|
|
104
|
+
declare function createServerActMiddleware<TAddedContext extends Record<string, unknown>, TContext extends Record<string, unknown> = {}>(middleware: UseMiddlewareFunction<TContext, Prettify<TContext & TAddedContext>>): UseMiddlewareFunction<TContext, Prettify<TContext & TAddedContext>>;
|
|
85
105
|
/**
|
|
86
106
|
* Server action builder
|
|
87
107
|
*/
|
|
@@ -90,4 +110,4 @@ declare const serverAct: ActionBuilder<{
|
|
|
90
110
|
_context: UnsetMarker;
|
|
91
111
|
}>;
|
|
92
112
|
//#endregion
|
|
93
|
-
export { serverAct };
|
|
113
|
+
export { createServerActMiddleware, serverAct };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
|
|
3
3
|
//#region src/internal/middleware.d.ts
|
|
4
|
-
type
|
|
4
|
+
type LegacyMiddlewareFunction<TContext, TReturn> = (params: {
|
|
5
5
|
ctx: TContext;
|
|
6
6
|
}) => Promise<TReturn> | TReturn;
|
|
7
|
+
type MiddlewareContext = Record<string, unknown>;
|
|
8
|
+
type Prettify$1<T> = { [P in keyof T]: T[P] } & {};
|
|
9
|
+
type MiddlewareNextFunction<TContext extends MiddlewareContext> = <TAddedContext extends MiddlewareContext>(opts?: {
|
|
10
|
+
ctx?: TAddedContext;
|
|
11
|
+
}) => Promise<Prettify$1<TContext & TAddedContext>>;
|
|
12
|
+
type UseMiddlewareFunction<TContext extends MiddlewareContext, TNextContext extends MiddlewareContext> = (params: {
|
|
13
|
+
ctx: TContext;
|
|
14
|
+
next: MiddlewareNextFunction<TContext>;
|
|
15
|
+
}) => Promise<TNextContext> | TNextContext;
|
|
7
16
|
//#endregion
|
|
8
17
|
//#region src/internal/schema.d.ts
|
|
9
18
|
declare function getInputErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>): {
|
|
@@ -15,6 +24,7 @@ declare function getInputErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>):
|
|
|
15
24
|
declare const unsetMarker: unique symbol;
|
|
16
25
|
type UnsetMarker = typeof unsetMarker;
|
|
17
26
|
type RemoveUnsetMarker<T> = T extends UnsetMarker ? undefined : T;
|
|
27
|
+
type NormalizeContext<T> = RemoveUnsetMarker<T> extends Record<string, unknown> ? RemoveUnsetMarker<T> : {};
|
|
18
28
|
type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
|
|
19
29
|
type Prettify<T> = { [P in keyof T]: T[P] } & {};
|
|
20
30
|
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;
|
|
@@ -30,16 +40,25 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
30
40
|
*
|
|
31
41
|
* Chaining multiple middlewares is possible, each middleware receives context from previous middlewares
|
|
32
42
|
* and returns additional context that gets merged.
|
|
43
|
+
*
|
|
44
|
+
* @deprecated Use `.use()` instead.
|
|
33
45
|
*/
|
|
34
|
-
middleware: <TNewContext>(middleware:
|
|
46
|
+
middleware: <TNewContext>(middleware: LegacyMiddlewareFunction<NormalizeContext<TParams["_context"]>, TNewContext>) => ActionBuilder<{
|
|
35
47
|
_input: TParams["_input"];
|
|
36
48
|
_context: TParams["_context"] extends UnsetMarker ? TNewContext : Prettify<TParams["_context"] & TNewContext>;
|
|
37
49
|
}>;
|
|
50
|
+
/**
|
|
51
|
+
* tRPC-style middleware that forwards context via `next()`.
|
|
52
|
+
*/
|
|
53
|
+
use: <TNextContext extends Record<string, unknown>>(middleware: UseMiddlewareFunction<NormalizeContext<TParams["_context"]>, TNextContext>) => ActionBuilder<{
|
|
54
|
+
_input: TParams["_input"];
|
|
55
|
+
_context: TNextContext;
|
|
56
|
+
}>;
|
|
38
57
|
/**
|
|
39
58
|
* Input validation for the action.
|
|
40
59
|
*/
|
|
41
60
|
input: <TParser extends StandardSchemaV1>(input: ((params: {
|
|
42
|
-
ctx:
|
|
61
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
43
62
|
}) => Promise<TParser> | TParser) | TParser) => Omit<ActionBuilder<{
|
|
44
63
|
_input: TParser;
|
|
45
64
|
_context: TParams["_context"];
|
|
@@ -48,14 +67,14 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
48
67
|
* Create an action.
|
|
49
68
|
*/
|
|
50
69
|
action: <TOutput>(action: (params: {
|
|
51
|
-
ctx:
|
|
70
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
52
71
|
input: InferInputType<TParams["_input"], "out">;
|
|
53
72
|
}) => Promise<TOutput>) => SanitizeFunctionParam<(input: InferInputType<TParams["_input"], "in">) => Promise<TOutput>>;
|
|
54
73
|
/**
|
|
55
74
|
* Create an action for React `useActionState`
|
|
56
75
|
*/
|
|
57
76
|
stateAction: <TState, TPrevState = UnsetMarker>(action: (params: Prettify<{
|
|
58
|
-
ctx:
|
|
77
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
59
78
|
prevState: RemoveUnsetMarker<TPrevState>;
|
|
60
79
|
rawInput: InferInputType<TParams["_input"], "in">;
|
|
61
80
|
} & ({
|
|
@@ -71,7 +90,7 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
71
90
|
* @deprecated Use `stateAction` instead.
|
|
72
91
|
*/
|
|
73
92
|
formAction: <TState, TPrevState = UnsetMarker>(action: (params: Prettify<{
|
|
74
|
-
ctx:
|
|
93
|
+
ctx: NormalizeContext<TParams["_context"]>;
|
|
75
94
|
prevState: RemoveUnsetMarker<TPrevState>;
|
|
76
95
|
formData: FormData;
|
|
77
96
|
} & ({
|
|
@@ -82,6 +101,7 @@ interface ActionBuilder<TParams extends ActionParams> {
|
|
|
82
101
|
formErrors: ReturnType<typeof getInputErrors>;
|
|
83
102
|
})>) => Promise<TState>) => (prevState: TState | RemoveUnsetMarker<TPrevState>, formData: InferInputType<TParams["_input"], "in">) => Promise<TState | RemoveUnsetMarker<TPrevState>>;
|
|
84
103
|
}
|
|
104
|
+
declare function createServerActMiddleware<TAddedContext extends Record<string, unknown>, TContext extends Record<string, unknown> = {}>(middleware: UseMiddlewareFunction<TContext, Prettify<TContext & TAddedContext>>): UseMiddlewareFunction<TContext, Prettify<TContext & TAddedContext>>;
|
|
85
105
|
/**
|
|
86
106
|
* Server action builder
|
|
87
107
|
*/
|
|
@@ -90,4 +110,4 @@ declare const serverAct: ActionBuilder<{
|
|
|
90
110
|
_context: UnsetMarker;
|
|
91
111
|
}>;
|
|
92
112
|
//#endregion
|
|
93
|
-
export { serverAct };
|
|
113
|
+
export { createServerActMiddleware, serverAct };
|
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import { SchemaError, getDotPath } from "@standard-schema/utils";
|
|
2
|
-
|
|
3
2
|
//#region src/internal/middleware.ts
|
|
3
|
+
function normalizeCtx(ctx) {
|
|
4
|
+
return ctx && typeof ctx === "object" ? { ...ctx } : {};
|
|
5
|
+
}
|
|
4
6
|
/**
|
|
5
7
|
* Executes an array of middleware functions with the given initial context.
|
|
6
8
|
*/
|
|
7
9
|
async function executeMiddlewares(middlewares, initialCtx) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
const executeAt = async (index, ctx) => {
|
|
11
|
+
const entry = middlewares[index];
|
|
12
|
+
if (!entry) return ctx;
|
|
13
|
+
if (entry.kind === "legacy") {
|
|
14
|
+
const result = await entry.middleware({ ctx });
|
|
15
|
+
const nextCtx = result && typeof result === "object" ? {
|
|
16
|
+
...ctx,
|
|
17
|
+
...result
|
|
18
|
+
} : ctx;
|
|
19
|
+
return await executeAt(index + 1, nextCtx);
|
|
20
|
+
}
|
|
21
|
+
let nextCalled = false;
|
|
22
|
+
const result = await entry.middleware({
|
|
23
|
+
ctx,
|
|
24
|
+
next: async (opts) => {
|
|
25
|
+
nextCalled = true;
|
|
26
|
+
const nextCtx = opts?.ctx ? {
|
|
27
|
+
...ctx,
|
|
28
|
+
...opts.ctx
|
|
29
|
+
} : ctx;
|
|
30
|
+
return await executeAt(index + 1, nextCtx);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
if (!nextCalled) throw new Error(".use() middleware must call next()");
|
|
34
|
+
return normalizeCtx(result);
|
|
35
|
+
};
|
|
36
|
+
return await executeAt(0, normalizeCtx(initialCtx));
|
|
17
37
|
}
|
|
18
|
-
|
|
19
38
|
//#endregion
|
|
20
39
|
//#region src/internal/schema.ts
|
|
21
40
|
async function standardValidate(schema, input) {
|
|
@@ -37,12 +56,14 @@ function getInputErrors(issues) {
|
|
|
37
56
|
fieldErrors
|
|
38
57
|
};
|
|
39
58
|
}
|
|
40
|
-
|
|
41
59
|
//#endregion
|
|
42
60
|
//#region src/index.ts
|
|
43
61
|
function createNewServerActionBuilder(def) {
|
|
44
62
|
return createServerActionBuilder(def);
|
|
45
63
|
}
|
|
64
|
+
function createServerActMiddleware(middleware) {
|
|
65
|
+
return middleware;
|
|
66
|
+
}
|
|
46
67
|
function createServerActionBuilder(initDef = {}) {
|
|
47
68
|
const _def = {
|
|
48
69
|
input: void 0,
|
|
@@ -52,8 +73,18 @@ function createServerActionBuilder(initDef = {}) {
|
|
|
52
73
|
return {
|
|
53
74
|
middleware: (middleware) => createNewServerActionBuilder({
|
|
54
75
|
..._def,
|
|
55
|
-
middleware: [..._def.middleware,
|
|
76
|
+
middleware: [..._def.middleware, {
|
|
77
|
+
kind: "legacy",
|
|
78
|
+
middleware
|
|
79
|
+
}]
|
|
56
80
|
}),
|
|
81
|
+
use: ((middleware) => createNewServerActionBuilder({
|
|
82
|
+
..._def,
|
|
83
|
+
middleware: [..._def.middleware, {
|
|
84
|
+
kind: "use",
|
|
85
|
+
middleware
|
|
86
|
+
}]
|
|
87
|
+
})),
|
|
57
88
|
input: (input) => createNewServerActionBuilder({
|
|
58
89
|
..._def,
|
|
59
90
|
input
|
|
@@ -136,6 +167,5 @@ function createServerActionBuilder(initDef = {}) {
|
|
|
136
167
|
* Server action builder
|
|
137
168
|
*/
|
|
138
169
|
const serverAct = createServerActionBuilder();
|
|
139
|
-
|
|
140
170
|
//#endregion
|
|
141
|
-
export { serverAct };
|
|
171
|
+
export { createServerActMiddleware, serverAct };
|
package/dist/utils.cjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region src/internal/assert.ts
|
|
3
3
|
function assert(condition, message) {
|
|
4
4
|
if (!condition) throw new Error(message || "Assertion failed");
|
|
5
5
|
}
|
|
6
|
-
|
|
7
6
|
//#endregion
|
|
8
7
|
//#region src/utils.ts
|
|
9
8
|
function isNumberString(str) {
|
|
@@ -102,6 +101,5 @@ function formDataToObject(formData) {
|
|
|
102
101
|
for (const [key, value] of formData.entries()) set(obj, key.split(/[.[\]]/).filter(Boolean), value);
|
|
103
102
|
return obj;
|
|
104
103
|
}
|
|
105
|
-
|
|
106
104
|
//#endregion
|
|
107
|
-
exports.formDataToObject = formDataToObject;
|
|
105
|
+
exports.formDataToObject = formDataToObject;
|
package/dist/utils.mjs
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
function assert(condition, message) {
|
|
3
3
|
if (!condition) throw new Error(message || "Assertion failed");
|
|
4
4
|
}
|
|
5
|
-
|
|
6
5
|
//#endregion
|
|
7
6
|
//#region src/utils.ts
|
|
8
7
|
function isNumberString(str) {
|
|
@@ -101,6 +100,5 @@ function formDataToObject(formData) {
|
|
|
101
100
|
for (const [key, value] of formData.entries()) set(obj, key.split(/[.[\]]/).filter(Boolean), value);
|
|
102
101
|
return obj;
|
|
103
102
|
}
|
|
104
|
-
|
|
105
103
|
//#endregion
|
|
106
|
-
export { formDataToObject };
|
|
104
|
+
export { formDataToObject };
|