@leancodepl/react-query-cqrs-client 9.7.2 → 9.7.3

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/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";
@@ -1,3 +0,0 @@
1
- import { MonoTypeOperatorFunction } from "rxjs";
2
- import { TokenProvider } from "@leancodepl/cqrs-client-base";
3
- export declare function authGuard<T>(tokenProvider?: Partial<TokenProvider>): MonoTypeOperatorFunction<T>;
@@ -1,2 +0,0 @@
1
- import { UncapitalizeDeep } from "@leancodepl/utils";
2
- export type NullableUncapitalizeDeep<T> = T extends null ? null : UncapitalizeDeep<T>;