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