@tracekit/node-apm 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,6 +15,7 @@ Zero-config distributed tracing and performance monitoring for Express and NestJ
15
15
  - **TypeScript First** - Full type definitions included
16
16
  - **HTTP Request Tracing** - Track every request, route, and handler
17
17
  - **Error Tracking** - Capture exceptions with full context
18
+ - **Code Monitoring** - Live debugging with breakpoints and variable inspection
18
19
  - **Low Overhead** - < 5% performance impact
19
20
 
20
21
  ## Installation
@@ -95,6 +96,94 @@ export class AppModule {}
95
96
 
96
97
  That's it! Your app is now automatically traced.
97
98
 
99
+ ## Code Monitoring (Live Debugging)
100
+
101
+ TraceKit includes production-safe code monitoring for live debugging without redeployment.
102
+
103
+ ### Enable Code Monitoring
104
+
105
+ ```typescript
106
+ import * as tracekit from '@tracekit/node-apm';
107
+
108
+ // Enable code monitoring
109
+ const client = tracekit.init({
110
+ apiKey: process.env.TRACEKIT_API_KEY!,
111
+ serviceName: 'my-app',
112
+ enableCodeMonitoring: true, // Enable live debugging
113
+ });
114
+ ```
115
+
116
+ ### Add Debug Points
117
+
118
+ Add checkpoints anywhere in your code to capture variable state and stack traces:
119
+
120
+ ```typescript
121
+ // In any service or controller
122
+ app.post('/checkout', async (req, res) => {
123
+ const cart = req.body.cart;
124
+ const userId = req.body.userId;
125
+
126
+ // Capture snapshot at this point
127
+ await client.captureSnapshot('checkout-validation', {
128
+ userId,
129
+ cartItems: cart.items.length,
130
+ totalAmount: cart.total,
131
+ });
132
+
133
+ // Process payment...
134
+ const result = await processPayment(cart);
135
+
136
+ // Another checkpoint
137
+ await client.captureSnapshot('payment-complete', {
138
+ userId,
139
+ paymentId: result.paymentId,
140
+ success: result.success,
141
+ });
142
+
143
+ res.json(result);
144
+ });
145
+ ```
146
+
147
+ ### Automatic Breakpoint Management
148
+
149
+ - **Auto-Registration**: First call to `captureSnapshot()` automatically creates breakpoints in TraceKit
150
+ - **Smart Matching**: Breakpoints match by function name + label (stable across code changes)
151
+ - **Background Sync**: SDK polls for active breakpoints every 30 seconds
152
+ - **Production Safe**: No performance impact when breakpoints are inactive
153
+
154
+ ### View Captured Data
155
+
156
+ Snapshots include:
157
+ - **Variables**: Local variables at capture point
158
+ - **Stack Trace**: Full call stack with file/line numbers
159
+ - **Request Context**: HTTP method, URL, headers, query params
160
+ - **Execution Time**: When the snapshot was captured
161
+
162
+ ### NestJS Usage
163
+
164
+ ```typescript
165
+ import { Injectable, Inject } from '@nestjs/common';
166
+ import { SnapshotClient } from '@tracekit/node-apm';
167
+
168
+ @Injectable()
169
+ export class PaymentService {
170
+ constructor(
171
+ @Inject('TRACEKIT_SNAPSHOT_CLIENT')
172
+ private snapshotClient?: SnapshotClient
173
+ ) {}
174
+
175
+ async processPayment(order: Order) {
176
+ // Automatic snapshot capture
177
+ await this.snapshotClient?.checkAndCaptureWithContext('payment-processing', {
178
+ orderId: order.id,
179
+ amount: order.amount,
180
+ });
181
+
182
+ // ... payment logic
183
+ }
184
+ }
185
+ ```
186
+
98
187
  Get your API key at [https://app.tracekit.dev](https://app.tracekit.dev)
99
188
 
100
189
  ## Configuration
@@ -119,6 +208,15 @@ tracekit.init({
119
208
 
120
209
  // Optional: Sample rate 0.0-1.0 (default: 1.0 = 100%)
121
210
  sampleRate: 0.5, // Trace 50% of requests
211
+
212
+ // Optional: Enable live code debugging (default: false)
213
+ enableCodeMonitoring: true, // Enable breakpoints and snapshots
214
+
215
+ // Optional: Map hostnames to service names for service graph
216
+ serviceNameMappings: {
217
+ 'localhost:8082': 'payment-service',
218
+ 'localhost:8083': 'user-service',
219
+ },
122
220
  });
123
221
  ```
124
222
 
@@ -138,6 +236,7 @@ import { TracekitModule } from '@tracekit/node-apm/nestjs';
138
236
  apiKey: config.get('TRACEKIT_API_KEY')!,
139
237
  serviceName: config.get('APP_NAME', 'my-app'),
140
238
  enabled: config.get('NODE_ENV') !== 'development',
239
+ enableCodeMonitoring: config.get('TRACEKIT_CODE_MONITORING_ENABLED', false),
141
240
  }),
142
241
  }),
143
242
  ],
@@ -145,11 +244,109 @@ import { TracekitModule } from '@tracekit/node-apm/nestjs';
145
244
  export class AppModule {}
146
245
  ```
147
246
 
247
+ ## Automatic Service Discovery
248
+
249
+ TraceKit automatically instruments **outgoing HTTP calls** to create service dependency graphs. This enables you to see which services talk to each other in your distributed system.
250
+
251
+ ### How It Works
252
+
253
+ When your service makes an HTTP request to another service:
254
+
255
+ 1. ✅ TraceKit creates a **CLIENT span** for the outgoing request
256
+ 2. ✅ Trace context is automatically injected into request headers (`traceparent`)
257
+ 3. ✅ The receiving service creates a **SERVER span** linked to your CLIENT span
258
+ 4. ✅ TraceKit maps the dependency: **YourService → TargetService**
259
+
260
+ ### Supported HTTP Clients
261
+
262
+ TraceKit automatically instruments these HTTP libraries:
263
+
264
+ - ✅ **`http`** / **`https`** (Node.js built-in modules)
265
+ - ✅ **`fetch`** (Node 18+ native fetch API)
266
+ - ✅ **`axios`** (works via http module)
267
+ - ✅ **`node-fetch`** (works via http module)
268
+ - ✅ **`got`**, **`superagent`**, etc. (work via http module)
269
+
270
+ **Zero configuration required!** Just make HTTP calls as normal:
271
+
272
+ ```typescript
273
+ import axios from 'axios';
274
+ import fetch from 'node-fetch';
275
+
276
+ // All of these automatically create CLIENT spans:
277
+ await fetch('http://payment-service/charge');
278
+ await axios.get('http://inventory-service/check');
279
+ http.get('http://user-service/profile/123', callback);
280
+ ```
281
+
282
+ ### Service Name Detection
283
+
284
+ TraceKit intelligently extracts service names from URLs:
285
+
286
+ | URL | Extracted Service Name |
287
+ |-----|------------------------|
288
+ | `http://payment-service:3000` | `payment-service` |
289
+ | `http://payment.internal` | `payment` |
290
+ | `http://payment.svc.cluster.local` | `payment` |
291
+ | `https://api.example.com` | `api.example.com` |
292
+
293
+ This works seamlessly with:
294
+ - Kubernetes service names
295
+ - Internal DNS names
296
+ - Docker Compose service names
297
+ - External APIs
298
+
299
+ ### Custom Service Name Mappings
300
+
301
+ For local development or when service names can't be inferred from hostnames, use `serviceNameMappings`:
302
+
303
+ ```typescript
304
+ tracekit.init({
305
+ apiKey: process.env.TRACEKIT_API_KEY,
306
+ serviceName: 'my-service',
307
+ // Map localhost URLs to actual service names
308
+ serviceNameMappings: {
309
+ 'localhost:8082': 'payment-service',
310
+ 'localhost:8083': 'user-service',
311
+ 'localhost:8084': 'inventory-service',
312
+ 'localhost:5001': 'analytics-service',
313
+ },
314
+ });
315
+
316
+ // Now requests to localhost:8082 will show as "payment-service" in the service graph
317
+ const response = await fetch('http://localhost:8082/charge');
318
+ // -> Creates CLIENT span with peer.service = "payment-service"
319
+ ```
320
+
321
+ This is especially useful when:
322
+ - Running microservices locally on different ports
323
+ - Using Docker Compose with localhost networking
324
+ - Testing distributed tracing in development
325
+
326
+ ### Viewing Service Dependencies
327
+
328
+ Visit your TraceKit dashboard to see:
329
+
330
+ - **Service Map**: Visual graph showing which services call which
331
+ - **Service List**: Table of all services with health metrics
332
+ - **Service Detail**: Deep dive on individual services with upstream/downstream dependencies
333
+
334
+ ### Disabling Auto-Instrumentation
335
+
336
+ If you need to disable automatic HTTP client instrumentation:
337
+
338
+ ```typescript
339
+ tracekit.init({
340
+ apiKey: process.env.TRACEKIT_API_KEY,
341
+ autoInstrumentHttpClient: false, // Disable auto-instrumentation
342
+ });
343
+ ```
344
+
148
345
  ## What Gets Traced?
149
346
 
150
- ### HTTP Requests
347
+ ### Incoming HTTP Requests (SERVER spans)
151
348
 
152
- Every HTTP request is automatically traced with:
349
+ Every HTTP request to your service is automatically traced with:
153
350
 
154
351
  - Route path and HTTP method
155
352
  - Request URL and query parameters
@@ -158,6 +355,15 @@ Every HTTP request is automatically traced with:
158
355
  - User agent and client IP
159
356
  - Controller and handler names (NestJS)
160
357
 
358
+ ### Outgoing HTTP Requests (CLIENT spans)
359
+
360
+ Every HTTP request from your service is automatically traced with:
361
+
362
+ - Target URL and HTTP method
363
+ - HTTP status code
364
+ - Request duration
365
+ - `peer.service` attribute for service dependency mapping
366
+
161
367
  ### Errors and Exceptions
162
368
 
163
369
  All exceptions are automatically captured with:
package/dist/client.d.ts CHANGED
@@ -1,26 +1,36 @@
1
1
  import * as api from '@opentelemetry/api';
2
+ import { SnapshotClient } from './snapshot-client';
2
3
  export interface TracekitConfig {
3
4
  apiKey: string;
4
5
  endpoint?: string;
5
6
  serviceName?: string;
6
7
  enabled?: boolean;
7
8
  sampleRate?: number;
9
+ enableCodeMonitoring?: boolean;
10
+ autoInstrumentHttpClient?: boolean;
11
+ serviceNameMappings?: Record<string, string>;
8
12
  }
9
13
  export declare class TracekitClient {
10
14
  private provider;
11
15
  private tracer;
12
16
  private config;
17
+ private snapshotClient?;
13
18
  constructor(config: TracekitConfig);
14
19
  startTrace(operationName: string, attributes?: Record<string, any>): api.Span;
20
+ startServerSpan(operationName: string, attributes?: Record<string, any>): api.Span;
15
21
  startSpan(operationName: string, parentSpan?: api.Span | null, attributes?: Record<string, any>): api.Span;
16
22
  endSpan(span: api.Span, finalAttributes?: Record<string, any>, status?: string): void;
17
23
  addEvent(span: api.Span, name: string, attributes?: Record<string, any>): void;
18
24
  recordException(span: api.Span, error: Error): void;
25
+ private formatStackTrace;
19
26
  flush(): Promise<void>;
20
27
  shutdown(): Promise<void>;
21
28
  isEnabled(): boolean;
22
29
  shouldSample(): boolean;
23
30
  getTracer(): api.Tracer;
31
+ getSnapshotClient(): SnapshotClient | undefined;
32
+ captureSnapshot(label: string, variables?: Record<string, any>): Promise<void>;
33
+ private extractServiceName;
24
34
  private normalizeAttributes;
25
35
  }
26
36
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,EAAE,cAAc;IAsClC,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,GAAG,CAAC,IAAI;IAOjF,SAAS,CACP,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,EAC5B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACnC,GAAG,CAAC,IAAI;IAcX,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAgBzF,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI;IAIlF,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAQ7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,OAAO;IAIvB,SAAS,IAAI,GAAG,CAAC,MAAM;IAIvB,OAAO,CAAC,mBAAmB;CAiB5B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAI1C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAMnC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,cAAc,CAAC,CAAiB;gBAE5B,MAAM,EAAE,cAAc;IA8ElC,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,GAAG,CAAC,IAAI;IAWjF,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,GAAG,CAAC,IAAI;IAWtF,SAAS,CACP,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,EAC5B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACnC,GAAG,CAAC,IAAI;IAcX,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAgBzF,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI;IAIlF,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAwBnD,OAAO,CAAC,gBAAgB;IAgClB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,OAAO;IAIvB,SAAS,IAAI,GAAG,CAAC,MAAM;IAKvB,iBAAiB,IAAI,cAAc,GAAG,SAAS;IAKzC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxF,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,mBAAmB;CAiB5B"}
package/dist/client.js CHANGED
@@ -40,6 +40,10 @@ const resources_1 = require("@opentelemetry/resources");
40
40
  const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
41
41
  const sdk_trace_node_2 = require("@opentelemetry/sdk-trace-node");
42
42
  const api = __importStar(require("@opentelemetry/api"));
43
+ const instrumentation_1 = require("@opentelemetry/instrumentation");
44
+ const instrumentation_http_1 = require("@opentelemetry/instrumentation-http");
45
+ const instrumentation_fetch_1 = require("@opentelemetry/instrumentation-fetch");
46
+ const snapshot_client_1 = require("./snapshot-client");
43
47
  class TracekitClient {
44
48
  constructor(config) {
45
49
  this.config = {
@@ -47,7 +51,10 @@ class TracekitClient {
47
51
  serviceName: config.serviceName || 'node-app',
48
52
  enabled: config.enabled ?? true,
49
53
  sampleRate: config.sampleRate ?? 1.0,
54
+ enableCodeMonitoring: config.enableCodeMonitoring ?? false,
55
+ autoInstrumentHttpClient: config.autoInstrumentHttpClient ?? true,
50
56
  apiKey: config.apiKey,
57
+ serviceNameMappings: config.serviceNameMappings ?? {},
51
58
  };
52
59
  const resource = new resources_1.Resource({
53
60
  [semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: this.config.serviceName,
@@ -64,8 +71,33 @@ class TracekitClient {
64
71
  });
65
72
  this.provider.addSpanProcessor(new sdk_trace_node_2.BatchSpanProcessor(exporter));
66
73
  this.provider.register();
74
+ if (this.config.autoInstrumentHttpClient) {
75
+ (0, instrumentation_1.registerInstrumentations)({
76
+ tracerProvider: this.provider,
77
+ instrumentations: [
78
+ new instrumentation_http_1.HttpInstrumentation({
79
+ requireParentforOutgoingSpans: true,
80
+ requireParentforIncomingSpans: false,
81
+ requestHook: (span, request) => {
82
+ if ('hostname' in request || 'host' in request) {
83
+ const hostname = request.hostname || request.host;
84
+ if (hostname) {
85
+ const serviceName = this.extractServiceName(hostname);
86
+ span.setAttribute('peer.service', serviceName);
87
+ }
88
+ }
89
+ },
90
+ }),
91
+ new instrumentation_fetch_1.FetchInstrumentation({}),
92
+ ],
93
+ });
94
+ }
67
95
  }
68
96
  this.tracer = api.trace.getTracer('@tracekit/node-apm', '1.0.0');
97
+ if (this.config.enableCodeMonitoring) {
98
+ this.snapshotClient = new snapshot_client_1.SnapshotClient(this.config.apiKey, this.config.endpoint.replace('/v1/traces', ''), this.config.serviceName);
99
+ this.snapshotClient.start();
100
+ }
69
101
  }
70
102
  startTrace(operationName, attributes = {}) {
71
103
  return this.tracer.startSpan(operationName, {
@@ -73,6 +105,12 @@ class TracekitClient {
73
105
  attributes: this.normalizeAttributes(attributes),
74
106
  });
75
107
  }
108
+ startServerSpan(operationName, attributes = {}) {
109
+ return this.tracer.startSpan(operationName, {
110
+ kind: api.SpanKind.SERVER,
111
+ attributes: this.normalizeAttributes(attributes),
112
+ }, api.context.active());
113
+ }
76
114
  startSpan(operationName, parentSpan, attributes = {}) {
77
115
  const options = {
78
116
  kind: api.SpanKind.INTERNAL,
@@ -100,16 +138,51 @@ class TracekitClient {
100
138
  span.addEvent(name, this.normalizeAttributes(attributes));
101
139
  }
102
140
  recordException(span, error) {
141
+ let formattedStackTrace = '';
142
+ if (error.stack) {
143
+ formattedStackTrace = this.formatStackTrace(error.stack);
144
+ }
145
+ span.addEvent('exception', {
146
+ 'exception.type': error.constructor.name,
147
+ 'exception.message': error.message,
148
+ 'exception.stacktrace': formattedStackTrace,
149
+ });
103
150
  span.recordException(error);
104
151
  span.setStatus({
105
152
  code: api.SpanStatusCode.ERROR,
106
153
  message: error.message,
107
154
  });
108
155
  }
156
+ formatStackTrace(stack) {
157
+ const lines = stack.split('\n');
158
+ const formatted = [];
159
+ for (let i = 0; i < lines.length; i++) {
160
+ const line = lines[i].trim();
161
+ if (i === 0 && !line.startsWith('at ')) {
162
+ continue;
163
+ }
164
+ const match = line.match(/at\s+(?:([^\s]+)\s+\()?([^:]+):(\d+):\d+\)?/);
165
+ if (match) {
166
+ const functionName = match[1] || '';
167
+ const file = match[2];
168
+ const lineNumber = match[3];
169
+ if (functionName && functionName !== 'anonymous') {
170
+ formatted.push(`${functionName} at ${file}:${lineNumber}`);
171
+ }
172
+ else {
173
+ formatted.push(`${file}:${lineNumber}`);
174
+ }
175
+ }
176
+ }
177
+ return formatted.join('\n');
178
+ }
109
179
  async flush() {
110
180
  await this.provider.forceFlush();
111
181
  }
112
182
  async shutdown() {
183
+ if (this.snapshotClient) {
184
+ this.snapshotClient.stop();
185
+ }
113
186
  await this.provider.shutdown();
114
187
  }
115
188
  isEnabled() {
@@ -121,6 +194,30 @@ class TracekitClient {
121
194
  getTracer() {
122
195
  return this.tracer;
123
196
  }
197
+ getSnapshotClient() {
198
+ return this.snapshotClient;
199
+ }
200
+ async captureSnapshot(label, variables = {}) {
201
+ if (this.snapshotClient) {
202
+ await this.snapshotClient.checkAndCaptureWithContext(label, variables);
203
+ }
204
+ }
205
+ extractServiceName(hostname) {
206
+ if (this.config.serviceNameMappings[hostname]) {
207
+ return this.config.serviceNameMappings[hostname];
208
+ }
209
+ const hostWithoutPort = hostname.split(':')[0];
210
+ if (this.config.serviceNameMappings[hostWithoutPort]) {
211
+ return this.config.serviceNameMappings[hostWithoutPort];
212
+ }
213
+ if (hostname.includes('.svc.cluster.local')) {
214
+ return hostname.split('.')[0];
215
+ }
216
+ if (hostname.includes('.internal')) {
217
+ return hostname.split('.')[0];
218
+ }
219
+ return hostWithoutPort;
220
+ }
124
221
  normalizeAttributes(attributes) {
125
222
  const normalized = {};
126
223
  for (const [key, value] of Object.entries(attributes)) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export declare function init(config: TracekitConfig): TracekitClient;
3
3
  export declare function middleware(): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => Promise<void>;
4
4
  export declare function getClient(): TracekitClient;
5
5
  export { TracekitClient, TracekitConfig } from './client';
6
+ export { SnapshotClient } from './snapshot-client';
6
7
  export { createExpressMiddleware, getCurrentSpan } from './middleware/express';
7
8
  export { Span, Context } from '@opentelemetry/api';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAQ1D,wBAAgB,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAG3D;AAKD,wBAAgB,UAAU,6HAOzB;AAKD,wBAAgB,SAAS,IAAI,cAAc,CAO1C;AAGD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG/E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAS1D,wBAAgB,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAG3D;AAKD,wBAAgB,UAAU,6HAOzB;AAKD,wBAAgB,SAAS,IAAI,cAAc,CAO1C;AAGD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG/E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCurrentSpan = exports.createExpressMiddleware = exports.TracekitClient = void 0;
3
+ exports.getCurrentSpan = exports.createExpressMiddleware = exports.SnapshotClient = exports.TracekitClient = void 0;
4
4
  exports.init = init;
5
5
  exports.middleware = middleware;
6
6
  exports.getClient = getClient;
@@ -15,7 +15,7 @@ function middleware() {
15
15
  if (!globalClient) {
16
16
  throw new Error('TraceKit not initialized. Call tracekit.init() first.');
17
17
  }
18
- return (0, express_1.createExpressMiddleware)(globalClient);
18
+ return (0, express_1.createExpressMiddleware)(globalClient, globalClient.getSnapshotClient());
19
19
  }
20
20
  function getClient() {
21
21
  if (!globalClient) {
@@ -25,6 +25,8 @@ function getClient() {
25
25
  }
26
26
  var client_2 = require("./client");
27
27
  Object.defineProperty(exports, "TracekitClient", { enumerable: true, get: function () { return client_2.TracekitClient; } });
28
+ var snapshot_client_1 = require("./snapshot-client");
29
+ Object.defineProperty(exports, "SnapshotClient", { enumerable: true, get: function () { return snapshot_client_1.SnapshotClient; } });
28
30
  var express_2 = require("./middleware/express");
29
31
  Object.defineProperty(exports, "createExpressMiddleware", { enumerable: true, get: function () { return express_2.createExpressMiddleware; } });
30
32
  Object.defineProperty(exports, "getCurrentSpan", { enumerable: true, get: function () { return express_2.getCurrentSpan; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAQA,oBAGC;AAKD,gCAOC;AAKD,8BAOC;AAnCD,qCAA0D;AAC1D,kDAA+D;AAE/D,IAAI,YAAY,GAA0B,IAAI,CAAC;AAK/C,SAAgB,IAAI,CAAC,MAAsB;IACzC,YAAY,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,YAAY,CAAC;AACtB,CAAC;AAKD,SAAgB,UAAU;IACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,IAAA,iCAAuB,EAAC,YAAY,CAAC,CAAC;AAC/C,CAAC;AAKD,SAAgB,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAGD,mCAA0D;AAAjD,wGAAA,cAAc,OAAA;AACvB,gDAA+E;AAAtE,kHAAA,uBAAuB,OAAA;AAAE,yGAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AASA,oBAGC;AAKD,gCAOC;AAKD,8BAOC;AApCD,qCAA0D;AAC1D,kDAA+D;AAG/D,IAAI,YAAY,GAA0B,IAAI,CAAC;AAK/C,SAAgB,IAAI,CAAC,MAAsB;IACzC,YAAY,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,YAAY,CAAC;AACtB,CAAC;AAKD,SAAgB,UAAU;IACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,IAAA,iCAAuB,EAAC,YAAY,EAAE,YAAY,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACjF,CAAC;AAKD,SAAgB,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAGD,mCAA0D;AAAjD,wGAAA,cAAc,OAAA;AACvB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,gDAA+E;AAAtE,kHAAA,uBAAuB,OAAA;AAAE,yGAAA,cAAc,OAAA"}
@@ -1,6 +1,8 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
2
  import { TracekitClient } from '../client';
3
+ import { SnapshotClient } from '../snapshot-client';
3
4
  import * as api from '@opentelemetry/api';
4
- export declare function createExpressMiddleware(client: TracekitClient): (req: Request, res: Response, next: NextFunction) => Promise<void>;
5
+ export declare function createExpressMiddleware(client: TracekitClient, snapshotClient?: SnapshotClient): (req: Request, res: Response, next: NextFunction) => Promise<void>;
5
6
  export declare function getCurrentSpan(req: Request): api.Span | null;
7
+ export declare function getRequestContext(): Record<string, any> | undefined;
6
8
  //# sourceMappingURL=express.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAE1C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,IAC9C,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAwD9D;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAE5D"}
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAS1C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,EAAE,cAAc,IAC/E,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAwF9D;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAE5D;AAGD,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAEnE"}
@@ -1,50 +1,113 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.createExpressMiddleware = createExpressMiddleware;
4
37
  exports.getCurrentSpan = getCurrentSpan;
5
- function createExpressMiddleware(client) {
38
+ exports.getRequestContext = getRequestContext;
39
+ const async_hooks_1 = require("async_hooks");
40
+ const api = __importStar(require("@opentelemetry/api"));
41
+ const core_1 = require("@opentelemetry/core");
42
+ const requestContextStorage = new async_hooks_1.AsyncLocalStorage();
43
+ const propagator = new core_1.W3CTraceContextPropagator();
44
+ function createExpressMiddleware(client, snapshotClient) {
6
45
  return async (req, res, next) => {
7
46
  if (!client.isEnabled() || !client.shouldSample()) {
8
47
  return next();
9
48
  }
10
49
  const startTime = Date.now();
11
50
  const operationName = getOperationName(req);
12
- const span = client.startTrace(operationName, {
13
- 'http.method': req.method,
14
- 'http.url': req.originalUrl || req.url,
15
- 'http.route': req.route?.path || req.path,
16
- 'http.user_agent': req.get('user-agent') || '',
17
- 'http.client_ip': getClientIp(req),
51
+ const parentContext = propagator.extract(api.context.active(), req.headers, {
52
+ get(carrier, key) {
53
+ return carrier[key.toLowerCase()];
54
+ },
55
+ keys(carrier) {
56
+ return Object.keys(carrier);
57
+ },
58
+ });
59
+ const span = api.context.with(parentContext, () => {
60
+ return client.startServerSpan(operationName, {
61
+ 'http.method': req.method,
62
+ 'http.url': req.originalUrl || req.url,
63
+ 'http.route': req.route?.path || req.path,
64
+ 'http.user_agent': req.get('user-agent') || '',
65
+ 'http.client_ip': getClientIp(req),
66
+ });
18
67
  });
19
68
  req.__tracekitSpan = span;
20
- const originalSend = res.send;
21
- let responseSent = false;
22
- res.send = function (body) {
23
- if (!responseSent) {
24
- responseSent = true;
25
- const durationMs = Date.now() - startTime;
26
- client.endSpan(span, {
27
- 'http.status_code': res.statusCode,
28
- 'http.duration_ms': durationMs,
29
- }, res.statusCode >= 400 ? 'ERROR' : 'OK');
30
- }
31
- return originalSend.call(this, body);
69
+ const requestContext = {
70
+ method: req.method,
71
+ path: req.path,
72
+ url: req.originalUrl,
73
+ ip: getClientIp(req),
74
+ user_agent: req.get('user-agent') || '',
75
+ query: req.query,
76
+ headers: filterHeaders(req.headers),
32
77
  };
33
- try {
34
- next();
35
- }
36
- catch (error) {
37
- if (error instanceof Error) {
38
- client.recordException(span, error);
39
- client.endSpan(span, {}, 'ERROR');
78
+ requestContextStorage.run(requestContext, () => {
79
+ const originalSend = res.send;
80
+ let responseSent = false;
81
+ res.send = function (body) {
82
+ if (!responseSent) {
83
+ responseSent = true;
84
+ const durationMs = Date.now() - startTime;
85
+ client.endSpan(span, {
86
+ 'http.status_code': res.statusCode,
87
+ 'http.duration_ms': durationMs,
88
+ }, res.statusCode >= 400 ? 'ERROR' : 'OK');
89
+ }
90
+ return originalSend.call(this, body);
91
+ };
92
+ try {
93
+ next();
40
94
  }
41
- throw error;
42
- }
95
+ catch (error) {
96
+ if (error instanceof Error) {
97
+ client.recordException(span, error);
98
+ client.endSpan(span, {}, 'ERROR');
99
+ }
100
+ throw error;
101
+ }
102
+ });
43
103
  };
44
104
  }
45
105
  function getCurrentSpan(req) {
46
106
  return req.__tracekitSpan || null;
47
107
  }
108
+ function getRequestContext() {
109
+ return requestContextStorage.getStore();
110
+ }
48
111
  function getOperationName(req) {
49
112
  if (req.route?.path) {
50
113
  return `${req.method} ${req.route.path}`;
@@ -57,4 +120,14 @@ function getClientIp(req) {
57
120
  req.socket.remoteAddress ||
58
121
  '');
59
122
  }
123
+ function filterHeaders(headers) {
124
+ const filtered = {};
125
+ const allowlist = ['content-type', 'content-length', 'host', 'user-agent', 'referer'];
126
+ for (const key of allowlist) {
127
+ if (headers[key]) {
128
+ filtered[key] = headers[key];
129
+ }
130
+ }
131
+ return filtered;
132
+ }
60
133
  //# sourceMappingURL=express.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":";;AAIA,0DAyDC;AAGD,wCAEC;AA9DD,SAAgB,uBAAuB,CAAC,MAAsB;IAC5D,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAE/D,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC;YAClD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAG7B,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAG5C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE;YAC5C,aAAa,EAAE,GAAG,CAAC,MAAM;YACzB,UAAU,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG;YACtC,YAAY,EAAG,GAAG,CAAC,KAAK,EAAE,IAAe,IAAI,GAAG,CAAC,IAAI;YACrD,iBAAiB,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE;YAC9C,gBAAgB,EAAE,WAAW,CAAC,GAAG,CAAC;SACnC,CAAC,CAAC;QAGF,GAAW,CAAC,cAAc,GAAG,IAAI,CAAC;QAGnC,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC;QAC9B,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,GAAG,CAAC,IAAI,GAAG,UAAU,IAAS;YAC5B,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,YAAY,GAAG,IAAI,CAAC;gBACpB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAE1C,MAAM,CAAC,OAAO,CACZ,IAAI,EACJ;oBACE,kBAAkB,EAAE,GAAG,CAAC,UAAU;oBAClC,kBAAkB,EAAE,UAAU;iBAC/B,EACD,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACvC,CAAC;YACJ,CAAC;YAED,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;QAGF,IAAI,CAAC;YACH,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACpC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAGD,SAAgB,cAAc,CAAC,GAAY;IACzC,OAAQ,GAAW,CAAC,cAAc,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY;IAEpC,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QACpB,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAGD,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,OAAO,CACJ,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE;QAChE,GAAG,CAAC,OAAO,CAAC,WAAW,CAAY;QACpC,GAAG,CAAC,MAAM,CAAC,aAAa;QACxB,EAAE,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- import { DynamicModule } from '@nestjs/common';
1
+ import { DynamicModule, OnModuleDestroy } from '@nestjs/common';
2
2
  import { TracekitConfig } from '../client';
3
- export declare class TracekitModule {
3
+ export declare class TracekitModule implements OnModuleDestroy {
4
4
  static forRoot(config: TracekitConfig): DynamicModule;
5
5
  static forRootAsync(options: {
6
6
  useFactory: (...args: any[]) => Promise<TracekitConfig> | TracekitConfig;
7
7
  inject?: any[];
8
8
  }): DynamicModule;
9
+ onModuleDestroy(): Promise<void>;
9
10
  }
10
11
  //# sourceMappingURL=tracekit.module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracekit.module.d.ts","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAkB,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3D,qBAEa,cAAc;IACzB,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa;IAoBrD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;QAC3B,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;QACzE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,GAAG,aAAa;CAqBlB"}
1
+ {"version":3,"file":"tracekit.module.d.ts","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAU,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,EAAkB,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3D,qBAEa,cAAe,YAAW,eAAe;IACpD,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa;IA0BrD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;QAC3B,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;QACzE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,GAAG,aAAa;IAgCX,eAAe;CAGtB"}
@@ -14,11 +14,15 @@ const client_1 = require("../client");
14
14
  const tracekit_interceptor_1 = require("./tracekit.interceptor");
15
15
  let TracekitModule = TracekitModule_1 = class TracekitModule {
16
16
  static forRoot(config) {
17
+ const client = new client_1.TracekitClient(config);
18
+ const snapshotClient = client.getSnapshotClient();
17
19
  const clientProvider = {
18
20
  provide: 'TRACEKIT_CLIENT',
19
- useFactory: () => {
20
- return new client_1.TracekitClient(config);
21
- },
21
+ useValue: client,
22
+ };
23
+ const snapshotClientProvider = {
24
+ provide: 'TRACEKIT_SNAPSHOT_CLIENT',
25
+ useValue: snapshotClient,
22
26
  };
23
27
  const interceptorProvider = {
24
28
  provide: core_1.APP_INTERCEPTOR,
@@ -26,8 +30,8 @@ let TracekitModule = TracekitModule_1 = class TracekitModule {
26
30
  };
27
31
  return {
28
32
  module: TracekitModule_1,
29
- providers: [clientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
30
- exports: ['TRACEKIT_CLIENT'],
33
+ providers: [clientProvider, snapshotClientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
34
+ exports: ['TRACEKIT_CLIENT', 'TRACEKIT_SNAPSHOT_CLIENT'],
31
35
  };
32
36
  }
33
37
  static forRootAsync(options) {
@@ -39,16 +43,27 @@ let TracekitModule = TracekitModule_1 = class TracekitModule {
39
43
  },
40
44
  inject: options.inject || [],
41
45
  };
46
+ const snapshotClientProvider = {
47
+ provide: 'TRACEKIT_SNAPSHOT_CLIENT',
48
+ useFactory: async (...args) => {
49
+ const config = await options.useFactory(...args);
50
+ const client = new client_1.TracekitClient(config);
51
+ return client.getSnapshotClient();
52
+ },
53
+ inject: options.inject || [],
54
+ };
42
55
  const interceptorProvider = {
43
56
  provide: core_1.APP_INTERCEPTOR,
44
57
  useClass: tracekit_interceptor_1.TracekitInterceptor,
45
58
  };
46
59
  return {
47
60
  module: TracekitModule_1,
48
- providers: [clientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
49
- exports: ['TRACEKIT_CLIENT'],
61
+ providers: [clientProvider, snapshotClientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
62
+ exports: ['TRACEKIT_CLIENT', 'TRACEKIT_SNAPSHOT_CLIENT'],
50
63
  };
51
64
  }
65
+ async onModuleDestroy() {
66
+ }
52
67
  };
53
68
  exports.TracekitModule = TracekitModule;
54
69
  exports.TracekitModule = TracekitModule = TracekitModule_1 = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"tracekit.module.js","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAC/D,uCAA+C;AAC/C,sCAA2D;AAC3D,iEAA6D;AAItD,IAAM,cAAc,sBAApB,MAAM,cAAc;IACzB,MAAM,CAAC,OAAO,CAAC,MAAsB;QACnC,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iBAAiB;YAC1B,UAAU,EAAE,GAAG,EAAE;gBACf,OAAO,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;SACF,CAAC;QAEF,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,sBAAe;YACxB,QAAQ,EAAE,0CAAmB;SAC9B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE,CAAC,cAAc,EAAE,mBAAmB,EAAE,0CAAmB,CAAC;YACrE,OAAO,EAAE,CAAC,iBAAiB,CAAC;SAC7B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAGnB;QACC,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iBAAiB;YAC1B,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjD,OAAO,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,sBAAe;YACxB,QAAQ,EAAE,0CAAmB;SAC9B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE,CAAC,cAAc,EAAE,mBAAmB,EAAE,0CAAmB,CAAC;YACrE,OAAO,EAAE,CAAC,iBAAiB,CAAC;SAC7B,CAAC;IACJ,CAAC;CACF,CAAA;AA7CY,wCAAc;yBAAd,cAAc;IAF1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CA6C1B"}
1
+ {"version":3,"file":"tracekit.module.js","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAgF;AAChF,uCAA+C;AAC/C,sCAA2D;AAC3D,iEAA6D;AAItD,IAAM,cAAc,sBAApB,MAAM,cAAc;IACzB,MAAM,CAAC,OAAO,CAAC,MAAsB;QACnC,MAAM,MAAM,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAElD,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iBAAiB;YAC1B,QAAQ,EAAE,MAAM;SACjB,CAAC;QAEF,MAAM,sBAAsB,GAAG;YAC7B,OAAO,EAAE,0BAA0B;YACnC,QAAQ,EAAE,cAAc;SACzB,CAAC;QAEF,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,sBAAe;YACxB,QAAQ,EAAE,0CAAmB;SAC9B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE,CAAC,cAAc,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,0CAAmB,CAAC;YAC7F,OAAO,EAAE,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAGnB;QACC,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iBAAiB;YAC1B,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjD,OAAO,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,MAAM,sBAAsB,GAAG;YAC7B,OAAO,EAAE,0BAA0B;YACnC,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;gBAC1C,OAAO,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACpC,CAAC;YACD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,sBAAe;YACxB,QAAQ,EAAE,0CAAmB;SAC9B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE,CAAC,cAAc,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,0CAAmB,CAAC;YAC7F,OAAO,EAAE,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe;IAErB,CAAC;CACF,CAAA;AAjEY,wCAAc;yBAAd,cAAc;IAF1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAiE1B"}
@@ -0,0 +1,48 @@
1
+ export interface BreakpointConfig {
2
+ id: string;
3
+ service_name: string;
4
+ file_path: string;
5
+ function_name: string;
6
+ label?: string;
7
+ line_number: number;
8
+ condition?: string;
9
+ max_captures: number;
10
+ capture_count: number;
11
+ expire_at?: Date;
12
+ enabled: boolean;
13
+ }
14
+ export interface Snapshot {
15
+ breakpoint_id?: string;
16
+ service_name: string;
17
+ file_path: string;
18
+ function_name: string;
19
+ label?: string;
20
+ line_number: number;
21
+ variables: Record<string, any>;
22
+ stack_trace: string;
23
+ trace_id?: string;
24
+ span_id?: string;
25
+ request_context?: Record<string, any>;
26
+ captured_at: Date;
27
+ }
28
+ export declare class SnapshotClient {
29
+ private apiKey;
30
+ private baseURL;
31
+ private serviceName;
32
+ private breakpointsCache;
33
+ private registrationCache;
34
+ private pollInterval?;
35
+ private lastFetch?;
36
+ constructor(apiKey: string, baseURL: string, serviceName: string);
37
+ start(): void;
38
+ stop(): void;
39
+ checkAndCaptureWithContext(label: string, variables?: Record<string, any>): Promise<void>;
40
+ private parseStackTrace;
41
+ private fetchActiveBreakpoints;
42
+ private updateBreakpointCache;
43
+ private autoRegisterBreakpoint;
44
+ private captureSnapshot;
45
+ private extractRequestContext;
46
+ private sanitizeVariables;
47
+ }
48
+ //# sourceMappingURL=snapshot-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-client.d.ts","sourceRoot":"","sources":["../src/snapshot-client.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,SAAS,CAAC,CAAO;gBAEb,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAOhE,KAAK,IAAI,IAAI;IAUb,IAAI,IAAI,IAAI;IASN,0BAA0B,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,OAAO,CAAC,IAAI,CAAC;IAqEhB,OAAO,CAAC,eAAe;YA+BT,sBAAsB;IAsBpC,OAAO,CAAC,qBAAqB;YAqBf,sBAAsB;YAiCtB,eAAe;IAsB7B,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,iBAAiB;CAc1B"}
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnapshotClient = void 0;
4
+ const express_1 = require("./middleware/express");
5
+ class SnapshotClient {
6
+ constructor(apiKey, baseURL, serviceName) {
7
+ this.breakpointsCache = new Map();
8
+ this.registrationCache = new Set();
9
+ this.apiKey = apiKey;
10
+ this.baseURL = baseURL;
11
+ this.serviceName = serviceName;
12
+ }
13
+ start() {
14
+ this.fetchActiveBreakpoints();
15
+ this.pollInterval = setInterval(() => this.fetchActiveBreakpoints(), 30000);
16
+ console.log(`📸 TraceKit Snapshot Client started for service: ${this.serviceName}`);
17
+ }
18
+ stop() {
19
+ if (this.pollInterval) {
20
+ clearInterval(this.pollInterval);
21
+ this.pollInterval = undefined;
22
+ }
23
+ console.log('📸 TraceKit Snapshot Client stopped');
24
+ }
25
+ async checkAndCaptureWithContext(label, variables = {}) {
26
+ const stack = new Error().stack || '';
27
+ const caller = this.parseStackTrace(stack);
28
+ if (!caller) {
29
+ console.warn('⚠️ Could not detect caller location');
30
+ return;
31
+ }
32
+ const { file, line, functionName } = caller;
33
+ const locationKey = `${functionName}:${label}`;
34
+ if (!this.registrationCache.has(locationKey)) {
35
+ const breakpoint = await this.autoRegisterBreakpoint({
36
+ file_path: file,
37
+ line_number: line,
38
+ function_name: functionName,
39
+ label,
40
+ });
41
+ if (breakpoint) {
42
+ this.registrationCache.add(locationKey);
43
+ this.breakpointsCache.set(locationKey, breakpoint);
44
+ }
45
+ else {
46
+ return;
47
+ }
48
+ }
49
+ const breakpoint = this.breakpointsCache.get(locationKey);
50
+ if (!breakpoint || !breakpoint.enabled) {
51
+ return;
52
+ }
53
+ if (breakpoint.expire_at && new Date() > breakpoint.expire_at) {
54
+ return;
55
+ }
56
+ if (breakpoint.max_captures > 0 && breakpoint.capture_count >= breakpoint.max_captures) {
57
+ return;
58
+ }
59
+ const requestContext = this.extractRequestContext();
60
+ const snapshot = {
61
+ breakpoint_id: breakpoint.id,
62
+ service_name: this.serviceName,
63
+ file_path: file,
64
+ function_name: functionName,
65
+ label,
66
+ line_number: line,
67
+ variables: this.sanitizeVariables(variables),
68
+ stack_trace: stack,
69
+ request_context: requestContext,
70
+ captured_at: new Date(),
71
+ };
72
+ await this.captureSnapshot(snapshot);
73
+ }
74
+ parseStackTrace(stack) {
75
+ const lines = stack.split('\n');
76
+ const callerLine = lines[3]?.trim();
77
+ if (!callerLine)
78
+ return null;
79
+ const match = callerLine.match(/at\s+(?:([^\s]+)\s+\()?([^:]+):(\d+):\d+\)?/);
80
+ if (!match)
81
+ return null;
82
+ const functionName = match[1] || 'anonymous';
83
+ const file = match[2];
84
+ const line = parseInt(match[3], 10);
85
+ return { file, line, functionName };
86
+ }
87
+ async fetchActiveBreakpoints() {
88
+ try {
89
+ const url = `${this.baseURL}/sdk/snapshots/active/${this.serviceName}`;
90
+ const response = await fetch(url, {
91
+ headers: {
92
+ 'X-API-Key': this.apiKey,
93
+ },
94
+ });
95
+ if (!response.ok) {
96
+ throw new Error(`HTTP ${response.status}`);
97
+ }
98
+ const data = await response.json();
99
+ this.updateBreakpointCache(data.breakpoints || []);
100
+ this.lastFetch = new Date();
101
+ }
102
+ catch (error) {
103
+ console.error('⚠️ Failed to fetch breakpoints:', error);
104
+ }
105
+ }
106
+ updateBreakpointCache(breakpoints) {
107
+ this.breakpointsCache.clear();
108
+ for (const bp of breakpoints) {
109
+ if (bp.label && bp.function_name) {
110
+ const labelKey = `${bp.function_name}:${bp.label}`;
111
+ this.breakpointsCache.set(labelKey, bp);
112
+ }
113
+ const lineKey = `${bp.file_path}:${bp.line_number}`;
114
+ this.breakpointsCache.set(lineKey, bp);
115
+ }
116
+ if (breakpoints.length > 0) {
117
+ console.log(`📸 Updated breakpoint cache: ${breakpoints.length} active breakpoints`);
118
+ }
119
+ }
120
+ async autoRegisterBreakpoint(data) {
121
+ try {
122
+ const response = await fetch(`${this.baseURL}/sdk/snapshots/auto-register`, {
123
+ method: 'POST',
124
+ headers: {
125
+ 'X-API-Key': this.apiKey,
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ body: JSON.stringify({
129
+ service_name: this.serviceName,
130
+ ...data,
131
+ }),
132
+ });
133
+ if (!response.ok) {
134
+ console.error('⚠️ Failed to auto-register breakpoint:', response.status);
135
+ return null;
136
+ }
137
+ const result = await response.json();
138
+ return result;
139
+ }
140
+ catch (error) {
141
+ console.error('⚠️ Failed to auto-register breakpoint:', error);
142
+ return null;
143
+ }
144
+ }
145
+ async captureSnapshot(snapshot) {
146
+ try {
147
+ const response = await fetch(`${this.baseURL}/sdk/snapshots/capture`, {
148
+ method: 'POST',
149
+ headers: {
150
+ 'X-API-Key': this.apiKey,
151
+ 'Content-Type': 'application/json',
152
+ },
153
+ body: JSON.stringify(snapshot),
154
+ });
155
+ if (!response.ok) {
156
+ console.error('⚠️ Failed to capture snapshot:', response.status);
157
+ }
158
+ else {
159
+ console.log(`📸 Snapshot captured: ${snapshot.label || snapshot.file_path}`);
160
+ }
161
+ }
162
+ catch (error) {
163
+ console.error('⚠️ Failed to capture snapshot:', error);
164
+ }
165
+ }
166
+ extractRequestContext() {
167
+ return (0, express_1.getRequestContext)();
168
+ }
169
+ sanitizeVariables(variables) {
170
+ const sanitized = {};
171
+ for (const [key, value] of Object.entries(variables)) {
172
+ try {
173
+ JSON.stringify(value);
174
+ sanitized[key] = value;
175
+ }
176
+ catch {
177
+ sanitized[key] = `[${typeof value}]`;
178
+ }
179
+ }
180
+ return sanitized;
181
+ }
182
+ }
183
+ exports.SnapshotClient = SnapshotClient;
184
+ //# sourceMappingURL=snapshot-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-client.js","sourceRoot":"","sources":["../src/snapshot-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tracekit/node-apm",
3
- "version": "1.0.2",
4
- "description": "TraceKit APM for Node.js - Zero-config distributed tracing for Express and NestJS",
3
+ "version": "1.2.0",
4
+ "description": "TraceKit APM for Node.js - Zero-config distributed tracing and code monitoring for Express and NestJS",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
@@ -38,15 +38,18 @@
38
38
  "homepage": "https://tracekit.dev",
39
39
  "dependencies": {
40
40
  "@opentelemetry/api": "^1.7.0",
41
- "@opentelemetry/sdk-trace-node": "^1.19.0",
42
41
  "@opentelemetry/exporter-trace-otlp-http": "^0.46.0",
42
+ "@opentelemetry/instrumentation": "^0.56.0",
43
+ "@opentelemetry/instrumentation-fetch": "^0.56.0",
44
+ "@opentelemetry/instrumentation-http": "^0.56.0",
43
45
  "@opentelemetry/resources": "^1.19.0",
46
+ "@opentelemetry/sdk-trace-node": "^1.19.0",
44
47
  "@opentelemetry/semantic-conventions": "^1.19.0"
45
48
  },
46
49
  "peerDependencies": {
47
- "express": "^4.18.0 || ^5.0.0",
48
50
  "@nestjs/common": "^10.0.0",
49
- "@nestjs/core": "^10.0.0"
51
+ "@nestjs/core": "^10.0.0",
52
+ "express": "^4.18.0 || ^5.0.0"
50
53
  },
51
54
  "peerDependenciesMeta": {
52
55
  "express": {
@@ -60,12 +63,12 @@
60
63
  }
61
64
  },
62
65
  "devDependencies": {
63
- "@types/express": "^4.17.21",
64
- "@types/node": "^20.10.0",
65
66
  "@nestjs/common": "^10.0.0",
66
67
  "@nestjs/core": "^10.0.0",
67
- "typescript": "^5.3.0",
68
- "express": "^4.18.0"
68
+ "@types/express": "^4.17.21",
69
+ "@types/node": "^20.10.0",
70
+ "express": "^4.18.0",
71
+ "typescript": "^5.3.0"
69
72
  },
70
73
  "engines": {
71
74
  "node": ">=16.0.0"