autotel 4.0.0 → 4.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.
Files changed (232) hide show
  1. package/README.md +26 -1
  2. package/dist/auto.cjs +2 -2
  3. package/dist/auto.js +1 -1
  4. package/dist/correlation-id.cjs +1 -1
  5. package/dist/correlation-id.js +1 -1
  6. package/dist/decorators.cjs +1 -1
  7. package/dist/decorators.js +1 -1
  8. package/dist/{event-Dlqr4ZNL.cjs → event-BhHREDJk.cjs} +3 -3
  9. package/dist/{event-Dlqr4ZNL.cjs.map → event-BhHREDJk.cjs.map} +1 -1
  10. package/dist/{event-_58ryBjh.js → event-ByBTV9M2.js} +3 -3
  11. package/dist/{event-_58ryBjh.js.map → event-ByBTV9M2.js.map} +1 -1
  12. package/dist/event.cjs +1 -1
  13. package/dist/event.js +1 -1
  14. package/dist/{functional-BGkT8J-h.js → functional-DtI0u4vx.js} +19 -19
  15. package/dist/functional-DtI0u4vx.js.map +1 -0
  16. package/dist/{functional-C4CzoVrX.cjs → functional-zpzNLhky.cjs} +4 -4
  17. package/dist/{functional-C4CzoVrX.cjs.map → functional-zpzNLhky.cjs.map} +1 -1
  18. package/dist/functional.cjs +1 -1
  19. package/dist/functional.js +1 -1
  20. package/dist/http.cjs +1 -1
  21. package/dist/http.js +1 -1
  22. package/dist/index.cjs +5 -5
  23. package/dist/index.d.cts +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +5 -5
  26. package/dist/{init-DJQOdVlN.d.ts → init-B7u-DjxM.d.ts} +57 -2
  27. package/dist/init-B7u-DjxM.d.ts.map +1 -0
  28. package/dist/{init-DvapOXCc.cjs → init-BX7AmFRl.cjs} +40 -21
  29. package/dist/init-BX7AmFRl.cjs.map +1 -0
  30. package/dist/{init-Ch6t7MNI.js → init-D-jnNMix.js} +39 -20
  31. package/dist/init-D-jnNMix.js.map +1 -0
  32. package/dist/{init-CNp-ee80.d.cts → init-DSrRmVnz.d.cts} +57 -2
  33. package/dist/init-DSrRmVnz.d.cts.map +1 -0
  34. package/dist/instrumentation.cjs +1 -1
  35. package/dist/instrumentation.js +1 -1
  36. package/dist/logger-D3Ej3DII.js +446 -0
  37. package/dist/logger-D3Ej3DII.js.map +1 -0
  38. package/dist/logger-thMPLpOG.cjs +487 -0
  39. package/dist/logger-thMPLpOG.cjs.map +1 -0
  40. package/dist/logger.cjs +8 -236
  41. package/dist/logger.js +2 -204
  42. package/dist/messaging.cjs +1 -1
  43. package/dist/messaging.js +1 -1
  44. package/dist/semantic-helpers.cjs +1 -1
  45. package/dist/semantic-helpers.js +1 -1
  46. package/dist/{track-3HY4NGV-.cjs → track-D59FfpL0.cjs} +2 -2
  47. package/dist/{track-3HY4NGV-.cjs.map → track-D59FfpL0.cjs.map} +1 -1
  48. package/dist/{track-nsKVy-pj.js → track-wc0HafS_.js} +6 -6
  49. package/dist/track-wc0HafS_.js.map +1 -0
  50. package/dist/webhook.cjs +1 -1
  51. package/dist/webhook.js +1 -1
  52. package/dist/workflow-distributed.cjs +1 -1
  53. package/dist/workflow-distributed.js +1 -1
  54. package/dist/workflow.cjs +1 -1
  55. package/dist/workflow.js +1 -1
  56. package/dist/{yaml-config-B3dQ82GR.cjs → yaml-config-Ck2uB0Dp.cjs} +2 -1
  57. package/dist/yaml-config-Ck2uB0Dp.cjs.map +1 -0
  58. package/dist/yaml-config.cjs +1 -1
  59. package/dist/yaml-config.d.cts +7 -1
  60. package/dist/yaml-config.d.cts.map +1 -1
  61. package/dist/yaml-config.d.ts +7 -1
  62. package/dist/yaml-config.d.ts.map +1 -1
  63. package/dist/yaml-config.js +1 -0
  64. package/dist/yaml-config.js.map +1 -1
  65. package/package.json +1 -2
  66. package/skills/autotel-core/SKILL.md +2 -0
  67. package/skills/autotel-instrumentation/SKILL.md +25 -0
  68. package/skills/debug-missing-spans/SKILL.md +3 -1
  69. package/skills/migrate-to-autotel/SKILL.md +24 -23
  70. package/skills/review-otel-patterns/SKILL.md +5 -4
  71. package/dist/functional-BGkT8J-h.js.map +0 -1
  72. package/dist/init-CNp-ee80.d.cts.map +0 -1
  73. package/dist/init-Ch6t7MNI.js.map +0 -1
  74. package/dist/init-DJQOdVlN.d.ts.map +0 -1
  75. package/dist/init-DvapOXCc.cjs.map +0 -1
  76. package/dist/logger.cjs.map +0 -1
  77. package/dist/logger.js.map +0 -1
  78. package/dist/track-nsKVy-pj.js.map +0 -1
  79. package/dist/yaml-config-B3dQ82GR.cjs.map +0 -1
  80. package/src/attribute-redacting-processor.test.ts +0 -763
  81. package/src/attribute-redacting-processor.ts +0 -621
  82. package/src/attributes/attachers.ts +0 -161
  83. package/src/attributes/builders.ts +0 -529
  84. package/src/attributes/domains.ts +0 -42
  85. package/src/attributes/index.ts +0 -81
  86. package/src/attributes/registry.ts +0 -323
  87. package/src/attributes/types.ts +0 -211
  88. package/src/attributes/utils.ts +0 -64
  89. package/src/attributes/validators.ts +0 -266
  90. package/src/attributes.test.ts +0 -292
  91. package/src/auto.ts +0 -67
  92. package/src/autotel-logger.test.ts +0 -548
  93. package/src/autotel-logger.ts +0 -364
  94. package/src/baggage-span-processor.test.ts +0 -202
  95. package/src/baggage-span-processor.ts +0 -100
  96. package/src/business-baggage.test.ts +0 -500
  97. package/src/business-baggage.ts +0 -669
  98. package/src/circuit-breaker.test.ts +0 -341
  99. package/src/circuit-breaker.ts +0 -184
  100. package/src/config.test.ts +0 -94
  101. package/src/config.ts +0 -172
  102. package/src/correlated-events.test.ts +0 -151
  103. package/src/correlated-events.ts +0 -47
  104. package/src/correlation-id.test.ts +0 -163
  105. package/src/correlation-id.ts +0 -206
  106. package/src/db.test.ts +0 -252
  107. package/src/db.ts +0 -447
  108. package/src/decorators.test.ts +0 -153
  109. package/src/decorators.ts +0 -188
  110. package/src/define-event.test.ts +0 -41
  111. package/src/define-event.ts +0 -58
  112. package/src/devtools.ts +0 -60
  113. package/src/drain-pipeline.test.ts +0 -68
  114. package/src/drain-pipeline.ts +0 -199
  115. package/src/drain-toolkit.test.ts +0 -113
  116. package/src/drain-toolkit.ts +0 -129
  117. package/src/enricher-toolkit.test.ts +0 -67
  118. package/src/enricher-toolkit.ts +0 -79
  119. package/src/enrichers.test.ts +0 -150
  120. package/src/enrichers.ts +0 -145
  121. package/src/env-config.test.ts +0 -323
  122. package/src/env-config.ts +0 -309
  123. package/src/error-catalog.test.ts +0 -133
  124. package/src/error-catalog.ts +0 -262
  125. package/src/event-queue.test.ts +0 -864
  126. package/src/event-queue.ts +0 -699
  127. package/src/event-subscriber.ts +0 -262
  128. package/src/event-testing.ts +0 -197
  129. package/src/event.test.ts +0 -1104
  130. package/src/event.ts +0 -988
  131. package/src/events-config.ts +0 -235
  132. package/src/exporters.ts +0 -165
  133. package/src/filtering-span-processor.test.ts +0 -281
  134. package/src/filtering-span-processor.ts +0 -111
  135. package/src/flatten-attributes.test.ts +0 -76
  136. package/src/flatten-attributes.ts +0 -80
  137. package/src/functional.strict-types.typecheck.ts +0 -53
  138. package/src/functional.test.ts +0 -1464
  139. package/src/functional.ts +0 -2539
  140. package/src/functional.types.test.ts +0 -135
  141. package/src/hook.mjs +0 -15
  142. package/src/http.test.ts +0 -485
  143. package/src/http.ts +0 -424
  144. package/src/index.ts +0 -433
  145. package/src/init-auto-redactor.test.ts +0 -53
  146. package/src/init-redactor.test.ts +0 -8
  147. package/src/init.customization.test.ts +0 -594
  148. package/src/init.integrations.test.ts +0 -399
  149. package/src/init.openllmetry.test.ts +0 -194
  150. package/src/init.protocol.test.ts +0 -215
  151. package/src/init.ts +0 -2312
  152. package/src/instrumentation.test.ts +0 -108
  153. package/src/instrumentation.ts +0 -319
  154. package/src/logger.test.ts +0 -125
  155. package/src/logger.ts +0 -341
  156. package/src/messaging-adapters.test.ts +0 -595
  157. package/src/messaging-adapters.ts +0 -583
  158. package/src/messaging-testing.test.ts +0 -573
  159. package/src/messaging-testing.ts +0 -935
  160. package/src/messaging.test.ts +0 -1646
  161. package/src/messaging.ts +0 -2245
  162. package/src/metric-helpers.ts +0 -47
  163. package/src/metric-testing.ts +0 -197
  164. package/src/metric.ts +0 -446
  165. package/src/metrics.test.ts +0 -241
  166. package/src/node-require.ts +0 -123
  167. package/src/operation-context.ts +0 -93
  168. package/src/parse-error.test.ts +0 -73
  169. package/src/parse-error.ts +0 -112
  170. package/src/posthog-logs.test.ts +0 -115
  171. package/src/posthog-logs.ts +0 -77
  172. package/src/pretty-console-exporter.test.ts +0 -545
  173. package/src/pretty-console-exporter.ts +0 -413
  174. package/src/pretty-log-formatter.test.ts +0 -123
  175. package/src/pretty-log-formatter.ts +0 -210
  176. package/src/processors/canonical-log-line-processor.test.ts +0 -523
  177. package/src/processors/canonical-log-line-processor.ts +0 -396
  178. package/src/processors.ts +0 -152
  179. package/src/rate-limiter.test.ts +0 -199
  180. package/src/rate-limiter.ts +0 -98
  181. package/src/redact-values.test.ts +0 -90
  182. package/src/redact-values.ts +0 -34
  183. package/src/register.ts +0 -37
  184. package/src/request-logger.test.ts +0 -545
  185. package/src/request-logger.ts +0 -342
  186. package/src/sampling.test.ts +0 -1060
  187. package/src/sampling.ts +0 -737
  188. package/src/security-schema.test.ts +0 -45
  189. package/src/security-schema.ts +0 -107
  190. package/src/semantic-conventions.ts +0 -15
  191. package/src/semantic-helpers.test.ts +0 -226
  192. package/src/semantic-helpers.ts +0 -438
  193. package/src/shutdown.test.ts +0 -364
  194. package/src/shutdown.ts +0 -246
  195. package/src/span-name-normalizer.test.ts +0 -377
  196. package/src/span-name-normalizer.ts +0 -213
  197. package/src/stable-hash.ts +0 -27
  198. package/src/structured-error.test.ts +0 -191
  199. package/src/structured-error.ts +0 -157
  200. package/src/stub.integration.test.ts +0 -361
  201. package/src/tail-sampling-processor.test.ts +0 -230
  202. package/src/tail-sampling-processor.ts +0 -55
  203. package/src/test-span-collector.test.ts +0 -234
  204. package/src/test-span-collector.ts +0 -150
  205. package/src/testing.ts +0 -705
  206. package/src/trace-context.test.ts +0 -73
  207. package/src/trace-context.ts +0 -567
  208. package/src/trace-helpers.new.test.ts +0 -278
  209. package/src/trace-helpers.test.ts +0 -290
  210. package/src/trace-helpers.ts +0 -710
  211. package/src/trace-hybrid.test.ts +0 -42
  212. package/src/trace-hybrid.ts +0 -37
  213. package/src/tracer-provider.test.ts +0 -183
  214. package/src/tracer-provider.ts +0 -266
  215. package/src/track.test.ts +0 -154
  216. package/src/track.ts +0 -216
  217. package/src/validate.test.ts +0 -287
  218. package/src/validate.ts +0 -307
  219. package/src/validation-attributes.ts +0 -43
  220. package/src/validation.test.ts +0 -330
  221. package/src/validation.ts +0 -246
  222. package/src/variable-name-inference.test.ts +0 -178
  223. package/src/variable-name-inference.ts +0 -242
  224. package/src/webhook.test.ts +0 -649
  225. package/src/webhook.ts +0 -637
  226. package/src/workflow-distributed.test.ts +0 -786
  227. package/src/workflow-distributed.ts +0 -916
  228. package/src/workflow.async-safety.integration.test.ts +0 -345
  229. package/src/workflow.test.ts +0 -647
  230. package/src/workflow.ts +0 -810
  231. package/src/yaml-config.test.ts +0 -337
  232. package/src/yaml-config.ts +0 -342
