Skip to content

Commit 8e4e671

Browse files
authored
ref(types): Verbosify envelope types (#4609)
This PR refactors our `Envelope` types, with the goal of both slightly simplifying the implementation and (primarily) moving from having values inlined to assigning them to variables, in order to make it easier to see how all of the parts fit together. Notes: - In addition to the envelope types, there are two new types, `UserFeedback` and `ClientReport`, representing the payloads of their respective envelope types. - Both envelope and item headers base types are now objects containing all optional and required properties (as well as an index signature allowing them to be extended). This allows us to avoid having to perform type intersections in the item and envelope types, thus making them easier to parse. - All formerly inlined values are split out into variables, in order to be able to use naming as a way to show exactly what's in each successive wrapper type. - All of the base types are exported in order to allow them to be extended in other SDKs. Also exported, primarily for the purposes of type casting, are the various item and envelope types. Header types aren't exported because they're internal to items and envelopes, which are the only two units upon which outside code should be acting.
1 parent 22a7cf3 commit 8e4e671

File tree

4 files changed

+61
-59
lines changed

4 files changed

+61
-59
lines changed

packages/types/src/clientreport.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { SentryRequestType } from './request';
2+
import { Outcome } from './transport';
3+
4+
export type ClientReport = {
5+
timestamp: number;
6+
discarded_events: { reason: Outcome; category: SentryRequestType; quantity: number };
7+
};

packages/types/src/envelope.ts

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,51 @@
1+
import { ClientReport } from './clientreport';
12
import { Event } from './event';
2-
import { SentryRequestType } from './request';
33
import { SdkInfo } from './sdkinfo';
44
import { Session, SessionAggregates } from './session';
5-
import { Outcome } from './transport';
6-
import { User } from './user';
5+
import { UserFeedback } from './user';
76

87
// Based on: https://develop.sentry.dev/sdk/envelopes/
98

10-
type CommonEnvelopeHeaders = {
9+
export type BaseEnvelopeHeaders = {
10+
[key: string]: unknown;
1111
dsn?: string;
1212
sdk?: SdkInfo;
1313
};
1414

15-
type CommonEnvelopeItemHeaders = {
15+
export type BaseEnvelopeItemHeaders = {
16+
[key: string]: unknown;
17+
type: string;
1618
length?: number;
1719
};
1820

19-
/**
20-
* 1st Item: Item headers
21-
* 2nd Item: Item payload
22-
*/
23-
type BaseEnvelopeItem<ItemHeader extends { type: string }, Payload = unknown> = [
24-
CommonEnvelopeItemHeaders & ItemHeader,
25-
Payload,
26-
];
27-
28-
type UnknownEnvelopeItem = BaseEnvelopeItem<{ type: '__unknown__' }>;
29-
30-
type BaseEnvelope<
31-
EnvelopeHeaders extends Record<string, unknown>,
32-
EnvelopeItem extends BaseEnvelopeItem<{ type: string }>,
33-
> = {
34-
headers: CommonEnvelopeHeaders & EnvelopeHeaders;
35-
items: Array<EnvelopeItem | UnknownEnvelopeItem>;
36-
};
37-
38-
export type EventEnvelopeItem = BaseEnvelopeItem<{ type: 'event' | 'transaction' }, Event>;
39-
40-
type AttachmentEnvelopeItem = BaseEnvelopeItem<{ type: 'attachment'; filename: 'string' }>;
41-
42-
type UserFeedbackEnvelopeItem = BaseEnvelopeItem<
43-
{ type: 'user_report' },
44-
{
45-
event_id: string;
46-
email: User['email'];
47-
name: string;
48-
comments: string;
49-
}
50-
>;
51-
52-
export type EventEnvelope = BaseEnvelope<
53-
{ event_id: string; sent_at: string },
54-
EventEnvelopeItem | AttachmentEnvelopeItem | UserFeedbackEnvelopeItem
55-
>;
56-
57-
export type SessionEnvelopeItem =
58-
| BaseEnvelopeItem<{ type: 'session' }, Session>
59-
| BaseEnvelopeItem<{ type: 'sessions' }, SessionAggregates>;
60-
61-
export type SessionEnvelope = BaseEnvelope<{ sent_at: string }, SessionEnvelopeItem>;
62-
63-
export type ClientReportEnvelopeItem = BaseEnvelopeItem<
64-
{ type: 'client_report' },
65-
{ timestamp: number; discarded_events: { reason: Outcome; category: SentryRequestType; quantity: number } }
66-
>;
67-
68-
export type ClientReportEnvelope = BaseEnvelope<Record<string, unknown>, ClientReportEnvelopeItem>;
21+
export type BaseEnvelopeItem<IH extends BaseEnvelopeItemHeaders, P extends unknown> = [IH, P]; // P is for payload
22+
23+
export type BaseEnvelope<
24+
EH extends BaseEnvelopeHeaders,
25+
I extends BaseEnvelopeItem<BaseEnvelopeItemHeaders, unknown>,
26+
> = [EH, I[]];
27+
28+
type EventItemHeaders = { type: 'event' | 'transaction' };
29+
type AttachmentItemHeaders = { type: 'attachment'; filename: string };
30+
type UserFeedbackItemHeaders = { type: 'user_report' };
31+
type SessionItemHeaders = { type: 'session' };
32+
type SessionAggregatesItemHeaders = { type: 'sessions' };
33+
type ClientReportItemHeaders = { type: 'client_report' };
34+
35+
export type EventItem = BaseEnvelopeItem<EventItemHeaders, Event>;
36+
export type AttachmentItem = BaseEnvelopeItem<AttachmentItemHeaders, unknown>;
37+
export type UserFeedbackItem = BaseEnvelopeItem<UserFeedbackItemHeaders, UserFeedback>;
38+
export type SessionItem =
39+
| BaseEnvelopeItem<SessionItemHeaders, Session>
40+
| BaseEnvelopeItem<SessionAggregatesItemHeaders, SessionAggregates>;
41+
export type ClientReportItem = BaseEnvelopeItem<ClientReportItemHeaders, ClientReport>;
42+
43+
type EventEnvelopeHeaders = { event_id: string; sent_at: string };
44+
type SessionEnvelopeHeaders = { sent_at: string };
45+
type ClientReportEnvelopeHeaders = BaseEnvelopeHeaders;
46+
47+
export type EventEnvelope = BaseEnvelope<EventEnvelopeHeaders, EventItem | AttachmentItem | UserFeedbackItem>;
48+
export type SessionEnvelope = BaseEnvelope<SessionEnvelopeHeaders, SessionItem>;
49+
export type ClientReportEnvelope = BaseEnvelope<ClientReportEnvelopeHeaders, ClientReportItem>;
6950

7051
export type Envelope = EventEnvelope | SessionEnvelope | ClientReportEnvelope;

packages/types/src/index.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
export { Breadcrumb, BreadcrumbHint } from './breadcrumb';
22
export { Client } from './client';
3+
export { ClientReport } from './clientreport';
34
export { Context, Contexts } from './context';
45
export { DsnComponents, DsnLike, DsnProtocol } from './dsn';
56
export { DebugImage, DebugImageType, DebugMeta } from './debugMeta';
67
export {
8+
AttachmentItem,
9+
BaseEnvelope,
10+
BaseEnvelopeHeaders,
11+
BaseEnvelopeItem,
12+
BaseEnvelopeItemHeaders,
713
ClientReportEnvelope,
8-
ClientReportEnvelopeItem,
14+
ClientReportItem,
915
Envelope,
1016
EventEnvelope,
11-
EventEnvelopeItem,
17+
EventItem,
1218
SessionEnvelope,
13-
SessionEnvelopeItem,
19+
SessionItem,
20+
UserFeedbackItem,
1421
} from './envelope';
1522
export { ExtendedError } from './error';
1623
export { Event, EventHint } from './event';
@@ -58,5 +65,5 @@ export {
5865
} from './transaction';
5966
export { Thread } from './thread';
6067
export { Outcome, Transport, TransportOptions, TransportClass } from './transport';
61-
export { User } from './user';
68+
export { User, UserFeedback } from './user';
6269
export { WrappedFunction } from './wrappedfunction';

packages/types/src/user.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,10 @@ export interface User {
66
email?: string;
77
username?: string;
88
}
9+
10+
export interface UserFeedback {
11+
event_id: string;
12+
email: User['email'];
13+
name: string;
14+
comments: string;
15+
}

0 commit comments

Comments
 (0)