import _ from 'lodash'; import { ObjectType } from 'type-graphql'; import { classToPlain, Exclude, plainToClassFromExist } from 'class-transformer'; import { Collection, ObjectId } from 'mongodb'; import DB from '@seed/services/database/DBService'; import { Permission } from '@seed/interfaces/permission'; import { ApolloContext } from '@seed/interfaces/context'; import { IEngineSchema, MetaBy } from './EngineSchema'; import { GetArgs } from '@seed/graphql/Request'; import { bulk, deleteOne, getAll, getCount, getMany, getOne, getQuery, saveMany, saveOne, updateOne, updateOneCustom, updateOneSubField, } from './utils/crud.utils'; import { getCountGeneric, getManyGeneric, getManyGenericWithArgs, getOneGeneric } from './utils/service.utils'; import { BulkInput, DeleteOneInput, GetAllInput, GetCountInput, GetManyInput, GetOneInput, GetQueryInput, SaveManyInput, SaveOneInput, UpdateOneCustomInput, UpdateOneInput, UpdateOneSubField, } from './utils/__interface'; import { EnginePathComponent } from '@seed/interfaces/components'; import { ModelCollectionEnum } from '@src/__indexes/__collections'; import { nullToUndefined } from '@seed/helpers/Utils'; @ObjectType() export abstract class EngineModel implements IEngineSchema { @Exclude() public collectionName: ModelCollectionEnum | string; @Exclude() public permissions: Permission; @Exclude() defaultSort: string; dbData: SchemaDB; searchT?: string; _id: string; organisationId?: string | undefined; paths?: EnginePathComponent[]; by?: MetaBy | undefined; createdAt: Date; updatedAt: Date; tagsIds?: string[]; public constructor(init: { collectionName: ModelCollectionEnum | string; permissions: Permission; dataInit: SchemaDB & Partial; defaultSort?: string; }) { this.collectionName = init.collectionName; this.permissions = init.permissions; this.dbData = init.dataInit; this.permissions = { c: init.permissions.c, r: init.permissions.r, w: init.permissions.w, d: init.permissions.d, }; this.createdAt = new Date(); this.updatedAt = new Date(); this.defaultSort = init.defaultSort || 'createdAt desc'; } /* * * Model functions * */ public get(): Schema { const data: any = this.dbData; if (this._id) data._id = this._id; if (this.permissions) data.permissions = this.permissions; if (this.organisationId) data.organisationId = this.organisationId; if (this.by) data.by = this.by; if (this.createdAt) data.createdAt = this.createdAt; if (this.updatedAt) data.updatedAt = this.updatedAt; return this.plainToClass(data) as Schema; } public set(doc: any): void { const newData = { ...classToPlain(this.dbData), // Get old data ...doc, // Replace with new data }; this.dbData = _.assign(this.dbData, newData); if (doc._id) this._id = doc._id; if (doc.permissions) { this.permissions = { c: _.uniq(_.concat(doc.permissions.c)), r: _.uniq(_.concat(doc.permissions.r)), w: _.uniq(_.concat(doc.permissions.w)), d: _.uniq(_.concat(doc.permissions.d)), }; } if (doc.organisationId) this.organisationId = doc.organisationId; if (doc.paths) this.paths = doc.paths; if (doc.createdAt) this.createdAt = doc.createdAt; if (doc.updatedAt) this.updatedAt = doc.updatedAt; } async beforeCreate?(ctx?: ApolloContext | null): Promise; async beforeUpdate?(ctx?: ApolloContext | null): Promise; async beforeDelete?(ctx?: ApolloContext | null): Promise; async afterCreate?(changeStream: any): Promise; async afterUpdate?(changeStream: any): Promise; async afterDelete?(changeStream: any): Promise; /* * * Search Functions & Helpers * */ searchEngine?(): any; searchText?(): any; /* * * Transform Functions * */ abstract plainToClass(plain: any): Schema | Schema[]; /* * * DB Functions * */ public async db(): Promise> { return await (await DB.getInstance()).db.collection(this.collectionName); } generatePaths?(): EnginePathComponent[]; public getPaths(): EnginePathComponent[] { return this.generatePaths ? this.generatePaths() : this.paths ? this.paths : []; } public getFullPath(): EnginePathComponent[] { const myPath = this.getPaths(); myPath.push({ ressourceModel: this.collectionName, ressourceId: this._id, }); return myPath; } // ██████╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗ // ██╔═══██╗██║ ██║██╔════╝██╔══██╗╚██╗ ██╔╝ // ██║ ██║██║ ██║█████╗ ██████╔╝ ╚████╔╝ // ██║▄▄ ██║██║ ██║██╔══╝ ██╔══██╗ ╚██╔╝ // ╚██████╔╝╚██████╔╝███████╗██║ ██║ ██║ // ╚══▀▀═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ public async getQuery(input: GetQueryInput): Promise { return getQuery(this, input); } public async getMany(input: GetManyInput): Promise { return getMany(this, input); } public async getCount(input: GetCountInput): Promise { return getCount(this, input); } public async getAll(input: GetAllInput): Promise { return getAll(this, input); } public async getOne(input: GetOneInput): Promise { let newInput; if (!input.query) { newInput = { query: input }; } else newInput = input; return getOne(this, newInput); } // ███╗ ███╗██╗ ██╗████████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗ // ████╗ ████║██║ ██║╚══██╔══╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║ // ██╔████╔██║██║ ██║ ██║ ███████║ ██║ ██║██║ ██║██╔██╗ ██║ // ██║╚██╔╝██║██║ ██║ ██║ ██╔══██║ ██║ ██║██║ ██║██║╚██╗██║ // ██║ ╚═╝ ██║╚██████╔╝ ██║ ██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║ // ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ public async saveOne(input: SaveOneInput): Promise { return saveOne(this, input); } public async updateOne(input: UpdateOneInput): Promise { return updateOne(this, input); } public async updateOneCustom(input: UpdateOneCustomInput): Promise { return updateOneCustom(this, input); } public async updateOneSubField(input: UpdateOneSubField): Promise { return updateOneSubField(this, input); } public async deleteOne(input: DeleteOneInput): Promise { return deleteOne(this, input); } public async saveMany(input: SaveManyInput): Promise { return saveMany(this, input); } public async bulk(input: BulkInput): Promise { return bulk(this, input); } // ██████╗ ███████╗███╗ ██╗███████╗██████╗ ██╗ ██████╗███████╗ // ██╔════╝ ██╔════╝████╗ ██║██╔════╝██╔══██╗██║██╔════╝██╔════╝ // ██║ ███╗█████╗ ██╔██╗ ██║█████╗ ██████╔╝██║██║ ███████╗ // ██║ ██║██╔══╝ ██║╚██╗██║██╔══╝ ██╔══██╗██║██║ ╚════██║ // ╚██████╔╝███████╗██║ ╚████║███████╗██║ ██║██║╚██████╗███████║ // ╚═════╝ ╚══════╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝╚══════ public async getOneGeneric(id: string, ctx: ApolloContext): Promise { return getOneGeneric(this, id, ctx); } public async getManyGeneric(query: any, pagination: GetArgs | undefined, ctx: ApolloContext | null): Promise { return getManyGeneric(this, query, pagination, ctx); } public async getCountGeneric(baseArguments: any, ctx: ApolloContext): Promise { return getCountGeneric(this, baseArguments, ctx); } public async getManyGenericWithArgs(baseArguments: any, ctx: ApolloContext | null): Promise { return getManyGenericWithArgs(this, baseArguments, ctx); } }