askui 0.31.0 → 0.32.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.
@@ -16,7 +16,22 @@ export declare class HttpClientGot {
16
16
  http: http.Agent;
17
17
  https: https.Agent;
18
18
  } | undefined);
19
+ /**
20
+ * Configures got with retry behavior for transient server errors.
21
+ *
22
+ * Got retries requests that fail with retryable status codes
23
+ * (500, 502, 503, 504, etc.) up to `limit` times using exponential backoff.
24
+ *
25
+ * POST requests are only retried if their URL is registered in `urlsToRetry`
26
+ * (see `shouldRetryOnError`), to avoid retrying non-idempotent calls
27
+ * to unknown endpoints.
28
+ */
19
29
  private buildGotExtendOptions;
30
+ /**
31
+ * Only retry POST requests if the URL is explicitly registered in `urlsToRetry`
32
+ * (populated by InferenceClient with inference endpoint URLs).
33
+ * Non-POST requests (GET, PUT, etc.) are always retried.
34
+ */
20
35
  private shouldRetryOnError;
21
36
  private shouldRetryPostRequest;
22
37
  private initHeaders;
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -8,16 +31,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
31
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
32
  });
10
33
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
34
  Object.defineProperty(exports, "__esModule", { value: true });
15
35
  exports.HttpClientGot = void 0;
16
- const got_1 = __importDefault(require("got"));
36
+ const got_1 = __importStar(require("got"));
17
37
  const tough_cookie_1 = require("tough-cookie");
18
38
  const lib_1 = require("../../lib");
19
39
  const credentials_1 = require("./credentials");
20
40
  const custom_errors_1 = require("./custom-errors");
