const gh = (path) => new URL(path, 'https://nobsdelivr.private.coffee/gh'); const getJson = (url) => fetch(url, { headers: { Accept: "application/json" } }) .then((response) => response.json()) .catch((error) => { console.error(error); }); async function fetchInstances() { const targetTypes = [ 'anonymousoverflow', 'breezewiki', 'dumb', 'eddrit', 'intellectual', 'invidious', 'libmedium', 'nerdsfornerds', 'neuters', 'nitter', 'photon-reddit', 'priviblur', 'quetre', 'redlib', 'ruraldictionary', 'scribe', ]; const instances = targetTypes.reduce((out, type) => { out[type] = []; return out; }, Object.create(null)); 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 .filter((instance) => !instance.endsWith('.onion')) .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(gh(provider.source)); if (!result) { return []; } return provider.normalize(result); }); const sources = await Promise.all(promises); for (const source of sources.flat()) { if (!(source.type in instances)) continue; const list = instances[source.type]; for (const instance of source.instances) { const { href } = new URL(instance); if (!list.includes(href)) { list.push(href); list.sort(); } } } return instances; } async function testBackups() { const backups = [ 'https://api.npoint.io/6ee2cb1b5a1aa6f10be5', ]; 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}`); } } }