@orpc/server 0.0.0-next.b15d206 → 0.0.0-next.bc564a6

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 (100) hide show
  1. package/dist/chunk-ESTRJAOX.js +299 -0
  2. package/dist/chunk-KK4SDLC7.js +320 -0
  3. package/dist/chunk-WUOGVGWG.js +1 -0
  4. package/dist/fetch.js +12 -678
  5. package/dist/hono.js +30 -0
  6. package/dist/index.js +319 -322
  7. package/dist/next.js +36 -0
  8. package/dist/node.js +87 -0
  9. package/dist/src/adapters/fetch/index.d.ts +6 -0
  10. package/dist/src/adapters/fetch/orpc-handler.d.ts +20 -0
  11. package/dist/src/adapters/fetch/orpc-payload-codec.d.ts +16 -0
  12. package/dist/src/adapters/fetch/orpc-procedure-matcher.d.ts +12 -0
  13. package/dist/src/adapters/fetch/super-json.d.ts +12 -0
  14. package/dist/src/adapters/fetch/types.d.ts +21 -0
  15. package/dist/src/adapters/hono/index.d.ts +3 -0
  16. package/dist/src/adapters/hono/middleware.d.ts +12 -0
  17. package/dist/src/adapters/next/index.d.ts +3 -0
  18. package/dist/src/adapters/next/serve.d.ts +19 -0
  19. package/dist/src/adapters/node/index.d.ts +5 -0
  20. package/dist/src/adapters/node/orpc-handler.d.ts +12 -0
  21. package/dist/src/adapters/node/request-listener.d.ts +28 -0
  22. package/dist/src/adapters/node/types.d.ts +22 -0
  23. package/dist/src/builder-variants.d.ts +74 -0
  24. package/dist/src/builder.d.ts +47 -39
  25. package/dist/src/config.d.ts +6 -0
  26. package/dist/src/context.d.ts +9 -0
  27. package/dist/src/hidden.d.ts +8 -0
  28. package/dist/src/implementer-procedure.d.ts +30 -0
  29. package/dist/src/implementer-variants.d.ts +16 -0
  30. package/dist/src/implementer.d.ts +27 -0
  31. package/dist/src/index.d.ts +16 -10
  32. package/dist/src/lazy-utils.d.ts +6 -0
  33. package/dist/src/lazy.d.ts +22 -0
  34. package/dist/src/middleware-decorated.d.ts +10 -0
  35. package/dist/src/middleware-utils.d.ts +5 -0
  36. package/dist/src/middleware.d.ts +28 -17
  37. package/dist/src/procedure-client.d.ts +20 -0
  38. package/dist/src/procedure-decorated.d.ts +21 -0
  39. package/dist/src/procedure-utils.d.ts +17 -0
  40. package/dist/src/procedure.d.ts +25 -25
  41. package/dist/src/router-accessible-lazy.d.ts +8 -0
  42. package/dist/src/router-client.d.ts +22 -0
  43. package/dist/src/router.d.ts +25 -16
  44. package/package.json +29 -21
  45. package/dist/chunk-TDFYNRZV.js +0 -190
  46. package/dist/chunk-TDFYNRZV.js.map +0 -1
  47. package/dist/fetch.js.map +0 -1
  48. package/dist/index.js.map +0 -1
  49. package/dist/src/adapters/fetch.d.ts +0 -42
  50. package/dist/src/adapters/fetch.d.ts.map +0 -1
  51. package/dist/src/builder.d.ts.map +0 -1
  52. package/dist/src/index.d.ts.map +0 -1
  53. package/dist/src/middleware.d.ts.map +0 -1
  54. package/dist/src/procedure-builder.d.ts +0 -31
  55. package/dist/src/procedure-builder.d.ts.map +0 -1
  56. package/dist/src/procedure-caller.d.ts +0 -19
  57. package/dist/src/procedure-caller.d.ts.map +0 -1
  58. package/dist/src/procedure-implementer.d.ts +0 -18
  59. package/dist/src/procedure-implementer.d.ts.map +0 -1
  60. package/dist/src/procedure.d.ts.map +0 -1
  61. package/dist/src/router-builder.d.ts +0 -22
  62. package/dist/src/router-builder.d.ts.map +0 -1
  63. package/dist/src/router-caller.d.ts +0 -22
  64. package/dist/src/router-caller.d.ts.map +0 -1
  65. package/dist/src/router-implementer.d.ts +0 -20
  66. package/dist/src/router-implementer.d.ts.map +0 -1
  67. package/dist/src/router.d.ts.map +0 -1
  68. package/dist/src/types.d.ts +0 -8
  69. package/dist/src/types.d.ts.map +0 -1
  70. package/dist/src/utils.d.ts +0 -3
  71. package/dist/src/utils.d.ts.map +0 -1
  72. package/dist/tsconfig.tsbuildinfo +0 -1
  73. package/src/adapters/fetch.test.ts +0 -629
  74. package/src/adapters/fetch.ts +0 -290
  75. package/src/builder.test.ts +0 -371
  76. package/src/builder.ts +0 -238
  77. package/src/index.ts +0 -16
  78. package/src/middleware.test.ts +0 -260
  79. package/src/middleware.ts +0 -136
  80. package/src/procedure-builder.test.ts +0 -223
  81. package/src/procedure-builder.ts +0 -158
  82. package/src/procedure-caller.test.ts +0 -171
  83. package/src/procedure-caller.ts +0 -138
  84. package/src/procedure-implementer.test.ts +0 -220
  85. package/src/procedure-implementer.ts +0 -102
  86. package/src/procedure.test.ts +0 -317
  87. package/src/procedure.ts +0 -237
  88. package/src/router-builder.test.ts +0 -106
  89. package/src/router-builder.ts +0 -122
  90. package/src/router-caller.test.ts +0 -126
  91. package/src/router-caller.ts +0 -64
  92. package/src/router-implementer.test.ts +0 -116
  93. package/src/router-implementer.ts +0 -113
  94. package/src/router.test-d.ts +0 -48
  95. package/src/router.test.ts +0 -142
  96. package/src/router.ts +0 -91
  97. package/src/types.test.ts +0 -18
  98. package/src/types.ts +0 -13
  99. package/src/utils.test.ts +0 -16
  100. package/src/utils.ts +0 -16
