diff --git a/bun.lock b/bun.lock index eafb6f8b..05016a3b 100644 --- a/bun.lock +++ b/bun.lock @@ -67,6 +67,7 @@ "zod-validation-error": "catalog:", }, "devDependencies": { + "@biomejs/biome": "catalog:", "@types/bun": "catalog:", "@types/html-to-text": "catalog:", "@types/markdown-it-container": "catalog:", @@ -89,12 +90,15 @@ "name": "@versia-server/api", "version": "0.9.0-alpha.0", "dependencies": { + "@hono/zod-validator": "catalog:", "@logtape/logtape": "catalog:", "@scalar/hono-api-reference": "catalog:", "@versia-server/config": "workspace:*", + "@versia-server/tests": "workspace:*", "@versia/client": "workspace:*", "@versia/kit": "workspace:*", "@versia/sdk": "workspace:*", + "altcha-lib": "catalog:", "bun-bagel": "catalog:", "chalk": "catalog:", "drizzle-orm": "catalog:", @@ -104,12 +108,15 @@ "ip-matching": "catalog:", "iso-639-1": "catalog:", "jose": "catalog:", + "magic-regexp": "catalog:", + "qs": "catalog:", "sharp": "catalog:", "string-comparison": "catalog:", "unicode-emoji-json": "catalog:", "youch": "catalog:", "zod": "catalog:", "zod-openapi": "catalog:", + "zod-validation-error": "catalog:", }, }, "packages/client": { @@ -142,6 +149,8 @@ "name": "@versia/kit", "version": "0.0.0", "dependencies": { + "@hackmd/markdown-it-task-lists": "catalog:", + "@hono/zod-validator": "catalog:", "@logtape/logtape": "catalog:", "@versia-server/config": "workspace:*", "@versia/client": "workspace:*", @@ -152,8 +161,14 @@ "hono": "catalog:", "hono-openapi": "catalog:", "html-to-text": "catalog:", + "ioredis": "catalog:", + "linkify-html": "catalog:", "magic-regexp": "catalog:", + "markdown-it": "catalog:", + "markdown-it-container": "catalog:", + "markdown-it-toc-done-right": "catalog:", "mitt": "catalog:", + "qs": "catalog:", "sharp": "catalog:", "zod": "catalog:", "zod-to-json-schema": "catalog:", @@ -194,6 +209,7 @@ "trustedDependencies": [ "sharp", "esbuild", + "@biomejs/biome", "msgpackr-extract", ], "catalog": { @@ -323,6 +339,24 @@ "@badgateway/oauth2-client": ["@badgateway/oauth2-client@3.2.0", "", {}, "sha512-EHsoV6oLHot7HeYkIoSxCZApNgBjwNo1OTV9kXIDnmijGAshlVkJreVAAtexFn+sfDKPE0JW5SCPYJV1y4IoMg=="], + "@biomejs/biome": ["@biomejs/biome@2.0.0-beta.5", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.0.0-beta.5", "@biomejs/cli-darwin-x64": "2.0.0-beta.5", "@biomejs/cli-linux-arm64": "2.0.0-beta.5", "@biomejs/cli-linux-arm64-musl": "2.0.0-beta.5", "@biomejs/cli-linux-x64": "2.0.0-beta.5", "@biomejs/cli-linux-x64-musl": "2.0.0-beta.5", "@biomejs/cli-win32-arm64": "2.0.0-beta.5", "@biomejs/cli-win32-x64": "2.0.0-beta.5" }, "bin": { "biome": "bin/biome" } }, "sha512-1ldO4AepieVvg4aLi1ubZkA7NsefQT2UTNssbJbDiQTGem8kCHx/PZCwLxIR6UzFpGIjh0xsDzivyVvhnmqmuA=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.0.0-beta.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-pnJiaoDpwGo+ctGkMu4POcO8jgOgCErBdYbhutr+K9rxxJS+TlHLr0LR91GCEWbGV2O1oyZRFQcW21rYFoak4w=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.0.0-beta.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-WwEZpqcmsNoFpZkUFNQcbZo52WK4hLGQ0vZk3PQ8JlZ55gJsHiyhtv6aem6fVlyVCvZgpsC0sYPLE3VvFVKNAQ=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.0.0-beta.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAF1de+Ki0vnq14NwDXouKkAR/iviyMNrUngSHjTGFC4z8XGVEfIw0ZMSm7fAdJZ5fAWodt9HiYmEAVs5EtHQg=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.0.0-beta.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-4vxNkYx1uEt211W8hLdXddc7icRHQgYENb72g6uTd/tLVPSBvIwqUAxAOkU+9Ai1E/8R4sWy7HIxREgpuFgbNA=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.0.0-beta.5", "", { "os": "linux", "cpu": "x64" }, "sha512-I0Pt1VHeL1mN8G7ZwV2u9AfzBd5ZKfbvHUI4x2wETUZbwcQlAu/nEzEa2LUe5HqSmnctTR36ig7RkkM9qbmIrA=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.0.0-beta.5", "", { "os": "linux", "cpu": "x64" }, "sha512-nUeKGO517GtRCxziVD9les1HiCs2s2/WIVITMN9+9RRuLOko8r+T77E8ZXEmlfLOfOIOeE6z62WITqei3oNccA=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.0.0-beta.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-YXW6hgbrgBcWQ1SLO69ypWlluPchgQV5C1lTG4xOcBUWdCsfYuQirM64S6Dov7SFPqsMIoFC6LlQRW+n8qAyiA=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.0.0-beta.5", "", { "os": "win32", "cpu": "x64" }, "sha512-N7Yby52BJmvEdst1iMbclE5hxxefboaXKRJLm1tLfBYr4FeuoCe6j8HdiQSwhCRdIUGFFqBLaDXh//LLF6EReA=="], + "@bull-board/api": ["@bull-board/api@6.10.1", "", { "dependencies": { "redis-info": "^3.1.0" }, "peerDependencies": { "@bull-board/ui": "6.10.1" } }, "sha512-VPkZa2XZI2Wk2MqK1XyiiS+tOhNan54mnm2fpv2KA0fdZ92mQqNjhKkOpsykhQv9XUEc8cCRlZqGxf67YCMJbQ=="], "@bull-board/hono": ["@bull-board/hono@6.10.1", "", { "dependencies": { "@bull-board/api": "6.10.1", "@bull-board/ui": "6.10.1", "ejs": "^3.1.10" }, "peerDependencies": { "hono": "^4" } }, "sha512-2I9BUS7jbtQ4tCKOJdVKQn6uW8MXJKUGIhHLK2r4X8kiXZvk2I7jjt0KZ4VNyF9nfoBblgX5WemxE4sU61kGGg=="], diff --git a/classes/functions/status.ts b/classes/functions/status.ts deleted file mode 100644 index beadfacb..00000000 --- a/classes/functions/status.ts +++ /dev/null @@ -1,359 +0,0 @@ -import markdownItTaskLists from "@hackmd/markdown-it-task-lists"; -import { db, type Note, User } from "@versia/kit/db"; -import { Instances, Users } from "@versia/kit/tables"; -import type * as VersiaEntities from "@versia/sdk/entities"; -import { FederationRequester } from "@versia/sdk/http"; -import { config } from "@versia-server/config"; -import { and, eq, inArray, isNull, or, sql } from "drizzle-orm"; -import linkifyHtml from "linkify-html"; -import { - anyOf, - charIn, - createRegExp, - digit, - exactly, - global, - letter, -} from "magic-regexp"; -import MarkdownIt from "markdown-it"; -import markdownItContainer from "markdown-it-container"; -import markdownItTocDoneRight from "markdown-it-toc-done-right"; -import { mentionValidator } from "@/api"; -import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization"; -import { transformOutputToUserWithRelations, userRelations } from "./user.ts"; - -/** - * Wrapper against the Status object to make it easier to work with - * @param query - * @returns - */ -export const findManyNotes = async ( - query: Parameters[0], - userId?: string, -): Promise<(typeof Note.$type)[]> => { - const output = await db.query.Notes.findMany({ - ...query, - with: { - ...query?.with, - attachments: { - with: { - media: true, - }, - }, - reactions: { - with: { - emoji: { - with: { - instance: true, - media: true, - }, - }, - }, - }, - emojis: { - with: { - emoji: { - with: { - instance: true, - media: true, - }, - }, - }, - }, - author: { - with: { - ...userRelations, - }, - }, - mentions: { - with: { - user: { - with: { - instance: true, - }, - }, - }, - }, - reblog: { - with: { - attachments: { - with: { - media: true, - }, - }, - reactions: { - with: { - emoji: { - with: { - instance: true, - media: true, - }, - }, - }, - }, - emojis: { - with: { - emoji: { - with: { - instance: true, - media: true, - }, - }, - }, - }, - likes: true, - application: true, - mentions: { - with: { - user: { - with: userRelations, - }, - }, - }, - author: { - with: { - ...userRelations, - }, - }, - }, - extras: { - pinned: userId - ? sql`EXISTS (SELECT 1 FROM "UserToPinnedNotes" WHERE "UserToPinnedNotes"."noteId" = "Notes_reblog".id AND "UserToPinnedNotes"."userId" = ${userId})`.as( - "pinned", - ) - : sql`false`.as("pinned"), - reblogged: userId - ? sql`EXISTS (SELECT 1 FROM "Notes" WHERE "Notes"."authorId" = ${userId} AND "Notes"."reblogId" = "Notes_reblog".id)`.as( - "reblogged", - ) - : sql`false`.as("reblogged"), - muted: userId - ? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."ownerId" = ${userId} AND "Relationships"."subjectId" = "Notes_reblog"."authorId" AND "Relationships"."muting" = true)`.as( - "muted", - ) - : sql`false`.as("muted"), - liked: userId - ? sql`EXISTS (SELECT 1 FROM "Likes" WHERE "Likes"."likedId" = "Notes_reblog".id AND "Likes"."likerId" = ${userId})`.as( - "liked", - ) - : sql`false`.as("liked"), - }, - }, - reply: true, - quote: true, - }, - extras: { - pinned: userId - ? sql`EXISTS (SELECT 1 FROM "UserToPinnedNotes" WHERE "UserToPinnedNotes"."noteId" = "Notes".id AND "UserToPinnedNotes"."userId" = ${userId})`.as( - "pinned", - ) - : sql`false`.as("pinned"), - reblogged: userId - ? sql`EXISTS (SELECT 1 FROM "Notes" WHERE "Notes"."authorId" = ${userId} AND "Notes"."reblogId" = "Notes".id)`.as( - "reblogged", - ) - : sql`false`.as("reblogged"), - muted: userId - ? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."ownerId" = ${userId} AND "Relationships"."subjectId" = "Notes"."authorId" AND "Relationships"."muting" = true)`.as( - "muted", - ) - : sql`false`.as("muted"), - liked: userId - ? sql`EXISTS (SELECT 1 FROM "Likes" WHERE "Likes"."likedId" = "Notes".id AND "Likes"."likerId" = ${userId})`.as( - "liked", - ) - : sql`false`.as("liked"), - ...query?.extras, - }, - }); - - return output.map((post) => ({ - ...post, - author: transformOutputToUserWithRelations(post.author), - mentions: post.mentions.map((mention) => ({ - ...mention.user, - endpoints: mention.user.endpoints, - })), - attachments: post.attachments.map((attachment) => attachment.media), - emojis: (post.emojis ?? []).map((emoji) => emoji.emoji), - reblog: post.reblog && { - ...post.reblog, - author: transformOutputToUserWithRelations(post.reblog.author), - mentions: post.reblog.mentions.map((mention) => ({ - ...mention.user, - endpoints: mention.user.endpoints, - })), - attachments: post.reblog.attachments.map( - (attachment) => attachment.media, - ), - emojis: (post.reblog.emojis ?? []).map((emoji) => emoji.emoji), - pinned: Boolean(post.reblog.pinned), - reblogged: Boolean(post.reblog.reblogged), - muted: Boolean(post.reblog.muted), - liked: Boolean(post.reblog.liked), - }, - pinned: Boolean(post.pinned), - reblogged: Boolean(post.reblogged), - muted: Boolean(post.muted), - liked: Boolean(post.liked), - })); -}; - -/** - * Get people mentioned in the content (match @username or @username@domain.com mentions) - * @param text The text to parse mentions from. - * @returns An array of users mentioned in the text. - */ -export const parseTextMentions = async (text: string): Promise => { - const mentionedPeople = [...text.matchAll(mentionValidator)]; - if (mentionedPeople.length === 0) { - return []; - } - - const baseUrlHost = config.http.base_url.host; - const isLocal = (host?: string): boolean => host === baseUrlHost || !host; - - // Find local and matching users - const foundUsers = await db - .select({ - id: Users.id, - username: Users.username, - baseUrl: Instances.baseUrl, - }) - .from(Users) - .leftJoin(Instances, eq(Users.instanceId, Instances.id)) - .where( - or( - ...mentionedPeople.map((person) => - and( - eq(Users.username, person[1] ?? ""), - isLocal(person[2]) - ? isNull(Users.instanceId) - : eq(Instances.baseUrl, person[2] ?? ""), - ), - ), - ), - ); - - // Separate found and unresolved users - const finalList = await User.manyFromSql( - inArray( - Users.id, - foundUsers.map((u) => u.id), - ), - ); - - // Every remote user that isn't in database - const notFoundRemoteUsers = mentionedPeople.filter( - (p) => - !( - foundUsers.some( - (user) => user.username === p[1] && user.baseUrl === p[2], - ) || isLocal(p[2]) - ), - ); - - // Resolve remote mentions not in database - for (const person of notFoundRemoteUsers) { - const url = await FederationRequester.resolveWebFinger( - person[1] ?? "", - person[2] ?? "", - ); - - if (url) { - const user = await User.resolve(url); - - if (user) { - finalList.push(user); - } - } - } - - return finalList; -}; - -export const replaceTextMentions = (text: string, mentions: User[]): string => { - return mentions.reduce((finalText, mention) => { - const { username, instance } = mention.data; - const { uri } = mention; - const baseHost = config.http.base_url.host; - const linkTemplate = (displayText: string): string => - `${displayText}`; - - if (mention.remote) { - return finalText.replaceAll( - `@${username}@${instance?.baseUrl}`, - linkTemplate(`@${username}@${instance?.baseUrl}`), - ); - } - - return finalText.replace( - createRegExp( - exactly( - exactly(`@${username}`) - .notBefore(anyOf(letter, digit, charIn("@"))) - .notAfter(anyOf(letter, digit, charIn("@"))), - ).or(exactly(`@${username}@${baseHost}`)), - [global], - ), - linkTemplate(`@${username}@${baseHost}`), - ); - }, text); -}; - -export const contentToHtml = async ( - content: VersiaEntities.TextContentFormat, - mentions: User[] = [], - inline = false, -): Promise => { - const sanitizer = inline ? sanitizeHtmlInline : sanitizeHtml; - let htmlContent = ""; - - if (content.data["text/html"]) { - htmlContent = await sanitizer(content.data["text/html"].content); - } else if (content.data["text/markdown"]) { - htmlContent = await sanitizer( - await markdownParse(content.data["text/markdown"].content), - ); - } else if (content.data["text/plain"]?.content) { - htmlContent = (await sanitizer(content.data["text/plain"].content)) - .split("\n") - .map((line) => `

${line}

`) - .join("\n"); - } - - htmlContent = replaceTextMentions(htmlContent, mentions); - - return linkifyHtml(htmlContent, { - defaultProtocol: "https", - validate: { email: (): false => false }, - target: "_blank", - rel: "nofollow noopener noreferrer", - }); -}; - -export const markdownParse = async (content: string): Promise => { - return (await getMarkdownRenderer()).render(content); -}; - -export const getMarkdownRenderer = (): MarkdownIt => { - const renderer = MarkdownIt({ - html: true, - linkify: true, - }); - - renderer.use(markdownItTocDoneRight, { - containerClass: "toc", - level: [1, 2, 3, 4], - listType: "ul", - listClass: "toc-list", - itemClass: "toc-item", - linkClass: "toc-link", - }); - - renderer.use(markdownItTaskLists); - - renderer.use(markdownItContainer); - - return renderer; -}; diff --git a/classes/functions/user.ts b/classes/functions/user.ts deleted file mode 100644 index a9cb5726..00000000 --- a/classes/functions/user.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { - type Application, - db, - type Emoji, - type Instance, - type Media, - type Role, - type Token, - type User, -} from "@versia/kit/db"; -import type { Users } from "@versia/kit/tables"; -import type { InferSelectModel } from "drizzle-orm"; - -export const userRelations = { - instance: true, - emojis: { - with: { - emoji: { - with: { - instance: true, - media: true, - }, - }, - }, - }, - avatar: true, - header: true, - roles: { - with: { - role: true, - }, - }, -} as const; - -export interface AuthData { - user: User | null; - token: Token | null; - application: Application | null; -} - -export const transformOutputToUserWithRelations = ( - user: Omit, "endpoints"> & { - followerCount: unknown; - followingCount: unknown; - statusCount: unknown; - avatar: typeof Media.$type | null; - header: typeof Media.$type | null; - emojis: { - userId: string; - emojiId: string; - emoji?: typeof Emoji.$type; - }[]; - instance: typeof Instance.$type | null; - roles: { - userId: string; - roleId: string; - role?: typeof Role.$type; - }[]; - endpoints: unknown; - }, -): typeof User.$type => { - return { - ...user, - followerCount: Number(user.followerCount), - followingCount: Number(user.followingCount), - statusCount: Number(user.statusCount), - endpoints: - user.endpoints ?? - ({} as Partial<{ - dislikes: string; - featured: string; - likes: string; - followers: string; - following: string; - inbox: string; - outbox: string; - }>), - emojis: user.emojis.map( - (emoji) => - (emoji as unknown as Record) - .emoji as typeof Emoji.$type, - ), - roles: user.roles - .map((role) => role.role) - .filter(Boolean) as (typeof Role.$type)[], - }; -}; - -export const findManyUsers = async ( - query: Parameters[0], -): Promise<(typeof User.$type)[]> => { - const output = await db.query.Users.findMany({ - ...query, - with: { - ...userRelations, - ...query?.with, - }, - }); - - return output.map((user) => transformOutputToUserWithRelations(user)); -}; diff --git a/classes/queues/delivery.ts b/classes/queues/delivery.ts index 9f44f98f..8fba83ba 100644 --- a/classes/queues/delivery.ts +++ b/classes/queues/delivery.ts @@ -1,10 +1,10 @@ import { User } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import type { JSONObject } from "@versia/sdk"; import * as VersiaEntities from "@versia/sdk/entities"; import { config } from "@versia-server/config"; import { Queue, Worker } from "bullmq"; import chalk from "chalk"; -import { connection } from "~/utils/redis.ts"; export enum DeliveryJobType { FederateEntity = "federateEntity", diff --git a/classes/queues/fetch.ts b/classes/queues/fetch.ts index 4b5bd098..3be2cd53 100644 --- a/classes/queues/fetch.ts +++ b/classes/queues/fetch.ts @@ -1,9 +1,9 @@ import { Instance } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import { Instances } from "@versia/kit/tables"; import { config } from "@versia-server/config"; import { Queue, Worker } from "bullmq"; import { eq } from "drizzle-orm"; -import { connection } from "~/utils/redis.ts"; export enum FetchJobType { Instance = "instance", diff --git a/classes/queues/inbox.ts b/classes/queues/inbox.ts index 00ed5511..ad1a833f 100644 --- a/classes/queues/inbox.ts +++ b/classes/queues/inbox.ts @@ -1,11 +1,11 @@ import { getLogger } from "@logtape/logtape"; import { ApiError } from "@versia/kit"; import { Instance, User } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import type { JSONObject } from "@versia/sdk"; import { config } from "@versia-server/config"; import { Queue, Worker } from "bullmq"; import type { SocketAddress } from "bun"; -import { connection } from "~/utils/redis.ts"; import { InboxProcessor } from "../inbox/processor.ts"; export enum InboxJobType { diff --git a/classes/queues/media.ts b/classes/queues/media.ts index b5d6b2cf..2e907231 100644 --- a/classes/queues/media.ts +++ b/classes/queues/media.ts @@ -1,7 +1,7 @@ import { Media } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import { config } from "@versia-server/config"; import { Queue, Worker } from "bullmq"; -import { connection } from "~/utils/redis.ts"; import { calculateBlurhash } from "../media/preprocessors/blurhash.ts"; import { convertImage } from "../media/preprocessors/image-conversion.ts"; diff --git a/classes/queues/push.ts b/classes/queues/push.ts index 8bf46086..c7e1a012 100644 --- a/classes/queues/push.ts +++ b/classes/queues/push.ts @@ -1,9 +1,9 @@ import { Note, PushSubscription, Token, User } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import { config } from "@versia-server/config"; import { Queue, Worker } from "bullmq"; import { sendNotification } from "web-push"; import { htmlToText } from "@/content_types.ts"; -import { connection } from "~/utils/redis.ts"; export enum PushJobType { Notify = "notify", diff --git a/classes/queues/relationships.ts b/classes/queues/relationships.ts index a5d7c335..d4a49775 100644 --- a/classes/queues/relationships.ts +++ b/classes/queues/relationships.ts @@ -1,7 +1,7 @@ import { Relationship, User } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import { config } from "@versia-server/config"; import { Queue, Worker } from "bullmq"; -import { connection } from "~/utils/redis.ts"; export enum RelationshipJobType { Unmute = "unmute", diff --git a/cli/utils.ts b/cli/utils.ts index 9ccc08f5..8a22ce08 100644 --- a/cli/utils.ts +++ b/cli/utils.ts @@ -1,7 +1,7 @@ import { Instance, User } from "@versia/kit/db"; +import { parseUserAddress } from "@versia/kit/parsers"; import { Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; -import { parseUserAddress } from "@/api"; export const retrieveUser = async ( usernameOrHandle: string, diff --git a/flake.lock b/flake.lock index e59f2580..70093745 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "lastModified": 1749903597, + "narHash": "sha256-jp0D4vzBcRKwNZwfY4BcWHemLGUs4JrS3X9w5k/JYDA=", "owner": "nixos", "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "rev": "41da1e3ea8e23e094e5e3eeb1e6b830468a7399e", "type": "github" }, "original": { diff --git a/nix/package.nix b/nix/package.nix index 0a2a8f8b..043b557a 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -21,7 +21,7 @@ in pnpmDeps = pnpm.fetchDeps { inherit (finalAttrs) pname version src pnpmInstallFlags; - hash = "sha256-6lcsXcMEh7UbB5aLJzgJKUzynZbSZPgdj6l9E7RVx7c="; + hash = "sha256-nC1bYW+It2N0Mp8+Yh1uk3MOj8DABOCNP5E3LbMuCEQ="; }; nativeBuildInputs = [ diff --git a/package.json b/package.json index b1a2f0b9..88c067a4 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "sharp" ], "devDependencies": { + "@biomejs/biome": "catalog:", "@types/bun": "catalog:", "@types/html-to-text": "catalog:", "@types/markdown-it-container": "catalog:", diff --git a/packages/api/package.json b/packages/api/package.json index 35ab3d7a..c15d6116 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -63,6 +63,11 @@ "zod-openapi": "catalog:", "@scalar/hono-api-reference": "catalog:", "hono-rate-limiter": "catalog:", - "ip-matching": "catalog:" + "ip-matching": "catalog:", + "qs": "catalog:", + "magic-regexp": "catalog:", + "altcha-lib": "catalog:", + "@hono/zod-validator": "catalog:", + "zod-validation-error": "catalog:" } } diff --git a/packages/api/routes/api/auth/login/index.ts b/packages/api/routes/api/auth/login/index.ts index 120191bf..4676492c 100644 --- a/packages/api/routes/api/auth/login/index.ts +++ b/packages/api/routes/api/auth/login/index.ts @@ -1,4 +1,5 @@ import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { Application, User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; @@ -10,7 +11,6 @@ import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { SignJWT } from "jose"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; const returnError = ( context: Context, diff --git a/packages/api/routes/api/auth/redirect/index.ts b/packages/api/routes/api/auth/redirect/index.ts index cccdfdbf..be27327f 100644 --- a/packages/api/routes/api/auth/redirect/index.ts +++ b/packages/api/routes/api/auth/redirect/index.ts @@ -1,3 +1,4 @@ +import { apiRoute, handleZodError } from "@versia/kit/api"; import { db } from "@versia/kit/db"; import { Applications, Tokens } from "@versia/kit/tables"; import { config } from "@versia-server/config"; @@ -5,7 +6,6 @@ import { and, eq } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; /** * OAuth Code flow diff --git a/packages/api/routes/api/auth/reset/index.ts b/packages/api/routes/api/auth/reset/index.ts index ce69c426..cd1822da 100644 --- a/packages/api/routes/api/auth/reset/index.ts +++ b/packages/api/routes/api/auth/reset/index.ts @@ -1,3 +1,4 @@ +import { apiRoute, handleZodError } from "@versia/kit/api"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; @@ -7,7 +8,6 @@ import type { Context } from "hono"; import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; const returnError = ( context: Context, diff --git a/packages/api/routes/api/v1/accounts/[id]/block.ts b/packages/api/routes/api/v1/accounts/[id]/block.ts index 1985973a..9fae484d 100644 --- a/packages/api/routes/api/v1/accounts/[id]/block.ts +++ b/packages/api/routes/api/v1/accounts/[id]/block.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/feed.atom.ts b/packages/api/routes/api/v1/accounts/[id]/feed.atom.ts index 1a59947a..144145a8 100644 --- a/packages/api/routes/api/v1/accounts/[id]/feed.atom.ts +++ b/packages/api/routes/api/v1/accounts/[id]/feed.atom.ts @@ -1,9 +1,9 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { getFeed } from "@/rss"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/accounts/[id]/feed.rss.ts b/packages/api/routes/api/v1/accounts/[id]/feed.rss.ts index 920138a9..159dc7bf 100644 --- a/packages/api/routes/api/v1/accounts/[id]/feed.rss.ts +++ b/packages/api/routes/api/v1/accounts/[id]/feed.rss.ts @@ -1,9 +1,9 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { getFeed } from "@/rss"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/accounts/[id]/follow.ts b/packages/api/routes/api/v1/accounts/[id]/follow.ts index 6528ccac..f18bbb53 100644 --- a/packages/api/routes/api/v1/accounts/[id]/follow.ts +++ b/packages/api/routes/api/v1/accounts/[id]/follow.ts @@ -4,11 +4,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/followers.ts b/packages/api/routes/api/v1/accounts/[id]/followers.ts index dba9c5d7..42a37d2d 100644 --- a/packages/api/routes/api/v1/accounts/[id]/followers.ts +++ b/packages/api/routes/api/v1/accounts/[id]/followers.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/accounts/[id]/following.ts b/packages/api/routes/api/v1/accounts/[id]/following.ts index f11b5381..decdfa7b 100644 --- a/packages/api/routes/api/v1/accounts/[id]/following.ts +++ b/packages/api/routes/api/v1/accounts/[id]/following.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/accounts/[id]/index.ts b/packages/api/routes/api/v1/accounts/[id]/index.ts index b8e6dd3e..d10f37d7 100644 --- a/packages/api/routes/api/v1/accounts/[id]/index.ts +++ b/packages/api/routes/api/v1/accounts/[id]/index.ts @@ -3,9 +3,9 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/accounts/[id]/mute.ts b/packages/api/routes/api/v1/accounts/[id]/mute.ts index bdd73375..6cb39a32 100644 --- a/packages/api/routes/api/v1/accounts/[id]/mute.ts +++ b/packages/api/routes/api/v1/accounts/[id]/mute.ts @@ -3,11 +3,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { RelationshipJobType, relationshipQueue, diff --git a/packages/api/routes/api/v1/accounts/[id]/note.ts b/packages/api/routes/api/v1/accounts/[id]/note.ts index 1ceb2666..221ef268 100644 --- a/packages/api/routes/api/v1/accounts/[id]/note.ts +++ b/packages/api/routes/api/v1/accounts/[id]/note.ts @@ -3,11 +3,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/pin.ts b/packages/api/routes/api/v1/accounts/[id]/pin.ts index 649e66b2..6466f77b 100644 --- a/packages/api/routes/api/v1/accounts/[id]/pin.ts +++ b/packages/api/routes/api/v1/accounts/[id]/pin.ts @@ -2,10 +2,10 @@ import { Relationship as RelationshipSchema, RolePermission, } from "@versia/client/schemas"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/refetch.ts b/packages/api/routes/api/v1/accounts/[id]/refetch.ts index 91f1e0ff..1d6d28c7 100644 --- a/packages/api/routes/api/v1/accounts/[id]/refetch.ts +++ b/packages/api/routes/api/v1/accounts/[id]/refetch.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { User } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/remove_from_followers.ts b/packages/api/routes/api/v1/accounts/[id]/remove_from_followers.ts index e9fdabf6..5d26e43a 100644 --- a/packages/api/routes/api/v1/accounts/[id]/remove_from_followers.ts +++ b/packages/api/routes/api/v1/accounts/[id]/remove_from_followers.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/roles/[role_id]/index.ts b/packages/api/routes/api/v1/accounts/[id]/roles/[role_id]/index.ts index 99c11e0f..cb135e3e 100644 --- a/packages/api/routes/api/v1/accounts/[id]/roles/[role_id]/index.ts +++ b/packages/api/routes/api/v1/accounts/[id]/roles/[role_id]/index.ts @@ -4,11 +4,11 @@ import { Role as RoleSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Role } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; export default apiRoute((app) => { app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/roles/index.ts b/packages/api/routes/api/v1/accounts/[id]/roles/index.ts index 3bd8b18a..ff61b24f 100644 --- a/packages/api/routes/api/v1/accounts/[id]/roles/index.ts +++ b/packages/api/routes/api/v1/accounts/[id]/roles/index.ts @@ -1,9 +1,9 @@ import { Role as RoleSchema } from "@versia/client/schemas"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Role } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => { app.get( diff --git a/packages/api/routes/api/v1/accounts/[id]/statuses.ts b/packages/api/routes/api/v1/accounts/[id]/statuses.ts index b5bf9a2f..97ff8190 100644 --- a/packages/api/routes/api/v1/accounts/[id]/statuses.ts +++ b/packages/api/routes/api/v1/accounts/[id]/statuses.ts @@ -4,13 +4,13 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, isNull, lt, or, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/accounts/[id]/unblock.ts b/packages/api/routes/api/v1/accounts/[id]/unblock.ts index d96fbde2..0f0dc149 100644 --- a/packages/api/routes/api/v1/accounts/[id]/unblock.ts +++ b/packages/api/routes/api/v1/accounts/[id]/unblock.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/unfollow.ts b/packages/api/routes/api/v1/accounts/[id]/unfollow.ts index faaf9dc5..a089068f 100644 --- a/packages/api/routes/api/v1/accounts/[id]/unfollow.ts +++ b/packages/api/routes/api/v1/accounts/[id]/unfollow.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/unmute.ts b/packages/api/routes/api/v1/accounts/[id]/unmute.ts index 4c2d966d..92dfa6c6 100644 --- a/packages/api/routes/api/v1/accounts/[id]/unmute.ts +++ b/packages/api/routes/api/v1/accounts/[id]/unmute.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/[id]/unpin.ts b/packages/api/routes/api/v1/accounts/[id]/unpin.ts index e3ea20ea..57713f7c 100644 --- a/packages/api/routes/api/v1/accounts/[id]/unpin.ts +++ b/packages/api/routes/api/v1/accounts/[id]/unpin.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withUserParam } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withUserParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/accounts/familiar_followers/index.ts b/packages/api/routes/api/v1/accounts/familiar_followers/index.ts index ba089824..50d9f478 100644 --- a/packages/api/routes/api/v1/accounts/familiar_followers/index.ts +++ b/packages/api/routes/api/v1/accounts/familiar_followers/index.ts @@ -4,13 +4,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, qsQuery } from "@versia/kit/api"; import { db, User } from "@versia/kit/db"; import type { Users } from "@versia/kit/tables"; import { type InferSelectModel, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, qsQuery } from "@/api"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/accounts/index.ts b/packages/api/routes/api/v1/accounts/index.ts index 7ef05fb7..57908913 100644 --- a/packages/api/routes/api/v1/accounts/index.ts +++ b/packages/api/routes/api/v1/accounts/index.ts @@ -1,5 +1,12 @@ import { Account as AccountSchema, zBoolean } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { + apiRoute, + auth, + handleZodError, + jsonOrForm, + qsQuery, +} from "@versia/kit/api"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; @@ -8,7 +15,6 @@ import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import ISO6391 from "iso-639-1"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, jsonOrForm, qsQuery } from "@/api"; import { tempmailDomains } from "@/tempmail"; import { rateLimit } from "../../../../middlewares/rate-limit.ts"; diff --git a/packages/api/routes/api/v1/accounts/lookup/index.ts b/packages/api/routes/api/v1/accounts/lookup/index.ts index c9d7bef6..b700bab9 100644 --- a/packages/api/routes/api/v1/accounts/lookup/index.ts +++ b/packages/api/routes/api/v1/accounts/lookup/index.ts @@ -3,14 +3,15 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Instance, User } from "@versia/kit/db"; +import { parseUserAddress } from "@versia/kit/parsers"; import { Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; import { and, eq, isNull } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/accounts/relationships/index.ts b/packages/api/routes/api/v1/accounts/relationships/index.ts index f89e586e..5ca8db7b 100644 --- a/packages/api/routes/api/v1/accounts/relationships/index.ts +++ b/packages/api/routes/api/v1/accounts/relationships/index.ts @@ -5,11 +5,11 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, qsQuery } from "@versia/kit/api"; import { Relationship } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, qsQuery } from "@/api"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/accounts/search/index.ts b/packages/api/routes/api/v1/accounts/search/index.ts index ca6455a1..a6b62863 100644 --- a/packages/api/routes/api/v1/accounts/search/index.ts +++ b/packages/api/routes/api/v1/accounts/search/index.ts @@ -4,14 +4,15 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { User } from "@versia/kit/db"; +import { parseUserAddress } from "@versia/kit/parsers"; import { Users } from "@versia/kit/tables"; import { eq, ilike, not, or, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import stringComparison from "string-comparison"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/accounts/update_credentials/index.ts b/packages/api/routes/api/v1/accounts/update_credentials/index.ts index 394343d9..d3e84961 100644 --- a/packages/api/routes/api/v1/accounts/update_credentials/index.ts +++ b/packages/api/routes/api/v1/accounts/update_credentials/index.ts @@ -4,7 +4,9 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { Emoji, Media, User } from "@versia/kit/db"; +import { versiaTextToHtml } from "@versia/kit/parsers"; import { Users } from "@versia/kit/tables"; import * as VersiaEntities from "@versia/sdk/entities"; import { config } from "@versia-server/config"; @@ -12,10 +14,8 @@ import { and, eq, isNull } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; import { mergeAndDeduplicate } from "@/lib"; import { sanitizedHtmlStrip } from "@/sanitization"; -import { contentToHtml } from "~/classes/functions/status"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts"; export default apiRoute((app) => @@ -242,7 +242,7 @@ export default apiRoute((app) => if (note) { self.source.note = note; - self.note = await contentToHtml( + self.note = await versiaTextToHtml( new VersiaEntities.TextContentFormat({ "text/markdown": { content: note, @@ -329,7 +329,7 @@ export default apiRoute((app) => self.source.fields = []; for (const field of fields_attributes) { // Can be Markdown or plaintext, also has emojis - const parsedName = await contentToHtml( + const parsedName = await versiaTextToHtml( new VersiaEntities.TextContentFormat({ "text/markdown": { content: field.name, @@ -340,7 +340,7 @@ export default apiRoute((app) => true, ); - const parsedValue = await contentToHtml( + const parsedValue = await versiaTextToHtml( new VersiaEntities.TextContentFormat({ "text/markdown": { content: field.value, diff --git a/packages/api/routes/api/v1/accounts/verify_credentials/index.ts b/packages/api/routes/api/v1/accounts/verify_credentials/index.ts index 33e595c9..09a34c53 100644 --- a/packages/api/routes/api/v1/accounts/verify_credentials/index.ts +++ b/packages/api/routes/api/v1/accounts/verify_credentials/index.ts @@ -1,8 +1,8 @@ import { Account } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/apps/index.ts b/packages/api/routes/api/v1/apps/index.ts index 0726cb1a..1193cbc1 100644 --- a/packages/api/routes/api/v1/apps/index.ts +++ b/packages/api/routes/api/v1/apps/index.ts @@ -3,12 +3,12 @@ import { CredentialApplication as CredentialApplicationSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError, jsonOrForm } from "@versia/kit/api"; import { Application } from "@versia/kit/db"; import { randomUUIDv7 } from "bun"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError, jsonOrForm } from "@/api"; import { randomString } from "@/math"; import { rateLimit } from "../../../../middlewares/rate-limit.ts"; diff --git a/packages/api/routes/api/v1/apps/verify_credentials/index.ts b/packages/api/routes/api/v1/apps/verify_credentials/index.ts index ad7f0489..d21065f6 100644 --- a/packages/api/routes/api/v1/apps/verify_credentials/index.ts +++ b/packages/api/routes/api/v1/apps/verify_credentials/index.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { Application } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/blocks/index.ts b/packages/api/routes/api/v1/blocks/index.ts index 1e5a088d..4cc21a5e 100644 --- a/packages/api/routes/api/v1/blocks/index.ts +++ b/packages/api/routes/api/v1/blocks/index.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/challenges/index.ts b/packages/api/routes/api/v1/challenges/index.ts index b1f255fb..3d739b64 100644 --- a/packages/api/routes/api/v1/challenges/index.ts +++ b/packages/api/routes/api/v1/challenges/index.ts @@ -1,9 +1,9 @@ import { Challenge } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth } from "@/api"; import { generateChallenge } from "@/challenges"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/custom_emojis/index.ts b/packages/api/routes/api/v1/custom_emojis/index.ts index 7eadfde2..a037cfe4 100644 --- a/packages/api/routes/api/v1/custom_emojis/index.ts +++ b/packages/api/routes/api/v1/custom_emojis/index.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { Emoji } from "@versia/kit/db"; import { Emojis } from "@versia/kit/tables"; import { and, eq, isNull, or } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/emojis/[id]/index.ts b/packages/api/routes/api/v1/emojis/[id]/index.ts index 341b8253..4c2c5661 100644 --- a/packages/api/routes/api/v1/emojis/[id]/index.ts +++ b/packages/api/routes/api/v1/emojis/[id]/index.ts @@ -3,17 +3,17 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; -import { config } from "@versia-server/config"; -import { describeRoute } from "hono-openapi"; -import { resolver, validator } from "hono-openapi/zod"; -import { z } from "zod"; import { apiRoute, auth, handleZodError, jsonOrForm, withEmojiParam, -} from "@/api"; +} from "@versia/kit/api"; +import { config } from "@versia-server/config"; +import { describeRoute } from "hono-openapi"; +import { resolver, validator } from "hono-openapi/zod"; +import { z } from "zod"; import { mimeLookup } from "@/content_types"; export default apiRoute((app) => { diff --git a/packages/api/routes/api/v1/emojis/index.ts b/packages/api/routes/api/v1/emojis/index.ts index 919b5e02..8098fd6e 100644 --- a/packages/api/routes/api/v1/emojis/index.ts +++ b/packages/api/routes/api/v1/emojis/index.ts @@ -3,6 +3,7 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { Emoji, Media } from "@versia/kit/db"; import { Emojis } from "@versia/kit/tables"; import { config } from "@versia-server/config"; @@ -11,7 +12,6 @@ import { and, eq, isNull, or } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; import { mimeLookup } from "@/content_types"; export default apiRoute((app) => diff --git a/packages/api/routes/api/v1/favourites/index.ts b/packages/api/routes/api/v1/favourites/index.ts index ce0bab5b..d25eb5b2 100644 --- a/packages/api/routes/api/v1/favourites/index.ts +++ b/packages/api/routes/api/v1/favourites/index.ts @@ -1,12 +1,12 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/follow_requests/[account_id]/authorize.ts b/packages/api/routes/api/v1/follow_requests/[account_id]/authorize.ts index c3e052a2..6a06597f 100644 --- a/packages/api/routes/api/v1/follow_requests/[account_id]/authorize.ts +++ b/packages/api/routes/api/v1/follow_requests/[account_id]/authorize.ts @@ -4,11 +4,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Relationship, User } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/follow_requests/[account_id]/reject.ts b/packages/api/routes/api/v1/follow_requests/[account_id]/reject.ts index 686f0df9..1047e335 100644 --- a/packages/api/routes/api/v1/follow_requests/[account_id]/reject.ts +++ b/packages/api/routes/api/v1/follow_requests/[account_id]/reject.ts @@ -4,11 +4,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Relationship, User } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/follow_requests/index.ts b/packages/api/routes/api/v1/follow_requests/index.ts index ba36990f..5111e8e6 100644 --- a/packages/api/routes/api/v1/follow_requests/index.ts +++ b/packages/api/routes/api/v1/follow_requests/index.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/frontend/config/index.ts b/packages/api/routes/api/v1/frontend/config/index.ts index a0a0e417..8c757ff3 100644 --- a/packages/api/routes/api/v1/frontend/config/index.ts +++ b/packages/api/routes/api/v1/frontend/config/index.ts @@ -1,8 +1,8 @@ +import { apiRoute } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/instance/extended_description.ts b/packages/api/routes/api/v1/instance/extended_description.ts index b49815df..566468c5 100644 --- a/packages/api/routes/api/v1/instance/extended_description.ts +++ b/packages/api/routes/api/v1/instance/extended_description.ts @@ -1,9 +1,9 @@ import { ExtendedDescription as ExtendedDescriptionSchema } from "@versia/client/schemas"; +import { apiRoute } from "@versia/kit/api"; +import { markdownToHtml } from "@versia/kit/markdown"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute } from "@/api"; -import { markdownParse } from "~/classes/functions/status"; export default apiRoute((app) => app.get( @@ -27,7 +27,7 @@ export default apiRoute((app) => }, }), async (context) => { - const content = await markdownParse( + const content = await markdownToHtml( config.instance.extended_description_path?.content ?? "This is a [Versia](https://versia.pub) server with the default extended description.", ); diff --git a/packages/api/routes/api/v1/instance/index.ts b/packages/api/routes/api/v1/instance/index.ts index d2154271..c4d56aea 100644 --- a/packages/api/routes/api/v1/instance/index.ts +++ b/packages/api/routes/api/v1/instance/index.ts @@ -1,13 +1,13 @@ import { InstanceV1 as InstanceV1Schema } from "@versia/client/schemas"; +import { apiRoute } from "@versia/kit/api"; import { Instance, Note, User } from "@versia/kit/db"; +import { markdownToHtml } from "@versia/kit/markdown"; import { Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; import { and, eq, isNull } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import type { z } from "zod"; -import { apiRoute } from "@/api"; -import { markdownParse } from "~/classes/functions/status"; import manifest from "~/package.json" with { type: "json" }; export default apiRoute((app) => @@ -60,7 +60,7 @@ export default apiRoute((app) => } | undefined; - const content = await markdownParse( + const content = await markdownToHtml( config.instance.extended_description_path?.content ?? "This is a [Versia](https://versia.pub) server with the default extended description.", ); diff --git a/packages/api/routes/api/v1/instance/privacy_policy.ts b/packages/api/routes/api/v1/instance/privacy_policy.ts index 6320fbb5..8b29b1c2 100644 --- a/packages/api/routes/api/v1/instance/privacy_policy.ts +++ b/packages/api/routes/api/v1/instance/privacy_policy.ts @@ -1,9 +1,9 @@ import { PrivacyPolicy as PrivacyPolicySchema } from "@versia/client/schemas"; +import { apiRoute } from "@versia/kit/api"; +import { markdownToHtml } from "@versia/kit/markdown"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute } from "@/api"; -import { markdownParse } from "~/classes/functions/status"; export default apiRoute((app) => app.get( @@ -27,7 +27,7 @@ export default apiRoute((app) => }, }), async (context) => { - const content = await markdownParse( + const content = await markdownToHtml( config.instance.privacy_policy_path?.content ?? "This instance has not provided any privacy policy.", ); diff --git a/packages/api/routes/api/v1/instance/rules.ts b/packages/api/routes/api/v1/instance/rules.ts index bf5de671..36662d67 100644 --- a/packages/api/routes/api/v1/instance/rules.ts +++ b/packages/api/routes/api/v1/instance/rules.ts @@ -1,9 +1,9 @@ import { Rule as RuleSchema } from "@versia/client/schemas"; +import { apiRoute } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/instance/terms_of_service.ts b/packages/api/routes/api/v1/instance/terms_of_service.ts index c3cd8e7e..9b35b1f8 100644 --- a/packages/api/routes/api/v1/instance/terms_of_service.ts +++ b/packages/api/routes/api/v1/instance/terms_of_service.ts @@ -1,9 +1,9 @@ import { TermsOfService as TermsOfServiceSchema } from "@versia/client/schemas"; +import { apiRoute } from "@versia/kit/api"; +import { markdownToHtml } from "@versia/kit/markdown"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute } from "@/api"; -import { markdownParse } from "~/classes/functions/status"; export default apiRoute((app) => app.get( @@ -28,7 +28,7 @@ export default apiRoute((app) => }, }), async (context) => { - const content = await markdownParse( + const content = await markdownToHtml( config.instance.tos_path?.content ?? "This instance has not provided any terms of service.", ); diff --git a/packages/api/routes/api/v1/markers/index.ts b/packages/api/routes/api/v1/markers/index.ts index c1960674..66744a4f 100644 --- a/packages/api/routes/api/v1/markers/index.ts +++ b/packages/api/routes/api/v1/markers/index.ts @@ -5,6 +5,7 @@ import { Status as StatusSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { db } from "@versia/kit/db"; import { Markers } from "@versia/kit/tables"; import { randomUUIDv7 } from "bun"; @@ -12,7 +13,6 @@ import { and, eq, type SQL } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; const MarkerResponseSchema = z.object({ notifications: MarkerSchema.optional(), diff --git a/packages/api/routes/api/v1/media/[id]/index.ts b/packages/api/routes/api/v1/media/[id]/index.ts index fca9de5a..f848fae8 100644 --- a/packages/api/routes/api/v1/media/[id]/index.ts +++ b/packages/api/routes/api/v1/media/[id]/index.ts @@ -3,12 +3,12 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Media } from "@versia/kit/db"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => { app.get( diff --git a/packages/api/routes/api/v1/media/index.ts b/packages/api/routes/api/v1/media/index.ts index e4f32b7d..b9668cd9 100644 --- a/packages/api/routes/api/v1/media/index.ts +++ b/packages/api/routes/api/v1/media/index.ts @@ -3,12 +3,12 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Media } from "@versia/kit/db"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/mutes/index.ts b/packages/api/routes/api/v1/mutes/index.ts index 30ac4ec7..1bfddff4 100644 --- a/packages/api/routes/api/v1/mutes/index.ts +++ b/packages/api/routes/api/v1/mutes/index.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/notifications/[id]/dismiss.ts b/packages/api/routes/api/v1/notifications/[id]/dismiss.ts index bec02ca2..29d8ba3f 100644 --- a/packages/api/routes/api/v1/notifications/[id]/dismiss.ts +++ b/packages/api/routes/api/v1/notifications/[id]/dismiss.ts @@ -3,11 +3,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Notification } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/notifications/[id]/index.ts b/packages/api/routes/api/v1/notifications/[id]/index.ts index 00407f62..9e1dfac0 100644 --- a/packages/api/routes/api/v1/notifications/[id]/index.ts +++ b/packages/api/routes/api/v1/notifications/[id]/index.ts @@ -3,11 +3,11 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Notification } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/notifications/clear/index.ts b/packages/api/routes/api/v1/notifications/clear/index.ts index d229af50..86565f27 100644 --- a/packages/api/routes/api/v1/notifications/clear/index.ts +++ b/packages/api/routes/api/v1/notifications/clear/index.ts @@ -1,7 +1,7 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/notifications/destroy_multiple/index.ts b/packages/api/routes/api/v1/notifications/destroy_multiple/index.ts index 4d7d4958..ebec88c1 100644 --- a/packages/api/routes/api/v1/notifications/destroy_multiple/index.ts +++ b/packages/api/routes/api/v1/notifications/destroy_multiple/index.ts @@ -1,9 +1,9 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, qsQuery } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, qsQuery } from "@/api"; export default apiRoute((app) => app.delete( diff --git a/packages/api/routes/api/v1/notifications/index.ts b/packages/api/routes/api/v1/notifications/index.ts index 4bd79467..ead91a0c 100644 --- a/packages/api/routes/api/v1/notifications/index.ts +++ b/packages/api/routes/api/v1/notifications/index.ts @@ -5,13 +5,13 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Notifications } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, lt, not, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/profile/avatar.ts b/packages/api/routes/api/v1/profile/avatar.ts index 4ca65bb8..e4bd5273 100644 --- a/packages/api/routes/api/v1/profile/avatar.ts +++ b/packages/api/routes/api/v1/profile/avatar.ts @@ -1,8 +1,8 @@ import { Account, RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.delete( diff --git a/packages/api/routes/api/v1/profile/header.ts b/packages/api/routes/api/v1/profile/header.ts index bad6938f..eba087cc 100644 --- a/packages/api/routes/api/v1/profile/header.ts +++ b/packages/api/routes/api/v1/profile/header.ts @@ -1,8 +1,8 @@ import { Account, RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.delete( diff --git a/packages/api/routes/api/v1/push/subscription/index.delete.ts b/packages/api/routes/api/v1/push/subscription/index.delete.ts index dfc31a1b..770b88ad 100644 --- a/packages/api/routes/api/v1/push/subscription/index.delete.ts +++ b/packages/api/routes/api/v1/push/subscription/index.delete.ts @@ -1,10 +1,10 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { PushSubscription } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.delete( diff --git a/packages/api/routes/api/v1/push/subscription/index.get.ts b/packages/api/routes/api/v1/push/subscription/index.get.ts index b484029a..6347ba78 100644 --- a/packages/api/routes/api/v1/push/subscription/index.get.ts +++ b/packages/api/routes/api/v1/push/subscription/index.get.ts @@ -3,10 +3,10 @@ import { WebPushSubscription as WebPushSubscriptionSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth } from "@versia/kit/api"; import { PushSubscription } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/push/subscription/index.post.ts b/packages/api/routes/api/v1/push/subscription/index.post.ts index f8bd3ddc..f7088cd8 100644 --- a/packages/api/routes/api/v1/push/subscription/index.post.ts +++ b/packages/api/routes/api/v1/push/subscription/index.post.ts @@ -4,11 +4,11 @@ import { WebPushSubscription as WebPushSubscriptionSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { PushSubscription } from "@versia/kit/db"; import { randomUUIDv7 } from "bun"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/push/subscription/index.put.ts b/packages/api/routes/api/v1/push/subscription/index.put.ts index 6a21a3d0..8ff17611 100644 --- a/packages/api/routes/api/v1/push/subscription/index.put.ts +++ b/packages/api/routes/api/v1/push/subscription/index.put.ts @@ -4,10 +4,10 @@ import { WebPushSubscription as WebPushSubscriptionSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { PushSubscription } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; export default apiRoute((app) => app.put( diff --git a/packages/api/routes/api/v1/roles/[id]/index.ts b/packages/api/routes/api/v1/roles/[id]/index.ts index 3a8ce0c8..20a15d43 100644 --- a/packages/api/routes/api/v1/roles/[id]/index.ts +++ b/packages/api/routes/api/v1/roles/[id]/index.ts @@ -1,10 +1,10 @@ import { RolePermission, Role as RoleSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Role } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => { app.get( diff --git a/packages/api/routes/api/v1/roles/index.ts b/packages/api/routes/api/v1/roles/index.ts index c59b98a0..764b377c 100644 --- a/packages/api/routes/api/v1/roles/index.ts +++ b/packages/api/routes/api/v1/roles/index.ts @@ -1,11 +1,11 @@ import { RolePermission, Role as RoleSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Role } from "@versia/kit/db"; import { randomUUIDv7 } from "bun"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => { app.get( diff --git a/packages/api/routes/api/v1/statuses/[id]/context.ts b/packages/api/routes/api/v1/statuses/[id]/context.ts index df51fbaa..8c145e8b 100644 --- a/packages/api/routes/api/v1/statuses/[id]/context.ts +++ b/packages/api/routes/api/v1/statuses/[id]/context.ts @@ -3,9 +3,9 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/statuses/[id]/favourite.ts b/packages/api/routes/api/v1/statuses/[id]/favourite.ts index fc7db499..ce4e3e3e 100644 --- a/packages/api/routes/api/v1/statuses/[id]/favourite.ts +++ b/packages/api/routes/api/v1/statuses/[id]/favourite.ts @@ -1,8 +1,8 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/statuses/[id]/favourited_by.ts b/packages/api/routes/api/v1/statuses/[id]/favourited_by.ts index 0c8e0b9b..ea6e5329 100644 --- a/packages/api/routes/api/v1/statuses/[id]/favourited_by.ts +++ b/packages/api/routes/api/v1/statuses/[id]/favourited_by.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withNoteParam } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withNoteParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/statuses/[id]/index.ts b/packages/api/routes/api/v1/statuses/[id]/index.ts index 57797999..4f3be06c 100644 --- a/packages/api/routes/api/v1/statuses/[id]/index.ts +++ b/packages/api/routes/api/v1/statuses/[id]/index.ts @@ -7,21 +7,21 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; -import { Emoji, Media } from "@versia/kit/db"; -import * as VersiaEntities from "@versia/sdk/entities"; -import { config } from "@versia-server/config"; -import { describeRoute } from "hono-openapi"; -import { resolver, validator } from "hono-openapi/zod"; -import { z } from "zod"; import { apiRoute, auth, handleZodError, jsonOrForm, withNoteParam, -} from "@/api"; +} from "@versia/kit/api"; +import { Emoji, Media } from "@versia/kit/db"; +import { parseMentionsFromText, versiaTextToHtml } from "@versia/kit/parsers"; +import * as VersiaEntities from "@versia/sdk/entities"; +import { config } from "@versia-server/config"; +import { describeRoute } from "hono-openapi"; +import { resolver, validator } from "hono-openapi/zod"; +import { z } from "zod"; import { sanitizedHtmlStrip } from "@/sanitization"; -import { contentToHtml, parseTextMentions } from "~/classes/functions/status"; const schema = z .object({ @@ -256,7 +256,7 @@ export default apiRoute((app) => { : undefined; const parsedMentions = statusText - ? await parseTextMentions(statusText) + ? await parseMentionsFromText(statusText) : []; const parsedEmojis = statusText @@ -267,7 +267,7 @@ export default apiRoute((app) => { spoilerText: sanitizedSpoilerText, sensitive, content: content - ? await contentToHtml(content, parsedMentions) + ? await versiaTextToHtml(content, parsedMentions) : undefined, }); diff --git a/packages/api/routes/api/v1/statuses/[id]/pin.ts b/packages/api/routes/api/v1/statuses/[id]/pin.ts index b9f89db6..bdfc3919 100644 --- a/packages/api/routes/api/v1/statuses/[id]/pin.ts +++ b/packages/api/routes/api/v1/statuses/[id]/pin.ts @@ -1,10 +1,10 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { db } from "@versia/kit/db"; import { and, eq, type SQL } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/statuses/[id]/reactions/[name].ts b/packages/api/routes/api/v1/statuses/[id]/reactions/[name].ts index 5b89cad2..d6cd0bbd 100644 --- a/packages/api/routes/api/v1/statuses/[id]/reactions/[name].ts +++ b/packages/api/routes/api/v1/statuses/[id]/reactions/[name].ts @@ -1,5 +1,6 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withNoteParam } from "@versia/kit/api"; import { Emoji } from "@versia/kit/db"; import { Emojis } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; @@ -9,7 +10,6 @@ import emojis from "unicode-emoji-json/data-ordered-emoji.json" with { type: "json", }; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withNoteParam } from "@/api"; export default apiRoute((app) => { app.put( diff --git a/packages/api/routes/api/v1/statuses/[id]/reactions/index.ts b/packages/api/routes/api/v1/statuses/[id]/reactions/index.ts index 2527b14e..f5d22f5f 100644 --- a/packages/api/routes/api/v1/statuses/[id]/reactions/index.ts +++ b/packages/api/routes/api/v1/statuses/[id]/reactions/index.ts @@ -3,10 +3,10 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/statuses/[id]/reblog.ts b/packages/api/routes/api/v1/statuses/[id]/reblog.ts index aaadfa29..ab3c8eef 100644 --- a/packages/api/routes/api/v1/statuses/[id]/reblog.ts +++ b/packages/api/routes/api/v1/statuses/[id]/reblog.ts @@ -1,9 +1,9 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, jsonOrForm, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, jsonOrForm, withNoteParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/statuses/[id]/reblogged_by.ts b/packages/api/routes/api/v1/statuses/[id]/reblogged_by.ts index cd09bccf..72b93475 100644 --- a/packages/api/routes/api/v1/statuses/[id]/reblogged_by.ts +++ b/packages/api/routes/api/v1/statuses/[id]/reblogged_by.ts @@ -3,13 +3,13 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, withNoteParam } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, withNoteParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/statuses/[id]/source.ts b/packages/api/routes/api/v1/statuses/[id]/source.ts index 2760d874..dbc9df12 100644 --- a/packages/api/routes/api/v1/statuses/[id]/source.ts +++ b/packages/api/routes/api/v1/statuses/[id]/source.ts @@ -3,9 +3,9 @@ import { StatusSource as StatusSourceSchema, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/statuses/[id]/unfavourite.ts b/packages/api/routes/api/v1/statuses/[id]/unfavourite.ts index 608103b5..f3f392ab 100644 --- a/packages/api/routes/api/v1/statuses/[id]/unfavourite.ts +++ b/packages/api/routes/api/v1/statuses/[id]/unfavourite.ts @@ -1,8 +1,8 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/statuses/[id]/unpin.ts b/packages/api/routes/api/v1/statuses/[id]/unpin.ts index f05c1098..bff34009 100644 --- a/packages/api/routes/api/v1/statuses/[id]/unpin.ts +++ b/packages/api/routes/api/v1/statuses/[id]/unpin.ts @@ -1,8 +1,8 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/statuses/[id]/unreblog.ts b/packages/api/routes/api/v1/statuses/[id]/unreblog.ts index 5627d7df..3742c4e0 100644 --- a/packages/api/routes/api/v1/statuses/[id]/unreblog.ts +++ b/packages/api/routes/api/v1/statuses/[id]/unreblog.ts @@ -1,9 +1,9 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, withNoteParam } from "@versia/kit/api"; import { Note } from "@versia/kit/db"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute, auth, withNoteParam } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v1/statuses/index.ts b/packages/api/routes/api/v1/statuses/index.ts index 3e968042..46ea2b39 100644 --- a/packages/api/routes/api/v1/statuses/index.ts +++ b/packages/api/routes/api/v1/statuses/index.ts @@ -7,16 +7,16 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { Emoji, Media, Note } from "@versia/kit/db"; +import { parseMentionsFromText, versiaTextToHtml } from "@versia/kit/parsers"; import * as VersiaEntities from "@versia/sdk/entities"; import { config } from "@versia-server/config"; import { randomUUIDv7 } from "bun"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; import { sanitizedHtmlStrip } from "@/sanitization"; -import { contentToHtml, parseTextMentions } from "~/classes/functions/status"; const schema = z .object({ @@ -220,7 +220,7 @@ export default apiRoute((app) => : undefined; const parsedMentions = status - ? await parseTextMentions(status) + ? await parseMentionsFromText(status) : []; const parsedEmojis = status @@ -232,7 +232,7 @@ export default apiRoute((app) => authorId: user.id, visibility, content: content - ? await contentToHtml(content, parsedMentions) + ? await versiaTextToHtml(content, parsedMentions) : undefined, sensitive, spoilerText: sanitizedSpoilerText, diff --git a/packages/api/routes/api/v1/timelines/home.ts b/packages/api/routes/api/v1/timelines/home.ts index 4d96660c..0f1ebdb3 100644 --- a/packages/api/routes/api/v1/timelines/home.ts +++ b/packages/api/routes/api/v1/timelines/home.ts @@ -1,12 +1,12 @@ import { RolePermission, Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v1/timelines/public.ts b/packages/api/routes/api/v1/timelines/public.ts index 1b9bfcc1..52e1abf8 100644 --- a/packages/api/routes/api/v1/timelines/public.ts +++ b/packages/api/routes/api/v1/timelines/public.ts @@ -4,13 +4,13 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Timeline } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/api/v2/filters/[id]/index.ts b/packages/api/routes/api/v2/filters/[id]/index.ts index bd4a96bc..61a06dd0 100644 --- a/packages/api/routes/api/v2/filters/[id]/index.ts +++ b/packages/api/routes/api/v2/filters/[id]/index.ts @@ -5,13 +5,13 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { db } from "@versia/kit/db"; import { FilterKeywords, Filters } from "@versia/kit/tables"; import { and, eq, inArray, type SQL } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; export default apiRoute((app) => { app.get( diff --git a/packages/api/routes/api/v2/filters/index.ts b/packages/api/routes/api/v2/filters/index.ts index c0a16b2a..0872839e 100644 --- a/packages/api/routes/api/v2/filters/index.ts +++ b/packages/api/routes/api/v2/filters/index.ts @@ -4,6 +4,7 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { db } from "@versia/kit/db"; import { FilterKeywords, Filters } from "@versia/kit/tables"; import { randomUUIDv7 } from "bun"; @@ -11,7 +12,6 @@ import { eq, type SQL } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; export default apiRoute((app) => { app.get( diff --git a/packages/api/routes/api/v2/instance/index.ts b/packages/api/routes/api/v2/instance/index.ts index 224718d1..cd449aa6 100644 --- a/packages/api/routes/api/v2/instance/index.ts +++ b/packages/api/routes/api/v2/instance/index.ts @@ -1,11 +1,11 @@ import { Instance as InstanceSchema } from "@versia/client/schemas"; +import { apiRoute } from "@versia/kit/api"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; import { and, eq, isNull } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute } from "@/api"; import pkg from "~/package.json" with { type: "json" }; export default apiRoute((app) => diff --git a/packages/api/routes/api/v2/media/index.ts b/packages/api/routes/api/v2/media/index.ts index 49741dd0..44a40731 100644 --- a/packages/api/routes/api/v2/media/index.ts +++ b/packages/api/routes/api/v2/media/index.ts @@ -3,12 +3,12 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { Media } from "@versia/kit/db"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/api/v2/search/index.ts b/packages/api/routes/api/v2/search/index.ts index daaea8c8..e5d08724 100644 --- a/packages/api/routes/api/v2/search/index.ts +++ b/packages/api/routes/api/v2/search/index.ts @@ -7,14 +7,15 @@ import { zBoolean, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, auth, handleZodError } from "@versia/kit/api"; import { db, Note, User } from "@versia/kit/db"; +import { parseUserAddress } from "@versia/kit/parsers"; import { Instances, Notes, Users } from "@versia/kit/tables"; import { config } from "@versia-server/config"; import { and, eq, inArray, isNull, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api"; import { searchManager } from "~/classes/search/search-manager"; export default apiRoute((app) => diff --git a/packages/api/routes/inbox/index.ts b/packages/api/routes/inbox/index.ts index 43567d88..5ea50af6 100644 --- a/packages/api/routes/inbox/index.ts +++ b/packages/api/routes/inbox/index.ts @@ -1,7 +1,7 @@ +import { apiRoute, handleZodError } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; import { InboxJobType, inboxQueue } from "~/classes/queues/inbox"; export default apiRoute((app) => diff --git a/packages/api/routes/likes/[uuid]/index.ts b/packages/api/routes/likes/[uuid]/index.ts index c94be1bc..f0fe1c8e 100644 --- a/packages/api/routes/likes/[uuid]/index.ts +++ b/packages/api/routes/likes/[uuid]/index.ts @@ -1,5 +1,6 @@ import { Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { Like, User } from "@versia/kit/db"; import { Likes } from "@versia/kit/tables"; import { LikeSchema } from "@versia/sdk/schemas"; @@ -8,7 +9,6 @@ import { and, eq, sql } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/media/[hash]/[name]/index.ts b/packages/api/routes/media/[hash]/[name]/index.ts index 2ea7b57c..21601bff 100644 --- a/packages/api/routes/media/[hash]/[name]/index.ts +++ b/packages/api/routes/media/[hash]/[name]/index.ts @@ -1,9 +1,9 @@ import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { file as bunFile } from "bun"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/media/proxy/[id].ts b/packages/api/routes/media/proxy/[id].ts index 725a6572..c8c5a608 100644 --- a/packages/api/routes/media/proxy/[id].ts +++ b/packages/api/routes/media/proxy/[id].ts @@ -1,11 +1,11 @@ import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { proxy } from "hono/proxy"; import type { ContentfulStatusCode, StatusCode } from "hono/utils/http-status"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/messaging/index.ts b/packages/api/routes/messaging/index.ts index 677576c0..12d5c83a 100644 --- a/packages/api/routes/messaging/index.ts +++ b/packages/api/routes/messaging/index.ts @@ -1,7 +1,7 @@ import { getLogger } from "@logtape/logtape"; +import { apiRoute } from "@versia/kit/api"; import chalk from "chalk"; import { describeRoute } from "hono-openapi"; -import { apiRoute } from "@/api"; export default apiRoute((app) => app.post( diff --git a/packages/api/routes/notes/[uuid]/index.ts b/packages/api/routes/notes/[uuid]/index.ts index 34bd00e0..e7aaca0c 100644 --- a/packages/api/routes/notes/[uuid]/index.ts +++ b/packages/api/routes/notes/[uuid]/index.ts @@ -1,5 +1,6 @@ import { Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { Note } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { NoteSchema } from "@versia/sdk/schemas"; @@ -8,7 +9,6 @@ import { and, eq, inArray } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/notes/[uuid]/quotes.ts b/packages/api/routes/notes/[uuid]/quotes.ts index 2901754a..1b1a8291 100644 --- a/packages/api/routes/notes/[uuid]/quotes.ts +++ b/packages/api/routes/notes/[uuid]/quotes.ts @@ -1,5 +1,6 @@ import { Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { db, Note } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import * as VersiaEntities from "@versia/sdk/entities"; @@ -9,7 +10,6 @@ import { and, eq, inArray } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/notes/[uuid]/replies.ts b/packages/api/routes/notes/[uuid]/replies.ts index 715a06f3..0f0ea187 100644 --- a/packages/api/routes/notes/[uuid]/replies.ts +++ b/packages/api/routes/notes/[uuid]/replies.ts @@ -1,5 +1,6 @@ import { Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { db, Note } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import * as VersiaEntities from "@versia/sdk/entities"; @@ -9,7 +10,6 @@ import { and, eq, inArray } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/notes/[uuid]/shares.ts b/packages/api/routes/notes/[uuid]/shares.ts index bdc57ed9..43835670 100644 --- a/packages/api/routes/notes/[uuid]/shares.ts +++ b/packages/api/routes/notes/[uuid]/shares.ts @@ -1,5 +1,6 @@ import { Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { db, Note } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import * as VersiaEntities from "@versia/sdk/entities"; @@ -9,7 +10,6 @@ import { and, eq, inArray } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/shares/[uuid]/index.ts b/packages/api/routes/shares/[uuid]/index.ts index 7ef0c43e..3795bb6f 100644 --- a/packages/api/routes/shares/[uuid]/index.ts +++ b/packages/api/routes/shares/[uuid]/index.ts @@ -1,5 +1,6 @@ import { Status as StatusSchema } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { Note } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { ShareSchema } from "@versia/sdk/schemas"; @@ -8,7 +9,6 @@ import { and, eq, inArray } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/users/[uuid]/inbox/index.ts b/packages/api/routes/users/[uuid]/inbox/index.ts index 0ae1ea0a..68875797 100644 --- a/packages/api/routes/users/[uuid]/inbox/index.ts +++ b/packages/api/routes/users/[uuid]/inbox/index.ts @@ -1,8 +1,8 @@ import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; import { InboxJobType, inboxQueue } from "~/classes/queues/inbox"; export default apiRoute((app) => diff --git a/packages/api/routes/users/[uuid]/index.ts b/packages/api/routes/users/[uuid]/index.ts index b7c08dc2..c0786a93 100644 --- a/packages/api/routes/users/[uuid]/index.ts +++ b/packages/api/routes/users/[uuid]/index.ts @@ -1,10 +1,10 @@ import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { User } from "@versia/kit/db"; import { UserSchema } from "@versia/sdk/schemas"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/users/[uuid]/outbox/index.ts b/packages/api/routes/users/[uuid]/outbox/index.ts index 01baa18f..e2bbe6a2 100644 --- a/packages/api/routes/users/[uuid]/outbox/index.ts +++ b/packages/api/routes/users/[uuid]/outbox/index.ts @@ -1,4 +1,5 @@ import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { db, Note, User } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import * as VersiaEntities from "@versia/sdk/entities"; @@ -8,7 +9,6 @@ import { and, eq, inArray } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute, handleZodError } from "@/api"; const NOTES_PER_PAGE = 20; diff --git a/packages/api/routes/well-known/host-meta/index.ts b/packages/api/routes/well-known/host-meta/index.ts index 13e9cf13..a287f5af 100644 --- a/packages/api/routes/well-known/host-meta/index.ts +++ b/packages/api/routes/well-known/host-meta/index.ts @@ -1,8 +1,8 @@ +import { apiRoute } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/well-known/nodeinfo/2.0/index.ts b/packages/api/routes/well-known/nodeinfo/2.0/index.ts index 9956ce1a..863f8ec6 100644 --- a/packages/api/routes/well-known/nodeinfo/2.0/index.ts +++ b/packages/api/routes/well-known/nodeinfo/2.0/index.ts @@ -1,9 +1,9 @@ +import { apiRoute } from "@versia/kit/api"; import { Note, User } from "@versia/kit/db"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute } from "@/api"; import manifest from "~/package.json" with { type: "json" }; export default apiRoute((app) => diff --git a/packages/api/routes/well-known/nodeinfo/index.ts b/packages/api/routes/well-known/nodeinfo/index.ts index 4a60a204..1dc7d88f 100644 --- a/packages/api/routes/well-known/nodeinfo/index.ts +++ b/packages/api/routes/well-known/nodeinfo/index.ts @@ -1,8 +1,8 @@ +import { apiRoute } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/well-known/openid-configuration/index.ts b/packages/api/routes/well-known/openid-configuration/index.ts index fb1add0e..4ac77f2e 100644 --- a/packages/api/routes/well-known/openid-configuration/index.ts +++ b/packages/api/routes/well-known/openid-configuration/index.ts @@ -1,8 +1,8 @@ +import { apiRoute } from "@versia/kit/api"; import { config } from "@versia-server/config"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { z } from "zod"; -import { apiRoute } from "@/api"; export default apiRoute((app) => app.get( diff --git a/packages/api/routes/well-known/versia.ts b/packages/api/routes/well-known/versia.ts index 28f593cd..c1f3a5b0 100644 --- a/packages/api/routes/well-known/versia.ts +++ b/packages/api/routes/well-known/versia.ts @@ -1,3 +1,4 @@ +import { apiRoute } from "@versia/kit/api"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { InstanceMetadataSchema } from "@versia/sdk/schemas"; @@ -5,7 +6,6 @@ import { config } from "@versia-server/config"; import { asc } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; -import { apiRoute } from "@/api"; import { urlToContentFormat } from "@/content_types"; import pkg from "~/package.json" with { type: "json" }; diff --git a/packages/api/routes/well-known/webfinger/index.ts b/packages/api/routes/well-known/webfinger/index.ts index 2212ba11..27b7e6da 100644 --- a/packages/api/routes/well-known/webfinger/index.ts +++ b/packages/api/routes/well-known/webfinger/index.ts @@ -1,6 +1,9 @@ import { getLogger } from "@logtape/logtape"; import { ApiError } from "@versia/kit"; +import { apiRoute, handleZodError } from "@versia/kit/api"; import { User } from "@versia/kit/db"; +import { parseUserAddress } from "@versia/kit/parsers"; +import { uuid, webfingerMention } from "@versia/kit/regex"; import { Users } from "@versia/kit/tables"; import { FederationRequester } from "@versia/sdk/http"; import { WebFingerSchema } from "@versia/sdk/schemas"; @@ -9,13 +12,6 @@ import { and, eq, isNull } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { - apiRoute, - handleZodError, - idValidator, - parseUserAddress, - webfingerMention, -} from "@/api"; export default apiRoute((app) => app.get( @@ -68,7 +64,7 @@ export default apiRoute((app) => ); } - const isUuid = username.match(idValidator); + const isUuid = username.match(uuid); const user = await User.fromSql( and( diff --git a/packages/api/setup.ts b/packages/api/setup.ts index 1c44afd4..9647bc6f 100644 --- a/packages/api/setup.ts +++ b/packages/api/setup.ts @@ -1,8 +1,8 @@ import { getLogger } from "@logtape/logtape"; import { Note, setupDatabase } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import { config } from "@versia-server/config"; import { configureLoggers } from "@/loggers"; -import { connection } from "@/redis.ts"; import { searchManager } from "../../classes/search/search-manager.ts"; const timeAtStart = performance.now(); diff --git a/packages/api/util.ts b/packages/api/util.ts new file mode 100644 index 00000000..e69de29b diff --git a/utils/api.ts b/packages/plugin-kit/api.ts similarity index 82% rename from utils/api.ts rename to packages/plugin-kit/api.ts index a325469b..e3dd5636 100644 --- a/utils/api.ts +++ b/packages/plugin-kit/api.ts @@ -1,91 +1,29 @@ import type { Hook } from "@hono/zod-validator"; import { getLogger } from "@logtape/logtape"; import type { RolePermission } from "@versia/client/schemas"; -import { ApiError } from "@versia/kit"; -import { Application, db, Emoji, Note, Token, User } from "@versia/kit/db"; -import { Challenges } from "@versia/kit/tables"; import { config } from "@versia-server/config"; import { extractParams, verifySolution } from "altcha-lib"; -import { SHA256 } from "bun"; import chalk from "chalk"; import { eq, type SQL } from "drizzle-orm"; import type { Context, Hono, MiddlewareHandler, ValidationTargets } from "hono"; import { every } from "hono/combine"; import { createMiddleware } from "hono/factory"; import { validator } from "hono-openapi/zod"; -import { - anyOf, - caseInsensitive, - charIn, - createRegExp, - digit, - exactly, - global, - letter, - maybe, - oneOrMore, -} from "magic-regexp"; import { type ParsedQs, parse } from "qs"; import { type ZodAny, type ZodError, z } from "zod"; import { fromZodError } from "zod-validation-error"; -import type { AuthData } from "~/classes/functions/user"; -import type { HonoEnv } from "~/types/api"; +import type { AuthData, HonoEnv } from "~/types/api"; +import { ApiError } from "./api-error.ts"; +import { Application } from "./db/application.ts"; +import { Emoji } from "./db/emoji.ts"; +import { Note } from "./db/note.ts"; +import { Token } from "./db/token.ts"; +import { User } from "./db/user.ts"; +import { db } from "./tables/db.ts"; +import { Challenges } from "./tables/schema.ts"; export const apiRoute = (fn: (app: Hono) => void): typeof fn => fn; -export const idValidator = createRegExp( - anyOf(digit, charIn("ABCDEF")).times(8), - exactly("-"), - anyOf(digit, charIn("ABCDEF")).times(4), - exactly("-"), - exactly("7"), - anyOf(digit, charIn("ABCDEF")).times(3), - exactly("-"), - anyOf("8", "9", "A", "B").times(1), - anyOf(digit, charIn("ABCDEF")).times(3), - exactly("-"), - anyOf(digit, charIn("ABCDEF")).times(12), - [caseInsensitive], -); - -export const mentionValidator = createRegExp( - exactly("@"), - oneOrMore(anyOf(letter.lowercase, digit, charIn("-_"))).groupedAs( - "username", - ), - maybe( - exactly("@"), - oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"), - ), - [global], -); - -export const webfingerMention = createRegExp( - exactly("acct:"), - oneOrMore(anyOf(letter, digit, charIn("-_"))).groupedAs("username"), - maybe( - exactly("@"), - oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"), - ), - [], -); - -export const parseUserAddress = ( - address: string, -): { - username: string; - domain?: string; -} => { - let output = address; - // Remove leading @ if it exists - if (output.startsWith("@")) { - output = output.slice(1); - } - - const [username, domain] = output.split("@"); - return { username, domain }; -}; - export const handleZodError: Hook< z.infer, HonoEnv, @@ -478,31 +416,6 @@ export const jsonOrForm = (): MiddlewareHandler => { }); }; -export const debugRequest = async (req: Request): Promise => { - const body = await req.text(); - const logger = getLogger("server"); - - const urlAndMethod = `${chalk.green(req.method)} ${chalk.blue(req.url)}`; - - const hash = `${chalk.bold("Hash")}: ${chalk.yellow( - new SHA256().update(body).digest("hex"), - )}`; - - const headers = `${chalk.bold("Headers")}:\n${Array.from( - req.headers.entries(), - ) - .map(([key, value]) => ` - ${chalk.cyan(key)}: ${chalk.white(value)}`) - .join("\n")}`; - - const bodyLog = `${chalk.bold("Body")}: ${chalk.gray(body)}`; - - if (config.logging.types.requests_content) { - logger.debug`${urlAndMethod}\n${hash}\n${headers}\n${bodyLog}`; - } else { - logger.debug`${urlAndMethod}`; - } -}; - export const debugResponse = async (res: Response): Promise => { const body = await res.clone().text(); const logger = getLogger("server"); diff --git a/packages/plugin-kit/db/note.ts b/packages/plugin-kit/db/note.ts index 5144ff20..df3e7f98 100644 --- a/packages/plugin-kit/db/note.ts +++ b/packages/plugin-kit/db/note.ts @@ -1,5 +1,7 @@ import type { NoteReactionWithAccounts, Status } from "@versia/client/schemas"; import { db, Instance, type Reaction } from "@versia/kit/db"; +import { versiaTextToHtml } from "@versia/kit/parsers"; +import { uuid } from "@versia/kit/regex"; import { EmojiToNote, Likes, @@ -26,10 +28,8 @@ import { import { htmlToText } from "html-to-text"; import { createRegExp, exactly, global } from "magic-regexp"; import type { z } from "zod"; -import { idValidator } from "@/api"; import { mergeAndDeduplicate } from "@/lib.ts"; import { sanitizedHtmlStrip } from "@/sanitization"; -import { contentToHtml, findManyNotes } from "~/classes/functions/status"; import { DeliveryJobType, deliveryQueue, @@ -38,7 +38,188 @@ import { Application } from "./application.ts"; import { BaseInterface } from "./base.ts"; import { Emoji } from "./emoji.ts"; import { Media } from "./media.ts"; -import { User } from "./user.ts"; +import { + transformOutputToUserWithRelations, + User, + userRelations, +} from "./user.ts"; + +/** + * Wrapper against the Status object to make it easier to work with + * @param query + * @returns + */ +const findManyNotes = async ( + query: Parameters[0], + userId?: string, +): Promise<(typeof Note.$type)[]> => { + const output = await db.query.Notes.findMany({ + ...query, + with: { + ...query?.with, + attachments: { + with: { + media: true, + }, + }, + reactions: { + with: { + emoji: { + with: { + instance: true, + media: true, + }, + }, + }, + }, + emojis: { + with: { + emoji: { + with: { + instance: true, + media: true, + }, + }, + }, + }, + author: { + with: { + ...userRelations, + }, + }, + mentions: { + with: { + user: { + with: { + instance: true, + }, + }, + }, + }, + reblog: { + with: { + attachments: { + with: { + media: true, + }, + }, + reactions: { + with: { + emoji: { + with: { + instance: true, + media: true, + }, + }, + }, + }, + emojis: { + with: { + emoji: { + with: { + instance: true, + media: true, + }, + }, + }, + }, + likes: true, + application: true, + mentions: { + with: { + user: { + with: userRelations, + }, + }, + }, + author: { + with: { + ...userRelations, + }, + }, + }, + extras: { + pinned: userId + ? sql`EXISTS (SELECT 1 FROM "UserToPinnedNotes" WHERE "UserToPinnedNotes"."noteId" = "Notes_reblog".id AND "UserToPinnedNotes"."userId" = ${userId})`.as( + "pinned", + ) + : sql`false`.as("pinned"), + reblogged: userId + ? sql`EXISTS (SELECT 1 FROM "Notes" WHERE "Notes"."authorId" = ${userId} AND "Notes"."reblogId" = "Notes_reblog".id)`.as( + "reblogged", + ) + : sql`false`.as("reblogged"), + muted: userId + ? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."ownerId" = ${userId} AND "Relationships"."subjectId" = "Notes_reblog"."authorId" AND "Relationships"."muting" = true)`.as( + "muted", + ) + : sql`false`.as("muted"), + liked: userId + ? sql`EXISTS (SELECT 1 FROM "Likes" WHERE "Likes"."likedId" = "Notes_reblog".id AND "Likes"."likerId" = ${userId})`.as( + "liked", + ) + : sql`false`.as("liked"), + }, + }, + reply: true, + quote: true, + }, + extras: { + pinned: userId + ? sql`EXISTS (SELECT 1 FROM "UserToPinnedNotes" WHERE "UserToPinnedNotes"."noteId" = "Notes".id AND "UserToPinnedNotes"."userId" = ${userId})`.as( + "pinned", + ) + : sql`false`.as("pinned"), + reblogged: userId + ? sql`EXISTS (SELECT 1 FROM "Notes" WHERE "Notes"."authorId" = ${userId} AND "Notes"."reblogId" = "Notes".id)`.as( + "reblogged", + ) + : sql`false`.as("reblogged"), + muted: userId + ? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."ownerId" = ${userId} AND "Relationships"."subjectId" = "Notes"."authorId" AND "Relationships"."muting" = true)`.as( + "muted", + ) + : sql`false`.as("muted"), + liked: userId + ? sql`EXISTS (SELECT 1 FROM "Likes" WHERE "Likes"."likedId" = "Notes".id AND "Likes"."likerId" = ${userId})`.as( + "liked", + ) + : sql`false`.as("liked"), + ...query?.extras, + }, + }); + + return output.map((post) => ({ + ...post, + author: transformOutputToUserWithRelations(post.author), + mentions: post.mentions.map((mention) => ({ + ...mention.user, + endpoints: mention.user.endpoints, + })), + attachments: post.attachments.map((attachment) => attachment.media), + emojis: (post.emojis ?? []).map((emoji) => emoji.emoji), + reblog: post.reblog && { + ...post.reblog, + author: transformOutputToUserWithRelations(post.reblog.author), + mentions: post.reblog.mentions.map((mention) => ({ + ...mention.user, + endpoints: mention.user.endpoints, + })), + attachments: post.reblog.attachments.map( + (attachment) => attachment.media, + ), + emojis: (post.reblog.emojis ?? []).map((emoji) => emoji.emoji), + pinned: Boolean(post.reblog.pinned), + reblogged: Boolean(post.reblog.reblogged), + muted: Boolean(post.reblog.muted), + liked: Boolean(post.reblog.liked), + }, + pinned: Boolean(post.pinned), + reblogged: Boolean(post.reblogged), + muted: Boolean(post.muted), + liked: Boolean(post.liked), + })); +}; type NoteType = InferSelectModel; @@ -423,15 +604,15 @@ export class Note extends BaseInterface { // Check if URI is of a local note if (uri.origin === config.http.base_url.origin) { - const uuid = uri.pathname.match(idValidator); + const noteUuid = uri.pathname.match(uuid); - if (!uuid?.[0]) { + if (!noteUuid?.[0]) { throw new Error( `URI ${uri} is of a local note, but it could not be parsed`, ); } - return await Note.fromId(uuid[0]); + return await Note.fromId(noteUuid[0]); } return Note.fromVersia(uri); @@ -535,7 +716,7 @@ export class Note extends BaseInterface { await note.update({ content: versiaNote.content - ? await contentToHtml(versiaNote.content, mentions) + ? await versiaTextToHtml(versiaNote.content, mentions) : undefined, contentSource: versiaNote.content ? versiaNote.content.data["text/plain"]?.content || diff --git a/packages/plugin-kit/db/notification.ts b/packages/plugin-kit/db/notification.ts index a90f5afa..175f1fd8 100644 --- a/packages/plugin-kit/db/notification.ts +++ b/packages/plugin-kit/db/notification.ts @@ -10,11 +10,8 @@ import { type SQL, } from "drizzle-orm"; import type { z } from "zod"; -import { - transformOutputToUserWithRelations, - userRelations, -} from "../../../classes/functions/user.ts"; import { BaseInterface } from "./base.ts"; +import { transformOutputToUserWithRelations, userRelations } from "./user.ts"; export type NotificationType = InferSelectModel & { status: typeof Note.$type | null; diff --git a/packages/plugin-kit/db/user.ts b/packages/plugin-kit/db/user.ts index 16fe1c58..3058765e 100644 --- a/packages/plugin-kit/db/user.ts +++ b/packages/plugin-kit/db/user.ts @@ -13,6 +13,7 @@ import { PushSubscription, Reaction, } from "@versia/kit/db"; +import { uuid } from "@versia/kit/regex"; import { EmojiToUser, Likes, @@ -46,11 +47,9 @@ import { } from "drizzle-orm"; import { htmlToText } from "html-to-text"; import type { z } from "zod"; -import { idValidator } from "@/api"; import { getBestContentType } from "@/content_types"; import { randomString } from "@/math"; import { sentry } from "@/sentry"; -import { findManyUsers } from "~/classes/functions/user"; import { searchManager } from "~/classes/search/search-manager"; import type { HttpVerb, KnownEntity } from "~/types/api.ts"; import { @@ -66,6 +65,89 @@ import { Note } from "./note.ts"; import { Relationship } from "./relationship.ts"; import { Role } from "./role.ts"; +export const userRelations = { + instance: true, + emojis: { + with: { + emoji: { + with: { + instance: true, + media: true, + }, + }, + }, + }, + avatar: true, + header: true, + roles: { + with: { + role: true, + }, + }, +} as const; + +export const transformOutputToUserWithRelations = ( + user: Omit, "endpoints"> & { + followerCount: unknown; + followingCount: unknown; + statusCount: unknown; + avatar: typeof Media.$type | null; + header: typeof Media.$type | null; + emojis: { + userId: string; + emojiId: string; + emoji?: typeof Emoji.$type; + }[]; + instance: typeof Instance.$type | null; + roles: { + userId: string; + roleId: string; + role?: typeof Role.$type; + }[]; + endpoints: unknown; + }, +): typeof User.$type => { + return { + ...user, + followerCount: Number(user.followerCount), + followingCount: Number(user.followingCount), + statusCount: Number(user.statusCount), + endpoints: + user.endpoints ?? + ({} as Partial<{ + dislikes: string; + featured: string; + likes: string; + followers: string; + following: string; + inbox: string; + outbox: string; + }>), + emojis: user.emojis.map( + (emoji) => + (emoji as unknown as Record) + .emoji as typeof Emoji.$type, + ), + roles: user.roles + .map((role) => role.role) + .filter(Boolean) as (typeof Role.$type)[], + }; +}; + +const findManyUsers = async ( + query: Parameters[0], +): Promise<(typeof User.$type)[]> => { + const output = await db.query.Users.findMany({ + ...query, + with: { + ...userRelations, + ...query?.with, + }, + }); + + return output.map((user) => transformOutputToUserWithRelations(user)); +}; + type UserWithInstance = InferSelectModel & { instance: typeof Instance.$type | null; }; @@ -1094,15 +1176,15 @@ export class User extends BaseInterface { // Check if URI is of a local user if (uri.origin === config.http.base_url.origin) { - const uuid = uri.href.match(idValidator); + const userUuid = uri.href.match(uuid); - if (!uuid?.[0]) { + if (!userUuid?.[0]) { throw new Error( `URI ${uri} is of a local user, but it could not be parsed`, ); } - return await User.fromId(uuid[0]); + return await User.fromId(userUuid[0]); } getLogger(["federation", "resolvers"]) diff --git a/packages/plugin-kit/markdown.ts b/packages/plugin-kit/markdown.ts new file mode 100644 index 00000000..7ad88a17 --- /dev/null +++ b/packages/plugin-kit/markdown.ts @@ -0,0 +1,35 @@ +import markdownItTaskLists from "@hackmd/markdown-it-task-lists"; +import MarkdownIt from "markdown-it"; +import markdownItContainer from "markdown-it-container"; +import markdownItTocDoneRight from "markdown-it-toc-done-right"; + +const createMarkdownIt = (): MarkdownIt => { + const renderer = MarkdownIt({ + html: true, + linkify: true, + }); + + renderer.use(markdownItTocDoneRight, { + containerClass: "toc", + level: [1, 2, 3, 4], + listType: "ul", + listClass: "toc-list", + itemClass: "toc-item", + linkClass: "toc-link", + }); + + renderer.use(markdownItTaskLists); + + renderer.use(markdownItContainer); + + return renderer; +}; + +/** + * Converts markdown text to HTML using MarkdownIt. + * @param content + * @returns + */ +export const markdownToHtml = async (content: string): Promise => { + return (await createMarkdownIt()).render(content); +}; diff --git a/packages/plugin-kit/package.json b/packages/plugin-kit/package.json index 3e3ef6d1..202c8710 100644 --- a/packages/plugin-kit/package.json +++ b/packages/plugin-kit/package.json @@ -47,7 +47,15 @@ "sharp": "catalog:", "magic-regexp": "catalog:", "altcha-lib": "catalog:", - "hono-openapi": "catalog:" + "hono-openapi": "catalog:", + "qs": "catalog:", + "@hono/zod-validator": "catalog:", + "ioredis": "catalog:", + "linkify-html": "catalog:", + "markdown-it": "catalog:", + "markdown-it-toc-done-right": "catalog:", + "markdown-it-container": "catalog:", + "@hackmd/markdown-it-task-lists": "catalog:" }, "files": [ "tables/migrations" @@ -64,6 +72,26 @@ "./tables": { "import": "./tables/schema.ts", "default": "./tables/schema.ts" + }, + "./api": { + "import": "./api.ts", + "default": "./api.ts" + }, + "./redis": { + "import": "./redis.ts", + "default": "./redis.ts" + }, + "./regex": { + "import": "./regex.ts", + "default": "./regex.ts" + }, + "./markdown": { + "import": "./markdown.ts", + "default": "./markdown.ts" + }, + "./parsers": { + "import": "./parsers.ts", + "default": "./parsers.ts" } } } diff --git a/packages/plugin-kit/parsers.ts b/packages/plugin-kit/parsers.ts new file mode 100644 index 00000000..5d0e66ac --- /dev/null +++ b/packages/plugin-kit/parsers.ts @@ -0,0 +1,169 @@ +import type * as VersiaEntities from "@versia/sdk/entities"; +import { FederationRequester } from "@versia/sdk/http"; +import { config } from "@versia-server/config"; +import { and, eq, inArray, isNull, or } from "drizzle-orm"; +import linkifyHtml from "linkify-html"; +import { + anyOf, + charIn, + createRegExp, + digit, + exactly, + global, + letter, +} from "magic-regexp"; +import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization"; +import { User } from "./db/user.ts"; +import { markdownToHtml } from "./markdown.ts"; +import { mention } from "./regex.ts"; +import { db } from "./tables/db.ts"; +import { Instances, Users } from "./tables/schema.ts"; + +/** + * Get people mentioned in the content (match @username or @username@domain.com mentions) + * @param text The text to parse mentions from. + * @returns An array of users mentioned in the text. + */ +export const parseMentionsFromText = async (text: string): Promise => { + const mentionedPeople = [...text.matchAll(mention)]; + if (mentionedPeople.length === 0) { + return []; + } + + const baseUrlHost = config.http.base_url.host; + const isLocal = (host?: string): boolean => host === baseUrlHost || !host; + + // Find local and matching users + const foundUsers = await db + .select({ + id: Users.id, + username: Users.username, + baseUrl: Instances.baseUrl, + }) + .from(Users) + .leftJoin(Instances, eq(Users.instanceId, Instances.id)) + .where( + or( + ...mentionedPeople.map((person) => + and( + eq(Users.username, person[1] ?? ""), + isLocal(person[2]) + ? isNull(Users.instanceId) + : eq(Instances.baseUrl, person[2] ?? ""), + ), + ), + ), + ); + + // Separate found and unresolved users + const finalList = await User.manyFromSql( + inArray( + Users.id, + foundUsers.map((u) => u.id), + ), + ); + + // Every remote user that isn't in database + const notFoundRemoteUsers = mentionedPeople.filter( + (p) => + !( + foundUsers.some( + (user) => user.username === p[1] && user.baseUrl === p[2], + ) || isLocal(p[2]) + ), + ); + + // Resolve remote mentions not in database + for (const person of notFoundRemoteUsers) { + const url = await FederationRequester.resolveWebFinger( + person[1] ?? "", + person[2] ?? "", + ); + + if (url) { + const user = await User.resolve(url); + + if (user) { + finalList.push(user); + } + } + } + + return finalList; +}; + +export const linkifyUserMentions = (text: string, mentions: User[]): string => { + return mentions.reduce((finalText, mention) => { + const { username, instance } = mention.data; + const { uri } = mention; + const baseHost = config.http.base_url.host; + const linkTemplate = (displayText: string): string => + `${displayText}`; + + if (mention.remote) { + return finalText.replaceAll( + `@${username}@${instance?.baseUrl}`, + linkTemplate(`@${username}@${instance?.baseUrl}`), + ); + } + + return finalText.replace( + createRegExp( + exactly( + exactly(`@${username}`) + .notBefore(anyOf(letter, digit, charIn("@"))) + .notAfter(anyOf(letter, digit, charIn("@"))), + ).or(exactly(`@${username}@${baseHost}`)), + [global], + ), + linkTemplate(`@${username}@${baseHost}`), + ); + }, text); +}; + +export const versiaTextToHtml = async ( + content: VersiaEntities.TextContentFormat, + mentions: User[] = [], + inline = false, +): Promise => { + const sanitizer = inline ? sanitizeHtmlInline : sanitizeHtml; + let htmlContent = ""; + + if (content.data["text/html"]) { + htmlContent = await sanitizer(content.data["text/html"].content); + } else if (content.data["text/markdown"]) { + htmlContent = await sanitizer( + await markdownToHtml(content.data["text/markdown"].content), + ); + } else if (content.data["text/plain"]?.content) { + htmlContent = (await sanitizer(content.data["text/plain"].content)) + .split("\n") + .map((line) => `

${line}

`) + .join("\n"); + } + + htmlContent = linkifyUserMentions(htmlContent, mentions); + + return linkifyHtml(htmlContent, { + defaultProtocol: "https", + validate: { email: (): false => false }, + target: "_blank", + rel: "nofollow noopener noreferrer", + }); +}; + +export const parseUserAddress = ( + address: string, +): { + username: string; + domain?: string; +} => { + let output = address; + // Remove leading @ if it exists + if (output.startsWith("@")) { + output = output.slice(1); + } + + const [username, domain] = output.split("@"); + return { username, domain }; +}; diff --git a/utils/redis.ts b/packages/plugin-kit/redis.ts similarity index 100% rename from utils/redis.ts rename to packages/plugin-kit/redis.ts diff --git a/packages/plugin-kit/regex.ts b/packages/plugin-kit/regex.ts new file mode 100644 index 00000000..11cb505c --- /dev/null +++ b/packages/plugin-kit/regex.ts @@ -0,0 +1,49 @@ +import { + anyOf, + caseInsensitive, + charIn, + createRegExp, + digit, + exactly, + global, + letter, + maybe, + oneOrMore, +} from "magic-regexp"; + +export const uuid = createRegExp( + anyOf(digit, charIn("ABCDEF")).times(8), + exactly("-"), + anyOf(digit, charIn("ABCDEF")).times(4), + exactly("-"), + exactly("7"), + anyOf(digit, charIn("ABCDEF")).times(3), + exactly("-"), + anyOf("8", "9", "A", "B").times(1), + anyOf(digit, charIn("ABCDEF")).times(3), + exactly("-"), + anyOf(digit, charIn("ABCDEF")).times(12), + [caseInsensitive], +); + +export const mention = createRegExp( + exactly("@"), + oneOrMore(anyOf(letter.lowercase, digit, charIn("-_"))).groupedAs( + "username", + ), + maybe( + exactly("@"), + oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"), + ), + [global], +); + +export const webfingerMention = createRegExp( + exactly("acct:"), + oneOrMore(anyOf(letter, digit, charIn("-_"))).groupedAs("username"), + maybe( + exactly("@"), + oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"), + ), + [], +); diff --git a/packages/worker/setup.ts b/packages/worker/setup.ts index ea668dce..526a4892 100644 --- a/packages/worker/setup.ts +++ b/packages/worker/setup.ts @@ -1,9 +1,9 @@ import { getLogger } from "@logtape/logtape"; import { Note, setupDatabase } from "@versia/kit/db"; +import { connection } from "@versia/kit/redis"; import { config } from "@versia-server/config"; import chalk from "chalk"; import { configureLoggers } from "@/loggers"; -import { connection } from "@/redis.ts"; import { searchManager } from "../../classes/search/search-manager.ts"; const timeAtStart = performance.now(); diff --git a/plugins/openid/routes/authorize.ts b/plugins/openid/routes/authorize.ts index f75f5999..e554fc21 100644 --- a/plugins/openid/routes/authorize.ts +++ b/plugins/openid/routes/authorize.ts @@ -1,4 +1,5 @@ import { RolePermission } from "@versia/client/schemas"; +import { auth, handleZodError, jsonOrForm } from "@versia/kit/api"; import { Application, Token, User } from "@versia/kit/db"; import { randomUUIDv7 } from "bun"; import { describeRoute } from "hono-openapi"; @@ -6,7 +7,6 @@ import { validator } from "hono-openapi/zod"; import { type JWTPayload, jwtVerify, SignJWT } from "jose"; import { JOSEError } from "jose/errors"; import { z } from "zod"; -import { auth, handleZodError, jsonOrForm } from "@/api"; import { randomString } from "@/math"; import { errorRedirect, errors } from "../errors.ts"; import type { PluginType } from "../index.ts"; diff --git a/plugins/openid/routes/jwks.ts b/plugins/openid/routes/jwks.ts index 02751413..66b627b4 100644 --- a/plugins/openid/routes/jwks.ts +++ b/plugins/openid/routes/jwks.ts @@ -1,8 +1,8 @@ +import { auth } from "@versia/kit/api"; import { describeRoute } from "hono-openapi"; import { resolver } from "hono-openapi/zod"; import { exportJWK } from "jose"; import { z } from "zod"; -import { auth } from "@/api"; import type { PluginType } from "../index.ts"; export default (plugin: PluginType): void => { diff --git a/plugins/openid/routes/oauth/callback.ts b/plugins/openid/routes/oauth/callback.ts index 5683a60e..182db3eb 100644 --- a/plugins/openid/routes/oauth/callback.ts +++ b/plugins/openid/routes/oauth/callback.ts @@ -3,6 +3,7 @@ import { RolePermission, } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { handleZodError } from "@versia/kit/api"; import { db, Media, Token, User } from "@versia/kit/db"; import { OpenIdAccounts, Users } from "@versia/kit/tables"; import { randomUUIDv7 } from "bun"; @@ -12,7 +13,6 @@ import { describeRoute } from "hono-openapi"; import { validator } from "hono-openapi/zod"; import { SignJWT } from "jose"; import { z } from "zod"; -import { handleZodError } from "@/api"; import { randomString } from "@/math.ts"; import type { PluginType } from "../../index.ts"; import { automaticOidcFlow } from "../../utils.ts"; diff --git a/plugins/openid/routes/oauth/revoke.ts b/plugins/openid/routes/oauth/revoke.ts index da0a4ab9..979d6593 100644 --- a/plugins/openid/routes/oauth/revoke.ts +++ b/plugins/openid/routes/oauth/revoke.ts @@ -1,10 +1,10 @@ +import { handleZodError, jsonOrForm } from "@versia/kit/api"; import { db, Token } from "@versia/kit/db"; import { Tokens } from "@versia/kit/tables"; import { and, eq } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { handleZodError, jsonOrForm } from "@/api"; import type { PluginType } from "../../index.ts"; export default (plugin: PluginType): void => { diff --git a/plugins/openid/routes/oauth/sso.ts b/plugins/openid/routes/oauth/sso.ts index 9918998f..847d42f4 100644 --- a/plugins/openid/routes/oauth/sso.ts +++ b/plugins/openid/routes/oauth/sso.ts @@ -1,3 +1,4 @@ +import { handleZodError } from "@versia/kit/api"; import { Application, db } from "@versia/kit/db"; import { OpenIdLoginFlows } from "@versia/kit/tables"; import { randomUUIDv7 } from "bun"; @@ -10,7 +11,6 @@ import { processDiscoveryResponse, } from "oauth4webapi"; import { z } from "zod"; -import { handleZodError } from "@/api.ts"; import type { PluginType } from "../../index.ts"; import { oauthRedirectUri } from "../../utils.ts"; diff --git a/plugins/openid/routes/oauth/token.ts b/plugins/openid/routes/oauth/token.ts index a2585fcd..dfaf0b2f 100644 --- a/plugins/openid/routes/oauth/token.ts +++ b/plugins/openid/routes/oauth/token.ts @@ -1,10 +1,10 @@ +import { handleZodError, jsonOrForm } from "@versia/kit/api"; import { Application, Token } from "@versia/kit/db"; import { Tokens } from "@versia/kit/tables"; import { and, eq } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { handleZodError, jsonOrForm } from "@/api"; import type { PluginType } from "../../index.ts"; export default (plugin: PluginType): void => { diff --git a/plugins/openid/routes/sso/:id/index.ts b/plugins/openid/routes/sso/:id/index.ts index d08fc0b8..5327c0c6 100644 --- a/plugins/openid/routes/sso/:id/index.ts +++ b/plugins/openid/routes/sso/:id/index.ts @@ -1,12 +1,12 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { auth, handleZodError } from "@versia/kit/api"; import { db } from "@versia/kit/db"; import { OpenIdAccounts } from "@versia/kit/tables"; import { and, eq, type SQL } from "drizzle-orm"; import { describeRoute } from "hono-openapi"; import { resolver, validator } from "hono-openapi/zod"; import { z } from "zod"; -import { auth, handleZodError } from "@/api"; import type { PluginType } from "~/plugins/openid"; export default (plugin: PluginType): void => { diff --git a/plugins/openid/routes/sso/index.ts b/plugins/openid/routes/sso/index.ts index 0f09dbff..b6ab5585 100644 --- a/plugins/openid/routes/sso/index.ts +++ b/plugins/openid/routes/sso/index.ts @@ -1,5 +1,6 @@ import { RolePermission } from "@versia/client/schemas"; import { ApiError } from "@versia/kit"; +import { auth, handleZodError } from "@versia/kit/api"; import { Application, db } from "@versia/kit/db"; import { OpenIdLoginFlows } from "@versia/kit/tables"; import { randomUUIDv7 } from "bun"; @@ -10,7 +11,6 @@ import { generateRandomCodeVerifier, } from "oauth4webapi"; import { z } from "zod"; -import { auth, handleZodError } from "@/api"; import type { PluginType } from "../../index.ts"; import { oauthDiscoveryRequest, oauthRedirectUri } from "../../utils.ts"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 464080a3..cdd81082 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,9 @@ settings: catalogs: default: + '@biomejs/biome': + specifier: 2.0.0-beta.5 + version: 2.0.0-beta.5 '@bull-board/api': specifier: ^6.10.1 version: 6.10.1 @@ -414,6 +417,9 @@ importers: specifier: 'catalog:' version: 3.5.0(zod@3.25.64) devDependencies: + '@biomejs/biome': + specifier: 'catalog:' + version: 2.0.0-beta.5 '@types/bun': specifier: 'catalog:' version: 1.2.16 @@ -465,6 +471,9 @@ importers: packages/api: dependencies: + '@hono/zod-validator': + specifier: 'catalog:' + version: 0.7.0(hono@4.7.11)(zod@3.25.64) '@logtape/logtape': specifier: 'catalog:' version: 0.12.0 @@ -486,6 +495,9 @@ importers: '@versia/sdk': specifier: workspace:* version: link:../sdk + altcha-lib: + specifier: 'catalog:' + version: 1.3.0 bun-bagel: specifier: 'catalog:' version: 1.2.0(typescript@5.8.3) @@ -513,6 +525,12 @@ importers: jose: specifier: 'catalog:' version: 6.0.11 + magic-regexp: + specifier: 'catalog:' + version: 0.10.0 + qs: + specifier: 'catalog:' + version: 6.14.0 sharp: specifier: 'catalog:' version: 0.34.2 @@ -531,6 +549,9 @@ importers: zod-openapi: specifier: 'catalog:' version: 4.2.4(zod@3.25.64) + zod-validation-error: + specifier: 'catalog:' + version: 3.5.0(zod@3.25.64) packages/client: dependencies: @@ -582,6 +603,12 @@ importers: packages/plugin-kit: dependencies: + '@hackmd/markdown-it-task-lists': + specifier: 'catalog:' + version: 2.1.4 + '@hono/zod-validator': + specifier: 'catalog:' + version: 0.7.0(hono@4.7.11)(zod@3.25.64) '@logtape/logtape': specifier: 'catalog:' version: 0.12.0 @@ -612,12 +639,30 @@ importers: html-to-text: specifier: 'catalog:' version: 9.0.5 + ioredis: + specifier: 'catalog:' + version: 5.6.1 + linkify-html: + specifier: 'catalog:' + version: 4.3.1(linkifyjs@4.3.1) magic-regexp: specifier: 'catalog:' version: 0.10.0 + markdown-it: + specifier: 'catalog:' + version: 14.1.0 + markdown-it-container: + specifier: 'catalog:' + version: 4.0.0 + markdown-it-toc-done-right: + specifier: 'catalog:' + version: 4.2.0 mitt: specifier: 'catalog:' version: 3.0.1 + qs: + specifier: 'catalog:' + version: 6.14.0 sharp: specifier: 'catalog:' version: 0.34.2 @@ -783,6 +828,59 @@ packages: resolution: {integrity: sha512-EHsoV6oLHot7HeYkIoSxCZApNgBjwNo1OTV9kXIDnmijGAshlVkJreVAAtexFn+sfDKPE0JW5SCPYJV1y4IoMg==} engines: {node: '>= 18'} + '@biomejs/biome@2.0.0-beta.5': + resolution: {integrity: sha512-1ldO4AepieVvg4aLi1ubZkA7NsefQT2UTNssbJbDiQTGem8kCHx/PZCwLxIR6UzFpGIjh0xsDzivyVvhnmqmuA==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.0.0-beta.5': + resolution: {integrity: sha512-pnJiaoDpwGo+ctGkMu4POcO8jgOgCErBdYbhutr+K9rxxJS+TlHLr0LR91GCEWbGV2O1oyZRFQcW21rYFoak4w==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.0.0-beta.5': + resolution: {integrity: sha512-WwEZpqcmsNoFpZkUFNQcbZo52WK4hLGQ0vZk3PQ8JlZ55gJsHiyhtv6aem6fVlyVCvZgpsC0sYPLE3VvFVKNAQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.0.0-beta.5': + resolution: {integrity: sha512-4vxNkYx1uEt211W8hLdXddc7icRHQgYENb72g6uTd/tLVPSBvIwqUAxAOkU+9Ai1E/8R4sWy7HIxREgpuFgbNA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.0.0-beta.5': + resolution: {integrity: sha512-lAF1de+Ki0vnq14NwDXouKkAR/iviyMNrUngSHjTGFC4z8XGVEfIw0ZMSm7fAdJZ5fAWodt9HiYmEAVs5EtHQg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.0.0-beta.5': + resolution: {integrity: sha512-nUeKGO517GtRCxziVD9les1HiCs2s2/WIVITMN9+9RRuLOko8r+T77E8ZXEmlfLOfOIOeE6z62WITqei3oNccA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.0.0-beta.5': + resolution: {integrity: sha512-I0Pt1VHeL1mN8G7ZwV2u9AfzBd5ZKfbvHUI4x2wETUZbwcQlAu/nEzEa2LUe5HqSmnctTR36ig7RkkM9qbmIrA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.0.0-beta.5': + resolution: {integrity: sha512-YXW6hgbrgBcWQ1SLO69ypWlluPchgQV5C1lTG4xOcBUWdCsfYuQirM64S6Dov7SFPqsMIoFC6LlQRW+n8qAyiA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.0.0-beta.5': + resolution: {integrity: sha512-N7Yby52BJmvEdst1iMbclE5hxxefboaXKRJLm1tLfBYr4FeuoCe6j8HdiQSwhCRdIUGFFqBLaDXh//LLF6EReA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@bull-board/api@6.10.1': resolution: {integrity: sha512-VPkZa2XZI2Wk2MqK1XyiiS+tOhNan54mnm2fpv2KA0fdZ92mQqNjhKkOpsykhQv9XUEc8cCRlZqGxf67YCMJbQ==} peerDependencies: @@ -3837,6 +3935,41 @@ snapshots: '@badgateway/oauth2-client@3.2.0': {} + '@biomejs/biome@2.0.0-beta.5': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.0.0-beta.5 + '@biomejs/cli-darwin-x64': 2.0.0-beta.5 + '@biomejs/cli-linux-arm64': 2.0.0-beta.5 + '@biomejs/cli-linux-arm64-musl': 2.0.0-beta.5 + '@biomejs/cli-linux-x64': 2.0.0-beta.5 + '@biomejs/cli-linux-x64-musl': 2.0.0-beta.5 + '@biomejs/cli-win32-arm64': 2.0.0-beta.5 + '@biomejs/cli-win32-x64': 2.0.0-beta.5 + + '@biomejs/cli-darwin-arm64@2.0.0-beta.5': + optional: true + + '@biomejs/cli-darwin-x64@2.0.0-beta.5': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.0.0-beta.5': + optional: true + + '@biomejs/cli-linux-arm64@2.0.0-beta.5': + optional: true + + '@biomejs/cli-linux-x64-musl@2.0.0-beta.5': + optional: true + + '@biomejs/cli-linux-x64@2.0.0-beta.5': + optional: true + + '@biomejs/cli-win32-arm64@2.0.0-beta.5': + optional: true + + '@biomejs/cli-win32-x64@2.0.0-beta.5': + optional: true + '@bull-board/api@6.10.1(@bull-board/ui@6.10.1)': dependencies: '@bull-board/ui': 6.10.1 diff --git a/types/api.ts b/types/api.ts index 494d582e..553e6831 100644 --- a/types/api.ts +++ b/types/api.ts @@ -1,13 +1,19 @@ +import type { Application, Token, User } from "@versia/kit/db"; import type * as VersiaEntities from "@versia/sdk/entities"; import type { ConfigSchema } from "@versia-server/config/schema"; import type { SocketAddress } from "bun"; import type { Hono } from "hono"; import type { RouterRoute } from "hono/types"; import type { z } from "zod"; -import type { AuthData } from "~/classes/functions/user"; export type HttpVerb = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS"; +export interface AuthData { + user: User | null; + token: Token | null; + application: Application | null; +} + export type HonoEnv = { Variables: { config: z.infer; diff --git a/utils/server.ts b/utils/server.ts index d5979633..6cd047e9 100644 --- a/utils/server.ts +++ b/utils/server.ts @@ -1,9 +1,9 @@ +import { debugResponse } from "@versia/kit/api"; import type { ConfigSchema } from "@versia-server/config/schema"; import { type Server, serve } from "bun"; import type { Hono } from "hono"; import type { z } from "zod"; import type { HonoEnv } from "~/types/api"; -import { debugResponse } from "./api.ts"; export const createServer = ( config: z.infer,