ref: remove all releases.js files and _common/ fetchers

These files are no longer loaded at runtime. All release data now comes
from _cache/YYYY-MM/{pkg}.json files generated by the Go webicached daemon.

Deleted:
- 94 {pkg}/releases.js files (per-package upstream fetchers)
- 8 _common/*.js files (github.js, gitea.js, git-tag.js, fetcher.js, etc.)

Updated:
- _webi/classify-one.js: reads from cache instead of require(releases.js)
- Fixed hardcoded triplet key to use dynamic lookup
This commit is contained in:
AJ ONeal
2026-03-11 02:01:59 -06:00
parent 073d7458e2
commit 13ea83f963
104 changed files with 13 additions and 4703 deletions

3
QUESTIONS.md Normal file
View File

@@ -0,0 +1,3 @@
# Questions from ref-webi-go agent (resolver work)
(none yet)

View File

@@ -1,62 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
/**
* Gets releases from 'brew'.
*
* @param {null} _
* @param {string} formula
* @returns {Promise<any>}
*/
async function getDistributables(_, formula) {
if (!formula) {
return Promise.reject('missing formula for brew');
}
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;
if (module === require.main) {
getDistributables(null, 'mariadb').then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,56 +0,0 @@
'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;
};

View File

@@ -1,218 +0,0 @@
'use strict';
require('dotenv').config({ path: '.env' });
var Crypto = require('crypto');
var util = require('util');
var exec = util.promisify(require('child_process').exec);
var Fs = require('node:fs/promises');
var FsSync = require('node:fs');
var Path = require('node:path');
var repoBaseDir = process.env.REPO_BASE_DIR || '';
if (!repoBaseDir) {
repoBaseDir = Path.resolve('./_repos');
// for stderr
console.error(`[Warn] REPO_BASE_DIR= not set, ${repoBaseDir}`);
}
var Repos = {};
Repos.clone = async function (repoPath, gitUrl) {
let uuid = Crypto.randomUUID();
let tmpPath = `${repoPath}.${uuid}.tmp`;
let bakPath = `${repoPath}.${uuid}.dup`;
await exec(`git clone --bare --filter=tree:0 ${gitUrl} ${tmpPath}`);
try {
FsSync.accessSync(repoPath);
return;
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
// sync to avoid race conditions
try {
FsSync.renameSync(repoPath, bakPath);
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
FsSync.renameSync(tmpPath, repoPath);
await Fs.rm(bakPath, { force: true, recursive: true });
};
Repos.checkExists = async function (repoPath) {
let err = await Fs.access(repoPath).catch(Object);
if (!err) {
return true;
}
if (err.code !== 'ENOENT') {
throw err;
}
return false;
};
Repos.fetch = async function (repoPath) {
await exec(`git --git-dir=${repoPath} fetch`);
};
Repos.getTags = async function (repoPath) {
var { stdout } = await exec(`git --git-dir=${repoPath} tag`);
var rawTags = stdout.trim().split('\n');
let tags = [];
for (let tag of rawTags) {
// ex: v1, v2, v1.1, 1.1.0-rc
let maybeVersionRe = /^(v\d+|v?\d+\.\d+)/;
let maybeVersion = maybeVersionRe.test(tag);
if (maybeVersion) {
tags.push(tag);
}
}
tags = tags.reverse();
return tags;
};
Repos.getTipInfo = async function (repoPath) {
var { stdout } = await exec(
`git --git-dir=${repoPath} rev-parse --abbrev-ref HEAD`,
);
var branch = stdout.trim();
var info = await Repos.getCommitInfo(repoPath, 'HEAD');
info.commitish = branch;
return info;
};
Repos.getCommitInfo = async function (repoPath, commitish) {
var { stdout } = await exec(
`git --git-dir=${repoPath} log -1 --format="%h %H %ad %cd" --date=iso-strict ${commitish}`,
);
stdout = stdout.trim();
var commitParts = stdout.split(/\s+/g);
return {
commitish: commitish,
commit_id: `${commitParts[0]}`,
commit: `${commitParts[1]}`,
date: commitParts[2],
date_authored: commitParts[3],
};
};
/**
* Lists GitHub Releases (w/ uploaded assets)
*
* @param request
* @param {string} owner
* @param {string} gitUrl
* @returns {PromiseLike<any> | Promise<any>}
*/
async function getDistributables(gitUrl) {
let all = {
releases: [],
download: '',
};
let repoName = gitUrl.split('/').pop();
repoName = repoName.replace(/\.git$/, '');
let repoPath = `${repoBaseDir}/${repoName}.git`;
let isCloned = await Repos.checkExists(repoPath);
if (!isCloned) {
await Repos.clone(repoPath, gitUrl);
} else {
await Repos.fetch(repoPath);
}
let commitInfos = [];
let tags = await Repos.getTags(repoPath);
for (let tag of tags) {
let commitInfo = await Repos.getCommitInfo(repoPath, tag);
Object.assign(commitInfo, { version: tag, channel: '' });
commitInfos.push(commitInfo);
}
{
let tipInfo = await Repos.getTipInfo(repoPath);
// "2024-01-01T00:00:00-05:00" => "2024-01-01T05:00:00"
let date = new Date(tipInfo.date);
// "2024-01-01T05:00:00" => "v2024.01.01-05.00.00"
let version = date.toISOString();
// strip '.000Z'
version = version.replace(/\.\d+Z/, '');
version = version.replace(/[:\-]/g, '.');
version = version.replace(/T/, '-');
Object.assign(tipInfo, { version: `v${version}`, channel: '' });
if (commitInfos.length > 1) {
tipInfo.channel = 'beta';
}
commitInfos.push(tipInfo);
}
let releases = [];
for (let commitInfo of commitInfos) {
let version = commitInfo.version.replace(/^v/, '');
let date = new Date(commitInfo.date);
let isoDate = date.toISOString();
isoDate = isoDate.replace(/\.\d+Z/, '');
// tags and HEAD qualify for '--branch <branchish>'
let branch = commitInfo.commitish;
let rel = {
name: `${repoName}-v${version}`,
version: version,
git_tag: branch,
git_commit_hash: commitInfo.commit_id,
lts: false,
channel: commitInfo.channel,
date: isoDate,
os: '*',
arch: '*',
ext: 'git',
download: gitUrl,
};
releases.push(rel);
}
all.releases = releases;
return all;
}
module.exports = getDistributables;
if (module === require.main) {
(async function main() {
let testRepos = [
// just a few tags, and a different HEAD
'https://github.com/tpope/vim-commentary.git',
// no tags, just HEAD
'https://github.com/ziglang/zig.vim.git',
// many, many tags
//'https://github.com/dense-analysis/ale.git',
];
for (let url of testRepos) {
let all = await getDistributables(url);
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
}
})()
.then(function () {
process.exit(0);
})
.catch(function (err) {
console.error(err);
});
}

View File

@@ -1,47 +0,0 @@
'use strict';
var GitHubish = require('./githubish.js');
/**
* Lists Gitea Releases (w/ uploaded assets)
*
* @param {null} _ - deprecated
* @param {String} owner
* @param {String} repo
* @param {String} baseurl
* @param {String} [username]
* @param {String} [token]
*/
async function getDistributables(
_,
owner,
repo,
baseurl,
username = '',
token = '',
) {
baseurl = `${baseurl}/api/v1`;
let all = await GitHubish.getDistributables({
owner,
repo,
baseurl,
username,
token,
});
return all;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables(
null,
'root',
'pathman',
'https://git.rootprojects.org',
'',
'',
).then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,40 +0,0 @@
'use strict';
require('dotenv').config({ path: '.env' });
let GitHubSource = module.exports;
let GitHubishSource = require('./githubish-source.js');
/**
* @param {Object} opts
* @param {String} opts.owner
* @param {String} opts.repo
* @param {String} [opts.baseurl]
* @param {String} [opts.username]
* @param {String} [opts.token]
*/
GitHubSource.getDistributables = async function ({
owner,
repo,
baseurl = 'https://api.github.com',
username = process.env.GITHUB_USERNAME || '',
token = process.env.GITHUB_TOKEN || '',
}) {
let all = await GitHubishSource.getDistributables({
owner,
repo,
baseurl,
username,
token,
});
return all;
};
if (module === require.main) {
GitHubSource.getDistributables(null, 'BeyondCodeBootcamp', 'DuckDNS.sh').then(
function (all) {
console.info(JSON.stringify(all, null, 2));
},
);
}

View File

@@ -1,42 +0,0 @@
'use strict';
require('dotenv').config({ path: '.env' });
let GitHubish = require('./githubish.js');
/**
* Lists GitHub Releases (w/ uploaded assets)
*
* @param {null} _ - deprecated
* @param {String} owner
* @param {String} repo
* @param {String} [baseurl]
* @param {String} [username]
* @param {String} [token]
*/
module.exports = async function (
_,
owner,
repo,
baseurl = 'https://api.github.com',
username = process.env.GITHUB_USERNAME || '',
token = process.env.GITHUB_TOKEN || '',
) {
let all = await GitHubish.getDistributables({
owner,
repo,
baseurl,
username,
token,
});
return all;
};
let GitHub = module.exports;
GitHub.getDistributables = module.exports;
if (module === require.main) {
GitHub.getDistributables(null, 'BurntSushi', 'ripgrep').then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,174 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
let GitHubishSource = module.exports;
/**
* Lists GitHub-Like Releases (source tarball & zip)
*
* @param {Object} opts
* @param {String} opts.owner
* @param {String} opts.repo
* @param {String} opts.baseurl
* @param {String} [opts.username]
* @param {String} [opts.token]
*/
GitHubishSource.getDistributables = async function ({
owner,
repo,
baseurl,
username = '',
token = '',
}) {
if (!owner) {
throw new Error('missing owner for repo');
}
if (!repo) {
throw new Error('missing repo name');
}
if (!baseurl) {
throw new Error('missing baseurl');
}
let url = `${baseurl}/repos/${owner}/${repo}/releases`;
let opts = {
headers: {
'Content-Type': 'appplication/json',
},
};
if (token) {
let userpass = `${username}:${token}`;
let basicAuth = btoa(userpass);
Object.assign(opts.headers, {
Authorization: `Basic ${basicAuth}`,
});
}
let resp;
try {
resp = await Fetcher.fetch(url, opts);
} 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 '${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: [],
download: '',
};
for (let release of gHubResp) {
let dists = GitHubishSource.releaseToDistributables(release);
for (let dist of dists) {
let updates =
await GitHubishSource.followDistributableDownloadAttachment(dist);
Object.assign(dist, updates);
all.releases.push(dist);
}
}
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']);
let channel = 'stable';
if (ghRelease['prerelease']) {
channel = 'beta';
}
let date = ghRelease['published_at'] || '';
date = date.replace(/T.*/, '');
let urls = [ghRelease.tarball_url, ghRelease.zipball_url];
/** @type {Array<BuildInfo>} */
let dists = [];
for (let url of urls) {
dists.push({
name: '',
version: ghTag,
lts: lts,
channel: channel,
date: date,
os: '*',
arch: '*',
libc: '',
ext: '',
download: url,
});
}
return dists;
};
/**
* @param {BuildInfo} dist
*/
GitHubishSource.followDistributableDownloadAttachment = async function (dist) {
let abortCtrl = new AbortController();
let resp = await fetch(dist.download, {
method: 'HEAD',
redirect: 'follow',
signal: abortCtrl.signal,
});
let headers = Object.fromEntries(resp.headers);
// Workaround for bug where METHOD changes to GET
abortCtrl.abort();
await resp.text().catch(function (err) {
if (err.name !== 'AbortError') {
throw err;
}
});
// ex: content-disposition: attachment; filename=BeyondCodeBootcamp-DuckDNS.sh-v1.0.1-0-ga2f4bde.zip
// => BeyondCodeBootcamp-DuckDNS.sh-v1.0.1-0-ga2f4bde.zip
let name = headers['content-disposition'].replace(
/.*filename=([^;]+)(;|$)/,
'$1',
);
let download = resp.url;
return { name, download };
};
if (module === require.main) {
GitHubishSource.getDistributables({
owner: 'BeyondCodeBootcamp',
repo: 'DuckDNS.sh',
baseurl: 'https://api.github.com',
}).then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,137 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
/**
* @typedef DistributableRaw
* @prop {String} name
* @prop {String} version
* @prop {Boolean} lts
* @prop {String} [channel]
* @prop {String} date
* @prop {String} os
* @prop {String} arch
* @prop {String} ext
* @prop {String} download
*/
let GitHubish = module.exports;
/**
* Lists GitHub-Like Releases (w/ uploaded assets)
*
* @param {Object} opts
* @param {String} opts.owner
* @param {String} opts.repo
* @param {String} opts.baseurl
* @param {String} [opts.username]
* @param {String} [opts.token]
*/
GitHubish.getDistributables = async function ({
owner,
repo,
baseurl,
username = '',
token = '',
}) {
if (!owner) {
throw new Error('missing owner for repo');
}
if (!repo) {
throw new Error('missing repo name');
}
if (!baseurl) {
throw new Error('missing baseurl');
}
let url = `${baseurl}/repos/${owner}/${repo}/releases`;
let opts = {
headers: {
'Content-Type': 'appplication/json',
},
};
if (token) {
let userpass = `${username}:${token}`;
let basicAuth = btoa(userpass);
Object.assign(opts.headers, {
Authorization: `Basic ${basicAuth}`,
});
}
let resp;
try {
resp = await Fetcher.fetch(url, opts);
} 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 '${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>} */
releases: [],
// todo make this ':baseurl' + ':releasename'
download: '',
};
try {
gHubResp.forEach(transformReleases);
} catch (e) {
/** @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'];
let date = release['published_at']?.replace(/T.*/, '');
let download = asset['browser_download_url'];
// TODO tags aren't always semver / sensical
let version = release['tag_name'];
let channel;
if (release['prerelease']) {
// -rcX, -preview, -beta, etc will be checked in _webi/normalize.js
channel = 'beta';
}
let lts = /(\b|_)(lts)(\b|_)/.test(release['tag_name']);
all.releases.push({
name: name,
version: version,
lts: lts,
channel: channel,
date: date,
os: '', // will be guessed by download filename
arch: '', // will be guessed by download filename
ext: '', // will be normalized
download: download,
});
}
}
return all;
};
if (module === require.main) {
GitHubish.getDistributables({
owner: 'BurntSushi',
repo: 'ripgrep',
baseurl: 'https://api.github.com',
}).then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,37 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'BurntSushi';
var repo = 'ripgrep';
/******************************************************************************/
/** Note: Delete this Comment! **/
/** **/
/** Need a an example that filters out miscellaneous release files? **/
/** See `deno`, `gitea`, or `caddy` **/
/** **/
/******************************************************************************/
let Releases = module.exports;
Releases.latest = async function () {
let all = await github(null, owner, repo);
return all;
};
Releases.sample = async function () {
let normalize = require('../_webi/normalize.js');
let all = await Releases.latest();
all = normalize(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
return all;
};
if (module === require.main) {
(async function () {
let samples = await Releases.sample();
console.info(JSON.stringify(samples, null, 2));
})();
}

View File

@@ -1,8 +1,8 @@
'use strict';
let Fs = require('node:fs/promises');
let Path = require('node:path');
// let Builds = require('./builds.js');
let BuildsCacher = require('./builds-cacher.js');
let Triplet = require('./build-classifier/triplet.js');
@@ -36,16 +36,13 @@ async function main() {
arches: [],
libcs: [],
formats: [],
// TODO channels: [],
};
let installersDir = Path.join(__dirname, '..');
let Releases = require(`${installersDir}/${projName}/releases.js`);
if (!Releases.latest) {
Releases.latest = Releases;
}
let projInfo = await Releases.latest();
let cacheDir = Path.join(__dirname, '..', '_cache');
let yearMonth = new Date().toISOString().slice(0, 7);
let dataFile = `${cacheDir}/${yearMonth}/${projName}.json`;
let json = await Fs.readFile(dataFile, 'utf8');
let projInfo = JSON.parse(json);
// let packages = await Builds.getPackage({ name: projName });
// console.log(packages);
@@ -70,9 +67,11 @@ async function main() {
console.log(`[DEBUG] transformed`);
let sample = transformed.packages.slice(0, 20);
console.log('packages:', sample, ':packages');
let firstTriplet = Object.keys(transformed.releasesByTriplet)[0];
let firstVersion = transformed.versions[0];
console.log(
'releasesByTriplet:',
transformed.releasesByTriplet['linux-x86_64-none'][transformed.versions[0]],
`releasesByTriplet[${firstTriplet}][${firstVersion}]:`,
transformed.releasesByTriplet[firstTriplet]?.[firstVersion],
':releasesByTriplet',
);
console.log('versions:', transformed.versions, ':versions');

View File

@@ -1,22 +0,0 @@
'use strict';
let Releases = module.exports;
let GitHubSource = require('../_common/github-source.js');
let owner = 'BeyondCodeBootcamp';
let repo = 'aliasman';
Releases.latest = async function () {
let all = await GitHubSource.getDistributables({ owner, repo });
for (let pkg of all.releases) {
pkg.os = 'posix_2017';
}
return all;
};
if (module === require.main) {
Releases.latest().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,21 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'mholt';
var repo = 'archiver';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all._names = ['archiver', 'arc'];
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,79 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'wez';
var repo = 'atomicparsley';
let targets = {
x86win: {
os: 'windows',
arch: 'x86',
libc: 'msvc',
},
x64win: {
os: 'windows',
arch: 'amd64',
// https://github.com/wez/atomicparsley/issues/6#issuecomment-1364523028
libc: 'msvc',
},
x64mac: {
os: 'macos',
arch: 'amd64',
},
x64lin: {
os: 'linux',
arch: 'amd64',
libc: 'gnu',
},
x64musl: {
os: 'linux',
arch: 'amd64',
libc: 'musl',
},
};
module.exports = function () {
return github(null, owner, repo).then(function (all) {
for (let rel of all.releases) {
let windows32 = rel.name.includes('WindowsX86.');
if (windows32) {
Object.assign(rel, targets.x86win);
continue;
}
let windows64 = rel.name.includes('Windows.');
if (windows64) {
Object.assign(rel, targets.x64win);
continue;
}
let macos64 = rel.name.includes('MacOS');
if (macos64) {
Object.assign(rel, targets.x64mac);
continue;
}
let musl64 = rel.name.includes('Alpine');
if (musl64) {
Object.assign(rel, targets.x64musl);
continue;
}
let lin64 = rel.name.includes('Linux.');
if (lin64) {
Object.assign(rel, targets.x64lin);
continue;
}
}
all._names = ['AtomicParsley', 'atomicparsley'];
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
//console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,22 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'wallix';
var repo = 'awless';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
return !/(\.txt)|(\.deb)$/i.test(rel.name);
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'sharkdp';
var repo = 'bat';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
//console.info(JSON.stringify(all));
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,61 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'oven-sh';
var repo = 'bun';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// collect baseline asset names so we can prefer them over non-baseline
// (baseline builds avoid SIGILL on older/container CPUs)
let baselineNames = new Set();
all.releases.forEach(function (r) {
if (r.name.includes('-baseline')) {
baselineNames.add(r.name.replace('-baseline', ''));
}
});
all.releases = all.releases
.filter(function (r) {
if (r.name.includes('-profile')) {
return false;
}
if (r.name.endsWith('.txt') || r.name.endsWith('.asc')) {
return false;
}
// drop the non-baseline asset when a baseline twin exists
if (!r.name.includes('-baseline') && baselineNames.has(r.name)) {
return false;
}
let isMusl = r.name.includes('-musl');
if (isMusl) {
r._musl = true;
r.libc = 'musl';
} else if (r.name.includes('-linux-')) {
r.libc = 'gnu';
}
return true;
})
.map(function (r) {
// bun-linux-x64-baseline.zip => bun-linux-x64
r.name = r.name.replace('-baseline', '').replace(/\.zip$/, '');
// bun-v0.5.1 => v0.5.1
r.version = r.version.replace(/bun-/g, '');
return r;
});
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,27 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'caddyserver';
var repo = 'caddy';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
let isOneOffAsset = rel.download.includes('buildable-artifact');
if (isOneOffAsset) {
return false;
}
return true;
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,101 +0,0 @@
'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';
// {
// "timestamp": "2023-11-15T21:08:56.730Z",
// "versions": [
// {
// "version": "121.0.6120.0",
// "revision": "1222902",
// "downloads": {
// "chrome": [],
// "chromedriver": [
// {
// "platform": "linux64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/linux64/chromedriver-linux64.zip"
// },
// {
// "platform": "mac-arm64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/mac-arm64/chromedriver-mac-arm64.zip"
// },
// {
// "platform": "mac-x64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/mac-x64/chromedriver-mac-x64.zip"
// },
// {
// "platform": "win32",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/win32/chromedriver-win32.zip"
// },
// {
// "platform": "win64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/win64/chromedriver-win64.zip"
// }
// ],
// "chrome-headless-shell": []
// }
// }
// ]
// }
module.exports = async function () {
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 data = JSON.parse(resp.body);
let builds = [];
for (let release of data.versions) {
if (!release.downloads.chromedriver) {
continue;
}
let version = release.version;
for (let asset of release.downloads.chromedriver) {
let build = {
version: version,
download: asset.url,
// I' not sure that this is actually statically built but it
// seems to be and at worst we'll just get bug reports for Alpine
libc: 'none',
};
builds.push(build);
}
}
let all = {
download: '',
releases: builds,
};
return all;
};
if (module === require.main) {
module
.exports()
.then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the latest 20 for demonstration
all.releases = all.releases.slice(-20);
console.info(JSON.stringify(all, null, 2));
})
.catch(function (err) {
console.error('Error:', err);
});
}

View File

@@ -1,21 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'cilium';
var repo = 'cilium-cli';
module.exports = async function () {
let all = await github(null, owner, repo);
return all;
};
if (module === require.main) {
(async function () {
let normalize = require('../_webi/normalize.js');
let all = await module.exports();
all = normalize(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
})();
}

View File

@@ -1,53 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'Kitware';
var repo = 'CMake';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
for (let rel of all.releases) {
if (rel.version.startsWith('v')) {
rel._version = rel.version.slice(1);
}
{
let linuxRe = /(\b|_)(linux|gnu)(\b|_)/i;
let isLinux = linuxRe.test(rel.download) || linuxRe.test(rel.name);
if (isLinux) {
let muslRe = /(\b|_)(musl|alpine)(\b|_)/i;
let isMusl = muslRe.test(rel.download) || muslRe.test(rel.name);
if (isMusl) {
rel.libc = 'musl';
} else {
rel.libc = 'gnu';
}
continue;
}
}
{
let windowsRe = /(\b|_)(win\d*|windows\d*)(\b|_)/i;
let isWindows =
windowsRe.test(rel.download) || windowsRe.test(rel.name);
if (isWindows) {
rel.libc = 'msvc';
continue;
}
}
}
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,40 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'kivikakk';
var repo = 'comrak';
var ODDITIES = ['-musleabihf.1-'];
module.exports = function () {
return github(null, owner, repo).then(function (all) {
let builds = [];
loopBuilds: for (let build of all.releases) {
let isOddity;
for (let oddity of ODDITIES) {
isOddity = build.name.includes(oddity);
if (isOddity) {
break;
}
}
if (isOddity) {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
//console.info(JSON.stringify(all));
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,31 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'sstadick';
var repo = 'crabz';
module.exports = async function () {
let all = await github(null, owner, repo);
let releases = [];
for (let rel of all.releases) {
let isSrc = rel.download.includes('-src.');
if (isSrc) {
continue;
}
releases.push(rel);
}
all.releases = releases;
return all;
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,21 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'rs';
var repo = 'curlie';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all._names = ['curlie', 'curl-httpie'];
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
//console.info(JSON.stringify(all));
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,31 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'dashpay';
var repo = 'dash';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all.releases.forEach(function (rel) {
if (rel.name.includes('osx64')) {
rel.os = 'macos';
}
if (rel.version.startsWith('v')) {
rel._version = rel.version.slice(1);
}
});
all._names = ['dashd', 'dashcore'];
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,3 +0,0 @@
'use strict';
module.exports = require('../dashcore/releases.js');

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'dashhive';
var repo = 'dashmsg';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'dandavison';
var repo = 'delta';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the first 15 for demonstration
all.releases = all.releases.slice(0, 15);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,42 +0,0 @@
'use strict';
var path = require('path');
var github = require('../_common/github.js');
var owner = 'denoland';
var repo = 'deno';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases
.filter(function (rel) {
let isMeta = rel.name.endsWith('.d.ts');
if (isMeta) {
return false;
}
return true;
})
.map(function (rel) {
var ext;
if (!rel.name.match(rel.version)) {
ext = path.extname(rel.name);
rel.filename =
rel.name.slice(0, rel.name.length - ext.length) +
'-' +
rel.version +
ext;
}
return rel;
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'dotenv-linter';
var repo = 'dotenv-linter';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'therootcompany';
var repo = 'dotenv';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,22 +0,0 @@
'use strict';
let Releases = module.exports;
let GitHubSource = require('../_common/github-source.js');
let owner = 'BeyondCodeBootcamp';
let repo = 'DuckDNS.sh';
Releases.latest = async function () {
let all = await GitHubSource.getDistributables({ owner, repo });
for (let pkg of all.releases) {
pkg.os = 'posix_2017';
}
return all;
};
if (module === require.main) {
Releases.latest().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,31 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'sharkdp';
var repo = 'fd';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
if (build.name === 'fd') {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
//console.info(JSON.stringify(all));
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,45 +0,0 @@
'use strict';
var path = require('path');
var github = require('../_common/github.js');
var owner = 'eugeneware';
var repo = 'ffmpeg-static';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all.releases = all.releases
.filter(function (rel) {
let isFfmpeg = rel.name.includes('ffmpeg');
if (!isFfmpeg) {
return;
}
// remove README and LICENSE
return !['.README', '.LICENSE'].includes(path.extname(rel.name));
})
.map(function (rel) {
rel.version = rel.version.replace(/^b/, '');
if (/win32/.test(rel.name)) {
rel.os = 'windows';
rel.ext = 'exe';
}
if (/ia32/.test(rel.name)) {
rel.arch = '386';
} else if (/x64/.test(rel.name)) {
rel.arch = 'amd64';
}
return rel;
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'ffuf';
var repo = 'ffuf';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,39 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'fish-shell';
var repo = 'fish-shell';
var ODDITIES = ['bundledpcre'];
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all.releases = all.releases
.map(function (rel) {
for (let oddity of ODDITIES) {
let isOddity = rel.name.includes(oddity);
if (isOddity) {
return;
}
}
// We can extract the macos bins from the .app
if (/\.app\.zip$/.test(rel.name)) {
rel.os = 'macos';
rel.arch = 'amd64';
return rel;
}
})
.filter(Boolean);
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,132 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
let FLUTTER_OSES = ['macos', 'linux', 'windows'];
/**
* stable, beta, dev
* @type {Object.<String, Boolean>}
*/
let channelMap = {};
// This can be spot-checked against
// https://docs.flutter.dev/release/archive?tab=windows
// The release URLs are
// - https://storage.googleapis.com/flutter_infra_release/releases/releases_macos.json
// - https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json
// - https://storage.googleapis.com/flutter_infra_release/releases/releases_windows.json
// The old release URLs are
// - https://storage.googleapis.com/flutter_infra/releases/releases_macos.json
// - https://storage.googleapis.com/flutter_infra/releases/releases_linux.json
// - https://storage.googleapis.com/flutter_infra/releases/releases_windows.json
// The data looks like
// {
// "base_url": "https://storage.googleapis.com/flutter_infra/releases",
// "current_release": {
// "beta": "b22742018b3edf16c6cadd7b76d9db5e7f9064b5",
// "dev": "fa5883b78e566877613ad1ccb48dd92075cb5c23",
// "stable": "02c026b03cd31dd3f867e5faeb7e104cce174c5f"
// },
// "releases": [
// {
// "hash": "fa5883b78e566877613ad1ccb48dd92075cb5c23",
// "channel": "dev",
// "version": "2.3.0-16.0.pre",
// "release_date": "2021-05-27T23:58:47.683121Z",
// "archive": "dev/macos/flutter_macos_2.3.0-16.0.pre-dev.zip",
// "sha256": "f572b42d36714e6c58a3ed170b93bb414e2ced3ca4bde5094fbe18061cbcba6c"
// },
// {
// "hash": "02c026b03cd31dd3f867e5faeb7e104cce174c5f",
// "channel": "stable",
// "version": "2.2.1",
// "release_date": "2021-05-27T23:06:07.243882Z",
// "archive": "stable/macos/flutter_macos_2.2.1-stable.zip",
// "sha256": "6373d39ec563c337600baf42a42b258420208e4523d85479373e113d61d748df"
// },
// {
// "hash": "b22742018b3edf16c6cadd7b76d9db5e7f9064b5",
// "channel": "beta",
// "version": "2.2.0",
// "release_date": "2021-05-19T21:14:59.281482Z",
// "archive": "beta/macos/flutter_macos_2.2.0-beta.zip",
// "sha256": "31ab530e708f8d1274712211253a27a4ce7d676f139d30f2ec021df22382f052"
// }
// ]
// }
/**
* @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) {
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 = JSON.parse(resp.body);
let osBaseUrl = data.base_url;
let osReleases = data.releases;
for (let asset of osReleases) {
if (!channelMap[asset.channel]) {
channelMap[asset.channel] = true;
}
all.releases.push({
version: asset.version,
_version: `${asset.version}-${asset.channel}`,
lts: false,
channel: asset.channel,
date: asset.release_date.replace(/T.*/, ''),
download: `${osBaseUrl}/${asset.archive}`,
_filename: asset.archive,
});
}
}
all.channels = Object.keys(channelMap);
// note: versions have a waterfall relationship with channels:
// - a release that is in beta today may become stable tomorrow
// - semver prereleases are either beta or dev
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all.releases = all.releases.slice(25);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'junegunn';
var repo = 'fzf';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
//console.info(JSON.stringify(all));
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'cli';
var repo = 'cli';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,33 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'git-for-windows';
var repo = 'git';
module.exports = function () {
// TODO support mac and linux tarballs
return github(null, owner, repo).then(function (all) {
// See https://github.com/git-for-windows/git/wiki/MinGit
// also consider https://github.com/git-for-windows/git/wiki/Silent-or-Unattended-Installation
all.releases = all.releases
.filter(function (rel) {
rel.os = 'windows';
rel._version = rel.version.replace(/\.windows.1.*/, '');
rel._version = rel._version.replace(/\.windows(\.\d)/, '$1');
return (
/MinGit/i.test(rel.name || rel.download) &&
!/busybox/i.test(rel.name || rel.download)
);
})
.slice(0, 20);
all._names = ['MinGit', 'git'];
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'therootcompany';
var repo = 'gitdeploy';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,34 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'go-gitea';
var repo = 'gitea';
var ODDITIES = ['-gogit-', '-docs-'];
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
for (let oddity of ODDITIES) {
let isOddity = rel.name.includes(oddity);
if (isOddity) {
return false;
}
}
return true;
});
// "windows-4.0" as a nod to Windows NT ¯\_(ツ)_/¯
all._names = ['gitea', '-4.0-'];
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,130 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
/** @type {Object.<String, String>} */
let osMap = {
darwin: 'macos',
};
/** @type {Object.<String, String>} */
let archMap = {
386: 'x86',
};
let ODDITIES = ['bootstrap', '-arm6.'];
/**
* @param {String} filename
*/
function isOdd(filename) {
for (let oddity of ODDITIES) {
let isOddity = filename.includes(oddity);
if (isOddity) {
return true;
}
}
}
/**
* @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() {
/*
{
version: 'go1.13.8',
stable: true,
files: [
{
filename: 'go1.13.8.src.tar.gz',
os: '',
arch: '',
version: 'go1.13.8',
sha256:
'b13bf04633d4d8cf53226ebeaace8d4d2fd07ae6fa676d0844a688339debec34',
size: 21631178,
kind: 'source'
}
]
};
*/
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: [],
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().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));
});
}

View File

@@ -1,3 +0,0 @@
'use strict';
module.exports = require('../go/releases.js');

View File

@@ -1,21 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'goreleaser';
var repo = 'goreleaser';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all._names = ['goreleaser', '1'];
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,129 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
let ltsRe = /GnuPG-(2\.2\.[\d\.]+)/;
function createRssMatcher() {
return new RegExp(
'<link>(https://sourceforge\\.net/projects/gpgosx/files/GnuPG-([\\d\\.]+)\\.dmg/download)</link>',
'g',
);
}
function createUrlMatcher() {
return new RegExp(
'https://sourceforge\\.net/projects/gpgosx/files/(GnuPG-([\\d\\.]+)\\.dmg)/download',
'',
);
}
/**
* @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 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?.includes('xml')) {
throw new Error(`Unexpected content type: ${contentType}`);
}
let matcher = createRssMatcher();
let links = [];
for (;;) {
let m = matcher.exec(resp.body);
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 builds = [];
for (let link of links) {
let isLts = ltsRe.test(link);
let parts = link.match(matcher);
if (!parts || !parts[2]) {
continue;
}
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: builds,
};
}
async function getDistributables() {
let releases = await getRawReleases();
let all = transformReleases(releases);
return all;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10000);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'creedasaurus';
var repo = 'gprox';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'anchore';
var repo = 'grype';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'sharkdp';
var repo = 'hexyl';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
//console.info(JSON.stringify(all));
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,32 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'gohugoio';
var repo = 'hugo';
module.exports = async function () {
let all = await github(null, owner, repo);
all.releases = all.releases.filter(function (rel) {
let isExtended = rel.name.includes('_extended_');
if (!isExtended) {
return false;
}
let isOldAlias = rel.name.includes('Linux-64bit');
if (isOldAlias) {
return false;
}
return true;
});
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,32 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'gohugoio';
var repo = 'hugo';
module.exports = async function () {
let all = await github(null, owner, repo);
all.releases = all.releases.filter(function (rel) {
let isExtended = rel.name.includes('_extended_');
if (isExtended) {
return false;
}
let isOldAlias = rel.name.includes('Linux-64bit');
if (isOldAlias) {
return false;
}
return true;
});
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,93 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
async function getRawReleases() {
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');
if (!contentType || !contentType.includes('text/html')) {
throw new Error(`Unexpected Content-Type: ${contentType}`);
}
let lines = resp.body.split(/[<>]+/g);
/** @type {Array<String>} */
let links = [];
for (let str of lines) {
let m = str.match(/href="(https:\/\/iterm2\.com\/downloads\/.*\.zip)"/);
if (m && /iTerm2-[34]/.test(m[1])) {
if (m[1]) {
links.push(m[1]);
}
}
}
return links;
}
/**
* @param {Array<String>} links
*/
function transformReleases(links) {
let builds = [];
for (let link of links) {
let channel = /\/stable\//.test(link) ? 'stable' : '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
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: builds,
};
}
async function getDistributables() {
let rawReleases = await getRawReleases();
let all = transformReleases(rawReleases);
return all;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10000);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,43 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'stedolan';
var repo = 'jq';
let ODDITIES = ['-no-oniguruma'];
function isOdd(build) {
for (let oddity of ODDITIES) {
let isOddity = build.name.includes(oddity);
if (isOddity) {
return true;
}
}
}
module.exports = function () {
return github(null, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
let odd = isOdd(build);
if (odd) {
continue;
}
build.version = build.version.replace(/^jq\-/, '');
builds.push(build);
}
all.releases = builds;
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
//console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,181 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
/** @type {Object.<String, String>} */
let osMap = {
winnt: 'windows',
mac: 'darwin',
};
/** @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;
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);
/*
{
"url": "https://julialang-s3.julialang.org/bin/mac/aarch64/1.9/julia-1.9.4-macaarch64.tar.gz",
"triplet": "aarch64-apple-darwin14",
"kind": "archive",
"arch": "aarch64",
"asc": "-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCAAdFiEENnPfUp2QSUd/drN1ZuPH3APW5JUFAmVTQBcACgkQZuPH3APW\n5JWUqw//QF/CJLAxXZdcXqpBulLUs/AX+x/8aERGcKxZqfeYOwA5efOzma8sASa/\nUzYCLp9E31x/RMDoZah6vPRRjBR+uVI6CLlXCCCmbAJP3lD2vlcY9LKe2/7s3Ba8\nhwITRaL6R5zNr+YfSHW1Hoj2tWgAQh9Y+Te7bP3jzwp5dlFygFO0pzoN+aeJbPNA\nbgT0ry8tgh78/tgNjgt4Ev3E2t3ehhrDGK4tgkkKieO6sdFz8jOacZVZkR1kLVEg\nMBIqmqZfk+5/HMf/6gHwd5GOXW8+GakN7vYXO+9VFETA2EiD5Z5k4Edq/VrNCn4O\npC6WHpBmVBBYX4aQtHkJyQaV8PtFd1j9338jUWlDaa6BVtX2hjRtU1k1oLZB1TTX\nl4awzYgFqdCRnFmOtzTdMDBcfedOiIHdTyxXPjJCX3i0GXmeuk89e5dE4P6sTT9n\n24GeBVQgMaXuNorg9L0oKrsQ8RDT20yEnVbfhy4Cvoq7dNIks6IxLZt10tjJFp1j\n0oJ5f6KucGyqFM9UhXRcuLj8Z+Q+JDzBs5c2pPe/bEzv6nChRNv252e5dve17esg\nK7tHkhXzM+6wl60oyRtpWghOubXyBDsNu1MH3qC9lWy3wmWuMN7no+yX0vGFyhMT\naxjLJSeYdccKD3SuzYotp3XwBKk05PFX9lWy0vuIjVj1sGWcES8=\n=G1tO\n-----END PGP SIGNATURE-----\n",
"sha256": "67542975e86102eec95bc4bb7c30c5d8c7ea9f9a0b388f0e10f546945363b01a",
"size": 119559478,
"version": "1.9.4",
"os": "mac",
"extension": "tar.gz"
}
*/
let versions = Object.keys(buildsByVersion);
for (let version of versions) {
let release = buildsByVersion[version];
// let odd = isOdd(asset.filename);
// if (odd) {
// return;
// }
for (let build of release.files) {
// // For debugging
// let paths = build.url.split('/');
// let extlen = build.extension.length + 1;
// let name = paths.at(-1);
// name = name.replace(`-${build.version}`, '');
// name = name.slice('julia-'.length);
// name = name.slice(0, -extlen);
// console.log(`name: ${name}`);
// console.log(`triplet: ${build.triplet}`);
// console.log(`arch: ${build.arch}`);
// console.log(`os: ${build.os}`);
// console.log(`kind: ${build.kind}`);
// console.log(`extension: ${build.extension}`);
// console.log(`version: ${build.version}`);
if (build.kind === 'installer') {
continue;
}
let arch = archMap[build.arch] || build.arch || '-';
let os = osMap[build.os] || build.os || '-';
let libc = '';
let hardMusl = /\b(musl)\b/.test(build.url);
if (hardMusl) {
libc = 'musl';
} else if (os === 'linux') {
libc = 'gnu';
}
let webiBuild = {
version: build.version,
_version: build.version,
lts: false,
channel: '', // autodetect by filename (-beta1, -alpha1, -rc1)
date: '1970-01-01', // the world may never know
os: os,
arch: arch,
libc: libc,
_musl: hardMusl,
ext: '', // let normalize run the split/test/join
hash: '-', // build.sha256 not ready to standardize this yet
download: build.url,
};
all.releases.push(webiBuild);
}
}
all.releases.sort(sortByVersion);
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('-');
let aVers = aVer.split('.');
let bVers = bVer.split('.');
for (let i = 0; i < 3; i += 1) {
aVers[i] = aVers[i].padStart(4, '0');
bVers[i] = bVers[i].padStart(4, '0');
}
aVer = aVers.join('.');
if (aPre) {
aVer += `-${aPre}`;
}
bVer = bVers.join('.');
if (bPre) {
bVer += `-${aPre}`;
}
if (aVer > bVer) {
return -1;
}
if (aVer < bVer) {
return 1;
}
return 0;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'derailed';
var repo = 'k9s';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'therootcompany';
var repo = 'keypairs';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,28 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'kubernetes-sigs';
var repo = 'kind';
/******************************************************************************/
/** Note: Delete this Comment! **/
/** **/
/** Need a an example that filters out miscellaneous release files? **/
/** See `deno`, `gitea`, or `caddy` **/
/** **/
/******************************************************************************/
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'cococonscious';
var repo = 'koji';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,37 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'ahmetb';
var repo = 'kubectx';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
// this installs separately
if (build.name.includes('kubens')) {
continue;
}
// this is the legacy bash script
if (build.name === 'kubectx') {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,37 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'ahmetb';
var repo = 'kubectx';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
// this installs separately
if (build.name.includes('kubectx')) {
continue;
}
// this is the legacy bash script
if (build.name === 'kubens') {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,25 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'gokcehan';
var repo = 'lf';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all.releases = all.releases.map(function (r) {
// r21 -> 0.21.0
if (/^r/.test(r.version)) {
r.version = '0.' + r.version.replace('r', '') + '.0';
}
return r;
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')._debug(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,23 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'lsd-rs';
var repo = 'lsd';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all.releases = all.releases.filter(function (rel) {
return !/(-msvc\.)|(\.deb$)/.test(rel.name);
});
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,144 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
let oses = [
{
name: 'macOS Sierra',
version: '10.12.6',
date: '2018-09-26',
channel: 'beta',
url: 'https://support.apple.com/en-us/HT208202',
},
{
name: 'OS X El Capitan',
version: '10.11.6',
date: '2018-07-09',
lts: true,
channel: 'stable',
url: 'https://support.apple.com/en-us/HT206886',
},
{
name: 'OS X Yosemite',
version: '10.10.5',
date: '2017-07-19',
channel: 'beta',
url: 'https://support.apple.com/en-us/HT210717',
},
];
let headers = {
Connection: 'keep-alive',
'Cache-Control': 'max-age=0',
'Upgrade-Insecure-Requests': '1',
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
'Sec-Fetch-Dest': 'document',
Accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Accept-Language': 'en-US,en;q=0.9,sq;q=0.8',
};
/**
* @param {typeof oses[0]} os
*/
async function fetchReleasesForOS(os) {
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 = resp.body.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() {
let all = {
_names: ['InstallOS'],
download: '',
/** @type {Array<BuildInfo>} */
releases: [],
};
// Fetch data for each OS and populate the releases array
for (let os of oses) {
let download = await fetchReleasesForOS(os);
if (!download) {
continue;
}
// 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(function (a, b) {
if (a.version === '10.11.6') {
return -1;
}
if (a.date > b.date) {
return 1;
} else if (a.date < b.date) {
return -1;
}
return 0;
});
return all;
}
module.exports = getDistributables;
if (module === require.main) {
module.exports().then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,181 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
let Releases = module.exports;
let PRODUCT = `mariadb`;
// `https://downloads.mariadb.org/rest-api/${PRODUCT}/${minor}/`
// `https://downloads.mariadb.org/rest-api/mariadb/10.5/`
// https://github.com/MariaDB/mariadb-documentation/issues/41
Releases.latest = async function () {
let packages = [];
let versionData = await getVersionIds();
for (let verData of versionData.major_releases) {
let isVersion = /^\d+[.]\d+$/.test(verData.release_id);
if (!isVersion) {
continue;
}
let releaseData = await getReleases(verData.release_id);
let versions = Object.keys(releaseData.releases);
for (let ver of versions) {
let relData = releaseData.releases[ver];
for (let fileData of relData.files) {
let packageData = pluckData(verData, relData, fileData);
if (!packageData) {
continue;
}
packages.push(packageData);
}
}
}
let all = { releases: packages };
return all;
};
/** @type {Object.<String?, String>} */
let channelsMap = {
// 'Long Term Support': 'stable',
// 'Short Term Support': 'stable',
// 'Rolling': null,
Stable: 'stable',
RC: 'rc',
Alpha: 'preview',
null: 'preview',
};
/** @type {Object.<String, String>} */
let cpusMap = {
x86_64: 'amd64',
};
/**
* @param {MajorRelease} verData
* @param {Release} relData
* @param {File} fileData
*/
function pluckData(verData, relData, fileData) {
let lts =
verData.release_status === 'Stable' &&
verData.release_support_type === 'Long Term Support';
let cpu = fileData.cpu || '';
cpu = cpu.trim();
let isNotBinary = !fileData.os || !cpu; // "Source" or some such
if (isNotBinary) {
return null;
}
let isDebug = /debug/.test(fileData.file_name);
if (isDebug) {
return null;
}
let pkgData = {
name: fileData.file_name,
version: relData.release_id,
lts: lts,
channel: channelsMap[verData.release_status],
date: relData.date_of_release,
os: fileData.os?.toLowerCase(),
arch: cpusMap[cpu] || cpu,
hash: fileData.checksum.sha256sum,
download: fileData.file_download_url,
};
return pkgData;
}
/**
* @typedef {String} ISODate - YYYY-MM-DD (ISO 8601 format)
*/
/**
* @typedef MajorRelease
* @prop {String} release_id - version-like for stable versions, otherwise a title
* @prop {String} release_name - same as id for MariaDB
* @prop {String} release_status - Stable|RC|Alpha
* @prop {String?} release_support_type - Long Term Support|Short Term Support|Rolling|null
* @prop {ISODate?} release_eol_date
*/
/**
* @typedef MajorReleasesWrapper
* @prop {Array<MajorRelease>} major_releases
*/
/**
* @typedef Release
* @prop {String} release_id - "11.4.4" or "11.6.0 Vector"
* @prop {String} release_name - "MariaDB Server 11.8.0 Preview"
* @prop {ISODate} date_of_release
* @prop {String} release_notes_url
* @prop {String} change_log
* @prop {Array<File>} files - release assets (packages, docs, etc)
*/
/**
* @typedef ReleasesWrapper
* @prop {Object.<String, Release>} releases
*/
/**
* @typedef File
* @prop {Number} file_id
* @prop {String} file_name
* @prop {String?} package_type - "gzipped tar file" or "ZIP file"
* @prop {String?} os - "Linux" or "Windows"
* @prop {String?} cpu - "x86_64" (or null)
* @prop {Checksum} checksum
* @prop {String} file_download_url
* @prop {String?} signature
* @prop {String} checksum_url
* @prop {String} signature_url
*/
/**
* @typedef Checksum
* @prop {String?} md5sum
* @prop {String?} sha1sum
* @prop {String?} sha256sum
* @prop {String?} sha512sum
*/
/**
* @returns {Promise<MajorReleasesWrapper>}
*/
async function getVersionIds() {
let url = `https://downloads.mariadb.org/rest-api/${PRODUCT}/`;
let resp = await Fetcher.fetch(url, {
headers: { Accept: 'application/json' },
});
let result = JSON.parse(resp.body);
return result;
}
/**
* @param {String} verId
* @returns {Promise<ReleasesWrapper>}
*/
async function getReleases(verId) {
let url = `https://downloads.mariadb.org/rest-api/${PRODUCT}/${verId}`;
let resp = await Fetcher.fetch(url, {
headers: { Accept: 'application/json' },
});
let result = JSON.parse(resp.body);
return result;
}
if (module === require.main) {
Releases.latest().then(function (all) {
let normalize = require('../_webi/normalize.js');
all = normalize(all);
let json = JSON.stringify(all, null, 2);
console.info(json);
});
}

View File

@@ -1,37 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'therootcompany';
var repo = 'golib';
let Releases = module.exports;
Releases.latest = async function () {
let all = await github(null, owner, repo);
// This is a monorepo — keep only monorel releases and strip the
// path prefix from the version so normalize.js sees plain semver.
all.releases = all.releases.filter(function (rel) {
return rel.version.startsWith('tools/monorel/');
});
all.releases.forEach(function (rel) {
rel.version = rel.version.replace(/^tools\/monorel\//, '');
});
return all;
};
Releases.sample = async function () {
let normalize = require('../_webi/normalize.js');
let all = await Releases.latest();
all = normalize(all);
all.releases = all.releases.slice(0, 5);
return all;
};
if (module === require.main) {
(async function () {
let samples = await Releases.sample();
console.info(JSON.stringify(samples, null, 2));
})();
}

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'mutagen-io';
var repo = 'mutagen';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')._debug(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,229 +0,0 @@
'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"
//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;
// OSes
/** @type {Object.<String, String>} */
let osMap = {
osx: 'macos', // NOTE: filename is 'darwin'
linux: 'linux',
win: 'windows', // windows
sunos: 'sunos',
aix: 'aix',
};
// CPU architectures
/** @type {Object.<String, String>} */
let archMap = {
x64: 'amd64',
x86: 'x86',
ppc64: 'ppc64',
ppc64le: 'ppc64le',
arm64: 'arm64',
armv7l: 'armv7l',
armv6l: 'armv6l',
s390x: 's390x',
};
// file extensions
/** @type {Object.<String, Array<String>>} */
let pkgMap = {
pkg: ['pkg'],
//exe: ['exe'], // disable
'7z': ['7z'],
zip: ['zip'],
tar: ['tar.gz', 'tar.xz'],
// oddity - no os in download
msi: ['msi'],
// oddity - no pkg info
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: '',
};
/*
[
{
"version":"v20.3.1",
"date":"2023-06-20",
"files":["headers","linux-armv6l","linux-x64-musl","linux-x64-pointer-compression"],
"npm":"9.6.7",
"v8":"11.3.244.8",
"uv":"1.45.0",
"zlib":"1.2.13.1-motley",
"openssl":"3.0.9+quic",
"modules":"115",
"lts":false,
"security":true
},
]
*/
{
// Alternate: 'https://nodejs.org/dist/index.json',
let baseUrl = `https://nodejs.org/download/release`;
// Fetch official builds
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(resp.body);
void transform(baseUrl, data);
}
{
let unofficialBaseUrl = `https://unofficial-builds.nodejs.org/download/release`;
// 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(resp.body);
transform(unofficialBaseUrl, data);
}
/**
* @param {String} baseUrl
* @param {Array<any>} builds
*/
function transform(baseUrl, builds) {
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) {
continue;
}
let lts = false !== build.lts;
// skip 'v'
let vparts = build.version.slice(1).split('.');
let major = parseInt(vparts[0], 10);
let channel = 'stable';
let isEven = 0 === major % 2;
if (!isEven) {
channel = 'beta';
}
for (let file of build.files) {
if ('src' === file || 'headers' === file) {
continue;
}
let fileParts = file.split('-');
let osPart = fileParts[0];
let os = osMap[osPart];
let archPart = fileParts[1];
let arch = archMap[archPart];
let libc = '';
let pkgPart = fileParts[2];
let pkgs = pkgMap[pkgPart];
if (!pkgPart) {
pkgs = pkgMap.tar;
}
if (!pkgs?.length) {
continue;
}
let extra = '';
let muslNative;
if (fileParts[2] === 'musl') {
extra = '-musl';
muslNative = true;
libc = 'musl';
} else if (os === 'linux') {
libc = 'gnu';
}
if (osPart === 'osx') {
osPart = 'darwin';
}
for (let pkg of pkgs) {
let filename = `node-${build.version}-${osPart}-${archPart}${extra}.${pkg}`;
if ('msi' === pkg) {
filename = `node-${build.version}-${archPart}${extra}.${pkg}`;
}
let downloadUrl = `${baseUrl}/${build.version}/${filename}`;
let release = {
name: filename,
version: build.version,
lts: lts,
channel: channel,
date: build.date,
os: os,
arch: arch,
ext: pkg,
download: downloadUrl,
libc: libc,
};
all.releases.push(release);
}
}
}
}
return all;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
//console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,59 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'jmorganca';
var repo = 'ollama';
module.exports = async function () {
let all = await github(null, owner, repo);
let releases = [];
for (let rel of all.releases) {
// this is a janky, sudo-wantin' .app
let isJank = rel.name.startsWith('Ollama-darwin');
if (isJank) {
continue;
}
let isUniversal = rel.name === 'ollama-darwin';
if (isUniversal) {
let x64 = Object.assign({ arch: 'x86_64' }, rel);
releases.push(x64);
rel.arch = 'aarch64';
}
let isROCm = rel.name.includes('-rocm');
if (isROCm) {
Object.assign(rel, { arch: 'x86_64_rocm' });
}
let oddballs = {
tgz: 'tar.gz',
tbz2: 'tar.bz2',
txz: 'tar.xz',
};
let oddExts = Object.keys(oddballs);
for (let oddExt of oddExts) {
let isOddball = rel.name.endsWith(`.${oddExt}`);
if (isOddball) {
let ext = oddballs[oddExt];
rel.name = rel.name.replace(`.${oddExt}`, `.${ext}`);
rel.ext = ext;
}
}
releases.push(rel);
}
all.releases = releases;
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
//console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'emdneto';
var repo = 'otsgo';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'jgm';
var repo = 'pandoc';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,28 +0,0 @@
'use strict';
var github = require('../_common/gitea.js');
var owner = 'root';
var repo = 'pathman';
var baseurl = 'https://git.rootprojects.org';
module.exports = function () {
return github(null, owner, repo, baseurl).then(function (all) {
all.releases = all.releases.filter(function (release) {
release._filename = release.name;
let isOldAlias = release.name.includes('armv8');
if (isOldAlias) {
return false;
}
return true;
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,50 +0,0 @@
'use strict';
let Releases = module.exports;
var Github = require('../_common/github.js');
var owner = 'bnnanet';
var repo = 'postgresql-releases';
Releases.latest = async function () {
let all = await Github.getDistributables(null, owner, repo);
/** @type {Array<Awaited<ReturnType<typeof Github.getDistributables>>>[Number]["releases"]} */
let distributables = [];
for (let dist of all.releases) {
let isBaseline = dist.name.includes('baseline');
if (isBaseline) {
continue;
}
let isServer = dist.name.includes('postgres');
if (!isServer) {
continue;
}
// REL_17_0 => 17.0
dist.version = dist.version.replace(/REL_/g, '');
dist.version = dist.version.replace(/_/g, '.');
let isHardMusl = dist.name.includes('musl');
if (isHardMusl) {
Object.assign(dist, { libc: 'musl', _musl: true });
}
distributables.push(dist);
}
all.releases = distributables;
Object.assign(all, { _names: ['postgres', 'postgresql', 'pgsql', 'psql'] });
return all;
};
if (module === require.main) {
Releases.latest().then(function (all) {
let normalize = require('../_webi/normalize.js');
all = normalize(all);
let json = JSON.stringify(all, null, 2);
console.info(json);
});
}

View File

@@ -1,129 +0,0 @@
'use strict';
let Releases = module.exports;
var Github = require('../_common/github.js');
var owner = 'bnnanet';
var repo = 'postgresql-releases';
let originalReleases = {
_names: ['PostgreSQL', 'postgresql', 'Postgres', 'postgres', 'binaries'],
releases: [
{
name: 'postgresql-10.12-1-linux-x64-binaries.tar.gz',
version: '10.12',
lts: false,
channel: 'stable',
date: '',
os: 'linux',
arch: 'amd64',
libc: 'gnu',
ext: 'tar',
download: '',
},
{
name: 'postgresql-10.12-1-linux-binaries.tar.gz',
version: '10.12',
lts: false,
channel: 'stable',
date: '',
os: 'linux',
arch: 'x86',
libc: 'gnu',
ext: 'tar',
download: '',
},
{
name: 'postgresql-10.12-1-osx-binaries.zip',
version: '10.12',
lts: false,
channel: 'stable',
date: '',
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: '',
},
{
name: 'postgresql-10.13-1-osx-binaries.zip',
version: '10.13',
lts: false,
channel: 'stable',
date: '',
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: '',
},
{
name: 'postgresql-11.8-1-osx-binaries.zip',
version: '11.8',
lts: false,
channel: 'stable',
date: '',
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: '',
},
{
name: 'postgresql-12.3-1-osx-binaries.zip',
version: '12.3',
lts: false,
channel: 'stable',
date: '',
os: 'macos',
arch: 'amd64',
ext: 'zip',
download: '',
},
].map(function (rel) {
//@ts-ignore - it's a special property
rel._version = `${rel.version}-1`;
rel.download = `https://get.enterprisedb.com/postgresql/${rel.name}?ls=Crossover&type=Crossover`;
return rel;
}),
download: '',
};
Releases.latest = async function () {
let all = await Github.getDistributables(null, owner, repo);
/** @type {Array<Awaited<ReturnType<typeof Github.getDistributables>>>[Number]["releases"]} */
let distributables = [];
for (let dist of all.releases) {
console.log(dist);
console.log(dist.name, 'niche', /psql|baseline/.test(dist.name));
let isNiche = /psql|baseline/.test(dist.name);
if (isNiche) {
continue;
}
// REL_17_0 => 17.0
dist.version = dist.version.replace(/REL_/g, '');
dist.version = dist.version.replace(/_/g, '.');
let isHardMusl = dist.name.includes('musl');
if (isHardMusl) {
Object.assign(dist, { libc: 'musl', _musl: true });
}
distributables.push(dist);
}
all.releases = distributables;
Object.assign(all, { _names: originalReleases._names });
//@ts-ignore - mixing old and new release types
all.releases = all.releases.concat(originalReleases.releases);
return all;
};
if (module === require.main) {
Releases.latest().then(function (all) {
let normalize = require('../_webi/normalize.js');
all = normalize(all);
let json = JSON.stringify(all, null, 2);
console.info(json);
});
}

View File

@@ -1,50 +0,0 @@
'use strict';
let Releases = module.exports;
var Github = require('../_common/github.js');
var owner = 'bnnanet';
var repo = 'postgresql-releases';
Releases.latest = async function () {
let all = await Github.getDistributables(null, owner, repo);
/** @type {Array<Awaited<ReturnType<typeof Github.getDistributables>>>[Number]["releases"]} */
let distributables = [];
for (let dist of all.releases) {
let isBaseline = dist.name.includes('baseline');
if (isBaseline) {
continue;
}
let isClient = dist.name.includes('psql');
if (!isClient) {
continue;
}
// REL_17_0 => 17.0
dist.version = dist.version.replace(/REL_/g, '');
dist.version = dist.version.replace(/_/g, '.');
let isHardMusl = dist.name.includes('musl');
if (isHardMusl) {
Object.assign(dist, { libc: 'musl', _musl: true });
}
distributables.push(dist);
}
all.releases = distributables;
Object.assign(all, { _names: ['postgres', 'postgresql', 'pgsql', 'psql'] });
return all;
};
if (module === require.main) {
Releases.latest().then(function (all) {
let normalize = require('../_webi/normalize.js');
all = normalize(all);
let json = JSON.stringify(all, null, 2);
console.info(json);
});
}

View File

@@ -1,51 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'powershell';
var repo = 'powershell';
let ODDITIES = ['-fxdependent'];
function isOdd(build) {
for (let oddity of ODDITIES) {
let isOddity = build.name.includes(oddity);
if (isOddity) {
return true;
}
}
}
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
let odd = isOdd(rel);
if (odd) {
return false;
}
let isPreview = rel.name.includes('-preview.');
if (isPreview) {
rel.channel = 'beta';
}
let isMusl = rel.download.match(/(\b|_)(musl|alpine)(\b|_)/i);
if (isMusl) {
// not a fully static build, not gnu-compatible
rel.libc = 'musl';
}
return true;
});
all._names = ['PowerShell', 'powershell'];
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,19 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'rclone';
var repo = 'rclone';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 10);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,21 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'BurntSushi';
var repo = 'ripgrep';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all._names = ['ripgrep', 'rg'];
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,19 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'BurntSushi';
var repo = 'ripgrep';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
//console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,23 +0,0 @@
'use strict';
let Releases = module.exports;
let GitHub = require('../_common/github.js');
let owner = 'therootcompany';
let repo = 'runzip';
Releases.latest = async function () {
let all = await GitHub.getDistributables(null, owner, repo);
return all;
};
if (module === require.main) {
(async function () {
let normalize = require('../_webi/normalize.js');
let all = await Releases.latest();
all = normalize(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
})();
}

View File

@@ -1,46 +0,0 @@
'use strict';
let Releases = module.exports;
let Github = require('../_common/github.js');
let owner = 'sass';
let repo = 'dart-sass';
// https://github.com/sass/dart-sass/releases/
/** @type {Object.<String, String>} */
let archMap = {
ia32: 'x86',
x64: 'amd64',
arm: 'armv7',
};
let keys = Object.keys(archMap);
let keyList = keys.join('|');
let archRe = new RegExp(`\\b(${keyList})\\b`);
Releases.latest = function () {
return Github.getDistributables(null, owner, repo).then(function (all) {
Object.assign(all, {
_names: ['dart-sass', 'sass'],
});
for (let asset of all.releases) {
let m = asset.name.match(archRe);
let arch = m?.[1];
if (arch) {
asset.arch = archMap[arch];
}
}
return all;
});
};
if (module === require.main) {
Releases.latest().then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 10);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,18 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'therootcompany';
var repo = 'sclient';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'chmln';
var repo = 'sd';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,35 +0,0 @@
'use strict';
let Releases = module.exports;
let GitHub = require('../_common/github.js');
let oldOwner = 'therootcompany';
let oldRepo = 'serviceman';
let GitHubSource = require('../_common/github-source.js');
let owner = 'bnnanet';
let repo = 'serviceman';
Releases.latest = async function () {
let all = await GitHubSource.getDistributables({ owner, repo });
for (let pkg of all.releases) {
//@ts-expect-error
pkg.os = 'posix_2017';
}
let all2 = await GitHub.getDistributables(null, oldOwner, oldRepo);
for (let pkg of all2.releases) {
//@ts-expect-error
all.releases.push(pkg);
}
return all;
};
if (module === require.main) {
//@ts-expect-error
Releases.latest().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'koalaman';
var repo = 'shellcheck';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,19 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'mvdan';
var repo = 'sh';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,17 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'sqlc-dev';
var repo = 'sqlc';
module.exports = async function () {
let all = await github(null, owner, repo);
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,19 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'nalgeon';
var repo = 'sqlpkg-cli';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all._names = ['sqlpkg-cli', 'sqlpkg'];
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'abhimanyu003';
var repo = 'sttr';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'syncthing';
var repo = 'syncthing';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,78 +0,0 @@
'use strict';
let Fetcher = require('../_common/fetcher.js');
let alphaRe = /\d-alpha\d/;
let betaRe = /\d-beta\d/;
let rcRe = /\d-rc\d/;
/**
* @typedef BuildInfo
* @prop {String} version
* @prop {String} download
*/
async function getDistributables() {
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 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 channel = 'stable';
let isRc = rcRe.test(version);
let isBeta = betaRe.test(version);
let isAlpha = alphaRe.test(version);
if (isRc) {
channel = 'rc';
} else if (isBeta) {
channel = 'beta';
} else if (isAlpha) {
channel = 'alpha';
}
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: channel,
};
all.releases.push(r);
}
}
return all;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,36 +0,0 @@
'use strict';
let github = require('../_common/github.js');
let owner = 'terramate-io';
let repo = 'terramate';
let junkFiles = ['checksums.txt', 'cosign.pub'];
async function getDistributables() {
let all = await github(null, owner, repo);
let releases = [];
for (let release of all.releases) {
let isJunk = junkFiles.includes(release.name);
if (isJunk) {
continue;
}
releases.push(release);
}
all.releases = releases;
return all;
}
module.exports = getDistributables;
if (module === require.main) {
getDistributables().then(function (all) {
all = require('../_webi/normalize.js')(all);
// just select the first 5 for demonstration
// all.releases = all.releases.slice(0, 5);
// all.releases = all.releases.filter(
// release => !["checksums.txt.sig", "cosign.pub","terramate_0.9.0_windows_x86_64.zip"].includes(release.name)
// );
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,23 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'tinygo-org';
var repo = 'tinygo';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// all.releases = all.releases.filter(function (rel) {
// return !rel.name.endsWith('.deb');
// });
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,21 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'fujiapple852';
var repo = 'trippy';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all._names = ['trippy', 'trip'];
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,41 +0,0 @@
'use strict';
let Releases = module.exports;
let GitHub = require('../_common/github.js');
let owner = 'coolaj86';
let repo = 'uuidv7';
Releases.latest = async function () {
let all = await GitHub.getDistributables(null, owner, repo);
let distributables = [];
for (let dist of all.releases) {
// TODO update classifier to make thumb armv5
// and gnueabi armeb, not gnu
// and loongarch64 not arch64
let isSpecial =
dist.name.includes('-thumb') ||
dist.name.includes('-armeb') ||
dist.name.includes('-loong') ||
dist.name.includes('-gnux32') ||
dist.name.includes('-risc');
if (isSpecial) {
continue;
}
distributables.push(dist);
}
all.releases = distributables;
return all;
};
if (module === require.main) {
(async function () {
let normalize = require('../_webi/normalize.js');
let all = await Releases.latest();
all = normalize(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
})();
}

View File

@@ -1,19 +0,0 @@
'use strict';
var git = require('../_common/git-tag.js');
var gitUrl = 'https://github.com/tpope/vim-commentary.git';
module.exports = async function () {
let all = await git(gitUrl);
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
let samples = JSON.stringify(all, null, 2);
console.info(samples);
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var git = require('../_common/git-tag.js');
var gitUrl = 'https://github.com/ziglang/zig.vim.git';
module.exports = async function () {
let all = await git(gitUrl);
all._names = ['zig.vim', 'vim-zig'];
return all;
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
let samples = JSON.stringify(all, null, 2);
console.info(samples);
});
}

View File

@@ -1,27 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'watchexec';
var repo = 'watchexec';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
build.version = build.version.replace(/^cli-/, '');
builds.push(build);
}
all.releases = builds;
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,22 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'caddyserver';
var repo = 'xcaddy';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
return !/(\.txt)|(\.deb)$/i.test(rel.name);
});
return all;
});
};
if (module === require.main) {
module.exports().then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -1,20 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'BurntSushi';
var repo = 'xsv';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

View File

@@ -1,27 +0,0 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'therootcompany';
var repo = 'xz-static';
module.exports = function () {
return github(null, owner, repo).then(function (all) {
all.releases.forEach(function (rel) {
if (/windows/.test(rel.download)) {
if (!/(86|64)/.test(rel.arch)) {
rel.arch = 'amd64';
}
}
});
return all;
});
};
if (module === require.main) {
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);
console.info(JSON.stringify(all, null, 2));
});
}

Some files were not shown because too many files have changed in this diff Show More