@mikro-orm/core 7.0.0-dev.22 → 7.0.0-dev.221

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 (209) hide show
  1. package/EntityManager.d.ts +101 -59
  2. package/EntityManager.js +302 -276
  3. package/MikroORM.d.ts +44 -35
  4. package/MikroORM.js +109 -143
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +1 -1
  7. package/cache/FileCacheAdapter.js +8 -7
  8. package/cache/GeneratedCacheAdapter.d.ts +0 -1
  9. package/cache/GeneratedCacheAdapter.js +0 -2
  10. package/cache/index.d.ts +0 -1
  11. package/cache/index.js +0 -1
  12. package/connections/Connection.d.ts +16 -7
  13. package/connections/Connection.js +23 -14
  14. package/drivers/DatabaseDriver.d.ts +25 -16
  15. package/drivers/DatabaseDriver.js +80 -35
  16. package/drivers/IDatabaseDriver.d.ts +46 -19
  17. package/entity/BaseEntity.d.ts +61 -2
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +94 -29
  20. package/entity/Collection.js +434 -97
  21. package/entity/EntityAssigner.d.ts +1 -1
  22. package/entity/EntityAssigner.js +26 -18
  23. package/entity/EntityFactory.d.ts +13 -1
  24. package/entity/EntityFactory.js +84 -53
  25. package/entity/EntityHelper.d.ts +2 -2
  26. package/entity/EntityHelper.js +40 -15
  27. package/entity/EntityLoader.d.ts +6 -6
  28. package/entity/EntityLoader.js +119 -82
  29. package/entity/EntityRepository.d.ts +27 -7
  30. package/entity/EntityRepository.js +8 -2
  31. package/entity/Reference.d.ts +6 -5
  32. package/entity/Reference.js +34 -9
  33. package/entity/WrappedEntity.d.ts +0 -5
  34. package/entity/WrappedEntity.js +3 -8
  35. package/entity/defineEntity.d.ts +595 -0
  36. package/entity/defineEntity.js +533 -0
  37. package/entity/index.d.ts +3 -2
  38. package/entity/index.js +3 -2
  39. package/entity/utils.d.ts +7 -0
  40. package/entity/utils.js +16 -4
  41. package/entity/validators.d.ts +11 -0
  42. package/entity/validators.js +65 -0
  43. package/enums.d.ts +22 -7
  44. package/enums.js +15 -1
  45. package/errors.d.ts +22 -9
  46. package/errors.js +56 -21
  47. package/events/EventManager.d.ts +2 -1
  48. package/events/EventManager.js +19 -11
  49. package/hydration/Hydrator.js +1 -2
  50. package/hydration/ObjectHydrator.d.ts +4 -4
  51. package/hydration/ObjectHydrator.js +52 -33
  52. package/index.d.ts +2 -2
  53. package/index.js +1 -2
  54. package/logging/DefaultLogger.d.ts +1 -1
  55. package/logging/DefaultLogger.js +1 -0
  56. package/logging/SimpleLogger.d.ts +1 -1
  57. package/logging/colors.d.ts +1 -1
  58. package/logging/colors.js +7 -6
  59. package/logging/index.d.ts +1 -0
  60. package/logging/index.js +1 -0
  61. package/logging/inspect.d.ts +2 -0
  62. package/logging/inspect.js +11 -0
  63. package/metadata/EntitySchema.d.ts +40 -23
  64. package/metadata/EntitySchema.js +81 -34
  65. package/metadata/MetadataDiscovery.d.ts +7 -10
  66. package/metadata/MetadataDiscovery.js +391 -331
  67. package/metadata/MetadataProvider.d.ts +11 -2
  68. package/metadata/MetadataProvider.js +46 -2
  69. package/metadata/MetadataStorage.d.ts +13 -11
  70. package/metadata/MetadataStorage.js +70 -37
  71. package/metadata/MetadataValidator.d.ts +17 -9
  72. package/metadata/MetadataValidator.js +94 -40
  73. package/metadata/discover-entities.d.ts +5 -0
  74. package/metadata/discover-entities.js +40 -0
  75. package/metadata/index.d.ts +1 -1
  76. package/metadata/index.js +1 -1
  77. package/metadata/types.d.ts +498 -0
  78. package/metadata/types.js +1 -0
  79. package/naming-strategy/AbstractNamingStrategy.d.ts +12 -4
  80. package/naming-strategy/AbstractNamingStrategy.js +14 -2
  81. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  82. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  83. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  84. package/naming-strategy/MongoNamingStrategy.js +6 -6
  85. package/naming-strategy/NamingStrategy.d.ts +24 -4
  86. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  87. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  88. package/not-supported.d.ts +2 -0
  89. package/not-supported.js +4 -0
  90. package/package.json +19 -11
  91. package/platforms/ExceptionConverter.js +1 -1
  92. package/platforms/Platform.d.ts +10 -15
  93. package/platforms/Platform.js +20 -43
  94. package/serialization/EntitySerializer.d.ts +5 -0
  95. package/serialization/EntitySerializer.js +47 -27
  96. package/serialization/EntityTransformer.js +28 -18
  97. package/serialization/SerializationContext.d.ts +6 -6
  98. package/serialization/SerializationContext.js +16 -13
  99. package/types/ArrayType.d.ts +1 -1
  100. package/types/ArrayType.js +2 -3
  101. package/types/BigIntType.d.ts +8 -6
  102. package/types/BigIntType.js +1 -1
  103. package/types/BlobType.d.ts +0 -1
  104. package/types/BlobType.js +0 -3
  105. package/types/BooleanType.d.ts +2 -1
  106. package/types/BooleanType.js +3 -0
  107. package/types/DecimalType.d.ts +6 -4
  108. package/types/DecimalType.js +3 -3
  109. package/types/DoubleType.js +2 -2
  110. package/types/EnumArrayType.js +1 -2
  111. package/types/JsonType.d.ts +1 -1
  112. package/types/JsonType.js +7 -2
  113. package/types/TinyIntType.js +1 -1
  114. package/types/Type.d.ts +2 -4
  115. package/types/Type.js +3 -3
  116. package/types/Uint8ArrayType.d.ts +0 -1
  117. package/types/Uint8ArrayType.js +1 -4
  118. package/types/index.d.ts +1 -1
  119. package/typings.d.ts +315 -155
  120. package/typings.js +66 -44
  121. package/unit-of-work/ChangeSet.d.ts +2 -6
  122. package/unit-of-work/ChangeSet.js +4 -5
  123. package/unit-of-work/ChangeSetComputer.d.ts +1 -3
  124. package/unit-of-work/ChangeSetComputer.js +26 -13
  125. package/unit-of-work/ChangeSetPersister.d.ts +5 -4
  126. package/unit-of-work/ChangeSetPersister.js +70 -34
  127. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  128. package/unit-of-work/CommitOrderCalculator.js +13 -13
  129. package/unit-of-work/IdentityMap.d.ts +12 -0
  130. package/unit-of-work/IdentityMap.js +39 -1
  131. package/unit-of-work/UnitOfWork.d.ts +23 -3
  132. package/unit-of-work/UnitOfWork.js +175 -98
  133. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  134. package/utils/AbstractSchemaGenerator.js +18 -16
  135. package/utils/AsyncContext.d.ts +6 -0
  136. package/utils/AsyncContext.js +42 -0
  137. package/utils/Configuration.d.ts +791 -207
  138. package/utils/Configuration.js +147 -190
  139. package/utils/ConfigurationLoader.d.ts +1 -54
  140. package/utils/ConfigurationLoader.js +1 -352
  141. package/utils/Cursor.d.ts +0 -3
  142. package/utils/Cursor.js +27 -11
  143. package/utils/DataloaderUtils.d.ts +15 -5
  144. package/utils/DataloaderUtils.js +64 -30
  145. package/utils/EntityComparator.d.ts +13 -9
  146. package/utils/EntityComparator.js +101 -42
  147. package/utils/QueryHelper.d.ts +14 -6
  148. package/utils/QueryHelper.js +87 -25
  149. package/utils/RawQueryFragment.d.ts +60 -32
  150. package/utils/RawQueryFragment.js +68 -70
  151. package/utils/RequestContext.js +2 -2
  152. package/utils/TransactionContext.js +2 -2
  153. package/utils/TransactionManager.d.ts +65 -0
  154. package/utils/TransactionManager.js +223 -0
  155. package/utils/Utils.d.ts +13 -126
  156. package/utils/Utils.js +100 -391
  157. package/utils/clone.js +8 -23
  158. package/utils/env-vars.d.ts +7 -0
  159. package/utils/env-vars.js +97 -0
  160. package/utils/fs-utils.d.ts +33 -0
  161. package/utils/fs-utils.js +192 -0
  162. package/utils/index.d.ts +2 -1
  163. package/utils/index.js +2 -1
  164. package/utils/upsert-utils.d.ts +9 -4
  165. package/utils/upsert-utils.js +55 -4
  166. package/decorators/Check.d.ts +0 -3
  167. package/decorators/Check.js +0 -13
  168. package/decorators/CreateRequestContext.d.ts +0 -3
  169. package/decorators/CreateRequestContext.js +0 -32
  170. package/decorators/Embeddable.d.ts +0 -8
  171. package/decorators/Embeddable.js +0 -11
  172. package/decorators/Embedded.d.ts +0 -12
  173. package/decorators/Embedded.js +0 -18
  174. package/decorators/Entity.d.ts +0 -18
  175. package/decorators/Entity.js +0 -12
  176. package/decorators/Enum.d.ts +0 -9
  177. package/decorators/Enum.js +0 -16
  178. package/decorators/Filter.d.ts +0 -2
  179. package/decorators/Filter.js +0 -8
  180. package/decorators/Formula.d.ts +0 -4
  181. package/decorators/Formula.js +0 -15
  182. package/decorators/Indexed.d.ts +0 -19
  183. package/decorators/Indexed.js +0 -20
  184. package/decorators/ManyToMany.d.ts +0 -40
  185. package/decorators/ManyToMany.js +0 -14
  186. package/decorators/ManyToOne.d.ts +0 -32
  187. package/decorators/ManyToOne.js +0 -14
  188. package/decorators/OneToMany.d.ts +0 -28
  189. package/decorators/OneToMany.js +0 -17
  190. package/decorators/OneToOne.d.ts +0 -26
  191. package/decorators/OneToOne.js +0 -7
  192. package/decorators/PrimaryKey.d.ts +0 -8
  193. package/decorators/PrimaryKey.js +0 -20
  194. package/decorators/Property.d.ts +0 -250
  195. package/decorators/Property.js +0 -32
  196. package/decorators/Transactional.d.ts +0 -13
  197. package/decorators/Transactional.js +0 -28
  198. package/decorators/hooks.d.ts +0 -16
  199. package/decorators/hooks.js +0 -47
  200. package/decorators/index.d.ts +0 -17
  201. package/decorators/index.js +0 -17
  202. package/entity/ArrayCollection.d.ts +0 -116
  203. package/entity/ArrayCollection.js +0 -402
  204. package/entity/EntityValidator.d.ts +0 -19
  205. package/entity/EntityValidator.js +0 -150
  206. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  207. package/metadata/ReflectMetadataProvider.js +0 -44
  208. package/utils/resolveContextProvider.d.ts +0 -10
  209. package/utils/resolveContextProvider.js +0 -28
