@mikro-orm/core 7.0.0-dev.7 → 7.0.0-dev.71

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 (161) hide show
  1. package/EntityManager.d.ts +85 -42
  2. package/EntityManager.js +282 -194
  3. package/MikroORM.d.ts +11 -29
  4. package/MikroORM.js +33 -127
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.js +1 -2
  7. package/connections/Connection.d.ts +11 -7
  8. package/connections/Connection.js +16 -14
  9. package/drivers/DatabaseDriver.d.ts +11 -5
  10. package/drivers/DatabaseDriver.js +13 -4
  11. package/drivers/IDatabaseDriver.d.ts +27 -5
  12. package/entity/BaseEntity.d.ts +0 -1
  13. package/entity/BaseEntity.js +0 -3
  14. package/entity/Collection.d.ts +98 -30
  15. package/entity/Collection.js +432 -93
  16. package/entity/EntityAssigner.d.ts +1 -1
  17. package/entity/EntityAssigner.js +9 -1
  18. package/entity/EntityFactory.d.ts +7 -0
  19. package/entity/EntityFactory.js +63 -40
  20. package/entity/EntityHelper.js +26 -9
  21. package/entity/EntityLoader.d.ts +5 -4
  22. package/entity/EntityLoader.js +69 -36
  23. package/entity/EntityRepository.d.ts +1 -1
  24. package/entity/EntityValidator.js +4 -4
  25. package/entity/Reference.d.ts +9 -7
  26. package/entity/Reference.js +32 -5
  27. package/entity/WrappedEntity.d.ts +0 -2
  28. package/entity/WrappedEntity.js +1 -5
  29. package/entity/defineEntity.d.ts +549 -0
  30. package/entity/defineEntity.js +529 -0
  31. package/entity/index.d.ts +2 -1
  32. package/entity/index.js +2 -1
  33. package/entity/utils.d.ts +7 -0
  34. package/entity/utils.js +15 -3
  35. package/enums.d.ts +20 -5
  36. package/enums.js +13 -0
  37. package/errors.d.ts +6 -1
  38. package/errors.js +14 -4
  39. package/events/EventSubscriber.d.ts +3 -1
  40. package/hydration/ObjectHydrator.d.ts +4 -4
  41. package/hydration/ObjectHydrator.js +35 -24
  42. package/index.d.ts +2 -2
  43. package/index.js +1 -2
  44. package/logging/DefaultLogger.d.ts +1 -1
  45. package/logging/SimpleLogger.d.ts +1 -1
  46. package/metadata/EntitySchema.d.ts +9 -13
  47. package/metadata/EntitySchema.js +44 -26
  48. package/metadata/MetadataDiscovery.d.ts +6 -7
  49. package/metadata/MetadataDiscovery.js +161 -162
  50. package/metadata/MetadataProvider.d.ts +2 -2
  51. package/metadata/MetadataProvider.js +15 -0
  52. package/metadata/MetadataStorage.d.ts +0 -4
  53. package/metadata/MetadataStorage.js +6 -10
  54. package/metadata/MetadataValidator.d.ts +0 -7
  55. package/metadata/MetadataValidator.js +4 -13
  56. package/metadata/discover-entities.d.ts +5 -0
  57. package/metadata/discover-entities.js +39 -0
  58. package/metadata/index.d.ts +1 -1
  59. package/metadata/index.js +1 -1
  60. package/metadata/types.d.ts +480 -0
  61. package/metadata/types.js +1 -0
  62. package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
  63. package/naming-strategy/AbstractNamingStrategy.js +7 -1
  64. package/naming-strategy/NamingStrategy.d.ts +11 -1
  65. package/package.json +11 -10
  66. package/platforms/Platform.d.ts +6 -10
  67. package/platforms/Platform.js +6 -22
  68. package/serialization/EntitySerializer.d.ts +2 -0
  69. package/serialization/EntitySerializer.js +29 -11
  70. package/serialization/EntityTransformer.js +22 -12
  71. package/serialization/SerializationContext.js +14 -11
  72. package/types/ArrayType.d.ts +1 -1
  73. package/types/ArrayType.js +1 -2
  74. package/types/BigIntType.d.ts +8 -6
  75. package/types/BlobType.d.ts +0 -1
  76. package/types/BlobType.js +0 -3
  77. package/types/BooleanType.d.ts +2 -1
  78. package/types/BooleanType.js +3 -0
  79. package/types/DecimalType.d.ts +6 -4
  80. package/types/DecimalType.js +1 -1
  81. package/types/DoubleType.js +1 -1
  82. package/types/JsonType.d.ts +1 -1
  83. package/types/JsonType.js +7 -2
  84. package/types/Type.d.ts +2 -1
  85. package/types/Type.js +1 -1
  86. package/types/Uint8ArrayType.d.ts +0 -1
  87. package/types/Uint8ArrayType.js +0 -3
  88. package/types/index.d.ts +1 -1
  89. package/typings.d.ts +112 -77
  90. package/typings.js +32 -32
  91. package/unit-of-work/ChangeSetComputer.js +8 -3
  92. package/unit-of-work/ChangeSetPersister.d.ts +4 -2
  93. package/unit-of-work/ChangeSetPersister.js +37 -16
  94. package/unit-of-work/UnitOfWork.d.ts +8 -1
  95. package/unit-of-work/UnitOfWork.js +111 -54
  96. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  97. package/utils/AbstractSchemaGenerator.js +10 -8
  98. package/utils/Configuration.d.ts +200 -191
  99. package/utils/Configuration.js +141 -152
  100. package/utils/ConfigurationLoader.d.ts +3 -44
  101. package/utils/ConfigurationLoader.js +26 -239
  102. package/utils/Cursor.d.ts +3 -3
  103. package/utils/Cursor.js +3 -0
  104. package/utils/DataloaderUtils.d.ts +15 -5
  105. package/utils/DataloaderUtils.js +53 -7
  106. package/utils/EntityComparator.d.ts +8 -4
  107. package/utils/EntityComparator.js +107 -60
  108. package/utils/QueryHelper.d.ts +9 -1
  109. package/utils/QueryHelper.js +69 -8
  110. package/utils/RawQueryFragment.d.ts +36 -4
  111. package/utils/RawQueryFragment.js +34 -13
  112. package/utils/TransactionManager.d.ts +65 -0
  113. package/utils/TransactionManager.js +223 -0
  114. package/utils/Utils.d.ts +17 -84
  115. package/utils/Utils.js +132 -252
  116. package/utils/index.d.ts +1 -0
  117. package/utils/index.js +1 -0
  118. package/utils/upsert-utils.d.ts +7 -2
  119. package/utils/upsert-utils.js +52 -1
  120. package/decorators/Check.d.ts +0 -3
  121. package/decorators/Check.js +0 -13
  122. package/decorators/CreateRequestContext.d.ts +0 -3
  123. package/decorators/CreateRequestContext.js +0 -32
  124. package/decorators/Embeddable.d.ts +0 -8
  125. package/decorators/Embeddable.js +0 -11
  126. package/decorators/Embedded.d.ts +0 -18
  127. package/decorators/Embedded.js +0 -18
  128. package/decorators/Entity.d.ts +0 -18
  129. package/decorators/Entity.js +0 -12
  130. package/decorators/Enum.d.ts +0 -9
  131. package/decorators/Enum.js +0 -16
  132. package/decorators/Filter.d.ts +0 -2
  133. package/decorators/Filter.js +0 -8
  134. package/decorators/Formula.d.ts +0 -4
  135. package/decorators/Formula.js +0 -15
  136. package/decorators/Indexed.d.ts +0 -19
  137. package/decorators/Indexed.js +0 -20
  138. package/decorators/ManyToMany.d.ts +0 -40
  139. package/decorators/ManyToMany.js +0 -14
  140. package/decorators/ManyToOne.d.ts +0 -30
  141. package/decorators/ManyToOne.js +0 -14
  142. package/decorators/OneToMany.d.ts +0 -28
  143. package/decorators/OneToMany.js +0 -17
  144. package/decorators/OneToOne.d.ts +0 -24
  145. package/decorators/OneToOne.js +0 -7
  146. package/decorators/PrimaryKey.d.ts +0 -8
  147. package/decorators/PrimaryKey.js +0 -20
  148. package/decorators/Property.d.ts +0 -250
  149. package/decorators/Property.js +0 -32
  150. package/decorators/Transactional.d.ts +0 -13
  151. package/decorators/Transactional.js +0 -28
  152. package/decorators/hooks.d.ts +0 -16
  153. package/decorators/hooks.js +0 -47
  154. package/decorators/index.d.ts +0 -17
  155. package/decorators/index.js +0 -17
  156. package/entity/ArrayCollection.d.ts +0 -116
  157. package/entity/ArrayCollection.js +0 -402
  158. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  159. package/metadata/ReflectMetadataProvider.js +0 -44
  160. package/utils/resolveContextProvider.d.ts +0 -10
  161. package/utils/resolveContextProvider.js +0 -28
