UNPKG

npminstall

Version:

Make npm install fast and handy.

100 lines (89 loc) 2.99 kB
const minimatch = require('minimatch'); const chalk = require('chalk'); const utils = require('./utils'); const { parsePackageName } = require('./alias'); const npa = require('./npa'); // https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md#package-designation // https://github.com/yarnpkg/yarn/blob/3119382885/src/util/parse-package-path.js#L10 const WRONG_PATTERNS = /\/$|\/{2,}|\*+$/; // createResolution module.exports = (pkg, options) => { const resolutions = pkg && pkg.resolutions || {}; const resolutionMap = new Map(); // parse resolutions, generate resolutionMap: // { // debug: [ // "koa/accept", "1.0.0", // "send": "2.0.0" // ], // less: [ // "**", "^1" // ], // vary: [ // "@koa/cors", "1.0.0" // ] // } for (const path in resolutions) { const sections = path.split('/'); let scope = ''; const packages = []; // 1. check package name if (WRONG_PATTERNS.test(path)) { throw new Error(`[resolutions] resolution package ${path} format error`); } // 2. process package with scope like `@koa/cors` for (let section of sections) { if (section.startsWith('@') && !scope) { scope = section; continue; } if (scope) { section = `${scope}/${section}`; scope = ''; } packages.push(section); } // debug => **/debug if (packages.length === 1) packages.unshift('**'); const endpoint = packages.pop(); const version = resolutions[path]; if (!resolutionMap.has(endpoint)) resolutionMap.set(endpoint, []); resolutionMap.get(endpoint).push([ packages.join('/'), version ]); } return (pkg, ancestors, nested) => { // only work for nested dependencies if (!ancestors.length) return pkg; // check pkg.name first to reduce calculate const resolutions = resolutionMap.get(pkg.name); if (!resolutions) return pkg; const ancestorPath = ancestors.map(ancestor => ancestor.name).join('/'); for (const resolution of resolutions) { const path = resolution[0]; const version = resolution[1]; if (minimatch(ancestorPath, path)) { options.pendingMessages.push([ 'warn', '%s %s override by %s', chalk.yellow('resolutions'), chalk.gray(utils.getDisplayName(pkg, ancestors)), chalk.magenta(`${path}/${pkg.name}@${version}`), ]); // alias(npm:lodash@^1) support const [ aliasPackageName, realPackageName ] = parsePackageName(`${pkg.name}@${version}`, nested); if (aliasPackageName) { const { name, fetchSpec, } = npa(realPackageName, { nested }); return Object.assign({}, pkg, { alias: aliasPackageName, version: fetchSpec, name, }); } return Object.assign({}, pkg, { version }); } } return pkg; }; };