ncrudify
Version:
Configurable CRUD module for NestJS and Mongoose.
93 lines (81 loc) • 2.94 kB
text/typescript
import { applyDecorators } from "@nestjs/common";
import "reflect-metadata";
import { ICrudify } from "./interface/crudify.interface";
import { CrudifyRoutes } from "./crudify.routes";
export function Crudify<T>(options: ICrudify) {
return function (target: Function) {
const prototype = target.prototype;
const basePrototype = Object.getPrototypeOf(prototype);
const isSoftDelete = options.softDelete ?? false;
disableRoutes(options, prototype, isSoftDelete);
const routes = CrudifyRoutes.routes(options);
for (const route of routes) {
let method = prototype[route.methodName];
if (!method || method === basePrototype[route.methodName]) {
method = function (this: any, ...args: any[]) {
return basePrototype[route.methodName]?.apply(this, args);
};
Object.defineProperty(prototype, route.methodName, {
value: method,
writable: true,
configurable: true,
});
}
if (isSoftDelete && route.methodName === "delete") {
const originalMethod = prototype[route.methodName];
prototype[route.methodName] = async function (...args: any[]) {
const entity = args[0];
const deleteDto = { deletedAt: new Date() };
return originalMethod.apply(this, [entity, deleteDto]);
};
}
if (route.parameters) {
for (const param of route.parameters) {
param.decorator(prototype, route.methodName, param.index);
}
}
const uniqueOperationId = `${target.name}_${route.methodName}`;
Reflect.defineMetadata(
"swagger/apiOperation",
{
operationId: uniqueOperationId,
summary: `Method: ${route.methodName}`,
},
prototype,
route.methodName
);
const methodDecorators = [
route.httpMethod(route.path),
...route.decorators,
];
applyDecorators(...methodDecorators)(
prototype,
route.methodName,
Object.getOwnPropertyDescriptor(prototype, route.methodName)!
);
}
};
}
export function disableRoutes(
options: ICrudify,
prototype: any,
isSoftDelete: boolean
) {
Reflect.defineMetadata("softDelete", isSoftDelete, prototype);
if (options.routes === undefined) options.routes = { exclude: [] };
if (options.routes?.exclude === undefined) {
options.routes.exclude = [];
}
if (Array.isArray(options.routes.exclude)) {
if (!isSoftDelete) {
options.routes.exclude.push("restore");
options.routes.exclude.push("restoreBulk");
}
if (options.routes?.disableBulk) {
options.routes.exclude.push("createBulk");
options.routes.exclude.push("updateBulk");
options.routes.exclude.push("deleteBulk");
options.routes.exclude.push("restoreBulk");
}
}
}