@ethlete/query 4.2.0 → 4.2.2
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/esm2022/lib/directives/infinity-query-trigger.directive.mjs +55 -0
- package/esm2022/lib/directives/infinity-query.directive.mjs +176 -0
- package/esm2022/lib/directives/query.directive.mjs +113 -0
- package/esm2022/lib/query-form/query-form.mjs +173 -0
- package/{esm2020 → esm2022}/lib/query-form/query-form.types.mjs +1 -1
- package/{fesm2020 → fesm2022}/ethlete-query.mjs +35 -19
- package/fesm2022/ethlete-query.mjs.map +1 -0
- package/lib/auth/bearer-auth-provider.d.ts +3 -3
- package/lib/directives/infinity-query-trigger.directive.d.ts +1 -1
- package/lib/directives/infinity-query.directive.d.ts +1 -1
- package/lib/directives/query.directive.d.ts +1 -1
- package/lib/query/query.utils.d.ts +12 -8
- package/lib/query-form/query-form.d.ts +11 -8
- package/lib/query-form/query-form.types.d.ts +4 -0
- package/package.json +8 -14
- package/esm2020/lib/directives/infinity-query-trigger.directive.mjs +0 -54
- package/esm2020/lib/directives/infinity-query.directive.mjs +0 -175
- package/esm2020/lib/directives/query.directive.mjs +0 -112
- package/esm2020/lib/query-form/query-form.mjs +0 -157
- package/fesm2015/ethlete-query.mjs +0 -2273
- package/fesm2015/ethlete-query.mjs.map +0 -1
- package/fesm2020/ethlete-query.mjs.map +0 -1
- /package/{esm2020 → esm2022}/ethlete-query.mjs +0 -0
- /package/{esm2020 → esm2022}/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/auth/auth-provider.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/auth/auth-provider.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/auth/basic-auth-provider.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/auth/bearer-auth-provider.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/auth/custom-header-auth-provider.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/auth/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/entity/entity-store.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/entity/entity.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/entity/entity.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/entity/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/gql/gql.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/gql/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/infinite-query/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/infinite-query/infinity-query.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/infinite-query/infinity-query.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/infinite-query/infinity-query.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/logger/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/logger/logger.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query/query.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query/query.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query/query.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-client/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-client/query-client.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-client/query-client.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-client/query-client.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-creator/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-creator/query-creator.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-creator/query-creator.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-form/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-form/query-form.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-store/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/query-store/query-store.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/request/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/request/request.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/request/request.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/request/request.util.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/symfony/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/symfony/symfony.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/symfony/symfony.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/deep-freeze.util.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/def.util.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/index.mjs +0 -0
|
@@ -1,2273 +0,0 @@
|
|
|
1
|
-
import * as i1 from '@ethlete/core';
|
|
2
|
-
import { BehaviorSubjectWithSubscriberCount, getCookie, setCookie, deleteCookie, DestroyService, DelayableDirective, equal, clone } from '@ethlete/core';
|
|
3
|
-
import { Observable, filter, takeWhile, switchMap, of, tap, BehaviorSubject, shareReplay, Subject, takeUntil, interval, skip, map, timer, combineLatest, withLatestFrom, fromEvent, startWith, debounceTime, take, concat, distinctUntilChanged, pairwise } from 'rxjs';
|
|
4
|
-
import * as i0 from '@angular/core';
|
|
5
|
-
import { isDevMode, Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
|
|
6
|
-
import { FormGroup } from '@angular/forms';
|
|
7
|
-
import { Router, ActivatedRoute } from '@angular/router';
|
|
8
|
-
|
|
9
|
-
class CustomHeaderAuthProvider {
|
|
10
|
-
get header() {
|
|
11
|
-
return { [this._config.name]: this._config.value };
|
|
12
|
-
}
|
|
13
|
-
constructor(_config) {
|
|
14
|
-
this._config = _config;
|
|
15
|
-
}
|
|
16
|
-
cleanUp() {
|
|
17
|
-
// noop
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
class BasicAuthProvider {
|
|
22
|
-
get header() {
|
|
23
|
-
return { Authorization: `Basic ${this._basicAuthString}` };
|
|
24
|
-
}
|
|
25
|
-
get _basicAuthString() {
|
|
26
|
-
return btoa(`${this._config.username}:${this._config.password}`);
|
|
27
|
-
}
|
|
28
|
-
constructor(_config) {
|
|
29
|
-
this._config = _config;
|
|
30
|
-
}
|
|
31
|
-
cleanUp() {
|
|
32
|
-
// noop
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const buildErrorMessage = (code, message) => `[@ethlete\\query:${code}] ${message}`;
|
|
37
|
-
class QueryError extends Error {
|
|
38
|
-
constructor(code, message, data) {
|
|
39
|
-
super(buildErrorMessage(code, message));
|
|
40
|
-
this.name = 'QueryError';
|
|
41
|
-
this.data = data;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const invalidBaseRouteError = (data) => new QueryError('001', 'The baseRoute must not end with a slash', data);
|
|
45
|
-
const invalidRouteError = (data) => new QueryError('002', 'The route must start with a slash', data);
|
|
46
|
-
const pathParamsMissingInRouteFunctionError = (data) => new QueryError('003', 'The route is a function but pathParams are missing', data);
|
|
47
|
-
const queryStateAlreadyHasKeyError = (data) => new QueryError('004', 'The query state already contains the provided key', data);
|
|
48
|
-
const queryStateDoesNotContainKeyError = (data) => new QueryError('005', 'The query state does not contain the provided key', data);
|
|
49
|
-
const queryStateCannotTransformError = (data) => new QueryError('006', 'The query state cannot be transformed because it is not loading', data);
|
|
50
|
-
const invalidBodyError = (data) => new QueryError('007', 'The body is not valid or upsupported', data);
|
|
51
|
-
|
|
52
|
-
const isSymfonyError = (error) => {
|
|
53
|
-
if (!error || typeof error !== 'object') {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
const symfonyError = error;
|
|
57
|
-
return (symfonyError.class !== undefined &&
|
|
58
|
-
symfonyError.detail !== undefined &&
|
|
59
|
-
symfonyError.status !== undefined &&
|
|
60
|
-
symfonyError.title !== undefined &&
|
|
61
|
-
symfonyError.trace !== undefined &&
|
|
62
|
-
symfonyError.type !== undefined);
|
|
63
|
-
};
|
|
64
|
-
const isSymfonyPagerfantaOutOfRangeError = (error) => {
|
|
65
|
-
if (!isSymfonyError(error)) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
return error.class.startsWith('Pagerfanta') && error.class.endsWith('OutOfRangeCurrentPageException');
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const isRequestError = (error) => error instanceof Object && 'status' in error && 'statusText' in error && 'url' in error;
|
|
72
|
-
const buildRoute = (options) => {
|
|
73
|
-
var _a;
|
|
74
|
-
if (options.base.endsWith('/')) {
|
|
75
|
-
throw invalidBaseRouteError(options.base);
|
|
76
|
-
}
|
|
77
|
-
let route = null;
|
|
78
|
-
if (typeof options.route === 'function') {
|
|
79
|
-
if (!options.pathParams) {
|
|
80
|
-
throw pathParamsMissingInRouteFunctionError(options.route({}));
|
|
81
|
-
}
|
|
82
|
-
route = options.route(options.pathParams);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
route = (_a = options.route) !== null && _a !== void 0 ? _a : null;
|
|
86
|
-
}
|
|
87
|
-
if (route && !route.startsWith('/')) {
|
|
88
|
-
throw invalidRouteError(route);
|
|
89
|
-
}
|
|
90
|
-
if (options.queryParams) {
|
|
91
|
-
const queryString = buildQueryString(options.queryParams);
|
|
92
|
-
if (queryString) {
|
|
93
|
-
route = route ? `${route}?${queryString}` : `/?${queryString}`;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return `${options.base}${route !== null && route !== void 0 ? route : ''}`;
|
|
97
|
-
};
|
|
98
|
-
const buildQueryString = (params) => {
|
|
99
|
-
const validParams = filterInvalidParams(params);
|
|
100
|
-
const queryString = Object.keys(validParams)
|
|
101
|
-
.map((key) => {
|
|
102
|
-
if (Array.isArray(validParams[key])) {
|
|
103
|
-
return buildQueryArrayString(key, validParams[key]);
|
|
104
|
-
}
|
|
105
|
-
if (typeof validParams[key] === 'object' && validParams[key] !== null) {
|
|
106
|
-
return buildQueryObjectString(key, validParams[key]);
|
|
107
|
-
}
|
|
108
|
-
return `${key}=${encodeURIComponent(validParams[key])}`;
|
|
109
|
-
})
|
|
110
|
-
.join('&');
|
|
111
|
-
return queryString || null;
|
|
112
|
-
};
|
|
113
|
-
const buildQueryArrayString = (key, array) => {
|
|
114
|
-
const uriBrackets = encodeURIComponent('[]');
|
|
115
|
-
return array
|
|
116
|
-
.slice()
|
|
117
|
-
.map((item) => `${key}${uriBrackets}=${encodeURIComponent(item)}`)
|
|
118
|
-
.join('&');
|
|
119
|
-
};
|
|
120
|
-
const buildQueryObjectString = (key, object) => {
|
|
121
|
-
const uriBracketStart = encodeURIComponent(`${key}[`);
|
|
122
|
-
const uriBracketEnd = encodeURIComponent(`]`);
|
|
123
|
-
return Object.keys(object)
|
|
124
|
-
.map((k) => {
|
|
125
|
-
const key = `${uriBracketStart}${k}${uriBracketEnd}`;
|
|
126
|
-
if (Array.isArray(object[k])) {
|
|
127
|
-
return buildQueryArrayString(key, object[k]);
|
|
128
|
-
}
|
|
129
|
-
if (typeof object[k] === 'object' && object[k] !== null) {
|
|
130
|
-
return buildQueryObjectString(key, object[k]);
|
|
131
|
-
}
|
|
132
|
-
return `${key}=${encodeURIComponent(object[k])}`;
|
|
133
|
-
})
|
|
134
|
-
.join('&');
|
|
135
|
-
};
|
|
136
|
-
const filterInvalidParams = (params) => {
|
|
137
|
-
const filteredParams = Object.entries(params)
|
|
138
|
-
.map(([key, value]) => {
|
|
139
|
-
if (Array.isArray(value)) {
|
|
140
|
-
return [key, value.filter((v) => isParamValid(v))];
|
|
141
|
-
}
|
|
142
|
-
else if (typeof value === 'object' && value !== null) {
|
|
143
|
-
return [key, filterInvalidParams(value)];
|
|
144
|
-
}
|
|
145
|
-
return [key, value];
|
|
146
|
-
})
|
|
147
|
-
.filter(([, value]) => isParamValid(value))
|
|
148
|
-
.reduce((acc, [key, value]) => (Object.assign(Object.assign({}, acc), { [key]: value })), {});
|
|
149
|
-
return filteredParams;
|
|
150
|
-
};
|
|
151
|
-
const isParamValid = (primitive) => {
|
|
152
|
-
if (primitive === undefined || primitive === null || primitive === '') {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
if (typeof primitive === 'string' && primitive.trim() === '') {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
if (typeof primitive === 'number' && isNaN(primitive)) {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
};
|
|
163
|
-
const extractExpiresInSeconds = (headers) => {
|
|
164
|
-
const cacheControl = headers['cache-control'];
|
|
165
|
-
const age = headers['age'];
|
|
166
|
-
const expires = headers['expires'];
|
|
167
|
-
// In seconds
|
|
168
|
-
let expiresIn = null;
|
|
169
|
-
let maxAge = null;
|
|
170
|
-
if (cacheControl === null || cacheControl === void 0 ? void 0 : cacheControl.includes('no-cache')) {
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
if (cacheControl === null || cacheControl === void 0 ? void 0 : cacheControl.includes('max-age')) {
|
|
174
|
-
maxAge = parseInt(cacheControl.split('max-age=')[1]);
|
|
175
|
-
}
|
|
176
|
-
else if (cacheControl === null || cacheControl === void 0 ? void 0 : cacheControl.includes('s-maxage')) {
|
|
177
|
-
maxAge = parseInt(cacheControl.split('s-maxage=')[1]);
|
|
178
|
-
}
|
|
179
|
-
if (maxAge && age) {
|
|
180
|
-
const ageSeconds = parseInt(age);
|
|
181
|
-
expiresIn = maxAge - ageSeconds;
|
|
182
|
-
}
|
|
183
|
-
else if (maxAge) {
|
|
184
|
-
expiresIn = maxAge / 2; // We assume the response is half way to its expiration
|
|
185
|
-
}
|
|
186
|
-
else if (expires) {
|
|
187
|
-
// Used by some apis to tell the response will never expire
|
|
188
|
-
// In this case we let the response expire after 1 hour
|
|
189
|
-
if (expires === '-1') {
|
|
190
|
-
expiresIn = 3600;
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
const expiresDate = new Date(expires);
|
|
194
|
-
// check if the date is valid
|
|
195
|
-
if (expiresDate.toString() !== 'Invalid Date') {
|
|
196
|
-
expiresIn = Math.floor((expiresDate.getTime() - Date.now()) / 1000);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return expiresIn;
|
|
201
|
-
};
|
|
202
|
-
const buildTimestampFromSeconds = (seconds) => {
|
|
203
|
-
if (seconds === null) {
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
return new Date(Date.now() + seconds * 1000).getTime();
|
|
207
|
-
};
|
|
208
|
-
const serializeBody = (body) => {
|
|
209
|
-
if (body === null || body === undefined) {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
if (body instanceof ArrayBuffer ||
|
|
213
|
-
body instanceof Blob ||
|
|
214
|
-
body instanceof FormData ||
|
|
215
|
-
body instanceof URLSearchParams ||
|
|
216
|
-
typeof body === 'string') {
|
|
217
|
-
return body;
|
|
218
|
-
}
|
|
219
|
-
if (typeof body === 'object' || typeof body === 'boolean' || Array.isArray(body)) {
|
|
220
|
-
return JSON.stringify(body);
|
|
221
|
-
}
|
|
222
|
-
return body.toString();
|
|
223
|
-
};
|
|
224
|
-
const transformMethod = (config) => {
|
|
225
|
-
if (config.method === 'GQL_QUERY' || config.method === 'GQL_MUTATE') {
|
|
226
|
-
if (!config.transferVia) {
|
|
227
|
-
return 'POST';
|
|
228
|
-
}
|
|
229
|
-
return config.transferVia;
|
|
230
|
-
}
|
|
231
|
-
return config.method;
|
|
232
|
-
};
|
|
233
|
-
const detectContentTypeHeader = (body) => {
|
|
234
|
-
// An empty body has no content type.
|
|
235
|
-
if (body === null) {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
// FormData bodies rely on the browser's content type assignment.
|
|
239
|
-
if (body instanceof FormData) {
|
|
240
|
-
return null;
|
|
241
|
-
}
|
|
242
|
-
// Blobs usually have their own content type. If it doesn't, then
|
|
243
|
-
// no type can be inferred.
|
|
244
|
-
if (body instanceof Blob) {
|
|
245
|
-
return body.type || null;
|
|
246
|
-
}
|
|
247
|
-
// Array buffers have unknown contents and thus no type can be inferred.
|
|
248
|
-
if (body instanceof ArrayBuffer) {
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
// Technically, strings could be a form of JSON data, but it's safe enough
|
|
252
|
-
// to assume they're plain strings.
|
|
253
|
-
if (typeof body === 'string') {
|
|
254
|
-
return 'text/plain';
|
|
255
|
-
}
|
|
256
|
-
// Arrays, objects, boolean and numbers will be encoded as JSON.
|
|
257
|
-
if (typeof body === 'object' || typeof body === 'number' || typeof body === 'boolean') {
|
|
258
|
-
return 'application/json';
|
|
259
|
-
}
|
|
260
|
-
// No type could be inferred.
|
|
261
|
-
return null;
|
|
262
|
-
};
|
|
263
|
-
const hasHeader = (headers, header) => {
|
|
264
|
-
return Object.keys(headers).some((key) => key.toLowerCase() === header.toLowerCase());
|
|
265
|
-
};
|
|
266
|
-
const forEachHeader = (headers, callback) => {
|
|
267
|
-
Object.entries(headers).forEach(([key, value]) => {
|
|
268
|
-
callback(key, value);
|
|
269
|
-
});
|
|
270
|
-
};
|
|
271
|
-
const parseAllXhrResponseHeaders = (xhr) => {
|
|
272
|
-
const headers = xhr.getAllResponseHeaders();
|
|
273
|
-
const parsedHeaders = {};
|
|
274
|
-
for (const line of headers.split('\n')) {
|
|
275
|
-
const index = line.indexOf(':');
|
|
276
|
-
if (index > 0) {
|
|
277
|
-
const name = line.slice(0, index);
|
|
278
|
-
const key = name.toLowerCase();
|
|
279
|
-
const value = line.slice(index + 1).trim();
|
|
280
|
-
parsedHeaders[key] = value;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
return parsedHeaders;
|
|
284
|
-
};
|
|
285
|
-
const getResponseUrl = (xhr) => {
|
|
286
|
-
if ('responseURL' in xhr && xhr.responseURL) {
|
|
287
|
-
return xhr.responseURL;
|
|
288
|
-
}
|
|
289
|
-
if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
|
|
290
|
-
return xhr.getResponseHeader('X-Request-URL');
|
|
291
|
-
}
|
|
292
|
-
return null;
|
|
293
|
-
};
|
|
294
|
-
const shouldRetryRequest = (config) => {
|
|
295
|
-
const defaultRetryDelay = 1000 + 1000 * config.currentRetryCount;
|
|
296
|
-
if (config.currentRetryCount > 3) {
|
|
297
|
-
return { retry: false };
|
|
298
|
-
}
|
|
299
|
-
if (!isRequestError(config.error)) {
|
|
300
|
-
return { retry: false };
|
|
301
|
-
}
|
|
302
|
-
const { status, detail } = config.error;
|
|
303
|
-
// Retry on 5xx errors
|
|
304
|
-
if (status >= 500) {
|
|
305
|
-
// Don't retry if a requested page is out of range
|
|
306
|
-
if (isSymfonyPagerfantaOutOfRangeError(detail)) {
|
|
307
|
-
return { retry: false };
|
|
308
|
-
}
|
|
309
|
-
return { retry: true, delay: defaultRetryDelay };
|
|
310
|
-
}
|
|
311
|
-
// Retry on 408 or 425 errors
|
|
312
|
-
if (status === 408 /* HttpStatusCode.RequestTimeout */ || status === 425 /* HttpStatusCode.TooEarly */) {
|
|
313
|
-
return { retry: true, delay: defaultRetryDelay };
|
|
314
|
-
}
|
|
315
|
-
// Retry on 429 errors
|
|
316
|
-
if (status === 429 /* HttpStatusCode.TooManyRequests */) {
|
|
317
|
-
const retryAfter = config.headers['retry-after'] ||
|
|
318
|
-
config.headers['Retry-After'] ||
|
|
319
|
-
config.headers['x-retry-after'] ||
|
|
320
|
-
config.headers['X-Retry-After'];
|
|
321
|
-
if (retryAfter) {
|
|
322
|
-
const delay = parseInt(retryAfter) * 1000;
|
|
323
|
-
return { retry: true, delay: Number.isNaN(delay) ? defaultRetryDelay : delay };
|
|
324
|
-
}
|
|
325
|
-
return { retry: true, delay: defaultRetryDelay };
|
|
326
|
-
}
|
|
327
|
-
return { retry: false };
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
const XSSI_PREFIX = /^\)\]\}',?\n/;
|
|
331
|
-
const request = (config) => {
|
|
332
|
-
const headers = config.headers || {};
|
|
333
|
-
const responseType = config.responseType || 'json';
|
|
334
|
-
const body = config.body || null;
|
|
335
|
-
const url = config.urlWithParams.split('?')[0];
|
|
336
|
-
const retryFn = config.retryFn || shouldRetryRequest;
|
|
337
|
-
let currentRetryCount = 0;
|
|
338
|
-
let retryTimeout = null;
|
|
339
|
-
return new Observable((observer) => {
|
|
340
|
-
const xhr = new XMLHttpRequest();
|
|
341
|
-
const reqBody = serializeBody(body);
|
|
342
|
-
const setupXhr = () => {
|
|
343
|
-
xhr.open(config.method, config.urlWithParams);
|
|
344
|
-
if (config.withCredentials) {
|
|
345
|
-
xhr.withCredentials = true;
|
|
346
|
-
}
|
|
347
|
-
forEachHeader(headers, (name, value) => xhr.setRequestHeader(name, value));
|
|
348
|
-
if (!hasHeader(headers, 'Accept')) {
|
|
349
|
-
xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
|
|
350
|
-
}
|
|
351
|
-
if (!hasHeader(headers, 'Content-Type')) {
|
|
352
|
-
const detectedType = detectContentTypeHeader(body);
|
|
353
|
-
if (detectedType) {
|
|
354
|
-
xhr.setRequestHeader('Content-Type', detectedType);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
xhr.responseType = responseType !== 'json' ? responseType : 'text';
|
|
358
|
-
};
|
|
359
|
-
setupXhr();
|
|
360
|
-
const partialFromXhr = () => {
|
|
361
|
-
const statusText = xhr.statusText || 'OK';
|
|
362
|
-
const headers = parseAllXhrResponseHeaders(xhr);
|
|
363
|
-
const _url = getResponseUrl(xhr) || url;
|
|
364
|
-
return { headers, status: xhr.status, statusText, url: _url };
|
|
365
|
-
};
|
|
366
|
-
const handleRetry = (error) => {
|
|
367
|
-
const newRetryCount = currentRetryCount + 1;
|
|
368
|
-
const { headers } = partialFromXhr();
|
|
369
|
-
const { retry, delay } = retryFn({ currentRetryCount: newRetryCount, headers, error });
|
|
370
|
-
if (!retry) {
|
|
371
|
-
observer.next({ type: 'failure', headers, error });
|
|
372
|
-
observer.complete();
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
const _delay = delay !== null && delay !== void 0 ? delay : 1000;
|
|
376
|
-
observer.next({ type: 'delay-retry', headers, retryNumber: newRetryCount, retryDelay: _delay });
|
|
377
|
-
retryTimeout = window.setTimeout(() => {
|
|
378
|
-
setupXhr();
|
|
379
|
-
xhr.send(reqBody);
|
|
380
|
-
currentRetryCount = newRetryCount;
|
|
381
|
-
observer.next({ type: 'start', headers, isRetry: true, retryNumber: currentRetryCount, retryDelay: _delay });
|
|
382
|
-
}, _delay);
|
|
383
|
-
};
|
|
384
|
-
const onLoad = () => {
|
|
385
|
-
var _a, _b;
|
|
386
|
-
const { headers, statusText, url } = partialFromXhr();
|
|
387
|
-
let { status } = partialFromXhr();
|
|
388
|
-
let body = null;
|
|
389
|
-
if (status !== 204 /* HttpStatusCode.NoContent */) {
|
|
390
|
-
body = typeof xhr.response === 'undefined' ? xhr.responseText : xhr.response;
|
|
391
|
-
}
|
|
392
|
-
if (status === 0) {
|
|
393
|
-
status = body ? 200 /* HttpStatusCode.Ok */ : 0;
|
|
394
|
-
}
|
|
395
|
-
let ok = status >= 200 && status < 300;
|
|
396
|
-
if (responseType === 'json' && typeof body === 'string') {
|
|
397
|
-
const originalBody = body;
|
|
398
|
-
body = body.replace(XSSI_PREFIX, '');
|
|
399
|
-
try {
|
|
400
|
-
body = body !== '' ? JSON.parse(body) : null;
|
|
401
|
-
}
|
|
402
|
-
catch (error) {
|
|
403
|
-
body = originalBody;
|
|
404
|
-
if (ok) {
|
|
405
|
-
ok = false;
|
|
406
|
-
body = { error, text: body };
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
if (ok) {
|
|
411
|
-
const successEvent = {
|
|
412
|
-
type: 'success',
|
|
413
|
-
headers,
|
|
414
|
-
response: body,
|
|
415
|
-
};
|
|
416
|
-
const expiresInSeconds = (_b = (_a = config.cacheAdapter) === null || _a === void 0 ? void 0 : _a.call(config, headers)) !== null && _b !== void 0 ? _b : extractExpiresInSeconds(headers);
|
|
417
|
-
const expiresInTimestamp = buildTimestampFromSeconds(expiresInSeconds);
|
|
418
|
-
if (expiresInTimestamp) {
|
|
419
|
-
successEvent.expiresInTimestamp = expiresInTimestamp;
|
|
420
|
-
}
|
|
421
|
-
observer.next(successEvent);
|
|
422
|
-
observer.complete();
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
handleRetry({
|
|
426
|
-
url,
|
|
427
|
-
detail: body,
|
|
428
|
-
status,
|
|
429
|
-
statusText,
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
};
|
|
433
|
-
const onError = (error) => {
|
|
434
|
-
const { url } = partialFromXhr();
|
|
435
|
-
handleRetry({
|
|
436
|
-
url,
|
|
437
|
-
detail: error,
|
|
438
|
-
status: xhr.status || 0,
|
|
439
|
-
statusText: xhr.statusText || 'Unknown Error',
|
|
440
|
-
});
|
|
441
|
-
};
|
|
442
|
-
const onDownProgress = (event) => {
|
|
443
|
-
const { headers } = partialFromXhr();
|
|
444
|
-
const progress = {
|
|
445
|
-
type: 'download-progress',
|
|
446
|
-
headers,
|
|
447
|
-
progress: {
|
|
448
|
-
current: event.loaded,
|
|
449
|
-
},
|
|
450
|
-
};
|
|
451
|
-
if (event.lengthComputable) {
|
|
452
|
-
const progressPercent = (event.loaded / event.total) * 100;
|
|
453
|
-
progress.progress.percentage = Math.round(progressPercent * 100) / 100;
|
|
454
|
-
progress.progress.total = event.total;
|
|
455
|
-
}
|
|
456
|
-
if (responseType === 'text' && !!xhr.responseText) {
|
|
457
|
-
progress.partialText = xhr.responseText;
|
|
458
|
-
}
|
|
459
|
-
observer.next(progress);
|
|
460
|
-
};
|
|
461
|
-
const onUpProgress = (event) => {
|
|
462
|
-
const { headers } = partialFromXhr();
|
|
463
|
-
const progress = {
|
|
464
|
-
type: 'upload-progress',
|
|
465
|
-
headers,
|
|
466
|
-
progress: {
|
|
467
|
-
current: event.loaded,
|
|
468
|
-
},
|
|
469
|
-
};
|
|
470
|
-
if (event.lengthComputable) {
|
|
471
|
-
const progressPercent = (event.loaded / event.total) * 100;
|
|
472
|
-
progress.progress.percentage = Math.round(progressPercent * 100) / 100;
|
|
473
|
-
progress.progress.total = event.total;
|
|
474
|
-
}
|
|
475
|
-
observer.next(progress);
|
|
476
|
-
};
|
|
477
|
-
xhr.addEventListener('load', onLoad);
|
|
478
|
-
xhr.addEventListener('error', onError);
|
|
479
|
-
xhr.addEventListener('timeout', onError);
|
|
480
|
-
xhr.addEventListener('abort', onError);
|
|
481
|
-
if (config.reportProgress) {
|
|
482
|
-
xhr.addEventListener('progress', onDownProgress);
|
|
483
|
-
if (reqBody !== null && xhr.upload) {
|
|
484
|
-
xhr.upload.addEventListener('progress', onUpProgress);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
xhr.send(reqBody);
|
|
488
|
-
observer.next({ type: 'start', headers });
|
|
489
|
-
return () => {
|
|
490
|
-
xhr.removeEventListener('error', onError);
|
|
491
|
-
xhr.removeEventListener('abort', onError);
|
|
492
|
-
xhr.removeEventListener('load', onLoad);
|
|
493
|
-
xhr.removeEventListener('timeout', onError);
|
|
494
|
-
if (retryTimeout) {
|
|
495
|
-
window.clearTimeout(retryTimeout);
|
|
496
|
-
}
|
|
497
|
-
if (config.reportProgress) {
|
|
498
|
-
xhr.removeEventListener('progress', onDownProgress);
|
|
499
|
-
if (reqBody !== null && xhr.upload) {
|
|
500
|
-
xhr.upload.removeEventListener('progress', onUpProgress);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
if (xhr.readyState !== xhr.DONE) {
|
|
504
|
-
xhr.abort();
|
|
505
|
-
}
|
|
506
|
-
observer.next({ type: 'cancel', headers });
|
|
507
|
-
};
|
|
508
|
-
});
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
const getOpName = /(query|mutation) ?([\w\d-_]+)? ?\(.*?\)? \{/;
|
|
512
|
-
const transformGql = (str) => {
|
|
513
|
-
str = Array.isArray(str) ? str.join('') : str;
|
|
514
|
-
const name = getOpName.exec(str);
|
|
515
|
-
return function (variables) {
|
|
516
|
-
const data = { query: str };
|
|
517
|
-
if (variables)
|
|
518
|
-
data['variables'] = JSON.stringify(variables);
|
|
519
|
-
if (name && name.length) {
|
|
520
|
-
const operationName = name[2];
|
|
521
|
-
if (operationName)
|
|
522
|
-
data['operationName'] = name[2];
|
|
523
|
-
}
|
|
524
|
-
return data;
|
|
525
|
-
};
|
|
526
|
-
};
|
|
527
|
-
const gql = (strings, ...values) => {
|
|
528
|
-
const str = strings.reduce((acc, cur, i) => {
|
|
529
|
-
return acc + cur + (values[i] || '');
|
|
530
|
-
}, '');
|
|
531
|
-
return str;
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
535
|
-
function filterSuccess() {
|
|
536
|
-
return function (source) {
|
|
537
|
-
return source.pipe(filter((value) => isQueryStateSuccess(value)));
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
function ignoreAutoRefresh() {
|
|
541
|
-
return function (source) {
|
|
542
|
-
return source.pipe(filter((value) => !isAutoRefresh(value)));
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
function filterFailure() {
|
|
546
|
-
return function (source) {
|
|
547
|
-
return source.pipe(filter((value) => isQueryStateFailure(value)));
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
function filterQueryStates(allowedStates) {
|
|
551
|
-
return function (source) {
|
|
552
|
-
return source.pipe(filter((value) => value && allowedStates.includes(value.type)));
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
function takeUntilResponse(config) {
|
|
556
|
-
return function (source) {
|
|
557
|
-
return source.pipe(takeWhile((value) => {
|
|
558
|
-
if ((config === null || config === void 0 ? void 0 : config.excludeNull) && value === null) {
|
|
559
|
-
return false;
|
|
560
|
-
}
|
|
561
|
-
return isQueryStateLoading(value) || value === null;
|
|
562
|
-
}, true));
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
function filterNull() {
|
|
566
|
-
return function (source) {
|
|
567
|
-
return source.pipe(filter((value) => value !== null));
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
function switchQueryState() {
|
|
571
|
-
return function (source) {
|
|
572
|
-
return source.pipe(switchMap((value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.state$) !== null && _a !== void 0 ? _a : of(null); }));
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
function switchQueryCollectionState() {
|
|
576
|
-
return function (source) {
|
|
577
|
-
return source.pipe(switchMap((value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.query.state$) !== null && _a !== void 0 ? _a : of(null); }));
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
const resetPageOnError = (config) => (source) => {
|
|
581
|
-
const { queryForm, pageControlKey = 'page' } = config;
|
|
582
|
-
if (isDevMode() && !queryForm.form.controls[pageControlKey]) {
|
|
583
|
-
console.warn(`resetPageOnError: queryForm.form.controls["${pageControlKey}"] is undefined`);
|
|
584
|
-
}
|
|
585
|
-
return source.pipe(switchMap((q) => {
|
|
586
|
-
if (!q) {
|
|
587
|
-
return of(q);
|
|
588
|
-
}
|
|
589
|
-
return q.state$.pipe(tap((state) => {
|
|
590
|
-
var _a;
|
|
591
|
-
if (!isQueryStateFailure(state)) {
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
switch (state.error.status) {
|
|
595
|
-
// The page is invalid (in prod mode, code is 416)
|
|
596
|
-
case 416 /* HttpStatusCode.RangeNotSatisfiable */:
|
|
597
|
-
(_a = queryForm.form.controls[pageControlKey]) === null || _a === void 0 ? void 0 : _a.patchValue(1);
|
|
598
|
-
break;
|
|
599
|
-
// The page might be invalid (in dev mode, code is 500)
|
|
600
|
-
case 500 /* HttpStatusCode.InternalServerError */:
|
|
601
|
-
if (isSymfonyPagerfantaOutOfRangeError(state.error.detail)) {
|
|
602
|
-
queryForm.form.controls[pageControlKey].patchValue(1);
|
|
603
|
-
}
|
|
604
|
-
break;
|
|
605
|
-
}
|
|
606
|
-
}), takeUntilResponse());
|
|
607
|
-
}));
|
|
608
|
-
};
|
|
609
|
-
const isQueryStateLoading = (state) => (state === null || state === void 0 ? void 0 : state.type) === "LOADING" /* QueryStateType.Loading */;
|
|
610
|
-
const isQueryStateSuccess = (state) => (state === null || state === void 0 ? void 0 : state.type) === "SUCCESS" /* QueryStateType.Success */;
|
|
611
|
-
const isQueryStateFailure = (state) => (state === null || state === void 0 ? void 0 : state.type) === "FAILURE" /* QueryStateType.Failure */;
|
|
612
|
-
const isQueryStateCancelled = (state) => (state === null || state === void 0 ? void 0 : state.type) === "CANCELLED" /* QueryStateType.Cancelled */;
|
|
613
|
-
const isQueryStatePrepared = (state) => (state === null || state === void 0 ? void 0 : state.type) === "PREPARED" /* QueryStateType.Prepared */;
|
|
614
|
-
const isAutoRefresh = (state) => (state === null || state === void 0 ? void 0 : state.meta.triggeredVia) === 'auto';
|
|
615
|
-
const mergeHeaders = (...headers) => {
|
|
616
|
-
return headers.reduce((acc, headers) => {
|
|
617
|
-
if (!headers) {
|
|
618
|
-
return acc;
|
|
619
|
-
}
|
|
620
|
-
return Object.assign(Object.assign({}, acc), headers);
|
|
621
|
-
}, {});
|
|
622
|
-
};
|
|
623
|
-
const isGqlQueryConfig = (config) => {
|
|
624
|
-
if (!config || typeof config !== 'object' || Array.isArray(config)) {
|
|
625
|
-
return false;
|
|
626
|
-
}
|
|
627
|
-
if (!('query' in config)) {
|
|
628
|
-
return false;
|
|
629
|
-
}
|
|
630
|
-
return true;
|
|
631
|
-
};
|
|
632
|
-
const isQuery = (query) => {
|
|
633
|
-
if (!query || typeof query !== 'object' || Array.isArray(query)) {
|
|
634
|
-
return false;
|
|
635
|
-
}
|
|
636
|
-
if (!('state$' in query)) {
|
|
637
|
-
return false;
|
|
638
|
-
}
|
|
639
|
-
return true;
|
|
640
|
-
};
|
|
641
|
-
const createQueryCollection = (
|
|
642
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
643
|
-
queryMap) => new BehaviorSubject(null);
|
|
644
|
-
const extractQuery = (v) => { var _a; return (_a = (isQuery(v) ? v : v === null || v === void 0 ? void 0 : v.query)) !== null && _a !== void 0 ? _a : null; };
|
|
645
|
-
const getDefaultHeaders = (headers, method) => {
|
|
646
|
-
var _a;
|
|
647
|
-
if (!headers) {
|
|
648
|
-
return {};
|
|
649
|
-
}
|
|
650
|
-
if (method in headers) {
|
|
651
|
-
return ((_a = headers[method]) !== null && _a !== void 0 ? _a : {});
|
|
652
|
-
}
|
|
653
|
-
return headers;
|
|
654
|
-
};
|
|
655
|
-
const castQueryCreatorTypes = (config) => {
|
|
656
|
-
var _a;
|
|
657
|
-
if ((_a = config.args) === null || _a === void 0 ? void 0 : _a.pathParams) {
|
|
658
|
-
console.error(config);
|
|
659
|
-
throw new Error('Path params cannot be overridden in castQueryCreatorTypes. Create a new query creator instead.');
|
|
660
|
-
}
|
|
661
|
-
return config.creator;
|
|
662
|
-
};
|
|
663
|
-
const computeQueryMethod = (config) => {
|
|
664
|
-
var _a, _b, _c;
|
|
665
|
-
let method;
|
|
666
|
-
if (isGqlQueryConfig(config.config)) {
|
|
667
|
-
const transferVia = (_a = config.config.transferVia) !== null && _a !== void 0 ? _a : (_c = (_b = config.client.config.request) === null || _b === void 0 ? void 0 : _b.gql) === null || _c === void 0 ? void 0 : _c.transferVia;
|
|
668
|
-
method = transformMethod({ method: config.config.method, transferVia });
|
|
669
|
-
}
|
|
670
|
-
else {
|
|
671
|
-
method = transformMethod({ method: config.config.method });
|
|
672
|
-
}
|
|
673
|
-
return method;
|
|
674
|
-
};
|
|
675
|
-
const computeQueryBody = (config) => {
|
|
676
|
-
var _a, _b, _c, _d;
|
|
677
|
-
let body;
|
|
678
|
-
if (config.method === 'GET' ||
|
|
679
|
-
config.method === 'HEAD' ||
|
|
680
|
-
config.method === 'OPTIONS' ||
|
|
681
|
-
(isGqlQueryConfig(config.config) &&
|
|
682
|
-
(config.config.transferVia === 'GET' ||
|
|
683
|
-
(((_b = (_a = config.client.config.request) === null || _a === void 0 ? void 0 : _a.gql) === null || _b === void 0 ? void 0 : _b.transferVia) === 'GET' && !config.config.transferVia)))) {
|
|
684
|
-
return undefined;
|
|
685
|
-
}
|
|
686
|
-
if (isGqlQueryConfig(config.config)) {
|
|
687
|
-
const queryTemplate = config.config.query;
|
|
688
|
-
const query = transformGql(queryTemplate);
|
|
689
|
-
body = query((_c = config.args) === null || _c === void 0 ? void 0 : _c.variables);
|
|
690
|
-
}
|
|
691
|
-
else {
|
|
692
|
-
body = (_d = config.args) === null || _d === void 0 ? void 0 : _d.body;
|
|
693
|
-
}
|
|
694
|
-
return body;
|
|
695
|
-
};
|
|
696
|
-
const computeQueryAuthHeader = (config) => {
|
|
697
|
-
var _a, _b;
|
|
698
|
-
let authHeader = null;
|
|
699
|
-
if (config.config.secure) {
|
|
700
|
-
const header = (_a = config.client.authProvider) === null || _a === void 0 ? void 0 : _a.header;
|
|
701
|
-
if (header) {
|
|
702
|
-
authHeader = header;
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
else if ((_b = config.client.authProvider) === null || _b === void 0 ? void 0 : _b.header) {
|
|
706
|
-
if (config.config.secure === undefined || config.config.secure) {
|
|
707
|
-
authHeader = config.client.authProvider.header;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
return authHeader;
|
|
711
|
-
};
|
|
712
|
-
const computeQueryHeaders = (config) => {
|
|
713
|
-
var _a, _b;
|
|
714
|
-
const authHeader = computeQueryAuthHeader(config);
|
|
715
|
-
const mergedHeaders = mergeHeaders(getDefaultHeaders((_a = config.client.config.request) === null || _a === void 0 ? void 0 : _a.headers, config.config.method), authHeader, (_b = config.args) === null || _b === void 0 ? void 0 : _b.headers) || undefined;
|
|
716
|
-
return mergedHeaders;
|
|
717
|
-
};
|
|
718
|
-
const computeQueryQueryParams = (config) => {
|
|
719
|
-
var _a, _b, _c, _d, _e, _f;
|
|
720
|
-
if (isGqlQueryConfig(config.config) &&
|
|
721
|
-
(config.config.transferVia === 'GET' ||
|
|
722
|
-
(((_b = (_a = config.client.config.request) === null || _a === void 0 ? void 0 : _a.gql) === null || _b === void 0 ? void 0 : _b.transferVia) === 'GET' && !config.config.transferVia))) {
|
|
723
|
-
const queryTemplate = config.config.query;
|
|
724
|
-
const query = transformGql(queryTemplate);
|
|
725
|
-
let params = query((_c = config.args) === null || _c === void 0 ? void 0 : _c.variables);
|
|
726
|
-
if ((_d = config.args) === null || _d === void 0 ? void 0 : _d.queryParams) {
|
|
727
|
-
params = Object.assign(Object.assign({}, params), (_e = config.args) === null || _e === void 0 ? void 0 : _e.queryParams);
|
|
728
|
-
}
|
|
729
|
-
return params;
|
|
730
|
-
}
|
|
731
|
-
return (_f = config.args) === null || _f === void 0 ? void 0 : _f.queryParams;
|
|
732
|
-
};
|
|
733
|
-
const paginatedEntityValueUpdater = (findFn) => ({ response, rawResponse, entity }) => {
|
|
734
|
-
const indexOfEntityRaw = rawResponse.items.findIndex((item) => findFn(item, entity));
|
|
735
|
-
const indexOfEntity = response.items.findIndex((item) => findFn(item, entity));
|
|
736
|
-
if (indexOfEntity === -1 || indexOfEntityRaw === -1) {
|
|
737
|
-
return null;
|
|
738
|
-
}
|
|
739
|
-
const newRawResponse = Object.assign(Object.assign({}, rawResponse), { items: [
|
|
740
|
-
...rawResponse.items.slice(0, indexOfEntityRaw),
|
|
741
|
-
entity,
|
|
742
|
-
...rawResponse.items.slice(indexOfEntityRaw + 1),
|
|
743
|
-
] });
|
|
744
|
-
const newResponse = Object.assign(Object.assign({}, response), { items: [...response.items.slice(0, indexOfEntity), entity, ...response.items.slice(indexOfEntity + 1)] });
|
|
745
|
-
return {
|
|
746
|
-
response: newResponse,
|
|
747
|
-
rawResponse: newRawResponse,
|
|
748
|
-
};
|
|
749
|
-
};
|
|
750
|
-
|
|
751
|
-
class Query {
|
|
752
|
-
get _nextId() {
|
|
753
|
-
return ++this._currentId;
|
|
754
|
-
}
|
|
755
|
-
get state$() {
|
|
756
|
-
return this._state$.pipe(switchMap((s) => this._transformState(s)), shareReplay({ bufferSize: 1, refCount: true }));
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* The current state of the query.
|
|
760
|
-
*
|
|
761
|
-
* **Warning!** This differs from the `state$` observable in that it does not use the query store. Thus, the response data might be outdated.
|
|
762
|
-
* Use `state$` (or `firstValueFrom(state$)`) the most up-to-date data.
|
|
763
|
-
*/
|
|
764
|
-
get rawState() {
|
|
765
|
-
return this._state$.value;
|
|
766
|
-
}
|
|
767
|
-
get isExpired() {
|
|
768
|
-
if (!isQueryStateSuccess(this._state$.value)) {
|
|
769
|
-
return false;
|
|
770
|
-
}
|
|
771
|
-
const ts = this._state$.value.meta.expiresAt;
|
|
772
|
-
if (!ts) {
|
|
773
|
-
return true;
|
|
774
|
-
}
|
|
775
|
-
return ts < Date.now();
|
|
776
|
-
}
|
|
777
|
-
get isInUse() {
|
|
778
|
-
return this._state$.subscriberCount > 0;
|
|
779
|
-
}
|
|
780
|
-
get isPolling() {
|
|
781
|
-
return !!this._pollingSubscription;
|
|
782
|
-
}
|
|
783
|
-
get autoRefreshOnConfig() {
|
|
784
|
-
var _a, _b, _c;
|
|
785
|
-
const base = (_a = this._queryConfig.autoRefreshOn) !== null && _a !== void 0 ? _a : {};
|
|
786
|
-
const transformed = {
|
|
787
|
-
queryClientDefaultHeadersChange: (_b = base.queryClientDefaultHeadersChange) !== null && _b !== void 0 ? _b : true,
|
|
788
|
-
windowFocus: (_c = base.windowFocus) !== null && _c !== void 0 ? _c : true,
|
|
789
|
-
};
|
|
790
|
-
return transformed;
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* @internal
|
|
794
|
-
*/
|
|
795
|
-
get _enableSmartPolling() {
|
|
796
|
-
var _a;
|
|
797
|
-
return (_a = this._queryConfig.enableSmartPolling) !== null && _a !== void 0 ? _a : true;
|
|
798
|
-
}
|
|
799
|
-
get store() {
|
|
800
|
-
var _a, _b;
|
|
801
|
-
return (_b = (_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.store) !== null && _b !== void 0 ? _b : null;
|
|
802
|
-
}
|
|
803
|
-
constructor(_client, _queryConfig, _routeWithParams, _args) {
|
|
804
|
-
this._client = _client;
|
|
805
|
-
this._queryConfig = _queryConfig;
|
|
806
|
-
this._routeWithParams = _routeWithParams;
|
|
807
|
-
this._args = _args;
|
|
808
|
-
this._currentId = 0;
|
|
809
|
-
this._pollingSubscription = null;
|
|
810
|
-
this._requestSubscription = null;
|
|
811
|
-
this._onAbort$ = new Subject();
|
|
812
|
-
this._currentPollConfig = null;
|
|
813
|
-
/**
|
|
814
|
-
* @internal
|
|
815
|
-
*/
|
|
816
|
-
this._isPollingPaused = false;
|
|
817
|
-
this._state$ = new BehaviorSubjectWithSubscriberCount({
|
|
818
|
-
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
819
|
-
meta: { id: this._currentId, triggeredVia: 'program' },
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
execute(options = {}) {
|
|
823
|
-
var _a, _b;
|
|
824
|
-
const { skipCache = false, _triggeredVia: triggeredVia = 'program' } = options;
|
|
825
|
-
const { authProvider } = this._client;
|
|
826
|
-
const queryConfig = this._queryConfig;
|
|
827
|
-
if (!this.isExpired && !skipCache && isQueryStateSuccess(this.rawState)) {
|
|
828
|
-
return this;
|
|
829
|
-
}
|
|
830
|
-
if (queryConfig.secure && !authProvider) {
|
|
831
|
-
throw new Error('Cannot execute secure query without auth provider');
|
|
832
|
-
}
|
|
833
|
-
const id = this._nextId;
|
|
834
|
-
const meta = { id, triggeredVia };
|
|
835
|
-
if (isQueryStateLoading(this.rawState)) {
|
|
836
|
-
this.abort();
|
|
837
|
-
}
|
|
838
|
-
this._state$.next({ type: "LOADING" /* QueryStateType.Loading */, meta });
|
|
839
|
-
const method = computeQueryMethod({ config: queryConfig, client: this._client });
|
|
840
|
-
const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._args, method });
|
|
841
|
-
const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._args });
|
|
842
|
-
this._requestSubscription = request({
|
|
843
|
-
urlWithParams: this._routeWithParams,
|
|
844
|
-
method,
|
|
845
|
-
body,
|
|
846
|
-
headers,
|
|
847
|
-
reportProgress: queryConfig.reportProgress,
|
|
848
|
-
responseType: queryConfig.responseType,
|
|
849
|
-
withCredentials: queryConfig.withCredentials,
|
|
850
|
-
cacheAdapter: (_a = this._client.config.request) === null || _a === void 0 ? void 0 : _a.cacheAdapter,
|
|
851
|
-
retryFn: (_b = this._client.config.request) === null || _b === void 0 ? void 0 : _b.retryFn,
|
|
852
|
-
})
|
|
853
|
-
.pipe(takeUntil(this._onAbort$), tap((state) => this._updateEntityState(state, meta, options)))
|
|
854
|
-
.subscribe();
|
|
855
|
-
return this;
|
|
856
|
-
}
|
|
857
|
-
abort() {
|
|
858
|
-
this._onAbort$.next();
|
|
859
|
-
return this;
|
|
860
|
-
}
|
|
861
|
-
poll(config) {
|
|
862
|
-
if (this._pollingSubscription) {
|
|
863
|
-
return this;
|
|
864
|
-
}
|
|
865
|
-
this._currentPollConfig = config;
|
|
866
|
-
const interval$ = interval(config.interval);
|
|
867
|
-
const poll$ = interval$.pipe(skip(config.triggerImmediately ? 0 : 1), takeUntil(config.takeUntil), takeWhile(() => !this._isPollingPaused), filter(() => !isQueryStateLoading(this._state$.value)));
|
|
868
|
-
this._pollingSubscription = poll$.subscribe({
|
|
869
|
-
next: () => this.execute({ skipCache: true, _triggeredVia: 'poll' }),
|
|
870
|
-
complete: () => this.stopPolling(),
|
|
871
|
-
});
|
|
872
|
-
return this;
|
|
873
|
-
}
|
|
874
|
-
stopPolling() {
|
|
875
|
-
var _a;
|
|
876
|
-
(_a = this._pollingSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
877
|
-
this._pollingSubscription = null;
|
|
878
|
-
this._currentPollConfig = null;
|
|
879
|
-
return this;
|
|
880
|
-
}
|
|
881
|
-
pausePolling() {
|
|
882
|
-
var _a;
|
|
883
|
-
(_a = this._pollingSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
884
|
-
this._pollingSubscription = null;
|
|
885
|
-
this._isPollingPaused = true;
|
|
886
|
-
return this;
|
|
887
|
-
}
|
|
888
|
-
resumePolling() {
|
|
889
|
-
if (!this._isPollingPaused || !this._currentPollConfig) {
|
|
890
|
-
return this;
|
|
891
|
-
}
|
|
892
|
-
this._isPollingPaused = false;
|
|
893
|
-
return this.poll(Object.assign(Object.assign({}, this._currentPollConfig), { triggerImmediately: true }));
|
|
894
|
-
}
|
|
895
|
-
/**
|
|
896
|
-
* @internal
|
|
897
|
-
*/
|
|
898
|
-
_destroy() {
|
|
899
|
-
var _a, _b;
|
|
900
|
-
this._state$.complete();
|
|
901
|
-
this._onAbort$.complete();
|
|
902
|
-
(_a = this._pollingSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
903
|
-
(_b = this._requestSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
|
|
904
|
-
}
|
|
905
|
-
_getBearerAuthProvider() {
|
|
906
|
-
const authProvider = this._client.authProvider;
|
|
907
|
-
if (authProvider && isBearerAuthProvider(authProvider)) {
|
|
908
|
-
return authProvider;
|
|
909
|
-
}
|
|
910
|
-
return null;
|
|
911
|
-
}
|
|
912
|
-
_updateEntityState(requestEvent, meta, options) {
|
|
913
|
-
var _a, _b;
|
|
914
|
-
switch (requestEvent.type) {
|
|
915
|
-
case 'start':
|
|
916
|
-
case 'delay-retry': {
|
|
917
|
-
const { type, retryDelay, retryNumber } = requestEvent;
|
|
918
|
-
const newMeta = Object.assign(Object.assign({}, meta), { isWaitingForRetry: type === 'delay-retry', retryDelay, retryNumber });
|
|
919
|
-
this._state$.next({
|
|
920
|
-
type: "LOADING" /* QueryStateType.Loading */,
|
|
921
|
-
meta: newMeta,
|
|
922
|
-
});
|
|
923
|
-
break;
|
|
924
|
-
}
|
|
925
|
-
case 'upload-progress':
|
|
926
|
-
case 'download-progress': {
|
|
927
|
-
this._state$.next({
|
|
928
|
-
type: "LOADING" /* QueryStateType.Loading */,
|
|
929
|
-
progress: requestEvent.progress,
|
|
930
|
-
partialText: 'partialText' in requestEvent ? requestEvent.partialText : undefined,
|
|
931
|
-
meta,
|
|
932
|
-
});
|
|
933
|
-
break;
|
|
934
|
-
}
|
|
935
|
-
case 'success': {
|
|
936
|
-
const { response, expiresInTimestamp } = requestEvent;
|
|
937
|
-
const isGql = isGqlQueryConfig(this._queryConfig);
|
|
938
|
-
const responseData = isGql && typeof response === 'object' && !!response && 'data' in response
|
|
939
|
-
? response['data']
|
|
940
|
-
: response;
|
|
941
|
-
if (this._queryConfig.entity && this._queryConfig.entity.set) {
|
|
942
|
-
const id = (_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.id({ args: this._args, response: responseData });
|
|
943
|
-
(_b = this._queryConfig.entity) === null || _b === void 0 ? void 0 : _b.set({
|
|
944
|
-
args: this._args,
|
|
945
|
-
response: responseData,
|
|
946
|
-
id,
|
|
947
|
-
store: this._queryConfig.entity.store,
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
this._state$.next({
|
|
951
|
-
type: "SUCCESS" /* QueryStateType.Success */,
|
|
952
|
-
response: responseData,
|
|
953
|
-
meta: Object.assign(Object.assign({}, meta), { expiresAt: expiresInTimestamp }),
|
|
954
|
-
});
|
|
955
|
-
break;
|
|
956
|
-
}
|
|
957
|
-
case 'failure': {
|
|
958
|
-
const { error } = requestEvent;
|
|
959
|
-
const failure = () => this._state$.next({ type: "FAILURE" /* QueryStateType.Failure */, error, meta });
|
|
960
|
-
const bearerAuthProvider = this._getBearerAuthProvider();
|
|
961
|
-
if (!bearerAuthProvider ||
|
|
962
|
-
(options === null || options === void 0 ? void 0 : options._isUnauthorizedRetry) ||
|
|
963
|
-
error.status !== 401 /* HttpStatusCode.Unauthorized */ ||
|
|
964
|
-
!bearerAuthProvider.shouldRefreshOnUnauthorizedResponse) {
|
|
965
|
-
return failure();
|
|
966
|
-
}
|
|
967
|
-
const query = bearerAuthProvider._refreshQuery();
|
|
968
|
-
if (!query)
|
|
969
|
-
return failure();
|
|
970
|
-
query.state$
|
|
971
|
-
.pipe(takeUntilResponse(), takeUntil(this._onAbort$), tap((state) => isQueryStateSuccess(state) ? this.execute(Object.assign(Object.assign({}, options), { _isUnauthorizedRetry: true })) : failure()))
|
|
972
|
-
.subscribe();
|
|
973
|
-
break;
|
|
974
|
-
}
|
|
975
|
-
case 'cancel': {
|
|
976
|
-
this._state$.next({
|
|
977
|
-
type: "CANCELLED" /* QueryStateType.Cancelled */,
|
|
978
|
-
meta,
|
|
979
|
-
});
|
|
980
|
-
break;
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
_transformState(s) {
|
|
985
|
-
var _a;
|
|
986
|
-
if (!isQueryStateSuccess(s) || !((_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.get)) {
|
|
987
|
-
return of(s);
|
|
988
|
-
}
|
|
989
|
-
const id = this._queryConfig.entity.id({ args: this._args, response: s.response });
|
|
990
|
-
return this._queryConfig.entity
|
|
991
|
-
.get({ args: this._args, id, response: s.response, store: this._queryConfig.entity.store })
|
|
992
|
-
.pipe(map((v) => (Object.assign(Object.assign({}, s), { response: v }))));
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
|
|
997
|
-
const isBearerAuthProvider = (authProvider) => authProvider instanceof BearerAuthProvider;
|
|
998
|
-
const isCustomHeaderAuthProvider = (authProvider) => authProvider instanceof CustomHeaderAuthProvider;
|
|
999
|
-
const decryptBearer = (token) => {
|
|
1000
|
-
try {
|
|
1001
|
-
const base64Url = token.split('.')[1];
|
|
1002
|
-
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
1003
|
-
const jsonPayload = decodeURIComponent(atob(base64)
|
|
1004
|
-
.split('')
|
|
1005
|
-
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
1006
|
-
.join(''));
|
|
1007
|
-
return JSON.parse(jsonPayload);
|
|
1008
|
-
}
|
|
1009
|
-
catch (error) {
|
|
1010
|
-
console.error(`Invalid bearer token: ${token}`, error);
|
|
1011
|
-
return null;
|
|
1012
|
-
}
|
|
1013
|
-
};
|
|
1014
|
-
|
|
1015
|
-
class BearerAuthProvider {
|
|
1016
|
-
get header() {
|
|
1017
|
-
return { Authorization: `Bearer ${this._tokens$.getValue().token}` };
|
|
1018
|
-
}
|
|
1019
|
-
get tokens$() {
|
|
1020
|
-
return this._tokens$.asObservable();
|
|
1021
|
-
}
|
|
1022
|
-
get tokens() {
|
|
1023
|
-
return this._tokens$.getValue();
|
|
1024
|
-
}
|
|
1025
|
-
get currentRefreshQuery$() {
|
|
1026
|
-
return this._currentRefreshQuery$.asObservable();
|
|
1027
|
-
}
|
|
1028
|
-
get currentRefreshQuery() {
|
|
1029
|
-
return this._currentRefreshQuery$.getValue();
|
|
1030
|
-
}
|
|
1031
|
-
get shouldRefreshOnUnauthorizedResponse() {
|
|
1032
|
-
return (!!this._config.refreshConfig &&
|
|
1033
|
-
(this._config.refreshConfig.refreshOnUnauthorizedResponse === undefined ||
|
|
1034
|
-
this._config.refreshConfig.refreshOnUnauthorizedResponse));
|
|
1035
|
-
}
|
|
1036
|
-
constructor(_config) {
|
|
1037
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1038
|
-
this._config = _config;
|
|
1039
|
-
this._destroy$ = new Subject();
|
|
1040
|
-
this._currentRefreshQuery$ = new BehaviorSubject(null);
|
|
1041
|
-
this._tokens$ = new BehaviorSubject({
|
|
1042
|
-
token: null,
|
|
1043
|
-
refreshToken: null,
|
|
1044
|
-
});
|
|
1045
|
-
const cookieEnabled = (_b = (_a = _config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieEnabled) !== null && _b !== void 0 ? _b : true;
|
|
1046
|
-
const cookieToken = ((_c = _config.refreshConfig) === null || _c === void 0 ? void 0 : _c.cookieName) && cookieEnabled ? (_d = getCookie(_config.refreshConfig.cookieName)) !== null && _d !== void 0 ? _d : null : null;
|
|
1047
|
-
this._tokens$.next({
|
|
1048
|
-
token: _config.token || null,
|
|
1049
|
-
refreshToken: ((_e = _config.refreshConfig) === null || _e === void 0 ? void 0 : _e.token) || cookieToken || null,
|
|
1050
|
-
});
|
|
1051
|
-
if (!this.tokens.token && !this.tokens.refreshToken) {
|
|
1052
|
-
if (!((_f = _config.refreshConfig) === null || _f === void 0 ? void 0 : _f.cookieName)) {
|
|
1053
|
-
console.error('A BearerAuthProvider was created without token or refresh token. You should provide at least a cookieName where the refresh token might be stored.');
|
|
1054
|
-
}
|
|
1055
|
-
return;
|
|
1056
|
-
}
|
|
1057
|
-
if (this.tokens.token) {
|
|
1058
|
-
this._prepareForRefresh();
|
|
1059
|
-
if (this.tokens.refreshToken && ((_g = this._config.refreshConfig) === null || _g === void 0 ? void 0 : _g.cookieName) && cookieEnabled) {
|
|
1060
|
-
setCookie(this._config.refreshConfig.cookieName, this.tokens.refreshToken);
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
else if (this.tokens.refreshToken) {
|
|
1064
|
-
this._refreshQuery();
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
cleanUp() {
|
|
1068
|
-
var _a;
|
|
1069
|
-
this._destroy$.next(true);
|
|
1070
|
-
this._destroy$.unsubscribe();
|
|
1071
|
-
this._currentRefreshQuery$.next(null);
|
|
1072
|
-
if ((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieName) {
|
|
1073
|
-
deleteCookie(this._config.refreshConfig.cookieName, '/');
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
enableCookie() {
|
|
1077
|
-
var _a;
|
|
1078
|
-
if (!((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieName)) {
|
|
1079
|
-
throw new Error('No cookie name was provided');
|
|
1080
|
-
}
|
|
1081
|
-
if (!this.tokens.refreshToken) {
|
|
1082
|
-
throw new Error('No refresh token was provided');
|
|
1083
|
-
}
|
|
1084
|
-
this._config.refreshConfig.cookieEnabled = true;
|
|
1085
|
-
setCookie(this._config.refreshConfig.cookieName, this.tokens.refreshToken);
|
|
1086
|
-
}
|
|
1087
|
-
disableCookie() {
|
|
1088
|
-
var _a;
|
|
1089
|
-
if (!((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieName)) {
|
|
1090
|
-
throw new Error('No cookie name was provided');
|
|
1091
|
-
}
|
|
1092
|
-
this._config.refreshConfig.cookieEnabled = false;
|
|
1093
|
-
deleteCookie(this._config.refreshConfig.cookieName, '/');
|
|
1094
|
-
}
|
|
1095
|
-
_prepareForRefresh() {
|
|
1096
|
-
var _a, _b;
|
|
1097
|
-
if (!this.tokens.token || !this._config.refreshConfig) {
|
|
1098
|
-
return;
|
|
1099
|
-
}
|
|
1100
|
-
const bearer = decryptBearer(this.tokens.token);
|
|
1101
|
-
if (!bearer) {
|
|
1102
|
-
return;
|
|
1103
|
-
}
|
|
1104
|
-
const expiresInPropertyName = this._config.refreshConfig.expiresInPropertyName || 'exp';
|
|
1105
|
-
const expiresIn = bearer[expiresInPropertyName];
|
|
1106
|
-
const fiveMinutes = 5 * 60 * 1000;
|
|
1107
|
-
const refreshBuffer = (_a = this._config.refreshConfig.refreshBuffer) !== null && _a !== void 0 ? _a : fiveMinutes;
|
|
1108
|
-
if (expiresIn === undefined) {
|
|
1109
|
-
throw new Error(`Bearer token does not contain an '${expiresInPropertyName}' property`);
|
|
1110
|
-
}
|
|
1111
|
-
const remainingTime = new Date(expiresIn * 1000).getTime() - refreshBuffer - new Date().getTime();
|
|
1112
|
-
const strategy = (_b = this._config.refreshConfig.strategy) !== null && _b !== void 0 ? _b : "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */;
|
|
1113
|
-
switch (strategy) {
|
|
1114
|
-
case "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */:
|
|
1115
|
-
timer(remainingTime)
|
|
1116
|
-
.pipe(takeUntil(this._destroy$))
|
|
1117
|
-
.subscribe(() => this._refreshQuery());
|
|
1118
|
-
break;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
/**
|
|
1122
|
-
* @internal
|
|
1123
|
-
*/
|
|
1124
|
-
_refreshQuery() {
|
|
1125
|
-
var _a, _b, _c, _d;
|
|
1126
|
-
if (isQueryStateLoading((_a = this._currentRefreshQuery$.getValue()) === null || _a === void 0 ? void 0 : _a.rawState)) {
|
|
1127
|
-
return;
|
|
1128
|
-
}
|
|
1129
|
-
const currentRefreshToken = this.tokens.refreshToken;
|
|
1130
|
-
if (!currentRefreshToken || !this._config.refreshConfig) {
|
|
1131
|
-
return;
|
|
1132
|
-
}
|
|
1133
|
-
const args = (_d = (_c = (_b = this._config.refreshConfig).requestArgsAdapter) === null || _c === void 0 ? void 0 : _c.call(_b, {
|
|
1134
|
-
token: this.tokens.token,
|
|
1135
|
-
refreshToken: currentRefreshToken,
|
|
1136
|
-
})) !== null && _d !== void 0 ? _d : {
|
|
1137
|
-
body: { refreshToken: currentRefreshToken },
|
|
1138
|
-
};
|
|
1139
|
-
const query = this._config.refreshConfig.queryCreator.prepare(args).execute({ skipCache: true });
|
|
1140
|
-
this._currentRefreshQuery$.next(query);
|
|
1141
|
-
this._currentRefreshQuery$
|
|
1142
|
-
.pipe(switchQueryState(), tap((state) => {
|
|
1143
|
-
var _a, _b, _c, _d, _e;
|
|
1144
|
-
if (isQueryStateSuccess(state)) {
|
|
1145
|
-
if ((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.responseAdapter) {
|
|
1146
|
-
const tokens = this._config.refreshConfig.responseAdapter(state.response);
|
|
1147
|
-
this._tokens$.next(tokens);
|
|
1148
|
-
}
|
|
1149
|
-
else {
|
|
1150
|
-
this._tokens$.next({
|
|
1151
|
-
token: state.response['token'],
|
|
1152
|
-
refreshToken: state.response['refreshToken'],
|
|
1153
|
-
});
|
|
1154
|
-
}
|
|
1155
|
-
const cookieEnabled = (_c = (_b = this._config.refreshConfig) === null || _b === void 0 ? void 0 : _b.cookieEnabled) !== null && _c !== void 0 ? _c : true;
|
|
1156
|
-
if (((_d = this._config.refreshConfig) === null || _d === void 0 ? void 0 : _d.cookieName) && this.tokens.refreshToken && cookieEnabled) {
|
|
1157
|
-
setCookie(this._config.refreshConfig.cookieName, this.tokens.refreshToken);
|
|
1158
|
-
}
|
|
1159
|
-
this._prepareForRefresh();
|
|
1160
|
-
}
|
|
1161
|
-
else if (isQueryStateFailure(state)) {
|
|
1162
|
-
this._tokens$.next({ token: null, refreshToken: null });
|
|
1163
|
-
if ((_e = this._config.refreshConfig) === null || _e === void 0 ? void 0 : _e.cookieName) {
|
|
1164
|
-
deleteCookie(this._config.refreshConfig.cookieName, '/');
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
}), takeUntilResponse(), takeUntil(this._destroy$))
|
|
1168
|
-
.subscribe();
|
|
1169
|
-
return query;
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
class QueryDirective {
|
|
1174
|
-
get query() {
|
|
1175
|
-
return this._query;
|
|
1176
|
-
}
|
|
1177
|
-
set query(v) {
|
|
1178
|
-
this._query = v;
|
|
1179
|
-
this._subscribeToQuery();
|
|
1180
|
-
}
|
|
1181
|
-
get cache() {
|
|
1182
|
-
return this._cache;
|
|
1183
|
-
}
|
|
1184
|
-
set cache(v) {
|
|
1185
|
-
this._cache = v;
|
|
1186
|
-
}
|
|
1187
|
-
constructor(_mainTemplateRef, _viewContainerRef, _errorHandler, _cdr) {
|
|
1188
|
-
this._mainTemplateRef = _mainTemplateRef;
|
|
1189
|
-
this._viewContainerRef = _viewContainerRef;
|
|
1190
|
-
this._errorHandler = _errorHandler;
|
|
1191
|
-
this._cdr = _cdr;
|
|
1192
|
-
this._isMainViewCreated = false;
|
|
1193
|
-
this._subscription = null;
|
|
1194
|
-
this._viewContext = {
|
|
1195
|
-
$implicit: null,
|
|
1196
|
-
etQuery: null,
|
|
1197
|
-
loading: false,
|
|
1198
|
-
refreshing: false,
|
|
1199
|
-
error: null,
|
|
1200
|
-
progress: null,
|
|
1201
|
-
};
|
|
1202
|
-
this._cache = false;
|
|
1203
|
-
}
|
|
1204
|
-
static ngTemplateContextGuard(dir, ctx) {
|
|
1205
|
-
return true;
|
|
1206
|
-
}
|
|
1207
|
-
ngOnInit() {
|
|
1208
|
-
this._renderMainView();
|
|
1209
|
-
}
|
|
1210
|
-
ngOnDestroy() {
|
|
1211
|
-
var _a;
|
|
1212
|
-
(_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
1213
|
-
}
|
|
1214
|
-
_subscribeToQuery() {
|
|
1215
|
-
var _a;
|
|
1216
|
-
(_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
1217
|
-
this._subscription = null;
|
|
1218
|
-
if (!this.query) {
|
|
1219
|
-
this._viewContext.$implicit = null;
|
|
1220
|
-
this._viewContext.etQuery = null;
|
|
1221
|
-
this._viewContext.loading = false;
|
|
1222
|
-
this._viewContext.refreshing = false;
|
|
1223
|
-
this._viewContext.error = null;
|
|
1224
|
-
this._viewContext.progress = null;
|
|
1225
|
-
return;
|
|
1226
|
-
}
|
|
1227
|
-
const query = isQuery(this.query) ? this.query : this.query.query;
|
|
1228
|
-
const sub = query.state$.pipe(tap((state) => this._updateView(state))).subscribe();
|
|
1229
|
-
this._subscription = sub;
|
|
1230
|
-
}
|
|
1231
|
-
_updateView(state) {
|
|
1232
|
-
var _a;
|
|
1233
|
-
if (isQueryStateLoading(state)) {
|
|
1234
|
-
this._viewContext.loading = true;
|
|
1235
|
-
this._viewContext.progress = (_a = state.progress) !== null && _a !== void 0 ? _a : null;
|
|
1236
|
-
this._viewContext.refreshing = state.meta.triggeredVia === 'auto' || state.meta.triggeredVia === 'poll';
|
|
1237
|
-
}
|
|
1238
|
-
else {
|
|
1239
|
-
this._viewContext.loading = false;
|
|
1240
|
-
this._viewContext.refreshing = false;
|
|
1241
|
-
this._viewContext.progress = null;
|
|
1242
|
-
}
|
|
1243
|
-
if (isQueryStateSuccess(state)) {
|
|
1244
|
-
this._viewContext.etQuery = state.response;
|
|
1245
|
-
this._viewContext.$implicit = state.response;
|
|
1246
|
-
}
|
|
1247
|
-
else if (!this.cache) {
|
|
1248
|
-
this._viewContext.etQuery = null;
|
|
1249
|
-
this._viewContext.$implicit = null;
|
|
1250
|
-
}
|
|
1251
|
-
if (isQueryStateFailure(state)) {
|
|
1252
|
-
this._viewContext.error = state.error;
|
|
1253
|
-
this._errorHandler.handleError(state.error);
|
|
1254
|
-
}
|
|
1255
|
-
else {
|
|
1256
|
-
this._viewContext.error = null;
|
|
1257
|
-
}
|
|
1258
|
-
this._cdr.markForCheck();
|
|
1259
|
-
}
|
|
1260
|
-
_renderMainView() {
|
|
1261
|
-
if (!this._isMainViewCreated) {
|
|
1262
|
-
this._isMainViewCreated = true;
|
|
1263
|
-
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1268
|
-
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.8", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 });
|
|
1269
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: QueryDirective, decorators: [{
|
|
1270
|
-
type: Directive,
|
|
1271
|
-
args: [{
|
|
1272
|
-
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1273
|
-
selector: '[etQuery]',
|
|
1274
|
-
standalone: true,
|
|
1275
|
-
}]
|
|
1276
|
-
}], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i0.ErrorHandler }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { query: [{
|
|
1277
|
-
type: Input,
|
|
1278
|
-
args: ['etQuery']
|
|
1279
|
-
}], cache: [{
|
|
1280
|
-
type: Input,
|
|
1281
|
-
args: ['etQueryCache']
|
|
1282
|
-
}] } });
|
|
1283
|
-
|
|
1284
|
-
class InfinityQuery {
|
|
1285
|
-
get currentPage$() {
|
|
1286
|
-
return this._currentPage$.asObservable();
|
|
1287
|
-
}
|
|
1288
|
-
get currentPage() {
|
|
1289
|
-
return this._currentPage$.getValue();
|
|
1290
|
-
}
|
|
1291
|
-
get currentCalculatedPage$() {
|
|
1292
|
-
return this._currentCalculatedPage$.asObservable();
|
|
1293
|
-
}
|
|
1294
|
-
get currentCalculatedPage() {
|
|
1295
|
-
return this._currentCalculatedPage$.getValue();
|
|
1296
|
-
}
|
|
1297
|
-
get totalPages$() {
|
|
1298
|
-
return this._totalPages$.asObservable();
|
|
1299
|
-
}
|
|
1300
|
-
get totalPages() {
|
|
1301
|
-
return this._totalPages$.getValue();
|
|
1302
|
-
}
|
|
1303
|
-
get itemsPerPage$() {
|
|
1304
|
-
return this._itemsPerPage$.asObservable();
|
|
1305
|
-
}
|
|
1306
|
-
get itemsPerPage() {
|
|
1307
|
-
return this._itemsPerPage$.getValue();
|
|
1308
|
-
}
|
|
1309
|
-
get data$() {
|
|
1310
|
-
return this._data$;
|
|
1311
|
-
}
|
|
1312
|
-
get currentQuery$() {
|
|
1313
|
-
return this._lastQuery$;
|
|
1314
|
-
}
|
|
1315
|
-
constructor(_config) {
|
|
1316
|
-
var _a, _b;
|
|
1317
|
-
this._config = _config;
|
|
1318
|
-
this._queries$ = new BehaviorSubject([]);
|
|
1319
|
-
this._currentPage$ = new BehaviorSubject(null);
|
|
1320
|
-
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
1321
|
-
this._totalPages$ = new BehaviorSubject(null);
|
|
1322
|
-
this._itemsPerPage$ = new BehaviorSubject((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
|
|
1323
|
-
this._data$ = this._queries$.pipe(switchMap((queries) => {
|
|
1324
|
-
if (!queries.length) {
|
|
1325
|
-
return of([]);
|
|
1326
|
-
}
|
|
1327
|
-
return combineLatest(queries.map((query) => query.state$));
|
|
1328
|
-
}), tap((states) => {
|
|
1329
|
-
var _a, _b, _c, _d, _e;
|
|
1330
|
-
const lastState = states[states.length - 1];
|
|
1331
|
-
if (!isQueryStateSuccess(lastState)) {
|
|
1332
|
-
return;
|
|
1333
|
-
}
|
|
1334
|
-
const totalPages = (_e = (_c = (_b = (_a = this._config.response).totalPagesExtractor) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
|
1335
|
-
response: lastState.response,
|
|
1336
|
-
itemsPerPage: this.itemsPerPage,
|
|
1337
|
-
})) !== null && _c !== void 0 ? _c :
|
|
1338
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1339
|
-
(_d = lastState.response) === null || _d === void 0 ? void 0 : _d.totalPages) !== null && _e !== void 0 ? _e : null;
|
|
1340
|
-
this._totalPages$.next(totalPages);
|
|
1341
|
-
}), map((states) => {
|
|
1342
|
-
const fullData = states.reduce((acc, state) => {
|
|
1343
|
-
var _a;
|
|
1344
|
-
if (isQueryStateSuccess(state)) {
|
|
1345
|
-
let data = (_a = this._config) === null || _a === void 0 ? void 0 : _a.response.valueExtractor(state.response);
|
|
1346
|
-
if (this._config.response.reverse) {
|
|
1347
|
-
data = [...data].reverse();
|
|
1348
|
-
}
|
|
1349
|
-
if (this._config.response.appendItemsTo === 'start') {
|
|
1350
|
-
acc.unshift(...data);
|
|
1351
|
-
}
|
|
1352
|
-
else {
|
|
1353
|
-
acc.push(...data);
|
|
1354
|
-
}
|
|
1355
|
-
}
|
|
1356
|
-
return acc;
|
|
1357
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1358
|
-
}, []);
|
|
1359
|
-
return fullData;
|
|
1360
|
-
}), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1361
|
-
this._lastQuery$ = this._queries$.pipe(map((queries) => { var _a; return (_a = queries[queries.length - 1]) !== null && _a !== void 0 ? _a : null; }), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1362
|
-
}
|
|
1363
|
-
nextPage() {
|
|
1364
|
-
var _a, _b, _c, _d, _e;
|
|
1365
|
-
const newPage = ((_a = this._currentPage$.value) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1366
|
-
const calculatedPage = (_e = (_d = (_c = (_b = this._config) === null || _b === void 0 ? void 0 : _b.pageParam) === null || _c === void 0 ? void 0 : _c.valueCalculator) === null || _d === void 0 ? void 0 : _d.call(_c, {
|
|
1367
|
-
page: newPage,
|
|
1368
|
-
totalPages: this.totalPages,
|
|
1369
|
-
itemsPerPage: this.itemsPerPage,
|
|
1370
|
-
})) !== null && _e !== void 0 ? _e : newPage;
|
|
1371
|
-
if (this.totalPages !== null && calculatedPage > this.totalPages) {
|
|
1372
|
-
console.error('Cannot load more pages, already at the end. Make sure to not render the infinity query trigger using *ngIf canLoadMore');
|
|
1373
|
-
return;
|
|
1374
|
-
}
|
|
1375
|
-
const args = this._prepareArgs(this._config, calculatedPage);
|
|
1376
|
-
const query = this._config.queryCreator.prepare(args).execute();
|
|
1377
|
-
this._queries$.next([...this._queries$.value, query]);
|
|
1378
|
-
this._currentPage$.next(newPage);
|
|
1379
|
-
this._currentCalculatedPage$.next(calculatedPage);
|
|
1380
|
-
}
|
|
1381
|
-
reset(newConfig) {
|
|
1382
|
-
var _a, _b;
|
|
1383
|
-
this._config = Object.assign(Object.assign({}, this._config), (newConfig !== null && newConfig !== void 0 ? newConfig : {}));
|
|
1384
|
-
this._currentPage$.next(null);
|
|
1385
|
-
this._currentCalculatedPage$.next(null);
|
|
1386
|
-
this._totalPages$.next(null);
|
|
1387
|
-
this._itemsPerPage$.next((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
|
|
1388
|
-
this._queries$.next([]);
|
|
1389
|
-
this.nextPage();
|
|
1390
|
-
}
|
|
1391
|
-
_prepareArgs(config, page) {
|
|
1392
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
1393
|
-
const pageParamLocation = this._getPageParamLocation((_a = config === null || config === void 0 ? void 0 : config.pageParam) === null || _a === void 0 ? void 0 : _a.location);
|
|
1394
|
-
const pageArgs = {
|
|
1395
|
-
[pageParamLocation]: {
|
|
1396
|
-
[(_c = (_b = config === null || config === void 0 ? void 0 : config.pageParam) === null || _b === void 0 ? void 0 : _b.key) !== null && _c !== void 0 ? _c : 'page']: page,
|
|
1397
|
-
},
|
|
1398
|
-
};
|
|
1399
|
-
const limitParamLocation = this._getPageParamLocation((_d = config === null || config === void 0 ? void 0 : config.limitParam) === null || _d === void 0 ? void 0 : _d.location);
|
|
1400
|
-
const limitArgs = {
|
|
1401
|
-
[limitParamLocation]: {
|
|
1402
|
-
[(_f = (_e = config === null || config === void 0 ? void 0 : config.limitParam) === null || _e === void 0 ? void 0 : _e.key) !== null && _f !== void 0 ? _f : 'limit']: (_h = (_g = config === null || config === void 0 ? void 0 : config.limitParam) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : 10,
|
|
1403
|
-
},
|
|
1404
|
-
};
|
|
1405
|
-
const defaultConfig = (_j = config === null || config === void 0 ? void 0 : config.defaultArgs) !== null && _j !== void 0 ? _j : {};
|
|
1406
|
-
const mergedArgs = pageParamLocation === limitParamLocation
|
|
1407
|
-
? Object.assign(Object.assign({}, defaultConfig), { [pageParamLocation]: Object.assign(Object.assign(Object.assign({}, ((_l = (_k = config === null || config === void 0 ? void 0 : config.defaultArgs) === null || _k === void 0 ? void 0 : _k[pageParamLocation]) !== null && _l !== void 0 ? _l : {})), pageArgs[limitParamLocation]), limitArgs[limitParamLocation]) }) : Object.assign(Object.assign({}, defaultConfig), { [pageParamLocation]: Object.assign(Object.assign({}, ((_o = (_m = config === null || config === void 0 ? void 0 : config.defaultArgs) === null || _m === void 0 ? void 0 : _m[pageParamLocation]) !== null && _o !== void 0 ? _o : {})), pageArgs[pageParamLocation]), [limitParamLocation]: Object.assign(Object.assign({}, ((_q = (_p = config === null || config === void 0 ? void 0 : config.defaultArgs) === null || _p === void 0 ? void 0 : _p[limitParamLocation]) !== null && _q !== void 0 ? _q : {})), limitArgs[limitParamLocation]) });
|
|
1408
|
-
return mergedArgs;
|
|
1409
|
-
}
|
|
1410
|
-
_getPageParamLocation(location) {
|
|
1411
|
-
const loc = location !== null && location !== void 0 ? location : 'query';
|
|
1412
|
-
switch (loc) {
|
|
1413
|
-
case 'path':
|
|
1414
|
-
return 'pathParams';
|
|
1415
|
-
case 'query':
|
|
1416
|
-
return 'queryParams';
|
|
1417
|
-
case 'body':
|
|
1418
|
-
return 'body';
|
|
1419
|
-
case 'header':
|
|
1420
|
-
return 'headers';
|
|
1421
|
-
case 'variable':
|
|
1422
|
-
return 'variables';
|
|
1423
|
-
default:
|
|
1424
|
-
throw new Error(`Invalid pageParamLocation: ${loc}`);
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
const createInfinityQueryConfig = (config) => config;
|
|
1430
|
-
const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPage * (page - 1);
|
|
1431
|
-
|
|
1432
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1433
|
-
const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
|
|
1434
|
-
class InfinityQueryDirective {
|
|
1435
|
-
constructor() {
|
|
1436
|
-
this._queryConfigChanged$ = new Subject();
|
|
1437
|
-
this._viewContext = {
|
|
1438
|
-
$implicit: null,
|
|
1439
|
-
etInfinityQuery: null,
|
|
1440
|
-
loading: false,
|
|
1441
|
-
error: null,
|
|
1442
|
-
isFirstLoad: false,
|
|
1443
|
-
canLoadMore: false,
|
|
1444
|
-
currentPage: null,
|
|
1445
|
-
currentCalculatedPage: null,
|
|
1446
|
-
totalPages: null,
|
|
1447
|
-
itemsPerPage: null,
|
|
1448
|
-
currentQuery: null,
|
|
1449
|
-
};
|
|
1450
|
-
this._infinityQueryInstance = null;
|
|
1451
|
-
this._destroy$ = inject(DestroyService, { host: true }).destroy$;
|
|
1452
|
-
this._cdr = inject(ChangeDetectorRef);
|
|
1453
|
-
this._viewContainerRef = inject(ViewContainerRef);
|
|
1454
|
-
this._mainTemplateRef = inject((TemplateRef));
|
|
1455
|
-
this._errorHandler = inject(ErrorHandler);
|
|
1456
|
-
this._delayable = inject(DelayableDirective, { host: true });
|
|
1457
|
-
this._data$ = new BehaviorSubject([]);
|
|
1458
|
-
this._didReceiveFirstData$ = new BehaviorSubject(false);
|
|
1459
|
-
this._isMainViewCreated = false;
|
|
1460
|
-
}
|
|
1461
|
-
get infinityQuery() {
|
|
1462
|
-
return this._infinityQuery;
|
|
1463
|
-
}
|
|
1464
|
-
set infinityQuery(v) {
|
|
1465
|
-
this._cleanup();
|
|
1466
|
-
this._infinityQuery = v;
|
|
1467
|
-
this._infinityQueryInstance = this._setupInfinityQuery(v);
|
|
1468
|
-
this.loadNextPage();
|
|
1469
|
-
}
|
|
1470
|
-
get context() {
|
|
1471
|
-
return this._viewContext;
|
|
1472
|
-
}
|
|
1473
|
-
get instance() {
|
|
1474
|
-
return this._infinityQueryInstance;
|
|
1475
|
-
}
|
|
1476
|
-
get data$() {
|
|
1477
|
-
return this._data$.asObservable();
|
|
1478
|
-
}
|
|
1479
|
-
get data() {
|
|
1480
|
-
return this._data$.getValue();
|
|
1481
|
-
}
|
|
1482
|
-
static ngTemplateContextGuard(dir, ctx) {
|
|
1483
|
-
return true;
|
|
1484
|
-
}
|
|
1485
|
-
ngOnInit() {
|
|
1486
|
-
this._renderMainView();
|
|
1487
|
-
}
|
|
1488
|
-
_setupInfinityQuery(config) {
|
|
1489
|
-
const instance = new InfinityQuery(config);
|
|
1490
|
-
combineLatest([
|
|
1491
|
-
instance.currentQuery$.pipe(switchQueryState(), withLatestFrom(instance.currentQuery$)),
|
|
1492
|
-
this._delayable.isDelayed$,
|
|
1493
|
-
this._didReceiveFirstData$,
|
|
1494
|
-
])
|
|
1495
|
-
.pipe(tap(([[state, currentQuery], isDelayed, didReceiveFirstData]) => {
|
|
1496
|
-
this._viewContext.currentPage = instance.currentPage;
|
|
1497
|
-
this._viewContext.totalPages = instance.totalPages;
|
|
1498
|
-
this._viewContext.itemsPerPage = instance.itemsPerPage;
|
|
1499
|
-
this._viewContext.canLoadMore =
|
|
1500
|
-
(instance.totalPages && instance.currentPage && instance.totalPages > instance.currentPage) || false;
|
|
1501
|
-
this._viewContext.currentCalculatedPage = instance.currentCalculatedPage;
|
|
1502
|
-
this._viewContext.currentQuery = currentQuery;
|
|
1503
|
-
if (isQueryStateLoading(state) || isDelayed || (!didReceiveFirstData && isQueryStateSuccess(state))) {
|
|
1504
|
-
this._viewContext.loading = true;
|
|
1505
|
-
this._viewContext.error = null;
|
|
1506
|
-
this._viewContext.isFirstLoad = this.context.etInfinityQuery === null;
|
|
1507
|
-
}
|
|
1508
|
-
else if (isQueryStateFailure(state)) {
|
|
1509
|
-
this._viewContext.loading = false;
|
|
1510
|
-
this._viewContext.error = state.error;
|
|
1511
|
-
this._viewContext.isFirstLoad = false;
|
|
1512
|
-
this._errorHandler.handleError(state.error);
|
|
1513
|
-
}
|
|
1514
|
-
else if (isQueryStateSuccess(state)) {
|
|
1515
|
-
this._viewContext.loading = false;
|
|
1516
|
-
this._viewContext.error = null;
|
|
1517
|
-
this._viewContext.isFirstLoad = false;
|
|
1518
|
-
}
|
|
1519
|
-
else {
|
|
1520
|
-
this._viewContext.loading = false;
|
|
1521
|
-
this._viewContext.error = null;
|
|
1522
|
-
this._viewContext.etInfinityQuery = null;
|
|
1523
|
-
this._viewContext.$implicit = null;
|
|
1524
|
-
this._viewContext.isFirstLoad = false;
|
|
1525
|
-
this._viewContext.canLoadMore = false;
|
|
1526
|
-
this._viewContext.currentPage = null;
|
|
1527
|
-
this._viewContext.itemsPerPage = null;
|
|
1528
|
-
this._viewContext.totalPages = null;
|
|
1529
|
-
this._viewContext.currentQuery = null;
|
|
1530
|
-
this._data$.next([]);
|
|
1531
|
-
}
|
|
1532
|
-
this._cdr.markForCheck();
|
|
1533
|
-
}), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
|
|
1534
|
-
.subscribe();
|
|
1535
|
-
instance.data$
|
|
1536
|
-
.pipe(skip(1), tap((data) => {
|
|
1537
|
-
this._viewContext.etInfinityQuery = this._viewContext.$implicit = data;
|
|
1538
|
-
this._data$.next(data);
|
|
1539
|
-
if (!this._didReceiveFirstData$.getValue()) {
|
|
1540
|
-
this._didReceiveFirstData$.next(true);
|
|
1541
|
-
}
|
|
1542
|
-
this._cdr.markForCheck();
|
|
1543
|
-
}), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
|
|
1544
|
-
.subscribe();
|
|
1545
|
-
return instance;
|
|
1546
|
-
}
|
|
1547
|
-
loadNextPage() {
|
|
1548
|
-
if (!this._infinityQueryInstance) {
|
|
1549
|
-
return;
|
|
1550
|
-
}
|
|
1551
|
-
if (this._viewContext.loading) {
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
this._infinityQueryInstance.nextPage();
|
|
1555
|
-
}
|
|
1556
|
-
reset(newConfig) {
|
|
1557
|
-
if (!this._infinityQueryInstance) {
|
|
1558
|
-
return;
|
|
1559
|
-
}
|
|
1560
|
-
this._infinityQueryInstance.reset(newConfig);
|
|
1561
|
-
}
|
|
1562
|
-
_renderMainView() {
|
|
1563
|
-
if (!this._isMainViewCreated) {
|
|
1564
|
-
this._isMainViewCreated = true;
|
|
1565
|
-
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
_cleanup() {
|
|
1569
|
-
this._queryConfigChanged$.next(true);
|
|
1570
|
-
this._viewContext.loading = false;
|
|
1571
|
-
this._viewContext.error = null;
|
|
1572
|
-
this._viewContext.etInfinityQuery = null;
|
|
1573
|
-
this._viewContext.$implicit = null;
|
|
1574
|
-
this._viewContext.isFirstLoad = false;
|
|
1575
|
-
this._viewContext.canLoadMore = false;
|
|
1576
|
-
this._viewContext.currentPage = null;
|
|
1577
|
-
this._viewContext.itemsPerPage = null;
|
|
1578
|
-
this._viewContext.totalPages = null;
|
|
1579
|
-
this._viewContext.currentQuery = null;
|
|
1580
|
-
this._data$.next([]);
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1584
|
-
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.8", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 });
|
|
1585
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
1586
|
-
type: Directive,
|
|
1587
|
-
args: [{
|
|
1588
|
-
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1589
|
-
selector: '[etInfinityQuery]',
|
|
1590
|
-
exportAs: 'etInfinityQuery',
|
|
1591
|
-
standalone: true,
|
|
1592
|
-
providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
|
|
1593
|
-
hostDirectives: [DelayableDirective],
|
|
1594
|
-
}]
|
|
1595
|
-
}], propDecorators: { infinityQuery: [{
|
|
1596
|
-
type: Input,
|
|
1597
|
-
args: ['etInfinityQuery']
|
|
1598
|
-
}] } });
|
|
1599
|
-
|
|
1600
|
-
class InfinityQueryTriggerDirective {
|
|
1601
|
-
constructor() {
|
|
1602
|
-
this._elementRef = inject((ElementRef));
|
|
1603
|
-
this._infinityQuery = inject(INFINITY_QUERY_TOKEN);
|
|
1604
|
-
this._destroy = new Subject();
|
|
1605
|
-
this._observer = null;
|
|
1606
|
-
this.click$ = fromEvent(this._elementRef.nativeElement, 'click');
|
|
1607
|
-
this.scrollContainerSelector = null;
|
|
1608
|
-
}
|
|
1609
|
-
ngOnInit() {
|
|
1610
|
-
const isInteractive = this._elementRef.nativeElement.hasAttribute('etInfinityQueryTrigger');
|
|
1611
|
-
if (isInteractive) {
|
|
1612
|
-
this.click$.pipe(takeUntil(this._destroy)).subscribe(() => this._infinityQuery.loadNextPage());
|
|
1613
|
-
}
|
|
1614
|
-
else {
|
|
1615
|
-
this._setupIntersectionObserver();
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
ngOnDestroy() {
|
|
1619
|
-
var _a;
|
|
1620
|
-
this._destroy.next(true);
|
|
1621
|
-
this._destroy.unsubscribe();
|
|
1622
|
-
(_a = this._observer) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1623
|
-
}
|
|
1624
|
-
_setupIntersectionObserver() {
|
|
1625
|
-
this._observer = new IntersectionObserver((entries) => {
|
|
1626
|
-
const entry = entries[0];
|
|
1627
|
-
if (entry.isIntersecting && !this._infinityQuery.context.loading) {
|
|
1628
|
-
this._infinityQuery.loadNextPage();
|
|
1629
|
-
}
|
|
1630
|
-
}, {
|
|
1631
|
-
root: this.scrollContainerSelector ? document.querySelector(this.scrollContainerSelector) : null,
|
|
1632
|
-
rootMargin: '0px',
|
|
1633
|
-
threshold: [0.25, 0.5, 0.75, 1],
|
|
1634
|
-
});
|
|
1635
|
-
this._observer.observe(this._elementRef.nativeElement);
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1639
|
-
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.8", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
|
|
1640
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
1641
|
-
type: Directive,
|
|
1642
|
-
args: [{
|
|
1643
|
-
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1644
|
-
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
1645
|
-
standalone: true,
|
|
1646
|
-
}]
|
|
1647
|
-
}], propDecorators: { scrollContainerSelector: [{
|
|
1648
|
-
type: Input
|
|
1649
|
-
}] } });
|
|
1650
|
-
|
|
1651
|
-
class EntityStoreError extends Error {
|
|
1652
|
-
constructor(message, detail) {
|
|
1653
|
-
super(message);
|
|
1654
|
-
this.detail = detail;
|
|
1655
|
-
this.name = 'EntityStoreError';
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
class EntityStore {
|
|
1659
|
-
constructor(_config) {
|
|
1660
|
-
this._config = _config;
|
|
1661
|
-
this._dictionary = new Map();
|
|
1662
|
-
this._change$ = new Subject();
|
|
1663
|
-
}
|
|
1664
|
-
select(keyOrKeys) {
|
|
1665
|
-
if (Array.isArray(keyOrKeys)) {
|
|
1666
|
-
return this._selectMany(keyOrKeys);
|
|
1667
|
-
}
|
|
1668
|
-
return this._select(keyOrKeys);
|
|
1669
|
-
}
|
|
1670
|
-
/**
|
|
1671
|
-
* **Note:** Prefer `select` over `selectWhere` when possible.
|
|
1672
|
-
*/
|
|
1673
|
-
selectWhere(predicate) {
|
|
1674
|
-
return this._change$.pipe(startWith(null), debounceTime(0), map(() => Array.from(this._dictionary.values()).filter(predicate)), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1675
|
-
}
|
|
1676
|
-
set(keyOrKeys, valueOrValues) {
|
|
1677
|
-
if (Array.isArray(keyOrKeys)) {
|
|
1678
|
-
if (!Array.isArray(valueOrValues)) {
|
|
1679
|
-
throw new EntityStoreError('When setting multiple keys, values must be an array', {
|
|
1680
|
-
keyOrValues: keyOrKeys,
|
|
1681
|
-
valueOrValues,
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
for (let i = 0; i < keyOrKeys.length; i++) {
|
|
1685
|
-
this._set(keyOrKeys[i], valueOrValues[i]);
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
else {
|
|
1689
|
-
this._set(keyOrKeys, valueOrValues);
|
|
1690
|
-
}
|
|
1691
|
-
this._change$.next(keyOrKeys);
|
|
1692
|
-
}
|
|
1693
|
-
remove(keyOrKeys) {
|
|
1694
|
-
if (Array.isArray(keyOrKeys)) {
|
|
1695
|
-
for (const key of keyOrKeys) {
|
|
1696
|
-
this._remove(key);
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
|
-
else {
|
|
1700
|
-
this._remove(keyOrKeys);
|
|
1701
|
-
}
|
|
1702
|
-
this._change$.next(keyOrKeys);
|
|
1703
|
-
}
|
|
1704
|
-
logState() {
|
|
1705
|
-
console.log('EntityStore:', this._config.name, {
|
|
1706
|
-
dictionary: this._dictionary,
|
|
1707
|
-
});
|
|
1708
|
-
}
|
|
1709
|
-
_select(key) {
|
|
1710
|
-
if (this._config.logActions) {
|
|
1711
|
-
console.log('EntityStore: select', this._config.name, key);
|
|
1712
|
-
}
|
|
1713
|
-
return this._change$.pipe(startWith(null), filter((v) => {
|
|
1714
|
-
if (v === null) {
|
|
1715
|
-
return true;
|
|
1716
|
-
}
|
|
1717
|
-
if (Array.isArray(v)) {
|
|
1718
|
-
return v.includes(key);
|
|
1719
|
-
}
|
|
1720
|
-
return v === key;
|
|
1721
|
-
}), map(() => { var _a; return (_a = this._dictionary.get(key)) !== null && _a !== void 0 ? _a : null; }));
|
|
1722
|
-
}
|
|
1723
|
-
_selectMany(keys) {
|
|
1724
|
-
if (this._config.logActions) {
|
|
1725
|
-
console.log('EntityStore: selectMany', this._config.name, keys);
|
|
1726
|
-
}
|
|
1727
|
-
return this._change$.pipe(startWith(null), filter((v) => {
|
|
1728
|
-
if (v === null) {
|
|
1729
|
-
return true;
|
|
1730
|
-
}
|
|
1731
|
-
if (Array.isArray(v)) {
|
|
1732
|
-
return keys.some((key) => v.includes(key));
|
|
1733
|
-
}
|
|
1734
|
-
return keys.includes(v);
|
|
1735
|
-
}), map(() => keys.map((key) => this._dictionary.get(key)).filter((value) => value !== undefined)));
|
|
1736
|
-
}
|
|
1737
|
-
_set(key, value) {
|
|
1738
|
-
if (this._config.logActions) {
|
|
1739
|
-
console.log('EntityStore: set', this._config.name, key, value);
|
|
1740
|
-
}
|
|
1741
|
-
this._dictionary.set(key, value);
|
|
1742
|
-
}
|
|
1743
|
-
_remove(key) {
|
|
1744
|
-
if (this._config.logActions) {
|
|
1745
|
-
console.log('EntityStore: remove', this._config.name, key);
|
|
1746
|
-
}
|
|
1747
|
-
this._dictionary.delete(key);
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1750
|
-
|
|
1751
|
-
function mapToPaginated(response) {
|
|
1752
|
-
return map((items) => (Object.assign(Object.assign({}, response), { items })));
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
class QueryCreator {
|
|
1756
|
-
constructor(_queryConfig, _client, _store) {
|
|
1757
|
-
this._queryConfig = _queryConfig;
|
|
1758
|
-
this._client = _client;
|
|
1759
|
-
this._store = _store;
|
|
1760
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1761
|
-
// @ts-ignore
|
|
1762
|
-
this.prepare = (args) => {
|
|
1763
|
-
const route = buildRoute({
|
|
1764
|
-
base: this._client.config.baseRoute,
|
|
1765
|
-
route: this._queryConfig.route,
|
|
1766
|
-
pathParams: args === null || args === void 0 ? void 0 : args.pathParams,
|
|
1767
|
-
queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
|
|
1768
|
-
});
|
|
1769
|
-
const cacheKey = isGqlQueryConfig(this._queryConfig) ? buildGqlCacheKey(this._queryConfig, args) : route;
|
|
1770
|
-
if (shouldCacheQuery(this._queryConfig.method)) {
|
|
1771
|
-
const existingQuery = this._store.get(cacheKey);
|
|
1772
|
-
if (existingQuery) {
|
|
1773
|
-
return existingQuery;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
const query = new Query(this._client, this._queryConfig, route, args !== null && args !== void 0 ? args : {});
|
|
1777
|
-
if (shouldCacheQuery(this._queryConfig.method)) {
|
|
1778
|
-
this._store.add(cacheKey, query);
|
|
1779
|
-
}
|
|
1780
|
-
return query;
|
|
1781
|
-
};
|
|
1782
|
-
this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue !== null && initialValue !== void 0 ? initialValue : null);
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
class QueryStore {
|
|
1787
|
-
constructor(_config) {
|
|
1788
|
-
this._config = _config;
|
|
1789
|
-
this._store = new Map();
|
|
1790
|
-
this._garbageCollector = null;
|
|
1791
|
-
this._isInLowResourceMode = false;
|
|
1792
|
-
this._lastBlurTimestamp = Date.now();
|
|
1793
|
-
this._initSmartQueryHandling();
|
|
1794
|
-
}
|
|
1795
|
-
add(id, query) {
|
|
1796
|
-
this._store.set(id, query);
|
|
1797
|
-
this._initGarbageCollector();
|
|
1798
|
-
this._logState(id, query, 'SET');
|
|
1799
|
-
}
|
|
1800
|
-
get(id) {
|
|
1801
|
-
var _a;
|
|
1802
|
-
return (_a = this._store.get(id)) !== null && _a !== void 0 ? _a : null;
|
|
1803
|
-
}
|
|
1804
|
-
remove(id) {
|
|
1805
|
-
var _a;
|
|
1806
|
-
(_a = this.get(id)) === null || _a === void 0 ? void 0 : _a._destroy();
|
|
1807
|
-
this._store.delete(id);
|
|
1808
|
-
this._logState(id, null, 'REMOVE');
|
|
1809
|
-
}
|
|
1810
|
-
forEach(callback) {
|
|
1811
|
-
for (const [key, query] of this._store) {
|
|
1812
|
-
callback(query, key);
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
refreshQueriesInUse(config) {
|
|
1816
|
-
const { ignoreCacheValidity, purgeUnused } = config !== null && config !== void 0 ? config : {};
|
|
1817
|
-
for (const [key, query] of this._store) {
|
|
1818
|
-
if (query.isInUse &&
|
|
1819
|
-
(query.isExpired || ignoreCacheValidity) &&
|
|
1820
|
-
query.autoRefreshOnConfig.queryClientDefaultHeadersChange) {
|
|
1821
|
-
query.execute({ skipCache: true, _triggeredVia: 'auto' });
|
|
1822
|
-
}
|
|
1823
|
-
else if (purgeUnused && !query.isInUse) {
|
|
1824
|
-
this.remove(key);
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
_initSmartQueryHandling() {
|
|
1829
|
-
const windowBlur$ = fromEvent(window, 'blur');
|
|
1830
|
-
const windowFocus$ = fromEvent(window, 'focus');
|
|
1831
|
-
windowBlur$.subscribe(() => {
|
|
1832
|
-
timer(5000)
|
|
1833
|
-
.pipe(takeUntil(windowFocus$), take(1))
|
|
1834
|
-
.subscribe(() => {
|
|
1835
|
-
var _a;
|
|
1836
|
-
this._lastBlurTimestamp = Date.now();
|
|
1837
|
-
this._isInLowResourceMode = true;
|
|
1838
|
-
this._stopGarbageCollector();
|
|
1839
|
-
if ((_a = this._config) === null || _a === void 0 ? void 0 : _a.enableSmartPolling) {
|
|
1840
|
-
this.forEach((query) => {
|
|
1841
|
-
if (!query.isPolling || !query._enableSmartPolling) {
|
|
1842
|
-
return;
|
|
1843
|
-
}
|
|
1844
|
-
query.pausePolling();
|
|
1845
|
-
});
|
|
1846
|
-
}
|
|
1847
|
-
});
|
|
1848
|
-
});
|
|
1849
|
-
windowFocus$.subscribe(() => {
|
|
1850
|
-
var _a, _b;
|
|
1851
|
-
if (!this._isInLowResourceMode) {
|
|
1852
|
-
return;
|
|
1853
|
-
}
|
|
1854
|
-
this._isInLowResourceMode = false;
|
|
1855
|
-
if (((_a = this._config) === null || _a === void 0 ? void 0 : _a.enableSmartPolling) || ((_b = this._config) === null || _b === void 0 ? void 0 : _b.autoRefreshQueriesOnWindowFocus)) {
|
|
1856
|
-
this.forEach((query) => {
|
|
1857
|
-
var _a, _b;
|
|
1858
|
-
if (((_a = this._config) === null || _a === void 0 ? void 0 : _a.enableSmartPolling) && query._isPollingPaused) {
|
|
1859
|
-
query.resumePolling();
|
|
1860
|
-
}
|
|
1861
|
-
if (Date.now() - this._lastBlurTimestamp > 15000) {
|
|
1862
|
-
if (((_b = this._config) === null || _b === void 0 ? void 0 : _b.autoRefreshQueriesOnWindowFocus) &&
|
|
1863
|
-
query.isExpired &&
|
|
1864
|
-
query.isInUse &&
|
|
1865
|
-
query.autoRefreshOnConfig.windowFocus) {
|
|
1866
|
-
query.execute({ skipCache: true, _triggeredVia: 'auto' });
|
|
1867
|
-
}
|
|
1868
|
-
}
|
|
1869
|
-
});
|
|
1870
|
-
}
|
|
1871
|
-
this._initGarbageCollector();
|
|
1872
|
-
});
|
|
1873
|
-
}
|
|
1874
|
-
_logState(key, item, operation) {
|
|
1875
|
-
var _a;
|
|
1876
|
-
if (!((_a = this._config) === null || _a === void 0 ? void 0 : _a.enableChangeLogging))
|
|
1877
|
-
return;
|
|
1878
|
-
const stateAsJson = {};
|
|
1879
|
-
this._store.forEach((value, key) => {
|
|
1880
|
-
stateAsJson[key] = value;
|
|
1881
|
-
});
|
|
1882
|
-
console.log(`%c[${operation}] ${key}`, 'font-weight: bold');
|
|
1883
|
-
console.log({ operation, key, item });
|
|
1884
|
-
console.log(stateAsJson);
|
|
1885
|
-
}
|
|
1886
|
-
_initGarbageCollector() {
|
|
1887
|
-
if (this._garbageCollector !== null) {
|
|
1888
|
-
return;
|
|
1889
|
-
}
|
|
1890
|
-
this._logGarbageCollector('Start');
|
|
1891
|
-
this._garbageCollector = window.setInterval(() => {
|
|
1892
|
-
this._runGarbageCollector();
|
|
1893
|
-
}, 15000);
|
|
1894
|
-
}
|
|
1895
|
-
_stopGarbageCollector() {
|
|
1896
|
-
if (this._garbageCollector !== null) {
|
|
1897
|
-
window.clearInterval(this._garbageCollector);
|
|
1898
|
-
this._garbageCollector = null;
|
|
1899
|
-
this._logGarbageCollector('Stop');
|
|
1900
|
-
}
|
|
1901
|
-
}
|
|
1902
|
-
_runGarbageCollector() {
|
|
1903
|
-
this._logGarbageCollector('Collecting...');
|
|
1904
|
-
this._store.forEach((item, key) => {
|
|
1905
|
-
if (item.isExpired && !item.isInUse) {
|
|
1906
|
-
this.remove(key);
|
|
1907
|
-
}
|
|
1908
|
-
});
|
|
1909
|
-
this._logGarbageCollector('Collection done');
|
|
1910
|
-
if (!this._store.size) {
|
|
1911
|
-
this._stopGarbageCollector();
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
_logGarbageCollector(action) {
|
|
1915
|
-
var _a;
|
|
1916
|
-
if (!((_a = this._config) === null || _a === void 0 ? void 0 : _a.enableGarbageCollectorLogging))
|
|
1917
|
-
return;
|
|
1918
|
-
console.log(`%cGC: ${action}`, 'color: yellow; font-weight: bold');
|
|
1919
|
-
}
|
|
1920
|
-
}
|
|
1921
|
-
|
|
1922
|
-
class QueryClient {
|
|
1923
|
-
get config() {
|
|
1924
|
-
return this._clientConfig;
|
|
1925
|
-
}
|
|
1926
|
-
get authProvider() {
|
|
1927
|
-
var _a, _b, _c;
|
|
1928
|
-
return (_c = (_a = this._authProvider$.getValue()) !== null && _a !== void 0 ? _a : (_b = this._clientConfig.parent) === null || _b === void 0 ? void 0 : _b._authProvider$.getValue()) !== null && _c !== void 0 ? _c : null;
|
|
1929
|
-
}
|
|
1930
|
-
get authProvider$() {
|
|
1931
|
-
var _a, _b, _c;
|
|
1932
|
-
return (_c = (_a = this._authProvider$.asObservable()) !== null && _a !== void 0 ? _a : (_b = this._clientConfig.parent) === null || _b === void 0 ? void 0 : _b._authProvider$.asObservable()) !== null && _c !== void 0 ? _c : null;
|
|
1933
|
-
}
|
|
1934
|
-
constructor(_clientConfig) {
|
|
1935
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1936
|
-
this._clientConfig = _clientConfig;
|
|
1937
|
-
this._authProvider$ = new BehaviorSubject(null);
|
|
1938
|
-
this.get = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'GET' }));
|
|
1939
|
-
this.post = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'POST' }));
|
|
1940
|
-
this.put = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'PUT' }));
|
|
1941
|
-
this.patch = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'PATCH' }));
|
|
1942
|
-
this.delete = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'DELETE' }));
|
|
1943
|
-
this.gqlQuery = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'GQL_QUERY' }));
|
|
1944
|
-
this.gqlMutate = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'GQL_MUTATE' }));
|
|
1945
|
-
this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
|
|
1946
|
-
this.setAuthProvider = (authProvider) => {
|
|
1947
|
-
if (this.authProvider) {
|
|
1948
|
-
throw new Error('The auth provider is already set. Please call clearAuthProvider() first.');
|
|
1949
|
-
}
|
|
1950
|
-
this._authProvider$.next(authProvider);
|
|
1951
|
-
};
|
|
1952
|
-
this.setDefaultHeaders = (config) => {
|
|
1953
|
-
var _a, _b;
|
|
1954
|
-
if (!this._clientConfig.request) {
|
|
1955
|
-
this._clientConfig.request = {
|
|
1956
|
-
headers: (_a = config.headers) !== null && _a !== void 0 ? _a : undefined,
|
|
1957
|
-
};
|
|
1958
|
-
}
|
|
1959
|
-
else {
|
|
1960
|
-
this._clientConfig.request.headers = (_b = config.headers) !== null && _b !== void 0 ? _b : undefined;
|
|
1961
|
-
}
|
|
1962
|
-
if (config.refreshQueriesInUse) {
|
|
1963
|
-
this._store.refreshQueriesInUse({ purgeUnused: true, ignoreCacheValidity: true });
|
|
1964
|
-
}
|
|
1965
|
-
};
|
|
1966
|
-
this.clearAuthProvider = () => {
|
|
1967
|
-
var _a;
|
|
1968
|
-
(_a = this.authProvider) === null || _a === void 0 ? void 0 : _a.cleanUp();
|
|
1969
|
-
this._authProvider$.next(null);
|
|
1970
|
-
};
|
|
1971
|
-
this._store = new QueryStore({
|
|
1972
|
-
enableChangeLogging: (_a = _clientConfig.logging) === null || _a === void 0 ? void 0 : _a.queryStateChanges,
|
|
1973
|
-
enableGarbageCollectorLogging: (_b = _clientConfig.logging) === null || _b === void 0 ? void 0 : _b.queryStateGarbageCollector,
|
|
1974
|
-
autoRefreshQueriesOnWindowFocus: (_d = (_c = _clientConfig.request) === null || _c === void 0 ? void 0 : _c.autoRefreshQueriesOnWindowFocus) !== null && _d !== void 0 ? _d : true,
|
|
1975
|
-
enableSmartPolling: (_f = (_e = _clientConfig.request) === null || _e === void 0 ? void 0 : _e.enableSmartPolling) !== null && _f !== void 0 ? _f : true,
|
|
1976
|
-
});
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
const shouldCacheQuery = (method) => {
|
|
1981
|
-
return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
|
|
1982
|
-
};
|
|
1983
|
-
const buildGqlCacheKey = (config, args) => {
|
|
1984
|
-
const { query } = config;
|
|
1985
|
-
const variables = (args === null || args === void 0 ? void 0 : args.variables) || {};
|
|
1986
|
-
const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
|
|
1987
|
-
const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
|
|
1988
|
-
const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
|
|
1989
|
-
const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
|
|
1990
|
-
const vars = JSON.stringify(variables);
|
|
1991
|
-
return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
|
|
1992
|
-
};
|
|
1993
|
-
|
|
1994
|
-
class QueryField {
|
|
1995
|
-
get control() {
|
|
1996
|
-
return this.data.control;
|
|
1997
|
-
}
|
|
1998
|
-
constructor(data) {
|
|
1999
|
-
this.data = data;
|
|
2000
|
-
this.changes$ = this._setupChangesObservable();
|
|
2001
|
-
this._currentDebounceTimeout = null;
|
|
2002
|
-
}
|
|
2003
|
-
setValue(value, options) {
|
|
2004
|
-
if (this._currentDebounceTimeout !== null) {
|
|
2005
|
-
clearTimeout(this._currentDebounceTimeout);
|
|
2006
|
-
}
|
|
2007
|
-
if (this.data.debounce && !(options === null || options === void 0 ? void 0 : options.skipDebounce)) {
|
|
2008
|
-
this._currentDebounceTimeout = window.setTimeout(() => {
|
|
2009
|
-
this.control.setValue(value);
|
|
2010
|
-
}, this.data.debounce);
|
|
2011
|
-
}
|
|
2012
|
-
else {
|
|
2013
|
-
this.control.setValue(value);
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
_setupChangesObservable() {
|
|
2017
|
-
const obs = this.control.valueChanges.pipe(startWith(this.control.value));
|
|
2018
|
-
if (!this.data.debounce) {
|
|
2019
|
-
return obs;
|
|
2020
|
-
}
|
|
2021
|
-
// The initial value should get emitted immediately
|
|
2022
|
-
// concat switches to the debounced observable after the first observable is completed
|
|
2023
|
-
return concat(obs.pipe(take(1)), this.control.valueChanges.pipe(debounceTime(this.data.debounce)));
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2027
|
-
class QueryForm {
|
|
2028
|
-
constructor(_fields) {
|
|
2029
|
-
this._fields = _fields;
|
|
2030
|
-
this._router = inject(Router, { optional: true });
|
|
2031
|
-
this._activatedRoute = inject(ActivatedRoute, { optional: true });
|
|
2032
|
-
this._defaultValues = this._extractDefaultValues();
|
|
2033
|
-
this.form = this._setupFormGroup();
|
|
2034
|
-
}
|
|
2035
|
-
observe(options) {
|
|
2036
|
-
return combineLatest(Object.values(this._fields).map((field) => field.changes$)).pipe(map(() => this.form.getRawValue()), distinctUntilChanged((a, b) => equal(a, b)), tap((values) => {
|
|
2037
|
-
if ((options === null || options === void 0 ? void 0 : options.syncViaUrlQueryParams) !== false) {
|
|
2038
|
-
this._syncViaUrlQueryParams(values);
|
|
2039
|
-
}
|
|
2040
|
-
}), pairwise(), startWith([null, this.form.getRawValue()]), map(([previousValue, currentValue]) => ({ previousValue, currentValue })), map(({ previousValue, currentValue }) => {
|
|
2041
|
-
let didResetValues = false;
|
|
2042
|
-
for (const formFieldKey in this._fields) {
|
|
2043
|
-
const resets = this._fields[formFieldKey].data.isResetBy;
|
|
2044
|
-
if (!resets)
|
|
2045
|
-
continue;
|
|
2046
|
-
const resetConditionKeys = Array.isArray(resets) ? resets : [resets];
|
|
2047
|
-
for (const resetConditionKey of resetConditionKeys) {
|
|
2048
|
-
if (!(resetConditionKey in this._fields)) {
|
|
2049
|
-
if (isDevMode()) {
|
|
2050
|
-
console.warn(`The field "${resetConditionKey}" is not defined in the QueryForm. Is it a typo?`, this);
|
|
2051
|
-
}
|
|
2052
|
-
continue;
|
|
2053
|
-
}
|
|
2054
|
-
if (previousValue &&
|
|
2055
|
-
currentValue &&
|
|
2056
|
-
!equal(previousValue[resetConditionKey], currentValue[resetConditionKey])) {
|
|
2057
|
-
const defaultValueForKeyToReset = this._defaultValues[formFieldKey];
|
|
2058
|
-
const currentValueForKeyToReset = currentValue[formFieldKey];
|
|
2059
|
-
if (equal(defaultValueForKeyToReset, currentValueForKeyToReset)) {
|
|
2060
|
-
continue;
|
|
2061
|
-
}
|
|
2062
|
-
this.form.controls[formFieldKey].setValue(defaultValueForKeyToReset);
|
|
2063
|
-
didResetValues = true;
|
|
2064
|
-
break;
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
return (didResetValues || {
|
|
2069
|
-
previousValue,
|
|
2070
|
-
currentValue,
|
|
2071
|
-
});
|
|
2072
|
-
}), filter((value) => value !== true));
|
|
2073
|
-
}
|
|
2074
|
-
setFormValueFromUrlQueryParams(options) {
|
|
2075
|
-
var _a, _b, _c, _d;
|
|
2076
|
-
if (!this._activatedRoute) {
|
|
2077
|
-
throw new Error('Cannot set form value from url query params without ActivatedRoute');
|
|
2078
|
-
}
|
|
2079
|
-
const queryParams = this._activatedRoute.snapshot.queryParams;
|
|
2080
|
-
for (const [key, field] of Object.entries(this._fields)) {
|
|
2081
|
-
const value = queryParams[key];
|
|
2082
|
-
// We only check using == because the value types can be different (e.g. "1" and 1)
|
|
2083
|
-
if (value === undefined || value == field.control.value) {
|
|
2084
|
-
continue;
|
|
2085
|
-
}
|
|
2086
|
-
const deserializedValue = (_c = (_b = (_a = field.data).queryParamToValueTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)) !== null && _c !== void 0 ? _c : value;
|
|
2087
|
-
field.setValue(deserializedValue, { skipDebounce: (_d = options === null || options === void 0 ? void 0 : options.skipDebounce) !== null && _d !== void 0 ? _d : true });
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
updateFormOnUrlQueryParamsChange() {
|
|
2091
|
-
if (!this._activatedRoute) {
|
|
2092
|
-
throw new Error('Cannot update form on url query params change without ActivatedRoute');
|
|
2093
|
-
}
|
|
2094
|
-
return this._activatedRoute.queryParams.pipe(tap(() => this.setFormValueFromUrlQueryParams()));
|
|
2095
|
-
}
|
|
2096
|
-
_getDefaultValue(key) {
|
|
2097
|
-
var _a;
|
|
2098
|
-
return (_a = this._defaultValues[key]) !== null && _a !== void 0 ? _a : null;
|
|
2099
|
-
}
|
|
2100
|
-
_isDefaultValue(key, value) {
|
|
2101
|
-
const normalizedValue = Array.isArray(value) ? JSON.stringify(value) : value;
|
|
2102
|
-
return this._getDefaultValue(key) === normalizedValue;
|
|
2103
|
-
}
|
|
2104
|
-
_setupFormGroup() {
|
|
2105
|
-
const group = new FormGroup({});
|
|
2106
|
-
for (const [key, field] of Object.entries(this._fields)) {
|
|
2107
|
-
group.addControl(key, field.control);
|
|
2108
|
-
}
|
|
2109
|
-
return group;
|
|
2110
|
-
}
|
|
2111
|
-
_extractDefaultValues() {
|
|
2112
|
-
const defaultValues = {};
|
|
2113
|
-
for (const [key, field] of Object.entries(this._fields)) {
|
|
2114
|
-
const value = field.control.value;
|
|
2115
|
-
if (value === null || value === undefined) {
|
|
2116
|
-
continue;
|
|
2117
|
-
}
|
|
2118
|
-
if (Array.isArray(value)) {
|
|
2119
|
-
defaultValues[key] = JSON.stringify(value);
|
|
2120
|
-
}
|
|
2121
|
-
else {
|
|
2122
|
-
defaultValues[key] = value;
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
return defaultValues;
|
|
2126
|
-
}
|
|
2127
|
-
_syncViaUrlQueryParams(values) {
|
|
2128
|
-
var _a, _b;
|
|
2129
|
-
if (!this._router || !this._activatedRoute) {
|
|
2130
|
-
return;
|
|
2131
|
-
}
|
|
2132
|
-
const queryParams = Object.assign({}, clone(this._activatedRoute.snapshot.queryParams));
|
|
2133
|
-
for (const [key, value] of Object.entries(values)) {
|
|
2134
|
-
if (this._isDefaultValue(key, value) || this._fields[key].data.appendToUrl === false) {
|
|
2135
|
-
delete queryParams[key];
|
|
2136
|
-
}
|
|
2137
|
-
else {
|
|
2138
|
-
queryParams[key] = this._fields[key].data.valueToQueryParamTransformFn
|
|
2139
|
-
? (_b = (_a = this._fields[key].data).valueToQueryParamTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)
|
|
2140
|
-
: value;
|
|
2141
|
-
}
|
|
2142
|
-
}
|
|
2143
|
-
this._router.navigate([], {
|
|
2144
|
-
queryParams,
|
|
2145
|
-
});
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
|
-
const transformToString = (value) => {
|
|
2150
|
-
if (typeof value === 'string') {
|
|
2151
|
-
return value;
|
|
2152
|
-
}
|
|
2153
|
-
return null;
|
|
2154
|
-
};
|
|
2155
|
-
const transformToStringArray = (value) => {
|
|
2156
|
-
if (Array.isArray(value)) {
|
|
2157
|
-
return value.map(transformToString).filter(Boolean);
|
|
2158
|
-
}
|
|
2159
|
-
else if (typeof value === 'string') {
|
|
2160
|
-
return [transformToString(value)];
|
|
2161
|
-
}
|
|
2162
|
-
return null;
|
|
2163
|
-
};
|
|
2164
|
-
const transformToNumber = (value) => {
|
|
2165
|
-
if (typeof value === 'number') {
|
|
2166
|
-
return value;
|
|
2167
|
-
}
|
|
2168
|
-
if (typeof value === 'string') {
|
|
2169
|
-
return Number(value);
|
|
2170
|
-
}
|
|
2171
|
-
return null;
|
|
2172
|
-
};
|
|
2173
|
-
const transformToNumberArray = (value) => {
|
|
2174
|
-
if (Array.isArray(value)) {
|
|
2175
|
-
return value.map(transformToNumber).filter((item) => item !== null);
|
|
2176
|
-
}
|
|
2177
|
-
else if (typeof value === 'number') {
|
|
2178
|
-
return [value];
|
|
2179
|
-
}
|
|
2180
|
-
return null;
|
|
2181
|
-
};
|
|
2182
|
-
const transformToBoolean = (value) => {
|
|
2183
|
-
if (typeof value === 'boolean') {
|
|
2184
|
-
return value;
|
|
2185
|
-
}
|
|
2186
|
-
if (typeof value === 'string') {
|
|
2187
|
-
return value === 'true' || value === '1';
|
|
2188
|
-
}
|
|
2189
|
-
return null;
|
|
2190
|
-
};
|
|
2191
|
-
const transformToBooleanArray = (value) => {
|
|
2192
|
-
if (Array.isArray(value)) {
|
|
2193
|
-
return value.map(transformToBoolean).filter((item) => item !== null);
|
|
2194
|
-
}
|
|
2195
|
-
else if (typeof value === 'string' || typeof value === 'boolean') {
|
|
2196
|
-
return [transformToBoolean(value)];
|
|
2197
|
-
}
|
|
2198
|
-
return null;
|
|
2199
|
-
};
|
|
2200
|
-
const transformToDate = (value) => {
|
|
2201
|
-
if (value instanceof Date) {
|
|
2202
|
-
return value;
|
|
2203
|
-
}
|
|
2204
|
-
if (typeof value === 'string') {
|
|
2205
|
-
const date = new Date(value);
|
|
2206
|
-
if (isNaN(date.getTime())) {
|
|
2207
|
-
return null;
|
|
2208
|
-
}
|
|
2209
|
-
return date;
|
|
2210
|
-
}
|
|
2211
|
-
return null;
|
|
2212
|
-
};
|
|
2213
|
-
const transformToDateArray = (value) => {
|
|
2214
|
-
if (Array.isArray(value)) {
|
|
2215
|
-
return value.map(transformToDate).filter((item) => item !== null);
|
|
2216
|
-
}
|
|
2217
|
-
else if (typeof value === 'string' || value instanceof Date) {
|
|
2218
|
-
return [transformToDate(value)];
|
|
2219
|
-
}
|
|
2220
|
-
return null;
|
|
2221
|
-
};
|
|
2222
|
-
const transformToSort = (value) => {
|
|
2223
|
-
if (typeof value === 'string') {
|
|
2224
|
-
const [active, direction] = value.split(':');
|
|
2225
|
-
return {
|
|
2226
|
-
active,
|
|
2227
|
-
direction: direction,
|
|
2228
|
-
};
|
|
2229
|
-
}
|
|
2230
|
-
return null;
|
|
2231
|
-
};
|
|
2232
|
-
const transformToSortQueryParam = (value) => {
|
|
2233
|
-
if (typeof value === 'string') {
|
|
2234
|
-
return value;
|
|
2235
|
-
}
|
|
2236
|
-
if (value && typeof value === 'object' && 'active' in value && 'direction' in value) {
|
|
2237
|
-
const valAsSort = value;
|
|
2238
|
-
return valAsSort.direction ? `${valAsSort.active}:${valAsSort.direction}` : null;
|
|
2239
|
-
}
|
|
2240
|
-
return null;
|
|
2241
|
-
};
|
|
2242
|
-
|
|
2243
|
-
const deepFreeze = (object) => {
|
|
2244
|
-
// check if object is actually an object or frozen
|
|
2245
|
-
if (!object || typeof object !== 'object' || Object.isFrozen(object)) {
|
|
2246
|
-
return object;
|
|
2247
|
-
}
|
|
2248
|
-
// Retrieve the property names defined on object
|
|
2249
|
-
const propNames = Object.getOwnPropertyNames(object);
|
|
2250
|
-
// Freeze properties before freezing self
|
|
2251
|
-
for (const name of propNames) {
|
|
2252
|
-
const value = object[name];
|
|
2253
|
-
if (value && typeof value === 'object') {
|
|
2254
|
-
deepFreeze(value);
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
|
-
return Object.freeze(object);
|
|
2258
|
-
};
|
|
2259
|
-
|
|
2260
|
-
/**
|
|
2261
|
-
* Dummy function for providing types while not breaking inference.
|
|
2262
|
-
* **This function always returns null.**
|
|
2263
|
-
* @see https://github.com/microsoft/TypeScript/issues/26242
|
|
2264
|
-
* @returns null
|
|
2265
|
-
*/
|
|
2266
|
-
const def = () => null;
|
|
2267
|
-
|
|
2268
|
-
/**
|
|
2269
|
-
* Generated bundle index. Do not edit.
|
|
2270
|
-
*/
|
|
2271
|
-
|
|
2272
|
-
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryCreator, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryObjectString, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds, extractQuery, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isGqlQueryConfig, isParamValid, isQuery, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, resetPageOnError, serializeBody, shouldCacheQuery, shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
2273
|
-
//# sourceMappingURL=ethlete-query.mjs.map
|