package/MikroORM.d.ts CHANGED
@@ -3,13 +3,15 @@ import { type EntitySchema } from './metadata/EntitySchema.js';
3
3
  import { MetadataStorage } from './metadata/MetadataStorage.js';
4
4
  import { Configuration, type Options } from './utils/Configuration.js';
5
5
  import type { EntityManager } from './EntityManager.js';
6
- import type { Constructor, EntityMetadata, EntityName, IEntityGenerator, IMigrator, ISeedManager } from './typings.js';
6
+ import type { AnyEntity, Constructor, EntityClass, EntityMetadata, EntityName, IEntityGenerator, IMigrator, ISeedManager } from './typings.js';
7
7
  /**
8
8
  * Helper class for bootstrapping the MikroORM.
9
9
  */
10
- export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = Driver[typeof EntityManagerType] & EntityManager> {
10
+ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver, EM extends Driver[typeof EntityManagerType] & EntityManager<Driver> = Driver[typeof EntityManagerType] & EntityManager<Driver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> {
11
11
  /** The global EntityManager instance. If you are using `RequestContext` helper, it will automatically pick the request specific context under the hood */
12
- em: EM;
12
+ em: EM & {
13
+ '~entities'?: Entities;
14
+ };
13
15
  readonly driver: Driver;
14
16
  readonly config: Configuration<Driver>;
15
17
  private metadata;
@@ -19,16 +21,14 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
19
21
  * Initialize the ORM, load entity metadata, create EntityManager and connect to the database.
20
22
  * If you omit the `options` parameter, your CLI config will be used.
21
23
  */
22
- static init<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options?: Options<D, EM>): Promise<MikroORM<D, EM>>;
24
+ static init<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Options<D, EM, Entities>): Promise<MikroORM<D, EM, Entities>>;
23
25
  /**
24
26
  * Synchronous variant of the `init` method with some limitations:
25
27
  * - database connection will be established when you first interact with the database (or you can use `orm.connect()` explicitly)
26
28
  * - no loading of the `config` file, `options` parameter is mandatory
27
29
  * - no support for folder based discovery
28
- * - no check for mismatched package versions
29
30
  */
