All files / src/api/repositories/mongoose deviceRepository.ts

0% Statements 0/38
0% Branches 0/21
0% Functions 0/9
0% Lines 0/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                                                                                                                                                         
import mongoose from 'mongoose';
import { Device } from '../../models/device';
import { DeviceRepository } from '../../interfaces/deviceRepository';
 
const deviceSchema = new mongoose.Schema({
  type: { type: String, required: true },
  name: { type: String, required: true },
  macAddress: { type: String, required: true, unique: true },
  _deactivate: { type: Boolean, required: false },
  location: {
    floor_id: { type: String, required: false },
    x: { type: Number, required: false },
    y: { type: Number, required: false },
  },
});
 
const DeviceModel = mongoose.model('Device', deviceSchema);
 
function removeEmpty(obj: any): any {
  Iif (obj === null || obj === undefined) return undefined;
  Iif (typeof obj !== 'object') return obj;
 
  const entries = Object.entries(obj)
    .map(([k, v]) => [k, removeEmpty(v)])
    // Only remove if value is undefined or null, NOT if it's false or 0
    .filter(([_, v]) => v !== undefined && v !== null && (typeof v !== 'object' || Object.keys(v).length > 0));
 
  return Object.fromEntries(entries);
}
 
export class MongooseDeviceRepository implements DeviceRepository {
  private toDomain(doc: any): Device {
    // Convert the document to a plain object and recursively remove empty fields
    return removeEmpty({
      _id: doc._id ? doc._id.toString() : undefined,
      type: doc.type,
      name: doc.name,
      macAddress: doc.macAddress,
      _deactivate: doc._deactivate,
      location: doc.location
        ? {
            floor_id: doc.location.floor_id,
            x: doc.location.x,
            y: doc.location.y,
          }
        : undefined,
    });
  }
  
  async update(device: Device): Promise<Device | null> {
    const updatedDevice = await DeviceModel.findOneAndUpdate(
      { _id: device._id },
      { $set: device },
      { new: true, upsert: true }
    );
    return updatedDevice ? this.toDomain(updatedDevice) : null;
  }
 
  async create(device: Device): Promise<Device> {
    const newDevice = new DeviceModel(device);
    const savedDevice = await newDevice.save();
    return this.toDomain(savedDevice);
  }
 
  async delete(macAddress: string): Promise<boolean> {
    const result = await DeviceModel.deleteOne({ macAddress });
    return result.deletedCount > 0;
  }
 
  async filterDevices(filters: any): Promise<Device[]> {
    const query: any = {};
 
    // Add filters dynamically
    Iif (filters.type) query.type = filters.type;
    Iif (filters.name) query.name = filters.name;
    Iif (filters['location.floor_id']) query['location.floor_id'] = filters['location.floor_id'];
    Iif (filters['location.x']) query['location.x'] = filters['location.x'];
    Iif (filters['location.y']) query['location.y'] = filters['location.y'];
    Iif (filters.macAddress) query.macAddress = filters.macAddress;
    Iif (filters._deactivate !== undefined) query._deactivate = filters._deactivate;
 
    const docs = await DeviceModel.find(query);
    return docs.map((doc) => this.toDomain(doc));
  }
}