@pingops/core 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/index.cjs +824 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.cts +306 -0
  4. package/dist/index.d.cts.map +1 -0
  5. package/dist/index.d.mts +306 -0
  6. package/dist/index.d.mts.map +1 -0
  7. package/dist/index.mjs +804 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +17 -5
  10. package/dist/context-keys.d.ts +0 -30
  11. package/dist/context-keys.d.ts.map +0 -1
  12. package/dist/context-keys.js +0 -31
  13. package/dist/context-keys.js.map +0 -1
  14. package/dist/filtering/domain-filter.d.ts +0 -9
  15. package/dist/filtering/domain-filter.d.ts.map +0 -1
  16. package/dist/filtering/domain-filter.js +0 -136
  17. package/dist/filtering/domain-filter.js.map +0 -1
  18. package/dist/filtering/header-filter.d.ts +0 -31
  19. package/dist/filtering/header-filter.d.ts.map +0 -1
  20. package/dist/filtering/header-filter.js +0 -187
  21. package/dist/filtering/header-filter.js.map +0 -1
  22. package/dist/filtering/span-filter.d.ts +0 -13
  23. package/dist/filtering/span-filter.d.ts.map +0 -1
  24. package/dist/filtering/span-filter.js +0 -46
  25. package/dist/filtering/span-filter.js.map +0 -1
  26. package/dist/index.d.ts +0 -13
  27. package/dist/index.d.ts.map +0 -1
  28. package/dist/index.js +0 -13
  29. package/dist/index.js.map +0 -1
  30. package/dist/logger.d.ts +0 -21
  31. package/dist/logger.d.ts.map +0 -1
  32. package/dist/logger.js +0 -36
  33. package/dist/logger.js.map +0 -1
  34. package/dist/transport/client.d.ts +0 -46
  35. package/dist/transport/client.d.ts.map +0 -1
  36. package/dist/transport/client.js +0 -110
  37. package/dist/transport/client.js.map +0 -1
  38. package/dist/types.d.ts +0 -34
  39. package/dist/types.d.ts.map +0 -1
  40. package/dist/types.js +0 -5
  41. package/dist/types.js.map +0 -1
  42. package/dist/utils/context-extractor.d.ts +0 -13
  43. package/dist/utils/context-extractor.d.ts.map +0 -1
  44. package/dist/utils/context-extractor.js +0 -44
  45. package/dist/utils/context-extractor.js.map +0 -1
  46. package/dist/utils/span-extractor.d.ts +0 -10
  47. package/dist/utils/span-extractor.d.ts.map +0 -1
  48. package/dist/utils/span-extractor.js +0 -125
  49. package/dist/utils/span-extractor.js.map +0 -1
  50. package/dist/wrap-http.d.ts +0 -55
  51. package/dist/wrap-http.d.ts.map +0 -1
  52. package/dist/wrap-http.js +0 -129
  53. package/dist/wrap-http.js.map +0 -1
