@mikro-orm/core 7.0.0-dev.3 → 7.0.0-dev.300

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 (214) hide show
  1. package/EntityManager.d.ts +114 -63
  2. package/EntityManager.js +385 -310
  3. package/MikroORM.d.ts +44 -35
  4. package/MikroORM.js +109 -143
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +1 -1
  7. package/cache/FileCacheAdapter.js +17 -8
  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 +119 -36
  16. package/drivers/IDatabaseDriver.d.ts +125 -23
  17. package/entity/BaseEntity.d.ts +63 -4
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +102 -31
  20. package/entity/Collection.js +446 -108
  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 +106 -60
  25. package/entity/EntityHelper.d.ts +2 -2
  26. package/entity/EntityHelper.js +65 -20
  27. package/entity/EntityLoader.d.ts +13 -11
  28. package/entity/EntityLoader.js +257 -107
  29. package/entity/EntityRepository.d.ts +28 -8
  30. package/entity/EntityRepository.js +8 -2
  31. package/entity/PolymorphicRef.d.ts +12 -0
  32. package/entity/PolymorphicRef.js +18 -0
  33. package/entity/Reference.d.ts +9 -12
  34. package/entity/Reference.js +34 -9
  35. package/entity/WrappedEntity.d.ts +3 -8
  36. package/entity/WrappedEntity.js +3 -8
  37. package/entity/defineEntity.d.ts +753 -0
  38. package/entity/defineEntity.js +537 -0
  39. package/entity/index.d.ts +4 -2
  40. package/entity/index.js +4 -2
  41. package/entity/utils.d.ts +13 -1
  42. package/entity/utils.js +49 -4
  43. package/entity/validators.d.ts +11 -0
  44. package/entity/validators.js +65 -0
  45. package/enums.d.ts +23 -8
  46. package/enums.js +15 -1
  47. package/errors.d.ts +25 -9
  48. package/errors.js +67 -21
  49. package/events/EventManager.d.ts +2 -1
  50. package/events/EventManager.js +19 -11
  51. package/events/EventSubscriber.d.ts +3 -1
  52. package/hydration/Hydrator.js +1 -2
  53. package/hydration/ObjectHydrator.d.ts +4 -4
  54. package/hydration/ObjectHydrator.js +89 -36
  55. package/index.d.ts +2 -2
  56. package/index.js +1 -2
  57. package/logging/DefaultLogger.d.ts +1 -1
  58. package/logging/DefaultLogger.js +1 -0
  59. package/logging/SimpleLogger.d.ts +1 -1
  60. package/logging/colors.d.ts +1 -1
  61. package/logging/colors.js +7 -6
  62. package/logging/index.d.ts +1 -0
  63. package/logging/index.js +1 -0
  64. package/logging/inspect.d.ts +2 -0
  65. package/logging/inspect.js +11 -0
  66. package/metadata/EntitySchema.d.ts +53 -27
  67. package/metadata/EntitySchema.js +125 -52
  68. package/metadata/MetadataDiscovery.d.ts +64 -10
  69. package/metadata/MetadataDiscovery.js +823 -344
  70. package/metadata/MetadataProvider.d.ts +11 -2
  71. package/metadata/MetadataProvider.js +66 -2
  72. package/metadata/MetadataStorage.d.ts +13 -11
  73. package/metadata/MetadataStorage.js +71 -38
  74. package/metadata/MetadataValidator.d.ts +32 -9
  75. package/metadata/MetadataValidator.js +198 -42
  76. package/metadata/discover-entities.d.ts +5 -0
  77. package/metadata/discover-entities.js +40 -0
  78. package/metadata/index.d.ts +1 -1
  79. package/metadata/index.js +1 -1
  80. package/metadata/types.d.ts +577 -0
  81. package/metadata/types.js +1 -0
  82. package/naming-strategy/AbstractNamingStrategy.d.ts +16 -4
  83. package/naming-strategy/AbstractNamingStrategy.js +20 -2
  84. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  85. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  86. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  87. package/naming-strategy/MongoNamingStrategy.js +6 -6
  88. package/naming-strategy/NamingStrategy.d.ts +28 -4
  89. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  90. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  91. package/not-supported.d.ts +2 -0
  92. package/not-supported.js +4 -0
  93. package/package.json +22 -11
  94. package/platforms/ExceptionConverter.js +1 -1
  95. package/platforms/Platform.d.ts +14 -16
  96. package/platforms/Platform.js +24 -44
  97. package/serialization/EntitySerializer.d.ts +8 -3
  98. package/serialization/EntitySerializer.js +47 -27
  99. package/serialization/EntityTransformer.js +33 -21
  100. package/serialization/SerializationContext.d.ts +6 -6
  101. package/serialization/SerializationContext.js +16 -13
  102. package/types/ArrayType.d.ts +1 -1
  103. package/types/ArrayType.js +2 -3
  104. package/types/BigIntType.d.ts +9 -6
  105. package/types/BigIntType.js +4 -1
  106. package/types/BlobType.d.ts +0 -1
  107. package/types/BlobType.js +0 -3
  108. package/types/BooleanType.d.ts +2 -1
  109. package/types/BooleanType.js +3 -0
  110. package/types/DecimalType.d.ts +6 -4
  111. package/types/DecimalType.js +3 -3
  112. package/types/DoubleType.js +2 -2
  113. package/types/EnumArrayType.js +1 -2
  114. package/types/JsonType.d.ts +1 -1
  115. package/types/JsonType.js +7 -2
  116. package/types/TinyIntType.js +1 -1
  117. package/types/Type.d.ts +2 -4
  118. package/types/Type.js +3 -3
  119. package/types/Uint8ArrayType.d.ts +0 -1
  120. package/types/Uint8ArrayType.js +1 -4
  121. package/types/index.d.ts +1 -1
  122. package/typings.d.ts +469 -175
  123. package/typings.js +120 -45
  124. package/unit-of-work/ChangeSet.d.ts +4 -6
  125. package/unit-of-work/ChangeSet.js +4 -5
  126. package/unit-of-work/ChangeSetComputer.d.ts +3 -8
  127. package/unit-of-work/ChangeSetComputer.js +44 -21
  128. package/unit-of-work/ChangeSetPersister.d.ts +15 -12
  129. package/unit-of-work/ChangeSetPersister.js +113 -45
  130. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  131. package/unit-of-work/CommitOrderCalculator.js +13 -13
  132. package/unit-of-work/IdentityMap.d.ts +12 -0
  133. package/unit-of-work/IdentityMap.js +39 -1
  134. package/unit-of-work/UnitOfWork.d.ts +28 -3
  135. package/unit-of-work/UnitOfWork.js +315 -110
  136. package/utils/AbstractMigrator.d.ts +101 -0
  137. package/utils/AbstractMigrator.js +305 -0
  138. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  139. package/utils/AbstractSchemaGenerator.js +32 -18
  140. package/utils/AsyncContext.d.ts +6 -0
  141. package/utils/AsyncContext.js +42 -0
  142. package/utils/Configuration.d.ts +801 -207
  143. package/utils/Configuration.js +150 -191
  144. package/utils/ConfigurationLoader.d.ts +1 -54
  145. package/utils/ConfigurationLoader.js +1 -352
  146. package/utils/Cursor.d.ts +3 -6
  147. package/utils/Cursor.js +27 -11
  148. package/utils/DataloaderUtils.d.ts +15 -5
  149. package/utils/DataloaderUtils.js +65 -17
  150. package/utils/EntityComparator.d.ts +21 -10
  151. package/utils/EntityComparator.js +243 -106
  152. package/utils/QueryHelper.d.ts +24 -6
  153. package/utils/QueryHelper.js +122 -26
  154. package/utils/RawQueryFragment.d.ts +60 -32
  155. package/utils/RawQueryFragment.js +69 -66
  156. package/utils/RequestContext.js +2 -2
  157. package/utils/TransactionContext.js +2 -2
  158. package/utils/TransactionManager.d.ts +65 -0
  159. package/utils/TransactionManager.js +223 -0
  160. package/utils/Utils.d.ts +15 -122
  161. package/utils/Utils.js +108 -376
  162. package/utils/clone.js +8 -23
  163. package/utils/env-vars.d.ts +7 -0
  164. package/utils/env-vars.js +97 -0
  165. package/utils/fs-utils.d.ts +34 -0
  166. package/utils/fs-utils.js +196 -0
  167. package/utils/index.d.ts +2 -3
  168. package/utils/index.js +2 -3
  169. package/utils/upsert-utils.d.ts +9 -4
  170. package/utils/upsert-utils.js +55 -4
  171. package/decorators/Check.d.ts +0 -3
  172. package/decorators/Check.js +0 -13
  173. package/decorators/CreateRequestContext.d.ts +0 -3
  174. package/decorators/CreateRequestContext.js +0 -32
  175. package/decorators/Embeddable.d.ts +0 -8
  176. package/decorators/Embeddable.js +0 -11
  177. package/decorators/Embedded.d.ts +0 -18
  178. package/decorators/Embedded.js +0 -18
  179. package/decorators/Entity.d.ts +0 -18
  180. package/decorators/Entity.js +0 -13
  181. package/decorators/Enum.d.ts +0 -9
  182. package/decorators/Enum.js +0 -16
  183. package/decorators/Filter.d.ts +0 -2
  184. package/decorators/Filter.js +0 -8
  185. package/decorators/Formula.d.ts +0 -5
  186. package/decorators/Formula.js +0 -15
  187. package/decorators/Indexed.d.ts +0 -17
  188. package/decorators/Indexed.js +0 -20
  189. package/decorators/ManyToMany.d.ts +0 -40
  190. package/decorators/ManyToMany.js +0 -14
  191. package/decorators/ManyToOne.d.ts +0 -30
  192. package/decorators/ManyToOne.js +0 -14
  193. package/decorators/OneToMany.d.ts +0 -28
  194. package/decorators/OneToMany.js +0 -17
  195. package/decorators/OneToOne.d.ts +0 -24
  196. package/decorators/OneToOne.js +0 -7
  197. package/decorators/PrimaryKey.d.ts +0 -9
  198. package/decorators/PrimaryKey.js +0 -20
  199. package/decorators/Property.d.ts +0 -250
  200. package/decorators/Property.js +0 -32
  201. package/decorators/Transactional.d.ts +0 -13
  202. package/decorators/Transactional.js +0 -28
  203. package/decorators/hooks.d.ts +0 -16
  204. package/decorators/hooks.js +0 -47
  205. package/decorators/index.d.ts +0 -17
  206. package/decorators/index.js +0 -17
  207. package/entity/ArrayCollection.d.ts +0 -116
  208. package/entity/ArrayCollection.js +0 -395
  209. package/entity/EntityValidator.d.ts +0 -19
  210. package/entity/EntityValidator.js +0 -150
  211. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  212. package/metadata/ReflectMetadataProvider.js +0 -44
  213. package/utils/resolveContextProvider.d.ts +0 -10
  214. package/utils/resolveContextProvider.js +0 -28
