mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 05:49:16 +01:00
feat(api): 🏷️ Port Account OpenAPI schemas from Mastodon API docs
This commit is contained in:
parent
76d1ccc859
commit
2aeada4904
95 changed files with 610 additions and 388 deletions
|
|
@ -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<typeof Applications>;
|
||||
|
|
|
|||
|
|
@ -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<typeof Emojis> & {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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<typeof Notes, NoteTypeWithRelations> {
|
|||
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<typeof Notes, NoteTypeWithRelations> {
|
|||
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(),
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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<typeof Notifications> & {
|
||||
|
|
@ -27,7 +28,7 @@ export class Notification extends BaseInterface<
|
|||
NotificationType
|
||||
> {
|
||||
public static schema: z.ZodType<APINotification> = 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<void> {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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<typeof Tokens> & {
|
||||
|
|
|
|||
|
|
@ -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<typeof Users, UserWithRelations> {
|
||||
// @ts-expect-error Roles are weird
|
||||
public static schema: z.ZodType<ApiAccount> = 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<typeof Users, UserWithRelations> {
|
|||
return { ok: true };
|
||||
}
|
||||
|
||||
public toApi(isOwnAccount = false): ApiAccount {
|
||||
public toApi(isOwnAccount = false): z.infer<typeof Account> {
|
||||
const user = this.data;
|
||||
return {
|
||||
id: user.id,
|
||||
|
|
@ -1199,6 +1129,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
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<typeof Users, UserWithRelations> {
|
|||
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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue