-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0ba5241
commit 857a465
Showing
3 changed files
with
138 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* eslint-disable no-param-reassign */ | ||
|
||
/** | ||
* A mongoose schema plugin which allows user to hide fields dynamically using a hide option | ||
*/ | ||
|
||
const inlineToJSON = (schema: any) => { | ||
schema.options.toJSON = {}; | ||
schema.options.toJSON.hide = ''; | ||
schema.options.toJSON.transform = function (doc: any, ret: any, options: Record<string, any>) { | ||
if (options['hide']) { | ||
options['hide'].split(' ').forEach(function (prop: string) { | ||
delete ret[prop]; | ||
}); | ||
} | ||
ret.id = ret._id.toString(); | ||
delete ret._id; | ||
delete ret.__v; | ||
delete ret.createdAt; | ||
delete ret.updatedAt; | ||
return ret; | ||
}; | ||
}; | ||
|
||
export default inlineToJSON; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* eslint-disable no-param-reassign */ | ||
|
||
const paginate = (schema: any) => { | ||
/** | ||
* @typedef {Object} QueryResult | ||
* @property {Document[]} results - Results found | ||
* @property {number} page - Current page | ||
* @property {number} limit - Maximum number of results per page | ||
* @property {number} totalPages - Total number of pages | ||
* @property {number} totalResults - Total number of documents | ||
*/ | ||
/** | ||
* Query for documents with pagination | ||
* @param {Object} [filter] - Mongo filter | ||
* @param {Object} [options] - Query options | ||
* @param {string} [options.sortBy] - Sorting criteria using the format: sortField:(desc|asc). Multiple sorting criteria should be separated by commas (,) | ||
* @param {string} [options.populate] - Populate data fields. Hierarchy of fields should be separated by (.). Multiple populating criteria should be separated by commas (,) | ||
* @param {number} [options.limit] - Maximum number of results per page (default = 10) | ||
* @param {number} [options.page] - Current page (default = 1) | ||
* @returns {Promise<QueryResult>} | ||
*/ | ||
schema.statics.paginate = async function (filter: Record<string, any>, options: Record<string, any>) { | ||
let sort = ''; | ||
if (options['sortBy']) { | ||
const sortingCriteria: any = []; | ||
options['sortBy'].split(',').forEach((sortOption: string) => { | ||
const [key, order] = sortOption.split(':'); | ||
sortingCriteria.push((order === 'desc' ? '-' : '') + key); | ||
}); | ||
sort = sortingCriteria.join(' '); | ||
} else { | ||
sort = 'createdAt'; | ||
} | ||
|
||
const limit = options['limit'] && parseInt(options['limit'], 10) > 0 ? parseInt(options['limit'], 10) : 10; | ||
const page = options['page'] && parseInt(options['page'], 10) > 0 ? parseInt(options['page'], 10) : 1; | ||
const skip = (page - 1) * limit; | ||
|
||
const countPromise = this.countDocuments(filter).exec(); | ||
let docsPromise = this.find(filter).sort(sort).skip(skip).limit(limit); | ||
|
||
if (options['populate']) { | ||
options['populate'].split(',').forEach((populateOption: any) => { | ||
docsPromise = docsPromise.populate( | ||
populateOption | ||
.split('.') | ||
.reverse() | ||
.reduce((a: string, b: string) => ({ path: b, populate: a })) | ||
); | ||
}); | ||
} | ||
|
||
docsPromise = docsPromise.exec(); | ||
|
||
return Promise.all([countPromise, docsPromise]).then((values) => { | ||
const [totalResults, results] = values; | ||
const totalPages = Math.ceil(totalResults / limit); | ||
const result = { | ||
results, | ||
page, | ||
limit, | ||
totalPages, | ||
totalResults, | ||
}; | ||
return Promise.resolve(result); | ||
}); | ||
}; | ||
}; | ||
|
||
export default paginate; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* 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 deleteAtPath = (obj: any, path: any, index: number) => { | ||
if (index === path.length - 1) { | ||
delete obj[path[index]]; | ||
return; | ||
} | ||
deleteAtPath(obj[path[index]], path, index + 1); | ||
}; | ||
|
||
const toJSON = (schema: any) => { | ||
let transform: Function; | ||
if (schema.options.toJSON && schema.options.toJSON.transform) { | ||
transform = schema.options.toJSON.transform; | ||
} | ||
|
||
schema.options.toJSON = Object.assign(schema.options.toJSON || {}, { | ||
transform(doc: any, ret: any, options: Record<string, any>) { | ||
Object.keys(schema.paths).forEach((path) => { | ||
if (schema.paths[path].options && schema.paths[path].options.private) { | ||
deleteAtPath(ret, path.split('.'), 0); | ||
} | ||
}); | ||
|
||
ret.id = ret._id.toString(); | ||
delete ret._id; | ||
delete ret.__v; | ||
delete ret.createdAt; | ||
delete ret.updatedAt; | ||
if (transform) { | ||
return transform(doc, ret, options); | ||
} | ||
}, | ||
}); | ||
}; | ||
|
||
export default toJSON; |