-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathmatcher.ts
159 lines (155 loc) · 3.98 KB
/
matcher.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import { style } from '@ogma/styler';
import { isIP } from 'net';
import { ok } from 'uvu/assert';
interface LogObject {
/**
* The IP or IP addresses of the machine making a call to the server
*/
callerAddress: string[] | string;
/**
* REST: an HTTP Verb (GET, POST, PATCH, etc)
*
* GraphQL: Query, Mutation, or Subscription
*
* Microservice: Request or Reply
*
* Websockets: unknown at moment
*/
method: string;
/**
* REST: endpoint
*
* GraphQL: Query or Mutation name
*
* Microservice: Message Topic
*
* WebSockets: Subscription Event name
*/
callPoint: string;
/**
* REST: HTTP/majorVersion.minorVersion e.g. `HTTP/1.1`
*
* GraphQL: HTTP/majorVersion.minorVersion e.g. `HTTP/1.1`
*
* Microservice: microservice type e.g. amqp
*
* WebSockets: ws
*/
protocol: string;
/**
* REST: HTTP Status code, will extract from Nest Exception if possible
*
* GraphQL: HTTP Status code, will extract from Nest Exception if possible
*
* Microservice: 200 for success, 500 for error
*
* Websockets: 200 for success, 500 for error
*/
status: string;
/**
* The time it took the request, in milliseconds, from entering the interceptor to leaving the interceptor
*/
responseTime: number;
/**
* Number of bytes in the response data, determined by Buffer encoding the response body
*/
contentLength: number;
}
const timeRegex = /\d+ms/;
const sizeRegex = /\d+/;
const expectMessage = (field: string, expected: string, actual: string) =>
`Expected ${field} to be ${style.green.apply(expected)} but got ${style.red.apply(actual)}.\n`;
const doTest = (
recIp: string,
method: string,
recMethod: string,
endpoint: string,
recEndpoint: string,
protocol: string,
recProto: string,
status: string,
recStatus: string,
recTime: string,
recSize: string,
): { pass: boolean; message: string } => {
let pass = true;
let message = '';
if (!isIP(recIp) && !isIP(recIp.split(/:\d{2,}/)[0])) {
pass = false;
message += expectMessage('Caller Ip', 'an IPv4 or IPv6', recIp);
}
if (recMethod !== method) {
pass = false;
message += expectMessage('method', method, recMethod);
}
if (recEndpoint !== endpoint) {
pass = false;
message += expectMessage('endpoint', endpoint, recEndpoint);
}
if (!recProto.match(protocol)) {
pass = false;
message += expectMessage('protocol', protocol, recProto);
}
if (recStatus !== status) {
pass = false;
message += expectMessage('status', status, recStatus);
}
if (!timeRegex.test(recTime)) {
pass = false;
message += expectMessage('time', 'a time in milliseconds', recTime);
}
if (!sizeRegex.test(recSize)) {
pass = false;
message += expectMessage('size', 'a content-size in bytes', recSize);
}
return { pass, message };
};
export const toBeALogObject = (
received: string | LogObject,
method: string,
endpoint: string,
protocol: string,
status: string,
) => {
let recIp: string,
recMethod: string,
recEndpoint: string,
recProto: string,
recStatus: string,
recTime: string,
recSize: string;
if (typeof received === 'string') {
[recIp, , recMethod, recEndpoint, recProto, recStatus, recTime, , recSize] =
received.split(' ');
} else {
let callerAddress: string | string[], responseTime: number, contentLength: number;
({
callerAddress,
protocol: recProto,
callPoint: recEndpoint,
responseTime,
status: recStatus,
method: recMethod,
contentLength,
} = received);
recIp = Array.isArray(callerAddress) ? callerAddress.join(' ') : callerAddress;
recTime = responseTime.toString();
recSize = contentLength.toString();
recTime = `${recTime.toString()}ms`;
recSize = recSize.toString();
}
const result = doTest(
recIp,
method,
recMethod,
endpoint,
recEndpoint,
protocol,
recProto,
status,
recStatus,
recTime,
recSize,
);
ok(result.pass, result.message);
};