@mikro-orm/core 6.4.7-dev.1 → 7.0.0-dev.1

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 (40) hide show
  1. package/EntityManager.d.ts +3 -2
  2. package/EntityManager.js +119 -101
  3. package/MikroORM.d.ts +8 -8
  4. package/MikroORM.js +1 -1
  5. package/README.md +0 -2
  6. package/connections/Connection.d.ts +3 -7
  7. package/drivers/DatabaseDriver.js +2 -6
  8. package/entity/Collection.js +8 -8
  9. package/entity/Reference.js +5 -5
  10. package/events/EventManager.js +4 -4
  11. package/events/TransactionEventBroadcaster.d.ts +1 -5
  12. package/events/TransactionEventBroadcaster.js +6 -9
  13. package/index.mjs +2 -0
  14. package/logging/Logger.d.ts +1 -1
  15. package/metadata/MetadataDiscovery.js +12 -0
  16. package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
  17. package/naming-strategy/NamingStrategy.d.ts +1 -1
  18. package/package.json +3 -3
  19. package/platforms/Platform.d.ts +13 -4
  20. package/platforms/Platform.js +26 -6
  21. package/serialization/EntitySerializer.js +2 -1
  22. package/serialization/EntityTransformer.js +2 -1
  23. package/typings.d.ts +12 -4
  24. package/typings.js +23 -6
  25. package/unit-of-work/ChangeSetComputer.d.ts +1 -1
  26. package/unit-of-work/ChangeSetComputer.js +9 -9
  27. package/unit-of-work/ChangeSetPersister.d.ts +1 -1
  28. package/unit-of-work/ChangeSetPersister.js +19 -18
  29. package/unit-of-work/UnitOfWork.js +1 -1
  30. package/utils/AbstractSchemaGenerator.js +3 -1
  31. package/utils/Configuration.d.ts +6 -20
  32. package/utils/Configuration.js +11 -5
  33. package/utils/ConfigurationLoader.js +7 -8
  34. package/utils/DataloaderUtils.d.ts +0 -2
  35. package/utils/DataloaderUtils.js +0 -10
  36. package/utils/QueryHelper.js +5 -5
  37. package/utils/RawQueryFragment.d.ts +2 -0
  38. package/utils/RawQueryFragment.js +8 -2
  39. package/utils/Utils.d.ts +1 -1
  40. package/utils/Utils.js +1 -1
package/typings.d.ts CHANGED
@@ -1,12 +1,18 @@
1
1
  import type { Transaction } from './connections';
2
2
  import { type Cascade, type DeferMode, type EventType, type LoadStrategy, type PopulatePath, type QueryOrderMap, ReferenceKind } from './enums';
3
- import { type AssignOptions, type Collection, type EntityFactory, type EntityIdentifier, type EntityLoaderOptions, type EntityRepository, Reference, type ScalarReference } from './entity';
3
+ import { type AssignOptions } from './entity/EntityAssigner';
4
+ import { type EntityIdentifier } from './entity/EntityIdentifier';
5
+ import { type EntityLoaderOptions } from './entity/EntityLoader';
6
+ import { type Collection } from './entity/Collection';
7
+ import { type EntityFactory } from './entity/EntityFactory';
8
+ import { type EntityRepository } from './entity/EntityRepository';
9
+ import { Reference, type ScalarReference } from './entity/Reference';
4
10
  import type { MikroORM } from './MikroORM';
5
11
  import type { SerializationContext, SerializeOptions } from './serialization';
6
12
  import type { EntitySchema, MetadataStorage } from './metadata';
7
13
  import type { Type, types } from './types';
8
14
  import type { Platform } from './platforms';
9
- import type { Configuration } from './utils';
15
+ import type { Configuration, RawQueryFragment } from './utils';
10
16
  import type { EntityManager } from './EntityManager';
11
17
  import type { EmbeddedPrefixMode } from './decorators/Embedded';
12
18
  import type { EventSubscriber } from './events';
