Skip to main content
Home
Works with
This package works with Deno
This package works with Deno
JSR Score52%
Downloads13/wk
Published2 years ago (0.2.1)

Système de gestion des ressources de cohabit.

import type { UUID } from '../../../types.ts' import type { Db } from '../../db/mod.ts' import { Credential, Group, Machine, type Resource, Service, User, } from '../mod.ts' export type RefString<T extends Resource> = | `@ref/${T['type']}#${UUID}` | Ref<T> export type RefResolver<T extends Resource> = ( ref: RefString<T>, ) => T | Promise<T> export class Ref<T extends Resource> extends String { static #toString<T extends Resource>( { uuid, type }: { uuid: UUID; type: T['type'] }, ) { return `@ref/${type}#${uuid}` as const } static parse<T extends Resource>( string: RefString<T>, ): { type: T['type']; uuid: UUID } { const [_, value] = string.split('/') const [type, uuid] = value.split('#') as [T['type'], UUID] return { type, uuid } as const } static fromResource<T extends Resource>(resource: T): Ref<T> { return new Ref<T>(resource) } static fromString<T extends Resource>(string: RefString<T>): Ref<T> { return new Ref<T>(Ref.parse(string)) } static dbResolver( db: Db, ): <T extends Resource>(ref: RefString<T>) => Promise<T> { return <T extends Resource>(ref: RefString<T>): Promise<T> => { const { type, uuid } = Ref.parse(ref) //@ts-expect-error force type casting to fix return db.resource[type].get({ uuid }) } } static restResolver( endpoint: string | URL, ): <T extends Resource>(ref: RefString<T>) => Promise<T> { return async <T extends Resource>(ref: RefString<T>): Promise<T> => { const { type, uuid } = Ref.parse(ref) const url = new URL(`${type}s/${uuid}`, endpoint) const response = await fetch(url) const json = await response.json() if (type === 'user') { return User.fromJSON(json) as unknown as T } if (type === 'machine') { return Machine.fromJSON(json) as unknown as T } if (type === 'service') { return Service.fromJSON(json) as unknown as T } if (type === 'group') { return Group.fromJSON(json) as unknown as T } if (type === 'credential') { return Credential.fromJSON(json) as unknown as T } throw new TypeError(`unknown ref type "${type}"`) } } private constructor({ uuid, type }: { uuid: UUID; type: T['type'] }) { super(Ref.#toString({ uuid, type })) this.#type = type this.#uuid = uuid } #type: T['type'] #uuid: UUID get type(): T['type'] { return this.#type } get uuid(): UUID { return this.#uuid } ref(resolver: RefResolver<T>): T | Promise<T> { return resolver(this.toString()) } toString(): `@ref/${T['type']}#${UUID}` { return Ref.#toString<T>({ uuid: this.uuid, type: this.type }) } toJSON(): `@ref/${T['type']}#${UUID}` { return this.toString() } }