@ciq-dev/neoiq-foundation-node 1.0.1-beta.2 → 1.0.1-beta.4

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.
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+
24
+ //#endregion
25
+ const __opentelemetry_sdk_node = __toESM(require("@opentelemetry/sdk-node"));
26
+ const __opentelemetry_auto_instrumentations_node = __toESM(require("@opentelemetry/auto-instrumentations-node"));
27
+ const __opentelemetry_exporter_trace_otlp_grpc = __toESM(require("@opentelemetry/exporter-trace-otlp-grpc"));
28
+ const __opentelemetry_resources = __toESM(require("@opentelemetry/resources"));
29
+ const __opentelemetry_semantic_conventions = __toESM(require("@opentelemetry/semantic-conventions"));
30
+ const __opentelemetry_api = __toESM(require("@opentelemetry/api"));
31
+ const zod = __toESM(require("zod"));
32
+
33
+ //#region src/config.ts
34
+ const AutoInstrumentationConfigSchema = zod.z.object({
35
+ http: zod.z.boolean().default(true),
36
+ fastify: zod.z.boolean().default(true),
37
+ express: zod.z.boolean().default(true),
38
+ mongodb: zod.z.boolean().default(true),
39
+ pg: zod.z.boolean().default(true),
40
+ mysql: zod.z.boolean().default(true),
41
+ redis: zod.z.boolean().default(true),
42
+ ioredis: zod.z.boolean().default(true),
43
+ grpc: zod.z.boolean().default(true),
44
+ fs: zod.z.boolean().default(false),
45
+ dns: zod.z.boolean().default(false)
46
+ }).partial();
47
+ const FeaturesConfigSchema = zod.z.object({
48
+ tracing: zod.z.boolean().default(true),
49
+ metrics: zod.z.boolean().default(true),
50
+ logging: zod.z.boolean().default(true),
51
+ autoInstrumentation: AutoInstrumentationConfigSchema.default({})
52
+ }).partial();
53
+ const DEFAULT_OTEL_ENDPOINT = "http://otel-stack-deployment-collector.observability.svc.cluster.local:4317";
54
+ const OtelConfigSchema = zod.z.object({
55
+ endpoint: zod.z.string().default(() => process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT),
56
+ metricsIntervalMs: zod.z.number().min(1e3).default(5e3)
57
+ });
58
+ const LoggingConfigSchema = zod.z.object({
59
+ level: zod.z.enum([
60
+ "debug",
61
+ "info",
62
+ "warn",
63
+ "error"
64
+ ]).default("info"),
65
+ prettyPrint: zod.z.boolean().optional()
66
+ }).partial();
67
+ const RequestLoggingConfigSchema = zod.z.object({
68
+ logHeaders: zod.z.boolean().default(true),
69
+ logBody: zod.z.boolean().default(false),
70
+ logResponseBody: zod.z.boolean().default(false),
71
+ maxBodySize: zod.z.number().default(10 * 1024),
72
+ redactHeaders: zod.z.array(zod.z.string()).optional()
73
+ }).partial();
74
+ const RedactionConfigSchema = zod.z.object({ additionalPaths: zod.z.array(zod.z.string()).default([]) }).partial();
75
+ const ShutdownConfigSchema = zod.z.object({
76
+ flushOnCrash: zod.z.boolean().default(false),
77
+ flushTimeoutMs: zod.z.number().min(100).default(5e3)
78
+ }).partial();
79
+ const FoundationConfigSchema = zod.z.object({
80
+ serviceName: zod.z.string().min(1, "serviceName is required"),
81
+ serviceVersion: zod.z.string().default(process.env.SERVICE_VERSION || "1.0.0"),
82
+ environment: zod.z.enum([
83
+ "development",
84
+ "staging",
85
+ "qa",
86
+ "production"
87
+ ]).default([
88
+ "development",
89
+ "staging",
90
+ "qa",
91
+ "production"
92
+ ].includes(process.env.NODE_ENV ?? "") ? process.env.NODE_ENV : "development"),
93
+ features: FeaturesConfigSchema.default({}),
94
+ otel: OtelConfigSchema.default({}),
95
+ logging: LoggingConfigSchema.default({}),
96
+ requestLogging: RequestLoggingConfigSchema.default({}),
97
+ redaction: RedactionConfigSchema.default({}),
98
+ shutdown: ShutdownConfigSchema.default({})
99
+ });
100
+ /** Parse and validate configuration */
101
+ function parseConfig(input) {
102
+ const result = FoundationConfigSchema.safeParse(input);
103
+ if (!result.success) {
104
+ const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
105
+ throw new Error(`Invalid foundation configuration:\n${errors}`);
106
+ }
107
+ return result.data;
108
+ }
109
+ /** Get default OTEL endpoint */
110
+ function getDefaultOtelEndpoint() {
111
+ return process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT;
112
+ }
113
+
114
+ //#endregion
115
+ //#region src/features/tracing.ts
116
+ let sdk = null;
117
+ let isInitialized = false;
118
+ const MONITORED_MODULES = [
119
+ "pg",
120
+ "mongodb",
121
+ "ioredis",
122
+ "mysql2",
123
+ "express",
124
+ "@grpc/grpc-js"
125
+ ];
126
+ function warnPreloadedModules() {
127
+ if (typeof require === "undefined" || typeof require.cache === "undefined") return;
128
+ for (const mod of MONITORED_MODULES) try {
129
+ const resolved = require.resolve(mod);
130
+ if (require.cache[resolved]) console.warn(`[neoiq-foundation] "${mod}" was imported before tracing init. Auto-instrumentation may not work for this module. Use node -r @ciq-dev/neoiq-foundation-node/bootstrap or call createFoundation() first.`);
131
+ } catch {}
132
+ }
133
+ /** Initialize OpenTelemetry tracing */
134
+ function setupTracing(options) {
135
+ if (isInitialized) {
136
+ console.warn("[neoiq-foundation] Tracing already initialized");
137
+ return;
138
+ }
139
+ warnPreloadedModules();
140
+ const { serviceName, serviceVersion, environment, endpoint = getDefaultOtelEndpoint(), autoInstrumentation = {} } = options;
141
+ const resource = (0, __opentelemetry_resources.resourceFromAttributes)({
142
+ [__opentelemetry_semantic_conventions.ATTR_SERVICE_NAME]: serviceName,
143
+ [__opentelemetry_semantic_conventions.ATTR_SERVICE_VERSION]: serviceVersion,
144
+ "deployment.environment": environment
145
+ });
146
+ const traceExporter = new __opentelemetry_exporter_trace_otlp_grpc.OTLPTraceExporter({ url: endpoint });
147
+ const instrumentationConfig = buildInstrumentationConfig(autoInstrumentation);
148
+ sdk = new __opentelemetry_sdk_node.NodeSDK({
149
+ resource,
150
+ traceExporter,
151
+ instrumentations: [(0, __opentelemetry_auto_instrumentations_node.getNodeAutoInstrumentations)(instrumentationConfig)]
152
+ });
153
+ sdk.start();
154
+ isInitialized = true;
155
+ }
156
+ function buildInstrumentationConfig(config) {
157
+ const mapping = {
158
+ http: "@opentelemetry/instrumentation-http",
159
+ fastify: "@opentelemetry/instrumentation-fastify",
160
+ express: "@opentelemetry/instrumentation-express",
161
+ mongodb: "@opentelemetry/instrumentation-mongodb",
162
+ pg: "@opentelemetry/instrumentation-pg",
163
+ mysql: "@opentelemetry/instrumentation-mysql",
164
+ redis: "@opentelemetry/instrumentation-redis",
165
+ ioredis: "@opentelemetry/instrumentation-ioredis",
166
+ grpc: "@opentelemetry/instrumentation-grpc",
167
+ fs: "@opentelemetry/instrumentation-fs",
168
+ dns: "@opentelemetry/instrumentation-dns"
169
+ };
170
+ const result = {};
171
+ for (const [key, instrumentationName] of Object.entries(mapping)) {
172
+ const userSetting = config[key];
173
+ const defaultValue = key !== "fs" && key !== "dns";
174
+ result[instrumentationName] = { enabled: userSetting ?? defaultValue };
175
+ }
176
+ return result;
177
+ }
178
+ /** Shutdown tracing gracefully */
179
+ async function shutdownTracing() {
180
+ if (!sdk) return;
181
+ try {
182
+ await sdk.shutdown();
183
+ isInitialized = false;
184
+ sdk = null;
185
+ } catch (error) {
186
+ console.error("[neoiq-foundation] Error shutting down tracing:", error);
187
+ throw error;
188
+ }
189
+ }
190
+ function getTracer(name) {
191
+ return __opentelemetry_api.trace.getTracer(name);
192
+ }
193
+ function getActiveSpan() {
194
+ return __opentelemetry_api.trace.getActiveSpan();
195
+ }
196
+ function getTraceContext() {
197
+ const span = __opentelemetry_api.trace.getActiveSpan();
198
+ if (!span) return {};
199
+ const ctx = span.spanContext();
200
+ return {
201
+ traceId: ctx.traceId,
202
+ spanId: ctx.spanId
203
+ };
204
+ }
205
+ function isTracingEnabled() {
206
+ return isInitialized;
207
+ }
208
+
209
+ //#endregion
210
+ Object.defineProperty(exports, 'AutoInstrumentationConfigSchema', {
211
+ enumerable: true,
212
+ get: function () {
213
+ return AutoInstrumentationConfigSchema;
214
+ }
215
+ });
216
+ Object.defineProperty(exports, 'FeaturesConfigSchema', {
217
+ enumerable: true,
218
+ get: function () {
219
+ return FeaturesConfigSchema;
220
+ }
221
+ });
222
+ Object.defineProperty(exports, 'FoundationConfigSchema', {
223
+ enumerable: true,
224
+ get: function () {
225
+ return FoundationConfigSchema;
226
+ }
227
+ });
228
+ Object.defineProperty(exports, 'LoggingConfigSchema', {
229
+ enumerable: true,
230
+ get: function () {
231
+ return LoggingConfigSchema;
232
+ }
233
+ });
234
+ Object.defineProperty(exports, 'OtelConfigSchema', {
235
+ enumerable: true,
236
+ get: function () {
237
+ return OtelConfigSchema;
238
+ }
239
+ });
240
+ Object.defineProperty(exports, 'RedactionConfigSchema', {
241
+ enumerable: true,
242
+ get: function () {
243
+ return RedactionConfigSchema;
244
+ }
245
+ });
246
+ Object.defineProperty(exports, 'RequestLoggingConfigSchema', {
247
+ enumerable: true,
248
+ get: function () {
249
+ return RequestLoggingConfigSchema;
250
+ }
251
+ });
252
+ Object.defineProperty(exports, 'ShutdownConfigSchema', {
253
+ enumerable: true,
254
+ get: function () {
255
+ return ShutdownConfigSchema;
256
+ }
257
+ });
258
+ Object.defineProperty(exports, '__toESM', {
259
+ enumerable: true,
260
+ get: function () {
261
+ return __toESM;
262
+ }
263
+ });
264
+ Object.defineProperty(exports, 'getActiveSpan', {
265
+ enumerable: true,
266
+ get: function () {
267
+ return getActiveSpan;
268
+ }
269
+ });
270
+ Object.defineProperty(exports, 'getDefaultOtelEndpoint', {
271
+ enumerable: true,
272
+ get: function () {
273
+ return getDefaultOtelEndpoint;
274
+ }
275
+ });
276
+ Object.defineProperty(exports, 'getTraceContext', {
277
+ enumerable: true,
278
+ get: function () {
279
+ return getTraceContext;
280
+ }
281
+ });
282
+ Object.defineProperty(exports, 'getTracer', {
283
+ enumerable: true,
284
+ get: function () {
285
+ return getTracer;
286
+ }
287
+ });
288
+ Object.defineProperty(exports, 'isTracingEnabled', {
289
+ enumerable: true,
290
+ get: function () {
291
+ return isTracingEnabled;
292
+ }
293
+ });
294
+ Object.defineProperty(exports, 'parseConfig', {
295
+ enumerable: true,
296
+ get: function () {
297
+ return parseConfig;
298
+ }
299
+ });
300
+ Object.defineProperty(exports, 'setupTracing', {
301
+ enumerable: true,
302
+ get: function () {
303
+ return setupTracing;
304
+ }
305
+ });
306
+ Object.defineProperty(exports, 'shutdownTracing', {
307
+ enumerable: true,
308
+ get: function () {
309
+ return shutdownTracing;
310
+ }
311
+ });
312
+ //# sourceMappingURL=tracing-B8-Ntcll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-B8-Ntcll.js","names":["input: FoundationConfigInput","sdk: NodeSDK | null","options: TracingOptions","config: AutoInstrumentationConfig","mapping: Record<string, string>","result: Record<string, { enabled: boolean }>","name: string"],"sources":["../src/config.ts","../src/features/tracing.ts"],"sourcesContent":["/**\n * Foundation Configuration with Zod Validation\n */\n\nimport { z } from 'zod';\n\n// Auto-Instrumentation Config\nexport const AutoInstrumentationConfigSchema = z\n .object({\n http: z.boolean().default(true),\n fastify: z.boolean().default(true),\n express: z.boolean().default(true),\n mongodb: z.boolean().default(true),\n pg: z.boolean().default(true),\n mysql: z.boolean().default(true),\n redis: z.boolean().default(true),\n ioredis: z.boolean().default(true),\n grpc: z.boolean().default(true),\n fs: z.boolean().default(false),\n dns: z.boolean().default(false),\n })\n .partial();\n\nexport type AutoInstrumentationConfig = z.infer<typeof AutoInstrumentationConfigSchema>;\n\n// Features Config\nexport const FeaturesConfigSchema = z\n .object({\n tracing: z.boolean().default(true),\n metrics: z.boolean().default(true),\n logging: z.boolean().default(true),\n autoInstrumentation: AutoInstrumentationConfigSchema.default({}),\n })\n .partial();\n\nexport type FeaturesConfig = z.infer<typeof FeaturesConfigSchema>;\n\n// OTEL Config\nconst DEFAULT_OTEL_ENDPOINT =\n 'http://otel-stack-deployment-collector.observability.svc.cluster.local:4317';\n\nexport const OtelConfigSchema = z.object({\n endpoint: z\n .string()\n .default(() => process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT),\n metricsIntervalMs: z.number().min(1000).default(5000),\n});\n\nexport type OtelConfig = z.infer<typeof OtelConfigSchema>;\n\n// Logging Config\nexport const LoggingConfigSchema = z\n .object({\n level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n prettyPrint: z.boolean().optional(),\n })\n .partial();\n\nexport type LoggingConfig = z.infer<typeof LoggingConfigSchema>;\n\n// Request Logging Config\nexport const RequestLoggingConfigSchema = z\n .object({\n logHeaders: z.boolean().default(true),\n logBody: z.boolean().default(false),\n logResponseBody: z.boolean().default(false),\n maxBodySize: z.number().default(10 * 1024),\n redactHeaders: z.array(z.string()).optional(),\n })\n .partial();\n\nexport type RequestLoggingConfig = z.infer<typeof RequestLoggingConfigSchema>;\n\n// Redaction Config\nexport const RedactionConfigSchema = z\n .object({\n additionalPaths: z.array(z.string()).default([]),\n })\n .partial();\n\nexport type RedactionConfig = z.infer<typeof RedactionConfigSchema>;\n\n// Shutdown Config\nexport const ShutdownConfigSchema = z\n .object({\n /** Flush telemetry on uncaughtException / unhandledRejection before process exits */\n flushOnCrash: z.boolean().default(false),\n /** Grace period (ms) for flushing before forcing exit */\n flushTimeoutMs: z.number().min(100).default(5000),\n })\n .partial();\n\nexport type ShutdownConfig = z.infer<typeof ShutdownConfigSchema>;\n\n// Main Foundation Config\nexport const FoundationConfigSchema = z.object({\n serviceName: z.string().min(1, 'serviceName is required'),\n serviceVersion: z.string().default(process.env.SERVICE_VERSION || '1.0.0'),\n environment: z\n .enum(['development', 'staging', 'qa', 'production'])\n .default(\n (['development', 'staging', 'qa', 'production'].includes(process.env.NODE_ENV ?? '')\n ? (process.env.NODE_ENV as 'development' | 'staging' | 'qa' | 'production')\n : 'development'),\n ),\n features: FeaturesConfigSchema.default({}),\n otel: OtelConfigSchema.default({}),\n logging: LoggingConfigSchema.default({}),\n requestLogging: RequestLoggingConfigSchema.default({}),\n redaction: RedactionConfigSchema.default({}),\n shutdown: ShutdownConfigSchema.default({}),\n});\n\nexport type FoundationConfig = z.infer<typeof FoundationConfigSchema>;\n\nexport type FoundationConfigInput = z.input<typeof FoundationConfigSchema> & {\n serviceName: string;\n};\n\n/** Parse and validate configuration */\nexport function parseConfig(input: FoundationConfigInput): FoundationConfig {\n const result = FoundationConfigSchema.safeParse(input);\n\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(`Invalid foundation configuration:\\n${errors}`);\n }\n\n return result.data;\n}\n\n/** Get default OTEL endpoint */\nexport function getDefaultOtelEndpoint(): string {\n return process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT;\n}\n","/**\n * OpenTelemetry Tracing Setup\n */\n\nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';\nimport { resourceFromAttributes } from '@opentelemetry/resources';\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';\nimport { trace, context, propagation, SpanStatusCode, type Tracer } from '@opentelemetry/api';\nimport { type AutoInstrumentationConfig, getDefaultOtelEndpoint } from '../config';\n\nexport interface TracingOptions {\n serviceName: string;\n serviceVersion: string;\n environment: string;\n endpoint?: string;\n autoInstrumentation?: AutoInstrumentationConfig;\n}\n\nlet sdk: NodeSDK | null = null;\nlet isInitialized = false;\n\nconst MONITORED_MODULES = ['pg', 'mongodb', 'ioredis', 'mysql2', 'express', '@grpc/grpc-js'];\n\nfunction warnPreloadedModules(): void {\n // require.resolve / require.cache are only available in CJS contexts\n if (typeof require === 'undefined' || typeof require.cache === 'undefined') return;\n\n for (const mod of MONITORED_MODULES) {\n try {\n const resolved = require.resolve(mod);\n if (require.cache[resolved]) {\n console.warn(\n `[neoiq-foundation] \"${mod}\" was imported before tracing init. ` +\n 'Auto-instrumentation may not work for this module. ' +\n 'Use node -r @ciq-dev/neoiq-foundation-node/bootstrap or call createFoundation() first.',\n );\n }\n } catch {\n // Module not installed — no warning needed\n }\n }\n}\n\n/** Initialize OpenTelemetry tracing */\nexport function setupTracing(options: TracingOptions): void {\n if (isInitialized) {\n console.warn('[neoiq-foundation] Tracing already initialized');\n return;\n }\n\n warnPreloadedModules();\n\n const {\n serviceName,\n serviceVersion,\n environment,\n endpoint = getDefaultOtelEndpoint(),\n autoInstrumentation = {},\n } = options;\n\n const resource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: serviceName,\n [ATTR_SERVICE_VERSION]: serviceVersion,\n 'deployment.environment': environment,\n });\n\n const traceExporter = new OTLPTraceExporter({ url: endpoint });\n const instrumentationConfig = buildInstrumentationConfig(autoInstrumentation);\n\n sdk = new NodeSDK({\n resource,\n traceExporter,\n instrumentations: [getNodeAutoInstrumentations(instrumentationConfig)],\n });\n\n sdk.start();\n isInitialized = true;\n}\n\nfunction buildInstrumentationConfig(\n config: AutoInstrumentationConfig\n): Record<string, { enabled: boolean }> {\n const mapping: Record<string, string> = {\n http: '@opentelemetry/instrumentation-http',\n fastify: '@opentelemetry/instrumentation-fastify',\n express: '@opentelemetry/instrumentation-express',\n mongodb: '@opentelemetry/instrumentation-mongodb',\n pg: '@opentelemetry/instrumentation-pg',\n mysql: '@opentelemetry/instrumentation-mysql',\n redis: '@opentelemetry/instrumentation-redis',\n ioredis: '@opentelemetry/instrumentation-ioredis',\n grpc: '@opentelemetry/instrumentation-grpc',\n fs: '@opentelemetry/instrumentation-fs',\n dns: '@opentelemetry/instrumentation-dns',\n };\n\n const result: Record<string, { enabled: boolean }> = {};\n for (const [key, instrumentationName] of Object.entries(mapping)) {\n const userSetting = config[key as keyof AutoInstrumentationConfig];\n const defaultValue = key !== 'fs' && key !== 'dns';\n result[instrumentationName] = { enabled: userSetting ?? defaultValue };\n }\n return result;\n}\n\n/** Shutdown tracing gracefully */\nexport async function shutdownTracing(): Promise<void> {\n if (!sdk) return;\n try {\n await sdk.shutdown();\n isInitialized = false;\n sdk = null;\n } catch (error) {\n console.error('[neoiq-foundation] Error shutting down tracing:', error);\n throw error;\n }\n}\n\nexport function getTracer(name: string): Tracer {\n return trace.getTracer(name);\n}\n\nexport function getActiveSpan(): ReturnType<typeof trace.getActiveSpan> {\n return trace.getActiveSpan();\n}\n\nexport function getTraceContext(): { traceId?: string; spanId?: string } {\n const span = trace.getActiveSpan();\n if (!span) return {};\n const ctx = span.spanContext();\n return { traceId: ctx.traceId, spanId: ctx.spanId };\n}\n\nexport function isTracingEnabled(): boolean {\n return isInitialized;\n}\n\nexport { trace, context, propagation, SpanStatusCode };\nexport type { Tracer };\n"],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ import { createRequire } from "module";
2
+ import { NodeSDK } from "@opentelemetry/sdk-node";
3
+ import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
4
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
5
+ import { resourceFromAttributes } from "@opentelemetry/resources";
6
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
7
+ import { SpanStatusCode as SpanStatusCode$1, context as context$1, propagation as propagation$1, trace as trace$1 } from "@opentelemetry/api";
8
+ import { z } from "zod";
9
+
10
+ //#region rolldown:runtime
11
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
12
+
13
+ //#endregion
14
+ //#region src/config.ts
15
+ const AutoInstrumentationConfigSchema = z.object({
16
+ http: z.boolean().default(true),
17
+ fastify: z.boolean().default(true),
18
+ express: z.boolean().default(true),
19
+ mongodb: z.boolean().default(true),
20
+ pg: z.boolean().default(true),
21
+ mysql: z.boolean().default(true),
22
+ redis: z.boolean().default(true),
23
+ ioredis: z.boolean().default(true),
24
+ grpc: z.boolean().default(true),
25
+ fs: z.boolean().default(false),
26
+ dns: z.boolean().default(false)
27
+ }).partial();
28
+ const FeaturesConfigSchema = z.object({
29
+ tracing: z.boolean().default(true),
30
+ metrics: z.boolean().default(true),
31
+ logging: z.boolean().default(true),
32
+ autoInstrumentation: AutoInstrumentationConfigSchema.default({})
33
+ }).partial();
34
+ const DEFAULT_OTEL_ENDPOINT = "http://otel-stack-deployment-collector.observability.svc.cluster.local:4317";
35
+ const OtelConfigSchema = z.object({
36
+ endpoint: z.string().default(() => process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT),
37
+ metricsIntervalMs: z.number().min(1e3).default(5e3)
38
+ });
39
+ const LoggingConfigSchema = z.object({
40
+ level: z.enum([
41
+ "debug",
42
+ "info",
43
+ "warn",
44
+ "error"
45
+ ]).default("info"),
46
+ prettyPrint: z.boolean().optional()
47
+ }).partial();
48
+ const RequestLoggingConfigSchema = z.object({
49
+ logHeaders: z.boolean().default(true),
50
+ logBody: z.boolean().default(false),
51
+ logResponseBody: z.boolean().default(false),
52
+ maxBodySize: z.number().default(10 * 1024),
53
+ redactHeaders: z.array(z.string()).optional()
54
+ }).partial();
55
+ const RedactionConfigSchema = z.object({ additionalPaths: z.array(z.string()).default([]) }).partial();
56
+ const ShutdownConfigSchema = z.object({
57
+ flushOnCrash: z.boolean().default(false),
58
+ flushTimeoutMs: z.number().min(100).default(5e3)
59
+ }).partial();
60
+ const FoundationConfigSchema = z.object({
61
+ serviceName: z.string().min(1, "serviceName is required"),
62
+ serviceVersion: z.string().default(process.env.SERVICE_VERSION || "1.0.0"),
63
+ environment: z.enum([
64
+ "development",
65
+ "staging",
66
+ "qa",
67
+ "production"
68
+ ]).default([
69
+ "development",
70
+ "staging",
71
+ "qa",
72
+ "production"
73
+ ].includes(process.env.NODE_ENV ?? "") ? process.env.NODE_ENV : "development"),
74
+ features: FeaturesConfigSchema.default({}),
75
+ otel: OtelConfigSchema.default({}),
76
+ logging: LoggingConfigSchema.default({}),
77
+ requestLogging: RequestLoggingConfigSchema.default({}),
78
+ redaction: RedactionConfigSchema.default({}),
79
+ shutdown: ShutdownConfigSchema.default({})
80
+ });
81
+ /** Parse and validate configuration */
82
+ function parseConfig(input) {
83
+ const result = FoundationConfigSchema.safeParse(input);
84
+ if (!result.success) {
85
+ const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
86
+ throw new Error(`Invalid foundation configuration:\n${errors}`);
87
+ }
88
+ return result.data;
89
+ }
90
+ /** Get default OTEL endpoint */
91
+ function getDefaultOtelEndpoint() {
92
+ return process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT;
93
+ }
94
+
95
+ //#endregion
96
+ //#region src/features/tracing.ts
97
+ let sdk = null;
98
+ let isInitialized = false;
99
+ const MONITORED_MODULES = [
100
+ "pg",
101
+ "mongodb",
102
+ "ioredis",
103
+ "mysql2",
104
+ "express",
105
+ "@grpc/grpc-js"
106
+ ];
107
+ function warnPreloadedModules() {
108
+ if (typeof __require === "undefined" || typeof __require.cache === "undefined") return;
109
+ for (const mod of MONITORED_MODULES) try {
110
+ const resolved = __require.resolve(mod);
111
+ if (__require.cache[resolved]) console.warn(`[neoiq-foundation] "${mod}" was imported before tracing init. Auto-instrumentation may not work for this module. Use node -r @ciq-dev/neoiq-foundation-node/bootstrap or call createFoundation() first.`);
112
+ } catch {}
113
+ }
114
+ /** Initialize OpenTelemetry tracing */
115
+ function setupTracing(options) {
116
+ if (isInitialized) {
117
+ console.warn("[neoiq-foundation] Tracing already initialized");
118
+ return;
119
+ }
120
+ warnPreloadedModules();
121
+ const { serviceName, serviceVersion, environment, endpoint = getDefaultOtelEndpoint(), autoInstrumentation = {} } = options;
122
+ const resource = resourceFromAttributes({
123
+ [ATTR_SERVICE_NAME]: serviceName,
124
+ [ATTR_SERVICE_VERSION]: serviceVersion,
125
+ "deployment.environment": environment
126
+ });
127
+ const traceExporter = new OTLPTraceExporter({ url: endpoint });
128
+ const instrumentationConfig = buildInstrumentationConfig(autoInstrumentation);
129
+ sdk = new NodeSDK({
130
+ resource,
131
+ traceExporter,
132
+ instrumentations: [getNodeAutoInstrumentations(instrumentationConfig)]
133
+ });
134
+ sdk.start();
135
+ isInitialized = true;
136
+ }
137
+ function buildInstrumentationConfig(config) {
138
+ const mapping = {
139
+ http: "@opentelemetry/instrumentation-http",
140
+ fastify: "@opentelemetry/instrumentation-fastify",
141
+ express: "@opentelemetry/instrumentation-express",
142
+ mongodb: "@opentelemetry/instrumentation-mongodb",
143
+ pg: "@opentelemetry/instrumentation-pg",
144
+ mysql: "@opentelemetry/instrumentation-mysql",
145
+ redis: "@opentelemetry/instrumentation-redis",
146
+ ioredis: "@opentelemetry/instrumentation-ioredis",
147
+ grpc: "@opentelemetry/instrumentation-grpc",
148
+ fs: "@opentelemetry/instrumentation-fs",
149
+ dns: "@opentelemetry/instrumentation-dns"
150
+ };
151
+ const result = {};
152
+ for (const [key, instrumentationName] of Object.entries(mapping)) {
153
+ const userSetting = config[key];
154
+ const defaultValue = key !== "fs" && key !== "dns";
155
+ result[instrumentationName] = { enabled: userSetting ?? defaultValue };
156
+ }
157
+ return result;
158
+ }
159
+ /** Shutdown tracing gracefully */
160
+ async function shutdownTracing() {
161
+ if (!sdk) return;
162
+ try {
163
+ await sdk.shutdown();
164
+ isInitialized = false;
165
+ sdk = null;
166
+ } catch (error) {
167
+ console.error("[neoiq-foundation] Error shutting down tracing:", error);
168
+ throw error;
169
+ }
170
+ }
171
+ function getTracer(name) {
172
+ return trace$1.getTracer(name);
173
+ }
174
+ function getActiveSpan() {
175
+ return trace$1.getActiveSpan();
176
+ }
177
+ function getTraceContext() {
178
+ const span = trace$1.getActiveSpan();
179
+ if (!span) return {};
180
+ const ctx = span.spanContext();
181
+ return {
182
+ traceId: ctx.traceId,
183
+ spanId: ctx.spanId
184
+ };
185
+ }
186
+ function isTracingEnabled() {
187
+ return isInitialized;
188
+ }
189
+
190
+ //#endregion
191
+ export { AutoInstrumentationConfigSchema, FeaturesConfigSchema, FoundationConfigSchema, LoggingConfigSchema, OtelConfigSchema, RedactionConfigSchema, RequestLoggingConfigSchema, ShutdownConfigSchema, SpanStatusCode$1 as SpanStatusCode, context$1 as context, getActiveSpan, getDefaultOtelEndpoint, getTraceContext, getTracer, isTracingEnabled, parseConfig, propagation$1 as propagation, setupTracing, shutdownTracing, trace$1 as trace };
192
+ //# sourceMappingURL=tracing-CcsyQIpB.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-CcsyQIpB.mjs","names":["input: FoundationConfigInput","sdk: NodeSDK | null","options: TracingOptions","config: AutoInstrumentationConfig","mapping: Record<string, string>","result: Record<string, { enabled: boolean }>","name: string"],"sources":["../src/config.ts","../src/features/tracing.ts"],"sourcesContent":["/**\n * Foundation Configuration with Zod Validation\n */\n\nimport { z } from 'zod';\n\n// Auto-Instrumentation Config\nexport const AutoInstrumentationConfigSchema = z\n .object({\n http: z.boolean().default(true),\n fastify: z.boolean().default(true),\n express: z.boolean().default(true),\n mongodb: z.boolean().default(true),\n pg: z.boolean().default(true),\n mysql: z.boolean().default(true),\n redis: z.boolean().default(true),\n ioredis: z.boolean().default(true),\n grpc: z.boolean().default(true),\n fs: z.boolean().default(false),\n dns: z.boolean().default(false),\n })\n .partial();\n\nexport type AutoInstrumentationConfig = z.infer<typeof AutoInstrumentationConfigSchema>;\n\n// Features Config\nexport const FeaturesConfigSchema = z\n .object({\n tracing: z.boolean().default(true),\n metrics: z.boolean().default(true),\n logging: z.boolean().default(true),\n autoInstrumentation: AutoInstrumentationConfigSchema.default({}),\n })\n .partial();\n\nexport type FeaturesConfig = z.infer<typeof FeaturesConfigSchema>;\n\n// OTEL Config\nconst DEFAULT_OTEL_ENDPOINT =\n 'http://otel-stack-deployment-collector.observability.svc.cluster.local:4317';\n\nexport const OtelConfigSchema = z.object({\n endpoint: z\n .string()\n .default(() => process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT),\n metricsIntervalMs: z.number().min(1000).default(5000),\n});\n\nexport type OtelConfig = z.infer<typeof OtelConfigSchema>;\n\n// Logging Config\nexport const LoggingConfigSchema = z\n .object({\n level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n prettyPrint: z.boolean().optional(),\n })\n .partial();\n\nexport type LoggingConfig = z.infer<typeof LoggingConfigSchema>;\n\n// Request Logging Config\nexport const RequestLoggingConfigSchema = z\n .object({\n logHeaders: z.boolean().default(true),\n logBody: z.boolean().default(false),\n logResponseBody: z.boolean().default(false),\n maxBodySize: z.number().default(10 * 1024),\n redactHeaders: z.array(z.string()).optional(),\n })\n .partial();\n\nexport type RequestLoggingConfig = z.infer<typeof RequestLoggingConfigSchema>;\n\n// Redaction Config\nexport const RedactionConfigSchema = z\n .object({\n additionalPaths: z.array(z.string()).default([]),\n })\n .partial();\n\nexport type RedactionConfig = z.infer<typeof RedactionConfigSchema>;\n\n// Shutdown Config\nexport const ShutdownConfigSchema = z\n .object({\n /** Flush telemetry on uncaughtException / unhandledRejection before process exits */\n flushOnCrash: z.boolean().default(false),\n /** Grace period (ms) for flushing before forcing exit */\n flushTimeoutMs: z.number().min(100).default(5000),\n })\n .partial();\n\nexport type ShutdownConfig = z.infer<typeof ShutdownConfigSchema>;\n\n// Main Foundation Config\nexport const FoundationConfigSchema = z.object({\n serviceName: z.string().min(1, 'serviceName is required'),\n serviceVersion: z.string().default(process.env.SERVICE_VERSION || '1.0.0'),\n environment: z\n .enum(['development', 'staging', 'qa', 'production'])\n .default(\n (['development', 'staging', 'qa', 'production'].includes(process.env.NODE_ENV ?? '')\n ? (process.env.NODE_ENV as 'development' | 'staging' | 'qa' | 'production')\n : 'development'),\n ),\n features: FeaturesConfigSchema.default({}),\n otel: OtelConfigSchema.default({}),\n logging: LoggingConfigSchema.default({}),\n requestLogging: RequestLoggingConfigSchema.default({}),\n redaction: RedactionConfigSchema.default({}),\n shutdown: ShutdownConfigSchema.default({}),\n});\n\nexport type FoundationConfig = z.infer<typeof FoundationConfigSchema>;\n\nexport type FoundationConfigInput = z.input<typeof FoundationConfigSchema> & {\n serviceName: string;\n};\n\n/** Parse and validate configuration */\nexport function parseConfig(input: FoundationConfigInput): FoundationConfig {\n const result = FoundationConfigSchema.safeParse(input);\n\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(`Invalid foundation configuration:\\n${errors}`);\n }\n\n return result.data;\n}\n\n/** Get default OTEL endpoint */\nexport function getDefaultOtelEndpoint(): string {\n return process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTEL_ENDPOINT;\n}\n","/**\n * OpenTelemetry Tracing Setup\n */\n\nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';\nimport { resourceFromAttributes } from '@opentelemetry/resources';\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';\nimport { trace, context, propagation, SpanStatusCode, type Tracer } from '@opentelemetry/api';\nimport { type AutoInstrumentationConfig, getDefaultOtelEndpoint } from '../config';\n\nexport interface TracingOptions {\n serviceName: string;\n serviceVersion: string;\n environment: string;\n endpoint?: string;\n autoInstrumentation?: AutoInstrumentationConfig;\n}\n\nlet sdk: NodeSDK | null = null;\nlet isInitialized = false;\n\nconst MONITORED_MODULES = ['pg', 'mongodb', 'ioredis', 'mysql2', 'express', '@grpc/grpc-js'];\n\nfunction warnPreloadedModules(): void {\n // require.resolve / require.cache are only available in CJS contexts\n if (typeof require === 'undefined' || typeof require.cache === 'undefined') return;\n\n for (const mod of MONITORED_MODULES) {\n try {\n const resolved = require.resolve(mod);\n if (require.cache[resolved]) {\n console.warn(\n `[neoiq-foundation] \"${mod}\" was imported before tracing init. ` +\n 'Auto-instrumentation may not work for this module. ' +\n 'Use node -r @ciq-dev/neoiq-foundation-node/bootstrap or call createFoundation() first.',\n );\n }\n } catch {\n // Module not installed — no warning needed\n }\n }\n}\n\n/** Initialize OpenTelemetry tracing */\nexport function setupTracing(options: TracingOptions): void {\n if (isInitialized) {\n console.warn('[neoiq-foundation] Tracing already initialized');\n return;\n }\n\n warnPreloadedModules();\n\n const {\n serviceName,\n serviceVersion,\n environment,\n endpoint = getDefaultOtelEndpoint(),\n autoInstrumentation = {},\n } = options;\n\n const resource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: serviceName,\n [ATTR_SERVICE_VERSION]: serviceVersion,\n 'deployment.environment': environment,\n });\n\n const traceExporter = new OTLPTraceExporter({ url: endpoint });\n const instrumentationConfig = buildInstrumentationConfig(autoInstrumentation);\n\n sdk = new NodeSDK({\n resource,\n traceExporter,\n instrumentations: [getNodeAutoInstrumentations(instrumentationConfig)],\n });\n\n sdk.start();\n isInitialized = true;\n}\n\nfunction buildInstrumentationConfig(\n config: AutoInstrumentationConfig\n): Record<string, { enabled: boolean }> {\n const mapping: Record<string, string> = {\n http: '@opentelemetry/instrumentation-http',\n fastify: '@opentelemetry/instrumentation-fastify',\n express: '@opentelemetry/instrumentation-express',\n mongodb: '@opentelemetry/instrumentation-mongodb',\n pg: '@opentelemetry/instrumentation-pg',\n mysql: '@opentelemetry/instrumentation-mysql',\n redis: '@opentelemetry/instrumentation-redis',\n ioredis: '@opentelemetry/instrumentation-ioredis',\n grpc: '@opentelemetry/instrumentation-grpc',\n fs: '@opentelemetry/instrumentation-fs',\n dns: '@opentelemetry/instrumentation-dns',\n };\n\n const result: Record<string, { enabled: boolean }> = {};\n for (const [key, instrumentationName] of Object.entries(mapping)) {\n const userSetting = config[key as keyof AutoInstrumentationConfig];\n const defaultValue = key !== 'fs' && key !== 'dns';\n result[instrumentationName] = { enabled: userSetting ?? defaultValue };\n }\n return result;\n}\n\n/** Shutdown tracing gracefully */\nexport async function shutdownTracing(): Promise<void> {\n if (!sdk) return;\n try {\n await sdk.shutdown();\n isInitialized = false;\n sdk = null;\n } catch (error) {\n console.error('[neoiq-foundation] Error shutting down tracing:', error);\n throw error;\n }\n}\n\nexport function getTracer(name: string): Tracer {\n return trace.getTracer(name);\n}\n\nexport function getActiveSpan(): ReturnType<typeof trace.getActiveSpan> {\n return trace.getActiveSpan();\n}\n\nexport function getTraceContext(): { traceId?: string; spanId?: string } {\n const span = trace.getActiveSpan();\n if (!span) return {};\n const ctx = span.spanContext();\n return { traceId: ctx.traceId, spanId: ctx.spanId };\n}\n\nexport function isTracingEnabled(): boolean {\n return isInitialized;\n}\n\nexport { trace, context, propagation, SpanStatusCode };\nexport type { Tracer };\n"],"mappings":";;;;;;;;;;;;;;AAOA,MAAa,kCAAkC,EAC5C,OAAO;CACN,MAAM,EAAE,SAAS,CAAC,QAAQ,KAAK;CAC/B,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,IAAI,EAAE,SAAS,CAAC,QAAQ,KAAK;CAC7B,OAAO,EAAE,SAAS,CAAC,QAAQ,KAAK;CAChC,OAAO,EAAE,SAAS,CAAC,QAAQ,KAAK;CAChC,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,MAAM,EAAE,SAAS,CAAC,QAAQ,KAAK;CAC/B,IAAI,EAAE,SAAS,CAAC,QAAQ,MAAM;CAC9B,KAAK,EAAE,SAAS,CAAC,QAAQ,MAAM;AAChC,EAAC,CACD,SAAS;AAKZ,MAAa,uBAAuB,EACjC,OAAO;CACN,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;CAClC,qBAAqB,gCAAgC,QAAQ,CAAE,EAAC;AACjE,EAAC,CACD,SAAS;AAKZ,MAAM,wBACJ;AAEF,MAAa,mBAAmB,EAAE,OAAO;CACvC,UAAU,EACP,QAAQ,CACR,QAAQ,MAAM,QAAQ,IAAI,+BAA+B,sBAAsB;CAClF,mBAAmB,EAAE,QAAQ,CAAC,IAAI,IAAK,CAAC,QAAQ,IAAK;AACtD,EAAC;AAKF,MAAa,sBAAsB,EAChC,OAAO;CACN,OAAO,EAAE,KAAK;EAAC;EAAS;EAAQ;EAAQ;CAAQ,EAAC,CAAC,QAAQ,OAAO;CACjE,aAAa,EAAE,SAAS,CAAC,UAAU;AACpC,EAAC,CACD,SAAS;AAKZ,MAAa,6BAA6B,EACvC,OAAO;CACN,YAAY,EAAE,SAAS,CAAC,QAAQ,KAAK;CACrC,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;CACnC,iBAAiB,EAAE,SAAS,CAAC,QAAQ,MAAM;CAC3C,aAAa,EAAE,QAAQ,CAAC,QAAQ,KAAK,KAAK;CAC1C,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;AAC9C,EAAC,CACD,SAAS;AAKZ,MAAa,wBAAwB,EAClC,OAAO,EACN,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAE,EAAC,CACjD,EAAC,CACD,SAAS;AAKZ,MAAa,uBAAuB,EACjC,OAAO;CAEN,cAAc,EAAE,SAAS,CAAC,QAAQ,MAAM;CAExC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAK;AAClD,EAAC,CACD,SAAS;AAKZ,MAAa,yBAAyB,EAAE,OAAO;CAC7C,aAAa,EAAE,QAAQ,CAAC,IAAI,GAAG,0BAA0B;CACzD,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,QAAQ,IAAI,mBAAmB,QAAQ;CAC1E,aAAa,EACV,KAAK;EAAC;EAAe;EAAW;EAAM;CAAa,EAAC,CACpD,QACE;EAAC;EAAe;EAAW;EAAM;CAAa,EAAC,SAAS,QAAQ,IAAI,YAAY,GAAG,GAC/E,QAAQ,IAAI,WACb,cACL;CACH,UAAU,qBAAqB,QAAQ,CAAE,EAAC;CAC1C,MAAM,iBAAiB,QAAQ,CAAE,EAAC;CAClC,SAAS,oBAAoB,QAAQ,CAAE,EAAC;CACxC,gBAAgB,2BAA2B,QAAQ,CAAE,EAAC;CACtD,WAAW,sBAAsB,QAAQ,CAAE,EAAC;CAC5C,UAAU,qBAAqB,QAAQ,CAAE,EAAC;AAC3C,EAAC;;AASF,SAAgB,YAAYA,OAAgD;CAC1E,MAAM,SAAS,uBAAuB,UAAU,MAAM;AAEtD,MAAK,OAAO,SAAS;EACnB,MAAM,SAAS,OAAO,MAAM,OACzB,IAAI,CAAC,OAAO,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CACnD,KAAK,KAAK;AACb,QAAM,IAAI,OAAO,qCAAqC,OAAO;CAC9D;AAED,QAAO,OAAO;AACf;;AAGD,SAAgB,yBAAiC;AAC/C,QAAO,QAAQ,IAAI,+BAA+B;AACnD;;;;ACpHD,IAAIC,MAAsB;AAC1B,IAAI,gBAAgB;AAEpB,MAAM,oBAAoB;CAAC;CAAM;CAAW;CAAW;CAAU;CAAW;AAAgB;AAE5F,SAAS,uBAA6B;AAEpC,0BAAuB,gCAA8B,UAAU,YAAa;AAE5E,MAAK,MAAM,OAAO,kBAChB,KAAI;EACF,MAAM,WAAW,UAAQ,QAAQ,IAAI;AACrC,gBAAY,MAAM,UAChB,SAAQ,MACL,sBAAsB,IAAI,+KAG5B;CAEJ,QAAO,CAEP;AAEJ;;AAGD,SAAgB,aAAaC,SAA+B;AAC1D,KAAI,eAAe;AACjB,UAAQ,KAAK,iDAAiD;AAC9D;CACD;AAED,uBAAsB;CAEtB,MAAM,EACJ,aACA,gBACA,aACA,WAAW,wBAAwB,EACnC,sBAAsB,CAAE,GACzB,GAAG;CAEJ,MAAM,WAAW,uBAAuB;GACrC,oBAAoB;GACpB,uBAAuB;EACxB,0BAA0B;CAC3B,EAAC;CAEF,MAAM,gBAAgB,IAAI,kBAAkB,EAAE,KAAK,SAAU;CAC7D,MAAM,wBAAwB,2BAA2B,oBAAoB;AAE7E,OAAM,IAAI,QAAQ;EAChB;EACA;EACA,kBAAkB,CAAC,4BAA4B,sBAAsB,AAAC;CACvE;AAED,KAAI,OAAO;AACX,iBAAgB;AACjB;AAED,SAAS,2BACPC,QACsC;CACtC,MAAMC,UAAkC;EACtC,MAAM;EACN,SAAS;EACT,SAAS;EACT,SAAS;EACT,IAAI;EACJ,OAAO;EACP,OAAO;EACP,SAAS;EACT,MAAM;EACN,IAAI;EACJ,KAAK;CACN;CAED,MAAMC,SAA+C,CAAE;AACvD,MAAK,MAAM,CAAC,KAAK,oBAAoB,IAAI,OAAO,QAAQ,QAAQ,EAAE;EAChE,MAAM,cAAc,OAAO;EAC3B,MAAM,eAAe,QAAQ,QAAQ,QAAQ;AAC7C,SAAO,uBAAuB,EAAE,SAAS,eAAe,aAAc;CACvE;AACD,QAAO;AACR;;AAGD,eAAsB,kBAAiC;AACrD,MAAK,IAAK;AACV,KAAI;AACF,QAAM,IAAI,UAAU;AACpB,kBAAgB;AAChB,QAAM;CACP,SAAQ,OAAO;AACd,UAAQ,MAAM,mDAAmD,MAAM;AACvE,QAAM;CACP;AACF;AAED,SAAgB,UAAUC,MAAsB;AAC9C,QAAO,QAAM,UAAU,KAAK;AAC7B;AAED,SAAgB,gBAAwD;AACtE,QAAO,QAAM,eAAe;AAC7B;AAED,SAAgB,kBAAyD;CACvE,MAAM,OAAO,QAAM,eAAe;AAClC,MAAK,KAAM,QAAO,CAAE;CACpB,MAAM,MAAM,KAAK,aAAa;AAC9B,QAAO;EAAE,SAAS,IAAI;EAAS,QAAQ,IAAI;CAAQ;AACpD;AAED,SAAgB,mBAA4B;AAC1C,QAAO;AACR"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciq-dev/neoiq-foundation-node",
3
- "version": "1.0.1-beta.2",
3
+ "version": "1.0.1-beta.4",
4
4
  "description": "Node.js observability foundation for CommerceIQ services. Integrates with Groundcover via OpenTelemetry.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -17,8 +17,14 @@