30
- static initSync<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options: Options<D, EM>): MikroORM<D, EM>;
31
- constructor(options: Options<Driver, EM>);
31
+ constructor(options: Options<Driver, EM, Entities>);
32
32
  /**
33
33
  * Connects to the database.
34
34
  */
@@ -36,7 +36,7 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
36
36
  /**
37
37
  * Reconnects, possibly to a different database.
38
38
  */
39
- reconnect(options?: Options): Promise<void>;
39
+ reconnect(options?: Partial<Options<Driver, EM, Entities>>): Promise<void>;
40
40
  /**
41
41
  * Checks whether the database connection is active.
42
42
  */
@@ -63,8 +63,6 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
63
63
  * Gets the `EntityMetadata` instance when provided with the `entityName` parameter.
64
64
  */
65
65
  getMetadata<Entity extends object>(entityName: EntityName<Entity>): EntityMetadata<Entity>;
66
- discoverEntities(): Promise<void>;
67
- discoverEntitiesSync(): void;
68
66
  private createEntityManager;
69
67
  /**
70
68
  * Allows dynamically discovering new entity by reference, handy for testing schema diffing.
@@ -73,33 +71,17 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
73
71
  /**
74
72
  * Gets the SchemaGenerator.
75
73
  */
76
- getSchemaGenerator(): ReturnType<ReturnType<Driver['getPlatform']>['getSchemaGenerator']>;
77
- /**
78
- * Gets the EntityGenerator.
79
- */
80
- getEntityGenerator<T extends IEntityGenerator = IEntityGenerator>(): T;
81
- /**
82
- * Gets the Migrator.
83
- */
84
- getMigrator<T extends IMigrator = IMigrator>(): T;
74
+ get schema(): ReturnType<ReturnType<Driver['getPlatform']>['getSchemaGenerator']>;
85
75
  /**
86
76
  * Gets the SeedManager
87
77
  */
88
- getSeeder<T extends ISeedManager = ISeedManager>(): T;
89
- /**
90
- * Shortcut for `orm.getSchemaGenerator()`
91
- */
92
- get schema(): ReturnType<ReturnType<Driver["getPlatform"]>["getSchemaGenerator"]>;
93
- /**
94
- * Shortcut for `orm.getSeeder()`
95
- */
96
78
  get seeder(): ISeedManager;
97
79
  /**
98
- * Shortcut for `orm.getMigrator()`
80
+ * Gets the Migrator.
99
81
  */
100
82
  get migrator(): IMigrator;
101
83
  /**
102
- * Shortcut for `orm.getEntityGenerator()`
84
+ * Gets the EntityGenerator.
103
85
  */
104
86
  get entityGenerator(): IEntityGenerator;
105
87
  }
package/MikroORM.js CHANGED
@@ -1,12 +1,9 @@
1
1
  import { MetadataDiscovery } from './metadata/MetadataDiscovery.js';
2
2
  import { MetadataStorage } from './metadata/MetadataStorage.js';
3
- import { MetadataValidator } from './metadata/MetadataValidator.js';
4
- import { ReflectMetadataProvider } from './metadata/ReflectMetadataProvider.js';
5
3
  import { Configuration } from './utils/Configuration.js';
6
4
  import { ConfigurationLoader } from './utils/ConfigurationLoader.js';
7
5
  import { Utils } from './utils/Utils.js';
8
6
  import { colors } from './logging/colors.js';
9
- import { NullCacheAdapter } from './cache/NullCacheAdapter.js';
10
7
  /**
11
8
  * Helper class for bootstrapping the MikroORM.
12
9
  */
