onshape 0.1.2 → 0.1.3

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.
Files changed (2) hide show
  1. package/dist/api/client.js +30 -6
  2. package/package.json +1 -1
@@ -2,6 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OnshapeClient = exports.HttpError = void 0;
4
4
  const node_url_1 = require("node:url");
5
+ const promises_1 = require("node:timers/promises");
6
+ const READ_RETRY_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
7
+ const MAX_READ_ATTEMPTS = 5;
8
+ const MAX_RETRY_DELAY_MS = 10_000;
5
9
  class HttpError extends Error {
6
10
  status;
7
11
  detail;
@@ -50,13 +54,19 @@ class OnshapeClient {
50
54
  return responseJsonOrStatus(response, "deleted");
51
55
  }
52
56
  async requestJson(url) {
53
- const response = await this.fetchWithAuthRedirects(url, {
54
- Accept: "application/json;charset=UTF-8; qs=0.09",
55
- });
56
- if (!response.ok) {
57
- throw new HttpError(response.status, await responseDetail(response));
57
+ for (let attempt = 1; attempt <= MAX_READ_ATTEMPTS; attempt += 1) {
58
+ const response = await this.fetchWithAuthRedirects(url, {
59
+ Accept: "application/json;charset=UTF-8; qs=0.09",
60
+ });
61
+ if (response.ok) {
62
+ return response.json();
63
+ }
64
+ if (!READ_RETRY_STATUSES.has(response.status) || attempt === MAX_READ_ATTEMPTS) {
65
+ throw new HttpError(response.status, await responseDetail(response));
66
+ }
67
+ await (0, promises_1.setTimeout)(retryDelayMs(response, attempt));
58
68
  }
59
- return response.json();
69
+ throw new Error("unreachable read retry state");
60
70
  }
61
71
  async fetchWithAuthRedirects(url, headers, method = "GET", body) {
62
72
  const auth = Buffer.from(`${this.creds.accessKey}:${this.creds.secretKey}`).toString("base64");
@@ -95,3 +105,17 @@ async function responseJsonOrStatus(response, key) {
95
105
  return { [key]: true, status: response.status, text: text.slice(0, 500) };
96
106
  }
97
107
  }
108
+ function retryDelayMs(response, attempt) {
109
+ const retryAfter = response.headers.get("retry-after");
110
+ if (retryAfter) {
111
+ const seconds = Number(retryAfter);
112
+ if (Number.isFinite(seconds) && seconds >= 0) {
113
+ return Math.min(seconds * 1000, MAX_RETRY_DELAY_MS);
114
+ }
115
+ const dateMs = Date.parse(retryAfter);
116
+ if (Number.isFinite(dateMs)) {
117
+ return Math.min(Math.max(dateMs - Date.now(), 0), MAX_RETRY_DELAY_MS);
118
+ }
119
+ }
120
+ return Math.min(500 * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
121
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onshape",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Node.js CLI for Onshape CAD automation with the same JSON contract as onshape-cli.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",