@ethlete/query 6.0.0-next.16 → 6.0.0-next.18
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/CHANGELOG.md +18 -0
- package/fesm2022/ethlete-query-testing.mjs.map +1 -1
- package/fesm2022/ethlete-query.mjs +397 -157
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/generators/migrate-to-query-v3/legacy-prepare-migration.js +1 -1
- package/generators/prep-for-query-v3/migration.js +3 -3
- package/package.json +8 -9
- package/types/ethlete-query.d.ts +211 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { isDevMode, DestroyRef, InjectionToken, inject, Injector, EnvironmentInjector, ErrorHandler, createEnvironmentInjector, effect, untracked, signal, linkedSignal, computed, runInInjectionContext, assertInInjectionContext, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, ElementRef, input, Pipe, ViewEncapsulation, Component, DOCUMENT, NgZone } from '@angular/core';
|
|
2
|
+
import { isDevMode, DestroyRef, InjectionToken, inject, Injector, EnvironmentInjector, ErrorHandler, createEnvironmentInjector, effect, untracked, signal, linkedSignal, computed, runInInjectionContext, assertInInjectionContext, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, ElementRef, input, Pipe, ViewEncapsulation, Component, resource, DOCUMENT, NgZone } from '@angular/core';
|
|
3
3
|
import { createStaticProvider, RuntimeError, clamp, createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, createProvider, nextFrame, randomId, createRootProvider, isObject, injectRoute, getDomain, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED, previousSignalValue } from '@ethlete/core';
|
|
4
4
|
import { filter, Subject, Subscription, Observable, tap, retry, throwError, timer, catchError, takeUntil, startWith, pairwise, switchMap, of, BehaviorSubject, fromEvent, take, ReplaySubject, map, shareReplay, interval, skip, takeWhile, combineLatest, EMPTY, withLatestFrom, debounceTime, firstValueFrom, merge, throttleTime } from 'rxjs';
|
|
5
5
|
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
@@ -8,6 +8,7 @@ import { getActiveConsumer, setActiveConsumer } from '@angular/core/primitives/s
|
|
|
8
8
|
import { NgClass, AsyncPipe, JsonPipe } from '@angular/common';
|
|
9
9
|
import * as i1 from '@angular/forms';
|
|
10
10
|
import { FormControl, ReactiveFormsModule, FormGroup } from '@angular/forms';
|
|
11
|
+
import { validateAsync } from '@angular/forms/signals';
|
|
11
12
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
12
13
|
import { io } from 'socket.io-client';
|
|
13
14
|
|
|
@@ -194,6 +195,8 @@ const QueryRuntimeErrorCode = {
|
|
|
194
195
|
INVALID_STATE_INSIDE_SECURE_EXECUTE_FACTORY: 701,
|
|
195
196
|
// Query Execution
|
|
196
197
|
CIRCULAR_QUERY_DEPENDENCY: 800,
|
|
198
|
+
// Query Sequence
|
|
199
|
+
QUERY_SEQUENCE_ALREADY_RUNNING: 900,
|
|
197
200
|
};
|
|
198
201
|
const queryFeatureUsedMultipleTimes = (type) => {
|
|
199
202
|
return new RuntimeError(QueryRuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES, `The query feature "${type}()" was used multiple times.`);
|
|
@@ -262,6 +265,9 @@ const invalidStateInsideSecureExecuteFactory = () => {
|
|
|
262
265
|
const circularQueryDependency = () => {
|
|
263
266
|
return new RuntimeError(QueryRuntimeErrorCode.CIRCULAR_QUERY_DEPENDENCY, `Query was executed more than 5 times in less than 100ms. This is usually a sign of a circular dependency.`);
|
|
264
267
|
};
|
|
268
|
+
const querySequenceAlreadyRunning = () => {
|
|
269
|
+
return new RuntimeError(QueryRuntimeErrorCode.QUERY_SEQUENCE_ALREADY_RUNNING, `run() was called on a query sequence that is already running. Wait for the current run to settle before starting another.`);
|
|
270
|
+
};
|
|
265
271
|
|
|
266
272
|
/**
|
|
267
273
|
* Returning this inside a withArgs feature will reset the query args to null.
|
|
@@ -1266,7 +1272,7 @@ const request = (config) => {
|
|
|
1266
1272
|
body = text;
|
|
1267
1273
|
}
|
|
1268
1274
|
}
|
|
1269
|
-
catch
|
|
1275
|
+
catch {
|
|
1270
1276
|
// Ignore the error.
|
|
1271
1277
|
}
|
|
1272
1278
|
}
|
|
@@ -3354,13 +3360,17 @@ const isQueryCollection = (query) => {
|
|
|
3354
3360
|
const createQueryCollection = (
|
|
3355
3361
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3356
3362
|
queryMap) => new BehaviorSubject(null);
|
|
3357
|
-
const createQueryCollectionSubject = (
|
|
3363
|
+
const createQueryCollectionSubject = (
|
|
3364
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3365
|
+
queryMap, config) => {
|
|
3358
3366
|
assertInInjectionContext(createQueryCollectionSubject);
|
|
3359
3367
|
const subject = new BehaviorSubject(null);
|
|
3360
3368
|
addQueryContainerHandling(subject.pipe(map((s) => s?.query ?? null)), () => subject.getValue()?.query ?? null, config);
|
|
3361
3369
|
return subject;
|
|
3362
3370
|
};
|
|
3363
|
-
const createQueryCollectionSignal = (
|
|
3371
|
+
const createQueryCollectionSignal = (
|
|
3372
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3373
|
+
queryMap, config) => {
|
|
3364
3374
|
assertInInjectionContext(createQueryCollectionSignal);
|
|
3365
3375
|
const _signal = signal(null, /* @ts-ignore */
|
|
3366
3376
|
...(ngDevMode ? [{ debugName: "_signal" }] : /* istanbul ignore next */ []));
|
|
@@ -4307,7 +4317,7 @@ class InfinityQueryDirective {
|
|
|
4307
4317
|
get data$() {
|
|
4308
4318
|
return this._data$.asObservable();
|
|
4309
4319
|
}
|
|
4310
|
-
static ngTemplateContextGuard(
|
|
4320
|
+
static ngTemplateContextGuard(_dir, _ctx) {
|
|
4311
4321
|
return true;
|
|
4312
4322
|
}
|
|
4313
4323
|
constructor() {
|
|
@@ -4409,13 +4419,13 @@ class InfinityQueryDirective {
|
|
|
4409
4419
|
this._viewContext.currentQuery = null;
|
|
4410
4420
|
this._data$.next([]);
|
|
4411
4421
|
}
|
|
4412
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4413
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.
|
|
4422
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4423
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [
|
|
4414
4424
|
{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective },
|
|
4415
4425
|
provideInfinityQueryResponseDelay(),
|
|
4416
4426
|
], exportAs: ["etInfinityQuery"], ngImport: i0 }); }
|
|
4417
4427
|
}
|
|
4418
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
4428
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
4419
4429
|
type: Directive,
|
|
4420
4430
|
args: [{
|
|
4421
4431
|
selector: '[etInfinityQuery]',
|
|
@@ -4475,10 +4485,10 @@ class InfinityQueryTriggerDirective {
|
|
|
4475
4485
|
});
|
|
4476
4486
|
this._observer.observe(this._elementRef.nativeElement);
|
|
4477
4487
|
}
|
|
4478
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4479
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.
|
|
4488
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4489
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: { classPropertyName: "scrollContainerSelector", publicName: "scrollContainerSelector", isSignal: true, isRequired: false, transformFunction: null }, infinityQueryOverride: { classPropertyName: "infinityQueryOverride", publicName: "infinityQueryOverride", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
4480
4490
|
}
|
|
4481
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
4491
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
4482
4492
|
type: Directive,
|
|
4483
4493
|
args: [{
|
|
4484
4494
|
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
@@ -4486,7 +4496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
4486
4496
|
}], propDecorators: { scrollContainerSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollContainerSelector", required: false }] }], infinityQueryOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "infinityQueryOverride", required: false }] }] } });
|
|
4487
4497
|
|
|
4488
4498
|
class QueryDirective {
|
|
4489
|
-
static ngTemplateContextGuard(
|
|
4499
|
+
static ngTemplateContextGuard(_dir, _ctx) {
|
|
4490
4500
|
return true;
|
|
4491
4501
|
}
|
|
4492
4502
|
constructor() {
|
|
@@ -4564,10 +4574,10 @@ class QueryDirective {
|
|
|
4564
4574
|
});
|
|
4565
4575
|
});
|
|
4566
4576
|
}
|
|
4567
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4568
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.
|
|
4577
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4578
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: { classPropertyName: "query", publicName: "etQuery", isSignal: true, isRequired: true, transformFunction: null }, cache: { classPropertyName: "cache", publicName: "etQueryCache", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
4569
4579
|
}
|
|
4570
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
4580
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDirective, decorators: [{
|
|
4571
4581
|
type: Directive,
|
|
4572
4582
|
args: [{
|
|
4573
4583
|
selector: '[etQuery]',
|
|
@@ -4588,10 +4598,10 @@ class QueryShortNamePipe {
|
|
|
4588
4598
|
}
|
|
4589
4599
|
return route;
|
|
4590
4600
|
}
|
|
4591
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4592
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.
|
|
4601
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
4602
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
|
|
4593
4603
|
}
|
|
4594
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
4604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryShortNamePipe, decorators: [{
|
|
4595
4605
|
type: Pipe,
|
|
4596
4606
|
args: [{ name: 'queryShortName' }]
|
|
4597
4607
|
}] });
|
|
@@ -4638,15 +4648,13 @@ class QueryDevtoolsComponent {
|
|
|
4638
4648
|
this.selectedQueryId = signal(null, /* @ts-ignore */
|
|
4639
4649
|
...(ngDevMode ? [{ debugName: "selectedQueryId" }] : /* istanbul ignore next */ []));
|
|
4640
4650
|
this.selectedClientConfig = computed(() => {
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
if (!cfg) {
|
|
4647
|
-
return this.queryClientConfigs[0];
|
|
4651
|
+
const configs = this.queryClientConfigs;
|
|
4652
|
+
const index = configs.length === 1 ? 0 : (this.selectedClientId() ?? 0);
|
|
4653
|
+
const config = configs[index] ?? configs[0];
|
|
4654
|
+
if (!config) {
|
|
4655
|
+
throw new Error('QueryDevtools: no query client configs registered');
|
|
4648
4656
|
}
|
|
4649
|
-
return
|
|
4657
|
+
return config;
|
|
4650
4658
|
}, /* @ts-ignore */
|
|
4651
4659
|
...(ngDevMode ? [{ debugName: "selectedClientConfig" }] : /* istanbul ignore next */ []));
|
|
4652
4660
|
this.queryStore = computed(() => {
|
|
@@ -4899,10 +4907,10 @@ class QueryDevtoolsComponent {
|
|
|
4899
4907
|
clearQueryHistory() {
|
|
4900
4908
|
this.queryHistory$.next([]);
|
|
4901
4909
|
}
|
|
4902
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4903
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ $safeNavigationMigration(query?.state$) | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }], encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
4910
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4911
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ $safeNavigationMigration(query?.state$) | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }], encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
4904
4912
|
}
|
|
4905
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
4913
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
4906
4914
|
type: Component,
|
|
4907
4915
|
args: [{ selector: 'et-query-devtools', encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
4908
4916
|
class: 'et-query-devtools',
|
|
@@ -5063,6 +5071,216 @@ const removeFrom = (store, { where, id }) => {
|
|
|
5063
5071
|
.subscribe();
|
|
5064
5072
|
};
|
|
5065
5073
|
|
|
5074
|
+
/** `kind` of a `ValidationError` created from a single server violation. */
|
|
5075
|
+
const SERVER_VIOLATION_ERROR_KIND = 'etServerViolation';
|
|
5076
|
+
/** `kind` of the form-level fallback error created when a failed request carries no violations. */
|
|
5077
|
+
const SERVER_ERROR_KIND = 'etServerError';
|
|
5078
|
+
/**
|
|
5079
|
+
* Extracts the violation list from a failed request in any of the shapes it may reach you:
|
|
5080
|
+
* a `QueryErrorResponse` (from `query.error()` or a settled snapshot), a raw `HttpErrorResponse`,
|
|
5081
|
+
* an already-unwrapped error body, or a plain violation array. Returns `[]` when the error
|
|
5082
|
+
* carries no violations.
|
|
5083
|
+
*/
|
|
5084
|
+
const extractFormViolations = (error) => {
|
|
5085
|
+
if (!error)
|
|
5086
|
+
return [];
|
|
5087
|
+
const body = isQueryErrorResponse(error) ? error.raw.error : error instanceof HttpErrorResponse ? error.error : error;
|
|
5088
|
+
if (isSymfonyFormViolationListError(body)) {
|
|
5089
|
+
return body.violations;
|
|
5090
|
+
}
|
|
5091
|
+
if (isSymfonyListError(body)) {
|
|
5092
|
+
return body;
|
|
5093
|
+
}
|
|
5094
|
+
return [];
|
|
5095
|
+
};
|
|
5096
|
+
/**
|
|
5097
|
+
* Maps a failed request's violations onto a signal-forms field tree as validation errors —
|
|
5098
|
+
* the bridge between an API's violation list (`@ethlete/types` `FormViolationView`) and
|
|
5099
|
+
* signal forms.
|
|
5100
|
+
*
|
|
5101
|
+
* Each violation's `propertyPath` (e.g. `items[2].name`) is resolved against `fieldTree`; a
|
|
5102
|
+
* resolved violation becomes a `ServerViolationValidationError` bound to that field, an
|
|
5103
|
+
* unresolved one becomes a form-level error (customizable via `onUnmappedViolation`). A failed
|
|
5104
|
+
* request that carries no violations at all degrades to form-level `ServerValidationError`s
|
|
5105
|
+
* built from the normalized error message — so returning this function's result from a
|
|
5106
|
+
* `submit()` action never silently succeeds on failure.
|
|
5107
|
+
*
|
|
5108
|
+
* ```ts
|
|
5109
|
+
* await submit(this.form, async (field) => {
|
|
5110
|
+
* const snapshot = await executeUntilSettled(this.createPost, { args: { body: field().value() } });
|
|
5111
|
+
* const error = snapshot.error();
|
|
5112
|
+
*
|
|
5113
|
+
* if (!error) return;
|
|
5114
|
+
*
|
|
5115
|
+
* return mapViolationsToFormErrors({ fieldTree: field, error });
|
|
5116
|
+
* });
|
|
5117
|
+
* ```
|
|
5118
|
+
*/
|
|
5119
|
+
const mapViolationsToFormErrors = (options) => {
|
|
5120
|
+
const { fieldTree, error, rewritePath, onUnmappedViolation } = options;
|
|
5121
|
+
if (error === null || error === undefined)
|
|
5122
|
+
return [];
|
|
5123
|
+
const violations = extractFormViolations(error);
|
|
5124
|
+
if (!violations.length) {
|
|
5125
|
+
// An empty violation array is an explicit "nothing to map" — only unrecognized error
|
|
5126
|
+
// shapes degrade to the form-level fallback.
|
|
5127
|
+
if (Array.isArray(error) && !error.length)
|
|
5128
|
+
return [];
|
|
5129
|
+
return createFallbackErrors(error);
|
|
5130
|
+
}
|
|
5131
|
+
const errors = [];
|
|
5132
|
+
for (const violation of violations) {
|
|
5133
|
+
const rawPath = violation.propertyPath;
|
|
5134
|
+
const path = rawPath && rewritePath ? rewritePath(rawPath, violation) : rawPath;
|
|
5135
|
+
const resolvedFieldTree = path ? resolveFieldTreePath(fieldTree, path) : null;
|
|
5136
|
+
if (resolvedFieldTree) {
|
|
5137
|
+
const mappedError = {
|
|
5138
|
+
kind: SERVER_VIOLATION_ERROR_KIND,
|
|
5139
|
+
message: violation.message,
|
|
5140
|
+
fieldTree: resolvedFieldTree,
|
|
5141
|
+
violation,
|
|
5142
|
+
};
|
|
5143
|
+
errors.push(mappedError);
|
|
5144
|
+
}
|
|
5145
|
+
else if (onUnmappedViolation) {
|
|
5146
|
+
const customError = onUnmappedViolation(violation);
|
|
5147
|
+
if (customError) {
|
|
5148
|
+
errors.push(customError);
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5151
|
+
else {
|
|
5152
|
+
const unmappedError = {
|
|
5153
|
+
kind: SERVER_VIOLATION_ERROR_KIND,
|
|
5154
|
+
message: violation.message,
|
|
5155
|
+
violation,
|
|
5156
|
+
};
|
|
5157
|
+
errors.push(unmappedError);
|
|
5158
|
+
}
|
|
5159
|
+
}
|
|
5160
|
+
return errors;
|
|
5161
|
+
};
|
|
5162
|
+
const createFallbackErrors = (error) => {
|
|
5163
|
+
const queryError = isQueryErrorResponse(error) ? error : createQueryErrorResponse(error);
|
|
5164
|
+
if (queryError.isList) {
|
|
5165
|
+
return queryError.errors.map((item) => ({ kind: SERVER_ERROR_KIND, message: item.message }));
|
|
5166
|
+
}
|
|
5167
|
+
return [{ kind: SERVER_ERROR_KIND, message: queryError.error.message }];
|
|
5168
|
+
};
|
|
5169
|
+
/** Splits a property path like `items[2].name` or `translations['de'].title` into its segments. */
|
|
5170
|
+
const parsePropertyPath = (path) => {
|
|
5171
|
+
return path
|
|
5172
|
+
.replace(/\[(['"]?)([^\]]*?)\1\]/g, '.$2')
|
|
5173
|
+
.split('.')
|
|
5174
|
+
.filter((segment) => segment.length > 0);
|
|
5175
|
+
};
|
|
5176
|
+
const resolveFieldTreePath = (fieldTree, path) => {
|
|
5177
|
+
let current = fieldTree;
|
|
5178
|
+
for (const segment of parsePropertyPath(path)) {
|
|
5179
|
+
if (current === null || (typeof current !== 'object' && typeof current !== 'function')) {
|
|
5180
|
+
return null;
|
|
5181
|
+
}
|
|
5182
|
+
current = current[segment];
|
|
5183
|
+
}
|
|
5184
|
+
// A field tree node is callable (calling it returns the field state) — anything else means the
|
|
5185
|
+
// path left the tree (e.g. an index past the array's current length).
|
|
5186
|
+
return typeof current === 'function' ? current : null;
|
|
5187
|
+
};
|
|
5188
|
+
|
|
5189
|
+
// Shared core for the query-backed async validators (`validateWithQuery` /
|
|
5190
|
+
// `validateWithV2Query`). Everything except how the query is executed — the `factory` that turns
|
|
5191
|
+
// the debounced params into a `Resource` — is identical between the v2 and v3 variants, so it is
|
|
5192
|
+
// factored here and imported by both. This module is intentionally NOT part of the `http` barrel;
|
|
5193
|
+
// it is internal plumbing consumed by direct path (the legacy variant already imports from `http`).
|
|
5194
|
+
/** Default debounce (ms) applied before a validate request runs, mirroring `selectOptionsFrom*Query`. */
|
|
5195
|
+
const DEFAULT_QUERY_VALIDATION_DEBOUNCE = 300;
|
|
5196
|
+
/**
|
|
5197
|
+
* Turns a failed validate request into field errors — the default `onError` mapping shared by both
|
|
5198
|
+
* validators. Reuses the existing `mapViolationsToFormErrors` bridge: a `422` violation list is
|
|
5199
|
+
* resolved onto the child fields by `propertyPath`, while a network / non-violation error degrades
|
|
5200
|
+
* to a non-swallowed form-level error. A caller-supplied `mapViolations` overrides only the
|
|
5201
|
+
* violation → error step (it receives the already-extracted violations).
|
|
5202
|
+
*/
|
|
5203
|
+
const mapQueryValidationError = (error, ctx, mapViolations) => {
|
|
5204
|
+
// Angular's `resource()` wraps a thrown non-`Error` (our `QueryErrorResponse` / `HttpErrorResponse`)
|
|
5205
|
+
// into an `Error` and stashes the original on `.cause`, so unwrap it before extraction.
|
|
5206
|
+
const cause = error instanceof Error && error.cause !== undefined ? error.cause : error;
|
|
5207
|
+
if (mapViolations) {
|
|
5208
|
+
return mapViolations(extractFormViolations(cause), ctx);
|
|
5209
|
+
}
|
|
5210
|
+
// `ctx.fieldTree` is the (read-only) tree of the validated field; `propertyPath`s resolve against
|
|
5211
|
+
// it. The cast bridges `ReadonlyFieldTree` → `FieldTree` — `mapViolationsToFormErrors` only walks
|
|
5212
|
+
// and reads the tree, never mutates it.
|
|
5213
|
+
return mapViolationsToFormErrors({ fieldTree: ctx.fieldTree, error: cause });
|
|
5214
|
+
};
|
|
5215
|
+
/**
|
|
5216
|
+
* Binds a query-backed async validator to `path` via `validateAsync`. Success (`204` / any `2xx`
|
|
5217
|
+
* with no violation body) reports no errors; a failed request is mapped by
|
|
5218
|
+
* {@link mapQueryValidationError}. Async validation only runs once the field's synchronous
|
|
5219
|
+
* validators pass and while `when` holds — signal forms feeds the `factory` `undefined` params when
|
|
5220
|
+
* the request shouldn't run, so the resource stays idle.
|
|
5221
|
+
*/
|
|
5222
|
+
const applyQueryAsyncValidator = (path, config) => {
|
|
5223
|
+
validateAsync(path, {
|
|
5224
|
+
params: config.params,
|
|
5225
|
+
debounce: config.debounce ?? DEFAULT_QUERY_VALIDATION_DEBOUNCE,
|
|
5226
|
+
factory: config.factory,
|
|
5227
|
+
when: config.when,
|
|
5228
|
+
onSuccess: () => null,
|
|
5229
|
+
onError: (error, ctx) => mapQueryValidationError(error, ctx, config.mapViolations),
|
|
5230
|
+
});
|
|
5231
|
+
};
|
|
5232
|
+
|
|
5233
|
+
/**
|
|
5234
|
+
* Binds a query-backed async validator to a signal-forms field, adapting a **legacy v2**
|
|
5235
|
+
* `@ethlete/query` query into what `validateAsync` consumes — the `V2QueryClient` counterpart of
|
|
5236
|
+
* {@link validateWithQuery}, so apps that haven't migrated yet can still validate against the
|
|
5237
|
+
* server. The query runs through the client (bearer auth, base route, caching, Symfony error
|
|
5238
|
+
* normalization), where a raw `httpResource` would fire unauthenticated and bypass the pipeline.
|
|
5239
|
+
*
|
|
5240
|
+
* The query is prepared and executed (debounced) as the field value changes, only after the
|
|
5241
|
+
* field's synchronous validators pass. A `204` / successful response reports no errors; a
|
|
5242
|
+
* `422 FormViolationListView` maps each violation onto its child field by `propertyPath`; a
|
|
5243
|
+
* network / other error degrades to a non-swallowed form-level error.
|
|
5244
|
+
*
|
|
5245
|
+
* Call it from a schema definition, the same place you'd call `validateAsync`:
|
|
5246
|
+
*
|
|
5247
|
+
* ```ts
|
|
5248
|
+
* const schema = schema<OpportunityEmail>((p) => {
|
|
5249
|
+
* validateWithV2Query(p, {
|
|
5250
|
+
* queryCreator: postOpportunityEmailValidate, // hubApiClient.post({ ... })
|
|
5251
|
+
* args: (ctx) => ({ pathParams: { opportunityId }, body: { ...ctx.value() } }),
|
|
5252
|
+
* });
|
|
5253
|
+
* });
|
|
5254
|
+
* ```
|
|
5255
|
+
*/
|
|
5256
|
+
const validateWithV2Query = (path, config) => {
|
|
5257
|
+
applyQueryAsyncValidator(path, {
|
|
5258
|
+
params: config.args,
|
|
5259
|
+
debounce: config.debounce,
|
|
5260
|
+
when: config.when,
|
|
5261
|
+
mapViolations: config.mapViolations,
|
|
5262
|
+
factory: (params) => resource({
|
|
5263
|
+
params: () => params(),
|
|
5264
|
+
loader: ({ params: prepareArgs, abortSignal }) => {
|
|
5265
|
+
// Prepared per request — v2 caches by the prepared args, so a fresh `prepare()` is the
|
|
5266
|
+
// legacy idiom (the sibling `selectOptionsFromV2Query` does the same via `queryComputed`).
|
|
5267
|
+
const query = config.queryCreator.prepare(prepareArgs);
|
|
5268
|
+
abortSignal.addEventListener('abort', () => query.abort());
|
|
5269
|
+
query.execute();
|
|
5270
|
+
// Resolve once the query settles. A failure is thrown so it lands in `onError`, where the
|
|
5271
|
+
// violations are mapped onto the fields; the underlying `HttpErrorResponse` is thrown so
|
|
5272
|
+
// `extractFormViolations` can unwrap the 422 body.
|
|
5273
|
+
return firstValueFrom(query.state$.pipe(filter((state) => isQueryStateSuccess(state) || isQueryStateFailure(state)), take(1))).then((state) => {
|
|
5274
|
+
if (isQueryStateFailure(state)) {
|
|
5275
|
+
throw state.error.httpErrorResponse;
|
|
5276
|
+
}
|
|
5277
|
+
return state.response;
|
|
5278
|
+
});
|
|
5279
|
+
},
|
|
5280
|
+
}),
|
|
5281
|
+
});
|
|
5282
|
+
};
|
|
5283
|
+
|
|
5066
5284
|
const generateUuid = () => randomId();
|
|
5067
5285
|
const createQueryRepository = (config) => {
|
|
5068
5286
|
const cache = new Map();
|
|
@@ -5261,121 +5479,6 @@ const createPatchQuery = createQueryTemplate('PATCH');
|
|
|
5261
5479
|
/** A query creator that creates a secure PATCH query (requires authentication) */
|
|
5262
5480
|
const createSecurePatchQuery = createSecureQueryTemplate('PATCH');
|
|
5263
5481
|
|
|
5264
|
-
/** `kind` of a `ValidationError` created from a single server violation. */
|
|
5265
|
-
const SERVER_VIOLATION_ERROR_KIND = 'etServerViolation';
|
|
5266
|
-
/** `kind` of the form-level fallback error created when a failed request carries no violations. */
|
|
5267
|
-
const SERVER_ERROR_KIND = 'etServerError';
|
|
5268
|
-
/**
|
|
5269
|
-
* Extracts the violation list from a failed request in any of the shapes it may reach you:
|
|
5270
|
-
* a `QueryErrorResponse` (from `query.error()` or a settled snapshot), a raw `HttpErrorResponse`,
|
|
5271
|
-
* an already-unwrapped error body, or a plain violation array. Returns `[]` when the error
|
|
5272
|
-
* carries no violations.
|
|
5273
|
-
*/
|
|
5274
|
-
const extractFormViolations = (error) => {
|
|
5275
|
-
if (!error)
|
|
5276
|
-
return [];
|
|
5277
|
-
const body = isQueryErrorResponse(error) ? error.raw.error : error instanceof HttpErrorResponse ? error.error : error;
|
|
5278
|
-
if (isSymfonyFormViolationListError(body)) {
|
|
5279
|
-
return body.violations;
|
|
5280
|
-
}
|
|
5281
|
-
if (isSymfonyListError(body)) {
|
|
5282
|
-
return body;
|
|
5283
|
-
}
|
|
5284
|
-
return [];
|
|
5285
|
-
};
|
|
5286
|
-
/**
|
|
5287
|
-
* Maps a failed request's violations onto a signal-forms field tree as validation errors —
|
|
5288
|
-
* the bridge between an API's violation list (`@ethlete/types` `FormViolationView`) and
|
|
5289
|
-
* signal forms.
|
|
5290
|
-
*
|
|
5291
|
-
* Each violation's `propertyPath` (e.g. `items[2].name`) is resolved against `fieldTree`; a
|
|
5292
|
-
* resolved violation becomes a `ServerViolationValidationError` bound to that field, an
|
|
5293
|
-
* unresolved one becomes a form-level error (customizable via `onUnmappedViolation`). A failed
|
|
5294
|
-
* request that carries no violations at all degrades to form-level `ServerValidationError`s
|
|
5295
|
-
* built from the normalized error message — so returning this function's result from a
|
|
5296
|
-
* `submit()` action never silently succeeds on failure.
|
|
5297
|
-
*
|
|
5298
|
-
* ```ts
|
|
5299
|
-
* await submit(this.form, async (field) => {
|
|
5300
|
-
* const snapshot = await executeUntilSettled(this.createPost, { args: { body: field().value() } });
|
|
5301
|
-
* const error = snapshot.error();
|
|
5302
|
-
*
|
|
5303
|
-
* if (!error) return;
|
|
5304
|
-
*
|
|
5305
|
-
* return mapViolationsToFormErrors({ fieldTree: field, error });
|
|
5306
|
-
* });
|
|
5307
|
-
* ```
|
|
5308
|
-
*/
|
|
5309
|
-
const mapViolationsToFormErrors = (options) => {
|
|
5310
|
-
const { fieldTree, error, rewritePath, onUnmappedViolation } = options;
|
|
5311
|
-
if (error === null || error === undefined)
|
|
5312
|
-
return [];
|
|
5313
|
-
const violations = extractFormViolations(error);
|
|
5314
|
-
if (!violations.length) {
|
|
5315
|
-
// An empty violation array is an explicit "nothing to map" — only unrecognized error
|
|
5316
|
-
// shapes degrade to the form-level fallback.
|
|
5317
|
-
if (Array.isArray(error) && !error.length)
|
|
5318
|
-
return [];
|
|
5319
|
-
return createFallbackErrors(error);
|
|
5320
|
-
}
|
|
5321
|
-
const errors = [];
|
|
5322
|
-
for (const violation of violations) {
|
|
5323
|
-
const rawPath = violation.propertyPath;
|
|
5324
|
-
const path = rawPath && rewritePath ? rewritePath(rawPath, violation) : rawPath;
|
|
5325
|
-
const resolvedFieldTree = path ? resolveFieldTreePath(fieldTree, path) : null;
|
|
5326
|
-
if (resolvedFieldTree) {
|
|
5327
|
-
const mappedError = {
|
|
5328
|
-
kind: SERVER_VIOLATION_ERROR_KIND,
|
|
5329
|
-
message: violation.message,
|
|
5330
|
-
fieldTree: resolvedFieldTree,
|
|
5331
|
-
violation,
|
|
5332
|
-
};
|
|
5333
|
-
errors.push(mappedError);
|
|
5334
|
-
}
|
|
5335
|
-
else if (onUnmappedViolation) {
|
|
5336
|
-
const customError = onUnmappedViolation(violation);
|
|
5337
|
-
if (customError) {
|
|
5338
|
-
errors.push(customError);
|
|
5339
|
-
}
|
|
5340
|
-
}
|
|
5341
|
-
else {
|
|
5342
|
-
const unmappedError = {
|
|
5343
|
-
kind: SERVER_VIOLATION_ERROR_KIND,
|
|
5344
|
-
message: violation.message,
|
|
5345
|
-
violation,
|
|
5346
|
-
};
|
|
5347
|
-
errors.push(unmappedError);
|
|
5348
|
-
}
|
|
5349
|
-
}
|
|
5350
|
-
return errors;
|
|
5351
|
-
};
|
|
5352
|
-
const createFallbackErrors = (error) => {
|
|
5353
|
-
const queryError = isQueryErrorResponse(error) ? error : createQueryErrorResponse(error);
|
|
5354
|
-
if (queryError.isList) {
|
|
5355
|
-
return queryError.errors.map((item) => ({ kind: SERVER_ERROR_KIND, message: item.message }));
|
|
5356
|
-
}
|
|
5357
|
-
return [{ kind: SERVER_ERROR_KIND, message: queryError.error.message }];
|
|
5358
|
-
};
|
|
5359
|
-
/** Splits a property path like `items[2].name` or `translations['de'].title` into its segments. */
|
|
5360
|
-
const parsePropertyPath = (path) => {
|
|
5361
|
-
return path
|
|
5362
|
-
.replace(/\[(['"]?)([^\]]*?)\1\]/g, '.$2')
|
|
5363
|
-
.split('.')
|
|
5364
|
-
.filter((segment) => segment.length > 0);
|
|
5365
|
-
};
|
|
5366
|
-
const resolveFieldTreePath = (fieldTree, path) => {
|
|
5367
|
-
let current = fieldTree;
|
|
5368
|
-
for (const segment of parsePropertyPath(path)) {
|
|
5369
|
-
if (current === null || (typeof current !== 'object' && typeof current !== 'function')) {
|
|
5370
|
-
return null;
|
|
5371
|
-
}
|
|
5372
|
-
current = current[segment];
|
|
5373
|
-
}
|
|
5374
|
-
// A field tree node is callable (calling it returns the field state) — anything else means the
|
|
5375
|
-
// path left the tree (e.g. an index past the array's current length).
|
|
5376
|
-
return typeof current === 'function' ? current : null;
|
|
5377
|
-
};
|
|
5378
|
-
|
|
5379
5482
|
/**
|
|
5380
5483
|
* Executes the query and resolves once that execution has settled (response or error received).
|
|
5381
5484
|
* The returned snapshot is frozen to the awaited execution, so a later execution can't swap the
|
|
@@ -5394,6 +5497,143 @@ const executeUntilSettled = async (query, executeArgs) => {
|
|
|
5394
5497
|
return snapshot;
|
|
5395
5498
|
};
|
|
5396
5499
|
|
|
5500
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5501
|
+
const createSequenceState = () => ({
|
|
5502
|
+
status: signal('idle'),
|
|
5503
|
+
running: signal(false),
|
|
5504
|
+
currentStep: signal(0),
|
|
5505
|
+
error: signal(null),
|
|
5506
|
+
failedAt: signal(null),
|
|
5507
|
+
snapshots: signal([]),
|
|
5508
|
+
responses: signal([]),
|
|
5509
|
+
});
|
|
5510
|
+
const buildSequence = (steps, state) => {
|
|
5511
|
+
const run = async () => {
|
|
5512
|
+
if (state.running())
|
|
5513
|
+
throw querySequenceAlreadyRunning();
|
|
5514
|
+
state.status.set('running');
|
|
5515
|
+
state.running.set(true);
|
|
5516
|
+
state.currentStep.set(0);
|
|
5517
|
+
state.error.set(null);
|
|
5518
|
+
state.failedAt.set(null);
|
|
5519
|
+
state.snapshots.set([]);
|
|
5520
|
+
state.responses.set([]);
|
|
5521
|
+
const snapshots = [];
|
|
5522
|
+
const responses = [];
|
|
5523
|
+
let previousResponse = undefined;
|
|
5524
|
+
for (const [i, step] of steps.entries()) {
|
|
5525
|
+
state.currentStep.set(i + 1);
|
|
5526
|
+
const { args } = step.produceArgs(previousResponse, responses);
|
|
5527
|
+
const snapshot = await executeUntilSettled(step.query, { args });
|
|
5528
|
+
snapshots.push(snapshot);
|
|
5529
|
+
state.snapshots.set([...snapshots]);
|
|
5530
|
+
const error = snapshot.error();
|
|
5531
|
+
if (error) {
|
|
5532
|
+
state.status.set('error');
|
|
5533
|
+
state.error.set(error);
|
|
5534
|
+
state.failedAt.set(i);
|
|
5535
|
+
state.running.set(false);
|
|
5536
|
+
return { ok: false, failedAt: i, error, snapshots };
|
|
5537
|
+
}
|
|
5538
|
+
const response = snapshot.response();
|
|
5539
|
+
responses.push(response);
|
|
5540
|
+
state.responses.set([...responses]);
|
|
5541
|
+
previousResponse = response;
|
|
5542
|
+
}
|
|
5543
|
+
state.status.set('success');
|
|
5544
|
+
state.running.set(false);
|
|
5545
|
+
return { ok: true, responses: responses, snapshots };
|
|
5546
|
+
};
|
|
5547
|
+
return {
|
|
5548
|
+
then: (query, mapArgs) => buildSequence([
|
|
5549
|
+
...steps,
|
|
5550
|
+
{ query, produceArgs: (previousResponse, responses) => mapArgs(previousResponse, responses) },
|
|
5551
|
+
], state),
|
|
5552
|
+
status: state.status.asReadonly(),
|
|
5553
|
+
running: state.running.asReadonly(),
|
|
5554
|
+
currentStep: state.currentStep.asReadonly(),
|
|
5555
|
+
total: steps.length,
|
|
5556
|
+
error: state.error.asReadonly(),
|
|
5557
|
+
failedAt: state.failedAt.asReadonly(),
|
|
5558
|
+
snapshots: state.snapshots.asReadonly(),
|
|
5559
|
+
responses: state.responses.asReadonly(),
|
|
5560
|
+
run,
|
|
5561
|
+
};
|
|
5562
|
+
};
|
|
5563
|
+
/**
|
|
5564
|
+
* Starts an imperative waterfall of dependent queries. Chain the remaining steps with `.then()`
|
|
5565
|
+
* and trigger it with `.run()` — see {@link QuerySequence}.
|
|
5566
|
+
*
|
|
5567
|
+
* The seed step's `args` are produced lazily (at `run()` time), so the sequence can safely live as
|
|
5568
|
+
* a component field while still reading current signal values on each run.
|
|
5569
|
+
*
|
|
5570
|
+
* @example
|
|
5571
|
+
* ```ts
|
|
5572
|
+
* readonly checkout = querySequence(this.createOrder, () => ({ args: { body: this.order() } }))
|
|
5573
|
+
* .then(this.createPayment, (order) => ({ args: { body: { orderId: order.id } } }))
|
|
5574
|
+
* .then(this.confirmOrder, (payment, [order]) => ({
|
|
5575
|
+
* args: { pathParams: { paymentId: payment.id }, body: { orderRef: order.id } },
|
|
5576
|
+
* }));
|
|
5577
|
+
*
|
|
5578
|
+
* async submit() {
|
|
5579
|
+
* const result = await this.checkout.run();
|
|
5580
|
+
* if (!result.ok) return this.handle(result.error);
|
|
5581
|
+
* const [order, payment, confirmation] = result.responses;
|
|
5582
|
+
* }
|
|
5583
|
+
* ```
|
|
5584
|
+
*/
|
|
5585
|
+
const querySequence = (query, seedArgs) => buildSequence([{ query, produceArgs: () => seedArgs() }], createSequenceState());
|
|
5586
|
+
|
|
5587
|
+
/**
|
|
5588
|
+
* Binds a query-backed async validator to a signal-forms field, adapting an `@ethlete/query` v3
|
|
5589
|
+
* query into what `validateAsync` consumes. The query runs through the query client — so bearer
|
|
5590
|
+
* auth, base route, caching and Symfony error normalization all apply — where a raw `httpResource`
|
|
5591
|
+
* would fire unauthenticated and bypass the pipeline.
|
|
5592
|
+
*
|
|
5593
|
+
* On the current v3 `QueryClient` / `createPostQuery` creators; the `validateWithV2Query` twin
|
|
5594
|
+
* covers the legacy `V2QueryClient`. The query is created once and re-executed (debounced) as the
|
|
5595
|
+
* field value changes, only after the field's synchronous validators pass. A `204` / successful
|
|
5596
|
+
* response reports no errors; a `422 FormViolationListView` maps each violation onto its child
|
|
5597
|
+
* field by `propertyPath`; a network / other error degrades to a non-swallowed form-level error.
|
|
5598
|
+
*
|
|
5599
|
+
* Call it from a schema definition, the same place you'd call `validateAsync`:
|
|
5600
|
+
*
|
|
5601
|
+
* ```ts
|
|
5602
|
+
* const schema = schema<OpportunityEmail>((p) => {
|
|
5603
|
+
* validateWithQuery(p, {
|
|
5604
|
+
* queryCreator: postOpportunityEmailValidate,
|
|
5605
|
+
* args: (ctx) => ({ pathParams: { opportunityId }, body: { ...ctx.value() } }),
|
|
5606
|
+
* });
|
|
5607
|
+
* });
|
|
5608
|
+
* ```
|
|
5609
|
+
*/
|
|
5610
|
+
const validateWithQuery = (path, config) => {
|
|
5611
|
+
applyQueryAsyncValidator(path, {
|
|
5612
|
+
params: config.args,
|
|
5613
|
+
debounce: config.debounce,
|
|
5614
|
+
when: config.when,
|
|
5615
|
+
mapViolations: config.mapViolations,
|
|
5616
|
+
factory: (params) => {
|
|
5617
|
+
// Created once, exactly like a query stack. A POST validate route doesn't auto-execute, so
|
|
5618
|
+
// the resource loader drives it — each params change re-executes with the new args.
|
|
5619
|
+
const query = config.queryCreator();
|
|
5620
|
+
return resource({
|
|
5621
|
+
params: () => params(),
|
|
5622
|
+
loader: async ({ params: requestArgs }) => {
|
|
5623
|
+
const snapshot = await executeUntilSettled(query, { args: requestArgs });
|
|
5624
|
+
const error = snapshot.error();
|
|
5625
|
+
// A failed request (e.g. 422) is thrown so it lands in `onError`, where the violations are
|
|
5626
|
+
// mapped onto the fields. A `204` / success settles with no error and no violations.
|
|
5627
|
+
if (error) {
|
|
5628
|
+
throw error;
|
|
5629
|
+
}
|
|
5630
|
+
return snapshot.response() ?? undefined;
|
|
5631
|
+
},
|
|
5632
|
+
});
|
|
5633
|
+
},
|
|
5634
|
+
});
|
|
5635
|
+
};
|
|
5636
|
+
|
|
5397
5637
|
const setupLeaderElection = () => {
|
|
5398
5638
|
const destroyRef = inject(DestroyRef);
|
|
5399
5639
|
const channelName = 'ethlete-auth-leader';
|
|
@@ -6671,10 +6911,10 @@ class ParseHttpErrorCodeToTitleDePipe {
|
|
|
6671
6911
|
constructor() {
|
|
6672
6912
|
this.transform = parseHttpErrorCodeToTitleDe;
|
|
6673
6913
|
}
|
|
6674
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
6675
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.
|
|
6914
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
6915
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, isStandalone: true, name: "parseHttpErrorCodeToTitleDe" }); }
|
|
6676
6916
|
}
|
|
6677
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
6917
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, decorators: [{
|
|
6678
6918
|
type: Pipe,
|
|
6679
6919
|
args: [{
|
|
6680
6920
|
name: 'parseHttpErrorCodeToTitleDe',
|
|
@@ -6684,10 +6924,10 @@ class ParseHttpErrorCodeToMessageDePipe {
|
|
|
6684
6924
|
constructor() {
|
|
6685
6925
|
this.transform = parseHttpErrorCodeToMessageDe;
|
|
6686
6926
|
}
|
|
6687
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
6688
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.
|
|
6927
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
6928
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, isStandalone: true, name: "parseHttpErrorCodeToMessageDe" }); }
|
|
6689
6929
|
}
|
|
6690
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
6930
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, decorators: [{
|
|
6691
6931
|
type: Pipe,
|
|
6692
6932
|
args: [{
|
|
6693
6933
|
name: 'parseHttpErrorCodeToMessageDe',
|
|
@@ -6871,10 +7111,10 @@ class ParseHttpErrorCodeToTitleEnPipe {
|
|
|
6871
7111
|
constructor() {
|
|
6872
7112
|
this.transform = parseHttpErrorCodeToTitleEn;
|
|
6873
7113
|
}
|
|
6874
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
6875
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.
|
|
7114
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
7115
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, isStandalone: true, name: "parseHttpErrorCodeToTitleEn" }); }
|
|
6876
7116
|
}
|
|
6877
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
7117
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, decorators: [{
|
|
6878
7118
|
type: Pipe,
|
|
6879
7119
|
args: [{
|
|
6880
7120
|
name: 'parseHttpErrorCodeToTitleEn',
|
|
@@ -6884,10 +7124,10 @@ class ParseHttpErrorCodeToMessageEnPipe {
|
|
|
6884
7124
|
constructor() {
|
|
6885
7125
|
this.transform = parseHttpErrorCodeToMessageEn;
|
|
6886
7126
|
}
|
|
6887
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
6888
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.
|
|
7127
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
7128
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, isStandalone: true, name: "parseHttpErrorCodeToMessageEn" }); }
|
|
6889
7129
|
}
|
|
6890
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
7130
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, decorators: [{
|
|
6891
7131
|
type: Pipe,
|
|
6892
7132
|
args: [{
|
|
6893
7133
|
name: 'parseHttpErrorCodeToMessageEn',
|
|
@@ -7657,5 +7897,5 @@ const createWebSocketClient = (options) => {
|
|
|
7657
7897
|
* Generated bundle index. Do not edit.
|
|
7658
7898
|
*/
|
|
7659
7899
|
|
|
7660
|
-
export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DateArrayQueryField, DateQueryField, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createInfinityQueryConfig, createLegacyQueryCreator, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryErrorResponse, createQueryFeature, createQueryObject, createQueryRepository, createQuerySnapshotFn, createQueryStack, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, decryptBearer, deepFreeze, def, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isLegacyQuery, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mapViolationsToFormErrors, maybeExecute, mergeHeaders, nestedEffect, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryExecute, queryFeatureUsedMultipleTimes, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetExecuteState, resetPageOnError, serializeBody, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, splitQueryConfig, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
|
|
7900
|
+
export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DateArrayQueryField, DateQueryField, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createInfinityQueryConfig, createLegacyQueryCreator, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryErrorResponse, createQueryFeature, createQueryObject, createQueryRepository, createQuerySnapshotFn, createQueryStack, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, decryptBearer, deepFreeze, def, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isLegacyQuery, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mapViolationsToFormErrors, maybeExecute, mergeHeaders, nestedEffect, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryExecute, queryFeatureUsedMultipleTimes, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetExecuteState, resetPageOnError, serializeBody, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, splitQueryConfig, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
|
|
7661
7901
|
//# sourceMappingURL=ethlete-query.mjs.map
|