@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/package.json
CHANGED
|
@@ -1,8 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"
|
|
4
|
-
"version": "7.0.0-rc.2",
|
|
3
|
+
"version": "7.0.0-rc.3",
|
|
5
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
|
+
"keywords": [
|
|
6
|
+
"data-mapper",
|
|
7
|
+
"ddd",
|
|
8
|
+
"entity",
|
|
9
|
+
"identity-map",
|
|
10
|
+
"javascript",
|
|
11
|
+
"js",
|
|
12
|
+
"mariadb",
|
|
13
|
+
"mikro-orm",
|
|
14
|
+
"mongo",
|
|
15
|
+
"mongodb",
|
|
16
|
+
"mysql",
|
|
17
|
+
"orm",
|
|
18
|
+
"postgresql",
|
|
19
|
+
"sqlite",
|
|
20
|
+
"sqlite3",
|
|
21
|
+
"ts",
|
|
22
|
+
"typescript",
|
|
23
|
+
"unit-of-work"
|
|
24
|
+
],
|
|
25
|
+
"homepage": "https://mikro-orm.io",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/mikro-orm/mikro-orm/issues"
|
|
28
|
+
},
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"author": "Martin Adámek",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
|
|
34
|
+
},
|
|
35
|
+
"funding": "https://github.com/sponsors/b4nan",
|
|
36
|
+
"type": "module",
|
|
6
37
|
"exports": {
|
|
7
38
|
"./package.json": "./package.json",
|
|
8
39
|
".": "./index.js",
|
|
@@ -18,39 +49,8 @@
|
|
|
18
49
|
"./schema": "./utils/AbstractSchemaGenerator.js",
|
|
19
50
|
"./dataloader": "./utils/DataloaderUtils.js"
|
|
20
51
|
},
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
|
|
24
|
-
},
|
|
25
|
-
"funding": "https://github.com/sponsors/b4nan",
|
|
26
|
-
"keywords": [
|
|
27
|
-
"orm",
|
|
28
|
-
"mongo",
|
|
29
|
-
"mongodb",
|
|
30
|
-
"mysql",
|
|
31
|
-
"mariadb",
|
|
32
|
-
"postgresql",
|
|
33
|
-
"sqlite",
|
|
34
|
-
"sqlite3",
|
|
35
|
-
"ts",
|
|
36
|
-
"typescript",
|
|
37
|
-
"js",
|
|
38
|
-
"javascript",
|
|
39
|
-
"entity",
|
|
40
|
-
"ddd",
|
|
41
|
-
"mikro-orm",
|
|
42
|
-
"unit-of-work",
|
|
43
|
-
"data-mapper",
|
|
44
|
-
"identity-map"
|
|
45
|
-
],
|
|
46
|
-
"author": "Martin Adámek",
|
|
47
|
-
"license": "MIT",
|
|
48
|
-
"bugs": {
|
|
49
|
-
"url": "https://github.com/mikro-orm/mikro-orm/issues"
|
|
50
|
-
},
|
|
51
|
-
"homepage": "https://mikro-orm.io",
|
|
52
|
-
"engines": {
|
|
53
|
-
"node": ">= 22.17.0"
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "yarn compile && yarn copy",
|
|
@@ -58,9 +58,6 @@
|
|
|
58
58
|
"compile": "yarn run -T tsc -p tsconfig.build.json",
|
|
59
59
|
"copy": "node ../../scripts/copy.mjs"
|
|
60
60
|
},
|
|
61
|
-
"publishConfig": {
|
|
62
|
-
"access": "public"
|
|
63
|
-
},
|
|
64
61
|
"peerDependencies": {
|
|
65
62
|
"dataloader": "2.2.3"
|
|
66
63
|
},
|
|
@@ -68,5 +65,8 @@
|
|
|
68
65
|
"dataloader": {
|
|
69
66
|
"optional": true
|
|
70
67
|
}
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">= 22.17.0"
|
|
71
71
|
}
|
|
72
72
|
}
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -140,6 +140,7 @@ export declare abstract class Platform {
|
|
|
140
140
|
getDefaultMappedType(type: string): Type<unknown>;
|
|
141
141
|
supportsMultipleCascadePaths(): boolean;
|
|
142
142
|
supportsMultipleStatements(): boolean;
|
|
143
|
+
supportsUnionWhere(): boolean;
|
|
143
144
|
getArrayDeclarationSQL(): string;
|
|
144
145
|
marshallArray(values: string[]): string;
|
|
145
146
|
unmarshallArray(value: string): string[];
|
package/platforms/Platform.js
CHANGED
|
@@ -198,35 +198,58 @@ export class Platform {
|
|
|
198
198
|
}
|
|
199
199
|
switch (this.extractSimpleType(type)) {
|
|
200
200
|
case 'character':
|
|
201
|
-
case 'char':
|
|
201
|
+
case 'char':
|
|
202
|
+
return Type.getType(CharacterType);
|
|
202
203
|
case 'string':
|
|
203
|
-
case 'varchar':
|
|
204
|
-
|
|
205
|
-
case '
|
|
204
|
+
case 'varchar':
|
|
205
|
+
return Type.getType(StringType);
|
|
206
|
+
case 'interval':
|
|
207
|
+
return Type.getType(IntervalType);
|
|
208
|
+
case 'text':
|
|
209
|
+
return Type.getType(TextType);
|
|
206
210
|
case 'int':
|
|
207
|
-
case 'number':
|
|
208
|
-
|
|
209
|
-
case '
|
|
210
|
-
|
|
211
|
-
case '
|
|
212
|
-
|
|
213
|
-
case '
|
|
214
|
-
|
|
211
|
+
case 'number':
|
|
212
|
+
return Type.getType(IntegerType);
|
|
213
|
+
case 'bigint':
|
|
214
|
+
return Type.getType(BigIntType);
|
|
215
|
+
case 'smallint':
|
|
216
|
+
return Type.getType(SmallIntType);
|
|
217
|
+
case 'tinyint':
|
|
218
|
+
return Type.getType(TinyIntType);
|
|
219
|
+
case 'mediumint':
|
|
220
|
+
return Type.getType(MediumIntType);
|
|
221
|
+
case 'float':
|
|
222
|
+
return Type.getType(FloatType);
|
|
223
|
+
case 'double':
|
|
224
|
+
return Type.getType(DoubleType);
|
|
225
|
+
case 'integer':
|
|
226
|
+
return Type.getType(IntegerType);
|
|
215
227
|
case 'decimal':
|
|
216
|
-
case 'numeric':
|
|
217
|
-
|
|
228
|
+
case 'numeric':
|
|
229
|
+
return Type.getType(DecimalType);
|
|
230
|
+
case 'boolean':
|
|
231
|
+
return Type.getType(BooleanType);
|
|
218
232
|
case 'blob':
|
|
219
|
-
case 'buffer':
|
|
220
|
-
|
|
221
|
-
case '
|
|
222
|
-
|
|
233
|
+
case 'buffer':
|
|
234
|
+
return Type.getType(BlobType);
|
|
235
|
+
case 'uint8array':
|
|
236
|
+
return Type.getType(Uint8ArrayType);
|
|
237
|
+
case 'uuid':
|
|
238
|
+
return Type.getType(UuidType);
|
|
239
|
+
case 'date':
|
|
240
|
+
return Type.getType(DateType);
|
|
223
241
|
case 'datetime':
|
|
224
|
-
case 'timestamp':
|
|
225
|
-
|
|
242
|
+
case 'timestamp':
|
|
243
|
+
return Type.getType(DateTimeType);
|
|
244
|
+
case 'time':
|
|
245
|
+
return Type.getType(TimeType);
|
|
226
246
|
case 'object':
|
|
227
|
-
case 'json':
|
|
228
|
-
|
|
229
|
-
|
|
247
|
+
case 'json':
|
|
248
|
+
return Type.getType(JsonType);
|
|
249
|
+
case 'enum':
|
|
250
|
+
return Type.getType(EnumType);
|
|
251
|
+
default:
|
|
252
|
+
return Type.getType(UnknownType);
|
|
230
253
|
}
|
|
231
254
|
}
|
|
232
255
|
supportsMultipleCascadePaths() {
|
|
@@ -235,6 +258,9 @@ export class Platform {
|
|
|
235
258
|
supportsMultipleStatements() {
|
|
236
259
|
return this.config.get('multipleStatements');
|
|
237
260
|
}
|
|
261
|
+
supportsUnionWhere() {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
238
264
|
getArrayDeclarationSQL() {
|
|
239
265
|
return 'text';
|
|
240
266
|
}
|
|
@@ -9,7 +9,8 @@ function isVisible(meta, propName, options) {
|
|
|
9
9
|
if (options.groups && prop?.groups) {
|
|
10
10
|
return prop.groups.some(g => options.groups.includes(g));
|
|
11
11
|
}
|
|
12
|
-
if (Array.isArray(options.populate) &&
|
|
12
|
+
if (Array.isArray(options.populate) &&
|
|
13
|
+
options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
|
|
13
14
|
return true;
|
|
14
15
|
}
|
|
15
16
|
if (options.exclude?.find(item => item === propName)) {
|
|
@@ -20,7 +21,8 @@ function isVisible(meta, propName, options) {
|
|
|
20
21
|
return visible && !prefixed;
|
|
21
22
|
}
|
|
22
23
|
function isPopulated(propName, options) {
|
|
23
|
-
if (typeof options.populate !== 'boolean' &&
|
|
24
|
+
if (typeof options.populate !== 'boolean' &&
|
|
25
|
+
options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
|
|
24
26
|
return true;
|
|
25
27
|
}
|
|
26
28
|
if (typeof options.populate === 'boolean') {
|
|
@@ -176,7 +178,9 @@ export class EntitySerializer {
|
|
|
176
178
|
static extractChildOptions(options, prop) {
|
|
177
179
|
return {
|
|
178
180
|
...options,
|
|
179
|
-
populate: Array.isArray(options.populate)
|
|
181
|
+
populate: Array.isArray(options.populate)
|
|
182
|
+
? Utils.extractChildElements(options.populate, prop, '*')
|
|
183
|
+
: options.populate,
|
|
180
184
|
exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop) : options.exclude,
|
|
181
185
|
};
|
|
182
186
|
}
|
|
@@ -104,7 +104,7 @@ export class SerializationContext {
|
|
|
104
104
|
}
|
|
105
105
|
fields = fields
|
|
106
106
|
.filter(field => field.startsWith(`${segment[1]}.`) || field === '*')
|
|
107
|
-
.map(field => field === '*' ? field : field.substring(segment[1].length + 1));
|
|
107
|
+
.map(field => (field === '*' ? field : field.substring(segment[1].length + 1)));
|
|
108
108
|
}
|
|
109
109
|
return fields.some(p => p === prop || p === '*');
|
|
110
110
|
}
|
package/typings.d.ts
CHANGED
|
@@ -36,11 +36,11 @@ export type Compute<T> = {
|
|
|
36
36
|
[K in keyof T]: T[K];
|
|
37
37
|
} & {};
|
|
38
38
|
type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | '__selectedType' | '__loadedType';
|
|
39
|
-
export type CleanKeys<T, K extends keyof T, B extends boolean = false> =
|
|
39
|
+
export type CleanKeys<T, K extends keyof T, B extends boolean = false> = T[K] & {} extends Function ? never : K extends symbol | InternalKeys ? never : B extends true ? T[K] & {} extends Scalar ? never : K : K;
|
|
40
40
|
export type FunctionKeys<T, K extends keyof T> = T[K] extends Function ? K : never;
|
|
41
41
|
export type Cast<T, R> = T extends R ? T : R;
|
|
42
|
-
export type IsUnknown<T> = T extends unknown ? unknown extends T ? true : never : never;
|
|
43
|
-
export type IsAny<T> = 0 extends
|
|
42
|
+
export type IsUnknown<T> = T extends unknown ? (unknown extends T ? true : never) : never;
|
|
43
|
+
export type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
44
44
|
export type IsNever<T, True = true, False = false> = [T] extends [never] ? True : False;
|
|
45
45
|
export type MaybePromise<T> = T | Promise<T>;
|
|
46
46
|
/**
|
|
@@ -98,9 +98,9 @@ type LoadableShape = CollectionShape | ReferenceShape | readonly any[];
|
|
|
98
98
|
export type UnionKeys<T> = T extends any ? keyof T : never;
|
|
99
99
|
export type UnionPropertyType<T, K extends PropertyKey> = T extends any ? (K extends keyof T ? T[K] : never) : never;
|
|
100
100
|
type IsUnion<T, U = T> = T extends any ? ([U] extends [T] ? false : true) : false;
|
|
101
|
-
export type MergeUnion<T> = [T] extends [object] ?
|
|
101
|
+
export type MergeUnion<T> = [T] extends [object] ? T extends Scalar ? T : IsUnion<T> extends true ? {
|
|
102
102
|
[K in UnionKeys<T>]: UnionPropertyType<T, K>;
|
|
103
|
-
} : T
|
|
103
|
+
} : T : T;
|
|
104
104
|
export type DeepPartial<T> = T & {
|
|
105
105
|
[P in keyof T]?: T[P] extends (infer U)[] ? DeepPartial<U>[] : T[P] extends Readonly<infer U>[] ? Readonly<DeepPartial<U>>[] : DeepPartial<T[P]>;
|
|
106
106
|
};
|
|
@@ -113,7 +113,7 @@ export declare const Config: unique symbol;
|
|
|
113
113
|
export declare const EntityName: unique symbol;
|
|
114
114
|
export type InferEntityName<T> = T extends {
|
|
115
115
|
[EntityName]?: infer Name;
|
|
116
|
-
} ? Name extends string ? Name : never : never;
|
|
116
|
+
} ? (Name extends string ? Name : never) : never;
|
|
117
117
|
export type Opt<T = unknown> = T & Opt.Brand;
|
|
118
118
|
export declare namespace Opt {
|
|
119
119
|
const __optional: unique symbol;
|
|
@@ -173,11 +173,11 @@ export type Primary<T> = IsAny<T> extends true ? any : T extends {
|
|
|
173
173
|
/** @internal */
|
|
174
174
|
export type PrimaryProperty<T> = T extends {
|
|
175
175
|
[PrimaryKeyProp]?: infer PK;
|
|
176
|
-
} ?
|
|
176
|
+
} ? PK extends keyof T ? PK : PK extends any[] ? PK[number] : never : T extends {
|
|
177
177
|
_id?: any;
|
|
178
|
-
} ?
|
|
178
|
+
} ? T extends {
|
|
179
179
|
id?: any;
|
|
180
|
-
} ? 'id' | '_id' : '_id'
|
|
180
|
+
} ? 'id' | '_id' : '_id' : T extends {
|
|
181
181
|
id?: any;
|
|
182
182
|
} ? 'id' : T extends {
|
|
183
183
|
uuid?: any;
|
|
@@ -237,7 +237,7 @@ type ExpandQueryMerged<T> = [T] extends [object] ? [T] extends [Scalar] ? never
|
|
|
237
237
|
export type FilterObject<T> = {
|
|
238
238
|
-readonly [K in EntityKey<T>]?: ExpandQuery<ExpandProperty<FilterObjectProp<T, K>>> | ExpandQueryMerged<ExpandProperty<FilterObjectProp<T, K>>> | FilterValue<ExpandProperty<FilterObjectProp<T, K>>> | null;
|
|
239
239
|
};
|
|
240
|
-
export type ExpandQuery<T> = T extends object ? T extends Scalar ? never : FilterQuery<T> : FilterValue<T>;
|
|
240
|
+
export type ExpandQuery<T> = T extends object ? (T extends Scalar ? never : FilterQuery<T>) : FilterValue<T>;
|
|
241
241
|
export type EntityProps<T> = {
|
|
242
242
|
-readonly [K in EntityKey<T>]?: T[K];
|
|
243
243
|
};
|
|
@@ -324,11 +324,11 @@ type NonArrayObject = object & {
|
|
|
324
324
|
export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends {
|
|
325
325
|
__runtime?: infer Runtime;
|
|
326
326
|
__raw?: infer Raw;
|
|
327
|
-
} ?
|
|
327
|
+
} ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
|
|
328
328
|
export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends {
|
|
329
329
|
__runtime?: infer Runtime;
|
|
330
330
|
__raw?: infer Raw;
|
|
331
|
-
} ?
|
|
331
|
+
} ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, 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>;
|
|
332
332
|
export type EntityDataNested<T, C extends boolean = false> = T extends undefined ? never : T extends any[] ? Readonly<T> : EntityData<T, C> | ExpandEntityProp<T, C>;
|
|
333
333
|
type UnwrapScalarRef<T> = T extends ScalarReference<infer U> ? U : T;
|
|
334
334
|
type EntityDataItem<T, C extends boolean> = C extends false ? UnwrapScalarRef<T> | EntityDataProp<T, C> | Raw | null : EntityDataProp<T, C> | Raw | null;
|
|
@@ -368,9 +368,9 @@ export type Rel<T> = T;
|
|
|
368
368
|
/** Alias for `ScalarReference` (see {@apilink Ref}). */
|
|
369
369
|
export type ScalarRef<T> = ScalarReference<T>;
|
|
370
370
|
/** Alias for `Reference<T> & { id: number }` (see {@apilink Ref}). */
|
|
371
|
-
export type EntityRef<T extends object> = true extends IsUnknown<PrimaryProperty<T>> ? Reference<T> : IsAny<T> extends true ? Reference<T> :
|
|
371
|
+
export type EntityRef<T extends object> = true extends IsUnknown<PrimaryProperty<T>> ? Reference<T> : IsAny<T> extends true ? Reference<T> : {
|
|
372
372
|
[K in PrimaryProperty<T> & keyof T]: T[K];
|
|
373
|
-
} & Reference<T
|
|
373
|
+
} & Reference<T>;
|
|
374
374
|
/**
|
|
375
375
|
* Ref type represents a `Reference` instance, and adds the primary keys to its prototype automatically, so you can do
|
|
376
376
|
* `ref.id` instead of `ref.unwrap().id`. It resolves to either `ScalarRef` or `EntityRef`, based on the type argument.
|
|
@@ -384,7 +384,7 @@ type ExtractHiddenProps<T> = (T extends {
|
|
|
384
384
|
type ExcludeHidden<T, K extends keyof T> = K extends ExtractHiddenProps<T> ? never : K;
|
|
385
385
|
type ExtractConfig<T> = T extends {
|
|
386
386
|
[Config]?: infer K;
|
|
387
|
-
} ?
|
|
387
|
+
} ? K & TypeConfig : TypeConfig;
|
|
388
388
|
type PreferExplicitConfig<E, I> = IsNever<E, I, E>;
|
|
389
389
|
type PrimaryOrObject<T, U, C extends TypeConfig> = PreferExplicitConfig<C, ExtractConfig<T>>['forceObject'] extends true ? {
|
|
390
390
|
[K in PrimaryProperty<U> & keyof U]: U[K];
|
|
@@ -392,7 +392,7 @@ type PrimaryOrObject<T, U, C extends TypeConfig> = PreferExplicitConfig<C, Extra
|
|
|
392
392
|
type DTOWrapper<T, C extends TypeConfig, Flat extends boolean> = Flat extends true ? EntityDTOFlat<T, C> : EntityDTO<T, C>;
|
|
393
393
|
export type EntityDTOProp<E, T, C extends TypeConfig = never, Flat extends boolean = false> = T extends Scalar ? T : T extends ScalarReference<infer U> ? U : T extends {
|
|
394
394
|
__serialized?: infer U;
|
|
395
|
-
} ?
|
|
395
|
+
} ? IsUnknown<U> extends false ? U : T : T extends LoadedReferenceShape<infer U> ? DTOWrapper<U, C, Flat> : T extends ReferenceShape<infer U> ? PrimaryOrObject<E, U, C> : T extends LoadedCollectionShape<infer U> ? DTOWrapper<U & object, C, Flat>[] : T extends CollectionShape<infer U> ? PrimaryOrObject<E, U & object, C>[] : T extends readonly (infer U)[] ? U extends Scalar ? T : EntityDTOProp<E, U, C, Flat>[] : T extends Relation<T> ? DTOWrapper<T, C, Flat> : T;
|
|
396
396
|
type UnwrapLoadedEntity<T> = T extends {
|
|
397
397
|
[__loadedType]?: infer U;
|
|
398
398
|
} ? NonNullable<U> : T;
|
|
@@ -422,7 +422,7 @@ export type EntityDTOFlat<T, C extends TypeConfig = never> = {
|
|
|
422
422
|
*/
|
|
423
423
|
type SerializeTopHints<H extends string> = H extends `${infer Top}.${string}` ? Top : H;
|
|
424
424
|
type SerializeSubHints<K extends string, H extends string> = H extends `${K}.${infer Rest}` ? Rest : never;
|
|
425
|
-
type SerializePropValue<T, K extends keyof T, H extends string, C extends TypeConfig = never> =
|
|
425
|
+
type SerializePropValue<T, K extends keyof T, H extends string, C extends TypeConfig = never> = K & string extends SerializeTopHints<H> ? NonNullable<T[K]> extends CollectionShape<infer U> ? SerializeDTO<U & object, SerializeSubHints<K & string, H>, never, C>[] : SerializeDTO<ExpandProperty<T[K]>, SerializeSubHints<K & string, H>, never, C> | Extract<T[K], null | undefined> : EntityDTOProp<T, T[K], C>;
|
|
426
426
|
export type SerializeDTO<T, H extends string = never, E extends string = never, C extends TypeConfig = never> = string extends H ? EntityDTOFlat<T, C> : {
|
|
427
427
|
[K in keyof T as ExcludeHidden<T, K> & CleanKeys<T, K> & (IsNever<E> extends true ? K : Exclude<K, E>)]: SerializePropValue<T, K, H, C> | Extract<T[K], null | undefined>;
|
|
428
428
|
};
|
|
@@ -975,7 +975,7 @@ type ExtractStringKeys<T> = {
|
|
|
975
975
|
* Simplified to just check `T extends object` since ExtractType handles the unwrapping.
|
|
976
976
|
*/
|
|
977
977
|
type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<ExtractType<T>> | E : never;
|
|
978
|
-
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> :
|
|
978
|
+
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> : K extends E ? keyof T : never;
|
|
979
979
|
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
980
980
|
type RelationKeys<T> = T extends object ? {
|
|
981
981
|
[K in keyof T]-?: CleanKeys<T, K, true>;
|
|
@@ -985,12 +985,12 @@ export type UnboxArray<T> = T extends any[] ? ArrayElement<T> : T;
|
|
|
985
985
|
export type ArrayElement<ArrayType extends unknown[]> = ArrayType extends (infer ElementType)[] ? ElementType : never;
|
|
986
986
|
export type ExpandProperty<T> = T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
|
|
987
987
|
type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
|
|
988
|
-
type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? T extends true ? true : false : false;
|
|
989
|
-
type StringLiteral<T> = T extends string ? string extends T ? never : T : never;
|
|
990
|
-
type Prefix<T, K> = K extends `${infer S}.${string}` ? S :
|
|
988
|
+
type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? (T extends true ? true : false) : false;
|
|
989
|
+
type StringLiteral<T> = T extends string ? (string extends T ? never : T) : never;
|
|
990
|
+
type Prefix<T, K> = K extends `${infer S}.${string}` ? S : K extends '*' ? keyof T : K;
|
|
991
991
|
type IsPrefixedExclude<T, K extends keyof T, E extends string> = K extends E ? never : K;
|
|
992
|
-
export type IsPrefixed<T, K extends keyof T, L extends string, E extends string = never> = IsNever<E> extends false ? IsPrefixedExclude<T, K, E> : K extends symbol ? never : IsTrue<L> extends true ?
|
|
993
|
-
type Suffix<Key, Hint extends string, All = true | '*'> = Hint extends `${infer Pref}.${infer Suf}` ?
|
|
992
|
+
export type IsPrefixed<T, K extends keyof T, L extends string, E extends string = never> = IsNever<E> extends false ? IsPrefixedExclude<T, K, E> : K extends symbol ? never : IsTrue<L> extends true ? T[K] & {} extends LoadableShape ? K : never : IsNever<StringLiteral<L>> extends true ? never : '*' extends L ? K : K extends Prefix<T, L> ? K : K extends PrimaryProperty<T> ? K : never;
|
|
993
|
+
type Suffix<Key, Hint extends string, All = true | '*'> = Hint extends `${infer Pref}.${infer Suf}` ? Pref extends Key ? Suf : never : Hint extends All ? Hint : never;
|
|
994
994
|
export type IsSubset<T, U> = keyof U extends keyof T ? {} : string extends keyof U ? {} : {
|
|
995
995
|
[K in keyof U as K extends keyof T ? never : CleanKeys<U, K>]: never;
|
|
996
996
|
};
|
package/typings.js
CHANGED
|
@@ -31,11 +31,9 @@ export class EntityMetadata {
|
|
|
31
31
|
Object.assign(this, meta);
|
|
32
32
|
const name = meta.className ?? meta.name;
|
|
33
33
|
if (!this.class && name) {
|
|
34
|
-
const Class = this.extends === BaseEntity
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
: ({ [name]: class {
|
|
38
|
-
} })[name];
|
|
34
|
+
const Class = this.extends === BaseEntity ? { [name]: class extends BaseEntity {
|
|
35
|
+
} }[name] : { [name]: class {
|
|
36
|
+
} }[name];
|
|
39
37
|
this.class = Class;
|
|
40
38
|
}
|
|
41
39
|
}
|
|
@@ -108,9 +106,7 @@ export class EntityMetadata {
|
|
|
108
106
|
*/
|
|
109
107
|
createSchemaColumnMappingObject() {
|
|
110
108
|
// For TPT entities, only include properties that belong to this entity's table
|
|
111
|
-
const props = this.inheritanceType === 'tpt' && this.ownProps
|
|
112
|
-
? this.ownProps
|
|
113
|
-
: Object.values(this.properties);
|
|
109
|
+
const props = this.inheritanceType === 'tpt' && this.ownProps ? this.ownProps : Object.values(this.properties);
|
|
114
110
|
return props.reduce((o, prop) => {
|
|
115
111
|
if (prop.fieldNames) {
|
|
116
112
|
o[prop.name] = prop.fieldNames[0];
|
|
@@ -208,7 +204,11 @@ export class EntityMetadata {
|
|
|
208
204
|
const hydrator = wrapped.hydrator;
|
|
209
205
|
const entity = Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
|
|
210
206
|
const old = Reference.unwrapReference(wrapped.__data[prop.name]);
|
|
211
|
-
if (old &&
|
|
207
|
+
if (old &&
|
|
208
|
+
old !== entity &&
|
|
209
|
+
prop.kind === ReferenceKind.MANY_TO_ONE &&
|
|
210
|
+
prop.inversedBy &&
|
|
211
|
+
old[prop.inversedBy]) {
|
|
212
212
|
old[prop.inversedBy].removeWithoutPropagation(this);
|
|
213
213
|
}
|
|
214
214
|
wrapped.__data[prop.name] = Reference.wrapReference(val, prop);
|
|
@@ -27,10 +27,10 @@ export class ChangeSet {
|
|
|
27
27
|
else {
|
|
28
28
|
this.primaryKey = this.originalEntity[this.meta.primaryKeys[0]];
|
|
29
29
|
}
|
|
30
|
-
if (!this.meta.compositePK
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
if (!this.meta.compositePK &&
|
|
31
|
+
this.meta.getPrimaryProp().targetMeta?.compositePK &&
|
|
32
|
+
typeof this.primaryKey === 'object' &&
|
|
33
|
+
this.primaryKey !== null) {
|
|
34
34
|
this.primaryKey = this.meta.getPrimaryProp().targetMeta.primaryKeys.map(childPK => {
|
|
35
35
|
return this.primaryKey[childPK];
|
|
36
36
|
});
|
|
@@ -31,7 +31,8 @@ export class ChangeSetComputer {
|
|
|
31
31
|
const map = new Map();
|
|
32
32
|
// Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
|
|
33
33
|
// to the `map` as we want to apply those only if something else changed.
|
|
34
|
-
if (type === ChangeSetType.CREATE) {
|
|
34
|
+
if (type === ChangeSetType.CREATE) {
|
|
35
|
+
// run update hooks only after we know there are other changes
|
|
35
36
|
for (const prop of meta.hydrateProps) {
|
|
36
37
|
this.processPropertyInitializers(entity, prop, type, map);
|
|
37
38
|
}
|
|
@@ -74,10 +75,10 @@ export class ChangeSetComputer {
|
|
|
74
75
|
* Traverses entity graph and executes `onCreate` and `onUpdate` methods, assigning the values to given properties.
|
|
75
76
|
*/
|
|
76
77
|
processPropertyInitializers(entity, prop, type, map, nested) {
|
|
77
|
-
if (prop.onCreate
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
if (prop.onCreate &&
|
|
79
|
+
type === ChangeSetType.CREATE &&
|
|
80
|
+
(entity[prop.name] == null ||
|
|
81
|
+
(Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
|
|
81
82
|
entity[prop.name] = prop.onCreate(entity, this.em);
|
|
82
83
|
}
|
|
83
84
|
if (prop.onUpdate && type === ChangeSetType.UPDATE) {
|
|
@@ -120,7 +121,8 @@ export class ChangeSetComputer {
|
|
|
120
121
|
targets.forEach(([t]) => this.processProperty(changeSet, prop, t));
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
|
-
if (Utils.isCollection(target)) {
|
|
124
|
+
if (Utils.isCollection(target)) {
|
|
125
|
+
// m:n or 1:m
|
|
124
126
|
this.processToMany(prop, changeSet);
|
|
125
127
|
}
|
|
126
128
|
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
@@ -49,7 +49,10 @@ export class ChangeSetPersister {
|
|
|
49
49
|
// For STI with conflicting fieldNames (renamedFrom properties), we can't batch mixed child types
|
|
50
50
|
const hasSTIConflicts = meta.root.props.some(p => p.renamedFrom);
|
|
51
51
|
const hasMixedTypes = hasSTIConflicts && changeSets.some(cs => cs.meta.class !== meta.class);
|
|
52
|
-
if (batched &&
|
|
52
|
+
if (batched &&
|
|
53
|
+
changeSets.length > 1 &&
|
|
54
|
+
!hasMixedTypes &&
|
|
55
|
+
this.config.get('useBatchUpdates', this.platform.usesBatchUpdates())) {
|
|
53
56
|
return this.persistManagedEntities(meta, changeSets, options);
|
|
54
57
|
}
|
|
55
58
|
for (const changeSet of changeSets) {
|
|
@@ -238,7 +241,9 @@ export class ChangeSetPersister {
|
|
|
238
241
|
// some drivers might be returning bigint PKs as numbers when the number is small enough,
|
|
239
242
|
// but we need to have it as string so comparison works in change set tracking, so instead
|
|
240
243
|
// of using the raw value from db, we convert it back to the db value explicitly
|
|
241
|
-
value = prop.customType
|
|
244
|
+
value = prop.customType
|
|
245
|
+
? prop.customType.convertToDatabaseValue(insertId, this.platform, { mode: 'serialization' })
|
|
246
|
+
: value;
|
|
242
247
|
changeSet.payload[wrapped.__meta.primaryKeys[0]] = value;
|
|
243
248
|
if (wrapped.__identifier && !Array.isArray(wrapped.__identifier)) {
|
|
244
249
|
wrapped.__identifier.setValue(value);
|
|
@@ -268,7 +273,8 @@ export class ChangeSetPersister {
|
|
|
268
273
|
options = this.prepareOptions(meta, options, {
|
|
269
274
|
convertCustomTypes: false,
|
|
270
275
|
});
|
|
271
|
-
if (meta.concurrencyCheckKeys.size === 0 &&
|
|
276
|
+
if (meta.concurrencyCheckKeys.size === 0 &&
|
|
277
|
+
(!meta.versionProperty || changeSet.entity[meta.versionProperty] == null)) {
|
|
272
278
|
return this.driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
|
|
273
279
|
}
|
|
274
280
|
if (meta.versionProperty) {
|
|
@@ -278,7 +284,8 @@ export class ChangeSetPersister {
|
|
|
278
284
|
return this.driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
|
|
279
285
|
}
|
|
280
286
|
async checkOptimisticLocks(meta, changeSets, options) {
|
|
281
|
-
if (meta.concurrencyCheckKeys.size === 0 &&
|
|
287
|
+
if (meta.concurrencyCheckKeys.size === 0 &&
|
|
288
|
+
(!meta.versionProperty || changeSets.every(cs => cs.entity[meta.versionProperty] == null))) {
|
|
282
289
|
return;
|
|
283
290
|
}
|
|
284
291
|
// skip entity references as they don't have version values loaded
|
|
@@ -344,9 +351,7 @@ export class ChangeSetPersister {
|
|
|
344
351
|
});
|
|
345
352
|
// reload generated columns
|
|
346
353
|
if (!this.usesReturningStatement) {
|
|
347
|
-
meta.props
|
|
348
|
-
.filter(prop => prop.generated && !prop.primary)
|
|
349
|
-
.forEach(prop => reloadProps.push(prop));
|
|
354
|
+
meta.props.filter(prop => prop.generated && !prop.primary).forEach(prop => reloadProps.push(prop));
|
|
350
355
|
reloadProps.push(...returning);
|
|
351
356
|
}
|
|
352
357
|
}
|
|
@@ -407,7 +412,7 @@ export class ChangeSetPersister {
|
|
|
407
412
|
return;
|
|
408
413
|
}
|
|
409
414
|
if (prop.kind === ReferenceKind.MANY_TO_MANY && Array.isArray(value)) {
|
|
410
|
-
changeSet.payload[prop.name] = value.map(val => val instanceof EntityIdentifier ? val.getValue() : val);
|
|
415
|
+
changeSet.payload[prop.name] = value.map(val => (val instanceof EntityIdentifier ? val.getValue() : val));
|
|
411
416
|
return;
|
|
412
417
|
}
|
|
413
418
|
if (prop.name in changeSet.payload) {
|
|
@@ -78,11 +78,13 @@ export class CommitOrderCalculator {
|
|
|
78
78
|
for (const edge of node.dependencies.values()) {
|
|
79
79
|
const target = this.nodes.get(edge.to);
|
|
80
80
|
switch (target.state) {
|
|
81
|
-
case 2 /* NodeState.VISITED */:
|
|
81
|
+
case 2 /* NodeState.VISITED */:
|
|
82
|
+
break; // Do nothing, since node was already visited
|
|
82
83
|
case 1 /* NodeState.IN_PROGRESS */:
|
|
83
84
|
this.visitOpenNode(node, target, edge);
|
|
84
85
|
break;
|
|
85
|
-
case 0 /* NodeState.NOT_VISITED */:
|
|
86
|
+
case 0 /* NodeState.NOT_VISITED */:
|
|
87
|
+
this.visit(target);
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
if (node.state !== 2 /* NodeState.VISITED */) {
|
|
@@ -72,7 +72,13 @@ export declare class UnitOfWork {
|
|
|
72
72
|
getRemoveStack(): Set<AnyEntity>;
|
|
73
73
|
getChangeSets(): ChangeSet<AnyEntity>[];
|
|
74
74
|
getCollectionUpdates(): Collection<AnyEntity>[];
|
|
75
|
-
getExtraUpdates(): Set<[
|
|
75
|
+
getExtraUpdates(): Set<[
|
|
76
|
+
AnyEntity,
|
|
77
|
+
string | string[],
|
|
78
|
+
AnyEntity | AnyEntity[] | Reference<any> | Collection<any>,
|
|
79
|
+
ChangeSet<any> | undefined,
|
|
80
|
+
ChangeSetType
|
|
81
|
+
]>;
|
|
76
82
|
shouldAutoFlush<T extends object>(meta: EntityMetadata<T>): boolean;
|
|
77
83
|
clearActionsQueue(): void;
|
|
78
84
|
computeChangeSet<T extends object>(entity: T, type?: ChangeSetType): void;
|