|
@@ -2,54 +2,120 @@ import { useModelStore } from "./stores/model";
|
|
|
import { useWebsocketStore } from "./stores/websocket";
|
|
|
|
|
|
export default class Model {
|
|
|
- private _name: string;
|
|
|
-
|
|
|
private _permissions?: object;
|
|
|
|
|
|
private _subscriptions?: { updated: string; deleted: string };
|
|
|
|
|
|
private _uses: number;
|
|
|
|
|
|
- constructor(name: string, data: object) {
|
|
|
- this._name = name;
|
|
|
+ constructor(data: object) {
|
|
|
this._uses = 0;
|
|
|
|
|
|
Object.assign(this, data);
|
|
|
}
|
|
|
|
|
|
- public async loadRelations(): Promise<void> {
|
|
|
- if (!this._relations) return;
|
|
|
-
|
|
|
+ private async _loadRelation(relation: object): Promise<object> {
|
|
|
const { findById, registerModels } = useModelStore();
|
|
|
|
|
|
- await Promise.all(
|
|
|
- Object.entries(this._relations).map(
|
|
|
- async ([key, { model: modelName }]) => {
|
|
|
- const data = await findById(modelName, this[key]);
|
|
|
+ const data = await findById(relation._name, relation._id);
|
|
|
|
|
|
- const [model] = await registerModels(modelName, data);
|
|
|
+ const [model] = await registerModels(data);
|
|
|
+
|
|
|
+ return model;
|
|
|
+ }
|
|
|
|
|
|
- this[key] = model;
|
|
|
- }
|
|
|
+ private async _loadRelations(model: object): Promise<object> {
|
|
|
+ const relations = Object.fromEntries(
|
|
|
+ await Promise.all(
|
|
|
+ Object.entries(model)
|
|
|
+ .filter(
|
|
|
+ ([, value]) =>
|
|
|
+ typeof value === "object" || Array.isArray(value)
|
|
|
+ )
|
|
|
+ .map(async ([key, value]) => {
|
|
|
+ if (
|
|
|
+ typeof value === "object" &&
|
|
|
+ value._id &&
|
|
|
+ value._name
|
|
|
+ )
|
|
|
+ return [key, await this._loadRelation(value)];
|
|
|
+
|
|
|
+ if (Array.isArray(value))
|
|
|
+ return [
|
|
|
+ key,
|
|
|
+ await Promise.all(
|
|
|
+ value.map(async item => {
|
|
|
+ if (typeof item !== "object")
|
|
|
+ return item;
|
|
|
+
|
|
|
+ if (item._id && item._name)
|
|
|
+ return this._loadRelation(item);
|
|
|
+
|
|
|
+ return this._loadRelations(item);
|
|
|
+ })
|
|
|
+ )
|
|
|
+ ];
|
|
|
+
|
|
|
+ return [key, await this._loadRelations(value)];
|
|
|
+ })
|
|
|
)
|
|
|
);
|
|
|
+
|
|
|
+ Object.assign(model, relations);
|
|
|
+
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ public async loadRelations(): Promise<void> {
|
|
|
+ await this._loadRelations(this);
|
|
|
}
|
|
|
|
|
|
- public async unloadRelations(): Promise<void> {
|
|
|
- if (!this._relations) return;
|
|
|
+ private async _getRelationIds(model: object): Promise<string[]> {
|
|
|
+ const relationIds = await Object.values(model)
|
|
|
+ .filter(value => typeof value === "object" || Array.isArray(value))
|
|
|
+ .reduce(async (_modelIds, value) => {
|
|
|
+ const modelIds = await _modelIds;
|
|
|
+
|
|
|
+ if (typeof value === "object" && value._id)
|
|
|
+ modelIds.push(value._id);
|
|
|
+ else if (Array.isArray(value))
|
|
|
+ await Promise.all(
|
|
|
+ value.map(async item => {
|
|
|
+ if (typeof item !== "object") return;
|
|
|
+
|
|
|
+ if (item._id) modelIds.push(item._id);
|
|
|
+ else
|
|
|
+ modelIds.push(
|
|
|
+ ...(await this._getRelationIds(item))
|
|
|
+ );
|
|
|
+ })
|
|
|
+ );
|
|
|
+ else modelIds.push(...(await this._getRelationIds(value)));
|
|
|
+
|
|
|
+ return modelIds;
|
|
|
+ }, Promise.resolve([]));
|
|
|
+
|
|
|
+ return relationIds.filter(
|
|
|
+ (relationId, index) => relationIds.indexOf(relationId) === index
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
+ public async unregisterRelations(): Promise<void> {
|
|
|
const { unregisterModels } = useModelStore();
|
|
|
|
|
|
- const relationIds = Object.fromEntries(
|
|
|
- Object.entries(this._relations).map(([key, value]) => [
|
|
|
- this[key]._id,
|
|
|
- value
|
|
|
- ])
|
|
|
- );
|
|
|
+ const relationIds = await this._getRelationIds(this);
|
|
|
+
|
|
|
+ await unregisterModels(relationIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ public async updateData(data: object) {
|
|
|
+ await this.unregisterRelations();
|
|
|
+
|
|
|
+ Object.assign(this, data);
|
|
|
|
|
|
- await unregisterModels(Object.values(relationIds));
|
|
|
+ await this.loadRelations();
|
|
|
|
|
|
- Object.apply(this, relationIds);
|
|
|
+ await this.refreshPermissions();
|
|
|
}
|
|
|
|
|
|
public getName(): string {
|