-
-
Notifications
You must be signed in to change notification settings - Fork 934
/
index.ts
75 lines (69 loc) · 2.29 KB
/
index.ts
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
import { FetchFromRegistry } from '@pnpm/fetching-types'
import semver from 'semver'
import versionSelectorType from 'version-selector-type'
interface NodeVersion {
version: string
lts: false | string
}
const SEMVER_OPTS = {
includePrerelease: true,
loose: true,
}
export async function resolveNodeVersion (
fetch: FetchFromRegistry,
versionSpec: string,
nodeMirrorBaseUrl?: string
): Promise<string | null> {
const allVersions = await fetchAllVersions(fetch, nodeMirrorBaseUrl)
if (versionSpec === 'latest') {
return allVersions[0].version
}
const { versions, versionRange } = filterVersions(allVersions, versionSpec)
return semver.maxSatisfying(versions, versionRange, SEMVER_OPTS) ?? null
}
export async function resolveNodeVersions (
fetch: FetchFromRegistry,
versionSpec?: string,
nodeMirrorBaseUrl?: string
): Promise<string[]> {
const allVersions = await fetchAllVersions(fetch, nodeMirrorBaseUrl)
if (!versionSpec) {
return allVersions.map(({ version }) => version)
}
if (versionSpec === 'latest') {
return [allVersions[0].version]
}
const { versions, versionRange } = filterVersions(allVersions, versionSpec)
return versions.filter(version => semver.satisfies(version, versionRange, SEMVER_OPTS))
}
async function fetchAllVersions (fetch: FetchFromRegistry, nodeMirrorBaseUrl?: string): Promise<NodeVersion[]> {
const response = await fetch(`${nodeMirrorBaseUrl ?? 'https://nodejs.org/download/release/'}index.json`)
return ((await response.json()) as NodeVersion[]).map(({ version, lts }) => ({
version: version.substring(1),
lts,
}))
}
function filterVersions (versions: NodeVersion[], versionSelector: string) {
if (versionSelector === 'lts') {
return {
versions: versions
.filter(({ lts }) => lts !== false)
.map(({ version }) => version),
versionRange: '*',
}
}
const vst = versionSelectorType(versionSelector)
if (vst?.type === 'tag') {
const wantedLtsVersion = vst.normalized.toLowerCase()
return {
versions: versions
.filter(({ lts }) => typeof lts === 'string' && lts.toLowerCase() === wantedLtsVersion)
.map(({ version }) => version),
versionRange: '*',
}
}
return {
versions: versions.map(({ version }) => version),
versionRange: versionSelector,
}
}