@orpc/server 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/chunk-26DTFWOI.js +200 -0
- package/dist/chunk-26DTFWOI.js.map +1 -0
- package/dist/fetch.js +87 -91
- package/dist/fetch.js.map +1 -1
- package/dist/index.js +6 -9
- package/dist/index.js.map +1 -1
- package/dist/src/adapters/fetch.d.ts +9 -3
- package/dist/src/adapters/fetch.d.ts.map +1 -1
- package/dist/src/builder.d.ts +4 -4
- package/dist/src/builder.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/middleware.d.ts +17 -7
- package/dist/src/middleware.d.ts.map +1 -1
- package/dist/src/procedure-builder.d.ts +4 -4
- package/dist/src/procedure-builder.d.ts.map +1 -1
- package/dist/src/procedure-caller.d.ts +0 -5
- package/dist/src/procedure-caller.d.ts.map +1 -1
- package/dist/src/procedure-implementer.d.ts +4 -5
- package/dist/src/procedure-implementer.d.ts.map +1 -1
- package/dist/src/procedure.d.ts +8 -9
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/router-builder.d.ts +2 -2
- package/dist/src/router-builder.d.ts.map +1 -1
- package/dist/src/router-caller.d.ts +1 -6
- package/dist/src/router-caller.d.ts.map +1 -1
- package/dist/src/router-implementer.d.ts +2 -2
- package/dist/src/router-implementer.d.ts.map +1 -1
- package/dist/src/router.d.ts +1 -1
- package/dist/src/router.d.ts.map +1 -1
- package/dist/src/types.d.ts +1 -10
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils.d.ts +1 -2
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/adapters/fetch.test.ts +32 -17
- package/src/adapters/fetch.ts +134 -123
- package/src/builder.test.ts +48 -39
- package/src/builder.ts +32 -30
- package/src/index.ts +2 -2
- package/src/middleware.test.ts +54 -73
- package/src/middleware.ts +39 -22
- package/src/procedure-builder.test.ts +26 -22
- package/src/procedure-builder.ts +15 -15
- package/src/procedure-caller.test.ts +25 -70
- package/src/procedure-caller.ts +69 -88
- package/src/procedure-implementer.test.ts +27 -22
- package/src/procedure-implementer.ts +16 -17
- package/src/procedure.test.ts +17 -12
- package/src/procedure.ts +46 -45
- package/src/router-builder.test.ts +4 -4
- package/src/router-builder.ts +12 -10
- package/src/router-caller.test.ts +6 -6
- package/src/router-caller.ts +5 -16
- package/src/router-implementer.test.ts +12 -12
- package/src/router-implementer.ts +9 -6
- package/src/router.test.ts +4 -4
- package/src/router.ts +12 -10
- package/src/types.test.ts +1 -1
- package/src/types.ts +1 -15
- package/src/utils.test.ts +2 -229
- package/src/utils.ts +5 -84
- package/dist/chunk-ACLC6USM.js +0 -262
- package/dist/chunk-ACLC6USM.js.map +0 -1
package/src/types.ts
CHANGED
@@ -7,22 +7,8 @@ export type MergeContext<
|
|
7
7
|
TB extends Context,
|
8
8
|
> = TA extends undefined ? TB : TB extends undefined ? TA : TA & TB
|
9
9
|
|
10
|
-
export interface Meta
|
10
|
+
export interface Meta {
|
11
11
|
path: string[]
|
12
12
|
internal: boolean
|
13
13
|
procedure: WELL_DEFINED_PROCEDURE
|
14
14
|
}
|
15
|
-
|
16
|
-
export type Promisable<T> = T | Promise<T>
|
17
|
-
|
18
|
-
export interface UnsubscribeFn {
|
19
|
-
(): void
|
20
|
-
}
|
21
|
-
|
22
|
-
export interface Hooks<T> {
|
23
|
-
onSuccess: (fn: (output: T) => Promisable<void>) => UnsubscribeFn
|
24
|
-
onError: (fn: (error: unknown) => Promisable<void>) => UnsubscribeFn
|
25
|
-
onFinish: (
|
26
|
-
fn: (output: T | undefined, error: unknown | undefined) => Promisable<void>,
|
27
|
-
) => UnsubscribeFn
|
28
|
-
}
|
package/src/utils.test.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import {
|
1
|
+
import { mergeContext } from './utils'
|
2
2
|
|
3
|
-
|
3
|
+
it('mergeContext', () => {
|
4
4
|
expect(mergeContext(undefined, undefined)).toBe(undefined)
|
5
5
|
expect(mergeContext(undefined, { foo: 'bar' })).toEqual({ foo: 'bar' })
|
6
6
|
expect(mergeContext({ foo: 'bar' }, undefined)).toEqual({ foo: 'bar' })
|
@@ -14,230 +14,3 @@ test('mergeContext', () => {
|
|
14
14
|
bar: 'bar',
|
15
15
|
})
|
16
16
|
})
|
17
|
-
|
18
|
-
describe('hook', async () => {
|
19
|
-
it('on success', async () => {
|
20
|
-
const onSuccess = vi.fn()
|
21
|
-
const onError = vi.fn()
|
22
|
-
const onFinish = vi.fn()
|
23
|
-
|
24
|
-
await hook(async (hooks) => {
|
25
|
-
hooks.onSuccess(onSuccess)
|
26
|
-
hooks.onError(onError)
|
27
|
-
hooks.onFinish(onFinish)
|
28
|
-
|
29
|
-
return 'foo'
|
30
|
-
})
|
31
|
-
|
32
|
-
expect(onSuccess).toHaveBeenCalledWith('foo')
|
33
|
-
expect(onError).not.toHaveBeenCalled()
|
34
|
-
expect(onFinish).toHaveBeenCalledWith('foo', undefined)
|
35
|
-
})
|
36
|
-
|
37
|
-
it('on failed', async () => {
|
38
|
-
const onSuccess = vi.fn()
|
39
|
-
const onError = vi.fn()
|
40
|
-
const onFinish = vi.fn()
|
41
|
-
const error = new Error('foo')
|
42
|
-
|
43
|
-
try {
|
44
|
-
await hook(async (hooks) => {
|
45
|
-
hooks.onSuccess(onSuccess)
|
46
|
-
hooks.onError(onError)
|
47
|
-
hooks.onFinish(onFinish)
|
48
|
-
|
49
|
-
throw error
|
50
|
-
})
|
51
|
-
} catch (e) {
|
52
|
-
expect(e).toBe(error)
|
53
|
-
}
|
54
|
-
|
55
|
-
expect(onSuccess).not.toHaveBeenCalled()
|
56
|
-
expect(onError).toHaveBeenCalledWith(error)
|
57
|
-
expect(onFinish).toHaveBeenCalledWith(undefined, error)
|
58
|
-
})
|
59
|
-
|
60
|
-
it('throw the last error', async () => {
|
61
|
-
const error = new Error('foo')
|
62
|
-
const error1 = new Error('1')
|
63
|
-
const error2 = new Error('2')
|
64
|
-
|
65
|
-
try {
|
66
|
-
await hook(async (hooks) => {
|
67
|
-
hooks.onSuccess(() => {
|
68
|
-
throw error
|
69
|
-
})
|
70
|
-
})
|
71
|
-
} catch (e) {
|
72
|
-
expect(e).toBe(error)
|
73
|
-
}
|
74
|
-
|
75
|
-
try {
|
76
|
-
await hook(async (hooks) => {
|
77
|
-
hooks.onError(() => {
|
78
|
-
throw error1
|
79
|
-
})
|
80
|
-
})
|
81
|
-
} catch (e) {
|
82
|
-
expect(e).toBe(error1)
|
83
|
-
}
|
84
|
-
|
85
|
-
try {
|
86
|
-
await hook(async (hooks) => {
|
87
|
-
hooks.onFinish(() => {
|
88
|
-
throw error2
|
89
|
-
})
|
90
|
-
})
|
91
|
-
} catch (e) {
|
92
|
-
expect(e).toBe(error2)
|
93
|
-
}
|
94
|
-
|
95
|
-
try {
|
96
|
-
await hook(async (hooks) => {
|
97
|
-
hooks.onError((e) => {
|
98
|
-
expect(e).toBe(error)
|
99
|
-
throw error1
|
100
|
-
})
|
101
|
-
hooks.onFinish((_, error) => {
|
102
|
-
expect(error).toBe(error1)
|
103
|
-
throw error2
|
104
|
-
})
|
105
|
-
|
106
|
-
throw error
|
107
|
-
})
|
108
|
-
} catch (e) {
|
109
|
-
expect(e).toBe(error2)
|
110
|
-
}
|
111
|
-
})
|
112
|
-
|
113
|
-
it('Fist In Last Out', async () => {
|
114
|
-
const ref = { value: 0 }
|
115
|
-
const hooked = hook(async (hooks) => {
|
116
|
-
hooks.onSuccess(() => {
|
117
|
-
expect(ref).toEqual({ value: 2 })
|
118
|
-
ref.value++
|
119
|
-
})
|
120
|
-
hooks.onSuccess(() => {
|
121
|
-
expect(ref).toEqual({ value: 1 })
|
122
|
-
ref.value++
|
123
|
-
})
|
124
|
-
hooks.onSuccess(() => {
|
125
|
-
expect(ref).toEqual({ value: 0 })
|
126
|
-
ref.value++
|
127
|
-
})
|
128
|
-
|
129
|
-
hooks.onFinish(() => {
|
130
|
-
expect(ref).toEqual({ value: 5 })
|
131
|
-
ref.value++
|
132
|
-
})
|
133
|
-
hooks.onFinish(() => {
|
134
|
-
expect(ref).toEqual({ value: 4 })
|
135
|
-
ref.value++
|
136
|
-
})
|
137
|
-
hooks.onFinish(() => {
|
138
|
-
expect(ref).toEqual({ value: 3 })
|
139
|
-
ref.value++
|
140
|
-
})
|
141
|
-
})
|
142
|
-
|
143
|
-
await expect(hooked).resolves.toEqual(undefined)
|
144
|
-
expect(ref).toEqual({ value: 6 })
|
145
|
-
})
|
146
|
-
|
147
|
-
it('Fist In Last Out - onError', async () => {
|
148
|
-
const ref = { value: 0 }
|
149
|
-
const hooked = hook(async (hooks) => {
|
150
|
-
hooks.onError(() => {
|
151
|
-
expect(ref).toEqual({ value: 2 })
|
152
|
-
ref.value++
|
153
|
-
})
|
154
|
-
hooks.onError(() => {
|
155
|
-
expect(ref).toEqual({ value: 1 })
|
156
|
-
ref.value++
|
157
|
-
})
|
158
|
-
hooks.onError(() => {
|
159
|
-
expect(ref).toEqual({ value: 0 })
|
160
|
-
ref.value++
|
161
|
-
})
|
162
|
-
|
163
|
-
hooks.onFinish(() => {
|
164
|
-
expect(ref).toEqual({ value: 5 })
|
165
|
-
ref.value++
|
166
|
-
})
|
167
|
-
hooks.onFinish(() => {
|
168
|
-
expect(ref).toEqual({ value: 4 })
|
169
|
-
ref.value++
|
170
|
-
})
|
171
|
-
hooks.onFinish(() => {
|
172
|
-
expect(ref).toEqual({ value: 3 })
|
173
|
-
ref.value++
|
174
|
-
})
|
175
|
-
|
176
|
-
throw new Error('foo')
|
177
|
-
})
|
178
|
-
|
179
|
-
await expect(hooked).rejects.toThrow('foo')
|
180
|
-
expect(ref).toEqual({ value: 6 })
|
181
|
-
})
|
182
|
-
|
183
|
-
it('ensure run every onSuccess and onFinish even on throw many times', async () => {
|
184
|
-
const error = new Error('foo')
|
185
|
-
const error1 = new Error('1')
|
186
|
-
const error2 = new Error('2')
|
187
|
-
|
188
|
-
const onError = vi.fn(() => {
|
189
|
-
throw error
|
190
|
-
})
|
191
|
-
const onFinish = vi.fn(() => {
|
192
|
-
throw error1
|
193
|
-
})
|
194
|
-
|
195
|
-
try {
|
196
|
-
await hook(async (hooks) => {
|
197
|
-
hooks.onError(onError)
|
198
|
-
hooks.onError(onError)
|
199
|
-
hooks.onError(onError)
|
200
|
-
hooks.onFinish(onFinish)
|
201
|
-
hooks.onFinish(onFinish)
|
202
|
-
hooks.onFinish(onFinish)
|
203
|
-
|
204
|
-
throw error2
|
205
|
-
})
|
206
|
-
} catch (e) {
|
207
|
-
expect(e).toBe(error1)
|
208
|
-
}
|
209
|
-
|
210
|
-
expect(onError).toHaveBeenCalledTimes(3)
|
211
|
-
expect(onFinish).toHaveBeenCalledTimes(3)
|
212
|
-
})
|
213
|
-
|
214
|
-
it('can unsubscribe', async () => {
|
215
|
-
const onSuccess = vi.fn()
|
216
|
-
const onError = vi.fn()
|
217
|
-
const onFinish = vi.fn()
|
218
|
-
|
219
|
-
await hook(async (hooks) => {
|
220
|
-
hooks.onSuccess(onSuccess)()
|
221
|
-
hooks.onSuccess(onSuccess)()
|
222
|
-
hooks.onError(onError)()
|
223
|
-
hooks.onFinish(onFinish)()
|
224
|
-
|
225
|
-
return 'foo'
|
226
|
-
})
|
227
|
-
|
228
|
-
await expect(
|
229
|
-
hook(async (hooks) => {
|
230
|
-
hooks.onSuccess(onSuccess)()
|
231
|
-
hooks.onSuccess(onSuccess)()
|
232
|
-
hooks.onError(onError)()
|
233
|
-
hooks.onFinish(onFinish)()
|
234
|
-
|
235
|
-
throw new Error('foo')
|
236
|
-
}),
|
237
|
-
).rejects.toThrow('foo')
|
238
|
-
|
239
|
-
expect(onSuccess).not.toHaveBeenCalled()
|
240
|
-
expect(onError).not.toHaveBeenCalled()
|
241
|
-
expect(onFinish).not.toHaveBeenCalled()
|
242
|
-
})
|
243
|
-
})
|
package/src/utils.ts
CHANGED
@@ -1,95 +1,16 @@
|
|
1
|
-
import type { Context,
|
1
|
+
import type { Context, MergeContext } from './types'
|
2
2
|
|
3
3
|
export function mergeContext<A extends Context, B extends Context>(
|
4
4
|
a: A,
|
5
5
|
b: B,
|
6
6
|
): MergeContext<A, B> {
|
7
|
-
if (!a)
|
8
|
-
|
7
|
+
if (!a)
|
8
|
+
return b as any
|
9
|
+
if (!b)
|
10
|
+
return a as any
|
9
11
|
|
10
12
|
return {
|
11
13
|
...a,
|
12
14
|
...b,
|
13
15
|
} as any
|
14
16
|
}
|
15
|
-
|
16
|
-
export async function hook<T>(
|
17
|
-
fn: (hooks: Hooks<T>) => Promisable<T>,
|
18
|
-
): Promise<T> {
|
19
|
-
const onSuccessFns: ((output: T) => Promisable<void>)[] = []
|
20
|
-
const onErrorFns: ((error: unknown) => Promisable<void>)[] = []
|
21
|
-
const onFinishFns: ((
|
22
|
-
output: T | undefined,
|
23
|
-
error: unknown | undefined,
|
24
|
-
) => Promisable<void>)[] = []
|
25
|
-
|
26
|
-
const hooks: Hooks<T> = {
|
27
|
-
onSuccess(fn) {
|
28
|
-
onSuccessFns.unshift(fn)
|
29
|
-
|
30
|
-
return () => {
|
31
|
-
const index = onSuccessFns.indexOf(fn)
|
32
|
-
if (index !== -1) onSuccessFns.splice(index, 1)
|
33
|
-
}
|
34
|
-
},
|
35
|
-
|
36
|
-
onError(fn) {
|
37
|
-
onErrorFns.unshift(fn)
|
38
|
-
|
39
|
-
return () => {
|
40
|
-
const index = onErrorFns.indexOf(fn)
|
41
|
-
if (index !== -1) onErrorFns.splice(index, 1)
|
42
|
-
}
|
43
|
-
},
|
44
|
-
|
45
|
-
onFinish(fn) {
|
46
|
-
onFinishFns.unshift(fn)
|
47
|
-
|
48
|
-
return () => {
|
49
|
-
const index = onFinishFns.indexOf(fn)
|
50
|
-
if (index !== -1) onFinishFns.splice(index, 1)
|
51
|
-
}
|
52
|
-
},
|
53
|
-
}
|
54
|
-
|
55
|
-
let error: unknown = undefined
|
56
|
-
let output: T | undefined = undefined
|
57
|
-
|
58
|
-
try {
|
59
|
-
output = await fn(hooks)
|
60
|
-
|
61
|
-
for (const onSuccessFn of onSuccessFns) {
|
62
|
-
await onSuccessFn(output)
|
63
|
-
}
|
64
|
-
|
65
|
-
return output
|
66
|
-
} catch (e) {
|
67
|
-
error = e
|
68
|
-
|
69
|
-
for (const onErrorFn of onErrorFns) {
|
70
|
-
try {
|
71
|
-
await onErrorFn(error)
|
72
|
-
} catch (e) {
|
73
|
-
error = e
|
74
|
-
}
|
75
|
-
}
|
76
|
-
|
77
|
-
throw error
|
78
|
-
} finally {
|
79
|
-
let hasNewError = false
|
80
|
-
|
81
|
-
for (const onFinishFn of onFinishFns) {
|
82
|
-
try {
|
83
|
-
await onFinishFn(output, error)
|
84
|
-
} catch (e) {
|
85
|
-
error = e
|
86
|
-
hasNewError = true
|
87
|
-
}
|
88
|
-
}
|
89
|
-
|
90
|
-
if (hasNewError) {
|
91
|
-
// biome-ignore lint/correctness/noUnsafeFinally: this behavior is expected
|
92
|
-
throw error
|
93
|
-
}
|
94
|
-
}
|
95
|
-
}
|
package/dist/chunk-ACLC6USM.js
DELETED
@@ -1,262 +0,0 @@
|
|
1
|
-
// src/utils.ts
|
2
|
-
function mergeContext(a, b) {
|
3
|
-
if (!a) return b;
|
4
|
-
if (!b) return a;
|
5
|
-
return {
|
6
|
-
...a,
|
7
|
-
...b
|
8
|
-
};
|
9
|
-
}
|
10
|
-
async function hook(fn) {
|
11
|
-
const onSuccessFns = [];
|
12
|
-
const onErrorFns = [];
|
13
|
-
const onFinishFns = [];
|
14
|
-
const hooks = {
|
15
|
-
onSuccess(fn2) {
|
16
|
-
onSuccessFns.unshift(fn2);
|
17
|
-
return () => {
|
18
|
-
const index = onSuccessFns.indexOf(fn2);
|
19
|
-
if (index !== -1) onSuccessFns.splice(index, 1);
|
20
|
-
};
|
21
|
-
},
|
22
|
-
onError(fn2) {
|
23
|
-
onErrorFns.unshift(fn2);
|
24
|
-
return () => {
|
25
|
-
const index = onErrorFns.indexOf(fn2);
|
26
|
-
if (index !== -1) onErrorFns.splice(index, 1);
|
27
|
-
};
|
28
|
-
},
|
29
|
-
onFinish(fn2) {
|
30
|
-
onFinishFns.unshift(fn2);
|
31
|
-
return () => {
|
32
|
-
const index = onFinishFns.indexOf(fn2);
|
33
|
-
if (index !== -1) onFinishFns.splice(index, 1);
|
34
|
-
};
|
35
|
-
}
|
36
|
-
};
|
37
|
-
let error = void 0;
|
38
|
-
let output = void 0;
|
39
|
-
try {
|
40
|
-
output = await fn(hooks);
|
41
|
-
for (const onSuccessFn of onSuccessFns) {
|
42
|
-
await onSuccessFn(output);
|
43
|
-
}
|
44
|
-
return output;
|
45
|
-
} catch (e) {
|
46
|
-
error = e;
|
47
|
-
for (const onErrorFn of onErrorFns) {
|
48
|
-
try {
|
49
|
-
await onErrorFn(error);
|
50
|
-
} catch (e2) {
|
51
|
-
error = e2;
|
52
|
-
}
|
53
|
-
}
|
54
|
-
throw error;
|
55
|
-
} finally {
|
56
|
-
let hasNewError = false;
|
57
|
-
for (const onFinishFn of onFinishFns) {
|
58
|
-
try {
|
59
|
-
await onFinishFn(output, error);
|
60
|
-
} catch (e) {
|
61
|
-
error = e;
|
62
|
-
hasNewError = true;
|
63
|
-
}
|
64
|
-
}
|
65
|
-
if (hasNewError) {
|
66
|
-
throw error;
|
67
|
-
}
|
68
|
-
}
|
69
|
-
}
|
70
|
-
|
71
|
-
// src/middleware.ts
|
72
|
-
var decoratedMiddlewareSymbol = Symbol("\u{1F512}decoratedMiddleware");
|
73
|
-
function decorateMiddleware(middleware) {
|
74
|
-
if (Reflect.get(middleware, decoratedMiddlewareSymbol)) {
|
75
|
-
return middleware;
|
76
|
-
}
|
77
|
-
const concat = (concatMiddleware, mapInput2) => {
|
78
|
-
const concatMiddleware_ = mapInput2 ? decorateMiddleware(concatMiddleware).mapInput(mapInput2) : concatMiddleware;
|
79
|
-
return decorateMiddleware(async (input, context, meta, ...rest) => {
|
80
|
-
const input_ = input;
|
81
|
-
const context_ = context;
|
82
|
-
const meta_ = meta;
|
83
|
-
const m1 = await middleware(input_, context_, meta_, ...rest);
|
84
|
-
const m2 = await concatMiddleware_(
|
85
|
-
input_,
|
86
|
-
mergeContext(context_, m1?.context),
|
87
|
-
meta_,
|
88
|
-
...rest
|
89
|
-
);
|
90
|
-
return { context: mergeContext(m1?.context, m2?.context) };
|
91
|
-
});
|
92
|
-
};
|
93
|
-
const mapInput = (map) => {
|
94
|
-
return decorateMiddleware(
|
95
|
-
(input, ...rest) => middleware(map(input), ...rest)
|
96
|
-
);
|
97
|
-
};
|
98
|
-
return Object.assign(middleware, {
|
99
|
-
[decoratedMiddlewareSymbol]: true,
|
100
|
-
concat,
|
101
|
-
mapInput
|
102
|
-
});
|
103
|
-
}
|
104
|
-
|
105
|
-
// src/procedure-caller.ts
|
106
|
-
import { ORPCError } from "@orpc/shared/error";
|
107
|
-
function createProcedureCaller(options) {
|
108
|
-
const internal = options.internal ?? true;
|
109
|
-
const path = options.path ?? [];
|
110
|
-
const procedure = options.procedure;
|
111
|
-
const validate = options.validate ?? true;
|
112
|
-
const caller = async (input) => {
|
113
|
-
const handler = async (input2, context, partialMeta, middlewares) => {
|
114
|
-
if (middlewares[0]) {
|
115
|
-
const [middleware, ...rest] = middlewares;
|
116
|
-
return await hook(async (hooks) => {
|
117
|
-
const mid = await middleware(input2, context, {
|
118
|
-
...partialMeta,
|
119
|
-
...hooks
|
120
|
-
});
|
121
|
-
return await handler(
|
122
|
-
input2,
|
123
|
-
mergeContext(context, mid?.context),
|
124
|
-
partialMeta,
|
125
|
-
rest
|
126
|
-
);
|
127
|
-
});
|
128
|
-
}
|
129
|
-
return await hook(async (hooks) => {
|
130
|
-
const output = await procedure.zz$p.handler(input2, context, {
|
131
|
-
...partialMeta,
|
132
|
-
...hooks
|
133
|
-
});
|
134
|
-
const validOutput = await (async () => {
|
135
|
-
if (!validate) return output;
|
136
|
-
const schema = procedure.zz$p.contract.zz$cp.OutputSchema;
|
137
|
-
if (!schema) return output;
|
138
|
-
const result = await schema.safeParseAsync(output);
|
139
|
-
if (result.error)
|
140
|
-
throw new ORPCError({
|
141
|
-
message: "Validation output failed",
|
142
|
-
code: "INTERNAL_SERVER_ERROR",
|
143
|
-
cause: result.error
|
144
|
-
});
|
145
|
-
return result.data;
|
146
|
-
})();
|
147
|
-
return validOutput;
|
148
|
-
});
|
149
|
-
};
|
150
|
-
return await hook(async (hooks) => {
|
151
|
-
options.hooks?.(options.context, {
|
152
|
-
...hooks,
|
153
|
-
path,
|
154
|
-
procedure,
|
155
|
-
internal
|
156
|
-
});
|
157
|
-
const validInput = (() => {
|
158
|
-
if (!validate) return input;
|
159
|
-
const schema = procedure.zz$p.contract.zz$cp.InputSchema;
|
160
|
-
if (!schema) return input;
|
161
|
-
try {
|
162
|
-
return schema.parse(input);
|
163
|
-
} catch (e) {
|
164
|
-
throw new ORPCError({
|
165
|
-
message: "Validation input failed",
|
166
|
-
code: "BAD_REQUEST",
|
167
|
-
cause: e
|
168
|
-
});
|
169
|
-
}
|
170
|
-
})();
|
171
|
-
return await handler(
|
172
|
-
validInput,
|
173
|
-
options.context,
|
174
|
-
{ path, procedure, internal },
|
175
|
-
procedure.zz$p.middlewares ?? []
|
176
|
-
);
|
177
|
-
});
|
178
|
-
};
|
179
|
-
return caller;
|
180
|
-
}
|
181
|
-
|
182
|
-
// src/procedure.ts
|
183
|
-
import {
|
184
|
-
DecoratedContractProcedure,
|
185
|
-
isContractProcedure
|
186
|
-
} from "@orpc/contract";
|
187
|
-
import { OpenAPIDeserializer } from "@orpc/transformer";
|
188
|
-
var Procedure = class {
|
189
|
-
constructor(zz$p) {
|
190
|
-
this.zz$p = zz$p;
|
191
|
-
}
|
192
|
-
};
|
193
|
-
var DECORATED_PROCEDURE_SYMBOL = Symbol("DECORATED_PROCEDURE");
|
194
|
-
function decorateProcedure(procedure) {
|
195
|
-
if (DECORATED_PROCEDURE_SYMBOL in procedure) {
|
196
|
-
return procedure;
|
197
|
-
}
|
198
|
-
const serverAction = async (input) => {
|
199
|
-
const input_ = (() => {
|
200
|
-
if (!(input instanceof FormData)) return input;
|
201
|
-
const transformer = new OpenAPIDeserializer({
|
202
|
-
schema: procedure.zz$p.contract.zz$cp.InputSchema
|
203
|
-
});
|
204
|
-
return transformer.deserializeAsFormData(input);
|
205
|
-
})();
|
206
|
-
const procedureCaller = createProcedureCaller({
|
207
|
-
procedure,
|
208
|
-
context: void 0,
|
209
|
-
internal: false,
|
210
|
-
validate: true
|
211
|
-
});
|
212
|
-
return await procedureCaller(input_);
|
213
|
-
};
|
214
|
-
return Object.assign(serverAction, {
|
215
|
-
[DECORATED_PROCEDURE_SYMBOL]: true,
|
216
|
-
zz$p: procedure.zz$p,
|
217
|
-
prefix(prefix) {
|
218
|
-
return decorateProcedure({
|
219
|
-
zz$p: {
|
220
|
-
...procedure.zz$p,
|
221
|
-
contract: DecoratedContractProcedure.decorate(
|
222
|
-
procedure.zz$p.contract
|
223
|
-
).prefix(prefix)
|
224
|
-
}
|
225
|
-
});
|
226
|
-
},
|
227
|
-
route(opts) {
|
228
|
-
return decorateProcedure({
|
229
|
-
zz$p: {
|
230
|
-
...procedure.zz$p,
|
231
|
-
contract: DecoratedContractProcedure.decorate(
|
232
|
-
procedure.zz$p.contract
|
233
|
-
).route(opts)
|
234
|
-
}
|
235
|
-
});
|
236
|
-
},
|
237
|
-
use(middleware, mapInput) {
|
238
|
-
const middleware_ = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
|
239
|
-
return decorateProcedure({
|
240
|
-
zz$p: {
|
241
|
-
...procedure.zz$p,
|
242
|
-
middlewares: [middleware_, ...procedure.zz$p.middlewares ?? []]
|
243
|
-
}
|
244
|
-
});
|
245
|
-
}
|
246
|
-
});
|
247
|
-
}
|
248
|
-
function isProcedure(item) {
|
249
|
-
if (item instanceof Procedure) return true;
|
250
|
-
return (typeof item === "object" || typeof item === "function") && item !== null && "zz$p" in item && typeof item.zz$p === "object" && item.zz$p !== null && "contract" in item.zz$p && isContractProcedure(item.zz$p.contract) && "handler" in item.zz$p && typeof item.zz$p.handler === "function";
|
251
|
-
}
|
252
|
-
|
253
|
-
export {
|
254
|
-
mergeContext,
|
255
|
-
hook,
|
256
|
-
decorateMiddleware,
|
257
|
-
createProcedureCaller,
|
258
|
-
Procedure,
|
259
|
-
decorateProcedure,
|
260
|
-
isProcedure
|
261
|
-
};
|
262
|
-
//# sourceMappingURL=chunk-ACLC6USM.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/middleware.ts","../src/procedure-caller.ts","../src/procedure.ts"],"sourcesContent":["import type { Context, Hooks, MergeContext, Promisable } from './types'\n\nexport function mergeContext<A extends Context, B extends Context>(\n a: A,\n b: B,\n): MergeContext<A, B> {\n if (!a) return b as any\n if (!b) return a as any\n\n return {\n ...a,\n ...b,\n } as any\n}\n\nexport async function hook<T>(\n fn: (hooks: Hooks<T>) => Promisable<T>,\n): Promise<T> {\n const onSuccessFns: ((output: T) => Promisable<void>)[] = []\n const onErrorFns: ((error: unknown) => Promisable<void>)[] = []\n const onFinishFns: ((\n output: T | undefined,\n error: unknown | undefined,\n ) => Promisable<void>)[] = []\n\n const hooks: Hooks<T> = {\n onSuccess(fn) {\n onSuccessFns.unshift(fn)\n\n return () => {\n const index = onSuccessFns.indexOf(fn)\n if (index !== -1) onSuccessFns.splice(index, 1)\n }\n },\n\n onError(fn) {\n onErrorFns.unshift(fn)\n\n return () => {\n const index = onErrorFns.indexOf(fn)\n if (index !== -1) onErrorFns.splice(index, 1)\n }\n },\n\n onFinish(fn) {\n onFinishFns.unshift(fn)\n\n return () => {\n const index = onFinishFns.indexOf(fn)\n if (index !== -1) onFinishFns.splice(index, 1)\n }\n },\n }\n\n let error: unknown = undefined\n let output: T | undefined = undefined\n\n try {\n output = await fn(hooks)\n\n for (const onSuccessFn of onSuccessFns) {\n await onSuccessFn(output)\n }\n\n return output\n } catch (e) {\n error = e\n\n for (const onErrorFn of onErrorFns) {\n try {\n await onErrorFn(error)\n } catch (e) {\n error = e\n }\n }\n\n throw error\n } finally {\n let hasNewError = false\n\n for (const onFinishFn of onFinishFns) {\n try {\n await onFinishFn(output, error)\n } catch (e) {\n error = e\n hasNewError = true\n }\n }\n\n if (hasNewError) {\n // biome-ignore lint/correctness/noUnsafeFinally: this behavior is expected\n throw error\n }\n }\n}\n","import type { Context, MergeContext, Meta, Promisable } from './types'\nimport { mergeContext } from './utils'\n\nexport interface Middleware<\n TContext extends Context,\n TExtraContext extends Context,\n TInput,\n TOutput,\n> {\n (\n input: TInput,\n context: TContext,\n meta: Meta<TOutput>,\n ): Promisable<\n TExtraContext extends undefined ? void : { context: TExtraContext }\n >\n}\n\nexport interface MapInputMiddleware<TInput, TMappedInput> {\n (input: TInput): TMappedInput\n}\n\nexport interface DecoratedMiddleware<\n TContext extends Context,\n TExtraContext extends Context,\n TInput,\n TOutput,\n> extends Middleware<TContext, TExtraContext, TInput, TOutput> {\n concat<UExtraContext extends Context = undefined, UInput = TInput>(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n UInput & TInput,\n TOutput\n >,\n ): DecoratedMiddleware<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInput & UInput,\n TOutput\n >\n\n concat<\n UExtraContext extends Context = undefined,\n UInput = TInput,\n UMappedInput = unknown,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n UMappedInput,\n TOutput\n >,\n mapInput: MapInputMiddleware<UInput, UMappedInput>,\n ): DecoratedMiddleware<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInput & UInput,\n TOutput\n >\n\n mapInput<UInput = unknown>(\n map: MapInputMiddleware<UInput, TInput>,\n ): DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput>\n}\n\nconst decoratedMiddlewareSymbol = Symbol('🔒decoratedMiddleware')\n\nexport function decorateMiddleware<\n TContext extends Context,\n TExtraContext extends Context,\n TInput,\n TOutput,\n>(\n middleware: Middleware<TContext, TExtraContext, TInput, TOutput>,\n): DecoratedMiddleware<TContext, TExtraContext, TInput, TOutput> {\n if (Reflect.get(middleware, decoratedMiddlewareSymbol)) {\n return middleware as any\n }\n\n const concat = (\n concatMiddleware: Middleware<any, any, any, any>,\n mapInput?: MapInputMiddleware<any, any>,\n ) => {\n const concatMiddleware_ = mapInput\n ? decorateMiddleware(concatMiddleware).mapInput(mapInput)\n : concatMiddleware\n\n return decorateMiddleware(async (input, context, meta, ...rest) => {\n const input_ = input as any\n const context_ = context as any\n const meta_ = meta as any\n\n const m1 = await middleware(input_, context_, meta_, ...rest)\n const m2 = await concatMiddleware_(\n input_,\n mergeContext(context_, m1?.context),\n meta_,\n ...rest,\n )\n\n return { context: mergeContext(m1?.context, m2?.context) }\n })\n }\n\n const mapInput = <UInput = unknown>(\n map: MapInputMiddleware<UInput, TInput>,\n ): DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput> => {\n return decorateMiddleware((input, ...rest) =>\n middleware(map(input), ...rest),\n )\n }\n\n return Object.assign(middleware, {\n [decoratedMiddlewareSymbol]: true,\n concat: concat as any,\n mapInput,\n })\n}\n","import type { SchemaInput, SchemaOutput } from '@orpc/contract'\nimport { ORPCError } from '@orpc/shared/error'\nimport type { Middleware } from './middleware'\nimport type { Procedure } from './procedure'\nimport type { Context, Hooks, Meta, Promisable } from './types'\nimport { hook, mergeContext } from './utils'\n\nexport interface CreateProcedureCallerOptions<\n TProcedure extends Procedure<any, any, any, any, any>,\n TValidate extends boolean,\n> {\n procedure: TProcedure\n\n /**\n * The context used when calling the procedure.\n */\n context: TProcedure extends Procedure<infer UContext, any, any, any, any>\n ? UContext\n : never\n\n /**\n * Helpful hooks to do some logics on specific time.\n */\n hooks?: (\n context: TProcedure extends Procedure<infer UContext, any, any, any, any>\n ? UContext\n : never,\n meta: Meta<unknown>,\n ) => Promisable<void>\n\n /**\n * This is helpful for logging and analytics.\n */\n path?: string[]\n\n /**\n * This flag helpful when you want bypass some logics not necessary to internal server calls.\n *\n * @default true\n */\n internal?: boolean\n\n /**\n * Indicate whether validate input and output.\n *\n * @default true\n */\n validate?: TValidate\n}\n\nexport type ProcedureCaller<\n TProcedure extends Procedure<any, any, any, any, any>,\n TValidate extends boolean,\n> = TProcedure extends Procedure<\n any,\n any,\n infer UInputSchema,\n infer UOutputSchema,\n infer UHandlerOutput\n>\n ? (\n input: TValidate extends true\n ? SchemaInput<UInputSchema>\n : SchemaOutput<UInputSchema>,\n ) => Promise<\n TValidate extends true\n ? SchemaOutput<UOutputSchema, UHandlerOutput>\n : SchemaInput<UOutputSchema, UHandlerOutput>\n >\n : never\n\nexport function createProcedureCaller<\n TProcedure extends Procedure<any, any, any, any, any>,\n TValidate extends boolean = true,\n>(\n options: CreateProcedureCallerOptions<TProcedure, TValidate>,\n): ProcedureCaller<TProcedure, TValidate> {\n const internal = options.internal ?? true\n const path = options.path ?? []\n const procedure = options.procedure\n const validate = options.validate ?? true\n\n const caller = async (input: unknown) => {\n const handler = async (\n input: unknown,\n context: Context,\n partialMeta: Omit<Meta<unknown>, keyof Hooks<unknown>>,\n middlewares: Middleware<any, any, any, any>[],\n ): Promise<unknown> => {\n if (middlewares[0]) {\n const [middleware, ...rest] = middlewares\n\n return await hook(async (hooks) => {\n const mid = await middleware(input, context, {\n ...partialMeta,\n ...hooks,\n })\n return await handler(\n input,\n mergeContext(context, mid?.context),\n partialMeta,\n rest,\n )\n })\n }\n\n return await hook(async (hooks) => {\n const output = await procedure.zz$p.handler(input, context, {\n ...partialMeta,\n ...hooks,\n })\n\n const validOutput = await (async () => {\n if (!validate) return output\n const schema = procedure.zz$p.contract.zz$cp.OutputSchema\n if (!schema) return output\n const result = await schema.safeParseAsync(output)\n if (result.error)\n throw new ORPCError({\n message: 'Validation output failed',\n code: 'INTERNAL_SERVER_ERROR',\n cause: result.error,\n })\n return result.data\n })()\n\n return validOutput\n })\n }\n\n return await hook(async (hooks) => {\n options.hooks?.(options.context, {\n ...hooks,\n path,\n procedure,\n internal,\n })\n\n const validInput = (() => {\n if (!validate) return input\n const schema = procedure.zz$p.contract.zz$cp.InputSchema\n if (!schema) return input\n\n try {\n return schema.parse(input)\n } catch (e) {\n throw new ORPCError({\n message: 'Validation input failed',\n code: 'BAD_REQUEST',\n cause: e,\n })\n }\n })()\n\n return await handler(\n validInput,\n options.context,\n { path, procedure, internal },\n procedure.zz$p.middlewares ?? [],\n )\n })\n }\n\n return caller as ProcedureCaller<TProcedure, TValidate>\n}\n","import {\n type ContractProcedure,\n DecoratedContractProcedure,\n type HTTPPath,\n type SchemaInput,\n type SchemaOutput,\n isContractProcedure,\n} from '@orpc/contract'\nimport type { RouteOptions, Schema } from '@orpc/contract'\nimport { OpenAPIDeserializer } from '@orpc/transformer'\nimport {\n type MapInputMiddleware,\n type Middleware,\n decorateMiddleware,\n} from './middleware'\nimport { createProcedureCaller } from './procedure-caller'\nimport type { Context, MergeContext, Meta, Promisable } from './types'\n\nexport class Procedure<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n THandlerOutput extends SchemaOutput<TOutputSchema>,\n> {\n constructor(\n public zz$p: {\n middlewares?: Middleware<any, any, any, any>[]\n contract: ContractProcedure<TInputSchema, TOutputSchema>\n handler: ProcedureHandler<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n },\n ) {}\n}\n\nexport type DecoratedProcedure<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n THandlerOutput extends SchemaOutput<TOutputSchema>,\n> = Procedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n> & {\n prefix(\n prefix: HTTPPath,\n ): DecoratedProcedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n\n route(\n opts: RouteOptions,\n ): DecoratedProcedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n\n use<\n UExtraContext extends\n | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>\n | undefined = undefined,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n SchemaOutput<TInputSchema>,\n SchemaOutput<TOutputSchema, THandlerOutput>\n >,\n ): DecoratedProcedure<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n\n use<\n UExtraContext extends\n | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>\n | undefined = undefined,\n UMappedInput = unknown,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n UMappedInput,\n SchemaOutput<TOutputSchema, THandlerOutput>\n >,\n mapInput: MapInputMiddleware<\n SchemaOutput<TInputSchema, THandlerOutput>,\n UMappedInput\n >,\n ): DecoratedProcedure<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n} & (undefined extends TContext\n ? (\n input: SchemaInput<TInputSchema> | FormData,\n ) => Promise<SchemaOutput<TOutputSchema, THandlerOutput>>\n : // biome-ignore lint/complexity/noBannedTypes: {} seem has no side-effect on this case\n {})\n\nexport interface ProcedureHandler<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n TOutput extends SchemaOutput<TOutputSchema>,\n> {\n (\n input: SchemaOutput<TInputSchema>,\n context: MergeContext<TContext, TExtraContext>,\n meta: Meta<unknown>,\n ): Promisable<SchemaInput<TOutputSchema, TOutput>>\n}\n\nconst DECORATED_PROCEDURE_SYMBOL = Symbol('DECORATED_PROCEDURE')\n\nexport function decorateProcedure<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n THandlerOutput extends SchemaOutput<TOutputSchema>,\n>(\n procedure: Procedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >,\n): DecoratedProcedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n> {\n if (DECORATED_PROCEDURE_SYMBOL in procedure) {\n return procedure as any\n }\n\n const serverAction = async (input: unknown) => {\n const input_ = (() => {\n if (!(input instanceof FormData)) return input\n\n const transformer = new OpenAPIDeserializer({\n schema: procedure.zz$p.contract.zz$cp.InputSchema,\n })\n\n return transformer.deserializeAsFormData(input)\n })()\n\n const procedureCaller = createProcedureCaller({\n procedure,\n context: undefined as any,\n internal: false,\n validate: true,\n })\n\n return await procedureCaller(input_ as any)\n }\n\n return Object.assign(serverAction, {\n [DECORATED_PROCEDURE_SYMBOL]: true,\n zz$p: procedure.zz$p,\n\n prefix(prefix: HTTPPath) {\n return decorateProcedure({\n zz$p: {\n ...procedure.zz$p,\n contract: DecoratedContractProcedure.decorate(\n procedure.zz$p.contract,\n ).prefix(prefix),\n },\n })\n },\n\n route(opts: RouteOptions) {\n return decorateProcedure({\n zz$p: {\n ...procedure.zz$p,\n contract: DecoratedContractProcedure.decorate(\n procedure.zz$p.contract,\n ).route(opts),\n },\n })\n },\n\n use(\n middleware: Middleware<any, any, any, any>,\n mapInput?: MapInputMiddleware<any, any>,\n ) {\n const middleware_ = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware\n\n return decorateProcedure({\n zz$p: {\n ...procedure.zz$p,\n middlewares: [middleware_, ...(procedure.zz$p.middlewares ?? [])],\n },\n })\n },\n }) as any\n}\n\nexport type WELL_DEFINED_PROCEDURE = Procedure<\n Context,\n Context,\n Schema,\n Schema,\n unknown\n>\n\nexport function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE {\n if (item instanceof Procedure) return true\n\n return (\n (typeof item === 'object' || typeof item === 'function') &&\n item !== null &&\n 'zz$p' in item &&\n typeof item.zz$p === 'object' &&\n item.zz$p !== null &&\n 'contract' in item.zz$p &&\n isContractProcedure(item.zz$p.contract) &&\n 'handler' in item.zz$p &&\n typeof item.zz$p.handler === 'function'\n )\n}\n"],"mappings":"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","names":["fn","e","mapInput","input"]}
|