@mikro-orm/core 7.0.0-dev.12 → 7.0.0-dev.120

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.
Files changed (207) hide show
  1. package/EntityManager.d.ts +85 -56
  2. package/EntityManager.js +332 -293
  3. package/MikroORM.d.ts +41 -32
  4. package/MikroORM.js +100 -140
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +1 -1
  7. package/cache/FileCacheAdapter.js +8 -7
  8. package/cache/GeneratedCacheAdapter.d.ts +0 -1
  9. package/cache/GeneratedCacheAdapter.js +0 -2
  10. package/cache/index.d.ts +0 -1
  11. package/cache/index.js +0 -1
  12. package/connections/Connection.d.ts +16 -7
  13. package/connections/Connection.js +23 -14
  14. package/drivers/DatabaseDriver.d.ts +25 -16
  15. package/drivers/DatabaseDriver.js +35 -19
  16. package/drivers/IDatabaseDriver.d.ts +38 -17
  17. package/entity/BaseEntity.d.ts +0 -1
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +95 -30
  20. package/entity/Collection.js +439 -99
  21. package/entity/EntityAssigner.d.ts +1 -1
  22. package/entity/EntityAssigner.js +26 -18
  23. package/entity/EntityFactory.d.ts +7 -0
  24. package/entity/EntityFactory.js +72 -53
  25. package/entity/EntityHelper.d.ts +2 -2
  26. package/entity/EntityHelper.js +30 -15
  27. package/entity/EntityLoader.d.ts +7 -6
  28. package/entity/EntityLoader.js +84 -72
  29. package/entity/EntityRepository.d.ts +1 -1
  30. package/entity/EntityRepository.js +2 -2
  31. package/entity/Reference.d.ts +6 -5
  32. package/entity/Reference.js +34 -9
  33. package/entity/WrappedEntity.d.ts +2 -7
  34. package/entity/WrappedEntity.js +3 -8
  35. package/entity/defineEntity.d.ts +568 -0
  36. package/entity/defineEntity.js +529 -0
  37. package/entity/index.d.ts +3 -2
  38. package/entity/index.js +3 -2
  39. package/entity/utils.d.ts +7 -0
  40. package/entity/utils.js +16 -4
  41. package/entity/validators.d.ts +11 -0
  42. package/entity/validators.js +65 -0
  43. package/enums.d.ts +21 -6
  44. package/enums.js +14 -1
  45. package/errors.d.ts +17 -9
  46. package/errors.js +41 -21
  47. package/events/EventManager.d.ts +2 -1
  48. package/events/EventManager.js +19 -11
  49. package/hydration/Hydrator.js +1 -2
  50. package/hydration/ObjectHydrator.d.ts +4 -4
  51. package/hydration/ObjectHydrator.js +50 -33
  52. package/index.d.ts +2 -2
  53. package/index.js +1 -2
  54. package/logging/DefaultLogger.d.ts +1 -1
  55. package/logging/DefaultLogger.js +1 -0
  56. package/logging/SimpleLogger.d.ts +1 -1
  57. package/logging/colors.d.ts +1 -1
  58. package/logging/colors.js +7 -6
  59. package/logging/index.d.ts +1 -0
  60. package/logging/index.js +1 -0
  61. package/logging/inspect.d.ts +2 -0
  62. package/logging/inspect.js +11 -0
  63. package/metadata/EntitySchema.d.ts +13 -17
  64. package/metadata/EntitySchema.js +67 -51
  65. package/metadata/MetadataDiscovery.d.ts +6 -10
  66. package/metadata/MetadataDiscovery.js +289 -298
  67. package/metadata/MetadataProvider.d.ts +11 -2
  68. package/metadata/MetadataProvider.js +46 -2
  69. package/metadata/MetadataStorage.d.ts +13 -11
  70. package/metadata/MetadataStorage.js +70 -37
  71. package/metadata/MetadataValidator.d.ts +2 -9
  72. package/metadata/MetadataValidator.js +22 -38
  73. package/metadata/discover-entities.d.ts +5 -0
  74. package/metadata/discover-entities.js +40 -0
  75. package/metadata/index.d.ts +1 -1
  76. package/metadata/index.js +1 -1
  77. package/metadata/types.d.ts +480 -0
  78. package/metadata/types.js +1 -0
  79. package/naming-strategy/AbstractNamingStrategy.d.ts +8 -4
  80. package/naming-strategy/AbstractNamingStrategy.js +8 -2
  81. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  82. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  83. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  84. package/naming-strategy/MongoNamingStrategy.js +6 -6
  85. package/naming-strategy/NamingStrategy.d.ts +14 -4
  86. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  87. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  88. package/not-supported.d.ts +2 -0
  89. package/not-supported.js +4 -0
  90. package/package.json +19 -11
  91. package/platforms/ExceptionConverter.js +1 -1
  92. package/platforms/Platform.d.ts +6 -13
  93. package/platforms/Platform.js +17 -43
  94. package/serialization/EntitySerializer.d.ts +5 -0
  95. package/serialization/EntitySerializer.js +47 -27
  96. package/serialization/EntityTransformer.js +28 -18
  97. package/serialization/SerializationContext.d.ts +6 -6
  98. package/serialization/SerializationContext.js +16 -13
  99. package/types/ArrayType.d.ts +1 -1
  100. package/types/ArrayType.js +2 -3
  101. package/types/BigIntType.d.ts +8 -6
  102. package/types/BigIntType.js +1 -1
  103. package/types/BlobType.d.ts +0 -1
  104. package/types/BlobType.js +0 -3
  105. package/types/BooleanType.d.ts +2 -1
  106. package/types/BooleanType.js +3 -0
  107. package/types/DecimalType.d.ts +6 -4
  108. package/types/DecimalType.js +3 -3
  109. package/types/DoubleType.js +2 -2
  110. package/types/EnumArrayType.js +1 -2
  111. package/types/JsonType.d.ts +1 -1
  112. package/types/JsonType.js +7 -2
  113. package/types/TinyIntType.js +1 -1
  114. package/types/Type.d.ts +2 -4
  115. package/types/Type.js +3 -3
  116. package/types/Uint8ArrayType.d.ts +0 -1
  117. package/types/Uint8ArrayType.js +1 -4
  118. package/types/index.d.ts +1 -1
  119. package/typings.d.ts +124 -86
  120. package/typings.js +50 -42
  121. package/unit-of-work/ChangeSet.d.ts +2 -6
  122. package/unit-of-work/ChangeSet.js +4 -5
  123. package/unit-of-work/ChangeSetComputer.d.ts +1 -3
  124. package/unit-of-work/ChangeSetComputer.js +14 -12
  125. package/unit-of-work/ChangeSetPersister.d.ts +5 -4
  126. package/unit-of-work/ChangeSetPersister.js +65 -33
  127. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  128. package/unit-of-work/CommitOrderCalculator.js +13 -13
  129. package/unit-of-work/UnitOfWork.d.ts +10 -3
  130. package/unit-of-work/UnitOfWork.js +139 -96
  131. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  132. package/utils/AbstractSchemaGenerator.js +18 -16
  133. package/utils/AsyncContext.d.ts +6 -0
  134. package/utils/AsyncContext.js +42 -0
  135. package/utils/Configuration.d.ts +753 -207
  136. package/utils/Configuration.js +145 -190
  137. package/utils/ConfigurationLoader.d.ts +1 -54
  138. package/utils/ConfigurationLoader.js +1 -352
  139. package/utils/Cursor.d.ts +0 -3
  140. package/utils/Cursor.js +9 -6
  141. package/utils/DataloaderUtils.d.ts +15 -5
  142. package/utils/DataloaderUtils.js +65 -17
  143. package/utils/EntityComparator.d.ts +13 -9
  144. package/utils/EntityComparator.js +85 -43
  145. package/utils/QueryHelper.d.ts +14 -6
  146. package/utils/QueryHelper.js +87 -25
  147. package/utils/RawQueryFragment.d.ts +48 -25
  148. package/utils/RawQueryFragment.js +66 -70
  149. package/utils/RequestContext.js +2 -2
  150. package/utils/TransactionContext.js +2 -2
  151. package/utils/TransactionManager.d.ts +65 -0
  152. package/utils/TransactionManager.js +223 -0
  153. package/utils/Utils.d.ts +12 -119
  154. package/utils/Utils.js +97 -373
  155. package/utils/clone.js +8 -23
  156. package/utils/env-vars.d.ts +7 -0
  157. package/utils/env-vars.js +97 -0
  158. package/utils/fs-utils.d.ts +32 -0
  159. package/utils/fs-utils.js +178 -0
  160. package/utils/index.d.ts +2 -1
  161. package/utils/index.js +2 -1
  162. package/utils/upsert-utils.d.ts +9 -4
  163. package/utils/upsert-utils.js +55 -4
  164. package/decorators/Check.d.ts +0 -3
  165. package/decorators/Check.js +0 -13
  166. package/decorators/CreateRequestContext.d.ts +0 -3
  167. package/decorators/CreateRequestContext.js +0 -32
  168. package/decorators/Embeddable.d.ts +0 -8
  169. package/decorators/Embeddable.js +0 -11
  170. package/decorators/Embedded.d.ts +0 -18
  171. package/decorators/Embedded.js +0 -18
  172. package/decorators/Entity.d.ts +0 -18
  173. package/decorators/Entity.js +0 -12
  174. package/decorators/Enum.d.ts +0 -9
  175. package/decorators/Enum.js +0 -16
  176. package/decorators/Filter.d.ts +0 -2
  177. package/decorators/Filter.js +0 -8
  178. package/decorators/Formula.d.ts +0 -4
  179. package/decorators/Formula.js +0 -15
  180. package/decorators/Indexed.d.ts +0 -19
  181. package/decorators/Indexed.js +0 -20
  182. package/decorators/ManyToMany.d.ts +0 -40
  183. package/decorators/ManyToMany.js +0 -14
  184. package/decorators/ManyToOne.d.ts +0 -30
  185. package/decorators/ManyToOne.js +0 -14
  186. package/decorators/OneToMany.d.ts +0 -28
  187. package/decorators/OneToMany.js +0 -17
  188. package/decorators/OneToOne.d.ts +0 -24
  189. package/decorators/OneToOne.js +0 -7
  190. package/decorators/PrimaryKey.d.ts +0 -8
  191. package/decorators/PrimaryKey.js +0 -20
  192. package/decorators/Property.d.ts +0 -250
  193. package/decorators/Property.js +0 -32
  194. package/decorators/Transactional.d.ts +0 -13
  195. package/decorators/Transactional.js +0 -28
  196. package/decorators/hooks.d.ts +0 -16
  197. package/decorators/hooks.js +0 -47
  198. package/decorators/index.d.ts +0 -17
  199. package/decorators/index.js +0 -17
  200. package/entity/ArrayCollection.d.ts +0 -116
  201. package/entity/ArrayCollection.js +0 -402
  202. package/entity/EntityValidator.d.ts +0 -19
  203. package/entity/EntityValidator.js +0 -150
  204. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  205. package/metadata/ReflectMetadataProvider.js +0 -44
  206. package/utils/resolveContextProvider.d.ts +0 -10
  207. package/utils/resolveContextProvider.js +0 -28
