11import cheerio from 'cheerio'
2- import got , { Response , OptionsOfTextResponseBody , Method } from 'got '
2+ import { fetchWithRetry } from '@/frame/lib/fetch-utils '
33import { omitBy , isUndefined } from 'lodash-es'
44
55type ResponseTypes = 'buffer' | 'json' | 'text'
@@ -9,8 +9,8 @@ type ResponseTypeMap = {
99 text : string
1010}
1111
12- interface GetOptions < ResponseType extends ResponseTypes = 'text' , M extends Method = 'get' > {
13- method ?: M
12+ interface GetOptions < ResponseType extends ResponseTypes = 'text' > {
13+ method ?: string
1414 body ?: any
1515 followRedirects ?: boolean
1616 followAllRedirects ?: boolean
@@ -26,12 +26,16 @@ interface GetDOMOptions {
2626 retries ?: number
2727}
2828
29- interface ResponseWithHeaders < T > extends Response < T > {
29+ interface ResponseWithHeaders < T > {
30+ body : T
31+ statusCode : number
3032 headers : Record < string , string >
33+ url : string
34+ ok : boolean
3135}
3236
3337// Type alias for cached DOM results to improve maintainability
34- type CachedDOMResult = cheerio . Root & { res : Response ; $ : cheerio . Root }
38+ type CachedDOMResult = cheerio . Root & { res : ResponseWithHeaders < string > ; $ : cheerio . Root }
3539
3640// Cache to store DOM objects
3741const getDOMCache = new Map < string , CachedDOMResult > ( )
@@ -43,43 +47,62 @@ const getDOMCache = new Map<string, CachedDOMResult>()
4347 * @param options - Configuration options for the request.
4448 * @returns A promise that resolves to the HTTP response.
4549 */
46- export async function get < T extends ResponseTypes = 'text' , M extends Method = 'get' > (
50+ export async function get < T extends ResponseTypes = 'text' > (
4751 route : string ,
48- options : GetOptions < T , M > = { } ,
52+ options : GetOptions < T > = { } ,
4953) : Promise < ResponseWithHeaders < ResponseTypeMap [ T ] > > {
5054 const {
5155 method = 'get' ,
52- body,
56+ body : requestBody ,
5357 followRedirects = false ,
5458 followAllRedirects = false ,
5559 headers = { } ,
5660 responseType,
5761 retries = 0 ,
5862 } = options
5963
60- // Ensure the method is a valid function on `got`
61- const fn = got [ method as 'get' ]
62- if ( ! fn || typeof fn !== 'function' ) {
63- throw new Error ( `No method function for '${ method } '` )
64- }
65-
66- // Construct the options for the `got` request, omitting undefined values
67- const xopts : OptionsOfTextResponseBody = omitBy (
64+ // Construct the options for the fetch request
65+ const fetchOptions : RequestInit = omitBy (
6866 {
69- body,
70- headers,
71- retry : { limit : retries } ,
72- throwHttpErrors : false ,
73- followRedirect : followAllRedirects || followRedirects ,
74- responseType : responseType || undefined ,
67+ method : method . toUpperCase ( ) ,
68+ body : requestBody ,
69+ headers : headers as HeadersInit ,
70+ redirect : followAllRedirects || followRedirects ? 'follow' : 'manual' ,
7571 } ,
7672 isUndefined ,
7773 )
7874
7975 // Perform the HTTP request
80- return ( await fn ( `http://localhost:4000${ route } ` , xopts ) ) as ResponseWithHeaders <
81- ResponseTypeMap [ T ]
82- >
76+ const response = await fetchWithRetry ( `http://localhost:4000${ route } ` , fetchOptions , {
77+ retries,
78+ throwHttpErrors : false ,
79+ } )
80+
81+ // Get response body based on responseType
82+ let responseBody : ResponseTypeMap [ T ]
83+ if ( responseType === 'json' ) {
84+ responseBody = ( await response . json ( ) ) as ResponseTypeMap [ T ]
85+ } else if ( responseType === 'buffer' ) {
86+ const arrayBuffer = await response . arrayBuffer ( )
87+ responseBody = arrayBuffer as ResponseTypeMap [ T ]
88+ } else {
89+ responseBody = ( await response . text ( ) ) as ResponseTypeMap [ T ]
90+ }
91+
92+ // Convert headers to record format
93+ const headersRecord : Record < string , string > = { }
94+ response . headers . forEach ( ( value , key ) => {
95+ headersRecord [ key ] = value
96+ } )
97+
98+ // Return response in got-compatible format
99+ return {
100+ body : responseBody ,
101+ statusCode : response . status ,
102+ headers : headersRecord ,
103+ url : response . url ,
104+ ok : response . ok ,
105+ } as ResponseWithHeaders < ResponseTypeMap [ T ] >
83106}
84107
85108/**
@@ -92,7 +115,7 @@ export async function get<T extends ResponseTypes = 'text', M extends Method = '
92115export async function head (
93116 route : string ,
94117 opts : { followRedirects ?: boolean } = { followRedirects : false } ,
95- ) : Promise < Response < string > > {
118+ ) : Promise < ResponseWithHeaders < string > > {
96119 const res = await get ( route , { method : 'head' , followRedirects : opts . followRedirects } )
97120 return res
98121}
@@ -107,7 +130,7 @@ export async function head(
107130export function post (
108131 route : string ,
109132 opts : Omit < GetOptions , 'method' > = { } ,
110- ) : Promise < Response < string > > {
133+ ) : Promise < ResponseWithHeaders < string > > {
111134 return get ( route , { ...opts , method : 'post' } )
112135}
113136
0 commit comments