87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
import type { Low } from 'lowdb';
|
|
import { nanoid } from 'nanoid';
|
|
import { type New, type Updated } from '../../types';
|
|
import { type Group, type GroupError, GroupErrors } from '../../types/group';
|
|
import type { IGroupRepo } from '../groupRepo';
|
|
import type { LowStorage } from './_init';
|
|
|
|
export class LowGroupRepo implements IGroupRepo {
|
|
private readonly db;
|
|
|
|
constructor(db: Low<LowStorage.LowData>) {
|
|
this.db = db;
|
|
}
|
|
|
|
async getAll(): Promise<Group[]> {
|
|
return this.db.data.groups;
|
|
}
|
|
|
|
async getById(id: string): Promise<Group | undefined> {
|
|
return this.db.data.groups.find((g) => g.id === id);
|
|
}
|
|
|
|
async create(group: New<Group>): Promise<GroupError | undefined> {
|
|
if (this.db.data.groups.find((g) => g.name === group.name)) {
|
|
return GroupErrors.DUPLICATE_NAME;
|
|
}
|
|
|
|
for (const deviceId of group.devices) {
|
|
if (!this.db.data.devices.some((d) => d.id === deviceId)) {
|
|
return GroupErrors.UNKNOWN_DEVICE;
|
|
}
|
|
}
|
|
|
|
await this.db.update(({ groups }) => {
|
|
groups.push({ id: nanoid(), ...group });
|
|
});
|
|
|
|
return undefined;
|
|
}
|
|
|
|
async update(group: Updated<Group>): Promise<GroupError | undefined> {
|
|
if (this.db.data.groups.find((g) => g.name === group.name && g.id !== group.id)) {
|
|
return GroupErrors.DUPLICATE_NAME;
|
|
}
|
|
|
|
for (const deviceId of group.devices ?? []) {
|
|
if (!this.db.data.devices.some((d) => d.id === deviceId)) {
|
|
return GroupErrors.UNKNOWN_DEVICE;
|
|
}
|
|
}
|
|
|
|
let found = false;
|
|
await this.db.update(({ groups }) => {
|
|
const existingGroup = groups.find((g) => g.id === group.id);
|
|
if (!existingGroup) return;
|
|
|
|
Object.assign(existingGroup, group);
|
|
found = true;
|
|
});
|
|
|
|
return found ? undefined : GroupErrors.NOT_FOUND;
|
|
}
|
|
|
|
async delete(groupId: string): Promise<GroupError | undefined> {
|
|
let found = false;
|
|
|
|
this.db.data.groups = this.db.data.groups.filter((g) => {
|
|
if (g.id === groupId) {
|
|
found = true;
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
|
|
if (found) {
|
|
this.db.data.users.forEach((u) => (u.groups = u.groups.filter((gid) => gid != groupId)));
|
|
await this.db.write();
|
|
}
|
|
|
|
return found ? undefined : GroupErrors.NOT_FOUND;
|
|
}
|
|
|
|
async countUsers(groupId: string): Promise<number> {
|
|
return this.db.data.users.filter((u) => u.groups.includes(groupId)).length;
|
|
}
|
|
}
|