const { Errors } = require('../../shared') const { NodeDescriptorType } = require('../../enum') module.exports = exports = async (message, di) => { const Node = di.models.get('fs:Node') const { source, destination } = message.data() if ( !source ) { return message.send_response( message.fresh().error(Errors.NodeDoesNotExist) ) } if ( source === '/' ) { return message.send_response( message.fresh.error(Errors.NodePermissionFail) ) } const node = await Node.get_path(source, message.socket.session.overlay_name || 'mainline') if ( !node ) { return message.send_response( message.fresh().error(Errors.NodeDoesNotExist) ) } // make sure the move-to destination is valid const [pied_parent_path, pied_name] = Node.path_parts(destination) if ( pied_parent_path !== '/' ) { const parent_node = await Node.get_path(pied_parent_path, message.socket.session.overlay_name || 'mainline') if ( !parent_node ) { return message.send_response( message.fresh().error(Errors.NodeDoesNotExist) ) } if ( parent_node.descriptor_type !== NodeDescriptorType.Directory ) { return message.send_response( message.fresh().error(Errors.NotDirectoryDescriptor) ) } } const existing_target = await Node.get_path(destination, message.socket.session.overlay_name || 'mainline') if ( existing_target ) { // If we're moving to an existing target, overwrite that target const all_desc = await existing_target.all_descendants(message.socket.session.overlay_name || 'mainline') await Promise.all(all_desc.map(desc => { desc.deleted = true return desc.save() })) existing_target.deleted = true await existing_target.save() } const moved_desc = await node.all_descendants(message.socket.session.overlay_name || 'mainline') await Promise.all(moved_desc.map(moved_node => { moved_node.pied_parent_path = moved_node.pied_parent_path.replace(source, destination) return moved_node.save() })) node.pied_parent_path = pied_parent_path node.pied_name = pied_name await node.save() message.send_response( message.fresh() ) }