@modyo/cli
Version:
Modyo Command Line Interface
216 lines (213 loc) • 6.95 kB
JavaScript
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)
})
})