@fulmenhq/tsfulmen 0.4.0 → 0.4.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/appidentity/index.js +6 -6
  3. package/dist/assets/index.d.ts +5 -0
  4. package/dist/assets/index.js +1 -1
  5. package/dist/bin/prometheus-cli.js +6 -6
  6. package/dist/bin/schema-cli.js +2 -2
  7. package/dist/bin/signals-cli.js +4 -4
  8. package/dist/{chunk-HIBZ2AY7.js → chunk-24BAF63H.js} +4 -4
  9. package/dist/{chunk-HIBZ2AY7.js.map → chunk-24BAF63H.js.map} +1 -1
  10. package/dist/{chunk-BTUS6PZZ.js → chunk-56F2EEAG.js} +33 -7
  11. package/dist/chunk-56F2EEAG.js.map +1 -0
  12. package/dist/{chunk-K2FYT43R.js → chunk-7YWACZEJ.js} +4 -4
  13. package/dist/{chunk-K2FYT43R.js.map → chunk-7YWACZEJ.js.map} +1 -1
  14. package/dist/{chunk-CW4CSNVF.js → chunk-GOTEQYAD.js} +3 -3
  15. package/dist/{chunk-CW4CSNVF.js.map → chunk-GOTEQYAD.js.map} +1 -1
  16. package/dist/{chunk-K7BMFGQP.js → chunk-LMNAUTW7.js} +3 -3
  17. package/dist/{chunk-K7BMFGQP.js.map → chunk-LMNAUTW7.js.map} +1 -1
  18. package/dist/{chunk-HS4F3BRR.js → chunk-QGTNV4U2.js} +3 -3
  19. package/dist/{chunk-HS4F3BRR.js.map → chunk-QGTNV4U2.js.map} +1 -1
  20. package/dist/{chunk-7SVYOPJ3.js → chunk-SNV5WG5V.js} +9 -9
  21. package/dist/{chunk-7SVYOPJ3.js.map → chunk-SNV5WG5V.js.map} +1 -1
  22. package/dist/{chunk-BJDL6JEX.js → chunk-VJIGX7MH.js} +4 -4
  23. package/dist/{chunk-BJDL6JEX.js.map → chunk-VJIGX7MH.js.map} +1 -1
  24. package/dist/{chunk-W6TQFTTY.js → chunk-WCCMRVZF.js} +3 -3
  25. package/dist/{chunk-W6TQFTTY.js.map → chunk-WCCMRVZF.js.map} +1 -1
  26. package/dist/config/index.js +2 -2
  27. package/dist/crucible/index.js +2 -2
  28. package/dist/errors/index.js +3 -3
  29. package/dist/errors-R7ZODJXS.js +8 -0
  30. package/dist/{errors-RBJX6ETJ.js.map → errors-R7ZODJXS.js.map} +1 -1
  31. package/dist/export-EA3RNQNS.js +6 -0
  32. package/dist/{export-BWRETGYS.js.map → export-EA3RNQNS.js.map} +1 -1
  33. package/dist/foundry/index.js +5 -5
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.js +7 -7
  36. package/dist/index.js.map +1 -1
  37. package/dist/loader-VP2ZIC4O.js +9 -0
  38. package/dist/{loader-H5K7HSO5.js.map → loader-VP2ZIC4O.js.map} +1 -1
  39. package/dist/pathfinder/index.js +3 -3
  40. package/dist/reports/license-inventory.csv +1 -1
  41. package/dist/schema/index.js +2 -2
  42. package/dist/signals/index.js +4 -4
  43. package/dist/telemetry/http/index.js +6 -6
  44. package/dist/telemetry/index.js +2 -2
  45. package/dist/telemetry/prometheus/index.js +4 -4
  46. package/dist/{validator-U4CKD2Y3.js → validator-I3ASDVDB.js} +4 -4
  47. package/dist/{validator-U4CKD2Y3.js.map → validator-I3ASDVDB.js.map} +1 -1
  48. package/package.json +1 -1
  49. package/dist/chunk-BTUS6PZZ.js.map +0 -1
  50. package/dist/errors-RBJX6ETJ.js +0 -8
  51. package/dist/export-BWRETGYS.js +0 -6
  52. package/dist/loader-H5K7HSO5.js +0 -9
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/telemetry/prometheus/constants.ts","../src/telemetry/prometheus/errors.ts","../src/telemetry/prometheus/exporter.ts","../src/telemetry/prometheus/lifecycle.ts","../src/telemetry/prometheus/server.ts"],"names":["metrics"],"mappings":"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","file":"chunk-K2FYT43R.js","sourcesContent":["/**\n * Prometheus exporter constants\n *\n * ADR-0007 histogram buckets and metric names from Crucible v0.2.7 taxonomy.\n */\n\n/**\n * ADR-0007 histogram buckets for millisecond timing\n *\n * Buckets: 1ms, 5ms, 10ms, 50ms, 100ms, 500ms, 1s, 5s, 10s\n * Used for: MIME detection, error handling, FulHash operations\n */\nexport const ADR0007_BUCKETS_MS = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000] as const;\n\n/**\n * ADR-0007 histogram buckets for second timing (refresh operations)\n *\n * Buckets: 1ms, 5ms, 10ms, 50ms, 100ms, 500ms, 1s, 5s, 10s (converted to seconds)\n * Used for: Prometheus exporter refresh duration\n */\nexport const ADR0007_BUCKETS_SECONDS = [\n 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0,\n] as const;\n\n/**\n * Convert milliseconds to seconds for Prometheus histograms\n */\nexport function msToSeconds(ms: number): number {\n return ms / 1000;\n}\n\n/**\n * Prometheus exporter metric names (Crucible v0.2.7 taxonomy)\n */\nexport const PROMETHEUS_EXPORTER_METRICS = {\n // Refresh metrics\n REFRESH_DURATION_SECONDS: \"prometheus_exporter_refresh_duration_seconds\",\n REFRESH_TOTAL: \"prometheus_exporter_refresh_total\",\n REFRESH_ERRORS_TOTAL: \"prometheus_exporter_refresh_errors_total\",\n REFRESH_INFLIGHT: \"prometheus_exporter_refresh_inflight\",\n\n // HTTP metrics\n HTTP_REQUESTS_TOTAL: \"prometheus_exporter_http_requests_total\",\n HTTP_ERRORS_TOTAL: \"prometheus_exporter_http_errors_total\",\n\n // Restart metrics\n RESTARTS_TOTAL: \"prometheus_exporter_restarts_total\",\n} as const;\n\n/**\n * Foundry module metric names (Crucible v0.2.7 taxonomy)\n */\nexport const FOUNDRY_METRICS = {\n // MIME detection counters\n MIME_DETECTIONS_JSON: \"foundry_mime_detections_total_json\",\n MIME_DETECTIONS_XML: \"foundry_mime_detections_total_xml\",\n MIME_DETECTIONS_YAML: \"foundry_mime_detections_total_yaml\",\n MIME_DETECTIONS_CSV: \"foundry_mime_detections_total_csv\",\n MIME_DETECTIONS_PLAIN_TEXT: \"foundry_mime_detections_total_plain_text\",\n MIME_DETECTIONS_UNKNOWN: \"foundry_mime_detections_total_unknown\",\n\n // MIME detection timing histograms\n MIME_DETECTION_MS_JSON: \"foundry_mime_detection_ms_json\",\n MIME_DETECTION_MS_XML: \"foundry_mime_detection_ms_xml\",\n MIME_DETECTION_MS_YAML: \"foundry_mime_detection_ms_yaml\",\n MIME_DETECTION_MS_CSV: \"foundry_mime_detection_ms_csv\",\n MIME_DETECTION_MS_PLAIN_TEXT: \"foundry_mime_detection_ms_plain_text\",\n MIME_DETECTION_MS_UNKNOWN: \"foundry_mime_detection_ms_unknown\",\n\n // General lookup counter\n LOOKUP_COUNT: \"foundry_lookup_count\",\n} as const;\n\n/**\n * Error handling module metric names (Crucible v0.2.7 taxonomy)\n */\nexport const ERROR_HANDLING_METRICS = {\n WRAPS_TOTAL: \"error_handling_wraps_total\",\n WRAP_MS: \"error_handling_wrap_ms\",\n} as const;\n\n/**\n * FulHash module metric names (Crucible v0.2.7 taxonomy)\n */\nexport const FULHASH_METRICS = {\n // Algorithm-specific counters\n OPERATIONS_XXH3_128: \"fulhash_operations_total_xxh3_128\",\n OPERATIONS_SHA256: \"fulhash_operations_total_sha256\",\n\n // General counters\n HASH_STRING_TOTAL: \"fulhash_hash_string_total\",\n BYTES_HASHED_TOTAL: \"fulhash_bytes_hashed_total\",\n\n // Timing histogram\n OPERATION_MS: \"fulhash_operation_ms\",\n} as const;\n\n/**\n * Label values for Prometheus exporter metrics (taxonomy-compliant)\n */\nexport const EXPORTER_LABELS = {\n // Refresh phases\n PHASE_COLLECT: \"collect\",\n PHASE_CONVERT: \"convert\",\n PHASE_EXPORT: \"export\",\n\n // Results\n RESULT_SUCCESS: \"success\",\n RESULT_ERROR: \"error\",\n\n // Error types\n ERROR_VALIDATION: \"validation\",\n ERROR_IO: \"io\",\n ERROR_TIMEOUT: \"timeout\",\n ERROR_OTHER: \"other\",\n\n // Restart reasons\n REASON_CONFIG_CHANGE: \"config_change\",\n REASON_ERROR: \"error\",\n REASON_MANUAL: \"manual\",\n REASON_OTHER: \"other\",\n} as const;\n","/**\n * Prometheus exporter error classes\n *\n * Specialized errors for Prometheus integration failures.\n */\n\nimport { FulmenError } from \"../../errors/index.js\";\n\n/**\n * Base error class for Prometheus exporter errors\n */\nexport class PrometheusExporterError extends FulmenError {\n constructor(\n message: string,\n options?: {\n code?: string;\n cause?: unknown;\n context?: Record<string, unknown>;\n },\n ) {\n super({\n code: options?.code || \"PROMETHEUS_EXPORTER_ERROR\",\n message,\n severity: \"medium\",\n context: options?.context,\n });\n\n if (options?.cause) {\n this.cause = options.cause;\n }\n\n this.name = \"PrometheusExporterError\";\n }\n}\n\n/**\n * Error thrown when prom-client peer dependency is not installed\n */\nexport class PromClientNotFoundError extends PrometheusExporterError {\n constructor(cause?: unknown) {\n super(\n \"prom-client peer dependency not found. Install with: bun add prom-client\\n\" +\n \"For npm: npm install prom-client\\n\" +\n \"For more information, see: https://github.com/siimon/prom-client\",\n {\n code: \"PROM_CLIENT_NOT_FOUND\",\n cause,\n context: {\n suggestion: 'Run \"bun add prom-client\" to install the required peer dependency',\n },\n },\n );\n\n this.name = \"PromClientNotFoundError\";\n }\n}\n\n/**\n * Error thrown when metric name is invalid for Prometheus\n */\nexport class InvalidMetricNameError extends PrometheusExporterError {\n constructor(metricName: string, reason: string) {\n super(`Invalid Prometheus metric name: \"${metricName}\". ${reason}`, {\n code: \"INVALID_METRIC_NAME\",\n context: {\n metricName,\n reason,\n suggestion:\n \"Prometheus metric names must match: [a-zA-Z_:][a-zA-Z0-9_:]*\\n\" +\n \"See: https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels\",\n },\n });\n\n this.name = \"InvalidMetricNameError\";\n }\n}\n\n/**\n * Error thrown when label name is invalid for Prometheus\n */\nexport class InvalidLabelNameError extends PrometheusExporterError {\n constructor(labelName: string, reason: string) {\n super(`Invalid Prometheus label name: \"${labelName}\". ${reason}`, {\n code: \"INVALID_LABEL_NAME\",\n context: {\n labelName,\n reason,\n suggestion:\n \"Prometheus label names must match: [a-zA-Z_][a-zA-Z0-9_]*\\n\" +\n \"See: https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels\",\n },\n });\n\n this.name = \"InvalidLabelNameError\";\n }\n}\n\n/**\n * Error thrown when metric registration fails\n */\nexport class MetricRegistrationError extends PrometheusExporterError {\n constructor(metricName: string, cause: unknown) {\n super(`Failed to register Prometheus metric: \"${metricName}\"`, {\n code: \"METRIC_REGISTRATION_FAILED\",\n cause,\n context: {\n metricName,\n suggestion: \"Check for duplicate metric names or incompatible collector types\",\n },\n });\n\n this.name = \"MetricRegistrationError\";\n }\n}\n\n/**\n * Error thrown when refresh operation fails\n *\n * This error wraps underlying errors (InvalidMetricNameError, MetricRegistrationError, etc.)\n * that occur during the refresh process. Callers should inspect the `cause` property\n * to access the root error for specific error handling.\n *\n * @example\n * ```typescript\n * try {\n * await exporter.refresh();\n * } catch (err) {\n * if (err instanceof RefreshError) {\n * // Check the underlying cause for specific error types\n * if (err.cause instanceof InvalidMetricNameError) {\n * console.error('Invalid metric name:', err.cause.message);\n * }\n * }\n * }\n * ```\n */\nexport class RefreshError extends PrometheusExporterError {\n constructor(cause: unknown, context?: Record<string, unknown>) {\n super(\"Failed to refresh Prometheus metrics from TelemetryRegistry\", {\n code: \"REFRESH_FAILED\",\n cause,\n context,\n });\n\n this.name = \"RefreshError\";\n }\n}\n","/**\n * Prometheus exporter core implementation\n *\n * Bridges TSFulmen TelemetryRegistry to prom-client for Prometheus exposition.\n * Uses dynamic imports and loose typing for optional peer dependency (prom-client).\n *\n * NOTE: This file intentionally uses 'any' types for prom-client peer dependency\n * to avoid compile-time dependency. Runtime validation ensures type safety.\n * See .plans/active/v0.2.x-plans/prometheus-type-safety-enhancement.md for future work.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { metrics as defaultRegistry } from \"../index.js\";\nimport type { MetricsEvent } from \"../types.js\";\nimport { isHistogramSummary } from \"../types.js\";\nimport {\n ADR0007_BUCKETS_SECONDS,\n EXPORTER_LABELS,\n msToSeconds,\n PROMETHEUS_EXPORTER_METRICS,\n} from \"./constants.js\";\nimport {\n InvalidLabelNameError,\n InvalidMetricNameError,\n MetricRegistrationError,\n PromClientNotFoundError,\n RefreshError,\n} from \"./errors.js\";\nimport type { ExporterStats, PrometheusExporterOptions, RefreshOptions } from \"./types.js\";\n\n/**\n * Prometheus exporter\n *\n * Converts TSFulmen TelemetryRegistry metrics to Prometheus format using prom-client.\n *\n * @example\n * ```typescript\n * import { PrometheusExporter } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n * import { metrics } from '@fulmenhq/tsfulmen/telemetry';\n *\n * // Create exporter\n * const exporter = new PrometheusExporter({\n * registry: metrics,\n * namespace: 'myapp',\n * defaultLabels: { environment: 'production' }\n * });\n *\n * // Refresh metrics from registry\n * await exporter.refresh();\n *\n * // Get Prometheus text format\n * const output = await exporter.getMetrics();\n * console.log(output);\n * ```\n */\nexport class PrometheusExporter {\n private readonly telemetryRegistry: typeof defaultRegistry;\n private namespace: string;\n private subsystem: string;\n private readonly defaultLabels: Record<string, string>;\n private readonly helpText: Record<string, string>;\n private readonly metricsEnabled: boolean;\n private readonly recordClientLabel: boolean;\n private readonly moduleMetricsEnabled: boolean;\n\n // prom-client types unavailable at compile time (optional peer dependency)\n // Using 'any' with runtime validation - see file header comment for rationale\n // biome-ignore lint/suspicious/noExplicitAny: prom-client is optional peer dependency\n private promClient: any = null;\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Registry type unavailable at compile time\n private promRegistry: any = null;\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Counter type unavailable at compile time\n private counters: Map<string, any> = new Map();\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Gauge type unavailable at compile time\n private gauges: Map<string, any> = new Map();\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Histogram type unavailable at compile time\n private histograms: Map<string, any> = new Map();\n\n // Statistics\n private refreshCount = 0;\n private errorCount = 0;\n private lastRefreshTime: string | null = null;\n\n // Background refresh loop\n private refreshInterval: NodeJS.Timeout | null = null;\n private refreshPromise: Promise<void> | null = null;\n private isRefreshing = false;\n\n /**\n * Create Prometheus exporter\n *\n * @param options - Exporter configuration\n * @throws {InvalidLabelNameError} If default label names are invalid\n */\n constructor(options: PrometheusExporterOptions = {}) {\n this.telemetryRegistry = options.registry || defaultRegistry;\n this.defaultLabels = options.defaultLabels || {};\n this.helpText = options.helpText || {};\n this.metricsEnabled = options.metricsEnabled ?? true;\n this.recordClientLabel = options.recordClientLabel ?? false;\n this.moduleMetricsEnabled = options.moduleMetricsEnabled ?? true;\n\n // Validate default label names\n for (const labelName of Object.keys(this.defaultLabels)) {\n this.validateLabelName(labelName);\n }\n\n // Initialize namespace and subsystem\n // May be overridden by App Identity in init()\n this.namespace = options.namespace || \"tsfulmen\";\n this.subsystem = options.subsystem || \"app\";\n }\n\n /**\n * Initialize exporter (async setup)\n *\n * Loads prom-client and optionally loads App Identity for namespace/subsystem.\n * Called automatically on first refresh() or getMetrics() call.\n *\n * @throws {PromClientNotFoundError} If prom-client not installed\n */\n private async init(): Promise<void> {\n if (this.promClient) {\n return; // Already initialized\n }\n\n // Lazy load prom-client (peer dependency)\n try {\n this.promClient = await import(\"prom-client\");\n this.promRegistry = new this.promClient.Registry();\n } catch (err) {\n throw new PromClientNotFoundError(err);\n }\n\n // Try to load App Identity for namespace/subsystem (optional)\n if (this.namespace === \"tsfulmen\" || this.subsystem === \"app\") {\n try {\n const { loadIdentity } = await import(\"../../appidentity/index.js\");\n const identity = await loadIdentity({ skipValidation: true });\n\n if (this.namespace === \"tsfulmen\" && identity.app.vendor) {\n this.namespace = identity.app.vendor;\n }\n if (this.subsystem === \"app\" && identity.app.binary_name) {\n this.subsystem = identity.app.binary_name;\n }\n } catch {\n // App Identity not available - use defaults\n }\n }\n }\n\n /**\n * Safely emit instrumentation metric (silently fails if registry doesn't support it)\n * Used to avoid breaking tests that use mock registries\n */\n private safeInstrument(fn: () => void): void {\n try {\n fn();\n } catch {\n // Silently ignore instrumentation failures (e.g., mock registries in tests)\n }\n }\n\n /**\n * Refresh metrics from TelemetryRegistry\n *\n * Exports current metrics from TelemetryRegistry and updates Prometheus collectors.\n * Emits instrumentation metrics per Crucible v0.2.7 taxonomy.\n *\n * @throws {RefreshError} If refresh operation fails. Inspect `error.cause` for the\n * underlying error (InvalidMetricNameError, MetricRegistrationError, etc.) to handle\n * specific failure conditions.\n */\n async refresh(): Promise<void> {\n const startTime = performance.now();\n\n // Set inflight gauge to 1\n this.safeInstrument(() => {\n this.telemetryRegistry.gauge(PROMETHEUS_EXPORTER_METRICS.REFRESH_INFLIGHT).set(1);\n });\n\n try {\n // Phase: collect - export from telemetry registry\n await this.init();\n const events = await this.telemetryRegistry.export();\n\n // Phase: convert - update Prometheus collectors\n for (const event of events) {\n this.updateCollector(event);\n }\n\n // Success metrics\n this.refreshCount++;\n this.lastRefreshTime = new Date().toISOString();\n\n const durationMs = performance.now() - startTime;\n\n // Emit success metrics\n this.safeInstrument(() => {\n this.telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.REFRESH_TOTAL)\n .inc(1, { result: EXPORTER_LABELS.RESULT_SUCCESS });\n\n this.telemetryRegistry\n .histogram(PROMETHEUS_EXPORTER_METRICS.REFRESH_DURATION_SECONDS, {\n buckets: [...ADR0007_BUCKETS_SECONDS],\n })\n .observe(msToSeconds(durationMs), {\n phase: EXPORTER_LABELS.PHASE_EXPORT,\n result: EXPORTER_LABELS.RESULT_SUCCESS,\n });\n });\n } catch (err) {\n this.errorCount++;\n\n const durationMs = performance.now() - startTime;\n\n // Classify error type\n let errorType: string = EXPORTER_LABELS.ERROR_OTHER;\n if (err instanceof InvalidMetricNameError || err instanceof InvalidLabelNameError) {\n errorType = EXPORTER_LABELS.ERROR_VALIDATION;\n } else if (err instanceof MetricRegistrationError) {\n errorType = EXPORTER_LABELS.ERROR_OTHER;\n }\n\n // Emit error metrics\n this.safeInstrument(() => {\n this.telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.REFRESH_TOTAL)\n .inc(1, { result: EXPORTER_LABELS.RESULT_ERROR });\n\n this.telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.REFRESH_ERRORS_TOTAL)\n .inc(1, { error_type: errorType });\n\n this.telemetryRegistry\n .histogram(PROMETHEUS_EXPORTER_METRICS.REFRESH_DURATION_SECONDS, {\n buckets: [...ADR0007_BUCKETS_SECONDS],\n })\n .observe(msToSeconds(durationMs), {\n phase: EXPORTER_LABELS.PHASE_EXPORT,\n result: EXPORTER_LABELS.RESULT_ERROR,\n });\n });\n\n throw new RefreshError(err, {\n refreshCount: this.refreshCount,\n errorCount: this.errorCount,\n });\n } finally {\n // Clear inflight gauge\n this.safeInstrument(() => {\n this.telemetryRegistry.gauge(PROMETHEUS_EXPORTER_METRICS.REFRESH_INFLIGHT).set(0);\n });\n }\n }\n\n /**\n * Get Prometheus metrics in text format\n *\n * Returns metrics in Prometheus exposition text format.\n *\n * @returns Prometheus text format string\n */\n async getMetrics(): Promise<string> {\n await this.init();\n\n if (!this.promRegistry) {\n throw new Error(\"Prometheus registry not initialized\");\n }\n\n return this.promRegistry.metrics();\n }\n\n /**\n * Get exporter statistics\n */\n getStats(): ExporterStats {\n return {\n refreshCount: this.refreshCount,\n errorCount: this.errorCount,\n lastRefreshTime: this.lastRefreshTime,\n metricsCount: this.counters.size + this.gauges.size + this.histograms.size,\n isRefreshing: this.isRefreshing,\n };\n }\n\n /**\n * Get current metrics configuration\n *\n * Returns effective configuration being used by exporter,\n * including defaults for any unspecified options.\n *\n * @returns Current metrics configuration\n */\n getMetricsConfig() {\n return {\n metricsEnabled: this.metricsEnabled,\n recordClientLabel: this.recordClientLabel,\n moduleMetricsEnabled: this.moduleMetricsEnabled,\n namespace: this.namespace,\n subsystem: this.subsystem,\n defaultLabels: { ...this.defaultLabels },\n helpText: { ...this.helpText },\n };\n }\n\n /**\n * Get underlying prom-client Registry\n *\n * Returns null if not yet initialized.\n * Use for advanced prom-client operations.\n */\n // biome-ignore lint/suspicious/noExplicitAny: Returns prom-client Registry type (optional peer dependency)\n getRegistry(): any {\n return this.promRegistry;\n }\n\n /**\n * Get telemetry registry for self-instrumentation\n *\n * Returns the MetricsRegistry instance used for exporter self-instrumentation.\n * Useful for HTTP handler instrumentation.\n *\n * @internal\n */\n getTelemetryRegistry(): typeof defaultRegistry {\n return this.telemetryRegistry;\n }\n\n /**\n * Emit restart metric\n *\n * Records a restart event for tracking exporter or server restarts.\n * Use this when restarting the HTTP metrics server or other exporter components.\n *\n * @param reason - Reason for restart (config_change, error, manual, other)\n *\n * @example\n * ```typescript\n * // Restart server after config change\n * await stopMetricsServer(server);\n * exporter.recordRestart('config_change');\n * const newServer = await startMetricsServer(exporter, newConfig);\n * ```\n */\n recordRestart(reason: \"config_change\" | \"error\" | \"manual\" | \"other\"): void {\n this.safeInstrument(() => {\n this.telemetryRegistry.counter(PROMETHEUS_EXPORTER_METRICS.RESTARTS_TOTAL).inc(1, { reason });\n });\n }\n\n /**\n * Reset all metrics\n */\n reset(): void {\n if (this.promRegistry) {\n this.promRegistry.clear();\n }\n this.counters.clear();\n this.gauges.clear();\n this.histograms.clear();\n }\n\n /**\n * Start background refresh loop\n *\n * Automatically refreshes metrics from TelemetryRegistry at specified interval.\n * Useful for long-running services where metrics should be continuously updated.\n *\n * @param options - Refresh configuration (interval, error handler)\n *\n * @example\n * ```typescript\n * const exporter = new PrometheusExporter({ registry: metrics });\n *\n * // Start refreshing every 15 seconds (default)\n * exporter.startRefresh();\n *\n * // Custom interval and error handling\n * exporter.startRefresh({\n * intervalMs: 10000,\n * onError: (err) => logger.error('Refresh failed:', err)\n * });\n * ```\n */\n startRefresh(options: RefreshOptions = {}): void {\n const intervalMs = options.intervalMs ?? 15000;\n const _isRestart = !!this.refreshInterval;\n\n // Stop existing refresh if running (restart scenario)\n if (this.refreshInterval) {\n this.stopRefresh();\n\n // Emit restart metric\n this.safeInstrument(() => {\n this.telemetryRegistry.counter(PROMETHEUS_EXPORTER_METRICS.RESTARTS_TOTAL).inc(1, {\n reason: options.restartReason || EXPORTER_LABELS.REASON_OTHER,\n });\n });\n }\n\n // Start refresh loop\n this.refreshInterval = setInterval(() => {\n // Don't start new refresh if one is already running (serialization)\n if (this.refreshPromise) {\n return;\n }\n\n this.refreshPromise = this.refresh()\n .catch((err) => {\n // Call error handler if provided\n if (options.onError) {\n options.onError(err as Error);\n }\n })\n .finally(() => {\n this.refreshPromise = null;\n });\n }, intervalMs);\n\n // Update stats to indicate refreshing\n this.isRefreshing = true;\n }\n\n /**\n * Stop background refresh loop\n *\n * Clears the refresh interval and performs one final refresh to capture\n * the latest metrics state before stopping.\n *\n * @example\n * ```typescript\n * // Graceful shutdown\n * await exporter.stopRefresh();\n * ```\n */\n async stopRefresh(): Promise<void> {\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval);\n this.refreshInterval = null;\n }\n\n // Wait for any in-flight refresh to complete\n if (this.refreshPromise) {\n await this.refreshPromise;\n }\n\n // Perform final refresh to capture latest state\n try {\n await this.refresh();\n } catch (_err) {\n // Log but don't throw during shutdown\n // Error is already tracked in stats\n }\n\n // Update stats to indicate not refreshing\n this.isRefreshing = false;\n }\n\n /**\n * Update Prometheus collector from MetricsEvent\n */\n private updateCollector(event: MetricsEvent): void {\n const metricName = this.formatMetricName(event.name);\n const help = this.getHelpText(event.name);\n const labelNames = Object.keys(this.defaultLabels);\n\n if (isHistogramSummary(event.value)) {\n this.updateHistogram(metricName, help, labelNames, event.value);\n } else if (typeof event.value === \"number\") {\n // Use Gauge for all scalar metrics (simplest approach)\n // TSFulmen doesn't distinguish Counter vs Gauge in export format\n this.updateGauge(metricName, help, labelNames, event.value);\n }\n }\n\n /**\n * Update or create Prometheus Gauge\n */\n private updateGauge(name: string, help: string, labelNames: string[], value: number): void {\n let gauge = this.gauges.get(name);\n if (!gauge) {\n try {\n gauge = new this.promClient.Gauge({\n name,\n help,\n labelNames,\n registers: [this.promRegistry],\n });\n this.gauges.set(name, gauge);\n } catch (err) {\n throw new MetricRegistrationError(name, err);\n }\n }\n\n gauge.labels(this.defaultLabels).set(value);\n }\n\n /**\n * Update or create Prometheus Histogram\n *\n * CRITICAL: Converts OTLP cumulative buckets to Prometheus format.\n * This is an approximation - see Phase 0 investigation for details.\n *\n * LIMITATION: Original observations cannot be perfectly reconstructed from bucket summary.\n * Percentiles will be approximate based on bucket midpoints.\n */\n // biome-ignore lint/suspicious/noExplicitAny: summary is HistogramSummary from TelemetryRegistry\n private updateHistogram(name: string, help: string, labelNames: string[], summary: any): void {\n // biome-ignore lint/suspicious/noExplicitAny: bucket type from HistogramSummary\n const buckets = summary.buckets.map((b: any) => b.le);\n\n let histogram = this.histograms.get(name);\n if (!histogram) {\n try {\n histogram = new this.promClient.Histogram({\n name,\n help,\n labelNames,\n buckets,\n registers: [this.promRegistry],\n });\n this.histograms.set(name, histogram);\n } catch (err) {\n throw new MetricRegistrationError(name, err);\n }\n }\n\n // Reconstruct observations from summary\n const observations = this.reconstructObservations(summary);\n for (const value of observations) {\n histogram.labels(this.defaultLabels).observe(value);\n }\n }\n\n /**\n * Reconstruct observations from histogram summary\n *\n * Converts OTLP cumulative bucket counts to approximate observation values.\n * Uses bucket midpoints to generate synthetic observations.\n *\n * LIMITATION: This is an approximation. Original observation values cannot be\n * perfectly reconstructed from bucket summaries. Percentiles will be approximate\n * based on bucket boundaries. This is acceptable for v0.1.8 initial release.\n *\n * TODO: Future enhancement - capture raw observations in TelemetryRegistry\n * for lossless Prometheus export. Track in Phase 2+ planning.\n * See: .plans/active/v0.2.x-plans/prometheus-type-safety-enhancement.md\n *\n * Algorithm:\n * 1. Calculate non-cumulative count for each bucket (delta between adjacent buckets)\n * 2. For each bucket, place observations at the midpoint between bucket boundaries\n * 3. Return array of synthetic observation values\n */\n // biome-ignore lint/suspicious/noExplicitAny: summary is HistogramSummary from TelemetryRegistry\n private reconstructObservations(summary: any): number[] {\n const observations: number[] = [];\n const buckets = summary.buckets;\n\n if (!buckets || buckets.length === 0) {\n return observations;\n }\n\n let prevCount = 0;\n for (let i = 0; i < buckets.length; i++) {\n const bucket = buckets[i];\n const count = bucket.count - prevCount; // Non-cumulative count for this bucket\n\n if (count > 0) {\n // Determine observation value (bucket midpoint)\n let value: number;\n if (i === 0) {\n // First bucket: midpoint between 0 and upper bound\n value = bucket.le / 2;\n } else {\n // Other buckets: midpoint between previous and current upper bound\n const prevLe = buckets[i - 1].le;\n value = (prevLe + bucket.le) / 2;\n }\n\n // Add 'count' observations at this value\n for (let j = 0; j < count; j++) {\n observations.push(value);\n }\n }\n\n prevCount = bucket.count;\n }\n\n return observations;\n }\n\n /**\n * Format metric name with namespace and subsystem prefix\n *\n * Format: {namespace}_{subsystem}_{metric}\n * Example: fulmen_myapp_schema_validations\n */\n private formatMetricName(name: string): string {\n this.validateMetricName(name);\n return `${this.namespace}_${this.subsystem}_${name}`;\n }\n\n /**\n * Get help text for metric\n *\n * Uses custom help text if provided, otherwise generates default.\n */\n private getHelpText(name: string): string {\n if (this.helpText[name]) {\n return this.helpText[name];\n }\n return `TSFulmen metric: ${name}`;\n }\n\n /**\n * Validate Prometheus metric name\n *\n * Rules: Must start with [a-zA-Z_:] and contain only [a-zA-Z0-9_:]\n *\n * @throws {InvalidMetricNameError} If name is invalid\n */\n private validateMetricName(name: string): void {\n const validPattern = /^[a-zA-Z_:][a-zA-Z0-9_:]*$/;\n if (!validPattern.test(name)) {\n throw new InvalidMetricNameError(\n name,\n \"Metric names must start with [a-zA-Z_:] and contain only [a-zA-Z0-9_:]\",\n );\n }\n }\n\n /**\n * Validate Prometheus label name\n *\n * Rules: Must start with [a-zA-Z_] and contain only [a-zA-Z0-9_]\n *\n * @throws {InvalidLabelNameError} If name is invalid\n */\n private validateLabelName(name: string): void {\n const validPattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n if (!validPattern.test(name)) {\n throw new InvalidLabelNameError(\n name,\n \"Label names must start with [a-zA-Z_] and contain only [a-zA-Z0-9_]\",\n );\n }\n }\n}\n","/**\n * Prometheus exporter lifecycle integration\n *\n * Helpers for integrating PrometheusExporter with TSFulmen lifecycle management,\n * particularly signal handling for graceful shutdown.\n */\n\nimport type { SignalManager } from \"../../foundry/signals/index.js\";\nimport type { PrometheusExporter } from \"./exporter.js\";\n\n/**\n * Register Prometheus exporter shutdown handler\n *\n * Automatically stops the background refresh loop and performs a final refresh\n * when SIGTERM or SIGINT is received. This ensures metrics are up-to-date\n * before the process terminates.\n *\n * @param exporter - PrometheusExporter instance to manage\n * @param manager - SignalManager instance for lifecycle coordination\n *\n * @example\n * ```typescript\n * import { PrometheusExporter, registerPrometheusShutdown } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n * import { createSignalManager } from '@fulmenhq/tsfulmen/foundry/signals';\n *\n * const exporter = new PrometheusExporter({ registry: metrics });\n * const signalManager = createSignalManager();\n *\n * // Register graceful shutdown\n * await registerPrometheusShutdown(exporter, signalManager);\n *\n * // Start refresh loop\n * exporter.startRefresh({ intervalMs: 15000 });\n *\n * // When SIGTERM/SIGINT received, exporter will:\n * // 1. Stop refresh loop\n * // 2. Perform final refresh\n * // 3. Allow process to exit gracefully\n * ```\n */\nexport async function registerPrometheusShutdown(\n exporter: PrometheusExporter,\n manager: SignalManager,\n): Promise<void> {\n const shutdownHandler = async () => {\n await exporter.stopRefresh();\n };\n\n // Register for both SIGTERM and SIGINT\n await manager.register(\"SIGTERM\", shutdownHandler);\n await manager.register(\"SIGINT\", shutdownHandler);\n}\n","/**\n * Prometheus HTTP server implementation\n *\n * Framework-agnostic HTTP handler and dev server for exposing Prometheus metrics.\n * Compatible with Node.js http, Express, Fastify, and other frameworks.\n */\n\nimport type { IncomingMessage, Server, ServerResponse } from \"node:http\";\nimport { createServer } from \"node:http\";\nimport { createLogger, LoggingProfile } from \"../../logging/index.js\";\nimport type { MetricsRegistry } from \"../registry.js\";\nimport { PROMETHEUS_EXPORTER_METRICS } from \"./constants.js\";\nimport type { PrometheusExporter } from \"./exporter.js\";\nimport type { ServerOptions } from \"./types.js\";\n\n/**\n * Safe instrumentation helper for HTTP metrics\n *\n * Emits HTTP metrics to provided registry, silently failing if registry\n * doesn't support operation (e.g., mock registries in tests).\n */\nfunction safeInstrumentHTTP(registry: MetricsRegistry | null, fn: () => void): void {\n if (!registry) return;\n try {\n fn();\n } catch {\n // Silently fail - instrumentation is non-critical\n }\n}\n\n/**\n * Get logger from exporter with metricsEnabled check\n */\nfunction getExporterLogger(exporter: PrometheusExporter) {\n // Access private logger property through type assertion\n // biome-ignore lint/suspicious/noExplicitAny: Need to access private logger property\n const exporterAny = exporter as any;\n const logger = exporterAny.logger;\n\n // Return null logger if metrics disabled\n return exporterAny.metricsEnabled ? logger : null;\n}\n\n/**\n * HTTP request context for hooks\n *\n * Provides minimal interface for auth and rate limiting hooks.\n * Compatible with Node.js IncomingMessage and framework request objects.\n */\nexport interface RequestContext {\n /** HTTP method (GET, POST, etc.) */\n method?: string;\n /** Request URL path */\n url?: string;\n /** Request headers */\n headers: Record<string, string | string[] | undefined>;\n /** Remote IP address */\n remoteAddress?: string;\n}\n\n/**\n * Extract request context from Node.js IncomingMessage\n */\nfunction extractRequestContext(req: IncomingMessage): RequestContext {\n return {\n method: req.method,\n url: req.url,\n headers: req.headers as Record<string, string | string[] | undefined>,\n remoteAddress: req.socket.remoteAddress,\n };\n}\n\n/**\n * Create Prometheus metrics HTTP handler\n *\n * Returns a framework-agnostic handler compatible with Node.js http, Express,\n * Fastify, and other frameworks. The handler serves Prometheus metrics in\n * text exposition format with optional authentication and rate limiting.\n *\n * @param exporter - PrometheusExporter instance\n * @param options - Server options (auth, rate limiting, refresh behavior)\n * @returns HTTP handler function\n *\n * @example\n * ```typescript\n * // Basic usage with Node.js http\n * import http from 'node:http';\n * import { PrometheusExporter, createMetricsHandler } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n *\n * const exporter = new PrometheusExporter({ registry: metrics });\n * const handler = createMetricsHandler(exporter);\n *\n * const server = http.createServer(handler);\n * server.listen(9464);\n * ```\n *\n * @example\n * ```typescript\n * // With authentication\n * const handler = createMetricsHandler(exporter, {\n * authenticate: async (req) => {\n * const token = req.headers['authorization'];\n * return token === 'Bearer secret-token';\n * }\n * });\n * ```\n *\n * @example\n * ```typescript\n * // With rate limiting\n * const handler = createMetricsHandler(exporter, {\n * rateLimit: async (req) => {\n * const ip = req.remoteAddress;\n * return rateLimiter.checkLimit(ip);\n * }\n * });\n * ```\n */\nexport function createMetricsHandler(\n exporter: PrometheusExporter,\n options: ServerOptions = {},\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n const path = options.path ?? \"/metrics\";\n const refreshOnScrape = options.refreshOnScrape ?? false;\n const logger = getExporterLogger(exporter);\n\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const telemetryRegistry = exporter.getTelemetryRegistry();\n let _statusCode = 200;\n const startTime = performance.now();\n\n try {\n // Extract request context for hooks\n const context = extractRequestContext(req);\n\n // Check path - only serve metrics on configured path\n if (req.url !== path) {\n _statusCode = 404;\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not Found\");\n\n // Emit HTTP request metric (4xx)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"404\", path: req.url || \"unknown\" });\n });\n return;\n }\n\n // Check authentication if hook provided\n if (options.authenticate) {\n const authResult = await options.authenticate(context);\n if (!authResult) {\n _statusCode = 401;\n res.writeHead(401, {\n \"Content-Type\": \"text/plain\",\n \"WWW-Authenticate\": \"Bearer\",\n });\n res.end(\"Unauthorized\");\n\n // Emit HTTP request and error metrics (auth failure)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"401\", path });\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_ERRORS_TOTAL)\n .inc(1, { status: \"401\", path });\n });\n return;\n }\n }\n\n // Check rate limit if hook provided\n if (options.rateLimit) {\n const rateLimitResult = await options.rateLimit(context);\n if (!rateLimitResult) {\n _statusCode = 429;\n res.writeHead(429, {\n \"Content-Type\": \"text/plain\",\n \"Retry-After\": \"60\",\n });\n res.end(\"Too Many Requests\");\n\n // Emit HTTP request metric (4xx rate limit)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"429\", path });\n });\n return;\n }\n }\n\n // Refresh metrics if configured (optional, adds latency)\n if (refreshOnScrape) {\n await exporter.refresh();\n }\n\n // Get metrics in Prometheus text format\n const metrics = await exporter.getMetrics();\n\n // Send response with correct content-type\n // Prometheus text format version 0.0.4\n _statusCode = 200;\n res.writeHead(200, {\n \"Content-Type\": \"text/plain; version=0.0.4; charset=utf-8\",\n \"Content-Length\": Buffer.byteLength(metrics, \"utf-8\"),\n });\n res.end(metrics);\n\n // Emit HTTP request metric (2xx success)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"200\", path });\n });\n } catch (err) {\n // Internal server error\n const errorMessage = err instanceof Error ? err.message : \"Internal Server Error\";\n\n _statusCode = 500;\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(`Error: ${errorMessage}`);\n\n // Emit HTTP request and error metrics (5xx failure)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"500\", path });\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_ERRORS_TOTAL)\n .inc(1, { status: \"500\", path });\n });\n } finally {\n // Log HTTP request completion\n if (logger) {\n const durationMs = performance.now() - startTime;\n const context = extractRequestContext(req);\n\n logger.info(\"HTTP request processed\", {\n metric_name: PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL,\n status: _statusCode.toString(),\n path: req.url || \"unknown\",\n method: context.method || \"GET\",\n duration_ms: Math.round(durationMs),\n remote_address: context.remoteAddress,\n });\n }\n }\n };\n}\n\n/**\n * Start Prometheus metrics dev server\n *\n * Creates a standalone HTTP server for serving Prometheus metrics.\n * Useful for development, testing, and simple deployments without a full application framework.\n *\n * @param exporter - PrometheusExporter instance\n * @param options - Server configuration (host, port, path, auth, rate limiting)\n * @returns Promise that resolves to the HTTP Server instance\n *\n * @example\n * ```typescript\n * import { PrometheusExporter, startMetricsServer } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n *\n * const exporter = new PrometheusExporter({ registry: metrics });\n *\n * // Start dev server\n * const server = await startMetricsServer(exporter, {\n * host: '127.0.0.1',\n * port: 9464,\n * path: '/metrics'\n * });\n *\n * console.log('Metrics server listening on http://127.0.0.1:9464/metrics');\n *\n * // Graceful shutdown\n * process.on('SIGTERM', async () => {\n * await stopMetricsServer(server);\n * });\n * ```\n */\nexport async function startMetricsServer(\n exporter: PrometheusExporter,\n options: ServerOptions = {},\n): Promise<Server> {\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 9464;\n const path = options.path ?? \"/metrics\";\n\n // Create handler with options\n const handler = createMetricsHandler(exporter, options);\n\n // Create HTTP server\n const server = createServer(handler);\n\n // Create logger for server operations (only if metrics enabled)\n const exporterLogger = getExporterLogger(exporter);\n const logger =\n exporterLogger ||\n createLogger({\n service: \"prometheus_exporter\",\n profile: LoggingProfile.STRUCTURED,\n });\n\n // Start listening\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n // Log server startup\n logger.info(\"Prometheus metrics server started\", {\n host,\n port,\n path,\n url: `http://${host}:${port}${path}`,\n });\n resolve(server);\n });\n\n server.on(\"error\", (err) => {\n // Log server error\n logger.error(\"Prometheus metrics server error\", err as Error, {\n host,\n port,\n path,\n });\n reject(err);\n });\n });\n}\n\n/**\n * Stop Prometheus metrics server\n *\n * Gracefully shuts down the HTTP server with a configurable timeout.\n * Closes all connections and waits for in-flight requests to complete.\n *\n * @param server - HTTP Server instance from startMetricsServer\n * @param timeoutMs - Timeout in milliseconds (default: 5000)\n * @returns Promise that resolves when server is closed\n *\n * @example\n * ```typescript\n * // Graceful shutdown with 5 second timeout\n * await stopMetricsServer(server);\n *\n * // Custom timeout\n * await stopMetricsServer(server, 10000);\n * ```\n */\nexport async function stopMetricsServer(\n server: Server,\n timeoutMs = 5000,\n exporter?: PrometheusExporter,\n): Promise<void> {\n // Create logger for server operations (only if metrics enabled)\n const exporterLogger = exporter ? getExporterLogger(exporter) : null;\n const logger =\n exporterLogger ||\n createLogger({\n service: \"prometheus_exporter\",\n profile: LoggingProfile.STRUCTURED,\n });\n\n return new Promise((resolve, reject) => {\n // Set timeout for forced shutdown\n const timeout = setTimeout(() => {\n logger.warn(\"Prometheus metrics server shutdown timed out, forcing close\", {\n timeout_ms: timeoutMs,\n });\n server.closeAllConnections?.(); // Available in Node.js 18.2+\n reject(new Error(`Server shutdown timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n // Graceful close\n server.close((err) => {\n clearTimeout(timeout);\n if (err) {\n logger.error(\"Error stopping Prometheus metrics server\", err, {\n timeout_ms: timeoutMs,\n });\n reject(err);\n } else {\n logger.info(\"Prometheus metrics server stopped\", {\n timeout_ms: timeoutMs,\n });\n resolve();\n }\n });\n\n // Close all connections immediately (allows graceful request completion)\n server.closeAllConnections?.(); // Available in Node.js 18.2+\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/telemetry/prometheus/constants.ts","../src/telemetry/prometheus/errors.ts","../src/telemetry/prometheus/exporter.ts","../src/telemetry/prometheus/lifecycle.ts","../src/telemetry/prometheus/server.ts"],"names":["metrics"],"mappings":"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","file":"chunk-7YWACZEJ.js","sourcesContent":["/**\n * Prometheus exporter constants\n *\n * ADR-0007 histogram buckets and metric names from Crucible v0.2.7 taxonomy.\n */\n\n/**\n * ADR-0007 histogram buckets for millisecond timing\n *\n * Buckets: 1ms, 5ms, 10ms, 50ms, 100ms, 500ms, 1s, 5s, 10s\n * Used for: MIME detection, error handling, FulHash operations\n */\nexport const ADR0007_BUCKETS_MS = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000] as const;\n\n/**\n * ADR-0007 histogram buckets for second timing (refresh operations)\n *\n * Buckets: 1ms, 5ms, 10ms, 50ms, 100ms, 500ms, 1s, 5s, 10s (converted to seconds)\n * Used for: Prometheus exporter refresh duration\n */\nexport const ADR0007_BUCKETS_SECONDS = [\n 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0,\n] as const;\n\n/**\n * Convert milliseconds to seconds for Prometheus histograms\n */\nexport function msToSeconds(ms: number): number {\n return ms / 1000;\n}\n\n/**\n * Prometheus exporter metric names (Crucible v0.2.7 taxonomy)\n */\nexport const PROMETHEUS_EXPORTER_METRICS = {\n // Refresh metrics\n REFRESH_DURATION_SECONDS: \"prometheus_exporter_refresh_duration_seconds\",\n REFRESH_TOTAL: \"prometheus_exporter_refresh_total\",\n REFRESH_ERRORS_TOTAL: \"prometheus_exporter_refresh_errors_total\",\n REFRESH_INFLIGHT: \"prometheus_exporter_refresh_inflight\",\n\n // HTTP metrics\n HTTP_REQUESTS_TOTAL: \"prometheus_exporter_http_requests_total\",\n HTTP_ERRORS_TOTAL: \"prometheus_exporter_http_errors_total\",\n\n // Restart metrics\n RESTARTS_TOTAL: \"prometheus_exporter_restarts_total\",\n} as const;\n\n/**\n * Foundry module metric names (Crucible v0.2.7 taxonomy)\n */\nexport const FOUNDRY_METRICS = {\n // MIME detection counters\n MIME_DETECTIONS_JSON: \"foundry_mime_detections_total_json\",\n MIME_DETECTIONS_XML: \"foundry_mime_detections_total_xml\",\n MIME_DETECTIONS_YAML: \"foundry_mime_detections_total_yaml\",\n MIME_DETECTIONS_CSV: \"foundry_mime_detections_total_csv\",\n MIME_DETECTIONS_PLAIN_TEXT: \"foundry_mime_detections_total_plain_text\",\n MIME_DETECTIONS_UNKNOWN: \"foundry_mime_detections_total_unknown\",\n\n // MIME detection timing histograms\n MIME_DETECTION_MS_JSON: \"foundry_mime_detection_ms_json\",\n MIME_DETECTION_MS_XML: \"foundry_mime_detection_ms_xml\",\n MIME_DETECTION_MS_YAML: \"foundry_mime_detection_ms_yaml\",\n MIME_DETECTION_MS_CSV: \"foundry_mime_detection_ms_csv\",\n MIME_DETECTION_MS_PLAIN_TEXT: \"foundry_mime_detection_ms_plain_text\",\n MIME_DETECTION_MS_UNKNOWN: \"foundry_mime_detection_ms_unknown\",\n\n // General lookup counter\n LOOKUP_COUNT: \"foundry_lookup_count\",\n} as const;\n\n/**\n * Error handling module metric names (Crucible v0.2.7 taxonomy)\n */\nexport const ERROR_HANDLING_METRICS = {\n WRAPS_TOTAL: \"error_handling_wraps_total\",\n WRAP_MS: \"error_handling_wrap_ms\",\n} as const;\n\n/**\n * FulHash module metric names (Crucible v0.2.7 taxonomy)\n */\nexport const FULHASH_METRICS = {\n // Algorithm-specific counters\n OPERATIONS_XXH3_128: \"fulhash_operations_total_xxh3_128\",\n OPERATIONS_SHA256: \"fulhash_operations_total_sha256\",\n\n // General counters\n HASH_STRING_TOTAL: \"fulhash_hash_string_total\",\n BYTES_HASHED_TOTAL: \"fulhash_bytes_hashed_total\",\n\n // Timing histogram\n OPERATION_MS: \"fulhash_operation_ms\",\n} as const;\n\n/**\n * Label values for Prometheus exporter metrics (taxonomy-compliant)\n */\nexport const EXPORTER_LABELS = {\n // Refresh phases\n PHASE_COLLECT: \"collect\",\n PHASE_CONVERT: \"convert\",\n PHASE_EXPORT: \"export\",\n\n // Results\n RESULT_SUCCESS: \"success\",\n RESULT_ERROR: \"error\",\n\n // Error types\n ERROR_VALIDATION: \"validation\",\n ERROR_IO: \"io\",\n ERROR_TIMEOUT: \"timeout\",\n ERROR_OTHER: \"other\",\n\n // Restart reasons\n REASON_CONFIG_CHANGE: \"config_change\",\n REASON_ERROR: \"error\",\n REASON_MANUAL: \"manual\",\n REASON_OTHER: \"other\",\n} as const;\n","/**\n * Prometheus exporter error classes\n *\n * Specialized errors for Prometheus integration failures.\n */\n\nimport { FulmenError } from \"../../errors/index.js\";\n\n/**\n * Base error class for Prometheus exporter errors\n */\nexport class PrometheusExporterError extends FulmenError {\n constructor(\n message: string,\n options?: {\n code?: string;\n cause?: unknown;\n context?: Record<string, unknown>;\n },\n ) {\n super({\n code: options?.code || \"PROMETHEUS_EXPORTER_ERROR\",\n message,\n severity: \"medium\",\n context: options?.context,\n });\n\n if (options?.cause) {\n this.cause = options.cause;\n }\n\n this.name = \"PrometheusExporterError\";\n }\n}\n\n/**\n * Error thrown when prom-client peer dependency is not installed\n */\nexport class PromClientNotFoundError extends PrometheusExporterError {\n constructor(cause?: unknown) {\n super(\n \"prom-client peer dependency not found. Install with: bun add prom-client\\n\" +\n \"For npm: npm install prom-client\\n\" +\n \"For more information, see: https://github.com/siimon/prom-client\",\n {\n code: \"PROM_CLIENT_NOT_FOUND\",\n cause,\n context: {\n suggestion: 'Run \"bun add prom-client\" to install the required peer dependency',\n },\n },\n );\n\n this.name = \"PromClientNotFoundError\";\n }\n}\n\n/**\n * Error thrown when metric name is invalid for Prometheus\n */\nexport class InvalidMetricNameError extends PrometheusExporterError {\n constructor(metricName: string, reason: string) {\n super(`Invalid Prometheus metric name: \"${metricName}\". ${reason}`, {\n code: \"INVALID_METRIC_NAME\",\n context: {\n metricName,\n reason,\n suggestion:\n \"Prometheus metric names must match: [a-zA-Z_:][a-zA-Z0-9_:]*\\n\" +\n \"See: https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels\",\n },\n });\n\n this.name = \"InvalidMetricNameError\";\n }\n}\n\n/**\n * Error thrown when label name is invalid for Prometheus\n */\nexport class InvalidLabelNameError extends PrometheusExporterError {\n constructor(labelName: string, reason: string) {\n super(`Invalid Prometheus label name: \"${labelName}\". ${reason}`, {\n code: \"INVALID_LABEL_NAME\",\n context: {\n labelName,\n reason,\n suggestion:\n \"Prometheus label names must match: [a-zA-Z_][a-zA-Z0-9_]*\\n\" +\n \"See: https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels\",\n },\n });\n\n this.name = \"InvalidLabelNameError\";\n }\n}\n\n/**\n * Error thrown when metric registration fails\n */\nexport class MetricRegistrationError extends PrometheusExporterError {\n constructor(metricName: string, cause: unknown) {\n super(`Failed to register Prometheus metric: \"${metricName}\"`, {\n code: \"METRIC_REGISTRATION_FAILED\",\n cause,\n context: {\n metricName,\n suggestion: \"Check for duplicate metric names or incompatible collector types\",\n },\n });\n\n this.name = \"MetricRegistrationError\";\n }\n}\n\n/**\n * Error thrown when refresh operation fails\n *\n * This error wraps underlying errors (InvalidMetricNameError, MetricRegistrationError, etc.)\n * that occur during the refresh process. Callers should inspect the `cause` property\n * to access the root error for specific error handling.\n *\n * @example\n * ```typescript\n * try {\n * await exporter.refresh();\n * } catch (err) {\n * if (err instanceof RefreshError) {\n * // Check the underlying cause for specific error types\n * if (err.cause instanceof InvalidMetricNameError) {\n * console.error('Invalid metric name:', err.cause.message);\n * }\n * }\n * }\n * ```\n */\nexport class RefreshError extends PrometheusExporterError {\n constructor(cause: unknown, context?: Record<string, unknown>) {\n super(\"Failed to refresh Prometheus metrics from TelemetryRegistry\", {\n code: \"REFRESH_FAILED\",\n cause,\n context,\n });\n\n this.name = \"RefreshError\";\n }\n}\n","/**\n * Prometheus exporter core implementation\n *\n * Bridges TSFulmen TelemetryRegistry to prom-client for Prometheus exposition.\n * Uses dynamic imports and loose typing for optional peer dependency (prom-client).\n *\n * NOTE: This file intentionally uses 'any' types for prom-client peer dependency\n * to avoid compile-time dependency. Runtime validation ensures type safety.\n * See .plans/active/v0.2.x-plans/prometheus-type-safety-enhancement.md for future work.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { metrics as defaultRegistry } from \"../index.js\";\nimport type { MetricsEvent } from \"../types.js\";\nimport { isHistogramSummary } from \"../types.js\";\nimport {\n ADR0007_BUCKETS_SECONDS,\n EXPORTER_LABELS,\n msToSeconds,\n PROMETHEUS_EXPORTER_METRICS,\n} from \"./constants.js\";\nimport {\n InvalidLabelNameError,\n InvalidMetricNameError,\n MetricRegistrationError,\n PromClientNotFoundError,\n RefreshError,\n} from \"./errors.js\";\nimport type { ExporterStats, PrometheusExporterOptions, RefreshOptions } from \"./types.js\";\n\n/**\n * Prometheus exporter\n *\n * Converts TSFulmen TelemetryRegistry metrics to Prometheus format using prom-client.\n *\n * @example\n * ```typescript\n * import { PrometheusExporter } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n * import { metrics } from '@fulmenhq/tsfulmen/telemetry';\n *\n * // Create exporter\n * const exporter = new PrometheusExporter({\n * registry: metrics,\n * namespace: 'myapp',\n * defaultLabels: { environment: 'production' }\n * });\n *\n * // Refresh metrics from registry\n * await exporter.refresh();\n *\n * // Get Prometheus text format\n * const output = await exporter.getMetrics();\n * console.log(output);\n * ```\n */\nexport class PrometheusExporter {\n private readonly telemetryRegistry: typeof defaultRegistry;\n private namespace: string;\n private subsystem: string;\n private readonly defaultLabels: Record<string, string>;\n private readonly helpText: Record<string, string>;\n private readonly metricsEnabled: boolean;\n private readonly recordClientLabel: boolean;\n private readonly moduleMetricsEnabled: boolean;\n\n // prom-client types unavailable at compile time (optional peer dependency)\n // Using 'any' with runtime validation - see file header comment for rationale\n // biome-ignore lint/suspicious/noExplicitAny: prom-client is optional peer dependency\n private promClient: any = null;\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Registry type unavailable at compile time\n private promRegistry: any = null;\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Counter type unavailable at compile time\n private counters: Map<string, any> = new Map();\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Gauge type unavailable at compile time\n private gauges: Map<string, any> = new Map();\n // biome-ignore lint/suspicious/noExplicitAny: prom-client Histogram type unavailable at compile time\n private histograms: Map<string, any> = new Map();\n\n // Statistics\n private refreshCount = 0;\n private errorCount = 0;\n private lastRefreshTime: string | null = null;\n\n // Background refresh loop\n private refreshInterval: NodeJS.Timeout | null = null;\n private refreshPromise: Promise<void> | null = null;\n private isRefreshing = false;\n\n /**\n * Create Prometheus exporter\n *\n * @param options - Exporter configuration\n * @throws {InvalidLabelNameError} If default label names are invalid\n */\n constructor(options: PrometheusExporterOptions = {}) {\n this.telemetryRegistry = options.registry || defaultRegistry;\n this.defaultLabels = options.defaultLabels || {};\n this.helpText = options.helpText || {};\n this.metricsEnabled = options.metricsEnabled ?? true;\n this.recordClientLabel = options.recordClientLabel ?? false;\n this.moduleMetricsEnabled = options.moduleMetricsEnabled ?? true;\n\n // Validate default label names\n for (const labelName of Object.keys(this.defaultLabels)) {\n this.validateLabelName(labelName);\n }\n\n // Initialize namespace and subsystem\n // May be overridden by App Identity in init()\n this.namespace = options.namespace || \"tsfulmen\";\n this.subsystem = options.subsystem || \"app\";\n }\n\n /**\n * Initialize exporter (async setup)\n *\n * Loads prom-client and optionally loads App Identity for namespace/subsystem.\n * Called automatically on first refresh() or getMetrics() call.\n *\n * @throws {PromClientNotFoundError} If prom-client not installed\n */\n private async init(): Promise<void> {\n if (this.promClient) {\n return; // Already initialized\n }\n\n // Lazy load prom-client (peer dependency)\n try {\n this.promClient = await import(\"prom-client\");\n this.promRegistry = new this.promClient.Registry();\n } catch (err) {\n throw new PromClientNotFoundError(err);\n }\n\n // Try to load App Identity for namespace/subsystem (optional)\n if (this.namespace === \"tsfulmen\" || this.subsystem === \"app\") {\n try {\n const { loadIdentity } = await import(\"../../appidentity/index.js\");\n const identity = await loadIdentity({ skipValidation: true });\n\n if (this.namespace === \"tsfulmen\" && identity.app.vendor) {\n this.namespace = identity.app.vendor;\n }\n if (this.subsystem === \"app\" && identity.app.binary_name) {\n this.subsystem = identity.app.binary_name;\n }\n } catch {\n // App Identity not available - use defaults\n }\n }\n }\n\n /**\n * Safely emit instrumentation metric (silently fails if registry doesn't support it)\n * Used to avoid breaking tests that use mock registries\n */\n private safeInstrument(fn: () => void): void {\n try {\n fn();\n } catch {\n // Silently ignore instrumentation failures (e.g., mock registries in tests)\n }\n }\n\n /**\n * Refresh metrics from TelemetryRegistry\n *\n * Exports current metrics from TelemetryRegistry and updates Prometheus collectors.\n * Emits instrumentation metrics per Crucible v0.2.7 taxonomy.\n *\n * @throws {RefreshError} If refresh operation fails. Inspect `error.cause` for the\n * underlying error (InvalidMetricNameError, MetricRegistrationError, etc.) to handle\n * specific failure conditions.\n */\n async refresh(): Promise<void> {\n const startTime = performance.now();\n\n // Set inflight gauge to 1\n this.safeInstrument(() => {\n this.telemetryRegistry.gauge(PROMETHEUS_EXPORTER_METRICS.REFRESH_INFLIGHT).set(1);\n });\n\n try {\n // Phase: collect - export from telemetry registry\n await this.init();\n const events = await this.telemetryRegistry.export();\n\n // Phase: convert - update Prometheus collectors\n for (const event of events) {\n this.updateCollector(event);\n }\n\n // Success metrics\n this.refreshCount++;\n this.lastRefreshTime = new Date().toISOString();\n\n const durationMs = performance.now() - startTime;\n\n // Emit success metrics\n this.safeInstrument(() => {\n this.telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.REFRESH_TOTAL)\n .inc(1, { result: EXPORTER_LABELS.RESULT_SUCCESS });\n\n this.telemetryRegistry\n .histogram(PROMETHEUS_EXPORTER_METRICS.REFRESH_DURATION_SECONDS, {\n buckets: [...ADR0007_BUCKETS_SECONDS],\n })\n .observe(msToSeconds(durationMs), {\n phase: EXPORTER_LABELS.PHASE_EXPORT,\n result: EXPORTER_LABELS.RESULT_SUCCESS,\n });\n });\n } catch (err) {\n this.errorCount++;\n\n const durationMs = performance.now() - startTime;\n\n // Classify error type\n let errorType: string = EXPORTER_LABELS.ERROR_OTHER;\n if (err instanceof InvalidMetricNameError || err instanceof InvalidLabelNameError) {\n errorType = EXPORTER_LABELS.ERROR_VALIDATION;\n } else if (err instanceof MetricRegistrationError) {\n errorType = EXPORTER_LABELS.ERROR_OTHER;\n }\n\n // Emit error metrics\n this.safeInstrument(() => {\n this.telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.REFRESH_TOTAL)\n .inc(1, { result: EXPORTER_LABELS.RESULT_ERROR });\n\n this.telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.REFRESH_ERRORS_TOTAL)\n .inc(1, { error_type: errorType });\n\n this.telemetryRegistry\n .histogram(PROMETHEUS_EXPORTER_METRICS.REFRESH_DURATION_SECONDS, {\n buckets: [...ADR0007_BUCKETS_SECONDS],\n })\n .observe(msToSeconds(durationMs), {\n phase: EXPORTER_LABELS.PHASE_EXPORT,\n result: EXPORTER_LABELS.RESULT_ERROR,\n });\n });\n\n throw new RefreshError(err, {\n refreshCount: this.refreshCount,\n errorCount: this.errorCount,\n });\n } finally {\n // Clear inflight gauge\n this.safeInstrument(() => {\n this.telemetryRegistry.gauge(PROMETHEUS_EXPORTER_METRICS.REFRESH_INFLIGHT).set(0);\n });\n }\n }\n\n /**\n * Get Prometheus metrics in text format\n *\n * Returns metrics in Prometheus exposition text format.\n *\n * @returns Prometheus text format string\n */\n async getMetrics(): Promise<string> {\n await this.init();\n\n if (!this.promRegistry) {\n throw new Error(\"Prometheus registry not initialized\");\n }\n\n return this.promRegistry.metrics();\n }\n\n /**\n * Get exporter statistics\n */\n getStats(): ExporterStats {\n return {\n refreshCount: this.refreshCount,\n errorCount: this.errorCount,\n lastRefreshTime: this.lastRefreshTime,\n metricsCount: this.counters.size + this.gauges.size + this.histograms.size,\n isRefreshing: this.isRefreshing,\n };\n }\n\n /**\n * Get current metrics configuration\n *\n * Returns effective configuration being used by exporter,\n * including defaults for any unspecified options.\n *\n * @returns Current metrics configuration\n */\n getMetricsConfig() {\n return {\n metricsEnabled: this.metricsEnabled,\n recordClientLabel: this.recordClientLabel,\n moduleMetricsEnabled: this.moduleMetricsEnabled,\n namespace: this.namespace,\n subsystem: this.subsystem,\n defaultLabels: { ...this.defaultLabels },\n helpText: { ...this.helpText },\n };\n }\n\n /**\n * Get underlying prom-client Registry\n *\n * Returns null if not yet initialized.\n * Use for advanced prom-client operations.\n */\n // biome-ignore lint/suspicious/noExplicitAny: Returns prom-client Registry type (optional peer dependency)\n getRegistry(): any {\n return this.promRegistry;\n }\n\n /**\n * Get telemetry registry for self-instrumentation\n *\n * Returns the MetricsRegistry instance used for exporter self-instrumentation.\n * Useful for HTTP handler instrumentation.\n *\n * @internal\n */\n getTelemetryRegistry(): typeof defaultRegistry {\n return this.telemetryRegistry;\n }\n\n /**\n * Emit restart metric\n *\n * Records a restart event for tracking exporter or server restarts.\n * Use this when restarting the HTTP metrics server or other exporter components.\n *\n * @param reason - Reason for restart (config_change, error, manual, other)\n *\n * @example\n * ```typescript\n * // Restart server after config change\n * await stopMetricsServer(server);\n * exporter.recordRestart('config_change');\n * const newServer = await startMetricsServer(exporter, newConfig);\n * ```\n */\n recordRestart(reason: \"config_change\" | \"error\" | \"manual\" | \"other\"): void {\n this.safeInstrument(() => {\n this.telemetryRegistry.counter(PROMETHEUS_EXPORTER_METRICS.RESTARTS_TOTAL).inc(1, { reason });\n });\n }\n\n /**\n * Reset all metrics\n */\n reset(): void {\n if (this.promRegistry) {\n this.promRegistry.clear();\n }\n this.counters.clear();\n this.gauges.clear();\n this.histograms.clear();\n }\n\n /**\n * Start background refresh loop\n *\n * Automatically refreshes metrics from TelemetryRegistry at specified interval.\n * Useful for long-running services where metrics should be continuously updated.\n *\n * @param options - Refresh configuration (interval, error handler)\n *\n * @example\n * ```typescript\n * const exporter = new PrometheusExporter({ registry: metrics });\n *\n * // Start refreshing every 15 seconds (default)\n * exporter.startRefresh();\n *\n * // Custom interval and error handling\n * exporter.startRefresh({\n * intervalMs: 10000,\n * onError: (err) => logger.error('Refresh failed:', err)\n * });\n * ```\n */\n startRefresh(options: RefreshOptions = {}): void {\n const intervalMs = options.intervalMs ?? 15000;\n const _isRestart = !!this.refreshInterval;\n\n // Stop existing refresh if running (restart scenario)\n if (this.refreshInterval) {\n this.stopRefresh();\n\n // Emit restart metric\n this.safeInstrument(() => {\n this.telemetryRegistry.counter(PROMETHEUS_EXPORTER_METRICS.RESTARTS_TOTAL).inc(1, {\n reason: options.restartReason || EXPORTER_LABELS.REASON_OTHER,\n });\n });\n }\n\n // Start refresh loop\n this.refreshInterval = setInterval(() => {\n // Don't start new refresh if one is already running (serialization)\n if (this.refreshPromise) {\n return;\n }\n\n this.refreshPromise = this.refresh()\n .catch((err) => {\n // Call error handler if provided\n if (options.onError) {\n options.onError(err as Error);\n }\n })\n .finally(() => {\n this.refreshPromise = null;\n });\n }, intervalMs);\n\n // Update stats to indicate refreshing\n this.isRefreshing = true;\n }\n\n /**\n * Stop background refresh loop\n *\n * Clears the refresh interval and performs one final refresh to capture\n * the latest metrics state before stopping.\n *\n * @example\n * ```typescript\n * // Graceful shutdown\n * await exporter.stopRefresh();\n * ```\n */\n async stopRefresh(): Promise<void> {\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval);\n this.refreshInterval = null;\n }\n\n // Wait for any in-flight refresh to complete\n if (this.refreshPromise) {\n await this.refreshPromise;\n }\n\n // Perform final refresh to capture latest state\n try {\n await this.refresh();\n } catch (_err) {\n // Log but don't throw during shutdown\n // Error is already tracked in stats\n }\n\n // Update stats to indicate not refreshing\n this.isRefreshing = false;\n }\n\n /**\n * Update Prometheus collector from MetricsEvent\n */\n private updateCollector(event: MetricsEvent): void {\n const metricName = this.formatMetricName(event.name);\n const help = this.getHelpText(event.name);\n const labelNames = Object.keys(this.defaultLabels);\n\n if (isHistogramSummary(event.value)) {\n this.updateHistogram(metricName, help, labelNames, event.value);\n } else if (typeof event.value === \"number\") {\n // Use Gauge for all scalar metrics (simplest approach)\n // TSFulmen doesn't distinguish Counter vs Gauge in export format\n this.updateGauge(metricName, help, labelNames, event.value);\n }\n }\n\n /**\n * Update or create Prometheus Gauge\n */\n private updateGauge(name: string, help: string, labelNames: string[], value: number): void {\n let gauge = this.gauges.get(name);\n if (!gauge) {\n try {\n gauge = new this.promClient.Gauge({\n name,\n help,\n labelNames,\n registers: [this.promRegistry],\n });\n this.gauges.set(name, gauge);\n } catch (err) {\n throw new MetricRegistrationError(name, err);\n }\n }\n\n gauge.labels(this.defaultLabels).set(value);\n }\n\n /**\n * Update or create Prometheus Histogram\n *\n * CRITICAL: Converts OTLP cumulative buckets to Prometheus format.\n * This is an approximation - see Phase 0 investigation for details.\n *\n * LIMITATION: Original observations cannot be perfectly reconstructed from bucket summary.\n * Percentiles will be approximate based on bucket midpoints.\n */\n // biome-ignore lint/suspicious/noExplicitAny: summary is HistogramSummary from TelemetryRegistry\n private updateHistogram(name: string, help: string, labelNames: string[], summary: any): void {\n // biome-ignore lint/suspicious/noExplicitAny: bucket type from HistogramSummary\n const buckets = summary.buckets.map((b: any) => b.le);\n\n let histogram = this.histograms.get(name);\n if (!histogram) {\n try {\n histogram = new this.promClient.Histogram({\n name,\n help,\n labelNames,\n buckets,\n registers: [this.promRegistry],\n });\n this.histograms.set(name, histogram);\n } catch (err) {\n throw new MetricRegistrationError(name, err);\n }\n }\n\n // Reconstruct observations from summary\n const observations = this.reconstructObservations(summary);\n for (const value of observations) {\n histogram.labels(this.defaultLabels).observe(value);\n }\n }\n\n /**\n * Reconstruct observations from histogram summary\n *\n * Converts OTLP cumulative bucket counts to approximate observation values.\n * Uses bucket midpoints to generate synthetic observations.\n *\n * LIMITATION: This is an approximation. Original observation values cannot be\n * perfectly reconstructed from bucket summaries. Percentiles will be approximate\n * based on bucket boundaries. This is acceptable for v0.1.8 initial release.\n *\n * TODO: Future enhancement - capture raw observations in TelemetryRegistry\n * for lossless Prometheus export. Track in Phase 2+ planning.\n * See: .plans/active/v0.2.x-plans/prometheus-type-safety-enhancement.md\n *\n * Algorithm:\n * 1. Calculate non-cumulative count for each bucket (delta between adjacent buckets)\n * 2. For each bucket, place observations at the midpoint between bucket boundaries\n * 3. Return array of synthetic observation values\n */\n // biome-ignore lint/suspicious/noExplicitAny: summary is HistogramSummary from TelemetryRegistry\n private reconstructObservations(summary: any): number[] {\n const observations: number[] = [];\n const buckets = summary.buckets;\n\n if (!buckets || buckets.length === 0) {\n return observations;\n }\n\n let prevCount = 0;\n for (let i = 0; i < buckets.length; i++) {\n const bucket = buckets[i];\n const count = bucket.count - prevCount; // Non-cumulative count for this bucket\n\n if (count > 0) {\n // Determine observation value (bucket midpoint)\n let value: number;\n if (i === 0) {\n // First bucket: midpoint between 0 and upper bound\n value = bucket.le / 2;\n } else {\n // Other buckets: midpoint between previous and current upper bound\n const prevLe = buckets[i - 1].le;\n value = (prevLe + bucket.le) / 2;\n }\n\n // Add 'count' observations at this value\n for (let j = 0; j < count; j++) {\n observations.push(value);\n }\n }\n\n prevCount = bucket.count;\n }\n\n return observations;\n }\n\n /**\n * Format metric name with namespace and subsystem prefix\n *\n * Format: {namespace}_{subsystem}_{metric}\n * Example: fulmen_myapp_schema_validations\n */\n private formatMetricName(name: string): string {\n this.validateMetricName(name);\n return `${this.namespace}_${this.subsystem}_${name}`;\n }\n\n /**\n * Get help text for metric\n *\n * Uses custom help text if provided, otherwise generates default.\n */\n private getHelpText(name: string): string {\n if (this.helpText[name]) {\n return this.helpText[name];\n }\n return `TSFulmen metric: ${name}`;\n }\n\n /**\n * Validate Prometheus metric name\n *\n * Rules: Must start with [a-zA-Z_:] and contain only [a-zA-Z0-9_:]\n *\n * @throws {InvalidMetricNameError} If name is invalid\n */\n private validateMetricName(name: string): void {\n const validPattern = /^[a-zA-Z_:][a-zA-Z0-9_:]*$/;\n if (!validPattern.test(name)) {\n throw new InvalidMetricNameError(\n name,\n \"Metric names must start with [a-zA-Z_:] and contain only [a-zA-Z0-9_:]\",\n );\n }\n }\n\n /**\n * Validate Prometheus label name\n *\n * Rules: Must start with [a-zA-Z_] and contain only [a-zA-Z0-9_]\n *\n * @throws {InvalidLabelNameError} If name is invalid\n */\n private validateLabelName(name: string): void {\n const validPattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n if (!validPattern.test(name)) {\n throw new InvalidLabelNameError(\n name,\n \"Label names must start with [a-zA-Z_] and contain only [a-zA-Z0-9_]\",\n );\n }\n }\n}\n","/**\n * Prometheus exporter lifecycle integration\n *\n * Helpers for integrating PrometheusExporter with TSFulmen lifecycle management,\n * particularly signal handling for graceful shutdown.\n */\n\nimport type { SignalManager } from \"../../foundry/signals/index.js\";\nimport type { PrometheusExporter } from \"./exporter.js\";\n\n/**\n * Register Prometheus exporter shutdown handler\n *\n * Automatically stops the background refresh loop and performs a final refresh\n * when SIGTERM or SIGINT is received. This ensures metrics are up-to-date\n * before the process terminates.\n *\n * @param exporter - PrometheusExporter instance to manage\n * @param manager - SignalManager instance for lifecycle coordination\n *\n * @example\n * ```typescript\n * import { PrometheusExporter, registerPrometheusShutdown } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n * import { createSignalManager } from '@fulmenhq/tsfulmen/foundry/signals';\n *\n * const exporter = new PrometheusExporter({ registry: metrics });\n * const signalManager = createSignalManager();\n *\n * // Register graceful shutdown\n * await registerPrometheusShutdown(exporter, signalManager);\n *\n * // Start refresh loop\n * exporter.startRefresh({ intervalMs: 15000 });\n *\n * // When SIGTERM/SIGINT received, exporter will:\n * // 1. Stop refresh loop\n * // 2. Perform final refresh\n * // 3. Allow process to exit gracefully\n * ```\n */\nexport async function registerPrometheusShutdown(\n exporter: PrometheusExporter,\n manager: SignalManager,\n): Promise<void> {\n const shutdownHandler = async () => {\n await exporter.stopRefresh();\n };\n\n // Register for both SIGTERM and SIGINT\n await manager.register(\"SIGTERM\", shutdownHandler);\n await manager.register(\"SIGINT\", shutdownHandler);\n}\n","/**\n * Prometheus HTTP server implementation\n *\n * Framework-agnostic HTTP handler and dev server for exposing Prometheus metrics.\n * Compatible with Node.js http, Express, Fastify, and other frameworks.\n */\n\nimport type { IncomingMessage, Server, ServerResponse } from \"node:http\";\nimport { createServer } from \"node:http\";\nimport { createLogger, LoggingProfile } from \"../../logging/index.js\";\nimport type { MetricsRegistry } from \"../registry.js\";\nimport { PROMETHEUS_EXPORTER_METRICS } from \"./constants.js\";\nimport type { PrometheusExporter } from \"./exporter.js\";\nimport type { ServerOptions } from \"./types.js\";\n\n/**\n * Safe instrumentation helper for HTTP metrics\n *\n * Emits HTTP metrics to provided registry, silently failing if registry\n * doesn't support operation (e.g., mock registries in tests).\n */\nfunction safeInstrumentHTTP(registry: MetricsRegistry | null, fn: () => void): void {\n if (!registry) return;\n try {\n fn();\n } catch {\n // Silently fail - instrumentation is non-critical\n }\n}\n\n/**\n * Get logger from exporter with metricsEnabled check\n */\nfunction getExporterLogger(exporter: PrometheusExporter) {\n // Access private logger property through type assertion\n // biome-ignore lint/suspicious/noExplicitAny: Need to access private logger property\n const exporterAny = exporter as any;\n const logger = exporterAny.logger;\n\n // Return null logger if metrics disabled\n return exporterAny.metricsEnabled ? logger : null;\n}\n\n/**\n * HTTP request context for hooks\n *\n * Provides minimal interface for auth and rate limiting hooks.\n * Compatible with Node.js IncomingMessage and framework request objects.\n */\nexport interface RequestContext {\n /** HTTP method (GET, POST, etc.) */\n method?: string;\n /** Request URL path */\n url?: string;\n /** Request headers */\n headers: Record<string, string | string[] | undefined>;\n /** Remote IP address */\n remoteAddress?: string;\n}\n\n/**\n * Extract request context from Node.js IncomingMessage\n */\nfunction extractRequestContext(req: IncomingMessage): RequestContext {\n return {\n method: req.method,\n url: req.url,\n headers: req.headers as Record<string, string | string[] | undefined>,\n remoteAddress: req.socket.remoteAddress,\n };\n}\n\n/**\n * Create Prometheus metrics HTTP handler\n *\n * Returns a framework-agnostic handler compatible with Node.js http, Express,\n * Fastify, and other frameworks. The handler serves Prometheus metrics in\n * text exposition format with optional authentication and rate limiting.\n *\n * @param exporter - PrometheusExporter instance\n * @param options - Server options (auth, rate limiting, refresh behavior)\n * @returns HTTP handler function\n *\n * @example\n * ```typescript\n * // Basic usage with Node.js http\n * import http from 'node:http';\n * import { PrometheusExporter, createMetricsHandler } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n *\n * const exporter = new PrometheusExporter({ registry: metrics });\n * const handler = createMetricsHandler(exporter);\n *\n * const server = http.createServer(handler);\n * server.listen(9464);\n * ```\n *\n * @example\n * ```typescript\n * // With authentication\n * const handler = createMetricsHandler(exporter, {\n * authenticate: async (req) => {\n * const token = req.headers['authorization'];\n * return token === 'Bearer secret-token';\n * }\n * });\n * ```\n *\n * @example\n * ```typescript\n * // With rate limiting\n * const handler = createMetricsHandler(exporter, {\n * rateLimit: async (req) => {\n * const ip = req.remoteAddress;\n * return rateLimiter.checkLimit(ip);\n * }\n * });\n * ```\n */\nexport function createMetricsHandler(\n exporter: PrometheusExporter,\n options: ServerOptions = {},\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n const path = options.path ?? \"/metrics\";\n const refreshOnScrape = options.refreshOnScrape ?? false;\n const logger = getExporterLogger(exporter);\n\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const telemetryRegistry = exporter.getTelemetryRegistry();\n let _statusCode = 200;\n const startTime = performance.now();\n\n try {\n // Extract request context for hooks\n const context = extractRequestContext(req);\n\n // Check path - only serve metrics on configured path\n if (req.url !== path) {\n _statusCode = 404;\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not Found\");\n\n // Emit HTTP request metric (4xx)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"404\", path: req.url || \"unknown\" });\n });\n return;\n }\n\n // Check authentication if hook provided\n if (options.authenticate) {\n const authResult = await options.authenticate(context);\n if (!authResult) {\n _statusCode = 401;\n res.writeHead(401, {\n \"Content-Type\": \"text/plain\",\n \"WWW-Authenticate\": \"Bearer\",\n });\n res.end(\"Unauthorized\");\n\n // Emit HTTP request and error metrics (auth failure)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"401\", path });\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_ERRORS_TOTAL)\n .inc(1, { status: \"401\", path });\n });\n return;\n }\n }\n\n // Check rate limit if hook provided\n if (options.rateLimit) {\n const rateLimitResult = await options.rateLimit(context);\n if (!rateLimitResult) {\n _statusCode = 429;\n res.writeHead(429, {\n \"Content-Type\": \"text/plain\",\n \"Retry-After\": \"60\",\n });\n res.end(\"Too Many Requests\");\n\n // Emit HTTP request metric (4xx rate limit)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"429\", path });\n });\n return;\n }\n }\n\n // Refresh metrics if configured (optional, adds latency)\n if (refreshOnScrape) {\n await exporter.refresh();\n }\n\n // Get metrics in Prometheus text format\n const metrics = await exporter.getMetrics();\n\n // Send response with correct content-type\n // Prometheus text format version 0.0.4\n _statusCode = 200;\n res.writeHead(200, {\n \"Content-Type\": \"text/plain; version=0.0.4; charset=utf-8\",\n \"Content-Length\": Buffer.byteLength(metrics, \"utf-8\"),\n });\n res.end(metrics);\n\n // Emit HTTP request metric (2xx success)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"200\", path });\n });\n } catch (err) {\n // Internal server error\n const errorMessage = err instanceof Error ? err.message : \"Internal Server Error\";\n\n _statusCode = 500;\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(`Error: ${errorMessage}`);\n\n // Emit HTTP request and error metrics (5xx failure)\n safeInstrumentHTTP(telemetryRegistry, () => {\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL)\n .inc(1, { status: \"500\", path });\n telemetryRegistry\n .counter(PROMETHEUS_EXPORTER_METRICS.HTTP_ERRORS_TOTAL)\n .inc(1, { status: \"500\", path });\n });\n } finally {\n // Log HTTP request completion\n if (logger) {\n const durationMs = performance.now() - startTime;\n const context = extractRequestContext(req);\n\n logger.info(\"HTTP request processed\", {\n metric_name: PROMETHEUS_EXPORTER_METRICS.HTTP_REQUESTS_TOTAL,\n status: _statusCode.toString(),\n path: req.url || \"unknown\",\n method: context.method || \"GET\",\n duration_ms: Math.round(durationMs),\n remote_address: context.remoteAddress,\n });\n }\n }\n };\n}\n\n/**\n * Start Prometheus metrics dev server\n *\n * Creates a standalone HTTP server for serving Prometheus metrics.\n * Useful for development, testing, and simple deployments without a full application framework.\n *\n * @param exporter - PrometheusExporter instance\n * @param options - Server configuration (host, port, path, auth, rate limiting)\n * @returns Promise that resolves to the HTTP Server instance\n *\n * @example\n * ```typescript\n * import { PrometheusExporter, startMetricsServer } from '@fulmenhq/tsfulmen/telemetry/prometheus';\n *\n * const exporter = new PrometheusExporter({ registry: metrics });\n *\n * // Start dev server\n * const server = await startMetricsServer(exporter, {\n * host: '127.0.0.1',\n * port: 9464,\n * path: '/metrics'\n * });\n *\n * console.log('Metrics server listening on http://127.0.0.1:9464/metrics');\n *\n * // Graceful shutdown\n * process.on('SIGTERM', async () => {\n * await stopMetricsServer(server);\n * });\n * ```\n */\nexport async function startMetricsServer(\n exporter: PrometheusExporter,\n options: ServerOptions = {},\n): Promise<Server> {\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 9464;\n const path = options.path ?? \"/metrics\";\n\n // Create handler with options\n const handler = createMetricsHandler(exporter, options);\n\n // Create HTTP server\n const server = createServer(handler);\n\n // Create logger for server operations (only if metrics enabled)\n const exporterLogger = getExporterLogger(exporter);\n const logger =\n exporterLogger ||\n createLogger({\n service: \"prometheus_exporter\",\n profile: LoggingProfile.STRUCTURED,\n });\n\n // Start listening\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n // Log server startup\n logger.info(\"Prometheus metrics server started\", {\n host,\n port,\n path,\n url: `http://${host}:${port}${path}`,\n });\n resolve(server);\n });\n\n server.on(\"error\", (err) => {\n // Log server error\n logger.error(\"Prometheus metrics server error\", err as Error, {\n host,\n port,\n path,\n });\n reject(err);\n });\n });\n}\n\n/**\n * Stop Prometheus metrics server\n *\n * Gracefully shuts down the HTTP server with a configurable timeout.\n * Closes all connections and waits for in-flight requests to complete.\n *\n * @param server - HTTP Server instance from startMetricsServer\n * @param timeoutMs - Timeout in milliseconds (default: 5000)\n * @returns Promise that resolves when server is closed\n *\n * @example\n * ```typescript\n * // Graceful shutdown with 5 second timeout\n * await stopMetricsServer(server);\n *\n * // Custom timeout\n * await stopMetricsServer(server, 10000);\n * ```\n */\nexport async function stopMetricsServer(\n server: Server,\n timeoutMs = 5000,\n exporter?: PrometheusExporter,\n): Promise<void> {\n // Create logger for server operations (only if metrics enabled)\n const exporterLogger = exporter ? getExporterLogger(exporter) : null;\n const logger =\n exporterLogger ||\n createLogger({\n service: \"prometheus_exporter\",\n profile: LoggingProfile.STRUCTURED,\n });\n\n return new Promise((resolve, reject) => {\n // Set timeout for forced shutdown\n const timeout = setTimeout(() => {\n logger.warn(\"Prometheus metrics server shutdown timed out, forcing close\", {\n timeout_ms: timeoutMs,\n });\n server.closeAllConnections?.(); // Available in Node.js 18.2+\n reject(new Error(`Server shutdown timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n // Graceful close\n server.close((err) => {\n clearTimeout(timeout);\n if (err) {\n logger.error(\"Error stopping Prometheus metrics server\", err, {\n timeout_ms: timeoutMs,\n });\n reject(err);\n } else {\n logger.info(\"Prometheus metrics server stopped\", {\n timeout_ms: timeoutMs,\n });\n resolve();\n }\n });\n\n // Close all connections immediately (allows graceful request completion)\n server.closeAllConnections?.(); // Available in Node.js 18.2+\n });\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { compileSchemaById } from './chunk-7SVYOPJ3.js';
1
+ import { compileSchemaById } from './chunk-SNV5WG5V.js';
2
2
  import { randomUUID } from 'crypto';
3
3
 
4
4
  var UUID_V4_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
@@ -406,5 +406,5 @@ function isFulmenErrorData(value) {
406
406
  var VERSION = "0.2.0";
407
407
 
408
408
  export { FulmenError, LEVEL_TO_SEVERITY, SEVERITY_LEVELS, Severity, VERSION, assertValidErrorData, compareSeverity, extractErrorMessage, extractStackTrace, formatValidationErrors, generateCorrelationId, getDefaultSeverity, getValidationErrors, isCorrelationId, isFulmenError, isFulmenErrorData, isSeverityLevel, isSeverityName, isValidCorrelationId, levelToSeverity, normalizeCorrelationId, serializeError, severityToLevel, validateErrorData };
409
- //# sourceMappingURL=chunk-CW4CSNVF.js.map
410
- //# sourceMappingURL=chunk-CW4CSNVF.js.map
409
+ //# sourceMappingURL=chunk-GOTEQYAD.js.map
410
+ //# sourceMappingURL=chunk-GOTEQYAD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/correlation.ts","../src/errors/severity.ts","../src/errors/serialization.ts","../src/errors/validators.ts","../src/errors/fulmen-error.ts","../src/errors/index.ts"],"names":[],"mappings":"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","file":"chunk-CW4CSNVF.js","sourcesContent":["/**\n * Correlation ID generation and validation for error tracking\n *\n * Provides UUID v4 generation for correlation IDs used in observability\n * and distributed tracing scenarios.\n */\n\nimport { randomUUID } from \"node:crypto\";\n\n/**\n * UUID v4 regex pattern for validation\n */\nconst UUID_V4_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * Generate a new correlation ID (UUID v4)\n *\n * Uses Node.js crypto.randomUUID() for cryptographically strong random values.\n *\n * @returns UUID v4 string (e.g., \"550e8400-e29b-41d4-a716-446655440000\")\n *\n * @example\n * ```typescript\n * const correlationId = generateCorrelationId();\n * // \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function generateCorrelationId(): string {\n return randomUUID();\n}\n\n/**\n * Validate if a string is a valid UUID v4 correlation ID\n *\n * Checks format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n * where y is one of [8, 9, a, b]\n *\n * @param id - String to validate\n * @returns True if valid UUID v4 format\n *\n * @example\n * ```typescript\n * isValidCorrelationId('550e8400-e29b-41d4-a716-446655440000') // true\n * isValidCorrelationId('not-a-uuid') // false\n * isValidCorrelationId('550e8400-e29b-31d4-a716-446655440000') // false (version 3, not 4)\n * ```\n */\nexport function isValidCorrelationId(id: string): boolean {\n return UUID_V4_PATTERN.test(id);\n}\n\n/**\n * Normalize a correlation ID (lowercase, trim whitespace)\n *\n * @param id - Correlation ID to normalize\n * @returns Normalized correlation ID\n *\n * @example\n * ```typescript\n * normalizeCorrelationId(' 550E8400-E29B-41D4-A716-446655440000 ')\n * // \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function normalizeCorrelationId(id: string): string {\n return id.trim().toLowerCase();\n}\n\n/**\n * Type guard to check if a value is a valid correlation ID\n *\n * @param value - Value to check\n * @returns True if value is a string and valid UUID v4\n *\n * @example\n * ```typescript\n * if (isCorrelationId(value)) {\n * // TypeScript knows value is string here\n * const normalized = normalizeCorrelationId(value);\n * }\n * ```\n */\nexport function isCorrelationId(value: unknown): value is string {\n return typeof value === \"string\" && isValidCorrelationId(value);\n}\n","/**\n * Severity mappings for error handling\n *\n * Implements severity levels from assessment/v1.0.0/severity-definitions schema\n * Provides bidirectional mapping between severity names and numeric levels\n */\n\n/**\n * Severity names aligned with assessment taxonomy\n */\nexport const Severity = {\n INFO: \"info\",\n LOW: \"low\",\n MEDIUM: \"medium\",\n HIGH: \"high\",\n CRITICAL: \"critical\",\n} as const;\n\n/**\n * Severity name type (string literal union)\n */\nexport type SeverityName = (typeof Severity)[keyof typeof Severity];\n\n/**\n * Numeric severity level for sorting and comparison\n * info=0, low=1, medium=2, high=3, critical=4\n */\nexport type SeverityLevel = 0 | 1 | 2 | 3 | 4;\n\n/**\n * Canonical severity level mapping (name → level)\n * Aligned with schemas/crucible-ts/assessment/v1.0.0/severity-definitions.schema.json\n */\nexport const SEVERITY_LEVELS: Record<SeverityName, SeverityLevel> = {\n info: 0,\n low: 1,\n medium: 2,\n high: 3,\n critical: 4,\n};\n\n/**\n * Reverse mapping (level → name)\n */\nexport const LEVEL_TO_SEVERITY: Record<SeverityLevel, SeverityName> = {\n 0: \"info\",\n 1: \"low\",\n 2: \"medium\",\n 3: \"high\",\n 4: \"critical\",\n};\n\n/**\n * Convert severity name to numeric level\n *\n * @param name - Severity name (info, low, medium, high, critical)\n * @returns Numeric severity level (0-4)\n * @throws {Error} If severity name is invalid\n *\n * @example\n * ```typescript\n * severityToLevel('high') // returns 3\n * severityToLevel('info') // returns 0\n * ```\n */\nexport function severityToLevel(name: string): SeverityLevel {\n if (!isSeverityName(name)) {\n throw new Error(\n `Invalid severity name: \"${name}\". Must be one of: ${Object.values(Severity).join(\", \")}`,\n );\n }\n return SEVERITY_LEVELS[name];\n}\n\n/**\n * Convert numeric level to severity name\n *\n * @param level - Numeric severity level (0-4)\n * @returns Severity name\n * @throws {Error} If level is invalid\n *\n * @example\n * ```typescript\n * levelToSeverity(3) // returns 'high'\n * levelToSeverity(0) // returns 'info'\n * ```\n */\nexport function levelToSeverity(level: number): SeverityName {\n if (!isSeverityLevel(level)) {\n throw new Error(`Invalid severity level: ${level}. Must be 0-4`);\n }\n return LEVEL_TO_SEVERITY[level];\n}\n\n/**\n * Type guard to check if a value is a valid severity name\n *\n * @param value - Value to check\n * @returns True if value is a valid SeverityName\n *\n * @example\n * ```typescript\n * if (isSeverityName(value)) {\n * const level = severityToLevel(value); // Type-safe\n * }\n * ```\n */\nexport function isSeverityName(value: unknown): value is SeverityName {\n return typeof value === \"string\" && Object.values(Severity).includes(value as SeverityName);\n}\n\n/**\n * Type guard to check if a value is a valid severity level\n *\n * @param value - Value to check\n * @returns True if value is a valid SeverityLevel\n *\n * @example\n * ```typescript\n * if (isSeverityLevel(value)) {\n * const name = levelToSeverity(value); // Type-safe\n * }\n * ```\n */\nexport function isSeverityLevel(value: unknown): value is SeverityLevel {\n return typeof value === \"number\" && value >= 0 && value <= 4 && Number.isInteger(value);\n}\n\n/**\n * Get default severity (medium/2) when not specified\n *\n * @returns Default severity name and level\n */\nexport function getDefaultSeverity(): {\n name: SeverityName;\n level: SeverityLevel;\n} {\n return {\n name: Severity.MEDIUM,\n level: 2,\n };\n}\n\n/**\n * Compare two severity levels\n *\n * @param a - First severity (name or level)\n * @param b - Second severity (name or level)\n * @returns Negative if a < b, positive if a > b, zero if equal\n *\n * @example\n * ```typescript\n * compareSeverity('high', 'low') // returns positive (high > low)\n * compareSeverity(2, 'critical') // returns negative (medium < critical)\n * ```\n */\nexport function compareSeverity(\n a: SeverityName | SeverityLevel,\n b: SeverityName | SeverityLevel,\n): number {\n const levelA = typeof a === \"string\" ? severityToLevel(a) : a;\n const levelB = typeof b === \"string\" ? severityToLevel(b) : b;\n return levelA - levelB;\n}\n","/**\n * Error serialization utilities\n *\n * Provides safe serialization of Error objects and unknown errors to structured data\n */\n\nimport { Severity, type SeverityLevel, type SeverityName } from \"./severity.js\";\n\n/**\n * FulmenError data structure (for serialization)\n * Defined here to avoid circular dependency\n */\nexport interface FulmenErrorData {\n readonly code: string;\n readonly message: string;\n readonly details?: Record<string, unknown>;\n readonly path?: string;\n readonly timestamp?: string;\n readonly severity?: SeverityName;\n readonly severity_level?: SeverityLevel;\n readonly correlation_id?: string;\n readonly trace_id?: string;\n readonly exit_code?: number;\n readonly context?: Record<string, unknown>;\n readonly original?: string | object;\n}\n\n/**\n * Safely serialize any error-like value to FulmenErrorData structure\n *\n * Handles native Error objects, plain objects, strings, and unknown types.\n *\n * @param error - Error value to serialize\n * @param code - Optional error code (defaults to 'UNKNOWN_ERROR')\n * @param severity - Optional severity (defaults to 'medium')\n * @returns Structured error data\n *\n * @example\n * ```typescript\n * try {\n * throw new Error('Something failed');\n * } catch (err) {\n * const data = serializeError(err, 'OPERATION_FAILED', 'high');\n * console.log(JSON.stringify(data));\n * }\n * ```\n */\nexport function serializeError(\n error: unknown,\n code = \"UNKNOWN_ERROR\",\n severity: SeverityName = Severity.MEDIUM,\n): FulmenErrorData {\n // Handle Error instances\n if (error instanceof Error) {\n return {\n code,\n message: error.message,\n severity,\n timestamp: new Date().toISOString(),\n context: {\n name: error.name,\n stack: error.stack,\n },\n original: error.stack || error.message,\n };\n }\n\n // Handle plain objects with message\n if (isErrorLike(error)) {\n return {\n code,\n message: error.message,\n severity,\n timestamp: new Date().toISOString(),\n details: error.details,\n context: error.context,\n original: JSON.stringify(error),\n };\n }\n\n // Handle strings\n if (typeof error === \"string\") {\n return {\n code,\n message: error,\n severity,\n timestamp: new Date().toISOString(),\n };\n }\n\n // Handle everything else\n return {\n code,\n message: String(error),\n severity,\n timestamp: new Date().toISOString(),\n original: typeof error === \"object\" ? JSON.stringify(error) : String(error),\n };\n}\n\n/**\n * Extract error message from unknown error value\n *\n * @param error - Error value\n * @returns Error message string\n */\nexport function extractErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (isErrorLike(error)) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n return String(error);\n}\n\n/**\n * Extract stack trace from error if available\n *\n * @param error - Error value\n * @returns Stack trace string or undefined\n */\nexport function extractStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.stack;\n }\n if (isErrorLike(error) && typeof error.stack === \"string\") {\n return error.stack;\n }\n return undefined;\n}\n\n/**\n * Type guard for error-like objects\n */\nfunction isErrorLike(value: unknown): value is {\n message: string;\n stack?: string;\n details?: Record<string, unknown>;\n context?: Record<string, unknown>;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"message\" in value &&\n typeof (value as { message: unknown }).message === \"string\"\n );\n}\n","/**\n * Schema validation for FulmenError data\n *\n * Provides singleton validator that pre-compiles error-response schema\n * using existing src/schema infrastructure. Performance target: <1ms per validation.\n */\n\nimport { compileSchemaById } from \"../schema/index.js\";\nimport type { CompiledValidator } from \"../schema/types.js\";\n\n/**\n * Singleton validator for FulmenError data\n *\n * Pre-compiles the error-response schema at first access for optimal performance.\n * Reuses existing AJV setup from src/schema module.\n */\nclass ErrorValidator {\n private static instance: ErrorValidator;\n private validateFn: CompiledValidator | null = null;\n private initPromise: Promise<void> | null = null;\n private initError: Error | null = null;\n\n private constructor() {\n // Private constructor for singleton\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): ErrorValidator {\n if (!ErrorValidator.instance) {\n ErrorValidator.instance = new ErrorValidator();\n }\n return ErrorValidator.instance;\n }\n\n /**\n * Initialize validator (lazy load, async)\n */\n private async init(): Promise<void> {\n if (this.validateFn !== null || this.initError !== null) {\n return; // Already initialized\n }\n\n if (this.initPromise) {\n return this.initPromise; // Already initializing\n }\n\n this.initPromise = (async () => {\n try {\n // Ensure dependency schemas are registered before compiling error-response\n // Error handling schema references pathfinder error-response relatively.\n await compileSchemaById(\"pathfinder/v1.0.0/error-response\");\n await compileSchemaById(\"assessment/v1.0.0/severity-definitions\");\n\n // Compile schema using existing schema infrastructure\n // Schema ID for error-response extends pathfinder error-response\n this.validateFn = await compileSchemaById(\"error-handling/v1.0.0/error-response\");\n } catch (err) {\n this.initError = err instanceof Error ? err : new Error(String(err));\n throw new Error(`Failed to initialize error validator: ${this.initError.message}`);\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Validate error data against schema\n *\n * @param data - Data to validate\n * @returns Promise resolving to true if valid, false otherwise\n * @throws {Error} If validator failed to initialize\n */\n async validate(data: unknown): Promise<boolean> {\n if (this.validateFn === null) {\n await this.init();\n }\n\n if (this.initError) {\n throw this.initError;\n }\n\n if (!this.validateFn) {\n throw new Error(\"Validator not initialized\");\n }\n\n return this.validateFn(data);\n }\n\n /**\n * Get validation errors from last validation\n *\n * @returns Validation errors or null\n */\n getErrors() {\n if (!this.validateFn) {\n return null;\n }\n return this.validateFn.errors;\n }\n\n /**\n * Reset validator state (for testing)\n * @internal\n */\n static _reset(): void {\n ErrorValidator.instance = new ErrorValidator();\n }\n}\n\n/**\n * Validate FulmenError data against error-response schema\n *\n * Uses pre-compiled validator singleton for optimal performance (<1ms target).\n *\n * @param data - Error data to validate\n * @returns Promise resolving to true if valid, false otherwise\n *\n * @example\n * ```typescript\n * const data = {\n * code: 'CONFIG_INVALID',\n * message: 'Configuration validation failed'\n * };\n *\n * if (await validateErrorData(data)) {\n * // Data is schema-compliant\n * } else {\n * const errors = await getValidationErrors();\n * console.error('Validation failed:', errors);\n * }\n * ```\n */\nexport async function validateErrorData(data: unknown): Promise<boolean> {\n return ErrorValidator.getInstance().validate(data);\n}\n\n/**\n * Get validation errors from last validation\n *\n * @returns Validation errors or null\n *\n * @example\n * ```typescript\n * if (!(await validateErrorData(data))) {\n * const errors = getValidationErrors();\n * errors?.forEach(err => {\n * console.error(`${err.instancePath}: ${err.message}`);\n * });\n * }\n * ```\n */\nexport function getValidationErrors() {\n return ErrorValidator.getInstance().getErrors();\n}\n\n/**\n * Format validation errors as human-readable string\n *\n * @param errors - Validation error objects\n * @returns Formatted error message\n *\n * @example\n * ```typescript\n * const errors = getValidationErrors();\n * if (errors) {\n * throw new Error(formatValidationErrors(errors));\n * }\n * ```\n */\nexport function formatValidationErrors(\n errors: Array<{ instancePath?: string; message?: string }>,\n): string {\n return errors\n .map((err) => {\n const path = err.instancePath || \"(root)\";\n const message = err.message || \"validation failed\";\n return `${path}: ${message}`;\n })\n .join(\"; \");\n}\n\n/**\n * Validate and throw if invalid\n *\n * @param data - Error data to validate\n * @throws {Error} If validation fails\n *\n * @example\n * ```typescript\n * await assertValidErrorData(data); // Throws if invalid\n * // Safe to use data here\n * ```\n */\nexport async function assertValidErrorData(data: unknown): Promise<void> {\n if (!(await validateErrorData(data))) {\n const errors = getValidationErrors();\n const message = errors ? formatValidationErrors(errors) : \"Error data validation failed\";\n throw new Error(`Invalid error data: ${message}`);\n }\n}\n\n// Export for testing\nexport { ErrorValidator };\n","/**\n * FulmenError - Structured error data model for observability\n *\n * Implements ADR-0006 error data model extending Pathfinder error-response\n * with optional telemetry metadata (severity, correlation_id, trace_id, etc.)\n */\n\nimport { extractErrorMessage, extractStackTrace, type FulmenErrorData } from \"./serialization.js\";\nimport type { SeverityLevel, SeverityName } from \"./severity.js\";\nimport { getDefaultSeverity, SEVERITY_LEVELS, Severity } from \"./severity.js\";\nimport { validateErrorData } from \"./validators.js\";\n\n// Re-export FulmenErrorData from serialization\nexport type { FulmenErrorData } from \"./serialization.js\";\n\n/**\n * Options for creating/wrapping FulmenError\n */\nexport interface FulmenErrorOptions {\n code?: string;\n severity?: SeverityName;\n correlation_id?: string;\n trace_id?: string;\n exit_code?: number;\n context?: Record<string, unknown>;\n details?: Record<string, unknown>;\n path?: string;\n}\n\n/**\n * FulmenError class - wraps structured error data with helper methods\n *\n * Implements ADR-0006 canonical data model pattern:\n * - Data stored in immutable FulmenErrorData interface\n * - Class provides ergonomic API and methods\n * - Extends native Error for stack traces and instanceof checks\n */\nexport class FulmenError extends Error {\n readonly data: FulmenErrorData;\n\n constructor(data: FulmenErrorData) {\n super(data.message);\n this.name = \"FulmenError\";\n\n // Freeze data for immutability\n this.data = Object.freeze({ ...data });\n\n // Capture stack trace\n Error.captureStackTrace(this, FulmenError);\n }\n\n /**\n * Serialize to JSON (schema-compliant)\n */\n toJSON(): FulmenErrorData {\n return this.data;\n }\n\n /**\n * Check equality with another FulmenError\n */\n equals(other: FulmenError): boolean {\n return JSON.stringify(this.data) === JSON.stringify(other.data);\n }\n\n /**\n * Get severity level for comparison\n */\n getSeverityLevel(): SeverityLevel {\n return this.data.severity_level ?? SEVERITY_LEVELS[this.data.severity ?? \"medium\"];\n }\n\n /**\n * Wrap an existing error with FulmenError structure\n *\n * @param error - Error to wrap (Error instance or FulmenErrorData)\n * @param options - Additional error options\n * @returns New FulmenError instance\n *\n * @example\n * ```typescript\n * try {\n * throw new Error('Config invalid');\n * } catch (err) {\n * const fulmenErr = FulmenError.wrap(err, {\n * code: 'CONFIG_INVALID',\n * severity: 'high',\n * exit_code: 2\n * });\n * throw fulmenErr;\n * }\n * ```\n */\n static wrap(error: Error | FulmenErrorData, options: FulmenErrorOptions = {}): FulmenError {\n // If already FulmenError, merge options with recomputed derived fields\n if (error instanceof FulmenError) {\n // Determine effective severity (prefer options, fallback to existing, default to medium)\n const effectiveSeverity = options.severity ?? error.data.severity ?? Severity.MEDIUM;\n // CRITICAL: Recompute severity_level from severity to maintain consistency (ADR-0006)\n const effectiveSeverityLevel = SEVERITY_LEVELS[effectiveSeverity];\n\n // Update timestamp when re-wrapping (indicates new error context)\n const timestamp = new Date().toISOString();\n\n return new FulmenError({\n ...error.data,\n ...options,\n code: options.code ?? error.data.code,\n message: error.data.message,\n severity: effectiveSeverity, // Consistent severity\n severity_level: effectiveSeverityLevel, // Recomputed level\n timestamp, // Updated timestamp\n });\n }\n\n // If FulmenErrorData, recompute derived fields\n if (isFulmenErrorData(error)) {\n const defaultSeverity = getDefaultSeverity();\n // Prefer options.severity, fall back to error.severity, default to medium\n const effectiveSeverity = options.severity ?? error.severity ?? defaultSeverity.name;\n // CRITICAL: Always recompute severity_level from severity (never trust provided level)\n const effectiveSeverityLevel = SEVERITY_LEVELS[effectiveSeverity];\n\n return new FulmenError({\n ...error,\n ...options,\n severity: effectiveSeverity,\n severity_level: effectiveSeverityLevel, // Recomputed, not from error.severity_level\n timestamp: error.timestamp ?? new Date().toISOString(),\n });\n }\n\n // Wrap native Error\n return FulmenError.fromError(error, options);\n }\n\n /**\n * Create FulmenError from native Error object\n *\n * @param err - Native Error instance\n * @param options - Error options\n * @returns New FulmenError instance\n *\n * @example\n * ```typescript\n * const err = new TypeError('Invalid type');\n * const fulmenErr = FulmenError.fromError(err, {\n * code: 'TYPE_ERROR',\n * severity: 'medium'\n * });\n * ```\n */\n static fromError(err: Error | unknown, options: FulmenErrorOptions = {}): FulmenError {\n const code = options.code ?? \"UNKNOWN_ERROR\";\n const severity = options.severity ?? Severity.MEDIUM;\n const severityLevel = SEVERITY_LEVELS[severity];\n\n const message = extractErrorMessage(err);\n const stack = extractStackTrace(err);\n\n const data: FulmenErrorData = {\n code,\n message,\n severity,\n severity_level: severityLevel,\n timestamp: new Date().toISOString(),\n ...options,\n context: {\n ...options.context,\n originalName: err instanceof Error ? err.name : typeof err,\n stack,\n },\n original: stack || message,\n };\n\n return new FulmenError(data);\n }\n\n /**\n * Validate error data against schema\n *\n * @param data - Error data to validate\n * @returns Promise resolving to true if valid\n *\n * @example\n * ```typescript\n * const data = { code: 'TEST', message: 'Test error' };\n * if (await FulmenError.validate(data)) {\n * const err = new FulmenError(data);\n * }\n * ```\n */\n static async validate(data: unknown): Promise<boolean> {\n return validateErrorData(data);\n }\n\n /**\n * Exit process with structured error\n *\n * Logs error as JSON and exits with specified exit code.\n * Mockable for testing (override process.exit).\n *\n * @param error - FulmenError instance\n * @param options - Exit options\n *\n * @example\n * ```typescript\n * const err = FulmenError.fromError(new Error('Fatal'), {\n * code: 'FATAL_ERROR',\n * exit_code: 1\n * });\n * FulmenError.exitWithError(err); // Exits with code 1\n * ```\n */\n static exitWithError(\n error: FulmenError,\n options: { logger?: (msg: string) => void } = {},\n ): never {\n const logger = options.logger ?? console.error;\n const exitCode = error.data.exit_code ?? 1;\n\n // Log structured error\n logger(JSON.stringify(error.toJSON(), null, 2));\n\n // Exit with code\n process.exit(exitCode);\n }\n}\n\n/**\n * Type guard to check if value is FulmenError instance\n *\n * @param value - Value to check\n * @returns True if value is FulmenError\n */\nexport function isFulmenError(value: unknown): value is FulmenError {\n return value instanceof FulmenError;\n}\n\n/**\n * Type guard to check if value is FulmenErrorData\n *\n * @param value - Value to check\n * @returns True if value is FulmenErrorData\n */\nexport function isFulmenErrorData(value: unknown): value is FulmenErrorData {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"code\" in value &&\n typeof (value as FulmenErrorData).code === \"string\" &&\n \"message\" in value &&\n typeof (value as FulmenErrorData).message === \"string\"\n );\n}\n","/**\n * Errors module - structured error handling with telemetry\n *\n * Provides FulmenError data model and utilities for schema-backed error responses\n * with optional telemetry metadata (severity, correlation IDs, exit codes).\n */\n\nexport const VERSION = \"0.2.0\";\n\n// Correlation ID utilities\nexport {\n generateCorrelationId,\n isCorrelationId,\n isValidCorrelationId,\n normalizeCorrelationId,\n} from \"./correlation.js\";\n// Core error class and types\nexport {\n FulmenError,\n type FulmenErrorData,\n type FulmenErrorOptions,\n isFulmenError,\n isFulmenErrorData,\n} from \"./fulmen-error.js\";\n// Serialization utilities\nexport {\n extractErrorMessage,\n extractStackTrace,\n serializeError,\n} from \"./serialization.js\";\n// Severity utilities\nexport {\n compareSeverity,\n getDefaultSeverity,\n isSeverityLevel,\n isSeverityName,\n LEVEL_TO_SEVERITY,\n levelToSeverity,\n SEVERITY_LEVELS,\n Severity,\n type SeverityLevel,\n type SeverityName,\n severityToLevel,\n} from \"./severity.js\";\n// Validation utilities\nexport {\n assertValidErrorData,\n formatValidationErrors,\n getValidationErrors,\n validateErrorData,\n} from \"./validators.js\";\n"]}
1
+ {"version":3,"sources":["../src/errors/correlation.ts","../src/errors/severity.ts","../src/errors/serialization.ts","../src/errors/validators.ts","../src/errors/fulmen-error.ts","../src/errors/index.ts"],"names":[],"mappings":"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","file":"chunk-GOTEQYAD.js","sourcesContent":["/**\n * Correlation ID generation and validation for error tracking\n *\n * Provides UUID v4 generation for correlation IDs used in observability\n * and distributed tracing scenarios.\n */\n\nimport { randomUUID } from \"node:crypto\";\n\n/**\n * UUID v4 regex pattern for validation\n */\nconst UUID_V4_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * Generate a new correlation ID (UUID v4)\n *\n * Uses Node.js crypto.randomUUID() for cryptographically strong random values.\n *\n * @returns UUID v4 string (e.g., \"550e8400-e29b-41d4-a716-446655440000\")\n *\n * @example\n * ```typescript\n * const correlationId = generateCorrelationId();\n * // \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function generateCorrelationId(): string {\n return randomUUID();\n}\n\n/**\n * Validate if a string is a valid UUID v4 correlation ID\n *\n * Checks format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n * where y is one of [8, 9, a, b]\n *\n * @param id - String to validate\n * @returns True if valid UUID v4 format\n *\n * @example\n * ```typescript\n * isValidCorrelationId('550e8400-e29b-41d4-a716-446655440000') // true\n * isValidCorrelationId('not-a-uuid') // false\n * isValidCorrelationId('550e8400-e29b-31d4-a716-446655440000') // false (version 3, not 4)\n * ```\n */\nexport function isValidCorrelationId(id: string): boolean {\n return UUID_V4_PATTERN.test(id);\n}\n\n/**\n * Normalize a correlation ID (lowercase, trim whitespace)\n *\n * @param id - Correlation ID to normalize\n * @returns Normalized correlation ID\n *\n * @example\n * ```typescript\n * normalizeCorrelationId(' 550E8400-E29B-41D4-A716-446655440000 ')\n * // \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function normalizeCorrelationId(id: string): string {\n return id.trim().toLowerCase();\n}\n\n/**\n * Type guard to check if a value is a valid correlation ID\n *\n * @param value - Value to check\n * @returns True if value is a string and valid UUID v4\n *\n * @example\n * ```typescript\n * if (isCorrelationId(value)) {\n * // TypeScript knows value is string here\n * const normalized = normalizeCorrelationId(value);\n * }\n * ```\n */\nexport function isCorrelationId(value: unknown): value is string {\n return typeof value === \"string\" && isValidCorrelationId(value);\n}\n","/**\n * Severity mappings for error handling\n *\n * Implements severity levels from assessment/v1.0.0/severity-definitions schema\n * Provides bidirectional mapping between severity names and numeric levels\n */\n\n/**\n * Severity names aligned with assessment taxonomy\n */\nexport const Severity = {\n INFO: \"info\",\n LOW: \"low\",\n MEDIUM: \"medium\",\n HIGH: \"high\",\n CRITICAL: \"critical\",\n} as const;\n\n/**\n * Severity name type (string literal union)\n */\nexport type SeverityName = (typeof Severity)[keyof typeof Severity];\n\n/**\n * Numeric severity level for sorting and comparison\n * info=0, low=1, medium=2, high=3, critical=4\n */\nexport type SeverityLevel = 0 | 1 | 2 | 3 | 4;\n\n/**\n * Canonical severity level mapping (name → level)\n * Aligned with schemas/crucible-ts/assessment/v1.0.0/severity-definitions.schema.json\n */\nexport const SEVERITY_LEVELS: Record<SeverityName, SeverityLevel> = {\n info: 0,\n low: 1,\n medium: 2,\n high: 3,\n critical: 4,\n};\n\n/**\n * Reverse mapping (level → name)\n */\nexport const LEVEL_TO_SEVERITY: Record<SeverityLevel, SeverityName> = {\n 0: \"info\",\n 1: \"low\",\n 2: \"medium\",\n 3: \"high\",\n 4: \"critical\",\n};\n\n/**\n * Convert severity name to numeric level\n *\n * @param name - Severity name (info, low, medium, high, critical)\n * @returns Numeric severity level (0-4)\n * @throws {Error} If severity name is invalid\n *\n * @example\n * ```typescript\n * severityToLevel('high') // returns 3\n * severityToLevel('info') // returns 0\n * ```\n */\nexport function severityToLevel(name: string): SeverityLevel {\n if (!isSeverityName(name)) {\n throw new Error(\n `Invalid severity name: \"${name}\". Must be one of: ${Object.values(Severity).join(\", \")}`,\n );\n }\n return SEVERITY_LEVELS[name];\n}\n\n/**\n * Convert numeric level to severity name\n *\n * @param level - Numeric severity level (0-4)\n * @returns Severity name\n * @throws {Error} If level is invalid\n *\n * @example\n * ```typescript\n * levelToSeverity(3) // returns 'high'\n * levelToSeverity(0) // returns 'info'\n * ```\n */\nexport function levelToSeverity(level: number): SeverityName {\n if (!isSeverityLevel(level)) {\n throw new Error(`Invalid severity level: ${level}. Must be 0-4`);\n }\n return LEVEL_TO_SEVERITY[level];\n}\n\n/**\n * Type guard to check if a value is a valid severity name\n *\n * @param value - Value to check\n * @returns True if value is a valid SeverityName\n *\n * @example\n * ```typescript\n * if (isSeverityName(value)) {\n * const level = severityToLevel(value); // Type-safe\n * }\n * ```\n */\nexport function isSeverityName(value: unknown): value is SeverityName {\n return typeof value === \"string\" && Object.values(Severity).includes(value as SeverityName);\n}\n\n/**\n * Type guard to check if a value is a valid severity level\n *\n * @param value - Value to check\n * @returns True if value is a valid SeverityLevel\n *\n * @example\n * ```typescript\n * if (isSeverityLevel(value)) {\n * const name = levelToSeverity(value); // Type-safe\n * }\n * ```\n */\nexport function isSeverityLevel(value: unknown): value is SeverityLevel {\n return typeof value === \"number\" && value >= 0 && value <= 4 && Number.isInteger(value);\n}\n\n/**\n * Get default severity (medium/2) when not specified\n *\n * @returns Default severity name and level\n */\nexport function getDefaultSeverity(): {\n name: SeverityName;\n level: SeverityLevel;\n} {\n return {\n name: Severity.MEDIUM,\n level: 2,\n };\n}\n\n/**\n * Compare two severity levels\n *\n * @param a - First severity (name or level)\n * @param b - Second severity (name or level)\n * @returns Negative if a < b, positive if a > b, zero if equal\n *\n * @example\n * ```typescript\n * compareSeverity('high', 'low') // returns positive (high > low)\n * compareSeverity(2, 'critical') // returns negative (medium < critical)\n * ```\n */\nexport function compareSeverity(\n a: SeverityName | SeverityLevel,\n b: SeverityName | SeverityLevel,\n): number {\n const levelA = typeof a === \"string\" ? severityToLevel(a) : a;\n const levelB = typeof b === \"string\" ? severityToLevel(b) : b;\n return levelA - levelB;\n}\n","/**\n * Error serialization utilities\n *\n * Provides safe serialization of Error objects and unknown errors to structured data\n */\n\nimport { Severity, type SeverityLevel, type SeverityName } from \"./severity.js\";\n\n/**\n * FulmenError data structure (for serialization)\n * Defined here to avoid circular dependency\n */\nexport interface FulmenErrorData {\n readonly code: string;\n readonly message: string;\n readonly details?: Record<string, unknown>;\n readonly path?: string;\n readonly timestamp?: string;\n readonly severity?: SeverityName;\n readonly severity_level?: SeverityLevel;\n readonly correlation_id?: string;\n readonly trace_id?: string;\n readonly exit_code?: number;\n readonly context?: Record<string, unknown>;\n readonly original?: string | object;\n}\n\n/**\n * Safely serialize any error-like value to FulmenErrorData structure\n *\n * Handles native Error objects, plain objects, strings, and unknown types.\n *\n * @param error - Error value to serialize\n * @param code - Optional error code (defaults to 'UNKNOWN_ERROR')\n * @param severity - Optional severity (defaults to 'medium')\n * @returns Structured error data\n *\n * @example\n * ```typescript\n * try {\n * throw new Error('Something failed');\n * } catch (err) {\n * const data = serializeError(err, 'OPERATION_FAILED', 'high');\n * console.log(JSON.stringify(data));\n * }\n * ```\n */\nexport function serializeError(\n error: unknown,\n code = \"UNKNOWN_ERROR\",\n severity: SeverityName = Severity.MEDIUM,\n): FulmenErrorData {\n // Handle Error instances\n if (error instanceof Error) {\n return {\n code,\n message: error.message,\n severity,\n timestamp: new Date().toISOString(),\n context: {\n name: error.name,\n stack: error.stack,\n },\n original: error.stack || error.message,\n };\n }\n\n // Handle plain objects with message\n if (isErrorLike(error)) {\n return {\n code,\n message: error.message,\n severity,\n timestamp: new Date().toISOString(),\n details: error.details,\n context: error.context,\n original: JSON.stringify(error),\n };\n }\n\n // Handle strings\n if (typeof error === \"string\") {\n return {\n code,\n message: error,\n severity,\n timestamp: new Date().toISOString(),\n };\n }\n\n // Handle everything else\n return {\n code,\n message: String(error),\n severity,\n timestamp: new Date().toISOString(),\n original: typeof error === \"object\" ? JSON.stringify(error) : String(error),\n };\n}\n\n/**\n * Extract error message from unknown error value\n *\n * @param error - Error value\n * @returns Error message string\n */\nexport function extractErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (isErrorLike(error)) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n return String(error);\n}\n\n/**\n * Extract stack trace from error if available\n *\n * @param error - Error value\n * @returns Stack trace string or undefined\n */\nexport function extractStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.stack;\n }\n if (isErrorLike(error) && typeof error.stack === \"string\") {\n return error.stack;\n }\n return undefined;\n}\n\n/**\n * Type guard for error-like objects\n */\nfunction isErrorLike(value: unknown): value is {\n message: string;\n stack?: string;\n details?: Record<string, unknown>;\n context?: Record<string, unknown>;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"message\" in value &&\n typeof (value as { message: unknown }).message === \"string\"\n );\n}\n","/**\n * Schema validation for FulmenError data\n *\n * Provides singleton validator that pre-compiles error-response schema\n * using existing src/schema infrastructure. Performance target: <1ms per validation.\n */\n\nimport { compileSchemaById } from \"../schema/index.js\";\nimport type { CompiledValidator } from \"../schema/types.js\";\n\n/**\n * Singleton validator for FulmenError data\n *\n * Pre-compiles the error-response schema at first access for optimal performance.\n * Reuses existing AJV setup from src/schema module.\n */\nclass ErrorValidator {\n private static instance: ErrorValidator;\n private validateFn: CompiledValidator | null = null;\n private initPromise: Promise<void> | null = null;\n private initError: Error | null = null;\n\n private constructor() {\n // Private constructor for singleton\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): ErrorValidator {\n if (!ErrorValidator.instance) {\n ErrorValidator.instance = new ErrorValidator();\n }\n return ErrorValidator.instance;\n }\n\n /**\n * Initialize validator (lazy load, async)\n */\n private async init(): Promise<void> {\n if (this.validateFn !== null || this.initError !== null) {\n return; // Already initialized\n }\n\n if (this.initPromise) {\n return this.initPromise; // Already initializing\n }\n\n this.initPromise = (async () => {\n try {\n // Ensure dependency schemas are registered before compiling error-response\n // Error handling schema references pathfinder error-response relatively.\n await compileSchemaById(\"pathfinder/v1.0.0/error-response\");\n await compileSchemaById(\"assessment/v1.0.0/severity-definitions\");\n\n // Compile schema using existing schema infrastructure\n // Schema ID for error-response extends pathfinder error-response\n this.validateFn = await compileSchemaById(\"error-handling/v1.0.0/error-response\");\n } catch (err) {\n this.initError = err instanceof Error ? err : new Error(String(err));\n throw new Error(`Failed to initialize error validator: ${this.initError.message}`);\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Validate error data against schema\n *\n * @param data - Data to validate\n * @returns Promise resolving to true if valid, false otherwise\n * @throws {Error} If validator failed to initialize\n */\n async validate(data: unknown): Promise<boolean> {\n if (this.validateFn === null) {\n await this.init();\n }\n\n if (this.initError) {\n throw this.initError;\n }\n\n if (!this.validateFn) {\n throw new Error(\"Validator not initialized\");\n }\n\n return this.validateFn(data);\n }\n\n /**\n * Get validation errors from last validation\n *\n * @returns Validation errors or null\n */\n getErrors() {\n if (!this.validateFn) {\n return null;\n }\n return this.validateFn.errors;\n }\n\n /**\n * Reset validator state (for testing)\n * @internal\n */\n static _reset(): void {\n ErrorValidator.instance = new ErrorValidator();\n }\n}\n\n/**\n * Validate FulmenError data against error-response schema\n *\n * Uses pre-compiled validator singleton for optimal performance (<1ms target).\n *\n * @param data - Error data to validate\n * @returns Promise resolving to true if valid, false otherwise\n *\n * @example\n * ```typescript\n * const data = {\n * code: 'CONFIG_INVALID',\n * message: 'Configuration validation failed'\n * };\n *\n * if (await validateErrorData(data)) {\n * // Data is schema-compliant\n * } else {\n * const errors = await getValidationErrors();\n * console.error('Validation failed:', errors);\n * }\n * ```\n */\nexport async function validateErrorData(data: unknown): Promise<boolean> {\n return ErrorValidator.getInstance().validate(data);\n}\n\n/**\n * Get validation errors from last validation\n *\n * @returns Validation errors or null\n *\n * @example\n * ```typescript\n * if (!(await validateErrorData(data))) {\n * const errors = getValidationErrors();\n * errors?.forEach(err => {\n * console.error(`${err.instancePath}: ${err.message}`);\n * });\n * }\n * ```\n */\nexport function getValidationErrors() {\n return ErrorValidator.getInstance().getErrors();\n}\n\n/**\n * Format validation errors as human-readable string\n *\n * @param errors - Validation error objects\n * @returns Formatted error message\n *\n * @example\n * ```typescript\n * const errors = getValidationErrors();\n * if (errors) {\n * throw new Error(formatValidationErrors(errors));\n * }\n * ```\n */\nexport function formatValidationErrors(\n errors: Array<{ instancePath?: string; message?: string }>,\n): string {\n return errors\n .map((err) => {\n const path = err.instancePath || \"(root)\";\n const message = err.message || \"validation failed\";\n return `${path}: ${message}`;\n })\n .join(\"; \");\n}\n\n/**\n * Validate and throw if invalid\n *\n * @param data - Error data to validate\n * @throws {Error} If validation fails\n *\n * @example\n * ```typescript\n * await assertValidErrorData(data); // Throws if invalid\n * // Safe to use data here\n * ```\n */\nexport async function assertValidErrorData(data: unknown): Promise<void> {\n if (!(await validateErrorData(data))) {\n const errors = getValidationErrors();\n const message = errors ? formatValidationErrors(errors) : \"Error data validation failed\";\n throw new Error(`Invalid error data: ${message}`);\n }\n}\n\n// Export for testing\nexport { ErrorValidator };\n","/**\n * FulmenError - Structured error data model for observability\n *\n * Implements ADR-0006 error data model extending Pathfinder error-response\n * with optional telemetry metadata (severity, correlation_id, trace_id, etc.)\n */\n\nimport { extractErrorMessage, extractStackTrace, type FulmenErrorData } from \"./serialization.js\";\nimport type { SeverityLevel, SeverityName } from \"./severity.js\";\nimport { getDefaultSeverity, SEVERITY_LEVELS, Severity } from \"./severity.js\";\nimport { validateErrorData } from \"./validators.js\";\n\n// Re-export FulmenErrorData from serialization\nexport type { FulmenErrorData } from \"./serialization.js\";\n\n/**\n * Options for creating/wrapping FulmenError\n */\nexport interface FulmenErrorOptions {\n code?: string;\n severity?: SeverityName;\n correlation_id?: string;\n trace_id?: string;\n exit_code?: number;\n context?: Record<string, unknown>;\n details?: Record<string, unknown>;\n path?: string;\n}\n\n/**\n * FulmenError class - wraps structured error data with helper methods\n *\n * Implements ADR-0006 canonical data model pattern:\n * - Data stored in immutable FulmenErrorData interface\n * - Class provides ergonomic API and methods\n * - Extends native Error for stack traces and instanceof checks\n */\nexport class FulmenError extends Error {\n readonly data: FulmenErrorData;\n\n constructor(data: FulmenErrorData) {\n super(data.message);\n this.name = \"FulmenError\";\n\n // Freeze data for immutability\n this.data = Object.freeze({ ...data });\n\n // Capture stack trace\n Error.captureStackTrace(this, FulmenError);\n }\n\n /**\n * Serialize to JSON (schema-compliant)\n */\n toJSON(): FulmenErrorData {\n return this.data;\n }\n\n /**\n * Check equality with another FulmenError\n */\n equals(other: FulmenError): boolean {\n return JSON.stringify(this.data) === JSON.stringify(other.data);\n }\n\n /**\n * Get severity level for comparison\n */\n getSeverityLevel(): SeverityLevel {\n return this.data.severity_level ?? SEVERITY_LEVELS[this.data.severity ?? \"medium\"];\n }\n\n /**\n * Wrap an existing error with FulmenError structure\n *\n * @param error - Error to wrap (Error instance or FulmenErrorData)\n * @param options - Additional error options\n * @returns New FulmenError instance\n *\n * @example\n * ```typescript\n * try {\n * throw new Error('Config invalid');\n * } catch (err) {\n * const fulmenErr = FulmenError.wrap(err, {\n * code: 'CONFIG_INVALID',\n * severity: 'high',\n * exit_code: 2\n * });\n * throw fulmenErr;\n * }\n * ```\n */\n static wrap(error: Error | FulmenErrorData, options: FulmenErrorOptions = {}): FulmenError {\n // If already FulmenError, merge options with recomputed derived fields\n if (error instanceof FulmenError) {\n // Determine effective severity (prefer options, fallback to existing, default to medium)\n const effectiveSeverity = options.severity ?? error.data.severity ?? Severity.MEDIUM;\n // CRITICAL: Recompute severity_level from severity to maintain consistency (ADR-0006)\n const effectiveSeverityLevel = SEVERITY_LEVELS[effectiveSeverity];\n\n // Update timestamp when re-wrapping (indicates new error context)\n const timestamp = new Date().toISOString();\n\n return new FulmenError({\n ...error.data,\n ...options,\n code: options.code ?? error.data.code,\n message: error.data.message,\n severity: effectiveSeverity, // Consistent severity\n severity_level: effectiveSeverityLevel, // Recomputed level\n timestamp, // Updated timestamp\n });\n }\n\n // If FulmenErrorData, recompute derived fields\n if (isFulmenErrorData(error)) {\n const defaultSeverity = getDefaultSeverity();\n // Prefer options.severity, fall back to error.severity, default to medium\n const effectiveSeverity = options.severity ?? error.severity ?? defaultSeverity.name;\n // CRITICAL: Always recompute severity_level from severity (never trust provided level)\n const effectiveSeverityLevel = SEVERITY_LEVELS[effectiveSeverity];\n\n return new FulmenError({\n ...error,\n ...options,\n severity: effectiveSeverity,\n severity_level: effectiveSeverityLevel, // Recomputed, not from error.severity_level\n timestamp: error.timestamp ?? new Date().toISOString(),\n });\n }\n\n // Wrap native Error\n return FulmenError.fromError(error, options);\n }\n\n /**\n * Create FulmenError from native Error object\n *\n * @param err - Native Error instance\n * @param options - Error options\n * @returns New FulmenError instance\n *\n * @example\n * ```typescript\n * const err = new TypeError('Invalid type');\n * const fulmenErr = FulmenError.fromError(err, {\n * code: 'TYPE_ERROR',\n * severity: 'medium'\n * });\n * ```\n */\n static fromError(err: Error | unknown, options: FulmenErrorOptions = {}): FulmenError {\n const code = options.code ?? \"UNKNOWN_ERROR\";\n const severity = options.severity ?? Severity.MEDIUM;\n const severityLevel = SEVERITY_LEVELS[severity];\n\n const message = extractErrorMessage(err);\n const stack = extractStackTrace(err);\n\n const data: FulmenErrorData = {\n code,\n message,\n severity,\n severity_level: severityLevel,\n timestamp: new Date().toISOString(),\n ...options,\n context: {\n ...options.context,\n originalName: err instanceof Error ? err.name : typeof err,\n stack,\n },\n original: stack || message,\n };\n\n return new FulmenError(data);\n }\n\n /**\n * Validate error data against schema\n *\n * @param data - Error data to validate\n * @returns Promise resolving to true if valid\n *\n * @example\n * ```typescript\n * const data = { code: 'TEST', message: 'Test error' };\n * if (await FulmenError.validate(data)) {\n * const err = new FulmenError(data);\n * }\n * ```\n */\n static async validate(data: unknown): Promise<boolean> {\n return validateErrorData(data);\n }\n\n /**\n * Exit process with structured error\n *\n * Logs error as JSON and exits with specified exit code.\n * Mockable for testing (override process.exit).\n *\n * @param error - FulmenError instance\n * @param options - Exit options\n *\n * @example\n * ```typescript\n * const err = FulmenError.fromError(new Error('Fatal'), {\n * code: 'FATAL_ERROR',\n * exit_code: 1\n * });\n * FulmenError.exitWithError(err); // Exits with code 1\n * ```\n */\n static exitWithError(\n error: FulmenError,\n options: { logger?: (msg: string) => void } = {},\n ): never {\n const logger = options.logger ?? console.error;\n const exitCode = error.data.exit_code ?? 1;\n\n // Log structured error\n logger(JSON.stringify(error.toJSON(), null, 2));\n\n // Exit with code\n process.exit(exitCode);\n }\n}\n\n/**\n * Type guard to check if value is FulmenError instance\n *\n * @param value - Value to check\n * @returns True if value is FulmenError\n */\nexport function isFulmenError(value: unknown): value is FulmenError {\n return value instanceof FulmenError;\n}\n\n/**\n * Type guard to check if value is FulmenErrorData\n *\n * @param value - Value to check\n * @returns True if value is FulmenErrorData\n */\nexport function isFulmenErrorData(value: unknown): value is FulmenErrorData {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"code\" in value &&\n typeof (value as FulmenErrorData).code === \"string\" &&\n \"message\" in value &&\n typeof (value as FulmenErrorData).message === \"string\"\n );\n}\n","/**\n * Errors module - structured error handling with telemetry\n *\n * Provides FulmenError data model and utilities for schema-backed error responses\n * with optional telemetry metadata (severity, correlation IDs, exit codes).\n */\n\nexport const VERSION = \"0.2.0\";\n\n// Correlation ID utilities\nexport {\n generateCorrelationId,\n isCorrelationId,\n isValidCorrelationId,\n normalizeCorrelationId,\n} from \"./correlation.js\";\n// Core error class and types\nexport {\n FulmenError,\n type FulmenErrorData,\n type FulmenErrorOptions,\n isFulmenError,\n isFulmenErrorData,\n} from \"./fulmen-error.js\";\n// Serialization utilities\nexport {\n extractErrorMessage,\n extractStackTrace,\n serializeError,\n} from \"./serialization.js\";\n// Severity utilities\nexport {\n compareSeverity,\n getDefaultSeverity,\n isSeverityLevel,\n isSeverityName,\n LEVEL_TO_SEVERITY,\n levelToSeverity,\n SEVERITY_LEVELS,\n Severity,\n type SeverityLevel,\n type SeverityName,\n severityToLevel,\n} from \"./severity.js\";\n// Validation utilities\nexport {\n assertValidErrorData,\n formatValidationErrors,\n getValidationErrors,\n validateErrorData,\n} from \"./validators.js\";\n"]}
@@ -1,4 +1,4 @@
1
- import { loadIdentity } from './chunk-BJDL6JEX.js';
1
+ import { loadIdentity } from './chunk-VJIGX7MH.js';
2
2
 
3
3
  // src/appidentity/helpers.ts
4
4
  async function getBinaryName(options) {
@@ -39,5 +39,5 @@ async function getEnvVar(key, options) {
39
39
  }
40
40
 
41
41
  export { buildEnvVar, getBinaryName, getConfigIdentifiers, getConfigName, getEnvPrefix, getEnvVar, getTelemetryNamespace, getVendor };
42
- //# sourceMappingURL=chunk-K7BMFGQP.js.map
43
- //# sourceMappingURL=chunk-K7BMFGQP.js.map
42
+ //# sourceMappingURL=chunk-LMNAUTW7.js.map
43
+ //# sourceMappingURL=chunk-LMNAUTW7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/appidentity/helpers.ts"],"names":[],"mappings":";;;AAwBA,eAAsB,cAAc,OAAA,EAAgD;AAClF,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,WAAA;AACtB;AAQA,eAAsB,UAAU,OAAA,EAAgD;AAC9E,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,MAAA;AACtB;AAQA,eAAsB,aAAa,OAAA,EAAgD;AACjF,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,UAAA;AACtB;AAQA,eAAsB,cAAc,OAAA,EAAgD;AAClF,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,WAAA;AACtB;AAUA,eAAsB,sBAAsB,OAAA,EAAgD;AAC1F,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,QAAA,CAAS,QAAA,EAAU,mBAAA,IAAuB,QAAA,CAAS,GAAA,CAAI,WAAA;AAChE;AAWA,eAAsB,qBACpB,OAAA,EAC4B;AAC5B,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,MAAA,EAAQ,SAAS,GAAA,CAAI,MAAA;AAAA,IACrB,UAAA,EAAY,SAAS,GAAA,CAAI;AAAA,GAC1B,CAAA;AACH;AAkBA,eAAsB,WAAA,CAAY,KAAa,OAAA,EAAgD;AAC7F,EAAA,MAAM,SAAA,GAAY,MAAM,YAAA,CAAa,OAAO,CAAA;AAE5C,EAAA,MAAM,gBAAgB,GAAA,CAAI,WAAA,EAAY,CAAE,OAAA,CAAQ,eAAe,GAAG,CAAA;AAClE,EAAA,OAAO,CAAA,EAAG,SAAS,CAAA,EAAG,aAAa,CAAA,CAAA;AACrC;AAWA,eAAsB,SAAA,CACpB,KACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,CAAY,GAAA,EAAK,OAAO,CAAA;AACjD,EAAA,OAAO,OAAA,CAAQ,IAAI,UAAU,CAAA;AAC/B","file":"chunk-K7BMFGQP.js","sourcesContent":["/**\n * Application Identity Helpers\n *\n * Convenience functions for accessing identity fields\n * All helpers use loadIdentity() under the hood for caching benefits\n */\n\nimport { loadIdentity } from \"./loader.js\";\nimport type { LoadIdentityOptions } from \"./types.js\";\n\n/**\n * Config identifiers for path construction\n */\nexport interface ConfigIdentifiers {\n readonly vendor: string;\n readonly configName: string;\n}\n\n/**\n * Get the binary name from app identity\n *\n * @param options - Load options (optional)\n * @returns Binary name (e.g., 'myapp')\n */\nexport async function getBinaryName(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.binary_name;\n}\n\n/**\n * Get the vendor namespace from app identity\n *\n * @param options - Load options (optional)\n * @returns Vendor namespace (e.g., 'acmecorp')\n */\nexport async function getVendor(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.vendor;\n}\n\n/**\n * Get the environment variable prefix from app identity\n *\n * @param options - Load options (optional)\n * @returns Env prefix (e.g., 'MYAPP_')\n */\nexport async function getEnvPrefix(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.env_prefix;\n}\n\n/**\n * Get the config directory name from app identity\n *\n * @param options - Load options (optional)\n * @returns Config name (e.g., 'myapp')\n */\nexport async function getConfigName(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.config_name;\n}\n\n/**\n * Get the telemetry namespace from app identity\n *\n * Falls back to binary_name if telemetry_namespace is not specified\n *\n * @param options - Load options (optional)\n * @returns Telemetry namespace (e.g., 'acmecorp_myapp' or 'myapp')\n */\nexport async function getTelemetryNamespace(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.metadata?.telemetry_namespace ?? identity.app.binary_name;\n}\n\n/**\n * Get config identifiers for path construction\n *\n * Returns vendor and configName for building config paths like:\n * ~/.config/{vendor}/{configName}/config.yaml\n *\n * @param options - Load options (optional)\n * @returns Frozen config identifiers { vendor, configName }\n */\nexport async function getConfigIdentifiers(\n options?: LoadIdentityOptions,\n): Promise<ConfigIdentifiers> {\n const identity = await loadIdentity(options);\n return Object.freeze({\n vendor: identity.app.vendor,\n configName: identity.app.config_name,\n });\n}\n\n/**\n * Build environment variable name with app prefix\n *\n * Constructs env var names like: MYAPP_DATABASE_URL\n * Normalizes invalid characters (anything outside [A-Z0-9_]) to underscores\n * for conventional env var naming.\n *\n * Examples:\n * - 'database-url' → 'MYAPP_DATABASE_URL'\n * - 'my.config' → 'MYAPP_MY_CONFIG'\n * - 'log_level' → 'MYAPP_LOG_LEVEL'\n *\n * @param key - Environment variable key (will be uppercased and normalized)\n * @param options - Load options (optional)\n * @returns Full environment variable name (e.g., 'MYAPP_DATABASE_URL')\n */\nexport async function buildEnvVar(key: string, options?: LoadIdentityOptions): Promise<string> {\n const envPrefix = await getEnvPrefix(options);\n // Uppercase and replace any non-alphanumeric/underscore characters with underscores\n const normalizedKey = key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n return `${envPrefix}${normalizedKey}`;\n}\n\n/**\n * Get environment variable value using app prefix\n *\n * Convenience wrapper around process.env using buildEnvVar\n *\n * @param key - Environment variable key (will be uppercased)\n * @param options - Load options (optional)\n * @returns Environment variable value or undefined\n */\nexport async function getEnvVar(\n key: string,\n options?: LoadIdentityOptions,\n): Promise<string | undefined> {\n const envVarName = await buildEnvVar(key, options);\n return process.env[envVarName];\n}\n"]}
1
+ {"version":3,"sources":["../src/appidentity/helpers.ts"],"names":[],"mappings":";;;AAwBA,eAAsB,cAAc,OAAA,EAAgD;AAClF,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,WAAA;AACtB;AAQA,eAAsB,UAAU,OAAA,EAAgD;AAC9E,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,MAAA;AACtB;AAQA,eAAsB,aAAa,OAAA,EAAgD;AACjF,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,UAAA;AACtB;AAQA,eAAsB,cAAc,OAAA,EAAgD;AAClF,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,SAAS,GAAA,CAAI,WAAA;AACtB;AAUA,eAAsB,sBAAsB,OAAA,EAAgD;AAC1F,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,QAAA,CAAS,QAAA,EAAU,mBAAA,IAAuB,QAAA,CAAS,GAAA,CAAI,WAAA;AAChE;AAWA,eAAsB,qBACpB,OAAA,EAC4B;AAC5B,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAO,CAAA;AAC3C,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,MAAA,EAAQ,SAAS,GAAA,CAAI,MAAA;AAAA,IACrB,UAAA,EAAY,SAAS,GAAA,CAAI;AAAA,GAC1B,CAAA;AACH;AAkBA,eAAsB,WAAA,CAAY,KAAa,OAAA,EAAgD;AAC7F,EAAA,MAAM,SAAA,GAAY,MAAM,YAAA,CAAa,OAAO,CAAA;AAE5C,EAAA,MAAM,gBAAgB,GAAA,CAAI,WAAA,EAAY,CAAE,OAAA,CAAQ,eAAe,GAAG,CAAA;AAClE,EAAA,OAAO,CAAA,EAAG,SAAS,CAAA,EAAG,aAAa,CAAA,CAAA;AACrC;AAWA,eAAsB,SAAA,CACpB,KACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,CAAY,GAAA,EAAK,OAAO,CAAA;AACjD,EAAA,OAAO,OAAA,CAAQ,IAAI,UAAU,CAAA;AAC/B","file":"chunk-LMNAUTW7.js","sourcesContent":["/**\n * Application Identity Helpers\n *\n * Convenience functions for accessing identity fields\n * All helpers use loadIdentity() under the hood for caching benefits\n */\n\nimport { loadIdentity } from \"./loader.js\";\nimport type { LoadIdentityOptions } from \"./types.js\";\n\n/**\n * Config identifiers for path construction\n */\nexport interface ConfigIdentifiers {\n readonly vendor: string;\n readonly configName: string;\n}\n\n/**\n * Get the binary name from app identity\n *\n * @param options - Load options (optional)\n * @returns Binary name (e.g., 'myapp')\n */\nexport async function getBinaryName(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.binary_name;\n}\n\n/**\n * Get the vendor namespace from app identity\n *\n * @param options - Load options (optional)\n * @returns Vendor namespace (e.g., 'acmecorp')\n */\nexport async function getVendor(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.vendor;\n}\n\n/**\n * Get the environment variable prefix from app identity\n *\n * @param options - Load options (optional)\n * @returns Env prefix (e.g., 'MYAPP_')\n */\nexport async function getEnvPrefix(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.env_prefix;\n}\n\n/**\n * Get the config directory name from app identity\n *\n * @param options - Load options (optional)\n * @returns Config name (e.g., 'myapp')\n */\nexport async function getConfigName(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.app.config_name;\n}\n\n/**\n * Get the telemetry namespace from app identity\n *\n * Falls back to binary_name if telemetry_namespace is not specified\n *\n * @param options - Load options (optional)\n * @returns Telemetry namespace (e.g., 'acmecorp_myapp' or 'myapp')\n */\nexport async function getTelemetryNamespace(options?: LoadIdentityOptions): Promise<string> {\n const identity = await loadIdentity(options);\n return identity.metadata?.telemetry_namespace ?? identity.app.binary_name;\n}\n\n/**\n * Get config identifiers for path construction\n *\n * Returns vendor and configName for building config paths like:\n * ~/.config/{vendor}/{configName}/config.yaml\n *\n * @param options - Load options (optional)\n * @returns Frozen config identifiers { vendor, configName }\n */\nexport async function getConfigIdentifiers(\n options?: LoadIdentityOptions,\n): Promise<ConfigIdentifiers> {\n const identity = await loadIdentity(options);\n return Object.freeze({\n vendor: identity.app.vendor,\n configName: identity.app.config_name,\n });\n}\n\n/**\n * Build environment variable name with app prefix\n *\n * Constructs env var names like: MYAPP_DATABASE_URL\n * Normalizes invalid characters (anything outside [A-Z0-9_]) to underscores\n * for conventional env var naming.\n *\n * Examples:\n * - 'database-url' → 'MYAPP_DATABASE_URL'\n * - 'my.config' → 'MYAPP_MY_CONFIG'\n * - 'log_level' → 'MYAPP_LOG_LEVEL'\n *\n * @param key - Environment variable key (will be uppercased and normalized)\n * @param options - Load options (optional)\n * @returns Full environment variable name (e.g., 'MYAPP_DATABASE_URL')\n */\nexport async function buildEnvVar(key: string, options?: LoadIdentityOptions): Promise<string> {\n const envPrefix = await getEnvPrefix(options);\n // Uppercase and replace any non-alphanumeric/underscore characters with underscores\n const normalizedKey = key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n return `${envPrefix}${normalizedKey}`;\n}\n\n/**\n * Get environment variable value using app prefix\n *\n * Convenience wrapper around process.env using buildEnvVar\n *\n * @param key - Environment variable key (will be uppercased)\n * @param options - Load options (optional)\n * @returns Environment variable value or undefined\n */\nexport async function getEnvVar(\n key: string,\n options?: LoadIdentityOptions,\n): Promise<string | undefined> {\n const envVarName = await buildEnvVar(key, options);\n return process.env[envVarName];\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { getSignal, supportsSignal, isWindows, isPOSIX } from './chunk-HIBZ2AY7.js';
1
+ import { getSignal, supportsSignal, isWindows, isPOSIX } from './chunk-24BAF63H.js';
2
2
  import { buildRuntimeInfo } from './chunk-HY6JQOFN.js';
3
3
  import { FoundryCatalogError } from './chunk-3HISR2XI.js';
4
4
 
@@ -981,5 +981,5 @@ var ConfigReloadTracker = class {
981
981
  };
982
982
 
983
983
  export { ConfigReloadTracker, SignalManager, createBearerTokenAuth, createConfigReloadEndpoint, createConfigReloadHandler, createControlDiscoveryEndpoint, createDoubleTapTracker, createSignalEndpoint, createSignalManager, createSimpleRateLimiter, ensurePOSIX, ensureSignalExitCodesSupported, ensureSupported, ensureWindows, getFallbackMetadata, getHttpFallbackGuidance, getWindowTimeRemaining, handleDoubleTap, handleWindowsFallback, isWithinWindow, onAnyShutdown, onEmergencyQuit, onReload, onShutdown, onUSR1, onUSR2, requiresFallback, resetDoubleTap };
984
- //# sourceMappingURL=chunk-HS4F3BRR.js.map
985
- //# sourceMappingURL=chunk-HS4F3BRR.js.map
984
+ //# sourceMappingURL=chunk-QGTNV4U2.js.map
985
+ //# sourceMappingURL=chunk-QGTNV4U2.js.map