tsarr 2.4.0 → 2.4.2
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/commands/lidarr.d.ts.map +1 -1
- package/dist/cli/commands/prowlarr.d.ts.map +1 -1
- package/dist/cli/commands/radarr.d.ts.map +1 -1
- 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 +1257 -190
- package/dist/clients/bazarr.d.ts.map +1 -1
- package/dist/clients/bazarr.js +10 -2
- package/dist/clients/lidarr.d.ts +26 -0
- package/dist/clients/lidarr.d.ts.map +1 -1
- package/dist/clients/lidarr.js +47 -0
- package/dist/clients/readarr.d.ts +46 -0
- package/dist/clients/readarr.d.ts.map +1 -1
- package/dist/clients/readarr.js +84 -0
- package/dist/clients/sonarr.d.ts.map +1 -1
- package/dist/clients/sonarr.js +1 -0
- package/dist/index.js +13 -13
- package/dist/tsarr-2.4.2.tgz +0 -0
- package/package.json +1 -1
- package/dist/tsarr-2.4.0.tgz +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -5259,6 +5259,7 @@ var exports_radarr3 = {};
|
|
|
5259
5259
|
__export(exports_radarr3, {
|
|
5260
5260
|
radarr: () => radarr
|
|
5261
5261
|
});
|
|
5262
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
5262
5263
|
function unwrapData(result) {
|
|
5263
5264
|
return result?.data ?? result;
|
|
5264
5265
|
}
|
|
@@ -5299,6 +5300,10 @@ async function findMovieByTmdbId(client2, tmdbId) {
|
|
|
5299
5300
|
function getApiStatus(result) {
|
|
5300
5301
|
return result?.error?.status ?? result?.response?.status;
|
|
5301
5302
|
}
|
|
5303
|
+
function readJsonInput(filePath) {
|
|
5304
|
+
const raw = filePath === "-" ? readFileSync2(0, "utf-8") : readFileSync2(filePath, "utf-8");
|
|
5305
|
+
return JSON.parse(raw);
|
|
5306
|
+
}
|
|
5302
5307
|
var resources, radarr;
|
|
5303
5308
|
var init_radarr3 = __esm(() => {
|
|
5304
5309
|
init_radarr2();
|
|
@@ -5319,6 +5324,7 @@ var init_radarr3 = __esm(() => {
|
|
|
5319
5324
|
name: "get",
|
|
5320
5325
|
description: "Get a movie by ID",
|
|
5321
5326
|
args: [{ name: "id", description: "Movie ID", required: true, type: "number" }],
|
|
5327
|
+
columns: ["id", "title", "year", "monitored", "hasFile", "status", "qualityProfileId"],
|
|
5322
5328
|
run: (c3, a2) => c3.getMovie(a2.id)
|
|
5323
5329
|
},
|
|
5324
5330
|
{
|
|
@@ -5657,6 +5663,24 @@ var init_radarr3 = __esm(() => {
|
|
|
5657
5663
|
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
5658
5664
|
run: (c3, a2) => c3.getNotification(a2.id)
|
|
5659
5665
|
},
|
|
5666
|
+
{
|
|
5667
|
+
name: "add",
|
|
5668
|
+
description: "Add a notification from JSON file or stdin",
|
|
5669
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
5670
|
+
run: async (c3, a2) => c3.addNotification(readJsonInput(a2.file))
|
|
5671
|
+
},
|
|
5672
|
+
{
|
|
5673
|
+
name: "edit",
|
|
5674
|
+
description: "Edit a notification (merges JSON with existing)",
|
|
5675
|
+
args: [
|
|
5676
|
+
{ name: "id", description: "Notification ID", required: true, type: "number" },
|
|
5677
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
5678
|
+
],
|
|
5679
|
+
run: async (c3, a2) => {
|
|
5680
|
+
const existing = unwrapData(await c3.getNotification(a2.id));
|
|
5681
|
+
return c3.updateNotification(a2.id, { ...existing, ...readJsonInput(a2.file) });
|
|
5682
|
+
}
|
|
5683
|
+
},
|
|
5660
5684
|
{
|
|
5661
5685
|
name: "delete",
|
|
5662
5686
|
description: "Delete a notification",
|
|
@@ -5687,6 +5711,24 @@ var init_radarr3 = __esm(() => {
|
|
|
5687
5711
|
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
5688
5712
|
run: (c3, a2) => c3.getDownloadClient(a2.id)
|
|
5689
5713
|
},
|
|
5714
|
+
{
|
|
5715
|
+
name: "add",
|
|
5716
|
+
description: "Add a download client from JSON file or stdin",
|
|
5717
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
5718
|
+
run: async (c3, a2) => c3.addDownloadClient(readJsonInput(a2.file))
|
|
5719
|
+
},
|
|
5720
|
+
{
|
|
5721
|
+
name: "edit",
|
|
5722
|
+
description: "Edit a download client (merges JSON with existing)",
|
|
5723
|
+
args: [
|
|
5724
|
+
{ name: "id", description: "Download client ID", required: true, type: "number" },
|
|
5725
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
5726
|
+
],
|
|
5727
|
+
run: async (c3, a2) => {
|
|
5728
|
+
const existing = unwrapData(await c3.getDownloadClient(a2.id));
|
|
5729
|
+
return c3.updateDownloadClient(a2.id, { ...existing, ...readJsonInput(a2.file) });
|
|
5730
|
+
}
|
|
5731
|
+
},
|
|
5690
5732
|
{
|
|
5691
5733
|
name: "delete",
|
|
5692
5734
|
description: "Delete a download client",
|
|
@@ -5754,6 +5796,24 @@ var init_radarr3 = __esm(() => {
|
|
|
5754
5796
|
args: [{ name: "id", description: "Import list ID", required: true, type: "number" }],
|
|
5755
5797
|
run: (c3, a2) => c3.getImportList(a2.id)
|
|
5756
5798
|
},
|
|
5799
|
+
{
|
|
5800
|
+
name: "add",
|
|
5801
|
+
description: "Add an import list from JSON file or stdin",
|
|
5802
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
5803
|
+
run: async (c3, a2) => c3.addImportList(readJsonInput(a2.file))
|
|
5804
|
+
},
|
|
5805
|
+
{
|
|
5806
|
+
name: "edit",
|
|
5807
|
+
description: "Edit an import list (merges JSON with existing)",
|
|
5808
|
+
args: [
|
|
5809
|
+
{ name: "id", description: "Import list ID", required: true, type: "number" },
|
|
5810
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
5811
|
+
],
|
|
5812
|
+
run: async (c3, a2) => {
|
|
5813
|
+
const existing = unwrapData(await c3.getImportList(a2.id));
|
|
5814
|
+
return c3.updateImportList(a2.id, { ...existing, ...readJsonInput(a2.file) });
|
|
5815
|
+
}
|
|
5816
|
+
},
|
|
5757
5817
|
{
|
|
5758
5818
|
name: "delete",
|
|
5759
5819
|
description: "Delete an import list",
|
|
@@ -8029,6 +8089,7 @@ class SonarrClient {
|
|
|
8029
8089
|
query.end = endDate;
|
|
8030
8090
|
if (unmonitored !== undefined)
|
|
8031
8091
|
query.unmonitored = unmonitored;
|
|
8092
|
+
query.includeSeries = true;
|
|
8032
8093
|
return getApiV3Calendar2(Object.keys(query).length > 0 ? { query } : {});
|
|
8033
8094
|
}
|
|
8034
8095
|
async getCalendarFeed(pastDays, futureDays, tags) {
|
|
@@ -8177,6 +8238,7 @@ var exports_sonarr3 = {};
|
|
|
8177
8238
|
__export(exports_sonarr3, {
|
|
8178
8239
|
sonarr: () => sonarr
|
|
8179
8240
|
});
|
|
8241
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
8180
8242
|
function unwrapData2(result) {
|
|
8181
8243
|
return result?.data ?? result;
|
|
8182
8244
|
}
|
|
@@ -8236,6 +8298,10 @@ async function findSeriesByTvdbId(client3, tvdbId) {
|
|
|
8236
8298
|
function getApiStatus2(result) {
|
|
8237
8299
|
return result?.error?.status ?? result?.response?.status;
|
|
8238
8300
|
}
|
|
8301
|
+
function readJsonInput2(filePath) {
|
|
8302
|
+
const raw = filePath === "-" ? readFileSync3(0, "utf-8") : readFileSync3(filePath, "utf-8");
|
|
8303
|
+
return JSON.parse(raw);
|
|
8304
|
+
}
|
|
8239
8305
|
var resources2, sonarr;
|
|
8240
8306
|
var init_sonarr3 = __esm(() => {
|
|
8241
8307
|
init_sonarr2();
|
|
@@ -8268,7 +8334,21 @@ var init_sonarr3 = __esm(() => {
|
|
|
8268
8334
|
name: "get",
|
|
8269
8335
|
description: "Get a series by ID",
|
|
8270
8336
|
args: [{ name: "id", description: "Series ID", required: true, type: "number" }],
|
|
8271
|
-
|
|
8337
|
+
columns: [
|
|
8338
|
+
"id",
|
|
8339
|
+
"title",
|
|
8340
|
+
"year",
|
|
8341
|
+
"monitored",
|
|
8342
|
+
"seasonCount",
|
|
8343
|
+
"episodeCount",
|
|
8344
|
+
"network",
|
|
8345
|
+
"status"
|
|
8346
|
+
],
|
|
8347
|
+
run: async (c3, a2) => {
|
|
8348
|
+
const result = await c3.getSeriesById(a2.id);
|
|
8349
|
+
const series = unwrapData2(result);
|
|
8350
|
+
return formatSeriesListItem(series);
|
|
8351
|
+
}
|
|
8272
8352
|
},
|
|
8273
8353
|
{
|
|
8274
8354
|
name: "search",
|
|
@@ -8438,6 +8518,12 @@ var init_sonarr3 = __esm(() => {
|
|
|
8438
8518
|
description: "List quality profiles",
|
|
8439
8519
|
columns: ["id", "name"],
|
|
8440
8520
|
run: (c3) => c3.getQualityProfiles()
|
|
8521
|
+
},
|
|
8522
|
+
{
|
|
8523
|
+
name: "get",
|
|
8524
|
+
description: "Get a quality profile by ID",
|
|
8525
|
+
args: [{ name: "id", description: "Profile ID", required: true, type: "number" }],
|
|
8526
|
+
run: (c3, a2) => c3.getQualityProfile(a2.id)
|
|
8441
8527
|
}
|
|
8442
8528
|
]
|
|
8443
8529
|
},
|
|
@@ -8586,7 +8672,14 @@ var init_sonarr3 = __esm(() => {
|
|
|
8586
8672
|
{ name: "unmonitored", description: "Include unmonitored", type: "boolean" }
|
|
8587
8673
|
],
|
|
8588
8674
|
columns: ["id", "seriesTitle", "title", "seasonNumber", "episodeNumber", "airDateUtc"],
|
|
8589
|
-
run: (c3, a2) =>
|
|
8675
|
+
run: async (c3, a2) => {
|
|
8676
|
+
const result = await c3.getCalendar(a2.start, a2.end, a2.unmonitored);
|
|
8677
|
+
const episodes = unwrapData2(result);
|
|
8678
|
+
return episodes.map((ep) => ({
|
|
8679
|
+
...ep,
|
|
8680
|
+
seriesTitle: ep.seriesTitle || ep.series?.title || "—"
|
|
8681
|
+
}));
|
|
8682
|
+
}
|
|
8590
8683
|
}
|
|
8591
8684
|
]
|
|
8592
8685
|
},
|
|
@@ -8606,6 +8699,24 @@ var init_sonarr3 = __esm(() => {
|
|
|
8606
8699
|
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
8607
8700
|
run: (c3, a2) => c3.getNotification(a2.id)
|
|
8608
8701
|
},
|
|
8702
|
+
{
|
|
8703
|
+
name: "add",
|
|
8704
|
+
description: "Add a notification from JSON file or stdin",
|
|
8705
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
8706
|
+
run: async (c3, a2) => c3.addNotification(readJsonInput2(a2.file))
|
|
8707
|
+
},
|
|
8708
|
+
{
|
|
8709
|
+
name: "edit",
|
|
8710
|
+
description: "Edit a notification (merges JSON with existing)",
|
|
8711
|
+
args: [
|
|
8712
|
+
{ name: "id", description: "Notification ID", required: true, type: "number" },
|
|
8713
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
8714
|
+
],
|
|
8715
|
+
run: async (c3, a2) => {
|
|
8716
|
+
const existing = unwrapData2(await c3.getNotification(a2.id));
|
|
8717
|
+
return c3.updateNotification(a2.id, { ...existing, ...readJsonInput2(a2.file) });
|
|
8718
|
+
}
|
|
8719
|
+
},
|
|
8609
8720
|
{
|
|
8610
8721
|
name: "delete",
|
|
8611
8722
|
description: "Delete a notification",
|
|
@@ -8636,6 +8747,24 @@ var init_sonarr3 = __esm(() => {
|
|
|
8636
8747
|
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
8637
8748
|
run: (c3, a2) => c3.getDownloadClient(a2.id)
|
|
8638
8749
|
},
|
|
8750
|
+
{
|
|
8751
|
+
name: "add",
|
|
8752
|
+
description: "Add a download client from JSON file or stdin",
|
|
8753
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
8754
|
+
run: async (c3, a2) => c3.addDownloadClient(readJsonInput2(a2.file))
|
|
8755
|
+
},
|
|
8756
|
+
{
|
|
8757
|
+
name: "edit",
|
|
8758
|
+
description: "Edit a download client (merges JSON with existing)",
|
|
8759
|
+
args: [
|
|
8760
|
+
{ name: "id", description: "Download client ID", required: true, type: "number" },
|
|
8761
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
8762
|
+
],
|
|
8763
|
+
run: async (c3, a2) => {
|
|
8764
|
+
const existing = unwrapData2(await c3.getDownloadClient(a2.id));
|
|
8765
|
+
return c3.updateDownloadClient(a2.id, { ...existing, ...readJsonInput2(a2.file) });
|
|
8766
|
+
}
|
|
8767
|
+
},
|
|
8639
8768
|
{
|
|
8640
8769
|
name: "delete",
|
|
8641
8770
|
description: "Delete a download client",
|
|
@@ -8703,6 +8832,24 @@ var init_sonarr3 = __esm(() => {
|
|
|
8703
8832
|
args: [{ name: "id", description: "Import list ID", required: true, type: "number" }],
|
|
8704
8833
|
run: (c3, a2) => c3.getImportList(a2.id)
|
|
8705
8834
|
},
|
|
8835
|
+
{
|
|
8836
|
+
name: "add",
|
|
8837
|
+
description: "Add an import list from JSON file or stdin",
|
|
8838
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
8839
|
+
run: async (c3, a2) => c3.addImportList(readJsonInput2(a2.file))
|
|
8840
|
+
},
|
|
8841
|
+
{
|
|
8842
|
+
name: "edit",
|
|
8843
|
+
description: "Edit an import list (merges JSON with existing)",
|
|
8844
|
+
args: [
|
|
8845
|
+
{ name: "id", description: "Import list ID", required: true, type: "number" },
|
|
8846
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
8847
|
+
],
|
|
8848
|
+
run: async (c3, a2) => {
|
|
8849
|
+
const existing = unwrapData2(await c3.getImportList(a2.id));
|
|
8850
|
+
return c3.updateImportList(a2.id, { ...existing, ...readJsonInput2(a2.file) });
|
|
8851
|
+
}
|
|
8852
|
+
},
|
|
8706
8853
|
{
|
|
8707
8854
|
name: "delete",
|
|
8708
8855
|
description: "Delete an import list",
|
|
@@ -9822,6 +9969,14 @@ var getApiV1Album = (options) => (options?.client ?? client3).get({
|
|
|
9822
9969
|
}],
|
|
9823
9970
|
url: "/api/v1/customformat/schema",
|
|
9824
9971
|
...options
|
|
9972
|
+
}), getApiV1WantedCutoff = (options) => (options?.client ?? client3).get({
|
|
9973
|
+
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
9974
|
+
in: "query",
|
|
9975
|
+
name: "apikey",
|
|
9976
|
+
type: "apiKey"
|
|
9977
|
+
}],
|
|
9978
|
+
url: "/api/v1/wanted/cutoff",
|
|
9979
|
+
...options
|
|
9825
9980
|
}), getApiV1Diskspace = (options) => (options?.client ?? client3).get({
|
|
9826
9981
|
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
9827
9982
|
in: "query",
|
|
@@ -10230,6 +10385,14 @@ var getApiV1Album = (options) => (options?.client ?? client3).get({
|
|
|
10230
10385
|
}],
|
|
10231
10386
|
url: "/api/v1/config/metadataprovider",
|
|
10232
10387
|
...options
|
|
10388
|
+
}), getApiV1WantedMissing = (options) => (options?.client ?? client3).get({
|
|
10389
|
+
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
10390
|
+
in: "query",
|
|
10391
|
+
name: "apikey",
|
|
10392
|
+
type: "apiKey"
|
|
10393
|
+
}],
|
|
10394
|
+
url: "/api/v1/wanted/missing",
|
|
10395
|
+
...options
|
|
10233
10396
|
}), getApiV1ConfigNamingById = (options) => (options.client ?? client3).get({
|
|
10234
10397
|
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
10235
10398
|
in: "query",
|
|
@@ -10698,6 +10861,7 @@ class LidarrClient {
|
|
|
10698
10861
|
query.end = end;
|
|
10699
10862
|
if (unmonitored !== undefined)
|
|
10700
10863
|
query.unmonitored = unmonitored;
|
|
10864
|
+
query.includeArtist = true;
|
|
10701
10865
|
return getApiV1Calendar(Object.keys(query).length > 0 ? { query } : {});
|
|
10702
10866
|
}
|
|
10703
10867
|
async getCalendarFeed(pastDays, futureDays, tags) {
|
|
@@ -11055,6 +11219,34 @@ class LidarrClient {
|
|
|
11055
11219
|
async removeBlocklistItemsBulk(ids) {
|
|
11056
11220
|
return deleteApiV1BlocklistBulk({ body: { ids } });
|
|
11057
11221
|
}
|
|
11222
|
+
async getWantedMissing(page, pageSize, sortKey, sortDirection, monitored) {
|
|
11223
|
+
const query = { includeArtist: true };
|
|
11224
|
+
if (page !== undefined)
|
|
11225
|
+
query.page = page;
|
|
11226
|
+
if (pageSize !== undefined)
|
|
11227
|
+
query.pageSize = pageSize;
|
|
11228
|
+
if (sortKey)
|
|
11229
|
+
query.sortKey = sortKey;
|
|
11230
|
+
if (sortDirection)
|
|
11231
|
+
query.sortDirection = sortDirection;
|
|
11232
|
+
if (monitored !== undefined)
|
|
11233
|
+
query.monitored = monitored;
|
|
11234
|
+
return getApiV1WantedMissing(Object.keys(query).length > 0 ? { query } : {});
|
|
11235
|
+
}
|
|
11236
|
+
async getWantedCutoff(page, pageSize, sortKey, sortDirection, monitored) {
|
|
11237
|
+
const query = { includeArtist: true };
|
|
11238
|
+
if (page !== undefined)
|
|
11239
|
+
query.page = page;
|
|
11240
|
+
if (pageSize !== undefined)
|
|
11241
|
+
query.pageSize = pageSize;
|
|
11242
|
+
if (sortKey)
|
|
11243
|
+
query.sortKey = sortKey;
|
|
11244
|
+
if (sortDirection)
|
|
11245
|
+
query.sortDirection = sortDirection;
|
|
11246
|
+
if (monitored !== undefined)
|
|
11247
|
+
query.monitored = monitored;
|
|
11248
|
+
return getApiV1WantedCutoff(Object.keys(query).length > 0 ? { query } : {});
|
|
11249
|
+
}
|
|
11058
11250
|
updateConfig(newConfig) {
|
|
11059
11251
|
const updatedConfig = { ...this.clientConfig.config, ...newConfig };
|
|
11060
11252
|
this.clientConfig = createServarrClient(updatedConfig);
|
|
@@ -11076,6 +11268,38 @@ var exports_lidarr3 = {};
|
|
|
11076
11268
|
__export(exports_lidarr3, {
|
|
11077
11269
|
lidarr: () => lidarr
|
|
11078
11270
|
});
|
|
11271
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
11272
|
+
function unwrapData3(result) {
|
|
11273
|
+
return result?.data ?? result;
|
|
11274
|
+
}
|
|
11275
|
+
function formatAlbumListItem(album) {
|
|
11276
|
+
return {
|
|
11277
|
+
...album,
|
|
11278
|
+
artistName: album?.artistName ?? album?.artist?.artistName ?? "—"
|
|
11279
|
+
};
|
|
11280
|
+
}
|
|
11281
|
+
function formatQueueListItem(item) {
|
|
11282
|
+
return {
|
|
11283
|
+
...item,
|
|
11284
|
+
artistName: item?.artistName ?? item?.artist?.artistName ?? "—"
|
|
11285
|
+
};
|
|
11286
|
+
}
|
|
11287
|
+
function formatHistoryListItem(item) {
|
|
11288
|
+
return {
|
|
11289
|
+
...item,
|
|
11290
|
+
artistName: item?.artistName ?? item?.artist?.artistName ?? "—"
|
|
11291
|
+
};
|
|
11292
|
+
}
|
|
11293
|
+
function formatBlocklistItem(item) {
|
|
11294
|
+
return {
|
|
11295
|
+
...item,
|
|
11296
|
+
artistName: item?.artistName ?? item?.artist?.artistName ?? "—"
|
|
11297
|
+
};
|
|
11298
|
+
}
|
|
11299
|
+
function readJsonInput3(filePath) {
|
|
11300
|
+
const raw = filePath === "-" ? readFileSync4(0, "utf-8") : readFileSync4(filePath, "utf-8");
|
|
11301
|
+
return JSON.parse(raw);
|
|
11302
|
+
}
|
|
11079
11303
|
var resources3, lidarr;
|
|
11080
11304
|
var init_lidarr3 = __esm(() => {
|
|
11081
11305
|
init_lidarr2();
|
|
@@ -11111,31 +11335,28 @@ var init_lidarr3 = __esm(() => {
|
|
|
11111
11335
|
description: "Search and add an artist",
|
|
11112
11336
|
args: [{ name: "term", description: "Search term", required: true }],
|
|
11113
11337
|
run: async (c3, a2) => {
|
|
11114
|
-
const
|
|
11115
|
-
const results = searchResult?.data ?? searchResult;
|
|
11338
|
+
const results = unwrapData3(await c3.searchArtists(a2.term));
|
|
11116
11339
|
if (!Array.isArray(results) || results.length === 0) {
|
|
11117
11340
|
throw new Error("No artists found.");
|
|
11118
11341
|
}
|
|
11119
|
-
const artistId = await promptSelect("Select an artist:", results.map((
|
|
11120
|
-
label:
|
|
11121
|
-
value: String(
|
|
11342
|
+
const artistId = await promptSelect("Select an artist:", results.map((artist2) => ({
|
|
11343
|
+
label: artist2.artistName,
|
|
11344
|
+
value: String(artist2.foreignArtistId)
|
|
11122
11345
|
})));
|
|
11123
|
-
const artist = results.find((
|
|
11346
|
+
const artist = results.find((item) => String(item.foreignArtistId) === artistId);
|
|
11124
11347
|
if (!artist) {
|
|
11125
11348
|
throw new Error("Selected artist was not found in the search results.");
|
|
11126
11349
|
}
|
|
11127
|
-
const
|
|
11128
|
-
const profiles = profilesResult?.data ?? profilesResult;
|
|
11350
|
+
const profiles = unwrapData3(await c3.getQualityProfiles());
|
|
11129
11351
|
if (!Array.isArray(profiles) || profiles.length === 0) {
|
|
11130
11352
|
throw new Error("No quality profiles found. Configure one in Lidarr first.");
|
|
11131
11353
|
}
|
|
11132
|
-
const profileId = await promptSelect("Select quality profile:", profiles.map((
|
|
11133
|
-
const
|
|
11134
|
-
const folders = foldersResult?.data ?? foldersResult;
|
|
11354
|
+
const profileId = await promptSelect("Select quality profile:", profiles.map((profile) => ({ label: profile.name, value: String(profile.id) })));
|
|
11355
|
+
const folders = unwrapData3(await c3.getRootFolders());
|
|
11135
11356
|
if (!Array.isArray(folders) || folders.length === 0) {
|
|
11136
11357
|
throw new Error("No root folders found. Configure one in Lidarr first.");
|
|
11137
11358
|
}
|
|
11138
|
-
const rootFolderPath = await promptSelect("Select root folder:", folders.map((
|
|
11359
|
+
const rootFolderPath = await promptSelect("Select root folder:", folders.map((folder) => ({ label: folder.path, value: folder.path })));
|
|
11139
11360
|
const confirmed = await promptConfirm(`Add "${artist.artistName}"?`, !!a2.yes);
|
|
11140
11361
|
if (!confirmed)
|
|
11141
11362
|
throw new Error("Cancelled.");
|
|
@@ -11158,15 +11379,16 @@ var init_lidarr3 = __esm(() => {
|
|
|
11158
11379
|
{ name: "tags", description: "Comma-separated tag IDs" }
|
|
11159
11380
|
],
|
|
11160
11381
|
run: async (c3, a2) => {
|
|
11161
|
-
const
|
|
11162
|
-
const artist = result?.data ?? result;
|
|
11382
|
+
const artist = unwrapData3(await c3.getArtist(a2.id));
|
|
11163
11383
|
const updates = { ...artist };
|
|
11164
11384
|
if (a2.monitored !== undefined)
|
|
11165
11385
|
updates.monitored = a2.monitored === "true";
|
|
11166
|
-
if (a2["quality-profile-id"] !== undefined)
|
|
11386
|
+
if (a2["quality-profile-id"] !== undefined) {
|
|
11167
11387
|
updates.qualityProfileId = Number(a2["quality-profile-id"]);
|
|
11168
|
-
|
|
11169
|
-
|
|
11388
|
+
}
|
|
11389
|
+
if (a2.tags !== undefined) {
|
|
11390
|
+
updates.tags = a2.tags.split(",").map((tag) => Number(tag.trim()));
|
|
11391
|
+
}
|
|
11170
11392
|
return c3.updateArtist(a2.id, updates);
|
|
11171
11393
|
}
|
|
11172
11394
|
},
|
|
@@ -11198,22 +11420,56 @@ var init_lidarr3 = __esm(() => {
|
|
|
11198
11420
|
{
|
|
11199
11421
|
name: "list",
|
|
11200
11422
|
description: "List all albums",
|
|
11201
|
-
columns: ["id", "
|
|
11202
|
-
run: (c3) =>
|
|
11423
|
+
columns: ["id", "artistName", "title", "monitored"],
|
|
11424
|
+
run: async (c3) => {
|
|
11425
|
+
const albums = unwrapData3(await c3.getAlbums());
|
|
11426
|
+
return albums.map(formatAlbumListItem);
|
|
11427
|
+
}
|
|
11203
11428
|
},
|
|
11204
11429
|
{
|
|
11205
11430
|
name: "get",
|
|
11206
11431
|
description: "Get an album by ID",
|
|
11207
11432
|
args: [{ name: "id", description: "Album ID", required: true, type: "number" }],
|
|
11208
|
-
run: (c3, a2) =>
|
|
11433
|
+
run: async (c3, a2) => {
|
|
11434
|
+
const album = unwrapData3(await c3.getAlbum(a2.id));
|
|
11435
|
+
return formatAlbumListItem(album);
|
|
11436
|
+
}
|
|
11209
11437
|
},
|
|
11210
11438
|
{
|
|
11211
11439
|
name: "search",
|
|
11212
11440
|
description: "Search for albums",
|
|
11213
11441
|
args: [{ name: "term", description: "Search term", required: true }],
|
|
11214
|
-
columns: ["foreignAlbumId", "title", "
|
|
11442
|
+
columns: ["foreignAlbumId", "artistName", "title", "monitored"],
|
|
11215
11443
|
idField: "foreignAlbumId",
|
|
11216
|
-
run: (c3, a2) =>
|
|
11444
|
+
run: async (c3, a2) => {
|
|
11445
|
+
const albums = unwrapData3(await c3.searchAlbums(a2.term));
|
|
11446
|
+
return albums.map(formatAlbumListItem);
|
|
11447
|
+
}
|
|
11448
|
+
},
|
|
11449
|
+
{
|
|
11450
|
+
name: "add",
|
|
11451
|
+
description: "Add an album from JSON file or stdin",
|
|
11452
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
11453
|
+
run: async (c3, a2) => c3.addAlbum(readJsonInput3(a2.file))
|
|
11454
|
+
},
|
|
11455
|
+
{
|
|
11456
|
+
name: "edit",
|
|
11457
|
+
description: "Edit an album (merges JSON with existing)",
|
|
11458
|
+
args: [
|
|
11459
|
+
{ name: "id", description: "Album ID", required: true, type: "number" },
|
|
11460
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
11461
|
+
],
|
|
11462
|
+
run: async (c3, a2) => {
|
|
11463
|
+
const existing = unwrapData3(await c3.getAlbum(a2.id));
|
|
11464
|
+
return c3.updateAlbum(a2.id, { ...existing, ...readJsonInput3(a2.file) });
|
|
11465
|
+
}
|
|
11466
|
+
},
|
|
11467
|
+
{
|
|
11468
|
+
name: "delete",
|
|
11469
|
+
description: "Delete an album",
|
|
11470
|
+
args: [{ name: "id", description: "Album ID", required: true, type: "number" }],
|
|
11471
|
+
confirmMessage: "Are you sure you want to delete this album?",
|
|
11472
|
+
run: (c3, a2) => c3.deleteAlbum(a2.id)
|
|
11217
11473
|
}
|
|
11218
11474
|
]
|
|
11219
11475
|
},
|
|
@@ -11226,6 +11482,12 @@ var init_lidarr3 = __esm(() => {
|
|
|
11226
11482
|
description: "List quality profiles",
|
|
11227
11483
|
columns: ["id", "name"],
|
|
11228
11484
|
run: (c3) => c3.getQualityProfiles()
|
|
11485
|
+
},
|
|
11486
|
+
{
|
|
11487
|
+
name: "get",
|
|
11488
|
+
description: "Get a quality profile by ID",
|
|
11489
|
+
args: [{ name: "id", description: "Profile ID", required: true, type: "number" }],
|
|
11490
|
+
run: (c3, a2) => c3.getQualityProfile(a2.id)
|
|
11229
11491
|
}
|
|
11230
11492
|
]
|
|
11231
11493
|
},
|
|
@@ -11248,7 +11510,7 @@ var init_lidarr3 = __esm(() => {
|
|
|
11248
11510
|
const tagResult = await c3.getTag(a2.id);
|
|
11249
11511
|
if (tagResult?.error)
|
|
11250
11512
|
return tagResult;
|
|
11251
|
-
const tag = tagResult
|
|
11513
|
+
const tag = unwrapData3(tagResult);
|
|
11252
11514
|
const deleteResult = await c3.deleteTag(a2.id);
|
|
11253
11515
|
if (deleteResult?.error)
|
|
11254
11516
|
return deleteResult;
|
|
@@ -11264,64 +11526,312 @@ var init_lidarr3 = __esm(() => {
|
|
|
11264
11526
|
]
|
|
11265
11527
|
},
|
|
11266
11528
|
{
|
|
11267
|
-
name: "
|
|
11268
|
-
description: "Manage
|
|
11529
|
+
name: "queue",
|
|
11530
|
+
description: "Manage download queue",
|
|
11269
11531
|
actions: [
|
|
11270
11532
|
{
|
|
11271
11533
|
name: "list",
|
|
11272
|
-
description: "List
|
|
11273
|
-
columns: ["id", "
|
|
11274
|
-
run: (c3) =>
|
|
11534
|
+
description: "List queue items",
|
|
11535
|
+
columns: ["id", "artistName", "title", "status", "sizeleft", "timeleft"],
|
|
11536
|
+
run: async (c3) => {
|
|
11537
|
+
const items = unwrapData3(await c3.getQueue());
|
|
11538
|
+
return items.map(formatQueueListItem);
|
|
11539
|
+
}
|
|
11275
11540
|
},
|
|
11276
11541
|
{
|
|
11277
|
-
name: "
|
|
11278
|
-
description: "
|
|
11279
|
-
|
|
11280
|
-
run: (c3, a2) => c3.addRootFolder(a2.path)
|
|
11542
|
+
name: "status",
|
|
11543
|
+
description: "Get queue status",
|
|
11544
|
+
run: (c3) => c3.getQueueStatus()
|
|
11281
11545
|
},
|
|
11282
11546
|
{
|
|
11283
11547
|
name: "delete",
|
|
11284
|
-
description: "
|
|
11285
|
-
args: [
|
|
11286
|
-
|
|
11287
|
-
|
|
11548
|
+
description: "Remove an item from the queue",
|
|
11549
|
+
args: [
|
|
11550
|
+
{ name: "id", description: "Queue item ID", required: true, type: "number" },
|
|
11551
|
+
{ name: "blocklist", description: "Add to blocklist", type: "boolean" },
|
|
11552
|
+
{
|
|
11553
|
+
name: "remove-from-client",
|
|
11554
|
+
description: "Remove from download client",
|
|
11555
|
+
type: "boolean"
|
|
11556
|
+
}
|
|
11557
|
+
],
|
|
11558
|
+
confirmMessage: "Are you sure you want to remove this queue item?",
|
|
11559
|
+
run: (c3, a2) => c3.removeQueueItem(a2.id, a2["remove-from-client"], a2.blocklist)
|
|
11560
|
+
},
|
|
11561
|
+
{
|
|
11562
|
+
name: "grab",
|
|
11563
|
+
description: "Force download a queue item",
|
|
11564
|
+
args: [{ name: "id", description: "Queue item ID", required: true, type: "number" }],
|
|
11565
|
+
run: (c3, a2) => c3.grabQueueItem(a2.id)
|
|
11288
11566
|
}
|
|
11289
11567
|
]
|
|
11290
11568
|
},
|
|
11291
11569
|
{
|
|
11292
|
-
name: "
|
|
11293
|
-
description: "
|
|
11570
|
+
name: "history",
|
|
11571
|
+
description: "View history",
|
|
11294
11572
|
actions: [
|
|
11295
11573
|
{
|
|
11296
|
-
name: "
|
|
11297
|
-
description: "
|
|
11298
|
-
|
|
11299
|
-
|
|
11574
|
+
name: "list",
|
|
11575
|
+
description: "List recent history",
|
|
11576
|
+
args: [
|
|
11577
|
+
{ name: "since", description: "Start date (ISO 8601, e.g. 2024-01-01)" },
|
|
11578
|
+
{ name: "until", description: "End date (ISO 8601, e.g. 2024-12-31)" }
|
|
11579
|
+
],
|
|
11580
|
+
columns: ["id", "artistName", "sourceTitle", "eventType", "date"],
|
|
11581
|
+
run: async (c3, a2) => {
|
|
11582
|
+
const items = a2.since ? unwrapData3(await c3.getHistorySince(a2.since)) : unwrapData3(await c3.getHistory());
|
|
11583
|
+
const filtered = a2.until ? items.filter((item) => new Date(item.date) <= new Date(a2.until)) : items;
|
|
11584
|
+
return filtered.map(formatHistoryListItem);
|
|
11585
|
+
}
|
|
11586
|
+
}
|
|
11587
|
+
]
|
|
11588
|
+
},
|
|
11589
|
+
{
|
|
11590
|
+
name: "calendar",
|
|
11591
|
+
description: "View upcoming releases",
|
|
11592
|
+
actions: [
|
|
11300
11593
|
{
|
|
11301
|
-
name: "
|
|
11302
|
-
description: "
|
|
11303
|
-
|
|
11304
|
-
|
|
11594
|
+
name: "list",
|
|
11595
|
+
description: "List upcoming album releases",
|
|
11596
|
+
args: [
|
|
11597
|
+
{ name: "start", description: "Start date (ISO 8601)" },
|
|
11598
|
+
{ name: "end", description: "End date (ISO 8601)" },
|
|
11599
|
+
{ name: "unmonitored", description: "Include unmonitored", type: "boolean" }
|
|
11600
|
+
],
|
|
11601
|
+
columns: ["id", "artistName", "title", "releaseDate"],
|
|
11602
|
+
run: async (c3, a2) => {
|
|
11603
|
+
const albums = unwrapData3(await c3.getCalendar(a2.start, a2.end, a2.unmonitored));
|
|
11604
|
+
return albums.map(formatAlbumListItem);
|
|
11605
|
+
}
|
|
11305
11606
|
}
|
|
11306
11607
|
]
|
|
11307
|
-
}
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11608
|
+
},
|
|
11609
|
+
{
|
|
11610
|
+
name: "notification",
|
|
11611
|
+
description: "Manage notifications",
|
|
11612
|
+
actions: [
|
|
11613
|
+
{
|
|
11614
|
+
name: "list",
|
|
11615
|
+
description: "List notification providers",
|
|
11616
|
+
columns: ["id", "name", "implementation"],
|
|
11617
|
+
run: (c3) => c3.getNotifications()
|
|
11618
|
+
},
|
|
11619
|
+
{
|
|
11620
|
+
name: "get",
|
|
11621
|
+
description: "Get a notification by ID",
|
|
11622
|
+
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
11623
|
+
run: (c3, a2) => c3.getNotification(a2.id)
|
|
11624
|
+
},
|
|
11625
|
+
{
|
|
11626
|
+
name: "add",
|
|
11627
|
+
description: "Add a notification from JSON file or stdin",
|
|
11628
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
11629
|
+
run: async (c3, a2) => c3.addNotification(readJsonInput3(a2.file))
|
|
11630
|
+
},
|
|
11631
|
+
{
|
|
11632
|
+
name: "edit",
|
|
11633
|
+
description: "Edit a notification (merges JSON with existing)",
|
|
11634
|
+
args: [
|
|
11635
|
+
{ name: "id", description: "Notification ID", required: true, type: "number" },
|
|
11636
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
11637
|
+
],
|
|
11638
|
+
run: async (c3, a2) => {
|
|
11639
|
+
const existing = unwrapData3(await c3.getNotification(a2.id));
|
|
11640
|
+
return c3.updateNotification(a2.id, { ...existing, ...readJsonInput3(a2.file) });
|
|
11641
|
+
}
|
|
11642
|
+
},
|
|
11643
|
+
{
|
|
11644
|
+
name: "delete",
|
|
11645
|
+
description: "Delete a notification",
|
|
11646
|
+
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
11647
|
+
confirmMessage: "Are you sure you want to delete this notification?",
|
|
11648
|
+
run: (c3, a2) => c3.deleteNotification(a2.id)
|
|
11649
|
+
},
|
|
11650
|
+
{
|
|
11651
|
+
name: "test",
|
|
11652
|
+
description: "Test all notifications",
|
|
11653
|
+
run: (c3) => c3.testAllNotifications()
|
|
11654
|
+
}
|
|
11655
|
+
]
|
|
11656
|
+
},
|
|
11657
|
+
{
|
|
11658
|
+
name: "downloadclient",
|
|
11659
|
+
description: "Manage download clients",
|
|
11660
|
+
actions: [
|
|
11661
|
+
{
|
|
11662
|
+
name: "list",
|
|
11663
|
+
description: "List download clients",
|
|
11664
|
+
columns: ["id", "name", "implementation", "enable"],
|
|
11665
|
+
run: (c3) => c3.getDownloadClients()
|
|
11666
|
+
},
|
|
11667
|
+
{
|
|
11668
|
+
name: "get",
|
|
11669
|
+
description: "Get a download client by ID",
|
|
11670
|
+
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
11671
|
+
run: (c3, a2) => c3.getDownloadClient(a2.id)
|
|
11672
|
+
},
|
|
11673
|
+
{
|
|
11674
|
+
name: "add",
|
|
11675
|
+
description: "Add a download client from JSON file or stdin",
|
|
11676
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
11677
|
+
run: async (c3, a2) => c3.addDownloadClient(readJsonInput3(a2.file))
|
|
11678
|
+
},
|
|
11679
|
+
{
|
|
11680
|
+
name: "edit",
|
|
11681
|
+
description: "Edit a download client (merges JSON with existing)",
|
|
11682
|
+
args: [
|
|
11683
|
+
{ name: "id", description: "Download client ID", required: true, type: "number" },
|
|
11684
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
11685
|
+
],
|
|
11686
|
+
run: async (c3, a2) => {
|
|
11687
|
+
const existing = unwrapData3(await c3.getDownloadClient(a2.id));
|
|
11688
|
+
return c3.updateDownloadClient(a2.id, { ...existing, ...readJsonInput3(a2.file) });
|
|
11689
|
+
}
|
|
11690
|
+
},
|
|
11691
|
+
{
|
|
11692
|
+
name: "delete",
|
|
11693
|
+
description: "Delete a download client",
|
|
11694
|
+
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
11695
|
+
confirmMessage: "Are you sure you want to delete this download client?",
|
|
11696
|
+
run: (c3, a2) => c3.deleteDownloadClient(a2.id)
|
|
11697
|
+
},
|
|
11698
|
+
{
|
|
11699
|
+
name: "test",
|
|
11700
|
+
description: "Test all download clients",
|
|
11701
|
+
run: (c3) => c3.testAllDownloadClients()
|
|
11702
|
+
}
|
|
11703
|
+
]
|
|
11704
|
+
},
|
|
11705
|
+
{
|
|
11706
|
+
name: "blocklist",
|
|
11707
|
+
description: "View blocked releases",
|
|
11708
|
+
actions: [
|
|
11709
|
+
{
|
|
11710
|
+
name: "list",
|
|
11711
|
+
description: "List blocked releases",
|
|
11712
|
+
columns: ["id", "artistName", "sourceTitle", "date"],
|
|
11713
|
+
run: async (c3) => {
|
|
11714
|
+
const items = unwrapData3(await c3.getBlocklist());
|
|
11715
|
+
return items.map(formatBlocklistItem);
|
|
11716
|
+
}
|
|
11717
|
+
},
|
|
11718
|
+
{
|
|
11719
|
+
name: "delete",
|
|
11720
|
+
description: "Remove a release from the blocklist",
|
|
11721
|
+
args: [{ name: "id", description: "Blocklist item ID", required: true, type: "number" }],
|
|
11722
|
+
confirmMessage: "Are you sure you want to remove this blocklist entry?",
|
|
11723
|
+
run: (c3, a2) => c3.removeBlocklistItem(a2.id)
|
|
11724
|
+
}
|
|
11725
|
+
]
|
|
11726
|
+
},
|
|
11727
|
+
{
|
|
11728
|
+
name: "wanted",
|
|
11729
|
+
description: "View missing and cutoff unmet albums",
|
|
11730
|
+
actions: [
|
|
11731
|
+
{
|
|
11732
|
+
name: "missing",
|
|
11733
|
+
description: "List albums with missing tracks",
|
|
11734
|
+
columns: ["id", "artistName", "title", "releaseDate"],
|
|
11735
|
+
run: async (c3) => {
|
|
11736
|
+
const albums = unwrapData3(await c3.getWantedMissing());
|
|
11737
|
+
return albums.map(formatAlbumListItem);
|
|
11738
|
+
}
|
|
11739
|
+
},
|
|
11740
|
+
{
|
|
11741
|
+
name: "cutoff",
|
|
11742
|
+
description: "List albums below quality cutoff",
|
|
11743
|
+
columns: ["id", "artistName", "title", "releaseDate"],
|
|
11744
|
+
run: async (c3) => {
|
|
11745
|
+
const albums = unwrapData3(await c3.getWantedCutoff());
|
|
11746
|
+
return albums.map(formatAlbumListItem);
|
|
11747
|
+
}
|
|
11748
|
+
}
|
|
11749
|
+
]
|
|
11750
|
+
},
|
|
11751
|
+
{
|
|
11752
|
+
name: "importlist",
|
|
11753
|
+
description: "Manage import lists",
|
|
11754
|
+
actions: [
|
|
11755
|
+
{
|
|
11756
|
+
name: "list",
|
|
11757
|
+
description: "List import lists",
|
|
11758
|
+
columns: ["id", "name", "implementation", "enable"],
|
|
11759
|
+
run: (c3) => c3.getImportLists()
|
|
11760
|
+
},
|
|
11761
|
+
{
|
|
11762
|
+
name: "get",
|
|
11763
|
+
description: "Get an import list by ID",
|
|
11764
|
+
args: [{ name: "id", description: "Import list ID", required: true, type: "number" }],
|
|
11765
|
+
run: (c3, a2) => c3.getImportList(a2.id)
|
|
11766
|
+
},
|
|
11767
|
+
{
|
|
11768
|
+
name: "delete",
|
|
11769
|
+
description: "Delete an import list",
|
|
11770
|
+
args: [{ name: "id", description: "Import list ID", required: true, type: "number" }],
|
|
11771
|
+
confirmMessage: "Are you sure you want to delete this import list?",
|
|
11772
|
+
run: (c3, a2) => c3.deleteImportList(a2.id)
|
|
11773
|
+
}
|
|
11774
|
+
]
|
|
11775
|
+
},
|
|
11776
|
+
{
|
|
11777
|
+
name: "rootfolder",
|
|
11778
|
+
description: "Manage root folders",
|
|
11779
|
+
actions: [
|
|
11780
|
+
{
|
|
11781
|
+
name: "list",
|
|
11782
|
+
description: "List root folders",
|
|
11783
|
+
columns: ["id", "path", "freeSpace"],
|
|
11784
|
+
run: (c3) => c3.getRootFolders()
|
|
11785
|
+
},
|
|
11786
|
+
{
|
|
11787
|
+
name: "add",
|
|
11788
|
+
description: "Add a root folder",
|
|
11789
|
+
args: [{ name: "path", description: "Folder path", required: true }],
|
|
11790
|
+
run: (c3, a2) => c3.addRootFolder(a2.path)
|
|
11791
|
+
},
|
|
11792
|
+
{
|
|
11793
|
+
name: "delete",
|
|
11794
|
+
description: "Delete a root folder",
|
|
11795
|
+
args: [{ name: "id", description: "Root folder ID", required: true, type: "number" }],
|
|
11796
|
+
confirmMessage: "Are you sure you want to delete this root folder?",
|
|
11797
|
+
run: (c3, a2) => c3.deleteRootFolder(a2.id)
|
|
11798
|
+
}
|
|
11799
|
+
]
|
|
11800
|
+
},
|
|
11801
|
+
{
|
|
11802
|
+
name: "system",
|
|
11803
|
+
description: "System information",
|
|
11804
|
+
actions: [
|
|
11805
|
+
{
|
|
11806
|
+
name: "status",
|
|
11807
|
+
description: "Get system status",
|
|
11808
|
+
run: (c3) => c3.getSystemStatus()
|
|
11809
|
+
},
|
|
11810
|
+
{
|
|
11811
|
+
name: "health",
|
|
11812
|
+
description: "Get health check results",
|
|
11813
|
+
columns: ["type", "message", "source"],
|
|
11814
|
+
run: (c3) => c3.getHealth()
|
|
11815
|
+
}
|
|
11816
|
+
]
|
|
11817
|
+
}
|
|
11818
|
+
];
|
|
11819
|
+
lidarr = buildServiceCommand("lidarr", "Manage Lidarr (Music)", (config) => new LidarrClient(config), resources3);
|
|
11820
|
+
});
|
|
11821
|
+
|
|
11822
|
+
// src/generated/readarr/core/bodySerializer.gen.ts
|
|
11823
|
+
var jsonBodySerializer4;
|
|
11824
|
+
var init_bodySerializer_gen4 = __esm(() => {
|
|
11825
|
+
jsonBodySerializer4 = {
|
|
11826
|
+
bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value)
|
|
11827
|
+
};
|
|
11828
|
+
});
|
|
11829
|
+
|
|
11830
|
+
// src/generated/readarr/core/serverSentEvents.gen.ts
|
|
11831
|
+
var createSseClient4 = ({
|
|
11832
|
+
onRequest,
|
|
11833
|
+
onSseError,
|
|
11834
|
+
onSseEvent,
|
|
11325
11835
|
responseTransformer,
|
|
11326
11836
|
responseValidator,
|
|
11327
11837
|
sseDefaultRetryDelay,
|
|
@@ -12282,6 +12792,22 @@ var getApiV1Author = (options) => (options?.client ?? client4).get({
|
|
|
12282
12792
|
}],
|
|
12283
12793
|
url: "/api/v1/book/lookup",
|
|
12284
12794
|
...options
|
|
12795
|
+
}), getApiV1Calendar2 = (options) => (options?.client ?? client4).get({
|
|
12796
|
+
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
12797
|
+
in: "query",
|
|
12798
|
+
name: "apikey",
|
|
12799
|
+
type: "apiKey"
|
|
12800
|
+
}],
|
|
12801
|
+
url: "/api/v1/calendar",
|
|
12802
|
+
...options
|
|
12803
|
+
}), getFeedV1CalendarReadarrIcs = (options) => (options?.client ?? client4).get({
|
|
12804
|
+
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
12805
|
+
in: "query",
|
|
12806
|
+
name: "apikey",
|
|
12807
|
+
type: "apiKey"
|
|
12808
|
+
}],
|
|
12809
|
+
url: "/feed/v1/calendar/readarr.ics",
|
|
12810
|
+
...options
|
|
12285
12811
|
}), getApiV1Command2 = (options) => (options?.client ?? client4).get({
|
|
12286
12812
|
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
12287
12813
|
in: "query",
|
|
@@ -12358,6 +12884,14 @@ var getApiV1Author = (options) => (options?.client ?? client4).get({
|
|
|
12358
12884
|
}],
|
|
12359
12885
|
url: "/api/v1/customformat/schema",
|
|
12360
12886
|
...options
|
|
12887
|
+
}), getApiV1WantedCutoff2 = (options) => (options?.client ?? client4).get({
|
|
12888
|
+
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
12889
|
+
in: "query",
|
|
12890
|
+
name: "apikey",
|
|
12891
|
+
type: "apiKey"
|
|
12892
|
+
}],
|
|
12893
|
+
url: "/api/v1/wanted/cutoff",
|
|
12894
|
+
...options
|
|
12361
12895
|
}), getApiV1ConfigDevelopment = (options) => (options?.client ?? client4).get({
|
|
12362
12896
|
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
12363
12897
|
in: "query",
|
|
@@ -12770,6 +13304,14 @@ var getApiV1Author = (options) => (options?.client ?? client4).get({
|
|
|
12770
13304
|
"Content-Type": "application/json",
|
|
12771
13305
|
...options.headers
|
|
12772
13306
|
}
|
|
13307
|
+
}), getApiV1WantedMissing2 = (options) => (options?.client ?? client4).get({
|
|
13308
|
+
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
13309
|
+
in: "query",
|
|
13310
|
+
name: "apikey",
|
|
13311
|
+
type: "apiKey"
|
|
13312
|
+
}],
|
|
13313
|
+
url: "/api/v1/wanted/missing",
|
|
13314
|
+
...options
|
|
12773
13315
|
}), getApiV1ConfigNaming2 = (options) => (options?.client ?? client4).get({
|
|
12774
13316
|
security: [{ name: "X-Api-Key", type: "apiKey" }, {
|
|
12775
13317
|
in: "query",
|
|
@@ -13341,6 +13883,26 @@ class ReadarrClient {
|
|
|
13341
13883
|
async searchBooks(term) {
|
|
13342
13884
|
return getApiV1BookLookup({ query: { term } });
|
|
13343
13885
|
}
|
|
13886
|
+
async getCalendar(start, end, unmonitored) {
|
|
13887
|
+
const query = { includeAuthor: true };
|
|
13888
|
+
if (start)
|
|
13889
|
+
query.start = start;
|
|
13890
|
+
if (end)
|
|
13891
|
+
query.end = end;
|
|
13892
|
+
if (unmonitored !== undefined)
|
|
13893
|
+
query.unmonitored = unmonitored;
|
|
13894
|
+
return getApiV1Calendar2(Object.keys(query).length > 0 ? { query } : {});
|
|
13895
|
+
}
|
|
13896
|
+
async getCalendarFeed(pastDays, futureDays, tagList) {
|
|
13897
|
+
const query = {};
|
|
13898
|
+
if (pastDays !== undefined)
|
|
13899
|
+
query.pastDays = pastDays;
|
|
13900
|
+
if (futureDays !== undefined)
|
|
13901
|
+
query.futureDays = futureDays;
|
|
13902
|
+
if (tagList)
|
|
13903
|
+
query.tagList = tagList;
|
|
13904
|
+
return getFeedV1CalendarReadarrIcs(Object.keys(query).length > 0 ? { query } : {});
|
|
13905
|
+
}
|
|
13344
13906
|
async getQualityProfiles() {
|
|
13345
13907
|
return getApiV1Qualityprofile2();
|
|
13346
13908
|
}
|
|
@@ -13577,6 +14139,34 @@ class ReadarrClient {
|
|
|
13577
14139
|
async removeBlocklistItemsBulk(ids) {
|
|
13578
14140
|
return deleteApiV1BlocklistBulk2({ body: { ids } });
|
|
13579
14141
|
}
|
|
14142
|
+
async getWantedMissing(page, pageSize, sortKey, sortDirection, monitored) {
|
|
14143
|
+
const query = { includeAuthor: true };
|
|
14144
|
+
if (page !== undefined)
|
|
14145
|
+
query.page = page;
|
|
14146
|
+
if (pageSize !== undefined)
|
|
14147
|
+
query.pageSize = pageSize;
|
|
14148
|
+
if (sortKey)
|
|
14149
|
+
query.sortKey = sortKey;
|
|
14150
|
+
if (sortDirection)
|
|
14151
|
+
query.sortDirection = sortDirection;
|
|
14152
|
+
if (monitored !== undefined)
|
|
14153
|
+
query.monitored = monitored;
|
|
14154
|
+
return getApiV1WantedMissing2(Object.keys(query).length > 0 ? { query } : {});
|
|
14155
|
+
}
|
|
14156
|
+
async getWantedCutoff(page, pageSize, sortKey, sortDirection, monitored) {
|
|
14157
|
+
const query = { includeAuthor: true };
|
|
14158
|
+
if (page !== undefined)
|
|
14159
|
+
query.page = page;
|
|
14160
|
+
if (pageSize !== undefined)
|
|
14161
|
+
query.pageSize = pageSize;
|
|
14162
|
+
if (sortKey)
|
|
14163
|
+
query.sortKey = sortKey;
|
|
14164
|
+
if (sortDirection)
|
|
14165
|
+
query.sortDirection = sortDirection;
|
|
14166
|
+
if (monitored !== undefined)
|
|
14167
|
+
query.monitored = monitored;
|
|
14168
|
+
return getApiV1WantedCutoff2(Object.keys(query).length > 0 ? { query } : {});
|
|
14169
|
+
}
|
|
13580
14170
|
updateConfig(newConfig) {
|
|
13581
14171
|
const updatedConfig = { ...this.clientConfig.config, ...newConfig };
|
|
13582
14172
|
this.clientConfig = createServarrClient(updatedConfig);
|
|
@@ -13598,7 +14188,39 @@ var exports_readarr3 = {};
|
|
|
13598
14188
|
__export(exports_readarr3, {
|
|
13599
14189
|
readarr: () => readarr
|
|
13600
14190
|
});
|
|
13601
|
-
|
|
14191
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
14192
|
+
function unwrapData4(result) {
|
|
14193
|
+
return result?.data ?? result;
|
|
14194
|
+
}
|
|
14195
|
+
function formatBookListItem(book) {
|
|
14196
|
+
return {
|
|
14197
|
+
...book,
|
|
14198
|
+
authorName: book?.authorName ?? book?.authorTitle ?? book?.author?.authorName ?? "—"
|
|
14199
|
+
};
|
|
14200
|
+
}
|
|
14201
|
+
function formatQueueListItem2(item) {
|
|
14202
|
+
return {
|
|
14203
|
+
...item,
|
|
14204
|
+
authorName: item?.authorName ?? item?.authorTitle ?? item?.author?.authorName ?? "—"
|
|
14205
|
+
};
|
|
14206
|
+
}
|
|
14207
|
+
function formatHistoryListItem2(item) {
|
|
14208
|
+
return {
|
|
14209
|
+
...item,
|
|
14210
|
+
authorName: item?.authorName ?? item?.authorTitle ?? item?.author?.authorName ?? "—"
|
|
14211
|
+
};
|
|
14212
|
+
}
|
|
14213
|
+
function formatBlocklistItem2(item) {
|
|
14214
|
+
return {
|
|
14215
|
+
...item,
|
|
14216
|
+
authorName: item?.authorName ?? item?.authorTitle ?? item?.author?.authorName ?? "—"
|
|
14217
|
+
};
|
|
14218
|
+
}
|
|
14219
|
+
function readJsonInput4(filePath) {
|
|
14220
|
+
const raw = filePath === "-" ? readFileSync5(0, "utf-8") : readFileSync5(filePath, "utf-8");
|
|
14221
|
+
return JSON.parse(raw);
|
|
14222
|
+
}
|
|
14223
|
+
var resources4, readarr;
|
|
13602
14224
|
var init_readarr3 = __esm(() => {
|
|
13603
14225
|
init_readarr2();
|
|
13604
14226
|
init_prompt2();
|
|
@@ -13615,168 +14237,459 @@ var init_readarr3 = __esm(() => {
|
|
|
13615
14237
|
run: (c3) => c3.getAuthors()
|
|
13616
14238
|
},
|
|
13617
14239
|
{
|
|
13618
|
-
name: "get",
|
|
13619
|
-
description: "Get an author by ID",
|
|
13620
|
-
args: [{ name: "id", description: "Author ID", required: true, type: "number" }],
|
|
13621
|
-
run: (c3, a2) => c3.getAuthor(a2.id)
|
|
14240
|
+
name: "get",
|
|
14241
|
+
description: "Get an author by ID",
|
|
14242
|
+
args: [{ name: "id", description: "Author ID", required: true, type: "number" }],
|
|
14243
|
+
run: (c3, a2) => c3.getAuthor(a2.id)
|
|
14244
|
+
},
|
|
14245
|
+
{
|
|
14246
|
+
name: "search",
|
|
14247
|
+
description: "Search for authors",
|
|
14248
|
+
args: [{ name: "term", description: "Search term", required: true }],
|
|
14249
|
+
columns: ["foreignAuthorId", "authorName", "overview"],
|
|
14250
|
+
idField: "foreignAuthorId",
|
|
14251
|
+
run: (c3, a2) => c3.searchAuthors(a2.term)
|
|
14252
|
+
},
|
|
14253
|
+
{
|
|
14254
|
+
name: "add",
|
|
14255
|
+
description: "Search and add an author",
|
|
14256
|
+
args: [{ name: "term", description: "Search term", required: true }],
|
|
14257
|
+
run: async (c3, a2) => {
|
|
14258
|
+
const results = unwrapData4(await c3.searchAuthors(a2.term));
|
|
14259
|
+
if (!Array.isArray(results) || results.length === 0) {
|
|
14260
|
+
throw new Error("No authors found.");
|
|
14261
|
+
}
|
|
14262
|
+
const authorId = await promptSelect("Select an author:", results.map((author2) => ({
|
|
14263
|
+
label: author2.authorName,
|
|
14264
|
+
value: String(author2.foreignAuthorId)
|
|
14265
|
+
})));
|
|
14266
|
+
const author = results.find((item) => String(item.foreignAuthorId) === authorId);
|
|
14267
|
+
if (!author) {
|
|
14268
|
+
throw new Error("Selected author was not found in the search results.");
|
|
14269
|
+
}
|
|
14270
|
+
const profiles = unwrapData4(await c3.getQualityProfiles());
|
|
14271
|
+
if (!Array.isArray(profiles) || profiles.length === 0) {
|
|
14272
|
+
throw new Error("No quality profiles found. Configure one in Readarr first.");
|
|
14273
|
+
}
|
|
14274
|
+
const profileId = await promptSelect("Select quality profile:", profiles.map((profile) => ({ label: profile.name, value: String(profile.id) })));
|
|
14275
|
+
const folders = unwrapData4(await c3.getRootFolders());
|
|
14276
|
+
if (!Array.isArray(folders) || folders.length === 0) {
|
|
14277
|
+
throw new Error("No root folders found. Configure one in Readarr first.");
|
|
14278
|
+
}
|
|
14279
|
+
const rootFolderPath = await promptSelect("Select root folder:", folders.map((folder) => ({ label: folder.path, value: folder.path })));
|
|
14280
|
+
const confirmed = await promptConfirm(`Add "${author.authorName}"?`, !!a2.yes);
|
|
14281
|
+
if (!confirmed)
|
|
14282
|
+
throw new Error("Cancelled.");
|
|
14283
|
+
return c3.addAuthor({
|
|
14284
|
+
...author,
|
|
14285
|
+
qualityProfileId: Number(profileId),
|
|
14286
|
+
rootFolderPath,
|
|
14287
|
+
monitored: true,
|
|
14288
|
+
addOptions: { searchForMissingBooks: true }
|
|
14289
|
+
});
|
|
14290
|
+
}
|
|
14291
|
+
},
|
|
14292
|
+
{
|
|
14293
|
+
name: "edit",
|
|
14294
|
+
description: "Edit an author",
|
|
14295
|
+
args: [
|
|
14296
|
+
{ name: "id", description: "Author ID", required: true, type: "number" },
|
|
14297
|
+
{ name: "monitored", description: "Set monitored (true/false)" },
|
|
14298
|
+
{ name: "quality-profile-id", description: "Quality profile ID", type: "number" },
|
|
14299
|
+
{ name: "tags", description: "Comma-separated tag IDs" }
|
|
14300
|
+
],
|
|
14301
|
+
run: async (c3, a2) => {
|
|
14302
|
+
const author = unwrapData4(await c3.getAuthor(a2.id));
|
|
14303
|
+
const updates = { ...author };
|
|
14304
|
+
if (a2.monitored !== undefined)
|
|
14305
|
+
updates.monitored = a2.monitored === "true";
|
|
14306
|
+
if (a2["quality-profile-id"] !== undefined) {
|
|
14307
|
+
updates.qualityProfileId = Number(a2["quality-profile-id"]);
|
|
14308
|
+
}
|
|
14309
|
+
if (a2.tags !== undefined) {
|
|
14310
|
+
updates.tags = a2.tags.split(",").map((tag) => Number(tag.trim()));
|
|
14311
|
+
}
|
|
14312
|
+
return c3.updateAuthor(a2.id, updates);
|
|
14313
|
+
}
|
|
14314
|
+
},
|
|
14315
|
+
{
|
|
14316
|
+
name: "refresh",
|
|
14317
|
+
description: "Refresh author metadata",
|
|
14318
|
+
args: [{ name: "id", description: "Author ID", required: true, type: "number" }],
|
|
14319
|
+
run: (c3, a2) => c3.runCommand({ name: "RefreshAuthor", authorId: a2.id })
|
|
14320
|
+
},
|
|
14321
|
+
{
|
|
14322
|
+
name: "manual-search",
|
|
14323
|
+
description: "Trigger a manual search for releases",
|
|
14324
|
+
args: [{ name: "id", description: "Author ID", required: true, type: "number" }],
|
|
14325
|
+
run: (c3, a2) => c3.runCommand({ name: "AuthorSearch", authorId: a2.id })
|
|
14326
|
+
},
|
|
14327
|
+
{
|
|
14328
|
+
name: "delete",
|
|
14329
|
+
description: "Delete an author",
|
|
14330
|
+
args: [{ name: "id", description: "Author ID", required: true, type: "number" }],
|
|
14331
|
+
confirmMessage: "Are you sure you want to delete this author?",
|
|
14332
|
+
run: (c3, a2) => c3.deleteAuthor(a2.id)
|
|
14333
|
+
}
|
|
14334
|
+
]
|
|
14335
|
+
},
|
|
14336
|
+
{
|
|
14337
|
+
name: "book",
|
|
14338
|
+
description: "Manage books",
|
|
14339
|
+
actions: [
|
|
14340
|
+
{
|
|
14341
|
+
name: "list",
|
|
14342
|
+
description: "List all books",
|
|
14343
|
+
columns: ["id", "authorName", "title", "monitored"],
|
|
14344
|
+
run: async (c3) => {
|
|
14345
|
+
const books = unwrapData4(await c3.getBooks());
|
|
14346
|
+
return books.map(formatBookListItem);
|
|
14347
|
+
}
|
|
14348
|
+
},
|
|
14349
|
+
{
|
|
14350
|
+
name: "get",
|
|
14351
|
+
description: "Get a book by ID",
|
|
14352
|
+
args: [{ name: "id", description: "Book ID", required: true, type: "number" }],
|
|
14353
|
+
run: async (c3, a2) => {
|
|
14354
|
+
const book = unwrapData4(await c3.getBook(a2.id));
|
|
14355
|
+
return formatBookListItem(book);
|
|
14356
|
+
}
|
|
14357
|
+
},
|
|
14358
|
+
{
|
|
14359
|
+
name: "search",
|
|
14360
|
+
description: "Search for books",
|
|
14361
|
+
args: [{ name: "term", description: "Search term", required: true }],
|
|
14362
|
+
columns: ["foreignBookId", "authorName", "title", "monitored"],
|
|
14363
|
+
idField: "foreignBookId",
|
|
14364
|
+
run: async (c3, a2) => {
|
|
14365
|
+
const books = unwrapData4(await c3.searchBooks(a2.term));
|
|
14366
|
+
return books.map(formatBookListItem);
|
|
14367
|
+
}
|
|
14368
|
+
},
|
|
14369
|
+
{
|
|
14370
|
+
name: "add",
|
|
14371
|
+
description: "Add a book from JSON file or stdin",
|
|
14372
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
14373
|
+
run: async (c3, a2) => c3.addBook(readJsonInput4(a2.file))
|
|
14374
|
+
},
|
|
14375
|
+
{
|
|
14376
|
+
name: "edit",
|
|
14377
|
+
description: "Edit a book (merges JSON with existing)",
|
|
14378
|
+
args: [
|
|
14379
|
+
{ name: "id", description: "Book ID", required: true, type: "number" },
|
|
14380
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
14381
|
+
],
|
|
14382
|
+
run: async (c3, a2) => {
|
|
14383
|
+
const existing = unwrapData4(await c3.getBook(a2.id));
|
|
14384
|
+
return c3.updateBook(a2.id, { ...existing, ...readJsonInput4(a2.file) });
|
|
14385
|
+
}
|
|
14386
|
+
},
|
|
14387
|
+
{
|
|
14388
|
+
name: "delete",
|
|
14389
|
+
description: "Delete a book",
|
|
14390
|
+
args: [{ name: "id", description: "Book ID", required: true, type: "number" }],
|
|
14391
|
+
confirmMessage: "Are you sure you want to delete this book?",
|
|
14392
|
+
run: (c3, a2) => c3.deleteBook(a2.id)
|
|
14393
|
+
}
|
|
14394
|
+
]
|
|
14395
|
+
},
|
|
14396
|
+
{
|
|
14397
|
+
name: "profile",
|
|
14398
|
+
description: "Manage quality profiles",
|
|
14399
|
+
actions: [
|
|
14400
|
+
{
|
|
14401
|
+
name: "list",
|
|
14402
|
+
description: "List quality profiles",
|
|
14403
|
+
columns: ["id", "name"],
|
|
14404
|
+
run: (c3) => c3.getQualityProfiles()
|
|
14405
|
+
},
|
|
14406
|
+
{
|
|
14407
|
+
name: "get",
|
|
14408
|
+
description: "Get a quality profile by ID",
|
|
14409
|
+
args: [{ name: "id", description: "Profile ID", required: true, type: "number" }],
|
|
14410
|
+
run: (c3, a2) => c3.getQualityProfile(a2.id)
|
|
14411
|
+
}
|
|
14412
|
+
]
|
|
14413
|
+
},
|
|
14414
|
+
{
|
|
14415
|
+
name: "tag",
|
|
14416
|
+
description: "Manage tags",
|
|
14417
|
+
actions: [
|
|
14418
|
+
{
|
|
14419
|
+
name: "create",
|
|
14420
|
+
description: "Create a tag",
|
|
14421
|
+
args: [{ name: "label", description: "Tag label", required: true }],
|
|
14422
|
+
run: (c3, a2) => c3.addTag({ label: a2.label })
|
|
14423
|
+
},
|
|
14424
|
+
{
|
|
14425
|
+
name: "delete",
|
|
14426
|
+
description: "Delete a tag",
|
|
14427
|
+
args: [{ name: "id", description: "Tag ID", required: true, type: "number" }],
|
|
14428
|
+
confirmMessage: "Are you sure you want to delete this tag?",
|
|
14429
|
+
run: async (c3, a2) => {
|
|
14430
|
+
const tagResult = await c3.getTag(a2.id);
|
|
14431
|
+
if (tagResult?.error)
|
|
14432
|
+
return tagResult;
|
|
14433
|
+
const tag = unwrapData4(tagResult);
|
|
14434
|
+
const deleteResult = await c3.deleteTag(a2.id);
|
|
14435
|
+
if (deleteResult?.error)
|
|
14436
|
+
return deleteResult;
|
|
14437
|
+
return { message: `Deleted tag: ${tag.label} (ID: ${tag.id})` };
|
|
14438
|
+
}
|
|
14439
|
+
},
|
|
14440
|
+
{
|
|
14441
|
+
name: "list",
|
|
14442
|
+
description: "List all tags",
|
|
14443
|
+
columns: ["id", "label"],
|
|
14444
|
+
run: (c3) => c3.getTags()
|
|
14445
|
+
}
|
|
14446
|
+
]
|
|
14447
|
+
},
|
|
14448
|
+
{
|
|
14449
|
+
name: "queue",
|
|
14450
|
+
description: "Manage download queue",
|
|
14451
|
+
actions: [
|
|
14452
|
+
{
|
|
14453
|
+
name: "list",
|
|
14454
|
+
description: "List queue items",
|
|
14455
|
+
columns: ["id", "authorName", "title", "status", "sizeleft", "timeleft"],
|
|
14456
|
+
run: async (c3) => {
|
|
14457
|
+
const items = unwrapData4(await c3.getQueue());
|
|
14458
|
+
return items.map(formatQueueListItem2);
|
|
14459
|
+
}
|
|
14460
|
+
},
|
|
14461
|
+
{
|
|
14462
|
+
name: "status",
|
|
14463
|
+
description: "Get queue status",
|
|
14464
|
+
run: (c3) => c3.getQueueStatus()
|
|
14465
|
+
},
|
|
14466
|
+
{
|
|
14467
|
+
name: "delete",
|
|
14468
|
+
description: "Remove an item from the queue",
|
|
14469
|
+
args: [
|
|
14470
|
+
{ name: "id", description: "Queue item ID", required: true, type: "number" },
|
|
14471
|
+
{ name: "blocklist", description: "Add to blocklist", type: "boolean" },
|
|
14472
|
+
{
|
|
14473
|
+
name: "remove-from-client",
|
|
14474
|
+
description: "Remove from download client",
|
|
14475
|
+
type: "boolean"
|
|
14476
|
+
}
|
|
14477
|
+
],
|
|
14478
|
+
confirmMessage: "Are you sure you want to remove this queue item?",
|
|
14479
|
+
run: (c3, a2) => c3.removeQueueItem(a2.id, a2["remove-from-client"], a2.blocklist)
|
|
14480
|
+
},
|
|
14481
|
+
{
|
|
14482
|
+
name: "grab",
|
|
14483
|
+
description: "Force download a queue item",
|
|
14484
|
+
args: [{ name: "id", description: "Queue item ID", required: true, type: "number" }],
|
|
14485
|
+
run: (c3, a2) => c3.grabQueueItem(a2.id)
|
|
14486
|
+
}
|
|
14487
|
+
]
|
|
14488
|
+
},
|
|
14489
|
+
{
|
|
14490
|
+
name: "history",
|
|
14491
|
+
description: "View history",
|
|
14492
|
+
actions: [
|
|
14493
|
+
{
|
|
14494
|
+
name: "list",
|
|
14495
|
+
description: "List recent history",
|
|
14496
|
+
args: [
|
|
14497
|
+
{ name: "since", description: "Start date (ISO 8601, e.g. 2024-01-01)" },
|
|
14498
|
+
{ name: "until", description: "End date (ISO 8601, e.g. 2024-12-31)" }
|
|
14499
|
+
],
|
|
14500
|
+
columns: ["id", "authorName", "sourceTitle", "eventType", "date"],
|
|
14501
|
+
run: async (c3, a2) => {
|
|
14502
|
+
const items = a2.since ? unwrapData4(await c3.getHistorySince(a2.since)) : unwrapData4(await c3.getHistory());
|
|
14503
|
+
const filtered = a2.until ? items.filter((item) => new Date(item.date) <= new Date(a2.until)) : items;
|
|
14504
|
+
return filtered.map(formatHistoryListItem2);
|
|
14505
|
+
}
|
|
14506
|
+
}
|
|
14507
|
+
]
|
|
14508
|
+
},
|
|
14509
|
+
{
|
|
14510
|
+
name: "calendar",
|
|
14511
|
+
description: "View upcoming releases",
|
|
14512
|
+
actions: [
|
|
14513
|
+
{
|
|
14514
|
+
name: "list",
|
|
14515
|
+
description: "List upcoming book releases",
|
|
14516
|
+
args: [
|
|
14517
|
+
{ name: "start", description: "Start date (ISO 8601)" },
|
|
14518
|
+
{ name: "end", description: "End date (ISO 8601)" },
|
|
14519
|
+
{ name: "unmonitored", description: "Include unmonitored", type: "boolean" }
|
|
14520
|
+
],
|
|
14521
|
+
columns: ["id", "authorName", "title", "releaseDate"],
|
|
14522
|
+
run: async (c3, a2) => {
|
|
14523
|
+
const books = unwrapData4(await c3.getCalendar(a2.start, a2.end, a2.unmonitored));
|
|
14524
|
+
return books.map(formatBookListItem);
|
|
14525
|
+
}
|
|
14526
|
+
}
|
|
14527
|
+
]
|
|
14528
|
+
},
|
|
14529
|
+
{
|
|
14530
|
+
name: "notification",
|
|
14531
|
+
description: "Manage notifications",
|
|
14532
|
+
actions: [
|
|
14533
|
+
{
|
|
14534
|
+
name: "list",
|
|
14535
|
+
description: "List notification providers",
|
|
14536
|
+
columns: ["id", "name", "implementation"],
|
|
14537
|
+
run: (c3) => c3.getNotifications()
|
|
13622
14538
|
},
|
|
13623
14539
|
{
|
|
13624
|
-
name: "
|
|
13625
|
-
description: "
|
|
13626
|
-
args: [{ name: "
|
|
13627
|
-
|
|
13628
|
-
run: (c3, a2) => c3.searchAuthors(a2.term)
|
|
14540
|
+
name: "get",
|
|
14541
|
+
description: "Get a notification by ID",
|
|
14542
|
+
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
14543
|
+
run: (c3, a2) => c3.getNotification(a2.id)
|
|
13629
14544
|
},
|
|
13630
14545
|
{
|
|
13631
14546
|
name: "add",
|
|
13632
|
-
description: "
|
|
13633
|
-
args: [{ name: "
|
|
13634
|
-
run: async (c3, a2) =>
|
|
13635
|
-
const searchResult = await c3.searchAuthors(a2.term);
|
|
13636
|
-
const results = searchResult?.data ?? searchResult;
|
|
13637
|
-
if (!Array.isArray(results) || results.length === 0) {
|
|
13638
|
-
throw new Error("No authors found.");
|
|
13639
|
-
}
|
|
13640
|
-
const authorId = await promptSelect("Select an author:", results.map((au) => ({
|
|
13641
|
-
label: au.authorName,
|
|
13642
|
-
value: String(au.foreignAuthorId)
|
|
13643
|
-
})));
|
|
13644
|
-
const author = results.find((au) => String(au.foreignAuthorId) === authorId);
|
|
13645
|
-
const profilesResult = await c3.getQualityProfiles();
|
|
13646
|
-
const profiles = profilesResult?.data ?? profilesResult;
|
|
13647
|
-
if (!Array.isArray(profiles) || profiles.length === 0) {
|
|
13648
|
-
throw new Error("No quality profiles found. Configure one in Readarr first.");
|
|
13649
|
-
}
|
|
13650
|
-
const profileId = await promptSelect("Select quality profile:", profiles.map((p) => ({ label: p.name, value: String(p.id) })));
|
|
13651
|
-
const foldersResult = await c3.getRootFolders();
|
|
13652
|
-
const folders = foldersResult?.data ?? foldersResult;
|
|
13653
|
-
if (!Array.isArray(folders) || folders.length === 0) {
|
|
13654
|
-
throw new Error("No root folders found. Configure one in Readarr first.");
|
|
13655
|
-
}
|
|
13656
|
-
const rootFolderPath = await promptSelect("Select root folder:", folders.map((f3) => ({ label: f3.path, value: f3.path })));
|
|
13657
|
-
const confirmed = await promptConfirm(`Add "${author.authorName}"?`, !!a2.yes);
|
|
13658
|
-
if (!confirmed)
|
|
13659
|
-
throw new Error("Cancelled.");
|
|
13660
|
-
return c3.addAuthor({
|
|
13661
|
-
...author,
|
|
13662
|
-
qualityProfileId: Number(profileId),
|
|
13663
|
-
rootFolderPath,
|
|
13664
|
-
monitored: true,
|
|
13665
|
-
addOptions: { searchForMissingBooks: true }
|
|
13666
|
-
});
|
|
13667
|
-
}
|
|
14547
|
+
description: "Add a notification from JSON file or stdin",
|
|
14548
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
14549
|
+
run: async (c3, a2) => c3.addNotification(readJsonInput4(a2.file))
|
|
13668
14550
|
},
|
|
13669
14551
|
{
|
|
13670
14552
|
name: "edit",
|
|
13671
|
-
description: "Edit
|
|
14553
|
+
description: "Edit a notification (merges JSON with existing)",
|
|
13672
14554
|
args: [
|
|
13673
|
-
{ name: "id", description: "
|
|
13674
|
-
{ name: "
|
|
13675
|
-
{ name: "quality-profile-id", description: "Quality profile ID", type: "number" },
|
|
13676
|
-
{ name: "tags", description: "Comma-separated tag IDs" }
|
|
14555
|
+
{ name: "id", description: "Notification ID", required: true, type: "number" },
|
|
14556
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
13677
14557
|
],
|
|
13678
14558
|
run: async (c3, a2) => {
|
|
13679
|
-
const
|
|
13680
|
-
|
|
13681
|
-
const updates = { ...author };
|
|
13682
|
-
if (a2.monitored !== undefined)
|
|
13683
|
-
updates.monitored = a2.monitored === "true";
|
|
13684
|
-
if (a2["quality-profile-id"] !== undefined)
|
|
13685
|
-
updates.qualityProfileId = Number(a2["quality-profile-id"]);
|
|
13686
|
-
if (a2.tags !== undefined)
|
|
13687
|
-
updates.tags = a2.tags.split(",").map((t2) => Number(t2.trim()));
|
|
13688
|
-
return c3.updateAuthor(a2.id, updates);
|
|
14559
|
+
const existing = unwrapData4(await c3.getNotification(a2.id));
|
|
14560
|
+
return c3.updateNotification(a2.id, { ...existing, ...readJsonInput4(a2.file) });
|
|
13689
14561
|
}
|
|
13690
14562
|
},
|
|
13691
14563
|
{
|
|
13692
|
-
name: "
|
|
13693
|
-
description: "
|
|
13694
|
-
args: [{ name: "id", description: "
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
{
|
|
13698
|
-
name: "manual-search",
|
|
13699
|
-
description: "Trigger a manual search for releases",
|
|
13700
|
-
args: [{ name: "id", description: "Author ID", required: true, type: "number" }],
|
|
13701
|
-
run: (c3, a2) => c3.runCommand({ name: "AuthorSearch", authorId: a2.id })
|
|
14564
|
+
name: "delete",
|
|
14565
|
+
description: "Delete a notification",
|
|
14566
|
+
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
14567
|
+
confirmMessage: "Are you sure you want to delete this notification?",
|
|
14568
|
+
run: (c3, a2) => c3.deleteNotification(a2.id)
|
|
13702
14569
|
},
|
|
13703
14570
|
{
|
|
13704
|
-
name: "
|
|
13705
|
-
description: "
|
|
13706
|
-
|
|
13707
|
-
confirmMessage: "Are you sure you want to delete this author?",
|
|
13708
|
-
run: (c3, a2) => c3.deleteAuthor(a2.id)
|
|
14571
|
+
name: "test",
|
|
14572
|
+
description: "Test all notifications",
|
|
14573
|
+
run: (c3) => c3.testAllNotifications()
|
|
13709
14574
|
}
|
|
13710
14575
|
]
|
|
13711
14576
|
},
|
|
13712
14577
|
{
|
|
13713
|
-
name: "
|
|
13714
|
-
description: "Manage
|
|
14578
|
+
name: "downloadclient",
|
|
14579
|
+
description: "Manage download clients",
|
|
13715
14580
|
actions: [
|
|
13716
14581
|
{
|
|
13717
14582
|
name: "list",
|
|
13718
|
-
description: "List
|
|
13719
|
-
columns: ["id", "
|
|
13720
|
-
run: (c3) => c3.
|
|
14583
|
+
description: "List download clients",
|
|
14584
|
+
columns: ["id", "name", "implementation", "enable"],
|
|
14585
|
+
run: (c3) => c3.getDownloadClients()
|
|
13721
14586
|
},
|
|
13722
14587
|
{
|
|
13723
14588
|
name: "get",
|
|
13724
|
-
description: "Get a
|
|
13725
|
-
args: [{ name: "id", description: "
|
|
13726
|
-
run: (c3, a2) => c3.
|
|
14589
|
+
description: "Get a download client by ID",
|
|
14590
|
+
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
14591
|
+
run: (c3, a2) => c3.getDownloadClient(a2.id)
|
|
13727
14592
|
},
|
|
13728
14593
|
{
|
|
13729
|
-
name: "
|
|
13730
|
-
description: "
|
|
13731
|
-
args: [{ name: "
|
|
13732
|
-
|
|
13733
|
-
|
|
14594
|
+
name: "add",
|
|
14595
|
+
description: "Add a download client from JSON file or stdin",
|
|
14596
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
14597
|
+
run: async (c3, a2) => c3.addDownloadClient(readJsonInput4(a2.file))
|
|
14598
|
+
},
|
|
14599
|
+
{
|
|
14600
|
+
name: "edit",
|
|
14601
|
+
description: "Edit a download client (merges JSON with existing)",
|
|
14602
|
+
args: [
|
|
14603
|
+
{ name: "id", description: "Download client ID", required: true, type: "number" },
|
|
14604
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
14605
|
+
],
|
|
14606
|
+
run: async (c3, a2) => {
|
|
14607
|
+
const existing = unwrapData4(await c3.getDownloadClient(a2.id));
|
|
14608
|
+
return c3.updateDownloadClient(a2.id, { ...existing, ...readJsonInput4(a2.file) });
|
|
14609
|
+
}
|
|
14610
|
+
},
|
|
14611
|
+
{
|
|
14612
|
+
name: "delete",
|
|
14613
|
+
description: "Delete a download client",
|
|
14614
|
+
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
14615
|
+
confirmMessage: "Are you sure you want to delete this download client?",
|
|
14616
|
+
run: (c3, a2) => c3.deleteDownloadClient(a2.id)
|
|
14617
|
+
},
|
|
14618
|
+
{
|
|
14619
|
+
name: "test",
|
|
14620
|
+
description: "Test all download clients",
|
|
14621
|
+
run: (c3) => c3.testAllDownloadClients()
|
|
13734
14622
|
}
|
|
13735
14623
|
]
|
|
13736
14624
|
},
|
|
13737
14625
|
{
|
|
13738
|
-
name: "
|
|
13739
|
-
description: "
|
|
14626
|
+
name: "blocklist",
|
|
14627
|
+
description: "View blocked releases",
|
|
13740
14628
|
actions: [
|
|
13741
14629
|
{
|
|
13742
14630
|
name: "list",
|
|
13743
|
-
description: "List
|
|
13744
|
-
columns: ["id", "
|
|
13745
|
-
run: (c3) =>
|
|
14631
|
+
description: "List blocked releases",
|
|
14632
|
+
columns: ["id", "authorName", "sourceTitle", "date"],
|
|
14633
|
+
run: async (c3) => {
|
|
14634
|
+
const items = unwrapData4(await c3.getBlocklist());
|
|
14635
|
+
return items.map(formatBlocklistItem2);
|
|
14636
|
+
}
|
|
14637
|
+
},
|
|
14638
|
+
{
|
|
14639
|
+
name: "delete",
|
|
14640
|
+
description: "Remove a release from the blocklist",
|
|
14641
|
+
args: [{ name: "id", description: "Blocklist item ID", required: true, type: "number" }],
|
|
14642
|
+
confirmMessage: "Are you sure you want to remove this blocklist entry?",
|
|
14643
|
+
run: (c3, a2) => c3.removeBlocklistItem(a2.id)
|
|
13746
14644
|
}
|
|
13747
14645
|
]
|
|
13748
14646
|
},
|
|
13749
14647
|
{
|
|
13750
|
-
name: "
|
|
13751
|
-
description: "
|
|
14648
|
+
name: "wanted",
|
|
14649
|
+
description: "View missing and cutoff unmet books",
|
|
13752
14650
|
actions: [
|
|
13753
14651
|
{
|
|
13754
|
-
name: "
|
|
13755
|
-
description: "
|
|
13756
|
-
|
|
13757
|
-
run: (c3
|
|
14652
|
+
name: "missing",
|
|
14653
|
+
description: "List books with missing files",
|
|
14654
|
+
columns: ["id", "authorName", "title", "releaseDate"],
|
|
14655
|
+
run: async (c3) => {
|
|
14656
|
+
const books = unwrapData4(await c3.getWantedMissing());
|
|
14657
|
+
return books.map(formatBookListItem);
|
|
14658
|
+
}
|
|
13758
14659
|
},
|
|
13759
14660
|
{
|
|
13760
|
-
name: "
|
|
13761
|
-
description: "
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
if (tagResult?.error)
|
|
13767
|
-
return tagResult;
|
|
13768
|
-
const tag = tagResult?.data ?? tagResult;
|
|
13769
|
-
const deleteResult = await c3.deleteTag(a2.id);
|
|
13770
|
-
if (deleteResult?.error)
|
|
13771
|
-
return deleteResult;
|
|
13772
|
-
return { message: `Deleted tag: ${tag.label} (ID: ${tag.id})` };
|
|
14661
|
+
name: "cutoff",
|
|
14662
|
+
description: "List books below quality cutoff",
|
|
14663
|
+
columns: ["id", "authorName", "title", "releaseDate"],
|
|
14664
|
+
run: async (c3) => {
|
|
14665
|
+
const books = unwrapData4(await c3.getWantedCutoff());
|
|
14666
|
+
return books.map(formatBookListItem);
|
|
13773
14667
|
}
|
|
13774
|
-
}
|
|
14668
|
+
}
|
|
14669
|
+
]
|
|
14670
|
+
},
|
|
14671
|
+
{
|
|
14672
|
+
name: "importlist",
|
|
14673
|
+
description: "Manage import lists",
|
|
14674
|
+
actions: [
|
|
13775
14675
|
{
|
|
13776
14676
|
name: "list",
|
|
13777
|
-
description: "List
|
|
13778
|
-
columns: ["id", "
|
|
13779
|
-
run: (c3) => c3.
|
|
14677
|
+
description: "List import lists",
|
|
14678
|
+
columns: ["id", "name", "implementation", "enable"],
|
|
14679
|
+
run: (c3) => c3.getImportLists()
|
|
14680
|
+
},
|
|
14681
|
+
{
|
|
14682
|
+
name: "get",
|
|
14683
|
+
description: "Get an import list by ID",
|
|
14684
|
+
args: [{ name: "id", description: "Import list ID", required: true, type: "number" }],
|
|
14685
|
+
run: (c3, a2) => c3.getImportList(a2.id)
|
|
14686
|
+
},
|
|
14687
|
+
{
|
|
14688
|
+
name: "delete",
|
|
14689
|
+
description: "Delete an import list",
|
|
14690
|
+
args: [{ name: "id", description: "Import list ID", required: true, type: "number" }],
|
|
14691
|
+
confirmMessage: "Are you sure you want to delete this import list?",
|
|
14692
|
+
run: (c3, a2) => c3.deleteImportList(a2.id)
|
|
13780
14693
|
}
|
|
13781
14694
|
]
|
|
13782
14695
|
},
|
|
@@ -15446,6 +16359,53 @@ var exports_prowlarr3 = {};
|
|
|
15446
16359
|
__export(exports_prowlarr3, {
|
|
15447
16360
|
prowlarr: () => prowlarr
|
|
15448
16361
|
});
|
|
16362
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
16363
|
+
function unwrapData5(result) {
|
|
16364
|
+
return result?.data ?? result;
|
|
16365
|
+
}
|
|
16366
|
+
function readJsonInput5(filePath) {
|
|
16367
|
+
const raw = filePath === "-" ? readFileSync6(0, "utf-8") : readFileSync6(filePath, "utf-8");
|
|
16368
|
+
return JSON.parse(raw);
|
|
16369
|
+
}
|
|
16370
|
+
async function runIndexerTest(client6, indexer) {
|
|
16371
|
+
const result = await client6.testIndexer(indexer);
|
|
16372
|
+
if (result?.error) {
|
|
16373
|
+
const error = result.error;
|
|
16374
|
+
const response = result.response;
|
|
16375
|
+
const status = error?.status ?? response?.status;
|
|
16376
|
+
return {
|
|
16377
|
+
id: indexer?.id,
|
|
16378
|
+
name: indexer?.name ?? "Unknown indexer",
|
|
16379
|
+
status: "fail",
|
|
16380
|
+
message: error?.title ?? error?.message ?? `API error (${status ?? "unknown"})`
|
|
16381
|
+
};
|
|
16382
|
+
}
|
|
16383
|
+
const data = unwrapData5(result);
|
|
16384
|
+
return {
|
|
16385
|
+
id: indexer?.id,
|
|
16386
|
+
name: indexer?.name ?? "Unknown indexer",
|
|
16387
|
+
status: "ok",
|
|
16388
|
+
message: extractIndexerTestMessage(data)
|
|
16389
|
+
};
|
|
16390
|
+
}
|
|
16391
|
+
function extractIndexerTestMessage(data) {
|
|
16392
|
+
if (typeof data === "string" && data.trim() !== "") {
|
|
16393
|
+
return data;
|
|
16394
|
+
}
|
|
16395
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
16396
|
+
const first = data[0];
|
|
16397
|
+
if (typeof first === "string" && first.trim() !== "") {
|
|
16398
|
+
return first;
|
|
16399
|
+
}
|
|
16400
|
+
if (typeof first?.message === "string" && first.message.trim() !== "") {
|
|
16401
|
+
return first.message;
|
|
16402
|
+
}
|
|
16403
|
+
}
|
|
16404
|
+
if (typeof data?.message === "string" && data.message.trim() !== "") {
|
|
16405
|
+
return data.message;
|
|
16406
|
+
}
|
|
16407
|
+
return "Test completed";
|
|
16408
|
+
}
|
|
15449
16409
|
var resources5, prowlarr;
|
|
15450
16410
|
var init_prowlarr3 = __esm(() => {
|
|
15451
16411
|
init_prowlarr2();
|
|
@@ -15468,6 +16428,28 @@ var init_prowlarr3 = __esm(() => {
|
|
|
15468
16428
|
args: [{ name: "id", description: "Indexer ID", required: true, type: "number" }],
|
|
15469
16429
|
run: (c3, a2) => c3.getIndexer(a2.id)
|
|
15470
16430
|
},
|
|
16431
|
+
{
|
|
16432
|
+
name: "add",
|
|
16433
|
+
description: "Add an indexer from JSON file or stdin",
|
|
16434
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
16435
|
+
run: async (c3, a2) => {
|
|
16436
|
+
const body = readJsonInput5(a2.file);
|
|
16437
|
+
return c3.addIndexer(body);
|
|
16438
|
+
}
|
|
16439
|
+
},
|
|
16440
|
+
{
|
|
16441
|
+
name: "edit",
|
|
16442
|
+
description: "Edit an indexer (merges JSON with existing)",
|
|
16443
|
+
args: [
|
|
16444
|
+
{ name: "id", description: "Indexer ID", required: true, type: "number" },
|
|
16445
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
16446
|
+
],
|
|
16447
|
+
run: async (c3, a2) => {
|
|
16448
|
+
const existing = unwrapData5(await c3.getIndexer(a2.id));
|
|
16449
|
+
const updates = readJsonInput5(a2.file);
|
|
16450
|
+
return c3.updateIndexer(a2.id, { ...existing, ...updates });
|
|
16451
|
+
}
|
|
16452
|
+
},
|
|
15471
16453
|
{
|
|
15472
16454
|
name: "delete",
|
|
15473
16455
|
description: "Delete an indexer",
|
|
@@ -15477,8 +16459,17 @@ var init_prowlarr3 = __esm(() => {
|
|
|
15477
16459
|
},
|
|
15478
16460
|
{
|
|
15479
16461
|
name: "test",
|
|
15480
|
-
description: "Test all indexers",
|
|
15481
|
-
|
|
16462
|
+
description: "Test one indexer or all configured indexers",
|
|
16463
|
+
args: [{ name: "id", description: "Indexer ID", type: "number" }],
|
|
16464
|
+
columns: ["id", "name", "status", "message"],
|
|
16465
|
+
run: async (c3, a2) => {
|
|
16466
|
+
const indexers = a2.id ? [unwrapData5(await c3.getIndexer(a2.id))] : unwrapData5(await c3.getIndexers());
|
|
16467
|
+
const results = [];
|
|
16468
|
+
for (const indexer of indexers) {
|
|
16469
|
+
results.push(await runIndexerTest(c3, indexer));
|
|
16470
|
+
}
|
|
16471
|
+
return a2.id ? results[0] : results;
|
|
16472
|
+
}
|
|
15482
16473
|
}
|
|
15483
16474
|
]
|
|
15484
16475
|
},
|
|
@@ -15514,6 +16505,28 @@ var init_prowlarr3 = __esm(() => {
|
|
|
15514
16505
|
args: [{ name: "id", description: "Application ID", required: true, type: "number" }],
|
|
15515
16506
|
run: (c3, a2) => c3.getApplication(a2.id)
|
|
15516
16507
|
},
|
|
16508
|
+
{
|
|
16509
|
+
name: "add",
|
|
16510
|
+
description: "Add an application from JSON file or stdin",
|
|
16511
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
16512
|
+
run: async (c3, a2) => {
|
|
16513
|
+
const body = readJsonInput5(a2.file);
|
|
16514
|
+
return c3.addApplication(body);
|
|
16515
|
+
}
|
|
16516
|
+
},
|
|
16517
|
+
{
|
|
16518
|
+
name: "edit",
|
|
16519
|
+
description: "Edit an application (merges JSON with existing)",
|
|
16520
|
+
args: [
|
|
16521
|
+
{ name: "id", description: "Application ID", required: true, type: "number" },
|
|
16522
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
16523
|
+
],
|
|
16524
|
+
run: async (c3, a2) => {
|
|
16525
|
+
const existing = unwrapData5(await c3.getApplication(a2.id));
|
|
16526
|
+
const updates = readJsonInput5(a2.file);
|
|
16527
|
+
return c3.updateApplication(a2.id, { ...existing, ...updates });
|
|
16528
|
+
}
|
|
16529
|
+
},
|
|
15517
16530
|
{
|
|
15518
16531
|
name: "delete",
|
|
15519
16532
|
description: "Delete an application",
|
|
@@ -15569,7 +16582,17 @@ var init_prowlarr3 = __esm(() => {
|
|
|
15569
16582
|
{
|
|
15570
16583
|
name: "list",
|
|
15571
16584
|
description: "Get indexer performance statistics",
|
|
15572
|
-
|
|
16585
|
+
columns: [
|
|
16586
|
+
"indexerName",
|
|
16587
|
+
"numberOfQueries",
|
|
16588
|
+
"numberOfGrabs",
|
|
16589
|
+
"numberOfFailures",
|
|
16590
|
+
"averageResponseTime"
|
|
16591
|
+
],
|
|
16592
|
+
run: async (c3) => {
|
|
16593
|
+
const result = unwrapData5(await c3.getIndexerStats());
|
|
16594
|
+
return result?.indexers ?? result;
|
|
16595
|
+
}
|
|
15573
16596
|
}
|
|
15574
16597
|
]
|
|
15575
16598
|
},
|
|
@@ -15589,6 +16612,24 @@ var init_prowlarr3 = __esm(() => {
|
|
|
15589
16612
|
args: [{ name: "id", description: "Notification ID", required: true, type: "number" }],
|
|
15590
16613
|
run: (c3, a2) => c3.getNotification(a2.id)
|
|
15591
16614
|
},
|
|
16615
|
+
{
|
|
16616
|
+
name: "add",
|
|
16617
|
+
description: "Add a notification from JSON file or stdin",
|
|
16618
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
16619
|
+
run: async (c3, a2) => c3.addNotification(readJsonInput5(a2.file))
|
|
16620
|
+
},
|
|
16621
|
+
{
|
|
16622
|
+
name: "edit",
|
|
16623
|
+
description: "Edit a notification (merges JSON with existing)",
|
|
16624
|
+
args: [
|
|
16625
|
+
{ name: "id", description: "Notification ID", required: true, type: "number" },
|
|
16626
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
16627
|
+
],
|
|
16628
|
+
run: async (c3, a2) => {
|
|
16629
|
+
const existing = unwrapData5(await c3.getNotification(a2.id));
|
|
16630
|
+
return c3.updateNotification(a2.id, { ...existing, ...readJsonInput5(a2.file) });
|
|
16631
|
+
}
|
|
16632
|
+
},
|
|
15592
16633
|
{
|
|
15593
16634
|
name: "delete",
|
|
15594
16635
|
description: "Delete a notification",
|
|
@@ -15619,6 +16660,24 @@ var init_prowlarr3 = __esm(() => {
|
|
|
15619
16660
|
args: [{ name: "id", description: "Download client ID", required: true, type: "number" }],
|
|
15620
16661
|
run: (c3, a2) => c3.getDownloadClient(a2.id)
|
|
15621
16662
|
},
|
|
16663
|
+
{
|
|
16664
|
+
name: "add",
|
|
16665
|
+
description: "Add a download client from JSON file or stdin",
|
|
16666
|
+
args: [{ name: "file", description: "JSON file path (use - for stdin)", required: true }],
|
|
16667
|
+
run: async (c3, a2) => c3.addDownloadClient(readJsonInput5(a2.file))
|
|
16668
|
+
},
|
|
16669
|
+
{
|
|
16670
|
+
name: "edit",
|
|
16671
|
+
description: "Edit a download client (merges JSON with existing)",
|
|
16672
|
+
args: [
|
|
16673
|
+
{ name: "id", description: "Download client ID", required: true, type: "number" },
|
|
16674
|
+
{ name: "file", description: "JSON file with fields to update", required: true }
|
|
16675
|
+
],
|
|
16676
|
+
run: async (c3, a2) => {
|
|
16677
|
+
const existing = unwrapData5(await c3.getDownloadClient(a2.id));
|
|
16678
|
+
return c3.updateDownloadClient(a2.id, { ...existing, ...readJsonInput5(a2.file) });
|
|
16679
|
+
}
|
|
16680
|
+
},
|
|
15622
16681
|
{
|
|
15623
16682
|
name: "delete",
|
|
15624
16683
|
description: "Delete a download client",
|
|
@@ -16762,6 +17821,12 @@ function getBazarrApiBaseUrl(baseUrl) {
|
|
|
16762
17821
|
const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
|
|
16763
17822
|
return normalizedBaseUrl.endsWith("/api") ? normalizedBaseUrl : `${normalizedBaseUrl}/api`;
|
|
16764
17823
|
}
|
|
17824
|
+
function getBazarrHeaders(config) {
|
|
17825
|
+
return {
|
|
17826
|
+
"Content-Type": "application/json",
|
|
17827
|
+
...config.config.headers ?? {}
|
|
17828
|
+
};
|
|
17829
|
+
}
|
|
16765
17830
|
|
|
16766
17831
|
class BazarrClient {
|
|
16767
17832
|
clientConfig;
|
|
@@ -16769,7 +17834,8 @@ class BazarrClient {
|
|
|
16769
17834
|
this.clientConfig = createServarrClient(config);
|
|
16770
17835
|
client6.setConfig({
|
|
16771
17836
|
baseUrl: getBazarrApiBaseUrl(this.clientConfig.getBaseUrl()),
|
|
16772
|
-
headers: this.clientConfig
|
|
17837
|
+
headers: getBazarrHeaders(this.clientConfig),
|
|
17838
|
+
auth: this.clientConfig.config.apiKey
|
|
16773
17839
|
});
|
|
16774
17840
|
}
|
|
16775
17841
|
async getSystemStatus() {
|
|
@@ -17109,7 +18175,8 @@ class BazarrClient {
|
|
|
17109
18175
|
this.clientConfig = createServarrClient(updatedConfig);
|
|
17110
18176
|
client6.setConfig({
|
|
17111
18177
|
baseUrl: getBazarrApiBaseUrl(this.clientConfig.getBaseUrl()),
|
|
17112
|
-
headers: this.clientConfig
|
|
18178
|
+
headers: getBazarrHeaders(this.clientConfig),
|
|
18179
|
+
auth: this.clientConfig.config.apiKey
|
|
17113
18180
|
});
|
|
17114
18181
|
return this.clientConfig.config;
|
|
17115
18182
|
}
|
|
@@ -17751,8 +18818,8 @@ var init_completions = __esm(() => {
|
|
|
17751
18818
|
|
|
17752
18819
|
// src/cli/index.ts
|
|
17753
18820
|
init_dist();
|
|
17754
|
-
import { readFileSync as
|
|
17755
|
-
var { version } = JSON.parse(
|
|
18821
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
18822
|
+
var { version } = JSON.parse(readFileSync7(new URL("../../package.json", import.meta.url), "utf-8"));
|
|
17756
18823
|
var main = defineCommand({
|
|
17757
18824
|
meta: {
|
|
17758
18825
|
name: "tsarr",
|