@mikro-orm/core 7.0.0-dev.260 → 7.0.0-dev.261
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/EntityManager.js +1 -1
- package/index.d.ts +1 -1
- package/package.json +5 -2
- package/typings.d.ts +18 -6
- package/utils/AbstractMigrator.d.ts +101 -0
- package/utils/AbstractMigrator.js +305 -0
- package/utils/Utils.js +1 -1
- package/utils/fs-utils.d.ts +1 -0
- package/utils/fs-utils.js +4 -0
- package/utils/index.d.ts +0 -2
- package/utils/index.js +0 -2
package/EntityManager.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { getOnConflictReturningFields, getWhereCondition } from './utils/upsert-utils.js';
|
|
2
2
|
import { Utils } from './utils/Utils.js';
|
|
3
3
|
import { Cursor } from './utils/Cursor.js';
|
|
4
|
-
import { DataloaderUtils } from './utils/DataloaderUtils.js';
|
|
5
4
|
import { QueryHelper } from './utils/QueryHelper.js';
|
|
6
5
|
import { TransactionContext } from './utils/TransactionContext.js';
|
|
7
6
|
import { isRaw, Raw } from './utils/RawQueryFragment.js';
|
|
@@ -1816,6 +1815,7 @@ export class EntityManager {
|
|
|
1816
1815
|
if (em.loaders[type]) {
|
|
1817
1816
|
return em.loaders[type];
|
|
1818
1817
|
}
|
|
1818
|
+
const { DataloaderUtils } = await import('@mikro-orm/core/dataloader');
|
|
1819
1819
|
const DataLoader = await DataloaderUtils.getDataLoader();
|
|
1820
1820
|
switch (type) {
|
|
1821
1821
|
case 'ref': return (em.loaders[type] ??= new DataLoader(DataloaderUtils.getRefBatchLoadFn(em)));
|
package/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module core
|
|
4
4
|
*/
|
|
5
5
|
export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName } from './typings.js';
|
|
6
|
-
export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IEntityGenerator, ISeedManager, RequiredEntityData, CheckCallback, IndexCallback, FormulaCallback, FormulaTable, SchemaTable, SchemaColumns, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator,
|
|
6
|
+
export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IMigrationRunner, IEntityGenerator, ISeedManager, IMigratorStorage, RequiredEntityData, CheckCallback, IndexCallback, FormulaCallback, FormulaTable, SchemaTable, SchemaColumns, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
|
|
7
7
|
export * from './enums.js';
|
|
8
8
|
export * from './errors.js';
|
|
9
9
|
export * from './exceptions.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-dev.
|
|
4
|
+
"version": "7.0.0-dev.261",
|
|
5
5
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./package.json": "./package.json",
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
"./fs-utils": {
|
|
14
14
|
"node": "./utils/fs-utils.js",
|
|
15
15
|
"browser": "./not-supported.js"
|
|
16
|
-
}
|
|
16
|
+
},
|
|
17
|
+
"./migrations": "./utils/AbstractMigrator.js",
|
|
18
|
+
"./schema": "./utils/AbstractSchemaGenerator.js",
|
|
19
|
+
"./dataloader": "./utils/DataloaderUtils.js"
|
|
17
20
|
},
|
|
18
21
|
"repository": {
|
|
19
22
|
"type": "git",
|
package/typings.d.ts
CHANGED
|
@@ -818,7 +818,7 @@ export interface GenerateOptions {
|
|
|
818
818
|
export interface IEntityGenerator {
|
|
819
819
|
generate(options?: GenerateOptions): Promise<string[]>;
|
|
820
820
|
}
|
|
821
|
-
export type
|
|
821
|
+
export type MigrationInfo = {
|
|
822
822
|
name: string;
|
|
823
823
|
path?: string;
|
|
824
824
|
};
|
|
@@ -838,6 +838,14 @@ export type MigrationRow = {
|
|
|
838
838
|
name: string;
|
|
839
839
|
executed_at: Date;
|
|
840
840
|
};
|
|
841
|
+
/**
|
|
842
|
+
* @internal
|
|
843
|
+
*/
|
|
844
|
+
export interface IMigrationRunner {
|
|
845
|
+
run(migration: Migration, method: 'up' | 'down'): Promise<void>;
|
|
846
|
+
setMasterMigration(trx: Transaction): void;
|
|
847
|
+
unsetMasterMigration(): void;
|
|
848
|
+
}
|
|
841
849
|
/**
|
|
842
850
|
* @internal
|
|
843
851
|
*/
|
|
@@ -878,23 +886,23 @@ export interface IMigrator {
|
|
|
878
886
|
/**
|
|
879
887
|
* Returns list of pending (not yet executed) migrations found in the migration directory.
|
|
880
888
|
*/
|
|
881
|
-
getPending(): Promise<
|
|
889
|
+
getPending(): Promise<MigrationInfo[]>;
|
|
882
890
|
/**
|
|
883
891
|
* Executes specified migrations. Without parameter it will migrate up to the latest version.
|
|
884
892
|
*/
|
|
885
|
-
up(options?: string | string[] | MigrateOptions): Promise<
|
|
893
|
+
up(options?: string | string[] | MigrateOptions): Promise<MigrationInfo[]>;
|
|
886
894
|
/**
|
|
887
895
|
* Executes down migrations to the given point. Without parameter it will migrate one version down.
|
|
888
896
|
*/
|
|
889
|
-
down(options?: string | string[] | MigrateOptions): Promise<
|
|
897
|
+
down(options?: string | string[] | Omit<MigrateOptions, 'from'>): Promise<MigrationInfo[]>;
|
|
890
898
|
/**
|
|
891
899
|
* Registers event handler.
|
|
892
900
|
*/
|
|
893
|
-
on(event: MigratorEvent, listener: (event:
|
|
901
|
+
on(event: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise<void>): IMigrator;
|
|
894
902
|
/**
|
|
895
903
|
* Removes event handler.
|
|
896
904
|
*/
|
|
897
|
-
off(event: MigratorEvent, listener: (event:
|
|
905
|
+
off(event: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise<void>): IMigrator;
|
|
898
906
|
/**
|
|
899
907
|
* @internal
|
|
900
908
|
*/
|
|
@@ -922,6 +930,10 @@ export interface IMigrationGenerator {
|
|
|
922
930
|
export interface Migration {
|
|
923
931
|
up(): Promise<void> | void;
|
|
924
932
|
down(): Promise<void> | void;
|
|
933
|
+
isTransactional(): boolean;
|
|
934
|
+
reset(): void;
|
|
935
|
+
setTransactionContext(ctx: Transaction): void;
|
|
936
|
+
getQueries?(): any[];
|
|
925
937
|
}
|
|
926
938
|
export interface MigrationObject {
|
|
927
939
|
name: string;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { Constructor, IMigrationGenerator, IMigrationRunner, IMigrator, IMigratorStorage, MaybePromise, Migration, MigrationInfo, MigrationRow, MigratorEvent } from '../typings.js';
|
|
2
|
+
import type { Transaction } from '../connections/Connection.js';
|
|
3
|
+
import type { Configuration, MigrationsOptions } from './Configuration.js';
|
|
4
|
+
import type { EntityManagerType, IDatabaseDriver } from '../drivers/IDatabaseDriver.js';
|
|
5
|
+
interface RunnableMigration {
|
|
6
|
+
name: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
up: () => MaybePromise<void>;
|
|
9
|
+
down: () => MaybePromise<void>;
|
|
10
|
+
}
|
|
11
|
+
type MigrateOptions = {
|
|
12
|
+
from?: string | number;
|
|
13
|
+
to?: string | number;
|
|
14
|
+
migrations?: string[];
|
|
15
|
+
transaction?: Transaction;
|
|
16
|
+
};
|
|
17
|
+
export declare abstract class AbstractMigrator<D extends IDatabaseDriver> implements IMigrator {
|
|
18
|
+
protected readonly em: D[typeof EntityManagerType];
|
|
19
|
+
protected runner: IMigrationRunner;
|
|
20
|
+
protected storage: IMigratorStorage;
|
|
21
|
+
protected generator: IMigrationGenerator;
|
|
22
|
+
protected readonly driver: D;
|
|
23
|
+
protected readonly config: Configuration;
|
|
24
|
+
protected readonly options: MigrationsOptions;
|
|
25
|
+
protected absolutePath: string;
|
|
26
|
+
protected initialized: boolean;
|
|
27
|
+
private readonly listeners;
|
|
28
|
+
constructor(em: D[typeof EntityManagerType]);
|
|
29
|
+
protected abstract createRunner(): IMigrationRunner;
|
|
30
|
+
protected abstract createStorage(): IMigratorStorage;
|
|
31
|
+
protected abstract getDefaultGenerator(): IMigrationGenerator;
|
|
32
|
+
abstract create(path?: string, blank?: boolean, initial?: boolean, name?: string): Promise<{
|
|
33
|
+
fileName: string;
|
|
34
|
+
code: string;
|
|
35
|
+
diff: {
|
|
36
|
+
up: string[];
|
|
37
|
+
down: string[];
|
|
38
|
+
};
|
|
39
|
+
}>;
|
|
40
|
+
abstract checkSchema(): Promise<boolean>;
|
|
41
|
+
abstract createInitial(path?: string, name?: string, blank?: boolean): Promise<{
|
|
42
|
+
fileName: string;
|
|
43
|
+
code: string;
|
|
44
|
+
diff: {
|
|
45
|
+
up: string[];
|
|
46
|
+
down: string[];
|
|
47
|
+
};
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* @inheritDoc
|
|
51
|
+
*/
|
|
52
|
+
on(eventName: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise<void>): this;
|
|
53
|
+
/**
|
|
54
|
+
* @inheritDoc
|
|
55
|
+
*/
|
|
56
|
+
off(eventName: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise<void>): this;
|
|
57
|
+
/**
|
|
58
|
+
* @inheritDoc
|
|
59
|
+
*/
|
|
60
|
+
getExecuted(): Promise<MigrationRow[]>;
|
|
61
|
+
/**
|
|
62
|
+
* @inheritDoc
|
|
63
|
+
*/
|
|
64
|
+
getPending(): Promise<MigrationInfo[]>;
|
|
65
|
+
/**
|
|
66
|
+
* @inheritDoc
|
|
67
|
+
*/
|
|
68
|
+
up(options?: string | string[] | MigrateOptions): Promise<MigrationInfo[]>;
|
|
69
|
+
/**
|
|
70
|
+
* @inheritDoc
|
|
71
|
+
*/
|
|
72
|
+
down(options?: string | string[] | Omit<MigrateOptions, 'from'>): Promise<MigrationInfo[]>;
|
|
73
|
+
abstract getStorage(): IMigratorStorage;
|
|
74
|
+
protected init(): Promise<void>;
|
|
75
|
+
protected initServices(): void;
|
|
76
|
+
protected resolve(params: {
|
|
77
|
+
name: string;
|
|
78
|
+
path: string;
|
|
79
|
+
}): RunnableMigration;
|
|
80
|
+
protected initialize(MigrationClass: Constructor<Migration>, name: string): RunnableMigration;
|
|
81
|
+
/**
|
|
82
|
+
* Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
|
|
83
|
+
* If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
|
|
84
|
+
* used for the TS variant (`pathTs` option).
|
|
85
|
+
*
|
|
86
|
+
* If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
|
|
87
|
+
* break existing projects, only help with the new ones.
|
|
88
|
+
*/
|
|
89
|
+
private detectSourceFolder;
|
|
90
|
+
private registerDefaultListeners;
|
|
91
|
+
private emit;
|
|
92
|
+
private discoverMigrations;
|
|
93
|
+
private executeMigrations;
|
|
94
|
+
private filterUp;
|
|
95
|
+
private filterDown;
|
|
96
|
+
private getMigrationFilename;
|
|
97
|
+
private prefix;
|
|
98
|
+
private runMigrations;
|
|
99
|
+
private runInTransaction;
|
|
100
|
+
}
|
|
101
|
+
export {};
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { Utils } from './Utils.js';
|
|
2
|
+
export class AbstractMigrator {
|
|
3
|
+
em;
|
|
4
|
+
runner;
|
|
5
|
+
storage;
|
|
6
|
+
generator;
|
|
7
|
+
driver;
|
|
8
|
+
config;
|
|
9
|
+
options;
|
|
10
|
+
absolutePath;
|
|
11
|
+
initialized = false;
|
|
12
|
+
listeners = new Map();
|
|
13
|
+
constructor(em) {
|
|
14
|
+
this.em = em;
|
|
15
|
+
this.driver = this.em.getDriver();
|
|
16
|
+
this.config = this.em.config;
|
|
17
|
+
this.options = this.config.get('migrations');
|
|
18
|
+
this.initServices();
|
|
19
|
+
this.registerDefaultListeners();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* @inheritDoc
|
|
23
|
+
*/
|
|
24
|
+
on(eventName, listener) {
|
|
25
|
+
if (!this.listeners.has(eventName)) {
|
|
26
|
+
this.listeners.set(eventName, new Set());
|
|
27
|
+
}
|
|
28
|
+
this.listeners.get(eventName).add(listener);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
off(eventName, listener) {
|
|
35
|
+
this.listeners.get(eventName)?.delete(listener);
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @inheritDoc
|
|
40
|
+
*/
|
|
41
|
+
async getExecuted() {
|
|
42
|
+
await this.init();
|
|
43
|
+
return this.storage.getExecutedMigrations();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @inheritDoc
|
|
47
|
+
*/
|
|
48
|
+
async getPending() {
|
|
49
|
+
await this.init();
|
|
50
|
+
const all = await this.discoverMigrations();
|
|
51
|
+
const executed = new Set(await this.storage.executed());
|
|
52
|
+
return all
|
|
53
|
+
.filter(m => !executed.has(m.name))
|
|
54
|
+
.map(m => ({ name: m.name, path: m.path }));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @inheritDoc
|
|
58
|
+
*/
|
|
59
|
+
async up(options) {
|
|
60
|
+
return this.runMigrations('up', options);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @inheritDoc
|
|
64
|
+
*/
|
|
65
|
+
async down(options) {
|
|
66
|
+
return this.runMigrations('down', options);
|
|
67
|
+
}
|
|
68
|
+
async init() {
|
|
69
|
+
if (this.initialized) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.initialized = true;
|
|
73
|
+
if (!this.options.migrationsList) {
|
|
74
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
75
|
+
this.detectSourceFolder(fs);
|
|
76
|
+
/* v8 ignore next */
|
|
77
|
+
const key = (this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.options.pathTs) ? 'pathTs' : 'path';
|
|
78
|
+
this.absolutePath = fs.absolutePath(this.options[key], this.config.get('baseDir'));
|
|
79
|
+
fs.ensureDir(this.absolutePath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
initServices() {
|
|
83
|
+
this.runner = this.createRunner();
|
|
84
|
+
this.storage = this.createStorage();
|
|
85
|
+
if (this.options.generator) {
|
|
86
|
+
this.generator = new this.options.generator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.generator = this.getDefaultGenerator();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
resolve(params) {
|
|
93
|
+
const createMigrationHandler = async (method) => {
|
|
94
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
95
|
+
const migration = await fs.dynamicImport(params.path);
|
|
96
|
+
const MigrationClass = Object.values(migration).find(cls => typeof cls === 'function' && typeof cls.constructor === 'function');
|
|
97
|
+
const instance = new MigrationClass(this.driver, this.config);
|
|
98
|
+
await this.runner.run(instance, method);
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
name: this.storage.getMigrationName(params.name),
|
|
102
|
+
path: params.path,
|
|
103
|
+
up: () => createMigrationHandler('up'),
|
|
104
|
+
down: () => createMigrationHandler('down'),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
initialize(MigrationClass, name) {
|
|
108
|
+
const instance = new MigrationClass(this.driver, this.config);
|
|
109
|
+
return {
|
|
110
|
+
name: this.storage.getMigrationName(name),
|
|
111
|
+
up: () => this.runner.run(instance, 'up'),
|
|
112
|
+
down: () => this.runner.run(instance, 'down'),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
|
|
117
|
+
* If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
|
|
118
|
+
* used for the TS variant (`pathTs` option).
|
|
119
|
+
*
|
|
120
|
+
* If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
|
|
121
|
+
* break existing projects, only help with the new ones.
|
|
122
|
+
*/
|
|
123
|
+
detectSourceFolder(fs) {
|
|
124
|
+
const baseDir = this.config.get('baseDir');
|
|
125
|
+
const defaultPath = './migrations';
|
|
126
|
+
if (!fs.pathExists(baseDir + '/src')) {
|
|
127
|
+
this.options.path ??= defaultPath;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const exists = fs.pathExists(`${baseDir}/${defaultPath}`);
|
|
131
|
+
const distDir = fs.pathExists(baseDir + '/dist');
|
|
132
|
+
const buildDir = fs.pathExists(baseDir + '/build');
|
|
133
|
+
// if neither `dist` nor `build` exist, we use the `src` folder as it might be a JS project without building, but with `src` folder
|
|
134
|
+
/* v8 ignore next */
|
|
135
|
+
const path = distDir ? './dist' : (buildDir ? './build' : './src');
|
|
136
|
+
// only if the user did not provide any values and if the default path does not exist
|
|
137
|
+
if (!this.options.path && !this.options.pathTs && !exists) {
|
|
138
|
+
this.options.path = `${path}/migrations`;
|
|
139
|
+
this.options.pathTs = './src/migrations';
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
registerDefaultListeners() {
|
|
143
|
+
/* v8 ignore else */
|
|
144
|
+
if (!this.options.silent) {
|
|
145
|
+
const logger = this.config.getLogger();
|
|
146
|
+
this.on('migrating', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
|
|
147
|
+
this.on('migrated', event => logger.log('migrator', `Applied '${event.name}'`, { enabled: true }));
|
|
148
|
+
this.on('reverting', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
|
|
149
|
+
this.on('reverted', event => logger.log('migrator', `Reverted '${event.name}'`, { enabled: true }));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async emit(event, data) {
|
|
153
|
+
for (const listener of this.listeners.get(event) ?? []) {
|
|
154
|
+
await listener(data);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async discoverMigrations() {
|
|
158
|
+
if (this.options.migrationsList) {
|
|
159
|
+
return this.options.migrationsList.map(migration => {
|
|
160
|
+
if (typeof migration === 'function') {
|
|
161
|
+
return this.initialize(migration, migration.name);
|
|
162
|
+
}
|
|
163
|
+
return this.initialize(migration.class, migration.name);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
167
|
+
const pattern = fs.normalizePath(this.absolutePath, this.options.glob);
|
|
168
|
+
const files = fs.glob(pattern).sort();
|
|
169
|
+
return files.map(filePath => this.resolve({
|
|
170
|
+
name: filePath.replace(/\\/g, '/').split('/').pop(),
|
|
171
|
+
path: filePath,
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
async executeMigrations(method, options = {}) {
|
|
175
|
+
const all = await this.discoverMigrations();
|
|
176
|
+
const executed = await this.storage.executed();
|
|
177
|
+
const executedSet = new Set(executed);
|
|
178
|
+
let toRun;
|
|
179
|
+
if (method === 'up') {
|
|
180
|
+
toRun = this.filterUp(all, executedSet, options);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
toRun = this.filterDown(all, executed, options);
|
|
184
|
+
}
|
|
185
|
+
const result = [];
|
|
186
|
+
const eventBefore = method === 'up' ? 'migrating' : 'reverting';
|
|
187
|
+
const eventAfter = method === 'up' ? 'migrated' : 'reverted';
|
|
188
|
+
for (const migration of toRun) {
|
|
189
|
+
const event = { name: migration.name, path: migration.path };
|
|
190
|
+
await this.emit(eventBefore, event);
|
|
191
|
+
await migration[method]();
|
|
192
|
+
if (method === 'up') {
|
|
193
|
+
await this.storage.logMigration({ name: migration.name });
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
await this.storage.unlogMigration({ name: migration.name });
|
|
197
|
+
}
|
|
198
|
+
await this.emit(eventAfter, event);
|
|
199
|
+
result.push(event);
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
filterUp(all, executed, options) {
|
|
204
|
+
let pending = all.filter(m => !executed.has(m.name));
|
|
205
|
+
if (options.migrations) {
|
|
206
|
+
const set = new Set(options.migrations);
|
|
207
|
+
return pending.filter(m => set.has(m.name));
|
|
208
|
+
}
|
|
209
|
+
if (options.from) {
|
|
210
|
+
const idx = all.findIndex(m => m.name === options.from);
|
|
211
|
+
if (idx >= 0) {
|
|
212
|
+
const names = new Set(all.slice(idx + 1).map(m => m.name));
|
|
213
|
+
pending = pending.filter(m => names.has(m.name));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (options.to && typeof options.to === 'string') {
|
|
217
|
+
const idx = all.findIndex(m => m.name === options.to);
|
|
218
|
+
if (idx >= 0) {
|
|
219
|
+
const names = new Set(all.slice(0, idx + 1).map(m => m.name));
|
|
220
|
+
pending = pending.filter(m => names.has(m.name));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return pending;
|
|
224
|
+
}
|
|
225
|
+
filterDown(all, executed, options) {
|
|
226
|
+
const migrationMap = new Map(all.map(m => [m.name, m]));
|
|
227
|
+
const executedReversed = [...executed].reverse();
|
|
228
|
+
if (options.migrations) {
|
|
229
|
+
const set = new Set(options.migrations);
|
|
230
|
+
return executedReversed
|
|
231
|
+
.filter(name => set.has(name))
|
|
232
|
+
.map(name => migrationMap.get(name))
|
|
233
|
+
.filter(Boolean);
|
|
234
|
+
}
|
|
235
|
+
if (options.to === 0) {
|
|
236
|
+
return executedReversed.map(name => migrationMap.get(name)).filter(Boolean);
|
|
237
|
+
}
|
|
238
|
+
if (options.to) {
|
|
239
|
+
const result = [];
|
|
240
|
+
for (const name of executedReversed) {
|
|
241
|
+
if (name === String(options.to)) {
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
const m = migrationMap.get(name);
|
|
245
|
+
if (m) {
|
|
246
|
+
result.push(m);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
// Default: revert last 1
|
|
252
|
+
if (executedReversed.length > 0) {
|
|
253
|
+
const m = migrationMap.get(executedReversed[0]);
|
|
254
|
+
return m ? [m] : [];
|
|
255
|
+
}
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
getMigrationFilename(name) {
|
|
259
|
+
name = name.replace(/\.[jt]s$/, '');
|
|
260
|
+
return name.match(/^\d{14}$/) ? this.options.fileName(name) : name;
|
|
261
|
+
}
|
|
262
|
+
prefix(options) {
|
|
263
|
+
if (typeof options === 'string' || Array.isArray(options)) {
|
|
264
|
+
return { migrations: Utils.asArray(options).map(name => this.getMigrationFilename(name)) };
|
|
265
|
+
}
|
|
266
|
+
if (!options) {
|
|
267
|
+
return {};
|
|
268
|
+
}
|
|
269
|
+
const result = {};
|
|
270
|
+
if (options.migrations) {
|
|
271
|
+
result.migrations = options.migrations.map(name => this.getMigrationFilename(name));
|
|
272
|
+
}
|
|
273
|
+
if (options.from) {
|
|
274
|
+
result.from = this.getMigrationFilename(String(options.from));
|
|
275
|
+
}
|
|
276
|
+
if (options.to && options.to !== 0) {
|
|
277
|
+
result.to = this.getMigrationFilename(String(options.to));
|
|
278
|
+
}
|
|
279
|
+
else if (options.to === 0) {
|
|
280
|
+
result.to = 0;
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
async runMigrations(method, options) {
|
|
285
|
+
await this.init();
|
|
286
|
+
if (!this.options.transactional || !this.options.allOrNothing) {
|
|
287
|
+
return this.executeMigrations(method, this.prefix(options));
|
|
288
|
+
}
|
|
289
|
+
if (Utils.isObject(options) && options.transaction) {
|
|
290
|
+
return this.runInTransaction(options.transaction, method, options);
|
|
291
|
+
}
|
|
292
|
+
return this.driver.getConnection().transactional(trx => this.runInTransaction(trx, method, options));
|
|
293
|
+
}
|
|
294
|
+
async runInTransaction(trx, method, options) {
|
|
295
|
+
this.runner.setMasterMigration(trx);
|
|
296
|
+
this.storage.setMasterMigration(trx);
|
|
297
|
+
try {
|
|
298
|
+
return await this.executeMigrations(method, this.prefix(options));
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
this.runner.unsetMasterMigration();
|
|
302
|
+
this.storage.unsetMasterMigration();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
package/utils/Utils.js
CHANGED
|
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
|
|
|
123
123
|
}
|
|
124
124
|
export class Utils {
|
|
125
125
|
static PK_SEPARATOR = '~~~';
|
|
126
|
-
static #ORM_VERSION = '7.0.0-dev.
|
|
126
|
+
static #ORM_VERSION = '7.0.0-dev.261';
|
|
127
127
|
/**
|
|
128
128
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
129
129
|
*/
|
package/utils/fs-utils.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare const fs: {
|
|
|
28
28
|
* If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
|
|
29
29
|
*/
|
|
30
30
|
absolutePath(path: string, baseDir?: string): string;
|
|
31
|
+
writeFile(path: string, data: string, options?: Record<string, any>): Promise<void>;
|
|
31
32
|
dynamicImport<T = any>(id: string): Promise<T>;
|
|
32
33
|
};
|
|
33
34
|
export * from '../cache/FileCacheAdapter.js';
|
package/utils/fs-utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync, globSync as nodeGlobSync, mkdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
2
|
+
import { writeFile as nodeWriteFile } from 'node:fs/promises';
|
|
2
3
|
import { isAbsolute, join, normalize, relative } from 'node:path';
|
|
3
4
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
5
|
import { Utils } from './Utils.js';
|
|
@@ -182,6 +183,9 @@ export const fs = {
|
|
|
182
183
|
}
|
|
183
184
|
return this.normalizePath(path);
|
|
184
185
|
},
|
|
186
|
+
async writeFile(path, data, options) {
|
|
187
|
+
await nodeWriteFile(path, data, options);
|
|
188
|
+
},
|
|
185
189
|
async dynamicImport(id) {
|
|
186
190
|
/* v8 ignore next */
|
|
187
191
|
const specifier = id.startsWith('file://') ? id : pathToFileURL(id).href;
|
package/utils/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './Configuration.js';
|
|
2
2
|
export * from './Cursor.js';
|
|
3
|
-
export * from './DataloaderUtils.js';
|
|
4
3
|
export * from './Utils.js';
|
|
5
4
|
export * from './RequestContext.js';
|
|
6
5
|
export * from './TransactionContext.js';
|
|
@@ -8,7 +7,6 @@ export * from './TransactionManager.js';
|
|
|
8
7
|
export * from './QueryHelper.js';
|
|
9
8
|
export * from './NullHighlighter.js';
|
|
10
9
|
export * from './EntityComparator.js';
|
|
11
|
-
export * from './AbstractSchemaGenerator.js';
|
|
12
10
|
export * from './RawQueryFragment.js';
|
|
13
11
|
export * from './env-vars.js';
|
|
14
12
|
export * from './upsert-utils.js';
|
package/utils/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './Configuration.js';
|
|
2
2
|
export * from './Cursor.js';
|
|
3
|
-
export * from './DataloaderUtils.js';
|
|
4
3
|
export * from './Utils.js';
|
|
5
4
|
export * from './RequestContext.js';
|
|
6
5
|
export * from './TransactionContext.js';
|
|
@@ -8,7 +7,6 @@ export * from './TransactionManager.js';
|
|
|
8
7
|
export * from './QueryHelper.js';
|
|
9
8
|
export * from './NullHighlighter.js';
|
|
10
9
|
export * from './EntityComparator.js';
|
|
11
|
-
export * from './AbstractSchemaGenerator.js';
|
|
12
10
|
export * from './RawQueryFragment.js';
|
|
13
11
|
export * from './env-vars.js';
|
|
14
12
|
export * from './upsert-utils.js';
|