@cutls/megalodon
Version:
Mastodon, Pleroma, Misskey API client for node.js and browser
659 lines (658 loc) • 27.1 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isEmojiArr = void 0;
var axios_1 = __importDefault(require("axios"));
var dayjs_1 = __importDefault(require("dayjs"));
var form_data_1 = __importDefault(require("form-data"));
var default_1 = require("../default");
var web_socket_1 = __importDefault(require("./web_socket"));
var notification_1 = __importDefault(require("./notification"));
var notification_2 = __importDefault(require("../notification"));
var default_2 = require("../default");
var autolinker_1 = __importDefault(require("autolinker"));
var isEmojiArr = function (item) { return Array.isArray(item); };
exports.isEmojiArr = isEmojiArr;
function autoLinker(input, host) {
return autolinker_1.default.link(input, {
hashtag: 'twitter',
mention: 'twitter',
email: false,
stripPrefix: false,
replaceFn: function (match) {
switch (match.type) {
case 'url':
return true;
case 'mention':
return "<a href=\"https://".concat(host, "/@").concat(encodeURIComponent(match.getMention()), "\" target=\"_blank\">@").concat(match.getMention(), "</a>");
case 'hashtag':
return "<a href=\"https://".concat(host, "/tags/").concat(encodeURIComponent(match.getHashtag()), "\" target=\"_blank\">#").concat(match.getHashtag(), "</a>");
}
return false;
}
});
}
var MisskeyAPI;
(function (MisskeyAPI) {
var Converter;
(function (Converter) {
Converter.emoji = function (e) {
return {
shortcode: e.name,
static_url: e.url,
url: e.url,
visible_in_picker: true
};
};
Converter.emojiConverter = function (e) {
if (!e)
return [];
if ((0, exports.isEmojiArr)(e))
return e;
var emojiArr = Object.entries(e).map(function (_a) {
var _b = __read(_a, 2), key = _b[0], value = _b[1];
return {
name: key,
host: null,
url: value,
aliases: []
};
});
return emojiArr;
};
Converter.user = function (u, host) {
host = host.replace('https://', '');
var acct = u.username;
var acctUrl = "https://".concat(host || u.host || 'example.com', "/@").concat(u.username);
if (u.host) {
acct = "".concat(u.username, "@").concat(u.host);
acctUrl = "https://".concat(u.host, "/@").concat(u.username);
}
return {
id: u.id,
username: u.username,
acct: acct,
display_name: u.name || u.username,
locked: false,
created_at: new Date().toISOString(),
followers_count: 0,
following_count: 0,
statuses_count: 0,
note: '',
url: acctUrl,
avatar: u.avatarUrl,
avatar_static: u.avatarUrl,
header: u.avatarUrl,
header_static: u.avatarUrl,
emojis: Converter.emojiConverter(u.emojis).map(function (e) { return Converter.emoji(e); }),
moved: null,
fields: [],
bot: false,
group: false,
discoverable: false,
noindex: false,
suspended: false,
limited: false
};
};
Converter.userDetail = function (u, host) {
var acct = u.username;
host = host.replace('https://', '');
var acctUrl = "https://".concat(host || u.host || 'example.com', "/@").concat(u.username);
if (u.host) {
acct = "".concat(u.username, "@").concat(u.host);
acctUrl = "https://".concat(u.host, "/@").concat(u.username);
}
return {
id: u.id,
username: u.username,
acct: acct,
display_name: u.name || u.username,
locked: !!u.isLocked,
created_at: u.createdAt || new Date().toISOString(),
followers_count: u.followersCount || 0,
following_count: u.followingCount || 0,
statuses_count: u.notesCount || 0,
note: u.description || '',
url: acctUrl,
avatar: u.avatarUrl || 'https://http.cat/404',
avatar_static: u.avatarUrl || 'https://http.cat/404',
header: u.bannerUrl || u.avatarUrl || 'https://http.cat/404',
header_static: u.bannerUrl || u.avatarUrl || 'https://http.cat/404',
emojis: Converter.emojiConverter(u.emojis).map(function (e) { return Converter.emoji(e); }),
moved: null,
fields: [],
bot: u.isBot || false,
group: false,
discoverable: false,
noindex: false,
suspended: false,
limited: false
};
};
Converter.visibility = function (v) {
switch (v) {
case 'public':
return v;
case 'home':
return 'unlisted';
case 'followers':
return 'private';
case 'specified':
return 'direct';
}
};
Converter.encodeVisibility = function (v) {
switch (v) {
case 'public':
return v;
case 'unlisted':
return 'home';
case 'private':
return 'followers';
case 'direct':
return 'specified';
}
};
Converter.fileType = function (s) {
if (s === 'image/gif') {
return 'gifv';
}
if (s.includes('image')) {
return 'image';
}
if (s.includes('video')) {
return 'video';
}
if (s.includes('audio')) {
return 'audio';
}
return 'unknown';
};
Converter.file = function (f) {
return {
id: f.id,
type: Converter.fileType(f.type),
url: f.url,
remote_url: f.url,
preview_url: f.thumbnailUrl,
text_url: f.url,
meta: {
width: f.properties.width,
height: f.properties.height
},
description: null,
blurhash: null
};
};
Converter.follower = function (f, host) {
return Converter.user(f.follower, host);
};
Converter.following = function (f, host) {
return Converter.user(f.followee, host);
};
Converter.relation = function (r) {
return {
id: r.id,
following: r.isFollowing,
followed_by: r.isFollowed,
blocking: r.isBlocking,
blocked_by: r.isBlocked,
muting: r.isMuted,
muting_notifications: false,
requested: r.hasPendingFollowRequestFromYou,
domain_blocking: false,
showing_reblogs: true,
endorsed: false,
notifying: false,
note: ''
};
};
Converter.choice = function (c) {
return {
title: c.text,
votes_count: c.votes
};
};
Converter.poll = function (p) {
var now = (0, dayjs_1.default)();
var expire = (0, dayjs_1.default)(p.expiresAt);
var count = p.choices.reduce(function (sum, choice) { return sum + choice.votes; }, 0);
return {
id: '',
expires_at: p.expiresAt,
expired: now.isAfter(expire),
multiple: p.multiple,
votes_count: count,
options: p.choices.map(function (c) { return Converter.choice(c); }),
voted: p.choices.some(function (c) { return c.isVoted; })
};
};
Converter.note = function (n, host) {
host = host.replace('https://', '');
var text = n.text
? n.text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/`/g, '`')
.replace(/\r?\n/g, '<br>')
: '';
var html = autoLinker(text, host);
return {
id: n.id,
uri: n.uri ? n.uri : "https://".concat(host, "/notes/").concat(n.id),
url: n.uri ? n.uri : "https://".concat(host, "/notes/").concat(n.id),
account: Converter.user(n.user, host),
in_reply_to_id: n.replyId,
in_reply_to_account_id: null,
reblog: n.renote ? Converter.note(n.renote, host) : null,
content: html,
plain_content: n.text ? n.text : null,
created_at: n.createdAt,
edited_at: null,
emojis: Converter.emojiConverter(n.emojis).map(function (e) { return Converter.emoji(e); }),
replies_count: n.repliesCount,
reblogs_count: n.renoteCount,
favourites_count: 0,
reblogged: false,
favourited: !!n.myReaction,
muted: false,
sensitive: n.files ? n.files.some(function (f) { return f.isSensitive; }) : false,
spoiler_text: n.cw ? n.cw : '',
visibility: Converter.visibility(n.visibility),
media_attachments: n.files ? n.files.map(function (f) { return Converter.file(f); }) : [],
mentions: [],
tags: [],
card: null,
poll: n.poll ? Converter.poll(n.poll) : null,
application: null,
language: null,
pinned: null,
emoji_reactions: Converter.mapReactions(host, n.reactions, n.myReaction || '', n.reactionEmojis || {}),
bookmarked: false,
quote: !!(n.renote && n.text),
quote_status_misskey: n.renote && n.text ? Converter.note(n.renote, host) : null
};
};
Converter.mapReactions = function (host, r, myReaction, emojiData) {
if ((0, exports.isEmojiArr)(emojiData)) {
return emojiData.map(function (e) {
return {
count: 0,
me: false,
name: e.name,
url: e.url,
static_url: e.url
};
});
}
return Object.keys(r).map(function (key) {
var keyObj = key.replace(/:/g, '');
var shortcode = key.replace(/[:@.]/g, '');
var isCustomEmoji = shortcode !== key;
if (myReaction && key === myReaction) {
return {
count: r[key],
me: true,
name: shortcode,
url: isCustomEmoji ? emojiData[keyObj] || "https://".concat(host, "/emoji/").concat(shortcode, ".webp") : undefined,
static_url: isCustomEmoji ? emojiData[keyObj] || "https://".concat(host, "/emoji/").concat(shortcode, ".webp") : undefined
};
}
return {
count: r[key],
me: false,
name: shortcode,
url: isCustomEmoji ? emojiData[keyObj] || "https://".concat(host, "/emoji/").concat(shortcode, ".webp") : undefined,
static_url: isCustomEmoji ? emojiData[keyObj] || "https://".concat(host, "/emoji/").concat(shortcode, ".webp") : undefined
};
});
};
Converter.reactions = function (r, host, emojiData) {
var e_1, _a;
var result = [];
if ((0, exports.isEmojiArr)(emojiData)) {
return emojiData.map(function (e) {
return {
count: 0,
me: false,
name: e.name,
url: e.url,
static_url: e.url
};
});
}
var _loop_1 = function (e) {
var shortcode = e.type.replace(/[:@.]/g, '');
var isCustomEmoji = shortcode !== e.type;
var i = result.findIndex(function (res) { return res.name === e.type; });
if (i >= 0) {
result[i].count++;
}
else {
result.push({
count: 1,
me: false,
name: shortcode,
url: isCustomEmoji ? emojiData[shortcode] || "https://".concat(host, "/emoji/").concat(shortcode, ".webp") : undefined,
static_url: isCustomEmoji ? emojiData[shortcode] || "https://".concat(host, "/emoji/").concat(shortcode, ".webp") : undefined
});
}
};
try {
for (var r_1 = __values(r), r_1_1 = r_1.next(); !r_1_1.done; r_1_1 = r_1.next()) {
var e = r_1_1.value;
_loop_1(e);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (r_1_1 && !r_1_1.done && (_a = r_1.return)) _a.call(r_1);
}
finally { if (e_1) throw e_1.error; }
}
return result;
};
Converter.noteToConversation = function (n, host) {
var accounts = [Converter.user(n.user, host)];
if (n.reply) {
accounts.push(Converter.user(n.reply.user, host));
}
return {
id: n.id,
accounts: accounts,
last_status: Converter.note(n, host),
unread: false
};
};
Converter.list = function (l) { return ({
id: l.id,
title: l.name,
replies_policy: null
}); };
Converter.encodeNotificationType = function (e) {
switch (e) {
case notification_2.default.Follow:
return notification_1.default.Follow;
case notification_2.default.Mention:
return notification_1.default.Reply;
case notification_2.default.Favourite:
case notification_2.default.Reaction:
return notification_1.default.Reaction;
case notification_2.default.Reblog:
return notification_1.default.Renote;
case notification_2.default.PollVote:
return notification_1.default.PollVote;
case notification_2.default.FollowRequest:
return notification_1.default.ReceiveFollowRequest;
default:
return e;
}
};
Converter.decodeNotificationType = function (e) {
switch (e) {
case notification_1.default.Follow:
return notification_2.default.Follow;
case notification_1.default.Mention:
case notification_1.default.Reply:
return notification_2.default.Mention;
case notification_1.default.Renote:
case notification_1.default.Quote:
return notification_2.default.Reblog;
case notification_1.default.Reaction:
return notification_2.default.Reaction;
case notification_1.default.PollVote:
return notification_2.default.PollVote;
case notification_1.default.ReceiveFollowRequest:
return notification_2.default.FollowRequest;
case notification_1.default.FollowRequestAccepted:
return notification_2.default.Follow;
default:
return e;
}
};
var modelOfAcct = {
id: '1',
username: 'none',
acct: 'none',
display_name: 'none',
locked: true,
bot: true,
discoverable: false,
group: false,
created_at: '1971-01-01T00:00:00.000Z',
note: '',
url: 'https://http.cat/404',
avatar: 'https://http.cat/404',
avatar_static: 'https://http.cat/404',
header: 'https://http.cat/404',
header_static: 'https://http.cat/404',
followers_count: -1,
following_count: 0,
statuses_count: 0,
noindex: true,
emojis: [],
fields: [],
moved: null,
suspended: false,
limited: false
};
Converter.notification = function (n, host) {
var notification = {
id: n.id,
account: n.user ? Converter.user(n.user, host) : modelOfAcct,
created_at: n.createdAt,
type: Converter.decodeNotificationType(n.type)
};
if (n.note) {
notification = Object.assign(notification, {
status: Converter.note(n.note, host)
});
}
if (n.reaction) {
notification = Object.assign(notification, {
emoji: n.reaction
});
}
return notification;
};
Converter.stats = function (s) {
return {
user_count: s.usersCount,
status_count: s.notesCount,
domain_count: s.instances
};
};
Converter.meta = function (m, s) {
var wss = m.uri.replace(/^https:\/\//, 'wss://');
return {
uri: m.uri,
title: m.name,
description: m.description,
email: m.maintainerEmail,
version: m.version,
thumbnail: m.bannerUrl,
urls: {
streaming_api: "".concat(wss, "/streaming")
},
stats: Converter.stats(s),
languages: m.langs,
contact_account: undefined,
registrations: !m.disableRegistration,
approval_required: false,
configuration: {
statuses: {
max_characters: m.maxNoteTextLength
}
}
};
};
Converter.hashtag = function (h) {
return {
name: h.tag,
url: h.tag,
history: [],
following: false
};
};
})(Converter = MisskeyAPI.Converter || (MisskeyAPI.Converter = {}));
MisskeyAPI.DEFAULT_SCOPE = [
'read:account',
'write:account',
'read:blocks',
'write:blocks',
'read:drive',
'write:drive',
'read:favorites',
'write:favorites',
'read:following',
'write:following',
'read:mutes',
'write:mutes',
'write:notes',
'read:notifications',
'write:notifications',
'read:reactions',
'write:reactions',
'write:votes'
];
var Client = (function () {
function Client(baseUrl, accessToken, userAgent) {
if (userAgent === void 0) { userAgent = default_1.DEFAULT_UA; }
this.accessToken = accessToken;
this.baseUrl = baseUrl;
this.userAgent = userAgent;
this.abortController = new AbortController();
axios_1.default.defaults.signal = this.abortController.signal;
}
Client.prototype.post = function (path_1) {
return __awaiter(this, arguments, void 0, function (path, params, headers) {
var options, bodyParams;
if (params === void 0) { params = {}; }
if (headers === void 0) { headers = {}; }
return __generator(this, function (_a) {
options = {
headers: headers,
maxContentLength: Infinity,
maxBodyLength: Infinity
};
bodyParams = params;
if (this.accessToken) {
if (params instanceof form_data_1.default) {
bodyParams.set('limit', parseInt(bodyParams.get('limit'), 10));
bodyParams.append('i', this.accessToken);
}
else {
params.limit = parseInt(params.limit, 10);
bodyParams = Object.assign(params, {
i: this.accessToken
});
}
}
return [2, axios_1.default.post(this.baseUrl + path, bodyParams, options).then(function (resp) {
var res = {
data: resp.data,
status: resp.status,
statusText: resp.statusText,
headers: resp.headers
};
return res;
})];
});
});
};
Client.prototype.cancel = function () {
return this.abortController.abort();
};
Client.prototype.socket = function (channel, listId) {
if (!this.accessToken) {
throw new Error('accessToken is required');
}
var url = this.baseUrl.replace('https://', 'wss://') + '/streaming';
var streaming = new web_socket_1.default(url, channel, this.accessToken, listId, this.userAgent);
if (!(0, default_2.isBrowser)()) {
process.nextTick(function () {
streaming.start();
});
}
else {
setTimeout(function () {
streaming.start();
}, 0);
}
return streaming;
};
return Client;
}());
MisskeyAPI.Client = Client;
})(MisskeyAPI || (MisskeyAPI = {}));
exports.default = MisskeyAPI;