@@ -0,0 +1,306 @@
1
+ import { Context } from "@opentelemetry/api";
2
+ import { ReadableSpan } from "@opentelemetry/sdk-trace-base";
3
+
4
+ //#region src/types.d.ts
5
+ /**
6
+ * Shared type definitions for PingOps SDK
7
+ */
8
+ interface DomainRule {
9
+ domain: string;
10
+ paths?: string[];
11
+ headersAllowList?: string[];
12
+ headersDenyList?: string[];
13
+ captureRequestBody?: boolean;
14
+ captureResponseBody?: boolean;
15
+ }
16
+ interface SpanPayload {
17
+ traceId: string;
18
+ spanId: string;
19
+ parentSpanId?: string;
20
+ name: string;
21
+ kind: string;
22
+ startTime: string;
23
+ endTime: string;
24
+ duration: number;
25
+ attributes: Record<string, unknown>;
26
+ status: {
27
+ code: string;
28
+ message?: string;
29
+ };
30
+ }
31
+ /**
32
+ * Attributes to propagate to HTTP spans
33
+ */
34
+ interface WrapHttpAttributes {
35
+ userId?: string;
36
+ sessionId?: string;
37
+ tags?: string[];
38
+ metadata?: Record<string, string>;
39
+ /**
40
+ * Whether to capture request body for HTTP spans in this context.
41
+ * Takes precedence over domain-specific rules and global config.
42
+ */
43
+ captureRequestBody?: boolean;
44
+ /**
45
+ * Whether to capture response body for HTTP spans in this context.
46
+ * Takes precedence over domain-specific rules and global config.
47
+ */
48
+ captureResponseBody?: boolean;
49
+ }
50
+ //#endregion
51
+ //#region src/filtering/span-filter.d.ts
52
+ /**
53
+ * Checks if a span is eligible for capture based on span kind and attributes.
54
+ * A span is eligible if:
55
+ * 1. span.kind === SpanKind.CLIENT
56
+ * 2. AND has HTTP attributes (http.method, http.url, or server.address)
57
+ * OR has GenAI attributes (gen_ai.system, gen_ai.operation.name)
58
+ */
59
+ declare function isSpanEligible(span: ReadableSpan): boolean;
60
+ //#endregion
61
+ //#region src/filtering/domain-filter.d.ts
62
+ /**
63
+ * Determines if a span should be captured based on domain rules
64
+ */
65
+ declare function shouldCaptureSpan(url: string, domainAllowList?: DomainRule[], domainDenyList?: DomainRule[]): boolean;
66
+ //#endregion
67
+ //#region src/filtering/sensitive-headers.d.ts
68
+ /**
69
+ * Sensitive header patterns and redaction configuration
70
+ */
71
+ /**
72
+ * Default patterns for sensitive headers that should be redacted
73
+ * These are matched case-insensitively
74
+ */
75
+ declare const DEFAULT_SENSITIVE_HEADER_PATTERNS: readonly ["authorization", "www-authenticate", "proxy-authenticate", "proxy-authorization", "x-auth-token", "x-api-key", "x-api-token", "x-access-token", "x-auth-user", "x-auth-password", "x-csrf-token", "x-xsrf-token", "api-key", "apikey", "api_key", "access-key", "accesskey", "access_key", "secret-key", "secretkey", "secret_key", "private-key", "privatekey", "private_key", "cookie", "set-cookie", "session-id", "sessionid", "session_id", "session-token", "sessiontoken", "session_token", "oauth-token", "oauth_token", "oauth2-token", "oauth2_token", "bearer", "x-amz-security-token", "x-amz-signature", "x-aws-access-key", "x-aws-secret-key", "x-aws-session-token", "x-password", "x-secret", "x-token", "x-jwt", "x-jwt-token", "x-refresh-token", "x-client-secret", "x-client-id", "x-user-token", "x-service-key"];
76
+ /**
77
+ * Redaction strategies for sensitive header values
78
+ */
79
+ declare enum HeaderRedactionStrategy {
80
+ /**
81
+ * Replace the entire value with a fixed redaction string
82
+ */
83
+ REPLACE = "replace",
84
+ /**
85
+ * Show only the first N characters, redact the rest
86
+ */
87
+ PARTIAL = "partial",
88
+ /**
89
+ * Show only the last N characters, redact the rest
90
+ */
91
+ PARTIAL_END = "partial_end",
92
+ /**
93
+ * Remove the header entirely (same as deny list)
94
+ */
95
+ REMOVE = "remove",
96
+ }
97
+ /**
98
+ * Configuration for header redaction
99
+ */
100
+ interface HeaderRedactionConfig {
101
+ /**
102
+ * Patterns to match sensitive headers (case-insensitive)
103
+ * Defaults to DEFAULT_SENSITIVE_HEADER_PATTERNS if not provided
104
+ */
105
+ sensitivePatterns?: readonly string[];
106
+ /**
107
+ * Redaction strategy to use
108
+ * @default HeaderRedactionStrategy.REPLACE
109
+ */
110
+ strategy?: HeaderRedactionStrategy;
111
+ /**
112
+ * Redaction string used when strategy is REPLACE
113
+ * @default "[REDACTED]"
114
+ */
115
+ redactionString?: string;
116
+ /**
117
+ * Number of characters to show when strategy is PARTIAL or PARTIAL_END
118
+ * @default 4
119
+ */
120
+ visibleChars?: number;
121
+ /**
122
+ * Whether to enable redaction
123
+ * @default true
124
+ */
125
+ enabled?: boolean;
126
+ }
127
+ /**
128
+ * Default redaction configuration
129
+ */
130
+ declare const DEFAULT_REDACTION_CONFIG: Required<HeaderRedactionConfig>;
131
+ /**
132
+ * Checks if a header name matches any sensitive pattern
133
+ * Uses case-insensitive matching with exact match, prefix/suffix, and substring matching
134
+ *
135
+ * @param headerName - The header name to check
136
+ * @param patterns - Array of patterns to match against (defaults to DEFAULT_SENSITIVE_HEADER_PATTERNS)
137
+ * @returns true if the header matches any sensitive pattern
138
+ */
139
+ declare function isSensitiveHeader(headerName: string, patterns?: readonly string[]): boolean;
140
+ /**
141
+ * Redacts a header value based on the configuration
142
+ */
143
+ declare function redactHeaderValue(value: string | string[] | undefined, config: Required<HeaderRedactionConfig>): string | string[] | undefined;
144
+ //#endregion
145
+ //#region src/filtering/header-filter.d.ts
146
+ /**
147
+ * Filters headers based on allow/deny lists and applies redaction to sensitive headers
148
+ * - Deny list always wins (if header is in deny list, exclude it)
149
+ * - Allow list filters included headers (if specified, only include these)
150
+ * - Sensitive headers are redacted after filtering (if redaction is enabled)
151
+ * - Case-insensitive matching
152
+ *
153
+ * @param headers - Headers to filter
154
+ * @param headersAllowList - Optional allow list of header names to include
155
+ * @param headersDenyList - Optional deny list of header names to exclude
156
+ * @param redactionConfig - Optional configuration for header value redaction
157
+ * @returns Filtered and redacted headers
158
+ */
159
+ declare function filterHeaders(headers: Record<string, string | string[] | undefined>, headersAllowList?: string[], headersDenyList?: string[], redactionConfig?: HeaderRedactionConfig): Record<string, string | string[] | undefined>;
160
+ /**
161
+ * Extracts and normalizes headers from OpenTelemetry span attributes
162
+ *
163
+ * Handles flat array format headers (e.g., 'http.request.header.0', 'http.request.header.1')
164
+ * and converts them to proper key-value objects.
165
+ *
166
+ * Some OpenTelemetry instrumentations store headers as flat arrays:
167
+ * - 'http.request.header.0': 'Content-Type'
168
+ * - 'http.request.header.1': 'application/json'
169
+ * - 'http.request.header.2': 'Authorization'
170
+ * - 'http.request.header.3': 'Bearer token'
171
+ *
172
+ * This function converts them to:
173
+ * - { 'Content-Type': 'application/json', 'Authorization': 'Bearer token' }
174
+ */
175
+ declare function extractHeadersFromAttributes(attributes: Record<string, unknown>, headerPrefix: "http.request.header" | "http.response.header"): Record<string, string | string[] | undefined> | null;
176
+ /**
177
+ * Normalizes headers from various sources into a proper key-value object
178
+ */
179
+ declare function normalizeHeaders(headers: unknown): Record<string, string | string[] | undefined>;
180
+ //#endregion
181
+ //#region src/utils/span-extractor.d.ts
182
+ /**
183
+ * Extracts structured payload from a span
184
+ */
185
+ declare function extractSpanPayload(span: ReadableSpan, domainAllowList?: DomainRule[], globalHeadersAllowList?: string[], globalHeadersDenyList?: string[], globalCaptureRequestBody?: boolean, globalCaptureResponseBody?: boolean, headerRedaction?: HeaderRedactionConfig): SpanPayload | null;
186
+ //#endregion
187
+ //#region src/utils/context-extractor.d.ts
188
+ /**
189
+ * Extracts propagated attributes from the given context and returns them
190
+ * as span attributes that can be set on a span.
191
+ *
192
+ * @param parentContext - The OpenTelemetry context to extract attributes from
193
+ * @returns Record of attribute key-value pairs to set on spans
194
+ */
195
+ declare function getPropagatedAttributesFromContext(parentContext: Context): Record<string, string | string[]>;
196
+ //#endregion
197
+ //#region src/logger.d.ts
198
+ /**
199
+ * Global logger utility for PingOps Core
200
+ *
201
+ * Provides consistent logging across all core components with support for
202
+ * different log levels and debug mode control via PINGOPS_DEBUG environment variable.
203
+ */
204
+ type LogLevel = "debug" | "info" | "warn" | "error";
205
+ interface Logger {
206
+ debug(message: string, ...args: unknown[]): void;
207
+ info(message: string, ...args: unknown[]): void;
208
+ warn(message: string, ...args: unknown[]): void;
209
+ error(message: string, ...args: unknown[]): void;
210
+ }
211
+ /**
212
+ * Creates a logger instance with a specific prefix
213
+ *
214
+ * @param prefix - Prefix to add to all log messages (e.g., '[PingOps Filter]')
215
+ * @returns Logger instance
216
+ */
217
+ declare function createLogger(prefix: string): Logger;
218
+ //#endregion
219
+ //#region src/context-keys.d.ts
220
+ /**
221
+ * OpenTelemetry context keys for PingOps
222
+ */
223
+ /**
224
+ * Context key for enabling HTTP instrumentation.
225
+ * When set to true, HTTP requests will be automatically instrumented.
226
+ * This allows wrapHttp to control which HTTP calls are captured.
227
+ */
228
+ declare const PINGOPS_HTTP_ENABLED: symbol;
229
+ /**
230
+ * Context key for user ID attribute.
231
+ * Used to propagate user identifier to all spans in the context.
232
+ */
233
+ declare const PINGOPS_USER_ID: symbol;
234
+ /**
235
+ * Context key for session ID attribute.
236
+ * Used to propagate session identifier to all spans in the context.
237
+ */
238
+ declare const PINGOPS_SESSION_ID: symbol;
239
+ /**
240
+ * Context key for tags attribute.
241
+ * Used to propagate tags array to all spans in the context.
242
+ */
243
+ declare const PINGOPS_TAGS: symbol;
244
+ /**
245
+ * Context key for metadata attribute.
246
+ * Used to propagate metadata object to all spans in the context.
247
+ */
248
+ declare const PINGOPS_METADATA: symbol;
249
+ /**
250
+ * Context key for capturing request body.
251
+ * When set, controls whether request bodies should be captured for HTTP spans.
252
+ * This allows wrapHttp to control body capture per-request.
253
+ */
254
+ declare const PINGOPS_CAPTURE_REQUEST_BODY: symbol;
255
+ /**
256
+ * Context key for capturing response body.
257
+ * When set, controls whether response bodies should be captured for HTTP spans.
258
+ * This allows wrapHttp to control body capture per-request.
259
+ */
260
+ declare const PINGOPS_CAPTURE_RESPONSE_BODY: symbol;
261
+ //#endregion
262
+ //#region src/wrap-http.d.ts
263
+ /**
264
+ * Options for wrapHttp function
265
+ */
266
+ interface WrapHttpOptions {
267
+ attributes?: WrapHttpAttributes;
268
+ /**
269
+ * Callback to check if SDK is initialized.
270
+ * Required to determine if global instrumentation is enabled.
271
+ */
272
+ checkInitialized: () => boolean;
273
+ /**
274
+ * Callback to check if global instrumentation is enabled.
275
+ * Required to determine instrumentation behavior.
276
+ */
277
+ isGlobalInstrumentationEnabled: () => boolean;
278
+ /**
279
+ * Optional callback to ensure SDK is initialized (auto-initialization).
280
+ * If not provided, wrapHttp will try to auto-initialize from environment variables.
281
+ */
282
+ ensureInitialized?: () => Promise<void>;
283
+ }
284
+ /**
285
+ * Wraps a function to set attributes on HTTP spans created within the wrapped block.
286
+ *
287
+ * This function sets attributes (userId, sessionId, tags, metadata) in the OpenTelemetry
288
+ * context, which are automatically propagated to all spans created within the wrapped function.
289
+ *
290
+ * Instrumentation behavior:
291
+ * - If `initializePingops` was called: All HTTP requests are instrumented by default.
292
+ * `wrapHttp` only adds attributes to spans created within the wrapped block.
293
+ * - If `initializePingops` was NOT called: Only HTTP requests within `wrapHttp` blocks
294
+ * are instrumented. Requests outside `wrapHttp` are not instrumented.
295
+ *
296
+ * Note: This is the low-level API. For a simpler API with automatic setup,
297
+ * use `wrapHttp` from `@pingops/sdk` instead.
298
+ *
299
+ * @param options - Options including attributes and required callbacks
300
+ * @param fn - Function to execute within the attribute context
301
+ * @returns The result of the function
302
+ */
303
+ declare function wrapHttp<T>(options: WrapHttpOptions, fn: () => T | Promise<T>): T | Promise<T>;
304
+ //#endregion
305
+ export { DEFAULT_REDACTION_CONFIG, DEFAULT_SENSITIVE_HEADER_PATTERNS, DomainRule, HeaderRedactionConfig, HeaderRedactionStrategy, LogLevel, Logger, PINGOPS_CAPTURE_REQUEST_BODY, PINGOPS_CAPTURE_RESPONSE_BODY, PINGOPS_HTTP_ENABLED, PINGOPS_METADATA, PINGOPS_SESSION_ID, PINGOPS_TAGS, PINGOPS_USER_ID, SpanPayload, WrapHttpAttributes, WrapHttpOptions, createLogger, extractHeadersFromAttributes, extractSpanPayload, filterHeaders, getPropagatedAttributesFromContext, isSensitiveHeader, isSpanEligible, normalizeHeaders, redactHeaderValue, shouldCaptureSpan, wrapHttp };
306
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/filtering/span-filter.ts","../src/filtering/domain-filter.ts","../src/filtering/sensitive-headers.ts","../src/filtering/header-filter.ts","../src/utils/span-extractor.ts","../src/utils/context-extractor.ts","../src/logger.ts","../src/context-keys.ts","../src/wrap-http.ts"],"sourcesContent":[],"mappings":"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"}