UNPKG

@solid-nestjs/rest-api

Version:

solid-nestjs Rest-API utilities

335 lines 16.1 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataControllerFrom = DataControllerFrom; exports.extractOperationSettings = extractOperationSettings; const common_1 = require("@nestjs/common"); const swagger_1 = require("@nestjs/swagger"); const common_2 = require("@solid-nestjs/common"); const classes_1 = require("../classes"); const decorators_1 = require("../decorators"); /** * Generates a NestJS controller class for a given entity, service, and context, * providing standard RESTful endpoints for data access and manipulation. * * This mixin function dynamically creates a controller with endpoints for: * - Listing all entities (`findAll`) * - Paginated listing (`pagination`) * - Paginated list with data and pagination info (`findAllPaginated`) * - Retrieving a single entity by ID (`findOne`) * * The generated controller is decorated with OpenAPI/Swagger decorators for API documentation, * and supports custom decorators, pipes, and operation settings via the `controllerStructure` parameter. * * Disabled operations (set to `false` in `controllerStructure.operations`) are omitted from the controller. * * @param controllerStructure - Configuration object specifying entity, service, decorators, * operation settings, and other controller customizations. * * @returns A NestJS controller class (as a mixin) with the specified endpoints and configuration. */ function DataControllerFrom(controllerStructure) { const { entityType, serviceType, findArgsType, groupByArgsType } = controllerStructure; const ContextDecorator = controllerStructure.parameterDecorators?.context ?? common_2.CurrentContext; const argsType = findArgsType ?? classes_1.DefaultArgs; let idType = Number; let pipeTransforms = [common_1.ParseIntPipe]; if (controllerStructure.entityId) { idType = controllerStructure.entityId.type; pipeTransforms = controllerStructure.entityId.pipeTransforms ?? []; } const controllerApiTags = controllerStructure.route ?? entityType.name.toLowerCase() + 's'; const controllerRoute = controllerStructure.route ?? entityType.name.toLowerCase() + 's'; const controllerDecorators = controllerStructure.classDecorators ?? []; const findAllSettings = extractOperationSettings(controllerStructure.operations?.findAll, { disabled: controllerStructure.operations?.findAll === false, route: '', summary: 'List of ' + entityType.name.toLowerCase() + 's records', description: 'list of ' + entityType.name.toLowerCase() + 's records', successCode: common_1.HttpStatus.OK, errorCodes: [common_1.HttpStatus.BAD_REQUEST], }); const findOneSettings = extractOperationSettings(controllerStructure.operations?.findOne, { disabled: controllerStructure.operations?.findOne === false, route: ':id', summary: 'Retrieve ' + entityType.name.toLowerCase() + ' record by id', description: 'retrieval of ' + entityType.name.toLowerCase() + ' record by id', successCode: common_1.HttpStatus.OK, errorCodes: [common_1.HttpStatus.BAD_REQUEST, common_1.HttpStatus.NOT_FOUND], }); const paginationSettings = extractOperationSettings(controllerStructure.operations?.pagination, { disabled: !controllerStructure.operations?.pagination, route: 'pagination', summary: 'Pagination of ' + entityType.name.toLowerCase(), description: 'pagination of ' + entityType.name.toLowerCase(), successCode: common_1.HttpStatus.OK, errorCodes: [common_1.HttpStatus.BAD_REQUEST], }); const findAllPaginatedSettings = extractOperationSettings(controllerStructure.operations?.findAllPaginated, { disabled: controllerStructure.operations?.findAllPaginated === false, route: 'paginated', summary: 'Paginated List of ' + entityType.name.toLowerCase() + 's records', description: 'paginated list of ' + entityType.name.toLowerCase() + 's records', successCode: common_1.HttpStatus.OK, errorCodes: [common_1.HttpStatus.BAD_REQUEST], }); const findAllGroupedSettings = extractOperationSettings(controllerStructure.operations?.findAllGrouped, { disabled: controllerStructure.operations?.findAllGrouped === false || !groupByArgsType, route: 'grouped', summary: 'Grouped query of ' + entityType.name.toLowerCase() + 's with aggregations', description: 'grouped query with aggregations for ' + entityType.name.toLowerCase() + 's', successCode: common_1.HttpStatus.OK, errorCodes: [common_1.HttpStatus.BAD_REQUEST], }); const paramApiConfig = { name: 'id', description: 'ID of the ' + entityType.name + ' entity', required: true, }; let DataControllerClass = class DataControllerClass { constructor() { } async findAll(context, args) { return this.service.findAll(context, args); } async pagination(context, args) { return this.service.pagination(context, args); } async findAllPaginated(context, args) { return this.service.findAll(context, args, true); } async findAllGrouped(context, args) { return await this.service.findAllGrouped(context, args); } async findOne(context, id) { return await this.service.findOne(context, id, true); } }; __decorate([ (0, common_1.Inject)(serviceType), __metadata("design:type", Object) ], DataControllerClass.prototype, "service", void 0); __decorate([ (0, common_1.Get)(findAllSettings?.route ?? ''), (0, common_2.applyMethodDecorators)(findAllSettings?.decorators ?? []), (0, swagger_1.ApiOperation)({ summary: findAllSettings?.summary, description: findAllSettings?.description, operationId: findAllSettings?.operationId, }), (0, swagger_1.ApiQuery)({ name: 'args', required: false, schema: { $ref: (0, swagger_1.getSchemaPath)(argsType), }, }), (0, common_1.HttpCode)(findAllSettings?.successCode ?? common_1.HttpStatus.OK), (0, decorators_1.ApiResponses)({ type: entityType, isArray: true, successCodes: findAllSettings?.successCodes ?? [common_1.HttpStatus.OK], errorCodes: findAllSettings?.errorCodes ?? [common_1.HttpStatus.BAD_REQUEST], }), __param(0, ContextDecorator()), __param(1, (0, common_1.Query)(common_2.QueryTransformPipe, new common_1.ValidationPipe({ transform: true, expectedType: argsType, whitelist: true, forbidNonWhitelisted: true, forbidUnknownValues: true, }))), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], DataControllerClass.prototype, "findAll", null); __decorate([ (0, common_1.Get)(paginationSettings?.route ?? 'pagination'), (0, common_2.applyMethodDecorators)(paginationSettings?.decorators ?? []), (0, swagger_1.ApiOperation)({ summary: paginationSettings?.summary, description: paginationSettings?.description, operationId: paginationSettings?.operationId, }), (0, swagger_1.ApiQuery)({ name: 'args', required: false, schema: { $ref: (0, swagger_1.getSchemaPath)(argsType), }, }), (0, common_1.HttpCode)(paginationSettings?.successCode ?? common_1.HttpStatus.OK), (0, decorators_1.ApiResponses)({ type: classes_1.PaginationResult, successCodes: paginationSettings?.successCodes ?? [common_1.HttpStatus.OK], errorCodes: paginationSettings?.errorCodes ?? [common_1.HttpStatus.BAD_REQUEST], }), __param(0, ContextDecorator()), __param(1, (0, common_1.Query)(common_2.QueryTransformPipe, new common_1.ValidationPipe({ transform: true, expectedType: argsType, whitelist: true, forbidNonWhitelisted: true, forbidUnknownValues: true, }))), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], DataControllerClass.prototype, "pagination", null); __decorate([ (0, common_1.Get)(findAllPaginatedSettings?.route ?? 'paginated'), (0, common_2.applyMethodDecorators)(findAllPaginatedSettings?.decorators ?? []), (0, swagger_1.ApiOperation)({ summary: findAllPaginatedSettings?.summary, description: findAllPaginatedSettings?.description, operationId: findAllPaginatedSettings?.operationId, }), (0, swagger_1.ApiQuery)({ name: 'args', required: false, schema: { $ref: (0, swagger_1.getSchemaPath)(argsType), }, }), (0, common_1.HttpCode)(findAllPaginatedSettings?.successCode ?? common_1.HttpStatus.OK), (0, decorators_1.ApiResponses)({ schema: { type: 'object', properties: { data: { type: 'array', items: { $ref: (0, swagger_1.getSchemaPath)(entityType), }, }, pagination: { $ref: (0, swagger_1.getSchemaPath)(classes_1.PaginationResult) }, }, }, isArray: true, successCodes: findAllPaginatedSettings?.successCodes ?? [common_1.HttpStatus.OK], errorCodes: findAllPaginatedSettings?.errorCodes ?? [ common_1.HttpStatus.BAD_REQUEST, ], }), __param(0, ContextDecorator()), __param(1, (0, common_1.Query)(common_2.QueryTransformPipe, new common_1.ValidationPipe({ transform: true, expectedType: argsType, whitelist: true, forbidNonWhitelisted: true, forbidUnknownValues: true, }))), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], DataControllerClass.prototype, "findAllPaginated", null); __decorate([ (0, common_1.Get)(findAllGroupedSettings?.route ?? 'grouped'), (0, common_2.applyMethodDecorators)(findAllGroupedSettings?.decorators ?? []), (0, swagger_1.ApiOperation)({ summary: findAllGroupedSettings?.summary, description: findAllGroupedSettings?.description, operationId: findAllGroupedSettings?.operationId, }), (0, swagger_1.ApiQuery)({ name: 'args', required: false, schema: { $ref: (0, swagger_1.getSchemaPath)(groupByArgsType), }, }), (0, common_1.HttpCode)(findAllGroupedSettings?.successCode ?? common_1.HttpStatus.OK), (0, decorators_1.ApiResponses)({ type: classes_1.GroupedPaginationResult, successCodes: findAllGroupedSettings?.successCodes ?? [common_1.HttpStatus.OK], errorCodes: findAllGroupedSettings?.errorCodes ?? [common_1.HttpStatus.BAD_REQUEST], }), __param(0, ContextDecorator()), __param(1, (0, common_1.Query)(common_2.QueryTransformPipe, new common_1.ValidationPipe({ transform: true, expectedType: groupByArgsType, whitelist: true, forbidNonWhitelisted: true, forbidUnknownValues: true, }))), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], DataControllerClass.prototype, "findAllGrouped", null); __decorate([ (0, common_1.Get)(findOneSettings?.route ?? ':id'), (0, common_2.applyMethodDecorators)(findOneSettings?.decorators ?? []), (0, swagger_1.ApiOperation)({ summary: findOneSettings?.summary, description: findOneSettings?.description, operationId: findOneSettings?.operationId, }), (0, swagger_1.ApiParam)(paramApiConfig), (0, common_1.HttpCode)(findOneSettings?.successCode ?? common_1.HttpStatus.OK), (0, decorators_1.ApiResponses)({ type: entityType, successCodes: findOneSettings?.successCodes ?? [common_1.HttpStatus.OK], errorCodes: findOneSettings?.errorCodes ?? [ common_1.HttpStatus.BAD_REQUEST, common_1.HttpStatus.NOT_FOUND, ], }), __param(0, ContextDecorator()), __param(1, (0, common_1.Param)('id', ...pipeTransforms)), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], DataControllerClass.prototype, "findOne", null); DataControllerClass = __decorate([ (0, swagger_1.ApiTags)(controllerApiTags), (0, common_1.Controller)(controllerRoute), (0, common_2.applyClassDecorators)(controllerDecorators), (0, swagger_1.ApiExtraModels)(argsType, classes_1.PaginationResult, ...(groupByArgsType ? [groupByArgsType, classes_1.GroupedPaginationResult] : [])), __metadata("design:paramtypes", []) ], DataControllerClass); //remove controller methods if they are disabled in the structure if (findAllSettings.disabled) { delete DataControllerClass.prototype.findAll; } if (findOneSettings.disabled) { delete DataControllerClass.prototype.findOne; } if (paginationSettings.disabled) { delete DataControllerClass.prototype.pagination; } if (findAllPaginatedSettings.disabled) { delete DataControllerClass.prototype.findAllPaginated; } if (findAllGroupedSettings.disabled || !groupByArgsType) { delete DataControllerClass.prototype.findAllGrouped; } return (0, common_1.mixin)(DataControllerClass); } function extractOperationSettings(operation, defaults) { if (typeof operation !== 'object') operation = {}; return { disabled: defaults.disabled, route: operation.route ?? defaults.route, decorators: operation.decorators ?? [], summary: operation.title ?? defaults.summary, description: operation.description ?? defaults.description, operationId: operation.operationId, successCode: operation.successCode ?? (operation.successCodes ?? [])[0] ?? defaults.successCode, successCodes: operation.successCodes ?? [defaults.successCode], errorCodes: operation.errorCodes ?? defaults.errorCodes, }; } //# sourceMappingURL=data-controller.mixin.js.map