@mikro-orm/core 7.0.4-dev.8 → 7.0.4

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.
Files changed (206) hide show
  1. package/EntityManager.d.ts +884 -583
  2. package/EntityManager.js +1922 -1895
  3. package/MikroORM.d.ts +103 -74
  4. package/MikroORM.js +178 -179
  5. package/README.md +1 -1
  6. package/cache/CacheAdapter.d.ts +36 -36
  7. package/cache/FileCacheAdapter.d.ts +30 -24
  8. package/cache/FileCacheAdapter.js +80 -78
  9. package/cache/GeneratedCacheAdapter.d.ts +18 -20
  10. package/cache/GeneratedCacheAdapter.js +30 -30
  11. package/cache/MemoryCacheAdapter.d.ts +18 -20
  12. package/cache/MemoryCacheAdapter.js +35 -36
  13. package/cache/NullCacheAdapter.d.ts +16 -16
  14. package/cache/NullCacheAdapter.js +24 -24
  15. package/connections/Connection.d.ts +95 -84
  16. package/connections/Connection.js +165 -168
  17. package/drivers/DatabaseDriver.d.ts +186 -80
  18. package/drivers/DatabaseDriver.js +450 -443
  19. package/drivers/IDatabaseDriver.d.ts +440 -301
  20. package/entity/BaseEntity.d.ts +120 -83
  21. package/entity/BaseEntity.js +43 -43
  22. package/entity/Collection.d.ts +212 -179
  23. package/entity/Collection.js +727 -721
  24. package/entity/EntityAssigner.d.ts +88 -77
  25. package/entity/EntityAssigner.js +231 -230
  26. package/entity/EntityFactory.d.ts +66 -54
  27. package/entity/EntityFactory.js +425 -383
  28. package/entity/EntityHelper.d.ts +34 -22
  29. package/entity/EntityHelper.js +280 -267
  30. package/entity/EntityIdentifier.d.ts +4 -4
  31. package/entity/EntityIdentifier.js +10 -10
  32. package/entity/EntityLoader.d.ts +98 -72
  33. package/entity/EntityLoader.js +753 -723
  34. package/entity/EntityRepository.d.ts +316 -201
  35. package/entity/EntityRepository.js +213 -213
  36. package/entity/PolymorphicRef.d.ts +5 -5
  37. package/entity/PolymorphicRef.js +10 -10
  38. package/entity/Reference.d.ts +126 -82
  39. package/entity/Reference.js +278 -274
  40. package/entity/WrappedEntity.d.ts +115 -72
  41. package/entity/WrappedEntity.js +168 -166
  42. package/entity/defineEntity.d.ts +1315 -636
  43. package/entity/defineEntity.js +527 -518
  44. package/entity/utils.d.ts +13 -3
  45. package/entity/utils.js +71 -73
  46. package/entity/validators.js +43 -43
  47. package/entity/wrap.js +8 -8
  48. package/enums.d.ts +258 -253
  49. package/enums.js +251 -252
  50. package/errors.d.ts +114 -72
  51. package/errors.js +350 -253
  52. package/events/EventManager.d.ts +26 -14
  53. package/events/EventManager.js +79 -77
  54. package/events/EventSubscriber.d.ts +29 -29
  55. package/events/TransactionEventBroadcaster.d.ts +15 -8
  56. package/events/TransactionEventBroadcaster.js +14 -14
  57. package/exceptions.d.ts +23 -40
  58. package/exceptions.js +35 -52
  59. package/hydration/Hydrator.d.ts +42 -17
  60. package/hydration/Hydrator.js +43 -43
  61. package/hydration/ObjectHydrator.d.ts +50 -17
  62. package/hydration/ObjectHydrator.js +481 -416
  63. package/index.d.ts +116 -2
  64. package/index.js +10 -1
  65. package/logging/DefaultLogger.d.ts +34 -32
  66. package/logging/DefaultLogger.js +86 -86
  67. package/logging/Logger.d.ts +41 -41
  68. package/logging/SimpleLogger.d.ts +13 -11
  69. package/logging/SimpleLogger.js +22 -22
  70. package/logging/colors.d.ts +6 -6
  71. package/logging/colors.js +11 -10
  72. package/logging/inspect.js +7 -7
  73. package/metadata/EntitySchema.d.ts +211 -127
  74. package/metadata/EntitySchema.js +397 -398
  75. package/metadata/MetadataDiscovery.d.ts +114 -114
  76. package/metadata/MetadataDiscovery.js +1951 -1863
  77. package/metadata/MetadataProvider.d.ts +24 -21
  78. package/metadata/MetadataProvider.js +82 -84
  79. package/metadata/MetadataStorage.d.ts +38 -32
  80. package/metadata/MetadataStorage.js +118 -118
  81. package/metadata/MetadataValidator.d.ts +39 -39
  82. package/metadata/MetadataValidator.js +381 -338
  83. package/metadata/discover-entities.d.ts +5 -2
  84. package/metadata/discover-entities.js +35 -27
  85. package/metadata/types.d.ts +615 -531
  86. package/naming-strategy/AbstractNamingStrategy.d.ts +54 -39
  87. package/naming-strategy/AbstractNamingStrategy.js +90 -85
  88. package/naming-strategy/EntityCaseNamingStrategy.d.ts +6 -6
  89. package/naming-strategy/EntityCaseNamingStrategy.js +22 -22
  90. package/naming-strategy/MongoNamingStrategy.d.ts +6 -6
  91. package/naming-strategy/MongoNamingStrategy.js +18 -18
  92. package/naming-strategy/NamingStrategy.d.ts +109 -99
  93. package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
  94. package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
  95. package/not-supported.js +7 -4
  96. package/package.json +1 -1
  97. package/platforms/ExceptionConverter.d.ts +1 -1
  98. package/platforms/ExceptionConverter.js +4 -4
  99. package/platforms/Platform.d.ts +310 -299
  100. package/platforms/Platform.js +663 -636
  101. package/serialization/EntitySerializer.d.ts +49 -26
  102. package/serialization/EntitySerializer.js +224 -218
  103. package/serialization/EntityTransformer.d.ts +10 -6
  104. package/serialization/EntityTransformer.js +219 -217
  105. package/serialization/SerializationContext.d.ts +27 -23
  106. package/serialization/SerializationContext.js +105 -105
  107. package/types/ArrayType.d.ts +8 -8
  108. package/types/ArrayType.js +33 -33
  109. package/types/BigIntType.d.ts +17 -10
  110. package/types/BigIntType.js +37 -37
  111. package/types/BlobType.d.ts +3 -3
  112. package/types/BlobType.js +13 -13
  113. package/types/BooleanType.d.ts +4 -4
  114. package/types/BooleanType.js +12 -12
  115. package/types/CharacterType.d.ts +2 -2
  116. package/types/CharacterType.js +6 -6
  117. package/types/DateTimeType.d.ts +5 -5
  118. package/types/DateTimeType.js +15 -15
  119. package/types/DateType.d.ts +5 -5
  120. package/types/DateType.js +15 -15
  121. package/types/DecimalType.d.ts +7 -7
  122. package/types/DecimalType.js +26 -26
  123. package/types/DoubleType.d.ts +3 -3
  124. package/types/DoubleType.js +12 -12
  125. package/types/EnumArrayType.d.ts +5 -5
  126. package/types/EnumArrayType.js +24 -24
  127. package/types/EnumType.d.ts +3 -3
  128. package/types/EnumType.js +11 -11
  129. package/types/FloatType.d.ts +3 -3
  130. package/types/FloatType.js +9 -9
  131. package/types/IntegerType.d.ts +3 -3
  132. package/types/IntegerType.js +9 -9
  133. package/types/IntervalType.d.ts +4 -4
  134. package/types/IntervalType.js +12 -12
  135. package/types/JsonType.d.ts +8 -8
  136. package/types/JsonType.js +32 -32
  137. package/types/MediumIntType.d.ts +1 -1
  138. package/types/MediumIntType.js +3 -3
  139. package/types/SmallIntType.d.ts +3 -3
  140. package/types/SmallIntType.js +9 -9
  141. package/types/StringType.d.ts +4 -4
  142. package/types/StringType.js +12 -12
  143. package/types/TextType.d.ts +3 -3
  144. package/types/TextType.js +9 -9
  145. package/types/TimeType.d.ts +5 -5
  146. package/types/TimeType.js +17 -17
  147. package/types/TinyIntType.d.ts +3 -3
  148. package/types/TinyIntType.js +10 -10
  149. package/types/Type.d.ts +83 -79
  150. package/types/Type.js +82 -82
  151. package/types/Uint8ArrayType.d.ts +4 -4
  152. package/types/Uint8ArrayType.js +21 -21
  153. package/types/UnknownType.d.ts +4 -4
  154. package/types/UnknownType.js +12 -12
  155. package/types/UuidType.d.ts +5 -5
  156. package/types/UuidType.js +19 -19
  157. package/types/index.d.ts +75 -49
  158. package/types/index.js +52 -26
  159. package/typings.d.ts +1250 -737
  160. package/typings.js +244 -231
  161. package/unit-of-work/ChangeSet.d.ts +26 -26
  162. package/unit-of-work/ChangeSet.js +56 -56
  163. package/unit-of-work/ChangeSetComputer.d.ts +12 -12
  164. package/unit-of-work/ChangeSetComputer.js +178 -170
  165. package/unit-of-work/ChangeSetPersister.d.ts +63 -44
  166. package/unit-of-work/ChangeSetPersister.js +442 -421
  167. package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
  168. package/unit-of-work/CommitOrderCalculator.js +89 -88
  169. package/unit-of-work/IdentityMap.d.ts +31 -31
  170. package/unit-of-work/IdentityMap.js +105 -105
  171. package/unit-of-work/UnitOfWork.d.ts +181 -141
  172. package/unit-of-work/UnitOfWork.js +1200 -1183
  173. package/utils/AbstractMigrator.d.ts +111 -91
  174. package/utils/AbstractMigrator.js +275 -275
  175. package/utils/AbstractSchemaGenerator.d.ts +43 -34
  176. package/utils/AbstractSchemaGenerator.js +121 -122
  177. package/utils/AsyncContext.d.ts +3 -3
  178. package/utils/AsyncContext.js +34 -35
  179. package/utils/Configuration.d.ts +852 -808
  180. package/utils/Configuration.js +359 -344
  181. package/utils/Cursor.d.ts +40 -22
  182. package/utils/Cursor.js +135 -127
  183. package/utils/DataloaderUtils.d.ts +58 -43
  184. package/utils/DataloaderUtils.js +203 -198
  185. package/utils/EntityComparator.d.ts +98 -81
  186. package/utils/EntityComparator.js +828 -728
  187. package/utils/NullHighlighter.d.ts +1 -1
  188. package/utils/NullHighlighter.js +3 -3
  189. package/utils/QueryHelper.d.ts +79 -51
  190. package/utils/QueryHelper.js +372 -361
  191. package/utils/RawQueryFragment.d.ts +50 -34
  192. package/utils/RawQueryFragment.js +107 -105
  193. package/utils/RequestContext.d.ts +32 -32
  194. package/utils/RequestContext.js +52 -53
  195. package/utils/TransactionContext.d.ts +16 -16
  196. package/utils/TransactionContext.js +27 -27
  197. package/utils/TransactionManager.d.ts +58 -58
  198. package/utils/TransactionManager.js +199 -197
  199. package/utils/Utils.d.ts +204 -145
  200. package/utils/Utils.js +812 -810
  201. package/utils/clone.js +104 -113
  202. package/utils/env-vars.js +90 -88
  203. package/utils/fs-utils.d.ts +15 -15
  204. package/utils/fs-utils.js +180 -181
  205. package/utils/upsert-utils.d.ts +20 -5
  206. package/utils/upsert-utils.js +114 -116
