@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 +7 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +6 -4
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +0 -1
- package/cache/index.js +0 -1
- package/metadata/MetadataDiscovery.d.ts +0 -2
- package/metadata/MetadataDiscovery.js +3 -41
- package/metadata/MetadataProvider.d.ts +9 -0
- package/metadata/MetadataProvider.js +28 -1
- package/metadata/discover-entities.js +2 -1
- package/not-supported.d.ts +1 -0
- package/not-supported.js +2 -1
- package/package.json +5 -1
- package/utils/Configuration.d.ts +3 -21
- package/utils/Configuration.js +11 -46
- package/utils/ConfigurationLoader.d.ts +1 -13
- package/utils/ConfigurationLoader.js +1 -151
- package/utils/Utils.d.ts +0 -4
- package/utils/Utils.js +1 -38
- package/utils/env-vars.d.ts +3 -0
- package/utils/env-vars.js +87 -0
- package/utils/fs-utils.d.ts +12 -0
- package/utils/fs-utils.js +96 -0
- package/utils/index.d.ts +1 -1
- package/utils/index.js +1 -1
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 {
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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;
|
package/cache/index.d.ts
CHANGED
package/cache/index.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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
|
-
|
|
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 ??
|
|
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 =
|
|
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);
|
package/not-supported.d.ts
CHANGED
package/not-supported.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export function discoverEntities() {
|
|
2
|
-
throw new Error('
|
|
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.
|
|
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": {
|
package/utils/Configuration.d.ts
CHANGED
|
@@ -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.
|
package/utils/Configuration.js
CHANGED
|
@@ -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
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,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';
|