@mikro-orm/core 7.0.0-dev.99 → 7.0.0-rc.1

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.
Files changed (107) hide show
  1. package/EntityManager.d.ts +34 -17
  2. package/EntityManager.js +95 -103
  3. package/MikroORM.d.ts +5 -5
  4. package/MikroORM.js +25 -20
  5. package/cache/FileCacheAdapter.js +11 -3
  6. package/connections/Connection.d.ts +3 -2
  7. package/connections/Connection.js +4 -3
  8. package/drivers/DatabaseDriver.d.ts +11 -11
  9. package/drivers/DatabaseDriver.js +91 -25
  10. package/drivers/IDatabaseDriver.d.ts +50 -20
  11. package/entity/BaseEntity.d.ts +61 -1
  12. package/entity/Collection.d.ts +8 -1
  13. package/entity/Collection.js +12 -13
  14. package/entity/EntityAssigner.js +9 -9
  15. package/entity/EntityFactory.d.ts +6 -1
  16. package/entity/EntityFactory.js +40 -22
  17. package/entity/EntityHelper.d.ts +2 -2
  18. package/entity/EntityHelper.js +27 -4
  19. package/entity/EntityLoader.d.ts +5 -4
  20. package/entity/EntityLoader.js +193 -80
  21. package/entity/EntityRepository.d.ts +27 -7
  22. package/entity/EntityRepository.js +8 -2
  23. package/entity/PolymorphicRef.d.ts +12 -0
  24. package/entity/PolymorphicRef.js +18 -0
  25. package/entity/WrappedEntity.d.ts +2 -2
  26. package/entity/WrappedEntity.js +1 -1
  27. package/entity/defineEntity.d.ts +89 -50
  28. package/entity/defineEntity.js +12 -0
  29. package/entity/index.d.ts +1 -0
  30. package/entity/index.js +1 -0
  31. package/entity/utils.d.ts +6 -1
  32. package/entity/utils.js +33 -0
  33. package/entity/validators.js +2 -2
  34. package/enums.d.ts +2 -2
  35. package/enums.js +1 -0
  36. package/errors.d.ts +16 -8
  37. package/errors.js +40 -13
  38. package/hydration/ObjectHydrator.js +63 -21
  39. package/index.d.ts +1 -1
  40. package/logging/colors.d.ts +1 -1
  41. package/logging/colors.js +7 -6
  42. package/logging/inspect.js +1 -6
  43. package/metadata/EntitySchema.d.ts +43 -13
  44. package/metadata/EntitySchema.js +82 -27
  45. package/metadata/MetadataDiscovery.d.ts +60 -3
  46. package/metadata/MetadataDiscovery.js +665 -154
  47. package/metadata/MetadataProvider.js +3 -1
  48. package/metadata/MetadataStorage.d.ts +13 -6
  49. package/metadata/MetadataStorage.js +64 -19
  50. package/metadata/MetadataValidator.d.ts +32 -2
  51. package/metadata/MetadataValidator.js +196 -31
  52. package/metadata/discover-entities.js +5 -5
  53. package/metadata/types.d.ts +111 -14
  54. package/naming-strategy/AbstractNamingStrategy.d.ts +11 -3
  55. package/naming-strategy/AbstractNamingStrategy.js +12 -0
  56. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  57. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  58. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  59. package/naming-strategy/MongoNamingStrategy.js +6 -6
  60. package/naming-strategy/NamingStrategy.d.ts +17 -3
  61. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  62. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  63. package/package.json +2 -2
  64. package/platforms/Platform.d.ts +4 -2
  65. package/platforms/Platform.js +5 -2
  66. package/serialization/EntitySerializer.d.ts +3 -0
  67. package/serialization/EntitySerializer.js +15 -13
  68. package/serialization/EntityTransformer.js +6 -6
  69. package/serialization/SerializationContext.d.ts +6 -6
  70. package/typings.d.ts +325 -110
  71. package/typings.js +84 -17
  72. package/unit-of-work/ChangeSet.d.ts +4 -3
  73. package/unit-of-work/ChangeSet.js +2 -3
  74. package/unit-of-work/ChangeSetComputer.d.ts +3 -6
  75. package/unit-of-work/ChangeSetComputer.js +34 -13
  76. package/unit-of-work/ChangeSetPersister.d.ts +12 -10
  77. package/unit-of-work/ChangeSetPersister.js +55 -25
  78. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  79. package/unit-of-work/CommitOrderCalculator.js +13 -13
  80. package/unit-of-work/IdentityMap.d.ts +12 -0
  81. package/unit-of-work/IdentityMap.js +39 -1
  82. package/unit-of-work/UnitOfWork.d.ts +21 -3
  83. package/unit-of-work/UnitOfWork.js +203 -56
  84. package/utils/AbstractSchemaGenerator.js +17 -8
  85. package/utils/AsyncContext.d.ts +6 -0
  86. package/utils/AsyncContext.js +42 -0
  87. package/utils/Configuration.d.ts +52 -11
  88. package/utils/Configuration.js +12 -8
  89. package/utils/Cursor.js +21 -8
  90. package/utils/DataloaderUtils.js +13 -11
  91. package/utils/EntityComparator.d.ts +14 -7
  92. package/utils/EntityComparator.js +132 -46
  93. package/utils/QueryHelper.d.ts +16 -6
  94. package/utils/QueryHelper.js +53 -18
  95. package/utils/RawQueryFragment.d.ts +28 -23
  96. package/utils/RawQueryFragment.js +34 -56
  97. package/utils/RequestContext.js +2 -2
  98. package/utils/TransactionContext.js +2 -2
  99. package/utils/TransactionManager.js +1 -1
  100. package/utils/Utils.d.ts +7 -26
  101. package/utils/Utils.js +25 -79
  102. package/utils/clone.js +7 -21
  103. package/utils/env-vars.d.ts +4 -0
  104. package/utils/env-vars.js +13 -3
  105. package/utils/fs-utils.d.ts +21 -0
  106. package/utils/fs-utils.js +106 -11
  107. package/utils/upsert-utils.d.ts +4 -4