@@ -1,6 +1,8 @@
1
- import type { EntityData, EntityDictionary, EntityMetadata, EntityProperty, IMetadataStorage } from '../typings.js';
1
+ import type { EntityData, EntityDictionary, EntityMetadata, EntityName, EntityProperty, IMetadataStorage } from '../typings.js';
2
2
  import type { Platform } from '../platforms/Platform.js';
3
- type Comparator<T> = (a: T, b: T) => EntityData<T>;
3
+ type Comparator<T> = (a: T, b: T, options?: {
4
+ includeInverseSides?: boolean;
5
+ }) => EntityData<T>;
4
6
  type ResultMapper<T> = (result: EntityData<T>) => EntityData<T> | null;
5
7
  type SnapshotGenerator<T> = (entity: T) => EntityData<T>;
6
8
  type CompositeKeyPart = string | CompositeKeyPart[];
@@ -18,17 +20,19 @@ export declare class EntityComparator {
18
20
  /**
19
21
  * Computes difference between two entities.
20
22
  */
21
- diffEntities<T>(entityName: string, a: EntityData<T>, b: EntityData<T>): EntityData<T>;
22
- matching<T>(entityName: string, a: EntityData<T>, b: EntityData<T>): boolean;
23
+ diffEntities<T extends object>(entityName: EntityName<T>, a: EntityData<T>, b: EntityData<T>, options?: {
24
+ includeInverseSides?: boolean;
25
+ }): EntityData<T>;
26
+ matching<T extends object>(entityName: EntityName<T>, a: EntityData<T>, b: EntityData<T>): boolean;
23
27
  /**
24
28
  * Removes ORM specific code from entities and prepares it for serializing. Used before change set computation.
25
29
  * References will be mapped to primary keys, collections to arrays of primary keys.
26
30
  */
27
- prepareEntity<T>(entity: T): EntityData<T>;
31
+ prepareEntity<T extends object>(entity: T): EntityData<T>;
28
32
  /**
29
33
  * Maps database columns to properties.
30
34
  */
31
- mapResult<T>(entityName: string, result: EntityDictionary<T>): EntityData<T>;
35
+ mapResult<T>(meta: EntityMetadata<T>, result: EntityDictionary<T>): EntityData<T>;
32
36
  /**
33
37
  * @internal Highly performance-sensitive method.
34
38
  */
@@ -44,7 +48,7 @@ export declare class EntityComparator {
44
48
  /**
45
49
  * @internal Highly performance-sensitive method.
46
50
  */
47
- getSnapshotGenerator<T>(entityName: string): SnapshotGenerator<T>;
51
+ getSnapshotGenerator<T>(entityName: EntityName<T>): SnapshotGenerator<T>;
48
52
  /**
49
53
  * @internal
50
54
  */
@@ -60,7 +64,7 @@ export declare class EntityComparator {
60
64
  /**
61
65
  * @internal Highly performance-sensitive method.
62
66
  */
63
- getResultMapper<T>(entityName: string): ResultMapper<T>;
67
+ getResultMapper<T>(meta: EntityMetadata<T>): ResultMapper<T>;
64
68
  private getPropertyCondition;
65
69
  private getEmbeddedArrayPropertySnapshot;
66
70
  /**
@@ -74,7 +78,7 @@ export declare class EntityComparator {
74
78
  /**
75
79
  * @internal Highly performance-sensitive method.
76
80
  */
77
- getEntityComparator<T extends object>(entityName: string): Comparator<T>;
81
+ getEntityComparator<T extends object>(entityName: EntityName<T>): Comparator<T>;
78
82
  private getGenericComparator;
79
83
  private getPropertyComparator;
80
84
  private wrap;
@@ -2,7 +2,8 @@ import { clone } from './clone.js';
2
2
  import { ReferenceKind } from '../enums.js';
3
3
  import { compareArrays, compareBooleans, compareBuffers, compareObjects, equals, parseJsonSafe, Utils } from './Utils.js';
4
4
  import { JsonType } from '../types/JsonType.js';
5
- import { RawQueryFragment } from './RawQueryFragment.js';
5
+ import { Raw } from './RawQueryFragment.js';
6
+ import { EntityIdentifier } from '../entity/EntityIdentifier.js';
6
7
  export class EntityComparator {
7
8
  metadata;
8
9
  platform;
@@ -20,9 +21,9 @@ export class EntityComparator {
20
21
  /**
21
22
  * Computes difference between two entities.
22
23
  */
23
- diffEntities(entityName, a, b) {
24
+ diffEntities(entityName, a, b, options) {
24
25
  const comparator = this.getEntityComparator(entityName);
25
- return Utils.callCompiledFunction(comparator, a, b);
26
+ return Utils.callCompiledFunction(comparator, a, b, options);
26
27
  }
27
28
  matching(entityName, a, b) {
28
29
  const diff = this.diffEntities(entityName, a, b);
@@ -33,22 +34,22 @@ export class EntityComparator {
33
34
  * References will be mapped to primary keys, collections to arrays of primary keys.
34
35
  */
35
36
  prepareEntity(entity) {
36
- const generator = this.getSnapshotGenerator(entity.constructor.name);
37
+ const generator = this.getSnapshotGenerator(entity.constructor);
37
38
  return Utils.callCompiledFunction(generator, entity);
38
39
  }
39
40
  /**
40
41
  * Maps database columns to properties.
41
42
  */
42
- mapResult(entityName, result) {
43
- const mapper = this.getResultMapper(entityName);
43
+ mapResult(meta, result) {
44
+ const mapper = this.getResultMapper(meta);
44
45
  return Utils.callCompiledFunction(mapper, result);
45
46
  }
46
47
  /**
47
48
  * @internal Highly performance-sensitive method.
48
49
  */
49
50
  getPkGetter(meta) {
50
- const exists = this.pkGetters.get(meta.className);
51
- /* v8 ignore next 3 */
51
+ const exists = this.pkGetters.get(meta);
52
+ /* v8 ignore next */
52
53
  if (exists) {
53
54
  return exists;
54
55
  }
@@ -90,15 +91,15 @@ export class EntityComparator {
90
91
  const code = `// compiled pk serializer for entity ${meta.className}\n`
91
92
  + `return function(entity) {\n${lines.join('\n')}\n}`;
92
93
  const pkSerializer = Utils.createFunction(context, code);
93
- this.pkGetters.set(meta.className, pkSerializer);
94
+ this.pkGetters.set(meta, pkSerializer);
94
95
  return pkSerializer;
95
96
  }
96
97
  /**
97
98
  * @internal Highly performance-sensitive method.
98
99
  */
99
100
  getPkGetterConverted(meta) {
100
- const exists = this.pkGettersConverted.get(meta.className);
101
- /* v8 ignore next 3 */
101
+ const exists = this.pkGettersConverted.get(meta);
102
+ /* v8 ignore next */
102
103
  if (exists) {
103
104
  return exists;
104
105
  }
@@ -140,21 +141,22 @@ export class EntityComparator {
140
141
  const code = `// compiled pk getter (with converted custom types) for entity ${meta.className}\n`
141
142
  + `return function(entity) {\n${lines.join('\n')}\n}`;
142
143
  const pkSerializer = Utils.createFunction(context, code);
143
- this.pkGettersConverted.set(meta.className, pkSerializer);
144
+ this.pkGettersConverted.set(meta, pkSerializer);
144
145
  return pkSerializer;
145
146
  }
146
147
  /**
147
148
  * @internal Highly performance-sensitive method.
148
149
  */
149
150
  getPkSerializer(meta) {
150
- const exists = this.pkSerializers.get(meta.className);
151
- /* v8 ignore next 3 */
151
+ const exists = this.pkSerializers.get(meta);
152
+ /* v8 ignore next */
152
153
  if (exists) {
153
154
  return exists;
154
155
  }
155
156
  const lines = [];
156
157
  const context = new Map();
157
158
  context.set('getCompositeKeyValue', (val) => Utils.flatten(Utils.getCompositeKeyValue(val, meta, 'convertToDatabaseValue', this.platform)));
159
+ context.set('getPrimaryKeyHash', (val) => Utils.getPrimaryKeyHash(Utils.asArray(val)));
158
160
  if (meta.primaryKeys.length > 1) {
159
161
  lines.push(` const pks = entity.__helper.__pk ? getCompositeKeyValue(entity.__helper.__pk) : [`);
160
162
  meta.primaryKeys.forEach(pk => {
@@ -170,30 +172,39 @@ export class EntityComparator {
170
172
  }
171
173
  else {
172
174
  const pk = meta.primaryKeys[0];
173
- if (meta.properties[pk].kind !== ReferenceKind.SCALAR) {
175
+ const prop = meta.properties[pk];
176
+ if (prop.kind !== ReferenceKind.SCALAR) {
174
177
  lines.push(` if (entity${this.wrap(pk)} != null && (entity${this.wrap(pk)}.__entity || entity${this.wrap(pk)}.__reference)) return entity${this.wrap(pk)}.__helper.getSerializedPrimaryKey();`);
175
178
  }
176
179
  const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
177
180
  if (serializedPrimaryKey) {
178
181
  lines.push(` return '' + entity.${serializedPrimaryKey.name};`);
179
182
  }
180
- lines.push(` return '' + entity.${meta.primaryKeys[0]};`);
183
+ else if (prop.customType) {
184
+ const convertorKey = this.registerCustomType(meta.properties[pk], context);
185
+ const idx = this.tmpIndex++;
186
+ lines.push(` const val_${idx} = convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)});`);
187
+ lines.push(` return getPrimaryKeyHash(val_${idx});`);
188
+ }
189
+ else {
190
+ lines.push(` return '' + entity${this.wrap(pk)};`);
191
+ }
181
192
  }
182
193
  const code = `// compiled pk serializer for entity ${meta.className}\n`
183
194
  + `return function(entity) {\n${lines.join('\n')}\n}`;
184
195
  const pkSerializer = Utils.createFunction(context, code);
185
- this.pkSerializers.set(meta.className, pkSerializer);
196
+ this.pkSerializers.set(meta, pkSerializer);
186
197
  return pkSerializer;
187
198
  }
188
199
  /**
189
200
  * @internal Highly performance-sensitive method.
190
201
  */
191
202
  getSnapshotGenerator(entityName) {
192
- const exists = this.snapshotGenerators.get(entityName);
203
+ const meta = this.metadata.find(entityName);
204
+ const exists = this.snapshotGenerators.get(meta);
193
205
  if (exists) {
194
206
  return exists;
195
207
  }
196
- const meta = this.metadata.find(entityName);
197
208
  const lines = [];
198
209
  const context = new Map();
199
210
  context.set('clone', clone);
@@ -211,7 +222,7 @@ export class EntityComparator {
211
222
  .forEach(prop => lines.push(this.getPropertySnapshot(meta, prop, context, this.wrap(prop.name), this.wrap(prop.name), [prop.name])));
212
223
  const code = `return function(entity) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
213
224
  const snapshotGenerator = Utils.createFunction(context, code);
214
- this.snapshotGenerators.set(entityName, snapshotGenerator);
225
+ this.snapshotGenerators.set(meta, snapshotGenerator);
215
226
  return snapshotGenerator;
216
227
  }
217
228
  /**
@@ -261,12 +272,11 @@ export class EntityComparator {
261
272
  /**
262
273
  * @internal Highly performance-sensitive method.
263
274
  */
264
- getResultMapper(entityName) {
265
- const exists = this.mappers.get(entityName);
275
+ getResultMapper(meta) {
276
+ const exists = this.mappers.get(meta);
266
277
  if (exists) {
267
278
  return exists;
268
279
  }
269
- const meta = this.metadata.get(entityName);
270
280
  const lines = [];
271
281
  const context = new Map();
272
282
  const tz = this.platform.getTimezone();
@@ -274,10 +284,14 @@ export class EntityComparator {
274
284
  lines.push(`${padding} if (${value} == null || ${value} instanceof Date) {`);
275
285
  lines.push(`${padding} ${key} = ${value};`);
276
286
  if (!tz || tz === 'local') {
287
+ lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
288
+ lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
277
289
  lines.push(`${padding} } else {`);
278
290
  lines.push(`${padding} ${key} = parseDate(${value});`);
279
291
  }
280
292
  else {
293
+ lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
294
+ lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
281
295
  lines.push(`${padding} } else if (typeof ${value} === 'number' || ${value}.includes('+') || ${value}.lastIndexOf('-') > 10 || ${value}.endsWith('Z')) {`);
282
296
  lines.push(`${padding} ${key} = parseDate(${value});`);
283
297
  lines.push(`${padding} } else {`);
@@ -321,9 +335,9 @@ export class EntityComparator {
321
335
  context.set(`mapEmbeddedResult_${idx}`, (data) => {
322
336
  const item = parseJsonSafe(data);
323
337
  if (Array.isArray(item)) {
324
- return item.map(row => row == null ? row : this.getResultMapper(prop.type)(row));
338
+ return item.map(row => row == null ? row : this.getResultMapper(prop.targetMeta)(row));
325
339
  }
326
- return item == null ? item : this.getResultMapper(prop.type)(item);
340
+ return item == null ? item : this.getResultMapper(prop.targetMeta)(item);
327
341
  });
328
342
  lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
329
343
  lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : mapEmbeddedResult_${idx}(${this.propName(prop.fieldNames[0])});`);
@@ -352,11 +366,11 @@ export class EntityComparator {
352
366
  else {
353
367
  mapEntityProperties(meta);
354
368
  }
355
- lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k]) ret[k] = result[k]; }`);
369
+ lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k] && ret[k] === undefined) ret[k] = result[k]; }`);
356
370
  const code = `// compiled mapper for entity ${meta.className}\n`
357
371
  + `return function(result) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
358
372
  const resultMapper = Utils.createFunction(context, code);
359
- this.mappers.set(entityName, resultMapper);
373
+ this.mappers.set(meta, resultMapper);
360
374
  return resultMapper;
361
375
  }
362
376
  getPropertyCondition(path) {
@@ -407,11 +421,21 @@ export class EntityComparator {
407
421
  }
408
422
  getEmbeddedPropertySnapshot(meta, prop, context, level, path, dataKey, object = prop.object) {
409
423
  const padding = ' '.repeat(level * 2);
424
+ const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
410
425
  let ret = `${level === 1 ? '' : '\n'}`;
411
426
  if (object) {
412
- const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
413
427
  ret += `${padding}if (${nullCond}) ret${dataKey} = null;\n`;
414
428
  }
429
+ else {
430
+ ret += `${padding}if (${nullCond}) {\n`;
431
+ ret += meta.props.filter(p => p.embedded?.[0] === prop.name
432
+ // object for JSON embeddable
433
+ && (p.object || (p.persist !== false))).map(childProp => {
434
+ const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
435
+ return `${padding} ret${childDataKey} = null;`;
436
+ }).join('\n') + `\n`;
437
+ ret += `${padding}}\n`;
438
+ }
415
439
  const cond = `entity${path.map(k => this.wrap(k)).join('')} != null`;
416
440
  ret += `${padding}if (${cond}) {\n`;
417
441
  if (object) {
@@ -456,8 +480,8 @@ export class EntityComparator {
456
480
  registerCustomType(prop, context) {
457
481
  const convertorKey = this.safeKey(prop.name);
458
482
  context.set(`convertToDatabaseValue_${convertorKey}`, (val) => {
459
- /* v8 ignore next 3 */
460
- if (RawQueryFragment.isKnownFragment(val)) {
483
+ /* v8 ignore next */
484
+ if (Raw.isKnownFragment(val)) {
461
485
  return val;
462
486
  }
463
487
  return prop.customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' });
@@ -494,8 +518,11 @@ export class EntityComparator {
494
518
  return val;
495
519
  };
496
520
  context.set('toArray', toArray);
521
+ context.set('EntityIdentifier', EntityIdentifier);
497
522
  ret += ` if (entity${entityKey} === null) {\n`;
498
523
  ret += ` ret${dataKey} = null;\n`;
524
+ ret += ` } else if (entity${entityKey}?.__helper.__identifier && !entity${entityKey}.__helper.hasPrimaryKey()) {\n`;
525
+ ret += ` ret${dataKey} = entity${entityKey}?.__helper.__identifier;\n`;
499
526
  ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
500
527
  ret += ` ret${dataKey} = toArray(entity${entityKey}.__helper.getPrimaryKey(true));\n`;
501
528
  ret += ` }\n`;
@@ -519,11 +546,11 @@ export class EntityComparator {
519
546
  * @internal Highly performance-sensitive method.
520
547
  */
521
548
  getEntityComparator(entityName) {
522
- const exists = this.comparators.get(entityName);
549
+ const meta = this.metadata.find(entityName);
550
+ const exists = this.comparators.get(meta);
523
551
  if (exists) {
524
552
  return exists;
525
553
  }
526
- const meta = this.metadata.find(entityName);
527
554
  const lines = [];
528
555
  const context = new Map();
529
556
  context.set('compareArrays', compareArrays);
@@ -531,17 +558,27 @@ export class EntityComparator {
531
558
  context.set('compareBuffers', compareBuffers);
532
559
  context.set('compareObjects', compareObjects);
533
560
  context.set('equals', equals);
534
- meta.comparableProps.forEach(prop => {
561
+ for (const prop of meta.comparableProps) {
535
562
  lines.push(this.getPropertyComparator(prop, context));
536
- });
563
+ }
564
+ // also compare 1:1 inverse sides, important for `factory.mergeData`
565
+ lines.push(`if (options?.includeInverseSides) {`);
566
+ for (const prop of meta.bidirectionalRelations) {
567
+ if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner && prop.hydrate !== false) {
568
+ lines.push(this.getPropertyComparator(prop, context));
569
+ }
570
+ }
571
+ lines.push(`}`);
537
572
  const code = `// compiled comparator for entity ${meta.className}\n`
538
- + `return function(last, current) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
573
+ + `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
539
574
  const comparator = Utils.createFunction(context, code);
540
- this.comparators.set(entityName, comparator);
575
+ this.comparators.set(meta, comparator);
541
576
  return comparator;
542
577
  }
543
578
  getGenericComparator(prop, cond) {
544
- return ` if (current${prop} == null && last${prop} == null) {\n\n` +
579
+ return ` if (current${prop} === null && last${prop} === undefined) {\n` +
580
+ ` diff${prop} = current${prop};\n` +
581
+ ` } else if (current${prop} == null && last${prop} == null) {\n\n` +
545
582
  ` } else if ((current${prop} != null && last${prop} == null) || (current${prop} == null && last${prop} != null)) {\n` +
546
583
  ` diff${prop} = current${prop};\n` +
547
584
  ` } else if (${cond}) {\n` +
@@ -551,18 +588,23 @@ export class EntityComparator {
551
588
  getPropertyComparator(prop, context) {
552
589
  let type = prop.type.toLowerCase();
553
590
  if (prop.kind !== ReferenceKind.SCALAR && prop.kind !== ReferenceKind.EMBEDDED) {
554
- const meta2 = this.metadata.find(prop.type);
591
+ const meta2 = prop.targetMeta;
555
592
  if (meta2.primaryKeys.length > 1) {
556
593
  type = 'array';
557
594
  }
558
595
  else {
559
- type = meta2.properties[meta2.primaryKeys[0]].type.toLowerCase();
596
+ type = meta2.getPrimaryProp().type.toLowerCase();
560
597
  }
561
598
  }
562
599
  if (prop.customType) {
563
600
  if (prop.customType.compareValues) {
564
601
  const idx = this.tmpIndex++;
565
- context.set(`compareValues_${idx}`, (a, b) => prop.customType.compareValues(a, b));
602
+ context.set(`compareValues_${idx}`, (a, b) => {
603
+ if (Raw.isKnownFragment(a) || Raw.isKnownFragment(b)) {
604
+ return Raw.getKnownFragment(a) === Raw.getKnownFragment(b);
605
+ }
606
+ return prop.customType.compareValues(a, b);
607
+ });
566
608
  return this.getGenericComparator(this.wrap(prop.name), `!compareValues_${idx}(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
567
609
  }
568
610
  type = prop.customType.compareAsType().toLowerCase();
@@ -582,10 +624,10 @@ export class EntityComparator {
582
624
  if (['buffer', 'uint8array'].includes(type)) {
583
625
  return this.getGenericComparator(this.wrap(prop.name), `!compareBuffers(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
584
626
  }
585
- if (['date'].includes(type)) {
627
+ if (type === 'date') {
586
628
  return this.getGenericComparator(this.wrap(prop.name), `last${this.wrap(prop.name)}.valueOf() !== current${this.wrap(prop.name)}.valueOf()`);
587
629
  }
588
- if (['objectid'].includes(type)) {
630
+ if (type === 'objectid') {
589
631
  // We might be comparing PK to object, in case we compare with cached data of populated entity
590
632
  // in such case we just ignore the comparison and fallback to `equals()` (which will still mark
591
633
  // it as not equal as we compare PK to plain object).
@@ -607,7 +649,7 @@ export class EntityComparator {
607
649
  * perf: used to generate list of comparable properties during discovery, so we speed up the runtime comparison
608
650
  */
609
651
  static isComparable(prop, root) {
610
- const virtual = prop.persist === false || prop.generated;
652
+ const virtual = prop.persist === false || (prop.generated && !prop.primary);
611
653
  const inverse = prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner;
612
654
  const discriminator = prop.name === root.discriminatorColumn;
613
655
  const collection = prop.kind === ReferenceKind.ONE_TO_MANY || prop.kind === ReferenceKind.MANY_TO_MANY;
@@ -1,14 +1,22 @@
1
- import type { Dictionary, EntityMetadata, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
1
+ import type { Dictionary, EntityMetadata, EntityName, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
2
2
  import type { Platform } from '../platforms/Platform.js';
3
3
  import type { MetadataStorage } from '../metadata/MetadataStorage.js';
4
+ import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
5
+ /** @internal */
4
6
  export declare class QueryHelper {
5
7
  static readonly SUPPORTED_OPERATORS: string[];
6
8
  static processParams(params: unknown): any;
7
- static processObjectParams<T extends object>(params?: T): T;
9
+ static processObjectParams<T extends Dictionary>(params?: T): T;
10
+ /**
11
+ * converts `{ account: { $or: [ [Object], [Object] ] } }`
12
+ * to `{ $or: [ { account: [Object] }, { account: [Object] } ] }`
13
+ */
14
+ static liftGroupOperators<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): string | undefined;
8
15
  static inlinePrimaryKeyObjects<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): boolean;
9
16
  static processWhere<T extends object>(options: ProcessWhereOptions<T>): FilterQuery<T>;
10
- static getActiveFilters(entityName: string, options: Dictionary<boolean | Dictionary> | string[] | boolean, filters: Dictionary<FilterDef>): FilterDef[];
11
- static isFilterActive(entityName: string, filterName: string, filter: FilterDef, options: Dictionary<boolean | Dictionary>): boolean;
17
+ static getActiveFilters<T>(meta: EntityMetadata<T>, options: FilterOptions | undefined, filters: Dictionary<FilterDef>): FilterDef[];
18
+ static mergePropertyFilters(propFilters: FilterOptions | undefined, options: FilterOptions | undefined): FilterOptions | undefined;
19
+ static isFilterActive<T>(meta: EntityMetadata<T>, filterName: string, filter: FilterDef, options: Dictionary<boolean | Dictionary>): boolean;
12
20
  static processCustomType<T extends object>(prop: EntityProperty<T>, cond: FilterQuery<T>, platform: Platform, key?: string, fromQuery?: boolean): FilterQuery<T>;
13
21
  private static isSupportedOperator;
14
22
  private static processJsonCondition;
@@ -17,11 +25,11 @@ export declare class QueryHelper {
17
25
  }
18
26
  interface ProcessWhereOptions<T> {
19
27
  where: FilterQuery<T>;
20
- entityName: string;
28
+ entityName: EntityName<T>;
21
29
  metadata: MetadataStorage;
22
30
  platform: Platform;
23
31
  aliased?: boolean;
24
- aliasMap?: Dictionary<string>;
32
+ aliasMap?: Dictionary<EntityName>;
25
33
  convertCustomTypes?: boolean;
26
34
  root?: boolean;
27
35
  type?: 'where' | 'orderBy';