ditto/packages/api/DittoRoute.ts
2025-02-17 14:48:10 -06:00

59 lines
1.5 KiB
TypeScript

import { type Context, type ErrorHandler, Hono } from '@hono/hono';
import { HTTPException } from '@hono/hono/http-exception';
import type { HonoOptions } from '@hono/hono/hono-base';
import type { DittoEnv } from './DittoEnv.ts';
/**
* Ditto base route class.
* Ensures that required variables are set for type safety.
*/
export class DittoRoute extends Hono<DittoEnv> {
constructor(opts: HonoOptions<DittoEnv> = {}) {
super(opts);
this.use((c, next) => {
this.setSignal(c);
this.assertVars(c.var);
return next();
});
this.onError(this._errorHandler);
}
private setSignal(c: Context<DittoEnv>): void {
if (!c.var.signal) {
c.set('signal', c.req.raw.signal);
}
}
private assertVars(vars: Partial<DittoEnv['Variables']>): DittoEnv['Variables'] {
if (!vars.db) this.throwMissingVar('db');
if (!vars.conf) this.throwMissingVar('conf');
if (!vars.store) this.throwMissingVar('store');
if (!vars.signal) this.throwMissingVar('signal');
return {
db: vars.db,
conf: vars.conf,
store: vars.store,
signal: vars.signal,
};
}
private throwMissingVar(name: string): never {
throw new HTTPException(500, { message: `Missing required variable: ${name}` });
}
private _errorHandler: ErrorHandler = (error, c) => {
if (error instanceof HTTPException) {
if (error.res) {
return error.res;
} else {
return c.json({ error: error.message }, error.status);
}
}
return c.json({ error: 'Something went wrong' }, 500);
};
}