diff --git a/classes/database/application.ts b/classes/database/application.ts index 6a7c7aa3..945254fa 100644 --- a/classes/database/application.ts +++ b/classes/database/application.ts @@ -12,7 +12,7 @@ import { import { z } from "zod"; import { BaseInterface } from "./base.ts"; -export type ApplicationType = InferSelectModel; +type ApplicationType = InferSelectModel; export class Application extends BaseInterface { public static schema: z.ZodType = z.object({ @@ -23,6 +23,8 @@ export class Application extends BaseInterface { scopes: z.string().optional(), }); + public static $type: ApplicationType; + public async reload(): Promise { const reloaded = await Application.fromId(this.data.id); diff --git a/classes/database/attachment.ts b/classes/database/attachment.ts index cd1b522f..2d8dec03 100644 --- a/classes/database/attachment.ts +++ b/classes/database/attachment.ts @@ -16,7 +16,7 @@ import { MediaBackendType } from "~/packages/config-manager/config.type"; import { config } from "~/packages/config-manager/index.ts"; import { BaseInterface } from "./base.ts"; -export type AttachmentType = InferSelectModel; +type AttachmentType = InferSelectModel; export class Attachment extends BaseInterface { public static schema: z.ZodType = z.object({ @@ -47,6 +47,8 @@ export class Attachment extends BaseInterface { blurhash: z.string().nullable(), }); + public static $type: AttachmentType; + public async reload(): Promise { const reloaded = await Attachment.fromId(this.data.id); diff --git a/classes/database/emoji.ts b/classes/database/emoji.ts index a6feec5d..d37f97fd 100644 --- a/classes/database/emoji.ts +++ b/classes/database/emoji.ts @@ -17,7 +17,7 @@ import { z } from "zod"; import { BaseInterface } from "./base.ts"; import { Instance } from "./instance.ts"; -export type EmojiWithInstance = InferSelectModel & { +type EmojiWithInstance = InferSelectModel & { instance: InferSelectModel | null; }; @@ -30,6 +30,8 @@ export class Emoji extends BaseInterface { static_url: z.string(), }); + public static $type: EmojiWithInstance; + public async reload(): Promise { const reloaded = await Emoji.fromId(this.data.id); diff --git a/classes/database/instance.ts b/classes/database/instance.ts index 3cc71513..7315a38d 100644 --- a/classes/database/instance.ts +++ b/classes/database/instance.ts @@ -20,9 +20,11 @@ import { config } from "~/packages/config-manager/index.ts"; import { BaseInterface } from "./base.ts"; import { User } from "./user.ts"; -export type InstanceType = InferSelectModel; +type InstanceType = InferSelectModel; export class Instance extends BaseInterface { + public static $type: InstanceType; + public async reload(): Promise { const reloaded = await Instance.fromId(this.data.id); diff --git a/classes/database/like.ts b/classes/database/like.ts index e3e0aed1..5759b2ac 100644 --- a/classes/database/like.ts +++ b/classes/database/like.ts @@ -1,7 +1,12 @@ import { RolePermission } from "@versia/client/types"; import type { Delete, LikeExtension } from "@versia/federation/types"; import { db } from "@versia/kit/db"; -import { Likes, Notifications } from "@versia/kit/tables"; +import { + Likes, + type Notes, + Notifications, + type Users, +} from "@versia/kit/tables"; import { type InferInsertModel, type InferSelectModel, @@ -13,15 +18,13 @@ import { } from "drizzle-orm"; import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; -import type { Status } from "../functions/status.ts"; -import type { UserType } from "../functions/user.ts"; import { BaseInterface } from "./base.ts"; import { Note } from "./note.ts"; import { User } from "./user.ts"; -export type LikeType = InferSelectModel & { - liker: UserType; - liked: Status; +type LikeType = InferSelectModel & { + liker: InferSelectModel; + liked: InferSelectModel; }; export class Like extends BaseInterface { @@ -35,6 +38,8 @@ export class Like extends BaseInterface { icon: z.string().nullable(), }); + public static $type: LikeType; + public async reload(): Promise { const reloaded = await Like.fromId(this.data.id); diff --git a/classes/database/note.ts b/classes/database/note.ts index 103f509e..0cc6e3cd 100644 --- a/classes/database/note.ts +++ b/classes/database/note.ts @@ -14,7 +14,7 @@ import type { Delete as VersiaDelete, Note as VersiaNote, } from "@versia/federation/types"; -import { Notification, db } from "@versia/kit/db"; +import { type Instance, Notification, db } from "@versia/kit/db"; import { Attachments, EmojiToNote, @@ -24,6 +24,7 @@ import { } from "@versia/kit/tables"; import { type InferInsertModel, + type InferSelectModel, type SQL, and, desc, @@ -36,7 +37,6 @@ import { htmlToText } from "html-to-text"; import { createRegExp, exactly, global } from "magic-regexp"; import { z } from "zod"; import { - type StatusWithRelations, contentToHtml, findManyNotes, parseTextMentions, @@ -48,10 +48,37 @@ import { BaseInterface } from "./base.ts"; import { Emoji } from "./emoji.ts"; import { User } from "./user.ts"; +type NoteType = InferSelectModel; + +type NoteTypeWithRelations = NoteType & { + author: typeof User.$type; + mentions: (InferSelectModel & { + instance: typeof Instance.$type | null; + })[]; + attachments: (typeof Attachment.$type)[]; + reblog: NoteTypeWithoutRecursiveRelations | null; + emojis: (typeof Emoji.$type)[]; + reply: NoteType | null; + quote: NoteType | null; + application: typeof Application.$type | null; + reblogCount: number; + likeCount: number; + replyCount: number; + pinned: boolean; + reblogged: boolean; + muted: boolean; + liked: boolean; +}; + +export type NoteTypeWithoutRecursiveRelations = Omit< + NoteTypeWithRelations, + "reply" | "quote" | "reblog" +>; + /** * Gives helpers to fetch notes from database in a nice format */ -export class Note extends BaseInterface { +export class Note extends BaseInterface { public static schema: z.ZodType = z.object({ id: z.string().uuid(), uri: z.string().url(), @@ -142,7 +169,9 @@ export class Note extends BaseInterface { bookmarked: z.boolean(), }); - public save(): Promise { + public static $type: NoteTypeWithRelations; + + public save(): Promise { return this.update(this.data); } @@ -814,8 +843,8 @@ export class Note extends BaseInterface { } public async update( - newStatus: Partial, - ): Promise { + newStatus: Partial, + ): Promise { await db.update(Notes).set(newStatus).where(eq(Notes.id, this.data.id)); const updated = await Note.fromId(this.data.id); @@ -932,7 +961,7 @@ export class Note extends BaseInterface { // TODO: Add polls poll: null, reblog: data.reblog - ? await new Note(data.reblog as StatusWithRelations).toApi( + ? await new Note(data.reblog as NoteTypeWithRelations).toApi( userFetching, ) : null, diff --git a/classes/database/notification.ts b/classes/database/notification.ts index 8f42bc6f..79374e27 100644 --- a/classes/database/notification.ts +++ b/classes/database/notification.ts @@ -12,9 +12,7 @@ import { import { z } from "zod"; import { MediaBackendType } from "~/packages/config-manager/config.type"; import { config } from "~/packages/config-manager/index.ts"; -import type { StatusWithRelations } from "../functions/status.ts"; import { - type UserWithRelations, transformOutputToUserWithRelations, userExtrasTemplate, userRelations, @@ -22,8 +20,8 @@ import { import { BaseInterface } from "./base.ts"; export type NotificationType = InferSelectModel & { - status: StatusWithRelations | null; - account: UserWithRelations; + status: typeof Note.$type | null; + account: typeof User.$type; }; export class Notification extends BaseInterface< diff --git a/classes/database/relationship.ts b/classes/database/relationship.ts index a79ad3f5..5e5e4b8d 100644 --- a/classes/database/relationship.ts +++ b/classes/database/relationship.ts @@ -14,9 +14,9 @@ import { z } from "zod"; import { BaseInterface } from "./base.ts"; import type { User } from "./user.ts"; -export type RelationshipType = InferSelectModel; +type RelationshipType = InferSelectModel; -export type RelationshipWithOpposite = RelationshipType & { +type RelationshipWithOpposite = RelationshipType & { followedBy: boolean; blockedBy: boolean; requestedBy: boolean; @@ -43,6 +43,8 @@ export class Relationship extends BaseInterface< showing_reblogs: z.boolean(), }); + public static $type: RelationshipWithOpposite; + public async reload(): Promise { const reloaded = await Relationship.fromId(this.data.id); diff --git a/classes/database/role.ts b/classes/database/role.ts index 37cb1c70..8cd56a57 100644 --- a/classes/database/role.ts +++ b/classes/database/role.ts @@ -18,7 +18,7 @@ import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; import { BaseInterface } from "./base.ts"; -export type RoleType = InferSelectModel; +type RoleType = InferSelectModel; export class Role extends BaseInterface { public static schema = z.object({ @@ -31,6 +31,8 @@ export class Role extends BaseInterface { icon: z.string().nullable(), }); + public static $type: RoleType; + public async reload(): Promise { const reloaded = await Role.fromId(this.data.id); diff --git a/classes/database/token.ts b/classes/database/token.ts index 0a5b009b..25e564c2 100644 --- a/classes/database/token.ts +++ b/classes/database/token.ts @@ -1,6 +1,6 @@ import type { Token as ApiToken } from "@versia/client/types"; -import { User, db } from "@versia/kit/db"; -import { type Applications, Tokens } from "@versia/kit/tables"; +import { type Application, User, db } from "@versia/kit/db"; +import { Tokens } from "@versia/kit/tables"; import { type InferInsertModel, type InferSelectModel, @@ -12,8 +12,8 @@ import { import { z } from "zod"; import { BaseInterface } from "./base.ts"; -export type TokenType = InferSelectModel & { - application: InferSelectModel | null; +type TokenType = InferSelectModel & { + application: typeof Application.$type | null; }; export class Token extends BaseInterface { @@ -24,6 +24,8 @@ export class Token extends BaseInterface { created_at: z.number(), }); + public static $type: TokenType; + public async reload(): Promise { const reloaded = await Token.fromId(this.data.id); diff --git a/classes/database/user.ts b/classes/database/user.ts index d55c2c52..478af0d6 100644 --- a/classes/database/user.ts +++ b/classes/database/user.ts @@ -33,6 +33,7 @@ import { import chalk from "chalk"; import { type InferInsertModel, + type InferSelectModel, type SQL, and, countDistinct, @@ -47,7 +48,6 @@ import { import { htmlToText } from "html-to-text"; import { z } from "zod"; import { - type UserWithRelations, findManyUsers, followAcceptToVersia, followRejectToVersia, @@ -64,6 +64,18 @@ import type { Note } from "./note.ts"; import { Relationship } from "./relationship.ts"; import { Role } from "./role.ts"; +type UserWithInstance = InferSelectModel & { + instance: typeof Instance.$type | null; +}; + +type UserWithRelations = UserWithInstance & { + emojis: (typeof Emoji.$type)[]; + followerCount: number; + followingCount: number; + statusCount: number; + roles: (typeof Role.$type)[]; +}; + /** * Gives helpers to fetch users from database in a nice format */ @@ -125,6 +137,8 @@ export class User extends BaseInterface { mute_expires_at: z.string().optional(), }); + public static $type: UserWithRelations; + public async reload(): Promise { const reloaded = await User.fromId(this.data.id); diff --git a/classes/functions/status.ts b/classes/functions/status.ts index ade0d2a6..1e12118a 100644 --- a/classes/functions/status.ts +++ b/classes/functions/status.ts @@ -2,22 +2,9 @@ import { mentionValidator } from "@/api"; import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization"; import markdownItTaskLists from "@hackmd/markdown-it-task-lists"; import type { ContentFormat } from "@versia/federation/types"; -import { User, db } from "@versia/kit/db"; -import { - type Attachments, - Instances, - type Notes, - Users, -} from "@versia/kit/tables"; -import { - type InferSelectModel, - and, - eq, - inArray, - isNull, - or, - sql, -} from "drizzle-orm"; +import { type Note, User, db } from "@versia/kit/db"; +import { Instances, Users } from "@versia/kit/tables"; +import { and, eq, inArray, isNull, or, sql } from "drizzle-orm"; import linkifyHtml from "linkify-html"; import { anyOf, @@ -31,42 +18,13 @@ import { import MarkdownIt from "markdown-it"; import markdownItContainer from "markdown-it-container"; import markdownItTocDoneRight from "markdown-it-toc-done-right"; -import type { ApplicationType } from "~/classes/database/application.ts"; -import type { EmojiWithInstance } from "~/classes/database/emoji.ts"; import { config } from "~/packages/config-manager/index.ts"; import { - type UserWithInstance, - type UserWithRelations, transformOutputToUserWithRelations, userExtrasTemplate, userRelations, } from "./user.ts"; -export type Status = InferSelectModel; - -export type StatusWithRelations = Status & { - author: UserWithRelations; - mentions: UserWithInstance[]; - attachments: InferSelectModel[]; - reblog: StatusWithoutRecursiveRelations | null; - emojis: EmojiWithInstance[]; - reply: Status | null; - quote: Status | null; - application: ApplicationType | null; - reblogCount: number; - likeCount: number; - replyCount: number; - pinned: boolean; - reblogged: boolean; - muted: boolean; - liked: boolean; -}; - -export type StatusWithoutRecursiveRelations = Omit< - StatusWithRelations, - "reply" | "quote" | "reblog" ->; - /** * Wrapper against the Status object to make it easier to work with * @param query @@ -75,7 +33,7 @@ export type StatusWithoutRecursiveRelations = Omit< export const findManyNotes = async ( query: Parameters[0], userId?: string, -): Promise => { +): Promise<(typeof Note.$type)[]> => { const output = await db.query.Notes.findMany({ ...query, with: { diff --git a/classes/functions/user.ts b/classes/functions/user.ts index b665ae7d..0f126996 100644 --- a/classes/functions/user.ts +++ b/classes/functions/user.ts @@ -3,25 +3,17 @@ import type { FollowAccept, FollowReject, } from "@versia/federation/types"; -import { type Application, type Token, type User, db } from "@versia/kit/db"; -import type { Instances, Roles, Users } from "@versia/kit/tables"; +import { + type Application, + type Emoji, + type Instance, + type Role, + type Token, + type User, + db, +} from "@versia/kit/db"; +import type { Users } from "@versia/kit/tables"; import { type InferSelectModel, type SQL, sql } from "drizzle-orm"; -import type { EmojiWithInstance } from "~/classes/database/emoji.ts"; - -export type UserType = InferSelectModel; - -export type UserWithInstance = UserType & { - instance: InferSelectModel | null; -}; - -export type UserWithRelations = UserType & { - instance: InferSelectModel | null; - emojis: EmojiWithInstance[]; - followerCount: number; - followingCount: number; - statusCount: number; - roles: InferSelectModel[]; -}; export const userRelations = { instance: true, @@ -84,24 +76,24 @@ export interface AuthData { } export const transformOutputToUserWithRelations = ( - user: Omit & { + user: Omit, "endpoints"> & { followerCount: unknown; followingCount: unknown; statusCount: unknown; emojis: { userId: string; emojiId: string; - emoji?: EmojiWithInstance; + emoji?: typeof Emoji.$type; }[]; - instance: InferSelectModel | null; + instance: typeof Instance.$type | null; roles: { userId: string; roleId: string; - role?: InferSelectModel; + role?: typeof Role.$type; }[]; endpoints: unknown; }, -): UserWithRelations => { +): typeof User.$type => { return { ...user, followerCount: Number(user.followerCount), @@ -121,17 +113,17 @@ export const transformOutputToUserWithRelations = ( emojis: user.emojis.map( (emoji) => (emoji as unknown as Record) - .emoji as EmojiWithInstance, + .emoji as typeof Emoji.$type, ), roles: user.roles .map((role) => role.role) - .filter(Boolean) as InferSelectModel[], + .filter(Boolean) as (typeof Role.$type)[], }; }; export const findManyUsers = async ( query: Parameters[0], -): Promise => { +): Promise<(typeof User.$type)[]> => { const output = await db.query.Users.findMany({ ...query, with: { diff --git a/cli/classes.ts b/cli/classes.ts index e2902dd0..13cd0c3b 100644 --- a/cli/classes.ts +++ b/cli/classes.ts @@ -1,15 +1,9 @@ import { parseUserAddress, userAddressValidator } from "@/api"; import { Args, type Command, Flags, type Interfaces } from "@oclif/core"; -import { Instance, User, db } from "@versia/kit/db"; +import { type Emoji, Instance, User, db } from "@versia/kit/db"; import { Emojis, Instances, Users } from "@versia/kit/tables"; import chalk from "chalk"; -import { - type InferSelectModel, - and, - eq, - getTableColumns, - like, -} from "drizzle-orm"; +import { and, eq, getTableColumns, like } from "drizzle-orm"; import { BaseCommand } from "./base.ts"; export type FlagsType = Interfaces.InferredFlags< @@ -210,9 +204,12 @@ export abstract class EmojiFinderCommand< } public async findEmojis(): Promise< - (InferSelectModel & { - instanceUrl: string | null; - })[] + Omit< + typeof Emoji.$type & { + instanceUrl: string | null; + }, + "instance" + >[] > { // Check if there are asterisks in the identifier but no pattern flag, warn the user if so if (this.args.identifier.includes("*") && !this.flags.pattern) { diff --git a/plugins/openid/utils.ts b/plugins/openid/utils.ts index 068c3525..b7f36c84 100644 --- a/plugins/openid/utils.ts +++ b/plugins/openid/utils.ts @@ -1,6 +1,6 @@ -import { db } from "@versia/kit/db"; +import { type Application, db } from "@versia/kit/db"; import type { InferSelectModel, SQL } from "@versia/kit/drizzle"; -import type { Applications, OpenIdLoginFlows } from "@versia/kit/tables"; +import type { OpenIdLoginFlows } from "@versia/kit/tables"; import { type AuthorizationResponseError, type AuthorizationServer, @@ -18,7 +18,6 @@ import { userInfoRequest, validateAuthResponse, } from "oauth4webapi"; -import type { ApplicationType } from "~/classes/database/application"; export const oauthDiscoveryRequest = ( issuerUrl: string | URL, @@ -37,7 +36,7 @@ const getFlow = ( flowId: string, ): Promise< | (InferSelectModel & { - application?: ApplicationType | null; + application?: typeof Application.$type | null; }) | undefined > => { @@ -143,7 +142,7 @@ export const automaticOidcFlow = async ( message: string, flow: | (InferSelectModel & { - application?: InferSelectModel | null; + application?: typeof Application.$type | null; }) | null, ) => Response, @@ -152,7 +151,7 @@ export const automaticOidcFlow = async ( | { userInfo: UserInfoResponse; flow: InferSelectModel & { - application?: ApplicationType | null; + application?: typeof Application.$type | null; }; claims: Record; } diff --git a/tests/oauth-scopes.test.ts b/tests/oauth-scopes.test.ts index 22722bd7..c80bd649 100644 --- a/tests/oauth-scopes.test.ts +++ b/tests/oauth-scopes.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it } from "bun:test"; import { checkIfOauthIsValid } from "@/oauth"; import { Application } from "@versia/kit/db"; -import type { ApplicationType } from "~/classes/database/application"; - describe("checkIfOauthIsValid", () => { it("should return true when routeScopes and application.scopes are empty", () => { - const application = new Application({ scopes: "" } as ApplicationType); + const application = new Application({ + scopes: "", + } as typeof Application.$type); const routeScopes: string[] = []; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -14,7 +14,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes is empty and application.scopes contains write:* or write", () => { const application = new Application({ scopes: "write:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes: string[] = []; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -23,7 +23,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes is empty and application.scopes contains read:* or read", () => { const application = new Application({ scopes: "read:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes: string[] = []; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -32,7 +32,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes contains only write: permissions and application.scopes contains write:* or write", () => { const application = new Application({ scopes: "write:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "write:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -41,7 +41,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes contains only read: permissions and application.scopes contains read:* or read", () => { const application = new Application({ scopes: "read:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["read:users", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -50,7 +50,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes contains both write: and read: permissions and application.scopes contains write:* or write and read:* or read", () => { const application = new Application({ scopes: "write:* read:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -59,7 +59,7 @@ describe("checkIfOauthIsValid", () => { it("should return false when routeScopes contains write: permissions but application.scopes does not contain write:* or write", () => { const application = new Application({ scopes: "read:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "write:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(false); @@ -68,14 +68,16 @@ describe("checkIfOauthIsValid", () => { it("should return false when routeScopes contains read: permissions but application.scopes does not contain read:* or read", () => { const application = new Application({ scopes: "write:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["read:users", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(false); }); it("should return false when routeScopes contains both write: and read: permissions but application.scopes does not contain write:* or write and read:* or read", () => { - const application = new Application({ scopes: "" } as ApplicationType); + const application = new Application({ + scopes: "", + } as typeof Application.$type); const routeScopes = ["write:users", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(false); @@ -84,7 +86,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes contains a mix of valid and invalid permissions and application.scopes contains all the required permissions", () => { const application = new Application({ scopes: "write:* read:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "invalid:permission", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -93,7 +95,7 @@ describe("checkIfOauthIsValid", () => { it("should return false when routeScopes contains a mix of valid and invalid permissions but application.scopes does not contain all the required permissions", () => { const application = new Application({ scopes: "write:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "invalid:permission", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(false); @@ -102,7 +104,7 @@ describe("checkIfOauthIsValid", () => { it("should return true when routeScopes contains a mix of valid write and read permissions and application.scopes contains all the required permissions", () => { const application = new Application({ scopes: "write:* read:posts", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(true); @@ -111,7 +113,7 @@ describe("checkIfOauthIsValid", () => { it("should return false when routeScopes contains a mix of valid write and read permissions but application.scopes does not contain all the required permissions", () => { const application = new Application({ scopes: "write:*", - } as ApplicationType); + } as typeof Application.$type); const routeScopes = ["write:users", "read:posts"]; const result = checkIfOauthIsValid(application, routeScopes); expect(result).toBe(false); diff --git a/tests/utils.ts b/tests/utils.ts index 49d42a9d..cfcf9114 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -3,9 +3,8 @@ import { randomString } from "@/math"; import { Note, Token, User, db } from "@versia/kit/db"; import { Notes, Users } from "@versia/kit/tables"; import { solveChallenge } from "altcha-lib"; -import { asc, inArray, like } from "drizzle-orm"; +import { type InferSelectModel, asc, inArray, like } from "drizzle-orm"; import { appFactory } from "~/app"; -import type { Status } from "~/classes/functions/status"; import { searchManager } from "~/classes/search/search-manager"; import { setupDatabase } from "~/drizzle/db"; import { config } from "~/packages/config-manager"; @@ -92,7 +91,7 @@ export const getTestUsers = async ( export const getTestStatuses = async ( count: number, user: User, - partial?: Partial, + partial?: Partial>, ): Promise => { const statuses: Note[] = [];