@mikro-orm/core 7.0.0-dev.1 → 7.0.0-dev.100

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 (281) hide show
  1. package/EntityManager.d.ts +96 -58
  2. package/EntityManager.js +465 -395
  3. package/MikroORM.d.ts +45 -35
  4. package/MikroORM.js +109 -160
  5. package/README.md +3 -2
  6. package/cache/CacheAdapter.js +1 -2
  7. package/cache/FileCacheAdapter.d.ts +2 -2
  8. package/cache/FileCacheAdapter.js +20 -27
  9. package/cache/GeneratedCacheAdapter.d.ts +2 -3
  10. package/cache/GeneratedCacheAdapter.js +1 -7
  11. package/cache/MemoryCacheAdapter.d.ts +1 -1
  12. package/cache/MemoryCacheAdapter.js +1 -5
  13. package/cache/NullCacheAdapter.d.ts +1 -1
  14. package/cache/NullCacheAdapter.js +1 -5
  15. package/cache/index.d.ts +4 -5
  16. package/cache/index.js +4 -21
  17. package/connections/Connection.d.ts +22 -14
  18. package/connections/Connection.js +27 -23
  19. package/connections/index.d.ts +1 -1
  20. package/connections/index.js +1 -17
  21. package/drivers/DatabaseDriver.d.ts +25 -15
  22. package/drivers/DatabaseDriver.js +77 -64
  23. package/drivers/IDatabaseDriver.d.ts +40 -16
  24. package/drivers/IDatabaseDriver.js +1 -4
  25. package/drivers/index.d.ts +2 -2
  26. package/drivers/index.js +2 -18
  27. package/entity/BaseEntity.d.ts +6 -7
  28. package/entity/BaseEntity.js +16 -23
  29. package/entity/Collection.d.ts +98 -34
  30. package/entity/Collection.js +466 -131
  31. package/entity/EntityAssigner.d.ts +3 -3
  32. package/entity/EntityAssigner.js +67 -64
  33. package/entity/EntityFactory.d.ts +10 -3
  34. package/entity/EntityFactory.js +112 -91
  35. package/entity/EntityHelper.d.ts +2 -2
  36. package/entity/EntityHelper.js +66 -53
  37. package/entity/EntityIdentifier.d.ts +1 -1
  38. package/entity/EntityIdentifier.js +1 -5
  39. package/entity/EntityLoader.d.ts +8 -7
  40. package/entity/EntityLoader.js +161 -128
  41. package/entity/EntityRepository.d.ts +8 -8
  42. package/entity/EntityRepository.js +7 -11
  43. package/entity/Reference.d.ts +10 -13
  44. package/entity/Reference.js +64 -46
  45. package/entity/WrappedEntity.d.ts +12 -17
  46. package/entity/WrappedEntity.js +22 -31
  47. package/entity/defineEntity.d.ts +568 -0
  48. package/entity/defineEntity.js +529 -0
  49. package/entity/index.d.ts +14 -13
  50. package/entity/index.js +14 -29
  51. package/entity/utils.d.ts +8 -1
  52. package/entity/utils.js +22 -13
  53. package/entity/validators.d.ts +11 -0
  54. package/entity/validators.js +65 -0
  55. package/entity/wrap.d.ts +1 -1
  56. package/entity/wrap.js +2 -6
  57. package/enums.d.ts +24 -9
  58. package/enums.js +50 -41
  59. package/errors.d.ts +11 -3
  60. package/errors.js +42 -32
  61. package/events/EventManager.d.ts +5 -4
  62. package/events/EventManager.js +26 -22
  63. package/events/EventSubscriber.d.ts +8 -5
  64. package/events/EventSubscriber.js +1 -2
  65. package/events/TransactionEventBroadcaster.d.ts +3 -3
  66. package/events/TransactionEventBroadcaster.js +1 -5
  67. package/events/index.d.ts +3 -3
  68. package/events/index.js +3 -19
  69. package/exceptions.js +18 -39
  70. package/hydration/Hydrator.d.ts +5 -5
  71. package/hydration/Hydrator.js +2 -6
  72. package/hydration/ObjectHydrator.d.ts +7 -7
  73. package/hydration/ObjectHydrator.js +58 -50
  74. package/hydration/index.d.ts +2 -2
  75. package/hydration/index.js +2 -18
  76. package/index.d.ts +21 -21
  77. package/index.js +20 -46
  78. package/logging/DefaultLogger.d.ts +2 -2
  79. package/logging/DefaultLogger.js +10 -13
  80. package/logging/Logger.d.ts +1 -1
  81. package/logging/Logger.js +1 -2
  82. package/logging/SimpleLogger.d.ts +3 -3
  83. package/logging/SimpleLogger.js +2 -6
  84. package/logging/colors.js +1 -5
  85. package/logging/index.d.ts +5 -4
  86. package/logging/index.js +5 -20
  87. package/logging/inspect.d.ts +2 -0
  88. package/logging/inspect.js +16 -0
  89. package/metadata/EntitySchema.d.ts +14 -10
  90. package/metadata/EntitySchema.js +78 -64
  91. package/metadata/MetadataDiscovery.d.ts +11 -14
  92. package/metadata/MetadataDiscovery.js +278 -317
  93. package/metadata/MetadataProvider.d.ts +13 -4
  94. package/metadata/MetadataProvider.js +47 -8
  95. package/metadata/MetadataStorage.d.ts +2 -7
  96. package/metadata/MetadataStorage.js +19 -35
  97. package/metadata/MetadataValidator.d.ts +3 -10
  98. package/metadata/MetadataValidator.js +51 -64
  99. package/metadata/discover-entities.d.ts +5 -0
  100. package/metadata/discover-entities.js +40 -0
  101. package/metadata/index.d.ts +6 -6
  102. package/metadata/index.js +6 -22
  103. package/metadata/types.d.ts +480 -0
  104. package/metadata/types.js +1 -0
  105. package/naming-strategy/AbstractNamingStrategy.d.ts +7 -3
  106. package/naming-strategy/AbstractNamingStrategy.js +11 -9
  107. package/naming-strategy/EntityCaseNamingStrategy.d.ts +1 -1
  108. package/naming-strategy/EntityCaseNamingStrategy.js +2 -6
  109. package/naming-strategy/MongoNamingStrategy.d.ts +1 -1
  110. package/naming-strategy/MongoNamingStrategy.js +2 -6
  111. package/naming-strategy/NamingStrategy.d.ts +12 -2
  112. package/naming-strategy/NamingStrategy.js +1 -2
  113. package/naming-strategy/UnderscoreNamingStrategy.d.ts +1 -1
  114. package/naming-strategy/UnderscoreNamingStrategy.js +2 -6
  115. package/naming-strategy/index.d.ts +5 -5
  116. package/naming-strategy/index.js +5 -21
  117. package/not-supported.d.ts +2 -0
  118. package/not-supported.js +4 -0
  119. package/package.json +19 -20
  120. package/platforms/ExceptionConverter.d.ts +2 -2
  121. package/platforms/ExceptionConverter.js +4 -8
  122. package/platforms/Platform.d.ts +15 -22
  123. package/platforms/Platform.js +58 -88
  124. package/platforms/index.d.ts +2 -2
  125. package/platforms/index.js +2 -18
  126. package/serialization/EntitySerializer.d.ts +4 -2
  127. package/serialization/EntitySerializer.js +64 -51
  128. package/serialization/EntityTransformer.d.ts +1 -1
  129. package/serialization/EntityTransformer.js +48 -42
  130. package/serialization/SerializationContext.d.ts +2 -2
  131. package/serialization/SerializationContext.js +24 -25
  132. package/serialization/index.d.ts +3 -3
  133. package/serialization/index.js +3 -19
  134. package/types/ArrayType.d.ts +3 -3
  135. package/types/ArrayType.js +6 -11
  136. package/types/BigIntType.d.ts +12 -9
  137. package/types/BigIntType.js +6 -6
  138. package/types/BlobType.d.ts +3 -4
  139. package/types/BlobType.js +2 -11
  140. package/types/BooleanType.d.ts +5 -4
  141. package/types/BooleanType.js +5 -6
  142. package/types/CharacterType.d.ts +3 -3
  143. package/types/CharacterType.js +2 -6
  144. package/types/DateTimeType.d.ts +3 -3
  145. package/types/DateTimeType.js +2 -6
  146. package/types/DateType.d.ts +3 -3
  147. package/types/DateType.js +2 -6
  148. package/types/DecimalType.d.ts +9 -7
  149. package/types/DecimalType.js +5 -8
  150. package/types/DoubleType.d.ts +3 -3
  151. package/types/DoubleType.js +4 -7
  152. package/types/EnumArrayType.d.ts +4 -4
  153. package/types/EnumArrayType.js +4 -10
  154. package/types/EnumType.d.ts +3 -3
  155. package/types/EnumType.js +2 -6
  156. package/types/FloatType.d.ts +3 -3
  157. package/types/FloatType.js +2 -6
  158. package/types/IntegerType.d.ts +3 -3
  159. package/types/IntegerType.js +2 -6
  160. package/types/IntervalType.d.ts +3 -3
  161. package/types/IntervalType.js +2 -6
  162. package/types/JsonType.d.ts +4 -4
  163. package/types/JsonType.js +9 -8
  164. package/types/MediumIntType.d.ts +3 -3
  165. package/types/MediumIntType.js +2 -6
  166. package/types/SmallIntType.d.ts +3 -3
  167. package/types/SmallIntType.js +2 -6
  168. package/types/StringType.d.ts +3 -3
  169. package/types/StringType.js +2 -6
  170. package/types/TextType.d.ts +3 -3
  171. package/types/TextType.js +2 -6
  172. package/types/TimeType.d.ts +3 -3
  173. package/types/TimeType.js +4 -8
  174. package/types/TinyIntType.d.ts +3 -3
  175. package/types/TinyIntType.js +3 -6
  176. package/types/Type.d.ts +4 -6
  177. package/types/Type.js +6 -10
  178. package/types/Uint8ArrayType.d.ts +3 -4
  179. package/types/Uint8ArrayType.js +3 -12
  180. package/types/UnknownType.d.ts +3 -3
  181. package/types/UnknownType.js +2 -6
  182. package/types/UuidType.d.ts +3 -3
  183. package/types/UuidType.js +2 -6
  184. package/types/index.d.ts +25 -25
  185. package/types/index.js +52 -79
  186. package/typings.d.ts +134 -93
  187. package/typings.js +67 -65
  188. package/unit-of-work/ChangeSet.d.ts +1 -4
  189. package/unit-of-work/ChangeSet.js +13 -17
  190. package/unit-of-work/ChangeSetComputer.d.ts +8 -9
  191. package/unit-of-work/ChangeSetComputer.js +36 -38
  192. package/unit-of-work/ChangeSetPersister.d.ts +11 -9
  193. package/unit-of-work/ChangeSetPersister.js +100 -65
  194. package/unit-of-work/CommitOrderCalculator.d.ts +1 -1
  195. package/unit-of-work/CommitOrderCalculator.js +6 -10
  196. package/unit-of-work/IdentityMap.d.ts +1 -1
  197. package/unit-of-work/IdentityMap.js +1 -5
  198. package/unit-of-work/UnitOfWork.d.ts +16 -8
  199. package/unit-of-work/UnitOfWork.js +266 -209
  200. package/unit-of-work/index.d.ts +6 -6
  201. package/unit-of-work/index.js +6 -22
  202. package/utils/AbstractSchemaGenerator.d.ts +11 -11
  203. package/utils/AbstractSchemaGenerator.js +21 -20
  204. package/utils/Configuration.d.ts +774 -224
  205. package/utils/Configuration.js +166 -216
  206. package/utils/ConfigurationLoader.d.ts +1 -53
  207. package/utils/ConfigurationLoader.js +1 -367
  208. package/utils/Cursor.d.ts +6 -9
  209. package/utils/Cursor.js +25 -25
  210. package/utils/DataloaderUtils.d.ts +18 -8
  211. package/utils/DataloaderUtils.js +63 -21
  212. package/utils/EntityComparator.d.ts +9 -5
  213. package/utils/EntityComparator.js +155 -108
  214. package/utils/NullHighlighter.d.ts +1 -1
  215. package/utils/NullHighlighter.js +1 -5
  216. package/utils/QueryHelper.d.ts +12 -4
  217. package/utils/QueryHelper.js +110 -53
  218. package/utils/RawQueryFragment.d.ts +37 -14
  219. package/utils/RawQueryFragment.js +50 -33
  220. package/utils/RequestContext.d.ts +2 -2
  221. package/utils/RequestContext.js +3 -7
  222. package/utils/TransactionContext.d.ts +1 -1
  223. package/utils/TransactionContext.js +4 -8
  224. package/utils/TransactionManager.d.ts +65 -0
  225. package/utils/TransactionManager.js +223 -0
  226. package/utils/Utils.d.ts +16 -100
  227. package/utils/Utils.js +114 -332
  228. package/utils/clone.js +7 -11
  229. package/utils/env-vars.d.ts +3 -0
  230. package/utils/env-vars.js +87 -0
  231. package/utils/fs-utils.d.ts +12 -0
  232. package/utils/fs-utils.js +97 -0
  233. package/utils/index.d.ts +14 -13
  234. package/utils/index.js +14 -29
  235. package/utils/upsert-utils.d.ts +8 -3
  236. package/utils/upsert-utils.js +57 -10
  237. package/decorators/Check.d.ts +0 -3
  238. package/decorators/Check.js +0 -16
  239. package/decorators/CreateRequestContext.d.ts +0 -3
  240. package/decorators/CreateRequestContext.js +0 -33
  241. package/decorators/Embeddable.d.ts +0 -8
  242. package/decorators/Embeddable.js +0 -14
  243. package/decorators/Embedded.d.ts +0 -18
  244. package/decorators/Embedded.js +0 -20
  245. package/decorators/Entity.d.ts +0 -18
  246. package/decorators/Entity.js +0 -16
  247. package/decorators/Enum.d.ts +0 -9
  248. package/decorators/Enum.js +0 -19
  249. package/decorators/Filter.d.ts +0 -2
  250. package/decorators/Filter.js +0 -11
  251. package/decorators/Formula.d.ts +0 -5
  252. package/decorators/Formula.js +0 -18
  253. package/decorators/Indexed.d.ts +0 -17
  254. package/decorators/Indexed.js +0 -24
  255. package/decorators/ManyToMany.d.ts +0 -40
  256. package/decorators/ManyToMany.js +0 -16
  257. package/decorators/ManyToOne.d.ts +0 -30
  258. package/decorators/ManyToOne.js +0 -16
  259. package/decorators/OneToMany.d.ts +0 -28
  260. package/decorators/OneToMany.js +0 -20
  261. package/decorators/OneToOne.d.ts +0 -24
  262. package/decorators/OneToOne.js +0 -10
  263. package/decorators/PrimaryKey.d.ts +0 -9
  264. package/decorators/PrimaryKey.js +0 -23
  265. package/decorators/Property.d.ts +0 -250
  266. package/decorators/Property.js +0 -34
  267. package/decorators/Transactional.d.ts +0 -13
  268. package/decorators/Transactional.js +0 -31
  269. package/decorators/hooks.d.ts +0 -16
  270. package/decorators/hooks.js +0 -59
  271. package/decorators/index.d.ts +0 -17
  272. package/decorators/index.js +0 -36
  273. package/entity/ArrayCollection.d.ts +0 -116
  274. package/entity/ArrayCollection.js +0 -399
  275. package/entity/EntityValidator.d.ts +0 -19
  276. package/entity/EntityValidator.js +0 -154
  277. package/index.mjs +0 -199
  278. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  279. package/metadata/ReflectMetadataProvider.js +0 -48
  280. package/utils/resolveContextProvider.d.ts +0 -10
  281. package/utils/resolveContextProvider.js +0 -31
