UNPKG

reactium

Version:

A CLI for creating Reactium / Actinium projects.

379 lines (336 loc) 9.56 kB
/** * ----------------------------------------------------------------------------- * Imports * ----------------------------------------------------------------------------- */ import GENERATOR from './generator.js'; import { AuthValidated, Session } from '../../../lib/auth.js'; const { _, chalk, inquirer, fs, normalizePath, op, path, prefix, semver, } = arcli; const { cwd } = arcli.props; const pkgFile = normalizePath(cwd, 'package.json'); const getPackage = () => fs.existsSync(pkgFile) ? fs.readJsonSync(pkgFile) : { version: '0.0.1', scripts: { test: 'echo "Error: no test specified" && exit 1', }, keywords: [], reactium: {}, actinium: {}, }; const getPackageVersion = inc => { let { version } = getPackage(); version = semver.coerce(version).version; return inc ? semver.inc(version, inc) : version; }; /** * NAME String * @description Constant defined as the command name. Value passed to the commander.command() function. * @example $ arcli publish * @see https://www.npmjs.com/package/commander#command-specific-options * @since 2.0.0 */ export const NAME = 'publish'; /** * DESC String * @description Constant defined as the command description. Value passed to * the commander.desc() function. This string is also used in the --help flag output. * @see https://www.npmjs.com/package/commander#automated---help * @since 2.0.0 */ const DESC = 'Publish an Actinium or Reactium module.'; /** * CANCELED String * @description Message sent when the command is canceled * @since 2.0.0 */ const CANCELED = 'Publish canceled!'; /** * conform(input:Object) Function * @description Reduces the input object. * @param input Object The key value pairs to reduce. * @since 2.0.0 */ const CONFORM = input => Object.keys(input).reduce((obj, key) => { let val = input[key]; switch (key) { case 'ver': const incs = ['major', 'minor', 'patch']; obj['version'] = incs.includes(String(val).toLowerCase()) ? semver.inc(getPackageVersion(), val) : semver.coerce(val).version; break; case 'version': obj['version'] = semver.coerce(val).version; break; case 'name': obj['name'] = String(val) .toLowerCase() .replace(/\s\s+/g, ' ') .replace(/[^0-9a-z@\-\/]/gi, '-'); break; default: obj[key] = val; break; } return obj; }, {}); /** * HELP Function * @description Function called in the commander.on('--help', callback) callback. * @see https://www.npmjs.com/package/commander#automated---help * @since 2.0.0 */ const HELP = () => console.log(` When specifying -v, --version with ${chalk.cyan('major')}, ${chalk.cyan( 'minor', )}, or ${chalk.cyan('patch')}, the plugin ${chalk.bold( 'package.json', )} ${chalk.cyan('version')} value will be incremented accordingly. Example: $ arcli publish `); /** * FLAGS * @description Array of flags passed from the commander options. * @since 2.0.18 */ const FLAGS = [ 'actinium', 'app', 'author', 'description', 'license', 'name', 'private', 'reactium', 'server', 'ver', ]; /** * FLAGS_TO_PARAMS Function * @description Create an object used by the prompt.override property. * @since 2.0.18 */ const FLAGS_TO_PARAMS = opt => FLAGS.reduce((obj, key) => { let val = opt[key]; val = typeof val === 'function' ? undefined : val; if (val) { key = key === 'private' ? 'priv' : key; obj[key] = val; } return obj; }, {}); const PROMPT = {}; PROMPT.TMPDIR = params => { params.tmpDir = normalizePath( arcli.props.homedir, '.arcli', 'tmp', 'publish', path.basename(cwd), ); return params; }; PROMPT.AUTH = async params => { const config = arcli.props.config; params.app = op.get(params, 'app') || op.get(config, 'registry.app', 'ReactiumRegistry'); params.server = op.get(params, 'server') || op.get(config, 'registry.server'); params.authorized = await AuthValidated(params); const { username, password } = await inquirer.prompt( [ { prefix, name: 'username', type: 'input', message: 'Username:', when: !params.authorized, }, { prefix, name: 'password', type: 'password', message: 'Password:', when: !params.authorized, }, ], params, ); params.username = username; params.password = password; return params; }; PROMPT.PKG = async params => { const PACKAGE = getPackage(); const { actinium, author, description, license, name, priv, reactium, ver, } = await inquirer.prompt( [ { prefix, name: 'ver', type: 'input', askAnswered: true, default: getPackageVersion('patch'), message: 'Version:', }, { prefix, name: 'priv', default: false, type: 'confirm', message: 'Private:', }, { prefix, name: 'actinium', message: 'Minimum Actinium Version:', default: '3.6.6', }, { prefix, name: 'reactium', message: 'Minium Reactium Version:', default: '3.2.6', }, { prefix, name: 'name', type: 'input', message: 'Plugin Name:', }, { prefix, name: 'description', type: 'input', message: 'Plugin Description:', }, { prefix, name: 'author', type: 'input', message: 'Plugin Author:', }, { prefix, name: 'license', type: 'input', message: 'Plugin License:', }, ], { ...params, ...PACKAGE }, ); params.version = ver; params.private = priv; params.pkg = { actinium: {}, reactium: {}, ...PACKAGE, description, name, license, author, version: ver, }; if (_.isString(actinium)) { params.pkg.actinium.version = actinium; } if (_.isString(reactium)) { params.pkg.reactium.version = reactium; } return params; }; const PKG_TO_PARAMS = () => { const pkg = getPackage(); const keys = ['author', 'app', 'description', 'private', 'license', 'name']; const pkeys = Object.keys(pkg); const newPkg = keys.reduce((obj, key) => { if (pkeys.includes(key)) { obj[key] = op.get(pkg, key); } return obj; }, {}); return newPkg; }; /** * ACTION Function * @description Function used as the commander.action() callback. * @see https://www.npmjs.com/package/commander * @param opt Object The commander options passed into the function. * @param props Object The CLI props passed from the calling class `orcli.js`. * @since 2.0.0 */ const ACTION = async ({ opt, props }) => { console.log(''); let params = { pkg: PKG_TO_PARAMS(), ...FLAGS_TO_PARAMS(opt), }; try { for (let P of Object.values(PROMPT)) { await P(params, props); } } catch (err) { console.log(err); process.exit(); } params = CONFORM(params); return GENERATOR({ params, props }); }; /** * COMMAND Function * @description Function that executes program.command() */ export const COMMAND = ({ program, props }) => program .command(NAME) .description(DESC) .action(opt => ACTION({ opt, props })) .option( '-a, --app [app]', 'Plugin registry application ID. Used when server plugins from a custom registry server. Default: ReactiumRegistry', ) .option( '-p, --private [private]', 'Make the plugin available to ACL targets only', ) .option('-s, --server [server]', 'Server URL') .option('--ver [ver]', 'Plugin semver. Default: 0.0.1') .option( '--actinium [actinium]', 'Minimum Actinium version required to install the plugin', ) .option( '--reactium [reactium]', 'Minimum Reactium version required to install the plugin', ) .option('--description [description]', 'Plugin description') .option('--author [author]', 'Plugin author') .option('--license [license]', 'Plugin license') .option('--name [name]', 'Plugin name used when installing the plugin') .on('--help', HELP);