Refactor arr routes: explicit dependency injection
- Updated all arr route modules to use destructured dependencies - Added JSDoc comments for factory functions - Replaced ctx. references with direct parameter access - Updated arr/index.js to extract and pass explicit dependencies - Maintained backward compatibility with context pattern - All files pass syntax validation Files refactored: - routes/arr/detect.js - routes/arr/credentials.js - routes/arr/config.js (579 lines) - routes/arr/smart-connect.js - routes/arr/plex.js - routes/arr/helpers.js - routes/arr/index.js (orchestrator)
This commit is contained in:
@@ -1,12 +1,23 @@
|
||||
const express = require('express');
|
||||
const { APP_PORTS, ARR_SERVICES } = require('../../constants');
|
||||
|
||||
module.exports = function(ctx, helpers) {
|
||||
/**
|
||||
* Arr service detection routes factory
|
||||
* @param {Object} deps - Explicit dependencies
|
||||
* @param {Object} deps.docker - Docker client wrapper
|
||||
* @param {Object} deps.servicesStateManager - Services state manager
|
||||
* @param {Object} deps.credentialManager - Credential manager
|
||||
* @param {Function} deps.fetchT - Timeout-wrapped fetch
|
||||
* @param {Function} deps.asyncHandler - Async route handler wrapper
|
||||
* @param {Object} deps.helpers - Arr helpers module
|
||||
* @returns {express.Router}
|
||||
*/
|
||||
module.exports = function({ docker, servicesStateManager, credentialManager, fetchT, asyncHandler, helpers }) {
|
||||
const router = express.Router();
|
||||
|
||||
// Detect running arr services and their configurations
|
||||
router.get('/arr/detect', ctx.asyncHandler(async (req, res) => {
|
||||
const containers = await ctx.docker.client.listContainers({ all: false });
|
||||
router.get('/arr/detect', asyncHandler(async (req, res) => {
|
||||
const containers = await docker.client.listContainers({ all: false });
|
||||
const detected = {
|
||||
plex: null,
|
||||
radarr: null,
|
||||
@@ -64,14 +75,14 @@ module.exports = function(ctx, helpers) {
|
||||
}, 'arr-detect'));
|
||||
|
||||
// Smart Detect: Unified discovery of all arr services
|
||||
router.get('/arr/smart-detect', ctx.asyncHandler(async (req, res) => {
|
||||
router.get('/arr/smart-detect', asyncHandler(async (req, res) => {
|
||||
const serviceList = ['plex', 'radarr', 'sonarr', 'prowlarr', 'seerr'];
|
||||
const defaultPorts = APP_PORTS;
|
||||
const result = {};
|
||||
|
||||
// 1. Scan Docker containers
|
||||
let containers = [];
|
||||
try { containers = await ctx.docker.client.listContainers({ all: false }); } catch (e) { /* Docker not available */ }
|
||||
try { containers = await docker.client.listContainers({ all: false }); } catch (e) { /* Docker not available */ }
|
||||
|
||||
const servicePatterns = ARR_SERVICES;
|
||||
|
||||
@@ -95,18 +106,18 @@ module.exports = function(ctx, helpers) {
|
||||
// 2. Load services.json for external entries
|
||||
let storedServices = [];
|
||||
try {
|
||||
const data = await ctx.servicesStateManager.read();
|
||||
const data = await servicesStateManager.read();
|
||||
storedServices = Array.isArray(data) ? data : data.services || [];
|
||||
} catch (e) { /* ignore */ }
|
||||
|
||||
// 3. Load stored credentials
|
||||
const storedCreds = {};
|
||||
const seedboxBaseUrl = await ctx.credentialManager.retrieve('arr.seedbox.baseurl');
|
||||
const seedboxBaseUrl = await credentialManager.retrieve('arr.seedbox.baseurl');
|
||||
|
||||
for (const svc of serviceList) {
|
||||
const credKey = svc === 'plex' ? 'arr.plex.token' : `arr.${svc}.apikey`;
|
||||
const apiKey = await ctx.credentialManager.retrieve(credKey);
|
||||
const metadata = await ctx.credentialManager.getMetadata(credKey);
|
||||
const apiKey = await credentialManager.retrieve(credKey);
|
||||
const metadata = await credentialManager.getMetadata(credKey);
|
||||
if (apiKey) {
|
||||
storedCreds[svc] = { apiKey, metadata };
|
||||
}
|
||||
@@ -141,7 +152,7 @@ module.exports = function(ctx, helpers) {
|
||||
entry.hasToken = true;
|
||||
entry.status = 'connected';
|
||||
// Store for later use
|
||||
await ctx.credentialManager.store('arr.plex.token', token, {
|
||||
await credentialManager.store('arr.plex.token', token, {
|
||||
service: 'plex', source: 'local', url: entry.url,
|
||||
lastVerified: new Date().toISOString()
|
||||
});
|
||||
@@ -158,7 +169,7 @@ module.exports = function(ctx, helpers) {
|
||||
entry.hasApiKey = true;
|
||||
const configuredServices = { radarr: false, sonarr: false, plex: false };
|
||||
try {
|
||||
const radarrCheck = await ctx.fetchT(`http://host.docker.internal:${dc.port}/api/v1/settings/radarr`, {
|
||||
const radarrCheck = await fetchT(`http://host.docker.internal:${dc.port}/api/v1/settings/radarr`, {
|
||||
headers: { 'Cookie': session.cookie },
|
||||
signal: AbortSignal.timeout(5000)
|
||||
});
|
||||
@@ -168,7 +179,7 @@ module.exports = function(ctx, helpers) {
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
try {
|
||||
const sonarrCheck = await ctx.fetchT(`http://host.docker.internal:${dc.port}/api/v1/settings/sonarr`, {
|
||||
const sonarrCheck = await fetchT(`http://host.docker.internal:${dc.port}/api/v1/settings/sonarr`, {
|
||||
headers: { 'Cookie': session.cookie },
|
||||
signal: AbortSignal.timeout(5000)
|
||||
});
|
||||
@@ -178,7 +189,7 @@ module.exports = function(ctx, helpers) {
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
try {
|
||||
const plexCheck = await ctx.fetchT(`http://host.docker.internal:${dc.port}/api/v1/settings/plex`, {
|
||||
const plexCheck = await fetchT(`http://host.docker.internal:${dc.port}/api/v1/settings/plex`, {
|
||||
headers: { 'Cookie': session.cookie },
|
||||
signal: AbortSignal.timeout(5000)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user