@mikro-orm/core 6.4.17-dev.1 → 6.4.17-dev.11

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.
@@ -37,4 +37,6 @@ export interface ManyToManyOptions<Owner, Target> extends ReferenceOptions<Owner
37
37
  deleteRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
38
38
  /** What to do when the reference to the target entity gets updated. */
39
39
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
40
+ /** Enable/disable foreign key constraint creation on this relation */
41
+ createForeignKeyConstraint?: boolean;
40
42
  }
@@ -27,6 +27,8 @@ export interface ManyToOneOptions<Owner, Target> extends ReferenceOptions<Owner,
27
27
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
28
28
  /** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
29
29
  deferMode?: DeferMode | `${DeferMode}`;
30
+ /** Enable/disable foreign key constraint creation on this relation */
31
+ createForeignKeyConstraint?: boolean;
30
32
  /** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
31
33
  foreignKeyName?: string;
32
34
  }
@@ -23,4 +23,6 @@ export interface OneToOneOptions<Owner, Target> extends Partial<Omit<OneToManyOp
23
23
  deferMode?: DeferMode | `${DeferMode}`;
24
24
  /** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
25
25
  foreignKeyName?: string;
26
+ /** Enable/disable foreign key constraint creation on this relation */
27
+ createForeignKeyConstraint?: boolean;
26
28
  }
@@ -102,6 +102,8 @@ class EntitySchema {
102
102
  if (prop.fieldNames && !prop.joinColumns) {
103
103
  prop.joinColumns = prop.fieldNames;
104
104
  }
105
+ // By default, the foreign key constraint is created on the relation
106
+ utils_1.Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
105
107
  this.addProperty(name, type, prop);
106
108
  }
