@ethlete/query 0.1.0-next.1 → 0.1.0-next.11
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/basic-auth-provider.mjs +5 -5
- package/esm2020/lib/auth/bearer-auth-provider.mjs +12 -9
- package/esm2020/lib/auth/custom-header-auth-provider.mjs +4 -4
- 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 +17 -17
- 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 +49 -23
- package/esm2020/lib/query/query.types.mjs +1 -1
- package/esm2020/lib/query/query.utils.mjs +17 -2
- package/esm2020/lib/query-client/query-client.mjs +7 -7
- 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 +5 -3
- package/esm2020/lib/request/request.types.mjs +1 -1
- package/esm2020/lib/request/request.util.mjs +24 -6
- package/esm2020/lib/utils/deep-freeze.util.mjs +5 -1
- package/fesm2015/ethlete-query.mjs +240 -117
- package/fesm2015/ethlete-query.mjs.map +1 -1
- package/fesm2020/ethlete-query.mjs +231 -114
- package/fesm2020/ethlete-query.mjs.map +1 -1
- package/lib/auth/auth-provider.types.d.ts +11 -1
- 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 +1 -1
- 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 +17 -14
- package/lib/query/query.utils.d.ts +8 -3
- package/lib/query-client/query-client.d.ts +9 -9
- 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 +12 -10
- package/lib/request/request.util.d.ts +2 -2
- package/lib/utils/deep-freeze.util.d.ts +1 -1
- package/package.json +7 -6
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import { Subject, timer, filter, takeWhile, BehaviorSubject, interval, takeUntil, tap,
|
|
1
|
+
import { Subject, timer, filter, takeWhile, switchMap, of, BehaviorSubject, interval, takeUntil, tap, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
|
|
4
|
+
import { DestroyService } from '@ethlete/core';
|
|
4
5
|
import { FormGroup } from '@angular/forms';
|
|
5
6
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
6
7
|
|
|
7
8
|
class CustomHeaderAuthProvider {
|
|
9
|
+
get header() {
|
|
10
|
+
return { [this._config.name]: this._config.value };
|
|
11
|
+
}
|
|
8
12
|
constructor(_config) {
|
|
9
13
|
this._config = _config;
|
|
10
14
|
this.queryClient = null;
|
|
11
15
|
}
|
|
12
|
-
get header() {
|
|
13
|
-
return { [this._config.name]: this._config.value };
|
|
14
|
-
}
|
|
15
16
|
cleanUp() {
|
|
16
17
|
// noop
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
class BasicAuthProvider {
|
|
21
|
-
constructor(_config) {
|
|
22
|
-
this._config = _config;
|
|
23
|
-
this.queryClient = null;
|
|
24
|
-
}
|
|
25
22
|
get header() {
|
|
26
23
|
return { Authorization: `Basic ${this._basicAuthString}` };
|
|
27
24
|
}
|
|
28
25
|
get _basicAuthString() {
|
|
29
26
|
return btoa(`${this._config.username}:${this._config.password}`);
|
|
30
27
|
}
|
|
28
|
+
constructor(_config) {
|
|
29
|
+
this._config = _config;
|
|
30
|
+
this.queryClient = null;
|
|
31
|
+
}
|
|
31
32
|
cleanUp() {
|
|
32
33
|
// noop
|
|
33
34
|
}
|
|
@@ -164,13 +165,15 @@ const buildTimestampFromSeconds = (seconds) => {
|
|
|
164
165
|
}
|
|
165
166
|
return new Date(Date.now() + seconds * 1000).getTime();
|
|
166
167
|
};
|
|
167
|
-
const buildRequestError = async (error) => {
|
|
168
|
+
const buildRequestError = async (error, route, requestInit) => {
|
|
168
169
|
if (error instanceof DOMException && error.code === error.ABORT_ERR) {
|
|
169
170
|
const err = {
|
|
170
171
|
code: -1,
|
|
171
172
|
message: 'Request aborted',
|
|
172
173
|
detail: null,
|
|
173
174
|
raw: error,
|
|
175
|
+
route,
|
|
176
|
+
requestInit,
|
|
174
177
|
};
|
|
175
178
|
return err;
|
|
176
179
|
}
|
|
@@ -180,6 +183,8 @@ const buildRequestError = async (error) => {
|
|
|
180
183
|
message: 'Syntax error',
|
|
181
184
|
detail: null,
|
|
182
185
|
raw: error,
|
|
186
|
+
route,
|
|
187
|
+
requestInit,
|
|
183
188
|
};
|
|
184
189
|
return err;
|
|
185
190
|
}
|
|
@@ -189,23 +194,35 @@ const buildRequestError = async (error) => {
|
|
|
189
194
|
message: `${error.name}: ${error.message}`,
|
|
190
195
|
detail: null,
|
|
191
196
|
raw: error,
|
|
197
|
+
route,
|
|
198
|
+
requestInit,
|
|
192
199
|
};
|
|
193
200
|
return err;
|
|
194
201
|
}
|
|
195
202
|
if (isFetchResponse(error)) {
|
|
196
203
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
197
|
-
let detail;
|
|
204
|
+
let detail = null;
|
|
198
205
|
try {
|
|
199
|
-
detail = await error.
|
|
206
|
+
detail = await error.json();
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// noop
|
|
200
210
|
}
|
|
201
|
-
|
|
202
|
-
|
|
211
|
+
if (!detail) {
|
|
212
|
+
try {
|
|
213
|
+
detail = await error.text();
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// noop
|
|
217
|
+
}
|
|
203
218
|
}
|
|
204
219
|
const err = {
|
|
205
220
|
code: error.status,
|
|
206
221
|
message: error.statusText,
|
|
207
222
|
detail,
|
|
208
223
|
raw: error,
|
|
224
|
+
route,
|
|
225
|
+
requestInit,
|
|
209
226
|
};
|
|
210
227
|
return err;
|
|
211
228
|
}
|
|
@@ -214,6 +231,8 @@ const buildRequestError = async (error) => {
|
|
|
214
231
|
message: 'Unknown error',
|
|
215
232
|
detail: null,
|
|
216
233
|
raw: error,
|
|
234
|
+
route,
|
|
235
|
+
requestInit,
|
|
217
236
|
};
|
|
218
237
|
return err;
|
|
219
238
|
};
|
|
@@ -260,7 +279,9 @@ const request = async (options) => {
|
|
|
260
279
|
if (!response.ok) {
|
|
261
280
|
throw response;
|
|
262
281
|
}
|
|
263
|
-
const
|
|
282
|
+
const isJsonResponse = response.headers.get('Content-Type')?.includes('application/json');
|
|
283
|
+
const isTextResponse = response.headers.get('Content-Type')?.includes('text/plain');
|
|
284
|
+
const data = (isJsonResponse ? await response.json() : isTextResponse ? await response.text() : null);
|
|
264
285
|
const expiresInSeconds = options.cacheAdapter
|
|
265
286
|
? options.cacheAdapter(response.headers)
|
|
266
287
|
: extractExpiresInSeconds(response.headers);
|
|
@@ -268,7 +289,7 @@ const request = async (options) => {
|
|
|
268
289
|
return { data, expiresInTimestamp };
|
|
269
290
|
}
|
|
270
291
|
catch (error) {
|
|
271
|
-
throw await buildRequestError(error);
|
|
292
|
+
throw await buildRequestError(error, options.route, options.init);
|
|
272
293
|
}
|
|
273
294
|
};
|
|
274
295
|
|
|
@@ -292,6 +313,9 @@ const decryptBearer = (token) => {
|
|
|
292
313
|
};
|
|
293
314
|
|
|
294
315
|
class BearerAuthProvider {
|
|
316
|
+
get header() {
|
|
317
|
+
return { Authorization: `Bearer ${this._token}` };
|
|
318
|
+
}
|
|
295
319
|
constructor(_config) {
|
|
296
320
|
this._config = _config;
|
|
297
321
|
this._refreshToken = null;
|
|
@@ -306,9 +330,6 @@ class BearerAuthProvider {
|
|
|
306
330
|
this._setupRefresh(this._config.refreshConfig);
|
|
307
331
|
}
|
|
308
332
|
}
|
|
309
|
-
get header() {
|
|
310
|
-
return { Authorization: `Bearer ${this._token}` };
|
|
311
|
-
}
|
|
312
333
|
cleanUp() {
|
|
313
334
|
this._refreshTimerSubscription?.unsubscribe();
|
|
314
335
|
this._refreshTimerSubscription = null;
|
|
@@ -321,10 +342,11 @@ class BearerAuthProvider {
|
|
|
321
342
|
const expiresInPropertyName = config.expiresInPropertyName || 'exp';
|
|
322
343
|
const expiresIn = bearer[expiresInPropertyName];
|
|
323
344
|
const fiveMinutes = 5 * 60 * 1000;
|
|
345
|
+
const refreshBuffer = config.refreshBuffer ?? fiveMinutes;
|
|
324
346
|
if (expiresIn === undefined) {
|
|
325
347
|
throw new Error(`Bearer token does not contain an '${expiresInPropertyName}' property`);
|
|
326
348
|
}
|
|
327
|
-
const remainingTime = new Date(expiresIn * 1000).getTime() -
|
|
349
|
+
const remainingTime = new Date(expiresIn * 1000).getTime() - refreshBuffer - new Date().getTime();
|
|
328
350
|
const strategy = config.strategy ?? "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */;
|
|
329
351
|
switch (strategy) {
|
|
330
352
|
case "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */:
|
|
@@ -339,17 +361,19 @@ class BearerAuthProvider {
|
|
|
339
361
|
if (!this.queryClient) {
|
|
340
362
|
throw new Error('Query client instance is null');
|
|
341
363
|
}
|
|
342
|
-
const { method, route,
|
|
364
|
+
const { method, route, requestAdapter, responseAdapter, paramLocation } = config;
|
|
365
|
+
const data = requestAdapter?.(this._refreshToken) ?? { refreshToken: this._refreshToken };
|
|
343
366
|
const fullRoute = buildRoute({
|
|
344
367
|
base: this.queryClient.config.baseRoute,
|
|
345
368
|
route,
|
|
369
|
+
queryParams: paramLocation === 'query' ? data : undefined,
|
|
346
370
|
});
|
|
347
|
-
const
|
|
371
|
+
const requestInit = { body: paramLocation === 'body' ? buildBody(data) : undefined, method };
|
|
348
372
|
this.onRefreshInitiation$.next();
|
|
349
373
|
try {
|
|
350
374
|
const result = await request({
|
|
351
375
|
route: fullRoute,
|
|
352
|
-
init:
|
|
376
|
+
init: requestInit,
|
|
353
377
|
});
|
|
354
378
|
const tokens = responseAdapter ? responseAdapter(result.data) : result.data;
|
|
355
379
|
if (!tokens.token) {
|
|
@@ -364,7 +388,7 @@ class BearerAuthProvider {
|
|
|
364
388
|
}
|
|
365
389
|
catch (error) {
|
|
366
390
|
if (error instanceof Error) {
|
|
367
|
-
this.onRefreshFailure$.next(await buildRequestError(error));
|
|
391
|
+
this.onRefreshFailure$.next(await buildRequestError(error, fullRoute, requestInit));
|
|
368
392
|
}
|
|
369
393
|
else {
|
|
370
394
|
this.onRefreshFailure$.next(error);
|
|
@@ -396,27 +420,6 @@ const gql = (strings, ...values) => {
|
|
|
396
420
|
return str;
|
|
397
421
|
};
|
|
398
422
|
|
|
399
|
-
const deepFreeze = (object) => {
|
|
400
|
-
// Retrieve the property names defined on object
|
|
401
|
-
const propNames = Object.getOwnPropertyNames(object);
|
|
402
|
-
// Freeze properties before freezing self
|
|
403
|
-
for (const name of propNames) {
|
|
404
|
-
const value = object[name];
|
|
405
|
-
if (value && typeof value === 'object') {
|
|
406
|
-
deepFreeze(value);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
return Object.freeze(object);
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Dummy function for providing types while not breaking inference.
|
|
414
|
-
* **This function always returns null.**
|
|
415
|
-
* @see https://github.com/microsoft/TypeScript/issues/26242
|
|
416
|
-
* @returns null
|
|
417
|
-
*/
|
|
418
|
-
const def = () => null;
|
|
419
|
-
|
|
420
423
|
function filterSuccess() {
|
|
421
424
|
return function (source) {
|
|
422
425
|
return source.pipe(filter((value) => isQueryStateSuccess(value)));
|
|
@@ -427,11 +430,26 @@ function filterFailure() {
|
|
|
427
430
|
return source.pipe(filter((value) => isQueryStateFailure(value)));
|
|
428
431
|
};
|
|
429
432
|
}
|
|
433
|
+
function filterQueryStates(allowedStates) {
|
|
434
|
+
return function (source) {
|
|
435
|
+
return source.pipe(filter((value) => value && allowedStates.includes(value.type)));
|
|
436
|
+
};
|
|
437
|
+
}
|
|
430
438
|
function takeUntilResponse() {
|
|
431
439
|
return function (source) {
|
|
432
440
|
return source.pipe(takeWhile((value) => isQueryStateLoading(value), true));
|
|
433
441
|
};
|
|
434
442
|
}
|
|
443
|
+
function filterNull() {
|
|
444
|
+
return function (source) {
|
|
445
|
+
return source.pipe(filter((value) => value !== null));
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function switchQueryState() {
|
|
449
|
+
return function (source) {
|
|
450
|
+
return source.pipe(switchMap((value) => value?.state$ ?? of(null)));
|
|
451
|
+
};
|
|
452
|
+
}
|
|
435
453
|
const isQueryStateLoading = (state) => state?.type === "LOADING" /* QueryStateType.Loading */;
|
|
436
454
|
const isQueryStateSuccess = (state) => state?.type === "SUCCESS" /* QueryStateType.Success */;
|
|
437
455
|
const isQueryStateFailure = (state) => state?.type === "FAILURE" /* QueryStateType.Failure */;
|
|
@@ -459,21 +477,8 @@ const isGqlQueryConfig = (config) => {
|
|
|
459
477
|
};
|
|
460
478
|
|
|
461
479
|
class Query {
|
|
462
|
-
constructor(_client, _queryConfig, _route, _args) {
|
|
463
|
-
this._client = _client;
|
|
464
|
-
this._queryConfig = _queryConfig;
|
|
465
|
-
this._route = _route;
|
|
466
|
-
this._args = _args;
|
|
467
|
-
this._currentId = 0;
|
|
468
|
-
this._abortController = new AbortController();
|
|
469
|
-
this._pollingSubscription = null;
|
|
470
|
-
this._state$ = new BehaviorSubject({
|
|
471
|
-
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
472
|
-
meta: { id: this._currentId },
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
480
|
get _nextId() {
|
|
476
|
-
return this._currentId
|
|
481
|
+
return ++this._currentId;
|
|
477
482
|
}
|
|
478
483
|
get state$() {
|
|
479
484
|
return this._state$.asObservable();
|
|
@@ -491,6 +496,20 @@ class Query {
|
|
|
491
496
|
}
|
|
492
497
|
return ts < Date.now();
|
|
493
498
|
}
|
|
499
|
+
constructor(_client, _queryConfig, _route, _args) {
|
|
500
|
+
this._client = _client;
|
|
501
|
+
this._queryConfig = _queryConfig;
|
|
502
|
+
this._route = _route;
|
|
503
|
+
this._args = _args;
|
|
504
|
+
this._currentId = 0;
|
|
505
|
+
this._abortController = new AbortController();
|
|
506
|
+
this._pollingSubscription = null;
|
|
507
|
+
this._onAbort$ = new Subject();
|
|
508
|
+
this._state$ = new BehaviorSubject({
|
|
509
|
+
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
510
|
+
meta: { id: this._currentId },
|
|
511
|
+
});
|
|
512
|
+
}
|
|
494
513
|
clone() {
|
|
495
514
|
return this._client.fetch(this._queryConfig);
|
|
496
515
|
}
|
|
@@ -505,11 +524,12 @@ class Query {
|
|
|
505
524
|
if (isQueryStateLoading(this._state$.value)) {
|
|
506
525
|
this.abort();
|
|
507
526
|
}
|
|
508
|
-
const meta =
|
|
527
|
+
const meta = { id };
|
|
509
528
|
this._state$.next({
|
|
510
529
|
type: "LOADING" /* QueryStateType.Loading */,
|
|
511
530
|
meta,
|
|
512
531
|
});
|
|
532
|
+
this._updateUseResultInDependencies();
|
|
513
533
|
let body = null;
|
|
514
534
|
let contentType = null;
|
|
515
535
|
if (isGqlQueryConfig(this._queryConfig)) {
|
|
@@ -559,7 +579,11 @@ class Query {
|
|
|
559
579
|
const isResponseObject = typeof response === 'object';
|
|
560
580
|
const isGql = isGqlQueryConfig(this._queryConfig);
|
|
561
581
|
let responseData = null;
|
|
562
|
-
if (isGql &&
|
|
582
|
+
if (isGql &&
|
|
583
|
+
isResponseObject &&
|
|
584
|
+
!!response.data &&
|
|
585
|
+
typeof response.data === 'object' &&
|
|
586
|
+
'data' in response.data) {
|
|
563
587
|
responseData = response.data['data'];
|
|
564
588
|
}
|
|
565
589
|
else {
|
|
@@ -570,9 +594,9 @@ class Query {
|
|
|
570
594
|
: responseData;
|
|
571
595
|
this._state$.next({
|
|
572
596
|
type: "SUCCESS" /* QueryStateType.Success */,
|
|
573
|
-
response:
|
|
574
|
-
rawResponse:
|
|
575
|
-
meta:
|
|
597
|
+
response: transformedResponse,
|
|
598
|
+
rawResponse: responseData,
|
|
599
|
+
meta: { ...meta, expiresAt: response.expiresInTimestamp },
|
|
576
600
|
});
|
|
577
601
|
})
|
|
578
602
|
.catch((error) => this._handleExecuteError(error, meta));
|
|
@@ -581,6 +605,7 @@ class Query {
|
|
|
581
605
|
abort() {
|
|
582
606
|
this._abortController.abort();
|
|
583
607
|
this._abortController = new AbortController();
|
|
608
|
+
this._onAbort$.next();
|
|
584
609
|
return this;
|
|
585
610
|
}
|
|
586
611
|
poll(config) {
|
|
@@ -597,6 +622,26 @@ class Query {
|
|
|
597
622
|
this._pollingSubscription = null;
|
|
598
623
|
return this;
|
|
599
624
|
}
|
|
625
|
+
_updateUseResultInDependencies() {
|
|
626
|
+
if (!this._args?.useResultIn?.length) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
this.state$
|
|
630
|
+
.pipe(filterSuccess(), takeUntil(this._onAbort$), takeUntilResponse(), tap((state) => {
|
|
631
|
+
if (!this._args?.useResultIn) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
for (const query of this._args.useResultIn) {
|
|
635
|
+
query._state$.next({
|
|
636
|
+
type: "SUCCESS" /* QueryStateType.Success */,
|
|
637
|
+
meta: { ...state.meta, id: query._nextId },
|
|
638
|
+
rawResponse: state.rawResponse,
|
|
639
|
+
response: state.response,
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
}))
|
|
643
|
+
.subscribe();
|
|
644
|
+
}
|
|
600
645
|
_handleExecuteError(error, meta) {
|
|
601
646
|
if (isAbortRequestError(error)) {
|
|
602
647
|
this._state$.next({
|
|
@@ -618,6 +663,19 @@ class Query {
|
|
|
618
663
|
}
|
|
619
664
|
|
|
620
665
|
class QueryDirective {
|
|
666
|
+
get query() {
|
|
667
|
+
return this._query;
|
|
668
|
+
}
|
|
669
|
+
set query(v) {
|
|
670
|
+
this._query = v;
|
|
671
|
+
this._subscribeToQuery();
|
|
672
|
+
}
|
|
673
|
+
get cache() {
|
|
674
|
+
return this._cache;
|
|
675
|
+
}
|
|
676
|
+
set cache(v) {
|
|
677
|
+
this._cache = v;
|
|
678
|
+
}
|
|
621
679
|
constructor(_mainTemplateRef, _viewContainerRef, _errorHandler, _cdr) {
|
|
622
680
|
this._mainTemplateRef = _mainTemplateRef;
|
|
623
681
|
this._viewContainerRef = _viewContainerRef;
|
|
@@ -634,19 +692,6 @@ class QueryDirective {
|
|
|
634
692
|
};
|
|
635
693
|
this._cache = false;
|
|
636
694
|
}
|
|
637
|
-
get query() {
|
|
638
|
-
return this._query;
|
|
639
|
-
}
|
|
640
|
-
set query(v) {
|
|
641
|
-
this._query = v;
|
|
642
|
-
this._subscribeToQuery();
|
|
643
|
-
}
|
|
644
|
-
get cache() {
|
|
645
|
-
return this._cache;
|
|
646
|
-
}
|
|
647
|
-
set cache(v) {
|
|
648
|
-
this._cache = v;
|
|
649
|
-
}
|
|
650
695
|
static ngTemplateContextGuard(dir, ctx) {
|
|
651
696
|
return true;
|
|
652
697
|
}
|
|
@@ -698,9 +743,9 @@ class QueryDirective {
|
|
|
698
743
|
}
|
|
699
744
|
}
|
|
700
745
|
}
|
|
701
|
-
QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
702
|
-
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
703
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
746
|
+
QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
747
|
+
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.0", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
|
|
748
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: QueryDirective, decorators: [{
|
|
704
749
|
type: Directive,
|
|
705
750
|
args: [{
|
|
706
751
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -716,16 +761,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
|
|
|
716
761
|
|
|
717
762
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
718
763
|
class InfinityQuery {
|
|
719
|
-
constructor(_config) {
|
|
720
|
-
this._config = _config;
|
|
721
|
-
this._currentPage$ = new BehaviorSubject(null);
|
|
722
|
-
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
723
|
-
this._totalPages$ = new BehaviorSubject(null);
|
|
724
|
-
this._itemsPerPage$ = new BehaviorSubject(this._config.limitParam?.value ?? 10);
|
|
725
|
-
this._currentQuery$ = new BehaviorSubject(null);
|
|
726
|
-
this._data$ = new BehaviorSubject([]);
|
|
727
|
-
this._subscriptions = [];
|
|
728
|
-
}
|
|
729
764
|
get currentPage$() {
|
|
730
765
|
return this._currentPage$.asObservable();
|
|
731
766
|
}
|
|
@@ -762,6 +797,16 @@ class InfinityQuery {
|
|
|
762
797
|
get data() {
|
|
763
798
|
return this._data$.getValue();
|
|
764
799
|
}
|
|
800
|
+
constructor(_config) {
|
|
801
|
+
this._config = _config;
|
|
802
|
+
this._currentPage$ = new BehaviorSubject(null);
|
|
803
|
+
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
804
|
+
this._totalPages$ = new BehaviorSubject(null);
|
|
805
|
+
this._itemsPerPage$ = new BehaviorSubject(this._config.limitParam?.value ?? 10);
|
|
806
|
+
this._currentQuery$ = new BehaviorSubject(null);
|
|
807
|
+
this._data$ = new BehaviorSubject([]);
|
|
808
|
+
this._subscriptions = [];
|
|
809
|
+
}
|
|
765
810
|
nextPage() {
|
|
766
811
|
const newPage = (this._currentPage$.value ?? 0) + 1;
|
|
767
812
|
const calculatedPage = this._config?.pageParam?.valueCalculator?.({
|
|
@@ -880,6 +925,7 @@ const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPa
|
|
|
880
925
|
const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
|
|
881
926
|
class InfinityQueryDirective {
|
|
882
927
|
constructor() {
|
|
928
|
+
this._queryConfigChanged$ = new Subject();
|
|
883
929
|
this._viewContext = {
|
|
884
930
|
$implicit: null,
|
|
885
931
|
infinityQuery: null,
|
|
@@ -893,17 +939,19 @@ class InfinityQueryDirective {
|
|
|
893
939
|
itemsPerPage: null,
|
|
894
940
|
};
|
|
895
941
|
this._infinityQueryInstance = null;
|
|
896
|
-
this._destroy$ =
|
|
942
|
+
this._destroy$ = inject(DestroyService).destroy$;
|
|
897
943
|
this._cdr = inject(ChangeDetectorRef);
|
|
898
944
|
this._viewContainerRef = inject(ViewContainerRef);
|
|
899
945
|
this._mainTemplateRef = inject((TemplateRef));
|
|
900
946
|
this._errorHandler = inject(ErrorHandler);
|
|
947
|
+
this._data$ = new BehaviorSubject([]);
|
|
901
948
|
this._isMainViewCreated = false;
|
|
902
949
|
}
|
|
903
950
|
get infinityQuery() {
|
|
904
951
|
return this._infinityQuery;
|
|
905
952
|
}
|
|
906
953
|
set infinityQuery(v) {
|
|
954
|
+
this._cleanup();
|
|
907
955
|
this._infinityQuery = v;
|
|
908
956
|
this._infinityQueryInstance = this._setupInfinityQuery(v);
|
|
909
957
|
this._loadNextPage();
|
|
@@ -914,6 +962,12 @@ class InfinityQueryDirective {
|
|
|
914
962
|
get instance() {
|
|
915
963
|
return this._infinityQueryInstance;
|
|
916
964
|
}
|
|
965
|
+
get data$() {
|
|
966
|
+
return this._data$.asObservable();
|
|
967
|
+
}
|
|
968
|
+
get data() {
|
|
969
|
+
return this._data$.getValue();
|
|
970
|
+
}
|
|
917
971
|
static ngTemplateContextGuard(dir, ctx) {
|
|
918
972
|
return true;
|
|
919
973
|
}
|
|
@@ -921,8 +975,6 @@ class InfinityQueryDirective {
|
|
|
921
975
|
this._renderMainView();
|
|
922
976
|
}
|
|
923
977
|
ngOnDestroy() {
|
|
924
|
-
this._destroy$.next(true);
|
|
925
|
-
this._destroy$.unsubscribe();
|
|
926
978
|
this.instance?._destroy();
|
|
927
979
|
}
|
|
928
980
|
_setupInfinityQuery(config) {
|
|
@@ -961,15 +1013,17 @@ class InfinityQueryDirective {
|
|
|
961
1013
|
this._viewContext.currentPage = null;
|
|
962
1014
|
this._viewContext.itemsPerPage = null;
|
|
963
1015
|
this._viewContext.totalPages = null;
|
|
1016
|
+
this._data$.next([]);
|
|
964
1017
|
}
|
|
965
1018
|
this._cdr.markForCheck();
|
|
966
|
-
}), takeUntil(this._destroy$))
|
|
1019
|
+
}), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
|
|
967
1020
|
.subscribe();
|
|
968
1021
|
instance.data$
|
|
969
1022
|
.pipe(tap((data) => {
|
|
970
1023
|
this._viewContext.infinityQuery = this._viewContext.$implicit = data;
|
|
1024
|
+
this._data$.next(data);
|
|
971
1025
|
this._cdr.markForCheck();
|
|
972
|
-
}), takeUntil(this._destroy$))
|
|
1026
|
+
}), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
|
|
973
1027
|
.subscribe();
|
|
974
1028
|
return instance;
|
|
975
1029
|
}
|
|
@@ -985,16 +1039,31 @@ class InfinityQueryDirective {
|
|
|
985
1039
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
986
1040
|
}
|
|
987
1041
|
}
|
|
1042
|
+
_cleanup() {
|
|
1043
|
+
this._queryConfigChanged$.next(true);
|
|
1044
|
+
this.instance?._destroy();
|
|
1045
|
+
this._viewContext.loading = false;
|
|
1046
|
+
this._viewContext.error = null;
|
|
1047
|
+
this._viewContext.infinityQuery = null;
|
|
1048
|
+
this._viewContext.$implicit = null;
|
|
1049
|
+
this._viewContext.isFirstLoad = false;
|
|
1050
|
+
this._viewContext.canLoadMore = false;
|
|
1051
|
+
this._viewContext.currentPage = null;
|
|
1052
|
+
this._viewContext.itemsPerPage = null;
|
|
1053
|
+
this._viewContext.totalPages = null;
|
|
1054
|
+
this._data$.next([]);
|
|
1055
|
+
}
|
|
988
1056
|
}
|
|
989
|
-
InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
990
|
-
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
991
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1057
|
+
InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1058
|
+
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.0", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], ngImport: i0 });
|
|
1059
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
992
1060
|
type: Directive,
|
|
993
1061
|
args: [{
|
|
994
1062
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
995
1063
|
selector: '[infinityQuery]',
|
|
1064
|
+
exportAs: 'infinityQuery',
|
|
996
1065
|
standalone: true,
|
|
997
|
-
providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }],
|
|
1066
|
+
providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
|
|
998
1067
|
}]
|
|
999
1068
|
}], propDecorators: { infinityQuery: [{
|
|
1000
1069
|
type: Input
|
|
@@ -1037,9 +1106,9 @@ class InfinityQueryTriggerDirective {
|
|
|
1037
1106
|
this._observer.observe(this._elementRef.nativeElement);
|
|
1038
1107
|
}
|
|
1039
1108
|
}
|
|
1040
|
-
InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1041
|
-
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1042
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1109
|
+
InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1110
|
+
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.0", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
|
|
1111
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
1043
1112
|
type: Directive,
|
|
1044
1113
|
args: [{
|
|
1045
1114
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -1131,6 +1200,12 @@ config, args) => {
|
|
|
1131
1200
|
};
|
|
1132
1201
|
|
|
1133
1202
|
class QueryClient {
|
|
1203
|
+
get config() {
|
|
1204
|
+
return this._clientConfig;
|
|
1205
|
+
}
|
|
1206
|
+
get authProvider() {
|
|
1207
|
+
return this._authProvider;
|
|
1208
|
+
}
|
|
1134
1209
|
constructor(_clientConfig) {
|
|
1135
1210
|
this._clientConfig = _clientConfig;
|
|
1136
1211
|
this._authProvider = null;
|
|
@@ -1205,23 +1280,17 @@ class QueryClient {
|
|
|
1205
1280
|
enableGarbageCollectorLogging: _clientConfig.logging?.queryStateGarbageCollector,
|
|
1206
1281
|
});
|
|
1207
1282
|
}
|
|
1208
|
-
get config() {
|
|
1209
|
-
return this._clientConfig;
|
|
1210
|
-
}
|
|
1211
|
-
get authProvider() {
|
|
1212
|
-
return this._authProvider;
|
|
1213
|
-
}
|
|
1214
1283
|
}
|
|
1215
1284
|
|
|
1216
1285
|
class QueryField {
|
|
1286
|
+
get control() {
|
|
1287
|
+
return this.data.control;
|
|
1288
|
+
}
|
|
1217
1289
|
constructor(data) {
|
|
1218
1290
|
this.data = data;
|
|
1219
1291
|
this.changes$ = this._setupChangesObservable();
|
|
1220
1292
|
this._currentDebounceTimeout = null;
|
|
1221
1293
|
}
|
|
1222
|
-
get control() {
|
|
1223
|
-
return this.data.control;
|
|
1224
|
-
}
|
|
1225
1294
|
setValue(value) {
|
|
1226
1295
|
if (this._currentDebounceTimeout !== null) {
|
|
1227
1296
|
clearTimeout(this._currentDebounceTimeout);
|
|
@@ -1268,10 +1337,11 @@ class QueryForm {
|
|
|
1268
1337
|
const queryParams = this._activatedRoute.snapshot.queryParams;
|
|
1269
1338
|
for (const [key, field] of Object.entries(this._fields)) {
|
|
1270
1339
|
const value = queryParams[key];
|
|
1271
|
-
|
|
1340
|
+
// We only check using == because the value types can be different (e.g. "1" and 1)
|
|
1341
|
+
if (value === undefined || value == field.control.value) {
|
|
1272
1342
|
continue;
|
|
1273
1343
|
}
|
|
1274
|
-
const deserializedValue = field.data.
|
|
1344
|
+
const deserializedValue = field.data.queryParamToValueTransformFn?.(value) ?? value;
|
|
1275
1345
|
field.setValue(deserializedValue);
|
|
1276
1346
|
}
|
|
1277
1347
|
}
|
|
@@ -1321,7 +1391,9 @@ class QueryForm {
|
|
|
1321
1391
|
delete queryParams[key];
|
|
1322
1392
|
}
|
|
1323
1393
|
else {
|
|
1324
|
-
queryParams[key] =
|
|
1394
|
+
queryParams[key] = this._fields[key].data.valueToQueryParamTransformFn
|
|
1395
|
+
? this._fields[key].data.valueToQueryParamTransformFn?.(value)
|
|
1396
|
+
: value;
|
|
1325
1397
|
}
|
|
1326
1398
|
}
|
|
1327
1399
|
this._router.navigate([], {
|
|
@@ -1403,10 +1475,55 @@ const transformToDateArray = (value) => {
|
|
|
1403
1475
|
}
|
|
1404
1476
|
return null;
|
|
1405
1477
|
};
|
|
1478
|
+
const transformToSort = (value) => {
|
|
1479
|
+
if (typeof value === 'string') {
|
|
1480
|
+
const [active, direction] = value.split(':');
|
|
1481
|
+
return {
|
|
1482
|
+
active,
|
|
1483
|
+
direction: direction,
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
return null;
|
|
1487
|
+
};
|
|
1488
|
+
const transformToSortQueryParam = (value) => {
|
|
1489
|
+
if (typeof value === 'string') {
|
|
1490
|
+
return value;
|
|
1491
|
+
}
|
|
1492
|
+
if (value && typeof value === 'object' && 'active' in value && 'direction' in value) {
|
|
1493
|
+
const valAsSort = value;
|
|
1494
|
+
return valAsSort.direction ? `${valAsSort.active}:${valAsSort.direction}` : null;
|
|
1495
|
+
}
|
|
1496
|
+
return null;
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
const deepFreeze = (object) => {
|
|
1500
|
+
// check if object is actually an object or frozen
|
|
1501
|
+
if (!object || typeof object !== 'object' || Object.isFrozen(object)) {
|
|
1502
|
+
return object;
|
|
1503
|
+
}
|
|
1504
|
+
// Retrieve the property names defined on object
|
|
1505
|
+
const propNames = Object.getOwnPropertyNames(object);
|
|
1506
|
+
// Freeze properties before freezing self
|
|
1507
|
+
for (const name of propNames) {
|
|
1508
|
+
const value = object[name];
|
|
1509
|
+
if (value && typeof value === 'object') {
|
|
1510
|
+
deepFreeze(value);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
return Object.freeze(object);
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
/**
|
|
1517
|
+
* Dummy function for providing types while not breaking inference.
|
|
1518
|
+
* **This function always returns null.**
|
|
1519
|
+
* @see https://github.com/microsoft/TypeScript/issues/26242
|
|
1520
|
+
* @returns null
|
|
1521
|
+
*/
|
|
1522
|
+
const def = () => null;
|
|
1406
1523
|
|
|
1407
1524
|
/**
|
|
1408
1525
|
* Generated bundle index. Do not edit.
|
|
1409
1526
|
*/
|
|
1410
1527
|
|
|
1411
|
-
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 };
|
|
1528
|
+
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, filterNull, filterQueryStates, 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, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
1412
1529
|
//# sourceMappingURL=ethlete-query.mjs.map
|