@@ -1,23 +1,25 @@
1
1
  import type { AnyString, Dictionary, EntityKey } from '../typings.js';
2
- export declare class RawQueryFragment {
2
+ declare const rawFragmentSymbolBrand: unique symbol;
3
+ export type RawQueryFragmentSymbol = symbol & {
4
+ readonly [rawFragmentSymbolBrand]: true;
5
+ };
6
+ export declare class RawQueryFragment<Alias extends string = string> {
3
7
  #private;
4
8
  readonly sql: string;
5
9
  readonly params: unknown[];
6
- static cloneRegistry?: Set<string>;
10
+ /** @internal Type-level only - used to track the alias for type inference */
11
+ private readonly __alias?;
7
12
  constructor(sql: string, params?: unknown[]);
8
- as(alias: string): RawQueryFragment;
9
- valueOf(): string;
13
+ get key(): RawQueryFragmentSymbol;
14
+ as<A extends string>(alias: A): RawQueryFragment<A>;
15
+ [Symbol.toPrimitive](hint: 'string'): RawQueryFragmentSymbol;
16
+ get [Symbol.toStringTag](): string;
10
17
  toJSON(): string;
11
- toString(): string;
12
- clone(): RawQueryFragment;
13
- static run<T>(cb: (...args: any[]) => Promise<T>): Promise<T>;
14
- /**
15
- * @internal allows testing we don't leak memory, as the raw fragments cache needs to be cleared automatically
16
- */
17
- static checkCacheSize(): number;
18
- static isKnownFragment(key: string | RawQueryFragment): boolean;
19
- static getKnownFragment(key: string | RawQueryFragment, cleanup?: boolean): RawQueryFragment | undefined;
20
- static remove(key: string): void;
18
+ clone(): this;
19
+ static isKnownFragmentSymbol(key: unknown): key is RawQueryFragmentSymbol;
20
+ static hasObjectFragments(object: unknown): boolean;
21
+ static isKnownFragment(key: unknown): key is RawQueryFragment | symbol;
22
+ static getKnownFragment(key: unknown): RawQueryFragment<any> | undefined;
21
23
  }
22
24
  export { RawQueryFragment as Raw };
23
25
  export declare function isRaw(value: unknown): value is RawQueryFragment;
@@ -80,7 +82,7 @@ export declare const ALIAS_REPLACEMENT_RE = "\\[::alias::\\]";
80
82
  * export class Author { ... }
81
83
  * ```
82
84
  */
83
- export declare function raw<T extends object = any, R = any>(sql: EntityKey<T> | EntityKey<T>[] | AnyString | ((alias: string) => string) | RawQueryFragment, params?: readonly unknown[] | Dictionary<unknown>): NoInfer<R>;
85
+ export declare function raw<R = RawQueryFragment & symbol, T extends object = any>(sql: EntityKey<T> | EntityKey<T>[] | AnyString | ((alias: string) => string) | RawQueryFragment, params?: readonly unknown[] | Dictionary<unknown>): R;
84
86
  /**
85
87
  * Alternative to the `raw()` helper allowing to use it as a tagged template function for the simple cases.
86
88
  *
@@ -93,16 +95,19 @@ export declare function raw<T extends object = any, R = any>(sql: EntityKey<T> |
93
95
  *
94
96
  * // value can be empty array
95
97
  * await em.find(User, { [sql`(select 1 = 1)`]: [] });
98
+ *
99
+ * // with type parameter for assignment without casting
100
+ * entity.date = sql<Date>`now()`;
96
101
  * ```
97
102
  */
98
- export declare function sql(sql: readonly string[], ...values: unknown[]): any;
103
+ export declare function sql<R = RawQueryFragment & symbol>(sql: readonly string[], ...values: unknown[]): R;
99
104
  export declare namespace sql {
100
- var ref: <T extends object>(...keys: string[]) => NoInfer<RawQueryFragment>;
101
- var now: (length?: number) => string;
102
- var lower: <T extends object>(key: string | ((alias: string) => string)) => string;
103
- var upper: <T extends object>(key: string | ((alias: string) => string)) => string;
105
+ var ref: <T extends object = any>(...keys: string[]) => RawQueryFragment<string> & symbol;
106
+ var now: (length?: number) => RawQueryFragment<string> & symbol;
107
+ var lower: <R = RawQueryFragment<string> & symbol, T extends object = any>(key: string | ((alias: string) => string)) => R;
108
+ var upper: <R = RawQueryFragment<string> & symbol, T extends object = any>(key: string | ((alias: string) => string)) => R;
104
109
  }
105
- export declare function createSqlFunction<T extends object, R = string>(func: string, key: string | ((alias: string) => string)): R;
110
+ export declare function createSqlFunction<R = RawQueryFragment & symbol, T extends object = any>(func: string, key: string | ((alias: string) => string)): R;
106
111
  /**
107
112
  * Tag function providing quoting of db identifiers (table name, columns names, index names, ...).
108
113
  *
@@ -111,11 +116,11 @@ export declare function createSqlFunction<T extends object, R = string>(func: st
111
116
  * ```ts
112
117
  * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("name")
113
118
  * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`name`)
114
- * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
119
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns, indexName) => quote`create index ${indexName} on ${table} (${columns.name})` })
115
120
  * @Entity({ schema: 'library' })
116
121
  * export class Author { ... }
117
122
  * ```
118
123
  */
119
124
  export declare function quote(expParts: readonly string[], ...values: (string | {
120
125
  toString(): string;
121
- })[]): any;
126
+ })[]): RawQueryFragment<string> & symbol;
@@ -1,81 +1,60 @@
1
- import { AsyncLocalStorage } from 'node:async_hooks';
2
1
  import { Utils } from './Utils.js';
