UNPKG

mikro-orm-find-dataloader

Version:

Additional dataloaders for the MikroORM EntityManager find/findOne/etc methods.

139 lines (138 loc) 6.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EntityDataLoader = void 0; /* eslint-disable @typescript-eslint/dot-notation */ /* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/array-type */ const core_1 = require("@mikro-orm/core"); const dataloader_1 = __importDefault(require("dataloader")); const findDataloader_1 = require("./findDataloader"); class EntityDataLoader { em; bypass; findLoader; constructor(em, bypass = false) { this.em = em; this.bypass = bypass; this.findLoader = new dataloader_1.default(async (dataloaderFinds) => { const queriesMap = (0, findDataloader_1.groupFindQueries)(dataloaderFinds); (0, findDataloader_1.assertHasNewFilterAndMapKey)(dataloaderFinds); const resultsMap = new Map(); await Promise.all(Array.from(queriesMap, async ([key, [filter, options]]) => { const entityName = key.substring(0, key.indexOf("|")); let entitiesOrError; const findOptions = { ...(options?.populate != null && { populate: options.populate === true ? ["*"] : Array.from(options.populate), }), }; try { entitiesOrError = await em.getRepository(entityName).find(filter, findOptions); } catch (e) { entitiesOrError = e; } resultsMap.set(key, entitiesOrError); })); return dataloaderFinds.map(({ filtersAndKeys, many }) => { const res = filtersAndKeys.reduce((acc, { key, newFilter }) => { const entitiesOrError = resultsMap.get(key); if (entitiesOrError == null) { throw new Error("Cannot match results"); } if (!(entitiesOrError instanceof Error)) { const res = entitiesOrError[many ? "filter" : "find"]((entity) => { return filterResult(entity, newFilter); }); acc.push(...(Array.isArray(res) ? res : [res])); return acc; } else { throw entitiesOrError; } }, []); return many ? res : res[0] ?? null; }); function filterResult(entity, filter) { for (const [key, value] of Object.entries(filter)) { const entityValue = entity[key]; if (Array.isArray(value)) { if (Array.isArray(entityValue)) { // Collection if (!value.every((el) => entityValue.includes(el))) { return false; } } else { // Single value if (!value.includes(entityValue)) { return false; } } } else { // Object: recursion if (!filterResult(entityValue, value)) { return false; } } } return true; } }); } async find(repoOrClass, filter, options) { // Property 'entityName' is protected and only accessible within class 'EntityRepository<Entity>' and its subclasses. const entityName = core_1.Utils.className(repoOrClass instanceof core_1.EntityRepository ? repoOrClass["entityName"] : repoOrClass); return (options?.bypass ?? this.bypass) ? await (repoOrClass instanceof core_1.EntityRepository ? repoOrClass.find(filter, options) : this.em.find(repoOrClass, filter, options)) : await this.findLoader.load({ entityName, meta: this.em.getMetadata().get(entityName), filter: filter, options: options, many: true, }); } async findOne(repoOrClass, filter, options) { // Property 'entityName' is protected and only accessible within class 'EntityRepository<Entity>' and its subclasses. const entityName = core_1.Utils.className(repoOrClass instanceof core_1.EntityRepository ? repoOrClass["entityName"] : repoOrClass); return (options?.bypass ?? this.bypass) ? await (repoOrClass instanceof core_1.EntityRepository ? repoOrClass.findOne(filter, options) : this.em.findOne(repoOrClass, filter, options)) : await this.findLoader.load({ entityName, meta: this.em.getMetadata().get(entityName), filter: filter, options: options, many: false, }); } async findOneOrFail(repoOrClass, filter, options) { // Property 'entityName' is protected and only accessible within class 'EntityRepository<Entity>' and its subclasses. const entityName = core_1.Utils.className(repoOrClass instanceof core_1.EntityRepository ? repoOrClass["entityName"] : repoOrClass); if (options?.bypass ?? this.bypass) { return await (repoOrClass instanceof core_1.EntityRepository ? repoOrClass.findOneOrFail(filter, options) : this.em.findOneOrFail(repoOrClass, filter, options)); } const one = (await this.findLoader.load({ entityName, meta: this.em.getMetadata().get(entityName), filter: filter, options: options, many: false, })); if (one == null) { throw new Error("Cannot find result"); } return one; } } exports.EntityDataLoader = EntityDataLoader;