@mikro-orm/core 7.0.0-dev.5 → 7.0.0-dev.50

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 (115) hide show
  1. package/EntityManager.d.ts +81 -27
  2. package/EntityManager.js +287 -175
  3. package/MikroORM.d.ts +6 -6
  4. package/MikroORM.js +31 -74
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +2 -1
  7. package/cache/FileCacheAdapter.js +6 -4
  8. package/connections/Connection.d.ts +9 -5
  9. package/connections/Connection.js +16 -13
  10. package/decorators/Embedded.d.ts +5 -11
  11. package/decorators/Entity.d.ts +18 -3
  12. package/decorators/Indexed.d.ts +2 -2
  13. package/decorators/ManyToMany.d.ts +2 -0
  14. package/decorators/ManyToOne.d.ts +4 -0
  15. package/decorators/OneToOne.d.ts +4 -0
  16. package/decorators/Property.d.ts +53 -9
  17. package/decorators/Transactional.d.ts +1 -0
  18. package/decorators/Transactional.js +3 -3
  19. package/decorators/index.d.ts +1 -1
  20. package/drivers/DatabaseDriver.d.ts +10 -5
  21. package/drivers/DatabaseDriver.js +4 -4
  22. package/drivers/IDatabaseDriver.d.ts +28 -4
  23. package/entity/ArrayCollection.d.ts +6 -4
  24. package/entity/ArrayCollection.js +26 -9
  25. package/entity/BaseEntity.d.ts +0 -1
  26. package/entity/BaseEntity.js +0 -3
  27. package/entity/Collection.d.ts +3 -4
  28. package/entity/Collection.js +37 -17
  29. package/entity/EntityAssigner.d.ts +1 -1
  30. package/entity/EntityAssigner.js +9 -1
  31. package/entity/EntityFactory.d.ts +7 -0
  32. package/entity/EntityFactory.js +29 -11
  33. package/entity/EntityHelper.js +25 -8
  34. package/entity/EntityLoader.d.ts +5 -4
  35. package/entity/EntityLoader.js +69 -36
  36. package/entity/EntityRepository.d.ts +1 -1
  37. package/entity/EntityValidator.js +1 -1
  38. package/entity/Reference.d.ts +9 -7
  39. package/entity/Reference.js +30 -3
  40. package/entity/WrappedEntity.d.ts +0 -2
  41. package/entity/WrappedEntity.js +1 -5
  42. package/entity/defineEntity.d.ts +555 -0
  43. package/entity/defineEntity.js +529 -0
  44. package/entity/index.d.ts +2 -0
  45. package/entity/index.js +2 -0
  46. package/entity/utils.d.ts +7 -0
  47. package/entity/utils.js +15 -3
  48. package/enums.d.ts +16 -3
  49. package/enums.js +13 -0
  50. package/errors.d.ts +6 -1
  51. package/errors.js +14 -4
  52. package/events/EventSubscriber.d.ts +3 -1
  53. package/hydration/ObjectHydrator.d.ts +4 -4
  54. package/hydration/ObjectHydrator.js +35 -24
  55. package/index.d.ts +2 -1
  56. package/index.js +1 -1
  57. package/logging/DefaultLogger.d.ts +1 -1
  58. package/logging/SimpleLogger.d.ts +1 -1
  59. package/metadata/EntitySchema.d.ts +8 -4
  60. package/metadata/EntitySchema.js +39 -19
  61. package/metadata/MetadataDiscovery.d.ts +4 -4
  62. package/metadata/MetadataDiscovery.js +139 -122
  63. package/metadata/MetadataStorage.js +1 -1
  64. package/metadata/MetadataValidator.js +4 -3
  65. package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
  66. package/naming-strategy/AbstractNamingStrategy.js +7 -1
  67. package/naming-strategy/NamingStrategy.d.ts +11 -1
  68. package/package.json +5 -5
  69. package/platforms/Platform.d.ts +5 -3
  70. package/platforms/Platform.js +4 -8
  71. package/serialization/EntitySerializer.d.ts +2 -0
  72. package/serialization/EntitySerializer.js +23 -5
  73. package/serialization/EntityTransformer.js +16 -6
  74. package/serialization/SerializationContext.js +14 -11
  75. package/types/BigIntType.d.ts +9 -6
  76. package/types/BigIntType.js +3 -0
  77. package/types/BooleanType.d.ts +1 -1
  78. package/types/DecimalType.d.ts +6 -4
  79. package/types/DecimalType.js +1 -1
  80. package/types/DoubleType.js +1 -1
  81. package/types/JsonType.d.ts +1 -1
  82. package/types/JsonType.js +7 -2
  83. package/types/Type.d.ts +2 -1
  84. package/types/Type.js +1 -1
  85. package/types/index.d.ts +1 -1
  86. package/typings.d.ts +89 -49
  87. package/typings.js +31 -31
  88. package/unit-of-work/ChangeSetComputer.js +8 -3
  89. package/unit-of-work/ChangeSetPersister.d.ts +4 -2
  90. package/unit-of-work/ChangeSetPersister.js +37 -16
  91. package/unit-of-work/UnitOfWork.d.ts +8 -1
  92. package/unit-of-work/UnitOfWork.js +110 -53
  93. package/utils/AbstractSchemaGenerator.js +3 -1
  94. package/utils/Configuration.d.ts +29 -16
  95. package/utils/Configuration.js +17 -18
  96. package/utils/ConfigurationLoader.d.ts +9 -22
  97. package/utils/ConfigurationLoader.js +49 -72
  98. package/utils/Cursor.d.ts +3 -3
  99. package/utils/Cursor.js +3 -0
  100. package/utils/DataloaderUtils.d.ts +7 -2
  101. package/utils/DataloaderUtils.js +38 -7
  102. package/utils/EntityComparator.d.ts +6 -2
  103. package/utils/EntityComparator.js +104 -58
  104. package/utils/QueryHelper.d.ts +9 -1
  105. package/utils/QueryHelper.js +66 -5
  106. package/utils/RawQueryFragment.d.ts +36 -4
  107. package/utils/RawQueryFragment.js +34 -13
  108. package/utils/TransactionManager.d.ts +65 -0
  109. package/utils/TransactionManager.js +223 -0
  110. package/utils/Utils.d.ts +13 -11
  111. package/utils/Utils.js +82 -55
  112. package/utils/index.d.ts +1 -0
  113. package/utils/index.js +1 -0
  114. package/utils/upsert-utils.d.ts +7 -2
  115. package/utils/upsert-utils.js +52 -1
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 EntityManager = Driver[typeof EntityManagerType] & EntityManager, 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,15 +21,13 @@ 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 EntityManager = D[typeof EntityManagerType] & EntityManager, 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
31
  constructor(options: Options<Driver, EM>);