package/MikroORM.d.ts CHANGED
@@ -3,13 +3,42 @@ 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
+ /** @internal */
8
+ export declare function loadOptionalDependencies(options: Options): Promise<void>;
7
9
  /**
8
- * Helper class for bootstrapping the MikroORM.
10
+ * The main class used to configure and bootstrap the ORM.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // import from driver package
15
+ * import { MikroORM, defineEntity, p } from '@mikro-orm/sqlite';
16
+ *
17
+ * const User = defineEntity({
18
+ * name: 'User',
19
+ * properties: {
20
+ * id: p.integer().primary(),
21
+ * name: p.string(),
22
+ * },
23
+ * });
24
+ *
25
+ * const orm = new MikroORM({
26
+ * entities: [User],
27
+ * dbName: 'my.db',
28
+ * });
29
+ * await orm.schema.update();
30
+ *
31
+ * const em = orm.em.fork();
32
+ * const u1 = em.create(User, { name: 'John' });
33
+ * const u2 = em.create(User, { name: 'Ben' });
34
+ * await em.flush();
35
+ * ```
9
36
  */
10
- export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = Driver[typeof EntityManagerType] & EntityManager> {
37
+ 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
38
  /** The global EntityManager instance. If you are using `RequestContext` helper, it will automatically pick the request specific context under the hood */
12
- em: EM;
39
+ em: EM & {
40
+ '~entities'?: Entities;
41
+ };
13
42
  readonly driver: Driver;
14
43
  readonly config: Configuration<Driver>;
15
44
  private metadata;
@@ -19,16 +48,14 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
19
48
  * Initialize the ORM, load entity metadata, create EntityManager and connect to the database.
20
49
  * If you omit the `options` parameter, your CLI config will be used.
21
50
  */
22
- static init<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options?: Options<D, EM>): Promise<MikroORM<D, EM>>;
51
+ 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
52
  /**
24
53
  * Synchronous variant of the `init` method with some limitations:
25
- * - database connection will be established when you first interact with the database (or you can use `orm.connect()` explicitly)
26
- * - no loading of the `config` file, `options` parameter is mandatory
27
- * - no support for folder based discovery
28
- * - no check for mismatched package versions
54
+ * - folder-based discovery not supported
55
+ * - ORM extensions are not autoloaded
56
+ * - when metadata cache is enabled, `FileCacheAdapter` needs to be explicitly set in the config
29
57
  */
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>);
58
+ constructor(options: Options<Driver, EM, Entities>);
32
59
  /**
33
60
  * Connects to the database.
34
61
  */
