UNPKG

@twilio-labs/serverless-api

Version:
176 lines (175 loc) 7.66 kB
"use strict"; /** @module @twilio-labs/serverless-api/dist/api */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; 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>} */ function createFunctionResource(name, serviceSid, client) { return __awaiter(this, void 0, void 0, function* () { try { const resp = yield 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 */ function listFunctionResources(serviceSid, client) { return __awaiter(this, void 0, void 0, function* () { 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[]>} */ function getOrCreateFunctionResources(functions, serviceSid, client) { return __awaiter(this, void 0, void 0, function* () { const output = []; const existingFunctions = yield listFunctionResources(serviceSid, client); const functionsToCreate = []; functions.forEach((fn) => { const existingFn = existingFunctions.find((f) => fn.name === f.friendly_name); if (!existingFn) { functionsToCreate.push(Object.assign({}, fn)); } else { output.push(Object.assign(Object.assign({}, fn), { sid: existingFn.sid })); } }); const createdFunctions = yield Promise.all(functionsToCreate.map((fn) => __awaiter(this, void 0, void 0, function* () { const newFunction = yield createFunctionResource(fn.name, serviceSid, client); return Object.assign(Object.assign({}, 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>} */ function createFunctionVersion(fn, serviceSid, client, clientConfig) { return __awaiter(this, void 0, void 0, function* () { try { const contentType = (yield (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 = yield 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>} */ function uploadFunction(fn, serviceSid, client, clientConfig) { return __awaiter(this, void 0, void 0, function* () { const version = yield 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; function listFunctionVersions(serviceSid, functionSid, client) { return __awaiter(this, void 0, void 0, function* () { const resp = yield client.request('get', `Services/${serviceSid}/Functions/${functionSid}/Versions`); return resp.body; }); } exports.listFunctionVersions = listFunctionVersions; function downloadFunctionVersion(serviceSid, functionSid, functionVersionSid, client) { return __awaiter(this, void 0, void 0, function* () { const resp = yield client.request('get', `Services/${serviceSid}/Functions/${functionSid}/Versions/${functionVersionSid}/Content`); return resp.body; }); } exports.downloadFunctionVersion = downloadFunctionVersion;