Middleware patterns: auth guard, request timing, error handling.
Middleware patterns: auth guard, request timing, error handling.
Demonstrates: typed middleware context, auth guards, short-circuiting, and wrap-around timing.
Usage
bash
npx tsx examples/middleware.ts deploy production
npx tsx examples/middleware.ts deploy production --verboseSource
ts
/**
* Middleware patterns: auth guard, request timing, error handling.
*
* Demonstrates: typed middleware context, auth guards, short-circuiting, and
* wrap-around timing.
*
* Usage:
* npx tsx examples/middleware.ts deploy production
* npx tsx examples/middleware.ts deploy production --verbose
*/
import { , , , , , } from '@kjanat/dreamcli';
// --- Auth middleware — adds `user` to context ---
interface User {
readonly : string;
readonly : string;
readonly : 'admin' | 'user';
}
async function (): <User | null> {
// In real code, read a token from env/config/keychain and return null when missing.
return { : 'u-1', : 'Alice', : 'admin' };
}
const = <{ : User }>(async ({ }) => {
const = await ();
if (!) {
// Short-circuits the chain — action never runs.
throw new ('Not authenticated', {
: 'AUTH_REQUIRED',
: 'Run `myapp login` first',
: 2,
});
}
return ({ });
});
// --- Timing middleware — wraps the downstream chain ---
const = <{ : number }>(async ({ , }) => {
const = .();
await ({ : });
// Code after `next()` runs after the action completes (onion model).
const = (.() - ).(0);
.(`Completed in ${}ms`);
});
// --- Command using both middlewares ---
const = ('deploy')
.('Deploy to an environment')
.('target', .().('Deploy target'))
.('verbose', .().('v').('Verbose output'))
.()
.()
.(({ , , , }) => {
// ctx.user and ctx.startTime are typed via middleware chain.
.(`[${..}] ${..} deploying ${.}`);
if (.) {
.(`User ID: ${..}`);
.(`Started at: ${..(0)}ms`);
}
});
void ('myapp').().();