@@ -36,13 +63,13 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
36
63
  /**
37
64
  * Reconnects, possibly to a different database.
38
65
  */
39
- reconnect(options?: Options): Promise<void>;
66
+ reconnect(options?: Partial<Options<Driver, EM, Entities>>): Promise<void>;
40
67
  /**
41
68
  * Checks whether the database connection is active.
42
69
  */
43
70
  isConnected(): Promise<boolean>;
44
71
  /**
45
- * Checks whether the database connection is active, returns .
72
+ * Checks whether the database connection is active, returns the reason if not.
46
73
  */
47
74
  checkConnection(): Promise<{
48
75
  ok: true;
@@ -63,43 +90,25 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
63
90
  * Gets the `EntityMetadata` instance when provided with the `entityName` parameter.
64
91
  */
65
92
  getMetadata<Entity extends object>(entityName: EntityName<Entity>): EntityMetadata<Entity>;
66
- discoverEntities(): Promise<void>;
67
- discoverEntitiesSync(): void;
68
93
  private createEntityManager;
69
94
  /**
70
95
  * Allows dynamically discovering new entity by reference, handy for testing schema diffing.
71
96
  */
72
- discoverEntity<T extends Constructor | EntitySchema>(entities: T | T[], reset?: string | string[]): void;
97
+ discoverEntity<T extends Constructor | EntitySchema>(entities: T | T[], reset?: EntityName | EntityName[]): void;
73
98
  /**
74
99
  * Gets the SchemaGenerator.
75
100
  */
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;
101
+ get schema(): ReturnType<ReturnType<Driver['getPlatform']>['getSchemaGenerator']>;
85
102
  /**
86
103
  * Gets the SeedManager
87
104
  */
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
105
  get seeder(): ISeedManager;
97
106
  /**
98
- * Shortcut for `orm.getMigrator()`
107
+ * Gets the Migrator.
99
108
  */
100
109
  get migrator(): IMigrator;
101
110
  /**
102
- * Shortcut for `orm.getEntityGenerator()`
111
+ * Gets the EntityGenerator.
103
112
  */
104
113
  get entityGenerator(): IEntityGenerator;
105
114
  }
