1 | const got = require('got')
|
2 | const path = require('path')
|
3 | const semver = require('semver')
|
4 | const { writeFile } = require('fs').promises
|
5 |
|
6 | async function getJSONFromCDN (urlPath) {
|
7 | const response = await got(`https://cdn.jsdelivr.net/gh/${urlPath}`)
|
8 | return JSON.parse(response.body)
|
9 | }
|
10 |
|
11 | async function fetchElectronReleases () {
|
12 | return (await getJSONFromCDN('electron/releases/lite.json'))
|
13 | }
|
14 |
|
15 | async function fetchNodeVersions () {
|
16 | const schedule = await getJSONFromCDN('nodejs/Release/schedule.json')
|
17 | const versions = {}
|
18 |
|
19 | for (const [majorVersion, metadata] of Object.entries(schedule)) {
|
20 | if (majorVersion.startsWith('v0')) {
|
21 | continue
|
22 | }
|
23 | const version = `${majorVersion.slice(1)}.0.0`
|
24 | const lts = metadata.hasOwnProperty('lts') ? [metadata.lts, metadata.maintenance] : false
|
25 | versions[version] = {
|
26 | runtime: 'node',
|
27 | target: version,
|
28 | lts: lts,
|
29 | future: new Date(Date.parse(metadata.start)) > new Date()
|
30 | }
|
31 | }
|
32 |
|
33 | return versions
|
34 | }
|
35 |
|
36 | async function fetchAbiVersions () {
|
37 | return (await getJSONFromCDN('nodejs/node/doc/abi_version_registry.json'))
|
38 | .NODE_MODULE_VERSION
|
39 | .filter(({ modules }) => modules > 66)
|
40 | }
|
41 |
|
42 | function electronReleasesToTargets (releases) {
|
43 | const versions = releases.map(({ version }) => version)
|
44 | const versionsByModules = releases
|
45 | .filter(release => release.deps && Number(release.deps.modules) >= 70)
|
46 | .map(({ version, deps: { modules } }) => ({
|
47 | version,
|
48 | modules,
|
49 | }))
|
50 | .reduce(
|
51 | (acc, { modules, version }) => ({
|
52 | ...acc,
|
53 | [modules]: version,
|
54 | }),
|
55 | {}
|
56 | )
|
57 |
|
58 | return Object.entries(versionsByModules)
|
59 | .map(
|
60 | ([modules, version]) => ({
|
61 | abi: modules,
|
62 | future: !versions.find(
|
63 | v => {
|
64 | const major = version.split(".")[0]
|
65 | return semver.satisfies(
|
66 | v,
|
67 | /^[0-9]/.test(major) ? `>= ${major}` : major
|
68 | )
|
69 | }
|
70 | ),
|
71 | lts: false,
|
72 | runtime: 'electron',
|
73 | target: version
|
74 | })
|
75 | )
|
76 | }
|
77 |
|
78 | function nodeVersionsToTargets (abiVersions, nodeVersions) {
|
79 | return Object.values(
|
80 | abiVersions
|
81 | .filter(({ runtime }) => runtime === 'node')
|
82 | .reduce(
|
83 | (acc, abiVersion) => {
|
84 | const { version: nodeVersion } = semver.coerce(abiVersion.versions)
|
85 |
|
86 | return {
|
87 | [nodeVersion]: {
|
88 | ...nodeVersions[nodeVersion],
|
89 | abi: abiVersion.modules.toString(),
|
90 | },
|
91 | ...acc,
|
92 | };
|
93 | },
|
94 | {}
|
95 | )
|
96 | )
|
97 | }
|
98 |
|
99 | async function main () {
|
100 | const nodeVersions = await fetchNodeVersions()
|
101 | const abiVersions = await fetchAbiVersions()
|
102 | const electronReleases = await fetchElectronReleases()
|
103 | const electronTargets = electronReleasesToTargets(electronReleases)
|
104 | const nodeTargets = nodeVersionsToTargets(abiVersions, nodeVersions)
|
105 | const supportedTargets = [
|
106 | ...nodeTargets,
|
107 | ...electronTargets,
|
108 | ]
|
109 |
|
110 | await writeFile(path.resolve(__dirname, '..', 'abi_registry.json'), JSON.stringify(supportedTargets, null, 2))
|
111 | }
|
112 |
|
113 | main()
|