@muhammedaksam/easiarr 1.3.5 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +8 -5
  2. package/dist/index.js +29837 -0
  3. package/package.json +18 -16
  4. package/src/VersionInfo.ts +0 -12
  5. package/src/api/arr-api.ts +0 -508
  6. package/src/api/auto-setup-types.ts +0 -64
  7. package/src/api/bazarr-api.ts +0 -356
  8. package/src/api/cloudflare-api.ts +0 -577
  9. package/src/api/custom-format-api.ts +0 -212
  10. package/src/api/grafana-api.ts +0 -314
  11. package/src/api/heimdall-api.ts +0 -209
  12. package/src/api/homarr-api.ts +0 -296
  13. package/src/api/huntarr-api.ts +0 -622
  14. package/src/api/index.ts +0 -1
  15. package/src/api/jellyfin-api.ts +0 -473
  16. package/src/api/jellyseerr-api.ts +0 -660
  17. package/src/api/maintainerr-api.ts +0 -731
  18. package/src/api/naming-config.ts +0 -93
  19. package/src/api/overseerr-api.ts +0 -513
  20. package/src/api/plex-api.ts +0 -358
  21. package/src/api/portainer-api.ts +0 -467
  22. package/src/api/profilarr-api.ts +0 -380
  23. package/src/api/prowlarr-api.ts +0 -859
  24. package/src/api/qbittorrent-api.ts +0 -339
  25. package/src/api/quality-profile-api.ts +0 -269
  26. package/src/api/tautulli-api.ts +0 -277
  27. package/src/api/uptime-kuma-api.ts +0 -342
  28. package/src/apps/categories.ts +0 -14
  29. package/src/apps/index.ts +0 -2
  30. package/src/apps/registry.ts +0 -1255
  31. package/src/compose/caddy-config.ts +0 -129
  32. package/src/compose/generator.ts +0 -262
  33. package/src/compose/index.ts +0 -3
  34. package/src/compose/templates.ts +0 -78
  35. package/src/compose/traefik-config.ts +0 -185
  36. package/src/config/bookmarks-generator.ts +0 -149
  37. package/src/config/defaults.ts +0 -37
  38. package/src/config/homepage-config.ts +0 -376
  39. package/src/config/index.ts +0 -3
  40. package/src/config/manager.ts +0 -149
  41. package/src/config/recyclarr-config.ts +0 -179
  42. package/src/config/schema.ts +0 -310
  43. package/src/config/slskd-config.ts +0 -85
  44. package/src/config/soularr-config.ts +0 -105
  45. package/src/config/trash-quality-definitions.ts +0 -213
  46. package/src/data/lidarr-custom-formats.ts +0 -127
  47. package/src/data/trash-profiles.ts +0 -326
  48. package/src/docker/client.ts +0 -291
  49. package/src/docker/index.ts +0 -1
  50. package/src/index.ts +0 -77
  51. package/src/structure/manager.ts +0 -128
  52. package/src/ui/App.ts +0 -109
  53. package/src/ui/components/ApplicationSelector.ts +0 -272
  54. package/src/ui/components/FileEditor.ts +0 -91
  55. package/src/ui/components/FooterHint.ts +0 -119
  56. package/src/ui/components/PageLayout.ts +0 -152
  57. package/src/ui/components/UpdateNotification.ts +0 -101
  58. package/src/ui/index.ts +0 -1
  59. package/src/ui/screens/AdvancedSettings.ts +0 -181
  60. package/src/ui/screens/ApiKeyViewer.ts +0 -500
  61. package/src/ui/screens/AppConfigurator.ts +0 -731
  62. package/src/ui/screens/AppManager.ts +0 -276
  63. package/src/ui/screens/CloudflaredSetup.ts +0 -974
  64. package/src/ui/screens/ContainerControl.ts +0 -579
  65. package/src/ui/screens/FullAutoSetup.ts +0 -1719
  66. package/src/ui/screens/HomepageSetup.ts +0 -306
  67. package/src/ui/screens/JellyfinSetup.ts +0 -471
  68. package/src/ui/screens/JellyseerrSetup.ts +0 -612
  69. package/src/ui/screens/LogsViewer.ts +0 -468
  70. package/src/ui/screens/MainMenu.ts +0 -288
  71. package/src/ui/screens/MonitorDashboard.ts +0 -866
  72. package/src/ui/screens/ProwlarrSetup.ts +0 -623
  73. package/src/ui/screens/QBittorrentSetup.ts +0 -268
  74. package/src/ui/screens/QuickSetup.ts +0 -1161
  75. package/src/ui/screens/RecyclarrSetup.ts +0 -418
  76. package/src/ui/screens/SecretsEditor.ts +0 -214
  77. package/src/ui/screens/SettingsScreen.ts +0 -605
  78. package/src/ui/screens/TRaSHProfileSetup.ts +0 -395
  79. package/src/ui/screens/index.ts +0 -4
  80. package/src/util/arch.ts +0 -78
  81. package/src/utils/browser.ts +0 -26
  82. package/src/utils/categories.ts +0 -59
  83. package/src/utils/debug.ts +0 -91
  84. package/src/utils/env.ts +0 -137
  85. package/src/utils/logs.ts +0 -118
  86. package/src/utils/migrations/1765626338_rename_env_variables.ts +0 -101
  87. package/src/utils/migrations/1765707135_rename_easiarr_status.ts +0 -90
  88. package/src/utils/migrations/1765732722_remove_cloudflare_dns_api_token.ts +0 -44
  89. package/src/utils/migrations/1769515650_migrate_to_xdg.ts +0 -107
  90. package/src/utils/migrations.ts +0 -164
  91. package/src/utils/password.ts +0 -42
  92. package/src/utils/unraid.ts +0 -101
  93. package/src/utils/update-checker.ts +0 -210
  94. package/src/utils/url-utils.ts +0 -38
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@muhammedaksam/easiarr",
3
- "version": "1.3.5",
3
+ "version": "1.4.1",
4
4
  "description": "TUI tool for generating docker-compose files for the *arr media ecosystem with 41 apps, TRaSH Guides best practices, VPN routing, and Traefik reverse proxy support",