package/MikroORM.js CHANGED
@@ -1,14 +1,73 @@
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
- import { ConfigurationLoader } from './utils/ConfigurationLoader.js';
4
+ import { loadEnvironmentVars } from './utils/env-vars.js';
7
5
  import { Utils } from './utils/Utils.js';
8
6
  import { colors } from './logging/colors.js';
9
- import { NullCacheAdapter } from './cache/NullCacheAdapter.js';
7
+ async function tryRegisterExtension(name, pkg, extensions) {
8
+ try {
9
+ const url = import.meta.resolve(pkg);
10
+ const mod = await import(url);
11
+ if (mod[name]) {
12
+ extensions.push(mod[name]);
13
+ }
14
+ }
15
+ catch {
16
+ // not installed
17
+ }
18
+ }
19
+ /** @internal */
20
+ export async function loadOptionalDependencies(options) {
21
+ await import('@mikro-orm/core/fs-utils').then(m => m.fs.init()).catch(() => null);
22
+ const extensions = options.extensions ?? [];
23
+ const exists = (name) => extensions.some(ext => ext.name === name);
24
+ if (!exists('SeedManager')) {
25
+ await tryRegisterExtension('SeedManager', '@mikro-orm/seeder', extensions);
26
+ }
27
+ if (!exists('Migrator')) {
28
+ await tryRegisterExtension('Migrator', '@mikro-orm/migrations', extensions);
29
+ }
30
+ /* v8 ignore if */
31
+ if (!exists('Migrator')) {
32
+ await tryRegisterExtension('Migrator', '@mikro-orm/migrations-mongodb', extensions);
33
+ }
34
+ if (!exists('EntityGenerator')) {
35
+ await tryRegisterExtension('EntityGenerator', '@mikro-orm/entity-generator', extensions);
36
+ }
37
+ options.extensions = extensions;
38
+ const metadataCacheEnabled = options.metadataCache?.enabled || options.metadataProvider?.useCache?.();
39
+ if (metadataCacheEnabled) {
40
+ options.metadataCache ??= {};
41
+ options.metadataCache.adapter ??= await import('@mikro-orm/core/fs-utils').then(m => m.FileCacheAdapter);
42
+ }
43
+ }
10
44
  /**
11
- * Helper class for bootstrapping the MikroORM.
45
+ * The main class used to configure and bootstrap the ORM.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * // import from driver package
50
+ * import { MikroORM, defineEntity, p } from '@mikro-orm/sqlite';
51
+ *
52
+ * const User = defineEntity({
53
+ * name: 'User',
54
+ * properties: {
55
+ * id: p.integer().primary(),
56
+ * name: p.string(),
57
+ * },
58
+ * });
59
+ *
60
+ * const orm = new MikroORM({
61
+ * entities: [User],
62
+ * dbName: 'my.db',
63
+ * });
64
+ * await orm.schema.update();
65
+ *
66
+ * const em = orm.em.fork();
67
+ * const u1 = em.create(User, { name: 'John' });
68
+ * const u2 = em.create(User, { name: 'Ben' });
69
+ * await em.flush();
70
+ * ```
12
71
  */
