@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/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
|