@mikro-orm/core 6.6.18-dev.0 → 6.6.18-dev.2
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.
|
@@ -19,6 +19,10 @@ export declare class ObjectHydrator extends Hydrator {
|
|
|
19
19
|
getEntityHydrator<T extends object>(meta: EntityMetadata<T>, type: 'full' | 'reference', normalizeAccessors?: boolean): EntityHydrator<T>;
|
|
20
20
|
private createCollectionItemMapper;
|
|
21
21
|
private wrap;
|
|
22
|
+
/** Renders a key as a single-quoted JS string literal, safe to embed in generated code. */
|
|
23
|
+
private quote;
|
|
24
|
+
/** Renders a key as an object literal key, quoted unless it is a plain identifier. */
|
|
25
|
+
private objectKey;
|
|
22
26
|
private safeKey;
|
|
23
27
|
}
|
|
24
28
|
export {};
|
|
@@ -80,7 +80,7 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
80
80
|
ret.push(` if (data${dataKey} === null) {`);
|
|
81
81
|
if (prop.ref) {
|
|
82
82
|
ret.push(` entity${entityKey} = new ScalarReference();`);
|
|
83
|
-
ret.push(` entity${entityKey}.bind(entity,
|
|
83
|
+
ret.push(` entity${entityKey}.bind(entity, ${this.quote(prop.name)});`);
|
|
84
84
|
ret.push(` entity${entityKey}.set(${nullVal});`);
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
@@ -120,14 +120,14 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
120
120
|
if (prop.ref) {
|
|
121
121
|
ret.push(` const value = entity${entityKey};`);
|
|
122
122
|
ret.push(` entity${entityKey} = oldValue_${idx} ?? new ScalarReference(value);`);
|
|
123
|
-
ret.push(` entity${entityKey}.bind(entity,
|
|
123
|
+
ret.push(` entity${entityKey}.bind(entity, ${this.quote(prop.name)});`);
|
|
124
124
|
ret.push(` entity${entityKey}.set(value);`);
|
|
125
125
|
}
|
|
126
126
|
ret.push(` }`);
|
|
127
127
|
if (prop.ref) {
|
|
128
128
|
ret.push(` if (!entity${entityKey}) {`);
|
|
129
129
|
ret.push(` entity${entityKey} = new ScalarReference();`);
|
|
130
|
-
ret.push(` entity${entityKey}.bind(entity,
|
|
130
|
+
ret.push(` entity${entityKey}.bind(entity, ${this.quote(prop.name)});`);
|
|
131
131
|
ret.push(` }`);
|
|
132
132
|
}
|
|
133
133
|
return ret;
|
|
@@ -158,8 +158,8 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
158
158
|
const meta2 = this.metadata.get(prop.type);
|
|
159
159
|
const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
|
|
160
160
|
if (prop2 && !prop2.mapToPk) {
|
|
161
|
-
ret.push(` if (data${dataKey} && entity${entityKey} && !entity${entityKey}
|
|
162
|
-
ret.push(` entity${entityKey}
|
|
161
|
+
ret.push(` if (data${dataKey} && entity${entityKey} && !entity${entityKey}${this.wrap(prop2.name)}) {`);
|
|
162
|
+
ret.push(` entity${entityKey}${prop.ref ? '.unwrap()' : ''}${this.wrap(prop2.name)} = ${prop2.ref ? 'Reference.create(entity)' : 'entity'};`);
|
|
163
163
|
ret.push(` }`);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
@@ -179,7 +179,7 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
179
179
|
ret.push(` }`);
|
|
180
180
|
ret.push(` if (Array.isArray(data${dataKey})) {`);
|
|
181
181
|
ret.push(` const items = data${dataKey}.map(value => createCollectionItem_${this.safeKey(prop.name)}(value, entity));`);
|
|
182
|
-
ret.push(` const coll = Collection.create(entity,
|
|
182
|
+
ret.push(` const coll = Collection.create(entity, ${this.quote(prop.name)}, items, newEntity);`);
|
|
183
183
|
ret.push(` if (newEntity) {`);
|
|
184
184
|
ret.push(` coll.setDirty();`);
|
|
185
185
|
ret.push(` } else {`);
|
|
@@ -190,11 +190,11 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
190
190
|
if (!this.platform.usesPivotTable() && prop.owner && prop.kind === enums_1.ReferenceKind.MANY_TO_MANY) {
|
|
191
191
|
ret.push(` } else if (!entity${entityKey} && Array.isArray(data${dataKey})) {`);
|
|
192
192
|
const items = this.platform.usesPivotTable() || !prop.owner ? 'undefined' : '[]';
|
|
193
|
-
ret.push(` const coll = Collection.create(entity,
|
|
193
|
+
ret.push(` const coll = Collection.create(entity, ${this.quote(prop.name)}, ${items}, !!data${dataKey} || newEntity);`);
|
|
194
194
|
ret.push(` coll.setDirty(false);`);
|
|
195
195
|
}
|
|
196
196
|
ret.push(` } else if (!entity${entityKey}) {`);
|
|
197
|
-
ret.push(` const coll = Collection.create(entity,
|
|
197
|
+
ret.push(` const coll = Collection.create(entity, ${this.quote(prop.name)}, undefined, newEntity);`);
|
|
198
198
|
ret.push(` coll.setDirty(false);`);
|
|
199
199
|
ret.push(` }`);
|
|
200
200
|
return ret;
|
|
@@ -247,7 +247,7 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
247
247
|
else {
|
|
248
248
|
ret.push(` const embeddedData = {`);
|
|
249
249
|
for (const childProp of Object.values(prop.embeddedProps)) {
|
|
250
|
-
const key =
|
|
250
|
+
const key = this.objectKey(childProp.embedded[1]);
|
|
251
251
|
ret.push(` ${key}: data${this.wrap(childProp.name)},`);
|
|
252
252
|
}
|
|
253
253
|
ret.push(` };`);
|
|
@@ -361,8 +361,8 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
361
361
|
lines.push(` const createCollectionItem_${this.safeKey(prop.name)} = (value, entity) => {`);
|
|
362
362
|
const prop2 = prop.targetMeta.properties[prop.mappedBy];
|
|
363
363
|
if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY && prop2.primary) {
|
|
364
|
-
lines.push(` if (typeof value === 'object' && value?.[
|
|
365
|
-
lines.push(` value = { ...value, [
|
|
364
|
+
lines.push(` if (typeof value === 'object' && value?.[${this.quote(prop2.name)}] == null) {`);
|
|
365
|
+
lines.push(` value = { ...value, [${this.quote(prop2.name)}]: Reference.wrapReference(entity, { ref: ${prop2.ref} }) };`);
|
|
366
366
|
lines.push(` }`);
|
|
367
367
|
}
|
|
368
368
|
lines.push(` if (isPrimaryKey(value, ${meta.compositePK})) return factory.createReference('${prop.type}', value, { convertCustomTypes, schema, normalizeAccessors, merge: true });`);
|
|
@@ -372,10 +372,18 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
372
372
|
return lines;
|
|
373
373
|
}
|
|
374
374
|
wrap(key) {
|
|
375
|
-
if (key.match(/^\[
|
|
375
|
+
if (key.match(/^\[idx_\d+]$/)) {
|
|
376
376
|
return key;
|
|
377
377
|
}
|
|
378
|
-
return key.match(/^\w+$/) ? `.${key}` : `[
|
|
378
|
+
return key.match(/^\w+$/) ? `.${key}` : `[${this.quote(key)}]`;
|
|
379
|
+
}
|
|
380
|
+
/** Renders a key as a single-quoted JS string literal, safe to embed in generated code. */
|
|
381
|
+
quote(key) {
|
|
382
|
+
return `'${key.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
383
|
+
}
|
|
384
|
+
/** Renders a key as an object literal key, quoted unless it is a plain identifier. */
|
|
385
|
+
objectKey(key) {
|
|
386
|
+
return key.match(/^\w+$/) ? key : this.quote(key);
|
|
379
387
|
}
|
|
380
388
|
safeKey(key) {
|
|
381
389
|
return key.replace(/\W/g, '_');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "6.6.18-dev.
|
|
3
|
+
"version": "6.6.18-dev.2",
|
|
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.3",
|
|
66
66
|
"globby": "11.1.0",
|
|
67
|
-
"mikro-orm": "6.6.18-dev.
|
|
67
|
+
"mikro-orm": "6.6.18-dev.2",
|
|
68
68
|
"reflect-metadata": "0.2.2"
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -83,6 +83,10 @@ export declare class EntityComparator {
|
|
|
83
83
|
private getGenericComparator;
|
|
84
84
|
private getPropertyComparator;
|
|
85
85
|
private wrap;
|
|
86
|
+
/** Renders a key as a single-quoted JS string literal, safe to embed in generated code. */
|
|
87
|
+
private quote;
|
|
88
|
+
/** Renders a key as an object literal key, quoted unless it is a plain identifier. */
|
|
89
|
+
private objectKey;
|
|
86
90
|
private safeKey;
|
|
87
91
|
/**
|
|
88
92
|
* perf: used to generate list of comparable properties during discovery, so we speed up the runtime comparison
|
|
@@ -63,14 +63,14 @@ class EntityComparator {
|
|
|
63
63
|
lines.push(` const cond = {`);
|
|
64
64
|
meta.primaryKeys.forEach(pk => {
|
|
65
65
|
if (meta.properties[pk].kind !== enums_1.ReferenceKind.SCALAR) {
|
|
66
|
-
lines.push(` ${pk}: (entity${this.wrap(pk)} != null && isEntityOrRef(entity${this.wrap(pk)})) ? entity${this.wrap(pk)}.__helper.getPrimaryKey() : entity${this.wrap(pk)},`);
|
|
66
|
+
lines.push(` ${this.objectKey(pk)}: (entity${this.wrap(pk)} != null && isEntityOrRef(entity${this.wrap(pk)})) ? entity${this.wrap(pk)}.__helper.getPrimaryKey() : entity${this.wrap(pk)},`);
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
|
-
lines.push(` ${pk}: entity${this.wrap(pk)},`);
|
|
69
|
+
lines.push(` ${this.objectKey(pk)}: entity${this.wrap(pk)},`);
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
72
|
lines.push(` };`);
|
|
73
|
-
lines.push(` if (${meta.primaryKeys.map(pk => `cond
|
|
73
|
+
lines.push(` if (${meta.primaryKeys.map(pk => `cond${this.wrap(pk)} == null`).join(' || ')}) return null;`);
|
|
74
74
|
lines.push(` return cond;`);
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
@@ -114,20 +114,20 @@ class EntityComparator {
|
|
|
114
114
|
lines.push(` const cond = {`);
|
|
115
115
|
meta.primaryKeys.forEach(pk => {
|
|
116
116
|
if (meta.properties[pk].kind !== enums_1.ReferenceKind.SCALAR) {
|
|
117
|
-
lines.push(` ${pk}: (entity${this.wrap(pk)} != null && isEntityOrRef(entity${this.wrap(pk)})) ? entity${this.wrap(pk)}.__helper.getPrimaryKey(true) : entity${this.wrap(pk)},`);
|
|
117
|
+
lines.push(` ${this.objectKey(pk)}: (entity${this.wrap(pk)} != null && isEntityOrRef(entity${this.wrap(pk)})) ? entity${this.wrap(pk)}.__helper.getPrimaryKey(true) : entity${this.wrap(pk)},`);
|
|
118
118
|
}
|
|
119
119
|
else {
|
|
120
120
|
if (meta.properties[pk].customType) {
|
|
121
121
|
const convertorKey = this.registerCustomType(meta.properties[pk], context);
|
|
122
|
-
lines.push(` ${pk}: convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)}),`);
|
|
122
|
+
lines.push(` ${this.objectKey(pk)}: convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)}),`);
|
|
123
123
|
}
|
|
124
124
|
else {
|
|
125
|
-
lines.push(` ${pk}: entity${this.wrap(pk)},`);
|
|
125
|
+
lines.push(` ${this.objectKey(pk)}: entity${this.wrap(pk)},`);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
});
|
|
129
129
|
lines.push(` };`);
|
|
130
|
-
lines.push(` if (${meta.primaryKeys.map(pk => `cond
|
|
130
|
+
lines.push(` if (${meta.primaryKeys.map(pk => `cond${this.wrap(pk)} == null`).join(' || ')}) return null;`);
|
|
131
131
|
lines.push(` return cond;`);
|
|
132
132
|
}
|
|
133
133
|
else {
|
|
@@ -161,7 +161,8 @@ class EntityComparator {
|
|
|
161
161
|
const lines = [];
|
|
162
162
|
const context = new Map();
|
|
163
163
|
context.set('isEntityOrRef', (val) => Utils_1.Utils.isEntity(val, true));
|
|
164
|
-
|
|
164
|
+
// deep flatten, nested composite PKs produce nested arrays that would be comma-joined by the hash
|
|
165
|
+
context.set('getCompositeKeyValue', (val) => Utils_1.Utils.flatten(Utils_1.Utils.getCompositeKeyValue(val, meta, 'convertToDatabaseValue', this.platform), true));
|
|
165
166
|
context.set('getPrimaryKeyHash', (val) => Utils_1.Utils.getPrimaryKeyHash(Utils_1.Utils.asArray(val)));
|
|
166
167
|
if (meta.primaryKeys.length > 1) {
|
|
167
168
|
lines.push(` const pks = entity.__helper.__pk ? getCompositeKeyValue(entity.__helper.__pk) : [`);
|
|
@@ -184,7 +185,7 @@ class EntityComparator {
|
|
|
184
185
|
}
|
|
185
186
|
const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
|
|
186
187
|
if (serializedPrimaryKey) {
|
|
187
|
-
lines.push(` return '' + entity
|
|
188
|
+
lines.push(` return '' + entity${this.wrap(serializedPrimaryKey.name)};`);
|
|
188
189
|
}
|
|
189
190
|
else if (prop.customType) {
|
|
190
191
|
const convertorKey = this.registerCustomType(meta.properties[pk], context);
|
|
@@ -651,10 +652,18 @@ class EntityComparator {
|
|
|
651
652
|
return this.getGenericComparator(this.wrap(prop.name), `!equals(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
|
|
652
653
|
}
|
|
653
654
|
wrap(key) {
|
|
654
|
-
if (key.match(/^\[
|
|
655
|
+
if (key.match(/^\[idx_\d+]$/)) {
|
|
655
656
|
return key;
|
|
656
657
|
}
|
|
657
|
-
return key.match(/^\w+$/) ? `.${key}` : `[
|
|
658
|
+
return key.match(/^\w+$/) ? `.${key}` : `[${this.quote(key)}]`;
|
|
659
|
+
}
|
|
660
|
+
/** Renders a key as a single-quoted JS string literal, safe to embed in generated code. */
|
|
661
|
+
quote(key) {
|
|
662
|
+
return `'${key.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
663
|
+
}
|
|
664
|
+
/** Renders a key as an object literal key, quoted unless it is a plain identifier. */
|
|
665
|
+
objectKey(key) {
|
|
666
|
+
return key.match(/^\w+$/) ? key : this.quote(key);
|
|
658
667
|
}
|
|
659
668
|
safeKey(key) {
|
|
660
669
|
return key.replace(/\W/g, '_');
|
package/utils/Utils.js
CHANGED
|
@@ -503,7 +503,8 @@ class Utils {
|
|
|
503
503
|
static getCompositeKeyHash(data, meta, convertCustomTypes = false, platform, flat = false) {
|
|
504
504
|
let pks = this.getCompositeKeyValue(data, meta, convertCustomTypes, platform);
|
|
505
505
|
if (flat) {
|
|
506
|
-
|
|
506
|
+
// deep flatten, nested composite PKs produce nested arrays that would be comma-joined by the hash
|
|
507
|
+
pks = Utils.flatten(pks, true);
|
|
507
508
|
}
|
|
508
509
|
return Utils.getPrimaryKeyHash(pks);
|
|
509
510
|
}
|