UNPKG

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
"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;