13
72
  export class MikroORM {
14
73
  /** The global EntityManager instance. If you are using `RequestContext` helper, it will automatically pick the request specific context under the hood */
@@ -23,104 +82,58 @@ export class MikroORM {
23
82
  * If you omit the `options` parameter, your CLI config will be used.
24
83
  */
25
84
  static async init(options) {
26
- ConfigurationLoader.registerDotenv(options);
27
- const coreVersion = ConfigurationLoader.checkPackageVersion();
28
- const env = await ConfigurationLoader.loadEnvironmentVars();
85
+ /* v8 ignore next */
29
86
  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
- }
87
+ throw new Error(`options parameter is required`);
88
+ }
89
+ options = { ...options };
90
+ options.discovery ??= {};
91
+ options.discovery.skipSyncDiscovery ??= true;
92
+ await loadOptionalDependencies(options);
93
+ const orm = new this(options);
94
+ const preferTs = orm.config.get('preferTs', Utils.detectTypeScriptSupport());
95
+ orm.metadata = await orm.discovery.discover(preferTs);
96
+ orm.createEntityManager();
59
97
  return orm;
60
98
  }
61
99
  /**
62
100
  * Synchronous variant of the `init` method with some limitations:
63
- * - database connection will be established when you first interact with the database (or you can use `orm.connect()` explicitly)
64
- * - no loading of the `config` file, `options` parameter is mandatory
65
- * - no support for folder based discovery
66
- * - no check for mismatched package versions
101
+ * - folder-based discovery not supported
102
+ * - ORM extensions are not autoloaded
103
+ * - when metadata cache is enabled, `FileCacheAdapter` needs to be explicitly set in the config
67
104
  */
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
105
  constructor(options) {
106
+ const env = loadEnvironmentVars();
107
+ options = options.preferEnvVars
108
+ ? Utils.merge(options, env)
109
+ : Utils.merge(env, options);
88
110
  this.config = new Configuration(options);
89
111
  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
112
  this.driver = this.config.getDriver();
96
113
  this.logger = this.config.getLogger();
114
+ this.logger.log('info', `MikroORM version: ${colors.green(Utils.getORMVersion())}`);
97
115
  this.discovery = new MetadataDiscovery(new MetadataStorage(), this.driver.getPlatform(), this.config);
116
+ this.driver.getPlatform().init(this);
117
+ for (const extension of this.config.get('extensions')) {
118
+ extension.register(this);
119
+ }
120
+ if (!discovery.skipSyncDiscovery) {
121
+ this.metadata = this.discovery.discoverSync();
122
+ this.createEntityManager();
123
+ }
98
124
  }