5
- "module": "src/index.ts",
5
+ "module": "dist/index.js",
6
6
  "type": "module",
7
7
  "bin": {
8
- "easiarr": "./src/index.ts"
8
+ "easiarr": "./dist/index.js"
9
9
  },
10
10
  "files": [
11
- "src"
11
+ "dist"
12
12
  ],
13
13
  "author": "Muhammed Mustafa AKŞAM <info@muhammedaksam.com.tr> (https://github.com/muhammedaksam)",
14
14
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  "scripts": {
37
37
  "dev": "bun run --watch src/index.ts",
38
38
  "dev:debug": "bun run dev --debug",
39
- "build": "bun build src/index.ts --outdir dist --target bun",
39
+ "build": "bun build src/index.ts --outdir dist --target bun --external @opentui/core",
40
40
  "typecheck": "bun x tsc --noEmit",
41
41
  "lint": "eslint src/",
42
42
  "lint:fix": "eslint src/ --fix",
@@ -51,28 +51,30 @@
51
51
  "start": "bun run src/index.ts"
52
52
  },
53
53
  "devDependencies": {
54
- "@eslint/js": "^9.39.2",
54
+ "@eslint/js": "^10.0.1",
55
+ "@ianvs/prettier-plugin-sort-imports": "^4.7.1",
55
56
  "@types/bcrypt": "^6.0.0",
56
57
  "@types/bun": "latest",
57
58
  "@types/jest": "^30.0.0",
58
- "@types/node": "^25.0.10",
59
- "eslint": "^9.39.2",
60
- "jest": "^30.2.0",
61
- "jiti": "^2.6.1",
62
- "prettier": "^3.8.1",
63
- "ts-jest": "^29.4.6",
64
- "typescript-eslint": "^8.54.0"
59
+ "@types/node": "^26.0.1",
60
+ "eslint": "^10.6.0",
61
+ "eslint-plugin-import": "^2.32.0",
62
+ "jest": "^30.4.2",
63
+ "jiti": "^2.7.0",
64
+ "prettier": "^3.9.1",
65
+ "ts-jest": "^29.4.11",
66
+ "typescript-eslint": "^8.62.0"
65
67
  },
