2023-10-26 04:27:07 +08:00
import { isPlainObject } from "is-plain-object" ;
2022-11-04 00:55:07 +08:00
import { RequestError } from "@octokit/request-error" ;
import getBuffer from "./get-buffer-response" ;
2023-10-26 04:27:07 +08:00
function fetchWrapper ( requestOptions ) {
const log = requestOptions . request && requestOptions . request . log ? requestOptions . request . log : console ;
const parseSuccessResponseBody = requestOptions . request ? . parseSuccessResponseBody !== false ;
if ( isPlainObject ( requestOptions . body ) || Array . isArray ( requestOptions . body ) ) {
requestOptions . body = JSON . stringify ( requestOptions . body ) ;
}
let headers = { } ;
let status ;
let url ;
let { fetch } = globalThis ;
if ( requestOptions . request ? . fetch ) {
fetch = requestOptions . request . fetch ;
}
if ( ! fetch ) {
throw new Error (
"fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing"
) ;
}
return fetch ( requestOptions . url , {
method : requestOptions . method ,
body : requestOptions . body ,
headers : requestOptions . headers ,
signal : requestOptions . request ? . signal ,
// duplex must be set if request.body is ReadableStream or Async Iterables.
// See https://fetch.spec.whatwg.org/#dom-requestinit-duplex.
... requestOptions . body && { duplex : "half" }
} ) . then ( async ( response ) => {
url = response . url ;
status = response . status ;
for ( const keyAndValue of response . headers ) {
headers [ keyAndValue [ 0 ] ] = keyAndValue [ 1 ] ;
2022-11-04 00:55:07 +08:00
}
2023-10-26 04:27:07 +08:00
if ( "deprecation" in headers ) {
const matches = headers . link && headers . link . match ( /<([^>]+)>; rel="deprecation"/ ) ;
const deprecationLink = matches && matches . pop ( ) ;
log . warn (
` [@octokit/request] " ${ requestOptions . method } ${ requestOptions . url } " is deprecated. It is scheduled to be removed on ${ headers . sunset } ${ deprecationLink ? ` . See ${ deprecationLink } ` : "" } `
) ;
}
if ( status === 204 || status === 205 ) {
return ;
}
if ( requestOptions . method === "HEAD" ) {
if ( status < 400 ) {
return ;
}
throw new RequestError ( response . statusText , status , {
response : {
url ,
status ,
headers ,
data : void 0
} ,
request : requestOptions
} ) ;
}
if ( status === 304 ) {
throw new RequestError ( "Not modified" , status , {
response : {
url ,
status ,
headers ,
data : await getResponseData ( response )
} ,
request : requestOptions
} ) ;
}
if ( status >= 400 ) {
const data = await getResponseData ( response ) ;
const error = new RequestError ( toErrorMessage ( data ) , status , {
response : {
url ,
status ,
headers ,
data
} ,
request : requestOptions
} ) ;
throw error ;
}
return parseSuccessResponseBody ? await getResponseData ( response ) : response . body ;
} ) . then ( ( data ) => {
return {
status ,
url ,
headers ,
data
} ;
} ) . catch ( ( error ) => {
if ( error instanceof RequestError )
throw error ;
else if ( error . name === "AbortError" )
throw error ;
let message = error . message ;
if ( error . name === "TypeError" && "cause" in error ) {
if ( error . cause instanceof Error ) {
message = error . cause . message ;
} else if ( typeof error . cause === "string" ) {
message = error . cause ;
}
}
throw new RequestError ( message , 500 , {
request : requestOptions
2022-11-04 00:55:07 +08:00
} ) ;
2023-10-26 04:27:07 +08:00
} ) ;
}
async function getResponseData ( response ) {
const contentType = response . headers . get ( "content-type" ) ;
if ( /application\/json/ . test ( contentType ) ) {
return response . json ( ) ;
}
if ( ! contentType || /^text\/|charset=utf-8$/ . test ( contentType ) ) {
return response . text ( ) ;
}
return getBuffer ( response ) ;
}
function toErrorMessage ( data ) {
if ( typeof data === "string" )
return data ;
if ( "message" in data ) {
if ( Array . isArray ( data . errors ) ) {
return ` ${ data . message } : ${ data . errors . map ( JSON . stringify ) . join ( ", " ) } ` ;
}
return data . message ;
}
return ` Unknown error: ${ JSON . stringify ( data ) } ` ;
2022-11-04 00:55:07 +08:00
}
2023-10-26 04:27:07 +08:00
export {
fetchWrapper as default
} ;