@orpc/server 0.0.0-unsafe-pr-2-20241118033608

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/dist/chunk-ACLC6USM.js +262 -0
  2. package/dist/chunk-ACLC6USM.js.map +1 -0
  3. package/dist/fetch.js +648 -0
  4. package/dist/fetch.js.map +1 -0
  5. package/dist/index.js +403 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/src/adapters/fetch.d.ts +36 -0
  8. package/dist/src/adapters/fetch.d.ts.map +1 -0
  9. package/dist/src/builder.d.ts +49 -0
  10. package/dist/src/builder.d.ts.map +1 -0
  11. package/dist/src/index.d.ts +15 -0
  12. package/dist/src/index.d.ts.map +1 -0
  13. package/dist/src/middleware.d.ts +16 -0
  14. package/dist/src/middleware.d.ts.map +1 -0
  15. package/dist/src/procedure-builder.d.ts +31 -0
  16. package/dist/src/procedure-builder.d.ts.map +1 -0
  17. package/dist/src/procedure-caller.d.ts +33 -0
  18. package/dist/src/procedure-caller.d.ts.map +1 -0
  19. package/dist/src/procedure-implementer.d.ts +19 -0
  20. package/dist/src/procedure-implementer.d.ts.map +1 -0
  21. package/dist/src/procedure.d.ts +29 -0
  22. package/dist/src/procedure.d.ts.map +1 -0
  23. package/dist/src/router-builder.d.ts +22 -0
  24. package/dist/src/router-builder.d.ts.map +1 -0
  25. package/dist/src/router-caller.d.ts +36 -0
  26. package/dist/src/router-caller.d.ts.map +1 -0
  27. package/dist/src/router-implementer.d.ts +20 -0
  28. package/dist/src/router-implementer.d.ts.map +1 -0
  29. package/dist/src/router.d.ts +14 -0
  30. package/dist/src/router.d.ts.map +1 -0
  31. package/dist/src/types.d.ts +18 -0
  32. package/dist/src/types.d.ts.map +1 -0
  33. package/dist/src/utils.d.ts +4 -0
  34. package/dist/src/utils.d.ts.map +1 -0
  35. package/dist/tsconfig.tsbuildinfo +1 -0
  36. package/package.json +57 -0
  37. package/src/adapters/fetch.test.ts +399 -0
  38. package/src/adapters/fetch.ts +228 -0
  39. package/src/builder.test.ts +362 -0
  40. package/src/builder.ts +236 -0
  41. package/src/index.ts +16 -0
  42. package/src/middleware.test.ts +279 -0
  43. package/src/middleware.ts +119 -0
  44. package/src/procedure-builder.test.ts +219 -0
  45. package/src/procedure-builder.ts +158 -0
  46. package/src/procedure-caller.test.ts +210 -0
  47. package/src/procedure-caller.ts +165 -0
  48. package/src/procedure-implementer.test.ts +215 -0
  49. package/src/procedure-implementer.ts +103 -0
  50. package/src/procedure.test.ts +312 -0
  51. package/src/procedure.ts +251 -0
  52. package/src/router-builder.test.ts +106 -0
  53. package/src/router-builder.ts +120 -0
  54. package/src/router-caller.test.ts +173 -0
  55. package/src/router-caller.ts +95 -0
  56. package/src/router-implementer.test.ts +116 -0
  57. package/src/router-implementer.ts +110 -0
  58. package/src/router.test.ts +142 -0
  59. package/src/router.ts +69 -0
  60. package/src/types.test.ts +18 -0
  61. package/src/types.ts +28 -0
  62. package/src/utils.test.ts +243 -0
  63. package/src/utils.ts +95 -0
