autotel
Version:
Write Once, Observe Anywhere
224 lines (220 loc) • 7.05 kB
TypeScript
import { T as TraceContext } from './trace-context-t5X1AP-e.js';
import '@opentelemetry/api';
/**
* Safe baggage propagation with guardrails
*
* Provides type-safe baggage schemas with built-in protection against
* common pitfalls: high-cardinality values, PII leakage, and oversized payloads.
*
* @example Define a custom schema
* ```typescript
* import { createSafeBaggageSchema } from 'autotel/business-baggage';
*
* const OrderBaggage = createSafeBaggageSchema({
* orderId: { type: 'string' },
* customerId: { type: 'string', hash: true }, // Auto-hash for privacy
* priority: { type: 'enum', values: ['low', 'normal', 'high'] },
* });
*
* // Usage in traced function
* OrderBaggage.set(ctx, { orderId: 'ord-123', customerId: 'cust-456', priority: 'high' });
* const { orderId, priority } = OrderBaggage.get(ctx);
* ```
*
* @example Use pre-built BusinessBaggage
* ```typescript
* import { BusinessBaggage } from 'autotel/business-baggage';
*
* BusinessBaggage.set(ctx, { tenantId: 'acme', userId: 'user-123' });
* const { tenantId } = BusinessBaggage.get(ctx);
* ```
*
* @module
*/
/**
* Supported field types in baggage schema
*/
type BaggageFieldType = 'string' | 'number' | 'boolean' | 'enum';
/**
* Field definition in a baggage schema
*/
interface BaggageFieldDefinition {
/** Field type */
type: BaggageFieldType;
/** Maximum length for string values (default: 256) */
maxLength?: number;
/** Hash value before storing (for privacy) */
hash?: boolean;
/** Allowed values for enum type */
values?: readonly string[];
/** Default value if not provided */
defaultValue?: string | number | boolean;
/** Whether field is required */
required?: boolean;
/** Custom validation function */
validate?: (value: unknown) => boolean;
}
/**
* Options for creating a safe baggage schema
*/
interface SafeBaggageOptions {
/** Maximum key length (default: 64) */
maxKeyLength?: number;
/** Maximum value length (default: 256) */
maxValueLength?: number;
/** Maximum total baggage size in bytes (default: 8192) */
maxTotalSize?: number;
/** Prefix for all keys (default: none) */
prefix?: string;
/** Hash high-cardinality values automatically */
hashHighCardinality?: boolean;
/** Detect and redact PII patterns */
redactPII?: boolean;
/** Allowed keys whitelist (others rejected) */
allowedKeys?: string[];
/** Custom error handler */
onError?: (error: BaggageError) => void;
}
/**
* Schema definition type - maps field names to definitions
*/
type BaggageSchemaDefinition = Record<string, BaggageFieldDefinition>;
/**
* Inferred type from schema definition
*/
type InferBaggageType<T extends BaggageSchemaDefinition> = {
[K in keyof T]?: T[K]['type'] extends 'string' ? string : T[K]['type'] extends 'number' ? number : T[K]['type'] extends 'boolean' ? boolean : T[K]['type'] extends 'enum' ? T[K]['values'] extends readonly string[] ? T[K]['values'][number] : string : unknown;
};
/**
* Baggage error details
*/
interface BaggageError {
type: 'validation' | 'size' | 'pii' | 'key_length' | 'value_length';
key: string;
message: string;
value?: unknown;
}
/**
* Safe baggage schema interface
*/
interface SafeBaggageSchema<T extends BaggageSchemaDefinition> {
/**
* Get baggage values from context
*/
get(ctx?: TraceContext): Partial<InferBaggageType<T>>;
/**
* Set baggage values in context
* Returns new context with baggage (for context propagation)
*/
set(ctx: TraceContext | undefined, values: Partial<InferBaggageType<T>>): void;
/**
* Get a single baggage value
*/
getValue<K extends keyof T>(key: K, ctx?: TraceContext): InferBaggageType<T>[K] | undefined;
/**
* Set a single baggage value
*/
setValue<K extends keyof T>(key: K, value: InferBaggageType<T>[K], ctx?: TraceContext): void;
/**
* Clear all schema baggage values
*/
clear(ctx?: TraceContext): void;
/**
* Get all baggage as headers for propagation
*/
toHeaders(ctx?: TraceContext): Record<string, string>;
/**
* Restore baggage from headers
*/
fromHeaders(headers: Record<string, string>, ctx?: TraceContext): void;
}
/**
* Create a safe baggage schema with validation and guardrails
*
* @param schema - Field definitions
* @param options - Safety options
* @returns Type-safe baggage schema
*
* @example
* ```typescript
* const MyBaggage = createSafeBaggageSchema({
* userId: { type: 'string', hash: true },
* region: { type: 'enum', values: ['us', 'eu', 'ap'] },
* debug: { type: 'boolean', defaultValue: false },
* });
* ```
*/
declare function createSafeBaggageSchema<T extends BaggageSchemaDefinition>(schema: T, options?: SafeBaggageOptions): SafeBaggageSchema<T>;
/**
* Pre-built baggage schema for common business context fields
*
* Fields:
* - `tenantId`: Multi-tenant identifier (string, max 64 chars)
* - `userId`: User identifier (hashed for privacy)
* - `correlationId`: Request correlation ID (string)
* - `workflowId`: Workflow/saga instance ID (string)
* - `priority`: Request priority (low, normal, high, critical)
* - `region`: Geographic region (string)
* - `channel`: Request channel (web, mobile, api, internal)
*
* @example
* ```typescript
* import { BusinessBaggage } from 'autotel/business-baggage';
*
* // Set business context at entry point
* BusinessBaggage.set(ctx, {
* tenantId: 'acme-corp',
* userId: 'user-123',
* priority: 'high',
* channel: 'api',
* });
*
* // Access anywhere in the trace
* const { tenantId, priority } = BusinessBaggage.get(ctx);
* ```
*/
declare const BusinessBaggage: SafeBaggageSchema<{
tenantId: {
type: "string";
maxLength: number;
};
userId: {
type: "string";
hash: true;
maxLength: number;
};
correlationId: {
type: "string";
maxLength: number;
};
workflowId: {
type: "string";
maxLength: number;
};
priority: {
type: "enum";
values: readonly ["low", "normal", "high", "critical"];
defaultValue: string;
};
region: {
type: "string";
maxLength: number;
};
channel: {
type: "enum";
values: readonly ["web", "mobile", "api", "internal", "webhook", "scheduled"];
};
}>;
/**
* Type alias for BusinessBaggage values
*/
type BusinessBaggageValues = {
tenantId?: string;
userId?: string;
correlationId?: string;
workflowId?: string;
priority?: 'low' | 'normal' | 'high' | 'critical';
region?: string;
channel?: 'web' | 'mobile' | 'api' | 'internal' | 'webhook' | 'scheduled';
};
export { type BaggageError, type BaggageFieldDefinition, type BaggageFieldType, type BaggageSchemaDefinition, BusinessBaggage, type BusinessBaggageValues, type InferBaggageType, type SafeBaggageOptions, type SafeBaggageSchema, createSafeBaggageSchema };