@muhammedaksam/easiarr 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/index.js +29750 -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
@@ -1,216 +0,0 @@
1
- import { mkdir } from "node:fs/promises"
2
- import { dirname } from "node:path"
3
-
4
- import {
5
- BoxOptions,
6
- BoxRenderable,
7
- CliRenderer,
8
- InputRenderable,
9
- KeyEvent,
10
- RenderContext,
11
- RGBA,
12
- TextRenderable,
13
- } from "@opentui/core"
14
-
15
- import { getApp } from "~/apps/registry"
16
- import { AppSecret, EasiarrConfig } from "~/config/schema"
17
- import { getEnvPath, readEnv, updateEnv } from "~/utils/env"
18
-
19
- export interface SecretsEditorOptions extends BoxOptions {
20
- config: EasiarrConfig
21
- onSave: () => void
22
- onCancel: () => void
23
- extraEnv?: Record<string, { value: string; description: string }>
24
- }
25
-
26
- export class SecretsEditor extends BoxRenderable {
27
- private inputs: Map<string, InputRenderable> = new Map()
28
- private secrets: Map<string, AppSecret> = new Map()
29
- private currentFocusIndex = 0
30
- private inputKeys: string[] = []
31
- private config: EasiarrConfig
32
- private onSave: () => void
33
- private onCancel: () => void
34
- private extraEnv: Record<string, { value: string; description: string }> = {}
35
- private envValues: Record<string, string> = {}
36
- private renderer: CliRenderer
37
- private keyHandler: ((k: KeyEvent) => void) | null = null
38
-
39
- constructor(renderer: CliRenderer | RenderContext, options: SecretsEditorOptions) {
40
- super(renderer, {
41
- ...options,
42
- border: true,
43
- borderStyle: "double",
44
- title: "Secrets Manager (.env)",
45
- titleAlignment: "center",
46
- backgroundColor: RGBA.fromHex("#1a1a1a"), // Dark background
47
- })
48
-
49
- this.renderer = renderer as CliRenderer
50
- this.config = options.config
51
- this.onSave = options.onSave
52
- this.onCancel = options.onCancel
53
- this.extraEnv = options.extraEnv || {}
54
-
55
- this.initSecrets()
56
- }
57
-
58
- private async initSecrets() {
59
- // 0. Add Extra Env (System Config)
60
- for (const [key, info] of Object.entries(this.extraEnv)) {
61
- this.secrets.set(key, {
62
- name: key,
63
- description: info.description,
64
- default: info.value,
65
- required: true,
66
- })
67
- }
68
-
69
- // 1. Collect Secrets from Enabled Apps
70
- for (const appConfig of this.config.apps) {
71
- if (!appConfig.enabled) continue
72
- const appDef = getApp(appConfig.id)
73
- if (appDef && appDef.secrets) {
74
- for (const secret of appDef.secrets) {
75
- if (!this.secrets.has(secret.name)) {
76
- this.secrets.set(secret.name, secret)
77
- }
78
- }
79
- }
80
- }
81
-
82
- if (this.secrets.size === 0) {
83
- this.add(
84
- new TextRenderable(this.renderer as CliRenderer, {
85
- content: "No secrets required for selected apps.",
86
- left: 2,
87
- top: 2,
88
- })
89
- )
90
- // Add Exit hint
91
- this.add(
92
- new TextRenderable(this.renderer as CliRenderer, {
93
- content: "Press ESC to return",
94
- bottom: 1,
95
- left: 2,
96
- })
97
- )
98
- return
99
- }
100
-
101
- // 2. Load existing .env
102
- await this.loadEnv()
103
-
104
- // 3. Render Inputs
105
- const container = new BoxRenderable(this.renderer as CliRenderer, {
106
- width: "100%",
107
- flexDirection: "column",
108
- padding: 1,
109
- })
110
- this.add(container)
111
-
112
- this.secrets.forEach((secret, key) => {
113
- const row = new BoxRenderable(this.renderer as CliRenderer, {
114
- width: "100%",
115
- height: 1,
116
- flexDirection: "row",
117
- marginBottom: 1,
118
- })
119
-
120
- // Label
121
- const label = new TextRenderable(this.renderer as CliRenderer, {
122
- content: `${secret.name}${secret.required ? "*" : ""}:`.padEnd(30),
123
- width: 30,
124
- fg: secret.required ? RGBA.fromHex("#ff5555") : RGBA.fromHex("#aaaaaa"),
125
- })
126
- row.add(label)
127
-
128
- // Input
129
- const input = new InputRenderable(this.renderer as CliRenderer, {
130
- id: `input-${key}`,
131
- width: 60, // Wider for paths
132
- placeholder: secret.description,
133
- backgroundColor: RGBA.fromHex("#333333"),
134
- focusedBackgroundColor: RGBA.fromHex("#444444"),
135
- textColor: RGBA.fromHex("#ffffff"),
136
- })
137
-
138
- // Prefer envValue > default > empty
139
- input.value = this.envValues[key] || secret.default || ""
140
-
141
- row.add(input)
142
- container.add(row)
143
-
144
- this.inputs.set(key, input)
145
- this.inputKeys.push(key)
146
- })
147
-
148
- // Instructions
149
- this.add(
150
- new TextRenderable(this.renderer as CliRenderer, {
151
- content: "TAB: Next Field | CTRL+S: Save | ESC: Cancel",
152
- bottom: 0,
153
- left: 2,
154
- width: "100%",
155
- })
156
- )
157
-
158
- // Global Key Handling (intercept Tab, Enter, Esc, Ctrl+S)
159
- this.keyHandler = (k: KeyEvent) => {
160
- // Allow inputs to handle typing, but intercept navigation/actions
161
- if (k.name === "tab") {
162
- // k.preventDefault() // Prevent Input from adding tab char?
163
- this.focusNext()
164
- } else if (k.name === "s" && k.ctrl) {
165
- // k.preventDefault()
166
- this.save()
167
- } else if (k.name === "escape") {
168
- this.onCancel()
169
- }
170
- }
171
- this.renderer.keyInput.on("keypress", this.keyHandler)
172
-
173
- // Focus first
174
- if (this.inputKeys.length > 0) {
175
- this.inputs.get(this.inputKeys[0])?.focus()
176
- }
177
- }
178
-
179
- private async loadEnv() {
180
- this.envValues = await readEnv()
181
- }
182
-
183
- private async save() {
184
- // Collect values from inputs
185
- const updates: Record<string, string> = {}
186
- this.inputs.forEach((input, key) => {
187
- updates[key] = input.value
188
- })
189
-
190
- // Ensure directory exists
191
- try {
192
- await mkdir(dirname(getEnvPath()), { recursive: true })
193
- } catch {
194
- // Ignore if exists
195
- }
196
-
197
- // Update .env file
198
- await updateEnv(updates)
199
-
200
- this.onSave()
201
- }
202
-
203
- override destroy(): void {
204
- if (this.keyHandler) {
205
- this.renderer.keyInput.off("keypress", this.keyHandler)
206
- this.keyHandler = null
207
- }
208
- super.destroy()
209
- }
210
-
211
- private focusNext() {
212
- this.currentFocusIndex = (this.currentFocusIndex + 1) % this.inputKeys.length
213
- const key = this.inputKeys[this.currentFocusIndex]
214
- this.inputs.get(key)?.focus()
215
- }
216
- }