diff --git a/bun.lockb b/bun.lockb index 0ad05644..0c54c783 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/database/entities/federation.ts b/database/entities/federation.ts index b84048da..12e2c53f 100644 --- a/database/entities/federation.ts +++ b/database/entities/federation.ts @@ -1,8 +1,6 @@ import { debugRequest } from "@/api"; -import { - type EntityValidator, - SignatureConstructor, -} from "@lysand-org/federation"; +import { SignatureConstructor } from "@lysand-org/federation"; +import type { Entity, Undo } from "@lysand-org/federation/types"; import { config } from "config-manager"; import type { User } from "~/packages/database-interface/user"; import { LogLevel, LogManager } from "~/packages/log-manager"; @@ -11,7 +9,7 @@ export const localObjectUri = (id: string) => new URL(`/objects/${id}`, config.http.base_url).toString(); export const objectToInboxRequest = async ( - object: typeof EntityValidator.$Entity, + object: Entity, author: User, userToSendTo: User, ): Promise => { @@ -68,10 +66,7 @@ export const objectToInboxRequest = async ( return signed; }; -export const undoFederationRequest = ( - undoer: User, - uri: string, -): typeof EntityValidator.$Undo => { +export const undoFederationRequest = (undoer: User, uri: string): Undo => { const id = crypto.randomUUID(); return { type: "Undo", diff --git a/database/entities/instance.ts b/database/entities/instance.ts index cef9e05c..2b12133f 100644 --- a/database/entities/instance.ts +++ b/database/entities/instance.ts @@ -1,4 +1,4 @@ -import type { EntityValidator } from "@lysand-org/federation"; +import type { ServerMetadata } from "@lysand-org/federation/types"; import { db } from "~/drizzle/db"; import { Instances } from "~/drizzle/schema"; @@ -26,7 +26,7 @@ export const addInstanceIfNotExists = async (url: string) => { // Fetch the instance configuration const metadata = (await fetch(new URL("/.well-known/lysand", origin)).then( (res) => res.json(), - )) as typeof EntityValidator.$ServerMetadata; + )) as ServerMetadata; if (metadata.type !== "ServerMetadata") { throw new Error("Invalid instance metadata (wrong type)"); diff --git a/database/entities/like.ts b/database/entities/like.ts index 390c1a85..d7de9f4d 100644 --- a/database/entities/like.ts +++ b/database/entities/like.ts @@ -1,4 +1,4 @@ -import type { EntityValidator } from "@lysand-org/federation"; +import type { Like } from "@lysand-org/federation/types"; import { config } from "config-manager"; import { type InferSelectModel, and, eq } from "drizzle-orm"; import { db } from "~/drizzle/db"; @@ -6,12 +6,12 @@ import { Likes, Notifications } from "~/drizzle/schema"; import type { Note } from "~/packages/database-interface/note"; import type { User } from "~/packages/database-interface/user"; -export type Like = InferSelectModel; +export type LikeType = InferSelectModel; /** * Represents a Like entity in the database. */ -export const likeToLysand = (like: Like): typeof EntityValidator.$Like => { +export const likeToLysand = (like: LikeType): Like => { return { id: like.id, // biome-ignore lint/suspicious/noExplicitAny: to be rewritten diff --git a/database/entities/status.ts b/database/entities/status.ts index 2f75bc63..b387b968 100644 --- a/database/entities/status.ts +++ b/database/entities/status.ts @@ -2,7 +2,7 @@ import { mentionValidator } from "@/api"; import { dualLogger } from "@/loggers"; import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization"; import markdownItTaskLists from "@hackmd/markdown-it-task-lists"; -import type { EntityValidator } from "@lysand-org/federation"; +import type { ContentFormat } from "@lysand-org/federation/types"; import { config } from "config-manager"; import { type InferSelectModel, @@ -373,7 +373,7 @@ export const replaceTextMentions = (text: string, mentions: User[]) => { }; export const contentToHtml = async ( - content: typeof EntityValidator.$ContentFormat, + content: ContentFormat, mentions: User[] = [], inline = false, ): Promise => { diff --git a/database/entities/user.ts b/database/entities/user.ts index a5a2045d..073491df 100644 --- a/database/entities/user.ts +++ b/database/entities/user.ts @@ -1,5 +1,9 @@ import { dualLogger } from "@/loggers"; -import type { EntityValidator } from "@lysand-org/federation"; +import type { + Follow, + FollowAccept, + FollowReject, +} from "@lysand-org/federation/types"; import { config } from "config-manager"; import { type InferSelectModel, and, eq, sql } from "drizzle-orm"; import { db } from "~/drizzle/db"; @@ -505,7 +509,7 @@ export const getRelationshipToOtherUser = async ( export const followRequestToLysand = ( follower: User, followee: User, -): typeof EntityValidator.$Follow => { +): Follow => { if (follower.isRemote()) { throw new Error("Follower must be a local user"); } @@ -533,7 +537,7 @@ export const followRequestToLysand = ( export const followAcceptToLysand = ( follower: User, followee: User, -): typeof EntityValidator.$FollowAccept => { +): FollowAccept => { if (!follower.isRemote()) { throw new Error("Follower must be a remote user"); } @@ -561,7 +565,7 @@ export const followAcceptToLysand = ( export const followRejectToLysand = ( follower: User, followee: User, -): typeof EntityValidator.$FollowReject => { +): FollowReject => { return { ...followAcceptToLysand(follower, followee), type: "FollowReject", diff --git a/drizzle/schema.ts b/drizzle/schema.ts index d3c7af69..127a467f 100644 --- a/drizzle/schema.ts +++ b/drizzle/schema.ts @@ -1,4 +1,4 @@ -import type { EntityValidator } from "@lysand-org/federation"; +import type { ContentFormat } from "@lysand-org/federation/types"; import type { Challenge } from "altcha-lib/types"; import { relations, sql } from "drizzle-orm"; import { @@ -375,8 +375,8 @@ export const Users = pgTable( passwordResetToken: text("password_reset_token"), fields: jsonb("fields").notNull().default("[]").$type< { - key: typeof EntityValidator.$ContentFormat; - value: typeof EntityValidator.$ContentFormat; + key: ContentFormat; + value: ContentFormat; }[] >(), endpoints: jsonb("endpoints").$type { }; } - public toLysand(): typeof EntityValidator.$ContentFormat { + public toLysand(): ContentFormat { return { [this.data.mimeType]: { content: this.data.url, @@ -204,7 +204,7 @@ export class Attachment extends BaseInterface { } public static fromLysand( - attachmentToConvert: typeof EntityValidator.$ContentFormat, + attachmentToConvert: ContentFormat, ): Promise { const key = Object.keys(attachmentToConvert)[0]; const value = attachmentToConvert[key]; diff --git a/packages/database-interface/emoji.ts b/packages/database-interface/emoji.ts index 5a232264..0ecbda46 100644 --- a/packages/database-interface/emoji.ts +++ b/packages/database-interface/emoji.ts @@ -1,5 +1,5 @@ import { proxyUrl } from "@/response"; -import type { EntityValidator } from "@lysand-org/federation"; +import type { CustomEmojiExtension } from "@lysand-org/federation/types"; import { type InferInsertModel, type SQL, @@ -118,7 +118,7 @@ export class Emoji extends BaseInterface { } public static async fetchFromRemote( - emojiToFetch: (typeof EntityValidator.$CustomEmojiExtension)["emojis"][0], + emojiToFetch: CustomEmojiExtension["emojis"][0], host?: string, ): Promise { const existingEmoji = await db @@ -164,7 +164,7 @@ export class Emoji extends BaseInterface { }; } - public toLysand(): (typeof EntityValidator.$CustomEmojiExtension)["emojis"][0] { + public toLysand(): CustomEmojiExtension["emojis"][0] { return { name: this.data.shortcode, url: { @@ -177,7 +177,7 @@ export class Emoji extends BaseInterface { } public static fromLysand( - emoji: (typeof EntityValidator.$CustomEmojiExtension)["emojis"][0], + emoji: CustomEmojiExtension["emojis"][0], instanceId: string | null, ): Promise { return Emoji.insert({ diff --git a/packages/database-interface/note.ts b/packages/database-interface/note.ts index adaacab2..19e86759 100644 --- a/packages/database-interface/note.ts +++ b/packages/database-interface/note.ts @@ -3,6 +3,10 @@ import { dualLogger } from "@/loggers"; import { proxyUrl } from "@/response"; import { sanitizedHtmlStrip } from "@/sanitization"; import { EntityValidator } from "@lysand-org/federation"; +import type { + ContentFormat, + Note as LysandNote, +} from "@lysand-org/federation/types"; import { type InferInsertModel, type SQL, @@ -302,7 +306,7 @@ export class Note extends BaseInterface { */ static async fromData(data: { author: User; - content: typeof EntityValidator.$ContentFormat; + content: ContentFormat; visibility: APIStatus["visibility"]; isSensitive: boolean; spoilerText: string; @@ -392,7 +396,7 @@ export class Note extends BaseInterface { */ async updateFromData(data: { author?: User; - content?: typeof EntityValidator.$ContentFormat; + content?: ContentFormat; visibility?: APIStatus["visibility"]; isSensitive?: boolean; spoilerText?: string; @@ -579,7 +583,7 @@ export class Note extends BaseInterface { * @returns The saved note, or null if the note could not be fetched */ static async saveFromRemote(uri: string): Promise { - let note: typeof EntityValidator.$Note | null = null; + let note: LysandNote | null = null; if (uri) { if (!URL.canParse(uri)) { @@ -615,10 +619,7 @@ export class Note extends BaseInterface { * @param author Author of the note * @returns The saved note */ - static async fromLysand( - note: typeof EntityValidator.$Note, - author: User, - ): Promise { + static async fromLysand(note: LysandNote, author: User): Promise { const emojis: Emoji[] = []; for (const emoji of note.extensions?.["org.lysand:custom_emojis"] @@ -878,7 +879,7 @@ export class Note extends BaseInterface { * Convert a note to the Lysand format * @returns The note in the Lysand format */ - toLysand(): typeof EntityValidator.$Note { + toLysand(): LysandNote { const status = this.data; return { type: "Note", diff --git a/packages/database-interface/user.ts b/packages/database-interface/user.ts index 1c02d370..4ab1ada6 100644 --- a/packages/database-interface/user.ts +++ b/packages/database-interface/user.ts @@ -4,6 +4,7 @@ import { randomString } from "@/math"; import { addUserToMeilisearch } from "@/meilisearch"; import { proxyUrl } from "@/response"; import { EntityValidator } from "@lysand-org/federation"; +import type { Entity, User as LysandUser } from "@lysand-org/federation/types"; import { type InferInsertModel, type InferSelectModel, @@ -254,9 +255,7 @@ export class User extends BaseInterface { }, }); - const json = (await response.json()) as Partial< - typeof EntityValidator.$User - >; + const json = (await response.json()) as Partial; const validator = new EntityValidator(); @@ -299,7 +298,7 @@ export class User extends BaseInterface { } static async fromLysand( - user: typeof EntityValidator.$User, + user: LysandUser, instance: InferSelectModel, ): Promise { const data = { @@ -535,7 +534,7 @@ export class User extends BaseInterface { return updated.data; } - async federateToFollowers(object: typeof EntityValidator.$Entity) { + async federateToFollowers(object: Entity) { // Get followers const followers = await User.manyFromSql( and( @@ -625,7 +624,7 @@ export class User extends BaseInterface { }; } - toLysand(): typeof EntityValidator.$User { + toLysand(): LysandUser { if (this.isRemote()) { throw new Error("Cannot convert remote user to Lysand format"); } diff --git a/server/api/objects/:id/index.ts b/server/api/objects/:id/index.ts index cd8eeb51..4394978f 100644 --- a/server/api/objects/:id/index.ts +++ b/server/api/objects/:id/index.ts @@ -1,11 +1,11 @@ import { applyConfig, handleZodError } from "@/api"; import { errorResponse, jsonResponse } from "@/response"; import { zValidator } from "@hono/zod-validator"; -import type { EntityValidator } from "@lysand-org/federation"; +import type { Entity } from "@lysand-org/federation/types"; import { and, eq, inArray, sql } from "drizzle-orm"; import type { Hono } from "hono"; import { z } from "zod"; -import { type Like, likeToLysand } from "~/database/entities/like"; +import { type LikeType, likeToLysand } from "~/database/entities/like"; import { db } from "~/drizzle/db"; import { Notes } from "~/drizzle/schema"; import { Note } from "~/packages/database-interface/note"; @@ -36,8 +36,8 @@ export default (app: Hono) => async (context) => { const { id } = context.req.valid("param"); - let foundObject: Note | Like | null = null; - let apiObject: typeof EntityValidator.$Entity | null = null; + let foundObject: Note | LikeType | null = null; + let apiObject: Entity | null = null; foundObject = await Note.fromSql( and( diff --git a/server/api/users/:uuid/inbox/index.ts b/server/api/users/:uuid/inbox/index.ts index fe14a1c0..d58cbb75 100644 --- a/server/api/users/:uuid/inbox/index.ts +++ b/server/api/users/:uuid/inbox/index.ts @@ -7,6 +7,7 @@ import { RequestParserHandler, SignatureValidator, } from "@lysand-org/federation"; +import type { Entity } from "@lysand-org/federation/types"; import type { SocketAddress } from "bun"; import { and, eq } from "drizzle-orm"; import type { Hono } from "hono"; @@ -72,8 +73,7 @@ export default (app: Hono) => return response(null, 201); } - const body: typeof EntityValidator.$Entity = - await context.req.valid("json"); + const body: Entity = await context.req.valid("json"); if (config.debug.federation) { // Debug request diff --git a/server/api/well-known/lysand.ts b/server/api/well-known/lysand.ts index fe95e095..f64f1447 100644 --- a/server/api/well-known/lysand.ts +++ b/server/api/well-known/lysand.ts @@ -1,7 +1,7 @@ import { applyConfig } from "@/api"; import { urlToContentFormat } from "@/content_types"; import { jsonResponse } from "@/response"; -import type { EntityValidator } from "@lysand-org/federation"; +import type { ServerMetadata } from "@lysand-org/federation/types"; import type { Hono } from "hono"; import pkg from "~/package.json"; import { config } from "~/packages/config-manager"; @@ -29,5 +29,5 @@ export default (app: Hono) => banner: urlToContentFormat(config.instance.banner) ?? undefined, supported_extensions: ["org.lysand:custom_emojis"], website: "https://lysand.org", - } satisfies typeof EntityValidator.$ServerMetadata); + } satisfies ServerMetadata); }); diff --git a/tsconfig.json b/tsconfig.json index 278372d7..575a1c5d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,6 +28,7 @@ }, "noUnusedLocals": true }, + "exclude": ["node_modules"], "include": [ "*.ts", "*.d.ts", diff --git a/utils/content_types.ts b/utils/content_types.ts index 49d51b8c..17b2e947 100644 --- a/utils/content_types.ts +++ b/utils/content_types.ts @@ -1,9 +1,7 @@ -import type { EntityValidator } from "@lysand-org/federation"; +import type { ContentFormat } from "@lysand-org/federation/types"; import { lookup } from "mime-types"; -export const getBestContentType = ( - content?: typeof EntityValidator.$ContentFormat, -) => { +export const getBestContentType = (content?: ContentFormat) => { if (!content) { return { content: "", format: "text/plain" }; } @@ -24,9 +22,7 @@ export const getBestContentType = ( return { content: "", format: "text/plain" }; }; -export const urlToContentFormat = ( - url?: string, -): typeof EntityValidator.$ContentFormat | null => { +export const urlToContentFormat = (url?: string): ContentFormat | null => { if (!url) { return null; }