Skip to content

Commit 2270126

Browse files
adhityamamallanAssem-Uber
authored andcommitted
Add useConfigValue hook (#804)
Add useConfigValue hook that sends a query to the Config API route for config value Add some extra types to dynamic config util and API route
1 parent c58405a commit 2270126

File tree

5 files changed

+143
-3
lines changed

5 files changed

+143
-3
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { HttpResponse } from 'msw';
2+
3+
import { renderHook, waitFor } from '@/test-utils/rtl';
4+
5+
import useConfigValue from '../use-config-value';
6+
7+
describe(useConfigValue.name, () => {
8+
it('should return correct loading state and result', async () => {
9+
const { result } = setup({});
10+
11+
expect(result.current.isLoading).toStrictEqual(true);
12+
13+
await waitFor(() => {
14+
const value = result.current.data;
15+
expect(value).toStrictEqual('mock_config_response');
16+
});
17+
});
18+
19+
it('should return error if the API route errors out', async () => {
20+
const { result } = setup({ error: true });
21+
22+
await waitFor(() => {
23+
const res = result.current;
24+
expect(res.status).toEqual('error');
25+
});
26+
});
27+
});
28+
29+
function setup({ error }: { error?: boolean }) {
30+
const { result } = renderHook(
31+
() =>
32+
// @ts-expect-error - using a nonexistent config value
33+
useConfigValue('MOCK_CONFIG_VALUE', { arg: 'value' }),
34+
{
35+
endpointsMocks: [
36+
{
37+
path: '/api/config',
38+
httpMethod: 'GET',
39+
mockOnce: false,
40+
httpResolver: async () => {
41+
if (error) {
42+
return HttpResponse.json(
43+
{ message: 'Failed to fetch config' },
44+
{ status: 500 }
45+
);
46+
} else {
47+
return HttpResponse.json('mock_config_response');
48+
}
49+
},
50+
},
51+
],
52+
}
53+
);
54+
55+
return { result };
56+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useQuery } from '@tanstack/react-query';
2+
import queryString from 'query-string';
3+
4+
import {
5+
type GetConfigResponse,
6+
type GetConfigArgs,
7+
type GetConfigKeys,
8+
type GetConfigKeysWithArgs,
9+
type GetConfigKeysWithoutArgs,
10+
type GetConfigRequestQuery,
11+
} from '@/route-handlers/get-config/get-config.types';
12+
import request from '@/utils/request';
13+
import { type RequestError } from '@/utils/request/request-error';
14+
15+
import { type UseConfigValueResult } from './use-config-value.types';
16+
17+
export default function useConfigValue<K extends GetConfigKeysWithArgs>(
18+
key: K,
19+
args: GetConfigArgs<K>
20+
): UseConfigValueResult<K>;
21+
22+
export default function useConfigValue<K extends GetConfigKeysWithoutArgs>(
23+
key: K
24+
): UseConfigValueResult<K>;
25+
26+
export default function useConfigValue<K extends GetConfigKeys>(
27+
key: K,
28+
args?: GetConfigArgs<K>
29+
): UseConfigValueResult<K> {
30+
return useQuery<
31+
GetConfigResponse<K>,
32+
RequestError,
33+
GetConfigResponse<K>,
34+
[string, GetConfigRequestQuery<K>]
35+
>({
36+
queryKey: ['dynamic_config', { configKey: key, jsonArgs: args }] as const,
37+
queryFn: ({ queryKey: [_, { configKey, jsonArgs }] }) =>
38+
request(
39+
queryString.stringifyUrl({
40+
url: '/api/config',
41+
query: {
42+
configKey,
43+
jsonArgs: JSON.stringify(jsonArgs),
44+
},
45+
}),
46+
{
47+
method: 'GET',
48+
}
49+
).then((res) => res.json()),
50+
});
51+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { type UseQueryResult } from '@tanstack/react-query';
2+
3+
import {
4+
type GetConfigKeys,
5+
type GetConfigResponse,
6+
} from '@/route-handlers/get-config/get-config.types';
7+
import { type RequestError } from '@/utils/request/request-error';
8+
9+
export type UseConfigValueResult<K extends GetConfigKeys> = UseQueryResult<
10+
GetConfigResponse<K>,
11+
RequestError
12+
>;
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
import {
2+
type PublicLoadedResolvedValues,
23
type ArgsOfLoadedConfigResolver,
34
type PublicDynamicConfigKeys,
4-
type PublicLoadedConfig,
5+
type PublicConfigKeysWithArgs,
6+
type PublicConfigKeysWithoutArgs,
57
} from '@/utils/config/config.types';
68

7-
export type GetConfigResponse<K extends PublicDynamicConfigKeys> =
8-
PublicLoadedConfig[K];
99
export type GetConfigKeys = PublicDynamicConfigKeys;
10+
export type GetConfigKeysWithArgs = PublicConfigKeysWithArgs;
11+
export type GetConfigKeysWithoutArgs = PublicConfigKeysWithoutArgs;
12+
1013
export type GetConfigArgs<K extends PublicDynamicConfigKeys> =
1114
ArgsOfLoadedConfigResolver<K>;
15+
1216
export type GetConfigRequestQuery<K extends PublicDynamicConfigKeys> = {
1317
configKey: K;
1418
jsonArgs: GetConfigArgs<GetConfigKeys>;
1519
};
20+
21+
export type GetConfigResponse<K extends PublicDynamicConfigKeys> =
22+
PublicLoadedResolvedValues[K];

src/utils/config/config.types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ export type PublicDynamicConfigKeys = keyof PublicDynamicConfigDefinitions;
148148
export type PublicLoadedConfig =
149149
InferLoadedConfig<PublicDynamicConfigDefinitions>;
150150

151+
export type PublicLoadedResolvedValues =
152+
ConfigResolvedValues<PublicDynamicConfigDefinitions>;
153+
151154
export type LoadedConfigs = InferLoadedConfig<DynamicConfig>;
152155

153156
export type ArgsOfLoadedConfigResolver<K extends keyof LoadedConfigs> =
@@ -187,3 +190,14 @@ export type ResolverSchemas = InferResolverSchema<DynamicConfig>;
187190

188191
export type ArgsOfDynamicConfigResolver<K extends keyof ResolverSchemas> =
189192
ResolverSchemas[K]['args'];
193+
194+
export type PublicConfigKeysWithArgs = {
195+
[K in keyof PublicDynamicConfigDefinitions]: K extends ConfigKeysWithArgs
196+
? K
197+
: never;
198+
}[keyof PublicDynamicConfigDefinitions];
199+
200+
export type PublicConfigKeysWithoutArgs = Exclude<
201+
keyof PublicDynamicConfigDefinitions,
202+
PublicConfigKeysWithArgs
203+
>;

0 commit comments

Comments
 (0)