UNPKG

@buka/nestjs-type-helper

Version:
1,490 lines (1,447 loc) 82 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/mikro-orm/models/base-entity.ts import { BigIntType as BigIntType2, PrimaryKey, PrimaryKeyProp } from "@mikro-orm/core"; import { ApiProperty as ApiProperty3 } from "@nestjs/swagger"; import { IsNumberString } from "class-validator"; // src/mikro-orm/models/timestamped-entity.ts import { Config, OptionalProps } from "@mikro-orm/core"; // src/mikro-orm/decorators/entity-property.decorator.ts import { Property as OrmProperty } from "@mikro-orm/core"; // src/mikro-orm/decorators/api-entity-property.decorator.ts import { ApiHideProperty, getSchemaPath } from "@nestjs/swagger"; import { MetadataStorage as MetadataStorage2, ReferenceKind } from "@mikro-orm/core"; // src/mikro-orm/decorators/api-scalar-entity-property.decorator.ts import { BigIntType } from "@mikro-orm/core"; import { applyDecorators as applyDecorators3 } from "@nestjs/common"; import { IsBoolean, IsCurrency, IsInt, IsISO8601, IsNumber, IsString, MaxLength, MinLength } from "class-validator"; // src/decorators/nested-property.decorator.ts import * as R2 from "ramda"; import { applyDecorators } from "@nestjs/common"; import { Type as ClassType } from "class-transformer"; import { IsNotEmpty, ValidateNested } from "class-validator"; // src/decorators/model/model.register.ts import * as R from "ramda"; var MODEL_METADATA_KEY = "buka:model"; var PROPERTY_METADATA_KEY = "buka:property"; var ModelRegister = class { static { __name(this, "ModelRegister"); } static setModel(target, metadata) { Reflect.defineMetadata(MODEL_METADATA_KEY, metadata, target); } static getModel(target) { return Reflect.getMetadata(MODEL_METADATA_KEY, target); } static setProperty(target, propertyName, metadata) { Reflect.defineMetadata(PROPERTY_METADATA_KEY, metadata, target.prototype, propertyName); } static getProperty(target, propertyName) { return Reflect.getMetadata(PROPERTY_METADATA_KEY, target.prototype, propertyName); } static copyProperty(source, target, propertyName) { const metadata = this.getProperty(source, propertyName); if (metadata) { const modelMetadata = this.addModel(target); if (!modelMetadata.propertyKeys.includes(propertyName)) { modelMetadata.propertyKeys.push(propertyName); } this.setProperty(target, propertyName, metadata); } } static addModel(target, kind = "model") { const metadata = this.getModel(target); if (!metadata) { const metadata2 = { kind, propertyKeys: [] }; this.setModel(target, metadata2); return metadata2; } return metadata; } static addProperty(target, propertyName, metadata = {}) { const modelMetadata = this.addModel(target); if (!modelMetadata.propertyKeys.includes(propertyName)) { modelMetadata.propertyKeys.push(propertyName); } const propertyMetadata = { type() { return Reflect.getMetadata("design:type", target.prototype, propertyName); }, ...this.getProperty(target, propertyName) || {}, ...R.omit([ "schema" ], metadata) }; this.setProperty(target, propertyName, propertyMetadata); } /** * 判断是否为已注册的 Model * * @example * ```typescript * const isModel = ModelRegister.isModel(Class.prototype) * ``` */ static isModel(target) { return !!this.getModel(target); } /** * 获取 Model 的所有属性 * * @example * ```typescript * const properties = ModelRegister.getProperties(Class.prototype) * ``` */ static getModelPropertyKeys(target) { const metadata = this.getModel(target); return metadata ? metadata.propertyKeys : []; } static getProperties(target) { const propertyKeys = this.getModelPropertyKeys(target); return propertyKeys.map((propertyKey) => this.getProperty(target, propertyKey)).filter((property) => !!property); } }; // src/decorators/model/model.decorator.ts function Model() { return (target) => { ModelRegister.addModel(target); }; } __name(Model, "Model"); // src/exceptions/exceptions.ts import { CustomError } from "ts-custom-error"; var Exception = class extends CustomError { static { __name(this, "Exception"); } constructor(message) { super(`[@buka/nestjs] ${message}`); Object.defineProperty(this, "name", { value: "Exception" }); } }; // src/exceptions/type-exception.ts var TypeException = class extends Exception { static { __name(this, "TypeException"); } constructor(message) { super(message); Object.defineProperty(this, "name", { value: "TypeException" }); } }; // src/decorators/model/property.decorator.ts import { IsOptional } from "class-validator"; import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; function Property(options) { return (target, propertyKey) => { if (!("constructor" in target)) { throw new TypeException("@Property decorator can only be applied to class properties."); } if (options?.optional) { IsOptional()(target, propertyKey); } if (options?.schema) { if (options?.optional) { ApiPropertyOptional(options.schema)(target, propertyKey); } else { ApiProperty(options.schema)(target, propertyKey); } } ModelRegister.addProperty(target.constructor, propertyKey, options); }; } __name(Property, "Property"); // src/decorators/model/relation.decorator.ts var RELATION_METADATA_KEY = "buka:relation"; function Relation(metadata) { return (target, propertyKey) => { ModelRegister.addProperty(target.constructor, propertyKey, { relation: metadata }); }; } __name(Relation, "Relation"); // src/decorators/model/nested.decorator.ts function Nested(options) { return (target, propertyKey) => { Property({ kind: "nested", ...options })(target, propertyKey); }; } __name(Nested, "Nested"); // src/decorators/model/list.decorator.ts function List(options) { return (target, propertyKey) => { Property({ kind: "list", ...options })(target, propertyKey); }; } __name(List, "List"); // src/decorators/nested-property.decorator.ts function NestedProperty(type, options = {}) { const decorators = [ ValidateNested({ each: !!options.each }), ClassType(type) ]; const schema = options.schema || { type: /* @__PURE__ */ __name(() => type(), "type") }; const propertyMetadata = R2.pick([ "relation", "optional" ], options); if (options.each) { decorators.push(List({ type, schema, ...propertyMetadata })); } else { decorators.push(Nested({ type, schema, ...propertyMetadata })); } if (!options.optional) { decorators.push(...[ // 如果不添加 IsNotEmpty,ValidateNested 在没有 IsOptional 的情况下也会允许 undefined 值通过验证 // https://github.com/typestack/class-validator/issues/717 IsNotEmpty({ each: options.each, message: "$property is required" }) ]); } return applyDecorators(...decorators); } __name(NestedProperty, "NestedProperty"); // src/decorators/reference-property.decorator.ts import { applyDecorators as applyDecorators2 } from "@nestjs/common"; import { Allow } from "class-validator"; var ReferencePropertiesMetadataKey = "buka:reference-properties"; function ReferenceProperty(entity) { return applyDecorators2(Allow(), NestedProperty(() => EntityRefType(entity()), { relation: { kind: "1:1", type: /* @__PURE__ */ __name(() => entity(), "type") } })); } __name(ReferenceProperty, "ReferenceProperty"); // src/decorators/class-validator/has-any-key.ts import { registerDecorator } from "class-validator"; var HAS_ANY_KEY = "hasAnyKey"; function HasAnyKey(keys, validationOptions) { return function(object, propertyName) { registerDecorator({ name: HAS_ANY_KEY, target: object.constructor, propertyName, constraints: [ keys ], options: validationOptions, validator: { validate(value) { if (typeof value !== "object" || value === null) return false; for (const key of keys) { if (key in value) return true; } return false; }, defaultMessage() { return `$property must have at least one of the keys: ${keys.join(", ")}`; } } }); }; } __name(HasAnyKey, "HasAnyKey"); // src/decorators/class-validator/match-json-schema.ts import { registerDecorator as registerDecorator2 } from "class-validator"; import { validate } from "jsonschema"; var MATCH_JSON_SCHEMA = "matchJsonSchema"; function MatchJsonSchema(schema, validationOptions) { return function(object, propertyName) { registerDecorator2({ name: MATCH_JSON_SCHEMA, target: object.constructor, propertyName, constraints: [ schema ], options: validationOptions, validator: { validate(value, args) { const [schema2] = args.constraints; const results = validate(value, schema2); return results.valid; }, defaultMessage({ value, constraints }) { return `${propertyName} must match the JSON schema`; } } }); }; } __name(MatchJsonSchema, "MatchJsonSchema"); // src/decorators/page-query.ts import { Query } from "@nestjs/common"; import { ApiQuery } from "@nestjs/swagger"; // src/pipes/page-query-validation.pipe.ts import { BadRequestException, Injectable, InternalServerErrorException } from "@nestjs/common"; function _ts_decorate(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; } __name(_ts_decorate, "_ts_decorate"); function _ts_metadata(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } __name(_ts_metadata, "_ts_metadata"); var mixedOffsetAndCursorError = "Invalid page query: cannot mix offset-based and cursor-based pagination parameters."; var mixedNextAndLastCursorError = "Invalid page query: cannot mix next and last cursor pagination parameters."; var BukaPageQueryValidationPipe = class { static { __name(this, "BukaPageQueryValidationPipe"); } options; constructor(options = { optional: false }) { this.options = options; } transform(value, metadata) { if (metadata.type !== "query") { throw new InternalServerErrorException("BukaPageQueryValidationPipe can only be used to validate query parameters."); } if (!value.page) { if (this.options.optional) { return value; } else { throw new BadRequestException("Missing required query parameter: page"); } } const mode = this.options.mode; if ((!mode || mode === "offset") && ("limit" in value.page || "offset" in value.page)) { if ("after" in value.page || "first" in value.page || "before" in value.page || "last" in value.page) { throw new BadRequestException(mixedOffsetAndCursorError); } const limit = parseInt(value.page.limit, 10); const offset = parseInt(value.page.offset, 10); if (isNaN(limit) || limit <= 0) { throw new BadRequestException("Invalid page query: limit must be a positive integer."); } if (isNaN(offset) || offset < 0) { throw new BadRequestException("Invalid page query: offset must be a non-negative integer."); } return { page: { limit, offset } }; } if (!mode || mode === "cursor") { if ("after" in value.page || "first" in value.page) { if ("limit" in value.page || "offset" in value.page) { throw new BadRequestException(mixedOffsetAndCursorError); } if ("before" in value.page || "last" in value.page) { throw new BadRequestException(mixedNextAndLastCursorError); } const after = value.page.after; const first = parseInt(value.page.first, 10); if (typeof after !== "string") { throw new BadRequestException("Invalid page query: after must be a string."); } if (isNaN(first) || first <= 0) { throw new BadRequestException("Invalid page query: first must be a positive integer."); } return { page: { after, first } }; } if ("before" in value.page || "last" in value.page) { if ("limit" in value.page || "offset" in value.page) { throw new BadRequestException(mixedOffsetAndCursorError); } if ("after" in value.page || "first" in value.page) { throw new BadRequestException(mixedNextAndLastCursorError); } const before = value.page.before; const last = parseInt(value.page.last, 10); if (typeof before !== "string") { throw new BadRequestException("Invalid page query: before must be a string."); } if (isNaN(last) || last <= 0) { throw new BadRequestException("Invalid page query: last must be a positive integer."); } return { page: { before, last } }; } } throw new BadRequestException("Invalid page query: missing pagination parameters."); } }; BukaPageQueryValidationPipe = _ts_decorate([ Injectable(), _ts_metadata("design:type", Function), _ts_metadata("design:paramtypes", [ typeof BukaPageQueryValidationPipeOptions === "undefined" ? Object : BukaPageQueryValidationPipeOptions ]) ], BukaPageQueryValidationPipe); // src/decorators/page-query.ts var OffsetPageSchema = { type: "object", properties: { limit: { type: "number" }, offset: { type: "number" } }, required: [ "limit", "offset" ] }; var NextCursorPageSchema = { type: "object", properties: { after: { type: "string" }, first: { type: "number" } }, required: [ "after", "first" ] }; var PreviousCursorPageSchema = { type: "object", properties: { before: { type: "string" }, last: { type: "number" } }, required: [ "before", "last" ] }; function PageQuery(mode) { return (target, propertyKey, parameterIndex) => { if (!propertyKey) { throw new Error("@PageQuery decorator can only be used on method parameters."); } const descriptor = Reflect.getOwnPropertyDescriptor(target, propertyKey); if (mode === "offset") { ApiQuery({ name: "page", required: true, schema: OffsetPageSchema })(target, propertyKey, descriptor); } else if (mode === "cursor") { ApiQuery({ name: "page", required: true, schema: { oneOf: [ NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } else { ApiQuery({ name: "page", required: true, schema: { oneOf: [ OffsetPageSchema, NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } Query(new BukaPageQueryValidationPipe({ mode }))(target, propertyKey, parameterIndex); }; } __name(PageQuery, "PageQuery"); function OptionalPageQuery(mode) { return (target, propertyKey, parameterIndex) => { if (!propertyKey) { throw new Error("@PageQuery decorator can only be used on method parameters."); } const descriptor = Reflect.getOwnPropertyDescriptor(target, propertyKey); if (mode === "offset") { ApiQuery({ name: "page", required: false, schema: OffsetPageSchema }); } else if (mode === "cursor") { ApiQuery({ name: "page", required: false, schema: { oneOf: [ NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } else { ApiQuery({ name: "page", required: false, schema: { oneOf: [ OffsetPageSchema, NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } Query(new BukaPageQueryValidationPipe({ mode, optional: true }))(target, propertyKey, parameterIndex); }; } __name(OptionalPageQuery, "OptionalPageQuery"); // src/utils/logger.ts import { Logger } from "@nestjs/common"; var logger = new Logger("@buka/nestjs-type-helpers"); // src/mikro-orm/decorators/api-scalar-entity-property.decorator.ts function ApiScalarEntityProperty(options) { const { meta } = options; if (typeof meta["columnType"] === "string") { const columnType = meta["columnType"].toLowerCase(); if (columnType.startsWith("varchar")) { const length = Number(meta["columnType"].match(/\d+/)?.[0]); return VarcharProperty(length, options); } if (columnType.startsWith("char")) { const length = Number(meta["columnType"].match(/\d+/)?.[0]); return CharProperty(length, options); } if (columnType === "text") return TextProperty(options); if (columnType === "money") return MoneyProperty(options); if (columnType.startsWith("int")) return IntProperty(options); if (columnType.startsWith("smallint")) return IntProperty(options); if (columnType.startsWith("tinyint")) return TinyintProperty(options); if (columnType.startsWith("double")) return DoubleProperty(options); if (columnType.startsWith("decimal") || columnType.startsWith("numeric")) return DecimalProperty(options); if (columnType === "datetime") return DatetimeProperty(options); } if (meta.type === "varchar") return VarcharProperty(meta.length, options); if (meta.type === "char") return CharProperty(meta.length, options); if (meta.type === "text") return TextProperty(options); if (meta.type === "money") return MoneyProperty(options); if (meta.type === "int") return IntProperty(options); if (meta.type === "smallint") return IntProperty(options); if (meta.type === "tinyint") return TinyintProperty(options); if (meta.type === "double") return DoubleProperty(options); if (meta.type === "decimal" || meta.type === "numeric") return DecimalProperty(options); if (meta.type === "datetime") return DatetimeProperty(options); if (meta.type === "boolean" || meta.type === "bool") return BooleanProperty(options); if (meta.type === "bigint") return BigIntProperty(options); if (meta.type instanceof BigIntType) return BigIntProperty(options); logger.warn(`No decorator founded for type ${meta.type} for property ${meta.name}.`); return () => { }; } __name(ApiScalarEntityProperty, "ApiScalarEntityProperty"); function getEnumOptions(options) { if (options.meta.enum !== true) return {}; const items = options.meta.items; const values2 = typeof items === "function" ? items() : items; const enumName = options.schema?.enumName; return { enum: values2, enumName }; } __name(getEnumOptions, "getEnumOptions"); function VarcharProperty(length, options) { const decorators = []; if (!options.unverified) { decorators.push(IsString()); if (length) decorators.push(MaxLength(length)); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => String, "type"), optional: options.meta.nullable, schema: { type: "string", maxLength: length, ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(VarcharProperty, "VarcharProperty"); function CharProperty(length, options) { const decorators = []; if (!options.unverified) { decorators.push(IsString()); if (length) decorators.push(MaxLength(length), MinLength(length)); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => String, "type"), optional: options.meta.nullable, schema: { type: "string", maxLength: length, minimum: length, ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(CharProperty, "CharProperty"); function TextProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsString()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => String, "type"), optional: options.meta.nullable, schema: { type: "string", ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(TextProperty, "TextProperty"); function MoneyProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsCurrency({ symbol: "" })); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => String, "type"), optional: options.meta.nullable, schema: { type: "string", format: "money", ...options.schema || {}, required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(MoneyProperty, "MoneyProperty"); function BigIntProperty(options) { const { meta } = options; let mode; if (meta.type === "bigint") { mode = "string"; } else if (meta.type instanceof BigIntType) { const metaType = meta.type; mode = metaType.mode === "string" ? "string" : "number"; } else { throw new Error(`Unsupported type for BigIntProperty: ${meta.type}`); } const decorators = []; if (mode === "string") { if (!options.unverified) { decorators.push(IsString()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => String, "type"), optional: options.meta.nullable, schema: { type: "string", ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); } else { if (!options.unverified) { decorators.push(IsInt()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Number, "type"), optional: options.meta.nullable, schema: { type: "integer", format: "int64", ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); } return applyDecorators3(...decorators); } __name(BigIntProperty, "BigIntProperty"); function IntProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsInt()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Number, "type"), optional: options.meta.nullable, schema: { type: "integer", minimum: options.meta.unsigned ? 0 : -2147483647, maximum: options.meta.unsigned ? 4294967295 : 2147483647, ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(IntProperty, "IntProperty"); function TinyintProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsInt()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Number, "type"), optional: options.meta.nullable, schema: { type: "integer", minimum: options.meta.unsigned ? 0 : -128, maximum: options.meta.unsigned ? 255 : 127, ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(TinyintProperty, "TinyintProperty"); function DoubleProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsNumber()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Number, "type"), optional: options.meta.nullable, schema: { type: "number", format: "double", minimum: options.meta.unsigned ? 0 : void 0, ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(DoubleProperty, "DoubleProperty"); function DecimalProperty(options) { const decorators = []; if (!options.unverified) { if (options.meta.scale) decorators.push(IsNumber({ maxDecimalPlaces: options.meta.scale })); else decorators.push(IsNumber()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Number, "type"), optional: options.meta.nullable, schema: { type: "number", format: "double", minimum: options.meta.unsigned ? 0 : void 0, ...options.schema || {}, ...getEnumOptions(options), required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(DecimalProperty, "DecimalProperty"); function DatetimeProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsISO8601()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Date, "type"), optional: options.meta.nullable, schema: { type: "string", format: "date-time", ...options.schema || {}, required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(DatetimeProperty, "DatetimeProperty"); function BooleanProperty(options) { const decorators = []; if (!options.unverified) { decorators.push(IsBoolean()); } decorators.push(Property({ type: /* @__PURE__ */ __name(() => Boolean, "type"), optional: options.meta.nullable, schema: { type: "boolean", ...options.schema || {}, required: !options.meta.nullable, description: options.meta.comment } })); return applyDecorators3(...decorators); } __name(BooleanProperty, "BooleanProperty"); // src/utils/nestjs-swagger-utils.ts import * as R3 from "ramda"; import { ModelPropertiesAccessor } from "@nestjs/swagger/dist/services/model-properties-accessor"; import { DECORATORS } from "@nestjs/swagger/dist/constants"; import { METADATA_FACTORY_NAME } from "@nestjs/swagger/dist/plugin/plugin-constants"; import { clonePluginMetadataFactory } from "@nestjs/swagger/dist/type-helpers/mapped-types.utils"; import { ApiProperty as ApiProperty2 } from "@nestjs/swagger"; import { isFunction } from "@nestjs/common/utils/shared.utils"; import { isBuiltInType } from "@nestjs/swagger/dist/utils/is-built-in-type.util"; import { SchemaObjectMetadata } from "@nestjs/swagger/dist/interfaces/schema-object-metadata.interface"; var modelPropertiesAccessor = new ModelPropertiesAccessor(); function cloneMetadata(target, source, keys) { clonePluginMetadataFactory(target, source.prototype, (metadata) => R3.pick(keys, metadata)); for (const propertyKey of keys) { const metadata = getMetadataOfDecorator(source, propertyKey); if (metadata) { ApiProperty2(metadata)(target.prototype, propertyKey); } } } __name(cloneMetadata, "cloneMetadata"); function getMetadataOfDecorator(classRef, propertyKey) { if (propertyKey) { return Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES, classRef.prototype, propertyKey); } const props = modelPropertiesAccessor.getModelProperties(classRef.prototype); return R3.fromPairs(props.map((prop) => [ prop, Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES, classRef.prototype, prop) ])); } __name(getMetadataOfDecorator, "getMetadataOfDecorator"); function getMetadataOfPlugin(classRef, propertyKey) { const propsInPlugin = typeof classRef[METADATA_FACTORY_NAME] === "function" ? classRef[METADATA_FACTORY_NAME]() : {}; if (propertyKey) return propsInPlugin[propertyKey]; return propsInPlugin; } __name(getMetadataOfPlugin, "getMetadataOfPlugin"); function getMetadata(classRef, propertyKey) { const propsInDecorator = getMetadataOfDecorator(classRef); const propsInPlugin = getMetadataOfPlugin(classRef); const metadataMap = R3.mergeRight(propsInPlugin, propsInDecorator); if (propertyKey) return metadataMap[propertyKey]; return metadataMap; } __name(getMetadata, "getMetadata"); function isLazyTypeFunc(type) { return isFunction(type) && type.name == "type"; } __name(isLazyTypeFunc, "isLazyTypeFunc"); // src/utils/mikro-orm-utils.ts import * as R4 from "ramda"; import { EntityMetadata, MetadataStorage } from "@mikro-orm/core"; function getMetadata2(classRef) { const metadatas = []; let parent = classRef; do { const meta = MetadataStorage.getMetadataFromDecorator(parent); if (meta instanceof EntityMetadata) metadatas.push(meta); parent = Object.getPrototypeOf(parent); } while (parent && parent !== Object.prototype); return R4.unnest(metadatas.map((meta) => R4.values(meta.properties))); } __name(getMetadata2, "getMetadata"); // src/mikro-orm/converters/entity-ref-type/entity-ref-type.ts import { inheritTransformationMetadata, inheritValidationMetadata } from "@nestjs/mapped-types"; var EntityRefTypeClassMetadataPropertyKey = /* @__PURE__ */ Symbol("EntityRefTypeClassMetadataPropertyKey"); var storage = /* @__PURE__ */ new WeakMap(); function EntityRefType(classRef) { if (storage.has(classRef)) { return storage.get(classRef); } const properties = getMetadata2(classRef); const primaryProperties = properties.filter((prop) => prop.primary).map((prop) => prop.name); if (!primaryProperties.length) { throw new Error(`Cannot create EntityRefType for ${classRef.name} because it has no primary properties.`); } let EntityRefTypeClass = class EntityRefTypeClass { static { __name(this, "EntityRefTypeClass"); } }; EntityRefTypeClass[EntityRefTypeClassMetadataPropertyKey] = {}; cloneMetadata(EntityRefTypeClass, classRef, primaryProperties); inheritValidationMetadata(classRef, EntityRefTypeClass, (key) => primaryProperties.includes(key)); inheritTransformationMetadata(classRef, EntityRefTypeClass, (key) => primaryProperties.includes(key)); storage.set(classRef, EntityRefTypeClass); return EntityRefTypeClass; } __name(EntityRefType, "EntityRefType"); // src/mikro-orm/decorators/api-entity-property.decorator.ts function ApiEntityProperty(options) { return (target, propertyKey) => { const meta = MetadataStorage2.getMetadataFromDecorator(target.constructor); const prop = meta.properties[propertyKey]; if (!prop) return; if (prop.hidden === true) { ApiHideProperty()(target, propertyKey); return; } if (prop.kind === ReferenceKind.EMBEDDED) { return; } if (prop.kind === ReferenceKind.SCALAR) { ApiScalarEntityProperty({ meta: prop, schema: options })(target, propertyKey); return; } const getType = /* @__PURE__ */ __name(() => { const ent = prop.entity(); if (prop.eager === true) return ent; if (typeof ent === "function") { return EntityRefType(ent); } return Object; }, "getType"); if (prop.kind === ReferenceKind.ONE_TO_ONE || prop.kind === ReferenceKind.MANY_TO_ONE) { Property({ type: /* @__PURE__ */ __name(() => getType(), "type"), relation: { kind: prop.kind, type: /* @__PURE__ */ __name(() => getType(), "type") }, schema: { description: prop.comment, required: !prop.nullable } })(target, propertyKey); return; } if (prop.kind === ReferenceKind.ONE_TO_MANY || prop.kind === ReferenceKind.MANY_TO_MANY) { NestedProperty(() => getType(), { each: true, optional: prop.nullable, schema: { description: prop.comment, type: "array", items: { type: getSchemaPath(() => getType()) } } })(target, propertyKey); Relation({ kind: prop.kind, type: /* @__PURE__ */ __name(() => getType(), "type") })(target, propertyKey); return; } }; } __name(ApiEntityProperty, "ApiEntityProperty"); // src/mikro-orm/decorators/entity-property.decorator.ts function EntityProperty(options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityProperty() can only be used on string property"); OrmProperty(options)(target, propertyKey); ApiEntityProperty({ example: options?.example })(target, propertyKey); }; } __name(EntityProperty, "EntityProperty"); // src/mikro-orm/models/timestamped-entity.ts function _ts_decorate2(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; } __name(_ts_decorate2, "_ts_decorate"); function _ts_metadata2(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } __name(_ts_metadata2, "_ts_metadata"); var TimestampedEntity = class { static { __name(this, "TimestampedEntity"); } [Config]; [OptionalProps]; createdAt = /* @__PURE__ */ new Date(); updatedAt = /* @__PURE__ */ new Date(); }; _ts_decorate2([ EntityProperty({ type: "datetime", onCreate: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "onCreate"), defaultRaw: "CURRENT_TIMESTAMP", comment: "\u521B\u5EFA\u65F6\u95F4" }), _ts_metadata2("design:type", typeof Date === "undefined" ? Object : Date) ], TimestampedEntity.prototype, "createdAt", void 0); _ts_decorate2([ EntityProperty({ type: "datetime", onUpdate: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "onUpdate"), defaultRaw: "CURRENT_TIMESTAMP", comment: "\u66F4\u65B0\u65F6\u95F4" }), _ts_metadata2("design:type", typeof Date === "undefined" ? Object : Date) ], TimestampedEntity.prototype, "updatedAt", void 0); // src/mikro-orm/models/base-entity.ts function _ts_decorate3(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; } __name(_ts_decorate3, "_ts_decorate"); function _ts_metadata3(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } __name(_ts_metadata3, "_ts_metadata"); var BaseEntity = class extends TimestampedEntity { static { __name(this, "BaseEntity"); } // [Config]?: DefineConfig<{ forceObject: true }>; [PrimaryKeyProp]; id; }; _ts_decorate3([ ApiProperty3({ type: "string", description: "PK", example: "1", required: true }), PrimaryKey({ type: new BigIntType2("string"), comment: "\u4E3B\u952E" }), IsNumberString(), _ts_metadata3("design:type", String) ], BaseEntity.prototype, "id", void 0); // src/mikro-orm/converters/entity-dto-type/entity-dto-type.ts import { inheritTransformationMetadata as inheritTransformationMetadata2, inheritValidationMetadata as inheritValidationMetadata2 } from "@nestjs/mapped-types"; import { wrap } from "@mikro-orm/core"; function EntityDtoType(entity) { const properties = getMetadata2(entity); if (!properties.length) { throw new Error(`Cannot create EntityDtoType for ${entity.name} because it isn't an MikroORM Entity.`); } const keys = properties.filter((prop) => { if (prop.hidden) return false; if (prop.kind === "scalar" && prop.ref) return false; return true; }).map((prop) => prop.name); let EntityDtoTypeClass = class EntityDtoTypeClass2 { static { __name(this, "EntityDtoTypeClass"); } static from(entity2) { const dto = new EntityDtoTypeClass2(); const json = wrap(entity2).toPOJO(); for (const property of properties) { if (property.hidden) continue; if (property.kind === "scalar" && !property.ref) { dto[property.name] = json[property.name]; } if (property.kind === "m:n" || property.kind === "1:m") { dto[property.name] = json[property.name]; } if (property.kind === "1:1" || property.kind === "m:1") { dto[property.name] = json[property.name]; } } return dto; } }; inheritValidationMetadata2(entity, EntityDtoTypeClass, (key) => keys.includes(key)); inheritTransformationMetadata2(entity, EntityDtoTypeClass, (key) => keys.includes(key)); cloneMetadata(EntityDtoTypeClass, entity, keys); for (const property of keys) { ModelRegister.copyProperty(entity, EntityDtoTypeClass, property); } return EntityDtoTypeClass; } __name(EntityDtoType, "EntityDtoType"); // src/mikro-orm/decorators/entity-enum.decorator.ts import { Enum } from "@mikro-orm/core"; function EntityEnum(options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityEnum() can only be used on string property"); Enum(options)(target, propertyKey); ApiEntityProperty({ example: options.example, enumName: options.enumName })(target, propertyKey); }; } __name(EntityEnum, "EntityEnum"); // src/mikro-orm/decorators/entity-transient.decorator.ts import { Property as Property2 } from "@mikro-orm/core"; function EntityTransient() { return Property2({ persist: false }); } __name(EntityTransient, "EntityTransient"); // src/mikro-orm/decorators/entity-one-to-one.decorator.ts import { OneToOne as OrmOneToOne } from "@mikro-orm/core"; function EntityOneToOne(entity, mappedByOrOptions, options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityOneToOne() can only be used on string property"); OrmOneToOne(entity, mappedByOrOptions, options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityOneToOne, "EntityOneToOne"); // src/mikro-orm/decorators/entity-one-to-many.decorator.ts import { OneToMany as OrmOneToMany } from "@mikro-orm/core"; function EntityOneToMany(options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityOneToMany() can only be used on string property"); OrmOneToMany(options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityOneToMany, "EntityOneToMany"); // src/mikro-orm/decorators/entity-many-to-one.decorator.ts import { ManyToOne as OrmManyToOne } from "@mikro-orm/core"; function EntityManyToOne(entity, options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityManyToOne() can only be used on string property"); OrmManyToOne(entity, options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityManyToOne, "EntityManyToOne"); // src/mikro-orm/decorators/entity-many-to-many.decorator.ts import { ManyToMany } from "@mikro-orm/core"; function EntityManyToMany(entity, mappedBy, options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityManyToMany() can only be used on string property"); ManyToMany(entity, mappedBy, options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityManyToMany, "EntityManyToMany"); // src/mikro-orm/database.config.ts import { ToNumber } from "@buka/class-transformer-extra"; import { IsBoolean as IsBoolean2, IsNumber as IsNumber2, IsString as IsString2 } from "class-validator"; import * as R5 from "ramda"; import * as util from "util"; import { Migrator } from "@mikro-orm/migrations"; import { FlushMode } from "@mikro-orm/core"; import { BadRequestException as BadRequestException2 } from "@nestjs/common"; function _ts_decorate4(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; } __name(_ts_decorate4, "_ts_decorate"); function _ts_metadata4(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } __name(_ts_metadata4, "_ts_metadata"); var DatabaseConfig = class { static { __name(this, "DatabaseConfig"); } debug = false; migration = false; dbName; host; port; user; password; timezone = "+08:00"; toMikroOrmOptions(config) { let options = { host: this.host, port: this.port, user: this.user, password: this.password, dbName: this.dbName, debug: this.debug, timezone: this.timezone, forceUndefined: true, flushMode: FlushMode.COMMIT, serialization: { forceObject: true }, findOneOrFailHandler: /* @__PURE__ */ __name((entityName, where) => new BadRequestException2(`Cannot find ${entityName} where ${util.inspect(where)}`), "findOneOrFailHandler") }; if (this.migration) { options = R5.mergeDeepRight(options, { extensions: [ Migrator ], migrations: { snapshotName: "snapshot", path: "migrations", fileName: /* @__PURE__ */ __name((timestamp) => `migration-${timestamp}`, "fileName") } }); } return R5.mergeDeepRight(options, config || {}); } }; _ts_decorate4([ IsBoolean2() ], DatabaseConfig.prototype, "debug", void 0); _ts_decorate4([ IsBoolean2(), _ts_metadata4("design:type", Boolean) ], DatabaseConfig.prototype, "migration", void 0); _ts_decorate4([ IsString2(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "dbName", void 0); _ts_decorate4([ IsString2(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "host", void 0); _ts_decorate4([ ToNumber(), IsNumber2({ allowNaN: false }), _ts_metadata4("design:type", Number) ], DatabaseConfig.prototype, "port", void 0); _ts_decorate4([ IsString2(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "user", void 0); _ts_decorate4([ IsString2(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "password", void 0); _ts_decorate4([ IsString2() ], DatabaseConfig.prototype, "timezone", void 0); // src/swagger/is-reference-object.ts function isReferenceObject(obj) { return !!obj && typeof obj === "object" && typeof obj.$ref === "string"; } __name(isReferenceObject, "isReferenceObject"); // src/swagger/deep-dereference.ts function deepDereference(openapi, reference) { let current = reference; const stack = []; while (isReferenceObject(current)) { const refPath = current.$ref; if (stack.includes(refPath)) return void 0; stack.push(refPath); const parts = refPath.replace(/^#\//, "").split("/"); let next = openapi; for (const part of parts) { next = next[part]; } if (!next) return void 0; current = next; } return current; } __name(deepDereference, "deepDereference"); // src/swagger/for-each-parameter.ts function forEachParameter(openapi, callback) { for (const pathItem of Object.values(openapi.paths)) { for (const operation of Object.values(pathItem)) { if (operation && operation.parameters) { for (const parameter of operation.parameters) { if (!("$ref" in parameter)) { callback(parameter); } } } } } for (const parameter of Object.values(openapi.components?.parameters || {})) { if (!("$ref" in parameter)) { callback(parameter); } } } __name(forEachParameter, "forEachParameter"); // src/swagger/deep-objectify-queries.ts function deepObjectifyQueries(openapi) { forEachParameter(openapi, (parameter) => { if (parameter.in === "query" && parameter.schema && parameter.style === void 0 && (parameter.explode === void 0 || parameter.explode === true)) { const schema = isReferenceObject(parameter.schema) ? deepDereference(openapi, parameter.schema) : parameter.schema; if (schema && (schema.type === "object" || schema.type === "array")) { parameter.style = "deepObject"; } } }); } __name(deepObjectifyQueries, "deepObjectifyQueries"); // src/pipes/validation.pipe.ts import { MikroORM, EntityManager } from "@mikro-orm/core"; import { ValidationPipe } from "@nestjs/common"; import { Injectable as Injectable2, Logger as Logger2 } from "@nestjs/common"; function _ts_decorate5(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; } __name(_ts_decorate5, "_ts_decorate"); function _ts_metadata5(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } __name(_ts_metadata5, "_ts_metadata"); function deepMap(obj, fn) { if (Array.isArray(obj)) { return obj.map((item) => deepMap(item, fn)); } else { return fn(obj); } } __name(deepMap, "deepMap"); function transformReference(em, value, metatype) { if (typeof value !== "object" || value === null) return value; const entityProperties = getMetadata2(metatype); const primaryProperties = entityProperties.filter((p) => p.primary); if (primaryProperties.length === 1) { const propertyKey = primaryProperties[0].name; const ref = em.getReference(metatype, value[propertyKey], { wrapped: true }); return ref; } else if (primaryProperties.length > 1) { const propertyKeys = primaryProperties.map((p) => p.name); const ref = em.getReference(metatype, propertyKeys.map((key) => value[key]), { wrapped: true }); return ref; } return value; } __name(transformReference, "transformReference"); function deepTransform(em, value, metatype) { if (typeof value !== "object" || value === null) { return value; } const propertyKeys = ModelRegister.getModelPropertyKeys(metatype); const result = { ...value }; for (const propertyKey of propertyKeys) { const propertyMetadata = ModelRegister.getProperty(metatype, propertyKey); if (!propertyMetadata) continue; if (!(propertyKey in value)) continue; const propertyValue = value[propertyKey]; if (propertyMetadata.kind === "nested") { const ctor = propertyMetadata.type(); if (EntityRefTypeClassMetadataPropertyKey in ctor) { result[propertyKey] = transformReference(em, propertyValue, ctor); } else { const v = deepTransform(em, propertyValue, ctor); result[propertyKey] = v; } } else if (propertyMetadata.kind === "list") { result[propertyKey] = deepMap(propertyValue, (item) => deepTransform(em, item, propertyMetadata.type())); } else if (propertyMetadata.kind === "dictionary") { result[propertyKey] = Object.fromEntries(Object.entries(propertyValue).map(([k, v]) => [ k, deepTransform(em, v, propertyMetadata.type()) ])); } } return result; } __name(deepTransform, "deepTransform"); var BukaValidationPipe = class _BukaValidationPipe extends ValidationPipe { static { __name(this, "BukaValidationPipe"); } orm; em; logger = new Logger2(_BukaValidationPipe.name); constructor(orm, em) { super(), this.orm = orm, this.em = em; } async transform(value, metadata) { value = await super.transform(value, metadata); if (!metadata.metatype || typeof metadata.metatype !== "function") { return value; } const metatype = metadata.metatype; const result = await deepTransform(this.em, value, metatype); return result; } static withParams(options) { let BukaParametrizedValidationPipe = class BukaParametrizedValidationPipe2 extends ValidationPip