UNPKG

@modyo/cli

Version:

Modyo Command Line Interface

336 lines (316 loc) 10.6 kB
const chalk = require('chalk') const fs = require('fs-extra') const path = require('path') const os = require('os') const inquirer = require('inquirer') const lodash = require('lodash') const { spawn } = require('child_process') const fetch = require('node-fetch') const modyoPrefix = { 8: 'api/v1', 9: 'api/admin' } /* * INTERNAL METHOD * Run a command line asynchronously returning a new Promise */ const runCommand = (cmd, args, options) => new Promise((resolve, _) => { const spawnx = spawn( cmd, args, { cwd: process.cwd(), stdio: 'inherit', shell: true, ...options } ) spawnx.on('exit', () => { resolve() }) }) /* * Get Site Id */ const selectSite = ({ accountUrl, modyoVersion }, token) => new Promise((resolve, reject) => { try { fetch(`${accountUrl}/${modyoPrefix[modyoVersion]}/sites?per_page=500`, { headers: { 'User-Agent': 'Modyo-CLI', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then((response) => { if (!response.ok && response.status === 401) { reject(new Error('Unauthorized to get the site\'s list of the account')) } response.json() .then((jsonResponse) => { const { sites } = jsonResponse const question = [ { type: 'list', name: 'site', message: 'Select the destination site', choices: sites.map((s) => s.name) } ] inquirer.prompt(question).then((answers) => { resolve(sites.find((obj) => obj.name === answers.site).id) }) }) .catch((err) => reject(err)) }) .catch((err) => reject(err)) } catch (error) { reject(error) } }) /* * Copy templates to the target directory depends on the type of the template */ const ensureFoldersAndFiles = (type, to) => { let from = '' switch (type) { case 'widget': from = path.resolve(__dirname, '../', 'widget/create/templates/widget') break case 'project': from = path.resolve(__dirname, '../', 'project/create/templates/project') break case 'blank_vue_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-webpack-simple-widget') break case 'vue_retail_bank_accounts_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-accounts-widget') break case 'vue_retail_bank_cash_advance_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-cash-advance-widget') break case 'vue_retail_bank_confirm_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-confirm-widget') break case 'vue_retail_bank_consumer_loan_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-consumer-loan-widget') break case 'vue_retail_bank_credit_cards_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-credit-cards-widget') break case 'vue_retail_bank_credit_cards_payment_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-credit-cards-payment-widget') break case 'vue_retail_bank_loans_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-loans-widget') break case 'vue_retail_bank_mortgage_loan_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-mortgage-loan-widget') break case 'vue_retail_bank_rewards_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-rewards-widget') break case 'vue_retail_bank_security_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-security-widget') break case 'vue_retail_bank_summary_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-summary-widget') break case 'vue_retail_bank_transfer_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-transfer-widget') break case 'vue_retail_bank_transfers_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-transfers-widget') break case 'vue_retail_bank_voucher_widget': from = path.resolve(__dirname, '../', 'widget/create/templates/vue-retail-bank-voucher-widget') break default: from = path.resolve(__dirname, '../', 'widget/create/templates/vue-webpack-simple-widget') break } fs.copySync(from, to) } /* * Generate the full path to the widget to be created */ const resolveWidgetSrcPath = (name) => path.resolve(lodash.snakeCase(name), 'src') /* * Generate the full path to the project to be created */ const resolveWidgetPath = (name) => path.resolve(lodash.snakeCase(name) || '.') /* * Fetch site attributes */ const getModyoSiteConfiguration = ({ accountUrl, selectedSite, modyoVersion }, token) => fetch(`${accountUrl}/${modyoPrefix[modyoVersion]}/sites/${selectedSite}`, { headers: { 'User-Agent': 'ModyoDX-CLI', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then((response) => { if (!response.ok && response.status === 401) { throw Error(`Unauthorized to get the site's information${accountUrl}/${modyoPrefix[modyoVersion]}/sites/${selectedSite}`) } return response.json() .then((jsonResponse) => jsonResponse) .catch((err) => { throw (err) }) }) .catch((err) => { throw (err) }) /* * Check and retrieve .modyorc */ const getModyoProjectConfiguration = (logger) => { if (fs.existsSync(path.resolve('.modyorc'))) { return JSON.parse(fs.readFileSync('.modyorc', 'utf-8')) } logger.info(`${chalk.red('ERROR: ')} No .modyorc file found, please add the widget in a project directory`) return null } /* * Check and retrieve promise to get project configuration */ const getModyoProjectConfigurationPromise = () => new Promise((resolve, reject) => { if (fs.existsSync(path.resolve('.modyorc'))) { const conf = JSON.parse(fs.readFileSync('.modyorc', 'utf-8')) resolve(conf) } else { reject(new Error('No .modyorc file found, please add the widget in a project directory')) } }) /* * Add widget json object to modyo.rc */ const addWidgetToConfig = (key, name) => new Promise((resolve, reject) => { const modyorcPath = path.resolve(lodash.snakeCase(name), '.modyorc') if (fs.existsSync(modyorcPath)) { const conf = fs.readJSONSync(modyorcPath, 'utf-8') conf.widget = { key, name, entrypoint: `./${path.relative('.', 'src/main.js')}` } fs.writeFileSync(modyorcPath, JSON.stringify(conf, null, 4), 'utf-8') resolve() } reject(new Error('No .modyorc file found, please add the widget and its path manually to webpack.config.js')) }) /* * Get widget webpack setup */ const webpackProjectSetup = () => { const projectWebpackPath = path.resolve('webpack.modyo.js') if (fs.existsSync(projectWebpackPath)) { // eslint-disable-next-line global-require,import/no-dynamic-require return require(projectWebpackPath) } return {} } /* * Install dependencies */ const installDependencies = (cwd, packageManager, logger) => { logger.info(`\n\n# ${chalk.green('Installing project dependencies ...')}`) logger.info('# ========================\n') return runCommand(packageManager, ['install', '--silent'], { cwd }) } /* * Print finish message given instructions */ const printFinishedMessage = (projectDir, logger, needInstall = false, packageManager = 'yarn') => { const installMessage = !needInstall ? `${packageManager} install` : '' const message = ` # ${chalk.green('Widget initialization finished!')} # ======================== To get started: ${chalk.yellow(`cd ${projectDir}\n ${installMessage}\n modyo-cli login\n modyo-cli widget start`)} \n ` logger.info(message) } /* * Get access token from user directory */ const getAccessTokens = () => new Promise((resolve, reject) => { const confFilePath = `${os.homedir()}/.modyo/modyo-cli.conf` if (fs.existsSync(confFilePath)) { const conf = JSON.parse(fs.readFileSync(confFilePath, 'utf-8')) resolve(conf) } else { reject(new Error('Modyo accees tokens configuration doesn\'t exist')) } }) /* * Write access token on user directory */ const writeAccessTokensConfiguration = (conf) => { const confFilePath = `${os.homedir()}/.modyo/modyo-cli.conf` fs.writeFileSync(confFilePath, JSON.stringify(conf, null, 4), 'utf-8') } /* * Get Auth Token from Modyo platform */ const getAuthToken = ({ accountUrl } = null, options = { token: null }) => new Promise((resolve, _) => { if (options.token) { return resolve(options.token) } let url = '' if (accountUrl === null) { if (!fs.existsSync('.modyorc')) { throw (new Error('no .modyorc file found, please run command from a valid ModyoCLI project path')) } const rcConf = JSON.parse(fs.readFileSync('.modyorc', 'utf-8')) if (rcConf.accountUrl) { url = rcConf.accountUrl } } else { url = accountUrl } const confFilePath = `${os.homedir()}/.modyo/modyo-cli.conf` let hConf = { accessTokens: {} } if (fs.existsSync(confFilePath)) { hConf = JSON.parse(fs.readFileSync(confFilePath, 'utf-8')) if (hConf.accessTokens && hConf.accessTokens[url]) { return resolve(hConf.accessTokens[url]) } } const question = [ { type: 'input', name: 'token', message: 'Please insert your Modyo CLI Api Access Token.', validate: (value) => { if (value.match(/^[a-f0-9]{64}$$/i)) { return true } return 'Please enter a valid Modyo Oauth2 Token' } } ] return inquirer.prompt(question).then((answers) => { fs.ensureFileSync(confFilePath) if (hConf.accessTokens) { hConf.accessTokens[url] = answers.token } else { hConf.accessTokens = {} hConf.accessTokens[url] = answers.token } fs.writeFileSync(confFilePath, JSON.stringify(hConf, null, 4), 'utf-8') return resolve(answers.token) }) }) module.exports = { getAuthToken, writeAccessTokensConfiguration, getAccessTokens, printFinishedMessage, installDependencies, webpackProjectSetup, addWidgetToConfig, getModyoProjectConfigurationPromise, getModyoProjectConfiguration, getModyoSiteConfiguration, resolveWidgetPath, resolveWidgetSrcPath, ensureFoldersAndFiles, selectSite, modyoPrefix }