@mikro-orm/core 7.0.0-dev.22 → 7.0.0-dev.24
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 +12 -2
- package/EntityManager.js +40 -53
- package/README.md +1 -2
- package/connections/Connection.d.ts +4 -2
- package/connections/Connection.js +2 -2
- package/decorators/Entity.d.ts +15 -0
- package/decorators/Indexed.d.ts +2 -2
- package/decorators/ManyToMany.d.ts +2 -0
- package/decorators/ManyToOne.d.ts +2 -0
- package/decorators/OneToOne.d.ts +2 -0
- 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/Collection.js +3 -2
- package/entity/EntityFactory.d.ts +6 -0
- package/entity/EntityFactory.js +17 -6
- package/entity/EntityHelper.js +5 -1
- package/entity/EntityLoader.js +27 -19
- package/entity/Reference.d.ts +5 -0
- package/entity/Reference.js +16 -0
- package/entity/WrappedEntity.js +1 -1
- package/entity/defineEntity.d.ts +537 -0
- package/entity/defineEntity.js +690 -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 +15 -3
- package/enums.d.ts +15 -2
- package/enums.js +13 -0
- package/errors.d.ts +6 -0
- package/errors.js +14 -0
- package/hydration/ObjectHydrator.js +1 -1
- package/index.d.ts +1 -1
- package/metadata/EntitySchema.js +10 -2
- package/metadata/MetadataDiscovery.d.ts +0 -1
- package/metadata/MetadataDiscovery.js +27 -18
- package/package.json +3 -3
- package/platforms/Platform.d.ts +3 -1
- package/serialization/SerializationContext.js +13 -10
- package/types/BooleanType.d.ts +1 -1
- package/types/DecimalType.js +1 -1
- package/types/DoubleType.js +1 -1
- package/typings.d.ts +32 -10
- package/typings.js +21 -4
- package/unit-of-work/ChangeSetComputer.js +3 -1
- package/unit-of-work/ChangeSetPersister.d.ts +4 -2
- package/unit-of-work/ChangeSetPersister.js +14 -10
- package/unit-of-work/UnitOfWork.d.ts +2 -1
- package/unit-of-work/UnitOfWork.js +36 -13
- 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/DataloaderUtils.d.ts +6 -1
- package/utils/DataloaderUtils.js +37 -20
- 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 -1
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +199 -0
- package/utils/Utils.d.ts +2 -2
- package/utils/Utils.js +31 -7
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/upsert-utils.js +9 -1
package/entity/index.d.ts
CHANGED
package/entity/index.js
CHANGED
package/entity/utils.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { EntityMetadata, PopulateOptions } from '../typings.js';
|
|
2
|
+
import { LoadStrategy, ReferenceKind } from '../enums.js';
|
|
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,5 +1,5 @@
|
|
|
1
|
-
import { PopulatePath, ReferenceKind } from '../enums.js';
|
|
2
|
-
import { Utils } from '
|
|
1
|
+
import { LoadStrategy, PopulatePath, ReferenceKind } from '../enums.js';
|
|
2
|
+
import { Utils } from '../utils/Utils.js';
|
|
3
3
|
/**
|
|
4
4
|
* Expands `books.perex` like populate to use `children` array instead of the dot syntax
|
|
5
5
|
*/
|
|
@@ -34,7 +34,6 @@ export function expandDotPaths(meta, populate, normalized = false) {
|
|
|
34
34
|
p.field = f;
|
|
35
35
|
p.children ??= [];
|
|
36
36
|
const prop = meta.properties[p.field];
|
|
37
|
-
p.strategy ??= prop.strategy;
|
|
38
37
|
if (parts[0] === PopulatePath.ALL) {
|
|
39
38
|
prop.targetMeta.props
|
|
40
39
|
.filter(prop => prop.lazy || prop.kind !== ReferenceKind.SCALAR)
|
|
@@ -55,3 +54,16 @@ export function expandDotPaths(meta, populate, normalized = false) {
|
|
|
55
54
|
}
|
|
56
55
|
return ret;
|
|
57
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the loading strategy based on the provided hint.
|
|
59
|
+
* If `BALANCED` strategy is used, it will return JOINED if the property is a to-one relation.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export function getLoadingStrategy(strategy, kind) {
|
|
63
|
+
if (strategy === LoadStrategy.BALANCED) {
|
|
64
|
+
return [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(kind)
|
|
65
|
+
? LoadStrategy.JOINED
|
|
66
|
+
: LoadStrategy.SELECT_IN;
|
|
67
|
+
}
|
|
68
|
+
return strategy;
|
|
69
|
+
}
|
package/enums.d.ts
CHANGED
|
@@ -85,7 +85,9 @@ 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
|
-
|
|
88
|
+
DISABLE_NESTED_INNER_JOIN = "DISABLE_NESTED_INNER_JOIN",
|
|
89
|
+
IDENTITY_INSERT = "IDENTITY_INSERT",// mssql only
|
|
90
|
+
OUTPUT_TABLE = "OUTPUT_TABLE"
|
|
89
91
|
}
|
|
90
92
|
export declare const SCALAR_TYPES: string[];
|
|
91
93
|
export declare enum ReferenceKind {
|
|
@@ -108,7 +110,8 @@ export declare enum Cascade {
|
|
|
108
110
|
}
|
|
109
111
|
export declare enum LoadStrategy {
|
|
110
112
|
SELECT_IN = "select-in",
|
|
111
|
-
JOINED = "joined"
|
|
113
|
+
JOINED = "joined",
|
|
114
|
+
BALANCED = "balanced"
|
|
112
115
|
}
|
|
113
116
|
export declare enum DataloaderType {
|
|
114
117
|
NONE = 0,
|
|
@@ -156,8 +159,18 @@ export declare enum EventType {
|
|
|
156
159
|
}
|
|
157
160
|
export declare const EventTypeMap: Record<EventType, number>;
|
|
158
161
|
export type TransactionEventType = EventType.beforeTransactionStart | EventType.afterTransactionStart | EventType.beforeTransactionCommit | EventType.afterTransactionCommit | EventType.beforeTransactionRollback | EventType.afterTransactionRollback;
|
|
162
|
+
export declare enum TransactionPropagation {
|
|
163
|
+
REQUIRED = "required",
|
|
164
|
+
REQUIRES_NEW = "requires_new",
|
|
165
|
+
NESTED = "nested",
|
|
166
|
+
NOT_SUPPORTED = "not_supported",
|
|
167
|
+
SUPPORTS = "supports",
|
|
168
|
+
MANDATORY = "mandatory",
|
|
169
|
+
NEVER = "never"
|
|
170
|
+
}
|
|
159
171
|
export interface TransactionOptions {
|
|
160
172
|
ctx?: Transaction;
|
|
173
|
+
propagation?: TransactionPropagation;
|
|
161
174
|
isolationLevel?: IsolationLevel;
|
|
162
175
|
readOnly?: boolean;
|
|
163
176
|
clear?: boolean;
|
package/enums.js
CHANGED
|
@@ -95,7 +95,9 @@ export var QueryFlag;
|
|
|
95
95
|
QueryFlag["INCLUDE_LAZY_FORMULAS"] = "INCLUDE_LAZY_FORMULAS";
|
|
96
96
|
QueryFlag["AUTO_JOIN_ONE_TO_ONE_OWNER"] = "AUTO_JOIN_ONE_TO_ONE_OWNER";
|
|
97
97
|
QueryFlag["INFER_POPULATE"] = "INFER_POPULATE";
|
|
98
|
+
QueryFlag["DISABLE_NESTED_INNER_JOIN"] = "DISABLE_NESTED_INNER_JOIN";
|
|
98
99
|
QueryFlag["IDENTITY_INSERT"] = "IDENTITY_INSERT";
|
|
100
|
+
QueryFlag["OUTPUT_TABLE"] = "OUTPUT_TABLE";
|
|
99
101
|
})(QueryFlag || (QueryFlag = {}));
|
|
100
102
|
export const SCALAR_TYPES = ['string', 'number', 'boolean', 'bigint', 'Date', 'Buffer', 'RegExp'];
|
|
101
103
|
export var ReferenceKind;
|
|
@@ -122,6 +124,7 @@ export var LoadStrategy;
|
|
|
122
124
|
(function (LoadStrategy) {
|
|
123
125
|
LoadStrategy["SELECT_IN"] = "select-in";
|
|
124
126
|
LoadStrategy["JOINED"] = "joined";
|
|
127
|
+
LoadStrategy["BALANCED"] = "balanced";
|
|
125
128
|
})(LoadStrategy || (LoadStrategy = {}));
|
|
126
129
|
export var DataloaderType;
|
|
127
130
|
(function (DataloaderType) {
|
|
@@ -175,6 +178,16 @@ export const EventTypeMap = Object.keys(EventType).reduce((a, b, i) => {
|
|
|
175
178
|
a[b] = i;
|
|
176
179
|
return a;
|
|
177
180
|
}, {});
|
|
181
|
+
export var TransactionPropagation;
|
|
182
|
+
(function (TransactionPropagation) {
|
|
183
|
+
TransactionPropagation["REQUIRED"] = "required";
|
|
184
|
+
TransactionPropagation["REQUIRES_NEW"] = "requires_new";
|
|
185
|
+
TransactionPropagation["NESTED"] = "nested";
|
|
186
|
+
TransactionPropagation["NOT_SUPPORTED"] = "not_supported";
|
|
187
|
+
TransactionPropagation["SUPPORTS"] = "supports";
|
|
188
|
+
TransactionPropagation["MANDATORY"] = "mandatory";
|
|
189
|
+
TransactionPropagation["NEVER"] = "never";
|
|
190
|
+
})(TransactionPropagation || (TransactionPropagation = {}));
|
|
178
191
|
export class PlainObject {
|
|
179
192
|
}
|
|
180
193
|
export var DeferMode;
|
package/errors.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class ValidationError<T extends AnyEntity = AnyEntity> extends Er
|
|
|
24
24
|
static cannotCommit(): ValidationError;
|
|
25
25
|
static cannotUseGlobalContext(): ValidationError;
|
|
26
26
|
static cannotUseOperatorsInsideEmbeddables(className: string, propName: string, payload: unknown): ValidationError;
|
|
27
|
+
static cannotUseGroupOperatorsInsideScalars(className: string, propName: string, payload: unknown): ValidationError;
|
|
27
28
|
static invalidEmbeddableQuery(className: string, propName: string, embeddableType: string): ValidationError;
|
|
28
29
|
}
|
|
29
30
|
export declare class CursorError<T extends AnyEntity = AnyEntity> extends ValidationError<T> {
|
|
@@ -66,3 +67,8 @@ export declare class NotFoundError<T extends AnyEntity = AnyEntity> extends Vali
|
|
|
66
67
|
static findOneFailed(name: string, where: Dictionary | IPrimaryKey): NotFoundError;
|
|
67
68
|
static findExactlyOneFailed(name: string, where: Dictionary | IPrimaryKey): NotFoundError;
|
|
68
69
|
}
|
|
70
|
+
export declare class TransactionStateError extends ValidationError {
|
|
71
|
+
static requiredTransactionNotFound(propagation: string): TransactionStateError;
|
|
72
|
+
static transactionNotAllowed(propagation: string): TransactionStateError;
|
|
73
|
+
static invalidPropagation(propagation: string): TransactionStateError;
|
|
74
|
+
}
|
package/errors.js
CHANGED
|
@@ -94,6 +94,9 @@ export class ValidationError extends Error {
|
|
|
94
94
|
static cannotUseOperatorsInsideEmbeddables(className, propName, payload) {
|
|
95
95
|
return new ValidationError(`Using operators inside embeddables is not allowed, move the operator above. (property: ${className}.${propName}, payload: ${inspect(payload)})`);
|
|
96
96
|
}
|
|
97
|
+
static cannotUseGroupOperatorsInsideScalars(className, propName, payload) {
|
|
98
|
+
return new ValidationError(`Using group operators ($and/$or) inside scalar properties is not allowed, move the operator above. (property: ${className}.${propName}, payload: ${inspect(payload)})`);
|
|
99
|
+
}
|
|
97
100
|
static invalidEmbeddableQuery(className, propName, embeddableType) {
|
|
98
101
|
return new ValidationError(`Invalid query for entity '${className}', property '${propName}' does not exist in embeddable '${embeddableType}'`);
|
|
99
102
|
}
|
|
@@ -220,3 +223,14 @@ export class NotFoundError extends ValidationError {
|
|
|
220
223
|
return new NotFoundError(`Wrong number of ${name} entities found for query ${inspect(where)}, expected exactly one`);
|
|
221
224
|
}
|
|
222
225
|
}
|
|
226
|
+
export class TransactionStateError extends ValidationError {
|
|
227
|
+
static requiredTransactionNotFound(propagation) {
|
|
228
|
+
return new TransactionStateError(`No existing transaction found for transaction marked with propagation "${propagation}"`);
|
|
229
|
+
}
|
|
230
|
+
static transactionNotAllowed(propagation) {
|
|
231
|
+
return new TransactionStateError(`Existing transaction found for transaction marked with propagation "${propagation}"`);
|
|
232
|
+
}
|
|
233
|
+
static invalidPropagation(propagation) {
|
|
234
|
+
return new TransactionStateError(`Unsupported transaction propagation type: ${propagation}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -63,7 +63,7 @@ export class ObjectHydrator extends Hydrator {
|
|
|
63
63
|
const ret = [];
|
|
64
64
|
const idx = this.tmpIndex++;
|
|
65
65
|
const nullVal = this.config.get('forceUndefined') ? 'undefined' : 'null';
|
|
66
|
-
if (prop.getter && !prop.setter) {
|
|
66
|
+
if (prop.getter && !prop.setter && prop.persist === false) {
|
|
67
67
|
return [];
|
|
68
68
|
}
|
|
69
69
|
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.js';
|
|
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.js';
|
|
6
6
|
export * from './enums.js';
|
|
7
7
|
export * from './errors.js';
|
|
8
8
|
export * from './exceptions.js';
|
package/metadata/EntitySchema.js
CHANGED
|
@@ -99,6 +99,8 @@ export class EntitySchema {
|
|
|
99
99
|
if (prop.fieldNames && !prop.joinColumns) {
|
|
100
100
|
prop.joinColumns = prop.fieldNames;
|
|
101
101
|
}
|
|
102
|
+
// By default, the foreign key constraint is created on the relation
|
|
103
|
+
Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
|
|
102
104
|
this.addProperty(name, type, prop);
|
|
103
105
|
}
|
|
104
106
|
addManyToMany(name, type, options) {
|
|
@@ -108,6 +110,8 @@ export class EntitySchema {
|
|
|
108
110
|
}
|
|
109
111
|
if (options.owner) {
|
|
110
112
|
Utils.renameKey(options, 'mappedBy', 'inversedBy');
|
|
113
|
+
// By default, the foreign key constraint is created on the relation
|
|
114
|
+
Utils.defaultValue(options, 'createForeignKeyConstraint', true);
|
|
111
115
|
}
|
|
112
116
|
const prop = this.createProperty(ReferenceKind.MANY_TO_MANY, options);
|
|
113
117
|
this.addProperty(name, type, prop);
|
|
@@ -120,8 +124,12 @@ export class EntitySchema {
|
|
|
120
124
|
const prop = this.createProperty(ReferenceKind.ONE_TO_ONE, options);
|
|
121
125
|
Utils.defaultValue(prop, 'owner', !!prop.inversedBy || !prop.mappedBy);
|
|
122
126
|
Utils.defaultValue(prop, 'unique', prop.owner);
|
|
123
|
-
if (prop.owner
|
|
124
|
-
|
|
127
|
+
if (prop.owner) {
|
|
128
|
+
if (options.mappedBy) {
|
|
129
|
+
Utils.renameKey(prop, 'mappedBy', 'inversedBy');
|
|
130
|
+
}
|
|
131
|
+
// By default, the foreign key constraint is created on the relation
|
|
132
|
+
Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
|
|
125
133
|
}
|
|
126
134
|
if (prop.joinColumns && !prop.fieldNames) {
|
|
127
135
|
prop.fieldNames = prop.joinColumns;
|
|
@@ -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;
|
|
@@ -619,7 +619,7 @@ export class MetadataDiscovery {
|
|
|
619
619
|
}
|
|
620
620
|
data.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.className, targetType + '_inverse', true, meta.className === targetType);
|
|
621
621
|
data.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetType, meta.name + '_owner', false, meta.className === targetType);
|
|
622
|
-
return this.metadata.set(data.className, data);
|
|
622
|
+
return this.metadata.set(data.className, EntitySchema.fromMetadata(data).init().meta);
|
|
623
623
|
}
|
|
624
624
|
defineFixedOrderProperty(prop, targetType) {
|
|
625
625
|
const pk = prop.fixedOrderColumn || this.namingStrategy.referenceColumnName();
|
|
@@ -654,6 +654,7 @@ export class MetadataDiscovery {
|
|
|
654
654
|
autoincrement: false,
|
|
655
655
|
updateRule: prop.updateRule,
|
|
656
656
|
deleteRule: prop.deleteRule,
|
|
657
|
+
createForeignKeyConstraint: prop.createForeignKeyConstraint,
|
|
657
658
|
};
|
|
658
659
|
if (selfReferencing && !this.platform.supportsMultipleCascadePaths()) {
|
|
659
660
|
ret.updateRule ??= 'no action';
|
|
@@ -821,9 +822,16 @@ export class MetadataDiscovery {
|
|
|
821
822
|
}
|
|
822
823
|
return prop.embedded ? isParentObject(meta.properties[prop.embedded[0]]) : false;
|
|
823
824
|
};
|
|
825
|
+
const isParentArray = (prop) => {
|
|
826
|
+
if (prop.array) {
|
|
827
|
+
return true;
|
|
828
|
+
}
|
|
829
|
+
return prop.embedded ? isParentArray(meta.properties[prop.embedded[0]]) : false;
|
|
830
|
+
};
|
|
824
831
|
const rootProperty = getRootProperty(embeddedProp);
|
|
825
832
|
const parentProperty = meta.properties[embeddedProp.embedded?.[0] ?? ''];
|
|
826
833
|
const object = isParentObject(embeddedProp);
|
|
834
|
+
const array = isParentArray(embeddedProp);
|
|
827
835
|
this.initFieldName(embeddedProp, rootProperty !== embeddedProp && object);
|
|
828
836
|
// the prefix of the parent cannot be a boolean; it already passed here
|
|
829
837
|
const prefix = this.getPrefix(embeddedProp, parentProperty);
|
|
@@ -836,7 +844,8 @@ export class MetadataDiscovery {
|
|
|
836
844
|
meta.propertyOrder.set(name, (order += 0.01));
|
|
837
845
|
embeddedProp.embeddedProps[prop.name] = meta.properties[name];
|
|
838
846
|
meta.properties[name].persist ??= embeddedProp.persist;
|
|
839
|
-
|
|
847
|
+
const refInArray = array && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && prop.owner;
|
|
848
|
+
if (embeddedProp.nullable || refInArray) {
|
|
840
849
|
meta.properties[name].nullable = true;
|
|
841
850
|
}
|
|
842
851
|
if (meta.properties[name].fieldNames) {
|
|
@@ -874,7 +883,7 @@ export class MetadataDiscovery {
|
|
|
874
883
|
meta.properties[name].persist = false; // only virtual as we store the whole object
|
|
875
884
|
meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
|
|
876
885
|
meta.properties[name].object = true;
|
|
877
|
-
this.initCustomType(meta, meta.properties[name], true);
|
|
886
|
+
this.initCustomType(meta, meta.properties[name], false, true);
|
|
878
887
|
}
|
|
879
888
|
this.initEmbeddables(meta, meta.properties[name], visited);
|
|
880
889
|
}
|
|
@@ -968,7 +977,7 @@ export class MetadataDiscovery {
|
|
|
968
977
|
}
|
|
969
978
|
}
|
|
970
979
|
initCheckConstraints(meta) {
|
|
971
|
-
const map =
|
|
980
|
+
const map = meta.createColumnMappingObject();
|
|
972
981
|
for (const check of meta.checks) {
|
|
973
982
|
const columns = check.property ? meta.properties[check.property].fieldNames : [];
|
|
974
983
|
check.name ??= this.namingStrategy.indexName(meta.tableName, columns, 'check');
|
|
@@ -1003,20 +1012,12 @@ export class MetadataDiscovery {
|
|
|
1003
1012
|
}
|
|
1004
1013
|
return;
|
|
1005
1014
|
}
|
|
1006
|
-
const map =
|
|
1015
|
+
const map = meta.createColumnMappingObject();
|
|
1007
1016
|
if (prop.generated instanceof Function) {
|
|
1008
1017
|
prop.generated = prop.generated(map);
|
|
1009
1018
|
}
|
|
1010
1019
|
}
|
|
1011
|
-
|
|
1012
|
-
return Object.values(meta.properties).reduce((o, prop) => {
|
|
1013
|
-
if (prop.fieldNames) {
|
|
1014
|
-
o[prop.name] = prop.fieldNames[0];
|
|
1015
|
-
}
|
|
1016
|
-
return o;
|
|
1017
|
-
}, {});
|
|
1018
|
-
}
|
|
1019
|
-
getDefaultVersionValue(prop) {
|
|
1020
|
+
getDefaultVersionValue(meta, prop) {
|
|
1020
1021
|
if (typeof prop.defaultRaw !== 'undefined') {
|
|
1021
1022
|
return prop.defaultRaw;
|
|
1022
1023
|
}
|
|
@@ -1024,7 +1025,9 @@ export class MetadataDiscovery {
|
|
|
1024
1025
|
if (prop.default != null) {
|
|
1025
1026
|
return '' + this.platform.quoteVersionValue(prop.default, prop);
|
|
1026
1027
|
}
|
|
1027
|
-
|
|
1028
|
+
this.initCustomType(meta, prop, true);
|
|
1029
|
+
const type = prop.customType?.runtimeType ?? prop.runtimeType ?? prop.type;
|
|
1030
|
+
if (type === 'Date') {
|
|
1028
1031
|
prop.length ??= this.platform.getDefaultVersionLength();
|
|
1029
1032
|
return this.platform.getCurrentTimestampSQL(prop.length);
|
|
1030
1033
|
}
|
|
@@ -1067,7 +1070,7 @@ export class MetadataDiscovery {
|
|
|
1067
1070
|
prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
|
|
1068
1071
|
return;
|
|
1069
1072
|
}
|
|
1070
|
-
if (
|
|
1073
|
+
if (Array.isArray(prop.default) && prop.customType) {
|
|
1071
1074
|
val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
|
|
1072
1075
|
}
|
|
1073
1076
|
prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
|
|
@@ -1095,13 +1098,13 @@ export class MetadataDiscovery {
|
|
|
1095
1098
|
if (prop.version) {
|
|
1096
1099
|
this.initDefaultValue(prop);
|
|
1097
1100
|
meta.versionProperty = prop.name;
|
|
1098
|
-
prop.defaultRaw = this.getDefaultVersionValue(prop);
|
|
1101
|
+
prop.defaultRaw = this.getDefaultVersionValue(meta, prop);
|
|
1099
1102
|
}
|
|
1100
1103
|
if (prop.concurrencyCheck && !prop.primary) {
|
|
1101
1104
|
meta.concurrencyCheckKeys.add(prop.name);
|
|
1102
1105
|
}
|
|
1103
1106
|
}
|
|
1104
|
-
initCustomType(meta, prop, objectEmbeddable = false) {
|
|
1107
|
+
initCustomType(meta, prop, simple = false, objectEmbeddable = false) {
|
|
1105
1108
|
// `prop.type` might be actually instance of custom type class
|
|
1106
1109
|
if (Type.isMappedType(prop.type) && !prop.customType) {
|
|
1107
1110
|
prop.customType = prop.type;
|
|
@@ -1112,12 +1115,18 @@ export class MetadataDiscovery {
|
|
|
1112
1115
|
prop.customType = new prop.type();
|
|
1113
1116
|
prop.type = prop.customType.constructor.name;
|
|
1114
1117
|
}
|
|
1118
|
+
if (simple) {
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1115
1121
|
if (!prop.customType && ['json', 'jsonb'].includes(prop.type?.toLowerCase())) {
|
|
1116
1122
|
prop.customType = new JsonType();
|
|
1117
1123
|
}
|
|
1118
1124
|
if (prop.kind === ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
|
|
1119
1125
|
prop.customType = new JsonType();
|
|
1120
1126
|
}
|
|
1127
|
+
if (prop.kind === ReferenceKind.EMBEDDED && !prop.customType && (prop.object || prop.array)) {
|
|
1128
|
+
prop.customType = new JsonType();
|
|
1129
|
+
}
|
|
1121
1130
|
if (!prop.customType && prop.array && prop.items) {
|
|
1122
1131
|
prop.customType = new EnumArrayType(`${meta.className}.${prop.name}`, prop.items);
|
|
1123
1132
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-dev.
|
|
4
|
+
"version": "7.0.0-dev.24",
|
|
5
5
|
"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.",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./package.json": "./package.json",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"dataloader": "2.2.3",
|
|
55
|
-
"dotenv": "
|
|
55
|
+
"dotenv": "17.2.1",
|
|
56
56
|
"esprima": "4.0.1",
|
|
57
|
-
"mikro-orm": "7.0.0-dev.
|
|
57
|
+
"mikro-orm": "7.0.0-dev.24",
|
|
58
58
|
"reflect-metadata": "0.2.2",
|
|
59
59
|
"tinyglobby": "0.2.13"
|
|
60
60
|
}
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -175,7 +175,9 @@ export declare abstract class Platform {
|
|
|
175
175
|
getExtension<T>(extensionName: string, extensionKey: string, moduleName: string, em: EntityManager): T;
|
|
176
176
|
getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): ISchemaGenerator;
|
|
177
177
|
processDateProperty(value: unknown): string | number | Date;
|
|
178
|
-
quoteIdentifier(id: string
|
|
178
|
+
quoteIdentifier(id: string | {
|
|
179
|
+
toString: () => string;
|
|
180
|
+
}, quote?: string): string;
|
|
179
181
|
quoteValue(value: any): string;
|
|
180
182
|
escape(value: any): string;
|
|
181
183
|
formatQuery(sql: string, params: readonly any[]): string;
|
|
@@ -73,18 +73,21 @@ export class SerializationContext {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
isMarkedAsPopulated(entityName, prop) {
|
|
76
|
-
let populate = this.populate;
|
|
76
|
+
let populate = this.populate ?? [];
|
|
77
77
|
for (const segment of this.path) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
const hints = populate.filter(p => p.field === segment[1]);
|
|
79
|
+
if (hints.length > 0) {
|
|
80
|
+
const childHints = [];
|
|
81
|
+
for (const hint of hints) {
|
|
82
|
+
// we need to check for cycles here too, as we could fall into endless loops for bidirectional relations
|
|
83
|
+
if (hint.all) {
|
|
84
|
+
return !this.path.find(([cls, item]) => entityName === cls && prop === item);
|
|
85
|
+
}
|
|
86
|
+
if (hint.children) {
|
|
87
|
+
childHints.push(...hint.children);
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
|
-
populate =
|
|
90
|
+
populate = childHints;
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
return !!populate?.some(p => p.field === prop);
|
package/types/BooleanType.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Type } from './Type.js';
|
|
2
2
|
import type { Platform } from '../platforms/Platform.js';
|
|
3
3
|
import type { EntityProperty } from '../typings.js';
|
|
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
|
@@ -53,11 +53,15 @@ export declare const EagerProps: unique symbol;
|
|
|
53
53
|
export declare const HiddenProps: unique symbol;
|
|
54
54
|
export declare const Config: unique symbol;
|
|
55
55
|
declare const __optional: unique symbol;
|
|
56
|
+
declare const __requiredNullable: unique symbol;
|
|
56
57
|
declare const __hidden: unique symbol;
|
|
57
58
|
declare const __config: unique symbol;
|
|
58
59
|
export type Opt<T = unknown> = T & {
|
|
59
60
|
[__optional]?: 1;
|
|
60
61
|
};
|
|
62
|
+
export type RequiredNullable<T = never> = (T & {
|
|
63
|
+
[__requiredNullable]?: 1;
|
|
64
|
+
}) | null;
|
|
61
65
|
export type Hidden<T = unknown> = T & {
|
|
62
66
|
[__hidden]?: 1;
|
|
63
67
|
};
|
|
@@ -82,6 +86,7 @@ export type Primary<T> = IsAny<T> extends true ? any : T extends {
|
|
|
82
86
|
} ? ReadonlyPrimary<PK> : T extends {
|
|
83
87
|
id?: infer PK;
|
|
84
88
|
} ? ReadonlyPrimary<PK> : T;
|
|
89
|
+
/** @internal */
|
|
85
90
|
export type PrimaryProperty<T> = T extends {
|
|
86
91
|
[PrimaryKeyProp]?: infer PK;
|
|
87
92
|
} ? (PK extends keyof T ? PK : (PK extends any[] ? PK[number] : never)) : T extends {
|
|
@@ -224,7 +229,9 @@ export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Dat
|
|
|
224
229
|
__runtime?: infer Runtime;
|
|
225
230
|
__raw?: infer Raw;
|
|
226
231
|
} ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? EntityDataNested<U, C> : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends Collection<infer U, any> ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
|
|
227
|
-
export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : T
|
|
232
|
+
export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends {
|
|
233
|
+
[__requiredNullable]?: 1;
|
|
234
|
+
} ? T | null : T extends Scalar ? T : T extends {
|
|
228
235
|
__runtime?: infer Runtime;
|
|
229
236
|
__raw?: infer Raw;
|
|
230
237
|
} ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? RequiredEntityDataNested<U, O, C> : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends Collection<infer U, any> ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
|
|
@@ -239,7 +246,12 @@ type ExplicitlyOptionalProps<T> = (T extends {
|
|
|
239
246
|
type NullableKeys<T, V = null> = {
|
|
240
247
|
[K in keyof T]: V extends T[K] ? K : never;
|
|
241
248
|
}[keyof T];
|
|
242
|
-
type
|
|
249
|
+
type RequiredNullableKeys<T> = {
|
|
250
|
+
[K in keyof T]: Exclude<T[K], null> extends {
|
|
251
|
+
[__requiredNullable]?: 1;
|
|
252
|
+
} ? K : never;
|
|
253
|
+
}[keyof T];
|
|
254
|
+
type ProbablyOptionalProps<T> = PrimaryProperty<T> | ExplicitlyOptionalProps<T> | Exclude<NonNullable<NullableKeys<T, null | undefined>>, RequiredNullableKeys<T>>;
|
|
243
255
|
type IsOptional<T, K extends keyof T, I> = T[K] extends Collection<any, any> ? true : ExtractType<T[K]> extends I ? true : K extends ProbablyOptionalProps<T> ? true : false;
|
|
244
256
|
type RequiredKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? CleanKeys<T, K> : never;
|
|
245
257
|
type OptionalKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? never : CleanKeys<T, K>;
|
|
@@ -297,8 +309,14 @@ export type EntityDTO<T, C extends TypeConfig = never> = {
|
|
|
297
309
|
[K in keyof T as DTOOptionalKeys<T, K>]?: EntityDTOProp<T, T[K], C> | AddOptional<T[K]>;
|
|
298
310
|
};
|
|
299
311
|
type TargetKeys<T> = T extends EntityClass<infer P> ? keyof P : keyof T;
|
|
300
|
-
type
|
|
301
|
-
|
|
312
|
+
type PropertyName<T> = IsUnknown<T> extends false ? TargetKeys<T> : string;
|
|
313
|
+
type TableName = {
|
|
314
|
+
name: string;
|
|
315
|
+
schema?: string;
|
|
316
|
+
toString: () => string;
|
|
317
|
+
};
|
|
318
|
+
export type IndexCallback<T> = (table: TableName, columns: Record<PropertyName<T>, string>, indexName: string) => string | RawQueryFragment;
|
|
319
|
+
export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>) => string;
|
|
302
320
|
export type GeneratedColumnCallback<T> = (columns: Record<keyof T, string>) => string;
|
|
303
321
|
export interface CheckConstraint<T = any> {
|
|
304
322
|
name?: string;
|
|
@@ -394,6 +412,7 @@ export interface EntityProperty<Owner = any, Target = any> {
|
|
|
394
412
|
optional?: boolean;
|
|
395
413
|
ignoreSchemaChanges?: ('type' | 'extra' | 'default')[];
|
|
396
414
|
deferMode?: DeferMode;
|
|
415
|
+
createForeignKeyConstraint: boolean;
|
|
397
416
|
foreignKeyName?: string;
|
|
398
417
|
}
|
|
399
418
|
export declare class EntityMetadata<T = any> {
|
|
@@ -403,8 +422,9 @@ export declare class EntityMetadata<T = any> {
|
|
|
403
422
|
constructor(meta?: Partial<EntityMetadata>);
|
|
404
423
|
addProperty(prop: Partial<EntityProperty<T>>, sync?: boolean): void;
|
|
405
424
|
removeProperty(name: string, sync?: boolean): void;
|
|
406
|
-
getPrimaryProps(): EntityProperty<T>[];
|
|
425
|
+
getPrimaryProps(flatten?: boolean): EntityProperty<T>[];
|
|
407
426
|
getPrimaryProp(): EntityProperty<T>;
|
|
427
|
+
createColumnMappingObject(): Dictionary<any>;
|
|
408
428
|
get tableName(): string;
|
|
409
429
|
set tableName(name: string);
|
|
410
430
|
sync(initIndexes?: boolean, config?: Configuration): void;
|
|
@@ -456,18 +476,18 @@ export interface EntityMetadata<T = any> {
|
|
|
456
476
|
uniqueProps: EntityProperty<T>[];
|
|
457
477
|
getterProps: EntityProperty<T>[];
|
|
458
478
|
indexes: {
|
|
459
|
-
properties
|
|
479
|
+
properties?: EntityKey<T> | EntityKey<T>[];
|
|
460
480
|
name?: string;
|
|
461
481
|
type?: string;
|
|
462
482
|
options?: Dictionary;
|
|
463
|
-
expression?: string
|
|
483
|
+
expression?: string | IndexCallback<T>;
|
|
464
484
|
}[];
|
|
465
485
|
uniques: {
|
|
466
|
-
properties
|
|
486
|
+
properties?: EntityKey<T> | EntityKey<T>[];
|
|
467
487
|
name?: string;
|
|
468
488
|
options?: Dictionary;
|
|
469
|
-
expression?: string
|
|
470
|
-
deferMode?: DeferMode
|
|
489
|
+
expression?: string | IndexCallback<T>;
|
|
490
|
+
deferMode?: DeferMode | `${DeferMode}`;
|
|
471
491
|
}[];
|
|
472
492
|
checks: CheckConstraint<T>[];
|
|
473
493
|
repositoryClass?: string;
|
|
@@ -486,6 +506,7 @@ export interface EntityMetadata<T = any> {
|
|
|
486
506
|
polymorphs?: EntityMetadata[];
|
|
487
507
|
root: EntityMetadata<T>;
|
|
488
508
|
definedProperties: Dictionary;
|
|
509
|
+
hasTriggers?: boolean;
|
|
489
510
|
/** @internal can be used for computed numeric cache keys */
|
|
490
511
|
readonly _id: number;
|
|
491
512
|
}
|
|
@@ -699,6 +720,7 @@ export type PopulateOptions<T> = {
|
|
|
699
720
|
strategy?: LoadStrategy;
|
|
700
721
|
all?: boolean;
|
|
701
722
|
filter?: boolean;
|
|
723
|
+
joinType?: 'inner join' | 'left join';
|
|
702
724
|
children?: PopulateOptions<T[keyof T]>[];
|
|
703
725
|
};
|
|
704
726
|
type Loadable<T extends object> = Collection<T, any> | Reference<T> | Ref<T> | readonly T[];
|