From 011d7f36c33f6f0ab9e39304a5be412a2651661e Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 7 Oct 2023 21:53:38 +0200 Subject: [PATCH] [mastodon-client] Set ctx.pagination in helper funcs --- .../api/mastodon/converters/announcement.ts | 2 +- .../server/api/mastodon/converters/auth.ts | 2 +- .../server/api/mastodon/endpoints/account.ts | 24 +++---- .../src/server/api/mastodon/endpoints/list.ts | 3 +- .../api/mastodon/endpoints/notifications.ts | 3 +- .../server/api/mastodon/endpoints/search.ts | 2 +- .../server/api/mastodon/endpoints/status.ts | 8 +-- .../server/api/mastodon/endpoints/timeline.ts | 17 ++--- .../src/server/api/mastodon/helpers/list.ts | 10 ++- .../src/server/api/mastodon/helpers/note.ts | 18 ++--- .../api/mastodon/helpers/notification.ts | 5 +- .../server/api/mastodon/helpers/pagination.ts | 18 +++-- .../server/api/mastodon/helpers/timeline.ts | 27 ++++---- .../src/server/api/mastodon/helpers/user.ts | 66 ++++++++----------- .../server/api/mastodon/middleware/auth.ts | 2 +- .../server/api/mastodon/middleware/cache.ts | 2 +- .../api/mastodon/middleware/catch-errors.ts | 2 +- .../mastodon/middleware/normalize-query.ts | 2 +- .../api/mastodon/middleware/pagination.ts | 7 +- .../api/mastodon/middleware/set-headers.ts | 2 +- 20 files changed, 88 insertions(+), 134 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/converters/announcement.ts b/packages/backend/src/server/api/mastodon/converters/announcement.ts index b3c191f26..35cd142df 100644 --- a/packages/backend/src/server/api/mastodon/converters/announcement.ts +++ b/packages/backend/src/server/api/mastodon/converters/announcement.ts @@ -21,4 +21,4 @@ export class AnnouncementConverter { reactions: [], }; } -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/converters/auth.ts b/packages/backend/src/server/api/mastodon/converters/auth.ts index 98f98cf86..cb029c1b1 100644 --- a/packages/backend/src/server/api/mastodon/converters/auth.ts +++ b/packages/backend/src/server/api/mastodon/converters/auth.ts @@ -146,4 +146,4 @@ export class AuthConverter { return unique(res); } -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 3dd1d530a..afb54e710 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -56,10 +56,9 @@ export function setupEndpointsAccount(router: Router): void { const query = await UserHelpers.getUserCachedOr404(userId, ctx); const args = normalizeUrlQuery(convertPaginationArgsIds(argsToBools(limitToInt(ctx.query)))); const res = await UserHelpers.getUserStatuses(query, args.max_id, args.since_id, args.min_id, args.limit, args['only_media'], args['exclude_replies'], args['exclude_reblogs'], args.pinned, args.tagged, ctx); - const tl = await NoteConverter.encodeMany(res.data, ctx); + const tl = await NoteConverter.encodeMany(res, ctx); ctx.body = tl.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; }, ); router.get<{ Params: { id: string } }>( @@ -76,10 +75,9 @@ export function setupEndpointsAccount(router: Router): void { const query = await UserHelpers.getUserCachedOr404(userId, ctx); const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserFollowers(query, args.max_id, args.since_id, args.min_id, args.limit, ctx); - const followers = await UserConverter.encodeMany(res.data, ctx); + const followers = await UserConverter.encodeMany(res, ctx); ctx.body = followers.map((account) => convertAccountId(account)); - ctx.pagination = res.pagination; }, ); router.get<{ Params: { id: string } }>( @@ -90,10 +88,9 @@ export function setupEndpointsAccount(router: Router): void { const query = await UserHelpers.getUserCachedOr404(userId, ctx); const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserFollowing(query, args.max_id, args.since_id, args.min_id, args.limit, ctx); - const following = await UserConverter.encodeMany(res.data, ctx); + const following = await UserConverter.encodeMany(res, ctx); ctx.body = following.map((account) => convertAccountId(account)); - ctx.pagination = res.pagination; }, ); router.get<{ Params: { id: string } }>( @@ -177,9 +174,8 @@ export function setupEndpointsAccount(router: Router): void { async (ctx) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserBookmarks(args.max_id, args.since_id, args.min_id, args.limit, ctx); - const bookmarks = await NoteConverter.encodeMany(res.data, ctx); + const bookmarks = await NoteConverter.encodeMany(res, ctx); ctx.body = bookmarks.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; } ); router.get("/v1/favourites", @@ -187,9 +183,8 @@ export function setupEndpointsAccount(router: Router): void { async (ctx) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserFavorites(args.max_id, args.since_id, args.min_id, args.limit, ctx); - const favorites = await NoteConverter.encodeMany(res.data, ctx); + const favorites = await NoteConverter.encodeMany(res, ctx); ctx.body = favorites.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; } ); router.get("/v1/mutes", @@ -197,8 +192,7 @@ export function setupEndpointsAccount(router: Router): void { async (ctx) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserMutes(args.max_id, args.since_id, args.min_id, args.limit, ctx); - ctx.body = res.data.map(m => convertAccountId(m)); - ctx.pagination = res.pagination; + ctx.body = res.map(m => convertAccountId(m)); } ); router.get("/v1/blocks", @@ -206,9 +200,8 @@ export function setupEndpointsAccount(router: Router): void { async (ctx) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserBlocks(args.max_id, args.since_id, args.min_id, args.limit, ctx); - const blocks = await UserConverter.encodeMany(res.data, ctx); + const blocks = await UserConverter.encodeMany(res, ctx); ctx.body = blocks.map(b => convertAccountId(b)); - ctx.pagination = res.pagination; } ); router.get("/v1/follow_requests", @@ -216,9 +209,8 @@ export function setupEndpointsAccount(router: Router): void { async (ctx) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await UserHelpers.getUserFollowRequests(args.max_id, args.since_id, args.min_id, args.limit, ctx); - const requests = await UserConverter.encodeMany(res.data, ctx); + const requests = await UserConverter.encodeMany(res, ctx); ctx.body = requests.map(b => convertAccountId(b)); - ctx.pagination = res.pagination; } ); router.post<{ Params: { id: string } }>( diff --git a/packages/backend/src/server/api/mastodon/endpoints/list.ts b/packages/backend/src/server/api/mastodon/endpoints/list.ts index ae29370e3..516aa822e 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/list.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/list.ts @@ -71,10 +71,9 @@ export function setupEndpointsList(router: Router): void { const id = convertId(ctx.params.id, IdType.IceshrimpId); const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query))); const res = await ListHelpers.getListUsers(id, args.max_id, args.since_id, args.min_id, args.limit, ctx); - const accounts = await UserConverter.encodeMany(res.data, ctx); + const accounts = await UserConverter.encodeMany(res, ctx); ctx.body = accounts.map(account => convertAccountId(account)); - ctx.pagination = res.pagination; }, ); router.post<{ Params: { id: string } }>( diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts index b713e9804..78959236e 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts @@ -12,10 +12,9 @@ export function setupEndpointsNotifications(router: Router): void { async (ctx) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query)), ['types[]', 'exclude_types[]']); const res = await NotificationHelpers.getNotifications(args.max_id, args.since_id, args.min_id, args.limit, args['types[]'], args['exclude_types[]'], args.account_id, ctx); - const data = await NotificationConverter.encodeMany(res.data, ctx); + const data = await NotificationConverter.encodeMany(res, ctx); ctx.body = data.map(n => convertNotificationIds(n)); - ctx.pagination = res.pagination; } ); diff --git a/packages/backend/src/server/api/mastodon/endpoints/search.ts b/packages/backend/src/server/api/mastodon/endpoints/search.ts index c6384dcaa..c5f3f5905 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/search.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/search.ts @@ -21,4 +21,4 @@ export function setupEndpointsSearch(router: Router): void { } } ); -} \ 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 66e458210..0acc46e15 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -117,9 +117,8 @@ export function setupEndpointsStatus(router: Router): void { const note = await NoteHelpers.getNoteOr404(id, ctx); const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); const res = await NoteHelpers.getNoteRebloggedBy(note, args.max_id, args.since_id, args.min_id, args.limit, ctx); - const users = await UserConverter.encodeMany(res.data, ctx); + const users = await UserConverter.encodeMany(res, ctx); ctx.body = users.map(m => convertAccountId(m)); - ctx.pagination = res.pagination; } ); router.get<{ Params: { id: string } }>( @@ -129,10 +128,9 @@ export function setupEndpointsStatus(router: Router): void { const id = convertId(ctx.params.id, IdType.IceshrimpId); const note = await NoteHelpers.getNoteOr404(id, ctx); const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query as any))); - const res = await NoteHelpers.getNoteFavoritedBy(note, args.max_id, args.since_id, args.min_id, args.limit); - const users = await UserConverter.encodeMany(res.data, ctx); + const res = await NoteHelpers.getNoteFavoritedBy(note, args.max_id, args.since_id, args.min_id, args.limit, ctx); + const users = await UserConverter.encodeMany(res, ctx); ctx.body = users.map(m => convertAccountId(m)); - ctx.pagination = res.pagination; } ); router.post<{ Params: { id: string } }>( diff --git a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts index 897f6707d..3395bcf5a 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts @@ -68,10 +68,9 @@ export function setupEndpointsTimeline(router: Router): void { async (ctx, reply) => { const args = normalizeUrlQuery(convertPaginationArgsIds(argsToBools(limitToInt(ctx.query)))); const res = await TimelineHelpers.getPublicTimeline(args.max_id, args.since_id, args.min_id, args.limit, args.only_media, args.local, args.remote, ctx); - const tl = await NoteConverter.encodeMany(res.data, ctx); + const tl = await NoteConverter.encodeMany(res, ctx); ctx.body = tl.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; }); router.get<{ Params: { hashtag: string } }>( "/v1/timelines/tag/:hashtag", @@ -79,11 +78,10 @@ export function setupEndpointsTimeline(router: Router): void { async (ctx, reply) => { const tag = (ctx.params.hashtag ?? '').trim(); const args = normalizeUrlQuery(convertPaginationArgsIds(argsToBools(limitToInt(ctx.query))), ['any[]', 'all[]', 'none[]']); - const res = await TimelineHelpers.getTagTimeline(ctx.user, tag, args.max_id, args.since_id, args.min_id, args.limit, args['any[]'] ?? [], args['all[]'] ?? [], args['none[]'] ?? [], args.only_media, args.local, args.remote); - const tl = await NoteConverter.encodeMany(res.data, ctx); + const res = await TimelineHelpers.getTagTimeline(tag, args.max_id, args.since_id, args.min_id, args.limit, args['any[]'] ?? [], args['all[]'] ?? [], args['none[]'] ?? [], args.only_media, args.local, args.remote, ctx); + const tl = await NoteConverter.encodeMany(res, ctx); ctx.body = tl.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; }, ); router.get("/v1/timelines/home", @@ -91,10 +89,9 @@ export function setupEndpointsTimeline(router: Router): void { async (ctx, reply) => { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query))); const res = await TimelineHelpers.getHomeTimeline(args.max_id, args.since_id, args.min_id, args.limit, ctx); - const tl = await NoteConverter.encodeMany(res.data, ctx); + const tl = await NoteConverter.encodeMany(res, ctx); ctx.body = tl.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; }); router.get<{ Params: { listId: string } }>( "/v1/timelines/list/:listId", @@ -106,10 +103,9 @@ export function setupEndpointsTimeline(router: Router): void { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query))); const res = await TimelineHelpers.getListTimeline(list, args.max_id, args.since_id, args.min_id, args.limit, ctx); - const tl = await NoteConverter.encodeMany(res.data, ctx); + const tl = await NoteConverter.encodeMany(res, ctx); ctx.body = tl.map(s => convertStatusIds(s)); - ctx.pagination = res.pagination; }, ); router.get("/v1/conversations", @@ -118,8 +114,7 @@ export function setupEndpointsTimeline(router: Router): void { const args = normalizeUrlQuery(convertPaginationArgsIds(limitToInt(ctx.query))); const res = await TimelineHelpers.getConversations(args.max_id, args.since_id, args.min_id, args.limit, ctx); - ctx.body = res.data.map(c => convertConversationIds(c)); - ctx.pagination = res.pagination; + ctx.body = res.map(c => convertConversationIds(c)); } ); } diff --git a/packages/backend/src/server/api/mastodon/helpers/list.ts b/packages/backend/src/server/api/mastodon/helpers/list.ts index db7fa6136..8485e2a3b 100644 --- a/packages/backend/src/server/api/mastodon/helpers/list.ts +++ b/packages/backend/src/server/api/mastodon/helpers/list.ts @@ -1,6 +1,6 @@ import { ILocalUser, User } from "@/models/entities/user.js"; import { Blockings, UserListJoinings, UserLists, Users } from "@/models/index.js"; -import { generatePaginationData, LinkPaginationObject } from "@/server/api/mastodon/middleware/pagination.js"; +import { generatePaginationData } from "@/server/api/mastodon/middleware/pagination.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { UserList } from "@/models/entities/user-list.js"; import { pushUserToUserList } from "@/services/user-list/push.js"; @@ -38,7 +38,7 @@ export class ListHelpers { }) } - public static async getListUsers(id: string, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getListUsers(id: string, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const user = ctx.user as ILocalUser; const list = await UserLists.findOneBy({ userId: user.id, id: id }); @@ -58,10 +58,8 @@ export class ListHelpers { .map(p => p.user) .filter(p => p) as User[]; - return { - data: users, - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return users; }); } diff --git a/packages/backend/src/server/api/mastodon/helpers/note.ts b/packages/backend/src/server/api/mastodon/helpers/note.ts index 5687dde7a..a035bda35 100644 --- a/packages/backend/src/server/api/mastodon/helpers/note.ts +++ b/packages/backend/src/server/api/mastodon/helpers/note.ts @@ -15,7 +15,7 @@ import { genId } from "@/misc/gen-id.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { UserConverter } from "@/server/api/mastodon/converters/user.js"; import { UserHelpers } from "@/server/api/mastodon/helpers/user.js"; -import { generatePaginationData, LinkPaginationObject } from "@/server/api/mastodon/middleware/pagination.js" +import { generatePaginationData } from "@/server/api/mastodon/middleware/pagination.js" import { addPinned, removePinned } from "@/services/i/pin.js"; import { NoteConverter } from "@/server/api/mastodon/converters/note.js"; import { convertId, IdType } from "@/misc/convert-id.js"; @@ -161,7 +161,7 @@ export class NoteHelpers { return status; } - public static async getNoteFavoritedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40): Promise> { + public static async getNoteFavoritedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const query = PaginationHelpers.makePaginationQuery( NoteReactions.createQueryBuilder("reaction"), @@ -178,10 +178,8 @@ export class NoteHelpers { .map(p => p.user) .filter(p => p) as User[]; - return { - data: users, - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return users; }); } @@ -231,7 +229,7 @@ export class NoteHelpers { } } - public static async getNoteRebloggedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getNoteRebloggedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const user = ctx.user as ILocalUser | null; const query = PaginationHelpers.makePaginationQuery( @@ -252,10 +250,8 @@ export class NoteHelpers { .map(p => p.user) .filter(p => p) as User[]; - return { - data: users, - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return users; }); } diff --git a/packages/backend/src/server/api/mastodon/helpers/notification.ts b/packages/backend/src/server/api/mastodon/helpers/notification.ts index 6e28f0125..1d1647b66 100644 --- a/packages/backend/src/server/api/mastodon/helpers/notification.ts +++ b/packages/backend/src/server/api/mastodon/helpers/notification.ts @@ -3,11 +3,10 @@ import { Notes, Notifications } from "@/models/index.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { Notification } from "@/models/entities/notification.js"; import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js"; -import { LinkPaginationObject } from "@/server/api/mastodon/middleware/pagination.js"; import { MastoContext } from "@/server/api/mastodon/index.js"; export class NotificationHelpers { - public static async getNotifications(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, types: string[] | undefined, excludeTypes: string[] | undefined, accountId: string | undefined, ctx: MastoContext): Promise> { + public static async getNotifications(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, types: string[] | undefined, excludeTypes: string[] | undefined, accountId: string | undefined, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const user = ctx.user as ILocalUser; @@ -34,7 +33,7 @@ export class NotificationHelpers { query.leftJoinAndSelect("notification.note", "note"); - return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined); + return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined, ctx); } public static async getNotification(id: string, ctx: MastoContext): Promise { diff --git a/packages/backend/src/server/api/mastodon/helpers/pagination.ts b/packages/backend/src/server/api/mastodon/helpers/pagination.ts index 60eb1fef2..3323566df 100644 --- a/packages/backend/src/server/api/mastodon/helpers/pagination.ts +++ b/packages/backend/src/server/api/mastodon/helpers/pagination.ts @@ -1,5 +1,5 @@ import { ObjectLiteral, SelectQueryBuilder } from "typeorm"; -import { LinkPaginationObject } from "@/server/api/mastodon/middleware/pagination.js"; +import { MastoContext } from "@/server/api/mastodon/index.js"; export class PaginationHelpers { public static makePaginationQuery( @@ -45,18 +45,16 @@ export class PaginationHelpers { return query.take(limit).getMany().then(found => reverse ? found.reverse() : found); } - public static async execQueryLinkPagination(query: SelectQueryBuilder, limit: number, reverse: boolean): Promise> { + public static async execQueryLinkPagination(query: SelectQueryBuilder, limit: number, reverse: boolean, ctx: MastoContext): Promise { return this.execQuery(query, limit, reverse) .then(p => { const ids = p.map(x => x.id); - return { - data: p, - pagination: p.length > 0 ? { - limit: limit, - maxId: ids.at(reverse ? 0 : -1), - minId: ids.at(reverse ? -1 : 0) - } : undefined - } + ctx.pagination = p.length > 0 ? { + limit: limit, + maxId: ids.at(reverse ? 0 : -1), + minId: ids.at(reverse ? -1 : 0) + } : undefined; + return p; }); } } diff --git a/packages/backend/src/server/api/mastodon/helpers/timeline.ts b/packages/backend/src/server/api/mastodon/helpers/timeline.ts index 952fd9c40..01c9262fb 100644 --- a/packages/backend/src/server/api/mastodon/helpers/timeline.ts +++ b/packages/backend/src/server/api/mastodon/helpers/timeline.ts @@ -18,11 +18,11 @@ import { NoteConverter } from "@/server/api/mastodon/converters/note.js"; import { awaitAll } from "@/prelude/await-all.js"; import { unique } from "@/prelude/array.js"; import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js"; -import { generatePaginationData, LinkPaginationObject } from "@/server/api/mastodon/middleware/pagination.js"; +import { generatePaginationData } from "@/server/api/mastodon/middleware/pagination.js"; import { MastoContext } from "@/server/api/mastodon/index.js"; export class TimelineHelpers { - public static async getHomeTimeline(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise> { + public static async getHomeTimeline(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const user = ctx.user as ILocalUser; @@ -54,10 +54,10 @@ export class TimelineHelpers { query.andWhere("note.visibility != 'hidden'"); query.andWhere("note.visibility != 'specified'"); - return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined); + return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined, ctx); } - public static async getPublicTimeline(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, onlyMedia: boolean = false, local: boolean = false, remote: boolean = false, ctx: MastoContext): Promise> { + public static async getPublicTimeline(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, onlyMedia: boolean = false, local: boolean = false, remote: boolean = false, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const user = ctx.user as ILocalUser; @@ -98,10 +98,10 @@ export class TimelineHelpers { if (onlyMedia) query.andWhere("note.fileIds != '{}'"); - return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined); + return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined, ctx); } - public static async getListTimeline(list: UserList, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise> { + public static async getListTimeline(list: UserList, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const user = ctx.user as ILocalUser; if (user.id != list.userId) throw new Error("List is not owned by user"); @@ -123,10 +123,10 @@ export class TimelineHelpers { generateVisibilityQuery(query, user); - return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined); + return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined, ctx); } - public static async getTagTimeline(tag: string, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, any: string[], all: string[], none: string[], onlyMedia: boolean = false, local: boolean = false, remote: boolean = false, ctx: MastoContext): Promise> { + public static async getTagTimeline(tag: string, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, any: string[], all: string[], none: string[], onlyMedia: boolean = false, local: boolean = false, remote: boolean = false, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const user = ctx.user as ILocalUser | null; @@ -165,10 +165,10 @@ export class TimelineHelpers { if (onlyMedia) query.andWhere("note.fileIds != '{}'"); - return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined); + return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined, ctx); } - public static async getConversations(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise> { + public static async getConversations(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const user = ctx.user as ILocalUser; const sq = Notes.createQueryBuilder("note") @@ -216,12 +216,9 @@ export class TimelineHelpers { unread: unread } }); - const res = { - data: Promise.all(conversations.map(c => awaitAll(c))), - pagination: generatePaginationData(p.map(p => p.threadId ?? p.id), limit, minId !== undefined) - }; - return awaitAll(res); + ctx.pagination = generatePaginationData(p.map(p => p.threadId ?? p.id), limit, minId !== undefined); + return Promise.all(conversations.map(c => awaitAll(c))); }); } } diff --git a/packages/backend/src/server/api/mastodon/helpers/user.ts b/packages/backend/src/server/api/mastodon/helpers/user.ts index bee08bb6b..7adfc31cc 100644 --- a/packages/backend/src/server/api/mastodon/helpers/user.ts +++ b/packages/backend/src/server/api/mastodon/helpers/user.ts @@ -40,7 +40,7 @@ import { MediaHelpers } from "@/server/api/mastodon/helpers/media.js"; import { UserProfile } from "@/models/entities/user-profile.js"; import { verifyLink } from "@/services/fetch-rel-me.js"; import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js"; -import { generatePaginationData, LinkPaginationObject } from "@/server/api/mastodon/middleware/pagination.js"; +import { generatePaginationData } from "@/server/api/mastodon/middleware/pagination.js"; import { MastoContext } from "@/server/api/mastodon/index.js"; export type AccountCache = { @@ -238,7 +238,7 @@ export class UserHelpers { }); } - public static async getUserMutes(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getUserMutes(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const user = ctx.user as ILocalUser; @@ -267,14 +267,12 @@ export class UserHelpers { } as MastodonEntity.MutedAccount })); - return { - data: result, - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return result; }); } - public static async getUserBlocks(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getUserBlocks(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const user = ctx.user as ILocalUser; @@ -294,14 +292,12 @@ export class UserHelpers { .map(p => p.blockee) .filter(p => p) as User[]; - return { - data: users, - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return users; }); } - public static async getUserFollowRequests(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getUserFollowRequests(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const user = ctx.user as ILocalUser; @@ -321,20 +317,18 @@ export class UserHelpers { .map(p => p.follower) .filter(p => p) as User[]; - return { - data: users, - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return users; }); } - public static async getUserStatuses(user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, onlyMedia: boolean = false, excludeReplies: boolean = false, excludeReblogs: boolean = false, pinned: boolean = false, tagged: string | undefined, ctx: MastoContext): Promise> { + public static async getUserStatuses(user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, onlyMedia: boolean = false, excludeReplies: boolean = false, excludeReblogs: boolean = false, pinned: boolean = false, tagged: string | undefined, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const localUser = ctx.user as ILocalUser | null; if (tagged !== undefined) { //FIXME respect tagged - return { data: [] }; + return []; } const query = PaginationHelpers.makePaginationQuery( @@ -387,10 +381,10 @@ export class UserHelpers { query.setParameters({ userId: user.id }); - return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined); + return PaginationHelpers.execQueryLinkPagination(query, limit, minId !== undefined, ctx); } - public static async getUserBookmarks(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise> { + public static async getUserBookmarks(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const localUser = ctx.user as ILocalUser; @@ -407,14 +401,12 @@ export class UserHelpers { return PaginationHelpers.execQuery(query, limit, minId !== undefined) .then(res => { - return { - data: res.map(p => p.note as Note), - pagination: generatePaginationData(res.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(res.map(p => p.id), limit, minId !== undefined); + return res.map(p => p.note as Note); }); } - public static async getUserFavorites(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise> { + public static async getUserFavorites(maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, ctx: MastoContext): Promise { if (limit > 40) limit = 40; const localUser = ctx.user as ILocalUser; @@ -431,22 +423,20 @@ export class UserHelpers { return PaginationHelpers.execQuery(query, limit, minId !== undefined) .then(res => { - return { - data: res.map(p => p.note as Note), - pagination: generatePaginationData(res.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(res.map(p => p.id), limit, minId !== undefined); + return res.map(p => p.note as Note); }); } - private static async getUserRelationships(type: RelationshipType, user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + private static async getUserRelationships(type: RelationshipType, user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { if (limit > 80) limit = 80; const localUser = ctx.user as ILocalUser | null; const profile = await UserProfiles.findOneByOrFail({ userId: user.id }); if (profile.ffVisibility === "private") { - if (!localUser || user.id !== localUser.id) return { data: [] }; + if (!localUser || user.id !== localUser.id) return []; } else if (profile.ffVisibility === "followers") { - if (!localUser) return { data: [] }; + if (!localUser) return []; if (user.id !== localUser.id) { const isFollowed = await Followings.exist({ where: { @@ -454,7 +444,7 @@ export class UserHelpers { followerId: localUser.id, }, }); - if (!isFollowed) return { data: [] }; + if (!isFollowed) return []; } } @@ -476,18 +466,16 @@ export class UserHelpers { return query.take(limit).getMany().then(p => { if (minId !== undefined) p = p.reverse(); - return { - data: p.map(p => type === "followers" ? p.follower : p.followee).filter(p => p) as User[], - pagination: generatePaginationData(p.map(p => p.id), limit, minId !== undefined) - }; + ctx.pagination = generatePaginationData(p.map(p => p.id), limit, minId !== undefined); + return p.map(p => type === "followers" ? p.follower : p.followee).filter(p => p) as User[]; }); } - public static async getUserFollowers(user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getUserFollowers(user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { return this.getUserRelationships('followers', user, maxId, sinceId, minId, limit, ctx); } - public static async getUserFollowing(user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise> { + public static async getUserFollowing(user: User, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40, ctx: MastoContext): Promise { return this.getUserRelationships('following', user, maxId, sinceId, minId, limit, ctx); } diff --git a/packages/backend/src/server/api/mastodon/middleware/auth.ts b/packages/backend/src/server/api/mastodon/middleware/auth.ts index c656d9f7a..da6ffd617 100644 --- a/packages/backend/src/server/api/mastodon/middleware/auth.ts +++ b/packages/backend/src/server/api/mastodon/middleware/auth.ts @@ -27,4 +27,4 @@ export function auth(required: boolean, scopes: string[] = []) { await next(); }; -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/middleware/cache.ts b/packages/backend/src/server/api/mastodon/middleware/cache.ts index 6c89c2e7b..ab338c37b 100644 --- a/packages/backend/src/server/api/mastodon/middleware/cache.ts +++ b/packages/backend/src/server/api/mastodon/middleware/cache.ts @@ -4,4 +4,4 @@ import { UserHelpers } from "@/server/api/mastodon/helpers/user.js"; export async function CacheMiddleware(ctx: MastoContext, next: () => Promise) { ctx.cache = UserHelpers.getFreshAccountCache(); await next(); -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/middleware/catch-errors.ts b/packages/backend/src/server/api/mastodon/middleware/catch-errors.ts index b843a6fb5..fb15f0278 100644 --- a/packages/backend/src/server/api/mastodon/middleware/catch-errors.ts +++ b/packages/backend/src/server/api/mastodon/middleware/catch-errors.ts @@ -45,4 +45,4 @@ export async function CatchErrorsMiddleware(ctx: MastoContext, next: () => Promi ctx.body = { error: e.message ?? e }; return; } -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/middleware/normalize-query.ts b/packages/backend/src/server/api/mastodon/middleware/normalize-query.ts index 9c073c6a3..bc73f4ff9 100644 --- a/packages/backend/src/server/api/mastodon/middleware/normalize-query.ts +++ b/packages/backend/src/server/api/mastodon/middleware/normalize-query.ts @@ -9,4 +9,4 @@ export async function NormalizeQueryMiddleware(ctx: MastoContext, next: () => Pr } } await next(); -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/middleware/pagination.ts b/packages/backend/src/server/api/mastodon/middleware/pagination.ts index b9ecb06f8..988b71015 100644 --- a/packages/backend/src/server/api/mastodon/middleware/pagination.ts +++ b/packages/backend/src/server/api/mastodon/middleware/pagination.ts @@ -8,11 +8,6 @@ type PaginationData = { minId?: string | undefined; } -export type LinkPaginationObject = { - data: T; - pagination?: PaginationData; -} - export async function PaginationMiddleware(ctx: MastoContext, next: () => Promise) { await next(); if (!ctx.pagination) return; @@ -40,4 +35,4 @@ export function generatePaginationData(ids: string[], limit: number, reverse: bo maxId: ids.at(reverse ? 0 : -1), minId: ids.at(reverse ? -1 : 0) } -} \ No newline at end of file +} diff --git a/packages/backend/src/server/api/mastodon/middleware/set-headers.ts b/packages/backend/src/server/api/mastodon/middleware/set-headers.ts index 0e073e673..a56d95af4 100644 --- a/packages/backend/src/server/api/mastodon/middleware/set-headers.ts +++ b/packages/backend/src/server/api/mastodon/middleware/set-headers.ts @@ -7,4 +7,4 @@ const headers = { export async function SetHeadersMiddleware(ctx: MastoContext, next: () => Promise) { ctx.set(headers); await next(); -} \ No newline at end of file +}