UNPKG

@schamane/small-graphql-mongoose-middleware

Version:

![Check Code](https://github.com/schamane/small-graphql-mongoose-middleware/workflows/Check%20Code/badge.svg)

155 lines 7.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoDataSource = void 0; const apollo_datasource_1 = require("apollo-datasource"); const lodash_1 = require("lodash"); const mongoose_1 = require("mongoose"); const utils_1 = require("../utils"); const { ObjectId } = mongoose_1.Types; class MongoDataSource extends apollo_datasource_1.DataSource { Entity; context; importFields; fieldTranslations; limit; // eslint-disable-next-line @typescript-eslint/no-explicit-any extensions; // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(entity, fieldTranslations, exts) { super(); this.Entity = entity; this.fieldTranslations = fieldTranslations; this.extensions = (0, lodash_1.map)(exts, (Ext) => new Ext()); } initialize(config) { this.context = config.context; (0, lodash_1.map)(this.extensions, (ext) => ext.initialize(config.context)); } async add(entity) { const instance = new this.Entity(this.entityPreSave(entity)); return instance.save(); } async update(entity) { const { _id } = entity; const original = await this.findById(_id); await original.updateOne(this.entityPreUpdate(entity)); return this.findById(_id); } async import(data) { const { db, collection: { name } } = this.Entity; const { insertedCount } = await db.collection(name).insertMany(data); // eslint-disable-next-line no-console console.debug(`Inserted ${name}:`, insertedCount); return insertedCount; } async truncate() { const { db, collection: { name } } = this.Entity; return db.dropCollection(name); } async findByIdAndDelete(id) { return this.Entity.findByIdAndDelete(id); } async findByIds(ids) { const objectIds = (0, lodash_1.map)(ids, ObjectId); const query = { _id: { $in: objectIds } }; return this.Entity.find(await this.entityPreQuery(query)).exec(); } async findById(id) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return this.Entity.findOne(await this.entityPreQuery({ _id: new ObjectId(id) })); } async find(filters, sort, distinct) { const query = (0, lodash_1.isArray)(filters) ? (0, utils_1.filtersToQuery)(filters, this.fieldTranslations) : (0, utils_1.filterToQuery)(filters, this.fieldTranslations); const entity = this.Entity.find(await this.entityPreQuery(query)); if (this.limit) { entity.limit(this.limit); } return this.sortAndExecuteQuery(entity, sort, distinct); } async count(filters, distinct) { const query = (0, lodash_1.isArray)(filters) ? (0, utils_1.filtersToQuery)(filters, this.fieldTranslations) : (0, utils_1.filterToQuery)(filters, this.fieldTranslations); const entity = this.Entity; return distinct ? entity.distinct(distinct).countDocuments(await this.entityPreQuery(query)) : entity.countDocuments(await this.entityPreQuery(query)); } async all(sort, distinct) { const entity = this.Entity.find(await this.entityPreQuery({})); if (this.limit) { entity.limit(this.limit); } return this.sortAndExecuteQuery(entity, sort, distinct); } setLimit(limit) { this.limit = limit; } getLimit() { return this.limit; } entityPreSave(entity) { let result = entity; (0, lodash_1.map)(this.extensions, (ext) => { result = ext.entityPreSave && (0, lodash_1.isFunction)(ext.entityPreSave) ? ext.entityPreSave(result) : result; }); return result; } entityPreUpdate(entity) { let result = entity; (0, lodash_1.map)(this.extensions, (ext) => { result = ext.entityPreUpdate && (0, lodash_1.isFunction)(ext.entityPreUpdate) ? ext.entityPreUpdate(result) : result; }); return result; } async entityPreQuery(query) { let result = query; await (0, utils_1.serialExec)(this.extensions, async (ext) => { result = ext.entityPreQuery && ext.entityPreQuery ? await ext.entityPreQuery(result) : result; }); return result; } async values(attribute, language) { const query = { ...(0, utils_1.languageFilter)(attribute, language), ...(0, utils_1.filterToQuery)(this.valuesFilter(), this.fieldTranslations) }; const res = await this.Entity.find(await this.entityPreQuery(query)).select((0, utils_1.translationsFieldPath)(attribute)); // detect if translation is in object or array const firstItem = (0, lodash_1.head)(res); const path = (0, lodash_1.isArray)((0, lodash_1.get)(firstItem, attribute)) ? (0, utils_1.translationsFieldStringPath)(attribute) : (0, utils_1.translationsFieldPath)(attribute); const translations = (0, lodash_1.flatten)((0, lodash_1.map)(res, path)); const translationsFiltered = (0, lodash_1.map)((0, lodash_1.filter)(translations, { language }), 'translation'); return (0, lodash_1.uniq)(translationsFiltered); } toSortObject(sorter) { const { name, direction } = sorter; const fields = (0, utils_1.translateSorter)(name, this.fieldTranslations); const mapFn = (myfields) => (0, lodash_1.map)(myfields, (field) => ({ [field]: direction })); return (0, lodash_1.isArray)(fields) ? (0, lodash_1.merge)({}, ...mapFn(fields)) : { [fields]: sorter.direction }; } static toLodashSort(sortObject) { const result = (0, lodash_1.unzip)((0, lodash_1.map)((0, lodash_1.keys)(sortObject), (key) => [key, (0, lodash_1.get)(sortObject, key)])); return { fields: (0, lodash_1.head)(result), direction: (0, lodash_1.last)(result) }; } async sortAndExecuteQuery(query, sort, distinct) { if (!sort) { return distinct ? query.distinct(distinct).exec() : query.exec(); } const sortObject = this.toSortObject(sort); if (MongoDataSource.isSortOnDB(sortObject)) { return MongoDataSource.sortAndExecuteQueryOnDB(query, sortObject, distinct); } return MongoDataSource.sortAndExecuteQueryOnApi(query, sortObject, distinct); } static async sortAndExecuteQueryOnDB(query, sortObject, distinct) { return distinct ? query.distinct(distinct).sort(sortObject).exec() : query.sort(sortObject).exec(); } static async sortAndExecuteQueryOnApi(query, sortObject, distinct) { const result = await query.exec(); const { fields, direction } = MongoDataSource.toLodashSort(sortObject); return distinct ? (0, lodash_1.uniqBy)((0, lodash_1.orderBy)(result, fields, direction), distinct) : (0, lodash_1.orderBy)(result, fields, direction); } static isSortOnDB(sortObject) { const list = (0, lodash_1.keys)(sortObject); const result = (0, lodash_1.some)(list, (i) => (0, lodash_1.includes)(i, '.')); return !result; } } exports.MongoDataSource = MongoDataSource; //# sourceMappingURL=mongoDataSource.js.map