package/src/builder.ts ADDED
@@ -0,0 +1,236 @@
1
+ import {
2
+ ContractProcedure,
3
+ type ContractRouter,
4
+ type HTTPPath,
5
+ type RouteOptions,
6
+ type Schema,
7
+ type SchemaInput,
8
+ type SchemaOutput,
9
+ isContractProcedure,
10
+ } from '@orpc/contract'
11
+ import type { IsEqual } from '@orpc/shared'
12
+ import {
13
+ type DecoratedMiddleware,
14
+ type MapInputMiddleware,
15
+ type Middleware,
16
+ decorateMiddleware,
17
+ } from './middleware'
18
+ import {
19
+ type DecoratedProcedure,
20
+ type ProcedureHandler,
21
+ decorateProcedure,
22
+ } from './procedure'
23
+ import { ProcedureBuilder } from './procedure-builder'
24
+ import { ProcedureImplementer } from './procedure-implementer'
25
+ import type { HandledRouter, Router } from './router'
26
+ import { RouterBuilder } from './router-builder'
27
+ import {
28
+ type ChainedRouterImplementer,
29
+ chainRouterImplementer,
30
+ } from './router-implementer'
31
+ import type { Context, MergeContext } from './types'
32
+
33
+ export class Builder<TContext extends Context, TExtraContext extends Context> {
34
+ constructor(
35
+ public zz$b: {
36
+ middlewares?: Middleware<any, any, any, any>[]
37
+ } = {},
38
+ ) {}
39
+
40
+ /**
41
+ * Self chainable
42
+ */
43
+
44
+ context<UContext extends Context>(): IsEqual<UContext, Context> extends true
45
+ ? Builder<TContext, TExtraContext>
46
+ : Builder<UContext, TExtraContext> {
47
+ return this as any
48
+ }
49
+
50
+ use<
51
+ UExtraContext extends
52
+ | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
53
+ | undefined = undefined,
54
+ >(
55
+ middleware: Middleware<
56
+ MergeContext<TContext, TExtraContext>,
57
+ UExtraContext,
58
+ unknown,
59
+ unknown
60
+ >,
61
+ ): Builder<TContext, MergeContext<TExtraContext, UExtraContext>>
62
+
63
+ use<
64
+ UExtraContext extends
65
+ | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
66
+ | undefined = undefined,
67
+ UMappedInput = unknown,
68
+ >(
69
+ middleware: Middleware<
70
+ MergeContext<TContext, TExtraContext>,
71
+ UExtraContext,
72
+ UMappedInput,
73
+ unknown
74
+ >,
75
+ mapInput: MapInputMiddleware<unknown, UMappedInput>,
76
+ ): Builder<TContext, MergeContext<TExtraContext, UExtraContext>>
77
+
78
+ use(
79
+ middleware: Middleware<any, any, any, any>,
80
+ mapInput?: MapInputMiddleware<any, any>,
81
+ ): Builder<any, any> {
82
+ const middleware_ = mapInput
83
+ ? decorateMiddleware(middleware).mapInput(mapInput)
84
+ : middleware
85
+
86
+ return new Builder({
87
+ ...this.zz$b,
88
+ middlewares: [...(this.zz$b.middlewares || []), middleware_],
89
+ })
90
+ }
91
+
92
+ /**
93
+ * Convert to ContractProcedureBuilder
94
+ */
95
+
96
+ route(
97
+ opts: RouteOptions,
98
+ ): ProcedureBuilder<TContext, TExtraContext, undefined, undefined> {
99
+ return new ProcedureBuilder({
100
+ middlewares: this.zz$b.middlewares,
101
+ contract: new ContractProcedure({
102
+ ...opts,
103
+ InputSchema: undefined,
104
+ OutputSchema: undefined,
105
+ }),
106
+ })
107
+ }
108
+
109
+ input<USchema extends Schema = undefined>(
110
+ schema: USchema,
111
+ example?: SchemaInput<USchema>,
112
+ ): ProcedureBuilder<TContext, TExtraContext, USchema, undefined> {
113
+ return new ProcedureBuilder({
114
+ middlewares: this.zz$b.middlewares,
115
+ contract: new ContractProcedure({
116
+ OutputSchema: undefined,
117
+ InputSchema: schema,
118
+ inputExample: example,
119
+ }),
120
+ })
121
+ }
122
+
123
+ output<USchema extends Schema = undefined>(
124
+ schema: USchema,
125
+ example?: SchemaOutput<USchema>,
126
+ ): ProcedureBuilder<TContext, TExtraContext, undefined, USchema> {
127
+ return new ProcedureBuilder({
128
+ middlewares: this.zz$b.middlewares,
129
+ contract: new ContractProcedure({
130
+ InputSchema: undefined,
131
+ OutputSchema: schema,
132
+ outputExample: example,
133
+ }),
134
+ })
135
+ }
136
+
137
+ /**
138
+ * Convert to Procedure
139
+ */
140
+ handler<UHandlerOutput = undefined>(
141
+ handler: ProcedureHandler<
142
+ TContext,
143
+ TExtraContext,
144
+ undefined,
145
+ undefined,
146
+ UHandlerOutput
147
+ >,
148
+ ): DecoratedProcedure<
149
+ TContext,
150
+ TExtraContext,
151
+ undefined,
152
+ undefined,
153
+ UHandlerOutput
154
+ > {
155
+ return decorateProcedure({
156
+ zz$p: {
157
+ middlewares: this.zz$b.middlewares,
158
+ contract: new ContractProcedure({
159
+ InputSchema: undefined,
160
+ OutputSchema: undefined,
161
+ }),
162
+ handler,
163
+ },
164
+ })
165
+ }
166
+
167
+ /**
168
+ * Convert to ProcedureImplementer | RouterBuilder
169
+ */
170
+
171
+ contract<UContract extends ContractProcedure<any, any> | ContractRouter>(
172
+ contract: UContract,
173
+ ): UContract extends ContractProcedure<
174
+ infer UInputSchema,
175
+ infer UOutputSchema
176
+ >
177
+ ? ProcedureImplementer<TContext, TExtraContext, UInputSchema, UOutputSchema>
178
+ : UContract extends ContractRouter
179
+ ? ChainedRouterImplementer<TContext, UContract, TExtraContext>
180
+ : never {
181
+ if (isContractProcedure(contract)) {
182
+ return new ProcedureImplementer({
183
+ contract,
184
+ middlewares: this.zz$b.middlewares,
185
+ }) as any
186
+ }
187
+
188
+ return chainRouterImplementer(
189
+ contract as ContractRouter,
190
+ this.zz$b.middlewares,
191
+ ) as any
192
+ }
193
+
194
+ /**
195
+ * Create ExtendedMiddleware
196
+ */
197
+
198
+ middleware<UExtraContext extends Context = undefined, TInput = unknown>(
199
+ middleware: Middleware<
200
+ MergeContext<TContext, TExtraContext>,
201
+ UExtraContext,
202
+ TInput,
203
+ unknown
204
+ >,
205
+ ): DecoratedMiddleware<
206
+ MergeContext<TContext, TExtraContext>,
207
+ UExtraContext,
208
+ TInput,
209
+ unknown
210
+ > {
211
+ return decorateMiddleware(middleware)
212
+ }
213
+
214
+ prefix(prefix: HTTPPath): RouterBuilder<TContext, TExtraContext> {
215
+ return new RouterBuilder({
216
+ ...this.zz$b,
217
+ prefix,
218
+ })
219
+ }
220
+
221
+ tags(...tags: string[]): RouterBuilder<TContext, TExtraContext> {
222
+ return new RouterBuilder({
223
+ ...this.zz$b,
224
+ tags,
225
+ })
226
+ }
227
+
228
+ /**
229
+ * Create DecoratedRouter
230
+ */
231
+ router<URouter extends Router<TContext>>(
232
+ router: URouter,
233
+ ): HandledRouter<URouter> {
234
+ return new RouterBuilder<TContext, TExtraContext>(this.zz$b).router(router)
235
+ }
236
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Builder } from './builder'
2
+
3
+ export * from './builder'
4
+ export * from '@orpc/shared/error'
5
+ export * from './middleware'
6
+ export * from './procedure'
7
+ export * from './procedure-caller'
8
+ export * from './procedure-builder'
9
+ export * from './procedure-implementer'
10
+ export * from './router'
11
+ export * from './router-caller'
12
+ export * from './router-implementer'
13
+ export * from './types'
14
+ export * from './utils'
15
+
16
+ export const os = new Builder<undefined | Record<string, unknown>, undefined>()
@@ -0,0 +1,279 @@
1
+ import {
2
+ type DecoratedMiddleware,
3
+ type Middleware,
4
+ decorateMiddleware,
5
+ } from './middleware'
6
+ import type { Meta } from './types'
7
+
8
+ describe('middleware', () => {
9
+ it('just a function', () => {
10
+ const mid: Middleware<
11
+ { auth: boolean },
12
+ { userId: string },
13
+ unknown,
14
+ unknown
15
+ > = (input, context, meta) => {
16
+ expectTypeOf(input).toEqualTypeOf<unknown>()
17
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
18
+ expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
19
+
20
+ return {
21
+ context: {
22
+ userId: '1',
23
+ },
24
+ }
25
+ }
26
+ })
27
+
28
+ it('expect required return if has extra context', () => {
29
+ const mid: Middleware<
30
+ { auth: boolean },
31
+ { userId: string },
32
+ unknown,
33
+ unknown
34
+ > = (input, context, meta) => {
35
+ expectTypeOf(input).toEqualTypeOf<unknown>()
36
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
37
+ expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
38
+
39
+ return {
40
+ context: {
41
+ userId: '1',
42
+ },
43
+ }
44
+ }
45
+
46
+ // @ts-expect-error mid is not return extra context
47
+ const mid2: Middleware<
48
+ { auth: boolean },
49
+ { userId: string },
50
+ unknown,
51
+ unknown
52
+ > = (input, context, meta) => {
53
+ expectTypeOf(input).toEqualTypeOf<unknown>()
54
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
55
+ expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
56
+ }
57
+
58
+ // @ts-expect-error mid return invalid context
59
+ const mid3: Middleware<
60
+ { auth: boolean },
61
+ { userId: string },
62
+ unknown,
63
+ unknown
64
+ > = (input, context, meta) => {
65
+ expectTypeOf(input).toEqualTypeOf<unknown>()
66
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
67
+ expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
68
+
69
+ return {
70
+ context: {
71
+ valid: false,
72
+ },
73
+ }
74
+ }
75
+ })
76
+
77
+ it('not allow return if has no extra context', () => {
78
+ const mid: Middleware<{ auth: boolean }, undefined, unknown, unknown> = (
79
+ input,
80
+ context,
81
+ meta,
82
+ ) => {
83
+ expectTypeOf(input).toEqualTypeOf<unknown>()
84
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
85
+ expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
86
+ }
87
+
88
+ // @ts-expect-error mid2 is not return extra context
89
+ const mid2: Middleware<{ auth: boolean }, undefined, unknown, unknown> = (
90
+ input,
91
+ context,
92
+ meta,
93
+ ) => {
94
+ expectTypeOf(input).toEqualTypeOf<unknown>()
95
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
96
+ expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
97
+
98
+ return {
99
+ context: {
100
+ userId: '1',
101
+ },
102
+ }
103
+ }
104
+ })
105
+ })
106
+
107
+ describe('decorateMiddleware', () => {
108
+ it('infer types', () => {
109
+ const mid = decorateMiddleware<
110
+ { auth: boolean },
111
+ { userId: string },
112
+ { id: string },
113
+ { name: string }
114
+ >((input, context, meta) => {
115
+ expectTypeOf(input).toEqualTypeOf<{ id: string }>()
116
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
117
+ expectTypeOf(meta).toEqualTypeOf<Meta<{ name: string }>>()
118
+
119
+ return {
120
+ context: {
121
+ userId: '1',
122
+ },
123
+ }
124
+ })
125
+
126
+ expectTypeOf(mid).toEqualTypeOf<
127
+ DecoratedMiddleware<
128
+ { auth: boolean },
129
+ { userId: string },
130
+ { id: string },
131
+ { name: string }
132
+ >
133
+ >()
134
+
135
+ expectTypeOf(mid).toMatchTypeOf<
136
+ Middleware<
137
+ { auth: boolean },
138
+ { userId: string },
139
+ { id: string },
140
+ { name: string }
141
+ >
142
+ >()
143
+ })
144
+
145
+ it('concat: infer types', () => {
146
+ const mid = decorateMiddleware<
147
+ { auth: boolean },
148
+ undefined,
149
+ { id: string },
150
+ { name: string }
151
+ >(() => {}).concat((input, context, meta) => {
152
+ expectTypeOf(input).toEqualTypeOf<{ id: string }>()
153
+ expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
154
+ expectTypeOf(meta).toEqualTypeOf<Meta<{ name: string }>>()
155
+
156
+ return {
157
+ context: {
158
+ userId: '1',
159
+ },
160
+ }
161
+ })
162
+
163
+ expectTypeOf(mid).toEqualTypeOf<
164
+ DecoratedMiddleware<
165
+ { auth: boolean },
166
+ { userId: string },
167
+ { id: string },
168
+ { name: string }
169
+ >
170
+ >()
171
+ })
172
+
173
+ it('concat: can expect input', () => {
174
+ const mid = decorateMiddleware<
175
+ { auth: boolean },
176
+ undefined,
177
+ unknown,
178
+ unknown
179
+ >(() => {})
180
+ .concat((input: { id: string }) => {})
181
+ .concat((input: { status: string }) => {})
182
+
183
+ expectTypeOf(mid).toEqualTypeOf<
184
+ DecoratedMiddleware<
185
+ { auth: boolean },
186
+ undefined,
187
+ { id: string } & { status: string },
188
+ unknown
189
+ >
190
+ >()
191
+
192
+ // MID2 isn't usable because input type is wrong
193
+ const mid2 = mid.concat((input: { id: number }) => {})
194
+ expectTypeOf(mid2).toMatchTypeOf<
195
+ DecoratedMiddleware<
196
+ { auth: boolean },
197
+ undefined,
198
+ { id: never; status: string },
199
+ unknown
200
+ >
201
+ >()
202
+ })
203
+
204
+ it('concat: deep copy', () => {
205
+ const middleware = decorateMiddleware(() => {})
206
+ const mid2 = middleware.concat(() => {})
207
+ expect(mid2).not.toBe(middleware)
208
+ })
209
+
210
+ it('concat: can map input', async () => {
211
+ const middleware = decorateMiddleware<
212
+ { auth: boolean },
213
+ undefined,
214
+ unknown,
215
+ unknown
216
+ >(() => {})
217
+
218
+ const mid2 = middleware.concat(
219
+ (input: { postId: number }) => {
220
+ return { context: { a: 'a' } }
221
+ },
222
+ (input) => ({ postId: 12455 }),
223
+ )
224
+
225
+ // mid2 input is unknown, because it's map input does not expect anything
226
+ expectTypeOf(mid2).toEqualTypeOf<
227
+ DecoratedMiddleware<{ auth: boolean }, { a: string }, unknown, unknown>
228
+ >()
229
+
230
+ const fn = vi.fn()
231
+ const mid3 = middleware.concat(
232
+ (input: { postId: string }) => {
233
+ fn()
234
+ expect(input).toEqual({ postId: '123' })
235
+ },
236
+ (input: { postId: number }) => {
237
+ fn()
238
+ expect(input).toEqual({ postId: 123 })
239
+ return {
240
+ postId: `${input.postId}`,
241
+ }
242
+ },
243
+ )
244
+
245
+ await mid3({ postId: 123 }, {} as any, {} as any)
246
+ expect(fn).toHaveBeenCalledTimes(2)
247
+
248
+ // INPUT now follow expect types from map not from middleware
249
+ expectTypeOf(mid3).toMatchTypeOf<
250
+ DecoratedMiddleware<
251
+ { auth: boolean },
252
+ undefined,
253
+ { postId: number },
254
+ unknown
255
+ >
256
+ >()
257
+ })
258
+
259
+ it('mapInput', async () => {
260
+ const fn = vi.fn()
261
+
262
+ const mid = decorateMiddleware<
263
+ undefined,
264
+ undefined,
265
+ { id: string },
266
+ unknown
267
+ >(fn).mapInput((input: { postId: string }) => {
268
+ return { id: input.postId }
269
+ })
270
+
271
+ expectTypeOf(mid).toEqualTypeOf<
272
+ DecoratedMiddleware<undefined, undefined, { postId: string }, unknown>
273
+ >()
274
+
275
+ await mid({ postId: '1' }, undefined, {} as any)
276
+
277
+ expect(fn).toHaveBeenCalledWith({ id: '1' }, undefined, {})
278
+ })
279
+ })
@@ -0,0 +1,119 @@
1
+ import type { Context, MergeContext, Meta, Promisable } from './types'
2
+ import { mergeContext } from './utils'
3
+
4
+ export interface Middleware<
5
+ TContext extends Context,
6
+ TExtraContext extends Context,
7
+ TInput,
8
+ TOutput,
9
+ > {
10
+ (
11
+ input: TInput,
12
+ context: TContext,
13
+ meta: Meta<TOutput>,
14
+ ): Promisable<
15
+ TExtraContext extends undefined ? void : { context: TExtraContext }
16
+ >
17
+ }
18
+
19
+ export interface MapInputMiddleware<TInput, TMappedInput> {
20
+ (input: TInput): TMappedInput
21
+ }
22
+
23
+ export interface DecoratedMiddleware<
24
+ TContext extends Context,
25
+ TExtraContext extends Context,
26
+ TInput,
27
+ TOutput,
28
+ > extends Middleware<TContext, TExtraContext, TInput, TOutput> {
29
+ concat<UExtraContext extends Context = undefined, UInput = TInput>(
30
+ middleware: Middleware<
31
+ MergeContext<TContext, TExtraContext>,
32
+ UExtraContext,
33
+ UInput & TInput,
34
+ TOutput
35
+ >,
36
+ ): DecoratedMiddleware<
37
+ TContext,
38
+ MergeContext<TExtraContext, UExtraContext>,
39
+ TInput & UInput,
40
+ TOutput
41
+ >
42
+
43
+ concat<
44
+ UExtraContext extends Context = undefined,
45
+ UInput = TInput,
46
+ UMappedInput = unknown,
47
+ >(
48
+ middleware: Middleware<
49
+ MergeContext<TContext, TExtraContext>,
50
+ UExtraContext,
51
+ UMappedInput,
52
+ TOutput
53
+ >,
54
+ mapInput: MapInputMiddleware<UInput, UMappedInput>,
55
+ ): DecoratedMiddleware<
56
+ TContext,
57
+ MergeContext<TExtraContext, UExtraContext>,
58
+ TInput & UInput,
59
+ TOutput
60
+ >
61
+
62
+ mapInput<UInput = unknown>(
63
+ map: MapInputMiddleware<UInput, TInput>,
64
+ ): DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput>
65
+ }
66
+
67
+ const decoratedMiddlewareSymbol = Symbol('🔒decoratedMiddleware')
68
+
69
+ export function decorateMiddleware<
70
+ TContext extends Context,
71
+ TExtraContext extends Context,
72
+ TInput,
73
+ TOutput,
74
+ >(
75
+ middleware: Middleware<TContext, TExtraContext, TInput, TOutput>,
76
+ ): DecoratedMiddleware<TContext, TExtraContext, TInput, TOutput> {
77
+ if (Reflect.get(middleware, decoratedMiddlewareSymbol)) {
78
+ return middleware as any
79
+ }
80
+
81
+ const concat = (
82
+ concatMiddleware: Middleware<any, any, any, any>,
83
+ mapInput?: MapInputMiddleware<any, any>,
84
+ ) => {
85
+ const concatMiddleware_ = mapInput
86
+ ? decorateMiddleware(concatMiddleware).mapInput(mapInput)
87
+ : concatMiddleware
88
+
89
+ return decorateMiddleware(async (input, context, meta, ...rest) => {
90
+ const input_ = input as any
91
+ const context_ = context as any
92
+ const meta_ = meta as any
93
+
94
+ const m1 = await middleware(input_, context_, meta_, ...rest)
95
+ const m2 = await concatMiddleware_(
96
+ input_,
97
+ mergeContext(context_, m1?.context),
98
+ meta_,
99
+ ...rest,
100
+ )
101
+
102
+ return { context: mergeContext(m1?.context, m2?.context) }
103
+ })
104
+ }
105
+
106
+ const mapInput = <UInput = unknown>(
107
+ map: MapInputMiddleware<UInput, TInput>,
108
+ ): DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput> => {
109
+ return decorateMiddleware((input, ...rest) =>
110
+ middleware(map(input), ...rest),
111
+ )
112
+ }
113
+
114
+ return Object.assign(middleware, {
115
+ [decoratedMiddlewareSymbol]: true,
116
+ concat: concat as any,
117
+ mapInput,
118
+ })
119
+ }