17
17
  }
18
18
  },
19
19
  "./bootstrap": {
20
- "import": "./dist/bootstrap.mjs",
21
- "require": "./dist/bootstrap.js"
20
+ "import": {
21
+ "types": "./dist/bootstrap.d.mts",
22
+ "default": "./dist/bootstrap.mjs"
23
+ },
24
+ "require": {
25
+ "types": "./dist/bootstrap.d.ts",
26
+ "default": "./dist/bootstrap.js"
27
+ }
22
28
  }
23
29
  },
24
30
  "files": [
@@ -40,7 +46,8 @@
40
46
  "node": ">=18.0.0"
41
47
  },
42
48
  "peerDependencies": {
43
- "zod": "^3.22.0",
49
+ "@aws-sdk/client-s3": "^3.0.0",
50
+ "@aws-sdk/s3-request-presigner": "^3.0.0",
44
51
  "@opentelemetry/api": "^1.7.0",
45
52
  "@opentelemetry/auto-instrumentations-node": ">=0.41.0",
46
53
  "@opentelemetry/exporter-metrics-otlp-grpc": ">=0.48.0",
@@ -56,8 +63,7 @@
56
63
  "opossum": ">=8.1.0",
57
64
  "pino": ">=8.17.0",
58
65
  "pino-pretty": ">=10.3.0",
59
- "@aws-sdk/client-s3": "^3.0.0",
60
- "@aws-sdk/s3-request-presigner": "^3.0.0"
66
+ "zod": "^3.22.0"
61
67
  },
62
68
  "peerDependenciesMeta": {
63
69
  "@aws-sdk/client-s3": {