From db6dc1b52e53dc086440969ed9f6363aceecbfcf Mon Sep 17 00:00:00 2001 From: Mar0xy Date: Sun, 24 Sep 2023 17:36:13 +0200 Subject: [PATCH] chore: lint and update package name --- package.json | 4 +- .../api/mastodon/MastodonApiServerService.ts | 1397 ++++++++--------- .../src/server/api/mastodon/converters.ts | 85 +- .../src/server/api/mastodon/endpoints.ts | 30 +- .../server/api/mastodon/endpoints/account.ts | 360 ++--- .../src/server/api/mastodon/endpoints/auth.ts | 62 +- .../server/api/mastodon/endpoints/filter.ts | 62 +- .../src/server/api/mastodon/endpoints/meta.ts | 8 +- .../api/mastodon/endpoints/notifications.ts | 74 +- .../server/api/mastodon/endpoints/search.ts | 131 +- .../server/api/mastodon/endpoints/status.ts | 759 +++++---- .../server/api/mastodon/endpoints/timeline.ts | 347 ++-- 12 files changed, 1636 insertions(+), 1683 deletions(-) diff --git a/package.json b/package.json index 8b5f57494..6389287c4 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "misskey", + "name": "sharkey", "version": "2023.9.0-beta.10", "codename": "nasubi", "repository": { "type": "git", - "url": "https://github.com/misskey-dev/misskey.git" + "url": "https://github.com/transfem-org/sharkey.git" }, "packageManager": "pnpm@8.7.6", "workspaces": [ diff --git a/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts b/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts index da5ab2831..883d25aaa 100644 --- a/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts +++ b/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts @@ -1,19 +1,16 @@ -import { fileURLToPath } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; +import megalodon, { Entity, MegalodonInterface } from 'megalodon'; +import { IsNull } from 'typeorm'; +import multer from 'fastify-multer'; import type { UsersRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; -import megalodon, { Entity, MegalodonInterface } from 'megalodon'; -import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; -import { convertId, IdConvertType as IdType, convertAccount, convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList } from './converters.js'; -import { IsNull } from 'typeorm'; import type { Config } from '@/config.js'; -import { getInstance } from './endpoints/meta.js'; import { MetaService } from '@/core/MetaService.js'; -import multer from 'fastify-multer'; -import { apiAuthMastodon, apiAccountMastodon, apiFilterMastodon, apiNotifyMastodon, apiSearchMastodon, apiTimelineMastodon, apiStatusMastodon } from './endpoints.js'; - -const staticAssets = fileURLToPath(new URL('../../../../assets/', import.meta.url)); +import { convertId, IdConvertType as IdType, 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'; export function getClient(BASE_URL: string, authorization: string | undefined): MegalodonInterface { const accessTokenArr = authorization?.split(' ') ?? [null]; @@ -35,752 +32,752 @@ export class MastodonApiServerService { @bindThis public createServer(fastify: FastifyInstance, _options: FastifyPluginOptions, done: (err?: Error) => void) { - const upload = multer({ - storage: multer.diskStorage({}), - limits: { - fileSize: this.config.maxFileSize || 262144000, - files: 1, - }, - }); + const upload = multer({ + storage: multer.diskStorage({}), + limits: { + fileSize: this.config.maxFileSize || 262144000, + files: 1, + }, + }); - fastify.register(multer.contentParser); + fastify.register(multer.contentParser); - fastify.get('/v1/custom_emojis', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getInstanceCustomEmojis(); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/custom_emojis', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getInstanceCustomEmojis(); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/instance', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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 data = await client.getInstance(); - const admin = await this.usersRepository.findOne({ - where: { - host: IsNull(), - isRoot: true, - isDeleted: false, - isSuspended: false, - }, - order: { id: 'ASC' }, - }); - const contact = admin == null ? null : convertAccount((await client.getAccount(admin.id)).data); - reply.send(await getInstance(data.data, contact, this.config, await this.metaService.fetch())); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/instance', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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 data = await client.getInstance(); + const admin = await this.usersRepository.findOne({ + where: { + host: IsNull(), + isRoot: true, + isDeleted: false, + isSuspended: false, + }, + order: { id: 'ASC' }, + }); + const contact = admin == null ? null : convertAccount((await client.getAccount(admin.id)).data); + reply.send(await getInstance(data.data, contact, this.config, await this.metaService.fetch())); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/announcements', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getInstanceAnnouncements(); - reply.send(data.data.map((announcement) => convertAnnouncement(announcement))); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/announcements', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getInstanceAnnouncements(); + reply.send(data.data.map((announcement) => convertAnnouncement(announcement))); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Body: { id: string } }>('/v1/announcements/:id/dismiss', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.dismissInstanceAnnouncement( - convertId(_request.body['id'], IdType.SharkeyId) - ); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }, - ); + fastify.post<{ Body: { id: string } }>('/v1/announcements/:id/dismiss', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.dismissInstanceAnnouncement( + convertId(_request.body['id'], IdType.SharkeyId), + ); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }, + ); - fastify.post('/v1/media', { preHandler: upload.single('file') }, async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const multipartData = await _request.file; - if (!multipartData) { - reply.code(401).send({ error: 'No image' }); - return; - } - const data = await client.uploadMedia(multipartData); - reply.send(convertAttachment(data.data as Entity.Attachment)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.post('/v1/media', { preHandler: upload.single('file') }, async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const multipartData = await _request.file; + if (!multipartData) { + reply.code(401).send({ error: 'No image' }); + return; + } + const data = await client.uploadMedia(multipartData); + reply.send(convertAttachment(data.data as Entity.Attachment)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.post('/v2/media', { preHandler: upload.single('file') }, async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const multipartData = await _request.file; - if (!multipartData) { - reply.code(401).send({ error: 'No image' }); - return; - } - const data = await client.uploadMedia(multipartData, _request.body!); - reply.send(convertAttachment(data.data as Entity.Attachment)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.post('/v2/media', { preHandler: upload.single('file') }, async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const multipartData = await _request.file; + if (!multipartData) { + reply.code(401).send({ error: 'No image' }); + return; + } + const data = await client.uploadMedia(multipartData, _request.body!); + reply.send(convertAttachment(data.data as Entity.Attachment)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/filters', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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 data = await client.getFilters(); - reply.send(data.data.map((filter) => convertFilter(filter))); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/filters', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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 data = await client.getFilters(); + reply.send(data.data.map((filter) => convertFilter(filter))); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/trends', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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 data = await client.getInstanceTrends(); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/trends', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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 data = await client.getInstanceTrends(); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.post('/v1/apps', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const client = getClient(BASE_URL, ''); // we are using this here, because in private mode some info isnt - // displayed without being logged in - try { - const data = await apiAuthMastodon(_request, client); - reply.send(data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.post('/v1/apps', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const client = getClient(BASE_URL, ''); // we are using this here, because in private mode some info isnt + // displayed without being logged in + try { + const data = await ApiAuthMastodon(_request, client); + reply.send(data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/preferences', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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 data = await client.getPreferences(); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/preferences', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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 data = await client.getPreferences(); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - //#region Accounts - fastify.get('/v1/accounts/verify_credentials', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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); - reply.send(await account.verifyCredentials()); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + //#region Accounts + fastify.get('/v1/accounts/verify_credentials', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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); + reply.send(await account.verifyCredentials()); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.patch('/v1/accounts/update_credentials', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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); - reply.send(await account.updateCredentials()); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.patch('/v1/accounts/update_credentials', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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); + reply.send(await account.updateCredentials()); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/accounts/lookup', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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); - reply.send(await account.lookup()); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/accounts/lookup', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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); + reply.send(await account.lookup()); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/accounts/relationships', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt - // displayed without being logged in - let users; - try { - let ids = _request.query ? (_request.query as any)['id[]'] : null; - if (typeof ids === 'string') { - ids = [ids]; - } - users = ids; - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getRelationships(users)); - } catch (e: any) { - console.error(e); - let data = e.response.data; - data.users = users; - console.error(data); - reply.code(401).send(data); - } - }); + fastify.get('/v1/accounts/relationships', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt + // displayed without being logged in + let users; + try { + let ids = _request.query ? (_request.query as any)['id[]'] : null; + if (typeof ids === 'string') { + ids = [ids]; + } + users = ids; + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getRelationships(users)); + } catch (e: any) { + console.error(e); + const data = e.response.data; + data.users = users; + console.error(data); + reply.code(401).send(data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/accounts/:id', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const sharkId = convertId(_request.params.id, IdType.SharkeyId); - const data = await client.getAccount(sharkId); - reply.send(convertAccount(data.data)); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/accounts/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const sharkId = convertId(_request.params.id, IdType.SharkeyId); + const data = await client.getAccount(sharkId); + reply.send(convertAccount(data.data)); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/statuses', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getStatuses()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/statuses', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getStatuses()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/featured_tags', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getFeaturedTags(); - reply.send(data.data.map((tag) => convertFeaturedTag(tag))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/featured_tags', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getFeaturedTags(); + reply.send(data.data.map((tag) => convertFeaturedTag(tag))); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/followers', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getFollowers()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/followers', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getFollowers()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/following', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getFollowing()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/following', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getFollowing()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/lists', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getAccountLists(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(data.data.map((list) => convertList(list))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/accounts/:id/lists', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getAccountLists(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(data.data.map((list) => convertList(list))); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/follow', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.addFollow()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/follow', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.addFollow()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/unfollow', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.rmFollow()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/unfollow', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.rmFollow()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/block', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.addBlock()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/block', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.addBlock()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/unblock', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.rmBlock()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/unblock', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.rmBlock()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.addMute()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.addMute()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/unmute', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.rmMute()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/accounts/:id/unmute', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.rmMute()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/followed_tags', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getFollowedTags(); - reply.send(data.data); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/followed_tags', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getFollowedTags(); + reply.send(data.data); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/bookmarks', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getBookmarks()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/bookmarks', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getBookmarks()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/favourites', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getFavourites()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/favourites', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getFavourites()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/mutes', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getMutes()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/mutes', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getMutes()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/blocks', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.getBlocks()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/blocks', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.getBlocks()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/follow_requests', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getFollowRequests( ((_request.query as any) || { limit: 20 }).limit ); - reply.send(data.data.map((account) => convertAccount(account as Entity.Account))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/follow_requests', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getFollowRequests( ((_request.query as any) || { limit: 20 }).limit ); + reply.send(data.data.map((account) => convertAccount(account as Entity.Account))); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/follow_requests/:id/authorize', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.acceptFollow()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/follow_requests/:id/authorize', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.acceptFollow()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/follow_requests/:id/reject', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const account = new apiAccountMastodon(_request, client, BASE_URL); - reply.send(await account.rejectFollow()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); - //#endregion + fastify.post<{ Params: { id: string } }>('/v1/follow_requests/:id/reject', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const account = new ApiAccountMastodon(_request, client, BASE_URL); + reply.send(await account.rejectFollow()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); + //#endregion - //#region Search - fastify.get('/v1/search', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const search = new apiSearchMastodon(_request, client, BASE_URL); - reply.send(await search.SearchV1()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + //#region Search + fastify.get('/v1/search', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const search = new ApiSearchMastodon(_request, client, BASE_URL); + reply.send(await search.SearchV1()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v2/search', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const search = new apiSearchMastodon(_request, client, BASE_URL); - reply.send(await search.SearchV2()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v2/search', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const search = new ApiSearchMastodon(_request, client, BASE_URL); + reply.send(await search.SearchV2()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v1/trends/statuses', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const search = new apiSearchMastodon(_request, client, BASE_URL); - reply.send(await search.getStatusTrends()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get('/v1/trends/statuses', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const search = new ApiSearchMastodon(_request, client, BASE_URL); + reply.send(await search.getStatusTrends()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get('/v2/suggestions', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const search = new apiSearchMastodon(_request, client, BASE_URL); - reply.send(await search.getSuggestions()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); - //#endregion + fastify.get('/v2/suggestions', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const search = new ApiSearchMastodon(_request, client, BASE_URL); + reply.send(await search.getSuggestions()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); + //#endregion - //#region Notifications - fastify.get('/v1/notifications', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const notify = new apiNotifyMastodon(_request, client); - reply.send(await notify.getNotifications()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + //#region Notifications + fastify.get('/v1/notifications', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const notify = new ApiNotifyMastodon(_request, client); + reply.send(await notify.getNotifications()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.get<{ Params: { id: string } }>('/v1/notification/:id', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const notify = new apiNotifyMastodon(_request, client); - reply.send(await notify.getNotification()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.get<{ Params: { id: string } }>('/v1/notification/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const notify = new ApiNotifyMastodon(_request, client); + reply.send(await notify.getNotification()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/notification/:id/dismiss', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const notify = new apiNotifyMastodon(_request, client); - reply.send(await notify.rmNotification()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/notification/:id/dismiss', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const notify = new ApiNotifyMastodon(_request, client); + reply.send(await notify.rmNotification()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post('/v1/notifications/clear', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const notify = new apiNotifyMastodon(_request, client); - reply.send(await notify.rmNotifications()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); - //#endregion + fastify.post('/v1/notifications/clear', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const notify = new ApiNotifyMastodon(_request, client); + reply.send(await notify.rmNotifications()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); + //#endregion - //#region Filters - fastify.get<{ Params: { id: string } }>('/v1/filters/:id', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const filter = new apiFilterMastodon(_request, client); - !_request.params.id ? reply.send(await filter.getFilters()) : reply.send(await filter.getFilter()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + //#region Filters + fastify.get<{ Params: { id: string } }>('/v1/filters/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const filter = new ApiFilterMastodon(_request, client); + !_request.params.id ? reply.send(await filter.getFilters()) : reply.send(await filter.getFilter()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post('/v1/filters', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const filter = new apiFilterMastodon(_request, client); - reply.send(await filter.createFilter()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post('/v1/filters', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const filter = new ApiFilterMastodon(_request, client); + reply.send(await filter.createFilter()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.post<{ Params: { id: string } }>('/v1/filters/:id', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const filter = new apiFilterMastodon(_request, client); - reply.send(await filter.updateFilter()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + fastify.post<{ Params: { id: string } }>('/v1/filters/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const filter = new ApiFilterMastodon(_request, client); + reply.send(await filter.updateFilter()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); - fastify.delete<{ Params: { id: string } }>('/v1/filters/:id', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const filter = new apiFilterMastodon(_request, client); - reply.send(await filter.rmFilter()); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); - //#endregion + fastify.delete<{ Params: { id: string } }>('/v1/filters/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const filter = new ApiFilterMastodon(_request, client); + reply.send(await filter.rmFilter()); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); + //#endregion - //#region Timelines - const TLEndpoint = new apiTimelineMastodon(fastify); + //#region Timelines + const TLEndpoint = new ApiTimelineMastodon(fastify); - // GET Endpoints - TLEndpoint.getTL(); - TLEndpoint.getHomeTl(); - TLEndpoint.getListTL(); - TLEndpoint.getTagTl(); - TLEndpoint.getConversations(); - TLEndpoint.getList(); - TLEndpoint.getLists(); - TLEndpoint.getListAccounts(); + // GET Endpoints + TLEndpoint.getTL(); + TLEndpoint.getHomeTl(); + TLEndpoint.getListTL(); + TLEndpoint.getTagTl(); + TLEndpoint.getConversations(); + TLEndpoint.getList(); + TLEndpoint.getLists(); + TLEndpoint.getListAccounts(); - // POST Endpoints - TLEndpoint.createList(); - TLEndpoint.addListAccount(); + // POST Endpoints + TLEndpoint.createList(); + TLEndpoint.addListAccount(); - // PUT Endpoint - TLEndpoint.updateList(); + // PUT Endpoint + TLEndpoint.updateList(); - // DELETE Endpoints - TLEndpoint.deleteList(); - TLEndpoint.rmListAccount(); - //#endregion + // DELETE Endpoints + TLEndpoint.deleteList(); + TLEndpoint.rmListAccount(); + //#endregion - //#region Status - const NoteEndpoint = new apiStatusMastodon(fastify); + //#region Status + const NoteEndpoint = new ApiStatusMastodon(fastify); - // GET Endpoints - NoteEndpoint.getStatus(); - NoteEndpoint.getContext(); - NoteEndpoint.getHistory(); - NoteEndpoint.getReblogged(); - NoteEndpoint.getFavourites(); - NoteEndpoint.getMedia(); - NoteEndpoint.getPoll(); + // GET Endpoints + NoteEndpoint.getStatus(); + NoteEndpoint.getContext(); + NoteEndpoint.getHistory(); + NoteEndpoint.getReblogged(); + NoteEndpoint.getFavourites(); + NoteEndpoint.getMedia(); + NoteEndpoint.getPoll(); - //POST Endpoints - NoteEndpoint.postStatus(); - NoteEndpoint.addFavourite(); - NoteEndpoint.rmFavourite(); - NoteEndpoint.reblogStatus(); - NoteEndpoint.unreblogStatus(); - NoteEndpoint.bookmarkStatus(); - NoteEndpoint.unbookmarkStatus(); - NoteEndpoint.pinStatus(); - NoteEndpoint.unpinStatus(); - NoteEndpoint.reactStatus(); - NoteEndpoint.unreactStatus(); - NoteEndpoint.votePoll(); + //POST Endpoints + NoteEndpoint.postStatus(); + NoteEndpoint.addFavourite(); + NoteEndpoint.rmFavourite(); + NoteEndpoint.reblogStatus(); + NoteEndpoint.unreblogStatus(); + NoteEndpoint.bookmarkStatus(); + NoteEndpoint.unbookmarkStatus(); + NoteEndpoint.pinStatus(); + NoteEndpoint.unpinStatus(); + NoteEndpoint.reactStatus(); + NoteEndpoint.unreactStatus(); + NoteEndpoint.votePoll(); - // PUT Endpoint - NoteEndpoint.updateMedia(); + // PUT Endpoint + NoteEndpoint.updateMedia(); - // DELETE Endpoint - NoteEndpoint.deleteStatus(); - //#endregion + // DELETE Endpoint + NoteEndpoint.deleteStatus(); + //#endregion done(); } -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/converters.ts b/packages/backend/src/server/api/mastodon/converters.ts index 5d77a3e3f..4621a50ff 100644 --- a/packages/backend/src/server/api/mastodon/converters.ts +++ b/packages/backend/src/server/api/mastodon/converters.ts @@ -1,6 +1,6 @@ import { Entity } from 'megalodon'; -const CHAR_COLLECTION: string = '0123456789abcdefghijklmnopqrstuvwxyz'; +const CHAR_COLLECTION = '0123456789abcdefghijklmnopqrstuvwxyz'; export enum IdConvertType { MastodonId, @@ -8,48 +8,50 @@ export enum IdConvertType { } export function convertId(in_id: string, id_convert_type: IdConvertType): string { - switch (id_convert_type) { - case IdConvertType.MastodonId: - let out: bigint = 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(); + 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 = BigInt(in_id); - let outStr = ''; - while (input > BigInt(0)) { - const remainder = Number(input % BigInt(36)); - outStr = charFromNum(remainder) + outStr; - input /= BigInt(36); - } - let ReversedoutStr = outStr.split('').reduce((acc, char) => char + acc, ''); - return ReversedoutStr; + 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'); - } + default: + throw new Error('Invalid ID conversion type'); + } } function numFromChar(character: string): number { - for (let i = 0; i < CHAR_COLLECTION.length; i++) { - if (CHAR_COLLECTION.charAt(i) === character) { - return i; - } - } + for (let i = 0; i < CHAR_COLLECTION.length; i++) { + if (CHAR_COLLECTION.charAt(i) === character) { + return i; + } + } - throw new Error('Invalid character in parsed base36 id'); + 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'); - } + if (number >= 0 && number < CHAR_COLLECTION.length) { + return CHAR_COLLECTION.charAt(number); + } else { + throw new Error('Invalid number for base-36 encoding'); + } } function simpleConvert(data: any) { @@ -81,8 +83,7 @@ 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); + if (notification.status) notification.status = convertStatus(notification.status); return notification; } @@ -102,13 +103,11 @@ 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); + 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), ); diff --git a/packages/backend/src/server/api/mastodon/endpoints.ts b/packages/backend/src/server/api/mastodon/endpoints.ts index 92cf6fe3d..5a7582389 100644 --- a/packages/backend/src/server/api/mastodon/endpoints.ts +++ b/packages/backend/src/server/api/mastodon/endpoints.ts @@ -1,17 +1,17 @@ -import { apiAuthMastodon } from './endpoints/auth.js'; -import { apiAccountMastodon } from './endpoints/account.js'; -import { apiSearchMastodon } from './endpoints/search.js'; -import { apiNotifyMastodon } from './endpoints/notifications.js'; -import { apiFilterMastodon } from './endpoints/filter.js'; -import { apiTimelineMastodon } from './endpoints/timeline.js'; -import { apiStatusMastodon } from './endpoints/status.js'; +import { ApiAuthMastodon } from './endpoints/auth.js'; +import { ApiAccountMastodon } from './endpoints/account.js'; +import { ApiSearchMastodon } from './endpoints/search.js'; +import { ApiNotifyMastodon } from './endpoints/notifications.js'; +import { ApiFilterMastodon } from './endpoints/filter.js'; +import { ApiTimelineMastodon } from './endpoints/timeline.js'; +import { ApiStatusMastodon } from './endpoints/status.js'; export { - apiAccountMastodon, - apiAuthMastodon, - apiSearchMastodon, - apiNotifyMastodon, - apiFilterMastodon, - apiTimelineMastodon, - apiStatusMastodon -} + ApiAccountMastodon, + ApiAuthMastodon, + ApiSearchMastodon, + ApiNotifyMastodon, + ApiFilterMastodon, + ApiTimelineMastodon, + ApiStatusMastodon, +}; diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 21e1fa9fc..23c96281f 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -1,7 +1,7 @@ +import { convertId, IdConvertType as IdType, convertAccount, convertRelationship, convertStatus } from '../converters.js'; +import { argsToBools, convertTimelinesArgsId, limitToInt } from './timeline.js'; import type { MegalodonInterface } from 'megalodon'; import type { FastifyRequest } from 'fastify'; -import { argsToBools, convertTimelinesArgsId, limitToInt } from './timeline.js'; -import { convertId, IdConvertType as IdType, convertAccount, convertRelationship, convertStatus } from '../converters.js'; const relationshipModel = { id: '', @@ -20,21 +20,21 @@ const relationshipModel = { note: '', }; -export class apiAccountMastodon { - private request: FastifyRequest; - private client: MegalodonInterface; - private BASE_URL: string; +export class ApiAccountMastodon { + private request: FastifyRequest; + private client: MegalodonInterface; + private BASE_URL: string; - constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) { - this.request = request; - this.client = client; - this.BASE_URL = BASE_URL; - } + constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) { + this.request = request; + this.client = client; + this.BASE_URL = BASE_URL; + } - public async verifyCredentials() { - try { + public async verifyCredentials() { + try { const data = await this.client.verifyAccountCredentials(); - let acct = data.data; + 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}`; @@ -56,230 +56,230 @@ export class apiAccountMastodon { console.error(e.response.data); return e.response.data; } - } + } - public async updateCredentials() { - try { - const data = await this.client.updateCredentials(this.request.body as any); - return convertAccount(data.data); - } catch (e: any) { - console.error(e); + public async updateCredentials() { + try { + const data = await this.client.updateCredentials(this.request.body as any); + return convertAccount(data.data); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async lookup() { - try { - const data = await this.client.search((this.request.query as any).acct, { type: 'accounts' }); - return convertAccount(data.data.accounts[0]); - } catch (e: any) { - console.error(e); + public async lookup() { + try { + const data = await this.client.search((this.request.query as any).acct, { type: 'accounts' }); + return convertAccount(data.data.accounts[0]); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async getRelationships(users: [string]) { - try { - relationshipModel.id = users?.toString() || '1'; + public async getRelationships(users: [string]) { + try { + relationshipModel.id = users.toString() || '1'; - if (!users) { + if (!(users.length > 0)) { return [relationshipModel]; } - let reqIds = []; + const reqIds = []; for (let i = 0; i < users.length; i++) { reqIds.push(convertId(users[i], IdType.SharkeyId)); } const data = await this.client.getRelationships(reqIds); return data.data.map((relationship) => convertRelationship(relationship)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - 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))) - ); + 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)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - 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)) - ); + 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)), + ); return data.data.map((account) => convertAccount(account)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - 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)) - ); + 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)), + ); return data.data.map((account) => convertAccount(account)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async addFollow() { - try { - const data = await this.client.followAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); - let acct = convertRelationship(data.data); - acct.following = true; + public async addFollow() { + try { + const data = await this.client.followAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); + const acct = convertRelationship(data.data); + acct.following = true; return acct; - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async rmFollow() { - try { - const data = await this.client.unfollowAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); - let acct = convertRelationship(data.data); - acct.following = false; + public async rmFollow() { + try { + const data = await this.client.unfollowAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); + const acct = convertRelationship(data.data); + acct.following = false; return acct; - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async addBlock() { - try { - const data = await this.client.blockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); + public async addBlock() { + try { + const data = await this.client.blockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); return convertRelationship(data.data); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async rmBlock() { - try { - const data = await this.client.unblockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); + public async rmBlock() { + try { + const data = await this.client.unblockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); return convertRelationship(data.data); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async addMute() { - try { - const data = await this.client.muteAccount( - convertId((this.request.params as any).id, IdType.SharkeyId), - this.request.body as any - ); + public async addMute() { + try { + const data = await this.client.muteAccount( + convertId((this.request.params as any).id, IdType.SharkeyId), + this.request.body as any, + ); return convertRelationship(data.data); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async rmMute() { - try { - const data = await this.client.unmuteAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); + public async rmMute() { + try { + const data = await this.client.unmuteAccount( convertId((this.request.params as any).id, IdType.SharkeyId) ); return convertRelationship(data.data); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async getBookmarks() { - try { - const data = await this.client.getBookmarks( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); + public async getBookmarks() { + try { + const data = await this.client.getBookmarks( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); return data.data.map((status) => convertStatus(status)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async getFavourites() { - try { - const data = await this.client.getFavourites( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); + public async getFavourites() { + try { + const data = await this.client.getFavourites( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); return data.data.map((status) => convertStatus(status)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async getMutes() { - try { - const data = await this.client.getMutes( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); + public async getMutes() { + try { + const data = await this.client.getMutes( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); return data.data.map((account) => convertAccount(account)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async getBlocks() { - try { - const data = await this.client.getBlocks( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); + public async getBlocks() { + try { + const data = await this.client.getBlocks( convertTimelinesArgsId(limitToInt(this.request.query as any)) ); return data.data.map((account) => convertAccount(account)); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async acceptFollow() { - try { - const data = await this.client.acceptFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) ); + public async acceptFollow() { + try { + const data = await this.client.acceptFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) ); return convertRelationship(data.data); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } + return e.response.data; + } + } - public async rejectFollow() { - try { - const data = await this.client.rejectFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) ); + public async rejectFollow() { + try { + const data = await this.client.rejectFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) ); return convertRelationship(data.data); - } catch (e: any) { - console.error(e); + } catch (e: any) { + console.error(e); console.error(e.response.data); - return e.response.data; - } - } -} \ No newline at end of file + return e.response.data; + } + } +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/auth.ts b/packages/backend/src/server/api/mastodon/endpoints/auth.ts index 27664ae1f..3eb92644b 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/auth.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/auth.ts @@ -39,36 +39,36 @@ const writeScope = [ 'write:gallery-likes', ]; -export async function apiAuthMastodon(request: FastifyRequest, client: MegalodonInterface) { - const body: any = request.body || request.query; - try { - let scope = body.scopes; - if (typeof scope === 'string') scope = scope.split(' '); - const pushScope = new Set(); - for (const s of scope) { - if (s.match(/^read/)) for (const r of readScope) pushScope.add(r); - if (s.match(/^write/)) for (const r of writeScope) pushScope.add(r); - } - const scopeArr = Array.from(pushScope); - - const red = body.redirect_uris; - const appData = await client.registerApp(body.client_name, { - scopes: scopeArr, - redirect_uris: red, - website: body.website, - }); - const returns = { - id: Math.floor(Math.random() * 100).toString(), - name: appData.name, - website: body.website, - redirect_uri: red, - client_id: Buffer.from(appData.url || '').toString('base64'), - client_secret: appData.clientSecret, - }; - - return returns; - } catch (e: any) { - console.error(e); - return e.response.data; +export async function ApiAuthMastodon(request: FastifyRequest, client: MegalodonInterface) { + const body: any = request.body || request.query; + try { + let scope = body.scopes; + if (typeof scope === 'string') scope = scope.split(' '); + const pushScope = new Set(); + for (const s of scope) { + if (s.match(/^read/)) for (const r of readScope) pushScope.add(r); + if (s.match(/^write/)) for (const r of writeScope) pushScope.add(r); } + const scopeArr = Array.from(pushScope); + + const red = body.redirect_uris; + const appData = await client.registerApp(body.client_name, { + scopes: scopeArr, + redirect_uris: red, + website: body.website, + }); + const returns = { + id: Math.floor(Math.random() * 100).toString(), + name: appData.name, + website: body.website, + redirect_uri: red, + client_id: Buffer.from(appData.url || '').toString('base64'), + client_secret: appData.clientSecret, + }; + + return returns; + } catch (e: any) { + console.error(e); + return e.response.data; + } } diff --git a/packages/backend/src/server/api/mastodon/endpoints/filter.ts b/packages/backend/src/server/api/mastodon/endpoints/filter.ts index 175f2d519..e27bc956f 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/filter.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/filter.ts @@ -1,65 +1,65 @@ +import { IdConvertType as IdType, convertId, convertFilter } from '../converters.js'; import type { MegalodonInterface } from 'megalodon'; import type { FastifyRequest } from 'fastify'; -import { IdConvertType as IdType, convertId, convertFilter } from '../converters.js'; -export class apiFilterMastodon { - private request: FastifyRequest; - private client: MegalodonInterface; +export class ApiFilterMastodon { + private request: FastifyRequest; + private client: MegalodonInterface; - constructor(request: FastifyRequest, client: MegalodonInterface) { - this.request = request; - this.client = client; - } + constructor(request: FastifyRequest, client: MegalodonInterface) { + this.request = request; + this.client = client; + } - public async getFilters() { - try { + public async getFilters() { + try { const data = await this.client.getFilters(); - return data.data.map((filter) => convertFilter(filter)); + return data.data.map((filter) => convertFilter(filter)); } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async getFilter() { - try { + public async getFilter() { + try { const data = await this.client.getFilter( convertId((this.request.params as any).id, IdType.SharkeyId) ); - return convertFilter(data.data); + return convertFilter(data.data); } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async createFilter() { - try { - const body: any = this.request.body; + public async createFilter() { + try { + const body: any = this.request.body; const data = await this.client.createFilter(body.pharse, body.context, body); - return convertFilter(data.data); + return convertFilter(data.data); } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async updateFilter() { - try { - const body: any = this.request.body; + 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); - return convertFilter(data.data); + return convertFilter(data.data); } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async rmFilter() { - try { + public async rmFilter() { + try { const data = await this.client.deleteFilter( convertId((this.request.params as any).id, IdType.SharkeyId) ); - return data.data; + return data.data; } catch (e: any) { console.error(e); return e.response.data; } - } -} \ No newline at end of file + } +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/meta.ts b/packages/backend/src/server/api/mastodon/endpoints/meta.ts index 28ea6c08f..77b643ff7 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/meta.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/meta.ts @@ -6,8 +6,8 @@ import type { MiMeta } from '@/models/Meta.js'; export async function getInstance( response: Entity.Instance, contact: Entity.Account, - config: Config, - meta: MiMeta, + config: Config, + meta: MiMeta, ) { return { uri: config.url, @@ -16,7 +16,7 @@ export async function getInstance( meta.description?.substring(0, 50) || 'See real server website', description: meta.description || - "This is a vanilla Sharkey Instance. It doesn't seem to have a description.", + 'This is a vanilla Sharkey Instance. It doesn\'t seem to have a description.', email: response.email || '', version: `3.0.0 (compatible; Sharkey ${config.version})`, urls: response.urls, @@ -60,4 +60,4 @@ export async function getInstance( contact_account: contact, rules: [], }; -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts index 667379e8b..1dbb8d8b7 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts @@ -1,71 +1,71 @@ -import type { MegalodonInterface } from 'megalodon'; -import type { FastifyRequest } from 'fastify'; -import { convertTimelinesArgsId } from './timeline.js'; import { IdConvertType as IdType, convertId, convertNotification } from '../converters.js'; +import { convertTimelinesArgsId } from './timeline.js'; +import type { MegalodonInterface, Entity } from 'megalodon'; +import type { FastifyRequest } from 'fastify'; function toLimitToInt(q: any) { - if (q.limit) if (typeof q.limit === 'string') q.limit = parseInt(q.limit, 10); - return q; + if (q.limit) if (typeof q.limit === 'string') q.limit = parseInt(q.limit, 10); + return q; } -export class apiNotifyMastodon { - private request: FastifyRequest; - private client: MegalodonInterface; +export class ApiNotifyMastodon { + private request: FastifyRequest; + private client: MegalodonInterface; - constructor(request: FastifyRequest, client: MegalodonInterface) { - this.request = request; - this.client = client; - } + constructor(request: FastifyRequest, client: MegalodonInterface) { + this.request = request; + this.client = client; + } - public async getNotifications() { - try { + public async getNotifications() { + try { const data = await this.client.getNotifications( convertTimelinesArgsId(toLimitToInt(this.request.query)) ); - const notifs = data.data; - const processed = notifs.map((n) => { - n = convertNotification(n); - if (n.type !== 'follow' && n.type !== 'follow_request') { - if (n.type === 'reaction') n.type = 'favourite'; - return n; - } else { - return n; - } - }); + const notifs = data.data; + const processed = notifs.map((n: Entity.Notification) => { + let convertedn = convertNotification(n); + if (convertedn.type !== 'follow' && convertedn.type !== 'follow_request') { + if (convertedn.type === 'reaction') convertedn.type = 'favourite'; + return convertedn; + } else { + return convertedn; + } + }); return processed; } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async getNotification() { - try { + public async getNotification() { + try { const data = await this.client.getNotification( convertId((this.request.params as any).id, IdType.SharkeyId) ); - const notif = convertNotification(data.data); - if (notif.type !== 'follow' && notif.type !== 'follow_request' && notif.type === 'reaction') notif.type = 'favourite'; + const notif = convertNotification(data.data); + if (notif.type !== 'follow' && notif.type !== 'follow_request' && notif.type === 'reaction') notif.type = 'favourite'; return notif; } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async rmNotification() { - try { + public async rmNotification() { + try { const data = await this.client.dismissNotification( convertId((this.request.params as any).id, IdType.SharkeyId) ); return data.data; } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async rmNotifications() { - try { + public async rmNotifications() { + try { const data = await this.client.dismissNotifications(); return data.data; } catch (e: any) { console.error(e); return e.response.data; } - } -} \ No newline at end of file + } +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/search.ts b/packages/backend/src/server/api/mastodon/endpoints/search.ts index 6b36582b9..5c68402ed 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/search.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/search.ts @@ -1,30 +1,29 @@ -import type { MegalodonInterface } from 'megalodon'; -import { Converter } from 'megalodon'; -import type { FastifyRequest } from 'fastify'; -import { convertTimelinesArgsId, limitToInt } from './timeline.js'; +import { Converter } from 'megalodon'; import { convertAccount, convertStatus } from '../converters.js'; +import { convertTimelinesArgsId, limitToInt } from './timeline.js'; +import type { MegalodonInterface } from 'megalodon'; +import type { FastifyRequest } from 'fastify'; async function getHighlight( BASE_URL: string, domain: string, accessTokens: string | undefined, ) { - const accessTokenArr = accessTokens?.split(" ") ?? [null]; + const accessTokenArr = accessTokens?.split(' ') ?? [null]; const accessToken = accessTokenArr[accessTokenArr.length - 1]; try { - const apicall = await fetch(`${BASE_URL}/api/notes/featured`, - { - method: 'POST', - headers: { - 'Accept': 'application/json, text/plain, */*', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({i: accessToken}) - }); - const api = await apicall.json(); - const data: MisskeyEntity.Note[] = api; - return data.map((note) => Converter.note(note, domain)); + { + method: 'POST', + headers: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ i: accessToken }), + }); + const api = await apicall.json(); + const data: MisskeyEntity.Note[] = api; + return data.map((note) => Converter.note(note, domain)); } catch (e: any) { console.log(e); console.log(e.response.data); @@ -33,76 +32,76 @@ async function getHighlight( } async function getFeaturedUser( BASE_URL: string, host: string, accessTokens: string | undefined, limit: number ) { - const accessTokenArr = accessTokens?.split(" ") ?? [null]; + const accessTokenArr = accessTokens?.split(' ') ?? [null]; const accessToken = accessTokenArr[accessTokenArr.length - 1]; try { - const apicall = await fetch(`${BASE_URL}/api/users`, - { - method: 'POST', - headers: { - 'Accept': 'application/json, text/plain, */*', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({i: accessToken, limit, origin: "local", sort: "+follower", state: "alive"}) - }); - const api = await apicall.json(); - const data: MisskeyEntity.UserDetail[] = api; - return data.map((u) => { - return { - source: "past_interactions", - account: Converter.userDetail(u, host), - }; - }); + const apicall = await fetch(`${BASE_URL}/api/users`, + { + method: 'POST', + headers: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ i: accessToken, limit, origin: 'local', sort: '+follower', state: 'alive' }), + }); + const api = await apicall.json(); + const data: MisskeyEntity.UserDetail[] = api; + return data.map((u) => { + return { + source: 'past_interactions', + account: Converter.userDetail(u, host), + }; + }); } catch (e: any) { console.log(e); console.log(e.response.data); return []; } } -export class apiSearchMastodon { - private request: FastifyRequest; - private client: MegalodonInterface; - private BASE_URL: string; +export class ApiSearchMastodon { + private request: FastifyRequest; + private client: MegalodonInterface; + private BASE_URL: string; - constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) { - this.request = request; - this.client = client; - this.BASE_URL = BASE_URL; - } + constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) { + this.request = request; + this.client = client; + this.BASE_URL = BASE_URL; + } - public async SearchV1() { - try { + public async SearchV1() { + try { const query: any = convertTimelinesArgsId(limitToInt(this.request.query as any)); - const type = query.type || ""; + const type = query.type || ''; const data = await this.client.search(query.q, { type: type, ...query }); return data.data; } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async SearchV2() { - try { + public async SearchV2() { + try { const query: any = convertTimelinesArgsId(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; - const tags = !type || type === "hashtags" ? await this.client.search(query.q, { type: "hashtags", ...query }) : null; + 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; + const tags = !type || type === 'hashtags' ? await this.client.search(query.q, { type: 'hashtags', ...query }) : null; const data = { - accounts: acct?.data.accounts.map((account) => convertAccount(account)) ?? [], - statuses: stat?.data.statuses.map((status) => convertStatus(status)) ?? [], - hashtags: tags?.data.hashtags ?? [] - }; + accounts: acct?.data.accounts.map((account) => convertAccount(account)) ?? [], + statuses: stat?.data.statuses.map((status) => convertStatus(status)) ?? [], + hashtags: tags?.data.hashtags ?? [], + }; return data; } catch (e: any) { console.error(e); return e.response.data; } - } + } - public async getStatusTrends() { - try { + public async getStatusTrends() { + try { const data = await getHighlight( this.BASE_URL, this.request.hostname, @@ -113,14 +112,14 @@ export class apiSearchMastodon { console.error(e); return e.response.data; } - } + } - public async getSuggestions() { - try { + public async getSuggestions() { + try { const data = await getFeaturedUser( this.BASE_URL, this.request.hostname, - this.request.headers.authorization, + this.request.headers.authorization, (this.request.query as any).limit || 20, ); return data.map((suggestion) => { suggestion.account = convertAccount(suggestion.account); return suggestion; }); @@ -128,5 +127,5 @@ export class apiSearchMastodon { console.error(e); return e.response.data; } - } -} \ No newline at end of file + } +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index 85a67a4a1..5ce0c8941 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -1,407 +1,400 @@ -import { convertId, IdConvertType as IdType, convertAccount, convertAttachment, convertPoll, convertStatus } from '../converters.js'; import querystring from 'querystring'; -import type { Entity, MegalodonInterface } from 'megalodon'; -import type { FastifyInstance } from 'fastify'; +import { emojiRegexAtStartToEnd } from '@/misc/emoji-regex.js'; +import { convertId, IdConvertType as IdType, convertAccount, convertAttachment, convertPoll, convertStatus } from '../converters.js'; import { getClient } from '../MastodonApiServerService.js'; import { convertTimelinesArgsId, limitToInt } from './timeline.js'; -import { emojiRegexAtStartToEnd } from "@/misc/emoji-regex.js"; -import { MetaService } from '@/core/MetaService.js'; +import type { Entity } from 'megalodon'; +import type { FastifyInstance } from 'fastify'; function normalizeQuery(data: any) { const str = querystring.stringify(data); return querystring.parse(str); } -export class apiStatusMastodon { - private fastify: FastifyInstance; - private metaService: MetaService; +export class ApiStatusMastodon { + private fastify: FastifyInstance; - constructor(fastify: FastifyInstance) { - this.fastify = fastify; - } + constructor(fastify: FastifyInstance) { + this.fastify = fastify; + } - public async getStatus() { - this.fastify.get<{ Params: { id: string } }>("/v1/statuses/:id", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(_request.is404 ? 404 : 401).send(e.response.data); - } - }); - } + public async getStatus() { + this.fastify.get<{ Params: { id: string } }>('/v1/statuses/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(_request.is404 ? 404 : 401).send(e.response.data); + } + }); + } - public async getContext() { - this.fastify.get<{ Params: { id: string } }>("/v1/statuses/:id/context", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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)) - ); - data.data.ancestors = data.data.ancestors.map((status: Entity.Status) => convertStatus(status)); - data.data.descendants = data.data.descendants.map((status: Entity.Status) => convertStatus(status)); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(_request.is404 ? 404 : 401).send(e.response.data); - } - }); - } - - public async getHistory() { - this.fastify.get<{ Params: { id: string } }>("/v1/statuses/:id/history", async (_request, reply) => { - try { - reply.code(401).send({ message: 'Not Implemented' }); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async getReblogged() { - this.fastify.get<{ Params: { id: string } }>("/v1/statuses/:id/reblogged_by", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - 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))); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async getFavourites() { - this.fastify.get<{ Params: { id: string } }>("/v1/statuses/:id/favourited_by", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - 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))); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async getMedia() { - this.fastify.get<{ Params: { id: string } }>("/v1/media/:id", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getMedia(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertAttachment(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async getPoll() { - this.fastify.get<{ Params: { id: string } }>("/v1/polls/:id", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.getPoll(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertPoll(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async votePoll() { - this.fastify.post<{ Params: { id: string } }>("/v1/polls/:id/votes", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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); - reply.send(convertPoll(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async postStatus() { - this.fastify.post("/v1/statuses", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - 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[]"]) - ) { - body = normalizeQuery(body); - } - const text = body.status; - const removed = text.replace(/@\S+/g, "").replace(/\s|​/g, ""); - const isDefaultEmoji = emojiRegexAtStartToEnd.test(removed); - const isCustomEmoji = /^:[a-zA-Z0-9@_]+:$/.test(removed); - if ((body.in_reply_to_id && isDefaultEmoji) || isCustomEmoji) { - const a = await client.createEmojiReaction( - body.in_reply_to_id, - removed, - ); - reply.send(a.data); - } - if (body.in_reply_to_id && removed === "/unreact") { - try { - const id = body.in_reply_to_id; - const post = await client.getStatus(id); - const react = post.data.emoji_reactions.filter((e: any) => e.me)[0].name; - const data = await client.deleteEmojiReaction(id, react); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - } - 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; - - if (body.poll) { - if ( - body.poll.expires_in != null && - typeof body.poll.expires_in === "string" - ) - body.poll.expires_in = parseInt(body.poll.expires_in); - if ( - body.poll.multiple != null && - typeof body.poll.multiple === "string" - ) - body.poll.multiple = body.poll.multiple == "true"; - if ( - body.poll.hide_totals != null && - typeof body.poll.hide_totals === "string" - ) - body.poll.hide_totals = body.poll.hide_totals == "true"; - } - - const data = await client.postStatus(text, body); - reply.send(convertStatus(data.data as Entity.Status)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async addFavourite() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/favourite", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = (await client.createEmojiReaction( + public async getContext() { + this.fastify.get<{ Params: { id: string } }>('/v1/statuses/:id/context', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + const query: any = _request.query; + try { + const data = await client.getStatusContext( convertId(_request.params.id, IdType.SharkeyId), - '⭐' - )) as any; - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } - - public async rmFavourite() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/unfavourite", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.deleteEmojiReaction( - convertId(_request.params.id, IdType.SharkeyId), - '⭐' + convertTimelinesArgsId(limitToInt(query)), ); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + data.data.ancestors = data.data.ancestors.map((status: Entity.Status) => convertStatus(status)); + data.data.descendants = data.data.descendants.map((status: Entity.Status) => convertStatus(status)); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(_request.is404 ? 404 : 401).send(e.response.data); + } + }); + } - public async reblogStatus() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/reblog", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.reblogStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async getHistory() { + this.fastify.get<{ Params: { id: string } }>('/v1/statuses/:id/history', async (_request, reply) => { + try { + reply.code(401).send({ message: 'Not Implemented' }); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } - public async unreblogStatus() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/unreblog", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.unreblogStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async getReblogged() { + this.fastify.get<{ Params: { id: string } }>('/v1/statuses/:id/reblogged_by', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + 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))); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } - public async bookmarkStatus() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/bookmark", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.bookmarkStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async getFavourites() { + this.fastify.get<{ Params: { id: string } }>('/v1/statuses/:id/favourited_by', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + 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))); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } - public async unbookmarkStatus() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/unbookmark", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.unbookmarkStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async getMedia() { + this.fastify.get<{ Params: { id: string } }>('/v1/media/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getMedia(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertAttachment(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } - public async pinStatus() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/pin", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.pinStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async getPoll() { + this.fastify.get<{ Params: { id: string } }>('/v1/polls/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getPoll(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertPoll(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } - public async unpinStatus() { - this.fastify.post<{ Params: { id: string } }>("/v1/statuses/:id/unpin", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.unpinStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async votePoll() { + this.fastify.post<{ Params: { id: string } }>('/v1/polls/:id/votes', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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); + reply.send(convertPoll(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } - public async reactStatus() { - this.fastify.post<{ Params: { id: string, name: string } }>("/v1/statuses/:id/react/:name", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - 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); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + public async postStatus() { + this.fastify.post('/v1/statuses', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + 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[]']) + ) { + body = normalizeQuery(body); + } + const text = body.status; + const removed = text.replace(/@\S+/g, '').replace(/\s|/g, ''); + const isDefaultEmoji = emojiRegexAtStartToEnd.test(removed); + const isCustomEmoji = /^:[a-zA-Z0-9@_]+:$/.test(removed); + if ((body.in_reply_to_id && isDefaultEmoji) || isCustomEmoji) { + const a = await client.createEmojiReaction( + body.in_reply_to_id, + removed, + ); + reply.send(a.data); + } + if (body.in_reply_to_id && removed === '/unreact') { + try { + const id = body.in_reply_to_id; + const post = await client.getStatus(id); + const react = post.data.emoji_reactions.filter((e: any) => e.me)[0].name; + const data = await client.deleteEmojiReaction(id, react); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + } + 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)); + } - public async unreactStatus() { - this.fastify.post<{ Params: { id: string, name: string } }>("/v1/statuses/:id/unreact/:name", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - 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); - reply.send(convertStatus(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + const { sensitive } = body; + body.sensitive = typeof sensitive === 'string' ? sensitive === 'true' : sensitive; - public async updateMedia() { - this.fastify.put<{ Params: { id: string } }>("/v1/media/:id", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - 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 as any); - reply.send(convertAttachment(data.data)); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } + if (body.poll) { + if ( + body.poll.expires_in != null && + typeof body.poll.expires_in === 'string' + ) body.poll.expires_in = parseInt(body.poll.expires_in); + if ( + body.poll.multiple != null && + typeof body.poll.multiple === 'string' + ) body.poll.multiple = body.poll.multiple === 'true'; + if ( + body.poll.hide_totals != null && + typeof body.poll.hide_totals === 'string' + ) body.poll.hide_totals = body.poll.hide_totals === 'true'; + } - public async deleteStatus() { - this.fastify.delete<{ Params: { id: string } }>("/v1/statuses/:id", async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.deleteStatus(convertId(_request.params.id, IdType.SharkeyId)); - reply.send(data.data); - } catch (e: any) { - console.error(e); - reply.code(401).send(e.response.data); - } - }); - } -} \ No newline at end of file + const data = await client.postStatus(text, body); + reply.send(convertStatus(data.data as Entity.Status)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async addFavourite() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/favourite', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + 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; + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async rmFavourite() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/unfavourite', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.deleteEmojiReaction( + convertId(_request.params.id, IdType.SharkeyId), + '⭐', + ); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async reblogStatus() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/reblog', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.reblogStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async unreblogStatus() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/unreblog', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.unreblogStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async bookmarkStatus() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/bookmark', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.bookmarkStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async unbookmarkStatus() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/unbookmark', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.unbookmarkStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async pinStatus() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/pin', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.pinStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async unpinStatus() { + this.fastify.post<{ Params: { id: string } }>('/v1/statuses/:id/unpin', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.unpinStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async reactStatus() { + this.fastify.post<{ Params: { id: string, name: string } }>('/v1/statuses/:id/react/:name', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + 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); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async unreactStatus() { + this.fastify.post<{ Params: { id: string, name: string } }>('/v1/statuses/:id/unreact/:name', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + 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); + reply.send(convertStatus(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async updateMedia() { + this.fastify.put<{ Params: { id: string } }>('/v1/media/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + 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 as any); + reply.send(convertAttachment(data.data)); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } + + public async deleteStatus() { + this.fastify.delete<{ Params: { id: string } }>('/v1/statuses/:id', async (_request, reply) => { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.deleteStatus(convertId(_request.params.id, IdType.SharkeyId)); + reply.send(data.data); + } catch (e: any) { + console.error(e); + reply.code(401).send(e.response.data); + } + }); + } +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts index ec7010ee7..a17120516 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts @@ -1,15 +1,13 @@ -import { convertId, IdConvertType as IdType, convertAccount, convertConversation, convertList, convertStatus } from '../converters.js'; import { ParsedUrlQuery } from 'querystring'; -import type { Entity, MegalodonInterface } from 'megalodon'; -import type { FastifyInstance } from 'fastify'; +import { convertId, IdConvertType as IdType, convertAccount, convertConversation, convertList, convertStatus } from '../converters.js'; import { getClient } from '../MastodonApiServerService.js'; +import type { Entity } from 'megalodon'; +import type { FastifyInstance } from 'fastify'; export function limitToInt(q: ParsedUrlQuery) { - let object: any = q; - if (q.limit) - if (typeof q.limit === 'string') object.limit = parseInt(q.limit, 10); - if (q.offset) - if (typeof q.offset === 'string') object.offset = parseInt(q.offset, 10); + const object: any = q; + if (q.limit) if (typeof q.limit === 'string') object.limit = parseInt(q.limit, 10); + if (q.offset) if (typeof q.offset === 'string') object.offset = parseInt(q.offset, 10); return object; } @@ -22,165 +20,133 @@ export function argsToBools(q: ParsedUrlQuery) { // - https://docs.joinmastodon.org/methods/accounts/#statuses // - https://docs.joinmastodon.org/methods/timelines/#public // - https://docs.joinmastodon.org/methods/timelines/#tag - let object: any = q; - if (q.only_media) - if (typeof q.only_media === 'string') - object.only_media = toBoolean(q.only_media); - if (q.exclude_replies) - if (typeof q.exclude_replies === 'string') - object.exclude_replies = toBoolean(q.exclude_replies); - if (q.exclude_reblogs) - if (typeof q.exclude_reblogs === 'string') - object.exclude_reblogs = toBoolean(q.exclude_reblogs); - if (q.pinned) - if (typeof q.pinned === 'string') object.pinned = toBoolean(q.pinned); - if (q.local) - if (typeof q.local === 'string') object.local = toBoolean(q.local); + const object: any = q; + if (q.only_media) if (typeof q.only_media === 'string') object.only_media = toBoolean(q.only_media); + if (q.exclude_replies) if (typeof q.exclude_replies === 'string') object.exclude_replies = toBoolean(q.exclude_replies); + if (q.exclude_reblogs) if (typeof q.exclude_reblogs === 'string') object.exclude_reblogs = toBoolean(q.exclude_reblogs); + if (q.pinned) if (typeof q.pinned === 'string') object.pinned = toBoolean(q.pinned); + if (q.local) if (typeof q.local === 'string') object.local = toBoolean(q.local); 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); + 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; } -function escapeHTML(str: string) { - if (!str) { - return ''; - } - return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/'/g, '"') - .replace(/'/g, '''); -} - -function nl2br(str: string) { - if (!str) { - return ''; - } - str = str.replace(/\r\n/g, '
'); - str = str.replace(/(\n|\r)/g, '
'); - return str; -} - -export class apiTimelineMastodon { +export class ApiTimelineMastodon { private fastify: FastifyInstance; - constructor(fastify: FastifyInstance) { + constructor(fastify: FastifyInstance) { this.fastify = fastify; - } + } public async getTL() { this.fastify.get('/v1/timelines/public', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const query: any = _request.query; + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + 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)))); - reply.send(data.data.map((status: Entity.Status) => convertStatus(status))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(data.data.map((status: Entity.Status) => convertStatus(status))); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async getHomeTl() { this.fastify.get('/v1/timelines/home', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const query: any = _request.query; + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const query: any = _request.query; const data = await client.getHomeTimeline(convertTimelinesArgsId(limitToInt(query))); reply.send(data.data.map((status: Entity.Status) => convertStatus(status))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async getTagTl() { this.fastify.get<{ Params: { hashtag: string } }>('/v1/timelines/tag/:hashtag', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const query: any = _request.query; + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const query: any = _request.query; const params: any = _request.params; const data = await client.getTagTimeline(params.hashtag, convertTimelinesArgsId(limitToInt(query))); reply.send(data.data.map((status: Entity.Status) => convertStatus(status))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async getListTL() { this.fastify.get<{ Params: { id: string } }>('/v1/timelines/list/:id', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const query: any = _request.query; + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const query: any = _request.query; const params: any = _request.params; const data = await client.getListTimeline(convertId(params.id, IdType.SharkeyId), convertTimelinesArgsId(limitToInt(query))); reply.send(data.data.map((status: Entity.Status) => convertStatus(status))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async getConversations() { this.fastify.get('/v1/conversations', async (_request, reply) => { - const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { + const BASE_URL = `${_request.protocol}://${_request.hostname}`; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { const query: any = _request.query; const data = await client.getConversationTimeline(convertTimelinesArgsId(limitToInt(query))); - reply.send(data.data.map((conversation: Entity.Conversation) => convertConversation(conversation))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(data.data.map((conversation: Entity.Conversation) => convertConversation(conversation))); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } - public async getList(){ + public async getList() { this.fastify.get<{ Params: { id: string } }>('/v1/lists/:id', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - const params: any = _request.params; + 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)); - reply.send(convertList(data.data)); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(convertList(data.data)); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async getLists() { @@ -197,121 +163,120 @@ export class apiTimelineMastodon { return e.response.data; } }); - } + } - public async getListAccounts(){ + public async getListAccounts() { this.fastify.get<{ Params: { id: string } }>('/v1/lists/:id/accounts', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - const params: any = _request.params; + const accessTokens = _request.headers.authorization; + 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) + convertTimelinesArgsId(query), ); - reply.send(data.data.map((account: Entity.Account) => convertAccount(account))); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(data.data.map((account: Entity.Account) => convertAccount(account))); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async addListAccount() { this.fastify.post<{ Params: { id: string } }>('/v1/lists/:id/accounts', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - const params: any = _request.params; + const accessTokens = _request.headers.authorization; + 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)) + (query.accounts_id as string[]).map((id) => convertId(id, IdType.SharkeyId)), ); - reply.send(data.data); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(data.data); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async rmListAccount() { this.fastify.delete<{ Params: { id: string } }>('/v1/lists/:id/accounts', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); + const accessTokens = _request.headers.authorization; + 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)) + (query.accounts_id as string[]).map((id) => convertId(id, IdType.SharkeyId)), ); - reply.send(data.data); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(data.data); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async createList() { this.fastify.post('/v1/lists', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - const body: any = _request.body; + const accessTokens = _request.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + const body: any = _request.body; const data = await client.createList(body.title); - reply.send(convertList(data.data)); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(convertList(data.data)); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async updateList() { this.fastify.put<{ Params: { id: string } }>('/v1/lists/:id', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - const body: any = _request.body; + const accessTokens = _request.headers.authorization; + 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); - reply.send(convertList(data.data)); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(convertList(data.data)); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } public async deleteList() { this.fastify.delete<{ Params: { id: string } }>('/v1/lists/:id', async (_request, reply) => { - try { + try { const BASE_URL = `${_request.protocol}://${_request.hostname}`; - const accessTokens = _request.headers.authorization; - const client = getClient(BASE_URL, accessTokens); + 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)); - reply.send(data.data); - } catch (e: any) { - console.error(e); - console.error(e.response.data); - reply.code(401).send(e.response.data); - } - }); + reply.send(data.data); + } catch (e: any) { + console.error(e); + console.error(e.response.data); + reply.code(401).send(e.response.data); + } + }); } - -} \ No newline at end of file +}