UNPKG

@buka/nestjs-type-helper

Version:
1,426 lines (1,385 loc) 87.7 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { BaseEntity: () => BaseEntity, BukaValidationPipe: () => BukaValidationPipe, DatabaseConfig: () => DatabaseConfig, EntityDtoType: () => EntityDtoType, EntityEnum: () => EntityEnum, EntityManyToMany: () => EntityManyToMany, EntityManyToOne: () => EntityManyToOne, EntityOneToMany: () => EntityOneToMany, EntityOneToOne: () => EntityOneToOne, EntityProperty: () => EntityProperty, EntityRefType: () => EntityRefType, EntityRefTypeClassMetadataPropertyKey: () => EntityRefTypeClassMetadataPropertyKey, EntityTransient: () => EntityTransient, FilterQueryOperators: () => FilterQueryOperators, FilterQueryOperatorsMetadataKey: () => FilterQueryOperatorsMetadataKey, FilterQueryType: () => FilterQueryType, HAS_ANY_KEY: () => HAS_ANY_KEY, HasAnyKey: () => HasAnyKey, ListResponseBodyType: () => ListResponseBodyType, MATCH_JSON_SCHEMA: () => MATCH_JSON_SCHEMA, MatchJsonSchema: () => MatchJsonSchema, Model: () => Model, ModelRegister: () => ModelRegister, Nested: () => Nested, NestedProperty: () => NestedProperty, OmitType: () => OmitType, OptionalPageQuery: () => OptionalPageQuery, OrderQueryType: () => OrderQueryType, PageQuery: () => PageQuery, PartialType: () => PartialType, PickType: () => PickType, Property: () => Property, RELATION_METADATA_KEY: () => RELATION_METADATA_KEY, ReferencePropertiesMetadataKey: () => ReferencePropertiesMetadataKey, ReferenceProperty: () => ReferenceProperty, Relation: () => Relation, ResponseBodyType: () => ResponseBodyType, Slice: () => Slice, TimestampedEntity: () => TimestampedEntity, deepObjectifyQueries: () => deepObjectifyQueries, getFilterQueryOperators: () => getFilterQueryOperators }); module.exports = __toCommonJS(index_exports); // src/mikro-orm/models/base-entity.ts var import_core6 = require("@mikro-orm/core"); var import_swagger5 = require("@nestjs/swagger"); var import_class_validator7 = require("class-validator"); // src/mikro-orm/models/timestamped-entity.ts var import_core5 = require("@mikro-orm/core"); // src/mikro-orm/decorators/entity-property.decorator.ts var import_core4 = require("@mikro-orm/core"); // src/mikro-orm/decorators/api-entity-property.decorator.ts var import_swagger4 = require("@nestjs/swagger"); var import_core3 = require("@mikro-orm/core"); // src/mikro-orm/decorators/api-scalar-entity-property.decorator.ts var import_core = require("@mikro-orm/core"); var import_common6 = require("@nestjs/common"); var import_class_validator6 = require("class-validator"); // src/decorators/nested-property.decorator.ts var R2 = __toESM(require("ramda")); var import_common = require("@nestjs/common"); var import_class_transformer = require("class-transformer"); var import_class_validator2 = require("class-validator"); // src/decorators/model/model.register.ts var R = __toESM(require("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 var import_ts_custom_error = require("ts-custom-error"); var Exception = class extends import_ts_custom_error.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 var import_class_validator = require("class-validator"); var import_swagger = require("@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) { (0, import_class_validator.IsOptional)()(target, propertyKey); } if (options?.schema) { if (options?.optional) { (0, import_swagger.ApiPropertyOptional)(options.schema)(target, propertyKey); } else { (0, import_swagger.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 = [ (0, import_class_validator2.ValidateNested)({ each: !!options.each }), (0, import_class_transformer.Type)(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 (0, import_class_validator2.IsNotEmpty)({ each: options.each, message: "$property is required" }) ]); } return (0, import_common.applyDecorators)(...decorators); } __name(NestedProperty, "NestedProperty"); // src/decorators/reference-property.decorator.ts var import_common2 = require("@nestjs/common"); var import_class_validator3 = require("class-validator"); var ReferencePropertiesMetadataKey = "buka:reference-properties"; function ReferenceProperty(entity) { return (0, import_common2.applyDecorators)((0, import_class_validator3.Allow)(), NestedProperty(() => EntityRefType(entity()), { relation: { kind: "1:1", type: /* @__PURE__ */ __name(() => entity(), "type") } })); } __name(ReferenceProperty, "ReferenceProperty"); // src/decorators/class-validator/has-any-key.ts var import_class_validator4 = require("class-validator"); var HAS_ANY_KEY = "hasAnyKey"; function HasAnyKey(keys, validationOptions) { return function(object, propertyName) { (0, import_class_validator4.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 var import_class_validator5 = require("class-validator"); var import_jsonschema = require("jsonschema"); var MATCH_JSON_SCHEMA = "matchJsonSchema"; function MatchJsonSchema(schema, validationOptions) { return function(object, propertyName) { (0, import_class_validator5.registerDecorator)({ name: MATCH_JSON_SCHEMA, target: object.constructor, propertyName, constraints: [ schema ], options: validationOptions, validator: { validate(value, args) { const [schema2] = args.constraints; const results = (0, import_jsonschema.validate)(value, schema2); return results.valid; }, defaultMessage({ value, constraints }) { return `${propertyName} must match the JSON schema`; } } }); }; } __name(MatchJsonSchema, "MatchJsonSchema"); // src/decorators/page-query.ts var import_common4 = require("@nestjs/common"); var import_swagger2 = require("@nestjs/swagger"); // src/pipes/page-query-validation.pipe.ts var import_common3 = require("@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 import_common3.InternalServerErrorException("BukaPageQueryValidationPipe can only be used to validate query parameters."); } if (!value.page) { if (this.options.optional) { return value; } else { throw new import_common3.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 import_common3.BadRequestException(mixedOffsetAndCursorError); } const limit = parseInt(value.page.limit, 10); const offset = parseInt(value.page.offset, 10); if (isNaN(limit) || limit <= 0) { throw new import_common3.BadRequestException("Invalid page query: limit must be a positive integer."); } if (isNaN(offset) || offset < 0) { throw new import_common3.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 import_common3.BadRequestException(mixedOffsetAndCursorError); } if ("before" in value.page || "last" in value.page) { throw new import_common3.BadRequestException(mixedNextAndLastCursorError); } const after = value.page.after; const first = parseInt(value.page.first, 10); if (typeof after !== "string") { throw new import_common3.BadRequestException("Invalid page query: after must be a string."); } if (isNaN(first) || first <= 0) { throw new import_common3.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 import_common3.BadRequestException(mixedOffsetAndCursorError); } if ("after" in value.page || "first" in value.page) { throw new import_common3.BadRequestException(mixedNextAndLastCursorError); } const before = value.page.before; const last = parseInt(value.page.last, 10); if (typeof before !== "string") { throw new import_common3.BadRequestException("Invalid page query: before must be a string."); } if (isNaN(last) || last <= 0) { throw new import_common3.BadRequestException("Invalid page query: last must be a positive integer."); } return { page: { before, last } }; } } throw new import_common3.BadRequestException("Invalid page query: missing pagination parameters."); } }; BukaPageQueryValidationPipe = _ts_decorate([ (0, import_common3.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") { (0, import_swagger2.ApiQuery)({ name: "page", required: true, schema: OffsetPageSchema })(target, propertyKey, descriptor); } else if (mode === "cursor") { (0, import_swagger2.ApiQuery)({ name: "page", required: true, schema: { oneOf: [ NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } else { (0, import_swagger2.ApiQuery)({ name: "page", required: true, schema: { oneOf: [ OffsetPageSchema, NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } (0, import_common4.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") { (0, import_swagger2.ApiQuery)({ name: "page", required: false, schema: OffsetPageSchema }); } else if (mode === "cursor") { (0, import_swagger2.ApiQuery)({ name: "page", required: false, schema: { oneOf: [ NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } else { (0, import_swagger2.ApiQuery)({ name: "page", required: false, schema: { oneOf: [ OffsetPageSchema, NextCursorPageSchema, PreviousCursorPageSchema ] } })(target, propertyKey, descriptor); } (0, import_common4.Query)(new BukaPageQueryValidationPipe({ mode, optional: true }))(target, propertyKey, parameterIndex); }; } __name(OptionalPageQuery, "OptionalPageQuery"); // src/utils/logger.ts var import_common5 = require("@nestjs/common"); var logger = new import_common5.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 import_core.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((0, import_class_validator6.IsString)()); if (length) decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(VarcharProperty, "VarcharProperty"); function CharProperty(length, options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.IsString)()); if (length) decorators.push((0, import_class_validator6.MaxLength)(length), (0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(CharProperty, "CharProperty"); function TextProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(TextProperty, "TextProperty"); function MoneyProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(MoneyProperty, "MoneyProperty"); function BigIntProperty(options) { const { meta } = options; let mode; if (meta.type === "bigint") { mode = "string"; } else if (meta.type instanceof import_core.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((0, import_class_validator6.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((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(BigIntProperty, "BigIntProperty"); function IntProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(IntProperty, "IntProperty"); function TinyintProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(TinyintProperty, "TinyintProperty"); function DoubleProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(DoubleProperty, "DoubleProperty"); function DecimalProperty(options) { const decorators = []; if (!options.unverified) { if (options.meta.scale) decorators.push((0, import_class_validator6.IsNumber)({ maxDecimalPlaces: options.meta.scale })); else decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(DecimalProperty, "DecimalProperty"); function DatetimeProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(DatetimeProperty, "DatetimeProperty"); function BooleanProperty(options) { const decorators = []; if (!options.unverified) { decorators.push((0, import_class_validator6.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 (0, import_common6.applyDecorators)(...decorators); } __name(BooleanProperty, "BooleanProperty"); // src/utils/nestjs-swagger-utils.ts var R3 = __toESM(require("ramda")); var import_model_properties_accessor = require("@nestjs/swagger/dist/services/model-properties-accessor"); var import_constants = require("@nestjs/swagger/dist/constants"); var import_plugin_constants = require("@nestjs/swagger/dist/plugin/plugin-constants"); var import_mapped_types = require("@nestjs/swagger/dist/type-helpers/mapped-types.utils"); var import_swagger3 = require("@nestjs/swagger"); var import_shared = require("@nestjs/common/utils/shared.utils"); var import_is_built_in_type = require("@nestjs/swagger/dist/utils/is-built-in-type.util"); var import_schema_object_metadata = require("@nestjs/swagger/dist/interfaces/schema-object-metadata.interface"); var modelPropertiesAccessor = new import_model_properties_accessor.ModelPropertiesAccessor(); function cloneMetadata(target, source, keys) { (0, import_mapped_types.clonePluginMetadataFactory)(target, source.prototype, (metadata) => R3.pick(keys, metadata)); for (const propertyKey of keys) { const metadata = getMetadataOfDecorator(source, propertyKey); if (metadata) { (0, import_swagger3.ApiProperty)(metadata)(target.prototype, propertyKey); } } } __name(cloneMetadata, "cloneMetadata"); function getMetadataOfDecorator(classRef, propertyKey) { if (propertyKey) { return Reflect.getMetadata(import_constants.DECORATORS.API_MODEL_PROPERTIES, classRef.prototype, propertyKey); } const props = modelPropertiesAccessor.getModelProperties(classRef.prototype); return R3.fromPairs(props.map((prop) => [ prop, Reflect.getMetadata(import_constants.DECORATORS.API_MODEL_PROPERTIES, classRef.prototype, prop) ])); } __name(getMetadataOfDecorator, "getMetadataOfDecorator"); function getMetadataOfPlugin(classRef, propertyKey) { const propsInPlugin = typeof classRef[import_plugin_constants.METADATA_FACTORY_NAME] === "function" ? classRef[import_plugin_constants.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 (0, import_shared.isFunction)(type) && type.name == "type"; } __name(isLazyTypeFunc, "isLazyTypeFunc"); // src/utils/mikro-orm-utils.ts var R4 = __toESM(require("ramda")); var import_core2 = require("@mikro-orm/core"); function getMetadata2(classRef) { const metadatas = []; let parent = classRef; do { const meta = import_core2.MetadataStorage.getMetadataFromDecorator(parent); if (meta instanceof import_core2.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 var import_mapped_types2 = require("@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); (0, import_mapped_types2.inheritValidationMetadata)(classRef, EntityRefTypeClass, (key) => primaryProperties.includes(key)); (0, import_mapped_types2.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 = import_core3.MetadataStorage.getMetadataFromDecorator(target.constructor); const prop = meta.properties[propertyKey]; if (!prop) return; if (prop.hidden === true) { (0, import_swagger4.ApiHideProperty)()(target, propertyKey); return; } if (prop.kind === import_core3.ReferenceKind.EMBEDDED) { return; } if (prop.kind === import_core3.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 === import_core3.ReferenceKind.ONE_TO_ONE || prop.kind === import_core3.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 === import_core3.ReferenceKind.ONE_TO_MANY || prop.kind === import_core3.ReferenceKind.MANY_TO_MANY) { NestedProperty(() => getType(), { each: true, optional: prop.nullable, schema: { description: prop.comment, type: "array", items: { type: (0, import_swagger4.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"); (0, import_core4.Property)(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"); } [import_core5.Config]; [import_core5.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 }>; [import_core6.PrimaryKeyProp]; id; }; _ts_decorate3([ (0, import_swagger5.ApiProperty)({ type: "string", description: "PK", example: "1", required: true }), (0, import_core6.PrimaryKey)({ type: new import_core6.BigIntType("string"), comment: "\u4E3B\u952E" }), (0, import_class_validator7.IsNumberString)(), _ts_metadata3("design:type", String) ], BaseEntity.prototype, "id", void 0); // src/mikro-orm/converters/entity-dto-type/entity-dto-type.ts var import_mapped_types3 = require("@nestjs/mapped-types"); var import_core7 = require("@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 = (0, import_core7.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; } }; (0, import_mapped_types3.inheritValidationMetadata)(entity, EntityDtoTypeClass, (key) => keys.includes(key)); (0, import_mapped_types3.inheritTransformationMetadata)(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 var import_core8 = require("@mikro-orm/core"); function EntityEnum(options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityEnum() can only be used on string property"); (0, import_core8.Enum)(options)(target, propertyKey); ApiEntityProperty({ example: options.example, enumName: options.enumName })(target, propertyKey); }; } __name(EntityEnum, "EntityEnum"); // src/mikro-orm/decorators/entity-transient.decorator.ts var import_core9 = require("@mikro-orm/core"); function EntityTransient() { return (0, import_core9.Property)({ persist: false }); } __name(EntityTransient, "EntityTransient"); // src/mikro-orm/decorators/entity-one-to-one.decorator.ts var import_core10 = require("@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"); (0, import_core10.OneToOne)(entity, mappedByOrOptions, options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityOneToOne, "EntityOneToOne"); // src/mikro-orm/decorators/entity-one-to-many.decorator.ts var import_core11 = require("@mikro-orm/core"); function EntityOneToMany(options) { return (target, propertyKey) => { if (typeof propertyKey !== "string") throw new TypeError("@EntityOneToMany() can only be used on string property"); (0, import_core11.OneToMany)(options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityOneToMany, "EntityOneToMany"); // src/mikro-orm/decorators/entity-many-to-one.decorator.ts var import_core12 = require("@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"); (0, import_core12.ManyToOne)(entity, options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityManyToOne, "EntityManyToOne"); // src/mikro-orm/decorators/entity-many-to-many.decorator.ts var import_core13 = require("@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"); (0, import_core13.ManyToMany)(entity, mappedBy, options)(target, propertyKey); ApiEntityProperty()(target, propertyKey); }; } __name(EntityManyToMany, "EntityManyToMany"); // src/mikro-orm/database.config.ts var import_class_transformer_extra = require("@buka/class-transformer-extra"); var import_class_validator8 = require("class-validator"); var R5 = __toESM(require("ramda")); var util = __toESM(require("util")); var import_migrations = require("@mikro-orm/migrations"); var import_core14 = require("@mikro-orm/core"); var import_common7 = require("@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: import_core14.FlushMode.COMMIT, serialization: { forceObject: true }, findOneOrFailHandler: /* @__PURE__ */ __name((entityName, where) => new import_common7.BadRequestException(`Cannot find ${entityName} where ${util.inspect(where)}`), "findOneOrFailHandler") }; if (this.migration) { options = R5.mergeDeepRight(options, { extensions: [ import_migrations.Migrator ], migrations: { snapshotName: "snapshot", path: "migrations", fileName: /* @__PURE__ */ __name((timestamp) => `migration-${timestamp}`, "fileName") } }); } return R5.mergeDeepRight(options, config || {}); } }; _ts_decorate4([ (0, import_class_validator8.IsBoolean)() ], DatabaseConfig.prototype, "debug", void 0); _ts_decorate4([ (0, import_class_validator8.IsBoolean)(), _ts_metadata4("design:type", Boolean) ], DatabaseConfig.prototype, "migration", void 0); _ts_decorate4([ (0, import_class_validator8.IsString)(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "dbName", void 0); _ts_decorate4([ (0, import_class_validator8.IsString)(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "host", void 0); _ts_decorate4([ (0, import_class_transformer_extra.ToNumber)(), (0, import_class_validator8.IsNumber)({ allowNaN: false }), _ts_metadata4("design:type", Number) ], DatabaseConfig.prototype, "port", void 0); _ts_decorate4([ (0, import_class_validator8.IsString)(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "user", void 0); _ts_decorate4([ (0, import_class_validator8.IsString)(), _ts_metadata4("design:type", String) ], DatabaseConfig.prototype, "password", void 0); _ts_decorate4([ (0, import_class_validator8.IsString)() ], 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]; }