@@ -2,10 +2,13 @@ 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';
7
+ import { PolymorphicRef } from '../entity/PolymorphicRef.js';
6
8
  export class EntityComparator {
7
9
  metadata;
8
10
  platform;
11
+ config;
9
12
  comparators = new Map();
10
13
  mappers = new Map();
11
14
  snapshotGenerators = new Map();
@@ -13,16 +16,17 @@ export class EntityComparator {
13
16
  pkGettersConverted = new Map();
14
17
  pkSerializers = new Map();
15
18
  tmpIndex = 0;
16
- constructor(metadata, platform) {
19
+ constructor(metadata, platform, config) {
17
20
  this.metadata = metadata;
18
21
  this.platform = platform;
22
+ this.config = config;
19
23
  }
20
24
  /**
21
25
  * Computes difference between two entities.
22
26
  */
23
- diffEntities(entityName, a, b) {
27
+ diffEntities(entityName, a, b, options) {
24
28
  const comparator = this.getEntityComparator(entityName);
25
- return Utils.callCompiledFunction(comparator, a, b);
29
+ return Utils.callCompiledFunction(comparator, a, b, options);
26
30
  }
27
31
  matching(entityName, a, b) {
28
32
  const diff = this.diffEntities(entityName, a, b);
@@ -33,22 +37,22 @@ export class EntityComparator {
33
37
  * References will be mapped to primary keys, collections to arrays of primary keys.
34
38
  */
35
39
  prepareEntity(entity) {
36
- const generator = this.getSnapshotGenerator(entity.constructor.name);
40
+ const generator = this.getSnapshotGenerator(entity.constructor);
37
41
  return Utils.callCompiledFunction(generator, entity);
38
42
  }
39
43
  /**
40
44
  * Maps database columns to properties.
41
45
  */
42
- mapResult(entityName, result) {
43
- const mapper = this.getResultMapper(entityName);
46
+ mapResult(meta, result) {
47
+ const mapper = this.getResultMapper(meta);
44
48
  return Utils.callCompiledFunction(mapper, result);
45
49
  }
46
50
  /**
47
51
  * @internal Highly performance-sensitive method.
48
52
  */
49
53
  getPkGetter(meta) {
50
- const exists = this.pkGetters.get(meta.className);
51
- /* v8 ignore next 3 */
54
+ const exists = this.pkGetters.get(meta);
55
+ /* v8 ignore next */
52
56
  if (exists) {
53
57
  return exists;
54
58
  }
@@ -74,7 +78,7 @@ export class EntityComparator {
74
78
  lines.push(` if (entity${this.wrap(pk)} != null && (entity${this.wrap(pk)}.__entity || entity${this.wrap(pk)}.__reference)) {`);
75
79
  lines.push(` const pk = entity${this.wrap(pk)}.__helper.getPrimaryKey();`);
76
80
  if (meta.properties[pk].targetMeta.compositePK) {
77
- lines.push(` if (typeof pk === 'object') {`);
81
+ lines.push(` if (typeof pk === 'object' && pk != null) {`);
78
82
  lines.push(` return [`);
79
83
  for (const childPK of meta.properties[pk].targetMeta.primaryKeys) {
80
84
  lines.push(` pk${this.wrap(childPK)},`);
@@ -87,18 +91,19 @@ export class EntityComparator {
87
91
  }
88
92
  lines.push(` return entity${this.wrap(pk)};`);
89
93
  }
90
- const code = `// compiled pk serializer for entity ${meta.className}\n`
94
+ const code = `// compiled pk getter for entity ${meta.className}\n`
91
95
  + `return function(entity) {\n${lines.join('\n')}\n}`;
92
- const pkSerializer = Utils.createFunction(context, code);
93
- this.pkGetters.set(meta.className, pkSerializer);
96
+ const fnKey = `pkGetter-${meta.uniqueName}`;
97
+ const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
98
+ this.pkGetters.set(meta, pkSerializer);
94
99
  return pkSerializer;
95
100
  }
96
101
  /**
97
102
  * @internal Highly performance-sensitive method.
98
103
  */
99
104
  getPkGetterConverted(meta) {
100
- const exists = this.pkGettersConverted.get(meta.className);
101
- /* v8 ignore next 3 */
105
+ const exists = this.pkGettersConverted.get(meta);
106
+ /* v8 ignore next */
102
107
  if (exists) {
103
108
  return exists;
104
109
  }
@@ -139,22 +144,24 @@ export class EntityComparator {
139
144
  }
140
145
  const code = `// compiled pk getter (with converted custom types) for entity ${meta.className}\n`
141
146
  + `return function(entity) {\n${lines.join('\n')}\n}`;
142
- const pkSerializer = Utils.createFunction(context, code);
143
- this.pkGettersConverted.set(meta.className, pkSerializer);
147
+ const fnKey = `pkGetterConverted-${meta.uniqueName}`;
148
+ const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
149
+ this.pkGettersConverted.set(meta, pkSerializer);
144
150
  return pkSerializer;
145
151
  }
146
152
  /**
147
153
  * @internal Highly performance-sensitive method.
148
154
  */
149
155
  getPkSerializer(meta) {
150
- const exists = this.pkSerializers.get(meta.className);
151
- /* v8 ignore next 3 */
156
+ const exists = this.pkSerializers.get(meta);
157
+ /* v8 ignore next */
152
158
  if (exists) {
153
159
  return exists;
154
160
  }
155
161
  const lines = [];
156
162
  const context = new Map();
157
163
  context.set('getCompositeKeyValue', (val) => Utils.flatten(Utils.getCompositeKeyValue(val, meta, 'convertToDatabaseValue', this.platform)));
164
+ context.set('getPrimaryKeyHash', (val) => Utils.getPrimaryKeyHash(Utils.asArray(val)));
158
165
  if (meta.primaryKeys.length > 1) {
159
166
  lines.push(` const pks = entity.__helper.__pk ? getCompositeKeyValue(entity.__helper.__pk) : [`);
160
167
  meta.primaryKeys.forEach(pk => {
@@ -170,35 +177,45 @@ export class EntityComparator {
170
177
  }
171
178
  else {
172
179
  const pk = meta.primaryKeys[0];
173
- if (meta.properties[pk].kind !== ReferenceKind.SCALAR) {
180
+ const prop = meta.properties[pk];
181
+ if (prop.kind !== ReferenceKind.SCALAR) {
174
182
  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
183
  }
176
184
  const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
177
185
  if (serializedPrimaryKey) {
178
186
  lines.push(` return '' + entity.${serializedPrimaryKey.name};`);
179
187
  }
180
- lines.push(` return '' + entity.${meta.primaryKeys[0]};`);
188
+ else if (prop.customType) {
189
+ const convertorKey = this.registerCustomType(meta.properties[pk], context);
190
+ const idx = this.tmpIndex++;
191
+ lines.push(` const val_${idx} = convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)});`);
192
+ lines.push(` return getPrimaryKeyHash(val_${idx});`);
193
+ }
194
+ else {
195
+ lines.push(` return '' + entity${this.wrap(pk)};`);
196
+ }
181
197
  }
182
198
  const code = `// compiled pk serializer for entity ${meta.className}\n`
183
199
  + `return function(entity) {\n${lines.join('\n')}\n}`;
184
- const pkSerializer = Utils.createFunction(context, code);
185
- this.pkSerializers.set(meta.className, pkSerializer);
200
+ const fnKey = `pkSerializer-${meta.uniqueName}`;
201
+ const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
202
+ this.pkSerializers.set(meta, pkSerializer);
186
203
  return pkSerializer;
187
204
  }
188
205
  /**
189
206
  * @internal Highly performance-sensitive method.
190
207
  */
191
208
  getSnapshotGenerator(entityName) {
192
- const exists = this.snapshotGenerators.get(entityName);
209
+ const meta = this.metadata.find(entityName);
210
+ const exists = this.snapshotGenerators.get(meta);
193
211
  if (exists) {
194
212
  return exists;
195
213
  }
196
- const meta = this.metadata.find(entityName);
197
214
  const lines = [];
198
215
  const context = new Map();
199
216
  context.set('clone', clone);
200
217
  context.set('cloneEmbeddable', (o) => this.platform.cloneEmbeddable(o)); // do not clone prototypes
201
- if (meta.discriminatorValue) {
218
+ if (meta.root.inheritanceType === 'sti' && meta.discriminatorValue) {
202
219
  lines.push(` ret${this.wrap(meta.root.discriminatorColumn)} = '${meta.discriminatorValue}'`);
203
220
  }
204
221
  const getRootProperty = (prop) => prop.embedded ? getRootProperty(meta.properties[prop.embedded[0]]) : prop;
@@ -210,8 +227,9 @@ export class EntityComparator {
210
227
  })
211
228
  .forEach(prop => lines.push(this.getPropertySnapshot(meta, prop, context, this.wrap(prop.name), this.wrap(prop.name), [prop.name])));
212
229
  const code = `return function(entity) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
213
- const snapshotGenerator = Utils.createFunction(context, code);
214
- this.snapshotGenerators.set(entityName, snapshotGenerator);
230
+ const fnKey = `snapshotGenerator-${meta.uniqueName}`;
231
+ const snapshotGenerator = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
232
+ this.snapshotGenerators.set(meta, snapshotGenerator);
215
233
  return snapshotGenerator;
216
234
  }
217
235
  /**
@@ -261,23 +279,27 @@ export class EntityComparator {
261
279
  /**
262
280
  * @internal Highly performance-sensitive method.
263
281
  */
264
- getResultMapper(entityName) {
265
- const exists = this.mappers.get(entityName);
282
+ getResultMapper(meta) {
283
+ const exists = this.mappers.get(meta);
266
284
  if (exists) {
267
285
  return exists;
268
286
  }
269
- const meta = this.metadata.get(entityName);
270
287
  const lines = [];
271
288
  const context = new Map();
289
+ context.set('PolymorphicRef', PolymorphicRef);
272
290
  const tz = this.platform.getTimezone();
273
291
  const parseDate = (key, value, padding = '') => {
274
292
  lines.push(`${padding} if (${value} == null || ${value} instanceof Date) {`);
275
293
  lines.push(`${padding} ${key} = ${value};`);
276
294
  if (!tz || tz === 'local') {
295
+ lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
296
+ lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
277
297
  lines.push(`${padding} } else {`);
278
298
  lines.push(`${padding} ${key} = parseDate(${value});`);
279
299
  }
280
300
  else {
301
+ lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
302
+ lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
281
303
  lines.push(`${padding} } else if (typeof ${value} === 'number' || ${value}.includes('+') || ${value}.lastIndexOf('-') > 10 || ${value}.endsWith('Z')) {`);
282
304
  lines.push(`${padding} ${key} = parseDate(${value});`);
283
305
  lines.push(`${padding} } else {`);
@@ -286,61 +308,94 @@ export class EntityComparator {
286
308
  lines.push(`${padding} }`);
287
309
  };
288
310
  lines.push(` const mapped = {};`);
289
- meta.props.forEach(prop => {
290
- if (!prop.fieldNames) {
291
- return;
292
- }
293
- if (prop.targetMeta && prop.fieldNames.length > 1) {
294
- lines.push(` if (${prop.fieldNames.map(field => `typeof ${this.propName(field)} === 'undefined'`).join(' && ')}) {`);
295
- lines.push(` } else if (${prop.fieldNames.map(field => `${this.propName(field)} != null`).join(' && ')}) {`);
296
- lines.push(` ret${this.wrap(prop.name)} = ${this.createCompositeKeyArray(prop)};`);
297
- lines.push(...prop.fieldNames.map(field => ` ${this.propName(field, 'mapped')} = true;`));
298
- lines.push(` } else if (${prop.fieldNames.map(field => `${this.propName(field)} == null`).join(' && ')}) {\n ret${this.wrap(prop.name)} = null;`);
299
- lines.push(...prop.fieldNames.map(field => ` ${this.propName(field, 'mapped')} = true;`), ' }');
300
- return;
301
- }
302
- if (prop.embedded && (meta.embeddable || meta.properties[prop.embedded[0]].object)) {
303
- return;
304
- }
305
- if (prop.runtimeType === 'boolean') {
306
- lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
307
- lines.push(` ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : !!${this.propName(prop.fieldNames[0])};`);
308
- lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
309
- lines.push(` }`);
310
- }
311
- else if (prop.runtimeType === 'Date' && !this.platform.isNumericProperty(prop)) {
312
- lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
313
- context.set('parseDate', (value) => this.platform.parseDate(value));
314
- parseDate('ret' + this.wrap(prop.name), this.propName(prop.fieldNames[0]));
315
- lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
316
- lines.push(` }`);
317
- }
318
- else if (prop.kind === ReferenceKind.EMBEDDED && (prop.object || meta.embeddable)) {
319
- const idx = this.tmpIndex++;
320
- context.set(`mapEmbeddedResult_${idx}`, (data) => {
321
- const item = parseJsonSafe(data);
322
- if (Array.isArray(item)) {
323
- return item.map(row => row == null ? row : this.getResultMapper(prop.type)(row));
311
+ const mapEntityProperties = (meta, padding = '') => {
312
+ for (const prop of meta.props) {
313
+ if (!prop.fieldNames) {
314
+ continue;
315
+ }
316
+ if (prop.polymorphic && prop.fieldNames.length >= 2) {
317
+ const discriminatorField = prop.fieldNames[0];
318
+ const idFields = prop.fieldNames.slice(1);
319
+ lines.push(`${padding} if (${prop.fieldNames.map(field => `typeof ${this.propName(field)} === 'undefined'`).join(' && ')}) {`);
320
+ lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} != null`).join(' && ')}) {`);
321
+ if (idFields.length === 1) {
322
+ lines.push(`${padding} ret${this.wrap(prop.name)} = new PolymorphicRef(${this.propName(discriminatorField)}, ${this.propName(idFields[0])});`);
324
323
  }
325
- return item == null ? item : this.getResultMapper(prop.type)(item);
326
- });
327
- lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
328
- lines.push(` ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : mapEmbeddedResult_${idx}(${this.propName(prop.fieldNames[0])});`);
329
- lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
330
- lines.push(` }`);
324
+ else {
325
+ lines.push(`${padding} ret${this.wrap(prop.name)} = new PolymorphicRef(${this.propName(discriminatorField)}, [${idFields.map(f => this.propName(f)).join(', ')}]);`);
326
+ }
327
+ lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`));
328
+ lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} == null`).join(' && ')}) {\n${padding} ret${this.wrap(prop.name)} = null;`);
329
+ lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`), ' }');
330
+ continue;
331
+ }
332
+ if (prop.targetMeta && prop.fieldNames.length > 1) {
333
+ lines.push(`${padding} if (${prop.fieldNames.map(field => `typeof ${this.propName(field)} === 'undefined'`).join(' && ')}) {`);
334
+ lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} != null`).join(' && ')}) {`);
335
+ lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.createCompositeKeyArray(prop)};`);
336
+ lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`));
337
+ lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} == null`).join(' && ')}) {\n${padding} ret${this.wrap(prop.name)} = null;`);
338
+ lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`), ' }');
339
+ continue;
340
+ }
341
+ if (prop.embedded && (meta.embeddable || meta.properties[prop.embedded[0]].object)) {
342
+ continue;
343
+ }
344
+ if (prop.runtimeType === 'boolean') {
345
+ lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
346
+ lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : !!${this.propName(prop.fieldNames[0])};`);
347
+ lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
348
+ lines.push(`${padding} }`);
349
+ }
350
+ else if (prop.runtimeType === 'Date' && !this.platform.isNumericProperty(prop)) {
351
+ lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
352
+ context.set('parseDate', (value) => this.platform.parseDate(value));
353
+ parseDate('ret' + this.wrap(prop.name), this.propName(prop.fieldNames[0]), padding);
354
+ lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
355
+ lines.push(`${padding} }`);
356
+ }
357
+ else if (prop.kind === ReferenceKind.EMBEDDED && (prop.object || meta.embeddable)) {
358
+ const idx = this.tmpIndex++;
359
+ context.set(`mapEmbeddedResult_${idx}`, (data) => {
360
+ const item = parseJsonSafe(data);
361
+ if (Array.isArray(item)) {
362
+ return item.map(row => row == null ? row : this.getResultMapper(prop.targetMeta)(row));
363
+ }
364
+ return item == null ? item : this.getResultMapper(prop.targetMeta)(item);
365
+ });
366
+ lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
367
+ 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])});`);
368
+ lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
369
+ lines.push(`${padding} }`);
370
+ }
371
+ else if (prop.kind !== ReferenceKind.EMBEDDED) {
372
+ lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
373
+ lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])};`);
374
+ lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
375
+ lines.push(`${padding} }`);
376
+ }
331
377
  }
332
- else if (prop.kind !== ReferenceKind.EMBEDDED) {
333
- lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
334
- lines.push(` ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])};`);
335
- lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
378
+ };
379
+ if (meta.polymorphs && meta.discriminatorColumn) {
380
+ for (const polymorph of meta.polymorphs) {
381
+ const first = polymorph === meta.polymorphs[0];
382
+ lines.push(` ${first ? '' : 'else '}if (${this.propName(meta.discriminatorColumn)} == '${polymorph.discriminatorValue}') {`);
383
+ mapEntityProperties(polymorph, ' ');
336
384
  lines.push(` }`);
337
385
  }
338
- });
339
- lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k]) ret[k] = result[k]; }`);
386
+ lines.push(` else {`);
387
+ mapEntityProperties(meta, ' ');
388
+ lines.push(` }`);
389
+ }
390
+ else {
391
+ mapEntityProperties(meta);
392
+ }
393
+ lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k] && ret[k] === undefined) ret[k] = result[k]; }`);
340
394
  const code = `// compiled mapper for entity ${meta.className}\n`
