UNPKG

@modyo/cli

Version:

Modyo Command Line Interface

216 lines (213 loc) 6.95 kB
const Webpack = require('webpack') const WebpackMerge = require('webpack-merge') const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages') const chalk = require('chalk') const inquirer = require('inquirer') const fetch = require('node-fetch') const path = require('path') const fs = require('fs-extra') const HtmlWebpackPlugin = require('html-webpack-plugin') const baseWebpackConfig = require('./config/webpack.build.config') const { getModyoProjectConfiguration, getAuthToken, webpackProjectSetup, modyoPrefix } = require('../../helpers') /* * Generate a unique webpack config with entry points relatives to the widget path */ const createWebpackConfig = ((widget) => { const entry = {} entry[widget.key] = widget.entrypoint baseWebpackConfig.name = widget.key const plugins = [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'templates', 'index.ejs'), filename: `${widget.key}.build.html`, ref: widget.key, inject: false }) ] return WebpackMerge( { entry }, { plugins }, baseWebpackConfig, webpackProjectSetup() ) }) /* * Build bundle of widget to upload */ const buildWidget = (widget, logger) => { logger.info(`Creating an optimized production build for ${chalk.yellow(widget.name)}...`) const webpackConf = createWebpackConfig(widget) const compiler = Webpack(webpackConf) return new Promise((resolve, reject) => { compiler.run((err, stats) => { const messages = formatWebpackMessages(stats.toJson({}, true)) if (messages.errors.length) { if (messages.errors.length > 1) { messages.errors.length = 1 } messages.name = widget.name return reject(new Error(messages.errors.join('\n\n'))) } const resolveArgs = { name: widget.name, stats, warnings: messages.warnings } return resolve(resolveArgs) }) }) } /* * Get Site Widgets to see if exist */ const getSiteWidgets = (token, conf) => new Promise((resolve, reject) => { try { const url = `${conf.accountUrl}/${modyoPrefix[conf.modyoVersion]}/sites/${conf.selectedSite}/widget_definitions?paginate=false` fetch(url, { 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 widgets')) } return response.json() }) .then((json) => { resolve(json.widget_definitions) }) .catch((err) => reject(err)) } catch (error) { reject(error) } }) /* * Update Widget Project */ const updateWidget = (widgetId, conf, token) => { const url = `${conf.accountUrl}/${modyoPrefix[conf.modyoVersion]}/sites/${conf.selectedSite}/widget_definitions/${widgetId}` const html = fs.readFileSync(`dist/${conf.widget.key}.build.html`, 'utf-8') const js = fs.readFileSync(`dist/${conf.widget.key}.build.js`, 'utf-8') const query = { method: 'PUT', headers: { 'User-Agent': 'MODYODX-CLI', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ id: widgetId, html, js, public: true }) } return new Promise((resolve, reject) => { fetch(url, query) .then((response) => response.json()) .then((json) => { if (Object.keys(json) .includes('errors')) { return reject(json.errors) } return resolve(json) }) }) } /* * Creating blank boilerplate widget in widget Builder */ const creatingNewWidget = (conf, token) => { const url = `${conf.accountUrl}/${modyoPrefix[conf.modyoVersion]}/sites/${conf.selectedSite}/widget_definitions` const query = { method: 'POST', headers: { 'User-Agent': 'MODYODX-CLI', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ name: conf.widget.name, read_only: true, public: true }) } return new Promise((resolve, reject) => fetch(url, query) .then((response) => response.json()) .then(((json) => resolve(json))) .catch((err) => reject(err))) } /* * Push the widget */ const pushWidget = (conf, siteWidgets, token, logger, options) => new Promise((resolve, reject) => { const { widget } = conf const existing = siteWidgets.find((w) => w.name === widget.name) if (!existing) { logger.info(`Adding new widget: ${widget.name}`) return creatingNewWidget(conf, token) .then((json) => resolve(updateWidget(json.id, conf, token))) .catch((error) => reject(error)) } logger.info(`${chalk.yellow('Replacing')} existing widget: ${widget.name}`) if (options.force) { return updateWidget(existing.id, conf, token) .then((jsonFinal) => resolve(jsonFinal)) .catch((err) => reject(err)) } const confirmQuestion = [ { type: 'confirm', name: 'confirmReplaceWidget', default: false, message: `Are you sure to replace the content of the widget ${chalk.yellow(widget.name)} on the ${chalk.green('Modyo Platform')}?` } ] return inquirer.prompt(confirmQuestion) .then((answers) => { if (answers.confirmReplaceWidget) { updateWidget(existing.id, conf, token) .then((jsonFinal) => resolve(jsonFinal)) .catch((err) => reject(err)) } }) }) module.exports = ((argWidget, options, logger) => { const conf = getModyoProjectConfiguration() const { widget } = conf getAuthToken(conf, options) .then((token) => { buildWidget(widget, logger) .then(({ _, warnings }) => { if (warnings.length) { logger.info(chalk.yellow('Compiled with warnings.\n')) logger.info(warnings.join('\n\n')) logger.info(`\nSearch for the ${chalk.underline(chalk.yellow('keywords'))} to learn more about each warning.`) logger.info(`To ignore, add ${chalk.cyan('// eslint-disable-next-line')} to the line before.\n`) } else { logger.info(chalk.green('Compiled successfully.')) } getSiteWidgets(token, conf) .then((siteWidgets) => { pushWidget(conf, siteWidgets, token, logger, options) .then((uploadedWidget) => logger.info(`${uploadedWidget.name} successfully uploaded`)) .catch((error) => { logger.info(`Widget Upload Failed: ${JSON.stringify(error)}`, true) }) }) .catch((error) => { logger.info(`Error on get site widgets: ${error}`, true) }) }) .catch((error) => { logger.info(`Build Failed: ${error}`, true) }) }) .catch((error) => { logger.info(`Error on token: ${error}`, true) }) })