Skip to content

Commit 5bbc3fe

Browse files
authored
Downgrade to semver compatible with Node v8 (#1575)
* Downgrade to `semver` compatible with Node v8 * update
1 parent 738132c commit 5bbc3fe

File tree

2 files changed

+207
-2
lines changed

2 files changed

+207
-2
lines changed

Diff for: lib/rules/no-unsupported-features.js

+206-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ module.exports = {
129129
* @returns {boolean} `true` if it's supporting.
130130
*/
131131
function isNotSupportingVersion(aCase) {
132-
return !semver.subset(versionRange, getSemverRange(aCase.supported))
132+
return !semverSubset(versionRange, getSemverRange(aCase.supported))
133133
}
134134

135135
/** @type {TemplateListener} */
@@ -163,3 +163,208 @@ module.exports = {
163163
)
164164
}
165165
}
166+
167+
// TODO replace semver.subset() in the major version.
168+
/**
169+
* semver.subset()
170+
*
171+
* We need to use a copy of the semver source code until a major version upgrade.
172+
*
173+
* @see https://github.com/npm/node-semver/blob/e79ac3a450e8bb504e78b8159e3efc70895699b8/ranges/subset.js#L43
174+
* @license ISC at Isaac Z. Schlueter and Contributors
175+
* https://github.com/npm/node-semver/blob/master/LICENSE
176+
*
177+
* @param {semver.Range} sub
178+
* @param {semver.Range} dom
179+
*/
180+
function semverSubset(sub, dom) {
181+
if (sub === dom) return true
182+
183+
sub = new semver.Range(sub)
184+
dom = new semver.Range(dom)
185+
let sawNonNull = false
186+
187+
// eslint-disable-next-line no-labels
188+
OUTER: for (const simpleSub of sub.set) {
189+
for (const simpleDom of dom.set) {
190+
const isSub = simpleSubset(simpleSub, simpleDom)
191+
sawNonNull = sawNonNull || isSub !== null
192+
// eslint-disable-next-line no-labels
193+
if (isSub) continue OUTER
194+
}
195+
if (sawNonNull) return false
196+
}
197+
return true
198+
}
199+
200+
/**
201+
* @license ISC at Isaac Z. Schlueter and Contributors
202+
* https://github.com/npm/node-semver/blob/master/LICENSE
203+
* @param {readonly semver.Comparator[]} sub
204+
* @param {readonly semver.Comparator[]} dom
205+
*/
206+
function simpleSubset(sub, dom) {
207+
if (sub === dom) return true
208+
209+
/**
210+
* @param {semver.Comparator} c
211+
*/
212+
function isAny(c) {
213+
return Object.keys(c.semver).length === 0
214+
}
215+
216+
if (sub.length === 1 && isAny(sub[0])) {
217+
if (dom.length === 1 && isAny(dom[0])) return true
218+
else sub = [new semver.Comparator('>=0.0.0')]
219+
}
220+
221+
if (dom.length === 1 && isAny(dom[0])) {
222+
dom = [new semver.Comparator('>=0.0.0')]
223+
}
224+
225+
const eqSet = new Set()
226+
let gt, lt
227+
for (const c of sub) {
228+
if (c.operator === '>' || c.operator === '>=') gt = higherGT(gt, c)
229+
else if (c.operator === '<' || c.operator === '<=') lt = lowerLT(lt, c)
230+
else eqSet.add(c.semver)
231+
}
232+
233+
if (eqSet.size > 1) return null
234+
235+
let gtltComp
236+
if (gt && lt) {
237+
gtltComp = semver.compare(gt.semver, lt.semver)
238+
if (gtltComp > 0) return null
239+
else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<='))
240+
return null
241+
}
242+
243+
// will iterate one or zero times
244+
for (const eq of eqSet) {
245+
if (gt && !semver.satisfies(eq, String(gt))) return null
246+
247+
if (lt && !semver.satisfies(eq, String(lt))) return null
248+
249+
for (const c of dom) {
250+
if (!semver.satisfies(eq, String(c))) return false
251+
}
252+
253+
return true
254+
}
255+
256+
let higher, lower
257+
let hasDomLT, hasDomGT
258+
// if the subset has a prerelease, we need a comparator in the superset
259+
// with the same tuple and a prerelease, or it's not a subset
260+
let needDomLTPre = lt && lt.semver.prerelease.length ? lt.semver : false
261+
let needDomGTPre = gt && gt.semver.prerelease.length ? gt.semver : false
262+
// exception: <1.2.3-0 is the same as <1.2.3
263+
if (
264+
needDomLTPre &&
265+
needDomLTPre.prerelease.length === 1 &&
266+
lt &&
267+
lt.operator === '<' &&
268+
needDomLTPre.prerelease[0] === 0
269+
) {
270+
needDomLTPre = false
271+
}
272+
273+
for (const c of dom) {
274+
hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='
275+
hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='
276+
if (gt) {
277+
if (needDomGTPre) {
278+
if (
279+
c.semver.prerelease &&
280+
c.semver.prerelease.length &&
281+
c.semver.major === needDomGTPre.major &&
282+
c.semver.minor === needDomGTPre.minor &&
283+
c.semver.patch === needDomGTPre.patch
284+
) {
285+
needDomGTPre = false
286+
}
287+
}
288+
if (c.operator === '>' || c.operator === '>=') {
289+
higher = higherGT(gt, c)
290+
if (higher === c && higher !== gt) return false
291+
} else if (
292+
gt.operator === '>=' &&
293+
!semver.satisfies(gt.semver, String(c))
294+
)
295+
return false
296+
}
297+
if (lt) {
298+
if (needDomLTPre) {
299+
if (
300+
c.semver.prerelease &&
301+
c.semver.prerelease.length &&
302+
c.semver.major === needDomLTPre.major &&
303+
c.semver.minor === needDomLTPre.minor &&
304+
c.semver.patch === needDomLTPre.patch
305+
) {
306+
needDomLTPre = false
307+
}
308+
}
309+
if (c.operator === '<' || c.operator === '<=') {
310+
lower = lowerLT(lt, c)
311+
if (lower === c && lower !== lt) return false
312+
} else if (
313+
lt.operator === '<=' &&
314+
!semver.satisfies(lt.semver, String(c))
315+
)
316+
return false
317+
}
318+
if (!c.operator && (lt || gt) && gtltComp !== 0) return false
319+
}
320+
321+
// if there was a < or >, and nothing in the dom, then must be false
322+
// UNLESS it was limited by another range in the other direction.
323+
// Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0
324+
if (gt && hasDomLT && !lt && gtltComp !== 0) return false
325+
326+
if (lt && hasDomGT && !gt && gtltComp !== 0) return false
327+
328+
// we needed a prerelease range in a specific tuple, but didn't get one
329+
// then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0,
330+
// because it includes prereleases in the 1.2.3 tuple
331+
if (needDomGTPre || needDomLTPre) return false
332+
333+
return true
334+
}
335+
336+
/**
337+
* @license ISC at Isaac Z. Schlueter and Contributors
338+
* https://github.com/npm/node-semver/blob/master/LICENSE
339+
* @param {semver.Comparator | void} a
340+
* @param {semver.Comparator} b
341+
*/
342+
const higherGT = (a, b) => {
343+
if (!a) return b
344+
const comp = semver.compare(a.semver, b.semver)
345+
return comp > 0
346+
? a
347+
: comp < 0
348+
? b
349+
: b.operator === '>' && a.operator === '>='
350+
? b
351+
: a
352+
}
353+
354+
/**
355+
* @license ISC at Isaac Z. Schlueter and Contributors
356+
* https://github.com/npm/node-semver/blob/master/LICENSE
357+
* @param {semver.Comparator | void} a
358+
* @param {semver.Comparator} b
359+
*/
360+
const lowerLT = (a, b) => {
361+
if (!a) return b
362+
const comp = semver.compare(a.semver, b.semver)
363+
return comp < 0
364+
? a
365+
: comp > 0
366+
? b
367+
: b.operator === '<' && a.operator === '<='
368+
? b
369+
: a
370+
}

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"dependencies": {
5656
"eslint-utils": "^2.1.0",
5757
"natural-compare": "^1.4.0",
58-
"semver": "^7.3.2",
58+
"semver": "^6.3.0",
5959
"vue-eslint-parser": "^7.8.0"
6060
},
6161
"devDependencies": {

0 commit comments

Comments
 (0)