JezK
Edit File: upgrade.js
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.cleanLockfile = cleanLockfile; exports.getOutdated = getOutdated; exports.hasWrapper = hasWrapper; exports.requireLockfile = void 0; exports.run = run; exports.setFlags = setFlags; function _regenerator() { var data = _interopRequireDefault(require("@babel/runtime/regenerator")); _regenerator = function _regenerator() { return data; }; return data; } function _asyncToGenerator2() { var data = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); _asyncToGenerator2 = function _asyncToGenerator2() { return data; }; return data; } function _add() { var data = require("./add.js"); _add = function _add() { return data; }; return data; } function _lockfile() { var data = _interopRequireDefault(require("../../lockfile")); _lockfile = function _lockfile() { return data; }; return data; } function _packageRequest() { var data = _interopRequireDefault(require("../../package-request.js")); _packageRequest = function _packageRequest() { return data; }; return data; } function _normalizePattern() { var data = require("../../util/normalize-pattern.js"); _normalizePattern = function _normalizePattern() { return data; }; return data; } function _install() { var data = require("./install.js"); _install = function _install() { return data; }; return data; } // used to detect whether a semver range is simple enough to preserve when doing a --latest upgrade. // when not matched, the upgraded version range will default to `^` the same as the `add` command would. var basicSemverOperatorRegex = new RegExp('^(\\^|~|>=|<=)?[^ |&,]+$'); // used to detect if a passed parameter is a scope or a package name. var validScopeRegex = /^@[a-zA-Z0-9-][a-zA-Z0-9_.-]*\/$/; // If specific versions were requested for packages, override what getOutdated reported as the latest to install // Also add ones that are missing, since the requested packages may not have been outdated at all. function setUserRequestedPackageVersions(deps, args, latest, packagePatterns, reporter) { args.forEach(function (requestedPattern) { var found = false; var normalized = (0, _normalizePattern().normalizePattern)(requestedPattern); // if the user specified a package name without a version range, then that implies "latest" // but if the latest flag is not passed then we need to use the version range from package.json if (!normalized.hasVersion && !latest) { packagePatterns.forEach(function (packagePattern) { var packageNormalized = (0, _normalizePattern().normalizePattern)(packagePattern.pattern); if (packageNormalized.name === normalized.name) { normalized = packageNormalized; } }); } var newPattern = "".concat(normalized.name, "@").concat(normalized.range); // if this dependency is already in the outdated list, // just update the upgradeTo to whatever version the user requested. deps.forEach(function (dep) { if (normalized.hasVersion && dep.name === normalized.name) { found = true; dep.upgradeTo = newPattern; reporter.verbose(reporter.lang('verboseUpgradeBecauseRequested', requestedPattern, newPattern)); } }); // if this dependency was not in the outdated list, // then add a new entry if (normalized.hasVersion && !found) { deps.push({ name: normalized.name, wanted: '', latest: '', url: '', hint: '', range: '', current: '', upgradeTo: newPattern, workspaceName: '', workspaceLoc: '' }); reporter.verbose(reporter.lang('verboseUpgradeBecauseRequested', requestedPattern, newPattern)); } }); } // this function attempts to determine the range operator on the semver range. // this will only handle the simple cases of a semver starting with '^', '~', '>=', '<=', or an exact version. // "exotic" semver ranges will not be handled. function getRangeOperator(version) { var result = basicSemverOperatorRegex.exec(version); return result ? result[1] || '' : '^'; } // Attempt to preserve the range operator from the package.json specified semver range. // If an explicit operator was specified using --exact, --tilde, --caret, then that will take precedence. function buildPatternToUpgradeTo(dep, flags) { if (dep.latest === 'exotic') { return "".concat(dep.name, "@").concat(dep.url); } var toLatest = flags.latest; var toVersion = toLatest ? dep.latest : dep.range; var rangeOperator = ''; if (toLatest) { if (flags.caret) { rangeOperator = '^'; } else if (flags.tilde) { rangeOperator = '~'; } else if (flags.exact) { rangeOperator = ''; } else { rangeOperator = getRangeOperator(dep.range); } } return "".concat(dep.name, "@").concat(rangeOperator).concat(toVersion); } function scopeFilter(flags, dep) { if (validScopeRegex.test(flags.scope)) { return dep.name.startsWith(flags.scope); } return true; } // Remove deps being upgraded from the lockfile, or else Add will use the already-installed version // instead of the latest for the range. // We do this recursively so that when Yarn installs the potentially updated transitive deps, // it may upgrade them too instead of just using the "locked" version from the lockfile. // Transitive dependencies that are also a direct dependency are skipped. function cleanLockfile(lockfile, deps, packagePatterns, reporter) { function cleanDepFromLockfile(pattern, depth) { var lockManifest = lockfile.getLocked(pattern); if (!lockManifest || depth > 1 && packagePatterns.some(function (packagePattern) { return packagePattern.pattern === pattern; })) { reporter.verbose(reporter.lang('verboseUpgradeNotUnlocking', pattern)); return; } var dependencies = Object.assign({}, lockManifest.dependencies || {}, lockManifest.optionalDependencies || {}); var depPatterns = Object.keys(dependencies).map(function (key) { return "".concat(key, "@").concat(dependencies[key]); }); reporter.verbose(reporter.lang('verboseUpgradeUnlocking', pattern)); lockfile.removePattern(pattern); depPatterns.forEach(function (pattern) { return cleanDepFromLockfile(pattern, depth + 1); }); } var patterns = deps.map(function (dep) { return dep.upgradeTo; }); patterns.forEach(function (pattern) { return cleanDepFromLockfile(pattern, 1); }); } function setFlags(commander) { commander.description('Upgrades packages to their latest version based on the specified range.'); commander.usage('upgrade [flags]'); commander.option('-S, --scope <scope>', 'upgrade packages under the specified scope'); commander.option('-L, --latest', 'list the latest version of packages, ignoring version ranges in package.json'); commander.option('-E, --exact', 'install exact version. Only used when --latest is specified.'); commander.option('-P, --pattern [pattern]', 'upgrade packages that match pattern'); commander.option('-T, --tilde', 'install most recent release with the same minor version. Only used when --latest is specified.'); commander.option('-C, --caret', 'install most recent release with the same major version. Only used when --latest is specified.'); commander.option('-A, --audit', 'Run vulnerability audit on installed packages'); } function hasWrapper(commander, args) { return true; } var requireLockfile = true; exports.requireLockfile = requireLockfile; function run(_x, _x2, _x3, _x4, _x5) { return _run.apply(this, arguments); } function _run() { _run = (0, _asyncToGenerator2()["default"])( /*#__PURE__*/_regenerator()["default"].mark(function _callee(config, reporter, commander, flags, args) { var addArgs, upgradeAll, addFlags, lockfile, deps, install, _yield$install$fetchR, packagePatterns, add; return _regenerator()["default"].wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: addArgs = []; upgradeAll = args.length === 0 && typeof flags.scope === 'undefined' && typeof flags.pattern === 'undefined'; addFlags = Object.assign({}, flags, { force: true, ignoreWorkspaceRootCheck: true, workspaceRootIsCwd: config.cwd === config.lockfileFolder }); _context.next = 5; return _lockfile()["default"].fromDirectory(config.lockfileFolder, reporter); case 5: lockfile = _context.sent; _context.next = 8; return getOutdated(config, reporter, flags, lockfile, args); case 8: deps = _context.sent; install = new (_install().Install)(flags, config, reporter, lockfile); _context.next = 12; return install.fetchRequestFromCwd(); case 12: _yield$install$fetchR = _context.sent; packagePatterns = _yield$install$fetchR.requests; setUserRequestedPackageVersions(deps, args, flags.latest, packagePatterns, reporter); cleanLockfile(lockfile, deps, packagePatterns, reporter); addArgs = deps.map(function (dep) { return dep.upgradeTo; }); if (flags.scope && validScopeRegex.test(flags.scope)) { addArgs = addArgs.filter(function (depName) { return depName.startsWith(flags.scope); }); } add = new (_add().Add)(addArgs, addFlags, config, reporter, upgradeAll ? new (_lockfile()["default"])() : lockfile); _context.next = 21; return add.init(); case 21: case "end": return _context.stop(); } }, _callee); })); return _run.apply(this, arguments); } function getOutdated(_x6, _x7, _x8, _x9, _x10) { return _getOutdated.apply(this, arguments); } function _getOutdated() { _getOutdated = (0, _asyncToGenerator2()["default"])( /*#__PURE__*/_regenerator()["default"].mark(function _callee2(config, reporter, flags, lockfile, patterns) { var install, outdatedFieldName, normalizeScope, versionFilter, deps; return _regenerator()["default"].wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: install = new (_install().Install)(flags, config, reporter, lockfile); outdatedFieldName = flags.latest ? 'latest' : 'wanted'; // ensure scope is of the form `@scope/` normalizeScope = function normalizeScope() { if (flags.scope) { if (!flags.scope.startsWith('@')) { flags.scope = '@' + flags.scope; } if (!flags.scope.endsWith('/')) { flags.scope += '/'; } } }; versionFilter = function versionFilter(dep) { return dep.current !== dep[outdatedFieldName]; }; if (!flags.latest) { // these flags only have an affect when --latest is used flags.tilde = false; flags.exact = false; flags.caret = false; } normalizeScope(); _context2.next = 8; return _packageRequest()["default"].getOutdatedPackages(lockfile, install, config, reporter, patterns, flags); case 8: deps = _context2.sent.filter(versionFilter).filter(scopeFilter.bind(this, flags)); deps.forEach(function (dep) { dep.upgradeTo = buildPatternToUpgradeTo(dep, flags); reporter.verbose(reporter.lang('verboseUpgradeBecauseOutdated', dep.name, dep.upgradeTo)); }); return _context2.abrupt("return", deps); case 11: case "end": return _context2.stop(); } }, _callee2, this); })); return _getOutdated.apply(this, arguments); } //# sourceMappingURL=upgrade.js.map