@mikro-orm/core 7.0.0-dev.42 → 7.0.0-dev.44

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 (41) hide show
  1. package/EntityManager.d.ts +2 -14
  2. package/EntityManager.js +24 -5
  3. package/MikroORM.d.ts +1 -2
  4. package/MikroORM.js +21 -58
  5. package/connections/Connection.d.ts +5 -3
  6. package/connections/Connection.js +14 -11
  7. package/decorators/Property.d.ts +0 -6
  8. package/drivers/DatabaseDriver.d.ts +6 -2
  9. package/drivers/DatabaseDriver.js +4 -4
  10. package/drivers/IDatabaseDriver.d.ts +6 -2
  11. package/entity/ArrayCollection.d.ts +2 -2
  12. package/entity/ArrayCollection.js +8 -3
  13. package/entity/BaseEntity.d.ts +0 -1
  14. package/entity/BaseEntity.js +0 -3
  15. package/entity/Collection.d.ts +2 -2
  16. package/entity/Collection.js +18 -7
  17. package/entity/EntityFactory.js +0 -2
  18. package/entity/EntityHelper.js +2 -7
  19. package/entity/WrappedEntity.d.ts +0 -2
  20. package/entity/WrappedEntity.js +0 -4
  21. package/entity/defineEntity.d.ts +0 -6
  22. package/entity/defineEntity.js +0 -8
  23. package/metadata/MetadataDiscovery.d.ts +1 -1
  24. package/metadata/MetadataDiscovery.js +2 -7
  25. package/package.json +2 -2
  26. package/serialization/EntitySerializer.js +21 -3
  27. package/serialization/EntityTransformer.js +15 -5
  28. package/typings.d.ts +4 -6
  29. package/typings.js +7 -27
  30. package/unit-of-work/ChangeSetComputer.js +5 -2
  31. package/unit-of-work/UnitOfWork.js +3 -14
  32. package/utils/AbstractSchemaGenerator.js +3 -1
  33. package/utils/Configuration.d.ts +2 -7
  34. package/utils/Configuration.js +2 -12
  35. package/utils/ConfigurationLoader.d.ts +2 -18
  36. package/utils/ConfigurationLoader.js +8 -32
  37. package/utils/RawQueryFragment.d.ts +0 -2
  38. package/utils/RawQueryFragment.js +0 -13
  39. package/utils/TransactionManager.js +8 -3
  40. package/utils/Utils.d.ts +0 -4
  41. package/utils/Utils.js +0 -20
@@ -178,12 +178,6 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
178
178
  ref<T extends boolean = true>(ref?: T): UniversalPropertyOptionsBuilder<Value, Omit<Options, 'ref'> & {
179
179
  ref: T;
180
180
  }, IncludeKeys>;
181
- /**
182
- * Set false to disable change tracking on a property level.
183
- *
184
- * @see https://mikro-orm.io/docs/unit-of-work#change-tracking-and-performance-considerations
185
- */
186
- trackChanges(trackChanges?: boolean): UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>;
187
181
  /**
188
182
  * Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
189
183
  */
