import { Id } from '../types'; import { BaseModel } from './base'; import { Keys } from './entities'; /** * @param {BaseModel} parent The parent BaseModel * @param {string} relationKey The name of the property on the parent to refer the relation to (e.g. users.forms where forms is the relationKey) * @param {string} foreignKey The foreignKey on the relation refering to the parent. (e.g userId on a form) * @param {Keys} storeKey The store key of the relation items. */ export class BelongsTo { protected _parent: BaseModel; public _foreignKey: string; public _relationKey: string; public _storeKey: Keys; constructor( parent: BaseModel, relationKey: string, foreignKey: string, storeKey: Keys, ) { this._parent = parent; this._foreignKey = foreignKey; this._relationKey = relationKey; this._storeKey = storeKey; } async getLocal(parentId: Id): Promise { const actualId = await this._parent.getId(parentId); const parentItem = this._parent._store.get( this._parent._storeKey, actualId, ); if (parentItem && parentItem[this._foreignKey]) { return this._parent._store.get( this._storeKey, parentItem[this._foreignKey], ); } return; } async get(parentId: Id) { const actualId = await this._parent.getId(parentId); const cached = this.getLocal(actualId); if (cached) { return cached; } const data = await this._parent._requestModel[this._relationKey].get( actualId, ); this._parent._store.set(this._storeKey, data, { deep: false }); return data; } } export function belongsTo({ relationKey, foreignKey, storeKey, }: { relationKey: string; foreignKey: string; storeKey: Keys; }) { return function _DecoratorName( ctor: C, ) { return class extends ctor { constructor(...args: any[]) { super(...args); this[relationKey] = new BelongsTo( >(this), relationKey, foreignKey, storeKey, ); } }; }; }