@ethlete/query 6.0.0-next.15 → 6.0.0-next.17
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 +20 -0
- package/fesm2022/ethlete-query.mjs +285 -3
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/package.json +1 -2
- package/types/ethlete-query.d.ts +196 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @ethlete/query
|
|
2
2
|
|
|
3
|
+
## 6.0.0-next.17
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#3030](https://github.com/ethlete-io/ethdk/pull/3030) [`47e4109`](https://github.com/ethlete-io/ethdk/commit/47e41097adf96788120840bdd03cad25306628f2) Thanks [@github-actions](https://github.com/apps/github-actions)! - Add `validateWithQuery` (v3) and `validateWithV2Query` (v2) — query-backed async
|
|
8
|
+
validators for Angular signal forms. They adapt an `@ethlete/query` query into
|
|
9
|
+
`validateAsync`, so server-side validation runs through the query client (auth,
|
|
10
|
+
base route, caching, error normalization) instead of a raw `httpResource`. A
|
|
11
|
+
`422 FormViolationListView` maps each violation onto its child field by
|
|
12
|
+
`propertyPath` (via `mapViolationsToFormErrors`); success reports no errors and
|
|
13
|
+
network/other errors surface as a form-level error.
|
|
14
|
+
|
|
15
|
+
## 6.0.0-next.16
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [`a41491d`](https://github.com/ethlete-io/ethdk/commit/a41491db447152e69902020d19bfc30bccf3b01d) Thanks [@TomTomB](https://github.com/TomTomB)! - Server violations → signal-forms bridge:
|
|
20
|
+
- `@ethlete/query`: `mapViolationsToFormErrors({ fieldTree, error, rewritePath?, onUnmappedViolation? })` maps an API error's violation list onto a signal form's fields (unmapped violations become form-level errors, violation-free failures degrade to a form-level `etServerError`), plus `extractFormViolations(error)`, `executeUntilSettled(query, executeArgs?)` for awaiting one execution as a settled snapshot, and the `isQueryErrorResponse` guard.
|
|
21
|
+
- `@ethlete/components`: `provideFormErrorMessageResolver(resolver)` lets apps centralize/localize the text `et-form-error` renders by error `kind`; the error's own `message` stays the default.
|
|
22
|
+
|
|
3
23
|
## 6.0.0-next.15
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -1,13 +1,14 @@
|
|
|
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
|
-
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, merge, throttleTime } from 'rxjs';
|
|
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';
|
|
6
6
|
import { HttpClient, HttpEventType, HttpErrorResponse, HttpHeaders, HttpStatusCode } from '@angular/common/http';
|
|
7
7
|
import { getActiveConsumer, setActiveConsumer } from '@angular/core/primitives/signals';
|
|
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
|
|
|
@@ -1492,6 +1493,9 @@ const shouldRetryRequest = (options) => {
|
|
|
1492
1493
|
return { retry: false };
|
|
1493
1494
|
};
|
|
1494
1495
|
|
|
1496
|
+
const isQueryErrorResponse = (error) => {
|
|
1497
|
+
return typeof error === 'object' && error !== null && 'raw' in error && 'retryState' in error && 'isList' in error;
|
|
1498
|
+
};
|
|
1495
1499
|
const createQueryErrorResponse = (error) => {
|
|
1496
1500
|
let err = error instanceof HttpErrorResponse ? error : null;
|
|
1497
1501
|
if (!err) {
|
|
@@ -5060,6 +5064,216 @@ const removeFrom = (store, { where, id }) => {
|
|
|
5060
5064
|
.subscribe();
|
|
5061
5065
|
};
|
|
5062
5066
|
|
|
5067
|
+
/** `kind` of a `ValidationError` created from a single server violation. */
|
|
5068
|
+
const SERVER_VIOLATION_ERROR_KIND = 'etServerViolation';
|
|
5069
|
+
/** `kind` of the form-level fallback error created when a failed request carries no violations. */
|
|
5070
|
+
const SERVER_ERROR_KIND = 'etServerError';
|
|
5071
|
+
/**
|
|
5072
|
+
* Extracts the violation list from a failed request in any of the shapes it may reach you:
|
|
5073
|
+
* a `QueryErrorResponse` (from `query.error()` or a settled snapshot), a raw `HttpErrorResponse`,
|
|
5074
|
+
* an already-unwrapped error body, or a plain violation array. Returns `[]` when the error
|
|
5075
|
+
* carries no violations.
|
|
5076
|
+
*/
|
|
5077
|
+
const extractFormViolations = (error) => {
|
|
5078
|
+
if (!error)
|
|
5079
|
+
return [];
|
|
5080
|
+
const body = isQueryErrorResponse(error) ? error.raw.error : error instanceof HttpErrorResponse ? error.error : error;
|
|
5081
|
+
if (isSymfonyFormViolationListError(body)) {
|
|
5082
|
+
return body.violations;
|
|
5083
|
+
}
|
|
5084
|
+
if (isSymfonyListError(body)) {
|
|
5085
|
+
return body;
|
|
5086
|
+
}
|
|
5087
|
+
return [];
|
|
5088
|
+
};
|
|
5089
|
+
/**
|
|
5090
|
+
* Maps a failed request's violations onto a signal-forms field tree as validation errors —
|
|
5091
|
+
* the bridge between an API's violation list (`@ethlete/types` `FormViolationView`) and
|
|
5092
|
+
* signal forms.
|
|
5093
|
+
*
|
|
5094
|
+
* Each violation's `propertyPath` (e.g. `items[2].name`) is resolved against `fieldTree`; a
|
|
5095
|
+
* resolved violation becomes a `ServerViolationValidationError` bound to that field, an
|
|
5096
|
+
* unresolved one becomes a form-level error (customizable via `onUnmappedViolation`). A failed
|
|
5097
|
+
* request that carries no violations at all degrades to form-level `ServerValidationError`s
|
|
5098
|
+
* built from the normalized error message — so returning this function's result from a
|
|
5099
|
+
* `submit()` action never silently succeeds on failure.
|
|
5100
|
+
*
|
|
5101
|
+
* ```ts
|
|
5102
|
+
* await submit(this.form, async (field) => {
|
|
5103
|
+
* const snapshot = await executeUntilSettled(this.createPost, { args: { body: field().value() } });
|
|
5104
|
+
* const error = snapshot.error();
|
|
5105
|
+
*
|
|
5106
|
+
* if (!error) return;
|
|
5107
|
+
*
|
|
5108
|
+
* return mapViolationsToFormErrors({ fieldTree: field, error });
|
|
5109
|
+
* });
|
|
5110
|
+
* ```
|
|
5111
|
+
*/
|
|
5112
|
+
const mapViolationsToFormErrors = (options) => {
|
|
5113
|
+
const { fieldTree, error, rewritePath, onUnmappedViolation } = options;
|
|
5114
|
+
if (error === null || error === undefined)
|
|
5115
|
+
return [];
|
|
5116
|
+
const violations = extractFormViolations(error);
|
|
5117
|
+
if (!violations.length) {
|
|
5118
|
+
// An empty violation array is an explicit "nothing to map" — only unrecognized error
|
|
5119
|
+
// shapes degrade to the form-level fallback.
|
|
5120
|
+
if (Array.isArray(error) && !error.length)
|
|
5121
|
+
return [];
|
|
5122
|
+
return createFallbackErrors(error);
|
|
5123
|
+
}
|
|
5124
|
+
const errors = [];
|
|
5125
|
+
for (const violation of violations) {
|
|
5126
|
+
const rawPath = violation.propertyPath;
|
|
5127
|
+
const path = rawPath && rewritePath ? rewritePath(rawPath, violation) : rawPath;
|
|
5128
|
+
const resolvedFieldTree = path ? resolveFieldTreePath(fieldTree, path) : null;
|
|
5129
|
+
if (resolvedFieldTree) {
|
|
5130
|
+
const mappedError = {
|
|
5131
|
+
kind: SERVER_VIOLATION_ERROR_KIND,
|
|
5132
|
+
message: violation.message,
|
|
5133
|
+
fieldTree: resolvedFieldTree,
|
|
5134
|
+
violation,
|
|
5135
|
+
};
|
|
5136
|
+
errors.push(mappedError);
|
|
5137
|
+
}
|
|
5138
|
+
else if (onUnmappedViolation) {
|
|
5139
|
+
const customError = onUnmappedViolation(violation);
|
|
5140
|
+
if (customError) {
|
|
5141
|
+
errors.push(customError);
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
else {
|
|
5145
|
+
const unmappedError = {
|
|
5146
|
+
kind: SERVER_VIOLATION_ERROR_KIND,
|
|
5147
|
+
message: violation.message,
|
|
5148
|
+
violation,
|
|
5149
|
+
};
|
|
5150
|
+
errors.push(unmappedError);
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5153
|
+
return errors;
|
|
5154
|
+
};
|
|
5155
|
+
const createFallbackErrors = (error) => {
|
|
5156
|
+
const queryError = isQueryErrorResponse(error) ? error : createQueryErrorResponse(error);
|
|
5157
|
+
if (queryError.isList) {
|
|
5158
|
+
return queryError.errors.map((item) => ({ kind: SERVER_ERROR_KIND, message: item.message }));
|
|
5159
|
+
}
|
|
5160
|
+
return [{ kind: SERVER_ERROR_KIND, message: queryError.error.message }];
|
|
5161
|
+
};
|
|
5162
|
+
/** Splits a property path like `items[2].name` or `translations['de'].title` into its segments. */
|
|
5163
|
+
const parsePropertyPath = (path) => {
|
|
5164
|
+
return path
|
|
5165
|
+
.replace(/\[(['"]?)([^\]]*?)\1\]/g, '.$2')
|
|
5166
|
+
.split('.')
|
|
5167
|
+
.filter((segment) => segment.length > 0);
|
|
5168
|
+
};
|
|
5169
|
+
const resolveFieldTreePath = (fieldTree, path) => {
|
|
5170
|
+
let current = fieldTree;
|
|
5171
|
+
for (const segment of parsePropertyPath(path)) {
|
|
5172
|
+
if (current === null || (typeof current !== 'object' && typeof current !== 'function')) {
|
|
5173
|
+
return null;
|
|
5174
|
+
}
|
|
5175
|
+
current = current[segment];
|
|
5176
|
+
}
|
|
5177
|
+
// A field tree node is callable (calling it returns the field state) — anything else means the
|
|
5178
|
+
// path left the tree (e.g. an index past the array's current length).
|
|
5179
|
+
return typeof current === 'function' ? current : null;
|
|
5180
|
+
};
|
|
5181
|
+
|
|
5182
|
+
// Shared core for the query-backed async validators (`validateWithQuery` /
|
|
5183
|
+
// `validateWithV2Query`). Everything except how the query is executed — the `factory` that turns
|
|
5184
|
+
// the debounced params into a `Resource` — is identical between the v2 and v3 variants, so it is
|
|
5185
|
+
// factored here and imported by both. This module is intentionally NOT part of the `http` barrel;
|
|
5186
|
+
// it is internal plumbing consumed by direct path (the legacy variant already imports from `http`).
|
|
5187
|
+
/** Default debounce (ms) applied before a validate request runs, mirroring `selectOptionsFrom*Query`. */
|
|
5188
|
+
const DEFAULT_QUERY_VALIDATION_DEBOUNCE = 300;
|
|
5189
|
+
/**
|
|
5190
|
+
* Turns a failed validate request into field errors — the default `onError` mapping shared by both
|
|
5191
|
+
* validators. Reuses the existing `mapViolationsToFormErrors` bridge: a `422` violation list is
|
|
5192
|
+
* resolved onto the child fields by `propertyPath`, while a network / non-violation error degrades
|
|
5193
|
+
* to a non-swallowed form-level error. A caller-supplied `mapViolations` overrides only the
|
|
5194
|
+
* violation → error step (it receives the already-extracted violations).
|
|
5195
|
+
*/
|
|
5196
|
+
const mapQueryValidationError = (error, ctx, mapViolations) => {
|
|
5197
|
+
// Angular's `resource()` wraps a thrown non-`Error` (our `QueryErrorResponse` / `HttpErrorResponse`)
|
|
5198
|
+
// into an `Error` and stashes the original on `.cause`, so unwrap it before extraction.
|
|
5199
|
+
const cause = error instanceof Error && error.cause !== undefined ? error.cause : error;
|
|
5200
|
+
if (mapViolations) {
|
|
5201
|
+
return mapViolations(extractFormViolations(cause), ctx);
|
|
5202
|
+
}
|
|
5203
|
+
// `ctx.fieldTree` is the (read-only) tree of the validated field; `propertyPath`s resolve against
|
|
5204
|
+
// it. The cast bridges `ReadonlyFieldTree` → `FieldTree` — `mapViolationsToFormErrors` only walks
|
|
5205
|
+
// and reads the tree, never mutates it.
|
|
5206
|
+
return mapViolationsToFormErrors({ fieldTree: ctx.fieldTree, error: cause });
|
|
5207
|
+
};
|
|
5208
|
+
/**
|
|
5209
|
+
* Binds a query-backed async validator to `path` via `validateAsync`. Success (`204` / any `2xx`
|
|
5210
|
+
* with no violation body) reports no errors; a failed request is mapped by
|
|
5211
|
+
* {@link mapQueryValidationError}. Async validation only runs once the field's synchronous
|
|
5212
|
+
* validators pass and while `when` holds — signal forms feeds the `factory` `undefined` params when
|
|
5213
|
+
* the request shouldn't run, so the resource stays idle.
|
|
5214
|
+
*/
|
|
5215
|
+
const applyQueryAsyncValidator = (path, config) => {
|
|
5216
|
+
validateAsync(path, {
|
|
5217
|
+
params: config.params,
|
|
5218
|
+
debounce: config.debounce ?? DEFAULT_QUERY_VALIDATION_DEBOUNCE,
|
|
5219
|
+
factory: config.factory,
|
|
5220
|
+
when: config.when,
|
|
5221
|
+
onSuccess: () => null,
|
|
5222
|
+
onError: (error, ctx) => mapQueryValidationError(error, ctx, config.mapViolations),
|
|
5223
|
+
});
|
|
5224
|
+
};
|
|
5225
|
+
|
|
5226
|
+
/**
|
|
5227
|
+
* Binds a query-backed async validator to a signal-forms field, adapting a **legacy v2**
|
|
5228
|
+
* `@ethlete/query` query into what `validateAsync` consumes — the `V2QueryClient` counterpart of
|
|
5229
|
+
* {@link validateWithQuery}, so apps that haven't migrated yet can still validate against the
|
|
5230
|
+
* server. The query runs through the client (bearer auth, base route, caching, Symfony error
|
|
5231
|
+
* normalization), where a raw `httpResource` would fire unauthenticated and bypass the pipeline.
|
|
5232
|
+
*
|
|
5233
|
+
* The query is prepared and executed (debounced) as the field value changes, only after the
|
|
5234
|
+
* field's synchronous validators pass. A `204` / successful response reports no errors; a
|
|
5235
|
+
* `422 FormViolationListView` maps each violation onto its child field by `propertyPath`; a
|
|
5236
|
+
* network / other error degrades to a non-swallowed form-level error.
|
|
5237
|
+
*
|
|
5238
|
+
* Call it from a schema definition, the same place you'd call `validateAsync`:
|
|
5239
|
+
*
|
|
5240
|
+
* ```ts
|
|
5241
|
+
* const schema = schema<OpportunityEmail>((p) => {
|
|
5242
|
+
* validateWithV2Query(p, {
|
|
5243
|
+
* queryCreator: postOpportunityEmailValidate, // hubApiClient.post({ ... })
|
|
5244
|
+
* args: (ctx) => ({ pathParams: { opportunityId }, body: { ...ctx.value() } }),
|
|
5245
|
+
* });
|
|
5246
|
+
* });
|
|
5247
|
+
* ```
|
|
5248
|
+
*/
|
|
5249
|
+
const validateWithV2Query = (path, config) => {
|
|
5250
|
+
applyQueryAsyncValidator(path, {
|
|
5251
|
+
params: config.args,
|
|
5252
|
+
debounce: config.debounce,
|
|
5253
|
+
when: config.when,
|
|
5254
|
+
mapViolations: config.mapViolations,
|
|
5255
|
+
factory: (params) => resource({
|
|
5256
|
+
params: () => params(),
|
|
5257
|
+
loader: ({ params: prepareArgs, abortSignal }) => {
|
|
5258
|
+
// Prepared per request — v2 caches by the prepared args, so a fresh `prepare()` is the
|
|
5259
|
+
// legacy idiom (the sibling `selectOptionsFromV2Query` does the same via `queryComputed`).
|
|
5260
|
+
const query = config.queryCreator.prepare(prepareArgs);
|
|
5261
|
+
abortSignal.addEventListener('abort', () => query.abort());
|
|
5262
|
+
query.execute();
|
|
5263
|
+
// Resolve once the query settles. A failure is thrown so it lands in `onError`, where the
|
|
5264
|
+
// violations are mapped onto the fields; the underlying `HttpErrorResponse` is thrown so
|
|
5265
|
+
// `extractFormViolations` can unwrap the 422 body.
|
|
5266
|
+
return firstValueFrom(query.state$.pipe(filter((state) => isQueryStateSuccess(state) || isQueryStateFailure(state)), take(1))).then((state) => {
|
|
5267
|
+
if (isQueryStateFailure(state)) {
|
|
5268
|
+
throw state.error.httpErrorResponse;
|
|
5269
|
+
}
|
|
5270
|
+
return state.response;
|
|
5271
|
+
});
|
|
5272
|
+
},
|
|
5273
|
+
}),
|
|
5274
|
+
});
|
|
5275
|
+
};
|
|
5276
|
+
|
|
5063
5277
|
const generateUuid = () => randomId();
|
|
5064
5278
|
const createQueryRepository = (config) => {
|
|
5065
5279
|
const cache = new Map();
|
|
@@ -5258,6 +5472,74 @@ const createPatchQuery = createQueryTemplate('PATCH');
|
|
|
5258
5472
|
/** A query creator that creates a secure PATCH query (requires authentication) */
|
|
5259
5473
|
const createSecurePatchQuery = createSecureQueryTemplate('PATCH');
|
|
5260
5474
|
|
|
5475
|
+
/**
|
|
5476
|
+
* Executes the query and resolves once that execution has settled (response or error received).
|
|
5477
|
+
* The returned snapshot is frozen to the awaited execution, so a later execution can't swap the
|
|
5478
|
+
* `response()` / `error()` you read from it.
|
|
5479
|
+
*
|
|
5480
|
+
* Designed for imperative flows that need a mutation's outcome in place — e.g. a signal-forms
|
|
5481
|
+
* `submit()` action mapping server violations onto the form via `mapViolationsToFormErrors`.
|
|
5482
|
+
*
|
|
5483
|
+
* The promise stays pending if the execution is cancelled (e.g. `reset()`) and the query is never
|
|
5484
|
+
* executed again — the snapshot settles with whichever execution completes next.
|
|
5485
|
+
*/
|
|
5486
|
+
const executeUntilSettled = async (query, executeArgs) => {
|
|
5487
|
+
query.execute(executeArgs);
|
|
5488
|
+
const snapshot = query.createSnapshot();
|
|
5489
|
+
await firstValueFrom(snapshot.isAlive.asObservable().pipe(filter((isAlive) => !isAlive)));
|
|
5490
|
+
return snapshot;
|
|
5491
|
+
};
|
|
5492
|
+
|
|
5493
|
+
/**
|
|
5494
|
+
* Binds a query-backed async validator to a signal-forms field, adapting an `@ethlete/query` v3
|
|
5495
|
+
* query into what `validateAsync` consumes. The query runs through the query client — so bearer
|
|
5496
|
+
* auth, base route, caching and Symfony error normalization all apply — where a raw `httpResource`
|
|
5497
|
+
* would fire unauthenticated and bypass the pipeline.
|
|
5498
|
+
*
|
|
5499
|
+
* On the current v3 `QueryClient` / `createPostQuery` creators; the `validateWithV2Query` twin
|
|
5500
|
+
* covers the legacy `V2QueryClient`. The query is created once and re-executed (debounced) as the
|
|
5501
|
+
* field value changes, only after the field's synchronous validators pass. A `204` / successful
|
|
5502
|
+
* response reports no errors; a `422 FormViolationListView` maps each violation onto its child
|
|
5503
|
+
* field by `propertyPath`; a network / other error degrades to a non-swallowed form-level error.
|
|
5504
|
+
*
|
|
5505
|
+
* Call it from a schema definition, the same place you'd call `validateAsync`:
|
|
5506
|
+
*
|
|
5507
|
+
* ```ts
|
|
5508
|
+
* const schema = schema<OpportunityEmail>((p) => {
|
|
5509
|
+
* validateWithQuery(p, {
|
|
5510
|
+
* queryCreator: postOpportunityEmailValidate,
|
|
5511
|
+
* args: (ctx) => ({ pathParams: { opportunityId }, body: { ...ctx.value() } }),
|
|
5512
|
+
* });
|
|
5513
|
+
* });
|
|
5514
|
+
* ```
|
|
5515
|
+
*/
|
|
5516
|
+
const validateWithQuery = (path, config) => {
|
|
5517
|
+
applyQueryAsyncValidator(path, {
|
|
5518
|
+
params: config.args,
|
|
5519
|
+
debounce: config.debounce,
|
|
5520
|
+
when: config.when,
|
|
5521
|
+
mapViolations: config.mapViolations,
|
|
5522
|
+
factory: (params) => {
|
|
5523
|
+
// Created once, exactly like a query stack. A POST validate route doesn't auto-execute, so
|
|
5524
|
+
// the resource loader drives it — each params change re-executes with the new args.
|
|
5525
|
+
const query = config.queryCreator();
|
|
5526
|
+
return resource({
|
|
5527
|
+
params: () => params(),
|
|
5528
|
+
loader: async ({ params: requestArgs }) => {
|
|
5529
|
+
const snapshot = await executeUntilSettled(query, { args: requestArgs });
|
|
5530
|
+
const error = snapshot.error();
|
|
5531
|
+
// A failed request (e.g. 422) is thrown so it lands in `onError`, where the violations are
|
|
5532
|
+
// mapped onto the fields. A `204` / success settles with no error and no violations.
|
|
5533
|
+
if (error) {
|
|
5534
|
+
throw error;
|
|
5535
|
+
}
|
|
5536
|
+
return snapshot.response() ?? undefined;
|
|
5537
|
+
},
|
|
5538
|
+
});
|
|
5539
|
+
},
|
|
5540
|
+
});
|
|
5541
|
+
};
|
|
5542
|
+
|
|
5261
5543
|
const setupLeaderElection = () => {
|
|
5262
5544
|
const destroyRef = inject(DestroyRef);
|
|
5263
5545
|
const channelName = 'ethlete-auth-leader';
|
|
@@ -7521,5 +7803,5 @@ const createWebSocketClient = (options) => {
|
|
|
7521
7803
|
* Generated bundle index. Do not edit.
|
|
7522
7804
|
*/
|
|
7523
7805
|
|
|
7524
|
-
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, 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, extractExpiresInSeconds, 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, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, 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 };
|
|
7806
|
+
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, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
|
|
7525
7807
|
//# sourceMappingURL=ethlete-query.mjs.map
|