trpcLink.ts2.0 KBView on GitHub import type { TRPCLink } from '@trpc/client';
import { observable } from '@trpc/server/observable';
import type { AnyRouter } from '@trpc/server';
import { push, isCaptureBodies } from './buffer';
import { redact } from './redact';
let opCounter = 0;
function nextRequestId(): string {
opCounter++;
return `req_${Date.now().toString(36)}_${opCounter.toString(36)}`;
}
export function createDeepDebuggerLink<TRouter extends AnyRouter>(): TRPCLink<TRouter> {
return () =>
({ next, op }) =>
observable((observer) => {
const requestId = nextRequestId();
const start = performance.now();
push({
source: 'trpc.request',
path: op.path,
type: op.type,
input: redact(op.input, { captureBodies: isCaptureBodies() }),
requestId,
});
const sub = next(op).subscribe({
next(value) {
push({
source: 'trpc.response',
path: op.path,
type: op.type,
output: redact((value as { result?: { data?: unknown } }).result?.data, { captureBodies: isCaptureBodies() }),
durationMs: performance.now() - start,
requestId,
});
observer.next(value);
},
error(err) {
push({
source: 'trpc.error',
path: op.path,
type: op.type,
error: {
message: err?.message ?? String(err),
code: (err as { data?: { code?: string } })?.data?.code,
data: redact((err as { data?: unknown })?.data, { captureBodies: isCaptureBodies() }),
stack: (err as { stack?: string })?.stack,
},
durationMs: performance.now() - start,
requestId,
});
observer.error(err);
},
complete() {
observer.complete();
},
});
return () => sub.unsubscribe();
});
}