@mablhq/mabl-cli 1.16.5 → 1.16.11

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.
@@ -37,6 +37,14 @@ const DEFAULT_MAX_TOTAL_RETRY_TIME_MILLISECONDS = DEFAULT_RETRYABLE_REQUEST_TIME
37
37
  const DEFAULT_NONRETRYABLE_REQUEST_TIMEOUT_MILLISECONDS = DEFAULT_MAX_TOTAL_RETRY_TIME_MILLISECONDS;
38
38
  const DEFAULT_MIN_RETRY_INTERVAL_MILLISECONDS = 1000;
39
39
  const DEFAULT_MAX_RETRY_INTERVAL_MILLISECONDS = 10000;
40
+ const RETRYABLE_NODEJS_ERRORS = [
41
+ 'EAI_AGAIN',
42
+ 'ECONNRESET',
43
+ 'ENOTFOUND',
44
+ 'ENETUNREACH',
45
+ 'ETIMEOUT',
46
+ 'ECONNABORTED',
47
+ ];
40
48
  var AuthType;
41
49
  (function (AuthType) {
42
50
  AuthType[AuthType["Bearer"] = 0] = "Bearer";
@@ -44,12 +52,12 @@ var AuthType;
44
52
  })(AuthType = exports.AuthType || (exports.AuthType = {}));
