import { MultipartData } from '@src/utils/MultipartData' ; import { Client as Undici , request } from 'undici' ; import { DiscordooError } from '@src/utils' ; import { Client } from '@src/core' ; import { RestFinishedResponse , RestProvider , RestRequestData , RestRequestOptions } from '@discordoo/providers' ; import { CompletedRestOptions } from '@src/rest/interfaces/CompletedRestOptions' ; import * as process from 'process' ; export class DefaultRestProvider implements RestProvider { public client : Client ; public options : CompletedRestOptions ; private readonly undici : Undici ; constructor ( client , options ) { this . client = client ; this . options = options ; this . undici = new Undici ( `${ this . options . scheme }://${ this . options . domain }/` ) ; } async init ( ) { return undefined ; } async request < T = any > ( data , options = { } ) { let headers = this . options . headers ; headers [ 'Authorization' ] = options . auth ?? this . options . auth ; if ( this . options . userAgent ) { headers [ 'User-Agent' ] = this . options . userAgent ; } if ( options . reason ) { headers [ 'X-Audit-Log-Reason' ] = options . reason ; } if ( data . headers ) { headers = { ... headers , ... data . headers } ; } let body ; if ( data . attachments . length ) { const multipart = new MultipartData ( ) ; headers [ 'Content-Type' ] = 'multipart/form-data; boundary=' + multipart . boundary ; if ( data . attachments . length === 1 ) { const attachment = data . attachments [ 0 ] ; multipart . attach ( 'file' , attachment . data , attachment . name ) ; } else { data . attachments . forEach ( attachment => { multipart . attach ( attachment . name , attachment . data , attachment . name ) ; } ) ; } if ( data . body ) { multipart . attach ( 'payload_json' , JSON . stringify ( data . body ) ) ; } body = multipart . finish ( ) ; } else if ( data . body ) { headers [ 'Content-Type' ] = 'application/json' ; body = JSON . stringify ( data . body ) ; } const before = process . hrtime . bigint ( ) ; const response = await request ( `${ this . options . scheme }://${ this . options . domain }/api/v${ this . options . version }/${ data . path }` , { dispatcher : this . undici , method : data . method , body , headers , headersTimeout : this . options . requestTimeout , bodyTimeout : this . options . requestTimeout , } ) ; const after = process . hrtime . bigint ( ) ; let result = await response . body . text ( ) , success = response . statusCode > 199 && response . statusCode < 400 ; try { if ( response . statusCode !== 204 ) result = JSON . parse ( result ) ; } catch ( e ) { success = false ; result = new DiscordooError ( 'DefaultRestProvider#request' , 'failed to parse response:' , result ) ; } return { success , result , statusCode : response . statusCode , headers : response . headers , latency : Number ( after - before ) / 1000000 , } ; } }