UNPKG

nwb

Version:

A toolkit for React, Preact & Inferno apps, React libraries and other npm modules for the web, with no configuration (until you need it)

266 lines (213 loc) 6.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clean = clean; exports.clearConsole = clearConsole; exports.deepToString = deepToString; exports.directoryExists = directoryExists; exports.getArgsPlugins = getArgsPlugins; exports.install = install; exports.joinAnd = joinAnd; exports.modulePath = modulePath; exports.padLines = padLines; exports.pluralise = pluralise; exports.toSource = toSource; exports.typeOf = typeOf; exports.unique = unique; exports.formatPackageName = formatPackageName; exports.replaceArrayMerge = void 0; var _path = _interopRequireDefault(require("path")); var _util = _interopRequireDefault(require("util")); var _crossSpawn = _interopRequireDefault(require("cross-spawn")); var _fsExtra = _interopRequireDefault(require("fs-extra")); var _ora = _interopRequireDefault(require("ora")); var _resolve = _interopRequireDefault(require("resolve")); var _runSeries = _interopRequireDefault(require("run-series")); var _webpackMerge = _interopRequireDefault(require("webpack-merge")); var _debug = _interopRequireDefault(require("./debug")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Check if the given directories exist and filter out any which don't. */ function checkDirectories(dirs, cb) { (0, _runSeries.default)(dirs.map(dir => cb => _fsExtra.default.stat(dir, (err, stats) => { if (err) return cb(err.code === 'ENOENT' ? null : err); cb(null, stats.isDirectory() ? dir : null); })), (err, dirs) => { if (err) return cb(err); cb(null, dirs.filter(dir => dir != null)); }); } /** * If any of the given directories exist, display a spinner and delete them. */ function clean( // A description of what's being cleaned, e.g. 'app' desc, // Paths to delete dirs, cb) { checkDirectories(dirs, (err, dirs) => { if (err != null) return cb(err); if (dirs == null || dirs.length === 0) return cb(); let spinner = (0, _ora.default)(`Cleaning ${desc}`).start(); (0, _runSeries.default)(dirs.map(dir => cb => _fsExtra.default.remove(dir, cb)), err => { if (err) { spinner.fail(); return cb(err); } spinner.succeed(); cb(); }); }); } /** * Clear console scrollback. */ function clearConsole() { // Hack for testing if (process.env.NWB_TEST) return; // This will completely wipe scrollback in cmd.exe on Windows - use cmd.exe's // `start` command to launch nwb's dev server in a new prompt if you don't // want to lose it. process.stdout.write(process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'); } /** * Log objects in their entirety so we can see everything in debug output. */ function deepToString(object) { return _util.default.inspect(object, { colors: true, depth: null }); } /** * Check if a directory exists. */ function directoryExists(dir) { try { return _fsExtra.default.statSync(dir).isDirectory(); } catch (e) { return false; } } /** * Get a list of nwb plugin names passed as arguments. */ function getArgsPlugins(args) { let plugins = args.plugins || args.plugin; if (!plugins) return []; return plugins.split(',').map(name => name.replace(/^(nwb-)?/, 'nwb-')); } /** * Install packages from npm. */ function install( // npm package names, which may be in package@version format packages, options, cb) { let { args = null, check = false, cwd = process.cwd(), dev = false, save = false } = options; // If the command being run allows users to specify an nwb plugins option by // providing the args object here, make sure they're installed. if (args) { packages = packages.concat(getArgsPlugins(args)); } if (check) { packages = packages.filter(pkg => { // Assumption: we're not dealing with scoped packages, which start with @ let name = pkg.split('@')[0]; try { _resolve.default.sync(name, { basedir: cwd }); return false; } catch (e) { return true; } }); } if (packages.length === 0) { return process.nextTick(cb); } let npmArgs = ['install', '--silent', '--no-progress', '--no-package-lock']; if (save) { npmArgs.push(`--save${dev ? '-dev' : ''}`); } npmArgs = npmArgs.concat(packages); (0, _debug.default)(`${cwd} $ npm ${npmArgs.join(' ')}`); let spinner = (0, _ora.default)(`Installing ${joinAnd(packages)}`).start(); let npm = (0, _crossSpawn.default)('npm', npmArgs, { cwd, stdio: ['ignore', 'pipe', 'inherit'] }); npm.on('close', code => { if (code !== 0) { spinner.fail(); return cb(new Error('npm install failed')); } spinner.succeed(); cb(); }); } /** * Join multiple items with a penultimate "and". */ function joinAnd(array, lastClause = 'and') { if (array.length === 0) return ''; if (array.length === 1) return String(array[0]); return `${array.slice(0, -1).join(', ')} ${lastClause} ${array[array.length - 1]}`; } /** * Get the path to an npm module. */ function modulePath(module, basedir = process.cwd()) { return _path.default.dirname(_resolve.default.sync(`${module}/package.json`, { basedir })); } function padLines(message, padding = ' ') { return message.split('\n').map(line => `${padding}${line}`).join('\n'); } function pluralise(count, suffixes = ',s') { return suffixes.split(',')[count === 1 ? 0 : 1]; } /** * Custom merge which replaces arrays instead of concatenating them. */ const replaceArrayMerge = (0, _webpackMerge.default)({ customizeArray(a, b, key) { return b; } }); /** * Hack to generate simple config file contents by stringifying to JSON, but * without JSON formatting. */ exports.replaceArrayMerge = replaceArrayMerge; function toSource(obj) { return JSON.stringify(obj, null, 2).replace(/"([^"]+)":/g, '$1:').replace(/"/g, "'"); } /** * Better typeof. */ function typeOf(o) { if (Number.isNaN(o)) return 'nan'; return Object.prototype.toString.call(o).slice(8, -1).toLowerCase(); } /** * @param {Array<string>} strings */ function unique(strings) { // eslint-disable-next-line return Object.keys(strings.reduce((o, s) => (o[s] = true, o), {})); } /** * Removes npm package scope from package name */ function formatPackageName(name) { const scopedPackageRegex = new RegExp(`^@[a-z0-9][\\w-.]+/[a-z0-9][\\w-.]*`, 'i'); if (scopedPackageRegex.test(name)) { return name.split('/')[1]; } return name; }