|
8 | 8 | * You should have received a copy of the MIT License along with this program.
|
9 | 9 | */
|
10 | 10 |
|
11 |
| -import { ClassType } from '@deepkit/core'; |
| 11 | +import { ClassType, isEsm } from '@deepkit/core'; |
12 | 12 | import { Database, DatabaseRegistry } from '@deepkit/orm';
|
13 | 13 | import glob from 'fast-glob';
|
14 | 14 | import { basename, join } from 'path';
|
@@ -51,24 +51,63 @@ export class MigrationProvider {
|
51 | 51 | return migrationsPerDatabase;
|
52 | 52 | }
|
53 | 53 |
|
54 |
| - async getMigrations(migrationDir: string): Promise<Migration[]> { |
55 |
| - let migrations: Migration[] = []; |
56 |
| - |
57 |
| - const files = await glob('**/*.ts', { cwd: migrationDir }); |
58 |
| - require('ts-node').register({ |
| 54 | + private async registerTsNode() { |
| 55 | + const esm = isEsm(); |
| 56 | + const { register } = await import('ts-node'); |
| 57 | + register({ |
| 58 | + esm, |
59 | 59 | compilerOptions: {
|
60 | 60 | experimentalDecorators: true,
|
61 |
| - module: 'undefined' !== typeof require ? 'CommonJS' : 'ESNext', |
| 61 | + module: esm ? 'ESNext' : 'CommonJS', |
62 | 62 | },
|
63 | 63 | transpileOnly: true,
|
64 | 64 | });
|
| 65 | + } |
| 66 | + |
| 67 | + async addDatabase(path: string): Promise<void> { |
| 68 | + await this.registerTsNode(); |
| 69 | + |
| 70 | + const exports = Object.values((await import(path) || {})); |
| 71 | + if (!exports.length) { |
| 72 | + throw new Error(`No database found in path ${path}`); |
| 73 | + } |
| 74 | + |
| 75 | + let databaseInstance: Database | undefined; |
| 76 | + let foundDatabaseClass: ClassType<Database> | undefined; |
| 77 | + |
| 78 | + for (const value of exports) { |
| 79 | + if (value instanceof Database) { |
| 80 | + databaseInstance = value; |
| 81 | + break; |
| 82 | + } |
| 83 | + if (Object.getPrototypeOf(value) instanceof Database) { |
| 84 | + foundDatabaseClass = value as ClassType<Database>; |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + if (!databaseInstance) { |
| 89 | + if (foundDatabaseClass) { |
| 90 | + throw new Error(`Found database class ${foundDatabaseClass.name} in path ${path} but it has to be instantiated an exported. export const database = new ${foundDatabaseClass.name}(/* ... */);`); |
| 91 | + } |
| 92 | + throw new Error(`No database found in path ${path}`); |
| 93 | + } |
| 94 | + |
| 95 | + this.databases.addDatabaseInstance(databaseInstance); |
| 96 | + } |
| 97 | + |
| 98 | + async getMigrations(migrationDir: string): Promise<Migration[]> { |
| 99 | + let migrations: Migration[] = []; |
| 100 | + |
| 101 | + const files = await glob('**/*.ts', { cwd: migrationDir }); |
| 102 | + |
| 103 | + await this.registerTsNode(); |
65 | 104 |
|
66 | 105 | for (const file of files) {
|
67 | 106 | const path = join(process.cwd(), migrationDir, file);
|
68 | 107 | const name = basename(file.replace('.ts', ''));
|
69 |
| - const migration = require(path); |
70 |
| - if (migration && migration.SchemaMigration) { |
71 |
| - const jo = new class extends (migration.SchemaMigration as ClassType<Migration>) { |
| 108 | + const { SchemaMigration } = (await import(path) || {}); |
| 109 | + if (SchemaMigration) { |
| 110 | + const jo = new class extends (SchemaMigration as ClassType<Migration>) { |
72 | 111 | constructor() {
|
73 | 112 | super();
|
74 | 113 | if (!this.name) this.name = name;
|
|
0 commit comments