UNPKG

express-base-controller

Version:
334 lines 12.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const mongoose_1 = require("mongoose"); const api_controller_1 = __importDefault(require("./api.controller")); const helpers_1 = require("./helpers"); const isValidId = mongoose_1.Types.ObjectId.isValid; class BaseController extends api_controller_1.default { constructor(model) { super(model); this.filters = ['type', 'deleted']; } index(req, _res, next) { return __awaiter(this, void 0, void 0, function* () { let query = { deleted: false, limit: 100, offset: 0, q: {}, select: {}, sort: null, total: {}, }; const processedQuery = this.processQuery(req.query, query); if (typeof this.model.parseQuery === 'function') { query = this.model.parseQuery(processedQuery); } else { query = this.parseQuery(processedQuery); } query.populate = query.populate ? query.populate : []; return this.model.find(query.q) .limit((0, helpers_1.toNumber)(query.limit)) .skip((0, helpers_1.toNumber)(query.offset)) .sort(query.sort) .select(query.select) .populate(query.populate) .exec() .then((models) => { req.data = models; return next(); }) .catch((err) => next(err)); }); } read(req, res, _next) { return __awaiter(this, void 0, void 0, function* () { if (this.hasModel(req.model)) { const model = req.model.toObject(); return res.jsonp(model); } else { return this.respondModelMissingError(res); } }); } create(req, res, next) { return __awaiter(this, void 0, void 0, function* () { var _a; delete req.body._id; delete req.body.timestamps; const Model = this.model; const entity = Object.assign(Object.assign({}, req.body), { timestamps: { created: { by: ((_a = req.user) === null || _a === void 0 ? void 0 : _a.username) || 'missing', }, } }); const model = new Model(entity); return model.save() .then((resModel) => (res.status(201).json(resModel.toObject()))) .catch((err) => this.respondValidationError(err, res, next)); }); } update(req, res, next) { return __awaiter(this, void 0, void 0, function* () { var _a; if (req.body._id === null) { delete req.body._id; } delete req.body.timestamps; if (this.hasModel(req.model)) { const model = req.model; Object.keys(req.body).forEach((key) => { model[key] = req.body[key]; }); model.timestamps.updated.by = ((_a = req.user) === null || _a === void 0 ? void 0 : _a.username) || 'missing'; return model.save() .then((resModel) => res.status(200).json(resModel.toObject())) .catch((err) => this.respondValidationError(err, res, next)); } else { return this.respondModelMissingError(res); } }); } softDelete(req, res, _next) { return __awaiter(this, void 0, void 0, function* () { var _a; if (this.hasModel(req.model)) { const model = req.model; model.mark.deleted = true; model.timestamps.updated.by = ((_a = req.user) === null || _a === void 0 ? void 0 : _a.username) || 'missing'; return model.save() .then((resModel) => res.status(200).jsonp(resModel.toObject())) .catch((err) => this.respondDeletionError(res, err)); } else { return Promise.resolve(this.respondModelMissingError(res)); } }); } delete(req, res, _next) { return __awaiter(this, void 0, void 0, function* () { if (this.hasModel(req.model)) { const model = req.model; return this.model.deleteOne({ _id: model._id }) .then(() => res.status(200).jsonp(model.toObject())) .catch((err) => { if (err instanceof Error) { return this.respondDeletionError(res, err); } else { return this.respondDeletionError(res, new Error('Unknown error occurred while deleting')); } }); } else { return this.respondModelMissingError(res); } }); } findById(req, res, next, id, _urlParam, populate) { return __awaiter(this, void 0, void 0, function* () { if (isValidId(id)) { if (typeof populate === 'undefined') { populate = []; } return this.model .findById(id) .populate(populate) .exec() .then((model) => { if (model === null) { return this.respondNotFound(id, res, this.model.modelName); } else if (this.hasModel(model)) { req.model = model; return next(); } else { return this.respondModelMissingError(res); } }) .catch((err) => this.respondServerError(res, err)); } else { return this.respondInvalidId(res); } }); } stats(req, res, next) { return __awaiter(this, void 0, void 0, function* () { return this.model.countDocuments() .then((result) => { if (typeof req.stats !== 'object') { req.stats = {}; } req.stats[this.model.collection.name] = result; return next(); }) .catch((err) => this.respondServerError(res, err)); }); } statsResponse(req, res, _next) { if (typeof req.stats !== 'object') { req.stats = {}; } return res.status(200).json(req.stats); } statistics(req, res, next) { return __awaiter(this, void 0, void 0, function* () { if (typeof this.model.statistics === 'function') { const query = req.dateRange || {}; return this.model.statistics(query).then((result) => { if (typeof req.stats !== 'object') { req.stats = {}; } req.stats[this.model.collection.name] = result; return next(); }) .catch((err) => this.respondServerError(res, err)); } else { return this.stats(req, res, next); } }); } parseDateRange(req, _res, next, _id, _urlParam) { const year = parseInt(req.params.year, 10); let month = parseInt(req.params.month, 10); let toMonth = 12; if (!isNaN(year)) { if (isNaN(month)) { month = 0; } else { month = Math.max(Math.min(month, 12), 1); toMonth = --month + 1; } let from = new Date(); from = new Date(from.setFullYear(year, month, 1)); from = new Date(from.setHours(0, 0, 0, 0)); let to = new Date(from.valueOf()); to = new Date(to.setFullYear(year, toMonth, 1)); if (typeof req.stats !== 'object') { req.stats = {}; } req.stats.range = { from: from, to: to, }; req.dateRange = { $and: [{ date: { $gte: from } }, { date: { $lt: to } }] }; } return next(); } processQuery(query, defaultQuery) { const modelQuery = { offset: 0, deleted: false, limit: 100, q: {}, select: {}, sort: null, total: {}, }; if (typeof query.offset === 'string') { modelQuery.offset = this.parsePagination(query.offset, defaultQuery.offset); } if (typeof query.limit === 'string') { modelQuery.limit = this.parsePagination(query.limit, defaultQuery.limit); } if (typeof query.sort === 'string') { modelQuery.sort = this.parseSort(query.sort); } if (typeof query.filter === 'string') { modelQuery.filter = this.parseFilter(query.filter); } return modelQuery; } parseSort(sort = null) { if (sort) { const parsedSort = {}; let _sort = {}; try { _sort = JSON.parse(sort); } catch (error) { if (error instanceof SyntaxError) { _sort = sort.split(' ') .filter(s => /^\w+$/.test(s)) .reduce((acc, cur) => { acc[cur] = 1; return acc; }, {}); } else { throw error; } } Object.entries(_sort).forEach(([key, value]) => { const order = (0, helpers_1.isString)(value) ? parseInt(value, 10) : value; parsedSort[key] = isNaN(order) ? 1 : Math.min(Math.max(order, -1), 1); }); if (Object.keys(parsedSort).length === 0) { parsedSort['date'] = -1; } return parsedSort; } else { return null; } } parseFilter(filterQuery = null) { let filter = {}; try { filter = filterQuery ? JSON.parse(filterQuery.replace(/\'/g, '"')) : {}; } catch (e) { filter = {}; } const allowedFilters = {}; this.filters.forEach(f => { if (typeof filter[f] !== 'undefined' && filter[f] !== null) { allowedFilters[f] = filter[f].toString(); } }); return allowedFilters; } parsePagination(value, defaultValue) { const _value = (0, helpers_1.toNumber)(value); const _default = (0, helpers_1.toNumber)(defaultValue); return isNaN(_value) ? _default : _value; } parseQuery(query) { return { q: {}, offset: query.offset || 0, limit: query.limit || 100, sort: query.sort ? Object.assign({}, query.sort) : null, filter: Object.assign({}, query.filter), populate: query.populate ? [...query.populate] : [], deleted: !!query.deleted, select: query.select ? Object.assign({}, query.select) : {}, total: {}, }; } } exports.default = BaseController; //# sourceMappingURL=base.controller.js.map