eden-tanstack-query 0.0.9 → 0.1.0-alpha.1
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 +69 -310
- package/dist/index.d.mts +84 -0
- package/dist/index.d.ts +75 -103
- package/dist/index.js +1 -226
- package/dist/index.mjs +1 -0
- package/package.json +59 -40
- package/src/index.ts +217 -0
- package/src/types.ts +178 -0
package/README.md
CHANGED
|
@@ -1,360 +1,119 @@
|
|
|
1
1
|
# eden-tanstack-query
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🔗 **Type-safe** - Full TypeScript inference from Elysia server types
|
|
8
|
-
- ⚡ **Framework-agnostic** - Works with React Query, Svelte Query, Solid Query, Vue Query
|
|
9
|
-
- 🎯 **queryOptions** - Reusable, type-safe query configurations
|
|
10
|
-
- 🔄 **mutationOptions** - Type-safe mutation configurations
|
|
11
|
-
- 🔑 **Query keys** - Auto-generated, type-safe query keys for cache operations
|
|
12
|
-
- ⚠️ **Error handling** - Configurable error throwing
|
|
13
|
-
- 🛠️ **Eden integration** - Seamlessly integrates with existing Treaty clients
|
|
3
|
+
TanStack Query integration for [Elysia Eden](https://github.com/elysiajs/eden) - type-safe queries and mutations with zero boilerplate.
|
|
14
4
|
|
|
15
5
|
## Installation
|
|
16
6
|
|
|
17
7
|
```bash
|
|
18
|
-
bun add eden-tanstack-query @tanstack/query-core
|
|
8
|
+
bun add eden-tanstack-query @elysiajs/eden @tanstack/query-core
|
|
9
|
+
# or
|
|
10
|
+
npm install eden-tanstack-query @elysiajs/eden @tanstack/query-core
|
|
19
11
|
```
|
|
20
12
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
### Setup
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { treaty } from '@elysiajs/eden/treaty2'
|
|
27
|
-
import { createEdenQuery } from 'eden-tanstack-query'
|
|
28
|
-
import { useQuery } from '@tanstack/svelte-query'
|
|
29
|
-
|
|
30
|
-
// Your Elysia app type
|
|
31
|
-
type App = {
|
|
32
|
-
users: {
|
|
33
|
-
get: {
|
|
34
|
-
query: { page?: number }
|
|
35
|
-
response: { users: User[] }
|
|
36
|
-
}
|
|
37
|
-
post: {
|
|
38
|
-
body: { name: string, email: string }
|
|
39
|
-
response: { user: User }
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
13
|
+
## Usage
|
|
43
14
|
|
|
44
|
-
|
|
45
|
-
|
|
15
|
+
```ts
|
|
16
|
+
import { createEdenTQ } from 'eden-tanstack-query'
|
|
17
|
+
import type { App } from './server' // Your Elysia app type
|
|
18
|
+
|
|
19
|
+
const eden = createEdenTQ<App>('http://localhost:3000')
|
|
46
20
|
```
|
|
47
21
|
|
|
48
22
|
### Queries
|
|
49
23
|
|
|
50
|
-
```
|
|
51
|
-
//
|
|
52
|
-
const query = useQuery(eden.users.get.queryOptions())
|
|
24
|
+
```ts
|
|
25
|
+
import { createQuery } from '@tanstack/svelte-query' // or react-query, vue-query, etc.
|
|
53
26
|
|
|
54
|
-
//
|
|
55
|
-
const query =
|
|
56
|
-
eden.users
|
|
27
|
+
// Fully type-safe, auto-generated query key
|
|
28
|
+
const query = createQuery(() =>
|
|
29
|
+
eden.users({ id: '123' }).get.queryOptions({
|
|
30
|
+
params: { id: '123' }
|
|
31
|
+
})
|
|
57
32
|
)
|
|
58
33
|
|
|
59
|
-
//
|
|
60
|
-
query.data?.users // Fully typed from your Elysia response
|
|
34
|
+
// query.data is typed as your Elysia response type!
|
|
61
35
|
```
|
|
62
36
|
|
|
63
37
|
### Mutations
|
|
64
38
|
|
|
65
|
-
```
|
|
66
|
-
import {
|
|
67
|
-
|
|
68
|
-
// Basic mutation
|
|
69
|
-
const mutation = useMutation(eden.users.post.mutationOptions())
|
|
70
|
-
|
|
71
|
-
// Using the mutation
|
|
72
|
-
mutation.mutate({ name: 'John', email: 'john@example.com' })
|
|
73
|
-
|
|
74
|
-
// Access the response
|
|
75
|
-
mutation.data?.user // Fully typed
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Query Keys
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
// Get type-safe query keys for cache operations
|
|
82
|
-
const usersKey = eden.users.get.queryKey()
|
|
83
|
-
|
|
84
|
-
// Invalidate queries
|
|
85
|
-
const queryClient = useQueryClient()
|
|
86
|
-
queryClient.invalidateQueries({ queryKey: usersKey })
|
|
87
|
-
|
|
88
|
-
// Get query data type-safely
|
|
89
|
-
const data = queryClient.getQueryData(eden.users.get.queryKey())
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Error Handling
|
|
93
|
-
|
|
94
|
-
### Global Error Handler
|
|
95
|
-
|
|
96
|
-
Define error handling logic once when creating the client:
|
|
39
|
+
```ts
|
|
40
|
+
import { createMutation } from '@tanstack/svelte-query'
|
|
97
41
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const eden = createEdenQuery<App>('http://localhost:8080', {
|
|
102
|
-
throwOnError: true,
|
|
103
|
-
onError: ({ error, path, method, type }: EdenErrorContext) => {
|
|
104
|
-
// Runs for ALL queries and mutations before throwing
|
|
105
|
-
|
|
106
|
-
if (error.status === 401) {
|
|
107
|
-
authStore.logout()
|
|
108
|
-
router.push('/login')
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (error.status === 403) {
|
|
112
|
-
toast.error('Not authorized')
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (error.status >= 500) {
|
|
116
|
-
toast.error('Server error, please try again')
|
|
117
|
-
logger.error('API Error', { path, method, error })
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
})
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
The `EdenErrorContext` provides:
|
|
124
|
-
- `error` - The `EdenFetchError` with status and value
|
|
125
|
-
- `queryKey` - The generated query key
|
|
126
|
-
- `method` - HTTP method ('get', 'post', etc.)
|
|
127
|
-
- `path` - API path segments (['users', 'posts'])
|
|
128
|
-
- `input` - The request input
|
|
129
|
-
- `type` - Either 'query' or 'mutation'
|
|
130
|
-
|
|
131
|
-
### Throw on Error (Default)
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
const eden = createEdenQuery<App>('http://localhost:8080', {
|
|
135
|
-
throwOnError: true
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
// Per-query error handling (in addition to global handler)
|
|
139
|
-
useQuery(eden.users.get.queryOptions(undefined, {
|
|
140
|
-
onError: (error: EdenFetchError) => {
|
|
141
|
-
// Runs after global handler, only for this query
|
|
142
|
-
if (error.status === 404) {
|
|
143
|
-
// Handle not found specifically for this query
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}))
|
|
147
|
-
```
|
|
42
|
+
const mutation = createMutation(() =>
|
|
43
|
+
eden.users.post.mutationOptions()
|
|
44
|
+
)
|
|
148
45
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const eden = createEdenQuery<App>('http://localhost:8080', {
|
|
153
|
-
throwOnError: (queryKey, status) => {
|
|
154
|
-
// Don't throw on 404 (not found)
|
|
155
|
-
if (status === 404) return false
|
|
156
|
-
// Throw on server errors
|
|
157
|
-
if (status >= 500) return true
|
|
158
|
-
return false
|
|
159
|
-
}
|
|
46
|
+
// Type-safe variables
|
|
47
|
+
mutation.mutate({
|
|
48
|
+
body: { name: 'Alice', email: 'alice@example.com' }
|
|
160
49
|
})
|
|
161
50
|
```
|
|
162
51
|
|
|
163
|
-
###
|
|
164
|
-
|
|
165
|
-
When `throwOnError` is `true` (the default), errors are thrown before reaching callbacks like `select` and `onSuccess`. The library automatically narrows the data type to exclude error shapes:
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
// Given an endpoint that returns:
|
|
169
|
-
// - Success: { users: User[] }
|
|
170
|
-
// - Error: { error: string }
|
|
171
|
-
|
|
172
|
-
// Default: throwOnError = true (or omitted)
|
|
173
|
-
const eden = createEdenQuery<App>('http://localhost:8080')
|
|
174
|
-
// OR explicitly:
|
|
175
|
-
const eden = createEdenQuery<App>('http://localhost:8080', { throwOnError: true })
|
|
176
|
-
|
|
177
|
-
useQuery(eden.users.get.queryOptions(undefined, {
|
|
178
|
-
select: (data) => {
|
|
179
|
-
// data: { users: User[] }
|
|
180
|
-
// Error shape is excluded - errors throw before reaching here
|
|
181
|
-
return data.users // No type guard needed
|
|
182
|
-
},
|
|
183
|
-
onSuccess: (data) => {
|
|
184
|
-
// data: { users: User[] }
|
|
185
|
-
console.log(data.users)
|
|
186
|
-
}
|
|
187
|
-
}))
|
|
188
|
-
|
|
189
|
-
// query.data type: { users: User[] } | undefined
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
When `throwOnError` is `false`, the full union type is preserved since errors don't throw:
|
|
52
|
+
### Invalidation
|
|
193
53
|
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
const eden = createEdenQuery<App>('http://localhost:8080', {
|
|
197
|
-
throwOnError: false
|
|
198
|
-
})
|
|
54
|
+
```ts
|
|
55
|
+
import { useQueryClient } from '@tanstack/svelte-query'
|
|
199
56
|
|
|
200
|
-
|
|
201
|
-
select: (data) => {
|
|
202
|
-
// data: { users: User[] } | { error: string }
|
|
203
|
-
// Must handle both cases since errors don't throw
|
|
204
|
-
if ('error' in data) return null
|
|
205
|
-
return data.users
|
|
206
|
-
},
|
|
207
|
-
onSuccess: (data) => {
|
|
208
|
-
// data: { users: User[] } | { error: string }
|
|
209
|
-
if ('error' in data) {
|
|
210
|
-
console.log('Error:', data.error)
|
|
211
|
-
} else {
|
|
212
|
-
console.log(data.users)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}))
|
|
216
|
-
|
|
217
|
-
// query.data type: { users: User[] } | { error: string } | undefined
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
When `throwOnError` is a function, the full union type is also preserved (since throwing is conditional):
|
|
57
|
+
const queryClient = useQueryClient()
|
|
221
58
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
throwOnError: (queryKey, status) => status >= 500
|
|
59
|
+
// Invalidate specific query
|
|
60
|
+
await eden.users({ id: '123' }).get.invalidate(queryClient, {
|
|
61
|
+
params: { id: '123' }
|
|
226
62
|
})
|
|
227
63
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// data: { users: User[] } | { error: string }
|
|
231
|
-
// Full union - some errors may not throw (e.g., 404)
|
|
232
|
-
if ('error' in data) return null
|
|
233
|
-
return data.users
|
|
234
|
-
}
|
|
235
|
-
}))
|
|
64
|
+
// Invalidate all queries for a route
|
|
65
|
+
await eden.users({ id: '123' }).get.invalidate(queryClient)
|
|
236
66
|
```
|
|
237
67
|
|
|
238
|
-
|
|
68
|
+
## API
|
|
239
69
|
|
|
240
|
-
|
|
70
|
+
### `createEdenTQ<App>(domain, config?)`
|
|
241
71
|
|
|
242
|
-
|
|
243
|
-
- `NarrowedData` type correctly excludes error shapes
|
|
244
|
-
- `queryFn` return type is narrowed at the library level
|
|
245
|
-
- Query keys are correctly typed
|
|
246
|
-
- Direct access to options properties
|
|
72
|
+
Creates a type-safe Eden client with TanStack Query helpers.
|
|
247
73
|
|
|
248
|
-
|
|
249
|
-
- `
|
|
250
|
-
- `query.data` may show as `unknown` or full union in some cases
|
|
74
|
+
- `domain`: Your API URL or Elysia app instance
|
|
75
|
+
- `config.queryKeyPrefix`: Custom prefix for query keys (default: `['eden']`)
|
|
251
76
|
|
|
252
|
-
|
|
77
|
+
### Method Helpers
|
|
253
78
|
|
|
254
|
-
|
|
255
|
-
// 1. Use select to transform with explicit types
|
|
256
|
-
useQuery(eden.users.get.queryOptions(undefined, {
|
|
257
|
-
select: (data) => data.users // data is narrowed here
|
|
258
|
-
}))
|
|
79
|
+
Each HTTP method (`get`, `post`, `put`, `delete`, `patch`) has:
|
|
259
80
|
|
|
260
|
-
|
|
261
|
-
|
|
81
|
+
- `.queryOptions(input, overrides?)` - Returns `{ queryKey, queryFn }`
|
|
82
|
+
- `.mutationOptions(overrides?)` - Returns `{ mutationKey, mutationFn }`
|
|
83
|
+
- `.queryKey(input?)` - Returns the query key
|
|
84
|
+
- `.mutationKey(input?)` - Returns the mutation key
|
|
85
|
+
- `.invalidate(queryClient, input?, exact?)` - Invalidates matching queries
|
|
262
86
|
|
|
263
|
-
|
|
264
|
-
const options = eden.users.get.queryOptions()
|
|
265
|
-
const data = await options.queryFn() // Correctly typed
|
|
266
|
-
```
|
|
87
|
+
## Before / After
|
|
267
88
|
|
|
268
|
-
|
|
89
|
+
### Before (manual boilerplate)
|
|
269
90
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
useQuery(eden.users.get.queryOptions(
|
|
281
|
-
{ query: { page: 1 } },
|
|
282
|
-
{
|
|
283
|
-
eden: {
|
|
284
|
-
headers: { 'X-Custom': 'value' }
|
|
91
|
+
```ts
|
|
92
|
+
export function createUserQuery(userId: string) {
|
|
93
|
+
return createQuery<User>(() => ({
|
|
94
|
+
queryKey: ['users', userId],
|
|
95
|
+
queryFn: async () => {
|
|
96
|
+
const { data, error } = await api.users({ id: userId }).get()
|
|
97
|
+
if (error) throw error
|
|
98
|
+
return data as User // Manual cast!
|
|
285
99
|
},
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
))
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Query Key Prefix
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
const eden = createEdenQuery<App>('http://localhost:8080', {
|
|
295
|
-
queryKeyPrefix: 'my-api'
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
// Keys will be prefixed: ['my-api', 'users', 'get']
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Using with React Query
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
305
|
-
|
|
306
|
-
const query = useQuery(eden.users.get.queryOptions())
|
|
307
|
-
const mutation = useMutation(eden.users.post.mutationOptions())
|
|
308
|
-
const queryClient = useQueryClient()
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Using with Solid Query
|
|
312
|
-
|
|
313
|
-
```typescript
|
|
314
|
-
import { createQuery, createMutation } from '@tanstack/solid-query'
|
|
315
|
-
|
|
316
|
-
const query = createQuery(() => eden.users.get.queryOptions())
|
|
317
|
-
const mutation = createMutation(() => eden.users.post.mutationOptions())
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### Using with Vue Query
|
|
321
|
-
|
|
322
|
-
```typescript
|
|
323
|
-
import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query'
|
|
324
|
-
|
|
325
|
-
const query = useQuery(eden.users.get.queryOptions())
|
|
326
|
-
const mutation = useMutation(eden.users.post.mutationOptions())
|
|
327
|
-
const queryClient = useQueryClient()
|
|
100
|
+
}))
|
|
101
|
+
}
|
|
328
102
|
```
|
|
329
103
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
Query keys are auto-generated from your API paths:
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
// Simple path
|
|
336
|
-
eden.users.get.queryKey()
|
|
337
|
-
// → ['users', 'get']
|
|
338
|
-
|
|
339
|
-
// Path with parameters
|
|
340
|
-
eden.users({ id: '123' }).get.queryKey()
|
|
341
|
-
// → ['users', { id: '123' }, 'get']
|
|
104
|
+
### After (with eden-tanstack-query)
|
|
342
105
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
106
|
+
```ts
|
|
107
|
+
export function createUserQuery(userId: string) {
|
|
108
|
+
return createQuery(() =>
|
|
109
|
+
eden.users({ id: userId }).get.queryOptions({
|
|
110
|
+
params: { id: userId }
|
|
111
|
+
})
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
// Types are inferred from your Elysia server!
|
|
346
115
|
```
|
|
347
116
|
|
|
348
|
-
## Type Safety
|
|
349
|
-
|
|
350
|
-
All types are fully inferred from your Elysia server:
|
|
351
|
-
|
|
352
|
-
- ✅ Query data type (from success responses)
|
|
353
|
-
- ✅ Error type (from EdenFetchError or Treaty response)
|
|
354
|
-
- ✅ Input validation (query params, body)
|
|
355
|
-
- ✅ Query keys (type-safe, auto-generated)
|
|
356
|
-
- ✅ Framework-agnostic (works with all TanStack Query variants)
|
|
357
|
-
|
|
358
117
|
## License
|
|
359
118
|
|
|
360
119
|
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Elysia, ELYSIA_FORM_DATA } from 'elysia';
|
|
2
|
+
import { Treaty } from '@elysiajs/eden/treaty2';
|
|
3
|
+
import { QueryKey, QueryClient } from '@tanstack/query-core';
|
|
4
|
+
export { QueryClient, QueryKey } from '@tanstack/query-core';
|
|
5
|
+
|
|
6
|
+
type IsNever<T> = [T] extends [never] ? true : false;
|
|
7
|
+
type Prettify<T> = {
|
|
8
|
+
[K in keyof T]: T[K];
|
|
9
|
+
} & {};
|
|
10
|
+
type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc['length']]>;
|
|
11
|
+
type IntegerRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
|
|
12
|
+
type SuccessCodeRange = IntegerRange<200, 300>;
|
|
13
|
+
type ExtractData<Res extends Record<number, unknown>> = Res[Extract<keyof Res, SuccessCodeRange>] extends {
|
|
14
|
+
[ELYSIA_FORM_DATA]: infer Data;
|
|
15
|
+
} ? Data : Res[Extract<keyof Res, SuccessCodeRange>];
|
|
16
|
+
type ExtractError<Res extends Record<number, unknown>> = Exclude<keyof Res, SuccessCodeRange> extends never ? {
|
|
17
|
+
status: unknown;
|
|
18
|
+
value: unknown;
|
|
19
|
+
} : {
|
|
20
|
+
[Status in keyof Res]: {
|
|
21
|
+
status: Status;
|
|
22
|
+
value: Res[Status] extends {
|
|
23
|
+
[ELYSIA_FORM_DATA]: infer Data;
|
|
24
|
+
} ? Data : Res[Status];
|
|
25
|
+
};
|
|
26
|
+
}[Exclude<keyof Res, SuccessCodeRange>];
|
|
27
|
+
interface TQParamBase {
|
|
28
|
+
fetch?: RequestInit;
|
|
29
|
+
}
|
|
30
|
+
type SerializeQueryParams<T> = T extends Record<string, any> ? {
|
|
31
|
+
[K in keyof T]: T[K] extends Date ? string : T[K] extends Date | undefined ? string | undefined : T[K];
|
|
32
|
+
} : T;
|
|
33
|
+
type IsEmptyObject<T> = T extends Record<string, never> ? [keyof T] extends [never] ? true : false : false;
|
|
34
|
+
type MaybeEmptyObject<T, K extends PropertyKey> = [T] extends [never] ? {} : [T] extends [undefined] ? {
|
|
35
|
+
[P in K]?: T;
|
|
36
|
+
} : IsEmptyObject<T> extends true ? {
|
|
37
|
+
[P in K]?: T;
|
|
38
|
+
} : undefined extends T ? {
|
|
39
|
+
[P in K]?: T;
|
|
40
|
+
} : {
|
|
41
|
+
[P in K]: T;
|
|
42
|
+
};
|
|
43
|
+
type TQMethodParam<Body, Headers, Query, Params> = MaybeEmptyObject<Headers, 'headers'> & MaybeEmptyObject<SerializeQueryParams<Query>, 'query'> & MaybeEmptyObject<Params, 'params'> & MaybeEmptyObject<Body, 'body'> & TQParamBase;
|
|
44
|
+
interface EdenQueryOptions<TData = unknown, TError = unknown> {
|
|
45
|
+
queryKey: QueryKey;
|
|
46
|
+
queryFn: () => Promise<TData>;
|
|
47
|
+
}
|
|
48
|
+
interface EdenMutationOptions<TData = unknown, TError = unknown, TVariables = unknown> {
|
|
49
|
+
mutationKey: QueryKey;
|
|
50
|
+
mutationFn: (variables: TVariables) => Promise<TData>;
|
|
51
|
+
}
|
|
52
|
+
interface EdenTQMethod<Body, Headers, Query, Params, Res extends Record<number, unknown>> {
|
|
53
|
+
<TQueryFnData = ExtractData<Res>>(input: TQMethodParam<Body, Headers, Query, Params>, options?: RequestInit): Promise<Treaty.TreatyResponse<Res>>;
|
|
54
|
+
queryKey(input?: TQMethodParam<Body, Headers, Query, Params>): QueryKey;
|
|
55
|
+
queryOptions<TData = ExtractData<Res>>(input: TQMethodParam<Body, Headers, Query, Params>, overrides?: Partial<EdenQueryOptions<TData, ExtractError<Res>>>): EdenQueryOptions<TData, ExtractError<Res>>;
|
|
56
|
+
mutationKey(input?: TQMethodParam<Body, Headers, Query, Params>): QueryKey;
|
|
57
|
+
mutationOptions<TData = ExtractData<Res>>(overrides?: Partial<EdenMutationOptions<TData, ExtractError<Res>, TQMethodParam<Body, Headers, Query, Params>>>): EdenMutationOptions<TData, ExtractError<Res>, TQMethodParam<Body, Headers, Query, Params>>;
|
|
58
|
+
invalidate(queryClient: QueryClient, input?: TQMethodParam<Body, Headers, Query, Params>, exact?: boolean): Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
declare namespace EdenTQ {
|
|
61
|
+
export type Config = Treaty.Config & {
|
|
62
|
+
queryKeyPrefix?: QueryKey;
|
|
63
|
+
};
|
|
64
|
+
export type Create<App extends Elysia<any, any, any, any, any, any, any>> = App extends {
|
|
65
|
+
'~Routes': infer Schema extends Record<any, any>;
|
|
66
|
+
} ? Prettify<Sign<Schema>> & CreateParams<Schema> : 'Please install Elysia before using Eden';
|
|
67
|
+
export type Sign<in out Route extends Record<any, any>> = {
|
|
68
|
+
[K in keyof Route as K extends `:${string}` ? never : K]: Route[K] extends {
|
|
69
|
+
body: infer Body;
|
|
70
|
+
headers: infer Headers;
|
|
71
|
+
params: infer Params;
|
|
72
|
+
query: infer Query;
|
|
73
|
+
response: infer Res extends Record<number, unknown>;
|
|
74
|
+
} ? EdenTQMethod<Body, Headers, Query, Params, Res> : CreateParams<Route[K]>;
|
|
75
|
+
};
|
|
76
|
+
type CreateParams<Route extends Record<string, any>> = Extract<keyof Route, `:${string}`> extends infer Path extends string ? IsNever<Path> extends true ? Prettify<Sign<Route>> : (((params: {
|
|
77
|
+
[param in Path extends `:${infer Param}` ? Param extends `${infer P}?` ? P : Param : never]: string | number;
|
|
78
|
+
}) => Prettify<Sign<Route[Path]>> & CreateParams<Route[Path]>) & Prettify<Sign<Route>>) & (Path extends `:${string}?` ? CreateParams<Route[Path]> : {}) : never;
|
|
79
|
+
export { };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare function createEdenTQ<const App extends Elysia<any, any, any, any, any, any, any>>(domain: string | App, config?: EdenTQ.Config): EdenTQ.Create<App>;
|
|
83
|
+
|
|
84
|
+
export { type EdenMutationOptions, type EdenQueryOptions, EdenTQ, createEdenTQ };
|