tsarr 2.9.0 → 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/README.md +7 -5
- package/dist/cli/commands/bazarr.d.ts +2 -0
- package/dist/cli/commands/bazarr.d.ts.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/lidarr.d.ts +2 -0
- package/dist/cli/commands/lidarr.d.ts.map +1 -1
- package/dist/cli/commands/radarr.d.ts.map +1 -1
- package/dist/cli/commands/readarr.d.ts +2 -0
- package/dist/cli/commands/readarr.d.ts.map +1 -1
- package/dist/cli/commands/sonarr.d.ts.map +1 -1
- package/dist/cli/index.js +2138 -2405
- package/dist/clients/base.d.ts +136 -0
- package/dist/clients/base.d.ts.map +1 -0
- package/dist/clients/bazarr.d.ts +1 -1
- package/dist/clients/bazarr.d.ts.map +1 -1
- package/dist/clients/bazarr.js +100 -3
- package/dist/clients/lidarr.d.ts +24 -681
- package/dist/clients/lidarr.d.ts.map +1 -1
- package/dist/clients/lidarr.js +323 -196
- package/dist/clients/prowlarr.d.ts +25 -638
- package/dist/clients/prowlarr.d.ts.map +1 -1
- package/dist/clients/prowlarr.js +331 -175
- package/dist/clients/qbittorrent.d.ts +1 -17
- package/dist/clients/qbittorrent.d.ts.map +1 -1
- package/dist/clients/qbittorrent.js +97 -2
- package/dist/clients/radarr.d.ts +4 -657
- package/dist/clients/radarr.d.ts.map +1 -1
- package/dist/clients/radarr.js +323 -164
- package/dist/clients/readarr.d.ts +4 -635
- package/dist/clients/readarr.d.ts.map +1 -1
- package/dist/clients/readarr.js +323 -164
- package/dist/clients/seerr.d.ts +1 -1
- package/dist/clients/seerr.d.ts.map +1 -1
- package/dist/clients/seerr.js +100 -3
- package/dist/clients/sonarr.d.ts +181 -772
- package/dist/clients/sonarr.d.ts.map +1 -1
- package/dist/clients/sonarr.js +346 -157
- package/dist/core/client.d.ts +3 -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 +2 -4
- package/dist/tsarr-2.9.0.tgz +0 -0
package/dist/clients/seerr.js
CHANGED
|
@@ -26,7 +26,95 @@ 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
|
|
117
|
+
var DEFAULT_TIMEOUT_MS = 30000;
|
|
30
118
|
function createServarrClient(config) {
|
|
31
119
|
if (!config.apiKey) {
|
|
32
120
|
throw new ApiKeyError;
|
|
@@ -38,6 +126,11 @@ function createServarrClient(config) {
|
|
|
38
126
|
...config,
|
|
39
127
|
baseUrl: config.baseUrl.replace(/\/$/, "")
|
|
40
128
|
};
|
|
129
|
+
const timeoutMs = validatedConfig.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
130
|
+
const resilientFetch = createResilientFetch({
|
|
131
|
+
timeout: timeoutMs,
|
|
132
|
+
retry: validatedConfig.retry
|
|
133
|
+
});
|
|
41
134
|
return {
|
|
42
135
|
config: validatedConfig,
|
|
43
136
|
getHeaders: () => ({
|
|
@@ -45,7 +138,9 @@ function createServarrClient(config) {
|
|
|
45
138
|
"Content-Type": "application/json",
|
|
46
139
|
...validatedConfig.headers
|
|
47
140
|
}),
|
|
48
|
-
getBaseUrl: () => validatedConfig.baseUrl
|
|
141
|
+
getBaseUrl: () => validatedConfig.baseUrl,
|
|
142
|
+
getTimeout: () => timeoutMs,
|
|
143
|
+
getFetch: () => resilientFetch
|
|
49
144
|
};
|
|
50
145
|
}
|
|
51
146
|
// src/generated/seerr/core/serverSentEvents.gen.ts
|
|
@@ -924,7 +1019,8 @@ class SeerrClient {
|
|
|
924
1019
|
headers: {
|
|
925
1020
|
"X-Api-Key": this.clientConfig.config.apiKey,
|
|
926
1021
|
...this.clientConfig.config.headers ?? {}
|
|
927
|
-
}
|
|
1022
|
+
},
|
|
1023
|
+
fetch: this.clientConfig.getFetch()
|
|
928
1024
|
});
|
|
929
1025
|
}
|
|
930
1026
|
async getSystemStatus() {
|
|
@@ -999,7 +1095,8 @@ class SeerrClient {
|
|
|
999
1095
|
headers: {
|
|
1000
1096
|
"X-Api-Key": this.clientConfig.config.apiKey,
|
|
1001
1097
|
...this.clientConfig.config.headers ?? {}
|
|
1002
|
-
}
|
|
1098
|
+
},
|
|
1099
|
+
fetch: this.clientConfig.getFetch()
|
|
1003
1100
|
});
|
|
1004
1101
|
return this.clientConfig.config;
|
|
1005
1102
|
}
|