@ethlete/query 6.0.0-next.17 → 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 +6 -0
- package/fesm2022/ethlete-query-testing.mjs.map +1 -1
- package/fesm2022/ethlete-query.mjs +135 -41
- 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 -8
- package/types/ethlete-query.d.ts +103 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ethlete/query
|
|
2
2
|
|
|
3
|
+
## 6.0.0-next.18
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`5685798`](https://github.com/ethlete-io/ethdk/commit/56857988a9fb579a791950cd85d015dfd36921a3) Thanks [@TomTomB](https://github.com/TomTomB)! - Add `querySequence` for imperative waterfalls of dependent queries — chain mutations with `.then()`, thread each response into the next, and `run()` to a typed, discriminated result that aborts on the first error. Exposes `status`/`running`/`currentStep`/`error` progress signals for driving UI.
|
|
8
|
+
|
|
3
9
|
## 6.0.0-next.17
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ethlete-query-testing.mjs","sources":["../../../../libs/query/testing/query-test-utils.ts","../../../../libs/query/testing/auth-test-utils.ts","../../../../libs/query/testing/query-test-setup.ts","../../../../libs/query/testing/ethlete-query-testing.ts"],"sourcesContent":["import { HttpTestingController } from '@angular/common/http/testing';\nimport { TestBed } from '@angular/core/testing';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const expectAndFlush = <T = unknown>(\n httpTesting: HttpTestingController,\n url: string,\n response: T,\n statusOpts?: { status: number; statusText: string },\n): void => {\n const req = httpTesting.expectOne(url);\n if (statusOpts) {\n req.flush(response as any, statusOpts);\n } else {\n req.flush(response as any);\n }\n};\n\nexport const expectFlushAndWait = <T = unknown>(\n httpTesting: HttpTestingController,\n url: string,\n response: T,\n statusOpts?: { status: number; statusText: string },\n): void => {\n expectAndFlush(httpTesting, url, response, statusOpts);\n TestBed.tick();\n};\n","import { DestroyRef } from '@angular/core';\nimport { TestBed } from '@angular/core/testing';\nimport {\n AnyQueryBuilder,\n AuthQueryBuilder,\n BearerAuthProvider,\n BearerAuthProviderFeatureContext,\n createBearerAuthProvider,\n TokenRefreshQueryBuilder,\n TokenRefreshQueryConfig,\n withAuthenticationQuery,\n withRefreshQuery,\n} from '@ethlete/query';\nimport { QueryTestSetup } from './query-test-setup';\nimport { expectFlushAndWait } from './query-test-utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFeatureBuilder = (context: BearerAuthProviderFeatureContext<any, readonly AnyQueryBuilder[]>) => {\n type: string;\n instance: unknown;\n};\n\nexport type AuthTestSetupConfig<\n TLoginArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TRefreshArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TFeatures extends readonly AnyFeatureBuilder[] = [],\n TBearerData = unknown,\n> = {\n /** The query test setup instance */\n querySetup: QueryTestSetup;\n /** Login endpoint path. Default: '/auth/login' */\n loginPath?: string;\n /** Refresh endpoint path. Default: '/auth/refresh' */\n refreshPath?: string;\n /** Whether to enable auto-retry on 401. Default: false */\n autoRetryOn401?: boolean;\n /** Function to extract tokens from login response */\n extractLoginTokens?: (response: TLoginArgs['response']) => { accessToken: string; refreshToken: string };\n /** Function to extract tokens from refresh response */\n extractRefreshTokens?: (response: TRefreshArgs['response']) => { accessToken: string; refreshToken: string };\n /** Feature builders for additional auth functionality */\n features?: [...TFeatures];\n /** Custom bearer decrypt function for testing */\n bearerDecryptFn?: (token: string) => TBearerData;\n /** Whether to disable multi-tab sync. Default: false */\n multiTabSync?:\n | false\n | { enabled?: boolean; channelName?: string; syncTokens?: boolean; syncLogout?: boolean; leaderElection?: boolean };\n /** Refresh strategy configuration. See TokenRefreshQueryConfig for details */\n refreshStrategy?: TokenRefreshQueryConfig<TRefreshArgs>['refreshStrategy'];\n /** Minimum refresh interval in milliseconds */\n minRefreshInterval?: number;\n /** Whether to refresh if token is already expired */\n refreshIfExpired?: boolean;\n /** Property name for expiration in JWT */\n expiresInPropertyName?: string;\n};\n\nexport type AuthTestSetup<\n TLoginArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TRefreshArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TFeatures extends readonly AnyFeatureBuilder[] = [],\n TBearerData = unknown,\n> = {\n /** The bearer auth provider instance */\n auth: BearerAuthProvider<\n [AuthQueryBuilder<'login', TLoginArgs>, TokenRefreshQueryBuilder<'refresh', TRefreshArgs>],\n TFeatures,\n TBearerData\n >;\n /** Helper to login a user and flush the HTTP request */\n login: (credentials: TLoginArgs['body'], response: TLoginArgs['response']) => void;\n /** Helper to trigger a refresh and flush the HTTP request */\n refresh: (token: string, response: TRefreshArgs['response']) => void;\n /** Helper to make a secure request that requires authentication */\n makeSecureRequest: (route: string) => void;\n};\n\nexport const setupAuthTest = <\n TLoginArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TRefreshArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TFeatures extends readonly AnyFeatureBuilder[] = readonly AnyFeatureBuilder[],\n TBearerData = unknown,\n>(\n config: AuthTestSetupConfig<TLoginArgs, TRefreshArgs, TFeatures, TBearerData>,\n): AuthTestSetup<TLoginArgs, TRefreshArgs, TFeatures, TBearerData> => {\n const {\n querySetup,\n loginPath = '/auth/login',\n refreshPath = '/auth/refresh',\n autoRetryOn401 = false,\n extractLoginTokens = (response) => ({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n }),\n extractRefreshTokens = (response) => ({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n }),\n features,\n bearerDecryptFn,\n multiTabSync = false,\n refreshStrategy,\n minRefreshInterval,\n refreshIfExpired,\n expiresInPropertyName,\n } = config;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const login = querySetup.createPost<TLoginArgs>(loginPath as any, {} as any) as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const refresh = querySetup.createPost<TRefreshArgs>(refreshPath as any, {} as any) as any;\n\n const [, injectAuth] = createBearerAuthProvider({\n name: 'test-auth',\n queryClientRef: querySetup.queryClientRef,\n queries: [\n withAuthenticationQuery('login', {\n queryCreator: login,\n extractTokens: extractLoginTokens,\n }),\n withRefreshQuery('refresh', {\n queryCreator: refresh,\n extractTokens: extractRefreshTokens,\n autoRetryOn401,\n refreshStrategy,\n minRefreshInterval,\n refreshIfExpired,\n expiresInPropertyName,\n }),\n ] as [AuthQueryBuilder<'login', TLoginArgs>, TokenRefreshQueryBuilder<'refresh', TRefreshArgs>],\n features: (features ?? ([] as const)) as unknown as TFeatures,\n bearerDecryptFn,\n multiTabSync,\n });\n\n const auth = TestBed.runInInjectionContext(() => {\n const provider = injectAuth();\n if (!provider) {\n throw new Error('Failed to create auth provider in test setup');\n }\n return provider;\n });\n\n const loginHelper = (credentials: TLoginArgs['body'], response: TLoginArgs['response']) => {\n TestBed.runInInjectionContext(() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n auth.queries.login.execute({ body: credentials } as any);\n });\n const fullUrl = `${querySetup.baseUrl}${loginPath}`;\n expectFlushAndWait(querySetup.httpTesting, fullUrl, response);\n };\n\n const refreshHelper = (token: string, response: TRefreshArgs['response']) => {\n TestBed.runInInjectionContext(() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n auth.queries.refresh.execute({ body: { token } as any } as any);\n });\n const fullUrl = `${querySetup.baseUrl}${refreshPath}`;\n expectFlushAndWait(querySetup.httpTesting, fullUrl, response);\n };\n\n const makeSecureRequest = (route: string) => {\n TestBed.runInInjectionContext(() => {\n querySetup.queryClient.repository.request({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n route: route as any,\n method: 'GET',\n isSecure: true,\n consumerDestroyRef: TestBed.inject(DestroyRef),\n });\n });\n };\n\n return {\n auth,\n login: loginHelper,\n refresh: refreshHelper,\n makeSecureRequest,\n };\n};\n","import { HttpClient, provideHttpClient } from '@angular/common/http';\nimport { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';\nimport { EnvironmentProviders, ErrorHandler, Injector } from '@angular/core';\nimport { TestBed } from '@angular/core/testing';\nimport { provideRouter } from '@angular/router';\nimport {\n AnyCreateQueryClientResult,\n createDeleteQuery,\n createGetQuery,\n createPatchQuery,\n createPostQuery,\n createPutQuery,\n createQueryClient,\n QueryClientRef,\n} from '@ethlete/query';\n\nexport type QueryTestSetup = {\n queryClient: NonNullable<ReturnType<AnyCreateQueryClientResult[1]>>;\n queryClientRef: QueryClientRef;\n httpClient: HttpClient;\n httpTesting: HttpTestingController;\n injector: Injector;\n baseUrl: string;\n createGet: ReturnType<typeof createGetQuery>;\n createPost: ReturnType<typeof createPostQuery>;\n createPut: ReturnType<typeof createPutQuery>;\n createPatch: ReturnType<typeof createPatchQuery>;\n createDelete: ReturnType<typeof createDeleteQuery>;\n};\n\nexport type QueryTestSetupConfig = {\n baseUrl?: string;\n name?: string;\n mockErrorHandler?: boolean;\n};\n\nexport const setupQueryTest = (config?: QueryTestSetupConfig): QueryTestSetup => {\n const baseUrl = config?.baseUrl ?? 'https://api.test.com';\n const name = config?.name ?? 'test';\n const mockErrorHandler = config?.mockErrorHandler !== false;\n\n // Suppress console.warn for auth-related warnings during tests\n const originalWarn = console.warn;\n console.warn = (...args: unknown[]) => {\n const message = args[0];\n if (typeof message === 'string' && message.includes('auto-refresh')) {\n return; // Suppress auto-refresh warnings\n }\n originalWarn(...args);\n };\n\n // Suppress console.error for expected error scenarios during tests\n const originalError = console.error;\n console.error = (...args: unknown[]) => {\n const message = args[0];\n // Suppress HttpErrorResponse logs\n if (message && typeof message === 'object' && 'name' in message && message.name === 'HttpErrorResponse') {\n return;\n }\n // Suppress bearer token decryption errors\n if (typeof message === 'string' && message.includes('Failed to decrypt bearer token')) {\n return;\n }\n // Suppress token extraction errors\n if (typeof message === 'string' && message.includes('Failed to extract tokens from')) {\n return;\n }\n originalError(...args);\n };\n\n const providers: (EnvironmentProviders | object)[] = [\n provideHttpClient(),\n provideHttpClientTesting(),\n provideRouter([]),\n ];\n\n if (mockErrorHandler) {\n providers.push({\n provide: ErrorHandler,\n useValue: { handleError: () => undefined },\n });\n }\n\n TestBed.configureTestingModule({ providers });\n\n const queryClientRef = createQueryClient({ baseUrl, name });\n\n const setup = TestBed.runInInjectionContext(() => {\n const [, inject] = queryClientRef;\n const queryClient = inject();\n\n if (!queryClient) {\n throw new Error('Failed to create query client in test setup');\n }\n\n return {\n queryClient,\n queryClientRef,\n httpClient: TestBed.inject(HttpClient),\n httpTesting: TestBed.inject(HttpTestingController),\n injector: TestBed.inject(Injector),\n baseUrl,\n createGet: createGetQuery(queryClientRef),\n createPost: createPostQuery(queryClientRef),\n createPut: createPutQuery(queryClientRef),\n createPatch: createPatchQuery(queryClientRef),\n createDelete: createDeleteQuery(queryClientRef),\n };\n });\n\n // Restore console.warn and console.error when tests are done\n const restoreConsole = () => {\n console.warn = originalWarn;\n console.error = originalError;\n };\n\n // Store the restore function for cleanup\n (setup as any)._restoreConsole = restoreConsole;\n\n return setup;\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ethlete-query-testing.mjs","sources":["../../../../libs/query/testing/query-test-utils.ts","../../../../libs/query/testing/auth-test-utils.ts","../../../../libs/query/testing/query-test-setup.ts","../../../../libs/query/testing/ethlete-query-testing.ts"],"sourcesContent":["import { HttpTestingController } from '@angular/common/http/testing';\nimport { TestBed } from '@angular/core/testing';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const expectAndFlush = <T = unknown>(\n httpTesting: HttpTestingController,\n url: string,\n response: T,\n statusOpts?: { status: number; statusText: string },\n): void => {\n const req = httpTesting.expectOne(url);\n if (statusOpts) {\n req.flush(response as any, statusOpts);\n } else {\n req.flush(response as any);\n }\n};\n\nexport const expectFlushAndWait = <T = unknown>(\n httpTesting: HttpTestingController,\n url: string,\n response: T,\n statusOpts?: { status: number; statusText: string },\n): void => {\n expectAndFlush(httpTesting, url, response, statusOpts);\n TestBed.tick();\n};\n","import { DestroyRef } from '@angular/core';\nimport { TestBed } from '@angular/core/testing';\nimport {\n AnyQueryBuilder,\n AuthQueryBuilder,\n BearerAuthProvider,\n BearerAuthProviderFeatureContext,\n createBearerAuthProvider,\n TokenRefreshQueryBuilder,\n TokenRefreshQueryConfig,\n withAuthenticationQuery,\n withRefreshQuery,\n} from '@ethlete/query';\nimport { QueryTestSetup } from './query-test-setup';\nimport { expectFlushAndWait } from './query-test-utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFeatureBuilder = (context: BearerAuthProviderFeatureContext<any, readonly AnyQueryBuilder[]>) => {\n type: string;\n instance: unknown;\n};\n\nexport type AuthTestSetupConfig<\n TLoginArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TRefreshArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TFeatures extends readonly AnyFeatureBuilder[] = [],\n TBearerData = unknown,\n> = {\n /** The query test setup instance */\n querySetup: QueryTestSetup;\n /** Login endpoint path. Default: '/auth/login' */\n loginPath?: string;\n /** Refresh endpoint path. Default: '/auth/refresh' */\n refreshPath?: string;\n /** Whether to enable auto-retry on 401. Default: false */\n autoRetryOn401?: boolean;\n /** Function to extract tokens from login response */\n extractLoginTokens?: (response: TLoginArgs['response']) => { accessToken: string; refreshToken: string };\n /** Function to extract tokens from refresh response */\n extractRefreshTokens?: (response: TRefreshArgs['response']) => { accessToken: string; refreshToken: string };\n /** Feature builders for additional auth functionality */\n features?: [...TFeatures];\n /** Custom bearer decrypt function for testing */\n bearerDecryptFn?: (token: string) => TBearerData;\n /** Whether to disable multi-tab sync. Default: false */\n multiTabSync?:\n | false\n | { enabled?: boolean; channelName?: string; syncTokens?: boolean; syncLogout?: boolean; leaderElection?: boolean };\n /** Refresh strategy configuration. See TokenRefreshQueryConfig for details */\n refreshStrategy?: TokenRefreshQueryConfig<TRefreshArgs>['refreshStrategy'];\n /** Minimum refresh interval in milliseconds */\n minRefreshInterval?: number;\n /** Whether to refresh if token is already expired */\n refreshIfExpired?: boolean;\n /** Property name for expiration in JWT */\n expiresInPropertyName?: string;\n};\n\nexport type AuthTestSetup<\n TLoginArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TRefreshArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TFeatures extends readonly AnyFeatureBuilder[] = [],\n TBearerData = unknown,\n> = {\n /** The bearer auth provider instance */\n auth: BearerAuthProvider<\n [AuthQueryBuilder<'login', TLoginArgs>, TokenRefreshQueryBuilder<'refresh', TRefreshArgs>],\n TFeatures,\n TBearerData\n >;\n /** Helper to login a user and flush the HTTP request */\n login: (credentials: TLoginArgs['body'], response: TLoginArgs['response']) => void;\n /** Helper to trigger a refresh and flush the HTTP request */\n refresh: (token: string, response: TRefreshArgs['response']) => void;\n /** Helper to make a secure request that requires authentication */\n makeSecureRequest: (route: string) => void;\n};\n\nexport const setupAuthTest = <\n TLoginArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TRefreshArgs extends { body: Record<string, unknown>; response: { accessToken: string; refreshToken: string } } = {\n body: Record<string, unknown>;\n response: { accessToken: string; refreshToken: string };\n },\n TFeatures extends readonly AnyFeatureBuilder[] = readonly AnyFeatureBuilder[],\n TBearerData = unknown,\n>(\n config: AuthTestSetupConfig<TLoginArgs, TRefreshArgs, TFeatures, TBearerData>,\n): AuthTestSetup<TLoginArgs, TRefreshArgs, TFeatures, TBearerData> => {\n const {\n querySetup,\n loginPath = '/auth/login',\n refreshPath = '/auth/refresh',\n autoRetryOn401 = false,\n extractLoginTokens = (response) => ({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n }),\n extractRefreshTokens = (response) => ({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n }),\n features,\n bearerDecryptFn,\n multiTabSync = false,\n refreshStrategy,\n minRefreshInterval,\n refreshIfExpired,\n expiresInPropertyName,\n } = config;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const login = querySetup.createPost<TLoginArgs>(loginPath as any, {} as any) as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const refresh = querySetup.createPost<TRefreshArgs>(refreshPath as any, {} as any) as any;\n\n const [, injectAuth] = createBearerAuthProvider({\n name: 'test-auth',\n queryClientRef: querySetup.queryClientRef,\n queries: [\n withAuthenticationQuery('login', {\n queryCreator: login,\n extractTokens: extractLoginTokens,\n }),\n withRefreshQuery('refresh', {\n queryCreator: refresh,\n extractTokens: extractRefreshTokens,\n autoRetryOn401,\n refreshStrategy,\n minRefreshInterval,\n refreshIfExpired,\n expiresInPropertyName,\n }),\n ] as [AuthQueryBuilder<'login', TLoginArgs>, TokenRefreshQueryBuilder<'refresh', TRefreshArgs>],\n features: (features ?? ([] as const)) as unknown as TFeatures,\n bearerDecryptFn,\n multiTabSync,\n });\n\n const auth = TestBed.runInInjectionContext(() => {\n const provider = injectAuth();\n if (!provider) {\n throw new Error('Failed to create auth provider in test setup');\n }\n return provider;\n });\n\n const loginHelper = (credentials: TLoginArgs['body'], response: TLoginArgs['response']) => {\n TestBed.runInInjectionContext(() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n auth.queries.login.execute({ body: credentials } as any);\n });\n const fullUrl = `${querySetup.baseUrl}${loginPath}`;\n expectFlushAndWait(querySetup.httpTesting, fullUrl, response);\n };\n\n const refreshHelper = (token: string, response: TRefreshArgs['response']) => {\n TestBed.runInInjectionContext(() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n auth.queries.refresh.execute({ body: { token } as any } as any);\n });\n const fullUrl = `${querySetup.baseUrl}${refreshPath}`;\n expectFlushAndWait(querySetup.httpTesting, fullUrl, response);\n };\n\n const makeSecureRequest = (route: string) => {\n TestBed.runInInjectionContext(() => {\n querySetup.queryClient.repository.request({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n route: route as any,\n method: 'GET',\n isSecure: true,\n consumerDestroyRef: TestBed.inject(DestroyRef),\n });\n });\n };\n\n return {\n auth,\n login: loginHelper,\n refresh: refreshHelper,\n makeSecureRequest,\n };\n};\n","import { HttpClient, provideHttpClient } from '@angular/common/http';\nimport { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';\nimport { EnvironmentProviders, ErrorHandler, Injector } from '@angular/core';\nimport { TestBed } from '@angular/core/testing';\nimport { provideRouter } from '@angular/router';\nimport {\n AnyCreateQueryClientResult,\n createDeleteQuery,\n createGetQuery,\n createPatchQuery,\n createPostQuery,\n createPutQuery,\n createQueryClient,\n QueryClientRef,\n} from '@ethlete/query';\n\nexport type QueryTestSetup = {\n queryClient: NonNullable<ReturnType<AnyCreateQueryClientResult[1]>>;\n queryClientRef: QueryClientRef;\n httpClient: HttpClient;\n httpTesting: HttpTestingController;\n injector: Injector;\n baseUrl: string;\n createGet: ReturnType<typeof createGetQuery>;\n createPost: ReturnType<typeof createPostQuery>;\n createPut: ReturnType<typeof createPutQuery>;\n createPatch: ReturnType<typeof createPatchQuery>;\n createDelete: ReturnType<typeof createDeleteQuery>;\n};\n\nexport type QueryTestSetupConfig = {\n baseUrl?: string;\n name?: string;\n mockErrorHandler?: boolean;\n};\n\nexport const setupQueryTest = (config?: QueryTestSetupConfig): QueryTestSetup => {\n const baseUrl = config?.baseUrl ?? 'https://api.test.com';\n const name = config?.name ?? 'test';\n const mockErrorHandler = config?.mockErrorHandler !== false;\n\n // Suppress console.warn for auth-related warnings during tests\n const originalWarn = console.warn;\n console.warn = (...args: unknown[]) => {\n const message = args[0];\n if (typeof message === 'string' && message.includes('auto-refresh')) {\n return; // Suppress auto-refresh warnings\n }\n originalWarn(...args);\n };\n\n // Suppress console.error for expected error scenarios during tests\n const originalError = console.error;\n console.error = (...args: unknown[]) => {\n const message = args[0];\n // Suppress HttpErrorResponse logs\n if (message && typeof message === 'object' && 'name' in message && message.name === 'HttpErrorResponse') {\n return;\n }\n // Suppress bearer token decryption errors\n if (typeof message === 'string' && message.includes('Failed to decrypt bearer token')) {\n return;\n }\n // Suppress token extraction errors\n if (typeof message === 'string' && message.includes('Failed to extract tokens from')) {\n return;\n }\n originalError(...args);\n };\n\n const providers: (EnvironmentProviders | object)[] = [\n provideHttpClient(),\n provideHttpClientTesting(),\n provideRouter([]),\n ];\n\n if (mockErrorHandler) {\n providers.push({\n provide: ErrorHandler,\n useValue: { handleError: () => undefined },\n });\n }\n\n TestBed.configureTestingModule({ providers });\n\n const queryClientRef = createQueryClient({ baseUrl, name });\n\n const setup = TestBed.runInInjectionContext(() => {\n const [, inject] = queryClientRef;\n const queryClient = inject();\n\n if (!queryClient) {\n throw new Error('Failed to create query client in test setup');\n }\n\n return {\n queryClient,\n queryClientRef,\n httpClient: TestBed.inject(HttpClient),\n httpTesting: TestBed.inject(HttpTestingController),\n injector: TestBed.inject(Injector),\n baseUrl,\n createGet: createGetQuery(queryClientRef),\n createPost: createPostQuery(queryClientRef),\n createPut: createPutQuery(queryClientRef),\n createPatch: createPatchQuery(queryClientRef),\n createDelete: createDeleteQuery(queryClientRef),\n };\n });\n\n // Restore console.warn and console.error when tests are done\n const restoreConsole = () => {\n console.warn = originalWarn;\n console.error = originalError;\n };\n\n // Store the restore function for cleanup\n (setup as typeof setup & { _restoreConsole: () => void })._restoreConsole = restoreConsole;\n\n return setup;\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -195,6 +195,8 @@ const QueryRuntimeErrorCode = {
|
|
|
195
195
|
INVALID_STATE_INSIDE_SECURE_EXECUTE_FACTORY: 701,
|
|
196
196
|
// Query Execution
|
|
197
197
|
CIRCULAR_QUERY_DEPENDENCY: 800,
|
|
198
|
+
// Query Sequence
|
|
199
|
+
QUERY_SEQUENCE_ALREADY_RUNNING: 900,
|
|
198
200
|
};
|
|
199
201
|
const queryFeatureUsedMultipleTimes = (type) => {
|
|
200
202
|
return new RuntimeError(QueryRuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES, `The query feature "${type}()" was used multiple times.`);
|
|
@@ -263,6 +265,9 @@ const invalidStateInsideSecureExecuteFactory = () => {
|
|
|
263
265
|
const circularQueryDependency = () => {
|
|
264
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.`);
|
|
265
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
|
+
};
|
|
266
271
|
|
|
267
272
|
/**
|
|
268
273
|
* Returning this inside a withArgs feature will reset the query args to null.
|
|
@@ -1267,7 +1272,7 @@ const request = (config) => {
|
|
|
1267
1272
|
body = text;
|
|
1268
1273
|
}
|
|
1269
1274
|
}
|
|
1270
|
-
catch
|
|
1275
|
+
catch {
|
|
1271
1276
|
// Ignore the error.
|
|
1272
1277
|
}
|
|
1273
1278
|
}
|
|
@@ -3355,13 +3360,17 @@ const isQueryCollection = (query) => {
|
|
|
3355
3360
|
const createQueryCollection = (
|
|
3356
3361
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3357
3362
|
queryMap) => new BehaviorSubject(null);
|
|
3358
|
-
const createQueryCollectionSubject = (
|
|
3363
|
+
const createQueryCollectionSubject = (
|
|
3364
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3365
|
+
queryMap, config) => {
|
|
3359
3366
|
assertInInjectionContext(createQueryCollectionSubject);
|
|
3360
3367
|
const subject = new BehaviorSubject(null);
|
|
3361
3368
|
addQueryContainerHandling(subject.pipe(map((s) => s?.query ?? null)), () => subject.getValue()?.query ?? null, config);
|
|
3362
3369
|
return subject;
|
|
3363
3370
|
};
|
|
3364
|
-
const createQueryCollectionSignal = (
|
|
3371
|
+
const createQueryCollectionSignal = (
|
|
3372
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3373
|
+
queryMap, config) => {
|
|
3365
3374
|
assertInInjectionContext(createQueryCollectionSignal);
|
|
3366
3375
|
const _signal = signal(null, /* @ts-ignore */
|
|
3367
3376
|
...(ngDevMode ? [{ debugName: "_signal" }] : /* istanbul ignore next */ []));
|
|
@@ -4308,7 +4317,7 @@ class InfinityQueryDirective {
|
|
|
4308
4317
|
get data$() {
|
|
4309
4318
|
return this._data$.asObservable();
|
|
4310
4319
|
}
|
|
4311
|
-
static ngTemplateContextGuard(
|
|
4320
|
+
static ngTemplateContextGuard(_dir, _ctx) {
|
|
4312
4321
|
return true;
|
|
4313
4322
|
}
|
|
4314
4323
|
constructor() {
|
|
@@ -4410,13 +4419,13 @@ class InfinityQueryDirective {
|
|
|
4410
4419
|
this._viewContext.currentQuery = null;
|
|
4411
4420
|
this._data$.next([]);
|
|
4412
4421
|
}
|
|
4413
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4414
|
-
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: [
|
|
4415
4424
|
{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective },
|
|
4416
4425
|
provideInfinityQueryResponseDelay(),
|
|
4417
4426
|
], exportAs: ["etInfinityQuery"], ngImport: i0 }); }
|
|
4418
4427
|
}
|
|
4419
|
-
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: [{
|
|
4420
4429
|
type: Directive,
|
|
4421
4430
|
args: [{
|
|
4422
4431
|
selector: '[etInfinityQuery]',
|
|
@@ -4476,10 +4485,10 @@ class InfinityQueryTriggerDirective {
|
|
|
4476
4485
|
});
|
|
4477
4486
|
this._observer.observe(this._elementRef.nativeElement);
|
|
4478
4487
|
}
|
|
4479
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4480
|
-
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 }); }
|
|
4481
4490
|
}
|
|
4482
|
-
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: [{
|
|
4483
4492
|
type: Directive,
|
|
4484
4493
|
args: [{
|
|
4485
4494
|
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
@@ -4487,7 +4496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
4487
4496
|
}], propDecorators: { scrollContainerSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollContainerSelector", required: false }] }], infinityQueryOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "infinityQueryOverride", required: false }] }] } });
|
|
4488
4497
|
|
|
4489
4498
|
class QueryDirective {
|
|
4490
|
-
static ngTemplateContextGuard(
|
|
4499
|
+
static ngTemplateContextGuard(_dir, _ctx) {
|
|
4491
4500
|
return true;
|
|
4492
4501
|
}
|
|
4493
4502
|
constructor() {
|
|
@@ -4565,10 +4574,10 @@ class QueryDirective {
|
|
|
4565
4574
|
});
|
|
4566
4575
|
});
|
|
4567
4576
|
}
|
|
4568
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4569
|
-
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 }); }
|
|
4570
4579
|
}
|
|
4571
|
-
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: [{
|
|
4572
4581
|
type: Directive,
|
|
4573
4582
|
args: [{
|
|
4574
4583
|
selector: '[etQuery]',
|
|
@@ -4589,10 +4598,10 @@ class QueryShortNamePipe {
|
|
|
4589
4598
|
}
|
|
4590
4599
|
return route;
|
|
4591
4600
|
}
|
|
4592
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4593
|
-
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" }); }
|
|
4594
4603
|
}
|
|
4595
|
-
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: [{
|
|
4596
4605
|
type: Pipe,
|
|
4597
4606
|
args: [{ name: 'queryShortName' }]
|
|
4598
4607
|
}] });
|
|
@@ -4639,15 +4648,13 @@ class QueryDevtoolsComponent {
|
|
|
4639
4648
|
this.selectedQueryId = signal(null, /* @ts-ignore */
|
|
4640
4649
|
...(ngDevMode ? [{ debugName: "selectedQueryId" }] : /* istanbul ignore next */ []));
|
|
4641
4650
|
this.selectedClientConfig = computed(() => {
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
if (!cfg) {
|
|
4648
|
-
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');
|
|
4649
4656
|
}
|
|
4650
|
-
return
|
|
4657
|
+
return config;
|
|
4651
4658
|
}, /* @ts-ignore */
|
|
4652
4659
|
...(ngDevMode ? [{ debugName: "selectedClientConfig" }] : /* istanbul ignore next */ []));
|
|
4653
4660
|
this.queryStore = computed(() => {
|
|
@@ -4900,10 +4907,10 @@ class QueryDevtoolsComponent {
|
|
|
4900
4907
|
clearQueryHistory() {
|
|
4901
4908
|
this.queryHistory$.next([]);
|
|
4902
4909
|
}
|
|
4903
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
4904
|
-
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 }); }
|
|
4905
4912
|
}
|
|
4906
|
-
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: [{
|
|
4907
4914
|
type: Component,
|
|
4908
4915
|
args: [{ selector: 'et-query-devtools', encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
4909
4916
|
class: 'et-query-devtools',
|
|
@@ -5490,6 +5497,93 @@ const executeUntilSettled = async (query, executeArgs) => {
|
|
|
5490
5497
|
return snapshot;
|
|
5491
5498
|
};
|
|
5492
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
|
+
|
|
5493
5587
|
/**
|
|
5494
5588
|
* Binds a query-backed async validator to a signal-forms field, adapting an `@ethlete/query` v3
|
|
5495
5589
|
* query into what `validateAsync` consumes. The query runs through the query client — so bearer
|
|
@@ -6817,10 +6911,10 @@ class ParseHttpErrorCodeToTitleDePipe {
|
|
|
6817
6911
|
constructor() {
|
|
6818
6912
|
this.transform = parseHttpErrorCodeToTitleDe;
|
|
6819
6913
|
}
|
|
6820
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
6821
|
-
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" }); }
|
|
6822
6916
|
}
|
|
6823
|
-
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: [{
|
|
6824
6918
|
type: Pipe,
|
|
6825
6919
|
args: [{
|
|
6826
6920
|
name: 'parseHttpErrorCodeToTitleDe',
|
|
@@ -6830,10 +6924,10 @@ class ParseHttpErrorCodeToMessageDePipe {
|
|
|
6830
6924
|
constructor() {
|
|
6831
6925
|
this.transform = parseHttpErrorCodeToMessageDe;
|
|
6832
6926
|
}
|
|
6833
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
6834
|
-
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" }); }
|
|
6835
6929
|
}
|
|
6836
|
-
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: [{
|
|
6837
6931
|
type: Pipe,
|
|
6838
6932
|
args: [{
|
|
6839
6933
|
name: 'parseHttpErrorCodeToMessageDe',
|
|
@@ -7017,10 +7111,10 @@ class ParseHttpErrorCodeToTitleEnPipe {
|
|
|
7017
7111
|
constructor() {
|
|
7018
7112
|
this.transform = parseHttpErrorCodeToTitleEn;
|
|
7019
7113
|
}
|
|
7020
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
7021
|
-
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" }); }
|
|
7022
7116
|
}
|
|
7023
|
-
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: [{
|
|
7024
7118
|
type: Pipe,
|
|
7025
7119
|
args: [{
|
|
7026
7120
|
name: 'parseHttpErrorCodeToTitleEn',
|
|
@@ -7030,10 +7124,10 @@ class ParseHttpErrorCodeToMessageEnPipe {
|
|
|
7030
7124
|
constructor() {
|
|
7031
7125
|
this.transform = parseHttpErrorCodeToMessageEn;
|
|
7032
7126
|
}
|
|
7033
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
7034
|
-
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" }); }
|
|
7035
7129
|
}
|
|
7036
|
-
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: [{
|
|
7037
7131
|
type: Pipe,
|
|
7038
7132
|
args: [{
|
|
7039
7133
|
name: 'parseHttpErrorCodeToMessageEn',
|
|
@@ -7803,5 +7897,5 @@ const createWebSocketClient = (options) => {
|
|
|
7803
7897
|
* Generated bundle index. Do not edit.
|
|
7804
7898
|
*/
|
|
7805
7899
|
|
|
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 };
|
|
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 };
|
|
7807
7901
|
//# sourceMappingURL=ethlete-query.mjs.map
|