UNPKG

counsel

Version:

the end of boilerplate. automatically bake structure, opinions, and business rules into projects

82 lines (77 loc) 2.55 kB
import semver from 'semver' import { Context } from './counsel' // eslint-disable-line no-unused-vars import { map } from 'lodash' import { Dependency } from './interfaces' // eslint-disable-line no-unused-vars export const dependencyToString = ({ name, range }: Dependency) => `${name}@${range}` export const fromNameVersionObject = (obj: { [name: string]: string }) => map(obj, (version, name) => toFullyQualifiedDependency(name, version)) export const toFullyQualifiedDependency = ( name: string, range: string ): Dependency => { const isValidRange = !!semver.validRange(range) if (!isValidRange) { throw new Error( [ `unable to convert ${name}@${range} to`, `a valid SemVer range. do you need to add a`, '@<semver-version> suffix to the package name? e.g.:\n', '\tstandard@*, debug@^5, koa@2.0.x' ].join(' ') ) } return { name, range } } /** * takes a set of packages currently installed A, a set of packages requested to * be installed B, returns the set difference B - A */ export const filterToInstallPackages = ( current: Dependency[], toInstall: Dependency[], logger: Context['logger'] ): Dependency[] => { const toInstallByName: { [key: string]: Dependency } = {} for (const dependency of toInstall) { if (toInstallByName[dependency.name]) { logger.warn( `duplicated install request for dependency ${ dependency.name } [version: ${dependency.range}]` ) } toInstallByName[dependency.name] = dependency } for (const dependency of current) { if (dependency.name in toInstallByName) { const targetRange = toInstallByName[dependency.name].range let isIntersecting = true try { isIntersecting = semver.intersects(dependency.range, targetRange) } catch (err) { logger.verbose( [ 'semver intersect failed. see: https://github.com/npm/node-semver/issues/266.', 'ignoring error and proceeding' ].join(' ') ) } if (!isIntersecting) { throw new Error( [ `requested to install ${ dependency.name }@${targetRange}, but an incompatible`, `version/range @${ dependency.range } is already installed. please remove or`, 'widen your current or target semver ranges' ].join(' ') ) } delete toInstallByName[dependency.name] } } return Object.values(toInstallByName) }