@elysiajs/eden 0.3.0-exp-230224.1831 → 0.3.0-rc.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/.eslintrc +23 -0
- package/dist/fetch/index.d.ts +4 -0
- package/dist/fetch/types.d.ts +26 -0
- package/dist/fetch.d.ts +1 -0
- package/dist/fetch.js +1 -0
- package/dist/fetch.mjs +33 -0
- package/dist/fn/index.d.ts +4 -0
- package/dist/fn/types.d.ts +24 -0
- package/dist/fn/utils.d.ts +13 -0
- package/dist/fn.d.ts +1 -0
- package/dist/fn.js +1 -0
- package/dist/fn.mjs +80 -0
- package/dist/index.d.ts +3 -15
- package/dist/index.js +1 -1
- package/dist/index.mjs +7 -197
- package/dist/treaty/index.d.ts +16 -0
- package/dist/treaty/types.d.ts +57 -0
- package/dist/treaty/utils.d.ts +1 -0
- package/dist/treaty.d.ts +1 -0
- package/dist/treaty.js +1 -0
- package/dist/treaty.mjs +111 -0
- package/dist/types.d.ts +18 -81
- package/dist/utils-0d2b8b1a.mjs +8 -0
- package/dist/utils-0d7d9b21.js +1 -0
- package/dist/utils.d.ts +0 -14
- package/package.json +29 -6
- package/src/fetch/index.ts +55 -0
- package/src/fetch/types.ts +53 -0
- package/src/fn/index.ts +53 -0
- package/src/fn/types.ts +45 -0
- package/src/fn/utils.ts +86 -0
- package/src/index.ts +34 -253
- package/src/treaty/index.ts +192 -0
- package/src/treaty/types.ts +140 -0
- package/src/treaty/utils.ts +15 -0
- package/src/types.ts +40 -201
- package/src/utils.ts +0 -105
- package/dist/index.umd.js +0 -1
package/src/index.ts
CHANGED
|
@@ -1,253 +1,34 @@
|
|
|
1
|
-
import type { Elysia
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
on<K extends keyof WebSocketEventMap>(
|
|
37
|
-
type: K,
|
|
38
|
-
listener: (event: EdenWSEvent<K, Schema['response']>) => void,
|
|
39
|
-
options?: boolean | AddEventListenerOptions
|
|
40
|
-
) {
|
|
41
|
-
return this.addEventListener(type, listener, options)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
off<K extends keyof WebSocketEventMap>(
|
|
45
|
-
type: K,
|
|
46
|
-
listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,
|
|
47
|
-
options?: boolean | EventListenerOptions
|
|
48
|
-
) {
|
|
49
|
-
this.ws.removeEventListener(type, listener, options)
|
|
50
|
-
|
|
51
|
-
return this
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
addEventListener<K extends keyof WebSocketEventMap>(
|
|
55
|
-
type: K,
|
|
56
|
-
listener: (event: EdenWSEvent<K, Schema['response']>) => void,
|
|
57
|
-
options?: boolean | AddEventListenerOptions
|
|
58
|
-
) {
|
|
59
|
-
this.ws.addEventListener(
|
|
60
|
-
type,
|
|
61
|
-
(ws) => {
|
|
62
|
-
if (type === 'message') {
|
|
63
|
-
let data = (ws as MessageEvent).data.toString() as any
|
|
64
|
-
const start = data.charCodeAt(0)
|
|
65
|
-
|
|
66
|
-
if (start === 47 || start === 123)
|
|
67
|
-
try {
|
|
68
|
-
data = JSON.parse(data)
|
|
69
|
-
} catch {}
|
|
70
|
-
else if (!Number.isNaN(+data)) data = +data
|
|
71
|
-
else if (data === 'true') data = true
|
|
72
|
-
else if (data === 'fase') data = false
|
|
73
|
-
|
|
74
|
-
// @ts-ignore
|
|
75
|
-
listener({
|
|
76
|
-
...ws,
|
|
77
|
-
data
|
|
78
|
-
})
|
|
79
|
-
} else {
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
listener(ws)
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
options
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
return this
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
removeEventListener<K extends keyof WebSocketEventMap>(
|
|
91
|
-
type: K,
|
|
92
|
-
listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,
|
|
93
|
-
options?: boolean | EventListenerOptions
|
|
94
|
-
) {
|
|
95
|
-
this.off(type, listener, options)
|
|
96
|
-
|
|
97
|
-
return this
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
close() {
|
|
101
|
-
this.ws.close()
|
|
102
|
-
|
|
103
|
-
return this
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const createFn = (
|
|
108
|
-
domain: string,
|
|
109
|
-
procedure: string[],
|
|
110
|
-
signal: Signal
|
|
111
|
-
): Record<string, unknown> =>
|
|
112
|
-
// @ts-ignore
|
|
113
|
-
new Proxy((...v: any[]) => {}, {
|
|
114
|
-
get(target, key, value) {
|
|
115
|
-
return createFn(domain, [...procedure, key as string], signal)
|
|
116
|
-
},
|
|
117
|
-
apply(target, _, params) {
|
|
118
|
-
const param = params[0]
|
|
119
|
-
|
|
120
|
-
if (procedure.length === 1) {
|
|
121
|
-
if (
|
|
122
|
-
procedure[0] in Object.prototype ||
|
|
123
|
-
procedure[0] in Promise.prototype
|
|
124
|
-
)
|
|
125
|
-
return target(params)
|
|
126
|
-
|
|
127
|
-
switch (procedure[0]) {
|
|
128
|
-
case 'toJSON':
|
|
129
|
-
return target(params)
|
|
130
|
-
|
|
131
|
-
case '$set':
|
|
132
|
-
return signal.setConfig(param)
|
|
133
|
-
|
|
134
|
-
case '$clone':
|
|
135
|
-
return createFn(domain, [], signal.clone(param))
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return signal.run(procedure, params).then((result) => {
|
|
140
|
-
if (result instanceof Error) throw result
|
|
141
|
-
|
|
142
|
-
return result
|
|
143
|
-
})
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
const createProxy = (
|
|
148
|
-
domain: string,
|
|
149
|
-
path: string = '',
|
|
150
|
-
config: EdenConfig
|
|
151
|
-
): Record<string, unknown> =>
|
|
152
|
-
new Proxy(() => {}, {
|
|
153
|
-
get(target, key, value) {
|
|
154
|
-
return createProxy(domain, `${path}/${key.toString()}`, config)
|
|
155
|
-
},
|
|
156
|
-
apply(
|
|
157
|
-
target,
|
|
158
|
-
_,
|
|
159
|
-
[
|
|
160
|
-
{ $query, $fetch, $body, ...bodyObj } = {
|
|
161
|
-
$fetch: undefined,
|
|
162
|
-
$query: undefined,
|
|
163
|
-
$body: undefined
|
|
164
|
-
}
|
|
165
|
-
]: EdenCall[] = [{}]
|
|
166
|
-
) {
|
|
167
|
-
const i = path.lastIndexOf('/'),
|
|
168
|
-
method = path.slice(i + 1),
|
|
169
|
-
url = composePath(domain, path.slice(0, i), $query)
|
|
170
|
-
|
|
171
|
-
if (method === 'subscribe')
|
|
172
|
-
return new EdenWS(
|
|
173
|
-
url.replace(
|
|
174
|
-
/^([^]+):\/\//,
|
|
175
|
-
url.startsWith('https://') ? 'wss://' : 'ws://'
|
|
176
|
-
)
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
const body =
|
|
180
|
-
$body ?? (Object.keys(bodyObj).length ? bodyObj : undefined)
|
|
181
|
-
const isObject = typeof body === 'object'
|
|
182
|
-
|
|
183
|
-
return fetch(url, {
|
|
184
|
-
method,
|
|
185
|
-
body: isObject ? JSON.stringify(body) : body,
|
|
186
|
-
...config.fetch,
|
|
187
|
-
...$fetch,
|
|
188
|
-
headers: body
|
|
189
|
-
? {
|
|
190
|
-
'content-type': isObject
|
|
191
|
-
? 'application/json'
|
|
192
|
-
: 'text/plain',
|
|
193
|
-
...config.fetch?.headers,
|
|
194
|
-
...$fetch?.['headers']
|
|
195
|
-
}
|
|
196
|
-
: undefined
|
|
197
|
-
}).then(async (res) => {
|
|
198
|
-
if (res.status > 300) {
|
|
199
|
-
let data
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
res.headers
|
|
203
|
-
.get('content-type')
|
|
204
|
-
?.includes('application/json')
|
|
205
|
-
)
|
|
206
|
-
try {
|
|
207
|
-
data = await res.json()
|
|
208
|
-
} catch (_) {
|
|
209
|
-
data = await res.text()
|
|
210
|
-
}
|
|
211
|
-
else data = await res.text()
|
|
212
|
-
|
|
213
|
-
return new EdenFetchError(res.status, data)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
res.headers
|
|
218
|
-
.get('content-type')
|
|
219
|
-
?.includes('application/json')
|
|
220
|
-
)
|
|
221
|
-
try {
|
|
222
|
-
return await res.json()
|
|
223
|
-
} catch (_) {
|
|
224
|
-
// if json is error then it's string
|
|
225
|
-
// flow down
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
let data = await res.text()
|
|
229
|
-
|
|
230
|
-
if (!Number.isNaN(+data)) return +data
|
|
231
|
-
if (data === 'true') return true
|
|
232
|
-
if (data === 'false') return false
|
|
233
|
-
|
|
234
|
-
return data
|
|
235
|
-
})
|
|
236
|
-
}
|
|
237
|
-
}) as unknown as Record<string, unknown>
|
|
238
|
-
|
|
239
|
-
export const eden = <App extends Elysia<any>>(
|
|
240
|
-
domain: string,
|
|
241
|
-
config: EdenConfig = {}
|
|
242
|
-
): Eden<App> =>
|
|
243
|
-
new Proxy(
|
|
244
|
-
{},
|
|
245
|
-
{
|
|
246
|
-
get(target, key) {
|
|
247
|
-
if (key === '$fn')
|
|
248
|
-
return createFn(domain, [], new Signal(domain, config))
|
|
249
|
-
|
|
250
|
-
return createProxy(domain, key as string, config)
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
) as any
|
|
1
|
+
import type { Elysia } from 'elysia'
|
|
2
|
+
|
|
3
|
+
import type { EdenTreaty } from './treaty'
|
|
4
|
+
import type { EdenFetch } from './fetch'
|
|
5
|
+
import type { EdenFn } from './fn'
|
|
6
|
+
|
|
7
|
+
export { edenTreaty } from './treaty'
|
|
8
|
+
export { edenFetch } from './fetch'
|
|
9
|
+
export { edenFn } from './fn'
|
|
10
|
+
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
// export const eden: Eden = (domain: string) => ({
|
|
13
|
+
// treaty(config) {
|
|
14
|
+
// return import('./treaty').then((x) => x.edenTreaty(domain, config))
|
|
15
|
+
// },
|
|
16
|
+
// fn(config) {
|
|
17
|
+
// return import('./fn').then((x) => x.edenFn(domain, config))
|
|
18
|
+
// },
|
|
19
|
+
// fetch(config) {
|
|
20
|
+
// return import('./fetch').then((x) => x.edenFetch(domain, config))
|
|
21
|
+
// }
|
|
22
|
+
// })
|
|
23
|
+
|
|
24
|
+
// type Eden = (domain: string) => {
|
|
25
|
+
// treaty<App extends Elysia<any>>(
|
|
26
|
+
// config?: EdenTreaty.Config
|
|
27
|
+
// ): EdenTreaty.Create<App>
|
|
28
|
+
|
|
29
|
+
// fetch<App extends Elysia<any>>(
|
|
30
|
+
// config?: EdenFetch.Config
|
|
31
|
+
// ): EdenFetch.Create<App>
|
|
32
|
+
|
|
33
|
+
// fn<App extends Elysia<any>>(config?: EdenFn.Config): EdenFn.Create<App>
|
|
34
|
+
// }
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import type { Elysia, TypedSchema } from 'elysia'
|
|
2
|
+
|
|
3
|
+
import { EdenFetchError } from '../utils'
|
|
4
|
+
|
|
5
|
+
import { composePath } from './utils'
|
|
6
|
+
import type { EdenTreaty } from './types'
|
|
7
|
+
|
|
8
|
+
export type { EdenTreaty } from './types'
|
|
9
|
+
|
|
10
|
+
export class EdenWS<Schema extends TypedSchema<any> = TypedSchema> {
|
|
11
|
+
ws: WebSocket
|
|
12
|
+
url: string
|
|
13
|
+
|
|
14
|
+
constructor(url: string) {
|
|
15
|
+
this.ws = new WebSocket(url)
|
|
16
|
+
this.url = url
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
send(data: Schema['body'] | Schema['body'][]) {
|
|
20
|
+
if (Array.isArray(data)) {
|
|
21
|
+
data.forEach((datum) => this.send(datum))
|
|
22
|
+
|
|
23
|
+
return this
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.ws.send(
|
|
27
|
+
typeof data === 'object' ? JSON.stringify(data) : data.toString()
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
return this
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
on<K extends keyof WebSocketEventMap>(
|
|
34
|
+
type: K,
|
|
35
|
+
listener: (event: EdenTreaty.WSEvent<K, Schema['response']>) => void,
|
|
36
|
+
options?: boolean | AddEventListenerOptions
|
|
37
|
+
) {
|
|
38
|
+
return this.addEventListener(type, listener, options)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
off<K extends keyof WebSocketEventMap>(
|
|
42
|
+
type: K,
|
|
43
|
+
listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,
|
|
44
|
+
options?: boolean | EventListenerOptions
|
|
45
|
+
) {
|
|
46
|
+
this.ws.removeEventListener(type, listener, options)
|
|
47
|
+
|
|
48
|
+
return this
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
addEventListener<K extends keyof WebSocketEventMap>(
|
|
52
|
+
type: K,
|
|
53
|
+
listener: (event: EdenTreaty.WSEvent<K, Schema['response']>) => void,
|
|
54
|
+
options?: boolean | AddEventListenerOptions
|
|
55
|
+
) {
|
|
56
|
+
this.ws.addEventListener(
|
|
57
|
+
type,
|
|
58
|
+
(ws) => {
|
|
59
|
+
if (type === 'message') {
|
|
60
|
+
let data = (ws as MessageEvent).data.toString() as any
|
|
61
|
+
const start = data.charCodeAt(0)
|
|
62
|
+
|
|
63
|
+
if (start === 47 || start === 123)
|
|
64
|
+
try {
|
|
65
|
+
data = JSON.parse(data)
|
|
66
|
+
} catch {}
|
|
67
|
+
else if (!Number.isNaN(+data)) data = +data
|
|
68
|
+
else if (data === 'true') data = true
|
|
69
|
+
else if (data === 'fase') data = false
|
|
70
|
+
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
listener({
|
|
73
|
+
...ws,
|
|
74
|
+
data
|
|
75
|
+
})
|
|
76
|
+
} else {
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
listener(ws)
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
options
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return this
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
removeEventListener<K extends keyof WebSocketEventMap>(
|
|
88
|
+
type: K,
|
|
89
|
+
listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,
|
|
90
|
+
options?: boolean | EventListenerOptions
|
|
91
|
+
) {
|
|
92
|
+
this.off(type, listener, options)
|
|
93
|
+
|
|
94
|
+
return this
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
close() {
|
|
98
|
+
this.ws.close()
|
|
99
|
+
|
|
100
|
+
return this
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const createProxy = (
|
|
105
|
+
domain: string,
|
|
106
|
+
path: string = '',
|
|
107
|
+
config: {}
|
|
108
|
+
): Record<string, unknown> =>
|
|
109
|
+
new Proxy(() => {}, {
|
|
110
|
+
get(target, key, value) {
|
|
111
|
+
return createProxy(domain, `${path}/${key.toString()}`, config)
|
|
112
|
+
},
|
|
113
|
+
apply(
|
|
114
|
+
target,
|
|
115
|
+
_,
|
|
116
|
+
[
|
|
117
|
+
{ $query, $fetch, $body, ...bodyObj } = {
|
|
118
|
+
$fetch: undefined,
|
|
119
|
+
$query: undefined,
|
|
120
|
+
$body: undefined
|
|
121
|
+
}
|
|
122
|
+
]: EdenTreaty.CallOption[] = [{}]
|
|
123
|
+
) {
|
|
124
|
+
const i = path.lastIndexOf('/'),
|
|
125
|
+
method = path.slice(i + 1),
|
|
126
|
+
url = composePath(domain, path.slice(0, i), $query)
|
|
127
|
+
|
|
128
|
+
if (method === 'subscribe')
|
|
129
|
+
return new EdenWS(
|
|
130
|
+
url.replace(
|
|
131
|
+
/^([^]+):\/\//,
|
|
132
|
+
url.startsWith('https://') ? 'wss://' : 'ws://'
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
const body =
|
|
137
|
+
$body ?? (Object.keys(bodyObj).length ? bodyObj : undefined)
|
|
138
|
+
const isObject = typeof body === 'object'
|
|
139
|
+
|
|
140
|
+
return fetch(url, {
|
|
141
|
+
method,
|
|
142
|
+
body: isObject ? JSON.stringify(body) : body,
|
|
143
|
+
// ...config.fetch,
|
|
144
|
+
...$fetch,
|
|
145
|
+
headers: body
|
|
146
|
+
? {
|
|
147
|
+
'content-type': isObject
|
|
148
|
+
? 'application/json'
|
|
149
|
+
: 'text/plain',
|
|
150
|
+
// ...config.fetch?.headers,
|
|
151
|
+
...$fetch?.['headers']
|
|
152
|
+
}
|
|
153
|
+
: undefined
|
|
154
|
+
}).then(async (res) => {
|
|
155
|
+
let data: Promise<unknown>
|
|
156
|
+
|
|
157
|
+
switch (res.headers.get('Content-Type')?.split(';')[0]) {
|
|
158
|
+
case 'application/json':
|
|
159
|
+
data = res.json()
|
|
160
|
+
break
|
|
161
|
+
|
|
162
|
+
default:
|
|
163
|
+
data = res.text().then((data) => {
|
|
164
|
+
if (!Number.isNaN(+data)) return +data
|
|
165
|
+
if (data === 'true') return true
|
|
166
|
+
if (data === 'false') return false
|
|
167
|
+
|
|
168
|
+
return data
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (res.status > 300)
|
|
173
|
+
return new EdenFetchError(res.status, await data)
|
|
174
|
+
|
|
175
|
+
return data
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
}) as unknown as Record<string, unknown>
|
|
179
|
+
|
|
180
|
+
export const edenTreaty = <App extends Elysia<any>>(
|
|
181
|
+
domain: string,
|
|
182
|
+
config: {} = {}
|
|
183
|
+
): EdenTreaty.Create<App> =>
|
|
184
|
+
new Proxy(
|
|
185
|
+
{},
|
|
186
|
+
{
|
|
187
|
+
get(target, key) {
|
|
188
|
+
return createProxy(domain, key as string, config)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
) as any
|
|
192
|
+
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { Elysia, SCHEMA, AnyTypedSchema } from 'elysia'
|
|
2
|
+
|
|
3
|
+
import type { EdenWS } from './index'
|
|
4
|
+
import type { IsNever, IsUnknown, MapError, UnionToIntersect } from '../types'
|
|
5
|
+
import { EdenFetchError } from '../utils'
|
|
6
|
+
|
|
7
|
+
export namespace EdenTreaty {
|
|
8
|
+
export type Create<App extends Elysia<any>> = App['meta'] extends Record<
|
|
9
|
+
typeof SCHEMA,
|
|
10
|
+
infer Schema extends Record<string, any>
|
|
11
|
+
>
|
|
12
|
+
? EdenTreaty.Sign<Schema>
|
|
13
|
+
: 'Please install Elysia before using Eden'
|
|
14
|
+
|
|
15
|
+
export interface Config {}
|
|
16
|
+
|
|
17
|
+
export type Sign<A> = {
|
|
18
|
+
[Path in keyof A as Path extends `/${infer Prefix}/${infer _}`
|
|
19
|
+
? Prefix
|
|
20
|
+
: Path extends `/`
|
|
21
|
+
? 'index'
|
|
22
|
+
: Path extends `/${infer Prefix}`
|
|
23
|
+
? Prefix
|
|
24
|
+
: never]: UnionToIntersect<
|
|
25
|
+
Path extends `/${infer _}/${infer Rest}`
|
|
26
|
+
? NestPath<
|
|
27
|
+
Rest,
|
|
28
|
+
{
|
|
29
|
+
[Method in keyof A[Path]]: A[Path][Method] extends infer Route extends AnyTypedSchema
|
|
30
|
+
? Method extends 'subscribe'
|
|
31
|
+
? undefined extends Route['query']
|
|
32
|
+
? (params?: {
|
|
33
|
+
$query?: Record<string, string>
|
|
34
|
+
}) => EdenWS<Route>
|
|
35
|
+
: undefined extends Route['query']
|
|
36
|
+
? (params: {
|
|
37
|
+
$query: Route['query']
|
|
38
|
+
}) => EdenWS<Route>
|
|
39
|
+
: (params?: {
|
|
40
|
+
$query?: Record<string, string>
|
|
41
|
+
}) => EdenWS<Route>
|
|
42
|
+
: IsUnknown<Route['body']> extends true
|
|
43
|
+
? (params?: {
|
|
44
|
+
$query?: Record<string, string>
|
|
45
|
+
$fetch?: RequestInit
|
|
46
|
+
}) =>
|
|
47
|
+
| Promise<Route['response']['200']>
|
|
48
|
+
| (MapError<
|
|
49
|
+
Route['response']
|
|
50
|
+
> extends infer Errors
|
|
51
|
+
? IsNever<Errors> extends true
|
|
52
|
+
? EdenFetchError<
|
|
53
|
+
number,
|
|
54
|
+
string
|
|
55
|
+
>
|
|
56
|
+
: Errors
|
|
57
|
+
: never)
|
|
58
|
+
: (
|
|
59
|
+
params: Route['body'] & {
|
|
60
|
+
$query?: Record<string, string>
|
|
61
|
+
$fetch?: RequestInit
|
|
62
|
+
}
|
|
63
|
+
) => Promise<
|
|
64
|
+
Route['response'] extends {
|
|
65
|
+
200: infer ReturnedType
|
|
66
|
+
}
|
|
67
|
+
? ReturnedType
|
|
68
|
+
: unknown
|
|
69
|
+
>
|
|
70
|
+
: never
|
|
71
|
+
}
|
|
72
|
+
>
|
|
73
|
+
: {
|
|
74
|
+
[Method in keyof A[Path]]: A[Path][Method] extends infer Route extends AnyTypedSchema
|
|
75
|
+
? Method extends 'subscribe'
|
|
76
|
+
? IsUnknown<Route['query']> extends true
|
|
77
|
+
? (params?: {
|
|
78
|
+
$query?: Record<string, string>
|
|
79
|
+
}) => EdenWS<Route>
|
|
80
|
+
: undefined extends Route['query']
|
|
81
|
+
? (params: {
|
|
82
|
+
$query: Route['query']
|
|
83
|
+
}) => EdenWS<Route>
|
|
84
|
+
: (params?: {
|
|
85
|
+
$query?: Record<string, string>
|
|
86
|
+
}) => EdenWS<Route>
|
|
87
|
+
: IsUnknown<Route['body']> extends true
|
|
88
|
+
? (params?: {
|
|
89
|
+
$query?: Record<string, string>
|
|
90
|
+
$fetch?: RequestInit
|
|
91
|
+
}) =>
|
|
92
|
+
| Promise<Route['response']['200']>
|
|
93
|
+
| (MapError<
|
|
94
|
+
Route['response']
|
|
95
|
+
> extends infer Errors
|
|
96
|
+
? IsNever<Errors> extends true
|
|
97
|
+
? EdenFetchError<number, string>
|
|
98
|
+
: Errors
|
|
99
|
+
: never)
|
|
100
|
+
: (
|
|
101
|
+
params: Route['body'] & {
|
|
102
|
+
$query?: Record<string, string>
|
|
103
|
+
$fetch?: RequestInit
|
|
104
|
+
}
|
|
105
|
+
) => Promise<
|
|
106
|
+
Route['response'] extends {
|
|
107
|
+
200: infer ReturnedType
|
|
108
|
+
}
|
|
109
|
+
? ReturnedType
|
|
110
|
+
: unknown
|
|
111
|
+
>
|
|
112
|
+
: never
|
|
113
|
+
}
|
|
114
|
+
>
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface OnMessage<Data = unknown> extends MessageEvent {
|
|
118
|
+
data: Data
|
|
119
|
+
rawData: MessageEvent['data']
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export type WSEvent<
|
|
123
|
+
K extends keyof WebSocketEventMap,
|
|
124
|
+
Data = unknown
|
|
125
|
+
> = K extends 'message' ? OnMessage<Data> : WebSocketEventMap[K]
|
|
126
|
+
|
|
127
|
+
export interface CallOption {
|
|
128
|
+
[x: string]: any
|
|
129
|
+
$fetch?: RequestInit
|
|
130
|
+
$query?: Record<string, string>
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
type NestPath<T extends string, V> = T extends `${infer First}/${infer Rest}`
|
|
135
|
+
? First extends `:${infer Parameter}`
|
|
136
|
+
? Record<(string & {}) | `:${Parameter}`, NestPath<Rest, V>>
|
|
137
|
+
: Record<First, NestPath<Rest, V>>
|
|
138
|
+
: T extends `:${infer Parameter}`
|
|
139
|
+
? Record<(string & {}) | T, V>
|
|
140
|
+
: Record<T, V>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const composePath = (
|
|
2
|
+
domain: string,
|
|
3
|
+
path: string,
|
|
4
|
+
query: Record<string, string> | undefined
|
|
5
|
+
) => {
|
|
6
|
+
if (!domain.endsWith('/')) domain += '/'
|
|
7
|
+
if (path === 'index') path = ''
|
|
8
|
+
|
|
9
|
+
if (!query || !Object.keys(query).length) return `${domain}${path}`
|
|
10
|
+
|
|
11
|
+
let q = ''
|
|
12
|
+
for (const [key, value] of Object.entries(query)) q += `${key}=${value}&`
|
|
13
|
+
|
|
14
|
+
return `${domain}${path}?${q.slice(0, -1)}`
|
|
15
|
+
}
|