@@ -170,14 +170,6 @@ export class UniversalPropertyOptionsBuilder {
170
170
  ref(ref = true) {
171
171
  return this.assignOptions({ ref });
172
172
  }
173
- /**
174
- * Set false to disable change tracking on a property level.
175
- *
176
- * @see https://mikro-orm.io/docs/unit-of-work#change-tracking-and-performance-considerations
177
- */
178
- trackChanges(trackChanges = true) {
179
- return this.assignOptions({ trackChanges });
180
- }
181
173
  /**
182
174
  * Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
183
175
  */
@@ -16,7 +16,7 @@ export declare class MetadataDiscovery {
16
16
  private readonly discovered;
17
17
  constructor(metadata: MetadataStorage, platform: Platform, config: Configuration);
18
18
  discover(preferTs?: boolean): Promise<MetadataStorage>;
19
- discoverSync(preferTs?: boolean): MetadataStorage;
19
+ discoverSync(): MetadataStorage;
20
20
  private mapDiscoveredEntities;
21
21
  private initAccessors;
22
22
  processDiscoveredEntities(discovered: EntityMetadata[]): EntityMetadata[];
@@ -47,10 +47,10 @@ export class MetadataDiscovery {
47
47
  await this.config.get('discovery').afterDiscovered?.(storage, this.platform);
48
48
  return storage;
49
49
  }
50
- discoverSync(preferTs = true) {
50
+ discoverSync() {
51
51
  const startTime = Date.now();
52
52
  this.logger.log('discovery', `ORM entity discovery started, using ${colors.cyan(this.metadataProvider.constructor.name)} in sync mode`);
53
- this.findEntities(preferTs, true);
53
+ this.findEntities();
54
54
  for (const meta of this.discovered) {
55
55
  /* v8 ignore next */
56
56
  void this.config.get('discovery').onMetadata?.(meta, this.platform);
@@ -100,7 +100,6 @@ export class MetadataDiscovery {
100
100
  this.initFieldName(prop);
101
101
  prop.serializedName ??= prop.accessor;
102
102
  prop.name = name;
103
- prop.trackChanges = false;
104
103
  }
105
104
  }
106
105
  }
@@ -132,10 +131,6 @@ export class MetadataDiscovery {
132
131
  this.initDefaultValue(prop);
133
132
  this.inferTypeFromDefault(prop);
134
133
  this.initColumnType(prop);
135
- // change tracking on scalars is used only for "auto" flushMode
136
- if (this.config.get('flushMode') !== 'auto' && [ReferenceKind.SCALAR, ReferenceKind.EMBEDDED].includes(prop.kind)) {
137
- prop.trackChanges = false;
138
- }
139
134
  }
140
135
  }
141
136
  filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initIndexes(meta, prop)));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
3
  "type": "module",
4
- "version": "7.0.0-dev.42",
4
+ "version": "7.0.0-dev.44",
5
5
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
6
6
  "exports": {
7
7
  "./package.json": "./package.json",
@@ -54,7 +54,7 @@
54
54
  "dataloader": "2.2.3",
55
55
  "dotenv": "17.2.3",
56
56
  "esprima": "4.0.1",
57
- "mikro-orm": "7.0.0-dev.42",
57
+ "mikro-orm": "7.0.0-dev.44",
58
58
  "reflect-metadata": "0.2.2",
59
59
  "tinyglobby": "0.2.13"
60
60
  }
@@ -41,13 +41,31 @@ export class EntitySerializer {
41
41
  }
42
42
  const root = wrapped.__serializationContext.root;
43
43
  const ret = {};
44
- const keys = new Set(meta.primaryKeys);
45
- Utils.keys(entity).forEach(prop => keys.add(prop));
44
+ const props = new Set();
45
+ if (meta.serializedPrimaryKey && !meta.compositePK) {
46
+ props.add(meta.serializedPrimaryKey);
47
+ }
48
+ else {
49
+ meta.primaryKeys.forEach(pk => props.add(pk));
50
+ }
51
+ if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
52
+ const entityKeys = new Set(Object.keys(entity));
53
+ for (const prop of meta.props) {
54
+ if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
55
+ props.add(prop.name);
56
+ }
57
+ }
58
+ for (const key of entityKeys) {
59
+ if (!meta.properties[key]) {
60
+ props.add(key);
61
+ }
62
+ }
63
+ }
46
64
  const visited = root.visited.has(entity);
47
65
  if (!visited) {
48
66
  root.visited.add(entity);
49
67
  }