341
395
  + `return function(result) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
342
- const resultMapper = Utils.createFunction(context, code);
343
- this.mappers.set(entityName, resultMapper);
396
+ const fnKey = `resultMapper-${meta.uniqueName}`;
397
+ const resultMapper = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
398
+ this.mappers.set(meta, resultMapper);
344
399
  return resultMapper;
345
400
  }
346
401
  getPropertyCondition(path) {
@@ -391,11 +446,21 @@ export class EntityComparator {
391
446
  }
392
447
  getEmbeddedPropertySnapshot(meta, prop, context, level, path, dataKey, object = prop.object) {
393
448
  const padding = ' '.repeat(level * 2);
449
+ const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
394
450
  let ret = `${level === 1 ? '' : '\n'}`;
395
451
  if (object) {
396
- const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
397
452
  ret += `${padding}if (${nullCond}) ret${dataKey} = null;\n`;
398
453
  }
454
+ else {
455
+ ret += `${padding}if (${nullCond}) {\n`;
456
+ ret += meta.props.filter(p => p.embedded?.[0] === prop.name
457
+ // object for JSON embeddable
458
+ && (p.object || (p.persist !== false))).map(childProp => {
459
+ const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
460
+ return `${padding} ret${childDataKey} = null;`;
461
+ }).join('\n') + `\n`;
462
+ ret += `${padding}}\n`;
463
+ }
399
464
  const cond = `entity${path.map(k => this.wrap(k)).join('')} != null`;
400
465
  ret += `${padding}if (${cond}) {\n`;
401
466
  if (object) {
@@ -440,8 +505,8 @@ export class EntityComparator {
440
505
  registerCustomType(prop, context) {
441
506
  const convertorKey = this.safeKey(prop.name);
442
507
  context.set(`convertToDatabaseValue_${convertorKey}`, (val) => {
443
- /* v8 ignore next 3 */
444
- if (RawQueryFragment.isKnownFragment(val)) {
508
+ /* v8 ignore next */
509
+ if (Raw.isKnownFragment(val)) {
445
510
  return val;
446
511
  }
447
512
  return prop.customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' });
@@ -470,16 +535,51 @@ export class EntityComparator {
470
535
  ret += ` ret${dataKey} = entity${entityKey};\n`;
471
536
  }
472
537
  }
538
+ else if (prop.polymorphic) {
539
+ const discriminatorMapKey = `discriminatorMapReverse_${prop.name}`;
540
+ const reverseMap = new Map();
541
+ for (const [key, value] of Object.entries(prop.discriminatorMap)) {
542
+ reverseMap.set(value, key);
543
+ }
544
+ context.set(discriminatorMapKey, reverseMap);
545
+ this.setToArrayHelper(context);
546
+ context.set('EntityIdentifier', EntityIdentifier);
547
+ context.set('PolymorphicRef', PolymorphicRef);
548
+ ret += ` if (entity${entityKey} === null) {\n`;
549
+ ret += ` ret${dataKey} = null;\n`;
550
+ ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
551
+ ret += ` const val${level} = entity${entityKey}${unwrap};\n`;
552
+ ret += ` const discriminator = ${discriminatorMapKey}.get(val${level}?.constructor);\n`;
553
+ ret += ` const pk = val${level}?.__helper?.__identifier && !val${level}?.__helper?.hasPrimaryKey()\n`;
554
+ ret += ` ? val${level}.__helper.__identifier\n`;
555
+ ret += ` : toArray(val${level}?.__helper?.getPrimaryKey(true));\n`;
556
+ ret += ` ret${dataKey} = new PolymorphicRef(discriminator, pk);\n`;
557
+ ret += ` }\n`;
558
+ }
559
+ else if (prop.targetKey) {
560
+ // When targetKey is set, extract that property value instead of the PK
561
+ const targetProp = prop.targetMeta?.properties[prop.targetKey];
562
+ ret += ` if (entity${entityKey} === null) {\n`;
563
+ ret += ` ret${dataKey} = null;\n`;
564
+ ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
565
+ ret += ` const val${level} = entity${entityKey}${unwrap};\n`;
566
+ if (targetProp?.customType) {
567
+ // If targetKey property has a custom type, convert to database value
568
+ const convertorKey = this.registerCustomType(targetProp, context);
569
+ ret += ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(val${level}?.${prop.targetKey});\n`;
570
+ }
571
+ else {
572
+ ret += ` ret${dataKey} = val${level}?.${prop.targetKey};\n`;
573
+ }
574
+ ret += ` }\n`;
575
+ }
473
576
  else {
474
- const toArray = (val) => {
475
- if (Utils.isPlainObject(val)) {
476
- return Object.values(val).map(v => toArray(v));
477
- }
478
- return val;
479
- };
480
- context.set('toArray', toArray);
577
+ this.setToArrayHelper(context);
578
+ context.set('EntityIdentifier', EntityIdentifier);
481
579
  ret += ` if (entity${entityKey} === null) {\n`;
482
580
  ret += ` ret${dataKey} = null;\n`;
581
+ ret += ` } else if (entity${entityKey}?.__helper.__identifier && !entity${entityKey}.__helper.hasPrimaryKey()) {\n`;
582
+ ret += ` ret${dataKey} = entity${entityKey}?.__helper.__identifier;\n`;
483
583
  ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
484
584
  ret += ` ret${dataKey} = toArray(entity${entityKey}.__helper.getPrimaryKey(true));\n`;
485
585
  ret += ` }\n`;
@@ -503,11 +603,11 @@ export class EntityComparator {
503
603
  * @internal Highly performance-sensitive method.
504
604
  */
505
605
  getEntityComparator(entityName) {
506
- const exists = this.comparators.get(entityName);
606
+ const meta = this.metadata.find(entityName);
607
+ const exists = this.comparators.get(meta);
507
608
  if (exists) {
508
609
  return exists;
509
610
  }
510
- const meta = this.metadata.find(entityName);
511
611
  const lines = [];
512
612
  const context = new Map();
513
613
  context.set('compareArrays', compareArrays);
@@ -515,17 +615,28 @@ export class EntityComparator {
515
615
  context.set('compareBuffers', compareBuffers);
516
616
  context.set('compareObjects', compareObjects);
517
617
  context.set('equals', equals);
518
- meta.comparableProps.forEach(prop => {
618
+ for (const prop of meta.comparableProps) {
519
619
  lines.push(this.getPropertyComparator(prop, context));
520
- });
620
+ }
621
+ // also compare 1:1 inverse sides, important for `factory.mergeData`
622
+ lines.push(`if (options?.includeInverseSides) {`);
623
+ for (const prop of meta.bidirectionalRelations) {
624
+ if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner && prop.hydrate !== false) {
625
+ lines.push(this.getPropertyComparator(prop, context));
626
+ }
627
+ }
628
+ lines.push(`}`);
521
629
  const code = `// compiled comparator for entity ${meta.className}\n`
522
- + `return function(last, current) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
523
- const comparator = Utils.createFunction(context, code);
524
- this.comparators.set(entityName, comparator);
630
+ + `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
631
+ const fnKey = `comparator-${meta.uniqueName}`;
632
+ const comparator = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
633
+ this.comparators.set(meta, comparator);
525
634
  return comparator;
526
635
  }
527
636
  getGenericComparator(prop, cond) {
528
- return ` if (current${prop} == null && last${prop} == null) {\n\n` +
637
+ return ` if (current${prop} === null && last${prop} === undefined) {\n` +
638
+ ` diff${prop} = current${prop};\n` +
639
+ ` } else if (current${prop} == null && last${prop} == null) {\n\n` +
529
640
  ` } else if ((current${prop} != null && last${prop} == null) || (current${prop} == null && last${prop} != null)) {\n` +
530
641
  ` diff${prop} = current${prop};\n` +
531
642
  ` } else if (${cond}) {\n` +
@@ -535,18 +646,28 @@ export class EntityComparator {
535
646
  getPropertyComparator(prop, context) {
536
647
  let type = prop.type.toLowerCase();
537
648
  if (prop.kind !== ReferenceKind.SCALAR && prop.kind !== ReferenceKind.EMBEDDED) {
538
- const meta2 = this.metadata.find(prop.type);
539
- if (meta2.primaryKeys.length > 1) {
540
- type = 'array';
649
+ if (prop.polymorphic) {
650
+ type = 'object';
541
651
  }
542
652
  else {
543
- type = meta2.properties[meta2.primaryKeys[0]].type.toLowerCase();
653
+ const meta2 = prop.targetMeta;
654
+ if (meta2.primaryKeys.length > 1) {
655
+ type = 'array';
656
+ }
657
+ else {
658
+ type = meta2.getPrimaryProp().type.toLowerCase();
659
+ }
544
660
  }
545
661
  }
546
662
  if (prop.customType) {
547
663
  if (prop.customType.compareValues) {
548
664
  const idx = this.tmpIndex++;
549
- context.set(`compareValues_${idx}`, (a, b) => prop.customType.compareValues(a, b));
665
+ context.set(`compareValues_${idx}`, (a, b) => {
666
+ if (Raw.isKnownFragment(a) || Raw.isKnownFragment(b)) {
667
+ return Raw.getKnownFragment(a) === Raw.getKnownFragment(b);
668
+ }
669
+ return prop.customType.compareValues(a, b);
670
+ });
550
671
  return this.getGenericComparator(this.wrap(prop.name), `!compareValues_${idx}(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
551
672
  }
552
673
  type = prop.customType.compareAsType().toLowerCase();
@@ -566,10 +687,10 @@ export class EntityComparator {
566
687
  if (['buffer', 'uint8array'].includes(type)) {
567
688
  return this.getGenericComparator(this.wrap(prop.name), `!compareBuffers(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
568
689
  }
569
- if (['date'].includes(type)) {
690
+ if (type === 'date') {
570
691
  return this.getGenericComparator(this.wrap(prop.name), `last${this.wrap(prop.name)}.valueOf() !== current${this.wrap(prop.name)}.valueOf()`);
571
692
  }
572
- if (['objectid'].includes(type)) {
693
+ if (type === 'objectid') {
573
694
  // We might be comparing PK to object, in case we compare with cached data of populated entity
574
695
  // in such case we just ignore the comparison and fallback to `equals()` (which will still mark
575
696
  // it as not equal as we compare PK to plain object).
@@ -587,11 +708,27 @@ export class EntityComparator {
587
708
  safeKey(key) {
588
709
  return key.replace(/\W/g, '_');
589
710
  }
711
+ /**
712
+ * Sets the toArray helper in the context if not already set.
713
+ * Used for converting composite PKs to arrays.
714
+ */
715
+ setToArrayHelper(context) {
716
+ if (context.has('toArray')) {
717
+ return;
718
+ }
719
+ const toArray = (val) => {
720
+ if (Utils.isPlainObject(val)) {
721
+ return Object.values(val).map(v => toArray(v));
722
+ }
723
+ return val;
724
+ };
725
+ context.set('toArray', toArray);
726
+ }
590
727
  /**
591
728
  * perf: used to generate list of comparable properties during discovery, so we speed up the runtime comparison
592
729
  */
593
730
  static isComparable(prop, root) {
594
- const virtual = prop.persist === false || prop.generated;
731
+ const virtual = prop.persist === false || (prop.generated && !prop.primary);
595
732
  const inverse = prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner;
596
733
  const discriminator = prop.name === root.discriminatorColumn;
597
734
  const collection = prop.kind === ReferenceKind.ONE_TO_MANY || prop.kind === ReferenceKind.MANY_TO_MANY;
@@ -1,27 +1,45 @@
1
- import type { Dictionary, EntityMetadata, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
1
+ import type { Dictionary, EntityMetadata, EntityName, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
2
+ import { type QueryOrderMap } from '../enums.js';
2
3
  import type { Platform } from '../platforms/Platform.js';
3
4
  import type { MetadataStorage } from '../metadata/MetadataStorage.js';
5
+ import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
6
+ /** @internal */
4
7
  export declare class QueryHelper {
5
8
  static readonly SUPPORTED_OPERATORS: string[];
9
+ /**
10
+ * Finds the discriminator value (key) for a given entity class in a discriminator map.
11
+ */
12
+ static findDiscriminatorValue<T>(discriminatorMap: Dictionary<T>, targetClass: T): string | undefined;
6
13
  static processParams(params: unknown): any;
7
- static processObjectParams<T extends object>(params?: T): T;
14
+ static processObjectParams<T extends Dictionary>(params?: T): T;
15
+ /**
16
+ * converts `{ account: { $or: [ [Object], [Object] ] } }`
17
+ * to `{ $or: [ { account: [Object] }, { account: [Object] } ] }`
18
+ */
19
+ static liftGroupOperators<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): string | undefined;
8
20
  static inlinePrimaryKeyObjects<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): boolean;
9
21
  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;
22
+ static getActiveFilters<T>(meta: EntityMetadata<T>, options: FilterOptions | undefined, filters: Dictionary<FilterDef>): FilterDef[];
23
+ static mergePropertyFilters(propFilters: FilterOptions | undefined, options: FilterOptions | undefined): FilterOptions | undefined;
24
+ static isFilterActive<T>(meta: EntityMetadata<T>, filterName: string, filter: FilterDef, options: Dictionary<boolean | Dictionary>): boolean;
12
25
  static processCustomType<T extends object>(prop: EntityProperty<T>, cond: FilterQuery<T>, platform: Platform, key?: string, fromQuery?: boolean): FilterQuery<T>;
13
26
  private static isSupportedOperator;
14
27
  private static processJsonCondition;
15
28
  private static getValueType;
16
29
  static findProperty<T>(fieldName: string, options: ProcessWhereOptions<T>): EntityProperty<T> | undefined;
30
+ /**
31
+ * Merges multiple orderBy sources with key-level deduplication (first-seen key wins).
32
+ * RawQueryFragment symbol keys are never deduped (each is unique).
33
+ */
34
+ static mergeOrderBy<T>(...sources: (QueryOrderMap<T> | QueryOrderMap<T>[] | undefined)[]): QueryOrderMap<T>[];
17
35
  }
18
36
  interface ProcessWhereOptions<T> {
19
37
  where: FilterQuery<T>;
20
- entityName: string;
38
+ entityName: EntityName<T>;
21
39
  metadata: MetadataStorage;
22
40
  platform: Platform;
23
41
  aliased?: boolean;
24
- aliasMap?: Dictionary<string>;
42
+ aliasMap?: Dictionary<EntityName>;
25
43
  convertCustomTypes?: boolean;
26
44
  root?: boolean;
27
45
  type?: 'where' | 'orderBy';