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

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 (61) hide show
  1. package/EntityManager.d.ts +1 -1
  2. package/EntityManager.js +94 -43
  3. package/MikroORM.js +4 -4
  4. package/cache/FileCacheAdapter.js +1 -3
  5. package/connections/Connection.js +16 -3
  6. package/drivers/DatabaseDriver.js +25 -7
  7. package/entity/Collection.js +43 -17
  8. package/entity/EntityAssigner.js +23 -11
  9. package/entity/EntityFactory.js +32 -12
  10. package/entity/EntityHelper.js +12 -8
  11. package/entity/EntityLoader.js +55 -22
  12. package/entity/Reference.d.ts +1 -1
  13. package/entity/Reference.js +37 -8
  14. package/entity/WrappedEntity.js +5 -1
  15. package/entity/defineEntity.d.ts +5 -7
  16. package/entity/utils.js +28 -26
  17. package/entity/validators.js +2 -1
  18. package/enums.js +12 -17
  19. package/errors.js +18 -8
  20. package/events/EventManager.js +1 -1
  21. package/exceptions.js +7 -2
  22. package/hydration/ObjectHydrator.js +27 -13
  23. package/index.d.ts +1 -1
  24. package/index.js +1 -1
  25. package/logging/DefaultLogger.js +3 -5
  26. package/logging/colors.js +3 -6
  27. package/metadata/EntitySchema.js +12 -2
  28. package/metadata/MetadataDiscovery.js +101 -46
  29. package/metadata/MetadataProvider.js +6 -1
  30. package/metadata/MetadataStorage.js +1 -3
  31. package/metadata/MetadataValidator.js +20 -5
  32. package/metadata/types.d.ts +2 -2
  33. package/naming-strategy/AbstractNamingStrategy.js +5 -2
  34. package/not-supported.js +5 -1
  35. package/package.json +38 -38
  36. package/platforms/Platform.js +46 -23
  37. package/serialization/EntitySerializer.js +7 -3
  38. package/serialization/SerializationContext.js +1 -1
  39. package/typings.d.ts +23 -23
  40. package/typings.js +9 -9
  41. package/unit-of-work/ChangeSet.js +4 -4
  42. package/unit-of-work/ChangeSetComputer.js +8 -6
  43. package/unit-of-work/ChangeSetPersister.js +13 -8
  44. package/unit-of-work/CommitOrderCalculator.js +4 -2
  45. package/unit-of-work/UnitOfWork.d.ts +7 -1
  46. package/unit-of-work/UnitOfWork.js +51 -22
  47. package/utils/AbstractMigrator.js +3 -5
  48. package/utils/AbstractSchemaGenerator.js +2 -1
  49. package/utils/AsyncContext.js +1 -1
  50. package/utils/Configuration.js +8 -4
  51. package/utils/Cursor.js +4 -2
  52. package/utils/DataloaderUtils.js +15 -12
  53. package/utils/EntityComparator.js +51 -43
  54. package/utils/QueryHelper.js +38 -26
  55. package/utils/RawQueryFragment.js +3 -2
  56. package/utils/TransactionManager.js +2 -1
  57. package/utils/Utils.d.ts +1 -1
  58. package/utils/Utils.js +36 -30
  59. package/utils/env-vars.js +6 -5
  60. package/utils/fs-utils.js +2 -5
  61. package/utils/upsert-utils.js +6 -3
@@ -49,9 +49,7 @@ export class AbstractMigrator {
49
49
  await this.init();
50
50
  const all = await this.discoverMigrations();
51
51
  const executed = new Set(await this.storage.executed());
52
- return all
53
- .filter(m => !executed.has(m.name))
54
- .map(m => ({ name: m.name, path: m.path }));
52
+ return all.filter(m => !executed.has(m.name)).map(m => ({ name: m.name, path: m.path }));
55
53
  }
56
54
  /**
57
55
  * @inheritDoc
@@ -74,7 +72,7 @@ export class AbstractMigrator {
74
72
  const { fs } = await import('@mikro-orm/core/fs-utils');
75
73
  this.detectSourceFolder(fs);
76
74
  /* v8 ignore next */
