flexiblepersistence
Version:
A CQRS and Event Sourcing platform
1,090 lines • 47.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MongoPersistence = void 0;
/* eslint-disable @typescript-eslint/ban-ts-comment */
const mongoose_1 = require("mongoose");
const event_1 = require("../../../event/event");
const __1 = require("../../..");
const genericSchema_1 = __importDefault(require("./genericSchema"));
const type_1 = require("../../../event/type");
const subType_1 = require("../../../event/subType");
const toCast_1 = require("./toCast");
const mongodb_1 = require("mongodb");
const pipelineCRUD_1 = require("./pipelineCRUD");
const transaction_1 = require("./transaction");
class MongoPersistence {
constructor(persistenceInfo, element) {
this.element = { Generic: new genericSchema_1.default() };
this.persistenceInfo = persistenceInfo;
this.mongooseInstance = new mongoose_1.Mongoose();
const uri = (!persistenceInfo.connectionType ? 'mongodb://' : '') +
persistenceInfo.uri;
this.mongooseInstance.set('toJSON', {
virtuals: true,
transform: (doc, converted) => {
delete converted._id;
},
});
if (process.env.SHOW_DATABASE_URI?.toLowerCase() === 'true' ||
process.env.SHOW_DATABASE_URI?.toLowerCase() === '1') {
console.log('MongoDB URI:', uri);
console.log('MongoDB PersistenceInfo:', persistenceInfo);
}
this.mongooseInstance.connect(uri, {
autoIndex: false,
});
this.setElement(element);
}
async transaction(options,
// eslint-disable-next-line no-unused-vars
callback) {
const transaction = new transaction_1.Transaction(this.mongooseInstance);
await transaction.begin(options);
await callback?.(transaction);
return transaction;
}
initElement() {
for (const key in this.element) {
if (Object.prototype.hasOwnProperty.call(this.element, key)) {
const element = this.element[key];
const schema = new this.mongooseInstance.Schema(element.getAttributes(), element.getOptions());
const index = element.getIndex();
const virtual = element.getVirtual();
const populate = element.getPopulate();
const pipeline = element.getPipeline();
const pipelineOptions = element.getPipelineOptions();
const toCast = element.getToCast();
if (index) {
schema.index(index, element.getIndexOptions());
}
if (virtual) {
for (const key in virtual) {
if (Object.hasOwnProperty.call(virtual, key)) {
const element = virtual[key];
const currentVirtual = schema.virtual(key, element);
if (element)
for (const key in element) {
if (Object.hasOwnProperty.call(element, key)) {
const element2 = element[key];
if (currentVirtual[key] instanceof Function) {
currentVirtual[key](element2);
}
else {
currentVirtual[key] = element2;
}
}
}
}
}
schema['virtualOptions'] = virtual;
}
if (populate) {
schema['populateOptions'] = populate;
}
if (toCast) {
schema['toCastOptions'] = toCast;
}
if (pipeline) {
schema['pipeline'] = pipeline;
}
if (pipelineOptions) {
schema['pipelineOptions'] = pipelineOptions;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.addModel(element?.getName(), schema);
}
}
// console.log('Mongoose Models:', this.getModels());
}
setElement(element) {
if (element)
this.element = { ...this.element, ...element };
this.initElement();
}
getModel(name) {
if (this.getModels()[name])
return this.getModels()[name];
const genericSchema = new this.mongooseInstance.Schema({
id: {
type: mongoose_1.Schema.Types.ObjectId,
unique: true,
index: true,
},
}, {
strict: false,
id: true,
versionKey: false,
});
return this.addModel(name, genericSchema);
}
getModels() {
return this.mongooseInstance.models;
}
addModel(name, schema) {
// this.model[name] =
const model = this.mongooseInstance.model(name, schema);
return model;
}
populateStep(query, populateOptions, populate, callback) {
if (Array.isArray(populateOptions))
for (const populateOption of populateOptions) {
console.log('populate:', populateOption);
if (populate)
query = query.populate(populate, populateOption);
else
query = query.populate(populateOption);
}
else
query = query.populate(populate);
query.exec(callback);
return query;
}
getCrud(method) {
switch (method) {
case 'create':
case 'insertMany':
return pipelineCRUD_1.PipelineCRUDType.create;
case 'find':
case 'findOne':
case 'findById':
return pipelineCRUD_1.PipelineCRUDType.read;
case 'updateMany':
case 'findOneAndUpdate':
case 'findByIdAndUpdate':
return pipelineCRUD_1.PipelineCRUDType.update;
case 'deleteMany':
case 'findOneAnddelete':
case 'findByIdAndDelete':
return pipelineCRUD_1.PipelineCRUDType.delete;
}
return pipelineCRUD_1.PipelineCRUDType.read;
}
isPipelineCrud(pipeline) {
let isPipeline = pipeline &&
!Array.isArray(pipeline) &&
// @ts-ignore
(pipeline.create !== undefined ||
// @ts-ignore
pipeline.read !== undefined ||
// @ts-ignore
pipeline.update !== undefined ||
// @ts-ignore
pipeline.delete !== undefined);
isPipeline = isPipeline || false;
return isPipeline;
}
populate(scheme, method, queryParams, populateOptions, callback) {
const model = this.getModel(scheme);
const crud = this.getCrud(method);
model.aggregate();
let pipeline = model.schema['pipeline'];
pipeline = (this.isPipelineCrud(pipeline) ? pipeline?.[crud] : pipeline);
const pipelineOptions = model.schema['pipelineOptions'];
const hasPopulate = populateOptions !== undefined &&
populateOptions !== null &&
Array.isArray(populateOptions)
? populateOptions.length > 0
: true;
const hasPipeline = pipeline !== undefined && pipeline !== null;
let query = undefined;
model.collection.collectionName;
if (hasPipeline) {
let firstParam = queryParams?.[0];
firstParam = (typeof firstParam === 'string' ||
typeof firstParam === 'number' ||
firstParam instanceof mongodb_1.ObjectId
? { id: firstParam }
: firstParam);
const secondParam = queryParams?.[1];
//! missing: const thirdParam = queryParams?.[2];
const queryPipeline = [{ $match: firstParam }];
switch (crud) {
case pipelineCRUD_1.PipelineCRUDType.create:
queryPipeline.push({
$merge: {
into: model.collection.collectionName,
on: 'id',
whenMatched: 'fail',
whenNotMatched: 'insert',
},
});
break;
case pipelineCRUD_1.PipelineCRUDType.update:
queryPipeline.push({
$merge: {
into: model.collection.collectionName,
on: Object.keys(firstParam),
let: secondParam,
whenMatched: 'replace',
whenNotMatched: 'fail',
},
});
break;
}
pipeline = Array.isArray(pipeline)
? [...pipeline, ...queryPipeline]
: pipeline
? [pipeline, ...queryPipeline]
: queryPipeline;
if (method === 'deleteMany' ||
method === 'findOneAndDelete' ||
method === 'findByIdAndDelete') {
//@ts-ignore
query = model.aggregate(pipeline, pipelineOptions).then((result) => {
const queryIds = result.map((doc) => doc._id);
query = model.deleteMany({ _id: { $in: queryIds } }, secondParam, (...params) => {
if (hasPopulate)
query = this.populateStep(model, populateOptions, params[0], callback);
else
query = callback(...params);
});
}, callback);
}
else {
//@ts-ignore
query = model.aggregate(pipeline, pipelineOptions, (...params) => {
if (hasPopulate)
query = this.populateStep(model, populateOptions, params[0], callback);
else
query = callback(...params);
});
}
}
else {
query = model?.[method]?.bind(model);
if (hasPopulate) {
query = query?.(...queryParams);
console.log('populate:', query, query.name, queryParams);
query = this.populateStep(query, populateOptions, undefined, callback);
}
else {
query = query(...queryParams, callback);
}
}
return query;
}
populateAll(scheme, method, //query (model[method].bind(model)) => model.create.bind(model)
queryParams, fullOperation,
// eslint-disable-next-line no-unused-vars
callback) {
queryParams = this.filterQueryParams(queryParams);
const model = this.getModel(scheme);
const populate = model.schema['populateOptions'];
// console.log('populateAll:', queryParams);
if (populate) {
if (Array.isArray(populate)) {
return this.populate(scheme, method, queryParams, populate, callback);
}
else if (fullOperation?.operation !== undefined) {
const operation = __1.Operation[fullOperation?.operation];
const hasOparation = operation !== undefined && operation !== null;
const populateOpertaion = hasOparation
? populate[operation]
: undefined;
const hasPopulateOparation = populateOpertaion !== undefined && populateOpertaion !== null;
if (hasPopulateOparation) {
if (Array.isArray(populateOpertaion)) {
return this.populate(scheme, method, queryParams, populateOpertaion, callback);
}
else if (fullOperation?.type !== undefined) {
const type = type_1.Type[fullOperation?.type];
const hasType = type !== undefined && type !== null;
const populateType = hasType ? populateOpertaion[type] : undefined;
const hasPopulateType = populateType !== undefined && populateType !== null;
if (hasPopulateType) {
if (Array.isArray(populateType)) {
return this.populate(scheme, method, queryParams, populateType, callback);
}
else if (fullOperation?.subType !== undefined) {
const subType = subType_1.SubType[fullOperation?.subType];
const hasSubType = subType !== undefined && subType !== null;
const populateSubType = hasSubType
? populateType[subType]
: undefined;
const hasPopulateSubType = populateSubType !== undefined && populateSubType !== null;
if (hasPopulateSubType && Array.isArray(populateSubType)) {
return this.populate(scheme, method, queryParams, populateSubType, callback);
}
}
}
}
}
}
}
return this.populate(scheme, method, queryParams, [], callback);
}
execute(query, queryParams, callback) {
queryParams = this.filterQueryParams(queryParams);
const hasCallback = callback !== undefined && callback !== null;
// console.log('execute:', queryParams);
if (typeof query !== 'function') {
if (query.exec !== undefined) {
return hasCallback ? query.exec(callback) : query(queryParams);
}
return query;
}
else if (typeof query === 'function') {
try {
if (queryParams.length > 0)
return hasCallback
? query(...queryParams, callback)
: query(...queryParams);
return query({}, callback);
}
catch (error) {
const functionQuery = queryParams.length > 0 ? query(...queryParams) : query();
if (typeof functionQuery.exec !== undefined && hasCallback) {
return functionQuery.exec(callback);
}
else {
return functionQuery;
}
}
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
advancedFilter(queryParams) {
if (queryParams !== undefined &&
queryParams !== null &&
queryParams.length > 0)
for (const element of queryParams) {
if (element !== undefined && element !== null) {
for (const key in element) {
if (key !== undefined &&
key !== null &&
element[key] !== undefined &&
element[key] !== null) {
let isArray = false;
if (key.includes('[]')) {
const keySplit = key.split('[]');
element[keySplit[0]] = element[key];
delete element[key];
isArray = true;
}
if (key.includes('.$')) {
const keySplit = key.split('.$');
if (element[keySplit[0]] === undefined ||
element[keySplit[0]] === null)
element[keySplit[0]] = {};
let newKey = '$' + keySplit[1];
if ((isArray || Array.isArray(element[key])) &&
keySplit[1] === 'ne') {
newKey = '$nin';
}
element[keySplit[0]][newKey] = element[key];
delete element[key];
}
}
}
}
}
}
filterQueryParams(queryParams) {
if (queryParams !== undefined &&
queryParams !== null &&
queryParams.length > 0)
for (let index = queryParams.length - 1; index >= 0 && queryParams[index] === undefined; index--) {
queryParams.splice(index, 1);
}
else
queryParams = [];
this.advancedFilter.bind(this)(queryParams);
return queryParams;
}
toCast(type) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const value = toCast_1.CastType[type];
return value === 'none' ||
value === '' ||
value === undefined ||
value === null
? ''
: value;
}
toCastAll(schema, fullOperation) {
const model = this.getModel(schema);
let toCast = model.schema['toCastOptions'];
if (toCast) {
if (typeof toCast === 'number') {
return this.toCast(toCast);
}
else {
if (fullOperation?.operation === undefined ||
fullOperation?.operation === null)
return '';
const operation = __1.Operation[fullOperation?.operation];
const hasOperation = operation !== undefined && operation !== null;
toCast = hasOperation ? toCast[operation] : undefined;
let hasToCast = toCast !== undefined && toCast !== null;
if (hasToCast) {
if (typeof toCast === 'number') {
return this.toCast(toCast);
}
else {
if (fullOperation?.type === undefined ||
fullOperation?.type === null)
return '';
const type = type_1.Type[fullOperation?.type];
const hasType = type !== undefined && type !== null;
toCast = hasType ? toCast[type] : undefined;
hasToCast = toCast !== undefined && toCast !== null;
if (hasToCast) {
if (typeof toCast === 'number') {
return this.toCast(toCast);
}
else {
if (fullOperation?.subType === undefined ||
fullOperation?.subType === null)
return '';
const subType = subType_1.SubType[fullOperation?.subType];
const hasSubType = subType !== undefined && subType !== null;
toCast = hasSubType ? toCast[subType] : undefined;
hasToCast = toCast !== undefined && toCast !== null;
if (hasToCast && typeof toCast === 'number') {
return this.toCast(toCast);
}
}
}
}
}
}
}
return '';
}
async clearModel(scheme) {
try {
const model = this.getModel(scheme);
await model?.deleteMany({}, undefined);
return true;
}
catch (error) {
console.error(error);
return false;
}
}
clear() {
return new Promise(async (resolve, reject) => {
const responses = [];
for (const key in this.getModels()) {
if (Object.prototype.hasOwnProperty.call(this.getModels(), key)) {
responses.push(this.clearModel(key));
}
}
const response = await Promise.all(responses);
for (const element of response) {
if (!element) {
reject(response);
return;
}
}
resolve(true);
});
}
other(input) {
return new Promise((resolve) => {
resolve({
receivedItem: input,
});
});
}
create(input) {
const isRegularArray = Array.isArray(input.item);
const isContentArray = isRegularArray
? false
: Array.isArray(input.item.content);
const isArray = isContentArray || isRegularArray;
input.single =
input.single === undefined || input.single === null ? true : input.single;
// console.log('Input Item:', input.item);
// console.log('Is Array:', isArray);
// console.log('Is Content Array:', isRegularArray);
// console.log('Is Regular Array:', isContentArray);
// console.log('Is single:', input.single);
const isEvent = input.item instanceof event_1.Event;
if ((input.single && !isArray) || isEvent) {
return this.createItem(input.scheme, input.item);
}
else {
return this.createArray(input.scheme, input.item, isRegularArray, input.options);
}
}
read(input) {
if (input?.id)
input.id =
typeof input?.id === 'string' && input?.id?.includes('ObjectId')
? new mongodb_1.ObjectId(input?.id
?.replaceAll('ObjectId(', '')
?.replaceAll(')', '')
?.replaceAll("'", ''))
: input?.id;
if (input?.selectedItem)
for (const key in input?.selectedItem) {
if (Object.hasOwnProperty.call(input?.selectedItem, key)) {
const element = input?.selectedItem[key];
input.selectedItem[key] =
typeof element === 'string' && element?.includes('ObjectId')
? new mongodb_1.ObjectId(element
?.replaceAll('ObjectId(', '')
?.replaceAll(')', '')
?.replaceAll("'", ''))
: element;
}
}
if (input?.single || (input?.id && !Array.isArray(input?.id))) {
if (input?.id)
return this.readItemById(input?.scheme, input?.id, input?.options, input?.additionalOptions, input?.eventOptions);
return this.readItem(input?.scheme, input?.selectedItem, input?.options, input?.additionalOptions, input?.eventOptions);
}
else {
return this.readArray(input?.scheme, input?.selectedItem, input?.options, input?.additionalOptions, input?.eventOptions);
}
}
update(input) {
const isRegularArray = Array.isArray(input?.item);
const isContentArray = isRegularArray
? false
: Array.isArray(input?.item?.content);
const isArray = isContentArray || isRegularArray;
// console.log('Input:', input);
if (input?.id)
input.id =
typeof input?.id === 'string' && input?.id?.includes('ObjectId')
? new mongodb_1.ObjectId(input?.id
?.replaceAll('ObjectId(', '')
?.replaceAll(')', '')
?.replaceAll("'", ''))
: input?.id;
if (input?.selectedItem)
for (const key in input?.selectedItem) {
if (Object.hasOwnProperty.call(input?.selectedItem, key)) {
const element = input?.selectedItem[key];
input.selectedItem[key] =
typeof element === 'string' && element?.includes('ObjectId')
? new mongodb_1.ObjectId(element
?.replaceAll('ObjectId(', '')
?.replaceAll(')', '')
?.replaceAll("'", ''))
: element;
}
}
if ((input?.single || (input?.id && !Array.isArray(input?.id))) &&
!isArray) {
return this.updateItem(input?.scheme, input?.selectedItem, input?.item, input?.options);
}
else {
return this.updateArray(input?.scheme, input?.selectedItem, input?.item, isRegularArray, input?.options);
}
}
delete(input) {
if (input?.single || (input?.id && !Array.isArray(input?.id))) {
if (input?.id)
return this.deleteItemById(input?.scheme, input?.id, input?.options);
return this.deleteItem(input?.scheme, input?.selectedItem, input?.options);
}
else {
return this.deleteArray(input?.scheme, input?.selectedItem, input?.options);
}
}
cleanReceived(received) {
if (received.receivedItem === undefined || received.receivedItem === null) {
delete received.receivedItem;
}
if (received.result === undefined || received.result === null) {
delete received.result;
}
if (received.selectedItem === undefined || received.selectedItem === null) {
delete received.selectedItem;
}
if (received.sentItem === undefined || received.sentItem === null) {
delete received.sentItem;
}
return received;
}
generateOptions(options, eventOptions) {
if (eventOptions?.pageSize || eventOptions?.pageSize) {
const pageSize = eventOptions?.pageSize || eventOptions?.pagesize;
const skip = eventOptions?.page && pageSize ? +eventOptions?.page * +pageSize : 0;
const compiledOptions = {
...options,
limit: pageSize ? +pageSize : undefined,
skip: skip ? +skip : undefined,
sort: eventOptions?.sort ? JSON.parse(eventOptions?.sort) : undefined,
perDocumentLimit: eventOptions?.perDocumentLimit
? JSON.parse(eventOptions?.perDocumentLimit)
: undefined,
_recursed: eventOptions?.recursed
? JSON.parse(eventOptions?.recursed)
: undefined,
tailable: eventOptions?.tailable
? JSON.parse(eventOptions?.tailable)
: undefined,
allowDiskUse: eventOptions?.allowDiskUse
? JSON.parse(eventOptions?.allowDiskUse)
: undefined,
batchSize: eventOptions?.batchSize
? JSON.parse(eventOptions?.batchSize)
: undefined,
readPreference: eventOptions?.readPreference
? JSON.parse(eventOptions?.readPreference)
: undefined,
hint: eventOptions?.hint ? JSON.parse(eventOptions?.hint) : undefined,
comment: eventOptions?.comment
? JSON.parse(eventOptions?.comment)
: undefined,
snapshot: eventOptions?.snapshot
? JSON.parse(eventOptions?.snapshot)
: undefined,
maxscan: eventOptions?.maxscan
? JSON.parse(eventOptions?.maxscan)
: undefined,
upsert: eventOptions?.upsert
? JSON.parse(eventOptions?.upsert)
: undefined,
writeConcern: eventOptions?.writeConcern
? JSON.parse(eventOptions?.writeConcern)
: undefined,
timestamps: eventOptions?.timestamps
? JSON.parse(eventOptions?.timestamps)
: undefined,
overwriteDiscriminatorKey: eventOptions?.overwriteDiscriminatorKey
? JSON.parse(eventOptions?.overwriteDiscriminatorKey)
: undefined,
lean: eventOptions?.lean ? JSON.parse(eventOptions?.lean) : undefined,
populate: eventOptions?.populate
? JSON.parse(eventOptions?.populate)
: undefined,
projection: eventOptions?.projection
? JSON.parse(eventOptions?.projection)
: undefined,
sanitizeProjection: eventOptions?.sanitizeProjection
? JSON.parse(eventOptions?.sanitizeProjection)
: undefined,
maxTimeMS: eventOptions?.maxTimeMS
? JSON.parse(eventOptions?.maxTimeMS)
: undefined,
rawResult: eventOptions?.rawResult
? JSON.parse(eventOptions?.rawResult)
: undefined,
strict: eventOptions?.strict
? JSON.parse(eventOptions?.strict)
: undefined,
collation: eventOptions?.collation
? JSON.parse(eventOptions?.collation)
: undefined,
session: eventOptions?.session
? JSON.parse(eventOptions?.session)
: undefined,
explain: eventOptions?.explain
? JSON.parse(eventOptions?.explain)
: undefined,
};
for (const key in compiledOptions) {
if (Object.hasOwnProperty.call(compiledOptions, key)) {
if (compiledOptions[key] === undefined)
delete compiledOptions[key];
}
}
return compiledOptions;
}
return options;
}
async count(scheme, selectedItem, options, eventOptions, compiledOptions) {
const model = this.getModel(scheme);
if (compiledOptions && compiledOptions.limit) {
const count = await model.countDocuments(selectedItem, options);
if (eventOptions) {
eventOptions.pages = Math.ceil(count / compiledOptions.limit);
}
}
}
generateReceivedArray(docs, scheme, fullOperation) {
let receivedItem;
if (Array.isArray(docs))
receivedItem = docs.map((doc) => this.generateReceivedItem.bind(this)(doc, scheme, fullOperation));
else
receivedItem = this.generateReceivedItem.bind(this)(docs, scheme, fullOperation);
return receivedItem;
}
generateNewArray(item, regular) {
let items = item || {};
if (!Array.isArray(item) && item?.content && Array.isArray(item.content)) {
if (regular)
items = item?.content?.map((itemC) => this.generateNewItem(itemC));
else
items = item?.content?.map((itemC) => this.generateNewItem({ ...item, content: itemC, id: itemC.id }));
}
else if (Array.isArray(item)) {
items = item.map((itemC) => this.generateNewItem(itemC));
}
return items;
}
generateNewItem(item) {
if (item && item.id) {
const newItem = JSON.parse(JSON.stringify(item));
newItem._id = newItem.id;
return newItem;
}
if (item === undefined)
return {};
return item;
}
generateReceivedItem(doc, scheme, fullOperation) {
const cast = scheme !== undefined ? this.toCastAll(scheme, fullOperation) : '';
let receivedItem = doc === undefined || doc === null
? undefined
: doc['_doc']
? doc['_doc']
: doc['value']
? doc['value']
: doc;
// console.log('Received cast:', cast);
receivedItem =
cast !== undefined &&
cast !== null &&
cast !== '' &&
cast !== 'none' &&
doc !== undefined &&
doc !== null
? doc[cast]()
: doc;
if (receivedItem && receivedItem._id) {
if (!receivedItem.id)
receivedItem.id = receivedItem._id;
delete receivedItem._id;
}
return receivedItem;
}
createItem(scheme, item) {
return new Promise((resolve, reject) => {
const newItem = this.generateNewItem(item);
const fullOperation = {
operation: __1.Operation.create,
type: type_1.Type.item,
subType: subType_1.SubType.byFilter,
};
const callback = (error, doc) => {
// console.log('Scheme:', scheme, item, newItem);
if (error) {
// console.error('error:', error);
reject(error);
}
else {
// console.log('doc:', doc);
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: doc,
sentItem: item,
}));
}
};
this.populateAll.bind(this)(scheme, 'create', [newItem], fullOperation, callback.bind(this));
});
}
async createArray(scheme, item, regular, options) {
const items = this.generateNewArray(item, regular);
const fullOperation = {
operation: __1.Operation.create,
type: type_1.Type.array,
subType: subType_1.SubType.byFilter,
};
return new Promise((resolve, reject) => {
const callback = (error, docs) => {
// console.log('Scheme ARRAY:', scheme, item, items);
if (error) {
// console.error('error:', error);
reject(error);
}
else {
// console.log('docs:', docs);
const receivedItem = this.generateReceivedArray.bind(this)(docs, scheme, fullOperation);
resolve(this.cleanReceived.bind(this)({
receivedItem: receivedItem,
result: docs,
sentItem: item,
}));
}
};
this.populateAll.bind(this)(scheme, 'insertMany', [items, options], fullOperation, callback.bind(this));
});
}
readArray(scheme, selectedItem, options, additionalOptions, eventOptions) {
return new Promise((resolve, reject) => {
const compiledOptions = this.generateOptions(options, eventOptions);
const newSelectedItem = this.generateNewItem(selectedItem);
const fullOperation = {
operation: __1.Operation.read,
type: type_1.Type.array,
subType: subType_1.SubType.byFilter,
};
const callback = async (error, docs) => {
// console.log('Scheme readArray:', scheme);
if (error) {
reject(error);
}
else {
await this.count.bind(this)(scheme, newSelectedItem, options, eventOptions, compiledOptions);
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedArray.bind(this)(docs, scheme, fullOperation),
result: docs,
selectedItem: selectedItem,
}));
}
};
this.populateAll.bind(this)(scheme, 'find', [newSelectedItem, additionalOptions, compiledOptions], fullOperation, callback.bind(this));
});
}
readItem(scheme, selectedItem, options, additionalOptions, eventOptions) {
return new Promise((resolve, reject) => {
const compiledOptions = this.generateOptions(options, eventOptions);
const newSelectedItem = this.generateNewItem(selectedItem);
const fullOperation = {
operation: __1.Operation.read,
type: type_1.Type.item,
subType: subType_1.SubType.byFilter,
};
const callback = async (error, doc) => {
// console.log('Scheme readArray:', scheme);
if (error) {
reject(error);
}
else {
await this.count.bind(this)(scheme, newSelectedItem, options, eventOptions, compiledOptions);
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: doc,
selectedItem,
}));
}
};
this.populateAll.bind(this)(scheme, 'findOne', [newSelectedItem, additionalOptions, compiledOptions], fullOperation, callback.bind(this));
});
}
readItemById(scheme, id, options, additionalOptions, eventOptions) {
return new Promise((resolve, reject) => {
const compiledOptions = this.generateOptions(options, eventOptions);
const fullOperation = {
operation: __1.Operation.read,
type: type_1.Type.item,
subType: subType_1.SubType.byId,
};
const callback = async (error, doc) => {
if (error) {
reject(error);
}
else {
await this.count.bind(this)(scheme, { id: id }, options, eventOptions, compiledOptions);
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: doc,
selectedItem: { id: id },
}));
}
};
this.populateAll.bind(this)(scheme, 'findById', [id, additionalOptions, compiledOptions], fullOperation, callback.bind(this));
});
}
async updateItem(scheme, selectedItem, item, options) {
return new Promise(async (resolve) => {
const newItem = this.generateNewItem(item);
const newSelectedItem = this.generateNewItem(selectedItem);
const response = await this.findOneAndUpdate.bind(this)(scheme, newSelectedItem, newItem, options);
resolve(this.cleanReceived.bind(this)({
...response,
selectedItem: selectedItem,
sentItem: item,
}));
});
}
updateArray(scheme, selectedItem, item, regular, options) {
return new Promise(async (resolve, reject) => {
const newItem = Array.isArray(item)
? this.generateNewArray(item, regular)
: this.generateNewItem(item);
if (Array.isArray(newItem)) {
// console.log('newItem Array:', newItem);
const promisedResponses = [];
for (let index = 0; index < newItem.length; index++) {
const newItemElement = newItem[index];
const selectedItemElement = Array.isArray(selectedItem)
? selectedItem[index]
: {
id: newItemElement.id,
_id: newItemElement._id,
...selectedItem,
};
// delete newItemElement.id;
// delete newItemElement._id;
// console.log(
// '-selectedItemElement:',
// selectedItemElement,
// newItemElement
// );
promisedResponses.push(this.findOneAndUpdate.bind(this)(scheme, selectedItemElement, newItemElement, options));
}
const responses = await Promise.all(promisedResponses);
// console.log('responses:', responses);
resolve(this.cleanReceived.bind(this)({
receivedItem: responses.map((response) => response.receivedItem),
result: responses.map((response) => response.result),
selectedItem: selectedItem,
sentItem: item,
}));
}
else {
// console.log('newItem:', newItem);
const fullOperation = {
operation: __1.Operation.update,
type: type_1.Type.array,
subType: subType_1.SubType.byFilter,
};
const callback = (error, doc) => {
// console.log('Scheme:', scheme);
if (error) {
reject(error);
}
else {
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: doc,
selectedItem: selectedItem,
sentItem: item,
}));
}
};
this.populateAll.bind(this)(scheme, 'updateMany', [selectedItem, newItem, options], fullOperation, callback.bind(this));
}
});
}
deleteArray(scheme, selectedItem, options) {
return new Promise((resolve, reject) => {
const newSelectedItem = this.generateNewItem(selectedItem);
const fullOperation = {
operation: __1.Operation.delete,
type: type_1.Type.array,
subType: subType_1.SubType.byFilter,
};
const callback = (error) => {
// console.log('Scheme:', scheme);
if (error) {
reject(error);
}
else {
resolve(this.cleanReceived.bind(this)({
selectedItem,
}));
}
};
this.populateAll.bind(this)(scheme, 'deleteMany', [newSelectedItem, options], fullOperation, callback.bind(this));
});
}
deleteItem(scheme, selectedItem, options) {
return new Promise((resolve, reject) => {
const newSelectedItem = this.generateNewItem(selectedItem);
const fullOperation = {
operation: __1.Operation.delete,
type: type_1.Type.item,
subType: subType_1.SubType.byFilter,
};
const callback = (error, doc) => {
// console.log('Scheme:', scheme);
if (error) {
reject(error);
}
else {
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: doc,
selectedItem: selectedItem,
}));
}
};
this.populateAll.bind(this)(scheme, 'findOneAndDelete', [newSelectedItem, options], fullOperation, callback.bind(this));
});
}
deleteItemById(scheme, id, options) {
return new Promise((resolve, reject) => {
const fullOperation = {
operation: __1.Operation.delete,
type: type_1.Type.item,
subType: subType_1.SubType.byId,
};
const callback = (error, doc) => {
// console.log('Scheme:', scheme);
if (error) {
reject(error);
}
else {
resolve(this.cleanReceived.bind(this)({
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: doc,
selectedItem: { id: id },
}));
}
};
this.populateAll.bind(this)(scheme, 'findByIdAndDelete', [id, options], fullOperation, callback.bind(this));
});
}
async findOneAndUpdateResult(
// eslint-disable-next-line no-unused-vars
resolve,
// eslint-disable-next-line no-unused-vars
reject, error, doc, result, scheme, fullOperation) {
if (error) {
reject(error);
}
else {
const item = {
receivedItem: this.generateReceivedItem.bind(this)(doc, scheme, fullOperation),
result: result ? { doc, result } : doc,
};
resolve(item);
}
}
async findOneAndUpdate(scheme, selectedItem, item, options) {
return new Promise(async (resolve, reject) => {
delete item.id;
delete item._id;
const id = selectedItem?.id || selectedItem?._id;
const fullOperation = {
operation: __1.Operation.update,
type: type_1.Type.item,
};
if (id) {
fullOperation.subType = subType_1.SubType.byId;
const callback = (error, doc, result) => {
// console.log('selectedItem:', selectedItem);
this.findOneAndUpdateResult.bind(this)(resolve, reject, error, doc, result, scheme, fullOperation);
};
this.populateAll.bind(this)(scheme, 'findByIdAndUpdate', [id, item, { new: true, ...options }], fullOperation, callback.bind(this));
}
else {
fullOperation.subType = subType_1.SubType.byFilter;
const callback = (error, doc, result) => {
// console.log('selectedItem:', selectedItem);
this.findOneAndUpdateResult.bind(this)(resolve, reject, error, doc, result, scheme, fullOperation);
};
this.populateAll.bind(this)(scheme, 'findOneAndUpdate', [selectedItem, item, options], fullOperation, callback.bind(this));
}
});
}
getPersistenceInfo() {
return this.persistenceInfo;
}
async close() {
try {
await this.mongooseInstance.connection.close(true);
return true;
}
catch (error) {
console.error(error);
return false;
}
}
}
exports.MongoPersistence = MongoPersistence;
//# sourceMappingURL=mongoPersistence.js.map