-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathupdate-abi-registry.js
134 lines (118 loc) · 3.73 KB
/
update-abi-registry.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
133
134
import { writeFile } from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url';
import semver from 'semver'
function sortByElectronVersionFn (a, b) {
const modulesComp = Number(a.modules) - Number(b.modules)
if (modulesComp !== 0) return modulesComp
if (semver.lt(a.version, b.version)) return 1
if (semver.gt(a.version, b.version)) return -1
return 0
}
function sortByNodeVersionFn (a, b) {
const abiComp = Number(a.abi) - Number(b.abi)
if (abiComp !== 0) return abiComp
if (semver.lt(a.target, b.target)) return 1
if (semver.gt(a.target, b.target)) return -1
return 0
}
async function getJSONFromCDN (urlPath) {
return fetch(`https://cdn.jsdelivr.net/gh/${urlPath}`).then((resp) => resp.json())
}
async function fetchElectronReleases () {
return fetch(`https://electronjs.org/headers/index.json`).then((resp) => resp.json())
}
async function fetchNodeVersions () {
const schedule = await getJSONFromCDN('nodejs/Release@main/schedule.json')
const versions = {}
for (const [majorVersion, metadata] of Object.entries(schedule)) {
if (majorVersion.startsWith('v0')) {
continue
}
const version = `${majorVersion.slice(1)}.0.0`
const lts = metadata.hasOwnProperty('lts') ? [metadata.lts, metadata.maintenance] : false
versions[version] = {
runtime: 'node',
target: version,
lts: lts,
future: new Date(Date.parse(metadata.start)) > new Date()
}
}
return versions
}
async function fetchAbiVersions () {
return (await getJSONFromCDN('nodejs/node@main/doc/abi_version_registry.json'))
.NODE_MODULE_VERSION
.filter(({ modules }) => modules > 66)
}
function electronReleasesToTargets (releases) {
const versions = releases.map(({ version }) => version)
const versionsByModules = releases
.filter(release => Number(release.modules) >= 70)
.map(({ version, modules }) => ({
version,
modules,
}))
.filter(({ version }) => !version.includes('nightly'))
.sort(sortByElectronVersionFn)
.reduce(
(acc, { modules, version }) => ({
...acc,
[`${version.split('.')[0]}-${modules}`]: {
version,
modules,
}
}),
{}
)
return Object.entries(versionsByModules)
.map(
([major, {version, modules}]) => ({
abi: modules,
future: !versions.find(
v => {
const major = version.split(".")[0]
return semver.satisfies(
v,
/^[0-9]/.test(major) ? `>= ${major}` : major
)
}
),
lts: false,
runtime: 'electron',
target: version
})
)
}
function nodeVersionsToTargets (abiVersions, nodeVersions) {
return Object.values(
abiVersions
.filter(({ runtime }) => runtime === 'node')
.reduce(
(acc, abiVersion) => {
const { version: nodeVersion } = semver.coerce(abiVersion.versions)
return {
[nodeVersion]: {
...nodeVersions[nodeVersion],
abi: abiVersion.modules.toString(),
},
...acc,
};
},
{}
)
).sort(sortByNodeVersionFn)
}
async function main () {
const nodeVersions = await fetchNodeVersions()
const abiVersions = await fetchAbiVersions()
const electronReleases = await fetchElectronReleases()
const electronTargets = electronReleasesToTargets(electronReleases)
const nodeTargets = nodeVersionsToTargets(abiVersions, nodeVersions)
const supportedTargets = [
...nodeTargets,
...electronTargets,
]
await writeFile(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'abi_registry.json'), JSON.stringify(supportedTargets, null, 2))
}
main()