32
32
  /**
33
33
  * Connects to the database.
package/MikroORM.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { MetadataDiscovery } from './metadata/MetadataDiscovery.js';
2
2
  import { MetadataStorage } from './metadata/MetadataStorage.js';
3
- import { MetadataValidator } from './metadata/MetadataValidator.js';
4
3
  import { ReflectMetadataProvider } from './metadata/ReflectMetadataProvider.js';
5
4
  import { Configuration } from './utils/Configuration.js';
6
5
  import { ConfigurationLoader } from './utils/ConfigurationLoader.js';
@@ -23,39 +22,14 @@ export class MikroORM {
23
22
  * If you omit the `options` parameter, your CLI config will be used.
24
23
  */
25
24
  static async init(options) {
26
- ConfigurationLoader.registerDotenv(options);
27
- const coreVersion = ConfigurationLoader.checkPackageVersion();
28
- const env = await ConfigurationLoader.loadEnvironmentVars();
25
+ /* v8 ignore next 3 */
29
26
  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;
27
+ throw new Error(`options parameter is required`);
41
28
  }
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);
29
+ options.discovery ??= {};
30
+ options.discovery.skipSyncDiscovery ??= true;
31
+ const orm = new this(options);
47
32
  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
- }
59
33
  return orm;
60
34
  }
