@buka/nestjs-type-helper
Version:
An easy to use nestjs config module
1,426 lines (1,385 loc) • 87.7 kB
JavaScript
"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];
}