@orpc/server 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{chunk-26DTFWOI.js → chunk-LYQ2OSU4.js} +26 -36
- package/dist/chunk-LYQ2OSU4.js.map +1 -0
- package/dist/fetch.js +5 -5
- package/dist/fetch.js.map +1 -1
- package/dist/index.js +9 -15
- package/dist/index.js.map +1 -1
- package/dist/src/adapters/fetch.d.ts +2 -2
- package/dist/src/adapters/fetch.d.ts.map +1 -1
- package/dist/src/builder.d.ts +2 -2
- package/dist/src/builder.d.ts.map +1 -1
- package/dist/src/procedure-builder.d.ts +2 -2
- package/dist/src/procedure-builder.d.ts.map +1 -1
- package/dist/src/procedure-caller.d.ts +7 -16
- package/dist/src/procedure-caller.d.ts.map +1 -1
- package/dist/src/procedure-implementer.d.ts +2 -2
- package/dist/src/procedure-implementer.d.ts.map +1 -1
- package/dist/src/procedure.d.ts +11 -10
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/router-caller.d.ts +8 -17
- package/dist/src/router-caller.d.ts.map +1 -1
- package/dist/src/router.d.ts +2 -2
- package/dist/src/router.d.ts.map +1 -1
- package/dist/src/types.d.ts +0 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/adapters/fetch.test.ts +18 -18
- package/src/adapters/fetch.ts +9 -5
- package/src/builder.test.ts +4 -4
- package/src/builder.ts +6 -6
- package/src/middleware.test.ts +1 -1
- package/src/procedure-builder.test.ts +2 -2
- package/src/procedure-builder.ts +6 -6
- package/src/procedure-caller.test.ts +27 -36
- package/src/procedure-caller.ts +36 -44
- package/src/procedure-implementer.test.ts +8 -8
- package/src/procedure-implementer.ts +6 -6
- package/src/procedure.test.ts +20 -20
- package/src/procedure.ts +30 -45
- package/src/router-builder.test.ts +4 -4
- package/src/router-caller.test.ts +5 -52
- package/src/router-caller.ts +11 -31
- package/src/router-implementer.test.ts +6 -6
- package/src/router.test-d.ts +2 -2
- package/src/router.test.ts +10 -10
- package/src/router.ts +4 -4
- package/src/types.ts +0 -1
- package/dist/chunk-26DTFWOI.js.map +0 -1
package/src/procedure.test.ts
CHANGED
@@ -18,7 +18,7 @@ it('isProcedure', () => {
|
|
18
18
|
InputSchema: undefined,
|
19
19
|
OutputSchema: undefined,
|
20
20
|
}),
|
21
|
-
|
21
|
+
func: () => {},
|
22
22
|
}),
|
23
23
|
),
|
24
24
|
),
|
@@ -29,7 +29,7 @@ it('isProcedure', () => {
|
|
29
29
|
InputSchema: undefined,
|
30
30
|
OutputSchema: undefined,
|
31
31
|
}),
|
32
|
-
|
32
|
+
func: () => {},
|
33
33
|
},
|
34
34
|
}).toSatisfy(isProcedure)
|
35
35
|
|
@@ -57,7 +57,7 @@ it('isProcedure', () => {
|
|
57
57
|
|
58
58
|
describe('route method', () => {
|
59
59
|
it('sets route options correctly', () => {
|
60
|
-
const p = os.context<{ auth: boolean }>().
|
60
|
+
const p = os.context<{ auth: boolean }>().func(() => {
|
61
61
|
return 'test'
|
62
62
|
})
|
63
63
|
|
@@ -69,11 +69,11 @@ describe('route method', () => {
|
|
69
69
|
|
70
70
|
it('preserves existing context and handler', () => {
|
71
71
|
const handler = () => 'test'
|
72
|
-
const p = os.context<{ auth: boolean }>().
|
72
|
+
const p = os.context<{ auth: boolean }>().func(handler)
|
73
73
|
|
74
74
|
const p2 = p.route({ path: '/test' })
|
75
75
|
|
76
|
-
expect(p2.zz$p.
|
76
|
+
expect(p2.zz$p.func).toBe(handler)
|
77
77
|
// Context type is preserved through the route method
|
78
78
|
expectTypeOf(p2).toEqualTypeOf<
|
79
79
|
DecoratedProcedure<
|
@@ -90,7 +90,7 @@ describe('route method', () => {
|
|
90
90
|
const p = os
|
91
91
|
.context<{ auth: boolean }>()
|
92
92
|
.route({ path: '/api', method: 'POST' })
|
93
|
-
.
|
93
|
+
.func(() => 'test')
|
94
94
|
|
95
95
|
const p2 = p.prefix('/v1')
|
96
96
|
|
@@ -105,7 +105,7 @@ describe('route method', () => {
|
|
105
105
|
.context<{ auth: boolean }>()
|
106
106
|
.route({ path: '/test' })
|
107
107
|
.use(mid)
|
108
|
-
.
|
108
|
+
.func((input, context) => {
|
109
109
|
expectTypeOf(context).toEqualTypeOf<
|
110
110
|
{ auth: boolean } & { userId: string }
|
111
111
|
>()
|
@@ -120,7 +120,7 @@ describe('route method', () => {
|
|
120
120
|
const p = os
|
121
121
|
.context<{ auth: boolean }>()
|
122
122
|
.route({ path: '/test1', method: 'GET' })
|
123
|
-
.
|
123
|
+
.func(() => 'test')
|
124
124
|
|
125
125
|
const p2 = p.route({ path: '/test2', method: 'POST' })
|
126
126
|
|
@@ -136,7 +136,7 @@ describe('route method', () => {
|
|
136
136
|
.input(inputSchema)
|
137
137
|
.output(outputSchema)
|
138
138
|
.route({ path: '/test' })
|
139
|
-
.
|
139
|
+
.func((input) => {
|
140
140
|
expectTypeOf(input).toEqualTypeOf<{ id: number }>()
|
141
141
|
return 'test'
|
142
142
|
})
|
@@ -157,7 +157,7 @@ describe('route method', () => {
|
|
157
157
|
})
|
158
158
|
|
159
159
|
it('prefix method', () => {
|
160
|
-
const p = os.context<{ auth: boolean }>().
|
160
|
+
const p = os.context<{ auth: boolean }>().func(() => {
|
161
161
|
return 'unnoq'
|
162
162
|
})
|
163
163
|
|
@@ -168,7 +168,7 @@ it('prefix method', () => {
|
|
168
168
|
const p3 = os
|
169
169
|
.context<{ auth: boolean }>()
|
170
170
|
.route({ path: '/test1' })
|
171
|
-
.
|
171
|
+
.func(() => {
|
172
172
|
return 'unnoq'
|
173
173
|
})
|
174
174
|
|
@@ -183,7 +183,7 @@ describe('use middleware', () => {
|
|
183
183
|
.use((_, __, meta) => {
|
184
184
|
return meta.next({ context: { postId: 'string' } })
|
185
185
|
})
|
186
|
-
.
|
186
|
+
.func(() => {
|
187
187
|
return 'unnoq'
|
188
188
|
})
|
189
189
|
|
@@ -251,7 +251,7 @@ describe('use middleware', () => {
|
|
251
251
|
const mid2 = vi.fn()
|
252
252
|
const mid3 = vi.fn()
|
253
253
|
|
254
|
-
const p1 = os.use(mid1).
|
254
|
+
const p1 = os.use(mid1).func(() => 'unnoq')
|
255
255
|
const p2 = p1.use(mid2).use(mid3)
|
256
256
|
|
257
257
|
expect(p2.zz$p.middlewares).toEqual([mid3, mid2, mid1])
|
@@ -260,12 +260,12 @@ describe('use middleware', () => {
|
|
260
260
|
|
261
261
|
describe('server action', () => {
|
262
262
|
it('only accept undefined context', () => {
|
263
|
-
expectTypeOf(os.
|
263
|
+
expectTypeOf(os.func(() => {})).toMatchTypeOf<(...args: any[]) => any>()
|
264
264
|
expectTypeOf(
|
265
|
-
os.context<{ auth: boolean } | undefined>().
|
265
|
+
os.context<{ auth: boolean } | undefined>().func(() => {}),
|
266
266
|
).toMatchTypeOf<(...args: any[]) => any>()
|
267
267
|
expectTypeOf(
|
268
|
-
os.context<{ auth: boolean }>().
|
268
|
+
os.context<{ auth: boolean }>().func(() => {}),
|
269
269
|
).not.toMatchTypeOf<(...args: any[]) => any>()
|
270
270
|
})
|
271
271
|
|
@@ -273,13 +273,13 @@ describe('server action', () => {
|
|
273
273
|
const p = os
|
274
274
|
.input(z.object({ id: z.number() }))
|
275
275
|
.output(z.string())
|
276
|
-
.
|
276
|
+
.func(() => 'string')
|
277
277
|
|
278
278
|
expectTypeOf(p).toMatchTypeOf<
|
279
279
|
(input: { id: number } | FormData) => Promise<string>
|
280
280
|
>()
|
281
281
|
|
282
|
-
const p2 = os.input(z.object({ id: z.number() })).
|
282
|
+
const p2 = os.input(z.object({ id: z.number() })).func(() => 12333)
|
283
283
|
|
284
284
|
expectTypeOf(p2).toMatchTypeOf<
|
285
285
|
(input: { id: number } | FormData) => Promise<number>
|
@@ -289,7 +289,7 @@ describe('server action', () => {
|
|
289
289
|
it('works with input', async () => {
|
290
290
|
const p = os
|
291
291
|
.input(z.object({ id: z.number(), date: z.date() }))
|
292
|
-
.
|
292
|
+
.func(async (input, context) => {
|
293
293
|
expect(context).toBe(undefined)
|
294
294
|
return input
|
295
295
|
})
|
@@ -303,7 +303,7 @@ describe('server action', () => {
|
|
303
303
|
it('can deserialize form data', async () => {
|
304
304
|
const p = os
|
305
305
|
.input(z.object({ id: z.number(), nested: z.object({ date: z.date() }) }))
|
306
|
-
.
|
306
|
+
.func(async input => input)
|
307
307
|
|
308
308
|
const form = new FormData()
|
309
309
|
form.append('id', '123')
|
package/src/procedure.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import type { Promisable } from '@orpc/shared'
|
2
|
+
import type { ProcedureCaller } from './procedure-caller'
|
2
3
|
import type { Context, MergeContext, Meta } from './types'
|
3
4
|
import {
|
4
5
|
type ContractProcedure,
|
@@ -10,7 +11,6 @@ import {
|
|
10
11
|
type SchemaInput,
|
11
12
|
type SchemaOutput,
|
12
13
|
} from '@orpc/contract'
|
13
|
-
import { OpenAPIDeserializer } from '@orpc/transformer'
|
14
14
|
import {
|
15
15
|
decorateMiddleware,
|
16
16
|
type MapInputMiddleware,
|
@@ -23,18 +23,18 @@ export class Procedure<
|
|
23
23
|
TExtraContext extends Context,
|
24
24
|
TInputSchema extends Schema,
|
25
25
|
TOutputSchema extends Schema,
|
26
|
-
|
26
|
+
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
27
27
|
> {
|
28
28
|
constructor(
|
29
29
|
public zz$p: {
|
30
30
|
middlewares?: Middleware<any, any, any, any>[]
|
31
31
|
contract: ContractProcedure<TInputSchema, TOutputSchema>
|
32
|
-
|
32
|
+
func: ProcedureFunc<
|
33
33
|
TContext,
|
34
34
|
TExtraContext,
|
35
35
|
TInputSchema,
|
36
36
|
TOutputSchema,
|
37
|
-
|
37
|
+
TFuncOutput
|
38
38
|
>
|
39
39
|
},
|
40
40
|
) {}
|
@@ -45,13 +45,13 @@ export type DecoratedProcedure<
|
|
45
45
|
TExtraContext extends Context,
|
46
46
|
TInputSchema extends Schema,
|
47
47
|
TOutputSchema extends Schema,
|
48
|
-
|
48
|
+
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
49
49
|
> = Procedure<
|
50
50
|
TContext,
|
51
51
|
TExtraContext,
|
52
52
|
TInputSchema,
|
53
53
|
TOutputSchema,
|
54
|
-
|
54
|
+
TFuncOutput
|
55
55
|
> & {
|
56
56
|
prefix: (
|
57
57
|
prefix: HTTPPath,
|
@@ -60,7 +60,7 @@ export type DecoratedProcedure<
|
|
60
60
|
TExtraContext,
|
61
61
|
TInputSchema,
|
62
62
|
TOutputSchema,
|
63
|
-
|
63
|
+
TFuncOutput
|
64
64
|
>
|
65
65
|
|
66
66
|
route: (
|
@@ -70,7 +70,7 @@ export type DecoratedProcedure<
|
|
70
70
|
TExtraContext,
|
71
71
|
TInputSchema,
|
72
72
|
TOutputSchema,
|
73
|
-
|
73
|
+
TFuncOutput
|
74
74
|
>
|
75
75
|
|
76
76
|
use: (<
|
@@ -82,14 +82,14 @@ export type DecoratedProcedure<
|
|
82
82
|
MergeContext<TContext, TExtraContext>,
|
83
83
|
UExtraContext,
|
84
84
|
SchemaOutput<TInputSchema>,
|
85
|
-
SchemaInput<TOutputSchema,
|
85
|
+
SchemaInput<TOutputSchema, TFuncOutput>
|
86
86
|
>,
|
87
87
|
) => DecoratedProcedure<
|
88
88
|
TContext,
|
89
89
|
MergeContext<TExtraContext, UExtraContext>,
|
90
90
|
TInputSchema,
|
91
91
|
TOutputSchema,
|
92
|
-
|
92
|
+
TFuncOutput
|
93
93
|
>) & (<
|
94
94
|
UExtraContext extends
|
95
95
|
| Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
|
@@ -100,10 +100,10 @@ export type DecoratedProcedure<
|
|
100
100
|
MergeContext<TContext, TExtraContext>,
|
101
101
|
UExtraContext,
|
102
102
|
UMappedInput,
|
103
|
-
SchemaInput<TOutputSchema,
|
103
|
+
SchemaInput<TOutputSchema, TFuncOutput>
|
104
104
|
>,
|
105
105
|
mapInput: MapInputMiddleware<
|
106
|
-
SchemaOutput<TInputSchema,
|
106
|
+
SchemaOutput<TInputSchema, TFuncOutput>,
|
107
107
|
UMappedInput
|
108
108
|
>,
|
109
109
|
) => DecoratedProcedure<
|
@@ -111,15 +111,19 @@ export type DecoratedProcedure<
|
|
111
111
|
MergeContext<TExtraContext, UExtraContext>,
|
112
112
|
TInputSchema,
|
113
113
|
TOutputSchema,
|
114
|
-
|
114
|
+
TFuncOutput
|
115
115
|
>)
|
116
116
|
} & (undefined extends TContext
|
117
|
-
?
|
118
|
-
|
119
|
-
|
117
|
+
? ProcedureCaller<Procedure<
|
118
|
+
TContext,
|
119
|
+
TExtraContext,
|
120
|
+
TInputSchema,
|
121
|
+
TOutputSchema,
|
122
|
+
TFuncOutput
|
123
|
+
>>
|
120
124
|
: unknown)
|
121
125
|
|
122
|
-
export interface
|
126
|
+
export interface ProcedureFunc<
|
123
127
|
TContext extends Context,
|
124
128
|
TExtraContext extends Context,
|
125
129
|
TInputSchema extends Schema,
|
@@ -140,49 +144,30 @@ export function decorateProcedure<
|
|
140
144
|
TExtraContext extends Context,
|
141
145
|
TInputSchema extends Schema,
|
142
146
|
TOutputSchema extends Schema,
|
143
|
-
|
147
|
+
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
144
148
|
>(
|
145
149
|
procedure: Procedure<
|
146
150
|
TContext,
|
147
151
|
TExtraContext,
|
148
152
|
TInputSchema,
|
149
153
|
TOutputSchema,
|
150
|
-
|
154
|
+
TFuncOutput
|
151
155
|
>,
|
152
156
|
): DecoratedProcedure<
|
153
157
|
TContext,
|
154
158
|
TExtraContext,
|
155
159
|
TInputSchema,
|
156
160
|
TOutputSchema,
|
157
|
-
|
161
|
+
TFuncOutput
|
158
162
|
> {
|
159
163
|
if (DECORATED_PROCEDURE_SYMBOL in procedure) {
|
160
164
|
return procedure as any
|
161
165
|
}
|
162
166
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
const transformer = new OpenAPIDeserializer({
|
169
|
-
schema: procedure.zz$p.contract.zz$cp.InputSchema,
|
170
|
-
})
|
171
|
-
|
172
|
-
return transformer.deserializeAsFormData(input)
|
173
|
-
})()
|
174
|
-
|
175
|
-
const procedureCaller = createProcedureCaller({
|
176
|
-
procedure,
|
177
|
-
context: undefined as any,
|
178
|
-
internal: false,
|
179
|
-
validate: true,
|
180
|
-
})
|
181
|
-
|
182
|
-
return await procedureCaller(input_ as any)
|
183
|
-
}
|
184
|
-
|
185
|
-
return Object.assign(serverAction, {
|
167
|
+
return Object.assign(createProcedureCaller({
|
168
|
+
procedure,
|
169
|
+
context: undefined as any,
|
170
|
+
}), {
|
186
171
|
[DECORATED_PROCEDURE_SYMBOL]: true,
|
187
172
|
zz$p: procedure.zz$p,
|
188
173
|
|
@@ -246,7 +231,7 @@ export function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE {
|
|
246
231
|
&& item.zz$p !== null
|
247
232
|
&& 'contract' in item.zz$p
|
248
233
|
&& isContractProcedure(item.zz$p.contract)
|
249
|
-
&& '
|
250
|
-
&& typeof item.zz$p.
|
234
|
+
&& 'func' in item.zz$p
|
235
|
+
&& typeof item.zz$p.func === 'function'
|
251
236
|
)
|
252
237
|
}
|
@@ -6,10 +6,10 @@ import { RouterBuilder } from './router-builder'
|
|
6
6
|
const builder = new RouterBuilder<undefined, undefined>({})
|
7
7
|
const ping = os
|
8
8
|
.route({ method: 'GET', path: '/ping', tags: ['ping'] })
|
9
|
-
.
|
9
|
+
.func(() => 'ping')
|
10
10
|
const pong = os
|
11
11
|
.output(z.object({ id: z.string() }))
|
12
|
-
.
|
12
|
+
.func(() => ({ id: '123' }))
|
13
13
|
|
14
14
|
describe('prefix', () => {
|
15
15
|
it('chainable prefix', () => {
|
@@ -80,7 +80,7 @@ describe('middleware', () => {
|
|
80
80
|
InputSchema: undefined,
|
81
81
|
OutputSchema: undefined,
|
82
82
|
}),
|
83
|
-
|
83
|
+
func: () => {},
|
84
84
|
})
|
85
85
|
|
86
86
|
const decorated = decorateProcedure({
|
@@ -89,7 +89,7 @@ describe('middleware', () => {
|
|
89
89
|
InputSchema: undefined,
|
90
90
|
OutputSchema: undefined,
|
91
91
|
}),
|
92
|
-
|
92
|
+
func: () => {},
|
93
93
|
},
|
94
94
|
})
|
95
95
|
|
@@ -2,24 +2,22 @@ import { z } from 'zod'
|
|
2
2
|
import { createRouterCaller, os } from '.'
|
3
3
|
|
4
4
|
describe('createRouterCaller', () => {
|
5
|
-
|
6
|
-
|
5
|
+
const internal = false
|
6
|
+
const context = { auth: true }
|
7
7
|
|
8
8
|
const osw = os.context<{ auth?: boolean }>()
|
9
9
|
|
10
10
|
const ping = osw
|
11
11
|
.input(z.object({ value: z.string().transform(v => Number(v)) }))
|
12
12
|
.output(z.object({ value: z.number().transform(v => v.toString()) }))
|
13
|
-
.
|
13
|
+
.func((input, context, meta) => {
|
14
14
|
expect(context).toEqual(context)
|
15
|
-
expect(meta.internal).toEqual(internal)
|
16
15
|
|
17
16
|
return input
|
18
17
|
})
|
19
18
|
|
20
|
-
const pong = osw.
|
19
|
+
const pong = osw.func((_, context, meta) => {
|
21
20
|
expect(context).toEqual(context)
|
22
|
-
expect(meta.internal).toBe(internal)
|
23
21
|
|
24
22
|
return { value: true }
|
25
23
|
})
|
@@ -50,7 +48,6 @@ describe('createRouterCaller', () => {
|
|
50
48
|
const caller = createRouterCaller({
|
51
49
|
router,
|
52
50
|
context,
|
53
|
-
internal,
|
54
51
|
})
|
55
52
|
|
56
53
|
expectTypeOf(caller.ping).toMatchTypeOf<
|
@@ -98,52 +95,8 @@ describe('createRouterCaller', () => {
|
|
98
95
|
)
|
99
96
|
})
|
100
97
|
|
101
|
-
it('without validate', () => {
|
102
|
-
internal = true
|
103
|
-
context = { auth: false }
|
104
|
-
|
105
|
-
const caller = createRouterCaller({
|
106
|
-
router,
|
107
|
-
context,
|
108
|
-
internal,
|
109
|
-
validate: false,
|
110
|
-
})
|
111
|
-
|
112
|
-
expectTypeOf(caller.ping).toMatchTypeOf<
|
113
|
-
(input: { value: number }) => Promise<{
|
114
|
-
value: number
|
115
|
-
}>
|
116
|
-
>()
|
117
|
-
|
118
|
-
expectTypeOf(caller.pong).toMatchTypeOf<
|
119
|
-
(input: unknown) => Promise<{
|
120
|
-
value: boolean
|
121
|
-
}>
|
122
|
-
>()
|
123
|
-
|
124
|
-
expectTypeOf(caller.nested.ping).toMatchTypeOf<
|
125
|
-
(input: { value: number }) => Promise<{
|
126
|
-
value: number
|
127
|
-
}>
|
128
|
-
>()
|
129
|
-
|
130
|
-
expectTypeOf(caller.nested.pong).toMatchTypeOf<
|
131
|
-
(input: unknown) => Promise<{
|
132
|
-
value: boolean
|
133
|
-
}>
|
134
|
-
>()
|
135
|
-
|
136
|
-
expect(caller.ping({ value: 123 })).resolves.toEqual({ value: 123 })
|
137
|
-
expect(caller.pong({ value: 123 })).resolves.toEqual({ value: true })
|
138
|
-
expect(caller.nested.ping({ value: 123 })).resolves.toEqual({ value: 123 })
|
139
|
-
expect(caller.nested.pong({ value: 123 })).resolves.toEqual({ value: true })
|
140
|
-
|
141
|
-
// @ts-expect-error it's not validate so bellow still works
|
142
|
-
expect(caller.ping({ value: '123' })).resolves.toEqual({ value: '123' })
|
143
|
-
})
|
144
|
-
|
145
98
|
it('path', () => {
|
146
|
-
const ping = osw.
|
99
|
+
const ping = osw.func((_, __, { path }) => {
|
147
100
|
return path
|
148
101
|
})
|
149
102
|
|
package/src/router-caller.ts
CHANGED
@@ -1,59 +1,43 @@
|
|
1
|
-
import type {} from '@orpc/
|
1
|
+
import type { PromisableValue } from '@orpc/shared'
|
2
2
|
import type { Router } from './router'
|
3
3
|
import { isProcedure, type Procedure } from './procedure'
|
4
4
|
import { createProcedureCaller, type ProcedureCaller } from './procedure-caller'
|
5
5
|
|
6
6
|
export interface CreateRouterCallerOptions<
|
7
7
|
TRouter extends Router<any>,
|
8
|
-
TValidate extends boolean,
|
9
8
|
> {
|
10
9
|
router: TRouter
|
11
10
|
|
12
11
|
/**
|
13
12
|
* The context used when calling the procedure.
|
14
13
|
*/
|
15
|
-
context:
|
14
|
+
context: PromisableValue<
|
15
|
+
TRouter extends Router<infer UContext> ? UContext : never
|
16
|
+
>
|
16
17
|
|
17
18
|
/**
|
18
19
|
* This is helpful for logging and analytics.
|
19
|
-
*/
|
20
|
-
basePath?: string[]
|
21
|
-
|
22
|
-
/**
|
23
|
-
* This flag helpful when you want bypass some logics not necessary to internal server calls.
|
24
|
-
*
|
25
|
-
* @default true
|
26
|
-
*/
|
27
|
-
internal?: boolean
|
28
|
-
|
29
|
-
/**
|
30
|
-
* Indicate whether validate input and output.
|
31
20
|
*
|
32
|
-
* @
|
21
|
+
* @internal
|
33
22
|
*/
|
34
|
-
|
23
|
+
basePath?: string[]
|
35
24
|
}
|
36
25
|
|
37
26
|
export type RouterCaller<
|
38
27
|
TRouter extends Router<any>,
|
39
|
-
TValidate extends boolean,
|
40
28
|
> = {
|
41
29
|
[K in keyof TRouter]: TRouter[K] extends Procedure<any, any, any, any, any>
|
42
|
-
? ProcedureCaller<TRouter[K]
|
30
|
+
? ProcedureCaller<TRouter[K]>
|
43
31
|
: TRouter[K] extends Router<any>
|
44
|
-
? RouterCaller<TRouter[K]
|
32
|
+
? RouterCaller<TRouter[K]>
|
45
33
|
: never
|
46
34
|
}
|
47
35
|
|
48
36
|
export function createRouterCaller<
|
49
37
|
TRouter extends Router<any>,
|
50
|
-
TValidate extends boolean = true,
|
51
38
|
>(
|
52
|
-
options: CreateRouterCallerOptions<TRouter
|
53
|
-
): RouterCaller<TRouter
|
54
|
-
const internal = options.internal ?? true
|
55
|
-
const validate = options.validate ?? true
|
56
|
-
|
39
|
+
options: CreateRouterCallerOptions<TRouter>,
|
40
|
+
): RouterCaller<TRouter> {
|
57
41
|
const caller: Record<string, unknown> = {}
|
58
42
|
|
59
43
|
for (const key in options.router) {
|
@@ -65,8 +49,6 @@ export function createRouterCaller<
|
|
65
49
|
procedure: item,
|
66
50
|
context: options.context as any,
|
67
51
|
path,
|
68
|
-
internal,
|
69
|
-
validate,
|
70
52
|
})
|
71
53
|
}
|
72
54
|
else {
|
@@ -74,11 +56,9 @@ export function createRouterCaller<
|
|
74
56
|
router: item as any,
|
75
57
|
context: options.context,
|
76
58
|
basePath: path,
|
77
|
-
internal,
|
78
|
-
validate,
|
79
59
|
})
|
80
60
|
}
|
81
61
|
}
|
82
62
|
|
83
|
-
return caller as RouterCaller<TRouter
|
63
|
+
return caller as RouterCaller<TRouter>
|
84
64
|
}
|
@@ -17,15 +17,15 @@ const cr = oc.router({
|
|
17
17
|
|
18
18
|
const osw = os.context<{ auth: boolean }>().contract(cr)
|
19
19
|
|
20
|
-
const p1 = osw.p1.
|
20
|
+
const p1 = osw.p1.func(() => {
|
21
21
|
return 'unnoq'
|
22
22
|
})
|
23
23
|
|
24
|
-
const p2 = osw.nested.p2.
|
24
|
+
const p2 = osw.nested.p2.func(() => {
|
25
25
|
return 'unnoq'
|
26
26
|
})
|
27
27
|
|
28
|
-
const p3 = osw.nested2.p3.
|
28
|
+
const p3 = osw.nested2.p3.func(() => {
|
29
29
|
return 'unnoq'
|
30
30
|
})
|
31
31
|
|
@@ -37,7 +37,7 @@ it('required all procedure match', () => {
|
|
37
37
|
implementer.router({
|
38
38
|
p1,
|
39
39
|
nested: {
|
40
|
-
p2: os.contract(cp2).
|
40
|
+
p2: os.contract(cp2).func(() => ''),
|
41
41
|
},
|
42
42
|
nested2: {
|
43
43
|
p3,
|
@@ -47,7 +47,7 @@ it('required all procedure match', () => {
|
|
47
47
|
expect(() => {
|
48
48
|
implementer.router({
|
49
49
|
// @ts-expect-error p1 is mismatch
|
50
|
-
p1: os.
|
50
|
+
p1: os.func(() => {}),
|
51
51
|
nested: {
|
52
52
|
p2,
|
53
53
|
},
|
@@ -76,7 +76,7 @@ it('required all procedure match', () => {
|
|
76
76
|
p1: os
|
77
77
|
.input(z.string())
|
78
78
|
.output(z.string())
|
79
|
-
.
|
79
|
+
.func(() => 'unnoq'),
|
80
80
|
nested: {
|
81
81
|
p2,
|
82
82
|
},
|
package/src/router.test-d.ts
CHANGED
@@ -6,11 +6,11 @@ const router = os.router({
|
|
6
6
|
ping: os
|
7
7
|
.input(z.object({ ping: z.string().transform(() => 1) }))
|
8
8
|
.output(z.object({ pong: z.number().transform(() => '1') }))
|
9
|
-
.
|
9
|
+
.func(() => ({ pong: 1 })),
|
10
10
|
user: {
|
11
11
|
find: os
|
12
12
|
.input(z.object({ find: z.number().transform(() => '1') }))
|
13
|
-
.
|
13
|
+
.func(() => ({ user: { id: 1 } }))
|
14
14
|
,
|
15
15
|
},
|
16
16
|
})
|
package/src/router.test.ts
CHANGED
@@ -6,22 +6,22 @@ it('require procedure match context', () => {
|
|
6
6
|
const osw = os.context<{ auth: boolean, userId: string }>()
|
7
7
|
|
8
8
|
osw.router({
|
9
|
-
ping: osw.context<{ auth: boolean }>().
|
9
|
+
ping: osw.context<{ auth: boolean }>().func(() => {
|
10
10
|
return { pong: 'ping' }
|
11
11
|
}),
|
12
12
|
|
13
13
|
// @ts-expect-error userId is not match
|
14
|
-
ping2: osw.context<{ userId: number }>().
|
14
|
+
ping2: osw.context<{ userId: number }>().func(() => {
|
15
15
|
return { name: 'unnoq' }
|
16
16
|
}),
|
17
17
|
|
18
18
|
nested: {
|
19
|
-
ping: osw.context<{ auth: boolean }>().
|
19
|
+
ping: osw.context<{ auth: boolean }>().func(() => {
|
20
20
|
return { pong: 'ping' }
|
21
21
|
}),
|
22
22
|
|
23
23
|
// @ts-expect-error userId is not match
|
24
|
-
ping2: osw.context<{ userId: number }>().
|
24
|
+
ping2: osw.context<{ userId: number }>().func(() => {
|
25
25
|
return { name: 'unnoq' }
|
26
26
|
}),
|
27
27
|
},
|
@@ -31,10 +31,10 @@ it('require procedure match context', () => {
|
|
31
31
|
it('require match contract', () => {
|
32
32
|
const pingContract = oc.route({ method: 'GET', path: '/ping' })
|
33
33
|
const pongContract = oc.input(z.string()).output(z.string())
|
34
|
-
const ping = os.contract(pingContract).
|
34
|
+
const ping = os.contract(pingContract).func(() => {
|
35
35
|
return 'ping'
|
36
36
|
})
|
37
|
-
const pong = os.contract(pongContract).
|
37
|
+
const pong = os.contract(pongContract).func(() => {
|
38
38
|
return 'pong'
|
39
39
|
})
|
40
40
|
|
@@ -85,7 +85,7 @@ it('require match contract', () => {
|
|
85
85
|
nested: {
|
86
86
|
ping,
|
87
87
|
// @ts-expect-error nested.pong is mismatch
|
88
|
-
pong: os.
|
88
|
+
pong: os.func(() => 'ping'),
|
89
89
|
},
|
90
90
|
}
|
91
91
|
|
@@ -120,18 +120,18 @@ it('toContractRouter', () => {
|
|
120
120
|
const osw = os.contract(contract)
|
121
121
|
|
122
122
|
const router = osw.router({
|
123
|
-
p1: osw.p1.
|
123
|
+
p1: osw.p1.func(() => {
|
124
124
|
return 'unnoq'
|
125
125
|
}),
|
126
126
|
|
127
127
|
nested: osw.nested.router({
|
128
|
-
p2: osw.nested.p2.
|
128
|
+
p2: osw.nested.p2.func(() => {
|
129
129
|
return 'unnoq'
|
130
130
|
}),
|
131
131
|
}),
|
132
132
|
|
133
133
|
nested2: {
|
134
|
-
p3: osw.nested2.p3.
|
134
|
+
p3: osw.nested2.p3.func(() => {
|
135
135
|
return 'unnoq'
|
136
136
|
}),
|
137
137
|
},
|