diff --git a/api/api/auth/login/index.ts b/api/api/auth/login/index.ts index 93d59c89..5458724b 100644 --- a/api/api/auth/login/index.ts +++ b/api/api/auth/login/index.ts @@ -1,12 +1,11 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Application, User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { eq, or } from "drizzle-orm"; import type { Context } from "hono"; import { setCookie } from "hono/cookie"; import { SignJWT } from "jose"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; diff --git a/api/api/auth/redirect/index.ts b/api/api/auth/redirect/index.ts index c35033ec..07310ff4 100644 --- a/api/api/auth/redirect/index.ts +++ b/api/api/auth/redirect/index.ts @@ -1,9 +1,8 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { db } from "@versia/kit/db"; import { Applications, Tokens } from "@versia/kit/tables"; import { and, eq } from "drizzle-orm"; -import { z } from "zod"; import { config } from "~/packages/config-manager"; const schemas = { diff --git a/api/api/auth/reset/index.ts b/api/api/auth/reset/index.ts index 9a04d4b0..dbc9a487 100644 --- a/api/api/auth/reset/index.ts +++ b/api/api/auth/reset/index.ts @@ -1,10 +1,9 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { eq } from "drizzle-orm"; import type { Context } from "hono"; -import { z } from "zod"; import { config } from "~/packages/config-manager"; const schemas = { diff --git a/api/api/v1/accounts/:id/block.ts b/api/api/v1/accounts/:id/block.ts index 595e25a5..58b7f8fb 100644 --- a/api/api/v1/accounts/:id/block.ts +++ b/api/api/v1/accounts/:id/block.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/accounts/:id/follow.ts b/api/api/v1/accounts/:id/follow.ts index c6db8951..dc443f53 100644 --- a/api/api/v1/accounts/:id/follow.ts +++ b/api/api/v1/accounts/:id/follow.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; import ISO6391 from "iso-639-1"; -import { z } from "zod"; const schemas = { param: z.object({ diff --git a/api/api/v1/accounts/:id/followers.ts b/api/api/v1/accounts/:id/followers.ts index 9eafe3cc..8a84dc45 100644 --- a/api/api/v1/accounts/:id/followers.ts +++ b/api/api/v1/accounts/:id/followers.ts @@ -1,9 +1,9 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -43,7 +43,7 @@ const route = createRoute({ description: "A list of accounts that follow the specified account", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, headers: { diff --git a/api/api/v1/accounts/:id/following.ts b/api/api/v1/accounts/:id/following.ts index bcdcf4ae..409f5286 100644 --- a/api/api/v1/accounts/:id/following.ts +++ b/api/api/v1/accounts/:id/following.ts @@ -1,9 +1,9 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -44,7 +44,7 @@ const route = createRoute({ "A list of accounts that the specified account follows", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, headers: { diff --git a/api/api/v1/accounts/:id/index.ts b/api/api/v1/accounts/:id/index.ts index bed7d8b2..1f66730f 100644 --- a/api/api/v1/accounts/:id/index.ts +++ b/api/api/v1/accounts/:id/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const route = createRoute({ method: "get", @@ -26,7 +25,7 @@ const route = createRoute({ description: "Account data", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/accounts/:id/mute.ts b/api/api/v1/accounts/:id/mute.ts index 41b393f2..45b49541 100644 --- a/api/api/v1/accounts/:id/mute.ts +++ b/api/api/v1/accounts/:id/mute.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const schemas = { param: z.object({ diff --git a/api/api/v1/accounts/:id/note.ts b/api/api/v1/accounts/:id/note.ts index 5533b91c..c0f04822 100644 --- a/api/api/v1/accounts/:id/note.ts +++ b/api/api/v1/accounts/:id/note.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const schemas = { param: z.object({ diff --git a/api/api/v1/accounts/:id/pin.ts b/api/api/v1/accounts/:id/pin.ts index d33f7407..72a13771 100644 --- a/api/api/v1/accounts/:id/pin.ts +++ b/api/api/v1/accounts/:id/pin.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/accounts/:id/refetch.ts b/api/api/v1/accounts/:id/refetch.ts index f5da0f71..54d6dcd5 100644 --- a/api/api/v1/accounts/:id/refetch.ts +++ b/api/api/v1/accounts/:id/refetch.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; +import { Account } from "~/classes/schemas/account"; import { ErrorSchema } from "~/types/api"; const route = createRoute({ @@ -29,7 +28,7 @@ const route = createRoute({ description: "Updated user data", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/accounts/:id/remove_from_followers.ts b/api/api/v1/accounts/:id/remove_from_followers.ts index 2ee7a465..aee745c1 100644 --- a/api/api/v1/accounts/:id/remove_from_followers.ts +++ b/api/api/v1/accounts/:id/remove_from_followers.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/accounts/:id/roles/:role_id/index.ts b/api/api/v1/accounts/:id/roles/:role_id/index.ts index af3840e5..e4a72cdb 100644 --- a/api/api/v1/accounts/:id/roles/:role_id/index.ts +++ b/api/api/v1/accounts/:id/roles/:role_id/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Role } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/accounts/:id/roles/index.ts b/api/api/v1/accounts/:id/roles/index.ts index fedf9adc..4adcba97 100644 --- a/api/api/v1/accounts/:id/roles/index.ts +++ b/api/api/v1/accounts/:id/roles/index.ts @@ -1,7 +1,6 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Role } from "@versia/kit/db"; -import { z } from "zod"; const route = createRoute({ method: "get", diff --git a/api/api/v1/accounts/:id/statuses.ts b/api/api/v1/accounts/:id/statuses.ts index 230c01a0..1b5649b2 100644 --- a/api/api/v1/accounts/:id/statuses.ts +++ b/api/api/v1/accounts/:id/statuses.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note, Timeline } from "@versia/kit/db"; import { Notes, RolePermissions } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, isNull, lt, or, sql } from "drizzle-orm"; -import { z } from "zod"; const schemas = { param: z.object({ diff --git a/api/api/v1/accounts/:id/unblock.ts b/api/api/v1/accounts/:id/unblock.ts index fe892b08..f480b575 100644 --- a/api/api/v1/accounts/:id/unblock.ts +++ b/api/api/v1/accounts/:id/unblock.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/accounts/:id/unfollow.ts b/api/api/v1/accounts/:id/unfollow.ts index 19cf3b57..d38ecef8 100644 --- a/api/api/v1/accounts/:id/unfollow.ts +++ b/api/api/v1/accounts/:id/unfollow.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ErrorSchema } from "~/types/api"; const route = createRoute({ diff --git a/api/api/v1/accounts/:id/unmute.ts b/api/api/v1/accounts/:id/unmute.ts index c9ebe777..4bbd9cec 100644 --- a/api/api/v1/accounts/:id/unmute.ts +++ b/api/api/v1/accounts/:id/unmute.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/accounts/:id/unpin.ts b/api/api/v1/accounts/:id/unpin.ts index ee4baf93..59aa469b 100644 --- a/api/api/v1/accounts/:id/unpin.ts +++ b/api/api/v1/accounts/:id/unpin.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withUserParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/accounts/familiar_followers/index.ts b/api/api/v1/accounts/familiar_followers/index.ts index be9632f2..2fc5caa9 100644 --- a/api/api/v1/accounts/familiar_followers/index.ts +++ b/api/api/v1/accounts/familiar_followers/index.ts @@ -1,9 +1,9 @@ import { apiRoute, auth, qsQuery } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { User, db } from "@versia/kit/db"; import { RolePermissions, type Users } from "@versia/kit/tables"; import { type InferSelectModel, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -41,7 +41,7 @@ const route = createRoute({ schema: z.array( z.object({ id: z.string().uuid(), - accounts: z.array(User.schema), + accounts: z.array(Account), }), ), }, diff --git a/api/api/v1/accounts/id/index.ts b/api/api/v1/accounts/id/index.ts index a2c4a050..8f355c97 100644 --- a/api/api/v1/accounts/id/index.ts +++ b/api/api/v1/accounts/id/index.ts @@ -1,10 +1,10 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { User } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; +import { Account } from "~/classes/schemas/account"; import { ErrorSchema } from "~/types/api"; const schemas = { @@ -32,7 +32,7 @@ const route = createRoute({ description: "Account", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/accounts/index.ts b/api/api/v1/accounts/index.ts index a22918e9..b76e6fdc 100644 --- a/api/api/v1/accounts/index.ts +++ b/api/api/v1/accounts/index.ts @@ -1,11 +1,10 @@ import { apiRoute, auth, jsonOrForm } from "@/api"; import { tempmailDomains } from "@/tempmail"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; import ISO6391 from "iso-639-1"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; diff --git a/api/api/v1/accounts/lookup/index.ts b/api/api/v1/accounts/lookup/index.ts index 8763d1e4..ae6b1f5b 100644 --- a/api/api/v1/accounts/lookup/index.ts +++ b/api/api/v1/accounts/lookup/index.ts @@ -1,10 +1,10 @@ import { apiRoute, auth, parseUserAddress } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Instance, User } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; +import { Account } from "~/classes/schemas/account"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; @@ -33,7 +33,7 @@ const route = createRoute({ description: "Account", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/accounts/relationships/index.ts b/api/api/v1/accounts/relationships/index.ts index 5b4b4bcd..f3a81c56 100644 --- a/api/api/v1/accounts/relationships/index.ts +++ b/api/api/v1/accounts/relationships/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, qsQuery } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const schemas = { query: z.object({ diff --git a/api/api/v1/accounts/search/index.ts b/api/api/v1/accounts/search/index.ts index 78efea7e..8fed1c62 100644 --- a/api/api/v1/accounts/search/index.ts +++ b/api/api/v1/accounts/search/index.ts @@ -1,11 +1,11 @@ import { apiRoute, auth, parseUserAddress, userAddressValidator } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { User } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { eq, ilike, not, or, sql } from "drizzle-orm"; import stringComparison from "string-comparison"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -43,7 +43,7 @@ export const route = createRoute({ description: "Accounts", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, }, diff --git a/api/api/v1/accounts/update_credentials/index.ts b/api/api/v1/accounts/update_credentials/index.ts index f44ade7f..868886dc 100644 --- a/api/api/v1/accounts/update_credentials/index.ts +++ b/api/api/v1/accounts/update_credentials/index.ts @@ -1,134 +1,72 @@ import { apiRoute, auth, jsonOrForm } from "@/api"; import { mergeAndDeduplicate } from "@/lib"; import { sanitizedHtmlStrip } from "@/sanitization"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Emoji, User } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; -import ISO6391 from "iso-639-1"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { contentToHtml } from "~/classes/functions/status"; +import { Account } from "~/classes/schemas/account"; import { config } from "~/packages/config-manager/index.ts"; import { ErrorSchema } from "~/types/api"; const schemas = { - json: z.object({ - display_name: z - .string() - .min(3) - .trim() - .max(config.validation.max_displayname_size) - .refine( - (s) => - !config.filters.displayname.some((filter) => - s.match(filter), - ), - "Display name contains blocked words", - ) - .optional(), - username: z - .string() - .min(3) - .trim() - .max(config.validation.max_username_size) - .toLowerCase() - .regex( - /^[a-z0-9_-]+$/, - "Username can only contain letters, numbers, underscores and hyphens", - ) - .refine( - (s) => - !config.filters.username.some((filter) => s.match(filter)), - "Username contains blocked words", - ) - .optional(), - note: z - .string() - .min(0) - .max(config.validation.max_bio_size) - .trim() - .refine( - (s) => !config.filters.bio.some((filter) => s.match(filter)), - "Bio contains blocked words", - ) - .optional(), - avatar: z - .string() - .trim() - .min(1) - .max(2000) - .url() - .transform((a) => new URL(a)) - .or( - z - .instanceof(File) - .refine( - (v) => v.size <= config.validation.max_avatar_size, - `Avatar must be less than ${config.validation.max_avatar_size} bytes`, - ), - ) - .optional(), - header: z - .string() - .trim() - .min(1) - .max(2000) - .url() - .transform((v) => new URL(v)) - .or( - z - .instanceof(File) - .refine( - (v) => v.size <= config.validation.max_header_size, - `Header must be less than ${config.validation.max_header_size} bytes`, - ), - ) - .optional(), - locked: z - .string() - .transform((v) => ["true", "1", "on"].includes(v.toLowerCase())) - .optional(), - bot: z - .string() - .transform((v) => ["true", "1", "on"].includes(v.toLowerCase())) - .optional(), - discoverable: z - .string() - .transform((v) => ["true", "1", "on"].includes(v.toLowerCase())) - .optional(), - source: z - .object({ - privacy: z - .enum(["public", "unlisted", "private", "direct"]) - .optional(), - sensitive: z - .string() - .transform((v) => - ["true", "1", "on"].includes(v.toLowerCase()), - ) - .optional(), - language: z - .enum(ISO6391.getAllCodes() as [string, ...string[]]) - .optional(), - }) - .optional(), - fields_attributes: z - .array( - z.object({ - name: z - .string() - .trim() - .max(config.validation.max_field_name_size), - value: z - .string() - .trim() - .max(config.validation.max_field_value_size), - }), - ) - .max(config.validation.max_field_count) - .optional(), - }), + json: z + .object({ + display_name: Account.shape.display_name, + username: Account.shape.username, + note: Account.shape.note, + avatar: z + .string() + .trim() + .min(1) + .max(2000) + .url() + .transform((a) => new URL(a)) + .or( + z + .instanceof(File) + .refine( + (v) => v.size <= config.validation.max_avatar_size, + `Avatar must be less than ${config.validation.max_avatar_size} bytes`, + ), + ), + header: z + .string() + .trim() + .min(1) + .max(2000) + .url() + .transform((v) => new URL(v)) + .or( + z + .instanceof(File) + .refine( + (v) => v.size <= config.validation.max_header_size, + `Header must be less than ${config.validation.max_header_size} bytes`, + ), + ), + locked: Account.shape.locked, + bot: Account.shape.bot, + discoverable: Account.shape.discoverable, + source: z + .object({ + privacy: Account.shape.source.unwrap().shape.privacy, + sensitive: Account.shape.source.unwrap().shape.sensitive, + language: Account.shape.source.unwrap().shape.language, + }) + .partial(), + fields_attributes: z + .array( + z.object({ + name: Account.shape.fields.element.shape.name, + value: Account.shape.fields.element.shape.value, + }), + ) + .max(config.validation.max_field_count), + }) + .partial(), }; const route = createRoute({ @@ -158,7 +96,7 @@ const route = createRoute({ description: "Updated user", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/accounts/verify_credentials/index.ts b/api/api/v1/accounts/verify_credentials/index.ts index 6898807c..d14d76f6 100644 --- a/api/api/v1/accounts/verify_credentials/index.ts +++ b/api/api/v1/accounts/verify_credentials/index.ts @@ -1,6 +1,6 @@ import { apiRoute, auth } from "@/api"; import { createRoute } from "@hono/zod-openapi"; -import { User } from "@versia/kit/db"; +import { Account } from "~/classes/schemas/account"; const route = createRoute({ method: "get", @@ -18,7 +18,7 @@ const route = createRoute({ description: "Account", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/apps/index.ts b/api/api/v1/apps/index.ts index d9ba9bf0..69227bdc 100644 --- a/api/api/v1/apps/index.ts +++ b/api/api/v1/apps/index.ts @@ -1,8 +1,7 @@ import { apiRoute, jsonOrForm } from "@/api"; import { randomString } from "@/math"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Application } from "@versia/kit/db"; -import { z } from "zod"; const schemas = { json: z.object({ diff --git a/api/api/v1/blocks/index.ts b/api/api/v1/blocks/index.ts index fe5c6666..a28a8484 100644 --- a/api/api/v1/blocks/index.ts +++ b/api/api/v1/blocks/index.ts @@ -1,9 +1,9 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -34,7 +34,7 @@ const route = createRoute({ description: "Blocks", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, }, diff --git a/api/api/v1/emojis/:id/index.ts b/api/api/v1/emojis/:id/index.ts index a1a80a15..7f69fb12 100644 --- a/api/api/v1/emojis/:id/index.ts +++ b/api/api/v1/emojis/:id/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, emojiValidator, jsonOrForm } from "@/api"; import { mimeLookup } from "@/content_types"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Emoji } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/emojis/index.ts b/api/api/v1/emojis/index.ts index b198d65d..75b60d80 100644 --- a/api/api/v1/emojis/index.ts +++ b/api/api/v1/emojis/index.ts @@ -1,10 +1,9 @@ import { apiRoute, auth, emojiValidator, jsonOrForm } from "@/api"; import { mimeLookup } from "@/content_types"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Emoji, Media } from "@versia/kit/db"; import { Emojis, RolePermissions } from "@versia/kit/tables"; import { and, eq, isNull, or } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/favourites/index.ts b/api/api/v1/favourites/index.ts index 4d667acf..886dee91 100644 --- a/api/api/v1/favourites/index.ts +++ b/api/api/v1/favourites/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note, Timeline } from "@versia/kit/db"; import { Notes, RolePermissions } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; const schemas = { query: z.object({ diff --git a/api/api/v1/follow_requests/:account_id/authorize.ts b/api/api/v1/follow_requests/:account_id/authorize.ts index 371f5948..2cb28c6d 100644 --- a/api/api/v1/follow_requests/:account_id/authorize.ts +++ b/api/api/v1/follow_requests/:account_id/authorize.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship, User } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/follow_requests/:account_id/reject.ts b/api/api/v1/follow_requests/:account_id/reject.ts index 7341744b..e487cc88 100644 --- a/api/api/v1/follow_requests/:account_id/reject.ts +++ b/api/api/v1/follow_requests/:account_id/reject.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Relationship, User } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/follow_requests/index.ts b/api/api/v1/follow_requests/index.ts index ffb638bb..d6f70b22 100644 --- a/api/api/v1/follow_requests/index.ts +++ b/api/api/v1/follow_requests/index.ts @@ -1,9 +1,9 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -32,7 +32,7 @@ const route = createRoute({ description: "Follow requests", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, }, diff --git a/api/api/v1/markers/index.ts b/api/api/v1/markers/index.ts index 92f2b881..864095bb 100644 --- a/api/api/v1/markers/index.ts +++ b/api/api/v1/markers/index.ts @@ -1,10 +1,9 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import type { Marker as ApiMarker } from "@versia/client/types"; import { db } from "@versia/kit/db"; import { Markers, RolePermissions } from "@versia/kit/tables"; import { type SQL, and, eq } from "drizzle-orm"; -import { z } from "zod"; const schemas = { markers: z.object({ diff --git a/api/api/v1/media/:id/index.ts b/api/api/v1/media/:id/index.ts index a7ce3e91..abf63bda 100644 --- a/api/api/v1/media/:id/index.ts +++ b/api/api/v1/media/:id/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Media } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager/index.ts"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/media/index.ts b/api/api/v1/media/index.ts index dfc8f130..25b8b349 100644 --- a/api/api/v1/media/index.ts +++ b/api/api/v1/media/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Media } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/mutes/index.ts b/api/api/v1/mutes/index.ts index f7c2c50e..f771d996 100644 --- a/api/api/v1/mutes/index.ts +++ b/api/api/v1/mutes/index.ts @@ -1,9 +1,9 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -33,7 +33,7 @@ const route = createRoute({ description: "Muted users", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, }, diff --git a/api/api/v1/notifications/:id/dismiss.ts b/api/api/v1/notifications/:id/dismiss.ts index 143f5a0c..86e3415d 100644 --- a/api/api/v1/notifications/:id/dismiss.ts +++ b/api/api/v1/notifications/:id/dismiss.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Notification } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; const route = createRoute({ diff --git a/api/api/v1/notifications/:id/index.ts b/api/api/v1/notifications/:id/index.ts index c1a5cbe6..5a1166ba 100644 --- a/api/api/v1/notifications/:id/index.ts +++ b/api/api/v1/notifications/:id/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Notification } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/notifications/destroy_multiple/index.ts b/api/api/v1/notifications/destroy_multiple/index.ts index 0ddc6ab4..17e1a322 100644 --- a/api/api/v1/notifications/destroy_multiple/index.ts +++ b/api/api/v1/notifications/destroy_multiple/index.ts @@ -1,7 +1,6 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const schemas = { query: z.object({ diff --git a/api/api/v1/notifications/index.ts b/api/api/v1/notifications/index.ts index cbf2b16f..b2bfd987 100644 --- a/api/api/v1/notifications/index.ts +++ b/api/api/v1/notifications/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Notification, Timeline } from "@versia/kit/db"; import { Notifications, RolePermissions } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, lt, not, sql } from "drizzle-orm"; -import { z } from "zod"; const schemas = { query: z diff --git a/api/api/v1/profile/avatar.ts b/api/api/v1/profile/avatar.ts index e7380bc8..9c02e985 100644 --- a/api/api/v1/profile/avatar.ts +++ b/api/api/v1/profile/avatar.ts @@ -1,7 +1,7 @@ import { apiRoute, auth } from "@/api"; import { createRoute } from "@hono/zod-openapi"; -import { User } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; +import { Account } from "~/classes/schemas/account"; const route = createRoute({ method: "delete", @@ -19,7 +19,7 @@ const route = createRoute({ description: "User", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/profile/header.ts b/api/api/v1/profile/header.ts index d6389d94..651f6ce4 100644 --- a/api/api/v1/profile/header.ts +++ b/api/api/v1/profile/header.ts @@ -1,7 +1,7 @@ import { apiRoute, auth } from "@/api"; import { createRoute } from "@hono/zod-openapi"; -import { User } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; +import { Account } from "~/classes/schemas/account"; const route = createRoute({ method: "delete", @@ -19,7 +19,7 @@ const route = createRoute({ description: "User", content: { "application/json": { - schema: User.schema, + schema: Account, }, }, }, diff --git a/api/api/v1/roles/:id/index.ts b/api/api/v1/roles/:id/index.ts index 4f0de903..521cc385 100644 --- a/api/api/v1/roles/:id/index.ts +++ b/api/api/v1/roles/:id/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Role } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/statuses/:id/context.ts b/api/api/v1/statuses/:id/context.ts index b21e58e4..f2ed139b 100644 --- a/api/api/v1/statuses/:id/context.ts +++ b/api/api/v1/statuses/:id/context.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ErrorSchema } from "~/types/api"; const route = createRoute({ diff --git a/api/api/v1/statuses/:id/favourite.ts b/api/api/v1/statuses/:id/favourite.ts index e89bd84e..106056f5 100644 --- a/api/api/v1/statuses/:id/favourite.ts +++ b/api/api/v1/statuses/:id/favourite.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/statuses/:id/favourited_by.ts b/api/api/v1/statuses/:id/favourited_by.ts index 8d0d6269..3c1171fe 100644 --- a/api/api/v1/statuses/:id/favourited_by.ts +++ b/api/api/v1/statuses/:id/favourited_by.ts @@ -1,9 +1,9 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { query: z.object({ @@ -40,7 +40,7 @@ const route = createRoute({ description: "Users who favourited a status", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, }, diff --git a/api/api/v1/statuses/:id/index.ts b/api/api/v1/statuses/:id/index.ts index 6bacd8ac..7643d72e 100644 --- a/api/api/v1/statuses/:id/index.ts +++ b/api/api/v1/statuses/:id/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, jsonOrForm, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Media, Note } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; import ISO6391 from "iso-639-1"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager/index.ts"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/statuses/:id/pin.ts b/api/api/v1/statuses/:id/pin.ts index 899412e6..2dd262d1 100644 --- a/api/api/v1/statuses/:id/pin.ts +++ b/api/api/v1/statuses/:id/pin.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note, db } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; import type { SQL } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/statuses/:id/reblog.ts b/api/api/v1/statuses/:id/reblog.ts index 6651fae4..cfc5d046 100644 --- a/api/api/v1/statuses/:id/reblog.ts +++ b/api/api/v1/statuses/:id/reblog.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, jsonOrForm, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note } from "@versia/kit/db"; import { Notes, RolePermissions } from "@versia/kit/tables"; import { and, eq } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/statuses/:id/reblogged_by.ts b/api/api/v1/statuses/:id/reblogged_by.ts index 72392182..4e6113e8 100644 --- a/api/api/v1/statuses/:id/reblogged_by.ts +++ b/api/api/v1/statuses/:id/reblogged_by.ts @@ -1,9 +1,9 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { Timeline, User } from "@versia/kit/db"; +import { createRoute, z } from "@hono/zod-openapi"; +import { Timeline } from "@versia/kit/db"; import { RolePermissions, Users } from "@versia/kit/tables"; import { and, gt, gte, lt, sql } from "drizzle-orm"; -import { z } from "zod"; +import { Account } from "~/classes/schemas/account"; const schemas = { param: z.object({ @@ -40,7 +40,7 @@ const route = createRoute({ description: "Users who reblogged a status", content: { "application/json": { - schema: z.array(User.schema), + schema: z.array(Account), }, }, }, diff --git a/api/api/v1/statuses/:id/source.ts b/api/api/v1/statuses/:id/source.ts index a54a53da..a483dd11 100644 --- a/api/api/v1/statuses/:id/source.ts +++ b/api/api/v1/statuses/:id/source.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import type { StatusSource as ApiStatusSource } from "@versia/client/types"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "get", diff --git a/api/api/v1/statuses/:id/unfavourite.ts b/api/api/v1/statuses/:id/unfavourite.ts index 09c75dd1..944c3d09 100644 --- a/api/api/v1/statuses/:id/unfavourite.ts +++ b/api/api/v1/statuses/:id/unfavourite.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/api/v1/statuses/:id/unpin.ts b/api/api/v1/statuses/:id/unpin.ts index bf5561fa..9b47440c 100644 --- a/api/api/v1/statuses/:id/unpin.ts +++ b/api/api/v1/statuses/:id/unpin.ts @@ -1,8 +1,7 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/statuses/:id/unreblog.ts b/api/api/v1/statuses/:id/unreblog.ts index e56f2082..98bf280e 100644 --- a/api/api/v1/statuses/:id/unreblog.ts +++ b/api/api/v1/statuses/:id/unreblog.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, withNoteParam } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note } from "@versia/kit/db"; import { Notes, RolePermissions } from "@versia/kit/tables"; import { and, eq } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/statuses/index.ts b/api/api/v1/statuses/index.ts index 346c90d6..acf8b25e 100644 --- a/api/api/v1/statuses/index.ts +++ b/api/api/v1/statuses/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, jsonOrForm } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Media, Note } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; import ISO6391 from "iso-639-1"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager/index.ts"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v1/timelines/home.ts b/api/api/v1/timelines/home.ts index 7a98ce38..cca26065 100644 --- a/api/api/v1/timelines/home.ts +++ b/api/api/v1/timelines/home.ts @@ -1,9 +1,8 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note, Timeline } from "@versia/kit/db"; import { Notes, RolePermissions } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm"; -import { z } from "zod"; const schemas = { query: z.object({ diff --git a/api/api/v1/timelines/public.ts b/api/api/v1/timelines/public.ts index 9b239dfc..02170ee0 100644 --- a/api/api/v1/timelines/public.ts +++ b/api/api/v1/timelines/public.ts @@ -1,9 +1,8 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note, Timeline } from "@versia/kit/db"; import { Notes, RolePermissions } from "@versia/kit/tables"; import { and, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm"; -import { z } from "zod"; const schemas = { query: z.object({ diff --git a/api/api/v2/filters/:id/index.ts b/api/api/v2/filters/:id/index.ts index ed3d45b9..84242575 100644 --- a/api/api/v2/filters/:id/index.ts +++ b/api/api/v2/filters/:id/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, jsonOrForm } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { db } from "@versia/kit/db"; import { FilterKeywords, Filters, RolePermissions } from "@versia/kit/tables"; import { type SQL, and, eq, inArray } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v2/filters/index.ts b/api/api/v2/filters/index.ts index 2bb49d24..2d609c5f 100644 --- a/api/api/v2/filters/index.ts +++ b/api/api/v2/filters/index.ts @@ -1,9 +1,8 @@ import { apiRoute, auth, jsonOrForm } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { db } from "@versia/kit/db"; import { FilterKeywords, Filters, RolePermissions } from "@versia/kit/tables"; import type { SQL } from "drizzle-orm"; -import { z } from "zod"; const schemas = { json: z.object({ diff --git a/api/api/v2/instance/index.ts b/api/api/v2/instance/index.ts index ce999dd6..e403733a 100644 --- a/api/api/v2/instance/index.ts +++ b/api/api/v2/instance/index.ts @@ -4,6 +4,7 @@ import { createRoute, z } from "@hono/zod-openapi"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; +import { Account } from "~/classes/schemas/account"; import manifest from "~/package.json"; import { config } from "~/packages/config-manager"; @@ -83,7 +84,7 @@ const route = createRoute({ }), contact: z.object({ email: z.string().nullable(), - account: User.schema.nullable(), + account: Account.nullable(), }), rules: z.array( z.object({ diff --git a/api/api/v2/media/index.ts b/api/api/v2/media/index.ts index f2f8abf6..48b0f838 100644 --- a/api/api/v2/media/index.ts +++ b/api/api/v2/media/index.ts @@ -1,8 +1,7 @@ import { apiRoute, auth } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Media } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; -import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; import { ErrorSchema } from "~/types/api"; diff --git a/api/api/v2/search/index.ts b/api/api/v2/search/index.ts index a877e797..add9e5fa 100644 --- a/api/api/v2/search/index.ts +++ b/api/api/v2/search/index.ts @@ -1,10 +1,10 @@ import { apiRoute, auth, parseUserAddress, userAddressValidator } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Note, User, db } from "@versia/kit/db"; import { Instances, Notes, RolePermissions, Users } from "@versia/kit/tables"; import { and, eq, inArray, isNull, sql } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; +import { Account } from "~/classes/schemas/account"; import { searchManager } from "~/classes/search/search-manager"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; @@ -47,7 +47,7 @@ const route = createRoute({ content: { "application/json": { schema: z.object({ - accounts: z.array(User.schema), + accounts: z.array(Account), statuses: z.array(Note.schema), hashtags: z.array(z.string()), }), diff --git a/api/inbox/index.ts b/api/inbox/index.ts index 9b466fe1..5256a6bc 100644 --- a/api/inbox/index.ts +++ b/api/inbox/index.ts @@ -1,7 +1,6 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import type { Entity } from "@versia/federation/types"; -import { z } from "zod"; import { InboxJobType, inboxQueue } from "~/classes/queues/inbox"; const schemas = { diff --git a/api/media/:hash/:name/index.ts b/api/media/:hash/:name/index.ts index ec8b9e53..4b1a83c3 100644 --- a/api/media/:hash/:name/index.ts +++ b/api/media/:hash/:name/index.ts @@ -1,6 +1,5 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; -import { z } from "zod"; +import { createRoute, z } from "@hono/zod-openapi"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/media/proxy/:id.ts b/api/media/proxy/:id.ts index 5fe97b00..d2089f03 100644 --- a/api/media/proxy/:id.ts +++ b/api/media/proxy/:id.ts @@ -1,7 +1,6 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import type { ContentfulStatusCode, StatusCode } from "hono/utils/http-status"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; diff --git a/api/messaging/index.ts b/api/messaging/index.ts index e1d2d284..abee0998 100644 --- a/api/messaging/index.ts +++ b/api/messaging/index.ts @@ -1,8 +1,7 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { getLogger } from "@logtape/logtape"; import chalk from "chalk"; -import { z } from "zod"; const route = createRoute({ method: "post", diff --git a/api/objects/:id/index.ts b/api/objects/:id/index.ts index dd6b9030..ce480dab 100644 --- a/api/objects/:id/index.ts +++ b/api/objects/:id/index.ts @@ -1,5 +1,5 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { LikeExtension as LikeSchema, Note as NoteSchema, @@ -7,7 +7,6 @@ import { import { Like, Note, User } from "@versia/kit/db"; import { Likes, Notes } from "@versia/kit/tables"; import { and, eq, inArray, sql } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; import { ErrorSchema, type KnownEntity } from "~/types/api"; diff --git a/api/users/:uuid/inbox/index.ts b/api/users/:uuid/inbox/index.ts index fa003880..9303240d 100644 --- a/api/users/:uuid/inbox/index.ts +++ b/api/users/:uuid/inbox/index.ts @@ -1,7 +1,6 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import type { Entity } from "@versia/federation/types"; -import { z } from "zod"; import { InboxJobType, inboxQueue } from "~/classes/queues/inbox"; import { ErrorSchema } from "~/types/api"; diff --git a/api/users/:uuid/index.ts b/api/users/:uuid/index.ts index ff416cb5..647cccd2 100644 --- a/api/users/:uuid/index.ts +++ b/api/users/:uuid/index.ts @@ -1,8 +1,7 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { User as UserSchema } from "@versia/federation/schemas"; import { User } from "@versia/kit/db"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { ErrorSchema } from "~/types/api"; diff --git a/api/users/:uuid/outbox/index.ts b/api/users/:uuid/outbox/index.ts index 1eeb5cc6..0183e7a0 100644 --- a/api/users/:uuid/outbox/index.ts +++ b/api/users/:uuid/outbox/index.ts @@ -1,5 +1,5 @@ import { apiRoute } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { Collection as CollectionSchema, Note as NoteSchema, @@ -7,7 +7,6 @@ import { import { Note, User, db } from "@versia/kit/db"; import { Notes } from "@versia/kit/tables"; import { and, eq, inArray } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; diff --git a/api/well-known/webfinger/index.ts b/api/well-known/webfinger/index.ts index d7089c91..8cab7a37 100644 --- a/api/well-known/webfinger/index.ts +++ b/api/well-known/webfinger/index.ts @@ -4,14 +4,13 @@ import { parseUserAddress, webfingerMention, } from "@/api"; -import { createRoute } from "@hono/zod-openapi"; +import { createRoute, z } from "@hono/zod-openapi"; import { getLogger } from "@logtape/logtape"; import type { ResponseError } from "@versia/federation"; import { WebFinger } from "@versia/federation/schemas"; import { User } from "@versia/kit/db"; import { Users } from "@versia/kit/tables"; import { and, eq, isNull } from "drizzle-orm"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error"; import { config } from "~/packages/config-manager"; import { ErrorSchema } from "~/types/api"; diff --git a/classes/database/application.ts b/classes/database/application.ts index 945254fa..276c4e25 100644 --- a/classes/database/application.ts +++ b/classes/database/application.ts @@ -1,3 +1,4 @@ +import { z } from "@hono/zod-openapi"; import type { Application as APIApplication } from "@versia/client/types"; import { Token, db } from "@versia/kit/db"; import { Applications } from "@versia/kit/tables"; @@ -9,7 +10,6 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { BaseInterface } from "./base.ts"; type ApplicationType = InferSelectModel; diff --git a/classes/database/emoji.ts b/classes/database/emoji.ts index 08d103d7..4b15a58a 100644 --- a/classes/database/emoji.ts +++ b/classes/database/emoji.ts @@ -1,5 +1,6 @@ import { emojiValidatorWithColons, emojiValidatorWithIdentifiers } from "@/api"; import { proxyUrl } from "@/response"; +import { z } from "@hono/zod-openapi"; import type { Emoji as APIEmoji } from "@versia/client/types"; import type { CustomEmojiExtension } from "@versia/federation/types"; import { type Instance, Media, db } from "@versia/kit/db"; @@ -14,7 +15,6 @@ import { inArray, isNull, } from "drizzle-orm"; -import { z } from "zod"; import { BaseInterface } from "./base.ts"; type EmojiType = InferSelectModel & { diff --git a/classes/database/like.ts b/classes/database/like.ts index a6d5d948..629f26f5 100644 --- a/classes/database/like.ts +++ b/classes/database/like.ts @@ -1,3 +1,4 @@ +import { z } from "@hono/zod-openapi"; import { RolePermission } from "@versia/client/types"; import type { Delete, LikeExtension } from "@versia/federation/types"; import { db } from "@versia/kit/db"; @@ -16,7 +17,6 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; import { BaseInterface } from "./base.ts"; import { Note } from "./note.ts"; diff --git a/classes/database/media.ts b/classes/database/media.ts index b5b44881..06a85903 100644 --- a/classes/database/media.ts +++ b/classes/database/media.ts @@ -1,6 +1,7 @@ import { join } from "node:path"; import { mimeLookup } from "@/content_types.ts"; import { proxyUrl } from "@/response"; +import { z } from "@hono/zod-openapi"; import type { Attachment as ApiAttachment } from "@versia/client/types"; import type { ContentFormat } from "@versia/federation/types"; import { db } from "@versia/kit/db"; @@ -15,7 +16,6 @@ import { inArray, } from "drizzle-orm"; import sharp from "sharp"; -import { z } from "zod"; import { MediaBackendType } from "~/packages/config-manager/config.type"; import { config } from "~/packages/config-manager/index.ts"; import { ApiError } from "../errors/api-error.ts"; diff --git a/classes/database/note.ts b/classes/database/note.ts index 23eb1cf1..70c5188d 100644 --- a/classes/database/note.ts +++ b/classes/database/note.ts @@ -3,6 +3,7 @@ import { localObjectUri } from "@/constants"; import { mergeAndDeduplicate } from "@/lib.ts"; import { sanitizedHtmlStrip } from "@/sanitization"; import { sentry } from "@/sentry"; +import { z } from "@hono/zod-openapi"; import { getLogger } from "@logtape/logtape"; import type { Attachment as ApiAttachment, @@ -35,7 +36,6 @@ import { } from "drizzle-orm"; import { htmlToText } from "html-to-text"; import { createRegExp, exactly, global } from "magic-regexp"; -import { z } from "zod"; import { contentToHtml, findManyNotes, @@ -43,6 +43,7 @@ import { } from "~/classes/functions/status"; import { config } from "~/packages/config-manager"; import { DeliveryJobType, deliveryQueue } from "../queues/delivery.ts"; +import { Account } from "../schemas/account.ts"; import { Application } from "./application.ts"; import { BaseInterface } from "./base.ts"; import { Emoji } from "./emoji.ts"; @@ -84,7 +85,7 @@ export class Note extends BaseInterface { id: z.string().uuid(), uri: z.string().url(), url: z.string().url(), - account: z.lazy(() => User.schema), + account: Account, in_reply_to_id: z.string().uuid().nullable(), in_reply_to_account_id: z.string().uuid().nullable(), reblog: z.lazy(() => Note.schema).nullable(), @@ -162,7 +163,7 @@ export class Note extends BaseInterface { name: z.string(), url: z.string().url().optional(), static_url: z.string().url().optional(), - accounts: z.array(z.lazy(() => User.schema)).optional(), + accounts: z.array(Account).optional(), account_ids: z.array(z.string().uuid()).optional(), }), ), diff --git a/classes/database/notification.ts b/classes/database/notification.ts index ebe3fae9..67effe85 100644 --- a/classes/database/notification.ts +++ b/classes/database/notification.ts @@ -1,3 +1,4 @@ +import { z } from "@hono/zod-openapi"; import type { Notification as APINotification } from "@versia/client/types"; import { Note, User, db } from "@versia/kit/db"; import { Notifications } from "@versia/kit/tables"; @@ -9,12 +10,12 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { transformOutputToUserWithRelations, userExtrasTemplate, userRelations, } from "../functions/user.ts"; +import { Account } from "../schemas/account.ts"; import { BaseInterface } from "./base.ts"; export type NotificationType = InferSelectModel & { @@ -27,7 +28,7 @@ export class Notification extends BaseInterface< NotificationType > { public static schema: z.ZodType = z.object({ - account: z.lazy(() => User.schema).nullable(), + account: Account.nullable(), created_at: z.string(), id: z.string().uuid(), status: z.lazy(() => Note.schema).optional(), @@ -54,7 +55,7 @@ export class Notification extends BaseInterface< "group_favourite", "user_approved", ]), - target: z.lazy(() => User.schema).optional(), + target: Account.optional(), }); public async reload(): Promise { diff --git a/classes/database/reaction.ts b/classes/database/reaction.ts index 8aa2b86f..36992594 100644 --- a/classes/database/reaction.ts +++ b/classes/database/reaction.ts @@ -1,3 +1,4 @@ +import { z } from "@hono/zod-openapi"; import type { Emoji as APIEmoji } from "@versia/client/types"; import type { ReactionExtension } from "@versia/federation/types"; import { Emoji, Instance, Note, User, db } from "@versia/kit/db"; @@ -10,7 +11,6 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; import { BaseInterface } from "./base.ts"; diff --git a/classes/database/relationship.ts b/classes/database/relationship.ts index 5e5e4b8d..1a431346 100644 --- a/classes/database/relationship.ts +++ b/classes/database/relationship.ts @@ -1,3 +1,4 @@ +import { z } from "@hono/zod-openapi"; import type { Relationship as APIRelationship } from "@versia/client/types"; import { db } from "@versia/kit/db"; import { Relationships } from "@versia/kit/tables"; @@ -10,7 +11,6 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { BaseInterface } from "./base.ts"; import type { User } from "./user.ts"; diff --git a/classes/database/role.ts b/classes/database/role.ts index 0f439a6d..46fbb308 100644 --- a/classes/database/role.ts +++ b/classes/database/role.ts @@ -1,4 +1,5 @@ import { proxyUrl } from "@/response"; +import { z } from "@hono/zod-openapi"; import { type VersiaRole as APIRole, RolePermission, @@ -14,7 +15,6 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { config } from "~/packages/config-manager/index.ts"; import { BaseInterface } from "./base.ts"; diff --git a/classes/database/token.ts b/classes/database/token.ts index 25e564c2..a4b433af 100644 --- a/classes/database/token.ts +++ b/classes/database/token.ts @@ -1,3 +1,4 @@ +import { z } from "@hono/zod-openapi"; import type { Token as ApiToken } from "@versia/client/types"; import { type Application, User, db } from "@versia/kit/db"; import { Tokens } from "@versia/kit/tables"; @@ -9,7 +10,6 @@ import { eq, inArray, } from "drizzle-orm"; -import { z } from "zod"; import { BaseInterface } from "./base.ts"; type TokenType = InferSelectModel & { diff --git a/classes/database/user.ts b/classes/database/user.ts index ec4d2557..2f6db3a2 100644 --- a/classes/database/user.ts +++ b/classes/database/user.ts @@ -4,10 +4,7 @@ import { randomString } from "@/math"; import { proxyUrl } from "@/response"; import { sentry } from "@/sentry"; import { getLogger } from "@logtape/logtape"; -import type { - Account as ApiAccount, - Mention as ApiMention, -} from "@versia/client/types"; +import type { Mention as ApiMention } from "@versia/client/types"; import { EntityValidator, FederationRequester, @@ -48,13 +45,14 @@ import { sql, } from "drizzle-orm"; import { htmlToText } from "html-to-text"; -import { z } from "zod"; +import type { z } from "zod"; import { findManyUsers } from "~/classes/functions/user"; import { searchManager } from "~/classes/search/search-manager"; import { type Config, config } from "~/packages/config-manager"; import type { KnownEntity } from "~/types/api.ts"; import { DeliveryJobType, deliveryQueue } from "../queues/delivery.ts"; import { PushJobType, pushQueue } from "../queues/push.ts"; +import type { Account } from "../schemas/account.ts"; import { BaseInterface } from "./base.ts"; import { Emoji } from "./emoji.ts"; import { Instance } from "./instance.ts"; @@ -81,74 +79,6 @@ type UserWithRelations = UserWithInstance & { * Gives helpers to fetch users from database in a nice format */ export class User extends BaseInterface { - // @ts-expect-error Roles are weird - public static schema: z.ZodType = z.object({ - id: z.string(), - username: z.string(), - acct: z.string(), - display_name: z.string(), - locked: z.boolean(), - discoverable: z.boolean().optional(), - group: z.boolean().nullable(), - noindex: z.boolean().nullable(), - suspended: z.boolean().nullable(), - limited: z.boolean().nullable(), - created_at: z.string(), - followers_count: z.number(), - following_count: z.number(), - statuses_count: z.number(), - note: z.string(), - uri: z.string(), - url: z.string(), - avatar: z.string(), - avatar_static: z.string(), - header: z.string(), - header_static: z.string(), - emojis: z.array(Emoji.schema), - fields: z.array( - z.object({ - name: z.string(), - value: z.string(), - verified: z.boolean().optional(), - verified_at: z.string().nullable().optional(), - }), - ), - // FIXME: Use a proper type - moved: z.lazy(() => User.schema).nullable(), - bot: z.boolean().nullable(), - source: z - .object({ - privacy: z.string().nullable(), - sensitive: z.boolean().nullable(), - language: z.string().nullable(), - note: z.string(), - fields: z.array( - z.object({ - name: z.string(), - value: z.string(), - }), - ), - avatar: z - .object({ - content_type: z.string(), - }) - .optional(), - header: z - .object({ - content_type: z.string(), - }) - .optional(), - }) - .optional(), - role: z - .object({ - name: z.string(), - }) - .optional(), - roles: z.array(Role.schema), - mute_expires_at: z.string().optional(), - }); - public static $type: UserWithRelations; public avatar: Media | null; @@ -1175,7 +1105,7 @@ export class User extends BaseInterface { return { ok: true }; } - public toApi(isOwnAccount = false): ApiAccount { + public toApi(isOwnAccount = false): z.infer { const user = this.data; return { id: user.id, @@ -1199,6 +1129,7 @@ export class User extends BaseInterface { fields: user.fields.map((field) => ({ name: htmlToText(getBestContentType(field.key).content), value: getBestContentType(field.value).content, + verified_at: null, })), bot: user.isBot, source: isOwnAccount ? user.source : undefined, @@ -1213,8 +1144,8 @@ export class User extends BaseInterface { moved: null, noindex: false, suspended: false, - discoverable: undefined, - mute_expires_at: undefined, + discoverable: null, + mute_expires_at: null, roles: user.roles .map((role) => new Role(role)) .concat( diff --git a/classes/schemas/account.ts b/classes/schemas/account.ts new file mode 100644 index 00000000..cf5c0b6e --- /dev/null +++ b/classes/schemas/account.ts @@ -0,0 +1,403 @@ +import { z } from "@hono/zod-openapi"; +import type { Account as ApiAccount } from "@versia/client/types"; +import ISO6391 from "iso-639-1"; +import { config } from "~/packages/config-manager"; +import { zBoolean } from "~/packages/config-manager/config.type"; +import { Emoji } from "../database/emoji.ts"; +import { Role } from "../database/role.ts"; + +export const Field = z.object({ + name: z + .string() + .trim() + .min(1) + .max(config.validation.max_field_name_size) + .openapi({ + description: "The key of a given field’s key-value pair.", + example: "Freak level", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#name", + }, + }), + value: z + .string() + .trim() + .min(1) + .max(config.validation.max_field_value_size) + .openapi({ + description: "The value associated with the name key.", + example: "

High

", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#value", + }, + }), + verified_at: z + .string() + .datetime() + .nullable() + .openapi({ + description: + "Timestamp of when the server verified a URL value for a rel=“me” link.", + example: null, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#verified_at", + }, + }), +}); + +export const Source = z + .object({ + privacy: z.enum(["public", "unlisted", "private", "direct"]).openapi({ + description: + "The default post privacy to be used for new statuses.", + example: "unlisted", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#source-privacy", + }, + }), + sensitive: zBoolean.openapi({ + description: + "Whether new statuses should be marked sensitive by default.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#source-sensitive", + }, + }), + language: z + .enum(ISO6391.getAllCodes() as [string, ...string[]]) + .openapi({ + description: "The default posting language for new statuses.", + example: "en", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#source-language", + }, + }), + follow_requests_count: z + .number() + .int() + .optional() + .openapi({ + description: "The number of pending follow requests.", + example: 3, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#follow_requests_count", + }, + }), + note: z + .string() + .trim() + .min(0) + .max(config.validation.max_bio_size) + .refine( + (s) => !config.filters.bio.some((filter) => s.match(filter)), + "Bio contains blocked words", + ) + .openapi({ + description: "Profile bio, in plain-text instead of in HTML.", + example: "ermmm what the meow meow", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#source-note", + }, + }), + fields: z.array(Field).max(config.validation.max_field_count).openapi({ + description: "Metadata about the account.", + }), + }) + .openapi({ + description: + "An extra attribute that contains source values to be used with API methods that verify credentials and update credentials.", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#source", + }, + }); + +export const Account = z.object({ + id: z + .string() + .uuid() + .openapi({ + description: "The account id.", + example: "9e84842b-4db6-4a9b-969d-46ab408278da", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#id", + }, + }), + username: z + .string() + .min(3) + .trim() + .max(config.validation.max_username_size) + .toLowerCase() + .regex( + /^[a-z0-9_-]+$/, + "Username can only contain letters, numbers, underscores and hyphens", + ) + .refine( + (s) => !config.filters.username.some((filter) => s.match(filter)), + "Username contains blocked words", + ) + .openapi({ + description: "The username of the account, not including domain.", + example: "lexi", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#username", + }, + }), + acct: z.string().openapi({ + description: + "The Webfinger account URI. Equal to username for local users, or username@domain for remote users.", + example: "lexi@beta.versia.social", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#acct", + }, + }), + url: z + .string() + .url() + .openapi({ + description: "The location of the user’s profile page.", + example: "https://beta.versia.social/@lexi", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#url", + }, + }), + display_name: z + .string() + .min(3) + .trim() + .max(config.validation.max_displayname_size) + .refine( + (s) => + !config.filters.displayname.some((filter) => s.match(filter)), + "Display name contains blocked words", + ) + .openapi({ + description: "The profile’s display name.", + example: "Lexi :flower:", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#display_name", + }, + }), + note: z + .string() + .min(0) + .max(config.validation.max_bio_size) + .trim() + .refine( + (s) => !config.filters.bio.some((filter) => s.match(filter)), + "Bio contains blocked words", + ) + .openapi({ + description: "The profile’s bio or description.", + example: "

ermmm what the meow meow

", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#note", + }, + }), + avatar: z + .string() + .url() + .openapi({ + description: + "An image icon that is shown next to statuses and in the profile.", + example: + "https://cdn.versia.social/avatars/cff9aea0-0000-43fe-8b5e-e7c7ea69a488/lexi.webp", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#avatar", + }, + }), + avatar_static: z + .string() + .url() + .openapi({ + description: + "A static version of the avatar. Equal to avatar if its value is a static image; different if avatar is an animated GIF.", + example: + "https://cdn.versia.social/avatars/cff9aea0-0000-43fe-8b5e-e7c7ea69a488/lexi.webp", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#avatar_static", + }, + }), + header: z + .string() + .url() + .openapi({ + description: + "An image banner that is shown above the profile and in profile cards.", + example: + "https://cdn.versia.social/headers/a049f8e3-878c-4faa-ae4c-a6bcceddbd9d/femboy_2.webp", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#header", + }, + }), + header_static: z + .string() + .url() + .openapi({ + description: + "A static version of the header. Equal to header if its value is a static image; different if header is an animated GIF.", + example: + "https://cdn.versia.social/headers/a049f8e3-878c-4faa-ae4c-a6bcceddbd9d/femboy_2.webp", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#header_static", + }, + }), + locked: zBoolean.openapi({ + description: "Whether the account manually approves follow requests.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#locked", + }, + }), + fields: z + .array(Field) + .max(config.validation.max_field_count) + .openapi({ + description: + "Additional metadata attached to a profile as name-value pairs.", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#fields", + }, + }), + emojis: z.array(Emoji.schema).openapi({ + description: + "Custom emoji entities to be used when rendering the profile.", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#emojis", + }, + }), + bot: zBoolean.openapi({ + description: + "Indicates that the account may perform automated actions, may not be monitored, or identifies as a robot.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#bot", + }, + }), + group: z.literal(false).openapi({ + description: "Indicates that the account represents a Group actor.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#group", + }, + }), + discoverable: zBoolean.nullable().openapi({ + description: + "Whether the account has opted into discovery features such as the profile directory.", + example: true, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#discoverable", + }, + }), + noindex: zBoolean + .nullable() + .optional() + .openapi({ + description: + "Whether the local user has opted out of being indexed by search engines.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#noindex", + }, + }), + // FIXME: Use a proper type + moved: z + .lazy((): z.ZodType => Account as z.ZodType) + .nullable() + .optional() + .openapi({ + description: + "Indicates that the profile is currently inactive and that its user has moved to a new account.", + example: null, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#moved", + }, + }), + suspended: zBoolean.optional().openapi({ + description: + "An extra attribute returned only when an account is suspended.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#suspended", + }, + }), + limited: zBoolean.optional().openapi({ + description: + "An extra attribute returned only when an account is silenced. If true, indicates that the account should be hidden behind a warning screen.", + example: false, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#limited", + }, + }), + created_at: z + .string() + .datetime() + .openapi({ + description: "When the account was created.", + example: "2024-10-15T22:00:00.000Z", + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#created_at", + }, + }), + // TODO + last_status_at: z + .literal(null) + .openapi({ + description: "When the most recent status was posted.", + example: null, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#last_status_at", + }, + }) + .nullable(), + statuses_count: z + .number() + .min(0) + .int() + .openapi({ + description: "How many statuses are attached to this account.", + example: 42, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#statuses_count", + }, + }), + followers_count: z + .number() + .min(0) + .int() + .openapi({ + description: "The reported followers of this profile.", + example: 6, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#followers_count", + }, + }), + following_count: z + .number() + .min(0) + .int() + .openapi({ + description: "The reported follows of this profile.", + example: 23, + externalDocs: { + url: "https://docs.joinmastodon.org/entities/Account/#following_count", + }, + }), + uri: z.string().url().openapi({ + description: + "The location of the user's Versia profile page, as opposed to the local representation.", + example: + "https://beta.versia.social/users/9e84842b-4db6-4a9b-969d-46ab408278da", + }), + source: Source.optional(), + role: z + .object({ + name: z.string(), + }) + .optional(), + roles: z.array(Role.schema), + mute_expires_at: z.string().datetime().nullable().openapi({ + description: "When a timed mute will expire, if applicable.", + example: "2025-03-01T14:00:00.000Z", + }), +}); diff --git a/packages/config-manager/config.type.ts b/packages/config-manager/config.type.ts index 0818f50c..63b84db4 100644 --- a/packages/config-manager/config.type.ts +++ b/packages/config-manager/config.type.ts @@ -1,10 +1,10 @@ +import { z } from "@hono/zod-openapi"; import { ADMIN_ROLES, DEFAULT_ROLES, RolePermissions, } from "@versia/kit/tables"; import { types as mimeTypes } from "mime-types"; -import { z } from "zod"; export enum MediaBackendType { Local = "local", @@ -26,6 +26,11 @@ const zUrl = z .transform((arg) => arg.replace(/\/$/, "")) .transform((arg) => new URL(arg)); +export const zBoolean = z + .string() + .transform((v) => ["true", "1", "on"].includes(v.toLowerCase())) + .or(z.boolean()); + export const configValidator = z .object({ database: z diff --git a/packages/plugin-kit/example.ts b/packages/plugin-kit/example.ts index 8ebb14cf..92c01b00 100644 --- a/packages/plugin-kit/example.ts +++ b/packages/plugin-kit/example.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "@hono/zod-openapi"; import { Hooks } from "./hooks.ts"; import { Plugin } from "./plugin.ts"; diff --git a/packages/plugin-kit/schema.ts b/packages/plugin-kit/schema.ts index 97288af3..7c04abad 100644 --- a/packages/plugin-kit/schema.ts +++ b/packages/plugin-kit/schema.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "@hono/zod-openapi"; export const manifestSchema = z.object({ // biome-ignore lint/style/useNamingConvention: diff --git a/plugins/openid/index.ts b/plugins/openid/index.ts index 94d4345e..7edcdaf1 100644 --- a/plugins/openid/index.ts +++ b/plugins/openid/index.ts @@ -1,10 +1,10 @@ +import { z } from "@hono/zod-openapi"; import { Hooks, Plugin } from "@versia/kit"; import { User } from "@versia/kit/db"; import chalk from "chalk"; import { getCookie } from "hono/cookie"; import { jwtVerify } from "jose"; import { JOSEError, JWTExpired } from "jose/errors"; -import { z } from "zod"; import { ApiError } from "~/classes/errors/api-error.ts"; import { RolePermissions } from "~/drizzle/schema.ts"; import authorizeRoute from "./routes/authorize.ts"; diff --git a/plugins/openid/routes/authorize.ts b/plugins/openid/routes/authorize.ts index 27dd22e3..b7bf489b 100644 --- a/plugins/openid/routes/authorize.ts +++ b/plugins/openid/routes/authorize.ts @@ -1,10 +1,10 @@ import { auth, jsonOrForm } from "@/api"; import { randomString } from "@/math"; +import { z } from "@hono/zod-openapi"; import { Application, Token, User } from "@versia/kit/db"; import { RolePermissions } from "@versia/kit/tables"; import { type JWTPayload, SignJWT, jwtVerify } from "jose"; import { JOSEError } from "jose/errors"; -import { z } from "zod"; import { errorRedirect, errors } from "../errors.ts"; import type { PluginType } from "../index.ts"; diff --git a/plugins/openid/routes/sso/index.ts b/plugins/openid/routes/sso/index.ts index 67b7b004..544c6652 100644 --- a/plugins/openid/routes/sso/index.ts +++ b/plugins/openid/routes/sso/index.ts @@ -1,11 +1,11 @@ import { auth } from "@/api"; +import { z } from "@hono/zod-openapi"; import { Application, db } from "@versia/kit/db"; import { OpenIdLoginFlows, RolePermissions } from "@versia/kit/tables"; import { calculatePKCECodeChallenge, generateRandomCodeVerifier, } from "oauth4webapi"; -import { z } from "zod"; import { ErrorSchema } from "~/types/api"; import type { PluginType } from "../../index.ts"; import { oauthDiscoveryRequest, oauthRedirectUri } from "../../utils.ts"; diff --git a/types/api.ts b/types/api.ts index 068e1aec..e79cddc6 100644 --- a/types/api.ts +++ b/types/api.ts @@ -1,4 +1,5 @@ import type { OpenAPIHono } from "@hono/zod-openapi"; +import { z } from "@hono/zod-openapi"; import type { Delete, Follow, @@ -12,7 +13,6 @@ import type { } from "@versia/federation/types"; import type { SocketAddress } from "bun"; import type { RouterRoute } from "hono/types"; -import { z } from "zod"; import type { AuthData } from "~/classes/functions/user"; import type { Config } from "~/packages/config-manager"; diff --git a/utils/api.ts b/utils/api.ts index ecf3608f..b9c32805 100644 --- a/utils/api.ts +++ b/utils/api.ts @@ -1,4 +1,5 @@ import type { OpenAPIHono } from "@hono/zod-openapi"; +import { z } from "@hono/zod-openapi"; import { zValidator } from "@hono/zod-validator"; import { getLogger } from "@logtape/logtape"; import { Application, Note, Token, User, db } from "@versia/kit/db"; @@ -24,7 +25,6 @@ import { oneOrMore, } from "magic-regexp"; import { type ParsedQs, parse } from "qs"; -import { z } from "zod"; import { fromZodError } from "zod-validation-error"; import { ApiError } from "~/classes/errors/api-error"; import type { AuthData } from "~/classes/functions/user";