diff --git a/src/models/plugins/index.js b/src/models/plugins/index.js new file mode 100644 index 00000000..d85ebb80 --- /dev/null +++ b/src/models/plugins/index.js @@ -0,0 +1,2 @@ +module.exports.toJSON = require('./toJSON.plugin'); +module.exports.paginate = require('./paginate.plugin'); diff --git a/src/models/plugins.js b/src/models/plugins/paginate.plugin.js similarity index 65% rename from src/models/plugins.js rename to src/models/plugins/paginate.plugin.js index 9f1c9549..073ec887 100644 --- a/src/models/plugins.js +++ b/src/models/plugins/paginate.plugin.js @@ -1,36 +1,5 @@ /* eslint-disable no-param-reassign */ -/** - * A mongoose schema plugin which applies the following in the toJSON transform call: - * - removes __v, createdAt, updatedAt, and any path that has private: true - * - replaces _id with id - */ -const toJSON = (schema) => { - let transform; - if (schema.options.toJSON && schema.options.toJSON.transform) { - transform = schema.options.toJSON.transform; - } - - schema.options.toJSON = Object.assign(schema.options.toJSON || {}, { - transform(doc, ret, options) { - Object.keys(schema.paths).forEach((path) => { - if (schema.paths[path].options && schema.paths[path].options.private) { - delete ret[path]; - } - }); - - ret.id = ret._id.toString(); - delete ret._id; - delete ret.__v; - delete ret.createdAt; - delete ret.updatedAt; - if (transform) { - return transform(doc, ret, options); - } - }, - }); -}; - const paginate = (schema) => { /** * @typedef {Object} QueryResult @@ -77,7 +46,4 @@ const paginate = (schema) => { }; }; -module.exports = { - toJSON, - paginate, -}; +module.exports = paginate; diff --git a/src/models/plugins/toJSON.plugin.js b/src/models/plugins/toJSON.plugin.js new file mode 100644 index 00000000..bb7abda9 --- /dev/null +++ b/src/models/plugins/toJSON.plugin.js @@ -0,0 +1,34 @@ +/* eslint-disable no-param-reassign */ + +/** + * A mongoose schema plugin which applies the following in the toJSON transform call: + * - removes __v, createdAt, updatedAt, and any path that has private: true + * - replaces _id with id + */ +const toJSON = (schema) => { + let transform; + if (schema.options.toJSON && schema.options.toJSON.transform) { + transform = schema.options.toJSON.transform; + } + + schema.options.toJSON = Object.assign(schema.options.toJSON || {}, { + transform(doc, ret, options) { + Object.keys(schema.paths).forEach((path) => { + if (schema.paths[path].options && schema.paths[path].options.private) { + delete ret[path]; + } + }); + + ret.id = ret._id.toString(); + delete ret._id; + delete ret.__v; + delete ret.createdAt; + delete ret.updatedAt; + if (transform) { + return transform(doc, ret, options); + } + }, + }); +}; + +module.exports = toJSON; diff --git a/tests/unit/models/plugins.test.js b/tests/unit/models/plugins.test.js deleted file mode 100644 index e8c41a55..00000000 --- a/tests/unit/models/plugins.test.js +++ /dev/null @@ -1,72 +0,0 @@ -const mongoose = require('mongoose'); -const { toJSON } = require('../../../src/models/plugins'); - -describe('Model utils', () => { - describe('toJSON plugin', () => { - let connection; - - beforeEach(() => { - connection = mongoose.createConnection(); - }); - - it('should replace _id with id', () => { - const schema = mongoose.Schema(); - schema.plugin(toJSON); - const Model = connection.model('Model', schema); - const doc = new Model(); - expect(doc.toJSON()).not.toHaveProperty('_id'); - expect(doc.toJSON()).toHaveProperty('id', doc._id.toString()); - }); - - it('should remove __v', () => { - const schema = mongoose.Schema(); - schema.plugin(toJSON); - const Model = connection.model('Model', schema); - const doc = new Model(); - expect(doc.toJSON()).not.toHaveProperty('__v'); - }); - - it('should remove createdAt and updatedAt', () => { - const schema = mongoose.Schema({}, { timestamps: true }); - schema.plugin(toJSON); - const Model = connection.model('Model', schema); - const doc = new Model(); - expect(doc.toJSON()).not.toHaveProperty('createdAt'); - expect(doc.toJSON()).not.toHaveProperty('updatedAt'); - }); - - it('should remove any path set as private', () => { - const schema = mongoose.Schema({ - public: { type: String }, - private: { type: String, private: true }, - }); - schema.plugin(toJSON); - const Model = connection.model('Model', schema); - const doc = new Model({ public: 'some public value', private: 'some private value' }); - expect(doc.toJSON()).not.toHaveProperty('private'); - expect(doc.toJSON()).toHaveProperty('public'); - }); - - it('should also call the schema toJSON transform function', () => { - const schema = mongoose.Schema( - { - public: { type: String }, - private: { type: String }, - }, - { - toJSON: { - transform: (doc, ret) => { - // eslint-disable-next-line no-param-reassign - delete ret.private; - }, - }, - } - ); - schema.plugin(toJSON); - const Model = connection.model('Model', schema); - const doc = new Model({ public: 'some public value', private: 'some private value' }); - expect(doc.toJSON()).not.toHaveProperty('private'); - expect(doc.toJSON()).toHaveProperty('public'); - }); - }); -}); diff --git a/tests/unit/models/plugins/toJSON.plugin.test.js b/tests/unit/models/plugins/toJSON.plugin.test.js new file mode 100644 index 00000000..7e7fb92d --- /dev/null +++ b/tests/unit/models/plugins/toJSON.plugin.test.js @@ -0,0 +1,70 @@ +const mongoose = require('mongoose'); +const { toJSON } = require('../../../../src/models/plugins'); + +describe('toJSON plugin', () => { + let connection; + + beforeEach(() => { + connection = mongoose.createConnection(); + }); + + it('should replace _id with id', () => { + const schema = mongoose.Schema(); + schema.plugin(toJSON); + const Model = connection.model('Model', schema); + const doc = new Model(); + expect(doc.toJSON()).not.toHaveProperty('_id'); + expect(doc.toJSON()).toHaveProperty('id', doc._id.toString()); + }); + + it('should remove __v', () => { + const schema = mongoose.Schema(); + schema.plugin(toJSON); + const Model = connection.model('Model', schema); + const doc = new Model(); + expect(doc.toJSON()).not.toHaveProperty('__v'); + }); + + it('should remove createdAt and updatedAt', () => { + const schema = mongoose.Schema({}, { timestamps: true }); + schema.plugin(toJSON); + const Model = connection.model('Model', schema); + const doc = new Model(); + expect(doc.toJSON()).not.toHaveProperty('createdAt'); + expect(doc.toJSON()).not.toHaveProperty('updatedAt'); + }); + + it('should remove any path set as private', () => { + const schema = mongoose.Schema({ + public: { type: String }, + private: { type: String, private: true }, + }); + schema.plugin(toJSON); + const Model = connection.model('Model', schema); + const doc = new Model({ public: 'some public value', private: 'some private value' }); + expect(doc.toJSON()).not.toHaveProperty('private'); + expect(doc.toJSON()).toHaveProperty('public'); + }); + + it('should also call the schema toJSON transform function', () => { + const schema = mongoose.Schema( + { + public: { type: String }, + private: { type: String }, + }, + { + toJSON: { + transform: (doc, ret) => { + // eslint-disable-next-line no-param-reassign + delete ret.private; + }, + }, + } + ); + schema.plugin(toJSON); + const Model = connection.model('Model', schema); + const doc = new Model({ public: 'some public value', private: 'some private value' }); + expect(doc.toJSON()).not.toHaveProperty('private'); + expect(doc.toJSON()).toHaveProperty('public'); + }); +});