@mikro-orm/core 6.4.4-dev.9 → 6.4.5-dev.0
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/EntityManager.js +19 -1
- package/drivers/IDatabaseDriver.d.ts +1 -0
- package/entity/EntityAssigner.d.ts +4 -0
- package/entity/EntityAssigner.js +4 -2
- package/entity/EntityValidator.js +5 -3
- package/metadata/MetadataDiscovery.js +5 -3
- package/package.json +2 -2
- package/utils/Configuration.d.ts +1 -0
- package/utils/Configuration.js +1 -0
- package/utils/EntityComparator.js +2 -2
package/EntityManager.js
CHANGED
|
@@ -607,6 +607,13 @@ class EntityManager {
|
|
|
607
607
|
* If the entity is already present in current context, there won't be any queries - instead, the entity data will be assigned and an explicit `flush` will be required for those changes to be persisted.
|
|
608
608
|
*/
|
|
609
609
|
async upsert(entityNameOrEntity, data, options = {}) {
|
|
610
|
+
if (options.disableIdentityMap ?? this.config.get('disableIdentityMap')) {
|
|
611
|
+
const em = this.getContext(false);
|
|
612
|
+
const fork = em.fork({ keepTransactionContext: true });
|
|
613
|
+
const ret = await fork.upsert(entityNameOrEntity, data, { ...options, disableIdentityMap: false });
|
|
614
|
+
fork.clear();
|
|
615
|
+
return ret;
|
|
616
|
+
}
|
|
610
617
|
const em = this.getContext(false);
|
|
611
618
|
em.prepareOptions(options);
|
|
612
619
|
let entityName;
|
|
@@ -731,6 +738,13 @@ class EntityManager {
|
|
|
731
738
|
* If the entity is already present in current context, there won't be any queries - instead, the entity data will be assigned and an explicit `flush` will be required for those changes to be persisted.
|
|
732
739
|
*/
|
|
733
740
|
async upsertMany(entityNameOrEntity, data, options = {}) {
|
|
741
|
+
if (options.disableIdentityMap ?? this.config.get('disableIdentityMap')) {
|
|
742
|
+
const em = this.getContext(false);
|
|
743
|
+
const fork = em.fork({ keepTransactionContext: true });
|
|
744
|
+
const ret = await fork.upsertMany(entityNameOrEntity, data, { ...options, disableIdentityMap: false });
|
|
745
|
+
fork.clear();
|
|
746
|
+
return ret;
|
|
747
|
+
}
|
|
734
748
|
const em = this.getContext(false);
|
|
735
749
|
em.prepareOptions(options);
|
|
736
750
|
let entityName;
|
|
@@ -1184,7 +1198,7 @@ class EntityManager {
|
|
|
1184
1198
|
merge: options.managed,
|
|
1185
1199
|
});
|
|
1186
1200
|
options.persist ??= em.config.get('persistOnCreate');
|
|
1187
|
-
if (options.persist) {
|
|
1201
|
+
if (options.persist && !this.getMetadata(entityName).embeddable) {
|
|
1188
1202
|
em.persist(entity);
|
|
1189
1203
|
}
|
|
1190
1204
|
return entity;
|
|
@@ -1558,6 +1572,10 @@ class EntityManager {
|
|
|
1558
1572
|
continue;
|
|
1559
1573
|
}
|
|
1560
1574
|
const prop = meta.properties[key];
|
|
1575
|
+
if (!prop.targetMeta) {
|
|
1576
|
+
ret.push(key);
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1561
1579
|
const inner = pruneToOneRelations(prop.targetMeta, [parts.join('.')]);
|
|
1562
1580
|
if (inner.length > 0) {
|
|
1563
1581
|
ret.push(...inner.map(c => `${key}.${c}`));
|
|
@@ -171,6 +171,7 @@ export interface UpsertOptions<Entity, Fields extends string = never> extends Om
|
|
|
171
171
|
onConflictAction?: 'ignore' | 'merge';
|
|
172
172
|
onConflictMergeFields?: AutoPath<Entity, Fields, `${PopulatePath.ALL}`>[];
|
|
173
173
|
onConflictExcludeFields?: AutoPath<Entity, Fields, `${PopulatePath.ALL}`>[];
|
|
174
|
+
disableIdentityMap?: boolean;
|
|
174
175
|
}
|
|
175
176
|
export interface UpsertManyOptions<Entity, Fields extends string = never> extends UpsertOptions<Entity, Fields> {
|
|
176
177
|
batchSize?: number;
|
|
@@ -40,6 +40,10 @@ export interface AssignOptions<Convert extends boolean> {
|
|
|
40
40
|
* to foreign keys. Defaults to `false`.
|
|
41
41
|
*/
|
|
42
42
|
onlyOwnProperties?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* With `ignoreUndefined` enabled, `undefined` properties passed in the payload are skipped. Defaults to `false`.
|
|
45
|
+
*/
|
|
46
|
+
ignoreUndefined?: boolean;
|
|
43
47
|
/**
|
|
44
48
|
* `assign` excepts runtime values for properties using custom types. To be able to assign raw database values, you
|
|
45
49
|
* can enable the `convertCustomTypes` option. Defaults to `false`.
|
package/entity/EntityAssigner.js
CHANGED
|
@@ -37,10 +37,12 @@ class EntityAssigner {
|
|
|
37
37
|
return entity;
|
|
38
38
|
}
|
|
39
39
|
static assignProperty(entity, propName, props, data, options) {
|
|
40
|
-
|
|
40
|
+
let value = data[propName];
|
|
41
|
+
const onlyProperties = options.onlyProperties && !(propName in props);
|
|
42
|
+
const ignoreUndefined = options.ignoreUndefined === true && value === undefined;
|
|
43
|
+
if (onlyProperties || ignoreUndefined) {
|
|
41
44
|
return;
|
|
42
45
|
}
|
|
43
|
-
let value = data[propName];
|
|
44
46
|
const prop = { ...props[propName], name: propName };
|
|
45
47
|
if (prop && options.onlyOwnProperties) {
|
|
46
48
|
if ([enums_1.ReferenceKind.MANY_TO_MANY, enums_1.ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
|
|
@@ -5,6 +5,7 @@ const enums_1 = require("../enums");
|
|
|
5
5
|
const Utils_1 = require("../utils/Utils");
|
|
6
6
|
const errors_1 = require("../errors");
|
|
7
7
|
const wrap_1 = require("./wrap");
|
|
8
|
+
const RawQueryFragment_1 = require("../utils/RawQueryFragment");
|
|
8
9
|
class EntityValidator {
|
|
9
10
|
strict;
|
|
10
11
|
KNOWN_TYPES = new Set(['string', 'number', 'boolean', 'bigint', 'Uint8Array', 'Date', 'Buffer', 'RegExp']);
|
|
@@ -54,10 +55,11 @@ class EntityValidator {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
validateProperty(prop, givenValue, entity) {
|
|
57
|
-
if (givenValue
|
|
58
|
+
if (givenValue == null || givenValue instanceof RawQueryFragment_1.RawQueryFragment) {
|
|
58
59
|
return givenValue;
|
|
59
60
|
}
|
|
60
61
|
const expectedType = prop.runtimeType;
|
|
62
|
+
const propName = prop.embedded ? prop.name.replace(/~/g, '.') : prop.name;
|
|
61
63
|
let givenType = Utils_1.Utils.getObjectType(givenValue);
|
|
62
64
|
let ret = givenValue;
|
|
63
65
|
if (!this.strict) {
|
|
@@ -66,12 +68,12 @@ class EntityValidator {
|
|
|
66
68
|
}
|
|
67
69
|
if (prop.enum && prop.items) {
|
|
68
70
|
if (!prop.items.some(it => it === givenValue)) {
|
|
69
|
-
throw errors_1.ValidationError.fromWrongPropertyType(entity,
|
|
71
|
+
throw errors_1.ValidationError.fromWrongPropertyType(entity, propName, expectedType, givenType, givenValue);
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
else {
|
|
73
75
|
if (givenType !== expectedType && this.KNOWN_TYPES.has(expectedType)) {
|
|
74
|
-
throw errors_1.ValidationError.fromWrongPropertyType(entity,
|
|
76
|
+
throw errors_1.ValidationError.fromWrongPropertyType(entity, propName, expectedType, givenType, givenValue);
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
return ret;
|
|
@@ -826,10 +826,11 @@ class MetadataDiscovery {
|
|
|
826
826
|
const parentProperty = meta.properties[embeddedProp.embedded?.[0] ?? ''];
|
|
827
827
|
const object = isParentObject(embeddedProp);
|
|
828
828
|
this.initFieldName(embeddedProp, rootProperty !== embeddedProp && object);
|
|
829
|
-
// the prefix of the parent
|
|
829
|
+
// the prefix of the parent cannot be a boolean; it already passed here
|
|
830
830
|
const prefix = this.getPrefix(embeddedProp, parentProperty);
|
|
831
|
+
const glue = object ? '~' : '_';
|
|
831
832
|
for (const prop of Object.values(embeddable.properties)) {
|
|
832
|
-
const name = (embeddedProp.embeddedPath?.join(
|
|
833
|
+
const name = (embeddedProp.embeddedPath?.join(glue) ?? embeddedProp.fieldNames[0] + glue) + prop.name;
|
|
833
834
|
meta.properties[name] = Utils_1.Utils.copy(prop, false);
|
|
834
835
|
meta.properties[name].name = name;
|
|
835
836
|
meta.properties[name].embedded = [embeddedProp.name, prop.name];
|
|
@@ -1245,7 +1246,8 @@ class MetadataDiscovery {
|
|
|
1245
1246
|
if (prop.customType) {
|
|
1246
1247
|
return prop.customType;
|
|
1247
1248
|
}
|
|
1248
|
-
|
|
1249
|
+
/* istanbul ignore next */
|
|
1250
|
+
let t = prop.columnTypes?.[0] ?? prop.type ?? '';
|
|
1249
1251
|
if (prop.nativeEnumName) {
|
|
1250
1252
|
t = 'enum';
|
|
1251
1253
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "6.4.
|
|
3
|
+
"version": "6.4.5-dev.0",
|
|
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.3.0",
|
|
66
66
|
"globby": "11.1.0",
|
|
67
|
-
"mikro-orm": "6.4.
|
|
67
|
+
"mikro-orm": "6.4.5-dev.0",
|
|
68
68
|
"reflect-metadata": "0.2.2"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/utils/Configuration.d.ts
CHANGED
package/utils/Configuration.js
CHANGED
|
@@ -389,8 +389,8 @@ class EntityComparator {
|
|
|
389
389
|
dataKey = dataKey.replace(/^\./, '');
|
|
390
390
|
const contains = (str, re) => (str.match(re) || []).length > 0;
|
|
391
391
|
const a = contains(dataKey, /\./g);
|
|
392
|
-
const b = contains(dataKey, /\[/g);
|
|
393
|
-
return !!prop.object && !
|
|
392
|
+
const b = contains(dataKey, /\[idx_/g);
|
|
393
|
+
return !!prop.object && !a && !b;
|
|
394
394
|
}
|
|
395
395
|
getEmbeddedPropertySnapshot(meta, prop, context, level, path, dataKey, object = prop.object) {
|
|
396
396
|
const padding = ' '.repeat(level * 2);
|