@leancodepl/react-query-cqrs-client 9.7.2 → 9.7.4
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/CHANGELOG.md +680 -0
- package/LICENSE +201 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2470 -0
- package/dist/index.umd.cjs +4 -0
- package/dist/lib/authGuard.d.ts +4 -0
- package/dist/lib/authGuard.d.ts.map +1 -0
- package/{src → dist}/lib/mkCqrsClient.d.ts +9 -8
- package/dist/lib/mkCqrsClient.d.ts.map +1 -0
- package/dist/lib/types/index.d.ts +3 -0
- package/dist/lib/types/index.d.ts.map +1 -0
- package/{src → dist}/lib/uncapitalizedJSONParse.d.ts +1 -0
- package/dist/lib/uncapitalizedJSONParse.d.ts.map +1 -0
- package/package.json +24 -18
- package/index.cjs.default.js +0 -1
- package/index.cjs.js +0 -282
- package/index.cjs.mjs +0 -2
- package/index.d.ts +0 -1
- package/index.esm.js +0 -280
- package/src/index.d.ts +0 -1
- package/src/lib/authGuard.d.ts +0 -3
- package/src/lib/types/index.d.ts +0 -2
package/index.esm.js
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { useMutation, useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
|
2
|
-
import { catchError, throwError, of, race, fromEvent, from, firstValueFrom } from 'rxjs';
|
|
3
|
-
import { AjaxError, ajax } from 'rxjs/ajax';
|
|
4
|
-
import { map, mergeMap } from 'rxjs/operators';
|
|
5
|
-
import { handleResponse } from '@leancodepl/validation';
|
|
6
|
-
import { toLowerFirst } from '@leancodepl/utils';
|
|
7
|
-
|
|
8
|
-
function _extends() {
|
|
9
|
-
_extends = Object.assign || function assign(target) {
|
|
10
|
-
for(var i = 1; i < arguments.length; i++){
|
|
11
|
-
var source = arguments[i];
|
|
12
|
-
for(var key in source)if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
|
|
13
|
-
}
|
|
14
|
-
return target;
|
|
15
|
-
};
|
|
16
|
-
return _extends.apply(this, arguments);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function _object_without_properties_loose(source, excluded) {
|
|
20
|
-
if (source == null) return {};
|
|
21
|
-
var target = {};
|
|
22
|
-
var sourceKeys = Object.keys(source);
|
|
23
|
-
var key, i;
|
|
24
|
-
for(i = 0; i < sourceKeys.length; i++){
|
|
25
|
-
key = sourceKeys[i];
|
|
26
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
27
|
-
target[key] = source[key];
|
|
28
|
-
}
|
|
29
|
-
return target;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function authGuard(tokenProvider) {
|
|
33
|
-
if (!(tokenProvider == null ? void 0 : tokenProvider.invalidateToken)) {
|
|
34
|
-
return (response)=>response;
|
|
35
|
-
}
|
|
36
|
-
return (response)=>response.pipe(catchError((error)=>{
|
|
37
|
-
if (error.status === 401) {
|
|
38
|
-
tokenProvider.invalidateToken == null ? void 0 : tokenProvider.invalidateToken.call(tokenProvider);
|
|
39
|
-
}
|
|
40
|
-
return throwError(()=>error);
|
|
41
|
-
}));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function uncapitalizedJSONParse(json) {
|
|
45
|
-
return JSON.parse(json, (key, value)=>{
|
|
46
|
-
if (value === null && key !== "") return undefined;
|
|
47
|
-
if (!value || Array.isArray(value) || typeof value !== "object") return value;
|
|
48
|
-
return Object.fromEntries(Object.entries(value).map(([key, value])=>[
|
|
49
|
-
toLowerFirst(key),
|
|
50
|
-
value
|
|
51
|
-
]));
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function uncapitalizedParse() {
|
|
56
|
-
return ($source)=>$source.pipe(map(uncapitalizedJSONParse));
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Creates React Query CQRS client with hooks for queries, operations, and commands.
|
|
60
|
-
*
|
|
61
|
-
* Integrates with React Query to provide caching, background updates, and optimistic updates
|
|
62
|
-
* for CQRS operations. Automatically handles authentication, retries, and response transformation
|
|
63
|
-
* with uncapitalized keys.
|
|
64
|
-
*
|
|
65
|
-
* @param cqrsEndpoint - Base URL for CQRS API endpoints
|
|
66
|
-
* @param queryClient - React Query client instance
|
|
67
|
-
* @param tokenProvider - Optional token provider for authentication
|
|
68
|
-
* @param ajaxOptions - Optional RxJS Ajax configuration options
|
|
69
|
-
* @param tokenHeader - Header name for authentication token (default: "Authorization")
|
|
70
|
-
* @returns Object with `createQuery`, `createOperation`, and `createCommand` hook factories
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* const client = mkCqrsClient({
|
|
74
|
-
* cqrsEndpoint: 'https://api.example.com',
|
|
75
|
-
* queryClient: new QueryClient()
|
|
76
|
-
* });
|
|
77
|
-
* ```
|
|
78
|
-
*/ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions, tokenHeader = "Authorization" }) {
|
|
79
|
-
function mkFetcher(endpoint, config = {}) {
|
|
80
|
-
const apiCall = (data, token)=>{
|
|
81
|
-
var _ajaxOptions_withCredentials;
|
|
82
|
-
return ajax(_extends({}, ajaxOptions, config, {
|
|
83
|
-
headers: {
|
|
84
|
-
[tokenHeader]: token,
|
|
85
|
-
"Content-Type": "application/json"
|
|
86
|
-
},
|
|
87
|
-
url: `${cqrsEndpoint}/${endpoint}`,
|
|
88
|
-
method: "POST",
|
|
89
|
-
body: data,
|
|
90
|
-
withCredentials: (_ajaxOptions_withCredentials = ajaxOptions == null ? void 0 : ajaxOptions.withCredentials) != null ? _ajaxOptions_withCredentials : true
|
|
91
|
-
}));
|
|
92
|
-
};
|
|
93
|
-
const getToken = tokenProvider == null ? void 0 : tokenProvider.getToken;
|
|
94
|
-
const mk$apiCall = (data, token)=>apiCall(data, token).pipe(authGuard(tokenProvider), map((result)=>result.response));
|
|
95
|
-
if (getToken) {
|
|
96
|
-
return (data)=>from(getToken()).pipe(mergeMap((token)=>mk$apiCall(data, token)));
|
|
97
|
-
}
|
|
98
|
-
return (data)=>mk$apiCall(data);
|
|
99
|
-
}
|
|
100
|
-
return {
|
|
101
|
-
createQuery (type) {
|
|
102
|
-
const fetcher = mkFetcher(`query/${type}`, {
|
|
103
|
-
responseType: "text"
|
|
104
|
-
});
|
|
105
|
-
function useApiQuery(data, options) {
|
|
106
|
-
return useQuery(_extends({
|
|
107
|
-
queryKey: useApiQuery.key(data),
|
|
108
|
-
queryFn: (context)=>firstValueFrom(useApiQuery.fetcher(data, context))
|
|
109
|
-
}, options), queryClient);
|
|
110
|
-
}
|
|
111
|
-
useApiQuery.type = type;
|
|
112
|
-
useApiQuery.fetcher = (data, context)=>race([
|
|
113
|
-
fetcher(data).pipe(uncapitalizedParse()),
|
|
114
|
-
...(context == null ? void 0 : context.signal) ? [
|
|
115
|
-
fromEvent(context.signal, "abort").pipe(mergeMap(()=>throwError(()=>new Error("Query aborted"))))
|
|
116
|
-
] : []
|
|
117
|
-
]);
|
|
118
|
-
useApiQuery.fetch = (data, options)=>queryClient.fetchQuery(_extends({
|
|
119
|
-
queryKey: useApiQuery.key(data),
|
|
120
|
-
queryFn: (context)=>firstValueFrom(useApiQuery.fetcher(data, context))
|
|
121
|
-
}, options));
|
|
122
|
-
useApiQuery.lazy = function(options = {}) {
|
|
123
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
124
|
-
return useMutation(_extends({
|
|
125
|
-
mutationKey: [
|
|
126
|
-
type
|
|
127
|
-
],
|
|
128
|
-
mutationFn: (variables)=>firstValueFrom(useApiQuery.fetcher(variables))
|
|
129
|
-
}, options), queryClient);
|
|
130
|
-
};
|
|
131
|
-
useApiQuery.infinite = function(initialPageData, options) {
|
|
132
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
133
|
-
return useInfiniteQuery(_extends({
|
|
134
|
-
queryKey: [
|
|
135
|
-
type
|
|
136
|
-
],
|
|
137
|
-
queryFn: (context)=>firstValueFrom(useApiQuery.fetcher(context.pageParam, context)),
|
|
138
|
-
initialPageParam: initialPageData
|
|
139
|
-
}, options), queryClient);
|
|
140
|
-
};
|
|
141
|
-
useApiQuery.key = (query)=>[
|
|
142
|
-
type,
|
|
143
|
-
query
|
|
144
|
-
];
|
|
145
|
-
function setQueryData(queryOrQueryKey, updater) {
|
|
146
|
-
const key = Array.isArray(queryOrQueryKey) ? queryOrQueryKey : useApiQuery.key(queryOrQueryKey);
|
|
147
|
-
return queryClient.setQueryData(key, updater);
|
|
148
|
-
}
|
|
149
|
-
useApiQuery.setQueryData = setQueryData;
|
|
150
|
-
useApiQuery.setQueriesData = (query, updater)=>queryClient.setQueriesData({
|
|
151
|
-
queryKey: useApiQuery.key(query)
|
|
152
|
-
}, updater);
|
|
153
|
-
useApiQuery.getQueryData = (query)=>queryClient.getQueryData(useApiQuery.key(query));
|
|
154
|
-
useApiQuery.getQueriesData = (query)=>queryClient.getQueriesData({
|
|
155
|
-
queryKey: useApiQuery.key(query)
|
|
156
|
-
});
|
|
157
|
-
useApiQuery.prefetch = (data, options)=>queryClient.prefetchQuery(_extends({
|
|
158
|
-
queryKey: useApiQuery.key(data),
|
|
159
|
-
queryFn: (context)=>firstValueFrom(useApiQuery.fetcher(data, context))
|
|
160
|
-
}, options));
|
|
161
|
-
useApiQuery.invalidate = (query)=>queryClient.invalidateQueries({
|
|
162
|
-
queryKey: useApiQuery.key(query)
|
|
163
|
-
});
|
|
164
|
-
useApiQuery.cancel = (query)=>queryClient.cancelQueries({
|
|
165
|
-
queryKey: useApiQuery.key(query)
|
|
166
|
-
});
|
|
167
|
-
useApiQuery.optimisticUpdate = async (updater, query = {})=>{
|
|
168
|
-
await useApiQuery.cancel(query);
|
|
169
|
-
const data = useApiQuery.getQueriesData(query);
|
|
170
|
-
useApiQuery.setQueriesData(query, updater);
|
|
171
|
-
return ()=>data.forEach(([key, result])=>queryClient.setQueryData(key, result));
|
|
172
|
-
};
|
|
173
|
-
return useApiQuery;
|
|
174
|
-
},
|
|
175
|
-
createOperation (type) {
|
|
176
|
-
const fetcher = mkFetcher(`operation/${type}`, {
|
|
177
|
-
responseType: "text"
|
|
178
|
-
});
|
|
179
|
-
function useApiOperation(_param = {}) {
|
|
180
|
-
var { onSuccess: onSuccessBase, invalidateQueries } = _param, options = _object_without_properties_loose(_param, [
|
|
181
|
-
"onSuccess",
|
|
182
|
-
"invalidateQueries"
|
|
183
|
-
]);
|
|
184
|
-
return useMutation(_extends({
|
|
185
|
-
mutationKey: useApiOperation.key,
|
|
186
|
-
mutationFn: (variables)=>firstValueFrom(useApiOperation.fetcher(variables))
|
|
187
|
-
}, options, {
|
|
188
|
-
async onSuccess (data, variables, onMutateResult, context) {
|
|
189
|
-
const result = await (onSuccessBase == null ? void 0 : onSuccessBase(data, variables, onMutateResult, context));
|
|
190
|
-
if (invalidateQueries) {
|
|
191
|
-
await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
|
|
192
|
-
queryKey
|
|
193
|
-
})));
|
|
194
|
-
}
|
|
195
|
-
return result;
|
|
196
|
-
}
|
|
197
|
-
}), queryClient);
|
|
198
|
-
}
|
|
199
|
-
useApiOperation.type = type;
|
|
200
|
-
useApiOperation.key = [
|
|
201
|
-
useApiOperation.type
|
|
202
|
-
];
|
|
203
|
-
useApiOperation.fetcher = (variables)=>fetcher(variables).pipe(uncapitalizedParse());
|
|
204
|
-
return useApiOperation;
|
|
205
|
-
},
|
|
206
|
-
createCommand (type, errorCodes) {
|
|
207
|
-
const fetcher = mkFetcher(`command/${type}`);
|
|
208
|
-
function useApiCommand(_param = {}) {
|
|
209
|
-
var { invalidateQueries, handler, optimisticUpdate, onMutate, onError, onSettled } = _param, options = _object_without_properties_loose(_param, [
|
|
210
|
-
"invalidateQueries",
|
|
211
|
-
"handler",
|
|
212
|
-
"optimisticUpdate",
|
|
213
|
-
"onMutate",
|
|
214
|
-
"onError",
|
|
215
|
-
"onSettled"
|
|
216
|
-
]);
|
|
217
|
-
return useMutation(_extends({}, options, {
|
|
218
|
-
mutationKey: useApiCommand.key,
|
|
219
|
-
mutationFn: (variables)=>firstValueFrom(useApiCommand.call(variables, handler)),
|
|
220
|
-
async onMutate (variables, context) {
|
|
221
|
-
// there's really no good way to do it without type cast
|
|
222
|
-
const baseResult = await (onMutate == null ? void 0 : onMutate(variables, context));
|
|
223
|
-
var _optimisticUpdate;
|
|
224
|
-
const optimisticUpdateReverts = await Promise.all((_optimisticUpdate = optimisticUpdate == null ? void 0 : optimisticUpdate(variables)) != null ? _optimisticUpdate : []);
|
|
225
|
-
return _extends({}, baseResult, {
|
|
226
|
-
revertOptimisticUpdate: ()=>optimisticUpdateReverts.forEach((revertOptimisticUpdate)=>revertOptimisticUpdate())
|
|
227
|
-
});
|
|
228
|
-
},
|
|
229
|
-
async onError (error, variables, onMutateResult, context) {
|
|
230
|
-
await (onError == null ? void 0 : onError(error, variables, onMutateResult, context));
|
|
231
|
-
onMutateResult == null ? void 0 : onMutateResult.revertOptimisticUpdate();
|
|
232
|
-
},
|
|
233
|
-
// eslint-disable-next-line max-params
|
|
234
|
-
async onSettled (data, error, variables, onMutateResult, context) {
|
|
235
|
-
if (invalidateQueries) {
|
|
236
|
-
await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
|
|
237
|
-
queryKey
|
|
238
|
-
})));
|
|
239
|
-
}
|
|
240
|
-
return await (onSettled == null ? void 0 : onSettled(data, error, variables, onMutateResult, context));
|
|
241
|
-
}
|
|
242
|
-
}), queryClient);
|
|
243
|
-
}
|
|
244
|
-
useApiCommand.type = type;
|
|
245
|
-
useApiCommand.key = [
|
|
246
|
-
useApiCommand.type
|
|
247
|
-
];
|
|
248
|
-
useApiCommand.fetcher = fetcher;
|
|
249
|
-
useApiCommand.call = (variables, handler)=>{
|
|
250
|
-
const $response = useApiCommand.fetcher(variables);
|
|
251
|
-
return $response.pipe(map((result)=>({
|
|
252
|
-
isSuccess: true,
|
|
253
|
-
result
|
|
254
|
-
})), catchError((e)=>of(useApiCommand.mapError(e))), map((response)=>{
|
|
255
|
-
const result = handler ? useApiCommand.handleResponse(handler, variables)(response) : response;
|
|
256
|
-
if (!response.isSuccess || !response.result.WasSuccessful) {
|
|
257
|
-
throw result;
|
|
258
|
-
}
|
|
259
|
-
return result;
|
|
260
|
-
}));
|
|
261
|
-
};
|
|
262
|
-
useApiCommand.mapError = (e)=>{
|
|
263
|
-
if (e instanceof AjaxError && e.status === 422) {
|
|
264
|
-
return {
|
|
265
|
-
isSuccess: true,
|
|
266
|
-
result: e.response
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
return {
|
|
270
|
-
isSuccess: false,
|
|
271
|
-
error: e
|
|
272
|
-
};
|
|
273
|
-
};
|
|
274
|
-
useApiCommand.handleResponse = (handler, variables)=>(response)=>handler(handleResponse(response, errorCodes), variables);
|
|
275
|
-
return useApiCommand;
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
export { mkCqrsClient };
|
package/src/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { mkCqrsClient } from "./lib/mkCqrsClient";
|
package/src/lib/authGuard.d.ts
DELETED
package/src/lib/types/index.d.ts
DELETED