esa-cli
Version:
A CLI for operating Alibaba Cloud ESA EdgeRoutine (Edge Functions).
240 lines (239 loc) • 10.8 kB
JavaScript
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 fs from 'fs-extra';
import path from 'path';
import inquirer from 'inquirer';
import { exit } from 'process';
import Template from '../../libs/templates/index.js';
import { installGit } from '../../libs/git/index.js';
import multiLevelSelect from '../../components/mutiLevelSelect.js';
import { generateConfigFile, getCliConfig, getProjectConfig, getTemplatesConfig, templateHubPath, updateProjectConfigFile } from '../../utils/fileUtils/index.js';
import t from '../../i18n/index.js';
import logger from '../../libs/logger.js';
import { quickDeploy } from '../deploy/index.js';
import { ApiService } from '../../libs/apiService.js';
import { checkRoutineExist } from '../../utils/checkIsRoutineCreated.js';
import { checkIsLoginSuccess } from '../utils.js';
import chalk from 'chalk';
import { checkAndUpdatePackage, getTemplateInstances, preInstallDependencies, transferTemplatesToSelectItem } from './helper.js';
const init = {
command: 'init [name]',
describe: `📥 ${t('init_describe').d('Initialize a routine with a template')}`,
builder: (yargs) => {
return yargs
.positional('name', {
describe: t('init_project_name').d('Project name'),
type: 'string'
})
.option('template', {
alias: 't',
describe: t('init_template_name').d('Template name to use'),
type: 'string'
})
.option('config', {
alias: 'c',
describe: t('init_config_file').d('Generate a config file for your project'),
type: 'boolean'
})
.option('skip', {
alias: 's',
describe: t('init_skip').d('Skip the project git and deployment initialization'),
type: 'boolean',
default: false
});
},
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
yield handleInit(argv);
exit(0);
})
};
export default init;
export function findTemplatePathByName(templateName) {
const templateInstanceList = getTemplateInstances(templateHubPath);
const templateConfig = getTemplatesConfig();
// find template recursively
function findTemplateRecursive(configs) {
for (const config of configs) {
const title = config.Title_EN;
if (title === templateName) {
const template = templateInstanceList.find((template) => {
return config.Title_EN === template.title;
});
return (template === null || template === void 0 ? void 0 : template.path) || null;
}
}
return null;
}
return findTemplateRecursive(templateConfig);
}
export function validateProjectName(name) {
const regex = /^[a-z0-9-]{2,}$/;
return regex.test(name);
}
export function promptProjectName() {
return __awaiter(this, void 0, void 0, function* () {
const { name } = yield inquirer.prompt([
{
type: 'input',
name: 'name',
message: `${t('init_input_name').d('Enter the name of edgeRoutine:')}`,
validate: (input) => {
const regex = /^[a-z0-9-]{2,}$/;
if (!regex.test(input)) {
return t('init_name_error').d('Error: The project name must be at least 2 characters long and can only contain lowercase letters, numbers, and hyphens.');
}
return true;
}
}
]);
return name;
});
}
export function prepareTemplateItems() {
var _a;
const templateInstanceList = getTemplateInstances(templateHubPath);
const templateConfig = getTemplatesConfig();
const cliConfig = getCliConfig();
const lang = (_a = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.lang) !== null && _a !== void 0 ? _a : 'en';
return transferTemplatesToSelectItem(templateConfig, templateInstanceList, lang);
}
export function selectTemplate(items) {
return __awaiter(this, void 0, void 0, function* () {
const selectedTemplatePath = yield multiLevelSelect(items, 'Select a template:');
if (!selectedTemplatePath) {
logger.log(t('init_cancel').d('User canceled the operation.'));
return null;
}
return selectedTemplatePath;
});
}
export function initializeProject(selectedTemplatePath, name) {
return __awaiter(this, void 0, void 0, function* () {
const selectTemplate = new Template(selectedTemplatePath, name);
const projectConfig = getProjectConfig(selectedTemplatePath);
if (!projectConfig) {
logger.notInProject();
return null;
}
const targetPath = path.join(process.cwd(), name);
if (fs.existsSync(targetPath)) {
logger.error(t('already_exist_file_error').d('Error: The project already exists. It looks like a folder named "<project-name>" is already present in the current directory. Please try the following options: 1. Choose a different project name. 2. Delete the existing folder if it\'s not needed: `rm -rf <project-name>` (use with caution!). 3. Move to a different directory before running the init command.'));
return null;
}
yield fs.copy(selectedTemplatePath, targetPath);
projectConfig.name = name;
yield updateProjectConfigFile(projectConfig, targetPath);
yield preInstallDependencies(targetPath);
return { template: selectTemplate, targetPath };
});
}
export function handleGitInitialization(targetPath) {
return __awaiter(this, void 0, void 0, function* () {
const { initGit } = yield inquirer.prompt([
{
type: 'list',
name: 'initGit',
message: t('init_git').d('Do you want to init git in your project?'),
choices: ['Yes', 'No']
}
]);
if (initGit === 'Yes') {
installGit(targetPath);
}
else {
logger.log(t('init_skip_git').d('Git installation was skipped.'));
}
});
}
export function handleDeployment(targetPath, projectConfig) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
const isLoginSuccess = yield checkIsLoginSuccess();
if (!isLoginSuccess) {
logger.log(chalk.yellow(t('not_login_auto_deploy').d('You are not logged in, automatic deployment cannot be performed. Please log in later and manually deploy.')));
return;
}
const { deploy } = yield inquirer.prompt([
{
type: 'list',
name: 'deploy',
message: t('auto_deploy').d('Do you want to deploy your project?'),
choices: ['Yes', 'No']
}
]);
if (deploy === 'Yes') {
yield checkRoutineExist((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.name) !== null && _a !== void 0 ? _a : '', targetPath);
yield quickDeploy(targetPath, projectConfig);
const service = yield ApiService.getInstance();
const res = yield service.getRoutine({ Name: (_b = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.name) !== null && _b !== void 0 ? _b : '' });
const defaultUrl = (_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.DefaultRelatedRecord;
const visitUrl = defaultUrl ? 'http://' + defaultUrl : '';
logger.success(`${t('init_deploy_success').d('Project deployment completed. Visit: ')}${chalk.yellowBright(visitUrl)}`);
logger.warn(t('deploy_url_warn').d('The domain may take some time to take effect, please try again later.'));
}
});
}
export function handleInit(argv) {
return __awaiter(this, void 0, void 0, function* () {
// Update the template package (currently commented out)
yield checkAndUpdatePackage('esa-template');
// If config option is provided, generate config file and exit
const config = getCliConfig();
if (config === undefined) {
yield generateConfigFile(String(config));
}
// Handle project name parameter
let name = argv.name;
if (!name) {
name = yield promptProjectName();
}
else {
if (!validateProjectName(name)) {
logger.error(t('init_name_error').d('Error: The project name must be at least 2 characters long and can only contain lowercase letters, numbers, and hyphens.'));
return;
}
}
// Handle template name parameter
let selectedTemplatePath = null;
if (argv.template) {
const templateName = argv.template;
selectedTemplatePath = findTemplatePathByName(templateName);
if (!selectedTemplatePath) {
logger.error(t('init_template_not_found').d(`Template "${templateName}" not found. Please check the template name and try again.`));
return;
}
}
else {
const templateItems = prepareTemplateItems();
// Select a template
selectedTemplatePath = yield selectTemplate(templateItems);
if (!selectedTemplatePath) {
return;
}
}
// Initialize project files and configuration
const project = yield initializeProject(selectedTemplatePath, name);
if (!project) {
return;
}
const { template, targetPath } = project;
if (!argv.skip) {
// Handle Git initialization
yield handleGitInitialization(targetPath);
}
if (!argv.skip) {
// Handle deployment
const projectConfig = getProjectConfig(targetPath);
yield handleDeployment(targetPath, projectConfig);
}
template.printSummary();
return;
});
}