/** * Class model for Collection Interface */ import type { CollectionContentTypes, CollectionInterface, CollectionModelInterface, CollectionPropertiesInterface } from "@/types/collection"; /** * Reduce a serialized resource identifier ("provider:service:collection") * 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 CollectionObject implements CollectionModelInterface { _data!: CollectionInterface; constructor() { this._data = { '@type': 'documents:collection', schema: 1, provider: '', service: '', collection: null, identifier: '', signature: null, created: null, modified: null, properties: new CollectionPropertiesObject(), }; } fromJson(data: CollectionInterface): CollectionObject { // the wire format carries full resource identifiers (provider:service:collection); // reduce them to plain ids, which is what the stores and UI operate on this._data = { ...data, service: plainIdentifier(data.service) ?? '', collection: plainIdentifier(data.collection), identifier: plainIdentifier(data.identifier) ?? '', }; if (data.properties) { this._data.properties = new CollectionPropertiesObject().fromJson(data.properties as CollectionPropertiesInterface); } return this; } toJson(): CollectionInterface { const json = { ...this._data }; if (this._data.properties instanceof CollectionPropertiesObject) { json.properties = this._data.properties.toJson(); } return json; } clone(): CollectionObject { const cloned = new CollectionObject(); cloned._data = { ...this._data }; cloned._data.properties = this.properties.clone(); return cloned; } /** Immutable Properties */ get schema(): number { return this._data.schema; } get provider(): string { return this._data.provider; } get service(): string | number { return this._data.service; } get collection(): string | number | null { return this._data.collection; } get identifier(): string | number { return this._data.identifier; } get signature(): string | null { return this._data.signature || null; } 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(): CollectionPropertiesObject { if (this._data.properties instanceof CollectionPropertiesObject) { return this._data.properties; } if (this._data.properties) { const hydrated = new CollectionPropertiesObject().fromJson(this._data.properties as CollectionPropertiesInterface); this._data.properties = hydrated; return hydrated; } const defaultProperties = new CollectionPropertiesObject(); this._data.properties = defaultProperties; return defaultProperties; } set properties(value: CollectionPropertiesObject) { if (value instanceof CollectionPropertiesObject) { this._data.properties = value as any; } else { this._data.properties = value; } } } export class CollectionPropertiesObject implements CollectionPropertiesInterface { _data!: CollectionPropertiesInterface; constructor() { this._data = { content: [], owner: '', label: '', }; } fromJson(data: CollectionPropertiesInterface): CollectionPropertiesObject { this._data = data; return this; } toJson(): CollectionPropertiesInterface { return this._data; } clone(): CollectionPropertiesObject { const cloned = new CollectionPropertiesObject(); cloned._data = { ...this._data }; return cloned; } /** Immutable Properties */ get content(): CollectionContentTypes[] { return this._data.content || []; } /** Mutable Properties */ get owner(): string { return this._data.owner; } set owner(value: string) { this._data.owner = value; } get label(): string { return this._data.label || ''; } set label(value: string) { this._data.label = value; } }