@@ -3,67 +3,67 @@ import { Utils } from '../utils/Utils.js';
3
3
  import { inspect } from '../logging/inspect.js';
4
4
  /** Represents a pending change (create, update, or delete) for a single entity. */
5
5
  export class ChangeSet {
6
- entity;
7
- type;
8
- payload;
9
- meta;
10
- primaryKey;
11
- serializedPrimaryKey;
12
- constructor(entity, type, payload, meta) {
13
- this.entity = entity;
14
- this.type = type;
15
- this.payload = payload;
16
- this.meta = meta;
17
- this.meta = meta;
18
- this.rootMeta = meta.root;
19
- this.schema = helper(entity).__schema ?? meta.root.schema;
6
+ entity;
7
+ type;
8
+ payload;
9
+ meta;
10
+ primaryKey;
11
+ serializedPrimaryKey;
12
+ constructor(entity, type, payload, meta) {
13
+ this.entity = entity;
14
+ this.type = type;
15
+ this.payload = payload;
16
+ this.meta = meta;
17
+ this.meta = meta;
18
+ this.rootMeta = meta.root;
19
+ this.schema = helper(entity).__schema ?? meta.root.schema;
20
+ }
21
+ /** Returns the primary key of the entity, optionally as an object for composite keys. */
22
+ getPrimaryKey(object = false) {
23
+ if (!this.originalEntity) {
24
+ this.primaryKey ??= helper(this.entity).getPrimaryKey(true);
25
+ } else if (this.meta.compositePK) {
26
+ this.primaryKey = this.meta.primaryKeys.map(pk => this.originalEntity[pk]);
27
+ } else {
28
+ this.primaryKey = this.originalEntity[this.meta.primaryKeys[0]];
20
29
  }
21
- /** Returns the primary key of the entity, optionally as an object for composite keys. */
22
- getPrimaryKey(object = false) {
23
- if (!this.originalEntity) {
24
- this.primaryKey ??= helper(this.entity).getPrimaryKey(true);
25
- }
26
- else if (this.meta.compositePK) {
27
- this.primaryKey = this.meta.primaryKeys.map(pk => this.originalEntity[pk]);
28
- }
29
- else {
30
- this.primaryKey = this.originalEntity[this.meta.primaryKeys[0]];
31
- }
32
- if (!this.meta.compositePK &&
33
- this.meta.getPrimaryProp().targetMeta?.compositePK &&
34
- typeof this.primaryKey === 'object' &&
35
- this.primaryKey !== null) {
36
- this.primaryKey = this.meta.getPrimaryProp().targetMeta.primaryKeys.map(childPK => {
37
- return this.primaryKey[childPK];
38
- });
39
- }
40
- if (object && this.primaryKey != null) {
41
- return Utils.primaryKeyToObject(this.meta, this.primaryKey);
42
- }
43
- return this.primaryKey ?? null;
30
+ if (
31
+ !this.meta.compositePK &&
32
+ this.meta.getPrimaryProp().targetMeta?.compositePK &&
33
+ typeof this.primaryKey === 'object' &&
34
+ this.primaryKey !== null
35
+ ) {
36
+ this.primaryKey = this.meta.getPrimaryProp().targetMeta.primaryKeys.map(childPK => {
37
+ return this.primaryKey[childPK];
38
+ });
44
39
  }
45
- /** Returns the serialized (string) form of the primary key. */
46
- getSerializedPrimaryKey() {
47
- this.serializedPrimaryKey ??= helper(this.entity).getSerializedPrimaryKey();
48
- return this.serializedPrimaryKey;
49
- }
50
- /** @ignore */
51
- [Symbol.for('nodejs.util.inspect.custom')](depth = 2) {
52
- const object = { ...this };
53
- const hidden = ['meta', 'serializedPrimaryKey'];
54
- hidden.forEach(k => delete object[k]);
55
- const ret = inspect(object, { depth });
56
- const name = `${this.constructor.name}<${this.meta.className}>`;
57
- /* v8 ignore next */
58
- return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
40
+ if (object && this.primaryKey != null) {
41
+ return Utils.primaryKeyToObject(this.meta, this.primaryKey);
59
42
  }
43
+ return this.primaryKey ?? null;
44
+ }
45
+ /** Returns the serialized (string) form of the primary key. */
46
+ getSerializedPrimaryKey() {
47
+ this.serializedPrimaryKey ??= helper(this.entity).getSerializedPrimaryKey();
48
+ return this.serializedPrimaryKey;
49
+ }
50
+ /** @ignore */
51
+ [Symbol.for('nodejs.util.inspect.custom')](depth = 2) {
52
+ const object = { ...this };
53
+ const hidden = ['meta', 'serializedPrimaryKey'];
54
+ hidden.forEach(k => delete object[k]);
55
+ const ret = inspect(object, { depth });
56
+ const name = `${this.constructor.name}<${this.meta.className}>`;
57
+ /* v8 ignore next */
58
+ return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
59
+ }
60
60
  }
61
61
  /** Enumeration of change set operation types. */
62
62
  export var ChangeSetType;
63
63
  (function (ChangeSetType) {
64
- ChangeSetType["CREATE"] = "create";
65
- ChangeSetType["UPDATE"] = "update";
66
- ChangeSetType["DELETE"] = "delete";
67
- ChangeSetType["UPDATE_EARLY"] = "update_early";
68
- ChangeSetType["DELETE_EARLY"] = "delete_early";
64
+ ChangeSetType['CREATE'] = 'create';
65
+ ChangeSetType['UPDATE'] = 'update';
66
+ ChangeSetType['DELETE'] = 'delete';
67
+ ChangeSetType['UPDATE_EARLY'] = 'update_early';
68
+ ChangeSetType['DELETE_EARLY'] = 'delete_early';
69
69
  })(ChangeSetType || (ChangeSetType = {}));
@@ -4,16 +4,16 @@ import { type Collection } from '../entity/Collection.js';
4
4
  import type { EntityManager } from '../EntityManager.js';
5
5
  /** @internal Computes change sets by comparing entity state against original snapshots. */
6
6
  export declare class ChangeSetComputer {
7
- #private;
8
- constructor(em: EntityManager, collectionUpdates: Set<Collection<AnyEntity>>);
9
- /** Computes a change set for the given entity by diffing against its original state. */
10
- computeChangeSet<T extends object>(entity: T): ChangeSet<T> | null;
11
- /**
12
- * Traverses entity graph and executes `onCreate` and `onUpdate` methods, assigning the values to given properties.
13
- */
14
- private processPropertyInitializers;
15
- private computePayload;
16
- private processProperty;
17
- private processToOne;
18
- private processToMany;
7
+ #private;
8
+ constructor(em: EntityManager, collectionUpdates: Set<Collection<AnyEntity>>);
9
+ /** Computes a change set for the given entity by diffing against its original state. */
10
+ computeChangeSet<T extends object>(entity: T): ChangeSet<T> | null;
11
+ /**
12
+ * Traverses entity graph and executes `onCreate` and `onUpdate` methods, assigning the values to given properties.
13
+ */
14
+ private processPropertyInitializers;
15
+ private computePayload;
16
+ private processProperty;
17
+ private processToOne;
18
+ private processToMany;
19
19
  }
@@ -9,179 +9,187 @@ import { ReferenceKind } from '../enums.js';
9
9
  import { isRaw } from '../utils/RawQueryFragment.js';
10
10
  /** @internal Computes change sets by comparing entity state against original snapshots. */
11
11
  export class ChangeSetComputer {
12
- #comparator;
13
- #metadata;
14
- #platform;
15
- #config;
16
- #em;
17
- #collectionUpdates;
18
- constructor(em, collectionUpdates) {
19
- this.#em = em;
20
- this.#collectionUpdates = collectionUpdates;
21
- this.#config = this.#em.config;
22
- this.#metadata = this.#em.getMetadata();
23
- this.#platform = this.#em.getPlatform();
24
- this.#comparator = this.#config.getComparator(this.#metadata);
25
- }
26
- /** Computes a change set for the given entity by diffing against its original state. */
27
- computeChangeSet(entity) {
28
- const meta = this.#metadata.get(entity.constructor);
29
- if (meta.readonly) {
30
- return null;
31
- }
32
- const wrapped = helper(entity);
33
- const type = wrapped.__originalEntityData ? ChangeSetType.UPDATE : ChangeSetType.CREATE;
34
- const map = new Map();
35
- // Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
36
- // to the `map` as we want to apply those only if something else changed.
37
- if (type === ChangeSetType.CREATE) {
38
- // run update hooks only after we know there are other changes
39
- for (const prop of meta.hydrateProps) {
40
- this.processPropertyInitializers(entity, prop, type, map);
41
- }
42
- }
43
- if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
44
- const data = this.#comparator.prepareEntity(entity);
45
- if (Utils.equals(data, wrapped.__originalEntityData)) {
46
- return null;
47
- }
48
- }
49
- const changeSet = new ChangeSet(entity, type, this.computePayload(entity), meta);
50
- changeSet.originalEntity = wrapped.__originalEntityData;
51
- for (const prop of meta.relations.filter(prop => prop.persist !== false || prop.userDefined === false)) {
52
- this.processProperty(changeSet, prop);
53
- }
54
- if (changeSet.type === ChangeSetType.UPDATE && !Utils.hasObjectKeys(changeSet.payload)) {
55
- return null;
56
- }
57
- validateEntity(changeSet.entity, meta);
58
- // Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
59
- // to the `map` as we want to apply those only if something else changed.
60
- if (type === ChangeSetType.UPDATE) {
61
- for (const prop of meta.hydrateProps) {
62
- this.processPropertyInitializers(entity, prop, type, map);
63
- }
64
- }
65
- if (map.size > 0) {
66
- for (const [entity, pairs] of map) {
67
- for (const [prop, value] of pairs) {
68
- entity[prop] = value;
69
- }
70
- }
71
- // Recompute the changeset, we need to merge this as here we ignore relations.
72
- const diff = this.computePayload(entity, true);
73
- Utils.merge(changeSet.payload, diff);
74
- }
75
- return changeSet;
76
- }
77
- /**
78
- * Traverses entity graph and executes `onCreate` and `onUpdate` methods, assigning the values to given properties.
79
- */
80
- processPropertyInitializers(entity, prop, type, map, nested) {
81
- if (prop.onCreate &&
82
- type === ChangeSetType.CREATE &&
83
- (entity[prop.name] == null ||
84
- (Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
85
- entity[prop.name] = prop.onCreate(entity, this.#em);
86
- }
87
- else if (prop.default != null &&
88
- !isRaw(prop.default) &&
89
- ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
90
- type === ChangeSetType.CREATE &&
91
- entity[prop.name] === undefined) {
92
- entity[prop.name] = prop.default;
93
- }
94
- if (prop.onUpdate && type === ChangeSetType.UPDATE) {
95
- const pairs = map.get(entity) ?? [];
96
- pairs.push([prop.name, prop.onUpdate(entity, this.#em)]);
97
- map.set(entity, pairs);
98
- }
99
- if (prop.kind === ReferenceKind.EMBEDDED && entity[prop.name]) {
100
- const items = prop.array ? entity[prop.name] : [entity[prop.name]];
101
- for (const item of items) {
102
- for (const embeddedProp of prop.targetMeta.hydrateProps) {
103
- this.processPropertyInitializers(item, embeddedProp, type, map, nested || prop.object);
104
- }
105
- }
106
- }
12
+ #comparator;
13
+ #metadata;
14
+ #platform;
15
+ #config;
16
+ #em;
17
+ #collectionUpdates;
18
+ constructor(em, collectionUpdates) {
19
+ this.#em = em;
20
+ this.#collectionUpdates = collectionUpdates;
21
+ this.#config = this.#em.config;
22
+ this.#metadata = this.#em.getMetadata();
23
+ this.#platform = this.#em.getPlatform();
24
+ this.#comparator = this.#config.getComparator(this.#metadata);
25
+ }
26
+ /** Computes a change set for the given entity by diffing against its original state. */
27
+ computeChangeSet(entity) {
28
+ const meta = this.#metadata.get(entity.constructor);
29
+ if (meta.readonly) {
30
+ return null;
107
31
  }
108
- computePayload(entity, ignoreUndefined = false) {
109
- const data = this.#comparator.prepareEntity(entity);
110
- const wrapped = helper(entity);
111
- const entityName = wrapped.__meta.class;
112
- const originalEntityData = wrapped.__originalEntityData;
113
- if (!wrapped.__initialized) {
114
- for (const prop of wrapped.__meta.primaryKeys) {
115
- delete data[prop];
116
- }
117
- return data;
118
- }
119
- if (originalEntityData) {
120
- const comparator = this.#comparator.getEntityComparator(entityName);
121
- const diff = comparator(originalEntityData, data);
122
- if (ignoreUndefined) {
123
- Utils.keys(diff)
124
- .filter(k => diff[k] === undefined)
125
- .forEach(k => delete diff[k]);
126
- }
127
- return diff;
128
- }
129
- return data;
32
+ const wrapped = helper(entity);
33
+ const type = wrapped.__originalEntityData ? ChangeSetType.UPDATE : ChangeSetType.CREATE;
34
+ const map = new Map();
35
+ // Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
36
+ // to the `map` as we want to apply those only if something else changed.
37
+ if (type === ChangeSetType.CREATE) {
38
+ // run update hooks only after we know there are other changes
39
+ for (const prop of meta.hydrateProps) {
40
+ this.processPropertyInitializers(entity, prop, type, map);
41
+ }
130
42
  }
131
- processProperty(changeSet, prop, target) {
132
- if (!target) {
133
- const targets = Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
134
- targets.forEach(([t]) => this.processProperty(changeSet, prop, t));
135
- return;
136
- }
137
- if (Utils.isCollection(target)) {
138
- // m:n or 1:m
139
- this.processToMany(prop, changeSet);
140
- }
141
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
142
- this.processToOne(prop, changeSet);
143
- }
43
+ if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
44
+ const data = this.#comparator.prepareEntity(entity);
45
+ if (Utils.equals(data, wrapped.__originalEntityData)) {
46
+ return null;
47
+ }
144
48
  }
145
- processToOne(prop, changeSet) {
146
- const isToOneOwner = prop.kind === ReferenceKind.MANY_TO_ONE || (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner);
147
- if (!isToOneOwner || prop.mapToPk) {
148
- return;
149
- }
150
- const targets = Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
151
- targets.forEach(([rawTarget, idx]) => {
152
- const target = Reference.unwrapReference(rawTarget);
153
- const needsProcessing = target != null && (prop.targetKey != null || !target.__helper.hasPrimaryKey());
154
- if (needsProcessing) {
155
- let value = prop.targetKey ? target[prop.targetKey] : target.__helper.__identifier;
156
- /* v8 ignore next */
157
- if (prop.targetKey && prop.targetMeta) {
158
- const targetProp = prop.targetMeta.properties[prop.targetKey];
159
- if (targetProp?.customType) {
160
- value = targetProp.customType.convertToDatabaseValue(value, this.#platform, { mode: 'serialization' });
161
- }
162
- }
163
- if (prop.polymorphic) {
164
- const discriminator = QueryHelper.findDiscriminatorValue(prop.discriminatorMap, target.constructor);
165
- Utils.setPayloadProperty(changeSet.payload, changeSet.meta, prop, new PolymorphicRef(discriminator, value), idx);
166
- }
167
- else {
168
- Utils.setPayloadProperty(changeSet.payload, changeSet.meta, prop, value, idx);
169
- }
170
- }
171
- });
172
- }
173
- processToMany(prop, changeSet) {
174
- const target = changeSet.entity[prop.name];
175
- if (!target.isDirty() && changeSet.type !== ChangeSetType.CREATE) {
176
- return;
177
- }
178
- if (target.isDirty()) {
179
- this.#collectionUpdates.add(target);
180
- }
181
- if (prop.owner && !this.#platform.usesPivotTable()) {
182
- changeSet.payload[prop.name] = target.getItems(false).map((item) => {
183
- return item.__helper.__identifier ?? item.__helper.getPrimaryKey();
184
- });
49
+ const changeSet = new ChangeSet(entity, type, this.computePayload(entity), meta);
50
+ changeSet.originalEntity = wrapped.__originalEntityData;
51
+ for (const prop of meta.relations.filter(prop => prop.persist !== false || prop.userDefined === false)) {
52
+ this.processProperty(changeSet, prop);
53
+ }
54
+ if (changeSet.type === ChangeSetType.UPDATE && !Utils.hasObjectKeys(changeSet.payload)) {
55
+ return null;
56
+ }
57
+ validateEntity(changeSet.entity, meta);
58
+ // Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
59
+ // to the `map` as we want to apply those only if something else changed.
60
+ if (type === ChangeSetType.UPDATE) {
61
+ for (const prop of meta.hydrateProps) {
62
+ this.processPropertyInitializers(entity, prop, type, map);
63
+ }
64
+ }
65
+ if (map.size > 0) {
66
+ for (const [entity, pairs] of map) {
67
+ for (const [prop, value] of pairs) {
68
+ entity[prop] = value;
69
+ }
70
+ }
71
+ // Recompute the changeset, we need to merge this as here we ignore relations.
72
+ const diff = this.computePayload(entity, true);
73
+ Utils.merge(changeSet.payload, diff);
74
+ }
75
+ return changeSet;
76
+ }
77
+ /**
78
+ * Traverses entity graph and executes `onCreate` and `onUpdate` methods, assigning the values to given properties.
79
+ */
80
+ processPropertyInitializers(entity, prop, type, map, nested) {
81
+ if (
82
+ prop.onCreate &&
83
+ type === ChangeSetType.CREATE &&
84
+ (entity[prop.name] == null || (Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))
85
+ ) {
86
+ entity[prop.name] = prop.onCreate(entity, this.#em);
87
+ } else if (
88
+ prop.default != null &&
89
+ !isRaw(prop.default) &&
90
+ ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
91
+ type === ChangeSetType.CREATE &&
92
+ entity[prop.name] === undefined
93
+ ) {
94
+ entity[prop.name] = prop.default;
95
+ }
96
+ if (prop.onUpdate && type === ChangeSetType.UPDATE) {
97
+ const pairs = map.get(entity) ?? [];
98
+ pairs.push([prop.name, prop.onUpdate(entity, this.#em)]);
99
+ map.set(entity, pairs);
100
+ }
101
+ if (prop.kind === ReferenceKind.EMBEDDED && entity[prop.name]) {
102
+ const items = prop.array ? entity[prop.name] : [entity[prop.name]];
103
+ for (const item of items) {
104
+ for (const embeddedProp of prop.targetMeta.hydrateProps) {
105
+ this.processPropertyInitializers(item, embeddedProp, type, map, nested || prop.object);
185
106
  }
107
+ }
108
+ }
109
+ }
110
+ computePayload(entity, ignoreUndefined = false) {
111
+ const data = this.#comparator.prepareEntity(entity);
112
+ const wrapped = helper(entity);
113
+ const entityName = wrapped.__meta.class;
114
+ const originalEntityData = wrapped.__originalEntityData;
115
+ if (!wrapped.__initialized) {
116
+ for (const prop of wrapped.__meta.primaryKeys) {
117
+ delete data[prop];
118
+ }
119
+ return data;
120
+ }
121
+ if (originalEntityData) {
122
+ const comparator = this.#comparator.getEntityComparator(entityName);
123
+ const diff = comparator(originalEntityData, data);
124
+ if (ignoreUndefined) {
125
+ Utils.keys(diff)
126
+ .filter(k => diff[k] === undefined)
127
+ .forEach(k => delete diff[k]);
128
+ }
129
+ return diff;
130
+ }
131
+ return data;
132
+ }
133
+ processProperty(changeSet, prop, target) {
134
+ if (!target) {
135
+ const targets = Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
136
+ targets.forEach(([t]) => this.processProperty(changeSet, prop, t));
137
+ return;
138
+ }
139
+ if (Utils.isCollection(target)) {
140
+ // m:n or 1:m
141
+ this.processToMany(prop, changeSet);
142
+ }
143
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
144
+ this.processToOne(prop, changeSet);
145
+ }
146
+ }
147
+ processToOne(prop, changeSet) {
148
+ const isToOneOwner =
149
+ prop.kind === ReferenceKind.MANY_TO_ONE || (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner);
150
+ if (!isToOneOwner || prop.mapToPk) {
151
+ return;
152
+ }
153
+ const targets = Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
154
+ targets.forEach(([rawTarget, idx]) => {
155
+ const target = Reference.unwrapReference(rawTarget);
156
+ const needsProcessing = target != null && (prop.targetKey != null || !target.__helper.hasPrimaryKey());
157
+ if (needsProcessing) {
158
+ let value = prop.targetKey ? target[prop.targetKey] : target.__helper.__identifier;
159
+ /* v8 ignore next */
160
+ if (prop.targetKey && prop.targetMeta) {
161
+ const targetProp = prop.targetMeta.properties[prop.targetKey];
162
+ if (targetProp?.customType) {
163
+ value = targetProp.customType.convertToDatabaseValue(value, this.#platform, { mode: 'serialization' });
164
+ }
165
+ }
166
+ if (prop.polymorphic) {
167
+ const discriminator = QueryHelper.findDiscriminatorValue(prop.discriminatorMap, target.constructor);
168
+ Utils.setPayloadProperty(
169
+ changeSet.payload,
170
+ changeSet.meta,
171
+ prop,
172
+ new PolymorphicRef(discriminator, value),
173
+ idx,
174
+ );
175
+ } else {
176
+ Utils.setPayloadProperty(changeSet.payload, changeSet.meta, prop, value, idx);
177
+ }
178
+ }
179
+ });
180
+ }
181
+ processToMany(prop, changeSet) {
182
+ const target = changeSet.entity[prop.name];
183
+ if (!target.isDirty() && changeSet.type !== ChangeSetType.CREATE) {
184
+ return;
185
+ }
186
+ if (target.isDirty()) {
187
+ this.#collectionUpdates.add(target);
188
+ }
189
+ if (prop.owner && !this.#platform.usesPivotTable()) {
190
+ changeSet.payload[prop.name] = target.getItems(false).map(item => {
191
+ return item.__helper.__identifier ?? item.__helper.getPrimaryKey();
192
+ });
186
193
  }
194
+ }
187
195
  }
@@ -4,48 +4,67 @@ import type { DriverMethodOptions } from '../drivers/IDatabaseDriver.js';
4
4
  import type { EntityManager } from '../EntityManager.js';
5
5
  /** @internal Executes change sets against the database, handling inserts, updates, and deletes. */
6
6
  export declare class ChangeSetPersister {
7
- #private;
8
- constructor(em: EntityManager);
9
- /** Executes all pending INSERT change sets, using batch inserts when possible. */
10
- executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
11
- /** Executes all pending UPDATE change sets, using batch updates when possible. */
12
- executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
13
- /** Executes all pending DELETE change sets in batches. */
14
- executeDeletes<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
15
- private runForEachSchema;
16
- private validateRequired;
17
- private processProperties;
18
- private persistNewEntity;
19
- private persistNewEntities;
20
- private prepareOptions;
21
- private persistNewEntitiesBatch;
22
- private persistManagedEntity;
23
- private persistManagedEntities;
24
- private checkConcurrencyKeys;
25
- private persistManagedEntitiesBatch;
26
- private mapPrimaryKey;
27
- /**
28
- * Sets populate flag to new entities so they are serialized like if they were loaded from the db
29
- */
30
- private markAsPopulated;
31
- private updateEntity;
32
- private checkOptimisticLocks;
33
- private checkOptimisticLock;
34
- /**
35
- * This method also handles reloading of database default values for inserts and raw property updates,
36
- * so we use a single query in case of both versioning and default values is used.
37
- */
38
- private reloadVersionValues;
39
- /**
40
- * For TPT child tables, resolve EntityIdentifier values in PK fields.
41
- * The parent table insert assigns the actual PK value, which the child table references.
42
- */
43
- private resolveTPTIdentifiers;
44
- private processProperty;
45
- /**
46
- * Maps values returned via `returning` statement (postgres) or the inserted id (other sql drivers).
47
- * No need to handle composite keys here as they need to be set upfront.
48
- * We do need to map to the change set payload too, as it will be used in the originalEntityData for new entities.
49
- */
50
- mapReturnedValues<T extends object>(entity: T | null | undefined, payload: EntityDictionary<T>, row: Dictionary | undefined, meta: EntityMetadata<T>, upsert?: boolean): void;
7
+ #private;
8
+ constructor(em: EntityManager);
9
+ /** Executes all pending INSERT change sets, using batch inserts when possible. */
10
+ executeInserts<T extends object>(
11
+ changeSets: ChangeSet<T>[],
12
+ options?: DriverMethodOptions,
13
+ withSchema?: boolean,
14
+ ): Promise<void>;
15
+ /** Executes all pending UPDATE change sets, using batch updates when possible. */
16
+ executeUpdates<T extends object>(
17
+ changeSets: ChangeSet<T>[],
18
+ batched: boolean,
19
+ options?: DriverMethodOptions,
20
+ withSchema?: boolean,
21
+ ): Promise<void>;
22
+ /** Executes all pending DELETE change sets in batches. */
23
+ executeDeletes<T extends object>(
24
+ changeSets: ChangeSet<T>[],
25
+ options?: DriverMethodOptions,
26
+ withSchema?: boolean,
27
+ ): Promise<void>;
28
+ private runForEachSchema;
29
+ private validateRequired;
30
+ private processProperties;
31
+ private persistNewEntity;
32
+ private persistNewEntities;
33
+ private prepareOptions;
34
+ private persistNewEntitiesBatch;
35
+ private persistManagedEntity;
36
+ private persistManagedEntities;
37
+ private checkConcurrencyKeys;
38
+ private persistManagedEntitiesBatch;
39
+ private mapPrimaryKey;
40
+ /**
41
+ * Sets populate flag to new entities so they are serialized like if they were loaded from the db
42
+ */
43
+ private markAsPopulated;
44
+ private updateEntity;
45
+ private checkOptimisticLocks;
46
+ private checkOptimisticLock;
47
+ /**
48
+ * This method also handles reloading of database default values for inserts and raw property updates,
49
+ * so we use a single query in case of both versioning and default values is used.
50
+ */
51
+ private reloadVersionValues;
52
+ /**
53
+ * For TPT child tables, resolve EntityIdentifier values in PK fields.
54
+ * The parent table insert assigns the actual PK value, which the child table references.
55
+ */
56
+ private resolveTPTIdentifiers;
57
+ private processProperty;
58
+ /**
59
+ * Maps values returned via `returning` statement (postgres) or the inserted id (other sql drivers).
60
+ * No need to handle composite keys here as they need to be set upfront.
61
+ * We do need to map to the change set payload too, as it will be used in the originalEntityData for new entities.
62
+ */
63
+ mapReturnedValues<T extends object>(
64
+ entity: T | null | undefined,
65
+ payload: EntityDictionary<T>,
66
+ row: Dictionary | undefined,
67
+ meta: EntityMetadata<T>,
68
+ upsert?: boolean,
69
+ ): void;
51
70
  }