refactor: Update response format for backward compatibility
This commit is contained in:
@@ -5,7 +5,6 @@ import { VIDEOS_DIR } from "../config/paths";
|
||||
import { ValidationError } from "../errors/DownloadErrors";
|
||||
import * as storageService from "../services/storageService";
|
||||
import { logger } from "../utils/logger";
|
||||
import { successResponse } from "../utils/response";
|
||||
|
||||
/**
|
||||
* Clean up temporary download files (.ytdl, .part)
|
||||
@@ -67,13 +66,9 @@ export const cleanupTempFiles = async (
|
||||
// Start cleanup from VIDEOS_DIR
|
||||
await cleanupDirectory(VIDEOS_DIR);
|
||||
|
||||
res.status(200).json(
|
||||
successResponse(
|
||||
{
|
||||
deletedCount,
|
||||
...(errors.length > 0 && { errors }),
|
||||
},
|
||||
`Cleaned up ${deletedCount} temporary files`
|
||||
)
|
||||
);
|
||||
// Return format expected by frontend: { deletedCount, errors? }
|
||||
res.status(200).json({
|
||||
deletedCount,
|
||||
...(errors.length > 0 && { errors }),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,23 +2,26 @@ import { Request, Response } from "express";
|
||||
import { NotFoundError, ValidationError } from "../errors/DownloadErrors";
|
||||
import * as storageService from "../services/storageService";
|
||||
import { Collection } from "../services/storageService";
|
||||
import { successMessage, successResponse } from "../utils/response";
|
||||
import { successMessage } from "../utils/response";
|
||||
|
||||
/**
|
||||
* Get all collections
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns array directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getCollections = async (
|
||||
_req: Request,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
const collections = storageService.getCollections();
|
||||
res.json(successResponse(collections));
|
||||
// Return array directly for backward compatibility (frontend expects response.data to be Collection[])
|
||||
res.json(collections);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new collection
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns collection object directly for backward compatibility with frontend
|
||||
*/
|
||||
export const createCollection = async (
|
||||
req: Request,
|
||||
@@ -49,19 +52,20 @@ export const createCollection = async (
|
||||
videoId
|
||||
);
|
||||
if (updatedCollection) {
|
||||
res
|
||||
.status(201)
|
||||
.json(successResponse(updatedCollection, "Collection created"));
|
||||
// Return collection object directly for backward compatibility
|
||||
res.status(201).json(updatedCollection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
res.status(201).json(successResponse(newCollection, "Collection created"));
|
||||
// Return collection object directly for backward compatibility
|
||||
res.status(201).json(newCollection);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a collection
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns collection object directly for backward compatibility with frontend
|
||||
*/
|
||||
export const updateCollection = async (
|
||||
req: Request,
|
||||
@@ -102,7 +106,8 @@ export const updateCollection = async (
|
||||
throw new NotFoundError("Collection", id);
|
||||
}
|
||||
|
||||
res.json(successResponse(updatedCollection));
|
||||
// Return collection object directly for backward compatibility
|
||||
res.json(updatedCollection);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Request, Response } from "express";
|
||||
import downloadManager from "../services/downloadManager";
|
||||
import * as storageService from "../services/storageService";
|
||||
import { successMessage, successResponse } from "../utils/response";
|
||||
import { successMessage } from "../utils/response";
|
||||
|
||||
/**
|
||||
* Cancel a download
|
||||
@@ -44,13 +44,15 @@ export const clearQueue = async (
|
||||
/**
|
||||
* Get download history
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns array directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getDownloadHistory = async (
|
||||
_req: Request,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
const history = storageService.getDownloadHistory();
|
||||
res.status(200).json(successResponse(history));
|
||||
// Return array directly for backward compatibility (frontend expects response.data to be DownloadHistoryItem[])
|
||||
res.status(200).json(history);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -234,5 +234,6 @@ export const scanFiles = async (
|
||||
const message = `Scan complete. Added ${addedCount} new videos. Deleted ${deletedCount} missing videos.`;
|
||||
logger.info(message);
|
||||
|
||||
res.status(200).json(successResponse({ addedCount, deletedCount }, message));
|
||||
// Return format expected by frontend: { addedCount, deletedCount }
|
||||
res.status(200).json({ addedCount, deletedCount });
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import { NotFoundError, ValidationError } from "../errors/DownloadErrors";
|
||||
import downloadManager from "../services/downloadManager";
|
||||
import * as storageService from "../services/storageService";
|
||||
import { logger } from "../utils/logger";
|
||||
import { successMessage, successResponse } from "../utils/response";
|
||||
import { successMessage } from "../utils/response";
|
||||
|
||||
interface Settings {
|
||||
loginEnabled: boolean;
|
||||
@@ -57,6 +57,7 @@ const defaultSettings: Settings = {
|
||||
/**
|
||||
* Get application settings
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns data directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getSettings = async (
|
||||
_req: Request,
|
||||
@@ -67,7 +68,8 @@ export const getSettings = async (
|
||||
// If empty (first run), save defaults
|
||||
if (Object.keys(settings).length === 0) {
|
||||
storageService.saveSettings(defaultSettings);
|
||||
res.json(successResponse(defaultSettings));
|
||||
// Return data directly for backward compatibility
|
||||
res.json(defaultSettings);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -76,7 +78,8 @@ export const getSettings = async (
|
||||
|
||||
// Do not send the hashed password to the frontend
|
||||
const { password, ...safeSettings } = mergedSettings;
|
||||
res.json(successResponse({ ...safeSettings, isPasswordSet: !!password }));
|
||||
// Return data directly for backward compatibility
|
||||
res.json({ ...safeSettings, isPasswordSet: !!password });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -89,7 +92,8 @@ export const migrateData = async (
|
||||
): Promise<void> => {
|
||||
const { runMigration } = await import("../services/migrationService");
|
||||
const results = await runMigration();
|
||||
res.json(successResponse(results, "Migration completed"));
|
||||
// Return format expected by frontend: { results: {...} }
|
||||
res.json({ results });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -128,7 +132,8 @@ export const deleteLegacyData = async (
|
||||
}
|
||||
}
|
||||
|
||||
res.json(successResponse(results, "Legacy data deletion completed"));
|
||||
// Return format expected by frontend: { results: { deleted: [], failed: [] } }
|
||||
res.json({ results });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -140,7 +145,8 @@ export const formatFilenames = async (
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
const results = storageService.formatLegacyFilenames();
|
||||
res.json(successResponse(results, "Filenames formatted"));
|
||||
// Return format expected by frontend: { results: {...} }
|
||||
res.json({ results });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -236,9 +242,11 @@ export const updateSettings = async (
|
||||
// Apply settings immediately where possible
|
||||
downloadManager.setMaxConcurrentDownloads(newSettings.maxConcurrentDownloads);
|
||||
|
||||
res.json(
|
||||
successResponse({ ...newSettings, password: undefined }, "Settings updated")
|
||||
);
|
||||
// Return format expected by frontend: { success: true, settings: {...} }
|
||||
res.json({
|
||||
success: true,
|
||||
settings: { ...newSettings, password: undefined },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -255,7 +263,8 @@ export const getPasswordEnabled = async (
|
||||
// Return true only if login is enabled AND a password is set
|
||||
const isEnabled = mergedSettings.loginEnabled && !!mergedSettings.password;
|
||||
|
||||
res.json(successResponse({ enabled: isEnabled }));
|
||||
// Return format expected by frontend: { enabled: boolean }
|
||||
res.json({ enabled: isEnabled });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -272,20 +281,23 @@ export const verifyPassword = async (
|
||||
const mergedSettings = { ...defaultSettings, ...settings };
|
||||
|
||||
if (!mergedSettings.loginEnabled) {
|
||||
res.json(successResponse({ verified: true }));
|
||||
// Return format expected by frontend: { success: boolean }
|
||||
res.json({ success: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mergedSettings.password) {
|
||||
// If no password set but login enabled, allow access
|
||||
res.json(successResponse({ verified: true }));
|
||||
// Return format expected by frontend: { success: boolean }
|
||||
res.json({ success: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const isMatch = await bcrypt.compare(password, mergedSettings.password);
|
||||
|
||||
if (isMatch) {
|
||||
res.json(successResponse({ verified: true }));
|
||||
// Return format expected by frontend: { success: boolean }
|
||||
res.json({ success: true });
|
||||
} else {
|
||||
throw new ValidationError("Incorrect password", "password");
|
||||
}
|
||||
@@ -332,7 +344,8 @@ export const checkCookies = async (
|
||||
const { DATA_DIR } = require("../config/paths");
|
||||
const cookiesPath = path.join(DATA_DIR, "cookies.txt");
|
||||
const exists = fs.existsSync(cookiesPath);
|
||||
res.json(successResponse({ exists }));
|
||||
// Return format expected by frontend: { exists: boolean }
|
||||
res.json({ exists });
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Request, Response } from "express";
|
||||
import { ValidationError } from "../errors/DownloadErrors";
|
||||
import { subscriptionService } from "../services/subscriptionService";
|
||||
import { logger } from "../utils/logger";
|
||||
import { successMessage, successResponse } from "../utils/response";
|
||||
import { successMessage } from "../utils/response";
|
||||
|
||||
/**
|
||||
* Create a new subscription
|
||||
@@ -23,19 +23,22 @@ export const createSubscription = async (
|
||||
url,
|
||||
parseInt(interval)
|
||||
);
|
||||
res.status(201).json(successResponse(subscription, "Subscription created"));
|
||||
// Return subscription object directly for backward compatibility
|
||||
res.status(201).json(subscription);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all subscriptions
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns array directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getSubscriptions = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
const subscriptions = await subscriptionService.listSubscriptions();
|
||||
res.json(successResponse(subscriptions));
|
||||
// Return array directly for backward compatibility (frontend expects response.data to be Subscription[])
|
||||
res.json(subscriptions);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,7 @@ export const upload = multer({ storage: storage });
|
||||
/**
|
||||
* Search for videos
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns { results } format for backward compatibility with frontend
|
||||
*/
|
||||
export const searchVideos = async (
|
||||
req: Request,
|
||||
@@ -57,7 +58,8 @@ export const searchVideos = async (
|
||||
limit,
|
||||
offset
|
||||
);
|
||||
res.status(200).json(successResponse({ results }));
|
||||
// Return { results } format for backward compatibility (frontend expects response.data.results)
|
||||
res.status(200).json({ results });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -85,7 +87,8 @@ export const checkVideoDownloadStatus = async (
|
||||
const { id: sourceVideoId, platform } = extractSourceVideoId(videoUrl);
|
||||
|
||||
if (!sourceVideoId) {
|
||||
res.status(200).json(successResponse({ found: false }));
|
||||
// Return object directly for backward compatibility (frontend expects response.data.found)
|
||||
res.status(200).json({ found: false });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,47 +103,45 @@ export const checkVideoDownloadStatus = async (
|
||||
if (!existingVideo) {
|
||||
// Video was deleted but not marked in download history, update it
|
||||
storageService.markVideoDownloadDeleted(downloadCheck.videoId);
|
||||
res.status(200).json(
|
||||
successResponse({
|
||||
found: true,
|
||||
status: "deleted",
|
||||
title: downloadCheck.title,
|
||||
author: downloadCheck.author,
|
||||
downloadedAt: downloadCheck.downloadedAt,
|
||||
})
|
||||
);
|
||||
// Return object directly for backward compatibility
|
||||
res.status(200).json({
|
||||
found: true,
|
||||
status: "deleted",
|
||||
title: downloadCheck.title,
|
||||
author: downloadCheck.author,
|
||||
downloadedAt: downloadCheck.downloadedAt,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json(
|
||||
successResponse({
|
||||
found: true,
|
||||
status: "exists",
|
||||
videoId: downloadCheck.videoId,
|
||||
title: downloadCheck.title || existingVideo.title,
|
||||
author: downloadCheck.author || existingVideo.author,
|
||||
downloadedAt: downloadCheck.downloadedAt,
|
||||
videoPath: existingVideo.videoPath,
|
||||
thumbnailPath: existingVideo.thumbnailPath,
|
||||
})
|
||||
);
|
||||
// Return object directly for backward compatibility
|
||||
res.status(200).json({
|
||||
found: true,
|
||||
status: "exists",
|
||||
videoId: downloadCheck.videoId,
|
||||
title: downloadCheck.title || existingVideo.title,
|
||||
author: downloadCheck.author || existingVideo.author,
|
||||
downloadedAt: downloadCheck.downloadedAt,
|
||||
videoPath: existingVideo.videoPath,
|
||||
thumbnailPath: existingVideo.thumbnailPath,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json(
|
||||
successResponse({
|
||||
found: true,
|
||||
status: downloadCheck.status,
|
||||
title: downloadCheck.title,
|
||||
author: downloadCheck.author,
|
||||
downloadedAt: downloadCheck.downloadedAt,
|
||||
deletedAt: downloadCheck.deletedAt,
|
||||
})
|
||||
);
|
||||
// Return object directly for backward compatibility
|
||||
res.status(200).json({
|
||||
found: true,
|
||||
status: downloadCheck.status,
|
||||
title: downloadCheck.title,
|
||||
author: downloadCheck.author,
|
||||
downloadedAt: downloadCheck.downloadedAt,
|
||||
deletedAt: downloadCheck.deletedAt,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json(successResponse({ found: false }));
|
||||
// Return object directly for backward compatibility
|
||||
res.status(200).json({ found: false });
|
||||
};
|
||||
|
||||
// Download video
|
||||
@@ -476,18 +477,21 @@ export const downloadVideo = async (
|
||||
/**
|
||||
* Get all videos
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns array directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getVideos = async (
|
||||
_req: Request,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
const videos = storageService.getVideos();
|
||||
res.status(200).json(successResponse(videos));
|
||||
// Return array directly for backward compatibility (frontend expects response.data to be Video[])
|
||||
res.status(200).json(videos);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get video by ID
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns video object directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getVideoById = async (
|
||||
req: Request,
|
||||
@@ -500,7 +504,8 @@ export const getVideoById = async (
|
||||
throw new NotFoundError("Video", id);
|
||||
}
|
||||
|
||||
res.status(200).json(successResponse(video));
|
||||
// Return video object directly for backward compatibility (frontend expects response.data to be Video)
|
||||
res.status(200).json(video);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -524,6 +529,7 @@ export const deleteVideo = async (
|
||||
/**
|
||||
* Get download status
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns status object directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getDownloadStatus = async (
|
||||
_req: Request,
|
||||
@@ -540,7 +546,8 @@ export const getDownloadStatus = async (
|
||||
}
|
||||
});
|
||||
}
|
||||
res.status(200).json(successResponse(status));
|
||||
// Return status object directly for backward compatibility (frontend expects response.data to be DownloadStatus)
|
||||
res.status(200).json(status);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -580,7 +587,8 @@ export const checkBilibiliParts = async (
|
||||
|
||||
const result = await downloadService.checkBilibiliVideoParts(videoId);
|
||||
|
||||
res.status(200).json(successResponse(result));
|
||||
// Return result object directly for backward compatibility (frontend expects response.data.success, response.data.videosNumber)
|
||||
res.status(200).json(result);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -621,12 +629,14 @@ export const checkBilibiliCollection = async (
|
||||
// Check if it's a collection or series
|
||||
const result = await downloadService.checkBilibiliCollectionOrSeries(videoId);
|
||||
|
||||
res.status(200).json(successResponse(result));
|
||||
// Return result object directly for backward compatibility (frontend expects response.data.success, response.data.type)
|
||||
res.status(200).json(result);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get video comments
|
||||
* Errors are automatically handled by asyncHandler middleware
|
||||
* Note: Returns comments array directly for backward compatibility with frontend
|
||||
*/
|
||||
export const getVideoComments = async (
|
||||
req: Request,
|
||||
@@ -636,7 +646,8 @@ export const getVideoComments = async (
|
||||
const comments = await import("../services/commentService").then((m) =>
|
||||
m.getComments(id)
|
||||
);
|
||||
res.status(200).json(successResponse(comments));
|
||||
// Return comments array directly for backward compatibility (frontend expects response.data to be Comment[])
|
||||
res.status(200).json(comments);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -741,9 +752,11 @@ export const rateVideo = async (req: Request, res: Response): Promise<void> => {
|
||||
throw new NotFoundError("Video", id);
|
||||
}
|
||||
|
||||
res
|
||||
.status(200)
|
||||
.json(successResponse({ video: updatedVideo }, "Video rated successfully"));
|
||||
// Return format expected by frontend: { success: true, video: ... }
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
video: updatedVideo,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -773,11 +786,11 @@ export const updateVideoDetails = async (
|
||||
throw new NotFoundError("Video", id);
|
||||
}
|
||||
|
||||
res
|
||||
.status(200)
|
||||
.json(
|
||||
successResponse({ video: updatedVideo }, "Video updated successfully")
|
||||
);
|
||||
// Return format expected by frontend: { success: true, video: ... }
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
video: updatedVideo,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -864,11 +877,11 @@ export const refreshThumbnail = async (
|
||||
// Return success with timestamp to bust cache
|
||||
const thumbnailUrl = `${newThumbnailPath}?t=${Date.now()}`;
|
||||
|
||||
res
|
||||
.status(200)
|
||||
.json(
|
||||
successResponse({ thumbnailUrl }, "Thumbnail refreshed successfully")
|
||||
);
|
||||
// Return format expected by frontend: { success: true, thumbnailUrl: ... }
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
thumbnailUrl,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -892,11 +905,11 @@ export const incrementViewCount = async (
|
||||
lastPlayedAt: Date.now(),
|
||||
});
|
||||
|
||||
res.status(200).json(
|
||||
successResponse({
|
||||
viewCount: updatedVideo?.viewCount,
|
||||
})
|
||||
);
|
||||
// Return format expected by frontend: { success: true, viewCount: ... }
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
viewCount: updatedVideo?.viewCount,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user