@orpc/server 0.10.0 → 0.11.0
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-TDFYNRZV.js → chunk-CVLK2PBB.js} +0 -1
- package/dist/fetch.js +1 -2
- package/dist/index.js +1 -2
- package/dist/src/adapters/fetch.d.ts +0 -1
- package/dist/src/builder.d.ts +0 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/middleware.d.ts +0 -1
- package/dist/src/procedure-builder.d.ts +0 -1
- package/dist/src/procedure-caller.d.ts +0 -1
- package/dist/src/procedure-implementer.d.ts +0 -1
- package/dist/src/procedure.d.ts +0 -1
- package/dist/src/router-builder.d.ts +0 -1
- package/dist/src/router-caller.d.ts +0 -1
- package/dist/src/router-implementer.d.ts +0 -1
- package/dist/src/router.d.ts +0 -1
- package/dist/src/types.d.ts +0 -1
- package/dist/src/utils.d.ts +0 -1
- package/package.json +12 -16
- package/dist/chunk-TDFYNRZV.js.map +0 -1
- package/dist/fetch.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/src/adapters/fetch.d.ts.map +0 -1
- package/dist/src/builder.d.ts.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/middleware.d.ts.map +0 -1
- package/dist/src/procedure-builder.d.ts.map +0 -1
- package/dist/src/procedure-caller.d.ts.map +0 -1
- package/dist/src/procedure-implementer.d.ts.map +0 -1
- package/dist/src/procedure.d.ts.map +0 -1
- package/dist/src/router-builder.d.ts.map +0 -1
- package/dist/src/router-caller.d.ts.map +0 -1
- package/dist/src/router-implementer.d.ts.map +0 -1
- package/dist/src/router.d.ts.map +0 -1
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/utils.d.ts.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/adapters/fetch.test.ts +0 -629
- package/src/adapters/fetch.ts +0 -290
- package/src/builder.test.ts +0 -371
- package/src/builder.ts +0 -238
- package/src/index.ts +0 -16
- package/src/middleware.test.ts +0 -260
- package/src/middleware.ts +0 -136
- package/src/procedure-builder.test.ts +0 -223
- package/src/procedure-builder.ts +0 -158
- package/src/procedure-caller.test.ts +0 -171
- package/src/procedure-caller.ts +0 -138
- package/src/procedure-implementer.test.ts +0 -220
- package/src/procedure-implementer.ts +0 -102
- package/src/procedure.test.ts +0 -317
- package/src/procedure.ts +0 -237
- package/src/router-builder.test.ts +0 -106
- package/src/router-builder.ts +0 -122
- package/src/router-caller.test.ts +0 -126
- package/src/router-caller.ts +0 -64
- package/src/router-implementer.test.ts +0 -116
- package/src/router-implementer.ts +0 -113
- package/src/router.test-d.ts +0 -48
- package/src/router.test.ts +0 -142
- package/src/router.ts +0 -91
- package/src/types.test.ts +0 -18
- package/src/types.ts +0 -13
- package/src/utils.test.ts +0 -16
- package/src/utils.ts +0 -16
package/src/procedure.ts
DELETED
@@ -1,237 +0,0 @@
|
|
1
|
-
import type { Promisable } from '@orpc/shared'
|
2
|
-
import type { ProcedureCaller } from './procedure-caller'
|
3
|
-
import type { Context, MergeContext, Meta } from './types'
|
4
|
-
import {
|
5
|
-
type ContractProcedure,
|
6
|
-
DecoratedContractProcedure,
|
7
|
-
type HTTPPath,
|
8
|
-
isContractProcedure,
|
9
|
-
type RouteOptions,
|
10
|
-
type Schema,
|
11
|
-
type SchemaInput,
|
12
|
-
type SchemaOutput,
|
13
|
-
} from '@orpc/contract'
|
14
|
-
import {
|
15
|
-
decorateMiddleware,
|
16
|
-
type MapInputMiddleware,
|
17
|
-
type Middleware,
|
18
|
-
} from './middleware'
|
19
|
-
import { createProcedureCaller } from './procedure-caller'
|
20
|
-
|
21
|
-
export class Procedure<
|
22
|
-
TContext extends Context,
|
23
|
-
TExtraContext extends Context,
|
24
|
-
TInputSchema extends Schema,
|
25
|
-
TOutputSchema extends Schema,
|
26
|
-
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
27
|
-
> {
|
28
|
-
constructor(
|
29
|
-
public zz$p: {
|
30
|
-
middlewares?: Middleware<any, any, any, any>[]
|
31
|
-
contract: ContractProcedure<TInputSchema, TOutputSchema>
|
32
|
-
func: ProcedureFunc<
|
33
|
-
TContext,
|
34
|
-
TExtraContext,
|
35
|
-
TInputSchema,
|
36
|
-
TOutputSchema,
|
37
|
-
TFuncOutput
|
38
|
-
>
|
39
|
-
},
|
40
|
-
) {}
|
41
|
-
}
|
42
|
-
|
43
|
-
export type DecoratedProcedure<
|
44
|
-
TContext extends Context,
|
45
|
-
TExtraContext extends Context,
|
46
|
-
TInputSchema extends Schema,
|
47
|
-
TOutputSchema extends Schema,
|
48
|
-
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
49
|
-
> = Procedure<
|
50
|
-
TContext,
|
51
|
-
TExtraContext,
|
52
|
-
TInputSchema,
|
53
|
-
TOutputSchema,
|
54
|
-
TFuncOutput
|
55
|
-
> & {
|
56
|
-
prefix: (
|
57
|
-
prefix: HTTPPath,
|
58
|
-
) => DecoratedProcedure<
|
59
|
-
TContext,
|
60
|
-
TExtraContext,
|
61
|
-
TInputSchema,
|
62
|
-
TOutputSchema,
|
63
|
-
TFuncOutput
|
64
|
-
>
|
65
|
-
|
66
|
-
route: (
|
67
|
-
opts: RouteOptions,
|
68
|
-
) => DecoratedProcedure<
|
69
|
-
TContext,
|
70
|
-
TExtraContext,
|
71
|
-
TInputSchema,
|
72
|
-
TOutputSchema,
|
73
|
-
TFuncOutput
|
74
|
-
>
|
75
|
-
|
76
|
-
use: (<
|
77
|
-
UExtraContext extends
|
78
|
-
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
79
|
-
| undefined = undefined,
|
80
|
-
>(
|
81
|
-
middleware: Middleware<
|
82
|
-
MergeContext<TContext, TExtraContext>,
|
83
|
-
UExtraContext,
|
84
|
-
SchemaOutput<TInputSchema>,
|
85
|
-
SchemaInput<TOutputSchema, TFuncOutput>
|
86
|
-
>,
|
87
|
-
) => DecoratedProcedure<
|
88
|
-
TContext,
|
89
|
-
MergeContext<TExtraContext, UExtraContext>,
|
90
|
-
TInputSchema,
|
91
|
-
TOutputSchema,
|
92
|
-
TFuncOutput
|
93
|
-
>) & (<
|
94
|
-
UExtraContext extends
|
95
|
-
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
96
|
-
| undefined = undefined,
|
97
|
-
UMappedInput = unknown,
|
98
|
-
>(
|
99
|
-
middleware: Middleware<
|
100
|
-
MergeContext<TContext, TExtraContext>,
|
101
|
-
UExtraContext,
|
102
|
-
UMappedInput,
|
103
|
-
SchemaInput<TOutputSchema, TFuncOutput>
|
104
|
-
>,
|
105
|
-
mapInput: MapInputMiddleware<
|
106
|
-
SchemaOutput<TInputSchema, TFuncOutput>,
|
107
|
-
UMappedInput
|
108
|
-
>,
|
109
|
-
) => DecoratedProcedure<
|
110
|
-
TContext,
|
111
|
-
MergeContext<TExtraContext, UExtraContext>,
|
112
|
-
TInputSchema,
|
113
|
-
TOutputSchema,
|
114
|
-
TFuncOutput
|
115
|
-
>)
|
116
|
-
} & (undefined extends TContext
|
117
|
-
? ProcedureCaller<Procedure<
|
118
|
-
TContext,
|
119
|
-
TExtraContext,
|
120
|
-
TInputSchema,
|
121
|
-
TOutputSchema,
|
122
|
-
TFuncOutput
|
123
|
-
>>
|
124
|
-
: unknown)
|
125
|
-
|
126
|
-
export interface ProcedureFunc<
|
127
|
-
TContext extends Context,
|
128
|
-
TExtraContext extends Context,
|
129
|
-
TInputSchema extends Schema,
|
130
|
-
TOutputSchema extends Schema,
|
131
|
-
TOutput extends SchemaOutput<TOutputSchema>,
|
132
|
-
> {
|
133
|
-
(
|
134
|
-
input: SchemaOutput<TInputSchema>,
|
135
|
-
context: MergeContext<TContext, TExtraContext>,
|
136
|
-
meta: Meta,
|
137
|
-
): Promisable<SchemaInput<TOutputSchema, TOutput>>
|
138
|
-
}
|
139
|
-
|
140
|
-
const DECORATED_PROCEDURE_SYMBOL = Symbol('DECORATED_PROCEDURE')
|
141
|
-
|
142
|
-
export function decorateProcedure<
|
143
|
-
TContext extends Context,
|
144
|
-
TExtraContext extends Context,
|
145
|
-
TInputSchema extends Schema,
|
146
|
-
TOutputSchema extends Schema,
|
147
|
-
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
148
|
-
>(
|
149
|
-
procedure: Procedure<
|
150
|
-
TContext,
|
151
|
-
TExtraContext,
|
152
|
-
TInputSchema,
|
153
|
-
TOutputSchema,
|
154
|
-
TFuncOutput
|
155
|
-
>,
|
156
|
-
): DecoratedProcedure<
|
157
|
-
TContext,
|
158
|
-
TExtraContext,
|
159
|
-
TInputSchema,
|
160
|
-
TOutputSchema,
|
161
|
-
TFuncOutput
|
162
|
-
> {
|
163
|
-
if (DECORATED_PROCEDURE_SYMBOL in procedure) {
|
164
|
-
return procedure as any
|
165
|
-
}
|
166
|
-
|
167
|
-
return Object.assign(createProcedureCaller({
|
168
|
-
procedure,
|
169
|
-
context: undefined as any,
|
170
|
-
}), {
|
171
|
-
[DECORATED_PROCEDURE_SYMBOL]: true,
|
172
|
-
zz$p: procedure.zz$p,
|
173
|
-
|
174
|
-
prefix(prefix: HTTPPath) {
|
175
|
-
return decorateProcedure({
|
176
|
-
zz$p: {
|
177
|
-
...procedure.zz$p,
|
178
|
-
contract: DecoratedContractProcedure.decorate(
|
179
|
-
procedure.zz$p.contract,
|
180
|
-
).prefix(prefix),
|
181
|
-
},
|
182
|
-
})
|
183
|
-
},
|
184
|
-
|
185
|
-
route(opts: RouteOptions) {
|
186
|
-
return decorateProcedure({
|
187
|
-
zz$p: {
|
188
|
-
...procedure.zz$p,
|
189
|
-
contract: DecoratedContractProcedure.decorate(
|
190
|
-
procedure.zz$p.contract,
|
191
|
-
).route(opts),
|
192
|
-
},
|
193
|
-
})
|
194
|
-
},
|
195
|
-
|
196
|
-
use(
|
197
|
-
middleware: Middleware<any, any, any, any>,
|
198
|
-
mapInput?: MapInputMiddleware<any, any>,
|
199
|
-
) {
|
200
|
-
const middleware_ = mapInput
|
201
|
-
? decorateMiddleware(middleware).mapInput(mapInput)
|
202
|
-
: middleware
|
203
|
-
|
204
|
-
return decorateProcedure({
|
205
|
-
zz$p: {
|
206
|
-
...procedure.zz$p,
|
207
|
-
middlewares: [middleware_, ...(procedure.zz$p.middlewares ?? [])],
|
208
|
-
},
|
209
|
-
})
|
210
|
-
},
|
211
|
-
}) as any
|
212
|
-
}
|
213
|
-
|
214
|
-
export type WELL_DEFINED_PROCEDURE = Procedure<
|
215
|
-
Context,
|
216
|
-
Context,
|
217
|
-
Schema,
|
218
|
-
Schema,
|
219
|
-
unknown
|
220
|
-
>
|
221
|
-
|
222
|
-
export function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE {
|
223
|
-
if (item instanceof Procedure)
|
224
|
-
return true
|
225
|
-
|
226
|
-
return (
|
227
|
-
(typeof item === 'object' || typeof item === 'function')
|
228
|
-
&& item !== null
|
229
|
-
&& 'zz$p' in item
|
230
|
-
&& typeof item.zz$p === 'object'
|
231
|
-
&& item.zz$p !== null
|
232
|
-
&& 'contract' in item.zz$p
|
233
|
-
&& isContractProcedure(item.zz$p.contract)
|
234
|
-
&& 'func' in item.zz$p
|
235
|
-
&& typeof item.zz$p.func === 'function'
|
236
|
-
)
|
237
|
-
}
|
@@ -1,106 +0,0 @@
|
|
1
|
-
import { ContractProcedure } from '@orpc/contract'
|
2
|
-
import { z } from 'zod'
|
3
|
-
import { decorateProcedure, isProcedure, os, Procedure } from '.'
|
4
|
-
import { RouterBuilder } from './router-builder'
|
5
|
-
|
6
|
-
const builder = new RouterBuilder<undefined, undefined>({})
|
7
|
-
const ping = os
|
8
|
-
.route({ method: 'GET', path: '/ping', tags: ['ping'] })
|
9
|
-
.func(() => 'ping')
|
10
|
-
const pong = os
|
11
|
-
.output(z.object({ id: z.string() }))
|
12
|
-
.func(() => ({ id: '123' }))
|
13
|
-
|
14
|
-
describe('prefix', () => {
|
15
|
-
it('chainable prefix', () => {
|
16
|
-
expect(builder.prefix('/1').prefix('/2').prefix('/3').zz$rb.prefix).toEqual(
|
17
|
-
'/1/2/3',
|
18
|
-
)
|
19
|
-
})
|
20
|
-
|
21
|
-
it('router', () => {
|
22
|
-
const router = builder
|
23
|
-
.prefix('/api')
|
24
|
-
.prefix('/users')
|
25
|
-
.router({ ping, pong })
|
26
|
-
|
27
|
-
expect(router.ping.zz$p.contract.zz$cp.path).toEqual('/api/users/ping')
|
28
|
-
expect(router.pong.zz$p.contract.zz$cp.path).toEqual(undefined)
|
29
|
-
})
|
30
|
-
})
|
31
|
-
|
32
|
-
describe('tags', () => {
|
33
|
-
it('chainable tags', () => {
|
34
|
-
expect(builder.tags('1', '2').tags('3').tags('4').zz$rb.tags).toEqual([
|
35
|
-
'1',
|
36
|
-
'2',
|
37
|
-
'3',
|
38
|
-
'4',
|
39
|
-
])
|
40
|
-
})
|
41
|
-
|
42
|
-
it('router', () => {
|
43
|
-
const router = builder
|
44
|
-
.tags('api')
|
45
|
-
.tags('users')
|
46
|
-
.router({ ping, pong })
|
47
|
-
|
48
|
-
expect(router.ping.zz$p.contract.zz$cp.tags).toEqual([
|
49
|
-
'ping',
|
50
|
-
'api',
|
51
|
-
'users',
|
52
|
-
])
|
53
|
-
expect(router.pong.zz$p.contract.zz$cp.tags).toEqual(['api', 'users'])
|
54
|
-
})
|
55
|
-
})
|
56
|
-
|
57
|
-
describe('middleware', () => {
|
58
|
-
const mid1 = vi.fn()
|
59
|
-
const mid2 = vi.fn()
|
60
|
-
const mid3 = vi.fn()
|
61
|
-
|
62
|
-
it('chainable middleware', () => {
|
63
|
-
expect(builder.use(mid1).use(mid2).use(mid3).zz$rb.middlewares).toEqual([
|
64
|
-
mid1,
|
65
|
-
mid2,
|
66
|
-
mid3,
|
67
|
-
])
|
68
|
-
})
|
69
|
-
|
70
|
-
it('router', () => {
|
71
|
-
const router = builder.use(mid1).use(mid2).router({ ping, pong })
|
72
|
-
|
73
|
-
expect(router.ping.zz$p.middlewares).toEqual([mid1, mid2])
|
74
|
-
expect(router.pong.zz$p.middlewares).toEqual([mid1, mid2])
|
75
|
-
})
|
76
|
-
|
77
|
-
it('decorate items', () => {
|
78
|
-
const ping = new Procedure({
|
79
|
-
contract: new ContractProcedure({
|
80
|
-
InputSchema: undefined,
|
81
|
-
OutputSchema: undefined,
|
82
|
-
}),
|
83
|
-
func: () => {},
|
84
|
-
})
|
85
|
-
|
86
|
-
const decorated = decorateProcedure({
|
87
|
-
zz$p: {
|
88
|
-
contract: new ContractProcedure({
|
89
|
-
InputSchema: undefined,
|
90
|
-
OutputSchema: undefined,
|
91
|
-
}),
|
92
|
-
func: () => {},
|
93
|
-
},
|
94
|
-
})
|
95
|
-
|
96
|
-
const router = builder.router({ ping, nested: { ping } })
|
97
|
-
|
98
|
-
expectTypeOf(router).toEqualTypeOf<{
|
99
|
-
ping: typeof decorated
|
100
|
-
nested: { ping: typeof decorated }
|
101
|
-
}>()
|
102
|
-
|
103
|
-
expect(router.ping).satisfies(isProcedure)
|
104
|
-
expect(router.nested.ping).satisfies(isProcedure)
|
105
|
-
})
|
106
|
-
})
|
package/src/router-builder.ts
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
import type { HandledRouter, Router } from './router'
|
2
|
-
import type { Context, MergeContext } from './types'
|
3
|
-
import { DecoratedContractProcedure, type HTTPPath } from '@orpc/contract'
|
4
|
-
import {
|
5
|
-
decorateMiddleware,
|
6
|
-
type MapInputMiddleware,
|
7
|
-
type Middleware,
|
8
|
-
} from './middleware'
|
9
|
-
import { decorateProcedure, isProcedure } from './procedure'
|
10
|
-
|
11
|
-
export class RouterBuilder<
|
12
|
-
TContext extends Context,
|
13
|
-
TExtraContext extends Context,
|
14
|
-
> {
|
15
|
-
constructor(
|
16
|
-
public zz$rb: {
|
17
|
-
prefix?: HTTPPath
|
18
|
-
tags?: string[]
|
19
|
-
middlewares?: Middleware<any, any, any, any>[]
|
20
|
-
},
|
21
|
-
) {}
|
22
|
-
|
23
|
-
prefix(prefix: HTTPPath): RouterBuilder<TContext, TExtraContext> {
|
24
|
-
return new RouterBuilder({
|
25
|
-
...this.zz$rb,
|
26
|
-
prefix: `${this.zz$rb.prefix ?? ''}${prefix}`,
|
27
|
-
})
|
28
|
-
}
|
29
|
-
|
30
|
-
tags(...tags: string[]): RouterBuilder<TContext, TExtraContext> {
|
31
|
-
if (!tags.length)
|
32
|
-
return this
|
33
|
-
|
34
|
-
return new RouterBuilder({
|
35
|
-
...this.zz$rb,
|
36
|
-
tags: [...(this.zz$rb.tags ?? []), ...tags],
|
37
|
-
})
|
38
|
-
}
|
39
|
-
|
40
|
-
use<
|
41
|
-
UExtraContext extends
|
42
|
-
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
43
|
-
| undefined = undefined,
|
44
|
-
>(
|
45
|
-
middleware: Middleware<
|
46
|
-
MergeContext<TContext, TExtraContext>,
|
47
|
-
UExtraContext,
|
48
|
-
unknown,
|
49
|
-
unknown
|
50
|
-
>,
|
51
|
-
): RouterBuilder<TContext, MergeContext<TExtraContext, UExtraContext>>
|
52
|
-
|
53
|
-
use<
|
54
|
-
UExtraContext extends
|
55
|
-
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
56
|
-
| undefined = undefined,
|
57
|
-
UMappedInput = unknown,
|
58
|
-
>(
|
59
|
-
middleware: Middleware<
|
60
|
-
MergeContext<TContext, TExtraContext>,
|
61
|
-
UExtraContext,
|
62
|
-
UMappedInput,
|
63
|
-
unknown
|
64
|
-
>,
|
65
|
-
mapInput: MapInputMiddleware<unknown, UMappedInput>,
|
66
|
-
): RouterBuilder<TContext, MergeContext<TExtraContext, UExtraContext>>
|
67
|
-
|
68
|
-
use(
|
69
|
-
middleware: Middleware<any, any, any, any>,
|
70
|
-
mapInput?: MapInputMiddleware<any, any>,
|
71
|
-
): RouterBuilder<any, any> {
|
72
|
-
const middleware_ = mapInput
|
73
|
-
? decorateMiddleware(middleware).mapInput(mapInput)
|
74
|
-
: middleware
|
75
|
-
|
76
|
-
return new RouterBuilder({
|
77
|
-
...this.zz$rb,
|
78
|
-
middlewares: [...(this.zz$rb.middlewares || []), middleware_],
|
79
|
-
})
|
80
|
-
}
|
81
|
-
|
82
|
-
router<URouter extends Router<TContext>>(
|
83
|
-
router: URouter,
|
84
|
-
): HandledRouter<URouter> {
|
85
|
-
const handled: Router<TContext> = {}
|
86
|
-
|
87
|
-
for (const key in router) {
|
88
|
-
const item = router[key]
|
89
|
-
|
90
|
-
if (isProcedure(item)) {
|
91
|
-
const builderMiddlewares = this.zz$rb.middlewares ?? []
|
92
|
-
const itemMiddlewares = item.zz$p.middlewares ?? []
|
93
|
-
|
94
|
-
const middlewares = [
|
95
|
-
...builderMiddlewares,
|
96
|
-
...itemMiddlewares.filter(
|
97
|
-
item => !builderMiddlewares.includes(item),
|
98
|
-
),
|
99
|
-
]
|
100
|
-
|
101
|
-
const contract = DecoratedContractProcedure.decorate(
|
102
|
-
item.zz$p.contract,
|
103
|
-
).addTags(...(this.zz$rb.tags ?? []))
|
104
|
-
|
105
|
-
handled[key] = decorateProcedure({
|
106
|
-
zz$p: {
|
107
|
-
...item.zz$p,
|
108
|
-
contract: this.zz$rb.prefix
|
109
|
-
? contract.prefix(this.zz$rb.prefix)
|
110
|
-
: contract,
|
111
|
-
middlewares,
|
112
|
-
},
|
113
|
-
})
|
114
|
-
}
|
115
|
-
else {
|
116
|
-
handled[key] = this.router(item as any)
|
117
|
-
}
|
118
|
-
}
|
119
|
-
|
120
|
-
return handled as HandledRouter<URouter>
|
121
|
-
}
|
122
|
-
}
|
@@ -1,126 +0,0 @@
|
|
1
|
-
import { z } from 'zod'
|
2
|
-
import { createRouterCaller, os } from '.'
|
3
|
-
|
4
|
-
describe('createRouterCaller', () => {
|
5
|
-
const internal = false
|
6
|
-
const context = { auth: true }
|
7
|
-
|
8
|
-
const osw = os.context<{ auth?: boolean }>()
|
9
|
-
|
10
|
-
const ping = osw
|
11
|
-
.input(z.object({ value: z.string().transform(v => Number(v)) }))
|
12
|
-
.output(z.object({ value: z.number().transform(v => v.toString()) }))
|
13
|
-
.func((input, context, meta) => {
|
14
|
-
expect(context).toEqual(context)
|
15
|
-
|
16
|
-
return input
|
17
|
-
})
|
18
|
-
|
19
|
-
const pong = osw.func((_, context, meta) => {
|
20
|
-
expect(context).toEqual(context)
|
21
|
-
|
22
|
-
return { value: true }
|
23
|
-
})
|
24
|
-
|
25
|
-
const router = osw.router({
|
26
|
-
ping,
|
27
|
-
pong,
|
28
|
-
nested: {
|
29
|
-
ping,
|
30
|
-
pong,
|
31
|
-
},
|
32
|
-
})
|
33
|
-
|
34
|
-
it('infer context', () => {
|
35
|
-
createRouterCaller({
|
36
|
-
router,
|
37
|
-
// @ts-expect-error invalid context
|
38
|
-
context: { auth: 123 },
|
39
|
-
})
|
40
|
-
|
41
|
-
createRouterCaller({
|
42
|
-
router,
|
43
|
-
context,
|
44
|
-
})
|
45
|
-
})
|
46
|
-
|
47
|
-
it('with validate', () => {
|
48
|
-
const caller = createRouterCaller({
|
49
|
-
router,
|
50
|
-
context,
|
51
|
-
})
|
52
|
-
|
53
|
-
expectTypeOf(caller.ping).toMatchTypeOf<
|
54
|
-
(input: { value: string }) => Promise<{
|
55
|
-
value: string
|
56
|
-
}>
|
57
|
-
>()
|
58
|
-
|
59
|
-
expectTypeOf(caller.pong).toMatchTypeOf<
|
60
|
-
(input: unknown) => Promise<{
|
61
|
-
value: boolean
|
62
|
-
}>
|
63
|
-
>()
|
64
|
-
|
65
|
-
expectTypeOf(caller.nested.ping).toMatchTypeOf<
|
66
|
-
(input: { value: string }) => Promise<{
|
67
|
-
value: string
|
68
|
-
}>
|
69
|
-
>()
|
70
|
-
|
71
|
-
expectTypeOf(caller.nested.pong).toMatchTypeOf<
|
72
|
-
(input: unknown) => Promise<{
|
73
|
-
value: boolean
|
74
|
-
}>
|
75
|
-
>()
|
76
|
-
|
77
|
-
expect(caller.ping({ value: '123' })).resolves.toEqual({ value: '123' })
|
78
|
-
expect(caller.pong({ value: '123' })).resolves.toEqual({ value: true })
|
79
|
-
|
80
|
-
expect(caller.nested.ping({ value: '123' })).resolves.toEqual({
|
81
|
-
value: '123',
|
82
|
-
})
|
83
|
-
expect(caller.nested.pong({ value: '123' })).resolves.toEqual({
|
84
|
-
value: true,
|
85
|
-
})
|
86
|
-
|
87
|
-
// @ts-expect-error - invalid input
|
88
|
-
expect(caller.ping({ value: new Date('2023-01-01') })).rejects.toThrowError(
|
89
|
-
'Validation input failed',
|
90
|
-
)
|
91
|
-
|
92
|
-
// @ts-expect-error - invalid input
|
93
|
-
expect(caller.nested.ping({ value: true })).rejects.toThrowError(
|
94
|
-
'Validation input failed',
|
95
|
-
)
|
96
|
-
})
|
97
|
-
|
98
|
-
it('path', () => {
|
99
|
-
const ping = osw.func((_, __, { path }) => {
|
100
|
-
return path
|
101
|
-
})
|
102
|
-
|
103
|
-
const router = osw.router({
|
104
|
-
ping,
|
105
|
-
nested: {
|
106
|
-
ping,
|
107
|
-
child: {
|
108
|
-
ping,
|
109
|
-
},
|
110
|
-
},
|
111
|
-
})
|
112
|
-
|
113
|
-
const caller = createRouterCaller({
|
114
|
-
router,
|
115
|
-
context,
|
116
|
-
})
|
117
|
-
|
118
|
-
expect(caller.ping('')).resolves.toEqual(['ping'])
|
119
|
-
expect(caller.nested.ping('')).resolves.toEqual(['nested', 'ping'])
|
120
|
-
expect(caller.nested.child.ping('')).resolves.toEqual([
|
121
|
-
'nested',
|
122
|
-
'child',
|
123
|
-
'ping',
|
124
|
-
])
|
125
|
-
})
|
126
|
-
})
|
package/src/router-caller.ts
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
import type { Value } from '@orpc/shared'
|
2
|
-
import type { Router } from './router'
|
3
|
-
import { isProcedure, type Procedure } from './procedure'
|
4
|
-
import { createProcedureCaller, type ProcedureCaller } from './procedure-caller'
|
5
|
-
|
6
|
-
export interface CreateRouterCallerOptions<
|
7
|
-
TRouter extends Router<any>,
|
8
|
-
> {
|
9
|
-
router: TRouter
|
10
|
-
|
11
|
-
/**
|
12
|
-
* The context used when calling the procedure.
|
13
|
-
*/
|
14
|
-
context: Value<
|
15
|
-
TRouter extends Router<infer UContext> ? UContext : never
|
16
|
-
>
|
17
|
-
|
18
|
-
/**
|
19
|
-
* This is helpful for logging and analytics.
|
20
|
-
*
|
21
|
-
* @internal
|
22
|
-
*/
|
23
|
-
basePath?: string[]
|
24
|
-
}
|
25
|
-
|
26
|
-
export type RouterCaller<
|
27
|
-
TRouter extends Router<any>,
|
28
|
-
> = {
|
29
|
-
[K in keyof TRouter]: TRouter[K] extends Procedure<any, any, any, any, any>
|
30
|
-
? ProcedureCaller<TRouter[K]>
|
31
|
-
: TRouter[K] extends Router<any>
|
32
|
-
? RouterCaller<TRouter[K]>
|
33
|
-
: never
|
34
|
-
}
|
35
|
-
|
36
|
-
export function createRouterCaller<
|
37
|
-
TRouter extends Router<any>,
|
38
|
-
>(
|
39
|
-
options: CreateRouterCallerOptions<TRouter>,
|
40
|
-
): RouterCaller<TRouter> {
|
41
|
-
const caller: Record<string, unknown> = {}
|
42
|
-
|
43
|
-
for (const key in options.router) {
|
44
|
-
const path = [...(options.basePath ?? []), key]
|
45
|
-
const item = options.router[key]
|
46
|
-
|
47
|
-
if (isProcedure(item)) {
|
48
|
-
caller[key] = createProcedureCaller({
|
49
|
-
procedure: item,
|
50
|
-
context: options.context as any,
|
51
|
-
path,
|
52
|
-
})
|
53
|
-
}
|
54
|
-
else {
|
55
|
-
caller[key] = createRouterCaller({
|
56
|
-
router: item as any,
|
57
|
-
context: options.context,
|
58
|
-
basePath: path,
|
59
|
-
})
|
60
|
-
}
|
61
|
-
}
|
62
|
-
|
63
|
-
return caller as RouterCaller<TRouter>
|
64
|
-
}
|