@burdenoff/be-sdk 2026.618.1 → 2026.623.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/auth/index.d.ts +3 -2
- package/dist/auth/index.js +2 -2
- package/dist/{chunk-XNQUN3AE.js → chunk-4OQRBSHM.js} +3 -3
- package/dist/{chunk-XNQUN3AE.js.map → chunk-4OQRBSHM.js.map} +1 -1
- package/dist/{chunk-FTDQ6NY5.js → chunk-6NB7P6SR.js} +3 -3
- package/dist/{chunk-FTDQ6NY5.js.map → chunk-6NB7P6SR.js.map} +1 -1
- package/dist/{chunk-L2P4CJUR.js → chunk-B527JLOB.js} +6 -2
- package/dist/chunk-B527JLOB.js.map +1 -0
- package/dist/{chunk-SMGTXYFR.js → chunk-EZ4PKRUK.js} +2 -2
- package/dist/chunk-EZ4PKRUK.js.map +1 -0
- package/dist/{chunk-5FEOFBQ4.js → chunk-F5BPKP75.js} +3 -3
- package/dist/{chunk-5FEOFBQ4.js.map → chunk-F5BPKP75.js.map} +1 -1
- package/dist/{chunk-ZHQUXD6S.js → chunk-IUL5TEKE.js} +3 -3
- package/dist/{chunk-ZHQUXD6S.js.map → chunk-IUL5TEKE.js.map} +1 -1
- package/dist/{chunk-N7UJFZQH.js → chunk-OWUVYM2S.js} +6 -47
- package/dist/chunk-OWUVYM2S.js.map +1 -0
- package/dist/{chunk-FKSMQLIV.js → chunk-SS4XWRYR.js} +3 -3
- package/dist/{chunk-FKSMQLIV.js.map → chunk-SS4XWRYR.js.map} +1 -1
- package/dist/{chunk-ZPEDC5V3.js → chunk-TYXGWVRL.js} +5 -5
- package/dist/{chunk-ZPEDC5V3.js.map → chunk-TYXGWVRL.js.map} +1 -1
- package/dist/{chunk-X7QMT2P6.js → chunk-UJI2S556.js} +3 -3
- package/dist/{chunk-X7QMT2P6.js.map → chunk-UJI2S556.js.map} +1 -1
- package/dist/chunk-VFCMR5GX.js +49 -0
- package/dist/chunk-VFCMR5GX.js.map +1 -0
- package/dist/{chunk-HRCWJLCZ.js → chunk-YEA4BZOL.js} +8 -4
- package/dist/chunk-YEA4BZOL.js.map +1 -0
- package/dist/{chunk-XR3KUHJ5.js → chunk-Z2423JIB.js} +3 -3
- package/dist/{chunk-XR3KUHJ5.js.map → chunk-Z2423JIB.js.map} +1 -1
- package/dist/database/index.js +2 -2
- package/dist/event-queue/index.d.ts +3 -3
- package/dist/export/index.js +4 -3
- package/dist/feature-flags/index.d.ts +1 -1
- package/dist/feature-flags/index.js +2 -1
- package/dist/gateway/index.d.ts +1 -1
- package/dist/gateway/index.js +3 -2
- package/dist/gateway/security/index.js +1 -1
- package/dist/graph/index.d.ts +4 -3
- package/dist/graph/index.js +2 -2
- package/dist/{graphql-CNhiZ89U.d.ts → graphql-BRj5KPOL.d.ts} +3 -2
- package/dist/{index-DraeealK.d.ts → index-1qCbBvKE.d.ts} +2 -2
- package/dist/{index-D7BJuXP3.d.ts → index-B3ECnOLp.d.ts} +2 -2
- package/dist/{index-CVFEyBvK.d.ts → index-BIhZJ1w7.d.ts} +1 -1
- package/dist/{index-DYQF_AIz.d.ts → index-BN_-AWdb.d.ts} +2 -2
- package/dist/{index-jOuh_TKn.d.ts → index-BdPnlJ8_.d.ts} +2 -0
- package/dist/{index-BKjt3X8L.d.ts → index-Bm6MYdqS.d.ts} +5 -2
- package/dist/{index-B-w7NWpD.d.ts → index-CNy4MwKc.d.ts} +1 -1
- package/dist/{index-D9RN6jp1.d.ts → index-DDCOGyYh.d.ts} +4 -0
- package/dist/{index-DohlGQGw.d.ts → index-DsBZRR82.d.ts} +3 -3
- package/dist/index.d.ts +15 -15
- package/dist/index.js +113 -32
- package/dist/index.js.map +1 -1
- package/dist/init/index.js +4 -3
- package/dist/instrumentation/index.d.ts +4 -3
- package/dist/logger/index.d.ts +3 -2
- package/dist/notifications/index.d.ts +4 -3
- package/dist/notifications/index.js +2 -2
- package/dist/rbac/index.d.ts +2 -2
- package/dist/rbac/index.js +2 -2
- package/dist/resource-caps/index.d.ts +3 -2
- package/dist/telemetry/index.d.ts +5 -4
- package/dist/telemetry/index.js.map +1 -1
- package/dist/tracker/index.d.ts +5 -4
- package/dist/tracker/index.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-HRCWJLCZ.js.map +0 -1
- package/dist/chunk-L2P4CJUR.js.map +0 -1
- package/dist/chunk-N7UJFZQH.js.map +0 -1
- package/dist/chunk-SMGTXYFR.js.map +0 -1
package/dist/init/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { getSDKState, initializeBurdenoffSDK, isSDKInitialized, resetSDK } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { getSDKState, initializeBurdenoffSDK, isSDKInitialized, resetSDK } from '../chunk-F5BPKP75.js';
|
|
2
|
+
import '../chunk-OWUVYM2S.js';
|
|
3
|
+
import '../chunk-B527JLOB.js';
|
|
4
4
|
import '../chunk-UIMPJNWC.js';
|
|
5
|
+
import '../chunk-VFCMR5GX.js';
|
|
5
6
|
import '../chunk-DXX6C6X6.js';
|
|
6
7
|
import '../chunk-YFOHAHZE.js';
|
|
7
8
|
import '../chunk-CBZNP6RF.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { A as ApolloInlineTraceOptions, C as CacheInstrumentationConfig, b as Counter, D as DEFAULT_CACHE_CONFIG, c as DEFAULT_DATABASE_CONFIG, d as DEFAULT_EVENT_QUEUE_CONFIG, e as DEFAULT_FEATURE_FLAGS, f as DEFAULT_GRAPHQL_CONFIG, g as DEFAULT_HTTP_CONFIG, h as DEFAULT_LOGGING_CONFIG, j as DEFAULT_METRICS_CONFIG, k as DEFAULT_TRACING_CONFIG, l as DatabaseInstrumentationConfig, E as ENV_VARS, m as EventQueueInstrumentationConfig, G as Gauge, n as GraphQLInstrumentationConfig, o as GraphQLOperationInfo, p as GraphQLOperationType, H as HTTPInstrumentationConfig, q as Histogram, r as InitializeInstrumentationOptions, t as Instrument, u as InstrumentationConfig, v as InstrumentationContextExtension, w as InstrumentationFeatureFlags, I as InstrumentationSetupResult, L as Log, x as LoggingConfig, M as Metric, y as MetricDefinition, z as MetricLabels, B as MetricsConfig, F as MetricsRegistry, O as OperationContext, P as PrometheusPluginOptions, J as STANDARD_METRICS, S as SetupInstrumentationOptions, K as Span, N as SpanAttributes, Q as SpanContext, R as SpanEvent, T as SpanKind, U as SpanStatus, V as Trace, W as TraceContext, X as Tracer, Y as TracingConfig, Z as UpDownCounter, _ as buildDatabaseConfig, $ as buildFeatureFlags, a0 as buildGraphQLConfig, a1 as buildInstrumentationConfig, a2 as buildMetricsConfig, a3 as buildTracingConfig, a4 as createApolloInlineTracePlugin, a5 as createCounter, a6 as createGauge, a7 as createGraphQLInstrumentationPlugin, a8 as createHistogram, a9 as createPrometheusPlugin, aa as createUpDownCounter, ab as extractOperationInfo, ac as extractTraceContext, ad as getGraphQLOperationFromContext, ae as getGraphQLSpanFromContext, af as getInstrumentationConfig, ag as getLogger, ah as getMetricsRegistry, ai as getTraceContext, aj as getTracer, i as initializeInstrumentation, ak as initializeInstrumentationConfig, al as initializeMetricsRegistry, am as initializeTracer, an as injectTraceContext, ao as instrumentResolver, ap as instrumentResolverMap, aq as instrumented, ar as isApolloInlineTraceAvailable, as as isFeatureEnabled, at as isInstrumentationConfigInitialized, au as isInstrumentationInitialized, av as isMetricsRegistryInitialized, aw as isPrometheusAvailable, ax as isTracerInitialized, ay as resetInstrumentation, az as resetInstrumentationConfig, aA as resetMetricsRegistry, s as setupInstrumentation, aB as startSpan, aC as traced, aD as updateInstrumentationConfig, aE as withSpan } from '../index-
|
|
2
|
-
export { l as logger } from '../index-
|
|
3
|
-
import '../index-
|
|
1
|
+
export { A as ApolloInlineTraceOptions, C as CacheInstrumentationConfig, b as Counter, D as DEFAULT_CACHE_CONFIG, c as DEFAULT_DATABASE_CONFIG, d as DEFAULT_EVENT_QUEUE_CONFIG, e as DEFAULT_FEATURE_FLAGS, f as DEFAULT_GRAPHQL_CONFIG, g as DEFAULT_HTTP_CONFIG, h as DEFAULT_LOGGING_CONFIG, j as DEFAULT_METRICS_CONFIG, k as DEFAULT_TRACING_CONFIG, l as DatabaseInstrumentationConfig, E as ENV_VARS, m as EventQueueInstrumentationConfig, G as Gauge, n as GraphQLInstrumentationConfig, o as GraphQLOperationInfo, p as GraphQLOperationType, H as HTTPInstrumentationConfig, q as Histogram, r as InitializeInstrumentationOptions, t as Instrument, u as InstrumentationConfig, v as InstrumentationContextExtension, w as InstrumentationFeatureFlags, I as InstrumentationSetupResult, L as Log, x as LoggingConfig, M as Metric, y as MetricDefinition, z as MetricLabels, B as MetricsConfig, F as MetricsRegistry, O as OperationContext, P as PrometheusPluginOptions, J as STANDARD_METRICS, S as SetupInstrumentationOptions, K as Span, N as SpanAttributes, Q as SpanContext, R as SpanEvent, T as SpanKind, U as SpanStatus, V as Trace, W as TraceContext, X as Tracer, Y as TracingConfig, Z as UpDownCounter, _ as buildDatabaseConfig, $ as buildFeatureFlags, a0 as buildGraphQLConfig, a1 as buildInstrumentationConfig, a2 as buildMetricsConfig, a3 as buildTracingConfig, a4 as createApolloInlineTracePlugin, a5 as createCounter, a6 as createGauge, a7 as createGraphQLInstrumentationPlugin, a8 as createHistogram, a9 as createPrometheusPlugin, aa as createUpDownCounter, ab as extractOperationInfo, ac as extractTraceContext, ad as getGraphQLOperationFromContext, ae as getGraphQLSpanFromContext, af as getInstrumentationConfig, ag as getLogger, ah as getMetricsRegistry, ai as getTraceContext, aj as getTracer, i as initializeInstrumentation, ak as initializeInstrumentationConfig, al as initializeMetricsRegistry, am as initializeTracer, an as injectTraceContext, ao as instrumentResolver, ap as instrumentResolverMap, aq as instrumented, ar as isApolloInlineTraceAvailable, as as isFeatureEnabled, at as isInstrumentationConfigInitialized, au as isInstrumentationInitialized, av as isMetricsRegistryInitialized, aw as isPrometheusAvailable, ax as isTracerInitialized, ay as resetInstrumentation, az as resetInstrumentationConfig, aA as resetMetricsRegistry, s as setupInstrumentation, aB as startSpan, aC as traced, aD as updateInstrumentationConfig, aE as withSpan } from '../index-BIhZJ1w7.js';
|
|
2
|
+
export { l as logger } from '../index-CNy4MwKc.js';
|
|
3
|
+
import '../index-DDCOGyYh.js';
|
|
4
|
+
import '../layer-GNAVXBMf.js';
|
package/dist/logger/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import '../index-
|
|
2
|
-
export { a as LogLevel, b as LogMeta, L as Logger, c as LoggerConfig, d as LoggerTransport, e as debug, f as error, g as log, l as logger, r as redactSensitiveFields, w as warn } from '../index-
|
|
1
|
+
import '../index-DDCOGyYh.js';
|
|
2
|
+
export { a as LogLevel, b as LogMeta, L as Logger, c as LoggerConfig, d as LoggerTransport, e as debug, f as error, g as log, l as logger, r as redactSensitiveFields, w as warn } from '../index-CNy4MwKc.js';
|
|
3
|
+
import '../layer-GNAVXBMf.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import '../graphql-
|
|
2
|
-
import '../index-
|
|
3
|
-
export { G as GetNotificationsOptions, b as Notification, c as NotificationChannel, d as NotificationPriority, e as NotificationResponse, N as NotificationType, a as NotificationsModule, R as RecipientInput, S as SendChannelNotificationOptions, f as SendNotificationOptions, g as SendTemplateNotificationOptions, T as TenantNotificationsModule } from '../index-
|
|
1
|
+
import '../graphql-BRj5KPOL.js';
|
|
2
|
+
import '../index-DDCOGyYh.js';
|
|
3
|
+
export { G as GetNotificationsOptions, b as Notification, c as NotificationChannel, d as NotificationPriority, e as NotificationResponse, N as NotificationType, a as NotificationsModule, R as RecipientInput, S as SendChannelNotificationOptions, f as SendNotificationOptions, g as SendTemplateNotificationOptions, T as TenantNotificationsModule } from '../index-1qCbBvKE.js';
|
|
4
4
|
import 'graphql-request';
|
|
5
|
+
import '../layer-GNAVXBMf.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { NotificationChannel, NotificationPriority, NotificationType, NotificationsModule, TenantNotificationsModule } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { NotificationChannel, NotificationPriority, NotificationType, NotificationsModule, TenantNotificationsModule } from '../chunk-IUL5TEKE.js';
|
|
2
|
+
import '../chunk-EZ4PKRUK.js';
|
|
3
3
|
import '../chunk-YFOHAHZE.js';
|
|
4
4
|
import '../chunk-CBZNP6RF.js';
|
|
5
5
|
import '../chunk-XE4OXN2W.js';
|
package/dist/rbac/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BurdenoffGraphQLClient } from '../graphql-
|
|
2
|
-
import { S as SDKContext } from '../index-
|
|
1
|
+
import { B as BurdenoffGraphQLClient } from '../graphql-BRj5KPOL.js';
|
|
2
|
+
import { S as SDKContext } from '../index-DDCOGyYh.js';
|
|
3
3
|
import { Plugin } from '@envelop/core';
|
|
4
4
|
import { S as ServiceLayer } from '../layer-GNAVXBMf.js';
|
|
5
5
|
import 'graphql-request';
|
package/dist/rbac/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { RBACClient, RBACModule, createRBACClientFromEnv, createRBACDirective, createRBACDirectiveForLayer, createRBACDirectiveFromEnv } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { RBACClient, RBACModule, createRBACClientFromEnv, createRBACDirective, createRBACDirectiveForLayer, createRBACDirectiveFromEnv } from '../chunk-6NB7P6SR.js';
|
|
2
|
+
import '../chunk-EZ4PKRUK.js';
|
|
3
3
|
import '../chunk-YFOHAHZE.js';
|
|
4
4
|
import '../chunk-CBZNP6RF.js';
|
|
5
5
|
import '../chunk-XE4OXN2W.js';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { GraphQLError } from 'graphql';
|
|
2
|
-
import { B as BurdenoffGraphQLClient } from '../graphql-
|
|
2
|
+
import { B as BurdenoffGraphQLClient } from '../graphql-BRj5KPOL.js';
|
|
3
3
|
import 'graphql-request';
|
|
4
|
-
import '../index-
|
|
4
|
+
import '../index-DDCOGyYh.js';
|
|
5
|
+
import '../layer-GNAVXBMf.js';
|
|
5
6
|
|
|
6
7
|
type ResourceName = 'workspace' | 'workspaceMember' | 'sandbox' | 'vibe' | 'agent' | 'conversation' | 'message' | 'tag' | 'file' | 'group' | 'calendar' | 'scheduledTask' | 'form' | 'apiKey' | 'webhook';
|
|
7
8
|
type PlanTier = 'free' | 'paid';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { L as Logger } from '../index-
|
|
2
|
-
import { S as SetupInstrumentationOptions, I as InstrumentationSetupResult } from '../index-
|
|
3
|
-
export { i as initializeInstrumentation, s as setupInstrumentation } from '../index-
|
|
4
|
-
import '../index-
|
|
1
|
+
import { L as Logger } from '../index-CNy4MwKc.js';
|
|
2
|
+
import { S as SetupInstrumentationOptions, I as InstrumentationSetupResult } from '../index-BIhZJ1w7.js';
|
|
3
|
+
export { i as initializeInstrumentation, s as setupInstrumentation } from '../index-BIhZJ1w7.js';
|
|
4
|
+
import '../index-DDCOGyYh.js';
|
|
5
|
+
import '../layer-GNAVXBMf.js';
|
|
5
6
|
|
|
6
7
|
interface PrismaLike {
|
|
7
8
|
$queryRaw: (strings: TemplateStringsArray) => Promise<unknown>;
|
|
@@ -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 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","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"]}
|
package/dist/tracker/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import '../graphql-
|
|
2
|
-
import '../index-
|
|
3
|
-
export { a as ActivityTrackingOptions, P as ProductTracker, R as RbacCheckOptions, b as TrackOptions, c as TrackResult, T as TrackerModule, d as TrackingEvent, e as UNIFIED_TRACKER_CONSTANTS, f as UnifiedTrackerStub, g as UnifiedTrackingOptions, h as UsageMetricType, i as UsageTrackingOptions, j as createProductTracker, t as trackOperation, k as trackerStub } from '../index-
|
|
4
|
-
import '../index-
|
|
1
|
+
import '../graphql-BRj5KPOL.js';
|
|
2
|
+
import '../index-DDCOGyYh.js';
|
|
3
|
+
export { a as ActivityTrackingOptions, P as ProductTracker, R as RbacCheckOptions, b as TrackOptions, c as TrackResult, T as TrackerModule, d as TrackingEvent, e as UNIFIED_TRACKER_CONSTANTS, f as UnifiedTrackerStub, g as UnifiedTrackingOptions, h as UsageMetricType, i as UsageTrackingOptions, j as createProductTracker, t as trackOperation, k as trackerStub } from '../index-DsBZRR82.js';
|
|
4
|
+
import '../index-1qCbBvKE.js';
|
|
5
5
|
import 'graphql-request';
|
|
6
|
+
import '../layer-GNAVXBMf.js';
|
package/dist/tracker/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { TrackerModule, UNIFIED_TRACKER_CONSTANTS, UnifiedTrackerStub, UsageMetricType, createProductTracker, trackOperation, trackerStub } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { TrackerModule, UNIFIED_TRACKER_CONSTANTS, UnifiedTrackerStub, UsageMetricType, createProductTracker, trackOperation, trackerStub } from '../chunk-TYXGWVRL.js';
|
|
2
|
+
import '../chunk-6NB7P6SR.js';
|
|
3
|
+
import '../chunk-IUL5TEKE.js';
|
|
4
|
+
import '../chunk-EZ4PKRUK.js';
|
|
5
5
|
import '../chunk-YFOHAHZE.js';
|
|
6
6
|
import '../chunk-CBZNP6RF.js';
|
|
7
7
|
import '../chunk-XE4OXN2W.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/be-sdk",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.623.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/feature-flags/index.ts","../src/feature-flags/provider.ts"],"names":["EVALUATE_QUERY","FeatureFlagProvider","gatewayUrl","cacheTtlMs","serviceToken","defaultActorType","cache","Map","config","cacheTtlSeconds","resolveBoolean","flagKey","defaultValue","context","evaluation","getEvaluation","value","reason","flagType","Boolean","variant","undefined","errorCode","resolveString","String","resolveNumber","Number","resolveObject","isEnabled","result","workspaceId","actorType","actorId","evaluateAll","keys","evaluations","fetchEvaluations","key","set","invalidateCache","cacheKey","buildCacheKey","delete","clear","get","cached","expiresAt","Date","now","response","fetch","method","headers","Authorization","ContextManager","getCfAccessHeaders","body","JSON","stringify","query","variables","input","ok","json","errors","data","evaluateFeatureFlags","ctx"],"mappings":";;;;AAAA,IAAA,qBAAA,GAAA;;;;;;ACsCA,IAAMA,cAAAA,GAAiB;;;;;;;;;;;;;;AAsBhB,IAAMC,sBAAN,MAAMA;EA5Db;;;AA6DmBC,EAAAA,UAAAA;AACAC,EAAAA,UAAAA;AACAC,EAAAA,YAAAA;AACAC,EAAAA,gBAAAA;;AAGAC,EAAAA,KAAAA,uBAAYC,GAAAA,EAAAA;AAE7B,EAAA,WAAA,CAAYC,MAAAA,EAAmC;AAC7C,IAAA,IAAA,CAAKN,aAAaM,MAAAA,CAAON,UAAAA;AACzB,IAAA,IAAA,CAAKC,UAAAA,GAAAA,CAAcK,MAAAA,CAAOC,eAAAA,IAAmB,EAAA,IAAM,GAAA;AACnD,IAAA,IAAA,CAAKL,eAAeI,MAAAA,CAAOJ,YAAAA;AAC3B,IAAA,IAAA,CAAKC,gBAAAA,GAAmBG,OAAOH,gBAAAA,IAAoB,SAAA;AACrD,EAAA;;;;;;;;;;;;EAcA,MAAMK,cAAAA,CACJC,OAAAA,EACAC,YAAAA,EACAC,OAAAA,EACqC;AACrC,IAAA,MAAMC,UAAAA,GAAa,MAAM,IAAA,CAAKC,aAAAA,CAAcJ,SAASE,OAAAA,CAAAA;AACrD,IAAA,IAAI,CAACC,UAAAA,EAAY;AACf,MAAA,OAAO;QACLE,KAAAA,EAAOJ,YAAAA;QACPK,MAAAA,EAAQ,SAAA;QACRC,QAAAA,EAAU;AACZ,OAAA;AACF,IAAA;AAEA,IAAA,OAAO;MACLF,KAAAA,EAAOG,OAAAA,CAAQL,WAAWE,KAAK,CAAA;AAC/BI,MAAAA,OAAAA,EAASN,WAAWM,OAAAA,IAAWC,MAAAA;AAC/BJ,MAAAA,MAAAA,EAAQH,UAAAA,CAAWG,MAAAA;AACnBC,MAAAA,QAAAA,EAAUJ,UAAAA,CAAWI,QAAAA;AACrBI,MAAAA,SAAAA,EAAWR,WAAWQ,SAAAA,IAAaD;AACrC,KAAA;AACF,EAAA;;;;EAKA,MAAME,aAAAA,CACJZ,OAAAA,EACAC,YAAAA,EACAC,OAAAA,EACoC;AACpC,IAAA,MAAMC,UAAAA,GAAa,MAAM,IAAA,CAAKC,aAAAA,CAAcJ,SAASE,OAAAA,CAAAA;AACrD,IAAA,IAAI,CAACC,UAAAA,EAAY;AACf,MAAA,OAAO;QACLE,KAAAA,EAAOJ,YAAAA;QACPK,MAAAA,EAAQ,SAAA;QACRC,QAAAA,EAAU;AACZ,OAAA;AACF,IAAA;AAEA,IAAA,OAAO;MACLF,KAAAA,EAAOQ,MAAAA,CAAOV,WAAWE,KAAK,CAAA;AAC9BI,MAAAA,OAAAA,EAASN,WAAWM,OAAAA,IAAWC,MAAAA;AAC/BJ,MAAAA,MAAAA,EAAQH,UAAAA,CAAWG,MAAAA;AACnBC,MAAAA,QAAAA,EAAUJ,UAAAA,CAAWI,QAAAA;AACrBI,MAAAA,SAAAA,EAAWR,WAAWQ,SAAAA,IAAaD;AACrC,KAAA;AACF,EAAA;;;;EAKA,MAAMI,aAAAA,CACJd,OAAAA,EACAC,YAAAA,EACAC,OAAAA,EACoC;AACpC,IAAA,MAAMC,UAAAA,GAAa,MAAM,IAAA,CAAKC,aAAAA,CAAcJ,SAASE,OAAAA,CAAAA;AACrD,IAAA,IAAI,CAACC,UAAAA,EAAY;AACf,MAAA,OAAO;QACLE,KAAAA,EAAOJ,YAAAA;QACPK,MAAAA,EAAQ,SAAA;QACRC,QAAAA,EAAU;AACZ,OAAA;AACF,IAAA;AAEA,IAAA,OAAO;MACLF,KAAAA,EAAOU,MAAAA,CAAOZ,WAAWE,KAAK,CAAA;AAC9BI,MAAAA,OAAAA,EAASN,WAAWM,OAAAA,IAAWC,MAAAA;AAC/BJ,MAAAA,MAAAA,EAAQH,UAAAA,CAAWG,MAAAA;AACnBC,MAAAA,QAAAA,EAAUJ,UAAAA,CAAWI,QAAAA;AACrBI,MAAAA,SAAAA,EAAWR,WAAWQ,SAAAA,IAAaD;AACrC,KAAA;AACF,EAAA;;;;EAKA,MAAMM,aAAAA,CACJhB,OAAAA,EACAC,YAAAA,EACAC,OAAAA,EAC+B;AAC/B,IAAA,MAAMC,UAAAA,GAAa,MAAM,IAAA,CAAKC,aAAAA,CAAcJ,SAASE,OAAAA,CAAAA;AACrD,IAAA,IAAI,CAACC,UAAAA,EAAY;AACf,MAAA,OAAO;QACLE,KAAAA,EAAOJ,YAAAA;QACPK,MAAAA,EAAQ,SAAA;QACRC,QAAAA,EAAU;AACZ,OAAA;AACF,IAAA;AAEA,IAAA,OAAO;AACLF,MAAAA,KAAAA,EAAOF,UAAAA,CAAWE,KAAAA;AAClBI,MAAAA,OAAAA,EAASN,WAAWM,OAAAA,IAAWC,MAAAA;AAC/BJ,MAAAA,MAAAA,EAAQH,UAAAA,CAAWG,MAAAA;AACnBC,MAAAA,QAAAA,EAAUJ,UAAAA,CAAWI,QAAAA;AACrBI,MAAAA,SAAAA,EAAWR,WAAWQ,SAAAA,IAAaD;AACrC,KAAA;AACF,EAAA;;;;;;;;;;;;;;;EAiBA,MAAMO,SAAAA,CAAUjB,SAAiBE,OAAAA,EAA+C;AAC9E,IAAA,MAAMgB,SAAS,MAAM,IAAA,CAAKnB,cAAAA,CACxBC,OAAAA,EACA,MACAE,OAAAA,IAAW;MAAEiB,WAAAA,EAAa,QAAA;MAAUC,SAAAA,EAAW,SAAA;MAAWC,OAAAA,EAAS;KAAO,CAAA;AAE5E,IAAA,OAAOH,MAAAA,CAAOb,KAAAA;AAChB,EAAA;;;;;EAMA,MAAMiB,WAAAA,CAAYpB,SAA4BqB,IAAAA,EAAmE;AAC/G,IAAA,MAAMC,WAAAA,GAAc,MAAM,IAAA,CAAKC,gBAAAA,CAAiBvB,SAASqB,IAAAA,CAAAA;AACzD,IAAA,MAAML,MAAAA,uBAAatB,GAAAA,EAAAA;AAEnB,IAAA,KAAA,MAAW,CAAC8B,GAAAA,EAAKvB,UAAAA,CAAAA,IAAeqB,WAAAA,EAAa;AAC3CN,MAAAA,MAAAA,CAAOS,IAAID,GAAAA,EAAK;AACdrB,QAAAA,KAAAA,EAAOF,UAAAA,CAAWE,KAAAA;AAClBI,QAAAA,OAAAA,EAASN,WAAWM,OAAAA,IAAWC,MAAAA;AAC/BJ,QAAAA,MAAAA,EAAQH,UAAAA,CAAWG,MAAAA;AACnBC,QAAAA,QAAAA,EAAUJ,UAAAA,CAAWI,QAAAA;AACrBI,QAAAA,SAAAA,EAAWR,WAAWQ,SAAAA,IAAaD;OACrC,CAAA;AACF,IAAA;AAEA,IAAA,OAAOQ,MAAAA;AACT,EAAA;;;;;AAMAU,EAAAA,eAAAA,CAAgB1B,OAAAA,EAAmC;AACjD,IAAA,IAAIA,OAAAA,EAAS;AACX,MAAA,MAAM2B,QAAAA,GAAW,IAAA,CAAKC,aAAAA,CAAc5B,OAAAA,CAAAA;AACpC,MAAA,IAAA,CAAKP,KAAAA,CAAMoC,OAAOF,QAAAA,CAAAA;IACpB,CAAA,MAAO;AACL,MAAA,IAAA,CAAKlC,MAAMqC,KAAAA,EAAK;AAClB,IAAA;AACF,EAAA;;;;;;;EASA,MAAc5B,aAAAA,CAAcJ,SAAiBE,OAAAA,EAAwE;AACnH,IAAA,IAAI;AACF,MAAA,MAAMsB,WAAAA,GAAc,MAAM,IAAA,CAAKC,gBAAAA,CAAiBvB,OAAAA,CAAAA;AAChD,MAAA,OAAOsB,WAAAA,CAAYS,GAAAA,CAAIjC,OAAAA,CAAAA,IAAY,IAAA;IACrC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AACT,IAAA;AACF,EAAA;;;;EAKA,MAAcyB,gBAAAA,CACZvB,SACAqB,IAAAA,EACsC;AACtC,IAAA,MAAMM,QAAAA,GAAW,IAAA,CAAKC,aAAAA,CAAc5B,OAAAA,CAAAA;AACpC,IAAA,MAAMgC,MAAAA,GAAS,IAAA,CAAKvC,KAAAA,CAAMsC,GAAAA,CAAIJ,QAAAA,CAAAA;AAE9B,IAAA,IAAIK,MAAAA,IAAUA,MAAAA,CAAOC,SAAAA,GAAYC,IAAAA,CAAKC,KAAG,EAAI;AAC3C,MAAA,OAAOH,MAAAA,CAAOV,WAAAA;AAChB,IAAA;AAIA,IAAA,IAAI,CAACtB,SAASiB,WAAAA,EAAa;AACzB,MAAA,2BAAWvB,GAAAA,EAAAA;AACb,IAAA;AAGA,IAAA,IAAI;AACF,MAAA,MAAM0C,QAAAA,GAAW,MAAMC,KAAAA,CAAM,IAAA,CAAKhD,UAAAA,EAAY;QAC5CiD,MAAAA,EAAQ,MAAA;QACRC,OAAAA,EAAS;UACP,cAAA,EAAgB,kBAAA;AAChB,UAAA,GAAIvC,QAAQmB,OAAAA,IAAW;AAAE,YAAA,YAAA,EAAcnB,OAAAA,CAAQmB;AAAQ,WAAA;UACvD,cAAA,EAAgBnB,OAAAA,CAAQkB,aAAa,IAAA,CAAK1B,gBAAAA;AAC1C,UAAA,gBAAA,EAAkBQ,OAAAA,CAAQiB,WAAAA;AAC1B,UAAA,GAAI,KAAK1B,YAAAA,IAAgB;YAAEiD,aAAAA,EAAe,CAAA,OAAA,EAAU,KAAKjD,YAAY,CAAA;AAAG,WAAA;;;;AAIxE,UAAA,GAAGkD,eAAeC,kBAAAA;AACpB,SAAA;AACAC,QAAAA,IAAAA,EAAMC,KAAKC,SAAAA,CAAU;UACnBC,KAAAA,EAAO3D,cAAAA;UACP4D,SAAAA,EAAW;YACTC,KAAAA,EAAO;AACL/B,cAAAA,WAAAA,EAAajB,OAAAA,CAAQiB,WAAAA;AACrBI,cAAAA,IAAAA,EAAMA,IAAAA,IAAQ;AAChB;AACF;SACF;OACF,CAAA;AAEA,MAAA,IAAI,CAACe,SAASa,EAAAA,EAAI;AAEhB,QAAA,2BAAWvD,GAAAA,EAAAA;AACb,MAAA;AAEA,MAAA,MAAMwD,IAAAA,GAAQ,MAAMd,QAAAA,CAASc,IAAAA,EAAI;AASjC,MAAA,IAAIA,KAAKC,MAAAA,IAAU,CAACD,IAAAA,CAAKE,IAAAA,EAAMC,sBAAsB/B,WAAAA,EAAa;AAChE,QAAA,2BAAW5B,GAAAA,EAAAA;AACb,MAAA;AAEA,MAAA,MAAM4B,WAAAA,uBAAkB5B,GAAAA,EAAAA;AACxB,MAAA,KAAA,MAAWO,UAAAA,IAAciD,IAAAA,CAAKE,IAAAA,CAAKC,oBAAAA,CAAqB/B,WAAAA,EAAa;AACnEA,QAAAA,WAAAA,CAAYG,GAAAA,CAAIxB,UAAAA,CAAWuB,GAAAA,EAAKvB,UAAAA,CAAAA;AAClC,MAAA;AAGA,MAAA,IAAA,CAAKR,KAAAA,CAAMgC,IAAIE,QAAAA,EAAU;AACvBL,QAAAA,WAAAA;QACAW,SAAAA,EAAWC,IAAAA,CAAKC,GAAAA,EAAG,GAAK,IAAA,CAAK7C;OAC/B,CAAA;AAEA,MAAA,OAAOgC,WAAAA;IACT,CAAA,CAAA,MAAQ;AAEN,MAAA,2BAAW5B,GAAAA,EAAAA;AACb,IAAA;AACF,EAAA;;;;;;;;;;;AAYQkC,EAAAA,aAAAA,CAAc5B,OAAAA,EAAgD;AACpE,IAAA,MAAMsD,GAAAA,GAAMtD,WAAY,EAAC;AACzB,IAAA,OAAO,CAAA,EAAGsD,GAAAA,CAAIrC,WAAAA,IAAe,QAAA,CAAA,CAAA,EAAYqC,GAAAA,CAAInC,OAAAA,IAAW,WAAA,CAAA,CAAA,EAAemC,GAAAA,CAAIpC,SAAAA,IAAa,MAAA,CAAA,CAAA;AAC1F,EAAA;AACF","file":"chunk-HRCWJLCZ.js","sourcesContent":["/**\n * Feature Flags Module\n *\n * In-house feature flag evaluation for Burdenoff backend services.\n * Compatible with OpenFeature specification concepts.\n *\n * @module feature-flags\n * @category FeatureFlags\n *\n * @example\n * ```typescript\n * import { FeatureFlagProvider } from '@burdenoff/be-sdk/feature-flags';\n *\n * // Create provider (typically done once at service startup)\n * const provider = new FeatureFlagProvider({\n * gatewayUrl: process.env.GLOBAL_INT_GATEWAY_URL || 'http://global-int-gateway:4000/global/graphql',\n * cacheTtlSeconds: 60,\n * });\n *\n * // Check a boolean flag\n * const ctx = { actorId: 'user-123', actorType: 'user' as const, workspaceId: 'ws-456' };\n * const isEnabled = await provider.isEnabled('calendar.recurring-events', ctx);\n *\n * // Resolve with full details\n * const details = await provider.resolveBoolean('calendar.recurring-events', true, ctx);\n * console.log(details.value); // true\n * console.log(details.reason); // 'TARGETING_MATCH'\n * console.log(details.variant); // 'user-opted-in'\n * ```\n */\n\nexport { FeatureFlagProvider } from './provider.js';\nexport type {\n EvaluationContext,\n FeatureFlagProviderConfig,\n FlagEvaluation,\n FlagType,\n ResolutionDetails,\n} from './types.js';\n","/**\n * Burdenoff Feature Flags Server Provider\n *\n * Server-side feature flag provider for backend services.\n * Evaluates flags via the global-tenant-svc GraphQL API through the internal gateway.\n * Supports in-memory caching with configurable TTL.\n *\n * @module feature-flags/provider\n * @category FeatureFlags\n *\n * @example\n * ```typescript\n * import { FeatureFlagProvider } from '@burdenoff/be-sdk/feature-flags';\n *\n * const provider = new FeatureFlagProvider({\n * gatewayUrl: 'http://global-int-gateway:4000/global/graphql',\n * cacheTtlSeconds: 60,\n * });\n *\n * const isEnabled = await provider.resolveBoolean('calendar.recurring-events', false, {\n * actorId: 'user-123',\n * actorType: 'user',\n * workspaceId: 'ws-456',\n * });\n *\n * console.log(isEnabled.value); // true or false\n * console.log(isEnabled.reason); // 'TARGETING_MATCH', 'DEFAULT', etc.\n * ```\n */\n\nimport { ContextManager } from '../context/index.js';\nimport type { EvaluationContext, FeatureFlagProviderConfig, FlagEvaluation, ResolutionDetails } from './types.js';\n\ninterface CacheEntry {\n evaluations: Map<string, FlagEvaluation>;\n expiresAt: number;\n}\n\nconst EVALUATE_QUERY = `\n query EvaluateFeatureFlags($input: EvaluateFeatureFlagsInput!) {\n evaluateFeatureFlags(input: $input) {\n evaluations {\n key\n value\n variant\n reason\n flagType\n errorCode\n }\n }\n }\n`;\n\n/**\n * Burdenoff Feature Flag Server Provider\n *\n * Evaluates feature flags by querying the global-tenant-svc through\n * the internal gateway. Results are cached in-memory per workspace+actor\n * combination with a configurable TTL.\n */\nexport class FeatureFlagProvider {\n private readonly gatewayUrl: string;\n private readonly cacheTtlMs: number;\n private readonly serviceToken?: string;\n private readonly defaultActorType: string;\n\n /** In-memory cache keyed by `${workspaceId}:${actorId}` */\n private readonly cache = new Map<string, CacheEntry>();\n\n constructor(config: FeatureFlagProviderConfig) {\n this.gatewayUrl = config.gatewayUrl;\n this.cacheTtlMs = (config.cacheTtlSeconds ?? 60) * 1000;\n this.serviceToken = config.serviceToken;\n this.defaultActorType = config.defaultActorType ?? 'service';\n }\n\n // =========================================================================\n // Public Resolution Methods (OpenFeature-compatible interface)\n // =========================================================================\n\n /**\n * Resolve a boolean feature flag\n *\n * @param flagKey - The flag key (e.g. \"calendar.recurring-events\")\n * @param defaultValue - Default value if resolution fails\n * @param context - Evaluation context with actor and workspace info\n * @returns Resolution details with the resolved boolean value\n */\n async resolveBoolean(\n flagKey: string,\n defaultValue: boolean,\n context: EvaluationContext\n ): Promise<ResolutionDetails<boolean>> {\n const evaluation = await this.getEvaluation(flagKey, context);\n if (!evaluation) {\n return {\n value: defaultValue,\n reason: 'DEFAULT',\n flagType: 'BOOLEAN',\n };\n }\n\n return {\n value: Boolean(evaluation.value),\n variant: evaluation.variant ?? undefined,\n reason: evaluation.reason,\n flagType: evaluation.flagType,\n errorCode: evaluation.errorCode ?? undefined,\n };\n }\n\n /**\n * Resolve a string feature flag\n */\n async resolveString(\n flagKey: string,\n defaultValue: string,\n context: EvaluationContext\n ): Promise<ResolutionDetails<string>> {\n const evaluation = await this.getEvaluation(flagKey, context);\n if (!evaluation) {\n return {\n value: defaultValue,\n reason: 'DEFAULT',\n flagType: 'STRING',\n };\n }\n\n return {\n value: String(evaluation.value),\n variant: evaluation.variant ?? undefined,\n reason: evaluation.reason,\n flagType: evaluation.flagType,\n errorCode: evaluation.errorCode ?? undefined,\n };\n }\n\n /**\n * Resolve a number feature flag\n */\n async resolveNumber(\n flagKey: string,\n defaultValue: number,\n context: EvaluationContext\n ): Promise<ResolutionDetails<number>> {\n const evaluation = await this.getEvaluation(flagKey, context);\n if (!evaluation) {\n return {\n value: defaultValue,\n reason: 'DEFAULT',\n flagType: 'NUMBER',\n };\n }\n\n return {\n value: Number(evaluation.value),\n variant: evaluation.variant ?? undefined,\n reason: evaluation.reason,\n flagType: evaluation.flagType,\n errorCode: evaluation.errorCode ?? undefined,\n };\n }\n\n /**\n * Resolve an object (JSON) feature flag\n */\n async resolveObject<T extends Record<string, unknown>>(\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext\n ): Promise<ResolutionDetails<T>> {\n const evaluation = await this.getEvaluation(flagKey, context);\n if (!evaluation) {\n return {\n value: defaultValue,\n reason: 'DEFAULT',\n flagType: 'JSON',\n };\n }\n\n return {\n value: evaluation.value as T,\n variant: evaluation.variant ?? undefined,\n reason: evaluation.reason,\n flagType: evaluation.flagType,\n errorCode: evaluation.errorCode ?? undefined,\n };\n }\n\n // =========================================================================\n // Convenience Methods\n // =========================================================================\n\n /**\n * Quick boolean check — returns just the value.\n * Defaults to `true` (default-allow philosophy) if the flag is not found.\n *\n * @example\n * ```typescript\n * if (await provider.isEnabled('calendar.recurring-events', ctx)) {\n * // Feature is enabled\n * }\n * ```\n */\n async isEnabled(flagKey: string, context?: EvaluationContext): Promise<boolean> {\n const result = await this.resolveBoolean(\n flagKey,\n true,\n context ?? { workspaceId: 'system', actorType: 'service', actorId: 'boot' }\n );\n return result.value;\n }\n\n /**\n * Bulk evaluate multiple flags at once.\n * Returns a map of key -> ResolutionDetails.\n */\n async evaluateAll(context: EvaluationContext, keys?: string[]): Promise<Map<string, ResolutionDetails<unknown>>> {\n const evaluations = await this.fetchEvaluations(context, keys);\n const result = new Map<string, ResolutionDetails<unknown>>();\n\n for (const [key, evaluation] of evaluations) {\n result.set(key, {\n value: evaluation.value,\n variant: evaluation.variant ?? undefined,\n reason: evaluation.reason,\n flagType: evaluation.flagType,\n errorCode: evaluation.errorCode ?? undefined,\n });\n }\n\n return result;\n }\n\n /**\n * Invalidate the cache for a specific workspace+actor combination,\n * or all cache entries if no context is provided.\n */\n invalidateCache(context?: EvaluationContext): void {\n if (context) {\n const cacheKey = this.buildCacheKey(context);\n this.cache.delete(cacheKey);\n } else {\n this.cache.clear();\n }\n }\n\n // =========================================================================\n // Private Methods\n // =========================================================================\n\n /**\n * Get a single flag evaluation, fetching from cache or API\n */\n private async getEvaluation(flagKey: string, context: EvaluationContext | undefined): Promise<FlagEvaluation | null> {\n try {\n const evaluations = await this.fetchEvaluations(context);\n return evaluations.get(flagKey) ?? null;\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch flag evaluations — uses cache if available, otherwise calls the API\n */\n private async fetchEvaluations(\n context: EvaluationContext | undefined,\n keys?: string[]\n ): Promise<Map<string, FlagEvaluation>> {\n const cacheKey = this.buildCacheKey(context);\n const cached = this.cache.get(cacheKey);\n\n if (cached && cached.expiresAt > Date.now()) {\n return cached.evaluations;\n }\n\n // Without a workspace context there's nothing the backend can evaluate\n // against — fall through to caller defaults instead of hitting the API.\n if (!context?.workspaceId) {\n return new Map();\n }\n\n // Fetch from API\n try {\n const response = await fetch(this.gatewayUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(context.actorId && { 'x-actor-id': context.actorId }),\n 'x-actor-type': context.actorType ?? this.defaultActorType,\n 'x-workspace-id': context.workspaceId,\n ...(this.serviceToken && { Authorization: `Bearer ${this.serviceToken}` }),\n // Re-present the inbound CF Access service token when the flag check\n // runs against a CF-Access-gated public gateway (alpha). No-op when\n // request context carries no CF creds (local dev, production).\n ...ContextManager.getCfAccessHeaders(),\n },\n body: JSON.stringify({\n query: EVALUATE_QUERY,\n variables: {\n input: {\n workspaceId: context.workspaceId,\n keys: keys ?? null,\n },\n },\n }),\n });\n\n if (!response.ok) {\n // Return empty map on error — default-allow handled by callers\n return new Map();\n }\n\n const json = (await response.json()) as {\n data?: {\n evaluateFeatureFlags?: {\n evaluations?: FlagEvaluation[];\n };\n };\n errors?: Array<{ message: string }>;\n };\n\n if (json.errors || !json.data?.evaluateFeatureFlags?.evaluations) {\n return new Map();\n }\n\n const evaluations = new Map<string, FlagEvaluation>();\n for (const evaluation of json.data.evaluateFeatureFlags.evaluations) {\n evaluations.set(evaluation.key, evaluation);\n }\n\n // Cache the results\n this.cache.set(cacheKey, {\n evaluations,\n expiresAt: Date.now() + this.cacheTtlMs,\n });\n\n return evaluations;\n } catch {\n // On network error, return empty map (default-allow handled by callers)\n return new Map();\n }\n }\n\n /**\n * Build a cache key from the evaluation context.\n *\n * Safe against undefined/null context — callers like isEnabled() may\n * pass no context during service boot (e.g. checking a default-allow\n * feature flag at startup before the first request builds a real\n * actor context). Without the guard, isEnabled(flag) used to throw\n * \"undefined is not an object (evaluating 'context.workspaceId')\"\n * and crash the svc at startServer().\n */\n private buildCacheKey(context: EvaluationContext | undefined): string {\n const ctx = context ?? ({} as EvaluationContext);\n return `${ctx.workspaceId ?? 'system'}:${ctx.actorId ?? 'anonymous'}:${ctx.actorType ?? 'user'}`;\n }\n}\n"]}
|