Skip to content

Commit 8cc1c2a

Browse files
committed
streamline isAttributeObject
1 parent 994f487 commit 8cc1c2a

File tree

3 files changed

+35
-56
lines changed

3 files changed

+35
-56
lines changed

packages/core/src/attributes.ts

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export type RawAttributes<T> = T & ValidatedAttributes<T>;
22
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3-
export type RawAttribute<T> = T extends { value: any } | { unit: any } ? AttributeWithUnit : T;
3+
export type RawAttribute<T> = T extends { value: any } | { unit: any } ? AttributeObject : T;
44

55
export type Attributes = Record<string, TypedAttributeValue>;
66

@@ -31,7 +31,7 @@ type AttributeUnion = {
3131

3232
export type TypedAttributeValue = AttributeUnion & { unit?: Units };
3333

34-
export type AttributeWithUnit = {
34+
export type AttributeObject = {
3535
value: unknown;
3636
unit?: Units;
3737
};
@@ -44,35 +44,20 @@ type Units = 'ms' | 's' | 'bytes' | 'count' | 'percent' | string;
4444
/* If an attribute has either a 'value' or 'unit' property, we use the ValidAttributeObject type. */
4545
export type ValidatedAttributes<T> = {
4646
// eslint-disable-next-line @typescript-eslint/no-explicit-any
47-
[K in keyof T]: T[K] extends { value: any } | { unit: any } ? AttributeWithUnit : unknown;
47+
[K in keyof T]: T[K] extends { value: any } | { unit: any } ? AttributeObject : unknown;
4848
};
4949

5050
/**
5151
* Type-guard: The attribute object has the shape the official attribute object (value, type, unit).
5252
* https://develop.sentry.dev/sdk/telemetry/scopes/#setting-attributes
5353
*/
54-
export function isAttributeObject(maybeObj: unknown): maybeObj is AttributeWithUnit {
55-
if (typeof maybeObj !== 'object' || maybeObj == null || Array.isArray(maybeObj)) {
56-
return false;
57-
}
58-
59-
// MUST have 'value' property
60-
// MAY have 'unit' property
61-
// MUST NOT have other properties
62-
const keys = Object.keys(maybeObj);
63-
64-
// MUST have 'value'
65-
if (!keys.includes('value')) {
66-
return false;
67-
}
68-
69-
// ALLOWED keys: 'value', optionally 'unit'
70-
if (keys.some(k => k !== 'value' && k !== 'unit')) {
71-
return false;
72-
}
73-
74-
// All checks passed
75-
return true;
54+
export function isAttributeObject(maybeObj: unknown): maybeObj is AttributeObject {
55+
return (
56+
typeof maybeObj === 'object' &&
57+
maybeObj != null &&
58+
!Array.isArray(maybeObj) &&
59+
Object.keys(maybeObj).includes('value')
60+
);
7661
}
7762

7863
/**

packages/core/src/scope.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable max-lines */
2-
import type { AttributeWithUnit, RawAttribute, RawAttributes } from './attributes';
2+
import type { AttributeObject, RawAttribute, RawAttributes } from './attributes';
33
import type { Client } from './client';
44
import { DEBUG_BUILD } from './debug-build';
55
import { updateSession } from './session';
@@ -350,7 +350,7 @@ export class Scope {
350350
* ```
351351
*/
352352
// eslint-disable-next-line @typescript-eslint/no-explicit-any
353-
public setAttribute<T extends RawAttribute<T> extends { value: any } | { unit: any } ? AttributeWithUnit : unknown>(
353+
public setAttribute<T extends RawAttribute<T> extends { value: any } | { unit: any } ? AttributeObject : unknown>(
354354
key: string,
355355
value: RawAttribute<T>,
356356
): this {

packages/core/test/lib/attributes.test.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,17 @@ describe('attributeValueToTypedAttributeValue', () => {
125125
unit: 'bytes',
126126
});
127127
});
128+
129+
it('extracts the value property of an object with a value property', () => {
130+
// and ignores other properties.
131+
// For now we're fine with this but we may reconsider in the future.
132+
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit: 'ms', bar: 'baz' });
133+
expect(result).toStrictEqual({
134+
value: 'foo',
135+
unit: 'ms',
136+
type: 'string',
137+
});
138+
});
128139
});
129140

130141
describe('unsupported value types', () => {
@@ -233,22 +244,6 @@ describe('attributeValueToTypedAttributeValue', () => {
233244
type: 'string',
234245
});
235246
});
236-
237-
it('stringifies an attribute-object-like object with additional properties to a string attribute value', () => {
238-
const result = attributeValueToTypedAttributeValue({ value: 'foo', bar: 'baz' });
239-
expect(result).toStrictEqual({
240-
value: '{"value":"foo","bar":"baz"}',
241-
type: 'string',
242-
});
243-
});
244-
245-
it('stringifies an attribute-object-like object with a unit property to a string attribute value', () => {
246-
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit: 'ms', bar: 'baz' });
247-
expect(result).toStrictEqual({
248-
value: '{"value":"foo","unit":"ms","bar":"baz"}',
249-
type: 'string',
250-
});
251-
});
252247
});
253248

254249
it.each([1, true, null, undefined, NaN, Symbol('test'), { foo: 'bar' }])(
@@ -275,18 +270,17 @@ describe('isAttributeObject', () => {
275270
expect(result).toBe(true);
276271
});
277272

278-
it.each([
279-
1,
280-
true,
281-
'test',
282-
null,
283-
undefined,
284-
NaN,
285-
Symbol('test'),
286-
{ value: { foo: 'bar' }, bar: 'baz' },
287-
{ value: 1, unit: 'ms', anotherProperty: 'test' },
288-
])('returns false for an invalid attribute object (%s)', obj => {
289-
const result = isAttributeObject(obj);
290-
expect(result).toBe(false);
273+
it('returns true for an object with a value property', () => {
274+
// Explicitly demonstrate this behaviour which for now we're fine with.
275+
// We may reconsider in the future.
276+
expect(isAttributeObject({ value: 123.45, some: 'other property' })).toBe(true);
291277
});
278+
279+
it.each([1, true, 'test', null, undefined, NaN, Symbol('test')])(
280+
'returns false for an invalid attribute object (%s)',
281+
obj => {
282+
const result = isAttributeObject(obj);
283+
expect(result).toBe(false);
284+
},
285+
);
292286
});

0 commit comments

Comments
 (0)