@flakiness/sdk 0.95.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.
@@ -0,0 +1,331 @@
1
+ // ../server/lib/common/typedHttp.js
2
+ var TypedHTTP;
3
+ ((TypedHTTP2) => {
4
+ TypedHTTP2.StatusCodes = {
5
+ Informational: {
6
+ CONTINUE: 100,
7
+ SWITCHING_PROTOCOLS: 101,
8
+ PROCESSING: 102,
9
+ EARLY_HINTS: 103
10
+ },
11
+ Success: {
12
+ OK: 200,
13
+ CREATED: 201,
14
+ ACCEPTED: 202,
15
+ NON_AUTHORITATIVE_INFORMATION: 203,
16
+ NO_CONTENT: 204,
17
+ RESET_CONTENT: 205,
18
+ PARTIAL_CONTENT: 206,
19
+ MULTI_STATUS: 207
20
+ },
21
+ Redirection: {
22
+ MULTIPLE_CHOICES: 300,
23
+ MOVED_PERMANENTLY: 301,
24
+ MOVED_TEMPORARILY: 302,
25
+ SEE_OTHER: 303,
26
+ NOT_MODIFIED: 304,
27
+ USE_PROXY: 305,
28
+ TEMPORARY_REDIRECT: 307,
29
+ PERMANENT_REDIRECT: 308
30
+ },
31
+ ClientErrors: {
32
+ BAD_REQUEST: 400,
33
+ UNAUTHORIZED: 401,
34
+ PAYMENT_REQUIRED: 402,
35
+ FORBIDDEN: 403,
36
+ NOT_FOUND: 404,
37
+ METHOD_NOT_ALLOWED: 405,
38
+ NOT_ACCEPTABLE: 406,
39
+ PROXY_AUTHENTICATION_REQUIRED: 407,
40
+ REQUEST_TIMEOUT: 408,
41
+ CONFLICT: 409,
42
+ GONE: 410,
43
+ LENGTH_REQUIRED: 411,
44
+ PRECONDITION_FAILED: 412,
45
+ REQUEST_TOO_LONG: 413,
46
+ REQUEST_URI_TOO_LONG: 414,
47
+ UNSUPPORTED_MEDIA_TYPE: 415,
48
+ REQUESTED_RANGE_NOT_SATISFIABLE: 416,
49
+ EXPECTATION_FAILED: 417,
50
+ IM_A_TEAPOT: 418,
51
+ INSUFFICIENT_SPACE_ON_RESOURCE: 419,
52
+ METHOD_FAILURE: 420,
53
+ MISDIRECTED_REQUEST: 421,
54
+ UNPROCESSABLE_ENTITY: 422,
55
+ LOCKED: 423,
56
+ FAILED_DEPENDENCY: 424,
57
+ UPGRADE_REQUIRED: 426,
58
+ PRECONDITION_REQUIRED: 428,
59
+ TOO_MANY_REQUESTS: 429,
60
+ REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
61
+ UNAVAILABLE_FOR_LEGAL_REASONS: 451
62
+ },
63
+ ServerErrors: {
64
+ INTERNAL_SERVER_ERROR: 500,
65
+ NOT_IMPLEMENTED: 501,
66
+ BAD_GATEWAY: 502,
67
+ SERVICE_UNAVAILABLE: 503,
68
+ GATEWAY_TIMEOUT: 504,
69
+ HTTP_VERSION_NOT_SUPPORTED: 505,
70
+ INSUFFICIENT_STORAGE: 507,
71
+ NETWORK_AUTHENTICATION_REQUIRED: 511
72
+ }
73
+ };
74
+ const AllErrorCodes = {
75
+ ...TypedHTTP2.StatusCodes.ClientErrors,
76
+ ...TypedHTTP2.StatusCodes.ServerErrors
77
+ };
78
+ class HttpError extends Error {
79
+ constructor(status, message) {
80
+ super(message);
81
+ this.status = status;
82
+ }
83
+ static withCode(code, message) {
84
+ const statusCode = AllErrorCodes[code];
85
+ const defaultMessage = code.split("_").map((word) => word.charAt(0) + word.slice(1).toLowerCase()).join(" ");
86
+ return new HttpError(statusCode, message ?? defaultMessage);
87
+ }
88
+ }
89
+ TypedHTTP2.HttpError = HttpError;
90
+ function isInformationalResponse(response) {
91
+ return response.status >= 100 && response.status < 200;
92
+ }
93
+ TypedHTTP2.isInformationalResponse = isInformationalResponse;
94
+ function isSuccessResponse(response) {
95
+ return response.status >= 200 && response.status < 300;
96
+ }
97
+ TypedHTTP2.isSuccessResponse = isSuccessResponse;
98
+ function isRedirectResponse(response) {
99
+ return response.status >= 300 && response.status < 400;
100
+ }
101
+ TypedHTTP2.isRedirectResponse = isRedirectResponse;
102
+ function isErrorResponse(response) {
103
+ return response.status >= 400 && response.status < 600;
104
+ }
105
+ TypedHTTP2.isErrorResponse = isErrorResponse;
106
+ function info(status) {
107
+ return { status };
108
+ }
109
+ TypedHTTP2.info = info;
110
+ function ok(data, status) {
111
+ return {
112
+ status: status ?? TypedHTTP2.StatusCodes.Success.OK,
113
+ data
114
+ };
115
+ }
116
+ TypedHTTP2.ok = ok;
117
+ function redirect(url, status = 302) {
118
+ return { status, url };
119
+ }
120
+ TypedHTTP2.redirect = redirect;
121
+ function error(message, status = TypedHTTP2.StatusCodes.ServerErrors.INTERNAL_SERVER_ERROR) {
122
+ return { status, message };
123
+ }
124
+ TypedHTTP2.error = error;
125
+ class Router {
126
+ constructor(_resolveContext) {
127
+ this._resolveContext = _resolveContext;
128
+ }
129
+ static create() {
130
+ return new Router(async (e) => e.ctx);
131
+ }
132
+ rawMethod(method, route) {
133
+ return {
134
+ [method]: {
135
+ method,
136
+ input: route.input,
137
+ etag: route.etag,
138
+ resolveContext: this._resolveContext,
139
+ handler: route.handler
140
+ }
141
+ };
142
+ }
143
+ get(route) {
144
+ return this.rawMethod("GET", {
145
+ ...route,
146
+ handler: (...args) => Promise.resolve(route.handler(...args)).then((result) => TypedHTTP2.ok(result))
147
+ });
148
+ }
149
+ post(route) {
150
+ return this.rawMethod("POST", {
151
+ ...route,
152
+ handler: (...args) => Promise.resolve(route.handler(...args)).then((result) => TypedHTTP2.ok(result))
153
+ });
154
+ }
155
+ use(resolveContext) {
156
+ return new Router(async (options) => {
157
+ const m = await this._resolveContext(options);
158
+ return resolveContext({ ...options, ctx: m });
159
+ });
160
+ }
161
+ }
162
+ TypedHTTP2.Router = Router;
163
+ function createClient(base, fetchCallback) {
164
+ function buildUrl(path, input, options) {
165
+ const method = path.at(-1);
166
+ const url = new URL(path.slice(0, path.length - 1).join("/"), base);
167
+ const signal = options?.signal;
168
+ let body = void 0;
169
+ if (method === "GET" && input)
170
+ url.searchParams.set("input", JSON.stringify(input));
171
+ else if (method !== "GET" && input)
172
+ body = JSON.stringify(input);
173
+ return {
174
+ url,
175
+ method,
176
+ headers: body ? { "Content-Type": "application/json" } : void 0,
177
+ body,
178
+ signal
179
+ };
180
+ }
181
+ function createProxy(path = []) {
182
+ return new Proxy(() => {
183
+ }, {
184
+ get(target, prop) {
185
+ if (typeof prop === "symbol")
186
+ return void 0;
187
+ if (prop === "prepare")
188
+ return (input, options) => buildUrl(path, input, options);
189
+ const newPath = [...path, prop];
190
+ return createProxy(newPath);
191
+ },
192
+ apply(target, thisArg, args) {
193
+ const options = buildUrl(path, args[0], args[1]);
194
+ return fetchCallback(options.url, {
195
+ method: options.method,
196
+ body: options.body,
197
+ headers: options.headers,
198
+ signal: options.signal
199
+ }).then(async (response) => {
200
+ if (response.status >= 200 && response.status < 300) {
201
+ if (response.headers.get("content-type")?.includes("application/json")) {
202
+ const text = await response.text();
203
+ return text.length ? JSON.parse(text) : void 0;
204
+ }
205
+ return await response.blob();
206
+ }
207
+ if (response.status >= 400 && response.status < 600) {
208
+ const text = await response.text();
209
+ if (text)
210
+ throw new Error(`HTTP request failed with status ${response.status}: ${text}`);
211
+ else
212
+ throw new Error(`HTTP request failed with status ${response.status}`);
213
+ }
214
+ });
215
+ }
216
+ });
217
+ }
218
+ return createProxy();
219
+ }
220
+ TypedHTTP2.createClient = createClient;
221
+ })(TypedHTTP || (TypedHTTP = {}));
222
+
223
+ // src/utils.ts
224
+ import http from "http";
225
+ import https from "https";
226
+ import util from "util";
227
+ import zlib from "zlib";
228
+ var gzipAsync = util.promisify(zlib.gzip);
229
+ var gunzipAsync = util.promisify(zlib.gunzip);
230
+ var gunzipSync = zlib.gunzipSync;
231
+ var brotliCompressAsync = util.promisify(zlib.brotliCompress);
232
+ var brotliCompressSync = zlib.brotliCompressSync;
233
+ async function retryWithBackoff(job, backoff = []) {
234
+ for (const timeout of backoff) {
235
+ try {
236
+ return await job();
237
+ } catch (e) {
238
+ if (e instanceof AggregateError)
239
+ console.error(`[flakiness.io err]`, e.errors[0].message);
240
+ else if (e instanceof Error)
241
+ console.error(`[flakiness.io err]`, e.message);
242
+ else
243
+ console.error(`[flakiness.io err]`, e);
244
+ await new Promise((x) => setTimeout(x, timeout));
245
+ }
246
+ }
247
+ return await job();
248
+ }
249
+ var httpUtils;
250
+ ((httpUtils2) => {
251
+ function createRequest({ url, method = "get", headers = {} }) {
252
+ let resolve;
253
+ let reject;
254
+ const responseDataPromise = new Promise((a, b) => {
255
+ resolve = a;
256
+ reject = b;
257
+ });
258
+ const protocol = url.startsWith("https") ? https : http;
259
+ const request = protocol.request(url, { method, headers }, (res) => {
260
+ const chunks = [];
261
+ res.on("data", (chunk) => chunks.push(chunk));
262
+ res.on("end", () => {
263
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300)
264
+ resolve(Buffer.concat(chunks));
265
+ else
266
+ reject(new Error(`Request to ${url} failed with ${res.statusCode}`));
267
+ });
268
+ res.on("error", (error) => reject(error));
269
+ });
270
+ request.on("error", reject);
271
+ return { request, responseDataPromise };
272
+ }
273
+ httpUtils2.createRequest = createRequest;
274
+ async function getBuffer(url, backoff) {
275
+ return await retryWithBackoff(async () => {
276
+ const { request, responseDataPromise } = createRequest({ url });
277
+ request.end();
278
+ return await responseDataPromise;
279
+ }, backoff);
280
+ }
281
+ httpUtils2.getBuffer = getBuffer;
282
+ async function getText(url, backoff) {
283
+ const buffer = await getBuffer(url, backoff);
284
+ return buffer.toString("utf-8");
285
+ }
286
+ httpUtils2.getText = getText;
287
+ async function getJSON(url) {
288
+ return JSON.parse(await getText(url));
289
+ }
290
+ httpUtils2.getJSON = getJSON;
291
+ async function postText(url, text, backoff) {
292
+ const headers = {
293
+ "Content-Type": "application/json",
294
+ "Content-Length": Buffer.byteLength(text) + ""
295
+ };
296
+ return await retryWithBackoff(async () => {
297
+ const { request, responseDataPromise } = createRequest({ url, headers, method: "post" });
298
+ request.write(text);
299
+ request.end();
300
+ return await responseDataPromise;
301
+ }, backoff);
302
+ }
303
+ httpUtils2.postText = postText;
304
+ async function postJSON(url, json, backoff) {
305
+ const buffer = await postText(url, JSON.stringify(json), backoff);
306
+ return JSON.parse(buffer.toString("utf-8"));
307
+ }
308
+ httpUtils2.postJSON = postJSON;
309
+ })(httpUtils || (httpUtils = {}));
310
+ var ansiRegex = new RegExp("[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", "g");
311
+ var IS_WIN32_PATH = new RegExp("^[a-zA-Z]:\\\\", "i");
312
+ var IS_ALMOST_POSIX_PATH = new RegExp("^[a-zA-Z]:/", "i");
313
+
314
+ // src/serverapi.ts
315
+ function createServerAPI(endpoint, options) {
316
+ endpoint += "/api/";
317
+ const fetcher = options?.auth ? (url, init) => fetch(url, {
318
+ ...init,
319
+ headers: {
320
+ ...init.headers,
321
+ "Authorization": `Bearer ${options.auth}`
322
+ }
323
+ }) : fetch;
324
+ if (options?.retries)
325
+ return TypedHTTP.createClient(endpoint, (url, init) => retryWithBackoff(() => fetcher(url, init), options.retries));
326
+ return TypedHTTP.createClient(endpoint, fetcher);
327
+ }
328
+ export {
329
+ createServerAPI
330
+ };
331
+ //# sourceMappingURL=serverapi.js.map
@@ -0,0 +1,71 @@
1
+ // src/systemUtilizationSampler.ts
2
+ import { spawnSync } from "child_process";
3
+ import os from "os";
4
+ function getAvailableMemMacOS() {
5
+ const lines = spawnSync("vm_stat", { encoding: "utf8" }).stdout.trim().split("\n");
6
+ const pageSize = parseInt(lines[0].match(/page size of (\d+) bytes/)[1], 10);
7
+ if (isNaN(pageSize)) {
8
+ console.warn("[flakiness.io] Error detecting macos page size");
9
+ return 0;
10
+ }
11
+ let totalFree = 0;
12
+ for (const line of lines) {
13
+ if (/Pages (free|inactive|speculative):/.test(line)) {
14
+ const match = line.match(/\d+/);
15
+ if (match)
16
+ totalFree += parseInt(match[0], 10);
17
+ }
18
+ }
19
+ return totalFree * pageSize;
20
+ }
21
+ function getSystemUtilization() {
22
+ let idleTicks = 0;
23
+ let totalTicks = 0;
24
+ for (const cpu of os.cpus()) {
25
+ totalTicks += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq + cpu.times.idle;
26
+ idleTicks += cpu.times.idle;
27
+ }
28
+ return {
29
+ idleTicks,
30
+ totalTicks,
31
+ timestamp: Date.now(),
32
+ freeBytes: os.platform() === "darwin" ? getAvailableMemMacOS() : os.freemem()
33
+ };
34
+ }
35
+ function toFKUtilization(sample, previous) {
36
+ const idleTicks = sample.idleTicks - previous.idleTicks;
37
+ const totalTicks = sample.totalTicks - previous.totalTicks;
38
+ const cpuUtilization = Math.floor((1 - idleTicks / totalTicks) * 1e4) / 100;
39
+ const memoryUtilization = Math.floor((1 - sample.freeBytes / os.totalmem()) * 1e4) / 100;
40
+ return {
41
+ cpuUtilization,
42
+ memoryUtilization,
43
+ dts: sample.timestamp - previous.timestamp
44
+ };
45
+ }
46
+ var SystemUtilizationSampler = class {
47
+ result;
48
+ _lastSample = getSystemUtilization();
49
+ _timer;
50
+ constructor() {
51
+ this.result = {
52
+ samples: [],
53
+ startTimestamp: this._lastSample.timestamp,
54
+ totalMemoryBytes: os.totalmem()
55
+ };
56
+ this._timer = setTimeout(this._addSample.bind(this), 50);
57
+ }
58
+ _addSample() {
59
+ const sample = getSystemUtilization();
60
+ this.result.samples.push(toFKUtilization(sample, this._lastSample));
61
+ this._lastSample = sample;
62
+ this._timer = setTimeout(this._addSample.bind(this), 1e3);
63
+ }
64
+ dispose() {
65
+ clearTimeout(this._timer);
66
+ }
67
+ };
68
+ export {
69
+ SystemUtilizationSampler
70
+ };
71
+ //# sourceMappingURL=systemUtilizationSampler.js.map