@ethlete/query 3.0.4 → 4.0.1
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/index.mjs +2 -1
- package/esm2020/lib/query/query.types.mjs +1 -1
- package/esm2020/lib/query/query.utils.mjs +33 -2
- package/esm2020/lib/query-form/query-form.mjs +36 -4
- package/esm2020/lib/query-form/query-form.types.mjs +1 -1
- package/esm2020/lib/request/request.util.mjs +7 -2
- package/esm2020/lib/symfony/index.mjs +3 -0
- package/esm2020/lib/symfony/symfony.types.mjs +2 -0
- package/esm2020/lib/symfony/symfony.utils.mjs +19 -0
- package/fesm2015/ethlete-query.mjs +90 -5
- package/fesm2015/ethlete-query.mjs.map +1 -1
- package/fesm2020/ethlete-query.mjs +89 -5
- package/fesm2020/ethlete-query.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/query/query.types.d.ts +12 -0
- package/lib/query/query.utils.d.ts +3 -1
- package/lib/query-form/query-form.d.ts +5 -4
- package/lib/query-form/query-form.types.d.ts +14 -0
- package/lib/query-form/query-form.utils.d.ts +1 -1
- package/lib/symfony/index.d.ts +2 -0
- package/lib/symfony/symfony.types.d.ts +19 -0
- package/lib/symfony/symfony.utils.d.ts +3 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as i1 from '@ethlete/core';
|
|
2
2
|
import { BehaviorSubjectWithSubscriberCount, getCookie, setCookie, deleteCookie, DestroyService, DelayableDirective, equal, clone } from '@ethlete/core';
|
|
3
|
-
import { Observable, filter, takeWhile, switchMap, of, BehaviorSubject, shareReplay, Subject, takeUntil,
|
|
3
|
+
import { Observable, filter, takeWhile, switchMap, of, tap, BehaviorSubject, shareReplay, Subject, takeUntil, interval, skip, map, timer, combineLatest, withLatestFrom, fromEvent, startWith, take, concat, debounceTime, distinctUntilChanged, pairwise } from 'rxjs';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
|
|
5
|
+
import { isDevMode, Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
|
|
6
6
|
import { FormGroup } from '@angular/forms';
|
|
7
7
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
8
8
|
|
|
@@ -49,6 +49,25 @@ const queryStateDoesNotContainKeyError = (data) => new QueryError('005', 'The qu
|
|
|
49
49
|
const queryStateCannotTransformError = (data) => new QueryError('006', 'The query state cannot be transformed because it is not loading', data);
|
|
50
50
|
const invalidBodyError = (data) => new QueryError('007', 'The body is not valid or upsupported', data);
|
|
51
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
|
+
|
|
52
71
|
const isRequestError = (error) => error instanceof Object && 'status' in error && 'statusText' in error && 'url' in error;
|
|
53
72
|
const buildRoute = (options) => {
|
|
54
73
|
if (options.base.endsWith('/')) {
|
|
@@ -279,9 +298,13 @@ const shouldRetryRequest = (config) => {
|
|
|
279
298
|
if (!isRequestError(config.error)) {
|
|
280
299
|
return { retry: false };
|
|
281
300
|
}
|
|
282
|
-
const { status } = config.error;
|
|
301
|
+
const { status, detail } = config.error;
|
|
283
302
|
// Retry on 5xx errors
|
|
284
303
|
if (status >= 500) {
|
|
304
|
+
// Don't retry if a requested page is out of range
|
|
305
|
+
if (isSymfonyPagerfantaOutOfRangeError(detail)) {
|
|
306
|
+
return { retry: false };
|
|
307
|
+
}
|
|
285
308
|
return { retry: true, delay: defaultRetryDelay };
|
|
286
309
|
}
|
|
287
310
|
// Retry on 408 or 425 errors
|
|
@@ -506,6 +529,7 @@ const gql = (strings, ...values) => {
|
|
|
506
529
|
return str;
|
|
507
530
|
};
|
|
508
531
|
|
|
532
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
509
533
|
function filterSuccess() {
|
|
510
534
|
return function (source) {
|
|
511
535
|
return source.pipe(filter((value) => isQueryStateSuccess(value)));
|
|
@@ -551,6 +575,34 @@ function switchQueryCollectionState() {
|
|
|
551
575
|
return source.pipe(switchMap((value) => value?.query.state$ ?? of(null)));
|
|
552
576
|
};
|
|
553
577
|
}
|
|
578
|
+
const resetPageOnError = (config) => (source) => {
|
|
579
|
+
const { queryForm, pageControlKey = 'page' } = config;
|
|
580
|
+
if (isDevMode() && !queryForm.form.controls[pageControlKey]) {
|
|
581
|
+
console.warn(`resetPageOnError: queryForm.form.controls["${pageControlKey}"] is undefined`);
|
|
582
|
+
}
|
|
583
|
+
return source.pipe(switchMap((q) => {
|
|
584
|
+
if (!q) {
|
|
585
|
+
return of(q);
|
|
586
|
+
}
|
|
587
|
+
return q.state$.pipe(tap((state) => {
|
|
588
|
+
if (!isQueryStateFailure(state)) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
switch (state.error.status) {
|
|
592
|
+
// The page is invalid (in prod mode, code is 416)
|
|
593
|
+
case 416 /* HttpStatusCode.RangeNotSatisfiable */:
|
|
594
|
+
queryForm.form.controls[pageControlKey]?.patchValue(1);
|
|
595
|
+
break;
|
|
596
|
+
// The page might be invalid (in dev mode, code is 500)
|
|
597
|
+
case 500 /* HttpStatusCode.InternalServerError */:
|
|
598
|
+
if (isSymfonyPagerfantaOutOfRangeError(state.error.detail)) {
|
|
599
|
+
queryForm.form.controls[pageControlKey].patchValue(1);
|
|
600
|
+
}
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
}), takeUntilResponse());
|
|
604
|
+
}));
|
|
605
|
+
};
|
|
554
606
|
const isQueryStateLoading = (state) => state?.type === "LOADING" /* QueryStateType.Loading */;
|
|
555
607
|
const isQueryStateSuccess = (state) => state?.type === "SUCCESS" /* QueryStateType.Success */;
|
|
556
608
|
const isQueryStateFailure = (state) => state?.type === "FAILURE" /* QueryStateType.Failure */;
|
|
@@ -1971,7 +2023,39 @@ class QueryForm {
|
|
|
1971
2023
|
if (options?.syncViaUrlQueryParams !== false) {
|
|
1972
2024
|
this._syncViaUrlQueryParams(values);
|
|
1973
2025
|
}
|
|
1974
|
-
}))
|
|
2026
|
+
}), pairwise(), startWith([null, this.form.getRawValue()]), map(([previousValue, currentValue]) => ({ previousValue, currentValue })), map(({ previousValue, currentValue }) => {
|
|
2027
|
+
let didResetValues = false;
|
|
2028
|
+
for (const formFieldKey in this._fields) {
|
|
2029
|
+
const resets = this._fields[formFieldKey].data.isResetBy;
|
|
2030
|
+
if (!resets)
|
|
2031
|
+
continue;
|
|
2032
|
+
const resetConditionKeys = Array.isArray(resets) ? resets : [resets];
|
|
2033
|
+
for (const resetConditionKey of resetConditionKeys) {
|
|
2034
|
+
if (!(resetConditionKey in this._fields)) {
|
|
2035
|
+
if (isDevMode()) {
|
|
2036
|
+
console.warn(`The field "${resetConditionKey}" is not defined in the QueryForm. Is it a typo?`, this);
|
|
2037
|
+
}
|
|
2038
|
+
continue;
|
|
2039
|
+
}
|
|
2040
|
+
if (previousValue &&
|
|
2041
|
+
currentValue &&
|
|
2042
|
+
!equal(previousValue[resetConditionKey], currentValue[resetConditionKey])) {
|
|
2043
|
+
const defaultValueForKeyToReset = this._defaultValues[formFieldKey];
|
|
2044
|
+
const currentValueForKeyToReset = currentValue[formFieldKey];
|
|
2045
|
+
if (equal(defaultValueForKeyToReset, currentValueForKeyToReset)) {
|
|
2046
|
+
continue;
|
|
2047
|
+
}
|
|
2048
|
+
this.form.controls[formFieldKey].setValue(defaultValueForKeyToReset);
|
|
2049
|
+
didResetValues = true;
|
|
2050
|
+
break;
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
return (didResetValues || {
|
|
2055
|
+
previousValue,
|
|
2056
|
+
currentValue,
|
|
2057
|
+
});
|
|
2058
|
+
}), filter((value) => value !== true));
|
|
1975
2059
|
}
|
|
1976
2060
|
setFormValueFromUrlQueryParams(options) {
|
|
1977
2061
|
if (!this._activatedRoute) {
|
|
@@ -2168,5 +2252,5 @@ const def = () => null;
|
|
|
2168
2252
|
* Generated bundle index. Do not edit.
|
|
2169
2253
|
*/
|
|
2170
2254
|
|
|
2171
|
-
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, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, serializeBody, shouldCacheQuery, shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
2255
|
+
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 };
|
|
2172
2256
|
//# sourceMappingURL=ethlete-query.mjs.map
|