@dcsv-io/d2-request-context-abstractions
v0.1.2
Published
<!-- Copyright (c) DCSV. Licensed under the Apache License, Version 2.0. -->
Readme
@dcsv-io/d2-request-context-abstractions
IRequestContext interface (extends IAuthContext) + IPropagatedContext
cross-hop subset + PropagatedContextSerializer round-trip helper.
Emitted from contracts/request-context/IRequestContext.spec.json via
the request-context spec (sources committed). Mirrors DcsvIo.D2.Context.Abstractions (.NET).
Install
pnpm add @dcsv-io/d2-request-context-abstractionsPublic API
Generated artifacts (committed to git):
| Export | Source |
| ----------------------------- | -------------------------------------------------------------------- |
| IRequestContext | IRequestContext.g.ts |
| IRequestContextRedactPaths | IRequestContext.g.ts (PII paths from spec redact: true) |
| IPropagatedContext | IPropagatedContext.g.ts (cross-hop subset, propagate: true only) |
| PropagatedContextSerializer | PropagatedContextSerializer.g.ts (serialize + tryDecode) |
Plus all @dcsv-io/d2-auth-context-abstractions exports re-exported transitively.
Codegen workflow
prebuild runs the request-context-emit.ts script before tsc -b, so
pnpm -r build regenerates transparently. The emitter reuses the
emitAuthContext core for the interface + emits the additional propagated
artifacts.
The emitter honors the spec's extends field: when set (as it is for
IRequestContext.spec.json:6 "extends": "DcsvIo.D2.AuthContext.Abstractions.IAuthContext"),
the generated IRequestContext.g.ts declares
export interface IRequestContext extends IAuthContext { ... } and
emits a import type { IAuthContext } from "@dcsv-io/d2-auth-context-abstractions";
line at the top. Consumers see the unified IRequestContext shape as a
single import — IAuthContext properties are inherited transitively.
Dependencies
@dcsv-io/d2-auth-context-abstractions—IAuthContext+ supporting enums.
Usage example
import {
PropagatedContextSerializer,
IRequestContextRedactPaths,
} from "@dcsv-io/d2-request-context-abstractions";
import { setupLogger } from "@dcsv-io/d2-logging";
// Encode envelope for cross-hop propagation.
const envelope = PropagatedContextSerializer.serialize(propagatedCtx);
amqpHeaders["x-d2-context"] = envelope;
// Decode incoming envelope (returns undefined on tamper / oversize).
const decoded = PropagatedContextSerializer.tryDecode(headers["x-d2-context"]);
// Wire PII paths into Pino redaction.
const log = setupLogger({
serviceName: "edge",
redactPaths: [IRequestContextRedactPaths],
});Parity with .NET
Mirrors DcsvIo.D2.Context.Abstractions:
IRequestContext↔ same property set, camelCased.PropagatedContextSerializer↔ 1:1 type-named class withSerialize/Deserialize.IPropagatedContext↔ same propagated subset.
Nullability convention
Canonical nullability rule (same as
@dcsv-io/d2-auth-context-abstractions):IRequestContextextendsIAuthContextand inherits the same spec-drivenT | nullemission for spec-emitted property types (the spec's?suffix on a type entry — e.g."string?"inIRequestContext.spec.json— triggers the| nullemission).
Edge cases
tryDecodeenforces per-fieldmaxLengthcaps from the spec — a forged envelope with any cap exceeded is dropped wholesale (returnsundefined). Propagation is opportunistic, never required.tryDecodetype-checks numeric / boolean fields and rejects on shape mismatch.nullvalues survive serialize → deserialize without becoming the string"null".- Generated files (
*.g.ts) are committed to git.
