@mikro-orm/core 7.0.0-rc.2 → 7.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EntityManager.d.ts +2 -1
- package/EntityManager.js +106 -42
- package/MikroORM.js +4 -4
- package/cache/FileCacheAdapter.js +1 -3
- package/connections/Connection.js +16 -3
- package/drivers/DatabaseDriver.js +26 -8
- package/drivers/IDatabaseDriver.d.ts +43 -0
- package/entity/Collection.js +43 -17
- package/entity/EntityAssigner.js +23 -11
- package/entity/EntityFactory.js +32 -12
- package/entity/EntityHelper.js +25 -16
- package/entity/EntityLoader.js +55 -22
- package/entity/Reference.d.ts +1 -1
- package/entity/Reference.js +37 -8
- package/entity/WrappedEntity.js +5 -1
- package/entity/defineEntity.d.ts +24 -12
- package/entity/utils.js +28 -26
- package/entity/validators.js +2 -1
- package/enums.js +12 -17
- package/errors.js +18 -8
- package/events/EventManager.js +1 -1
- package/exceptions.js +7 -2
- package/hydration/ObjectHydrator.js +27 -13
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/logging/DefaultLogger.js +3 -5
- package/logging/colors.js +3 -6
- package/metadata/EntitySchema.d.ts +2 -2
- package/metadata/EntitySchema.js +12 -2
- package/metadata/MetadataDiscovery.js +106 -47
- package/metadata/MetadataProvider.js +26 -1
- package/metadata/MetadataStorage.js +2 -4
- package/metadata/MetadataValidator.js +20 -5
- package/metadata/types.d.ts +2 -2
- package/naming-strategy/AbstractNamingStrategy.js +5 -2
- package/not-supported.js +5 -1
- package/package.json +38 -38
- package/platforms/Platform.d.ts +1 -0
- package/platforms/Platform.js +49 -23
- package/serialization/EntitySerializer.js +7 -3
- package/serialization/SerializationContext.js +1 -1
- package/typings.d.ts +23 -23
- package/typings.js +9 -9
- package/unit-of-work/ChangeSet.js +4 -4
- package/unit-of-work/ChangeSetComputer.js +8 -6
- package/unit-of-work/ChangeSetPersister.js +13 -8
- package/unit-of-work/CommitOrderCalculator.js +4 -2
- package/unit-of-work/UnitOfWork.d.ts +7 -1
- package/unit-of-work/UnitOfWork.js +51 -22
- package/utils/AbstractMigrator.d.ts +1 -1
- package/utils/AbstractMigrator.js +3 -5
- package/utils/AbstractSchemaGenerator.js +2 -1
- package/utils/AsyncContext.js +1 -1
- package/utils/Configuration.js +8 -4
- package/utils/Cursor.js +4 -2
- package/utils/DataloaderUtils.js +15 -12
- package/utils/EntityComparator.js +51 -43
- package/utils/QueryHelper.js +38 -26
- package/utils/RawQueryFragment.js +3 -2
- package/utils/TransactionManager.js +2 -1
- package/utils/Utils.d.ts +1 -1
- package/utils/Utils.js +36 -30
- package/utils/env-vars.js +6 -5
- package/utils/fs-utils.js +2 -5
- package/utils/upsert-utils.js +6 -3
package/entity/Reference.js
CHANGED
|
@@ -93,7 +93,8 @@ export class Reference {
|
|
|
93
93
|
await wrapped.__em.populate(this.entity, options.populate, options);
|
|
94
94
|
}
|
|
95
95
|
if (!this.isInitialized() || options.refresh) {
|
|
96
|
-
if (options.dataloader ??
|
|
96
|
+
if (options.dataloader ??
|
|
97
|
+
[DataloaderType.ALL, DataloaderType.REFERENCE].includes(wrapped.__em.config.getDataloaderType())) {
|
|
97
98
|
const dataLoader = await wrapped.__em.getDataLoader('ref');
|
|
98
99
|
return dataLoader.load([this, options]);
|
|
99
100
|
}
|
|
@@ -219,16 +220,44 @@ export class ScalarReference {
|
|
|
219
220
|
}
|
|
220
221
|
Object.defineProperties(Reference.prototype, {
|
|
221
222
|
__reference: { value: true, enumerable: false },
|
|
222
|
-
__meta: {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
__meta: {
|
|
224
|
+
get() {
|
|
225
|
+
return this.entity.__meta;
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
__platform: {
|
|
229
|
+
get() {
|
|
230
|
+
return this.entity.__platform;
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
__helper: {
|
|
234
|
+
get() {
|
|
235
|
+
return this.entity.__helper;
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
$: {
|
|
239
|
+
get() {
|
|
240
|
+
return this.entity;
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
get: {
|
|
244
|
+
get() {
|
|
245
|
+
return () => this.entity;
|
|
246
|
+
},
|
|
247
|
+
},
|
|
227
248
|
});
|
|
228
249
|
Object.defineProperties(ScalarReference.prototype, {
|
|
229
250
|
__scalarReference: { value: true, enumerable: false },
|
|
230
|
-
$: {
|
|
231
|
-
|
|
251
|
+
$: {
|
|
252
|
+
get() {
|
|
253
|
+
return this.value;
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
get: {
|
|
257
|
+
get() {
|
|
258
|
+
return () => this.value;
|
|
259
|
+
},
|
|
260
|
+
},
|
|
232
261
|
});
|
|
233
262
|
/**
|
|
234
263
|
* shortcut for `wrap(entity).toReference()`
|
package/entity/WrappedEntity.js
CHANGED
|
@@ -71,7 +71,11 @@ export class WrappedEntity {
|
|
|
71
71
|
if (!this.__em) {
|
|
72
72
|
throw ValidationError.entityNotManaged(this.entity);
|
|
73
73
|
}
|
|
74
|
-
return this.__em.findOne(this.entity.constructor, this.entity, {
|
|
74
|
+
return this.__em.findOne(this.entity.constructor, this.entity, {
|
|
75
|
+
...options,
|
|
76
|
+
refresh: true,
|
|
77
|
+
schema: this.__schema,
|
|
78
|
+
});
|
|
75
79
|
}
|
|
76
80
|
async populate(populate, options = {}) {
|
|
77
81
|
if (!this.__em) {
|
package/entity/defineEntity.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EntityManager } from '../EntityManager.js';
|
|
2
2
|
import type { ColumnType, PropertyOptions, ReferenceOptions, EnumOptions, EmbeddedOptions, ManyToOneOptions, OneToManyOptions, OneToOneOptions, ManyToManyOptions } from '../metadata/types.js';
|
|
3
|
-
import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, EntityRepositoryType, Hidden, Opt, Primary, EntityClass, EntitySchemaWithMeta, InferEntity, MaybeReturnType, Ref, IndexCallback, FormulaCallback, EntityCtor, IsNever } from '../typings.js';
|
|
3
|
+
import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, EntityRepositoryType, Hidden, Opt, Primary, EntityClass, EntitySchemaWithMeta, InferEntity, MaybeReturnType, Ref, IndexCallback, FormulaCallback, EntityCtor, IsNever, IWrappedEntity, DefineConfig, Config } from '../typings.js';
|
|
4
4
|
import type { Raw } from '../utils/RawQueryFragment.js';
|
|
5
5
|
import type { ScalarReference } from './Reference.js';
|
|
6
6
|
import type { SerializeOptions } from '../serialization/EntitySerializer.js';
|
|
@@ -96,7 +96,7 @@ export interface PropertyChain<Value, Options> {
|
|
|
96
96
|
serializer(serializer: (value: Value, options?: SerializeOptions<any>) => any): PropertyChain<Value, Options>;
|
|
97
97
|
serializedName(serializedName: string): PropertyChain<Value, Options>;
|
|
98
98
|
groups(...groups: string[]): PropertyChain<Value, Options>;
|
|
99
|
-
customOrder(...customOrder:
|
|
99
|
+
customOrder(...customOrder: string[] | number[] | boolean[]): PropertyChain<Value, Options>;
|
|
100
100
|
extra(extra: string): PropertyChain<Value, Options>;
|
|
101
101
|
ignoreSchemaChanges(...ignoreSchemaChanges: ('type' | 'extra' | 'default')[]): PropertyChain<Value, Options>;
|
|
102
102
|
index(index?: boolean | string): PropertyChain<Value, Options>;
|
|
@@ -409,7 +409,7 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
|
|
|
409
409
|
/**
|
|
410
410
|
* Specify a custom order based on the values. (SQL only)
|
|
411
411
|
*/
|
|
412
|
-
customOrder(...customOrder:
|
|
412
|
+
customOrder(...customOrder: string[] | number[] | boolean[]): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
|
|
413
413
|
/**
|
|
414
414
|
* Specify comment of column for {@link https://mikro-orm.io/docs/schema-generator Schema Generator}. (SQL only)
|
|
415
415
|
*/
|
|
@@ -501,7 +501,7 @@ export declare class OneToManyOptionsBuilderOnlyMappedBy<Value extends object> e
|
|
|
501
501
|
kind: '1:m';
|
|
502
502
|
}, IncludeKeysForOneToManyOptions> {
|
|
503
503
|
/** Point to the owning side property name. */
|
|
504
|
-
mappedBy(mappedBy:
|
|
504
|
+
mappedBy(mappedBy: keyof Value | ((e: Value) => any)): Pick<UniversalPropertyOptionsBuilder<Value, EmptyOptions & {
|
|
505
505
|
kind: '1:m';
|
|
506
506
|
}, IncludeKeysForOneToManyOptions>, IncludeKeysForOneToManyOptions>;
|
|
507
507
|
}
|
|
@@ -553,7 +553,7 @@ declare const propertyBuilders: {
|
|
|
553
553
|
};
|
|
554
554
|
/** Own keys + base entity keys (when TBase is not `never`). Guards against `keyof never = string | number | symbol`. */
|
|
555
555
|
type AllKeys<TProperties, TBase> = keyof TProperties | (IsNever<TBase> extends true ? never : keyof TBase);
|
|
556
|
-
export interface EntityMetadataWithProperties<TName extends string, TTableName extends string, TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never, TRepository = never> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK, TBase, TRepository>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'repository' | 'orderBy'> {
|
|
556
|
+
export interface EntityMetadataWithProperties<TName extends string, TTableName extends string, TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never, TRepository = never, TForceObject extends boolean = false> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK, TBase, TRepository>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'repository' | 'orderBy'> {
|
|
557
557
|
name: TName;
|
|
558
558
|
tableName?: TTableName;
|
|
559
559
|
extends?: {
|
|
@@ -563,6 +563,7 @@ export interface EntityMetadataWithProperties<TName extends string, TTableName e
|
|
|
563
563
|
primaryKeys?: TPK & InferPrimaryKey<TProperties>[];
|
|
564
564
|
hooks?: DefineEntityHooks;
|
|
565
565
|
repository?: () => TRepository;
|
|
566
|
+
forceObject?: TForceObject;
|
|
566
567
|
inheritance?: 'tpt';
|
|
567
568
|
orderBy?: {
|
|
568
569
|
[K in Extract<AllKeys<TProperties, TBase>, string>]?: QueryOrderKeysFlat;
|
|
@@ -588,7 +589,7 @@ export interface EntityMetadataWithProperties<TName extends string, TTableName e
|
|
|
588
589
|
deferMode?: DeferMode | `${DeferMode}`;
|
|
589
590
|
}[];
|
|
590
591
|
}
|
|
591
|
-
export declare function defineEntity<const TName extends string, const TTableName extends string, const TProperties extends Record<string, any>, const TPK extends (keyof TProperties)[] | undefined = undefined, const TBase = never, const TRepository = never>(meta: EntityMetadataWithProperties<TName, TTableName, TProperties, TPK, TBase, TRepository>): EntitySchemaWithMeta<TName, TTableName, InferEntityFromProperties<TProperties, TPK, TBase, TRepository>, TBase, TProperties>;
|
|
592
|
+
export declare function defineEntity<const TName extends string, const TTableName extends string, const TProperties extends Record<string, any>, const TPK extends (keyof TProperties)[] | undefined = undefined, const TBase = never, const TRepository = never, const TForceObject extends boolean = false>(meta: EntityMetadataWithProperties<TName, TTableName, TProperties, TPK, TBase, TRepository, TForceObject>): EntitySchemaWithMeta<TName, TTableName, InferEntityFromProperties<TProperties, TPK, TBase, TRepository, TForceObject>, TBase, TProperties>;
|
|
592
593
|
export declare function defineEntity<const TEntity = any, const TProperties extends Record<string, any> = Record<string, any>, const TClassName extends string = string, const TTableName extends string = string, const TBase = never, const TClass extends EntityCtor = EntityCtor<TEntity>>(meta: Omit<Partial<EntityMetadata<TEntity>>, 'properties' | 'extends' | 'className' | 'tableName' | 'hooks'> & {
|
|
593
594
|
class: TClass;
|
|
594
595
|
className?: TClassName;
|
|
@@ -658,23 +659,34 @@ export interface DefineEntityHooks<T = any> {
|
|
|
658
659
|
}
|
|
659
660
|
type PropertyValueType = PropertyOptions<any>['type'];
|
|
660
661
|
type InferPropertyValueType<T extends PropertyValueType> = T extends string ? InferTypeByString<T> : T extends NumberConstructor ? number : T extends StringConstructor ? string : T extends BooleanConstructor ? boolean : T extends DateConstructor ? Date : T extends ArrayConstructor ? string[] : T extends Constructor<infer TType> ? TType extends Type<infer TValue, any> ? NonNullable<TValue> : TType : T extends Type<infer TValue, any> ? NonNullable<TValue> : any;
|
|
661
|
-
type InferTypeByString<T extends string> = T extends keyof typeof types ? InferJSType<typeof types[T]> : InferColumnType<T>;
|
|
662
|
+
type InferTypeByString<T extends string> = T extends keyof typeof types ? InferJSType<(typeof types)[T]> : InferColumnType<T>;
|
|
662
663
|
type InferJSType<T> = T extends typeof Type<infer TValue, any> ? NonNullable<TValue> : never;
|
|
663
664
|
type InferColumnType<T extends string> = T extends 'int' | 'int4' | 'integer' | 'bigint' | 'int8' | 'int2' | 'tinyint' | 'smallint' | 'mediumint' ? number : T extends 'double' | 'double precision' | 'real' | 'float8' | 'decimal' | 'numeric' | 'float' | 'float4' ? number : T extends 'datetime' | 'time' | 'time with time zone' | 'timestamp' | 'timestamp with time zone' | 'timetz' | 'timestamptz' | 'date' | 'interval' ? Date : T extends 'ObjectId' | 'objectId' | 'character varying' | 'varchar' | 'char' | 'character' | 'uuid' | 'text' | 'tinytext' | 'mediumtext' | 'longtext' | 'enum' ? string : T extends 'boolean' | 'bool' | 'bit' ? boolean : T extends 'blob' | 'tinyblob' | 'mediumblob' | 'longblob' | 'bytea' ? Buffer : T extends 'point' | 'line' | 'lseg' | 'box' | 'circle' | 'path' | 'polygon' | 'geometry' ? number[] : T extends 'tsvector' | 'tsquery' ? string[] : T extends 'json' | 'jsonb' ? any : any;
|
|
664
|
-
|
|
665
|
+
type BaseEntityMethodKeys = 'toObject' | 'toPOJO' | 'serialize' | 'assign' | 'populate' | 'init' | 'toReference';
|
|
666
|
+
export type InferEntityFromProperties<Properties extends Record<string, any>, PK extends (keyof Properties)[] | undefined = undefined, Base = never, Repository = never, ForceObject extends boolean = false> = (IsNever<Base> extends true ? {} : Base extends {
|
|
667
|
+
toObject(...args: any[]): any;
|
|
668
|
+
} ? Pick<IWrappedEntity<{
|
|
665
669
|
-readonly [K in keyof Properties]: InferBuilderValue<MaybeReturnType<Properties[K]>>;
|
|
666
670
|
} & {
|
|
667
671
|
[PrimaryKeyProp]?: InferCombinedPrimaryKey<Properties, PK, Base>;
|
|
668
672
|
} & (IsNever<Repository> extends true ? {} : {
|
|
669
673
|
[EntityRepositoryType]?: Repository extends Constructor<infer R> ? R : Repository;
|
|
670
|
-
}) &
|
|
674
|
+
}) & Omit<Base, typeof PrimaryKeyProp>>, BaseEntityMethodKeys> : {}) & {
|
|
675
|
+
-readonly [K in keyof Properties]: InferBuilderValue<MaybeReturnType<Properties[K]>>;
|
|
676
|
+
} & {
|
|
677
|
+
[PrimaryKeyProp]?: InferCombinedPrimaryKey<Properties, PK, Base>;
|
|
678
|
+
} & (IsNever<Repository> extends true ? {} : {
|
|
679
|
+
[EntityRepositoryType]?: Repository extends Constructor<infer R> ? R : Repository;
|
|
680
|
+
}) & (IsNever<Base> extends true ? {} : Omit<Base, typeof PrimaryKeyProp>) & (ForceObject extends true ? {
|
|
681
|
+
[Config]?: DefineConfig<{
|
|
682
|
+
forceObject: true;
|
|
683
|
+
}>;
|
|
684
|
+
} : {});
|
|
671
685
|
type InferCombinedPrimaryKey<Properties extends Record<string, any>, PK, Base> = PK extends undefined ? CombinePrimaryKeys<InferPrimaryKey<Properties>, ExtractBasePrimaryKey<Base>> : PK;
|
|
672
686
|
type ExtractBasePrimaryKey<Base> = Base extends {
|
|
673
687
|
[PrimaryKeyProp]?: infer BasePK;
|
|
674
688
|
} ? BasePK : never;
|
|
675
|
-
type CombinePrimaryKeys<ChildPK, BasePK> = [
|
|
676
|
-
ChildPK
|
|
677
|
-
] extends [never] ? BasePK : [BasePK] extends [never] ? IsUnion<ChildPK> extends true ? ChildPK[] : ChildPK : ChildPK | BasePK;
|
|
689
|
+
type CombinePrimaryKeys<ChildPK, BasePK> = [ChildPK] extends [never] ? BasePK : [BasePK] extends [never] ? IsUnion<ChildPK> extends true ? ChildPK[] : ChildPK : ChildPK | BasePK;
|
|
678
690
|
export type InferPrimaryKey<Properties extends Record<string, any>> = {
|
|
679
691
|
[K in keyof Properties]: MaybeReturnType<Properties[K]> extends {
|
|
680
692
|
'~options': {
|
package/entity/utils.js
CHANGED
|
@@ -17,15 +17,17 @@ function expandNestedPopulate(parentProp, parts, strategy, all) {
|
|
|
17
17
|
* @internal
|
|
18
18
|
*/
|
|
19
19
|
export function expandDotPaths(meta, populate, normalized = false) {
|
|
20
|
-
const ret = normalized
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
const ret = normalized
|
|
21
|
+
? populate
|
|
22
|
+
: Utils.asArray(populate).map(field => {
|
|
23
|
+
if (typeof field === 'string') {
|
|
24
|
+
return { field };
|
|
25
|
+
}
|
|
26
|
+
/* v8 ignore next */
|
|
27
|
+
return typeof field === 'boolean' || field.field === PopulatePath.ALL
|
|
28
|
+
? { all: !!field, field: meta.primaryKeys[0] }
|
|
29
|
+
: field;
|
|
30
|
+
});
|
|
29
31
|
for (const p of ret) {
|
|
30
32
|
if (!p.field.includes('.')) {
|
|
31
33
|
continue;
|
|
@@ -35,8 +37,8 @@ export function expandDotPaths(meta, populate, normalized = false) {
|
|
|
35
37
|
p.children ??= [];
|
|
36
38
|
const prop = meta.properties[p.field];
|
|
37
39
|
if (parts[0] === PopulatePath.ALL) {
|
|
38
|
-
prop
|
|
39
|
-
.filter(prop => prop.lazy || prop.kind !== ReferenceKind.SCALAR)
|
|
40
|
+
prop
|
|
41
|
+
.targetMeta.props.filter(prop => prop.lazy || prop.kind !== ReferenceKind.SCALAR)
|
|
40
42
|
.forEach(prop => p.children.push({ field: prop.name, strategy: p.strategy }));
|
|
41
43
|
}
|
|
42
44
|
else if (prop.kind === ReferenceKind.EMBEDDED) {
|
|
@@ -67,6 +69,21 @@ export function getLoadingStrategy(strategy, kind) {
|
|
|
67
69
|
}
|
|
68
70
|
return strategy;
|
|
69
71
|
}
|
|
72
|
+
function findPopulateEntry(populate, parts) {
|
|
73
|
+
let current = populate;
|
|
74
|
+
for (let i = 0; i < parts.length; i++) {
|
|
75
|
+
const entry = current.find(p => p.field.split(':')[0] === parts[i]);
|
|
76
|
+
if (!entry) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
if (i === parts.length - 1) {
|
|
80
|
+
return entry;
|
|
81
|
+
}
|
|
82
|
+
current = (entry.children ?? []);
|
|
83
|
+
}
|
|
84
|
+
/* v8 ignore next */
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
70
87
|
/**
|
|
71
88
|
* Applies per-relation overrides from `populateHints` to the normalized populate tree.
|
|
72
89
|
* @internal
|
|
@@ -85,18 +102,3 @@ export function applyPopulateHints(populate, hints) {
|
|
|
85
102
|
}
|
|
86
103
|
}
|
|
87
104
|
}
|
|
88
|
-
function findPopulateEntry(populate, parts) {
|
|
89
|
-
let current = populate;
|
|
90
|
-
for (let i = 0; i < parts.length; i++) {
|
|
91
|
-
const entry = current.find(p => p.field.split(':')[0] === parts[i]);
|
|
92
|
-
if (!entry) {
|
|
93
|
-
return undefined;
|
|
94
|
-
}
|
|
95
|
-
if (i === parts.length - 1) {
|
|
96
|
-
return entry;
|
|
97
|
-
}
|
|
98
|
-
current = (entry.children ?? []);
|
|
99
|
-
}
|
|
100
|
-
/* v8 ignore next */
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
package/entity/validators.js
CHANGED
|
@@ -52,7 +52,8 @@ export function validateParams(params, type = 'search condition', field) {
|
|
|
52
52
|
}
|
|
53
53
|
/** @internal */
|
|
54
54
|
export function validatePrimaryKey(entity, meta) {
|
|
55
|
-
const pkExists = meta.primaryKeys.every(pk => entity[pk] != null) ||
|
|
55
|
+
const pkExists = meta.primaryKeys.every(pk => entity[pk] != null) ||
|
|
56
|
+
(meta.serializedPrimaryKey && entity[meta.serializedPrimaryKey] != null);
|
|
56
57
|
if (!entity || !pkExists) {
|
|
57
58
|
throw ValidationError.fromMergeWithoutPK(meta);
|
|
58
59
|
}
|
package/enums.js
CHANGED
|
@@ -49,22 +49,8 @@ export var QueryOperator;
|
|
|
49
49
|
QueryOperator["$hasKeys"] = "?&";
|
|
50
50
|
QueryOperator["$hasSomeKeys"] = "?|";
|
|
51
51
|
})(QueryOperator || (QueryOperator = {}));
|
|
52
|
-
export const ARRAY_OPERATORS = [
|
|
53
|
-
|
|
54
|
-
'$gt',
|
|
55
|
-
'$gte',
|
|
56
|
-
'$lt',
|
|
57
|
-
'$lte',
|
|
58
|
-
'$ne',
|
|
59
|
-
'$overlap',
|
|
60
|
-
'$contains',
|
|
61
|
-
'$contained',
|
|
62
|
-
];
|
|
63
|
-
export const JSON_KEY_OPERATORS = [
|
|
64
|
-
'$hasKey',
|
|
65
|
-
'$hasKeys',
|
|
66
|
-
'$hasSomeKeys',
|
|
67
|
-
];
|
|
52
|
+
export const ARRAY_OPERATORS = ['$eq', '$gt', '$gte', '$lt', '$lte', '$ne', '$overlap', '$contains', '$contained'];
|
|
53
|
+
export const JSON_KEY_OPERATORS = ['$hasKey', '$hasKeys', '$hasSomeKeys'];
|
|
68
54
|
export var QueryOrder;
|
|
69
55
|
(function (QueryOrder) {
|
|
70
56
|
QueryOrder["ASC"] = "ASC";
|
|
@@ -100,7 +86,16 @@ export var QueryFlag;
|
|
|
100
86
|
QueryFlag["IDENTITY_INSERT"] = "IDENTITY_INSERT";
|
|
101
87
|
QueryFlag["OUTPUT_TABLE"] = "OUTPUT_TABLE";
|
|
102
88
|
})(QueryFlag || (QueryFlag = {}));
|
|
103
|
-
export const SCALAR_TYPES = new Set([
|
|
89
|
+
export const SCALAR_TYPES = new Set([
|
|
90
|
+
'string',
|
|
91
|
+
'number',
|
|
92
|
+
'boolean',
|
|
93
|
+
'bigint',
|
|
94
|
+
'Uint8Array',
|
|
95
|
+
'Date',
|
|
96
|
+
'Buffer',
|
|
97
|
+
'RegExp',
|
|
98
|
+
]);
|
|
104
99
|
export var ReferenceKind;
|
|
105
100
|
(function (ReferenceKind) {
|
|
106
101
|
ReferenceKind["SCALAR"] = "scalar";
|
package/errors.js
CHANGED
|
@@ -34,12 +34,19 @@ export class ValidationError extends Error {
|
|
|
34
34
|
return new ValidationError(`Entity ${entity.constructor.name} is not managed. An entity is managed if its fetched from the database or registered as new through EntityManager.persist()`);
|
|
35
35
|
}
|
|
36
36
|
static notEntity(owner, prop, data) {
|
|
37
|
-
const type = Object.prototype.toString
|
|
37
|
+
const type = Object.prototype.toString
|
|
38
|
+
.call(data)
|
|
39
|
+
.match(/\[object (\w+)]/)[1]
|
|
40
|
+
.toLowerCase();
|
|
38
41
|
return new ValidationError(`Entity of type ${prop.type} expected for property ${owner.constructor.name}.${prop.name}, ${inspect(data)} of type ${type} given. If you are using Object.assign(entity, data), use em.assign(entity, data) instead.`);
|
|
39
42
|
}
|
|
40
43
|
static notDiscoveredEntity(data, meta, action = 'persist') {
|
|
41
44
|
/* v8 ignore next */
|
|
42
|
-
const type = meta?.className ??
|
|
45
|
+
const type = meta?.className ??
|
|
46
|
+
Object.prototype.toString
|
|
47
|
+
.call(data)
|
|
48
|
+
.match(/\[object (\w+)]/)[1]
|
|
49
|
+
.toLowerCase();
|
|
43
50
|
let err = `Trying to ${action} not discovered entity of type ${type}.`;
|
|
44
51
|
if (meta) {
|
|
45
52
|
err += ` Entity with this name was discovered, but not the prototype you are passing to the ORM. If using EntitySchema, be sure to point to the implementation via \`class\`.`;
|
|
@@ -56,7 +63,10 @@ export class ValidationError extends Error {
|
|
|
56
63
|
return new ValidationError(`Invalid enum array items provided in ${entityName}: ${inspect(invalid)}`);
|
|
57
64
|
}
|
|
58
65
|
static invalidType(type, value, mode) {
|
|
59
|
-
const valueType = Object.prototype.toString
|
|
66
|
+
const valueType = Object.prototype.toString
|
|
67
|
+
.call(value)
|
|
68
|
+
.match(/\[object (\w+)]/)[1]
|
|
69
|
+
.toLowerCase();
|
|
60
70
|
if (value instanceof Date) {
|
|
61
71
|
value = value.toISOString();
|
|
62
72
|
}
|
|
@@ -69,8 +79,8 @@ export class ValidationError extends Error {
|
|
|
69
79
|
static cannotModifyInverseCollection(owner, property) {
|
|
70
80
|
const inverseCollection = `${owner.constructor.name}.${property.name}`;
|
|
71
81
|
const ownerCollection = `${property.type}.${property.mappedBy}`;
|
|
72
|
-
const error = `You cannot modify inverse side of M:N collection ${inverseCollection} when the owning side is not initialized. `
|
|
73
|
-
|
|
82
|
+
const error = `You cannot modify inverse side of M:N collection ${inverseCollection} when the owning side is not initialized. ` +
|
|
83
|
+
`Consider working with the owning side instead (${ownerCollection}).`;
|
|
74
84
|
return new ValidationError(error, owner);
|
|
75
85
|
}
|
|
76
86
|
static cannotModifyReadonlyCollection(owner, property) {
|
|
@@ -79,7 +89,7 @@ export class ValidationError extends Error {
|
|
|
79
89
|
static cannotRemoveFromCollectionWithoutOrphanRemoval(owner, property) {
|
|
80
90
|
const options = [
|
|
81
91
|
' - add `orphanRemoval: true` to the collection options',
|
|
82
|
-
|
|
92
|
+
" - add `deleteRule: 'cascade'` to the owning side options",
|
|
83
93
|
' - add `nullable: true` to the owning side options',
|
|
84
94
|
].join('\n');
|
|
85
95
|
return new ValidationError(`Removing items from collection ${owner.constructor.name}.${property.name} without \`orphanRemoval: true\` would break non-null constraint on the owning side. You have several options: \n${options}`, owner);
|
|
@@ -91,7 +101,7 @@ export class ValidationError extends Error {
|
|
|
91
101
|
return new ValidationError('You cannot call em.flush() from inside lifecycle hook handlers');
|
|
92
102
|
}
|
|
93
103
|
static cannotUseGlobalContext() {
|
|
94
|
-
return new ValidationError(
|
|
104
|
+
return new ValidationError("Using global EntityManager instance methods for context specific actions is disallowed. If you need to work with the global instance's identity map, use `allowGlobalContext` configuration option or `fork()` instead.");
|
|
95
105
|
}
|
|
96
106
|
static cannotUseOperatorsInsideEmbeddables(entityName, propName, payload) {
|
|
97
107
|
return new ValidationError(`Using operators inside embeddables is not allowed, move the operator above. (property: ${Utils.className(entityName)}.${propName}, payload: ${inspect(payload)})`);
|
|
@@ -164,7 +174,7 @@ export class MetadataError extends ValidationError {
|
|
|
164
174
|
return new MetadataError(`Entity ${meta.className} has wrong ${type} definition: '${prop}' does not exist. You need to use property name, not column name.`);
|
|
165
175
|
}
|
|
166
176
|
static multipleVersionFields(meta, fields) {
|
|
167
|
-
return new MetadataError(`Entity ${meta.className} has multiple version properties defined: '${fields.join('
|
|
177
|
+
return new MetadataError(`Entity ${meta.className} has multiple version properties defined: '${fields.join("', '")}'. Only one version property is allowed per entity.`);
|
|
168
178
|
}
|
|
169
179
|
static invalidVersionFieldType(meta) {
|
|
170
180
|
const prop = meta.properties[meta.versionProperty];
|
package/events/EventManager.js
CHANGED
|
@@ -35,7 +35,7 @@ export class EventManager {
|
|
|
35
35
|
const hooks = (meta?.hooks[event] || []);
|
|
36
36
|
listeners.push(...hooks.map(hook => {
|
|
37
37
|
const prototypeHook = meta?.prototype[hook];
|
|
38
|
-
const handler = typeof hook === 'function' ? hook : entity[hook] ?? prototypeHook;
|
|
38
|
+
const handler = typeof hook === 'function' ? hook : (entity[hook] ?? prototypeHook);
|
|
39
39
|
return handler.bind(entity);
|
|
40
40
|
}));
|
|
41
41
|
for (const listener of this.listeners[event] ?? new Set()) {
|
package/exceptions.js
CHANGED
|
@@ -9,10 +9,15 @@ export class DriverException extends Error {
|
|
|
9
9
|
errmsg;
|
|
10
10
|
constructor(previous) {
|
|
11
11
|
super(previous.message);
|
|
12
|
-
Object.getOwnPropertyNames(previous).forEach(k => this[k] = previous[k]);
|
|
12
|
+
Object.getOwnPropertyNames(previous).forEach(k => (this[k] = previous[k]));
|
|
13
13
|
this.name = this.constructor.name;
|
|
14
14
|
Error.captureStackTrace(this, this.constructor);
|
|
15
|
-
this.stack +=
|
|
15
|
+
this.stack +=
|
|
16
|
+
'\n\n' +
|
|
17
|
+
previous
|
|
18
|
+
.stack.split('\n')
|
|
19
|
+
.filter(l => l.trim().startsWith('at '))
|
|
20
|
+
.join('\n');
|
|
16
21
|
}
|
|
17
22
|
}
|
|
18
23
|
/**
|
|
@@ -66,7 +66,10 @@ export class ObjectHydrator extends Hydrator {
|
|
|
66
66
|
const hydrateScalar = (prop, path, dataKey) => {
|
|
67
67
|
const entityKey = path.map(k => this.wrap(k)).join('');
|
|
68
68
|
const tz = this.platform.getTimezone();
|
|
69
|
-
const convertorKey = path
|
|
69
|
+
const convertorKey = path
|
|
70
|
+
.filter(k => !k.match(/\[idx_\d+]/))
|
|
71
|
+
.map(k => this.safeKey(k))
|
|
72
|
+
.join('_');
|
|
70
73
|
const ret = [];
|
|
71
74
|
const idx = this.tmpIndex++;
|
|
72
75
|
const nullVal = this.config.get('forceUndefined') ? 'undefined' : 'null';
|
|
@@ -139,7 +142,9 @@ export class ObjectHydrator extends Hydrator {
|
|
|
139
142
|
ret.push(` if (data${dataKey} === null) {\n entity${entityKey} = ${nullVal};`);
|
|
140
143
|
ret.push(` } else if (typeof data${dataKey} !== 'undefined') {`);
|
|
141
144
|
// For polymorphic: instanceof check; for regular: isPrimaryKey() check
|
|
142
|
-
const pkCheck = prop.polymorphic
|
|
145
|
+
const pkCheck = prop.polymorphic
|
|
146
|
+
? `data${dataKey} instanceof PolymorphicRef`
|
|
147
|
+
: `isPrimaryKey(data${dataKey}, true)`;
|
|
143
148
|
ret.push(` if (${pkCheck}) {`);
|
|
144
149
|
// When targetKey is set, pass the key option to createReference so it uses the alternate key
|
|
145
150
|
const keyOption = prop.targetKey ? `, key: '${prop.targetKey}'` : '';
|
|
@@ -232,7 +237,10 @@ export class ObjectHydrator extends Hydrator {
|
|
|
232
237
|
return ret;
|
|
233
238
|
};
|
|
234
239
|
const registerEmbeddedPrototype = (prop, path) => {
|
|
235
|
-
const convertorKey = path
|
|
240
|
+
const convertorKey = path
|
|
241
|
+
.filter(k => !k.match(/\[idx_\d+]/))
|
|
242
|
+
.map(k => this.safeKey(k))
|
|
243
|
+
.join('_');
|
|
236
244
|
if (prop.targetMeta?.polymorphs) {
|
|
237
245
|
prop.targetMeta.polymorphs.forEach(meta => {
|
|
238
246
|
context.set(`prototype_${convertorKey}_${meta.className}`, meta.prototype);
|
|
@@ -297,7 +305,9 @@ export class ObjectHydrator extends Hydrator {
|
|
|
297
305
|
meta.props
|
|
298
306
|
.filter(p => p.embedded?.[0] === prop.name)
|
|
299
307
|
.forEach(childProp => {
|
|
300
|
-
const childDataKey = prop.object
|
|
308
|
+
const childDataKey = prop.object
|
|
309
|
+
? dataKey + this.wrap(childProp.embedded[1])
|
|
310
|
+
: this.wrap(childProp.name);
|
|
301
311
|
const prop2 = childMeta.properties[childProp.embedded[1]];
|
|
302
312
|
const prop3 = {
|
|
303
313
|
...prop2,
|
|
@@ -305,8 +315,9 @@ export class ObjectHydrator extends Hydrator {
|
|
|
305
315
|
embedded: childProp.embedded,
|
|
306
316
|
embeddedProps: childProp.embeddedProps,
|
|
307
317
|
};
|
|
308
|
-
|
|
309
|
-
|
|
318
|
+
ret.push(
|
|
319
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define, no-use-before-define
|
|
320
|
+
...hydrateProperty(prop3, childProp.object, [...path, childProp.embedded[1]], childDataKey).map(l => ' ' + l));
|
|
310
321
|
});
|
|
311
322
|
ret.push(` }`);
|
|
312
323
|
});
|
|
@@ -321,8 +332,9 @@ export class ObjectHydrator extends Hydrator {
|
|
|
321
332
|
.filter(p => p.embedded?.[0] === prop.name)
|
|
322
333
|
.forEach(childProp => {
|
|
323
334
|
const childDataKey = prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
|
|
324
|
-
|
|
325
|
-
|
|
335
|
+
ret.push(
|
|
336
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define, no-use-before-define
|
|
337
|
+
...hydrateProperty(childProp, prop.object, [...path, childProp.embedded[1]], childDataKey).map(l => ' ' + l));
|
|
326
338
|
});
|
|
327
339
|
}
|
|
328
340
|
/* v8 ignore next */
|
|
@@ -353,7 +365,8 @@ export class ObjectHydrator extends Hydrator {
|
|
|
353
365
|
};
|
|
354
366
|
const hydrateProperty = (prop, object = prop.object, path = [prop.name], dataKey) => {
|
|
355
367
|
const entityKey = path.map(k => this.wrap(k)).join('');
|
|
356
|
-
dataKey =
|
|
368
|
+
dataKey =
|
|
369
|
+
dataKey ?? (object ? entityKey : this.wrap(normalizeAccessors ? (prop.accessor ?? prop.name) : prop.name));
|
|
357
370
|
const ret = [];
|
|
358
371
|
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && !prop.mapToPk) {
|
|
359
372
|
ret.push(...hydrateToOne(prop, dataKey, entityKey));
|
|
@@ -372,7 +385,8 @@ export class ObjectHydrator extends Hydrator {
|
|
|
372
385
|
}
|
|
373
386
|
}
|
|
374
387
|
}
|
|
375
|
-
else {
|
|
388
|
+
else {
|
|
389
|
+
// ReferenceKind.SCALAR
|
|
376
390
|
ret.push(...hydrateScalar(prop, path, dataKey));
|
|
377
391
|
}
|
|
378
392
|
if (this.config.get('forceUndefined')) {
|
|
@@ -383,9 +397,9 @@ export class ObjectHydrator extends Hydrator {
|
|
|
383
397
|
for (const prop of props) {
|
|
384
398
|
lines.push(...hydrateProperty(prop));
|
|
385
399
|
}
|
|
386
|
-
const code = `// compiled hydrator for entity ${meta.className} (${type + normalizeAccessors ? ' normalized' : ''})\n`
|
|
387
|
-
|
|
388
|
-
|
|
400
|
+
const code = `// compiled hydrator for entity ${meta.className} (${type + normalizeAccessors ? ' normalized' : ''})\n` +
|
|
401
|
+
`return function(entity, data, factory, newEntity, convertCustomTypes, schema, parentSchema, normalizeAccessors) {\n` +
|
|
402
|
+
`${lines.join('\n')}\n}`;
|
|
389
403
|
const fnKey = `hydrator-${meta.uniqueName}-${type}-${normalizeAccessors}`;
|
|
390
404
|
const hydrator = Utils.createFunction(context, code, this.config.get('compiledFunctions'), fnKey);
|
|
391
405
|
this.hydrators[key].set(meta.class, hydrator);
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module core
|
|
4
4
|
*/
|
|
5
|
-
export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName } from './typings.js';
|
|
5
|
+
export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, } from './typings.js';
|
|
6
6
|
export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, IndexCallback, FormulaCallback, FormulaTable, SchemaTable, SchemaColumns, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
|
|
7
7
|
export * from './enums.js';
|
|
8
8
|
export * from './errors.js';
|
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module core
|
|
4
4
|
*/
|
|
5
|
-
export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName } from './typings.js';
|
|
5
|
+
export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, } from './typings.js';
|
|
6
6
|
export * from './enums.js';
|
|
7
7
|
export * from './errors.js';
|
|
8
8
|
export * from './exceptions.js';
|
package/logging/DefaultLogger.js
CHANGED
|
@@ -29,9 +29,7 @@ export class DefaultLogger {
|
|
|
29
29
|
if (context?.level === 'warning') {
|
|
30
30
|
message = colors.yellow(message);
|
|
31
31
|
}
|
|
32
|
-
const label = context?.label
|
|
33
|
-
? colors.cyan(`(${context.label}) `)
|
|
34
|
-
: '';
|
|
32
|
+
const label = context?.label ? colors.cyan(`(${context.label}) `) : '';
|
|
35
33
|
this.writer(colors.grey(`[${namespace}] `) + label + message);
|
|
36
34
|
}
|
|
37
35
|
/**
|
|
@@ -60,8 +58,8 @@ export class DefaultLogger {
|
|
|
60
58
|
if (namespace === 'deprecated') {
|
|
61
59
|
const { ignoreDeprecations = false } = this.options;
|
|
62
60
|
return Array.isArray(ignoreDeprecations)
|
|
63
|
-
/* v8 ignore next */
|
|
64
|
-
|
|
61
|
+
? /* v8 ignore next */
|
|
62
|
+
!ignoreDeprecations.includes(context?.label ?? '')
|
|
65
63
|
: !ignoreDeprecations;
|
|
66
64
|
}
|
|
67
65
|
return !!debugMode && (!Array.isArray(debugMode) || debugMode.includes(namespace));
|
package/logging/colors.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { getEnv } from '../utils/env-vars.js';
|
|
2
2
|
const bool = (k) => ['true', 't', '1'].includes(getEnv(k)?.toLowerCase() ?? '');
|
|
3
|
-
const boolIfDefined = (k) => getEnv(k) != null ? bool(k) : true;
|
|
4
|
-
const enabled = () => !bool('NO_COLOR')
|
|
5
|
-
|
|
6
|
-
&& boolIfDefined('FORCE_COLOR')
|
|
7
|
-
&& boolIfDefined('MIKRO_ORM_COLORS');
|
|
8
|
-
const wrap = (fn) => (text) => enabled() ? fn(text) : text;
|
|
3
|
+
const boolIfDefined = (k) => (getEnv(k) != null ? bool(k) : true);
|
|
4
|
+
const enabled = () => !bool('NO_COLOR') && !bool('MIKRO_ORM_NO_COLOR') && boolIfDefined('FORCE_COLOR') && boolIfDefined('MIKRO_ORM_COLORS');
|
|
5
|
+
const wrap = (fn) => (text) => (enabled() ? fn(text) : text);
|
|
9
6
|
/** @internal */
|
|
10
7
|
export const colors = {
|
|
11
8
|
red: wrap((text) => `\x1B[31m${text}\x1B[39m`),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EntityMetadata, type AnyEntity, type EntityKey, type Constructor, type DeepPartial, type EntityName, type EntityProperty, type CleanKeys, type ExpandProperty, type IsNever, type EntityCtor } from '../typings.js';
|
|
2
2
|
import { type EventType, ReferenceKind } from '../enums.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { EventArgs } from '../events/EventSubscriber.js';
|
|
4
4
|
import { Type } from '../types/Type.js';
|
|
5
5
|
import type { PropertyOptions, ManyToOneOptions, OneToOneOptions, OneToManyOptions, ManyToManyOptions, EmbeddedOptions, EnumOptions, PrimaryKeyOptions, SerializedPrimaryKeyOptions, IndexOptions, UniqueOptions } from './types.js';
|
|
6
6
|
type TypeType = string | NumberConstructor | StringConstructor | BooleanConstructor | DateConstructor | ArrayConstructor | Constructor<Type<any>> | Type<any>;
|
|
@@ -108,6 +108,6 @@ export declare class EntitySchema<Entity = any, Base = never, Class extends Enti
|
|
|
108
108
|
* });
|
|
109
109
|
* ```
|
|
110
110
|
*/
|
|
111
|
-
addHook<
|
|
111
|
+
addHook<T extends Entity = Entity>(event: EventType | `${EventType}`, handler: (args: EventArgs<T>) => void | Promise<void>): this;
|
|
112
112
|
}
|
|
113
113
|
export {};
|
package/metadata/EntitySchema.js
CHANGED
|
@@ -34,7 +34,12 @@ export class EntitySchema {
|
|
|
34
34
|
}
|
|
35
35
|
addProperty(name, type, options = {}) {
|
|
36
36
|
this.renameCompositeOptions(name, options);
|
|
37
|
-
const prop = {
|
|
37
|
+
const prop = {
|
|
38
|
+
name,
|
|
39
|
+
kind: ReferenceKind.SCALAR,
|
|
40
|
+
...options,
|
|
41
|
+
...this.normalizeType(options, type),
|
|
42
|
+
};
|
|
38
43
|
if (type && Type.isMappedType(type.prototype)) {
|
|
39
44
|
prop.type = type;
|
|
40
45
|
}
|
|
@@ -299,7 +304,12 @@ export class EntitySchema {
|
|
|
299
304
|
}
|
|
300
305
|
else if (options.entity) {
|
|
301
306
|
const tmp = options.entity();
|
|
302
|
-
type = options.type = Array.isArray(tmp)
|
|
307
|
+
type = options.type = Array.isArray(tmp)
|
|
308
|
+
? tmp
|
|
309
|
+
.map(t => Utils.className(t))
|
|
310
|
+
.sort()
|
|
311
|
+
.join(' | ')
|
|
312
|
+
: Utils.className(tmp);
|
|
303
313
|
const target = tmp instanceof EntitySchema ? tmp.meta.class : tmp;
|
|
304
314
|
return { type, target };
|
|
305
315
|
}
|