Skip to content

Instantly share code, notes, and snippets.

@wxs77577
Created September 26, 2019 09:53
Show Gist options
  • Save wxs77577/9baf6ad76fe2740308af910b910264fb to your computer and use it in GitHub Desktop.
Save wxs77577/9baf6ad76fe2740308af910b910264fb to your computer and use it in GitHub Desktop.
import { ModelType } from "@hasezoey/typegoose/lib/types";
import { CrudRequest, CreateManyDto, GetManyDefaultResponse, CrudService } from "@nestjsx/crud";
import { BadRequestException, NotFoundException } from "@nestjs/common";
import { mongoose } from "@hasezoey/typegoose";
export class MongooseCrudService<T> extends CrudService<T> {
constructor(public model: ModelType<T>) {
super()
}
buildQuery(req: CrudRequest) {
let { limit = 10, page = 1, offset: skip = 0, filter = [], fields = [], sort = [], join = [], paramsFilter = [] } = req.parsed
if (page > 1) {
skip = (page - 1) * limit
}
const options = {
page,
skip,
limit,
sort: sort.reduce((acc, v) => (acc[v.field] = v.order === 'ASC' ? 1 : -1, acc), {}),
populate: join.map(v => v.field),
select: fields.join(' ')
}
const where = filter.reduce((acc, { field, operator, value }) => {
let cond = null
switch (operator) {
case 'starts':
cond = new RegExp(`^${value}`, 'i')
break;
case 'ends':
cond = new RegExp(`${value}\$`, 'i')
break;
case 'cont':
cond = new RegExp(`${value}`, 'i')
break;
case 'excl':
cond = { $ne: new RegExp(`${value}`, 'i') }
break;
case 'notin':
cond = { $nin: value }
break
case 'isnull':
cond = null
break
case 'notnull':
cond = { $ne: null }
break
case 'between':
const [min, max] = value
cond = { $gte: min, $lte: max }
break
default:
cond = { [`\$${operator}`]: value }
}
acc[field] = cond
return acc
}, {})
const idParam = paramsFilter.find(v => v.field === 'id')
return { options, where, id: idParam ? idParam.value : null }
}
async getMany(req: CrudRequest) {
const { options, where } = this.buildQuery(req)
const queryBuilder = this.model.find().setOptions({
...options
}).where({
...where
})
options.populate.map(v => {
queryBuilder.populate(v)
})
const data = await queryBuilder.exec()
if (options.page) {
const total = await this.model.countDocuments(where)
return this.createPageInfo(data, total, options.limit, options.skip)
}
return data
}
async getOne(req: CrudRequest): Promise<T> {
const { options, where, id } = this.buildQuery(req)
const queryBuilder = this.model.findById(id).setOptions({
...options
}).where({
...where
})
options.populate.map(v => {
queryBuilder.populate(v)
})
const data = await queryBuilder.exec()
return data
}
createOne(req: CrudRequest, dto: T): Promise<T> {
throw new Error("Method not implemented.");
}
createMany(req: CrudRequest, dto: CreateManyDto<any>): Promise<T[]> {
throw new Error("Method not implemented.");
}
updateOne(req: CrudRequest, dto: T): Promise<T> {
throw new Error("Method not implemented.");
}
replaceOne(req: CrudRequest, dto: T): Promise<T> {
throw new Error("Method not implemented.");
}
deleteOne(req: CrudRequest): Promise<void | T> {
throw new Error("Method not implemented.");
}
throwBadRequestException(msg?: any): BadRequestException {
throw new Error("Method not implemented.");
}
throwNotFoundException(name: string): NotFoundException {
throw new Error("Method not implemented.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment