@mikro-orm/core 7.0.0-dev.33 → 7.0.0-dev.331
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.d.ts +70 -75
- package/EntityManager.js +487 -402
- package/MikroORM.d.ts +45 -38
- package/MikroORM.js +123 -156
- package/README.md +7 -4
- package/cache/FileCacheAdapter.d.ts +2 -7
- package/cache/FileCacheAdapter.js +35 -30
- package/cache/GeneratedCacheAdapter.d.ts +1 -2
- package/cache/GeneratedCacheAdapter.js +6 -8
- package/cache/MemoryCacheAdapter.d.ts +1 -2
- package/cache/MemoryCacheAdapter.js +8 -8
- package/cache/index.d.ts +1 -2
- package/cache/index.js +0 -2
- package/connections/Connection.d.ts +12 -5
- package/connections/Connection.js +37 -15
- package/drivers/DatabaseDriver.d.ts +25 -18
- package/drivers/DatabaseDriver.js +144 -45
- package/drivers/IDatabaseDriver.d.ts +118 -23
- package/entity/BaseEntity.d.ts +63 -4
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +95 -31
- package/entity/Collection.js +487 -139
- package/entity/EntityAssigner.js +37 -25
- package/entity/EntityFactory.d.ts +8 -9
- package/entity/EntityFactory.js +152 -100
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +69 -27
- package/entity/EntityLoader.d.ts +12 -13
- package/entity/EntityLoader.js +286 -125
- package/entity/EntityRepository.d.ts +28 -8
- package/entity/EntityRepository.js +8 -2
- package/entity/PolymorphicRef.d.ts +12 -0
- package/entity/PolymorphicRef.js +18 -0
- package/entity/Reference.d.ts +3 -8
- package/entity/Reference.js +62 -29
- package/entity/WrappedEntity.d.ts +7 -10
- package/entity/WrappedEntity.js +6 -7
- package/entity/defineEntity.d.ts +472 -313
- package/entity/defineEntity.js +134 -290
- package/entity/index.d.ts +2 -2
- package/entity/index.js +2 -2
- package/entity/utils.d.ts +6 -1
- package/entity/utils.js +46 -11
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +66 -0
- package/enums.d.ts +8 -6
- package/enums.js +13 -17
- package/errors.d.ts +26 -16
- package/errors.js +63 -31
- package/events/EventManager.d.ts +3 -5
- package/events/EventManager.js +37 -26
- package/events/index.d.ts +1 -1
- package/events/index.js +0 -1
- package/exceptions.js +9 -2
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +5 -6
- package/hydration/ObjectHydrator.js +109 -50
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +3 -4
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/colors.d.ts +1 -1
- package/logging/colors.js +4 -6
- package/logging/index.d.ts +2 -1
- package/logging/index.js +1 -1
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +11 -0
- package/metadata/EntitySchema.d.ts +47 -23
- package/metadata/EntitySchema.js +103 -34
- package/metadata/MetadataDiscovery.d.ts +65 -18
- package/metadata/MetadataDiscovery.js +940 -424
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +71 -2
- package/metadata/MetadataStorage.d.ts +11 -13
- package/metadata/MetadataStorage.js +79 -48
- package/metadata/MetadataValidator.d.ts +32 -9
- package/metadata/MetadataValidator.js +214 -44
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +0 -1
- package/metadata/types.d.ts +577 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +16 -4
- package/naming-strategy/AbstractNamingStrategy.js +26 -5
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
- package/naming-strategy/EntityCaseNamingStrategy.js +7 -6
- package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
- package/naming-strategy/MongoNamingStrategy.js +6 -6
- package/naming-strategy/NamingStrategy.d.ts +28 -4
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
- package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
- package/naming-strategy/index.d.ts +1 -1
- package/naming-strategy/index.js +0 -1
- package/not-supported.d.ts +2 -0
- package/not-supported.js +8 -0
- package/package.json +47 -36
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +33 -15
- package/platforms/Platform.js +125 -69
- package/serialization/EntitySerializer.d.ts +6 -3
- package/serialization/EntitySerializer.js +54 -30
- package/serialization/EntityTransformer.js +37 -22
- package/serialization/SerializationContext.d.ts +10 -14
- package/serialization/SerializationContext.js +24 -19
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.js +1 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +1 -0
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.js +2 -2
- package/types/DoubleType.js +1 -1
- package/types/EnumArrayType.js +1 -2
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -4
- package/types/Type.js +3 -3
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/UuidType.d.ts +2 -0
- package/types/UuidType.js +14 -2
- package/types/index.d.ts +3 -2
- package/typings.d.ts +427 -170
- package/typings.js +100 -45
- package/unit-of-work/ChangeSet.d.ts +4 -6
- package/unit-of-work/ChangeSet.js +8 -9
- package/unit-of-work/ChangeSetComputer.d.ts +2 -12
- package/unit-of-work/ChangeSetComputer.js +61 -38
- package/unit-of-work/ChangeSetPersister.d.ts +10 -17
- package/unit-of-work/ChangeSetPersister.js +136 -73
- package/unit-of-work/CommitOrderCalculator.d.ts +13 -14
- package/unit-of-work/CommitOrderCalculator.js +22 -20
- package/unit-of-work/IdentityMap.d.ts +12 -3
- package/unit-of-work/IdentityMap.js +51 -13
- package/unit-of-work/UnitOfWork.d.ts +39 -23
- package/unit-of-work/UnitOfWork.js +441 -246
- package/utils/AbstractMigrator.d.ts +101 -0
- package/utils/AbstractMigrator.js +303 -0
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +30 -18
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +647 -185
- package/utils/Configuration.js +215 -252
- package/utils/ConfigurationLoader.d.ts +1 -52
- package/utils/ConfigurationLoader.js +1 -330
- package/utils/Cursor.d.ts +3 -6
- package/utils/Cursor.js +32 -17
- package/utils/DataloaderUtils.d.ts +10 -5
- package/utils/DataloaderUtils.js +42 -22
- package/utils/EntityComparator.d.ts +21 -21
- package/utils/EntityComparator.js +224 -118
- package/utils/QueryHelper.d.ts +34 -7
- package/utils/QueryHelper.js +183 -72
- package/utils/RawQueryFragment.d.ts +28 -34
- package/utils/RawQueryFragment.js +37 -72
- package/utils/RequestContext.js +2 -2
- package/utils/TransactionContext.js +2 -2
- package/utils/TransactionManager.js +11 -8
- package/utils/Utils.d.ts +16 -127
- package/utils/Utils.js +104 -402
- package/utils/clone.js +13 -23
- package/utils/env-vars.d.ts +7 -0
- package/utils/env-vars.js +98 -0
- package/utils/fs-utils.d.ts +20 -0
- package/utils/fs-utils.js +193 -0
- package/utils/index.d.ts +1 -3
- package/utils/index.js +1 -3
- package/utils/upsert-utils.d.ts +9 -4
- package/utils/upsert-utils.js +51 -5
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -13
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -32
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -12
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -33
- package/decorators/Entity.js +0 -12
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -16
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -8
- package/decorators/Formula.d.ts +0 -4
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -19
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -42
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -34
- package/decorators/ManyToOne.js +0 -14
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -17
- package/decorators/OneToOne.d.ts +0 -28
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -8
- package/decorators/PrimaryKey.js +0 -20
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -32
- package/decorators/Transactional.d.ts +0 -14
- package/decorators/Transactional.js +0 -28
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -47
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -17
- package/entity/ArrayCollection.d.ts +0 -118
- package/entity/ArrayCollection.js +0 -407
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -44
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -28
|
@@ -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
|
+
#private;
|
|
19
|
+
protected readonly em: D[typeof EntityManagerType];
|
|
20
|
+
protected runner: IMigrationRunner;
|
|
21
|
+
protected storage: IMigratorStorage;
|
|
22
|
+
protected generator: IMigrationGenerator;
|
|
23
|
+
protected readonly driver: D;
|
|
24
|
+
protected readonly config: Configuration;
|
|
25
|
+
protected readonly options: MigrationsOptions;
|
|
26
|
+
protected absolutePath: string;
|
|
27
|
+
protected initialized: boolean;
|
|
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
|
+
protected runMigrations(method: 'up' | 'down', options?: string | string[] | MigrateOptions): Promise<MigrationInfo[]>;
|
|
99
|
+
private runInTransaction;
|
|
100
|
+
}
|
|
101
|
+
export {};
|
|
@@ -0,0 +1,303 @@
|
|
|
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.filter(m => !executed.has(m.name)).map(m => ({ name: m.name, path: m.path }));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* @inheritDoc
|
|
56
|
+
*/
|
|
57
|
+
async up(options) {
|
|
58
|
+
return this.runMigrations('up', options);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @inheritDoc
|
|
62
|
+
*/
|
|
63
|
+
async down(options) {
|
|
64
|
+
return this.runMigrations('down', options);
|
|
65
|
+
}
|
|
66
|
+
async init() {
|
|
67
|
+
if (this.initialized) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.initialized = true;
|
|
71
|
+
if (!this.options.migrationsList) {
|
|
72
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
73
|
+
this.detectSourceFolder(fs);
|
|
74
|
+
/* v8 ignore next */
|
|
75
|
+
const key = this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.options.pathTs ? 'pathTs' : 'path';
|
|
76
|
+
this.absolutePath = fs.absolutePath(this.options[key], this.config.get('baseDir'));
|
|
77
|
+
fs.ensureDir(this.absolutePath);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
initServices() {
|
|
81
|
+
this.runner = this.createRunner();
|
|
82
|
+
this.storage = this.createStorage();
|
|
83
|
+
if (this.options.generator) {
|
|
84
|
+
this.generator = new this.options.generator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.generator = this.getDefaultGenerator();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
resolve(params) {
|
|
91
|
+
const createMigrationHandler = async (method) => {
|
|
92
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
93
|
+
const migration = await fs.dynamicImport(params.path);
|
|
94
|
+
const MigrationClass = Object.values(migration).find(cls => typeof cls === 'function' && typeof cls.constructor === 'function');
|
|
95
|
+
const instance = new MigrationClass(this.driver, this.config);
|
|
96
|
+
await this.runner.run(instance, method);
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
name: this.storage.getMigrationName(params.name),
|
|
100
|
+
path: params.path,
|
|
101
|
+
up: () => createMigrationHandler('up'),
|
|
102
|
+
down: () => createMigrationHandler('down'),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
initialize(MigrationClass, name) {
|
|
106
|
+
const instance = new MigrationClass(this.driver, this.config);
|
|
107
|
+
return {
|
|
108
|
+
name: this.storage.getMigrationName(name),
|
|
109
|
+
up: () => this.runner.run(instance, 'up'),
|
|
110
|
+
down: () => this.runner.run(instance, 'down'),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
|
|
115
|
+
* If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
|
|
116
|
+
* used for the TS variant (`pathTs` option).
|
|
117
|
+
*
|
|
118
|
+
* If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
|
|
119
|
+
* break existing projects, only help with the new ones.
|
|
120
|
+
*/
|
|
121
|
+
detectSourceFolder(fs) {
|
|
122
|
+
const baseDir = this.config.get('baseDir');
|
|
123
|
+
const defaultPath = './migrations';
|
|
124
|
+
if (!fs.pathExists(baseDir + '/src')) {
|
|
125
|
+
this.options.path ??= defaultPath;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const exists = fs.pathExists(`${baseDir}/${defaultPath}`);
|
|
129
|
+
const distDir = fs.pathExists(baseDir + '/dist');
|
|
130
|
+
const buildDir = fs.pathExists(baseDir + '/build');
|
|
131
|
+
// if neither `dist` nor `build` exist, we use the `src` folder as it might be a JS project without building, but with `src` folder
|
|
132
|
+
/* v8 ignore next */
|
|
133
|
+
const path = distDir ? './dist' : buildDir ? './build' : './src';
|
|
134
|
+
// only if the user did not provide any values and if the default path does not exist
|
|
135
|
+
if (!this.options.path && !this.options.pathTs && !exists) {
|
|
136
|
+
this.options.path = `${path}/migrations`;
|
|
137
|
+
this.options.pathTs = './src/migrations';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
registerDefaultListeners() {
|
|
141
|
+
/* v8 ignore else */
|
|
142
|
+
if (!this.options.silent) {
|
|
143
|
+
const logger = this.config.getLogger();
|
|
144
|
+
this.on('migrating', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
|
|
145
|
+
this.on('migrated', event => logger.log('migrator', `Applied '${event.name}'`, { enabled: true }));
|
|
146
|
+
this.on('reverting', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
|
|
147
|
+
this.on('reverted', event => logger.log('migrator', `Reverted '${event.name}'`, { enabled: true }));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async emit(event, data) {
|
|
151
|
+
for (const listener of this.#listeners.get(event) ?? []) {
|
|
152
|
+
await listener(data);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async discoverMigrations() {
|
|
156
|
+
if (this.options.migrationsList) {
|
|
157
|
+
return this.options.migrationsList.map(migration => {
|
|
158
|
+
if (typeof migration === 'function') {
|
|
159
|
+
return this.initialize(migration, migration.name);
|
|
160
|
+
}
|
|
161
|
+
return this.initialize(migration.class, migration.name);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
165
|
+
const pattern = fs.normalizePath(this.absolutePath, this.options.glob);
|
|
166
|
+
const files = fs.glob(pattern).sort();
|
|
167
|
+
return files.map(filePath => this.resolve({
|
|
168
|
+
name: filePath.replace(/\\/g, '/').split('/').pop(),
|
|
169
|
+
path: filePath,
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
async executeMigrations(method, options = {}) {
|
|
173
|
+
const all = await this.discoverMigrations();
|
|
174
|
+
const executed = await this.storage.executed();
|
|
175
|
+
const executedSet = new Set(executed);
|
|
176
|
+
let toRun;
|
|
177
|
+
if (method === 'up') {
|
|
178
|
+
toRun = this.filterUp(all, executedSet, options);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
toRun = this.filterDown(all, executed, options);
|
|
182
|
+
}
|
|
183
|
+
const result = [];
|
|
184
|
+
const eventBefore = method === 'up' ? 'migrating' : 'reverting';
|
|
185
|
+
const eventAfter = method === 'up' ? 'migrated' : 'reverted';
|
|
186
|
+
for (const migration of toRun) {
|
|
187
|
+
const event = { name: migration.name, path: migration.path };
|
|
188
|
+
await this.emit(eventBefore, event);
|
|
189
|
+
await migration[method]();
|
|
190
|
+
if (method === 'up') {
|
|
191
|
+
await this.storage.logMigration({ name: migration.name });
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
await this.storage.unlogMigration({ name: migration.name });
|
|
195
|
+
}
|
|
196
|
+
await this.emit(eventAfter, event);
|
|
197
|
+
result.push(event);
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
filterUp(all, executed, options) {
|
|
202
|
+
let pending = all.filter(m => !executed.has(m.name));
|
|
203
|
+
if (options.migrations) {
|
|
204
|
+
const set = new Set(options.migrations);
|
|
205
|
+
return pending.filter(m => set.has(m.name));
|
|
206
|
+
}
|
|
207
|
+
if (options.from) {
|
|
208
|
+
const idx = all.findIndex(m => m.name === options.from);
|
|
209
|
+
if (idx >= 0) {
|
|
210
|
+
const names = new Set(all.slice(idx + 1).map(m => m.name));
|
|
211
|
+
pending = pending.filter(m => names.has(m.name));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (options.to && typeof options.to === 'string') {
|
|
215
|
+
const idx = all.findIndex(m => m.name === options.to);
|
|
216
|
+
if (idx >= 0) {
|
|
217
|
+
const names = new Set(all.slice(0, idx + 1).map(m => m.name));
|
|
218
|
+
pending = pending.filter(m => names.has(m.name));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return pending;
|
|
222
|
+
}
|
|
223
|
+
filterDown(all, executed, options) {
|
|
224
|
+
const migrationMap = new Map(all.map(m => [m.name, m]));
|
|
225
|
+
const executedReversed = [...executed].reverse();
|
|
226
|
+
if (options.migrations) {
|
|
227
|
+
const set = new Set(options.migrations);
|
|
228
|
+
return executedReversed
|
|
229
|
+
.filter(name => set.has(name))
|
|
230
|
+
.map(name => migrationMap.get(name))
|
|
231
|
+
.filter(Boolean);
|
|
232
|
+
}
|
|
233
|
+
if (options.to === 0) {
|
|
234
|
+
return executedReversed.map(name => migrationMap.get(name)).filter(Boolean);
|
|
235
|
+
}
|
|
236
|
+
if (options.to) {
|
|
237
|
+
const result = [];
|
|
238
|
+
for (const name of executedReversed) {
|
|
239
|
+
if (name === String(options.to)) {
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
const m = migrationMap.get(name);
|
|
243
|
+
if (m) {
|
|
244
|
+
result.push(m);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
// Default: revert last 1
|
|
250
|
+
if (executedReversed.length > 0) {
|
|
251
|
+
const m = migrationMap.get(executedReversed[0]);
|
|
252
|
+
return m ? [m] : [];
|
|
253
|
+
}
|
|
254
|
+
return [];
|
|
255
|
+
}
|
|
256
|
+
getMigrationFilename(name) {
|
|
257
|
+
name = name.replace(/\.[jt]s$/, '');
|
|
258
|
+
return /^\d{14}$/.exec(name) ? this.options.fileName(name) : name;
|
|
259
|
+
}
|
|
260
|
+
prefix(options) {
|
|
261
|
+
if (typeof options === 'string' || Array.isArray(options)) {
|
|
262
|
+
return { migrations: Utils.asArray(options).map(name => this.getMigrationFilename(name)) };
|
|
263
|
+
}
|
|
264
|
+
if (!options) {
|
|
265
|
+
return {};
|
|
266
|
+
}
|
|
267
|
+
const result = {};
|
|
268
|
+
if (options.migrations) {
|
|
269
|
+
result.migrations = options.migrations.map(name => this.getMigrationFilename(name));
|
|
270
|
+
}
|
|
271
|
+
if (options.from) {
|
|
272
|
+
result.from = this.getMigrationFilename(String(options.from));
|
|
273
|
+
}
|
|
274
|
+
if (options.to && options.to !== 0) {
|
|
275
|
+
result.to = this.getMigrationFilename(String(options.to));
|
|
276
|
+
}
|
|
277
|
+
else if (options.to === 0) {
|
|
278
|
+
result.to = 0;
|
|
279
|
+
}
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
async runMigrations(method, options) {
|
|
283
|
+
await this.init();
|
|
284
|
+
if (!this.options.transactional || !this.options.allOrNothing) {
|
|
285
|
+
return this.executeMigrations(method, this.prefix(options));
|
|
286
|
+
}
|
|
287
|
+
if (Utils.isObject(options) && options.transaction) {
|
|
288
|
+
return this.runInTransaction(options.transaction, method, options);
|
|
289
|
+
}
|
|
290
|
+
return this.driver.getConnection().transactional(trx => this.runInTransaction(trx, method, options));
|
|
291
|
+
}
|
|
292
|
+
async runInTransaction(trx, method, options) {
|
|
293
|
+
this.runner.setMasterMigration(trx);
|
|
294
|
+
this.storage.setMasterMigration(trx);
|
|
295
|
+
try {
|
|
296
|
+
return await this.executeMigrations(method, this.prefix(options));
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
this.runner.unsetMasterMigration();
|
|
300
|
+
this.storage.unsetMasterMigration();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -10,18 +10,18 @@ export declare abstract class AbstractSchemaGenerator<D extends IDatabaseDriver>
|
|
|
10
10
|
protected readonly platform: ReturnType<D['getPlatform']>;
|
|
11
11
|
protected readonly connection: ReturnType<D['getConnection']>;
|
|
12
12
|
constructor(em: D | D[typeof EntityManagerType]);
|
|
13
|
-
|
|
13
|
+
create(options?: CreateSchemaOptions): Promise<void>;
|
|
14
14
|
/**
|
|
15
15
|
* Returns true if the database was created.
|
|
16
16
|
*/
|
|
17
17
|
ensureDatabase(options?: EnsureDatabaseOptions): Promise<boolean>;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
refresh(options?: RefreshDatabaseOptions): Promise<void>;
|
|
19
|
+
clear(options?: ClearDatabaseOptions): Promise<void>;
|
|
20
20
|
protected clearIdentityMap(): void;
|
|
21
21
|
getCreateSchemaSQL(options?: CreateSchemaOptions): Promise<string>;
|
|
22
|
-
|
|
22
|
+
drop(options?: DropSchemaOptions): Promise<void>;
|
|
23
23
|
getDropSchemaSQL(options?: Omit<DropSchemaOptions, 'dropDb'>): Promise<string>;
|
|
24
|
-
|
|
24
|
+
update(options?: UpdateSchemaOptions): Promise<void>;
|
|
25
25
|
getUpdateSchemaSQL(options?: UpdateSchemaOptions): Promise<string>;
|
|
26
26
|
getUpdateSchemaMigrationSQL(options?: UpdateSchemaOptions): Promise<{
|
|
27
27
|
up: string;
|
|
@@ -15,7 +15,7 @@ export class AbstractSchemaGenerator {
|
|
|
15
15
|
this.platform = this.driver.getPlatform();
|
|
16
16
|
this.connection = this.driver.getConnection();
|
|
17
17
|
}
|
|
18
|
-
async
|
|
18
|
+
async create(options) {
|
|
19
19
|
this.notImplemented();
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
@@ -24,7 +24,7 @@ export class AbstractSchemaGenerator {
|
|
|
24
24
|
async ensureDatabase(options) {
|
|
25
25
|
this.notImplemented();
|
|
26
26
|
}
|
|
27
|
-
async
|
|
27
|
+
async refresh(options) {
|
|
28
28
|
if (options?.dropDb) {
|
|
29
29
|
const name = this.config.get('dbName');
|
|
30
30
|
await this.dropDatabase(name);
|
|
@@ -32,20 +32,22 @@ export class AbstractSchemaGenerator {
|
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
34
|
await this.ensureDatabase();
|
|
35
|
-
await this.
|
|
35
|
+
await this.drop(options);
|
|
36
36
|
}
|
|
37
37
|
if (options?.createSchema !== false) {
|
|
38
|
-
await this.
|
|
38
|
+
await this.create(options);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
async
|
|
41
|
+
async clear(options) {
|
|
42
42
|
for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
|
|
43
|
-
await this.driver.nativeDelete(meta.
|
|
43
|
+
await this.driver.nativeDelete(meta.class, {}, options);
|
|
44
|
+
}
|
|
45
|
+
if (options?.clearIdentityMap ?? true) {
|
|
46
|
+
this.clearIdentityMap();
|
|
44
47
|
}
|
|
45
|
-
this.clearIdentityMap();
|
|
46
48
|
}
|
|
47
49
|
clearIdentityMap() {
|
|
48
|
-
/* v8 ignore next
|
|
50
|
+
/* v8 ignore next */
|
|
49
51
|
if (!this.em) {
|
|
50
52
|
return;
|
|
51
53
|
}
|
|
@@ -57,13 +59,13 @@ export class AbstractSchemaGenerator {
|
|
|
57
59
|
async getCreateSchemaSQL(options) {
|
|
58
60
|
this.notImplemented();
|
|
59
61
|
}
|
|
60
|
-
async
|
|
62
|
+
async drop(options) {
|
|
61
63
|
this.notImplemented();
|
|
62
64
|
}
|
|
63
65
|
async getDropSchemaSQL(options) {
|
|
64
66
|
this.notImplemented();
|
|
65
67
|
}
|
|
66
|
-
async
|
|
68
|
+
async update(options) {
|
|
67
69
|
this.notImplemented();
|
|
68
70
|
}
|
|
69
71
|
async getUpdateSchemaSQL(options) {
|
|
@@ -88,21 +90,31 @@ export class AbstractSchemaGenerator {
|
|
|
88
90
|
this.notImplemented();
|
|
89
91
|
}
|
|
90
92
|
getOrderedMetadata(schema) {
|
|
91
|
-
const metadata =
|
|
92
|
-
const isRootEntity = meta.root.
|
|
93
|
-
|
|
93
|
+
const metadata = [...this.metadata.getAll().values()].filter(meta => {
|
|
94
|
+
const isRootEntity = meta.root.class === meta.class;
|
|
95
|
+
const isTPTChild = meta.inheritanceType === 'tpt' && meta.tptParent;
|
|
96
|
+
return (isRootEntity || isTPTChild) && !meta.embeddable && !meta.virtual;
|
|
94
97
|
});
|
|
95
98
|
const calc = new CommitOrderCalculator();
|
|
96
|
-
metadata.forEach(meta =>
|
|
99
|
+
metadata.forEach(meta => {
|
|
100
|
+
const nodeId = meta.inheritanceType === 'tpt' && meta.tptParent ? meta._id : meta.root._id;
|
|
101
|
+
calc.addNode(nodeId);
|
|
102
|
+
});
|
|
97
103
|
let meta = metadata.pop();
|
|
98
104
|
while (meta) {
|
|
99
|
-
|
|
100
|
-
|
|
105
|
+
const nodeId = meta.inheritanceType === 'tpt' && meta.tptParent ? meta._id : meta.root._id;
|
|
106
|
+
for (const prop of meta.relations) {
|
|
107
|
+
calc.discoverProperty(prop, nodeId);
|
|
108
|
+
}
|
|
109
|
+
if (meta.inheritanceType === 'tpt' && meta.tptParent) {
|
|
110
|
+
const parentId = meta.tptParent._id;
|
|
111
|
+
calc.addDependency(parentId, nodeId, 1);
|
|
101
112
|
}
|
|
102
113
|
meta = metadata.pop();
|
|
103
114
|
}
|
|
104
|
-
return calc
|
|
105
|
-
.
|
|
115
|
+
return calc
|
|
116
|
+
.sort()
|
|
117
|
+
.map(cls => this.metadata.getById(cls))
|
|
106
118
|
.filter(meta => {
|
|
107
119
|
const targetSchema = meta.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
|
|
108
120
|
return schema ? [schema, '*'].includes(targetSchema) : meta.schema !== '*';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function getNodeAsyncContext() {
|
|
2
|
+
const mod = globalThis.process?.getBuiltinModule?.('node:async_hooks');
|
|
3
|
+
/* v8 ignore next */
|
|
4
|
+
if (!mod?.AsyncLocalStorage) {
|
|
5
|
+
throw new Error('AsyncLocalStorage not available');
|
|
6
|
+
}
|
|
7
|
+
return new mod.AsyncLocalStorage();
|
|
8
|
+
}
|
|
9
|
+
/* v8 ignore next */
|
|
10
|
+
function createFallbackAsyncContext() {
|
|
11
|
+
let store;
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
console.warn('AsyncLocalStorage not available');
|
|
14
|
+
return {
|
|
15
|
+
getStore: () => store,
|
|
16
|
+
enterWith: value => (store = value),
|
|
17
|
+
run: (value, cb) => {
|
|
18
|
+
const prev = store;
|
|
19
|
+
store = value;
|
|
20
|
+
try {
|
|
21
|
+
return cb();
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
store = prev;
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function createAsyncContext() {
|
|
30
|
+
/* v8 ignore next */
|
|
31
|
+
const ALS = globalThis.AsyncLocalStorage;
|
|
32
|
+
/* v8 ignore next */
|
|
33
|
+
if (typeof ALS === 'function' && ALS.prototype?.run) {
|
|
34
|
+
return new ALS();
|
|
35
|
+
}
|
|
36
|
+
/* v8 ignore else */
|
|
37
|
+
if (globalThis.process?.versions?.node) {
|
|
38
|
+
return getNodeAsyncContext();
|
|
39
|
+
}
|
|
40
|
+
/* v8 ignore next */
|
|
41
|
+
return createFallbackAsyncContext();
|
|
42
|
+
}
|