@mikro-orm/core 6.3.11-dev.0 → 6.3.11-dev.10
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/entity/EntityLoader.js +11 -7
- package/hydration/ObjectHydrator.js +13 -3
- package/logging/Logger.d.ts +4 -4
- package/package.json +2 -2
- package/platforms/Platform.d.ts +1 -0
- package/platforms/Platform.js +4 -0
- package/serialization/EntityTransformer.js +0 -3
- package/utils/EntityComparator.d.ts +1 -0
- package/utils/EntityComparator.js +17 -9
- package/utils/Utils.js +8 -6
package/entity/EntityLoader.js
CHANGED
|
@@ -26,11 +26,12 @@ class EntityLoader {
|
|
|
26
26
|
if (entities.length === 0 || Utils_1.Utils.isEmpty(populate)) {
|
|
27
27
|
return this.setSerializationContext(entities, populate, options);
|
|
28
28
|
}
|
|
29
|
+
const meta = this.metadata.find(entityName);
|
|
29
30
|
if (entities.some(e => !e.__helper)) {
|
|
30
31
|
const entity = entities.find(e => !Utils_1.Utils.isEntity(e));
|
|
31
|
-
const meta = this.metadata.find(entityName);
|
|
32
32
|
throw errors_1.ValidationError.notDiscoveredEntity(entity, meta, 'populate');
|
|
33
33
|
}
|
|
34
|
+
const references = entities.filter(e => !(0, wrap_1.helper)(e).isInitialized());
|
|
34
35
|
const visited = options.visited ??= new Set();
|
|
35
36
|
options.where ??= {};
|
|
36
37
|
options.orderBy ??= {};
|
|
@@ -39,6 +40,9 @@ class EntityLoader {
|
|
|
39
40
|
options.validate ??= true;
|
|
40
41
|
options.refresh ??= false;
|
|
41
42
|
options.convertCustomTypes ??= true;
|
|
43
|
+
if (references.length > 0) {
|
|
44
|
+
await this.populateScalar(meta, references, options);
|
|
45
|
+
}
|
|
42
46
|
populate = this.normalizePopulate(entityName, populate, options.strategy, options.lookup);
|
|
43
47
|
const invalid = populate.find(({ field }) => !this.em.canPopulate(entityName, field));
|
|
44
48
|
/* istanbul ignore next */
|
|
@@ -121,7 +125,7 @@ class EntityLoader {
|
|
|
121
125
|
if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner && !this.driver.getPlatform().usesPivotTable()) {
|
|
122
126
|
const filtered = entities.filter(e => !e[prop.name]?.isInitialized());
|
|
123
127
|
if (filtered.length > 0) {
|
|
124
|
-
await this.populateScalar(meta, filtered, options, prop);
|
|
128
|
+
await this.populateScalar(meta, filtered, { ...options, fields: [prop.name] });
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
131
|
if (prop.kind === enums_1.ReferenceKind.SCALAR && prop.lazy) {
|
|
@@ -129,7 +133,7 @@ class EntityLoader {
|
|
|
129
133
|
if (options.ignoreLazyScalarProperties || filtered.length === 0) {
|
|
130
134
|
return entities;
|
|
131
135
|
}
|
|
132
|
-
await this.populateScalar(meta, filtered, options, prop);
|
|
136
|
+
await this.populateScalar(meta, filtered, { ...options, fields: [prop.name] });
|
|
133
137
|
return entities;
|
|
134
138
|
}
|
|
135
139
|
if (prop.kind === enums_1.ReferenceKind.EMBEDDED) {
|
|
@@ -147,14 +151,14 @@ class EntityLoader {
|
|
|
147
151
|
this.initializeCollections(filtered, prop, field, data, innerOrderBy.length > 0);
|
|
148
152
|
return data;
|
|
149
153
|
}
|
|
150
|
-
async populateScalar(meta, filtered, options
|
|
154
|
+
async populateScalar(meta, filtered, options) {
|
|
151
155
|
const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
|
|
152
156
|
const ids = Utils_1.Utils.unique(filtered.map(e => Utils_1.Utils.getPrimaryKeyValues(e, meta.primaryKeys, true)));
|
|
153
157
|
const where = this.mergePrimaryCondition(ids, pk, options, meta, this.metadata, this.driver.getPlatform());
|
|
154
|
-
const { filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging } = options;
|
|
158
|
+
const { filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging, fields } = options;
|
|
155
159
|
await this.em.find(meta.className, where, {
|
|
156
160
|
filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging,
|
|
157
|
-
fields:
|
|
161
|
+
fields: fields,
|
|
158
162
|
populate: [],
|
|
159
163
|
});
|
|
160
164
|
}
|
|
@@ -466,7 +470,7 @@ class EntityLoader {
|
|
|
466
470
|
return entities.filter(e => Utils_1.Utils.isCollection(e[field]) && !e[field].isInitialized(!ref));
|
|
467
471
|
}
|
|
468
472
|
isPropertyLoaded(entity, field) {
|
|
469
|
-
if (!entity) {
|
|
473
|
+
if (!entity || field === '*') {
|
|
470
474
|
return true;
|
|
471
475
|
}
|
|
472
476
|
const wrapped = (0, wrap_1.helper)(entity);
|
|
@@ -6,6 +6,7 @@ const Collection_1 = require("../entity/Collection");
|
|
|
6
6
|
const Reference_1 = require("../entity/Reference");
|
|
7
7
|
const Utils_1 = require("../utils/Utils");
|
|
8
8
|
const enums_1 = require("../enums");
|
|
9
|
+
const RawQueryFragment_1 = require("../utils/RawQueryFragment");
|
|
9
10
|
class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
10
11
|
hydrators = {
|
|
11
12
|
full: new Map(),
|
|
@@ -48,6 +49,15 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
48
49
|
context.set('isPrimaryKey', Utils_1.Utils.isPrimaryKey);
|
|
49
50
|
context.set('Collection', Collection_1.Collection);
|
|
50
51
|
context.set('Reference', Reference_1.Reference);
|
|
52
|
+
const registerCustomType = (prop, convertorKey, method, context) => {
|
|
53
|
+
context.set(`${method}_${convertorKey}`, (val) => {
|
|
54
|
+
if (RawQueryFragment_1.RawQueryFragment.isKnownFragment(val)) {
|
|
55
|
+
return val;
|
|
56
|
+
}
|
|
57
|
+
return prop.customType[method](val, this.platform, { mode: 'serialization' });
|
|
58
|
+
});
|
|
59
|
+
return convertorKey;
|
|
60
|
+
};
|
|
51
61
|
const hydrateScalar = (prop, object, path, dataKey) => {
|
|
52
62
|
const entityKey = path.map(k => this.wrap(k)).join('');
|
|
53
63
|
const tz = this.platform.getTimezone();
|
|
@@ -66,8 +76,8 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
66
76
|
ret.push(` entity${entityKey} = ${nullVal};`);
|
|
67
77
|
ret.push(` } else if (typeof data${dataKey} !== 'undefined') {`);
|
|
68
78
|
if (prop.customType) {
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
registerCustomType(prop, convertorKey, 'convertToJSValue', context);
|
|
80
|
+
registerCustomType(prop, convertorKey, 'convertToDatabaseValue', context);
|
|
71
81
|
ret.push(` if (convertCustomTypes) {`, ` const value = convertToJSValue_${convertorKey}(data${dataKey});`);
|
|
72
82
|
if (prop.customType.ensureComparable(meta, prop)) {
|
|
73
83
|
ret.push(` data${dataKey} = convertToDatabaseValue_${convertorKey}(value);`);
|
|
@@ -142,7 +152,7 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
142
152
|
}
|
|
143
153
|
}
|
|
144
154
|
if (prop.customType?.ensureComparable(meta, prop)) {
|
|
145
|
-
|
|
155
|
+
registerCustomType(prop, this.safeKey(prop.name), 'convertToDatabaseValue', context);
|
|
146
156
|
ret.push(` if (data${dataKey} != null && typeof data${dataKey} !== 'object' && convertCustomTypes) {`);
|
|
147
157
|
ret.push(` data${dataKey} = convertToDatabaseValue_${this.safeKey(prop.name)}(entity${entityKey}.__helper.getPrimaryKey());`);
|
|
148
158
|
ret.push(` }`);
|
package/logging/Logger.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import type { Dictionary, Highlighter } from '../typings';
|
|
1
|
+
import type { AnyString, Dictionary, Highlighter } from '../typings';
|
|
2
2
|
export interface Logger {
|
|
3
3
|
/**
|
|
4
4
|
* Logs a message inside given namespace.
|
|
5
5
|
*/
|
|
6
|
-
log(namespace: LoggerNamespace, message: string, context?: LogContext): void;
|
|
6
|
+
log(namespace: LoggerNamespace | AnyString, message: string, context?: LogContext): void;
|
|
7
7
|
/**
|
|
8
8
|
* Logs error message inside given namespace.
|
|
9
9
|
*/
|
|
10
|
-
error(namespace: LoggerNamespace, message: string, context?: LogContext): void;
|
|
10
|
+
error(namespace: LoggerNamespace | AnyString, message: string, context?: LogContext): void;
|
|
11
11
|
/**
|
|
12
12
|
* Logs warning message inside given namespace.
|
|
13
13
|
*/
|
|
14
|
-
warn(namespace: LoggerNamespace, message: string, context?: LogContext): void;
|
|
14
|
+
warn(namespace: LoggerNamespace | AnyString, message: string, context?: LogContext): void;
|
|
15
15
|
/**
|
|
16
16
|
* Logs a message inside given namespace.
|
|
17
17
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "6.3.11-dev.
|
|
3
|
+
"version": "6.3.11-dev.10",
|
|
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
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"esprima": "4.0.1",
|
|
65
65
|
"fs-extra": "11.2.0",
|
|
66
66
|
"globby": "11.1.0",
|
|
67
|
-
"mikro-orm": "6.3.11-dev.
|
|
67
|
+
"mikro-orm": "6.3.11-dev.10",
|
|
68
68
|
"reflect-metadata": "0.2.2"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -175,6 +175,7 @@ export declare abstract class Platform {
|
|
|
175
175
|
processDateProperty(value: unknown): string | number | Date;
|
|
176
176
|
quoteIdentifier(id: string, quote?: string): string;
|
|
177
177
|
quoteValue(value: any): string;
|
|
178
|
+
escape(value: any): string;
|
|
178
179
|
formatQuery(sql: string, params: readonly any[]): string;
|
|
179
180
|
cloneEmbeddable<T>(data: T): T;
|
|
180
181
|
setConfig(config: Configuration): void;
|
package/platforms/Platform.js
CHANGED
|
@@ -5,6 +5,7 @@ const clone_1 = require("./clone");
|
|
|
5
5
|
const enums_1 = require("../enums");
|
|
6
6
|
const Utils_1 = require("./Utils");
|
|
7
7
|
const JsonType_1 = require("../types/JsonType");
|
|
8
|
+
const RawQueryFragment_1 = require("./RawQueryFragment");
|
|
8
9
|
class EntityComparator {
|
|
9
10
|
metadata;
|
|
10
11
|
platform;
|
|
@@ -102,8 +103,7 @@ class EntityComparator {
|
|
|
102
103
|
}
|
|
103
104
|
else {
|
|
104
105
|
if (meta.properties[pk].customType) {
|
|
105
|
-
const convertorKey = this.
|
|
106
|
-
context.set(`convertToDatabaseValue_${convertorKey}`, (val) => meta.properties[pk].customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' }));
|
|
106
|
+
const convertorKey = this.registerCustomType(meta.properties[pk], context);
|
|
107
107
|
lines.push(` ${pk}: convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)}),`);
|
|
108
108
|
}
|
|
109
109
|
else {
|
|
@@ -121,8 +121,7 @@ class EntityComparator {
|
|
|
121
121
|
lines.push(` if (entity${this.wrap(pk)} != null && (entity${this.wrap(pk)}.__entity || entity${this.wrap(pk)}.__reference)) return entity${this.wrap(pk)}.__helper.getPrimaryKey(true);`);
|
|
122
122
|
}
|
|
123
123
|
if (meta.properties[pk].customType) {
|
|
124
|
-
const convertorKey = this.
|
|
125
|
-
context.set(`convertToDatabaseValue_${convertorKey}`, (val) => meta.properties[pk].customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' }));
|
|
124
|
+
const convertorKey = this.registerCustomType(meta.properties[pk], context);
|
|
126
125
|
lines.push(` return convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)});`);
|
|
127
126
|
}
|
|
128
127
|
else {
|
|
@@ -414,8 +413,7 @@ class EntityComparator {
|
|
|
414
413
|
.split('\n').map(l => padding + l).join('\n');
|
|
415
414
|
}
|
|
416
415
|
if (shouldProcessCustomType(childProp)) {
|
|
417
|
-
const convertorKey = this.
|
|
418
|
-
context.set(`convertToDatabaseValue_${convertorKey}`, (val) => childProp.customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' }));
|
|
416
|
+
const convertorKey = this.registerCustomType(childProp, context);
|
|
419
417
|
if (['number', 'string', 'boolean', 'bigint'].includes(childProp.customType.compareAsType().toLowerCase())) {
|
|
420
418
|
return `${padding} if (${childCond}) ret${childDataKey} = convertToDatabaseValue_${convertorKey}(entity${childEntityKey});`;
|
|
421
419
|
}
|
|
@@ -428,8 +426,18 @@ class EntityComparator {
|
|
|
428
426
|
}
|
|
429
427
|
return `${ret}${padding}}`;
|
|
430
428
|
}
|
|
431
|
-
|
|
429
|
+
registerCustomType(prop, context) {
|
|
432
430
|
const convertorKey = this.safeKey(prop.name);
|
|
431
|
+
context.set(`convertToDatabaseValue_${convertorKey}`, (val) => {
|
|
432
|
+
/* istanbul ignore if */
|
|
433
|
+
if (RawQueryFragment_1.RawQueryFragment.isKnownFragment(val)) {
|
|
434
|
+
return val;
|
|
435
|
+
}
|
|
436
|
+
return prop.customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' });
|
|
437
|
+
});
|
|
438
|
+
return convertorKey;
|
|
439
|
+
}
|
|
440
|
+
getPropertySnapshot(meta, prop, context, dataKey, entityKey, path, level = 1, object) {
|
|
433
441
|
const unwrap = prop.ref ? '?.unwrap()' : '';
|
|
434
442
|
let ret = ` if (${this.getPropertyCondition(path)}) {\n`;
|
|
435
443
|
if (['number', 'string', 'boolean'].includes(prop.type.toLowerCase())) {
|
|
@@ -444,7 +452,7 @@ class EntityComparator {
|
|
|
444
452
|
if (prop.kind === enums_1.ReferenceKind.ONE_TO_ONE || prop.kind === enums_1.ReferenceKind.MANY_TO_ONE) {
|
|
445
453
|
if (prop.mapToPk) {
|
|
446
454
|
if (prop.customType) {
|
|
447
|
-
|
|
455
|
+
const convertorKey = this.registerCustomType(prop, context);
|
|
448
456
|
ret += ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(entity${entityKey});\n`;
|
|
449
457
|
}
|
|
450
458
|
else {
|
|
@@ -468,7 +476,7 @@ class EntityComparator {
|
|
|
468
476
|
return ret + ' }\n';
|
|
469
477
|
}
|
|
470
478
|
if (prop.customType) {
|
|
471
|
-
|
|
479
|
+
const convertorKey = this.registerCustomType(prop, context);
|
|
472
480
|
if (['number', 'string', 'boolean', 'bigint'].includes(prop.customType.compareAsType().toLowerCase())) {
|
|
473
481
|
return ret + ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(entity${entityKey}${unwrap});\n }\n`;
|
|
474
482
|
}
|
package/utils/Utils.js
CHANGED
|
@@ -49,10 +49,12 @@ function compareObjects(a, b) {
|
|
|
49
49
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
50
50
|
return a.sql === b.sql && compareArrays(a.params, b.params);
|
|
51
51
|
}
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
if ((typeof a === 'function' && typeof b === 'function') ||
|
|
53
|
+
(typeof a === 'object' && a.client && ['Ref', 'Raw'].includes(a.constructor.name) && typeof b === 'object' && b.client && ['Ref', 'Raw'].includes(b.constructor.name)) || // knex qb
|
|
54
|
+
(a instanceof Date && b instanceof Date) ||
|
|
55
|
+
(a instanceof RegExp && b instanceof RegExp) ||
|
|
56
|
+
(a instanceof String && b instanceof String) ||
|
|
57
|
+
(a instanceof Number && b instanceof Number)) {
|
|
56
58
|
return a.toString() === b.toString();
|
|
57
59
|
}
|
|
58
60
|
const keys = Object.keys(a);
|
|
@@ -881,8 +883,8 @@ class Utils {
|
|
|
881
883
|
catch {
|
|
882
884
|
// ignore
|
|
883
885
|
}
|
|
884
|
-
//
|
|
885
|
-
if (
|
|
886
|
+
// If the extension is not registered, we need to fall back to a file path.
|
|
887
|
+
if (require.extensions && !require.extensions[(0, node_path_1.extname)(id)]) {
|
|
886
888
|
id = (0, node_url_1.fileURLToPath)(id);
|
|
887
889
|
}
|
|
888
890
|
}
|