diff --git a/.eslintrc.cjs b/.eslintrc.cjs index a8f1a26c..fe8ec85f 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -16,5 +16,7 @@ module.exports = { "@typescript-eslint/no-unsafe-assignment": "off", "@typescript-eslint/no-unsafe-argument": "off", "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/consistent-type-exports": "error", + "@typescript-eslint/consistent-type-imports": "error" }, }; diff --git a/README.md b/README.md index 8155d2bf..243e176d 100644 --- a/README.md +++ b/README.md @@ -154,16 +154,20 @@ Working endpoints are: - `/oauth/authorize` - `/oauth/token` -Endpoints left: +Tests needed but completed: - `/api/v2/media` - `/api/v1/media/:id` +- `/api/v1/blocks` +- `/api/v1/mutes` + + +Endpoints left: + - `/api/v1/reports` - `/api/v1/accounts/:id/lists` - `/api/v1/favourites` - `/api/v1/accounts/:id/following` -- `/api/v1/mutes` -- `/api/v1/blocks` - `/api/v1/follow_requests` - `/api/v1/follow_requests/:account_id/authorize` - `/api/v1/follow_requests/:account_id/reject` diff --git a/classes/activitypub.ts b/classes/activitypub.ts index 2927a1e5..3ce4c8df 100644 --- a/classes/activitypub.ts +++ b/classes/activitypub.ts @@ -1,4 +1,4 @@ -import { APActivity, APActor } from "activitypub-types"; +import type { APActivity, APActor } from "activitypub-types"; export class RemoteActor { private actorData: APActor | null; diff --git a/classes/media.ts b/classes/media.ts index 60b1b00c..9d40ebe0 100644 --- a/classes/media.ts +++ b/classes/media.ts @@ -1,10 +1,10 @@ +import type { GetObjectCommandOutput } from "@aws-sdk/client-s3"; import { GetObjectCommand, - GetObjectCommandOutput, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3"; -import { ConfigType } from "@config"; +import type { ConfigType } from "@config"; import sharp from "sharp"; import { exists, mkdir } from "fs/promises"; class MediaBackend { diff --git a/database/entities/Application.ts b/database/entities/Application.ts index dca8dad5..5bd4f219 100644 --- a/database/entities/Application.ts +++ b/database/entities/Application.ts @@ -1,5 +1,5 @@ -import { APIApplication } from "~types/entities/application"; -import { Application } from "@prisma/client"; +import type { APIApplication } from "~types/entities/application"; +import type { Application } from "@prisma/client"; import { client } from "~database/datasource"; /** diff --git a/database/entities/Attachment.ts b/database/entities/Attachment.ts index 7b8cc853..e85bdeac 100644 --- a/database/entities/Attachment.ts +++ b/database/entities/Attachment.ts @@ -1,7 +1,7 @@ -import { ConfigType } from "@config"; -import { Attachment } from "@prisma/client"; -import { APIAsyncAttachment } from "~types/entities/async_attachment"; -import { APIAttachment } from "~types/entities/attachment"; +import type { ConfigType } from "@config"; +import type { Attachment } from "@prisma/client"; +import type { APIAsyncAttachment } from "~types/entities/async_attachment"; +import type { APIAttachment } from "~types/entities/attachment"; export const attachmentToAPI = ( attachment: Attachment diff --git a/database/entities/Emoji.ts b/database/entities/Emoji.ts index b9ebfac5..55511503 100644 --- a/database/entities/Emoji.ts +++ b/database/entities/Emoji.ts @@ -1,7 +1,7 @@ -import { APIEmoji } from "~types/entities/emoji"; -import { Emoji as LysandEmoji } from "~types/lysand/extensions/org.lysand/custom_emojis"; +import type { APIEmoji } from "~types/entities/emoji"; +import type { Emoji as LysandEmoji } from "~types/lysand/extensions/org.lysand/custom_emojis"; import { client } from "~database/datasource"; -import { Emoji } from "@prisma/client"; +import type { Emoji } from "@prisma/client"; /** * Represents an emoji entity in the database. diff --git a/database/entities/Instance.ts b/database/entities/Instance.ts index 2d6d7152..46d43a84 100644 --- a/database/entities/Instance.ts +++ b/database/entities/Instance.ts @@ -1,6 +1,6 @@ -import { Instance } from "@prisma/client"; +import type { Instance } from "@prisma/client"; import { client } from "~database/datasource"; -import { ServerMetadata } from "~types/lysand/Object"; +import type { ServerMetadata } from "~types/lysand/Object"; /** * Represents an instance in the database. diff --git a/database/entities/Like.ts b/database/entities/Like.ts index 1d0d7ceb..d173aef1 100644 --- a/database/entities/Like.ts +++ b/database/entities/Like.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { Like as LysandLike } from "~types/lysand/Object"; +import type { Like as LysandLike } from "~types/lysand/Object"; import { getConfig } from "@config"; -import { Like } from "@prisma/client"; +import type { Like } from "@prisma/client"; /** * Represents a Like entity in the database. diff --git a/database/entities/Notification.ts b/database/entities/Notification.ts new file mode 100644 index 00000000..bdef3cb3 --- /dev/null +++ b/database/entities/Notification.ts @@ -0,0 +1,23 @@ +import type { Notification } from "@prisma/client"; +import type { APINotification } from "~types/entities/notification"; +import { type StatusWithRelations, statusToAPI } from "./Status"; +import { type UserWithRelations, userToAPI } from "./User"; + +export type NotificationWithRelations = Notification & { + status: StatusWithRelations | null; + account: UserWithRelations; +}; + +export const notificationToAPI = async ( + notification: NotificationWithRelations +): Promise => { + return { + account: userToAPI(notification.account), + created_at: notification.createdAt.toISOString(), + id: notification.id, + type: notification.type, + status: notification.status + ? await statusToAPI(notification.status) + : undefined, + }; +}; diff --git a/database/entities/Object.ts b/database/entities/Object.ts index aae884d2..c01dc549 100644 --- a/database/entities/Object.ts +++ b/database/entities/Object.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { LysandObject } from "@prisma/client"; +import type { LysandObject } from "@prisma/client"; import { client } from "~database/datasource"; -import { LysandObjectType } from "~types/lysand/Object"; +import type { LysandObjectType } from "~types/lysand/Object"; /** * Represents a Lysand object in the database. diff --git a/database/entities/Relationship.ts b/database/entities/Relationship.ts index ea932329..5f290c5d 100644 --- a/database/entities/Relationship.ts +++ b/database/entities/Relationship.ts @@ -1,5 +1,5 @@ -import { Relationship, User } from "@prisma/client"; -import { APIRelationship } from "~types/entities/relationship"; +import type { Relationship, User } from "@prisma/client"; +import type { APIRelationship } from "~types/entities/relationship"; import { client } from "~database/datasource"; /** diff --git a/database/entities/Status.ts b/database/entities/Status.ts index 5de7546e..1708e788 100644 --- a/database/entities/Status.ts +++ b/database/entities/Status.ts @@ -1,17 +1,17 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { getConfig } from "@config"; +import type { UserWithRelations } from "./User"; import { - UserWithRelations, fetchRemoteUser, parseMentionsUris, userRelations, userToAPI, } from "./User"; import { client } from "~database/datasource"; -import { LysandPublication, Note } from "~types/lysand/Object"; +import type { LysandPublication, Note } from "~types/lysand/Object"; import { htmlToText } from "html-to-text"; import { getBestContentType } from "@content_types"; -import { +import type { Application, Emoji, Instance, @@ -21,7 +21,7 @@ import { User, } from "@prisma/client"; import { emojiToAPI, emojiToLysand, parseEmojis } from "./Emoji"; -import { APIStatus } from "~types/entities/status"; +import type { APIStatus } from "~types/entities/status"; import { applicationToAPI } from "./Application"; const config = getConfig(); diff --git a/database/entities/User.ts b/database/entities/User.ts index 23a5d4c0..66252007 100644 --- a/database/entities/User.ts +++ b/database/entities/User.ts @@ -1,8 +1,9 @@ -import { ConfigType, getConfig } from "@config"; -import { APIAccount } from "~types/entities/account"; -import { User as LysandUser } from "~types/lysand/Object"; +import type { ConfigType } from "@config"; +import { getConfig } from "@config"; +import type { APIAccount } from "~types/entities/account"; +import type { User as LysandUser } from "~types/lysand/Object"; import { htmlToText } from "html-to-text"; -import { +import type { Emoji, Instance, Like, @@ -13,7 +14,7 @@ import { import { client } from "~database/datasource"; import { addEmojiIfNotExists, emojiToAPI, emojiToLysand } from "./Emoji"; import { addInstanceIfNotExists } from "./Instance"; -import { APISource } from "~types/entities/source"; +import type { APISource } from "~types/entities/source"; export interface AuthData { user: UserWithRelations | null; diff --git a/index.ts b/index.ts index ec6079ad..88fc7000 100644 --- a/index.ts +++ b/index.ts @@ -1,15 +1,16 @@ import { getConfig } from "@config"; import { jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import chalk from "chalk"; import { appendFile } from "fs/promises"; import { matches } from "ip-matching"; import "reflect-metadata"; -import { AuthData, getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { AuthData } from "~database/entities/User"; +import { getFromRequest } from "~database/entities/User"; +import type { APIRouteMeta } from "~types/api"; import { mkdir } from "fs/promises"; import { client } from "~database/datasource"; -import { PrismaClientInitializationError } from "@prisma/client/runtime/library"; +import type { PrismaClientInitializationError } from "@prisma/client/runtime/library"; import { HookTypes, Server } from "~plugins/types"; const server = new Server(); diff --git a/plugins/test.plugin.ts b/plugins/test.plugin.ts index 96801411..2b279bb7 100644 --- a/plugins/test.plugin.ts +++ b/plugins/test.plugin.ts @@ -1,4 +1,5 @@ -import { HookTypes, Server } from "./types"; +import type { Server } from "./types"; +import { HookTypes } from "./types"; const registerPlugin = (server: Server) => { server.on(HookTypes.OnPostCreate, (req, newPost, author) => { diff --git a/plugins/types.ts b/plugins/types.ts index 285cb18d..b63f527f 100644 --- a/plugins/types.ts +++ b/plugins/types.ts @@ -1,7 +1,7 @@ import EventEmitter from "eventemitter3"; -import { StatusWithRelations } from "~database/entities/Status"; -import { UserWithRelations } from "~database/entities/User"; -import { LysandObjectType } from "~types/lysand/Object"; +import type { StatusWithRelations } from "~database/entities/Status"; +import type { UserWithRelations } from "~database/entities/User"; +import type { LysandObjectType } from "~types/lysand/Object"; export enum HookTypes { /** diff --git a/prisma/migrations/20231123022010_add_attachments/migration.sql b/prisma/migrations/20231123022010_add_attachments/migration.sql new file mode 100644 index 00000000..49152c59 --- /dev/null +++ b/prisma/migrations/20231123022010_add_attachments/migration.sql @@ -0,0 +1,22 @@ +-- CreateTable +CREATE TABLE "Attachment" ( + "id" UUID NOT NULL DEFAULT uuid_generate_v7(), + "url" TEXT NOT NULL, + "remote_url" TEXT, + "thumbnail_url" TEXT, + "mime_type" TEXT NOT NULL, + "description" TEXT, + "blurhash" TEXT, + "sha256" TEXT, + "fps" INTEGER, + "duration" INTEGER, + "width" INTEGER, + "height" INTEGER, + "size" INTEGER, + "statusId" UUID, + + CONSTRAINT "Attachment_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Attachment" ADD CONSTRAINT "Attachment_statusId_fkey" FOREIGN KEY ("statusId") REFERENCES "Status"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index bd29f93f..86874950 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -92,36 +92,37 @@ model Relationship { } model Status { - id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid - uri String @unique - author User @relation("UserStatuses", fields: [authorId], references: [id], onDelete: Cascade) - authorId String @db.Uuid - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - reblog Status? @relation("StatusToStatus", fields: [reblogId], references: [id], onDelete: Cascade) - reblogId String? @db.Uuid - isReblog Boolean - content String @default("") - contentType String @default("text/plain") - visibility String - inReplyToPost Status? @relation("StatusToStatusReply", fields: [inReplyToPostId], references: [id], onDelete: SetNull) - inReplyToPostId String? @db.Uuid - quotingPost Status? @relation("StatusToStatusQuote", fields: [quotingPostId], references: [id], onDelete: SetNull) - quotingPostId String? @db.Uuid - instance Instance? @relation(fields: [instanceId], references: [id], onDelete: Cascade) - instanceId String? @db.Uuid - sensitive Boolean - spoilerText String @default("") - application Application? @relation(fields: [applicationId], references: [id], onDelete: SetNull) - applicationId String? @db.Uuid - emojis Emoji[] @relation - mentions User[] - likes Like[] @relation("LikedToStatus") - reblogs Status[] @relation("StatusToStatus") - replies Status[] @relation("StatusToStatusReply") - quotes Status[] @relation("StatusToStatusQuote") - pinnedBy User[] @relation("UserPinnedNotes") - attachments Attachment[] + id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid + uri String @unique + author User @relation("UserStatuses", fields: [authorId], references: [id], onDelete: Cascade) + authorId String @db.Uuid + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + reblog Status? @relation("StatusToStatus", fields: [reblogId], references: [id], onDelete: Cascade) + reblogId String? @db.Uuid + isReblog Boolean + content String @default("") + contentType String @default("text/plain") + visibility String + inReplyToPost Status? @relation("StatusToStatusReply", fields: [inReplyToPostId], references: [id], onDelete: SetNull) + inReplyToPostId String? @db.Uuid + quotingPost Status? @relation("StatusToStatusQuote", fields: [quotingPostId], references: [id], onDelete: SetNull) + quotingPostId String? @db.Uuid + instance Instance? @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String? @db.Uuid + sensitive Boolean + spoilerText String @default("") + application Application? @relation(fields: [applicationId], references: [id], onDelete: SetNull) + applicationId String? @db.Uuid + emojis Emoji[] @relation + mentions User[] + likes Like[] @relation("LikedToStatus") + reblogs Status[] @relation("StatusToStatus") + replies Status[] @relation("StatusToStatusReply") + quotes Status[] @relation("StatusToStatusQuote") + pinnedBy User[] @relation("UserPinnedNotes") + attachments Attachment[] + relatedNotifications Notification[] } model Token { @@ -138,21 +139,33 @@ model Token { } model Attachment { - id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid - url String - remote_url String? + id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid + url String + remote_url String? thumbnail_url String? - mime_type String - description String? - blurhash String? - sha256 String? - fps Int? - duration Int? - width Int? - height Int? - size Int? - status Status? @relation(fields: [statusId], references: [id], onDelete: Cascade) - statusId String? @db.Uuid + mime_type String + description String? + blurhash String? + sha256 String? + fps Int? + duration Int? + width Int? + height Int? + size Int? + status Status? @relation(fields: [statusId], references: [id], onDelete: Cascade) + statusId String? @db.Uuid +} + +model Notification { + id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid + type String + createdAt DateTime @default(now()) + notified User @relation("NotificationToNotified", fields: [notifiedId], references: [id], onDelete: Cascade) + notifiedId String @db.Uuid + account User @relation(fields: [accountId], references: [id], onDelete: Cascade) + accountId String @db.Uuid + status Status? @relation(fields: [statusId], references: [id], onDelete: Cascade) + statusId String? @db.Uuid } model User { @@ -186,4 +199,6 @@ model User { tokens Token[] // One to many relation with Token likes Like[] @relation("UserLiked") // One to many relation with Like statusesMentioned Status[] // Many to many relation with Status + notifications Notification[] // One to many relation with Notification + notified Notification[] @relation("NotificationToNotified") // One to many relation with Notification } diff --git a/server/api/api/v1/accounts/[id]/block.ts b/server/api/api/v1/accounts/[id]/block.ts index 9b04e1c6..e0e55252 100644 --- a/server/api/api/v1/accounts/[id]/block.ts +++ b/server/api/api/v1/accounts/[id]/block.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/follow.ts b/server/api/api/v1/accounts/[id]/follow.ts index 62da3cf8..3d0b37d8 100644 --- a/server/api/api/v1/accounts/[id]/follow.ts +++ b/server/api/api/v1/accounts/[id]/follow.ts @@ -1,6 +1,6 @@ import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/index.ts b/server/api/api/v1/accounts/[id]/index.ts index 12bfc986..b1e609c4 100644 --- a/server/api/api/v1/accounts/[id]/index.ts +++ b/server/api/api/v1/accounts/[id]/index.ts @@ -1,7 +1,7 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; +import type { UserWithRelations } from "~database/entities/User"; import { - UserWithRelations, getFromRequest, userRelations, userToAPI, diff --git a/server/api/api/v1/accounts/[id]/mute.ts b/server/api/api/v1/accounts/[id]/mute.ts index 455b849f..54dba828 100644 --- a/server/api/api/v1/accounts/[id]/mute.ts +++ b/server/api/api/v1/accounts/[id]/mute.ts @@ -1,6 +1,6 @@ import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/note.ts b/server/api/api/v1/accounts/[id]/note.ts index 37659fd9..d67d6bda 100644 --- a/server/api/api/v1/accounts/[id]/note.ts +++ b/server/api/api/v1/accounts/[id]/note.ts @@ -1,6 +1,6 @@ import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/pin.ts b/server/api/api/v1/accounts/[id]/pin.ts index 1909b927..04cdb68e 100644 --- a/server/api/api/v1/accounts/[id]/pin.ts +++ b/server/api/api/v1/accounts/[id]/pin.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/remove_from_followers.ts b/server/api/api/v1/accounts/[id]/remove_from_followers.ts index 3f7fd3a9..94e2ddb0 100644 --- a/server/api/api/v1/accounts/[id]/remove_from_followers.ts +++ b/server/api/api/v1/accounts/[id]/remove_from_followers.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/statuses.ts b/server/api/api/v1/accounts/[id]/statuses.ts index 7196e3e8..ec261e81 100644 --- a/server/api/api/v1/accounts/[id]/statuses.ts +++ b/server/api/api/v1/accounts/[id]/statuses.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { statusAndUserRelations, statusToAPI } from "~database/entities/Status"; import { userRelations } from "~database/entities/User"; import { applyConfig } from "@api"; diff --git a/server/api/api/v1/accounts/[id]/unblock.ts b/server/api/api/v1/accounts/[id]/unblock.ts index c4833405..ea0139c2 100644 --- a/server/api/api/v1/accounts/[id]/unblock.ts +++ b/server/api/api/v1/accounts/[id]/unblock.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/unfollow.ts b/server/api/api/v1/accounts/[id]/unfollow.ts index 1ef88df3..de6ba90a 100644 --- a/server/api/api/v1/accounts/[id]/unfollow.ts +++ b/server/api/api/v1/accounts/[id]/unfollow.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/unmute.ts b/server/api/api/v1/accounts/[id]/unmute.ts index 3cdf3709..5a498a24 100644 --- a/server/api/api/v1/accounts/[id]/unmute.ts +++ b/server/api/api/v1/accounts/[id]/unmute.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/accounts/[id]/unpin.ts b/server/api/api/v1/accounts/[id]/unpin.ts index bcc86ce8..ee52384e 100644 --- a/server/api/api/v1/accounts/[id]/unpin.ts +++ b/server/api/api/v1/accounts/[id]/unpin.ts @@ -1,5 +1,5 @@ import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { createNewRelationship, relationshipToAPI, diff --git a/server/api/api/v1/blocks/index.ts b/server/api/api/v1/blocks/index.ts new file mode 100644 index 00000000..96a68b11 --- /dev/null +++ b/server/api/api/v1/blocks/index.ts @@ -0,0 +1,40 @@ +import { errorResponse, jsonResponse } from "@response"; +import { + getFromRequest, + userRelations, + userToAPI, +} from "~database/entities/User"; +import { applyConfig } from "@api"; +import { client } from "~database/datasource"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + route: "/api/v1/blocks", + ratelimits: { + max: 100, + duration: 60, + }, + auth: { + required: true, + }, +}); + +export default async (req: Request): Promise => { + const { user } = await getFromRequest(req); + + if (!user) return errorResponse("Unauthorized", 401); + + const blocks = await client.user.findMany({ + where: { + relationshipSubjects: { + every: { + ownerId: user.id, + blocking: true, + }, + }, + }, + include: userRelations, + }); + + return jsonResponse(blocks.map(u => userToAPI(u))); +}; diff --git a/server/api/api/v1/media/[id]/index.ts b/server/api/api/v1/media/[id]/index.ts index 386974c9..cc4c8e3c 100644 --- a/server/api/api/v1/media/[id]/index.ts +++ b/server/api/api/v1/media/[id]/index.ts @@ -2,11 +2,11 @@ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; import { client } from "~database/datasource"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; import { uploadFile } from "~classes/media"; import { getConfig } from "@config"; import { attachmentToAPI, getUrl } from "~database/entities/Attachment"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { parseRequest } from "@request"; export const meta: APIRouteMeta = applyConfig({ diff --git a/server/api/api/v1/mutes/index.ts b/server/api/api/v1/mutes/index.ts new file mode 100644 index 00000000..5e32d4a2 --- /dev/null +++ b/server/api/api/v1/mutes/index.ts @@ -0,0 +1,40 @@ +import { errorResponse, jsonResponse } from "@response"; +import { + getFromRequest, + userRelations, + userToAPI, +} from "~database/entities/User"; +import { applyConfig } from "@api"; +import { client } from "~database/datasource"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + route: "/api/v1/mutes", + ratelimits: { + max: 100, + duration: 60, + }, + auth: { + required: true, + }, +}); + +export default async (req: Request): Promise => { + const { user } = await getFromRequest(req); + + if (!user) return errorResponse("Unauthorized", 401); + + const blocks = await client.user.findMany({ + where: { + relationshipSubjects: { + every: { + ownerId: user.id, + muting: true, + }, + }, + }, + include: userRelations, + }); + + return jsonResponse(blocks.map(u => userToAPI(u))); +}; diff --git a/server/api/api/v1/notifications/index.ts b/server/api/api/v1/notifications/index.ts new file mode 100644 index 00000000..f1480d14 --- /dev/null +++ b/server/api/api/v1/notifications/index.ts @@ -0,0 +1,83 @@ +import { errorResponse, jsonResponse } from "@response"; +import { getFromRequest, userRelations } from "~database/entities/User"; +import { applyConfig } from "@api"; +import { client } from "~database/datasource"; +import { statusAndUserRelations } from "~database/entities/Status"; +import { parseRequest } from "@request"; +import { notificationToAPI } from "~database/entities/Notification"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + route: "/api/v1/notifications", + ratelimits: { + max: 100, + duration: 60, + }, + auth: { + required: true, + }, +}); + +export default async (req: Request): Promise => { + const { user } = await getFromRequest(req); + + if (!user) return errorResponse("Unauthorized", 401); + + const { + account_id, + exclude_types, + limit = 15, + max_id, + min_id, + since_id, + types, + } = await parseRequest<{ + max_id?: string; + since_id?: string; + min_id?: string; + limit?: number; + exclude_types?: string[]; + types?: string[]; + account_id?: string; + }>(req); + + if (limit > 30) return errorResponse("Limit too high", 400); + + if (limit <= 0) return errorResponse("Limit too low", 400); + + if (types && exclude_types) { + return errorResponse("Can't use both types and exclude_types", 400); + } + + const notifications = await client.notification.findMany({ + where: { + notifiedId: user.id, + id: { + lt: max_id, + gt: min_id, + gte: since_id, + }, + type: { + in: types, + notIn: exclude_types, + }, + accountId: account_id, + }, + include: { + account: { + include: userRelations, + }, + status: { + include: statusAndUserRelations, + }, + }, + orderBy: { + id: "asc", + }, + take: limit, + }); + + return jsonResponse( + await Promise.all(notifications.map(n => notificationToAPI(n))) + ); +}; diff --git a/server/api/api/v1/profile/avatar.ts b/server/api/api/v1/profile/avatar.ts index c3a8380b..c263718d 100644 --- a/server/api/api/v1/profile/avatar.ts +++ b/server/api/api/v1/profile/avatar.ts @@ -6,7 +6,7 @@ import { userRelations, userToAPI, } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["DELETE"], diff --git a/server/api/api/v1/profile/header.ts b/server/api/api/v1/profile/header.ts index 6d5c8543..9c9f9ec3 100644 --- a/server/api/api/v1/profile/header.ts +++ b/server/api/api/v1/profile/header.ts @@ -6,7 +6,7 @@ import { userRelations, userToAPI, } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["DELETE"], diff --git a/server/api/api/v1/statuses/[id]/context.ts b/server/api/api/v1/statuses/[id]/context.ts index d780de2a..5db9307e 100644 --- a/server/api/api/v1/statuses/[id]/context.ts +++ b/server/api/api/v1/statuses/[id]/context.ts @@ -1,6 +1,6 @@ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { getAncestors, @@ -9,7 +9,7 @@ import { statusToAPI, } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/api/v1/statuses/[id]/favourite.ts b/server/api/api/v1/statuses/[id]/favourite.ts index e8e60162..5341fd43 100644 --- a/server/api/api/v1/statuses/[id]/favourite.ts +++ b/server/api/api/v1/statuses/[id]/favourite.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -9,8 +9,8 @@ import { statusToAPI, } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; -import { APIStatus } from "~types/entities/status"; +import type { APIRouteMeta } from "~types/api"; +import type { APIStatus } from "~types/entities/status"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/api/v1/statuses/[id]/favourited_by.ts b/server/api/api/v1/statuses/[id]/favourited_by.ts index 16a5b15c..b94eb7dc 100644 --- a/server/api/api/v1/statuses/[id]/favourited_by.ts +++ b/server/api/api/v1/statuses/[id]/favourited_by.ts @@ -2,7 +2,7 @@ import { applyConfig } from "@api"; import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -13,7 +13,7 @@ import { userRelations, userToAPI, } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/api/v1/statuses/[id]/index.ts b/server/api/api/v1/statuses/[id]/index.ts index 7606deac..8fbc6bea 100644 --- a/server/api/api/v1/statuses/[id]/index.ts +++ b/server/api/api/v1/statuses/[id]/index.ts @@ -1,6 +1,6 @@ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -8,7 +8,7 @@ import { statusToAPI, } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["GET", "DELETE"], diff --git a/server/api/api/v1/statuses/[id]/reblog.ts b/server/api/api/v1/statuses/[id]/reblog.ts index 6c14d8e1..6a05273b 100644 --- a/server/api/api/v1/statuses/[id]/reblog.ts +++ b/server/api/api/v1/statuses/[id]/reblog.ts @@ -3,7 +3,7 @@ import { applyConfig } from "@api"; import { getConfig } from "@config"; import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -11,7 +11,7 @@ import { statusToAPI, } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/api/v1/statuses/[id]/reblogged_by.ts b/server/api/api/v1/statuses/[id]/reblogged_by.ts index 2401c666..dd9c5a06 100644 --- a/server/api/api/v1/statuses/[id]/reblogged_by.ts +++ b/server/api/api/v1/statuses/[id]/reblogged_by.ts @@ -2,7 +2,7 @@ import { applyConfig } from "@api"; import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -13,7 +13,7 @@ import { userRelations, userToAPI, } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/api/v1/statuses/[id]/unfavourite.ts b/server/api/api/v1/statuses/[id]/unfavourite.ts index 01038312..d893901a 100644 --- a/server/api/api/v1/statuses/[id]/unfavourite.ts +++ b/server/api/api/v1/statuses/[id]/unfavourite.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -9,8 +9,8 @@ import { statusToAPI, } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; -import { APIStatus } from "~types/entities/status"; +import type { APIRouteMeta } from "~types/api"; +import type { APIStatus } from "~types/entities/status"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/api/v1/statuses/[id]/unreblog.ts b/server/api/api/v1/statuses/[id]/unreblog.ts index 29c6d2b0..56a1f82a 100644 --- a/server/api/api/v1/statuses/[id]/unreblog.ts +++ b/server/api/api/v1/statuses/[id]/unreblog.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { isViewableByUser, @@ -9,8 +9,8 @@ import { statusToAPI, } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; -import { APIStatus } from "~types/entities/status"; +import type { APIRouteMeta } from "~types/api"; +import type { APIStatus } from "~types/entities/status"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/api/v1/statuses/index.ts b/server/api/api/v1/statuses/index.ts index 9fcdbe9c..c5946f82 100644 --- a/server/api/api/v1/statuses/index.ts +++ b/server/api/api/v1/statuses/index.ts @@ -6,18 +6,18 @@ import { getConfig } from "@config"; import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; import { sanitizeHtml } from "@sanitization"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { parse } from "marked"; import { client } from "~database/datasource"; import { getFromToken } from "~database/entities/Application"; +import type { StatusWithRelations } from "~database/entities/Status"; import { - StatusWithRelations, createNewStatus, statusAndUserRelations, statusToAPI, } from "~database/entities/Status"; -import { AuthData, UserWithRelations } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { AuthData, UserWithRelations } from "~database/entities/User"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/api/v1/timelines/home.ts b/server/api/api/v1/timelines/home.ts index b853f9b3..ee267abc 100644 --- a/server/api/api/v1/timelines/home.ts +++ b/server/api/api/v1/timelines/home.ts @@ -5,7 +5,7 @@ import { errorResponse, jsonResponse } from "@response"; import { client } from "~database/datasource"; import { statusAndUserRelations, statusToAPI } from "~database/entities/Status"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/api/v1/timelines/public.ts b/server/api/api/v1/timelines/public.ts index 2af03b1b..10bdd03c 100644 --- a/server/api/api/v1/timelines/public.ts +++ b/server/api/api/v1/timelines/public.ts @@ -3,7 +3,7 @@ import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; import { client } from "~database/datasource"; import { statusAndUserRelations, statusToAPI } from "~database/entities/Status"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/api/v2/media/index.ts b/server/api/api/v2/media/index.ts index 8a9f4b31..ed6140a8 100644 --- a/server/api/api/v2/media/index.ts +++ b/server/api/api/v2/media/index.ts @@ -3,7 +3,7 @@ import { errorResponse, jsonResponse } from "@response"; import { client } from "~database/datasource"; import { encode } from "blurhash"; import { getFromRequest } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; import sharp from "sharp"; import { uploadFile } from "~classes/media"; import { getConfig } from "@config"; diff --git a/server/api/auth/login/index.ts b/server/api/auth/login/index.ts index 85a67ab2..8a3b9b24 100644 --- a/server/api/auth/login/index.ts +++ b/server/api/auth/login/index.ts @@ -1,11 +1,11 @@ import { applyConfig } from "@api"; import { errorResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { randomBytes } from "crypto"; import { client } from "~database/datasource"; import { TokenType } from "~database/entities/Token"; import { userRelations } from "~database/entities/User"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const meta: APIRouteMeta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/oauth/authorize/index.ts b/server/api/oauth/authorize/index.ts index 0cf4c74d..219437d6 100644 --- a/server/api/oauth/authorize/index.ts +++ b/server/api/oauth/authorize/index.ts @@ -1,5 +1,5 @@ import { applyConfig } from "@api"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; export const meta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/object/[uuid]/index.ts b/server/api/object/[uuid]/index.ts index 902f9ecc..4d91f5b9 100644 --- a/server/api/object/[uuid]/index.ts +++ b/server/api/object/[uuid]/index.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { applyConfig } from "@api"; import { jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; export const meta = applyConfig({ allowedMethods: ["GET"], diff --git a/server/api/users/[uuid]/inbox/index.ts b/server/api/users/[uuid]/inbox/index.ts index 062cbae9..c04416b9 100644 --- a/server/api/users/[uuid]/inbox/index.ts +++ b/server/api/users/[uuid]/inbox/index.ts @@ -4,7 +4,7 @@ import { applyConfig } from "@api"; import { getConfig } from "@config"; import { getBestContentType } from "@content_types"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { parseEmojis } from "~database/entities/Emoji"; import { createFromObject } from "~database/entities/Object"; @@ -14,7 +14,11 @@ import { statusAndUserRelations, } from "~database/entities/Status"; import { parseMentionsUris, userRelations } from "~database/entities/User"; -import { LysandAction, LysandPublication, Patch } from "~types/lysand/Object"; +import type { + LysandAction, + LysandPublication, + Patch, +} from "~types/lysand/Object"; export const meta = applyConfig({ allowedMethods: ["POST"], diff --git a/server/api/users/[uuid]/index.ts b/server/api/users/[uuid]/index.ts index 8d37794b..d56dc905 100644 --- a/server/api/users/[uuid]/index.ts +++ b/server/api/users/[uuid]/index.ts @@ -3,7 +3,7 @@ import { applyConfig } from "@api"; import { getConfig } from "@config"; import { errorResponse, jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { userRelations, userToLysand } from "~database/entities/User"; diff --git a/server/api/users/[uuid]/outbox/index.ts b/server/api/users/[uuid]/outbox/index.ts index bc3d3559..b6b47750 100644 --- a/server/api/users/[uuid]/outbox/index.ts +++ b/server/api/users/[uuid]/outbox/index.ts @@ -1,5 +1,5 @@ import { jsonResponse } from "@response"; -import { MatchedRoute } from "bun"; +import type { MatchedRoute } from "bun"; import { getConfig, getHost } from "@config"; import { applyConfig } from "@api"; import { diff --git a/tests/api.test.ts b/tests/api.test.ts index 56e9e21e..1570393d 100644 --- a/tests/api.test.ts +++ b/tests/api.test.ts @@ -1,13 +1,16 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { getConfig } from "@config"; -import { Token } from "@prisma/client"; +import type { Token } from "@prisma/client"; import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { client } from "~database/datasource"; import { TokenType } from "~database/entities/Token"; -import { UserWithRelations, createNewLocalUser } from "~database/entities/User"; -import { APIEmoji } from "~types/entities/emoji"; -import { APIInstance } from "~types/entities/instance"; +import { + type UserWithRelations, + createNewLocalUser, +} from "~database/entities/User"; +import type { APIEmoji } from "~types/entities/emoji"; +import type { APIInstance } from "~types/entities/instance"; const config = getConfig(); diff --git a/tests/api/accounts.test.ts b/tests/api/accounts.test.ts index 2040b38d..425d28b5 100644 --- a/tests/api/accounts.test.ts +++ b/tests/api/accounts.test.ts @@ -1,14 +1,17 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { getConfig } from "@config"; -import { Token } from "@prisma/client"; +import type { Token } from "@prisma/client"; import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { client } from "~database/datasource"; import { TokenType } from "~database/entities/Token"; -import { UserWithRelations, createNewLocalUser } from "~database/entities/User"; -import { APIAccount } from "~types/entities/account"; -import { APIRelationship } from "~types/entities/relationship"; -import { APIStatus } from "~types/entities/status"; +import { + type UserWithRelations, + createNewLocalUser, +} from "~database/entities/User"; +import type { APIAccount } from "~types/entities/account"; +import type { APIRelationship } from "~types/entities/relationship"; +import type { APIStatus } from "~types/entities/status"; const config = getConfig(); diff --git a/tests/api/statuses.test.ts b/tests/api/statuses.test.ts index ef1e221c..9169d8a8 100644 --- a/tests/api/statuses.test.ts +++ b/tests/api/statuses.test.ts @@ -1,14 +1,17 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { getConfig } from "@config"; -import { Token } from "@prisma/client"; +import type { Token } from "@prisma/client"; import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { client } from "~database/datasource"; import { TokenType } from "~database/entities/Token"; -import { UserWithRelations, createNewLocalUser } from "~database/entities/User"; -import { APIAccount } from "~types/entities/account"; -import { APIContext } from "~types/entities/context"; -import { APIStatus } from "~types/entities/status"; +import { + type UserWithRelations, + createNewLocalUser, +} from "~database/entities/User"; +import type { APIAccount } from "~types/entities/account"; +import type { APIContext } from "~types/entities/context"; +import type { APIStatus } from "~types/entities/status"; const config = getConfig(); diff --git a/tests/entities/Media.test.ts b/tests/entities/Media.test.ts index befd57d6..df078d39 100644 --- a/tests/entities/Media.test.ts +++ b/tests/entities/Media.test.ts @@ -1,4 +1,4 @@ -import { ConfigType, getConfig } from "@config"; +import { type ConfigType, getConfig } from "@config"; import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import { LocalBackend, S3Backend } from "~classes/media"; import { unlink } from "fs/promises"; diff --git a/tests/oauth.test.ts b/tests/oauth.test.ts index 13adc8d9..6147d07b 100644 --- a/tests/oauth.test.ts +++ b/tests/oauth.test.ts @@ -1,5 +1,5 @@ import { getConfig } from "@config"; -import { Application, Token } from "@prisma/client"; +import type { Application, Token } from "@prisma/client"; import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { client } from "~database/datasource"; import { createNewLocalUser } from "~database/entities/User"; diff --git a/tsconfig.json b/tsconfig.json index c76781c9..1461898f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,6 +20,7 @@ "allowJs": true, "emitDecoratorMetadata": false, "experimentalDecorators": true, + "verbatimModuleSyntax": true, "types": [ "bun-types" // add Bun global ], diff --git a/types/entities/account.ts b/types/entities/account.ts index 311342c2..6348dc09 100644 --- a/types/entities/account.ts +++ b/types/entities/account.ts @@ -1,7 +1,7 @@ -import { APIEmoji } from "./emoji"; -import { APIField } from "./field"; -import { APIRole } from "./role"; -import { APISource } from "./source"; +import type { APIEmoji } from "./emoji"; +import type { APIField } from "./field"; +import type { APIRole } from "./role"; +import type { APISource } from "./source"; export interface APIAccount { id: string; diff --git a/types/entities/announcement.ts b/types/entities/announcement.ts index 73955b0b..33fa3a41 100644 --- a/types/entities/announcement.ts +++ b/types/entities/announcement.ts @@ -1,5 +1,5 @@ -import { APIEmoji } from "./emoji"; -import { APIStatusTag } from "./status"; +import type { APIEmoji } from "./emoji"; +import type { APIStatusTag } from "./status"; export interface APIAnnouncement { id: string; diff --git a/types/entities/async_attachment.ts b/types/entities/async_attachment.ts index e46cd2c9..9cb0f371 100644 --- a/types/entities/async_attachment.ts +++ b/types/entities/async_attachment.ts @@ -1,4 +1,4 @@ -import { APIMeta } from "./attachment"; +import type { APIMeta } from "./attachment"; export interface APIAsyncAttachment { id: string; diff --git a/types/entities/context.ts b/types/entities/context.ts index 79dfeac3..160a2b5a 100644 --- a/types/entities/context.ts +++ b/types/entities/context.ts @@ -1,4 +1,4 @@ -import { APIStatus } from "./status"; +import type { APIStatus } from "./status"; export interface APIContext { ancestors: APIStatus[]; diff --git a/types/entities/conversation.ts b/types/entities/conversation.ts index ef05c835..ac7a10ab 100644 --- a/types/entities/conversation.ts +++ b/types/entities/conversation.ts @@ -1,5 +1,5 @@ -import { APIAccount } from "./account"; -import { APIStatus } from "./status"; +import type { APIAccount } from "./account"; +import type { APIStatus } from "./status"; export interface APIConversation { id: string; diff --git a/types/entities/instance.ts b/types/entities/instance.ts index ba3c270e..2194f258 100644 --- a/types/entities/instance.ts +++ b/types/entities/instance.ts @@ -1,6 +1,6 @@ -import { APIAccount } from "./account"; -import { APIStats } from "./stats"; -import { APIURLs } from "./urls"; +import type { APIAccount } from "./account"; +import type { APIStats } from "./stats"; +import type { APIURLs } from "./urls"; export interface APIInstance { uri: string; diff --git a/types/entities/notification.ts b/types/entities/notification.ts index 6e8b4288..a9766473 100644 --- a/types/entities/notification.ts +++ b/types/entities/notification.ts @@ -1,5 +1,5 @@ -import { APIAccount } from "./account"; -import { APIStatus } from "./status"; +import type { APIAccount } from "./account"; +import type { APIStatus } from "./status"; export interface APINotification { account: APIAccount; diff --git a/types/entities/poll.ts b/types/entities/poll.ts index 1de2bf1d..9242eab3 100644 --- a/types/entities/poll.ts +++ b/types/entities/poll.ts @@ -1,4 +1,4 @@ -import { APIPollOption } from "./poll_option"; +import type { APIPollOption } from "./poll_option"; export interface APIPoll { id: string; diff --git a/types/entities/report.ts b/types/entities/report.ts index efc7d3ff..28d7d222 100644 --- a/types/entities/report.ts +++ b/types/entities/report.ts @@ -1,4 +1,4 @@ -import { APIAccount } from "./account"; +import type { APIAccount } from "./account"; export interface APIReport { id: string; diff --git a/types/entities/results.ts b/types/entities/results.ts index 54c1d2bd..494cce96 100644 --- a/types/entities/results.ts +++ b/types/entities/results.ts @@ -1,6 +1,6 @@ -import { APIAccount } from "./account"; -import { APIStatus } from "./status"; -import { APITag } from "./tag"; +import type { APIAccount } from "./account"; +import type { APIStatus } from "./status"; +import type { APITag } from "./tag"; export interface APIResults { accounts: APIAccount[]; diff --git a/types/entities/scheduled_status.ts b/types/entities/scheduled_status.ts index 10b9f505..a5975b9d 100644 --- a/types/entities/scheduled_status.ts +++ b/types/entities/scheduled_status.ts @@ -1,5 +1,5 @@ -import { APIAttachment } from "./attachment"; -import { APIStatusParams } from "./status_params"; +import type { APIAttachment } from "./attachment"; +import type { APIStatusParams } from "./status_params"; export interface APIScheduledStatus { id: string; diff --git a/types/entities/source.ts b/types/entities/source.ts index bd18094a..1433b90b 100644 --- a/types/entities/source.ts +++ b/types/entities/source.ts @@ -1,4 +1,4 @@ -import { APIField } from "./field"; +import type { APIField } from "./field"; export interface APISource { privacy: string | null; diff --git a/types/entities/status.ts b/types/entities/status.ts index 6fb21a5d..377ddf37 100644 --- a/types/entities/status.ts +++ b/types/entities/status.ts @@ -1,10 +1,10 @@ -import { APIAccount } from "./account"; -import { APIApplication } from "./application"; -import { APIAttachment } from "./attachment"; -import { APICard } from "./card"; -import { APIEmoji } from "./emoji"; -import { APIMention } from "./mention"; -import { APIPoll } from "./poll"; +import type { APIAccount } from "./account"; +import type { APIApplication } from "./application"; +import type { APIAttachment } from "./attachment"; +import type { APICard } from "./card"; +import type { APIEmoji } from "./emoji"; +import type { APIMention } from "./mention"; +import type { APIPoll } from "./poll"; export interface APIStatus { id: string; diff --git a/types/entities/tag.ts b/types/entities/tag.ts index a519dca2..7fe4395b 100644 --- a/types/entities/tag.ts +++ b/types/entities/tag.ts @@ -1,4 +1,4 @@ -import { APIHistory } from "./history"; +import type { APIHistory } from "./history"; export interface APITag { name: string; diff --git a/types/lysand/Extension.ts b/types/lysand/Extension.ts index cf3645a0..5a733664 100644 --- a/types/lysand/Extension.ts +++ b/types/lysand/Extension.ts @@ -1,4 +1,4 @@ -import { LysandObjectType } from "./Object"; +import type { LysandObjectType } from "./Object"; export interface ExtensionType extends LysandObjectType { type: "Extension"; diff --git a/types/lysand/Object.ts b/types/lysand/Object.ts index 4efe731b..c3904f74 100644 --- a/types/lysand/Object.ts +++ b/types/lysand/Object.ts @@ -1,4 +1,4 @@ -import { Emoji } from "./extensions/org.lysand/custom_emojis"; +import type { Emoji } from "./extensions/org.lysand/custom_emojis"; export interface LysandObjectType { type: string; diff --git a/types/lysand/extensions/org.lysand/custom_emojis.ts b/types/lysand/extensions/org.lysand/custom_emojis.ts index f47f770f..50aa0338 100644 --- a/types/lysand/extensions/org.lysand/custom_emojis.ts +++ b/types/lysand/extensions/org.lysand/custom_emojis.ts @@ -1,4 +1,4 @@ -import { ContentFormat } from "../../Object"; +import type { ContentFormat } from "../../Object"; export interface Emoji { name: string; diff --git a/types/lysand/extensions/org.lysand/polls.ts b/types/lysand/extensions/org.lysand/polls.ts index af157364..15d3f5fb 100644 --- a/types/lysand/extensions/org.lysand/polls.ts +++ b/types/lysand/extensions/org.lysand/polls.ts @@ -1,4 +1,4 @@ -import { ExtensionType } from "../../Extension"; +import type { ExtensionType } from "../../Extension"; export interface OrgLysandPollsVoteType extends ExtensionType { extension_type: "org.lysand:polls/Vote"; diff --git a/types/lysand/extensions/org.lysand/reactions.ts b/types/lysand/extensions/org.lysand/reactions.ts index 8830ea1f..4113dfcd 100644 --- a/types/lysand/extensions/org.lysand/reactions.ts +++ b/types/lysand/extensions/org.lysand/reactions.ts @@ -1,4 +1,4 @@ -import { ExtensionType } from "../../Extension"; +import type { ExtensionType } from "../../Extension"; export interface OrgLysandReactionsType extends ExtensionType { extension_type: "org.lysand:reactions/Reaction"; diff --git a/utils/api.ts b/utils/api.ts index 73125bb0..0e088cdd 100644 --- a/utils/api.ts +++ b/utils/api.ts @@ -1,5 +1,5 @@ import { getConfig } from "@config"; -import { APIRouteMeta } from "~types/api"; +import type { APIRouteMeta } from "~types/api"; export const applyConfig = (routeMeta: APIRouteMeta) => { const config = getConfig(); diff --git a/utils/content_types.ts b/utils/content_types.ts index 2cf871eb..d1d64f7e 100644 --- a/utils/content_types.ts +++ b/utils/content_types.ts @@ -1,4 +1,4 @@ -import { ContentFormat } from "~types/lysand/Object"; +import type { ContentFormat } from "~types/lysand/Object"; export const getBestContentType = (contents: ContentFormat[]) => { // Find the best content and content type diff --git a/utils/oauth.ts b/utils/oauth.ts index 9b971886..bc9110e1 100644 --- a/utils/oauth.ts +++ b/utils/oauth.ts @@ -1,4 +1,4 @@ -import { Application } from "@prisma/client"; +import type { Application } from "@prisma/client"; /** * Check if an OAuth application is valid for a route diff --git a/utils/response.ts b/utils/response.ts index cddd2f94..a34685cf 100644 --- a/utils/response.ts +++ b/utils/response.ts @@ -1,5 +1,5 @@ -import { APActivity, APObject } from "activitypub-types"; -import { NodeObject } from "jsonld"; +import type { APActivity, APObject } from "activitypub-types"; +import type { NodeObject } from "jsonld"; export const jsonResponse = ( data: object,