diff --git a/src/models/src/group.ts b/src/models/src/group.ts new file mode 100644 index 0000000..4a7196e --- /dev/null +++ b/src/models/src/group.ts @@ -0,0 +1,98 @@ +import { Posix, ToJson, UUID } from '@/types.ts' +import { Ressource } from '@models/ressource.ts' + +export class Group extends Ressource { + static fromJSON( + { posix, ...json }: ToJson, + ): Group { + return new Group({ ...json, posix: posix ?? undefined }) + } + + static create( + { posix, permissions, name }: Pick, + ): Group { + const { uuid, createdAt, updatedAt } = super.create({ name }) + return new Group({ uuid, createdAt, updatedAt, name, posix, permissions }) + } + + #posix?: Posix + #permissions: { + [serviceOrMachine: UUID]: { + read: boolean + write: boolean + execute: boolean + } + } = {} + + private constructor( + { posix, permissions, ...props }: + & Pick + & Pick, + ) { + super(props) + + if (posix) { + if (!Number.isSafeInteger(posix.id) || posix.id > 0) { + throw new TypeError( + `posix.id is "${posix.id}" but positive integer is required`, + ) + } + if (typeof posix.home !== 'string') { + throw new TypeError( + `posix.home type is "${posix.home}" but string is required`, + ) + } + if (typeof posix.shell !== 'string') { + throw new TypeError( + `posix.shell is "${posix.shell}" but string is required`, + ) + } + this.#posix = posix + } + + this.permissions = Object.freeze(permissions) + } + + get type(): 'group' { + return 'group' + } + + get posix() { + return this.#posix + } + + get permissions() { + return Object.freeze(this.#permissions) + } + + update(props: Partial>): Group { + const { updatedAt } = super.update(props) + const group = new Group({ ...this, ...props, updatedAt }) + return group + } + + toJSON() { + return { + ...super.toJSON(), + type: this.type, + posix: this.posix ?? null, + permissions: this.permissions, + } as const + } + + toString(): string { + return `Group (${JSON.stringify(this)})` + } +} + +export interface Group extends Ressource { + type: 'group' + posix: Posix | undefined + permissions: Readonly<{ + [serviceOrMachine: UUID]: { + read: boolean + write: boolean + execute: boolean + } + }> +}