mirror of
https://github.com/webinstall/webi-installers.git
synced 2026-02-14 17:49:53 +00:00
ref(webi): complete transition from 'request' for 'fetch'
This commit is contained in:
@@ -41,9 +41,7 @@ if (module === require.main) {
|
||||
'https://git.rootprojects.org',
|
||||
'',
|
||||
'',
|
||||
).then(
|
||||
function (all) {
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
},
|
||||
);
|
||||
).then(function (all) {
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ let HostTargets = require('./build-classifier/host-targets.js');
|
||||
let Lexver = require('./build-classifier/lexver.js');
|
||||
let Triplet = require('./build-classifier/triplet.js');
|
||||
|
||||
let request = require('@root/request');
|
||||
|
||||
var ALIAS_RE = /^alias: (\w+)$/m;
|
||||
|
||||
var LEGACY_ARCH_MAP = {
|
||||
@@ -153,7 +151,7 @@ async function getLatestBuilds(Releases, installersDir, cacheDir, name, date) {
|
||||
}
|
||||
|
||||
async function getLatestBuildsInner(Releases, cacheDir, name, date) {
|
||||
let data = await Releases.latest(request);
|
||||
let data = await Releases.latest();
|
||||
|
||||
if (!date) {
|
||||
date = new Date();
|
||||
|
||||
@@ -6,8 +6,6 @@ let Path = require('node:path');
|
||||
let BuildsCacher = require('./builds-cacher.js');
|
||||
let Triplet = require('./build-classifier/triplet.js');
|
||||
|
||||
let request = require('@root/request');
|
||||
|
||||
async function main() {
|
||||
let projName = process.argv[2];
|
||||
if (!projName) {
|
||||
@@ -47,7 +45,7 @@ async function main() {
|
||||
Releases.latest = Releases;
|
||||
}
|
||||
|
||||
let projInfo = await Releases.latest(request);
|
||||
let projInfo = await Releases.latest();
|
||||
|
||||
// let packages = await Builds.getPackage({ name: projName });
|
||||
// console.log(packages);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
var Releases = module.exports;
|
||||
|
||||
var path = require('path');
|
||||
var request = require('@root/request');
|
||||
var _normalize = require('./normalize.js');
|
||||
|
||||
var cache = {};
|
||||
@@ -28,7 +27,7 @@ Releases.get = async function (pkgdir) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
let all = await get.latest(request);
|
||||
let all = await get.latest();
|
||||
|
||||
return _normalize(all);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
var FLUTTER_OSES = ['macos', 'linux', 'windows'];
|
||||
|
||||
// stable, beta, dev
|
||||
/**
|
||||
* stable, beta, dev
|
||||
* @type {Object.<String, Boolean>}
|
||||
*/
|
||||
var channelMap = {};
|
||||
|
||||
// This can be spot-checked against
|
||||
@@ -53,25 +56,39 @@ var channelMap = {};
|
||||
// ]
|
||||
// }
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} [_version]
|
||||
* @prop {Boolean} lts
|
||||
* @prop {String} channel
|
||||
* @prop {String} date
|
||||
* @prop {String} download
|
||||
* @prop {String} [_filename]
|
||||
*/
|
||||
|
||||
module.exports = async function () {
|
||||
let all = {
|
||||
download: '',
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
/** @type {Array<String>} */
|
||||
channels: [],
|
||||
};
|
||||
|
||||
for (let osname of FLUTTER_OSES) {
|
||||
const response = await fetch(`https://storage.googleapis.com/flutter_infra_release/releases/releases_${osname}.json`, {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
let response = await fetch(
|
||||
`https://storage.googleapis.com/flutter_infra_release/releases/releases_${osname}.json`,
|
||||
{ headers: { Accept: 'application/json' } },
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch data for ${osname}: ${response.statusText}`);
|
||||
throw new Error(
|
||||
`Failed to fetch data for ${osname}: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
const respBody = await response.json();
|
||||
|
||||
let osBaseUrl = respBody.base_url;
|
||||
let osReleases = respBody.releases;
|
||||
let data = await response.json();
|
||||
let osBaseUrl = data.base_url;
|
||||
let osReleases = data.releases;
|
||||
|
||||
for (let asset of osReleases) {
|
||||
if (!channelMap[asset.channel]) {
|
||||
@@ -100,7 +117,7 @@ module.exports = async function () {
|
||||
};
|
||||
|
||||
if (module === require.main) {
|
||||
module.exports(require('@root/request')).then(function (all) {
|
||||
module.exports().then(function (all) {
|
||||
all.releases = all.releases.slice(25);
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
});
|
||||
|
||||
119
go/releases.js
119
go/releases.js
@@ -1,14 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
/** @type {Object.<String, String>} */
|
||||
var osMap = {
|
||||
darwin: 'macos',
|
||||
};
|
||||
/** @type {Object.<String, String>} */
|
||||
var archMap = {
|
||||
386: 'x86',
|
||||
};
|
||||
|
||||
let ODDITIES = ['bootstrap', '-arm6.'];
|
||||
|
||||
/**
|
||||
* @param {String} filename
|
||||
*/
|
||||
function isOdd(filename) {
|
||||
for (let oddity of ODDITIES) {
|
||||
let isOddity = filename.includes(oddity);
|
||||
@@ -18,6 +23,21 @@ function isOdd(filename) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} [_version]
|
||||
* @prop {String} arch
|
||||
* @prop {String} channel
|
||||
* @prop {String} date
|
||||
* @prop {String} download
|
||||
* @prop {String} ext
|
||||
* @prop {String} [_filename]
|
||||
* @prop {String} hash
|
||||
* @prop {Boolean} lts
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
async function getDistributables() {
|
||||
/*
|
||||
{
|
||||
@@ -37,60 +57,63 @@ async function getDistributables() {
|
||||
]
|
||||
};
|
||||
*/
|
||||
const response = await fetch('https://golang.org/dl/?mode=json&include=all', {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch Go releases: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const goReleases = await response.json();
|
||||
const all = {
|
||||
releases: [],
|
||||
download: '',
|
||||
};
|
||||
|
||||
goReleases.forEach((release) => {
|
||||
// Strip 'go' prefix and standardize version
|
||||
const parts = release.version.slice(2).split('.');
|
||||
while (parts.length < 3) {
|
||||
parts.push('0');
|
||||
}
|
||||
const version = parts.join('.');
|
||||
const fileversion = release.version.slice(2);
|
||||
|
||||
release.files.forEach((asset) => {
|
||||
if (isOdd(asset.filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filename = asset.filename;
|
||||
const os = osMap[asset.os] || asset.os || '-';
|
||||
const arch = archMap[asset.arch] || asset.arch || '-';
|
||||
all.releases.push({
|
||||
version: version,
|
||||
_version: fileversion,
|
||||
lts: (parts[0] > 0 && release.stable) || false,
|
||||
channel: (release.stable && 'stable') || 'beta',
|
||||
date: '1970-01-01', // Placeholder
|
||||
os: os,
|
||||
arch: arch,
|
||||
ext: '', // Let normalize run the split/test/join
|
||||
hash: '-', // Placeholder for hash
|
||||
download: `https://dl.google.com/go/${filename}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return all;
|
||||
let response = await fetch('https://golang.org/dl/?mode=json&include=all', {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch Go releases: ${response.statusText}`);
|
||||
}
|
||||
|
||||
let goReleases = await response.json();
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
download: '',
|
||||
};
|
||||
|
||||
for (let release of goReleases) {
|
||||
// Strip 'go' prefix, standardize version
|
||||
let parts = release.version.slice(2).split('.');
|
||||
while (parts.length < 3) {
|
||||
parts.push('0');
|
||||
}
|
||||
let version = parts.join('.');
|
||||
let fileversion = release.version.slice(2);
|
||||
|
||||
for (let asset of release.files) {
|
||||
if (isOdd(asset.filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let filename = asset.filename;
|
||||
let os = osMap[asset.os] || asset.os || '-';
|
||||
let arch = archMap[asset.arch] || asset.arch || '-';
|
||||
let build = {
|
||||
version: version,
|
||||
_version: fileversion,
|
||||
lts: (parts[0] > 0 && release.stable) || false,
|
||||
channel: (release.stable && 'stable') || 'beta',
|
||||
date: '1970-01-01', // the world may never know
|
||||
os: os,
|
||||
arch: arch,
|
||||
ext: '', // let normalize run the split/test/join
|
||||
hash: '-', // not ready to standardize this yet
|
||||
download: `https://dl.google.com/go/${filename}`,
|
||||
};
|
||||
all.releases.push(build);
|
||||
}
|
||||
}
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
module.exports = getDistributables;
|
||||
|
||||
if (module === require.main) {
|
||||
getDistributables(require('@root/request')).then(function (all) {
|
||||
getDistributables().then(function (all) {
|
||||
all = require('../_webi/normalize.js')(all);
|
||||
//@ts-expect-error
|
||||
all.releases = all.releases.slice(0, 10);
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
});
|
||||
|
||||
105
gpg/releases.js
105
gpg/releases.js
@@ -16,84 +16,97 @@ function createUrlMatcher() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} [_version]
|
||||
* @prop {String} arch
|
||||
* @prop {String} channel
|
||||
* @prop {String} date
|
||||
* @prop {String} download
|
||||
* @prop {String} ext
|
||||
* @prop {String} [_filename]
|
||||
* @prop {String} hash
|
||||
* @prop {Boolean} lts
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
async function getRawReleases() {
|
||||
let matcher = createRssMatcher();
|
||||
|
||||
const response = await fetch('https://sourceforge.net/projects/gpgosx/rss?path=/', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/rss+xml', // Ensure the correct content type is requested
|
||||
},
|
||||
let resp = await fetch('https://sourceforge.net/projects/gpgosx/rss?path=/', {
|
||||
headers: { Accept: 'application/rss+xml' },
|
||||
});
|
||||
|
||||
// Validate the response status
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch RSS feed: HTTP ${response.status} - ${response.statusText}`);
|
||||
let text = await resp.text(); // Fetch RSS feed as plain text
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to fetch RSS feed: HTTP ${resp.status}: ${text}`);
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('Content-Type');
|
||||
let contentType = resp.headers.get('Content-Type');
|
||||
if (!contentType || !contentType.includes('xml')) {
|
||||
throw new Error(`Unexpected content type: ${contentType}`);
|
||||
}
|
||||
|
||||
const body = await response.text(); // Fetch RSS feed as plain text
|
||||
|
||||
let links = [];
|
||||
for (;;) {
|
||||
let m = matcher.exec(body);
|
||||
let m = matcher.exec(text);
|
||||
if (!m) {
|
||||
break;
|
||||
}
|
||||
links.push(m[1]);
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<String>} links
|
||||
*/
|
||||
function transformReleases(links) {
|
||||
//console.log(JSON.stringify(links, null, 2));
|
||||
//console.log(links.length);
|
||||
|
||||
let matcher = createUrlMatcher();
|
||||
|
||||
let releases = links
|
||||
.map(function (link) {
|
||||
let isLts = ltsRe.test(link);
|
||||
let parts = link.match(matcher);
|
||||
if (!parts || !parts[2]) {
|
||||
return null;
|
||||
}
|
||||
let segs = parts[2].split('.');
|
||||
let version = segs.slice(0, 3).join('.');
|
||||
if (segs.length > 3) {
|
||||
version += '+' + segs.slice(3);
|
||||
}
|
||||
let fileversion = segs.join('.');
|
||||
let builds = [];
|
||||
for (let link of links) {
|
||||
let isLts = ltsRe.test(link);
|
||||
let parts = link.match(matcher);
|
||||
if (!parts || !parts[2]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return {
|
||||
name: parts[1],
|
||||
version: version,
|
||||
_version: fileversion,
|
||||
// all go versions >= 1.0.0 are effectively LTS
|
||||
lts: isLts,
|
||||
channel: 'stable',
|
||||
// TODO <pubDate>Sat, 19 Nov 2016 16:17:33 UT</pubDate>
|
||||
date: '1970-01-01', // the world may never know
|
||||
os: 'macos',
|
||||
arch: 'amd64',
|
||||
ext: 'dmg',
|
||||
download: link,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
let segs = parts[2].split('.');
|
||||
let version = segs.slice(0, 3).join('.');
|
||||
if (segs.length > 3) {
|
||||
version += '+' + segs.slice(3);
|
||||
}
|
||||
let fileversion = segs.join('.');
|
||||
|
||||
let build = {
|
||||
name: parts[1],
|
||||
version: version,
|
||||
_version: fileversion,
|
||||
lts: isLts,
|
||||
channel: 'stable',
|
||||
// TODO <pubDate>Sat, 19 Nov 2016 16:17:33 UT</pubDate>
|
||||
date: '1970-01-01', // the world may never know
|
||||
os: 'macos',
|
||||
arch: 'amd64',
|
||||
ext: 'dmg',
|
||||
download: link,
|
||||
};
|
||||
builds.push(build);
|
||||
}
|
||||
|
||||
return {
|
||||
_names: ['GnuPG', 'gpgosx'],
|
||||
releases: releases,
|
||||
releases: builds,
|
||||
};
|
||||
}
|
||||
|
||||
async function getDistributables(request) {
|
||||
let releases = await getRawReleases(request);
|
||||
async function getDistributables() {
|
||||
let releases = await getRawReleases();
|
||||
let all = transformReleases(releases);
|
||||
return all;
|
||||
}
|
||||
@@ -101,7 +114,7 @@ async function getDistributables(request) {
|
||||
module.exports = getDistributables;
|
||||
|
||||
if (module === require.main) {
|
||||
getDistributables(require('@root/request')).then(function (all) {
|
||||
getDistributables().then(function (all) {
|
||||
all = require('../_webi/normalize.js')(all);
|
||||
all.releases = all.releases.slice(0, 10000);
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
|
||||
@@ -1,89 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
async function getRawReleases() {
|
||||
const response = await fetch('https://iterm2.com/downloads.html', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'text/html', // Explicitly request HTML content
|
||||
},
|
||||
let resp = await fetch('https://iterm2.com/downloads.html', {
|
||||
headers: { Accept: 'text/html' },
|
||||
});
|
||||
|
||||
// Validate HTTP response
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${response.status} - ${response.statusText}`);
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${resp.status}: ${text}`);
|
||||
}
|
||||
|
||||
// Validate Content-Type header
|
||||
const contentType = response.headers.get('Content-Type');
|
||||
let contentType = resp.headers.get('Content-Type');
|
||||
if (!contentType || !contentType.includes('text/html')) {
|
||||
throw new Error(`Unexpected Content-Type: ${contentType}`);
|
||||
}
|
||||
|
||||
// Parse HTML content
|
||||
const body = await response.text();
|
||||
var links = body
|
||||
.split(/[<>]+/g)
|
||||
.map(function (str) {
|
||||
var m = str.match(
|
||||
/href="(https:\/\/iterm2\.com\/downloads\/.*\.zip)"/,
|
||||
);
|
||||
let lines = text.split(/[<>]+/g);
|
||||
|
||||
/** @type {Array<String>} */
|
||||
let links = [];
|
||||
for (let str of lines) {
|
||||
var m = str.match(/href="(https:\/\/iterm2\.com\/downloads\/.*\.zip)"/);
|
||||
if (m && /iTerm2-[34]/.test(m[1])) {
|
||||
return m[1];
|
||||
if (m[1]) {
|
||||
links.push(m[1]);
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<String>} links
|
||||
*/
|
||||
function transformReleases(links) {
|
||||
//console.log(JSON.stringify(links, null, 2));
|
||||
//console.log(links.length);
|
||||
let builds = [];
|
||||
for (let link of links) {
|
||||
var channel = /\/stable\//.test(link) ? 'stable' : 'beta';
|
||||
|
||||
var parts = link.replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1').split('_');
|
||||
var version = parts.join('.').replace(/([_-])?beta/, '-beta');
|
||||
|
||||
// ex: 3.5.0-beta17 => 3_5_0beta17
|
||||
// ex: 3.0.2-preview => 3_0_2-preview
|
||||
let fileversion = version.replace(/\./g, '_');
|
||||
fileversion = fileversion.replace(/-beta/g, 'beta');
|
||||
|
||||
let build = {
|
||||
version: version,
|
||||
_version: fileversion,
|
||||
lts: 'stable' === channel,
|
||||
channel: channel,
|
||||
date: '1970-01-01', // the world may never know
|
||||
os: 'macos',
|
||||
arch: 'amd64',
|
||||
ext: '', // let normalize run the split/test/join
|
||||
download: link,
|
||||
};
|
||||
builds.push(build);
|
||||
}
|
||||
|
||||
return {
|
||||
_names: ['iTerm2', 'iterm2'],
|
||||
releases: links
|
||||
.map(function (link) {
|
||||
var channel = /\/stable\//.test(link) ? 'stable' : 'beta';
|
||||
|
||||
var parts = link
|
||||
.replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1')
|
||||
.split('_');
|
||||
var version = parts.join('.').replace(/([_-])?beta/, '-beta');
|
||||
|
||||
// ex: 3.5.0-beta17 => 3_5_0beta17
|
||||
// ex: 3.0.2-preview => 3_0_2-preview
|
||||
let fileversion = version.replace(/\./g, '_');
|
||||
fileversion = fileversion.replace(/-beta/g, 'beta');
|
||||
|
||||
return {
|
||||
version: version,
|
||||
_version: fileversion,
|
||||
// all go versions >= 1.0.0 are effectively LTS
|
||||
lts: 'stable' === channel,
|
||||
channel: channel,
|
||||
date: '1970-01-01', // the world may never know
|
||||
os: 'macos',
|
||||
arch: 'amd64',
|
||||
ext: '', // let normalize run the split/test/join
|
||||
download: link,
|
||||
};
|
||||
})
|
||||
.filter(Boolean),
|
||||
releases: builds,
|
||||
};
|
||||
}
|
||||
|
||||
function getDistributables(request) {
|
||||
return getRawReleases(request)
|
||||
.then(transformReleases)
|
||||
.then(function (all) {
|
||||
return all;
|
||||
});
|
||||
async function getDistributables() {
|
||||
let rawReleases = await getRawReleases();
|
||||
let all = transformReleases(rawReleases);
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
module.exports = getDistributables;
|
||||
|
||||
if (module === require.main) {
|
||||
getDistributables(require('@root/request')).then(function (all) {
|
||||
getDistributables().then(function (all) {
|
||||
all = require('../_webi/normalize.js')(all);
|
||||
all.releases = all.releases.slice(0, 10000);
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
|
||||
@@ -40,65 +40,90 @@ var headers = {
|
||||
'Accept-Language': 'en-US,en;q=0.9,sq;q=0.8',
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {typeof oses[0]} os
|
||||
*/
|
||||
async function fetchReleasesForOS(os) {
|
||||
// Fetch the webpage for the given OS
|
||||
const response = await fetch(os.url, {
|
||||
method: 'GET',
|
||||
let resp = await fetch(os.url, {
|
||||
headers: headers,
|
||||
});
|
||||
|
||||
// Validate HTTP response
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch URL: ${os.url}. HTTP ${response.status} - ${response.statusText}`);
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch URL: ${os.url}. HTTP ${resp.status}: ${text}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Parse the response body
|
||||
const body = await response.text();
|
||||
|
||||
// Extract the download link
|
||||
const match = body.match(/(http[^>]+Install[^>]+\.dmg)/);
|
||||
return match ? match[1] : null;
|
||||
let match = text.match(/(http[^>]+Install[^>]+\.dmg)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} [_version]
|
||||
* @prop {String} arch
|
||||
* @prop {String} channel
|
||||
* @prop {String} date
|
||||
* @prop {String} download
|
||||
* @prop {String} ext
|
||||
* @prop {String} [_filename]
|
||||
* @prop {String} hash
|
||||
* @prop {Boolean} lts
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
let osnames = ['macos', 'linux'];
|
||||
|
||||
async function getDistributables() {
|
||||
const all = {
|
||||
let all = {
|
||||
_names: ['InstallOS'],
|
||||
download: '',
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
};
|
||||
|
||||
// Fetch data for each OS and populate the releases array
|
||||
await Promise.all(
|
||||
oses.map(async (os) => {
|
||||
try {
|
||||
const download = await fetchReleasesForOS(os);
|
||||
for (let os of oses) {
|
||||
let download = await fetchReleasesForOS(os);
|
||||
if (!download) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add releases for macOS and Linux
|
||||
['macos', 'linux'].forEach((osname) => {
|
||||
all.releases.push({
|
||||
version: os.version,
|
||||
lts: os.lts || false,
|
||||
channel: os.channel || 'beta',
|
||||
date: os.date,
|
||||
os: osname,
|
||||
arch: 'amd64',
|
||||
ext: 'dmg',
|
||||
hash: '-', // Placeholder for hash
|
||||
download: download,
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Error fetching for ${os.name}: ${err.message}`);
|
||||
}
|
||||
}),
|
||||
);
|
||||
// Add releases for macOS and Linux
|
||||
for (let osname of osnames) {
|
||||
let build = {
|
||||
version: os.version,
|
||||
lts: os.lts || false,
|
||||
channel: os.channel || 'beta',
|
||||
date: os.date,
|
||||
os: osname,
|
||||
arch: 'amd64',
|
||||
ext: 'dmg',
|
||||
hash: '-',
|
||||
download: download,
|
||||
};
|
||||
|
||||
all.releases.push(build);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort releases
|
||||
all.releases.sort((a, b) => {
|
||||
all.releases.sort(function (a, b) {
|
||||
if (a.version === '10.11.6') {
|
||||
return -1;
|
||||
}
|
||||
return a.date > b.date ? 1 : -1;
|
||||
|
||||
if (a.date > b.date) {
|
||||
return 1;
|
||||
} else if (a.date < b.date) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return all;
|
||||
@@ -107,7 +132,7 @@ async function getDistributables() {
|
||||
module.exports = getDistributables;
|
||||
|
||||
if (module === require.main) {
|
||||
module.exports(require('@root/request')).then(function (all) {
|
||||
module.exports().then(function (all) {
|
||||
console.info(JSON.stringify(all, null, 2));
|
||||
});
|
||||
}
|
||||
|
||||
114
node/releases.js
114
node/releases.js
@@ -7,6 +7,7 @@
|
||||
const END_OF_LIFE = 366 * 24 * 60 * 60 * 1000;
|
||||
|
||||
// OSes
|
||||
/** @type {Object.<String, String>} */
|
||||
let osMap = {
|
||||
osx: 'macos', // NOTE: filename is 'darwin'
|
||||
linux: 'linux',
|
||||
@@ -16,6 +17,7 @@ let osMap = {
|
||||
};
|
||||
|
||||
// CPU architectures
|
||||
/** @type {Object.<String, String>} */
|
||||
let archMap = {
|
||||
x64: 'amd64',
|
||||
x86: 'x86',
|
||||
@@ -28,6 +30,7 @@ let archMap = {
|
||||
};
|
||||
|
||||
// file extensions
|
||||
/** @type {Object.<String, Array<String>>} */
|
||||
let pkgMap = {
|
||||
pkg: ['pkg'],
|
||||
//exe: ['exe'], // disable
|
||||
@@ -40,8 +43,25 @@ let pkgMap = {
|
||||
musl: ['tar.gz', 'tar.xz'],
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} [_version]
|
||||
* @prop {String} arch
|
||||
* @prop {String} channel
|
||||
* @prop {String} date
|
||||
* @prop {String} download
|
||||
* @prop {String} ext
|
||||
* @prop {String} [_filename]
|
||||
* @prop {String} [hash]
|
||||
* @prop {String} libc
|
||||
* @prop {Boolean} lts
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
async function getDistributables() {
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
download: '',
|
||||
};
|
||||
@@ -64,51 +84,52 @@ async function getDistributables() {
|
||||
]
|
||||
*/
|
||||
|
||||
// Alternate: 'https://nodejs.org/dist/index.json',
|
||||
let baseUrl = `https://nodejs.org/download/release`;
|
||||
{
|
||||
// Alternate: 'https://nodejs.org/dist/index.json',
|
||||
let baseUrl = `https://nodejs.org/download/release`;
|
||||
|
||||
// Fetch official builds
|
||||
let officialP = fetch(`${baseUrl}/index.json`, {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
}).then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch official builds: HTTP ${response.status} - ${response.statusText}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
transform(baseUrl, data);
|
||||
});
|
||||
|
||||
|
||||
// Fetch unofficial builds
|
||||
let unofficialBaseUrl = `https://unofficial-builds.nodejs.org/download/release`;
|
||||
let unofficialP = fetch(`${unofficialBaseUrl}/index.json`, {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch unofficial builds: HTTP ${response.status} - ${response.statusText}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
transform(unofficialBaseUrl, data);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('failed to fetch unofficial-builds');
|
||||
console.error(err);
|
||||
// Fetch official builds
|
||||
let resp = await fetch(`${baseUrl}/index.json`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch official builds: HTTP ${resp.status}: ${text}`,
|
||||
);
|
||||
}
|
||||
let data = JSON.parse(text);
|
||||
|
||||
void transform(baseUrl, data);
|
||||
}
|
||||
|
||||
{
|
||||
// Fetch unofficial builds
|
||||
let unofficialBaseUrl = `https://unofficial-builds.nodejs.org/download/release`;
|
||||
let resp = await fetch(`${unofficialBaseUrl}/index.json`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch official builds: HTTP ${resp.status}: ${text}`,
|
||||
);
|
||||
}
|
||||
let data = JSON.parse(text);
|
||||
transform(unofficialBaseUrl, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} baseUrl
|
||||
* @param {Array<any>} builds
|
||||
*/
|
||||
function transform(baseUrl, builds) {
|
||||
builds.forEach(function (build) {
|
||||
for (let build of builds) {
|
||||
let buildDate = new Date(build.date).valueOf();
|
||||
let age = Date.now() - buildDate;
|
||||
let maintained = age < END_OF_LIFE;
|
||||
if (!maintained) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
let lts = false !== build.lts;
|
||||
@@ -122,9 +143,9 @@ async function getDistributables() {
|
||||
channel = 'beta';
|
||||
}
|
||||
|
||||
build.files.forEach(function (file) {
|
||||
for (let file of build.files) {
|
||||
if ('src' === file || 'headers' === file) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
let fileParts = file.split('-');
|
||||
@@ -140,7 +161,7 @@ async function getDistributables() {
|
||||
pkgs = pkgMap.tar;
|
||||
}
|
||||
if (!pkgs?.length) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
let extra = '';
|
||||
@@ -157,7 +178,7 @@ async function getDistributables() {
|
||||
osPart = 'darwin';
|
||||
}
|
||||
|
||||
pkgs.forEach(function (pkg) {
|
||||
for (let pkg of pkgs) {
|
||||
let filename = `node-${build.version}-${osPart}-${archPart}${extra}.${pkg}`;
|
||||
if ('msi' === pkg) {
|
||||
filename = `node-${build.version}-${archPart}${extra}.${pkg}`;
|
||||
@@ -178,20 +199,17 @@ async function getDistributables() {
|
||||
};
|
||||
|
||||
all.releases.push(release);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await officialP;
|
||||
await unofficialP;
|
||||
|
||||
return all;
|
||||
}
|
||||
module.exports = getDistributables;
|
||||
|
||||
if (module === require.main) {
|
||||
getDistributables(require('@root/request')).then(function (all) {
|
||||
getDistributables().then(function (all) {
|
||||
all = require('../_webi/normalize.js')(all);
|
||||
console.info(JSON.stringify(all));
|
||||
//console.info(JSON.stringify(all, null, 2));
|
||||
|
||||
@@ -1,59 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} download
|
||||
*/
|
||||
|
||||
async function getDistributables() {
|
||||
try {
|
||||
// Fetch the Terraform releases JSON
|
||||
const response = await fetch('https://releases.hashicorp.com/terraform/index.json', {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
|
||||
// Validate the HTTP response
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${response.status} - ${response.statusText}`);
|
||||
}
|
||||
|
||||
// Parse the JSON response
|
||||
const releases = await response.json();
|
||||
|
||||
let all = {
|
||||
releases: [],
|
||||
download: '', // Full URI provided in response body
|
||||
};
|
||||
|
||||
function getBuildsForVersion(version) {
|
||||
releases.versions[version].builds.forEach(function (build) {
|
||||
let r = {
|
||||
version: build.version,
|
||||
download: build.url,
|
||||
// These are generic enough for the autodetect,
|
||||
// and the per-file logic has proven to get outdated sooner
|
||||
//os: convert[build.os],
|
||||
//arch: convert[build.arch],
|
||||
//channel: 'stable|-rc|-beta|-alpha',
|
||||
};
|
||||
all.releases.push(r);
|
||||
});
|
||||
}
|
||||
|
||||
// Releases are listed chronologically, we want the latest first.
|
||||
const allVersions = Object.keys(releases.versions).reverse();
|
||||
|
||||
allVersions.forEach(function (version) {
|
||||
getBuildsForVersion(version);
|
||||
});
|
||||
|
||||
return all;
|
||||
} catch (err) {
|
||||
console.error('Error fetching Terraform releases:', err.message);
|
||||
return { releases: [], download: '' };
|
||||
let resp = await fetch(
|
||||
'https://releases.hashicorp.com/terraform/index.json',
|
||||
{ headers: { Accept: 'application/json' } },
|
||||
);
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${resp.status}: ${text}`);
|
||||
}
|
||||
|
||||
let releases = JSON.parse(text);
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
download: '',
|
||||
};
|
||||
|
||||
let allVersions = Object.keys(releases.versions);
|
||||
allVersions.reverse(); // Releases are listed chronologically, we want the latest first.
|
||||
|
||||
for (let version of allVersions) {
|
||||
for (let build of releases.versions[version].builds) {
|
||||
let r = {
|
||||
version: build.version,
|
||||
download: build.url,
|
||||
// These are generic enough for the autodetect,
|
||||
// and the per-file logic has proven to get outdated sooner
|
||||
//os: convert[build.os],
|
||||
//arch: convert[build.arch],
|
||||
//channel: 'stable|-rc|-beta|-alpha',
|
||||
};
|
||||
all.releases.push(r);
|
||||
}
|
||||
}
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
module.exports = getDistributables;
|
||||
|
||||
if (module === require.main) {
|
||||
getDistributables(require('@root/request')).then(function (all) {
|
||||
getDistributables().then(function (all) {
|
||||
all = require('../_webi/normalize.js')(all);
|
||||
console.info(JSON.stringify(all));
|
||||
});
|
||||
|
||||
178
zig/releases.js
178
zig/releases.js
@@ -3,100 +3,104 @@
|
||||
var NON_BUILDS = ['bootstrap', 'src'];
|
||||
var ODDITIES = NON_BUILDS.concat(['armv6kz-linux']);
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
* @prop {String} [_version]
|
||||
* @prop {String} [arch]
|
||||
* @prop {String} channel
|
||||
* @prop {String} date
|
||||
* @prop {String} download
|
||||
* @prop {String} [ext]
|
||||
* @prop {String} [_filename]
|
||||
* @prop {String} [hash]
|
||||
* @prop {String} [libc]
|
||||
* @prop {Boolean} [lts]
|
||||
* @prop {String} [size]
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
module.exports = async function () {
|
||||
try {
|
||||
// Fetch the Zig language download index JSON
|
||||
const response = await fetch('https://ziglang.org/download/index.json', {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
let resp = await fetch('https://ziglang.org/download/index.json', {
|
||||
method: 'GET',
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${resp.status}: ${text}`);
|
||||
}
|
||||
let versions = JSON.parse(text);
|
||||
|
||||
// Validate HTTP response
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${response.status} - ${response.statusText}`);
|
||||
/** @type {Array<BuildInfo>} */
|
||||
let releases = [];
|
||||
let refs = Object.keys(versions);
|
||||
for (let ref of refs) {
|
||||
let pkgs = versions[ref];
|
||||
let version = pkgs.version || ref;
|
||||
|
||||
// "platform" = arch + os combo
|
||||
let platforms = Object.keys(pkgs);
|
||||
for (let platform of platforms) {
|
||||
let pkg = pkgs[platform];
|
||||
|
||||
// don't grab 'date' or 'notes', which are (confusingly)
|
||||
// at the same level as platform releases
|
||||
let isNotPackage = !pkg || 'object' !== typeof pkg || !pkg.tarball;
|
||||
if (isNotPackage) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let isOdd = ODDITIES.includes(platform);
|
||||
if (isOdd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ex: aarch64-macos => ['aarch64', 'macos']
|
||||
let parts = platform.split('-');
|
||||
//let arch = parts[0];
|
||||
let os = parts[1];
|
||||
if (parts.length > 2) {
|
||||
console.warn(`unexpected platform name with multiple '-': ${platform}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let p = {
|
||||
version: version,
|
||||
date: pkgs.date,
|
||||
channel: 'stable',
|
||||
// linux, macos, windows
|
||||
os: os,
|
||||
// TODO map explicitly (rather than normalization auto-detect)
|
||||
//arch: arch,
|
||||
download: pkg.tarball,
|
||||
hash: pkg.shasum,
|
||||
size: pkg.size,
|
||||
// TODO docs + release notes?
|
||||
//docs: 'https://ziglang.org/documentation/0.9.1/',
|
||||
//stdDocs: 'https://ziglang.org/documentation/0.9.1/std/',
|
||||
//notes: 'https://ziglang.org/download/0.9.1/release-notes.html'
|
||||
};
|
||||
|
||||
// Mark branches or tags as beta (for now)
|
||||
// Ex: 'master'
|
||||
// Also mark prereleases (with build tags) as beta
|
||||
// Ex: 0.10.0-dev.1606+97a53bb8a
|
||||
let isNotStable = !/\./.test(ref) || /\+|-/.test(p.version);
|
||||
if (isNotStable) {
|
||||
p.channel = 'beta';
|
||||
}
|
||||
|
||||
releases.push(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the JSON response
|
||||
const versions = await response.json();
|
||||
|
||||
let releases = [];
|
||||
|
||||
let refs = Object.keys(versions);
|
||||
refs.forEach(function (ref) {
|
||||
let pkgs = versions[ref];
|
||||
let version = pkgs.version || ref;
|
||||
|
||||
// "platform" = arch + os combo
|
||||
let platforms = Object.keys(pkgs);
|
||||
platforms.forEach(function (platform) {
|
||||
let pkg = pkgs[platform];
|
||||
|
||||
// don't grab 'date' or 'notes', which are (confusingly)
|
||||
// at the same level as platform releases
|
||||
let isNotPackage = !pkg || 'object' !== typeof pkg || !pkg.tarball;
|
||||
if (isNotPackage) {
|
||||
return;
|
||||
}
|
||||
|
||||
let isOdd = ODDITIES.includes(platform);
|
||||
if (isOdd) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ex: aarch64-macos => ['aarch64', 'macos']
|
||||
let parts = platform.split('-');
|
||||
//let arch = parts[0];
|
||||
let os = parts[1];
|
||||
if (parts.length > 2) {
|
||||
console.warn(
|
||||
`unexpected platform name with multiple '-': ${platform}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let p = {
|
||||
version: version,
|
||||
date: pkgs.date,
|
||||
channel: 'stable',
|
||||
// linux, macos, windows
|
||||
os: os,
|
||||
// TODO map explicitly (rather than normalization auto-detect)
|
||||
//arch: arch,
|
||||
download: pkg.tarball,
|
||||
hash: pkg.shasum,
|
||||
size: pkg.size,
|
||||
// TODO docs + release notes?
|
||||
//docs: 'https://ziglang.org/documentation/0.9.1/',
|
||||
//stdDocs: 'https://ziglang.org/documentation/0.9.1/std/',
|
||||
//notes: 'https://ziglang.org/download/0.9.1/release-notes.html'
|
||||
};
|
||||
|
||||
// Mark branches or tags as beta (for now)
|
||||
// Ex: 'master'
|
||||
// Also mark prereleases (with build tags) as beta
|
||||
// Ex: 0.10.0-dev.1606+97a53bb8a
|
||||
let isNotStable = !/\./.test(ref) || /\+|-/.test(p.version);
|
||||
if (isNotStable) {
|
||||
p.channel = 'beta';
|
||||
}
|
||||
|
||||
releases.push(p);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
releases: releases,
|
||||
};
|
||||
}catch (err) {
|
||||
console.error('Error fetching Zig releases:', err.message);
|
||||
return {
|
||||
releases: [],
|
||||
};
|
||||
return {
|
||||
releases: releases,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if (module === require.main) {
|
||||
module.exports(require('@root/request')).then(function (all) {
|
||||
module.exports().then(function (all) {
|
||||
all = require('../_webi/normalize.js')(all);
|
||||
// just select the first 5 for demonstration
|
||||
all.releases = all.releases.slice(0, 5);
|
||||
|
||||
Reference in New Issue
Block a user