Spaces:
Running
Running
File size: 4,843 Bytes
484fdbc 184c874 484fdbc fc659a3 484fdbc 61c7d9c 484fdbc fc659a3 61c7d9c 484fdbc 61c7d9c fc659a3 61c7d9c fc659a3 61c7d9c 484fdbc 513e649 484fdbc dd1edf0 184c874 dd1edf0 513e649 184c874 484fdbc 513e649 fc659a3 dd1edf0 484fdbc 184c874 86f4808 484fdbc 52ccf8d fc659a3 52ccf8d fc659a3 52ccf8d 184c874 484fdbc 86f4808 fc659a3 86f4808 484fdbc 86f4808 733f745 86f4808 61c7d9c 184c874 733f745 184c874 484fdbc 61c7d9c 484fdbc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
import { HttpError } from "@lib/error-handling/http-error";
import { AnyKeys, Document, FilterQuery, Model } from "mongoose";
export const CrudService = <ModelDoc extends Document>(
model: Model<ModelDoc>,
crudOptions?: {
defaultFilter?: FilterQuery<ModelDoc>;
}
) => {
return class CrudServiceClass {
protected model: Model<ModelDoc> = model;
async create(data: AnyKeys<ModelDoc>): Promise<ModelDoc> {
return this.model.create(data);
}
async updateOne(
filter: FilterQuery<ModelDoc>,
data: AnyKeys<ModelDoc>
): Promise<ModelDoc> {
filter = { ...crudOptions?.defaultFilter, ...filter };
await this.existsOrThrow(filter);
await this.model.updateOne(filter, data);
return this.findOneOrFail(filter);
}
async updateMany(
filter: FilterQuery<ModelDoc>,
data: AnyKeys<ModelDoc>
): Promise<ModelDoc[]> {
filter = { ...crudOptions?.defaultFilter, ...filter };
await this.existsOrThrow(filter);
await this.model.updateMany(filter, data);
return this.model.find(filter);
}
async deleteOne(filter: FilterQuery<ModelDoc>): Promise<ModelDoc> {
filter = { ...crudOptions?.defaultFilter, ...filter };
await this.existsOrThrow(filter);
return this.model.findOneAndDelete(filter);
}
async list(
filter: FilterQuery<ModelDoc>,
paginationOptions: {
limit?: number;
skip?: number;
} = {
limit: 10,
skip: 1,
},
options?: {
populateArray?: any,
filterOptions?: any
},
): Promise<{
docs: ModelDoc[];
paginationData: {
total: number;
page: number;
perPage: number;
};
}> {
if (options?.filterOptions) filter = { ...filter, ...options.filterOptions };
filter = { ...crudOptions?.defaultFilter, ...filter };
const queryInstruction = this.model
.find(filter)
.limit(paginationOptions.limit)
.skip(paginationOptions.skip);
if (options?.populateArray) queryInstruction.populate(options.populateArray);
const docs = await queryInstruction;
const total = await this.model.countDocuments(filter);
const paginationData = {
total: total,
page: paginationOptions.skip,
perPage: paginationOptions.limit,
};
return { docs, paginationData };
}
async listAll(
filter: FilterQuery<ModelDoc>,
options?: {
populateArray: any
},
): Promise<ModelDoc[]> {
filter = { ...crudOptions?.defaultFilter, ...filter };
const queryInstruction = this.model.find(filter);
if (options?.populateArray) queryInstruction.populate(options.populateArray);
return queryInstruction;
}
async search(
filter: FilterQuery<ModelDoc>,
paginationOptions: {
limit?: number;
skip?: number;
} = {
limit: 10,
skip: 1,
},
options?: {
populateArray: any
},
): Promise<{
docs: ModelDoc[];
paginationData: {
total: number;
page: number;
perPage: number;
};
}> {
filter = { ...crudOptions?.defaultFilter, ...filter };
const queryInstruction = this.model
.find(filter)
.limit(paginationOptions.limit)
.skip(paginationOptions.skip);
if (options?.populateArray) queryInstruction.populate(options.populateArray);
const docs = await queryInstruction;
const total = await this.model.countDocuments(filter);
const paginationData = {
total: total,
page: paginationOptions.skip,
perPage: paginationOptions.limit,
};
return { docs, paginationData };
}
async findOne(
filter: FilterQuery<ModelDoc>,
options?: {
populateArray: any
}): Promise<ModelDoc | null> {
const queryInstruction = this.model.findOne();
if (options?.populateArray) queryInstruction.populate(options.populateArray);
const document = await queryInstruction
return document;
}
async findOneOrFail(
filter: FilterQuery<ModelDoc>,
options?: {
populateArray?: any,
selectArray?: any
}
): Promise<ModelDoc> {
await this.existsOrThrow(filter);
const queryInstruction = this.model.findOne(filter);
if (options?.populateArray) queryInstruction.populate(options.populateArray);
if (options?.selectArray) queryInstruction.select(options.selectArray);
const document = await queryInstruction;
return document;
}
private async existsOrThrow(filter: FilterQuery<ModelDoc>) {
if (!(await this.model.exists(filter))) {
throw new HttpError(404, "No Matching Result Found.");
}
}
};
};
|