/
index.js
132 lines (116 loc) · 3.6 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'use strict'
const figgyPudding = require('figgy-pudding')
const npa = require('npm-package-arg')
const semver = require('semver')
const PickerOpts = figgyPudding({
defaultTag: { default: 'latest' },
enjoyBy: {},
includeDeprecated: { default: false }
})
module.exports = pickManifest
function pickManifest (packument, wanted, opts) {
opts = PickerOpts(opts)
const time = opts.enjoyBy && packument.time && +(new Date(opts.enjoyBy))
const spec = npa.resolve(packument.name, wanted)
const type = spec.type
if (type === 'version' || type === 'range') {
wanted = semver.clean(wanted, true) || wanted
}
const distTags = packument['dist-tags'] || {}
const versions = Object.keys(packument.versions || {}).filter(v => {
return semver.valid(v, true)
})
const policyRestrictions = packument.policyRestrictions
const restrictedVersions = policyRestrictions
? Object.keys(policyRestrictions.versions) : []
function enjoyableBy (v) {
return !time || (
packument.time[v] && time >= +(new Date(packument.time[v]))
)
}
let err
if (!versions.length && !restrictedVersions.length) {
err = new Error(`No valid versions available for ${packument.name}`)
err.code = 'ENOVERSIONS'
err.name = packument.name
err.type = type
err.wanted = wanted
throw err
}
let target
if (type === 'tag' && enjoyableBy(distTags[wanted])) {
target = distTags[wanted]
} else if (type === 'version') {
target = wanted
} else if (type !== 'range' && enjoyableBy(distTags[wanted])) {
throw new Error('Only tag, version, and range are supported')
}
const tagVersion = distTags[opts.defaultTag]
if (
!target &&
tagVersion &&
packument.versions[tagVersion] &&
enjoyableBy(tagVersion) &&
semver.satisfies(tagVersion, wanted, true)
) {
target = tagVersion
}
if (!target && !opts.includeDeprecated) {
const undeprecated = versions.filter(v => !packument.versions[v].deprecated && enjoyableBy(v)
)
target = semver.maxSatisfying(undeprecated, wanted, true)
}
if (!target) {
const stillFresh = versions.filter(enjoyableBy)
target = semver.maxSatisfying(stillFresh, wanted, true)
}
if (!target && wanted === '*' && enjoyableBy(tagVersion)) {
// This specific corner is meant for the case where
// someone is using `*` as a selector, but all versions
// are pre-releases, which don't match ranges at all.
target = tagVersion
}
if (
!target &&
time &&
type === 'tag' &&
distTags[wanted] &&
!enjoyableBy(distTags[wanted])
) {
const stillFresh = versions.filter(v =>
enjoyableBy(v) && semver.lte(v, distTags[wanted], true)
).sort(semver.rcompare)
target = stillFresh[0]
}
const manifest = (
target &&
packument.versions[target]
)
if (!manifest) {
// Check if target is forbidden
const isForbidden = target && policyRestrictions && policyRestrictions.versions[target]
const pckg = `${packument.name}@${wanted}${
opts.enjoyBy
? ` with an Enjoy By date of ${
new Date(opts.enjoyBy).toLocaleString()
}. Maybe try a different date?`
: ''
}`
if (isForbidden) {
err = new Error(`Could not download ${pckg} due to policy violations.\n${policyRestrictions.message}\n`)
err.code = 'E403'
} else {
err = new Error(`No matching version found for ${pckg}.`)
err.code = 'ETARGET'
}
err.name = packument.name
err.type = type
err.wanted = wanted
err.versions = versions
err.distTags = distTags
err.defaultTag = opts.defaultTag
throw err
} else {
return manifest
}
}