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.
- package/README.md +26 -1
- package/dist/auto.cjs +2 -2
- package/dist/auto.js +1 -1
- package/dist/correlation-id.cjs +1 -1
- package/dist/correlation-id.js +1 -1
- package/dist/decorators.cjs +1 -1
- package/dist/decorators.js +1 -1
- package/dist/{event-Dlqr4ZNL.cjs → event-BhHREDJk.cjs} +3 -3
- package/dist/{event-Dlqr4ZNL.cjs.map → event-BhHREDJk.cjs.map} +1 -1
- package/dist/{event-_58ryBjh.js → event-ByBTV9M2.js} +3 -3
- package/dist/{event-_58ryBjh.js.map → event-ByBTV9M2.js.map} +1 -1
- package/dist/event.cjs +1 -1
- package/dist/event.js +1 -1
- package/dist/{functional-BGkT8J-h.js → functional-DtI0u4vx.js} +19 -19
- package/dist/functional-DtI0u4vx.js.map +1 -0
- package/dist/{functional-C4CzoVrX.cjs → functional-zpzNLhky.cjs} +4 -4
- package/dist/{functional-C4CzoVrX.cjs.map → functional-zpzNLhky.cjs.map} +1 -1
- package/dist/functional.cjs +1 -1
- package/dist/functional.js +1 -1
- package/dist/http.cjs +1 -1
- package/dist/http.js +1 -1
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/{init-DJQOdVlN.d.ts → init-B7u-DjxM.d.ts} +57 -2
- package/dist/init-B7u-DjxM.d.ts.map +1 -0
- package/dist/{init-DvapOXCc.cjs → init-BX7AmFRl.cjs} +40 -21
- package/dist/init-BX7AmFRl.cjs.map +1 -0
- package/dist/{init-Ch6t7MNI.js → init-D-jnNMix.js} +39 -20
- package/dist/init-D-jnNMix.js.map +1 -0
- package/dist/{init-CNp-ee80.d.cts → init-DSrRmVnz.d.cts} +57 -2
- package/dist/init-DSrRmVnz.d.cts.map +1 -0
- package/dist/instrumentation.cjs +1 -1
- package/dist/instrumentation.js +1 -1
- package/dist/logger-D3Ej3DII.js +446 -0
- package/dist/logger-D3Ej3DII.js.map +1 -0
- package/dist/logger-thMPLpOG.cjs +487 -0
- package/dist/logger-thMPLpOG.cjs.map +1 -0
- package/dist/logger.cjs +8 -236
- package/dist/logger.js +2 -204
- package/dist/messaging.cjs +1 -1
- package/dist/messaging.js +1 -1
- package/dist/semantic-helpers.cjs +1 -1
- package/dist/semantic-helpers.js +1 -1
- package/dist/{track-3HY4NGV-.cjs → track-D59FfpL0.cjs} +2 -2
- package/dist/{track-3HY4NGV-.cjs.map → track-D59FfpL0.cjs.map} +1 -1
- package/dist/{track-nsKVy-pj.js → track-wc0HafS_.js} +6 -6
- package/dist/track-wc0HafS_.js.map +1 -0
- package/dist/webhook.cjs +1 -1
- package/dist/webhook.js +1 -1
- package/dist/workflow-distributed.cjs +1 -1
- package/dist/workflow-distributed.js +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.js +1 -1
- package/dist/{yaml-config-B3dQ82GR.cjs → yaml-config-Ck2uB0Dp.cjs} +2 -1
- package/dist/yaml-config-Ck2uB0Dp.cjs.map +1 -0
- package/dist/yaml-config.cjs +1 -1
- package/dist/yaml-config.d.cts +7 -1
- package/dist/yaml-config.d.cts.map +1 -1
- package/dist/yaml-config.d.ts +7 -1
- package/dist/yaml-config.d.ts.map +1 -1
- package/dist/yaml-config.js +1 -0
- package/dist/yaml-config.js.map +1 -1
- package/package.json +1 -2
- package/skills/autotel-core/SKILL.md +2 -0
- package/skills/autotel-instrumentation/SKILL.md +25 -0
- package/skills/debug-missing-spans/SKILL.md +3 -1
- package/skills/migrate-to-autotel/SKILL.md +24 -23
- package/skills/review-otel-patterns/SKILL.md +5 -4
- package/dist/functional-BGkT8J-h.js.map +0 -1
- package/dist/init-CNp-ee80.d.cts.map +0 -1
- package/dist/init-Ch6t7MNI.js.map +0 -1
- package/dist/init-DJQOdVlN.d.ts.map +0 -1
- package/dist/init-DvapOXCc.cjs.map +0 -1
- package/dist/logger.cjs.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/track-nsKVy-pj.js.map +0 -1
- package/dist/yaml-config-B3dQ82GR.cjs.map +0 -1
- package/src/attribute-redacting-processor.test.ts +0 -763
- package/src/attribute-redacting-processor.ts +0 -621
- package/src/attributes/attachers.ts +0 -161
- package/src/attributes/builders.ts +0 -529
- package/src/attributes/domains.ts +0 -42
- package/src/attributes/index.ts +0 -81
- package/src/attributes/registry.ts +0 -323
- package/src/attributes/types.ts +0 -211
- package/src/attributes/utils.ts +0 -64
- package/src/attributes/validators.ts +0 -266
- package/src/attributes.test.ts +0 -292
- package/src/auto.ts +0 -67
- package/src/autotel-logger.test.ts +0 -548
- package/src/autotel-logger.ts +0 -364
- package/src/baggage-span-processor.test.ts +0 -202
- package/src/baggage-span-processor.ts +0 -100
- package/src/business-baggage.test.ts +0 -500
- package/src/business-baggage.ts +0 -669
- package/src/circuit-breaker.test.ts +0 -341
- package/src/circuit-breaker.ts +0 -184
- package/src/config.test.ts +0 -94
- package/src/config.ts +0 -172
- package/src/correlated-events.test.ts +0 -151
- package/src/correlated-events.ts +0 -47
- package/src/correlation-id.test.ts +0 -163
- package/src/correlation-id.ts +0 -206
- package/src/db.test.ts +0 -252
- package/src/db.ts +0 -447
- package/src/decorators.test.ts +0 -153
- package/src/decorators.ts +0 -188
- package/src/define-event.test.ts +0 -41
- package/src/define-event.ts +0 -58
- package/src/devtools.ts +0 -60
- package/src/drain-pipeline.test.ts +0 -68
- package/src/drain-pipeline.ts +0 -199
- package/src/drain-toolkit.test.ts +0 -113
- package/src/drain-toolkit.ts +0 -129
- package/src/enricher-toolkit.test.ts +0 -67
- package/src/enricher-toolkit.ts +0 -79
- package/src/enrichers.test.ts +0 -150
- package/src/enrichers.ts +0 -145
- package/src/env-config.test.ts +0 -323
- package/src/env-config.ts +0 -309
- package/src/error-catalog.test.ts +0 -133
- package/src/error-catalog.ts +0 -262
- package/src/event-queue.test.ts +0 -864
- package/src/event-queue.ts +0 -699
- package/src/event-subscriber.ts +0 -262
- package/src/event-testing.ts +0 -197
- package/src/event.test.ts +0 -1104
- package/src/event.ts +0 -988
- package/src/events-config.ts +0 -235
- package/src/exporters.ts +0 -165
- package/src/filtering-span-processor.test.ts +0 -281
- package/src/filtering-span-processor.ts +0 -111
- package/src/flatten-attributes.test.ts +0 -76
- package/src/flatten-attributes.ts +0 -80
- package/src/functional.strict-types.typecheck.ts +0 -53
- package/src/functional.test.ts +0 -1464
- package/src/functional.ts +0 -2539
- package/src/functional.types.test.ts +0 -135
- package/src/hook.mjs +0 -15
- package/src/http.test.ts +0 -485
- package/src/http.ts +0 -424
- package/src/index.ts +0 -433
- package/src/init-auto-redactor.test.ts +0 -53
- package/src/init-redactor.test.ts +0 -8
- package/src/init.customization.test.ts +0 -594
- package/src/init.integrations.test.ts +0 -399
- package/src/init.openllmetry.test.ts +0 -194
- package/src/init.protocol.test.ts +0 -215
- package/src/init.ts +0 -2312
- package/src/instrumentation.test.ts +0 -108
- package/src/instrumentation.ts +0 -319
- package/src/logger.test.ts +0 -125
- package/src/logger.ts +0 -341
- package/src/messaging-adapters.test.ts +0 -595
- package/src/messaging-adapters.ts +0 -583
- package/src/messaging-testing.test.ts +0 -573
- package/src/messaging-testing.ts +0 -935
- package/src/messaging.test.ts +0 -1646
- package/src/messaging.ts +0 -2245
- package/src/metric-helpers.ts +0 -47
- package/src/metric-testing.ts +0 -197
- package/src/metric.ts +0 -446
- package/src/metrics.test.ts +0 -241
- package/src/node-require.ts +0 -123
- package/src/operation-context.ts +0 -93
- package/src/parse-error.test.ts +0 -73
- package/src/parse-error.ts +0 -112
- package/src/posthog-logs.test.ts +0 -115
- package/src/posthog-logs.ts +0 -77
- package/src/pretty-console-exporter.test.ts +0 -545
- package/src/pretty-console-exporter.ts +0 -413
- package/src/pretty-log-formatter.test.ts +0 -123
- package/src/pretty-log-formatter.ts +0 -210
- package/src/processors/canonical-log-line-processor.test.ts +0 -523
- package/src/processors/canonical-log-line-processor.ts +0 -396
- package/src/processors.ts +0 -152
- package/src/rate-limiter.test.ts +0 -199
- package/src/rate-limiter.ts +0 -98
- package/src/redact-values.test.ts +0 -90
- package/src/redact-values.ts +0 -34
- package/src/register.ts +0 -37
- package/src/request-logger.test.ts +0 -545
- package/src/request-logger.ts +0 -342
- package/src/sampling.test.ts +0 -1060
- package/src/sampling.ts +0 -737
- package/src/security-schema.test.ts +0 -45
- package/src/security-schema.ts +0 -107
- package/src/semantic-conventions.ts +0 -15
- package/src/semantic-helpers.test.ts +0 -226
- package/src/semantic-helpers.ts +0 -438
- package/src/shutdown.test.ts +0 -364
- package/src/shutdown.ts +0 -246
- package/src/span-name-normalizer.test.ts +0 -377
- package/src/span-name-normalizer.ts +0 -213
- package/src/stable-hash.ts +0 -27
- package/src/structured-error.test.ts +0 -191
- package/src/structured-error.ts +0 -157
- package/src/stub.integration.test.ts +0 -361
- package/src/tail-sampling-processor.test.ts +0 -230
- package/src/tail-sampling-processor.ts +0 -55
- package/src/test-span-collector.test.ts +0 -234
- package/src/test-span-collector.ts +0 -150
- package/src/testing.ts +0 -705
- package/src/trace-context.test.ts +0 -73
- package/src/trace-context.ts +0 -567
- package/src/trace-helpers.new.test.ts +0 -278
- package/src/trace-helpers.test.ts +0 -290
- package/src/trace-helpers.ts +0 -710
- package/src/trace-hybrid.test.ts +0 -42
- package/src/trace-hybrid.ts +0 -37
- package/src/tracer-provider.test.ts +0 -183
- package/src/tracer-provider.ts +0 -266
- package/src/track.test.ts +0 -154
- package/src/track.ts +0 -216
- package/src/validate.test.ts +0 -287
- package/src/validate.ts +0 -307
- package/src/validation-attributes.ts +0 -43
- package/src/validation.test.ts +0 -330
- package/src/validation.ts +0 -246
- package/src/variable-name-inference.test.ts +0 -178
- package/src/variable-name-inference.ts +0 -242
- package/src/webhook.test.ts +0 -649
- package/src/webhook.ts +0 -637
- package/src/workflow-distributed.test.ts +0 -786
- package/src/workflow-distributed.ts +0 -916
- package/src/workflow.async-safety.integration.test.ts +0 -345
- package/src/workflow.test.ts +0 -647
- package/src/workflow.ts +0 -810
- package/src/yaml-config.test.ts +0 -337
- package/src/yaml-config.ts +0 -342
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Filtering Span Processor
|
|
3
|
-
*
|
|
4
|
-
* Filters spans based on a user-provided predicate function.
|
|
5
|
-
* Runs filtering on onEnd() to have access to complete span data.
|
|
6
|
-
*
|
|
7
|
-
* @example Filter out Next.js instrumentation spans
|
|
8
|
-
* ```typescript
|
|
9
|
-
* init({
|
|
10
|
-
* service: 'my-app',
|
|
11
|
-
* spanFilter: (span) => span.instrumentationScope.name !== 'next.js'
|
|
12
|
-
* })
|
|
13
|
-
* ```
|
|
14
|
-
*
|
|
15
|
-
* @example Filter out health check endpoints
|
|
16
|
-
* ```typescript
|
|
17
|
-
* init({
|
|
18
|
-
* service: 'my-app',
|
|
19
|
-
* spanFilter: (span) => !span.name.includes('/health')
|
|
20
|
-
* })
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import type {
|
|
25
|
-
SpanProcessor,
|
|
26
|
-
ReadableSpan,
|
|
27
|
-
} from '@opentelemetry/sdk-trace-base';
|
|
28
|
-
import type { Context } from '@opentelemetry/api';
|
|
29
|
-
import type { Span } from '@opentelemetry/sdk-trace-base';
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Predicate function for filtering spans
|
|
33
|
-
*
|
|
34
|
-
* @param span - The completed span (ReadableSpan) with all attributes and metadata
|
|
35
|
-
* @returns true to keep the span, false to drop it
|
|
36
|
-
*
|
|
37
|
-
* Available span properties for filtering:
|
|
38
|
-
* - `span.name` - Span name
|
|
39
|
-
* - `span.attributes` - All span attributes
|
|
40
|
-
* - `span.instrumentationScope` - `{ name, version }` of the instrumentation
|
|
41
|
-
* - `span.status` - Span status code and message
|
|
42
|
-
* - `span.duration` - Span duration as `[seconds, nanoseconds]`
|
|
43
|
-
* - `span.kind` - SpanKind (INTERNAL, SERVER, CLIENT, etc.)
|
|
44
|
-
*/
|
|
45
|
-
export type SpanFilterPredicate = (span: ReadableSpan) => boolean;
|
|
46
|
-
|
|
47
|
-
export interface FilteringSpanProcessorOptions {
|
|
48
|
-
/**
|
|
49
|
-
* Predicate function to determine if a span should be kept
|
|
50
|
-
* Return true to keep the span, false to drop it
|
|
51
|
-
*/
|
|
52
|
-
filter: SpanFilterPredicate;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Span processor that filters spans based on a predicate function.
|
|
57
|
-
*
|
|
58
|
-
* The filter is applied on onEnd() when the span has complete data including:
|
|
59
|
-
* - All attributes
|
|
60
|
-
* - Status code and message
|
|
61
|
-
* - Duration
|
|
62
|
-
* - Events and links
|
|
63
|
-
* - Instrumentation scope (useful for filtering by library)
|
|
64
|
-
*
|
|
65
|
-
* onStart() passes through unchanged to ensure child spans can still be created.
|
|
66
|
-
*
|
|
67
|
-
* Error handling: If the filter predicate throws, the span is forwarded (fail-open).
|
|
68
|
-
*/
|
|
69
|
-
export class FilteringSpanProcessor implements SpanProcessor {
|
|
70
|
-
private readonly wrappedProcessor: SpanProcessor;
|
|
71
|
-
private readonly filter: SpanFilterPredicate;
|
|
72
|
-
|
|
73
|
-
constructor(
|
|
74
|
-
wrappedProcessor: SpanProcessor,
|
|
75
|
-
options: FilteringSpanProcessorOptions,
|
|
76
|
-
) {
|
|
77
|
-
this.wrappedProcessor = wrappedProcessor;
|
|
78
|
-
this.filter = options.filter;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Pass through onStart - we need spans to start so child spans work
|
|
83
|
-
*/
|
|
84
|
-
onStart(span: Span, parentContext: Context): void {
|
|
85
|
-
this.wrappedProcessor.onStart(span, parentContext);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Apply filter predicate on span end
|
|
90
|
-
* If filter returns false, span is dropped (not forwarded)
|
|
91
|
-
*/
|
|
92
|
-
onEnd(span: ReadableSpan): void {
|
|
93
|
-
try {
|
|
94
|
-
if (this.filter(span)) {
|
|
95
|
-
this.wrappedProcessor.onEnd(span);
|
|
96
|
-
}
|
|
97
|
-
// If filter returns false, span is silently dropped
|
|
98
|
-
} catch {
|
|
99
|
-
// If filter throws, forward the span (fail-open behavior)
|
|
100
|
-
this.wrappedProcessor.onEnd(span);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
forceFlush(): Promise<void> {
|
|
105
|
-
return this.wrappedProcessor.forceFlush();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
shutdown(): Promise<void> {
|
|
109
|
-
return this.wrappedProcessor.shutdown();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { toAttributeValue, flattenToAttributes } from './flatten-attributes';
|
|
3
|
-
|
|
4
|
-
describe('toAttributeValue', () => {
|
|
5
|
-
it('returns primitives as-is', () => {
|
|
6
|
-
expect(toAttributeValue('hello')).toBe('hello');
|
|
7
|
-
expect(toAttributeValue(42)).toBe(42);
|
|
8
|
-
expect(toAttributeValue(true)).toBe(true);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('returns homogeneous arrays as-is', () => {
|
|
12
|
-
expect(toAttributeValue(['a', 'b'])).toEqual(['a', 'b']);
|
|
13
|
-
expect(toAttributeValue([1, 2])).toEqual([1, 2]);
|
|
14
|
-
expect(toAttributeValue([true, false])).toEqual([true, false]);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('serialises mixed arrays to JSON', () => {
|
|
18
|
-
expect(toAttributeValue([1, 'a'])).toBe('[1,"a"]');
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('converts Date to ISO string', () => {
|
|
22
|
-
const d = new Date('2025-01-01T00:00:00Z');
|
|
23
|
-
expect(toAttributeValue(d)).toBe('2025-01-01T00:00:00.000Z');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('converts Error to its message', () => {
|
|
27
|
-
expect(toAttributeValue(new Error('boom'))).toBe('boom');
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('returns undefined for plain objects', () => {
|
|
31
|
-
expect(toAttributeValue({ a: 1 })).toBeUndefined();
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('flattenToAttributes', () => {
|
|
36
|
-
it('flattens nested objects with dot-notation keys', () => {
|
|
37
|
-
expect(
|
|
38
|
-
flattenToAttributes({ user: { id: 'u1', plan: 'pro' }, count: 3 }),
|
|
39
|
-
).toEqual({
|
|
40
|
-
'user.id': 'u1',
|
|
41
|
-
'user.plan': 'pro',
|
|
42
|
-
count: 3,
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('uses prefix when provided', () => {
|
|
47
|
-
expect(flattenToAttributes({ key: 'val' }, 'error.details')).toEqual({
|
|
48
|
-
'error.details.key': 'val',
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('skips null and undefined values', () => {
|
|
53
|
-
expect(
|
|
54
|
-
flattenToAttributes({ a: 1, b: null, c: undefined, d: 'ok' }),
|
|
55
|
-
).toEqual({ a: 1, d: 'ok' });
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('handles circular references without stack overflow', () => {
|
|
59
|
-
const obj: Record<string, unknown> = { name: 'root' };
|
|
60
|
-
obj.self = obj;
|
|
61
|
-
|
|
62
|
-
const result = flattenToAttributes(obj);
|
|
63
|
-
expect(result).toEqual({
|
|
64
|
-
name: 'root',
|
|
65
|
-
'self.name': 'root',
|
|
66
|
-
'self.self': '<circular-reference>',
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('serialises non-plain objects to JSON', () => {
|
|
71
|
-
const result = flattenToAttributes({
|
|
72
|
-
date: new Date('2025-01-01T00:00:00Z'),
|
|
73
|
-
});
|
|
74
|
-
expect(result).toEqual({ date: '2025-01-01T00:00:00.000Z' });
|
|
75
|
-
});
|
|
76
|
-
});
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import type { AttributeValue } from './trace-context';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Convert an unknown value to an OTel-compatible AttributeValue.
|
|
5
|
-
* Returns undefined when the value cannot be represented.
|
|
6
|
-
*/
|
|
7
|
-
export function toAttributeValue(value: unknown): AttributeValue | undefined {
|
|
8
|
-
if (
|
|
9
|
-
typeof value === 'string' ||
|
|
10
|
-
typeof value === 'number' ||
|
|
11
|
-
typeof value === 'boolean'
|
|
12
|
-
) {
|
|
13
|
-
return value;
|
|
14
|
-
}
|
|
15
|
-
if (Array.isArray(value)) {
|
|
16
|
-
if (
|
|
17
|
-
value.every((v) => typeof v === 'string') ||
|
|
18
|
-
value.every((v) => typeof v === 'number') ||
|
|
19
|
-
value.every((v) => typeof v === 'boolean')
|
|
20
|
-
) {
|
|
21
|
-
return value as AttributeValue;
|
|
22
|
-
}
|
|
23
|
-
try {
|
|
24
|
-
return JSON.stringify(value);
|
|
25
|
-
} catch {
|
|
26
|
-
return '<serialization-failed>';
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
if (value instanceof Date) {
|
|
30
|
-
return value.toISOString();
|
|
31
|
-
}
|
|
32
|
-
if (value instanceof Error) {
|
|
33
|
-
return value.message;
|
|
34
|
-
}
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Recursively flatten a nested object into dot-notation OTel attributes.
|
|
40
|
-
* Includes circular reference protection via WeakSet.
|
|
41
|
-
*/
|
|
42
|
-
export function flattenToAttributes(
|
|
43
|
-
fields: Record<string, unknown>,
|
|
44
|
-
prefix = '',
|
|
45
|
-
): Record<string, AttributeValue> {
|
|
46
|
-
const out: Record<string, AttributeValue> = {};
|
|
47
|
-
const seen = new WeakSet<object>();
|
|
48
|
-
|
|
49
|
-
function flatten(obj: Record<string, unknown>, currentPrefix: string): void {
|
|
50
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
51
|
-
if (value == null) continue;
|
|
52
|
-
const nextKey = currentPrefix ? `${currentPrefix}.${key}` : key;
|
|
53
|
-
|
|
54
|
-
const attr = toAttributeValue(value);
|
|
55
|
-
if (attr !== undefined) {
|
|
56
|
-
out[nextKey] = attr;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (typeof value === 'object' && value.constructor === Object) {
|
|
61
|
-
if (seen.has(value)) {
|
|
62
|
-
out[nextKey] = '<circular-reference>';
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
seen.add(value);
|
|
66
|
-
flatten(value as Record<string, unknown>, nextKey);
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
out[nextKey] = JSON.stringify(value);
|
|
72
|
-
} catch {
|
|
73
|
-
out[nextKey] = '<serialization-failed>';
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
flatten(fields, prefix);
|
|
79
|
-
return out;
|
|
80
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strict type inference test for the bug:
|
|
3
|
-
* trace() with name parameter returns unknown type
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { trace } from './functional';
|
|
7
|
-
|
|
8
|
-
// This test file should be checked with: npx tsc --noEmit
|
|
9
|
-
|
|
10
|
-
// Helper type to detect unknown - this will be 'true' if T is unknown, 'false' otherwise
|
|
11
|
-
type IsUnknown<T> = unknown extends T
|
|
12
|
-
? T extends unknown
|
|
13
|
-
? true
|
|
14
|
-
: false
|
|
15
|
-
: false;
|
|
16
|
-
|
|
17
|
-
// Test 1: With explicit TraceContext type - this should always work
|
|
18
|
-
const withExplicitType = trace('test-span', () => async () => {
|
|
19
|
-
return { foo: 'bar' };
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// Type assertion - this line should compile without error if type is inferred correctly
|
|
23
|
-
const _test1: () => Promise<{ foo: string }> = withExplicitType;
|
|
24
|
-
|
|
25
|
-
// Test 2: Without explicit TraceContext type - this is the bug scenario
|
|
26
|
-
const withoutExplicitType = trace('test-span', () => async () => {
|
|
27
|
-
return { foo: 'bar' };
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Get the inner type of the Promise returned by the function
|
|
31
|
-
type InnerReturnType = Awaited<ReturnType<typeof withoutExplicitType>>;
|
|
32
|
-
|
|
33
|
-
// This will be 'true' if the bug exists (type is unknown)
|
|
34
|
-
type IsBugPresent = IsUnknown<InnerReturnType>;
|
|
35
|
-
|
|
36
|
-
// Type assertion - if the bug exists, this will fail because IsBugPresent is 'true'
|
|
37
|
-
// If the bug is fixed, IsBugPresent is 'false' and this compiles
|
|
38
|
-
const _bugCheck: IsBugPresent extends false ? 'fixed' : never = 'fixed';
|
|
39
|
-
|
|
40
|
-
// Type assertion - if the bug exists, this line will fail compilation
|
|
41
|
-
// because the return type would be () => Promise<unknown>
|
|
42
|
-
const _test2: () => Promise<{ foo: string }> = withoutExplicitType;
|
|
43
|
-
|
|
44
|
-
// Test 3: Alternative - check if we can access .foo on the result
|
|
45
|
-
async function testAccess() {
|
|
46
|
-
const result = await withoutExplicitType();
|
|
47
|
-
// If the type is unknown, TypeScript will error on .foo access
|
|
48
|
-
// If the type is { foo: string }, this compiles fine
|
|
49
|
-
return result.foo;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Prevent unused variable warnings
|
|
53
|
-
export { _test1, _test2, testAccess, _bugCheck };
|