@mikro-orm/cli 7.0.0-dev.1 → 7.0.0-dev.100

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.
@@ -1,21 +1,21 @@
1
- import yargs, { type CommandModule } from 'yargs';
1
+ import { type CommandModule } from 'yargs';
2
2
  /**
3
3
  * @internal
4
4
  */
5
- export type BaseArgs = Awaited<ReturnType<typeof CLIConfigurator['createBasicConfig']>['argv']>;
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
- * @internal
13
- */
14
- export declare class CLIConfigurator {
15
- private static createBasicConfig;
16
- static configure(): yargs.Argv<{
17
- config: string[] | undefined;
18
- } & {
19
- contextName: string;
20
- }>;
21
- }
11
+ declare function createBasicConfig(): import("yargs").Argv<{
12
+ config: string[] | undefined;
13
+ } & {
14
+ contextName: string;
15
+ }>;
16
+ export declare function configure(): Promise<import("yargs").Argv<{
17
+ config: string[] | undefined;
18
+ } & {
19
+ contextName: string;
20
+ }>>;
21
+ export {};
@@ -1,78 +1,71 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CLIConfigurator = void 0;
7
- const core_1 = require("@mikro-orm/core");
8
- const yargs_1 = __importDefault(require("yargs"));
9
- const ClearCacheCommand_1 = require("./commands/ClearCacheCommand");
10
- const CreateDatabaseCommand_1 = require("./commands/CreateDatabaseCommand");
11
- const CreateSeederCommand_1 = require("./commands/CreateSeederCommand");
12
- const DatabaseSeedCommand_1 = require("./commands/DatabaseSeedCommand");
13
- const DebugCommand_1 = require("./commands/DebugCommand");
14
- const GenerateCacheCommand_1 = require("./commands/GenerateCacheCommand");
15
- const GenerateEntitiesCommand_1 = require("./commands/GenerateEntitiesCommand");
16
- const ImportCommand_1 = require("./commands/ImportCommand");
17
- const MigrationCommandFactory_1 = require("./commands/MigrationCommandFactory");
18
- const SchemaCommandFactory_1 = require("./commands/SchemaCommandFactory");
19
- /**
20
- * @internal
21
- */
22
- class CLIConfigurator {
23
- static createBasicConfig() {
24
- return yargs_1.default
25
- .scriptName('mikro-orm')
26
- .usage('Usage: $0 <command> [options]')
27
- .example('$0 schema:update --run', 'Runs schema synchronization')
28
- .option('config', {
29
- type: 'string',
30
- array: true,
31
- desc: `Set path to the ORM configuration file`,
32
- })
33
- .option('contextName', {
34
- alias: 'context',
35
- type: 'string',
36
- desc: 'Set name of config to load out of the ORM configuration file. Used when config file exports an array or a function',
37
- default: process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default',
38
- })
39
- .alias('v', 'version')
40
- .alias('h', 'help')
41
- .recommendCommands()
42
- .strict();
43
- }
44
- static configure() {
45
- core_1.ConfigurationLoader.checkPackageVersion();
46
- const settings = core_1.ConfigurationLoader.getSettings();
47
- const version = core_1.Utils.getORMVersion();
48
- if (settings.useTsNode !== false) {
49
- const preferTs = core_1.ConfigurationLoader.registerTsNode(settings.tsConfigPath);
50
- /* istanbul ignore if */
51
- if (!preferTs) {
52
- process.env.MIKRO_ORM_CLI_USE_TS_NODE ??= '0';
53
- }
1
+ import { Utils } from '@mikro-orm/core';
2
+ import { fs } from '@mikro-orm/core/fs-utils';
3
+ import yargs from 'yargs';
4
+ import { ClearCacheCommand } from './commands/ClearCacheCommand.js';
5
+ import { CreateDatabaseCommand } from './commands/CreateDatabaseCommand.js';
6
+ import { CreateSeederCommand } from './commands/CreateSeederCommand.js';
7
+ import { DatabaseSeedCommand } from './commands/DatabaseSeedCommand.js';
8
+ import { DebugCommand } from './commands/DebugCommand.js';
9
+ import { GenerateCacheCommand } from './commands/GenerateCacheCommand.js';
10
+ import { GenerateEntitiesCommand } from './commands/GenerateEntitiesCommand.js';
11
+ import { ImportCommand } from './commands/ImportCommand.js';
12
+ import { MigrationCommandFactory } from './commands/MigrationCommandFactory.js';
13
+ import { SchemaCommandFactory } from './commands/SchemaCommandFactory.js';
14
+ import { CLIHelper } from './CLIHelper.js';
15
+ function createBasicConfig() {
16
+ return yargs()
17
+ .scriptName('mikro-orm')
18
+ .usage('Usage: $0 <command> [options]')
19
+ .example('$0 debug', 'Show debugging information')
20
+ .example('$0 schema:update --run', 'Runs schema synchronization')
21
+ .option('config', {
22
+ type: 'string',
23
+ array: true,
24
+ desc: `Set path to the ORM configuration file`,
25
+ })
26
+ .option('contextName', {
27
+ alias: 'context',
28
+ type: 'string',
29
+ desc: 'Set name of config to load out of the ORM configuration file. Used when config file exports an array or a function',
30
+ default: process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default',
31
+ })
32
+ .alias('v', 'version')
33
+ .alias('h', 'help')
34
+ .recommendCommands()
35
+ .showHelpOnFail(true)
36
+ .demandCommand(1, '')
37
+ .strict();
38
+ }
39
+ export async function configure() {
40
+ fs.checkPackageVersion();
41
+ const settings = CLIHelper.getSettings();
42
+ const version = Utils.getORMVersion();
43
+ if (settings.preferTs !== false) {
44
+ const preferTs = await CLIHelper.registerTypeScriptSupport(settings.tsConfigPath, settings.tsLoader);
45
+ /* v8 ignore next */
46
+ if (!preferTs) {
47
+ process.env.MIKRO_ORM_CLI_PREFER_TS ??= '0';
54
48
  }
55
- return CLIConfigurator.createBasicConfig()
56
- .version(version)
57
- .command(new ClearCacheCommand_1.ClearCacheCommand())
58
- .command(new GenerateCacheCommand_1.GenerateCacheCommand())
59
- .command(new GenerateEntitiesCommand_1.GenerateEntitiesCommand())
60
- .command(new CreateDatabaseCommand_1.CreateDatabaseCommand())
61
- .command(new ImportCommand_1.ImportCommand())
62
- .command(new DatabaseSeedCommand_1.DatabaseSeedCommand())
63
- .command(new CreateSeederCommand_1.CreateSeederCommand())
64
- .command(SchemaCommandFactory_1.SchemaCommandFactory.create('create'))
65
- .command(SchemaCommandFactory_1.SchemaCommandFactory.create('drop'))
66
- .command(SchemaCommandFactory_1.SchemaCommandFactory.create('update'))
67
- .command(SchemaCommandFactory_1.SchemaCommandFactory.create('fresh'))
68
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('create'))
69
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('up'))
70
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('down'))
71
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('list'))
72
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('check'))
73
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('pending'))
74
- .command(MigrationCommandFactory_1.MigrationCommandFactory.create('fresh'))
75
- .command(new DebugCommand_1.DebugCommand());
76
49
  }
