express-base-controller
Version:
a nodejs api controller
334 lines • 12.6 kB
JavaScript
;
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