@burdenoff/be-sdk 2026.518.3 → 2026.521.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EventQueueFactory-PVXBZCT5.js +6 -0
- package/dist/{EventQueueFactory-6UJ3UIP4.js.map → EventQueueFactory-PVXBZCT5.js.map} +1 -1
- package/dist/auth/index.js +2 -2
- package/dist/cache/index.js +1 -1
- package/dist/{chunk-EZOXXSD4.js → chunk-2BG75H2K.js} +4 -4
- package/dist/{chunk-EZOXXSD4.js.map → chunk-2BG75H2K.js.map} +1 -1
- package/dist/{chunk-UNPJMENC.js → chunk-7NUQXGA7.js} +3 -3
- package/dist/{chunk-UNPJMENC.js.map → chunk-7NUQXGA7.js.map} +1 -1
- package/dist/{chunk-KTPFSXZF.js → chunk-ACYGOENW.js} +2 -2
- package/dist/{chunk-KTPFSXZF.js.map → chunk-ACYGOENW.js.map} +1 -1
- package/dist/{chunk-MOCUBSTW.js → chunk-B7I4TABG.js} +2 -2
- package/dist/{chunk-MOCUBSTW.js.map → chunk-B7I4TABG.js.map} +1 -1
- package/dist/{chunk-O2MEBPDT.js → chunk-BNJFEOGH.js} +2 -2
- package/dist/chunk-BNJFEOGH.js.map +1 -0
- package/dist/{chunk-S5S6OBS6.js → chunk-BRYRHBAC.js} +3 -3
- package/dist/{chunk-S5S6OBS6.js.map → chunk-BRYRHBAC.js.map} +1 -1
- package/dist/{chunk-UBXFIIAW.js → chunk-BTQREMD4.js} +2 -2
- package/dist/{chunk-UBXFIIAW.js.map → chunk-BTQREMD4.js.map} +1 -1
- package/dist/{chunk-3F4SLVRL.js → chunk-DMPS4Y53.js} +3 -3
- package/dist/{chunk-3F4SLVRL.js.map → chunk-DMPS4Y53.js.map} +1 -1
- package/dist/{chunk-SNEOLWXT.js → chunk-E5USZ2MR.js} +2 -2
- package/dist/{chunk-SNEOLWXT.js.map → chunk-E5USZ2MR.js.map} +1 -1
- package/dist/{chunk-TM5RQ6P2.js → chunk-KGCISIBX.js} +22 -4
- package/dist/chunk-KGCISIBX.js.map +1 -0
- package/dist/{chunk-OJDXWHRJ.js → chunk-LD7ETTWG.js} +8 -7
- package/dist/chunk-LD7ETTWG.js.map +1 -0
- package/dist/{chunk-MVHOP4IG.js → chunk-MHNA7IS7.js} +2 -2
- package/dist/{chunk-MVHOP4IG.js.map → chunk-MHNA7IS7.js.map} +1 -1
- package/dist/{chunk-V2VEENJ2.js → chunk-PDSV3TFO.js} +3 -3
- package/dist/chunk-PDSV3TFO.js.map +1 -0
- package/dist/{chunk-5FJZI7VX.js → chunk-PPIDJP2W.js} +3 -3
- package/dist/chunk-PPIDJP2W.js.map +1 -0
- package/dist/{chunk-SO57HNXV.js → chunk-QRWTLPW5.js} +13 -7
- package/dist/chunk-QRWTLPW5.js.map +1 -0
- package/dist/{chunk-VLEOOG2L.js → chunk-SVONGBQR.js} +3 -3
- package/dist/{chunk-VLEOOG2L.js.map → chunk-SVONGBQR.js.map} +1 -1
- package/dist/{chunk-BESBOSX2.js → chunk-TGTJ653K.js} +4 -4
- package/dist/chunk-TGTJ653K.js.map +1 -0
- package/dist/{chunk-WCBKW3CL.js → chunk-X4GSV6NV.js} +5 -5
- package/dist/{chunk-WCBKW3CL.js.map → chunk-X4GSV6NV.js.map} +1 -1
- package/dist/{chunk-RRFNSBDZ.js → chunk-X4NELQLV.js} +3 -3
- package/dist/chunk-X4NELQLV.js.map +1 -0
- package/dist/event-queue/index.js +4 -4
- package/dist/export/index.js +3 -3
- package/dist/gateway/index.js +2 -2
- package/dist/gateway/security/index.js +1 -1
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/index.js +5 -5
- package/dist/graphql/index.js +2 -2
- package/dist/{index-CygU_fXS.d.ts → index-Cz9_vPi7.d.ts} +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +22 -22
- package/dist/index.js.map +1 -1
- package/dist/init/index.js +3 -3
- package/dist/instrumentation/index.js +1 -1
- package/dist/metrics/index.js.map +1 -1
- package/dist/pino-logger-NVZXQPWO.js +5 -0
- package/dist/{pino-logger-RYLGXPHZ.js.map → pino-logger-NVZXQPWO.js.map} +1 -1
- package/dist/prisma/index.js +4 -4
- package/dist/rbac/index.js +1 -1
- package/dist/{sdk-THO3IWEE.js → sdk-UWFH5PY7.js} +2 -2
- package/dist/{sdk-THO3IWEE.js.map → sdk-UWFH5PY7.js.map} +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.js.map +1 -1
- package/dist/telemetry/index.js +5 -5
- package/dist/telemetry/index.js.map +1 -1
- package/dist/tracker/index.js +2 -2
- package/dist/utils/index.js +1 -1
- package/dist/workspace-guard-524GBJQ6.js +5 -0
- package/dist/{workspace-guard-LHBNK4TG.js.map → workspace-guard-524GBJQ6.js.map} +1 -1
- package/package.json +1 -1
- package/dist/EventQueueFactory-6UJ3UIP4.js +0 -6
- package/dist/chunk-5FJZI7VX.js.map +0 -1
- package/dist/chunk-BESBOSX2.js.map +0 -1
- package/dist/chunk-O2MEBPDT.js.map +0 -1
- package/dist/chunk-OJDXWHRJ.js.map +0 -1
- package/dist/chunk-RRFNSBDZ.js.map +0 -1
- package/dist/chunk-SO57HNXV.js.map +0 -1
- package/dist/chunk-TM5RQ6P2.js.map +0 -1
- package/dist/chunk-V2VEENJ2.js.map +0 -1
- package/dist/pino-logger-RYLGXPHZ.js +0 -5
- package/dist/workspace-guard-LHBNK4TG.js +0 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gateway/index.ts","../src/gateway/service-jwt.ts","../src/gateway/types.ts","../src/gateway/client.ts"],"names":["SIGNING_ENV_VAR","KEY_ID","DEFAULT_TTL_SECONDS","REFRESH_BEFORE_EXP_MS","joseModule","getJose","cache","Map","cacheKey","actorId","ttlSeconds","signServiceJwt","secret","process","env","key","cached","get","expiresAtMs","Date","now","token","joseLib","encoder","TextEncoder","keyBytes","encode","nowSec","Math","floor","expSec","SignJWT","actor_type","setProtectedHeader","alg","typ","kid","setSubject","setIssuer","setIssuedAt","setExpirationTime","sign","set","CircuitState","GatewayErrorType","GatewayError","Error","type","gatewayUrl","statusCode","graphqlErrors","cause","message","options","name","Object","setPrototypeOf","prototype","uuidv4","crypto","randomUUID","hasAuthorizationHeader","headers","keys","toLowerCase","resolveBypassPermissionValue","normalizedToken","trim","CircuitBreaker","state","CLOSED","failures","successes","consecutiveFailures","lastFailureTime","lastSuccessTime","openedAt","failureTimestamps","config","getState","checkStateTransition","recordSuccess","HALF_OPEN","logger","info","recordFailure","push","windowStart","failureWindow","filter","t","length","failureThreshold","OPEN","warn","threshold","allowRequest","forceOpen","forceClose","getStats","elapsed","resetTimeout","GatewayClient","layerManager","internalCircuitBreaker","crossLayerCircuitBreaker","retryConfig","defaultHeaders","timeout","enableLogging","LayerManager","layer","serviceName","serviceIdentity","internalGatewayUrl","crossLayerGatewayUrl","cbConfig","DEFAULT_CIRCUIT_BREAKER_CONFIG","circuitBreaker","DEFAULT_GATEWAY_RETRY_CONFIG","retry","getServiceIdentity","debug","internalUrl","getInternalUrl","crossLayerUrl","getCrossLayerUrl","getInternalGatewayUrl","getCrossLayerGatewayUrl","internalQuery","context","createRequestContext","executeWithRetry","bypassPermission","crossLayerQuery","query","getInternalCircuitBreaker","getCrossLayerCircuitBreaker","getHealthStatus","internal","url","circuitState","stats","crossLayer","updateDefaultHeaders","callType","requestId","workspaceId","startTime","shouldRetryError","error","GRAPHQL_ERROR","CIRCUIT_OPEN","calculateRetryDelay","attempt","min","initialDelay","pow","backoffMultiplier","maxDelay","logRetryAttempt","maxAttempts","delay","settings","skipCircuitBreaker","skipRetry","lastError","result","executeRequest","String","sleep","UNKNOWN_ERROR","buildRequestHeaders","value","entries","undefined","toString","handleGraphQLErrors","duration","errors","errorMessages","map","e","join","handleFetchError","TIMEOUT_ERROR","NETWORK_ERROR","serviceActorId","serviceJwt","body","JSON","stringify","variables","operationName","controller","AbortController","timeoutId","setTimeout","abort","response","fetch","method","signal","clearTimeout","ok","status","statusText","json","hasData","data","ms","Promise","resolve","createGatewayClient","createGatewayClientFromEnv"],"mappings":"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","file":"chunk-3F4SLVRL.js","sourcesContent":["/**\n * Gateway Module\n *\n * Provides unified gateway client for layer-aware M2M communication\n * with circuit breaker and retry logic.\n *\n * @module gateway\n * @category Gateway\n *\n * @example\n * ```typescript\n * import { GatewayClient, createGatewayClientFromEnv } from '@burdenoff/be-sdk/gateway';\n *\n * // Create from environment variables\n * const client = createGatewayClientFromEnv();\n *\n * // Or create manually\n * const client = new GatewayClient({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Internal call (same layer, uses int-gateway with bypass)\n * const internalResult = await client.internalQuery({\n * query: `query { getTag(id: \"123\") { id name } }`,\n * });\n *\n * // Cross-layer call (via public gateway)\n * const crossLayerResult = await client.crossLayerQuery({\n * query: `query { getCurrentUser { id email } }`,\n * });\n * ```\n */\n\n// Client exports\nexport { GatewayClient, createGatewayClient, createGatewayClientFromEnv } from './client.js';\n\n// Type exports\nexport {\n CircuitState,\n GatewayErrorType,\n GatewayError,\n type GatewayClientConfig,\n type GraphQLRequestOptions,\n type GraphQLResponse,\n type GraphQLError,\n type IGatewayClient,\n type ICircuitBreaker,\n type CircuitBreakerStats,\n type GatewayClientHealth,\n type RequestContext,\n} from './types.js';\n\n// Gateway-side security plugin stack (for public gateways).\n// Imported by consumers as `@burdenoff/be-sdk/gateway/security` — this\n// re-export lets `@burdenoff/be-sdk/gateway` also resolve the namespace.\nexport * as Security from './security/index.js';\n","/**\n * Service JWT minting + caching for M2M cross-layer calls.\n *\n * The public gateways (global-public-gateway, wspace-public-gateway) validate\n * every incoming request's Authorization header and only propagate `x-actor-*`\n * context headers to subgraphs when the JWT is valid. Without a JWT, raw\n * actor headers are stripped as potential client spoofing. For service-to-\n * service cross-layer calls there is no user JWT to forward — we mint a short-\n * lived service JWT with `actor_type: 'service'` so the gateway admits the\n * call and the subgraph sees a trusted service context.\n *\n * Signing key: SERVICE_JWT_SECRET — a dedicated, separate secret from\n * GLOBAL_AUTH_SECRET (which signs user tokens). Keeping them distinct means a\n * service minter that leaks its env cannot forge user logins. The gateways\n * hold both secrets and pick between them by the JWT's `kid` header\n * (this minter stamps `kid: service-v1`).\n */\nimport type * as jose from 'jose';\n\n/**\n * Dedicated secret for service-minted JWTs.\n *\n * Deliberately separate from `GLOBAL_AUTH_SECRET` (which signs user tokens)\n * so that services that mint service JWTs do not also hold the ability to\n * forge user logins. Blast radius of a leaked secret stays scoped to 60s\n * service tokens with no PII.\n *\n * Gateways hold both secrets and select by the JWT's `kid` header.\n */\nconst SIGNING_ENV_VAR = 'SERVICE_JWT_SECRET';\nconst KEY_ID = 'service-v1';\nconst DEFAULT_TTL_SECONDS = 60;\nconst REFRESH_BEFORE_EXP_MS = 10_000;\n\nlet joseModule: typeof jose | null = null;\n\nasync function getJose(): Promise<typeof jose> {\n if (!joseModule) {\n joseModule = await import('jose');\n }\n return joseModule;\n}\n\ninterface CachedToken {\n token: string;\n expiresAtMs: number;\n}\n\nconst cache = new Map<string, CachedToken>();\n\nfunction cacheKey(actorId: string, ttlSeconds: number): string {\n return `${actorId}:${ttlSeconds}`;\n}\n\n/**\n * Sign a service-actor JWT.\n * Returns null when no signing secret is configured (opt-in).\n */\nexport async function signServiceJwt(\n actorId: string,\n ttlSeconds: number = DEFAULT_TTL_SECONDS\n): Promise<string | null> {\n const secret = process.env[SIGNING_ENV_VAR];\n if (!secret) {\n return null;\n }\n\n const key = cacheKey(actorId, ttlSeconds);\n const cached = cache.get(key);\n if (cached && cached.expiresAtMs - REFRESH_BEFORE_EXP_MS > Date.now()) {\n return cached.token;\n }\n\n const joseLib = await getJose();\n const encoder = new TextEncoder();\n const keyBytes = encoder.encode(secret);\n\n const nowSec = Math.floor(Date.now() / 1000);\n const expSec = nowSec + ttlSeconds;\n\n const token = await new joseLib.SignJWT({\n actor_type: 'service',\n })\n .setProtectedHeader({ alg: 'HS256', typ: 'JWT', kid: KEY_ID })\n .setSubject(actorId)\n // `iss` = the service identity that minted the token. Matches `sub`\n // because these are self-minted tokens (caller is asserting itself).\n // Gives the gateway room to enforce a minter allowlist later without\n // a token-format change.\n .setIssuer(actorId)\n .setIssuedAt(nowSec)\n .setExpirationTime(expSec)\n .sign(keyBytes);\n\n cache.set(key, { token, expiresAtMs: expSec * 1000 });\n return token;\n}\n\n/** Test hook to clear the cache between tests. */\nexport function __clearServiceJwtCache(): void {\n cache.clear();\n}\n","/**\n * Gateway Client Types\n *\n * Type definitions for the unified gateway client with\n * circuit breaker and retry logic.\n *\n * @module gateway/types\n * @category Gateway\n */\n\nimport type { ServiceLayer, CircuitBreakerConfig, GatewayRetryConfig, GatewayRequestHeaders } from '../types/layer.js';\n\n/**\n * Gateway client configuration\n */\nexport interface GatewayClientConfig {\n /**\n * Layer this client belongs to\n */\n layer: ServiceLayer;\n\n /**\n * Service name (for logging and headers)\n */\n serviceName: string;\n\n /**\n * Service identity for bypass headers\n * @default serviceName\n */\n serviceIdentity?: string;\n\n /**\n * Internal gateway URL (same layer M2M)\n * @default Resolved from layer defaults or environment\n */\n internalGatewayUrl?: string;\n\n /**\n * Cross-layer gateway URL (cross layer via public gateway)\n * @default Resolved from layer defaults or environment\n */\n crossLayerGatewayUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000 (30 seconds)\n */\n timeout?: number;\n\n /**\n * Circuit breaker configuration\n */\n circuitBreaker?: Partial<CircuitBreakerConfig>;\n\n /**\n * Retry configuration\n */\n retry?: Partial<GatewayRetryConfig>;\n\n /**\n * Enable request logging\n * @default true\n */\n enableLogging?: boolean;\n\n /**\n * Default headers to include in all requests\n */\n defaultHeaders?: GatewayRequestHeaders;\n}\n\n/**\n * Circuit breaker states\n */\nexport enum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\n/**\n * Circuit breaker instance interface\n */\nexport interface ICircuitBreaker {\n /**\n * Get current circuit state\n */\n getState(): CircuitState;\n\n /**\n * Record a successful call\n */\n recordSuccess(): void;\n\n /**\n * Record a failed call\n */\n recordFailure(): void;\n\n /**\n * Check if circuit allows calls\n */\n allowRequest(): boolean;\n\n /**\n * Force open the circuit\n */\n forceOpen(): void;\n\n /**\n * Force close the circuit\n */\n forceClose(): void;\n\n /**\n * Get circuit statistics\n */\n getStats(): CircuitBreakerStats;\n}\n\n/**\n * Circuit breaker statistics\n */\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failures: number;\n successes: number;\n consecutiveFailures: number;\n lastFailureTime: number | null;\n lastSuccessTime: number | null;\n openedAt: number | null;\n}\n\n/**\n * GraphQL request options\n */\nexport interface GraphQLRequestOptions {\n /**\n * GraphQL query or mutation string\n */\n query: string;\n\n /**\n * GraphQL variables\n */\n variables?: Record<string, unknown>;\n\n /**\n * Operation name (for multi-operation documents)\n */\n operationName?: string;\n\n /**\n * Additional headers for this request\n */\n headers?: GatewayRequestHeaders;\n\n /**\n * Override timeout for this request\n */\n timeout?: number;\n\n /**\n * Skip circuit breaker for this request\n * @default false\n */\n skipCircuitBreaker?: boolean;\n\n /**\n * Skip retry logic for this request\n * @default false\n */\n skipRetry?: boolean;\n}\n\n/**\n * GraphQL response\n */\nexport interface GraphQLResponse<T = unknown> {\n /**\n * Response data\n */\n data?: T;\n\n /**\n * GraphQL errors\n */\n errors?: GraphQLError[];\n}\n\n/**\n * GraphQL error structure\n */\nexport interface GraphQLError {\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Gateway client interface\n */\nexport interface IGatewayClient {\n /**\n * Execute internal (same layer) GraphQL query/mutation\n *\n * Uses internal gateway with bypass headers for M2M communication.\n *\n * @param options - Request options\n * @returns GraphQL response\n */\n internalQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Execute cross-layer GraphQL query/mutation\n *\n * Uses public gateway for cross-layer communication.\n *\n * @param options - Request options\n * @returns GraphQL response\n */\n crossLayerQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Execute GraphQL query/mutation with explicit gateway URL\n *\n * @param gatewayUrl - Gateway URL to use\n * @param options - Request options\n * @returns GraphQL response\n */\n query<T = unknown>(gatewayUrl: string, options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Get internal gateway circuit breaker\n */\n getInternalCircuitBreaker(): ICircuitBreaker;\n\n /**\n * Get cross-layer gateway circuit breaker\n */\n getCrossLayerCircuitBreaker(): ICircuitBreaker;\n\n /**\n * Get client health status\n */\n getHealthStatus(): GatewayClientHealth;\n\n /**\n * Update default headers\n */\n updateDefaultHeaders(headers: Partial<GatewayRequestHeaders>): void;\n}\n\n/**\n * Gateway client health status\n */\nexport interface GatewayClientHealth {\n /**\n * Internal gateway status\n */\n internal: {\n url: string;\n circuitState: CircuitState;\n stats: CircuitBreakerStats;\n };\n\n /**\n * Cross-layer gateway status\n */\n crossLayer: {\n url: string;\n circuitState: CircuitState;\n stats: CircuitBreakerStats;\n };\n}\n\n/**\n * Gateway error types\n */\nexport enum GatewayErrorType {\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT_ERROR = 'TIMEOUT_ERROR',\n CIRCUIT_OPEN = 'CIRCUIT_OPEN',\n GRAPHQL_ERROR = 'GRAPHQL_ERROR',\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n}\n\n/**\n * Gateway error class\n */\nexport class GatewayError extends Error {\n type: GatewayErrorType;\n gatewayUrl: string;\n statusCode?: number;\n graphqlErrors?: GraphQLError[];\n override cause?: Error;\n\n constructor(\n message: string,\n type: GatewayErrorType,\n gatewayUrl: string,\n options?: {\n statusCode?: number;\n graphqlErrors?: GraphQLError[];\n cause?: Error;\n }\n ) {\n super(message);\n this.name = 'GatewayError';\n this.type = type;\n this.gatewayUrl = gatewayUrl;\n this.statusCode = options?.statusCode;\n this.graphqlErrors = options?.graphqlErrors;\n this.cause = options?.cause;\n Object.setPrototypeOf(this, GatewayError.prototype);\n }\n}\n\n/**\n * Request context for logging and tracing\n */\nexport interface RequestContext {\n /**\n * Request ID for tracing\n */\n requestId: string;\n\n /**\n * Actor ID making the request\n */\n actorId?: string;\n\n /**\n * Workspace ID context\n */\n workspaceId?: string;\n\n /**\n * Timestamp when request started\n */\n startTime: number;\n\n /**\n * Call type\n */\n callType: 'internal' | 'cross-layer' | 'direct';\n}\n","/**\n * Unified Gateway Client\n *\n * Provides a layer-aware GraphQL client with circuit breaker,\n * retry logic, and automatic header management for M2M communication.\n *\n * @module gateway/client\n * @category Gateway\n *\n * @example\n * ```typescript\n * import { GatewayClient } from '@burdenoff/be-sdk/gateway';\n *\n * const client = new GatewayClient({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Internal call (same layer)\n * const result = await client.internalQuery({\n * query: `query { getTag(id: \"123\") { id name } }`,\n * });\n *\n * // Cross-layer call\n * const authResult = await client.crossLayerQuery({\n * query: `query { getCurrentUser { id email } }`,\n * });\n * ```\n */\n\nimport { LayerManager } from '../layer/index.js';\nimport { logger } from '../logger/index.js';\nimport { signServiceJwt } from './service-jwt.js';\nimport {\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n DEFAULT_GATEWAY_RETRY_CONFIG,\n type CircuitBreakerConfig,\n type GatewayRequestHeaders,\n type GatewayRetryConfig,\n type ServiceLayer,\n} from '../types/layer.js';\nimport {\n CircuitState,\n GatewayError,\n GatewayErrorType,\n type CircuitBreakerStats,\n type GatewayClientConfig,\n type GatewayClientHealth,\n type GraphQLError,\n type GraphQLRequestOptions,\n type GraphQLResponse,\n type ICircuitBreaker,\n type IGatewayClient,\n type RequestContext,\n} from './types.js';\n\nconst uuidv4 = (): string => crypto.randomUUID();\n\n/**\n * Case-insensitive presence check for the `Authorization` header. HTTP header\n * names are case-insensitive (RFC 7230), and while the outbound `fetch` will\n * preserve whatever casing the caller supplies, callers may legitimately set\n * `authorization` / `Authorization` / even `AUTHORIZATION` via defaultHeaders\n * or options.headers. We must not overwrite an already-supplied token.\n */\nfunction hasAuthorizationHeader(headers: Record<string, string>): boolean {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'authorization') return true;\n }\n return false;\n}\n\nexport function resolveBypassPermissionValue(\n token: string | undefined = process.env['INTERNAL_SERVICE_TOKEN']\n): string {\n const normalizedToken = token?.trim();\n\n if (!normalizedToken) {\n throw new Error('INTERNAL_SERVICE_TOKEN must be configured for bypass-enabled gateway calls');\n }\n\n return normalizedToken;\n}\n\n/**\n * Circuit Breaker Implementation\n */\nclass CircuitBreaker implements ICircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failures = 0;\n private successes = 0;\n private consecutiveFailures = 0;\n private lastFailureTime: number | null = null;\n private lastSuccessTime: number | null = null;\n private openedAt: number | null = null;\n private failureTimestamps: number[] = [];\n private config: CircuitBreakerConfig;\n\n constructor(config: CircuitBreakerConfig) {\n this.config = config;\n }\n\n getState(): CircuitState {\n this.checkStateTransition();\n return this.state;\n }\n\n recordSuccess(): void {\n this.successes++;\n this.consecutiveFailures = 0;\n this.lastSuccessTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.state = CircuitState.CLOSED;\n this.failures = 0;\n this.failureTimestamps = [];\n this.openedAt = null;\n logger.info('[CircuitBreaker] Circuit closed after successful test');\n }\n }\n\n recordFailure(): void {\n this.failures++;\n this.consecutiveFailures++;\n this.lastFailureTime = Date.now();\n this.failureTimestamps.push(Date.now());\n\n // Clean up old timestamps\n const windowStart = Date.now() - this.config.failureWindow;\n this.failureTimestamps = this.failureTimestamps.filter((t) => t > windowStart);\n\n // Check if we should open the circuit\n if (this.state === CircuitState.CLOSED && this.failureTimestamps.length >= this.config.failureThreshold) {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.warn('[CircuitBreaker] Circuit opened due to failures', {\n failures: this.failureTimestamps.length,\n threshold: this.config.failureThreshold,\n });\n }\n\n // If we're half-open and fail, go back to open\n if (this.state === CircuitState.HALF_OPEN) {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.warn('[CircuitBreaker] Circuit re-opened after failed test');\n }\n }\n\n allowRequest(): boolean {\n this.checkStateTransition();\n\n switch (this.state) {\n case CircuitState.CLOSED:\n return true;\n case CircuitState.OPEN:\n return false;\n case CircuitState.HALF_OPEN:\n // Allow one test request\n return true;\n default:\n return true;\n }\n }\n\n forceOpen(): void {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.info('[CircuitBreaker] Circuit force-opened');\n }\n\n forceClose(): void {\n this.state = CircuitState.CLOSED;\n this.failures = 0;\n this.consecutiveFailures = 0;\n this.failureTimestamps = [];\n this.openedAt = null;\n logger.info('[CircuitBreaker] Circuit force-closed');\n }\n\n getStats(): CircuitBreakerStats {\n return {\n state: this.state,\n failures: this.failures,\n successes: this.successes,\n consecutiveFailures: this.consecutiveFailures,\n lastFailureTime: this.lastFailureTime,\n lastSuccessTime: this.lastSuccessTime,\n openedAt: this.openedAt,\n };\n }\n\n private checkStateTransition(): void {\n if (this.state === CircuitState.OPEN && this.openedAt) {\n const elapsed = Date.now() - this.openedAt;\n if (elapsed >= this.config.resetTimeout) {\n this.state = CircuitState.HALF_OPEN;\n logger.info('[CircuitBreaker] Circuit transitioning to half-open');\n }\n }\n }\n}\n\n/**\n * Unified Gateway Client\n */\nexport class GatewayClient implements IGatewayClient {\n private config: GatewayClientConfig;\n private layerManager: LayerManager;\n private internalCircuitBreaker: CircuitBreaker;\n private crossLayerCircuitBreaker: CircuitBreaker;\n private retryConfig: GatewayRetryConfig;\n private defaultHeaders: GatewayRequestHeaders;\n\n constructor(config: GatewayClientConfig) {\n this.config = {\n timeout: 30000,\n enableLogging: true,\n ...config,\n };\n\n // Initialize layer manager\n this.layerManager = new LayerManager({\n layer: config.layer,\n serviceName: config.serviceName,\n serviceIdentity: config.serviceIdentity,\n });\n\n // Override URLs if provided\n if (config.internalGatewayUrl) {\n // Use getter internally, but we'll store the override\n }\n if (config.crossLayerGatewayUrl) {\n // Use getter internally, but we'll store the override\n }\n\n // Initialize circuit breakers\n const cbConfig: CircuitBreakerConfig = {\n ...DEFAULT_CIRCUIT_BREAKER_CONFIG,\n ...config.circuitBreaker,\n };\n this.internalCircuitBreaker = new CircuitBreaker(cbConfig);\n this.crossLayerCircuitBreaker = new CircuitBreaker(cbConfig);\n\n // Initialize retry config\n this.retryConfig = {\n ...DEFAULT_GATEWAY_RETRY_CONFIG,\n ...config.retry,\n };\n\n // Initialize default headers\n this.defaultHeaders = {\n 'x-service-identity': this.layerManager.getServiceIdentity(),\n 'x-actor-type': 'service',\n ...config.defaultHeaders,\n };\n\n logger.debug('[GatewayClient] Initialized', {\n layer: config.layer,\n serviceName: config.serviceName,\n internalUrl: this.getInternalUrl(),\n crossLayerUrl: this.getCrossLayerUrl(),\n });\n }\n\n private getInternalUrl(): string {\n return this.config.internalGatewayUrl || this.layerManager.getInternalGatewayUrl();\n }\n\n private getCrossLayerUrl(): string {\n return this.config.crossLayerGatewayUrl || this.layerManager.getCrossLayerGatewayUrl();\n }\n\n /**\n * Execute internal (same layer) GraphQL query/mutation\n */\n async internalQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('internal', options);\n\n return this.executeWithRetry(this.getInternalUrl(), options, this.internalCircuitBreaker, context, {\n bypassPermission: true,\n });\n }\n\n /**\n * Execute cross-layer GraphQL query/mutation\n */\n async crossLayerQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('cross-layer', options);\n\n return this.executeWithRetry(\n this.getCrossLayerUrl(),\n options,\n this.crossLayerCircuitBreaker,\n context,\n { bypassPermission: false } // Cross-layer calls go through public gateway\n );\n }\n\n /**\n * Execute GraphQL query/mutation with explicit gateway URL\n */\n async query<T = unknown>(gatewayUrl: string, options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('direct', options);\n\n // Use internal circuit breaker for direct calls\n return this.executeWithRetry(gatewayUrl, options, this.internalCircuitBreaker, context, {\n bypassPermission: false,\n });\n }\n\n getInternalCircuitBreaker(): ICircuitBreaker {\n return this.internalCircuitBreaker;\n }\n\n getCrossLayerCircuitBreaker(): ICircuitBreaker {\n return this.crossLayerCircuitBreaker;\n }\n\n getHealthStatus(): GatewayClientHealth {\n return {\n internal: {\n url: this.getInternalUrl(),\n circuitState: this.internalCircuitBreaker.getState(),\n stats: this.internalCircuitBreaker.getStats(),\n },\n crossLayer: {\n url: this.getCrossLayerUrl(),\n circuitState: this.crossLayerCircuitBreaker.getState(),\n stats: this.crossLayerCircuitBreaker.getStats(),\n },\n };\n }\n\n updateDefaultHeaders(headers: Partial<GatewayRequestHeaders>): void {\n this.defaultHeaders = { ...this.defaultHeaders, ...headers };\n }\n\n private createRequestContext(\n callType: 'internal' | 'cross-layer' | 'direct',\n options: GraphQLRequestOptions\n ): RequestContext {\n return {\n requestId: uuidv4(),\n actorId: options.headers?.['x-actor-id'] || this.defaultHeaders['x-actor-id'],\n workspaceId: options.headers?.['x-workspace-id'] || this.defaultHeaders['x-workspace-id'],\n startTime: Date.now(),\n callType,\n };\n }\n\n /**\n * Check if an error should be retried\n */\n private shouldRetryError(error: unknown): boolean {\n if (!(error instanceof GatewayError)) {\n return true;\n }\n // Don't retry GraphQL errors or circuit open errors\n return error.type !== GatewayErrorType.GRAPHQL_ERROR && error.type !== GatewayErrorType.CIRCUIT_OPEN;\n }\n\n /**\n * Calculate retry delay with exponential backoff\n */\n private calculateRetryDelay(attempt: number): number {\n return Math.min(\n this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt - 1),\n this.retryConfig.maxDelay\n );\n }\n\n /**\n * Log retry attempt if logging is enabled\n */\n private logRetryAttempt(\n context: RequestContext,\n attempt: number,\n maxAttempts: number,\n delay: number,\n error: Error\n ): void {\n if (this.config.enableLogging) {\n logger.warn('[GatewayClient] Request failed, retrying', {\n requestId: context.requestId,\n attempt,\n maxAttempts,\n delay,\n error: error.message,\n });\n }\n }\n\n private async executeWithRetry<T>(\n gatewayUrl: string,\n options: GraphQLRequestOptions,\n circuitBreaker: CircuitBreaker,\n context: RequestContext,\n settings: { bypassPermission: boolean }\n ): Promise<GraphQLResponse<T>> {\n // Check circuit breaker\n if (!options.skipCircuitBreaker && !circuitBreaker.allowRequest()) {\n throw new GatewayError(`Circuit breaker is open for ${gatewayUrl}`, GatewayErrorType.CIRCUIT_OPEN, gatewayUrl);\n }\n\n const maxAttempts = options.skipRetry ? 1 : this.retryConfig.maxAttempts;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const result = await this.executeRequest<T>(gatewayUrl, options, context, settings.bypassPermission);\n if (!options.skipCircuitBreaker) {\n circuitBreaker.recordSuccess();\n }\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (!options.skipCircuitBreaker) {\n circuitBreaker.recordFailure();\n }\n\n if (!this.shouldRetryError(error)) {\n throw error;\n }\n\n if (attempt < maxAttempts) {\n const delay = this.calculateRetryDelay(attempt);\n this.logRetryAttempt(context, attempt, maxAttempts, delay, lastError);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError || new GatewayError('Request failed after retries', GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);\n }\n\n /**\n * Build headers for a request\n */\n private buildRequestHeaders(\n context: RequestContext,\n options: GraphQLRequestOptions,\n bypassPermission: boolean\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-request-id': context.requestId,\n 'x-call-type': context.callType,\n };\n\n // Add default headers\n for (const [key, value] of Object.entries(this.defaultHeaders)) {\n if (value !== undefined) {\n headers[key] = String(value);\n }\n }\n\n // Add request-specific headers\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n if (value !== undefined) {\n headers[key] = String(value);\n }\n }\n }\n\n // Add bypass headers for internal calls\n if (bypassPermission) {\n headers['x-bypass-permission'] = resolveBypassPermissionValue();\n headers['x-bypass-source'] = this.layerManager.getServiceIdentity();\n headers['x-bypass-timestamp'] = Date.now().toString();\n }\n\n return headers;\n }\n\n /**\n * Handle GraphQL errors in response\n */\n private handleGraphQLErrors<T>(\n result: GraphQLResponse<T>,\n context: RequestContext,\n gatewayUrl: string,\n duration: number\n ): void {\n if (!result.errors || result.errors.length === 0) {\n return;\n }\n\n const errorMessages = result.errors.map((e: GraphQLError) => e.message).join(', ');\n\n if (this.config.enableLogging) {\n logger.warn('[GatewayClient] GraphQL errors', {\n requestId: context.requestId,\n errors: result.errors,\n duration,\n });\n }\n\n throw new GatewayError(`GraphQL error: ${errorMessages}`, GatewayErrorType.GRAPHQL_ERROR, gatewayUrl, {\n graphqlErrors: result.errors,\n });\n }\n\n /**\n * Handle fetch errors\n */\n private handleFetchError(\n error: unknown,\n context: RequestContext,\n gatewayUrl: string,\n timeout: number,\n duration: number\n ): never {\n if (error instanceof GatewayError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new GatewayError(`Request timed out after ${timeout}ms`, GatewayErrorType.TIMEOUT_ERROR, gatewayUrl, {\n cause: error,\n });\n }\n\n if (this.config.enableLogging) {\n logger.error('[GatewayClient] Request failed', {\n requestId: context.requestId,\n error: error.message,\n duration,\n });\n }\n\n throw new GatewayError(error.message, GatewayErrorType.NETWORK_ERROR, gatewayUrl, {\n cause: error,\n });\n }\n\n throw new GatewayError(String(error), GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);\n }\n\n private async executeRequest<T>(\n gatewayUrl: string,\n options: GraphQLRequestOptions,\n context: RequestContext,\n bypassPermission: boolean\n ): Promise<GraphQLResponse<T>> {\n const timeout = options.timeout || this.config.timeout || 30000;\n const headers = this.buildRequestHeaders(context, options, bypassPermission);\n\n // Cross-layer calls transit the peer layer's PUBLIC gateway, which\n // requires JWT auth to propagate actor context. Mint a short-lived\n // service-actor JWT so the gateway admits the call and preserves\n // `x-actor-type: service` downstream. Skipped when the caller has\n // already supplied an Authorization header (e.g., user-originated\n // cross-layer flows) or when SERVICE_JWT_SECRET is unset.\n if (context.callType === 'cross-layer' && !hasAuthorizationHeader(headers)) {\n const serviceActorId = this.layerManager.getServiceIdentity();\n const serviceJwt = await signServiceJwt(serviceActorId);\n if (serviceJwt) {\n headers['Authorization'] = `Bearer ${serviceJwt}`;\n } else if (this.config.enableLogging) {\n // Subtle failure mode: without the JWT the public gateway strips\n // actor headers and the subgraph rejects with `authenticationRequired`.\n // Surface the root cause so operators rolling out a new caller don't\n // spend time debugging the downstream error.\n logger.debug(\n '[GatewayClient] SERVICE_JWT_SECRET not configured — cross-layer call will proceed without service JWT',\n { requestId: context.requestId, gatewayUrl }\n );\n }\n }\n\n const body = JSON.stringify({\n query: options.query,\n variables: options.variables || {},\n operationName: options.operationName,\n });\n\n if (this.config.enableLogging) {\n logger.debug('[GatewayClient] Executing request', {\n requestId: context.requestId,\n gatewayUrl,\n operationName: options.operationName,\n callType: context.callType,\n bypassPermission,\n });\n }\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(gatewayUrl, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n const duration = Date.now() - context.startTime;\n\n if (!response.ok) {\n throw new GatewayError(\n `HTTP ${response.status}: ${response.statusText}`,\n GatewayErrorType.NETWORK_ERROR,\n gatewayUrl,\n { statusCode: response.status }\n );\n }\n\n const result = (await response.json()) as GraphQLResponse<T>;\n this.handleGraphQLErrors(result, context, gatewayUrl, duration);\n\n if (this.config.enableLogging) {\n logger.debug('[GatewayClient] Request completed', {\n requestId: context.requestId,\n duration,\n hasData: !!result.data,\n });\n }\n\n return result;\n } catch (error) {\n const duration = Date.now() - context.startTime;\n this.handleFetchError(error, context, gatewayUrl, timeout, duration);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\n/**\n * Create a gateway client for a specific layer\n */\nexport function createGatewayClient(config: GatewayClientConfig): GatewayClient {\n return new GatewayClient(config);\n}\n\n/**\n * Create a gateway client from environment variables\n *\n * Required environment variables:\n * - SERVICE_LAYER: 'wspace' | 'global'\n * - SERVICE_NAME: Service name\n *\n * Optional:\n * - SERVICE_IDENTITY: Service identity (defaults to SERVICE_NAME)\n * - {LAYER}_INT_GATEWAY_URL: Internal gateway URL\n * - {OPPOSITE_LAYER}_PUBLIC_GATEWAY_URL: Cross-layer gateway URL\n */\nexport function createGatewayClientFromEnv(): GatewayClient {\n const layer = process.env['SERVICE_LAYER'] as ServiceLayer;\n\n if (!layer || (layer !== 'wspace' && layer !== 'global')) {\n throw new Error(`[GatewayClient] Invalid or missing SERVICE_LAYER. Expected 'wspace' or 'global', got '${layer}'`);\n }\n\n const serviceName = process.env['SERVICE_NAME'];\n if (!serviceName) {\n throw new Error('[GatewayClient] SERVICE_NAME environment variable is required');\n }\n\n const serviceIdentity = process.env['SERVICE_IDENTITY'] || serviceName;\n\n return new GatewayClient({\n layer,\n serviceName,\n serviceIdentity,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/gateway/index.ts","../src/gateway/service-jwt.ts","../src/gateway/types.ts","../src/gateway/client.ts"],"names":["SIGNING_ENV_VAR","KEY_ID","DEFAULT_TTL_SECONDS","REFRESH_BEFORE_EXP_MS","joseModule","getJose","cache","Map","cacheKey","actorId","ttlSeconds","signServiceJwt","secret","process","env","key","cached","get","expiresAtMs","Date","now","token","joseLib","encoder","TextEncoder","keyBytes","encode","nowSec","Math","floor","expSec","SignJWT","actor_type","setProtectedHeader","alg","typ","kid","setSubject","setIssuer","setIssuedAt","setExpirationTime","sign","set","CircuitState","GatewayErrorType","GatewayError","Error","type","gatewayUrl","statusCode","graphqlErrors","cause","message","options","name","Object","setPrototypeOf","prototype","uuidv4","crypto","randomUUID","hasAuthorizationHeader","headers","keys","toLowerCase","resolveBypassPermissionValue","normalizedToken","trim","CircuitBreaker","state","CLOSED","failures","successes","consecutiveFailures","lastFailureTime","lastSuccessTime","openedAt","failureTimestamps","config","getState","checkStateTransition","recordSuccess","HALF_OPEN","logger","info","recordFailure","push","windowStart","failureWindow","filter","t","length","failureThreshold","OPEN","warn","threshold","allowRequest","forceOpen","forceClose","getStats","elapsed","resetTimeout","GatewayClient","layerManager","internalCircuitBreaker","crossLayerCircuitBreaker","retryConfig","defaultHeaders","timeout","enableLogging","LayerManager","layer","serviceName","serviceIdentity","internalGatewayUrl","crossLayerGatewayUrl","cbConfig","DEFAULT_CIRCUIT_BREAKER_CONFIG","circuitBreaker","DEFAULT_GATEWAY_RETRY_CONFIG","retry","getServiceIdentity","debug","internalUrl","getInternalUrl","crossLayerUrl","getCrossLayerUrl","getInternalGatewayUrl","getCrossLayerGatewayUrl","internalQuery","context","createRequestContext","executeWithRetry","bypassPermission","crossLayerQuery","query","getInternalCircuitBreaker","getCrossLayerCircuitBreaker","getHealthStatus","internal","url","circuitState","stats","crossLayer","updateDefaultHeaders","callType","requestId","workspaceId","startTime","shouldRetryError","error","GRAPHQL_ERROR","CIRCUIT_OPEN","calculateRetryDelay","attempt","min","initialDelay","pow","backoffMultiplier","maxDelay","logRetryAttempt","maxAttempts","delay","settings","skipCircuitBreaker","skipRetry","lastError","result","executeRequest","String","sleep","UNKNOWN_ERROR","buildRequestHeaders","value","entries","undefined","toString","handleGraphQLErrors","duration","errors","errorMessages","map","e","join","handleFetchError","TIMEOUT_ERROR","NETWORK_ERROR","serviceActorId","serviceJwt","body","JSON","stringify","variables","operationName","controller","AbortController","timeoutId","setTimeout","abort","response","fetch","method","signal","clearTimeout","ok","status","statusText","json","hasData","data","ms","Promise","resolve","createGatewayClient","createGatewayClientFromEnv"],"mappings":"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","file":"chunk-DMPS4Y53.js","sourcesContent":["/**\n * Gateway Module\n *\n * Provides unified gateway client for layer-aware M2M communication\n * with circuit breaker and retry logic.\n *\n * @module gateway\n * @category Gateway\n *\n * @example\n * ```typescript\n * import { GatewayClient, createGatewayClientFromEnv } from '@burdenoff/be-sdk/gateway';\n *\n * // Create from environment variables\n * const client = createGatewayClientFromEnv();\n *\n * // Or create manually\n * const client = new GatewayClient({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Internal call (same layer, uses int-gateway with bypass)\n * const internalResult = await client.internalQuery({\n * query: `query { getTag(id: \"123\") { id name } }`,\n * });\n *\n * // Cross-layer call (via public gateway)\n * const crossLayerResult = await client.crossLayerQuery({\n * query: `query { getCurrentUser { id email } }`,\n * });\n * ```\n */\n\n// Client exports\nexport { GatewayClient, createGatewayClient, createGatewayClientFromEnv } from './client.js';\n\n// Type exports\nexport {\n CircuitState,\n GatewayErrorType,\n GatewayError,\n type GatewayClientConfig,\n type GraphQLRequestOptions,\n type GraphQLResponse,\n type GraphQLError,\n type IGatewayClient,\n type ICircuitBreaker,\n type CircuitBreakerStats,\n type GatewayClientHealth,\n type RequestContext,\n} from './types.js';\n\n// Gateway-side security plugin stack (for public gateways).\n// Imported by consumers as `@burdenoff/be-sdk/gateway/security` — this\n// re-export lets `@burdenoff/be-sdk/gateway` also resolve the namespace.\nexport * as Security from './security/index.js';\n","/**\n * Service JWT minting + caching for M2M cross-layer calls.\n *\n * The public gateways (global-public-gateway, wspace-public-gateway) validate\n * every incoming request's Authorization header and only propagate `x-actor-*`\n * context headers to subgraphs when the JWT is valid. Without a JWT, raw\n * actor headers are stripped as potential client spoofing. For service-to-\n * service cross-layer calls there is no user JWT to forward — we mint a short-\n * lived service JWT with `actor_type: 'service'` so the gateway admits the\n * call and the subgraph sees a trusted service context.\n *\n * Signing key: SERVICE_JWT_SECRET — a dedicated, separate secret from\n * GLOBAL_AUTH_SECRET (which signs user tokens). Keeping them distinct means a\n * service minter that leaks its env cannot forge user logins. The gateways\n * hold both secrets and pick between them by the JWT's `kid` header\n * (this minter stamps `kid: service-v1`).\n */\nimport type * as jose from 'jose';\n\n/**\n * Dedicated secret for service-minted JWTs.\n *\n * Deliberately separate from `GLOBAL_AUTH_SECRET` (which signs user tokens)\n * so that services that mint service JWTs do not also hold the ability to\n * forge user logins. Blast radius of a leaked secret stays scoped to 60s\n * service tokens with no PII.\n *\n * Gateways hold both secrets and select by the JWT's `kid` header.\n */\nconst SIGNING_ENV_VAR = 'SERVICE_JWT_SECRET';\nconst KEY_ID = 'service-v1';\nconst DEFAULT_TTL_SECONDS = 60;\nconst REFRESH_BEFORE_EXP_MS = 10_000;\n\nlet joseModule: typeof jose | null = null;\n\nasync function getJose(): Promise<typeof jose> {\n if (!joseModule) {\n joseModule = await import('jose');\n }\n return joseModule;\n}\n\ninterface CachedToken {\n token: string;\n expiresAtMs: number;\n}\n\nconst cache = new Map<string, CachedToken>();\n\nfunction cacheKey(actorId: string, ttlSeconds: number): string {\n return `${actorId}:${ttlSeconds}`;\n}\n\n/**\n * Sign a service-actor JWT.\n * Returns null when no signing secret is configured (opt-in).\n */\nexport async function signServiceJwt(\n actorId: string,\n ttlSeconds: number = DEFAULT_TTL_SECONDS\n): Promise<string | null> {\n const secret = process.env[SIGNING_ENV_VAR];\n if (!secret) {\n return null;\n }\n\n const key = cacheKey(actorId, ttlSeconds);\n const cached = cache.get(key);\n if (cached && cached.expiresAtMs - REFRESH_BEFORE_EXP_MS > Date.now()) {\n return cached.token;\n }\n\n const joseLib = await getJose();\n const encoder = new TextEncoder();\n const keyBytes = encoder.encode(secret);\n\n const nowSec = Math.floor(Date.now() / 1000);\n const expSec = nowSec + ttlSeconds;\n\n const token = await new joseLib.SignJWT({\n actor_type: 'service',\n })\n .setProtectedHeader({ alg: 'HS256', typ: 'JWT', kid: KEY_ID })\n .setSubject(actorId)\n // `iss` = the service identity that minted the token. Matches `sub`\n // because these are self-minted tokens (caller is asserting itself).\n // Gives the gateway room to enforce a minter allowlist later without\n // a token-format change.\n .setIssuer(actorId)\n .setIssuedAt(nowSec)\n .setExpirationTime(expSec)\n .sign(keyBytes);\n\n cache.set(key, { token, expiresAtMs: expSec * 1000 });\n return token;\n}\n\n/** Test hook to clear the cache between tests. */\nexport function __clearServiceJwtCache(): void {\n cache.clear();\n}\n","/**\n * Gateway Client Types\n *\n * Type definitions for the unified gateway client with\n * circuit breaker and retry logic.\n *\n * @module gateway/types\n * @category Gateway\n */\n\nimport type { ServiceLayer, CircuitBreakerConfig, GatewayRetryConfig, GatewayRequestHeaders } from '../types/layer.js';\n\n/**\n * Gateway client configuration\n */\nexport interface GatewayClientConfig {\n /**\n * Layer this client belongs to\n */\n layer: ServiceLayer;\n\n /**\n * Service name (for logging and headers)\n */\n serviceName: string;\n\n /**\n * Service identity for bypass headers\n * @default serviceName\n */\n serviceIdentity?: string;\n\n /**\n * Internal gateway URL (same layer M2M)\n * @default Resolved from layer defaults or environment\n */\n internalGatewayUrl?: string;\n\n /**\n * Cross-layer gateway URL (cross layer via public gateway)\n * @default Resolved from layer defaults or environment\n */\n crossLayerGatewayUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000 (30 seconds)\n */\n timeout?: number;\n\n /**\n * Circuit breaker configuration\n */\n circuitBreaker?: Partial<CircuitBreakerConfig>;\n\n /**\n * Retry configuration\n */\n retry?: Partial<GatewayRetryConfig>;\n\n /**\n * Enable request logging\n * @default true\n */\n enableLogging?: boolean;\n\n /**\n * Default headers to include in all requests\n */\n defaultHeaders?: GatewayRequestHeaders;\n}\n\n/**\n * Circuit breaker states\n */\nexport enum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\n/**\n * Circuit breaker instance interface\n */\nexport interface ICircuitBreaker {\n /**\n * Get current circuit state\n */\n getState(): CircuitState;\n\n /**\n * Record a successful call\n */\n recordSuccess(): void;\n\n /**\n * Record a failed call\n */\n recordFailure(): void;\n\n /**\n * Check if circuit allows calls\n */\n allowRequest(): boolean;\n\n /**\n * Force open the circuit\n */\n forceOpen(): void;\n\n /**\n * Force close the circuit\n */\n forceClose(): void;\n\n /**\n * Get circuit statistics\n */\n getStats(): CircuitBreakerStats;\n}\n\n/**\n * Circuit breaker statistics\n */\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failures: number;\n successes: number;\n consecutiveFailures: number;\n lastFailureTime: number | null;\n lastSuccessTime: number | null;\n openedAt: number | null;\n}\n\n/**\n * GraphQL request options\n */\nexport interface GraphQLRequestOptions {\n /**\n * GraphQL query or mutation string\n */\n query: string;\n\n /**\n * GraphQL variables\n */\n variables?: Record<string, unknown>;\n\n /**\n * Operation name (for multi-operation documents)\n */\n operationName?: string;\n\n /**\n * Additional headers for this request\n */\n headers?: GatewayRequestHeaders;\n\n /**\n * Override timeout for this request\n */\n timeout?: number;\n\n /**\n * Skip circuit breaker for this request\n * @default false\n */\n skipCircuitBreaker?: boolean;\n\n /**\n * Skip retry logic for this request\n * @default false\n */\n skipRetry?: boolean;\n}\n\n/**\n * GraphQL response\n */\nexport interface GraphQLResponse<T = unknown> {\n /**\n * Response data\n */\n data?: T;\n\n /**\n * GraphQL errors\n */\n errors?: GraphQLError[];\n}\n\n/**\n * GraphQL error structure\n */\nexport interface GraphQLError {\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Gateway client interface\n */\nexport interface IGatewayClient {\n /**\n * Execute internal (same layer) GraphQL query/mutation\n *\n * Uses internal gateway with bypass headers for M2M communication.\n *\n * @param options - Request options\n * @returns GraphQL response\n */\n internalQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Execute cross-layer GraphQL query/mutation\n *\n * Uses public gateway for cross-layer communication.\n *\n * @param options - Request options\n * @returns GraphQL response\n */\n crossLayerQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Execute GraphQL query/mutation with explicit gateway URL\n *\n * @param gatewayUrl - Gateway URL to use\n * @param options - Request options\n * @returns GraphQL response\n */\n query<T = unknown>(gatewayUrl: string, options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Get internal gateway circuit breaker\n */\n getInternalCircuitBreaker(): ICircuitBreaker;\n\n /**\n * Get cross-layer gateway circuit breaker\n */\n getCrossLayerCircuitBreaker(): ICircuitBreaker;\n\n /**\n * Get client health status\n */\n getHealthStatus(): GatewayClientHealth;\n\n /**\n * Update default headers\n */\n updateDefaultHeaders(headers: Partial<GatewayRequestHeaders>): void;\n}\n\n/**\n * Gateway client health status\n */\nexport interface GatewayClientHealth {\n /**\n * Internal gateway status\n */\n internal: {\n url: string;\n circuitState: CircuitState;\n stats: CircuitBreakerStats;\n };\n\n /**\n * Cross-layer gateway status\n */\n crossLayer: {\n url: string;\n circuitState: CircuitState;\n stats: CircuitBreakerStats;\n };\n}\n\n/**\n * Gateway error types\n */\nexport enum GatewayErrorType {\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT_ERROR = 'TIMEOUT_ERROR',\n CIRCUIT_OPEN = 'CIRCUIT_OPEN',\n GRAPHQL_ERROR = 'GRAPHQL_ERROR',\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n}\n\n/**\n * Gateway error class\n */\nexport class GatewayError extends Error {\n type: GatewayErrorType;\n gatewayUrl: string;\n statusCode?: number;\n graphqlErrors?: GraphQLError[];\n override cause?: Error;\n\n constructor(\n message: string,\n type: GatewayErrorType,\n gatewayUrl: string,\n options?: {\n statusCode?: number;\n graphqlErrors?: GraphQLError[];\n cause?: Error;\n }\n ) {\n super(message);\n this.name = 'GatewayError';\n this.type = type;\n this.gatewayUrl = gatewayUrl;\n this.statusCode = options?.statusCode;\n this.graphqlErrors = options?.graphqlErrors;\n this.cause = options?.cause;\n Object.setPrototypeOf(this, GatewayError.prototype);\n }\n}\n\n/**\n * Request context for logging and tracing\n */\nexport interface RequestContext {\n /**\n * Request ID for tracing\n */\n requestId: string;\n\n /**\n * Actor ID making the request\n */\n actorId?: string;\n\n /**\n * Workspace ID context\n */\n workspaceId?: string;\n\n /**\n * Timestamp when request started\n */\n startTime: number;\n\n /**\n * Call type\n */\n callType: 'internal' | 'cross-layer' | 'direct';\n}\n","/**\n * Unified Gateway Client\n *\n * Provides a layer-aware GraphQL client with circuit breaker,\n * retry logic, and automatic header management for M2M communication.\n *\n * @module gateway/client\n * @category Gateway\n *\n * @example\n * ```typescript\n * import { GatewayClient } from '@burdenoff/be-sdk/gateway';\n *\n * const client = new GatewayClient({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Internal call (same layer)\n * const result = await client.internalQuery({\n * query: `query { getTag(id: \"123\") { id name } }`,\n * });\n *\n * // Cross-layer call\n * const authResult = await client.crossLayerQuery({\n * query: `query { getCurrentUser { id email } }`,\n * });\n * ```\n */\n\nimport { LayerManager } from '../layer/index.js';\nimport { logger } from '../logger/index.js';\nimport { signServiceJwt } from './service-jwt.js';\nimport {\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n DEFAULT_GATEWAY_RETRY_CONFIG,\n type CircuitBreakerConfig,\n type GatewayRequestHeaders,\n type GatewayRetryConfig,\n type ServiceLayer,\n} from '../types/layer.js';\nimport {\n CircuitState,\n GatewayError,\n GatewayErrorType,\n type CircuitBreakerStats,\n type GatewayClientConfig,\n type GatewayClientHealth,\n type GraphQLError,\n type GraphQLRequestOptions,\n type GraphQLResponse,\n type ICircuitBreaker,\n type IGatewayClient,\n type RequestContext,\n} from './types.js';\n\nconst uuidv4 = (): string => crypto.randomUUID();\n\n/**\n * Case-insensitive presence check for the `Authorization` header. HTTP header\n * names are case-insensitive (RFC 7230), and while the outbound `fetch` will\n * preserve whatever casing the caller supplies, callers may legitimately set\n * `authorization` / `Authorization` / even `AUTHORIZATION` via defaultHeaders\n * or options.headers. We must not overwrite an already-supplied token.\n */\nfunction hasAuthorizationHeader(headers: Record<string, string>): boolean {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'authorization') return true;\n }\n return false;\n}\n\nexport function resolveBypassPermissionValue(\n token: string | undefined = process.env['INTERNAL_SERVICE_TOKEN']\n): string {\n const normalizedToken = token?.trim();\n\n if (!normalizedToken) {\n throw new Error('INTERNAL_SERVICE_TOKEN must be configured for bypass-enabled gateway calls');\n }\n\n return normalizedToken;\n}\n\n/**\n * Circuit Breaker Implementation\n */\nclass CircuitBreaker implements ICircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failures = 0;\n private successes = 0;\n private consecutiveFailures = 0;\n private lastFailureTime: number | null = null;\n private lastSuccessTime: number | null = null;\n private openedAt: number | null = null;\n private failureTimestamps: number[] = [];\n private config: CircuitBreakerConfig;\n\n constructor(config: CircuitBreakerConfig) {\n this.config = config;\n }\n\n getState(): CircuitState {\n this.checkStateTransition();\n return this.state;\n }\n\n recordSuccess(): void {\n this.successes++;\n this.consecutiveFailures = 0;\n this.lastSuccessTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.state = CircuitState.CLOSED;\n this.failures = 0;\n this.failureTimestamps = [];\n this.openedAt = null;\n logger.info('[CircuitBreaker] Circuit closed after successful test');\n }\n }\n\n recordFailure(): void {\n this.failures++;\n this.consecutiveFailures++;\n this.lastFailureTime = Date.now();\n this.failureTimestamps.push(Date.now());\n\n // Clean up old timestamps\n const windowStart = Date.now() - this.config.failureWindow;\n this.failureTimestamps = this.failureTimestamps.filter((t) => t > windowStart);\n\n // Check if we should open the circuit\n if (this.state === CircuitState.CLOSED && this.failureTimestamps.length >= this.config.failureThreshold) {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.warn('[CircuitBreaker] Circuit opened due to failures', {\n failures: this.failureTimestamps.length,\n threshold: this.config.failureThreshold,\n });\n }\n\n // If we're half-open and fail, go back to open\n if (this.state === CircuitState.HALF_OPEN) {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.warn('[CircuitBreaker] Circuit re-opened after failed test');\n }\n }\n\n allowRequest(): boolean {\n this.checkStateTransition();\n\n switch (this.state) {\n case CircuitState.CLOSED:\n return true;\n case CircuitState.OPEN:\n return false;\n case CircuitState.HALF_OPEN:\n // Allow one test request\n return true;\n default:\n return true;\n }\n }\n\n forceOpen(): void {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.info('[CircuitBreaker] Circuit force-opened');\n }\n\n forceClose(): void {\n this.state = CircuitState.CLOSED;\n this.failures = 0;\n this.consecutiveFailures = 0;\n this.failureTimestamps = [];\n this.openedAt = null;\n logger.info('[CircuitBreaker] Circuit force-closed');\n }\n\n getStats(): CircuitBreakerStats {\n return {\n state: this.state,\n failures: this.failures,\n successes: this.successes,\n consecutiveFailures: this.consecutiveFailures,\n lastFailureTime: this.lastFailureTime,\n lastSuccessTime: this.lastSuccessTime,\n openedAt: this.openedAt,\n };\n }\n\n private checkStateTransition(): void {\n if (this.state === CircuitState.OPEN && this.openedAt) {\n const elapsed = Date.now() - this.openedAt;\n if (elapsed >= this.config.resetTimeout) {\n this.state = CircuitState.HALF_OPEN;\n logger.info('[CircuitBreaker] Circuit transitioning to half-open');\n }\n }\n }\n}\n\n/**\n * Unified Gateway Client\n */\nexport class GatewayClient implements IGatewayClient {\n private config: GatewayClientConfig;\n private layerManager: LayerManager;\n private internalCircuitBreaker: CircuitBreaker;\n private crossLayerCircuitBreaker: CircuitBreaker;\n private retryConfig: GatewayRetryConfig;\n private defaultHeaders: GatewayRequestHeaders;\n\n constructor(config: GatewayClientConfig) {\n this.config = {\n timeout: 30000,\n enableLogging: true,\n ...config,\n };\n\n // Initialize layer manager\n this.layerManager = new LayerManager({\n layer: config.layer,\n serviceName: config.serviceName,\n serviceIdentity: config.serviceIdentity,\n });\n\n // Override URLs if provided\n if (config.internalGatewayUrl) {\n // Use getter internally, but we'll store the override\n }\n if (config.crossLayerGatewayUrl) {\n // Use getter internally, but we'll store the override\n }\n\n // Initialize circuit breakers\n const cbConfig: CircuitBreakerConfig = {\n ...DEFAULT_CIRCUIT_BREAKER_CONFIG,\n ...config.circuitBreaker,\n };\n this.internalCircuitBreaker = new CircuitBreaker(cbConfig);\n this.crossLayerCircuitBreaker = new CircuitBreaker(cbConfig);\n\n // Initialize retry config\n this.retryConfig = {\n ...DEFAULT_GATEWAY_RETRY_CONFIG,\n ...config.retry,\n };\n\n // Initialize default headers\n this.defaultHeaders = {\n 'x-service-identity': this.layerManager.getServiceIdentity(),\n 'x-actor-type': 'service',\n ...config.defaultHeaders,\n };\n\n logger.debug('[GatewayClient] Initialized', {\n layer: config.layer,\n serviceName: config.serviceName,\n internalUrl: this.getInternalUrl(),\n crossLayerUrl: this.getCrossLayerUrl(),\n });\n }\n\n private getInternalUrl(): string {\n return this.config.internalGatewayUrl || this.layerManager.getInternalGatewayUrl();\n }\n\n private getCrossLayerUrl(): string {\n return this.config.crossLayerGatewayUrl || this.layerManager.getCrossLayerGatewayUrl();\n }\n\n /**\n * Execute internal (same layer) GraphQL query/mutation\n */\n async internalQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('internal', options);\n\n return this.executeWithRetry(this.getInternalUrl(), options, this.internalCircuitBreaker, context, {\n bypassPermission: true,\n });\n }\n\n /**\n * Execute cross-layer GraphQL query/mutation\n */\n async crossLayerQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('cross-layer', options);\n\n return this.executeWithRetry(\n this.getCrossLayerUrl(),\n options,\n this.crossLayerCircuitBreaker,\n context,\n { bypassPermission: false } // Cross-layer calls go through public gateway\n );\n }\n\n /**\n * Execute GraphQL query/mutation with explicit gateway URL\n */\n async query<T = unknown>(gatewayUrl: string, options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('direct', options);\n\n // Use internal circuit breaker for direct calls\n return this.executeWithRetry(gatewayUrl, options, this.internalCircuitBreaker, context, {\n bypassPermission: false,\n });\n }\n\n getInternalCircuitBreaker(): ICircuitBreaker {\n return this.internalCircuitBreaker;\n }\n\n getCrossLayerCircuitBreaker(): ICircuitBreaker {\n return this.crossLayerCircuitBreaker;\n }\n\n getHealthStatus(): GatewayClientHealth {\n return {\n internal: {\n url: this.getInternalUrl(),\n circuitState: this.internalCircuitBreaker.getState(),\n stats: this.internalCircuitBreaker.getStats(),\n },\n crossLayer: {\n url: this.getCrossLayerUrl(),\n circuitState: this.crossLayerCircuitBreaker.getState(),\n stats: this.crossLayerCircuitBreaker.getStats(),\n },\n };\n }\n\n updateDefaultHeaders(headers: Partial<GatewayRequestHeaders>): void {\n this.defaultHeaders = { ...this.defaultHeaders, ...headers };\n }\n\n private createRequestContext(\n callType: 'internal' | 'cross-layer' | 'direct',\n options: GraphQLRequestOptions\n ): RequestContext {\n return {\n requestId: uuidv4(),\n actorId: options.headers?.['x-actor-id'] || this.defaultHeaders['x-actor-id'],\n workspaceId: options.headers?.['x-workspace-id'] || this.defaultHeaders['x-workspace-id'],\n startTime: Date.now(),\n callType,\n };\n }\n\n /**\n * Check if an error should be retried\n */\n private shouldRetryError(error: unknown): boolean {\n if (!(error instanceof GatewayError)) {\n return true;\n }\n // Don't retry GraphQL errors or circuit open errors\n return error.type !== GatewayErrorType.GRAPHQL_ERROR && error.type !== GatewayErrorType.CIRCUIT_OPEN;\n }\n\n /**\n * Calculate retry delay with exponential backoff\n */\n private calculateRetryDelay(attempt: number): number {\n return Math.min(\n this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt - 1),\n this.retryConfig.maxDelay\n );\n }\n\n /**\n * Log retry attempt if logging is enabled\n */\n private logRetryAttempt(\n context: RequestContext,\n attempt: number,\n maxAttempts: number,\n delay: number,\n error: Error\n ): void {\n if (this.config.enableLogging) {\n logger.warn('[GatewayClient] Request failed, retrying', {\n requestId: context.requestId,\n attempt,\n maxAttempts,\n delay,\n error: error.message,\n });\n }\n }\n\n private async executeWithRetry<T>(\n gatewayUrl: string,\n options: GraphQLRequestOptions,\n circuitBreaker: CircuitBreaker,\n context: RequestContext,\n settings: { bypassPermission: boolean }\n ): Promise<GraphQLResponse<T>> {\n // Check circuit breaker\n if (!options.skipCircuitBreaker && !circuitBreaker.allowRequest()) {\n throw new GatewayError(`Circuit breaker is open for ${gatewayUrl}`, GatewayErrorType.CIRCUIT_OPEN, gatewayUrl);\n }\n\n const maxAttempts = options.skipRetry ? 1 : this.retryConfig.maxAttempts;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const result = await this.executeRequest<T>(gatewayUrl, options, context, settings.bypassPermission);\n if (!options.skipCircuitBreaker) {\n circuitBreaker.recordSuccess();\n }\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (!options.skipCircuitBreaker) {\n circuitBreaker.recordFailure();\n }\n\n if (!this.shouldRetryError(error)) {\n throw error;\n }\n\n if (attempt < maxAttempts) {\n const delay = this.calculateRetryDelay(attempt);\n this.logRetryAttempt(context, attempt, maxAttempts, delay, lastError);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError || new GatewayError('Request failed after retries', GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);\n }\n\n /**\n * Build headers for a request\n */\n private buildRequestHeaders(\n context: RequestContext,\n options: GraphQLRequestOptions,\n bypassPermission: boolean\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-request-id': context.requestId,\n 'x-call-type': context.callType,\n };\n\n // Add default headers\n for (const [key, value] of Object.entries(this.defaultHeaders)) {\n if (value !== undefined) {\n headers[key] = String(value);\n }\n }\n\n // Add request-specific headers\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n if (value !== undefined) {\n headers[key] = String(value);\n }\n }\n }\n\n // Add bypass headers for internal calls\n if (bypassPermission) {\n headers['x-bypass-permission'] = resolveBypassPermissionValue();\n headers['x-bypass-source'] = this.layerManager.getServiceIdentity();\n headers['x-bypass-timestamp'] = Date.now().toString();\n }\n\n return headers;\n }\n\n /**\n * Handle GraphQL errors in response\n */\n private handleGraphQLErrors<T>(\n result: GraphQLResponse<T>,\n context: RequestContext,\n gatewayUrl: string,\n duration: number\n ): void {\n if (!result.errors || result.errors.length === 0) {\n return;\n }\n\n const errorMessages = result.errors.map((e: GraphQLError) => e.message).join(', ');\n\n if (this.config.enableLogging) {\n logger.warn('[GatewayClient] GraphQL errors', {\n requestId: context.requestId,\n errors: result.errors,\n duration,\n });\n }\n\n throw new GatewayError(`GraphQL error: ${errorMessages}`, GatewayErrorType.GRAPHQL_ERROR, gatewayUrl, {\n graphqlErrors: result.errors,\n });\n }\n\n /**\n * Handle fetch errors\n */\n private handleFetchError(\n error: unknown,\n context: RequestContext,\n gatewayUrl: string,\n timeout: number,\n duration: number\n ): never {\n if (error instanceof GatewayError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new GatewayError(`Request timed out after ${timeout}ms`, GatewayErrorType.TIMEOUT_ERROR, gatewayUrl, {\n cause: error,\n });\n }\n\n if (this.config.enableLogging) {\n logger.error('[GatewayClient] Request failed', {\n requestId: context.requestId,\n error: error.message,\n duration,\n });\n }\n\n throw new GatewayError(error.message, GatewayErrorType.NETWORK_ERROR, gatewayUrl, {\n cause: error,\n });\n }\n\n throw new GatewayError(String(error), GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);\n }\n\n private async executeRequest<T>(\n gatewayUrl: string,\n options: GraphQLRequestOptions,\n context: RequestContext,\n bypassPermission: boolean\n ): Promise<GraphQLResponse<T>> {\n const timeout = options.timeout || this.config.timeout || 30000;\n const headers = this.buildRequestHeaders(context, options, bypassPermission);\n\n // Cross-layer calls transit the peer layer's PUBLIC gateway, which\n // requires JWT auth to propagate actor context. Mint a short-lived\n // service-actor JWT so the gateway admits the call and preserves\n // `x-actor-type: service` downstream. Skipped when the caller has\n // already supplied an Authorization header (e.g., user-originated\n // cross-layer flows) or when SERVICE_JWT_SECRET is unset.\n if (context.callType === 'cross-layer' && !hasAuthorizationHeader(headers)) {\n const serviceActorId = this.layerManager.getServiceIdentity();\n const serviceJwt = await signServiceJwt(serviceActorId);\n if (serviceJwt) {\n headers['Authorization'] = `Bearer ${serviceJwt}`;\n } else if (this.config.enableLogging) {\n // Subtle failure mode: without the JWT the public gateway strips\n // actor headers and the subgraph rejects with `authenticationRequired`.\n // Surface the root cause so operators rolling out a new caller don't\n // spend time debugging the downstream error.\n logger.debug(\n '[GatewayClient] SERVICE_JWT_SECRET not configured — cross-layer call will proceed without service JWT',\n { requestId: context.requestId, gatewayUrl }\n );\n }\n }\n\n const body = JSON.stringify({\n query: options.query,\n variables: options.variables || {},\n operationName: options.operationName,\n });\n\n if (this.config.enableLogging) {\n logger.debug('[GatewayClient] Executing request', {\n requestId: context.requestId,\n gatewayUrl,\n operationName: options.operationName,\n callType: context.callType,\n bypassPermission,\n });\n }\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(gatewayUrl, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n const duration = Date.now() - context.startTime;\n\n if (!response.ok) {\n throw new GatewayError(\n `HTTP ${response.status}: ${response.statusText}`,\n GatewayErrorType.NETWORK_ERROR,\n gatewayUrl,\n { statusCode: response.status }\n );\n }\n\n const result = (await response.json()) as GraphQLResponse<T>;\n this.handleGraphQLErrors(result, context, gatewayUrl, duration);\n\n if (this.config.enableLogging) {\n logger.debug('[GatewayClient] Request completed', {\n requestId: context.requestId,\n duration,\n hasData: !!result.data,\n });\n }\n\n return result;\n } catch (error) {\n const duration = Date.now() - context.startTime;\n this.handleFetchError(error, context, gatewayUrl, timeout, duration);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\n/**\n * Create a gateway client for a specific layer\n */\nexport function createGatewayClient(config: GatewayClientConfig): GatewayClient {\n return new GatewayClient(config);\n}\n\n/**\n * Create a gateway client from environment variables\n *\n * Required environment variables:\n * - SERVICE_LAYER: 'wspace' | 'global'\n * - SERVICE_NAME: Service name\n *\n * Optional:\n * - SERVICE_IDENTITY: Service identity (defaults to SERVICE_NAME)\n * - {LAYER}_INT_GATEWAY_URL: Internal gateway URL\n * - {OPPOSITE_LAYER}_PUBLIC_GATEWAY_URL: Cross-layer gateway URL\n */\nexport function createGatewayClientFromEnv(): GatewayClient {\n const layer = process.env['SERVICE_LAYER'] as ServiceLayer;\n\n if (!layer || (layer !== 'wspace' && layer !== 'global')) {\n throw new Error(`[GatewayClient] Invalid or missing SERVICE_LAYER. Expected 'wspace' or 'global', got '${layer}'`);\n }\n\n const serviceName = process.env['SERVICE_NAME'];\n if (!serviceName) {\n throw new Error('[GatewayClient] SERVICE_NAME environment variable is required');\n }\n\n const serviceIdentity = process.env['SERVICE_IDENTITY'] || serviceName;\n\n return new GatewayClient({\n layer,\n serviceName,\n serviceIdentity,\n });\n}\n"]}
|
|
@@ -144,5 +144,5 @@ function pickTraceFields() {
|
|
|
144
144
|
__name(pickTraceFields, "pickTraceFields");
|
|
145
145
|
|
|
146
146
|
export { DEFAULT_REDACT_PATHS, createPinoLogger };
|
|
147
|
-
//# sourceMappingURL=chunk-
|
|
148
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
//# sourceMappingURL=chunk-E5USZ2MR.js.map
|
|
148
|
+
//# sourceMappingURL=chunk-E5USZ2MR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry/pino-redaction.ts","../src/telemetry/pino-logger.ts"],"names":["DEFAULT_REDACT_PATHS","Object","freeze","tryLoadPino","mod","candidate","default","PinoAdapter","BaseLogger","pino","level","console","debug","message","args","mergeArgs","info","warn","error","log","trace","out","arg","Error","stack","name","assign","undefined","createPinoLogger","cfg","pinoFactory","fallback","env","setContext","service","serviceName","version","redactPaths","base","redact","paths","censor","remove","timestamp","Date","toISOString","mixin","pickTraceFields","api","globalThis","__otelApi","anyApi","span","getActiveSpan","ctx","spanContext","trace_id","traceId","span_id","spanId","trace_flags","traceFlags","toString","padStart"],"mappings":"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","file":"chunk-SNEOLWXT.js","sourcesContent":["/**\n * Default Pino redact paths — covers the Burdenoff authorization +\n * gateway header + NATS/GraphQL payload surface area.\n *\n * Services can extend this list via their own Pino options.\n */\nexport const DEFAULT_REDACT_PATHS: readonly string[] = Object.freeze([\n 'password',\n '*.password',\n '*.*.password',\n 'token',\n 'authToken',\n 'workspaceToken',\n 'accessToken',\n 'refreshToken',\n 'clientSecret',\n 'apiKey',\n '*.apiKey',\n 'authorization',\n 'req.headers.authorization',\n 'req.headers[\"x-workspace-authorization\"]',\n 'req.headers.cookie',\n 'res.headers[\"set-cookie\"]',\n 'params.*.password',\n 'params.*.token',\n 'params.*.secret',\n]);\n","/**\n * Pino logger wrapper that emits structured JSON with trace/span correlation\n * fields. Falls back to the SDK's built-in Logger when `pino` isn't installed\n * so services without the peer dep still compile and run.\n */\nimport { Logger as BaseLogger } from '../logger/index.js';\nimport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\n\nexport interface PinoLoggerConfig {\n serviceName: string;\n env: 'alpha' | 'prod' | 'dev';\n version: string;\n /** Override Pino log level. Default: warn (prod), info (alpha/dev). */\n level?: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n /** Extra redact paths appended to DEFAULT_REDACT_PATHS. */\n redactPaths?: string[];\n}\n\ninterface PinoLike {\n level: string;\n fatal: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n debug: (...args: unknown[]) => void;\n trace: (...args: unknown[]) => void;\n child: (bindings: Record<string, unknown>) => PinoLike;\n}\n\nasync function tryLoadPino(): Promise<((opts: unknown) => PinoLike) | null> {\n try {\n const mod = (await import('pino')) as unknown as { default?: unknown };\n const candidate = (mod.default ?? mod) as unknown;\n if (typeof candidate === 'function') {\n return candidate as (opts: unknown) => PinoLike;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nclass PinoAdapter extends BaseLogger {\n constructor(private readonly pino: PinoLike) {\n super({\n level: (pino.level as BaseLogger['getLevel'] extends () => infer L ? L : never) ?? 'info',\n console: false,\n });\n }\n\n public override debug(message: string, ...args: unknown[]): void {\n this.pino.debug(this.mergeArgs(args), message);\n }\n public override info(message: string, ...args: unknown[]): void {\n this.pino.info(this.mergeArgs(args), message);\n }\n public override warn(message: string, ...args: unknown[]): void {\n this.pino.warn(this.mergeArgs(args), message);\n }\n public override error(message: string, ...args: unknown[]): void {\n this.pino.error(this.mergeArgs(args), message);\n }\n public override log(message: string, ...args: unknown[]): void {\n this.pino.info(this.mergeArgs(args), message);\n }\n public override trace(message: string, ...args: unknown[]): void {\n this.pino.trace(this.mergeArgs(args), message);\n }\n\n private mergeArgs(args: unknown[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const arg of args) {\n if (arg instanceof Error) {\n out['err'] = { message: arg.message, stack: arg.stack, name: arg.name };\n } else if (arg && typeof arg === 'object') {\n Object.assign(out, arg as Record<string, unknown>);\n } else if (arg !== undefined && arg !== null) {\n out['data'] = arg;\n }\n }\n return out;\n }\n}\n\n/**\n * Build a logger instance. Returns a Pino-backed adapter when `pino` is\n * installed; otherwise falls back to the SDK's built-in JSON Logger.\n *\n * Services call this through `bootstrapTelemetry`, not directly.\n */\nexport async function createPinoLogger(cfg: PinoLoggerConfig): Promise<BaseLogger> {\n const pinoFactory = await tryLoadPino();\n if (!pinoFactory) {\n // No pino — fall back to the built-in Logger with console output.\n const fallback = new BaseLogger({ level: cfg.env === 'prod' ? 'warn' : 'info', console: true });\n fallback.setContext({\n service: cfg.serviceName,\n env: cfg.env,\n version: cfg.version,\n } as unknown as import('../types/index.js').SDKContext);\n return fallback;\n }\n\n const redactPaths = [...DEFAULT_REDACT_PATHS, ...(cfg.redactPaths ?? [])];\n const pino = pinoFactory({\n name: cfg.serviceName,\n level: cfg.level ?? (cfg.env === 'prod' ? 'warn' : 'info'),\n base: {\n service: { name: cfg.serviceName, version: cfg.version },\n env: cfg.env,\n },\n redact: {\n paths: redactPaths,\n censor: '[REDACTED]',\n remove: false,\n },\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n mixin: () => pickTraceFields(),\n });\n return new PinoAdapter(pino);\n}\n\nfunction pickTraceFields(): Record<string, string> {\n try {\n // Pull active span context via @opentelemetry/api if installed.\n // Use require-style dynamic access to keep this file dep-free.\n const api = (globalThis as unknown as { __otelApi?: unknown }).__otelApi;\n if (!api) return {};\n const anyApi = api as {\n trace: {\n getActiveSpan: () => { spanContext: () => { traceId: string; spanId: string; traceFlags: number } } | undefined;\n };\n };\n const span = anyApi.trace.getActiveSpan();\n if (!span) return {};\n const ctx = span.spanContext();\n return {\n trace_id: ctx.traceId,\n span_id: ctx.spanId,\n trace_flags: ctx.traceFlags.toString(16).padStart(2, '0'),\n };\n } catch {\n return {};\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/telemetry/pino-redaction.ts","../src/telemetry/pino-logger.ts"],"names":["DEFAULT_REDACT_PATHS","Object","freeze","tryLoadPino","mod","candidate","default","PinoAdapter","BaseLogger","pino","level","console","debug","message","args","mergeArgs","info","warn","error","log","trace","out","arg","Error","stack","name","assign","undefined","createPinoLogger","cfg","pinoFactory","fallback","env","setContext","service","serviceName","version","redactPaths","base","redact","paths","censor","remove","timestamp","Date","toISOString","mixin","pickTraceFields","api","globalThis","__otelApi","anyApi","span","getActiveSpan","ctx","spanContext","trace_id","traceId","span_id","spanId","trace_flags","traceFlags","toString","padStart"],"mappings":"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","file":"chunk-E5USZ2MR.js","sourcesContent":["/**\n * Default Pino redact paths — covers the Burdenoff authorization +\n * gateway header + NATS/GraphQL payload surface area.\n *\n * Services can extend this list via their own Pino options.\n */\nexport const DEFAULT_REDACT_PATHS: readonly string[] = Object.freeze([\n 'password',\n '*.password',\n '*.*.password',\n 'token',\n 'authToken',\n 'workspaceToken',\n 'accessToken',\n 'refreshToken',\n 'clientSecret',\n 'apiKey',\n '*.apiKey',\n 'authorization',\n 'req.headers.authorization',\n 'req.headers[\"x-workspace-authorization\"]',\n 'req.headers.cookie',\n 'res.headers[\"set-cookie\"]',\n 'params.*.password',\n 'params.*.token',\n 'params.*.secret',\n]);\n","/**\n * Pino logger wrapper that emits structured JSON with trace/span correlation\n * fields. Falls back to the SDK's built-in Logger when `pino` isn't installed\n * so services without the peer dep still compile and run.\n */\nimport { Logger as BaseLogger } from '../logger/index.js';\nimport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\n\nexport interface PinoLoggerConfig {\n serviceName: string;\n env: 'alpha' | 'prod' | 'dev';\n version: string;\n /** Override Pino log level. Default: warn (prod), info (alpha/dev). */\n level?: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n /** Extra redact paths appended to DEFAULT_REDACT_PATHS. */\n redactPaths?: string[];\n}\n\ninterface PinoLike {\n level: string;\n fatal: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n debug: (...args: unknown[]) => void;\n trace: (...args: unknown[]) => void;\n child: (bindings: Record<string, unknown>) => PinoLike;\n}\n\nasync function tryLoadPino(): Promise<((opts: unknown) => PinoLike) | null> {\n try {\n const mod = (await import('pino')) as unknown as { default?: unknown };\n const candidate = (mod.default ?? mod) as unknown;\n if (typeof candidate === 'function') {\n return candidate as (opts: unknown) => PinoLike;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nclass PinoAdapter extends BaseLogger {\n constructor(private readonly pino: PinoLike) {\n super({\n level: (pino.level as BaseLogger['getLevel'] extends () => infer L ? L : never) ?? 'info',\n console: false,\n });\n }\n\n public override debug(message: string, ...args: unknown[]): void {\n this.pino.debug(this.mergeArgs(args), message);\n }\n public override info(message: string, ...args: unknown[]): void {\n this.pino.info(this.mergeArgs(args), message);\n }\n public override warn(message: string, ...args: unknown[]): void {\n this.pino.warn(this.mergeArgs(args), message);\n }\n public override error(message: string, ...args: unknown[]): void {\n this.pino.error(this.mergeArgs(args), message);\n }\n public override log(message: string, ...args: unknown[]): void {\n this.pino.info(this.mergeArgs(args), message);\n }\n public override trace(message: string, ...args: unknown[]): void {\n this.pino.trace(this.mergeArgs(args), message);\n }\n\n private mergeArgs(args: unknown[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const arg of args) {\n if (arg instanceof Error) {\n out['err'] = { message: arg.message, stack: arg.stack, name: arg.name };\n } else if (arg && typeof arg === 'object') {\n Object.assign(out, arg as Record<string, unknown>);\n } else if (arg !== undefined && arg !== null) {\n out['data'] = arg;\n }\n }\n return out;\n }\n}\n\n/**\n * Build a logger instance. Returns a Pino-backed adapter when `pino` is\n * installed; otherwise falls back to the SDK's built-in JSON Logger.\n *\n * Services call this through `bootstrapTelemetry`, not directly.\n */\nexport async function createPinoLogger(cfg: PinoLoggerConfig): Promise<BaseLogger> {\n const pinoFactory = await tryLoadPino();\n if (!pinoFactory) {\n // No pino — fall back to the built-in Logger with console output.\n const fallback = new BaseLogger({ level: cfg.env === 'prod' ? 'warn' : 'info', console: true });\n fallback.setContext({\n service: cfg.serviceName,\n env: cfg.env,\n version: cfg.version,\n });\n return fallback;\n }\n\n const redactPaths = [...DEFAULT_REDACT_PATHS, ...(cfg.redactPaths ?? [])];\n const pino = pinoFactory({\n name: cfg.serviceName,\n level: cfg.level ?? (cfg.env === 'prod' ? 'warn' : 'info'),\n base: {\n service: { name: cfg.serviceName, version: cfg.version },\n env: cfg.env,\n },\n redact: {\n paths: redactPaths,\n censor: '[REDACTED]',\n remove: false,\n },\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n mixin: () => pickTraceFields(),\n });\n return new PinoAdapter(pino);\n}\n\nfunction pickTraceFields(): Record<string, string> {\n try {\n // Pull active span context via @opentelemetry/api if installed.\n // Use require-style dynamic access to keep this file dep-free.\n const api = (globalThis as unknown as { __otelApi?: unknown }).__otelApi;\n if (!api) return {};\n const anyApi = api as {\n trace: {\n getActiveSpan: () => { spanContext: () => { traceId: string; spanId: string; traceFlags: number } } | undefined;\n };\n };\n const span = anyApi.trace.getActiveSpan();\n if (!span) return {};\n const ctx = span.spanContext();\n return {\n trace_id: ctx.traceId,\n span_id: ctx.spanId,\n trace_flags: ctx.traceFlags.toString(16).padStart(2, '0'),\n };\n } catch {\n return {};\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RedisStreamsConnection, isWildcard, streamKey, boundaryOf, dlqKey, registryKey, delayQueueKey, delayLockKey, dedupKey, replyKey, matchSubject } from './chunk-
|
|
1
|
+
import { RedisStreamsConnection, isWildcard, streamKey, boundaryOf, dlqKey, registryKey, delayQueueKey, delayLockKey, dedupKey, replyKey, matchSubject } from './chunk-MHNA7IS7.js';
|
|
2
2
|
import { logger } from './chunk-CBZNP6RF.js';
|
|
3
3
|
import { __name } from './chunk-XE4OXN2W.js';
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
@@ -277,6 +277,23 @@ var RedisStreamsEventConsumer = class {
|
|
|
277
277
|
const startId = this.resolveStartId(opts.options?.deliverPolicy);
|
|
278
278
|
const wildcard = isWildcard(opts.subject);
|
|
279
279
|
const handlerFn = opts.handler;
|
|
280
|
+
if (opts.options?.stream) {
|
|
281
|
+
const stream = streamKey(opts.options.stream, {
|
|
282
|
+
prefix: this.keyPrefix
|
|
283
|
+
});
|
|
284
|
+
await this.ensureGroup(stream, startId);
|
|
285
|
+
this.knownStreams.set(stream, opts.subject);
|
|
286
|
+
const subjectFilter = wildcard ? opts.subject : null;
|
|
287
|
+
const filteredHandler = subjectFilter ? async (evt) => {
|
|
288
|
+
if (matchSubject(subjectFilter, evt.subject)) {
|
|
289
|
+
await handlerFn(evt);
|
|
290
|
+
} else {
|
|
291
|
+
await evt.ack();
|
|
292
|
+
}
|
|
293
|
+
} : handlerFn;
|
|
294
|
+
this.spawnLoop(sub, stream, opts.subject, filteredHandler);
|
|
295
|
+
return sub;
|
|
296
|
+
}
|
|
280
297
|
if (!wildcard) {
|
|
281
298
|
const stream = streamKey(opts.subject, {
|
|
282
299
|
prefix: this.keyPrefix
|
|
@@ -709,7 +726,8 @@ var RedisStreamsEventPublisher = class {
|
|
|
709
726
|
async publishInternal(opts) {
|
|
710
727
|
await this.connect();
|
|
711
728
|
const client = this.connection.getClient();
|
|
712
|
-
const
|
|
729
|
+
const streamName = opts.options?.stream ?? opts.subject;
|
|
730
|
+
const stream = streamKey(streamName, {
|
|
713
731
|
prefix: this.keyPrefix
|
|
714
732
|
});
|
|
715
733
|
const msgId = opts.options?.messageId ?? randomUUID();
|
|
@@ -921,5 +939,5 @@ var EventQueueFactory = class _EventQueueFactory {
|
|
|
921
939
|
};
|
|
922
940
|
|
|
923
941
|
export { EventQueueFactory, QueueType, RedisStreamsEventConsumer, RedisStreamsEventPublisher, resolveQueueType };
|
|
924
|
-
//# sourceMappingURL=chunk-
|
|
925
|
-
//# sourceMappingURL=chunk-
|
|
942
|
+
//# sourceMappingURL=chunk-KGCISIBX.js.map
|
|
943
|
+
//# sourceMappingURL=chunk-KGCISIBX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/event-queue/implementations/redis-streams/trace-context.ts","../src/event-queue/implementations/redis-streams/RedisStreamsEventConsumer.ts","../src/event-queue/implementations/redis-streams/RedisStreamsEventPublisher.ts","../src/event-queue/types/config.ts","../src/event-queue/factory/EventQueueFactory.ts"],"names":["otelApiPromise","loadOtelApi","mod","logger","debug","TRACE_KEYS","injectTraceFields","api","carrier","propagation","inject","context","active","set","c","k","v","err","error","Error","message","String","extractTraceContext","fields","undefined","key","value","extract","get","keys","Object","runWithConsumerSpan","subject","handler","parentCtx","tracer","trace","getTracer","Promise","resolve","reject","startActiveSpan","kind","attributes","span","result","setStatus","code","end","recordException","DEFAULT_BLOCK_MS","DEFAULT_BATCH","REGISTRY_REFRESH_MS","DEFAULT_ACK_WAIT_MS","DEFAULT_MAX_DELIVER","SWEEP_INTERVAL_MS","DELAYQ_INTERVAL_MS","RedisStreamsSubscription","id","randomUUID","receivedCount","processedCount","failedCount","lastActivity","Date","toISOString","unsubscribeFn","unsubscribe","isActive","getStats","messagesReceived","messagesProcessed","messagesFailed","recordReceived","recordProcessed","recordFailed","RedisStreamsEventConsumer","connection","subscriptions","subscriptionLoops","Set","keyPrefix","consumerName","group","maxDeliver","ackWaitMs","maxConcurrent","consumedCount","stopped","sweepTimer","delayqTimer","knownStreams","Map","config","RedisStreamsConnection","type","url","process","env","user","password","name","connectionTimeout","consumer","hostname","pid","ackWait","Math","max","round","connect","t","setInterval","sweepPending","catch","unref","drainDelayQueues","disconnect","clearInterval","unsubscribeAll","isConnected","healthCheck","t0","now","pong","ping","status","timestamp","connected","latencyMs","details","length","getStatistics","messagesConsumed","messagesPublished","activeConsumers","ensureStream","_config","ensureConsumer","subscribe","opts","sub","filter","s","push","startId","resolveStartId","options","deliverPolicy","wildcard","isWildcard","handlerFn","stream","streamKey","prefix","ensureGroup","subjectFilter","filteredHandler","evt","matchSubject","ack","spawnLoop","boundary","boundaryOf","refresh","client","getClient","subjects","smembers","registryKey","has","subscribeMultiple","out","pull","raw","xreadgroup","batch","timeout","streamName","entries","rawFields","parsed","parseEntry","toAcknowledgeable","clear","getSubscriptions","processDLQ","dlqGroup","dlq","dlqKey","xgroup","res","listSubjects","_stream","seen","values","members","m","add","policy","msg","includes","loop","makeBlockingClient","warn","setTimeout","nak","i","val","data","JSON","parse","metadata","correlationId","deliveryCount","acked","xack","xdel","delay","score","payload","stringify","zadd","delayQueueKey","term","flat","xadd","isRedelivered","getDeliveryAttempt","size","claimed","xautoclaim","pending","xpending","Array","isArray","lockKey","delayLockKey","got","due","zrangebyscore","member","split","indexOf","slice","zrem","del","RedisStreamsEventPublisher","publishCount","lastPublishTime","maxLen","dedupTtl","parseInt","dedupTtlSeconds","activePublishers","publish","publishInternal","msgId","messageId","enableDedup","enableDeduplication","ok","dedupKey","priority","defaultPriority","source","userId","workspaceId","tenantId","sadd","publishBatch","events","e","publishWithAck","reply","replyKey","replyTo","timeoutMs","xrange","last","payloadIdx","sendReply","expire","QueueType","resolveQueueType","REDIS_STREAMS","EventQueueFactory","createPublisher","info","createConsumer","createPublisherFromEnv","createConsumerFromEnv","createPublisherForLayer","_layer","serviceName","createConsumerForLayer"],"mappings":"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","file":"chunk-KGCISIBX.js","sourcesContent":["/**\n * W3C trace context propagation for Redis Streams entries.\n *\n * Stream entries carry trace context as ordinary fields (`traceparent`,\n * `tracestate`, `baggage`). When `@opentelemetry/api` isn't installed at the\n * consumer, these helpers degrade to no-ops.\n */\nimport { logger } from '../../../logger/index.js';\n\ntype OtelApi = {\n propagation: {\n inject: (\n ctx: unknown,\n carrier: Record<string, string>,\n setter: { set: (c: Record<string, string>, k: string, v: string) => void }\n ) => void;\n extract: (\n ctx: unknown,\n carrier: Record<string, string>,\n getter: {\n get: (c: Record<string, string>, k: string) => string | undefined;\n keys: (c: Record<string, string>) => string[];\n }\n ) => unknown;\n };\n context: { active: () => unknown; with: <T>(ctx: unknown, fn: () => T) => T };\n trace: { getTracer: (name: string, version?: string) => { startActiveSpan: (...args: unknown[]) => unknown } };\n};\n\nlet otelApiPromise: Promise<OtelApi | null> | null = null;\n\nasync function loadOtelApi(): Promise<OtelApi | null> {\n if (otelApiPromise) return otelApiPromise;\n otelApiPromise = (async () => {\n try {\n const mod = (await import('@opentelemetry/api')) as unknown as OtelApi;\n return mod;\n } catch {\n logger.debug('[redis-streams/trace-context] @opentelemetry/api not available; tracing disabled');\n return null;\n }\n })();\n return otelApiPromise;\n}\n\nconst TRACE_KEYS = ['traceparent', 'tracestate', 'baggage'] as const;\n\n/** Inject the active OTel context into a plain record of stream fields. */\nexport async function injectTraceFields(): Promise<Record<string, string>> {\n const api = await loadOtelApi();\n if (!api) return {};\n const carrier: Record<string, string> = {};\n try {\n api.propagation.inject(api.context.active(), carrier, {\n set(c, k, v) {\n c[k] = v;\n },\n });\n } catch (err) {\n logger.debug('[redis-streams/trace-context] inject failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n return carrier;\n}\n\n/** Extract OTel context from stream-entry fields. */\nexport async function extractTraceContext(fields: Record<string, string>): Promise<unknown> {\n const api = await loadOtelApi();\n if (!api) return undefined;\n const carrier: Record<string, string> = {};\n for (const key of TRACE_KEYS) {\n const value = fields[key];\n if (value) carrier[key] = value;\n }\n try {\n return api.propagation.extract(api.context.active(), carrier, {\n get(c, k) {\n return c[k];\n },\n keys(c) {\n return Object.keys(c);\n },\n });\n } catch {\n return undefined;\n }\n}\n\n/** Wrap a consumer handler in a CONSUMER-kind span rooted at the carried trace. */\nexport async function runWithConsumerSpan<T>(\n subject: string,\n fields: Record<string, string>,\n handler: () => Promise<T>\n): Promise<T> {\n const api = await loadOtelApi();\n if (!api) return handler();\n try {\n const parentCtx = await extractTraceContext(fields);\n const tracer = api.trace.getTracer('@burdenoff/be-sdk/redis-streams');\n return await new Promise<T>((resolve, reject) => {\n tracer.startActiveSpan(\n `redis-streams.consume ${subject}`,\n {\n kind: 5,\n attributes: { 'messaging.system': 'redis', 'messaging.destination.name': subject },\n },\n parentCtx,\n async (span: {\n setStatus: (status: { code: number; message?: string }) => void;\n recordException: (err: Error) => void;\n end: () => void;\n }) => {\n try {\n const result = await handler();\n span.setStatus({ code: 1 });\n span.end();\n resolve(result);\n } catch (err) {\n span.recordException(err as Error);\n span.setStatus({ code: 2, message: err instanceof Error ? err.message : String(err) });\n span.end();\n reject(err);\n }\n }\n );\n });\n } catch {\n return handler();\n }\n}\n","/**\n * Redis Streams implementation of IEventConsumer.\n *\n * One ioredis client per active subscription handles `XREADGROUP BLOCK` in a\n * background loop, with periodic XAUTOCLAIM reclaiming abandoned pending\n * entries and a small ZSET-based delay queue draining NAK'd messages back\n * into the stream when their delay expires.\n */\nimport { randomUUID } from 'node:crypto';\nimport { hostname } from 'node:os';\nimport { logger } from '../../../logger/index.js';\nimport type { IEventConsumer, ISubscription } from '../../interfaces/IEventConsumer.js';\nimport type { ConsumerConfig, EventQueueHealthCheckResult, QueueStatistics } from '../../types/config.js';\nimport type {\n AcknowledgeableEvent,\n EventHandler,\n EventMetadata,\n StreamConfig,\n SubscriptionOptions,\n} from '../../types/events.js';\nimport { RedisStreamsConnection, type IoRedis } from './RedisStreamsConnection.js';\nimport {\n boundaryOf,\n delayLockKey,\n delayQueueKey,\n dlqKey,\n isWildcard,\n matchSubject,\n registryKey,\n streamKey,\n} from './keyspace.js';\nimport { runWithConsumerSpan } from './trace-context.js';\n\ninterface ParsedEntry<T = unknown> {\n id: string;\n stream: string;\n subject: string;\n data: T;\n metadata: EventMetadata;\n timestamp: string;\n fields: Record<string, string>;\n deliveryCount: number;\n}\n\nconst DEFAULT_BLOCK_MS = 5000;\nconst DEFAULT_BATCH = 10;\nconst REGISTRY_REFRESH_MS = 10_000;\nconst DEFAULT_ACK_WAIT_MS = 30_000;\nconst DEFAULT_MAX_DELIVER = 3;\nconst SWEEP_INTERVAL_MS = 15_000;\nconst DELAYQ_INTERVAL_MS = 1_000;\n\nclass RedisStreamsSubscription implements ISubscription {\n readonly id = randomUUID();\n private active = true;\n private receivedCount = 0;\n private processedCount = 0;\n private failedCount = 0;\n private lastActivity = new Date().toISOString();\n\n constructor(\n readonly subject: string,\n private readonly unsubscribeFn: () => Promise<void>\n ) {}\n\n async unsubscribe(): Promise<void> {\n if (!this.active) return;\n this.active = false;\n await this.unsubscribeFn();\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n getStats(): {\n messagesReceived: number;\n messagesProcessed: number;\n messagesFailed: number;\n lastActivity: string;\n } {\n return {\n messagesReceived: this.receivedCount,\n messagesProcessed: this.processedCount,\n messagesFailed: this.failedCount,\n lastActivity: this.lastActivity,\n };\n }\n\n recordReceived(): void {\n this.receivedCount++;\n this.lastActivity = new Date().toISOString();\n }\n recordProcessed(): void {\n this.processedCount++;\n this.lastActivity = new Date().toISOString();\n }\n recordFailed(): void {\n this.failedCount++;\n this.lastActivity = new Date().toISOString();\n }\n}\n\nexport interface RedisStreamsConsumerConfig extends ConsumerConfig {\n keyPrefix?: string;\n}\n\nexport class RedisStreamsEventConsumer implements IEventConsumer {\n private readonly connection: RedisStreamsConnection;\n private subscriptions: RedisStreamsSubscription[] = [];\n private readonly subscriptionLoops: Set<() => Promise<void>> = new Set();\n private readonly keyPrefix: string;\n private readonly consumerName: string;\n private readonly group: string;\n private readonly maxDeliver: number;\n private readonly ackWaitMs: number;\n private readonly maxConcurrent: number;\n private consumedCount = 0;\n private failedCount = 0;\n private lastActivity: Date | null = null;\n private stopped = false;\n private sweepTimer: ReturnType<typeof setInterval> | null = null;\n private delayqTimer: ReturnType<typeof setInterval> | null = null;\n private knownStreams: Map<string, string> = new Map(); // streamKey -> subject\n\n constructor(config: RedisStreamsConsumerConfig) {\n this.connection = new RedisStreamsConnection({\n type: 'redis-streams',\n url: config.url ?? process.env['REDIS_URL'] ?? 'redis://localhost:6379',\n user: config.user,\n password: config.password,\n name: config.name,\n connectionTimeout: config.connectionTimeout,\n });\n this.keyPrefix = config.keyPrefix ?? process.env['REDIS_STREAMS_KEY_PREFIX'] ?? 'boff:events';\n this.group = config.consumer || config.name || 'default-consumer';\n this.consumerName = `${this.group}:${hostname()}:${process.pid}`;\n this.maxDeliver = config.maxDeliver ?? DEFAULT_MAX_DELIVER;\n this.ackWaitMs = config.ackWait ? Math.max(1000, Math.round(config.ackWait / 1_000_000)) : DEFAULT_ACK_WAIT_MS;\n this.maxConcurrent = config.maxConcurrent ?? 5;\n }\n\n async connect(): Promise<void> {\n await this.connection.connect();\n if (!this.sweepTimer) {\n const t = setInterval(() => {\n void this.sweepPending().catch((err) => {\n logger.debug('[RedisStreamsEventConsumer] sweep error', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }, SWEEP_INTERVAL_MS);\n t.unref?.();\n this.sweepTimer = t;\n }\n if (!this.delayqTimer) {\n const t = setInterval(() => {\n void this.drainDelayQueues().catch(() => undefined);\n }, DELAYQ_INTERVAL_MS);\n t.unref?.();\n this.delayqTimer = t;\n }\n }\n\n async disconnect(): Promise<void> {\n this.stopped = true;\n if (this.sweepTimer) clearInterval(this.sweepTimer);\n if (this.delayqTimer) clearInterval(this.delayqTimer);\n await this.unsubscribeAll();\n await this.connection.disconnect();\n }\n\n isConnected(): boolean {\n return this.connection.isConnected();\n }\n\n async healthCheck(): Promise<EventQueueHealthCheckResult> {\n try {\n const t0 = Date.now();\n const pong = await this.connection.ping();\n return {\n status: pong === 'PONG' ? 'healthy' : 'degraded',\n timestamp: new Date().toISOString(),\n connected: this.isConnected(),\n latencyMs: Date.now() - t0,\n details: {\n type: 'redis-streams',\n subscriptions: this.subscriptions.length,\n },\n };\n } catch (err) {\n return {\n status: 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: false,\n details: { type: 'redis-streams' },\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n async getStatistics(): Promise<QueueStatistics> {\n return Promise.resolve({\n messagesConsumed: this.consumedCount,\n messagesFailed: this.failedCount,\n messagesPublished: 0,\n activeConsumers: this.subscriptions.length,\n lastActivity: this.lastActivity?.toISOString() ?? null,\n details: { type: 'redis-streams', group: this.group },\n });\n }\n\n async ensureStream(_config: StreamConfig): Promise<void> {\n return Promise.resolve();\n }\n\n async ensureConsumer(_config: ConsumerConfig): Promise<void> {\n return Promise.resolve();\n }\n\n async subscribe<T = unknown>(opts: {\n subject: string;\n handler: EventHandler<T>;\n options?: SubscriptionOptions;\n }): Promise<ISubscription> {\n await this.connect();\n const sub = new RedisStreamsSubscription(opts.subject, async () => {\n this.subscriptions = this.subscriptions.filter((s) => s !== sub);\n });\n this.subscriptions.push(sub);\n\n const startId = this.resolveStartId(opts.options?.deliverPolicy);\n const wildcard = isWildcard(opts.subject);\n const handlerFn = opts.handler as EventHandler<unknown>;\n\n // When the caller provides an explicit stream name (e.g. 'WSPACE_GRAPH_EVENTS'),\n // pin the consumer to that single aggregated stream and filter by subject locally.\n // This mirrors the publisher's stream override logic so both sides use the same key.\n if (opts.options?.stream) {\n const stream = streamKey(opts.options.stream, { prefix: this.keyPrefix });\n await this.ensureGroup(stream, startId);\n this.knownStreams.set(stream, opts.subject);\n const subjectFilter = wildcard ? opts.subject : null;\n const filteredHandler: EventHandler<unknown> = subjectFilter\n ? async (evt) => {\n if (matchSubject(subjectFilter, evt.subject)) {\n await handlerFn(evt);\n } else {\n await evt.ack();\n }\n }\n : handlerFn;\n this.spawnLoop(sub, stream, opts.subject, filteredHandler);\n return sub;\n }\n\n if (!wildcard) {\n const stream = streamKey(opts.subject, { prefix: this.keyPrefix });\n await this.ensureGroup(stream, startId);\n this.knownStreams.set(stream, opts.subject);\n this.spawnLoop(sub, stream, opts.subject, handlerFn);\n } else {\n const boundary = boundaryOf(opts.subject);\n const refresh = async (): Promise<void> => {\n const client = this.connection.getClient();\n const subjects = await client.smembers(registryKey(boundary));\n for (const s of subjects) {\n if (!matchSubject(opts.subject, s)) continue;\n const stream = streamKey(s, { prefix: this.keyPrefix });\n if (this.knownStreams.has(stream)) continue;\n await this.ensureGroup(stream, startId);\n this.knownStreams.set(stream, s);\n this.spawnLoop(sub, stream, s, handlerFn);\n }\n };\n await refresh();\n const t = setInterval(() => {\n if (this.stopped || !sub.isActive()) {\n clearInterval(t);\n return;\n }\n void refresh().catch(() => undefined);\n }, REGISTRY_REFRESH_MS);\n t.unref?.();\n }\n\n return sub;\n }\n\n async subscribeMultiple<T = unknown>(\n subjects: string[],\n handler: EventHandler<T>,\n options?: SubscriptionOptions\n ): Promise<ISubscription[]> {\n const out: ISubscription[] = [];\n for (const subject of subjects) {\n out.push(await this.subscribe({ subject, handler, options }));\n }\n return out;\n }\n\n async pull<T = unknown>(opts: {\n subject: string;\n batch?: number;\n timeout?: number;\n }): Promise<AcknowledgeableEvent<T>[]> {\n await this.connect();\n const stream = streamKey(opts.subject, { prefix: this.keyPrefix });\n await this.ensureGroup(stream, '$');\n const client = this.connection.getClient();\n const raw = (await client.xreadgroup(\n 'GROUP',\n this.group,\n this.consumerName,\n 'COUNT',\n opts.batch ?? DEFAULT_BATCH,\n 'BLOCK',\n opts.timeout ?? DEFAULT_BLOCK_MS,\n 'STREAMS',\n stream,\n '>'\n )) as Array<[string, Array<[string, string[]]>]> | null;\n if (!raw) return [];\n const out: AcknowledgeableEvent<T>[] = [];\n for (const [streamName, entries] of raw) {\n for (const [id, rawFields] of entries) {\n const parsed = this.parseEntry<T>(streamName, id, rawFields);\n out.push(this.toAcknowledgeable(streamName, id, parsed));\n }\n }\n return out;\n }\n\n async unsubscribeAll(): Promise<void> {\n for (const sub of [...this.subscriptions]) {\n await sub.unsubscribe();\n }\n this.subscriptions = [];\n this.subscriptionLoops.clear();\n }\n\n getSubscriptions(): ISubscription[] {\n return [...this.subscriptions];\n }\n\n async processDLQ<T = unknown>(handler: EventHandler<T>): Promise<void> {\n await this.connect();\n const client = this.connection.getClient();\n const dlqGroup = `${this.group}-dlq`;\n for (const [stream] of this.knownStreams) {\n const dlq = dlqKey(stream);\n try {\n await client.xgroup('CREATE', dlq, dlqGroup, '0', 'MKSTREAM');\n } catch {\n /* already exists */\n }\n const res = (await client.xreadgroup(\n 'GROUP',\n dlqGroup,\n this.consumerName,\n 'COUNT',\n 50,\n 'BLOCK',\n 100,\n 'STREAMS',\n dlq,\n '>'\n )) as Array<[string, Array<[string, string[]]>]> | null;\n if (!res) continue;\n for (const [, entries] of res) {\n for (const [id, rawFields] of entries) {\n const parsed = this.parseEntry<T>(dlq, id, rawFields);\n const evt = this.toAcknowledgeable<T>(dlq, id, parsed, dlqGroup);\n try {\n await handler(evt);\n } catch (err) {\n logger.error('[RedisStreamsEventConsumer] DLQ handler error', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n }\n }\n\n async listSubjects(_stream?: string): Promise<string[]> {\n await this.connect();\n const client = this.connection.getClient();\n const seen = new Set<string>();\n for (const subject of this.knownStreams.values()) {\n const members = await client.smembers(registryKey(boundaryOf(subject)));\n for (const m of members) seen.add(m);\n }\n return [...seen];\n }\n\n // ---- internals ----\n\n private resolveStartId(policy: SubscriptionOptions['deliverPolicy'] | undefined): string {\n switch (policy) {\n case 'all':\n return '0';\n case 'new':\n return '$';\n case 'last':\n return '$';\n default:\n return '$';\n }\n }\n\n private async ensureGroup(stream: string, startId: string): Promise<void> {\n const client = this.connection.getClient();\n try {\n await client.xgroup('CREATE', stream, this.group, startId, 'MKSTREAM');\n logger.debug('[RedisStreamsEventConsumer] group created', {\n stream,\n group: this.group,\n startId,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!msg.includes('BUSYGROUP')) {\n throw err;\n }\n }\n }\n\n private spawnLoop(\n sub: RedisStreamsSubscription,\n stream: string,\n subject: string,\n handler: EventHandler<unknown>\n ): void {\n const loop = async (): Promise<void> => {\n const client = await this.connection.makeBlockingClient();\n try {\n while (!this.stopped && sub.isActive()) {\n let raw: Array<[string, Array<[string, string[]]>]> | null = null;\n try {\n raw = (await client.xreadgroup(\n 'GROUP',\n this.group,\n this.consumerName,\n 'COUNT',\n this.maxConcurrent,\n 'BLOCK',\n DEFAULT_BLOCK_MS,\n 'STREAMS',\n stream,\n '>'\n )) as Array<[string, Array<[string, string[]]>]> | null;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes('NOGROUP')) {\n await this.ensureGroup(stream, '$');\n continue;\n }\n logger.warn('[RedisStreamsEventConsumer] read error', { stream, error: msg });\n await new Promise((res) => setTimeout(res, 1000));\n continue;\n }\n if (!raw) continue;\n for (const [, entries] of raw) {\n for (const [id, rawFields] of entries) {\n sub.recordReceived();\n this.consumedCount++;\n this.lastActivity = new Date();\n const parsed = this.parseEntry(stream, id, rawFields);\n const evt = this.toAcknowledgeable(stream, id, parsed);\n try {\n await runWithConsumerSpan(subject, parsed.fields, () => handler(evt));\n sub.recordProcessed();\n } catch (err) {\n sub.recordFailed();\n this.failedCount++;\n logger.error('[RedisStreamsEventConsumer] handler error', {\n subject,\n id,\n error: err instanceof Error ? err.message : String(err),\n });\n // Auto-nak on uncaught throw (re-deliver after ackWait).\n try {\n await evt.nak();\n } catch {\n /* ignore */\n }\n }\n }\n }\n }\n } finally {\n try {\n client.disconnect();\n } catch {\n /* ignore */\n }\n }\n };\n void loop().catch((err) => {\n logger.error('[RedisStreamsEventConsumer] loop crashed', {\n stream,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }\n\n private parseEntry<T>(stream: string, id: string, rawFields: string[]): ParsedEntry<T> {\n const fields: Record<string, string> = {};\n for (let i = 0; i + 1 < rawFields.length; i += 2) {\n const key = rawFields[i];\n const val = rawFields[i + 1];\n if (key === undefined || val === undefined) continue;\n fields[key] = val;\n }\n let data: T;\n try {\n data = JSON.parse(fields['payload'] ?? 'null') as T;\n } catch {\n data = fields['payload'] as unknown as T;\n }\n let metadata: EventMetadata;\n try {\n metadata = JSON.parse(fields['metadata'] ?? '{}') as EventMetadata;\n } catch {\n metadata = { correlationId: fields['correlation-id'] ?? '' };\n }\n if (!metadata.correlationId) metadata.correlationId = fields['correlation-id'] ?? '';\n return {\n id,\n stream,\n subject: fields['subject'] ?? '',\n data,\n metadata,\n timestamp: fields['timestamp'] ?? new Date().toISOString(),\n fields,\n deliveryCount: 1,\n };\n }\n\n private toAcknowledgeable<T>(\n stream: string,\n id: string,\n parsed: ParsedEntry<T>,\n group: string = this.group\n ): AcknowledgeableEvent<T> {\n const connection = this.connection;\n let acked = false;\n return {\n id,\n subject: parsed.subject,\n data: parsed.data,\n metadata: parsed.metadata,\n timestamp: parsed.timestamp,\n async ack(): Promise<void> {\n if (acked) return;\n acked = true;\n const client = connection.getClient();\n await client.xack(stream, group, id);\n await client.xdel(stream, id).catch(() => undefined);\n },\n async nak(delay = 0): Promise<void> {\n if (acked) return;\n acked = true;\n const client = connection.getClient();\n if (delay > 0) {\n // Park in delay queue; worker will re-XADD and ACK original.\n const score = Date.now() + delay;\n const payload = JSON.stringify(parsed.fields);\n await client.zadd(delayQueueKey(stream), score, `${id}|${payload}`);\n await client.xack(stream, group, id);\n await client.xdel(stream, id).catch(() => undefined);\n }\n // delay=0: do nothing — XAUTOCLAIM will reclaim after ackWait.\n },\n async term(): Promise<void> {\n if (acked) return;\n acked = true;\n const client = connection.getClient();\n const dlq = dlqKey(stream);\n const flat: string[] = [];\n for (const [k, v] of Object.entries(parsed.fields)) flat.push(k, v);\n await client.xadd(dlq, 'MAXLEN', '~', 10_000, '*', ...flat);\n await client.xack(stream, group, id);\n await client.xdel(stream, id).catch(() => undefined);\n },\n isRedelivered(): boolean {\n return parsed.deliveryCount > 1;\n },\n getDeliveryAttempt(): number {\n return parsed.deliveryCount;\n },\n };\n }\n\n private async sweepPending(): Promise<void> {\n if (this.stopped || this.knownStreams.size === 0) return;\n const client = this.connection.getClient();\n for (const [stream] of this.knownStreams) {\n try {\n const claimed = (await client.xautoclaim(\n stream,\n this.group,\n this.consumerName,\n this.ackWaitMs,\n '0',\n 'COUNT',\n 50\n )) as [string, Array<[string, string[]]>, string[]] | null;\n if (!claimed) continue;\n const entries = claimed[1] ?? [];\n for (const [id, rawFields] of entries) {\n const pending = (await client.xpending(\n stream,\n this.group,\n 'IDLE',\n 0,\n '-',\n '+',\n 1,\n this.consumerName\n )) as Array<[string, string, number, number]>;\n const deliveryCount = Array.isArray(pending) && pending[0] ? pending[0][3] : 1;\n if (deliveryCount > this.maxDeliver) {\n const flat: string[] = [];\n for (let i = 0; i + 1 < rawFields.length; i += 2) {\n flat.push(rawFields[i]!, rawFields[i + 1]!);\n }\n flat.push('dlq-reason', 'max-deliver-exceeded');\n flat.push('dlq-deliveries', String(deliveryCount));\n await client.xadd(dlqKey(stream), 'MAXLEN', '~', 10_000, '*', ...flat);\n await client.xack(stream, this.group, id);\n await client.xdel(stream, id).catch(() => undefined);\n logger.warn('[RedisStreamsEventConsumer] message moved to DLQ', {\n stream,\n id,\n deliveryCount,\n });\n }\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes('NOGROUP')) continue;\n logger.debug('[RedisStreamsEventConsumer] sweep iteration error', { stream, error: msg });\n }\n }\n }\n\n private async drainDelayQueues(): Promise<void> {\n if (this.stopped || this.knownStreams.size === 0) return;\n const client = this.connection.getClient();\n for (const [stream] of this.knownStreams) {\n const lockKey = delayLockKey(stream);\n const got = await client.set(lockKey, this.consumerName, 'NX', 'EX', 30).catch(() => null);\n if (got !== 'OK') continue;\n try {\n const due = await client.zrangebyscore(delayQueueKey(stream), 0, Date.now(), 'LIMIT', 0, 50);\n for (const member of due) {\n const split = member.indexOf('|');\n if (split < 0) continue;\n const payload = member.slice(split + 1);\n let fields: Record<string, string> = {};\n try {\n fields = JSON.parse(payload) as Record<string, string>;\n } catch {\n continue;\n }\n const flat: string[] = [];\n for (const [k, v] of Object.entries(fields)) flat.push(k, v);\n await client.xadd(stream, 'MAXLEN', '~', 100_000, '*', ...flat);\n await client.zrem(delayQueueKey(stream), member);\n }\n } finally {\n await client.del(lockKey).catch(() => undefined);\n }\n }\n }\n}\n\nexport type { IoRedis };\n","/**\n * Redis Streams implementation of IEventPublisher.\n *\n * Each subject is its own stream (`boff:events:<subject-with-colons>`); MAXLEN\n * trimming keeps each stream bounded; dedup is enforced by `SET NX EX` on a\n * per-message-id key before XADD.\n */\nimport { randomUUID } from 'node:crypto';\nimport { logger } from '../../../logger/index.js';\nimport type { IEventPublisher, PublishOptions } from '../../interfaces/IEventPublisher.js';\nimport type { PublisherConfig, EventQueueHealthCheckResult, QueueStatistics } from '../../types/config.js';\nimport type { EventMetadata, StreamConfig } from '../../types/events.js';\nimport { RedisStreamsConnection, type IoRedis } from './RedisStreamsConnection.js';\nimport { boundaryOf, dedupKey, registryKey, replyKey, streamKey } from './keyspace.js';\nimport { injectTraceFields } from './trace-context.js';\n\nexport interface RedisStreamsPublisherConfig extends PublisherConfig {\n /** Approximate MAXLEN trim threshold per stream. Default 100_000. */\n maxLen?: number;\n /** Dedup TTL window in seconds. Default 120. */\n dedupTtlSeconds?: number;\n /** Key namespace override. Default `boff:events`. */\n keyPrefix?: string;\n}\n\nexport class RedisStreamsEventPublisher implements IEventPublisher {\n private connection: RedisStreamsConnection;\n private publishCount = 0;\n private lastPublishTime: Date | null = null;\n private readonly maxLen: number;\n private readonly dedupTtl: number;\n private readonly keyPrefix: string;\n\n constructor(private config: RedisStreamsPublisherConfig) {\n this.connection = new RedisStreamsConnection(config);\n this.maxLen = config.maxLen ?? parseInt(process.env['REDIS_STREAMS_MAXLEN'] ?? '100000', 10);\n this.dedupTtl = config.dedupTtlSeconds ?? parseInt(process.env['REDIS_STREAMS_DEDUP_TTL'] ?? '120', 10);\n this.keyPrefix = config.keyPrefix ?? process.env['REDIS_STREAMS_KEY_PREFIX'] ?? 'boff:events';\n }\n\n async connect(): Promise<void> {\n await this.connection.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.connection.disconnect();\n }\n\n isConnected(): boolean {\n return this.connection.isConnected();\n }\n\n async healthCheck(): Promise<EventQueueHealthCheckResult> {\n try {\n const t0 = Date.now();\n const pong = await this.connection.ping();\n return {\n status: pong === 'PONG' ? 'healthy' : 'degraded',\n timestamp: new Date().toISOString(),\n connected: this.isConnected(),\n latencyMs: Date.now() - t0,\n details: { type: 'redis-streams', url: this.config.url },\n };\n } catch (err) {\n return {\n status: 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: false,\n details: { type: 'redis-streams' },\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n async getStatistics(): Promise<QueueStatistics> {\n return {\n messagesPublished: this.publishCount,\n messagesConsumed: 0,\n messagesFailed: 0,\n activePublishers: 1,\n activeConsumers: 0,\n lastActivity: this.lastPublishTime?.toISOString() ?? null,\n details: { type: 'redis-streams' },\n };\n }\n\n async ensureStream(_config: StreamConfig): Promise<void> {\n // Streams are created lazily by XADD; no-op here.\n return Promise.resolve();\n }\n\n async publish<T = unknown>(options: {\n subject: string;\n data: T;\n metadata?: Partial<EventMetadata>;\n options?: PublishOptions;\n }): Promise<number | string> {\n return this.publishInternal(options);\n }\n\n private async publishInternal<T>(opts: {\n subject: string;\n data: T;\n metadata?: Partial<EventMetadata>;\n options?: PublishOptions;\n }): Promise<string> {\n await this.connect();\n const client = this.connection.getClient();\n // When the caller provides an explicit stream name (e.g. 'WSPACE_GRAPH_EVENTS'),\n // use it as the Redis stream key so all events land in one aggregated stream that\n // a single consumer can read. Fall back to the per-subject stream when no override.\n const streamName = opts.options?.stream ?? opts.subject;\n const stream = streamKey(streamName, { prefix: this.keyPrefix });\n const msgId = opts.options?.messageId ?? randomUUID();\n const correlationId = opts.metadata?.correlationId ?? randomUUID();\n const enableDedup = this.config.enableDeduplication === true || opts.options?.messageId !== undefined;\n\n if (enableDedup) {\n const ok = await client.set(dedupKey(stream, msgId), '1', 'NX', 'EX', this.dedupTtl);\n if (ok !== 'OK') {\n logger.debug('[RedisStreamsEventPublisher] dedup hit; skipping publish', {\n subject: opts.subject,\n msgId,\n });\n return msgId;\n }\n }\n\n const trace = await injectTraceFields();\n const fields: Record<string, string> = {\n 'msg-id': msgId,\n subject: opts.subject,\n 'correlation-id': correlationId,\n timestamp: new Date().toISOString(),\n priority: opts.options?.priority ?? this.config.defaultPriority ?? 'normal',\n source: opts.metadata?.source ?? this.config.name ?? 'unknown',\n payload: JSON.stringify(opts.data ?? null),\n metadata: JSON.stringify(opts.metadata ?? {}),\n ...trace,\n };\n if (opts.metadata?.userId) fields['user-id'] = String(opts.metadata.userId);\n if (opts.metadata?.workspaceId) fields['workspace-id'] = String(opts.metadata.workspaceId);\n if (opts.metadata?.tenantId) fields['tenant-id'] = String(opts.metadata.tenantId);\n\n const flat: string[] = [];\n for (const [k, v] of Object.entries(fields)) {\n flat.push(k, v);\n }\n\n const id = await client.xadd(stream, 'MAXLEN', '~', this.maxLen, '*', ...flat);\n\n // Async fire-and-forget registry update\n void client.sadd(registryKey(boundaryOf(opts.subject)), opts.subject).catch(() => undefined);\n\n this.publishCount++;\n this.lastPublishTime = new Date();\n logger.debug('[RedisStreamsEventPublisher] published', {\n subject: opts.subject,\n stream,\n id,\n });\n return id;\n }\n\n async publishBatch<T = unknown>(\n events: Array<{\n subject: string;\n data: T;\n metadata?: Partial<EventMetadata>;\n options?: PublishOptions;\n }>\n ): Promise<Array<number | string>> {\n const out: string[] = [];\n for (const e of events) {\n out.push(await this.publishInternal(e));\n }\n return out;\n }\n\n /**\n * Emulated request/response: writer XADDs onto its own subject, then\n * blocks on a one-shot reply stream keyed by correlationId.\n */\n async publishWithAck<T = unknown, R = unknown>(opts: {\n subject: string;\n data: T;\n metadata?: Partial<EventMetadata>;\n timeout?: number;\n }): Promise<R> {\n await this.connect();\n const client = this.connection.getClient();\n const correlationId = opts.metadata?.correlationId ?? randomUUID();\n const reply = replyKey(correlationId);\n await this.publishInternal({\n subject: opts.subject,\n data: opts.data,\n metadata: { ...opts.metadata, correlationId, replyTo: reply },\n });\n\n const timeoutMs = opts.timeout ?? 5000;\n const t0 = Date.now();\n while (Date.now() - t0 < timeoutMs) {\n const entries = (await client.xrange(reply, '-', '+')) as Array<[string, string[]]>;\n if (Array.isArray(entries) && entries.length > 0) {\n const last = entries[entries.length - 1];\n if (!last) break;\n const rawFields = last[1];\n const payloadIdx = rawFields.indexOf('payload');\n const payload = payloadIdx >= 0 ? rawFields[payloadIdx + 1] : '{}';\n await client.del(reply);\n return JSON.parse(payload ?? '{}') as R;\n }\n await new Promise((res) => setTimeout(res, 50));\n }\n await client.del(reply).catch(() => undefined);\n throw new Error(`[RedisStreamsEventPublisher] publishWithAck timed out for subject=${opts.subject}`);\n }\n\n /** Internal helper used by the consumer's reply path. */\n async sendReply(correlationId: string, data: unknown): Promise<void> {\n await this.connect();\n const client = this.connection.getClient();\n const key = replyKey(correlationId);\n await client.xadd(key, '*', 'payload', JSON.stringify(data ?? null));\n await client.expire(key, 60);\n }\n}\n\nexport type { IoRedis };\n","/**\n * Event Queue Configuration Types\n */\n\n/**\n * Queue type enum\n */\nexport enum QueueType {\n REDIS_STREAMS = 'redis-streams',\n RABBITMQ = 'rabbitmq',\n KAFKA = 'kafka',\n SQS = 'sqs',\n}\n\n/**\n * Base configuration for event queue\n */\nexport interface BaseQueueConfig {\n /** Queue type */\n type: QueueType | string;\n /** Connection URL */\n url: string;\n /** Optional username */\n user?: string;\n /** Optional password */\n password?: string;\n /** Optional auth token */\n token?: string;\n /** Optional credentials file contents (auth payload for the backend) */\n creds?: string;\n /** Optional path to a credentials file */\n credsFile?: string;\n /** Maximum reconnection attempts (-1 for infinite) */\n maxReconnectAttempts?: number;\n /** Time to wait between reconnection attempts (ms) */\n reconnectTimeWait?: number;\n /** Connection timeout (ms) */\n connectionTimeout?: number;\n /** Connection name/identifier */\n name?: string;\n}\n\n/**\n * Publisher-specific configuration\n */\nexport interface PublisherConfig extends BaseQueueConfig {\n /** Default message TTL (ms) */\n defaultTTL?: number;\n /** Enable message deduplication */\n enableDeduplication?: boolean;\n /** Default priority for messages */\n defaultPriority?: 'low' | 'normal' | 'high';\n}\n\n/**\n * Consumer-specific configuration\n */\nexport interface ConsumerConfig extends Partial<BaseQueueConfig> {\n /** Stream name to consume from */\n stream: string;\n /** Consumer name (durable) */\n consumer: string;\n /** Subject filter pattern */\n filterSubject?: string;\n /** Maximum concurrent message processing */\n maxConcurrent?: number;\n /** Maximum delivery attempts */\n maxDeliver?: number;\n /** Acknowledgment wait time (nanoseconds) */\n ackWait?: number;\n /** Acknowledgment policy */\n ackPolicy?: 'explicit' | 'all' | 'none';\n /** Delivery policy */\n deliverPolicy?: 'all' | 'last' | 'new' | 'byStartSequence' | 'byStartTime';\n /** Maximum pending acknowledgments */\n maxAckPending?: number;\n}\n\n/**\n * Health check result\n */\nexport interface EventQueueHealthCheckResult {\n /** Overall health status */\n status: 'healthy' | 'unhealthy' | 'degraded';\n /** Timestamp of health check */\n timestamp: string;\n /** Connection status */\n connected?: boolean;\n /** Latency in milliseconds */\n latencyMs?: number;\n /** Additional details */\n details?: Record<string, unknown>;\n /** Error message if unhealthy */\n error?: string;\n}\n\n/**\n * Statistics\n */\nexport interface QueueStatistics {\n /** Total messages published */\n messagesPublished?: number;\n /** Total messages consumed */\n messagesConsumed?: number;\n /** Messages currently pending */\n messagesPending?: number;\n /** Messages in queue */\n queueSize?: number;\n /** Failed message count */\n messagesFailed?: number;\n /** Active consumers count */\n activeConsumers?: number;\n /** Active publishers count */\n activePublishers?: number;\n /** Average processing time (ms) */\n avgProcessingTimeMs?: number;\n /** Last activity timestamp */\n lastActivity?: string | null;\n /** Custom metrics */\n details?: Record<string, unknown>;\n}\n","/**\n * Event Queue Factory\n *\n * Single-backend wrapper around the Redis Streams publisher/consumer.\n * NATS support was removed on 2026-05-16 — Redis is the canonical fleet\n * event-bus. Other backends (RabbitMQ, Kafka, SQS) are listed in\n * `QueueType` for future extension; today only `redis-streams` is wired.\n */\nimport { logger } from '../../logger/index.js';\nimport type { ServiceLayer } from '../../types/layer.js';\n\nimport { RedisStreamsEventConsumer } from '../implementations/redis-streams/RedisStreamsEventConsumer.js';\nimport { RedisStreamsEventPublisher } from '../implementations/redis-streams/RedisStreamsEventPublisher.js';\nimport type { IEventConsumer } from '../interfaces/IEventConsumer.js';\nimport type { IEventPublisher } from '../interfaces/IEventPublisher.js';\nimport { type ConsumerConfig, type PublisherConfig, QueueType } from '../types/config.js';\n\nfunction resolveQueueType(): QueueType {\n // Kept for the API contract — always returns REDIS_STREAMS now.\n return QueueType.REDIS_STREAMS;\n}\n\n/**\n * Factory for creating event queue instances\n */\nexport class EventQueueFactory {\n /**\n * Create an event publisher based on configuration\n */\n static createPublisher(config: PublisherConfig): IEventPublisher {\n logger.info('[EventQueueFactory] Creating event publisher', {\n type: config.type,\n url: config.url,\n });\n\n if (config.type === QueueType.REDIS_STREAMS) {\n return new RedisStreamsEventPublisher(config);\n }\n\n throw new Error(`Unsupported queue type: ${config.type}. NATS was retired on 2026-05-16; use 'redis-streams'.`);\n }\n\n /**\n * Create an event consumer based on configuration\n */\n static createConsumer(config: ConsumerConfig): IEventConsumer {\n logger.info('[EventQueueFactory] Creating event consumer', {\n type: config.type,\n url: config.url,\n stream: config.stream,\n consumer: config.consumer,\n });\n\n if (config.type === QueueType.REDIS_STREAMS) {\n return new RedisStreamsEventConsumer(config);\n }\n\n throw new Error(`Unsupported queue type: ${config.type}. NATS was retired on 2026-05-16; use 'redis-streams'.`);\n }\n\n /**\n * Create a publisher from environment variables.\n * Reads `REDIS_URL`, `REDIS_PASSWORD`, and standard queue options.\n */\n static createPublisherFromEnv(): IEventPublisher {\n return EventQueueFactory.createPublisher({\n type: QueueType.REDIS_STREAMS,\n url: process.env['REDIS_URL'] ?? 'redis://localhost:6379',\n password: process.env['REDIS_PASSWORD'],\n name: process.env['QUEUE_CLIENT_NAME'] ?? process.env['SERVICE_NAME'] ?? 'be-sdk-publisher',\n enableDeduplication: process.env['QUEUE_ENABLE_DEDUPLICATION'] === 'true',\n defaultPriority: (process.env['QUEUE_DEFAULT_PRIORITY'] as 'low' | 'normal' | 'high') ?? 'normal',\n });\n }\n\n /**\n * Create a consumer from environment variables.\n */\n static createConsumerFromEnv(stream: string, consumer: string): IEventConsumer {\n return EventQueueFactory.createConsumer({\n type: QueueType.REDIS_STREAMS,\n url: process.env['REDIS_URL'] ?? 'redis://localhost:6379',\n password: process.env['REDIS_PASSWORD'],\n name: process.env['QUEUE_CLIENT_NAME'] ?? process.env['SERVICE_NAME'] ?? consumer,\n stream,\n consumer,\n maxConcurrent: process.env['QUEUE_MAX_CONCURRENT'] ? parseInt(process.env['QUEUE_MAX_CONCURRENT'], 10) : 5,\n maxDeliver: process.env['QUEUE_MAX_DELIVER'] ? parseInt(process.env['QUEUE_MAX_DELIVER'], 10) : 3,\n ackWait: process.env['QUEUE_ACK_WAIT']\n ? parseInt(process.env['QUEUE_ACK_WAIT'], 10) * 1_000_000_000\n : 30_000_000_000,\n });\n }\n\n // ========================================================================\n // Layer-Aware Factory Methods\n // ========================================================================\n\n /**\n * Create a publisher for a specific layer.\n * The layer is preserved on the publisher name; otherwise identical to\n * `createPublisherFromEnv()`.\n */\n static createPublisherForLayer(_layer: ServiceLayer, serviceName: string): IEventPublisher {\n return EventQueueFactory.createPublisher({\n type: QueueType.REDIS_STREAMS,\n url: process.env['REDIS_URL'] ?? 'redis://localhost:6379',\n password: process.env['REDIS_PASSWORD'],\n name: serviceName,\n enableDeduplication: process.env['QUEUE_ENABLE_DEDUPLICATION'] === 'true',\n defaultPriority: (process.env['QUEUE_DEFAULT_PRIORITY'] as 'low' | 'normal' | 'high') ?? 'normal',\n });\n }\n\n /**\n * Create a consumer for a specific layer.\n */\n static createConsumerForLayer(\n _layer: ServiceLayer,\n serviceName: string,\n stream: string,\n consumer: string\n ): IEventConsumer {\n return EventQueueFactory.createConsumer({\n type: QueueType.REDIS_STREAMS,\n url: process.env['REDIS_URL'] ?? 'redis://localhost:6379',\n password: process.env['REDIS_PASSWORD'],\n name: serviceName,\n stream,\n consumer,\n maxConcurrent: process.env['QUEUE_MAX_CONCURRENT'] ? parseInt(process.env['QUEUE_MAX_CONCURRENT'], 10) : 5,\n maxDeliver: process.env['QUEUE_MAX_DELIVER'] ? parseInt(process.env['QUEUE_MAX_DELIVER'], 10) : 3,\n ackWait: process.env['QUEUE_ACK_WAIT']\n ? parseInt(process.env['QUEUE_ACK_WAIT'], 10) * 1_000_000_000\n : 30_000_000_000,\n });\n }\n}\n\n// Internal helper kept exported for callers that imported it previously.\nexport { resolveQueueType };\n"]}
|