50
- for (const prop of keys) {
68
+ for (const prop of props) {
51
69
  if (!isVisible(meta, prop, options)) {
52
70
  continue;
53
71
  }
@@ -27,22 +27,32 @@ export class EntityTransformer {
27
27
  const root = wrapped.__serializationContext.root;
28
28
  const meta = wrapped.__meta;
29
29
  const ret = {};
30
- const keys = new Set();
30
+ const props = new Set();
31
31
  if (meta.serializedPrimaryKey && !meta.compositePK) {
32
- keys.add(meta.serializedPrimaryKey);
32
+ props.add(meta.serializedPrimaryKey);
33
33
  }
34
34
  else {
35
- meta.primaryKeys.forEach(pk => keys.add(pk));
35
+ meta.primaryKeys.forEach(pk => props.add(pk));
36
36
  }
37
37
  if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
38
- Utils.keys(entity).forEach(prop => keys.add(prop));
38
+ const entityKeys = new Set(Object.keys(entity));
39
+ for (const prop of meta.props) {
40
+ if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
41
+ props.add(prop.name);
42
+ }
43
+ }
44
+ for (const key of entityKeys) {
45
+ if (!meta.properties[key]) {
46
+ props.add(key);
47
+ }
48
+ }
39
49
  }
40
50
  const visited = root.visited.has(entity);
41
51
  const includePrimaryKeys = wrapped.__config.get('serialization').includePrimaryKeys;
42
52
  if (!visited) {
43
53
  root.visited.add(entity);
44
54
  }
45
- for (const prop of keys) {
55
+ for (const prop of props) {
46
56
  const visible = raw ? meta.properties[prop] : isVisible(meta, prop, ignoreFields);
47
57
  if (!visible) {
48
58
  continue;
package/typings.d.ts CHANGED
@@ -160,7 +160,6 @@ export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T
160
160
  export type QBFilterQuery<T = any> = ObjectQuery<T> | Dictionary;
161
161
  export interface IWrappedEntity<Entity extends object> {
162
162
  isInitialized(): boolean;
163
- isTouched(): boolean;
164
163
  isManaged(): boolean;
165
164
  populated(populated?: boolean): void;
166
165
  populate<Hint extends string = never>(populate: AutoPath<Entity, Hint>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
@@ -191,7 +190,6 @@ export interface IWrappedEntityInternal<Entity extends object> extends IWrappedE
191
190
  __factory: EntityFactory;
192
191
  __hydrator: IHydrator;
193
192
  __initialized: boolean;
194
- __touched: boolean;
195
193
  __originalEntityData?: EntityData<Entity>;
196
194
  __loadedProperties: Set<string>;
197
195
  __identifier?: EntityIdentifier | EntityIdentifier[];
@@ -378,7 +376,6 @@ export interface EntityProperty<Owner = any, Target = any> {
378
376
  mapToPk?: boolean;
379
377
  persist?: boolean;
380
378
  hydrate?: boolean;
381
- trackChanges?: boolean;
382
379
  hidden?: boolean;
383
380
  enum?: boolean;
384
381
  items?: (number | string)[];
@@ -527,6 +524,7 @@ export interface CreateSchemaOptions {
527
524
  export interface ClearDatabaseOptions {
528
525
  schema?: string;
529
526
  truncate?: boolean;
527
+ clearIdentityMap?: boolean;
530
528
  }
531
529
  export interface EnsureDatabaseOptions extends CreateSchemaOptions, ClearDatabaseOptions {
532
530
  clear?: boolean;
@@ -721,11 +719,11 @@ export interface MigrationObject {
721
719
  name: string;
722
720
  class: Constructor<Migration>;
723
721
  }
724
- export type FilterDef = {
722
+ export type FilterDef<T extends object = any> = {
725
723
  name: string;
726
- cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any>, entityName?: EntityName<any>) => Dictionary | Promise<Dictionary>);
724
+ cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any>, entityName?: EntityName<T>) => MaybePromise<Dictionary>);
727
725
  default?: boolean;
728
- entity?: string[];
726
+ entity?: EntityName<T> | EntityName<T>[];
729
727
  args?: boolean;
730
728
  strict?: boolean;
731
729
  };
package/typings.js CHANGED
@@ -90,11 +90,12 @@ export class EntityMetadata {
90
90
  const onlyGetter = prop.getter && !prop.setter && prop.persist === false;
91
91
  return !prop.inherited && prop.hydrate !== false && !discriminator && !prop.embedded && !onlyGetter;
92
92
  });
93
- this.trackingProps = this.hydrateProps
94
- .filter(prop => !prop.getter && !prop.setter && prop.trackChanges !== false)
95
- .filter(prop => ![ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind))
96
- .filter(prop => !prop.serializedPrimaryKey);
97
- this.selfReferencing = this.relations.some(prop => [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type));
93
+ this.trackingProps = this.hydrateProps.filter(prop => {
94
+ return !prop.getter && !prop.setter && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
95
+ });
96
+ this.selfReferencing = this.relations.some(prop => {
97
+ return [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type);
98
+ });
98
99
  this.hasUniqueProps = this.uniques.length + this.uniqueProps.length > 0;
99
100
  this.virtual = !!this.expression;
100
101
  if (config) {
@@ -126,8 +127,7 @@ export class EntityMetadata {
126
127
  this.props.forEach(prop => this.initIndexes(prop));
127
128
  }
128
129
  this.definedProperties = this.trackingProps.reduce((o, prop) => {
129
- const isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
130
- const isReference = [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
130
+ const isReference = (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
131
131
  if (isReference) {
132
132
  // eslint-disable-next-line @typescript-eslint/no-this-alias
133
133
  const meta = this;
@@ -148,32 +148,12 @@ export class EntityMetadata {
148
148
  if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
149
149
  wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(val, prop.targetMeta, true);
150
150
  }
151
- else {
152
- wrapped.__touched = !hydrator.isRunning();
153
- }
154
151
  EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
155
152
  },
156
153
  enumerable: true,
157
154
  configurable: true,
158
155
  };
159
156
  }
160
- if (prop.inherited || prop.primary || isCollection || prop.persist === false || prop.trackChanges === false || isReference || prop.embedded) {
161
- return o;
162
- }
163
- o[prop.name] = {
164
- get() {
165
- return this.__helper.__data[prop.name];
166
- },
167
- set(val) {
168
- if (typeof val === 'object' && !!val && '__raw' in val) {
169
- val.assign();
170
- }
171
- this.__helper.__data[prop.name] = val;
172
- this.__helper.__touched = !this.__helper.hydrator.isRunning();
173
- },
174
- enumerable: true,
175
- configurable: true,
176
- };
177
157
  return o;
178
158
  }, { __gettersDefined: { value: true, enumerable: false } });
179
159
  }
@@ -34,8 +34,11 @@ export class ChangeSetComputer {
34
34
  this.processPropertyInitializers(entity, prop, type, map);
35
35
  }
36
36
  }
37
- if (type === ChangeSetType.UPDATE && !wrapped.__initialized && !wrapped.isTouched()) {
38
- return null;
37
+ if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
38
+ const data = this.comparator.prepareEntity(entity);
39
+ if (Utils.equals(data, wrapped.__originalEntityData)) {
40
+ return null;
41
+ }
39
42
  }
40
43
  const changeSet = new ChangeSet(entity, type, this.computePayload(entity), meta);
41
44
  changeSet.originalEntity = wrapped.__originalEntityData;
@@ -61,7 +61,6 @@ export class UnitOfWork {
61
61
  // as there can be some entity with already changed state that is not yet flushed
62
62
  if (wrapped.__initialized && (!visited || !wrapped.__originalEntityData)) {
63
63
  wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
64
- wrapped.__touched = false;
65
64
  }
66
65
  this.cascade(entity, Cascade.MERGE, visited ?? new Set());
67
66
  }
@@ -124,7 +123,6 @@ export class UnitOfWork {
124
123
  }
125
124
  }
126
125
  wrapped.__originalEntityData = data;
127
- wrapped.__touched = false;
128
126
  }
129
127
  return entity;
130
128
  }
@@ -215,11 +213,6 @@ export class UnitOfWork {
215
213
  if (meta.discriminatorMap && Object.values(meta.discriminatorMap).some(v => this.queuedActions.has(v))) {
216
214
  return true;
217
215
  }
218
- for (const entity of this.identityMap.getStore(meta).values()) {
219
- if (helper(entity).__initialized && helper(entity).isTouched()) {
220
- return true;
221
- }
222
- }
223
216
  return false;
224
217
  }
225
218
  clearActionsQueue() {
@@ -239,7 +232,6 @@ export class UnitOfWork {
239
232
  this.changeSets.set(entity, cs);
240
233
  this.persistStack.delete(entity);
241
234
  wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
242
- wrapped.__touched = false;
243
235
  }
244
236
  recomputeSingleChangeSet(entity) {
245
237
  const changeSet = this.changeSets.get(entity);
@@ -250,7 +242,6 @@ export class UnitOfWork {
250
242
  if (cs && !this.checkUniqueProps(cs)) {
251
243
  Object.assign(changeSet.payload, cs.payload);
252
244
  helper(entity).__originalEntityData = this.comparator.prepareEntity(entity);
253
- helper(entity).__touched = false;
254
245
  }
255
246
  }
256
247
  persist(entity, visited, options = {}) {
@@ -402,7 +393,6 @@ export class UnitOfWork {
402
393
  }
403
394
  delete wrapped.__identifier;
404
395
  delete wrapped.__originalEntityData;
405
- wrapped.__touched = false;
406
396
  wrapped.__managed = false;
407
397
  }
408
398
  computeChangeSets() {
@@ -412,14 +402,14 @@ export class UnitOfWork {
412
402
  this.cascade(entity, Cascade.REMOVE, visited);
413
403
  }
414
404
  visited.clear();
415
- for (const entity of this.persistStack) {
416
- this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
417
- }
418
405
  for (const entity of this.identityMap) {
419
406
  if (!this.removeStack.has(entity) && !this.persistStack.has(entity) && !this.orphanRemoveStack.has(entity)) {
420
407
  this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
421
408
  }
422
409
  }
410
+ for (const entity of this.persistStack) {
411
+ this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
412
+ }
423
413
  visited.clear();
424
414
  for (const entity of this.persistStack) {
425
415
  this.findNewEntities(entity, visited);
@@ -876,7 +866,6 @@ export class UnitOfWork {
876
866
  for (const changeSet of changeSets) {
877
867
  const wrapped = helper(changeSet.entity);
878
868
  wrapped.__originalEntityData = this.comparator.prepareEntity(changeSet.entity);
879
- wrapped.__touched = false;
880
869
  if (!wrapped.__initialized) {
881
870
  for (const prop of changeSet.meta.relations) {
882
871
  if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && changeSet.entity[prop.name] == null) {
@@ -42,7 +42,9 @@ export class AbstractSchemaGenerator {
42
42
  for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
43
43
  await this.driver.nativeDelete(meta.className, {}, options);
44
44
  }
45
- this.clearIdentityMap();
45
+ if (options?.clearIdentityMap ?? true) {
46
+ this.clearIdentityMap();
47
+ }
46
48
  }
47
49
  clearIdentityMap() {
48
50
  /* v8 ignore next 3 */
@@ -57,7 +57,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
57
57
  loadStrategy: LoadStrategy.BALANCED;
58
58
  dataloader: DataloaderType.NONE;
59
59
  populateWhere: PopulateHint.ALL;
60
- connect: true;
61
60
  ignoreUndefinedInQuery: false;
62
61
  onQuery: (sql: string) => string;
63
62
  autoJoinOneToOneOwner: true;
@@ -177,10 +176,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
177
176
  */
178
177
  getLogger(): Logger;
179
178
  getDataloaderType(): DataloaderType;
180
- /**
181
- * Gets current client URL (connection string).
182
- */
183
- getClientUrl(hidePassword?: boolean): string;
184
179
  getSchema(skipDefaultSchema?: boolean): string | undefined;
185
180
  /**
186
181
  * Gets current database driver instance.
@@ -239,7 +234,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
239
234
  /**
240
235
  * Type helper to make it easier to use `mikro-orm.config.js`.
241
236
  */
242
- export declare function defineConfig<D extends IDatabaseDriver>(options: Options<D>): Options<D, D[typeof EntityManagerType] & EntityManager<IDatabaseDriver<import("../index.js").Connection>>, (string | EntityClass<Partial<any>> | EntityClassGroup<Partial<any>> | EntitySchema<any, never>)[]>;
237
+ export declare function defineConfig<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager<D> = EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]>(options: Options<D, EM, Entities>): Options<D, EM, Entities>;
243
238
  export interface ConnectionOptions {
244
239
  dbName?: string;
245
240
  schema?: string;
@@ -301,6 +296,7 @@ export interface MetadataDiscoveryOptions {
301
296
  onMetadata?: (meta: EntityMetadata, platform: Platform) => MaybePromise<void>;
302
297
  afterDiscovered?: (storage: MetadataStorage, platform: Platform) => MaybePromise<void>;
303
298
  tsConfigPath?: string;
299
+ skipSyncDiscovery?: boolean;
304
300
  }
305
301
  export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = EntityManager> extends ConnectionOptions {
306
302
  entities: (string | EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[];
@@ -321,7 +317,6 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
321
317
  };
322
318
  implicitTransactions?: boolean;
323
319
  disableTransactions?: boolean;
324
- connect: boolean;
325
320
  verbose: boolean;
326
321
  ignoreUndefinedInQuery?: boolean;
327
322
  onQuery: (sql: string, params: readonly unknown[]) => string;
@@ -47,7 +47,6 @@ export class Configuration {
47
47
  loadStrategy: LoadStrategy.BALANCED,
48
48
  dataloader: DataloaderType.NONE,
49
49
  populateWhere: PopulateHint.ALL,
50
- connect: true,
51
50
  ignoreUndefinedInQuery: false,
52
51
  onQuery: sql => sql,
53
52
  autoJoinOneToOneOwner: true,
@@ -211,15 +210,6 @@ export class Configuration {
211
210
  }
212
211
  return this.options.dataloader;
213
212
  }
214
- /**
215
- * Gets current client URL (connection string).
216
- */
217
- getClientUrl(hidePassword = false) {
218
- if (hidePassword) {
219
- return this.options.clientUrl.replace(/\/\/([^:]+):(.+)@/, '//$1:*****@');
220
- }
221
- return this.options.clientUrl;
222
- }
223
213
  getSchema(skipDefaultSchema = false) {
224
214
  if (skipDefaultSchema && this.options.schema === this.platform.getDefaultSchemaName()) {
225
215
  return undefined;
@@ -322,13 +312,13 @@ export class Configuration {
322
312
  this.options.implicitTransactions = this.platform.usesImplicitTransactions();
323
313
  }
324
314
  try {
325
- const url = new URL(this.getClientUrl());
315
+ const url = new URL(this.options.clientUrl);
326
316
  if (url.pathname) {
327
317
  this.options.dbName = this.get('dbName', decodeURIComponent(url.pathname).substring(1));
328
318
  }
329
319
  }
330
320
  catch {
331
- const url = this.getClientUrl().match(/:\/\/.*\/([^?]+)/);
321
+ const url = this.options.clientUrl.match(/:\/\/.*\/([^?]+)/);
332
322
  if (url) {
333
323
  this.options.dbName = this.get('dbName', decodeURIComponent(url[1]));
334
324
  }
@@ -13,30 +13,14 @@ export declare class ConfigurationLoader {
13
13
  * @param paths Array of possible paths for a configuration file. Files will be checked in order, and the first existing one will be used. Defaults to the output of {@link ConfigurationLoader.getConfigPaths}.
14
14
  * @param options Additional options to augment the final configuration with.
15
15
  */
16
- static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(contextName: string, paths?: string[], options?: Partial<Options>): Promise<Configuration<D, EM>>;
17
- /**
18
- * Gets the default config from the default paths
19
- *
20
- * @deprecated Prefer to explicitly set the `contextName` at the first argument. This signature is available for backwards compatibility, and may be removed in v7.
21
- */
22
- static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(): Promise<Configuration<D, EM>>;
23
- /**
24
- * Gets default configuration out of the default paths, and possibly from `process.argv`
25
- *
26
- * @param validate Whether to validate the final configuration.
27
- * @param options Additional options to augment the final configuration with (just before validation).
28
- *
29
- * @deprecated Use the other overloads of this method. This signature will be removed in v7.
30
- */
31
- static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(validate: boolean, options?: Partial<Options>): Promise<Configuration<D, EM>>;
16
+ static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(contextName?: string, paths?: string[], options?: Partial<Options>): Promise<Configuration<D, EM>>;
32
17
  static getConfigFile(paths: string[]): Promise<[string, unknown] | []>;
33
18
  static getPackageConfig(basePath?: string): Dictionary;
34
19
  static getSettings(): Settings;
35
- static configPathsFromArg(): string[] | undefined;
36
20
  static getConfigPaths(): string[];
37
21
  static isESM(): boolean;
38
22
  static registerTypeScriptSupport(configPath?: string): Promise<boolean>;
39
- static registerDotenv<D extends IDatabaseDriver>(options?: Options<D>): void;
23
+ static registerDotenv<D extends IDatabaseDriver>(options: Options<D>): void;
40
24
  static loadEnvironmentVars<D extends IDatabaseDriver>(): Promise<Partial<Options<D>>>;
41
25
  static loadEnvironmentVarsSync<D extends IDatabaseDriver>(): Partial<Options<D>>;
42
26
  static getORMPackages(): Set<string>;
@@ -7,30 +7,14 @@ import { Utils } from './Utils.js';
7
7
  * @internal
8
8
  */
9
9
  export class ConfigurationLoader {
10
+ /**
11
+ * Gets a named configuration
12
+ *
13
+ * @param contextName Load a config with the given `contextName` value. Used when config file exports array or factory function. Setting it to "default" matches also config objects without `contextName` set.
14
+ * @param paths Array of possible paths for a configuration file. Files will be checked in order, and the first existing one will be used. Defaults to the output of {@link ConfigurationLoader.getConfigPaths}.
15
+ * @param options Additional options to augment the final configuration with.
16
+ */
10
17
  static async getConfiguration(contextName = 'default', paths = ConfigurationLoader.getConfigPaths(), options = {}) {
11
- // Backwards compatibility layer
12
- if (typeof contextName === 'boolean' || !Array.isArray(paths)) {
13
- this.registerDotenv(options);
14
- const configPathFromArg = ConfigurationLoader.configPathsFromArg();
15
- const configPaths = configPathFromArg ?? (Array.isArray(paths) ? paths : ConfigurationLoader.getConfigPaths());
16
- const config = contextName
17
- ? (await ConfigurationLoader.getConfiguration(process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default', configPaths, Array.isArray(paths) ? {} : paths))
18
- : await (async () => {
19
- const env = await this.loadEnvironmentVars();
20
- const [path, tmp] = await this.getConfigFile(configPaths);
21
- if (!path) {
22
- if (Utils.hasObjectKeys(env)) {
23
- return new Configuration(Utils.mergeConfig({}, options, env), false);
24
- }
25
- throw new Error(`MikroORM config file not found in ['${configPaths.join(`', '`)}']`);
26
- }
27
- return new Configuration(Utils.mergeConfig(tmp, options, env), false);
28
- })();
29
- if (configPathFromArg) {
30
- config.getLogger().warn('deprecated', 'Path for config file was inferred from the command line arguments. Instead, you should set the MIKRO_ORM_CLI_CONFIG environment variable to specify the path, or if you really must use the command line arguments, import the config manually based on them, and pass it to init.', { label: 'D0001' });
31
- }
32
- return config;
33
- }
34
18
  const env = await this.loadEnvironmentVars();
35
19
  const configFinder = (cfg) => {
36
20
  return typeof cfg === 'object' && cfg !== null && ('contextName' in cfg ? cfg.contextName === contextName : (contextName === 'default'));
@@ -134,14 +118,6 @@ export class ConfigurationLoader {
134
118
  }
135
119
  return settings;
136
120
  }
137
- static configPathsFromArg() {
138
- const options = Utils.parseArgs();
139
- const configArgName = process.env.MIKRO_ORM_CONFIG_ARG_NAME ?? 'config';
140
- if (options[configArgName]) {
141
- return [options[configArgName]];
142
- }
143
- return undefined;
144
- }
145
121
  static getConfigPaths() {
146
122
  const paths = [];
147
123
  const settings = ConfigurationLoader.getSettings();
@@ -187,7 +163,7 @@ export class ConfigurationLoader {
187
163
  return !!supported;
188
164
  }
189
165
  static registerDotenv(options) {
190
- const path = process.env.MIKRO_ORM_ENV ?? ((options?.baseDir ?? process.cwd()) + '/.env');
166
+ const path = process.env.MIKRO_ORM_ENV ?? ((options.baseDir ?? process.cwd()) + '/.env');
191
167
  const env = {};
192
168
  dotenv.config({ path, processEnv: env, quiet: true });
193
169
  // only propagate known env vars
@@ -10,8 +10,6 @@ export declare class RawQueryFragment {
10
10
  valueOf(): string;
11
11
  toJSON(): string;
12
12
  toString(): string;
13
- /** @internal */
14
- assign(): void;
15
13
  clone(): RawQueryFragment;
16
14
  static run<T>(cb: (...args: any[]) => Promise<T>): Promise<T>;
17
15
  /**
@@ -8,7 +8,6 @@ export class RawQueryFragment {
8
8
  static #storage = new AsyncLocalStorage();
9
9
  static #index = 0n;
10
10
  static cloneRegistry;
11
- #assigned = false;
12
11
  #used = 0;
13
12
  #key;
14
13
  constructor(sql, params = []) {
@@ -17,11 +16,6 @@ export class RawQueryFragment {
17
16
  this.#key = `[raw]: ${this.sql} (#${RawQueryFragment.#index++})`;
18
17
  }
19
18
  as(alias) {
20
- // TODO: to be removed in v7
21
- /* v8 ignore next 3 */
22
- if (alias.startsWith('`') || alias.startsWith('"')) {
23
- return new RawQueryFragment(`${this.sql} as ${alias}`, this.params);
24
- }
25
19
  return new RawQueryFragment(`${this.sql} as ??`, [...this.params, alias]);
26
20
  }
27
21
  valueOf() {
@@ -35,13 +29,6 @@ export class RawQueryFragment {
35
29
  this.#used++;
36
30
  return this.#key;
37
31
  }
38
- /** @internal */
39
- assign() {
40
- if (this.#assigned) {
41
- throw new Error(`Cannot reassign already used RawQueryFragment: '${this.sql}'`);
42
- }
43
- this.#assigned = true;
44
- }
45
32
  clone() {
46
33
  RawQueryFragment.cloneRegistry?.add(this.#key);
47
34
  return new RawQueryFragment(this.sql, this.params);
@@ -1,4 +1,4 @@
1
- import { TransactionPropagation } from '../enums.js';
1
+ import { ReferenceKind, TransactionPropagation } from '../enums.js';
2
2
  import { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster.js';
3
3
  import { TransactionContext } from '../utils/TransactionContext.js';
4
4
  import { ChangeSetType } from '../unit-of-work/ChangeSet.js';
@@ -164,8 +164,13 @@ export class TransactionManager {
164
164
  const parentEntity = parentUoW.getById(meta.className, wrapped.getPrimaryKey(), parent['_schema'], true);
165
165
  if (parentEntity && parentEntity !== entity) {
166
166
  const parentWrapped = helper(parentEntity);
167
- parentWrapped.__data = helper(entity).__data;
168
- parentWrapped.__originalEntityData = helper(entity).__originalEntityData;
167
+ parentWrapped.__data = wrapped.__data;
168
+ parentWrapped.__originalEntityData = wrapped.__originalEntityData;
169
+ for (const prop of meta.hydrateProps) {
170
+ if (prop.kind === ReferenceKind.SCALAR) {
171
+ parentEntity[prop.name] = entity[prop.name];
172
+ }
173
+ }
169
174
  }
170
175
  else {
171
176
  parentUoW.merge(entity, new Set([entity]));
package/utils/Utils.d.ts CHANGED
@@ -261,10 +261,6 @@ export declare class Utils {
261
261
  warning: string;
262
262
  }): Promise<T | undefined>;
263
263
  static stripRelativePath(str: string): string;
264
- /**
265
- * simple process.argv parser, supports only properties with long names, prefixed with `--`
266
- */
267
- static parseArgs<T extends Dictionary = Dictionary>(): T;
268
264
  static xor(a: boolean, b: boolean): boolean;
269
265
  static keys<T extends object>(obj: T): (keyof T)[];
270
266
  static values<T extends object>(obj: T): T[keyof T][];