99
125
  /**
100
126
  * Connects to the database.
101
127
  */
102
128
  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
- }
129
+ await this.driver.connect();
117
130
  return this.driver;
118
131
  }
119
132
  /**
120
133
  * Reconnects, possibly to a different database.
121
134
  */
122
135
  async reconnect(options = {}) {
123
- /* v8 ignore next 3 */
136
+ /* v8 ignore next */
124
137
  for (const key of Utils.keys(options)) {
125
138
  this.config.set(key, options[key]);
126
139
  }
@@ -133,7 +146,7 @@ export class MikroORM {
133
146
  return this.driver.getConnection().isConnected();
134
147
  }
135
148
  /**
136
- * Checks whether the database connection is active, returns .
149
+ * Checks whether the database connection is active, returns the reason if not.
137
150
  */
138
151
  async checkConnection() {
139
152
  return this.driver.getConnection().checkConnection();
@@ -142,34 +155,19 @@ export class MikroORM {
142
155
  * Closes the database connection.
143
156
  */
144
157
  async close(force = false) {
145
- if (await this.isConnected()) {
146
- await this.driver.close(force);
147
- }
148
- if (this.config.getMetadataCacheAdapter()?.close) {
149
- await this.config.getMetadataCacheAdapter().close();
150
- }
151
- if (this.config.getResultCacheAdapter()?.close) {
152
- await this.config.getResultCacheAdapter().close();
153
- }
158
+ await this.driver.close(force);
159
+ await this.config.getMetadataCacheAdapter()?.close?.();
160
+ await this.config.getResultCacheAdapter()?.close?.();
154
161
  }
155
162
  /**
156
163
  * Gets the `MetadataStorage` (without parameters) or `EntityMetadata` instance when provided with the `entityName` parameter.
157
164
  */
158
165
  getMetadata(entityName) {
159
166
  if (entityName) {
160
- entityName = Utils.className(entityName);
161
167
  return this.metadata.get(entityName);
162
168
  }
163
169
  return this.metadata;
164
170
  }
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
171
  createEntityManager() {
174
172
  this.driver.setMetadata(this.metadata);
175
173
  this.em = this.driver.createEntityManager();
@@ -181,72 +179,40 @@ export class MikroORM {
181
179
  * Allows dynamically discovering new entity by reference, handy for testing schema diffing.
182
180
  */
183
181
  discoverEntity(entities, reset) {
184
- entities = Utils.asArray(entities);
185
182
  for (const className of Utils.asArray(reset)) {
186
183
  this.metadata.reset(className);
187
184
  this.discovery.reset(className);
188
185
  }
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);
186
+ const tmp = this.discovery.discoverReferences(Utils.asArray(entities));
192
187
  const metadata = this.discovery.processDiscoveredEntities(tmp);
193
- metadata.forEach(meta => {
194
- this.metadata.set(meta.className, meta);
195
- meta.root = this.metadata.get(meta.root.className);
196
- });
188
+ for (const meta of metadata) {
189
+ this.metadata.set(meta.class, meta);
190
+ meta.root = this.metadata.get(meta.root.class);
191
+ }
197
192
  this.metadata.decorate(this.em);
198
193
  }
199
194
  /**
200
195
  * Gets the SchemaGenerator.
201
196
  */
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
197
  get schema() {
232
- return this.getSchemaGenerator();
198
+ return this.config.getExtension('@mikro-orm/schema-generator');
233
199
  }
234
200
  /**
235
- * Shortcut for `orm.getSeeder()`
201
+ * Gets the SeedManager
236
202
  */
237
203
  get seeder() {
238
- return this.getSeeder();
204
+ return this.driver.getPlatform().getExtension('SeedManager', '@mikro-orm/seeder', '@mikro-orm/seeder', this.em);
239
205
  }
240
206
  /**
241
- * Shortcut for `orm.getMigrator()`
207
+ * Gets the Migrator.
242
208
  */
243
209
  get migrator() {
244
- return this.getMigrator();
210
+ return this.driver.getPlatform().getExtension('Migrator', '@mikro-orm/migrator', '@mikro-orm/migrations', this.em);
245
211
  }
246
212
  /**
247
- * Shortcut for `orm.getEntityGenerator()`
213
+ * Gets the EntityGenerator.
248
214
  */
249
215
  get entityGenerator() {
250
- return this.getEntityGenerator();
216
+ return this.driver.getPlatform().getExtension('EntityGenerator', '@mikro-orm/entity-generator', '@mikro-orm/entity-generator', this.em);
251
217
  }
252
218
  }
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).
@@ -8,7 +8,7 @@ export declare class FileCacheAdapter implements SyncCacheAdapter {
8
8
  constructor(options: {
9
9
  cacheDir: string;
10
10
  combined?: boolean | string;
11
- }, baseDir: string, pretty?: boolean);
11
+ } | undefined, baseDir: string, pretty?: boolean);
12
12
  /**
13
13
  * @inheritDoc
14
14
  */
@@ -1,5 +1,5 @@
1
- import { globSync } from 'tinyglobby';
2
1
  import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
2
+ import { fs } from '../utils/fs-utils.js';
3
3
  import { Utils } from '../utils/Utils.js';
4
4
  export class FileCacheAdapter {
5
5
  options;
@@ -7,10 +7,11 @@ export class FileCacheAdapter {
7
7
  pretty;
8
8
  VERSION = Utils.getORMVersion();
9
9
  cache = {};
10
- constructor(options, baseDir, pretty = false) {
10
+ constructor(options = {}, baseDir, pretty = false) {
11
11
  this.options = options;
12
12
  this.baseDir = baseDir;
13
13
  this.pretty = pretty;
14
+ this.options.cacheDir ??= process.cwd() + '/temp';
14
15
  }
15
16
  /**
16
17
  * @inheritDoc
@@ -20,7 +21,7 @@ export class FileCacheAdapter {
20
21
  if (!existsSync(path)) {
21
22
  return null;
22
23
  }
23
- const payload = Utils.readJSONSync(path);
24
+ const payload = fs.readJSONSync(path);
24
25
  const hash = this.getHash(payload.origin);
25
26
  if (!hash || payload.hash !== hash) {
26
27
  return null;
@@ -51,7 +52,7 @@ export class FileCacheAdapter {
51
52
  */
52
53
  clear() {
53
54
  const path = this.path('*');
54
- const files = globSync(path);
55
+ const files = fs.glob(path);
55
56
  files.forEach(file => unlinkSync(file));
56
57
  this.cache = {};
57
58
  }
@@ -62,17 +63,17 @@ export class FileCacheAdapter {
62
63
  let path = typeof this.options.combined === 'string'
63
64
  ? this.options.combined
64
65
  : './metadata.json';
65
- path = Utils.normalizePath(this.options.cacheDir, path);
66
+ path = fs.normalizePath(this.options.cacheDir, path);
66
67
  this.options.combined = path; // override in the options, so we can log it from the CLI in `cache:generate` command
67
68
  writeFileSync(path, JSON.stringify(this.cache, null, this.pretty ? 2 : undefined));
68
69
  return path;
69
70
  }
70
71
  path(name) {
71
- Utils.ensureDir(this.options.cacheDir);
72
+ fs.ensureDir(this.options.cacheDir);
72
73
  return `${this.options.cacheDir}/${name}.json`;
73
74
  }
74
75
  getHash(origin) {
75
- origin = Utils.absolutePath(origin, this.baseDir);
76
+ origin = fs.absolutePath(origin, this.baseDir);
76
77
  if (!existsSync(origin)) {
77
78
  return null;
78
79
  }
@@ -1,7 +1,6 @@
1
1
  import type { CacheAdapter } from './CacheAdapter.js';
2
2
  import type { Dictionary } from '../typings.js';
3
3
  export declare class GeneratedCacheAdapter implements CacheAdapter {
4
- private readonly options;
5
4
  private readonly data;
6
5
  constructor(options: {
7
6
  data: Dictionary;
@@ -1,8 +1,6 @@
1
1
  export class GeneratedCacheAdapter {
2
- options;
3
2
  data = new Map();
4
3
  constructor(options) {
5
- this.options = options;
6
4
  this.data = new Map(Object.entries(options.data));
7
5
  }
8
6
  /**
package/cache/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './CacheAdapter.js';
2
2
  export * from './NullCacheAdapter.js';
3
- export * from './FileCacheAdapter.js';
4
3
  export * from './MemoryCacheAdapter.js';
5
4
  export * from './GeneratedCacheAdapter.js';
package/cache/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './CacheAdapter.js';
2
2
  export * from './NullCacheAdapter.js';
3
- export * from './FileCacheAdapter.js';
4
3
  export * from './MemoryCacheAdapter.js';
5
4
  export * from './GeneratedCacheAdapter.js';
@@ -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,33 @@ 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
+ /**
46
+ * Execute raw SQL queries, handy from running schema dump loaded from a file.
47
+ * This method doesn't support transactions, as opposed to `orm.schema.execute()`, which is used internally.
48
+ */
49
+ executeDump(dump: string): Promise<void>;
50
+ protected onConnect(): Promise<void>;
43
51
  transactional<T>(cb: (trx: Transaction) => Promise<T>, options?: {
44
- isolationLevel?: IsolationLevel;
52
+ isolationLevel?: IsolationLevel | `${IsolationLevel}`;
45
53
  readOnly?: boolean;
46
54
  ctx?: Transaction;
47
55
  eventBroadcaster?: TransactionEventBroadcaster;
56
+ loggerContext?: LogContext;
48
57
  }): Promise<T>;
49
58
  begin(options?: {
50
- isolationLevel?: IsolationLevel;
59
+ isolationLevel?: IsolationLevel | `${IsolationLevel}`;
51
60
  readOnly?: boolean;
52
61
  ctx?: Transaction;
53
62
  eventBroadcaster?: TransactionEventBroadcaster;
63
+ loggerContext?: LogContext;
54
64
  }): Promise<Transaction>;
55
- commit(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster): Promise<void>;
56
- rollback(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster): Promise<void>;
65
+ commit(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster, loggerContext?: LogContext): Promise<void>;
66
+ rollback(ctx: Transaction, eventBroadcaster?: TransactionEventBroadcaster, loggerContext?: LogContext): Promise<void>;
57
67
  abstract execute<T>(query: string, params?: any[], method?: 'all' | 'get' | 'run', ctx?: Transaction): Promise<QueryResult<T> | any | any[]>;
58
68
  getConnectionOptions(): ConnectionConfig;
59
- getClientUrl(): string;
60
69
  setMetadata(metadata: MetadataStorage): void;
61
70
  setPlatform(platform: Platform): void;
62
71
  getPlatform(): Platform;