@mikro-orm/core 7.0.0-dev.21 → 7.0.0-dev.211

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 (211) hide show
  1. package/EntityManager.d.ts +99 -57
  2. package/EntityManager.js +302 -276
  3. package/MikroORM.d.ts +44 -35
  4. package/MikroORM.js +103 -143
  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 +80 -35
  16. package/drivers/IDatabaseDriver.d.ts +44 -17
  17. package/entity/BaseEntity.d.ts +2 -2
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +94 -29
  20. package/entity/Collection.js +434 -97
  21. package/entity/EntityAssigner.d.ts +1 -1
  22. package/entity/EntityAssigner.js +26 -18
  23. package/entity/EntityFactory.d.ts +13 -1
  24. package/entity/EntityFactory.js +84 -53
  25. package/entity/EntityHelper.d.ts +2 -2
  26. package/entity/EntityHelper.js +40 -15
  27. package/entity/EntityLoader.d.ts +6 -6
  28. package/entity/EntityLoader.js +119 -82
  29. package/entity/EntityRepository.d.ts +24 -4
  30. package/entity/EntityRepository.js +8 -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 +594 -0
  36. package/entity/defineEntity.js +533 -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 -5
  44. package/enums.js +15 -1
  45. package/errors.d.ts +23 -9
  46. package/errors.js +59 -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 +52 -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 +40 -23
  64. package/metadata/EntitySchema.js +81 -34
  65. package/metadata/MetadataDiscovery.d.ts +7 -10
  66. package/metadata/MetadataDiscovery.js +391 -331
  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 +17 -9
  72. package/metadata/MetadataValidator.js +97 -40
  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 +502 -0
  78. package/metadata/types.js +1 -0
  79. package/naming-strategy/AbstractNamingStrategy.d.ts +12 -4
  80. package/naming-strategy/AbstractNamingStrategy.js +14 -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 +24 -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 +18 -11
  91. package/platforms/ExceptionConverter.js +1 -1
  92. package/platforms/Platform.d.ts +7 -13
  93. package/platforms/Platform.js +20 -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 +290 -137
  120. package/typings.js +59 -44
  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 +26 -13
  125. package/unit-of-work/ChangeSetPersister.d.ts +5 -4
  126. package/unit-of-work/ChangeSetPersister.js +70 -34
  127. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  128. package/unit-of-work/CommitOrderCalculator.js +13 -13
  129. package/unit-of-work/IdentityMap.d.ts +12 -0
  130. package/unit-of-work/IdentityMap.js +39 -1
  131. package/unit-of-work/UnitOfWork.d.ts +23 -3
  132. package/unit-of-work/UnitOfWork.js +175 -98
  133. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  134. package/utils/AbstractSchemaGenerator.js +18 -16
  135. package/utils/AsyncContext.d.ts +6 -0
  136. package/utils/AsyncContext.js +42 -0
  137. package/utils/Configuration.d.ts +785 -207
  138. package/utils/Configuration.js +147 -190
  139. package/utils/ConfigurationLoader.d.ts +1 -54
  140. package/utils/ConfigurationLoader.js +1 -352
  141. package/utils/Cursor.d.ts +0 -3
  142. package/utils/Cursor.js +27 -11
  143. package/utils/DataloaderUtils.d.ts +15 -5
  144. package/utils/DataloaderUtils.js +64 -30
  145. package/utils/EntityComparator.d.ts +13 -9
  146. package/utils/EntityComparator.js +101 -42
  147. package/utils/QueryHelper.d.ts +14 -6
  148. package/utils/QueryHelper.js +87 -25
  149. package/utils/RawQueryFragment.d.ts +48 -25
  150. package/utils/RawQueryFragment.js +66 -70
  151. package/utils/RequestContext.js +2 -2
  152. package/utils/TransactionContext.js +2 -2
  153. package/utils/TransactionManager.d.ts +65 -0
  154. package/utils/TransactionManager.js +223 -0
  155. package/utils/Utils.d.ts +13 -126
  156. package/utils/Utils.js +100 -391
  157. package/utils/clone.js +8 -23
  158. package/utils/env-vars.d.ts +7 -0
  159. package/utils/env-vars.js +97 -0
  160. package/utils/fs-utils.d.ts +32 -0
  161. package/utils/fs-utils.js +178 -0
  162. package/utils/index.d.ts +2 -1
  163. package/utils/index.js +2 -1
  164. package/utils/upsert-utils.d.ts +9 -4
  165. package/utils/upsert-utils.js +55 -4
  166. package/decorators/Check.d.ts +0 -3
  167. package/decorators/Check.js +0 -13
  168. package/decorators/CreateRequestContext.d.ts +0 -3
  169. package/decorators/CreateRequestContext.js +0 -32
  170. package/decorators/Embeddable.d.ts +0 -8
  171. package/decorators/Embeddable.js +0 -11
  172. package/decorators/Embedded.d.ts +0 -12
  173. package/decorators/Embedded.js +0 -18
  174. package/decorators/Entity.d.ts +0 -18
  175. package/decorators/Entity.js +0 -12
  176. package/decorators/Enum.d.ts +0 -9
  177. package/decorators/Enum.js +0 -16
  178. package/decorators/Filter.d.ts +0 -2
  179. package/decorators/Filter.js +0 -8
  180. package/decorators/Formula.d.ts +0 -4
  181. package/decorators/Formula.js +0 -15
  182. package/decorators/Indexed.d.ts +0 -19
  183. package/decorators/Indexed.js +0 -20
  184. package/decorators/ManyToMany.d.ts +0 -40
  185. package/decorators/ManyToMany.js +0 -14
  186. package/decorators/ManyToOne.d.ts +0 -32
  187. package/decorators/ManyToOne.js +0 -14
  188. package/decorators/OneToMany.d.ts +0 -28
  189. package/decorators/OneToMany.js +0 -17
  190. package/decorators/OneToOne.d.ts +0 -26
  191. package/decorators/OneToOne.js +0 -7
  192. package/decorators/PrimaryKey.d.ts +0 -8
  193. package/decorators/PrimaryKey.js +0 -20
  194. package/decorators/Property.d.ts +0 -250
  195. package/decorators/Property.js +0 -32
  196. package/decorators/Transactional.d.ts +0 -13
  197. package/decorators/Transactional.js +0 -28
  198. package/decorators/hooks.d.ts +0 -16
  199. package/decorators/hooks.js +0 -47
  200. package/decorators/index.d.ts +0 -17
  201. package/decorators/index.js +0 -17
  202. package/entity/ArrayCollection.d.ts +0 -116
  203. package/entity/ArrayCollection.js +0 -402
  204. package/entity/EntityValidator.d.ts +0 -19
  205. package/entity/EntityValidator.js +0 -150
  206. package/exports.d.ts +0 -24
  207. package/exports.js +0 -23
  208. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  209. package/metadata/ReflectMetadataProvider.js +0 -44
  210. package/utils/resolveContextProvider.d.ts +0 -10
  211. 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' });
