base.service.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // ./services/base.service.js
  2. import { getStatusCode, StatusCodes } from "http-status-codes";
  3. import ApplicationError from "../libs/errors/application.error.js";
  4. class BaseService {
  5. getModel() {
  6. throw Error("Should be overridden");
  7. }
  8. async find(params = {}, options = {}) {
  9. let queryModel = this.getModel();
  10. let searchQuery = Object.assign({}, params);
  11. const aggregate = options.aggregate;
  12. if (aggregate) {
  13. const aggregation = await queryModel.aggregate(aggregate);
  14. const aggregationIds = aggregation.map(({ _id }) => _id);
  15. searchQuery = Object.assign({}, searchQuery, {
  16. _id: { $in: aggregationIds },
  17. });
  18. }
  19. queryModel = this.getModel().find(searchQuery).lean();
  20. const populate = options.populate;
  21. if (populate) {
  22. if (Array.isArray(populate)) {
  23. populate.forEach((population) => {
  24. queryModel.populate(population);
  25. });
  26. } else {
  27. queryModel.populate(populate);
  28. }
  29. }
  30. return queryModel.exec();
  31. }
  32. async findById(id, options = {}) {
  33. const record = await this.byId(id, options);
  34. if (!record) {
  35. throw new ApplicationError(
  36. getStatusCode(StatusCodes.NOT_FOUND),
  37. "Record not found",
  38. StatusCodes.NOT_FOUND
  39. );
  40. }
  41. return record;
  42. }
  43. async byId(id, options = {}) {
  44. let model = this.getModel().findById(id);
  45. const populate = options.populate;
  46. if (populate) {
  47. if (Array.isArray(populate)) {
  48. populate.forEach((population) => {
  49. model = model.populate(population);
  50. });
  51. } else {
  52. model.populate(populate);
  53. }
  54. }
  55. return model.lean().exec();
  56. }
  57. async oneBy(q) {
  58. return this.getModel().findOne(q).lean().exec();
  59. }
  60. async all() {
  61. return this.getModel().find({}).lean().exec();
  62. }
  63. async paginate(limit, skip, searchOptions, options = {}) {
  64. let queryModel = this.getModel();
  65. let searchQuery = Object.assign({}, searchOptions);
  66. const aggregate = options.aggregate;
  67. if (aggregate) {
  68. const aggregation = await queryModel.aggregate(aggregate);
  69. const aggregationIds = aggregation.map(({ _id }) => _id);
  70. searchQuery = Object.assign({}, searchQuery, {
  71. _id: { $in: aggregationIds },
  72. });
  73. }
  74. queryModel = queryModel.find(searchQuery).limit(limit).skip(skip).lean();
  75. const populate = options.populate;
  76. if (populate) {
  77. if (Array.isArray(populate)) {
  78. populate.forEach((population) => {
  79. queryModel.populate(population);
  80. });
  81. } else {
  82. queryModel.populate(populate);
  83. }
  84. }
  85. return Promise.all([
  86. queryModel.exec(),
  87. this.getModel().find(searchOptions).count({}),
  88. ]);
  89. }
  90. async create(data) {
  91. try {
  92. const record = new (this.getModel())(data);
  93. return record.save();
  94. } catch (error) {
  95. throw new ApplicationError(
  96. getStatusCode(StatusCodes.INTERNAL_SERVER_ERROR),
  97. error.message,
  98. StatusCodes.INTERNAL_SERVER_ERROR
  99. );
  100. }
  101. }
  102. async update(id, data) {
  103. return this.getModel()
  104. .findOneAndUpdate({ _id: id }, data, { new: true });
  105. }
  106. async deleteLogically(id, deletedBy) {
  107. const result = await this.getModel().update(
  108. { _id: id },
  109. { $set: { active: false, deletedBy: deletedBy } }
  110. );
  111. return result;
  112. }
  113. async delete(id) {
  114. return this.getModel().findOneAndDelete({ _id: id });
  115. }
  116. async deleteMany(filter) {
  117. return this.getModel().deleteMany(filter);
  118. }
  119. async remove(id) {
  120. const result = await this.getModel().findById({ _id: id });
  121. result.remove();
  122. return result;
  123. }
  124. }
  125. export default BaseService;