@cutls/megalodon
Version:
Mastodon, Pleroma, Misskey API client for node.js and browser
107 lines (106 loc) • 4.25 kB
JavaScript
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');
}
};