UNPKG

@cutls/megalodon

Version:

Mastodon, Pleroma, Misskey API client for node.js and browser

107 lines (106 loc) 4.25 kB
import axios from 'axios'; import { NodeinfoError } from './megalodon.js'; const NODEINFO_10 = 'http://nodeinfo.diaspora.software/ns/schema/1.0'; const NODEINFO_20 = 'http://nodeinfo.diaspora.software/ns/schema/2.0'; const NODEINFO_21 = 'http://nodeinfo.diaspora.software/ns/schema/2.1'; export const detector = async (url) => { return (await getData(url)).compatibleSns; }; const getSemanticVersionNumber = (version) => { const match = version.match(/^(\d+\.\d+\.\d+)/); if (match) { return match[1]; } else { return version; } }; const getDataCore = async (url, sns, data) => { let ver = getSemanticVersionNumber(data.software.version); if (sns === 'pleroma') { try { const res = await axios.get(`${url}/api/v1/instance`, { timeout: 20000 }); ver = getSemanticVersionNumber(res.data.version); } catch { } } return { url: url, compatibleSns: sns, softwareName: data.software.name, version: data.software.version, semanticVersionCompatibleNumber: ver }; }; export const getData = async (url) => { const options = { timeout: 20000 }; const res = await axios.get(url + '/.well-known/nodeinfo', options); const link = res.data.links.find(l => l.rel === NODEINFO_20 || l.rel === NODEINFO_21); if (!link) throw new NodeinfoError('Could not find nodeinfo'); switch (link.rel) { case NODEINFO_10: { const res = await axios.get(link.href, options); switch (res.data.software.name) { case 'akkoma': return getDataCore(url, 'pleroma', res.data); case 'mastodon': return getDataCore(url, 'mastodon', res.data); case 'pleroma': return getDataCore(url, 'pleroma', res.data); default: if (res.data.metadata.upstream?.name && res.data.metadata.upstream.name.toLowerCase() === 'mastodon') { return getDataCore(url, 'mastodon', res.data); } throw new NodeinfoError('Unknown SNS'); } } case NODEINFO_20: { const res = await axios.get(link.href, options); switch (res.data.software.name) { case 'akkoma': return getDataCore(url, 'pleroma', res.data); case 'mastodon': return getDataCore(url, 'mastodon', res.data); case 'pleroma': return getDataCore(url, 'pleroma', res.data); case 'sharkey': return getDataCore(url, 'pleroma', res.data); default: if (res.data.metadata.upstream?.name && res.data.metadata.upstream.name.toLowerCase() === 'mastodon') { return getDataCore(url, 'mastodon', res.data); } throw new NodeinfoError('Unknown SNS'); } } case NODEINFO_21: { const res = await axios.get(link.href, options); switch (res.data.software.name) { case 'akkoma': return getDataCore(url, 'pleroma', res.data); case 'misskey': return getDataCore(url, 'misskey', res.data); case 'hometown': return getDataCore(url, 'mastodon', res.data); case 'mastodon': return getDataCore(url, 'mastodon', res.data); case 'pleroma': return getDataCore(url, 'pleroma', res.data); case 'sharkey': return getDataCore(url, 'pleroma', res.data); default: if (res.data.metadata.upstream?.name && res.data.metadata.upstream.name.toLowerCase() === 'mastodon') { return getDataCore(url, 'mastodon', res.data); } throw new NodeinfoError('Unknown SNS'); } } default: throw new NodeinfoError('Could not find nodeinfo'); } };