/** * Class model for Entity Interface */ import type { EntityInterface, EntityModelInterface } from "@/types/entity"; import type { DocumentInterface, DocumentModelInterface } from "@/types/document"; import { DocumentObject } from "./document"; /** * Reduce a serialized resource identifier ("provider:service:collection:entity") * to its own (last) segment; plain values pass through unchanged */ function plainIdentifier(value: string | number | null | undefined): string | number | null { if (value === null || value === undefined || value === '') { return value ?? null; } const text = String(value); const index = text.lastIndexOf(':'); return index >= 0 ? text.slice(index + 1) : value; } export class EntityObject implements EntityModelInterface { _data!: EntityInterface; constructor() { this._data = { '@type': '', schema: 1, provider: '', service: '', collection: '', identifier: '', signature: null, created: null, modified: null, properties: new DocumentObject(), }; } fromJson(data: EntityInterface): EntityObject { // the wire format carries full resource identifiers (provider:service:collection:entity); // reduce them to plain ids, which is what the stores and UI operate on this._data = { ...data, service: String(plainIdentifier(data.service) ?? ''), collection: plainIdentifier(data.collection) ?? '', identifier: plainIdentifier(data.identifier) ?? '', } if (data.properties) { this._data.properties = new DocumentObject().fromJson(data.properties as DocumentInterface); } return this; } toJson(): EntityInterface { const json = { ...this._data } if (this._data.properties instanceof DocumentObject) { json.properties = this._data.properties.toJson(); } return json as EntityInterface } clone(): EntityObject { const cloned = new EntityObject() cloned._data = { ...this._data } cloned._data.properties = this.properties.clone(); return cloned } /** Immutable Properties */ get provider(): string { return this._data.provider } get schema(): number { return this._data.schema } get service(): string { return this._data.service } get collection(): string | number { return this._data.collection } get identifier(): string | number { return this._data.identifier } get signature(): string | null { return this._data.signature } get created(): Date | null { return this._data.created ? new Date(this._data.created) : null } get modified(): Date | null { return this._data.modified ? new Date(this._data.modified) : null } get properties(): DocumentObject { if (this._data.properties instanceof DocumentObject) { return this._data.properties } if (this._data.properties) { const hydrated = new DocumentObject().fromJson(this._data.properties as DocumentInterface) this._data.properties = hydrated return hydrated } const defaultProperties = new DocumentObject() this._data.properties = defaultProperties return defaultProperties } set properties(value: DocumentObject) { this._data.properties = value } }