@@ -1,199 +0,0 @@
1
- /**
2
- * Tests for token bucket rate limiter
3
- */
4
-
5
- import { describe, it, expect, beforeEach, vi } from 'vitest';
6
- import { TokenBucketRateLimiter } from './rate-limiter';
7
-
8
- describe('TokenBucketRateLimiter', () => {
9
- beforeEach(() => {
10
- vi.useFakeTimers();
11
- });
12
-
13
- describe('tryConsume()', () => {
14
- it('should allow events within rate limit', () => {
15
- const limiter = new TokenBucketRateLimiter({
16
- maxEventsPerSecond: 10,
17
- burstCapacity: 20,
18
- });
19
-
20
- // Should allow first 20 events (burst capacity)
21
- for (let i = 0; i < 20; i++) {
22
- expect(limiter.tryConsume()).toBe(true);
23
- }
24
-
25
- // 21st event should be rejected
26
- expect(limiter.tryConsume()).toBe(false);
27
- });
28
-
29
- it('should refill tokens over time', () => {
30
- const limiter = new TokenBucketRateLimiter({
31
- maxEventsPerSecond: 10, // 10 events/sec = 1 event/100ms
32
- burstCapacity: 10,
33
- });
34
-
35
- // Consume all tokens
36
- for (let i = 0; i < 10; i++) {
37
- expect(limiter.tryConsume()).toBe(true);
38
- }
39
-
40
- // Should be rate limited
41
- expect(limiter.tryConsume()).toBe(false);
42
-
43
- // Advance time by 100ms (1 token should be added)
44
- vi.advanceTimersByTime(100);
45
-
46
- // Should allow 1 more event
47
- expect(limiter.tryConsume()).toBe(true);
48
- expect(limiter.tryConsume()).toBe(false);
49
-
50
- // Advance time by 500ms (5 tokens should be added)
51
- vi.advanceTimersByTime(500);
52
-
53
- // Should allow 5 more events
54
- for (let i = 0; i < 5; i++) {
55
- expect(limiter.tryConsume()).toBe(true);
56
- }
57
- expect(limiter.tryConsume()).toBe(false);
58
- });
59
-
60
- it('should not exceed max tokens', () => {
61
- const limiter = new TokenBucketRateLimiter({
62
- maxEventsPerSecond: 10,
63
- burstCapacity: 20,
64
- });
65
-
66
- // Wait a long time
67
- vi.advanceTimersByTime(10_000);
68
-
69
- // Should only have 20 tokens (burstCapacity), not more
70
- expect(limiter.getAvailableTokens()).toBe(20);
71
- });
72
-
73
- it('should consume multiple tokens at once', () => {
74
- const limiter = new TokenBucketRateLimiter({
75
- maxEventsPerSecond: 100,
76
- burstCapacity: 200,
77
- });
78
-
79
- // Consume 50 tokens at once
80
- expect(limiter.tryConsume(50)).toBe(true);
81
- expect(limiter.getAvailableTokens()).toBe(150);
82
-
83
- // Consume another 150 tokens
84
- expect(limiter.tryConsume(150)).toBe(true);
85
- expect(limiter.getAvailableTokens()).toBe(0);
86
-
87
- // Should reject request for 1 token
88
- expect(limiter.tryConsume(1)).toBe(false);
89
- });
90
- });
91
-
92
- describe('waitForToken()', () => {
93
- it('should wait until token is available', async () => {
94
- const limiter = new TokenBucketRateLimiter({
95
- maxEventsPerSecond: 10, // 1 token every 100ms
96
- burstCapacity: 1,
97
- });
98
-
99
- // Consume the only token
100
- expect(limiter.tryConsume()).toBe(true);
101
- expect(limiter.tryConsume()).toBe(false);
102
-
103
- // Wait for next token
104
- const promise = limiter.waitForToken();
105
-
106
- // Advance time by 100ms
107
- vi.advanceTimersByTime(100);
108
-
109
- // Should resolve after 100ms
110
- await promise;
111
-
112
- // Token should be consumed
113
- expect(limiter.tryConsume()).toBe(false);
114
- });
115
-
116
- it('should calculate correct wait time for multiple tokens', async () => {
117
- const limiter = new TokenBucketRateLimiter({
118
- maxEventsPerSecond: 10, // 1 token every 100ms
119
- burstCapacity: 10,
120
- });
121
-
122
- // Consume all tokens
123
- expect(limiter.tryConsume(10)).toBe(true);
124
-
125
- // Request 5 tokens (should wait 500ms)
126
- const promise = limiter.waitForToken(5);
127
-
128
- // Advance by 400ms (not enough)
129
- vi.advanceTimersByTime(400);
130
-
131
- // Promise should not resolve yet
132
- let resolved = false;
133
- promise.then(() => {
134
- resolved = true;
135
- });
136
-
137
- await vi.runAllTimersAsync();
138
-
139
- // Should be resolved now
140
- expect(resolved).toBe(true);
141
- });
142
- });
143
-
144
- describe('getAvailableTokens()', () => {
145
- it('should return current token count', () => {
146
- const limiter = new TokenBucketRateLimiter({
147
- maxEventsPerSecond: 100,
148
- burstCapacity: 200,
149
- });
150
-
151
- expect(limiter.getAvailableTokens()).toBe(200);
152
-
153
- limiter.tryConsume(50);
154
- expect(limiter.getAvailableTokens()).toBe(150);
155
-
156
- // Advance time by 100ms (10 tokens added)
157
- vi.advanceTimersByTime(100);
158
- expect(limiter.getAvailableTokens()).toBe(160);
159
- });
160
- });
161
-
162
- describe('reset()', () => {
163
- it('should reset to full capacity', () => {
164
- const limiter = new TokenBucketRateLimiter({
165
- maxEventsPerSecond: 10,
166
- burstCapacity: 20,
167
- });
168
-
169
- // Consume all tokens
170
- limiter.tryConsume(20);
171
- expect(limiter.getAvailableTokens()).toBe(0);
172
-
173
- // Reset
174
- limiter.reset();
175
- expect(limiter.getAvailableTokens()).toBe(20);
176
- });
177
- });
178
-
179
- describe('Burst capacity', () => {
180
- it('should default to 2x rate if not specified', () => {
181
- const limiter = new TokenBucketRateLimiter({
182
- maxEventsPerSecond: 50,
183
- // burstCapacity not specified
184
- });
185
-
186
- // Should have 100 tokens (2x rate)
187
- expect(limiter.getAvailableTokens()).toBe(100);
188
- });
189
-
190
- it('should allow custom burst capacity', () => {
191
- const limiter = new TokenBucketRateLimiter({
192
- maxEventsPerSecond: 50,
193
- burstCapacity: 500, // 10x rate
194
- });
195
-
196
- expect(limiter.getAvailableTokens()).toBe(500);
197
- });
198
- });
199
- });
@@ -1,98 +0,0 @@
1
- /**
2
- * Token bucket rate limiter for event subscribers
3
- *
4
- * Prevents overwhelming downstream events platforms with too many events.
5
- * Uses token bucket algorithm for smooth rate limiting with burst capacity.
6
- */
7
-
8
- export interface RateLimiterConfig {
9
- /** Maximum events per second (default: 100) */
10
- maxEventsPerSecond: number;
11
- /** Burst capacity - max events in a single burst (default: 2x rate) */
12
- burstCapacity?: number;
13
- }
14
-
15
- /**
16
- * Token bucket rate limiter
17
- *
18
- * Allows bursts up to burstCapacity, then smooths to maxEventsPerSecond.
19
- * Thread-safe for async operations.
20
- */
21
- export class TokenBucketRateLimiter {
22
- private tokens: number;
23
- private readonly maxTokens: number;
24
- private readonly refillRate: number; // tokens per millisecond
25
- private lastRefill: number;
26
-
27
- constructor(config: RateLimiterConfig) {
28
- this.maxTokens = config.burstCapacity || config.maxEventsPerSecond * 2;
29
- this.tokens = this.maxTokens; // Start with full bucket
30
- this.refillRate = config.maxEventsPerSecond / 1000; // Convert to per-ms
31
- this.lastRefill = Date.now();
32
- }
33
-
34
- /**
35
- * Try to consume a token (allow an event)
36
- * Returns true if allowed, false if rate limit exceeded
37
- */
38
- tryConsume(count = 1): boolean {
39
- this.refill();
40
-
41
- if (this.tokens >= count) {
42
- this.tokens -= count;
43
- return true;
44
- }
45
-
46
- return false;
47
- }
48
-
49
- /**
50
- * Wait until a token is available (async rate limiting)
51
- * Returns a promise that resolves when the event can be processed
52
- */
53
- async waitForToken(count = 1): Promise<void> {
54
- this.refill();
55
-
56
- if (this.tokens >= count) {
57
- this.tokens -= count;
58
- return;
59
- }
60
-
61
- // Calculate wait time until we have enough tokens
62
- const tokensNeeded = count - this.tokens;
63
- const waitMs = Math.ceil(tokensNeeded / this.refillRate);
64
-
65
- await new Promise((resolve) => setTimeout(resolve, waitMs));
66
-
67
- // After waiting, try again (recursive)
68
- return this.waitForToken(count);
69
- }
70
-
71
- /**
72
- * Refill tokens based on elapsed time
73
- */
74
- private refill(): void {
75
- const now = Date.now();
76
- const elapsed = now - this.lastRefill;
77
- const tokensToAdd = elapsed * this.refillRate;
78
-
79
- this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
80
- this.lastRefill = now;
81
- }
82
-
83
- /**
84
- * Get current available tokens (for testing/debugging)
85
- */
86
- getAvailableTokens(): number {
87
- this.refill();
88
- return Math.floor(this.tokens);
89
- }
90
-
91
- /**
92
- * Reset the rate limiter (for testing)
93
- */
94
- reset(): void {
95
- this.tokens = this.maxTokens;
96
- this.lastRefill = Date.now();
97
- }
98
- }
@@ -1,90 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { createStringRedactor } from './redact-values';
3
- import type { StringRedactor } from './redact-values';
4
-
5
- describe('createStringRedactor', () => {
6
- describe('default preset', () => {
7
- let redact: StringRedactor;
8
-
9
- beforeEach(() => {
10
- redact = createStringRedactor('default');
11
- });
12
-
13
- it('smart-masks emails', () => {
14
- expect(redact('Contact user@example.com for info')).toBe(
15
- 'Contact u***@***.com for info',
16
- );
17
- });
18
-
19
- it('smart-masks international phone numbers (country code + last 2 digits)', () => {
20
- expect(redact('Call +33 1 23 45 67 89 now')).toBe('Call +33******89 now');
21
- });
22
-
23
- it('smart-masks phone numbers with parens (last 2 digits)', () => {
24
- expect(redact('Call (415) 555-1234 now')).toBe('Call ********34 now');
25
- });
26
-
27
- it('smart-masks common US phone formats', () => {
28
- expect(redact('Call 555-123-4567 now')).toBe('Call ********67 now');
29
- expect(redact('Call 5551234567 now')).toBe('Call ********67 now');
30
- });
31
-
32
- it('does not mistake bare digit runs for phone numbers', () => {
33
- // UUIDs, order ids etc. should pass through untouched.
34
- expect(redact('Order: 12345678 ok')).toBe('Order: 12345678 ok');
35
- });
36
-
37
- it('smart-masks credit card numbers (last four digits preserved)', () => {
38
- expect(redact('Card: 4111-1111-1111-1111')).toBe('Card: ****1111');
39
- });
40
-
41
- it('returns input unchanged when no patterns match', () => {
42
- expect(redact('hello world')).toBe('hello world');
43
- });
44
- });
45
-
46
- describe('strict preset', () => {
47
- let redact: StringRedactor;
48
-
49
- beforeEach(() => {
50
- redact = createStringRedactor('strict');
51
- });
52
-
53
- it('smart-masks JWTs', () => {
54
- const jwt =
55
- 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.abc123_-def';
56
- expect(redact(`Token: ${jwt}`)).toBe('Token: eyJ***.***');
57
- });
58
-
59
- it('smart-masks bearer tokens', () => {
60
- expect(redact('Authorization: Bearer abc123.xyz')).toBe(
61
- 'Authorization: Bearer ***',
62
- );
63
- });
64
- });
65
-
66
- describe('custom config', () => {
67
- it('accepts custom config with custom patterns', () => {
68
- const redact = createStringRedactor({
69
- valuePatterns: [{ name: 'customId', pattern: /CUST-\d{8}/g }],
70
- replacement: '***',
71
- });
72
- expect(redact('Customer CUST-12345678 logged in')).toBe(
73
- 'Customer *** logged in',
74
- );
75
- });
76
-
77
- it('uses custom replacement string', () => {
78
- const redact = createStringRedactor({
79
- valuePatterns: [
80
- {
81
- name: 'email',
82
- pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/gi,
83
- },
84
- ],
85
- replacement: '<HIDDEN>',
86
- });
87
- expect(redact('Email: test@example.com')).toBe('Email: <HIDDEN>');
88
- });
89
- });
90
- });
@@ -1,34 +0,0 @@
1
- /** Standalone string redaction for use outside the span processor pipeline. */
2
-
3
- import {
4
- REDACTOR_PRESETS,
5
- type AttributeRedactorConfig,
6
- type AttributeRedactorPreset,
7
- type ValuePatternConfig,
8
- } from './attribute-redacting-processor';
9
-
10
- export type StringRedactor = (value: string) => string;
11
- export function createStringRedactor(
12
- config: AttributeRedactorConfig | AttributeRedactorPreset,
13
- ): StringRedactor {
14
- const resolved =
15
- typeof config === 'string' ? REDACTOR_PRESETS[config] : config;
16
- const valuePatterns: ValuePatternConfig[] = resolved.valuePatterns ?? [];
17
- const defaultReplacement = resolved.replacement ?? '[REDACTED]';
18
-
19
- return (value: string): string => {
20
- let result = value;
21
- for (const { pattern, replacement, mask } of valuePatterns) {
22
- pattern.lastIndex = 0;
23
- // Smart masks (e.g. email → a***@***.com) take precedence over the
24
- // static replacement so callers see the same output as the
25
- // span-attribute redactor does.
26
- if (mask) {
27
- result = result.replaceAll(pattern, (match) => mask(match));
28
- } else {
29
- result = result.replaceAll(pattern, replacement ?? defaultReplacement);
30
- }
31
- }
32
- return result;
33
- };
34
- }
package/src/register.ts DELETED
@@ -1,37 +0,0 @@
1
- /**
2
- * ESM instrumentation registration for Node.js 18.19+
3
- *
4
- * This module registers the OpenTelemetry ESM loader hook using the modern
5
- * node:module register() API. This eliminates the need for NODE_OPTIONS or
6
- * --experimental-loader flags.
7
- *
8
- * Usage in instrumentation.mjs:
9
- * ```typescript
10
- * import 'autotel/register'; // MUST be first import!
11
- * import { init } from 'autotel';
12
- *
13
- * init({
14
- * service: 'my-app',
15
- * instrumentations: [...], // or autoInstrumentations: ['express', 'http', 'pino']
16
- * });
17
- * ```
18
- *
19
- * Then run:
20
- * ```bash
21
- * node --import ./instrumentation.mjs src/index.js
22
- * # or with tsx:
23
- * tsx --import ./instrumentation.mjs src/index.ts
24
- * ```
25
- *
26
- * No NODE_OPTIONS or --experimental-loader needed!
27
- *
28
- * @requires Node.js 18.19.0 or later
29
- * @see https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md
30
- * @see https://nodejs.org/api/module.html#moduleregisterspecifier-parenturl-options
31
- */
32
-
33
- import { register } from 'node:module';
34
-
35
- // Use the official OpenTelemetry instrumentation hook which wraps import-in-the-middle
36
- // This ensures proper integration with OTel's instrumentation system
37
- register('@opentelemetry/instrumentation/hook.mjs', import.meta.url);