3
2
  export class RawQueryFragment {
4
3
  sql;
5
4
  params;
6
- static #rawQueryCache = new Map();
7
- static #storage = new AsyncLocalStorage();
8
- static #index = 0n;
9
- static cloneRegistry;
10
- #used = 0;
5
+ static #rawQueryReferences = new WeakMap();
11
6
  #key;
12
7
  constructor(sql, params = []) {
13
8
  this.sql = sql;
14
9
  this.params = params;
15
- this.#key = `[raw]: ${this.sql} (#${RawQueryFragment.#index++})`;
10
+ }
11
+ get key() {
12
+ if (!this.#key) {
13
+ this.#key = Symbol(this.toJSON());
14
+ RawQueryFragment.#rawQueryReferences.set(this.#key, this);
15
+ }
16
+ return this.#key;
16
17
  }
17
18
  as(alias) {
18
19
  return new RawQueryFragment(`${this.sql} as ??`, [...this.params, alias]);
19
20
  }
20
- valueOf() {
21
+ [Symbol.toPrimitive](hint) {
22
+ // if a fragment is converted to string (used as an object key), return a unique symbol
23
+ // and save a weak reference to map so we can retrieve it when compiling the query
24
+ if (hint === 'string') {
25
+ return this.key;
26
+ }
21
27
  throw new Error(`Trying to modify raw SQL fragment: '${this.sql}'`);
22
28
  }
23
- toJSON() {
24
- return this.#key;
29
+ get [Symbol.toStringTag]() {
30
+ return this.toJSON();
25
31
  }
26
- toString() {
27
- RawQueryFragment.#rawQueryCache.set(this.#key, this);
28
- this.#used++;
29
- return this.#key;
32
+ toJSON() {
33
+ return `raw('${this.sql}')`;
30
34
  }
31
35
  clone() {
32
- RawQueryFragment.cloneRegistry?.add(this.#key);
33
- return new RawQueryFragment(this.sql, this.params);
34
- }
35
- static async run(cb) {
36
- const removeStack = new Set();
37
- const res = await this.#storage.run(removeStack, cb);
38
- removeStack.forEach(key => RawQueryFragment.remove(key));
39
- removeStack.clear();
40
- return res;
41
- }
42
- /**
43
- * @internal allows testing we don't leak memory, as the raw fragments cache needs to be cleared automatically
44
- */
45
- static checkCacheSize() {
46
- return this.#rawQueryCache.size;
36
+ return this;
37
+ }
38
+ static isKnownFragmentSymbol(key) {
39
+ return typeof key === 'symbol' && this.#rawQueryReferences.has(key);
40
+ }
41
+ static hasObjectFragments(object) {
42
+ return Utils.isPlainObject(object) && Object.getOwnPropertySymbols(object).some(symbol => this.isKnownFragmentSymbol(symbol));
47
43
  }
48
44
  static isKnownFragment(key) {
49
45
  if (key instanceof RawQueryFragment) {
50
46
  return true;
51
47
  }
52
- return this.#rawQueryCache.has(key);
48
+ return this.isKnownFragmentSymbol(key);
53
49
  }
54
- static getKnownFragment(key, cleanup = true) {
50
+ static getKnownFragment(key) {
55
51
  if (key instanceof RawQueryFragment) {
56
52
  return key;
57
53
  }
58
- const raw = this.#rawQueryCache.get(key);
59
- if (raw && cleanup) {
60
- this.remove(key);
61
- }
62
- return raw;
63
- }
64
- static remove(key) {
65
- const raw = this.#rawQueryCache.get(key);
66
- if (!raw) {
54
+ if (typeof key !== 'symbol') {
67
55
  return;
68
56
  }
69
- raw.#used--;
70
- if (raw.#used <= 0) {
71
- const removeStack = this.#storage.getStore();
72
- if (removeStack) {
73
- removeStack.add(key);
74
- }
75
- else {
76
- this.#rawQueryCache.delete(key);
77
- }
78
- }
57
+ return this.#rawQueryReferences.get(key);
79
58
  }
80
59
  /** @ignore */
81
60
  /* v8 ignore next */
@@ -190,14 +169,13 @@ export function raw(sql, params) {
190
169
  *
191
170
  * // value can be empty array
192
171
  * await em.find(User, { [sql`(select 1 = 1)`]: [] });
172
+ *
173
+ * // with type parameter for assignment without casting
174
+ * entity.date = sql<Date>`now()`;
193
175
  * ```
194
176
  */
195
177
  export function sql(sql, ...values) {
196
- return raw(sql.reduce((query, queryPart, i) => {
197
- const valueExists = i < values.length;
198
- const text = query + queryPart;
199
- return valueExists ? text + '?' : text;
200
- }, ''), values);
178
+ return raw(sql.join('?'), values);
201
179
  }
202
180
  export function createSqlFunction(func, key) {
203
181
  if (typeof key === 'string') {
@@ -217,7 +195,7 @@ sql.upper = (key) => createSqlFunction('upper', key);
217
195
  * ```ts
218
196
  * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("name")
219
197
  * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`name`)
220
- * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
198
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns, indexName) => quote`create index ${indexName} on ${table} (${columns.name})` })
221
199
  * @Entity({ schema: 'library' })
222
200
  * export class Author { ... }
223
201
  * ```
@@ -1,10 +1,10 @@
1
- import { AsyncLocalStorage } from 'node:async_hooks';
1
+ import { createAsyncContext } from './AsyncContext.js';
2
2
  /**
3
3
  * Uses `AsyncLocalStorage` to create async context that holds the current EM fork.
4
4
  */
5
5
  export class RequestContext {
6
6
  map;
7
- static storage = new AsyncLocalStorage();
7
+ static storage = createAsyncContext();
8
8
  static counter = 1;
9
9
  id = RequestContext.counter++;
10
10
  constructor(map) {
@@ -1,7 +1,7 @@
1
- import { AsyncLocalStorage } from 'node:async_hooks';
1
+ import { createAsyncContext } from './AsyncContext.js';
2
2
  export class TransactionContext {
3
3
  em;
4
- static storage = new AsyncLocalStorage();
4
+ static storage = createAsyncContext();
5
5
  id;
6
6
  constructor(em) {
7
7
  this.em = em;
@@ -161,7 +161,7 @@ export class TransactionManager {
161
161
  const wrapped = helper(entity);
162
162
  const meta = wrapped.__meta;
163
163
  // eslint-disable-next-line dot-notation
164
- const parentEntity = parentUoW.getById(meta.className, wrapped.getPrimaryKey(), parent['_schema'], true);
164
+ const parentEntity = parentUoW.getById(meta.class, wrapped.getPrimaryKey(), parent['_schema'], true);
165
165
  if (parentEntity && parentEntity !== entity) {
166
166
  const parentWrapped = helper(parentEntity);
167
167
  parentWrapped.__data = wrapped.__data;
package/utils/Utils.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import type { Dictionary, EntityData, EntityDictionary, EntityKey, EntityMetadata, EntityName, EntityProperty, Primary } from '../typings.js';
1
+ import type { CompiledFunctions, Dictionary, EntityData, EntityDictionary, EntityKey, EntityMetadata, EntityName, EntityProperty, Primary } from '../typings.js';
2
2
  import type { Collection } from '../entity/Collection.js';
3
3
  import type { Platform } from '../platforms/Platform.js';
4
- import type { ScalarReference } from '../entity/Reference.js';
4
+ import { type ScalarReference } from '../entity/Reference.js';
5
+ import { type RawQueryFragmentSymbol } from './RawQueryFragment.js';
5
6
  export declare function compareObjects(a: any, b: any): boolean;
6
7
  export declare function compareArrays(a: any[] | string, b: any[] | string): boolean;
7
8
  export declare function compareBooleans(a: unknown, b: unknown): boolean;
@@ -14,7 +15,6 @@ export declare function parseJsonSafe<T = unknown>(value: unknown): T;
14
15
  export declare class Utils {
15
16
  #private;
16
17
  static readonly PK_SEPARATOR = "~~~";
17
- static dynamicImportProvider: (id: string) => Promise<any>;
18
18
  /**
19
19
  * Checks if the argument is instance of `Object`. Returns false for arrays.
20
20
  */
@@ -110,7 +110,7 @@ export declare class Utils {
110
110
  /**
111
111
  * Gets string name of given class.
112
112
  */
113
- static className<T>(classOrName: EntityName<T>): string;
113
+ static className<T>(classOrName: string | EntityName<T>): string;
114
114
  static extractChildElements(items: string[], prefix: string, allSymbol?: string): string[];
115
115
  /**
116
116
  * Tries to detect TypeScript support.
@@ -129,25 +129,6 @@ export declare class Utils {
129
129
  */
130
130
  static runSerial<T = any, U = any>(items: Iterable<U>, cb: (item: U) => Promise<T>): Promise<T[]>;
131
131
  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
132
  static hash(data: string, length?: number): string;
152
133
  static runIfNotEmpty(clause: () => any, data: any): void;
153
134
  static defaultValue<T extends Dictionary>(prop: T, option: keyof T, defaultValue: any): void;
@@ -158,12 +139,11 @@ export declare class Utils {
158
139
  * Extracts all possible values of a TS enum. Works with both string and numeric enums.
159
140
  */
160
141
  static extractEnumValues(target: Dictionary): (string | number)[];
161
- static flatten<T>(arrays: T[][]): T[];
142
+ static flatten<T>(arrays: T[][], deep?: boolean): T[];
162
143
  static isOperator(key: PropertyKey, includeGroupOperators?: boolean): boolean;
163
144
  static hasNestedKey(object: unknown, key: string): boolean;
164
- static dynamicImport<T = any>(id: string): Promise<T>;
165
145
  static getORMVersion(): string;
166
- static createFunction(context: Map<string, any>, code: string): any;
146
+ static createFunction(context: Map<string, any>, code: string, compiledFunctions?: CompiledFunctions, key?: string): any;
167
147
  static callCompiledFunction<T extends unknown[], R>(fn: (...args: T) => R, ...args: T): R;
168
148
  static unwrapProperty<T>(entity: T, meta: EntityMetadata<T>, prop: EntityProperty<T>, payload?: boolean): [unknown, number[]][];
169
149
  static setPayloadProperty<T>(entity: EntityDictionary<T>, meta: EntityMetadata<T>, prop: EntityProperty<T>, value: unknown, idx: number[]): void;
@@ -176,4 +156,5 @@ export declare class Utils {
176
156
  static values<T extends object>(obj: T): T[keyof T][];
177
157
  static entries<T extends object>(obj: T): [keyof T, T[keyof T]][];
178
158
  static primaryKeyToObject<T>(meta: EntityMetadata<T>, primaryKey: Primary<T> | T, visible?: (keyof T)[]): T;
159
+ static getObjectQueryKeys<T extends Dictionary, K extends string = Extract<keyof T, string>>(obj: T): (K | RawQueryFragmentSymbol)[];
179
160
  }
package/utils/Utils.js CHANGED
@@ -1,8 +1,7 @@
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';
4
+ import { Raw } from './RawQueryFragment.js';
6
5
  function compareConstructors(a, b) {
7
6
  if (a.constructor === b.constructor) {
8
7
  return true;
@@ -36,7 +35,6 @@ export function compareObjects(a, b) {
36
35
  }
37
36
  /* v8 ignore next */
38
37
  if ((typeof a === 'function' && typeof b === 'function') ||
39
- (typeof a === 'object' && a.client && ['Ref', 'Raw'].includes(a.constructor.name) && typeof b === 'object' && b.client && ['Ref', 'Raw'].includes(b.constructor.name)) || // knex qb
40
38
  (a instanceof RegExp && b instanceof RegExp) ||
41
39
  (a instanceof String && b instanceof String) ||
42
40
  (a instanceof Number && b instanceof Number)) {
@@ -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.99';
129
- /* v8 ignore next */
130
- static dynamicImportProvider = (id) => import(id);
126
+ static #ORM_VERSION = '7.0.0-rc.1';
131
127
  /**
132
128
  * Checks if the argument is instance of `Object`. Returns false for arrays.
133
129
  */
@@ -538,13 +534,15 @@ export class Utils {
538
534
  */
539
535
  static detectTypeScriptSupport() {
540
536
  /* v8 ignore next */
541
- return process.argv[0].endsWith('ts-node') // running via ts-node directly
542
- || !!process.env.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS // forced explicitly or enabled via `registerTypeScriptSupport()`
543
- || !!process.env.TS_JEST // check if ts-jest is used (works only with v27.0.4+)
544
- || !!process.env.VITEST // check if vitest is used
545
- || !!process.versions.bun // check if bun is used
546
- || process.argv.slice(1).some(arg => arg.match(/\.([mc]?ts|tsx)$/)) // executing `.ts` file
547
- || process.execArgv.some(arg => {
537
+ const process = globalThis.process ?? {};
538
+ /* v8 ignore next */
539
+ return process.argv?.[0]?.endsWith('ts-node') // running via ts-node directly
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;
@@ -702,8 +642,8 @@ export class Utils {
702
642
  }
703
643
  return values;
704
644
  }
705
- static flatten(arrays) {
706
- return [].concat.apply([], arrays);
645
+ static flatten(arrays, deep) {
646
+ return arrays.flatMap(v => deep && Array.isArray(v) ? this.flatten(v, true) : v);
707
647
  }
708
648
  static isOperator(key, includeGroupOperators = true) {
709
649
  if (!includeGroupOperators) {
@@ -723,15 +663,13 @@ 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
  }
734
- static createFunction(context, code) {
669
+ static createFunction(context, code, compiledFunctions, key) {
670
+ if (key && compiledFunctions?.[key]) {
671
+ return compiledFunctions[key](...context.values());
672
+ }
735
673
  try {
736
674
  return new Function(...context.keys(), `'use strict';\n` + code)(...context.values());
737
675
  /* v8 ignore next */
@@ -889,4 +827,12 @@ export class Utils {
889
827
  return o;
890
828
  }, {});
891
829
  }
830
+ static getObjectQueryKeys(obj) {
831
+ return Reflect.ownKeys(obj).filter(key => {
832
+ if (!Object.prototype.propertyIsEnumerable.call(obj, key)) {
833
+ return false;
834
+ }
835
+ return typeof key === 'string' || Raw.isKnownFragmentSymbol(key);
836
+ });
837
+ }
892
838
  }
package/utils/clone.js CHANGED
@@ -3,7 +3,6 @@
3
3
  * clone `EventEmitter`s to get around https://github.com/mikro-orm/mikro-orm/issues/2748
4
4
  * @internal
5
5
  */
6
- import { RawQueryFragment } from './RawQueryFragment.js';
7
6
  /**
8
7
  * Get the property descriptor of a property on an object or its prototype chain.
9
8
  *
@@ -29,10 +28,6 @@ export function clone(parent, respectCustomCloneMethod = true) {
29
28
  if (parent === null) {
30
29
  return null;
31
30
  }
32
- const raw = RawQueryFragment.getKnownFragment(parent, false);
33
- if (raw && respectCustomCloneMethod) {
34
- return raw.clone();
35
- }
36
31
  if (typeof parent !== 'object') {
37
32
  return parent;
38
33
  }
@@ -113,25 +108,16 @@ export function clone(parent, respectCustomCloneMethod = true) {
113
108
  if (attrs && typeof attrs.get === 'function' && attrs.set == null) {
114
109
  continue;
115
110
  }
116
- const raw = RawQueryFragment.getKnownFragment(i, false);
117
- if (raw && respectCustomCloneMethod) {
118
- const i2 = raw.clone().toString();
119
- child[i2] = _clone(parent[i]);
120
- continue;
121
- }
122
111
  child[i] = _clone(parent[i]);
123
112
  }
124
- if (Object.getOwnPropertySymbols) {
125
- const symbols = Object.getOwnPropertySymbols(parent);
126
- for (let i = 0; i < symbols.length; i++) {
127
- const symbol = symbols[i];
128
- const descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
129
- /* v8 ignore next */
130
- if (descriptor && !descriptor.enumerable) {
131
- continue;
132
- }
133
- child[symbol] = _clone(parent[symbol]);
113
+ const symbols = Object.getOwnPropertySymbols(parent);
114
+ for (let i = 0; i < symbols.length; i++) {
115
+ const symbol = symbols[i];
116
+ const descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
117
+ if (descriptor && !descriptor.enumerable) {
118
+ continue;
134
119
  }
120
+ child[symbol] = _clone(parent[symbol]);
135
121
  }
136
122
  return child;
137
123
  }
@@ -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
- if (envKey in process.env) {
17
- o[key] = mapper(process.env[envKey]);
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];
@@ -49,7 +60,6 @@ export function loadEnvironmentVars() {
49
60
  read1('warnWhenNoEntities', bool);
50
61
  read1('checkDuplicateTableNames', bool);
51
62
  read1('checkDuplicateFieldNames', bool);
52
- read1('checkDuplicateEntities', bool);
53
63
  read1('checkNonPersistentCompositeProps', bool);
54
64
  read1('inferDefaultValues', bool);
55
65
  read1('tsConfigPath');
@@ -1,12 +1,33 @@
1
1
  import { type Dictionary } from '../typings.js';
2
2
  export declare const fs: {
3
+ init(): Promise<void>;
3
4
  pathExists(path: string): boolean;
4
5
  ensureDir(path: string): void;
5
6
  readJSONSync<T = Dictionary>(path: string): T;
6
7
  glob(input: string | string[], cwd?: string): string[];
8
+ resolveGlob(input: string | string[], cwd?: string): string[];
7
9
  getPackageConfig<T extends Dictionary>(basePath?: string): T;
8
10
  getORMPackages(): Set<string>;
9
11
  getORMPackageVersion(name: string): string | undefined;
10
12
  checkPackageVersion(): void;
13
+ /**
14
+ * Resolves and normalizes a series of path parts relative to each preceding part.
15
+ * If any part is a `file:` URL, it is converted to a local path. If any part is an
16
+ * absolute path, it replaces preceding paths (similar to `path.resolve` in NodeJS).
17
+ * Trailing directory separators are removed, and all directory separators are converted
18
+ * to POSIX-style separators (`/`).
19
+ */
20
+ normalizePath(...parts: string[]): string;
21
+ /**
22
+ * Determines the relative path between two paths. If either path is a `file:` URL,
23
+ * it is converted to a local path.
24
+ */
25
+ relativePath(path: string, relativeTo: string): string;
26
+ /**
27
+ * Computes the absolute path to for the given path relative to the provided base directory.
28
+ * If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
29
+ */
30
+ absolutePath(path: string, baseDir?: string): string;
31
+ dynamicImport<T = any>(id: string): Promise<T>;
11
32
  };
12
33
  export * from '../cache/FileCacheAdapter.js';