41
+ const unkown_http_client_error_1 = require("./custom-errors/unkown-http-client-error");
21
42
  function buildRetryLog(requestUrl, errorCode, statusCode, errorMessage, delayInMs, delayReason, attemptCount) {
22
43
  const failureReasons = [];
23
44
  if (statusCode !== undefined && statusCode >= 400) {
@@ -46,6 +67,16 @@ class HttpClientGot {
46
67
  const gotExtendOptions = this.buildGotExtendOptions(proxyAgents);
47
68
  this.askuiGot = got_1.default.extend(gotExtendOptions);
48
69
  }
70
+ /**
71
+ * Configures got with retry behavior for transient server errors.
72
+ *
73
+ * Got retries requests that fail with retryable status codes
74
+ * (500, 502, 503, 504, etc.) up to `limit` times using exponential backoff.
75
+ *
76
+ * POST requests are only retried if their URL is registered in `urlsToRetry`
77
+ * (see `shouldRetryOnError`), to avoid retrying non-idempotent calls
78
+ * to unknown endpoints.
79
+ */
49
80
  buildGotExtendOptions(proxyAgents) {
50
81
  const gotExtendOptions = {
51
82
  retry: {
@@ -93,6 +124,11 @@ class HttpClientGot {
93
124
  }
94
125
  return gotExtendOptions;
95
126
  }
127
+ /**
128
+ * Only retry POST requests if the URL is explicitly registered in `urlsToRetry`
129
+ * (populated by InferenceClient with inference endpoint URLs).
130
+ * Non-POST requests (GET, PUT, etc.) are always retried.
131
+ */
96
132
  shouldRetryOnError(error) {
97
133
  var _a;
98
134
  return (((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.method) !== 'POST'
@@ -118,19 +154,31 @@ class HttpClientGot {
118
154
  }
119
155
  post(url, data) {
120
156
  return __awaiter(this, void 0, void 0, function* () {
157
+ // Note: We intentionally do NOT set `throwHttpErrors: false` here.
158
+ // Got must throw on non-2xx responses so that its built-in retry mechanism
159
+ // (configured in buildGotExtendOptions) can kick in for transient server errors
160
+ // (500, 502, 503, 504). After all retries are exhausted, got throws an HTTPError
161
+ // which we catch below and convert into our custom error hierarchy.
121
162
  const options = this.injectHeadersAndCookies(url, {
122
163
  json: data,
123
164
  responseType: 'json',
124
- throwHttpErrors: false,
125
165
  });
126
- const { body, statusCode, headers } = yield this.askuiGot.post(url, options);
127
- if (headers['deprecation'] !== undefined) {
128
- lib_1.logger.warn(headers['deprecation']);
166
+ try {
167
+ const { body, headers } = yield this.askuiGot.post(url, options);
168
+ if (headers['deprecation'] !== undefined) {
169
+ lib_1.logger.warn(headers['deprecation']);
170
+ }
171
+ return { body, headers };
129
172
  }
130
- if (statusCode !== 200) {
131
- throw (0, custom_errors_1.httpClientErrorHandler)(statusCode, JSON.stringify(body));
173
+ catch (error) {
174
+ // After got exhausts all retries, it throws HTTPError.
175
+ // Convert it to our custom error types (ServerHttpClientError,
176
+ // AuthenticationHttpClientError, etc.) for consistent error handling.
177
+ if (error instanceof got_1.HTTPError) {
178
+ throw (0, custom_errors_1.httpClientErrorHandler)(error.response.statusCode, error.response.body);
179
+ }
180
+ throw new unkown_http_client_error_1.UnkownHttpClientError(error instanceof Error ? error.message : String(error));
132
181
  }
133
- return { body, headers };
134
182
  });
135
183
  }
136
184
  get(url_1) {
@@ -16,7 +16,22 @@ export declare class HttpClientGot {
16
16
  http: http.Agent;
17
17
  https: https.Agent;
18
18
  } | undefined);
19
+ /**
20
+ * Configures got with retry behavior for transient server errors.
21
+ *
22
+ * Got retries requests that fail with retryable status codes
23
+ * (500, 502, 503, 504, etc.) up to `limit` times using exponential backoff.
24
+ *
25
+ * POST requests are only retried if their URL is registered in `urlsToRetry`
26
+ * (see `shouldRetryOnError`), to avoid retrying non-idempotent calls
27
+ * to unknown endpoints.
28
+ */
19
29
  private buildGotExtendOptions;
30
+ /**
31
+ * Only retry POST requests if the URL is explicitly registered in `urlsToRetry`
32
+ * (populated by InferenceClient with inference endpoint URLs).
33
+ * Non-POST requests (GET, PUT, etc.) are always retried.
34
+ */
20
35
  private shouldRetryOnError;
21
36
  private shouldRetryPostRequest;
22
37
  private initHeaders;
@@ -7,11 +7,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import got from 'got';
10
+ import got, { HTTPError, } from 'got';
11
11
  import { CookieJar } from 'tough-cookie';
12
12
  import { logger } from '../../lib';
13
13
  import { Credentials } from './credentials';
14
14
  import { httpClientErrorHandler } from './custom-errors';
15
+ import { UnkownHttpClientError } from './custom-errors/unkown-http-client-error';
15
16
  function buildRetryLog(requestUrl, errorCode, statusCode, errorMessage, delayInMs, delayReason, attemptCount) {
16
17
  const failureReasons = [];
17
18
  if (statusCode !== undefined && statusCode >= 400) {
@@ -40,6 +41,16 @@ export class HttpClientGot {
40
41
  const gotExtendOptions = this.buildGotExtendOptions(proxyAgents);
41
42
  this.askuiGot = got.extend(gotExtendOptions);
42
43
  }
44
+ /**
45
+ * Configures got with retry behavior for transient server errors.
46
+ *
47
+ * Got retries requests that fail with retryable status codes
48
+ * (500, 502, 503, 504, etc.) up to `limit` times using exponential backoff.
49
+ *
50
+ * POST requests are only retried if their URL is registered in `urlsToRetry`
51
+ * (see `shouldRetryOnError`), to avoid retrying non-idempotent calls
52
+ * to unknown endpoints.
53
+ */
43
54
  buildGotExtendOptions(proxyAgents) {
44
55
  const gotExtendOptions = {
45
56
  retry: {
@@ -87,6 +98,11 @@ export class HttpClientGot {
87
98
  }
88
99
  return gotExtendOptions;
89
100
  }
101
+ /**
102
+ * Only retry POST requests if the URL is explicitly registered in `urlsToRetry`
103
+ * (populated by InferenceClient with inference endpoint URLs).
104
+ * Non-POST requests (GET, PUT, etc.) are always retried.
105
+ */
90
106
  shouldRetryOnError(error) {
91
107
  var _a;
92
108
  return (((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.method) !== 'POST'
@@ -112,19 +128,31 @@ export class HttpClientGot {
112
128
  }
113
129
  post(url, data) {
114
130
  return __awaiter(this, void 0, void 0, function* () {
131
+ // Note: We intentionally do NOT set `throwHttpErrors: false` here.
132
+ // Got must throw on non-2xx responses so that its built-in retry mechanism
133
+ // (configured in buildGotExtendOptions) can kick in for transient server errors
134
+ // (500, 502, 503, 504). After all retries are exhausted, got throws an HTTPError
135
+ // which we catch below and convert into our custom error hierarchy.
115
136
  const options = this.injectHeadersAndCookies(url, {
116
137
  json: data,
117
138
  responseType: 'json',
118
- throwHttpErrors: false,
119
139
  });
120
- const { body, statusCode, headers } = yield this.askuiGot.post(url, options);
121
- if (headers['deprecation'] !== undefined) {
122
- logger.warn(headers['deprecation']);
140
+ try {
141
+ const { body, headers } = yield this.askuiGot.post(url, options);
142
+ if (headers['deprecation'] !== undefined) {
143
+ logger.warn(headers['deprecation']);
144
+ }
145
+ return { body, headers };
123
146
  }
124
- if (statusCode !== 200) {
125
- throw httpClientErrorHandler(statusCode, JSON.stringify(body));
147
+ catch (error) {
148
+ // After got exhausts all retries, it throws HTTPError.
149
+ // Convert it to our custom error types (ServerHttpClientError,
150
+ // AuthenticationHttpClientError, etc.) for consistent error handling.
151
+ if (error instanceof HTTPError) {
152
+ throw httpClientErrorHandler(error.response.statusCode, error.response.body);
153
+ }
154
+ throw new UnkownHttpClientError(error instanceof Error ? error.message : String(error));
126
155
  }
127
- return { body, headers };
128
156
  });
129
157
  }
130
158
  get(url_1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "askui",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "license": "MIT",
5
5
  "author": "askui GmbH <info@askui.com> (http://www.askui.com/)",
6
6
  "description": "Reliable, automated end-to-end-testing that depends on what is shown on your screen instead of the technology you are running on",
@@ -42,7 +42,8 @@
42
42
  "test": "cross-env NODE_EXTRA_CA_CERTS='test/proxy/certs/unit_test.pem' jest '/src'",
43
43
  "postinstall": "node -e \"require('./bin/askui-postinstall')\"",
44
44
  "release:prerelease": "cross-env HUSKY=0 release-it --preRelease=next",
45
- "release": "cross-env HUSKY=0 release-it"
45
+ "release": "cross-env HUSKY=0 release-it",
46
+ "generate:SBOM": "cyclonedx-npm package.json --omit dev --gather-license-texts --output-file bom.json --output-format JSON"
46
47
  },
47
48
  "files": [
48
49
  "dist/cjs/",
@@ -73,6 +74,7 @@
73
74
  "yup": "1.4.0"
74
75
  },
75
76
  "devDependencies": {
77
+ "@cyclonedx/cyclonedx-npm": "^4.1.2",
76
78
  "@release-it/bumper": "6.0.1",
77
79
  "@release-it/conventional-changelog": "8.0.2",
78
80
  "@types/fs-extra": "11.0.4",