66
68
  "peerDependencies": {
67
69
  "typescript": "^5.9.3"
68
70
  },
69
71
  "dependencies": {
70
- "@opentui/core": "^0.1.75",
72
+ "@opentui/core": "^0.4.2",
71
73
  "bcrypt": "^6.0.0",
72
74
  "socket.io-client": "^4.8.3",
73
- "yaml": "^2.8.2"
75
+ "yaml": "^2.9.0"
74
76
  },
75
77
  "engines": {
76
78
  "bun": ">=1.0"
77
79
  }
78
- }
80
+ }
@@ -1,12 +0,0 @@
1
- import packageJson from "../package.json" with { type: "json" }
2
-
3
- const pkg = packageJson
4
-
5
- export const VersionInfo = {
6
- version: pkg.version,
7
- name: pkg.name,
8
- description: pkg.description,
9
- author: pkg.author,
10
- }
11
-
12
- export const getVersion = () => `v${VersionInfo.version}`
@@ -1,508 +0,0 @@
1
- /**
2
- * *arr API Client
3
- * Interacts with Radarr, Sonarr, Lidarr, Readarr, Whisparr APIs
4
- */
5
-
6
- import { debugLog } from "../utils/debug"
7
-
8
- // Types for Root Folder API
9
- export interface RootFolder {
10
- id?: number
11
- path: string
12
- accessible?: boolean
13
- freeSpace?: number | null
14
- unmappedFolders?: { name: string | null; path: string | null; relativePath: string | null }[]
15
- }
16
-
17
- // Options for adding root folder (some apps like Lidarr need extra fields)
18
- export interface AddRootFolderOptions {
19
- path: string
20
- name?: string // Required for Lidarr
21
- defaultMetadataProfileId?: number
22
- defaultQualityProfileId?: number
23
- }
24
-
25
- // Types for Download Client API
26
- export interface DownloadClientConfig {
27
- name: string
28
- implementation: string
29
- configContract: string
30
- enable?: boolean
31
- priority?: number
32
- fields: { name: string; value: unknown }[]
33
- }
34
-
35
- export interface DownloadClient extends DownloadClientConfig {
36
- id?: number
37
- }
38
-
39
- // Types for Remote Path Mapping API
40
- export interface RemotePathMapping {
41
- id?: number
42
- host: string
43
- remotePath: string
44
- localPath: string
45
- }
46
-
47
- import type { AppId } from "../config/schema"
48
- import { getCategoryForApp, getCategoryFieldName } from "../utils/categories"
49
- import { TRASH_NAMING_CONFIG, type NamingConfig } from "./naming-config"
50
-
51
- // qBittorrent download client config
52
- export function createQBittorrentConfig(
53
- host: string,
54
- port: number,
55
- username: string,
56
- password: string,
57
- appId?: AppId
58
- ): DownloadClientConfig {
59
- const category = appId ? getCategoryForApp(appId) : "default"
60
- const categoryField = appId ? getCategoryFieldName(appId) : "category"
61
-
62
- return {
63
- name: "qBittorrent",
64
- implementation: "QBittorrent",
65
- configContract: "QBittorrentSettings",
66
- enable: true,
67
- priority: 1,
68
- fields: [
69
- { name: "host", value: host },
70
- { name: "port", value: port },
71
- { name: "username", value: username },
72
- { name: "password", value: password },
73
- { name: categoryField, value: category },
74
- { name: "savePath", value: "/data/torrents" },
75
- { name: "recentMoviePriority", value: 0 },
76
- { name: "olderMoviePriority", value: 0 },
77
- { name: "initialState", value: 0 },
78
- { name: "sequentialOrder", value: false },
79
- { name: "firstAndLast", value: false },
80
- ],
81
- }
82
- }
83
-
84
- // SABnzbd download client config
85
- export function createSABnzbdConfig(host: string, port: number, apiKey: string, appId?: AppId): DownloadClientConfig {
86
- const category = appId ? getCategoryForApp(appId) : "default"
87
- const categoryField = appId ? getCategoryFieldName(appId) : "category"
88
-
89
- return {
90
- name: "SABnzbd",
91
- implementation: "Sabnzbd",
92
- configContract: "SabnzbdSettings",
93
- enable: true,
94
- priority: 1,
95
- fields: [
96
- { name: "host", value: host },
97
- { name: "port", value: port },
98
- { name: "apiKey", value: apiKey },
99
- { name: categoryField, value: category },
100
- { name: "savePath", value: "/data/usenet" },
101
- { name: "recentMoviePriority", value: -100 },
102
- { name: "olderMoviePriority", value: -100 },
103
- ],
104
- }
105
- }
106
-
107
- export type ApiVersion = "v1" | "v3"
108
-
109
- /**
110
- * *arr API Client
111
- */
112
- export class ArrApiClient {
113
- private baseUrl: string
114
- private apiKey: string
115
- private apiVersion: ApiVersion
116
-
117
- constructor(host: string, port: number, apiKey: string, apiVersion: ApiVersion = "v3") {
118
- this.baseUrl = `http://${host}:${port}`
119
- this.apiKey = apiKey
120
- this.apiVersion = apiVersion
121
- }
122
-
123
- private async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
124
- const url = `${this.baseUrl}/api/${this.apiVersion}${endpoint}`
125
- const headers = {
126
- "X-Api-Key": this.apiKey,
127
- "Content-Type": "application/json",
128
- ...options.headers,
129
- }
130
-
131
- debugLog("ArrAPI", `${options.method || "GET"} ${url}`)
132
- if (options.body) {
133
- debugLog("ArrAPI", `Request Body: ${options.body}`)
134
- }
135
-
136
- const response = await fetch(url, { ...options, headers })
137
- const text = await response.text()
138
-
139
- debugLog("ArrAPI", `Response ${response.status} from ${endpoint}`)
140
- if (text && text.length < 2000) {
141
- debugLog("ArrAPI", `Response Body: ${text}`)
142
- }
143
-
144
- if (!response.ok) {
145
- throw new Error(`API request failed: ${response.status} ${response.statusText} - ${text}`)
146
- }
147
-
148
- if (!text) return {} as T
149
- return JSON.parse(text) as T
150
- }
151
-
152
- // Root Folder methods
153
- async getRootFolders(): Promise<RootFolder[]> {
154
- return this.request<RootFolder[]>("/rootfolder")
155
- }
156
-
157
- async addRootFolder(pathOrOptions: string | AddRootFolderOptions): Promise<RootFolder> {
158
- const body = typeof pathOrOptions === "string" ? { path: pathOrOptions } : pathOrOptions
159
- return this.request<RootFolder>("/rootfolder", {
160
- method: "POST",
161
- body: JSON.stringify(body),
162
- })
163
- }
164
-
165
- // Profile methods (needed for Lidarr root folders)
166
- async getMetadataProfiles(): Promise<{ id: number; name: string }[]> {
167
- try {
168
- return await this.request<{ id: number; name: string }[]>("/metadataprofile")
169
- } catch {
170
- return []
171
- }
172
- }
173
-
174
- async getQualityProfiles(): Promise<{ id: number; name: string }[]> {
175
- try {
176
- return await this.request<{ id: number; name: string }[]>("/qualityprofile")
177
- } catch {
178
- return []
179
- }
180
- }
181
-
182
- async deleteRootFolder(id: number): Promise<void> {
183
- await this.request(`/rootfolder/${id}`, { method: "DELETE" })
184
- }
185
-
186
- // Download Client methods
187
- async getDownloadClients(): Promise<DownloadClient[]> {
188
- return this.request<DownloadClient[]>("/downloadclient")
189
- }
190
-
191
- async addDownloadClient(config: DownloadClientConfig): Promise<DownloadClient> {
192
- return this.request<DownloadClient>("/downloadclient", {
193
- method: "POST",
194
- body: JSON.stringify(config),
195
- })
196
- }
197
-
198
- async deleteDownloadClient(id: number): Promise<void> {
199
- await this.request(`/downloadclient/${id}`, { method: "DELETE" })
200
- }
201
-
202
- // Health check
203
- async isHealthy(): Promise<boolean> {
204
- try {
205
- await this.request("/system/status")
206
- return true
207
- } catch {
208
- return false
209
- }
210
- }
211
-
212
- // Host Config methods - for setting up authentication
213
- async getHostConfig(): Promise<HostConfig> {
214
- return this.request<HostConfig>("/config/host")
215
- }
216
-
217
- async updateHostConfig(username: string, password: string, override = false): Promise<HostConfig | null> {
218
- // First get current config to preserve all other settings
219
- const currentConfig = await this.getHostConfig()
220
-
221
- // Only update if no password is set OR override is requested
222
- if (currentConfig.password && !override) {
223
- return null // Skip - password already configured
224
- }
225
-
226
- // Update with authentication settings (id must be in body, not URL)
227
- const updatedConfig: HostConfig = {
228
- ...currentConfig,
229
- authenticationMethod: "forms",
230
- authenticationRequired: "enabled",
231
- username,
232
- password,
233
- passwordConfirmation: password,
234
- }
235
-
236
- // PUT to /config/host with id in body (not /config/host/{id})
237
- return this.request<HostConfig>("/config/host", {
238
- method: "PUT",
239
- body: JSON.stringify(updatedConfig),
240
- })
241
- }
242
-
243
- /**
244
- * Set application URL for external access (e.g., from Jellyseerr/dashboard links)
245
- * URL will be used when generating external links in the app
246
- */
247
- async setApplicationUrl(applicationUrl: string): Promise<HostConfig> {
248
- const currentConfig = await this.getHostConfig()
249
-
250
- const updatedConfig: HostConfig = {
251
- ...currentConfig,
252
- applicationUrl,
253
- }
254
-
255
- debugLog("ArrAPI", `Setting applicationUrl to: ${applicationUrl}`)
256
-
257
- return this.request<HostConfig>("/config/host", {
258
- method: "PUT",
259
- body: JSON.stringify(updatedConfig),
260
- })
261
- }
262
-
263
- // Remote Path Mapping methods - for Docker path translation
264
-
265
- async getRemotePathMappings(): Promise<RemotePathMapping[]> {
266
- return this.request<RemotePathMapping[]>("/remotepathmapping")
267
- }
268
-
269
- // Naming Configuration methods
270
- async getNamingConfig<T extends NamingConfig>(): Promise<T> {
271
- return this.request<T>("/config/naming")
272
- }
273
-
274
- async updateNamingConfig<T extends NamingConfig>(config: T): Promise<T> {
275
- return this.request<T>("/config/naming", {
276
- method: "PUT",
277
- body: JSON.stringify(config),
278
- })
279
- }
280
-
281
- async configureTRaSHNaming(appType: "radarr" | "sonarr" | "lidarr"): Promise<void> {
282
- try {
283
- // 1. Get current configuration to preserve ID and other fields
284
- const currentConfig = await this.getNamingConfig<NamingConfig & { id?: number }>()
285
-
286
- // 2. Merge with TRaSH defaults
287
- const trashConfig = TRASH_NAMING_CONFIG[appType]
288
- const newConfig = {
289
- ...currentConfig,
290
- ...trashConfig,
291
- }
292
-
293
- // 3. Update configuration
294
- await this.updateNamingConfig(newConfig)
295
- } catch (e) {
296
- throw new Error(`Failed to configure naming: ${e}`)
297
- }
298
- }
299
-
300
- async addRemotePathMapping(host: string, remotePath: string, localPath: string): Promise<RemotePathMapping> {
301
- return this.request<RemotePathMapping>("/remotepathmapping", {
302
- method: "POST",
303
- body: JSON.stringify({ host, remotePath, localPath }),
304
- })
305
- }
306
-
307
- async deleteRemotePathMapping(id: number): Promise<void> {
308
- await this.request(`/remotepathmapping/${id}`, { method: "DELETE" })
309
- }
310
-
311
- // ==========================================
312
- // Health Check & Status Methods
313
- // ==========================================
314
-
315
- // Get health issues/warnings
316
- async getHealth(): Promise<HealthResource[]> {
317
- return this.request<HealthResource[]>("/health")
318
- }
319
-
320
- // Get disk space information for all monitored paths
321
- async getDiskSpace(): Promise<DiskSpaceResource[]> {
322
- return this.request<DiskSpaceResource[]>("/diskspace")
323
- }
324
-
325
- // Get system status (version, OS, runtime, etc.)
326
- async getSystemStatus(): Promise<SystemResource> {
327
- return this.request<SystemResource>("/system/status")
328
- }
329
-
330
- // Get all items in the download queue
331
- async getQueueDetails(includeUnknown = true): Promise<QueueResource[]> {
332
- const params = new URLSearchParams()
333
- if (includeUnknown) {
334
- params.set("includeUnknownMovieItems", "true")
335
- }
336
- const query = params.toString()
337
- return this.request<QueueResource[]>(`/queue/details${query ? `?${query}` : ""}`)
338
- }
339
-
340
- // Get queue status summary (counts, errors, warnings)
341
- async getQueueStatus(): Promise<QueueStatusResource> {
342
- return this.request<QueueStatusResource>("/queue/status")
343
- }
344
- }
345
-
346
- // Types for Host Config API
347
- export interface HostConfig {
348
- id: number
349
- bindAddress: string | null
350
- port: number
351
- sslPort: number
352
- enableSsl: boolean
353
- launchBrowser: boolean
354
- authenticationMethod: "none" | "basic" | "forms" | "external"
355
- authenticationRequired: "enabled" | "disabledForLocalAddresses"
356
- analyticsEnabled: boolean
357
- username: string | null
358
- password: string | null
359
- passwordConfirmation: string | null
360
- logLevel: string | null
361
- logSizeLimit: number
362
- consoleLogLevel: string | null
363
- branch: string | null
364
- apiKey: string | null
365
- sslCertPath: string | null
366
- sslCertPassword: string | null
367
- urlBase: string | null
368
- instanceName: string | null
369
- applicationUrl: string | null
370
- updateAutomatically: boolean
371
- updateMechanism: string
372
- updateScriptPath: string | null
373
- proxyEnabled: boolean
374
- proxyType: string
375
- proxyHostname: string | null
376
- proxyPort: number
377
- proxyUsername: string | null
378
- proxyPassword: string | null
379
- proxyBypassFilter: string | null
380
- proxyBypassLocalAddresses: boolean
381
- certificateValidation: string
382
- backupFolder: string | null
383
- backupInterval: number
384
- backupRetention: number
385
- trustCgnatIpAddresses: boolean
386
- }
387
-
388
- // ==========================================
389
- // Health Check & Status Types
390
- // ==========================================
391
-
392
- // Health check result types
393
- export type HealthCheckType = "ok" | "notice" | "warning" | "error"
394
-
395
- export interface HealthResource {
396
- id?: number
397
- source: string | null
398
- type: HealthCheckType
399
- message: string | null
400
- wikiUrl: string | null
401
- }
402
-
403
- // Disk space types
404
- export interface DiskSpaceResource {
405
- id?: number
406
- path: string | null
407
- label: string | null
408
- freeSpace: number // int64
409
- totalSpace: number // int64
410
- }
411
-
412
- // System status types
413
- export type RuntimeMode = "console" | "service" | "tray"
414
- export type DatabaseType = "sqLite" | "postgreSQL"
415
-
416
- export interface SystemResource {
417
- appName: string | null
418
- instanceName: string | null
419
- version: string | null
420
- buildTime: string | null
421
- isDebug: boolean
422
- isProduction: boolean
423
- isAdmin: boolean
424
- isUserInteractive: boolean
425
- startupPath: string | null
426
- appData: string | null
427
- osName: string | null
428
- osVersion: string | null
429
- isNetCore: boolean
430
- isLinux: boolean
431
- isOsx: boolean
432
- isWindows: boolean
433
- isDocker: boolean
434
- mode: RuntimeMode
435
- branch: string | null
436
- databaseType: DatabaseType
437
- databaseVersion: string | null
438
- authentication: "none" | "basic" | "forms" | "external"
439
- migrationVersion: number
440
- urlBase: string | null
441
- runtimeVersion: string | null
442
- runtimeName: string | null
443
- startTime: string | null
444
- }
445
-
446
- // Queue types
447
- export type QueueStatus =
448
- | "unknown"
449
- | "queued"
450
- | "paused"
451
- | "downloading"
452
- | "completed"
453
- | "failed"
454
- | "warning"
455
- | "delay"
456
- | "downloadClientUnavailable"
457
- | "fallback"
458
-
459
- export type TrackedDownloadStatus = "ok" | "warning" | "error"
460
- export type TrackedDownloadState =
461
- | "downloading"
462
- | "importBlocked"
463
- | "importPending"
464
- | "importing"
465
- | "imported"
466
- | "failedPending"
467
- | "failed"
468
- | "ignored"
469
-
470
- export interface QueueStatusMessage {
471
- title: string | null
472
- messages: string[] | null
473
- }
474
-
475
- export interface QueueResource {
476
- id?: number
477
- movieId?: number | null // Radarr
478
- seriesId?: number | null // Sonarr
479
- artistId?: number | null // Lidarr
480
- authorId?: number | null // Readarr
481
- title: string | null
482
- size: number
483
- sizeleft?: number
484
- timeleft?: string | null
485
- estimatedCompletionTime: string | null
486
- added: string | null
487
- status: QueueStatus
488
- trackedDownloadStatus: TrackedDownloadStatus
489
- trackedDownloadState: TrackedDownloadState
490
- statusMessages?: QueueStatusMessage[] | null
491
- errorMessage: string | null
492
- downloadId: string | null
493
- protocol: "unknown" | "usenet" | "torrent"
494
- downloadClient: string | null
495
- indexer: string | null
496
- outputPath: string | null
497
- }
498
-
499
- export interface QueueStatusResource {
500
- id?: number
501
- totalCount: number
502
- count: number
503
- unknownCount: number
504
- errors: boolean
505
- warnings: boolean
506
- unknownErrors: boolean
507
- unknownWarnings: boolean
508
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * Auto-Setup Types
3
- * Interfaces for auto-setup capability metadata and clients
4
- */
5
-
6
- import type { AppId } from "../config/schema"
7
-
8
- /**
9
- * Describes an app's auto-setup capability
10
- */
11
- export interface AutoSetupCapability {
12
- /** Type of auto-setup support */
13
- type: "full" | "partial" | "manual"
14
- /** Human-readable description of what gets configured */
15
- description: string
16
- /** Other apps that must be set up first */
17
- requires?: AppId[]
18
- /** Environment variables required for setup */
19
- envVars?: string[]
20
- /** Setup function name in FullAutoSetup (for dynamic discovery) */
21
- setupMethod?: string
22
- }
23
-
24
- /**
25
- * Result of an auto-setup operation
26
- */
27
- export interface AutoSetupResult {
28
- success: boolean
29
- message?: string
30
- /** Data to persist (e.g., API keys, tokens) */
31
- envUpdates?: Record<string, string>
32
- /** Additional result data (e.g., API keys, generated credentials) */
33
- data?: Record<string, unknown>
34
- }
35
-
36
- /**
37
- * Base interface for auto-setup clients
38
- */
39
- export interface IAutoSetupClient {
40
- /** Check if service is reachable */
41
- isHealthy(): Promise<boolean>
42
-
43
- /** Check if service is already configured */
44
- isInitialized(): Promise<boolean>
45
-
46
- /** Run the auto-setup process */
47
- setup(options: AutoSetupOptions): Promise<AutoSetupResult>
48
- }
49
-
50
- /**
51
- * Common options for auto-setup
52
- */
53
- export interface AutoSetupOptions {
54
- /** Global username for auth */
55
- username: string
56
- /** Global password for auth */
57
- password: string
58
- /** Environment variables available */
59
- env: Record<string, string>
60
- /** Plex authentication token (for Plex-dependent services) */
61
- plexToken?: string
62
- /** List of enabled app IDs (for smart library/config creation) */
63
- enabledApps?: AppId[]
64
- }