1- import { queryOptions , skipToken } from '@tanstack/react-query' ;
2- import type { SkipToken } from '@tanstack/react-query' ;
3-
4- import apiFetch , { type ApiResponse } from 'sentry/utils/api/apiFetch' ;
1+ import apiFetch , { apiFetchInfinite } from 'sentry/utils/api/apiFetch' ;
2+ import type { ApiResponse } from 'sentry/utils/api/apiFetch' ;
53import getApiUrl from 'sentry/utils/api/getApiUrl' ;
64import type { ExtractPathParams , OptionalPathParams } from 'sentry/utils/api/getApiUrl' ;
75import type { KnownGetsentryApiUrls } from 'sentry/utils/api/knownGetsentryApiUrls' ;
86import type { KnownSentryApiUrls } from 'sentry/utils/api/knownSentryApiUrls.generated' ;
9- import type { ApiQueryKey , QueryKeyEndpointOptions } from 'sentry/utils/queryClient' ;
7+ import parseLinkHeader , { type ParsedHeader } from 'sentry/utils/parseLinkHeader' ;
8+ import { infiniteQueryOptions , queryOptions , skipToken } from 'sentry/utils/queryClient' ;
9+ import type {
10+ ApiQueryKey ,
11+ InfiniteApiQueryKey ,
12+ InfiniteData ,
13+ QueryKeyEndpointOptions ,
14+ SkipToken ,
15+ } from 'sentry/utils/queryClient' ;
1016
1117type KnownApiUrls = KnownGetsentryApiUrls | KnownSentryApiUrls ;
1218
@@ -17,14 +23,6 @@ type PathParamOptions<TApiPath extends string> =
1723 ? { path ?: never }
1824 : { path : Record < ExtractPathParams < TApiPath > , string | number > | SkipToken } ;
1925
20- /** @public **/
21- export const selectJson = < TData > ( data : ApiResponse < TData > ) => data . json ;
22-
23- /** @public **/
24- export const selectJsonWithHeaders = < TData > (
25- data : ApiResponse < TData >
26- ) : ApiResponse < TData > => data ;
27-
2826function _apiOptions <
2927 TManualData = never ,
3028 TApiPath extends KnownApiUrls = KnownApiUrls ,
@@ -38,14 +36,7 @@ function _apiOptions<
3836 ? [ Options & { path ?: never } ]
3937 : [ Options & PathParamOptions < TApiPath > ]
4038) {
41- const url = getApiUrl (
42- path ,
43- ...( [
44- {
45- path : pathParams ,
46- } ,
47- ] as OptionalPathParams < TApiPath > )
48- ) ;
39+ const url = getApiUrl ( path , ...( [ { path : pathParams } ] as OptionalPathParams < TApiPath > ) ) ;
4940
5041 return queryOptions ( {
5142 queryKey :
@@ -55,7 +46,46 @@ function _apiOptions<
5546 queryFn : pathParams === skipToken ? skipToken : apiFetch < TActualData > ,
5647 enabled : pathParams !== skipToken ,
5748 staleTime,
58- select : selectJson ,
49+ select : data => data . json ,
50+ } ) ;
51+ }
52+
53+ function parsePageParam < TQueryFnData = unknown > ( dir : 'previous' | 'next' ) {
54+ return ( { headers} : ApiResponse < TQueryFnData > ) => {
55+ const parsed = parseLinkHeader ( headers . Link ?? null ) ;
56+ return parsed [ dir ] ?. results ? parsed [ dir ] : null ;
57+ } ;
58+ }
59+
60+ function _apiOptionsInfinite <
61+ TManualData = never ,
62+ TApiPath extends KnownApiUrls = KnownApiUrls ,
63+ // todo: infer the actual data type from the ApiMapping
64+ TActualData = TManualData ,
65+ > (
66+ path : TApiPath ,
67+ ...[
68+ { staleTime, path : pathParams , ...options } ,
69+ ] : ExtractPathParams < TApiPath > extends never
70+ ? [ Options & { path ?: never } ]
71+ : [ Options & PathParamOptions < TApiPath > ]
72+ ) {
73+ const url = getApiUrl ( path , ...( [ { path : pathParams } ] as OptionalPathParams < TApiPath > ) ) ;
74+
75+ return infiniteQueryOptions ( {
76+ queryKey :
77+ Object . keys ( options ) . length > 0
78+ ? ( [ 'infinite' , url , options ] as InfiniteApiQueryKey )
79+ : ( [ 'infinite' , url ] as InfiniteApiQueryKey ) ,
80+ queryFn : pathParams === skipToken ? skipToken : apiFetchInfinite < TActualData > ,
81+ getPreviousPageParam : parsePageParam ( 'previous' ) ,
82+ getNextPageParam : parsePageParam ( 'next' ) ,
83+ initialPageParam : undefined ,
84+ enabled : pathParams !== skipToken ,
85+ staleTime,
86+ select : (
87+ data : InfiniteData < ApiResponse < TActualData > , null | undefined | ParsedHeader >
88+ ) => data . pages . map ( page => page . json ) ,
5989 } ) ;
6090}
6191
@@ -67,4 +97,12 @@ export const apiOptions = {
6797 options : Options & PathParamOptions < TApiPath >
6898 ) =>
6999 _apiOptions < TManualData , TApiPath > ( path , options as never ) ,
100+
101+ asInfinite :
102+ < TManualData > ( ) =>
103+ < TApiPath extends KnownApiUrls = KnownApiUrls > (
104+ path : TApiPath ,
105+ options : Options & PathParamOptions < TApiPath >
106+ ) =>
107+ _apiOptionsInfinite < TManualData , TApiPath > ( path , options as never ) ,
70108} ;
0 commit comments