@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
157 lines (154 loc) • 8.51 kB
JavaScript
import { __decorate, __metadata } from '../../../external/tslib/tslib.es6.js';
import { API_CONTROLLER_CURSOR_TOKEN_MAX_LENGTH } from '../../../constant/api-controller-cursor.constant.js';
import { GET_LIST_QUERY_DTO_FACTORY_CONSTANT } from '../../../constant/factory-dto-get-list-query.constant.js';
import { ApiPropertyEnum } from '../../../decorator/api/property/enum.decorator.js';
import { ApiPropertyNumber } from '../../../decorator/api/property/number.decorator.js';
import { ApiPropertyString } from '../../../decorator/api/property/string.decorator.js';
import '../../../enum/decorator/api/action.enum.js';
import '../../../enum/decorator/api/authentication-type.enum.js';
import '../../../enum/decorator/api/controller/get-list/query/filter/missing-behavior.enum.js';
import { EApiControllerGetListQueryPaginationMode } from '../../../enum/decorator/api/controller/get-list/query/pagination-mode.enum.js';
import '../../../enum/decorator/api/controller/get-list/query/unlisted-fields.enum.js';
import '../../../enum/decorator/api/controller/relation-reference-shape.enum.js';
import '../../../enum/decorator/api/controller/request/target.enum.js';
import '../../../enum/decorator/api/controller/request/transformer-type.enum.js';
import '../../../enum/decorator/api/controller/response-target.enum.js';
import '../../../enum/decorator/api/dto-type.enum.js';
import '../../../enum/decorator/api/function/context-storage-kind.enum.js';
import '../../../enum/decorator/api/function/subscriber-transaction-expectation.enum.js';
import '../../../enum/decorator/api/function/transaction/event-status.enum.js';
import '../../../enum/decorator/api/function/transaction/failure-stage.enum.js';
import '../../../enum/decorator/api/function/transaction/mode.enum.js';
import '../../../enum/decorator/api/function/transaction/outcome.enum.js';
import '../../../enum/decorator/api/function/transaction/owner-kind.enum.js';
import '../../../enum/decorator/api/function/transaction/trace-type.enum.js';
import '../../../enum/decorator/api/function/type.enum.js';
import '../../../enum/decorator/api/on-type.enum.js';
import '../../../enum/decorator/api/property/data-type.enum.js';
import '../../../enum/decorator/api/property/date/identifier.enum.js';
import '../../../enum/decorator/api/property/date/type.enum.js';
import '../../../enum/decorator/api/property/desribe-type.enum.js';
import { EApiPropertyNumberType } from '../../../enum/decorator/api/property/number-type.enum.js';
import { EApiPropertyStringType } from '../../../enum/decorator/api/property/string-type.enum.js';
import '../../../enum/decorator/api/route/subscriber-authorization-expectation.enum.js';
import '../../../enum/decorator/api/route/type.enum.js';
import '../../../enum/filter/operand.enum.js';
import '../../../enum/filter/operation.enum.js';
import { EFilterOrderDirection } from '../../../enum/filter/order-direction.enum.js';
import { ApiControllerGetListQueryGetPaginationMode } from '../../api/controller/get-list/query/get-pagination-mode.utility.js';
import { FilterOrderByFromEntity } from '../../api/filter-order-by-from-entity.utility.js';
import { CapitalizeString } from '../../capitalize-string.utility.js';
import { AllOrNoneOfListedPropertiesValidator } from '../../../validator/all-or-none-of-listed-properties.validator.js';
import { Validate } from 'class-validator';
const noopPropertyDecorator = () => undefined;
const noopApiPropertyEnum = () => noopPropertyDecorator;
/**
* Creates a base class for list query DTOs with pagination and sorting properties.
* Includes limit, mode-specific pagination fields, and applicable sorting properties with
* appropriate validation rules. CURSOR omits orderBy and orderDirection when the plan enables
* no client-order fields.
* @param {ObjectLiteral} entity - The entity class or prototype
* @param {IApiEntity<E>} entityMetadata - The entity metadata containing column information
* @param {EApiRouteType} method - The API route type (GET_LIST)
* @param {EApiDtoType} dtoType - The type of DTO (QUERY)
* @param {IApiControllerGetListQueryPlan} [queryPlan] - Optional normalized plan that narrows sortable fields.
* @returns {Type<unknown>} A base class for list query DTOs
* @template E - The entity type
*/
function DtoGetGetListQueryBaseClass(entity, entityMetadata, method, dtoType, queryPlan) {
const isCursor = ApiControllerGetListQueryGetPaginationMode(queryPlan) === EApiControllerGetListQueryPaginationMode.CURSOR;
const orderBy = queryPlan && !queryPlan.order.isLegacy
? Object.fromEntries(Object.values(queryPlan.order.fields)
.filter((field) => field.isEnabled)
.map((field) => [field.path, field.path]))
: FilterOrderByFromEntity(entity, entityMetadata, method, dtoType);
const hasClientOrderFields = Object.keys(orderBy).length > 0;
const shouldExposeClientOrder = !isCursor || hasClientOrderFields;
const clientOrderPropertyDecorator = shouldExposeClientOrder ? ApiPropertyEnum : noopApiPropertyEnum;
class BaseQueryDTO {
limit;
orderBy;
orderDirection;
page;
constructor() {
if (isCursor) {
Reflect.deleteProperty(this, "page");
if (!shouldExposeClientOrder) {
Reflect.deleteProperty(this, "orderBy");
Reflect.deleteProperty(this, "orderDirection");
}
}
}
object() {
return this;
}
}
__decorate([
ApiPropertyNumber({
description: "Items per page",
entity: entityMetadata,
exampleValue: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.MINIMUM_LIST_LENGTH,
format: EApiPropertyNumberType.INTEGER,
isRequired: true,
maximum: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.MAXIMUM_LIST_LENGTH,
minimum: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.MINIMUM_LIST_LENGTH,
multipleOf: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.LIST_MULTIPLE_OF,
}),
__metadata("design:type", Number)
], BaseQueryDTO.prototype, "limit", void 0);
__decorate([
clientOrderPropertyDecorator({
description: "order by field",
entity: entityMetadata,
enum: orderBy,
enumName: queryPlan ? `${queryPlan.schemaName}OrderBy` : `E${CapitalizeString(entityMetadata.name ?? "UnknownResource")}FilterOrderBy`,
isRequired: false,
}),
__metadata("design:type", String)
], BaseQueryDTO.prototype, "orderBy", void 0);
__decorate([
clientOrderPropertyDecorator({
description: "order direction",
entity: entityMetadata,
enum: EFilterOrderDirection,
enumName: "EFilterOrderDirection",
isRequired: false,
}),
__metadata("design:type", String)
], BaseQueryDTO.prototype, "orderDirection", void 0);
if (isCursor) {
for (const [property, description] of [
["after", "Cursor after which to return items"],
["before", "Cursor before which to return items"],
]) {
ApiPropertyString({
description,
entity: entityMetadata,
exampleValue: "eyJ2IjoxLCJjIjoiLi4uIiwidmFsdWVzIjpbIi4uLiJdfQ",
format: EApiPropertyStringType.STRING,
isRequired: false,
maxLength: API_CONTROLLER_CURSOR_TOKEN_MAX_LENGTH,
minLength: 1,
pattern: "/^[A-Za-z0-9_-]+$/",
})(BaseQueryDTO.prototype, property);
}
}
else {
ApiPropertyNumber({
description: "Page to return",
entity: entityMetadata,
exampleValue: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.MINIMUM_LIST_PAGES_COUNT,
format: EApiPropertyNumberType.INTEGER,
isRequired: true,
maximum: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.MAXIMUM_LIST_PAGES_COUNT,
minimum: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.MINIMUM_LIST_PAGES_COUNT,
multipleOf: GET_LIST_QUERY_DTO_FACTORY_CONSTANT.LIST_MULTIPLE_OF,
})(BaseQueryDTO.prototype, "page");
}
if (shouldExposeClientOrder) {
Validate(AllOrNoneOfListedPropertiesValidator, ["orderBy", "orderDirection"])(BaseQueryDTO.prototype, "object");
}
return BaseQueryDTO;
}
export { DtoGetGetListQueryBaseClass };
//# sourceMappingURL=get-list-query-base-class.utility.js.map