const cdn = (path) => new URL(path, 'https://nobsdelivr.private.coffee/'); const withCatch = (action) => (...args) => Promise.try(action, ...args).catch((error) => { console.error('Caught error:', error); }); const getJson = withCatch((url) => fetch(url, { headers: { Accept: 'application/json' } }).then((response) => response.json(), ), ); async function testBackups() { const backups = [ 'https://jsonblob.com/api/jsonBlob/1392945386074857472', 'https://api.npoint.io/6ee2cb1b5a1aa6f10be5', 'https://api.pastes.dev/VSjbFP63yq', 'https://api.codetabs.com/v1/proxy/?quest=https%3A%2F%2Fstarb.in%2Fraw%2FMgDjym', 'https://bytebin.lucko.me/bDAxqrUNqD', ]; const results = await Promise.all(backups.map((backup) => getJson(backup))); for (const index of results.keys()) { const result = results[index]; if (!result) { const backup = backups[index]; console.warn(`Stale backup: ${backup}`); } } } async function fetchInstances() { const instances = { ducksforducks: ['https://ducksforducks.private.coffee'], nerdsfornerds: ['https://nn.vern.cc'], }; const providers = { libredirect: { source: 'libredirect/instances/data.json', normalize: (result) => Object.entries(result).map(([name, instances]) => ({ type: name.toLowerCase(), instances: instances.clearnet, })), }, farside: { source: 'benbusby/farside/services.json', normalize: (result) => result.map((service) => ({ type: service.type, instances: service.instances.concat(service.fallback), })), }, fastside: { source: 'cofob/fastside/services.json', normalize: (result) => result.services.map((service) => ({ type: service.type, instances: service.instances .filter((instance) => instance.tags.includes('clearnet')) .map((instance) => instance.url), })), }, }; const promises = Object.values(providers).map(async (provider) => { const result = await getJson(cdn(`gh/${provider.source}`)); if (!result) { return []; } return provider.normalize(result); }); const sources = await Promise.all(promises); for (const source of sources.flat()) { const list = (instances[source.type] ??= []); for (const url of source.instances) { if (!list.includes(url)) { list.push(url); } } } return instances; } await testBackups(); await fetchInstances();