mirror of
https://github.com/webinstall/webi-installers.git
synced 2026-02-14 09:39:51 +00:00
ref: handle fetch errors consistently (Fetcher.fetch)
This commit is contained in:
@@ -1,49 +1,56 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
/**
|
||||
* Gets releases from 'brew'.
|
||||
*
|
||||
* @param {null} _
|
||||
* @param {string} formula
|
||||
* @returns {PromiseLike<any> | Promise<any>}
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
function getDistributables(_, formula) {
|
||||
async function getDistributables(_, formula) {
|
||||
if (!formula) {
|
||||
return Promise.reject('missing formula for brew');
|
||||
}
|
||||
return fetch('https://formulae.brew.sh/api/formula/' + formula + '.json')
|
||||
.then(function (resp) {
|
||||
if (!resp.ok) {
|
||||
throw new Error(`HTTP error! Status: ${resp.status}`);
|
||||
}
|
||||
return resp.json(); // Parse JSON response
|
||||
})
|
||||
.then(function (body) {
|
||||
var ver = body.versions.stable;
|
||||
var dl = (
|
||||
body.bottle.stable.files.high_sierra ||
|
||||
body.bottle.stable.files.catalina
|
||||
).url.replace(new RegExp(ver.replace(/\./g, '\\.'), 'g'), '{{ v }}');
|
||||
return [
|
||||
{
|
||||
version: ver,
|
||||
download: dl.replace(/{{ v }}/g, ver),
|
||||
},
|
||||
].concat(
|
||||
body.versioned_formulae.map(function (f) {
|
||||
var ver = f.replace(/.*@/, '');
|
||||
return {
|
||||
version: ver,
|
||||
download: dl,
|
||||
};
|
||||
}),
|
||||
);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('Error fetching MariaDB versions (brew)');
|
||||
console.error(err);
|
||||
return [];
|
||||
|
||||
let resp;
|
||||
try {
|
||||
let url = `https://formulae.brew.sh/api/formula/${formula}.json`;
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch '${formula}' release data from 'brew': ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let body = JSON.parse(resp.body);
|
||||
|
||||
var ver = body.versions.stable;
|
||||
var dl = (
|
||||
body.bottle.stable.files.high_sierra || body.bottle.stable.files.catalina
|
||||
).url.replace(new RegExp(ver.replace(/\./g, '\\.'), 'g'), '{{ v }}');
|
||||
return [
|
||||
{
|
||||
version: ver,
|
||||
download: dl.replace(/{{ v }}/g, ver),
|
||||
},
|
||||
].concat(
|
||||
body.versioned_formulae.map(
|
||||
/** @param {String} f */
|
||||
function (f) {
|
||||
var ver = f.replace(/.*@/, '');
|
||||
return {
|
||||
version: ver,
|
||||
download: dl,
|
||||
};
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = getDistributables;
|
||||
|
||||
56
_common/fetcher.js
Normal file
56
_common/fetcher.js
Normal file
@@ -0,0 +1,56 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = module.exports;
|
||||
|
||||
/**
|
||||
* @typedef ResponseSummary
|
||||
* @prop {Boolean} ok
|
||||
* @prop {Headers} headers
|
||||
* @prop {Number} status
|
||||
* @prop {String} body
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {String} url
|
||||
* @param {RequestInit} opts
|
||||
* @returns {Promise<ResponseSummary>}
|
||||
*/
|
||||
Fetcher.fetch = async function (url, opts) {
|
||||
let resp = await fetch(url, opts);
|
||||
let summary = Fetcher.throwIfNotOk(resp);
|
||||
|
||||
return summary;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Response} resp
|
||||
* @returns {Promise<ResponseSummary>}
|
||||
*/
|
||||
Fetcher.throwIfNotOk = async function (resp) {
|
||||
let text = await resp.text();
|
||||
|
||||
if (!resp.ok) {
|
||||
let headers = Array.from(resp.headers);
|
||||
console.error('[Fetcher] error: Response Headers:', headers);
|
||||
console.error('[Fetcher] error: Response Text:', text);
|
||||
let err = new Error(`fetch was not ok`);
|
||||
Object.assign({
|
||||
status: 503,
|
||||
code: 'E_FETCH_RELEASES',
|
||||
response: {
|
||||
status: resp.status,
|
||||
headers: headers,
|
||||
body: text,
|
||||
},
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
|
||||
let summary = {
|
||||
ok: resp.ok,
|
||||
headers: resp.headers,
|
||||
status: resp.status,
|
||||
body: text,
|
||||
};
|
||||
return summary;
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
let GitHubishSource = module.exports;
|
||||
|
||||
/**
|
||||
@@ -44,30 +46,22 @@ GitHubishSource.getDistributables = async function ({
|
||||
});
|
||||
}
|
||||
|
||||
let resp = await fetch(url, opts);
|
||||
if (!resp.ok) {
|
||||
let headers = Array.from(resp.headers);
|
||||
console.error('Bad Resp Headers:', headers);
|
||||
let text = await resp.text();
|
||||
console.error('Bad Resp Body:', text);
|
||||
let msg = `failed to fetch releases from '${baseurl}' with user '${username}'`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
let respText = await resp.text();
|
||||
let gHubResp;
|
||||
let resp;
|
||||
try {
|
||||
gHubResp = JSON.parse(respText);
|
||||
resp = await Fetcher.fetch(url, opts);
|
||||
} catch (e) {
|
||||
console.error('Bad Resp JSON:', respText);
|
||||
console.error(e.message);
|
||||
let msg = `failed to parse releases from '${baseurl}' with user '${username}'`;
|
||||
throw new Error(msg);
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch '${baseurl}' (githubish-source, user '${username}) release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let gHubResp = JSON.parse(resp.body);
|
||||
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
// TODO make this ':baseurl' + ':releasename'
|
||||
download: '',
|
||||
};
|
||||
|
||||
@@ -84,6 +78,29 @@ GitHubishSource.getDistributables = async function ({
|
||||
return all;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} [name] - name to use instead of filename for hash urls
|
||||
* @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} [_musl]
|
||||
* @prop {Boolean} [lts]
|
||||
* @prop {String} [size]
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} ghRelease - TODO
|
||||
* @returns {Array<BuildInfo>}
|
||||
*/
|
||||
GitHubishSource.releaseToDistributables = function (ghRelease) {
|
||||
let ghTag = ghRelease['tag_name']; // TODO tags aren't always semver / sensical
|
||||
let lts = /(\b|_)(lts)(\b|_)/.test(ghRelease['tag_name']);
|
||||
@@ -95,6 +112,7 @@ GitHubishSource.releaseToDistributables = function (ghRelease) {
|
||||
date = date.replace(/T.*/, '');
|
||||
|
||||
let urls = [ghRelease.tarball_url, ghRelease.zipball_url];
|
||||
/** @type {Array<BuildInfo>} */
|
||||
let dists = [];
|
||||
for (let url of urls) {
|
||||
dists.push({
|
||||
@@ -114,6 +132,9 @@ GitHubishSource.releaseToDistributables = function (ghRelease) {
|
||||
return dists;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {BuildInfo} dist
|
||||
*/
|
||||
GitHubishSource.followDistributableDownloadAttachment = async function (dist) {
|
||||
let abortCtrl = new AbortController();
|
||||
let resp = await fetch(dist.download, {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
/**
|
||||
* @typedef DistributableRaw
|
||||
* @prop {String} name
|
||||
@@ -57,26 +59,18 @@ GitHubish.getDistributables = async function ({
|
||||
});
|
||||
}
|
||||
|
||||
let resp = await fetch(url, opts);
|
||||
if (!resp.ok) {
|
||||
let headers = Array.from(resp.headers);
|
||||
console.error('Bad Resp Headers:', headers);
|
||||
let text = await resp.text();
|
||||
console.error('Bad Resp Body:', text);
|
||||
let msg = `failed to fetch releases from '${baseurl}' with user '${username}'`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
let respText = await resp.text();
|
||||
let gHubResp;
|
||||
let resp;
|
||||
try {
|
||||
gHubResp = JSON.parse(respText);
|
||||
resp = await Fetcher.fetch(url, opts);
|
||||
} catch (e) {
|
||||
console.error('Bad Resp JSON:', respText);
|
||||
console.error(e.message);
|
||||
let msg = `failed to parse releases from '${baseurl}' with user '${username}'`;
|
||||
throw new Error(msg);
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch '${baseurl}' (githubish, user '${username}) release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let gHubResp = JSON.parse(resp.body);
|
||||
|
||||
let all = {
|
||||
/** @type {Array<DistributableRaw>} */
|
||||
@@ -88,13 +82,18 @@ GitHubish.getDistributables = async function ({
|
||||
try {
|
||||
gHubResp.forEach(transformReleases);
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
console.error(err.message);
|
||||
console.error('Error Headers:', resp.headers);
|
||||
console.error('Error Body:', resp.body);
|
||||
let msg = `failed to transform releases from '${baseurl}' with user '${username}'`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} release - TODO
|
||||
*/
|
||||
function transformReleases(release) {
|
||||
for (let asset of release['assets']) {
|
||||
let name = asset['name'];
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
// See <https://googlechromelabs.github.io/chrome-for-testing/>
|
||||
const releaseApiUrl =
|
||||
'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json';
|
||||
@@ -41,18 +43,23 @@ const releaseApiUrl =
|
||||
// }
|
||||
|
||||
module.exports = async function () {
|
||||
let resp = await fetch(releaseApiUrl);
|
||||
|
||||
if (!resp.ok) {
|
||||
let text = await resp.text();
|
||||
let msg = `failed to fetch releases from '${releaseApiUrl}': ${resp.status} ${text}`;
|
||||
throw new Error(msg);
|
||||
let resp;
|
||||
try {
|
||||
resp = await Fetcher.fetch(releaseApiUrl, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'chromedriver' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
let body = await resp.json();
|
||||
let data = JSON.parse(resp.body);
|
||||
|
||||
let builds = [];
|
||||
for (let release of body.versions) {
|
||||
for (let release of data.versions) {
|
||||
if (!release.downloads.chromedriver) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
var FLUTTER_OSES = ['macos', 'linux', 'windows'];
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
let FLUTTER_OSES = ['macos', 'linux', 'windows'];
|
||||
|
||||
/**
|
||||
* stable, beta, dev
|
||||
* @type {Object.<String, Boolean>}
|
||||
*/
|
||||
var channelMap = {};
|
||||
let channelMap = {};
|
||||
|
||||
// This can be spot-checked against
|
||||
// https://docs.flutter.dev/release/archive?tab=windows
|
||||
@@ -77,16 +79,22 @@ module.exports = async function () {
|
||||
};
|
||||
|
||||
for (let osname of FLUTTER_OSES) {
|
||||
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}`,
|
||||
);
|
||||
let resp;
|
||||
try {
|
||||
let url = `https://storage.googleapis.com/flutter_infra_release/releases/releases_${osname}.json`;
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'flutter' release data for ${osname}: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let data = await response.json();
|
||||
let data = JSON.parse(resp.body);
|
||||
|
||||
let osBaseUrl = data.base_url;
|
||||
let osReleases = data.releases;
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
/** @type {Object.<String, String>} */
|
||||
var osMap = {
|
||||
let osMap = {
|
||||
darwin: 'macos',
|
||||
};
|
||||
/** @type {Object.<String, String>} */
|
||||
var archMap = {
|
||||
let archMap = {
|
||||
386: 'x86',
|
||||
};
|
||||
|
||||
@@ -57,15 +59,23 @@ async function getDistributables() {
|
||||
]
|
||||
};
|
||||
*/
|
||||
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 resp;
|
||||
try {
|
||||
let url = 'https://golang.org/dl/?mode=json&include=all';
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'Go' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let goReleases = JSON.parse(resp.body);
|
||||
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
let ltsRe = /GnuPG-(2\.2\.[\d\.]+)/;
|
||||
|
||||
function createRssMatcher() {
|
||||
@@ -32,24 +34,29 @@ function createUrlMatcher() {
|
||||
*/
|
||||
|
||||
async function getRawReleases() {
|
||||
let matcher = createRssMatcher();
|
||||
|
||||
let resp = await fetch('https://sourceforge.net/projects/gpgosx/rss?path=/', {
|
||||
headers: { Accept: 'application/rss+xml' },
|
||||
});
|
||||
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}`);
|
||||
let resp;
|
||||
try {
|
||||
let url = 'https://sourceforge.net/projects/gpgosx/rss?path=/';
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/rss+xml' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'gpg' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
let contentType = resp.headers.get('Content-Type');
|
||||
if (!contentType || !contentType.includes('xml')) {
|
||||
if (!contentType?.includes('xml')) {
|
||||
throw new Error(`Unexpected content type: ${contentType}`);
|
||||
}
|
||||
|
||||
let matcher = createRssMatcher();
|
||||
let links = [];
|
||||
for (;;) {
|
||||
let m = matcher.exec(text);
|
||||
let m = matcher.exec(resp.body);
|
||||
if (!m) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
async function getRawReleases() {
|
||||
let resp = await fetch('https://iterm2.com/downloads.html', {
|
||||
headers: { Accept: 'text/html' },
|
||||
});
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to fetch releases: HTTP ${resp.status}: ${text}`);
|
||||
let resp;
|
||||
try {
|
||||
let url = 'https://iterm2.com/downloads.html';
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'text/html' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'iterm2' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
let contentType = resp.headers.get('Content-Type');
|
||||
@@ -14,12 +23,12 @@ async function getRawReleases() {
|
||||
throw new Error(`Unexpected Content-Type: ${contentType}`);
|
||||
}
|
||||
|
||||
let lines = text.split(/[<>]+/g);
|
||||
let lines = resp.body.split(/[<>]+/g);
|
||||
|
||||
/** @type {Array<String>} */
|
||||
let links = [];
|
||||
for (let str of lines) {
|
||||
var m = str.match(/href="(https:\/\/iterm2\.com\/downloads\/.*\.zip)"/);
|
||||
let m = str.match(/href="(https:\/\/iterm2\.com\/downloads\/.*\.zip)"/);
|
||||
if (m && /iTerm2-[34]/.test(m[1])) {
|
||||
if (m[1]) {
|
||||
links.push(m[1]);
|
||||
@@ -36,10 +45,10 @@ async function getRawReleases() {
|
||||
function transformReleases(links) {
|
||||
let builds = [];
|
||||
for (let link of links) {
|
||||
var channel = /\/stable\//.test(link) ? 'stable' : 'beta';
|
||||
let channel = /\/stable\//.test(link) ? 'stable' : 'beta';
|
||||
|
||||
var parts = link.replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1').split('_');
|
||||
var version = parts.join('.').replace(/([_-])?beta/, '-beta');
|
||||
let parts = link.replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1').split('_');
|
||||
let version = parts.join('.').replace(/([_-])?beta/, '-beta');
|
||||
|
||||
// ex: 3.5.0-beta17 => 3_5_0beta17
|
||||
// ex: 3.0.2-preview => 3_0_2-preview
|
||||
|
||||
@@ -1,31 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
var osMap = {
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
/** @type {Object.<String, String>} */
|
||||
let osMap = {
|
||||
winnt: 'windows',
|
||||
mac: 'darwin',
|
||||
};
|
||||
var archMap = {
|
||||
|
||||
/** @type {Object.<String, String>} */
|
||||
let archMap = {
|
||||
armv7l: 'armv7',
|
||||
i686: 'x86',
|
||||
powerpc64le: 'ppc64le',
|
||||
};
|
||||
|
||||
/**
|
||||
* @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} [_musl]
|
||||
* @prop {Boolean} [lts]
|
||||
* @prop {String} [size]
|
||||
* @prop {String} os
|
||||
*/
|
||||
|
||||
async function getDistributables() {
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
download: '',
|
||||
_names: ['julia', 'macaarch64'],
|
||||
};
|
||||
|
||||
let resp = await fetch(
|
||||
'https://julialang-s3.julialang.org/bin/versions.json',
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
},
|
||||
);
|
||||
let buildsByVersion = await resp.json();
|
||||
let resp;
|
||||
try {
|
||||
let url = 'https://julialang-s3.julialang.org/bin/versions.json';
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'julia' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let buildsByVersion = JSON.parse(resp.body);
|
||||
|
||||
/*
|
||||
{
|
||||
@@ -105,6 +135,12 @@ async function getDistributables() {
|
||||
return all;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} a
|
||||
* @param {String} a.version
|
||||
* @param {Object} b
|
||||
* @param {String} b.version
|
||||
*/
|
||||
function sortByVersion(a, b) {
|
||||
let [aVer, aPre] = a.version.split('-');
|
||||
let [bVer, bPre] = b.version.split('-');
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var oses = [
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
let oses = [
|
||||
{
|
||||
name: 'macOS Sierra',
|
||||
version: '10.12.6',
|
||||
@@ -25,7 +27,7 @@ var oses = [
|
||||
},
|
||||
];
|
||||
|
||||
var headers = {
|
||||
let headers = {
|
||||
Connection: 'keep-alive',
|
||||
'Cache-Control': 'max-age=0',
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
@@ -44,18 +46,22 @@ var headers = {
|
||||
* @param {typeof oses[0]} os
|
||||
*/
|
||||
async function fetchReleasesForOS(os) {
|
||||
let resp = await fetch(os.url, {
|
||||
headers: headers,
|
||||
});
|
||||
let text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch URL: ${os.url}. HTTP ${resp.status}: ${text}`,
|
||||
);
|
||||
let resp;
|
||||
try {
|
||||
resp = await Fetcher.fetch(os.url, {
|
||||
headers: headers,
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'macos' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Extract the download link
|
||||
let match = text.match(/(http[^>]+Install[^>]+\.dmg)/);
|
||||
let match = resp.body.match(/(http[^>]+Install[^>]+\.dmg)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
// https://blog.risingstack.com/update-nodejs-8-end-of-life-no-support/
|
||||
// 6 mos "current" + 18 mos LTS "active" + 12 mos LTS "maintenance"
|
||||
//var endOfLife = 3 * 366 * 24 * 60 * 60 * 1000;
|
||||
//let endOfLife = 3 * 366 * 24 * 60 * 60 * 1000;
|
||||
// If there have been no updates in 12 months, it's almost certainly end-of-life
|
||||
const END_OF_LIFE = 366 * 24 * 60 * 60 * 1000;
|
||||
|
||||
@@ -89,33 +91,43 @@ async function getDistributables() {
|
||||
let baseUrl = `https://nodejs.org/download/release`;
|
||||
|
||||
// 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 resp;
|
||||
try {
|
||||
resp = await Fetcher.fetch(`${baseUrl}/index.json`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'node' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let data = JSON.parse(text);
|
||||
let data = JSON.parse(resp.body);
|
||||
|
||||
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}`,
|
||||
);
|
||||
|
||||
// Fetch unofficial builds
|
||||
let resp;
|
||||
try {
|
||||
resp = await Fetcher.fetch(`${unofficialBaseUrl}/index.json`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'node' (unofficial) release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let data = JSON.parse(text);
|
||||
let data = JSON.parse(resp.body);
|
||||
|
||||
transform(unofficialBaseUrl, data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
* @prop {String} version
|
||||
@@ -7,16 +9,22 @@
|
||||
*/
|
||||
|
||||
async function getDistributables() {
|
||||
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 resp;
|
||||
try {
|
||||
let url = 'https://releases.hashicorp.com/terraform/index.json';
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'terraform' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let releases = JSON.parse(resp.body);
|
||||
|
||||
let releases = JSON.parse(text);
|
||||
let all = {
|
||||
/** @type {Array<BuildInfo>} */
|
||||
releases: [],
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
var NON_BUILDS = ['bootstrap', 'src'];
|
||||
var ODDITIES = NON_BUILDS.concat(['armv6kz-linux']);
|
||||
let Fetcher = require('../_common/fetcher.js');
|
||||
|
||||
let NON_BUILDS = ['bootstrap', 'src'];
|
||||
let ODDITIES = NON_BUILDS.concat(['armv6kz-linux']);
|
||||
|
||||
/**
|
||||
* @typedef BuildInfo
|
||||
@@ -21,15 +23,21 @@ var ODDITIES = NON_BUILDS.concat(['armv6kz-linux']);
|
||||
*/
|
||||
|
||||
module.exports = async function () {
|
||||
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 resp;
|
||||
try {
|
||||
let url = 'https://ziglang.org/download/index.json';
|
||||
resp = await Fetcher.fetch(url, {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
} catch (e) {
|
||||
/** @type {Error & { code: string, response: { status: number, body: string } }} */ //@ts-expect-error
|
||||
let err = e;
|
||||
if (err.code === 'E_FETCH_RELEASES') {
|
||||
err.message = `failed to fetch 'zig' release data: ${err.response.status} ${err.response.body}`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
let versions = JSON.parse(text);
|
||||
let versions = JSON.parse(resp.body);
|
||||
|
||||
/** @type {Array<BuildInfo>} */
|
||||
let releases = [];
|
||||
|
||||
Reference in New Issue
Block a user