UNPKG

@twilio-labs/serverless-api

Version:
159 lines (158 loc) 6.26 kB
"use strict"; /** @module @twilio-labs/serverless-api/dist/api */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.downloadFunctionVersion = exports.listFunctionVersions = exports.isFunctionSid = exports.uploadFunction = exports.getOrCreateFunctionResources = exports.listFunctionResources = exports.createFunctionResource = void 0; const debug_1 = __importDefault(require("debug")); const form_data_1 = __importDefault(require("form-data")); const content_type_1 = require("../utils/content-type"); const error_1 = require("../utils/error"); const api_client_1 = require("./utils/api-client"); const pagination_1 = require("./utils/pagination"); const log = (0, debug_1.default)('twilio-serverless-api:functions'); /** * Creates a new Function instance by calling the API * * @param {string} name the friendly name of the function to create * @param {string} serviceSid the service the function should belong to * @param {TwilioServerlessApiClient} client API client * @returns {Promise<FunctionApiResource>} */ async function createFunctionResource(name, serviceSid, client) { try { const resp = await client.request('post', `Services/${serviceSid}/Functions`, { form: { FriendlyName: name, }, }); return resp.body; } catch (err) { log('%O', new error_1.ClientApiError(err)); throw new Error(`Failed to create "${name}" function`); } } exports.createFunctionResource = createFunctionResource; /** * Lists all functions associated to a service * * @export * @param {string} serviceSid the service to look up * @param {TwilioServerlessApiClient} client API client * @returns */ async function listFunctionResources(serviceSid, client) { try { return (0, pagination_1.getPaginatedResource)(client, `Services/${serviceSid}/Functions`); } catch (err) { log('%O', new error_1.ClientApiError(err)); throw err; } } exports.listFunctionResources = listFunctionResources; /** * Given a list of functions it will create the ones that don't exist and retrieves the others * * @export * @param {FileInfo[]} functions list of functions to get or create * @param {string} serviceSid service the functions belong to * @param {TwilioServerlessApiClient} client API client * @returns {Promise<FunctionResource[]>} */ async function getOrCreateFunctionResources(functions, serviceSid, client) { const output = []; const existingFunctions = await listFunctionResources(serviceSid, client); const functionsToCreate = []; functions.forEach((fn) => { const existingFn = existingFunctions.find((f) => fn.name === f.friendly_name); if (!existingFn) { functionsToCreate.push({ ...fn }); } else { output.push({ ...fn, sid: existingFn.sid, }); } }); const createdFunctions = await Promise.all(functionsToCreate.map(async (fn) => { const newFunction = await createFunctionResource(fn.name, serviceSid, client); return { ...fn, sid: newFunction.sid, }; })); return [...output, ...createdFunctions]; } exports.getOrCreateFunctionResources = getOrCreateFunctionResources; /** * Creates a new Version to be used for uploading a new function * * @param {FunctionResource} fn the function the version should be created for * @param {string} serviceSid the service related to the function * @param {TwilioServerlessApiClient} client API client * @returns {Promise<VersionResource>} */ async function createFunctionVersion(fn, serviceSid, client, clientConfig) { try { const contentType = (await (0, content_type_1.getContentType)(fn.content, fn.filePath || 'application/json')) || 'application/javascript'; log('Uploading asset via form data with content-type "%s"', contentType); const contentOpts = { filename: fn.name, contentType: contentType, }; const form = new form_data_1.default(); form.append('Path', fn.path); form.append('Visibility', fn.access); form.append('Content', fn.content, contentOpts); const resp = await client.request('post', `Services/${serviceSid}/Functions/${fn.sid}/Versions`, { responseType: 'text', prefixUrl: (0, api_client_1.getApiUrl)(clientConfig, 'serverless-upload'), body: form, }); return JSON.parse(resp.body); } catch (err) { log('%O', new error_1.ClientApiError(err)); throw new Error(`Failed to upload Function ${fn.name}`); } } /** * Uploads a given function by creating a new version, reading the content if necessary and uploading the content * * @export * @param {FunctionResource} fn function to be uploaded * @param {string} serviceSid service that the function is connected to * @param {TwilioServerlessApiClient} client API client * @returns {Promise<Sid>} */ async function uploadFunction(fn, serviceSid, client, clientConfig) { const version = await createFunctionVersion(fn, serviceSid, client, clientConfig); return version.sid; } exports.uploadFunction = uploadFunction; /** * Checks if a string is an function SID by checking its prefix and length * * @export * @param {string} str the string to check * @returns */ function isFunctionSid(str) { return str.startsWith('ZH') && str.length === 34; } exports.isFunctionSid = isFunctionSid; async function listFunctionVersions(serviceSid, functionSid, client) { const resp = await client.request('get', `Services/${serviceSid}/Functions/${functionSid}/Versions`); return resp.body; } exports.listFunctionVersions = listFunctionVersions; async function downloadFunctionVersion(serviceSid, functionSid, functionVersionSid, client) { const resp = await client.request('get', `Services/${serviceSid}/Functions/${functionSid}/Versions/${functionVersionSid}/Content`); return resp.body; } exports.downloadFunctionVersion = downloadFunctionVersion;