Skip to content

Commit 6cb7ee0

Browse files
committed
fix(apiOptions): prevent empty options from being included in queryKey
1 parent 4dda701 commit 6cb7ee0

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

static/app/utils/api/apiOptions.spec.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ describe('apiOptions', () => {
4040
]);
4141
});
4242

43+
it('should not include options in queryKey when all values are undefined', () => {
44+
const options = apiOptions.as<unknown>()('/api-tokens/$tokenId/', {
45+
staleTime: 0,
46+
path: {tokenId: '123'},
47+
query: undefined,
48+
method: undefined,
49+
});
50+
51+
expect(options.queryKey).toEqual([
52+
{infinite: false, version: 'v2'},
53+
'/api-tokens/123/',
54+
]);
55+
});
56+
4357
it('should stringify number path params', () => {
4458
const options = apiOptions.as<unknown>()('/api-tokens/$tokenId/', {
4559
staleTime: 0,

static/app/utils/api/apiOptions.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ import {parseLinkHeader} from 'sentry/utils/parseLinkHeader';
1616

1717
type KnownApiUrls = KnownGetsentryApiUrls | KnownSentryApiUrls;
1818

19-
type Options = QueryKeyEndpointOptions & {staleTime: number};
19+
type Options = QueryKeyEndpointOptions & {staleTime: number | 'static'};
2020

2121
type PathParamOptions<TApiPath extends string> =
2222
ExtractPathParams<TApiPath> extends never
2323
? {path?: never}
2424
: {path: Record<ExtractPathParams<TApiPath>, string | number> | SkipToken};
2525

26+
function hasDefinedValues(obj: Record<string, unknown>): boolean {
27+
return Object.values(obj).some(v => v !== undefined);
28+
}
29+
2630
const selectJson = <TData>(data: ApiResponse<TData>) => data.json;
2731

2832
export const selectJsonWithHeaders = <TData>(
@@ -45,10 +49,9 @@ function _apiOptions<
4549
const url = getApiUrl(path, ...([{path: pathParams}] as OptionalPathParams<TApiPath>));
4650

4751
return queryOptions({
48-
queryKey:
49-
Object.keys(options).length > 0
50-
? ([{infinite: false, version: 'v2'}, url, options] as ApiQueryKey)
51-
: ([{infinite: false, version: 'v2'}, url] as ApiQueryKey),
52+
queryKey: hasDefinedValues(options)
53+
? ([{infinite: false, version: 'v2'}, url, options] as ApiQueryKey)
54+
: ([{infinite: false, version: 'v2'}, url] as ApiQueryKey),
5255
queryFn: pathParams === skipToken ? skipToken : apiFetch<TActualData>,
5356
enabled: pathParams !== skipToken,
5457
staleTime,
@@ -79,10 +82,9 @@ function _apiOptionsInfinite<
7982
const url = getApiUrl(path, ...([{path: pathParams}] as OptionalPathParams<TApiPath>));
8083

8184
return infiniteQueryOptions({
82-
queryKey:
83-
Object.keys(options).length > 0
84-
? ([{infinite: true, version: 'v2'}, url, options] as InfiniteApiQueryKey)
85-
: ([{infinite: true, version: 'v2'}, url] as InfiniteApiQueryKey),
85+
queryKey: hasDefinedValues(options)
86+
? ([{infinite: true, version: 'v2'}, url, options] as InfiniteApiQueryKey)
87+
: ([{infinite: true, version: 'v2'}, url] as InfiniteApiQueryKey),
8688
queryFn: pathParams === skipToken ? skipToken : apiFetchInfinite<TActualData>,
8789
getPreviousPageParam: parsePageParam('previous'),
8890
getNextPageParam: parsePageParam('next'),

0 commit comments

Comments
 (0)