@orpc/server 0.1.0 → 0.1.2

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.
Files changed (65) hide show
  1. package/dist/chunk-26DTFWOI.js +200 -0
  2. package/dist/chunk-26DTFWOI.js.map +1 -0
  3. package/dist/fetch.js +87 -91
  4. package/dist/fetch.js.map +1 -1
  5. package/dist/index.js +6 -9
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/adapters/fetch.d.ts +9 -3
  8. package/dist/src/adapters/fetch.d.ts.map +1 -1
  9. package/dist/src/builder.d.ts +4 -4
  10. package/dist/src/builder.d.ts.map +1 -1
  11. package/dist/src/index.d.ts +2 -2
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/middleware.d.ts +17 -7
  14. package/dist/src/middleware.d.ts.map +1 -1
  15. package/dist/src/procedure-builder.d.ts +4 -4
  16. package/dist/src/procedure-builder.d.ts.map +1 -1
  17. package/dist/src/procedure-caller.d.ts +0 -5
  18. package/dist/src/procedure-caller.d.ts.map +1 -1
  19. package/dist/src/procedure-implementer.d.ts +4 -5
  20. package/dist/src/procedure-implementer.d.ts.map +1 -1
  21. package/dist/src/procedure.d.ts +8 -9
  22. package/dist/src/procedure.d.ts.map +1 -1
  23. package/dist/src/router-builder.d.ts +2 -2
  24. package/dist/src/router-builder.d.ts.map +1 -1
  25. package/dist/src/router-caller.d.ts +1 -6
  26. package/dist/src/router-caller.d.ts.map +1 -1
  27. package/dist/src/router-implementer.d.ts +2 -2
  28. package/dist/src/router-implementer.d.ts.map +1 -1
  29. package/dist/src/router.d.ts +1 -1
  30. package/dist/src/router.d.ts.map +1 -1
  31. package/dist/src/types.d.ts +1 -10
  32. package/dist/src/types.d.ts.map +1 -1
  33. package/dist/src/utils.d.ts +1 -2
  34. package/dist/src/utils.d.ts.map +1 -1
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +5 -5
  37. package/src/adapters/fetch.test.ts +32 -17
  38. package/src/adapters/fetch.ts +134 -123
  39. package/src/builder.test.ts +48 -39
  40. package/src/builder.ts +32 -30
  41. package/src/index.ts +2 -2
  42. package/src/middleware.test.ts +54 -73
  43. package/src/middleware.ts +39 -22
  44. package/src/procedure-builder.test.ts +26 -22
  45. package/src/procedure-builder.ts +15 -15
  46. package/src/procedure-caller.test.ts +25 -70
  47. package/src/procedure-caller.ts +69 -88
  48. package/src/procedure-implementer.test.ts +27 -22
  49. package/src/procedure-implementer.ts +16 -17
  50. package/src/procedure.test.ts +17 -12
  51. package/src/procedure.ts +46 -45
  52. package/src/router-builder.test.ts +4 -4
  53. package/src/router-builder.ts +12 -10
  54. package/src/router-caller.test.ts +6 -6
  55. package/src/router-caller.ts +5 -16
  56. package/src/router-implementer.test.ts +12 -12
  57. package/src/router-implementer.ts +9 -6
  58. package/src/router.test.ts +4 -4
  59. package/src/router.ts +12 -10
  60. package/src/types.test.ts +1 -1
  61. package/src/types.ts +1 -15
  62. package/src/utils.test.ts +2 -229
  63. package/src/utils.ts +5 -84
  64. package/dist/chunk-ACLC6USM.js +0 -262
  65. 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<T> extends Hooks<T> {
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 { hook, mergeContext } from './utils'
1
+ import { mergeContext } from './utils'
2
2
 
3
- test('mergeContext', () => {
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, Hooks, MergeContext, Promisable } from './types'
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) return b as any
8
- if (!b) return a as any
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
- }
@@ -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"]}