@ethlete/query 5.43.1 → 6.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @ethlete/query
2
2
 
3
+ ## 6.0.0-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`d99c3f0`](https://github.com/ethlete-io/ethdk/commit/d99c3f0fc3d6b3b0e7105d21d1f7119cde68b561)]:
8
+ - @ethlete/types@2.0.0-next.0
9
+
10
+ ## 6.0.0-next.0
11
+
12
+ ### Major Changes
13
+
14
+ - [#2891](https://github.com/ethlete-io/ethdk/pull/2891) [`27aa7a8`](https://github.com/ethlete-io/ethdk/commit/27aa7a825573a12c3360530d1d32df7c4690e7e8) Thanks [@github-actions](https://github.com/apps/github-actions)! - You must run `yarn nx generate @ethlete/query:prep-for-query-v3` after updating to this version. Updating this package also requires updating `@ethlete/core` and `@ethlete/cdk` to their respective latest versions. **Please check the console output for warnings about any manual code changes that may be needed.**
15
+
16
+ - [#2891](https://github.com/ethlete-io/ethdk/pull/2891) [`6816054`](https://github.com/ethlete-io/ethdk/commit/68160548e8df8cd8fbaff61afa684442f7f7a7e5) Thanks [@github-actions](https://github.com/apps/github-actions)! - Remove ExperimentalQuery import. Query v3 is now considered stable
17
+
18
+ - [#2891](https://github.com/ethlete-io/ethdk/pull/2891) [`6816054`](https://github.com/ethlete-io/ethdk/commit/68160548e8df8cd8fbaff61afa684442f7f7a7e5) Thanks [@github-actions](https://github.com/apps/github-actions)! - Rename the following symbols to solve naming conflicts. Usages will be migrated.
19
+ - `BearerAuthProvider` -> `V2BearerAuthProvider`
20
+ - `AnyQueryCreator` -> `AnyV2QueryCreator`
21
+ - `CacheAdapterFn` -> `V2CacheAdapterFn`
22
+ - `Query` -> `V2Query`
23
+ - `QueryArgsOf` -> `V2QueryArgsOf`
24
+ - `QueryClient` -> `V2QueryClient`
25
+ - `QueryClientConfig` -> `V2QueryClientConfig`
26
+ - `QueryConfig` -> `V2QueryConfig`
27
+ - `QueryCreator` -> `V2QueryCreator`
28
+ - `QueryState` -> `V2QueryState`
29
+ - `RouteType` -> `V2RouteType`
30
+ - `RouteString` -> `V2RouteString`
31
+ - `AnyQuery` -> `AnyV2Query`
32
+
33
+ Rename the following functions to solve naming conflicts. Usages will be migrated.
34
+ - `buildQueryCacheKey` -> `v2BuildQueryCacheKey`
35
+ - `extractExpiresInSeconds` -> `v2ExtractExpiresInSeconds`
36
+ - `shouldCacheQuery` -> `v2ShouldCacheQuery`
37
+ - `shouldRetryRequest` -> `v2ShouldRetryRequest`
38
+
39
+ ### Minor Changes
40
+
41
+ - [#2891](https://github.com/ethlete-io/ethdk/pull/2891) [`5d7ae57`](https://github.com/ethlete-io/ethdk/commit/5d7ae57859077357e2e8a1761286c4744e58d4b9) Thanks [@github-actions](https://github.com/apps/github-actions)! - Add responseTransformer option to query creator
42
+
43
+ - [#2891](https://github.com/ethlete-io/ethdk/pull/2891) [`ee5014f`](https://github.com/ethlete-io/ethdk/commit/ee5014f33dc7d79b43774aaafc2fd187073871be) Thanks [@github-actions](https://github.com/apps/github-actions)! - Add support for secure gql queries
44
+
45
+ - [#2891](https://github.com/ethlete-io/ethdk/pull/2891) [`7e0f4d9`](https://github.com/ethlete-io/ethdk/commit/7e0f4d943abe6ae61719fcb7003cc8c19496320e) Thanks [@github-actions](https://github.com/apps/github-actions)! - Add testing entrypoint
46
+
47
+ ### Patch Changes
48
+
49
+ - Updated dependencies [[`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`99b3f64`](https://github.com/ethlete-io/ethdk/commit/99b3f646701cb763512e7148592457dc509f55e5), [`e4a7c6f`](https://github.com/ethlete-io/ethdk/commit/e4a7c6ff868e6dd541d4533e509b30821f6c83b5), [`d080bb2`](https://github.com/ethlete-io/ethdk/commit/d080bb2cc246d4559ffcbf88c319b9437133d377), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`f5ad487`](https://github.com/ethlete-io/ethdk/commit/f5ad4879061917e91bebf144889774226202308b), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`f4847d4`](https://github.com/ethlete-io/ethdk/commit/f4847d4eb25b70706a4ee8c81addcd58a7d99995), [`451e170`](https://github.com/ethlete-io/ethdk/commit/451e170f2df1c49fca07bde053efa75bd23ca22f), [`f5ad487`](https://github.com/ethlete-io/ethdk/commit/f5ad4879061917e91bebf144889774226202308b), [`55dc627`](https://github.com/ethlete-io/ethdk/commit/55dc627a6a49f3a8a5c8f80f63f163e443e07099), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`d080bb2`](https://github.com/ethlete-io/ethdk/commit/d080bb2cc246d4559ffcbf88c319b9437133d377), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`5e764b9`](https://github.com/ethlete-io/ethdk/commit/5e764b92cbcc6b6ec288a84b397d291f0b1138fb), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`e4a7c6f`](https://github.com/ethlete-io/ethdk/commit/e4a7c6ff868e6dd541d4533e509b30821f6c83b5), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`6e41e09`](https://github.com/ethlete-io/ethdk/commit/6e41e09668d2077fba27de1e11bacc98480becfe), [`8a85984`](https://github.com/ethlete-io/ethdk/commit/8a859841acaf7c10c876c7eb921f4c7e25e41764), [`5e764b9`](https://github.com/ethlete-io/ethdk/commit/5e764b92cbcc6b6ec288a84b397d291f0b1138fb), [`d080bb2`](https://github.com/ethlete-io/ethdk/commit/d080bb2cc246d4559ffcbf88c319b9437133d377), [`e4a7c6f`](https://github.com/ethlete-io/ethdk/commit/e4a7c6ff868e6dd541d4533e509b30821f6c83b5), [`5e764b9`](https://github.com/ethlete-io/ethdk/commit/5e764b92cbcc6b6ec288a84b397d291f0b1138fb)]:
50
+ - @ethlete/core@5.0.0-next.0
51
+
3
52
  ## 5.43.1
4
53
 
5
54
  ### Patch Changes
@@ -0,0 +1,178 @@
1
+ import { DestroyRef, ErrorHandler, Injector } from '@angular/core';
2
+ import { TestBed } from '@angular/core/testing';
3
+ import { createBearerAuthProvider, withAuthenticationQuery, withRefreshQuery, createQueryClient, createDeleteQuery, createPatchQuery, createPutQuery, createPostQuery, createGetQuery } from '@ethlete/query';
4
+ import { provideHttpClient, HttpClient } from '@angular/common/http';
5
+ import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
6
+ import { provideRouter } from '@angular/router';
7
+
8
+ /* eslint-disable @typescript-eslint/no-explicit-any */
9
+ const expectAndFlush = (httpTesting, url, response, statusOpts) => {
10
+ const req = httpTesting.expectOne(url);
11
+ if (statusOpts) {
12
+ req.flush(response, statusOpts);
13
+ }
14
+ else {
15
+ req.flush(response);
16
+ }
17
+ };
18
+ const expectFlushAndWait = (httpTesting, url, response, statusOpts) => {
19
+ expectAndFlush(httpTesting, url, response, statusOpts);
20
+ TestBed.tick();
21
+ };
22
+
23
+ const setupAuthTest = (config) => {
24
+ const { querySetup, loginPath = '/auth/login', refreshPath = '/auth/refresh', autoRetryOn401 = false, extractLoginTokens = (response) => ({
25
+ accessToken: response.accessToken,
26
+ refreshToken: response.refreshToken,
27
+ }), extractRefreshTokens = (response) => ({
28
+ accessToken: response.accessToken,
29
+ refreshToken: response.refreshToken,
30
+ }), features, bearerDecryptFn, multiTabSync = false, refreshStrategy, minRefreshInterval, refreshIfExpired, expiresInPropertyName, } = config;
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ const login = querySetup.createPost(loginPath, {});
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ const refresh = querySetup.createPost(refreshPath, {});
35
+ const [, injectAuth] = createBearerAuthProvider({
36
+ name: 'test-auth',
37
+ queryClientRef: querySetup.queryClientRef,
38
+ queries: [
39
+ withAuthenticationQuery('login', {
40
+ queryCreator: login,
41
+ extractTokens: extractLoginTokens,
42
+ }),
43
+ withRefreshQuery('refresh', {
44
+ queryCreator: refresh,
45
+ extractTokens: extractRefreshTokens,
46
+ autoRetryOn401,
47
+ refreshStrategy,
48
+ minRefreshInterval,
49
+ refreshIfExpired,
50
+ expiresInPropertyName,
51
+ }),
52
+ ],
53
+ features: (features ?? []),
54
+ bearerDecryptFn,
55
+ multiTabSync,
56
+ });
57
+ const auth = TestBed.runInInjectionContext(() => {
58
+ const provider = injectAuth();
59
+ if (!provider) {
60
+ throw new Error('Failed to create auth provider in test setup');
61
+ }
62
+ return provider;
63
+ });
64
+ const loginHelper = (credentials, response) => {
65
+ TestBed.runInInjectionContext(() => {
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ auth.queries.login.execute({ body: credentials });
68
+ });
69
+ const fullUrl = `${querySetup.baseUrl}${loginPath}`;
70
+ expectFlushAndWait(querySetup.httpTesting, fullUrl, response);
71
+ };
72
+ const refreshHelper = (token, response) => {
73
+ TestBed.runInInjectionContext(() => {
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ auth.queries.refresh.execute({ body: { token } });
76
+ });
77
+ const fullUrl = `${querySetup.baseUrl}${refreshPath}`;
78
+ expectFlushAndWait(querySetup.httpTesting, fullUrl, response);
79
+ };
80
+ const makeSecureRequest = (route) => {
81
+ TestBed.runInInjectionContext(() => {
82
+ querySetup.queryClient.repository.request({
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ route: route,
85
+ method: 'GET',
86
+ isSecure: true,
87
+ consumerDestroyRef: TestBed.inject(DestroyRef),
88
+ });
89
+ });
90
+ };
91
+ return {
92
+ auth,
93
+ login: loginHelper,
94
+ refresh: refreshHelper,
95
+ makeSecureRequest,
96
+ };
97
+ };
98
+
99
+ const setupQueryTest = (config) => {
100
+ const baseUrl = config?.baseUrl ?? 'https://api.test.com';
101
+ const name = config?.name ?? 'test';
102
+ const mockErrorHandler = config?.mockErrorHandler !== false;
103
+ // Suppress console.warn for auth-related warnings during tests
104
+ const originalWarn = console.warn;
105
+ console.warn = (...args) => {
106
+ const message = args[0];
107
+ if (typeof message === 'string' && message.includes('auto-refresh')) {
108
+ return; // Suppress auto-refresh warnings
109
+ }
110
+ originalWarn(...args);
111
+ };
112
+ // Suppress console.error for expected error scenarios during tests
113
+ const originalError = console.error;
114
+ console.error = (...args) => {
115
+ const message = args[0];
116
+ // Suppress HttpErrorResponse logs
117
+ if (message && typeof message === 'object' && 'name' in message && message.name === 'HttpErrorResponse') {
118
+ return;
119
+ }
120
+ // Suppress bearer token decryption errors
121
+ if (typeof message === 'string' && message.includes('Failed to decrypt bearer token')) {
122
+ return;
123
+ }
124
+ // Suppress token extraction errors
125
+ if (typeof message === 'string' && message.includes('Failed to extract tokens from')) {
126
+ return;
127
+ }
128
+ originalError(...args);
129
+ };
130
+ const providers = [
131
+ provideHttpClient(),
132
+ provideHttpClientTesting(),
133
+ provideRouter([]),
134
+ ];
135
+ if (mockErrorHandler) {
136
+ providers.push({
137
+ provide: ErrorHandler,
138
+ useValue: { handleError: () => undefined },
139
+ });
140
+ }
141
+ TestBed.configureTestingModule({ providers });
142
+ const queryClientRef = createQueryClient({ baseUrl, name });
143
+ const setup = TestBed.runInInjectionContext(() => {
144
+ const [, inject] = queryClientRef;
145
+ const queryClient = inject();
146
+ if (!queryClient) {
147
+ throw new Error('Failed to create query client in test setup');
148
+ }
149
+ return {
150
+ queryClient,
151
+ queryClientRef,
152
+ httpClient: TestBed.inject(HttpClient),
153
+ httpTesting: TestBed.inject(HttpTestingController),
154
+ injector: TestBed.inject(Injector),
155
+ baseUrl,
156
+ createGet: createGetQuery(queryClientRef),
157
+ createPost: createPostQuery(queryClientRef),
158
+ createPut: createPutQuery(queryClientRef),
159
+ createPatch: createPatchQuery(queryClientRef),
160
+ createDelete: createDeleteQuery(queryClientRef),
161
+ };
162
+ });
163
+ // Restore console.warn and console.error when tests are done
164
+ const restoreConsole = () => {
165
+ console.warn = originalWarn;
166
+ console.error = originalError;
167
+ };
168
+ // Store the restore function for cleanup
169
+ setup._restoreConsole = restoreConsole;
170
+ return setup;
171
+ };
172
+
173
+ /**
174
+ * Generated bundle index. Do not edit.
175
+ */
176
+
177
+ export { expectAndFlush, expectFlushAndWait, setupAuthTest, setupQueryTest };
178
+ //# sourceMappingURL=ethlete-query-testing.mjs.map
@@ -0,0 +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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"}