@mikro-orm/core 7.2.1-dev.22 → 7.2.1-dev.23

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.
@@ -21,6 +21,8 @@ export declare class ObjectHydrator extends Hydrator {
21
21
  private wrap;
22
22
  /** Renders a key as a single-quoted JS string literal, safe to embed in generated code. */
23
23
  private quote;
24
+ /** Renders a key as an object literal key, quoted unless it is a plain identifier. */
25
+ private objectKey;
24
26
  private safeKey;
25
27
  }
26
28
  export {};
@@ -151,7 +151,7 @@ export class ObjectHydrator extends Hydrator {
151
151
  : `isPrimaryKey(data${dataKey}, true)`;
152
152
  ret.push(` if (${pkCheck}) {`);
153
153
  // When targetKey is set, pass the key option to createReference so it uses the alternate key
154
- const keyOption = prop.targetKey ? `, key: '${prop.targetKey}'` : '';
154
+ const keyOption = prop.targetKey ? `, key: ${this.quote(prop.targetKey)}` : '';
155
155
  if (prop.polymorphic) {
156
156
  // For polymorphic: target class from discriminator map, PK from data.id
157
157
  const discriminatorMapKey = this.safeKey(`discriminatorMap_${prop.name}_${this.#tmpIndex++}`);
@@ -199,8 +199,8 @@ export class ObjectHydrator extends Hydrator {
199
199
  const meta2 = this.metadata.get(prop.targetMeta.class);
200
200
  const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
201
201
  if (prop2 && !prop2.mapToPk) {
202
- ret.push(` if (data${dataKey} && entity${entityKey} && !entity${entityKey}.${this.safeKey(prop2.name)}) {`);
203
- ret.push(` entity${entityKey}.${prop.ref ? 'unwrap().' : ''}${this.safeKey(prop2.name)} = ${prop2.ref ? 'Reference.create(entity)' : 'entity'};`);
202
+ ret.push(` if (data${dataKey} && entity${entityKey} && !entity${entityKey}${this.wrap(prop2.name)}) {`);
203
+ ret.push(` entity${entityKey}${prop.ref ? '.unwrap()' : ''}${this.wrap(prop2.name)} = ${prop2.ref ? 'Reference.create(entity)' : 'entity'};`);
204
204
  ret.push(` }`);
205
205
  }
206
206
  }
@@ -291,7 +291,7 @@ export class ObjectHydrator extends Hydrator {
291
291
  else {
292
292
  ret.push(` const embeddedData = {`);
293
293
  for (const childProp of Object.values(prop.embeddedProps)) {
294
- const key = /^\w+$/.exec(childProp.embedded[1]) ? childProp.embedded[1] : `'${childProp.embedded[1]}'`;
294
+ const key = this.objectKey(childProp.embedded[1]);
295
295
  ret.push(` ${key}: data${this.wrap(childProp.name)},`);
296
296
  }
297
297
  ret.push(` };`);
@@ -418,8 +418,8 @@ export class ObjectHydrator extends Hydrator {
418
418
  lines.push(` const createCollectionItem_${this.safeKey(prop.name)} = (value, entity) => {`);
419
419
  const prop2 = prop.targetMeta.properties[prop.mappedBy];
420
420
  if (prop.kind === ReferenceKind.ONE_TO_MANY && prop2.primary) {
421
- lines.push(` if (typeof value === 'object' && value?.['${prop2.name}'] == null) {`);
422
- lines.push(` value = { ...value, ['${prop2.name}']: Reference.wrapReference(entity, { ref: ${prop2.ref} }) };`);
421
+ lines.push(` if (typeof value === 'object' && value?.[${this.quote(prop2.name)}] == null) {`);
422
+ lines.push(` value = { ...value, [${this.quote(prop2.name)}]: Reference.wrapReference(entity, { ref: ${prop2.ref} }) };`);
423
423
  lines.push(` }`);
424
424
  }
425
425
  const targetKey = this.safeKey(`${prop.targetMeta.tableName}_${this.#tmpIndex++}`);
@@ -440,6 +440,10 @@ export class ObjectHydrator extends Hydrator {
440
440
  quote(key) {
441
441
  return `'${key.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
442
442
  }
443
+ /** Renders a key as an object literal key, quoted unless it is a plain identifier. */
444
+ objectKey(key) {
445
+ return /^\w+$/.exec(key) ? key : this.quote(key);
446
+ }
443
447
  safeKey(key) {
444
448
  return key.replace(/\W/g, '_');
445
449
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.2.1-dev.22",
3
+ "version": "7.2.1-dev.23",
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",
@@ -82,6 +82,8 @@ export declare class EntityComparator {
82
82
  private wrap;
83
83
  /** Renders a key as a single-quoted JS string literal, safe to embed in generated code. */
84
84
  private quote;
85
+ /** Renders a key as an object literal key, quoted unless it is a plain identifier. */
86
+ private objectKey;
85
87
  private safeKey;
86
88
  /**
87
89
  * Sets the toArray helper in the context if not already set.
@@ -65,14 +65,14 @@ export class EntityComparator {
65
65
  lines.push(` const cond = {`);
66
66
  meta.primaryKeys.forEach(pk => {
67
67
  if (meta.properties[pk].kind !== ReferenceKind.SCALAR) {
68
- lines.push(` ${pk}: (entity${this.wrap(pk)} != null && isEntityOrRef(entity${this.wrap(pk)})) ? entity${this.wrap(pk)}.__helper.getPrimaryKey() : entity${this.wrap(pk)},`);
68
+ 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)},`);
69
69
  }
70
70
  else {
71
- lines.push(` ${pk}: entity${this.wrap(pk)},`);
71
+ lines.push(` ${this.objectKey(pk)}: entity${this.wrap(pk)},`);
72
72
  }
73
73
  });
74
74
  lines.push(` };`);
75
- lines.push(` if (${meta.primaryKeys.map(pk => `cond.${pk} == null`).join(' || ')}) return null;`);
75
+ lines.push(` if (${meta.primaryKeys.map(pk => `cond${this.wrap(pk)} == null`).join(' || ')}) return null;`);
76
76
  lines.push(` return cond;`);
77
77
  }
78
78
  else {
@@ -116,20 +116,20 @@ export class EntityComparator {
116
116
  lines.push(` const cond = {`);
117
117
  meta.primaryKeys.forEach(pk => {
118
118
  if (meta.properties[pk].kind !== ReferenceKind.SCALAR) {
119
- lines.push(` ${pk}: (entity${this.wrap(pk)} != null && isEntityOrRef(entity${this.wrap(pk)})) ? entity${this.wrap(pk)}.__helper.getPrimaryKey(true) : entity${this.wrap(pk)},`);
119
+ 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)},`);
120
120
  }
121
121
  else {
122
122
  if (meta.properties[pk].customType) {
123
123
  const convertorKey = this.registerCustomType(meta.properties[pk], context);
124
- lines.push(` ${pk}: convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)}),`);
124
+ lines.push(` ${this.objectKey(pk)}: convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)}),`);
125
125
  }
126
126
  else {
127
- lines.push(` ${pk}: entity${this.wrap(pk)},`);
127
+ lines.push(` ${this.objectKey(pk)}: entity${this.wrap(pk)},`);
128
128
  }
129
129
  }
130
130
  });
131
131
  lines.push(` };`);
132
- lines.push(` if (${meta.primaryKeys.map(pk => `cond.${pk} == null`).join(' || ')}) return null;`);
132
+ lines.push(` if (${meta.primaryKeys.map(pk => `cond${this.wrap(pk)} == null`).join(' || ')}) return null;`);
133
133
  lines.push(` return cond;`);
134
134
  }
135
135
  else {
@@ -193,7 +193,7 @@ export class EntityComparator {
193
193
  }
194
194
  const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
195
195
  if (serializedPrimaryKey) {
196
- lines.push(` return '' + entity.${serializedPrimaryKey.name};`);
196
+ lines.push(` return '' + entity${this.wrap(serializedPrimaryKey.name)};`);
197
197
  }
198
198
  else if (prop.customType) {
199
199
  const convertorKey = this.registerCustomType(meta.properties[pk], context);
@@ -617,6 +617,8 @@ export class EntityComparator {
617
617
  else if (prop.targetKey) {
618
618
  // When targetKey is set, extract that property value instead of the PK
619
619
  const targetProp = prop.targetMeta?.properties[prop.targetKey];
620
+ // `wrap()` yields `.name` or `['name']`, optional chaining needs the dot in both forms
621
+ const targetAccess = `?${this.wrap(prop.targetKey).replace(/^\[/, '.[')}`;
620
622
  ret += ` if (entity${entityKey} === null) {\n`;
621
623
  ret += ` ret${dataKey} = null;\n`;
622
624
  ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
@@ -624,10 +626,10 @@ export class EntityComparator {
624
626
  if (targetProp?.customType) {
625
627
  // If targetKey property has a custom type, convert to database value
626
628
  const convertorKey = this.registerCustomType(targetProp, context);
627
- ret += ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(val${level}?.${prop.targetKey});\n`;
629
+ ret += ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(val${level}${targetAccess});\n`;
628
630
  }
629
631
  else {
630
- ret += ` ret${dataKey} = val${level}?.${prop.targetKey};\n`;
632
+ ret += ` ret${dataKey} = val${level}${targetAccess};\n`;
631
633
  }
632
634
  ret += ` }\n`;
633
635
  }
@@ -767,6 +769,10 @@ export class EntityComparator {
767
769
  quote(key) {
768
770
  return `'${key.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
769
771
  }
772
+ /** Renders a key as an object literal key, quoted unless it is a plain identifier. */
773
+ objectKey(key) {
774
+ return /^\w+$/.exec(key) ? key : this.quote(key);
775
+ }
770
776
  safeKey(key) {
771
777
  return key.replace(/\W/g, '_');
772
778
  }
package/utils/Utils.js CHANGED
@@ -153,7 +153,7 @@ export function parseJsonSafe(value) {
153
153
  /** Collection of general-purpose utility methods used throughout the ORM. */
154
154
  export class Utils {
155
155
  static PK_SEPARATOR = '~~~';
156
- static #ORM_VERSION = '7.2.1-dev.22';
156
+ static #ORM_VERSION = '7.2.1-dev.23';
157
157
  /** Default session variable name backing an RLS filter argument (`current_setting('mikro.<filter>.<arg>')`). */
158
158
  static getRlsSettingName(filterName, argName) {
159
159
  return `mikro.${filterName}.${argName}`;