@orpc/server 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/procedure.test.ts
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
import type { MiddlewareMeta } from '.'
|
1
2
|
import { ContractProcedure, DecoratedContractProcedure } from '@orpc/contract'
|
2
3
|
import { z } from 'zod'
|
3
|
-
import { os
|
4
|
+
import { os } from '.'
|
4
5
|
import {
|
5
6
|
type DecoratedProcedure,
|
6
|
-
Procedure,
|
7
7
|
decorateProcedure,
|
8
8
|
isProcedure,
|
9
|
+
Procedure,
|
9
10
|
} from './procedure'
|
10
11
|
|
11
12
|
it('isProcedure', () => {
|
@@ -98,7 +99,7 @@ describe('route method', () => {
|
|
98
99
|
})
|
99
100
|
|
100
101
|
it('works with middleware', () => {
|
101
|
-
const mid =
|
102
|
+
const mid = os.middleware((_, __, meta) => meta.next({ context: { userId: '1' } }))
|
102
103
|
|
103
104
|
const p = os
|
104
105
|
.context<{ auth: boolean }>()
|
@@ -155,7 +156,7 @@ describe('route method', () => {
|
|
155
156
|
})
|
156
157
|
})
|
157
158
|
|
158
|
-
|
159
|
+
it('prefix method', () => {
|
159
160
|
const p = os.context<{ auth: boolean }>().handler(() => {
|
160
161
|
return 'unnoq'
|
161
162
|
})
|
@@ -179,8 +180,8 @@ describe('use middleware', () => {
|
|
179
180
|
it('infer types', () => {
|
180
181
|
const p1 = os
|
181
182
|
.context<{ auth: boolean }>()
|
182
|
-
.use(() => {
|
183
|
-
return { context: { postId: 'string' } }
|
183
|
+
.use((_, __, meta) => {
|
184
|
+
return meta.next({ context: { postId: 'string' } })
|
184
185
|
})
|
185
186
|
.handler(() => {
|
186
187
|
return 'unnoq'
|
@@ -192,20 +193,22 @@ describe('use middleware', () => {
|
|
192
193
|
expectTypeOf(context).toEqualTypeOf<
|
193
194
|
{ auth: boolean } & { postId: string }
|
194
195
|
>()
|
195
|
-
expectTypeOf(meta).toEqualTypeOf<
|
196
|
+
expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<string>>()
|
196
197
|
|
197
|
-
return {
|
198
|
+
return meta.next({
|
198
199
|
context: {
|
199
200
|
userId: '1',
|
200
201
|
},
|
201
|
-
}
|
202
|
+
})
|
202
203
|
})
|
203
204
|
.use((input, context, meta) => {
|
204
205
|
expectTypeOf(input).toEqualTypeOf<unknown>()
|
205
206
|
expectTypeOf(context).toEqualTypeOf<
|
206
207
|
{ userId: string } & { postId: string } & { auth: boolean }
|
207
208
|
>()
|
208
|
-
expectTypeOf(meta).toEqualTypeOf<
|
209
|
+
expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<string>>()
|
210
|
+
|
211
|
+
return meta.next({})
|
209
212
|
})
|
210
213
|
|
211
214
|
expectTypeOf(p2).toEqualTypeOf<
|
@@ -220,7 +223,9 @@ describe('use middleware', () => {
|
|
220
223
|
})
|
221
224
|
|
222
225
|
it('can map input', () => {
|
223
|
-
const mid = (input: { id: number }) => {
|
226
|
+
const mid = os.middleware((input: { id: number }, __, meta) => {
|
227
|
+
return meta.next({})
|
228
|
+
})
|
224
229
|
|
225
230
|
os.input(z.object({ postId: z.number() })).use(mid, (input) => {
|
226
231
|
expectTypeOf(input).toEqualTypeOf<{ postId: number }>()
|
@@ -298,7 +303,7 @@ describe('server action', () => {
|
|
298
303
|
it('can deserialize form data', async () => {
|
299
304
|
const p = os
|
300
305
|
.input(z.object({ id: z.number(), nested: z.object({ date: z.date() }) }))
|
301
|
-
.handler(async
|
306
|
+
.handler(async input => input)
|
302
307
|
|
303
308
|
const form = new FormData()
|
304
309
|
form.append('id', '123')
|
package/src/procedure.ts
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
+
import type { Promisable } from '@orpc/shared'
|
2
|
+
import type { Context, MergeContext, Meta } from './types'
|
1
3
|
import {
|
2
4
|
type ContractProcedure,
|
3
5
|
DecoratedContractProcedure,
|
4
6
|
type HTTPPath,
|
7
|
+
isContractProcedure,
|
8
|
+
type RouteOptions,
|
9
|
+
type Schema,
|
5
10
|
type SchemaInput,
|
6
11
|
type SchemaOutput,
|
7
|
-
isContractProcedure,
|
8
12
|
} from '@orpc/contract'
|
9
|
-
import type { RouteOptions, Schema } from '@orpc/contract'
|
10
13
|
import { OpenAPIDeserializer } from '@orpc/transformer'
|
11
14
|
import {
|
15
|
+
decorateMiddleware,
|
12
16
|
type MapInputMiddleware,
|
13
17
|
type Middleware,
|
14
|
-
decorateMiddleware,
|
15
18
|
} from './middleware'
|
16
19
|
import { createProcedureCaller } from './procedure-caller'
|
17
|
-
import type { Context, MergeContext, Meta, Promisable } from './types'
|
18
20
|
|
19
21
|
export class Procedure<
|
20
22
|
TContext extends Context,
|
@@ -51,9 +53,9 @@ export type DecoratedProcedure<
|
|
51
53
|
TOutputSchema,
|
52
54
|
THandlerOutput
|
53
55
|
> & {
|
54
|
-
prefix(
|
56
|
+
prefix: (
|
55
57
|
prefix: HTTPPath,
|
56
|
-
)
|
58
|
+
) => DecoratedProcedure<
|
57
59
|
TContext,
|
58
60
|
TExtraContext,
|
59
61
|
TInputSchema,
|
@@ -61,9 +63,9 @@ export type DecoratedProcedure<
|
|
61
63
|
THandlerOutput
|
62
64
|
>
|
63
65
|
|
64
|
-
route(
|
66
|
+
route: (
|
65
67
|
opts: RouteOptions,
|
66
|
-
)
|
68
|
+
) => DecoratedProcedure<
|
67
69
|
TContext,
|
68
70
|
TExtraContext,
|
69
71
|
TInputSchema,
|
@@ -71,54 +73,51 @@ export type DecoratedProcedure<
|
|
71
73
|
THandlerOutput
|
72
74
|
>
|
73
75
|
|
74
|
-
use<
|
76
|
+
use: (<
|
75
77
|
UExtraContext extends
|
76
|
-
|
77
|
-
|
78
|
+
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
79
|
+
| undefined = undefined,
|
78
80
|
>(
|
79
81
|
middleware: Middleware<
|
80
82
|
MergeContext<TContext, TExtraContext>,
|
81
83
|
UExtraContext,
|
82
84
|
SchemaOutput<TInputSchema>,
|
83
|
-
|
85
|
+
SchemaInput<TOutputSchema, THandlerOutput>
|
84
86
|
>,
|
85
|
-
)
|
87
|
+
) => DecoratedProcedure<
|
86
88
|
TContext,
|
87
89
|
MergeContext<TExtraContext, UExtraContext>,
|
88
90
|
TInputSchema,
|
89
91
|
TOutputSchema,
|
90
92
|
THandlerOutput
|
91
|
-
>
|
92
|
-
|
93
|
-
use<
|
93
|
+
>) & (<
|
94
94
|
UExtraContext extends
|
95
|
-
|
96
|
-
|
95
|
+
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
96
|
+
| undefined = undefined,
|
97
97
|
UMappedInput = unknown,
|
98
98
|
>(
|
99
99
|
middleware: Middleware<
|
100
100
|
MergeContext<TContext, TExtraContext>,
|
101
101
|
UExtraContext,
|
102
102
|
UMappedInput,
|
103
|
-
|
103
|
+
SchemaInput<TOutputSchema, THandlerOutput>
|
104
104
|
>,
|
105
105
|
mapInput: MapInputMiddleware<
|
106
106
|
SchemaOutput<TInputSchema, THandlerOutput>,
|
107
107
|
UMappedInput
|
108
108
|
>,
|
109
|
-
)
|
109
|
+
) => DecoratedProcedure<
|
110
110
|
TContext,
|
111
111
|
MergeContext<TExtraContext, UExtraContext>,
|
112
112
|
TInputSchema,
|
113
113
|
TOutputSchema,
|
114
114
|
THandlerOutput
|
115
|
-
>
|
115
|
+
>)
|
116
116
|
} & (undefined extends TContext
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
{})
|
117
|
+
? (
|
118
|
+
input: SchemaInput<TInputSchema> | FormData,
|
119
|
+
) => Promise<SchemaOutput<TOutputSchema, THandlerOutput>>
|
120
|
+
: unknown)
|
122
121
|
|
123
122
|
export interface ProcedureHandler<
|
124
123
|
TContext extends Context,
|
@@ -130,7 +129,7 @@ export interface ProcedureHandler<
|
|
130
129
|
(
|
131
130
|
input: SchemaOutput<TInputSchema>,
|
132
131
|
context: MergeContext<TContext, TExtraContext>,
|
133
|
-
meta: Meta
|
132
|
+
meta: Meta,
|
134
133
|
): Promisable<SchemaInput<TOutputSchema, TOutput>>
|
135
134
|
}
|
136
135
|
|
@@ -151,19 +150,20 @@ export function decorateProcedure<
|
|
151
150
|
THandlerOutput
|
152
151
|
>,
|
153
152
|
): DecoratedProcedure<
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
> {
|
153
|
+
TContext,
|
154
|
+
TExtraContext,
|
155
|
+
TInputSchema,
|
156
|
+
TOutputSchema,
|
157
|
+
THandlerOutput
|
158
|
+
> {
|
160
159
|
if (DECORATED_PROCEDURE_SYMBOL in procedure) {
|
161
160
|
return procedure as any
|
162
161
|
}
|
163
162
|
|
164
|
-
const serverAction = async (input: unknown) => {
|
163
|
+
const serverAction = async (input: unknown): Promise<SchemaOutput<TOutputSchema, THandlerOutput>> => {
|
165
164
|
const input_ = (() => {
|
166
|
-
if (!(input instanceof FormData))
|
165
|
+
if (!(input instanceof FormData))
|
166
|
+
return input
|
167
167
|
|
168
168
|
const transformer = new OpenAPIDeserializer({
|
169
169
|
schema: procedure.zz$p.contract.zz$cp.InputSchema,
|
@@ -235,17 +235,18 @@ export type WELL_DEFINED_PROCEDURE = Procedure<
|
|
235
235
|
>
|
236
236
|
|
237
237
|
export function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE {
|
238
|
-
if (item instanceof Procedure)
|
238
|
+
if (item instanceof Procedure)
|
239
|
+
return true
|
239
240
|
|
240
241
|
return (
|
241
|
-
(typeof item === 'object' || typeof item === 'function')
|
242
|
-
item !== null
|
243
|
-
'zz$p' in item
|
244
|
-
typeof item.zz$p === 'object'
|
245
|
-
item.zz$p !== null
|
246
|
-
'contract' in item.zz$p
|
247
|
-
isContractProcedure(item.zz$p.contract)
|
248
|
-
'handler' in item.zz$p
|
249
|
-
typeof item.zz$p.handler === 'function'
|
242
|
+
(typeof item === 'object' || typeof item === 'function')
|
243
|
+
&& item !== null
|
244
|
+
&& 'zz$p' in item
|
245
|
+
&& typeof item.zz$p === 'object'
|
246
|
+
&& item.zz$p !== null
|
247
|
+
&& 'contract' in item.zz$p
|
248
|
+
&& isContractProcedure(item.zz$p.contract)
|
249
|
+
&& 'handler' in item.zz$p
|
250
|
+
&& typeof item.zz$p.handler === 'function'
|
250
251
|
)
|
251
252
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { ContractProcedure } from '@orpc/contract'
|
2
2
|
import { z } from 'zod'
|
3
|
-
import {
|
3
|
+
import { decorateProcedure, isProcedure, os, Procedure } from '.'
|
4
4
|
import { RouterBuilder } from './router-builder'
|
5
5
|
|
6
6
|
const builder = new RouterBuilder<undefined, undefined>({})
|
@@ -22,7 +22,7 @@ describe('prefix', () => {
|
|
22
22
|
const router = builder
|
23
23
|
.prefix('/api')
|
24
24
|
.prefix('/users')
|
25
|
-
.router({ ping
|
25
|
+
.router({ ping, pong })
|
26
26
|
|
27
27
|
expect(router.ping.zz$p.contract.zz$cp.path).toEqual('/api/users/ping')
|
28
28
|
expect(router.pong.zz$p.contract.zz$cp.path).toEqual(undefined)
|
@@ -43,7 +43,7 @@ describe('tags', () => {
|
|
43
43
|
const router = builder
|
44
44
|
.tags('api')
|
45
45
|
.tags('users')
|
46
|
-
.router({ ping
|
46
|
+
.router({ ping, pong })
|
47
47
|
|
48
48
|
expect(router.ping.zz$p.contract.zz$cp.tags).toEqual([
|
49
49
|
'ping',
|
@@ -68,7 +68,7 @@ describe('middleware', () => {
|
|
68
68
|
})
|
69
69
|
|
70
70
|
it('router', () => {
|
71
|
-
const router = builder.use(mid1).use(mid2).router({ ping
|
71
|
+
const router = builder.use(mid1).use(mid2).router({ ping, pong })
|
72
72
|
|
73
73
|
expect(router.ping.zz$p.middlewares).toEqual([mid1, mid2])
|
74
74
|
expect(router.pong.zz$p.middlewares).toEqual([mid1, mid2])
|
package/src/router-builder.ts
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
+
import type { HandledRouter, Router } from './router'
|
2
|
+
import type { Context, MergeContext } from './types'
|
1
3
|
import { DecoratedContractProcedure, type HTTPPath } from '@orpc/contract'
|
2
4
|
import {
|
5
|
+
decorateMiddleware,
|
3
6
|
type MapInputMiddleware,
|
4
7
|
type Middleware,
|
5
|
-
decorateMiddleware,
|
6
8
|
} from './middleware'
|
7
9
|
import { decorateProcedure, isProcedure } from './procedure'
|
8
|
-
import type { HandledRouter, Router } from './router'
|
9
|
-
import type { Context, MergeContext } from './types'
|
10
10
|
|
11
11
|
export class RouterBuilder<
|
12
12
|
TContext extends Context,
|
@@ -28,7 +28,8 @@ export class RouterBuilder<
|
|
28
28
|
}
|
29
29
|
|
30
30
|
tags(...tags: string[]): RouterBuilder<TContext, TExtraContext> {
|
31
|
-
if (!tags.length)
|
31
|
+
if (!tags.length)
|
32
|
+
return this
|
32
33
|
|
33
34
|
return new RouterBuilder({
|
34
35
|
...this.zz$rb,
|
@@ -38,8 +39,8 @@ export class RouterBuilder<
|
|
38
39
|
|
39
40
|
use<
|
40
41
|
UExtraContext extends
|
41
|
-
|
42
|
-
|
42
|
+
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
43
|
+
| undefined = undefined,
|
43
44
|
>(
|
44
45
|
middleware: Middleware<
|
45
46
|
MergeContext<TContext, TExtraContext>,
|
@@ -51,8 +52,8 @@ export class RouterBuilder<
|
|
51
52
|
|
52
53
|
use<
|
53
54
|
UExtraContext extends
|
54
|
-
|
55
|
-
|
55
|
+
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
56
|
+
| undefined = undefined,
|
56
57
|
UMappedInput = unknown,
|
57
58
|
>(
|
58
59
|
middleware: Middleware<
|
@@ -93,7 +94,7 @@ export class RouterBuilder<
|
|
93
94
|
const middlewares = [
|
94
95
|
...builderMiddlewares,
|
95
96
|
...itemMiddlewares.filter(
|
96
|
-
|
97
|
+
item => !builderMiddlewares.includes(item),
|
97
98
|
),
|
98
99
|
]
|
99
100
|
|
@@ -110,7 +111,8 @@ export class RouterBuilder<
|
|
110
111
|
middlewares,
|
111
112
|
},
|
112
113
|
})
|
113
|
-
}
|
114
|
+
}
|
115
|
+
else {
|
114
116
|
handled[key] = this.router(item as any)
|
115
117
|
}
|
116
118
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { z } from 'zod'
|
2
|
-
import {
|
2
|
+
import { createRouterCaller, os } from '.'
|
3
3
|
|
4
4
|
describe('createRouterCaller', () => {
|
5
5
|
let internal = false
|
@@ -8,8 +8,8 @@ describe('createRouterCaller', () => {
|
|
8
8
|
const osw = os.context<{ auth?: boolean }>()
|
9
9
|
|
10
10
|
const ping = osw
|
11
|
-
.input(z.object({ value: z.string().transform(
|
12
|
-
.output(z.object({ value: z.number().transform(
|
11
|
+
.input(z.object({ value: z.string().transform(v => Number(v)) }))
|
12
|
+
.output(z.object({ value: z.number().transform(v => v.toString()) }))
|
13
13
|
.handler((input, context, meta) => {
|
14
14
|
expect(context).toEqual(context)
|
15
15
|
expect(meta.internal).toEqual(internal)
|
@@ -87,12 +87,12 @@ describe('createRouterCaller', () => {
|
|
87
87
|
value: true,
|
88
88
|
})
|
89
89
|
|
90
|
-
// @ts-expect-error
|
90
|
+
// @ts-expect-error - invalid input
|
91
91
|
expect(caller.ping({ value: new Date('2023-01-01') })).rejects.toThrowError(
|
92
92
|
'Validation input failed',
|
93
93
|
)
|
94
94
|
|
95
|
-
// @ts-expect-error
|
95
|
+
// @ts-expect-error - invalid input
|
96
96
|
expect(caller.nested.ping({ value: true })).rejects.toThrowError(
|
97
97
|
'Validation input failed',
|
98
98
|
)
|
@@ -158,7 +158,7 @@ describe('createRouterCaller', () => {
|
|
158
158
|
})
|
159
159
|
|
160
160
|
const caller = createRouterCaller({
|
161
|
-
router
|
161
|
+
router,
|
162
162
|
context,
|
163
163
|
})
|
164
164
|
|
package/src/router-caller.ts
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
import type {} from '@orpc/contract'
|
2
|
-
import { type Procedure, isProcedure } from './procedure'
|
3
|
-
import { type ProcedureCaller, createProcedureCaller } from './procedure-caller'
|
4
2
|
import type { Router } from './router'
|
5
|
-
import
|
6
|
-
import {} from './
|
3
|
+
import { isProcedure, type Procedure } from './procedure'
|
4
|
+
import { createProcedureCaller, type ProcedureCaller } from './procedure-caller'
|
7
5
|
|
8
6
|
export interface CreateRouterCallerOptions<
|
9
7
|
TRouter extends Router<any>,
|
@@ -16,14 +14,6 @@ export interface CreateRouterCallerOptions<
|
|
16
14
|
*/
|
17
15
|
context: TRouter extends Router<infer UContext> ? UContext : never
|
18
16
|
|
19
|
-
/**
|
20
|
-
* Helpful hooks to do some logics on specific time.
|
21
|
-
*/
|
22
|
-
hooks?: (
|
23
|
-
context: TRouter extends Router<infer UContext> ? UContext : never,
|
24
|
-
meta: Meta<unknown>,
|
25
|
-
) => Promisable<void>
|
26
|
-
|
27
17
|
/**
|
28
18
|
* This is helpful for logging and analytics.
|
29
19
|
*/
|
@@ -74,16 +64,15 @@ export function createRouterCaller<
|
|
74
64
|
caller[key] = createProcedureCaller({
|
75
65
|
procedure: item,
|
76
66
|
context: options.context as any,
|
77
|
-
|
78
|
-
path: path,
|
67
|
+
path,
|
79
68
|
internal,
|
80
69
|
validate,
|
81
70
|
})
|
82
|
-
}
|
71
|
+
}
|
72
|
+
else {
|
83
73
|
caller[key] = createRouterCaller({
|
84
74
|
router: item as any,
|
85
75
|
context: options.context,
|
86
|
-
hooks: options.hooks,
|
87
76
|
basePath: path,
|
88
77
|
internal,
|
89
78
|
validate,
|
@@ -35,12 +35,12 @@ it('required all procedure match', () => {
|
|
35
35
|
})
|
36
36
|
|
37
37
|
implementer.router({
|
38
|
-
p1
|
38
|
+
p1,
|
39
39
|
nested: {
|
40
40
|
p2: os.contract(cp2).handler(() => ''),
|
41
41
|
},
|
42
42
|
nested2: {
|
43
|
-
p3
|
43
|
+
p3,
|
44
44
|
},
|
45
45
|
})
|
46
46
|
|
@@ -49,10 +49,10 @@ it('required all procedure match', () => {
|
|
49
49
|
// @ts-expect-error p1 is mismatch
|
50
50
|
p1: os.handler(() => {}),
|
51
51
|
nested: {
|
52
|
-
p2
|
52
|
+
p2,
|
53
53
|
},
|
54
54
|
nested2: {
|
55
|
-
p3
|
55
|
+
p3,
|
56
56
|
},
|
57
57
|
})
|
58
58
|
}).toThrowError('Mismatch implementation for procedure at [p1]')
|
@@ -62,10 +62,10 @@ it('required all procedure match', () => {
|
|
62
62
|
// @ts-expect-error p1 is mismatch
|
63
63
|
p1: osw,
|
64
64
|
nested: {
|
65
|
-
p2
|
65
|
+
p2,
|
66
66
|
},
|
67
67
|
nested2: {
|
68
|
-
p3
|
68
|
+
p3,
|
69
69
|
},
|
70
70
|
})
|
71
71
|
}).toThrowError('Mismatch implementation for procedure at [p1]')
|
@@ -78,10 +78,10 @@ it('required all procedure match', () => {
|
|
78
78
|
.output(z.string())
|
79
79
|
.handler(() => 'unnoq'),
|
80
80
|
nested: {
|
81
|
-
p2
|
81
|
+
p2,
|
82
82
|
},
|
83
83
|
nested2: {
|
84
|
-
p3
|
84
|
+
p3,
|
85
85
|
},
|
86
86
|
})
|
87
87
|
}).toThrowError('Mismatch implementation for procedure at [p1]')
|
@@ -93,9 +93,9 @@ it('required all procedure match', () => {
|
|
93
93
|
|
94
94
|
expect(() => {
|
95
95
|
implementer.router({
|
96
|
-
p1
|
96
|
+
p1,
|
97
97
|
nested: {
|
98
|
-
p2
|
98
|
+
p2,
|
99
99
|
},
|
100
100
|
// @ts-expect-error missing p3
|
101
101
|
nested2: {},
|
@@ -104,9 +104,9 @@ it('required all procedure match', () => {
|
|
104
104
|
|
105
105
|
expect(() => {
|
106
106
|
implementer.router({
|
107
|
-
p1
|
107
|
+
p1,
|
108
108
|
nested: {
|
109
|
-
p2
|
109
|
+
p2,
|
110
110
|
},
|
111
111
|
nested2: {
|
112
112
|
p3: p3.prefix('/test'),
|
@@ -1,13 +1,13 @@
|
|
1
|
+
import type { Middleware } from './middleware'
|
2
|
+
import type { RouterWithContract } from './router'
|
3
|
+
import type { Context } from './types'
|
1
4
|
import {
|
2
5
|
type ContractProcedure,
|
3
6
|
type ContractRouter,
|
4
7
|
isContractProcedure,
|
5
8
|
} from '@orpc/contract'
|
6
|
-
import type { Middleware } from './middleware'
|
7
9
|
import { isProcedure } from './procedure'
|
8
10
|
import { ProcedureImplementer } from './procedure-implementer'
|
9
|
-
import type { RouterWithContract } from './router'
|
10
|
-
import type { Context } from './types'
|
11
11
|
|
12
12
|
export class RouterImplementer<
|
13
13
|
TContext extends Context,
|
@@ -61,7 +61,8 @@ export function chainRouterImplementer<
|
|
61
61
|
contract: item,
|
62
62
|
middlewares,
|
63
63
|
})
|
64
|
-
}
|
64
|
+
}
|
65
|
+
else {
|
65
66
|
result[key] = chainRouterImplementer(item as ContractRouter, middlewares)
|
66
67
|
}
|
67
68
|
}
|
@@ -94,12 +95,14 @@ export function assertRouterImplementation(
|
|
94
95
|
`Mismatch implementation for procedure at [${currentPath.join('.')}]`,
|
95
96
|
)
|
96
97
|
}
|
97
|
-
}
|
98
|
+
}
|
99
|
+
else {
|
98
100
|
throw new Error(
|
99
101
|
`Mismatch implementation for procedure at [${currentPath.join('.')}]`,
|
100
102
|
)
|
101
103
|
}
|
102
|
-
}
|
104
|
+
}
|
105
|
+
else {
|
103
106
|
assertRouterImplementation(
|
104
107
|
contractItem as ContractRouter,
|
105
108
|
routerItem as any,
|
package/src/router.test.ts
CHANGED
@@ -3,7 +3,7 @@ import { z } from 'zod'
|
|
3
3
|
import { os, type RouterWithContract, toContractRouter } from '.'
|
4
4
|
|
5
5
|
it('require procedure match context', () => {
|
6
|
-
const osw = os.context<{ auth: boolean
|
6
|
+
const osw = os.context<{ auth: boolean, userId: string }>()
|
7
7
|
|
8
8
|
osw.router({
|
9
9
|
ping: osw.context<{ auth: boolean }>().handler(() => {
|
@@ -106,14 +106,14 @@ it('toContractRouter', () => {
|
|
106
106
|
const p3 = oc.route({ method: 'GET', path: '/test' })
|
107
107
|
|
108
108
|
const contract = oc.router({
|
109
|
-
p1
|
109
|
+
p1,
|
110
110
|
|
111
111
|
nested: oc.router({
|
112
|
-
p2
|
112
|
+
p2,
|
113
113
|
}),
|
114
114
|
|
115
115
|
nested2: {
|
116
|
-
p3
|
116
|
+
p3,
|
117
117
|
},
|
118
118
|
})
|
119
119
|
|
package/src/router.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { Context } from './types'
|
1
2
|
import {
|
2
3
|
type ContractProcedure,
|
3
4
|
type ContractRouter,
|
@@ -5,10 +6,9 @@ import {
|
|
5
6
|
} from '@orpc/contract'
|
6
7
|
import {
|
7
8
|
type DecoratedProcedure,
|
8
|
-
type Procedure,
|
9
9
|
isProcedure,
|
10
|
+
type Procedure,
|
10
11
|
} from './procedure'
|
11
|
-
import type { Context } from './types'
|
12
12
|
|
13
13
|
export interface Router<TContext extends Context> {
|
14
14
|
[k: string]: Procedure<TContext, any, any, any, any> | Router<TContext>
|
@@ -23,12 +23,12 @@ export type HandledRouter<TRouter extends Router<any>> = {
|
|
23
23
|
infer UHandlerOutput
|
24
24
|
>
|
25
25
|
? DecoratedProcedure<
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
UContext,
|
27
|
+
UExtraContext,
|
28
|
+
UInputSchema,
|
29
|
+
UOutputSchema,
|
30
|
+
UHandlerOutput
|
31
|
+
>
|
32
32
|
: TRouter[K] extends Router<any>
|
33
33
|
? HandledRouter<TRouter[K]>
|
34
34
|
: never
|
@@ -58,9 +58,11 @@ export function toContractRouter(
|
|
58
58
|
|
59
59
|
if (isContractProcedure(item)) {
|
60
60
|
contract[key] = item
|
61
|
-
}
|
61
|
+
}
|
62
|
+
else if (isProcedure(item)) {
|
62
63
|
contract[key] = item.zz$p.contract
|
63
|
-
}
|
64
|
+
}
|
65
|
+
else {
|
64
66
|
contract[key] = toContractRouter(item as any)
|
65
67
|
}
|
66
68
|
}
|
package/src/types.test.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { MergeContext } from './types'
|
2
2
|
|
3
|
-
|
3
|
+
it('mergeContext', () => {
|
4
4
|
expectTypeOf<MergeContext<undefined, undefined>>().toEqualTypeOf<undefined>()
|
5
5
|
expectTypeOf<MergeContext<undefined, { foo: string }>>().toEqualTypeOf<{
|
6
6
|
foo: string
|