@mikro-orm/core 7.1.0-dev.25 → 7.1.0-dev.27

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.1.0-dev.25",
3
+ "version": "7.1.0-dev.27",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
package/typings.d.ts CHANGED
@@ -985,6 +985,11 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
985
985
  export interface CreateSchemaOptions {
986
986
  wrap?: boolean;
987
987
  schema?: string;
988
+ /**
989
+ * When true, entities with a wildcard schema (`schema: '*'`) are included in the generated DDL.
990
+ * Without this, wildcard tables are skipped.
991
+ */
992
+ includeWildcardSchema?: boolean;
988
993
  }
989
994
  /** Options for `ISchemaGenerator.clear()` to truncate/clear database tables. */
990
995
  export interface ClearDatabaseOptions {
@@ -1014,6 +1019,13 @@ export interface UpdateSchemaOptions<DatabaseSchema = unknown> {
1014
1019
  dropTables?: boolean;
1015
1020
  schema?: string;
1016
1021
  fromSchema?: DatabaseSchema;
1022
+ /**
1023
+ * When true, entities with a wildcard schema (`schema: '*'`) are included in the diff so migrations
1024
+ * can be generated for them. The emitted SQL is unqualified — and therefore safe to apply against
1025
+ * any schema at runtime — only when neither `options.schema` nor `config.schema` is set; otherwise
1026
+ * wildcard tables inherit that schema qualifier.
1027
+ */
1028
+ includeWildcardSchema?: boolean;
1017
1029
  }
1018
1030
  /** Options for `ISchemaGenerator.refresh()` which drops and recreates the schema. */
1019
1031
  export interface RefreshDatabaseOptions extends CreateSchemaOptions {
@@ -1094,6 +1106,12 @@ export type MigrateOptions = {
1094
1106
  to?: string | number;
1095
1107
  migrations?: string[];
1096
1108
  transaction?: Transaction;
1109
+ /**
1110
+ * Target schema to run migrations against. Issues a driver-specific "set current schema"
1111
+ * statement (e.g. `SET search_path` on PostgreSQL) before each migration, and places the
1112
+ * tracking table in this schema. Overrides `migrations.schema` from config. Not supported on MSSQL.
1113
+ */
1114
+ schema?: string;
1097
1115
  };
1098
1116
  /** Result of creating a new migration file, including the generated code and schema diff. */
1099
1117
  export type MigrationResult = {
@@ -1114,6 +1132,8 @@ export interface IMigrationRunner {
1114
1132
  run(migration: Migration, method: 'up' | 'down'): Promise<void>;
1115
1133
  setMasterMigration(trx: Transaction): void;
1116
1134
  unsetMasterMigration(): void;
1135
+ setRunSchema?(schema?: string): void;
1136
+ unsetRunSchema?(): void;
1117
1137
  }
1118
1138
  /**
1119
1139
  * @internal
@@ -1126,6 +1146,8 @@ export interface IMigratorStorage {
1126
1146
  ensureTable?(): Promise<void>;
1127
1147
  setMasterMigration(trx: Transaction): void;
1128
1148
  unsetMasterMigration(): void;
1149
+ setRunSchema?(schema?: string): void;
1150
+ unsetRunSchema?(): void;
1129
1151
  getMigrationName(name: string): string;
1130
1152
  getTableName?(): {
1131
1153
  schemaName?: string;
@@ -1152,11 +1174,15 @@ export interface IMigrator {
1152
1174
  /**
1153
1175
  * Returns list of already executed migrations.
1154
1176
  */
1155
- getExecuted(): Promise<MigrationRow[]>;
1177
+ getExecuted(options?: {
1178
+ schema?: string;
1179
+ }): Promise<MigrationRow[]>;
1156
1180
  /**
1157
1181
  * Returns list of pending (not yet executed) migrations found in the migration directory.
1158
1182
  */
1159
- getPending(): Promise<MigrationInfo[]>;
1183
+ getPending(options?: {
1184
+ schema?: string;
1185
+ }): Promise<MigrationInfo[]>;
1160
1186
  /**
1161
1187
  * Executes specified migrations. Without parameter it will migrate up to the latest version.
1162
1188
  */
@@ -13,6 +13,7 @@ type MigrateOptions = {
13
13
  to?: string | number;
14
14
  migrations?: string[];
15
15
  transaction?: Transaction;
16
+ schema?: string;
16
17
  };
17
18
  export declare abstract class AbstractMigrator<D extends IDatabaseDriver> implements IMigrator {
18
19
  #private;
@@ -57,11 +58,15 @@ export declare abstract class AbstractMigrator<D extends IDatabaseDriver> implem
57
58
  /**
58
59
  * @inheritDoc
59
60
  */
60
- getExecuted(): Promise<MigrationRow[]>;
61
+ getExecuted(options?: {
62
+ schema?: string;
63
+ }): Promise<MigrationRow[]>;
61
64
  /**
62
65
  * @inheritDoc
63
66
  */
64
- getPending(): Promise<MigrationInfo[]>;
67
+ getPending(options?: {
68
+ schema?: string;
69
+ }): Promise<MigrationInfo[]>;
65
70
  /**
66
71
  * @inheritDoc
67
72
  */
@@ -38,18 +38,32 @@ export class AbstractMigrator {
38
38
  /**
39
39
  * @inheritDoc
40
40
  */
41
- async getExecuted() {
41
+ async getExecuted(options) {
42
42
  await this.init();
43
- return this.storage.getExecutedMigrations();
43
+ const schema = options?.schema ?? this.options.schema;
44
+ this.storage.setRunSchema?.(schema);
45
+ try {
46
+ return await this.storage.getExecutedMigrations();
47
+ }
48
+ finally {
49
+ this.storage.unsetRunSchema?.();
50
+ }
44
51
  }
45
52
  /**
46
53
  * @inheritDoc
47
54
  */
48
- async getPending() {
55
+ async getPending(options) {
49
56
  await this.init();
50
- const all = await this.discoverMigrations();
51
- const executed = new Set(await this.storage.executed());
52
- return all.filter(m => !executed.has(m.name)).map(m => ({ name: m.name, path: m.path }));
57
+ const schema = options?.schema ?? this.options.schema;
58
+ this.storage.setRunSchema?.(schema);
59
+ try {
60
+ const all = await this.discoverMigrations();
61
+ const executed = new Set(await this.storage.executed());
62
+ return all.filter(m => !executed.has(m.name)).map(m => ({ name: m.name, path: m.path }));
63
+ }
64
+ finally {
65
+ this.storage.unsetRunSchema?.();
66
+ }
53
67
  }
54
68
  /**
55
69
  * @inheritDoc
@@ -487,13 +501,17 @@ export class AbstractMigrator {
487
501
  return /^\d{14}$/.exec(name) ? this.options.fileName(name) : name;
488
502
  }
489
503
  prefix(options) {
504
+ const base = {};
505
+ if (this.options.schema) {
506
+ base.schema = this.options.schema;
507
+ }
490
508
  if (typeof options === 'string' || Array.isArray(options)) {
491
- return { migrations: Utils.asArray(options).map(name => this.getMigrationFilename(name)) };
509
+ return { ...base, migrations: Utils.asArray(options).map(name => this.getMigrationFilename(name)) };
492
510
  }
493
511
  if (!options) {
494
- return {};
512
+ return base;
495
513
  }
496
- const result = {};
514
+ const result = base;
497
515
  if (options.migrations) {
498
516
  result.migrations = options.migrations.map(name => this.getMigrationFilename(name));
499
517
  }
@@ -506,23 +524,35 @@ export class AbstractMigrator {
506
524
  else if (options.to === 0) {
507
525
  result.to = 0;
508
526
  }
527
+ if (options.schema !== undefined) {
528
+ result.schema = options.schema;
529
+ }
509
530
  return result;
510
531
  }
511
532
  async runMigrations(method, options) {
512
533
  await this.init();
513
- if (!this.options.transactional || !this.options.allOrNothing) {
514
- return this.executeMigrations(method, this.prefix(options));
534
+ const normalized = this.prefix(options);
535
+ this.runner.setRunSchema?.(normalized.schema);
536
+ this.storage.setRunSchema?.(normalized.schema);
537
+ try {
538
+ if (!this.options.transactional || !this.options.allOrNothing) {
539
+ return await this.executeMigrations(method, normalized);
540
+ }
541
+ if (Utils.isObject(options) && options.transaction) {
542
+ return await this.runInTransaction(options.transaction, method, normalized);
543
+ }
544
+ return await this.driver.getConnection().transactional(trx => this.runInTransaction(trx, method, normalized));
515
545
  }
516
- if (Utils.isObject(options) && options.transaction) {
517
- return this.runInTransaction(options.transaction, method, options);
546
+ finally {
547
+ this.runner.unsetRunSchema?.();
548
+ this.storage.unsetRunSchema?.();
518
549
  }
519
- return this.driver.getConnection().transactional(trx => this.runInTransaction(trx, method, options));
520
550
  }
521
551
  async runInTransaction(trx, method, options) {
522
552
  this.runner.setMasterMigration(trx);
523
553
  this.storage.setMasterMigration(trx);
524
554
  try {
525
- return await this.executeMigrations(method, this.prefix(options));
555
+ return await this.executeMigrations(method, options);
526
556
  }
527
557
  finally {
528
558
  this.runner.unsetMasterMigration();
@@ -34,6 +34,6 @@ export declare abstract class AbstractSchemaGenerator<D extends IDatabaseDriver>
34
34
  dropDatabase(name?: string): Promise<void>;
35
35
  execute(query: string): Promise<void>;
36
36
  ensureIndexes(): Promise<void>;
37
- protected getOrderedMetadata(schema?: string): EntityMetadata[];
37
+ protected getOrderedMetadata(schema?: string, includeWildcardSchema?: boolean): EntityMetadata[];
38
38
  protected notImplemented(): never;
39
39
  }
@@ -89,7 +89,7 @@ export class AbstractSchemaGenerator {
89
89
  async ensureIndexes() {
90
90
  this.notImplemented();
91
91
  }
92
- getOrderedMetadata(schema) {
92
+ getOrderedMetadata(schema, includeWildcardSchema = false) {
93
93
  const metadata = [...this.metadata.getAll().values()].filter(meta => {
94
94
  const isRootEntity = meta.root.class === meta.class;
95
95
  const isTPTChild = meta.inheritanceType === 'tpt' && meta.tptParent;
@@ -116,6 +116,9 @@ export class AbstractSchemaGenerator {
116
116
  .sort()
117
117
  .map(cls => this.metadata.getById(cls))
118
118
  .filter(meta => {
119
+ if (includeWildcardSchema && meta.schema === '*') {
120
+ return true;
121
+ }
119
122
  const targetSchema = meta.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
120
123
  return schema ? [schema, '*'].includes(targetSchema) : meta.schema !== '*';
121
124
  });
@@ -238,6 +238,24 @@ export type MigrationsOptions = {
238
238
  fileName?: (timestamp: string, name?: string) => string;
239
239
  /** List of migration classes or objects to use instead of file-based discovery. */
240
240
  migrationsList?: (MigrationObject | Constructor<Migration>)[];
241
+ /**
242
+ * Target schema used when running migrations. When set, the driver's "set current schema" statement
243
+ * (e.g. `SET search_path` on PostgreSQL) is issued before each migration, and the migration tracking
244
+ * table lives in this schema. Can be overridden per call via `migrator.up({ schema })`.
245
+ *
246
+ * Intended for per-deployment-one-schema setups (e.g. PR previews) and for applying a single
247
+ * unqualified migration to multiple schemas (see `includeWildcardSchema`). Not supported on MSSQL.
248
+ */
249
+ schema?: string;
250
+ /**
251
+ * When set, entities with a wildcard schema (`schema: '*'`) are included in generated migrations.
252
+ * The emitted SQL is unqualified — and therefore safe to apply against any schema at runtime via
253
+ * `migrator.up({ schema })` — only when neither `options.schema` nor the ORM's `config.schema`
254
+ * is set. If `config.schema` is set, wildcard tables are qualified with it (useful for local
255
+ * dev runs); in that case, generate migrations from an environment where `config.schema` is unset.
256
+ * @default false
257
+ */
258
+ includeWildcardSchema?: boolean;
241
259
  };
242
260
  /**
243
261
  * Configuration options for database seeders.
package/utils/Utils.js CHANGED
@@ -141,7 +141,7 @@ export function parseJsonSafe(value) {
141
141
  /** Collection of general-purpose utility methods used throughout the ORM. */
142
142
  export class Utils {
143
143
  static PK_SEPARATOR = '~~~';
144
- static #ORM_VERSION = '7.1.0-dev.25';
144
+ static #ORM_VERSION = '7.1.0-dev.27';
145
145
  /**
146
146
  * Checks if the argument is instance of `Object`. Returns false for arrays.
147
147
  */