@buka/nestjs-type-helper
Version:
An easy to use nestjs config module
1,490 lines (1,447 loc) • 82 kB
JavaScript
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