@mikro-orm/cli 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/CLIConfigurator.d.ts +11 -13
- package/CLIConfigurator.js +59 -60
- package/CLIHelper.d.ts +36 -6
- package/CLIHelper.js +253 -33
- package/README.md +7 -4
- package/cli +2 -2
- package/cli.js +2 -2
- package/commands/CompileCommand.d.ts +21 -0
- package/commands/CompileCommand.js +94 -0
- package/commands/CreateDatabaseCommand.js +1 -2
- package/commands/CreateSeederCommand.js +2 -3
- package/commands/DatabaseSeedCommand.js +1 -1
- package/commands/DebugCommand.js +15 -14
- package/commands/GenerateCacheCommand.js +3 -2
- package/commands/ImportCommand.js +3 -1
- package/commands/MigrationCommandFactory.js +19 -20
- package/commands/SchemaCommandFactory.js +6 -10
- package/package.json +30 -35
package/CLIConfigurator.d.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import { type CommandModule } from 'yargs';
|
|
1
|
+
import { type Argv, type CommandModule } from 'yargs';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
|
-
export type BaseArgs = Awaited<ReturnType<typeof
|
|
5
|
+
export type BaseArgs = Awaited<ReturnType<typeof createBasicConfig>['argv']>;
|
|
6
6
|
/**
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
9
|
export interface BaseCommand<CommandArgs extends BaseArgs = BaseArgs> extends CommandModule<BaseArgs, CommandArgs> {
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}>>;
|
|
21
|
-
}
|
|
11
|
+
declare function createBasicConfig(): Argv<{
|
|
12
|
+
config: string[] | undefined;
|
|
13
|
+
contextName: string;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function configure(): Promise<Argv<{
|
|
16
|
+
config: string[] | undefined;
|
|
17
|
+
contextName: string;
|
|
18
|
+
}>>;
|
|
19
|
+
export {};
|
package/CLIConfigurator.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Utils } from '@mikro-orm/core';
|
|
2
|
+
import { fs } from '@mikro-orm/core/fs-utils';
|
|
2
3
|
import yargs from 'yargs';
|
|
3
4
|
import { ClearCacheCommand } from './commands/ClearCacheCommand.js';
|
|
4
5
|
import { CreateDatabaseCommand } from './commands/CreateDatabaseCommand.js';
|
|
@@ -6,69 +7,67 @@ import { CreateSeederCommand } from './commands/CreateSeederCommand.js';
|
|
|
6
7
|
import { DatabaseSeedCommand } from './commands/DatabaseSeedCommand.js';
|
|
7
8
|
import { DebugCommand } from './commands/DebugCommand.js';
|
|
8
9
|
import { GenerateCacheCommand } from './commands/GenerateCacheCommand.js';
|
|
10
|
+
import { CompileCommand } from './commands/CompileCommand.js';
|
|
9
11
|
import { GenerateEntitiesCommand } from './commands/GenerateEntitiesCommand.js';
|
|
10
12
|
import { ImportCommand } from './commands/ImportCommand.js';
|
|
11
13
|
import { MigrationCommandFactory } from './commands/MigrationCommandFactory.js';
|
|
12
14
|
import { SchemaCommandFactory } from './commands/SchemaCommandFactory.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
/* v8 ignore next 3 */
|
|
48
|
-
if (!preferTs) {
|
|
49
|
-
process.env.MIKRO_ORM_CLI_PREFER_TS ??= '0';
|
|
50
|
-
}
|
|
15
|
+
import { CLIHelper } from './CLIHelper.js';
|
|
16
|
+
function createBasicConfig() {
|
|
17
|
+
return yargs()
|
|
18
|
+
.scriptName('mikro-orm')
|
|
19
|
+
.usage('Usage: $0 <command> [options]')
|
|
20
|
+
.example('$0 debug', 'Show debugging information')
|
|
21
|
+
.example('$0 schema:update --run', 'Runs schema synchronization')
|
|
22
|
+
.option('config', {
|
|
23
|
+
type: 'string',
|
|
24
|
+
array: true,
|
|
25
|
+
desc: `Set path to the ORM configuration file`,
|
|
26
|
+
})
|
|
27
|
+
.option('contextName', {
|
|
28
|
+
alias: 'context',
|
|
29
|
+
type: 'string',
|
|
30
|
+
desc: 'Set name of config to load out of the ORM configuration file. Used when config file exports an array or a function',
|
|
31
|
+
default: process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default',
|
|
32
|
+
})
|
|
33
|
+
.alias('v', 'version')
|
|
34
|
+
.alias('h', 'help')
|
|
35
|
+
.recommendCommands()
|
|
36
|
+
.showHelpOnFail(true)
|
|
37
|
+
.demandCommand(1, '')
|
|
38
|
+
.strict();
|
|
39
|
+
}
|
|
40
|
+
export async function configure() {
|
|
41
|
+
fs.checkPackageVersion();
|
|
42
|
+
const settings = CLIHelper.getSettings();
|
|
43
|
+
const version = Utils.getORMVersion();
|
|
44
|
+
if (settings.preferTs !== false) {
|
|
45
|
+
const preferTs = await CLIHelper.registerTypeScriptSupport(settings.tsConfigPath, settings.tsLoader);
|
|
46
|
+
/* v8 ignore next */
|
|
47
|
+
if (!preferTs) {
|
|
48
|
+
process.env.MIKRO_ORM_CLI_PREFER_TS ??= '0';
|
|
51
49
|
}
|
|
52
|
-
return CLIConfigurator.createBasicConfig()
|
|
53
|
-
.version(version)
|
|
54
|
-
.command(new ClearCacheCommand())
|
|
55
|
-
.command(new GenerateCacheCommand())
|
|
56
|
-
.command(new GenerateEntitiesCommand())
|
|
57
|
-
.command(new CreateDatabaseCommand())
|
|
58
|
-
.command(new ImportCommand())
|
|
59
|
-
.command(new DatabaseSeedCommand())
|
|
60
|
-
.command(new CreateSeederCommand())
|
|
61
|
-
.command(SchemaCommandFactory.create('create'))
|
|
62
|
-
.command(SchemaCommandFactory.create('drop'))
|
|
63
|
-
.command(SchemaCommandFactory.create('update'))
|
|
64
|
-
.command(SchemaCommandFactory.create('fresh'))
|
|
65
|
-
.command(MigrationCommandFactory.create('create'))
|
|
66
|
-
.command(MigrationCommandFactory.create('up'))
|
|
67
|
-
.command(MigrationCommandFactory.create('down'))
|
|
68
|
-
.command(MigrationCommandFactory.create('list'))
|
|
69
|
-
.command(MigrationCommandFactory.create('check'))
|
|
70
|
-
.command(MigrationCommandFactory.create('pending'))
|
|
71
|
-
.command(MigrationCommandFactory.create('fresh'))
|
|
72
|
-
.command(new DebugCommand());
|
|
73
50
|
}
|
|
51
|
+
return createBasicConfig()
|
|
52
|
+
.version(version)
|
|
53
|
+
.command(new ClearCacheCommand())
|
|
54
|
+
.command(new GenerateCacheCommand())
|
|
55
|
+
.command(new CompileCommand())
|
|
56
|
+
.command(new GenerateEntitiesCommand())
|
|
57
|
+
.command(new CreateDatabaseCommand())
|
|
58
|
+
.command(new ImportCommand())
|
|
59
|
+
.command(new DatabaseSeedCommand())
|
|
60
|
+
.command(new CreateSeederCommand())
|
|
61
|
+
.command(SchemaCommandFactory.create('create'))
|
|
62
|
+
.command(SchemaCommandFactory.create('drop'))
|
|
63
|
+
.command(SchemaCommandFactory.create('update'))
|
|
64
|
+
.command(SchemaCommandFactory.create('fresh'))
|
|
65
|
+
.command(MigrationCommandFactory.create('create'))
|
|
66
|
+
.command(MigrationCommandFactory.create('up'))
|
|
67
|
+
.command(MigrationCommandFactory.create('down'))
|
|
68
|
+
.command(MigrationCommandFactory.create('list'))
|
|
69
|
+
.command(MigrationCommandFactory.create('check'))
|
|
70
|
+
.command(MigrationCommandFactory.create('pending'))
|
|
71
|
+
.command(MigrationCommandFactory.create('fresh'))
|
|
72
|
+
.command(new DebugCommand());
|
|
74
73
|
}
|
package/CLIHelper.d.ts
CHANGED
|
@@ -1,22 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Configuration, type EntityManager, type EntityManagerType, type IDatabaseDriver, MikroORM, type Options } from '@mikro-orm/core';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
5
|
export declare class CLIHelper {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Gets a named configuration
|
|
8
|
+
*
|
|
9
|
+
* @param contextName Load a config with the given `contextName` value. Used when config file exports array or factory function. Setting it to "default" matches also config objects without `contextName` set.
|
|
10
|
+
* @param paths Array of possible paths for a configuration file. Files will be checked in order, and the first existing one will be used. Defaults to the output of {@link fs.getConfigPaths}.
|
|
11
|
+
* @param options Additional options to augment the final configuration with.
|
|
12
|
+
*/
|
|
13
|
+
static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>>(contextName?: string, paths?: string[], options?: Partial<Options<D>>): Promise<Configuration<D, EM>>;
|
|
14
|
+
static commonJSCompat(options: Partial<Options>): void;
|
|
7
15
|
static getORM<D extends IDatabaseDriver = IDatabaseDriver>(contextName?: string, configPaths?: string[], opts?: Partial<Options<D>>): Promise<MikroORM<D>>;
|
|
8
16
|
static isDBConnected(config: Configuration, reason?: false): Promise<boolean>;
|
|
9
17
|
static isDBConnected(config: Configuration, reason: true): Promise<true | string>;
|
|
10
|
-
static getNodeVersion(): string;
|
|
11
18
|
static getDriverDependencies(config: Configuration): string[];
|
|
12
19
|
static dump(text: string, config?: Configuration): void;
|
|
13
|
-
static
|
|
14
|
-
static
|
|
15
|
-
static
|
|
20
|
+
static getSettings(): Settings;
|
|
21
|
+
static getConfigPaths(): Promise<string[]>;
|
|
22
|
+
private static getConfigFile;
|
|
23
|
+
private static loadEnvironmentVars;
|
|
24
|
+
static dumpDependencies(): void;
|
|
25
|
+
static getModuleVersion(name: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve path to a module.
|
|
28
|
+
* @param id The module to require
|
|
29
|
+
* @param [from] Location to start the node resolution
|
|
30
|
+
*/
|
|
31
|
+
private static resolveModulePath;
|
|
16
32
|
static dumpTable(options: {
|
|
17
33
|
columns: string[];
|
|
18
34
|
rows: string[][];
|
|
19
35
|
empty: string;
|
|
20
36
|
}): void;
|
|
37
|
+
/**
|
|
38
|
+
* Tries to register TS support in the following order: swc, tsx, jiti, tsimp
|
|
39
|
+
* Use `MIKRO_ORM_CLI_TS_LOADER` env var to set the loader explicitly.
|
|
40
|
+
* This method is used only in CLI context.
|
|
41
|
+
*/
|
|
42
|
+
static registerTypeScriptSupport(configPath?: string, tsLoader?: 'swc' | 'tsx' | 'jiti' | 'tsimp' | 'auto'): Promise<boolean>;
|
|
43
|
+
static isESM(): boolean;
|
|
21
44
|
static showHelp(): void;
|
|
22
45
|
}
|
|
46
|
+
export interface Settings {
|
|
47
|
+
verbose?: boolean;
|
|
48
|
+
preferTs?: boolean;
|
|
49
|
+
tsLoader?: 'swc' | 'tsx' | 'jiti' | 'tsimp' | 'auto';
|
|
50
|
+
tsConfigPath?: string;
|
|
51
|
+
configPaths?: string[];
|
|
52
|
+
}
|
package/CLIHelper.js
CHANGED
|
@@ -1,27 +1,111 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { extname, join } from 'node:path';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
2
4
|
import yargs from 'yargs';
|
|
3
|
-
import { colors,
|
|
5
|
+
import { colors, Configuration, loadEnvironmentVars, loadOptionalDependencies, MikroORM, Utils, } from '@mikro-orm/core';
|
|
6
|
+
import { fs } from '@mikro-orm/core/fs-utils';
|
|
4
7
|
/**
|
|
5
8
|
* @internal
|
|
6
9
|
*/
|
|
7
10
|
export class CLIHelper {
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Gets a named configuration
|
|
13
|
+
*
|
|
14
|
+
* @param contextName Load a config with the given `contextName` value. Used when config file exports array or factory function. Setting it to "default" matches also config objects without `contextName` set.
|
|
15
|
+
* @param paths Array of possible paths for a configuration file. Files will be checked in order, and the first existing one will be used. Defaults to the output of {@link fs.getConfigPaths}.
|
|
16
|
+
* @param options Additional options to augment the final configuration with.
|
|
17
|
+
*/
|
|
18
|
+
static async getConfiguration(contextName, paths, options = {}) {
|
|
19
|
+
this.commonJSCompat(options);
|
|
20
|
+
paths ??= await this.getConfigPaths();
|
|
21
|
+
const deps = fs.getORMPackages();
|
|
10
22
|
if (!deps.has('@mikro-orm/cli') && !process.env.MIKRO_ORM_ALLOW_GLOBAL_CLI) {
|
|
11
23
|
throw new Error('@mikro-orm/cli needs to be installed as a local dependency!');
|
|
12
24
|
}
|
|
13
|
-
ConfigurationLoader.registerDotenv(options);
|
|
14
|
-
configPaths ??= ConfigurationLoader.getConfigPaths();
|
|
15
25
|
contextName ??= process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default';
|
|
16
|
-
|
|
26
|
+
const env = await this.loadEnvironmentVars();
|
|
27
|
+
await loadOptionalDependencies(options);
|
|
28
|
+
// oxfmt-ignore
|
|
29
|
+
const configFinder = (cfg) => {
|
|
30
|
+
return typeof cfg === 'object' && cfg !== null && ('contextName' in cfg ? cfg.contextName === contextName : contextName === 'default');
|
|
31
|
+
};
|
|
32
|
+
const isValidConfigFactoryResult = (cfg) => {
|
|
33
|
+
return typeof cfg === 'object' && cfg !== null && (!('contextName' in cfg) || cfg.contextName === contextName);
|
|
34
|
+
};
|
|
35
|
+
const result = await this.getConfigFile(paths);
|
|
36
|
+
if (!result[0]) {
|
|
37
|
+
if (Utils.hasObjectKeys(env)) {
|
|
38
|
+
return new Configuration(Utils.mergeConfig({ contextName }, options.preferEnvVars ? options : env, options.preferEnvVars ? env : options));
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`MikroORM config file not found in ['${paths.join(`', '`)}']`);
|
|
41
|
+
}
|
|
42
|
+
const path = result[0];
|
|
43
|
+
let tmp = result[1];
|
|
44
|
+
if (Array.isArray(tmp)) {
|
|
45
|
+
const tmpFirstIndex = tmp.findIndex(configFinder);
|
|
46
|
+
if (tmpFirstIndex === -1) {
|
|
47
|
+
// Static config not found. Try factory functions
|
|
48
|
+
let configCandidate;
|
|
49
|
+
for (let i = 0, l = tmp.length; i < l; ++i) {
|
|
50
|
+
const f = tmp[i];
|
|
51
|
+
if (typeof f !== 'function') {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
configCandidate = await f(contextName);
|
|
55
|
+
if (!isValidConfigFactoryResult(configCandidate)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
tmp = configCandidate;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(tmp)) {
|
|
62
|
+
throw new Error(`MikroORM config '${contextName}' was not found within the config file '${path}'. Either add a config with this name to the array, or add a function that when given this name will return a configuration object without a name, or with name set to this name.`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const tmpLastIndex = tmp.findLastIndex(configFinder);
|
|
67
|
+
if (tmpLastIndex !== tmpFirstIndex) {
|
|
68
|
+
throw new Error(`MikroORM config '${contextName}' is not unique within the array exported by '${path}' (first occurrence index: ${tmpFirstIndex}; last occurrence index: ${tmpLastIndex})`);
|
|
69
|
+
}
|
|
70
|
+
tmp = tmp[tmpFirstIndex];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
if (tmp instanceof Function) {
|
|
75
|
+
tmp = await tmp(contextName);
|
|
76
|
+
if (!isValidConfigFactoryResult(tmp)) {
|
|
77
|
+
throw new Error(`MikroORM config '${contextName}' was not what the function exported from '${path}' provided. Ensure it returns a config object with no name, or name matching the requested one.`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
if (!configFinder(tmp)) {
|
|
82
|
+
throw new Error(`MikroORM config '${contextName}' was not what the default export from '${path}' provided.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const esmConfigOptions = this.isESM() ? { entityGenerator: { esmImport: true } } : {};
|
|
87
|
+
await loadOptionalDependencies(tmp);
|
|
88
|
+
const preferEnvVars = options.preferEnvVars ?? tmp.preferEnvVars;
|
|
89
|
+
return new Configuration(Utils.mergeConfig({}, esmConfigOptions, tmp, preferEnvVars ? options : env, preferEnvVars ? env : options));
|
|
90
|
+
}
|
|
91
|
+
static commonJSCompat(options) {
|
|
92
|
+
if (this.isESM()) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
/* v8 ignore next */
|
|
96
|
+
options.dynamicImportProvider ??=
|
|
97
|
+
globalThis.dynamicImportProvider ??
|
|
98
|
+
((id) => {
|
|
99
|
+
return createRequire(process.cwd())(fileURLToPath(id));
|
|
100
|
+
});
|
|
101
|
+
globalThis.dynamicImportProvider = options.dynamicImportProvider;
|
|
17
102
|
}
|
|
18
103
|
static async getORM(contextName, configPaths, opts = {}) {
|
|
19
|
-
const options = await
|
|
20
|
-
const settings =
|
|
104
|
+
const options = await this.getConfiguration(contextName, configPaths, opts);
|
|
105
|
+
const settings = this.getSettings();
|
|
21
106
|
options.set('allowGlobalContext', true);
|
|
22
107
|
options.set('debug', !!settings.verbose);
|
|
23
108
|
options.getLogger().setDebugMode(!!settings.verbose);
|
|
24
|
-
options.set('connect', false);
|
|
25
109
|
if (settings.preferTs !== false) {
|
|
26
110
|
options.set('preferTs', true);
|
|
27
111
|
}
|
|
@@ -43,9 +127,6 @@ export class CLIHelper {
|
|
|
43
127
|
return false;
|
|
44
128
|
}
|
|
45
129
|
}
|
|
46
|
-
static getNodeVersion() {
|
|
47
|
-
return process.versions.node;
|
|
48
|
-
}
|
|
49
130
|
static getDriverDependencies(config) {
|
|
50
131
|
try {
|
|
51
132
|
return config.getDriver().getDependencies();
|
|
@@ -61,21 +142,97 @@ export class CLIHelper {
|
|
|
61
142
|
// eslint-disable-next-line no-console
|
|
62
143
|
console.log(text);
|
|
63
144
|
}
|
|
64
|
-
static
|
|
65
|
-
|
|
145
|
+
static getSettings() {
|
|
146
|
+
const config = fs.getPackageConfig();
|
|
147
|
+
const settings = { ...config['mikro-orm'] };
|
|
148
|
+
const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
|
|
149
|
+
settings.preferTs =
|
|
150
|
+
process.env.MIKRO_ORM_CLI_PREFER_TS != null ? bool(process.env.MIKRO_ORM_CLI_PREFER_TS) : settings.preferTs;
|
|
151
|
+
settings.tsLoader = process.env.MIKRO_ORM_CLI_TS_LOADER ?? settings.tsLoader;
|
|
152
|
+
settings.tsConfigPath = process.env.MIKRO_ORM_CLI_TS_CONFIG_PATH ?? settings.tsConfigPath;
|
|
153
|
+
settings.verbose =
|
|
154
|
+
process.env.MIKRO_ORM_CLI_VERBOSE != null ? bool(process.env.MIKRO_ORM_CLI_VERBOSE) : settings.verbose;
|
|
155
|
+
if (process.env.MIKRO_ORM_CLI_CONFIG?.endsWith('.ts')) {
|
|
156
|
+
settings.preferTs = true;
|
|
157
|
+
}
|
|
158
|
+
return settings;
|
|
159
|
+
}
|
|
160
|
+
static async getConfigPaths() {
|
|
161
|
+
const settings = this.getSettings();
|
|
162
|
+
const typeScriptSupport = settings.preferTs ?? Utils.detectTypeScriptSupport();
|
|
163
|
+
const paths = [];
|
|
164
|
+
if (process.env.MIKRO_ORM_CLI_CONFIG) {
|
|
165
|
+
paths.push(process.env.MIKRO_ORM_CLI_CONFIG);
|
|
166
|
+
}
|
|
167
|
+
paths.push(...(settings.configPaths || []));
|
|
168
|
+
if (typeScriptSupport) {
|
|
169
|
+
paths.push('./src/mikro-orm.config.ts');
|
|
170
|
+
paths.push('./mikro-orm.config.ts');
|
|
171
|
+
}
|
|
172
|
+
const distDir = fs.pathExists(process.cwd() + '/dist');
|
|
173
|
+
const buildDir = fs.pathExists(process.cwd() + '/build');
|
|
174
|
+
/* v8 ignore next */
|
|
175
|
+
const path = distDir ? 'dist' : buildDir ? 'build' : 'src';
|
|
176
|
+
paths.push(`./${path}/mikro-orm.config.js`);
|
|
177
|
+
paths.push('./mikro-orm.config.js');
|
|
178
|
+
/* v8 ignore next */
|
|
179
|
+
return Utils.unique(paths).filter(p => !/\.[mc]?ts$/.exec(p) || typeScriptSupport);
|
|
180
|
+
}
|
|
181
|
+
static async getConfigFile(paths) {
|
|
182
|
+
for (let path of paths) {
|
|
183
|
+
path = fs.absolutePath(path);
|
|
184
|
+
path = fs.normalizePath(path);
|
|
185
|
+
if (fs.pathExists(path)) {
|
|
186
|
+
const config = await fs.dynamicImport(path);
|
|
187
|
+
/* v8 ignore next */
|
|
188
|
+
return [path, await (config.default ?? config)];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return [];
|
|
66
192
|
}
|
|
67
|
-
static async
|
|
193
|
+
static async loadEnvironmentVars() {
|
|
194
|
+
const ret = loadEnvironmentVars();
|
|
195
|
+
/* v8 ignore next */
|
|
196
|
+
switch (process.env.MIKRO_ORM_TYPE) {
|
|
197
|
+
case 'mongo':
|
|
198
|
+
ret.driver ??= await import('@mikro-orm/sqlite').then(m => m.SqliteDriver);
|
|
199
|
+
break;
|
|
200
|
+
case 'mysql':
|
|
201
|
+
ret.driver ??= await import('@mikro-orm/mysql').then(m => m.MySqlDriver);
|
|
202
|
+
break;
|
|
203
|
+
case 'mssql':
|
|
204
|
+
ret.driver ??= await import('@mikro-orm/mssql').then(m => m.MsSqlDriver);
|
|
205
|
+
break;
|
|
206
|
+
case 'mariadb':
|
|
207
|
+
ret.driver ??= await import('@mikro-orm/mariadb').then(m => m.MariaDbDriver);
|
|
208
|
+
break;
|
|
209
|
+
case 'postgresql':
|
|
210
|
+
ret.driver ??= await import('@mikro-orm/postgresql').then(m => m.PostgreSqlDriver);
|
|
211
|
+
break;
|
|
212
|
+
case 'sqlite':
|
|
213
|
+
ret.driver ??= await import('@mikro-orm/sqlite').then(m => m.SqliteDriver);
|
|
214
|
+
break;
|
|
215
|
+
case 'libsql':
|
|
216
|
+
ret.driver ??= await import('@mikro-orm/libsql').then(m => m.LibSqlDriver);
|
|
217
|
+
break;
|
|
218
|
+
case 'oracledb':
|
|
219
|
+
ret.driver ??= await import('@mikro-orm/oracledb').then(m => m.OracleDriver);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
return ret;
|
|
223
|
+
}
|
|
224
|
+
static dumpDependencies() {
|
|
68
225
|
const version = Utils.getORMVersion();
|
|
69
226
|
CLIHelper.dump(' - dependencies:');
|
|
70
227
|
CLIHelper.dump(` - mikro-orm ${colors.green(version)}`);
|
|
71
|
-
CLIHelper.dump(` - node ${colors.green(
|
|
72
|
-
if (
|
|
73
|
-
/* v8 ignore
|
|
228
|
+
CLIHelper.dump(` - node ${colors.green(process.versions.node)}`);
|
|
229
|
+
if (fs.pathExists(process.cwd() + '/package.json')) {
|
|
230
|
+
/* v8 ignore if */
|
|
74
231
|
if (process.versions.bun) {
|
|
75
232
|
CLIHelper.dump(` - typescript via bun`);
|
|
76
233
|
}
|
|
77
234
|
else {
|
|
78
|
-
CLIHelper.dump(` - typescript ${
|
|
235
|
+
CLIHelper.dump(` - typescript ${CLIHelper.getModuleVersion('typescript')}`);
|
|
79
236
|
}
|
|
80
237
|
CLIHelper.dump(' - package.json ' + colors.green('found'));
|
|
81
238
|
}
|
|
@@ -83,22 +240,31 @@ export class CLIHelper {
|
|
|
83
240
|
CLIHelper.dump(' - package.json ' + colors.red('not found'));
|
|
84
241
|
}
|
|
85
242
|
}
|
|
86
|
-
static
|
|
243
|
+
static getModuleVersion(name) {
|
|
87
244
|
try {
|
|
88
|
-
const
|
|
245
|
+
const path = `${this.resolveModulePath(name)}/package.json`;
|
|
246
|
+
const pkg = fs.readJSONSync(path);
|
|
89
247
|
return colors.green(pkg.version);
|
|
90
248
|
}
|
|
91
249
|
catch {
|
|
92
|
-
|
|
93
|
-
const path = `${Utils.resolveModulePath(name)}/package.json`;
|
|
94
|
-
const pkg = await readFile(path, { encoding: 'utf8' });
|
|
95
|
-
return colors.green(JSON.parse(pkg).version);
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
return '';
|
|
99
|
-
}
|
|
250
|
+
return '';
|
|
100
251
|
}
|
|
101
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Resolve path to a module.
|
|
255
|
+
* @param id The module to require
|
|
256
|
+
* @param [from] Location to start the node resolution
|
|
257
|
+
*/
|
|
258
|
+
static resolveModulePath(id, from = process.cwd()) {
|
|
259
|
+
if (!extname(from)) {
|
|
260
|
+
from = join(from, '__fake.js');
|
|
261
|
+
}
|
|
262
|
+
const path = fs.normalizePath(import.meta.resolve(id, pathToFileURL(from)));
|
|
263
|
+
const parts = path.split('/');
|
|
264
|
+
const idx = parts.lastIndexOf(id) + 1;
|
|
265
|
+
parts.splice(idx, parts.length - idx);
|
|
266
|
+
return parts.join('/');
|
|
267
|
+
}
|
|
102
268
|
static dumpTable(options) {
|
|
103
269
|
if (options.rows.length === 0) {
|
|
104
270
|
return CLIHelper.dump(options.empty);
|
|
@@ -112,15 +278,69 @@ export class CLIHelper {
|
|
|
112
278
|
});
|
|
113
279
|
let ret = '';
|
|
114
280
|
ret += colors.grey('┌' + lengths.map(length => '─'.repeat(length)).join('┬') + '┐\n');
|
|
115
|
-
ret +=
|
|
281
|
+
ret +=
|
|
282
|
+
colors.grey('│') +
|
|
283
|
+
lengths
|
|
284
|
+
.map((length, idx) => ' ' + colors.red(options.columns[idx]) + ' '.repeat(length - options.columns[idx].length - 1))
|
|
285
|
+
.join(colors.grey('│')) +
|
|
286
|
+
colors.grey('│\n');
|
|
116
287
|
ret += colors.grey('├' + lengths.map(length => '─'.repeat(length)).join('┼') + '┤\n');
|
|
117
288
|
options.rows.forEach(row => {
|
|
118
|
-
ret +=
|
|
289
|
+
ret +=
|
|
290
|
+
colors.grey('│') +
|
|
291
|
+
lengths.map((length, idx) => ' ' + row[idx] + ' '.repeat(length - row[idx].length - 1)).join(colors.grey('│')) +
|
|
292
|
+
colors.grey('│\n');
|
|
119
293
|
});
|
|
120
294
|
ret += colors.grey('└' + lengths.map(length => '─'.repeat(length)).join('┴') + '┘');
|
|
121
295
|
CLIHelper.dump(ret);
|
|
122
296
|
}
|
|
123
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Tries to register TS support in the following order: swc, tsx, jiti, tsimp
|
|
299
|
+
* Use `MIKRO_ORM_CLI_TS_LOADER` env var to set the loader explicitly.
|
|
300
|
+
* This method is used only in CLI context.
|
|
301
|
+
*/
|
|
302
|
+
static async registerTypeScriptSupport(configPath = 'tsconfig.json', tsLoader) {
|
|
303
|
+
/* v8 ignore if */
|
|
304
|
+
if (process.versions.bun) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
process.env.SWC_NODE_PROJECT ??= configPath;
|
|
308
|
+
process.env.TSIMP_PROJECT ??= configPath;
|
|
309
|
+
process.env.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS ??= '1';
|
|
310
|
+
const explicitLoader = tsLoader ?? process.env.MIKRO_ORM_CLI_TS_LOADER ?? 'auto';
|
|
311
|
+
const setEsmImportProvider = () => {
|
|
312
|
+
return (globalThis.dynamicImportProvider = (id) => import(id).then(mod => mod?.default ?? mod));
|
|
313
|
+
};
|
|
314
|
+
const loaders = {
|
|
315
|
+
swc: { esm: '@swc-node/register/esm-register', cjs: '@swc-node/register' },
|
|
316
|
+
tsx: { esm: 'tsx/esm/api', cjs: 'tsx/cjs/api', cb: (tsx) => tsx.register({ tsconfig: configPath }) },
|
|
317
|
+
jiti: { cjs: 'jiti/register', cb: setEsmImportProvider },
|
|
318
|
+
tsimp: { cjs: 'tsimp/import', cb: setEsmImportProvider },
|
|
319
|
+
};
|
|
320
|
+
for (const loader of Utils.keys(loaders)) {
|
|
321
|
+
if (explicitLoader !== 'auto' && loader !== explicitLoader) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const { esm, cjs, cb } = loaders[loader];
|
|
325
|
+
const isEsm = this.isESM();
|
|
326
|
+
const module = isEsm && esm ? esm : cjs;
|
|
327
|
+
const mod = await Utils.tryImport({ module });
|
|
328
|
+
if (mod) {
|
|
329
|
+
cb?.(mod);
|
|
330
|
+
process.env.MIKRO_ORM_CLI_TS_LOADER = loader;
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// eslint-disable-next-line no-console
|
|
335
|
+
console.warn('Neither `swc`, `tsx`, `jiti` nor `tsimp` found in the project dependencies, support for working with TypeScript files might not work. To use `swc`, you need to install both `@swc-node/register` and `@swc/core`.');
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
static isESM() {
|
|
339
|
+
const config = fs.getPackageConfig();
|
|
340
|
+
const type = config?.type ?? '';
|
|
341
|
+
return type === 'module';
|
|
342
|
+
}
|
|
343
|
+
/* v8 ignore next */
|
|
124
344
|
static showHelp() {
|
|
125
345
|
yargs(process.argv.slice(2)).showHelp();
|
|
126
346
|
}
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
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
|
|
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.
|
|
6
6
|
|
|
7
7
|
> Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
|
|
8
8
|
|
|
9
|
-
[](https://
|
|
10
|
-
[](https://
|
|
9
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
10
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
|
-
[](https://
|
|
12
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
15
15
|
|
|
@@ -181,6 +181,7 @@ yarn add @mikro-orm/core @mikro-orm/mysql # for mysql/mariadb
|
|
|
181
181
|
yarn add @mikro-orm/core @mikro-orm/mariadb # for mysql/mariadb
|
|
182
182
|
yarn add @mikro-orm/core @mikro-orm/postgresql # for postgresql
|
|
183
183
|
yarn add @mikro-orm/core @mikro-orm/mssql # for mssql
|
|
184
|
+
yarn add @mikro-orm/core @mikro-orm/oracledb # for oracle
|
|
184
185
|
yarn add @mikro-orm/core @mikro-orm/sqlite # for sqlite
|
|
185
186
|
yarn add @mikro-orm/core @mikro-orm/libsql # for libsql
|
|
186
187
|
```
|
|
@@ -381,6 +382,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
|
|
|
381
382
|
|
|
382
383
|
Please ⭐️ this repository if this project helped you!
|
|
383
384
|
|
|
385
|
+
> If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
|
|
386
|
+
|
|
384
387
|
## 📝 License
|
|
385
388
|
|
|
386
389
|
Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
|
package/cli
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { CLIHelper } from './CLIHelper.js';
|
|
3
|
-
import {
|
|
4
|
-
const argv = await
|
|
3
|
+
import { configure } from './CLIConfigurator.js';
|
|
4
|
+
const argv = await configure();
|
|
5
5
|
const args = await argv.parse(process.argv.slice(2));
|
|
6
6
|
if (args._.length === 0) {
|
|
7
7
|
CLIHelper.showHelp();
|
package/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { CLIHelper } from './CLIHelper.js';
|
|
3
|
-
import {
|
|
4
|
-
const argv = await
|
|
3
|
+
import { configure } from './CLIConfigurator.js';
|
|
4
|
+
const argv = await configure();
|
|
5
5
|
const args = await argv.parse(process.argv.slice(2));
|
|
6
6
|
if (args._.length === 0) {
|
|
7
7
|
CLIHelper.showHelp();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ArgumentsCamelCase, Argv } from 'yargs';
|
|
2
|
+
import { MetadataStorage, type Configuration } from '@mikro-orm/core';
|
|
3
|
+
import type { BaseArgs, BaseCommand } from '../CLIConfigurator.js';
|
|
4
|
+
type CompileArgs = BaseArgs & {
|
|
5
|
+
out?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare class CompileCommand implements BaseCommand<CompileArgs> {
|
|
8
|
+
command: string;
|
|
9
|
+
describe: string;
|
|
10
|
+
builder: (args: Argv<BaseArgs>) => Argv<CompileArgs>;
|
|
11
|
+
/**
|
|
12
|
+
* @inheritDoc
|
|
13
|
+
*/
|
|
14
|
+
handler(args: ArgumentsCamelCase<CompileArgs>): Promise<void>;
|
|
15
|
+
static capture(metadata: MetadataStorage, config: Configuration): {
|
|
16
|
+
key: string;
|
|
17
|
+
contextKeys: string[];
|
|
18
|
+
code: string;
|
|
19
|
+
}[];
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { resolve, dirname } from 'node:path';
|
|
3
|
+
import { MetadataDiscovery, MetadataStorage, Utils, EntityComparator, ObjectHydrator, colors, } from '@mikro-orm/core';
|
|
4
|
+
import { fs } from '@mikro-orm/core/fs-utils';
|
|
5
|
+
import { CLIHelper } from '../CLIHelper.js';
|
|
6
|
+
export class CompileCommand {
|
|
7
|
+
command = 'compile';
|
|
8
|
+
describe = 'Pre-compile optimized entity functions for runtimes that prohibit eval (e.g. Cloudflare Workers)';
|
|
9
|
+
builder = (args) => {
|
|
10
|
+
args.option('out', {
|
|
11
|
+
type: 'string',
|
|
12
|
+
desc: 'Output path for the generated file (defaults to next to your ORM config)',
|
|
13
|
+
});
|
|
14
|
+
return args;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* @inheritDoc
|
|
18
|
+
*/
|
|
19
|
+
async handler(args) {
|
|
20
|
+
const config = await CLIHelper.getConfiguration(args.contextName, args.config);
|
|
21
|
+
const settings = CLIHelper.getSettings();
|
|
22
|
+
config.set('debug', !!settings.verbose);
|
|
23
|
+
const metadata = await new MetadataDiscovery(new MetadataStorage(), config.getDriver().getPlatform(), config).discover(false);
|
|
24
|
+
// Default output path to next to the ORM config file
|
|
25
|
+
if (!args.out) {
|
|
26
|
+
const configPaths = args.config ?? (await CLIHelper.getConfigPaths());
|
|
27
|
+
for (const configPath of configPaths) {
|
|
28
|
+
const absPath = fs.absolutePath(configPath);
|
|
29
|
+
if (fs.pathExists(absPath)) {
|
|
30
|
+
args.out = resolve(dirname(absPath), 'compiled-functions.js');
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const captured = CompileCommand.capture(metadata, config);
|
|
36
|
+
const entries = captured.map(({ key, contextKeys, code }) => {
|
|
37
|
+
const params = contextKeys.join(', ');
|
|
38
|
+
const indentedCode = code.replace(/\n/g, '\n ');
|
|
39
|
+
return ` '${key}': function(${params}) {\n ${indentedCode}\n }`;
|
|
40
|
+
});
|
|
41
|
+
const esm = CLIHelper.isESM();
|
|
42
|
+
const version = Utils.getORMVersion();
|
|
43
|
+
const output = esm
|
|
44
|
+
? `export default {\n __version: '${version}',\n${entries.join(',\n')}\n};\n`
|
|
45
|
+
: `'use strict';\nmodule.exports = {\n __version: '${version}',\n${entries.join(',\n')}\n};\n`;
|
|
46
|
+
const outPath = args.out ?? resolve(process.cwd(), 'compiled-functions.js');
|
|
47
|
+
const dtsPath = outPath.replace(/\.js$/, '.d.ts');
|
|
48
|
+
const dts = esm
|
|
49
|
+
? `import type { CompiledFunctions } from '@mikro-orm/core';\ndeclare const compiledFunctions: CompiledFunctions;\nexport default compiledFunctions;\n`
|
|
50
|
+
: `import type { CompiledFunctions } from '@mikro-orm/core';\ndeclare const compiledFunctions: CompiledFunctions;\nexport = compiledFunctions;\n`;
|
|
51
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
52
|
+
writeFileSync(outPath, output);
|
|
53
|
+
writeFileSync(dtsPath, dts);
|
|
54
|
+
CLIHelper.dump(colors.green(`Compiled functions generated to ${outPath} (${captured.length} functions)`));
|
|
55
|
+
CLIHelper.dump(`\nExample usage in your ORM config:\n`);
|
|
56
|
+
const importPath = esm ? './compiled-functions.js' : './compiled-functions';
|
|
57
|
+
CLIHelper.dump(` ${esm ? 'import' : 'const'} compiledFunctions ${esm ? 'from ' : '= require('}${colors.cyan(`'${importPath}'`)}${esm ? '' : ')'};`);
|
|
58
|
+
CLIHelper.dump('');
|
|
59
|
+
CLIHelper.dump(` export default defineConfig({ compiledFunctions });\n`);
|
|
60
|
+
}
|
|
61
|
+
static capture(metadata, config) {
|
|
62
|
+
const captured = [];
|
|
63
|
+
const original = Utils.createFunction;
|
|
64
|
+
Utils.createFunction = (context, code, _compiledFunctions, key) => {
|
|
65
|
+
captured.push({ key: key, contextKeys: [...context.keys()], code });
|
|
66
|
+
return original.call(Utils, context, code);
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
const platform = config.getDriver().getPlatform();
|
|
70
|
+
const hydrator = new ObjectHydrator(metadata, platform, config);
|
|
71
|
+
const comparator = new EntityComparator(metadata, platform, config);
|
|
72
|
+
for (const meta of metadata) {
|
|
73
|
+
hydrator.getEntityHydrator(meta, 'full', false);
|
|
74
|
+
hydrator.getEntityHydrator(meta, 'full', true);
|
|
75
|
+
comparator.getEntityComparator(meta.class);
|
|
76
|
+
comparator.getSnapshotGenerator(meta.class);
|
|
77
|
+
comparator.getResultMapper(meta);
|
|
78
|
+
if (!meta.embeddable && !meta.virtual) {
|
|
79
|
+
hydrator.getEntityHydrator(meta, 'reference', false);
|
|
80
|
+
hydrator.getEntityHydrator(meta, 'reference', true);
|
|
81
|
+
}
|
|
82
|
+
if (meta.primaryKeys.length > 0) {
|
|
83
|
+
comparator.getPkGetter(meta);
|
|
84
|
+
comparator.getPkGetterConverted(meta);
|
|
85
|
+
comparator.getPkSerializer(meta);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
Utils.createFunction = original;
|
|
91
|
+
}
|
|
92
|
+
return captured;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -7,8 +7,7 @@ export class CreateDatabaseCommand {
|
|
|
7
7
|
*/
|
|
8
8
|
async handler(args) {
|
|
9
9
|
const orm = await CLIHelper.getORM(args.contextName, args.config);
|
|
10
|
-
|
|
11
|
-
await schemaGenerator.ensureDatabase();
|
|
10
|
+
await orm.schema.ensureDatabase();
|
|
12
11
|
await orm.close(true);
|
|
13
12
|
}
|
|
14
13
|
}
|
|
@@ -16,8 +16,7 @@ export class CreateSeederCommand {
|
|
|
16
16
|
async handler(args) {
|
|
17
17
|
const className = CreateSeederCommand.getSeederClassName(args.seeder);
|
|
18
18
|
const orm = await CLIHelper.getORM(args.contextName, args.config);
|
|
19
|
-
const
|
|
20
|
-
const path = await seeder.createSeeder(className);
|
|
19
|
+
const path = await orm.seeder.create(className);
|
|
21
20
|
CLIHelper.dump(colors.green(`Seeder ${args.seeder} successfully created at ${path}`));
|
|
22
21
|
await orm.close(true);
|
|
23
22
|
}
|
|
@@ -25,7 +24,7 @@ export class CreateSeederCommand {
|
|
|
25
24
|
* Will return a seeder name that is formatted like this EntitySeeder
|
|
26
25
|
*/
|
|
27
26
|
static getSeederClassName(name) {
|
|
28
|
-
name =
|
|
27
|
+
name = /(.+)seeder/i.exec(name)?.[1] ?? name;
|
|
29
28
|
const parts = name.split('-');
|
|
30
29
|
return parts.map(name => name.charAt(0).toUpperCase() + name.slice(1)).join('') + 'Seeder';
|
|
31
30
|
}
|
|
@@ -17,7 +17,7 @@ export class DatabaseSeedCommand {
|
|
|
17
17
|
async handler(args) {
|
|
18
18
|
const orm = await CLIHelper.getORM(args.contextName, args.config);
|
|
19
19
|
const className = args.class ?? orm.config.get('seeder').defaultSeeder;
|
|
20
|
-
await orm.
|
|
20
|
+
await orm.seeder.seedString(className);
|
|
21
21
|
CLIHelper.dump(colors.green(`Seeder ${className} successfully executed`));
|
|
22
22
|
await orm.close(true);
|
|
23
23
|
}
|
package/commands/DebugCommand.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { colors } from '@mikro-orm/core';
|
|
2
|
+
import { fs } from '@mikro-orm/core/fs-utils';
|
|
2
3
|
import { CLIHelper } from '../CLIHelper.js';
|
|
3
4
|
export class DebugCommand {
|
|
4
5
|
command = 'debug';
|
|
@@ -8,12 +9,13 @@ export class DebugCommand {
|
|
|
8
9
|
*/
|
|
9
10
|
async handler(args) {
|
|
10
11
|
CLIHelper.dump(`Current ${colors.cyan('MikroORM')} CLI configuration`);
|
|
11
|
-
|
|
12
|
-
const settings =
|
|
12
|
+
CLIHelper.dumpDependencies();
|
|
13
|
+
const settings = CLIHelper.getSettings();
|
|
13
14
|
if (!process.versions.bun && settings.preferTs !== false) {
|
|
14
|
-
|
|
15
|
+
const loader = process.env.MIKRO_ORM_CLI_TS_LOADER ?? 'auto';
|
|
16
|
+
CLIHelper.dump(' - TypeScript support ' + colors.green(`enabled (${loader})`));
|
|
15
17
|
}
|
|
16
|
-
const configPaths = args.config ?? CLIHelper.getConfigPaths();
|
|
18
|
+
const configPaths = args.config ?? (await CLIHelper.getConfigPaths());
|
|
17
19
|
CLIHelper.dump(' - searched config paths:');
|
|
18
20
|
await DebugCommand.checkPaths(configPaths, 'yellow');
|
|
19
21
|
CLIHelper.dump(` - searched for config name: ${colors.green(args.contextName)}`);
|
|
@@ -23,7 +25,7 @@ export class DebugCommand {
|
|
|
23
25
|
const drivers = CLIHelper.getDriverDependencies(config);
|
|
24
26
|
CLIHelper.dump(' - driver dependencies:');
|
|
25
27
|
for (const driver of drivers) {
|
|
26
|
-
CLIHelper.dump(` - ${driver} ${
|
|
28
|
+
CLIHelper.dump(` - ${driver} ${CLIHelper.getModuleVersion(driver)}`);
|
|
27
29
|
}
|
|
28
30
|
const isConnected = await CLIHelper.isDBConnected(config, true);
|
|
29
31
|
if (isConnected === true) {
|
|
@@ -39,8 +41,8 @@ export class DebugCommand {
|
|
|
39
41
|
}
|
|
40
42
|
const entities = config.get('entities', []);
|
|
41
43
|
if (entities.length > 0) {
|
|
42
|
-
const refs = entities.filter(p =>
|
|
43
|
-
const paths = entities.filter(p =>
|
|
44
|
+
const refs = entities.filter(p => typeof p !== 'string');
|
|
45
|
+
const paths = entities.filter(p => typeof p === 'string');
|
|
44
46
|
const will = !config.get('preferTs') ? 'will' : 'could';
|
|
45
47
|
CLIHelper.dump(` - ${will} use \`entities\` array (contains ${refs.length} references and ${paths.length} paths)`);
|
|
46
48
|
if (paths.length > 0) {
|
|
@@ -49,8 +51,8 @@ export class DebugCommand {
|
|
|
49
51
|
}
|
|
50
52
|
const entitiesTs = config.get('entitiesTs', []);
|
|
51
53
|
if (entitiesTs.length > 0) {
|
|
52
|
-
const refs = entitiesTs.filter(p =>
|
|
53
|
-
const paths = entitiesTs.filter(p =>
|
|
54
|
+
const refs = entitiesTs.filter(p => typeof p !== 'string');
|
|
55
|
+
const paths = entitiesTs.filter(p => typeof p === 'string');
|
|
54
56
|
/* v8 ignore next */
|
|
55
57
|
const will = config.get('preferTs') ? 'will' : 'could';
|
|
56
58
|
CLIHelper.dump(` - ${will} use \`entitiesTs\` array (contains ${refs.length} references and ${paths.length} paths)`);
|
|
@@ -65,10 +67,9 @@ export class DebugCommand {
|
|
|
65
67
|
}
|
|
66
68
|
static async checkPaths(paths, failedColor, baseDir) {
|
|
67
69
|
for (let path of paths) {
|
|
68
|
-
path =
|
|
69
|
-
path =
|
|
70
|
-
|
|
71
|
-
if (found) {
|
|
70
|
+
path = fs.absolutePath(path, baseDir);
|
|
71
|
+
path = fs.normalizePath(path);
|
|
72
|
+
if (fs.pathExists(path)) {
|
|
72
73
|
CLIHelper.dump(` - ${path} (${colors.green('found')})`);
|
|
73
74
|
}
|
|
74
75
|
else {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { MetadataDiscovery, MetadataStorage, colors
|
|
1
|
+
import { MetadataDiscovery, MetadataStorage, colors } from '@mikro-orm/core';
|
|
2
|
+
import { FileCacheAdapter } from '@mikro-orm/core/fs-utils';
|
|
2
3
|
import { CLIHelper } from '../CLIHelper.js';
|
|
3
4
|
export class GenerateCacheCommand {
|
|
4
5
|
command = 'cache:generate';
|
|
@@ -25,7 +26,7 @@ export class GenerateCacheCommand {
|
|
|
25
26
|
await config.getMetadataCacheAdapter().clear();
|
|
26
27
|
config.set('logger', CLIHelper.dump.bind(null));
|
|
27
28
|
config.set('debug', true);
|
|
28
|
-
const discovery = new MetadataDiscovery(MetadataStorage
|
|
29
|
+
const discovery = new MetadataDiscovery(new MetadataStorage(), config.getDriver().getPlatform(), config);
|
|
29
30
|
await discovery.discover(args.ts ?? false);
|
|
30
31
|
const combined = args.combined && config.get('metadataCache').combined;
|
|
31
32
|
CLIHelper.dump(colors.green(`${combined ? 'Combined ' : ''}${args.ts ? 'TS' : 'JS'} metadata cache was successfully generated${combined ? ' to ' + combined : ''}`));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
1
2
|
import { colors } from '@mikro-orm/core';
|
|
2
3
|
import { CLIHelper } from '../CLIHelper.js';
|
|
3
4
|
export class ImportCommand {
|
|
@@ -8,7 +9,8 @@ export class ImportCommand {
|
|
|
8
9
|
*/
|
|
9
10
|
async handler(args) {
|
|
10
11
|
const orm = await CLIHelper.getORM(args.contextName, args.config, { multipleStatements: true });
|
|
11
|
-
await
|
|
12
|
+
const buf = await readFile(args.file);
|
|
13
|
+
await orm.em.getConnection().executeDump(buf.toString());
|
|
12
14
|
CLIHelper.dump(colors.green(`File ${args.file} successfully imported`));
|
|
13
15
|
await orm.close(true);
|
|
14
16
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Utils,
|
|
1
|
+
import { colors, Utils, } from '@mikro-orm/core';
|
|
2
2
|
import { CLIHelper } from '../CLIHelper.js';
|
|
3
3
|
export class MigrationCommandFactory {
|
|
4
4
|
static DESCRIPTIONS = {
|
|
@@ -11,6 +11,7 @@ export class MigrationCommandFactory {
|
|
|
11
11
|
fresh: 'Clear the database and rerun all migrations',
|
|
12
12
|
};
|
|
13
13
|
static create(command) {
|
|
14
|
+
// oxfmt-ignore
|
|
14
15
|
return {
|
|
15
16
|
command: `migration:${command}`,
|
|
16
17
|
describe: MigrationCommandFactory.DESCRIPTIONS[command],
|
|
@@ -80,26 +81,25 @@ export class MigrationCommandFactory {
|
|
|
80
81
|
// to be able to run have a master transaction, but run marked migrations outside of it, we need a second connection
|
|
81
82
|
const options = { pool: { min: 1, max: 2 } };
|
|
82
83
|
const orm = await CLIHelper.getORM(args.contextName, args.config, options);
|
|
83
|
-
const migrator = orm.getMigrator();
|
|
84
84
|
switch (method) {
|
|
85
85
|
case 'create':
|
|
86
|
-
await this.handleCreateCommand(migrator, args, orm.config);
|
|
86
|
+
await this.handleCreateCommand(orm.migrator, args, orm.config);
|
|
87
87
|
break;
|
|
88
88
|
case 'check':
|
|
89
|
-
await this.handleCheckCommand(migrator, orm);
|
|
89
|
+
await this.handleCheckCommand(orm.migrator, orm);
|
|
90
90
|
break;
|
|
91
91
|
case 'list':
|
|
92
|
-
await this.handleListCommand(migrator);
|
|
92
|
+
await this.handleListCommand(orm.migrator);
|
|
93
93
|
break;
|
|
94
94
|
case 'pending':
|
|
95
|
-
await this.handlePendingCommand(migrator);
|
|
95
|
+
await this.handlePendingCommand(orm.migrator);
|
|
96
96
|
break;
|
|
97
97
|
case 'up':
|
|
98
98
|
case 'down':
|
|
99
|
-
await this.handleUpDownCommand(args, migrator, method);
|
|
99
|
+
await this.handleUpDownCommand(args, orm.migrator, method);
|
|
100
100
|
break;
|
|
101
101
|
case 'fresh':
|
|
102
|
-
await this.handleFreshCommand(args, migrator, orm);
|
|
102
|
+
await this.handleFreshCommand(args, orm.migrator, orm);
|
|
103
103
|
}
|
|
104
104
|
await orm.close(true);
|
|
105
105
|
}
|
|
@@ -121,7 +121,7 @@ export class MigrationCommandFactory {
|
|
|
121
121
|
CLIHelper.dump(colors.green(message));
|
|
122
122
|
}
|
|
123
123
|
static async handlePendingCommand(migrator) {
|
|
124
|
-
const pending = await migrator.
|
|
124
|
+
const pending = await migrator.getPending();
|
|
125
125
|
CLIHelper.dumpTable({
|
|
126
126
|
columns: ['Name'],
|
|
127
127
|
rows: pending.map(row => [row.name]),
|
|
@@ -129,7 +129,7 @@ export class MigrationCommandFactory {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
static async handleListCommand(migrator) {
|
|
132
|
-
const executed = await migrator.
|
|
132
|
+
const executed = await migrator.getExecuted();
|
|
133
133
|
CLIHelper.dumpTable({
|
|
134
134
|
columns: ['Name', 'Executed at'],
|
|
135
135
|
rows: executed.map(row => {
|
|
@@ -141,7 +141,7 @@ export class MigrationCommandFactory {
|
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
static async handleCreateCommand(migrator, args, config) {
|
|
144
|
-
const ret = await migrator.
|
|
144
|
+
const ret = await migrator.create(args.path, args.blank, args.initial, args.name);
|
|
145
145
|
if (ret.diff.up.length === 0) {
|
|
146
146
|
return CLIHelper.dump(colors.green(`No changes required, schema is up-to-date`));
|
|
147
147
|
}
|
|
@@ -149,19 +149,20 @@ export class MigrationCommandFactory {
|
|
|
149
149
|
CLIHelper.dump(colors.green('Creating migration with following queries:'));
|
|
150
150
|
CLIHelper.dump(colors.green('up:'));
|
|
151
151
|
CLIHelper.dump(ret.diff.up.map(sql => ' ' + sql).join('\n'), config);
|
|
152
|
-
/* v8 ignore
|
|
152
|
+
/* v8 ignore if */
|
|
153
153
|
if (config.getDriver().getPlatform().supportsDownMigrations()) {
|
|
154
154
|
CLIHelper.dump(colors.green('down:'));
|
|
155
155
|
CLIHelper.dump(ret.diff.down.map(sql => ' ' + sql).join('\n'), config);
|
|
156
156
|
}
|
|
157
157
|
else {
|
|
158
|
+
/* v8 ignore next */
|
|
158
159
|
CLIHelper.dump(colors.yellow(`(${config.getDriver().constructor.name} does not support automatic down migrations)`));
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
CLIHelper.dump(colors.green(`${ret.fileName} successfully created`));
|
|
162
163
|
}
|
|
163
164
|
static async handleCheckCommand(migrator, orm) {
|
|
164
|
-
if (!(await migrator.
|
|
165
|
+
if (!(await migrator.checkSchema())) {
|
|
165
166
|
return CLIHelper.dump(colors.green(`No changes required, schema is up-to-date`));
|
|
166
167
|
}
|
|
167
168
|
await orm.close(true);
|
|
@@ -169,17 +170,15 @@ export class MigrationCommandFactory {
|
|
|
169
170
|
process.exit(1);
|
|
170
171
|
}
|
|
171
172
|
static async handleFreshCommand(args, migrator, orm) {
|
|
172
|
-
|
|
173
|
-
await generator.dropSchema({ dropMigrationsTable: true, dropDb: args.dropDb });
|
|
173
|
+
await orm.schema.drop({ dropMigrationsTable: true, dropDb: args.dropDb });
|
|
174
174
|
CLIHelper.dump(colors.green('Dropped schema successfully'));
|
|
175
175
|
const opts = MigrationCommandFactory.getUpDownOptions(args);
|
|
176
176
|
await migrator.up(opts);
|
|
177
177
|
const message = this.getUpDownSuccessMessage('up', opts);
|
|
178
178
|
CLIHelper.dump(colors.green(message));
|
|
179
179
|
if (args.seed !== undefined) {
|
|
180
|
-
const seeder = orm.getSeeder();
|
|
181
180
|
const seederClass = args.seed || orm.config.get('seeder').defaultSeeder;
|
|
182
|
-
await seeder.seedString(seederClass);
|
|
181
|
+
await orm.seeder.seedString(seederClass);
|
|
183
182
|
CLIHelper.dump(colors.green(`Database seeded successfully with seeder class ${seederClass}`));
|
|
184
183
|
}
|
|
185
184
|
}
|
|
@@ -188,7 +187,7 @@ export class MigrationCommandFactory {
|
|
|
188
187
|
return { migrations: flags.only.split(/[, ]+/) };
|
|
189
188
|
}
|
|
190
189
|
const ret = {};
|
|
191
|
-
['from', 'to'].filter(k => flags[k]).forEach(k => ret[k] = flags[k] === '0' ? 0 : flags[k]);
|
|
190
|
+
['from', 'to'].filter(k => flags[k]).forEach(k => (ret[k] = flags[k] === '0' ? 0 : flags[k]));
|
|
192
191
|
return ret;
|
|
193
192
|
}
|
|
194
193
|
static getUpDownSuccessMessage(method, options) {
|
|
@@ -203,10 +202,10 @@ export class MigrationCommandFactory {
|
|
|
203
202
|
if (method === 'up' && Utils.isEmpty(options)) {
|
|
204
203
|
return msg + ' to the latest version';
|
|
205
204
|
}
|
|
206
|
-
if (
|
|
205
|
+
if (typeof options.to === 'string') {
|
|
207
206
|
return msg + ' to version ' + options.to;
|
|
208
207
|
}
|
|
209
|
-
if (options.migrations
|
|
208
|
+
if (options.migrations?.length === 1) {
|
|
210
209
|
return msg + ' to version ' + options.migrations[0];
|
|
211
210
|
}
|
|
212
211
|
return msg;
|
|
@@ -80,12 +80,11 @@ export class SchemaCommandFactory {
|
|
|
80
80
|
return CLIHelper.showHelp();
|
|
81
81
|
}
|
|
82
82
|
const orm = await CLIHelper.getORM(args.contextName, args.config);
|
|
83
|
-
const generator = orm.getSchemaGenerator();
|
|
84
83
|
const params = { wrap: args.fkChecks == null ? undefined : !args.fkChecks, ...args };
|
|
85
84
|
if (args.dump) {
|
|
86
|
-
const m = `get${method.
|
|
87
|
-
const dump = await
|
|
88
|
-
/* v8 ignore
|
|
85
|
+
const m = `get${method.substring(0, 1).toUpperCase()}${method.substring(1)}SchemaSQL`;
|
|
86
|
+
const dump = await orm.schema[m](params);
|
|
87
|
+
/* v8 ignore if */
|
|
89
88
|
if (dump) {
|
|
90
89
|
CLIHelper.dump(dump, orm.config);
|
|
91
90
|
successMessage = '';
|
|
@@ -95,16 +94,13 @@ export class SchemaCommandFactory {
|
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
else if (method === 'fresh') {
|
|
98
|
-
await
|
|
99
|
-
await generator.createSchema(params);
|
|
97
|
+
await orm.schema.refresh(params);
|
|
100
98
|
}
|
|
101
99
|
else {
|
|
102
|
-
|
|
103
|
-
await generator[m](params);
|
|
100
|
+
await orm.schema[method](params);
|
|
104
101
|
}
|
|
105
102
|
if (typeof args.seed !== 'undefined') {
|
|
106
|
-
|
|
107
|
-
await seeder.seedString(args.seed || orm.config.get('seeder').defaultSeeder);
|
|
103
|
+
await orm.seeder.seedString(args.seed || orm.config.get('seeder').defaultSeeder);
|
|
108
104
|
}
|
|
109
105
|
CLIHelper.dump(colors.green(successMessage));
|
|
110
106
|
await orm.close(true);
|
package/package.json
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/cli",
|
|
3
|
-
"
|
|
4
|
-
"version": "7.0.0-dev.33",
|
|
3
|
+
"version": "7.0.0-dev.331",
|
|
5
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.",
|
|
6
|
-
"exports": {
|
|
7
|
-
"./package.json": "./package.json",
|
|
8
|
-
".": "./index.js"
|
|
9
|
-
},
|
|
10
|
-
"repository": {
|
|
11
|
-
"type": "git",
|
|
12
|
-
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
|
|
13
|
-
},
|
|
14
5
|
"keywords": [
|
|
15
|
-
"
|
|
6
|
+
"data-mapper",
|
|
7
|
+
"ddd",
|
|
8
|
+
"entity",
|
|
9
|
+
"identity-map",
|
|
10
|
+
"javascript",
|
|
11
|
+
"js",
|
|
12
|
+
"mariadb",
|
|
13
|
+
"mikro-orm",
|
|
16
14
|
"mongo",
|
|
17
15
|
"mongodb",
|
|
18
16
|
"mysql",
|
|
19
|
-
"
|
|
17
|
+
"orm",
|
|
20
18
|
"postgresql",
|
|
21
19
|
"sqlite",
|
|
22
20
|
"sqlite3",
|
|
23
21
|
"ts",
|
|
24
22
|
"typescript",
|
|
25
|
-
"
|
|
26
|
-
"javascript",
|
|
27
|
-
"entity",
|
|
28
|
-
"ddd",
|
|
29
|
-
"mikro-orm",
|
|
30
|
-
"unit-of-work",
|
|
31
|
-
"data-mapper",
|
|
32
|
-
"identity-map"
|
|
23
|
+
"unit-of-work"
|
|
33
24
|
],
|
|
34
|
-
"
|
|
35
|
-
"license": "MIT",
|
|
25
|
+
"homepage": "https://mikro-orm.io",
|
|
36
26
|
"bugs": {
|
|
37
27
|
"url": "https://github.com/mikro-orm/mikro-orm/issues"
|
|
38
28
|
},
|
|
39
|
-
"
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"author": "Martin Adámek",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
|
|
34
|
+
},
|
|
40
35
|
"bin": {
|
|
41
36
|
"mikro-orm": "./cli"
|
|
42
37
|
},
|
|
43
|
-
"
|
|
44
|
-
|
|
38
|
+
"type": "module",
|
|
39
|
+
"exports": {
|
|
40
|
+
"./package.json": "./package.json",
|
|
41
|
+
".": "./index.js"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
|
-
"build": "yarn
|
|
47
|
+
"build": "yarn compile && yarn copy",
|
|
48
48
|
"clean": "yarn run -T rimraf ./dist",
|
|
49
49
|
"compile": "yarn run -T tsc -p tsconfig.build.json",
|
|
50
50
|
"copy": "node ../../scripts/copy.mjs"
|
|
51
51
|
},
|
|
52
|
-
"publishConfig": {
|
|
53
|
-
"access": "public"
|
|
54
|
-
},
|
|
55
52
|
"dependencies": {
|
|
56
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
57
|
-
"
|
|
53
|
+
"@mikro-orm/core": "7.0.0-dev.331",
|
|
54
|
+
"mikro-orm": "7.0.0-dev.331",
|
|
58
55
|
"yargs": "17.7.2"
|
|
59
56
|
},
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"@mikro-orm/migrations": "^6.5.7",
|
|
63
|
-
"@mikro-orm/seeder": "^6.5.7"
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">= 22.17.0"
|
|
64
59
|
}
|
|
65
60
|
}
|