feat(model): ✨ add machine
model
This commit is contained in:
parent
0d78bc48ae
commit
8ae76d8254
113
src/models/src/machine.ts
Normal file
113
src/models/src/machine.ts
Normal file
|
@ -0,0 +1,113 @@
|
|||
import { ToJson } from '@/types.ts'
|
||||
import { Group } from '@models/group.ts'
|
||||
import { Ressource } from '@models/ressource.ts'
|
||||
import { Ref } from '@/src/models/utils/ref.ts'
|
||||
|
||||
export class Machine extends Ressource {
|
||||
static fromJSON(
|
||||
json: ToJson<Machine>,
|
||||
): Machine {
|
||||
const url = new URL(json.url)
|
||||
const avatar = new URL(json.avatar)
|
||||
const groups = json.groups.map((group) => Ref.fromString<Group>(group))
|
||||
|
||||
return new Machine({ ...json, url, avatar, groups })
|
||||
}
|
||||
|
||||
static create(
|
||||
{ tags, url, status, avatar, groups, ...props }:
|
||||
& Pick<Machine, 'tags' | 'url' | 'status' | 'avatar' | 'groups'>
|
||||
& Pick<Ressource, 'name' | 'uuid' | 'createdAt' | 'updatedAt'>,
|
||||
): Machine {
|
||||
return new Machine({ ...props, tags, url, status, avatar, groups })
|
||||
}
|
||||
|
||||
#tags: readonly string[]
|
||||
#url: URL
|
||||
#status:
|
||||
| 'ready'
|
||||
| 'busy'
|
||||
| 'unavailable'
|
||||
| 'discontinued'
|
||||
| 'error'
|
||||
| 'unknown'
|
||||
#avatar: URL
|
||||
#groups: readonly Ref<Group>[]
|
||||
|
||||
private constructor(
|
||||
{ tags, url, status, avatar, groups, ...props }:
|
||||
& Pick<Machine, 'tags' | 'url' | 'status' | 'avatar' | 'groups'>
|
||||
& Pick<Ressource, 'name' | 'uuid' | 'createdAt' | 'updatedAt'>,
|
||||
) {
|
||||
super(props)
|
||||
|
||||
this.#tags = Object.freeze(tags)
|
||||
this.#url = new URL(url)
|
||||
if (!['working', 'pending', 'ready', 'unavailable'].includes(status)) {
|
||||
throw new TypeError(
|
||||
`status is "${status}" but ('ready' | 'busy' | 'unavailable' | 'discontinued' | 'error' | 'unknown') is required`,
|
||||
)
|
||||
}
|
||||
this.#status = status
|
||||
this.#avatar = new URL(avatar)
|
||||
this.#groups = Object.freeze(groups)
|
||||
}
|
||||
|
||||
get type(): 'machine' {
|
||||
return 'machine'
|
||||
}
|
||||
get tags() {
|
||||
return this.#tags.slice()
|
||||
}
|
||||
get url() {
|
||||
return new URL(this.#url)
|
||||
}
|
||||
get status() {
|
||||
return this.#status
|
||||
}
|
||||
get avatar() {
|
||||
return new URL(this.#avatar)
|
||||
}
|
||||
get groups() {
|
||||
return this.#groups
|
||||
}
|
||||
|
||||
update(
|
||||
props: Partial<Omit<Machine, 'type' | 'uuid' | 'createdAt'>>,
|
||||
): Machine {
|
||||
const { updatedAt } = super.update(props)
|
||||
const machine = new Machine({ ...this, ...props, updatedAt })
|
||||
return machine
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
...super.toJSON(),
|
||||
type: this.type,
|
||||
tags: this.tags.slice(),
|
||||
url: this.url.toJSON(),
|
||||
status: this.status,
|
||||
avatar: this.avatar.toJSON(),
|
||||
groups: Object.freeze(this.groups.map((group) => group.toJSON())),
|
||||
} as const
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `Machine (${JSON.stringify(this)})`
|
||||
}
|
||||
}
|
||||
|
||||
export interface Machine extends Ressource {
|
||||
type: 'machine'
|
||||
tags: string[]
|
||||
url: URL
|
||||
status:
|
||||
| 'ready'
|
||||
| 'busy'
|
||||
| 'unavailable'
|
||||
| 'discontinued'
|
||||
| 'error'
|
||||
| 'unknown'
|
||||
avatar: URL
|
||||
groups: readonly Ref<Group>[]
|
||||
}
|
Loading…
Reference in a new issue