UNPKG

esa-cli

Version:

A CLI for operating Alibaba Cloud ESA EdgeRoutine (Edge Functions).

220 lines (219 loc) 10.8 kB
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()); }); }; import chalk from 'chalk'; import { getProjectConfig, readEdgeRoutineFile } from '../../utils/fileUtils/index.js'; import SelectItems from '../../components/selectInput.js'; import { Environment, PublishType } from '../../libs/interface.js'; import logger from '../../libs/logger.js'; import { checkDirectory, checkIsLoginSuccess, getRoutineVersionList } from '../utils.js'; import { displayMultiSelectTable } from '../../components/mutiSelectTable.js'; import { Base64 } from 'js-base64'; import { ApiService } from '../../libs/apiService.js'; import { createAndDeployVersion, displaySelectDeployType, promptSelectVersion, yesNoPromptAndExecute } from './helper.js'; import t from '../../i18n/index.js'; import prodBuild from '../commit/prodBuild.js'; import { exit } from 'process'; import path from 'path'; import { checkRoutineExist } from '../../utils/checkIsRoutineCreated.js'; import moment from 'moment'; const deploy = { command: 'deploy [entry]', builder: (yargs) => { return yargs .positional('entry', { describe: t('dev_entry_describe').d('Entry file of the Routine'), type: 'string', demandOption: false }) .option('quick', { alias: 'q', type: 'boolean' }); }, describe: `🚀 ${t('deploy_describe').d('Deploy your project')}`, handler: (argv) => __awaiter(void 0, void 0, void 0, function* () { handleDeploy(argv); }) }; export default deploy; export function quickDeploy(entry, projectConfig) { return __awaiter(this, void 0, void 0, function* () { const server = yield ApiService.getInstance(); const entryFile = path.resolve(entry !== null && entry !== void 0 ? entry : '', 'src/index.js'); yield prodBuild(false, entryFile, entry); const code = readEdgeRoutineFile(entry) || ''; const res = yield server.quickDeployRoutine({ name: projectConfig.name, code: code }); if (res) { logger.success(t('quick_deploy_success').d('Your code has been successfully deployed')); logger.log(`👉 ${t('quick_deploy_success_guide').d('Run this command to add domains')}: ${chalk.green('esa domain add <DOMAIN>')}`); } else { logger.error(t('quick_deploy_failed').d('Quick deploy failed')); process.exit(0); } }); } export function handleDeploy(argv) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e; if (!checkDirectory()) { return; } const projectConfig = getProjectConfig(); if (!projectConfig) return logger.notInProject(); const isSuccess = yield checkIsLoginSuccess(); if (!isSuccess) return; const server = yield ApiService.getInstance(); const entry = argv.entry; yield checkRoutineExist(projectConfig.name, entry); const req = { Name: projectConfig.name }; const routineDetail = yield server.getRoutine(req, false); const versionList = ((_a = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _a === void 0 ? void 0 : _a.CodeVersions) || []; const customEntry = argv.entry; const stagingVersion = (_c = (_b = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _b === void 0 ? void 0 : _b.Envs[1]) === null || _c === void 0 ? void 0 : _c.CodeVersion; const productionVersion = (_e = (_d = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _d === void 0 ? void 0 : _d.Envs[0]) === null || _e === void 0 ? void 0 : _e.CodeVersion; if (argv.quick) { yield quickDeploy(customEntry, projectConfig); exit(0); } if (versionList.length === 0) { logger.log(t('no_formal_version_found').d('No formal version found, you need to create a version first.')); yield handleOnlyUnstableVersionFound(projectConfig, customEntry); } else { yield displayVersionList(versionList, stagingVersion, productionVersion); logger.log(chalk.bold(`${t('deploy_version_select').d('Select the version you want to publish')}:`)); const selectedVersion = yield promptSelectVersion(versionList); const selectedType = yield displaySelectDeployType(); yield deploySelectedCodeVersion(projectConfig.name, selectedType, selectedVersion); } }); } export function displaySelectSpec(specList) { return __awaiter(this, void 0, void 0, function* () { logger.log(`📃 ${t('deploy_spec_select').d('Please select the spec of the routine you want to create')}`); const selectItems = specList.map((spec) => { return { label: spec, value: spec }; }); return new Promise((resolve) => { const handleSelection = (item) => __awaiter(this, void 0, void 0, function* () { resolve(item.value); }); SelectItems({ items: selectItems, handleSelect: handleSelection }); }); }); } function handleNoVersionsFound(projectConfig, customEntry) { return __awaiter(this, void 0, void 0, function* () { logger.log(`😄 ${t('deploy_first_time').d("This is first time to deploy. Let's create a version first!")}`); const created = yield yesNoPromptAndExecute(`📃 ${t('deploy_create_formal_version_ques').d('Do you want to create an unstable version now?')}`, () => createAndDeployVersion(projectConfig, true)); if (created) { yield handleOnlyUnstableVersionFound(projectConfig); } }); } function promptAndDeployVersion(projectConfig) { return __awaiter(this, void 0, void 0, function* () { const versionList = yield getRoutineVersionList(projectConfig.name); yield displayVersionList(versionList); logger.log(`📃 ${t('deploy_select_version').d("Select which version you'd like to deploy")}`); const selectedVersion = yield promptSelectVersion(versionList); const selectedType = yield displaySelectDeployType(); yield deploySelectedCodeVersion(projectConfig.name, selectedType, selectedVersion); }); } const specialAreaTransfer = (canaryAreaSelectList) => { return canaryAreaSelectList.map((item) => { if (item.label === 'HongKong') { return { label: 'HongKong(China)' }; } if (item.label === 'Macau') { return { label: 'Macau(China)' }; } if (item.label === 'Taiwan') { return { label: 'Taiwan(China)' }; } return { label: item.label }; }); }; export function handleOnlyUnstableVersionFound(projectConfig, customEntry) { return __awaiter(this, void 0, void 0, function* () { const created = yield yesNoPromptAndExecute(`📃 ${t('deploy_create_formal_version_ques').d('Do you want to create a formal version to deploy on production environment?')}`, () => createAndDeployVersion(projectConfig)); if (created) { yield promptAndDeployVersion(projectConfig); } }); } export function deploySelectedCodeVersion(name, selectedType, version) { return __awaiter(this, void 0, void 0, function* () { var _a; const server = yield ApiService.getInstance(); const param = { Name: name, Env: selectedType === PublishType.Staging ? Environment.Staging : Environment.Production }; if (selectedType === PublishType.Canary) { const res = yield server.listRoutineCanaryAreas(); const canaryList = (_a = res === null || res === void 0 ? void 0 : res.CanaryAreas) !== null && _a !== void 0 ? _a : []; logger.log(`📃 ${t('deploy_select_canary').d('Please select the canary area(s) you want to deploy to')}`); const canaryAreaSelectList = canaryList.map((area) => { return { label: area }; }); const selectedCanaryList = yield displayMultiSelectTable(specialAreaTransfer(canaryAreaSelectList)); param.CanaryAreaList = selectedCanaryList; param.CanaryCodeVersion = version; } else { param.CodeVersion = version; } try { const res = yield server.publishRoutineCodeVersion(param); if (res) { logger.success(t('deploy_success').d('Your code has been successfully deployed')); logger.log(`👉 ${t('deploy_success_guide').d('Run this command to add domains')}: ${chalk.green('esa domain add <DOMAIN>')}`); } } catch (e) { console.error(e); } }); } export function displayVersionList(versionList_1) { return __awaiter(this, arguments, void 0, function* (versionList, stagingVersion = 'unstable', productionVersion = 'unstable') { logger.log(`${chalk.bgYellow('Active')} ${t('deploy_env_staging').d('Staging')}`); logger.log(`${chalk.bgGreen('Active')} ${t('deploy_env_production').d('Production')}`); const data = []; for (let i = 0; i < versionList.length; i++) { const version = versionList[i]; const createTime = moment(version.CreateTime).format('YYYY/MM/DD HH:mm:ss'); const tags = [ version.CodeVersion === stagingVersion ? chalk.bgYellow('Active') : '', version.CodeVersion === productionVersion ? chalk.bgGreen('Active') : '' ]; data.push([ `${version.CodeVersion} ${tags.join(' ')}`, createTime, Base64.decode(version.CodeDescription) ]); } logger.table([ t('deploy_table_header_version').d('Version'), t('deploy_table_header_created').d('Created'), t('deploy_table_header_description').d('Description') ], data, [30, 25, 15]); }); }