107
109
  addManyToMany(name, type, options) {
@@ -111,6 +113,8 @@ class EntitySchema {
111
113
  }
112
114
  if (options.owner) {
113
115
  utils_1.Utils.renameKey(options, 'mappedBy', 'inversedBy');
116
+ // By default, the foreign key constraint is created on the relation
117
+ utils_1.Utils.defaultValue(options, 'createForeignKeyConstraint', true);
114
118
  }
115
119
  const prop = this.createProperty(enums_1.ReferenceKind.MANY_TO_MANY, options);
116
120
  this.addProperty(name, type, prop);
@@ -123,8 +127,12 @@ class EntitySchema {
123
127
  const prop = this.createProperty(enums_1.ReferenceKind.ONE_TO_ONE, options);
124
128
  utils_1.Utils.defaultValue(prop, 'owner', !!prop.inversedBy || !prop.mappedBy);
125
129
  utils_1.Utils.defaultValue(prop, 'unique', prop.owner);
126
- if (prop.owner && options.mappedBy) {
127
- utils_1.Utils.renameKey(prop, 'mappedBy', 'inversedBy');
130
+ if (prop.owner) {
131
+ if (options.mappedBy) {
132
+ utils_1.Utils.renameKey(prop, 'mappedBy', 'inversedBy');
133
+ }
134
+ // By default, the foreign key constraint is created on the relation
135
+ utils_1.Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
128
136
  }
129
137
  if (prop.joinColumns && !prop.fieldNames) {
130
138
  prop.fieldNames = prop.joinColumns;
@@ -657,6 +657,7 @@ class MetadataDiscovery {
657
657
  autoincrement: false,
658
658
  updateRule: prop.updateRule,
659
659
  deleteRule: prop.deleteRule,
660
+ createForeignKeyConstraint: prop.createForeignKeyConstraint,
660
661
  };
661
662
  if (selfReferencing && !this.platform.supportsMultipleCascadePaths()) {
662
663
  ret.updateRule ??= 'no action';
@@ -1057,7 +1058,7 @@ class MetadataDiscovery {
1057
1058
  prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
1058
1059
  return;
1059
1060
  }
1060
- if (prop.customType instanceof types_1.ArrayType && Array.isArray(prop.default)) {
1061
+ if (Array.isArray(prop.default) && prop.customType) {
1061
1062
  val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
1062
1063
  }
1063
1064
  prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
@@ -1111,6 +1112,9 @@ class MetadataDiscovery {
1111
1112
  if (prop.kind === enums_1.ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
1112
1113
  prop.customType = new types_1.JsonType();
1113
1114
  }
1115
+ if (prop.kind === enums_1.ReferenceKind.EMBEDDED && !prop.customType && (prop.object || prop.array)) {
1116
+ prop.customType = new types_1.JsonType();
1117
+ }
1114
1118
  if (!prop.customType && prop.array && prop.items) {
1115
1119
  prop.customType = new types_1.EnumArrayType(`${meta.className}.${prop.name}`, prop.items);
1116
1120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.4.17-dev.1",
3
+ "version": "6.4.17-dev.11",
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.17-dev.1",
67
+ "mikro-orm": "6.4.17-dev.11",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }
package/typings.d.ts CHANGED
@@ -384,6 +384,7 @@ export interface EntityProperty<Owner = any, Target = any> {
384
384
  optional?: boolean;
385
385
  ignoreSchemaChanges?: ('type' | 'extra' | 'default')[];
386
386
  deferMode?: DeferMode;
387
+ createForeignKeyConstraint: boolean;
387
388
  foreignKeyName?: string;
388
389
  }
389
390
  export declare class EntityMetadata<T = any> {
@@ -144,7 +144,9 @@ class ChangeSetComputer {
144
144
  if (!target.isDirty() && changeSet.type !== ChangeSet_1.ChangeSetType.CREATE) {
145
145
  return;
146
146
  }
147
- this.collectionUpdates.add(target);
147
+ if (target.isDirty()) {
148
+ this.collectionUpdates.add(target);
149
+ }
148
150
  if (prop.owner && !this.platform.usesPivotTable()) {
149
151
  changeSet.payload[prop.name] = target.getItems(false).map((item) => item.__helper.__identifier ?? item.__helper.getPrimaryKey());
150
152
  }
@@ -102,6 +102,7 @@ export declare class UnitOfWork {
102
102
  private commitDeleteChangeSets;
103
103
  private commitExtraUpdates;
104
104
  private commitCollectionUpdates;
105
+ private filterCollectionUpdates;
105
106
  /**
106
107
  * Orders change sets so FK constrains are maintained, ensures stable order (needed for node < 11)
107
108
  */
@@ -303,6 +303,7 @@ class UnitOfWork {
303
303
  cs.entity.__helper.__processing = true;
304
304
  }
305
305
  await this.eventManager.dispatchEvent(enums_1.EventType.onFlush, { em: this.em, uow: this });
306
+ this.filterCollectionUpdates();
306
307
  // nothing to do, do not start transaction
307
308
  if (this.changeSets.size === 0 && this.collectionUpdates.size === 0 && this.extraUpdates.size === 0) {
308
309
  return void await this.eventManager.dispatchEvent(enums_1.EventType.afterFlush, { em: this.em, uow: this });
@@ -886,23 +887,29 @@ class UnitOfWork {
886
887
  }
887
888
  }
888
889
  async commitCollectionUpdates(ctx) {
889
- const collectionUpdates = [];
890
+ this.filterCollectionUpdates();
891
+ await this.em.getDriver().syncCollections(this.collectionUpdates, { ctx, schema: this.em.schema });
890
892
  for (const coll of this.collectionUpdates) {
893
+ coll.takeSnapshot();
894
+ }
895
+ }
896
+ filterCollectionUpdates() {
897
+ for (const coll of this.collectionUpdates) {
898
+ let skip = true;
891
899
  if (coll.property.owner || coll.getItems(false).filter(item => !item.__helper.__initialized).length > 0) {
892
900
  if (this.platform.usesPivotTable()) {
893
- collectionUpdates.push(coll);
901
+ skip = false;
894
902
  }
895
903
  }
896
904
  else if (coll.property.kind === enums_1.ReferenceKind.ONE_TO_MANY && coll.getSnapshot() === undefined) {
897
- collectionUpdates.push(coll);
905
+ skip = false;
898
906
  }
899
907
  else if (coll.property.kind === enums_1.ReferenceKind.MANY_TO_MANY && !coll.property.owner) {
900
- collectionUpdates.push(coll);
908
+ skip = false;
909
+ }
910
+ if (skip) {
911
+ this.collectionUpdates.delete(coll);
901
912
  }
902
- }
903
- await this.em.getDriver().syncCollections(collectionUpdates, { ctx, schema: this.em.schema });
904
- for (const coll of this.collectionUpdates) {
905
- coll.takeSnapshot();
906
913
  }
907
914
  }
908
915
  /**
@@ -121,7 +121,7 @@ class QueryHelper {
121
121
  value = QueryHelper.processCustomType(prop, value, platform, undefined, true);
122
122
  }
123
123
  const isJsonProperty = prop?.customType instanceof JsonType_1.JsonType && Utils_1.Utils.isPlainObject(value) && !platform.isRaw(value) && Object.keys(value)[0] !== '$eq';
124
- if (isJsonProperty) {
124
+ if (isJsonProperty && prop?.kind !== enums_1.ReferenceKind.EMBEDDED) {
125
125
  return this.processJsonCondition(o, value, [prop.fieldNames[0]], platform, aliased);
126
126
  }
127
127
  if (Array.isArray(value) && !Utils_1.Utils.isOperator(key) && !QueryHelper.isSupportedOperator(key) && !key.includes('?') && options.type !== 'orderBy') {