@schamane/small-graphql-mongoose-middleware
Version:

155 lines • 7.21 kB
JavaScript
"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