@solid-nestjs/rest-api
Version:
solid-nestjs Rest-API utilities
335 lines • 16.1 kB
JavaScript
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
;