diff --git a/biome.json b/biome.json index 0f39b724..6c3e5655 100644 --- a/biome.json +++ b/biome.json @@ -60,7 +60,13 @@ } }, "nursery": { - "noDuplicateElseIf": "warn" + "noDuplicateElseIf": "warn", + "useConsistentMemberAccessibility": { + "level": "warn", + "options": { + "accessibility": "explicit" + } + } } } }, diff --git a/classes/database/application.ts b/classes/database/application.ts index 0cebc54d..abcef36d 100644 --- a/classes/database/application.ts +++ b/classes/database/application.ts @@ -15,7 +15,7 @@ import { BaseInterface } from "./base.ts"; export type ApplicationType = InferSelectModel; export class Application extends BaseInterface { - static schema: z.ZodType = z.object({ + public static schema: z.ZodType = z.object({ name: z.string(), website: z.string().url().optional().nullable(), vapid_key: z.string().optional().nullable(), @@ -23,7 +23,7 @@ export class Application extends BaseInterface { scopes: z.string().optional(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await Application.fromId(this.data.id); if (!reloaded) { @@ -95,7 +95,7 @@ export class Application extends BaseInterface { return Application.fromSql(eq(Applications.clientId, clientId)); } - async update( + public async update( newApplication: Partial, ): Promise { await db @@ -113,11 +113,11 @@ export class Application extends BaseInterface { return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Applications).where(inArray(Applications.id, ids)); } else { @@ -141,7 +141,7 @@ export class Application extends BaseInterface { return application; } - get id() { + public get id() { return this.data.id; } diff --git a/classes/database/attachment.ts b/classes/database/attachment.ts index bedd6c5f..41c3ce74 100644 --- a/classes/database/attachment.ts +++ b/classes/database/attachment.ts @@ -19,7 +19,7 @@ import { BaseInterface } from "./base.ts"; export type AttachmentType = InferSelectModel; export class Attachment extends BaseInterface { - static schema: z.ZodType = z.object({ + public static schema: z.ZodType = z.object({ id: z.string().uuid(), type: z.enum(["unknown", "image", "gifv", "video", "audio"]), url: z.string().url(), @@ -47,7 +47,7 @@ export class Attachment extends BaseInterface { blurhash: z.string().nullable(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await Attachment.fromId(this.data.id); if (!reloaded) { @@ -102,7 +102,7 @@ export class Attachment extends BaseInterface { return found.map((s) => new Attachment(s)); } - async update( + public async update( newAttachment: Partial, ): Promise { await db @@ -120,11 +120,11 @@ export class Attachment extends BaseInterface { return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Attachments).where(inArray(Attachments.id, ids)); } else { @@ -148,7 +148,7 @@ export class Attachment extends BaseInterface { return attachment; } - get id() { + public get id() { return this.data.id; } diff --git a/classes/database/base.ts b/classes/database/base.ts index a6802f37..865de264 100644 --- a/classes/database/base.ts +++ b/classes/database/base.ts @@ -18,7 +18,7 @@ export abstract class BaseInterface< * * @param data - The data for the model. */ - constructor(public data: Columns) {} + public constructor(public data: Columns) {} /** * Saves the current state of the model to the database. diff --git a/classes/database/emoji.ts b/classes/database/emoji.ts index abb3df90..91d8ab34 100644 --- a/classes/database/emoji.ts +++ b/classes/database/emoji.ts @@ -22,7 +22,7 @@ export type EmojiWithInstance = InferSelectModel & { }; export class Emoji extends BaseInterface { - static schema = z.object({ + public static schema = z.object({ shortcode: z.string(), url: z.string(), visible_in_picker: z.boolean(), @@ -30,7 +30,7 @@ export class Emoji extends BaseInterface { static_url: z.string(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await Emoji.fromId(this.data.id); if (!reloaded) { @@ -88,7 +88,7 @@ export class Emoji extends BaseInterface { return found.map((s) => new Emoji(s)); } - async update( + public async update( newEmoji: Partial, ): Promise { await db.update(Emojis).set(newEmoji).where(eq(Emojis.id, this.id)); @@ -103,11 +103,11 @@ export class Emoji extends BaseInterface { return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Emojis).where(inArray(Emojis.id, ids)); } else { @@ -160,7 +160,7 @@ export class Emoji extends BaseInterface { return await Emoji.fromVersia(emojiToFetch, foundInstance?.id ?? null); } - get id() { + public get id() { return this.data.id; } diff --git a/classes/database/instance.ts b/classes/database/instance.ts index 4bc61954..274beacf 100644 --- a/classes/database/instance.ts +++ b/classes/database/instance.ts @@ -23,7 +23,7 @@ import { User } from "./user.ts"; export type InstanceType = InferSelectModel; export class Instance extends BaseInterface { - async reload(): Promise { + public async reload(): Promise { const reloaded = await Instance.fromId(this.data.id); if (!reloaded) { @@ -78,7 +78,9 @@ export class Instance extends BaseInterface { return found.map((s) => new Instance(s)); } - async update(newInstance: Partial): Promise { + public async update( + newInstance: Partial, + ): Promise { await db .update(Instances) .set(newInstance) @@ -94,11 +96,11 @@ export class Instance extends BaseInterface { return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Instances).where(inArray(Instances.id, ids)); } else { @@ -130,11 +132,11 @@ export class Instance extends BaseInterface { return instance; } - get id() { + public get id() { return this.data.id; } - static async fetchMetadata(url: string): Promise<{ + public static async fetchMetadata(url: string): Promise<{ metadata: InstanceMetadata; protocol: "versia" | "activitypub"; } | null> { @@ -315,7 +317,7 @@ export class Instance extends BaseInterface { } } - static async resolve(url: string): Promise { + public static async resolve(url: string): Promise { const logger = getLogger("federation"); const host = new URL(url).host; @@ -345,7 +347,7 @@ export class Instance extends BaseInterface { }); } - static getCount(): Promise { + public static getCount(): Promise { return db.$count(Instances); } } diff --git a/classes/database/like.ts b/classes/database/like.ts index ea70c823..5d5eb939 100644 --- a/classes/database/like.ts +++ b/classes/database/like.ts @@ -24,7 +24,7 @@ export type LikeType = InferSelectModel & { }; export class Like extends BaseInterface { - static schema = z.object({ + public static schema = z.object({ id: z.string(), name: z.string(), permissions: z.array(z.nativeEnum(RolePermission)), @@ -34,7 +34,7 @@ export class Like extends BaseInterface { icon: z.string().nullable(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await Like.fromId(this.data.id); if (!reloaded) { @@ -97,7 +97,7 @@ export class Like extends BaseInterface { return found.map((s) => new Like(s)); } - async update(newRole: Partial): Promise { + public async update(newRole: Partial): Promise { await db.update(Likes).set(newRole).where(eq(Likes.id, this.id)); const updated = await Like.fromId(this.data.id); @@ -109,11 +109,11 @@ export class Like extends BaseInterface { return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Likes).where(inArray(Likes.id, ids)); } else { @@ -135,7 +135,7 @@ export class Like extends BaseInterface { return role; } - get id() { + public get id() { return this.data.id; } diff --git a/classes/database/note.ts b/classes/database/note.ts index 48fc20e7..dbc300ed 100644 --- a/classes/database/note.ts +++ b/classes/database/note.ts @@ -53,7 +53,7 @@ import { User } from "./user.ts"; * Gives helpers to fetch notes from database in a nice format */ export class Note extends BaseInterface { - static schema: z.ZodType = z.object({ + public static schema: z.ZodType = z.object({ id: z.string().uuid(), uri: z.string().url(), url: z.string().url(), @@ -143,14 +143,14 @@ export class Note extends BaseInterface { bookmarked: z.boolean(), }); - save(): Promise { + public save(): Promise { return this.update(this.data); } /** * @param userRequestingNoteId Used to calculate visibility of the note */ - async reload(userRequestingNoteId?: string): Promise { + public async reload(userRequestingNoteId?: string): Promise { const reloaded = await Note.fromId(this.data.id, userRequestingNoteId); if (!reloaded) { @@ -187,7 +187,7 @@ export class Note extends BaseInterface { * @param userRequestingNoteId - The ID of the user requesting the note (used to check visibility of the note) * @returns The fetched note */ - static async fromId( + public static async fromId( id: string | null, userRequestingNoteId?: string, ): Promise { @@ -207,7 +207,7 @@ export class Note extends BaseInterface { * @param userRequestingNoteId - The ID of the user requesting the note (used to check visibility of the note) * @returns The fetched notes */ - static async fromIds( + public static async fromIds( ids: string[], userRequestingNoteId?: string, ): Promise { @@ -227,7 +227,7 @@ export class Note extends BaseInterface { * @param userId - The ID of the user requesting the note (used to check visibility of the note) * @returns The fetched note */ - static async fromSql( + public static async fromSql( sql: SQL | undefined, orderBy: SQL | undefined = desc(Notes.id), userId?: string, @@ -256,7 +256,7 @@ export class Note extends BaseInterface { * @param userId - The ID of the user requesting the note (used to check visibility of the note) * @returns - The fetched notes */ - static async manyFromSql( + public static async manyFromSql( sql: SQL | undefined, orderBy: SQL | undefined = desc(Notes.id), limit?: number, @@ -276,11 +276,11 @@ export class Note extends BaseInterface { return found.map((s) => new Note(s)); } - get id() { + public get id() { return this.data.id; } - async federateToUsers(): Promise { + public async federateToUsers(): Promise { const users = await this.getUsersToFederateTo(); for (const user of users) { @@ -296,7 +296,7 @@ export class Note extends BaseInterface { * - Users that can see the note * @returns The users that should be federated to */ - async getUsersToFederateTo(): Promise { + public async getUsersToFederateTo(): Promise { // Mentioned users const mentionedUsers = this.data.mentions.length > 0 @@ -339,7 +339,7 @@ export class Note extends BaseInterface { return deduplicatedUsersById; } - get author() { + public get author() { return new User(this.data.author); } @@ -347,7 +347,7 @@ export class Note extends BaseInterface { * Get the number of notes in the database (excluding remote notes) * @returns The number of notes in the database */ - static async getCount(): Promise { + public static async getCount(): Promise { return await db.$count( Notes, sql`EXISTS (SELECT 1 FROM "Users" WHERE "Users"."id" = ${Notes.authorId} AND "Users"."instanceId" IS NULL)`, @@ -369,7 +369,7 @@ export class Note extends BaseInterface { ); } - isRemote() { + public isRemote() { return this.author.isRemote(); } @@ -377,7 +377,7 @@ export class Note extends BaseInterface { * Update a note from remote federated servers * @returns The updated note */ - async updateFromRemote(): Promise { + public async updateFromRemote(): Promise { if (!this.isRemote()) { throw new Error("Cannot refetch a local note (it is not remote)"); } @@ -398,7 +398,7 @@ export class Note extends BaseInterface { * @param data - The data to create the note from * @returns The created note */ - static async fromData(data: { + public static async fromData(data: { author: User; content: ContentFormat; visibility: ApiStatus["visibility"]; @@ -488,7 +488,7 @@ export class Note extends BaseInterface { * @param data - The data to update the note from * @returns The updated note */ - async updateFromData(data: { + public async updateFromData(data: { author: User; content?: ContentFormat; visibility?: ApiStatus["visibility"]; @@ -649,7 +649,7 @@ export class Note extends BaseInterface { * @param uri - The URI of the note to resolve * @returns The resolved note */ - static async resolve(uri: string): Promise { + public static async resolve(uri: string): Promise { // Check if note not already in database const foundNote = await Note.fromSql(eq(Notes.uri, uri)); @@ -678,7 +678,7 @@ export class Note extends BaseInterface { * @param uri - The URI of the note to save * @returns The saved note, or null if the note could not be fetched */ - static async saveFromRemote(uri: string): Promise { + public static async saveFromRemote(uri: string): Promise { let note: VersiaNote | null = null; if (uri) { @@ -715,7 +715,10 @@ export class Note extends BaseInterface { * @param author Author of the note * @returns The saved note */ - static async fromVersia(note: VersiaNote, author: User): Promise { + public static async fromVersia( + note: VersiaNote, + author: User, + ): Promise { const emojis: Emoji[] = []; const logger = getLogger("federation"); @@ -803,7 +806,7 @@ export class Note extends BaseInterface { return await Note.fromData(newData); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Notes).where(inArray(Notes.id, ids)); } else { @@ -811,7 +814,7 @@ export class Note extends BaseInterface { } } - async update( + public async update( newStatus: Partial, ): Promise { await db.update(Notes).set(newStatus).where(eq(Notes.id, this.data.id)); @@ -830,7 +833,7 @@ export class Note extends BaseInterface { * @param user The user to check. * @returns Whether this status is viewable by the user. */ - async isViewableByUser(user: User | null): Promise { + public async isViewableByUser(user: User | null): Promise { if (this.author.id === user?.id) { return true; } @@ -863,7 +866,7 @@ export class Note extends BaseInterface { * @param userFetching - The user fetching the note (used to check if the note is favourite and such) * @returns The note in the Mastodon API format */ - async toApi(userFetching?: User | null): Promise { + public async toApi(userFetching?: User | null): Promise { const data = this.data; // Convert mentions of local users from @username@host to @username @@ -957,11 +960,14 @@ export class Note extends BaseInterface { }; } - getUri(): string { + public getUri(): string { return this.data.uri || localObjectUri(this.id); } - static getUri(id: string | null, uri?: string | null): string | null { + public static getUri( + id: string | null, + uri?: string | null, + ): string | null { if (!id) { return null; } @@ -972,14 +978,14 @@ export class Note extends BaseInterface { * Get the frontend URI of this note * @returns The frontend URI of this note */ - getMastoUri(): string { + public getMastoUri(): string { return new URL( `/@${this.author.data.username}/${this.id}`, config.http.base_url, ).toString(); } - deleteToVersia(): VersiaDelete { + public deleteToVersia(): VersiaDelete { const id = crypto.randomUUID(); return { @@ -996,7 +1002,7 @@ export class Note extends BaseInterface { * Convert a note to the Versia format * @returns The note in the Versia format */ - toVersia(): VersiaNote { + public toVersia(): VersiaNote { const status = this.data; return { type: "Note", @@ -1045,7 +1051,7 @@ export class Note extends BaseInterface { * @param fetcher - The user fetching the ancestors * @returns The ancestors of this post */ - async getAncestors(fetcher: User | null): Promise { + public async getAncestors(fetcher: User | null): Promise { const ancestors: Note[] = []; let currentStatus: Note = this; @@ -1080,7 +1086,10 @@ export class Note extends BaseInterface { * @param depth - The depth of the recursion (internal) * @returns The descendants of this post */ - async getDescendants(fetcher: User | null, depth = 0): Promise { + public async getDescendants( + fetcher: User | null, + depth = 0, + ): Promise { const descendants: Note[] = []; for (const child of await this.getReplyChildren(fetcher?.id)) { descendants.push(child); diff --git a/classes/database/relationship.ts b/classes/database/relationship.ts index 6dbc258f..5321cb30 100644 --- a/classes/database/relationship.ts +++ b/classes/database/relationship.ts @@ -26,7 +26,7 @@ export class Relationship extends BaseInterface< typeof Relationships, RelationshipWithOpposite > { - static schema = z.object({ + public static schema = z.object({ id: z.string(), blocked_by: z.boolean(), blocking: z.boolean(), @@ -43,7 +43,7 @@ export class Relationship extends BaseInterface< showing_reblogs: z.boolean(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await Relationship.fromId(this.data.id); if (!reloaded) { @@ -232,7 +232,7 @@ export class Relationship extends BaseInterface< return output; } - async update( + public async update( newRelationship: Partial, ): Promise { await db @@ -250,11 +250,11 @@ export class Relationship extends BaseInterface< return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db .delete(Relationships) @@ -286,7 +286,7 @@ export class Relationship extends BaseInterface< return relationship; } - get id() { + public get id() { return this.data.id; } diff --git a/classes/database/role.ts b/classes/database/role.ts index b5ed912c..dcd07fdf 100644 --- a/classes/database/role.ts +++ b/classes/database/role.ts @@ -18,7 +18,7 @@ import { BaseInterface } from "./base.ts"; export type RoleType = InferSelectModel; export class Role extends BaseInterface { - static schema = z.object({ + public static schema = z.object({ id: z.string(), name: z.string(), permissions: z.array(z.nativeEnum(RolePermission)), @@ -28,7 +28,7 @@ export class Role extends BaseInterface { icon: z.string().nullable(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await Role.fromId(this.data.id); if (!reloaded) { @@ -127,7 +127,7 @@ export class Role extends BaseInterface { return found.map((s) => new Role(s)); } - async update(newRole: Partial): Promise { + public async update(newRole: Partial): Promise { await db.update(Roles).set(newRole).where(eq(Roles.id, this.id)); const updated = await Role.fromId(this.data.id); @@ -139,11 +139,11 @@ export class Role extends BaseInterface { return updated.data; } - save(): Promise { + public save(): Promise { return this.update(this.data); } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Roles).where(inArray(Roles.id, ids)); } else { @@ -183,7 +183,7 @@ export class Role extends BaseInterface { ); } - get id() { + public get id() { return this.data.id; } diff --git a/classes/database/timeline.ts b/classes/database/timeline.ts index f1984233..59dc8c7f 100644 --- a/classes/database/timeline.ts +++ b/classes/database/timeline.ts @@ -10,9 +10,9 @@ enum TimelineType { } export class Timeline { - constructor(private type: TimelineType) {} + public constructor(private type: TimelineType) {} - static getNoteTimeline( + public static getNoteTimeline( sql: SQL | undefined, limit: number, url: string, @@ -26,7 +26,7 @@ export class Timeline { ); } - static getUserTimeline( + public static getUserTimeline( sql: SQL | undefined, limit: number, url: string, diff --git a/classes/database/user.ts b/classes/database/user.ts index 2a69400c..c897893f 100644 --- a/classes/database/user.ts +++ b/classes/database/user.ts @@ -68,7 +68,7 @@ import { Role } from "./role.ts"; * Gives helpers to fetch users from database in a nice format */ export class User extends BaseInterface { - static schema: z.ZodType = z.object({ + public static schema: z.ZodType = z.object({ id: z.string(), username: z.string(), acct: z.string(), @@ -125,7 +125,7 @@ export class User extends BaseInterface { mute_expires_at: z.string().optional(), }); - async reload(): Promise { + public async reload(): Promise { const reloaded = await User.fromId(this.data.id); if (!reloaded) { @@ -135,7 +135,7 @@ export class User extends BaseInterface { this.data = reloaded.data; } - static async fromId(id: string | null): Promise { + public static async fromId(id: string | null): Promise { if (!id) { return null; } @@ -143,11 +143,11 @@ export class User extends BaseInterface { return await User.fromSql(eq(Users.id, id)); } - static async fromIds(ids: string[]): Promise { + public static async fromIds(ids: string[]): Promise { return await User.manyFromSql(inArray(Users.id, ids)); } - static async fromSql( + public static async fromSql( sql: SQL | undefined, orderBy: SQL | undefined = desc(Users.id), ) { @@ -162,7 +162,7 @@ export class User extends BaseInterface { return new User(found[0]); } - static async manyFromSql( + public static async manyFromSql( sql: SQL | undefined, orderBy: SQL | undefined = desc(Users.id), limit?: number, @@ -180,26 +180,26 @@ export class User extends BaseInterface { return found.map((s) => new User(s)); } - get id() { + public get id() { return this.data.id; } - isLocal() { + public isLocal() { return this.data.instanceId === null; } - isRemote() { + public isRemote() { return !this.isLocal(); } - getUri() { + public getUri() { return ( this.data.uri || new URL(`/users/${this.data.id}`, config.http.base_url).toString() ); } - static getUri(id: string, uri: string | null, baseUrl: string) { + public static getUri(id: string, uri: string | null, baseUrl: string) { return uri || new URL(`/users/${id}`, baseUrl).toString(); } @@ -270,7 +270,7 @@ export class User extends BaseInterface { return foundRelationship; } - async unfollow(followee: User, relationship: Relationship) { + public async unfollow(followee: User, relationship: Relationship) { if (followee.isRemote()) { // TODO: This should reschedule for a later time and maybe notify the server admin if it fails too often const { ok } = await this.federateToUser( @@ -329,7 +329,7 @@ export class User extends BaseInterface { ); } - static async webFinger( + public static async webFinger( manager: FederationRequester, username: string, hostname: string, @@ -344,11 +344,11 @@ export class User extends BaseInterface { ); } - static getCount(): Promise { + public static getCount(): Promise { return db.$count(Users, isNull(Users.instanceId)); } - static async getActiveInPeriod(milliseconds: number) { + public static async getActiveInPeriod(milliseconds: number) { return ( await db .select({ @@ -368,7 +368,7 @@ export class User extends BaseInterface { )[0].count; } - async delete(ids?: string[]): Promise { + public async delete(ids?: string[]): Promise { if (Array.isArray(ids)) { await db.delete(Users).where(inArray(Users.id, ids)); } else { @@ -376,7 +376,7 @@ export class User extends BaseInterface { } } - async resetPassword() { + public async resetPassword() { const resetToken = randomString(32, "hex"); await this.update({ @@ -386,7 +386,7 @@ export class User extends BaseInterface { return resetToken; } - async pin(note: Note) { + public async pin(note: Note) { return ( await db .insert(UserToPinnedNotes) @@ -398,7 +398,7 @@ export class User extends BaseInterface { )[0]; } - async unpin(note: Note) { + public async unpin(note: Note) { return ( await db .delete(UserToPinnedNotes) @@ -412,7 +412,7 @@ export class User extends BaseInterface { )[0]; } - save(): Promise { + public save(): Promise { return this.update(this.data); } @@ -534,7 +534,7 @@ export class User extends BaseInterface { } } - async updateFromRemote(): Promise { + public async updateFromRemote(): Promise { if (!this.isRemote()) { throw new Error( "Cannot refetch a local user (they are not remote)", @@ -548,7 +548,7 @@ export class User extends BaseInterface { return this; } - static async saveFromRemote(uri: string): Promise { + public static async saveFromRemote(uri: string): Promise { if (!URL.canParse(uri)) { throw new Error(`Invalid URI: ${uri}`); } @@ -618,7 +618,7 @@ export class User extends BaseInterface { return finalUser; } - static async fromVersia( + public static async fromVersia( user: VersiaUser, instance: Instance, ): Promise { @@ -686,7 +686,7 @@ export class User extends BaseInterface { return user; } - static async resolve(uri: string): Promise { + public static async resolve(uri: string): Promise { // Check if user not already in database const foundUser = await User.fromSql(eq(Users.uri, uri)); @@ -715,7 +715,7 @@ export class User extends BaseInterface { * @param config The config to use * @returns The raw URL for the user's avatar */ - getAvatarUrl(config: Config) { + public getAvatarUrl(config: Config) { if (!this.data.avatar) { return ( config.defaults.avatar || @@ -725,7 +725,7 @@ export class User extends BaseInterface { return this.data.avatar; } - static async generateKeys() { + public static async generateKeys() { const keys = await crypto.subtle.generateKey("Ed25519", true, [ "sign", "verify", @@ -747,7 +747,7 @@ export class User extends BaseInterface { }; } - static async fromDataLocal(data: { + public static async fromDataLocal(data: { username: string; display_name?: string; password: string | undefined; @@ -807,24 +807,28 @@ export class User extends BaseInterface { * @param config The config to use * @returns The raw URL for the user's header */ - getHeaderUrl(config: Config) { + public getHeaderUrl(config: Config) { if (!this.data.header) { return config.defaults.header || ""; } return this.data.header; } - getAcct() { + public getAcct() { return this.isLocal() ? this.data.username : `${this.data.username}@${this.data.instance?.baseUrl}`; } - static getAcct(isLocal: boolean, username: string, baseUrl?: string) { + public static getAcct( + isLocal: boolean, + username: string, + baseUrl?: string, + ) { return isLocal ? username : `${username}@${baseUrl}`; } - async update( + public async update( newUser: Partial, ): Promise { await db.update(Users).set(newUser).where(eq(Users.id, this.id)); @@ -865,7 +869,7 @@ export class User extends BaseInterface { * @param signatureMethod HTTP method to embed in signature (default: POST) * @returns The signed string and headers to send with the request */ - async sign( + public async sign( entity: KnownEntity | Collection, signatureUrl: string | URL, signatureMethod: HttpVerb = "POST", @@ -902,7 +906,7 @@ export class User extends BaseInterface { * * @returns The requester */ - static async getFederationRequester(): Promise { + public static async getFederationRequester(): Promise { const signatureConstructor = await SignatureConstructor.fromStringKey( config.instance.keys.private, config.http.base_url, @@ -916,7 +920,7 @@ export class User extends BaseInterface { * * @returns The requester */ - async getFederationRequester(): Promise { + public async getFederationRequester(): Promise { const signatureConstructor = await SignatureConstructor.fromStringKey( this.data.privateKey ?? "", this.getUri(), @@ -930,7 +934,7 @@ export class User extends BaseInterface { * * @param entity Entity to federate */ - async federateToFollowers(entity: KnownEntity): Promise { + public async federateToFollowers(entity: KnownEntity): Promise { // Get followers const followers = await User.manyFromSql( and( @@ -951,7 +955,7 @@ export class User extends BaseInterface { * @param user User to federate to * @returns Whether the federation was successful */ - async federateToUser( + public async federateToUser( entity: KnownEntity, user: User, ): Promise<{ ok: boolean }> { @@ -985,7 +989,7 @@ export class User extends BaseInterface { return { ok: true }; } - toApi(isOwnAccount = false): ApiAccount { + public toApi(isOwnAccount = false): ApiAccount { const user = this.data; return { id: user.id, @@ -1055,7 +1059,7 @@ export class User extends BaseInterface { }; } - toVersia(): VersiaUser { + public toVersia(): VersiaUser { if (this.isRemote()) { throw new Error("Cannot convert remote user to Versia format"); } @@ -1132,7 +1136,7 @@ export class User extends BaseInterface { }; } - toMention(): ApiMention { + public toMention(): ApiMention { return { url: this.getUri(), username: this.data.username, diff --git a/classes/inbox/processor.ts b/classes/inbox/processor.ts index 21547a67..d09eba51 100644 --- a/classes/inbox/processor.ts +++ b/classes/inbox/processor.ts @@ -68,7 +68,7 @@ export class InboxProcessor { * @param logger LogTape logger instance. * @param requestIp Request IP address. Grabs it from the Hono context if not provided. */ - constructor( + public constructor( private context: Context, private body: Entity, private sender: User, diff --git a/classes/media/drivers/disk.ts b/classes/media/drivers/disk.ts index e1048908..4b8060b0 100644 --- a/classes/media/drivers/disk.ts +++ b/classes/media/drivers/disk.ts @@ -18,7 +18,7 @@ export class DiskMediaDriver implements MediaDriver { * Creates a new DiskMediaDriver instance. * @param config - The configuration object. */ - constructor(private config: Config) {} + public constructor(private config: Config) {} /** * @inheritdoc diff --git a/classes/media/drivers/s3.ts b/classes/media/drivers/s3.ts index 744f116a..0eecf5a2 100644 --- a/classes/media/drivers/s3.ts +++ b/classes/media/drivers/s3.ts @@ -19,7 +19,7 @@ export class S3MediaDriver implements MediaDriver { * Creates a new S3MediaDriver instance. * @param config - The configuration object. */ - constructor(config: Config) { + public constructor(config: Config) { this.s3Client = new S3Client({ endPoint: config.s3.endpoint, useSSL: true, diff --git a/classes/media/media-manager.ts b/classes/media/media-manager.ts index a936066a..731c4266 100644 --- a/classes/media/media-manager.ts +++ b/classes/media/media-manager.ts @@ -32,7 +32,7 @@ export class MediaManager { * Creates a new MediaManager instance. * @param config - The configuration object. */ - constructor(private config: Config) { + public constructor(private config: Config) { this.driver = this.initializeDriver(); this.initializePreprocessors(); } diff --git a/classes/media/preprocessors/image-conversion.ts b/classes/media/preprocessors/image-conversion.ts index bb138ae6..88523cdc 100644 --- a/classes/media/preprocessors/image-conversion.ts +++ b/classes/media/preprocessors/image-conversion.ts @@ -40,7 +40,7 @@ export class ImageConversionPreprocessor implements MediaPreprocessor { * Creates a new ImageConversionPreprocessor instance. * @param config - The configuration object. */ - constructor(private config: Config) {} + public constructor(private config: Config) {} /** * @inheritdoc diff --git a/classes/search/search-manager.ts b/classes/search/search-manager.ts index ab3783ec..e23fac3c 100644 --- a/classes/search/search-manager.ts +++ b/classes/search/search-manager.ts @@ -31,7 +31,7 @@ export class SonicSearchManager { /** * @param config Configuration for Sonic */ - constructor(private config: Config) { + public constructor(private config: Config) { this.searchChannel = new SonicChannelSearch({ host: config.sonic.host, port: config.sonic.port, @@ -48,7 +48,7 @@ export class SonicSearchManager { /** * Connect to Sonic */ - async connect(silent = false): Promise { + public async connect(silent = false): Promise { if (!this.config.sonic.enabled) { !silent && this.logger.info`Sonic search is disabled`; return; @@ -125,7 +125,7 @@ export class SonicSearchManager { * Add a user to Sonic * @param user User to add */ - async addUser(user: User): Promise { + public async addUser(user: User): Promise { if (!this.config.sonic.enabled) { return; } @@ -192,7 +192,7 @@ export class SonicSearchManager { * @param batchSize Size of each batch * @param progressCallback Callback for progress updates */ - async rebuildSearchIndexes( + public async rebuildSearchIndexes( indexes: SonicIndexType[], batchSize = 100, progressCallback?: (progress: number) => void, @@ -275,7 +275,11 @@ export class SonicSearchManager { * @param limit Maximum number of results * @param offset Offset for pagination */ - searchAccounts(query: string, limit = 10, offset = 0): Promise { + public searchAccounts( + query: string, + limit = 10, + offset = 0, + ): Promise { return this.searchChannel.query( SonicIndexType.Accounts, "users", @@ -290,7 +294,11 @@ export class SonicSearchManager { * @param limit Maximum number of results * @param offset Offset for pagination */ - searchStatuses(query: string, limit = 10, offset = 0): Promise { + public searchStatuses( + query: string, + limit = 10, + offset = 0, + ): Promise { return this.searchChannel.query( SonicIndexType.Statuses, "notes", diff --git a/cli/classes.ts b/cli/classes.ts index b256e222..84e48638 100644 --- a/cli/classes.ts +++ b/cli/classes.ts @@ -16,7 +16,7 @@ export type ArgsType = Interfaces.InferredArgs< export abstract class UserFinderCommand< T extends typeof BaseCommand, > extends BaseCommand { - static baseFlags = { + public static baseFlags = { pattern: Flags.boolean({ char: "p", description: @@ -48,7 +48,7 @@ export abstract class UserFinderCommand< }), }; - static baseArgs = { + public static baseArgs = { identifier: Args.string({ description: "Identifier of the user (by default this must be an address, i.e. name@host.com)", @@ -156,7 +156,7 @@ export abstract class UserFinderCommand< export abstract class EmojiFinderCommand< T extends typeof BaseCommand, > extends BaseCommand { - static baseFlags = { + public static baseFlags = { pattern: Flags.boolean({ char: "p", description: @@ -181,7 +181,7 @@ export abstract class EmojiFinderCommand< }), }; - static baseArgs = { + public static baseArgs = { identifier: Args.string({ description: "Identifier of the emoji (defaults to shortcode)", required: true, diff --git a/cli/commands/emoji/add.ts b/cli/commands/emoji/add.ts index 656a6145..fbc020cb 100644 --- a/cli/commands/emoji/add.ts +++ b/cli/commands/emoji/add.ts @@ -9,7 +9,7 @@ import { BaseCommand } from "~/cli/base"; import { config } from "~/packages/config-manager"; export default class EmojiAdd extends BaseCommand { - static override args = { + public static override args = { shortcode: Args.string({ description: "Shortcode of the emoji", required: true, @@ -20,14 +20,14 @@ export default class EmojiAdd extends BaseCommand { }), }; - static override description = "Adds a new emoji"; + public static override description = "Adds a new emoji"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> baba_yassie ./emojis/baba_yassie.png", "<%= config.bin %> <%= command.id %> baba_yassie https://example.com/emojis/baba_yassie.png", ]; - static override flags = {}; + public static override flags = {}; public async run(): Promise { const { args } = await this.parse(EmojiAdd); diff --git a/cli/commands/emoji/delete.ts b/cli/commands/emoji/delete.ts index c3fdd37a..87281038 100644 --- a/cli/commands/emoji/delete.ts +++ b/cli/commands/emoji/delete.ts @@ -13,18 +13,18 @@ import { config } from "~/packages/config-manager"; export default class EmojiDelete extends EmojiFinderCommand< typeof EmojiDelete > { - static override args = { + public static override args = { identifier: EmojiFinderCommand.baseArgs.identifier, }; - static override description = "Deletes an emoji"; + public static override description = "Deletes an emoji"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> baba_yassie", '<%= config.bin %> <%= command.id %> "baba\\*" --pattern', ]; - static override flags = { + public static override flags = { confirm: Flags.boolean({ description: "Ask for confirmation before deleting the emoji (default yes)", diff --git a/cli/commands/emoji/import.ts b/cli/commands/emoji/import.ts index 7a939852..7089805a 100644 --- a/cli/commands/emoji/import.ts +++ b/cli/commands/emoji/import.ts @@ -20,22 +20,22 @@ type MetaType = { }; export default class EmojiImport extends BaseCommand { - static override args = { + public static override args = { path: Args.string({ description: "Path to the emoji archive (can be an URL)", required: true, }), }; - static override description = + public static override description = "Imports emojis from a zip file (which can be fetched from a zip URL, e.g. for Pleroma emoji packs)"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> https://volpeon.ink/emojis/neocat/neocat.zip", "<%= config.bin %> <%= command.id %> export.zip", ]; - static override flags = { + public static override flags = { confirm: Flags.boolean({ description: "Ask for confirmation before deleting the emoji (default yes)", diff --git a/cli/commands/emoji/list.ts b/cli/commands/emoji/list.ts index 130ad571..9c2afd83 100644 --- a/cli/commands/emoji/list.ts +++ b/cli/commands/emoji/list.ts @@ -6,16 +6,16 @@ import { BaseCommand } from "~/cli/base"; import { formatArray } from "~/cli/utils/format"; export default class EmojiList extends BaseCommand { - static override args = {}; + public static override args = {}; - static override description = "List all emojis"; + public static override description = "List all emojis"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> --format json --local", "<%= config.bin %> <%= command.id %>", ]; - static override flags = { + public static override flags = { format: Flags.string({ char: "f", description: "Output format", diff --git a/cli/commands/federation/instance/fetch.ts b/cli/commands/federation/instance/fetch.ts index 33d49687..5687e37b 100644 --- a/cli/commands/federation/instance/fetch.ts +++ b/cli/commands/federation/instance/fetch.ts @@ -7,18 +7,18 @@ import { formatArray } from "~/cli/utils/format"; export default class FederationInstanceFetch extends BaseCommand< typeof FederationInstanceFetch > { - static override args = { + public static override args = { url: Args.string({ description: "URL of the remote instance", required: true, }), }; - static override description = "Fetch metadata from remote instances"; + public static override description = "Fetch metadata from remote instances"; - static override examples = ["<%= config.bin %> <%= command.id %>"]; + public static override examples = ["<%= config.bin %> <%= command.id %>"]; - static override flags = {}; + public static override flags = {}; public async run(): Promise { const { args } = await this.parse(FederationInstanceFetch); diff --git a/cli/commands/federation/user/fetch.ts b/cli/commands/federation/user/fetch.ts index 329a45ed..33271d0b 100644 --- a/cli/commands/federation/user/fetch.ts +++ b/cli/commands/federation/user/fetch.ts @@ -8,18 +8,18 @@ import { BaseCommand } from "~/cli/base"; export default class FederationUserFetch extends BaseCommand< typeof FederationUserFetch > { - static override args = { + public static override args = { address: Args.string({ description: "Address of remote user (name@host.com)", required: true, }), }; - static override description = "Fetch remote users"; + public static override description = "Fetch remote users"; - static override examples = ["<%= config.bin %> <%= command.id %>"]; + public static override examples = ["<%= config.bin %> <%= command.id %>"]; - static override flags = {}; + public static override flags = {}; public async run(): Promise { const { args } = await this.parse(FederationUserFetch); diff --git a/cli/commands/federation/user/finger.ts b/cli/commands/federation/user/finger.ts index ab8fe1d4..78f7aac1 100644 --- a/cli/commands/federation/user/finger.ts +++ b/cli/commands/federation/user/finger.ts @@ -8,18 +8,19 @@ import { BaseCommand } from "~/cli/base"; export default class FederationUserFinger extends BaseCommand< typeof FederationUserFinger > { - static override args = { + public static override args = { address: Args.string({ description: "Address of remote user (name@host.com)", required: true, }), }; - static override description = "Fetch the URL of remote users via WebFinger"; + public static override description = + "Fetch the URL of remote users via WebFinger"; - static override examples = ["<%= config.bin %> <%= command.id %>"]; + public static override examples = ["<%= config.bin %> <%= command.id %>"]; - static override flags = {}; + public static override flags = {}; public async run(): Promise { const { args } = await this.parse(FederationUserFinger); diff --git a/cli/commands/generate-keys.ts b/cli/commands/generate-keys.ts index f9ba1126..d1f344da 100644 --- a/cli/commands/generate-keys.ts +++ b/cli/commands/generate-keys.ts @@ -3,11 +3,12 @@ import chalk from "chalk"; import { BaseCommand } from "~/cli/base"; export default class GenerateKeys extends BaseCommand { - static override args = {}; + public static override args = {}; - static override description = "Generates keys to use in Versia Server"; + public static override description = + "Generates keys to use in Versia Server"; - static override flags = {}; + public static override flags = {}; public async run(): Promise { const { public_key, private_key } = await User.generateKeys(); diff --git a/cli/commands/index/rebuild.ts b/cli/commands/index/rebuild.ts index dff65fea..bf79a4e5 100644 --- a/cli/commands/index/rebuild.ts +++ b/cli/commands/index/rebuild.ts @@ -5,7 +5,7 @@ import { BaseCommand } from "~/cli/base"; import { config } from "~/packages/config-manager"; export default class IndexRebuild extends BaseCommand { - static override args = { + public static override args = { type: Args.string({ description: "Index category to rebuild", options: ["accounts", "statuses"], @@ -13,11 +13,11 @@ export default class IndexRebuild extends BaseCommand { }), }; - static override description = "Rebuild search indexes"; + public static override description = "Rebuild search indexes"; - static override examples = ["<%= config.bin %> <%= command.id %>"]; + public static override examples = ["<%= config.bin %> <%= command.id %>"]; - static override flags = { + public static override flags = { "batch-size": Flags.integer({ char: "b", description: "Number of items to process in each batch", diff --git a/cli/commands/start.ts b/cli/commands/start.ts index 07de501a..f84366d1 100644 --- a/cli/commands/start.ts +++ b/cli/commands/start.ts @@ -3,16 +3,16 @@ import { Flags } from "@oclif/core"; import { BaseCommand } from "~/cli/base"; export default class Start extends BaseCommand { - static override args = {}; + public static override args = {}; - static override description = "Starts Versia Server"; + public static override description = "Starts Versia Server"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> --threads 4", "<%= config.bin %> <%= command.id %> --all-threads", ]; - static override flags = { + public static override flags = { threads: Flags.integer({ char: "t", description: "Number of threads to use", diff --git a/cli/commands/user/create.ts b/cli/commands/user/create.ts index d009b30a..f9322540 100644 --- a/cli/commands/user/create.ts +++ b/cli/commands/user/create.ts @@ -9,21 +9,21 @@ import { BaseCommand } from "~/cli/base"; import { formatArray } from "~/cli/utils/format"; export default class UserCreate extends BaseCommand { - static override args = { + public static override args = { username: Args.string({ description: "Username", required: true, }), }; - static override description = "Creates a new user"; + public static override description = "Creates a new user"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> johngastron --email joe@gamer.com", "<%= config.bin %> <%= command.id %> bimbobaggins", ]; - static override flags = { + public static override flags = { format: Flags.string({ char: "f", description: diff --git a/cli/commands/user/delete.ts b/cli/commands/user/delete.ts index da440947..3cea2ecf 100644 --- a/cli/commands/user/delete.ts +++ b/cli/commands/user/delete.ts @@ -6,15 +6,15 @@ import { UserFinderCommand } from "~/cli/classes"; import { formatArray } from "~/cli/utils/format"; export default class UserDelete extends UserFinderCommand { - static override description = "Deletes users"; + public static override description = "Deletes users"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> johngastron --type username", "<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912", '<%= config.bin %> <%= command.id %> "*badword*" --pattern --type username', ]; - static override flags = { + public static override flags = { confirm: Flags.boolean({ description: "Ask for confirmation before deleting the user (default yes)", @@ -23,7 +23,7 @@ export default class UserDelete extends UserFinderCommand { }), }; - static override args = { + public static override args = { identifier: UserFinderCommand.baseArgs.identifier, }; diff --git a/cli/commands/user/list.ts b/cli/commands/user/list.ts index c77532d7..6f5058eb 100644 --- a/cli/commands/user/list.ts +++ b/cli/commands/user/list.ts @@ -6,16 +6,16 @@ import { BaseCommand } from "~/cli/base"; import { formatArray } from "~/cli/utils/format"; export default class UserList extends BaseCommand { - static override args = {}; + public static override args = {}; - static override description = "List all users"; + public static override description = "List all users"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> --format json --local", "<%= config.bin %> <%= command.id %>", ]; - static override flags = { + public static override flags = { format: Flags.string({ char: "f", description: "Output format", diff --git a/cli/commands/user/refetch.ts b/cli/commands/user/refetch.ts index 8e44f79f..02f6b31b 100644 --- a/cli/commands/user/refetch.ts +++ b/cli/commands/user/refetch.ts @@ -6,14 +6,14 @@ import { UserFinderCommand } from "~/cli/classes"; import { formatArray } from "~/cli/utils/format"; export default class UserRefetch extends UserFinderCommand { - static override description = "Refetch remote users"; + public static override description = "Refetch remote users"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> johngastron --type username", "<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912", ]; - static override flags = { + public static override flags = { confirm: Flags.boolean({ description: "Ask for confirmation before refetching the user (default yes)", @@ -27,7 +27,7 @@ export default class UserRefetch extends UserFinderCommand { }), }; - static override args = { + public static override args = { identifier: UserFinderCommand.baseArgs.identifier, }; diff --git a/cli/commands/user/reset.ts b/cli/commands/user/reset.ts index 6114e7cd..f90049b3 100644 --- a/cli/commands/user/reset.ts +++ b/cli/commands/user/reset.ts @@ -7,14 +7,14 @@ import { formatArray } from "~/cli/utils/format"; import { config } from "~/packages/config-manager"; export default class UserReset extends UserFinderCommand { - static override description = "Resets users' passwords"; + public static override description = "Resets users' passwords"; - static override examples = [ + public static override examples = [ "<%= config.bin %> <%= command.id %> johngastron --type username", "<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912", ]; - static override flags = { + public static override flags = { confirm: Flags.boolean({ description: "Ask for confirmation before deleting the user (default yes)", @@ -32,7 +32,7 @@ export default class UserReset extends UserFinderCommand { }), }; - static override args = { + public static override args = { identifier: UserFinderCommand.baseArgs.identifier, }; diff --git a/packages/plugin-kit/plugin.ts b/packages/plugin-kit/plugin.ts index 916181ee..f607e4b9 100644 --- a/packages/plugin-kit/plugin.ts +++ b/packages/plugin-kit/plugin.ts @@ -19,9 +19,9 @@ export class Plugin { fn: (app: OpenAPIHono>) => void; }[] = []; - constructor(private configSchema: ConfigSchema) {} + public constructor(private configSchema: ConfigSchema) {} - get middleware() { + public get middleware() { // Middleware that adds the plugin's configuration to the request object return createMiddleware>( async (context, next) => { @@ -70,7 +70,7 @@ export class Plugin { this.handlers[hook] = handler; } - static [Symbol.hasInstance](instance: unknown): boolean { + public static [Symbol.hasInstance](instance: unknown): boolean { return ( typeof instance === "object" && instance !== null && diff --git a/types/api.ts b/types/api.ts index b40b5cbc..c0cf6390 100644 --- a/types/api.ts +++ b/types/api.ts @@ -64,7 +64,7 @@ export type HonoEnv = { }; export interface ApiRouteExports { - meta: ApiRouteMetadata; + meta?: ApiRouteMetadata; schemas?: { query?: z.AnyZodObject; body?: z.AnyZodObject;