@mikro-orm/core 7.0.0-dev.77 → 7.0.0-dev.78

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/MikroORM.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { MetadataDiscovery } from './metadata/MetadataDiscovery.js';
2
2
  import { MetadataStorage } from './metadata/MetadataStorage.js';
3
3
  import { Configuration } from './utils/Configuration.js';
4
- import { ConfigurationLoader } from './utils/ConfigurationLoader.js';
4
+ import { loadEnvironmentVars } from './utils/env-vars.js';
5
5
  import { Utils } from './utils/Utils.js';
6
6
  import { colors } from './logging/colors.js';
7
7
  async function registerExtension(name, mod, extensions) {
@@ -31,6 +31,11 @@ export async function lookupExtensions(options) {
31
31
  await registerExtension('EntityGenerator', import('@mikro-orm/entity-generator' + ''), extensions);
32
32
  }
33
33
  options.extensions = extensions;
34
+ const metadataCacheEnabled = options.metadataCache?.enabled || options.metadataProvider?.useCache?.();
35
+ if (metadataCacheEnabled) {
36
+ options.metadataCache ??= {};
37
+ options.metadataCache.adapter ??= await import('@mikro-orm/core/fs-utils').then(m => m.FileCacheAdapter);
38
+ }
34
39
  }
35
40
  /**
36
41
  * The main class used to configure and bootstrap the ORM.
@@ -94,7 +99,7 @@ export class MikroORM {
94
99
  * - no support for folder based discovery
95
100
  */
96
101
  constructor(options) {
97
- const env = ConfigurationLoader.loadEnvironmentVars();
102
+ const env = loadEnvironmentVars();
98
103
  options = Utils.merge(options, env);
99
104
  this.config = new Configuration(options);
100
105
  const discovery = this.config.get('discovery');
@@ -8,7 +8,7 @@ export declare class FileCacheAdapter implements SyncCacheAdapter {
8
8
  constructor(options: {
9
9
  cacheDir: string;
10
10
  combined?: boolean | string;
11
- }, baseDir: string, pretty?: boolean);
11
+ } | undefined, baseDir: string, pretty?: boolean);
12
12
  /**
13
13
  * @inheritDoc
14
14
  */
@@ -1,4 +1,5 @@
1
1
  import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
2
+ import { fs } from '../utils/fs-utils.js';
2
3
  import { Utils } from '../utils/Utils.js';
