@orpc/client 0.0.0-next.b15d206 → 0.0.0-next.b2e67f7
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/README.md +88 -0
- package/dist/chunk-4HZVK3GJ.js +212 -0
- package/dist/chunk-X34KXUAJ.js +281 -0
- package/dist/fetch.js +128 -0
- package/dist/index.js +78 -71
- package/dist/openapi.js +231 -0
- package/dist/rpc.js +10 -0
- package/dist/src/adapters/fetch/index.d.ts +3 -0
- package/dist/src/adapters/fetch/rpc-link.d.ts +98 -0
- package/dist/src/adapters/fetch/types.d.ts +5 -0
- package/dist/src/client.d.ts +9 -0
- package/dist/src/dynamic-link.d.ts +12 -0
- package/dist/src/error.d.ts +106 -0
- package/dist/src/event-iterator-state.d.ts +9 -0
- package/dist/src/event-iterator.d.ts +12 -0
- package/dist/src/index.d.ts +7 -5
- package/dist/src/openapi/bracket-notation.d.ts +9 -0
- package/dist/src/openapi/index.d.ts +4 -0
- package/dist/src/openapi/json-serializer.d.ts +7 -0
- package/dist/src/openapi/serializer.d.ts +11 -0
- package/dist/src/rpc/index.d.ts +3 -0
- package/dist/src/rpc/json-serializer.d.ts +12 -0
- package/dist/src/rpc/serializer.d.ts +9 -0
- package/dist/src/types.d.ts +29 -0
- package/dist/src/utils.d.ts +17 -0
- package/package.json +28 -19
- package/dist/index.js.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/procedure.d.ts +0 -27
- package/dist/src/procedure.d.ts.map +0 -1
- package/dist/src/router.d.ts +0 -34
- package/dist/src/router.d.ts.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/index.ts +0 -9
- package/src/procedure.test.ts +0 -245
- package/src/procedure.ts +0 -108
- package/src/router.test.ts +0 -148
- package/src/router.ts +0 -96
package/src/procedure.test.ts
DELETED
@@ -1,245 +0,0 @@
|
|
1
|
-
import { ORPCError, os } from '@orpc/server'
|
2
|
-
import { createFetchHandler } from '@orpc/server/fetch'
|
3
|
-
import { z } from 'zod'
|
4
|
-
import { createProcedureClient } from './procedure'
|
5
|
-
|
6
|
-
describe('createProcedureClient', () => {
|
7
|
-
const schema = z.object({
|
8
|
-
value: z.string(),
|
9
|
-
})
|
10
|
-
const ping = os.input(schema).func((_, __, { path }) => path)
|
11
|
-
const router = os.router({
|
12
|
-
ping,
|
13
|
-
nested: {
|
14
|
-
ping,
|
15
|
-
},
|
16
|
-
})
|
17
|
-
const handler = createFetchHandler({
|
18
|
-
router,
|
19
|
-
})
|
20
|
-
const orpcFetch: typeof fetch = async (...args) => {
|
21
|
-
const request = new Request(...args)
|
22
|
-
const response = await handler({
|
23
|
-
prefix: '/orpc',
|
24
|
-
request,
|
25
|
-
context: {},
|
26
|
-
})
|
27
|
-
return response
|
28
|
-
}
|
29
|
-
|
30
|
-
it('types', () => {
|
31
|
-
const schema = z.object({
|
32
|
-
value: z.string(),
|
33
|
-
})
|
34
|
-
const client = createProcedureClient<
|
35
|
-
typeof schema,
|
36
|
-
undefined,
|
37
|
-
{ age: number }
|
38
|
-
>({} as any)
|
39
|
-
|
40
|
-
expectTypeOf(client).toEqualTypeOf<
|
41
|
-
(input: { value: string }) => Promise<{ age: number }>
|
42
|
-
>()
|
43
|
-
|
44
|
-
const client2 = createProcedureClient<
|
45
|
-
undefined,
|
46
|
-
typeof schema,
|
47
|
-
{ value: string }
|
48
|
-
>({} as any)
|
49
|
-
|
50
|
-
expectTypeOf(client2).toEqualTypeOf<
|
51
|
-
(input: unknown) => Promise<{ value: string }>
|
52
|
-
>()
|
53
|
-
})
|
54
|
-
|
55
|
-
it('simple', async () => {
|
56
|
-
const client = createProcedureClient({
|
57
|
-
baseURL: 'http://localhost:3000/orpc',
|
58
|
-
fetch: orpcFetch,
|
59
|
-
path: ['ping'],
|
60
|
-
})
|
61
|
-
|
62
|
-
const result = await client({ value: 'hello' })
|
63
|
-
|
64
|
-
expect(result).toEqual(['ping'])
|
65
|
-
|
66
|
-
const client2 = createProcedureClient({
|
67
|
-
baseURL: 'http://localhost:3000/orpc',
|
68
|
-
fetch: orpcFetch,
|
69
|
-
path: ['nested', 'ping'],
|
70
|
-
})
|
71
|
-
|
72
|
-
const result2 = await client2({ value: 'hello' })
|
73
|
-
|
74
|
-
expect(result2).toEqual(['nested', 'ping'])
|
75
|
-
})
|
76
|
-
|
77
|
-
it('on known error', () => {
|
78
|
-
const client = createProcedureClient({
|
79
|
-
baseURL: 'http://localhost:3000/orpc',
|
80
|
-
fetch: orpcFetch,
|
81
|
-
path: ['ping'],
|
82
|
-
})
|
83
|
-
|
84
|
-
expect(client({ value: {} })).rejects.toThrowError(
|
85
|
-
'Validation input failed',
|
86
|
-
)
|
87
|
-
})
|
88
|
-
|
89
|
-
it('on unknown error', () => {
|
90
|
-
const orpcFetch: typeof fetch = async () => {
|
91
|
-
return new Response(JSON.stringify({}), {
|
92
|
-
status: 400,
|
93
|
-
headers: {
|
94
|
-
'Content-Type': 'application/json',
|
95
|
-
},
|
96
|
-
})
|
97
|
-
}
|
98
|
-
|
99
|
-
const client = createProcedureClient({
|
100
|
-
baseURL: 'http://localhost:3000/orpc',
|
101
|
-
fetch: orpcFetch,
|
102
|
-
path: ['ping'],
|
103
|
-
})
|
104
|
-
|
105
|
-
expect(client({ value: 'hello' })).rejects.toThrowError(
|
106
|
-
'Cannot parse response.',
|
107
|
-
)
|
108
|
-
})
|
109
|
-
|
110
|
-
it('transformer', async () => {
|
111
|
-
const router = os.router({
|
112
|
-
ping: os
|
113
|
-
.input(z.object({ value: z.date() }))
|
114
|
-
.func(input => input.value),
|
115
|
-
})
|
116
|
-
|
117
|
-
const handler = createFetchHandler({
|
118
|
-
router,
|
119
|
-
})
|
120
|
-
|
121
|
-
const client = createProcedureClient({
|
122
|
-
path: ['ping'],
|
123
|
-
baseURL: 'http://localhost:3000/orpc',
|
124
|
-
fetch: (...args) => {
|
125
|
-
const request = new Request(...args)
|
126
|
-
return handler({
|
127
|
-
prefix: '/orpc',
|
128
|
-
request,
|
129
|
-
context: {},
|
130
|
-
})
|
131
|
-
},
|
132
|
-
})
|
133
|
-
|
134
|
-
const now = new Date()
|
135
|
-
expect(await client({ value: now })).toEqual(now)
|
136
|
-
})
|
137
|
-
|
138
|
-
it('error include data', async () => {
|
139
|
-
const router = os.router({
|
140
|
-
ping: os.func((input) => {
|
141
|
-
throw new ORPCError({
|
142
|
-
code: 'BAD_GATEWAY',
|
143
|
-
data: {
|
144
|
-
value: 'from error',
|
145
|
-
},
|
146
|
-
})
|
147
|
-
}),
|
148
|
-
})
|
149
|
-
|
150
|
-
const handler = createFetchHandler({
|
151
|
-
router,
|
152
|
-
})
|
153
|
-
|
154
|
-
const client = createProcedureClient({
|
155
|
-
path: ['ping'],
|
156
|
-
baseURL: 'http://localhost:3000/orpc',
|
157
|
-
fetch: (...args) => {
|
158
|
-
const request = new Request(...args)
|
159
|
-
return handler({
|
160
|
-
prefix: '/orpc',
|
161
|
-
request,
|
162
|
-
context: {},
|
163
|
-
})
|
164
|
-
},
|
165
|
-
})
|
166
|
-
|
167
|
-
let error: any
|
168
|
-
try {
|
169
|
-
await client(undefined)
|
170
|
-
}
|
171
|
-
catch (e) {
|
172
|
-
error = e
|
173
|
-
}
|
174
|
-
|
175
|
-
expect(error).toBeInstanceOf(ORPCError)
|
176
|
-
expect(error.code).toEqual('BAD_GATEWAY')
|
177
|
-
expect(error.data).toEqual({ value: 'from error' })
|
178
|
-
})
|
179
|
-
})
|
180
|
-
|
181
|
-
describe('upload file', () => {
|
182
|
-
const router = os.router({
|
183
|
-
signal: os.input(z.instanceof(Blob)).func((input) => {
|
184
|
-
return input
|
185
|
-
}),
|
186
|
-
multiple: os
|
187
|
-
.input(
|
188
|
-
z.object({ first: z.instanceof(Blob), second: z.instanceof(Blob) }),
|
189
|
-
)
|
190
|
-
.func((input) => {
|
191
|
-
return input
|
192
|
-
}),
|
193
|
-
})
|
194
|
-
|
195
|
-
const handler = createFetchHandler({ router })
|
196
|
-
|
197
|
-
const orpcFetch: typeof fetch = async (...args) => {
|
198
|
-
const request = new Request(...args)
|
199
|
-
const response = await handler({
|
200
|
-
prefix: '/orpc',
|
201
|
-
request,
|
202
|
-
context: {},
|
203
|
-
})
|
204
|
-
return response
|
205
|
-
}
|
206
|
-
|
207
|
-
const blob1 = new Blob(['hello'], { type: 'text/plain;charset=utf-8' })
|
208
|
-
const blob2 = new Blob(['"world"'], { type: 'image/png' })
|
209
|
-
const blob3 = new Blob(['unnoq'], { type: 'application/octet-stream' })
|
210
|
-
|
211
|
-
it('single file', async () => {
|
212
|
-
const client = createProcedureClient({
|
213
|
-
baseURL: 'http://localhost:3000/orpc',
|
214
|
-
fetch: orpcFetch,
|
215
|
-
path: ['signal'],
|
216
|
-
})
|
217
|
-
|
218
|
-
const output = await client(blob1)
|
219
|
-
|
220
|
-
expect(output).toBeInstanceOf(Blob)
|
221
|
-
expect(output.type).toBe('text/plain;charset=utf-8')
|
222
|
-
expect(await output.text()).toBe('hello')
|
223
|
-
})
|
224
|
-
|
225
|
-
it('multiple file', async () => {
|
226
|
-
const client = createProcedureClient({
|
227
|
-
baseURL: 'http://localhost:3000/orpc',
|
228
|
-
fetch: orpcFetch,
|
229
|
-
path: ['multiple'],
|
230
|
-
})
|
231
|
-
|
232
|
-
const output = await client({ first: blob3, second: blob2 })
|
233
|
-
|
234
|
-
const file0 = output.first
|
235
|
-
const file1 = output.second
|
236
|
-
|
237
|
-
expect(file0).toBeInstanceOf(Blob)
|
238
|
-
expect(file0.type).toBe('application/octet-stream')
|
239
|
-
expect(await file0.text()).toBe('unnoq')
|
240
|
-
|
241
|
-
expect(file1).toBeInstanceOf(Blob)
|
242
|
-
expect(file1.type).toBe('image/png')
|
243
|
-
expect(await file1.text()).toBe('"world"')
|
244
|
-
})
|
245
|
-
})
|
package/src/procedure.ts
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
/// <reference lib="dom" />
|
2
|
-
/// <reference lib="dom.iterable" />
|
3
|
-
|
4
|
-
import type { Promisable } from '@orpc/shared'
|
5
|
-
import {
|
6
|
-
ORPC_HEADER,
|
7
|
-
ORPC_HEADER_VALUE,
|
8
|
-
type Schema,
|
9
|
-
type SchemaInput,
|
10
|
-
type SchemaOutput,
|
11
|
-
} from '@orpc/contract'
|
12
|
-
import { trim } from '@orpc/shared'
|
13
|
-
import { ORPCError } from '@orpc/shared/error'
|
14
|
-
import { ORPCDeserializer, ORPCSerializer } from '@orpc/transformer'
|
15
|
-
|
16
|
-
export interface ProcedureClient<
|
17
|
-
TInputSchema extends Schema,
|
18
|
-
TOutputSchema extends Schema,
|
19
|
-
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
20
|
-
> {
|
21
|
-
(
|
22
|
-
input: SchemaInput<TInputSchema>,
|
23
|
-
): Promise<SchemaOutput<TOutputSchema, TFuncOutput>>
|
24
|
-
}
|
25
|
-
|
26
|
-
export interface CreateProcedureClientOptions {
|
27
|
-
/**
|
28
|
-
* The base url of the server.
|
29
|
-
*/
|
30
|
-
baseURL: string
|
31
|
-
|
32
|
-
/**
|
33
|
-
* The fetch function used to make the request.
|
34
|
-
* @default global fetch
|
35
|
-
*/
|
36
|
-
fetch?: typeof fetch
|
37
|
-
|
38
|
-
/**
|
39
|
-
* The headers used to make the request.
|
40
|
-
* Invoked before the request is made.
|
41
|
-
*/
|
42
|
-
headers?: (input: unknown) => Promisable<Headers | Record<string, string>>
|
43
|
-
|
44
|
-
/**
|
45
|
-
* The path of the procedure on server.
|
46
|
-
*/
|
47
|
-
path: string[]
|
48
|
-
}
|
49
|
-
|
50
|
-
export function createProcedureClient<
|
51
|
-
TInputSchema extends Schema,
|
52
|
-
TOutputSchema extends Schema,
|
53
|
-
TFuncOutput extends SchemaOutput<TOutputSchema>,
|
54
|
-
>(
|
55
|
-
options: CreateProcedureClientOptions,
|
56
|
-
): ProcedureClient<TInputSchema, TOutputSchema, TFuncOutput> {
|
57
|
-
const serializer = new ORPCSerializer()
|
58
|
-
const deserializer = new ORPCDeserializer()
|
59
|
-
|
60
|
-
const client = async (input: unknown): Promise<unknown> => {
|
61
|
-
const fetch_ = options.fetch ?? fetch
|
62
|
-
const url = `${trim(options.baseURL, '/')}/${options.path.map(encodeURIComponent).join('/')}`
|
63
|
-
let headers = await options.headers?.(input)
|
64
|
-
headers = headers instanceof Headers ? headers : new Headers(headers)
|
65
|
-
|
66
|
-
const { body, headers: headers_ } = serializer.serialize(input)
|
67
|
-
|
68
|
-
for (const [key, value] of headers_.entries()) {
|
69
|
-
headers.set(key, value)
|
70
|
-
}
|
71
|
-
|
72
|
-
headers.set(ORPC_HEADER, ORPC_HEADER_VALUE)
|
73
|
-
|
74
|
-
const response = await fetch_(url, {
|
75
|
-
method: 'POST',
|
76
|
-
headers,
|
77
|
-
body,
|
78
|
-
})
|
79
|
-
|
80
|
-
const json = await (async () => {
|
81
|
-
try {
|
82
|
-
return await deserializer.deserialize(response)
|
83
|
-
}
|
84
|
-
catch (e) {
|
85
|
-
throw new ORPCError({
|
86
|
-
code: 'INTERNAL_SERVER_ERROR',
|
87
|
-
message: 'Cannot parse response.',
|
88
|
-
cause: e,
|
89
|
-
})
|
90
|
-
}
|
91
|
-
})()
|
92
|
-
|
93
|
-
if (!response.ok) {
|
94
|
-
throw (
|
95
|
-
ORPCError.fromJSON(json)
|
96
|
-
?? new ORPCError({
|
97
|
-
status: response.status,
|
98
|
-
code: 'INTERNAL_SERVER_ERROR',
|
99
|
-
message: 'Internal server error',
|
100
|
-
})
|
101
|
-
)
|
102
|
-
}
|
103
|
-
|
104
|
-
return json
|
105
|
-
}
|
106
|
-
|
107
|
-
return client as any
|
108
|
-
}
|
package/src/router.test.ts
DELETED
@@ -1,148 +0,0 @@
|
|
1
|
-
import { oc } from '@orpc/contract'
|
2
|
-
import { os } from '@orpc/server'
|
3
|
-
import { createFetchHandler } from '@orpc/server/fetch'
|
4
|
-
import { z } from 'zod'
|
5
|
-
import { createRouterClient } from './router'
|
6
|
-
|
7
|
-
describe('createRouterClient', () => {
|
8
|
-
const schema = z.object({
|
9
|
-
value: z.string(),
|
10
|
-
})
|
11
|
-
const ping = os.input(schema).func((_, __, { path }) => path)
|
12
|
-
const router = os.router({
|
13
|
-
ping,
|
14
|
-
nested: {
|
15
|
-
unique: ping,
|
16
|
-
},
|
17
|
-
})
|
18
|
-
const handler = createFetchHandler({
|
19
|
-
router,
|
20
|
-
})
|
21
|
-
const orpcFetch: typeof fetch = async (...args) => {
|
22
|
-
const request = new Request(...args)
|
23
|
-
return await handler({
|
24
|
-
prefix: '/orpc',
|
25
|
-
request,
|
26
|
-
context: {},
|
27
|
-
})
|
28
|
-
}
|
29
|
-
|
30
|
-
it('types with contract router', () => {
|
31
|
-
const schema = z.object({
|
32
|
-
value: z.string(),
|
33
|
-
})
|
34
|
-
|
35
|
-
const ping = oc.input(schema)
|
36
|
-
const pong = oc.output(schema)
|
37
|
-
const peng = oc.route({})
|
38
|
-
const router = oc.router({
|
39
|
-
ping,
|
40
|
-
pong,
|
41
|
-
peng,
|
42
|
-
nested: {
|
43
|
-
unique: ping,
|
44
|
-
},
|
45
|
-
})
|
46
|
-
|
47
|
-
const client = createRouterClient<typeof router>({} as any)
|
48
|
-
|
49
|
-
expectTypeOf(client.ping).toEqualTypeOf<
|
50
|
-
(input: { value: string }) => Promise<unknown>
|
51
|
-
>()
|
52
|
-
expectTypeOf(client.pong).toEqualTypeOf<
|
53
|
-
(input: unknown) => Promise<{ value: string }>
|
54
|
-
>()
|
55
|
-
expectTypeOf(client.peng).toEqualTypeOf<
|
56
|
-
(input: unknown) => Promise<unknown>
|
57
|
-
>()
|
58
|
-
|
59
|
-
expectTypeOf(client.nested.unique).toEqualTypeOf<
|
60
|
-
(input: { value: string }) => Promise<unknown>
|
61
|
-
>()
|
62
|
-
})
|
63
|
-
|
64
|
-
it('types with router', () => {
|
65
|
-
const schema = z.object({
|
66
|
-
value: z.string(),
|
67
|
-
})
|
68
|
-
const ping = os.input(schema).func(() => '')
|
69
|
-
const pong = os.output(schema).func(() => ({ value: 'string' }))
|
70
|
-
const peng = os.route({}).func(() => ({ age: 1244 }))
|
71
|
-
|
72
|
-
const router = os.router({
|
73
|
-
ping,
|
74
|
-
pong,
|
75
|
-
peng,
|
76
|
-
nested: {
|
77
|
-
unique: ping,
|
78
|
-
},
|
79
|
-
})
|
80
|
-
|
81
|
-
const client = createRouterClient<typeof router>({} as any)
|
82
|
-
|
83
|
-
expectTypeOf(client.ping).toEqualTypeOf<
|
84
|
-
(input: { value: string }) => Promise<string>
|
85
|
-
>()
|
86
|
-
expectTypeOf(client.pong).toEqualTypeOf<
|
87
|
-
(input: unknown) => Promise<{ value: string }>
|
88
|
-
>()
|
89
|
-
expectTypeOf(client.peng).toEqualTypeOf<
|
90
|
-
(input: unknown) => Promise<{ age: number }>
|
91
|
-
>()
|
92
|
-
expectTypeOf(client.nested.unique).toEqualTypeOf<
|
93
|
-
(input: { value: string }) => Promise<string>
|
94
|
-
>()
|
95
|
-
})
|
96
|
-
|
97
|
-
it('simple', async () => {
|
98
|
-
const client = createRouterClient<typeof router>({
|
99
|
-
baseURL: 'http://localhost:3000/orpc',
|
100
|
-
fetch: orpcFetch,
|
101
|
-
})
|
102
|
-
|
103
|
-
const result = await client.ping({ value: 'hello' })
|
104
|
-
expect(result).toEqual(['ping'])
|
105
|
-
|
106
|
-
const result2 = await client.nested.unique({ value: 'hello' })
|
107
|
-
expect(result2).toEqual(['nested', 'unique'])
|
108
|
-
})
|
109
|
-
|
110
|
-
it('on error', () => {
|
111
|
-
const client = createRouterClient<typeof router>({
|
112
|
-
baseURL: 'http://localhost:3000/orpc',
|
113
|
-
fetch: orpcFetch,
|
114
|
-
})
|
115
|
-
|
116
|
-
// @ts-expect-error - invalid input
|
117
|
-
expect(client.ping({ value: {} })).rejects.toThrowError(
|
118
|
-
'Validation input failed',
|
119
|
-
)
|
120
|
-
})
|
121
|
-
|
122
|
-
it('transformer', async () => {
|
123
|
-
const router = os.router({
|
124
|
-
ping: os
|
125
|
-
.input(z.object({ value: z.date() }))
|
126
|
-
.func(input => input.value),
|
127
|
-
})
|
128
|
-
|
129
|
-
const handler = createFetchHandler({
|
130
|
-
router,
|
131
|
-
})
|
132
|
-
|
133
|
-
const client = createRouterClient<typeof router>({
|
134
|
-
baseURL: 'http://localhost:3000/orpc',
|
135
|
-
fetch: (...args) => {
|
136
|
-
const request = new Request(...args)
|
137
|
-
return handler({
|
138
|
-
prefix: '/orpc',
|
139
|
-
request,
|
140
|
-
context: {},
|
141
|
-
})
|
142
|
-
},
|
143
|
-
})
|
144
|
-
|
145
|
-
const now = new Date()
|
146
|
-
expect(await client.ping({ value: now })).toEqual(now)
|
147
|
-
})
|
148
|
-
})
|
package/src/router.ts
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
/// <reference lib="dom" />
|
2
|
-
|
3
|
-
import type {
|
4
|
-
ContractProcedure,
|
5
|
-
ContractRouter,
|
6
|
-
SchemaOutput,
|
7
|
-
} from '@orpc/contract'
|
8
|
-
import type { Procedure, Router } from '@orpc/server'
|
9
|
-
import type { Promisable } from '@orpc/shared'
|
10
|
-
import { createProcedureClient, type ProcedureClient } from './procedure'
|
11
|
-
|
12
|
-
export type RouterClientWithContractRouter<TRouter extends ContractRouter> = {
|
13
|
-
[K in keyof TRouter]: TRouter[K] extends ContractProcedure<
|
14
|
-
infer UInputSchema,
|
15
|
-
infer UOutputSchema
|
16
|
-
>
|
17
|
-
? ProcedureClient<UInputSchema, UOutputSchema, SchemaOutput<UOutputSchema>>
|
18
|
-
: TRouter[K] extends ContractRouter
|
19
|
-
? RouterClientWithContractRouter<TRouter[K]>
|
20
|
-
: never
|
21
|
-
}
|
22
|
-
|
23
|
-
export type RouterClientWithRouter<TRouter extends Router<any>> = {
|
24
|
-
[K in keyof TRouter]: TRouter[K] extends Procedure<
|
25
|
-
any,
|
26
|
-
any,
|
27
|
-
infer UInputSchema,
|
28
|
-
infer UOutputSchema,
|
29
|
-
infer UFuncOutput
|
30
|
-
>
|
31
|
-
? ProcedureClient<UInputSchema, UOutputSchema, UFuncOutput>
|
32
|
-
: TRouter[K] extends Router<any>
|
33
|
-
? RouterClientWithRouter<TRouter[K]>
|
34
|
-
: never
|
35
|
-
}
|
36
|
-
|
37
|
-
export interface CreateRouterClientOptions {
|
38
|
-
/**
|
39
|
-
* The base url of the server.
|
40
|
-
*/
|
41
|
-
baseURL: string
|
42
|
-
|
43
|
-
/**
|
44
|
-
* The fetch function used to make the request.
|
45
|
-
* @default global fetch
|
46
|
-
*/
|
47
|
-
fetch?: typeof fetch
|
48
|
-
|
49
|
-
/**
|
50
|
-
* The headers used to make the request.
|
51
|
-
* Invoked before the request is made.
|
52
|
-
*/
|
53
|
-
headers?: (input: unknown) => Promisable<Headers | Record<string, string>>
|
54
|
-
|
55
|
-
/**
|
56
|
-
* This used for internal purpose only.
|
57
|
-
*
|
58
|
-
* @internal
|
59
|
-
*/
|
60
|
-
path?: string[]
|
61
|
-
}
|
62
|
-
|
63
|
-
export function createRouterClient<
|
64
|
-
TRouter extends Router<any> | ContractRouter,
|
65
|
-
>(
|
66
|
-
options: CreateRouterClientOptions,
|
67
|
-
): TRouter extends Router<any>
|
68
|
-
? RouterClientWithRouter<TRouter>
|
69
|
-
: TRouter extends ContractRouter
|
70
|
-
? RouterClientWithContractRouter<TRouter>
|
71
|
-
: never {
|
72
|
-
const path = options?.path ?? []
|
73
|
-
|
74
|
-
const client = new Proxy(
|
75
|
-
createProcedureClient({
|
76
|
-
baseURL: options.baseURL,
|
77
|
-
fetch: options.fetch,
|
78
|
-
headers: options.headers,
|
79
|
-
path,
|
80
|
-
}),
|
81
|
-
{
|
82
|
-
get(target, key) {
|
83
|
-
if (typeof key !== 'string') {
|
84
|
-
return Reflect.get(target, key)
|
85
|
-
}
|
86
|
-
|
87
|
-
return createRouterClient({
|
88
|
-
...options,
|
89
|
-
path: [...path, key],
|
90
|
-
})
|
91
|
-
},
|
92
|
-
},
|
93
|
-
)
|
94
|
-
|
95
|
-
return client as any
|
96
|
-
}
|