@tuyau/react-query 0.0.1-next.2 → 1.0.0-beta.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/build/index.d.ts +113 -262
- package/build/index.js +139 -236
- package/package.json +16 -16
package/build/index.d.ts
CHANGED
|
@@ -1,100 +1,111 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
1
|
+
import { SchemaEndpoint, RawRequestArgs, TuyauRegistry, InferTree, AdonisEndpoint, InferRoutes } from '@tuyau/core/types';
|
|
2
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
3
|
+
import { SkipToken, DataTag, QueryFilters, WithRequired as WithRequired$1, UseMutationOptions, InfiniteData, InfiniteQueryObserverOptions, DefinedInitialDataOptions, UndefinedInitialDataOptions, UnusedSkipTokenOptions, QueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { Tuyau } from '@tuyau/core/client';
|
|
5
5
|
|
|
6
|
+
type Response$2<E extends SchemaEndpoint> = E['types']['response'];
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* Decorate query endpoints with Tanstack queries abilities
|
|
8
9
|
*/
|
|
9
|
-
interface
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} | SkipToken, opts: DefinedTuyauQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): DefinedTuyauQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
|
|
14
|
-
<TData = UnionFromSuccessStatuses<EDef['response']>>(input: {
|
|
15
|
-
payload?: EDef['request'];
|
|
16
|
-
params?: TParams;
|
|
17
|
-
}, opts?: UnusedSkipTokenTuyauQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): UnusedSkipTokenTuyauQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
|
|
18
|
-
<TData = UnionFromSuccessStatuses<EDef['response']>>(input?: {
|
|
19
|
-
payload?: EDef['request'];
|
|
20
|
-
params?: TParams;
|
|
21
|
-
} | SkipToken, opts?: UndefinedTuyauQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): UndefinedTuyauQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
|
|
10
|
+
interface DecorateQueryFn<EDef extends SchemaEndpoint> {
|
|
11
|
+
queryOptions: TuyauReactQueryOptions<EDef>;
|
|
12
|
+
queryKey: (args?: RawRequestArgs<EDef>) => DataTag<TuyauQueryKey, Response$2<EDef>>;
|
|
13
|
+
queryFilter: (args?: RawRequestArgs<EDef>, filters?: QueryFilters<DataTag<TuyauQueryKey, Response$2<EDef>>>) => WithRequired$1<QueryFilters<DataTag<TuyauQueryKey, Response$2<EDef>>>, 'queryKey'>;
|
|
22
14
|
}
|
|
23
15
|
/**
|
|
24
|
-
*
|
|
16
|
+
* Type definition for query options with overloads for different scenarios
|
|
25
17
|
*/
|
|
26
|
-
interface
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
params?: TParams;
|
|
31
|
-
}) => DataTag<TuyauQueryKey, UnionFromSuccessStatuses<EDef['response']>, any>;
|
|
32
|
-
queryFilter: (input?: {
|
|
33
|
-
payload?: Partial<EDef['request']>;
|
|
34
|
-
params?: TParams;
|
|
35
|
-
}, filters?: QueryFilters<DataTag<TuyauQueryKey, UnionFromSuccessStatuses<EDef['response']>, any>>) => WithRequired<QueryFilters<DataTag<TuyauQueryKey, UnionFromSuccessStatuses<EDef['response']>, any>>, 'queryKey'>;
|
|
18
|
+
interface TuyauReactQueryOptions<EDef extends SchemaEndpoint> {
|
|
19
|
+
<TData = Response$2<EDef>>(input: RawRequestArgs<EDef> | SkipToken, opts: DefinedTuyauQueryOptionsIn<Response$2<EDef>, TData, unknown>): DefinedTuyauQueryOptionsOut<Response$2<EDef>, TData, unknown>;
|
|
20
|
+
<TData = Response$2<EDef>>(input: RawRequestArgs<EDef>, opts?: UnusedSkipTokenTuyauQueryOptionsIn<Response$2<EDef>, TData, unknown>): UnusedSkipTokenTuyauQueryOptionsOut<Response$2<EDef>, TData, unknown>;
|
|
21
|
+
<TData = Response$2<EDef>>(input?: RawRequestArgs<EDef> | SkipToken, opts?: UndefinedTuyauQueryOptionsIn<Response$2<EDef>, TData, unknown>): UndefinedTuyauQueryOptionsOut<Response$2<EDef>, TData, unknown>;
|
|
36
22
|
}
|
|
37
23
|
|
|
38
24
|
/**
|
|
39
|
-
*
|
|
25
|
+
* Omits the key without removing a potential union
|
|
26
|
+
*/
|
|
27
|
+
type DistributiveOmit<TObj, TKey extends keyof any> = TObj extends any ? Omit<TObj, TKey> : never;
|
|
28
|
+
/**
|
|
29
|
+
* Make certain keys required in a type
|
|
40
30
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
type WithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
32
|
+
|
|
33
|
+
type ReservedOptions = 'mutationKey' | 'mutationFn';
|
|
34
|
+
type Response$1<E extends SchemaEndpoint> = E['types']['response'];
|
|
35
|
+
interface TuyauMutationOptionsIn<TInput, TError, TOutput, TContext> extends DistributiveOmit<UseMutationOptions<TOutput, TError, TInput, TContext>, ReservedOptions>, TuyauQueryBaseOptions {
|
|
36
|
+
}
|
|
37
|
+
interface TuyauMutationOptionsOut<TInput, TError, TOutput, TContext> extends UseMutationOptions<TOutput, TError, TInput, TContext> {
|
|
38
|
+
mutationKey: TuyauMutationKey;
|
|
39
|
+
}
|
|
40
|
+
interface TuyauReactMutationOptions<TDef extends SchemaEndpoint> {
|
|
41
|
+
<TContext = unknown>(opts?: TuyauMutationOptionsIn<RawRequestArgs<TDef>, any, Response$1<TDef>, TContext>): TuyauMutationOptionsOut<RawRequestArgs<TDef>, any, Response$1<TDef>, TContext>;
|
|
42
|
+
}
|
|
43
|
+
declare function getMutationKeyInternal(options: {
|
|
44
|
+
segments: string[];
|
|
45
|
+
}): TuyauMutationKey;
|
|
46
|
+
interface DecorateMutationFn<EDef extends SchemaEndpoint> {
|
|
47
|
+
mutationOptions: TuyauReactMutationOptions<EDef>;
|
|
43
48
|
mutationKey: () => TuyauMutationKey;
|
|
44
49
|
}
|
|
50
|
+
interface TuyauMutationOptionsOptions {
|
|
51
|
+
opts?: TuyauMutationOptionsIn<any, any, any, any>;
|
|
52
|
+
routeName: string;
|
|
53
|
+
client: Tuyau<any>;
|
|
54
|
+
}
|
|
55
|
+
declare function tuyauMutationOptions(options: TuyauMutationOptionsOptions): _tanstack_react_query.WithRequired<UseMutationOptions<unknown, any, any, any>, "mutationKey">;
|
|
56
|
+
|
|
57
|
+
type Response<E extends SchemaEndpoint> = E['types']['response'];
|
|
45
58
|
/**
|
|
46
|
-
*
|
|
59
|
+
* Infinite query options input type
|
|
47
60
|
*/
|
|
48
|
-
interface
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
mutationKey: TuyauMutationKey;
|
|
61
|
+
interface TuyauInfiniteQueryOptionsIn<TQueryFnData, TError, TData> extends DistributiveOmit<InfiniteQueryObserverOptions<TQueryFnData, TError, TData>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'>, TuyauQueryBaseOptions {
|
|
62
|
+
/**
|
|
63
|
+
* The key that will be used for the page parameter in the request.
|
|
64
|
+
* For example, if your API expects ?page=1, set this to 'page'.
|
|
65
|
+
* If your API expects ?cursor=abc, set this to 'cursor'.
|
|
66
|
+
*/
|
|
67
|
+
pageParamKey?: string;
|
|
56
68
|
}
|
|
57
69
|
/**
|
|
58
|
-
*
|
|
70
|
+
* Infinite query options output type
|
|
59
71
|
*/
|
|
60
|
-
interface
|
|
61
|
-
|
|
72
|
+
interface TuyauInfiniteQueryOptionsOut<TQueryFnData, TError, TData> extends Omit<InfiniteQueryObserverOptions<TQueryFnData, TError, TData>, 'queryKey'> {
|
|
73
|
+
queryKey: DataTag<TuyauQueryKey, TData>;
|
|
62
74
|
}
|
|
63
|
-
|
|
64
75
|
/**
|
|
65
|
-
*
|
|
76
|
+
* Type definition for infinite query options
|
|
66
77
|
*/
|
|
67
|
-
|
|
78
|
+
interface TuyauReactInfiniteQueryOptions<EDef extends SchemaEndpoint> {
|
|
79
|
+
<TData = InfiniteData<Response<EDef>>>(input: RawRequestArgs<EDef> | SkipToken, opts: TuyauInfiniteQueryOptionsIn<Response<EDef>, unknown, TData>): TuyauInfiniteQueryOptionsOut<Response<EDef>, unknown, TData>;
|
|
80
|
+
<TData = InfiniteData<Response<EDef>>>(input?: RawRequestArgs<EDef> | SkipToken, opts?: TuyauInfiniteQueryOptionsIn<Response<EDef>, unknown, TData>): TuyauInfiniteQueryOptionsOut<Response<EDef>, unknown, TData>;
|
|
81
|
+
}
|
|
68
82
|
/**
|
|
69
|
-
*
|
|
83
|
+
* Decorate query endpoints with infinite query capabilities
|
|
70
84
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
interface DecorateInfiniteQueryFn<EDef extends SchemaEndpoint> {
|
|
86
|
+
infiniteQueryOptions: TuyauReactInfiniteQueryOptions<EDef>;
|
|
87
|
+
infiniteQueryKey: (args?: RawRequestArgs<EDef>) => DataTag<TuyauQueryKey, InfiniteData<Response<EDef>>>;
|
|
88
|
+
infiniteQueryFilter: (args?: RawRequestArgs<EDef>, filters?: QueryFilters<DataTag<TuyauQueryKey, InfiniteData<Response<EDef>>>>) => WithRequired$1<QueryFilters<DataTag<TuyauQueryKey, InfiniteData<Response<EDef>>>>, 'queryKey'>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Query type identifier
|
|
93
|
+
*/
|
|
94
|
+
type QueryType = 'any' | 'infinite' | 'query';
|
|
75
95
|
/**
|
|
76
96
|
* Tuyau-specific query key structure
|
|
77
97
|
*/
|
|
78
98
|
type TuyauQueryKey = [
|
|
79
99
|
readonly string[],
|
|
80
100
|
{
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
type?: 'infinite' | 'query';
|
|
101
|
+
request?: RawRequestArgs<any>;
|
|
102
|
+
type?: Exclude<QueryType, 'any'>;
|
|
84
103
|
}?
|
|
85
104
|
];
|
|
86
105
|
/**
|
|
87
106
|
* Tuyau-specific mutation key structure
|
|
88
107
|
*/
|
|
89
108
|
type TuyauMutationKey = [readonly string[]];
|
|
90
|
-
/**
|
|
91
|
-
* Omits the key without removing a potential union
|
|
92
|
-
*/
|
|
93
|
-
type DistributiveOmit<TObj, TKey extends keyof any> = TObj extends any ? Omit<TObj, TKey> : never;
|
|
94
|
-
/**
|
|
95
|
-
* Make certain keys required in a type
|
|
96
|
-
*/
|
|
97
|
-
type WithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
98
109
|
/**
|
|
99
110
|
* Query options with defined initial data
|
|
100
111
|
*/
|
|
@@ -113,57 +124,21 @@ interface UnusedSkipTokenTuyauQueryOptionsIn<TQueryFnData, TData, TError> extend
|
|
|
113
124
|
/**
|
|
114
125
|
* Output type for query options with defined initial data
|
|
115
126
|
*/
|
|
116
|
-
interface DefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends DefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey
|
|
127
|
+
interface DefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends DefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey> {
|
|
117
128
|
queryKey: DataTag<TuyauQueryKey, TData, TError>;
|
|
118
129
|
}
|
|
119
130
|
/**
|
|
120
131
|
* Output type for query options with undefined initial data
|
|
121
132
|
*/
|
|
122
|
-
interface UndefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UndefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey
|
|
133
|
+
interface UndefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UndefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey> {
|
|
123
134
|
queryKey: DataTag<TuyauQueryKey, TData, TError>;
|
|
124
135
|
}
|
|
125
136
|
/**
|
|
126
137
|
* Output type for query options with unused skip token
|
|
127
138
|
*/
|
|
128
|
-
interface UnusedSkipTokenTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UnusedSkipTokenOptions<TQueryFnData, TError, TData, TuyauQueryKey
|
|
139
|
+
interface UnusedSkipTokenTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UnusedSkipTokenOptions<TQueryFnData, TError, TData, TuyauQueryKey> {
|
|
129
140
|
queryKey: DataTag<TuyauQueryKey, TData, TError>;
|
|
130
141
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Input type for mutation options
|
|
133
|
-
*/
|
|
134
|
-
interface TuyauMutationOptionsIn<TInput, TError, TOutput, TContext, TParams = Record<string, string | number>> extends DistributiveOmit<UseMutationOptions<TOutput, TError, {
|
|
135
|
-
payload: TInput;
|
|
136
|
-
params?: TParams;
|
|
137
|
-
}, TContext>, 'mutationKey' | 'mutationFn'> {
|
|
138
|
-
/**
|
|
139
|
-
* Route parameters to be passed to the mutation
|
|
140
|
-
*/
|
|
141
|
-
params?: TParams;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Interface for router keyable decorators (pathKey, pathFilter)
|
|
145
|
-
*/
|
|
146
|
-
interface DecorateRouterKeyable {
|
|
147
|
-
pathKey: () => TuyauQueryKey;
|
|
148
|
-
pathFilter: (filters?: QueryFilters<TuyauQueryKey>) => WithRequired<QueryFilters<TuyauQueryKey>, 'queryKey'>;
|
|
149
|
-
}
|
|
150
|
-
interface TypeHelper<EDef extends EndpointDef> {
|
|
151
|
-
/**
|
|
152
|
-
* @internal
|
|
153
|
-
*/
|
|
154
|
-
'~types': {
|
|
155
|
-
request: EDef['request'];
|
|
156
|
-
response: EDef['response'];
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Infer request type from an endpoint
|
|
161
|
-
*/
|
|
162
|
-
type InferRequestType<Endpoint extends DecorateQueryFn<any> | DecorateMutationFn<any>> = Endpoint['~types']['request'];
|
|
163
|
-
/**
|
|
164
|
-
* Infer response type from an endpoint
|
|
165
|
-
*/
|
|
166
|
-
type InferResponseType<Endpoint extends DecorateQueryFn<any> | DecorateMutationFn<any>> = Endpoint['~types']['response']['200'];
|
|
167
142
|
/**
|
|
168
143
|
* Tuyau-specific request options for React Query integration
|
|
169
144
|
*/
|
|
@@ -177,180 +152,56 @@ interface TuyauReactRequestOptions {
|
|
|
177
152
|
* Base options for Tuyau queries
|
|
178
153
|
*/
|
|
179
154
|
interface TuyauQueryBaseOptions {
|
|
180
|
-
/**
|
|
181
|
-
* Tuyau-related options
|
|
182
|
-
*/
|
|
183
155
|
tuyau?: TuyauReactRequestOptions;
|
|
184
156
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
interface TuyauQueryOptionsResult {
|
|
189
|
-
tuyau: {
|
|
190
|
-
path: string[];
|
|
191
|
-
type: 'query';
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Reserved infinite query options that should not be overridden
|
|
197
|
-
*/
|
|
198
|
-
type InfiniteQueryReservedOptions = 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash';
|
|
199
|
-
/**
|
|
200
|
-
* Tuyau infinite data structure
|
|
201
|
-
*/
|
|
202
|
-
type TuyauInfiniteData<TData> = {
|
|
203
|
-
pages: TData[];
|
|
204
|
-
pageParams: unknown[];
|
|
205
|
-
};
|
|
206
|
-
/**
|
|
207
|
-
* Infinite query options with undefined initial data
|
|
208
|
-
*/
|
|
209
|
-
interface UndefinedTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError, TRequest, TPageParamKey extends keyof TRequest> extends DistributiveOmit<UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, ExtractPageParamType<TRequest, TPageParamKey> | null>, InfiniteQueryReservedOptions>, TuyauQueryBaseOptions {
|
|
210
|
-
pageParamKey: TPageParamKey;
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Infinite query options with defined initial data
|
|
214
|
-
*/
|
|
215
|
-
interface DefinedTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError, TRequest, TPageParamKey extends keyof TRequest> extends DistributiveOmit<DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, ExtractPageParamType<TRequest, TPageParamKey> | null>, InfiniteQueryReservedOptions>, TuyauQueryBaseOptions {
|
|
216
|
-
pageParamKey: TPageParamKey;
|
|
217
|
-
}
|
|
218
|
-
type ExtractPageParamType<TRequest, TPageParamKey extends keyof TRequest> = TRequest[TPageParamKey];
|
|
219
|
-
/**
|
|
220
|
-
* Infinite query options with unused skip token
|
|
221
|
-
*/
|
|
222
|
-
interface UnusedSkipTokenTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError, TRequest, TPageParamKey extends keyof TRequest> extends DistributiveOmit<UnusedSkipTokenInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, ExtractPageParamType<TRequest, TPageParamKey>>, InfiniteQueryReservedOptions>, TuyauQueryBaseOptions {
|
|
223
|
-
pageParamKey: TPageParamKey;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Output type for infinite query options with undefined initial data
|
|
227
|
-
*/
|
|
228
|
-
interface UndefinedTuyauInfiniteQueryOptionsOut<TQueryFnData, TData, TError> extends UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, unknown> {
|
|
229
|
-
queryKey: DataTag<TuyauQueryKey, TuyauInfiniteData<TData>, TError>;
|
|
230
|
-
tuyau: {
|
|
231
|
-
path: string[];
|
|
232
|
-
type: 'infinite';
|
|
233
|
-
};
|
|
157
|
+
interface DecorateRouterKeyable {
|
|
158
|
+
pathKey: () => TuyauQueryKey;
|
|
159
|
+
pathFilter: (filters?: QueryFilters<TuyauQueryKey>) => WithRequired<QueryFilters<TuyauQueryKey>, 'queryKey'>;
|
|
234
160
|
}
|
|
235
161
|
/**
|
|
236
|
-
*
|
|
162
|
+
* Keys that identify an endpoint-like structure
|
|
237
163
|
*/
|
|
238
|
-
|
|
239
|
-
queryKey: DataTag<TuyauQueryKey, TuyauInfiniteData<TData>, TError>;
|
|
240
|
-
tuyau: {
|
|
241
|
-
path: string[];
|
|
242
|
-
type: 'infinite';
|
|
243
|
-
};
|
|
244
|
-
}
|
|
164
|
+
type EndpointKeys = 'methods' | 'pattern' | 'types';
|
|
245
165
|
/**
|
|
246
|
-
*
|
|
166
|
+
* Determines if endpoint is a query (GET/HEAD) or mutation
|
|
247
167
|
*/
|
|
248
|
-
|
|
249
|
-
queryKey: DataTag<TuyauQueryKey, TuyauInfiniteData<TData>, TError>;
|
|
250
|
-
tuyau: {
|
|
251
|
-
path: string[];
|
|
252
|
-
type: 'infinite';
|
|
253
|
-
};
|
|
254
|
-
}
|
|
168
|
+
type IsQueryMethod<E extends SchemaEndpoint> = E['methods'][number] extends infer M ? M extends 'GET' | 'HEAD' ? true : false : false;
|
|
255
169
|
/**
|
|
256
|
-
*
|
|
170
|
+
* Endpoint node with query or mutation decorators
|
|
171
|
+
* Optimized: uses direct conditional instead of nested extends
|
|
257
172
|
*/
|
|
258
|
-
|
|
259
|
-
<TData = UnionFromSuccessStatuses<EDef['response']>, TPageParamKey extends keyof EDef['request'] = string>(input: {
|
|
260
|
-
payload?: Omit<EDef['request'], TPageParamKey>;
|
|
261
|
-
params?: TParams;
|
|
262
|
-
} | SkipToken, opts: DefinedTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any, EDef['request'], TPageParamKey>): DefinedTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
|
|
263
|
-
<TData = UnionFromSuccessStatuses<EDef['response']>, TPageParamKey extends keyof EDef['request'] = string>(input: {
|
|
264
|
-
payload?: Omit<EDef['request'], TPageParamKey>;
|
|
265
|
-
params?: TParams;
|
|
266
|
-
}, opts: UnusedSkipTokenTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any, EDef['request'], TPageParamKey>): UnusedSkipTokenTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
|
|
267
|
-
<TData = UnionFromSuccessStatuses<EDef['response']>, TPageParamKey extends keyof EDef['request'] = string>(input?: {
|
|
268
|
-
payload?: Omit<EDef['request'], TPageParamKey>;
|
|
269
|
-
params?: TParams;
|
|
270
|
-
} | SkipToken, opts?: UndefinedTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any, EDef['request'], TPageParamKey>): UndefinedTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
|
|
271
|
-
}
|
|
173
|
+
type EndpointNode<E extends SchemaEndpoint> = (IsQueryMethod<E> extends true ? DecorateQueryFn<E> & DecorateInfiniteQueryFn<E> : DecorateMutationFn<E>) & DecorateRouterKeyable;
|
|
272
174
|
/**
|
|
273
|
-
*
|
|
175
|
+
* Transform a pre-computed tree structure into react-query decorated endpoints
|
|
176
|
+
* Uses the $tree from the registry to avoid recomputing the structure
|
|
177
|
+
* Handles the case where a node is both an endpoint AND has children
|
|
274
178
|
*/
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
params?: TParams;
|
|
280
|
-
}) => DataTag<TuyauQueryKey, TuyauInfiniteData<UnionFromSuccessStatuses<EDef['response']>>, any>;
|
|
281
|
-
infiniteQueryFilter: (input?: {
|
|
282
|
-
payload?: Partial<EDef['request']>;
|
|
283
|
-
params?: TParams;
|
|
284
|
-
}, filters?: QueryFilters<DataTag<TuyauQueryKey, TuyauInfiniteData<UnionFromSuccessStatuses<EDef['response']>>, any>>) => WithRequired<QueryFilters<DataTag<TuyauQueryKey, TuyauInfiniteData<UnionFromSuccessStatuses<EDef['response']>>, any>>, 'queryKey'>;
|
|
285
|
-
}
|
|
179
|
+
type TransformToReactQuery<T> = {
|
|
180
|
+
[K in keyof T]: T[K] extends SchemaEndpoint ? EndpointNode<T[K]> & TransformToReactQuery<Omit<T[K], EndpointKeys>> : TransformToReactQuery<T[K]>;
|
|
181
|
+
} & DecorateRouterKeyable;
|
|
182
|
+
type TuyauReactQuery<R extends Record<string, SchemaEndpoint>> = TransformToReactQuery<R>;
|
|
286
183
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
*/
|
|
290
|
-
interface TuyauReactQueryClientOptions<D extends Record<string, any>, R extends GeneratedRoutes> {
|
|
291
|
-
client: TuyauClient<D, R>;
|
|
184
|
+
declare function createTuyauReactQueryClient<Reg extends TuyauRegistry, Tree = InferTree<Reg>, Routes extends Record<string, AdonisEndpoint> = InferRoutes<Reg>>(options: {
|
|
185
|
+
client: Tuyau<Reg, Routes>;
|
|
292
186
|
queryClient: QueryClient | (() => QueryClient);
|
|
293
|
-
/**
|
|
294
|
-
* Global Tuyau-specific request options
|
|
295
|
-
*/
|
|
296
187
|
globalOptions?: TuyauReactRequestOptions;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Create the Tuyau React Query client
|
|
300
|
-
*/
|
|
301
|
-
declare function createTuyauReactQueryClient<D extends Record<string, any>, R extends GeneratedRoutes>(options: TuyauReactQueryClientOptions<D, R>): TuyauReactQuery<D> & DecorateRouterKeyable;
|
|
302
|
-
/**
|
|
303
|
-
* Main type for the Tuyau React Query client
|
|
304
|
-
* Maps route definitions to appropriate query or mutation decorators
|
|
305
|
-
*/
|
|
306
|
-
type TuyauReactQuery<in out Route extends Record<string, any>, NotProvidedParams = {}> = {
|
|
307
|
-
[K in keyof Route as K extends `:${string}` ? never : K]: Route[K] extends {
|
|
308
|
-
response: infer _Res extends Record<number, unknown>;
|
|
309
|
-
request: infer _Request;
|
|
310
|
-
} ? K extends '$get' | '$head' ? DecorateQueryFn<Route[K], NotProvidedParams> & DecorateInfiniteQueryFn<Route[K], NotProvidedParams> & DecorateRouterKeyable : // POST, PUT, PATCH, DELETE methods become mutations
|
|
311
|
-
DecorateMutationFn<Route[K], NotProvidedParams> & DecorateRouterKeyable : K extends '$url' ? (options?: {
|
|
312
|
-
query?: QueryParameters;
|
|
313
|
-
}) => string : CreateParams<Route[K], NotProvidedParams> & DecorateRouterKeyable;
|
|
314
|
-
};
|
|
315
|
-
/**
|
|
316
|
-
* Extract path parameters from route keys
|
|
317
|
-
*/
|
|
318
|
-
type ExtractPathParams<Route> = Extract<keyof Route, `:${string}`>;
|
|
319
|
-
/**
|
|
320
|
-
* Convert path parameter to object type
|
|
321
|
-
*/
|
|
322
|
-
type PathParamToObject<Path extends string> = Path extends `:${infer Param}` ? {
|
|
323
|
-
[K in Param]: string | number;
|
|
324
|
-
} : never;
|
|
325
|
-
/**
|
|
326
|
-
* Create the route parameter function signature
|
|
327
|
-
*/
|
|
328
|
-
type CreateParamFunction<Route extends Record<string, any>, Path extends string, NotProvidedParams> = (params: PathParamToObject<Path>) => TuyauReactQuery<Route[Path], NotProvidedParams> & CreateParams<Route[Path], NotProvidedParams & PathParamToObject<Path>>;
|
|
329
|
-
/**
|
|
330
|
-
* Create the parameter property mappings
|
|
331
|
-
*/
|
|
332
|
-
type CreateParamProperties<Route extends Record<string, any>, Path extends string, NotProvidedParams> = {
|
|
333
|
-
[K in keyof Route as K extends `:${string}` ? K : never]: TuyauReactQuery<Route[K], NotProvidedParams & PathParamToObject<Path>> & DecorateRouterKeyable;
|
|
334
|
-
};
|
|
335
|
-
/**
|
|
336
|
-
* Type for handling route parameters
|
|
337
|
-
*/
|
|
338
|
-
type CreateParams<Route extends Record<string, any>, NotProvidedParams = {}> = ExtractPathParams<Route> extends infer Path extends string ? IsNever<Path> extends true ? TuyauReactQuery<Route, NotProvidedParams> & DecorateRouterKeyable : CreateParamFunction<Route, Path, NotProvidedParams> & TuyauReactQuery<Route, NotProvidedParams> & CreateParamProperties<Route, Path, NotProvidedParams> & DecorateRouterKeyable : never;
|
|
188
|
+
}): TransformToReactQuery<Tree>;
|
|
339
189
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}>;
|
|
348
|
-
useTuyau: () => InferTuyauReactQuery<API>;
|
|
349
|
-
useTuyauClient: () => InferTuyauClient<API>;
|
|
190
|
+
interface TuyauQueryOptionsOptions {
|
|
191
|
+
request: RawRequestArgs<any> | SkipToken;
|
|
192
|
+
opts?: TuyauQueryBaseOptions;
|
|
193
|
+
queryKey: TuyauQueryKey;
|
|
194
|
+
routeName: string;
|
|
195
|
+
client: Tuyau<any>;
|
|
196
|
+
globalOptions?: TuyauReactRequestOptions;
|
|
350
197
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
198
|
+
declare function tuyauQueryOptions(options: TuyauQueryOptionsOptions): _tanstack_react_query.UseQueryOptions<any, Error, any, readonly unknown[]> & {
|
|
199
|
+
initialData?: any;
|
|
200
|
+
} & {
|
|
201
|
+
queryKey: readonly unknown[] & {
|
|
202
|
+
[dataTagSymbol]: any;
|
|
203
|
+
[dataTagErrorSymbol]: Error;
|
|
204
|
+
};
|
|
205
|
+
};
|
|
355
206
|
|
|
356
|
-
export { type
|
|
207
|
+
export { type DecorateMutationFn, type DecorateRouterKeyable, type DefinedTuyauQueryOptionsIn, type DefinedTuyauQueryOptionsOut, type EndpointNode, type QueryType, type TransformToReactQuery, type TuyauMutationKey, type TuyauMutationOptionsIn, type TuyauMutationOptionsOptions, type TuyauMutationOptionsOut, type TuyauQueryBaseOptions, type TuyauQueryKey, type TuyauQueryOptionsOptions, type TuyauReactMutationOptions, type TuyauReactQuery, type TuyauReactRequestOptions, type UndefinedTuyauQueryOptionsIn, type UndefinedTuyauQueryOptionsOut, type UnusedSkipTokenTuyauQueryOptionsIn, type UnusedSkipTokenTuyauQueryOptionsOut, createTuyauReactQueryClient, getMutationKeyInternal, tuyauMutationOptions, tuyauQueryOptions };
|
package/build/index.js
CHANGED
|
@@ -1,273 +1,176 @@
|
|
|
1
|
-
// src/main.ts
|
|
2
|
-
import {
|
|
3
|
-
createTuyauRecursiveProxy
|
|
4
|
-
} from "@tuyau/client";
|
|
5
|
-
|
|
6
1
|
// src/utils.ts
|
|
7
|
-
|
|
8
|
-
return typeof arg === "function" ? arg() : arg;
|
|
9
|
-
}
|
|
2
|
+
import { skipToken } from "@tanstack/react-query";
|
|
10
3
|
function isObject(value) {
|
|
11
4
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
5
|
}
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
const result = [];
|
|
16
|
-
for (const segment of path) {
|
|
17
|
-
const segmentStr = String(segment);
|
|
18
|
-
if (segmentStr.includes("/")) {
|
|
19
|
-
const parts = segmentStr.split("/");
|
|
20
|
-
for (const part of parts) {
|
|
21
|
-
if (part.startsWith(":")) {
|
|
22
|
-
const paramName = part.slice(1);
|
|
23
|
-
result.push(params[paramName]?.toString() || part);
|
|
24
|
-
} else {
|
|
25
|
-
result.push(part);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
} else if (segmentStr.startsWith(":")) {
|
|
29
|
-
const paramName = segmentStr.slice(1);
|
|
30
|
-
result.push(params[paramName]?.toString() || segmentStr);
|
|
31
|
-
} else {
|
|
32
|
-
result.push(segmentStr);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return result;
|
|
6
|
+
function invoke(fn) {
|
|
7
|
+
return fn?.();
|
|
36
8
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
skipToken
|
|
42
|
-
} from "@tanstack/react-query";
|
|
43
|
-
function getQueryKeyInternal(path, input, type) {
|
|
44
|
-
let params;
|
|
45
|
-
let payload;
|
|
46
|
-
if (isObject(input)) {
|
|
47
|
-
if ("params" in input && input.params && typeof input.params === "object") {
|
|
48
|
-
params = input.params;
|
|
49
|
-
}
|
|
50
|
-
if ("payload" in input) {
|
|
51
|
-
payload = input.payload;
|
|
52
|
-
} else if (!("params" in input)) {
|
|
53
|
-
payload = input;
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
payload = input;
|
|
57
|
-
}
|
|
58
|
-
const splitPath = path.flatMap((part) => part.toString().split("/"));
|
|
59
|
-
if (!input && (!type || type === "any")) {
|
|
9
|
+
function buildKey(opts) {
|
|
10
|
+
const { segments, request, type } = opts;
|
|
11
|
+
const splitPath = segments.flatMap((part) => part.split("."));
|
|
12
|
+
if (!request && type === "any") {
|
|
60
13
|
return splitPath.length ? [splitPath] : [];
|
|
61
14
|
}
|
|
15
|
+
if (type === "infinite" && isObject(request) && ("direction" in request || "cursor" in request)) {
|
|
16
|
+
const { cursor: _, direction: __, ...inputWithoutCursorAndDirection } = request;
|
|
17
|
+
return [splitPath, { request: inputWithoutCursorAndDirection, type: "infinite" }];
|
|
18
|
+
}
|
|
62
19
|
return [
|
|
63
20
|
splitPath,
|
|
64
21
|
{
|
|
65
|
-
...typeof
|
|
66
|
-
...typeof params !== "undefined" && { params },
|
|
22
|
+
...typeof request !== "undefined" && request !== skipToken && { request },
|
|
67
23
|
...type && type !== "any" && { type }
|
|
68
24
|
}
|
|
69
25
|
];
|
|
70
26
|
}
|
|
27
|
+
|
|
28
|
+
// src/query.ts
|
|
29
|
+
import { queryOptions, skipToken as skipToken2 } from "@tanstack/react-query";
|
|
71
30
|
function tuyauQueryOptions(options) {
|
|
72
|
-
const {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
...opts?.tuyau,
|
|
82
|
-
...effectiveAbortOnUnmount ? { signal: queryFnContext.signal } : { signal: null }
|
|
83
|
-
}
|
|
31
|
+
const { request, routeName, opts, queryKey, client, globalOptions } = options;
|
|
32
|
+
const queryFn = invoke(() => {
|
|
33
|
+
if (request === skipToken2) return skipToken2;
|
|
34
|
+
return async (queryFnContext) => {
|
|
35
|
+
const effectiveAbortOnUnmount = opts?.tuyau?.abortOnUnmount ?? globalOptions?.abortOnUnmount ?? false;
|
|
36
|
+
return await client.request(routeName, {
|
|
37
|
+
...request,
|
|
38
|
+
...effectiveAbortOnUnmount ? { signal: queryFnContext.signal } : {}
|
|
39
|
+
});
|
|
84
40
|
};
|
|
85
|
-
return await client.$fetch({ paths: requestPath, input: payload, queryOptions: actualOpts });
|
|
86
|
-
};
|
|
87
|
-
return Object.assign(queryOptions({ ...opts, queryKey, queryFn }), {
|
|
88
|
-
tuyau: { path, type: "query" }
|
|
89
41
|
});
|
|
90
|
-
}
|
|
91
|
-
function extractInputAndPath(input, path) {
|
|
92
|
-
if (typeof input !== "object" || input === null || !("payload" in input) && !("params" in input)) {
|
|
93
|
-
return { payload: input, requestPath: path };
|
|
94
|
-
}
|
|
95
|
-
const { payload, params } = input;
|
|
96
|
-
const requestPath = buildRequestPath(path, params);
|
|
97
|
-
return { payload, requestPath };
|
|
42
|
+
return queryOptions({ ...opts, queryKey, queryFn });
|
|
98
43
|
}
|
|
99
44
|
|
|
100
45
|
// src/infinite_query.ts
|
|
101
|
-
import {
|
|
102
|
-
infiniteQueryOptions,
|
|
103
|
-
skipToken as skipToken2
|
|
104
|
-
} from "@tanstack/react-query";
|
|
105
|
-
function extractInfiniteInputAndPath(input, path, pageParamKey, pageParam) {
|
|
106
|
-
if (typeof input !== "object" || input === null || !("payload" in input) && !("params" in input)) {
|
|
107
|
-
const payload2 = typeof input === "object" && input !== null ? input : {};
|
|
108
|
-
const enhancedPayload2 = { ...payload2, [pageParamKey]: pageParam };
|
|
109
|
-
return { payload: enhancedPayload2, requestPath: path };
|
|
110
|
-
}
|
|
111
|
-
const { payload, params } = input;
|
|
112
|
-
const requestPath = buildRequestPath(path, params);
|
|
113
|
-
const enhancedPayload = { ...payload, [pageParamKey]: pageParam };
|
|
114
|
-
return { payload: enhancedPayload, requestPath };
|
|
115
|
-
}
|
|
46
|
+
import { infiniteQueryOptions, skipToken as skipToken3 } from "@tanstack/react-query";
|
|
116
47
|
function tuyauInfiniteQueryOptions(options) {
|
|
117
|
-
const {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
48
|
+
const { request, routeName, opts, queryKey, client, globalOptions } = options;
|
|
49
|
+
const queryFn = invoke(() => {
|
|
50
|
+
if (request === skipToken3) return skipToken3;
|
|
51
|
+
return async (queryFnContext) => {
|
|
52
|
+
const { pageParam } = queryFnContext;
|
|
53
|
+
const effectiveAbortOnUnmount = opts?.tuyau?.abortOnUnmount ?? globalOptions?.abortOnUnmount ?? false;
|
|
54
|
+
const pageParamKey = opts?.pageParamKey || "page";
|
|
55
|
+
let requestArgs;
|
|
56
|
+
if (typeof request === "object" && request !== null) {
|
|
57
|
+
if (pageParam !== void 0) {
|
|
58
|
+
requestArgs = {
|
|
59
|
+
...request,
|
|
60
|
+
query: { ...request.query, [pageParamKey]: pageParam }
|
|
61
|
+
};
|
|
62
|
+
} else {
|
|
63
|
+
requestArgs = request;
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
requestArgs = { query: pageParam !== void 0 ? { [pageParamKey]: pageParam } : {} };
|
|
136
67
|
}
|
|
68
|
+
return await client.request(routeName, {
|
|
69
|
+
...requestArgs,
|
|
70
|
+
...effectiveAbortOnUnmount ? { signal: queryFnContext.signal } : {}
|
|
71
|
+
});
|
|
137
72
|
};
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
{ tuyau: { path, type: "infinite" } }
|
|
148
|
-
);
|
|
73
|
+
});
|
|
74
|
+
return infiniteQueryOptions({
|
|
75
|
+
...opts,
|
|
76
|
+
queryKey,
|
|
77
|
+
queryFn,
|
|
78
|
+
initialPageParam: opts?.initialPageParam ?? 1,
|
|
79
|
+
getNextPageParam: opts?.getNextPageParam ?? (() => null),
|
|
80
|
+
getPreviousPageParam: opts?.getPreviousPageParam
|
|
81
|
+
});
|
|
149
82
|
}
|
|
150
83
|
|
|
151
84
|
// src/mutation.ts
|
|
152
|
-
import {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const splitPath = path.flatMap((part) => part.toString().split("."));
|
|
157
|
-
return splitPath.length ? [splitPath] : [];
|
|
85
|
+
import { mutationOptions } from "@tanstack/react-query";
|
|
86
|
+
function getMutationKeyInternal(options) {
|
|
87
|
+
const key = [options.segments.flatMap((part) => part.split("."))];
|
|
88
|
+
return key;
|
|
158
89
|
}
|
|
159
|
-
function tuyauMutationOptions(
|
|
160
|
-
const { opts,
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
);
|
|
166
|
-
const mutationSuccessOverride = overrides?.onSuccess ?? ((options) => options.originalFn());
|
|
167
|
-
const mutationFn = async (input) => {
|
|
168
|
-
const requestPath = buildRequestPath(path, input.params);
|
|
169
|
-
return await client.$fetch({ paths: requestPath, input: input.payload });
|
|
90
|
+
function tuyauMutationOptions(options) {
|
|
91
|
+
const { opts, routeName, client } = options;
|
|
92
|
+
const mutationKey = getMutationKeyInternal({ segments: routeName.split(".") });
|
|
93
|
+
const mutationFn = async (request) => {
|
|
94
|
+
const requestArgs = request || {};
|
|
95
|
+
return await client.request(routeName, requestArgs);
|
|
170
96
|
};
|
|
171
|
-
|
|
172
|
-
const originalFn = () => {
|
|
173
|
-
if (opts?.onSuccess) return opts.onSuccess(data, variables, context);
|
|
174
|
-
if (defaultOpts?.onSuccess) return defaultOpts.onSuccess(data, variables, context);
|
|
175
|
-
};
|
|
176
|
-
return mutationSuccessOverride({
|
|
177
|
-
originalFn,
|
|
178
|
-
queryClient,
|
|
179
|
-
meta: opts?.meta ?? defaultOpts?.meta ?? {}
|
|
180
|
-
});
|
|
181
|
-
};
|
|
182
|
-
return Object.assign(mutationOptions({ ...opts, mutationKey, mutationFn, onSuccess }), {
|
|
183
|
-
tuyau: { path, type: "mutation" }
|
|
184
|
-
});
|
|
97
|
+
return mutationOptions({ ...opts, mutationKey, mutationFn });
|
|
185
98
|
}
|
|
186
99
|
|
|
187
100
|
// src/main.ts
|
|
188
|
-
function
|
|
189
|
-
return
|
|
190
|
-
const fnName = paths.at(-1);
|
|
191
|
-
const path = paths.slice(0, -1);
|
|
192
|
-
const patternPath = patternPaths ? patternPaths.slice(0, -1) : path;
|
|
193
|
-
const [arg1, arg2] = args;
|
|
194
|
-
if (fnName === "queryOptions") {
|
|
195
|
-
return tuyauQueryOptions({
|
|
196
|
-
input: arg1,
|
|
197
|
-
opts: arg2 || {},
|
|
198
|
-
queryKey: getQueryKeyInternal(patternPath, arg1, "query"),
|
|
199
|
-
queryClient: unwrapLazyArg(options.queryClient),
|
|
200
|
-
client: options.client,
|
|
201
|
-
path,
|
|
202
|
-
globalOptions: options.globalOptions
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
if (fnName === "infiniteQueryOptions") {
|
|
206
|
-
return tuyauInfiniteQueryOptions({
|
|
207
|
-
input: arg1,
|
|
208
|
-
opts: arg2 || {},
|
|
209
|
-
queryKey: getQueryKeyInternal(patternPath, arg1, "infinite"),
|
|
210
|
-
queryClient: unwrapLazyArg(options.queryClient),
|
|
211
|
-
client: options.client,
|
|
212
|
-
path,
|
|
213
|
-
globalOptions: options.globalOptions
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
if (fnName === "queryKey") return getQueryKeyInternal(patternPath, arg1, "query");
|
|
217
|
-
if (fnName === "infiniteQueryKey") return getQueryKeyInternal(patternPath, arg1, "infinite");
|
|
218
|
-
if (fnName === "pathKey") return getQueryKeyInternal(patternPath);
|
|
219
|
-
if (fnName === "queryFilter") {
|
|
220
|
-
return { ...arg2, queryKey: getQueryKeyInternal(patternPath, arg1, "query") };
|
|
221
|
-
}
|
|
222
|
-
if (fnName === "infiniteQueryFilter") {
|
|
223
|
-
return { ...arg2, queryKey: getQueryKeyInternal(patternPath, arg1, "infinite") };
|
|
224
|
-
}
|
|
225
|
-
if (fnName === "pathFilter") {
|
|
226
|
-
return { ...arg1, queryKey: getQueryKeyInternal(patternPath) };
|
|
227
|
-
}
|
|
228
|
-
if (fnName === "mutationOptions") {
|
|
229
|
-
return tuyauMutationOptions({
|
|
230
|
-
path,
|
|
231
|
-
opts: arg1,
|
|
232
|
-
queryClient: unwrapLazyArg(options.queryClient),
|
|
233
|
-
client: options.client
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
if (fnName === "mutationKey") return getMutationKeyInternal(path);
|
|
237
|
-
const newProxy = executeIfRouteParamCall({ fnName, body: args[0] });
|
|
238
|
-
if (newProxy) return newProxy;
|
|
239
|
-
throw new Error(`Method ${fnName} not found on Tuyau client`);
|
|
240
|
-
});
|
|
101
|
+
function toSnakeCase(str) {
|
|
102
|
+
return str.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
|
|
241
103
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
function
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
104
|
+
function segmentsToRouteName(segments) {
|
|
105
|
+
return segments.map(toSnakeCase).join(".");
|
|
106
|
+
}
|
|
107
|
+
function createTuyauReactQueryClient(options) {
|
|
108
|
+
const { client, globalOptions } = options;
|
|
109
|
+
function makeReactQueryNamed(segments) {
|
|
110
|
+
const routeName = segmentsToRouteName(segments);
|
|
111
|
+
const decoratedEndpoint = {
|
|
112
|
+
/**
|
|
113
|
+
* Queries
|
|
114
|
+
*/
|
|
115
|
+
queryOptions: (request, opts) => {
|
|
116
|
+
return tuyauQueryOptions({
|
|
117
|
+
opts,
|
|
118
|
+
client,
|
|
119
|
+
request,
|
|
120
|
+
routeName,
|
|
121
|
+
globalOptions,
|
|
122
|
+
queryKey: buildKey({ segments, request, type: "query" })
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
queryKey: (request) => buildKey({ segments, request, type: "query" }),
|
|
126
|
+
queryFilter: (request, filters) => ({
|
|
127
|
+
queryKey: buildKey({ segments, request, type: "query" }),
|
|
128
|
+
...filters
|
|
253
129
|
}),
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Infinite Queries
|
|
132
|
+
*/
|
|
133
|
+
infiniteQueryOptions: (request, opts) => {
|
|
134
|
+
return tuyauInfiniteQueryOptions({
|
|
135
|
+
opts,
|
|
136
|
+
client,
|
|
137
|
+
request,
|
|
138
|
+
routeName,
|
|
139
|
+
globalOptions,
|
|
140
|
+
queryKey: buildKey({ segments, request, type: "infinite" })
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
infiniteQueryKey: (request) => buildKey({ segments, request, type: "infinite" }),
|
|
144
|
+
infiniteQueryFilter: (request, filters) => ({
|
|
145
|
+
queryKey: buildKey({ segments, request, type: "infinite" }),
|
|
146
|
+
...filters
|
|
147
|
+
}),
|
|
148
|
+
/**
|
|
149
|
+
* Mutations
|
|
150
|
+
*/
|
|
151
|
+
mutationOptions: (opts) => tuyauMutationOptions({ opts, client, routeName }),
|
|
152
|
+
mutationKey: () => getMutationKeyInternal({ segments }),
|
|
153
|
+
/**
|
|
154
|
+
* Paths
|
|
155
|
+
*/
|
|
156
|
+
pathKey: () => buildKey({ segments, type: "any" }),
|
|
157
|
+
pathFilter: (filters) => ({
|
|
158
|
+
queryKey: buildKey({ segments, type: "any" }),
|
|
159
|
+
...filters
|
|
160
|
+
})
|
|
161
|
+
};
|
|
162
|
+
return new Proxy(decoratedEndpoint, {
|
|
163
|
+
get: (target, prop) => {
|
|
164
|
+
if (prop in target) return target[prop];
|
|
165
|
+
return makeReactQueryNamed([...segments, String(prop)]);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
267
168
|
}
|
|
268
|
-
return
|
|
169
|
+
return makeReactQueryNamed([]);
|
|
269
170
|
}
|
|
270
171
|
export {
|
|
271
|
-
|
|
272
|
-
|
|
172
|
+
createTuyauReactQueryClient,
|
|
173
|
+
getMutationKeyInternal,
|
|
174
|
+
tuyauMutationOptions,
|
|
175
|
+
tuyauQueryOptions
|
|
273
176
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuyau/react-query",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.1
|
|
4
|
+
"version": "1.0.0-beta.1",
|
|
5
5
|
"description": "React Query plugin for Tuyau",
|
|
6
6
|
"author": "Julien Ripouteau <julien@ripouteau.com>",
|
|
7
7
|
"license": "ISC",
|
|
@@ -13,23 +13,23 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"build"
|
|
15
15
|
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=24.0.0"
|
|
18
|
+
},
|
|
16
19
|
"peerDependencies": {
|
|
17
20
|
"@tanstack/react-query": "^5.74.7",
|
|
18
|
-
"@tuyau/
|
|
19
|
-
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@tuyau/utils": "0.0.9"
|
|
21
|
+
"@tuyau/core": "1.0.0-beta.2"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@adonisjs/core": "^
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
24
|
+
"@adonisjs/core": "^7.0.0-next.10",
|
|
25
|
+
"@faker-js/faker": "^10.1.0",
|
|
26
|
+
"@happy-dom/global-registrator": "^20.0.10",
|
|
27
|
+
"@tanstack/react-query": "^5.90.7",
|
|
27
28
|
"@testing-library/react": "^16.3.0",
|
|
28
|
-
"@types/react": "^19.
|
|
29
|
-
"@vinejs/vine": "^
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"@tuyau/client": "0.2.11-next.2"
|
|
29
|
+
"@types/react": "^19.2.2",
|
|
30
|
+
"@vinejs/vine": "^4.1.0",
|
|
31
|
+
"react": "^19.2.0",
|
|
32
|
+
"@tuyau/core": "1.0.0-beta.4"
|
|
33
33
|
},
|
|
34
34
|
"tsup": {
|
|
35
35
|
"entry": [
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public",
|
|
46
|
-
"tag": "
|
|
46
|
+
"tag": "beta"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"lint": "eslint .",
|
|
50
50
|
"typecheck": "tsc --noEmit",
|
|
51
51
|
"build": "tsup-node",
|
|
52
|
-
"test": "
|
|
53
|
-
"quick:test": "node --enable-source-maps
|
|
52
|
+
"test": "pnpm quick:test",
|
|
53
|
+
"quick:test": "node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts --force-exit",
|
|
54
54
|
"checks": "pnpm lint && pnpm typecheck"
|
|
55
55
|
}
|
|
56
56
|
}
|