@ethlete/query 0.1.0-next.2 → 0.1.0-next.20
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/esm2020/lib/auth/auth-provider.types.mjs +1 -1
- package/esm2020/lib/auth/auth-provider.utils.mjs +1 -1
- package/esm2020/lib/auth/basic-auth-provider.mjs +4 -5
- package/esm2020/lib/auth/bearer-auth-provider.mjs +117 -60
- package/esm2020/lib/auth/custom-header-auth-provider.mjs +4 -5
- package/esm2020/lib/directives/infinity-query-trigger.directive.mjs +3 -3
- package/esm2020/lib/directives/infinity-query.directive.mjs +36 -11
- package/esm2020/lib/directives/query.directive.mjs +20 -19
- package/esm2020/lib/infinite-query/infinity-query.mjs +11 -11
- package/esm2020/lib/infinite-query/infinity-query.types.mjs +1 -1
- package/esm2020/lib/query/query.mjs +53 -23
- package/esm2020/lib/query/query.types.mjs +1 -1
- package/esm2020/lib/query/query.utils.mjs +42 -4
- package/esm2020/lib/query-client/query-client.mjs +15 -13
- package/esm2020/lib/query-client/query-client.types.mjs +1 -1
- package/esm2020/lib/query-form/query-form.mjs +10 -7
- package/esm2020/lib/query-form/query-form.types.mjs +1 -1
- package/esm2020/lib/query-form/query-form.utils.mjs +21 -1
- package/esm2020/lib/request/request.mjs +4 -2
- package/esm2020/lib/request/request.util.mjs +16 -8
- package/esm2020/lib/utils/deep-freeze.util.mjs +5 -1
- package/fesm2015/ethlete-query.mjs +443 -248
- package/fesm2015/ethlete-query.mjs.map +1 -1
- package/fesm2020/ethlete-query.mjs +430 -242
- package/fesm2020/ethlete-query.mjs.map +1 -1
- package/lib/auth/auth-provider.types.d.ts +30 -22
- package/lib/auth/auth-provider.utils.d.ts +2 -1
- package/lib/auth/basic-auth-provider.d.ts +0 -2
- package/lib/auth/bearer-auth-provider.d.ts +14 -14
- package/lib/auth/custom-header-auth-provider.d.ts +0 -2
- package/lib/directives/infinity-query-trigger.directive.d.ts +1 -1
- package/lib/directives/infinity-query.directive.d.ts +7 -2
- package/lib/directives/query.directive.d.ts +5 -5
- package/lib/infinite-query/infinity-query.types.d.ts +7 -4
- package/lib/query/query.d.ts +5 -3
- package/lib/query/query.types.d.ts +32 -15
- package/lib/query/query.utils.d.ts +22 -5
- package/lib/query-client/query-client.d.ts +11 -10
- package/lib/query-client/query-client.types.d.ts +9 -9
- package/lib/query-form/query-form.d.ts +1 -1
- package/lib/query-form/query-form.types.d.ts +13 -3
- package/lib/query-form/query-form.utils.d.ts +5 -0
- package/lib/request/request.types.d.ts +10 -10
- package/lib/utils/deep-freeze.util.d.ts +1 -1
- package/package.json +6 -6
|
@@ -1,39 +1,61 @@
|
|
|
1
|
+
import { getCookie, setCookie, deleteCookie, DestroyService } from '@ethlete/core';
|
|
2
|
+
import { filter, takeWhile, switchMap, of, BehaviorSubject, Subject, interval, takeUntil, tap, timer, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
|
|
1
3
|
import { __awaiter } from 'tslib';
|
|
2
|
-
import { Subject, timer, filter, takeWhile, BehaviorSubject, interval, takeUntil, tap, switchMap, of, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
|
|
3
4
|
import * as i0 from '@angular/core';
|
|
4
5
|
import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
|
|
5
6
|
import { FormGroup } from '@angular/forms';
|
|
6
7
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
7
8
|
|
|
8
9
|
class CustomHeaderAuthProvider {
|
|
9
|
-
constructor(_config) {
|
|
10
|
-
this._config = _config;
|
|
11
|
-
this.queryClient = null;
|
|
12
|
-
}
|
|
13
10
|
get header() {
|
|
14
11
|
return { [this._config.name]: this._config.value };
|
|
15
12
|
}
|
|
13
|
+
constructor(_config) {
|
|
14
|
+
this._config = _config;
|
|
15
|
+
}
|
|
16
16
|
cleanUp() {
|
|
17
17
|
// noop
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
class BasicAuthProvider {
|
|
22
|
-
constructor(_config) {
|
|
23
|
-
this._config = _config;
|
|
24
|
-
this.queryClient = null;
|
|
25
|
-
}
|
|
26
22
|
get header() {
|
|
27
23
|
return { Authorization: `Basic ${this._basicAuthString}` };
|
|
28
24
|
}
|
|
29
25
|
get _basicAuthString() {
|
|
30
26
|
return btoa(`${this._config.username}:${this._config.password}`);
|
|
31
27
|
}
|
|
28
|
+
constructor(_config) {
|
|
29
|
+
this._config = _config;
|
|
30
|
+
}
|
|
32
31
|
cleanUp() {
|
|
33
32
|
// noop
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
|
|
36
|
+
const getOpName = /(query|mutation) ?([\w\d-_]+)? ?\(.*?\)? \{/;
|
|
37
|
+
const transformGql = (str) => {
|
|
38
|
+
str = Array.isArray(str) ? str.join('') : str;
|
|
39
|
+
const name = getOpName.exec(str);
|
|
40
|
+
return function (variables) {
|
|
41
|
+
const data = { query: str };
|
|
42
|
+
if (variables)
|
|
43
|
+
data['variables'] = JSON.stringify(variables);
|
|
44
|
+
if (name && name.length) {
|
|
45
|
+
const operationName = name[2];
|
|
46
|
+
if (operationName)
|
|
47
|
+
data['operationName'] = name[2];
|
|
48
|
+
}
|
|
49
|
+
return JSON.stringify(data);
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const gql = (strings, ...values) => {
|
|
53
|
+
const str = strings.reduce((acc, cur, i) => {
|
|
54
|
+
return acc + cur + (values[i] || '');
|
|
55
|
+
}, '');
|
|
56
|
+
return str;
|
|
57
|
+
};
|
|
58
|
+
|
|
37
59
|
const buildErrorMessage = (code, message) => `[@ethlete\\query:${code}] ${message}`;
|
|
38
60
|
class QueryError extends Error {
|
|
39
61
|
constructor(code, message, data) {
|
|
@@ -202,12 +224,20 @@ const buildRequestError = (error, route, requestInit) => __awaiter(void 0, void
|
|
|
202
224
|
}
|
|
203
225
|
if (isFetchResponse(error)) {
|
|
204
226
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
205
|
-
let detail;
|
|
227
|
+
let detail = null;
|
|
206
228
|
try {
|
|
207
|
-
detail = yield error.
|
|
229
|
+
detail = yield error.json();
|
|
230
|
+
}
|
|
231
|
+
catch (_a) {
|
|
232
|
+
// noop
|
|
208
233
|
}
|
|
209
|
-
|
|
210
|
-
|
|
234
|
+
if (!detail) {
|
|
235
|
+
try {
|
|
236
|
+
detail = yield error.text();
|
|
237
|
+
}
|
|
238
|
+
catch (_b) {
|
|
239
|
+
// noop
|
|
240
|
+
}
|
|
211
241
|
}
|
|
212
242
|
const err = {
|
|
213
243
|
code: error.status,
|
|
@@ -236,12 +266,12 @@ const buildBody = (body) => {
|
|
|
236
266
|
if (typeof body === 'string') {
|
|
237
267
|
return body;
|
|
238
268
|
}
|
|
239
|
-
if (typeof body === 'object') {
|
|
240
|
-
return JSON.stringify(body);
|
|
241
|
-
}
|
|
242
269
|
if (body instanceof FormData) {
|
|
243
270
|
return body;
|
|
244
271
|
}
|
|
272
|
+
if (typeof body === 'object') {
|
|
273
|
+
return JSON.stringify(body);
|
|
274
|
+
}
|
|
245
275
|
throw invalidBodyError(body);
|
|
246
276
|
};
|
|
247
277
|
const transformMethod = (method) => {
|
|
@@ -267,12 +297,15 @@ const guessContentType = (body) => {
|
|
|
267
297
|
};
|
|
268
298
|
|
|
269
299
|
const request = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
300
|
+
var _a, _b;
|
|
270
301
|
try {
|
|
271
302
|
const response = yield fetch(options.route, options.init);
|
|
272
303
|
if (!response.ok) {
|
|
273
304
|
throw response;
|
|
274
305
|
}
|
|
275
|
-
const
|
|
306
|
+
const isJsonResponse = (_a = response.headers.get('Content-Type')) === null || _a === void 0 ? void 0 : _a.includes('application/json');
|
|
307
|
+
const isTextResponse = (_b = response.headers.get('Content-Type')) === null || _b === void 0 ? void 0 : _b.includes('text/plain');
|
|
308
|
+
const data = (isJsonResponse ? yield response.json() : isTextResponse ? yield response.text() : null);
|
|
276
309
|
const expiresInSeconds = options.cacheAdapter
|
|
277
310
|
? options.cacheAdapter(response.headers)
|
|
278
311
|
: extractExpiresInSeconds(response.headers);
|
|
@@ -284,157 +317,6 @@ const request = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
284
317
|
}
|
|
285
318
|
});
|
|
286
319
|
|
|
287
|
-
const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
|
|
288
|
-
const isBearerAuthProvider = (authProvider) => authProvider instanceof BearerAuthProvider;
|
|
289
|
-
const isCustomHeaderAuthProvider = (authProvider) => authProvider instanceof CustomHeaderAuthProvider;
|
|
290
|
-
const decryptBearer = (token) => {
|
|
291
|
-
try {
|
|
292
|
-
const base64Url = token.split('.')[1];
|
|
293
|
-
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
294
|
-
const jsonPayload = decodeURIComponent(atob(base64)
|
|
295
|
-
.split('')
|
|
296
|
-
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
297
|
-
.join(''));
|
|
298
|
-
return JSON.parse(jsonPayload);
|
|
299
|
-
}
|
|
300
|
-
catch (error) {
|
|
301
|
-
console.error(`Invalid bearer token: ${token}`, error);
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
class BearerAuthProvider {
|
|
307
|
-
constructor(_config) {
|
|
308
|
-
var _a, _b;
|
|
309
|
-
this._config = _config;
|
|
310
|
-
this._refreshToken = null;
|
|
311
|
-
this._refreshTimerSubscription = null;
|
|
312
|
-
this.queryClient = null;
|
|
313
|
-
this.onRefreshInitiation$ = new Subject();
|
|
314
|
-
this.onRefreshSuccess$ = new Subject();
|
|
315
|
-
this.onRefreshFailure$ = new Subject();
|
|
316
|
-
this._token = _config.token;
|
|
317
|
-
this._refreshToken = (_b = (_a = _config.refreshConfig) === null || _a === void 0 ? void 0 : _a.token) !== null && _b !== void 0 ? _b : null;
|
|
318
|
-
if (this._config.refreshConfig) {
|
|
319
|
-
this._setupRefresh(this._config.refreshConfig);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
get header() {
|
|
323
|
-
return { Authorization: `Bearer ${this._token}` };
|
|
324
|
-
}
|
|
325
|
-
cleanUp() {
|
|
326
|
-
var _a;
|
|
327
|
-
(_a = this._refreshTimerSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
328
|
-
this._refreshTimerSubscription = null;
|
|
329
|
-
}
|
|
330
|
-
_setupRefresh(config) {
|
|
331
|
-
var _a;
|
|
332
|
-
const bearer = decryptBearer(this._token);
|
|
333
|
-
if (!bearer) {
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
const expiresInPropertyName = config.expiresInPropertyName || 'exp';
|
|
337
|
-
const expiresIn = bearer[expiresInPropertyName];
|
|
338
|
-
const fiveMinutes = 5 * 60 * 1000;
|
|
339
|
-
if (expiresIn === undefined) {
|
|
340
|
-
throw new Error(`Bearer token does not contain an '${expiresInPropertyName}' property`);
|
|
341
|
-
}
|
|
342
|
-
const remainingTime = new Date(expiresIn * 1000).getTime() - fiveMinutes - new Date().getTime();
|
|
343
|
-
const strategy = (_a = config.strategy) !== null && _a !== void 0 ? _a : "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */;
|
|
344
|
-
switch (strategy) {
|
|
345
|
-
case "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */:
|
|
346
|
-
this._refreshTimerSubscription = timer(remainingTime).subscribe(() => this._refresh(config));
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
_refresh(config) {
|
|
351
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
352
|
-
if (!this._refreshToken) {
|
|
353
|
-
throw new Error('No refresh token found');
|
|
354
|
-
}
|
|
355
|
-
if (!this.queryClient) {
|
|
356
|
-
throw new Error('Query client instance is null');
|
|
357
|
-
}
|
|
358
|
-
const { method, route, bodyAdapter, responseAdapter } = config;
|
|
359
|
-
const fullRoute = buildRoute({
|
|
360
|
-
base: this.queryClient.config.baseRoute,
|
|
361
|
-
route,
|
|
362
|
-
});
|
|
363
|
-
const body = bodyAdapter ? bodyAdapter(this._refreshToken) : { refreshToken: this._refreshToken };
|
|
364
|
-
const requestInit = { body: buildBody(body), method };
|
|
365
|
-
this.onRefreshInitiation$.next();
|
|
366
|
-
try {
|
|
367
|
-
const result = yield request({
|
|
368
|
-
route: fullRoute,
|
|
369
|
-
init: requestInit,
|
|
370
|
-
});
|
|
371
|
-
const tokens = responseAdapter ? responseAdapter(result.data) : result.data;
|
|
372
|
-
if (!tokens.token) {
|
|
373
|
-
throw new Error('Token not found in response');
|
|
374
|
-
}
|
|
375
|
-
if (!tokens.refreshToken) {
|
|
376
|
-
throw new Error('Refresh token not found in response');
|
|
377
|
-
}
|
|
378
|
-
this._token = tokens.token;
|
|
379
|
-
this._refreshToken = tokens.refreshToken;
|
|
380
|
-
this.onRefreshSuccess$.next(tokens);
|
|
381
|
-
}
|
|
382
|
-
catch (error) {
|
|
383
|
-
if (error instanceof Error) {
|
|
384
|
-
this.onRefreshFailure$.next(yield buildRequestError(error, fullRoute, requestInit));
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
this.onRefreshFailure$.next(error);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
const getOpName = /(query|mutation) ?([\w\d-_]+)? ?\(.*?\)? \{/;
|
|
395
|
-
const transformGql = (str) => {
|
|
396
|
-
str = Array.isArray(str) ? str.join('') : str;
|
|
397
|
-
const name = getOpName.exec(str);
|
|
398
|
-
return function (variables) {
|
|
399
|
-
const data = { query: str };
|
|
400
|
-
if (variables)
|
|
401
|
-
data['variables'] = JSON.stringify(variables);
|
|
402
|
-
if (name && name.length) {
|
|
403
|
-
const operationName = name[2];
|
|
404
|
-
if (operationName)
|
|
405
|
-
data['operationName'] = name[2];
|
|
406
|
-
}
|
|
407
|
-
return JSON.stringify(data);
|
|
408
|
-
};
|
|
409
|
-
};
|
|
410
|
-
const gql = (strings, ...values) => {
|
|
411
|
-
const str = strings.reduce((acc, cur, i) => {
|
|
412
|
-
return acc + cur + (values[i] || '');
|
|
413
|
-
}, '');
|
|
414
|
-
return str;
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
const deepFreeze = (object) => {
|
|
418
|
-
// Retrieve the property names defined on object
|
|
419
|
-
const propNames = Object.getOwnPropertyNames(object);
|
|
420
|
-
// Freeze properties before freezing self
|
|
421
|
-
for (const name of propNames) {
|
|
422
|
-
const value = object[name];
|
|
423
|
-
if (value && typeof value === 'object') {
|
|
424
|
-
deepFreeze(value);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
return Object.freeze(object);
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Dummy function for providing types while not breaking inference.
|
|
432
|
-
* **This function always returns null.**
|
|
433
|
-
* @see https://github.com/microsoft/TypeScript/issues/26242
|
|
434
|
-
* @returns null
|
|
435
|
-
*/
|
|
436
|
-
const def = () => null;
|
|
437
|
-
|
|
438
320
|
function filterSuccess() {
|
|
439
321
|
return function (source) {
|
|
440
322
|
return source.pipe(filter((value) => isQueryStateSuccess(value)));
|
|
@@ -445,9 +327,34 @@ function filterFailure() {
|
|
|
445
327
|
return source.pipe(filter((value) => isQueryStateFailure(value)));
|
|
446
328
|
};
|
|
447
329
|
}
|
|
448
|
-
function
|
|
330
|
+
function filterQueryStates(allowedStates) {
|
|
331
|
+
return function (source) {
|
|
332
|
+
return source.pipe(filter((value) => value && allowedStates.includes(value.type)));
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function takeUntilResponse(config) {
|
|
449
336
|
return function (source) {
|
|
450
|
-
return source.pipe(takeWhile((value) =>
|
|
337
|
+
return source.pipe(takeWhile((value) => {
|
|
338
|
+
if ((config === null || config === void 0 ? void 0 : config.excludeNull) && value === null) {
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
return isQueryStateLoading(value) || value === null;
|
|
342
|
+
}, true));
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function filterNull() {
|
|
346
|
+
return function (source) {
|
|
347
|
+
return source.pipe(filter((value) => value !== null));
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function switchQueryState() {
|
|
351
|
+
return function (source) {
|
|
352
|
+
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); }));
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function switchQueryCollectionState() {
|
|
356
|
+
return function (source) {
|
|
357
|
+
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); }));
|
|
451
358
|
};
|
|
452
359
|
}
|
|
453
360
|
const isQueryStateLoading = (state) => (state === null || state === void 0 ? void 0 : state.type) === "LOADING" /* QueryStateType.Loading */;
|
|
@@ -472,23 +379,23 @@ const isGqlQueryConfig = (config) => {
|
|
|
472
379
|
}
|
|
473
380
|
return true;
|
|
474
381
|
};
|
|
382
|
+
const isQuery = (query) => {
|
|
383
|
+
if (!query || typeof query !== 'object' || Array.isArray(query)) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
if (!('state$' in query)) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
return true;
|
|
390
|
+
};
|
|
391
|
+
const createQueryCollection = (
|
|
392
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
393
|
+
queryMap) => new BehaviorSubject(null);
|
|
394
|
+
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; };
|
|
475
395
|
|
|
476
396
|
class Query {
|
|
477
|
-
constructor(_client, _queryConfig, _route, _args) {
|
|
478
|
-
this._client = _client;
|
|
479
|
-
this._queryConfig = _queryConfig;
|
|
480
|
-
this._route = _route;
|
|
481
|
-
this._args = _args;
|
|
482
|
-
this._currentId = 0;
|
|
483
|
-
this._abortController = new AbortController();
|
|
484
|
-
this._pollingSubscription = null;
|
|
485
|
-
this._state$ = new BehaviorSubject({
|
|
486
|
-
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
487
|
-
meta: { id: this._currentId },
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
397
|
get _nextId() {
|
|
491
|
-
return this._currentId
|
|
398
|
+
return ++this._currentId;
|
|
492
399
|
}
|
|
493
400
|
get state$() {
|
|
494
401
|
return this._state$.asObservable();
|
|
@@ -506,6 +413,20 @@ class Query {
|
|
|
506
413
|
}
|
|
507
414
|
return ts < Date.now();
|
|
508
415
|
}
|
|
416
|
+
constructor(_client, _queryConfig, _route, _args) {
|
|
417
|
+
this._client = _client;
|
|
418
|
+
this._queryConfig = _queryConfig;
|
|
419
|
+
this._route = _route;
|
|
420
|
+
this._args = _args;
|
|
421
|
+
this._currentId = 0;
|
|
422
|
+
this._abortController = new AbortController();
|
|
423
|
+
this._pollingSubscription = null;
|
|
424
|
+
this._onAbort$ = new Subject();
|
|
425
|
+
this._state$ = new BehaviorSubject({
|
|
426
|
+
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
427
|
+
meta: { id: this._currentId },
|
|
428
|
+
});
|
|
429
|
+
}
|
|
509
430
|
clone() {
|
|
510
431
|
return this._client.fetch(this._queryConfig);
|
|
511
432
|
}
|
|
@@ -521,11 +442,12 @@ class Query {
|
|
|
521
442
|
if (isQueryStateLoading(this._state$.value)) {
|
|
522
443
|
this.abort();
|
|
523
444
|
}
|
|
524
|
-
const meta =
|
|
445
|
+
const meta = { id };
|
|
525
446
|
this._state$.next({
|
|
526
447
|
type: "LOADING" /* QueryStateType.Loading */,
|
|
527
448
|
meta,
|
|
528
449
|
});
|
|
450
|
+
this._updateUseResultInDependencies();
|
|
529
451
|
let body = null;
|
|
530
452
|
let contentType = null;
|
|
531
453
|
if (isGqlQueryConfig(this._queryConfig)) {
|
|
@@ -561,6 +483,10 @@ class Query {
|
|
|
561
483
|
};
|
|
562
484
|
}
|
|
563
485
|
}
|
|
486
|
+
// For form data we need to remove content type header because browser will set it automatically including boundary
|
|
487
|
+
if (headers && 'Content-Type' in headers && headers['Content-Type'] === 'multipart/form-data') {
|
|
488
|
+
delete headers['Content-Type'];
|
|
489
|
+
}
|
|
564
490
|
request({
|
|
565
491
|
route: this._route,
|
|
566
492
|
init: {
|
|
@@ -575,7 +501,11 @@ class Query {
|
|
|
575
501
|
const isResponseObject = typeof response === 'object';
|
|
576
502
|
const isGql = isGqlQueryConfig(this._queryConfig);
|
|
577
503
|
let responseData = null;
|
|
578
|
-
if (isGql &&
|
|
504
|
+
if (isGql &&
|
|
505
|
+
isResponseObject &&
|
|
506
|
+
!!response.data &&
|
|
507
|
+
typeof response.data === 'object' &&
|
|
508
|
+
'data' in response.data) {
|
|
579
509
|
responseData = response.data['data'];
|
|
580
510
|
}
|
|
581
511
|
else {
|
|
@@ -586,9 +516,9 @@ class Query {
|
|
|
586
516
|
: responseData;
|
|
587
517
|
this._state$.next({
|
|
588
518
|
type: "SUCCESS" /* QueryStateType.Success */,
|
|
589
|
-
response:
|
|
590
|
-
rawResponse:
|
|
591
|
-
meta:
|
|
519
|
+
response: transformedResponse,
|
|
520
|
+
rawResponse: responseData,
|
|
521
|
+
meta: Object.assign(Object.assign({}, meta), { expiresAt: response.expiresInTimestamp }),
|
|
592
522
|
});
|
|
593
523
|
})
|
|
594
524
|
.catch((error) => this._handleExecuteError(error, meta));
|
|
@@ -597,6 +527,7 @@ class Query {
|
|
|
597
527
|
abort() {
|
|
598
528
|
this._abortController.abort();
|
|
599
529
|
this._abortController = new AbortController();
|
|
530
|
+
this._onAbort$.next();
|
|
600
531
|
return this;
|
|
601
532
|
}
|
|
602
533
|
poll(config) {
|
|
@@ -614,6 +545,28 @@ class Query {
|
|
|
614
545
|
this._pollingSubscription = null;
|
|
615
546
|
return this;
|
|
616
547
|
}
|
|
548
|
+
_updateUseResultInDependencies() {
|
|
549
|
+
var _a, _b;
|
|
550
|
+
if (!((_b = (_a = this._args) === null || _a === void 0 ? void 0 : _a.useResultIn) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
this.state$
|
|
554
|
+
.pipe(filterSuccess(), takeUntil(this._onAbort$), takeUntilResponse(), tap((state) => {
|
|
555
|
+
var _a;
|
|
556
|
+
if (!((_a = this._args) === null || _a === void 0 ? void 0 : _a.useResultIn)) {
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
for (const query of this._args.useResultIn) {
|
|
560
|
+
query._state$.next({
|
|
561
|
+
type: "SUCCESS" /* QueryStateType.Success */,
|
|
562
|
+
meta: Object.assign(Object.assign({}, state.meta), { id: query._nextId }),
|
|
563
|
+
rawResponse: state.rawResponse,
|
|
564
|
+
response: state.response,
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
}))
|
|
568
|
+
.subscribe();
|
|
569
|
+
}
|
|
617
570
|
_handleExecuteError(error, meta) {
|
|
618
571
|
if (isAbortRequestError(error)) {
|
|
619
572
|
this._state$.next({
|
|
@@ -634,7 +587,185 @@ class Query {
|
|
|
634
587
|
}
|
|
635
588
|
}
|
|
636
589
|
|
|
590
|
+
const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
|
|
591
|
+
const isBearerAuthProvider = (authProvider) => authProvider instanceof BearerAuthProvider;
|
|
592
|
+
const isCustomHeaderAuthProvider = (authProvider) => authProvider instanceof CustomHeaderAuthProvider;
|
|
593
|
+
const decryptBearer = (token) => {
|
|
594
|
+
try {
|
|
595
|
+
const base64Url = token.split('.')[1];
|
|
596
|
+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
597
|
+
const jsonPayload = decodeURIComponent(atob(base64)
|
|
598
|
+
.split('')
|
|
599
|
+
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
600
|
+
.join(''));
|
|
601
|
+
return JSON.parse(jsonPayload);
|
|
602
|
+
}
|
|
603
|
+
catch (error) {
|
|
604
|
+
console.error(`Invalid bearer token: ${token}`, error);
|
|
605
|
+
return null;
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
class BearerAuthProvider {
|
|
610
|
+
get header() {
|
|
611
|
+
return { Authorization: `Bearer ${this._tokens$.getValue().token}` };
|
|
612
|
+
}
|
|
613
|
+
get tokens$() {
|
|
614
|
+
return this._tokens$.asObservable();
|
|
615
|
+
}
|
|
616
|
+
get tokens() {
|
|
617
|
+
return this._tokens$.getValue();
|
|
618
|
+
}
|
|
619
|
+
get currentRefreshQuery$() {
|
|
620
|
+
return this._currentRefreshQuery$.asObservable();
|
|
621
|
+
}
|
|
622
|
+
get currentRefreshQuery() {
|
|
623
|
+
return this._currentRefreshQuery$.getValue();
|
|
624
|
+
}
|
|
625
|
+
constructor(_config) {
|
|
626
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
627
|
+
this._config = _config;
|
|
628
|
+
this._destroy$ = new Subject();
|
|
629
|
+
this._currentRefreshQuery$ = new BehaviorSubject(null);
|
|
630
|
+
this._tokens$ = new BehaviorSubject({
|
|
631
|
+
token: null,
|
|
632
|
+
refreshToken: null,
|
|
633
|
+
});
|
|
634
|
+
const cookieEnabled = (_b = (_a = _config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieEnabled) !== null && _b !== void 0 ? _b : true;
|
|
635
|
+
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;
|
|
636
|
+
this._tokens$.next({
|
|
637
|
+
token: _config.token || null,
|
|
638
|
+
refreshToken: ((_e = _config.refreshConfig) === null || _e === void 0 ? void 0 : _e.token) || cookieToken || null,
|
|
639
|
+
});
|
|
640
|
+
if (!this.tokens.token && !this.tokens.refreshToken) {
|
|
641
|
+
if (!((_f = _config.refreshConfig) === null || _f === void 0 ? void 0 : _f.cookieName)) {
|
|
642
|
+
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.');
|
|
643
|
+
}
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (this.tokens.token) {
|
|
647
|
+
this._prepareForRefresh();
|
|
648
|
+
if (this.tokens.refreshToken && ((_g = this._config.refreshConfig) === null || _g === void 0 ? void 0 : _g.cookieName)) {
|
|
649
|
+
setCookie(this._config.refreshConfig.cookieName, this.tokens.refreshToken);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
else if (this.tokens.refreshToken) {
|
|
653
|
+
this._refreshQuery();
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
cleanUp() {
|
|
657
|
+
var _a;
|
|
658
|
+
this._destroy$.next(true);
|
|
659
|
+
this._destroy$.unsubscribe();
|
|
660
|
+
this._currentRefreshQuery$.next(null);
|
|
661
|
+
if ((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieName) {
|
|
662
|
+
deleteCookie(this._config.refreshConfig.cookieName, '/');
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
enableCookie() {
|
|
666
|
+
var _a;
|
|
667
|
+
if (!((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieName)) {
|
|
668
|
+
throw new Error('No cookie name was provided');
|
|
669
|
+
}
|
|
670
|
+
if (!this.tokens.refreshToken) {
|
|
671
|
+
throw new Error('No refresh token was provided');
|
|
672
|
+
}
|
|
673
|
+
this._config.refreshConfig.cookieEnabled = true;
|
|
674
|
+
setCookie(this._config.refreshConfig.cookieName, this.tokens.refreshToken);
|
|
675
|
+
}
|
|
676
|
+
disableCookie() {
|
|
677
|
+
var _a;
|
|
678
|
+
if (!((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.cookieName)) {
|
|
679
|
+
throw new Error('No cookie name was provided');
|
|
680
|
+
}
|
|
681
|
+
this._config.refreshConfig.cookieEnabled = false;
|
|
682
|
+
deleteCookie(this._config.refreshConfig.cookieName, '/');
|
|
683
|
+
}
|
|
684
|
+
_prepareForRefresh() {
|
|
685
|
+
var _a, _b;
|
|
686
|
+
if (!this.tokens.token || !this._config.refreshConfig) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
const bearer = decryptBearer(this.tokens.token);
|
|
690
|
+
if (!bearer) {
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
const expiresInPropertyName = this._config.refreshConfig.expiresInPropertyName || 'exp';
|
|
694
|
+
const expiresIn = bearer[expiresInPropertyName];
|
|
695
|
+
const fiveMinutes = 5 * 60 * 1000;
|
|
696
|
+
const refreshBuffer = (_a = this._config.refreshConfig.refreshBuffer) !== null && _a !== void 0 ? _a : fiveMinutes;
|
|
697
|
+
if (expiresIn === undefined) {
|
|
698
|
+
throw new Error(`Bearer token does not contain an '${expiresInPropertyName}' property`);
|
|
699
|
+
}
|
|
700
|
+
const remainingTime = new Date(expiresIn * 1000).getTime() - refreshBuffer - new Date().getTime();
|
|
701
|
+
const strategy = (_b = this._config.refreshConfig.strategy) !== null && _b !== void 0 ? _b : "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */;
|
|
702
|
+
switch (strategy) {
|
|
703
|
+
case "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */:
|
|
704
|
+
timer(remainingTime)
|
|
705
|
+
.pipe(takeUntil(this._destroy$))
|
|
706
|
+
.subscribe(() => this._refreshQuery());
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
_refreshQuery() {
|
|
711
|
+
var _a, _b, _c;
|
|
712
|
+
const currentRefreshToken = this.tokens.refreshToken;
|
|
713
|
+
if (!currentRefreshToken || !this._config.refreshConfig) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
const args = (_c = (_b = (_a = this._config.refreshConfig).requestArgsAdapter) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
|
717
|
+
token: this.tokens.token,
|
|
718
|
+
refreshToken: currentRefreshToken,
|
|
719
|
+
})) !== null && _c !== void 0 ? _c : {
|
|
720
|
+
body: { refreshToken: currentRefreshToken },
|
|
721
|
+
};
|
|
722
|
+
const query = this._config.refreshConfig.queryCreator.prepare(args).execute({ skipCache: true });
|
|
723
|
+
this._currentRefreshQuery$.next(query);
|
|
724
|
+
this._currentRefreshQuery$
|
|
725
|
+
.pipe(switchQueryState(), tap((state) => {
|
|
726
|
+
var _a, _b, _c, _d, _e;
|
|
727
|
+
if (isQueryStateSuccess(state)) {
|
|
728
|
+
if ((_a = this._config.refreshConfig) === null || _a === void 0 ? void 0 : _a.responseAdapter) {
|
|
729
|
+
const tokens = this._config.refreshConfig.responseAdapter(state.response);
|
|
730
|
+
this._tokens$.next(tokens);
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
this._tokens$.next({
|
|
734
|
+
token: state.response['token'],
|
|
735
|
+
refreshToken: state.response['refreshToken'],
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
const cookieEnabled = (_c = (_b = this._config.refreshConfig) === null || _b === void 0 ? void 0 : _b.cookieEnabled) !== null && _c !== void 0 ? _c : true;
|
|
739
|
+
if (((_d = this._config.refreshConfig) === null || _d === void 0 ? void 0 : _d.cookieName) && this.tokens.refreshToken && cookieEnabled) {
|
|
740
|
+
setCookie(this._config.refreshConfig.cookieName, this.tokens.refreshToken);
|
|
741
|
+
}
|
|
742
|
+
this._prepareForRefresh();
|
|
743
|
+
}
|
|
744
|
+
else if (isQueryStateFailure(state)) {
|
|
745
|
+
this._tokens$.next({ token: null, refreshToken: null });
|
|
746
|
+
if ((_e = this._config.refreshConfig) === null || _e === void 0 ? void 0 : _e.cookieName) {
|
|
747
|
+
deleteCookie(this._config.refreshConfig.cookieName, '/');
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}), takeUntilResponse(), takeUntil(this._destroy$))
|
|
751
|
+
.subscribe();
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
637
755
|
class QueryDirective {
|
|
756
|
+
get query() {
|
|
757
|
+
return this._query;
|
|
758
|
+
}
|
|
759
|
+
set query(v) {
|
|
760
|
+
this._query = v;
|
|
761
|
+
this._subscribeToQuery();
|
|
762
|
+
}
|
|
763
|
+
get cache() {
|
|
764
|
+
return this._cache;
|
|
765
|
+
}
|
|
766
|
+
set cache(v) {
|
|
767
|
+
this._cache = v;
|
|
768
|
+
}
|
|
638
769
|
constructor(_mainTemplateRef, _viewContainerRef, _errorHandler, _cdr) {
|
|
639
770
|
this._mainTemplateRef = _mainTemplateRef;
|
|
640
771
|
this._viewContainerRef = _viewContainerRef;
|
|
@@ -651,19 +782,6 @@ class QueryDirective {
|
|
|
651
782
|
};
|
|
652
783
|
this._cache = false;
|
|
653
784
|
}
|
|
654
|
-
get query() {
|
|
655
|
-
return this._query;
|
|
656
|
-
}
|
|
657
|
-
set query(v) {
|
|
658
|
-
this._query = v;
|
|
659
|
-
this._subscribeToQuery();
|
|
660
|
-
}
|
|
661
|
-
get cache() {
|
|
662
|
-
return this._cache;
|
|
663
|
-
}
|
|
664
|
-
set cache(v) {
|
|
665
|
-
this._cache = v;
|
|
666
|
-
}
|
|
667
785
|
static ngTemplateContextGuard(dir, ctx) {
|
|
668
786
|
return true;
|
|
669
787
|
}
|
|
@@ -681,7 +799,8 @@ class QueryDirective {
|
|
|
681
799
|
if (!this.query) {
|
|
682
800
|
return;
|
|
683
801
|
}
|
|
684
|
-
const
|
|
802
|
+
const query = isQuery(this.query) ? this.query : this.query.query;
|
|
803
|
+
const sub = query.state$.pipe(tap((state) => this._updateView(state))).subscribe();
|
|
685
804
|
this._subscription = sub;
|
|
686
805
|
}
|
|
687
806
|
_updateView(state) {
|
|
@@ -717,9 +836,9 @@ class QueryDirective {
|
|
|
717
836
|
}
|
|
718
837
|
}
|
|
719
838
|
}
|
|
720
|
-
QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
721
|
-
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
722
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
839
|
+
QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
840
|
+
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.2", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
|
|
841
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: QueryDirective, decorators: [{
|
|
723
842
|
type: Directive,
|
|
724
843
|
args: [{
|
|
725
844
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -735,17 +854,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
|
|
|
735
854
|
|
|
736
855
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
737
856
|
class InfinityQuery {
|
|
738
|
-
constructor(_config) {
|
|
739
|
-
var _a, _b;
|
|
740
|
-
this._config = _config;
|
|
741
|
-
this._currentPage$ = new BehaviorSubject(null);
|
|
742
|
-
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
743
|
-
this._totalPages$ = new BehaviorSubject(null);
|
|
744
|
-
this._itemsPerPage$ = new BehaviorSubject((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
|
|
745
|
-
this._currentQuery$ = new BehaviorSubject(null);
|
|
746
|
-
this._data$ = new BehaviorSubject([]);
|
|
747
|
-
this._subscriptions = [];
|
|
748
|
-
}
|
|
749
857
|
get currentPage$() {
|
|
750
858
|
return this._currentPage$.asObservable();
|
|
751
859
|
}
|
|
@@ -782,6 +890,17 @@ class InfinityQuery {
|
|
|
782
890
|
get data() {
|
|
783
891
|
return this._data$.getValue();
|
|
784
892
|
}
|
|
893
|
+
constructor(_config) {
|
|
894
|
+
var _a, _b;
|
|
895
|
+
this._config = _config;
|
|
896
|
+
this._currentPage$ = new BehaviorSubject(null);
|
|
897
|
+
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
898
|
+
this._totalPages$ = new BehaviorSubject(null);
|
|
899
|
+
this._itemsPerPage$ = new BehaviorSubject((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
|
|
900
|
+
this._currentQuery$ = new BehaviorSubject(null);
|
|
901
|
+
this._data$ = new BehaviorSubject([]);
|
|
902
|
+
this._subscriptions = [];
|
|
903
|
+
}
|
|
785
904
|
nextPage() {
|
|
786
905
|
var _a, _b, _c, _d, _e;
|
|
787
906
|
const newPage = ((_a = this._currentPage$.value) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
@@ -884,6 +1003,7 @@ const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPa
|
|
|
884
1003
|
const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
|
|
885
1004
|
class InfinityQueryDirective {
|
|
886
1005
|
constructor() {
|
|
1006
|
+
this._queryConfigChanged$ = new Subject();
|
|
887
1007
|
this._viewContext = {
|
|
888
1008
|
$implicit: null,
|
|
889
1009
|
infinityQuery: null,
|
|
@@ -897,17 +1017,19 @@ class InfinityQueryDirective {
|
|
|
897
1017
|
itemsPerPage: null,
|
|
898
1018
|
};
|
|
899
1019
|
this._infinityQueryInstance = null;
|
|
900
|
-
this._destroy$ =
|
|
1020
|
+
this._destroy$ = inject(DestroyService, { self: true }).destroy$;
|
|
901
1021
|
this._cdr = inject(ChangeDetectorRef);
|
|
902
1022
|
this._viewContainerRef = inject(ViewContainerRef);
|
|
903
1023
|
this._mainTemplateRef = inject((TemplateRef));
|
|
904
1024
|
this._errorHandler = inject(ErrorHandler);
|
|
1025
|
+
this._data$ = new BehaviorSubject([]);
|
|
905
1026
|
this._isMainViewCreated = false;
|
|
906
1027
|
}
|
|
907
1028
|
get infinityQuery() {
|
|
908
1029
|
return this._infinityQuery;
|
|
909
1030
|
}
|
|
910
1031
|
set infinityQuery(v) {
|
|
1032
|
+
this._cleanup();
|
|
911
1033
|
this._infinityQuery = v;
|
|
912
1034
|
this._infinityQueryInstance = this._setupInfinityQuery(v);
|
|
913
1035
|
this._loadNextPage();
|
|
@@ -918,6 +1040,12 @@ class InfinityQueryDirective {
|
|
|
918
1040
|
get instance() {
|
|
919
1041
|
return this._infinityQueryInstance;
|
|
920
1042
|
}
|
|
1043
|
+
get data$() {
|
|
1044
|
+
return this._data$.asObservable();
|
|
1045
|
+
}
|
|
1046
|
+
get data() {
|
|
1047
|
+
return this._data$.getValue();
|
|
1048
|
+
}
|
|
921
1049
|
static ngTemplateContextGuard(dir, ctx) {
|
|
922
1050
|
return true;
|
|
923
1051
|
}
|
|
@@ -926,8 +1054,6 @@ class InfinityQueryDirective {
|
|
|
926
1054
|
}
|
|
927
1055
|
ngOnDestroy() {
|
|
928
1056
|
var _a;
|
|
929
|
-
this._destroy$.next(true);
|
|
930
|
-
this._destroy$.unsubscribe();
|
|
931
1057
|
(_a = this.instance) === null || _a === void 0 ? void 0 : _a._destroy();
|
|
932
1058
|
}
|
|
933
1059
|
_setupInfinityQuery(config) {
|
|
@@ -966,15 +1092,17 @@ class InfinityQueryDirective {
|
|
|
966
1092
|
this._viewContext.currentPage = null;
|
|
967
1093
|
this._viewContext.itemsPerPage = null;
|
|
968
1094
|
this._viewContext.totalPages = null;
|
|
1095
|
+
this._data$.next([]);
|
|
969
1096
|
}
|
|
970
1097
|
this._cdr.markForCheck();
|
|
971
|
-
}), takeUntil(this._destroy$))
|
|
1098
|
+
}), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
|
|
972
1099
|
.subscribe();
|
|
973
1100
|
instance.data$
|
|
974
1101
|
.pipe(tap((data) => {
|
|
975
1102
|
this._viewContext.infinityQuery = this._viewContext.$implicit = data;
|
|
1103
|
+
this._data$.next(data);
|
|
976
1104
|
this._cdr.markForCheck();
|
|
977
|
-
}), takeUntil(this._destroy$))
|
|
1105
|
+
}), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
|
|
978
1106
|
.subscribe();
|
|
979
1107
|
return instance;
|
|
980
1108
|
}
|
|
@@ -990,16 +1118,32 @@ class InfinityQueryDirective {
|
|
|
990
1118
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
991
1119
|
}
|
|
992
1120
|
}
|
|
1121
|
+
_cleanup() {
|
|
1122
|
+
var _a;
|
|
1123
|
+
this._queryConfigChanged$.next(true);
|
|
1124
|
+
(_a = this.instance) === null || _a === void 0 ? void 0 : _a._destroy();
|
|
1125
|
+
this._viewContext.loading = false;
|
|
1126
|
+
this._viewContext.error = null;
|
|
1127
|
+
this._viewContext.infinityQuery = null;
|
|
1128
|
+
this._viewContext.$implicit = null;
|
|
1129
|
+
this._viewContext.isFirstLoad = false;
|
|
1130
|
+
this._viewContext.canLoadMore = false;
|
|
1131
|
+
this._viewContext.currentPage = null;
|
|
1132
|
+
this._viewContext.itemsPerPage = null;
|
|
1133
|
+
this._viewContext.totalPages = null;
|
|
1134
|
+
this._data$.next([]);
|
|
1135
|
+
}
|
|
993
1136
|
}
|
|
994
|
-
InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
995
|
-
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
996
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1137
|
+
InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1138
|
+
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.2", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], ngImport: i0 });
|
|
1139
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
997
1140
|
type: Directive,
|
|
998
1141
|
args: [{
|
|
999
1142
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1000
1143
|
selector: '[infinityQuery]',
|
|
1144
|
+
exportAs: 'infinityQuery',
|
|
1001
1145
|
standalone: true,
|
|
1002
|
-
providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }],
|
|
1146
|
+
providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
|
|
1003
1147
|
}]
|
|
1004
1148
|
}], propDecorators: { infinityQuery: [{
|
|
1005
1149
|
type: Input
|
|
@@ -1043,9 +1187,9 @@ class InfinityQueryTriggerDirective {
|
|
|
1043
1187
|
this._observer.observe(this._elementRef.nativeElement);
|
|
1044
1188
|
}
|
|
1045
1189
|
}
|
|
1046
|
-
InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1047
|
-
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1048
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1190
|
+
InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1191
|
+
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.2", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
|
|
1192
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
1049
1193
|
type: Directive,
|
|
1050
1194
|
args: [{
|
|
1051
1195
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -1140,10 +1284,19 @@ config, args) => {
|
|
|
1140
1284
|
};
|
|
1141
1285
|
|
|
1142
1286
|
class QueryClient {
|
|
1287
|
+
get config() {
|
|
1288
|
+
return this._clientConfig;
|
|
1289
|
+
}
|
|
1290
|
+
get authProvider() {
|
|
1291
|
+
return this._authProvider$.getValue();
|
|
1292
|
+
}
|
|
1293
|
+
get authProvider$() {
|
|
1294
|
+
return this._authProvider$.asObservable();
|
|
1295
|
+
}
|
|
1143
1296
|
constructor(_clientConfig) {
|
|
1144
1297
|
var _a, _b;
|
|
1145
1298
|
this._clientConfig = _clientConfig;
|
|
1146
|
-
this._authProvider = null;
|
|
1299
|
+
this._authProvider$ = new BehaviorSubject(null);
|
|
1147
1300
|
this.get = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'GET' }));
|
|
1148
1301
|
this.post = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'POST' }));
|
|
1149
1302
|
this.put = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'PUT' }));
|
|
@@ -1179,39 +1332,32 @@ class QueryClient {
|
|
|
1179
1332
|
};
|
|
1180
1333
|
};
|
|
1181
1334
|
this.setAuthProvider = (authProvider) => {
|
|
1182
|
-
if (this.
|
|
1335
|
+
if (this.authProvider) {
|
|
1183
1336
|
throw new Error('The auth provider is already set. Please call clearAuthProvider() first.');
|
|
1184
1337
|
}
|
|
1185
|
-
this._authProvider
|
|
1186
|
-
authProvider.queryClient = this;
|
|
1338
|
+
this._authProvider$.next(authProvider);
|
|
1187
1339
|
};
|
|
1188
1340
|
this.clearAuthProvider = () => {
|
|
1189
1341
|
var _a;
|
|
1190
|
-
(_a = this.
|
|
1191
|
-
this._authProvider
|
|
1342
|
+
(_a = this.authProvider) === null || _a === void 0 ? void 0 : _a.cleanUp();
|
|
1343
|
+
this._authProvider$.next(null);
|
|
1192
1344
|
};
|
|
1193
1345
|
this._store = new QueryStore({
|
|
1194
1346
|
enableChangeLogging: (_a = _clientConfig.logging) === null || _a === void 0 ? void 0 : _a.queryStateChanges,
|
|
1195
1347
|
enableGarbageCollectorLogging: (_b = _clientConfig.logging) === null || _b === void 0 ? void 0 : _b.queryStateGarbageCollector,
|
|
1196
1348
|
});
|
|
1197
1349
|
}
|
|
1198
|
-
get config() {
|
|
1199
|
-
return this._clientConfig;
|
|
1200
|
-
}
|
|
1201
|
-
get authProvider() {
|
|
1202
|
-
return this._authProvider;
|
|
1203
|
-
}
|
|
1204
1350
|
}
|
|
1205
1351
|
|
|
1206
1352
|
class QueryField {
|
|
1353
|
+
get control() {
|
|
1354
|
+
return this.data.control;
|
|
1355
|
+
}
|
|
1207
1356
|
constructor(data) {
|
|
1208
1357
|
this.data = data;
|
|
1209
1358
|
this.changes$ = this._setupChangesObservable();
|
|
1210
1359
|
this._currentDebounceTimeout = null;
|
|
1211
1360
|
}
|
|
1212
|
-
get control() {
|
|
1213
|
-
return this.data.control;
|
|
1214
|
-
}
|
|
1215
1361
|
setValue(value) {
|
|
1216
1362
|
if (this._currentDebounceTimeout !== null) {
|
|
1217
1363
|
clearTimeout(this._currentDebounceTimeout);
|
|
@@ -1259,10 +1405,11 @@ class QueryForm {
|
|
|
1259
1405
|
const queryParams = this._activatedRoute.snapshot.queryParams;
|
|
1260
1406
|
for (const [key, field] of Object.entries(this._fields)) {
|
|
1261
1407
|
const value = queryParams[key];
|
|
1262
|
-
|
|
1408
|
+
// We only check using == because the value types can be different (e.g. "1" and 1)
|
|
1409
|
+
if (value === undefined || value == field.control.value) {
|
|
1263
1410
|
continue;
|
|
1264
1411
|
}
|
|
1265
|
-
const deserializedValue = (_c = (_b = (_a = field.data).
|
|
1412
|
+
const deserializedValue = (_c = (_b = (_a = field.data).queryParamToValueTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)) !== null && _c !== void 0 ? _c : value;
|
|
1266
1413
|
field.setValue(deserializedValue);
|
|
1267
1414
|
}
|
|
1268
1415
|
}
|
|
@@ -1304,6 +1451,7 @@ class QueryForm {
|
|
|
1304
1451
|
return defaultValues;
|
|
1305
1452
|
}
|
|
1306
1453
|
_syncViaUrlQueryParams(values) {
|
|
1454
|
+
var _a, _b;
|
|
1307
1455
|
if (!this._router || !this._activatedRoute) {
|
|
1308
1456
|
return;
|
|
1309
1457
|
}
|
|
@@ -1313,7 +1461,9 @@ class QueryForm {
|
|
|
1313
1461
|
delete queryParams[key];
|
|
1314
1462
|
}
|
|
1315
1463
|
else {
|
|
1316
|
-
queryParams[key] =
|
|
1464
|
+
queryParams[key] = this._fields[key].data.valueToQueryParamTransformFn
|
|
1465
|
+
? (_b = (_a = this._fields[key].data).valueToQueryParamTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)
|
|
1466
|
+
: value;
|
|
1317
1467
|
}
|
|
1318
1468
|
}
|
|
1319
1469
|
this._router.navigate([], {
|
|
@@ -1395,10 +1545,55 @@ const transformToDateArray = (value) => {
|
|
|
1395
1545
|
}
|
|
1396
1546
|
return null;
|
|
1397
1547
|
};
|
|
1548
|
+
const transformToSort = (value) => {
|
|
1549
|
+
if (typeof value === 'string') {
|
|
1550
|
+
const [active, direction] = value.split(':');
|
|
1551
|
+
return {
|
|
1552
|
+
active,
|
|
1553
|
+
direction: direction,
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
return null;
|
|
1557
|
+
};
|
|
1558
|
+
const transformToSortQueryParam = (value) => {
|
|
1559
|
+
if (typeof value === 'string') {
|
|
1560
|
+
return value;
|
|
1561
|
+
}
|
|
1562
|
+
if (value && typeof value === 'object' && 'active' in value && 'direction' in value) {
|
|
1563
|
+
const valAsSort = value;
|
|
1564
|
+
return valAsSort.direction ? `${valAsSort.active}:${valAsSort.direction}` : null;
|
|
1565
|
+
}
|
|
1566
|
+
return null;
|
|
1567
|
+
};
|
|
1568
|
+
|
|
1569
|
+
const deepFreeze = (object) => {
|
|
1570
|
+
// check if object is actually an object or frozen
|
|
1571
|
+
if (!object || typeof object !== 'object' || Object.isFrozen(object)) {
|
|
1572
|
+
return object;
|
|
1573
|
+
}
|
|
1574
|
+
// Retrieve the property names defined on object
|
|
1575
|
+
const propNames = Object.getOwnPropertyNames(object);
|
|
1576
|
+
// Freeze properties before freezing self
|
|
1577
|
+
for (const name of propNames) {
|
|
1578
|
+
const value = object[name];
|
|
1579
|
+
if (value && typeof value === 'object') {
|
|
1580
|
+
deepFreeze(value);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
return Object.freeze(object);
|
|
1584
|
+
};
|
|
1585
|
+
|
|
1586
|
+
/**
|
|
1587
|
+
* Dummy function for providing types while not breaking inference.
|
|
1588
|
+
* **This function always returns null.**
|
|
1589
|
+
* @see https://github.com/microsoft/TypeScript/issues/26242
|
|
1590
|
+
* @returns null
|
|
1591
|
+
*/
|
|
1592
|
+
const def = () => null;
|
|
1398
1593
|
|
|
1399
1594
|
/**
|
|
1400
1595
|
* Generated bundle index. Do not edit.
|
|
1401
1596
|
*/
|
|
1402
1597
|
|
|
1403
|
-
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildBody, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryString, buildRequestError, buildRoute, buildTimestampFromSeconds, createInfinityQueryConfig, decryptBearer, deepFreeze, def, extractExpiresInSeconds, filterFailure, filterInvalidParams, filterSuccess, gql, guessContentType, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAbortRequestError, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isFetchResponse, isGqlQueryConfig, isParamValid, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mergeHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, shouldCacheQuery, skipPaginationPageParamCalculator, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToString, transformToStringArray };
|
|
1598
|
+
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildBody, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryString, buildRequestError, buildRoute, buildTimestampFromSeconds, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, extractExpiresInSeconds, extractQuery, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, gql, guessContentType, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAbortRequestError, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isFetchResponse, isGqlQueryConfig, isParamValid, isQuery, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mergeHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, shouldCacheQuery, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
1404
1599
|
//# sourceMappingURL=ethlete-query.mjs.map
|