@mikro-orm/core 6.5.8-dev.14 → 6.5.8-dev.16

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 CHANGED
@@ -678,24 +678,7 @@ class EntityManager {
678
678
  }
679
679
  }
680
680
  }
681
- const unique = options.onConflictFields ?? meta.props.filter(p => p.unique).map(p => p.name);
682
- const propIndex = !utils_1.Utils.isRawSql(unique) && unique.findIndex(p => data[p] != null);
683
- if (options.onConflictFields || where == null) {
684
- if (propIndex !== false && propIndex >= 0) {
685
- where = { [unique[propIndex]]: data[unique[propIndex]] };
686
- }
687
- else if (meta.uniques.length > 0) {
688
- for (const u of meta.uniques) {
689
- if (utils_1.Utils.asArray(u.properties).every(p => data[p] != null)) {
690
- where = utils_1.Utils.asArray(u.properties).reduce((o, key) => {
691
- o[key] = data[key];
692
- return o;
693
- }, {});
694
- break;
695
- }
696
- }
697
- }
698
- }
681
+ where = (0, utils_1.getWhereCondition)(meta, options.onConflictFields, data, where).where;
699
682
  data = utils_1.QueryHelper.processObjectParams(data);
700
683
  em.validator.validateParams(data, 'insert data');
701
684
  if (em.eventManager.hasListeners(enums_1.EventType.beforeUpsert, meta)) {
@@ -830,31 +813,17 @@ class EntityManager {
830
813
  }
831
814
  }
832
815
  }
833
- const unique = meta.props.filter(p => p.unique).map(p => p.name);
834
- propIndex = unique.findIndex(p => row[p] != null);
835
- if (options.onConflictFields || where == null) {
836
- if (propIndex >= 0) {
837
- where = { [unique[propIndex]]: row[unique[propIndex]] };
838
- }
839
- else if (meta.uniques.length > 0) {
840
- for (const u of meta.uniques) {
841
- if (utils_1.Utils.asArray(u.properties).every(p => row[p] != null)) {
842
- where = utils_1.Utils.asArray(u.properties).reduce((o, key) => {
843
- o[key] = row[key];
844
- return o;
845
- }, {});
846
- break;
847
- }
848
- }
849
- }
850
- }
851
- row = utils_1.QueryHelper.processObjectParams(row);
816
+ const unique = options.onConflictFields ?? meta.props.filter(p => p.unique).map(p => p.name);
817
+ propIndex = !utils_1.Utils.isRawSql(unique) && unique.findIndex(p => data[p] ?? data[p.substring(0, p.indexOf('.'))] != null);
818
+ const tmp = (0, utils_1.getWhereCondition)(meta, options.onConflictFields, row, where);
819
+ propIndex = tmp.propIndex;
852
820
  where = utils_1.QueryHelper.processWhere({
853
- where,
821
+ where: tmp.where,
854
822
  entityName,
855
823
  metadata: this.metadata,
856
824
  platform: this.getPlatform(),
857
825
  });
826
+ row = utils_1.QueryHelper.processObjectParams(row);
858
827
  em.validator.validateParams(row, 'insert data');
859
828
  allData.push(row);
860
829
  allWhere.push(where);
@@ -896,7 +865,7 @@ class EntityManager {
896
865
  const reloadFields = returning.length > 0 && !(this.getPlatform().usesReturningStatement() && res.rows?.length);
897
866
  if (options.onConflictAction === 'ignore' || (!res.rows?.length && loadPK.size > 0) || reloadFields) {
898
867
  const unique = meta.hydrateProps.filter(p => !p.lazy).map(p => p.name);
899
- const add = new Set(propIndex >= 0 ? [unique[propIndex]] : []);
868
+ const add = new Set(propIndex !== false && propIndex >= 0 ? [unique[propIndex]] : []);
900
869
  for (const cond of loadPK.values()) {
901
870
  utils_1.Utils.keys(cond).forEach(key => add.add(key));
902
871
  }
@@ -6,7 +6,7 @@ import type { ManyToOneOptions } from '../decorators/ManyToOne';
6
6
  import type { OneToManyOptions } from '../decorators/OneToMany';
7
7
  import type { OneToOneOptions } from '../decorators/OneToOne';
8
8
  import type { ManyToManyOptions } from '../decorators/ManyToMany';
9
- import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, Hidden, Opt, EntityClass } from '../typings';
9
+ import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, Hidden, Opt, Primary, EntityClass } from '../typings';
10
10
  import type { Reference, ScalarReference } from './Reference';
11
11
  import type { SerializeOptions } from '../serialization/EntitySerializer';
12
12
  import type { Cascade, DeferMode, LoadStrategy, QueryOrderMap } from '../enums';
@@ -390,7 +390,11 @@ export declare class ManyToOneOptionsBuilder<TargetValue extends object> extends
390
390
  /** Point to the inverse side property name. */
