generic-repository
Version:
Generic repository pattern implementation for node.js. Currently supports mongo and in-memory(testing) databases.
147 lines (146 loc) • 5.01 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const not_found_error_1 = require("../errors/not_found_error");
class MemoryRepository {
constructor(type) {
this.Type = type;
this.docs = {};
}
count() {
return Promise.resolve(Object.keys(this.docs).length);
}
find(conditions) {
return Promise.resolve(this.findNow(conditions));
}
paginate(conditions, sortOptions, page, perPage) {
return Promise.resolve(this.findNow(conditions).slice(page * perPage - perPage, page * perPage));
}
findNow(conditions) {
const keys = Object.keys(this.docs);
const surveySubset = new Array();
keys.forEach(key => {
if (this.query(this.docs[key], conditions) && surveySubset.length < 5) {
surveySubset.push(this.docs[key]);
}
});
return surveySubset;
}
findOne(conditions) {
if (typeof conditions === 'string') {
if (this.docs[conditions]) {
return Promise.resolve(new this.Type(this.docs[conditions]));
}
else {
return Promise.reject(new Error(conditions + ' does not exist'));
}
}
return this.find(conditions).then(res => {
if (res.length === 0)
throw new not_found_error_1.NotFoundError('Not found');
return res[0];
});
}
findById(id) {
if (this.docs[id]) {
return Promise.resolve(new this.Type(this.docs[id]));
}
else {
return Promise.reject(new not_found_error_1.NotFoundError(id + ' does not exist'));
}
}
insert(data) {
const insertData = new this.Type(data);
if (!insertData['_id'] && !this.docs[insertData['_id']]) {
insertData['_id'] = 'test123'; // generate id just like mongo would
}
this.docs[insertData['_id']] = insertData;
return Promise.resolve(insertData);
}
insertMany(list) {
const iterator = 0;
const result = list.map(item => {
const insertData = new this.Type(item);
if (!insertData['_id']) {
insertData['_id'] = 'test' + iterator; // generate id just like mongo would
}
this.docs[insertData['_id']] = insertData;
return insertData;
});
return Promise.resolve(result);
}
update(query, newData) {
const current = this.docs[query._id];
if (current) {
this.docs[query._id] = this.updateFields(current, newData);
return Promise.resolve(new this.Type(current));
}
else {
return this.insert(this.updateFields({ _id: query._id }, newData));
}
}
updateFields(target, data) {
Object.keys(data).forEach(key => {
if (key === '$set') {
this.updateFields(target, data[key]);
}
target[key] = data[key];
});
return target;
}
findLast(sortField, limit) {
const sorted = Object.values(this.docs).sort((a, b) => a[sortField] >= b[sortField] ? 1 : -1);
return Promise.resolve(sorted.slice(0, limit));
}
findLastByQuery(query, sortField, limit) {
return this.find(query);
}
query(obj, query) {
const keys = Object.keys(query);
let match = true;
keys.forEach(key => {
if (key === '$and') {
for (let i = 0; i < query.$and.length; i++) {
match = this.query(obj, query.$and[i]) ? match : false;
}
}
else if (query[key]['$in']) {
const inQuery = query[key]['$in'];
if (Array.isArray(obj[key])) {
match = obj[key].some((el) => inQuery.includes(el));
}
else {
match = inQuery.includes(obj[key]) || (inQuery.includes(null) && !obj[key]) ? match : false;
}
}
else if (query[key] !== obj[key]) {
match = false;
}
});
return match;
}
deleteMany(query) {
const keys = Object.keys(this.docs);
const surveySubset = new Array();
keys.forEach(key => {
if (this.query(this.docs[key], query)) {
surveySubset.push(this.docs[key]);
delete this.docs[key];
}
});
if (surveySubset.length > 0 || keys.length === 0) {
return Promise.resolve(true);
}
return Promise.reject(false);
}
deleteOne(query) {
const keys = Object.keys(this.docs);
return Promise.resolve(keys.some(key => {
if (this.query(this.docs[key], query)) {
delete this.docs[key];
return true;
}
return false;
}));
}
}
exports.default = MemoryRepository;