1
0
Fork 0

upd: change deps, fix a few bugs, update converter

Fixes User and Notes count bug ()
Fixes build issues due to types ()
Return accounts and notes like Iceshrimp
Use MFM class from Iceshrimp to fix HTML output for mastodon
This commit is contained in:
Mar0xy 2023-10-29 00:50:00 +02:00
parent b0a7fd6ddb
commit 82c10de265
No known key found for this signature in database
GPG key ID: 56569BBE47D2C828
14 changed files with 421 additions and 242 deletions

View file

@ -388,4 +388,212 @@ export class MfmService {
return `<p>${doc.body.innerHTML}</p>`;
}
@bindThis
public async toMastoHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMentionedRemoteUsers = [], inline = false, quoteUri: string | null = null) {
if (nodes == null) {
return null;
}
const { window } = new Window();
const doc = window.document;
async function appendChildren(children: mfm.MfmNode[], targetElement: any): Promise<void> {
if (children) {
for (const child of await Promise.all(children.map(async (x) => await (handlers as any)[x.type](x)))) targetElement.appendChild(child);
}
}
const handlers: {
[K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => any;
} = {
async bold(node) {
const el = doc.createElement('span');
el.textContent = '**';
await appendChildren(node.children, el);
el.textContent += '**';
return el;
},
async small(node) {
const el = doc.createElement('small');
await appendChildren(node.children, el);
return el;
},
async strike(node) {
const el = doc.createElement('span');
el.textContent = '~~';
await appendChildren(node.children, el);
el.textContent += '~~';
return el;
},
async italic(node) {
const el = doc.createElement('span');
el.textContent = '*';
await appendChildren(node.children, el);
el.textContent += '*';
return el;
},
async fn(node) {
const el = doc.createElement('span');
el.textContent = '*';
await appendChildren(node.children, el);
el.textContent += '*';
return el;
},
blockCode(node) {
const pre = doc.createElement('pre');
const inner = doc.createElement('code');
const nodes = node.props.code
.split(/\r\n|\r|\n/)
.map((x) => doc.createTextNode(x));
for (const x of intersperse<FIXME | 'br'>('br', nodes)) {
inner.appendChild(x === 'br' ? doc.createElement('br') : x);
}
pre.appendChild(inner);
return pre;
},
async center(node) {
const el = doc.createElement('div');
await appendChildren(node.children, el);
return el;
},
emojiCode(node) {
return doc.createTextNode(`\u200B:${node.props.name}:\u200B`);
},
unicodeEmoji(node) {
return doc.createTextNode(node.props.emoji);
},
hashtag: (node) => {
const a = doc.createElement('a');
a.setAttribute('href', `${this.config.url}/tags/${node.props.hashtag}`);
a.textContent = `#${node.props.hashtag}`;
a.setAttribute('rel', 'tag');
a.setAttribute('class', 'hashtag');
return a;
},
inlineCode(node) {
const el = doc.createElement('code');
el.textContent = node.props.code;
return el;
},
mathInline(node) {
const el = doc.createElement('code');
el.textContent = node.props.formula;
return el;
},
mathBlock(node) {
const el = doc.createElement('code');
el.textContent = node.props.formula;
return el;
},
async link(node) {
const a = doc.createElement('a');
a.setAttribute('rel', 'nofollow noopener noreferrer');
a.setAttribute('target', '_blank');
a.setAttribute('href', node.props.url);
await appendChildren(node.children, a);
return a;
},
async mention(node) {
const { username, host, acct } = node.props;
const resolved = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
const el = doc.createElement('span');
if (!resolved) {
el.textContent = acct;
} else {
el.setAttribute('class', 'h-card');
el.setAttribute('translate', 'no');
const a = doc.createElement('a');
a.setAttribute('href', resolved.url ? resolved.url : resolved.uri);
a.className = 'u-url mention';
const span = doc.createElement('span');
span.textContent = resolved.username || username;
a.textContent = '@';
a.appendChild(span);
el.appendChild(a);
}
return el;
},
async quote(node) {
const el = doc.createElement('blockquote');
await appendChildren(node.children, el);
return el;
},
text(node) {
const el = doc.createElement('span');
const nodes = node.props.text
.split(/\r\n|\r|\n/)
.map((x) => doc.createTextNode(x));
for (const x of intersperse<FIXME | 'br'>('br', nodes)) {
el.appendChild(x === 'br' ? doc.createElement('br') : x);
}
return el;
},
url(node) {
const a = doc.createElement('a');
a.setAttribute('rel', 'nofollow noopener noreferrer');
a.setAttribute('target', '_blank');
a.setAttribute('href', node.props.url);
a.textContent = node.props.url.replace(/^https?:\/\//, '');
return a;
},
search: (node) => {
const a = doc.createElement('a');
a.setAttribute('href', `https"google.com/${node.props.query}`);
a.textContent = node.props.content;
return a;
},
async plain(node) {
const el = doc.createElement('span');
await appendChildren(node.children, el);
return el;
},
};
await appendChildren(nodes, doc.body);
if (quoteUri !== null) {
const a = doc.createElement('a');
a.setAttribute('href', quoteUri);
a.textContent = quoteUri.replace(/^https?:\/\//, '');
const quote = doc.createElement('span');
quote.setAttribute('class', 'quote-inline');
quote.appendChild(doc.createElement('br'));
quote.appendChild(doc.createElement('br'));
quote.innerHTML += 'RE: ';
quote.appendChild(a);
doc.body.appendChild(quote);
}
return inline ? doc.body.innerHTML : `<p>${doc.body.innerHTML}</p>`;
}
}

View file

@ -8,7 +8,7 @@ import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import type { Config } from '@/config.js';
import { MetaService } from '@/core/MetaService.js';
import { convertId, IdConvertType as IdType, convertAccount, convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList } from './converters.js';
import { convertAccount, convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList } from './converters.js';
import { getInstance } from './endpoints/meta.js';
import { ApiAuthMastodon, ApiAccountMastodon, ApiFilterMastodon, ApiNotifyMastodon, ApiSearchMastodon, ApiTimelineMastodon, ApiStatusMastodon } from './endpoints.js';
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
@ -128,7 +128,7 @@ export class MastodonApiServerService {
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.dismissInstanceAnnouncement(
convertId(_request.body['id'], IdType.SharkeyId),
_request.body['id'],
);
reply.send(data.data);
} catch (e: any) {
@ -236,7 +236,7 @@ export class MastodonApiServerService {
const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
// displayed without being logged in
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.verifyCredentials());
} catch (e: any) {
/* console.error(e); */
@ -286,7 +286,7 @@ export class MastodonApiServerService {
ids = [ids];
}
users = ids;
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getRelationships(users));
} catch (e: any) {
/* console.error(e); */
@ -302,7 +302,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const sharkId = convertId(_request.params.id, IdType.SharkeyId);
const sharkId = _request.params.id;
const data = await client.getAccount(sharkId);
const profile = await this.userProfilesRepository.findOneBy({ userId: sharkId });
data.data.fields = profile?.fields.map(f => ({ ...f, verified_at: null })) || [];
@ -319,7 +319,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getStatuses());
} catch (e: any) {
/* console.error(e);
@ -347,7 +347,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getFollowers());
} catch (e: any) {
/* console.error(e);
@ -361,7 +361,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getFollowing());
} catch (e: any) {
/* console.error(e);
@ -375,7 +375,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getAccountLists(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.getAccountLists(_request.params.id);
reply.send(data.data.map((list) => convertList(list)));
} catch (e: any) {
/* console.error(e);
@ -389,7 +389,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.addFollow());
} catch (e: any) {
/* console.error(e);
@ -403,7 +403,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.rmFollow());
} catch (e: any) {
/* console.error(e);
@ -417,7 +417,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.addBlock());
} catch (e: any) {
/* console.error(e);
@ -431,7 +431,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.rmBlock());
} catch (e: any) {
/* console.error(e);
@ -445,7 +445,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.addMute());
} catch (e: any) {
/* console.error(e);
@ -459,7 +459,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.rmMute());
} catch (e: any) {
/* console.error(e);
@ -487,7 +487,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getBookmarks());
} catch (e: any) {
/* console.error(e);
@ -501,7 +501,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getFavourites());
} catch (e: any) {
/* console.error(e);
@ -515,7 +515,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getMutes());
} catch (e: any) {
/* console.error(e);
@ -529,7 +529,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.getBlocks());
} catch (e: any) {
/* console.error(e);
@ -557,7 +557,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.acceptFollow());
} catch (e: any) {
/* console.error(e);
@ -571,7 +571,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const account = new ApiAccountMastodon(_request, client, BASE_URL);
const account = new ApiAccountMastodon(_request, client, BASE_URL, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
reply.send(await account.rejectFollow());
} catch (e: any) {
/* console.error(e);
@ -813,7 +813,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.updateMedia(convertId(_request.params.id, IdType.SharkeyId), _request.body!);
const data = await client.updateMedia(_request.params.id, _request.body!);
reply.send(convertAttachment(data.data));
} catch (e: any) {
/* console.error(e); */

View file

@ -3,14 +3,13 @@ import { MfmService } from '@/core/MfmService.js';
import { DI } from '@/di-symbols.js';
import { Inject } from '@nestjs/common';
import { Entity } from 'megalodon';
import { parse } from 'mfm-js';
import mfm from 'mfm-js';
import { GetterService } from '../GetterService.js';
import type { IMentionedRemoteUsers } from '@/models/Note.js';
import type { MiUser } from '@/models/User.js';
import type { NoteEditRepository, NotesRepository, UsersRepository } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
const CHAR_COLLECTION = '0123456789abcdefghijklmnopqrstuvwxyz';
import { awaitAll } from '@/misc/prelude/await-all.js';
export enum IdConvertType {
MastodonId,
@ -18,13 +17,13 @@ export enum IdConvertType {
}
export const escapeMFM = (text: string): string => text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;")
.replace(/`/g, "&#x60;")
.replace(/\r?\n/g, "<br>");
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;")
.replace(/`/g, "&#x60;")
.replace(/\r?\n/g, "<br>");
export class MastoConverters {
private MfmService: MfmService;
@ -49,7 +48,7 @@ export class MastoConverters {
this.GetterService = new GetterService(this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
}
private encode(u: MiUser, m: IMentionedRemoteUsers): MastodonEntity.Mention {
private encode(u: MiUser, m: IMentionedRemoteUsers): Entity.Mention {
let acct = u.username;
let acctUrl = `https://${u.host || this.config.host}/@${u.username}`;
let url: string | null = null;
@ -73,89 +72,97 @@ export class MastoConverters {
});
}
public async convertAccount(account: Entity.Account) {
return awaitAll({
id: account.id,
username: account.username,
acct: account.acct,
fqn: account.fqn,
display_name: account.display_name || account.username,
locked: account.locked,
created_at: account.created_at,
followers_count: account.followers_count,
following_count: account.following_count,
statuses_count: account.statuses_count,
note: account.note,
url: account.url,
avatar: account.avatar,
avatar_static: account.avatar,
header: account.header,
header_static: account.header,
emojis: account.emojis,
moved: null, //FIXME
fields: [],
bot: false,
discoverable: true,
});
}
public async convertStatus(status: Entity.Status) {
status.account = convertAccount(status.account);
const convertedAccount = this.convertAccount(status.account);
const note = await this.GetterService.getNote(status.id);
status.id = convertId(status.id, IdConvertType.MastodonId);
if (status.in_reply_to_account_id) status.in_reply_to_account_id = convertId(
status.in_reply_to_account_id,
IdConvertType.MastodonId,
);
if (status.in_reply_to_id) status.in_reply_to_id = convertId(status.in_reply_to_id, IdConvertType.MastodonId);
status.media_attachments = status.media_attachments.map((attachment) =>
convertAttachment(attachment),
);
// This will eventually be improved with a rewrite of this file
const mentions = Promise.all(note.mentions.map(p =>
this.getUser(p)
.then(u => this.encode(u, JSON.parse(note.mentionedRemoteUsers)))
.catch(() => null)))
.then(p => p.filter(m => m)) as Promise<MastodonEntity.Mention[]>;
status.mentions = await mentions;
status.mentions = status.mentions.map((mention) => ({
...mention,
id: convertId(mention.id, IdConvertType.MastodonId),
}));
const convertedMFM = this.MfmService.toHtml(parse(status.content), JSON.parse(note.mentionedRemoteUsers));
status.content = status.content ? convertedMFM?.replace(/&amp;/g, "&").replaceAll(`<span>&</span><a href="${this.config.url}/tags/39;" rel="tag">#39;</a>`, "<span>\'</span>") as string : status.content;
if (status.poll) status.poll = convertPoll(status.poll);
if (status.reblog) status.reblog = convertStatus(status.reblog);
return status;
}
}
.then(p => p.filter(m => m)) as Promise<Entity.Mention[]>;
export function convertId(in_id: string, id_convert_type: IdConvertType): string {
switch (id_convert_type) {
case IdConvertType.MastodonId: {
let out = BigInt(0);
const lowerCaseId = in_id.toLowerCase();
for (let i = 0; i < lowerCaseId.length; i++) {
const charValue = numFromChar(lowerCaseId.charAt(i));
out += BigInt(charValue) * BigInt(36) ** BigInt(i);
}
return out.toString();
}
case IdConvertType.SharkeyId: {
let input = BigInt(in_id);
let outStr = '';
while (input > BigInt(0)) {
const remainder = Number(input % BigInt(36));
outStr = charFromNum(remainder) + outStr;
input /= BigInt(36);
}
const ReversedoutStr = outStr.split('').reduce((acc, char) => char + acc, '');
return ReversedoutStr;
}
default:
throw new Error('Invalid ID conversion type');
}
}
const content = note.text !== null
? this.MfmService.toMastoHtml(mfm.parse(note.text!), JSON.parse(note.mentionedRemoteUsers), false, null)
.then(p => p ?? escapeMFM(note.text!))
: '';
function numFromChar(character: string): number {
for (let i = 0; i < CHAR_COLLECTION.length; i++) {
if (CHAR_COLLECTION.charAt(i) === character) {
return i;
}
}
const tags = note.tags.map(tag => {
return {
name: tag,
url: `${this.config.url}/tags/${tag}`,
} as Entity.Tag;
});
throw new Error('Invalid character in parsed base36 id');
}
function charFromNum(number: number): string {
if (number >= 0 && number < CHAR_COLLECTION.length) {
return CHAR_COLLECTION.charAt(number);
} else {
throw new Error('Invalid number for base-36 encoding');
// noinspection ES6MissingAwait
return await awaitAll({
id: note.id,
uri: note.uri ?? `https://${this.config.host}/notes/${note.id}`,
url: note.url ?? note.uri ?? `https://${this.config.host}/notes/${note.id}`,
account: convertedAccount,
in_reply_to_id: note.replyId,
in_reply_to_account_id: note.replyUserId,
reblog: status.reblog,
content: content,
content_type: 'text/x.misskeymarkdown',
text: note.text,
created_at: status.created_at,
emojis: status.emojis,
replies_count: note.repliesCount,
reblogs_count: note.renoteCount,
favourites_count: status.favourites_count,
reblogged: false,
favourited: status.favourited,
muted: status.muted,
sensitive: status.sensitive,
spoiler_text: note.cw ? note.cw : '',
visibility: status.visibility,
media_attachments: status.media_attachments,
mentions: mentions,
tags: tags,
card: null, //FIXME
poll: status.poll ?? null,
application: null, //FIXME
language: null, //FIXME
pinned: null,
reactions: status.emoji_reactions,
emoji_reactions: status.emoji_reactions,
bookmarked: false,
quote: false,
edited_at: note.updatedAt?.toISOString(),
});
}
}
function simpleConvert(data: any) {
// copy the object to bypass weird pass by reference bugs
const result = Object.assign({}, data);
result.id = convertId(data.id, IdConvertType.MastodonId);
return result;
}
@ -180,7 +187,6 @@ export function convertFeaturedTag(tag: Entity.FeaturedTag) {
export function convertNotification(notification: Entity.Notification) {
notification.account = convertAccount(notification.account);
notification.id = convertId(notification.id, IdConvertType.MastodonId);
if (notification.status) notification.status = convertStatus(notification.status);
return notification;
}
@ -200,19 +206,9 @@ export function convertRelationship(relationship: Entity.Relationship) {
export function convertStatus(status: Entity.Status) {
status.account = convertAccount(status.account);
status.id = convertId(status.id, IdConvertType.MastodonId);
if (status.in_reply_to_account_id) status.in_reply_to_account_id = convertId(
status.in_reply_to_account_id,
IdConvertType.MastodonId,
);
if (status.in_reply_to_id) status.in_reply_to_id = convertId(status.in_reply_to_id, IdConvertType.MastodonId);
status.media_attachments = status.media_attachments.map((attachment) =>
convertAttachment(attachment),
);
status.mentions = status.mentions.map((mention) => ({
...mention,
id: convertId(mention.id, IdConvertType.MastodonId),
}));
if (status.poll) status.poll = convertPoll(status.poll);
if (status.reblog) status.reblog = convertStatus(status.reblog);
@ -224,7 +220,6 @@ export function convertStatusSource(status: Entity.StatusSource) {
}
export function convertConversation(conversation: Entity.Conversation) {
conversation.id = convertId(conversation.id, IdConvertType.MastodonId);
conversation.accounts = conversation.accounts.map(convertAccount);
if (conversation.last_status) {
conversation.last_status = convertStatus(conversation.last_status);

View file

@ -1,7 +1,10 @@
import { convertId, IdConvertType as IdType, convertAccount, convertRelationship, convertStatus } from '../converters.js';
import { argsToBools, convertTimelinesArgsId, limitToInt } from './timeline.js';
import { MastoConverters, convertRelationship } from '../converters.js';
import { argsToBools, limitToInt } from './timeline.js';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
import { NoteEditRepository, NotesRepository, UsersRepository } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import type { Config } from '@/config.js';
const relationshipModel = {
id: '',
@ -24,18 +27,25 @@ export class ApiAccountMastodon {
private request: FastifyRequest;
private client: MegalodonInterface;
private BASE_URL: string;
private mastoconverter: MastoConverters;
constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) {
constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string,
config: Config,
usersrepo: UsersRepository,
notesrepo: NotesRepository,
noteeditrepo: NoteEditRepository,
userentity: UserEntityService,
) {
this.request = request;
this.client = client;
this.BASE_URL = BASE_URL;
this.mastoconverter = new MastoConverters(config, usersrepo, notesrepo, noteeditrepo, userentity);
}
public async verifyCredentials() {
try {
const data = await this.client.verifyAccountCredentials();
const acct = data.data;
acct.id = convertId(acct.id, IdType.MastodonId);
acct.display_name = acct.display_name || acct.username;
acct.url = `${this.BASE_URL}/@${acct.url}`;
acct.note = acct.note || '';
@ -61,7 +71,7 @@ export class ApiAccountMastodon {
public async lookup() {
try {
const data = await this.client.search((this.request.query as any).acct, { type: 'accounts' });
return convertAccount(data.data.accounts[0]);
return this.mastoconverter.convertAccount(data.data.accounts[0]);
} catch (e: any) {
/* console.error(e)
console.error(e.response.data); */
@ -79,7 +89,7 @@ export class ApiAccountMastodon {
const reqIds = [];
for (let i = 0; i < users.length; i++) {
reqIds.push(convertId(users[i], IdType.SharkeyId));
reqIds.push(users[i]);
}
const data = await this.client.getRelationships(reqIds);
@ -93,11 +103,8 @@ export class ApiAccountMastodon {
public async getStatuses() {
try {
const data = await this.client.getAccountStatuses(
convertId((this.request.params as any).id, IdType.SharkeyId),
convertTimelinesArgsId(argsToBools(limitToInt(this.request.query as any)))
);
return data.data.map((status) => convertStatus(status));
const data = await this.client.getAccountStatuses((this.request.params as any).id, argsToBools(limitToInt(this.request.query as any)));
return data.data.map((status) => this.mastoconverter.convertStatus(status));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -108,10 +115,10 @@ export class ApiAccountMastodon {
public async getFollowers() {
try {
const data = await this.client.getAccountFollowers(
convertId((this.request.params as any).id, IdType.SharkeyId),
convertTimelinesArgsId(limitToInt(this.request.query as any)),
(this.request.params as any).id,
limitToInt(this.request.query as any),
);
return data.data.map((account) => convertAccount(account));
return data.data.map((account) => this.mastoconverter.convertAccount(account));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -122,10 +129,10 @@ export class ApiAccountMastodon {
public async getFollowing() {
try {
const data = await this.client.getAccountFollowing(
convertId((this.request.params as any).id, IdType.SharkeyId),
convertTimelinesArgsId(limitToInt(this.request.query as any)),
(this.request.params as any).id,
limitToInt(this.request.query as any),
);
return data.data.map((account) => convertAccount(account));
return data.data.map((account) => this.mastoconverter.convertAccount(account));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -135,7 +142,7 @@ export class ApiAccountMastodon {
public async addFollow() {
try {
const data = await this.client.followAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.followAccount( (this.request.params as any).id );
const acct = convertRelationship(data.data);
acct.following = true;
return acct;
@ -148,7 +155,7 @@ export class ApiAccountMastodon {
public async rmFollow() {
try {
const data = await this.client.unfollowAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.unfollowAccount( (this.request.params as any).id );
const acct = convertRelationship(data.data);
acct.following = false;
return acct;
@ -161,7 +168,7 @@ export class ApiAccountMastodon {
public async addBlock() {
try {
const data = await this.client.blockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.blockAccount( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@ -172,7 +179,7 @@ export class ApiAccountMastodon {
public async rmBlock() {
try {
const data = await this.client.unblockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.unblockAccount( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@ -184,7 +191,7 @@ export class ApiAccountMastodon {
public async addMute() {
try {
const data = await this.client.muteAccount(
convertId((this.request.params as any).id, IdType.SharkeyId),
(this.request.params as any).id,
this.request.body as any,
);
return convertRelationship(data.data);
@ -197,7 +204,7 @@ export class ApiAccountMastodon {
public async rmMute() {
try {
const data = await this.client.unmuteAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.unmuteAccount( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@ -208,8 +215,8 @@ export class ApiAccountMastodon {
public async getBookmarks() {
try {
const data = await this.client.getBookmarks( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
return data.data.map((status) => convertStatus(status));
const data = await this.client.getBookmarks( limitToInt(this.request.query as any) );
return data.data.map((status) => this.mastoconverter.convertStatus(status));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -219,8 +226,8 @@ export class ApiAccountMastodon {
public async getFavourites() {
try {
const data = await this.client.getFavourites( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
return data.data.map((status) => convertStatus(status));
const data = await this.client.getFavourites( limitToInt(this.request.query as any) );
return data.data.map((status) => this.mastoconverter.convertStatus(status));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -230,8 +237,8 @@ export class ApiAccountMastodon {
public async getMutes() {
try {
const data = await this.client.getMutes( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
return data.data.map((account) => convertAccount(account));
const data = await this.client.getMutes( limitToInt(this.request.query as any) );
return data.data.map((account) => this.mastoconverter.convertAccount(account));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -241,8 +248,8 @@ export class ApiAccountMastodon {
public async getBlocks() {
try {
const data = await this.client.getBlocks( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
return data.data.map((account) => convertAccount(account));
const data = await this.client.getBlocks( limitToInt(this.request.query as any) );
return data.data.map((account) => this.mastoconverter.convertAccount(account));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -252,7 +259,7 @@ export class ApiAccountMastodon {
public async acceptFollow() {
try {
const data = await this.client.acceptFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.acceptFollowRequest( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@ -263,7 +270,7 @@ export class ApiAccountMastodon {
public async rejectFollow() {
try {
const data = await this.client.rejectFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.rejectFollowRequest( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);

View file

@ -1,4 +1,4 @@
import { IdConvertType as IdType, convertId, convertFilter } from '../converters.js';
import { convertFilter } from '../converters.js';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
@ -23,7 +23,7 @@ export class ApiFilterMastodon {
public async getFilter() {
try {
const data = await this.client.getFilter( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.getFilter( (this.request.params as any).id );
return convertFilter(data.data);
} catch (e: any) {
console.error(e);
@ -45,7 +45,7 @@ export class ApiFilterMastodon {
public async updateFilter() {
try {
const body: any = this.request.body;
const data = await this.client.updateFilter(convertId((this.request.params as any).id, IdType.SharkeyId), body.pharse, body.context);
const data = await this.client.updateFilter((this.request.params as any).id, body.pharse, body.context);
return convertFilter(data.data);
} catch (e: any) {
console.error(e);
@ -55,7 +55,7 @@ export class ApiFilterMastodon {
public async rmFilter() {
try {
const data = await this.client.deleteFilter( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.deleteFilter( (this.request.params as any).id );
return data.data;
} catch (e: any) {
console.error(e);

View file

@ -1,5 +1,4 @@
import { IdConvertType as IdType, convertId, convertNotification } from '../converters.js';
import { convertTimelinesArgsId } from './timeline.js';
import { convertNotification } from '../converters.js';
import type { MegalodonInterface, Entity } from 'megalodon';
import type { FastifyRequest } from 'fastify';
@ -19,7 +18,7 @@ export class ApiNotifyMastodon {
public async getNotifications() {
try {
const data = await this.client.getNotifications( convertTimelinesArgsId(toLimitToInt(this.request.query)) );
const data = await this.client.getNotifications( toLimitToInt(this.request.query) );
const notifs = data.data;
const processed = notifs.map((n: Entity.Notification) => {
const convertedn = convertNotification(n);
@ -39,7 +38,7 @@ export class ApiNotifyMastodon {
public async getNotification() {
try {
const data = await this.client.getNotification( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.getNotification( (this.request.params as any).id );
const notif = convertNotification(data.data);
if (notif.type !== 'follow' && notif.type !== 'follow_request' && notif.type === 'reaction') notif.type = 'favourite';
return notif;
@ -51,7 +50,7 @@ export class ApiNotifyMastodon {
public async rmNotification() {
try {
const data = await this.client.dismissNotification( convertId((this.request.params as any).id, IdType.SharkeyId) );
const data = await this.client.dismissNotification( (this.request.params as any).id );
return data.data;
} catch (e: any) {
console.error(e);

View file

@ -1,6 +1,6 @@
import { Converter } from 'megalodon';
import { convertAccount, convertStatus } from '../converters.js';
import { convertTimelinesArgsId, limitToInt } from './timeline.js';
import { limitToInt } from './timeline.js';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
@ -71,7 +71,7 @@ export class ApiSearchMastodon {
public async SearchV1() {
try {
const query: any = convertTimelinesArgsId(limitToInt(this.request.query as any));
const query: any = limitToInt(this.request.query as any);
const type = query.type || '';
const data = await this.client.search(query.q, { type: type, ...query });
return data.data;
@ -83,7 +83,7 @@ export class ApiSearchMastodon {
public async SearchV2() {
try {
const query: any = convertTimelinesArgsId(limitToInt(this.request.query as any));
const query: any = limitToInt(this.request.query as any);
const type = query.type;
const acct = !type || type === 'accounts' ? await this.client.search(query.q, { type: 'accounts', ...query }) : null;
const stat = !type || type === 'statuses' ? await this.client.search(query.q, { type: 'statuses', ...query }) : null;

View file

@ -1,8 +1,8 @@
import querystring from 'querystring';
import { emojiRegexAtStartToEnd } from '@/misc/emoji-regex.js';
import { convertId, IdConvertType as IdType, convertAccount, convertAttachment, convertPoll, convertStatusSource, MastoConverters } from '../converters.js';
import { convertAttachment, convertPoll, convertStatusSource, MastoConverters } from '../converters.js';
import { getClient } from '../MastodonApiServerService.js';
import { convertTimelinesArgsId, limitToInt } from './timeline.js';
import { limitToInt } from './timeline.js';
import type { Entity } from 'megalodon';
import type { FastifyInstance } from 'fastify';
import type { Config } from '@/config.js';
@ -29,7 +29,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.getStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -44,8 +44,8 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getStatusSource(convertId(_request.params.id, IdType.SharkeyId));
reply.send(convertStatusSource(data.data));
const data = await client.getStatusSource(_request.params.id);
reply.send(data.data);
} catch (e: any) {
console.error(e);
reply.code(_request.is404 ? 404 : 401).send(e.response.data);
@ -60,10 +60,7 @@ export class ApiStatusMastodon {
const client = getClient(BASE_URL, accessTokens);
const query: any = _request.query;
try {
const data = await client.getStatusContext(
convertId(_request.params.id, IdType.SharkeyId),
convertTimelinesArgsId(limitToInt(query)),
);
const data = await client.getStatusContext(_request.params.id, limitToInt(query));
data.data.ancestors = await Promise.all(data.data.ancestors.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status)));
data.data.descendants = await Promise.all(data.data.descendants.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status)));
reply.send(data.data);
@ -91,8 +88,8 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getStatusRebloggedBy(convertId(_request.params.id, IdType.SharkeyId));
reply.send(data.data.map((account: Entity.Account) => convertAccount(account)));
const data = await client.getStatusRebloggedBy(_request.params.id);
reply.send(data.data.map((account: Entity.Account) => this.mastoconverter.convertAccount(account)));
} catch (e: any) {
console.error(e);
reply.code(401).send(e.response.data);
@ -106,8 +103,8 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getStatusFavouritedBy(convertId(_request.params.id, IdType.SharkeyId));
reply.send(data.data.map((account: Entity.Account) => convertAccount(account)));
const data = await client.getStatusFavouritedBy(_request.params.id);
reply.send(data.data.map((account: Entity.Account) => this.mastoconverter.convertAccount(account)));
} catch (e: any) {
console.error(e);
reply.code(401).send(e.response.data);
@ -121,7 +118,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getMedia(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.getMedia(_request.params.id);
reply.send(convertAttachment(data.data));
} catch (e: any) {
console.error(e);
@ -136,7 +133,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getPoll(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.getPoll(_request.params.id);
reply.send(convertPoll(data.data));
} catch (e: any) {
console.error(e);
@ -152,7 +149,7 @@ export class ApiStatusMastodon {
const client = getClient(BASE_URL, accessTokens);
const body: any = _request.body;
try {
const data = await client.votePoll(convertId(_request.params.id, IdType.SharkeyId), body.choices);
const data = await client.votePoll(_request.params.id, body.choices);
reply.send(convertPoll(data.data));
} catch (e: any) {
console.error(e);
@ -168,8 +165,6 @@ export class ApiStatusMastodon {
const client = getClient(BASE_URL, accessTokens);
let body: any = _request.body;
try {
if (body.in_reply_to_id) body.in_reply_to_id = convertId(body.in_reply_to_id, IdType.SharkeyId);
if (body.quote_id) body.quote_id = convertId(body.quote_id, IdType.SharkeyId);
if (
(!body.poll && body['poll[options][]']) ||
(!body.media_ids && body['media_ids[]'])
@ -201,9 +196,6 @@ export class ApiStatusMastodon {
}
if (!body.media_ids) body.media_ids = undefined;
if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
if (body.media_ids) {
body.media_ids = (body.media_ids as string[]).map((p) => convertId(p, IdType.SharkeyId));
}
const { sensitive } = body;
body.sensitive = typeof sensitive === 'string' ? sensitive === 'true' : sensitive;
@ -241,10 +233,7 @@ export class ApiStatusMastodon {
try {
if (!body.media_ids) body.media_ids = undefined;
if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
if (body.media_ids) {
body.media_ids = (body.media_ids as string[]).map((p) => convertId(p, IdType.SharkeyId));
}
const data = await client.editStatus(convertId(_request.params.id, IdType.SharkeyId), body);
const data = await client.editStatus(_request.params.id, body);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -259,10 +248,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = (await client.createEmojiReaction(
convertId(_request.params.id, IdType.SharkeyId),
'❤',
)) as any;
const data = (await client.createEmojiReaction(_request.params.id, '❤')) as any;
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -277,10 +263,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.deleteEmojiReaction(
convertId(_request.params.id, IdType.SharkeyId),
'❤',
);
const data = await client.deleteEmojiReaction(_request.params.id, '❤');
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -295,7 +278,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.reblogStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.reblogStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -310,7 +293,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.unreblogStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.unreblogStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -325,7 +308,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.bookmarkStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.bookmarkStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -340,7 +323,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.unbookmarkStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.unbookmarkStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -355,7 +338,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.pinStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.pinStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -370,7 +353,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.unpinStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.unpinStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -385,7 +368,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.createEmojiReaction(convertId(_request.params.id, IdType.SharkeyId), _request.params.name);
const data = await client.createEmojiReaction(_request.params.id, _request.params.name);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -400,7 +383,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.deleteEmojiReaction(convertId(_request.params.id, IdType.SharkeyId), _request.params.name);
const data = await client.deleteEmojiReaction(_request.params.id, _request.params.name);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@ -415,7 +398,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.deleteStatus(convertId(_request.params.id, IdType.SharkeyId));
const data = await client.deleteStatus(_request.params.id);
reply.send(data.data);
} catch (e: any) {
console.error(e);

View file

@ -1,5 +1,5 @@
import { ParsedUrlQuery } from 'querystring';
import { convertId, IdConvertType as IdType, convertAccount, convertConversation, convertList, MastoConverters } from '../converters.js';
import { convertConversation, convertList, MastoConverters } from '../converters.js';
import { getClient } from '../MastodonApiServerService.js';
import type { Entity } from 'megalodon';
import type { FastifyInstance } from 'fastify';
@ -32,13 +32,6 @@ export function argsToBools(q: ParsedUrlQuery) {
return q;
}
export function convertTimelinesArgsId(q: ParsedUrlQuery) {
if (typeof q.min_id === 'string') q.min_id = convertId(q.min_id, IdType.SharkeyId);
if (typeof q.max_id === 'string') q.max_id = convertId(q.max_id, IdType.SharkeyId);
if (typeof q.since_id === 'string') q.since_id = convertId(q.since_id, IdType.SharkeyId);
return q;
}
export class ApiTimelineMastodon {
private fastify: FastifyInstance;
private mastoconverter: MastoConverters;
@ -56,8 +49,8 @@ export class ApiTimelineMastodon {
try {
const query: any = _request.query;
const data = query.local === 'true'
? await client.getLocalTimeline(convertTimelinesArgsId(argsToBools(limitToInt(query))))
: await client.getPublicTimeline(convertTimelinesArgsId(argsToBools(limitToInt(query))));
? await client.getLocalTimeline(argsToBools(limitToInt(query)))
: await client.getPublicTimeline(argsToBools(limitToInt(query)));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@ -74,7 +67,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
try {
const query: any = _request.query;
const data = await client.getHomeTimeline(convertTimelinesArgsId(limitToInt(query)));
const data = await client.getHomeTimeline(limitToInt(query));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@ -92,7 +85,7 @@ export class ApiTimelineMastodon {
try {
const query: any = _request.query;
const params: any = _request.params;
const data = await client.getTagTimeline(params.hashtag, convertTimelinesArgsId(limitToInt(query)));
const data = await client.getTagTimeline(params.hashtag, limitToInt(query));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@ -110,7 +103,7 @@ export class ApiTimelineMastodon {
try {
const query: any = _request.query;
const params: any = _request.params;
const data = await client.getListTimeline(convertId(params.id, IdType.SharkeyId), convertTimelinesArgsId(limitToInt(query)));
const data = await client.getListTimeline(params.id, limitToInt(query));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@ -127,7 +120,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
try {
const query: any = _request.query;
const data = await client.getConversationTimeline(convertTimelinesArgsId(limitToInt(query)));
const data = await client.getConversationTimeline(limitToInt(query));
reply.send(data.data.map((conversation: Entity.Conversation) => convertConversation(conversation)));
} catch (e: any) {
console.error(e);
@ -144,7 +137,7 @@ export class ApiTimelineMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const data = await client.getList(convertId(params.id, IdType.SharkeyId));
const data = await client.getList(params.id);
reply.send(convertList(data.data));
} catch (e: any) {
console.error(e);
@ -178,11 +171,8 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const query: any = _request.query;
const data = await client.getAccountsInList(
convertId(params.id, IdType.SharkeyId),
convertTimelinesArgsId(query),
);
reply.send(data.data.map((account: Entity.Account) => convertAccount(account)));
const data = await client.getAccountsInList(params.id, query);
reply.send(data.data.map((account: Entity.Account) => this.mastoconverter.convertAccount(account)));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@ -199,10 +189,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const query: any = _request.query;
const data = await client.addAccountsToList(
convertId(params.id, IdType.SharkeyId),
(query.accounts_id as string[]).map((id) => convertId(id, IdType.SharkeyId)),
);
const data = await client.addAccountsToList(params.id, query.accounts_id);
reply.send(data.data);
} catch (e: any) {
console.error(e);
@ -220,10 +207,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const query: any = _request.query;
const data = await client.deleteAccountsFromList(
convertId(params.id, IdType.SharkeyId),
(query.accounts_id as string[]).map((id) => convertId(id, IdType.SharkeyId)),
);
const data = await client.deleteAccountsFromList(params.id, query.accounts_id);
reply.send(data.data);
} catch (e: any) {
console.error(e);
@ -258,7 +242,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const body: any = _request.body;
const params: any = _request.params;
const data = await client.updateList(convertId(params.id, IdType.SharkeyId), body.title);
const data = await client.updateList(params.id, body.title);
reply.send(convertList(data.data));
} catch (e: any) {
console.error(e);
@ -275,7 +259,7 @@ export class ApiTimelineMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const data = await client.deleteList(convertId(params.id, IdType.SharkeyId));
const data = await client.deleteList(params.id);
reply.send(data.data);
} catch (e: any) {
console.error(e);

View file

@ -64,15 +64,15 @@
"socks-proxy-agent": "^8.0.2",
"typescript": "5.1.6",
"uuid": "^9.0.1",
"ws": "8.14.2"
},
"devDependencies": {
"ws": "8.14.2",
"@types/core-js": "^2.5.6",
"@types/form-data": "^2.5.0",
"@types/jest": "^29.5.5",
"@types/object-assign-deep": "^0.4.1",
"@types/parse-link-header": "^2.0.1",
"@types/uuid": "^9.0.4",
"@types/uuid": "^9.0.4"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"eslint": "^8.49.0",

View file

@ -5,15 +5,16 @@
namespace Entity {
export type Account = {
id: string
fqn?: string
username: string
acct: string
display_name: string
locked: boolean
discoverable?: boolean
group: boolean | null
noindex: boolean | null
suspended: boolean | null
limited: boolean | null
group?: boolean | null
noindex?: boolean | null
suspended?: boolean | null
limited?: boolean | null
created_at: string
followers_count: number
following_count: number

View file

@ -17,7 +17,7 @@ namespace Entity {
in_reply_to_account_id: string | null
reblog: Status | null
content: string
plain_content: string | null
plain_content?: string | null
created_at: string
emojis: Emoji[]
replies_count: number

View file

@ -2017,7 +2017,7 @@ export default class Misskey implements MegalodonInterface {
}
if (options.exclude_type) {
params = Object.assign(params, {
excludeType: options.exclude_type.map(e => MisskeyAPI.Converter.encodeNotificationType(e))
excludeTypes: options.exclude_type.map(e => MisskeyAPI.Converter.encodeNotificationType(e))
})
}
}

View file

@ -78,8 +78,10 @@ namespace MisskeyAPI {
acct = `${u.username}@${u.host}`;
acctUrl = `https://${u.host}/@${u.username}`;
}
const fqn = `${u.username}@${u.host ?? host}`;
return {
id: u.id,
fqn: fqn,
username: u.username,
acct: acct,
display_name: u.name ? u.name : '',
@ -465,8 +467,8 @@ namespace MisskeyAPI {
export const stats = (s: Entity.Stats): MegalodonEntity.Stats => {
return {
user_count: s.usersCount,
status_count: s.notesCount,
user_count: s.originalUsersCount,
status_count: s.originalNotesCount,
domain_count: s.instances
}
}