391
391
  inversedBy(inversedBy: (string & keyof TargetValue) | ((e: TargetValue) => any)): this;
392
392
  /** Map this relation to the primary key value instead of an entity. */
393
- mapToPk(mapToPk?: boolean): this;
393
+ mapToPk<T extends boolean = true>(mapToPk?: T): this & {
394
+ '~options': {
395
+ mapToPk: T;
396
+ };
397
+ };
394
398
  /** Override the default database column name on the owning side (see {@doclink naming-strategy | Naming Strategy}). This option is only for simple properties represented by a single column. */
395
399
  joinColumn(joinColumn: string): this;
396
400
  /** Override the default database column name on the owning side (see {@doclink naming-strategy | Naming Strategy}). This option is suitable for composite keys, where one property is represented by multiple columns. */
@@ -458,7 +462,11 @@ export declare class OneToOneOptionsBuilder<TargetValue extends object> extends
458
462
  /** Point to the inverse side property name. */
459
463
  inversedBy(inversedBy: (string & keyof TargetValue) | ((e: TargetValue) => any)): this;
460
464
  /** Map this relation to the primary key value instead of an entity. */
461
- mapToPk(mapToPk?: boolean): this;
465
+ mapToPk<T extends boolean = true>(mapToPk?: T): this & {
466
+ '~options': {
467
+ mapToPk: T;
468
+ };
469
+ };
462
470
  /** When a part of a composite column is shared in other properties, use this option to specify what columns are considered as owned by this property. This is useful when your composite property is nullable, but parts of it are not. */
463
471
  ownColumns(...ownColumns: string[]): this;
464
472
  /** What to do when the target entity gets deleted. */
@@ -582,27 +590,38 @@ type InferBuilderValue<Builder> = Builder extends {
582
590
  '~type'?: {
583
591
  value: infer Value;
584
592
  };
585
- } ? MaybeHidden<MaybeOpt<MaybeRef<MaybeNullable<MaybeArray<Value, Builder>, Builder>, Builder>, Builder>, Builder> : never;
593
+ } ? MaybeHidden<MaybeOpt<MaybeScalarRef<MaybeNullable<MaybeRelationRef<MaybeMapToPk<MaybeArray<Value, Builder>, Builder>, Builder>, Builder>, Builder>, Builder>, Builder> : never;
586
594
  type MaybeArray<Value, Builder> = Builder extends {
587
595
  '~options': {
588
596
  array: true;
589
597
  };
590
598
  } ? Value[] : Value;
599
+ type MaybeMapToPk<Value, Builder> = Builder extends {
600
+ '~options': {
601
+ mapToPk: true;
602
+ };
603
+ } ? Primary<Value> : Value;
591
604
  type MaybeNullable<Value, Builder> = Builder extends {
592
605
  '~options': {
593
606
  nullable: true;
594
607
  };
595
608
  } ? Value | null | undefined : Value;
