UNPKG

@wpk-cli/command-add

Version:
371 lines (264 loc) 11.1 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = addComponent; var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); var _findUp = _interopRequireDefault(require("find-up")); var _plur = _interopRequireDefault(require("plur")); var _map = _interopRequireDefault(require("lodash/map")); var _inquirer = _interopRequireDefault(require("inquirer")); var _ora = _interopRequireDefault(require("ora")); var _prettyFormat = _interopRequireDefault(require("pretty-format")); var _ajv = _interopRequireDefault(require("ajv")); var _chalk = _interopRequireDefault(require("chalk")); var _groupBy = _interopRequireDefault(require("lodash/groupBy")); var _replace = _interopRequireDefault(require("lodash/replace")); var _semver = _interopRequireDefault(require("semver")); var _find = _interopRequireDefault(require("lodash/find")); var _logger = _interopRequireDefault(require("@wpk-cli/logger")); var _requireLocalNodeModule = _interopRequireDefault(require("require-local-node-module")); var _forEach = _interopRequireDefault(require("lodash/forEach")); var _get = _interopRequireDefault(require("lodash/get")); var _size = _interopRequireDefault(require("lodash/size")); var _indent = _interopRequireDefault(require("indent")); var _cardinal = _interopRequireDefault(require("cardinal")); var _generator = _interopRequireDefault(require("@babel/generator")); var _ansiEscapes = _interopRequireDefault(require("ansi-escapes")); var pluginDefs = _interopRequireWildcard(require("@wpk-cli/defs/plugins")); var loaderDefs = _interopRequireWildcard(require("@wpk-cli/defs/loaders")); var _defs = require("@wpk-cli/defs"); var _utilities = require("@wpk-cli/utilities"); var _configurator = _interopRequireWildcard(require("../configurator")); var _constants = require("../constants"); const shortEnvNames = { prod: "production", dev: "development" }; function doesPackageJsonHaveDependency(dep) { const pkg = (0, _findUp.default)("package.json"); if (!pkg) { return false; } const deps = (0, _objectSpread2.default)({}, pkg.dependencies, pkg.devDependencies); return (0, _find.default)(deps, (_, k) => k === dep); } function installComponentPackage(_x, _x2) { return _installComponentPackage.apply(this, arguments); } /** * Add a plugin or loader to a webpack configuration. * @param type {"loader"|"plugin"} * @param cmd {Object} cli options * @param [opts] {Object} options object * @param [opts.config] {WebpackConfig} * @param [opts.definition] {Object} * @returns {Promise<*>} */ function _installComponentPackage() { _installComponentPackage = (0, _asyncToGenerator2.default)(function* (cmd, definition) { _logger.default.info(`installing "${cmd.name}"`, cmd.scope ? _chalk.default.grey(cmd.scope) : ""); return (0, _utilities.installPackages)(`${cmd.name}@${definition.version || "latest"}`, { scope: cmd.scope || "local", saveDev: true }); }); return _installComponentPackage.apply(this, arguments); } function addComponent(_x3, _x4, _x5) { return _addComponent.apply(this, arguments); } function _addComponent() { _addComponent = (0, _asyncToGenerator2.default)(function* (type, cmd, opts) { const nativeDefinitions = { plugin: pluginDefs, loader: loaderDefs }[type]; if (!nativeDefinitions) { _logger.default.error(`unknown component type "${type}"`); _logger.default.error('expecting type to be "plugin" or "loader"'); return false; } if (!cmd.name) { _logger.default.error(`expecting a ${type} name to add to config`); _logger.default.error(_chalk.default`e.g. {grey wpk add plugin define-plugin}`); return false; } let definition = opts.definition; if (!definition) { definition = (0, _find.default)(nativeDefinitions, def => def.name === cmd.name); } if (cmd.dryRun) { cmd.install = false; } if (cmd.dev) { cmd.env = "development"; } else if (cmd.prod) { cmd.env = "production"; } else if (cmd.env in shortEnvNames) { cmd.env = shortEnvNames[cmd.env]; } if (cmd.scope && cmd.scope !== "local" && cmd.scope !== "global") { _logger.default.error(`bad value for scope "${cmd.scope}"`); _logger.default.error('expecting "local" or "global"'); return false; } let didInstallPkg = false; if (definition && (definition.native || !cmd.install)) { const why = definition.native ? "(native component)" : ""; _logger.default.info(`skipping ${type} installation`, why); } else if (definition && cmd.install) { // we are looking at a loader for which we already have a definition // but no loaders are native to webpack so we always must install them if (definition.type === _constants.ComponentTypes.loader) { if (!doesPackageJsonHaveDependency(cmd.name)) { yield installComponentPackage(cmd); } } } else if (!definition && cmd.install) { const msg = `checking if "${cmd.name}" has a wpk-def.json`; const spinner = (0, _ora.default)(msg).start(); try { var hasWpkDefJson = yield (0, _utilities.checkPackageHasWpkDefJson)(cmd.name); } catch (err) { _logger.default.error(`failed to check for a wpk-def.json`); if (cmd.wpkDebug) { throw err; } } if (!hasWpkDefJson) { spinner.fail(); _logger.default.error(`no wpk-def.json found for "${cmd.name}"`); _logger.default.error(`wpk cannot add the ${type} without a definition`); _logger.default.error("the component must be added manually"); return false; } spinner.succeed(); if (cmd.install && !(0, _utilities.checkPackageHasWpkDefJson)(cmd.name)) { yield installComponentPackage(cmd); } _logger.default.info("installation successful"); try { definition = (0, _requireLocalNodeModule.default)(cmd.name + "/wpk-def.json"); } catch (err) { _logger.default.error(`could not find a ${type} definition for "${cmd.name}"`); _logger.default.error(`wpk cannot add the ${type} without a definition`); _logger.default.error("you will need to add the component manually"); if (cmd.wpkDebug) { throw err; } return false; } } if (!definition && didInstallPkg) { _logger.default.info("are you a plugin/loader maintainer?"); _logger.default.info(_chalk.default`consider adding a {grey wpk-def.json} file to your project`); _logger.default.info(_chalk.default`see {grey github.com/wpk-cli/wpk} for more information`); return 0; } const ajv = new _ajv.default({ useDefaults: true }); ajv.validate(_defs.schemas.wpkDef, definition); if (ajv.errors) { const msg = "wpk definition file failed validation"; const err = new Error(msg + ":\n\n" + (0, _prettyFormat.default)(ajv.errors) + "\n"); (0, _utilities.printError)(err, [msg, "please raise with the definition author"]); return false; } if (definition.webpackVersion) { const version = (0, _utilities.getWebpackVersion)(); if (!_semver.default.satisfies(version, definition.webpackVersion)) { _logger.default.warn("version of webpack detected is incompatible"); _logger.default.warn(type, "expecting webpack version", `"${definition.webpackVersion}"`); _logger.default.warn("continuing anyway, however you may encounter issues"); } } (0, _logger.default)(); let cont = cmd.configure; if (cmd.yes) { cont = false; } let components; if (cont) { const answers = yield _inquirer.default.prompt([{ name: "cont", message: `Configure the ${type} interactively?`, type: "confirm" }]); cont = answers.cont; } if (!cont) { cont = "skipped"; // remove the "do you want to configure this plugin" question process.stdout.write(_ansiEscapes.default.eraseLines(2)); components = yield Promise.all((0, _map.default)(definition.components, /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2.default)(function* (cmp) { return (0, _configurator.prepareComponent)(definition, cmp, opts, true); }); return function (_x6) { return _ref.apply(this, arguments); }; }())); } else { components = yield (0, _configurator.default)(opts.config, definition, cmd); } if (cmd.yes) { _logger.default.info(`using component defaults`); if ((0, _size.default)(definition.components) === 1) { const docs = (0, _get.default)(definition, "components[0].url"); if (docs) { _logger.default.info("docs:", docs); } } } else { (0, _logger.default)(); if (cont === "skipped") { process.stdout.write(_ansiEscapes.default.eraseLines(3)); _logger.default.info(`using component defaults`); } else { (0, _logger.default)(_chalk.default.grey("---")); } _logger.default.info(`${(0, _plur.default)("component", (0, _size.default)(components))} configured`); } const componentsByType = (0, _groupBy.default)(definition.components, "type"); let typeName = type; if ((0, _size.default)(componentsByType.loader) && (0, _size.default)(componentsByType.plugin)) { typeName = "component"; } _logger.default.info("added", (0, _size.default)(components), `${(0, _plur.default)(typeName, (0, _size.default)(components))}` + ":"); (0, _forEach.default)(components, (cmp, i) => { const cmpDef = definition.components[i]; if (cmpDef.environment) { cmp.environments = [cmpDef.environment]; } if (cmpDef.type === _constants.ComponentTypes.plugin) { opts.config.addPlugin(cmp); } else if (cmpDef.type === _constants.ComponentTypes.loader) { opts.config.addModuleRule(cmp); } const ast = cmp.buildAst(opts.config, { environmentConditional: false }); const src = (0, _generator.default)(ast); const code = (0, _indent.default)(_cardinal.default.highlight(src.code), 2); if (!i) { (0, _logger.default)(); } (0, _logger.default)(code); (0, _logger.default)(); }); if (cmd.install && (0, _size.default)(definition.packages)) { _logger.default.info("installing", (0, _size.default)(definition.packages), "packages"); yield (0, _utilities.installPackages)(definition.packages, { scope: "local", saveDev: true }); } }); return _addComponent.apply(this, arguments); }