@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.
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/builder.ts CHANGED
@@ -1,34 +1,34 @@
1
+ import type { IsEqual } from '@orpc/shared'
2
+ import type { HandledRouter, Router } from './router'
3
+ import type { Context, MergeContext } from './types'
1
4
  import {
2
5
  ContractProcedure,
3
6
  type ContractRouter,
4
7
  type HTTPPath,
8
+ isContractProcedure,
5
9
  type RouteOptions,
6
10
  type Schema,
7
11
  type SchemaInput,
8
12
  type SchemaOutput,
9
- isContractProcedure,
10
13
  } from '@orpc/contract'
11
- import type { IsEqual } from '@orpc/shared'
12
14
  import {
13
15
  type DecoratedMiddleware,
16
+ decorateMiddleware,
14
17
  type MapInputMiddleware,
15
18
  type Middleware,
16
- decorateMiddleware,
17
19
  } from './middleware'
18
20
  import {
19
21
  type DecoratedProcedure,
20
- type ProcedureHandler,
21
22
  decorateProcedure,
23
+ type ProcedureHandler,
22
24
  } from './procedure'
23
25
  import { ProcedureBuilder } from './procedure-builder'
24
26
  import { ProcedureImplementer } from './procedure-implementer'
25
- import type { HandledRouter, Router } from './router'
26
27
  import { RouterBuilder } from './router-builder'
27
28
  import {
28
29
  type ChainedRouterImplementer,
29
30
  chainRouterImplementer,
30
31
  } from './router-implementer'
31
- import type { Context, MergeContext } from './types'
32
32
 