61
35
  /**
@@ -63,28 +37,12 @@ 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) {
41
+ constructor(options) {
69
42
  ConfigurationLoader.registerDotenv(options);
70
43
  const env = ConfigurationLoader.loadEnvironmentVarsSync();
44
+ const coreVersion = ConfigurationLoader.checkPackageVersion();
71
45
  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
- constructor(options) {
88
46
  this.config = new Configuration(options);
89
47
  const discovery = this.config.get('discovery');
90
48
  if (discovery.disableDynamicFileAccess) {
@@ -94,26 +52,21 @@ export class MikroORM {
94
52
  }
95
53
  this.driver = this.config.getDriver();
96
54
  this.logger = this.config.getLogger();
55
+ this.logger.log('info', `MikroORM version: ${colors.green(coreVersion)}`);
97
56
  this.discovery = new MetadataDiscovery(new MetadataStorage(), this.driver.getPlatform(), this.config);
57
+ this.driver.getPlatform().init(this);
58
+ for (const extension of this.config.get('extensions')) {
59
+ extension.register(this);
60
+ }
61
+ if (!discovery.skipSyncDiscovery) {
62
+ this.discoverEntitiesSync();
63
+ }
98
64
  }
99
65
  /**
100
66
  * Connects to the database.
101
67
  */
102
68
  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
- }
69
+ await this.driver.connect();
117
70
  return this.driver;
118
71
  }
119
72
  /**
@@ -142,9 +95,7 @@ export class MikroORM {
142
95
  * Closes the database connection.
143
96
  */
