import * as semver from 'semver' ; import { localize } from '../localize' ; export namespace nugetUtils { const wildcard = '*' ; export function tryGetMaxInRange ( rangeString , versions ) { let finalRange = wildcard ; const range = parseVersionRange ( rangeString ) ; if ( typeof range === 'string' ) { finalRange = range ; } else { const minVersion = range . minVersion ; if ( minVersion ) { if ( minVersion . includes ( wildcard ) ) { if ( range . includeMinVersion ) { versions = versions . filter ( v => semver . satisfies ( v , minVersion ) || semver . gtr ( v , minVersion ) ) ; } else { versions = versions . filter ( v => semver . gtr ( v , minVersion ) ) ; } } else if ( range . includeMinVersion ) { versions = versions . filter ( v => semver . gte ( v , minVersion ) ) ; } else { versions = versions . filter ( v => semver . gt ( v , minVersion ) ) ; } } const maxVersion = range . maxVersion ; if ( maxVersion ) { if ( range . includeMaxVersion ) { versions = versions . filter ( v => semver . lte ( v , maxVersion ) ) ; } else { versions = versions . filter ( v => semver . lt ( v , maxVersion ) ) ; } } } return semver . maxSatisfying ( versions , finalRange ) ; } interface IVersionRange { minVersion : string ; includeMinVersion : boolean ; maxVersion : string | undefined ; includeMaxVersion : boolean | undefined ; } function parseVersionRange ( value ) { const error = new Error ( localize ( 'invalidRange' , 'Invalid range "{0}"' , value ) ) ; value = value . trim ( ) ; if ( value === wildcard ) { return value ; } if ( value . length < 3 ) { throw error ; } let includeMinVersion ; let minVersion ; let includeMaxVersion ; let maxVersion ; if ( value [ 0 ] === '(' || value [ 0 ] === '[' ) { switch ( value [ 0 ] ) { case '[' : includeMinVersion = true ; break ; case '(' : includeMinVersion = false ; break ; default : throw error ; } switch ( value [ value . length - 1 ] ) { case ']' : includeMaxVersion = true ; break ; case ')' : includeMaxVersion = false ; break ; default : throw error ; } value = value . substring ( 1 , value . length - 1 ) ; const parts = value . split ( ',' ) . map ( p => p . trim ( ) ) ; if ( parts . length > 2 || ! parts . some ( p => ! ! p ) ) { throw error ; } minVersion = parts [ 0 ] ; maxVersion = parts . length === 2 ? parts [ 1 ] : parts [ 0 ] ; } else { if ( value . includes ( wildcard ) ) { return value ; } else { includeMinVersion = true ; minVersion = value ; } } if ( minVersion ) { if ( minVersion . includes ( wildcard ) ) { if ( ! semver . validRange ( minVersion ) ) { throw error ; } } else { minVersion = appendMissingParts ( minVersion ) ; if ( ! semver . valid ( minVersion ) ) { throw error ; } } } if ( maxVersion ) { maxVersion = appendMissingParts ( maxVersion ) ; if ( ! semver . valid ( maxVersion ) ) { throw error ; } } return { minVersion , includeMinVersion , maxVersion , includeMaxVersion } ; } /**
     * Appends ".0" until we have major, minor, and patch
     */ function appendMissingParts ( version ) { if ( /[^0-9.]/ . test ( version ) ) { return version ; } else { let count = ( version . match ( /\./g ) || [ ] ) . length ; while ( count < 2 ) { version += '.0' ; count += 1 ; } return version ; } } }