@burdenoff/be-sdk 2026.623.1 → 2026.701.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/telemetry/health.ts","../../src/telemetry/metrics-endpoint.ts","../../src/telemetry/prisma-logging.ts","../../src/telemetry/index.ts"],"names":["createHealthRoutes","_deps","Proxy","get","_target","prop","undefined","loadDefaultRegistry","mod","collectDefaultMetrics","register","createMetricsRoutesImpl","app","opts","path","ctx","registry","ctxWithSet","set","status","headers","contentType","metrics","createMetricsRoutes","createPrismaLoggingExtension","logger","name","query","$allOperations","model","operation","args","start","Date","now","result","debug","duration_ms","redactSensitiveFields","err","error","Error","message","String","resolveEnv","explicit","fromEnv","process","env","resolveVersion","resolveEndpoint","proto","resolveSampling","Number","isFinite","Math","min","max","parsed","resolveOtelSdkEnabled","sdkDisabled","otelEnabled","bootstrapTelemetry","cfg","serviceVersion","otlpEndpoint","sampleRatio","createPinoLogger","serviceName","version","setActiveTelemetryLogger","instrumentation","setupInstrumentation","tracing","samplingRate","otelSdk","createOtelSdk","boundary","module","info","metricsEnabled","metricsDropReason","warn","reason","shutdown","defaultLogger","setLevel","getLevel"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * `/health`, `/health/live`, `/health/ready` Elysia routes with a 1s\n * result cache so readiness checks can't stampede Postgres.\n *\n * Dependencies (prisma, eventQueue, valkey) are optional — omit any client and\n * the readiness check simply skips it.\n */\n\ninterface PrismaLike {\n $queryRaw: (strings: TemplateStringsArray) => Promise<unknown>;\n}\ninterface EventQueueLike {\n isConnected?: () => boolean | Promise<boolean>;\n healthCheck?: () => Promise<{ ok: boolean }>;\n}\ninterface ValkeyLike {\n ping: () => Promise<unknown>;\n}\n\nexport interface HealthDeps {\n prisma?: PrismaLike;\n eventQueue?: EventQueueLike;\n valkey?: ValkeyLike;\n /** Service version reported on /health. */\n version?: string;\n /** Service name reported on /health. */\n serviceName?: string;\n}\n\ninterface CachedStatus {\n ready: boolean;\n checked: Record<string, { ok: boolean; error?: string }>;\n at: number;\n}\n\nconst CACHE_TTL_MS = 1000;\n\nasync function probeReady(deps: HealthDeps): Promise<CachedStatus> {\n const checked: Record<string, { ok: boolean; error?: string }> = {};\n\n if (deps.prisma) {\n try {\n await deps.prisma.$queryRaw`SELECT 1`;\n checked['postgres'] = { ok: true };\n } catch (err) {\n checked['postgres'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.eventQueue) {\n try {\n const connected =\n typeof deps.eventQueue.isConnected === 'function'\n ? await Promise.resolve(deps.eventQueue.isConnected())\n : ((await deps.eventQueue.healthCheck?.())?.ok ?? true);\n checked['eventQueue'] = { ok: Boolean(connected) };\n } catch (err) {\n checked['eventQueue'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.valkey) {\n try {\n await deps.valkey.ping();\n checked['valkey'] = { ok: true };\n } catch (err) {\n checked['valkey'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n const ready = Object.values(checked).every((c) => c.ok);\n return { ready, checked, at: Date.now() };\n}\n\nexport function createHealthRoutes(_deps: HealthDeps = {}): unknown {\n // Return an Elysia app lazily so be-sdk doesn't hard-require elysia.\n return new Proxy(\n {},\n {\n get(_target, prop): unknown {\n // Tell TypeScript consumers the returned object is an Elysia plugin;\n // the actual mount happens via `createHealthRoutesImpl`. Services\n // that prefer direct use can call `createHealthRoutesImpl(elysia, deps)`.\n if (prop === 'use' || prop === 'then') return undefined;\n return undefined;\n },\n }\n );\n}\n\n/**\n * Mount health routes on an existing Elysia app. Callers hold a reference\n * to Elysia themselves; be-sdk stays decoupled.\n */\nexport function createHealthRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, deps: HealthDeps = {}): App {\n let cache: CachedStatus | null = null;\n\n const getStatus = async (): Promise<CachedStatus> => {\n if (cache && Date.now() - cache.at < CACHE_TTL_MS) return cache;\n cache = await probeReady(deps);\n return cache;\n };\n\n app.get('/health/live', () => ({\n status: 'ok',\n serviceName: deps.serviceName,\n version: deps.version,\n }));\n\n app.get('/health/ready', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n };\n });\n\n app.get('/health', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n uptime_s: Math.round(process.uptime()),\n };\n });\n\n return app;\n}\n","/**\n * Prometheus `/metrics` route mounter. Uses the shared `prom-client`\n * default registry so all instrumentation (GraphQL Envelop, Prisma,\n * runtime) shows up on a single endpoint.\n */\n\ninterface PromRegistryLike {\n metrics: () => Promise<string> | string;\n contentType?: string;\n}\n\nexport interface MetricsMountOptions {\n registry?: PromRegistryLike;\n path?: string;\n}\n\nexport async function loadDefaultRegistry(): Promise<PromRegistryLike | null> {\n try {\n const mod = (await import('prom-client')) as unknown as {\n register: PromRegistryLike;\n collectDefaultMetrics: (opts?: Record<string, unknown>) => void;\n };\n // Kick runtime metrics into the default registry if not already.\n try {\n mod.collectDefaultMetrics({ register: mod.register });\n } catch {\n // Already registered — ignore duplicate-metric errors.\n }\n return mod.register;\n } catch {\n return null;\n }\n}\n\nexport function createMetricsRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, opts: MetricsMountOptions = {}): App {\n const path = opts.path ?? '/metrics';\n\n app.get(path, async (ctx: unknown): Promise<unknown> => {\n const registry = opts.registry ?? (await loadDefaultRegistry());\n const ctxWithSet = ctx as { set?: { status?: number; headers?: Record<string, string> } };\n if (!registry) {\n if (ctxWithSet.set) ctxWithSet.set.status = 503;\n return '# prom-client not installed\\n';\n }\n if (ctxWithSet.set) {\n ctxWithSet.set.status = 200;\n ctxWithSet.set.headers = {\n 'content-type': registry.contentType ?? 'text/plain; version=0.0.4; charset=utf-8',\n };\n }\n return registry.metrics();\n });\n\n return app;\n}\n\n/**\n * Legacy export name used by the service template. Composes the Elysia\n * plugin-style function that `new Elysia().use(...)` accepts.\n */\nexport function createMetricsRoutes(opts: MetricsMountOptions = {}): unknown {\n return (app: Parameters<typeof createMetricsRoutesImpl>[0]): unknown => createMetricsRoutesImpl(app, opts);\n}\n","/**\n * Prisma client extension that pipes query events through the SDK logger\n * with trace/span correlation fields auto-injected. The\n * `@prisma/instrumentation` peer provides the spans\n * themselves; this extension only adds structured log events on top.\n */\nimport type { Logger } from '../logger/index.js';\nimport { redactSensitiveFields } from '../logger/index.js';\n\ntype PrismaQueryArgs = {\n model?: string;\n operation: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n};\n\n/**\n * Returns a Prisma Client extension object compatible with the\n * `$extends()` API (Prisma v5+).\n *\n * ```ts\n * export const prisma = new PrismaClient().$extends(\n * createPrismaLoggingExtension(logger)\n * );\n * ```\n */\nexport function createPrismaLoggingExtension(logger: Logger): {\n name: string;\n query: {\n $allOperations: (args: PrismaQueryArgs) => Promise<unknown>;\n };\n} {\n return {\n name: 'burdenoff-pino-logging',\n query: {\n async $allOperations({ model, operation, args, query }: PrismaQueryArgs): Promise<unknown> {\n const start = Date.now();\n try {\n const result = await query(args);\n logger.debug('prisma.query', {\n model,\n operation,\n duration_ms: Date.now() - start,\n args: redactSensitiveFields(args),\n });\n return result;\n } catch (err) {\n logger.error('prisma.error', {\n model,\n operation,\n duration_ms: Date.now() - start,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n },\n },\n };\n}\n","/**\n * Unified telemetry bootstrap for Burdenoff services.\n *\n * Composes the existing `instrumentation/` + `observability/` + `logger/`\n * modules and adds:\n * - `bootstrapTelemetry({ serviceName, boundary, module, env })` — single\n * call that initializes OTel, wires Pino logger with trace fields,\n * exposes GraphQL Yoga plugins, registers process exit hooks.\n * - `createHealthRoutes({ prisma, nats, valkey, version })` — `/health`,\n * `/health/live`, `/health/ready` Elysia routes.\n * - `createMetricsRoutes(registry?)` — `/metrics` Prometheus exposition.\n * - `createPrismaLoggingExtension(logger)` — Prisma extension that pipes\n * query events through Pino with trace/span correlation ids.\n *\n * The module does not pull in `@opentelemetry/sdk-node` or `pino` as direct\n * deps — services install those as optional peers, and imports are lazy so\n * services that don't install them still load.\n */\n\nimport type { Logger as BaseLogger } from '../logger/index.js';\nimport { logger as defaultLogger } from '../logger/index.js';\nimport {\n initializeInstrumentation,\n setupInstrumentation,\n type SetupInstrumentationOptions,\n type InstrumentationSetupResult,\n} from '../instrumentation/index.js';\nimport { setActiveTelemetryLogger } from './logger-state.js';\nimport type { OtelSdkHandle } from './sdk.js';\n\nexport { createHealthRoutes } from './health.js';\nexport { createMetricsRoutes } from './metrics-endpoint.js';\nexport { createPrismaLoggingExtension } from './prisma-logging.js';\nexport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\nexport { createPinoLogger } from './pino-logger.js';\n\nexport type Boundary = 'wspace' | 'global' | 'gateway';\nexport type Env = 'alpha' | 'prod' | 'dev';\n\nexport interface TelemetryConfig {\n /** Full service name, e.g. \"wspace-auth-svc\". */\n serviceName: string;\n /** Semver of the service deployment; defaults to `process.env.npm_package_version`. */\n serviceVersion?: string;\n /** Monorepo boundary: `wspace`, `global`, or `gateway`. */\n boundary: Boundary;\n /** Module slug, e.g. `auth` (omit for gateways). */\n module?: string;\n /** Deployment environment; defaults to alpha for non-production NODE_ENV. */\n env?: Env;\n /**\n * OTLP endpoint for spans/metrics/logs. Defaults to\n * `$OTEL_EXPORTER_OTLP_ENDPOINT` or\n * `http://alloy.sre.svc.cluster.local:4318`.\n */\n otlpEndpoint?: string;\n /** Head-based sampling ratio. Default: alpha=1.0, prod=0.1. */\n sampleRatio?: number;\n /** Extra options forwarded to `setupInstrumentation`. */\n instrumentation?: SetupInstrumentationOptions;\n}\n\nexport interface TelemetryHandle {\n /** The configured service name (for use in health routes, etc.). */\n serviceName: string;\n /** The resolved service version. */\n serviceVersion: string;\n /** Environment. */\n env: Env;\n /** The Pino-backed logger. */\n logger: BaseLogger;\n /** Initialized instrumentation (tracer + metrics + plugins). */\n instrumentation: InstrumentationSetupResult;\n /** Cleanup hook; services call on SIGTERM. */\n shutdown: () => Promise<void>;\n}\n\nfunction resolveEnv(explicit?: Env): Env {\n if (explicit) return explicit;\n const fromEnv = process.env['DEPLOY_ENV'] ?? process.env['NODE_ENV'] ?? '';\n if (fromEnv === 'production' || fromEnv === 'prod') return 'prod';\n if (fromEnv === 'development' || fromEnv === 'dev') return 'dev';\n return 'alpha';\n}\n\nfunction resolveVersion(explicit?: string): string {\n if (explicit) return explicit;\n return process.env['npm_package_version'] ?? process.env['SERVICE_VERSION'] ?? '0.0.0';\n}\n\nfunction resolveEndpoint(explicit?: string): string {\n if (explicit) return explicit;\n const proto = 'http';\n // NOTE (ACA / current prod): the `alloy.sre.svc.cluster.local` fallback is a\n // LEGACY Kubernetes in-cluster DNS name and does NOT resolve on Azure\n // Container Apps. In ACA, service metrics reach Grafana/Azure Monitor via the\n // Prometheus `/metrics` *pull* path (the otel-collector scrapes each app) —\n // see `~/products/dev/platform/context/sre/HOW_TO_INTEGRATE_SRE_BACKEND.md`.\n // OTLP *push* (traces/metrics) only works where `OTEL_EXPORTER_OTLP_ENDPOINT`\n // is explicitly set to the env's otel-collector OTLP receiver. Kept as the\n // default for local/K8s remnants; override via env in ACA.\n return process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? `${proto}://alloy.sre.svc.cluster.local:4318`;\n}\n\nfunction resolveSampling(explicit: number | undefined, env: Env): number {\n if (typeof explicit === 'number' && Number.isFinite(explicit)) return Math.min(1, Math.max(0, explicit));\n const fromEnv = process.env['OTEL_TRACES_SAMPLER_ARG'];\n if (fromEnv) {\n const parsed = Number(fromEnv);\n if (Number.isFinite(parsed)) return Math.min(1, Math.max(0, parsed));\n }\n if (env === 'prod') return 0.1;\n return 1.0;\n}\n\nfunction resolveOtelSdkEnabled(): boolean {\n const sdkDisabled = process.env['OTEL_SDK_DISABLED'];\n if (sdkDisabled === 'true' || sdkDisabled === '1') return false;\n const otelEnabled = process.env['OTEL_ENABLED'];\n if (otelEnabled === 'false' || otelEnabled === '0') return false;\n return true;\n}\n\n/**\n * Bootstrap the full telemetry stack for a service.\n *\n * Services call this ONCE at startup **before** importing Prisma / GraphQL\n * Yoga / NATS so OTel can auto-instrument their dependencies.\n *\n * ```ts\n * // src/telemetry.ts\n * import { bootstrapTelemetry } from '@burdenoff/be-sdk/telemetry';\n * export const telemetry = await bootstrapTelemetry({\n * serviceName: 'wspace-auth-svc',\n * boundary: 'wspace',\n * module: 'auth',\n * });\n *\n * // src/index.ts — must be the FIRST import line.\n * import './telemetry.js';\n * ```\n */\nexport async function bootstrapTelemetry(cfg: TelemetryConfig): Promise<TelemetryHandle> {\n const env = resolveEnv(cfg.env);\n const serviceVersion = resolveVersion(cfg.serviceVersion);\n const otlpEndpoint = resolveEndpoint(cfg.otlpEndpoint);\n const sampleRatio = resolveSampling(cfg.sampleRatio, env);\n\n // Pino logger with trace/span correlation + redaction.\n // createPinoLogger is async (loads pino via dynamic import); awaiting it\n // is required — without await, `logger` is a Promise and calls like\n // logger.warn(...) crash with \"logger.warn is not a function\" during the\n // sdk-node fallback path.\n const { createPinoLogger } = await import('./pino-logger.js');\n const logger = await createPinoLogger({\n serviceName: cfg.serviceName,\n env,\n version: serviceVersion,\n });\n setActiveTelemetryLogger(logger);\n\n // Initialize core instrumentation (tracer, metrics registry, envelop plugins).\n // `setupInstrumentation` internally calls `initializeInstrumentation`.\n const instrumentation = setupInstrumentation(cfg.serviceName, {\n ...cfg.instrumentation,\n tracing: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.tracing ?? {}),\n samplingRate: sampleRatio,\n },\n metrics: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.metrics ?? {}),\n },\n });\n\n // Start the NodeSDK exporter pipeline if sdk-node is present (optional).\n let otelSdk: OtelSdkHandle | undefined;\n if (resolveOtelSdkEnabled()) {\n try {\n const { createOtelSdk } = await import('./sdk.js');\n otelSdk = await createOtelSdk({\n serviceName: cfg.serviceName,\n serviceVersion,\n boundary: cfg.boundary,\n module: cfg.module,\n env,\n otlpEndpoint,\n sampleRatio,\n });\n // Explicit success log includes metrics path status so an operator can\n // distinguish traces-only startup from full traces+metrics startup.\n logger.info('[telemetry] OpenTelemetry exporter pipeline started', {\n serviceName: cfg.serviceName,\n otlpEndpoint: otlpEndpoint ? '<configured>' : '<not set>',\n sampleRatio,\n metricsEnabled: otelSdk.metricsEnabled,\n });\n\n if (!otelSdk.metricsEnabled && otelSdk.metricsDropReason) {\n logger.warn('[telemetry] OpenTelemetry metrics reader disabled; continuing with traces only', {\n serviceName: cfg.serviceName,\n reason: otelSdk.metricsDropReason,\n });\n }\n } catch (err) {\n logger.warn('[telemetry] OpenTelemetry exporter pipeline failed to start; continuing with logs only', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n } else {\n logger.info('[telemetry] OTel SDK exporter disabled by env');\n }\n\n const shutdown = async (): Promise<void> => {\n try {\n if (otelSdk?.shutdown) await otelSdk.shutdown();\n } catch (err) {\n logger.warn('[telemetry] shutdown error (ignored)', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n };\n\n // Mirror defaultLogger so services that still use the singleton get trace-enriched output.\n defaultLogger.setLevel(logger.getLevel?.() ?? 'info');\n\n return {\n serviceName: cfg.serviceName,\n serviceVersion,\n env,\n logger: logger,\n instrumentation,\n shutdown,\n };\n}\n\n// Re-export what services typically import.\nexport { initializeInstrumentation, setupInstrumentation };\n"]}
1
+ {"version":3,"sources":["../../src/telemetry/health.ts","../../src/telemetry/metrics-endpoint.ts","../../src/telemetry/prisma-logging.ts","../../src/telemetry/index.ts"],"names":["createHealthRoutes","_deps","Proxy","get","_target","prop","undefined","loadDefaultRegistry","mod","collectDefaultMetrics","register","createMetricsRoutesImpl","app","opts","path","ctx","registry","ctxWithSet","set","status","headers","contentType","metrics","createMetricsRoutes","createPrismaLoggingExtension","logger","name","query","$allOperations","model","operation","args","start","Date","now","result","debug","duration_ms","redactSensitiveFields","err","error","Error","message","String","resolveEnv","explicit","fromEnv","process","env","resolveVersion","resolveEndpoint","proto","resolveSampling","Number","isFinite","Math","min","max","parsed","resolveOtelSdkEnabled","sdkDisabled","otelEnabled","bootstrapTelemetry","cfg","serviceVersion","otlpEndpoint","sampleRatio","createPinoLogger","serviceName","version","setActiveTelemetryLogger","instrumentation","setupInstrumentation","tracing","samplingRate","otelSdk","console","log","createOtelSdk","boundary","module","info","metricsEnabled","metricsDropReason","warn","reason","shutdown","defaultLogger","setLevel","getLevel"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * `/health`, `/health/live`, `/health/ready` Elysia routes with a 1s\n * result cache so readiness checks can't stampede Postgres.\n *\n * Dependencies (prisma, eventQueue, valkey) are optional — omit any client and\n * the readiness check simply skips it.\n */\n\ninterface PrismaLike {\n $queryRaw: (strings: TemplateStringsArray) => Promise<unknown>;\n}\ninterface EventQueueLike {\n isConnected?: () => boolean | Promise<boolean>;\n healthCheck?: () => Promise<{ ok: boolean }>;\n}\ninterface ValkeyLike {\n ping: () => Promise<unknown>;\n}\n\nexport interface HealthDeps {\n prisma?: PrismaLike;\n eventQueue?: EventQueueLike;\n valkey?: ValkeyLike;\n /** Service version reported on /health. */\n version?: string;\n /** Service name reported on /health. */\n serviceName?: string;\n}\n\ninterface CachedStatus {\n ready: boolean;\n checked: Record<string, { ok: boolean; error?: string }>;\n at: number;\n}\n\nconst CACHE_TTL_MS = 1000;\n\nasync function probeReady(deps: HealthDeps): Promise<CachedStatus> {\n const checked: Record<string, { ok: boolean; error?: string }> = {};\n\n if (deps.prisma) {\n try {\n await deps.prisma.$queryRaw`SELECT 1`;\n checked['postgres'] = { ok: true };\n } catch (err) {\n checked['postgres'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.eventQueue) {\n try {\n const connected =\n typeof deps.eventQueue.isConnected === 'function'\n ? await Promise.resolve(deps.eventQueue.isConnected())\n : ((await deps.eventQueue.healthCheck?.())?.ok ?? true);\n checked['eventQueue'] = { ok: Boolean(connected) };\n } catch (err) {\n checked['eventQueue'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.valkey) {\n try {\n await deps.valkey.ping();\n checked['valkey'] = { ok: true };\n } catch (err) {\n checked['valkey'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n const ready = Object.values(checked).every((c) => c.ok);\n return { ready, checked, at: Date.now() };\n}\n\nexport function createHealthRoutes(_deps: HealthDeps = {}): unknown {\n // Return an Elysia app lazily so be-sdk doesn't hard-require elysia.\n return new Proxy(\n {},\n {\n get(_target, prop): unknown {\n // Tell TypeScript consumers the returned object is an Elysia plugin;\n // the actual mount happens via `createHealthRoutesImpl`. Services\n // that prefer direct use can call `createHealthRoutesImpl(elysia, deps)`.\n if (prop === 'use' || prop === 'then') return undefined;\n return undefined;\n },\n }\n );\n}\n\n/**\n * Mount health routes on an existing Elysia app. Callers hold a reference\n * to Elysia themselves; be-sdk stays decoupled.\n */\nexport function createHealthRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, deps: HealthDeps = {}): App {\n let cache: CachedStatus | null = null;\n\n const getStatus = async (): Promise<CachedStatus> => {\n if (cache && Date.now() - cache.at < CACHE_TTL_MS) return cache;\n cache = await probeReady(deps);\n return cache;\n };\n\n app.get('/health/live', () => ({\n status: 'ok',\n serviceName: deps.serviceName,\n version: deps.version,\n }));\n\n app.get('/health/ready', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n };\n });\n\n app.get('/health', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n uptime_s: Math.round(process.uptime()),\n };\n });\n\n return app;\n}\n","/**\n * Prometheus `/metrics` route mounter. Uses the shared `prom-client`\n * default registry so all instrumentation (GraphQL Envelop, Prisma,\n * runtime) shows up on a single endpoint.\n */\n\ninterface PromRegistryLike {\n metrics: () => Promise<string> | string;\n contentType?: string;\n}\n\nexport interface MetricsMountOptions {\n registry?: PromRegistryLike;\n path?: string;\n}\n\nexport async function loadDefaultRegistry(): Promise<PromRegistryLike | null> {\n try {\n const mod = (await import('prom-client')) as unknown as {\n register: PromRegistryLike;\n collectDefaultMetrics: (opts?: Record<string, unknown>) => void;\n };\n // Kick runtime metrics into the default registry if not already.\n try {\n mod.collectDefaultMetrics({ register: mod.register });\n } catch {\n // Already registered — ignore duplicate-metric errors.\n }\n return mod.register;\n } catch {\n return null;\n }\n}\n\nexport function createMetricsRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, opts: MetricsMountOptions = {}): App {\n const path = opts.path ?? '/metrics';\n\n app.get(path, async (ctx: unknown): Promise<unknown> => {\n const registry = opts.registry ?? (await loadDefaultRegistry());\n const ctxWithSet = ctx as { set?: { status?: number; headers?: Record<string, string> } };\n if (!registry) {\n if (ctxWithSet.set) ctxWithSet.set.status = 503;\n return '# prom-client not installed\\n';\n }\n if (ctxWithSet.set) {\n ctxWithSet.set.status = 200;\n ctxWithSet.set.headers = {\n 'content-type': registry.contentType ?? 'text/plain; version=0.0.4; charset=utf-8',\n };\n }\n return registry.metrics();\n });\n\n return app;\n}\n\n/**\n * Legacy export name used by the service template. Composes the Elysia\n * plugin-style function that `new Elysia().use(...)` accepts.\n */\nexport function createMetricsRoutes(opts: MetricsMountOptions = {}): unknown {\n return (app: Parameters<typeof createMetricsRoutesImpl>[0]): unknown => createMetricsRoutesImpl(app, opts);\n}\n","/**\n * Prisma client extension that pipes query events through the SDK logger\n * with trace/span correlation fields auto-injected. The\n * `@prisma/instrumentation` peer provides the spans\n * themselves; this extension only adds structured log events on top.\n */\nimport type { Logger } from '../logger/index.js';\nimport { redactSensitiveFields } from '../logger/index.js';\n\ntype PrismaQueryArgs = {\n model?: string;\n operation: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n};\n\n/**\n * Returns a Prisma Client extension object compatible with the\n * `$extends()` API (Prisma v5+).\n *\n * ```ts\n * export const prisma = new PrismaClient().$extends(\n * createPrismaLoggingExtension(logger)\n * );\n * ```\n */\nexport function createPrismaLoggingExtension(logger: Logger): {\n name: string;\n query: {\n $allOperations: (args: PrismaQueryArgs) => Promise<unknown>;\n };\n} {\n return {\n name: 'burdenoff-pino-logging',\n query: {\n async $allOperations({ model, operation, args, query }: PrismaQueryArgs): Promise<unknown> {\n const start = Date.now();\n try {\n const result = await query(args);\n logger.debug('prisma.query', {\n model,\n operation,\n duration_ms: Date.now() - start,\n args: redactSensitiveFields(args),\n });\n return result;\n } catch (err) {\n logger.error('prisma.error', {\n model,\n operation,\n duration_ms: Date.now() - start,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n },\n },\n };\n}\n","/**\n * Unified telemetry bootstrap for Burdenoff services.\n *\n * Composes the existing `instrumentation/` + `observability/` + `logger/`\n * modules and adds:\n * - `bootstrapTelemetry({ serviceName, boundary, module, env })` — single\n * call that initializes OTel, wires Pino logger with trace fields,\n * exposes GraphQL Yoga plugins, registers process exit hooks.\n * - `createHealthRoutes({ prisma, nats, valkey, version })` — `/health`,\n * `/health/live`, `/health/ready` Elysia routes.\n * - `createMetricsRoutes(registry?)` — `/metrics` Prometheus exposition.\n * - `createPrismaLoggingExtension(logger)` — Prisma extension that pipes\n * query events through Pino with trace/span correlation ids.\n *\n * The module does not pull in `@opentelemetry/sdk-node` or `pino` as direct\n * deps — services install those as optional peers, and imports are lazy so\n * services that don't install them still load.\n */\n\nimport type { Logger as BaseLogger } from '../logger/index.js';\nimport { logger as defaultLogger } from '../logger/index.js';\nimport {\n initializeInstrumentation,\n setupInstrumentation,\n type SetupInstrumentationOptions,\n type InstrumentationSetupResult,\n} from '../instrumentation/index.js';\nimport { setActiveTelemetryLogger } from './logger-state.js';\nimport type { OtelSdkHandle } from './sdk.js';\n\nexport { createHealthRoutes } from './health.js';\nexport { createMetricsRoutes } from './metrics-endpoint.js';\nexport { createPrismaLoggingExtension } from './prisma-logging.js';\nexport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\nexport { createPinoLogger } from './pino-logger.js';\n\nexport type Boundary = 'wspace' | 'global' | 'gateway';\nexport type Env = 'alpha' | 'prod' | 'dev';\n\nexport interface TelemetryConfig {\n /** Full service name, e.g. \"wspace-auth-svc\". */\n serviceName: string;\n /** Semver of the service deployment; defaults to `process.env.npm_package_version`. */\n serviceVersion?: string;\n /** Monorepo boundary: `wspace`, `global`, or `gateway`. */\n boundary: Boundary;\n /** Module slug, e.g. `auth` (omit for gateways). */\n module?: string;\n /** Deployment environment; defaults to alpha for non-production NODE_ENV. */\n env?: Env;\n /**\n * OTLP endpoint for spans/metrics/logs. Defaults to\n * `$OTEL_EXPORTER_OTLP_ENDPOINT` or\n * `http://alloy.sre.svc.cluster.local:4318`.\n */\n otlpEndpoint?: string;\n /** Head-based sampling ratio. Default: alpha=1.0, prod=0.1. */\n sampleRatio?: number;\n /** Extra options forwarded to `setupInstrumentation`. */\n instrumentation?: SetupInstrumentationOptions;\n}\n\nexport interface TelemetryHandle {\n /** The configured service name (for use in health routes, etc.). */\n serviceName: string;\n /** The resolved service version. */\n serviceVersion: string;\n /** Environment. */\n env: Env;\n /** The Pino-backed logger. */\n logger: BaseLogger;\n /** Initialized instrumentation (tracer + metrics + plugins). */\n instrumentation: InstrumentationSetupResult;\n /** Cleanup hook; services call on SIGTERM. */\n shutdown: () => Promise<void>;\n}\n\nfunction resolveEnv(explicit?: Env): Env {\n if (explicit) return explicit;\n const fromEnv = process.env['DEPLOY_ENV'] ?? process.env['NODE_ENV'] ?? '';\n if (fromEnv === 'production' || fromEnv === 'prod') return 'prod';\n if (fromEnv === 'development' || fromEnv === 'dev') return 'dev';\n return 'alpha';\n}\n\nfunction resolveVersion(explicit?: string): string {\n if (explicit) return explicit;\n return process.env['npm_package_version'] ?? process.env['SERVICE_VERSION'] ?? '0.0.0';\n}\n\nfunction resolveEndpoint(explicit?: string): string {\n if (explicit) return explicit;\n const proto = 'http';\n // NOTE (ACA / current prod): the `alloy.sre.svc.cluster.local` fallback is a\n // LEGACY Kubernetes in-cluster DNS name and does NOT resolve on Azure\n // Container Apps. In ACA, service metrics reach Grafana/Azure Monitor via the\n // Prometheus `/metrics` *pull* path (the otel-collector scrapes each app) —\n // see `~/products/dev/platform/context/sre/HOW_TO_INTEGRATE_SRE_BACKEND.md`.\n // OTLP *push* (traces/metrics) only works where `OTEL_EXPORTER_OTLP_ENDPOINT`\n // is explicitly set to the env's otel-collector OTLP receiver. Kept as the\n // default for local/K8s remnants; override via env in ACA.\n return process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? `${proto}://alloy.sre.svc.cluster.local:4318`;\n}\n\nfunction resolveSampling(explicit: number | undefined, env: Env): number {\n if (typeof explicit === 'number' && Number.isFinite(explicit)) return Math.min(1, Math.max(0, explicit));\n const fromEnv = process.env['OTEL_TRACES_SAMPLER_ARG'];\n if (fromEnv) {\n const parsed = Number(fromEnv);\n if (Number.isFinite(parsed)) return Math.min(1, Math.max(0, parsed));\n }\n if (env === 'prod') return 0.1;\n return 1.0;\n}\n\nfunction resolveOtelSdkEnabled(): boolean {\n const sdkDisabled = process.env['OTEL_SDK_DISABLED'];\n if (sdkDisabled === 'true' || sdkDisabled === '1') return false;\n const otelEnabled = process.env['OTEL_ENABLED'];\n if (otelEnabled === 'false' || otelEnabled === '0') return false;\n return true;\n}\n\n/**\n * Bootstrap the full telemetry stack for a service.\n *\n * Services call this ONCE at startup **before** importing Prisma / GraphQL\n * Yoga / NATS so OTel can auto-instrument their dependencies.\n *\n * ```ts\n * // src/telemetry.ts\n * import { bootstrapTelemetry } from '@burdenoff/be-sdk/telemetry';\n * export const telemetry = await bootstrapTelemetry({\n * serviceName: 'wspace-auth-svc',\n * boundary: 'wspace',\n * module: 'auth',\n * });\n *\n * // src/index.ts — must be the FIRST import line.\n * import './telemetry.js';\n * ```\n */\nexport async function bootstrapTelemetry(cfg: TelemetryConfig): Promise<TelemetryHandle> {\n const env = resolveEnv(cfg.env);\n const serviceVersion = resolveVersion(cfg.serviceVersion);\n const otlpEndpoint = resolveEndpoint(cfg.otlpEndpoint);\n const sampleRatio = resolveSampling(cfg.sampleRatio, env);\n\n // Pino logger with trace/span correlation + redaction.\n // createPinoLogger is async (loads pino via dynamic import); awaiting it\n // is required — without await, `logger` is a Promise and calls like\n // logger.warn(...) crash with \"logger.warn is not a function\" during the\n // sdk-node fallback path.\n const { createPinoLogger } = await import('./pino-logger.js');\n const logger = await createPinoLogger({\n serviceName: cfg.serviceName,\n env,\n version: serviceVersion,\n });\n setActiveTelemetryLogger(logger);\n\n // Initialize core instrumentation (tracer, metrics registry, envelop plugins).\n // `setupInstrumentation` internally calls `initializeInstrumentation`.\n const instrumentation = setupInstrumentation(cfg.serviceName, {\n ...cfg.instrumentation,\n tracing: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.tracing ?? {}),\n samplingRate: sampleRatio,\n },\n metrics: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.metrics ?? {}),\n },\n });\n\n // Start the NodeSDK exporter pipeline if sdk-node is present (optional).\n let otelSdk: OtelSdkHandle | undefined;\n if (resolveOtelSdkEnabled()) {\n // Use console.log as a Pino-independent fallback for the critical OTel\n // bootstrap path. In ACA, Pino's default async sonic-boom destination is\n // not captured by ContainerAppConsoleLogs (see pino-logger.ts), so if the\n // sync-destination fix hasn't been deployed yet the *only* way operators\n // can see OTel startup/failure messages is through console.log.\n console.log('[telemetry] OTel SDK bootstrap starting...');\n try {\n const { createOtelSdk } = await import('./sdk.js');\n otelSdk = await createOtelSdk({\n serviceName: cfg.serviceName,\n serviceVersion,\n boundary: cfg.boundary,\n module: cfg.module,\n env,\n otlpEndpoint,\n sampleRatio,\n });\n // Explicit success log includes metrics path status so an operator can\n // distinguish traces-only startup from full traces+metrics startup.\n logger.info('[telemetry] OpenTelemetry exporter pipeline started', {\n serviceName: cfg.serviceName,\n otlpEndpoint: otlpEndpoint ? '<configured>' : '<not set>',\n sampleRatio,\n metricsEnabled: otelSdk.metricsEnabled,\n });\n console.log('[telemetry] OTel SDK exporter pipeline started');\n\n if (!otelSdk.metricsEnabled && otelSdk.metricsDropReason) {\n logger.warn('[telemetry] OpenTelemetry metrics reader disabled; continuing with traces only', {\n serviceName: cfg.serviceName,\n reason: otelSdk.metricsDropReason,\n });\n console.warn('[telemetry] OTel SDK metrics reader disabled:', otelSdk.metricsDropReason);\n }\n } catch (err) {\n logger.warn('[telemetry] OpenTelemetry exporter pipeline failed to start; continuing with logs only', {\n error: err instanceof Error ? err.message : String(err),\n });\n // console.error is always captured by ACA, ensuring the failure reason\n // is visible to operators even when Pino output is not.\n console.error('[telemetry] OTel SDK failed:', err);\n }\n } else {\n logger.info('[telemetry] OTel SDK exporter disabled by env');\n console.log('[telemetry] OTel SDK exporter disabled by env');\n }\n\n const shutdown = async (): Promise<void> => {\n try {\n if (otelSdk?.shutdown) await otelSdk.shutdown();\n } catch (err) {\n logger.warn('[telemetry] shutdown error (ignored)', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n };\n\n // Mirror defaultLogger so services that still use the singleton get trace-enriched output.\n defaultLogger.setLevel(logger.getLevel?.() ?? 'info');\n\n return {\n serviceName: cfg.serviceName,\n serviceVersion,\n env,\n logger: logger,\n instrumentation,\n shutdown,\n };\n}\n\n// Re-export what services typically import.\nexport { initializeInstrumentation, setupInstrumentation };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/be-sdk",
3
- "version": "2026.623.1",
3
+ "version": "2026.701.1",
4
4
  "description": "Backend SDK for Burdenoff products providing unified access to notifications, RBAC, activity tracking, usage monitoring, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1 +0,0 @@
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 +0,0 @@
1
- {"version":3,"sources":["../src/platform/index.ts","../src/platform/httpClient.ts","../src/platform/leaderLock.ts","../src/platform/rateLimit.ts","../src/platform/paginator.ts","../src/platform/dataLoaderFactory.ts","../src/platform/cacheInvalidation.ts","../src/platform/pgPartition.ts","../src/platform/llmClient.ts"],"names":["breakers","Map","hostOf","url","URL","host","getBreaker","b","get","failures","openedAt","state","set","defaultRetryOn","status","jitter","delay","Math","floor","random","sleep","ms","Promise","r","setTimeout","CircuitBreakerOpenError","Error","name","__resetHttpClientBreakers","clear","executeOnce","init","timeoutMs","signal","AbortSignal","timeout","fetch","httpClient","config","fullUrl","baseUrl","test","replace","breaker","breakerThreshold","threshold","cooldownMs","Date","now","logger","info","attempts","retry","initialDelay","initialDelayMs","maxDelay","maxDelayMs","retryOn","defaultTimeoutMs","headers","defaultHeaders","lastErr","attempt","response","warn","min","err","error","String","createHttpClient","RELEASE_LUA","RENEW_LUA","generateToken","toString","slice","process","pid","withLeaderLock","redis","fn","options","key","token","ttlMs","renewMs","max","ttlSeconds","ceil","acquired","stopped","renewTimer","setInterval","eval","catch","unref","result","clearInterval","rateLimitIncr","input","fullKey","count","incr","pexpire","windowMs","ttl","pttl","resetAt","remaining","limit","allowed","clampLimit","opts","def","defaultLimit","maxLimit","minLimit","Number","isNaN","paginate","model","take","undefined","items","findMany","skip","cursor","id","where","orderBy","hasMore","length","trimmed","nextCursor","buildLoaders","ctx","builder","resolveReferenceLoader","loaderName","keyField","reference","loader","loaders","load","VERSION_PREFIX","getNamespaceVersion","namespace","v","n","parseInt","isFinite","buildCacheKey","parts","ver","join","invalidateNamespace","pad2","monthlyPartitionName","table","year","month","ensureMonthlyPartitions","prisma","created","cur","UTC","from","getUTCFullYear","getUTCMonth","end","to","y","m","next","partition","lower","upper","$executeRawUnsafe","push","setUTCMonth","dropOldPartitions","rows","$queryRawUnsafe","dropped","cutoffYear","beforeDate","cutoffMonth","row","partitionRe","exec","partition_name","mo","DEFAULTS","maxAttempts","maxOutputTokensCap","LLMRouter","adapters","register","adapter","resolveChain","envChain","env","trim","split","map","s","filter","Boolean","Array","keys","complete","req","cappedReq","maxTokens","chain","providerName","ctrl","AbortController","t","abort","provider","clearTimeout"],"mappings":"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","file":"chunk-PHKK7725.js","sourcesContent":["/**\n * @burdenoff/be-sdk/platform\n *\n * Reusable platform primitives consumed fleet-wide by Burdenoff svcs.\n */\nexport { httpClient, createHttpClient, CircuitBreakerOpenError, __resetHttpClientBreakers } from './httpClient.js';\nexport type { HttpClientConfig, HttpClientInit, RetryConfig, BreakerConfig } from './httpClient.js';\n\nexport { withLeaderLock } from './leaderLock.js';\nexport type { LeaderLockRedis, LeaderLockOptions, LeaderLockResult } from './leaderLock.js';\n\nexport { rateLimitIncr } from './rateLimit.js';\nexport type { RateLimitRedis, RateLimitInput, RateLimitResult } from './rateLimit.js';\n\nexport { clampLimit, paginate } from './paginator.js';\nexport type { ClampLimitOptions, PaginateInput, PaginateResult, PrismaModelLike } from './paginator.js';\n\nexport { buildLoaders, resolveReferenceLoader } from './dataLoaderFactory.js';\nexport type { DataLoaderLike, LoaderMap, LoaderBuilder, ReferenceObject } from './dataLoaderFactory.js';\n\nexport { buildCacheKey, getNamespaceVersion, invalidateNamespace } from './cacheInvalidation.js';\nexport type { CacheVersionRedis } from './cacheInvalidation.js';\n\nexport { monthlyPartitionName, ensureMonthlyPartitions, dropOldPartitions } from './pgPartition.js';\nexport type { PrismaRawClient, EnsureMonthlyOptions, DropOldOptions } from './pgPartition.js';\n\nexport { LLMRouter } from './llmClient.js';\nexport type { LLMRequest, LLMResponse, LLMProviderAdapter, LLMRouterOptions } from './llmClient.js';\n","/**\n * httpClient — hardened wrapper around global `fetch` with:\n * - per-request AbortSignal.timeout (default 5s)\n * - retries (default 3) with exponential backoff + full jitter\n * - per-host circuit breaker (opens at 5 consecutive 5xx, half-open after 30s)\n * - structured logging via existing be-sdk logger\n *\n * No required upstream dependency — we use the runtime `fetch` so the same\n * code path works on Bun and Node 20+. Consumers may pass an undici Agent\n * via `init.dispatcher` if they need keep-alive pooling; we forward unknown\n * init fields through.\n */\n\nimport { logger } from '../logger/index.js';\n\nexport interface RetryConfig {\n /** Total attempts including the first (default 3) */\n attempts?: number;\n /** Initial backoff in ms (default 100) */\n initialDelayMs?: number;\n /** Maximum backoff in ms (default 2000) */\n maxDelayMs?: number;\n /** Status codes that trigger a retry (default 408, 425, 429, 5xx) */\n retryOn?: (status: number) => boolean;\n}\n\nexport interface BreakerConfig {\n /** Consecutive 5xx failures to open breaker (default 5) */\n threshold?: number;\n /** Time in ms before HALF_OPEN trial (default 30000) */\n cooldownMs?: number;\n}\n\nexport interface HttpClientConfig {\n baseUrl?: string;\n defaultTimeoutMs?: number;\n retry?: RetryConfig;\n breaker?: BreakerConfig;\n /** Default headers merged into every request */\n defaultHeaders?: Record<string, string>;\n}\n\ninterface BreakerState {\n failures: number;\n openedAt: number | null;\n state: 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n}\n\nconst breakers = new Map<string, BreakerState>();\n\nfunction hostOf(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return url;\n }\n}\n\nfunction getBreaker(host: string): BreakerState {\n let b = breakers.get(host);\n if (!b) {\n b = { failures: 0, openedAt: null, state: 'CLOSED' };\n breakers.set(host, b);\n }\n return b;\n}\n\nfunction defaultRetryOn(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || (status >= 500 && status <= 599);\n}\n\nfunction jitter(delay: number): number {\n return Math.floor(Math.random() * delay);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nexport class CircuitBreakerOpenError extends Error {\n constructor(host: string) {\n super(`circuit breaker OPEN for host=${host}`);\n this.name = 'CircuitBreakerOpenError';\n }\n}\n\nexport interface HttpClientInit extends RequestInit {\n timeoutMs?: number;\n retry?: RetryConfig;\n}\n\n/**\n * Reset all breaker state (test helper).\n */\nexport function __resetHttpClientBreakers(): void {\n breakers.clear();\n}\n\nasync function executeOnce(url: string, init: HttpClientInit, timeoutMs: number): Promise<Response> {\n const signal = init.signal ?? AbortSignal.timeout(timeoutMs);\n return fetch(url, { ...init, signal });\n}\n\nexport async function httpClient(\n url: string,\n init: HttpClientInit = {},\n config: HttpClientConfig = {}\n): Promise<Response> {\n const fullUrl =\n config.baseUrl && !/^https?:\\/\\//i.test(url)\n ? `${config.baseUrl.replace(/\\/$/, '')}/${url.replace(/^\\//, '')}`\n : url;\n const host = hostOf(fullUrl);\n const breaker = getBreaker(host);\n const breakerThreshold = config.breaker?.threshold ?? 5;\n const cooldownMs = config.breaker?.cooldownMs ?? 30_000;\n\n if (breaker.state === 'OPEN') {\n if (breaker.openedAt && Date.now() - breaker.openedAt >= cooldownMs) {\n breaker.state = 'HALF_OPEN';\n logger.info('httpClient.breaker.halfOpen', { host });\n } else {\n throw new CircuitBreakerOpenError(host);\n }\n }\n\n const attempts = init.retry?.attempts ?? config.retry?.attempts ?? 3;\n const initialDelay = init.retry?.initialDelayMs ?? config.retry?.initialDelayMs ?? 100;\n const maxDelay = init.retry?.maxDelayMs ?? config.retry?.maxDelayMs ?? 2_000;\n const retryOn = init.retry?.retryOn ?? config.retry?.retryOn ?? defaultRetryOn;\n const timeoutMs = init.timeoutMs ?? config.defaultTimeoutMs ?? 5_000;\n\n const headers = { ...(config.defaultHeaders ?? {}), ...((init.headers as Record<string, string> | undefined) ?? {}) };\n\n let lastErr: unknown;\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n const response = await executeOnce(fullUrl, { ...init, headers }, timeoutMs);\n if (response.status >= 500) {\n breaker.failures += 1;\n if (breaker.failures >= breakerThreshold) {\n breaker.state = 'OPEN';\n breaker.openedAt = Date.now();\n logger.warn('httpClient.breaker.open', { host, failures: breaker.failures });\n }\n if (attempt < attempts && retryOn(response.status)) {\n const delay = Math.min(initialDelay * 2 ** (attempt - 1), maxDelay);\n await sleep(jitter(delay));\n continue;\n }\n return response;\n }\n // success path\n breaker.failures = 0;\n if (breaker.state === 'HALF_OPEN') {\n breaker.state = 'CLOSED';\n breaker.openedAt = null;\n logger.info('httpClient.breaker.closed', { host });\n }\n if (attempt < attempts && retryOn(response.status)) {\n const delay = Math.min(initialDelay * 2 ** (attempt - 1), maxDelay);\n await sleep(jitter(delay));\n continue;\n }\n return response;\n } catch (err) {\n lastErr = err;\n breaker.failures += 1;\n if (breaker.failures >= breakerThreshold) {\n breaker.state = 'OPEN';\n breaker.openedAt = Date.now();\n logger.warn('httpClient.breaker.open', { host, failures: breaker.failures });\n }\n if (attempt >= attempts) break;\n const delay = Math.min(initialDelay * 2 ** (attempt - 1), maxDelay);\n await sleep(jitter(delay));\n }\n }\n\n logger.error('httpClient.exhausted', { url: fullUrl, attempts, host });\n throw lastErr instanceof Error ? lastErr : new Error(`httpClient failed: ${String(lastErr)}`);\n}\n\nexport function createHttpClient(\n config: HttpClientConfig = {}\n): (url: string, init?: HttpClientInit) => Promise<Response> {\n return (url: string, init: HttpClientInit = {}) => httpClient(url, init, config);\n}\n","/**\n * withLeaderLock — Redis-based leader election.\n *\n * Acquires `SET NX EX` on `besdk:leader:{name}`. If acquired, runs fn() and\n * auto-renews the lease every `renewMs` (default ttlMs/3). On exit (success\n * or throw) the holder DELs the key only if it still owns it (token check\n * via a Redis LUA script — Redis-side, NOT JS eval).\n * If the lock cannot be acquired, fn() is NOT called and the function\n * resolves with `{ acquired: false }`.\n *\n * Redis client is duck-typed (ioredis-compatible) so consumers can pass\n * either ioredis or the be-sdk cache provider's underlying client.\n */\n\nimport { logger } from '../logger/index.js';\n\nexport interface LeaderLockRedis {\n /** ioredis: set(key, val, 'EX', seconds, 'NX') -> 'OK' | null */\n set(key: string, value: string, ex: 'EX', seconds: number, nx: 'NX'): Promise<'OK' | null>;\n /** Redis LUA EVAL for compare-and-delete / compare-and-renew (server-side script) */\n eval(script: string, numKeys: number, ...args: string[]): Promise<unknown>;\n}\n\nexport interface LeaderLockOptions {\n ttlMs: number;\n renewMs?: number;\n}\n\nexport interface LeaderLockResult<T> {\n acquired: boolean;\n result?: T;\n}\n\nconst RELEASE_LUA = `\nif redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"del\", KEYS[1])\nelse\n return 0\nend\n`;\n\nconst RENEW_LUA = `\nif redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"pexpire\", KEYS[1], ARGV[2])\nelse\n return 0\nend\n`;\n\nfunction generateToken(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}-${process.pid}`;\n}\n\nexport async function withLeaderLock<T>(\n redis: LeaderLockRedis,\n name: string,\n fn: () => Promise<T>,\n options: LeaderLockOptions\n): Promise<LeaderLockResult<T>> {\n const key = `besdk:leader:${name}`;\n const token = generateToken();\n const ttlMs = options.ttlMs;\n const renewMs = options.renewMs ?? Math.max(1_000, Math.floor(ttlMs / 3));\n const ttlSeconds = Math.max(1, Math.ceil(ttlMs / 1000));\n\n const acquired = await redis.set(key, token, 'EX', ttlSeconds, 'NX');\n if (acquired !== 'OK') {\n return { acquired: false };\n }\n\n logger.info('leaderLock.acquired', { name, token, ttlMs });\n\n let stopped = false;\n const renewTimer = setInterval(() => {\n if (stopped) return;\n redis.eval(RENEW_LUA, 1, key, token, String(ttlMs)).catch((err: unknown) => {\n logger.warn('leaderLock.renew.failed', { name, err: String(err) });\n });\n }, renewMs);\n // Don't keep the process alive just for this timer.\n if (typeof (renewTimer as unknown as { unref?: () => void }).unref === 'function') {\n (renewTimer as unknown as { unref: () => void }).unref();\n }\n\n try {\n const result = await fn();\n return { acquired: true, result };\n } finally {\n stopped = true;\n clearInterval(renewTimer);\n try {\n await redis.eval(RELEASE_LUA, 1, key, token);\n logger.info('leaderLock.released', { name, token });\n } catch (err) {\n logger.warn('leaderLock.release.failed', { name, err: String(err) });\n }\n }\n}\n","/**\n * rateLimitIncr — atomic INCR-based rate limit using EXPIRE NX.\n *\n * Strategy:\n * 1. INCR key\n * 2. If returned value === 1 (i.e. first increment), EXPIRE key with windowMs\n * 3. Compute remaining + resetAt\n *\n * This is two round-trips in the worst case. A future Lua/EVALSHA variant\n * can collapse it into a single round-trip; the public API is stable.\n *\n * Returns `allowed=false` if `count > limit`. The key is `besdk:rl:{key}`.\n */\n\nexport interface RateLimitRedis {\n incr(key: string): Promise<number>;\n pexpire(key: string, ms: number): Promise<number | 'OK'>;\n pttl(key: string): Promise<number>;\n}\n\nexport interface RateLimitInput {\n key: string;\n limit: number;\n windowMs: number;\n}\n\nexport interface RateLimitResult {\n allowed: boolean;\n count: number;\n remaining: number;\n resetAt: number;\n}\n\nexport async function rateLimitIncr(redis: RateLimitRedis, input: RateLimitInput): Promise<RateLimitResult> {\n const fullKey = `besdk:rl:${input.key}`;\n const count = await redis.incr(fullKey);\n if (count === 1) {\n await redis.pexpire(fullKey, input.windowMs);\n }\n let ttl = -1;\n try {\n ttl = await redis.pttl(fullKey);\n } catch {\n ttl = input.windowMs;\n }\n const resetAt = Date.now() + (ttl > 0 ? ttl : input.windowMs);\n const remaining = Math.max(0, input.limit - count);\n return {\n allowed: count <= input.limit,\n count,\n remaining,\n resetAt,\n };\n}\n","/**\n * Paginator — Relay-style cursor pagination + safe limit clamping.\n *\n * Use `clampLimit` at resolver entry to enforce sane defaults/maxes.\n * Use `paginate` to translate a Relay-style { first, after } into a\n * Prisma-ready { take, skip, cursor } and return a connection-shaped\n * result.\n */\n\nexport interface ClampLimitOptions {\n defaultLimit?: number;\n maxLimit?: number;\n minLimit?: number;\n}\n\nexport function clampLimit(input: number | undefined | null, opts: ClampLimitOptions = {}): number {\n const def = opts.defaultLimit ?? 50;\n const max = opts.maxLimit ?? 200;\n const min = opts.minLimit ?? 1;\n if (input == null || Number.isNaN(input)) return def;\n return Math.min(Math.max(Math.floor(input), min), max);\n}\n\nexport interface PaginateInput<TWhere, TOrderBy> {\n take?: number | null;\n cursor?: string | null;\n where?: TWhere;\n orderBy?: TOrderBy;\n}\n\nexport interface PaginateResult<TItem> {\n items: TItem[];\n hasMore: boolean;\n nextCursor: string | null;\n}\n\nexport interface PrismaModelLike<TItem, TWhere, TOrderBy> {\n findMany(args: {\n take?: number;\n skip?: number;\n cursor?: { id: string };\n where?: TWhere;\n orderBy?: TOrderBy;\n }): Promise<TItem[]>;\n}\n\nexport async function paginate<TItem extends { id: string }, TWhere = unknown, TOrderBy = unknown>(\n model: PrismaModelLike<TItem, TWhere, TOrderBy>,\n input: PaginateInput<TWhere, TOrderBy>,\n opts: ClampLimitOptions = {}\n): Promise<PaginateResult<TItem>> {\n const take = clampLimit(input.take ?? undefined, opts);\n // fetch +1 to detect hasMore\n const items = await model.findMany({\n take: take + 1,\n skip: input.cursor ? 1 : 0,\n cursor: input.cursor ? { id: input.cursor } : undefined,\n where: input.where,\n orderBy: input.orderBy,\n });\n const hasMore = items.length > take;\n const trimmed = hasMore ? items.slice(0, take) : items;\n const nextCursor = hasMore && trimmed.length > 0 ? (trimmed[trimmed.length - 1] as { id: string }).id : null;\n return { items: trimmed, hasMore, nextCursor };\n}\n","/**\n * DataLoaderFactory — per-request DataLoader collection.\n *\n * Each GraphQL request creates a fresh loader set scoped to its context\n * (db, workspaceId, requestId). Loaders are addressed by name and reused\n * within the request to coalesce N+1 fan-outs into a single batched query.\n *\n * Also ships `resolveReferenceLoader` — a convenience for Apollo Federation\n * `__resolveReference` resolvers so entity hydration stays N+1-free.\n *\n * This module is intentionally framework-agnostic; consumers may pair it\n * with the existing `SimpleDataLoader` in `src/dataloader/index.ts` or the\n * upstream `dataloader` npm package.\n */\n\nexport interface DataLoaderLike<K, V> {\n load(key: K): Promise<V>;\n loadMany(keys: readonly K[]): Promise<(V | Error)[]>;\n clear(key: K): this;\n clearAll(): this;\n prime(key: K, value: V): this;\n}\n\nexport type LoaderMap = Record<string, DataLoaderLike<unknown, unknown>>;\n\nexport type LoaderBuilder<Ctx, M extends LoaderMap> = (ctx: Ctx) => M;\n\n/**\n * Build a fresh loader collection from a context.\n *\n * @example\n * const loaders = buildLoaders(ctx, (c) => ({\n * userById: createSimpleLoader(async ids => c.db.user.findMany({ where: { id: { in: [...ids] } } }), u => u.id),\n * tagById: createSimpleLoader(...),\n * }));\n * await loaders.userById.load('user-123');\n */\nexport function buildLoaders<Ctx, M extends LoaderMap>(ctx: Ctx, builder: LoaderBuilder<Ctx, M>): M {\n return builder(ctx);\n}\n\n/**\n * `__resolveReference` helper for Apollo Federation.\n *\n * Given a context that contains a `loaders` map, returns a resolver\n * function bound to a specific loader name. Field references shaped as\n * `{ id: string }` (or `{ __keyField: string }`) are forwarded to\n * `loader.load(...)`.\n */\nexport interface ReferenceObject {\n id?: string;\n [key: string]: unknown;\n}\n\nexport function resolveReferenceLoader<T, Ctx extends { loaders: LoaderMap }>(\n loaderName: string,\n keyField: string = 'id'\n): (reference: ReferenceObject, ctx: Ctx) => Promise<T | null> {\n return async (reference, ctx) => {\n const loader = ctx.loaders[loaderName] as DataLoaderLike<string, T> | undefined;\n if (!loader) {\n throw new Error(`resolveReferenceLoader: loader \"${loaderName}\" not found on ctx.loaders`);\n }\n const key = reference[keyField];\n if (typeof key !== 'string') {\n return null;\n }\n return loader.load(key);\n };\n}\n","/**\n * Versioned-key cache invalidation helper.\n *\n * Pattern:\n * - Store `v:{namespace}` integer in Redis\n * - Compose keys as `${namespace}:v${ver}:${rest}`\n * - Invalidate via INCR `v:{namespace}` — no KEYS / SCAN required\n *\n * Use this instead of cacheClearPattern() for Azure Managed Redis (O(N)\n * blocking on KEYS is unsafe in prod).\n */\n\nexport interface CacheVersionRedis {\n get(key: string): Promise<string | null>;\n incr(key: string): Promise<number>;\n}\n\nconst VERSION_PREFIX = 'besdk:cv:';\n\nexport async function getNamespaceVersion(redis: CacheVersionRedis, namespace: string): Promise<number> {\n const v = await redis.get(`${VERSION_PREFIX}${namespace}`);\n if (!v) return 1;\n const n = Number.parseInt(v, 10);\n return Number.isFinite(n) && n > 0 ? n : 1;\n}\n\nexport async function buildCacheKey(redis: CacheVersionRedis, namespace: string, ...parts: string[]): Promise<string> {\n const ver = await getNamespaceVersion(redis, namespace);\n return `${namespace}:v${ver}:${parts.join(':')}`;\n}\n\nexport async function invalidateNamespace(redis: CacheVersionRedis, namespace: string): Promise<number> {\n return redis.incr(`${VERSION_PREFIX}${namespace}`);\n}\n","/**\n * PG declarative partition + retention DSL.\n *\n * Helpers:\n * - ensureMonthlyPartitions(prisma, { table, from, to })\n * - dropOldPartitions(prisma, { table, beforeDate })\n *\n * Used by retention jobs / migrations to keep append-only tables\n * (ActivityLog, Message, TrackingEvent, ApplicationUsage, AuditLog)\n * bounded. Caller is responsible for ensuring the parent table is\n * already declared as PARTITION BY RANGE (created_at).\n */\n\nexport interface PrismaRawClient {\n $executeRawUnsafe(query: string, ...values: unknown[]): Promise<unknown>;\n $queryRawUnsafe<T = unknown>(query: string, ...values: unknown[]): Promise<T>;\n}\n\nfunction pad2(n: number): string {\n return n < 10 ? `0${n}` : `${n}`;\n}\n\nexport function monthlyPartitionName(table: string, year: number, month: number): string {\n return `${table}_y${year}m${pad2(month)}`;\n}\n\nexport interface EnsureMonthlyOptions {\n table: string;\n from: Date;\n to: Date;\n}\n\nexport async function ensureMonthlyPartitions(prisma: PrismaRawClient, opts: EnsureMonthlyOptions): Promise<string[]> {\n const created: string[] = [];\n const cur = new Date(Date.UTC(opts.from.getUTCFullYear(), opts.from.getUTCMonth(), 1));\n const end = new Date(Date.UTC(opts.to.getUTCFullYear(), opts.to.getUTCMonth(), 1));\n while (cur <= end) {\n const y = cur.getUTCFullYear();\n const m = cur.getUTCMonth() + 1;\n const next = new Date(Date.UTC(y, m, 1));\n const partition = monthlyPartitionName(opts.table, y, m);\n const lower = `${y}-${pad2(m)}-01`;\n const upper = `${next.getUTCFullYear()}-${pad2(next.getUTCMonth() + 1)}-01`;\n await prisma.$executeRawUnsafe(\n `CREATE TABLE IF NOT EXISTS \"${partition}\" PARTITION OF \"${opts.table}\" FOR VALUES FROM ('${lower}') TO ('${upper}');`\n );\n created.push(partition);\n cur.setUTCMonth(cur.getUTCMonth() + 1);\n }\n return created;\n}\n\nexport interface DropOldOptions {\n table: string;\n beforeDate: Date;\n}\n\ninterface PartitionRow {\n partition_name: string;\n}\n\nexport async function dropOldPartitions(prisma: PrismaRawClient, opts: DropOldOptions): Promise<string[]> {\n // Find inherited tables of the parent, parse year/month from suffix, drop ones before threshold.\n const rows = await prisma.$queryRawUnsafe<PartitionRow[]>(\n `SELECT child.relname AS partition_name\n FROM pg_inherits\n JOIN pg_class parent ON pg_inherits.inhparent = parent.oid\n JOIN pg_class child ON pg_inherits.inhrelid = child.oid\n WHERE parent.relname = $1`,\n opts.table\n );\n const dropped: string[] = [];\n const cutoffYear = opts.beforeDate.getUTCFullYear();\n const cutoffMonth = opts.beforeDate.getUTCMonth() + 1;\n for (const row of rows) {\n const partitionRe = /_y(\\d{4})m(\\d{2})$/;\n const m = partitionRe.exec(row.partition_name);\n if (!m) continue;\n const y = Number(m[1]);\n const mo = Number(m[2]);\n if (y < cutoffYear || (y === cutoffYear && mo < cutoffMonth)) {\n await prisma.$executeRawUnsafe(`DROP TABLE IF EXISTS \"${row.partition_name}\";`);\n dropped.push(row.partition_name);\n }\n }\n return dropped;\n}\n","/**\n * Multi-provider LLM wrapper with timeout, retries, jitter, provider\n * fallback chain, token cap, and streaming passthrough.\n *\n * No hard dependency on a specific SDK — consumers register adapters.\n * Provider chain order is controlled by env `LLM_PROVIDER_CHAIN`\n * (comma-separated, e.g. `anthropic,openai,openrouter`).\n *\n * The wrapper is intentionally minimal — callers should construct it\n * once at boot, register adapters, and inject the singleton.\n */\n\nimport { logger } from '../logger/index.js';\n\nexport interface LLMRequest {\n model?: string;\n messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>;\n maxTokens?: number;\n temperature?: number;\n stream?: boolean;\n /** Override timeout for this request. */\n timeoutMs?: number;\n}\n\nexport interface LLMResponse {\n provider: string;\n content: string;\n inputTokens?: number;\n outputTokens?: number;\n raw?: unknown;\n}\n\nexport interface LLMProviderAdapter {\n name: string;\n complete(req: LLMRequest, signal: AbortSignal): Promise<LLMResponse>;\n}\n\nexport interface LLMRouterOptions {\n /** Default per-attempt timeout (ms). */\n timeoutMs?: number;\n /** Max attempts across providers. */\n maxAttempts?: number;\n /** Initial backoff (ms). */\n initialDelayMs?: number;\n /** Hard cap on output tokens regardless of caller request. */\n maxOutputTokensCap?: number;\n}\n\nconst DEFAULTS: Required<LLMRouterOptions> = {\n timeoutMs: 30_000,\n maxAttempts: 3,\n initialDelayMs: 500,\n maxOutputTokensCap: 4096,\n};\n\nfunction jitter(n: number): number {\n return Math.floor(Math.random() * n);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nexport class LLMRouter {\n private readonly adapters: Map<string, LLMProviderAdapter> = new Map();\n private readonly opts: Required<LLMRouterOptions>;\n\n constructor(opts: LLMRouterOptions = {}) {\n this.opts = { ...DEFAULTS, ...opts };\n }\n\n register(adapter: LLMProviderAdapter): void {\n this.adapters.set(adapter.name, adapter);\n }\n\n private resolveChain(): string[] {\n const envChain = process.env['LLM_PROVIDER_CHAIN']?.trim();\n if (envChain) {\n return envChain\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n }\n return Array.from(this.adapters.keys());\n }\n\n async complete(req: LLMRequest): Promise<LLMResponse> {\n const cappedReq: LLMRequest = {\n ...req,\n maxTokens: Math.min(req.maxTokens ?? this.opts.maxOutputTokensCap, this.opts.maxOutputTokensCap),\n };\n const chain = this.resolveChain();\n if (chain.length === 0) {\n throw new Error('LLMRouter: no providers registered');\n }\n\n let lastErr: unknown = null;\n for (let attempt = 0; attempt < this.opts.maxAttempts; attempt++) {\n const providerName = chain[attempt % chain.length];\n const adapter = providerName ? this.adapters.get(providerName) : undefined;\n if (!adapter) {\n logger.warn('llmRouter.provider.notRegistered', { providerName });\n continue;\n }\n const timeoutMs = req.timeoutMs ?? this.opts.timeoutMs;\n const ctrl = new AbortController();\n const t = setTimeout(() => ctrl.abort(), timeoutMs);\n try {\n const response = await adapter.complete(cappedReq, ctrl.signal);\n return response;\n } catch (err) {\n lastErr = err;\n logger.warn('llmRouter.attempt.failed', { provider: adapter.name, attempt, err: String(err) });\n if (attempt < this.opts.maxAttempts - 1) {\n const delay = this.opts.initialDelayMs * 2 ** attempt;\n await sleep(jitter(delay));\n }\n } finally {\n clearTimeout(t);\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(`LLMRouter exhausted ${this.opts.maxAttempts} attempts`);\n }\n}\n"]}
@@ -1,222 +0,0 @@
1
- interface RetryConfig {
2
- attempts?: number;
3
- initialDelayMs?: number;
4
- maxDelayMs?: number;
5
- retryOn?: (status: number) => boolean;
6
- }
7
- interface BreakerConfig {
8
- threshold?: number;
9
- cooldownMs?: number;
10
- }
11
- interface HttpClientConfig {
12
- baseUrl?: string;
13
- defaultTimeoutMs?: number;
14
- retry?: RetryConfig;
15
- breaker?: BreakerConfig;
16
- defaultHeaders?: Record<string, string>;
17
- }
18
- declare class CircuitBreakerOpenError extends Error {
19
- constructor(host: string);
20
- }
21
- interface HttpClientInit extends RequestInit {
22
- timeoutMs?: number;
23
- retry?: RetryConfig;
24
- }
25
- declare function __resetHttpClientBreakers(): void;
26
- declare function httpClient(url: string, init?: HttpClientInit, config?: HttpClientConfig): Promise<Response>;
27
- declare function createHttpClient(config?: HttpClientConfig): (url: string, init?: HttpClientInit) => Promise<Response>;
28
-
29
- interface LeaderLockRedis {
30
- set(key: string, value: string, ex: 'EX', seconds: number, nx: 'NX'): Promise<'OK' | null>;
31
- eval(script: string, numKeys: number, ...args: string[]): Promise<unknown>;
32
- }
33
- interface LeaderLockOptions {
34
- ttlMs: number;
35
- renewMs?: number;
36
- }
37
- interface LeaderLockResult<T> {
38
- acquired: boolean;
39
- result?: T;
40
- }
41
- declare function withLeaderLock<T>(redis: LeaderLockRedis, name: string, fn: () => Promise<T>, options: LeaderLockOptions): Promise<LeaderLockResult<T>>;
42
-
43
- interface RateLimitRedis {
44
- incr(key: string): Promise<number>;
45
- pexpire(key: string, ms: number): Promise<number | 'OK'>;
46
- pttl(key: string): Promise<number>;
47
- }
48
- interface RateLimitInput {
49
- key: string;
50
- limit: number;
51
- windowMs: number;
52
- }
53
- interface RateLimitResult {
54
- allowed: boolean;
55
- count: number;
56
- remaining: number;
57
- resetAt: number;
58
- }
59
- declare function rateLimitIncr(redis: RateLimitRedis, input: RateLimitInput): Promise<RateLimitResult>;
60
-
61
- interface ClampLimitOptions {
62
- defaultLimit?: number;
63
- maxLimit?: number;
64
- minLimit?: number;
65
- }
66
- declare function clampLimit(input: number | undefined | null, opts?: ClampLimitOptions): number;
67
- interface PaginateInput<TWhere, TOrderBy> {
68
- take?: number | null;
69
- cursor?: string | null;
70
- where?: TWhere;
71
- orderBy?: TOrderBy;
72
- }
73
- interface PaginateResult<TItem> {
74
- items: TItem[];
75
- hasMore: boolean;
76
- nextCursor: string | null;
77
- }
78
- interface PrismaModelLike<TItem, TWhere, TOrderBy> {
79
- findMany(args: {
80
- take?: number;
81
- skip?: number;
82
- cursor?: {
83
- id: string;
84
- };
85
- where?: TWhere;
86
- orderBy?: TOrderBy;
87
- }): Promise<TItem[]>;
88
- }
89
- declare function paginate<TItem extends {
90
- id: string;
91
- }, TWhere = unknown, TOrderBy = unknown>(model: PrismaModelLike<TItem, TWhere, TOrderBy>, input: PaginateInput<TWhere, TOrderBy>, opts?: ClampLimitOptions): Promise<PaginateResult<TItem>>;
92
-
93
- interface DataLoaderLike<K, V> {
94
- load(key: K): Promise<V>;
95
- loadMany(keys: readonly K[]): Promise<(V | Error)[]>;
96
- clear(key: K): this;
97
- clearAll(): this;
98
- prime(key: K, value: V): this;
99
- }
100
- type LoaderMap = Record<string, DataLoaderLike<unknown, unknown>>;
101
- type LoaderBuilder<Ctx, M extends LoaderMap> = (ctx: Ctx) => M;
102
- declare function buildLoaders<Ctx, M extends LoaderMap>(ctx: Ctx, builder: LoaderBuilder<Ctx, M>): M;
103
- interface ReferenceObject {
104
- id?: string;
105
- [key: string]: unknown;
106
- }
107
- declare function resolveReferenceLoader<T, Ctx extends {
108
- loaders: LoaderMap;
109
- }>(loaderName: string, keyField?: string): (reference: ReferenceObject, ctx: Ctx) => Promise<T | null>;
110
-
111
- interface CacheVersionRedis {
112
- get(key: string): Promise<string | null>;
113
- incr(key: string): Promise<number>;
114
- }
115
- declare function getNamespaceVersion(redis: CacheVersionRedis, namespace: string): Promise<number>;
116
- declare function buildCacheKey(redis: CacheVersionRedis, namespace: string, ...parts: string[]): Promise<string>;
117
- declare function invalidateNamespace(redis: CacheVersionRedis, namespace: string): Promise<number>;
118
-
119
- interface PrismaRawClient {
120
- $executeRawUnsafe(query: string, ...values: unknown[]): Promise<unknown>;
121
- $queryRawUnsafe<T = unknown>(query: string, ...values: unknown[]): Promise<T>;
122
- }
123
- declare function monthlyPartitionName(table: string, year: number, month: number): string;
124
- interface EnsureMonthlyOptions {
125
- table: string;
126
- from: Date;
127
- to: Date;
128
- }
129
- declare function ensureMonthlyPartitions(prisma: PrismaRawClient, opts: EnsureMonthlyOptions): Promise<string[]>;
130
- interface DropOldOptions {
131
- table: string;
132
- beforeDate: Date;
133
- }
134
- declare function dropOldPartitions(prisma: PrismaRawClient, opts: DropOldOptions): Promise<string[]>;
135
-
136
- interface LLMRequest {
137
- model?: string;
138
- messages: Array<{
139
- role: 'system' | 'user' | 'assistant';
140
- content: string;
141
- }>;
142
- maxTokens?: number;
143
- temperature?: number;
144
- stream?: boolean;
145
- timeoutMs?: number;
146
- }
147
- interface LLMResponse {
148
- provider: string;
149
- content: string;
150
- inputTokens?: number;
151
- outputTokens?: number;
152
- raw?: unknown;
153
- }
154
- interface LLMProviderAdapter {
155
- name: string;
156
- complete(req: LLMRequest, signal: AbortSignal): Promise<LLMResponse>;
157
- }
158
- interface LLMRouterOptions {
159
- timeoutMs?: number;
160
- maxAttempts?: number;
161
- initialDelayMs?: number;
162
- maxOutputTokensCap?: number;
163
- }
164
- declare class LLMRouter {
165
- private readonly adapters;
166
- private readonly opts;
167
- constructor(opts?: LLMRouterOptions);
168
- register(adapter: LLMProviderAdapter): void;
169
- private resolveChain;
170
- complete(req: LLMRequest): Promise<LLMResponse>;
171
- }
172
-
173
- type index_BreakerConfig = BreakerConfig;
174
- type index_CacheVersionRedis = CacheVersionRedis;
175
- type index_CircuitBreakerOpenError = CircuitBreakerOpenError;
176
- declare const index_CircuitBreakerOpenError: typeof CircuitBreakerOpenError;
177
- type index_ClampLimitOptions = ClampLimitOptions;
178
- type index_DataLoaderLike<K, V> = DataLoaderLike<K, V>;
179
- type index_DropOldOptions = DropOldOptions;
180
- type index_EnsureMonthlyOptions = EnsureMonthlyOptions;
181
- type index_HttpClientConfig = HttpClientConfig;
182
- type index_HttpClientInit = HttpClientInit;
183
- type index_LLMProviderAdapter = LLMProviderAdapter;
184
- type index_LLMRequest = LLMRequest;
185
- type index_LLMResponse = LLMResponse;
186
- type index_LLMRouter = LLMRouter;
187
- declare const index_LLMRouter: typeof LLMRouter;
188
- type index_LLMRouterOptions = LLMRouterOptions;
189
- type index_LeaderLockOptions = LeaderLockOptions;
190
- type index_LeaderLockRedis = LeaderLockRedis;
191
- type index_LeaderLockResult<T> = LeaderLockResult<T>;
192
- type index_LoaderBuilder<Ctx, M extends LoaderMap> = LoaderBuilder<Ctx, M>;
193
- type index_LoaderMap = LoaderMap;
194
- type index_PaginateInput<TWhere, TOrderBy> = PaginateInput<TWhere, TOrderBy>;
195
- type index_PaginateResult<TItem> = PaginateResult<TItem>;
196
- type index_PrismaModelLike<TItem, TWhere, TOrderBy> = PrismaModelLike<TItem, TWhere, TOrderBy>;
197
- type index_PrismaRawClient = PrismaRawClient;
198
- type index_RateLimitInput = RateLimitInput;
199
- type index_RateLimitRedis = RateLimitRedis;
200
- type index_RateLimitResult = RateLimitResult;
201
- type index_ReferenceObject = ReferenceObject;
202
- type index_RetryConfig = RetryConfig;
203
- declare const index___resetHttpClientBreakers: typeof __resetHttpClientBreakers;
204
- declare const index_buildCacheKey: typeof buildCacheKey;
205
- declare const index_buildLoaders: typeof buildLoaders;
206
- declare const index_clampLimit: typeof clampLimit;
207
- declare const index_createHttpClient: typeof createHttpClient;
208
- declare const index_dropOldPartitions: typeof dropOldPartitions;
209
- declare const index_ensureMonthlyPartitions: typeof ensureMonthlyPartitions;
210
- declare const index_getNamespaceVersion: typeof getNamespaceVersion;
211
- declare const index_httpClient: typeof httpClient;
212
- declare const index_invalidateNamespace: typeof invalidateNamespace;
213
- declare const index_monthlyPartitionName: typeof monthlyPartitionName;
214
- declare const index_paginate: typeof paginate;
215
- declare const index_rateLimitIncr: typeof rateLimitIncr;
216
- declare const index_resolveReferenceLoader: typeof resolveReferenceLoader;
217
- declare const index_withLeaderLock: typeof withLeaderLock;
218
- declare namespace index {
219
- export { type index_BreakerConfig as BreakerConfig, type index_CacheVersionRedis as CacheVersionRedis, index_CircuitBreakerOpenError as CircuitBreakerOpenError, type index_ClampLimitOptions as ClampLimitOptions, type index_DataLoaderLike as DataLoaderLike, type index_DropOldOptions as DropOldOptions, type index_EnsureMonthlyOptions as EnsureMonthlyOptions, type index_HttpClientConfig as HttpClientConfig, type index_HttpClientInit as HttpClientInit, type index_LLMProviderAdapter as LLMProviderAdapter, type index_LLMRequest as LLMRequest, type index_LLMResponse as LLMResponse, index_LLMRouter as LLMRouter, type index_LLMRouterOptions as LLMRouterOptions, type index_LeaderLockOptions as LeaderLockOptions, type index_LeaderLockRedis as LeaderLockRedis, type index_LeaderLockResult as LeaderLockResult, type index_LoaderBuilder as LoaderBuilder, type index_LoaderMap as LoaderMap, type index_PaginateInput as PaginateInput, type index_PaginateResult as PaginateResult, type index_PrismaModelLike as PrismaModelLike, type index_PrismaRawClient as PrismaRawClient, type index_RateLimitInput as RateLimitInput, type index_RateLimitRedis as RateLimitRedis, type index_RateLimitResult as RateLimitResult, type index_ReferenceObject as ReferenceObject, type index_RetryConfig as RetryConfig, index___resetHttpClientBreakers as __resetHttpClientBreakers, index_buildCacheKey as buildCacheKey, index_buildLoaders as buildLoaders, index_clampLimit as clampLimit, index_createHttpClient as createHttpClient, index_dropOldPartitions as dropOldPartitions, index_ensureMonthlyPartitions as ensureMonthlyPartitions, index_getNamespaceVersion as getNamespaceVersion, index_httpClient as httpClient, index_invalidateNamespace as invalidateNamespace, index_monthlyPartitionName as monthlyPartitionName, index_paginate as paginate, index_rateLimitIncr as rateLimitIncr, index_resolveReferenceLoader as resolveReferenceLoader, index_withLeaderLock as withLeaderLock };
220
- }
221
-
222
- export { ensureMonthlyPartitions as A, type BreakerConfig as B, type CacheVersionRedis as C, type DataLoaderLike as D, type EnsureMonthlyOptions as E, getNamespaceVersion as F, httpClient as G, type HttpClientConfig as H, invalidateNamespace as I, monthlyPartitionName as J, paginate as K, type LLMProviderAdapter as L, rateLimitIncr as M, resolveReferenceLoader as N, withLeaderLock as O, type PaginateInput as P, type RateLimitInput as R, __resetHttpClientBreakers as _, CircuitBreakerOpenError as a, type ClampLimitOptions as b, type DropOldOptions as c, type HttpClientInit as d, type LLMRequest as e, type LLMResponse as f, LLMRouter as g, type LLMRouterOptions as h, index as i, type LeaderLockOptions as j, type LeaderLockRedis as k, type LeaderLockResult as l, type LoaderBuilder as m, type LoaderMap as n, type PaginateResult as o, type PrismaModelLike as p, type PrismaRawClient as q, type RateLimitRedis as r, type RateLimitResult as s, type ReferenceObject as t, type RetryConfig as u, buildCacheKey as v, buildLoaders as w, clampLimit as x, createHttpClient as y, dropOldPartitions as z };
@@ -1,5 +0,0 @@
1
- export { createPinoLogger } from './chunk-E5USZ2MR.js';
2
- import './chunk-CBZNP6RF.js';
3
- import './chunk-XE4OXN2W.js';
4
- //# sourceMappingURL=pino-logger-NVZXQPWO.js.map
5
- //# sourceMappingURL=pino-logger-NVZXQPWO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/telemetry/sdk.ts"],"names":["isThenable","value","then","asyncDisposeMetricReader","metricReaderCandidate","shutdown","result","call","createOtelSdk","cfg","sdkNodeMod","sdkMod","resourcesMod","resources","semMod","sem","traceExpMod","traceExp","metricsExp","metricsExpMod","undefined","metricReader","metricsEnabled","metricsDropReason","OTLPMetricExporter","metricsSdkMod","metricsSdk","candidate","PeriodicExportingMetricReader","exporter","url","otlpEndpoint","replace","setProducer","setMetricProducer","sampler","traceBaseMod","traceBase","ParentBasedSampler","root","TraceIdRatioBasedSampler","Math","min","max","sampleRatio","autoInstrumentations","autoMod","auto","getNodeAutoInstrumentations","enabled","serviceNamespaceByBoundary","wspace","global","gateway","resourceAttributes","serviceName","serviceVersion","boundary","env","module","serviceInstanceId","process","clusterName","resource","resourceFromAttributes","traceExporter","OTLPTraceExporter","nodeSdk","NodeSDK","instrumentations","startResult","start","otelApiMod","globalThis","__otelApi"],"mappings":"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","file":"sdk-UWFH5PY7.js","sourcesContent":["/**\n * Thin wrapper that initializes `@opentelemetry/sdk-node` with the\n * OTLPTrace + OTLPMetric exporters and standard auto-instrumentations.\n *\n * All imports are dynamic so services that haven't installed sdk-node\n * still compile and run. The function resolves `undefined` when the SDK\n * isn't available, letting `bootstrapTelemetry` fall back gracefully.\n */\nimport type { Boundary, Env } from './index.js';\n\nexport interface OtelSdkConfig {\n serviceName: string;\n serviceVersion: string;\n boundary: Boundary;\n module?: string;\n env: Env;\n otlpEndpoint: string;\n sampleRatio: number;\n}\n\nexport interface OtelSdkHandle {\n shutdown: () => Promise<void>;\n metricsEnabled: boolean;\n metricsDropReason?: string;\n}\n\ntype Thenable = {\n then: (onfulfilled?: (value: void) => void, onrejected?: (reason: unknown) => void) => unknown;\n};\n\nconst isThenable = (value: unknown): value is Thenable => {\n return typeof value === 'object' && value !== null && typeof (value as { then?: unknown }).then === 'function';\n};\n\nconst asyncDisposeMetricReader = async (metricReaderCandidate: unknown): Promise<void> => {\n const shutdown = (metricReaderCandidate as { shutdown?: () => void | Promise<void> }).shutdown;\n if (typeof shutdown === 'function') {\n const result = shutdown.call(metricReaderCandidate) as unknown;\n if (isThenable(result)) await result;\n }\n};\n\nexport async function createOtelSdk(cfg: OtelSdkConfig): Promise<OtelSdkHandle> {\n // Use local string variables so TypeScript skips static module resolution for\n // optional peer dependencies that may not be installed.\n const sdkNodeMod = '@opentelemetry/sdk-node';\n const sdkMod = (await import(sdkNodeMod)) as unknown as {\n NodeSDK: new (init: Record<string, unknown>) => {\n start: () => void;\n shutdown: () => Promise<void>;\n };\n };\n\n const resourcesMod = '@opentelemetry/resources';\n const resources = (await import(resourcesMod)) as unknown as {\n resourceFromAttributes: (attrs: Record<string, string | number>) => unknown;\n };\n\n const semMod = '@opentelemetry/semantic-conventions';\n const sem = (await import(semMod)) as unknown as Record<string, string>;\n\n const traceExpMod = '@opentelemetry/exporter-trace-otlp-http';\n const traceExp = (await import(traceExpMod)) as unknown as {\n OTLPTraceExporter: new (init: Record<string, string>) => unknown;\n };\n\n let metricsExp: { OTLPMetricExporter?: new (init: Record<string, string>) => unknown } | undefined;\n try {\n const metricsExpMod = '@opentelemetry/exporter-metrics-otlp-http';\n metricsExp = await import(metricsExpMod);\n } catch {\n metricsExp = undefined;\n }\n\n let metricReader: unknown;\n let metricsEnabled = false;\n let metricsDropReason: string | undefined;\n if (metricsExp?.OTLPMetricExporter) {\n try {\n const metricsSdkMod = '@opentelemetry/sdk-metrics';\n const metricsSdk = (await import(metricsSdkMod)) as unknown as {\n PeriodicExportingMetricReader: new (init: Record<string, unknown>) => unknown;\n };\n const candidate = new metricsSdk.PeriodicExportingMetricReader({\n exporter: new metricsExp.OTLPMetricExporter({\n url: `${cfg.otlpEndpoint.replace(/\\/$/, '')}/v1/metrics`,\n }),\n });\n // Pre-flight API compatibility check. Some OTel package version\n // combinations construct `PeriodicExportingMetricReader` successfully\n // but lack `setMetricProducer` on the prototype chain (mixed\n // sdk-metrics versions, or runtime-specific class-inheritance\n // quirks — Bun has surfaced this in the past). Without the check,\n // `NodeSDK.start()` may register the global tracer provider BEFORE\n // it tries to call `setMetricProducer` and throws — leaving the\n // global tracer pointing at a half-initialized provider whose\n // span pipeline never drains. Skipping the metric reader when the\n // API isn't there avoids that whole failure mode in one pass.\n const setProducer = (candidate as { setMetricProducer?: unknown }).setMetricProducer;\n if (typeof setProducer === 'function') {\n metricReader = candidate;\n metricsEnabled = true;\n } else {\n metricsDropReason =\n 'setMetricProducer is not a function on PeriodicExportingMetricReader; skipping metrics path';\n await asyncDisposeMetricReader(candidate);\n metricReader = undefined;\n }\n } catch {\n if (metricsDropReason === undefined) {\n metricsDropReason = 'metric reader construction or compatibility check failed';\n }\n metricReader = undefined;\n }\n }\n\n let sampler: unknown;\n try {\n const traceBaseMod = '@opentelemetry/sdk-trace-base';\n const traceBase = (await import(traceBaseMod)) as unknown as {\n ParentBasedSampler: new (init: Record<string, unknown>) => unknown;\n TraceIdRatioBasedSampler: new (ratio: number) => unknown;\n };\n sampler = new traceBase.ParentBasedSampler({\n root: new traceBase.TraceIdRatioBasedSampler(Math.min(1, Math.max(0, cfg.sampleRatio))),\n });\n } catch {\n sampler = undefined;\n }\n\n // Some services have auto-instrumentations installed; optional.\n let autoInstrumentations: unknown[] | undefined;\n try {\n const autoMod = '@opentelemetry/auto-instrumentations-node';\n const auto = (await import(autoMod)) as unknown as {\n getNodeAutoInstrumentations: (cfg?: Record<string, unknown>) => unknown[];\n };\n autoInstrumentations = auto.getNodeAutoInstrumentations({\n '@opentelemetry/instrumentation-fs': { enabled: false },\n });\n } catch {\n autoInstrumentations = undefined;\n }\n\n const serviceNamespaceByBoundary: Record<Boundary, string> = {\n wspace: 'workspaces',\n global: 'tenant',\n gateway: 'gateways',\n };\n const resourceAttributes: Record<string, string> = {\n [sem['SEMRESATTRS_SERVICE_NAME'] ?? 'service.name']: cfg.serviceName,\n [sem['SEMRESATTRS_SERVICE_VERSION'] ?? 'service.version']: cfg.serviceVersion,\n [sem['SEMRESATTRS_SERVICE_NAMESPACE'] ?? 'service.namespace']: serviceNamespaceByBoundary[cfg.boundary],\n [sem['SEMRESATTRS_DEPLOYMENT_ENVIRONMENT'] ?? 'deployment.environment']: cfg.env,\n 'burdenoff.boundary': cfg.boundary,\n };\n if (cfg.module) resourceAttributes['burdenoff.module'] = cfg.module;\n const serviceInstanceId = process.env['POD_NAME'] ?? process.env['HOSTNAME'];\n if (serviceInstanceId) resourceAttributes['service.instance.id'] = serviceInstanceId;\n const clusterName = process.env['CLUSTER_NAME'];\n if (clusterName) {\n resourceAttributes['cluster'] = clusterName;\n resourceAttributes['k8s.cluster.name'] = clusterName;\n }\n\n const resource = resources.resourceFromAttributes(resourceAttributes);\n\n const traceExporter = new traceExp.OTLPTraceExporter({\n url: `${cfg.otlpEndpoint.replace(/\\/$/, '')}/v1/traces`,\n });\n\n // Single NodeSDK, single start. The pre-flight `setMetricProducer`\n // check above means we never pass an incompatible metric reader into\n // NodeSDK construction — so we no longer need the prior catch+rebuild\n // fallback dance, which had its own side-effect: the failed first\n // NodeSDK could leave the global tracer provider partially registered,\n // and the second NodeSDK's `setGlobalTracerProvider` becomes a no-op\n // — meaning spans flow into the FIRST (broken) provider and never\n // reach the exporter. Eliminating the fallback eliminates that hazard.\n const nodeSdk = new sdkMod.NodeSDK({\n resource,\n traceExporter,\n ...(metricReader ? { metricReader } : {}),\n ...(sampler ? { sampler } : {}),\n ...(autoInstrumentations ? { instrumentations: autoInstrumentations } : {}),\n });\n // NodeSDK.start() returns void in modern versions and Promise<void> in older\n // ones. Cast to a permissive thenable shape so awaiting works either way\n // without tripping `@typescript-eslint/await-thenable`.\n const startResult = nodeSdk.start() as unknown;\n if (isThenable(startResult)) {\n await startResult;\n }\n\n // Stash the @opentelemetry/api reference for pino-logger's mixin.\n try {\n const otelApiMod = '@opentelemetry/api';\n (globalThis as unknown as { __otelApi?: unknown }).__otelApi = await import(otelApiMod);\n } catch {\n // Non-fatal.\n }\n\n return {\n shutdown: async (): Promise<void> => nodeSdk.shutdown(),\n metricsEnabled,\n metricsDropReason,\n };\n}\n"]}