45
53
  class BasicApiClient {
46
54
  constructor(options) {
47
- var _a, _b;
55
+ var _a, _b, _c, _d;
48
56
  const config = httpUtil_1.axiosProxyConfig({
49
57
  sslVerify: options.sslVerify,
50
58
  proxyHost: options.proxyUrl,
51
59
  });
52
- config.timeout = (_a = options.requestTimeoutMillis) !== null && _a !== void 0 ? _a : DEFAULT_RETRYABLE_REQUEST_TIMEOUT_MILLISECONDS;
60
+ config.timeout = (_c = (_a = options.requestTimeoutMillis) !== null && _a !== void 0 ? _a : (_b = options.retryConfig) === null || _b === void 0 ? void 0 : _b.requestTimeoutMillis) !== null && _c !== void 0 ? _c : DEFAULT_RETRYABLE_REQUEST_TIMEOUT_MILLISECONDS;
53
61
  switch (options.authType) {
54
62
  case AuthType.ApiKey:
55
63
  config.auth = {
@@ -77,7 +85,7 @@ class BasicApiClient {
77
85
  this.httpRequestConfig = config;
78
86
  this.httpClient = axios_1.default.create(config);
79
87
  this.retryConfig = options.retryConfig;
80
- this.debugLogger = (_b = options.debugLogger) !== null && _b !== void 0 ? _b : logUtils_1.logInternal;
88
+ this.debugLogger = (_d = options.debugLogger) !== null && _d !== void 0 ? _d : logUtils_1.logInternal;
81
89
  }
82
90
  getNonRetryableRequestConfig(override) {
83
91
  const overrideWithTimeout = { ...(override !== null && override !== void 0 ? override : {}) };
@@ -87,20 +95,26 @@ class BasicApiClient {
87
95
  }
88
96
  return { ...this.httpRequestConfig, ...overrideWithTimeout };
89
97
  }
90
- makeGetRequest(path) {
91
- return this.retryWrappedRequest(`makeGetRequest('${path}')`, () => this.getRequest(path));
98
+ getRetryableRequestConfig(retryConfig) {
99
+ var _a;
100
+ return this.getNonRetryableRequestConfig({
101
+ timeout: (_a = retryConfig === null || retryConfig === void 0 ? void 0 : retryConfig.requestTimeoutMillis) !== null && _a !== void 0 ? _a : this.httpRequestConfig.timeout,
102
+ });
103
+ }
104
+ makeGetRequest(path, retryConfig) {
105
+ return this.retryWrappedRequest(`makeGetRequest('${path}')`, () => this.getRequest(path, this.getRetryableRequestConfig(retryConfig)), retryConfig);
92
106
  }
93
- async getRequest(path) {
94
- const response = await this.debugRequest('GET', path, () => this.httpClient.get(path));
107
+ async getRequest(path, config) {
108
+ const response = await this.debugRequest('GET', path, () => this.httpClient.get(path, config));
95
109
  BasicApiClient.checkResponseStatusCode(response);
96
110
  return response.data;
97
111
  }
98
- makeGetRequestWithETag(path) {
99
- return this.retryWrappedRequest(`makeGetRequestWithETag('${path}')`, () => this.getRequestWithETag(path));
112
+ makeGetRequestWithETag(path, retryConfig) {
113
+ return this.retryWrappedRequest(`makeGetRequestWithETag('${path}')`, () => this.getRequestWithETag(path, this.getRetryableRequestConfig(retryConfig)), retryConfig);
100
114
  }
101
- async getRequestWithETag(path) {
115
+ async getRequestWithETag(path, config) {
102
116
  var _a;
103
- const response = await this.debugRequest('GET', path, () => this.httpClient.get(path));
117
+ const response = await this.debugRequest('GET', path, () => this.httpClient.get(path, config));
104
118
  BasicApiClient.checkResponseStatusCode(response);
105
119
  const headers = response.headers;
106
120
  const result = response.data;
@@ -120,11 +134,11 @@ class BasicApiClient {
120
134
  BasicApiClient.checkResponseStatusCode(response);
121
135
  return response.data;
122
136
  }
123
- makeDeleteRequest(path) {
124
- return this.retryWrappedRequest(`makeDeleteRequest('${path}')`, () => this.deleteRequest(path));
137
+ makeDeleteRequest(path, retryConfig) {
138
+ return this.retryWrappedRequest(`makeDeleteRequest('${path}')`, () => this.deleteRequest(path, this.getRetryableRequestConfig(retryConfig)), retryConfig);
125
139
  }
126
- async deleteRequest(path) {
127
- const response = await this.debugRequest('DELETE', path, () => this.deleteRequest(path));
140
+ async deleteRequest(path, config) {
141
+ const response = await this.debugRequest('DELETE', path, () => this.deleteRequest(path, config));
128
142
  BasicApiClient.checkResponseStatusCode(response);
129
143
  return response.data;
130
144
  }
@@ -158,38 +172,48 @@ class BasicApiClient {
158
172
  throw new ApiError_1.ApiError(`[${statusCode} - ${response.statusText}]`, statusCode);
159
173
  }
160
174
  }
161
- retryWrappedRequest(description, requestFunc) {
162
- var _a, _b, _c, _d, _e, _f, _g, _h;
175
+ retryWrappedRequest(description, requestFunc, retryConfigOverride) {
176
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
163
177
  const retryOptions = {
164
- retries: (_b = (_a = this.retryConfig) === null || _a === void 0 ? void 0 : _a.retryCount) !== null && _b !== void 0 ? _b : DEFAULT_RETRIES,
165
- minTimeout: (_d = (_c = this.retryConfig) === null || _c === void 0 ? void 0 : _c.minRetryIntervalMillis) !== null && _d !== void 0 ? _d : DEFAULT_MIN_RETRY_INTERVAL_MILLISECONDS,
166
- maxTimeout: (_f = (_e = this.retryConfig) === null || _e === void 0 ? void 0 : _e.maxRetryIntervalMillis) !== null && _f !== void 0 ? _f : DEFAULT_MAX_RETRY_INTERVAL_MILLISECONDS,
167
- maxRetryTime: (_h = (_g = this.retryConfig) === null || _g === void 0 ? void 0 : _g.maxRetryTimeMillis) !== null && _h !== void 0 ? _h : DEFAULT_MAX_TOTAL_RETRY_TIME_MILLISECONDS,
178
+ retries: (_c = (_a = retryConfigOverride === null || retryConfigOverride === void 0 ? void 0 : retryConfigOverride.retryCount) !== null && _a !== void 0 ? _a : (_b = this.retryConfig) === null || _b === void 0 ? void 0 : _b.retryCount) !== null && _c !== void 0 ? _c : DEFAULT_RETRIES,
179
+ minTimeout: (_f = (_d = retryConfigOverride === null || retryConfigOverride === void 0 ? void 0 : retryConfigOverride.minRetryIntervalMillis) !== null && _d !== void 0 ? _d : (_e = this.retryConfig) === null || _e === void 0 ? void 0 : _e.minRetryIntervalMillis) !== null && _f !== void 0 ? _f : DEFAULT_MIN_RETRY_INTERVAL_MILLISECONDS,
180
+ maxTimeout: (_j = (_g = retryConfigOverride === null || retryConfigOverride === void 0 ? void 0 : retryConfigOverride.maxRetryIntervalMillis) !== null && _g !== void 0 ? _g : (_h = this.retryConfig) === null || _h === void 0 ? void 0 : _h.maxRetryIntervalMillis) !== null && _j !== void 0 ? _j : DEFAULT_MAX_RETRY_INTERVAL_MILLISECONDS,
181
+ maxRetryTime: (_m = (_k = retryConfigOverride === null || retryConfigOverride === void 0 ? void 0 : retryConfigOverride.maxRetryTimeMillis) !== null && _k !== void 0 ? _k : (_l = this.retryConfig) === null || _l === void 0 ? void 0 : _l.maxRetryTimeMillis) !== null && _m !== void 0 ? _m : DEFAULT_MAX_TOTAL_RETRY_TIME_MILLISECONDS,
168
182
  onRetry: (error) => {
169
183
  this.debugLogger(`Retrying failed API request "${description}"`, error);
170
184
  },
171
185
  forever: false,
172
186
  };
173
187
  return asyncUtil_1.promiseWithTimeout(async_retry_1.default(async (bail) => {
174
- var _a, _b;
175
188
  try {
176
189
  return await requestFunc();
177
190
  }
178
191
  catch (error) {
179
- const axiosError = error;
180
- const statusCode = (_a = axiosError.code) !== null && _a !== void 0 ? _a : (_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.status;
181
- if (statusCode === 429 ||
182
- statusCode === 502 ||
183
- statusCode === 503 ||
184
- statusCode === 504) {
192
+ if (axios_1.default.isAxiosError(error) && BasicApiClient.isRetryable(error)) {
185
193
  throw error;
186
194
  }
187
195
  else {
196
+ let code;
197
+ if (axios_1.default.isAxiosError(error)) {
198
+ code = error.code;
199
+ }
200
+ this.debugLogger(`Non-retryable error on API client: ${code} ${description} ${error}`);
188
201
  bail(error);
189
202
  return {};
190
203
  }
191
204
  }
192
205
  }, retryOptions), retryOptions.maxRetryTime + retryOptions.maxTimeout, 'Retryable API request');
193
206
  }
207
+ static isRetryable(axiosError) {
208
+ if (axiosError.response) {
209
+ const statusCode = axiosError.response.status;
210
+ return (statusCode === 429 ||
211
+ statusCode === 502 ||
212
+ statusCode === 503 ||
213
+ statusCode === 504);
214
+ }
215
+ return (axiosError.code !== undefined &&
216
+ RETRYABLE_NODEJS_ERRORS.includes(axiosError.code));
217
+ }
194
218
  }
195
219
  exports.BasicApiClient = BasicApiClient;
@@ -227,7 +227,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
227
227
  }
228
228
  async getDeploymentResults(deploymentEventId) {
229
229
  try {
230
- return await this.makeGetRequest(`${env_1.BASE_API_URL}/execution/result/event/${deploymentEventId}`);
230
+ return await this.makeGetRequest(`${env_1.BASE_API_URL}/execution/result/event/${deploymentEventId}`, { requestTimeoutMillis: 600000, maxRetryTimeMillis: 900000 });
231
231
  }
232
232
  catch (error) {
233
233
  throw toApiError(`Failed to get deployment results`, error);
@@ -13,4 +13,5 @@ var PageEvent;
13
13
  PageEvent["Response"] = "response";
14
14
  PageEvent["TracingBufferUsage"] = "tracingbufferusage";
15
15
  PageEvent["TracingComplete"] = "tracingcomplete";
16
+ PageEvent["TracingDataCollected"] = "TracingDataCollected";
16
17
  })(PageEvent = exports.PageEvent || (exports.PageEvent = {}));
@@ -130,6 +130,12 @@ class PlaywrightPage extends events_1.default {
130
130
  this.emit(browserLauncher_1.PageEvent.TracingBufferUsage, tracing);
131
131
  });
132
132
  }
133
+ if (event === browserLauncher_1.PageEvent.TracingDataCollected &&
134
+ !this.listenerCount(event)) {
135
+ this.getCdpSession().on('Tracing.dataCollected', (data) => {
136
+ this.emit(browserLauncher_1.PageEvent.TracingDataCollected, data);
137
+ });
138
+ }
133
139
  if (event === browserLauncher_1.PageEvent.TracingComplete && !this.listenerCount(event)) {
134
140
  this.getCdpSession().on('Tracing.tracingComplete', (tracingComplete) => {
135
141
  this.emit(browserLauncher_1.PageEvent.TracingComplete, tracingComplete);
@@ -245,6 +245,12 @@ class PuppeteerPage extends events_1.default {
245
245
  this.emit(browserLauncher_1.PageEvent.TracingComplete, tracingComplete);
246
246
  });
247
247
  }
248
+ if (event === browserLauncher_1.PageEvent.TracingDataCollected &&
249
+ !this.listenerCount(event)) {
250
+ this.getCdpClient().on('Tracing.dataCollected', (data) => {
251
+ this.emit(browserLauncher_1.PageEvent.TracingComplete, data);
252
+ });
253
+ }
248
254
  }
249
255
  evaluateHandleInSecondaryWorld(code, ...args) {
250
256
  return this.mainFrame().evaluateHandleInSecondaryWorld(code, ...args);