@rewritejs/sdk 1.0.0 → 1.0.1
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.
- package/dist/index.js +79 -9
- package/dist/version.d.ts +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14,8 +14,33 @@ class HTTPError extends Error {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
class RateLimitError extends HTTPError {
|
|
18
|
+
limit;
|
|
19
|
+
global;
|
|
20
|
+
retryAfter;
|
|
21
|
+
constructor(message, url, method, context) {
|
|
22
|
+
super(message, 429, url, method);
|
|
23
|
+
this.limit = context.limit;
|
|
24
|
+
this.global = context.isGlobal;
|
|
25
|
+
this.retryAfter = context.retryAfter;
|
|
26
|
+
this.name = "RateLimitError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class RewriteError extends Error {
|
|
31
|
+
message;
|
|
32
|
+
code;
|
|
33
|
+
detailed;
|
|
34
|
+
constructor(message, code, detailed) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.message = message;
|
|
37
|
+
this.code = code;
|
|
38
|
+
this.detailed = detailed;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
17
42
|
// node_modules/@rewritejs/rest/dist/utils.js
|
|
18
|
-
var createURL = (route, query, baseURL = "https://api.
|
|
43
|
+
var createURL = (route, query, baseURL = "https://api.rewritetoday.com") => {
|
|
19
44
|
const url = `${baseURL}/v1${route}`;
|
|
20
45
|
return query ? `${url}?${new URLSearchParams(query)}` : url;
|
|
21
46
|
};
|
|
@@ -30,6 +55,7 @@ var backoff = (attempt) => {
|
|
|
30
55
|
return Math.floor(exp + jitter);
|
|
31
56
|
};
|
|
32
57
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
58
|
+
var RATE_LIMIT_STATUS = 429;
|
|
33
59
|
|
|
34
60
|
// node_modules/@rewritejs/rest/dist/client.js
|
|
35
61
|
class REST {
|
|
@@ -38,6 +64,7 @@ class REST {
|
|
|
38
64
|
constructor(options) {
|
|
39
65
|
this.options = typeof options === "string" ? { auth: options } : options;
|
|
40
66
|
this.headers = {
|
|
67
|
+
"Content-Type": "application/json",
|
|
41
68
|
...this.options.headers,
|
|
42
69
|
Authorization: `Bearer ${this.options.auth}`
|
|
43
70
|
};
|
|
@@ -63,7 +90,7 @@ class REST {
|
|
|
63
90
|
return this.fetch(route, { data, ...options, method: "PATCH" });
|
|
64
91
|
}
|
|
65
92
|
async fetch(route, options, attempt = 0) {
|
|
66
|
-
const response = await this.
|
|
93
|
+
const response = await this.prefetch(route, options);
|
|
67
94
|
if (!response.ok)
|
|
68
95
|
return this.handleError({
|
|
69
96
|
route,
|
|
@@ -77,19 +104,62 @@ class REST {
|
|
|
77
104
|
}
|
|
78
105
|
async handleError({ route, method, options, attempt, response }) {
|
|
79
106
|
if (!isRetryableStatus(response.status)) {
|
|
80
|
-
const { error } = await response.json();
|
|
81
|
-
throw new
|
|
107
|
+
const { code, error, message } = await response.json();
|
|
108
|
+
throw new RewriteError(message, code, error.detailed);
|
|
82
109
|
}
|
|
83
|
-
const { retry } = this.options;
|
|
110
|
+
const { onRateLimit, retry } = this.options;
|
|
111
|
+
const rateLimitContext = response.status === RATE_LIMIT_STATUS ? this.parseRateLimitContext(response) : null;
|
|
84
112
|
if (attempt >= (retry?.max ?? 3))
|
|
85
|
-
throw
|
|
113
|
+
throw this.buildRetryExceededError(response, method, rateLimitContext);
|
|
114
|
+
if (rateLimitContext && onRateLimit)
|
|
115
|
+
await onRateLimit(rateLimitContext);
|
|
86
116
|
if (retry?.onRetry)
|
|
87
117
|
await retry.onRetry({ route, attempt, options, response, method });
|
|
88
|
-
const delay = (retry
|
|
118
|
+
const delay = this.resolveRetryDelay(attempt, retry, rateLimitContext);
|
|
89
119
|
await sleep(delay);
|
|
90
120
|
return this.fetch(route, options, attempt + 1);
|
|
91
121
|
}
|
|
92
|
-
|
|
122
|
+
buildRetryExceededError(response, method, rateLimitContext) {
|
|
123
|
+
if (rateLimitContext)
|
|
124
|
+
return new RateLimitError("Rate limit has not been reset yet", response.url, method, rateLimitContext);
|
|
125
|
+
return new HTTPError("Max retries reached", response.status, response.url, method);
|
|
126
|
+
}
|
|
127
|
+
resolveRetryDelay(attempt, retry, rateLimitContext) {
|
|
128
|
+
const retryAfterDelay = rateLimitContext?.retryAfter ?? 0;
|
|
129
|
+
if (retryAfterDelay > 0)
|
|
130
|
+
return retryAfterDelay;
|
|
131
|
+
return (retry?.delay ?? backoff)(attempt);
|
|
132
|
+
}
|
|
133
|
+
parseRateLimitContext(response) {
|
|
134
|
+
const { headers } = response;
|
|
135
|
+
const xRateLimitRetryAfter = this.parseNumberHeader(headers, "X-RateLimit-Retry-After");
|
|
136
|
+
const retryAfter = xRateLimitRetryAfter > 0 ? xRateLimitRetryAfter : this.parseRetryAfterHeader(headers.get("Retry-After"));
|
|
137
|
+
return {
|
|
138
|
+
retryAfter,
|
|
139
|
+
limit: Number(headers.get("X-RateLimit-Limit")),
|
|
140
|
+
isGlobal: this.parseBooleanHeader(headers, "X-RateLimit-Global")
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
parseNumberHeader(headers, key) {
|
|
144
|
+
const value = headers.get(key);
|
|
145
|
+
if (!value)
|
|
146
|
+
return 0;
|
|
147
|
+
const parsed = Number(value);
|
|
148
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
149
|
+
}
|
|
150
|
+
parseBooleanHeader(headers, key) {
|
|
151
|
+
return headers.get(key)?.toLowerCase() === "true";
|
|
152
|
+
}
|
|
153
|
+
parseRetryAfterHeader(header) {
|
|
154
|
+
if (!header)
|
|
155
|
+
return 0;
|
|
156
|
+
const seconds = Number(header);
|
|
157
|
+
if (Number.isFinite(seconds))
|
|
158
|
+
return Math.max(0, Math.ceil(seconds * 1000));
|
|
159
|
+
const date = Date.parse(header);
|
|
160
|
+
return Number.isNaN(date) ? 0 : Math.max(0, date - Date.now());
|
|
161
|
+
}
|
|
162
|
+
prefetch(route, options) {
|
|
93
163
|
const timeout = options.timeout ?? this.options.timeout ?? FIVE_SECONDS_IN_MS;
|
|
94
164
|
const url = createURL(route, options.query, this.options.baseURL);
|
|
95
165
|
return fetch(url, {
|
|
@@ -306,7 +376,7 @@ class Rewrite {
|
|
|
306
376
|
}
|
|
307
377
|
}
|
|
308
378
|
// src/version.ts
|
|
309
|
-
var version = "1.0.
|
|
379
|
+
var version = "1.0.1";
|
|
310
380
|
export {
|
|
311
381
|
version,
|
|
312
382
|
Rewrite
|
package/dist/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
"module": "src/index.ts",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.1",
|
|
7
7
|
"devDependencies": {
|
|
8
8
|
"@biomejs/biome": "^2.4.2",
|
|
9
9
|
"@types/bun": "latest"
|
|
10
10
|
},
|
|
11
11
|
"peerDependencies": {
|
|
12
|
-
"typescript": "^5"
|
|
12
|
+
"typescript": "^5.9.3"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@rewritejs/rest": "^1.0.
|
|
15
|
+
"@rewritejs/rest": "^1.0.2",
|
|
16
16
|
"@rewritejs/types": "^1.0.0"
|
|
17
17
|
},
|
|
18
18
|
"main": "./dist/index.js",
|