diff options
Diffstat (limited to 'src/index.ts')
| -rw-r--r-- | src/index.ts | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..cbc946a --- /dev/null +++ b/src/index.ts @@ -0,0 +1,64 @@ +#!/usr/bin/env node + +import { argv, Either, getEnv, type IEither, HonoProxy } from '@emprespresso/pengueno'; +import { PosthookServer } from './server/index.js'; +import { Storage } from './storage/index.js'; +import { TokenSigner } from './token/index.js'; + +const main = async (_argv = process.argv.slice(2)): Promise<IEither<Error, void>> => { + const argsResult = argv( + ['--port', '--host', '--data-dir', '--token-secret'], + { + '--port': { absent: 9000, present: (port) => parseInt(port) }, + '--host': { absent: '0.0.0.0', present: (host) => host }, + '--data-dir': { absent: './data', present: (dir) => dir }, + '--token-secret': { absent: undefined, present: (secret) => secret }, + }, + _argv, + ); + + return argsResult + .mapRight((args) => ({ + port: args['--port'], + host: args['--host'], + dataDir: args['--data-dir'], + tokenSecret: args['--token-secret'], + })) + .flatMapAsync(async (config) => { + // Initialize storage + const storage = new Storage(config.dataDir); + const initResult = await storage.init(); + + if (initResult.left().present()) { + return Either.left(initResult.left().get()); + } + + // Initialize token signer (use env var or command line arg or generate random) + const envSecret = getEnv('POSTHOOK_TOKEN_SECRET'); + const secret = config.tokenSecret ?? (envSecret.present() ? envSecret.get() : undefined); + const signer = new TokenSigner(secret); + + if (config.tokenSecret === undefined && !envSecret.present()) { + console.log('No token secret provided; generated a random one (will not persist across restarts).'); + console.log('Set POSTHOOK_TOKEN_SECRET or pass --token-secret to use a persistent secret.'); + } + + console.log(`Storage initialized at: ${config.dataDir}`); + console.log(`Starting server on ${config.host}:${config.port}`); + + // Create and start server + const server = new PosthookServer(storage, signer); + const hono = new HonoProxy(server); + + return hono.serve(config.port, config.host); + }); +}; + +if (process.argv[1] === import.meta.filename) { + await main().then((eitherDone) => + eitherDone.mapLeft((err) => { + console.error('error:', err); + process.exit(1); + }), + ); +} |
