refactor(api): 🏷️ Use more new schemas

This commit is contained in:
Jesse Wierzbinski 2025-02-12 23:33:07 +01:00
parent bff1c5f734
commit a0ce18337a
No known key found for this signature in database
6 changed files with 27 additions and 45 deletions

View file

@ -1,30 +1,16 @@
import { apiRoute, auth } from "@/api"; import { apiRoute, auth } from "@/api";
import { createRoute, z } 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 { db } from "@versia/kit/db";
import { Markers, RolePermissions } from "@versia/kit/tables"; import { Markers, RolePermissions } from "@versia/kit/tables";
import { type SQL, and, eq } from "drizzle-orm"; import { type SQL, and, eq } from "drizzle-orm";
import { Marker as MarkerSchema } from "~/classes/schemas/marker";
import { Notification as NotificationSchema } from "~/classes/schemas/notification";
import { Status as StatusSchema } from "~/classes/schemas/status";
const schemas = { const MarkerResponseSchema = z.object({
markers: z.object({ notifications: MarkerSchema.optional(),
home: z home: MarkerSchema.optional(),
.object({ });
last_read_id: z.string().uuid(),
version: z.number(),
updated_at: z.string(),
})
.nullable()
.optional(),
notifications: z
.object({
last_read_id: z.string().uuid(),
version: z.number(),
updated_at: z.string(),
})
.nullable()
.optional(),
}),
};
const routeGet = createRoute({ const routeGet = createRoute({
method: "get", method: "get",
@ -50,7 +36,7 @@ const routeGet = createRoute({
description: "Markers", description: "Markers",
content: { content: {
"application/json": { "application/json": {
schema: schemas.markers, schema: MarkerResponseSchema,
}, },
}, },
}, },
@ -69,8 +55,9 @@ const routePost = createRoute({
] as const, ] as const,
request: { request: {
query: z.object({ query: z.object({
"home[last_read_id]": z.string().uuid().optional(), "home[last_read_id]": StatusSchema.shape.id.optional(),
"notifications[last_read_id]": z.string().uuid().optional(), "notifications[last_read_id]":
NotificationSchema.shape.id.optional(),
}), }),
}, },
responses: { responses: {
@ -78,7 +65,7 @@ const routePost = createRoute({
description: "Markers", description: "Markers",
content: { content: {
"application/json": { "application/json": {
schema: schemas.markers, schema: MarkerResponseSchema,
}, },
}, },
}, },
@ -96,7 +83,7 @@ export default apiRoute((app) => {
return context.json({}, 200); return context.json({}, 200);
} }
const markers: ApiMarker = { const markers: z.infer<typeof MarkerResponseSchema> = {
home: undefined, home: undefined,
notifications: undefined, notifications: undefined,
}; };
@ -160,7 +147,7 @@ export default apiRoute((app) => {
} = context.req.valid("query"); } = context.req.valid("query");
const { user } = context.get("auth"); const { user } = context.get("auth");
const markers: ApiMarker = { const markers: z.infer<typeof MarkerResponseSchema> = {
home: undefined, home: undefined,
notifications: undefined, notifications: undefined,
}; };

View file

@ -829,6 +829,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
pinned: data.pinned, pinned: data.pinned,
// TODO: Add polls // TODO: Add polls
poll: null, poll: null,
// @ts-expect-error broken recursive types
reblog: data.reblog reblog: data.reblog
? await new Note(data.reblog as NoteTypeWithRelations).toApi( ? await new Note(data.reblog as NoteTypeWithRelations).toApi(
userFetching, userFetching,
@ -844,6 +845,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
visibility: data.visibility, visibility: data.visibility,
url: data.uri || this.getMastoUri().toString(), url: data.uri || this.getMastoUri().toString(),
bookmarked: false, bookmarked: false,
// @ts-expect-error broken recursive types
quote: data.quotingId quote: data.quotingId
? ((await Note.fromId(data.quotingId, userFetching?.id).then( ? ((await Note.fromId(data.quotingId, userFetching?.id).then(
(n) => n?.toApi(userFetching), (n) => n?.toApi(userFetching),

View file

@ -1,7 +1,4 @@
import type { import type { z } from "@hono/zod-openapi";
Alerts,
PushSubscription as ApiPushSubscription,
} from "@versia/client/types";
import { type Token, type User, db } from "@versia/kit/db"; import { type Token, type User, db } from "@versia/kit/db";
import { PushSubscriptions, Tokens } from "@versia/kit/tables"; import { PushSubscriptions, Tokens } from "@versia/kit/tables";
import { import {
@ -12,6 +9,7 @@ import {
eq, eq,
inArray, inArray,
} from "drizzle-orm"; } from "drizzle-orm";
import type { WebPushSubscription as WebPushSubscriptionSchema } from "../schemas/pushsubscription.ts";
import { BaseInterface } from "./base.ts"; import { BaseInterface } from "./base.ts";
type PushSubscriptionType = InferSelectModel<typeof PushSubscriptions>; type PushSubscriptionType = InferSelectModel<typeof PushSubscriptions>;
@ -165,7 +163,7 @@ export class PushSubscription extends BaseInterface<
return this.data.id; return this.data.id;
} }
public getAlerts(): Alerts { public getAlerts(): z.infer<typeof WebPushSubscriptionSchema.shape.alerts> {
return { return {
mention: this.data.alerts.mention ?? false, mention: this.data.alerts.mention ?? false,
favourite: this.data.alerts.favourite ?? false, favourite: this.data.alerts.favourite ?? false,
@ -180,7 +178,7 @@ export class PushSubscription extends BaseInterface<
}; };
} }
public toApi(): ApiPushSubscription { public toApi(): z.infer<typeof WebPushSubscriptionSchema> {
return { return {
id: this.data.id, id: this.data.id,
alerts: this.getAlerts(), alerts: this.getAlerts(),

View file

@ -1,5 +1,4 @@
import { z } from "@hono/zod-openapi"; import type { z } from "@hono/zod-openapi";
import type { Token as ApiToken } from "@versia/client/types";
import { type Application, User, db } from "@versia/kit/db"; import { type Application, User, db } from "@versia/kit/db";
import { Tokens } from "@versia/kit/tables"; import { Tokens } from "@versia/kit/tables";
import { import {
@ -10,6 +9,7 @@ import {
eq, eq,
inArray, inArray,
} from "drizzle-orm"; } from "drizzle-orm";
import type { Token as TokenSchema } from "../schemas/token.ts";
import { BaseInterface } from "./base.ts"; import { BaseInterface } from "./base.ts";
type TokenType = InferSelectModel<typeof Tokens> & { type TokenType = InferSelectModel<typeof Tokens> & {
@ -17,13 +17,6 @@ type TokenType = InferSelectModel<typeof Tokens> & {
}; };
export class Token extends BaseInterface<typeof Tokens, TokenType> { export class Token extends BaseInterface<typeof Tokens, TokenType> {
public static schema: z.ZodType<ApiToken> = z.object({
access_token: z.string(),
token_type: z.enum(["bearer"]),
scope: z.string(),
created_at: z.number(),
});
public static $type: TokenType; public static $type: TokenType;
public async reload(): Promise<void> { public async reload(): Promise<void> {
@ -160,7 +153,7 @@ export class Token extends BaseInterface<typeof Tokens, TokenType> {
return await User.fromId(this.data.userId); return await User.fromId(this.data.userId);
} }
public toApi(): ApiToken { public toApi(): z.infer<typeof TokenSchema> {
return { return {
access_token: this.data.accessToken, access_token: this.data.accessToken,
token_type: "Bearer", token_type: "Bearer",

View file

@ -5,7 +5,6 @@ import { proxyUrl } from "@/response";
import { sentry } from "@/sentry"; import { sentry } from "@/sentry";
import type { z } from "@hono/zod-openapi"; import type { z } from "@hono/zod-openapi";
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import type { Mention as ApiMention } from "@versia/client/types";
import { import {
EntityValidator, EntityValidator,
FederationRequester, FederationRequester,
@ -53,6 +52,7 @@ import type { KnownEntity } from "~/types/api.ts";
import { DeliveryJobType, deliveryQueue } from "../queues/delivery.ts"; import { DeliveryJobType, deliveryQueue } from "../queues/delivery.ts";
import { PushJobType, pushQueue } from "../queues/push.ts"; import { PushJobType, pushQueue } from "../queues/push.ts";
import type { Account, Source } from "../schemas/account.ts"; import type { Account, Source } from "../schemas/account.ts";
import type { Mention as MentionSchema } from "../schemas/status.ts";
import { BaseInterface } from "./base.ts"; import { BaseInterface } from "./base.ts";
import { Emoji } from "./emoji.ts"; import { Emoji } from "./emoji.ts";
import { Instance } from "./instance.ts"; import { Instance } from "./instance.ts";
@ -1260,7 +1260,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
}; };
} }
public toMention(): ApiMention { public toMention(): z.infer<typeof MentionSchema> {
return { return {
url: this.getUri().toString(), url: this.getUri().toString(),
username: this.data.username, username: this.data.username,

View file

@ -102,6 +102,7 @@ export const Status = z.object({
}, },
}), }),
reblog: z reblog: z
// @ts-expect-error broken recursive types
.lazy((): z.ZodType<ApiNote> => Status as z.ZodType<ApiNote>) .lazy((): z.ZodType<ApiNote> => Status as z.ZodType<ApiNote>)
.nullable() .nullable()
.openapi({ .openapi({
@ -308,6 +309,7 @@ export const Status = z.object({
}), }),
reactions: z.array(NoteReaction).openapi({}), reactions: z.array(NoteReaction).openapi({}),
quote: z quote: z
// @ts-expect-error broken recursive types
.lazy((): z.ZodType<ApiNote> => Status as z.ZodType<ApiNote>) .lazy((): z.ZodType<ApiNote> => Status as z.ZodType<ApiNote>)
.nullable(), .nullable(),
bookmarked: zBoolean.optional().openapi({ bookmarked: zBoolean.optional().openapi({