@mikro-orm/cli 7.0.17 → 7.0.18-dev.1
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/CLIConfigurator.js +5 -0
- package/CLIHelper.js +9 -0
- package/README.md +2 -1
- package/cli.js +0 -0
- package/commands/DiscoveryExportCommand.d.ts +23 -0
- package/commands/DiscoveryExportCommand.js +218 -0
- package/commands/MigrationCommandFactory.d.ts +17 -1
- package/commands/MigrationCommandFactory.js +41 -4
- package/package.json +3 -3
package/CLIConfigurator.js
CHANGED
|
@@ -8,6 +8,7 @@ import { DatabaseSeedCommand } from './commands/DatabaseSeedCommand.js';
|
|
|
8
8
|
import { DebugCommand } from './commands/DebugCommand.js';
|
|
9
9
|
import { GenerateCacheCommand } from './commands/GenerateCacheCommand.js';
|
|
10
10
|
import { CompileCommand } from './commands/CompileCommand.js';
|
|
11
|
+
import { DiscoveryExportCommand } from './commands/DiscoveryExportCommand.js';
|
|
11
12
|
import { GenerateEntitiesCommand } from './commands/GenerateEntitiesCommand.js';
|
|
12
13
|
import { ImportCommand } from './commands/ImportCommand.js';
|
|
13
14
|
import { MigrationCommandFactory } from './commands/MigrationCommandFactory.js';
|
|
@@ -53,6 +54,7 @@ export async function configure() {
|
|
|
53
54
|
.command(new ClearCacheCommand())
|
|
54
55
|
.command(new GenerateCacheCommand())
|
|
55
56
|
.command(new CompileCommand())
|
|
57
|
+
.command(new DiscoveryExportCommand())
|
|
56
58
|
.command(new GenerateEntitiesCommand())
|
|
57
59
|
.command(new CreateDatabaseCommand())
|
|
58
60
|
.command(new ImportCommand())
|
|
@@ -69,5 +71,8 @@ export async function configure() {
|
|
|
69
71
|
.command(MigrationCommandFactory.create('check'))
|
|
70
72
|
.command(MigrationCommandFactory.create('pending'))
|
|
71
73
|
.command(MigrationCommandFactory.create('fresh'))
|
|
74
|
+
.command(MigrationCommandFactory.create('log'))
|
|
75
|
+
.command(MigrationCommandFactory.create('unlog'))
|
|
76
|
+
.command(MigrationCommandFactory.create('rollup'))
|
|
72
77
|
.command(new DebugCommand());
|
|
73
78
|
}
|
package/CLIHelper.js
CHANGED
|
@@ -210,6 +210,15 @@ export class CLIHelper {
|
|
|
210
210
|
case 'postgresql':
|
|
211
211
|
ret.driver ??= await import('@mikro-orm/postgresql').then(m => m.PostgreSqlDriver);
|
|
212
212
|
break;
|
|
213
|
+
case 'pglite': {
|
|
214
|
+
// Variable specifier (instead of a literal) keeps `@electric-sql/pglite`'s
|
|
215
|
+
// d.ts — which references DOM/Emscripten ambient globals not in our TS
|
|
216
|
+
// lib — out of the CLI's compile graph. Safe here: the CLI is a Node
|
|
217
|
+
// binary, not bundled into end-user apps.
|
|
218
|
+
const name = '@mikro-orm/pglite';
|
|
219
|
+
ret.driver ??= (await import(name)).PgliteDriver;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
213
222
|
case 'sqlite':
|
|
214
223
|
ret.driver ??= await import('@mikro-orm/sqlite').then(m => m.SqliteDriver);
|
|
215
224
|
break;
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
|
|
3
3
|
</h1>
|
|
4
4
|
|
|
5
|
-
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
|
|
5
|
+
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL (including CockroachDB and PGlite), SQLite (including libSQL), MSSQL and Oracle databases.
|
|
6
6
|
|
|
7
7
|
> Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
|
|
8
8
|
|
|
@@ -19,6 +19,7 @@ Install a driver package for your database:
|
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
21
|
npm install @mikro-orm/postgresql # PostgreSQL
|
|
22
|
+
npm install @mikro-orm/pglite # PGlite (embedded PostgreSQL in WASM)
|
|
22
23
|
npm install @mikro-orm/mysql # MySQL
|
|
23
24
|
npm install @mikro-orm/mariadb # MariaDB
|
|
24
25
|
npm install @mikro-orm/sqlite # SQLite
|
package/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ArgumentsCamelCase, Argv } from 'yargs';
|
|
2
|
+
import type { BaseArgs, BaseCommand } from '../CLIConfigurator.js';
|
|
3
|
+
type DiscoveryExportArgs = BaseArgs & {
|
|
4
|
+
path?: string[];
|
|
5
|
+
out?: string;
|
|
6
|
+
dump?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare class DiscoveryExportCommand implements BaseCommand<DiscoveryExportArgs> {
|
|
9
|
+
command: string;
|
|
10
|
+
describe: string;
|
|
11
|
+
builder: (args: Argv<BaseArgs>) => Argv<DiscoveryExportArgs>;
|
|
12
|
+
/**
|
|
13
|
+
* @inheritDoc
|
|
14
|
+
*/
|
|
15
|
+
handler: (args: ArgumentsCamelCase<DiscoveryExportArgs>) => Promise<void>;
|
|
16
|
+
private resolvePaths;
|
|
17
|
+
private discoverExports;
|
|
18
|
+
private inferNameFromDefault;
|
|
19
|
+
private resolveOutputPath;
|
|
20
|
+
private resolveDriverPackage;
|
|
21
|
+
private generateFile;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { colors, EntitySchema, MetadataStorage } from '@mikro-orm/core';
|
|
4
|
+
import { fs } from '@mikro-orm/core/fs-utils';
|
|
5
|
+
import { CLIHelper } from '../CLIHelper.js';
|
|
6
|
+
const driverPackageMap = {
|
|
7
|
+
PostgreSqlDriver: '@mikro-orm/postgresql',
|
|
8
|
+
PgliteDriver: '@mikro-orm/pglite',
|
|
9
|
+
MySqlDriver: '@mikro-orm/mysql',
|
|
10
|
+
MariaDbDriver: '@mikro-orm/mariadb',
|
|
11
|
+
SqliteDriver: '@mikro-orm/sqlite',
|
|
12
|
+
LibSqlDriver: '@mikro-orm/libsql',
|
|
13
|
+
MsSqlDriver: '@mikro-orm/mssql',
|
|
14
|
+
OracleDriver: '@mikro-orm/oracledb',
|
|
15
|
+
MongoDriver: '@mikro-orm/mongodb',
|
|
16
|
+
};
|
|
17
|
+
export class DiscoveryExportCommand {
|
|
18
|
+
command = 'discovery:export';
|
|
19
|
+
describe = 'Generate a TypeScript barrel file with entity exports for typed Kysely and ORM config';
|
|
20
|
+
builder = (args) => {
|
|
21
|
+
args.option('path', {
|
|
22
|
+
alias: 'p',
|
|
23
|
+
type: 'string',
|
|
24
|
+
array: true,
|
|
25
|
+
desc: 'Glob patterns for entity source files',
|
|
26
|
+
});
|
|
27
|
+
args.option('out', {
|
|
28
|
+
alias: 'o',
|
|
29
|
+
type: 'string',
|
|
30
|
+
desc: 'Output file path (defaults to next to ORM config)',
|
|
31
|
+
});
|
|
32
|
+
args.option('dump', {
|
|
33
|
+
alias: 'd',
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
desc: 'Print to stdout instead of writing a file',
|
|
36
|
+
default: false,
|
|
37
|
+
});
|
|
38
|
+
return args;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* @inheritDoc
|
|
42
|
+
*/
|
|
43
|
+
handler = async (args) => {
|
|
44
|
+
const config = await CLIHelper.getConfiguration(args.contextName, args.config);
|
|
45
|
+
const paths = this.resolvePaths(args, config);
|
|
46
|
+
const baseDir = fs.absolutePath(config.get('baseDir') ?? process.cwd());
|
|
47
|
+
const discovered = await this.discoverExports(paths, baseDir);
|
|
48
|
+
if (discovered.length === 0) {
|
|
49
|
+
CLIHelper.dump(colors.yellow('No entities found in the specified paths.'));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const esm = CLIHelper.isESM();
|
|
53
|
+
const driverPackage = this.resolveDriverPackage(config);
|
|
54
|
+
if (args.dump) {
|
|
55
|
+
const output = this.generateFile(discovered, join(process.cwd(), 'entities.generated.ts'), esm, driverPackage);
|
|
56
|
+
CLIHelper.dump(output);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const outPath = await this.resolveOutputPath(args);
|
|
60
|
+
const output = this.generateFile(discovered, outPath, esm, driverPackage);
|
|
61
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
62
|
+
writeFileSync(outPath, output);
|
|
63
|
+
CLIHelper.dump(colors.green(`Entity exports generated to ${outPath} (${discovered.length} entities)`));
|
|
64
|
+
CLIHelper.dump(`\nExample usage in your ORM config:\n`);
|
|
65
|
+
const importExt = esm ? '.js' : '';
|
|
66
|
+
const importPath = `./${basename(outPath).replace(/\.ts$/, importExt)}`;
|
|
67
|
+
CLIHelper.dump(` import { entities } from ${colors.cyan(`'${importPath}'`)};`);
|
|
68
|
+
CLIHelper.dump('');
|
|
69
|
+
CLIHelper.dump(' export default defineConfig({ entities });\n');
|
|
70
|
+
};
|
|
71
|
+
resolvePaths(args, config) {
|
|
72
|
+
if (args.path && args.path.length > 0) {
|
|
73
|
+
return args.path;
|
|
74
|
+
}
|
|
75
|
+
const entitiesTs = config.get('entitiesTs', []);
|
|
76
|
+
const stringPathsTs = entitiesTs.filter((p) => typeof p === 'string');
|
|
77
|
+
if (stringPathsTs.length > 0) {
|
|
78
|
+
return stringPathsTs;
|
|
79
|
+
}
|
|
80
|
+
const entities = config.get('entities', []);
|
|
81
|
+
const stringPaths = entities.filter((p) => typeof p === 'string');
|
|
82
|
+
if (stringPaths.length > 0) {
|
|
83
|
+
return stringPaths;
|
|
84
|
+
}
|
|
85
|
+
throw new Error('No entity paths found in config. Use --path to specify entity source locations.');
|
|
86
|
+
}
|
|
87
|
+
async discoverExports(paths, baseDir) {
|
|
88
|
+
const normalizedPaths = paths.map(path => fs.normalizePath(path));
|
|
89
|
+
const normalizedBaseDir = fs.normalizePath(baseDir);
|
|
90
|
+
const files = fs.glob(normalizedPaths, normalizedBaseDir);
|
|
91
|
+
const discovered = [];
|
|
92
|
+
for (const filepath of files) {
|
|
93
|
+
const filename = basename(filepath);
|
|
94
|
+
if (!/\.[cm]?[jt]s$/.exec(filename) || /\.d\.[cm]?ts/.exec(filename)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// fs.glob returns paths relative to normalizedBaseDir
|
|
98
|
+
const path = fs.normalizePath(baseDir, filepath);
|
|
99
|
+
const exports = await fs.dynamicImport(path);
|
|
100
|
+
const entries = Object.entries(exports);
|
|
101
|
+
// Collect entity schemas and their linked classes for dedup
|
|
102
|
+
const schemaClasses = new Set();
|
|
103
|
+
for (const [, value] of entries) {
|
|
104
|
+
if (EntitySchema.is(value) && value.meta.class) {
|
|
105
|
+
schemaClasses.add(value.meta.class);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
for (const [key, value] of entries) {
|
|
109
|
+
if (key === '__esModule') {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const isSchema = EntitySchema.is(value);
|
|
113
|
+
// Skip class implementations that are linked from an EntitySchema
|
|
114
|
+
if (!isSchema && schemaClasses.has(value)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const validTarget = isSchema || (value instanceof Function && MetadataStorage.isKnownEntity(value.name));
|
|
118
|
+
if (!validTarget) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const exportName = key === 'default' ? this.inferNameFromDefault(value, isSchema) : key;
|
|
122
|
+
// Avoid duplicates (e.g., default + named export of same thing)
|
|
123
|
+
if (discovered.some(d => d.filePath === path && d.exportName === exportName)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
discovered.push({
|
|
127
|
+
exportName,
|
|
128
|
+
filePath: path,
|
|
129
|
+
isDefault: key === 'default',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
discovered.sort((a, b) => a.exportName.localeCompare(b.exportName));
|
|
134
|
+
return discovered;
|
|
135
|
+
}
|
|
136
|
+
inferNameFromDefault(value, isSchema) {
|
|
137
|
+
if (isSchema) {
|
|
138
|
+
return value.meta.className ?? value.meta.name ?? 'DefaultEntity';
|
|
139
|
+
}
|
|
140
|
+
return value.name ?? 'DefaultEntity';
|
|
141
|
+
}
|
|
142
|
+
async resolveOutputPath(args) {
|
|
143
|
+
if (args.out) {
|
|
144
|
+
return resolve(args.out);
|
|
145
|
+
}
|
|
146
|
+
const configPaths = args.config ?? (await CLIHelper.getConfigPaths());
|
|
147
|
+
for (const configPath of configPaths) {
|
|
148
|
+
const absPath = fs.absolutePath(configPath);
|
|
149
|
+
if (fs.pathExists(absPath)) {
|
|
150
|
+
return resolve(dirname(absPath), 'entities.generated.ts');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return resolve(process.cwd(), 'entities.generated.ts');
|
|
154
|
+
}
|
|
155
|
+
resolveDriverPackage(config) {
|
|
156
|
+
try {
|
|
157
|
+
const driverName = config.getDriver().constructor.name;
|
|
158
|
+
return driverPackageMap[driverName] ?? '@mikro-orm/sql';
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return '@mikro-orm/sql';
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
generateFile(discovered, outPath, esm, driverPackage) {
|
|
165
|
+
const outDir = dirname(outPath);
|
|
166
|
+
const lines = [
|
|
167
|
+
'// This file was generated by MikroORM CLI. Do not edit manually.',
|
|
168
|
+
'// Re-run `mikro-orm discovery:export` to update.',
|
|
169
|
+
'',
|
|
170
|
+
];
|
|
171
|
+
// Group by file path for imports
|
|
172
|
+
const byFile = new Map();
|
|
173
|
+
for (const item of discovered) {
|
|
174
|
+
const list = byFile.get(item.filePath) ?? [];
|
|
175
|
+
list.push(item);
|
|
176
|
+
byFile.set(item.filePath, list);
|
|
177
|
+
}
|
|
178
|
+
// Generate import lines
|
|
179
|
+
for (const [filePath, items] of byFile) {
|
|
180
|
+
// `fs.relativePath` ensures POSIX separators (node:path.relative returns backslashes on Windows)
|
|
181
|
+
let rel = fs.relativePath(filePath, outDir);
|
|
182
|
+
// Remove .ts extension and optionally add .js for ESM
|
|
183
|
+
rel = rel.replace(/\.[cm]?[jt]s$/, '');
|
|
184
|
+
if (esm) {
|
|
185
|
+
rel += '.js';
|
|
186
|
+
}
|
|
187
|
+
const defaults = items.filter(i => i.isDefault);
|
|
188
|
+
const named = items.filter(i => !i.isDefault);
|
|
189
|
+
for (const d of defaults) {
|
|
190
|
+
lines.push(`import ${d.exportName} from '${rel}';`);
|
|
191
|
+
}
|
|
192
|
+
if (named.length > 0) {
|
|
193
|
+
const names = named.map(n => n.exportName).join(', ');
|
|
194
|
+
lines.push(`import { ${names} } from '${rel}';`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const isMongo = driverPackage === '@mikro-orm/mongodb';
|
|
198
|
+
// Type imports (Kysely types are not available for MongoDB)
|
|
199
|
+
if (!isMongo) {
|
|
200
|
+
lines.push(`import type { EntitySchemaWithMeta, InferKyselyDB, InferClassEntityDB } from '${driverPackage}';`);
|
|
201
|
+
}
|
|
202
|
+
lines.push('');
|
|
203
|
+
// entities array
|
|
204
|
+
lines.push('export const entities = [');
|
|
205
|
+
for (const item of discovered) {
|
|
206
|
+
lines.push(` ${item.exportName},`);
|
|
207
|
+
}
|
|
208
|
+
lines.push('] as const;');
|
|
209
|
+
// Database type (Kysely is SQL-only, skip for MongoDB)
|
|
210
|
+
if (!isMongo) {
|
|
211
|
+
lines.push('');
|
|
212
|
+
lines.push('export type Database = InferKyselyDB<Extract<(typeof entities)[number], EntitySchemaWithMeta>>');
|
|
213
|
+
lines.push(' & InferClassEntityDB<(typeof entities)[number]>;');
|
|
214
|
+
}
|
|
215
|
+
lines.push('');
|
|
216
|
+
return lines.join('\n');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -9,6 +9,9 @@ export declare class MigrationCommandFactory {
|
|
|
9
9
|
check: string;
|
|
10
10
|
pending: string;
|
|
11
11
|
fresh: string;
|
|
12
|
+
log: string;
|
|
13
|
+
unlog: string;
|
|
14
|
+
rollup: string;
|
|
12
15
|
};
|
|
13
16
|
static create<const T extends MigratorMethod>(command: T): {
|
|
14
17
|
command: string;
|
|
@@ -20,11 +23,15 @@ export declare class MigrationCommandFactory {
|
|
|
20
23
|
check: string;
|
|
21
24
|
pending: string;
|
|
22
25
|
fresh: string;
|
|
26
|
+
log: string;
|
|
27
|
+
unlog: string;
|
|
28
|
+
rollup: string;
|
|
23
29
|
}[T];
|
|
24
30
|
builder: (args: Argv<BaseArgs>) => Argv<MigrationOptionsMap[T]>;
|
|
25
31
|
handler: (args: ArgumentsCamelCase<MigrationOptionsMap[T]>) => Promise<void>;
|
|
26
32
|
};
|
|
27
33
|
static configureMigrationCommand<const T extends MigratorMethod>(args: Argv<BaseArgs>, method: T): Argv<MigrationOptionsMap[T]>;
|
|
34
|
+
private static configureLogUnlogCommand;
|
|
28
35
|
private static configureUpDownCommand;
|
|
29
36
|
private static configureCreateCommand;
|
|
30
37
|
static handleMigrationCommand(args: ArgumentsCamelCase<Opts>, method: MigratorMethod): Promise<void>;
|
|
@@ -35,6 +42,8 @@ export declare class MigrationCommandFactory {
|
|
|
35
42
|
private static handleCreateCommand;
|
|
36
43
|
private static handleCheckCommand;
|
|
37
44
|
private static handleFreshCommand;
|
|
45
|
+
private static handleLogUnlogCommand;
|
|
46
|
+
private static handleRollupCommand;
|
|
38
47
|
private static getUpDownOptions;
|
|
39
48
|
private static getUpDownSuccessMessage;
|
|
40
49
|
}
|
|
@@ -42,6 +51,7 @@ type CliUpDownOptions = BaseArgs & {
|
|
|
42
51
|
to?: string | number;
|
|
43
52
|
from?: string | number;
|
|
44
53
|
only?: string;
|
|
54
|
+
schema?: string;
|
|
45
55
|
};
|
|
46
56
|
type MigratorFreshOptions = BaseArgs & {
|
|
47
57
|
dropDb?: boolean;
|
|
@@ -54,6 +64,9 @@ type MigratorCreateOptions = BaseArgs & {
|
|
|
54
64
|
dump?: boolean;
|
|
55
65
|
name?: string;
|
|
56
66
|
};
|
|
67
|
+
type MigratorLogUnlogOptions = BaseArgs & {
|
|
68
|
+
name?: string;
|
|
69
|
+
};
|
|
57
70
|
type MigrationOptionsMap = {
|
|
58
71
|
create: MigratorCreateOptions;
|
|
59
72
|
check: BaseArgs;
|
|
@@ -62,7 +75,10 @@ type MigrationOptionsMap = {
|
|
|
62
75
|
list: BaseArgs;
|
|
63
76
|
pending: BaseArgs;
|
|
64
77
|
fresh: MigratorFreshOptions;
|
|
78
|
+
log: MigratorLogUnlogOptions;
|
|
79
|
+
unlog: MigratorLogUnlogOptions;
|
|
80
|
+
rollup: BaseArgs;
|
|
65
81
|
};
|
|
66
82
|
type MigratorMethod = keyof MigrationOptionsMap;
|
|
67
|
-
type Opts = BaseArgs & MigratorCreateOptions & CliUpDownOptions & MigratorFreshOptions;
|
|
83
|
+
type Opts = BaseArgs & MigratorCreateOptions & CliUpDownOptions & MigratorFreshOptions & MigratorLogUnlogOptions;
|
|
68
84
|
export {};
|
|
@@ -9,6 +9,9 @@ export class MigrationCommandFactory {
|
|
|
9
9
|
check: 'Check if migrations are needed. Useful for bash scripts.',
|
|
10
10
|
pending: 'List all pending migrations',
|
|
11
11
|
fresh: 'Clear the database and rerun all migrations',
|
|
12
|
+
log: 'Mark a migration as executed without running it',
|
|
13
|
+
unlog: 'Remove a migration from the executed list without reverting it',
|
|
14
|
+
rollup: 'Combine multiple migrations into a single migration',
|
|
12
15
|
};
|
|
13
16
|
static create(command) {
|
|
14
17
|
// oxfmt-ignore
|
|
@@ -29,6 +32,18 @@ export class MigrationCommandFactory {
|
|
|
29
32
|
if (method === 'fresh') {
|
|
30
33
|
return this.configureFreshCommand(args);
|
|
31
34
|
}
|
|
35
|
+
if (method === 'log' || method === 'unlog') {
|
|
36
|
+
return this.configureLogUnlogCommand(args);
|
|
37
|
+
}
|
|
38
|
+
return args;
|
|
39
|
+
}
|
|
40
|
+
static configureLogUnlogCommand(args) {
|
|
41
|
+
args.option('n', {
|
|
42
|
+
alias: 'name',
|
|
43
|
+
type: 'string',
|
|
44
|
+
desc: 'Name of the migration to log/unlog',
|
|
45
|
+
demandOption: true,
|
|
46
|
+
});
|
|
32
47
|
return args;
|
|
33
48
|
}
|
|
34
49
|
static configureUpDownCommand(args, method) {
|
|
@@ -47,6 +62,11 @@ export class MigrationCommandFactory {
|
|
|
47
62
|
type: 'string',
|
|
48
63
|
desc: 'Migrate only specified versions',
|
|
49
64
|
});
|
|
65
|
+
args.option('s', {
|
|
66
|
+
alias: 'schema',
|
|
67
|
+
type: 'string',
|
|
68
|
+
desc: 'Target schema to run the migration against (PostgreSQL, MySQL, Oracle)',
|
|
69
|
+
});
|
|
50
70
|
return args;
|
|
51
71
|
}
|
|
52
72
|
static configureCreateCommand(args) {
|
|
@@ -100,6 +120,14 @@ export class MigrationCommandFactory {
|
|
|
100
120
|
break;
|
|
101
121
|
case 'fresh':
|
|
102
122
|
await this.handleFreshCommand(args, orm.migrator, orm);
|
|
123
|
+
break;
|
|
124
|
+
case 'log':
|
|
125
|
+
case 'unlog':
|
|
126
|
+
await this.handleLogUnlogCommand(args, orm.migrator, method);
|
|
127
|
+
break;
|
|
128
|
+
case 'rollup':
|
|
129
|
+
await this.handleRollupCommand(orm.migrator);
|
|
130
|
+
break;
|
|
103
131
|
}
|
|
104
132
|
await orm.close(true);
|
|
105
133
|
}
|
|
@@ -182,12 +210,21 @@ export class MigrationCommandFactory {
|
|
|
182
210
|
CLIHelper.dump(colors.green(`Database seeded successfully with seeder class ${seederClass}`));
|
|
183
211
|
}
|
|
184
212
|
}
|
|
213
|
+
static async handleLogUnlogCommand(args, migrator, method) {
|
|
214
|
+
await migrator[`${method}Migration`](args.name);
|
|
215
|
+
const action = method === 'log' ? 'logged' : 'unlogged';
|
|
216
|
+
CLIHelper.dump(colors.green(`Successfully ${action} migration '${args.name}'`));
|
|
217
|
+
}
|
|
218
|
+
static async handleRollupCommand(migrator) {
|
|
219
|
+
const ret = await migrator.rollup();
|
|
220
|
+
CLIHelper.dump(colors.green(`${ret.fileName} successfully created (rollup)`));
|
|
221
|
+
}
|
|
185
222
|
static getUpDownOptions(flags) {
|
|
186
|
-
|
|
187
|
-
return { migrations: flags.only.split(/[, ]+/) };
|
|
188
|
-
}
|
|
189
|
-
const ret = {};
|
|
223
|
+
const ret = !flags.to && !flags.from && flags.only ? { migrations: flags.only.split(/[, ]+/) } : {};
|
|
190
224
|
['from', 'to'].filter(k => flags[k]).forEach(k => (ret[k] = flags[k] === '0' ? 0 : flags[k]));
|
|
225
|
+
if (flags.schema) {
|
|
226
|
+
ret.schema = flags.schema;
|
|
227
|
+
}
|
|
191
228
|
return ret;
|
|
192
229
|
}
|
|
193
230
|
static getUpDownSuccessMessage(method, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/cli",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.18-dev.1",
|
|
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",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"copy": "node ../../scripts/copy.mjs"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@mikro-orm/core": "7.0.
|
|
54
|
-
"mikro-orm": "7.0.
|
|
53
|
+
"@mikro-orm/core": "7.0.18-dev.1",
|
|
54
|
+
"mikro-orm": "7.0.18-dev.1",
|
|
55
55
|
"yargs": "17.7.2"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|