mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 05:49:16 +01:00
refactor(api): ♻️ Move to Hono for HTTP
This commit is contained in:
parent
2237be3689
commit
826a260e90
155 changed files with 7226 additions and 6077 deletions
108
utils/api.ts
108
utils/api.ts
|
|
@ -1,4 +1,9 @@
|
|||
import { errorResponse } from "@response";
|
||||
import { config } from "config-manager";
|
||||
import type { Context } from "hono";
|
||||
import { createMiddleware } from "hono/factory";
|
||||
import type { BodyData } from "hono/utils/body";
|
||||
import { validator } from "hono/validator";
|
||||
import {
|
||||
anyOf,
|
||||
caseInsensitive,
|
||||
|
|
@ -7,7 +12,18 @@ import {
|
|||
digit,
|
||||
exactly,
|
||||
} from "magic-regexp";
|
||||
import type { APIRouteMetadata, RouteHandler } from "server-handler";
|
||||
import { parse } from "qs";
|
||||
import type {
|
||||
APIRouteExports,
|
||||
APIRouteMetadata,
|
||||
HttpVerb,
|
||||
RouteHandler,
|
||||
} from "server-handler";
|
||||
import type { z } from "zod";
|
||||
import { fromZodError } from "zod-validation-error";
|
||||
import type { Application } from "~database/entities/Application";
|
||||
import { getFromHeader, getFromRequest } from "~database/entities/User";
|
||||
import type { User } from "~packages/database-interface/user";
|
||||
|
||||
export const applyConfig = (routeMeta: APIRouteMetadata) => {
|
||||
const newMeta = routeMeta;
|
||||
|
|
@ -27,7 +43,7 @@ export const apiRoute = <
|
|||
Metadata extends APIRouteMetadata,
|
||||
ZodSchema extends Zod.AnyZodObject,
|
||||
>(
|
||||
routeFunction: RouteHandler<Metadata, ZodSchema>,
|
||||
routeFunction: APIRouteExports["default"],
|
||||
) => {
|
||||
return routeFunction;
|
||||
};
|
||||
|
|
@ -46,3 +62,91 @@ export const idValidator = createRegExp(
|
|||
anyOf(digit, charIn("ABCDEF")).times(12),
|
||||
[caseInsensitive],
|
||||
);
|
||||
|
||||
export const handleZodError = (
|
||||
result:
|
||||
| { success: true; data?: object }
|
||||
| { success: false; error: z.ZodError<z.AnyZodObject>; data?: object },
|
||||
context: Context,
|
||||
) => {
|
||||
if (!result.success) {
|
||||
return errorResponse(fromZodError(result.error).message, 422);
|
||||
}
|
||||
};
|
||||
|
||||
export const auth = (authData: APIRouteMetadata["auth"]) =>
|
||||
validator("header", async (value, context) => {
|
||||
const auth = value.authorization
|
||||
? await getFromHeader(value.authorization)
|
||||
: null;
|
||||
|
||||
const error = errorResponse("Unauthorized", 401);
|
||||
|
||||
if (!auth) {
|
||||
if (authData.required) {
|
||||
return context.json(
|
||||
{
|
||||
error: "Unauthorized",
|
||||
},
|
||||
401,
|
||||
error.headers.toJSON(),
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
authData.requiredOnMethods?.includes(
|
||||
context.req.method as HttpVerb,
|
||||
)
|
||||
) {
|
||||
return context.json(
|
||||
{
|
||||
error: "Unauthorized",
|
||||
},
|
||||
401,
|
||||
error.headers.toJSON(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
user: auth.user as User,
|
||||
token: auth.token as string,
|
||||
application: auth.application as Application | null,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
user: null,
|
||||
token: null,
|
||||
application: null,
|
||||
};
|
||||
});
|
||||
|
||||
export const qs = () => {
|
||||
return createMiddleware(async (context, next) => {
|
||||
const parsed = parse(await context.req.text(), {
|
||||
parseArrays: true,
|
||||
interpretNumericEntities: true,
|
||||
});
|
||||
|
||||
context.req.parseBody = <T extends BodyData = BodyData>() =>
|
||||
Promise.resolve(parsed as T);
|
||||
// @ts-ignore Very bad hack
|
||||
context.req.formData = () => Promise.resolve(parsed);
|
||||
// @ts-ignore I'm so sorry for this
|
||||
context.req.bodyCache.formData = parsed;
|
||||
await next();
|
||||
});
|
||||
};
|
||||
|
||||
export const qsQuery = () => {
|
||||
return createMiddleware(async (context, next) => {
|
||||
const parsed = parse(context.req.query(), {
|
||||
parseArrays: true,
|
||||
interpretNumericEntities: true,
|
||||
});
|
||||
|
||||
// @ts-ignore Very bad hack
|
||||
context.req.query = () => parsed;
|
||||
await next();
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue