@mikro-orm/core 7.0.0-dev.107 → 7.0.0-dev.109
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/cache/FileCacheAdapter.js +2 -2
- package/entity/EntityHelper.js +2 -1
- package/logging/colors.d.ts +1 -1
- package/logging/colors.js +7 -6
- package/logging/inspect.js +1 -6
- package/metadata/MetadataDiscovery.js +8 -4
- package/metadata/discover-entities.js +5 -5
- package/package.json +1 -1
- package/utils/Configuration.js +4 -4
- package/utils/Utils.d.ts +0 -21
- package/utils/Utils.js +9 -74
- package/utils/env-vars.d.ts +4 -0
- package/utils/env-vars.js +13 -2
- package/utils/fs-utils.d.ts +20 -0
- package/utils/fs-utils.js +85 -4
|
@@ -63,7 +63,7 @@ export class FileCacheAdapter {
|
|
|
63
63
|
let path = typeof this.options.combined === 'string'
|
|
64
64
|
? this.options.combined
|
|
65
65
|
: './metadata.json';
|
|
66
|
-
path =
|
|
66
|
+
path = fs.normalizePath(this.options.cacheDir, path);
|
|
67
67
|
this.options.combined = path; // override in the options, so we can log it from the CLI in `cache:generate` command
|
|
68
68
|
writeFileSync(path, JSON.stringify(this.cache, null, this.pretty ? 2 : undefined));
|
|
69
69
|
return path;
|
|
@@ -73,7 +73,7 @@ export class FileCacheAdapter {
|
|
|
73
73
|
return `${this.options.cacheDir}/${name}.json`;
|
|
74
74
|
}
|
|
75
75
|
getHash(origin) {
|
|
76
|
-
origin =
|
|
76
|
+
origin = fs.absolutePath(origin, this.baseDir);
|
|
77
77
|
if (!existsSync(origin)) {
|
|
78
78
|
return null;
|
|
79
79
|
}
|
package/entity/EntityHelper.js
CHANGED
|
@@ -6,6 +6,7 @@ import { WrappedEntity } from './WrappedEntity.js';
|
|
|
6
6
|
import { ReferenceKind } from '../enums.js';
|
|
7
7
|
import { helper } from './wrap.js';
|
|
8
8
|
import { inspect } from '../logging/inspect.js';
|
|
9
|
+
import { getEnv } from '../utils/env-vars.js';
|
|
9
10
|
/**
|
|
10
11
|
* @internal
|
|
11
12
|
*/
|
|
@@ -130,7 +131,7 @@ export class EntityHelper {
|
|
|
130
131
|
.forEach(prop => delete object[prop.name]);
|
|
131
132
|
const ret = inspect(object, { depth });
|
|
132
133
|
let name = this.constructor.name;
|
|
133
|
-
const showEM = ['true', 't', '1'].includes(
|
|
134
|
+
const showEM = ['true', 't', '1'].includes(getEnv('MIKRO_ORM_LOG_EM_ID')?.toLowerCase() ?? '');
|
|
134
135
|
if (showEM) {
|
|
135
136
|
if (helper(this).__em) {
|
|
136
137
|
name += ` [managed by ${helper(this).__em.id}]`;
|
package/logging/colors.d.ts
CHANGED
package/logging/colors.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
&&
|
|
6
|
-
&& boolIfDefined(
|
|
1
|
+
import { getEnv } from '../utils/env-vars.js';
|
|
2
|
+
const bool = (k) => ['true', 't', '1'].includes(getEnv(k)?.toLowerCase() ?? '');
|
|
3
|
+
const boolIfDefined = (k) => getEnv(k) != null ? bool(k) : true;
|
|
4
|
+
const enabled = () => !bool('NO_COLOR')
|
|
5
|
+
&& !bool('MIKRO_ORM_NO_COLOR')
|
|
6
|
+
&& boolIfDefined('FORCE_COLOR')
|
|
7
|
+
&& boolIfDefined('MIKRO_ORM_COLORS');
|
|
7
8
|
const wrap = (fn) => (text) => enabled() ? fn(text) : text;
|
|
8
9
|
/** @internal */
|
|
9
10
|
export const colors = {
|
package/logging/inspect.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
let nodeInspect;
|
|
2
2
|
/** @internal */
|
|
3
3
|
export function inspect(value, options) {
|
|
4
|
-
|
|
5
|
-
/* v8 ignore else */
|
|
6
|
-
if (globalThis.process?.getBuiltinModule) {
|
|
7
|
-
nodeInspect = globalThis.process.getBuiltinModule('node:util').inspect;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
4
|
+
nodeInspect ??= globalThis.process?.getBuiltinModule?.('node:util').inspect;
|
|
10
5
|
/* v8 ignore else */
|
|
11
6
|
if (nodeInspect) {
|
|
12
7
|
return nodeInspect(value, options);
|
|
@@ -153,15 +153,19 @@ export class MetadataDiscovery {
|
|
|
153
153
|
const { entities, entitiesTs, baseDir } = this.config.getAll();
|
|
154
154
|
const targets = (preferTs && entitiesTs.length > 0) ? entitiesTs : entities;
|
|
155
155
|
const processed = [];
|
|
156
|
+
const paths = [];
|
|
156
157
|
for (const entity of targets) {
|
|
157
158
|
if (typeof entity === 'string') {
|
|
158
|
-
|
|
159
|
-
processed.push(...await discoverEntities(entity, { baseDir }));
|
|
159
|
+
paths.push(entity);
|
|
160
160
|
}
|
|
161
161
|
else {
|
|
162
162
|
processed.push(entity);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
+
if (paths.length > 0) {
|
|
166
|
+
const { discoverEntities } = await import('@mikro-orm/core/file-discovery');
|
|
167
|
+
processed.push(...await discoverEntities(paths, { baseDir }));
|
|
168
|
+
}
|
|
165
169
|
return this.discoverReferences(processed);
|
|
166
170
|
}
|
|
167
171
|
discoverMissingTargets() {
|
|
@@ -253,7 +257,7 @@ export class MetadataDiscovery {
|
|
|
253
257
|
const path = entity[MetadataStorage.PATH_SYMBOL];
|
|
254
258
|
if (path) {
|
|
255
259
|
const meta = Utils.copy(MetadataStorage.getMetadata(entity.name, path), false);
|
|
256
|
-
meta.path =
|
|
260
|
+
meta.path = path;
|
|
257
261
|
this.metadata.set(entity.name, meta);
|
|
258
262
|
}
|
|
259
263
|
const exists = this.metadata.has(entity.name);
|
|
@@ -279,7 +283,7 @@ export class MetadataDiscovery {
|
|
|
279
283
|
const path = meta.path;
|
|
280
284
|
this.logger.log('discovery', `- processing entity ${colors.cyan(meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
|
|
281
285
|
const root = this.getRootEntity(meta);
|
|
282
|
-
schema.meta.path =
|
|
286
|
+
schema.meta.path = meta.path;
|
|
283
287
|
const cache = this.metadataProvider.getCachedMetadata(meta, root);
|
|
284
288
|
if (cache) {
|
|
285
289
|
this.logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
|
|
@@ -4,8 +4,8 @@ import { Utils } from '../utils/Utils.js';
|
|
|
4
4
|
import { MetadataStorage } from './MetadataStorage.js';
|
|
5
5
|
import { EntitySchema } from './EntitySchema.js';
|
|
6
6
|
async function getEntityClassOrSchema(filepath, allTargets, baseDir) {
|
|
7
|
-
const path =
|
|
8
|
-
const exports = await
|
|
7
|
+
const path = fs.normalizePath(baseDir, filepath);
|
|
8
|
+
const exports = await fs.dynamicImport(path);
|
|
9
9
|
const targets = Object.values(exports);
|
|
10
10
|
// ignore class implementations that are linked from an EntitySchema
|
|
11
11
|
for (const item of targets) {
|
|
@@ -25,9 +25,9 @@ async function getEntityClassOrSchema(filepath, allTargets, baseDir) {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
export async function discoverEntities(paths, options) {
|
|
28
|
-
paths = Utils.asArray(paths).map(path =>
|
|
29
|
-
const baseDir = options?.baseDir ?? process.cwd();
|
|
30
|
-
const files = fs.glob(paths,
|
|
28
|
+
paths = Utils.asArray(paths).map(path => fs.normalizePath(path));
|
|
29
|
+
const baseDir = fs.absolutePath(options?.baseDir ?? process.cwd());
|
|
30
|
+
const files = fs.glob(paths, fs.normalizePath(baseDir));
|
|
31
31
|
const found = new Map();
|
|
32
32
|
for (const filepath of files) {
|
|
33
33
|
const filename = basename(filepath);
|
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.109",
|
|
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",
|
package/utils/Configuration.js
CHANGED
|
@@ -10,6 +10,7 @@ import { RequestContext } from './RequestContext.js';
|
|
|
10
10
|
import { DataloaderType, FlushMode, LoadStrategy, PopulateHint } from '../enums.js';
|
|
11
11
|
import { MemoryCacheAdapter } from '../cache/MemoryCacheAdapter.js';
|
|
12
12
|
import { EntityComparator } from './EntityComparator.js';
|
|
13
|
+
import { setEnv } from './env-vars.js';
|
|
13
14
|
const DEFAULTS = {
|
|
14
15
|
pool: {},
|
|
15
16
|
entities: [],
|
|
@@ -34,7 +35,7 @@ const DEFAULTS = {
|
|
|
34
35
|
colors: true,
|
|
35
36
|
findOneOrFailHandler: (entityName, where) => NotFoundError.findOneFailed(entityName, where),
|
|
36
37
|
findExactlyOneOrFailHandler: (entityName, where) => NotFoundError.findExactlyOneFailed(entityName, where),
|
|
37
|
-
baseDir: process
|
|
38
|
+
baseDir: globalThis.process?.cwd?.(),
|
|
38
39
|
hydrator: ObjectHydrator,
|
|
39
40
|
flushMode: FlushMode.AUTO,
|
|
40
41
|
loadStrategy: LoadStrategy.BALANCED,
|
|
@@ -135,10 +136,9 @@ export class Configuration {
|
|
|
135
136
|
extensions = new Map();
|
|
136
137
|
constructor(options, validate = true) {
|
|
137
138
|
if (options.dynamicImportProvider) {
|
|
138
|
-
|
|
139
|
+
globalThis.dynamicImportProvider = options.dynamicImportProvider;
|
|
139
140
|
}
|
|
140
141
|
this.options = Utils.mergeConfig({}, DEFAULTS, options);
|
|
141
|
-
this.options.baseDir = Utils.absolutePath(this.options.baseDir);
|
|
142
142
|
if (validate) {
|
|
143
143
|
this.validateOptions();
|
|
144
144
|
}
|
|
@@ -328,7 +328,7 @@ export class Configuration {
|
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
330
|
sync() {
|
|
331
|
-
|
|
331
|
+
setEnv('MIKRO_ORM_COLORS', this.options.colors);
|
|
332
332
|
this.logger.setDebugMode(this.options.debug);
|
|
333
333
|
}
|
|
334
334
|
validateOptions() {
|
package/utils/Utils.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ export declare function parseJsonSafe<T = unknown>(value: unknown): T;
|
|
|
14
14
|
export declare class Utils {
|
|
15
15
|
#private;
|
|
16
16
|
static readonly PK_SEPARATOR = "~~~";
|
|
17
|
-
static dynamicImportProvider: (id: string) => Promise<any>;
|
|
18
17
|
/**
|
|
19
18
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
20
19
|
*/
|
|
@@ -129,25 +128,6 @@ export declare class Utils {
|
|
|
129
128
|
*/
|
|
130
129
|
static runSerial<T = any, U = any>(items: Iterable<U>, cb: (item: U) => Promise<T>): Promise<T[]>;
|
|
131
130
|
static isCollection<T extends object, O extends object = object>(item: any): item is Collection<T, O>;
|
|
132
|
-
static fileURLToPath(url: string | URL): string;
|
|
133
|
-
/**
|
|
134
|
-
* Resolves and normalizes a series of path parts relative to each preceding part.
|
|
135
|
-
* If any part is a `file:` URL, it is converted to a local path. If any part is an
|
|
136
|
-
* absolute path, it replaces preceding paths (similar to `path.resolve` in NodeJS).
|
|
137
|
-
* Trailing directory separators are removed, and all directory separators are converted
|
|
138
|
-
* to POSIX-style separators (`/`).
|
|
139
|
-
*/
|
|
140
|
-
static normalizePath(...parts: string[]): string;
|
|
141
|
-
/**
|
|
142
|
-
* Determines the relative path between two paths. If either path is a `file:` URL,
|
|
143
|
-
* it is converted to a local path.
|
|
144
|
-
*/
|
|
145
|
-
static relativePath(path: string, relativeTo: string): string;
|
|
146
|
-
/**
|
|
147
|
-
* Computes the absolute path to for the given path relative to the provided base directory.
|
|
148
|
-
* If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
|
|
149
|
-
*/
|
|
150
|
-
static absolutePath(path: string, baseDir?: string): string;
|
|
151
131
|
static hash(data: string, length?: number): string;
|
|
152
132
|
static runIfNotEmpty(clause: () => any, data: any): void;
|
|
153
133
|
static defaultValue<T extends Dictionary>(prop: T, option: keyof T, defaultValue: any): void;
|
|
@@ -161,7 +141,6 @@ export declare class Utils {
|
|
|
161
141
|
static flatten<T>(arrays: T[][]): T[];
|
|
162
142
|
static isOperator(key: PropertyKey, includeGroupOperators?: boolean): boolean;
|
|
163
143
|
static hasNestedKey(object: unknown, key: string): boolean;
|
|
164
|
-
static dynamicImport<T = any>(id: string): Promise<T>;
|
|
165
144
|
static getORMVersion(): string;
|
|
166
145
|
static createFunction(context: Map<string, any>, code: string): any;
|
|
167
146
|
static callCompiledFunction<T extends unknown[], R>(fn: (...args: T) => R, ...args: T): R;
|
package/utils/Utils.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { isAbsolute, normalize, relative } from 'node:path';
|
|
2
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
1
|
import { clone } from './clone.js';
|
|
4
2
|
import { GroupOperator, PlainObject, QueryOperator, ReferenceKind } from '../enums.js';
|
|
5
3
|
import { helper } from '../entity/wrap.js';
|
|
@@ -125,9 +123,7 @@ export function parseJsonSafe(value) {
|
|
|
125
123
|
}
|
|
126
124
|
export class Utils {
|
|
127
125
|
static PK_SEPARATOR = '~~~';
|
|
128
|
-
static #ORM_VERSION = '7.0.0-dev.
|
|
129
|
-
/* v8 ignore next */
|
|
130
|
-
static dynamicImportProvider = (id) => import(id);
|
|
126
|
+
static #ORM_VERSION = '7.0.0-dev.109';
|
|
131
127
|
/**
|
|
132
128
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
133
129
|
*/
|
|
@@ -537,14 +533,16 @@ export class Utils {
|
|
|
537
533
|
* Tries to detect TypeScript support.
|
|
538
534
|
*/
|
|
539
535
|
static detectTypeScriptSupport() {
|
|
536
|
+
/* v8 ignore next */
|
|
537
|
+
const process = globalThis.process ?? {};
|
|
540
538
|
/* v8 ignore next */
|
|
541
539
|
return process.argv[0].endsWith('ts-node') // running via ts-node directly
|
|
542
|
-
|| !!process.env
|
|
543
|
-
|| !!process.env
|
|
544
|
-
|| !!process.env
|
|
545
|
-
|| !!process.versions
|
|
546
|
-
|| process.argv
|
|
547
|
-
|| process.execArgv
|
|
540
|
+
|| !!process.env?.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS // forced explicitly or enabled via `registerTypeScriptSupport()`
|
|
541
|
+
|| !!process.env?.TS_JEST // check if ts-jest is used
|
|
542
|
+
|| !!process.env?.VITEST // check if vitest is used
|
|
543
|
+
|| !!process.versions?.bun // check if bun is used
|
|
544
|
+
|| process.argv?.slice(1).some(arg => arg.match(/\.([mc]?ts|tsx)$/)) // executing `.ts` file
|
|
545
|
+
|| process.execArgv?.some(arg => {
|
|
548
546
|
return arg.includes('ts-node') // check for ts-node loader
|
|
549
547
|
|| arg.includes('@swc-node/register') // check for swc-node/register loader
|
|
550
548
|
|| arg.includes('node_modules/tsx/'); // check for tsx loader
|
|
@@ -589,64 +587,6 @@ export class Utils {
|
|
|
589
587
|
static isCollection(item) {
|
|
590
588
|
return item?.__collection;
|
|
591
589
|
}
|
|
592
|
-
static fileURLToPath(url) {
|
|
593
|
-
// expose `fileURLToPath` on Utils so that it can be properly mocked in tests
|
|
594
|
-
return fileURLToPath(url);
|
|
595
|
-
}
|
|
596
|
-
/**
|
|
597
|
-
* Resolves and normalizes a series of path parts relative to each preceding part.
|
|
598
|
-
* If any part is a `file:` URL, it is converted to a local path. If any part is an
|
|
599
|
-
* absolute path, it replaces preceding paths (similar to `path.resolve` in NodeJS).
|
|
600
|
-
* Trailing directory separators are removed, and all directory separators are converted
|
|
601
|
-
* to POSIX-style separators (`/`).
|
|
602
|
-
*/
|
|
603
|
-
static normalizePath(...parts) {
|
|
604
|
-
let start = 0;
|
|
605
|
-
for (let i = 0; i < parts.length; i++) {
|
|
606
|
-
const part = parts[i];
|
|
607
|
-
if (isAbsolute(part)) {
|
|
608
|
-
start = i;
|
|
609
|
-
}
|
|
610
|
-
else if (part.startsWith('file:')) {
|
|
611
|
-
start = i;
|
|
612
|
-
parts[i] = Utils.fileURLToPath(part);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
if (start > 0) {
|
|
616
|
-
parts = parts.slice(start);
|
|
617
|
-
}
|
|
618
|
-
let path = parts.join('/').replace(/\\/g, '/').replace(/\/$/, '');
|
|
619
|
-
path = normalize(path).replace(/\\/g, '/');
|
|
620
|
-
return (path.match(/^[/.]|[a-zA-Z]:/) || path.startsWith('!')) ? path : './' + path;
|
|
621
|
-
}
|
|
622
|
-
/**
|
|
623
|
-
* Determines the relative path between two paths. If either path is a `file:` URL,
|
|
624
|
-
* it is converted to a local path.
|
|
625
|
-
*/
|
|
626
|
-
static relativePath(path, relativeTo) {
|
|
627
|
-
if (!path) {
|
|
628
|
-
return path;
|
|
629
|
-
}
|
|
630
|
-
path = Utils.normalizePath(path);
|
|
631
|
-
if (path.startsWith('.')) {
|
|
632
|
-
return path;
|
|
633
|
-
}
|
|
634
|
-
path = relative(Utils.normalizePath(relativeTo), path);
|
|
635
|
-
return Utils.normalizePath(path);
|
|
636
|
-
}
|
|
637
|
-
/**
|
|
638
|
-
* Computes the absolute path to for the given path relative to the provided base directory.
|
|
639
|
-
* If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
|
|
640
|
-
*/
|
|
641
|
-
static absolutePath(path, baseDir = process.cwd()) {
|
|
642
|
-
if (!path) {
|
|
643
|
-
return Utils.normalizePath(baseDir);
|
|
644
|
-
}
|
|
645
|
-
if (!isAbsolute(path) && !path.startsWith('file://')) {
|
|
646
|
-
path = baseDir + '/' + path;
|
|
647
|
-
}
|
|
648
|
-
return Utils.normalizePath(path);
|
|
649
|
-
}
|
|
650
590
|
// FNV-1a 64-bit
|
|
651
591
|
static hash(data, length) {
|
|
652
592
|
let h1 = 0xcbf29ce484222325n;
|
|
@@ -723,11 +663,6 @@ export class Utils {
|
|
|
723
663
|
}
|
|
724
664
|
return false;
|
|
725
665
|
}
|
|
726
|
-
static async dynamicImport(id) {
|
|
727
|
-
/* v8 ignore next */
|
|
728
|
-
const specifier = id.startsWith('file://') ? id : pathToFileURL(id).href;
|
|
729
|
-
return this.dynamicImportProvider(specifier);
|
|
730
|
-
}
|
|
731
666
|
static getORMVersion() {
|
|
732
667
|
return this.#ORM_VERSION;
|
|
733
668
|
}
|
package/utils/env-vars.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { type Options } from './Configuration.js';
|
|
2
2
|
/** @internal */
|
|
3
|
+
export declare function setEnv(key: string, value: unknown): void;
|
|
4
|
+
/** @internal */
|
|
5
|
+
export declare function getEnv(key: string): string | undefined;
|
|
6
|
+
/** @internal */
|
|
3
7
|
export declare function loadEnvironmentVars(): Partial<Options>;
|
package/utils/env-vars.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { Utils } from './Utils.js';
|
|
2
2
|
/** @internal */
|
|
3
|
+
export function setEnv(key, value) {
|
|
4
|
+
if (globalThis.process?.env) {
|
|
5
|
+
globalThis.process.env[key] = String(value);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/** @internal */
|
|
9
|
+
export function getEnv(key) {
|
|
10
|
+
return globalThis.process?.env?.[key];
|
|
11
|
+
}
|
|
12
|
+
/** @internal */
|
|
3
13
|
export function loadEnvironmentVars() {
|
|
4
14
|
const ret = {};
|
|
5
15
|
const getEnvKey = (key, envPrefix = 'MIKRO_ORM_') => {
|
|
@@ -13,8 +23,9 @@ export function loadEnvironmentVars() {
|
|
|
13
23
|
const num = (v) => +v;
|
|
14
24
|
const read = (o, envPrefix, key, mapper = v => v) => {
|
|
15
25
|
const envKey = getEnvKey(key, envPrefix);
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
/* v8 ignore next */
|
|
27
|
+
if (envKey in (globalThis.process?.env ?? {})) {
|
|
28
|
+
o[key] = mapper(getEnv(envKey));
|
|
18
29
|
}
|
|
19
30
|
};
|
|
20
31
|
const cleanup = (o, k) => Utils.hasObjectKeys(o[k]) ? {} : delete o[k];
|
package/utils/fs-utils.d.ts
CHANGED
|
@@ -4,9 +4,29 @@ export declare const fs: {
|
|
|
4
4
|
ensureDir(path: string): void;
|
|
5
5
|
readJSONSync<T = Dictionary>(path: string): T;
|
|
6
6
|
glob(input: string | string[], cwd?: string): string[];
|
|
7
|
+
resolveGlob(input: string | string[], cwd?: string): string[];
|
|
7
8
|
getPackageConfig<T extends Dictionary>(basePath?: string): T;
|
|
8
9
|
getORMPackages(): Set<string>;
|
|
9
10
|
getORMPackageVersion(name: string): string | undefined;
|
|
10
11
|
checkPackageVersion(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Resolves and normalizes a series of path parts relative to each preceding part.
|
|
14
|
+
* If any part is a `file:` URL, it is converted to a local path. If any part is an
|
|
15
|
+
* absolute path, it replaces preceding paths (similar to `path.resolve` in NodeJS).
|
|
16
|
+
* Trailing directory separators are removed, and all directory separators are converted
|
|
17
|
+
* to POSIX-style separators (`/`).
|
|
18
|
+
*/
|
|
19
|
+
normalizePath(...parts: string[]): string;
|
|
20
|
+
/**
|
|
21
|
+
* Determines the relative path between two paths. If either path is a `file:` URL,
|
|
22
|
+
* it is converted to a local path.
|
|
23
|
+
*/
|
|
24
|
+
relativePath(path: string, relativeTo: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Computes the absolute path to for the given path relative to the provided base directory.
|
|
27
|
+
* If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
|
|
28
|
+
*/
|
|
29
|
+
absolutePath(path: string, baseDir?: string): string;
|
|
30
|
+
dynamicImport<T = any>(id: string): Promise<T>;
|
|
11
31
|
};
|
|
12
32
|
export * from '../cache/FileCacheAdapter.js';
|
package/utils/fs-utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, globSync, mkdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { isAbsolute, join, normalize, relative } from 'node:path';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
4
|
import { Utils } from './Utils.js';
|
|
5
5
|
import { colors } from '../logging/colors.js';
|
|
6
6
|
export const fs = {
|
|
@@ -20,13 +20,34 @@ export const fs = {
|
|
|
20
20
|
return JSON.parse(file.toString());
|
|
21
21
|
},
|
|
22
22
|
glob(input, cwd) {
|
|
23
|
+
const patterns = Array.isArray(input) ? input : [input];
|
|
24
|
+
const positive = [];
|
|
25
|
+
const negative = [];
|
|
26
|
+
for (const p of patterns) {
|
|
27
|
+
if (p.startsWith('!')) {
|
|
28
|
+
negative.push(p.slice(1));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
positive.push(p);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const included = new Set(this.resolveGlob(positive, cwd));
|
|
35
|
+
if (included.size > 0 && negative.length > 0) {
|
|
36
|
+
const excluded = this.resolveGlob(negative, cwd);
|
|
37
|
+
for (const file of excluded) {
|
|
38
|
+
included.delete(file);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return [...included];
|
|
42
|
+
},
|
|
43
|
+
resolveGlob(input, cwd) {
|
|
23
44
|
if (Array.isArray(input)) {
|
|
24
|
-
return input.flatMap(paths => this.
|
|
45
|
+
return input.flatMap(paths => this.resolveGlob(paths, cwd));
|
|
25
46
|
}
|
|
26
47
|
const hasGlobChars = /[*?[\]]/.test(input);
|
|
27
48
|
if (!hasGlobChars) {
|
|
28
49
|
try {
|
|
29
|
-
const s = statSync(cwd ?
|
|
50
|
+
const s = statSync(cwd ? this.normalizePath(cwd, input) : input);
|
|
30
51
|
if (s.isDirectory()) {
|
|
31
52
|
const files = globSync(join(input, '**'), { cwd, withFileTypes: true });
|
|
32
53
|
return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
|
|
@@ -93,5 +114,65 @@ export const fs = {
|
|
|
93
114
|
}
|
|
94
115
|
}
|
|
95
116
|
},
|
|
117
|
+
/**
|
|
118
|
+
* Resolves and normalizes a series of path parts relative to each preceding part.
|
|
119
|
+
* If any part is a `file:` URL, it is converted to a local path. If any part is an
|
|
120
|
+
* absolute path, it replaces preceding paths (similar to `path.resolve` in NodeJS).
|
|
121
|
+
* Trailing directory separators are removed, and all directory separators are converted
|
|
122
|
+
* to POSIX-style separators (`/`).
|
|
123
|
+
*/
|
|
124
|
+
normalizePath(...parts) {
|
|
125
|
+
let start = 0;
|
|
126
|
+
for (let i = 0; i < parts.length; i++) {
|
|
127
|
+
const part = parts[i];
|
|
128
|
+
if (isAbsolute(part)) {
|
|
129
|
+
start = i;
|
|
130
|
+
}
|
|
131
|
+
else if (part.startsWith('file:')) {
|
|
132
|
+
start = i;
|
|
133
|
+
parts[i] = fileURLToPath(part);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (start > 0) {
|
|
137
|
+
parts = parts.slice(start);
|
|
138
|
+
}
|
|
139
|
+
let path = parts.join('/').replace(/\\/g, '/').replace(/\/$/, '');
|
|
140
|
+
path = normalize(path).replace(/\\/g, '/');
|
|
141
|
+
return (path.match(/^[/.]|[a-zA-Z]:/) || path.startsWith('!')) ? path : './' + path;
|
|
142
|
+
},
|
|
143
|
+
/**
|
|
144
|
+
* Determines the relative path between two paths. If either path is a `file:` URL,
|
|
145
|
+
* it is converted to a local path.
|
|
146
|
+
*/
|
|
147
|
+
relativePath(path, relativeTo) {
|
|
148
|
+
if (!path) {
|
|
149
|
+
return path;
|
|
150
|
+
}
|
|
151
|
+
path = this.normalizePath(path);
|
|
152
|
+
if (path.startsWith('.')) {
|
|
153
|
+
return path;
|
|
154
|
+
}
|
|
155
|
+
path = relative(this.normalizePath(relativeTo), path);
|
|
156
|
+
return this.normalizePath(path);
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* Computes the absolute path to for the given path relative to the provided base directory.
|
|
160
|
+
* If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
|
|
161
|
+
*/
|
|
162
|
+
absolutePath(path, baseDir = process.cwd()) {
|
|
163
|
+
if (!path) {
|
|
164
|
+
return this.normalizePath(baseDir);
|
|
165
|
+
}
|
|
166
|
+
if (!isAbsolute(path) && !path.startsWith('file://')) {
|
|
167
|
+
path = baseDir + '/' + path;
|
|
168
|
+
}
|
|
169
|
+
return this.normalizePath(path);
|
|
170
|
+
},
|
|
171
|
+
async dynamicImport(id) {
|
|
172
|
+
/* v8 ignore next */
|
|
173
|
+
const specifier = id.startsWith('file://') ? id : pathToFileURL(id).href;
|
|
174
|
+
const dynamicImportProvider = globalThis.dynamicImportProvider ?? ((id) => import(id));
|
|
175
|
+
return dynamicImportProvider(specifier);
|
|
176
|
+
},
|
|
96
177
|
};
|
|
97
178
|
export * from '../cache/FileCacheAdapter.js';
|