Spaces:
Running
Running
File size: 5,195 Bytes
484fdbc 184c874 484fdbc fc659a3 484fdbc 6d6248c 484fdbc 61c7d9c 484fdbc fc659a3 61c7d9c 484fdbc 61c7d9c cbe2a8f 61c7d9c fc659a3 3daae40 cbe2a8f 61c7d9c fc659a3 61c7d9c 484fdbc 3daae40 484fdbc 3daae40 484fdbc dd1edf0 184c874 dd1edf0 513e649 184c874 484fdbc 513e649 fc659a3 3daae40 dd1edf0 484fdbc 184c874 86f4808 484fdbc 52ccf8d fc659a3 52ccf8d fc659a3 52ccf8d 184c874 484fdbc 86f4808 cbe2a8f 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 169 170 171 172 173 174 175 176 177 178 |
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 {
public 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>,
checkExists: boolean = true
): Promise<ModelDoc[]> {
filter = { ...crudOptions?.defaultFilter, ...filter };
if (checkExists)
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 softDelete(
filter: FilterQuery<ModelDoc>
): Promise<ModelDoc> {
filter = { ...crudOptions?.defaultFilter, ...filter };
await this.existsOrThrow(filter);
await this.model.updateOne(filter, { isDeleted: true });
return this.findOneOrFail(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(filter);
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.");
}
}
};
};
|