@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.
- package/dist/chunk-26DTFWOI.js +200 -0
- package/dist/chunk-26DTFWOI.js.map +1 -0
- package/dist/fetch.js +87 -91
- package/dist/fetch.js.map +1 -1
- package/dist/index.js +6 -9
- package/dist/index.js.map +1 -1
- package/dist/src/adapters/fetch.d.ts +9 -3
- package/dist/src/adapters/fetch.d.ts.map +1 -1
- package/dist/src/builder.d.ts +4 -4
- package/dist/src/builder.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/middleware.d.ts +17 -7
- package/dist/src/middleware.d.ts.map +1 -1
- package/dist/src/procedure-builder.d.ts +4 -4
- package/dist/src/procedure-builder.d.ts.map +1 -1
- package/dist/src/procedure-caller.d.ts +0 -5
- package/dist/src/procedure-caller.d.ts.map +1 -1
- package/dist/src/procedure-implementer.d.ts +4 -5
- package/dist/src/procedure-implementer.d.ts.map +1 -1
- package/dist/src/procedure.d.ts +8 -9
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/router-builder.d.ts +2 -2
- package/dist/src/router-builder.d.ts.map +1 -1
- package/dist/src/router-caller.d.ts +1 -6
- package/dist/src/router-caller.d.ts.map +1 -1
- package/dist/src/router-implementer.d.ts +2 -2
- package/dist/src/router-implementer.d.ts.map +1 -1
- package/dist/src/router.d.ts +1 -1
- package/dist/src/router.d.ts.map +1 -1
- package/dist/src/types.d.ts +1 -10
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils.d.ts +1 -2
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/adapters/fetch.test.ts +32 -17
- package/src/adapters/fetch.ts +134 -123
- package/src/builder.test.ts +48 -39
- package/src/builder.ts +32 -30
- package/src/index.ts +2 -2
- package/src/middleware.test.ts +54 -73
- package/src/middleware.ts +39 -22
- package/src/procedure-builder.test.ts +26 -22
- package/src/procedure-builder.ts +15 -15
- package/src/procedure-caller.test.ts +25 -70
- package/src/procedure-caller.ts +69 -88
- package/src/procedure-implementer.test.ts +27 -22
- package/src/procedure-implementer.ts +16 -17
- package/src/procedure.test.ts +17 -12
- package/src/procedure.ts +46 -45
- package/src/router-builder.test.ts +4 -4
- package/src/router-builder.ts +12 -10
- package/src/router-caller.test.ts +6 -6
- package/src/router-caller.ts +5 -16
- package/src/router-implementer.test.ts +12 -12
- package/src/router-implementer.ts +9 -6
- package/src/router.test.ts +4 -4
- package/src/router.ts +12 -10
- package/src/types.test.ts +1 -1
- package/src/types.ts +1 -15
- package/src/utils.test.ts +2 -229
- package/src/utils.ts +5 -84
- package/dist/chunk-ACLC6USM.js +0 -262
- package/dist/chunk-ACLC6USM.js.map +0 -1
package/src/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
|
-
|
53
|
-
|
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
|
-
|
66
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
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
|
-
|
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
|
-
|
205
|
+
TOutput
|
204
206
|
>,
|
205
207
|
): DecoratedMiddleware<
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
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>()
|
package/src/middleware.test.ts
CHANGED
@@ -1,9 +1,6 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
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<
|
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<
|
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
|
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<
|
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<
|
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<
|
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<
|
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
|
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
|
-
|
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 {
|
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:
|
28
|
+
meta: MiddlewareMeta<TOutput>,
|
14
29
|
): Promisable<
|
15
|
-
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
|
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
|
-
)
|
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
|
-
)
|
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
|
-
)
|
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
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
...
|
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
|
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<
|
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<
|
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
|
-
|
134
|
+
input => ({ postId: 12455 }),
|
131
135
|
)
|
132
136
|
|
133
137
|
builder.use(
|
134
|
-
(input: { postId: string }) => {},
|
135
|
-
|
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
|
-
|
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
|
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
|
204
|
+
expectTypeOf(meta).toEqualTypeOf<Meta>()
|
201
205
|
|
202
206
|
return {
|
203
207
|
name: 'unnoq',
|