-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathresponse.ts
144 lines (130 loc) · 3.91 KB
/
response.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { Status } from './status';
import { IncomingMessage } from 'http';
/** A response body for a request that returned 200 (successful). */
export type SuccessBody = {
eventsIngested: number;
payloadSizeBytes: number;
serverUploadTime: number;
};
/** A response body for a request that returned 413 (invalid request). */
export type InvalidRequestBody = {
error: string;
missingField: string | null;
eventsWithInvalidFields: { [eventField: string]: Array<number> };
eventsWithMissingFields: { [eventField: string]: Array<number> };
};
/** A response body for a request that returned 413 (payload too large). */
export type PayloadTooLargeBody = {
error: string;
};
/** A response body for a request that returned 429 (rate limit). */
export type RateLimitBody = {
error: string;
epsThreshold: number;
throttledDevices: { [deviceId: string]: number };
throttledUsers: { [userId: string]: number };
exceededDailyQuotaDevices: { [deviceId: string]: number };
exceededDailyQuotaUsers: { [userId: string]: number };
throttledEvents: Array<number>;
};
export type StatusWithResponseBody = Status.Invalid | Status.PayloadTooLarge | Status.RateLimit | Status.Success;
/** Represents additional data that is provided by the http v2 API */
export type ResponseBody = SuccessBody | InvalidRequestBody | PayloadTooLargeBody | RateLimitBody;
export const mapJSONToResponse = (json: any): Response | null => {
if (typeof json !== 'object') {
return null;
}
const status = Status.fromHttpCode(json.code);
const statusCode = json.code;
switch (status) {
case Status.Success:
return {
status,
statusCode,
body: {
eventsIngested: json.events_ingested,
payloadSizeBytes: json.payload_size_bytes,
serverUploadTime: json.server_upload_time,
},
};
case Status.Invalid:
return {
status,
statusCode,
body: {
error: json.error ?? '',
missingField: json.missing_field ?? null,
eventsWithInvalidFields: json.events_with_invalid_fields ?? {},
eventsWithMissingFields: json.events_with_missing_fields ?? {},
},
};
case Status.PayloadTooLarge:
return {
status,
statusCode,
body: {
error: json.error ?? '',
},
};
case Status.RateLimit:
return {
status,
statusCode,
body: {
error: json.error ?? '',
epsThreshold: json.eps_threshold,
throttledDevices: json.throttled_devices ?? {},
throttledUsers: json.throttled_users ?? {},
exceededDailyQuotaDevices: json.exceeded_daily_quota_devices ?? {},
exceededDailyQuotaUsers: json.exceeded_daily_quota_users ?? {},
throttledEvents: json.throttled_events ?? [],
},
};
default:
return {
status,
statusCode,
};
}
};
export const mapHttpMessageToResponse = (httpRes: IncomingMessage): Response => {
const statusCode = httpRes.statusCode === undefined ? 0 : httpRes.statusCode;
const status = Status.fromHttpCode(statusCode);
return {
status,
statusCode,
};
};
/** JSDoc */
export type Response =
| {
status: Status.Success;
statusCode: number;
body?: SuccessBody;
}
| {
status: Status.Invalid;
statusCode: number;
body?: InvalidRequestBody;
}
| {
status: Status.PayloadTooLarge;
statusCode: number;
body?: PayloadTooLargeBody;
}
| {
status: Status.RateLimit;
statusCode: number;
body?: RateLimitBody;
}
| {
status: Exclude<Status, StatusWithResponseBody>;
statusCode: number;
};
/** The Response to expect if a request might have been sent but it was skipped
* e.g. no events to flush, user has opted out and nothing should be sent.
*/
export const SKIPPED_RESPONSE: Response = {
status: Status.Skipped,
statusCode: 0,
};