50
+ return createBasicConfig()
51
+ .version(version)
52
+ .command(new ClearCacheCommand())
53
+ .command(new GenerateCacheCommand())
54
+ .command(new GenerateEntitiesCommand())
55
+ .command(new CreateDatabaseCommand())
56
+ .command(new ImportCommand())
57
+ .command(new DatabaseSeedCommand())
58
+ .command(new CreateSeederCommand())
59
+ .command(SchemaCommandFactory.create('create'))
60
+ .command(SchemaCommandFactory.create('drop'))
61
+ .command(SchemaCommandFactory.create('update'))
62
+ .command(SchemaCommandFactory.create('fresh'))
63
+ .command(MigrationCommandFactory.create('create'))
64
+ .command(MigrationCommandFactory.create('up'))
65
+ .command(MigrationCommandFactory.create('down'))
66
+ .command(MigrationCommandFactory.create('list'))
67
+ .command(MigrationCommandFactory.create('check'))
68
+ .command(MigrationCommandFactory.create('pending'))
69
+ .command(MigrationCommandFactory.create('fresh'))
70
+ .command(new DebugCommand());
77
71
  }
78
- exports.CLIConfigurator = CLIConfigurator;
package/CLIHelper.d.ts CHANGED
@@ -1,22 +1,52 @@
1
- import { MikroORM, type Configuration, type IDatabaseDriver, type Options } from '@mikro-orm/core';
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
- static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver>(contextName?: string, configPaths?: string[], options?: Partial<Options<D>>): Promise<Configuration<D>>;
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 getConfigPaths(): string[];
14
- static dumpDependencies(): Promise<void>;
15
- static getModuleVersion(name: string): Promise<string>;
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,35 +1,108 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CLIHelper = void 0;
7
- const fs_extra_1 = require("fs-extra");
8
- const yargs_1 = __importDefault(require("yargs"));
9
- const core_1 = require("@mikro-orm/core");
1
+ import { extname, join } from 'node:path';
2
+ import { createRequire } from 'node:module';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
4
+ import yargs from 'yargs';
5
+ import { colors, Configuration, loadEnvironmentVars, lookupExtensions, MikroORM, Utils, } from '@mikro-orm/core';
6
+ import { fs } from '@mikro-orm/core/fs-utils';
10
7
  /**
11
8
  * @internal
12
9
  */