@@ -1,20 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UnitOfWork = void 0;
4
- const node_async_hooks_1 = require("node:async_hooks");
5
- const entity_1 = require("../entity");
6
- const ChangeSet_1 = require("./ChangeSet");
7
- const ChangeSetComputer_1 = require("./ChangeSetComputer");
8
- const ChangeSetPersister_1 = require("./ChangeSetPersister");
9
- const CommitOrderCalculator_1 = require("./CommitOrderCalculator");
10
- const Utils_1 = require("../utils/Utils");
11
- const enums_1 = require("../enums");
12
- const errors_1 = require("../errors");
13
- const events_1 = require("../events");
14
- const IdentityMap_1 = require("./IdentityMap");
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { Collection } from '../entity/Collection.js';
3
+ import { EntityHelper } from '../entity/EntityHelper.js';
4
+ import { helper } from '../entity/wrap.js';
5
+ import { Reference } from '../entity/Reference.js';
6
+ import { EntityIdentifier } from '../entity/EntityIdentifier.js';
7
+ import { ChangeSet, ChangeSetType } from './ChangeSet.js';
8
+ import { ChangeSetComputer } from './ChangeSetComputer.js';
9
+ import { ChangeSetPersister } from './ChangeSetPersister.js';
10
+ import { CommitOrderCalculator } from './CommitOrderCalculator.js';
11
+ import { Utils } from '../utils/Utils.js';
12
+ import { Cascade, DeferMode, EventType, LockMode, ReferenceKind } from '../enums.js';
13
+ import { OptimisticLockError, ValidationError } from '../errors.js';
14
+ import { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster.js';
15
+ import { IdentityMap } from './IdentityMap.js';
15
16
  // to deal with validation for flush inside flush hooks and `Promise.all`
16
- const insideFlush = new node_async_hooks_1.AsyncLocalStorage();
17
- class UnitOfWork {
17
+ const insideFlush = new AsyncLocalStorage();
18
+ export class UnitOfWork {
18
19
  em;
19
20
  /** map of references to managed entities */
20
21
  identityMap;
@@ -38,14 +39,14 @@ class UnitOfWork {
38
39
  this.em = em;
39
40
  this.metadata = this.em.getMetadata();
40
41
  this.platform = this.em.getPlatform();
41
- this.identityMap = new IdentityMap_1.IdentityMap(this.platform.getDefaultSchemaName());
42
+ this.identityMap = new IdentityMap(this.platform.getDefaultSchemaName());
42
43
  this.eventManager = this.em.getEventManager();
43
44
  this.comparator = this.em.getComparator();
44
- this.changeSetComputer = new ChangeSetComputer_1.ChangeSetComputer(this.em.getValidator(), this.collectionUpdates, this.metadata, this.platform, this.em.config, this.em);
45
- this.changeSetPersister = new ChangeSetPersister_1.ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.getValidator(), this.em.config);
45
+ this.changeSetComputer = new ChangeSetComputer(this.collectionUpdates, this.metadata, this.platform, this.em.config, this.em);
46
+ this.changeSetPersister = new ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.config, this.em);
46
47
  }
47
48
  merge(entity, visited) {
48
- const wrapped = (0, entity_1.helper)(entity);
49
+ const wrapped = helper(entity);
49
50
  wrapped.__em = this.em;
50
51
  if (!wrapped.hasPrimaryKey()) {
51
52
  return;
@@ -60,52 +61,68 @@ class UnitOfWork {
60
61
  // as there can be some entity with already changed state that is not yet flushed
61
62
  if (wrapped.__initialized && (!visited || !wrapped.__originalEntityData)) {
62
63
  wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
63
- wrapped.__touched = false;
64
64
  }
65
- this.cascade(entity, enums_1.Cascade.MERGE, visited ?? new Set());
65
+ this.cascade(entity, Cascade.MERGE, visited ?? new Set());
66
+ }
67
+ /**
68
+ * Entity data can wary in its shape, e.g. we might get a deep relation graph with joined strategy, but for diffing,
69
+ * we need to normalize the shape, so relation values are only raw FKs. This method handles that.
70
+ * @internal
71
+ */
72
+ normalizeEntityData(meta, data) {
73
+ const forceUndefined = this.em.config.get('forceUndefined');
74
+ for (const key of Utils.keys(data)) {
75
+ const prop = meta.properties[key];
76
+ if (!prop) {
77
+ continue;
78
+ }
79
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
80
+ data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
81
+ }
82
+ else if (prop.kind === ReferenceKind.EMBEDDED && !prop.object && Utils.isPlainObject(data[prop.name])) {
83
+ for (const p of prop.targetMeta.props) {
84
+ /* v8 ignore next */
85
+ const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
86
+ data[prefix + p.name] = data[prop.name][p.name];
87
+ }
88
+ data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
89
+ }
90
+ if (prop.hydrate === false && prop.customType?.ensureComparable(meta, prop)) {
91
+ const converted = prop.customType.convertToJSValue(data[key], this.platform, { key, mode: 'hydration', force: true });
92
+ data[key] = prop.customType.convertToDatabaseValue(converted, this.platform, { key, mode: 'hydration' });
93
+ }
94
+ if (forceUndefined) {
95
+ if (data[key] === null) {
96
+ data[key] = undefined;
97
+ }
98
+ }
99
+ }
66
100
  }
67
101
  /**
68
102
  * @internal
69
103
  */
70
104
  register(entity, data, options) {
71
105
  this.identityMap.store(entity);
72
- entity_1.EntityHelper.ensurePropagation(entity);
106
+ EntityHelper.ensurePropagation(entity);
73
107
  if (options?.newEntity) {
74
108
  return entity;
75
109
  }
76
110
  const forceUndefined = this.em.config.get('forceUndefined');
77
- const wrapped = (0, entity_1.helper)(entity);
111
+ const wrapped = helper(entity);
78
112
  if (options?.loaded && wrapped.__initialized && !wrapped.__onLoadFired) {
79
113
  this.loadedEntities.add(entity);
80
114
  }
81
115
  wrapped.__em ??= this.em;
82
116
  wrapped.__managed = true;
83
117
  if (data && (options?.refresh || !wrapped.__originalEntityData)) {
84
- for (const key of Utils_1.Utils.keys(data)) {
118
+ this.normalizeEntityData(wrapped.__meta, data);
119
+ for (const key of Utils.keys(data)) {
85
120
  const prop = wrapped.__meta.properties[key];
86
- if (!prop) {
87
- continue;
88
- }
89
- wrapped.__loadedProperties.add(key);
90
- if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils_1.Utils.isPlainObject(data[prop.name])) {
91
- data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
92
- }
93
- else if (prop.kind === enums_1.ReferenceKind.EMBEDDED && !prop.object && Utils_1.Utils.isPlainObject(data[prop.name])) {
94
- for (const p of prop.targetMeta.props) {
95
- /* istanbul ignore next */
96
- const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
97
- data[prefix + p.name] = data[prop.name][p.name];
98
- }
99
- data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
100
- }
101
- if (forceUndefined) {
102
- if (data[key] === null) {
103
- data[key] = undefined;
104
- }
121
+ if (prop) {
122
+ wrapped.__loadedProperties.add(key);
105
123
  }
106
124
  }
107
125
  wrapped.__originalEntityData = data;
108
- wrapped.__touched = false;
109
126
  }
110
127
  return entity;
111
128
  }
@@ -114,9 +131,9 @@ class UnitOfWork {
114
131
  */
115
132
  async dispatchOnLoadEvent() {
116
133
  for (const entity of this.loadedEntities) {
117
- if (this.eventManager.hasListeners(enums_1.EventType.onLoad, entity.__meta)) {
118
- await this.eventManager.dispatchEvent(enums_1.EventType.onLoad, { entity, meta: entity.__meta, em: this.em });
119
- (0, entity_1.helper)(entity).__onLoadFired = true;
134
+ if (this.eventManager.hasListeners(EventType.onLoad, entity.__meta)) {
135
+ await this.eventManager.dispatchEvent(EventType.onLoad, { entity, meta: entity.__meta, em: this.em });
136
+ helper(entity).__onLoadFired = true;
120
137
  }
121
138
  }
122
139
  this.loadedEntities.clear();
@@ -124,7 +141,7 @@ class UnitOfWork {
124
141
  /**
125
142
  * Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
126
143
  */
127
- getById(entityName, id, schema) {
144
+ getById(entityName, id, schema, convertCustomTypes) {
128
145
  if (id == null || (Array.isArray(id) && id.length === 0)) {
129
146
  return undefined;
130
147
  }
@@ -134,8 +151,17 @@ class UnitOfWork {
134
151
  hash = '' + id;
135
152
  }
136
153
  else {
137
- const keys = Array.isArray(id) ? Utils_1.Utils.flatten(id) : [id];
138
- hash = Utils_1.Utils.getPrimaryKeyHash(keys);
154
+ let keys = Array.isArray(id) ? Utils.flatten(id) : [id];
155
+ keys = meta.getPrimaryProps(true).map((p, i) => {
156
+ if (!convertCustomTypes && p.customType) {
157
+ return p.customType.convertToDatabaseValue(keys[i], this.platform, {
158
+ key: p.name,
159
+ mode: 'hydration',
160
+ });
161
+ }
162
+ return keys[i];
163
+ });
164
+ hash = Utils.getPrimaryKeyHash(keys);
139
165
  }
140
166
  schema ??= meta.schema ?? this.em.config.getSchema();
141
167
  if (schema) {
@@ -144,7 +170,7 @@ class UnitOfWork {
144
170
  return this.identityMap.getByHash(meta, hash);
145
171
  }
146
172
  tryGetById(entityName, where, schema, strict = true) {
147
- const pk = Utils_1.Utils.extractPK(where, this.metadata.find(entityName), strict);
173
+ const pk = Utils.extractPK(where, this.metadata.find(entityName), strict);
148
174
  if (!pk) {
149
175
  return null;
150
176
  }
@@ -160,7 +186,7 @@ class UnitOfWork {
160
186
  * Returns stored snapshot of entity state that is used for change set computation.
161
187
  */
162
188
  getOriginalEntityData(entity) {
163
- return (0, entity_1.helper)(entity).__originalEntityData;
189
+ return helper(entity).__originalEntityData;
164
190
  }
165
191
  getPersistStack() {
166
192
  return this.persistStack;
@@ -184,10 +210,8 @@ class UnitOfWork {
184
210
  if (this.queuedActions.has(meta.className) || this.queuedActions.has(meta.root.className)) {
185
211
  return true;
186
212
  }
187
- for (const entity of this.identityMap.getStore(meta).values()) {
188
- if ((0, entity_1.helper)(entity).__initialized && (0, entity_1.helper)(entity).isTouched()) {
189
- return true;
190
- }
213
+ if (meta.discriminatorMap && Object.values(meta.discriminatorMap).some(v => this.queuedActions.has(v))) {
214
+ return true;
191
215
  }
192
216
  return false;
193
217
  }
@@ -195,9 +219,9 @@ class UnitOfWork {
195
219
  this.queuedActions.clear();
196
220
  }
197
221
  computeChangeSet(entity, type) {
198
- const wrapped = (0, entity_1.helper)(entity);
222
+ const wrapped = helper(entity);
199
223
  if (type) {
200
- this.changeSets.set(entity, new ChangeSet_1.ChangeSet(entity, type, {}, wrapped.__meta));
224
+ this.changeSets.set(entity, new ChangeSet(entity, type, {}, wrapped.__meta));
201
225
  return;
202
226
  }
203
227
  const cs = this.changeSetComputer.computeChangeSet(entity);
@@ -208,7 +232,6 @@ class UnitOfWork {
208
232
  this.changeSets.set(entity, cs);
209
233
  this.persistStack.delete(entity);
210
234
  wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
211
- wrapped.__touched = false;
212
235
  }
213
236
  recomputeSingleChangeSet(entity) {
214
237
  const changeSet = this.changeSets.get(entity);
@@ -216,19 +239,17 @@ class UnitOfWork {
216
239
  return;
217
240
  }
218
241
  const cs = this.changeSetComputer.computeChangeSet(entity);
219
- /* istanbul ignore else */
220
242
  if (cs && !this.checkUniqueProps(cs)) {
221
243
  Object.assign(changeSet.payload, cs.payload);
222
- (0, entity_1.helper)(entity).__originalEntityData = this.comparator.prepareEntity(entity);
223
- (0, entity_1.helper)(entity).__touched = false;
244
+ helper(entity).__originalEntityData = this.comparator.prepareEntity(entity);
224
245
  }
225
246
  }
226
247
  persist(entity, visited, options = {}) {
227
- entity_1.EntityHelper.ensurePropagation(entity);
248
+ EntityHelper.ensurePropagation(entity);
228
249
  if (options.checkRemoveStack && this.removeStack.has(entity)) {
229
250
  return;
230
251
  }
231
- const wrapped = (0, entity_1.helper)(entity);
252
+ const wrapped = helper(entity);
232
253
  this.persistStack.add(entity);
233
254
  this.queuedActions.add(wrapped.__meta.className);
234
255
  this.removeStack.delete(entity);
@@ -236,43 +257,43 @@ class UnitOfWork {
236
257
  this.identityMap.store(entity);
237
258
  }
238
259
  if (options.cascade ?? true) {
239
- this.cascade(entity, enums_1.Cascade.PERSIST, visited, options);
260
+ this.cascade(entity, Cascade.PERSIST, visited, options);
240
261
  }
241
262
  }
242
263
  remove(entity, visited, options = {}) {
243
264
  // allow removing not managed entities if they are not part of the persist stack
244
- if ((0, entity_1.helper)(entity).__managed || !this.persistStack.has(entity)) {
265
+ if (helper(entity).__managed || !this.persistStack.has(entity)) {
245
266
  this.removeStack.add(entity);
246
- this.queuedActions.add((0, entity_1.helper)(entity).__meta.className);
267
+ this.queuedActions.add(helper(entity).__meta.className);
247
268
  }
248
269
  else {
249
270
  this.persistStack.delete(entity);
250
271
  this.identityMap.delete(entity);
251
272
  }
252
273
  // remove from referencing relations that are nullable
253
- for (const prop of (0, entity_1.helper)(entity).__meta.bidirectionalRelations) {
274
+ for (const prop of helper(entity).__meta.bidirectionalRelations) {
254
275
  const inverseProp = prop.mappedBy || prop.inversedBy;
255
- const relation = entity_1.Reference.unwrapReference(entity[prop.name]);
276
+ const relation = Reference.unwrapReference(entity[prop.name]);
256
277
  const prop2 = prop.targetMeta.properties[inverseProp];
257
- if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY && prop2.nullable && Utils_1.Utils.isCollection(relation)) {
278
+ if (prop.kind === ReferenceKind.ONE_TO_MANY && prop2.nullable && Utils.isCollection(relation)) {
258
279
  for (const item of relation.getItems(false)) {
259
280
  delete item[inverseProp];
260
281
  }
261
282
  continue;
262
283
  }
263
284
  const target = relation && relation[inverseProp];
264
- if (relation && Utils_1.Utils.isCollection(target)) {
285
+ if (relation && Utils.isCollection(target)) {
265
286
  target.removeWithoutPropagation(entity);
266
287
  }
267
288
  }
268
289
  if (options.cascade ?? true) {
269
- this.cascade(entity, enums_1.Cascade.REMOVE, visited);
290
+ this.cascade(entity, Cascade.REMOVE, visited);
270
291
  }
271
292
  }
272
293
  async commit() {
273
294
  if (this.working) {
274
295
  if (insideFlush.getStore()) {
275
- throw errors_1.ValidationError.cannotCommit();
296
+ throw ValidationError.cannotCommit();
276
297
  }
277
298
  return new Promise((resolve, reject) => {
278
299
  this.flushQueue.push(() => {
@@ -297,23 +318,27 @@ class UnitOfWork {
297
318
  async doCommit() {
298
319
  const oldTx = this.em.getTransactionContext();
299
320
  try {
300
- await this.eventManager.dispatchEvent(enums_1.EventType.beforeFlush, { em: this.em, uow: this });
321
+ await this.eventManager.dispatchEvent(EventType.beforeFlush, { em: this.em, uow: this });
301
322
  this.computeChangeSets();
302
323
  for (const cs of this.changeSets.values()) {
303
324
  cs.entity.__helper.__processing = true;
304
325
  }
305
- await this.eventManager.dispatchEvent(enums_1.EventType.onFlush, { em: this.em, uow: this });
326
+ await this.eventManager.dispatchEvent(EventType.onFlush, { em: this.em, uow: this });
327
+ this.filterCollectionUpdates();
306
328
  // nothing to do, do not start transaction
307
329
  if (this.changeSets.size === 0 && this.collectionUpdates.size === 0 && this.extraUpdates.size === 0) {
308
- return void await this.eventManager.dispatchEvent(enums_1.EventType.afterFlush, { em: this.em, uow: this });
330
+ await this.eventManager.dispatchEvent(EventType.afterFlush, { em: this.em, uow: this });
331
+ return;
309
332
  }
310
333
  const groups = this.getChangeSetGroups();
311
334
  const platform = this.em.getPlatform();
312
335
  const runInTransaction = !this.em.isInTransaction() && platform.supportsTransactions() && this.em.config.get('implicitTransactions');
313
336
  if (runInTransaction) {
337
+ const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
314
338
  await this.em.getConnection('write').transactional(trx => this.persistToDatabase(groups, trx), {
315
339
  ctx: oldTx,
316
- eventBroadcaster: new events_1.TransactionEventBroadcaster(this.em),
340
+ eventBroadcaster: new TransactionEventBroadcaster(this.em),
341
+ loggerContext,
317
342
  });
318
343
  }
319
344
  else {
@@ -323,18 +348,18 @@ class UnitOfWork {
323
348
  for (const cs of this.changeSets.values()) {
324
349
  cs.entity.__helper.__processing = false;
325
350
  }
326
- await this.eventManager.dispatchEvent(enums_1.EventType.afterFlush, { em: this.em, uow: this });
351
+ await this.eventManager.dispatchEvent(EventType.afterFlush, { em: this.em, uow: this });
327
352
  }
328
353
  finally {
329
354
  this.resetTransaction(oldTx);
330
355
  }
331
356
  }
332
357
  async lock(entity, options) {
333
- if (!this.getById(entity.constructor.name, (0, entity_1.helper)(entity).__primaryKeys, (0, entity_1.helper)(entity).__schema)) {
334
- throw errors_1.ValidationError.entityNotManaged(entity);
358
+ if (!this.getById(entity.constructor.name, helper(entity).__primaryKeys, helper(entity).__schema)) {
359
+ throw ValidationError.entityNotManaged(entity);
335
360
  }
336
361
  const meta = this.metadata.find(entity.constructor.name);
337
- if (options.lockMode === enums_1.LockMode.OPTIMISTIC) {
362
+ if (options.lockMode === LockMode.OPTIMISTIC) {
338
363
  await this.lockOptimistic(entity, meta, options.lockVersion);
339
364
  }
340
365
  else if (options.lockMode != null) {
@@ -348,78 +373,77 @@ class UnitOfWork {
348
373
  }
349
374
  unsetIdentity(entity) {
350
375
  this.identityMap.delete(entity);
351
- const wrapped = (0, entity_1.helper)(entity);
376
+ const wrapped = helper(entity);
352
377
  const serializedPK = wrapped.getSerializedPrimaryKey();
353
378
  // remove references of this entity in all managed entities, otherwise flushing could reinsert the entity
354
379
  for (const { meta, prop } of wrapped.__meta.referencingProperties) {
355
380
  for (const referrer of this.identityMap.getStore(meta).values()) {
356
- const rel = entity_1.Reference.unwrapReference(referrer[prop.name]);
357
- if (Utils_1.Utils.isCollection(rel)) {
381
+ const rel = Reference.unwrapReference(referrer[prop.name]);
382
+ if (Utils.isCollection(rel)) {
358
383
  rel.removeWithoutPropagation(entity);
359
384
  }
360
- else if (rel && (prop.mapToPk ? (0, entity_1.helper)(this.em.getReference(prop.type, rel)).getSerializedPrimaryKey() === serializedPK : rel === entity)) {
385
+ else if (rel && (prop.mapToPk ? helper(this.em.getReference(prop.type, rel)).getSerializedPrimaryKey() === serializedPK : rel === entity)) {
361
386
  if (prop.formula) {
362
387
  delete referrer[prop.name];
363
388
  }
364
389
  else {
365
- delete (0, entity_1.helper)(referrer).__data[prop.name];
390
+ delete helper(referrer).__data[prop.name];
366
391
  }
367
392
  }
368
393
  }
369
394
  }
370
395
  delete wrapped.__identifier;
371
396
  delete wrapped.__originalEntityData;
372
- wrapped.__touched = false;
373
397
  wrapped.__managed = false;
374
398
  }
375
399
  computeChangeSets() {
376
400
  this.changeSets.clear();
377
401
  const visited = new Set();
378
402
  for (const entity of this.removeStack) {
379
- this.cascade(entity, enums_1.Cascade.REMOVE, visited);
403
+ this.cascade(entity, Cascade.REMOVE, visited);
380
404
  }
381
405
  visited.clear();
382
- for (const entity of this.persistStack) {
383
- this.cascade(entity, enums_1.Cascade.PERSIST, visited, { checkRemoveStack: true });
384
- }
385
406
  for (const entity of this.identityMap) {
386
407
  if (!this.removeStack.has(entity) && !this.persistStack.has(entity) && !this.orphanRemoveStack.has(entity)) {
387
- this.cascade(entity, enums_1.Cascade.PERSIST, visited, { checkRemoveStack: true });
408
+ this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
388
409
  }
389
410
  }
411
+ for (const entity of this.persistStack) {
412
+ this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
413
+ }
390
414
  visited.clear();
391
415
  for (const entity of this.persistStack) {
392
416
  this.findNewEntities(entity, visited);
393
417
  }
394
418
  for (const entity of this.orphanRemoveStack) {
395
- if (!(0, entity_1.helper)(entity).__processing) {
419
+ if (!helper(entity).__processing) {
396
420
  this.removeStack.add(entity);
397
421
  }
398
422
  }
399
423
  // Check insert stack if there are any entities matching something from delete stack. This can happen when recreating entities.
400
424
  const inserts = {};
401
425
  for (const cs of this.changeSets.values()) {
402
- if (cs.type === ChangeSet_1.ChangeSetType.CREATE) {
426
+ if (cs.type === ChangeSetType.CREATE) {
403
427
  inserts[cs.meta.className] ??= [];
404
428
  inserts[cs.meta.className].push(cs);
405
429
  }
406
430
  }
407
431
  for (const cs of this.changeSets.values()) {
408
- if (cs.type === ChangeSet_1.ChangeSetType.UPDATE) {
432
+ if (cs.type === ChangeSetType.UPDATE) {
409
433
  this.findEarlyUpdates(cs, inserts[cs.meta.className]);
410
434
  }
411
435
  }
412
436
  for (const entity of this.removeStack) {
413
- const wrapped = (0, entity_1.helper)(entity);
414
- /* istanbul ignore next */
437
+ const wrapped = helper(entity);
438
+ /* v8 ignore next */
415
439
  if (wrapped.__processing) {
416
440
  continue;
417
441
  }
418
442
  const deletePkHash = [wrapped.getSerializedPrimaryKey(), ...this.expandUniqueProps(entity)];
419
- let type = ChangeSet_1.ChangeSetType.DELETE;
443
+ let type = ChangeSetType.DELETE;
420
444
  for (const cs of inserts[wrapped.__meta.className] ?? []) {
421
445
  if (deletePkHash.some(hash => hash === cs.getSerializedPrimaryKey() || this.expandUniqueProps(cs.entity).find(child => hash === child))) {
422
- type = ChangeSet_1.ChangeSetType.DELETE_EARLY;
446
+ type = ChangeSetType.DELETE_EARLY;
423
447
  }
424
448
  }
425
449
  this.computeChangeSet(entity, type);
@@ -430,7 +454,7 @@ class UnitOfWork {
430
454
  return;
431
455
  }
432
456
  let conflicts = false;
433
- let type = ChangeSet_1.ChangeSetType.UPDATE;
457
+ let type = ChangeSetType.UPDATE;
434
458
  if (!props.some(prop => prop.name in changeSet.payload)) {
435
459
  return;
436
460
  }
@@ -439,7 +463,7 @@ class UnitOfWork {
439
463
  if (prop.name in cs.payload && cs.rootName === changeSet.rootName && cs.type === changeSet.type) {
440
464
  conflicts = true;
441
465
  if (changeSet.payload[prop.name] == null) {
442
- type = ChangeSet_1.ChangeSetType.UPDATE_EARLY;
466
+ type = ChangeSetType.UPDATE_EARLY;
443
467
  }
444
468
  }
445
469
  }
@@ -455,15 +479,15 @@ class UnitOfWork {
455
479
  }
456
480
  scheduleOrphanRemoval(entity, visited) {
457
481
  if (entity) {
458
- (0, entity_1.helper)(entity).__em = this.em;
482
+ helper(entity).__em = this.em;
459
483
  this.orphanRemoveStack.add(entity);
460
484
  this.queuedActions.add(entity.__meta.className);
461
- this.cascade(entity, enums_1.Cascade.SCHEDULE_ORPHAN_REMOVAL, visited);
485
+ this.cascade(entity, Cascade.SCHEDULE_ORPHAN_REMOVAL, visited);
462
486
  }
463
487
  }
464
488
  cancelOrphanRemoval(entity, visited) {
465
489
  this.orphanRemoveStack.delete(entity);
466
- this.cascade(entity, enums_1.Cascade.CANCEL_ORPHAN_REMOVAL, visited);
490
+ this.cascade(entity, Cascade.CANCEL_ORPHAN_REMOVAL, visited);
467
491
  }
468
492
  getOrphanRemoveStack() {
469
493
  return this.orphanRemoveStack;
@@ -477,7 +501,7 @@ class UnitOfWork {
477
501
  }
478
502
  visited.add(entity);
479
503
  processed.add(entity);
480
- const wrapped = (0, entity_1.helper)(entity);
504
+ const wrapped = helper(entity);
481
505
  if (wrapped.__processing || this.removeStack.has(entity) || this.orphanRemoveStack.has(entity)) {
482
506
  return;
483
507
  }
@@ -485,9 +509,9 @@ class UnitOfWork {
485
509
  wrapped.__schema ??= this.em.schema;
486
510
  this.initIdentifier(entity);
487
511
  for (const prop of wrapped.__meta.relations) {
488
- const targets = Utils_1.Utils.unwrapProperty(entity, wrapped.__meta, prop);
512
+ const targets = Utils.unwrapProperty(entity, wrapped.__meta, prop);
489
513
  for (const [target] of targets) {
490
- const kind = entity_1.Reference.unwrapReference(target);
514
+ const kind = Reference.unwrapReference(target);
491
515
  this.processReference(entity, prop, kind, visited, processed, idx);
492
516
  }
493
517
  }
@@ -500,37 +524,37 @@ class UnitOfWork {
500
524
  * Returns `true` when the change set should be skipped as it will be empty after the extra update.
501
525
  */
502
526
  checkUniqueProps(changeSet) {
503
- if (changeSet.type !== ChangeSet_1.ChangeSetType.UPDATE) {
527
+ if (changeSet.type !== ChangeSetType.UPDATE) {
504
528
  return false;
505
529
  }
506
530
  // when changing a unique nullable property (or a 1:1 relation), we can't do it in a single
507
531
  // query as it would cause unique constraint violations
508
532
  const uniqueProps = changeSet.meta.uniqueProps.filter(prop => {
509
- return (prop.nullable || changeSet.type !== ChangeSet_1.ChangeSetType.CREATE);
533
+ return (prop.nullable || changeSet.type !== ChangeSetType.CREATE);
510
534
  });
511
535
  this.scheduleExtraUpdate(changeSet, uniqueProps);
512
- return changeSet.type === ChangeSet_1.ChangeSetType.UPDATE && !Utils_1.Utils.hasObjectKeys(changeSet.payload);
536
+ return changeSet.type === ChangeSetType.UPDATE && !Utils.hasObjectKeys(changeSet.payload);
513
537
  }
514
538
  expandUniqueProps(entity) {
515
- const wrapped = (0, entity_1.helper)(entity);
539
+ const wrapped = helper(entity);
516
540
  if (!wrapped.__meta.hasUniqueProps) {
517
541
  return [];
518
542
  }
519
543
  const simpleUniqueHashes = wrapped.__meta.uniqueProps.map(prop => {
520
544
  if (entity[prop.name] != null) {
521
- return prop.kind === enums_1.ReferenceKind.SCALAR || prop.mapToPk ? entity[prop.name] : (0, entity_1.helper)(entity[prop.name]).getSerializedPrimaryKey();
545
+ return prop.kind === ReferenceKind.SCALAR || prop.mapToPk ? entity[prop.name] : helper(entity[prop.name]).getSerializedPrimaryKey();
522
546
  }
523
547
  if (wrapped.__originalEntityData?.[prop.name] != null) {
524
- return Utils_1.Utils.getPrimaryKeyHash(Utils_1.Utils.asArray(wrapped.__originalEntityData[prop.name]));
548
+ return Utils.getPrimaryKeyHash(Utils.asArray(wrapped.__originalEntityData[prop.name]));
525
549
  }
526
550
  return undefined;
527
551
  }).filter(i => i);
528
552
  const compoundUniqueHashes = wrapped.__meta.uniques.map(unique => {
529
- const props = Utils_1.Utils.asArray(unique.properties);
553
+ const props = Utils.asArray(unique.properties);
530
554
  if (props.every(prop => entity[prop] != null)) {
531
- return Utils_1.Utils.getPrimaryKeyHash(props.map(p => {
555
+ return Utils.getPrimaryKeyHash(props.map(p => {
532
556
  const prop = wrapped.__meta.properties[p];
533
- return prop.kind === enums_1.ReferenceKind.SCALAR || prop.mapToPk ? entity[prop.name] : (0, entity_1.helper)(entity[prop.name]).getSerializedPrimaryKey();
557
+ return prop.kind === ReferenceKind.SCALAR || prop.mapToPk ? entity[prop.name] : helper(entity[prop.name]).getSerializedPrimaryKey();
534
558
  }));
535
559
  }
536
560
  return undefined;
@@ -538,32 +562,41 @@ class UnitOfWork {
538
562
  return simpleUniqueHashes.concat(compoundUniqueHashes);
539
563
  }
540
564
  initIdentifier(entity) {
541
- const wrapped = entity && (0, entity_1.helper)(entity);
565
+ const wrapped = entity && helper(entity);
542
566
  if (!wrapped || wrapped.__identifier || wrapped.hasPrimaryKey()) {
543
567
  return;
544
568
  }
545
- const pk = wrapped.__meta.getPrimaryProps()[0];
546
- if (pk.kind === enums_1.ReferenceKind.SCALAR) {
547
- wrapped.__identifier = new entity_1.EntityIdentifier();
569
+ const pks = wrapped.__meta.getPrimaryProps();
570
+ const idents = [];
571
+ for (const pk of pks) {
572
+ if (pk.kind === ReferenceKind.SCALAR) {
573
+ idents.push(new EntityIdentifier(entity[pk.name]));
574
+ }
575
+ else if (entity[pk.name]) {
576
+ this.initIdentifier(entity[pk.name]);
577
+ idents.push(helper(entity[pk.name])?.__identifier);
578
+ }
579
+ }
580
+ if (pks.length === 1) {
581
+ wrapped.__identifier = idents[0];
548
582
  }
549
- else if (entity[pk.name]) {
550
- this.initIdentifier(entity[pk.name]);
551
- wrapped.__identifier = (0, entity_1.helper)(entity[pk.name])?.__identifier;
583
+ else {
584
+ wrapped.__identifier = idents;
552
585
  }
553
586
  }
554
587
  processReference(parent, prop, kind, visited, processed, idx) {
555
- const isToOne = prop.kind === enums_1.ReferenceKind.MANY_TO_ONE || prop.kind === enums_1.ReferenceKind.ONE_TO_ONE;
556
- if (isToOne && Utils_1.Utils.isEntity(kind)) {
588
+ const isToOne = prop.kind === ReferenceKind.MANY_TO_ONE || prop.kind === ReferenceKind.ONE_TO_ONE;
589
+ if (isToOne && Utils.isEntity(kind)) {
557
590
  return this.processToOneReference(kind, visited, processed, idx);
558
591
  }
559
- if (Utils_1.Utils.isCollection(kind)) {
592
+ if (Utils.isCollection(kind)) {
560
593
  kind.getItems(false)
561
594
  .filter(item => !item.__helper.__originalEntityData)
562
595
  .forEach(item => {
563
596
  // propagate schema from parent
564
- item.__helper.__schema ??= (0, entity_1.helper)(parent).__schema;
597
+ item.__helper.__schema ??= helper(parent).__schema;
565
598
  });
566
- if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && kind.isDirty()) {
599
+ if (prop.kind === ReferenceKind.MANY_TO_MANY && kind.isDirty()) {
567
600
  this.processToManyReference(kind, visited, processed, parent, prop);
568
601
  }
569
602
  }
@@ -575,8 +608,8 @@ class UnitOfWork {
575
608
  }
576
609
  processToManyReference(collection, visited, processed, parent, prop) {
577
610
  if (this.isCollectionSelfReferenced(collection, processed)) {
578
- this.extraUpdates.add([parent, prop.name, collection, undefined, ChangeSet_1.ChangeSetType.UPDATE]);
579
- const coll = new entity_1.Collection(parent);
611
+ this.extraUpdates.add([parent, prop.name, collection, undefined, ChangeSetType.UPDATE]);
612
+ const coll = new Collection(parent);
580
613
  coll.property = prop;
581
614
  parent[prop.name] = coll;
582
615
  return;
@@ -599,14 +632,21 @@ class UnitOfWork {
599
632
  const current = this.comparator.prepareEntity(changeSet.entity);
600
633
  const diff = this.comparator.diffEntities(changeSet.name, copy, current);
601
634
  Object.assign(changeSet.payload, diff);
602
- const wrapped = (0, entity_1.helper)(changeSet.entity);
603
- if (wrapped.__identifier && diff[wrapped.__meta.primaryKeys[0]]) {
604
- wrapped.__identifier.setValue(diff[wrapped.__meta.primaryKeys[0]]);
635
+ const wrapped = helper(changeSet.entity);
636
+ if (wrapped.__identifier) {
637
+ const idents = Utils.asArray(wrapped.__identifier);
638
+ let i = 0;
639
+ for (const pk of wrapped.__meta.primaryKeys) {
640
+ if (diff[pk]) {
641
+ idents[i].setValue(diff[pk]);
642
+ }
643
+ i++;
644
+ }
605
645
  }
606
646
  }
607
647
  postCommitCleanup() {
608
648
  for (const cs of this.changeSets.values()) {
609
- const wrapped = (0, entity_1.helper)(cs.entity);
649
+ const wrapped = helper(cs.entity);
610
650
  wrapped.__processing = false;
611
651
  delete wrapped.__pk;
612
652
  }
@@ -625,23 +665,23 @@ class UnitOfWork {
625
665
  }
626
666
  visited.add(entity);
627
667
  switch (type) {
628
- case enums_1.Cascade.PERSIST:
668
+ case Cascade.PERSIST:
629
669
  this.persist(entity, visited, options);
630
670
  break;
631
- case enums_1.Cascade.MERGE:
671
+ case Cascade.MERGE:
632
672
  this.merge(entity, visited);
633
673
  break;
634
- case enums_1.Cascade.REMOVE:
674
+ case Cascade.REMOVE:
635
675
  this.remove(entity, visited, options);
636
676
  break;
637
- case enums_1.Cascade.SCHEDULE_ORPHAN_REMOVAL:
677
+ case Cascade.SCHEDULE_ORPHAN_REMOVAL:
638
678
  this.scheduleOrphanRemoval(entity, visited);
639
679
  break;
640
- case enums_1.Cascade.CANCEL_ORPHAN_REMOVAL:
680
+ case Cascade.CANCEL_ORPHAN_REMOVAL:
641
681
  this.cancelOrphanRemoval(entity, visited);
642
682
  break;
643
683
  }
644
- for (const prop of (0, entity_1.helper)(entity).__meta.relations) {
684
+ for (const prop of helper(entity).__meta.relations) {
645
685
  this.cascadeReference(entity, prop, type, visited, options);
646
686
  }
647
687
  }
@@ -650,72 +690,72 @@ class UnitOfWork {
650
690
  if (!this.shouldCascade(prop, type)) {
651
691
  return;
652
692
  }
653
- const kind = entity_1.Reference.unwrapReference(entity[prop.name]);
654
- if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils_1.Utils.isEntity(kind)) {
693
+ const kind = Reference.unwrapReference(entity[prop.name]);
694
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isEntity(kind)) {
655
695
  return this.cascade(kind, type, visited, options);
656
696
  }
657
697
  const collection = kind;
658
- if ([enums_1.ReferenceKind.ONE_TO_MANY, enums_1.ReferenceKind.MANY_TO_MANY].includes(prop.kind) && collection) {
698
+ if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind) && collection) {
659
699
  for (const item of collection.getItems(false)) {
660
700
  this.cascade(item, type, visited, options);
661
701
  }
662
702
  }
663
703
  }
664
704
  isCollectionSelfReferenced(collection, processed) {
665
- const filtered = collection.getItems(false).filter(item => !(0, entity_1.helper)(item).__originalEntityData);
705
+ const filtered = collection.getItems(false).filter(item => !helper(item).__originalEntityData);
666
706
  return filtered.some(items => processed.has(items));
667
707
  }
668
708
  shouldCascade(prop, type) {
669
- if ([enums_1.Cascade.REMOVE, enums_1.Cascade.SCHEDULE_ORPHAN_REMOVAL, enums_1.Cascade.CANCEL_ORPHAN_REMOVAL, enums_1.Cascade.ALL].includes(type) && prop.orphanRemoval) {
709
+ if ([Cascade.REMOVE, Cascade.SCHEDULE_ORPHAN_REMOVAL, Cascade.CANCEL_ORPHAN_REMOVAL, Cascade.ALL].includes(type) && prop.orphanRemoval) {
670
710
  return true;
671
711
  }
672
712
  // ignore user settings for merge, it is kept only for back compatibility, this should have never been configurable
673
- if (type === enums_1.Cascade.MERGE) {
713
+ if (type === Cascade.MERGE) {
674
714
  return true;
675
715
  }
676
- return prop.cascade && (prop.cascade.includes(type) || prop.cascade.includes(enums_1.Cascade.ALL));
716
+ return prop.cascade && (prop.cascade.includes(type) || prop.cascade.includes(Cascade.ALL));
677
717
  }
678
718
  async lockPessimistic(entity, options) {
679
719
  if (!this.em.isInTransaction()) {
680
- throw errors_1.ValidationError.transactionRequired();
720
+ throw ValidationError.transactionRequired();
681
721
  }
682
722
  await this.em.getDriver().lockPessimistic(entity, { ctx: this.em.getTransactionContext(), ...options });
683
723
  }
684
724
  async lockOptimistic(entity, meta, version) {
685
725
  if (!meta.versionProperty) {
686
- throw errors_1.OptimisticLockError.notVersioned(meta);
726
+ throw OptimisticLockError.notVersioned(meta);
687
727
  }
688
- if (!Utils_1.Utils.isDefined(version)) {
728
+ if (typeof version === 'undefined') {
689
729
  return;
690
730
  }
691
- const wrapped = (0, entity_1.helper)(entity);
731
+ const wrapped = helper(entity);
692
732
  if (!wrapped.__initialized) {
693
733
  await wrapped.init();
694
734
  }
695
735
  const previousVersion = entity[meta.versionProperty];
696
736
  if (previousVersion !== version) {
697
- throw errors_1.OptimisticLockError.lockFailedVersionMismatch(entity, version, previousVersion);
737
+ throw OptimisticLockError.lockFailedVersionMismatch(entity, version, previousVersion);
698
738
  }
699
739
  }
700
740
  fixMissingReference(entity, prop) {
701
741
  const reference = entity[prop.name];
702
- const kind = entity_1.Reference.unwrapReference(reference);
703
- if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && kind && !prop.mapToPk) {
704
- if (!Utils_1.Utils.isEntity(kind)) {
742
+ const kind = Reference.unwrapReference(reference);
743
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && kind && !prop.mapToPk) {
744
+ if (!Utils.isEntity(kind)) {
705
745
  entity[prop.name] = this.em.getReference(prop.type, kind, { wrapped: !!prop.ref });
706
746
  }
707
- else if (!(0, entity_1.helper)(kind).__initialized && !(0, entity_1.helper)(kind).__em) {
708
- const pk = (0, entity_1.helper)(kind).getPrimaryKey();
747
+ else if (!helper(kind).__initialized && !helper(kind).__em) {
748
+ const pk = helper(kind).getPrimaryKey();
709
749
  entity[prop.name] = this.em.getReference(prop.type, pk, { wrapped: !!prop.ref });
710
750
  }
711
751
  }
712
752
  // perf: set the `Collection._property` to skip the getter, as it can be slow when there is a lot of relations
713
- if (Utils_1.Utils.isCollection(kind)) {
753
+ if (Utils.isCollection(kind)) {
714
754
  kind.property = prop;
715
755
  }
716
- const isCollection = [enums_1.ReferenceKind.ONE_TO_MANY, enums_1.ReferenceKind.MANY_TO_MANY].includes(prop.kind);
756
+ const isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
717
757
  if (isCollection && Array.isArray(kind)) {
718
- const collection = new entity_1.Collection(entity);
758
+ const collection = new Collection(entity);
719
759
  collection.property = prop;
720
760
  entity[prop.name] = collection;
721
761
  collection.set(kind);
@@ -729,29 +769,29 @@ class UnitOfWork {
729
769
  const commitOrderReversed = [...commitOrder].reverse();
730
770
  // early delete - when we recreate entity in the same UoW, we need to issue those delete queries before inserts
731
771
  for (const name of commitOrderReversed) {
732
- await this.commitDeleteChangeSets(groups[ChangeSet_1.ChangeSetType.DELETE_EARLY].get(name) ?? [], ctx);
772
+ await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE_EARLY].get(name) ?? [], ctx);
733
773
  }
734
774
  // early update - when we recreate entity in the same UoW, we need to issue those delete queries before inserts
735
775
  for (const name of commitOrder) {
736
- await this.commitUpdateChangeSets(groups[ChangeSet_1.ChangeSetType.UPDATE_EARLY].get(name) ?? [], ctx);
776
+ await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE_EARLY].get(name) ?? [], ctx);
737
777
  }
738
778
  // extra updates
739
- await this.commitExtraUpdates(ChangeSet_1.ChangeSetType.UPDATE_EARLY, ctx);
779
+ await this.commitExtraUpdates(ChangeSetType.UPDATE_EARLY, ctx);
740
780
  // create
741
781
  for (const name of commitOrder) {
742
- await this.commitCreateChangeSets(groups[ChangeSet_1.ChangeSetType.CREATE].get(name) ?? [], ctx);
782
+ await this.commitCreateChangeSets(groups[ChangeSetType.CREATE].get(name) ?? [], ctx);
743
783
  }
744
784
  // update
745
785
  for (const name of commitOrder) {
746
- await this.commitUpdateChangeSets(groups[ChangeSet_1.ChangeSetType.UPDATE].get(name) ?? [], ctx);
786
+ await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE].get(name) ?? [], ctx);
747
787
  }
748
788
  // extra updates
749
- await this.commitExtraUpdates(ChangeSet_1.ChangeSetType.UPDATE, ctx);
789
+ await this.commitExtraUpdates(ChangeSetType.UPDATE, ctx);
750
790
  // collection updates
751
791
  await this.commitCollectionUpdates(ctx);
752
792
  // delete - entity deletions need to be in reverse commit order
753
793
  for (const name of commitOrderReversed) {
754
- await this.commitDeleteChangeSets(groups[ChangeSet_1.ChangeSetType.DELETE].get(name) ?? [], ctx);
794
+ await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE].get(name) ?? [], ctx);
755
795
  }
756
796
  // take snapshots of all persisted collections
757
797
  const visited = new Set();
@@ -764,30 +804,30 @@ class UnitOfWork {
764
804
  return;
765
805
  }
766
806
  const props = changeSets[0].meta.root.relations.filter(prop => {
767
- return (prop.kind === enums_1.ReferenceKind.ONE_TO_ONE && prop.owner)
768
- || prop.kind === enums_1.ReferenceKind.MANY_TO_ONE
769
- || (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner && !this.platform.usesPivotTable());
807
+ return (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner)
808
+ || prop.kind === ReferenceKind.MANY_TO_ONE
809
+ || (prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && !this.platform.usesPivotTable());
770
810
  });
771
811
  for (const changeSet of changeSets) {
772
812
  this.findExtraUpdates(changeSet, props);
773
- await this.runHooks(enums_1.EventType.beforeCreate, changeSet, true);
813
+ await this.runHooks(EventType.beforeCreate, changeSet, true);
774
814
  }
775
815
  await this.changeSetPersister.executeInserts(changeSets, { ctx });
776
816
  for (const changeSet of changeSets) {
777
817
  this.register(changeSet.entity, changeSet.payload, { refresh: true });
778
- await this.runHooks(enums_1.EventType.afterCreate, changeSet);
818
+ await this.runHooks(EventType.afterCreate, changeSet);
779
819
  }
780
820
  }
781
821
  findExtraUpdates(changeSet, props) {
782
822
  for (const prop of props) {
783
823
  const ref = changeSet.entity[prop.name];
784
- if (!ref || prop.deferMode === enums_1.DeferMode.INITIALLY_DEFERRED) {
824
+ if (!ref || prop.deferMode === DeferMode.INITIALLY_DEFERRED) {
785
825
  continue;
786
826
  }
787
- if (Utils_1.Utils.isCollection(ref)) {
827
+ if (Utils.isCollection(ref)) {
788
828
  ref.getItems(false).some(item => {
789
- const cs = this.changeSets.get(entity_1.Reference.unwrapReference(item));
790
- const isScheduledForInsert = cs && cs.type === ChangeSet_1.ChangeSetType.CREATE && !cs.persisted;
829
+ const cs = this.changeSets.get(Reference.unwrapReference(item));
830
+ const isScheduledForInsert = cs && cs.type === ChangeSetType.CREATE && !cs.persisted;
791
831
  if (isScheduledForInsert) {
792
832
  this.scheduleExtraUpdate(changeSet, [prop]);
793
833
  return true;
@@ -795,8 +835,8 @@ class UnitOfWork {
795
835
  return false;
796
836
  });
797
837
  }
798
- const cs = this.changeSets.get(entity_1.Reference.unwrapReference(ref));
799
- const isScheduledForInsert = cs && cs.type === ChangeSet_1.ChangeSetType.CREATE && !cs.persisted;
838
+ const cs = this.changeSets.get(Reference.unwrapReference(ref));
839
+ const isScheduledForInsert = cs && cs.type === ChangeSetType.CREATE && !cs.persisted;
800
840
  if (isScheduledForInsert) {
801
841
  this.scheduleExtraUpdate(changeSet, [prop]);
802
842
  }
@@ -805,14 +845,14 @@ class UnitOfWork {
805
845
  findEarlyUpdates(changeSet, inserts = []) {
806
846
  const props = changeSet.meta.uniqueProps;
807
847
  for (const prop of props) {
808
- const insert = inserts.find(c => Utils_1.Utils.equals(c.payload[prop.name], changeSet.originalEntity[prop.name]));
848
+ const insert = inserts.find(c => Utils.equals(c.payload[prop.name], changeSet.originalEntity[prop.name]));
809
849
  const propEmpty = changeSet.payload[prop.name] === null || changeSet.payload[prop.name] === undefined;
810
850
  if (prop.name in changeSet.payload &&
811
851
  insert &&
812
852
  // We only want to update early if the unique property on the changeset is going to be empty, so that
813
853
  // the previous unique value can be set on a different entity without constraint issues
814
854
  propEmpty) {
815
- changeSet.type = ChangeSet_1.ChangeSetType.UPDATE_EARLY;
855
+ changeSet.type = ChangeSetType.UPDATE_EARLY;
816
856
  }
817
857
  }
818
858
  }
@@ -821,14 +861,21 @@ class UnitOfWork {
821
861
  return;
822
862
  }
823
863
  for (const changeSet of changeSets) {
824
- await this.runHooks(enums_1.EventType.beforeUpdate, changeSet, true);
864
+ await this.runHooks(EventType.beforeUpdate, changeSet, true);
825
865
  }
826
866
  await this.changeSetPersister.executeUpdates(changeSets, batched, { ctx });
827
867
  for (const changeSet of changeSets) {
828
- (0, entity_1.helper)(changeSet.entity).__originalEntityData = this.comparator.prepareEntity(changeSet.entity);
829
- (0, entity_1.helper)(changeSet.entity).__touched = false;
830
- (0, entity_1.helper)(changeSet.entity).__initialized = true;
831
- await this.runHooks(enums_1.EventType.afterUpdate, changeSet);
868
+ const wrapped = helper(changeSet.entity);
869
+ wrapped.__originalEntityData = this.comparator.prepareEntity(changeSet.entity);
870
+ if (!wrapped.__initialized) {
871
+ for (const prop of changeSet.meta.relations) {
872
+ if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && changeSet.entity[prop.name] == null) {
873
+ changeSet.entity[prop.name] = Collection.create(changeSet.entity, prop.name, undefined, wrapped.isInitialized());
874
+ }
875
+ }
876
+ wrapped.__initialized = true;
877
+ }
878
+ await this.runHooks(EventType.afterUpdate, changeSet);
832
879
  }
833
880
  }
834
881
  async commitDeleteChangeSets(changeSets, ctx) {
@@ -836,12 +883,12 @@ class UnitOfWork {
836
883
  return;
837
884
  }
838
885
  for (const changeSet of changeSets) {
839
- await this.runHooks(enums_1.EventType.beforeDelete, changeSet, true);
886
+ await this.runHooks(EventType.beforeDelete, changeSet, true);
840
887
  }
841
888
  await this.changeSetPersister.executeDeletes(changeSets, { ctx });
842
889
  for (const changeSet of changeSets) {
843
890
  this.unsetIdentity(changeSet.entity);
844
- await this.runHooks(enums_1.EventType.afterDelete, changeSet);
891
+ await this.runHooks(EventType.afterDelete, changeSet);
845
892
  }
846
893
  }
847
894
  async commitExtraUpdates(type, ctx) {
@@ -870,23 +917,34 @@ class UnitOfWork {
870
917
  }
871
918
  }
872
919
  async commitCollectionUpdates(ctx) {
873
- const collectionUpdates = [];
920
+ this.filterCollectionUpdates();
921
+ const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
922
+ await this.em.getDriver().syncCollections(this.collectionUpdates, {
923
+ ctx,
924
+ schema: this.em.schema,
925
+ loggerContext,
926
+ });
874
927
  for (const coll of this.collectionUpdates) {
928
+ coll.takeSnapshot();
929
+ }
930
+ }
931
+ filterCollectionUpdates() {
932
+ for (const coll of this.collectionUpdates) {
933
+ let skip = true;
875
934
  if (coll.property.owner || coll.getItems(false).filter(item => !item.__helper.__initialized).length > 0) {
876
935
  if (this.platform.usesPivotTable()) {
877
- collectionUpdates.push(coll);
936
+ skip = false;
878
937
  }
879
938
  }
880
- else if (coll.property.kind === enums_1.ReferenceKind.ONE_TO_MANY && coll.getSnapshot() === undefined) {
881
- collectionUpdates.push(coll);
939
+ else if (coll.property.kind === ReferenceKind.ONE_TO_MANY && coll.getSnapshot() === undefined) {
940
+ skip = false;
882
941
  }
883
- else if (coll.property.kind === enums_1.ReferenceKind.MANY_TO_MANY && !coll.property.owner) {
884
- collectionUpdates.push(coll);
942
+ else if (coll.property.kind === ReferenceKind.MANY_TO_MANY && !coll.property.owner) {
943
+ skip = false;
944
+ }
945
+ if (skip) {
946
+ this.collectionUpdates.delete(coll);
885
947
  }
886
- }
887
- await this.em.getDriver().syncCollections(collectionUpdates, { ctx });
888
- for (const coll of this.collectionUpdates) {
889
- coll.takeSnapshot();
890
948
  }
891
949
  }
892
950
  /**
@@ -894,11 +952,11 @@ class UnitOfWork {
894
952
  */
895
953
  getChangeSetGroups() {
896
954
  const groups = {
897
- [ChangeSet_1.ChangeSetType.CREATE]: new Map(),
898
- [ChangeSet_1.ChangeSetType.UPDATE]: new Map(),
899
- [ChangeSet_1.ChangeSetType.DELETE]: new Map(),
900
- [ChangeSet_1.ChangeSetType.UPDATE_EARLY]: new Map(),
901
- [ChangeSet_1.ChangeSetType.DELETE_EARLY]: new Map(),
955
+ [ChangeSetType.CREATE]: new Map(),
956
+ [ChangeSetType.UPDATE]: new Map(),
957
+ [ChangeSetType.DELETE]: new Map(),
958
+ [ChangeSetType.UPDATE_EARLY]: new Map(),
959
+ [ChangeSetType.DELETE_EARLY]: new Map(),
902
960
  };
903
961
  for (const cs of this.changeSets.values()) {
904
962
  const group = groups[cs.type];
@@ -911,7 +969,7 @@ class UnitOfWork {
911
969
  return groups;
912
970
  }
913
971
  getCommitOrder() {
914
- const calc = new CommitOrderCalculator_1.CommitOrderCalculator();
972
+ const calc = new CommitOrderCalculator();
915
973
  const set = new Set();
916
974
  this.changeSets.forEach(cs => set.add(cs.rootName));
917
975
  set.forEach(entityName => calc.addNode(entityName));
@@ -938,16 +996,15 @@ class UnitOfWork {
938
996
  return;
939
997
  }
940
998
  visited.add(entity);
941
- (0, entity_1.helper)(entity)?.__meta.relations.forEach(prop => {
999
+ helper(entity)?.__meta.relations.forEach(prop => {
942
1000
  const value = entity[prop.name];
943
- if (Utils_1.Utils.isCollection(value)) {
1001
+ if (Utils.isCollection(value)) {
944
1002
  value.takeSnapshot();
945
1003
  }
946
1004
  // cascade to m:1 relations as we need to snapshot the 1:m inverse side (for `removeAll()` with orphan removal)
947
- if (prop.kind === enums_1.ReferenceKind.MANY_TO_ONE && value) {
948
- this.takeCollectionSnapshots(entity_1.Reference.unwrapReference(value), visited);
1005
+ if (prop.kind === ReferenceKind.MANY_TO_ONE && value) {
1006
+ this.takeCollectionSnapshots(Reference.unwrapReference(value), visited);
949
1007
  }
950
1008
  });
951
1009
  }
952
1010
  }
953
- exports.UnitOfWork = UnitOfWork;