@@ -486,6 +510,23 @@ export class EntityComparator {
486
510
  ret += ` ret${dataKey} = entity${entityKey};\n`;
487
511
  }
488
512
  }
513
+ else if (prop.targetKey) {
514
+ // When targetKey is set, extract that property value instead of the PK
515
+ const targetProp = prop.targetMeta?.properties[prop.targetKey];
516
+ ret += ` if (entity${entityKey} === null) {\n`;
517
+ ret += ` ret${dataKey} = null;\n`;
518
+ ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
519
+ ret += ` const val${level} = entity${entityKey}${unwrap};\n`;
520
+ if (targetProp?.customType) {
521
+ // If targetKey property has a custom type, convert to database value
522
+ const convertorKey = this.registerCustomType(targetProp, context);
523
+ ret += ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(val${level}?.${prop.targetKey});\n`;
524
+ }
525
+ else {
526
+ ret += ` ret${dataKey} = val${level}?.${prop.targetKey};\n`;
527
+ }
528
+ ret += ` }\n`;
529
+ }
489
530
  else {
490
531
  const toArray = (val) => {
491
532
  if (Utils.isPlainObject(val)) {
@@ -494,8 +535,11 @@ export class EntityComparator {
494
535
  return val;
495
536
  };
496
537
  context.set('toArray', toArray);
538
+ context.set('EntityIdentifier', EntityIdentifier);
497
539
  ret += ` if (entity${entityKey} === null) {\n`;
498
540
  ret += ` ret${dataKey} = null;\n`;
541
+ ret += ` } else if (entity${entityKey}?.__helper.__identifier && !entity${entityKey}.__helper.hasPrimaryKey()) {\n`;
542
+ ret += ` ret${dataKey} = entity${entityKey}?.__helper.__identifier;\n`;
499
543
  ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
500
544
  ret += ` ret${dataKey} = toArray(entity${entityKey}.__helper.getPrimaryKey(true));\n`;
501
545
  ret += ` }\n`;
@@ -519,11 +563,11 @@ export class EntityComparator {
519
563
  * @internal Highly performance-sensitive method.
520
564
  */
521
565
  getEntityComparator(entityName) {
522
- const exists = this.comparators.get(entityName);
566
+ const meta = this.metadata.find(entityName);
567
+ const exists = this.comparators.get(meta);
523
568
  if (exists) {
524
569
  return exists;
525
570
  }
526
- const meta = this.metadata.find(entityName);
527
571
  const lines = [];
528
572
  const context = new Map();
529
573
  context.set('compareArrays', compareArrays);
@@ -531,17 +575,27 @@ export class EntityComparator {
531
575
  context.set('compareBuffers', compareBuffers);
532
576
  context.set('compareObjects', compareObjects);
533
577
  context.set('equals', equals);
534
- meta.comparableProps.forEach(prop => {
578
+ for (const prop of meta.comparableProps) {
535
579
  lines.push(this.getPropertyComparator(prop, context));
536
- });
580
+ }
581
+ // also compare 1:1 inverse sides, important for `factory.mergeData`
582
+ lines.push(`if (options?.includeInverseSides) {`);
583
+ for (const prop of meta.bidirectionalRelations) {
584
+ if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner && prop.hydrate !== false) {
585
+ lines.push(this.getPropertyComparator(prop, context));
586
+ }
587
+ }
588
+ lines.push(`}`);
537
589
  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}`;
590
+ + `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
539
591
  const comparator = Utils.createFunction(context, code);
540
- this.comparators.set(entityName, comparator);
592
+ this.comparators.set(meta, comparator);
541
593
  return comparator;
542
594
  }
543
595
  getGenericComparator(prop, cond) {
544
- return ` if (current${prop} == null && last${prop} == null) {\n\n` +
596
+ return ` if (current${prop} === null && last${prop} === undefined) {\n` +
597
+ ` diff${prop} = current${prop};\n` +
598
+ ` } else if (current${prop} == null && last${prop} == null) {\n\n` +
545
599
  ` } else if ((current${prop} != null && last${prop} == null) || (current${prop} == null && last${prop} != null)) {\n` +
546
600
  ` diff${prop} = current${prop};\n` +
547
601
  ` } else if (${cond}) {\n` +
@@ -551,18 +605,23 @@ export class EntityComparator {
551
605
  getPropertyComparator(prop, context) {
552
606
  let type = prop.type.toLowerCase();
553
607
  if (prop.kind !== ReferenceKind.SCALAR && prop.kind !== ReferenceKind.EMBEDDED) {
554
- const meta2 = this.metadata.find(prop.type);
608
+ const meta2 = prop.targetMeta;
555
609
  if (meta2.primaryKeys.length > 1) {
556
610
  type = 'array';
557
611
  }
558
612
  else {
559
- type = meta2.properties[meta2.primaryKeys[0]].type.toLowerCase();
613
+ type = meta2.getPrimaryProp().type.toLowerCase();
560
614
  }
561
615
  }
562
616
  if (prop.customType) {
563
617
  if (prop.customType.compareValues) {
564
618
  const idx = this.tmpIndex++;
565
- context.set(`compareValues_${idx}`, (a, b) => prop.customType.compareValues(a, b));
619
+ context.set(`compareValues_${idx}`, (a, b) => {
620
+ if (Raw.isKnownFragment(a) || Raw.isKnownFragment(b)) {
621
+ return Raw.getKnownFragment(a) === Raw.getKnownFragment(b);
622
+ }
623
+ return prop.customType.compareValues(a, b);
624
+ });
566
625
  return this.getGenericComparator(this.wrap(prop.name), `!compareValues_${idx}(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
567
626
  }
568
627
  type = prop.customType.compareAsType().toLowerCase();
@@ -582,10 +641,10 @@ export class EntityComparator {
582
641
  if (['buffer', 'uint8array'].includes(type)) {
583
642
  return this.getGenericComparator(this.wrap(prop.name), `!compareBuffers(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
584
643
  }
585
- if (['date'].includes(type)) {
644
+ if (type === 'date') {
586
645
  return this.getGenericComparator(this.wrap(prop.name), `last${this.wrap(prop.name)}.valueOf() !== current${this.wrap(prop.name)}.valueOf()`);
587
646
  }
588
- if (['objectid'].includes(type)) {
647
+ if (type === 'objectid') {
589
648
  // We might be comparing PK to object, in case we compare with cached data of populated entity
590
649
  // in such case we just ignore the comparison and fallback to `equals()` (which will still mark
591
650
  // it as not equal as we compare PK to plain object).
@@ -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';