13
- class CLIHelper {
14
- static async getConfiguration(contextName, configPaths, options = {}) {
15
- const deps = core_1.ConfigurationLoader.getORMPackages();
10
+ export class CLIHelper {
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();
16
22
  if (!deps.has('@mikro-orm/cli') && !process.env.MIKRO_ORM_ALLOW_GLOBAL_CLI) {
17
23
  throw new Error('@mikro-orm/cli needs to be installed as a local dependency!');
18
24
  }
19
- core_1.ConfigurationLoader.commonJSCompat(options);
20
- core_1.ConfigurationLoader.registerDotenv(options);
21
- configPaths ??= core_1.ConfigurationLoader.getConfigPaths();
22
25
  contextName ??= process.env.MIKRO_ORM_CONTEXT_NAME ?? 'default';
23
- return core_1.ConfigurationLoader.getConfiguration(contextName, configPaths, options);
26
+ const env = await this.loadEnvironmentVars();
27
+ await lookupExtensions(options);
28
+ const configFinder = (cfg) => {
29
+ return typeof cfg === 'object' && cfg !== null && ('contextName' in cfg ? cfg.contextName === contextName : (contextName === 'default'));
30
+ };
31
+ const isValidConfigFactoryResult = (cfg) => {
32
+ return typeof cfg === 'object' && cfg !== null && (!('contextName' in cfg) || cfg.contextName === contextName);
33
+ };
34
+ const result = await this.getConfigFile(paths);
35
+ if (!result[0]) {
36
+ if (Utils.hasObjectKeys(env)) {
37
+ return new Configuration(Utils.mergeConfig({ contextName }, options, env));
38
+ }
39
+ throw new Error(`MikroORM config file not found in ['${paths.join(`', '`)}']`);
40
+ }
41
+ const path = result[0];
42
+ let tmp = result[1];
43
+ if (Array.isArray(tmp)) {
44
+ const tmpFirstIndex = tmp.findIndex(configFinder);
45
+ if (tmpFirstIndex === -1) {
46
+ // Static config not found. Try factory functions
47
+ let configCandidate;
48
+ for (let i = 0, l = tmp.length; i < l; ++i) {
49
+ const f = tmp[i];
50
+ if (typeof f !== 'function') {
51
+ continue;
52
+ }
53
+ configCandidate = await f(contextName);
54
+ if (!isValidConfigFactoryResult(configCandidate)) {
55
+ continue;
56
+ }
57
+ tmp = configCandidate;
58
+ break;
59
+ }
60
+ if (Array.isArray(tmp)) {
61
+ 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.`);
62
+ }
63
+ }
64
+ else {
65
+ const tmpLastIndex = tmp.findLastIndex(configFinder);
66
+ if (tmpLastIndex !== tmpFirstIndex) {
67
+ throw new Error(`MikroORM config '${contextName}' is not unique within the array exported by '${path}' (first occurrence index: ${tmpFirstIndex}; last occurrence index: ${tmpLastIndex})`);
68
+ }
69
+ tmp = tmp[tmpFirstIndex];
70
+ }
71
+ }
72
+ else {
73
+ if (tmp instanceof Function) {
74
+ tmp = await tmp(contextName);
75
+ if (!isValidConfigFactoryResult(tmp)) {
76
+ 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.`);
77
+ }
78
+ }
79
+ else {
80
+ if (!configFinder(tmp)) {
81
+ throw new Error(`MikroORM config '${contextName}' was not what the default export from '${path}' provided.`);
82
+ }
83
+ }
84
+ }
85
+ const esmConfigOptions = this.isESM() ? { entityGenerator: { esmImport: true } } : {};
86
+ await lookupExtensions(tmp);
87
+ return new Configuration(Utils.mergeConfig({}, esmConfigOptions, tmp, options, env));
88
+ }
89
+ static commonJSCompat(options) {
90
+ if (this.isESM()) {
91
+ return;
92
+ }
93
+ /* v8 ignore next */
94
+ Utils.dynamicImportProvider = options.dynamicImportProvider ??= id => {
95
+ id = fileURLToPath(id);
96
+ return createRequire(process.cwd())(id);
97
+ };
24
98
  }
25
99
  static async getORM(contextName, configPaths, opts = {}) {
26
- const options = await CLIHelper.getConfiguration(contextName, configPaths, opts);
27
- const settings = core_1.ConfigurationLoader.getSettings();
100
+ const options = await this.getConfiguration(contextName, configPaths, opts);
101
+ const settings = this.getSettings();
28
102
  options.set('allowGlobalContext', true);
29
103
  options.set('debug', !!settings.verbose);
30
104
  options.getLogger().setDebugMode(!!settings.verbose);
31
- options.set('connect', false);
32
- if (settings.useTsNode !== false) {
105
+ if (settings.preferTs !== false) {
33
106
  options.set('preferTs', true);
34
107
  }
35
108
  // The only times when we don't care to have a warning about no entities is also the time when we ignore entities.
@@ -37,7 +110,7 @@ class CLIHelper {
37
110
  options.set('entities', []);
38
111
  options.set('entitiesTs', []);
39
112
  }
40
- return core_1.MikroORM.init(options.getAll());
113
+ return MikroORM.init(options.getAll());
41
114
  }
42
115
  static async isDBConnected(config, reason = false) {
43
116
  try {
@@ -50,9 +123,6 @@ class CLIHelper {
50
123
  return false;
51
124
  }
52
125
  }
53
- static getNodeVersion() {
54
- return process.versions.node;
55
- }
56
126
  static getDriverDependencies(config) {
57
127
  try {
58
128
  return config.getDriver().getDependencies();
@@ -68,36 +138,123 @@ class CLIHelper {
68
138
  // eslint-disable-next-line no-console
69
139
  console.log(text);
70
140
  }
71
- static getConfigPaths() {
72
- return core_1.ConfigurationLoader.getConfigPaths();
141
+ static getSettings() {
142
+ const config = fs.getPackageConfig();
143
+ const settings = { ...config['mikro-orm'] };
144
+ const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
145
+ settings.preferTs = process.env.MIKRO_ORM_CLI_PREFER_TS != null ? bool(process.env.MIKRO_ORM_CLI_PREFER_TS) : settings.preferTs;
146
+ settings.tsLoader = process.env.MIKRO_ORM_CLI_TS_LOADER ?? settings.tsLoader;
147
+ settings.tsConfigPath = process.env.MIKRO_ORM_CLI_TS_CONFIG_PATH ?? settings.tsConfigPath;
148
+ settings.verbose = process.env.MIKRO_ORM_CLI_VERBOSE != null ? bool(process.env.MIKRO_ORM_CLI_VERBOSE) : settings.verbose;
149
+ if (process.env.MIKRO_ORM_CLI_CONFIG?.endsWith('.ts')) {
150
+ settings.preferTs = true;
151
+ }
152
+ return settings;
153
+ }
154
+ static async getConfigPaths() {
155
+ const settings = this.getSettings();
156
+ const typeScriptSupport = settings.preferTs ?? Utils.detectTypeScriptSupport();
157
+ const paths = [];
158
+ if (process.env.MIKRO_ORM_CLI_CONFIG) {
159
+ paths.push(process.env.MIKRO_ORM_CLI_CONFIG);
160
+ }
161
+ paths.push(...(settings.configPaths || []));
162
+ if (typeScriptSupport) {
163
+ paths.push('./src/mikro-orm.config.ts');
164
+ paths.push('./mikro-orm.config.ts');
165
+ }
166
+ const distDir = fs.pathExists(process.cwd() + '/dist');
167
+ const buildDir = fs.pathExists(process.cwd() + '/build');
168
+ /* v8 ignore next */
169
+ const path = distDir ? 'dist' : (buildDir ? 'build' : 'src');
170
+ paths.push(`./${path}/mikro-orm.config.js`);
171
+ paths.push('./mikro-orm.config.js');
172
+ /* v8 ignore next */
173
+ return Utils.unique(paths).filter(p => !p.match(/\.[mc]?ts$/) || typeScriptSupport);
174
+ }
175
+ static async getConfigFile(paths) {
176
+ for (let path of paths) {
177
+ path = Utils.absolutePath(path);
178
+ path = Utils.normalizePath(path);
179
+ if (fs.pathExists(path)) {
180
+ const config = await Utils.dynamicImport(path);
181
+ /* v8 ignore next */
182
+ return [path, await (config.default ?? config)];
183
+ }
184
+ }
185
+ return [];
186
+ }
187
+ static async loadEnvironmentVars() {
188
+ const ret = loadEnvironmentVars();
189
+ /* v8 ignore next */
190
+ switch (process.env.MIKRO_ORM_TYPE) {
191
+ case 'mongo':
192
+ ret.driver ??= await import('@mikro-orm/sqlite').then(m => m.SqliteDriver);
193
+ break;
194
+ case 'mysql':
195
+ ret.driver ??= await import('@mikro-orm/mysql').then(m => m.MySqlDriver);
196
+ break;
197
+ case 'mssql':
198
+ ret.driver ??= await import('@mikro-orm/mssql').then(m => m.MsSqlDriver);
199
+ break;
200
+ case 'mariadb':
201
+ ret.driver ??= await import('@mikro-orm/mariadb').then(m => m.MariaDbDriver);
202
+ break;
203
+ case 'postgresql':
204
+ ret.driver ??= await import('@mikro-orm/postgresql').then(m => m.PostgreSqlDriver);
205
+ break;
206
+ case 'sqlite':
207
+ ret.driver ??= await import('@mikro-orm/sqlite').then(m => m.SqliteDriver);
208
+ break;
209
+ case 'libsql':
210
+ ret.driver ??= await import('@mikro-orm/libsql').then(m => m.LibSqlDriver);
211
+ break;
212
+ }
213
+ return ret;
73
214
  }
74
- static async dumpDependencies() {
75
- const version = core_1.Utils.getORMVersion();
215
+ static dumpDependencies() {
216
+ const version = Utils.getORMVersion();
76
217
  CLIHelper.dump(' - dependencies:');
77
- CLIHelper.dump(` - mikro-orm ${core_1.colors.green(version)}`);
78
- CLIHelper.dump(` - node ${core_1.colors.green(CLIHelper.getNodeVersion())}`);
79
- if ((0, fs_extra_1.pathExistsSync)(process.cwd() + '/package.json')) {
80
- /* istanbul ignore next */
218
+ CLIHelper.dump(` - mikro-orm ${colors.green(version)}`);
219
+ CLIHelper.dump(` - node ${colors.green(process.versions.node)}`);
220
+ if (fs.pathExists(process.cwd() + '/package.json')) {
221
+ /* v8 ignore if */
81
222
  if (process.versions.bun) {
82
223
  CLIHelper.dump(` - typescript via bun`);
83
224
  }
84
225
  else {
85
- CLIHelper.dump(` - typescript ${await CLIHelper.getModuleVersion('typescript')}`);
226
+ CLIHelper.dump(` - typescript ${CLIHelper.getModuleVersion('typescript')}`);
86
227
  }
87
- CLIHelper.dump(' - package.json ' + core_1.colors.green('found'));
228
+ CLIHelper.dump(' - package.json ' + colors.green('found'));
88
229
  }
89
230
  else {
90
- CLIHelper.dump(' - package.json ' + core_1.colors.red('not found'));
231
+ CLIHelper.dump(' - package.json ' + colors.red('not found'));
91
232
  }
92
233
  }
93
- static async getModuleVersion(name) {
234
+ static getModuleVersion(name) {
94
235
  try {
95
- const pkg = core_1.Utils.requireFrom(`${name}/package.json`);
96
- return core_1.colors.green(pkg.version);
236
+ const path = `${this.resolveModulePath(name)}/package.json`;
237
+ const pkg = fs.readJSONSync(path);
238
+ return colors.green(pkg.version);
97
239
  }
98
240
  catch {
99
- return core_1.colors.red('not-found');
241
+ return '';
242
+ }
243
+ }
244
+ /**
245
+ * Resolve path to a module.
246
+ * @param id The module to require
247
+ * @param [from] Location to start the node resolution
248
+ */
249
+ static resolveModulePath(id, from = process.cwd()) {
250
+ if (!extname(from)) {
251
+ from = join(from, '__fake.js');
100
252
  }
253
+ const path = Utils.normalizePath(import.meta.resolve(id, pathToFileURL(from)));
254
+ const parts = path.split('/');
255
+ const idx = parts.lastIndexOf(id) + 1;
256
+ parts.splice(idx, parts.length - idx);
257
+ return parts.join('/');
101
258
  }
102
259
  static dumpTable(options) {
103
260
  if (options.rows.length === 0) {
@@ -111,18 +268,61 @@ class CLIHelper {
111
268
  });
112
269
  });
113
270
  let ret = '';
114
- ret += core_1.colors.grey('┌' + lengths.map(length => '─'.repeat(length)).join('┬') + '┐\n');
115
- ret += core_1.colors.grey('│') + lengths.map((length, idx) => ' ' + core_1.colors.red(options.columns[idx]) + ' '.repeat(length - options.columns[idx].length - 1)).join(core_1.colors.grey('│')) + core_1.colors.grey('│\n');
116
- ret += core_1.colors.grey('├' + lengths.map(length => '─'.repeat(length)).join('┼') + '┤\n');
271
+ ret += colors.grey('┌' + lengths.map(length => '─'.repeat(length)).join('┬') + '┐\n');
272
+ ret += colors.grey('│') + lengths.map((length, idx) => ' ' + colors.red(options.columns[idx]) + ' '.repeat(length - options.columns[idx].length - 1)).join(colors.grey('│')) + colors.grey('│\n');
273
+ ret += colors.grey('├' + lengths.map(length => '─'.repeat(length)).join('┼') + '┤\n');
117
274
  options.rows.forEach(row => {
118
- ret += core_1.colors.grey('│') + lengths.map((length, idx) => ' ' + row[idx] + ' '.repeat(length - row[idx].length - 1)).join(core_1.colors.grey('│')) + core_1.colors.grey('│\n');
275
+ ret += colors.grey('│') + lengths.map((length, idx) => ' ' + row[idx] + ' '.repeat(length - row[idx].length - 1)).join(colors.grey('│')) + colors.grey('│\n');
119
276
  });
120
- ret += core_1.colors.grey('└' + lengths.map(length => '─'.repeat(length)).join('┴') + '┘');
277
+ ret += colors.grey('└' + lengths.map(length => '─'.repeat(length)).join('┴') + '┘');
121
278
  CLIHelper.dump(ret);
122
279
  }
123
- /* istanbul ignore next */
280
+ /**
281
+ * Tries to register TS support in the following order: swc, tsx, jiti, tsimp
282
+ * Use `MIKRO_ORM_CLI_TS_LOADER` env var to set the loader explicitly.
283
+ * This method is used only in CLI context.
284
+ */
285
+ static async registerTypeScriptSupport(configPath = 'tsconfig.json', tsLoader) {
286
+ /* v8 ignore if */
287
+ if (process.versions.bun) {
288
+ return true;
289
+ }
290
+ process.env.SWC_NODE_PROJECT ??= configPath;
291
+ process.env.TSIMP_PROJECT ??= configPath;
292
+ process.env.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS ??= '1';
293
+ const explicitLoader = tsLoader ?? process.env.MIKRO_ORM_CLI_TS_LOADER ?? 'auto';
294
+ const loaders = {
295
+ swc: { esm: '@swc-node/register/esm-register', cjs: '@swc-node/register' },
296
+ tsx: { esm: 'tsx/esm/api', cjs: 'tsx/cjs/api', cb: (tsx) => tsx.register({ tsconfig: configPath }) },
297
+ jiti: { esm: 'jiti/register', cjs: 'jiti/register', cb: () => Utils.dynamicImportProvider = id => import(id).then(mod => mod?.default ?? mod) },
298
+ tsimp: { esm: 'tsimp/import', cjs: 'tsimp/import' },
299
+ };
300
+ for (const loader of Utils.keys(loaders)) {
301
+ if (explicitLoader !== 'auto' && loader !== explicitLoader) {
302
+ continue;
303
+ }
304
+ const { esm, cjs, cb } = loaders[loader];
305
+ const isEsm = this.isESM();
306
+ /* v8 ignore next */
307
+ const module = isEsm ? esm : cjs;
308
+ const mod = await Utils.tryImport({ module });
309
+ if (mod) {
310
+ cb?.(mod);
311
+ process.env.MIKRO_ORM_CLI_TS_LOADER = loader;
312
+ return true;
313
+ }
314
+ }
315
+ // eslint-disable-next-line no-console
316
+ 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`.');
317
+ return false;
318
+ }
319
+ static isESM() {
320
+ const config = fs.getPackageConfig();
321
+ const type = config?.type ?? '';
322
+ return type === 'module';
323
+ }
324
+ /* v8 ignore next */
124
325
  static showHelp() {
125
- yargs_1.default.showHelp();
326
+ yargs(process.argv.slice(2)).showHelp();
126
327
  }
127
328
  }
128
- exports.CLIHelper = CLIHelper;
package/README.md CHANGED
@@ -11,7 +11,6 @@ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-or
11
11
  [![Chat on discord](https://img.shields.io/discord/1214904142443839538?label=discord&color=blue)](https://discord.gg/w8bjxFHS7X)
12
12
  [![Downloads](https://img.shields.io/npm/dm/@mikro-orm/core.svg)](https://www.npmjs.com/package/@mikro-orm/core)
13
13
  [![Coverage Status](https://img.shields.io/coveralls/mikro-orm/mikro-orm.svg)](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
14
- [![Maintainability](https://api.codeclimate.com/v1/badges/27999651d3adc47cfa40/maintainability)](https://codeclimate.com/github/mikro-orm/mikro-orm/maintainability)
15
14
  [![Build Status](https://github.com/mikro-orm/mikro-orm/workflows/tests/badge.svg?branch=master)](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
16
15
 
17
16
  ## 🤔 Unit of What?
@@ -141,7 +140,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
141
140
  - [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
142
141
  - [Filters](https://mikro-orm.io/docs/filters)
143
142
  - [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
144
- - [Preloading Deeply Nested Structures via populate](https://mikro-orm.io/docs/nested-populate)
143
+ - [Populating relations](https://mikro-orm.io/docs/populating-relations)
145
144
  - [Property Validation](https://mikro-orm.io/docs/property-validation)
146
145
  - [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
147
146
  - [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
@@ -382,6 +381,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
382
381
 
383
382
  Please ⭐️ this repository if this project helped you!
384
383
 
384
+ > If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
385
+
385
386
  ## 📝 License
386
387
 
387
388
  Copyright © 2018 [Martin Adámek](https://github.com/b4nan).