144
97
  async close(force = false) {
145
- if (await this.isConnected()) {
146
- await this.driver.close(force);
147
- }
98
+ await this.driver.close(force);
148
99
  if (this.config.getMetadataCacheAdapter()?.close) {
149
100
  await this.config.getMetadataCacheAdapter().close();
150
101
  }
@@ -163,12 +114,21 @@ export class MikroORM {
163
114
  return this.metadata;
164
115
  }
165
116
  async discoverEntities() {
166
- this.metadata = await this.discovery.discover(this.config.get('preferTs'));
117
+ // we need to allow global context here as we are not in a scope of requests yet
118
+ const allowGlobalContext = this.config.get('allowGlobalContext');
119
+ this.config.set('allowGlobalContext', true);
120
+ const preferTs = this.config.get('preferTs', Utils.detectTypeScriptSupport());
121
+ this.metadata = await this.discovery.discover(preferTs);
167
122
  this.createEntityManager();
123
+ this.config.set('allowGlobalContext', allowGlobalContext);
168
124
  }
169
125
  discoverEntitiesSync() {
170
- this.metadata = this.discovery.discoverSync(this.config.get('preferTs'));
126
+ // we need to allow global context here as we are not in a scope of requests yet
127
+ const allowGlobalContext = this.config.get('allowGlobalContext');
128
+ this.config.set('allowGlobalContext', true);
129
+ this.metadata = this.discovery.discoverSync();
171
130
  this.createEntityManager();
131
+ this.config.set('allowGlobalContext', allowGlobalContext);
172
132
  }
173
133
  createEntityManager() {
174
134
  this.driver.setMetadata(this.metadata);
@@ -181,19 +141,16 @@ export class MikroORM {
181
141
  * Allows dynamically discovering new entity by reference, handy for testing schema diffing.
182
142
  */
183
143
  discoverEntity(entities, reset) {
184
- entities = Utils.asArray(entities);
185
144
  for (const className of Utils.asArray(reset)) {
186
145
  this.metadata.reset(className);
187
146
  this.discovery.reset(className);
188
147
  }
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);
148
+ const tmp = this.discovery.discoverReferences(Utils.asArray(entities));
192
149
  const metadata = this.discovery.processDiscoveredEntities(tmp);
193
- metadata.forEach(meta => {
150
+ for (const meta of metadata) {
194
151
  this.metadata.set(meta.className, meta);
195
152
  meta.root = this.metadata.get(meta.root.className);
196
- });
153
+ }
197
154
  this.metadata.decorate(this.em);
198
155
  }
199
156
  /**
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).
@@ -3,12 +3,13 @@ export declare class FileCacheAdapter implements SyncCacheAdapter {
3
3
  private readonly options;
4
4
  private readonly baseDir;
5
5
  private readonly pretty;
6
+ private readonly hashAlgorithm;
6
7
  private readonly VERSION;
7
8
  private cache;
8
9
  constructor(options: {
9
10
  cacheDir: string;
10
11
  combined?: boolean | string;
11
- }, baseDir: string, pretty?: boolean);
12
+ }, baseDir: string, pretty?: boolean, hashAlgorithm?: 'md5' | 'sha256');
12
13
  /**
13
14
  * @inheritDoc
14
15
  */
@@ -1,16 +1,18 @@
1
- import globby from 'globby';
1
+ import { globSync } from 'tinyglobby';
2
2
  import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
3
3
  import { Utils } from '../utils/Utils.js';
4
4
  export class FileCacheAdapter {
5
5
  options;
6
6
  baseDir;
7
7
  pretty;
8
+ hashAlgorithm;
8
9
  VERSION = Utils.getORMVersion();
9
10
  cache = {};
10
- constructor(options, baseDir, pretty = false) {
11
+ constructor(options, baseDir, pretty = false, hashAlgorithm = 'md5') {
11
12
  this.options = options;
12
13
  this.baseDir = baseDir;
13
14
  this.pretty = pretty;
15
+ this.hashAlgorithm = hashAlgorithm;
14
16
  }
15
17
  /**
16
18
  * @inheritDoc
@@ -51,7 +53,7 @@ export class FileCacheAdapter {
51
53
  */
52
54
  clear() {
53
55
  const path = this.path('*');
54
- const files = globby.sync(path);
56
+ const files = globSync(path);
55
57
  files.forEach(file => unlinkSync(file));
56
58
  this.cache = {};
57
59
  }
@@ -77,6 +79,6 @@ export class FileCacheAdapter {
77
79
  return null;
78
80
  }
79
81
  const contents = readFileSync(origin);
80
- return Utils.hash(contents.toString() + this.VERSION);
82
+ return Utils.hash(contents.toString() + this.VERSION, undefined, this.hashAlgorithm);
81
83
  }
82
84
  }
@@ -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
47
  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
54
  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;
@@ -33,23 +33,35 @@ export class Connection {
33
33
  .forEach(k => delete this.options[k]);
34
34
  }
35
35
  /**
36
- * Ensure the connection exists, this is used to support lazy connect when using `MikroORM.initSync()`
36
+ * Ensure the connection exists, this is used to support lazy connect when using `new MikroORM()` instead of the async `init` method.
37
37
  */
38
38
  async ensureConnection() {
39
39
  if (!this.connected) {
40
40
  await this.connect();
41
41
  }
42
42
  }
43
+ async onConnect() {
44
+ const schemaGenerator = this.config.getExtension('@mikro-orm/schema-generator');
45
+ if (this.type === 'write' && schemaGenerator) {
46
+ if (this.config.get('ensureDatabase')) {
47
+ const options = this.config.get('ensureDatabase');
48
+ await schemaGenerator.ensureDatabase(typeof options === 'boolean' ? {} : { ...options, forceCheck: true });
49
+ }
50
+ if (this.config.get('ensureIndexes')) {
51
+ await schemaGenerator.ensureIndexes();
52
+ }
53
+ }
54
+ }
43
55
  async transactional(cb, options) {
44
56
  throw new Error(`Transactions are not supported by current driver`);
45
57
  }
46
58
  async begin(options) {
47
59
  throw new Error(`Transactions are not supported by current driver`);
48
60
  }
49
- async commit(ctx, eventBroadcaster) {
61
+ async commit(ctx, eventBroadcaster, loggerContext) {
50
62
  throw new Error(`Transactions are not supported by current driver`);
51
63
  }
52
- async rollback(ctx, eventBroadcaster) {
64
+ async rollback(ctx, eventBroadcaster, loggerContext) {
53
65
  throw new Error(`Transactions are not supported by current driver`);
54
66
  }
55
67
  getConnectionOptions() {
@@ -67,7 +79,7 @@ export class Connection {
67
79
  }
68
80
  }
69
81
  else {
70
- const url = new URL(this.config.getClientUrl());
82
+ const url = new URL(this.config.get('clientUrl'));
71
83
  this.options.host = ret.host = this.options.host ?? this.config.get('host', decodeURIComponent(url.hostname));
72
84
  this.options.port = ret.port = this.options.port ?? this.config.get('port', +url.port);
73
85
  this.options.user = ret.user = this.options.user ?? this.config.get('user', decodeURIComponent(url.username));
@@ -76,15 +88,6 @@ export class Connection {
76
88
  }
77
89
  return ret;
78
90
  }
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
91
  setMetadata(metadata) {
89
92
  this.metadata = metadata;
90
93
  }
@@ -1,18 +1,12 @@
1
- import type { AnyEntity } from '../typings.js';
2
- export declare function Embedded<T extends object>(type?: EmbeddedOptions | (() => AnyEntity), options?: EmbeddedOptions): (target: AnyEntity, propertyName: string) => any;
1
+ import type { AnyEntity, EntityName } from '../typings.js';
2
+ import type { PropertyOptions } from './Property.js';
3
+ export declare function Embedded<Owner extends object, Target>(type?: EmbeddedOptions<Owner, Target> | (() => EntityName<Target> | EntityName<Target>[]), options?: EmbeddedOptions<Owner, Target>): (target: AnyEntity, propertyName: string) => any;
3
4
  /** With `absolute` the prefix is set at the root of the entity (regardless of the nesting level) */
4
5
  export type EmbeddedPrefixMode = 'absolute' | 'relative';
5
- export interface EmbeddedOptions {
6
- entity?: string | (() => AnyEntity | AnyEntity[]);
7
- type?: string;
6
+ export interface EmbeddedOptions<Owner, Target> extends PropertyOptions<Owner> {
7
+ entity?: string | (() => EntityName<Target> | EntityName<Target>[]);
8
8
  prefix?: string | boolean;
9
9
  prefixMode?: EmbeddedPrefixMode;
10
- nullable?: boolean;
11
10
  object?: boolean;
12
11
  array?: boolean;
13
- hidden?: boolean;
14
- serializer?: (value: any) => any;
15
- serializedName?: string;
16
- groups?: string[];
17
- persist?: boolean;
18
12
  }
@@ -1,18 +1,33 @@
1
- import type { AnyString, Constructor, Dictionary, EntityClass, FilterQuery } from '../typings.js';
1
+ import type { AnyString, Constructor, Dictionary, EntityClass, ObjectQuery } from '../typings.js';
2
2
  import type { FindOptions } from '../drivers/IDatabaseDriver.js';
3
3
  export declare function Entity<T extends EntityClass<unknown>>(options?: EntityOptions<T>): (target: T) => void;
4
- export type EntityOptions<T> = {
4
+ export type EntityOptions<T, E = T extends EntityClass<infer P> ? P : T> = {
5
+ /** Override default collection/table name. Alias for `collection`. */
5
6
  tableName?: string;
7
+ /** Sets the schema name. */
6
8
  schema?: string;
9
+ /** Override default collection/table name. Alias for `tableName`. */
7
10
  collection?: string;
11
+ /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. */
8
12
  discriminatorColumn?: (T extends EntityClass<infer P> ? keyof P : string) | AnyString;
13
+ /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. */
9
14
  discriminatorMap?: Dictionary<string>;
15
+ /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. */
10
16
  discriminatorValue?: number | string;
17
+ /** Enforce use of constructor when creating managed entity instances. */
11
18
  forceConstructor?: boolean;
19
+ /** Specify comment to table. (SQL only) */
12
20
  comment?: string;
21
+ /** Marks entity as abstract, such entities are inlined during discovery. */
13
22
  abstract?: boolean;
23
+ /** Disables change tracking - such entities are ignored during flush. */
14
24
  readonly?: boolean;
25
+ /** Marks entity as {@doclink virtual-entities | virtual}. This is set automatically when you use `expression` option. */
15
26
  virtual?: boolean;
16
- expression?: string | ((em: any, where: FilterQuery<T>, options: FindOptions<T, any, any, any>) => object);
27
+ /** Used to make ORM aware of externally defined triggers. This is needed for MS SQL Server multi inserts, ignored in other dialects. */
28
+ hasTriggers?: boolean;
29
+ /** SQL query that maps to a {@doclink virtual-entities | virtual entity}. */
30
+ expression?: string | ((em: any, where: ObjectQuery<E>, options: FindOptions<E, any, any, any>, stream?: boolean) => object);
31
+ /** Set {@doclink repositories#custom-repository | custom repository class}. */
17
32
  repository?: () => Constructor;
18
33
  };
@@ -1,4 +1,4 @@
1
- import type { EntityClass, Dictionary, AutoPath } from '../typings.js';
1
+ import type { EntityClass, Dictionary, AutoPath, IndexCallback } from '../typings.js';
2
2
  import type { DeferMode } from '../enums.js';
3
3
  export declare function Index<T extends object, H extends string>(options?: IndexOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
4
4
  export declare function Unique<T extends object, H extends string>(options?: UniqueOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
@@ -8,7 +8,7 @@ interface BaseOptions<T, H extends string> {
8
8
  name?: string;
9
9
  properties?: (T extends EntityClass<infer P> ? Properties<P, H> : Properties<T, H>);
10
10
  options?: Dictionary;
11
- expression?: string;
11
+ expression?: string | (T extends EntityClass<infer P> ? IndexCallback<P> : IndexCallback<T>);
12
12
  }
13
13
  export interface UniqueOptions<T, H extends string = string> extends BaseOptions<T, H> {
14
14
  deferMode?: DeferMode | `${DeferMode}`;
@@ -37,4 +37,6 @@ export interface ManyToManyOptions<Owner, Target> extends ReferenceOptions<Owner
37
37
  deleteRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
38
38
  /** What to do when the reference to the target entity gets updated. */
39
39
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
40
+ /** Enable/disable foreign key constraint creation on this relation */
41
+ createForeignKeyConstraint?: boolean;
40
42
  }
@@ -27,4 +27,8 @@ export interface ManyToOneOptions<Owner, Target> extends ReferenceOptions<Owner,
27
27
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
28
28
  /** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
29
29
  deferMode?: DeferMode | `${DeferMode}`;
30
+ /** Enable/disable foreign key constraint creation on this relation */
31
+ createForeignKeyConstraint?: boolean;
32
+ /** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
33
+ foreignKeyName?: string;
30
34
  }
@@ -21,4 +21,8 @@ export interface OneToOneOptions<Owner, Target> extends Partial<Omit<OneToManyOp
21
21
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
22
22
  /** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
23
23
  deferMode?: DeferMode | `${DeferMode}`;
24
+ /** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
25
+ foreignKeyName?: string;
26
+ /** Enable/disable foreign key constraint creation on this relation */
27
+ createForeignKeyConstraint?: boolean;
24
28
  }
@@ -3,6 +3,7 @@ import type { EntityName, Constructor, CheckCallback, GeneratedColumnCallback, A
3
3
  import type { Type, types } from '../types/index.js';
4
4
  import type { EntityManager } from '../EntityManager.js';
5
5
  import type { SerializeOptions } from '../serialization/EntitySerializer.js';
6
+ import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
6
7
  export declare function Property<T extends object>(options?: PropertyOptions<T>): (target: T, propertyName: string) => any;
7
8
  export interface PropertyOptions<Owner> {
8
9
  /**
@@ -112,12 +113,6 @@ export interface PropertyOptions<Owner> {
112
113
  * Enable `ScalarReference` wrapper for lazy values. Use this in combination with `lazy: true` to have a type-safe accessor object in place of the value.
113
114
  */
114
115
  ref?: boolean;
115
- /**
116
- * Set false to disable change tracking on a property level.
117
- *
118
- * @see https://mikro-orm.io/docs/unit-of-work#change-tracking-and-performance-considerations
119
- */
120
- trackChanges?: boolean;
121
116
  /**
122
117
  * Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
123
118
  */
@@ -161,7 +156,7 @@ export interface PropertyOptions<Owner> {
161
156
  * Set true to define the properties as setter. (virtual)
162
157
  *
163
158
  * @example
164
- * ```
159
+ * ```ts
165
160
  * @Property({ setter: true })
166
161
  * set address(value: string) {
167
162
  * this._address = value.toLocaleLowerCase();
@@ -173,7 +168,7 @@ export interface PropertyOptions<Owner> {
173
168
  * Set true to define the properties as getter. (virtual)
174
169
  *
175
170
  * @example
176
- * ```
171
+ * ```ts
177
172
  * @Property({ getter: true })
178
173
  * get fullName() {
179
174
  * return this.firstName + this.lastName;
@@ -186,7 +181,7 @@ export interface PropertyOptions<Owner> {
186
181
  * to the method name.
187
182
  *
188
183
  * @example
189
- * ```
184
+ * ```ts
190
185
  * @Property({ getter: true })
191
186
  * getFullName() {
192
187
  * return this.firstName + this.lastName;
@@ -194,6 +189,53 @@ export interface PropertyOptions<Owner> {
194
189
  * ```
195
190
  */
196
191
  getterName?: keyof Owner;
192
+ /**
193
+ * When using a private property backed by a public get/set pair, use the `accessor` option to point to the other side.
194
+ *
195
+ * > The `fieldName` will be inferred based on the accessor name unless specified explicitly.
196
+ *
197
+ * If the `accessor` option points to something, the ORM will use the backing property directly.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * @Entity()
202
+ * export class User {
203
+ * // the ORM will use the backing field directly
204
+ * @Property({ accessor: 'email' })
205
+ * private _email: string;
206
+ *
207
+ * get email() {
208
+ * return this._email;
209
+ * }
210
+ *
211
+ * set email() {
212
+ * return this._email;
213
+ * }
214
+ * }
215
+ *```
216
+ *
217
+ * If you want to the ORM to use your accessor internally too, use `accessor: true` on the get/set property instead.
218
+ * This is handy if you want to use a native private property for the backing field.
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * @Entity({ forceConstructor: true })
223
+ * export class User {
224
+ * #email: string;
225
+ *
226
+ * // the ORM will use the accessor internally
227
+ * @Property({ accessor: true })
228
+ * get email() {
229
+ * return this.#email;
230
+ * }
231
+ *
232
+ * set email() {
233
+ * return this.#email;
234
+ * }
235
+ * }
236
+ * ```
237
+ */
238
+ accessor?: keyof Owner | AnyString | boolean;
197
239
  /**
198
240
  * Set to define serialized primary key for MongoDB. (virtual)
199
241
  * Alias for `@SerializedPrimaryKey()` decorator.
@@ -242,6 +284,8 @@ export interface ReferenceOptions<Owner, Target> extends PropertyOptions<Owner>
242
284
  eager?: boolean;
243
285
  /** Override the default loading strategy for this property. This option has precedence over the global `loadStrategy`, but can be overridden by `FindOptions.strategy`. */
244
286
  strategy?: LoadStrategy | `${LoadStrategy}`;
287
+ /** Control filter parameters for the relation. This will serve as a default value when processing filters on this relation. It's value can be overridden via `em.fork()` or `FindOptions`. */
288
+ filters?: FilterOptions;
245
289
  }
246
290
  /**
247
291
  * Inspired by https://github.com/typeorm/typeorm/blob/941b584ba135617e55d6685caef671172ec1dc03/src/driver/types/ColumnTypes.ts
@@ -2,6 +2,7 @@ import type { TransactionOptions } from '../enums.js';
2
2
  import type { ContextProvider } from '../typings.js';
3
3
  type TransactionalOptions<T> = TransactionOptions & {
4
4
  context?: ContextProvider<T>;
5
+ contextName?: string;
5
6
  };
6
7
  /**
7
8
  * This decorator wraps the method with `em.transactional()`, so you can provide `TransactionOptions` just like with `em.transactional()`.
@@ -14,10 +14,10 @@ export function Transactional(options = {}) {
14
14
  throw new Error('@Transactional() should be use with async functions');
15
15
  }
16
16
  descriptor.value = async function (...args) {
17
- const { context, ...txOptions } = options;
17
+ const { context, contextName, ...txOptions } = options;
18
18
  const em = (await resolveContextProvider(this, context))
19
- || TransactionContext.getEntityManager()
20
- || RequestContext.getEntityManager();
19
+ || TransactionContext.getEntityManager(contextName)
20
+ || RequestContext.getEntityManager(contextName);
21
21
  if (!em) {
22
22
  throw new Error(`@Transactional() decorator can only be applied to methods of classes with \`orm: MikroORM\` property, \`em: EntityManager\` property, or with a callback parameter like \`@Transactional(() => orm)\` that returns one of those types. The parameter will contain a reference to current \`this\`. Returning an EntityRepository from it is also supported.`);
23
23
  }
@@ -3,7 +3,7 @@ export * from './Entity.js';
3
3
  export * from './OneToOne.js';
4
4
  export * from './ManyToOne.js';
5
5
  export * from './ManyToMany.js';
6
- export { OneToMany, OneToManyOptions } from './OneToMany.js';
6
+ export { OneToMany, type OneToManyOptions } from './OneToMany.js';
7
7
  export * from './Property.js';
8
8
  export * from './Check.js';
9
9
  export * from './Enum.js';