77
- const key = (this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.options.pathTs) ? 'pathTs' : 'path';
75
+ const key = this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.options.pathTs ? 'pathTs' : 'path';
78
76
  this.absolutePath = fs.absolutePath(this.options[key], this.config.get('baseDir'));
79
77
  fs.ensureDir(this.absolutePath);
80
78
  }
@@ -132,7 +130,7 @@ export class AbstractMigrator {
132
130
  const buildDir = fs.pathExists(baseDir + '/build');
133
131
  // if neither `dist` nor `build` exist, we use the `src` folder as it might be a JS project without building, but with `src` folder
134
132
  /* v8 ignore next */
135
- const path = distDir ? './dist' : (buildDir ? './build' : './src');
133
+ const path = distDir ? './dist' : buildDir ? './build' : './src';
136
134
  // only if the user did not provide any values and if the default path does not exist
137
135
  if (!this.options.path && !this.options.pathTs && !exists) {
138
136
  this.options.path = `${path}/migrations`;
@@ -112,7 +112,8 @@ export class AbstractSchemaGenerator {
112
112
  }
113
113
  meta = metadata.pop();
114
114
  }
115
- return calc.sort()
115
+ return calc
116
+ .sort()
116
117
  .map(cls => this.metadata.getById(cls))
117
118
  .filter(meta => {
118
119
  const targetSchema = meta.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
@@ -13,7 +13,7 @@ function createFallbackAsyncContext() {
13
13
  console.warn('AsyncLocalStorage not available');
14
14
  return {
15
15
  getStore: () => store,
16
- enterWith: value => store = value,
16
+ enterWith: value => (store = value),
17
17
  run: (value, cb) => {
18
18
  const prev = store;
19
19
  store = value;
@@ -262,7 +262,10 @@ export class Configuration {
262
262
  * Gets instance of CacheAdapter for result cache. (cached)
263
263
  */
264
264
  getResultCacheAdapter() {
265
- return this.getCachedService(this.options.resultCache.adapter, { expiration: this.options.resultCache.expiration, ...this.options.resultCache.options });
265
+ return this.getCachedService(this.options.resultCache.adapter, {
266
+ expiration: this.options.resultCache.expiration,
267
+ ...this.options.resultCache.options,
268
+ });
266
269
  }
267
270
  /**
268
271
  * Gets EntityRepository class to be instantiated.
@@ -338,10 +341,10 @@ export class Configuration {
338
341
  validateOptions() {
339
342
  /* v8 ignore next */
340
343
  if ('type' in this.options) {
341
- throw new Error('The `type` option has been removed in v6, please fill in the `driver` option instead or use `defineConfig` helper (to define your ORM config) or `MikroORM` class (to call the `init` method) exported from the driver package (e.g. `import { defineConfig } from \'@mikro-orm/mysql\'; export default defineConfig({ ... })`).');
344
+ throw new Error("The `type` option has been removed in v6, please fill in the `driver` option instead or use `defineConfig` helper (to define your ORM config) or `MikroORM` class (to call the `init` method) exported from the driver package (e.g. `import { defineConfig } from '@mikro-orm/mysql'; export default defineConfig({ ... })`).");
342
345
  }
343
346
  if (!this.options.driver) {
344
- throw new Error('No driver specified, please fill in the `driver` option or use `defineConfig` helper (to define your ORM config) or `MikroORM` class (to call the `init` method) exported from the driver package (e.g. `import { defineConfig } from \'@mikro-orm/mysql\'; export defineConfig({ ... })`).');
347
+ throw new Error("No driver specified, please fill in the `driver` option or use `defineConfig` helper (to define your ORM config) or `MikroORM` class (to call the `init` method) exported from the driver package (e.g. `import { defineConfig } from '@mikro-orm/mysql'; export defineConfig({ ... })`).");
345
348
  }
346
349
  if (!this.options.dbName && !this.options.clientUrl) {
347
350
  throw new Error('No database specified, please fill in `dbName` or `clientUrl` option');
@@ -349,7 +352,8 @@ export class Configuration {
349
352
  if (this.options.entities.length === 0 && this.options.discovery.warnWhenNoEntities) {
350
353
  throw new Error('No entities found, please use `entities` option');
351
354
  }
352
- if (typeof this.options.driverOptions === 'function' && this.options.driverOptions.constructor.name === 'AsyncFunction') {
355
+ if (typeof this.options.driverOptions === 'function' &&
356
+ this.options.driverOptions.constructor.name === 'AsyncFunction') {
353
357
  throw new Error('`driverOptions` callback cannot be async');
354
358
  }
355
359
  }
package/utils/Cursor.js CHANGED
@@ -118,7 +118,7 @@ export class Cursor {
118
118
  value = value.unwrap();
119
119
  }
120
120
  if (object) {
121
- return ({ [prop]: value });
121
+ return { [prop]: value };
122
122
  }
123
123
  return value;
124
124
  };
@@ -167,7 +167,9 @@ export class Cursor {
167
167
  }
168
168
  const prop = meta.properties[key];
169
169
  /* v8 ignore next */
170
- if (!prop || !([ReferenceKind.SCALAR, ReferenceKind.EMBEDDED, ReferenceKind.MANY_TO_ONE].includes(prop.kind) || (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner))) {
170
+ if (!prop ||
171
+ !([ReferenceKind.SCALAR, ReferenceKind.EMBEDDED, ReferenceKind.MANY_TO_ONE].includes(prop.kind) ||
172
+ (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner))) {
171
173
  continue;
172
174
  }
173
175
  ret.push([prop.name, order[prop.name]]);
@@ -101,26 +101,27 @@ export class DataloaderUtils {
101
101
  const uniqueName = key.substring(0, key.indexOf('|'));
102
102
  const opts = JSON.parse(key.substring(key.indexOf('|') + 1));
103
103
  const meta = em.getMetadata().getByUniqueName(uniqueName);
104
- const res = await em.find(meta.class, opts?.where != null && Object.keys(opts.where).length > 0 ?
105
- {
104
+ const res = await em.find(meta.class, opts?.where != null && Object.keys(opts.where).length > 0
105
+ ? {
106
106
  $and: [
107
107
  {
108
108
  $or: Array.from(filterMap.entries()).map(([prop, pks]) => {
109
- return ({ [prop]: Array.from(pks) });
109
+ return { [prop]: Array.from(pks) };
110
110
  }),
111
111
  },
112
112
  opts.where,
113
113
  ],
114
- } : {
115
- // The entries of the filter Map will be used as the values of the $or operator
116
- $or: Array.from(filterMap.entries()).map(([prop, pks]) => {
117
- return ({ [prop]: Array.from(pks) });
118
- }),
119
- }, {
114
+ }
115
+ : {
116
+ // The entries of the filter Map will be used as the values of the $or operator
117
+ $or: Array.from(filterMap.entries()).map(([prop, pks]) => {
118
+ return { [prop]: Array.from(pks) };
119
+ }),
120
+ }, {
120
121
  ...opts,
121
122
  // We need to populate the inverse side of the relationship in order to be able to later retrieve the PK(s) from its item(s)
122
123
  populate: [
123
- ...(opts.populate === false ? [] : opts.populate ?? []),
124
+ ...(opts.populate === false ? [] : (opts.populate ?? [])),
124
125
  ...Array.from(filterMap.keys()).filter(
125
126
  // We need to do so only if the inverse side is a collection, because we can already retrieve the PK from a reference without having to load it
126
127
  prop => meta.properties[prop]?.ref !== true),
@@ -207,7 +208,9 @@ export class DataloaderUtils {
207
208
  options.refresh ??= c[1]?.refresh;
208
209
  }
209
210
  options.where = wrap({ $or });
210
- const r = await em.getEntityLoader().findChildrenFromPivotTable(owners, prop, options, orderBy, populate, group[0][1]?.ref);
211
+ const r = await em
212
+ .getEntityLoader()
213
+ .findChildrenFromPivotTable(owners, prop, options, orderBy, populate, group[0][1]?.ref);
211
214
  ret.push(...r);
212
215
  }
213
216
  return ret;
@@ -224,7 +227,7 @@ export class DataloaderUtils {
224
227
  }
225
228
  catch {
226
229
  /* v8 ignore next */
227
- throw new Error('DataLoader is not found, make sure `dataloader` package is installed in your project\'s dependencies.');
230
+ throw new Error("DataLoader is not found, make sure `dataloader` package is installed in your project's dependencies.");
228
231
  }
229
232
  }
230
233
  }
@@ -1,6 +1,6 @@
1
1
  import { clone } from './clone.js';
2
2
  import { ReferenceKind } from '../enums.js';
3
- import { compareArrays, compareBooleans, compareBuffers, compareObjects, equals, parseJsonSafe, Utils } from './Utils.js';
3
+ import { compareArrays, compareBooleans, compareBuffers, compareObjects, equals, parseJsonSafe, Utils, } from './Utils.js';
4
4
  import { JsonType } from '../types/JsonType.js';
5
5
  import { Raw } from './RawQueryFragment.js';
6
6
  import { EntityIdentifier } from '../entity/EntityIdentifier.js';
@@ -91,8 +91,7 @@ export class EntityComparator {
91
91
  }
92
92
  lines.push(` return entity${this.wrap(pk)};`);
93
93
  }
94
- const code = `// compiled pk getter for entity ${meta.className}\n`
95
- + `return function(entity) {\n${lines.join('\n')}\n}`;
94
+ const code = `// compiled pk getter for entity ${meta.className}\n` + `return function(entity) {\n${lines.join('\n')}\n}`;
96
95
  const fnKey = `pkGetter-${meta.uniqueName}`;
97
96
  const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
98
97
  this.pkGetters.set(meta, pkSerializer);
@@ -142,8 +141,8 @@ export class EntityComparator {
142
141
  lines.push(` return entity${this.wrap(pk)};`);
143
142
  }
144
143
  }
145
- const code = `// compiled pk getter (with converted custom types) for entity ${meta.className}\n`
146
- + `return function(entity) {\n${lines.join('\n')}\n}`;
144
+ const code = `// compiled pk getter (with converted custom types) for entity ${meta.className}\n` +
145
+ `return function(entity) {\n${lines.join('\n')}\n}`;
147
146
  const fnKey = `pkGetterConverted-${meta.uniqueName}`;
148
147
  const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
149
148
  this.pkGettersConverted.set(meta, pkSerializer);
@@ -195,8 +194,7 @@ export class EntityComparator {
195
194
  lines.push(` return '' + entity${this.wrap(pk)};`);
196
195
  }
197
196
  }
198
- const code = `// compiled pk serializer for entity ${meta.className}\n`
199
- + `return function(entity) {\n${lines.join('\n')}\n}`;
197
+ const code = `// compiled pk serializer for entity ${meta.className}\n` + `return function(entity) {\n${lines.join('\n')}\n}`;
200
198
  const fnKey = `pkSerializer-${meta.uniqueName}`;
201
199
  const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
202
200
  this.pkSerializers.set(meta, pkSerializer);
@@ -359,7 +357,7 @@ export class EntityComparator {
359
357
  context.set(`mapEmbeddedResult_${idx}`, (data) => {
360
358
  const item = parseJsonSafe(data);
361
359
  if (Array.isArray(item)) {
362
- return item.map(row => row == null ? row : this.getResultMapper(prop.targetMeta)(row));
360
+ return item.map(row => (row == null ? row : this.getResultMapper(prop.targetMeta)(row)));
363
361
  }
364
362
  return item == null ? item : this.getResultMapper(prop.targetMeta)(item);
365
363
  });
@@ -391,8 +389,8 @@ export class EntityComparator {
391
389
  mapEntityProperties(meta);
392
390
  }
393
391
  lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k] && ret[k] === undefined) ret[k] = result[k]; }`);
394
- const code = `// compiled mapper for entity ${meta.className}\n`
395
- + `return function(result) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
392
+ const code = `// compiled mapper for entity ${meta.className}\n` +
393
+ `return function(result) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
396
394
  const fnKey = `resultMapper-${meta.uniqueName}`;
397
395
  const resultMapper = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
398
396
  this.mappers.set(meta, resultMapper);
@@ -411,7 +409,7 @@ export class EntityComparator {
411
409
  return '';
412
410
  }
413
411
  const mapped = `typeof entity${tail ? '.' + tail : ''}${this.wrap(k)} !== 'undefined'`;
414
- tail += tail ? ('.' + k) : k;
412
+ tail += tail ? '.' + k : k;
415
413
  return mapped;
416
414
  })
417
415
  .filter(k => k)
@@ -453,12 +451,16 @@ export class EntityComparator {
453
451
  }
454
452
  else {
455
453
  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`;
454
+ ret +=
455
+ meta.props
456
+ .filter(p => p.embedded?.[0] === prop.name &&
457
+ // object for JSON embeddable
458
+ (p.object || p.persist !== false))
459
+ .map(childProp => {
460
+ const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
461
+ return `${padding} ret${childDataKey} = null;`;
462
+ })
463
+ .join('\n') + `\n`;
462
464
  ret += `${padding}}\n`;
463
465
  }
464
466
  const cond = `entity${path.map(k => this.wrap(k)).join('')} != null`;
@@ -475,28 +477,34 @@ export class EntityComparator {
475
477
  }
476
478
  return true;
477
479
  }
478
- ret += meta.props.filter(p => p.embedded?.[0] === prop.name
479
- // object for JSON embeddable
480
- && (p.object || (p.persist !== false))).map(childProp => {
481
- const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
482
- const childEntityKey = [...path, childProp.embedded[1]].map(k => this.wrap(k)).join('');
483
- const childCond = `typeof entity${childEntityKey} !== 'undefined'`;
484
- if (childProp.kind === ReferenceKind.EMBEDDED) {
485
- return this.getPropertySnapshot(meta, childProp, context, childDataKey, childEntityKey, [...path, childProp.embedded[1]], level + 1, prop.object);
486
- }
487
- if (childProp.kind !== ReferenceKind.SCALAR) {
488
- return this.getPropertySnapshot(meta, childProp, context, childDataKey, childEntityKey, [...path, childProp.embedded[1]], level, prop.object)
489
- .split('\n').map(l => padding + l).join('\n');
490
- }
491
- if (shouldProcessCustomType(childProp)) {
492
- const convertorKey = this.registerCustomType(childProp, context);
493
- if (['number', 'string', 'boolean', 'bigint'].includes(childProp.customType.compareAsType().toLowerCase())) {
494
- return `${padding} if (${childCond}) ret${childDataKey} = convertToDatabaseValue_${convertorKey}(entity${childEntityKey});`;
480
+ ret +=
481
+ meta.props
482
+ .filter(p => p.embedded?.[0] === prop.name &&
483
+ // object for JSON embeddable
484
+ (p.object || p.persist !== false))
485
+ .map(childProp => {
486
+ const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
487
+ const childEntityKey = [...path, childProp.embedded[1]].map(k => this.wrap(k)).join('');
488
+ const childCond = `typeof entity${childEntityKey} !== 'undefined'`;
489
+ if (childProp.kind === ReferenceKind.EMBEDDED) {
490
+ return this.getPropertySnapshot(meta, childProp, context, childDataKey, childEntityKey, [...path, childProp.embedded[1]], level + 1, prop.object);
495
491
  }
496
- return `${padding} if (${childCond}) ret${childDataKey} = clone(convertToDatabaseValue_${convertorKey}(entity${childEntityKey}));`;
497
- }
498
- return `${padding} if (${childCond}) ret${childDataKey} = clone(entity${childEntityKey});`;
499
- }).join('\n') + `\n`;
492
+ if (childProp.kind !== ReferenceKind.SCALAR) {
493
+ return this.getPropertySnapshot(meta, childProp, context, childDataKey, childEntityKey, [...path, childProp.embedded[1]], level, prop.object)
494
+ .split('\n')
495
+ .map(l => padding + l)
496
+ .join('\n');
497
+ }
498
+ if (shouldProcessCustomType(childProp)) {
499
+ const convertorKey = this.registerCustomType(childProp, context);
500
+ if (['number', 'string', 'boolean', 'bigint'].includes(childProp.customType.compareAsType().toLowerCase())) {
501
+ return `${padding} if (${childCond}) ret${childDataKey} = convertToDatabaseValue_${convertorKey}(entity${childEntityKey});`;
502
+ }
503
+ return `${padding} if (${childCond}) ret${childDataKey} = clone(convertToDatabaseValue_${convertorKey}(entity${childEntityKey}));`;
504
+ }
505
+ return `${padding} if (${childCond}) ret${childDataKey} = clone(entity${childEntityKey});`;
506
+ })
507
+ .join('\n') + `\n`;
500
508
  if (this.shouldSerialize(prop, dataKey)) {
501
509
  return `${ret + padding} ret${dataKey} = cloneEmbeddable(ret${dataKey});\n${padding}}`;
502
510
  }
@@ -591,7 +599,7 @@ export class EntityComparator {
591
599
  if (['number', 'string', 'boolean', 'bigint'].includes(prop.customType.compareAsType().toLowerCase())) {
592
600
  return ret + ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(entity${entityKey}${unwrap});\n }\n`;
593
601
  }
594
- return ret + ` ret${dataKey} = clone(convertToDatabaseValue_${convertorKey}(entity${entityKey}${unwrap}));\n }\n`;
602
+ return (ret + ` ret${dataKey} = clone(convertToDatabaseValue_${convertorKey}(entity${entityKey}${unwrap}));\n }\n`);
595
603
  }
596
604
  if (prop.runtimeType === 'Date') {
597
605
  context.set('processDateProperty', this.platform.processDateProperty.bind(this.platform));
@@ -626,22 +634,22 @@ export class EntityComparator {
626
634
  }
627
635
  }
628
636
  lines.push(`}`);
629
- const code = `// compiled comparator for entity ${meta.className}\n`
630
- + `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
637
+ const code = `// compiled comparator for entity ${meta.className}\n` +
638
+ `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
631
639
  const fnKey = `comparator-${meta.uniqueName}`;
632
640
  const comparator = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
633
641
  this.comparators.set(meta, comparator);
634
642
  return comparator;
635
643
  }
636
644
  getGenericComparator(prop, cond) {
637
- return ` if (current${prop} === null && last${prop} === undefined) {\n` +
645
+ return (` if (current${prop} === null && last${prop} === undefined) {\n` +
638
646
  ` diff${prop} = current${prop};\n` +
639
647
  ` } else if (current${prop} == null && last${prop} == null) {\n\n` +
640
648
  ` } else if ((current${prop} != null && last${prop} == null) || (current${prop} == null && last${prop} != null)) {\n` +
641
649
  ` diff${prop} = current${prop};\n` +
642
650
  ` } else if (${cond}) {\n` +
643
651
  ` diff${prop} = current${prop};\n` +
644
- ` }\n`;
652
+ ` }\n`);
645
653
  }
646
654
  getPropertyComparator(prop, context) {
647
655
  let type = prop.type.toLowerCase();
@@ -50,17 +50,21 @@ export class QueryHelper {
50
50
  }
51
51
  const keys = Object.keys(where);
52
52
  const groupOperator = keys.find(k => {
53
- return k in GroupOperator && Array.isArray(where[k]) && where[k].every(cond => {
54
- return Utils.isPlainObject(cond) && Object.keys(cond).every(k2 => {
55
- if (Utils.isOperator(k2, false)) {
56
- if (k2 === '$not') {
57
- return Object.keys(cond[k2]).every(k3 => meta.primaryKeys.includes(k3));
58
- }
59
- return true;
60
- }
61
- return meta.primaryKeys.includes(k2);
62
- });
63
- });
53
+ return (k in GroupOperator &&
54
+ Array.isArray(where[k]) &&
55
+ where[k].every(cond => {
56
+ return (Utils.isPlainObject(cond) &&
57
+ Object.keys(cond).every(k2 => {
58
+ if (Utils.isOperator(k2, false)) {
59
+ if (k2 === '$not') {
60
+ return Object.keys(cond[k2]).every(k3 => meta.primaryKeys.includes(k3));
61
+ }
62
+ /* v8 ignore next */
63
+ return true;
64
+ }
65
+ return meta.primaryKeys.includes(k2);
66
+ }));
67
+ }));
64
68
  });
65
69
  if (groupOperator) {
66
70
  return groupOperator;
@@ -96,15 +100,21 @@ export class QueryHelper {
96
100
  return false;
97
101
  }
98
102
  if (meta.primaryKeys.every(pk => pk in where) && Utils.getObjectKeysSize(where) === meta.primaryKeys.length) {
99
- return !!key && !GroupOperator[key] && key !== '$not' && Object.keys(where).every(k => !Utils.isPlainObject(where[k]) || Object.keys(where[k]).every(v => {
100
- if (Utils.isOperator(v, false)) {
101
- return true;
102
- }
103
- if (meta.properties[k].primary && [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(meta.properties[k].kind)) {
104
- return this.inlinePrimaryKeyObjects(where[k], meta.properties[k].targetMeta, metadata, v);
105
- }
106
- return true;
107
- }));
103
+ return (!!key &&
104
+ !GroupOperator[key] &&
105
+ key !== '$not' &&
106
+ Object.keys(where).every(k => !Utils.isPlainObject(where[k]) ||
107
+ Object.keys(where[k]).every(v => {
108
+ if (Utils.isOperator(v, false)) {
109
+ return true;
110
+ }
111
+ if (meta.properties[k].primary &&
112
+ [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(meta.properties[k].kind)) {
113
+ return this.inlinePrimaryKeyObjects(where[k], meta.properties[k].targetMeta, metadata, v);
114
+ }
115
+ /* v8 ignore next */
116
+ return true;
117
+ })));
108
118
  }
109
119
  Object.keys(where).forEach(k => {
110
120
  const meta2 = metadata.find(meta.properties[k]?.targetMeta?.class) || meta;
@@ -139,7 +149,9 @@ export class QueryHelper {
139
149
  let cond = { [rootPrimaryKey]: { $in: where } };
140
150
  // @ts-ignore
141
151
  // detect tuple comparison, use `$or` in case the number of constituents don't match
142
- if (meta && !where.every(c => Utils.isPrimaryKey(c) || (Array.isArray(c) && c.length === meta.primaryKeys.length && c.every(i => Utils.isPrimaryKey(i))))) {
152
+ if (meta &&
153
+ !where.every(c => Utils.isPrimaryKey(c) ||
154
+ (Array.isArray(c) && c.length === meta.primaryKeys.length && c.every(i => Utils.isPrimaryKey(i))))) {
143
155
  cond = { $or: where };
144
156
  }
145
157
  return QueryHelper.processWhere({ ...options, where: cond, root: false });
@@ -170,10 +182,12 @@ export class QueryHelper {
170
182
  if (prop?.customType && convertCustomTypes && !isRaw(value)) {
171
183
  value = QueryHelper.processCustomType(prop, value, platform, undefined, true);
172
184
  }
185
+ // oxfmt-ignore
173
186
  const isJsonProperty = prop?.customType instanceof JsonType && Utils.isPlainObject(value) && !isRaw(value) && Object.keys(value)[0] !== '$eq';
174
187
  if (isJsonProperty && prop?.kind !== ReferenceKind.EMBEDDED) {
175
188
  return this.processJsonCondition(o, value, [prop.fieldNames[0]], platform, aliased);
176
189
  }
190
+ // oxfmt-ignore
177
191
  if (Array.isArray(value) && !Utils.isOperator(key) && !QueryHelper.isSupportedOperator(key) && !(customExpression && Raw.getKnownFragment(key).params.length > 0) && options.type !== 'orderBy') {
178
192
  // comparing single composite key - use $eq instead of $in
179
193
  const op = composite && !value.every(v => Array.isArray(v)) ? '$eq' : '$in';
@@ -200,10 +214,10 @@ export class QueryHelper {
200
214
  }
201
215
  const opts = {};
202
216
  if (Array.isArray(options)) {
203
- options.forEach(filter => opts[filter] = true);
217
+ options.forEach(filter => (opts[filter] = true));
204
218
  }
205
219
  else if (Utils.isPlainObject(options)) {
206
- Object.keys(options).forEach(filter => opts[filter] = options[filter]);
220
+ Object.keys(options).forEach(filter => (opts[filter] = options[filter]));
207
221
  }
208
222
  return Object.keys(filters)
209
223
  .filter(f => QueryHelper.isFilterActive(meta, f, filters[f], opts))
@@ -252,9 +266,7 @@ export class QueryHelper {
252
266
  }, {});
253
267
  }
254
268
  if (key && JSON_KEY_OPERATORS.includes(key)) {
255
- return Array.isArray(cond)
256
- ? platform.marshallArray(cond)
257
- : cond;
269
+ return Array.isArray(cond) ? platform.marshallArray(cond) : cond;
258
270
  }
259
271
  if (Array.isArray(cond) && !(key && ARRAY_OPERATORS.includes(key))) {
260
272
  return cond.map(v => QueryHelper.processCustomType(prop, v, platform, key, fromQuery));
@@ -39,7 +39,8 @@ export class RawQueryFragment {
39
39
  return typeof key === 'symbol' && this.#rawQueryReferences.has(key);
40
40
  }
41
41
  static hasObjectFragments(object) {
42
- return Utils.isPlainObject(object) && Object.getOwnPropertySymbols(object).some(symbol => this.isKnownFragmentSymbol(symbol));
42
+ return (Utils.isPlainObject(object) &&
43
+ Object.getOwnPropertySymbols(object).some(symbol => this.isKnownFragmentSymbol(symbol)));
43
44
  }
44
45
  static isKnownFragment(key) {
45
46
  if (key instanceof RawQueryFragment) {
@@ -181,7 +182,7 @@ export function createSqlFunction(func, key) {
181
182
  if (typeof key === 'string') {
182
183
  return raw(`${func}(${key})`);
183
184
  }
184
- return raw(a => `${func}(${(key(a))})`);
185
+ return raw(a => `${func}(${key(a)})`);
185
186
  }
186
187
  sql.ref = (...keys) => raw('??', [keys.join('.')]);
187
188
  sql.now = (length) => raw('current_timestamp' + (length == null ? '' : `(${length})`));
@@ -183,7 +183,8 @@ export class TransactionManager {
183
183
  registerDeletionHandler(fork, parent) {
184
184
  fork.getEventManager().registerSubscriber({
185
185
  afterFlush: (args) => {
186
- const deletionChangeSets = args.uow.getChangeSets()
186
+ const deletionChangeSets = args.uow
187
+ .getChangeSets()
187
188
  .filter(cs => cs.type === ChangeSetType.DELETE || cs.type === ChangeSetType.DELETE_EARLY);
188
189
  for (const cs of deletionChangeSets) {
189
190
  parent.getUnitOfWork(false).unsetIdentity(cs.entity);
package/utils/Utils.d.ts CHANGED
@@ -147,7 +147,7 @@ export declare class Utils {
147
147
  static callCompiledFunction<T extends unknown[], R>(fn: (...args: T) => R, ...args: T): R;
148
148
  static unwrapProperty<T>(entity: T, meta: EntityMetadata<T>, prop: EntityProperty<T>, payload?: boolean): [unknown, number[]][];
149
149
  static setPayloadProperty<T>(entity: EntityDictionary<T>, meta: EntityMetadata<T>, prop: EntityProperty<T>, value: unknown, idx: number[]): void;
150
- static tryImport<T extends Dictionary = any>({ module, warning }: {
150
+ static tryImport<T extends Dictionary = any>({ module, warning, }: {
151
151
  module: string;
152
152
  warning?: string;
153
153
  }): Promise<T | undefined>;