import FormData from "form-data" ; import { ReadStream } from "fs" ; import { ApiKeyValidator } from "./apikey" ; import { RequestBuilder } from "./interfaces" ; import { retryRequest } from "./retry" ; /** Multipart payload destined to be sent to Datadog's API
 */ export interface MultipartPayload { content : Map < string , MultipartValue > ; } export interface MultipartValue { options ? : FormData . AppendOptions | string ; value : string | ReadStream ; } export interface UploadOptions { /** ApiKeyValidator (optional) throws an InvalidConfigurationException when upload fails because
     * of an invalid API key. Callers should most likely catch this exception and display it as a
     * nice error message.
     */ apiKeyValidator ? : ApiKeyValidator ; /** Retries is the amount of upload retries before giving up. Some requests are never retried
     * (400, 413).
     */ retries : number ; /** Callback when upload fails (retries are not considered as failure)
     */ onError ( error ) : void ; /** Callback to execute before retries
     */ onRetry ( error , attempts ) : void ; /** Callback to execute before upload.
     */ onUpload ( ) : void ; } export enum UploadStatus { Success , Failure , Skipped } /** Upload a MultipartPayload to Datadog's API using the provided RequestBuilder.
 * This handles retries as well as logging information about upload if a logger is provided in
 * the options
 */ export const upload = ( requestBuilder ) => async ( payload , opts ) : Promise < UploadStatus > => { opts . onUpload ( ) ; try { await retryRequest ( ( ) => uploadMultipart ( requestBuilder , payload ) , { onRetry : opts . onRetry , retries : opts . retries , } ) ; return UploadStatus . Success ; } catch ( error ) { if ( opts . apiKeyValidator ) { await opts . apiKeyValidator . verifyApiKey ( error ) ; } if ( error . response && error . response . statusText ) { opts . onError ( new Error ( `${ error . message } (${ error . response . statusText })` ) ) ; } else { opts . onError ( error ) ; } return UploadStatus . Failure ; } } ; const maxBodyLength = Infinity ; const uploadMultipart = async ( request , payload ) => { const form = new FormData ( ) ; payload . content . forEach ( ( value , key ) => { form . append ( key , value . value , value . options ) ; } ) ; return request ( { data : form , headers : form . getHeaders ( ) , maxBodyLength , method : "POST" , url : "v1/input" , } ) ; } ;