next-axiom
Version:
Send WebVitals from your Next.js project to Axiom.
49 lines (41 loc) • 1.47 kB
text/typescript
import { initTRPC } from '@trpc/server';
import { type NextRequest } from 'next/server';
import { type AxiomRequest, Logger } from 'next-axiom';
import { type createTRPCContext } from './trpc';
export type NextAxiomTRPCMiddlewareCtx = {
/**
* We are passing the entire req object. This means:
* - we have access to it in the procedure
* - because it's typed as NextRequest, the logger will be visible to TS at `ctx.log` but not on `ctx.res`
*/
req: NextRequest;
/**
* Anything you want to stick on all logs that are sent throughout the duration of the current procedure
* This is currently not optional, but can pass an empty object.
*/
axiomTRPCMeta: Record<string, unknown>;
};
function isAxiomRequest(req: unknown): req is AxiomRequest {
return (req as NextRequest & { log: Logger }).log instanceof Logger;
}
export function createAxiomPlugin() {
const t = initTRPC
.context<typeof createTRPCContext>()
// Add meta if required
// .meta<{}>()
.create();
return {
axiomProcedure: t.procedure.use((opts) => {
const req = opts.ctx.req;
if (!isAxiomRequest(req)) {
throw new Error(
'`nextAxiomTRPCMiddleware` could not find logger. Did you forget to wrap your route handler in `withAxiom`? See: TODO: link to docs',
);
}
const log = req.log.with({ axiomTRPCMeta: opts.ctx.axiomTRPCMeta });
return opts.next({
ctx: { log },
});
}),
};
}