-
Notifications
You must be signed in to change notification settings - Fork 472
Expand file tree
/
Copy pathuse-clerk-query-client.ts
More file actions
69 lines (61 loc) · 1.96 KB
/
Copy pathuse-clerk-query-client.ts
File metadata and controls
69 lines (61 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import type { QueryClient } from '@tanstack/query-core';
import { getClerkQueryClient } from './clerk-query-client';
export type RecursiveMock = {
(...args: unknown[]): RecursiveMock;
} & {
readonly [key in string | symbol]: RecursiveMock;
};
/**
* Creates a recursively self-referential Proxy that safely handles:
* - Arbitrary property access (e.g., obj.any.prop.path)
* - Function calls at any level (e.g., obj.a().b.c())
* - Construction (e.g., new obj.a.b())
*
* Always returns itself to allow infinite chaining without throwing.
*/
function createRecursiveProxy(label: string): RecursiveMock {
// The callable target for the proxy so that `apply` works
const callableTarget = function noop(): void {};
// eslint-disable-next-line prefer-const
let self: RecursiveMock;
const handler: ProxyHandler<typeof callableTarget> = {
get(_target, prop) {
// Avoid being treated as a Promise/thenable by test runners or frameworks
if (prop === 'then') {
return undefined;
}
if (prop === 'toString') {
return () => `[${label}]`;
}
if (prop === Symbol.toPrimitive) {
return () => 0;
}
return self;
},
apply() {
return self;
},
construct() {
return self as unknown as object;
},
has() {
return false;
},
set() {
return false;
},
};
self = new Proxy(callableTarget, handler) as unknown as RecursiveMock;
return self;
}
const mockQueryClient = createRecursiveProxy('ClerkMockQueryClient') as unknown as QueryClient;
/**
* Returns `[client, isLoaded]`. The real client is owned by `@clerk/shared`
* and lazily instantiated on the browser only — SSR returns the proxy mock
* + `isLoaded: false` so per-request renders never share a query cache.
*/
const useClerkQueryClient = (): [QueryClient, boolean] => {
const client = getClerkQueryClient();
return [client ?? mockQueryClient, Boolean(client)];
};
export { useClerkQueryClient };