@@ -1,223 +0,0 @@
1
- import type { MiddlewareMeta } from './middleware'
2
- import type { ProcedureImplementer } from './procedure-implementer'
3
- import type { Meta } from './types'
4
- import { ContractProcedure } from '@orpc/contract'
5
- import { z } from 'zod'
6
- import { os } from '.'
7
- import { type DecoratedProcedure, isProcedure } from './procedure'
8
- import { ProcedureBuilder } from './procedure-builder'
9
-
10
- const schema1 = z.object({ id: z.string() })
11
- const example1 = { id: '1' }
12
- const schema2 = z.object({ name: z.string() })
13
- const example2 = { name: 'unnoq' }
14
-
15
- const builder = new ProcedureBuilder<
16
- { auth: boolean },
17
- undefined,
18
- undefined,
19
- undefined
20
- >({
21
- contract: new ContractProcedure({
22
- InputSchema: undefined,
23
- OutputSchema: undefined,
24
- }),
25
- })
26
-
27
- it('input', () => {
28
- const builder2 = builder.input(schema1, example1)
29
-
30
- expectTypeOf(builder2).toEqualTypeOf<
31
- ProcedureBuilder<{ auth: boolean }, undefined, typeof schema1, undefined>
32
- >()
33
-
34
- expect(builder2.zz$pb).toMatchObject({
35
- contract: {
36
- zz$cp: {
37
- InputSchema: schema1,
38
- inputExample: example1,
39
- },
40
- },
41
- })
42
- })
43
-
44
- it('output', () => {
45
- const builder2 = builder.output(schema2, example2)
46
-
47
- expectTypeOf(builder2).toEqualTypeOf<
48
- ProcedureBuilder<{ auth: boolean }, undefined, undefined, typeof schema2>
49
- >()
50
-
51
- expect(builder2.zz$pb).toMatchObject({
52
- contract: {
53
- zz$cp: {
54
- OutputSchema: schema2,
55
- outputExample: example2,
56
- },
57
- },
58
- })
59
- })
60
-
61
- it('route', () => {
62
- const builder2 = builder.route({
63
- method: 'GET',
64
- path: '/test',
65
- deprecated: true,
66
- description: 'des',
67
- summary: 'sum',
68
- tags: ['hi'],
69
- })
70
-
71
- expectTypeOf(builder2).toEqualTypeOf<
72
- ProcedureBuilder<{ auth: boolean }, undefined, undefined, undefined>
73
- >()
74
-
75
- expect(builder2.zz$pb).toMatchObject({
76
- contract: {
77
- zz$cp: {
78
- method: 'GET',
79
- path: '/test',
80
- deprecated: true,
81
- description: 'des',
82
- summary: 'sum',
83
- tags: ['hi'],
84
- },
85
- },
86
- })
87
- })
88
-
89
- describe('use middleware', () => {
90
- it('infer types', () => {
91
- const implementer = builder
92
- .use((input, context, meta) => {
93
- expectTypeOf(input).toEqualTypeOf<unknown>()
94
- expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
95
- expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
96
-
97
- return meta.next({
98
- context: {
99
- userId: '1',
100
- },
101
- })
102
- })
103
- .use((input, context, meta) => {
104
- expectTypeOf(input).toEqualTypeOf<unknown>()
105
- expectTypeOf(context).toEqualTypeOf<
106
- { userId: string } & { auth: boolean }
107
- >()
108
- expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
109
-
110
- return meta.next({})
111
- })
112
-
113
- expectTypeOf(implementer).toEqualTypeOf<
114
- ProcedureImplementer<
115
- { auth: boolean },
116
- { userId: string },
117
- undefined,
118
- undefined
119
- >
120
- >()
121
- })
122
-
123
- it('map middleware input', () => {
124
- // @ts-expect-error mismatch input
125
- builder.use((input: { postId: string }) => {
126
- return { context: { a: 'a' } }
127
- })
128
-
129
- builder.use(
130
- (input: { postId: string }, _, meta) => {
131
- return meta.next({ context: { a: 'a' } })
132
- },
133
- // @ts-expect-error mismatch input
134
- input => ({ postId: 12455 }),
135
- )
136
-
137
- builder.use(
138
- (input: { postId: string }, context, meta) => meta.next({}),
139
- input => ({ postId: '12455' }),
140
- )
141
-
142
- const implementer = builder.input(schema1).use(
143
- (input: { id: number }, _, meta) => {
144
- return meta.next({
145
- context: {
146
- userId555: '1',
147
- },
148
- })
149
- },
150
- input => ({ id: Number.parseInt(input.id) }),
151
- )
152
-
153
- expectTypeOf(implementer).toEqualTypeOf<
154
- ProcedureImplementer<
155
- { auth: boolean },
156
- { userId555: string },
157
- typeof schema1,
158
- undefined
159
- >
160
- >()
161
- })
162
- })
163
-
164
- describe('handler', () => {
165
- it('infer types', () => {
166
- const handler = builder.func((input, context, meta) => {
167
- expectTypeOf(input).toEqualTypeOf<unknown>()
168
- expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
169
- expectTypeOf(meta).toEqualTypeOf<Meta>()
170
- })
171
-
172
- expectTypeOf(handler).toEqualTypeOf<
173
- DecoratedProcedure<
174
- { auth: boolean },
175
- undefined,
176
- undefined,
177
- undefined,
178
- void
179
- >
180
- >()
181
-
182
- expect(isProcedure(handler)).toBe(true)
183
- })
184
-
185
- it('combine middlewares', () => {
186
- const mid1 = os.middleware((input, context, meta) => {
187
- return meta.next({
188
- context: {
189
- userId: '1',
190
- },
191
- })
192
- })
193
-
194
- const mid2 = os.middleware((_, __, meta) => meta.next({}))
195
-
196
- const handler = builder
197
- .use(mid1)
198
- .use(mid2)
199
- .func((input, context, meta) => {
200
- expectTypeOf(input).toEqualTypeOf<unknown>()
201
- expectTypeOf(context).toEqualTypeOf<
202
- { userId: string } & { auth: boolean }
203
- >()
204
- expectTypeOf(meta).toEqualTypeOf<Meta>()
205
-
206
- return {
207
- name: 'unnoq',
208
- }
209
- })
210
-
211
- expectTypeOf(handler).toEqualTypeOf<
212
- DecoratedProcedure<
213
- { auth: boolean },
214
- { userId: string },
215
- undefined,
216
- undefined,
217
- { name: string }
218
- >
219
- >()
220
-
221
- expect(handler.zz$p.middlewares).toEqual([mid1, mid2])
222
- })
223
- })
@@ -1,158 +0,0 @@
1
- import type { MapInputMiddleware, Middleware } from './middleware'
2
- import type { Context, MergeContext } from './types'
3
- import {
4
- type ContractProcedure,
5
- DecoratedContractProcedure,
6
- type RouteOptions,
7
- type Schema,
8
- type SchemaInput,
9
- type SchemaOutput,
10
- } from '@orpc/contract'
11
- import {
12
- type DecoratedProcedure,
13
- decorateProcedure,
14
- type ProcedureFunc,
15
- } from './procedure'
16
- import { ProcedureImplementer } from './procedure-implementer'
17
-
18
- export class ProcedureBuilder<
19
- TContext extends Context,
20
- TExtraContext extends Context,
21
- TInputSchema extends Schema,
22
- TOutputSchema extends Schema,
23
- > {
24
- constructor(
25
- public zz$pb: {
26
- contract: ContractProcedure<TInputSchema, TOutputSchema>
27
- middlewares?: Middleware<any, any, any, any>[]
28
- },
29
- ) {}
30
-
31
- /**
32
- * Self chainable
33
- */
34
-
35
- route(
36
- opts: RouteOptions,
37
- ): ProcedureBuilder<TContext, TExtraContext, TInputSchema, TOutputSchema> {
38
- return new ProcedureBuilder({
39
- ...this.zz$pb,
40
- contract: DecoratedContractProcedure.decorate(this.zz$pb.contract).route(
41
- opts,
42
- ),
43
- })
44
- }
45
-
46
- input<USchema extends Schema = undefined>(
47
- schema: USchema,
48
- example?: SchemaInput<USchema>,
49
- ): ProcedureBuilder<TContext, TExtraContext, USchema, TOutputSchema> {
50
- return new ProcedureBuilder({
51
- ...this.zz$pb,
52
- contract: DecoratedContractProcedure.decorate(this.zz$pb.contract).input(
53
- schema,
54
- example,
55
- ),
56
- })
57
- }
58
-
59
- output<USchema extends Schema = undefined>(
60
- schema: USchema,
61
- example?: SchemaOutput<USchema>,
62
- ): ProcedureBuilder<TContext, TExtraContext, TInputSchema, USchema> {
63
- return new ProcedureBuilder({
64
- ...this.zz$pb,
65
- contract: DecoratedContractProcedure.decorate(this.zz$pb.contract).output(
66
- schema,
67
- example,
68
- ),
69
- })
70
- }
71
-
72
- /**
73
- * Convert to ProcedureBuilder
74
- */
75
-
76
- use<
77
- UExtraContext extends
78
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
79
- | undefined = undefined,
80
- >(
81
- middleware: Middleware<
82
- MergeContext<TContext, TExtraContext>,
83
- UExtraContext,
84
- SchemaOutput<TInputSchema>,
85
- SchemaInput<TOutputSchema>
86
- >,
87
- ): ProcedureImplementer<
88
- TContext,
89
- MergeContext<TExtraContext, UExtraContext>,
90
- TInputSchema,
91
- TOutputSchema
92
- >
93
-
94
- use<
95
- UExtraContext extends
96
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
97
- | undefined = undefined,
98
- UMappedInput = unknown,
99
- >(
100
- middleware: Middleware<
101
- MergeContext<TContext, TExtraContext>,
102
- UExtraContext,
103
- UMappedInput,
104
- SchemaInput<TOutputSchema>
105
- >,
106
- mapInput: MapInputMiddleware<SchemaOutput<TInputSchema>, UMappedInput>,
107
- ): ProcedureImplementer<
108
- TContext,
109
- MergeContext<TExtraContext, UExtraContext>,
110
- TInputSchema,
111
- TOutputSchema
112
- >
113
-
114
- use(
115
- middleware: Middleware<any, any, any, any>,
116
- mapInput?: MapInputMiddleware<any, any>,
117
- ): ProcedureImplementer<any, any, any, any> {
118
- if (!mapInput) {
119
- return new ProcedureImplementer({
120
- contract: this.zz$pb.contract,
121
- middlewares: this.zz$pb.middlewares,
122
- }).use(middleware)
123
- }
124
-
125
- return new ProcedureImplementer({
126
- contract: this.zz$pb.contract,
127
- middlewares: this.zz$pb.middlewares,
128
- }).use(middleware, mapInput)
129
- }
130
-
131
- /**
132
- * Convert to Procedure
133
- */
134
-
135
- func<UFuncOutput extends SchemaOutput<TOutputSchema>>(
136
- func: ProcedureFunc<
137
- TContext,
138
- TExtraContext,
139
- TInputSchema,
140
- TOutputSchema,
141
- UFuncOutput
142
- >,
143
- ): DecoratedProcedure<
144
- TContext,
145
- TExtraContext,
146
- TInputSchema,
147
- TOutputSchema,
148
- UFuncOutput
149
- > {
150
- return decorateProcedure({
151
- zz$p: {
152
- middlewares: this.zz$pb.middlewares,
153
- contract: this.zz$pb.contract,
154
- func,
155
- },
156
- })
157
- }
158
- }
@@ -1,171 +0,0 @@
1
- import { z } from 'zod'
2
- import { createProcedureCaller, os } from '.'
3
-
4
- describe('createProcedureCaller', () => {
5
- const path = ['ping']
6
- const context = { auth: true }
7
-
8
- const osw = os.context<{ auth?: boolean }>()
9
- const procedure = osw
10
- .input(z.object({ value: z.string().transform(v => Number(v)) }))
11
- .output(z.object({ value: z.number().transform(v => v.toString()) }))
12
- .func((input, context, meta) => {
13
- expect(context).toEqual(context)
14
- expect(meta.path).toBe(path)
15
-
16
- return input
17
- })
18
-
19
- it('infer context', () => {
20
- createProcedureCaller({
21
- procedure,
22
- // @ts-expect-error invalid context
23
- context: { auth: 123 },
24
- })
25
-
26
- createProcedureCaller({
27
- procedure,
28
- context,
29
- })
30
- })
31
-
32
- it('with validate', async () => {
33
- const caller = createProcedureCaller({
34
- procedure,
35
- context: async () => context,
36
- path,
37
- })
38
-
39
- expectTypeOf(caller).toMatchTypeOf<
40
- (input: { value: string }) => Promise<{
41
- value: string
42
- }>
43
- >()
44
-
45
- expect(await caller({ value: '123' })).toEqual({ value: '123' })
46
-
47
- // @ts-expect-error - invalid input
48
- expect(caller({ value: {} })).rejects.toThrowError(
49
- 'Validation input failed',
50
- )
51
- })
52
-
53
- it('without validate and schema', () => {
54
- const procedure = osw.func(() => {
55
- return { value: true }
56
- })
57
-
58
- const caller = createProcedureCaller({
59
- procedure,
60
- context,
61
- })
62
-
63
- expectTypeOf(caller).toMatchTypeOf<
64
- (value: unknown) => Promise<{ value: boolean }>
65
- >()
66
-
67
- expect(caller({ value: 123 })).resolves.toEqual({ value: true })
68
- })
69
-
70
- it('middlewares', () => {
71
- const ref = { value: 0 }
72
-
73
- const mid1 = vi.fn(
74
- osw.middleware(async (input: { id: string }, context, meta) => {
75
- expect(input).toEqual({ id: '1' })
76
-
77
- expect(ref.value).toBe(0)
78
- ref.value++
79
-
80
- try {
81
- const result = await meta.next({
82
- context: {
83
- userId: '1',
84
- },
85
- })
86
- expect(ref.value).toBe(5)
87
- ref.value++
88
- return result
89
- }
90
- finally {
91
- expect(ref.value).toBe(6)
92
- ref.value++
93
- }
94
- }),
95
- )
96
-
97
- const mid2 = vi.fn(
98
- osw.middleware(async (input, context, meta) => {
99
- expect(ref.value).toBe(1)
100
- ref.value++
101
-
102
- try {
103
- const result = await meta.next({})
104
- expect(ref.value).toBe(3)
105
- ref.value++
106
- return result
107
- }
108
- finally {
109
- expect(ref.value).toBe(4)
110
- ref.value++
111
- }
112
- }),
113
- )
114
-
115
- const ping = osw
116
- .input(z.object({ id: z.string() }))
117
- .use(mid1)
118
- .use(mid2)
119
- .func((input, context, meta) => {
120
- expect(context).toEqual({ userId: '1', auth: false })
121
-
122
- expect(ref.value).toBe(2)
123
- ref.value++
124
-
125
- return 'pong'
126
- })
127
-
128
- const caller = createProcedureCaller({
129
- procedure: ping,
130
- context: { auth: false },
131
- })
132
-
133
- expect(caller({ id: '1' })).resolves.toEqual('pong')
134
- })
135
-
136
- it('accept form data', async () => {
137
- const ping = osw
138
- .input(z.object({ id: z.number() }))
139
- .output(z.object({ id: z.number() }))
140
- .func((input, context, meta) => {
141
- expect(context).toEqual(context)
142
-
143
- return input
144
- })
145
-
146
- const caller = createProcedureCaller({
147
- procedure: ping,
148
- context,
149
- })
150
-
151
- const form = new FormData()
152
- form.append('id', '1')
153
-
154
- expect(await caller(form)).toEqual({ id: 1 })
155
- })
156
-
157
- it('optional input when possible', async () => {
158
- os.func(() => { })()
159
- os.func(() => { })({})
160
- // @ts-expect-error input is required
161
- expect(os.input(z.string()).func(() => { })()).rejects.toThrow()
162
- os.input(z.string().optional()).func(() => { })()
163
- // @ts-expect-error input is required
164
- expect(os.input(z.object({})).func(() => { })()).rejects.toThrow()
165
- os.input(z.object({}).optional()).func(() => { })()
166
- os.input(z.unknown()).func(() => { })()
167
- os.input(z.any()).func(() => { })()
168
- // @ts-expect-error input is required
169
- expect(os.input(z.boolean()).func(() => { })()).rejects.toThrow()
170
- })
171
- })
@@ -1,138 +0,0 @@
1
- import type { SchemaInput, SchemaOutput } from '@orpc/contract'
2
- import type { MiddlewareMeta } from './middleware'
3
- import type { Procedure } from './procedure'
4
- import type { Context } from './types'
5
- import { type Value, value } from '@orpc/shared'
6
- import { ORPCError } from '@orpc/shared/error'
7
- import { OpenAPIDeserializer } from '@orpc/transformer'
8
- import { mergeContext } from './utils'
9
-
10
- export interface CreateProcedureCallerOptions<
11
- TProcedure extends Procedure<any, any, any, any, any>,
12
- > {
13
- procedure: TProcedure
14
-
15
- /**
16
- * The context used when calling the procedure.
17
- */
18
- context: Value<
19
- TProcedure extends Procedure<infer UContext, any, any, any, any>
20
- ? UContext
21
- : never
22
- >
23
-
24
- /**
25
- * This is helpful for logging and analytics.
26
- *
27
- * @internal
28
- */
29
- path?: string[]
30
- }
31
-
32
- export type ProcedureCaller<
33
- TProcedure extends Procedure<any, any, any, any, any>,
34
- > = TProcedure extends Procedure<
35
- any,
36
- any,
37
- infer UInputSchema,
38
- infer UOutputSchema,
39
- infer UFuncOutput
40
- >
41
- ? (
42
- ...input: [input: SchemaInput<UInputSchema> | FormData] | (undefined extends SchemaInput<UInputSchema> ? [] : never)
43
- ) => Promise<
44
- SchemaOutput<UOutputSchema, UFuncOutput>
45
- >
46
- : never
47
-
48
- export function createProcedureCaller<
49
- TProcedure extends Procedure<any, any, any, any, any>,
50
- >(
51
- options: CreateProcedureCallerOptions<TProcedure>,
52
- ): ProcedureCaller<TProcedure> {
53
- const path = options.path ?? []
54
- const procedure = options.procedure
55
-
56
- const caller = async (input: unknown): Promise<unknown> => {
57
- const input_ = (() => {
58
- if (!(input instanceof FormData)) {
59
- return input
60
- }
61
-
62
- const transformer = new OpenAPIDeserializer({
63
- schema: procedure.zz$p.contract.zz$cp.InputSchema,
64
- })
65
-
66
- return transformer.deserializeAsFormData(input)
67
- })()
68
-
69
- const validInput = (() => {
70
- const schema = procedure.zz$p.contract.zz$cp.InputSchema
71
- if (!schema) {
72
- return input_
73
- }
74
-
75
- try {
76
- return schema.parse(input_)
77
- }
78
- catch (e) {
79
- throw new ORPCError({
80
- message: 'Validation input failed',
81
- code: 'BAD_REQUEST',
82
- cause: e,
83
- })
84
- }
85
- })()
86
-
87
- const middlewares = procedure.zz$p.middlewares ?? []
88
- let currentMidIndex = 0
89
- let currentContext: Context = await value(options.context)
90
-
91
- const next: MiddlewareMeta<unknown>['next'] = async (nextOptions) => {
92
- const mid = middlewares[currentMidIndex]
93
- currentMidIndex += 1
94
- currentContext = mergeContext(currentContext, nextOptions.context)
95
-
96
- if (mid) {
97
- return await mid(validInput, currentContext, {
98
- path,
99
- procedure,
100
- next,
101
- output: output => ({ output, context: undefined }),
102
- })
103
- }
104
- else {
105
- return {
106
- output: await await procedure.zz$p.func(validInput, currentContext, {
107
- path,
108
- procedure,
109
- }),
110
- context: currentContext,
111
- }
112
- }
113
- }
114
-
115
- const output = (await next({})).output
116
-
117
- const validOutput = await (async () => {
118
- const schema = procedure.zz$p.contract.zz$cp.OutputSchema
119
- if (!schema) {
120
- return output
121
- }
122
-
123
- const result = await schema.safeParseAsync(output)
124
- if (result.error) {
125
- throw new ORPCError({
126
- message: 'Validation output failed',
127
- code: 'INTERNAL_SERVER_ERROR',
128
- cause: result.error,
129
- })
130
- }
131
- return result.data
132
- })()
133
-
134
- return validOutput
135
- }
136
-
137
- return caller as ProcedureCaller<TProcedure>
138
- }