tsarr 2.10.0 → 2.11.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/LICENSE +21 -0
- package/README.md +120 -233
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/manual-import.d.ts +30 -0
- package/dist/cli/commands/manual-import.d.ts.map +1 -0
- package/dist/cli/commands/radarr.d.ts.map +1 -1
- package/dist/cli/commands/sonarr.d.ts.map +1 -1
- package/dist/cli/index.js +5200 -4854
- package/dist/cli/index.js.map +133 -0
- package/dist/clients/bazarr.d.ts +124 -124
- package/dist/clients/bazarr.js +88 -97
- package/dist/clients/bazarr.js.map +22 -0
- package/dist/clients/lidarr.d.ts +146 -146
- package/dist/clients/lidarr.js +88 -97
- package/dist/clients/lidarr.js.map +23 -0
- package/dist/clients/prowlarr.d.ts +28 -28
- package/dist/clients/prowlarr.js +88 -97
- package/dist/clients/prowlarr.js.map +23 -0
- package/dist/clients/qbittorrent.d.ts +2 -0
- package/dist/clients/qbittorrent.d.ts.map +1 -1
- package/dist/clients/qbittorrent.js +119 -102
- package/dist/clients/qbittorrent.js.map +21 -0
- package/dist/clients/radarr.d.ts +193 -149
- package/dist/clients/radarr.d.ts.map +1 -1
- package/dist/clients/radarr.js +128 -97
- package/dist/clients/radarr.js.map +23 -0
- package/dist/clients/readarr.d.ts +148 -148
- package/dist/clients/readarr.js +88 -97
- package/dist/clients/readarr.js.map +23 -0
- package/dist/clients/seerr-types.d.ts +1 -1
- package/dist/clients/seerr-types.d.ts.map +1 -1
- package/dist/clients/seerr.d.ts +16 -16
- package/dist/clients/seerr.js +88 -97
- package/dist/clients/seerr.js.map +22 -0
- package/dist/clients/sonarr.d.ts +201 -167
- package/dist/clients/sonarr.d.ts.map +1 -1
- package/dist/clients/sonarr.js +104 -107
- package/dist/clients/sonarr.js.map +23 -0
- package/dist/generated/bazarr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/bazarr/client/types.gen.d.ts +5 -2
- package/dist/generated/bazarr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/bazarr/client/utils.gen.d.ts +5 -1
- package/dist/generated/bazarr/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/lidarr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/lidarr/client/types.gen.d.ts +5 -2
- package/dist/generated/lidarr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/lidarr/client/utils.gen.d.ts +5 -1
- package/dist/generated/lidarr/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/prowlarr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/prowlarr/client/types.gen.d.ts +5 -2
- package/dist/generated/prowlarr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/prowlarr/client/utils.gen.d.ts +5 -1
- package/dist/generated/prowlarr/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/qbittorrent/client/client.gen.d.ts.map +1 -1
- package/dist/generated/qbittorrent/client/types.gen.d.ts +5 -2
- package/dist/generated/qbittorrent/client/types.gen.d.ts.map +1 -1
- package/dist/generated/qbittorrent/client/utils.gen.d.ts +5 -1
- package/dist/generated/qbittorrent/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/radarr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/radarr/client/types.gen.d.ts +5 -2
- package/dist/generated/radarr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/radarr/client/utils.gen.d.ts +5 -1
- package/dist/generated/radarr/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/readarr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/readarr/client/types.gen.d.ts +5 -2
- package/dist/generated/readarr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/readarr/client/utils.gen.d.ts +5 -1
- package/dist/generated/readarr/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/seerr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/seerr/client/types.gen.d.ts +5 -2
- package/dist/generated/seerr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/seerr/client/utils.gen.d.ts +5 -1
- package/dist/generated/seerr/client/utils.gen.d.ts.map +1 -1
- package/dist/generated/seerr/index.d.ts +2 -2
- package/dist/generated/seerr/index.d.ts.map +1 -1
- package/dist/generated/seerr/sdk.gen.d.ts +13 -1
- package/dist/generated/seerr/sdk.gen.d.ts.map +1 -1
- package/dist/generated/seerr/types.gen.d.ts +78 -7
- package/dist/generated/seerr/types.gen.d.ts.map +1 -1
- package/dist/generated/sonarr/client/client.gen.d.ts.map +1 -1
- package/dist/generated/sonarr/client/types.gen.d.ts +5 -2
- package/dist/generated/sonarr/client/types.gen.d.ts.map +1 -1
- package/dist/generated/sonarr/client/utils.gen.d.ts +5 -1
- package/dist/generated/sonarr/client/utils.gen.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +12 -0
- package/dist/tsarr-2.11.0.tgz +0 -0
- package/package.json +18 -9
- package/dist/tsarr-2.10.0.tgz +0 -0
|
@@ -745,126 +745,115 @@ var createClient = (config = {}) => {
|
|
|
745
745
|
return { opts: resolvedOpts, url };
|
|
746
746
|
};
|
|
747
747
|
const request = async (options) => {
|
|
748
|
-
const
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
...opts,
|
|
752
|
-
body: getValidRequestBody(opts)
|
|
753
|
-
};
|
|
754
|
-
let request2 = new Request(url, requestInit);
|
|
755
|
-
for (const fn of interceptors.request.fns) {
|
|
756
|
-
if (fn) {
|
|
757
|
-
request2 = await fn(request2, opts);
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
const _fetch = opts.fetch;
|
|
748
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
749
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
750
|
+
let request2;
|
|
761
751
|
let response;
|
|
762
752
|
try {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
753
|
+
const { opts, url } = await beforeRequest(options);
|
|
754
|
+
const requestInit = {
|
|
755
|
+
redirect: "follow",
|
|
756
|
+
...opts,
|
|
757
|
+
body: getValidRequestBody(opts)
|
|
758
|
+
};
|
|
759
|
+
request2 = new Request(url, requestInit);
|
|
760
|
+
for (const fn of interceptors.request.fns) {
|
|
767
761
|
if (fn) {
|
|
768
|
-
|
|
762
|
+
request2 = await fn(request2, opts);
|
|
769
763
|
}
|
|
770
764
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
765
|
+
const _fetch = opts.fetch;
|
|
766
|
+
response = await _fetch(request2);
|
|
767
|
+
for (const fn of interceptors.response.fns) {
|
|
768
|
+
if (fn) {
|
|
769
|
+
response = await fn(response, request2, opts);
|
|
770
|
+
}
|
|
774
771
|
}
|
|
775
|
-
|
|
776
|
-
error: finalError2,
|
|
772
|
+
const result = {
|
|
777
773
|
request: request2,
|
|
778
|
-
response
|
|
774
|
+
response
|
|
779
775
|
};
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
776
|
+
if (response.ok) {
|
|
777
|
+
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
778
|
+
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
779
|
+
let emptyData;
|
|
780
|
+
switch (parseAs) {
|
|
781
|
+
case "arrayBuffer":
|
|
782
|
+
case "blob":
|
|
783
|
+
case "text":
|
|
784
|
+
emptyData = await response[parseAs]();
|
|
785
|
+
break;
|
|
786
|
+
case "formData":
|
|
787
|
+
emptyData = new FormData;
|
|
788
|
+
break;
|
|
789
|
+
case "stream":
|
|
790
|
+
emptyData = response.body;
|
|
791
|
+
break;
|
|
792
|
+
case "json":
|
|
793
|
+
default:
|
|
794
|
+
emptyData = {};
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
return opts.responseStyle === "data" ? emptyData : {
|
|
798
|
+
data: emptyData,
|
|
799
|
+
...result
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
let data;
|
|
794
803
|
switch (parseAs) {
|
|
795
804
|
case "arrayBuffer":
|
|
796
805
|
case "blob":
|
|
806
|
+
case "formData":
|
|
797
807
|
case "text":
|
|
798
|
-
|
|
808
|
+
data = await response[parseAs]();
|
|
799
809
|
break;
|
|
800
|
-
case "
|
|
801
|
-
|
|
810
|
+
case "json": {
|
|
811
|
+
const text = await response.text();
|
|
812
|
+
data = text ? JSON.parse(text) : {};
|
|
802
813
|
break;
|
|
814
|
+
}
|
|
803
815
|
case "stream":
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
emptyData = {};
|
|
809
|
-
break;
|
|
816
|
+
return opts.responseStyle === "data" ? response.body : {
|
|
817
|
+
data: response.body,
|
|
818
|
+
...result
|
|
819
|
+
};
|
|
810
820
|
}
|
|
811
|
-
|
|
812
|
-
|
|
821
|
+
if (parseAs === "json") {
|
|
822
|
+
if (opts.responseValidator) {
|
|
823
|
+
await opts.responseValidator(data);
|
|
824
|
+
}
|
|
825
|
+
if (opts.responseTransformer) {
|
|
826
|
+
data = await opts.responseTransformer(data);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return opts.responseStyle === "data" ? data : {
|
|
830
|
+
data,
|
|
813
831
|
...result
|
|
814
832
|
};
|
|
815
833
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
break;
|
|
834
|
+
const textError = await response.text();
|
|
835
|
+
let jsonError;
|
|
836
|
+
try {
|
|
837
|
+
jsonError = JSON.parse(textError);
|
|
838
|
+
} catch {}
|
|
839
|
+
throw jsonError ?? textError;
|
|
840
|
+
} catch (error) {
|
|
841
|
+
let finalError = error;
|
|
842
|
+
for (const fn of interceptors.error.fns) {
|
|
843
|
+
if (fn) {
|
|
844
|
+
finalError = await fn(finalError, response, request2, options);
|
|
828
845
|
}
|
|
829
|
-
case "stream":
|
|
830
|
-
return opts.responseStyle === "data" ? response.body : {
|
|
831
|
-
data: response.body,
|
|
832
|
-
...result
|
|
833
|
-
};
|
|
834
846
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
}
|
|
839
|
-
if (opts.responseTransformer) {
|
|
840
|
-
data = await opts.responseTransformer(data);
|
|
841
|
-
}
|
|
847
|
+
finalError = finalError || {};
|
|
848
|
+
if (throwOnError) {
|
|
849
|
+
throw finalError;
|
|
842
850
|
}
|
|
843
|
-
return
|
|
844
|
-
|
|
845
|
-
|
|
851
|
+
return responseStyle === "data" ? undefined : {
|
|
852
|
+
error: finalError,
|
|
853
|
+
request: request2,
|
|
854
|
+
response
|
|
846
855
|
};
|
|
847
856
|
}
|
|
848
|
-
const textError = await response.text();
|
|
849
|
-
let jsonError;
|
|
850
|
-
try {
|
|
851
|
-
jsonError = JSON.parse(textError);
|
|
852
|
-
} catch {}
|
|
853
|
-
const error = jsonError ?? textError;
|
|
854
|
-
let finalError = error;
|
|
855
|
-
for (const fn of interceptors.error.fns) {
|
|
856
|
-
if (fn) {
|
|
857
|
-
finalError = await fn(error, response, request2, opts);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
finalError = finalError || {};
|
|
861
|
-
if (opts.throwOnError) {
|
|
862
|
-
throw finalError;
|
|
863
|
-
}
|
|
864
|
-
return opts.responseStyle === "data" ? undefined : {
|
|
865
|
-
error: finalError,
|
|
866
|
-
...result
|
|
867
|
-
};
|
|
868
857
|
};
|
|
869
858
|
const makeMethodFn = (method) => (options) => request({ ...options, method });
|
|
870
859
|
const makeSseFn = (method) => async (options) => {
|
|
@@ -872,7 +861,6 @@ var createClient = (config = {}) => {
|
|
|
872
861
|
return createSseClient({
|
|
873
862
|
...opts,
|
|
874
863
|
body: opts.body,
|
|
875
|
-
headers: opts.headers,
|
|
876
864
|
method,
|
|
877
865
|
onRequest: async (url2, init) => {
|
|
878
866
|
let request2 = new Request(url2, init);
|
|
@@ -1011,6 +999,7 @@ class QBittorrentClient {
|
|
|
1011
999
|
username;
|
|
1012
1000
|
password;
|
|
1013
1001
|
sid = null;
|
|
1002
|
+
cookieName = "SID";
|
|
1014
1003
|
fetch;
|
|
1015
1004
|
constructor(config) {
|
|
1016
1005
|
if (!config.baseUrl) {
|
|
@@ -1019,16 +1008,40 @@ class QBittorrentClient {
|
|
|
1019
1008
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
1020
1009
|
this.username = config.username;
|
|
1021
1010
|
this.password = config.password;
|
|
1022
|
-
|
|
1011
|
+
const baseFetch = createResilientFetch({
|
|
1023
1012
|
timeout: config.timeout ?? DEFAULT_TIMEOUT_MS,
|
|
1024
1013
|
retry: config.retry
|
|
1025
1014
|
});
|
|
1015
|
+
this.fetch = (input, init) => this.fetchWithCookieName(baseFetch, input, init);
|
|
1026
1016
|
client.setConfig({
|
|
1027
1017
|
baseUrl: `${this.baseUrl}/api/v2`,
|
|
1028
1018
|
auth: () => this.ensureAuth(),
|
|
1029
1019
|
fetch: this.fetch
|
|
1030
1020
|
});
|
|
1031
1021
|
}
|
|
1022
|
+
async fetchWithCookieName(baseFetch, input, init) {
|
|
1023
|
+
if (this.cookieName === "SID") {
|
|
1024
|
+
return baseFetch(input, init);
|
|
1025
|
+
}
|
|
1026
|
+
if (input instanceof Request) {
|
|
1027
|
+
const cookie = input.headers.get("cookie");
|
|
1028
|
+
if (cookie?.includes("SID=")) {
|
|
1029
|
+
const headers = new Headers(input.headers);
|
|
1030
|
+
headers.set("cookie", cookie.replace(/(^|;\s*)SID=/, `$1${this.cookieName}=`));
|
|
1031
|
+
return baseFetch(new Request(input, { headers }), init);
|
|
1032
|
+
}
|
|
1033
|
+
return baseFetch(input, init);
|
|
1034
|
+
}
|
|
1035
|
+
if (init?.headers) {
|
|
1036
|
+
const headers = new Headers(init.headers);
|
|
1037
|
+
const cookie = headers.get("cookie");
|
|
1038
|
+
if (cookie?.includes("SID=")) {
|
|
1039
|
+
headers.set("cookie", cookie.replace(/(^|;\s*)SID=/, `$1${this.cookieName}=`));
|
|
1040
|
+
return baseFetch(input, { ...init, headers });
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
return baseFetch(input, init);
|
|
1044
|
+
}
|
|
1032
1045
|
async ensureAuth() {
|
|
1033
1046
|
if (!this.sid) {
|
|
1034
1047
|
await this.login();
|
|
@@ -1050,16 +1063,17 @@ class QBittorrentClient {
|
|
|
1050
1063
|
if (!response.ok) {
|
|
1051
1064
|
throw new ConnectionError(`qBittorrent login failed (${response.status})`);
|
|
1052
1065
|
}
|
|
1053
|
-
const text = await response.text();
|
|
1054
|
-
if (text
|
|
1066
|
+
const text = (await response.text()).trim();
|
|
1067
|
+
if (text && text !== "Ok.") {
|
|
1055
1068
|
throw new ConnectionError("qBittorrent authentication failed: invalid username or password");
|
|
1056
1069
|
}
|
|
1057
1070
|
const setCookie = response.headers.get("set-cookie");
|
|
1058
|
-
const sidMatch = setCookie?.match(/SID=([^;]+)/);
|
|
1071
|
+
const sidMatch = setCookie?.match(/(SID|QBT_SID_\d+)=([^;]+)/);
|
|
1059
1072
|
if (!sidMatch) {
|
|
1060
1073
|
throw new ConnectionError("qBittorrent login succeeded but no SID cookie received");
|
|
1061
1074
|
}
|
|
1062
|
-
this.
|
|
1075
|
+
this.cookieName = sidMatch[1];
|
|
1076
|
+
this.sid = sidMatch[2];
|
|
1063
1077
|
}
|
|
1064
1078
|
async getAppVersion() {
|
|
1065
1079
|
const result = await appVersionGet();
|
|
@@ -1104,3 +1118,6 @@ class QBittorrentClient {
|
|
|
1104
1118
|
export {
|
|
1105
1119
|
QBittorrentClient
|
|
1106
1120
|
};
|
|
1121
|
+
|
|
1122
|
+
//# debugId=EEFE0D3C2E02FFD464756E2164756E21
|
|
1123
|
+
//# sourceMappingURL=qbittorrent.js.map
|