3
4
  export class FileCacheAdapter {
4
5
  options;
@@ -6,10 +7,11 @@ export class FileCacheAdapter {
6
7
  pretty;
7
8
  VERSION = Utils.getORMVersion();
8
9
  cache = {};
9
- constructor(options, baseDir, pretty = false) {
10
+ constructor(options = {}, baseDir, pretty = false) {
10
11
  this.options = options;
11
12
  this.baseDir = baseDir;
12
13
  this.pretty = pretty;
14
+ this.options.cacheDir ??= process.cwd() + '/temp';
13
15
  }
14
16
  /**
15
17
  * @inheritDoc
@@ -19,7 +21,7 @@ export class FileCacheAdapter {
19
21
  if (!existsSync(path)) {
20
22
  return null;
21
23
  }
22
- const payload = Utils.readJSONSync(path);
24
+ const payload = fs.readJSONSync(path);
23
25
  const hash = this.getHash(payload.origin);
24
26
  if (!hash || payload.hash !== hash) {
25
27
  return null;
@@ -50,7 +52,7 @@ export class FileCacheAdapter {
50
52
  */
51
53
  clear() {
52
54
  const path = this.path('*');
53
- const files = Utils.glob(path);
55
+ const files = fs.glob(path);
54
56
  files.forEach(file => unlinkSync(file));
55
57
  this.cache = {};
56
58
  }
@@ -67,7 +69,7 @@ export class FileCacheAdapter {
67
69
  return path;
68
70
  }
69
71
  path(name) {
70
- Utils.ensureDir(this.options.cacheDir);
72
+ fs.ensureDir(this.options.cacheDir);
71
73
  return `${this.options.cacheDir}/${name}.json`;
72
74
  }
73
75
  getHash(origin) {
@@ -1,7 +1,6 @@
1
1
  import type { CacheAdapter } from './CacheAdapter.js';
2
2
  import type { Dictionary } from '../typings.js';
3
3
  export declare class GeneratedCacheAdapter implements CacheAdapter {
4
- private readonly options;
5
4
  private readonly data;
6
5
  constructor(options: {
7
6
  data: Dictionary;
@@ -1,8 +1,6 @@
1
1
  export class GeneratedCacheAdapter {
2
- options;
3
2
  data = new Map();
4
3
  constructor(options) {
5
- this.options = options;
6
4
  this.data = new Map(Object.entries(options.data));
7
5
  }
8
6
  /**
package/cache/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './CacheAdapter.js';
2
2
  export * from './NullCacheAdapter.js';
3
- export * from './FileCacheAdapter.js';
4
3
  export * from './MemoryCacheAdapter.js';
5
4
  export * from './GeneratedCacheAdapter.js';
package/cache/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './CacheAdapter.js';
2
2
  export * from './NullCacheAdapter.js';
3
- export * from './FileCacheAdapter.js';
4
3
  export * from './MemoryCacheAdapter.js';
5
4
  export * from './GeneratedCacheAdapter.js';
@@ -9,7 +9,6 @@ export declare class MetadataDiscovery {
9
9
  private readonly config;
10
10
  private readonly namingStrategy;
11
11
  private readonly metadataProvider;
12
- private readonly cache;
13
12
  private readonly logger;
14
13
  private readonly schemaHelper;
15
14
  private readonly validator;
@@ -29,7 +28,6 @@ export declare class MetadataDiscovery {
29
28
  private getSchema;
30
29
  private getRootEntity;
31
30
  private discoverEntity;
32
- private saveToCache;
33
31
  private initNullability;
34
32
  private applyNamingStrategy;
35
33
  private initOwnColumns;
@@ -1,4 +1,3 @@
1
- import { extname } from 'node:path';
2
1
  import { EntityMetadata, } from '../typings.js';
3
2
  import { Utils } from '../utils/Utils.js';
4
3
  import { MetadataValidator } from './MetadataValidator.js';
@@ -15,7 +14,6 @@ export class MetadataDiscovery {
15
14
  config;
16
15
  namingStrategy;
17
16
  metadataProvider;
18
- cache;
19
17
  logger;
20
18
  schemaHelper;
21
19
  validator = new MetadataValidator();
@@ -26,7 +24,6 @@ export class MetadataDiscovery {
26
24
  this.config = config;
27
25
  this.namingStrategy = this.config.getNamingStrategy();
28
26
  this.metadataProvider = this.config.getMetadataProvider();
29
- this.cache = this.config.getMetadataCacheAdapter();
30
27
  this.logger = this.config.getLogger();
31
28
  this.schemaHelper = this.platform.getSchemaHelper();
32
29
  }
@@ -145,11 +142,7 @@ export class MetadataDiscovery {
145
142
  discovered.push(...this.processEntity(meta));
146
143
  }
147
144
  discovered.forEach(meta => meta.sync(true));
148
- const combinedCachePath = this.cache.combine?.();
149
- // override the path in the options, so we can log it from the CLI in `cache:generate` command
150
- if (combinedCachePath) {
151
- this.config.get('metadataCache').combined = combinedCachePath;
152
- }
145
+ this.metadataProvider.combineCache();
153
146
  return discovered.map(meta => {
154
147
  meta = this.metadata.get(meta.className);
155
148
  meta.sync(true);
@@ -287,11 +280,9 @@ export class MetadataDiscovery {
287
280
  this.logger.log('discovery', `- processing entity ${colors.cyan(meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
288
281
  const root = this.getRootEntity(meta);
289
282
  schema.meta.path = Utils.relativePath(meta.path, this.config.get('baseDir'));
290
- const cache = this.metadataProvider.useCache() && meta.path && this.cache.get(meta.className + extname(meta.path));
283
+ const cache = this.metadataProvider.getCachedMetadata(meta, root);
291
284
  if (cache) {
292
285
  this.logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
293
- this.metadataProvider.loadFromCache(meta, cache);
294
- meta.root = root;
295
286
  this.discovered.push(meta);
296
287
  return;
297
288
  }
@@ -305,39 +296,10 @@ export class MetadataDiscovery {
305
296
  const entityName = root.discriminatorColumn ? root.name : meta.name;
306
297
  meta.collection = this.namingStrategy.classToTableName(entityName);
307
298
  }
308
- delete meta.root; // to allow caching (as root can contain cycles)
309
- this.saveToCache(meta);
299
+ this.metadataProvider.saveToCache(meta);
310
300
  meta.root = root;
311
301
  this.discovered.push(meta);
312
302
  }
313
- saveToCache(meta) {
314
- if (!this.metadataProvider.useCache()) {
315
- return;
316
- }
317
- const copy = Utils.copy(meta, false);
318
- for (const prop of copy.props) {
319
- if (Type.isMappedType(prop.type)) {
320
- Reflect.deleteProperty(prop, 'type');
321
- Reflect.deleteProperty(prop, 'customType');
322
- }
323
- if (prop.default) {
324
- const raw = RawQueryFragment.getKnownFragment(prop.default);
325
- if (raw) {
326
- prop.defaultRaw ??= this.platform.formatQuery(raw.sql, raw.params);
327
- Reflect.deleteProperty(prop, 'default');
328
- }
329
- }
330
- Reflect.deleteProperty(prop, 'targetMeta');
331
- }
332
- [
333
- 'prototype', 'props', 'referencingProperties', 'propertyOrder', 'relations',
334
- 'concurrencyCheckKeys', 'checks',
335
- ].forEach(key => delete copy[key]);
336
- // base entity without properties might not have path, but nothing to cache there
337
- if (meta.path) {
338
- this.cache.set(meta.className + extname(meta.path), copy, meta.path);
339
- }
340
- }
341
303
  initNullability(prop) {
342
304
  if (prop.kind === ReferenceKind.ONE_TO_ONE) {
343
305
  return Utils.defaultValue(prop, 'nullable', prop.optional || !prop.owner);
@@ -1,13 +1,22 @@
1
1
  import type { EntityMetadata } from '../typings.js';
2
2
  import type { Logger } from '../logging/Logger.js';
3
+ import type { SyncCacheAdapter } from '../cache/CacheAdapter.js';
4
+ import type { Platform } from '../platforms/Platform.js';
3
5
  export interface IConfiguration {
4
6
  get(key: string, defaultValue?: any): any;
5
7
  getLogger(): Logger;
8
+ getMetadataCacheAdapter(): SyncCacheAdapter;
9
+ getPlatform(): Platform;
6
10
  }
7
11
  export declare class MetadataProvider {
8
12
  protected readonly config: IConfiguration;
9
13
  constructor(config: IConfiguration);
10
14
  loadEntityMetadata(meta: EntityMetadata): void;
11
15
  loadFromCache(meta: EntityMetadata, cache: EntityMetadata): void;
16
+ static useCache(): boolean;
12
17
  useCache(): boolean;
18
+ saveToCache(meta: EntityMetadata): void;
19
+ getCachedMetadata<T>(meta: Pick<EntityMetadata<T>, 'className' | 'path' | 'root'>, root: EntityMetadata<T>): EntityMetadata<T> | undefined;
20
+ combineCache(): void;
21
+ getCacheKey(meta: Pick<EntityMetadata, 'className' | 'path'>): string;
13
22
  }
@@ -29,7 +29,34 @@ export class MetadataProvider {
29
29
  });
30
30
  Utils.mergeConfig(meta, cache);
31
31
  }
32
+ static useCache() {
33
+ return false;
34
+ }
32
35
  useCache() {
33
- return this.config.get('metadataCache').enabled ?? false;
36
+ return this.config.get('metadataCache').enabled ?? MetadataProvider.useCache();
37
+ }
38
+ saveToCache(meta) {
39
+ //
40
+ }
41
+ getCachedMetadata(meta, root) {
42
+ if (!this.useCache()) {
43
+ return undefined;
44
+ }
45
+ const cache = meta.path && this.config.getMetadataCacheAdapter().get(this.getCacheKey(meta));
46
+ if (cache) {
47
+ this.loadFromCache(meta, cache);
48
+ meta.root = root;
49
+ }
50
+ return cache;
51
+ }
52
+ combineCache() {
53
+ const path = this.config.getMetadataCacheAdapter().combine?.();
54
+ // override the path in the options, so we can log it from the CLI in `cache:generate` command
55
+ if (path) {
56
+ this.config.get('metadataCache').combined = path;
57
+ }
58
+ }
59
+ getCacheKey(meta) {
60
+ return meta.className;
34
61
  }
35
62
  }
@@ -1,4 +1,5 @@
1
1
  import { basename } from 'node:path';
2
+ import { fs } from '../utils/fs-utils.js';
2
3
  import { Utils } from '../utils/Utils.js';
3
4
  import { MetadataStorage } from './MetadataStorage.js';
4
5
  import { EntitySchema } from './EntitySchema.js';
@@ -26,7 +27,7 @@ async function getEntityClassOrSchema(filepath, allTargets, baseDir) {
26
27
  export async function discoverEntities(paths, options) {
27
28
  paths = Utils.asArray(paths).map(path => Utils.normalizePath(path));
28
29
  const baseDir = options?.baseDir ?? process.cwd();
29
- const files = Utils.glob(paths, Utils.normalizePath(baseDir));
30
+ const files = fs.glob(paths, Utils.normalizePath(baseDir));
30
31
  const found = new Map();
31
32
  for (const filepath of files) {
32
33
  const filename = basename(filepath);
@@ -1 +1,2 @@
1
1
  export declare function discoverEntities(): void;
2
+ export declare const fs: {};
package/not-supported.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export function discoverEntities() {
2
- throw new Error('File discovery is not supported in this environment.');
2
+ throw new Error('Folder-based discovery is not supported in this environment.');
3
3
  }
4
+ export const fs = new Proxy({}, { get: () => { throw new Error('File system is not supported in this environment.'); } });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
3
  "type": "module",
4
- "version": "7.0.0-dev.77",
4
+ "version": "7.0.0-dev.78",
5
5
  "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
6
  "exports": {
7
7
  "./package.json": "./package.json",
@@ -9,6 +9,10 @@
9
9
  "./file-discovery": {
10
10
  "node": "./metadata/discover-entities.js",
11
11
  "browser": "./not-supported.js"
12
+ },
13
+ "./fs-utils": {
14
+ "node": "./utils/fs-utils.js",
15
+ "browser": "./not-supported.js"
12
16
  }
13
17
  },
14
18
  "repository": {
@@ -1,5 +1,4 @@
1
1
  import type { NamingStrategy } from '../naming-strategy/NamingStrategy.js';
2
- import { FileCacheAdapter } from '../cache/FileCacheAdapter.js';
3
2
  import { type CacheAdapter, type SyncCacheAdapter } from '../cache/CacheAdapter.js';
4
3
  import type { EntityRepository } from '../entity/EntityRepository.js';
5
4
  import type { AnyEntity, Constructor, Dictionary, EnsureDatabaseOptions, EntityClass, EntityMetadata, FilterDef, GenerateOptions, Highlighter, HydratorConstructor, IHydrator, IMigrationGenerator, IPrimaryKey, MaybePromise, Migration, MigrationObject } from '../typings.js';
@@ -80,7 +79,6 @@ declare const DEFAULTS: {
80
79
  readonly driverOptions: {};
81
80
  readonly migrations: {
82
81
  readonly tableName: "mikro_orm_migrations";
83
- readonly path: "./migrations";
84
82
  readonly glob: "!(*.d).{js,ts,cjs}";
85
83
  readonly silent: false;
86
84
  readonly transactional: true;
@@ -118,13 +116,7 @@ declare const DEFAULTS: {
118
116
  readonly readOnlyPivotTables: false;
119
117
  readonly useCoreBaseEntity: false;
120
118
  };
121
- readonly metadataCache: {
122
- readonly pretty: false;
123
- readonly adapter: typeof FileCacheAdapter;
124
- readonly options: {
125
- readonly cacheDir: string;
126
- };
127
- };
119
+ readonly metadataCache: {};
128
120
  readonly resultCache: {
129
121
  readonly adapter: typeof MemoryCacheAdapter;
130
122
  readonly expiration: 1000;
@@ -133,7 +125,6 @@ declare const DEFAULTS: {
133
125
  readonly metadataProvider: typeof MetadataProvider;
134
126
  readonly highlighter: NullHighlighter;
135
127
  readonly seeder: {
136
- readonly path: "./seeders";
137
128
  readonly defaultSeeder: "DatabaseSeeder";
138
129
  readonly glob: "!(*.d).{js,ts}";
139
130
  readonly emit: "ts";
@@ -213,15 +204,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
213
204
  resetServiceCache(): void;
214
205
  private init;
215
206
  private sync;
216
- /**
217
- * Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
218
- * If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
219
- * used for the TS variant (`pathTs` option).
220
- *
221
- * If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
222
- * break existing projects, only help with the new ones.
223
- */
224
- private detectSourceFolder;
225
207
  private validateOptions;
226
208
  }
227
209
  /**
@@ -903,8 +885,7 @@ export interface Options<Driver extends IDatabaseDriver = IDatabaseDriver, EM ex
903
885
  */
904
886
  pretty?: boolean;
905
887
  /**
906
- * Cache adapter class to use.
907
- * @default FileCacheAdapter
888
+ * Cache adapter class to use. When cache is enabled, and no adapter is provided explicitly, {@link FileCacheAdapter} is used automatically - but only if you use the async `MikroORM.init()` method.
908
889
  */
909
890
  adapter?: {
910
891
  new (...params: any[]): SyncCacheAdapter;
@@ -950,6 +931,7 @@ export interface Options<Driver extends IDatabaseDriver = IDatabaseDriver, EM ex
950
931
  */
951
932
  metadataProvider?: {
952
933
  new (config: Configuration): MetadataProvider;
934
+ useCache?: MetadataProvider['useCache'];
953
935
  };
954
936
  /**
955
937
  * Seeder configuration options.
@@ -1,4 +1,3 @@
1
- import { FileCacheAdapter } from '../cache/FileCacheAdapter.js';
2
1
  import { NullCacheAdapter } from '../cache/NullCacheAdapter.js';
3
2
  import { ObjectHydrator } from '../hydration/ObjectHydrator.js';
4
3
  import { NullHighlighter } from '../utils/NullHighlighter.js';
@@ -72,7 +71,6 @@ const DEFAULTS = {
72
71
  driverOptions: {},
73
72
  migrations: {
74
73
  tableName: 'mikro_orm_migrations',
75
- path: './migrations',
76
74
  glob: '!(*.d).{js,ts,cjs}',
77
75
  silent: false,
78
76
  transactional: true,
@@ -104,17 +102,14 @@ const DEFAULTS = {
104
102
  entityDefinition: 'defineEntity',
105
103
  decorators: 'legacy',
106
104
  enumMode: 'dictionary',
105
+ /* v8 ignore next */
107
106
  fileName: (className) => className,
108
107
  onlyPurePivotTables: false,
109
108
  outputPurePivotTables: false,
110
109
  readOnlyPivotTables: false,
111
110
  useCoreBaseEntity: false,
112
111
  },
113
- metadataCache: {
114
- pretty: false,
115
- adapter: FileCacheAdapter,
116
- options: { cacheDir: process.cwd() + '/temp' },
117
- },
112
+ metadataCache: {},
118
113
  resultCache: {
119
114
  adapter: MemoryCacheAdapter,
120
115
  expiration: 1000, // 1s
@@ -123,7 +118,6 @@ const DEFAULTS = {
123
118
  metadataProvider: MetadataProvider,
124
119
  highlighter: new NullHighlighter(),
125
120
  seeder: {
126
- path: './seeders',
127
121
  defaultSeeder: 'DatabaseSeeder',
128
122
  glob: '!(*.d).{js,ts}',
129
123
  emit: 'ts',
@@ -160,7 +154,6 @@ export class Configuration {
160
154
  this.driver = new this.options.driver(this);
161
155
  this.platform = this.driver.getPlatform();
162
156
  this.platform.setConfig(this);
163
- this.detectSourceFolder(options);
164
157
  this.init(validate);
165
158
  }
166
159
  }
@@ -292,16 +285,17 @@ export class Configuration {
292
285
  this.cache.clear();
293
286
  }
294
287
  init(validate) {
295
- if (!this.getMetadataProvider().useCache()) {
296
- this.options.metadataCache.adapter = NullCacheAdapter;
297
- }
298
- if (!('enabled' in this.options.metadataCache)) {
299
- this.options.metadataCache.enabled = this.getMetadataProvider().useCache();
300
- }
301
- if (!this.options.clientUrl) {
302
- this.options.clientUrl = this.platform.getDefaultClientUrl();
288
+ const useCache = this.getMetadataProvider().useCache();
289
+ const metadataCache = this.options.metadataCache;
290
+ if (!useCache) {
291
+ metadataCache.adapter = NullCacheAdapter;
303
292
  }
293
+ metadataCache.enabled ??= useCache;
294
+ this.options.clientUrl ??= this.platform.getDefaultClientUrl();
304
295
  this.options.implicitTransactions ??= this.platform.usesImplicitTransactions();
296
+ if (metadataCache.enabled && !metadataCache.adapter) {
297
+ throw new Error('No metadata cache adapter specified, please fill in `metadataCache.adapter` option or use the async MikroORM.init() method which can autoload it.');
298
+ }
305
299
  try {
306
300
  const url = new URL(this.options.clientUrl);
307
301
  if (url.pathname) {
@@ -337,35 +331,6 @@ export class Configuration {
337
331
  process.env.MIKRO_ORM_COLORS = '' + this.options.colors;
338
332
  this.logger.setDebugMode(this.options.debug);
339
333
  }
340
- /**
341
- * Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
342
- * If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
343
- * used for the TS variant (`pathTs` option).
344
- *
345
- * If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
346
- * break existing projects, only help with the new ones.
347
- */
348
- detectSourceFolder(options) {
349
- if (!Utils.pathExists(this.options.baseDir + '/src')) {
350
- return;
351
- }
352
- const migrationsPathExists = Utils.pathExists(this.options.baseDir + '/' + this.options.migrations.path);
353
- const seedersPathExists = Utils.pathExists(this.options.baseDir + '/' + this.options.seeder.path);
354
- const distDir = Utils.pathExists(this.options.baseDir + '/dist');
355
- const buildDir = Utils.pathExists(this.options.baseDir + '/build');
356
- // if neither `dist` nor `build` exist, we use the `src` folder as it might be a JS project without building, but with `src` folder
357
- const path = distDir ? './dist' : (buildDir ? './build' : './src');
358
- // only if the user did not provide any values and if the default path does not exist
359
- if (!options.migrations?.path && !options.migrations?.pathTs && !migrationsPathExists) {
360
- this.options.migrations.path = `${path}/migrations`;
361
- this.options.migrations.pathTs = './src/migrations';
362
- }
363
- // only if the user did not provide any values and if the default path does not exist
364
- if (!options.seeder?.path && !options.seeder?.pathTs && !seedersPathExists) {
365
- this.options.seeder.path = `${path}/seeders`;
366
- this.options.seeder.pathTs = './src/seeders';
367
- }
368
- }
369
334
  validateOptions() {
370
335
  /* v8 ignore next */
371
336
  if ('type' in this.options) {
@@ -1,13 +1 @@
1
- import type { IDatabaseDriver } from '../drivers/IDatabaseDriver.js';
2
- import type { Dictionary } from '../typings.js';
3
- import { type Options } from './Configuration.js';
4
- /**
5
- * @internal
6
- */
7
- export declare class ConfigurationLoader {
8
- static loadEnvironmentVars<D extends IDatabaseDriver>(): Partial<Options<D>>;
9
- static getPackageConfig<T extends Dictionary>(basePath?: string): Promise<T>;
10
- static getORMPackages(): Promise<Set<string>>;
11
- static getORMPackageVersion(name: string): string | undefined;
12
- static checkPackageVersion(): Promise<string>;
13
- }
1
+ export {};
@@ -1,151 +1 @@
1
- import { realpathSync } from 'node:fs';
2
- import { fileURLToPath } from 'node:url';
3
- import { Utils } from './Utils.js';
4
- import { colors } from '../logging/colors.js';
5
- /**
6
- * @internal
7
- */
8
- export class ConfigurationLoader {
9
- static loadEnvironmentVars() {
10
- const ret = {};
11
- const getEnvKey = (key, envPrefix = 'MIKRO_ORM_') => {
12
- return envPrefix + key
13
- .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
14
- .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
15
- .toUpperCase();
16
- };
17
- const array = (v) => v.split(',').map(vv => vv.trim());
18
- const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
19
- const num = (v) => +v;
20
- const read = (o, envPrefix, key, mapper = v => v) => {
21
- const envKey = getEnvKey(key, envPrefix);
22
- if (envKey in process.env) {
23
- o[key] = mapper(process.env[envKey]);
24
- }
25
- };
26
- const cleanup = (o, k) => Utils.hasObjectKeys(o[k]) ? {} : delete o[k];
27
- const read0 = read.bind(null, ret, 'MIKRO_ORM_');
28
- read0('baseDir');
29
- read0('entities', array);
30
- read0('entitiesTs', array);
31
- read0('clientUrl');
32
- read0('host');
33
- read0('port', num);
34
- read0('user');
35
- read0('password');
36
- read0('dbName');
37
- read0('schema');
38
- read0('loadStrategy');
39
- read0('batchSize', num);
40
- read0('useBatchInserts', bool);
41
- read0('useBatchUpdates', bool);
42
- read0('strict', bool);
43
- read0('validate', bool);
44
- read0('allowGlobalContext', bool);
45
- read0('autoJoinOneToOneOwner', bool);
46
- read0('populateAfterFlush', bool);
47
- read0('forceEntityConstructor', bool);
48
- read0('forceUndefined', bool);
49
- read0('forceUtcTimezone', bool);
50
- read0('timezone');
51
- read0('ensureIndexes', bool);
52
- read0('implicitTransactions', bool);
53
- read0('debug', bool);
54
- read0('colors', bool);
55
- ret.discovery = {};
56
- const read1 = read.bind(null, ret.discovery, 'MIKRO_ORM_DISCOVERY_');
57
- read1('warnWhenNoEntities', bool);
58
- read1('checkDuplicateTableNames', bool);
59
- read1('checkDuplicateFieldNames', bool);
60
- read1('checkDuplicateEntities', bool);
61
- read1('checkNonPersistentCompositeProps', bool);
62
- read1('inferDefaultValues', bool);
63
- read1('tsConfigPath');
64
- cleanup(ret, 'discovery');
65
- ret.migrations = {};
66
- const read2 = read.bind(null, ret.migrations, 'MIKRO_ORM_MIGRATIONS_');
67
- read2('tableName');
68
- read2('path');
69
- read2('pathTs');
70
- read2('glob');
71
- read2('transactional', bool);
72
- read2('disableForeignKeys', bool);
73
- read2('allOrNothing', bool);
74
- read2('dropTables', bool);
75
- read2('safe', bool);
76
- read2('silent', bool);
77
- read2('emit');
78
- read2('snapshot', bool);
79
- read2('snapshotName');
80
- cleanup(ret, 'migrations');
81
- ret.schemaGenerator = {};
82
- const read3 = read.bind(null, ret.schemaGenerator, 'MIKRO_ORM_SCHEMA_GENERATOR_');
83
- read3('disableForeignKeys', bool);
84
- read3('createForeignKeyConstraints', bool);
85
- cleanup(ret, 'schemaGenerator');
86
- ret.seeder = {};
87
- const read4 = read.bind(null, ret.seeder, 'MIKRO_ORM_SEEDER_');
88
- read4('path');
89
- read4('pathTs');
90
- read4('glob');
91
- read4('emit');
92
- read4('defaultSeeder');
93
- cleanup(ret, 'seeder');
94
- return ret;
95
- }
96
- static async getPackageConfig(basePath = process.cwd()) {
97
- if (Utils.pathExists(`${basePath}/package.json`)) {
98
- try {
99
- return await Utils.dynamicImport(`${basePath}/package.json`);
100
- }
101
- catch (e) {
102
- /* v8 ignore next */
103
- return {};
104
- }
105
- }
106
- const parentFolder = realpathSync(`${basePath}/..`);
107
- // we reached the root folder
108
- if (basePath === parentFolder) {
109
- return {};
110
- }
111
- return this.getPackageConfig(parentFolder);
112
- }
113
- static async getORMPackages() {
114
- const pkg = await this.getPackageConfig();
115
- return new Set([
116
- ...Object.keys(pkg.dependencies ?? {}),
117
- ...Object.keys(pkg.devDependencies ?? {}),
118
- ]);
119
- }
120
- static getORMPackageVersion(name) {
121
- try {
122
- const path = import.meta.resolve(`${name}/package.json`);
123
- const pkg = Utils.readJSONSync(fileURLToPath(path));
124
- /* v8 ignore next */
125
- return pkg?.version;
126
- }
127
- catch (e) {
128
- return undefined;
129
- }
130
- }
131
- // inspired by https://github.com/facebook/docusaurus/pull/3386
132
- static async checkPackageVersion() {
133
- const coreVersion = Utils.getORMVersion();
134
- if (process.env.MIKRO_ORM_ALLOW_VERSION_MISMATCH || coreVersion === 'N/A') {
135
- return coreVersion;
136
- }
137
- const deps = await this.getORMPackages();
138
- const exceptions = new Set(['nestjs', 'sql-highlighter', 'mongo-highlighter']);
139
- const ormPackages = [...deps].filter(d => d.startsWith('@mikro-orm/') && d !== '@mikro-orm/core' && !exceptions.has(d.substring('@mikro-orm/'.length)));
140
- for (const ormPackage of ormPackages) {
141
- const version = this.getORMPackageVersion(ormPackage);
142
- if (version != null && version !== coreVersion) {
143
- throw new Error(`Bad ${colors.cyan(ormPackage)} version ${colors.yellow('' + version)}.\n` +
144
- `All official @mikro-orm/* packages need to have the exact same version as @mikro-orm/core (${colors.green(coreVersion)}).\n` +
145
- `Only exceptions are packages that don't live in the 'mikro-orm' repository: ${[...exceptions].join(', ')}.\n` +
146
- `Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?`);
147
- }
148
- }
149
- return coreVersion;
150
- }
151
- }
1
+ export {};
package/utils/Utils.d.ts CHANGED
@@ -153,8 +153,6 @@ export declare class Utils {
153
153
  static findDuplicates<T>(items: T[]): T[];
154
154
  static removeDuplicates<T>(items: T[]): T[];
155
155
  static randomInt(min: number, max: number): number;
156
- static glob(input: string | string[], cwd?: string): string[];
157
- static pathExists(path: string): boolean;
158
156
  /**
159
157
  * Extracts all possible values of a TS enum. Works with both string and numeric enums.
160
158
  */
@@ -163,8 +161,6 @@ export declare class Utils {
163
161
  static isOperator(key: PropertyKey, includeGroupOperators?: boolean): boolean;
164
162
  static hasNestedKey(object: unknown, key: string): boolean;
165
163
  static dynamicImport<T = any>(id: string): Promise<T>;
166
- static ensureDir(path: string): void;
167
- static readJSONSync(path: string): Dictionary;
168
164
  static getORMVersion(): string;
169
165
  static createFunction(context: Map<string, any>, code: string): any;
170
166
  static callCompiledFunction<T extends unknown[], R>(fn: (...args: T) => R, ...args: T): R;
package/utils/Utils.js CHANGED
@@ -1,6 +1,5 @@
1
- import { isAbsolute, join, normalize, relative } from 'node:path';
1
+ import { isAbsolute, normalize, relative } from 'node:path';
2
2
  import { fileURLToPath, pathToFileURL } from 'node:url';
3
- import { existsSync, globSync, statSync, mkdirSync, readFileSync } from 'node:fs';
4
3
  import { clone } from './clone.js';
5
4
  import { GroupOperator, PlainObject, QueryOperator, ReferenceKind } from '../enums.js';
6
5
  import { helper } from '../entity/wrap.js';
@@ -686,33 +685,6 @@ export class Utils {
686
685
  static randomInt(min, max) {
687
686
  return Math.round(Math.random() * (max - min)) + min;
688
687
  }
689
- static glob(input, cwd) {
690
- if (Array.isArray(input)) {
691
- return input.flatMap(paths => this.glob(paths, cwd));
692
- }
693
- const hasGlobChars = /[*?[\]]/.test(input);
694
- if (!hasGlobChars) {
695
- try {
696
- const s = statSync(cwd ? Utils.normalizePath(cwd, input) : input);
697
- if (s.isDirectory()) {
698
- const files = globSync(join(input, '**'), { cwd, withFileTypes: true });
699
- return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
700
- }
701
- }
702
- catch {
703
- // ignore
704
- }
705
- }
706
- const files = globSync(input, { cwd, withFileTypes: true });
707
- return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
708
- }
709
- static pathExists(path) {
710
- if (/[*?[\]]/.test(path)) {
711
- const found = globSync(path);
712
- return found.length > 0;
713
- }
714
- return existsSync(path);
715
- }
716
688
  /**
717
689
  * Extracts all possible values of a TS enum. Works with both string and numeric enums.
718
690
  */
@@ -755,15 +727,6 @@ export class Utils {
755
727
  const specifier = id.startsWith('file://') ? id : pathToFileURL(id).href;
756
728
  return this.dynamicImportProvider(specifier);
757
729
  }
758
- static ensureDir(path) {
759
- if (!existsSync(path)) {
760
- mkdirSync(path, { recursive: true });
761
- }
762
- }
763
- static readJSONSync(path) {
764
- const file = readFileSync(path);
765
- return JSON.parse(file.toString());
766
- }
767
730
  static getORMVersion() {
768
731
  return '6.6.1';
769
732
  }
@@ -0,0 +1,3 @@
1
+ import { type Options } from './Configuration.js';
2
+ /** @internal */
3
+ export declare function loadEnvironmentVars(): Partial<Options>;
@@ -0,0 +1,87 @@
1
+ import { Utils } from './Utils.js';
2
+ /** @internal */
3
+ export function loadEnvironmentVars() {
4
+ const ret = {};
5
+ const getEnvKey = (key, envPrefix = 'MIKRO_ORM_') => {
6
+ return envPrefix + key
7
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
8
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
9
+ .toUpperCase();
10
+ };
11
+ const array = (v) => v.split(',').map(vv => vv.trim());
12
+ const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
13
+ const num = (v) => +v;
14
+ const read = (o, envPrefix, key, mapper = v => v) => {
15
+ const envKey = getEnvKey(key, envPrefix);
16
+ if (envKey in process.env) {
17
+ o[key] = mapper(process.env[envKey]);
18
+ }
19
+ };
20
+ const cleanup = (o, k) => Utils.hasObjectKeys(o[k]) ? {} : delete o[k];
21
+ const read0 = read.bind(null, ret, 'MIKRO_ORM_');
22
+ read0('baseDir');
23
+ read0('entities', array);
24
+ read0('entitiesTs', array);
25
+ read0('clientUrl');
26
+ read0('host');
27
+ read0('port', num);
28
+ read0('user');
29
+ read0('password');
30
+ read0('dbName');
31
+ read0('schema');
32
+ read0('loadStrategy');
33
+ read0('batchSize', num);
34
+ read0('useBatchInserts', bool);
35
+ read0('useBatchUpdates', bool);
36
+ read0('allowGlobalContext', bool);
37
+ read0('autoJoinOneToOneOwner', bool);
38
+ read0('populateAfterFlush', bool);
39
+ read0('forceEntityConstructor', bool);
40
+ read0('forceUndefined', bool);
41
+ read0('forceUtcTimezone', bool);
42
+ read0('timezone');
43
+ read0('ensureIndexes', bool);
44
+ read0('implicitTransactions', bool);
45
+ read0('debug', bool);
46
+ read0('colors', bool);
47
+ ret.discovery = {};
48
+ const read1 = read.bind(null, ret.discovery, 'MIKRO_ORM_DISCOVERY_');
49
+ read1('warnWhenNoEntities', bool);
50
+ read1('checkDuplicateTableNames', bool);
51
+ read1('checkDuplicateFieldNames', bool);
52
+ read1('checkDuplicateEntities', bool);
53
+ read1('checkNonPersistentCompositeProps', bool);
54
+ read1('inferDefaultValues', bool);
55
+ read1('tsConfigPath');
56
+ cleanup(ret, 'discovery');
57
+ ret.migrations = {};
58
+ const read2 = read.bind(null, ret.migrations, 'MIKRO_ORM_MIGRATIONS_');
59
+ read2('tableName');
60
+ read2('path');
61
+ read2('pathTs');
62
+ read2('glob');
63
+ read2('transactional', bool);
64
+ read2('disableForeignKeys', bool);
65
+ read2('allOrNothing', bool);
66
+ read2('dropTables', bool);
67
+ read2('safe', bool);
68
+ read2('silent', bool);
69
+ read2('emit');
70
+ read2('snapshot', bool);
71
+ read2('snapshotName');
72
+ cleanup(ret, 'migrations');
73
+ ret.schemaGenerator = {};
74
+ const read3 = read.bind(null, ret.schemaGenerator, 'MIKRO_ORM_SCHEMA_GENERATOR_');
75
+ read3('disableForeignKeys', bool);
76
+ read3('createForeignKeyConstraints', bool);
77
+ cleanup(ret, 'schemaGenerator');
78
+ ret.seeder = {};
79
+ const read4 = read.bind(null, ret.seeder, 'MIKRO_ORM_SEEDER_');
80
+ read4('path');
81
+ read4('pathTs');
82
+ read4('glob');
83
+ read4('emit');
84
+ read4('defaultSeeder');
85
+ cleanup(ret, 'seeder');
86
+ return ret;
87
+ }
@@ -0,0 +1,12 @@
1
+ import { type Dictionary } from '../typings.js';
2
+ export declare const fs: {
3
+ pathExists(path: string): boolean;
4
+ ensureDir(path: string): void;
5
+ readJSONSync<T = Dictionary>(path: string): T;
6
+ glob(input: string | string[], cwd?: string): string[];
7
+ getPackageConfig<T extends Dictionary>(basePath?: string): Promise<T>;
8
+ getORMPackages(): Promise<Set<string>>;
9
+ getORMPackageVersion(name: string): string | undefined;
10
+ checkPackageVersion(): Promise<void>;
11
+ };
12
+ export * from '../cache/FileCacheAdapter.js';
@@ -0,0 +1,96 @@
1
+ import { existsSync, globSync, mkdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { Utils } from './Utils.js';
5
+ import { colors } from '../logging/colors.js';
6
+ export const fs = {
7
+ pathExists(path) {
8
+ if (/[*?[\]]/.test(path)) {
9
+ return globSync(path).length > 0;
10
+ }
11
+ return existsSync(path);
12
+ },
13
+ ensureDir(path) {
14
+ if (!existsSync(path)) {
15
+ mkdirSync(path, { recursive: true });
16
+ }
17
+ },
18
+ readJSONSync(path) {
19
+ const file = readFileSync(path);
20
+ return JSON.parse(file.toString());
21
+ },
22
+ glob(input, cwd) {
23
+ if (Array.isArray(input)) {
24
+ return input.flatMap(paths => this.glob(paths, cwd));
25
+ }
26
+ const hasGlobChars = /[*?[\]]/.test(input);
27
+ if (!hasGlobChars) {
28
+ try {
29
+ const s = statSync(cwd ? Utils.normalizePath(cwd, input) : input);
30
+ if (s.isDirectory()) {
31
+ const files = globSync(join(input, '**'), { cwd, withFileTypes: true });
32
+ return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
33
+ }
34
+ }
35
+ catch {
36
+ // ignore
37
+ }
38
+ }
39
+ const files = globSync(input, { cwd, withFileTypes: true });
40
+ return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
41
+ },
42
+ async getPackageConfig(basePath = process.cwd()) {
43
+ if (this.pathExists(`${basePath}/package.json`)) {
44
+ try {
45
+ return await Utils.dynamicImport(`${basePath}/package.json`);
46
+ }
47
+ catch (e) {
48
+ /* v8 ignore next */
49
+ return {};
50
+ }
51
+ }
52
+ const parentFolder = realpathSync(`${basePath}/..`);
53
+ // we reached the root folder
54
+ if (basePath === parentFolder) {
55
+ return {};
56
+ }
57
+ return this.getPackageConfig(parentFolder);
58
+ },
59
+ async getORMPackages() {
60
+ const pkg = await this.getPackageConfig();
61
+ return new Set([
62
+ ...Object.keys(pkg.dependencies ?? {}),
63
+ ...Object.keys(pkg.devDependencies ?? {}),
64
+ ]);
65
+ },
66
+ getORMPackageVersion(name) {
67
+ try {
68
+ const path = import.meta.resolve(`${name}/package.json`);
69
+ const pkg = this.readJSONSync(fileURLToPath(path));
70
+ return pkg?.version;
71
+ }
72
+ catch (e) {
73
+ return undefined;
74
+ }
75
+ },
76
+ // inspired by https://github.com/facebook/docusaurus/pull/3386
77
+ async checkPackageVersion() {
78
+ const coreVersion = Utils.getORMVersion();
79
+ if (process.env.MIKRO_ORM_ALLOW_VERSION_MISMATCH || coreVersion === '[[MIKRO_ORM_VERSION]]') {
80
+ return;
81
+ }
82
+ const deps = await this.getORMPackages();
83
+ const exceptions = new Set(['nestjs', 'sql-highlighter', 'mongo-highlighter']);
84
+ const ormPackages = [...deps].filter(d => d.startsWith('@mikro-orm/') && d !== '@mikro-orm/core' && !exceptions.has(d.substring('@mikro-orm/'.length)));
85
+ for (const ormPackage of ormPackages) {
86
+ const version = this.getORMPackageVersion(ormPackage);
87
+ if (version != null && version !== coreVersion) {
88
+ throw new Error(`Bad ${colors.cyan(ormPackage)} version ${colors.yellow('' + version)}.\n` +
89
+ `All official @mikro-orm/* packages need to have the exact same version as @mikro-orm/core (${colors.green(coreVersion)}).\n` +
90
+ `Only exceptions are packages that don't live in the 'mikro-orm' repository: ${[...exceptions].join(', ')}.\n` +
91
+ `Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?`);
92
+ }
93
+ }
94
+ },
95
+ };
96
+ export * from '../cache/FileCacheAdapter.js';
package/utils/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './Configuration.js';
2
- export * from './ConfigurationLoader.js';
3
2
  export * from './Cursor.js';
4
3
  export * from './DataloaderUtils.js';
5
4
  export * from './Utils.js';
@@ -11,4 +10,5 @@ export * from './NullHighlighter.js';
11
10
  export * from './EntityComparator.js';
12
11
  export * from './AbstractSchemaGenerator.js';
13
12
  export * from './RawQueryFragment.js';
13
+ export * from './env-vars.js';
14
14
  export * from './upsert-utils.js';
package/utils/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './Configuration.js';
2
- export * from './ConfigurationLoader.js';
3
2
  export * from './Cursor.js';
4
3
  export * from './DataloaderUtils.js';
5
4
  export * from './Utils.js';
@@ -11,4 +10,5 @@ export * from './NullHighlighter.js';
11
10
  export * from './EntityComparator.js';
12
11
  export * from './AbstractSchemaGenerator.js';
13
12
  export * from './RawQueryFragment.js';
13
+ export * from './env-vars.js';
14
14
  export * from './upsert-utils.js';