@@ -391,7 +397,7 @@ export declare class EntityMetadata<T = any> {
391
397
  getPrimaryProp(): EntityProperty<T>;
392
398
  get tableName(): string;
393
399
  set tableName(name: string);
394
- sync(initIndexes?: boolean): void;
400
+ sync(initIndexes?: boolean, config?: Configuration): void;
395
401
  private initIndexes;
396
402
  /** @internal */
397
403
  clone(): this;
@@ -407,7 +413,7 @@ export interface EntityMetadata<T = any> {
407
413
  schema?: string;
408
414
  pivotTable?: boolean;
409
415
  virtual?: boolean;
410
- expression?: string | ((em: any, where: FilterQuery<T>, options: FindOptions<T, any, any, any>) => MaybePromise<object | string>);
416
+ expression?: string | ((em: any, where: FilterQuery<T>, options: FindOptions<T, any, any, any>) => MaybePromise<RawQueryFragment | object | string>);
411
417
  discriminatorColumn?: EntityKey<T> | AnyString;
412
418
  discriminatorValue?: number | string;
413
419
  discriminatorMap?: Dictionary<string>;
@@ -505,6 +511,7 @@ export interface UpdateSchemaOptions<DatabaseSchema = unknown> {
505
511
  export interface RefreshDatabaseOptions extends CreateSchemaOptions {
506
512
  ensureIndexes?: boolean;
507
513
  dropDb?: boolean;
514
+ createSchema?: boolean;
508
515
  }
509
516
  export interface ISchemaGenerator {
510
517
  createSchema(options?: CreateSchemaOptions): Promise<void>;
@@ -577,6 +584,7 @@ export type MigrationResult = {
577
584
  diff: MigrationDiff;
578
585
  };
579
586
  export type MigrationRow = {
587
+ id: number;
580
588
  name: string;
581
589
  executed_at: Date;
582
590
  };
package/typings.js CHANGED
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EntityMetadata = exports.Config = exports.HiddenProps = exports.EagerProps = exports.OptionalProps = exports.PrimaryKeyProp = exports.EntityRepositoryType = void 0;
4
4
  const enums_1 = require("./enums");
5
- const entity_1 = require("./entity");
5
+ const Reference_1 = require("./entity/Reference");
6
+ const EntityHelper_1 = require("./entity/EntityHelper");
6
7
  const Utils_1 = require("./utils/Utils");
7
8
  const EntityComparator_1 = require("./utils/EntityComparator");
8
9
  exports.EntityRepositoryType = Symbol('EntityRepositoryType');
@@ -59,7 +60,7 @@ class EntityMetadata {
59
60
  set tableName(name) {
60
61
  this.collection = name;
61
62
  }
62
- sync(initIndexes = false) {
63
+ sync(initIndexes = false, config) {
63
64
  this.root ??= this;
64
65
  const props = Object.values(this.properties).sort((a, b) => this.propertyOrder.get(a.name) - this.propertyOrder.get(b.name));
65
66
  this.props = [...props.filter(p => p.primary), ...props.filter(p => !p.primary)];
@@ -82,6 +83,22 @@ class EntityMetadata {
82
83
  this.selfReferencing = this.relations.some(prop => [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type));
83
84
  this.hasUniqueProps = this.uniques.length + this.uniqueProps.length > 0;
84
85
  this.virtual = !!this.expression;
86
+ if (config) {
87
+ for (const prop of this.props) {
88
+ if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => Utils_1.Utils.isString(item))) {
89
+ const name = config.getNamingStrategy().indexName(this.tableName, prop.fieldNames, 'check');
90
+ const exists = this.checks.findIndex(check => check.name === name);
91
+ if (exists !== -1) {
92
+ this.checks.splice(exists, 1);
93
+ }
94
+ this.checks.push({
95
+ name,
96
+ property: prop.name,
97
+ expression: `${config.getPlatform().quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
98
+ });
99
+ }
100
+ }
101
+ }
85
102
  this.checks = Utils_1.Utils.removeDuplicates(this.checks);
86
103
  this.indexes = Utils_1.Utils.removeDuplicates(this.indexes);
87
104
  this.uniques = Utils_1.Utils.removeDuplicates(this.uniques);
@@ -107,9 +124,9 @@ class EntityMetadata {
107
124
  set(val) {
108
125
  const wrapped = this.__helper;
109
126
  const hydrator = wrapped.hydrator;
110
- const entity = entity_1.Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
111
- const old = entity_1.Reference.unwrapReference(wrapped.__data[prop.name]);
112
- wrapped.__data[prop.name] = entity_1.Reference.wrapReference(val, prop);
127
+ const entity = Reference_1.Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
128
+ const old = Reference_1.Reference.unwrapReference(wrapped.__data[prop.name]);
129
+ wrapped.__data[prop.name] = Reference_1.Reference.wrapReference(val, prop);
113
130
  // when propagation from inside hydration, we set the FK to the entity data immediately
114
131
  if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
115
132
  wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(val, prop.targetMeta.primaryKeys, true);
@@ -117,7 +134,7 @@ class EntityMetadata {
117
134
  else {
118
135
  wrapped.__touched = !hydrator.isRunning();
119
136
  }
120
- entity_1.EntityHelper.propagate(meta, entity, this, prop, entity_1.Reference.unwrapReference(val), old);
137
+ EntityHelper_1.EntityHelper.propagate(meta, entity, this, prop, Reference_1.Reference.unwrapReference(val), old);
121
138
  },
122
139
  enumerable: true,
123
140
  configurable: true,
@@ -1,4 +1,4 @@
1
- import { type Configuration } from '../utils';
1
+ import { type Configuration } from '../utils/Configuration';
2
2
  import type { MetadataStorage } from '../metadata';
3
3
  import type { AnyEntity } from '../typings';
4
4
  import { ChangeSet } from './ChangeSet';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ChangeSetComputer = void 0;
4
- const utils_1 = require("../utils");
4
+ const Utils_1 = require("../utils/Utils");
5
5
  const ChangeSet_1 = require("./ChangeSet");
6
6
  const entity_1 = require("../entity");
7
7
  const enums_1 = require("../enums");
@@ -48,7 +48,7 @@ class ChangeSetComputer {
48
48
  for (const prop of meta.relations.filter(prop => prop.persist !== false || prop.userDefined === false)) {
49
49
  this.processProperty(changeSet, prop);
50
50
  }
51
- if (changeSet.type === ChangeSet_1.ChangeSetType.UPDATE && !utils_1.Utils.hasObjectKeys(changeSet.payload)) {
51
+ if (changeSet.type === ChangeSet_1.ChangeSetType.UPDATE && !Utils_1.Utils.hasObjectKeys(changeSet.payload)) {
52
52
  return null;
53
53
  }
54
54
  // Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
@@ -66,7 +66,7 @@ class ChangeSetComputer {
66
66
  }
67
67
  // Recompute the changeset, we need to merge this as here we ignore relations.
68
68
  const diff = this.computePayload(entity, true);
69
- utils_1.Utils.merge(changeSet.payload, diff);
69
+ Utils_1.Utils.merge(changeSet.payload, diff);
70
70
  }
71
71
  return changeSet;
72
72
  }
@@ -77,7 +77,7 @@ class ChangeSetComputer {
77
77
  if (prop.onCreate
78
78
  && type === ChangeSet_1.ChangeSetType.CREATE
79
79
  && (entity[prop.name] == null
80
- || (utils_1.Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
80
+ || (Utils_1.Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
81
81
  entity[prop.name] = prop.onCreate(entity, this.em);
82
82
  }
83
83
  if (prop.onUpdate && type === ChangeSet_1.ChangeSetType.UPDATE) {
@@ -106,7 +106,7 @@ class ChangeSetComputer {
106
106
  const comparator = this.comparator.getEntityComparator(entityName);
107
107
  const diff = comparator(originalEntityData, data);
108
108
  if (ignoreUndefined) {
109
- utils_1.Utils.keys(diff)
109
+ Utils_1.Utils.keys(diff)
110
110
  .filter(k => diff[k] === undefined)
111
111
  .forEach(k => delete diff[k]);
112
112
  }
@@ -116,11 +116,11 @@ class ChangeSetComputer {
116
116
  }
117
117
  processProperty(changeSet, prop, target) {
118
118
  if (!target) {
119
- const targets = utils_1.Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
119
+ const targets = Utils_1.Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
120
120
  targets.forEach(([t]) => this.processProperty(changeSet, prop, t));
121
121
  return;
122
122
  }
123
- if (utils_1.Utils.isCollection(target)) { // m:n or 1:m
123
+ if (Utils_1.Utils.isCollection(target)) { // m:n or 1:m
124
124
  this.processToMany(prop, changeSet);
125
125
  }
126
126
  if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
@@ -132,10 +132,10 @@ class ChangeSetComputer {
132
132
  if (!isToOneOwner || prop.mapToPk) {
133
133
  return;
134
134
  }
135
- const targets = utils_1.Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
135
+ const targets = Utils_1.Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
136
136
  targets.forEach(([target, idx]) => {
137
137
  if (!target.__helper.hasPrimaryKey()) {
138
- utils_1.Utils.setPayloadProperty(changeSet.payload, this.metadata.find(changeSet.name), prop, target.__helper.__identifier, idx);
138
+ Utils_1.Utils.setPayloadProperty(changeSet.payload, this.metadata.find(changeSet.name), prop, target.__helper.__identifier, idx);
139
139
  }
140
140
  });
141
141
  }
@@ -2,7 +2,7 @@ import type { MetadataStorage } from '../metadata';
2
2
  import type { Dictionary, EntityDictionary, EntityMetadata, IHydrator } from '../typings';
3
3
  import { type EntityFactory, type EntityValidator } from '../entity';
4
4
  import { type ChangeSet } from './ChangeSet';
5
- import { type Configuration } from '../utils';
5
+ import { type Configuration } from '../utils/Configuration';
6
6
  import type { DriverMethodOptions, IDatabaseDriver } from '../drivers';
7
7
  export declare class ChangeSetPersister {
8
8
  private readonly driver;
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ChangeSetPersister = void 0;
4
4
  const entity_1 = require("../entity");
5
5
  const ChangeSet_1 = require("./ChangeSet");
6
- const utils_1 = require("../utils");
6
+ const RawQueryFragment_1 = require("../utils/RawQueryFragment");
7
+ const Utils_1 = require("../utils/Utils");
7
8
  const errors_1 = require("../errors");
8
9
  const enums_1 = require("../enums");
9
10
  class ChangeSetPersister {
@@ -59,7 +60,7 @@ class ChangeSetPersister {
59
60
  }
60
61
  const size = this.config.get('batchSize');
61
62
  const meta = changeSets[0].meta;
62
- const pk = utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
63
+ const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
63
64
  for (let i = 0; i < changeSets.length; i += size) {
64
65
  const chunk = changeSets.slice(i, i + size);
65
66
  const pks = chunk.map(cs => cs.getPrimaryKey());
@@ -190,7 +191,7 @@ class ChangeSetPersister {
190
191
  }
191
192
  const res = await this.driver.nativeUpdateMany(meta.className, cond, payload, options);
192
193
  const map = new Map();
193
- res.rows?.forEach(item => map.set(utils_1.Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
194
+ res.rows?.forEach(item => map.set(Utils_1.Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
194
195
  for (const changeSet of changeSets) {
195
196
  if (res.rows) {
196
197
  const row = map.get((0, entity_1.helper)(changeSet.entity).getSerializedPrimaryKey());
@@ -224,10 +225,10 @@ class ChangeSetPersister {
224
225
  (0, entity_1.helper)(changeSet.entity).populated();
225
226
  meta.relations.forEach(prop => {
226
227
  const value = changeSet.entity[prop.name];
227
- if (utils_1.Utils.isEntity(value, true)) {
228
+ if (Utils_1.Utils.isEntity(value, true)) {
228
229
  value.__helper.populated();
229
230
  }
230
- else if (utils_1.Utils.isCollection(value)) {
231
+ else if (Utils_1.Utils.isCollection(value)) {
231
232
  value.populated();
232
233
  }
233
234
  });
@@ -253,7 +254,7 @@ class ChangeSetPersister {
253
254
  // skip entity references as they don't have version values loaded
254
255
  changeSets = changeSets.filter(cs => (0, entity_1.helper)(cs.entity).__initialized);
255
256
  const $or = changeSets.map(cs => {
256
- const cond = utils_1.Utils.getPrimaryKeyCond(cs.originalEntity, meta.primaryKeys.concat(...meta.concurrencyCheckKeys));
257
+ const cond = Utils_1.Utils.getPrimaryKeyCond(cs.originalEntity, meta.primaryKeys.concat(...meta.concurrencyCheckKeys));
257
258
  if (meta.versionProperty) {
258
259
  // @ts-ignore
259
260
  cond[meta.versionProperty] = this.platform.quoteVersionValue(cs.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
@@ -268,7 +269,7 @@ class ChangeSetPersister {
268
269
  if (res.length !== changeSets.length) {
269
270
  const compare = (a, b, keys) => keys.every(k => a[k] === b[k]);
270
271
  const entity = changeSets.find(cs => {
271
- return !res.some(row => compare(utils_1.Utils.getPrimaryKeyCond(cs.entity, primaryKeys), row, primaryKeys));
272
+ return !res.some(row => compare(Utils_1.Utils.getPrimaryKeyCond(cs.entity, primaryKeys), row, primaryKeys));
272
273
  }).entity;
273
274
  throw errors_1.OptimisticLockError.lockFailed(entity);
274
275
  }
@@ -288,14 +289,14 @@ class ChangeSetPersister {
288
289
  // do not reload things that already had a runtime value
289
290
  meta.props
290
291
  .filter(prop => prop.persist !== false && (prop.autoincrement || prop.generated || prop.defaultRaw))
291
- .filter(prop => (changeSets[0].entity[prop.name] == null && prop.defaultRaw !== 'null') || utils_1.Utils.isRawSql(changeSets[0].entity[prop.name]))
292
+ .filter(prop => (changeSets[0].entity[prop.name] == null && prop.defaultRaw !== 'null') || (0, RawQueryFragment_1.isRaw)(changeSets[0].entity[prop.name]))
292
293
  .forEach(prop => reloadProps.push(prop));
293
294
  }
294
295
  if (changeSets[0].type === ChangeSet_1.ChangeSetType.UPDATE) {
295
296
  const returning = new Set();
296
297
  changeSets.forEach(cs => {
297
- utils_1.Utils.keys(cs.payload).forEach(k => {
298
- if (utils_1.Utils.isRawSql(cs.payload[k]) && utils_1.Utils.isRawSql(cs.entity[k])) {
298
+ Utils_1.Utils.keys(cs.payload).forEach(k => {
299
+ if ((0, RawQueryFragment_1.isRaw)(cs.payload[k]) && (0, RawQueryFragment_1.isRaw)(cs.entity[k])) {
299
300
  returning.add(meta.properties[k]);
300
301
  }
301
302
  });
@@ -312,20 +313,20 @@ class ChangeSetPersister {
312
313
  return;
313
314
  }
314
315
  reloadProps.unshift(...meta.getPrimaryProps());
315
- const pk = utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
316
+ const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
316
317
  const pks = changeSets.map(cs => {
317
318
  const val = (0, entity_1.helper)(cs.entity).getPrimaryKey(true);
318
- if (utils_1.Utils.isPlainObject(val)) {
319
- return utils_1.Utils.getCompositeKeyValue(val, meta, false, this.platform);
319
+ if (Utils_1.Utils.isPlainObject(val)) {
320
+ return Utils_1.Utils.getCompositeKeyValue(val, meta, false, this.platform);
320
321
  }
321
322
  return val;
322
323
  });
323
324
  options = this.propagateSchemaFromMetadata(meta, options, {
324
- fields: utils_1.Utils.unique(reloadProps.map(prop => prop.name)),
325
+ fields: Utils_1.Utils.unique(reloadProps.map(prop => prop.name)),
325
326
  });
326
327
  const data = await this.driver.find(meta.className, { [pk]: { $in: pks } }, options);
327
328
  const map = new Map();
328
- data.forEach(item => map.set(utils_1.Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
329
+ data.forEach(item => map.set(Utils_1.Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
329
330
  for (const changeSet of changeSets) {
330
331
  const data = map.get((0, entity_1.helper)(changeSet.entity).getSerializedPrimaryKey());
331
332
  this.hydrator.hydrate(changeSet.entity, meta, data, this.factory, 'full', false, true);
@@ -346,10 +347,10 @@ class ChangeSetPersister {
346
347
  if (prop.name in changeSet.payload) {
347
348
  return;
348
349
  }
349
- const values = utils_1.Utils.unwrapProperty(changeSet.payload, meta, prop, true); // for object embeddables
350
+ const values = Utils_1.Utils.unwrapProperty(changeSet.payload, meta, prop, true); // for object embeddables
350
351
  values.forEach(([value, indexes]) => {
351
352
  if (value instanceof entity_1.EntityIdentifier) {
352
- utils_1.Utils.setPayloadProperty(changeSet.payload, meta, prop, value.getValue(), indexes);
353
+ Utils_1.Utils.setPayloadProperty(changeSet.payload, meta, prop, value.getValue(), indexes);
353
354
  }
354
355
  });
355
356
  }
@@ -359,7 +360,7 @@ class ChangeSetPersister {
359
360
  * We do need to map to the change set payload too, as it will be used in the originalEntityData for new entities.
360
361
  */
361
362
  mapReturnedValues(entity, payload, row, meta, upsert = false) {
362
- if ((!this.usesReturningStatement && !upsert) || !row || !utils_1.Utils.hasObjectKeys(row)) {
363
+ if ((!this.usesReturningStatement && !upsert) || !row || !Utils_1.Utils.hasObjectKeys(row)) {
363
364
  return;
364
365
  }
365
366
  const mapped = this.comparator.mapResult(meta.className, row);
@@ -313,7 +313,7 @@ class UnitOfWork {
313
313
  if (runInTransaction) {
314
314
  await this.em.getConnection('write').transactional(trx => this.persistToDatabase(groups, trx), {
315
315
  ctx: oldTx,
316
- eventBroadcaster: new events_1.TransactionEventBroadcaster(this.em, this),
316
+ eventBroadcaster: new events_1.TransactionEventBroadcaster(this.em),
317
317
  });
318
318
  }
319
319
  else {
@@ -37,7 +37,9 @@ class AbstractSchemaGenerator {
37
37
  await this.ensureDatabase();
38
38
  await this.dropSchema();
39
39
  }
40
- await this.createSchema(options);
40
+ if (options?.createSchema !== false) {
41
+ await this.createSchema(options);
42
+ }
41
43
  }
42
44
  async clearDatabase(options) {
43
45
  for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
@@ -2,7 +2,7 @@ import type { NamingStrategy } from '../naming-strategy';
2
2
  import { FileCacheAdapter, type SyncCacheAdapter, type CacheAdapter } from '../cache';
3
3
  import type { EntityRepository } from '../entity/EntityRepository';
4
4
  import type { AnyEntity, Constructor, Dictionary, EntityClass, EntityClassGroup, FilterDef, Highlighter, HydratorConstructor, IHydrator, IMigrationGenerator, IPrimaryKey, MaybePromise, MigrationObject, EntityMetadata, EnsureDatabaseOptions, GenerateOptions, Migration } from '../typings';
5
- import { ObjectHydrator } from '../hydration';
5
+ import { ObjectHydrator } from '../hydration/ObjectHydrator';
6
6
  import { NullHighlighter } from '../utils/NullHighlighter';
7
7
  import { type Logger, type LoggerNamespace, type LoggerOptions } from '../logging';
8
8
  import type { EntityManager } from '../EntityManager';
@@ -150,6 +150,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
150
150
  private readonly cache;
151
151
  private readonly extensions;
152
152
  constructor(options: Options, validate?: boolean);
153
+ getPlatform(): ReturnType<D['getPlatform']>;
153
154
  /**
154
155
  * Gets specific configuration option. Falls back to specified `defaultValue` if provided.
155
156
  */
@@ -167,7 +168,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
167
168
  * Gets Logger instance.
168
169
  */
169
170
  getLogger(): Logger;
170
- getPlatform(): Platform;
171
+ getDataloaderType(): DataloaderType;
171
172
  /**
172
173
  * Gets current client URL (connection string).
173
174
  */
@@ -231,10 +232,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
231
232
  * Type helper to make it easier to use `mikro-orm.config.js`.
232
233
  */
233
234
  export declare function defineConfig<D extends IDatabaseDriver>(options: Options<D>): Options<D, D[typeof EntityManagerType] & EntityManager<IDatabaseDriver<import("..").Connection>>>;
234
- export interface DynamicPassword {
235
- password: string;
236
- expirationChecker?: () => boolean;
237
- }
238
235
  export interface ConnectionOptions {
239
236
  dbName?: string;
240
237
  schema?: string;
@@ -243,12 +240,13 @@ export interface ConnectionOptions {
243
240
  host?: string;
244
241
  port?: number;
245
242
  user?: string;
246
- password?: string | (() => MaybePromise<string> | MaybePromise<DynamicPassword>);
243
+ password?: string | (() => MaybePromise<string>);
247
244
  charset?: string;
248
245
  collate?: string;
249
246
  multipleStatements?: boolean;
250
247
  pool?: PoolConfig;
251
248
  driverOptions?: Dictionary;
249
+ onCreateConnection?: (connection: unknown) => Promise<void>;
252
250
  }
253
251
  export type MigrationsOptions = {
254
252
  tableName?: string;
@@ -277,21 +275,9 @@ export interface SeederOptions {
277
275
  fileName?: (className: string) => string;
278
276
  }
279
277
  export interface PoolConfig {
280
- name?: string;
281
- afterCreate?: Function;
282
278
  min?: number;
283
279
  max?: number;
284
- refreshIdle?: boolean;
285
280
  idleTimeoutMillis?: number;
286
- reapIntervalMillis?: number;
287
- returnToHead?: boolean;
288
- priorityRange?: number;
289
- log?: (message: string, logLevel: string) => void;
290
- propagateCreateError?: boolean;
291
- createRetryIntervalMillis?: number;
292
- createTimeoutMillis?: number;
293
- destroyTimeoutMillis?: number;
294
- acquireTimeoutMillis?: number;
295
281
  }
296
282
  export interface MetadataDiscoveryOptions {
297
283
  warnWhenNoEntities?: boolean;
@@ -330,7 +316,7 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
330
316
  connect: boolean;
331
317
  verbose: boolean;
332
318
  ignoreUndefinedInQuery?: boolean;
333
- onQuery: (sql: string, params: unknown[]) => string;
319
+ onQuery: (sql: string, params: readonly unknown[]) => string;
334
320
  autoJoinOneToOneOwner: boolean;
335
321
  autoJoinRefsForFilters: boolean;
336
322
  propagationOnPrototype: boolean;
@@ -4,7 +4,7 @@ exports.Configuration = void 0;
4
4
  exports.defineConfig = defineConfig;
5
5
  const fs_extra_1 = require("fs-extra");
6
6
  const cache_1 = require("../cache");
7
- const hydration_1 = require("../hydration");
7
+ const ObjectHydrator_1 = require("../hydration/ObjectHydrator");
8
8
  const NullHighlighter_1 = require("../utils/NullHighlighter");
9
9
  const logging_1 = require("../logging");
10
10
  const Utils_1 = require("../utils/Utils");
@@ -45,7 +45,7 @@ class Configuration {
45
45
  findOneOrFailHandler: (entityName, where) => errors_1.NotFoundError.findOneFailed(entityName, where),
46
46
  findExactlyOneOrFailHandler: (entityName, where) => errors_1.NotFoundError.findExactlyOneFailed(entityName, where),
47
47
  baseDir: process.cwd(),
48
- hydrator: hydration_1.ObjectHydrator,
48
+ hydrator: ObjectHydrator_1.ObjectHydrator,
49
49
  flushMode: enums_1.FlushMode.AUTO,
50
50
  loadStrategy: enums_1.LoadStrategy.JOINED,
51
51
  dataloader: enums_1.DataloaderType.NONE,
@@ -167,6 +167,9 @@ class Configuration {
167
167
  this.init(validate);
168
168
  }
169
169
  }
170
+ getPlatform() {
171
+ return this.platform;
172
+ }
170
173
  /**
171
174
  * Gets specific configuration option. Falls back to specified `defaultValue` if provided.
172
175
  */
@@ -198,8 +201,11 @@ class Configuration {
198
201
  getLogger() {
199
202
  return this.logger;
200
203
  }
201
- getPlatform() {
202
- return this.platform;
204
+ getDataloaderType() {
205
+ if (typeof this.options.dataloader === 'boolean') {
206
+ return this.options.dataloader ? enums_1.DataloaderType.ALL : enums_1.DataloaderType.NONE;
207
+ }
208
+ return this.options.dataloader;
203
209
  }
204
210
  /**
205
211
  * Gets current client URL (connection string).
@@ -306,7 +312,7 @@ class Configuration {
306
312
  this.options.metadataCache.enabled = this.getMetadataProvider().useCache();
307
313
  }
308
314
  if (!this.options.clientUrl) {
309
- this.options.clientUrl = this.driver.getConnection().getDefaultClientUrl();
315
+ this.options.clientUrl = this.platform.getDefaultClientUrl();
310
316
  }
311
317
  if (!('implicitTransactions' in this.options)) {
312
318
  this.options.implicitTransactions = this.platform.usesImplicitTransactions();
@@ -225,14 +225,13 @@ class ConfigurationLoader {
225
225
  const ret = {};
226
226
  // only to keep some sort of back compatibility with those using env vars only, to support `MIKRO_ORM_TYPE`
227
227
  const PLATFORMS = {
228
- 'mongo': { className: 'MongoDriver', module: '@mikro-orm/mongodb' },
229
- 'mysql': { className: 'MySqlDriver', module: '@mikro-orm/mysql' },
230
- 'mssql': { className: 'MsSqlDriver', module: '@mikro-orm/mssql' },
231
- 'mariadb': { className: 'MariaDbDriver', module: '@mikro-orm/mariadb' },
232
- 'postgresql': { className: 'PostgreSqlDriver', module: '@mikro-orm/postgresql' },
233
- 'sqlite': { className: 'SqliteDriver', module: '@mikro-orm/sqlite' },
234
- 'better-sqlite': { className: 'BetterSqliteDriver', module: '@mikro-orm/better-sqlite' },
235
- 'libsql': { className: 'LibSqlDriver', module: '@mikro-orm/libsql' },
228
+ mongo: { className: 'MongoDriver', module: '@mikro-orm/mongodb' },
229
+ mysql: { className: 'MySqlDriver', module: '@mikro-orm/mysql' },
230
+ mssql: { className: 'MsSqlDriver', module: '@mikro-orm/mssql' },
231
+ mariadb: { className: 'MariaDbDriver', module: '@mikro-orm/mariadb' },
232
+ postgresql: { className: 'PostgreSqlDriver', module: '@mikro-orm/postgresql' },
233
+ sqlite: { className: 'SqliteDriver', module: '@mikro-orm/sqlite' },
234
+ libsql: { className: 'LibSqlDriver', module: '@mikro-orm/libsql' },
236
235
  };
237
236
  const array = (v) => v.split(',').map(vv => vv.trim());
238
237
  const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
@@ -2,7 +2,6 @@ import type { Primary, Ref } from '../typings';
2
2
  import { Collection, type InitCollectionOptions } from '../entity/Collection';
3
3
  import { type EntityManager } from '../EntityManager';
4
4
  import type DataLoader from 'dataloader';
5
- import { DataloaderType } from '../enums';
6
5
  import { type LoadReferenceOptions } from '../entity/Reference';
7
6
  export declare class DataloaderUtils {
8
7
  /**
@@ -39,5 +38,4 @@ export declare class DataloaderUtils {
39
38
  * makes one query per entity and maps each input collection to the corresponding result.
40
39
  */
41
40
  static getColBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
42
- static getDataloaderType(dataloaderCfg: DataloaderType | boolean): DataloaderType;
43
41
  }
@@ -182,15 +182,5 @@ class DataloaderUtils {
182
182
  });
183
183
  };
184
184
  }
185
- static getDataloaderType(dataloaderCfg) {
186
- switch (dataloaderCfg) {
187
- case true:
188
- return enums_1.DataloaderType.ALL;
189
- case false:
190
- return enums_1.DataloaderType.NONE;
191
- default:
192
- return dataloaderCfg;
193
- }
194
- }
195
185
  }
196
186
  exports.DataloaderUtils = DataloaderUtils;
@@ -74,7 +74,7 @@ class QueryHelper {
74
74
  if (meta && root) {
75
75
  QueryHelper.inlinePrimaryKeyObjects(where, meta, metadata);
76
76
  }
77
- if (options.platform.getConfig().get('ignoreUndefinedInQuery') && where && typeof where === 'object') {
77
+ if (platform.getConfig().get('ignoreUndefinedInQuery') && where && typeof where === 'object') {
78
78
  Utils_1.Utils.dropUndefinedProperties(where);
79
79
  }
80
80
  where = QueryHelper.processParams(where) ?? {};
@@ -112,15 +112,15 @@ class QueryHelper {
112
112
  return o;
113
113
  }
114
114
  // wrap top level operators (except platform allowed operators) with PK
115
- if (Utils_1.Utils.isOperator(key) && root && meta && !options.platform.isAllowedTopLevelOperator(key)) {
115
+ if (Utils_1.Utils.isOperator(key) && root && meta && !platform.isAllowedTopLevelOperator(key)) {
116
116
  const rootPrimaryKey = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
117
117
  o[rootPrimaryKey] = { [key]: QueryHelper.processWhere({ ...options, where: value, root: false }) };
118
118
  return o;
119
119
  }
120
- if (prop?.customType && convertCustomTypes && !platform.isRaw(value)) {
120
+ if (prop?.customType && convertCustomTypes && !(0, RawQueryFragment_1.isRaw)(value)) {
121
121
  value = QueryHelper.processCustomType(prop, value, platform, undefined, true);
122
122
  }
123
- const isJsonProperty = prop?.customType instanceof JsonType_1.JsonType && Utils_1.Utils.isPlainObject(value) && !platform.isRaw(value) && Object.keys(value)[0] !== '$eq';
123
+ const isJsonProperty = prop?.customType instanceof JsonType_1.JsonType && Utils_1.Utils.isPlainObject(value) && !(0, RawQueryFragment_1.isRaw)(value) && Object.keys(value)[0] !== '$eq';
124
124
  if (isJsonProperty) {
125
125
  return this.processJsonCondition(o, value, [prop.fieldNames[0]], platform, aliased);
126
126
  }
@@ -191,7 +191,7 @@ class QueryHelper {
191
191
  if (Array.isArray(cond) && !(key && Utils_1.Utils.isArrayOperator(key))) {
192
192
  return cond.map(v => QueryHelper.processCustomType(prop, v, platform, key, fromQuery));
193
193
  }
194
- if (platform.isRaw(cond)) {
194
+ if ((0, RawQueryFragment_1.isRaw)(cond)) {
195
195
  return cond;
196
196
  }
197
197
  return prop.customType.convertToDatabaseValue(cond, platform, { fromQuery, key, mode: 'query' });
@@ -30,6 +30,8 @@ export declare class RawQueryFragment {
30
30
  params?: undefined;
31
31
  };
32
32
  }
33
+ export { RawQueryFragment as Raw };
34
+ export declare function isRaw(value: unknown): value is RawQueryFragment;
33
35
  /** @internal */
34
36
  export declare const ALIAS_REPLACEMENT = "[::alias::]";
35
37
  /** @internal */
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ALIAS_REPLACEMENT_RE = exports.ALIAS_REPLACEMENT = exports.RawQueryFragment = void 0;
3
+ exports.ALIAS_REPLACEMENT_RE = exports.ALIAS_REPLACEMENT = exports.Raw = exports.RawQueryFragment = void 0;
4
+ exports.isRaw = isRaw;
4
5
  exports.raw = raw;
5
6
  exports.sql = sql;
6
7
  exports.createSqlFunction = createSqlFunction;
@@ -102,9 +103,13 @@ class RawQueryFragment {
102
103
  }
103
104
  }
104
105
  exports.RawQueryFragment = RawQueryFragment;
106
+ exports.Raw = RawQueryFragment;
105
107
  Object.defineProperties(RawQueryFragment.prototype, {
106
108
  __raw: { value: true, enumerable: false },
107
109
  });
110
+ function isRaw(value) {
111
+ return typeof value === 'object' && value !== null && '__raw' in value;
112
+ }
108
113
  /** @internal */
109
114
  exports.ALIAS_REPLACEMENT = '[::alias::]';
110
115
  /** @internal */
@@ -164,7 +169,8 @@ function raw(sql, params) {
164
169
  const pairs = Object.entries(params);
165
170
  const objectParams = [];
166
171
  for (const [key, value] of pairs) {
167
- sql = sql.replace(':' + key, '?');
172
+ sql = sql.replace(`:${key}:`, '??');
173
+ sql = sql.replace(`:${key}`, '?');
168
174
  objectParams.push(value);
169
175
  }
170
176
  return new RawQueryFragment(sql, objectParams);
package/utils/Utils.d.ts CHANGED
@@ -75,7 +75,7 @@ export declare class Utils {
75
75
  /**
76
76
  * Merges all sources into the target recursively. Ignores `undefined` values.
77
77
  */
78
- static mergeConfig(target: any, ...sources: any[]): any;
78
+ static mergeConfig<T>(target: T, ...sources: Dictionary[]): T;
79
79
  /**
80
80
  * Merges all sources into the target recursively.
81
81
  */
package/utils/Utils.js CHANGED
@@ -44,7 +44,7 @@ function compareObjects(a, b) {
44
44
  if (!a || !b || typeof a !== 'object' || typeof b !== 'object' || !compareConstructors(a, b)) {
45
45
  return false;
46
46
  }
47
- if (isRawSql(a) && isRawSql(b)) {
47
+ if (a.__raw && b.__raw) {
48
48
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
49
49
  return a.sql === b.sql && compareArrays(a.params, b.params);
50
50
  }