diff --git a/database/entities/DBStatus.ts b/database/entities/DBStatus.ts new file mode 100644 index 00000000..e28df093 --- /dev/null +++ b/database/entities/DBStatus.ts @@ -0,0 +1,73 @@ +import { getConfig } from "@config"; +import { + BaseEntity, + Column, + CreateDateColumn, + Entity, + ManyToOne, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from "typeorm"; +import { Status } from "~types/entities/status"; +import { DBUser } from "./DBUser"; + +const config = getConfig(); + +@Entity({ + name: "statuses", +}) +export class DBStatus extends BaseEntity { + @PrimaryGeneratedColumn("uuid") + id!: string; + + @ManyToOne(() => DBUser, (user) => user.id) + account!: DBUser; + + @CreateDateColumn() + created_at!: Date; + + @UpdateDateColumn() + updated_at!: Date; + + @ManyToOne(() => DBStatus, (status) => status.id, { + nullable: true, + }) + reblog?: DBStatus; + + @Column("boolean") + isReblog!: boolean; + + toAPI(): Status { + return { + account: this.account.toAPI(), + application: null, + bookmarked: false, + created_at: this.created_at.toISOString(), + emojis: [], + favourited: false, + favourites_count: 0, + id: this.id, + in_reply_to_account_id: null, + in_reply_to_id: null, + language: null, + media_attachments: [], + mentions: [], + muted: false, + pinned: false, + poll: null, + reblog: this.isReblog ? this.reblog?.toAPI() ?? null : null, + reblogged: false, + reblogs_count: 0, + replies_count: 0, + sensitive: false, + spoiler_text: "", + tags: [], + card: null, + content: "", + uri: `${config.http.base_url}/@${this.account.username}/${this.id}`, + url: `${config.http.base_url}/@${this.account.username}/${this.id}`, + visibility: "public", + quote: null, + }; + } +} diff --git a/database/entities/User.ts b/database/entities/DBUser.ts similarity index 95% rename from database/entities/User.ts rename to database/entities/DBUser.ts index 0b872192..0c4ca44f 100644 --- a/database/entities/User.ts +++ b/database/entities/DBUser.ts @@ -7,7 +7,7 @@ const config = getConfig(); @Entity({ name: "users", }) -export class User extends BaseEntity { +export class DBUser extends BaseEntity { @PrimaryGeneratedColumn("uuid") id!: string; @@ -35,7 +35,7 @@ export class User extends BaseEntity { @UpdateDateColumn() updated_at!: Date; - toAccount(): Account { + toAPI(): Account { return { acct: `@${this.username}@${getHost()}`, avatar: "", diff --git a/server/api/v1/accounts/[id]/index.ts b/server/api/v1/accounts/[id]/index.ts index 630da01c..c7253c64 100644 --- a/server/api/v1/accounts/[id]/index.ts +++ b/server/api/v1/accounts/[id]/index.ts @@ -1,6 +1,6 @@ import { jsonResponse } from "@response"; import { MatchedRoute } from "bun"; -import { User } from "~database/entities/User"; +import { DBUser } from "~database/entities/DBUser"; export default async ( req: Request, @@ -8,19 +8,17 @@ export default async ( ): Promise => { const id = matchedRoute.params.id; - const user = await User.findOneBy({ + const user = await DBUser.findOneBy({ id, }); if (!user) return jsonResponse( { - statusText: "User not found", + error: "User not found", }, 404 ); - return jsonResponse({ - id, - }); + return jsonResponse(user.toAPI()); }; diff --git a/server/api/v1/accounts/[id]/statuses.ts b/server/api/v1/accounts/[id]/statuses.ts new file mode 100644 index 00000000..cdc08534 --- /dev/null +++ b/server/api/v1/accounts/[id]/statuses.ts @@ -0,0 +1,53 @@ +import { jsonResponse } from "@response"; +import { MatchedRoute } from "bun"; +import { DBStatus } from "~database/entities/DBStatus"; +import { DBUser } from "~database/entities/DBUser"; + +export default async ( + req: Request, + matchedRoute: MatchedRoute +): Promise => { + const id = matchedRoute.params.id; + + const { + limit, + exclude_reblogs, + }: { + max_id?: string; + since_id?: string; + min_id?: string; + limit?: number; + only_media?: boolean; + exclude_replies?: boolean; + exclude_reblogs?: boolean; + pinned?: boolean; + tagged?: string; + } = matchedRoute.query; + + const user = await DBUser.findOneBy({ + id, + }); + + if (!user) + return jsonResponse( + { + error: "User not found", + }, + 404 + ); + + const statuses = await DBStatus.find({ + where: { + account: { + id: user.id, + }, + isReblog: !exclude_reblogs, + }, + order: { + created_at: "DESC", + }, + take: limit ?? 20, + }); + + return jsonResponse(statuses.map((status) => status.toAPI())); +}; diff --git a/types/entity.ts b/types/entity.ts deleted file mode 100644 index dcafdfe7..00000000 --- a/types/entity.ts +++ /dev/null @@ -1,39 +0,0 @@ -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// - -export default MastodonEntity