33
33
  export class Builder<TContext extends Context, TExtraContext extends Context> {
34
34
  constructor(
@@ -49,8 +49,8 @@ export class Builder<TContext extends Context, TExtraContext extends Context> {
49
49
 
50
50
  use<
51
51
  UExtraContext extends
52
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
53
- | undefined = undefined,
52
+ | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
53
+ | undefined = undefined,
54
54
  >(
55
55
  middleware: Middleware<
56
56
  MergeContext<TContext, TExtraContext>,
@@ -62,8 +62,8 @@ export class Builder<TContext extends Context, TExtraContext extends Context> {
62
62
 
63
63
  use<
64
64
  UExtraContext extends
65
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
66
- | undefined = undefined,
65
+ | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
66
+ | undefined = undefined,
67
67
  UMappedInput = unknown,
68
68
  >(
69
69
  middleware: Middleware<
@@ -146,12 +146,12 @@ export class Builder<TContext extends Context, TExtraContext extends Context> {
146
146
  UHandlerOutput
147
147
  >,
148
148
  ): DecoratedProcedure<
149
- TContext,
150
- TExtraContext,
151
- undefined,
152
- undefined,
153
- UHandlerOutput
154
- > {
149
+ TContext,
150
+ TExtraContext,
151
+ undefined,
152
+ undefined,
153
+ UHandlerOutput
154
+ > {
155
155
  return decorateProcedure({
156
156
  zz$p: {
157
157
  middlewares: this.zz$b.middlewares,
@@ -171,13 +171,13 @@ export class Builder<TContext extends Context, TExtraContext extends Context> {
171
171
  contract<UContract extends ContractProcedure<any, any> | ContractRouter>(
172
172
  contract: UContract,
173
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 {
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
181
  if (isContractProcedure(contract)) {
182
182
  return new ProcedureImplementer({
183
183
  contract,
@@ -195,19 +195,21 @@ export class Builder<TContext extends Context, TExtraContext extends Context> {
195
195
  * Create ExtendedMiddleware
196
196
  */
197
197
 
198
- middleware<UExtraContext extends Context = undefined, TInput = unknown>(
198
+ // TODO: TOutput always any, infer not work at all, because TOutput used inside middleware params,
199
+ // solution (maybe): create new generic for .output() method
200
+ middleware<UExtraContext extends Context = undefined, TInput = unknown, TOutput = any>(
199
201
  middleware: Middleware<
200
202
  MergeContext<TContext, TExtraContext>,
201
203
  UExtraContext,
202
204
  TInput,
203
- unknown
205
+ TOutput
204
206
  >,
205
207
  ): DecoratedMiddleware<
206
- MergeContext<TContext, TExtraContext>,
207
- UExtraContext,
208
- TInput,
209
- unknown
210
- > {
208
+ MergeContext<TContext, TExtraContext>,
209
+ UExtraContext,
210
+ TInput,
211
+ TOutput
212
+ > {
211
213
  return decorateMiddleware(middleware)
212
214
  }
213
215
 
package/src/index.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  import { Builder } from './builder'
2
2
 
3
3
  export * from './builder'
4
- export * from '@orpc/shared/error'
5
4
  export * from './middleware'
6
5
  export * from './procedure'
7
- export * from './procedure-caller'
8
6
  export * from './procedure-builder'
7
+ export * from './procedure-caller'
9
8
  export * from './procedure-implementer'
10
9
  export * from './router'
11
10
  export * from './router-caller'
12
11
  export * from './router-implementer'
13
12
  export * from './types'
14
13
  export * from './utils'
14
+ export * from '@orpc/shared/error'
15
15
 
16
16
  export const os = new Builder<undefined | Record<string, unknown>, undefined>()
@@ -1,9 +1,6 @@
1
- import {
2
- type DecoratedMiddleware,
3
- type Middleware,
4
- decorateMiddleware,
5
- } from './middleware'
6
- import type { Meta } from './types'
1
+ import type { DecoratedMiddleware, Middleware, MiddlewareMeta } from './middleware'
2
+ import { os } from '.'
3
+ import { decorateMiddleware } from './middleware'
7
4
 
8
5
  describe('middleware', () => {
9
6
  it('just a function', () => {
@@ -15,13 +12,9 @@ describe('middleware', () => {
15
12
  > = (input, context, meta) => {
16
13
  expectTypeOf(input).toEqualTypeOf<unknown>()
17
14
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
18
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
15
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta< unknown>>()
19
16
 
20
- return {
21
- context: {
22
- userId: '1',
23
- },
24
- }
17
+ return meta.next({ context: { userId: '1' } })
25
18
  }
26
19
  })
27
20
 
@@ -34,16 +27,12 @@ describe('middleware', () => {
34
27
  > = (input, context, meta) => {
35
28
  expectTypeOf(input).toEqualTypeOf<unknown>()
36
29
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
37
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
30
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta< unknown>>()
38
31
 
39
- return {
40
- context: {
41
- userId: '1',
42
- },
43
- }
32
+ return meta.next({ context: { userId: '1' } })
44
33
  }
45
34
 
46
- // @ts-expect-error mid is not return extra context
35
+ // @ts-expect-error mid must call next
47
36
  const mid2: Middleware<
48
37
  { auth: boolean },
49
38
  { userId: string },
@@ -52,7 +41,7 @@ describe('middleware', () => {
52
41
  > = (input, context, meta) => {
53
42
  expectTypeOf(input).toEqualTypeOf<unknown>()
54
43
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
55
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
44
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta< unknown>>()
56
45
  }
57
46
 
58
47
  // @ts-expect-error mid return invalid context
@@ -64,42 +53,13 @@ describe('middleware', () => {
64
53
  > = (input, context, meta) => {
65
54
  expectTypeOf(input).toEqualTypeOf<unknown>()
66
55
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
67
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
56
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
68
57
 
69
- return {
58
+ return meta.next({
70
59
  context: {
71
60
  valid: false,
72
61
  },
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
- }
62
+ })
103
63
  }
104
64
  })
105
65
  })
@@ -114,13 +74,13 @@ describe('decorateMiddleware', () => {
114
74
  >((input, context, meta) => {
115
75
  expectTypeOf(input).toEqualTypeOf<{ id: string }>()
116
76
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
117
- expectTypeOf(meta).toEqualTypeOf<Meta<{ name: string }>>()
77
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<{ name: string }>>()
118
78
 
119
- return {
79
+ return meta.next({
120
80
  context: {
121
81
  userId: '1',
122
82
  },
123
- }
83
+ })
124
84
  })
125
85
 
126
86
  expectTypeOf(mid).toEqualTypeOf<
@@ -148,16 +108,16 @@ describe('decorateMiddleware', () => {
148
108
  undefined,
149
109
  { id: string },
150
110
  { name: string }
151
- >(() => {}).concat((input, context, meta) => {
111
+ >((_, __, meta) => meta.next({})).concat(async (input, context, meta) => {
152
112
  expectTypeOf(input).toEqualTypeOf<{ id: string }>()
153
113
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
154
- expectTypeOf(meta).toEqualTypeOf<Meta<{ name: string }>>()
114
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<{ name: string }>>()
155
115
 
156
- return {
116
+ return meta.next({
157
117
  context: {
158
118
  userId: '1',
159
119
  },
160
- }
120
+ })
161
121
  })
162
122
 
163
123
  expectTypeOf(mid).toEqualTypeOf<
@@ -176,9 +136,9 @@ describe('decorateMiddleware', () => {
176
136
  undefined,
177
137
  unknown,
178
138
  unknown
179
- >(() => {})
180
- .concat((input: { id: string }) => {})
181
- .concat((input: { status: string }) => {})
139
+ >((_, __, meta) => meta.next({}))
140
+ .concat((input: { id: string }, _, meta) => meta.next({}))
141
+ .concat((input: { status: string }, _, meta) => meta.next({}))
182
142
 
183
143
  expectTypeOf(mid).toEqualTypeOf<
184
144
  DecoratedMiddleware<
@@ -190,20 +150,20 @@ describe('decorateMiddleware', () => {
190
150
  >()
191
151
 
192
152
  // MID2 isn't usable because input type is wrong
193
- const mid2 = mid.concat((input: { id: number }) => {})
153
+ const mid2 = mid.concat((input: { id: number }, _, meta) => meta.next({}))
194
154
  expectTypeOf(mid2).toMatchTypeOf<
195
155
  DecoratedMiddleware<
196
156
  { auth: boolean },
197
157
  undefined,
198
- { id: never; status: string },
158
+ { id: never, status: string },
199
159
  unknown
200
160
  >
201
161
  >()
202
162
  })
203
163
 
204
164
  it('concat: deep copy', () => {
205
- const middleware = decorateMiddleware(() => {})
206
- const mid2 = middleware.concat(() => {})
165
+ const middleware = decorateMiddleware((_, __, meta) => meta.next({}))
166
+ const mid2 = middleware.concat((_, __, meta) => meta.next({}))
207
167
  expect(mid2).not.toBe(middleware)
208
168
  })
209
169
 
@@ -213,13 +173,11 @@ describe('decorateMiddleware', () => {
213
173
  undefined,
214
174
  unknown,
215
175
  unknown
216
- >(() => {})
176
+ >((_, __, meta) => meta.next({}))
217
177
 
218
178
  const mid2 = middleware.concat(
219
- (input: { postId: number }) => {
220
- return { context: { a: 'a' } }
221
- },
222
- (input) => ({ postId: 12455 }),
179
+ (input: { postId: number }, _, meta) => meta.next({ context: { a: 'a' } }),
180
+ input => ({ postId: 12455 }),
223
181
  )
224
182
 
225
183
  // mid2 input is unknown, because it's map input does not expect anything
@@ -229,9 +187,11 @@ describe('decorateMiddleware', () => {
229
187
 
230
188
  const fn = vi.fn()
231
189
  const mid3 = middleware.concat(
232
- (input: { postId: string }) => {
190
+ (input: { postId: string }, _, meta) => {
233
191
  fn()
234
192
  expect(input).toEqual({ postId: '123' })
193
+
194
+ return meta.next({})
235
195
  },
236
196
  (input: { postId: number }) => {
237
197
  fn()
@@ -242,7 +202,7 @@ describe('decorateMiddleware', () => {
242
202
  },
243
203
  )
244
204
 
245
- await mid3({ postId: 123 }, {} as any, {} as any)
205
+ await mid3({ postId: 123 }, {} as any, { next: () => {} } as any)
246
206
  expect(fn).toHaveBeenCalledTimes(2)
247
207
 
248
208
  // INPUT now follow expect types from map not from middleware
@@ -277,3 +237,24 @@ describe('decorateMiddleware', () => {
277
237
  expect(fn).toHaveBeenCalledWith({ id: '1' }, undefined, {})
278
238
  })
279
239
  })
240
+
241
+ it('middleware can output', async () => {
242
+ let mid2Called = false
243
+ let handlerCalled = false
244
+ const ping = os
245
+ .use((input, ctx, meta) => {
246
+ return meta.output('from middleware')
247
+ })
248
+ .use((input, ctx, meta) => {
249
+ mid2Called = true
250
+ return meta.output('from middleware 2')
251
+ })
252
+ .handler(() => {
253
+ handlerCalled = true
254
+ return 'from handler'
255
+ })
256
+
257
+ expect(await ping(undefined)).toBe('from middleware')
258
+ expect(mid2Called).toBeFalsy()
259
+ expect(handlerCalled).toBeFalsy()
260
+ })
package/src/middleware.ts CHANGED
@@ -1,6 +1,21 @@
1
- import type { Context, MergeContext, Meta, Promisable } from './types'
1
+ import type { Promisable } from '@orpc/shared'
2
+ import type { Context, MergeContext, Meta } from './types'
2
3
  import { mergeContext } from './utils'
3
4
 
5
+ export type MiddlewareResult<TExtraContext extends Context, TOutput> = Promisable<{
6
+ output: TOutput
7
+ context: TExtraContext
8
+ }>
9
+
10
+ export interface MiddlewareMeta<
11
+ TOutput,
12
+ > extends Meta {
13
+ next: <UExtraContext extends Context = undefined>(
14
+ options: UExtraContext extends undefined ? { context?: UExtraContext } : { context: UExtraContext }
15
+ ) => MiddlewareResult<UExtraContext, TOutput>
16
+ output: <UOutput>(output: UOutput) => MiddlewareResult<undefined, UOutput>
17
+ }
18
+
4
19
  export interface Middleware<
5
20
  TContext extends Context,
6
21
  TExtraContext extends Context,
@@ -10,9 +25,9 @@ export interface Middleware<
10
25
  (
11
26
  input: TInput,
12
27
  context: TContext,
13
- meta: Meta<TOutput>,
28
+ meta: MiddlewareMeta<TOutput>,
14
29
  ): Promisable<
15
- TExtraContext extends undefined ? void : { context: TExtraContext }
30
+ MiddlewareResult<TExtraContext, TOutput>
16
31
  >
17
32
  }
18
33
 
@@ -26,22 +41,23 @@ export interface DecoratedMiddleware<
26
41
  TInput,
27
42
  TOutput,
28
43
  > extends Middleware<TContext, TExtraContext, TInput, TOutput> {
29
- concat<UExtraContext extends Context = undefined, UInput = TInput>(
44
+ concat: (<
45
+ UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined,
46
+ UInput = TInput,
47
+ >(
30
48
  middleware: Middleware<
31
49
  MergeContext<TContext, TExtraContext>,
32
50
  UExtraContext,
33
51
  UInput & TInput,
34
52
  TOutput
35
53
  >,
36
- ): DecoratedMiddleware<
54
+ ) => DecoratedMiddleware<
37
55
  TContext,
38
56
  MergeContext<TExtraContext, UExtraContext>,
39
57
  TInput & UInput,
40
58
  TOutput
41
- >
42
-
43
- concat<
44
- UExtraContext extends Context = undefined,
59
+ >) & (<
60
+ UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined,
45
61
  UInput = TInput,
46
62
  UMappedInput = unknown,
47
63
  >(
@@ -52,16 +68,16 @@ export interface DecoratedMiddleware<
52
68
  TOutput
53
69
  >,
54
70
  mapInput: MapInputMiddleware<UInput, UMappedInput>,
55
- ): DecoratedMiddleware<
71
+ ) => DecoratedMiddleware<
56
72
  TContext,
57
73
  MergeContext<TExtraContext, UExtraContext>,
58
74
  TInput & UInput,
59
75
  TOutput
60
- >
76
+ >)
61
77
 
62
- mapInput<UInput = unknown>(
78
+ mapInput: <UInput = unknown>(
63
79
  map: MapInputMiddleware<UInput, TInput>,
64
- ): DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput>
80
+ ) => DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput>
65
81
  }
66
82
 
67
83
  const decoratedMiddlewareSymbol = Symbol('🔒decoratedMiddleware')
@@ -81,7 +97,7 @@ export function decorateMiddleware<
81
97
  const concat = (
82
98
  concatMiddleware: Middleware<any, any, any, any>,
83
99
  mapInput?: MapInputMiddleware<any, any>,
84
- ) => {
100
+ ): Middleware<any, any, any, any> => {
85
101
  const concatMiddleware_ = mapInput
86
102
  ? decorateMiddleware(concatMiddleware).mapInput(mapInput)
87
103
  : concatMiddleware
@@ -91,15 +107,16 @@ export function decorateMiddleware<
91
107
  const context_ = context as any
92
108
  const meta_ = meta as any
93
109
 
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
- )
110
+ const next: MiddlewareMeta<any>['next'] = async (options) => {
111
+ return concatMiddleware_(input_, mergeContext(context_, options.context), meta_, ...rest)
112
+ }
113
+
114
+ const m1 = await middleware(input_, context_, {
115
+ ...meta_,
116
+ next,
117
+ }, ...rest)
101
118
 
102
- return { context: mergeContext(m1?.context, m2?.context) }
119
+ return m1
103
120
  })
104
121
  }
105
122
 
@@ -1,9 +1,11 @@
1
+ import type { MiddlewareMeta } from './middleware'
2
+ import type { ProcedureImplementer } from './procedure-implementer'
3
+ import type { Meta } from './types'
1
4
  import { ContractProcedure } from '@orpc/contract'
2
5
  import { z } from 'zod'
6
+ import { os } from '.'
3
7
  import { type DecoratedProcedure, isProcedure } from './procedure'
4
8
  import { ProcedureBuilder } from './procedure-builder'
5
- import type { ProcedureImplementer } from './procedure-implementer'
6
- import type { Meta } from './types'
7
9
 
8
10
  const schema1 = z.object({ id: z.string() })
9
11
  const example1 = { id: '1' }
@@ -90,20 +92,22 @@ describe('use middleware', () => {
90
92
  .use((input, context, meta) => {
91
93
  expectTypeOf(input).toEqualTypeOf<unknown>()
92
94
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
93
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
95
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
94
96
 
95
- return {
97
+ return meta.next({
96
98
  context: {
97
99
  userId: '1',
98
100
  },
99
- }
101
+ })
100
102
  })
101
103
  .use((input, context, meta) => {
102
104
  expectTypeOf(input).toEqualTypeOf<unknown>()
103
105
  expectTypeOf(context).toEqualTypeOf<
104
106
  { userId: string } & { auth: boolean }
105
107
  >()
106
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
108
+ expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
109
+
110
+ return meta.next({})
107
111
  })
108
112
 
109
113
  expectTypeOf(implementer).toEqualTypeOf<
@@ -123,27 +127,27 @@ describe('use middleware', () => {
123
127
  })
124
128
 
125
129
  builder.use(
126
- (input: { postId: string }) => {
127
- return { context: { a: 'a' } }
130
+ (input: { postId: string }, _, meta) => {
131
+ return meta.next({ context: { a: 'a' } })
128
132
  },
129
133
  // @ts-expect-error mismatch input
130
- (input) => ({ postId: 12455 }),
134
+ input => ({ postId: 12455 }),
131
135
  )
132
136
 
133
137
  builder.use(
134
- (input: { postId: string }) => {},
135
- (input) => ({ postId: '12455' }),
138
+ (input: { postId: string }, context, meta) => meta.next({}),
139
+ input => ({ postId: '12455' }),
136
140
  )
137
141
 
138
142
  const implementer = builder.input(schema1).use(
139
- (input: { id: number }) => {
140
- return {
143
+ (input: { id: number }, _, meta) => {
144
+ return meta.next({
141
145
  context: {
142
146
  userId555: '1',
143
147
  },
144
- }
148
+ })
145
149
  },
146
- (input) => ({ id: Number.parseInt(input.id) }),
150
+ input => ({ id: Number.parseInt(input.id) }),
147
151
  )
148
152
 
149
153
  expectTypeOf(implementer).toEqualTypeOf<
@@ -162,7 +166,7 @@ describe('handler', () => {
162
166
  const handler = builder.handler((input, context, meta) => {
163
167
  expectTypeOf(input).toEqualTypeOf<unknown>()
164
168
  expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
165
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
169
+ expectTypeOf(meta).toEqualTypeOf<Meta>()
166
170
  })
167
171
 
168
172
  expectTypeOf(handler).toEqualTypeOf<
@@ -179,15 +183,15 @@ describe('handler', () => {
179
183
  })
180
184
 
181
185
  it('combine middlewares', () => {
182
- const mid1 = () => {
183
- return {
186
+ const mid1 = os.middleware((input, context, meta) => {
187
+ return meta.next({
184
188
  context: {
185
189
  userId: '1',
186
190
  },
187
- }
188
- }
191
+ })
192
+ })
189
193
 
190
- const mid2 = () => {}
194
+ const mid2 = os.middleware((_, __, meta) => meta.next({}))
191
195
 
192
196
  const handler = builder
193
197
  .use(mid1)
@@ -197,7 +201,7 @@ describe('handler', () => {
197
201
  expectTypeOf(context).toEqualTypeOf<
198
202
  { userId: string } & { auth: boolean }
199
203
  >()
200
- expectTypeOf(meta).toEqualTypeOf<Meta<unknown>>()
204
+ expectTypeOf(meta).toEqualTypeOf<Meta>()
201
205
 
202
206
  return {
203
207
  name: 'unnoq',