tsarr 2.9.1 → 2.10.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.
- package/dist/cli/index.js +125 -24
- package/dist/clients/base.d.ts +8 -3
- package/dist/clients/base.d.ts.map +1 -1
- package/dist/clients/bazarr.d.ts +1 -0
- package/dist/clients/bazarr.d.ts.map +1 -1
- package/dist/clients/bazarr.js +95 -3
- package/dist/clients/lidarr.d.ts +2 -1
- package/dist/clients/lidarr.d.ts.map +1 -1
- package/dist/clients/lidarr.js +102 -5
- package/dist/clients/prowlarr.d.ts +2 -1
- package/dist/clients/prowlarr.d.ts.map +1 -1
- package/dist/clients/prowlarr.js +102 -5
- package/dist/clients/qbittorrent.d.ts +1 -1
- package/dist/clients/qbittorrent.d.ts.map +1 -1
- package/dist/clients/qbittorrent.js +95 -6
- package/dist/clients/radarr.d.ts +2 -1
- package/dist/clients/radarr.d.ts.map +1 -1
- package/dist/clients/radarr.js +102 -5
- package/dist/clients/readarr.d.ts +2 -1
- package/dist/clients/readarr.d.ts.map +1 -1
- package/dist/clients/readarr.js +102 -5
- package/dist/clients/seerr.d.ts +1 -0
- package/dist/clients/seerr.d.ts.map +1 -1
- package/dist/clients/seerr.js +95 -3
- package/dist/clients/sonarr.d.ts +2 -1
- package/dist/clients/sonarr.d.ts.map +1 -1
- package/dist/clients/sonarr.js +102 -5
- package/dist/core/client.d.ts +2 -0
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/fetch.d.ts +23 -0
- package/dist/core/fetch.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tsarr-2.10.0.tgz +0 -0
- package/package.json +1 -1
- package/dist/tsarr-2.9.1.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readarr.d.ts","sourceRoot":"","sources":["../../src/clients/readarr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"readarr.d.ts","sourceRoot":"","sources":["../../src/clients/readarr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,YAAY,EACZ,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,EAClB,6BAA6B,EAC7B,8BAA8B,EAC9B,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,iBAAiB;IAClD,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAmEhC;gBAEU,MAAM,EAAE,mBAAmB;IAMvC;;OAEG;IACG,UAAU;;;;;;;;;;IAIV,SAAS,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIpB,SAAS,CAAC,MAAM,EAAE,sBAAsB;;;;;;;;;;IAIxC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB;;;;;;;;;;IAIvD,YAAY,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAKvB,QAAQ;;;;;;;;;;IAIR,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAMxB;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;IAK1B,cAAc;;;;;;;;;;IAId,aAAa,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;IAM1B,gBAAgB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAMjC;;OAEG;IACG,eAAe;;;;;;;;;;IAIrB;;OAEG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIpC;;OAEG;IACG,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB;;;;;;;;;;IAIjE;;OAEG;IACG,uBAAuB;;;;;;;;;;IAI7B;;OAEG;IACG,wBAAwB;;;;;;;;;;IAI9B;;OAEG;IACG,4BAA4B,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI7C;;OAEG;IACG,2BAA2B,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,6BAA6B;;;;;;;;;;IAInF;;OAEG;IACG,oBAAoB;;;;;;;;;;IAI1B;;OAEG;IACG,wBAAwB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIzC;;OAEG;IACG,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB;;;;;;;;;;IAI3E;;OAEG;IACG,yBAAyB;;;;;;;;;;IAI/B;;OAEG;IACG,6BAA6B,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI9C;;OAEG;IACG,4BAA4B,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,8BAA8B;;;;;;;;;;IAOrF;;OAEG;IACG,aAAa;;;;;;;;;;IAInB;;OAEG;IACG,YAAY;;;;;;;;;;IAMlB;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,YAAY;;;;;;;;;;IAIhC;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY;;;;;;;;;;IAI/C;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI3B;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;IAKxB,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO;;;;;;;;;;IAS/D,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;;;;;;;;;;IAW9E;;OAEG;IACG,YAAY,CAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,EAAE,EACtB,MAAM,CAAC,EAAE,MAAM,EAAE,EACjB,QAAQ,CAAC,EAAE,OAAO;;;;;;;;;;IAWpB;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI5B;;OAEG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB;;;;;;;;;;IAInE;;OAEG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI/B;;OAEG;IACG,qBAAqB,CAAC,YAAY,EAAE,oBAAoB;;;;;;;;;;IAI9D;;OAEG;IACG,mBAAmB,CAAC,YAAY,EAAE,oBAAoB;;;;;;;;;;IAM5D;;OAEG;IACG,kBAAkB;;;;;;;;;;IAIxB;;OAEG;IACG,iBAAiB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIlC;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,sBAAsB;;;;;;;;;;IAIvD;;OAEG;IACG,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB;;;;;;;;;;IAItE;;OAEG;IACG,oBAAoB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIrC;;OAEG;IACG,uBAAuB;;;;;;;;;;IAM7B;;OAEG;IACG,gBAAgB;;;;;;;;;;IAItB;;OAEG;IACG,eAAe,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIhC;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,oBAAoB;;;;;;;;;;IAIlD;;OAEG;IACG,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB;;;;;;;;;;IAIjE;;OAEG;IACG,kBAAkB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAInC;;OAEG;IACG,qBAAqB;;;;;;;;;;IAM3B;;OAEG;IACG,cAAc;;;;;;;;;;IAIpB;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI9B;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,kBAAkB;;;;;;;;;;IAIlD;;OAEG;IACG,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB;;;;;;;;;;IAIjE;;OAEG;IACG,gBAAgB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIjC;;OAEG;IACG,mBAAmB;;;;;;;;;;IAIzB;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,kBAAkB;;;;;;;;;;IAInD;;OAEG;IACG,kBAAkB;;;;;;;;;;IAMxB;;OAEG;IACG,UAAU,CACd,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM;;;;;;;;;;IAarB;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;IAOrD;;OAEG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG;;;;;;;;;;IAQzE;;OAEG;IACG,qBAAqB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAMtC;;OAEG;IACG,QAAQ,CACZ,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,EACtB,yBAAyB,CAAC,EAAE,OAAO;;;;;;;;;;IAarC;;OAEG;IACG,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO;;;;;;;;;;IAWjF;;OAEG;IACG,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,gBAAgB,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO;;;;;;;;;;IAWzF;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAI9B;;OAEG;IACG,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;;;;;;;;;;IAItC;;OAEG;IACG,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,yBAAyB,CAAC,EAAE,OAAO;;;;;;;;;;IAS5E;;OAEG;IACG,cAAc;;;;;;;;;;IAMpB;;OAEG;IACG,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM;;;;;;;;;;IAU7F;;OAEG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;IAIpC;;OAEG;IACG,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE;;;;;;;;;;IAI5C;;OAEG;IACG,gBAAgB,CACpB,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,OAAO;;;;;;;;;;IAYrB;;OAEG;IACG,eAAe,CACnB,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,OAAO;;;;;;;;;;CAWtB;AAGD,cAAc,oBAAoB,CAAC"}
|
package/dist/clients/readarr.js
CHANGED
|
@@ -26,6 +26,93 @@ class ConnectionError extends TsarrError {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// src/core/fetch.ts
|
|
30
|
+
var DEFAULT_TIMEOUT = 30000;
|
|
31
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
32
|
+
var DEFAULT_INITIAL_DELAY = 1000;
|
|
33
|
+
var DEFAULT_MAX_DELAY = 1e4;
|
|
34
|
+
var RETRYABLE_STATUS_CODES = new Set([408, 429, 502, 503, 504]);
|
|
35
|
+
function isRetryable(error) {
|
|
36
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (error instanceof TypeError) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function getRetryDelay(attempt, initialDelayMs, maxDelayMs) {
|
|
45
|
+
const delay = initialDelayMs * 2 ** attempt;
|
|
46
|
+
const jitter = delay * 0.2 * Math.random();
|
|
47
|
+
return Math.min(delay + jitter, maxDelayMs);
|
|
48
|
+
}
|
|
49
|
+
function createResilientFetch(options = {}) {
|
|
50
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
51
|
+
const maxRetries = options.retry ? options.retry.maxRetries ?? DEFAULT_MAX_RETRIES : 0;
|
|
52
|
+
const initialDelayMs = options.retry?.initialDelayMs ?? DEFAULT_INITIAL_DELAY;
|
|
53
|
+
const maxDelayMs = options.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY;
|
|
54
|
+
const resilientFetch = async (input, init) => {
|
|
55
|
+
let lastError;
|
|
56
|
+
const template = createRequestTemplate(input, init);
|
|
57
|
+
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
58
|
+
const controller = new AbortController;
|
|
59
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
60
|
+
const callerSignal = init?.signal;
|
|
61
|
+
if (callerSignal?.aborted) {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
throw callerSignal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
64
|
+
}
|
|
65
|
+
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
66
|
+
callerSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
67
|
+
try {
|
|
68
|
+
const response = await globalThis.fetch(new Request(template.clone(), { signal: controller.signal }));
|
|
69
|
+
clearTimeout(timeoutId);
|
|
70
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
71
|
+
if (RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries) {
|
|
72
|
+
lastError = new ConnectionError(`Request failed with status ${response.status}`);
|
|
73
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
81
|
+
if (callerSignal?.aborted) {
|
|
82
|
+
throw callerSignal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
83
|
+
}
|
|
84
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
85
|
+
lastError = new ConnectionError(`Request timed out after ${timeout}ms`);
|
|
86
|
+
if (attempt < maxRetries) {
|
|
87
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
88
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
throw lastError;
|
|
92
|
+
}
|
|
93
|
+
if (isRetryable(error) && attempt < maxRetries) {
|
|
94
|
+
lastError = error;
|
|
95
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
96
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw lastError;
|
|
103
|
+
};
|
|
104
|
+
return Object.assign(resilientFetch, {
|
|
105
|
+
preconnect: globalThis.fetch.preconnect?.bind(globalThis.fetch)
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function createRequestTemplate(input, init) {
|
|
109
|
+
const { signal: _signal, ...requestInit } = init ?? {};
|
|
110
|
+
if (input instanceof Request) {
|
|
111
|
+
return init ? new Request(input.clone(), requestInit) : input.clone();
|
|
112
|
+
}
|
|
113
|
+
return new Request(input, requestInit);
|
|
114
|
+
}
|
|
115
|
+
|
|
29
116
|
// src/core/client.ts
|
|
30
117
|
var DEFAULT_TIMEOUT_MS = 30000;
|
|
31
118
|
function createServarrClient(config) {
|
|
@@ -40,6 +127,10 @@ function createServarrClient(config) {
|
|
|
40
127
|
baseUrl: config.baseUrl.replace(/\/$/, "")
|
|
41
128
|
};
|
|
42
129
|
const timeoutMs = validatedConfig.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
130
|
+
const resilientFetch = createResilientFetch({
|
|
131
|
+
timeout: timeoutMs,
|
|
132
|
+
retry: validatedConfig.retry
|
|
133
|
+
});
|
|
43
134
|
return {
|
|
44
135
|
config: validatedConfig,
|
|
45
136
|
getHeaders: () => ({
|
|
@@ -48,22 +139,28 @@ function createServarrClient(config) {
|
|
|
48
139
|
...validatedConfig.headers
|
|
49
140
|
}),
|
|
50
141
|
getBaseUrl: () => validatedConfig.baseUrl,
|
|
51
|
-
getTimeout: () => timeoutMs
|
|
142
|
+
getTimeout: () => timeoutMs,
|
|
143
|
+
getFetch: () => resilientFetch
|
|
52
144
|
};
|
|
53
145
|
}
|
|
54
146
|
|
|
55
147
|
// src/clients/base.ts
|
|
56
148
|
class ServarrBaseClient {
|
|
57
149
|
clientConfig;
|
|
58
|
-
|
|
150
|
+
rawClient;
|
|
151
|
+
constructor(config, rawClient) {
|
|
152
|
+
this.rawClient = rawClient;
|
|
59
153
|
this.clientConfig = createServarrClient(config);
|
|
60
154
|
this.configureRawClient();
|
|
61
155
|
}
|
|
156
|
+
configureRawClient() {
|
|
157
|
+
this.rawClient.setConfig(this.getClientConfig());
|
|
158
|
+
}
|
|
62
159
|
getClientConfig() {
|
|
63
160
|
return {
|
|
64
161
|
baseUrl: this.clientConfig.getBaseUrl(),
|
|
65
162
|
headers: this.clientConfig.getHeaders(),
|
|
66
|
-
|
|
163
|
+
fetch: this.clientConfig.getFetch()
|
|
67
164
|
};
|
|
68
165
|
}
|
|
69
166
|
async getSystemStatus() {
|
|
@@ -2317,8 +2414,8 @@ class ReadarrClient extends ServarrBaseClient {
|
|
|
2317
2414
|
getUiConfigById: getApiV1ConfigUiById,
|
|
2318
2415
|
updateUiConfig: putApiV1ConfigUiById
|
|
2319
2416
|
};
|
|
2320
|
-
|
|
2321
|
-
client
|
|
2417
|
+
constructor(config) {
|
|
2418
|
+
super(config, client);
|
|
2322
2419
|
}
|
|
2323
2420
|
async getAuthors() {
|
|
2324
2421
|
return getApiV1Author();
|
package/dist/clients/seerr.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seerr.d.ts","sourceRoot":"","sources":["../../src/clients/seerr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EAGd,YAAY,EACb,MAAM,8BAA8B,CAAC;AAEtC,KAAK,aAAa,GAAG,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAyC;gBAEjD,MAAM,EAAE,mBAAmB;IAejC,eAAe;;;;;;;;;;;;;;;;IAMf,WAAW,CAAC,OAAO,CAAC,EAAE;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,aAAa,CAAC;QACvB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QAC5B,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;KAChC;;;;;;;;;;;;;IAWK,cAAc,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;IAIhC,eAAe;;;;;;;;;;;;;;;;;;;;IAIf,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAOxD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IASxD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;IAUtD,QAAQ,CAAC,OAAO,CAAC,EAAE;QACvB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;KAC3D;;;;;;;;;;;;;IASK,WAAW,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;IAM1B,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;IASzD,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,mBAAmB,CAAC
|
|
1
|
+
{"version":3,"file":"seerr.d.ts","sourceRoot":"","sources":["../../src/clients/seerr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EAGd,YAAY,EACb,MAAM,8BAA8B,CAAC;AAEtC,KAAK,aAAa,GAAG,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAyC;gBAEjD,MAAM,EAAE,mBAAmB;IAejC,eAAe;;;;;;;;;;;;;;;;IAMf,WAAW,CAAC,OAAO,CAAC,EAAE;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,aAAa,CAAC;QACvB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QAC5B,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;KAChC;;;;;;;;;;;;;IAWK,cAAc,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;IAIhC,eAAe;;;;;;;;;;;;;;;;;;;;IAIf,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAOxD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IASxD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;IAUtD,QAAQ,CAAC,OAAO,CAAC,EAAE;QACvB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;KAC3D;;;;;;;;;;;;;IASK,WAAW,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;IAM1B,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;IASzD,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,mBAAmB,CAAC;;;;;;;CAcrD;AAGD,cAAc,kBAAkB,CAAC"}
|
package/dist/clients/seerr.js
CHANGED
|
@@ -26,6 +26,93 @@ class ConnectionError extends TsarrError {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// src/core/fetch.ts
|
|
30
|
+
var DEFAULT_TIMEOUT = 30000;
|
|
31
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
32
|
+
var DEFAULT_INITIAL_DELAY = 1000;
|
|
33
|
+
var DEFAULT_MAX_DELAY = 1e4;
|
|
34
|
+
var RETRYABLE_STATUS_CODES = new Set([408, 429, 502, 503, 504]);
|
|
35
|
+
function isRetryable(error) {
|
|
36
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (error instanceof TypeError) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function getRetryDelay(attempt, initialDelayMs, maxDelayMs) {
|
|
45
|
+
const delay = initialDelayMs * 2 ** attempt;
|
|
46
|
+
const jitter = delay * 0.2 * Math.random();
|
|
47
|
+
return Math.min(delay + jitter, maxDelayMs);
|
|
48
|
+
}
|
|
49
|
+
function createResilientFetch(options = {}) {
|
|
50
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
51
|
+
const maxRetries = options.retry ? options.retry.maxRetries ?? DEFAULT_MAX_RETRIES : 0;
|
|
52
|
+
const initialDelayMs = options.retry?.initialDelayMs ?? DEFAULT_INITIAL_DELAY;
|
|
53
|
+
const maxDelayMs = options.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY;
|
|
54
|
+
const resilientFetch = async (input, init) => {
|
|
55
|
+
let lastError;
|
|
56
|
+
const template = createRequestTemplate(input, init);
|
|
57
|
+
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
58
|
+
const controller = new AbortController;
|
|
59
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
60
|
+
const callerSignal = init?.signal;
|
|
61
|
+
if (callerSignal?.aborted) {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
throw callerSignal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
64
|
+
}
|
|
65
|
+
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
66
|
+
callerSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
67
|
+
try {
|
|
68
|
+
const response = await globalThis.fetch(new Request(template.clone(), { signal: controller.signal }));
|
|
69
|
+
clearTimeout(timeoutId);
|
|
70
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
71
|
+
if (RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries) {
|
|
72
|
+
lastError = new ConnectionError(`Request failed with status ${response.status}`);
|
|
73
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
81
|
+
if (callerSignal?.aborted) {
|
|
82
|
+
throw callerSignal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
83
|
+
}
|
|
84
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
85
|
+
lastError = new ConnectionError(`Request timed out after ${timeout}ms`);
|
|
86
|
+
if (attempt < maxRetries) {
|
|
87
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
88
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
throw lastError;
|
|
92
|
+
}
|
|
93
|
+
if (isRetryable(error) && attempt < maxRetries) {
|
|
94
|
+
lastError = error;
|
|
95
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
96
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw lastError;
|
|
103
|
+
};
|
|
104
|
+
return Object.assign(resilientFetch, {
|
|
105
|
+
preconnect: globalThis.fetch.preconnect?.bind(globalThis.fetch)
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function createRequestTemplate(input, init) {
|
|
109
|
+
const { signal: _signal, ...requestInit } = init ?? {};
|
|
110
|
+
if (input instanceof Request) {
|
|
111
|
+
return init ? new Request(input.clone(), requestInit) : input.clone();
|
|
112
|
+
}
|
|
113
|
+
return new Request(input, requestInit);
|
|
114
|
+
}
|
|
115
|
+
|
|
29
116
|
// src/core/client.ts
|
|
30
117
|
var DEFAULT_TIMEOUT_MS = 30000;
|
|
31
118
|
function createServarrClient(config) {
|
|
@@ -40,6 +127,10 @@ function createServarrClient(config) {
|
|
|
40
127
|
baseUrl: config.baseUrl.replace(/\/$/, "")
|
|
41
128
|
};
|
|
42
129
|
const timeoutMs = validatedConfig.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
130
|
+
const resilientFetch = createResilientFetch({
|
|
131
|
+
timeout: timeoutMs,
|
|
132
|
+
retry: validatedConfig.retry
|
|
133
|
+
});
|
|
43
134
|
return {
|
|
44
135
|
config: validatedConfig,
|
|
45
136
|
getHeaders: () => ({
|
|
@@ -48,7 +139,8 @@ function createServarrClient(config) {
|
|
|
48
139
|
...validatedConfig.headers
|
|
49
140
|
}),
|
|
50
141
|
getBaseUrl: () => validatedConfig.baseUrl,
|
|
51
|
-
getTimeout: () => timeoutMs
|
|
142
|
+
getTimeout: () => timeoutMs,
|
|
143
|
+
getFetch: () => resilientFetch
|
|
52
144
|
};
|
|
53
145
|
}
|
|
54
146
|
// src/generated/seerr/core/serverSentEvents.gen.ts
|
|
@@ -928,7 +1020,7 @@ class SeerrClient {
|
|
|
928
1020
|
"X-Api-Key": this.clientConfig.config.apiKey,
|
|
929
1021
|
...this.clientConfig.config.headers ?? {}
|
|
930
1022
|
},
|
|
931
|
-
|
|
1023
|
+
fetch: this.clientConfig.getFetch()
|
|
932
1024
|
});
|
|
933
1025
|
}
|
|
934
1026
|
async getSystemStatus() {
|
|
@@ -1004,7 +1096,7 @@ class SeerrClient {
|
|
|
1004
1096
|
"X-Api-Key": this.clientConfig.config.apiKey,
|
|
1005
1097
|
...this.clientConfig.config.headers ?? {}
|
|
1006
1098
|
},
|
|
1007
|
-
|
|
1099
|
+
fetch: this.clientConfig.getFetch()
|
|
1008
1100
|
});
|
|
1009
1101
|
return this.clientConfig.config;
|
|
1010
1102
|
}
|
package/dist/clients/sonarr.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ServarrBaseClient, type ServarrOps } from '../clients/base';
|
|
2
|
+
import type { ServarrClientConfig } from '../core/types';
|
|
2
3
|
import * as SonarrApi from '../generated/sonarr/index';
|
|
3
4
|
import type { CustomFormatBulkResource, CustomFormatResource, DownloadClientBulkResource, EpisodeFileListResource, EpisodeFileResource, EpisodeResource, ImportListResource, MediaManagementConfigResource, NamingConfigResource, QualityProfileResource, SeriesResource } from '../generated/sonarr/types.gen';
|
|
4
5
|
/**
|
|
@@ -16,7 +17,7 @@ import type { CustomFormatBulkResource, CustomFormatResource, DownloadClientBulk
|
|
|
16
17
|
*/
|
|
17
18
|
export declare class SonarrClient extends ServarrBaseClient {
|
|
18
19
|
protected readonly ops: ServarrOps;
|
|
19
|
-
|
|
20
|
+
constructor(config: ServarrClientConfig);
|
|
20
21
|
getSystemStatus(): Promise<({
|
|
21
22
|
data: unknown;
|
|
22
23
|
error: undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sonarr.d.ts","sourceRoot":"","sources":["../../src/clients/sonarr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"sonarr.d.ts","sourceRoot":"","sources":["../../src/clients/sonarr.ts"],"names":[],"mappings":"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"}
|
package/dist/clients/sonarr.js
CHANGED
|
@@ -26,6 +26,93 @@ class ConnectionError extends TsarrError {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// src/core/fetch.ts
|
|
30
|
+
var DEFAULT_TIMEOUT = 30000;
|
|
31
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
32
|
+
var DEFAULT_INITIAL_DELAY = 1000;
|
|
33
|
+
var DEFAULT_MAX_DELAY = 1e4;
|
|
34
|
+
var RETRYABLE_STATUS_CODES = new Set([408, 429, 502, 503, 504]);
|
|
35
|
+
function isRetryable(error) {
|
|
36
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (error instanceof TypeError) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function getRetryDelay(attempt, initialDelayMs, maxDelayMs) {
|
|
45
|
+
const delay = initialDelayMs * 2 ** attempt;
|
|
46
|
+
const jitter = delay * 0.2 * Math.random();
|
|
47
|
+
return Math.min(delay + jitter, maxDelayMs);
|
|
48
|
+
}
|
|
49
|
+
function createResilientFetch(options = {}) {
|
|
50
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
51
|
+
const maxRetries = options.retry ? options.retry.maxRetries ?? DEFAULT_MAX_RETRIES : 0;
|
|
52
|
+
const initialDelayMs = options.retry?.initialDelayMs ?? DEFAULT_INITIAL_DELAY;
|
|
53
|
+
const maxDelayMs = options.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY;
|
|
54
|
+
const resilientFetch = async (input, init) => {
|
|
55
|
+
let lastError;
|
|
56
|
+
const template = createRequestTemplate(input, init);
|
|
57
|
+
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
58
|
+
const controller = new AbortController;
|
|
59
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
60
|
+
const callerSignal = init?.signal;
|
|
61
|
+
if (callerSignal?.aborted) {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
throw callerSignal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
64
|
+
}
|
|
65
|
+
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
66
|
+
callerSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
67
|
+
try {
|
|
68
|
+
const response = await globalThis.fetch(new Request(template.clone(), { signal: controller.signal }));
|
|
69
|
+
clearTimeout(timeoutId);
|
|
70
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
71
|
+
if (RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries) {
|
|
72
|
+
lastError = new ConnectionError(`Request failed with status ${response.status}`);
|
|
73
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
81
|
+
if (callerSignal?.aborted) {
|
|
82
|
+
throw callerSignal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
83
|
+
}
|
|
84
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
85
|
+
lastError = new ConnectionError(`Request timed out after ${timeout}ms`);
|
|
86
|
+
if (attempt < maxRetries) {
|
|
87
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
88
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
throw lastError;
|
|
92
|
+
}
|
|
93
|
+
if (isRetryable(error) && attempt < maxRetries) {
|
|
94
|
+
lastError = error;
|
|
95
|
+
const delay = getRetryDelay(attempt, initialDelayMs, maxDelayMs);
|
|
96
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw lastError;
|
|
103
|
+
};
|
|
104
|
+
return Object.assign(resilientFetch, {
|
|
105
|
+
preconnect: globalThis.fetch.preconnect?.bind(globalThis.fetch)
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function createRequestTemplate(input, init) {
|
|
109
|
+
const { signal: _signal, ...requestInit } = init ?? {};
|
|
110
|
+
if (input instanceof Request) {
|
|
111
|
+
return init ? new Request(input.clone(), requestInit) : input.clone();
|
|
112
|
+
}
|
|
113
|
+
return new Request(input, requestInit);
|
|
114
|
+
}
|
|
115
|
+
|
|
29
116
|
// src/core/client.ts
|
|
30
117
|
var DEFAULT_TIMEOUT_MS = 30000;
|
|
31
118
|
function createServarrClient(config) {
|
|
@@ -40,6 +127,10 @@ function createServarrClient(config) {
|
|
|
40
127
|
baseUrl: config.baseUrl.replace(/\/$/, "")
|
|
41
128
|
};
|
|
42
129
|
const timeoutMs = validatedConfig.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
130
|
+
const resilientFetch = createResilientFetch({
|
|
131
|
+
timeout: timeoutMs,
|
|
132
|
+
retry: validatedConfig.retry
|
|
133
|
+
});
|
|
43
134
|
return {
|
|
44
135
|
config: validatedConfig,
|
|
45
136
|
getHeaders: () => ({
|
|
@@ -48,22 +139,28 @@ function createServarrClient(config) {
|
|
|
48
139
|
...validatedConfig.headers
|
|
49
140
|
}),
|
|
50
141
|
getBaseUrl: () => validatedConfig.baseUrl,
|
|
51
|
-
getTimeout: () => timeoutMs
|
|
142
|
+
getTimeout: () => timeoutMs,
|
|
143
|
+
getFetch: () => resilientFetch
|
|
52
144
|
};
|
|
53
145
|
}
|
|
54
146
|
|
|
55
147
|
// src/clients/base.ts
|
|
56
148
|
class ServarrBaseClient {
|
|
57
149
|
clientConfig;
|
|
58
|
-
|
|
150
|
+
rawClient;
|
|
151
|
+
constructor(config, rawClient) {
|
|
152
|
+
this.rawClient = rawClient;
|
|
59
153
|
this.clientConfig = createServarrClient(config);
|
|
60
154
|
this.configureRawClient();
|
|
61
155
|
}
|
|
156
|
+
configureRawClient() {
|
|
157
|
+
this.rawClient.setConfig(this.getClientConfig());
|
|
158
|
+
}
|
|
62
159
|
getClientConfig() {
|
|
63
160
|
return {
|
|
64
161
|
baseUrl: this.clientConfig.getBaseUrl(),
|
|
65
162
|
headers: this.clientConfig.getHeaders(),
|
|
66
|
-
|
|
163
|
+
fetch: this.clientConfig.getFetch()
|
|
67
164
|
};
|
|
68
165
|
}
|
|
69
166
|
async getSystemStatus() {
|
|
@@ -2338,8 +2435,8 @@ class SonarrClient extends ServarrBaseClient {
|
|
|
2338
2435
|
getUiConfigById: getApiV3ConfigUiById,
|
|
2339
2436
|
updateUiConfig: putApiV3ConfigUiById
|
|
2340
2437
|
};
|
|
2341
|
-
|
|
2342
|
-
client
|
|
2438
|
+
constructor(config) {
|
|
2439
|
+
super(config, client);
|
|
2343
2440
|
}
|
|
2344
2441
|
async getSystemStatus() {
|
|
2345
2442
|
return client.get({
|
package/dist/core/client.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare function createServarrClient(config: ServarrClientConfig): {
|
|
|
4
4
|
baseUrl: string;
|
|
5
5
|
apiKey: string;
|
|
6
6
|
timeout?: number;
|
|
7
|
+
retry?: import("./fetch").RetryOptions;
|
|
7
8
|
headers?: Record<string, string>;
|
|
8
9
|
};
|
|
9
10
|
getHeaders: () => {
|
|
@@ -12,6 +13,7 @@ export declare function createServarrClient(config: ServarrClientConfig): {
|
|
|
12
13
|
};
|
|
13
14
|
getBaseUrl: () => string;
|
|
14
15
|
getTimeout: () => number;
|
|
16
|
+
getFetch: () => typeof fetch;
|
|
15
17
|
};
|
|
16
18
|
export declare function validateApiKey(apiKey: string | undefined): string;
|
|
17
19
|
export declare function validateBaseUrl(baseUrl: string | undefined): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAInD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB;;;;;;;;;;;;;;;EAgC9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKjE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAmBnE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
/** Maximum number of retry attempts for transient failures (default: 3) */
|
|
3
|
+
maxRetries?: number;
|
|
4
|
+
/** Initial delay in ms before the first retry (default: 1000) */
|
|
5
|
+
initialDelayMs?: number;
|
|
6
|
+
/** Maximum delay in ms between retries (default: 10000) */
|
|
7
|
+
maxDelayMs?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ResilientFetchOptions {
|
|
10
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
11
|
+
timeout?: number;
|
|
12
|
+
/** Retry configuration for transient failures. Omit to disable retries. */
|
|
13
|
+
retry?: RetryOptions;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates a fetch function with timeout and retry support.
|
|
17
|
+
*
|
|
18
|
+
* - Timeout uses AbortController to cancel requests that exceed the limit.
|
|
19
|
+
* - Retry uses exponential backoff with jitter for transient failures
|
|
20
|
+
* (network errors and 408/429/502/503/504 status codes).
|
|
21
|
+
*/
|
|
22
|
+
export declare function createResilientFetch(options?: ResilientFetchOptions): typeof fetch;
|
|
23
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/core/fetch.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AA0BD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,KAAK,CAgFtF"}
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
+
import type { RetryOptions } from './fetch';
|
|
1
2
|
export interface ServarrClientConfig {
|
|
2
3
|
baseUrl: string;
|
|
3
4
|
apiKey: string;
|
|
5
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
4
6
|
timeout?: number;
|
|
7
|
+
/** Retry configuration for transient failures */
|
|
8
|
+
retry?: RetryOptions;
|
|
5
9
|
headers?: Record<string, string>;
|
|
6
10
|
}
|
|
7
11
|
export interface QBittorrentClientConfig {
|
|
8
12
|
baseUrl: string;
|
|
9
13
|
username: string;
|
|
10
14
|
password: string;
|
|
15
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
11
16
|
timeout?: number;
|
|
17
|
+
/** Retry configuration for transient failures */
|
|
18
|
+
retry?: RetryOptions;
|
|
12
19
|
}
|
|
13
20
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class p extends Error{code;statusCode;details;constructor(r,o,e,n){super(r);this.code=o;this.statusCode=e;this.details=n;this.name="TsarrError"}}class h extends p{constructor(r="Invalid or missing API key"){super(r,"API_KEY_ERROR",401);this.name="ApiKeyError"}}class c extends p{constructor(r,o){super(r,"CONNECTION_ERROR",void 0,o);this.name="ConnectionError"}}class K extends p{constructor(r,o){super(r,"VALIDATION_ERROR",void 0,o);this.name="ValidationError"}}class U extends p{constructor(r){super(`Resource not found: ${r}`,"NOT_FOUND",404);this.name="NotFoundError"}}var k=30000,B=3,$=1000,v=1e4,F=new Set([408,429,502,503,504]);function b(r){if(r instanceof DOMException&&r.name==="AbortError")return!1;if(r instanceof TypeError)return!0;return!1}function g(r,o,e){let n=o*2**r,s=n*0.2*Math.random();return Math.min(n+s,e)}function R(r={}){let o=r.timeout??k,e=r.retry?r.retry.maxRetries??B:0,n=r.retry?.initialDelayMs??$,s=r.retry?.maxDelayMs??v;return Object.assign(async(O,m)=>{let u,P=H(O,m);for(let d=0;d<=e;d++){let w=new AbortController,C=setTimeout(()=>w.abort(),o),f=m?.signal;if(f?.aborted)throw clearTimeout(C),f.reason??new DOMException("The operation was aborted.","AbortError");let N=()=>w.abort(f.reason);f?.addEventListener("abort",N,{once:!0});try{let t=await globalThis.fetch(new Request(P.clone(),{signal:w.signal}));if(clearTimeout(C),f?.removeEventListener("abort",N),F.has(t.status)&&d<e){u=new c(`Request failed with status ${t.status}`);let x=g(d,n,s);await new Promise((i)=>setTimeout(i,x));continue}return t}catch(t){if(clearTimeout(C),f?.removeEventListener("abort",N),f?.aborted)throw f.reason??new DOMException("The operation was aborted.","AbortError");if(t instanceof DOMException&&t.name==="AbortError"){if(u=new c(`Request timed out after ${o}ms`),d<e){let x=g(d,n,s);await new Promise((i)=>setTimeout(i,x));continue}throw u}if(b(t)&&d<e){u=t;let x=g(d,n,s);await new Promise((i)=>setTimeout(i,x));continue}throw t}}throw u},{preconnect:globalThis.fetch.preconnect?.bind(globalThis.fetch)})}function H(r,o){let{signal:e,...n}=o??{};if(r instanceof Request)return o?new Request(r.clone(),n):r.clone();return new Request(r,n)}var L=30000;function Z(r){if(!r.apiKey)throw new h;if(!r.baseUrl)throw new c("No base URL provided");let o={...r,baseUrl:r.baseUrl.replace(/\/$/,"")},e=o.timeout??L,n=R({timeout:e,retry:o.retry});return{config:o,getHeaders:()=>({"X-Api-Key":o.apiKey,"Content-Type":"application/json",...o.headers}),getBaseUrl:()=>o.baseUrl,getTimeout:()=>e,getFetch:()=>n}}function I(r){if(!r||r.trim()==="")throw new h;return r.trim()}function X(r){if(!r||r.trim()==="")throw new c("No base URL provided");let o;try{o=new URL(r)}catch{throw new c(`Failed to connect: Invalid URL: ${r}`)}if(o.protocol==="http:"&&!V(o.hostname))console.warn(`Warning: Using unencrypted HTTP for remote URL "${o.host}". Consider using HTTPS to protect your API key in transit.`);return r.trim().replace(/\/$/,"")}function V(r){return r==="localhost"||r==="127.0.0.1"||r==="::1"||r==="0.0.0.0"||r.endsWith(".local")||/^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(r)}export{X as validateBaseUrl,I as validateApiKey,Z as createServarrClient,R as createResilientFetch,K as ValidationError,p as TsarrError,dr as SonarrClient,wr as Sonarr,er as SeerrClient,hr as Seerr,or as ReadarrClient,pr as Readarr,l as RadarrClient,ir as Radarr,M as QBittorrentClient,xr as QBittorrent,E as ProwlarrClient,ur as Prowlarr,U as NotFoundError,S as LidarrClient,sr as Lidarr,c as ConnectionError,q as BazarrClient,cr as Bazarr,h as ApiKeyError};
|
|
Binary file
|
package/package.json
CHANGED
package/dist/tsarr-2.9.1.tgz
DELETED
|
Binary file
|