From 665be0c1b2e7d0364f78f6b0d7b87ef31c413a91 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 15 Feb 2025 17:46:40 -0600 Subject: [PATCH] Add @ditto/api package with conf middleware --- deno.json | 1 + packages/api/deno.json | 7 ++++++ packages/api/middleware/confMw.test.ts | 19 ++++++++++++++++ packages/api/middleware/confMw.ts | 15 +++++++++++++ .../api/middleware/confRequiredMw.test.ts | 22 +++++++++++++++++++ packages/api/middleware/confRequiredMw.ts | 15 +++++++++++++ packages/api/middleware/mod.ts | 2 ++ 7 files changed, 81 insertions(+) create mode 100644 packages/api/deno.json create mode 100644 packages/api/middleware/confMw.test.ts create mode 100644 packages/api/middleware/confMw.ts create mode 100644 packages/api/middleware/confRequiredMw.test.ts create mode 100644 packages/api/middleware/confRequiredMw.ts create mode 100644 packages/api/middleware/mod.ts diff --git a/deno.json b/deno.json index 1a12f40e..2c7392ce 100644 --- a/deno.json +++ b/deno.json @@ -1,5 +1,6 @@ { "workspace": [ + "./packages/api", "./packages/config", "./packages/ditto" ], diff --git a/packages/api/deno.json b/packages/api/deno.json new file mode 100644 index 00000000..a8bbb3f5 --- /dev/null +++ b/packages/api/deno.json @@ -0,0 +1,7 @@ +{ + "name": "@ditto/api", + "version": "1.1.0", + "exports": { + "./middleware": "./middleware/mod.ts" + } +} diff --git a/packages/api/middleware/confMw.test.ts b/packages/api/middleware/confMw.test.ts new file mode 100644 index 00000000..5eac707c --- /dev/null +++ b/packages/api/middleware/confMw.test.ts @@ -0,0 +1,19 @@ +import { Hono } from '@hono/hono'; +import { assertEquals } from '@std/assert'; + +import { confMw } from './confMw.ts'; + +Deno.test('confMw', async () => { + const env = new Map([ + ['DITTO_NSEC', 'nsec19shyxpuzd0cq2p5078fwnws7tyykypud6z205fzhlmlrs2vpz6hs83zwkw'], + ]); + + const app = new Hono(); + + app.get('/', confMw(env), (c) => c.text(c.var.conf.pubkey)); + + const response = await app.request('/'); + const body = await response.text(); + + assertEquals(body, '1ba0c5ed1bbbf3b7eb0d7843ba16836a0201ea68a76bafcba507358c45911ff6'); +}); diff --git a/packages/api/middleware/confMw.ts b/packages/api/middleware/confMw.ts new file mode 100644 index 00000000..ae53ab72 --- /dev/null +++ b/packages/api/middleware/confMw.ts @@ -0,0 +1,15 @@ +import { DittoConfig } from '@ditto/config'; + +import type { MiddlewareHandler } from '@hono/hono'; + +/** Set Ditto config. */ +export function confMw( + env: { get(key: string): string | undefined }, +): MiddlewareHandler<{ Variables: { conf: DittoConfig } }> { + const conf = new DittoConfig(env); + + return async (c, next) => { + c.set('conf', conf); + await next(); + }; +} diff --git a/packages/api/middleware/confRequiredMw.test.ts b/packages/api/middleware/confRequiredMw.test.ts new file mode 100644 index 00000000..9dfcc096 --- /dev/null +++ b/packages/api/middleware/confRequiredMw.test.ts @@ -0,0 +1,22 @@ +import { Hono } from '@hono/hono'; +import { assertEquals } from '@std/assert'; + +import { confMw } from './confMw.ts'; +import { confRequiredMw } from './confRequiredMw.ts'; + +Deno.test('confRequiredMw', async (t) => { + const app = new Hono(); + + app.get('/without', confRequiredMw, (c) => c.text('ok')); + app.get('/with', confMw(new Map()), confRequiredMw, (c) => c.text('ok')); + + await t.step('without conf returns 500', async () => { + const response = await app.request('/without'); + assertEquals(response.status, 500); + }); + + await t.step('with conf returns 200', async () => { + const response = await app.request('/with'); + assertEquals(response.status, 200); + }); +}); diff --git a/packages/api/middleware/confRequiredMw.ts b/packages/api/middleware/confRequiredMw.ts new file mode 100644 index 00000000..129734b4 --- /dev/null +++ b/packages/api/middleware/confRequiredMw.ts @@ -0,0 +1,15 @@ +import { HTTPException } from '@hono/hono/http-exception'; + +import type { DittoConfig } from '@ditto/config'; +import type { MiddlewareHandler } from '@hono/hono'; + +/** Throws an error if conf isn't set. */ +export const confRequiredMw: MiddlewareHandler<{ Variables: { conf: DittoConfig } }> = async (c, next) => { + const { conf } = c.var; + + if (!conf) { + throw new HTTPException(500, { message: 'Ditto config not set in request.' }); + } + + await next(); +}; diff --git a/packages/api/middleware/mod.ts b/packages/api/middleware/mod.ts new file mode 100644 index 00000000..54a1b35c --- /dev/null +++ b/packages/api/middleware/mod.ts @@ -0,0 +1,2 @@ +export { confMw } from './confMw.ts'; +export { confRequiredMw } from './confRequiredMw.ts';