module twilio-labs import debug from 'debug' ; import FormData from 'form-data' ; import { AssetApiResource , AssetList , AssetResource , ServerlessResourceConfig , Sid , VersionResource , ClientConfig , } from '../types' ; import { TwilioServerlessApiClient } from '../client' ; import { getContentType } from '../utils/content-type' ; import { ClientApiError } from '../utils/error' ; import { getApiUrl } from './utils/api-client' ; import { getPaginatedResource } from './utils/pagination' ; const log = debug ( 'twilio-serverless-api:assets' ) ; param { string } name param { string } serviceSid param { TwilioServerlessApiClient } client returns { Promise < AssetApiResource > } export async function createAssetResource ( name , serviceSid , client ) { try { const resp = await client . request ( 'post' , `Services/${ serviceSid }/Assets` , { form : { FriendlyName : name , } , } ) ; return ( resp . body as unknown ) as AssetApiResource ; } catch ( err ) { log ( '%O' , new ClientApiError ( err ) ) ; throw new Error ( `Failed to create "${ name }" asset` ) ; } } param { string } serviceSid param { TwilioServerlessApiClient } client returns { Promise < AssetApiResource [ ] > } export async function listAssetResources ( serviceSid , client ) { try { return getPaginatedResource < AssetList , AssetApiResource > ( client , `Services/${ serviceSid }/Assets` ) ; } catch ( err ) { log ( '%O' , new ClientApiError ( err ) ) ; throw err ; } } param { FileInfo [ ] } assets param { string } serviceSid param { TwilioServerlessApiClient } client returns { Promise < AssetResource [ ] > } export async function getOrCreateAssetResources ( assets , serviceSid , client ) { const output = [ ] ; const existingAssets = await listAssetResources ( serviceSid , client ) ; const assetsToCreate = [ ] ; assets . forEach ( asset => { const existingAsset = existingAssets . find ( x => asset . name === x . friendly_name ) ; if ( ! existingAsset ) { assetsToCreate . push ( asset ) ; } else { output . push ( { ... asset , sid : existingAsset . sid , } ) ; } } ) ; const createdAssets = await Promise . all ( assetsToCreate . map ( async ( asset ) => { const newAsset = await createAssetResource ( asset . name , serviceSid , client ) ; return { ... asset , sid : newAsset . sid , } ; } ) ) ; return [ ... output , ... createdAssets ] ; } param { AssetResource } asset param { string } serviceSid param { TwilioServerlessApiClient } client returns { Promise < VersionResource > } export async function createAssetVersion ( asset , serviceSid , client , clientConfig ) { try { const contentType = await getContentType ( asset . content , asset . filePath || asset . name ) ; log ( 'Uploading asset via form data with content-type "%s"' , contentType ) ; const contentOpts = { filename : asset . name , contentType : contentType , } ; const form = new FormData ( ) ; form . append ( 'Path' , asset . path ) ; form . append ( 'Visibility' , asset . access ) ; form . append ( 'Content' , asset . content , contentOpts ) ; const resp = await client . request ( 'post' , `Services/${ serviceSid }/Assets/${ asset . sid }/Versions` , { responseType : 'text' , prefixUrl : getApiUrl ( clientConfig , 'serverless-upload' ) , body : form , } ) ; return JSON . parse ( resp . body ) as VersionResource ; } catch ( err ) { log ( '%O' , new ClientApiError ( err ) ) ; throw new Error ( `Failed to upload Asset ${ asset && ( asset . name || asset . filePath ) }` ) ; } } export param { AssetResource } asset param { string } serviceSid param { TwilioServerlessApiClient } client returns { Promise < Sid > } export async function uploadAsset ( asset , serviceSid , client , clientConfig ) { const version = await createAssetVersion ( asset , serviceSid , client , clientConfig ) ; return version . sid ; }