@mikro-orm/core 7.0.0-dev.312 → 7.0.0-dev.313
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/README.md +2 -1
- package/entity/EntityLoader.js +3 -5
- package/exceptions.js +8 -6
- package/metadata/MetadataDiscovery.js +1 -0
- package/package.json +1 -1
- package/platforms/Platform.d.ts +23 -1
- package/platforms/Platform.js +55 -2
- package/types/UuidType.d.ts +2 -0
- package/types/UuidType.js +14 -2
- package/unit-of-work/ChangeSetPersister.js +1 -1
- package/utils/Configuration.d.ts +1 -0
- package/utils/QueryHelper.d.ts +0 -1
- package/utils/QueryHelper.js +2 -24
- package/utils/Utils.js +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
|
|
3
3
|
</h1>
|
|
4
4
|
|
|
5
|
-
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL
|
|
5
|
+
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
|
|
6
6
|
|
|
7
7
|
> Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
|
|
8
8
|
|
|
@@ -181,6 +181,7 @@ yarn add @mikro-orm/core @mikro-orm/mysql # for mysql/mariadb
|
|
|
181
181
|
yarn add @mikro-orm/core @mikro-orm/mariadb # for mysql/mariadb
|
|
182
182
|
yarn add @mikro-orm/core @mikro-orm/postgresql # for postgresql
|
|
183
183
|
yarn add @mikro-orm/core @mikro-orm/mssql # for mssql
|
|
184
|
+
yarn add @mikro-orm/core @mikro-orm/oracledb # for oracle
|
|
184
185
|
yarn add @mikro-orm/core @mikro-orm/sqlite # for sqlite
|
|
185
186
|
yarn add @mikro-orm/core @mikro-orm/libsql # for libsql
|
|
186
187
|
```
|
package/entity/EntityLoader.js
CHANGED
|
@@ -522,16 +522,14 @@ export class EntityLoader {
|
|
|
522
522
|
const options2 = { ...options, fields, exclude, populateFilter };
|
|
523
523
|
['limit', 'offset', 'first', 'last', 'before', 'after', 'overfetch'].forEach(prop => delete options2[prop]);
|
|
524
524
|
options2.populate = populate?.children ?? [];
|
|
525
|
-
if (prop.customType) {
|
|
526
|
-
ids.forEach((id, idx) => (ids[idx] = QueryHelper.processCustomType(prop, id, this.driver.getPlatform())));
|
|
527
|
-
}
|
|
528
525
|
if (!Utils.isEmpty(prop.where)) {
|
|
529
526
|
where = { $and: [where, prop.where] };
|
|
530
527
|
}
|
|
531
528
|
const map = await this.driver.loadFromPivotTable(prop, ids, where, orderBy, this.em.getTransactionContext(), options2, pivotJoin);
|
|
532
529
|
const children = [];
|
|
533
|
-
for (
|
|
534
|
-
const
|
|
530
|
+
for (let i = 0; i < filtered.length; i++) {
|
|
531
|
+
const entity = filtered[i];
|
|
532
|
+
const items = map[Utils.getPrimaryKeyHash(ids[i])].map(item => {
|
|
535
533
|
if (pivotJoin) {
|
|
536
534
|
return this.em.getReference(prop.targetMeta.class, item, {
|
|
537
535
|
convertCustomTypes: true,
|
package/exceptions.js
CHANGED
|
@@ -12,12 +12,14 @@ export class DriverException extends Error {
|
|
|
12
12
|
Object.getOwnPropertyNames(previous).forEach(k => (this[k] = previous[k]));
|
|
13
13
|
this.name = this.constructor.name;
|
|
14
14
|
Error.captureStackTrace(this, this.constructor);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.stack
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
if (previous.stack) {
|
|
16
|
+
this.stack +=
|
|
17
|
+
'\n\n' +
|
|
18
|
+
previous.stack
|
|
19
|
+
.split('\n')
|
|
20
|
+
.filter(l => l.trim().startsWith('at '))
|
|
21
|
+
.join('\n');
|
|
22
|
+
}
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.313",
|
|
4
4
|
"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.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"data-mapper",
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EntityRepository } from '../entity/EntityRepository.js';
|
|
2
2
|
import { type NamingStrategy } from '../naming-strategy/NamingStrategy.js';
|
|
3
|
-
import type { Constructor, EntityMetadata, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary, SimpleColumnMeta } from '../typings.js';
|
|
3
|
+
import type { Constructor, EntityMetadata, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary, SimpleColumnMeta, FilterQuery, EntityValue, EntityKey } from '../typings.js';
|
|
4
4
|
import { ExceptionConverter } from './ExceptionConverter.js';
|
|
5
5
|
import type { EntityManager } from '../EntityManager.js';
|
|
6
6
|
import type { Configuration } from '../utils/Configuration.js';
|
|
@@ -61,6 +61,13 @@ export declare abstract class Platform {
|
|
|
61
61
|
getDateTypeDeclarationSQL(length?: number): string;
|
|
62
62
|
getTimeTypeDeclarationSQL(length?: number): string;
|
|
63
63
|
getRegExpOperator(val?: unknown, flags?: string): string;
|
|
64
|
+
mapRegExpCondition(mappedKey: string, value: {
|
|
65
|
+
$re: string;
|
|
66
|
+
$flags?: string;
|
|
67
|
+
}): {
|
|
68
|
+
sql: string;
|
|
69
|
+
params: unknown[];
|
|
70
|
+
};
|
|
64
71
|
getRegExpValue(val: RegExp): {
|
|
65
72
|
$re: string;
|
|
66
73
|
$flags?: string;
|
|
@@ -139,6 +146,11 @@ export declare abstract class Platform {
|
|
|
139
146
|
getMappedType(type: string): Type<unknown>;
|
|
140
147
|
getDefaultMappedType(type: string): Type<unknown>;
|
|
141
148
|
supportsMultipleCascadePaths(): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Returns true if the platform supports ON UPDATE foreign key rules.
|
|
151
|
+
* Oracle doesn't support ON UPDATE rules.
|
|
152
|
+
*/
|
|
153
|
+
supportsOnUpdate(): boolean;
|
|
142
154
|
supportsMultipleStatements(): boolean;
|
|
143
155
|
supportsUnionWhere(): boolean;
|
|
144
156
|
getArrayDeclarationSQL(): string;
|
|
@@ -148,6 +160,8 @@ export declare abstract class Platform {
|
|
|
148
160
|
getJsonDeclarationSQL(): string;
|
|
149
161
|
getSearchJsonPropertySQL(path: string, type: string, aliased: boolean): string | Raw;
|
|
150
162
|
getSearchJsonPropertyKey(path: string[], type: string, aliased: boolean, value?: unknown): string | Raw;
|
|
163
|
+
processJsonCondition<T extends object>(o: FilterQuery<T>, value: EntityValue<T>, path: EntityKey<T>[], alias: boolean): FilterQuery<T>;
|
|
164
|
+
protected getJsonValueType(value: unknown): string;
|
|
151
165
|
getJsonIndexDefinition(index: {
|
|
152
166
|
columnNames: string[];
|
|
153
167
|
}): string[];
|
|
@@ -160,6 +174,14 @@ export declare abstract class Platform {
|
|
|
160
174
|
convertDateToJSValue(value: string | Date): string;
|
|
161
175
|
convertIntervalToJSValue(value: string): unknown;
|
|
162
176
|
convertIntervalToDatabaseValue(value: unknown): unknown;
|
|
177
|
+
usesAsKeyword(): boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Determines how UUID values are compared in the change set tracking.
|
|
180
|
+
* Return `'string'` for inline string comparison (fast), or `'any'` for deep comparison via type methods.
|
|
181
|
+
*/
|
|
182
|
+
compareUuids(): string;
|
|
183
|
+
convertUuidToJSValue(value: unknown): unknown;
|
|
184
|
+
convertUuidToDatabaseValue(value: unknown): unknown;
|
|
163
185
|
parseDate(value: string | number): Date;
|
|
164
186
|
getRepositoryClass<T extends object>(): Constructor<EntityRepository<T>>;
|
|
165
187
|
getDefaultCharset(): string;
|
package/platforms/Platform.js
CHANGED
|
@@ -3,7 +3,7 @@ import { EntityRepository } from '../entity/EntityRepository.js';
|
|
|
3
3
|
import { UnderscoreNamingStrategy } from '../naming-strategy/UnderscoreNamingStrategy.js';
|
|
4
4
|
import { ExceptionConverter } from './ExceptionConverter.js';
|
|
5
5
|
import { ArrayType, BigIntType, BlobType, BooleanType, CharacterType, DateTimeType, DateType, DecimalType, DoubleType, EnumType, FloatType, IntegerType, IntervalType, JsonType, MediumIntType, SmallIntType, StringType, TextType, TimeType, TinyIntType, Type, Uint8ArrayType, UnknownType, UuidType, } from '../types/index.js';
|
|
6
|
-
import { parseJsonSafe } from '../utils/Utils.js';
|
|
6
|
+
import { parseJsonSafe, Utils } from '../utils/Utils.js';
|
|
7
7
|
import { ReferenceKind } from '../enums.js';
|
|
8
8
|
import { Raw } from '../utils/RawQueryFragment.js';
|
|
9
9
|
export const JsonProperty = Symbol('JsonProperty');
|
|
@@ -104,6 +104,11 @@ export class Platform {
|
|
|
104
104
|
getRegExpOperator(val, flags) {
|
|
105
105
|
return 'regexp';
|
|
106
106
|
}
|
|
107
|
+
mapRegExpCondition(mappedKey, value) {
|
|
108
|
+
const operator = this.getRegExpOperator(value.$re, value.$flags);
|
|
109
|
+
const quotedKey = this.quoteIdentifier(mappedKey);
|
|
110
|
+
return { sql: `${quotedKey} ${operator} ?`, params: [value.$re] };
|
|
111
|
+
}
|
|
107
112
|
getRegExpValue(val) {
|
|
108
113
|
if (val.flags.includes('i')) {
|
|
109
114
|
return { $re: `(?i)${val.source}` };
|
|
@@ -156,7 +161,7 @@ export class Platform {
|
|
|
156
161
|
return 'interval' + (column.length ? `(${column.length})` : '');
|
|
157
162
|
}
|
|
158
163
|
getTextTypeDeclarationSQL(_column) {
|
|
159
|
-
return
|
|
164
|
+
return 'text';
|
|
160
165
|
}
|
|
161
166
|
getEnumTypeDeclarationSQL(column) {
|
|
162
167
|
if (column.items?.every(item => typeof item === 'string')) {
|
|
@@ -255,6 +260,13 @@ export class Platform {
|
|
|
255
260
|
supportsMultipleCascadePaths() {
|
|
256
261
|
return true;
|
|
257
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Returns true if the platform supports ON UPDATE foreign key rules.
|
|
265
|
+
* Oracle doesn't support ON UPDATE rules.
|
|
266
|
+
*/
|
|
267
|
+
supportsOnUpdate() {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
258
270
|
supportsMultipleStatements() {
|
|
259
271
|
return this.config.get('multipleStatements');
|
|
260
272
|
}
|
|
@@ -285,6 +297,31 @@ export class Platform {
|
|
|
285
297
|
getSearchJsonPropertyKey(path, type, aliased, value) {
|
|
286
298
|
return path.join('.');
|
|
287
299
|
}
|
|
300
|
+
processJsonCondition(o, value, path, alias) {
|
|
301
|
+
if (Utils.isPlainObject(value) && !Object.keys(value).some(k => Utils.isOperator(k))) {
|
|
302
|
+
Utils.keys(value).forEach(k => {
|
|
303
|
+
this.processJsonCondition(o, value[k], [...path, k], alias);
|
|
304
|
+
});
|
|
305
|
+
return o;
|
|
306
|
+
}
|
|
307
|
+
if (path.length === 1) {
|
|
308
|
+
o[path[0]] = value;
|
|
309
|
+
return o;
|
|
310
|
+
}
|
|
311
|
+
const type = this.getJsonValueType(value);
|
|
312
|
+
const k = this.getSearchJsonPropertyKey(path, type, alias, value);
|
|
313
|
+
o[k] = value;
|
|
314
|
+
return o;
|
|
315
|
+
}
|
|
316
|
+
getJsonValueType(value) {
|
|
317
|
+
if (Array.isArray(value)) {
|
|
318
|
+
return typeof value[0];
|
|
319
|
+
}
|
|
320
|
+
if (Utils.isPlainObject(value) && Object.keys(value).every(k => Utils.isOperator(k))) {
|
|
321
|
+
return this.getJsonValueType(Object.values(value)[0]);
|
|
322
|
+
}
|
|
323
|
+
return typeof value;
|
|
324
|
+
}
|
|
288
325
|
/* v8 ignore next */
|
|
289
326
|
getJsonIndexDefinition(index) {
|
|
290
327
|
return index.columnNames;
|
|
@@ -316,6 +353,22 @@ export class Platform {
|
|
|
316
353
|
convertIntervalToDatabaseValue(value) {
|
|
317
354
|
return value;
|
|
318
355
|
}
|
|
356
|
+
usesAsKeyword() {
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Determines how UUID values are compared in the change set tracking.
|
|
361
|
+
* Return `'string'` for inline string comparison (fast), or `'any'` for deep comparison via type methods.
|
|
362
|
+
*/
|
|
363
|
+
compareUuids() {
|
|
364
|
+
return 'string';
|
|
365
|
+
}
|
|
366
|
+
convertUuidToJSValue(value) {
|
|
367
|
+
return value;
|
|
368
|
+
}
|
|
369
|
+
convertUuidToDatabaseValue(value) {
|
|
370
|
+
return value;
|
|
371
|
+
}
|
|
319
372
|
parseDate(value) {
|
|
320
373
|
const date = new Date(value);
|
|
321
374
|
/* v8 ignore next */
|
package/types/UuidType.d.ts
CHANGED
|
@@ -4,5 +4,7 @@ import type { EntityProperty } from '../typings.js';
|
|
|
4
4
|
export declare class UuidType extends Type<string | null | undefined> {
|
|
5
5
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
6
6
|
compareAsType(): string;
|
|
7
|
+
convertToDatabaseValue(value: string | null | undefined, platform: Platform): string | null;
|
|
8
|
+
convertToJSValue(value: string | null | undefined, platform: Platform): string | null | undefined;
|
|
7
9
|
ensureComparable(): boolean;
|
|
8
10
|
}
|
package/types/UuidType.js
CHANGED
|
@@ -4,9 +4,21 @@ export class UuidType extends Type {
|
|
|
4
4
|
return platform.getUuidTypeDeclarationSQL(prop);
|
|
5
5
|
}
|
|
6
6
|
compareAsType() {
|
|
7
|
-
return 'string';
|
|
7
|
+
return this.platform?.compareUuids() ?? 'string';
|
|
8
|
+
}
|
|
9
|
+
convertToDatabaseValue(value, platform) {
|
|
10
|
+
if (value == null) {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
return platform.convertUuidToDatabaseValue(value);
|
|
14
|
+
}
|
|
15
|
+
convertToJSValue(value, platform) {
|
|
16
|
+
if (value == null) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
return platform.convertUuidToJSValue(value);
|
|
8
20
|
}
|
|
9
21
|
ensureComparable() {
|
|
10
|
-
return
|
|
22
|
+
return this.platform?.compareUuids() !== 'string';
|
|
11
23
|
}
|
|
12
24
|
}
|
|
@@ -123,7 +123,7 @@ export class ChangeSetPersister {
|
|
|
123
123
|
// Use changeSet's own meta for STI entities to get correct field mappings
|
|
124
124
|
const res = await this.driver.nativeInsertMany(changeSet.meta.class, [changeSet.payload], options);
|
|
125
125
|
if (!wrapped.hasPrimaryKey()) {
|
|
126
|
-
this.mapPrimaryKey(meta, res.insertId, changeSet);
|
|
126
|
+
this.mapPrimaryKey(meta, res.insertId ?? res.row?.[meta.primaryKeys[0]], changeSet);
|
|
127
127
|
}
|
|
128
128
|
this.mapReturnedValues(changeSet.entity, changeSet.payload, res.row, meta);
|
|
129
129
|
this.markAsPopulated(changeSet, meta);
|
package/utils/Configuration.d.ts
CHANGED
|
@@ -891,6 +891,7 @@ export interface Options<Driver extends IDatabaseDriver = IDatabaseDriver, EM ex
|
|
|
891
891
|
* When not set, no rule is emitted and the database uses its native default (NO ACTION/RESTRICT).
|
|
892
892
|
*/
|
|
893
893
|
defaultDeleteRule?: 'cascade' | 'no action' | 'set null' | 'set default' | 'restrict';
|
|
894
|
+
tableSpace?: string;
|
|
894
895
|
};
|
|
895
896
|
/**
|
|
896
897
|
* Embeddable entity configuration options.
|
package/utils/QueryHelper.d.ts
CHANGED
|
@@ -25,7 +25,6 @@ export declare class QueryHelper {
|
|
|
25
25
|
static processCustomType<T extends object>(prop: EntityProperty<T>, cond: FilterQuery<T>, platform: Platform, key?: string, fromQuery?: boolean): FilterQuery<T>;
|
|
26
26
|
private static isSupportedOperator;
|
|
27
27
|
private static processJsonCondition;
|
|
28
|
-
private static getValueType;
|
|
29
28
|
static findProperty<T>(fieldName: string, options: ProcessWhereOptions<T>): EntityProperty<T> | undefined;
|
|
30
29
|
/**
|
|
31
30
|
* Converts entity references for composite FK properties into flat arrays
|
package/utils/QueryHelper.js
CHANGED
|
@@ -186,7 +186,7 @@ export class QueryHelper {
|
|
|
186
186
|
value = QueryHelper.processCustomType(prop, value, platform, undefined, true);
|
|
187
187
|
}
|
|
188
188
|
// oxfmt-ignore
|
|
189
|
-
const isJsonProperty = prop?.customType instanceof JsonType &&
|
|
189
|
+
const isJsonProperty = prop?.customType instanceof JsonType && !isRaw(value) && (Utils.isPlainObject(value) ? Object.keys(value)[0] !== '$eq' : !Array.isArray(value));
|
|
190
190
|
if (isJsonProperty && prop?.kind !== ReferenceKind.EMBEDDED) {
|
|
191
191
|
return this.processJsonCondition(o, value, [prop.fieldNames[0]], platform, aliased);
|
|
192
192
|
}
|
|
@@ -283,29 +283,7 @@ export class QueryHelper {
|
|
|
283
283
|
return !!QueryHelper.SUPPORTED_OPERATORS.find(op => key === op);
|
|
284
284
|
}
|
|
285
285
|
static processJsonCondition(o, value, path, platform, alias) {
|
|
286
|
-
|
|
287
|
-
Utils.keys(value).forEach(k => {
|
|
288
|
-
this.processJsonCondition(o, value[k], [...path, k], platform, alias);
|
|
289
|
-
});
|
|
290
|
-
return o;
|
|
291
|
-
}
|
|
292
|
-
if (path.length === 1) {
|
|
293
|
-
o[path[0]] = value;
|
|
294
|
-
return o;
|
|
295
|
-
}
|
|
296
|
-
const type = this.getValueType(value);
|
|
297
|
-
const k = platform.getSearchJsonPropertyKey(path, type, alias, value);
|
|
298
|
-
o[k] = value;
|
|
299
|
-
return o;
|
|
300
|
-
}
|
|
301
|
-
static getValueType(value) {
|
|
302
|
-
if (Array.isArray(value)) {
|
|
303
|
-
return typeof value[0];
|
|
304
|
-
}
|
|
305
|
-
if (Utils.isPlainObject(value) && Object.keys(value).every(k => Utils.isOperator(k))) {
|
|
306
|
-
return this.getValueType(Object.values(value)[0]);
|
|
307
|
-
}
|
|
308
|
-
return typeof value;
|
|
286
|
+
return platform.processJsonCondition(o, value, path, alias);
|
|
309
287
|
}
|
|
310
288
|
static findProperty(fieldName, options) {
|
|
311
289
|
const parts = fieldName.split('.');
|
package/utils/Utils.js
CHANGED
|
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
|
|
|
123
123
|
}
|
|
124
124
|
export class Utils {
|
|
125
125
|
static PK_SEPARATOR = '~~~';
|
|
126
|
-
static #ORM_VERSION = '7.0.0-dev.
|
|
126
|
+
static #ORM_VERSION = '7.0.0-dev.313';
|
|
127
127
|
/**
|
|
128
128
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
129
129
|
*/
|