596
- type MaybeRef<Value, Builder> = Builder extends {
609
+ type MaybeRelationRef<Value, Builder> = Builder extends {
610
+ '~options': {
611
+ mapToPk: true;
612
+ };
613
+ } ? Value : Builder extends {
597
614
  '~options': {
598
615
  ref: false;
599
616
  };
600
617
  } ? Value : Builder extends {
601
618
  '~options': {
619
+ ref: true;
602
620
  kind: '1:1';
603
621
  };
604
622
  } ? Value extends object ? Reference<Value> : never : Builder extends {
605
623
  '~options': {
624
+ ref: true;
606
625
  kind: 'm:1';
607
626
  };
608
627
  } ? Value extends object ? Reference<Value> : never : Builder extends {
@@ -613,12 +632,25 @@ type MaybeRef<Value, Builder> = Builder extends {
613
632
  '~options': {
614
633
  kind: 'm:n';
615
634
  };
616
- } ? Value extends object ? Collection<Value> : never : Builder extends {
635
+ } ? Value extends object ? Collection<Value> : never : Value;
636
+ type MaybeScalarRef<Value, Builder> = Builder extends {
637
+ '~options': {
638
+ ref: false;
639
+ };
640
+ } ? Value : Builder extends {
641
+ '~options': {
642
+ kind: '1:1' | 'm:1' | '1:m' | 'm:n';
643
+ };
644
+ } ? Value : Builder extends {
617
645
  '~options': {
618
646
  ref: true;
619
647
  };
620
648
  } ? ScalarReference<Value> : Value;
621
649
  type MaybeOpt<Value, Builder> = Builder extends {
650
+ '~options': {
651
+ mapToPk: true;
652
+ };
653
+ } ? Value extends Opt<infer OriginalValue> ? OriginalValue : Value : Builder extends {
622
654
  '~options': {
623
655
  autoincrement: true;
624
656
  };
@@ -645,7 +645,6 @@ const propertyBuilders = {
645
645
  manyToOne: (target) => new ManyToOneOptionsBuilder({
646
646
  entity: () => target,
647
647
  kind: 'm:1',
648
- ref: true,
649
648
  }),
650
649
  oneToMany: (target) => new OneToManyOptionsBuilderOnlyMappedBy({
651
650
  entity: () => target,
@@ -654,7 +653,6 @@ const propertyBuilders = {
654
653
  oneToOne: (target) => new OneToOneOptionsBuilder({
655
654
  entity: () => target,
656
655
  kind: '1:1',
657
- ref: true,
658
656
  }),
659
657
  };
660
658
  function getBuilderOptions(builder) {
package/index.mjs CHANGED
@@ -204,6 +204,7 @@ export const expandDotPaths = mod.expandDotPaths;
204
204
  export const getLoadingStrategy = mod.getLoadingStrategy;
205
205
  export const getOnConflictFields = mod.getOnConflictFields;
206
206
  export const getOnConflictReturningFields = mod.getOnConflictReturningFields;
207
+ export const getWhereCondition = mod.getWhereCondition;
207
208
  export const helper = mod.helper;
208
209
  export const parseJsonSafe = mod.parseJsonSafe;
209
210
  export const quote = mod.quote;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.5.8-dev.14",
3
+ "version": "6.5.8-dev.16",
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.2",
66
66
  "globby": "11.1.0",
67
- "mikro-orm": "6.5.8-dev.14",
67
+ "mikro-orm": "6.5.8-dev.16",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }
@@ -1,7 +1,12 @@
1
- import type { EntityData, EntityMetadata } from '../typings';
1
+ import type { EntityData, EntityMetadata, FilterQuery } from '../typings';
2
2
  import type { UpsertOptions } from '../drivers/IDatabaseDriver';
3
3
  import type { RawQueryFragment } from '../utils/RawQueryFragment';
4
4
  /** @internal */
5
5
  export declare function getOnConflictFields<T>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | RawQueryFragment, options: UpsertOptions<T>): (keyof T)[];
6
6
  /** @internal */
7
7
  export declare function getOnConflictReturningFields<T, P extends string>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | RawQueryFragment, options: UpsertOptions<T, P>): (keyof T)[] | '*';
8
+ /** @internal */
9
+ export declare function getWhereCondition<T extends object>(meta: EntityMetadata<T>, onConflictFields: (keyof T)[] | RawQueryFragment | undefined, data: EntityData<T>, where: FilterQuery<T>): {
10
+ where: FilterQuery<T>;
11
+ propIndex: number | false;
12
+ };
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getOnConflictFields = getOnConflictFields;
4
4
  exports.getOnConflictReturningFields = getOnConflictReturningFields;
5
+ exports.getWhereCondition = getWhereCondition;
6
+ const Utils_1 = require("./Utils");
5
7
  function expandEmbeddedProperties(prop, key) {
6
8
  if (prop.object) {
7
9
  return [prop.name];
@@ -100,3 +102,44 @@ function getOnConflictReturningFields(meta, data, uniqueFields, options) {
100
102
  }
101
103
  return keys.filter(key => !(key in data));
102
104
  }
105
+ function getPropertyValue(obj, key) {
106
+ if (key.indexOf('.') === -1) {
107
+ return obj[key];
108
+ }
109
+ const parts = key.split('.');
110
+ let curr = obj;
111
+ for (let i = 0; i < parts.length - 1; i++) {
112
+ curr[parts[i]] ??= {};
113
+ curr = curr[parts[i]];
114
+ }
115
+ return curr[parts[parts.length - 1]];
116
+ }
117
+ /** @internal */
118
+ function getWhereCondition(meta, onConflictFields, data, where) {
119
+ const unique = onConflictFields ?? meta.props.filter(p => p.unique).map(p => p.name);
120
+ const propIndex = !Utils_1.Utils.isRawSql(unique) && unique.findIndex(p => data[p] ?? data[p.substring(0, p.indexOf('.'))] != null);
121
+ if (onConflictFields || where == null) {
122
+ if (propIndex !== false && propIndex >= 0) {
123
+ let key = unique[propIndex];
124
+ if (key.includes('.')) {
125
+ const prop = meta.properties[key.substring(0, key.indexOf('.'))];
126
+ if (prop) {
127
+ key = `${prop.fieldNames[0]}${key.substring(key.indexOf('.'))}`;
128
+ }
129
+ }
130
+ where = { [key]: getPropertyValue(data, unique[propIndex]) };
131
+ }
132
+ else if (meta.uniques.length > 0) {
133
+ for (const u of meta.uniques) {
134
+ if (Utils_1.Utils.asArray(u.properties).every(p => data[p] != null)) {
135
+ where = Utils_1.Utils.asArray(u.properties).reduce((o, key) => {
136
+ o[key] = data[key];
137
+ return o;
138
+ }, {});
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ return { where, propIndex };
145
+ }