feat(model): add base ressource definition

This commit is contained in:
Julien Oculi 2024-05-07 11:22:31 +02:00
parent d1ddde757d
commit bb0ff728e3

101
src/models/src/ressource.ts Normal file
View file

@ -0,0 +1,101 @@
import { DateString, ToJson, UUID } from '@/types.ts'
import { regex } from '@/utils.ts'
export class Ressource {
static fromJSON(
json: ToJson<Ressource>,
): Ressource {
return new Ressource({
name: json.name,
uuid: json.uuid,
createdAt: json.createdAt,
updatedAt: json.updatedAt,
})
}
static create({ name }: Pick<Ressource, 'name'>): Ressource {
const uuid = crypto.randomUUID() as UUID
const createdAt = new Date().toISOString() as DateString
const updatedAt = createdAt
return new Ressource({ name, uuid, createdAt, updatedAt })
}
#name: string
#uuid: UUID
#createdAt: DateString
#updatedAt: DateString
protected constructor(
{ name, uuid, createdAt, updatedAt }: Pick<
Ressource,
'name' | 'uuid' | 'createdAt' | 'updatedAt'
>,
) {
this.#name = name
if (!regex.uuidV4.test(uuid)) {
throw new SyntaxError(
`the following uuid "${uuid}" is not a valid UUID V4`,
)
}
this.#uuid = uuid
if (!regex.isoDateString.test(createdAt)) {
throw new SyntaxError(
`the following create date "${createdAt}" is not a valid UTC ISO string`,
)
}
this.#createdAt = createdAt
if (!regex.isoDateString.test(updatedAt)) {
throw new SyntaxError(
`the following update date "${updatedAt}" is not a valid UTC ISO string`,
)
}
this.#updatedAt = updatedAt
}
get type(): 'user' | 'machine' | 'service' | 'group' | 'credential' {
throw new Error('ressource super class has no type')
}
get uuid(): UUID {
return this.#uuid
}
get name(): string {
return this.#name
}
get createdAt(): DateString {
return this.#createdAt
}
get updatedAt(): DateString {
return this.#updatedAt
}
update(
props: Partial<Omit<Ressource, 'type' | 'uuid' | 'createdAt'>>,
): Ressource {
const updated = new Ressource({ ...this, ...props })
updated.#updatedAt = new Date().toISOString() as DateString
return updated
}
toJSON() {
return {
type: this.type,
uuid: this.uuid,
name: this.name,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
} as const
}
toString(): string {
return `Ressource (${JSON.stringify(this)})`
}
}
export interface Ressource {
type: 'user' | 'machine' | 'service' | 'group' | 'credential'
uuid: UUID
name: string
createdAt: DateString
updatedAt: DateString
}