@@ -23,39 +20,16 @@ export class MikroORM {
23
20
  * If you omit the `options` parameter, your CLI config will be used.
24
21
  */
25
22
  static async init(options) {
26
- ConfigurationLoader.registerDotenv(options);
27
- const coreVersion = ConfigurationLoader.checkPackageVersion();
28
- const env = await ConfigurationLoader.loadEnvironmentVars();
23
+ /* v8 ignore next 3 */
29
24
  if (!options) {
30
- const configPathFromArg = ConfigurationLoader.configPathsFromArg();
31
- const config = (await ConfigurationLoader.getConfiguration(process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default', configPathFromArg ?? ConfigurationLoader.getConfigPaths()));
32
- options = config.getAll();
33
- if (configPathFromArg) {
34
- 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' });
35
- }
36
- }
37
- options = Utils.mergeConfig(options, env);
38
- ConfigurationLoader.commonJSCompat(options);
39
- if ('DRIVER' in this && !options.driver) {
40
- options.driver = this.DRIVER;
41
- }
42
- const orm = new MikroORM(options);
43
- orm.logger.log('info', `MikroORM version: ${colors.green(coreVersion)}`);
44
- // we need to allow global context here as we are not in a scope of requests yet
45
- const allowGlobalContext = orm.config.get('allowGlobalContext');
46
- orm.config.set('allowGlobalContext', true);
47
- await orm.discoverEntities();
48
- orm.config.set('allowGlobalContext', allowGlobalContext);
49
- orm.driver.getPlatform().init(orm);
50
- if (orm.config.get('connect')) {
51
- await orm.connect();
52
- }
53
- for (const extension of orm.config.get('extensions')) {
54
- extension.register(orm);
55
- }
56
- if (orm.config.get('connect') && orm.config.get('ensureIndexes')) {
57
- await orm.getSchemaGenerator().ensureIndexes();
58
- }
25
+ throw new Error(`options parameter is required`);
26
+ }
27
+ options.discovery ??= {};
28
+ options.discovery.skipSyncDiscovery ??= true;
29
+ const orm = new this(options);
30
+ const preferTs = orm.config.get('preferTs', Utils.detectTypeScriptSupport());
31
+ orm.metadata = await orm.discovery.discover(preferTs);
32
+ orm.createEntityManager();
59
33
  return orm;
60
34
  }
61
35
  /**
@@ -63,57 +37,31 @@ export class MikroORM {
63
37
  * - database connection will be established when you first interact with the database (or you can use `orm.connect()` explicitly)
64
38
  * - no loading of the `config` file, `options` parameter is mandatory
65
39
  * - no support for folder based discovery
66
- * - no check for mismatched package versions
67
40
  */
68
- static initSync(options) {
69
- ConfigurationLoader.registerDotenv(options);
70
- const env = ConfigurationLoader.loadEnvironmentVarsSync();
71
- options = Utils.merge(options, env);
72
- if ('DRIVER' in this && !options.driver) {
73
- options.driver = this.DRIVER;
74
- }
75
- const orm = new MikroORM(options);
76
- // we need to allow global context here as we are not in a scope of requests yet
77
- const allowGlobalContext = orm.config.get('allowGlobalContext');
78
- orm.config.set('allowGlobalContext', true);
79
- orm.discoverEntitiesSync();
80
- orm.config.set('allowGlobalContext', allowGlobalContext);
81
- orm.driver.getPlatform().init(orm);
82
- for (const extension of orm.config.get('extensions')) {
83
- extension.register(orm);
84
- }
85
- return orm;
86
- }
87
41
  constructor(options) {
42
+ const env = ConfigurationLoader.loadEnvironmentVars();
43
+ const coreVersion = ConfigurationLoader.checkPackageVersion();
44
+ options = Utils.merge(options, env);
88
45
  this.config = new Configuration(options);
89
46
  const discovery = this.config.get('discovery');
90
- if (discovery.disableDynamicFileAccess) {
91
- this.config.set('metadataProvider', ReflectMetadataProvider);
92
- this.config.set('metadataCache', { adapter: NullCacheAdapter });
93
- discovery.requireEntitiesArray = true;
94
- }
95
47
  this.driver = this.config.getDriver();
96
48
  this.logger = this.config.getLogger();
49
+ this.logger.log('info', `MikroORM version: ${colors.green(coreVersion)}`);
97
50
  this.discovery = new MetadataDiscovery(new MetadataStorage(), this.driver.getPlatform(), this.config);
51
+ this.driver.getPlatform().init(this);
52
+ for (const extension of this.config.get('extensions')) {
53
+ extension.register(this);
54
+ }
55
+ if (!discovery.skipSyncDiscovery) {
56
+ this.metadata = this.discovery.discoverSync();
57
+ this.createEntityManager();
58
+ }
98
59
  }
99
60
  /**
100
61
  * Connects to the database.
101
62
  */
102
63
  async connect() {
103
- const connection = await this.driver.connect();
104
- const clientUrl = connection.getClientUrl();
105
- const dbName = this.config.get('dbName');
106
- const db = dbName + (clientUrl ? ' on ' + clientUrl : '');
107
- if (this.config.get('ensureDatabase')) {
108
- const options = this.config.get('ensureDatabase');
109
- await this.schema.ensureDatabase(typeof options === 'boolean' ? {} : { ...options, forceCheck: true });
110
- }
111
- if (await this.isConnected()) {
112
- this.logger.log('info', `MikroORM successfully connected to database ${colors.green(db)}`);
113
- }
114
- else {
115
- this.logger.error('info', `MikroORM failed to connect to database ${db}`);
116
- }
64
+ await this.driver.connect();
117
65
  return this.driver;
118
66
  }
119
67
  /**
@@ -142,9 +90,7 @@ export class MikroORM {
142
90
  * Closes the database connection.
143
91
  */
144
92
  async close(force = false) {
145
- if (await this.isConnected()) {
146
- await this.driver.close(force);
147
- }
93
+ await this.driver.close(force);
148
94
  if (this.config.getMetadataCacheAdapter()?.close) {
149
95
  await this.config.getMetadataCacheAdapter().close();
150
96
  }
@@ -162,14 +108,6 @@ export class MikroORM {
162
108
  }
163
109
  return this.metadata;
164
110
  }
165
- async discoverEntities() {
166
- this.metadata = await this.discovery.discover(this.config.get('preferTs'));
167
- this.createEntityManager();
168
- }
169
- discoverEntitiesSync() {
170
- this.metadata = this.discovery.discoverSync(this.config.get('preferTs'));
171
- this.createEntityManager();
172
- }
173
111
  createEntityManager() {
174
112
  this.driver.setMetadata(this.metadata);
175
113
  this.em = this.driver.createEntityManager();
@@ -181,72 +119,40 @@ export class MikroORM {
181
119
  * Allows dynamically discovering new entity by reference, handy for testing schema diffing.
182
120
  */
183
121
  discoverEntity(entities, reset) {
184
- entities = Utils.asArray(entities);
185
122
  for (const className of Utils.asArray(reset)) {
186
123
  this.metadata.reset(className);
187
124
  this.discovery.reset(className);
188
125
  }
189
- const tmp = this.discovery.discoverReferences(entities);
190
- const options = this.config.get('discovery');
191
- new MetadataValidator().validateDiscovered([...Object.values(this.metadata.getAll()), ...tmp], options);
126
+ const tmp = this.discovery.discoverReferences(Utils.asArray(entities));
192
127
  const metadata = this.discovery.processDiscoveredEntities(tmp);
193
- metadata.forEach(meta => {
128
+ for (const meta of metadata) {
194
129
  this.metadata.set(meta.className, meta);
195
130
  meta.root = this.metadata.get(meta.root.className);
196
- });
131
+ }
197
132
  this.metadata.decorate(this.em);
198
133
  }
199
134
  /**
200
135
  * Gets the SchemaGenerator.
201
136
  */
202
- getSchemaGenerator() {
203
- const extension = this.config.getExtension('@mikro-orm/schema-generator');
204
- if (extension) {
205
- return extension;
206
- }
207
- /* v8 ignore next 2 */
208
- throw new Error(`SchemaGenerator extension not registered.`);
209
- }
210
- /**
211
- * Gets the EntityGenerator.
212
- */
213
- getEntityGenerator() {
214
- return this.driver.getPlatform().getExtension('EntityGenerator', '@mikro-orm/entity-generator', '@mikro-orm/entity-generator', this.em);
215
- }
216
- /**
217
- * Gets the Migrator.
218
- */
219
- getMigrator() {
220
- return this.driver.getPlatform().getExtension('Migrator', '@mikro-orm/migrator', '@mikro-orm/migrations', this.em);
221
- }
222
- /**
223
- * Gets the SeedManager
224
- */
225
- getSeeder() {
226
- return this.driver.getPlatform().getExtension('SeedManager', '@mikro-orm/seeder', '@mikro-orm/seeder', this.em);
227
- }
228
- /**
229
- * Shortcut for `orm.getSchemaGenerator()`
230
- */
231
137
  get schema() {
232
- return this.getSchemaGenerator();
138
+ return this.config.getExtension('@mikro-orm/schema-generator');
233
139
  }
234
140
  /**
235
- * Shortcut for `orm.getSeeder()`
141
+ * Gets the SeedManager
236
142
  */
237
143
  get seeder() {
238
- return this.getSeeder();
144
+ return this.driver.getPlatform().getExtension('SeedManager', '@mikro-orm/seeder', '@mikro-orm/seeder', this.em);
239
145
  }
240
146
  /**
241
- * Shortcut for `orm.getMigrator()`
147
+ * Gets the Migrator.
242
148
  */
243
149
  get migrator() {
244
- return this.getMigrator();
150
+ return this.driver.getPlatform().getExtension('Migrator', '@mikro-orm/migrator', '@mikro-orm/migrations', this.em);
245
151
  }
246
152
  /**
247
- * Shortcut for `orm.getEntityGenerator()`
153
+ * Gets the EntityGenerator.
248
154
  */
249
155
  get entityGenerator() {
250
- return this.getEntityGenerator();
156
+ return this.driver.getPlatform().getExtension('EntityGenerator', '@mikro-orm/entity-generator', '@mikro-orm/entity-generator', this.em);
251
157
  }
252
158
  }
package/README.md CHANGED
@@ -11,7 +11,6 @@ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-or
11
11
  [![Chat on discord](https://img.shields.io/discord/1214904142443839538?label=discord&color=blue)](https://discord.gg/w8bjxFHS7X)
12
12
  [![Downloads](https://img.shields.io/npm/dm/@mikro-orm/core.svg)](https://www.npmjs.com/package/@mikro-orm/core)
13
13
  [![Coverage Status](https://img.shields.io/coveralls/mikro-orm/mikro-orm.svg)](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
14
- [![Maintainability](https://api.codeclimate.com/v1/badges/27999651d3adc47cfa40/maintainability)](https://codeclimate.com/github/mikro-orm/mikro-orm/maintainability)
15
14
  [![Build Status](https://github.com/mikro-orm/mikro-orm/workflows/tests/badge.svg?branch=master)](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
16
15
 
17
16
  ## 🤔 Unit of What?
@@ -141,7 +140,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
141
140
  - [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
142
141
  - [Filters](https://mikro-orm.io/docs/filters)
143
142
  - [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
144
- - [Preloading Deeply Nested Structures via populate](https://mikro-orm.io/docs/nested-populate)
143
+ - [Populating relations](https://mikro-orm.io/docs/populating-relations)
145
144
  - [Property Validation](https://mikro-orm.io/docs/property-validation)
146
145
  - [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
147
146
  - [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
@@ -382,6 +381,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
382
381
 
383
382
  Please ⭐️ this repository if this project helped you!
384
383
 
384
+ > If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
385
+
385
386
  ## 📝 License
386
387
 
387
388
  Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
@@ -1,4 +1,3 @@
1
- import globby from 'globby';
2
1
  import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
3
2
  import { Utils } from '../utils/Utils.js';
4
3
  export class FileCacheAdapter {
@@ -51,7 +50,7 @@ export class FileCacheAdapter {
51
50
  */
52
51
  clear() {
53
52
  const path = this.path('*');
54
- const files = globby.sync(path);
53
+ const files = Utils.glob(path);
55
54
  files.forEach(file => unlinkSync(file));
56
55
  this.cache = {};
57
56
  }
@@ -17,7 +17,9 @@ export declare abstract class Connection {
17
17
  /**
18
18
  * Establishes connection to database
19
19
  */
20
- abstract connect(): void | Promise<void>;
20
+ abstract connect(options?: {
21
+ skipOnConnect?: boolean;
22
+ }): void | Promise<void>;
21
23
  /**
22
24
  * Are we connected to the database
23
25
  */
@@ -37,26 +39,28 @@ export declare abstract class Connection {
37
39
  */
38
40
  close(force?: boolean): Promise<void>;
39
41
  /**
40
- * Ensure the connection exists, this is used to support lazy connect when using `MikroORM.initSync()`
42
+ * Ensure the connection exists, this is used to support lazy connect when using `new MikroORM()` instead of the async `init` method.
41
43
  */
42
44
  ensureConnection(): Promise<void>;
45
+ protected onConnect(): Promise<void>;
43
46
  transactional<T>(cb: (trx: Transaction) => Promise<T>, options?: {
44
- isolationLevel?: IsolationLevel;
47
+ isolationLevel?: IsolationLevel | `${IsolationLevel}`;
45
48
  readOnly?: boolean;
46
49
  ctx?: Transaction;
47
50
  eventBroadcaster?: TransactionEventBroadcaster;
51
+ loggerContext?: LogContext;
48
52
  }): Promise<T>;
49
53
  begin(options?: {
50
- isolationLevel?: IsolationLevel;
54
+ isolationLevel?: IsolationLevel | `${IsolationLevel}`;
51
55
  readOnly?: boolean;
52
56
  ctx?: Transaction;
53
57
  eventBroadcaster?: TransactionEventBroadcaster;
58
+ loggerContext?: LogContext;
54
59
  }): Promise<Transaction>;
55
- commit(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster): Promise<void>;
56
- rollback(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster): Promise<void>;
60
+ commit(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster, loggerContext?: LogContext): Promise<void>;
61
+ rollback(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster, loggerContext?: LogContext): Promise<void>;
57
62
  abstract execute<T>(query: string, params?: any[], method?: 'all' | 'get' | 'run', ctx?: Transaction): Promise<QueryResult<T> | any | any[]>;
58
63
  getConnectionOptions(): ConnectionConfig;
59
- getClientUrl(): string;
60
64
  setMetadata(metadata: MetadataStorage): void;
61
65
  setPlatform(platform: Platform): void;
62
66
  getPlatform(): Platform;
@@ -1,4 +1,3 @@
1
- import { URL } from 'node:url';
2
1
  import { Utils } from '../utils/Utils.js';
3
2
  export class Connection {
4
3
  config;
@@ -33,23 +32,35 @@ export class Connection {
33
32
  .forEach(k => delete this.options[k]);
34
33
  }
35
34
  /**
36
- * Ensure the connection exists, this is used to support lazy connect when using `MikroORM.initSync()`
35
+ * Ensure the connection exists, this is used to support lazy connect when using `new MikroORM()` instead of the async `init` method.
37
36
  */
38
37
  async ensureConnection() {
39
38
  if (!this.connected) {
40
39
  await this.connect();
41
40
  }
42
41
  }
42
+ async onConnect() {
43
+ const schemaGenerator = this.config.getExtension('@mikro-orm/schema-generator');
44
+ if (this.type === 'write' && schemaGenerator) {
45
+ if (this.config.get('ensureDatabase')) {
46
+ const options = this.config.get('ensureDatabase');
47
+ await schemaGenerator.ensureDatabase(typeof options === 'boolean' ? {} : { ...options, forceCheck: true });
48
+ }
49
+ if (this.config.get('ensureIndexes')) {
50
+ await schemaGenerator.ensureIndexes();
51
+ }
52
+ }
53
+ }
43
54
  async transactional(cb, options) {
44
55
  throw new Error(`Transactions are not supported by current driver`);
45
56
  }
46
57
  async begin(options) {
47
58
  throw new Error(`Transactions are not supported by current driver`);
48
59
  }
49
- async commit(ctx, eventBroadcaster) {
60
+ async commit(ctx, eventBroadcaster, loggerContext) {
50
61
  throw new Error(`Transactions are not supported by current driver`);
51
62
  }
52
- async rollback(ctx, eventBroadcaster) {
63
+ async rollback(ctx, eventBroadcaster, loggerContext) {
53
64
  throw new Error(`Transactions are not supported by current driver`);
54
65
  }
55
66
  getConnectionOptions() {
@@ -67,7 +78,7 @@ export class Connection {
67
78
  }
68
79
  }
69
80
  else {
70
- const url = new URL(this.config.getClientUrl());
81
+ const url = new URL(this.config.get('clientUrl'));
71
82
  this.options.host = ret.host = this.options.host ?? this.config.get('host', decodeURIComponent(url.hostname));
72
83
  this.options.port = ret.port = this.options.port ?? this.config.get('port', +url.port);
73
84
  this.options.user = ret.user = this.options.user ?? this.config.get('user', decodeURIComponent(url.username));
@@ -76,15 +87,6 @@ export class Connection {
76
87
  }
77
88
  return ret;
78
89
  }
79
- getClientUrl() {
80
- const options = this.getConnectionOptions();
81
- const url = new URL(this.config.getClientUrl(true));
82
- const password = options.password ? ':*****' : '';
83
- const schema = options.schema && options.schema !== this.platform.getDefaultSchemaName()
84
- ? `?schema=${options.schema}`
85
- : '';
86
- return `${url.protocol}//${options.user}${password}@${options.host}:${options.port}${schema}`;
87
- }
88
90
  setMetadata(metadata) {
89
91
  this.metadata = metadata;
90
92
  }
@@ -1,5 +1,5 @@
1
- import { type CountOptions, type DeleteOptions, type DriverMethodOptions, EntityManagerType, type FindOneOptions, type FindOptions, type IDatabaseDriver, type LockOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type OrderDefinition } from './IDatabaseDriver.js';
2
- import type { ConnectionType, Dictionary, EntityData, EntityDictionary, EntityMetadata, EntityProperty, FilterQuery, PopulateOptions, Primary } from '../typings.js';
1
+ import { type CountOptions, type DeleteOptions, type DriverMethodOptions, EntityManagerType, type FindOneOptions, type FindOptions, type IDatabaseDriver, type LockOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type OrderDefinition, type StreamOptions } from './IDatabaseDriver.js';
2
+ import type { ConnectionType, Dictionary, EntityData, EntityDictionary, EntityMetadata, EntityName, EntityProperty, FilterQuery, PopulateOptions, Primary } from '../typings.js';
3
3
  import type { MetadataStorage } from '../metadata/MetadataStorage.js';
4
4
  import type { Connection, QueryResult, Transaction } from '../connections/Connection.js';
5
5
  import { type Configuration, type ConnectionOptions } from '../utils/Configuration.js';
@@ -30,20 +30,25 @@ export declare abstract class DatabaseDriver<C extends Connection> implements ID
30
30
  abstract nativeDelete<T extends object>(entityName: string, where: FilterQuery<T>, options?: DeleteOptions<T>): Promise<QueryResult<T>>;
31
31
  abstract count<T extends object, P extends string = never>(entityName: string, where: FilterQuery<T>, options?: CountOptions<T, P>): Promise<number>;
32
32
  createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
33
- findVirtual<T extends object>(entityName: string, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
33
+ findVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
34
34
  countVirtual<T extends object>(entityName: string, where: FilterQuery<T>, options: CountOptions<T, any>): Promise<number>;
35
35
  aggregate(entityName: string, pipeline: any[]): Promise<any[]>;
36
36
  loadFromPivotTable<T extends object, O extends object>(prop: EntityProperty, owners: Primary<O>[][], where?: FilterQuery<any>, orderBy?: OrderDefinition<T>, ctx?: Transaction, options?: FindOptions<T, any, any, any>, pivotJoin?: boolean): Promise<Dictionary<T[]>>;
37
37
  syncCollections<T extends object, O extends object>(collections: Iterable<Collection<T, O>>, options?: DriverMethodOptions): Promise<void>;
38
38
  mapResult<T extends object>(result: EntityDictionary<T>, meta?: EntityMetadata<T>, populate?: PopulateOptions<T>[]): EntityData<T> | null;
39
- connect(): Promise<C>;
40
- reconnect(): Promise<C>;
39
+ connect(options?: {
40
+ skipOnConnect?: boolean;
41
+ }): Promise<C>;
42
+ reconnect(options?: {
43
+ skipOnConnect?: boolean;
44
+ }): Promise<C>;
41
45
  getConnection(type?: ConnectionType): C;
42
46
  close(force?: boolean): Promise<void>;
43
47
  getPlatform(): Platform;
44
48
  setMetadata(metadata: MetadataStorage): void;
45
49
  getMetadata(): MetadataStorage;
46
50
  getDependencies(): string[];
51
+ protected isPopulated<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T>, hint: PopulateOptions<T>, name?: string): boolean;
47
52
  protected processCursorOptions<T extends object, P extends string>(meta: EntityMetadata<T>, options: FindOptions<T, P, any, any>, orderBy: OrderDefinition<T>): {
48
53
  orderBy: OrderDefinition<T>[];
49
54
  where: FilterQuery<T>;
@@ -55,6 +60,7 @@ export declare abstract class DatabaseDriver<C extends Connection> implements ID
55
60
  protected getPrimaryKeyFields(entityName: string): string[];
56
61
  protected createReplicas(cb: (c: ConnectionOptions) => C): C[];
57
62
  lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
63
+ abstract stream<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T>): AsyncIterableIterator<T>;
58
64
  /**
59
65
  * @inheritDoc
60
66
  */
@@ -65,14 +65,14 @@ export class DatabaseDriver {
65
65
  }
66
66
  return this.comparator.mapResult(meta.className, result);
67
67
  }
68
- async connect() {
69
- await this.connection.connect();
68
+ async connect(options) {
69
+ await this.connection.connect(options);
70
70
  await Promise.all(this.replicas.map(replica => replica.connect()));
71
71
  return this.connection;
72
72
  }
73
- async reconnect() {
73
+ async reconnect(options) {
74
74
  await this.close(true);
75
- await this.connect();
75
+ await this.connect(options);
76
76
  return this.connection;
77
77
  }
78
78
  getConnection(type = 'write') {
@@ -105,6 +105,15 @@ export class DatabaseDriver {
105
105
  getDependencies() {
106
106
  return this.dependencies;
107
107
  }
108
+ isPopulated(meta, prop, hint, name) {
109
+ if (hint.field === prop.name || hint.field === name || hint.all) {
110
+ return true;
111
+ }
112
+ if (prop.embedded && hint.children && meta.properties[prop.embedded[0]].name === hint.field) {
113
+ return hint.children.some(c => this.isPopulated(meta, prop, c, prop.embedded[1]));
114
+ }
115
+ return false;
116
+ }
108
117
  processCursorOptions(meta, options, orderBy) {
109
118
  const { first, last, before, after, overfetch } = options;
110
119
  const limit = first ?? last;
@@ -1,4 +1,4 @@
1
- import type { ConnectionType, EntityData, EntityMetadata, EntityProperty, FilterQuery, Primary, Dictionary, QBFilterQuery, IPrimaryKey, PopulateOptions, EntityDictionary, AutoPath, ObjectQuery, FilterObject, Populate } from '../typings.js';
1
+ import type { ConnectionType, EntityData, EntityMetadata, EntityProperty, FilterQuery, Primary, Dictionary, QBFilterQuery, IPrimaryKey, PopulateOptions, EntityDictionary, AutoPath, ObjectQuery, FilterObject, Populate, EntityName } from '../typings.js';
2
2
  import type { Connection, QueryResult, Transaction } from '../connections/Connection.js';
3
3
  import type { FlushMode, LockMode, QueryOrderMap, QueryFlag, LoadStrategy, PopulateHint, PopulatePath } from '../enums.js';
4
4
  import type { Platform } from '../platforms/Platform.js';
@@ -14,9 +14,13 @@ export interface IDatabaseDriver<C extends Connection = Connection> {
14
14
  [EntityManagerType]: EntityManager<this>;
15
15
  readonly config: Configuration;
16
16
  createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
17
- connect(): Promise<C>;
17
+ connect(options?: {
18
+ skipOnConnect?: boolean;
19
+ }): Promise<C>;
18
20
  close(force?: boolean): Promise<void>;
19
- reconnect(): Promise<C>;
21
+ reconnect(options?: {
22
+ skipOnConnect?: boolean;
23
+ }): Promise<C>;
20
24
  getConnection(type?: ConnectionType): C;
21
25
  /**
22
26
  * Finds selection of entities
@@ -27,6 +31,7 @@ export interface IDatabaseDriver<C extends Connection = Connection> {
27
31
  */
28
32
  findOne<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName: string, where: FilterQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
29
33
  findVirtual<T extends object>(entityName: string, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
34
+ stream<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T>): AsyncIterableIterator<T>;
30
35
  nativeInsert<T extends object>(entityName: string, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
31
36
  nativeInsertMany<T extends object>(entityName: string, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>, transform?: (sql: string) => string): Promise<QueryResult<T>>;
32
37
  nativeUpdate<T extends object>(entityName: string, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
@@ -68,6 +73,18 @@ export type OrderDefinition<T> = (QueryOrderMap<T> & {
68
73
  export interface FindAllOptions<T, P extends string = never, F extends string = '*', E extends string = never> extends FindOptions<T, P, F, E> {
69
74
  where?: FilterQuery<T>;
70
75
  }
76
+ export interface StreamOptions<Entity, Populate extends string = never, Fields extends string = '*', Exclude extends string = never> extends Omit<FindAllOptions<Entity, Populate, Fields, Exclude>, 'cache' | 'before' | 'after' | 'first' | 'last' | 'overfetch' | 'strategy'> {
77
+ /**
78
+ * When populating to-many relations, the ORM streams fully merged entities instead of yielding every row.
79
+ * You can opt out of this behavior by specifying `mergeResults: false`. This will yield every row from
80
+ * the SQL result, but still mapped to entities, meaning that to-many collections will contain at most
81
+ * a single item, and you will get duplicate root entities when they have multiple items in the populated
82
+ * collection.
83
+ *
84
+ * @default true
85
+ */
86
+ mergeResults?: boolean;
87
+ }
71
88
  export type FilterOptions = Dictionary<boolean | Dictionary> | string[] | boolean;
72
89
  export interface LoadHint<Entity, Hint extends string = never, Fields extends string = PopulatePath.ALL, Excludes extends string = never> {
73
90
  populate?: Populate<Entity, Hint>;
@@ -149,9 +166,10 @@ export interface FindOptions<Entity, Hint extends string = never, Fields extends
149
166
  /** @internal used to apply filters to the auto-joined relations */
150
167
  em?: EntityManager;
151
168
  }
152
- export interface FindByCursorOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'offset'> {
169
+ export interface FindByCursorOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never, I extends boolean = true> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'offset'> {
170
+ includeCount?: I;
153
171
  }
154
- export interface FindOneOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'lockMode'> {
172
+ export interface FindOneOptions<T, P extends string = never, F extends string = '*', E extends string = never> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'lockMode'> {
155
173
  lockMode?: LockMode;
156
174
  lockVersion?: number | Date;
157
175
  }
@@ -165,6 +183,7 @@ export interface NativeInsertUpdateOptions<T> {
165
183
  schema?: string;
166
184
  /** `nativeUpdate()` only option */
167
185
  upsert?: boolean;
186
+ loggerContext?: LogContext;
168
187
  }
169
188
  export interface NativeInsertUpdateManyOptions<T> extends NativeInsertUpdateOptions<T> {
170
189
  processCollections?: boolean;
@@ -199,6 +218,8 @@ export interface CountOptions<T extends object, P extends string = never> {
199
218
  hintComments?: string | string[];
200
219
  loggerContext?: LogContext;
201
220
  logging?: LoggingOptions;
221
+ /** @internal used to apply filters to the auto-joined relations */
222
+ em?: EntityManager;
202
223
  }
203
224
  export interface UpdateOptions<T> {
204
225
  filters?: FilterOptions;
@@ -220,6 +241,7 @@ export interface LockOptions extends DriverMethodOptions {
220
241
  export interface DriverMethodOptions {
221
242
  ctx?: Transaction;
222
243
  schema?: string;
244
+ loggerContext?: LogContext;
223
245
  }
224
246
  export interface GetReferenceOptions {
225
247
  wrapped?: boolean;