/** * Move validation utilities for S3 objects */ export interface IMoveValidation { valid: boolean; error?: string; } /** * Validates if a move operation is allowed * @param sourceKey The source object key (file or folder with trailing /) * @param destPrefix The destination prefix (folder) * @returns Validation result with error message if invalid */ export function validateMove(sourceKey: string, destPrefix: string): IMoveValidation { // Check: Moving folder into itself or a subfolder of itself if (sourceKey.endsWith('/')) { // It's a folder - check if destPrefix starts with sourceKey if (destPrefix.startsWith(sourceKey)) { return { valid: false, error: 'Cannot move a folder into itself' }; } } // Check: Source and dest are the same location const sourceParent = getParentPrefix(sourceKey); if (sourceParent === destPrefix) { return { valid: false, error: 'Item is already in this location' }; } return { valid: true }; } /** * Gets the parent prefix (directory) of a given key * @param key The object key (file or folder) * @returns The parent prefix */ export function getParentPrefix(key: string): string { // "folder1/folder2/file.txt" -> "folder1/folder2/" // "folder1/folder2/" -> "folder1/" // "file.txt" -> "" // "folder/" -> "" const trimmed = key.endsWith('/') ? key.slice(0, -1) : key; const lastSlash = trimmed.lastIndexOf('/'); return lastSlash >= 0 ? trimmed.substring(0, lastSlash + 1) : ''; }