@mikro-orm/core 6.4.17-dev.9 → 6.4.17-dev.91
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 +11 -2
- package/EntityManager.js +37 -22
- package/README.md +1 -2
- package/connections/Connection.d.ts +4 -2
- package/connections/Connection.js +2 -2
- package/decorators/Entity.d.ts +14 -0
- package/decorators/Indexed.d.ts +2 -2
- package/decorators/Transactional.d.ts +1 -0
- package/decorators/Transactional.js +3 -3
- package/drivers/IDatabaseDriver.d.ts +4 -0
- package/entity/ArrayCollection.d.ts +3 -1
- package/entity/ArrayCollection.js +7 -2
- package/entity/EntityFactory.d.ts +6 -0
- package/entity/EntityFactory.js +17 -6
- package/entity/EntityHelper.js +4 -1
- package/entity/EntityLoader.js +26 -18
- package/entity/Reference.d.ts +5 -0
- package/entity/Reference.js +16 -0
- package/entity/WrappedEntity.js +1 -1
- package/entity/defineEntity.d.ts +528 -0
- package/entity/defineEntity.js +684 -0
- package/entity/index.d.ts +2 -0
- package/entity/index.js +2 -0
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +16 -3
- package/enums.d.ts +3 -1
- package/enums.js +2 -0
- package/hydration/ObjectHydrator.js +1 -1
- package/index.d.ts +1 -1
- package/index.mjs +4 -0
- package/metadata/MetadataDiscovery.d.ts +0 -1
- package/metadata/MetadataDiscovery.js +16 -13
- package/package.json +4 -4
- package/platforms/Platform.d.ts +3 -1
- package/types/BooleanType.d.ts +1 -1
- package/types/DecimalType.js +1 -1
- package/types/DoubleType.js +1 -1
- package/typings.d.ts +18 -9
- package/typings.js +21 -4
- package/unit-of-work/ChangeSetPersister.d.ts +4 -2
- package/unit-of-work/ChangeSetPersister.js +14 -10
- package/unit-of-work/UnitOfWork.d.ts +1 -1
- package/unit-of-work/UnitOfWork.js +22 -6
- package/utils/Configuration.d.ts +7 -1
- package/utils/Configuration.js +1 -0
- package/utils/ConfigurationLoader.js +2 -2
- package/utils/Cursor.js +3 -0
- package/utils/EntityComparator.d.ts +6 -2
- package/utils/EntityComparator.js +29 -8
- package/utils/QueryHelper.d.ts +6 -0
- package/utils/QueryHelper.js +47 -4
- package/utils/RawQueryFragment.d.ts +34 -0
- package/utils/RawQueryFragment.js +35 -0
- package/utils/Utils.d.ts +2 -2
- package/utils/Utils.js +32 -8
- package/utils/upsert-utils.js +9 -1
package/entity/index.js
CHANGED
|
@@ -27,3 +27,5 @@ __exportStar(require("./Reference"), exports);
|
|
|
27
27
|
__exportStar(require("./BaseEntity"), exports);
|
|
28
28
|
__exportStar(require("./WrappedEntity"), exports);
|
|
29
29
|
__exportStar(require("./wrap"), exports);
|
|
30
|
+
__exportStar(require("./defineEntity"), exports);
|
|
31
|
+
__exportStar(require("./utils"), exports);
|
package/entity/utils.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { EntityMetadata, PopulateOptions } from '../typings';
|
|
2
|
+
import { LoadStrategy, ReferenceKind } from '../enums';
|
|
2
3
|
/**
|
|
3
4
|
* @internal
|
|
4
5
|
*/
|
|
5
6
|
export declare function expandDotPaths<Entity>(meta: EntityMetadata<Entity>, populate?: readonly (string | PopulateOptions<Entity>)[], normalized?: boolean): PopulateOptions<Entity>[];
|
|
7
|
+
/**
|
|
8
|
+
* Returns the loading strategy based on the provided hint.
|
|
9
|
+
* If `BALANCED` strategy is used, it will return JOINED if the property is a to-one relation.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function getLoadingStrategy(strategy: LoadStrategy | `${LoadStrategy}`, kind: ReferenceKind): LoadStrategy.SELECT_IN | LoadStrategy.JOINED;
|
package/entity/utils.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.expandDotPaths = expandDotPaths;
|
|
4
|
+
exports.getLoadingStrategy = getLoadingStrategy;
|
|
4
5
|
const enums_1 = require("../enums");
|
|
5
|
-
const
|
|
6
|
+
const Utils_1 = require("../utils/Utils");
|
|
6
7
|
/**
|
|
7
8
|
* Expands `books.perex` like populate to use `children` array instead of the dot syntax
|
|
8
9
|
*/
|
|
@@ -20,7 +21,7 @@ function expandNestedPopulate(parentProp, parts, strategy, all) {
|
|
|
20
21
|
* @internal
|
|
21
22
|
*/
|
|
22
23
|
function expandDotPaths(meta, populate, normalized = false) {
|
|
23
|
-
const ret = normalized ? populate :
|
|
24
|
+
const ret = normalized ? populate : Utils_1.Utils.asArray(populate).map(field => {
|
|
24
25
|
if (typeof field === 'string') {
|
|
25
26
|
return { field };
|
|
26
27
|
}
|
|
@@ -37,7 +38,6 @@ function expandDotPaths(meta, populate, normalized = false) {
|
|
|
37
38
|
p.field = f;
|
|
38
39
|
p.children ??= [];
|
|
39
40
|
const prop = meta.properties[p.field];
|
|
40
|
-
p.strategy ??= prop.strategy;
|
|
41
41
|
if (parts[0] === enums_1.PopulatePath.ALL) {
|
|
42
42
|
prop.targetMeta.props
|
|
43
43
|
.filter(prop => prop.lazy || prop.kind !== enums_1.ReferenceKind.SCALAR)
|
|
@@ -58,3 +58,16 @@ function expandDotPaths(meta, populate, normalized = false) {
|
|
|
58
58
|
}
|
|
59
59
|
return ret;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns the loading strategy based on the provided hint.
|
|
63
|
+
* If `BALANCED` strategy is used, it will return JOINED if the property is a to-one relation.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
function getLoadingStrategy(strategy, kind) {
|
|
67
|
+
if (strategy === enums_1.LoadStrategy.BALANCED) {
|
|
68
|
+
return [enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(kind)
|
|
69
|
+
? enums_1.LoadStrategy.JOINED
|
|
70
|
+
: enums_1.LoadStrategy.SELECT_IN;
|
|
71
|
+
}
|
|
72
|
+
return strategy;
|
|
73
|
+
}
|
package/enums.d.ts
CHANGED
|
@@ -85,6 +85,7 @@ export declare enum QueryFlag {
|
|
|
85
85
|
INCLUDE_LAZY_FORMULAS = "INCLUDE_LAZY_FORMULAS",
|
|
86
86
|
AUTO_JOIN_ONE_TO_ONE_OWNER = "AUTO_JOIN_ONE_TO_ONE_OWNER",
|
|
87
87
|
INFER_POPULATE = "INFER_POPULATE",
|
|
88
|
+
DISABLE_NESTED_INNER_JOIN = "DISABLE_NESTED_INNER_JOIN",
|
|
88
89
|
IDENTITY_INSERT = "IDENTITY_INSERT"
|
|
89
90
|
}
|
|
90
91
|
export declare const SCALAR_TYPES: string[];
|
|
@@ -108,7 +109,8 @@ export declare enum Cascade {
|
|
|
108
109
|
}
|
|
109
110
|
export declare enum LoadStrategy {
|
|
110
111
|
SELECT_IN = "select-in",
|
|
111
|
-
JOINED = "joined"
|
|
112
|
+
JOINED = "joined",
|
|
113
|
+
BALANCED = "balanced"
|
|
112
114
|
}
|
|
113
115
|
export declare enum DataloaderType {
|
|
114
116
|
NONE = 0,
|
package/enums.js
CHANGED
|
@@ -98,6 +98,7 @@ var QueryFlag;
|
|
|
98
98
|
QueryFlag["INCLUDE_LAZY_FORMULAS"] = "INCLUDE_LAZY_FORMULAS";
|
|
99
99
|
QueryFlag["AUTO_JOIN_ONE_TO_ONE_OWNER"] = "AUTO_JOIN_ONE_TO_ONE_OWNER";
|
|
100
100
|
QueryFlag["INFER_POPULATE"] = "INFER_POPULATE";
|
|
101
|
+
QueryFlag["DISABLE_NESTED_INNER_JOIN"] = "DISABLE_NESTED_INNER_JOIN";
|
|
101
102
|
QueryFlag["IDENTITY_INSERT"] = "IDENTITY_INSERT";
|
|
102
103
|
})(QueryFlag || (exports.QueryFlag = QueryFlag = {}));
|
|
103
104
|
exports.SCALAR_TYPES = ['string', 'number', 'boolean', 'bigint', 'Date', 'Buffer', 'RegExp'];
|
|
@@ -125,6 +126,7 @@ var LoadStrategy;
|
|
|
125
126
|
(function (LoadStrategy) {
|
|
126
127
|
LoadStrategy["SELECT_IN"] = "select-in";
|
|
127
128
|
LoadStrategy["JOINED"] = "joined";
|
|
129
|
+
LoadStrategy["BALANCED"] = "balanced";
|
|
128
130
|
})(LoadStrategy || (exports.LoadStrategy = LoadStrategy = {}));
|
|
129
131
|
var DataloaderType;
|
|
130
132
|
(function (DataloaderType) {
|
|
@@ -65,7 +65,7 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
65
65
|
const ret = [];
|
|
66
66
|
const idx = this.tmpIndex++;
|
|
67
67
|
const nullVal = this.config.get('forceUndefined') ? 'undefined' : 'null';
|
|
68
|
-
if (prop.getter && !prop.setter) {
|
|
68
|
+
if (prop.getter && !prop.setter && prop.persist === false) {
|
|
69
69
|
return [];
|
|
70
70
|
}
|
|
71
71
|
if (prop.ref) {
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module core
|
|
4
4
|
*/
|
|
5
|
-
export { Constructor, ConnectionType, Dictionary, PrimaryKeyProp, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, EntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, EntityMetadata, QBFilterQuery, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, EntityRepositoryType, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, MigrationDiff, GenerateOptions, FilterObject, IEntityGenerator, ISeedManager, EntityClassGroup, OptionalProps, EagerProps, HiddenProps, RequiredEntityData, CheckCallback, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, UmzugMigration, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, Opt, EntityType, FromEntityType, Selected, IsSubset, NoInfer, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, Hidden, FilterValue, MergeLoaded, MergeSelected, Config, DefineConfig, TypeConfig, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, } from './typings';
|
|
5
|
+
export { Constructor, ConnectionType, Dictionary, PrimaryKeyProp, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, EntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, EntityMetadata, QBFilterQuery, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, EntityRepositoryType, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, MigrationDiff, GenerateOptions, FilterObject, IEntityGenerator, ISeedManager, EntityClassGroup, OptionalProps, EagerProps, HiddenProps, RequiredEntityData, CheckCallback, IndexCallback, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, UmzugMigration, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, Opt, EntityType, FromEntityType, Selected, IsSubset, NoInfer, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, Hidden, FilterValue, MergeLoaded, MergeSelected, Config, DefineConfig, TypeConfig, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, } from './typings';
|
|
6
6
|
export * from './enums';
|
|
7
7
|
export * from './errors';
|
|
8
8
|
export * from './exceptions';
|
package/index.mjs
CHANGED
|
@@ -182,11 +182,15 @@ export const compareBuffers = mod.compareBuffers;
|
|
|
182
182
|
export const compareObjects = mod.compareObjects;
|
|
183
183
|
export const createSqlFunction = mod.createSqlFunction;
|
|
184
184
|
export const defineConfig = mod.defineConfig;
|
|
185
|
+
export const defineEntity = mod.defineEntity;
|
|
185
186
|
export const equals = mod.equals;
|
|
187
|
+
export const expandDotPaths = mod.expandDotPaths;
|
|
188
|
+
export const getLoadingStrategy = mod.getLoadingStrategy;
|
|
186
189
|
export const getOnConflictFields = mod.getOnConflictFields;
|
|
187
190
|
export const getOnConflictReturningFields = mod.getOnConflictReturningFields;
|
|
188
191
|
export const helper = mod.helper;
|
|
189
192
|
export const parseJsonSafe = mod.parseJsonSafe;
|
|
193
|
+
export const quote = mod.quote;
|
|
190
194
|
export const raw = mod.raw;
|
|
191
195
|
export const ref = mod.ref;
|
|
192
196
|
export const rel = mod.rel;
|
|
@@ -54,7 +54,6 @@ export declare class MetadataDiscovery {
|
|
|
54
54
|
private initAutoincrement;
|
|
55
55
|
private initCheckConstraints;
|
|
56
56
|
private initGeneratedColumn;
|
|
57
|
-
private createColumnMappingObject;
|
|
58
57
|
private getDefaultVersionValue;
|
|
59
58
|
private inferDefaultValue;
|
|
60
59
|
private initDefaultValue;
|
|
@@ -622,7 +622,7 @@ class MetadataDiscovery {
|
|
|
622
622
|
}
|
|
623
623
|
data.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.className, targetType + '_inverse', true, meta.className === targetType);
|
|
624
624
|
data.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetType, meta.name + '_owner', false, meta.className === targetType);
|
|
625
|
-
return this.metadata.set(data.className, data);
|
|
625
|
+
return this.metadata.set(data.className, EntitySchema_1.EntitySchema.fromMetadata(data).init().meta);
|
|
626
626
|
}
|
|
627
627
|
defineFixedOrderProperty(prop, targetType) {
|
|
628
628
|
const pk = prop.fixedOrderColumn || this.namingStrategy.referenceColumnName();
|
|
@@ -825,9 +825,16 @@ class MetadataDiscovery {
|
|
|
825
825
|
}
|
|
826
826
|
return prop.embedded ? isParentObject(meta.properties[prop.embedded[0]]) : false;
|
|
827
827
|
};
|
|
828
|
+
const isParentArray = (prop) => {
|
|
829
|
+
if (prop.array) {
|
|
830
|
+
return true;
|
|
831
|
+
}
|
|
832
|
+
return prop.embedded ? isParentArray(meta.properties[prop.embedded[0]]) : false;
|
|
833
|
+
};
|
|
828
834
|
const rootProperty = getRootProperty(embeddedProp);
|
|
829
835
|
const parentProperty = meta.properties[embeddedProp.embedded?.[0] ?? ''];
|
|
830
836
|
const object = isParentObject(embeddedProp);
|
|
837
|
+
const array = isParentArray(embeddedProp);
|
|
831
838
|
this.initFieldName(embeddedProp, rootProperty !== embeddedProp && object);
|
|
832
839
|
// the prefix of the parent cannot be a boolean; it already passed here
|
|
833
840
|
const prefix = this.getPrefix(embeddedProp, parentProperty);
|
|
@@ -840,7 +847,8 @@ class MetadataDiscovery {
|
|
|
840
847
|
meta.propertyOrder.set(name, (order += 0.01));
|
|
841
848
|
embeddedProp.embeddedProps[prop.name] = meta.properties[name];
|
|
842
849
|
meta.properties[name].persist ??= embeddedProp.persist;
|
|
843
|
-
|
|
850
|
+
const refInArray = array && [enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && prop.owner;
|
|
851
|
+
if (embeddedProp.nullable || refInArray) {
|
|
844
852
|
meta.properties[name].nullable = true;
|
|
845
853
|
}
|
|
846
854
|
if (meta.properties[name].fieldNames) {
|
|
@@ -969,7 +977,7 @@ class MetadataDiscovery {
|
|
|
969
977
|
}
|
|
970
978
|
}
|
|
971
979
|
initCheckConstraints(meta) {
|
|
972
|
-
const map =
|
|
980
|
+
const map = meta.createColumnMappingObject();
|
|
973
981
|
for (const check of meta.checks) {
|
|
974
982
|
const columns = check.property ? meta.properties[check.property].fieldNames : [];
|
|
975
983
|
check.name ??= this.namingStrategy.indexName(meta.tableName, columns, 'check');
|
|
@@ -992,19 +1000,11 @@ class MetadataDiscovery {
|
|
|
992
1000
|
}
|
|
993
1001
|
return;
|
|
994
1002
|
}
|
|
995
|
-
const map =
|
|
1003
|
+
const map = meta.createColumnMappingObject();
|
|
996
1004
|
if (prop.generated instanceof Function) {
|
|
997
1005
|
prop.generated = prop.generated(map);
|
|
998
1006
|
}
|
|
999
1007
|
}
|
|
1000
|
-
createColumnMappingObject(meta) {
|
|
1001
|
-
return Object.values(meta.properties).reduce((o, prop) => {
|
|
1002
|
-
if (prop.fieldNames) {
|
|
1003
|
-
o[prop.name] = prop.fieldNames[0];
|
|
1004
|
-
}
|
|
1005
|
-
return o;
|
|
1006
|
-
}, {});
|
|
1007
|
-
}
|
|
1008
1008
|
getDefaultVersionValue(meta, prop) {
|
|
1009
1009
|
if (typeof prop.defaultRaw !== 'undefined') {
|
|
1010
1010
|
return prop.defaultRaw;
|
|
@@ -1058,7 +1058,7 @@ class MetadataDiscovery {
|
|
|
1058
1058
|
prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
|
|
1059
1059
|
return;
|
|
1060
1060
|
}
|
|
1061
|
-
if (
|
|
1061
|
+
if (Array.isArray(prop.default) && prop.customType) {
|
|
1062
1062
|
val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
|
|
1063
1063
|
}
|
|
1064
1064
|
prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
|
|
@@ -1112,6 +1112,9 @@ class MetadataDiscovery {
|
|
|
1112
1112
|
if (prop.kind === enums_1.ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
|
|
1113
1113
|
prop.customType = new types_1.JsonType();
|
|
1114
1114
|
}
|
|
1115
|
+
if (prop.kind === enums_1.ReferenceKind.EMBEDDED && !prop.customType && (prop.object || prop.array)) {
|
|
1116
|
+
prop.customType = new types_1.JsonType();
|
|
1117
|
+
}
|
|
1115
1118
|
if (!prop.customType && prop.array && prop.items) {
|
|
1116
1119
|
prop.customType = new types_1.EnumArrayType(`${meta.className}.${prop.name}`, prop.items);
|
|
1117
1120
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "6.4.17-dev.
|
|
3
|
+
"version": "6.4.17-dev.91",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"dataloader": "2.2.3",
|
|
63
|
-
"dotenv": "
|
|
63
|
+
"dotenv": "17.2.1",
|
|
64
64
|
"esprima": "4.0.1",
|
|
65
|
-
"fs-extra": "11.3.
|
|
65
|
+
"fs-extra": "11.3.1",
|
|
66
66
|
"globby": "11.1.0",
|
|
67
|
-
"mikro-orm": "6.4.17-dev.
|
|
67
|
+
"mikro-orm": "6.4.17-dev.91",
|
|
68
68
|
"reflect-metadata": "0.2.2"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -173,7 +173,9 @@ export declare abstract class Platform {
|
|
|
173
173
|
getExtension<T>(extensionName: string, extensionKey: string, moduleName: string, em: EntityManager): T;
|
|
174
174
|
getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): ISchemaGenerator;
|
|
175
175
|
processDateProperty(value: unknown): string | number | Date;
|
|
176
|
-
quoteIdentifier(id: string
|
|
176
|
+
quoteIdentifier(id: string | {
|
|
177
|
+
toString: () => string;
|
|
178
|
+
}, quote?: string): string;
|
|
177
179
|
quoteValue(value: any): string;
|
|
178
180
|
escape(value: any): string;
|
|
179
181
|
formatQuery(sql: string, params: readonly any[]): string;
|
package/types/BooleanType.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Type } from './Type';
|
|
2
2
|
import type { Platform } from '../platforms';
|
|
3
3
|
import type { EntityProperty } from '../typings';
|
|
4
|
-
export declare class BooleanType extends Type<
|
|
4
|
+
export declare class BooleanType extends Type<boolean | null | undefined, boolean | null | undefined> {
|
|
5
5
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
6
6
|
compareAsType(): string;
|
|
7
7
|
ensureComparable(): boolean;
|
package/types/DecimalType.js
CHANGED
package/types/DoubleType.js
CHANGED
package/typings.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { SerializationContext, SerializeOptions } from './serialization';
|
|
|
6
6
|
import type { EntitySchema, MetadataStorage } from './metadata';
|
|
7
7
|
import type { Type, types } from './types';
|
|
8
8
|
import type { Platform } from './platforms';
|
|
9
|
-
import type { Configuration } from './utils';
|
|
9
|
+
import type { Configuration, RawQueryFragment } from './utils';
|
|
10
10
|
import type { EntityManager } from './EntityManager';
|
|
11
11
|
import type { EmbeddedPrefixMode } from './decorators/Embedded';
|
|
12
12
|
import type { EventSubscriber } from './events';
|
|
@@ -73,6 +73,7 @@ export type Primary<T> = IsAny<T> extends true ? any : T extends {
|
|
|
73
73
|
} ? ReadonlyPrimary<PK> : T extends {
|
|
74
74
|
id?: infer PK;
|
|
75
75
|
} ? ReadonlyPrimary<PK> : T;
|
|
76
|
+
/** @internal */
|
|
76
77
|
export type PrimaryProperty<T> = T extends {
|
|
77
78
|
[PrimaryKeyProp]?: infer PK;
|
|
78
79
|
} ? (PK extends keyof T ? PK : (PK extends any[] ? PK[number] : never)) : T extends {
|
|
@@ -287,8 +288,14 @@ export type EntityDTO<T, C extends TypeConfig = never> = {
|
|
|
287
288
|
} & {
|
|
288
289
|
[K in keyof T as DTOOptionalKeys<T, K>]?: EntityDTOProp<T, T[K], C> | AddOptional<T[K]>;
|
|
289
290
|
};
|
|
290
|
-
type
|
|
291
|
-
|
|
291
|
+
type PropertyName<T> = IsUnknown<T> extends false ? keyof T : string;
|
|
292
|
+
type TableName = {
|
|
293
|
+
name: string;
|
|
294
|
+
schema?: string;
|
|
295
|
+
toString: () => string;
|
|
296
|
+
};
|
|
297
|
+
export type IndexCallback<T> = (table: TableName, columns: Record<PropertyName<T>, string>) => string | RawQueryFragment;
|
|
298
|
+
export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>) => string;
|
|
292
299
|
export type GeneratedColumnCallback<T> = (columns: Record<keyof T, string>) => string;
|
|
293
300
|
export interface CheckConstraint<T = any> {
|
|
294
301
|
name?: string;
|
|
@@ -394,8 +401,9 @@ export declare class EntityMetadata<T = any> {
|
|
|
394
401
|
constructor(meta?: Partial<EntityMetadata>);
|
|
395
402
|
addProperty(prop: Partial<EntityProperty<T>>, sync?: boolean): void;
|
|
396
403
|
removeProperty(name: string, sync?: boolean): void;
|
|
397
|
-
getPrimaryProps(): EntityProperty<T>[];
|
|
404
|
+
getPrimaryProps(flatten?: boolean): EntityProperty<T>[];
|
|
398
405
|
getPrimaryProp(): EntityProperty<T>;
|
|
406
|
+
createColumnMappingObject(): Dictionary<any>;
|
|
399
407
|
get tableName(): string;
|
|
400
408
|
set tableName(name: string);
|
|
401
409
|
sync(initIndexes?: boolean): void;
|
|
@@ -447,18 +455,18 @@ export interface EntityMetadata<T = any> {
|
|
|
447
455
|
uniqueProps: EntityProperty<T>[];
|
|
448
456
|
getterProps: EntityProperty<T>[];
|
|
449
457
|
indexes: {
|
|
450
|
-
properties
|
|
458
|
+
properties?: EntityKey<T> | EntityKey<T>[];
|
|
451
459
|
name?: string;
|
|
452
460
|
type?: string;
|
|
453
461
|
options?: Dictionary;
|
|
454
|
-
expression?: string
|
|
462
|
+
expression?: string | IndexCallback<T>;
|
|
455
463
|
}[];
|
|
456
464
|
uniques: {
|
|
457
|
-
properties
|
|
465
|
+
properties?: EntityKey<T> | EntityKey<T>[];
|
|
458
466
|
name?: string;
|
|
459
467
|
options?: Dictionary;
|
|
460
|
-
expression?: string
|
|
461
|
-
deferMode?: DeferMode
|
|
468
|
+
expression?: string | IndexCallback<T>;
|
|
469
|
+
deferMode?: DeferMode | `${DeferMode}`;
|
|
462
470
|
}[];
|
|
463
471
|
checks: CheckConstraint<T>[];
|
|
464
472
|
repositoryClass?: string;
|
|
@@ -690,6 +698,7 @@ export type PopulateOptions<T> = {
|
|
|
690
698
|
strategy?: LoadStrategy;
|
|
691
699
|
all?: boolean;
|
|
692
700
|
filter?: boolean;
|
|
701
|
+
joinType?: 'inner join' | 'left join';
|
|
693
702
|
children?: PopulateOptions<T[keyof T]>[];
|
|
694
703
|
};
|
|
695
704
|
type Loadable<T extends object> = Collection<T, any> | Reference<T> | Ref<T> | readonly T[];
|
package/typings.js
CHANGED
|
@@ -47,12 +47,29 @@ class EntityMetadata {
|
|
|
47
47
|
this.sync();
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
getPrimaryProps() {
|
|
51
|
-
|
|
50
|
+
getPrimaryProps(flatten = false) {
|
|
51
|
+
const pks = this.primaryKeys.map(pk => this.properties[pk]);
|
|
52
|
+
if (flatten) {
|
|
53
|
+
return pks.flatMap(pk => {
|
|
54
|
+
if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(pk.kind)) {
|
|
55
|
+
return pk.targetMeta.getPrimaryProps(true);
|
|
56
|
+
}
|
|
57
|
+
return [pk];
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return pks;
|
|
52
61
|
}
|
|
53
62
|
getPrimaryProp() {
|
|
54
63
|
return this.properties[this.primaryKeys[0]];
|
|
55
64
|
}
|
|
65
|
+
createColumnMappingObject() {
|
|
66
|
+
return Object.values(this.properties).reduce((o, prop) => {
|
|
67
|
+
if (prop.fieldNames) {
|
|
68
|
+
o[prop.name] = prop.fieldNames[0];
|
|
69
|
+
}
|
|
70
|
+
return o;
|
|
71
|
+
}, {});
|
|
72
|
+
}
|
|
56
73
|
get tableName() {
|
|
57
74
|
return this.collection;
|
|
58
75
|
}
|
|
@@ -72,7 +89,7 @@ class EntityMetadata {
|
|
|
72
89
|
// `prop.userDefined` is either `undefined` or `false`
|
|
73
90
|
const discriminator = this.root.discriminatorColumn === prop.name && prop.userDefined === false;
|
|
74
91
|
// even if we don't have a setter, do not ignore value from database!
|
|
75
|
-
const onlyGetter = prop.getter && !prop.setter;
|
|
92
|
+
const onlyGetter = prop.getter && !prop.setter && prop.persist === false;
|
|
76
93
|
return !prop.inherited && prop.hydrate !== false && !discriminator && !prop.embedded && !onlyGetter;
|
|
77
94
|
});
|
|
78
95
|
this.trackingProps = this.hydrateProps
|
|
@@ -115,7 +132,7 @@ class EntityMetadata {
|
|
|
115
132
|
wrapped.__data[prop.name] = entity_1.Reference.wrapReference(val, prop);
|
|
116
133
|
// when propagation from inside hydration, we set the FK to the entity data immediately
|
|
117
134
|
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
118
|
-
wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(val, prop.targetMeta
|
|
135
|
+
wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(val, prop.targetMeta, true);
|
|
119
136
|
}
|
|
120
137
|
else {
|
|
121
138
|
wrapped.__touched = !hydrator.isRunning();
|
|
@@ -4,6 +4,7 @@ import { type EntityFactory, type EntityValidator } from '../entity';
|
|
|
4
4
|
import { type ChangeSet } from './ChangeSet';
|
|
5
5
|
import { type Configuration } from '../utils';
|
|
6
6
|
import type { DriverMethodOptions, IDatabaseDriver } from '../drivers';
|
|
7
|
+
import type { EntityManager } from '../EntityManager';
|
|
7
8
|
export declare class ChangeSetPersister {
|
|
8
9
|
private readonly driver;
|
|
9
10
|
private readonly metadata;
|
|
@@ -11,10 +12,11 @@ export declare class ChangeSetPersister {
|
|
|
11
12
|
private readonly factory;
|
|
12
13
|
private readonly validator;
|
|
13
14
|
private readonly config;
|
|
15
|
+
private readonly em;
|
|
14
16
|
private readonly platform;
|
|
15
17
|
private readonly comparator;
|
|
16
18
|
private readonly usesReturningStatement;
|
|
17
|
-
constructor(driver: IDatabaseDriver, metadata: MetadataStorage, hydrator: IHydrator, factory: EntityFactory, validator: EntityValidator, config: Configuration);
|
|
19
|
+
constructor(driver: IDatabaseDriver, metadata: MetadataStorage, hydrator: IHydrator, factory: EntityFactory, validator: EntityValidator, config: Configuration, em: EntityManager);
|
|
18
20
|
executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
19
21
|
executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
20
22
|
executeDeletes<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
@@ -22,7 +24,7 @@ export declare class ChangeSetPersister {
|
|
|
22
24
|
private processProperties;
|
|
23
25
|
private persistNewEntity;
|
|
24
26
|
private persistNewEntities;
|
|
25
|
-
private
|
|
27
|
+
private prepareOptions;
|
|
26
28
|
private persistNewEntitiesBatch;
|
|
27
29
|
private persistManagedEntity;
|
|
28
30
|
private persistManagedEntities;
|
|
@@ -13,16 +13,18 @@ class ChangeSetPersister {
|
|
|
13
13
|
factory;
|
|
14
14
|
validator;
|
|
15
15
|
config;
|
|
16
|
+
em;
|
|
16
17
|
platform;
|
|
17
18
|
comparator;
|
|
18
19
|
usesReturningStatement;
|
|
19
|
-
constructor(driver, metadata, hydrator, factory, validator, config) {
|
|
20
|
+
constructor(driver, metadata, hydrator, factory, validator, config, em) {
|
|
20
21
|
this.driver = driver;
|
|
21
22
|
this.metadata = metadata;
|
|
22
23
|
this.hydrator = hydrator;
|
|
23
24
|
this.factory = factory;
|
|
24
25
|
this.validator = validator;
|
|
25
26
|
this.config = config;
|
|
27
|
+
this.em = em;
|
|
26
28
|
this.platform = this.driver.getPlatform();
|
|
27
29
|
this.comparator = this.config.getComparator(this.metadata);
|
|
28
30
|
this.usesReturningStatement = this.platform.usesReturningStatement() || this.platform.usesOutputStatement();
|
|
@@ -63,7 +65,7 @@ class ChangeSetPersister {
|
|
|
63
65
|
for (let i = 0; i < changeSets.length; i += size) {
|
|
64
66
|
const chunk = changeSets.slice(i, i + size);
|
|
65
67
|
const pks = chunk.map(cs => cs.getPrimaryKey());
|
|
66
|
-
options = this.
|
|
68
|
+
options = this.prepareOptions(meta, options);
|
|
67
69
|
await this.driver.nativeDelete(meta.root.className, { [pk]: { $in: pks } }, options);
|
|
68
70
|
}
|
|
69
71
|
}
|
|
@@ -91,7 +93,7 @@ class ChangeSetPersister {
|
|
|
91
93
|
}
|
|
92
94
|
async persistNewEntity(meta, changeSet, options) {
|
|
93
95
|
const wrapped = (0, entity_1.helper)(changeSet.entity);
|
|
94
|
-
options = this.
|
|
96
|
+
options = this.prepareOptions(meta, options, {
|
|
95
97
|
convertCustomTypes: false,
|
|
96
98
|
});
|
|
97
99
|
const res = await this.driver.nativeInsertMany(meta.className, [changeSet.payload], options);
|
|
@@ -117,15 +119,17 @@ class ChangeSetPersister {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
|
-
|
|
122
|
+
prepareOptions(meta, options, additionalOptions) {
|
|
123
|
+
const loggerContext = utils_1.Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
121
124
|
return {
|
|
122
125
|
...options,
|
|
123
126
|
...additionalOptions,
|
|
124
127
|
schema: options?.schema ?? meta.schema,
|
|
128
|
+
loggerContext,
|
|
125
129
|
};
|
|
126
130
|
}
|
|
127
131
|
async persistNewEntitiesBatch(meta, changeSets, options) {
|
|
128
|
-
options = this.
|
|
132
|
+
options = this.prepareOptions(meta, options, {
|
|
129
133
|
convertCustomTypes: false,
|
|
130
134
|
processCollections: false,
|
|
131
135
|
});
|
|
@@ -176,7 +180,7 @@ class ChangeSetPersister {
|
|
|
176
180
|
}
|
|
177
181
|
async persistManagedEntitiesBatch(meta, changeSets, options) {
|
|
178
182
|
await this.checkOptimisticLocks(meta, changeSets, options);
|
|
179
|
-
options = this.
|
|
183
|
+
options = this.prepareOptions(meta, options, {
|
|
180
184
|
convertCustomTypes: false,
|
|
181
185
|
processCollections: false,
|
|
182
186
|
});
|
|
@@ -236,7 +240,7 @@ class ChangeSetPersister {
|
|
|
236
240
|
}
|
|
237
241
|
async updateEntity(meta, changeSet, options) {
|
|
238
242
|
const cond = changeSet.getPrimaryKey(true);
|
|
239
|
-
options = this.
|
|
243
|
+
options = this.prepareOptions(meta, options, {
|
|
240
244
|
convertCustomTypes: false,
|
|
241
245
|
});
|
|
242
246
|
if (meta.concurrencyCheckKeys.size === 0 && (!meta.versionProperty || changeSet.entity[meta.versionProperty] == null)) {
|
|
@@ -263,7 +267,7 @@ class ChangeSetPersister {
|
|
|
263
267
|
return cond;
|
|
264
268
|
});
|
|
265
269
|
const primaryKeys = meta.primaryKeys.concat(...meta.concurrencyCheckKeys);
|
|
266
|
-
options = this.
|
|
270
|
+
options = this.prepareOptions(meta, options, {
|
|
267
271
|
fields: primaryKeys,
|
|
268
272
|
});
|
|
269
273
|
const res = await this.driver.find(meta.root.className, { $or }, options);
|
|
@@ -322,12 +326,12 @@ class ChangeSetPersister {
|
|
|
322
326
|
}
|
|
323
327
|
return val;
|
|
324
328
|
});
|
|
325
|
-
options = this.
|
|
329
|
+
options = this.prepareOptions(meta, options, {
|
|
326
330
|
fields: utils_1.Utils.unique(reloadProps.map(prop => prop.name)),
|
|
327
331
|
});
|
|
328
332
|
const data = await this.driver.find(meta.className, { [pk]: { $in: pks } }, options);
|
|
329
333
|
const map = new Map();
|
|
330
|
-
data.forEach(item => map.set(utils_1.Utils.getCompositeKeyHash(item, meta,
|
|
334
|
+
data.forEach(item => map.set(utils_1.Utils.getCompositeKeyHash(item, meta, false, this.platform, true), item));
|
|
331
335
|
for (const changeSet of changeSets) {
|
|
332
336
|
const data = map.get((0, entity_1.helper)(changeSet.entity).getSerializedPrimaryKey());
|
|
333
337
|
this.hydrator.hydrate(changeSet.entity, meta, data, this.factory, 'full', false, true);
|
|
@@ -38,7 +38,7 @@ export declare class UnitOfWork {
|
|
|
38
38
|
/**
|
|
39
39
|
* Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
|
|
40
40
|
*/
|
|
41
|
-
getById<T extends object>(entityName: string, id: Primary<T> | Primary<T>[], schema?: string): T | undefined;
|
|
41
|
+
getById<T extends object>(entityName: string, id: Primary<T> | Primary<T>[], schema?: string, convertCustomTypes?: boolean): T | undefined;
|
|
42
42
|
tryGetById<T extends object>(entityName: string, where: FilterQuery<T>, schema?: string, strict?: boolean): T | null;
|
|
43
43
|
/**
|
|
44
44
|
* Returns map of all managed entities.
|
|
@@ -42,7 +42,7 @@ class UnitOfWork {
|
|
|
42
42
|
this.eventManager = this.em.getEventManager();
|
|
43
43
|
this.comparator = this.em.getComparator();
|
|
44
44
|
this.changeSetComputer = new ChangeSetComputer_1.ChangeSetComputer(this.em.getValidator(), this.collectionUpdates, this.metadata, this.platform, this.em.config, this.em);
|
|
45
|
-
this.changeSetPersister = new ChangeSetPersister_1.ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.getValidator(), this.em.config);
|
|
45
|
+
this.changeSetPersister = new ChangeSetPersister_1.ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.getValidator(), this.em.config, this.em);
|
|
46
46
|
}
|
|
47
47
|
merge(entity, visited) {
|
|
48
48
|
const wrapped = (0, entity_1.helper)(entity);
|
|
@@ -88,7 +88,7 @@ class UnitOfWork {
|
|
|
88
88
|
}
|
|
89
89
|
wrapped.__loadedProperties.add(key);
|
|
90
90
|
if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils_1.Utils.isPlainObject(data[prop.name])) {
|
|
91
|
-
data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta
|
|
91
|
+
data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
92
92
|
}
|
|
93
93
|
else if (prop.kind === enums_1.ReferenceKind.EMBEDDED && !prop.object && Utils_1.Utils.isPlainObject(data[prop.name])) {
|
|
94
94
|
for (const p of prop.targetMeta.props) {
|
|
@@ -96,7 +96,7 @@ class UnitOfWork {
|
|
|
96
96
|
const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
|
|
97
97
|
data[prefix + p.name] = data[prop.name][p.name];
|
|
98
98
|
}
|
|
99
|
-
data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta
|
|
99
|
+
data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
100
100
|
}
|
|
101
101
|
if (forceUndefined) {
|
|
102
102
|
if (data[key] === null) {
|
|
@@ -124,7 +124,7 @@ class UnitOfWork {
|
|
|
124
124
|
/**
|
|
125
125
|
* Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
|
|
126
126
|
*/
|
|
127
|
-
getById(entityName, id, schema) {
|
|
127
|
+
getById(entityName, id, schema, convertCustomTypes) {
|
|
128
128
|
if (id == null || (Array.isArray(id) && id.length === 0)) {
|
|
129
129
|
return undefined;
|
|
130
130
|
}
|
|
@@ -134,7 +134,16 @@ class UnitOfWork {
|
|
|
134
134
|
hash = '' + id;
|
|
135
135
|
}
|
|
136
136
|
else {
|
|
137
|
-
|
|
137
|
+
let keys = Array.isArray(id) ? Utils_1.Utils.flatten(id) : [id];
|
|
138
|
+
keys = meta.getPrimaryProps(true).map((p, i) => {
|
|
139
|
+
if (!convertCustomTypes && p.customType) {
|
|
140
|
+
return p.customType.convertToDatabaseValue(keys[i], this.platform, {
|
|
141
|
+
key: p.name,
|
|
142
|
+
mode: 'hydration',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return keys[i];
|
|
146
|
+
});
|
|
138
147
|
hash = Utils_1.Utils.getPrimaryKeyHash(keys);
|
|
139
148
|
}
|
|
140
149
|
schema ??= meta.schema ?? this.em.config.getSchema();
|
|
@@ -312,9 +321,11 @@ class UnitOfWork {
|
|
|
312
321
|
const platform = this.em.getPlatform();
|
|
313
322
|
const runInTransaction = !this.em.isInTransaction() && platform.supportsTransactions() && this.em.config.get('implicitTransactions');
|
|
314
323
|
if (runInTransaction) {
|
|
324
|
+
const loggerContext = Utils_1.Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
315
325
|
await this.em.getConnection('write').transactional(trx => this.persistToDatabase(groups, trx), {
|
|
316
326
|
ctx: oldTx,
|
|
317
327
|
eventBroadcaster: new events_1.TransactionEventBroadcaster(this.em, this),
|
|
328
|
+
loggerContext,
|
|
318
329
|
});
|
|
319
330
|
}
|
|
320
331
|
else {
|
|
@@ -888,7 +899,12 @@ class UnitOfWork {
|
|
|
888
899
|
}
|
|
889
900
|
async commitCollectionUpdates(ctx) {
|
|
890
901
|
this.filterCollectionUpdates();
|
|
891
|
-
|
|
902
|
+
const loggerContext = Utils_1.Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
903
|
+
await this.em.getDriver().syncCollections(this.collectionUpdates, {
|
|
904
|
+
ctx,
|
|
905
|
+
schema: this.em.schema,
|
|
906
|
+
loggerContext,
|
|
907
|
+
});
|
|
892
908
|
for (const coll of this.collectionUpdates) {
|
|
893
909
|
coll.takeSnapshot();
|
|
894
910
|
}
|