@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
@@ -8,243 +8,244 @@ import { EntityHelper } from './EntityHelper.js';
8
8
  import { ValidationError } from '../errors.js';
9
9
  /** Handles assigning data to entities, resolving relations, and propagating changes. */
10
10
  export class EntityAssigner {
11
- /** Assigns the given data to the entity, resolving relations and handling custom types. */
12
- static assign(entity, data, options = {}) {
13
- let opts = options;
14
- if (opts.visited?.has(entity)) {
15
- return entity;
16
- }
17
- EntityHelper.ensurePropagation(entity);
18
- opts.visited ??= new Set();
19
- opts.visited.add(entity);
20
- const wrapped = helper(entity);
21
- opts = {
22
- ...wrapped.__config.get('assign'),
23
- schema: wrapped.__schema,
24
- ...opts, // allow overriding the defaults
25
- };
26
- const meta = wrapped.__meta;
27
- const props = meta.properties;
28
- Object.keys(data).forEach(prop => {
29
- return EntityAssigner.assignProperty(entity, prop, props, data, {
30
- ...opts,
31
- em: opts.em || wrapped.__em,
32
- platform: wrapped.__platform,
33
- });
34
- });
35
- return entity;
36
- }
37
- static assignProperty(entity, propName, props, data, options) {
38
- let value = data[propName];
39
- const onlyProperties = options.onlyProperties && !(propName in props);
40
- const ignoreUndefined = options.ignoreUndefined === true && value === undefined;
41
- if (onlyProperties || ignoreUndefined) {
42
- return;
43
- }
44
- const prop = { ...props[propName], name: propName };
45
- if (prop && options.onlyOwnProperties) {
46
- if ([ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
47
- return;
48
- }
49
- if ([ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
50
- if (!prop.owner) {
51
- return;
52
- }
53
- else if (value?.map) {
54
- value = value.map((v) => Utils.extractPK(v, prop.targetMeta));
55
- }
56
- }
57
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
58
- value = Utils.extractPK(value, prop.targetMeta);
59
- }
60
- }
61
- if (propName in props && !prop.nullable && value == null) {
62
- throw new Error(`You must pass a non-${value} value to the property ${propName} of entity ${entity.constructor.name}.`);
63
- }
64
- // create collection instance if its missing so old items can be deleted with orphan removal
65
- if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop?.kind) && entity[prop.name] == null) {
66
- entity[prop.name] = Collection.create(entity, prop.name, undefined, helper(entity).isInitialized());
67
- }
68
- if (prop && Utils.isCollection(entity[prop.name])) {
69
- return EntityAssigner.assignCollection(entity, entity[prop.name], value, prop, options.em, options);
70
- }
71
- const customType = prop?.customType;
72
- if (options.convertCustomTypes && customType && prop.kind === ReferenceKind.SCALAR && !Utils.isEntity(data)) {
73
- value = customType.convertToJSValue(value, options.platform);
74
- }
75
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop?.kind) && value != null) {
76
- if (options.updateNestedEntities &&
77
- Object.hasOwn(entity, propName) &&
78
- Utils.isEntity(entity[propName], true) &&
79
- Utils.isPlainObject(value)) {
80
- const unwrappedEntity = Reference.unwrapReference(entity[propName]);
81
- const wrapped = helper(unwrappedEntity);
82
- if (options.updateByPrimaryKey) {
83
- const pk = Utils.extractPK(value, prop.targetMeta);
84
- if (pk) {
85
- const ref = options.em.getReference(prop.targetMeta.class, pk, options);
86
- // if the PK differs, we want to change the target entity, not update it
87
- const wrappedChild = helper(ref);
88
- const sameTarget = wrappedChild.getSerializedPrimaryKey() === wrapped.getSerializedPrimaryKey();
89
- if (wrappedChild.__managed && wrappedChild.isInitialized() && sameTarget) {
90
- return EntityAssigner.assign(ref, value, options);
91
- }
92
- }
93
- return EntityAssigner.assignReference(entity, value, prop, options.em, options);
94
- }
95
- if (wrapped.__managed && wrap(unwrappedEntity).isInitialized()) {
96
- return EntityAssigner.assign(unwrappedEntity, value, options);
97
- }
98
- }
99
- return EntityAssigner.assignReference(entity, value, prop, options.em, options);
100
- }
101
- if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
102
- validateProperty(prop, value, entity);
103
- return (entity[prop.name] = value);
104
- }
105
- if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
106
- return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
107
- }
108
- if (options.mergeObjectProperties &&
109
- Utils.isPlainObject(entity[propName]) &&
110
- Utils.isPlainObject(value)) {
111
- entity[propName] ??= {};
112
- entity[propName] = Utils.merge({}, entity[propName], value);
113
- }
114
- else if (!prop || prop.setter || !prop.getter) {
115
- entity[propName] = value;
116
- }
11
+ /** Assigns the given data to the entity, resolving relations and handling custom types. */
12
+ static assign(entity, data, options = {}) {
13
+ let opts = options;
14
+ if (opts.visited?.has(entity)) {
15
+ return entity;
117
16
  }
118
- /**
119
- * auto-wire 1:1 inverse side with owner as in no-sql drivers it can't be joined
120
- * also makes sure the link is bidirectional when creating new entities from nested structures
121
- * @internal
122
- */
123
- static autoWireOneToOne(prop, entity) {
124
- const ref = entity[prop.name];
125
- if (prop.kind !== ReferenceKind.ONE_TO_ONE || !Utils.isEntity(ref)) {
126
- return;
127
- }
128
- const meta2 = helper(ref).__meta;
129
- const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
130
- /* v8 ignore next */
131
- if (prop2 && !ref[prop2.name]) {
132
- if (Reference.isReference(ref)) {
133
- ref.unwrap()[prop2.name] = Reference.wrapReference(entity, prop2);
134
- }
135
- else {
136
- ref[prop2.name] = Reference.wrapReference(entity, prop2);
137
- }
138
- }
17
+ EntityHelper.ensurePropagation(entity);
18
+ opts.visited ??= new Set();
19
+ opts.visited.add(entity);
20
+ const wrapped = helper(entity);
21
+ opts = {
22
+ ...wrapped.__config.get('assign'),
23
+ schema: wrapped.__schema,
24
+ ...opts, // allow overriding the defaults
25
+ };
26
+ const meta = wrapped.__meta;
27
+ const props = meta.properties;
28
+ Object.keys(data).forEach(prop => {
29
+ return EntityAssigner.assignProperty(entity, prop, props, data, {
30
+ ...opts,
31
+ em: opts.em || wrapped.__em,
32
+ platform: wrapped.__platform,
33
+ });
34
+ });
35
+ return entity;
36
+ }
37
+ static assignProperty(entity, propName, props, data, options) {
38
+ let value = data[propName];
39
+ const onlyProperties = options.onlyProperties && !(propName in props);
40
+ const ignoreUndefined = options.ignoreUndefined === true && value === undefined;
41
+ if (onlyProperties || ignoreUndefined) {
42
+ return;
139
43
  }
140
- static validateEM(em) {
141
- if (!em) {
142
- throw new Error(`To use assign() on not managed entities, explicitly provide EM instance: wrap(entity).assign(data, { em: orm.em })`);
143
- }
144
- return true;
44
+ const prop = { ...props[propName], name: propName };
45
+ if (prop && options.onlyOwnProperties) {
46
+ if ([ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
47
+ return;
48
+ }
49
+ if ([ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
50
+ if (!prop.owner) {
51
+ return;
52
+ } else if (value?.map) {
53
+ value = value.map(v => Utils.extractPK(v, prop.targetMeta));
54
+ }
55
+ }
56
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
57
+ value = Utils.extractPK(value, prop.targetMeta);
58
+ }
145
59
  }
146
- static assignReference(entity, value, prop, em, options) {
147
- if (Utils.isEntity(value, true)) {
148
- entity[prop.name] = Reference.wrapReference(value, prop);
149
- }
150
- else if (Utils.isPrimaryKey(value, true) && EntityAssigner.validateEM(em)) {
151
- entity[prop.name] = prop.mapToPk
152
- ? value
153
- : Reference.wrapReference(em.getReference(prop.targetMeta.class, value, options), prop);
154
- }
155
- else if (Utils.isPlainObject(value) && options.merge && EntityAssigner.validateEM(em)) {
156
- entity[prop.name] = Reference.wrapReference(em.merge(prop.targetMeta.class, value, options), prop);
157
- }
158
- else if (Utils.isPlainObject(value) && EntityAssigner.validateEM(em)) {
159
- entity[prop.name] = Reference.wrapReference(em.create(prop.targetMeta.class, value, options), prop);
160
- }
161
- else {
162
- const name = entity.constructor.name;
163
- throw new Error(`Invalid reference value provided for '${name}.${prop.name}' in ${name}.assign(): ${JSON.stringify(value)}`);
164
- }
165
- EntityAssigner.autoWireOneToOne(prop, entity);
166
- }
167
- static assignCollection(entity, collection, value, prop, em, options) {
168
- const invalid = [];
169
- const items = Utils.asArray(value).map((item, idx) => {
170
- // try to propagate missing owning side reference to the payload first
171
- const prop2 = prop.targetMeta?.properties[prop.mappedBy];
172
- if (Utils.isPlainObject(item) && prop2 && item[prop2.name] == null) {
173
- item = { ...item, [prop2.name]: Reference.wrapReference(entity, prop2) };
174
- }
175
- if (options.updateNestedEntities && options.updateByPrimaryKey && Utils.isPlainObject(item)) {
176
- const pk = Utils.extractPK(item, prop.targetMeta);
177
- if (pk && EntityAssigner.validateEM(em)) {
178
- const ref = em.getUnitOfWork().getById(prop.targetMeta.class, pk, options.schema);
179
- if (ref) {
180
- return EntityAssigner.assign(ref, item, options);
181
- }
182
- }
183
- return this.createCollectionItem(item, em, prop, invalid, options);
184
- }
185
- /* v8 ignore next */
186
- if (options.updateNestedEntities &&
187
- !options.updateByPrimaryKey &&
188
- collection[idx] &&
189
- helper(collection[idx])?.isInitialized()) {
190
- return EntityAssigner.assign(collection[idx], item, options);
60
+ if (propName in props && !prop.nullable && value == null) {
61
+ throw new Error(
62
+ `You must pass a non-${value} value to the property ${propName} of entity ${entity.constructor.name}.`,
63
+ );
64
+ }
65
+ // create collection instance if its missing so old items can be deleted with orphan removal
66
+ if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop?.kind) && entity[prop.name] == null) {
67
+ entity[prop.name] = Collection.create(entity, prop.name, undefined, helper(entity).isInitialized());
68
+ }
69
+ if (prop && Utils.isCollection(entity[prop.name])) {
70
+ return EntityAssigner.assignCollection(entity, entity[prop.name], value, prop, options.em, options);
71
+ }
72
+ const customType = prop?.customType;
73
+ if (options.convertCustomTypes && customType && prop.kind === ReferenceKind.SCALAR && !Utils.isEntity(data)) {
74
+ value = customType.convertToJSValue(value, options.platform);
75
+ }
76
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop?.kind) && value != null) {
77
+ if (
78
+ options.updateNestedEntities &&
79
+ Object.hasOwn(entity, propName) &&
80
+ Utils.isEntity(entity[propName], true) &&
81
+ Utils.isPlainObject(value)
82
+ ) {
83
+ const unwrappedEntity = Reference.unwrapReference(entity[propName]);
84
+ const wrapped = helper(unwrappedEntity);
85
+ if (options.updateByPrimaryKey) {
86
+ const pk = Utils.extractPK(value, prop.targetMeta);
87
+ if (pk) {
88
+ const ref = options.em.getReference(prop.targetMeta.class, pk, options);
89
+ // if the PK differs, we want to change the target entity, not update it
90
+ const wrappedChild = helper(ref);
91
+ const sameTarget = wrappedChild.getSerializedPrimaryKey() === wrapped.getSerializedPrimaryKey();
92
+ if (wrappedChild.__managed && wrappedChild.isInitialized() && sameTarget) {
93
+ return EntityAssigner.assign(ref, value, options);
191
94
  }
192
- return this.createCollectionItem(item, em, prop, invalid, options);
193
- });
194
- if (invalid.length > 0) {
195
- const name = entity.constructor.name;
196
- throw ValidationError.invalidCollectionValues(name, prop.name, invalid);
95
+ }
96
+ return EntityAssigner.assignReference(entity, value, prop, options.em, options);
197
97
  }
198
- if (Array.isArray(value)) {
199
- collection.set(items);
200
- }
201
- else {
202
- // append to the collection in case of assigning a single value instead of array
203
- collection.add(items);
98
+ if (wrapped.__managed && wrap(unwrappedEntity).isInitialized()) {
99
+ return EntityAssigner.assign(unwrappedEntity, value, options);
204
100
  }
101
+ }
102
+ return EntityAssigner.assignReference(entity, value, prop, options.em, options);
205
103
  }
206
- static assignEmbeddable(entity, value, prop, em, options) {
207
- const propName = prop.embedded ? prop.embedded[1] : prop.name;
208
- if (value == null) {
209
- entity[propName] = value;
210
- return;
211
- }
212
- // if the value is not an array, we just push, otherwise we replace the array
213
- if (prop.array && (Array.isArray(value) || entity[propName] == null)) {
214
- entity[propName] = [];
215
- }
216
- if (prop.array) {
217
- return Utils.asArray(value).forEach(item => {
218
- const tmp = {};
219
- this.assignEmbeddable(tmp, item, { ...prop, array: false }, em, options);
220
- entity[propName].push(...Object.values(tmp));
221
- });
222
- }
223
- const create = () => EntityAssigner.validateEM(em) &&
224
- em.getEntityFactory().createEmbeddable(prop.targetMeta.class, value, {
225
- convertCustomTypes: options.convertCustomTypes,
226
- newEntity: options.mergeEmbeddedProperties ? !('propName' in entity) : true,
227
- });
228
- entity[propName] = (options.mergeEmbeddedProperties ? entity[propName] || create() : create());
229
- Object.keys(value).forEach(key => {
230
- EntityAssigner.assignProperty(entity[propName], key, prop.embeddedProps, value, options);
231
- });
232
- }
233
- static createCollectionItem(item, em, prop, invalid, options) {
234
- if (Utils.isEntity(item)) {
235
- return item;
236
- }
237
- if (Utils.isPrimaryKey(item) && EntityAssigner.validateEM(em)) {
238
- return em.getReference(prop.targetMeta.class, item, options);
239
- }
240
- if (Utils.isPlainObject(item) && options.merge && EntityAssigner.validateEM(em)) {
241
- return em.merge(prop.targetMeta.class, item, options);
242
- }
243
- if (Utils.isPlainObject(item) && EntityAssigner.validateEM(em)) {
244
- return em.create(prop.targetMeta.class, item, options);
245
- }
246
- invalid.push(item);
247
- return item;
104
+ if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
105
+ validateProperty(prop, value, entity);
106
+ return (entity[prop.name] = value);
107
+ }
108
+ if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
109
+ return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
110
+ }
111
+ if (options.mergeObjectProperties && Utils.isPlainObject(entity[propName]) && Utils.isPlainObject(value)) {
112
+ entity[propName] ??= {};
113
+ entity[propName] = Utils.merge({}, entity[propName], value);
114
+ } else if (!prop || prop.setter || !prop.getter) {
115
+ entity[propName] = value;
116
+ }
117
+ }
118
+ /**
119
+ * auto-wire 1:1 inverse side with owner as in no-sql drivers it can't be joined
120
+ * also makes sure the link is bidirectional when creating new entities from nested structures
121
+ * @internal
122
+ */
123
+ static autoWireOneToOne(prop, entity) {
124
+ const ref = entity[prop.name];
125
+ if (prop.kind !== ReferenceKind.ONE_TO_ONE || !Utils.isEntity(ref)) {
126
+ return;
127
+ }
128
+ const meta2 = helper(ref).__meta;
129
+ const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
130
+ /* v8 ignore next */
131
+ if (prop2 && !ref[prop2.name]) {
132
+ if (Reference.isReference(ref)) {
133
+ ref.unwrap()[prop2.name] = Reference.wrapReference(entity, prop2);
134
+ } else {
135
+ ref[prop2.name] = Reference.wrapReference(entity, prop2);
136
+ }
137
+ }
138
+ }
139
+ static validateEM(em) {
140
+ if (!em) {
141
+ throw new Error(
142
+ `To use assign() on not managed entities, explicitly provide EM instance: wrap(entity).assign(data, { em: orm.em })`,
143
+ );
144
+ }
145
+ return true;
146
+ }
147
+ static assignReference(entity, value, prop, em, options) {
148
+ if (Utils.isEntity(value, true)) {
149
+ entity[prop.name] = Reference.wrapReference(value, prop);
150
+ } else if (Utils.isPrimaryKey(value, true) && EntityAssigner.validateEM(em)) {
151
+ entity[prop.name] = prop.mapToPk
152
+ ? value
153
+ : Reference.wrapReference(em.getReference(prop.targetMeta.class, value, options), prop);
154
+ } else if (Utils.isPlainObject(value) && options.merge && EntityAssigner.validateEM(em)) {
155
+ entity[prop.name] = Reference.wrapReference(em.merge(prop.targetMeta.class, value, options), prop);
156
+ } else if (Utils.isPlainObject(value) && EntityAssigner.validateEM(em)) {
157
+ entity[prop.name] = Reference.wrapReference(em.create(prop.targetMeta.class, value, options), prop);
158
+ } else {
159
+ const name = entity.constructor.name;
160
+ throw new Error(
161
+ `Invalid reference value provided for '${name}.${prop.name}' in ${name}.assign(): ${JSON.stringify(value)}`,
162
+ );
163
+ }
164
+ EntityAssigner.autoWireOneToOne(prop, entity);
165
+ }
166
+ static assignCollection(entity, collection, value, prop, em, options) {
167
+ const invalid = [];
168
+ const items = Utils.asArray(value).map((item, idx) => {
169
+ // try to propagate missing owning side reference to the payload first
170
+ const prop2 = prop.targetMeta?.properties[prop.mappedBy];
171
+ if (Utils.isPlainObject(item) && prop2 && item[prop2.name] == null) {
172
+ item = { ...item, [prop2.name]: Reference.wrapReference(entity, prop2) };
173
+ }
174
+ if (options.updateNestedEntities && options.updateByPrimaryKey && Utils.isPlainObject(item)) {
175
+ const pk = Utils.extractPK(item, prop.targetMeta);
176
+ if (pk && EntityAssigner.validateEM(em)) {
177
+ const ref = em.getUnitOfWork().getById(prop.targetMeta.class, pk, options.schema);
178
+ if (ref) {
179
+ return EntityAssigner.assign(ref, item, options);
180
+ }
181
+ }
182
+ return this.createCollectionItem(item, em, prop, invalid, options);
183
+ }
184
+ /* v8 ignore next */
185
+ if (
186
+ options.updateNestedEntities &&
187
+ !options.updateByPrimaryKey &&
188
+ collection[idx] &&
189
+ helper(collection[idx])?.isInitialized()
190
+ ) {
191
+ return EntityAssigner.assign(collection[idx], item, options);
192
+ }
193
+ return this.createCollectionItem(item, em, prop, invalid, options);
194
+ });
195
+ if (invalid.length > 0) {
196
+ const name = entity.constructor.name;
197
+ throw ValidationError.invalidCollectionValues(name, prop.name, invalid);
198
+ }
199
+ if (Array.isArray(value)) {
200
+ collection.set(items);
201
+ } else {
202
+ // append to the collection in case of assigning a single value instead of array
203
+ collection.add(items);
204
+ }
205
+ }
206
+ static assignEmbeddable(entity, value, prop, em, options) {
207
+ const propName = prop.embedded ? prop.embedded[1] : prop.name;
208
+ if (value == null) {
209
+ entity[propName] = value;
210
+ return;
211
+ }
212
+ // if the value is not an array, we just push, otherwise we replace the array
213
+ if (prop.array && (Array.isArray(value) || entity[propName] == null)) {
214
+ entity[propName] = [];
215
+ }
216
+ if (prop.array) {
217
+ return Utils.asArray(value).forEach(item => {
218
+ const tmp = {};
219
+ this.assignEmbeddable(tmp, item, { ...prop, array: false }, em, options);
220
+ entity[propName].push(...Object.values(tmp));
221
+ });
222
+ }
223
+ const create = () =>
224
+ EntityAssigner.validateEM(em) &&
225
+ em.getEntityFactory().createEmbeddable(prop.targetMeta.class, value, {
226
+ convertCustomTypes: options.convertCustomTypes,
227
+ newEntity: options.mergeEmbeddedProperties ? !('propName' in entity) : true,
228
+ });
229
+ entity[propName] = options.mergeEmbeddedProperties ? entity[propName] || create() : create();
230
+ Object.keys(value).forEach(key => {
231
+ EntityAssigner.assignProperty(entity[propName], key, prop.embeddedProps, value, options);
232
+ });
233
+ }
234
+ static createCollectionItem(item, em, prop, invalid, options) {
235
+ if (Utils.isEntity(item)) {
236
+ return item;
237
+ }
238
+ if (Utils.isPrimaryKey(item) && EntityAssigner.validateEM(em)) {
239
+ return em.getReference(prop.targetMeta.class, item, options);
240
+ }
241
+ if (Utils.isPlainObject(item) && options.merge && EntityAssigner.validateEM(em)) {
242
+ return em.merge(prop.targetMeta.class, item, options);
243
+ }
244
+ if (Utils.isPlainObject(item) && EntityAssigner.validateEM(em)) {
245
+ return em.create(prop.targetMeta.class, item, options);
248
246
  }
247
+ invalid.push(item);
248
+ return item;
249
+ }
249
250
  }
250
251
  export const assign = EntityAssigner.assign;
@@ -3,61 +3,73 @@ import type { EntityManager } from '../EntityManager.js';
3
3
  import type { EntityComparator } from '../utils/EntityComparator.js';
4
4
  /** @internal Options for creating and merging entities via the EntityFactory. */
5
5
  export interface FactoryOptions {
6
- /** Whether the entity should be marked as initialized. */
7
- initialized?: boolean;
8
- /** Whether the entity is being newly created (uses constructor). */
9
- newEntity?: boolean;
10
- /**
11
- * Property `onCreate` hooks are normally executed during `flush` operation.
12
- * With this option, they will be processed early inside `em.create()` method.
13
- */
14
- processOnCreateHooksEarly?: boolean;
15
- /** Whether to merge the entity into the identity map. */
16
- merge?: boolean;
17
- /** Whether to refresh an already loaded entity with new data. */
18
- refresh?: boolean;
19
- /** Whether to convert custom types during hydration. */
20
- convertCustomTypes?: boolean;
21
- /** Whether to recompute the entity snapshot after creation. */
22
- recomputeSnapshot?: boolean;
23
- /** Schema from FindOptions, overrides default schema. */
24
- schema?: string;
25
- /** Parent entity schema for nested entity creation. */
26
- parentSchema?: string;
27
- /** Whether to normalize accessors to the correct property names (normally handled via result mapper). */
28
- normalizeAccessors?: boolean;
29
- /**
30
- * Property name to use for identity map lookup instead of the primary key.
31
- * This is useful for creating references by unique non-PK properties.
32
- */
33
- key?: string;
6
+ /** Whether the entity should be marked as initialized. */
7
+ initialized?: boolean;
8
+ /** Whether the entity is being newly created (uses constructor). */
9
+ newEntity?: boolean;
10
+ /**
11
+ * Property `onCreate` hooks are normally executed during `flush` operation.
12
+ * With this option, they will be processed early inside `em.create()` method.
13
+ */
14
+ processOnCreateHooksEarly?: boolean;
15
+ /** Whether to merge the entity into the identity map. */
16
+ merge?: boolean;
17
+ /** Whether to refresh an already loaded entity with new data. */
18
+ refresh?: boolean;
19
+ /** Whether to convert custom types during hydration. */
20
+ convertCustomTypes?: boolean;
21
+ /** Whether to recompute the entity snapshot after creation. */
22
+ recomputeSnapshot?: boolean;
23
+ /** Schema from FindOptions, overrides default schema. */
24
+ schema?: string;
25
+ /** Parent entity schema for nested entity creation. */
26
+ parentSchema?: string;
27
+ /** Whether to normalize accessors to the correct property names (normally handled via result mapper). */
28
+ normalizeAccessors?: boolean;
29
+ /**
30
+ * Property name to use for identity map lookup instead of the primary key.
31
+ * This is useful for creating references by unique non-PK properties.
32
+ */
33
+ key?: string;
34
34
  }
35
35
  /** @internal Factory responsible for creating, merging, and hydrating entity instances. */
36
36
  export declare class EntityFactory {
37
- #private;
38
- constructor(em: EntityManager);
39
- /** Creates a new entity instance or returns an existing one from the identity map, hydrating it with the provided data. */
40
- create<T extends object, P extends string = string>(entityName: EntityName<T>, data: EntityData<T>, options?: FactoryOptions): New<T, P>;
41
- /** Merges new data into an existing entity, preserving user-modified properties. */
42
- mergeData<T extends object>(meta: EntityMetadata<T>, entity: T, data: EntityData<T>, options?: FactoryOptions): void;
43
- /** Creates or retrieves an uninitialized entity reference by its primary key or alternate key. */
44
- createReference<T extends object>(entityName: EntityName<T>, id: Primary<T> | Primary<T>[] | Record<string, Primary<T>>, options?: Pick<FactoryOptions, 'merge' | 'convertCustomTypes' | 'schema' | 'key'>): T;
45
- /** Creates an embeddable entity instance from the provided data. */
46
- createEmbeddable<T extends object>(entityName: EntityName<T>, data: EntityData<T>, options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>): T;
47
- /** Returns the EntityComparator instance used for diffing entities. */
48
- getComparator(): EntityComparator;
49
- private createEntity;
50
- private assignDefaultValues;
51
- private hydrate;
52
- private findEntity;
53
- private processDiscriminatorColumn;
54
- /**
55
- * denormalize PK to value required by driver (e.g. ObjectId)
56
- */
57
- private denormalizePrimaryKey;
58
- /**
59
- * returns parameters for entity constructor, creating references from plain ids
60
- */
61
- private extractConstructorParams;
62
- private get unitOfWork();
37
+ #private;
38
+ constructor(em: EntityManager);
39
+ /** Creates a new entity instance or returns an existing one from the identity map, hydrating it with the provided data. */
40
+ create<T extends object, P extends string = string>(
41
+ entityName: EntityName<T>,
42
+ data: EntityData<T>,
43
+ options?: FactoryOptions,
44
+ ): New<T, P>;
45
+ /** Merges new data into an existing entity, preserving user-modified properties. */
46
+ mergeData<T extends object>(meta: EntityMetadata<T>, entity: T, data: EntityData<T>, options?: FactoryOptions): void;
47
+ /** Creates or retrieves an uninitialized entity reference by its primary key or alternate key. */
48
+ createReference<T extends object>(
49
+ entityName: EntityName<T>,
50
+ id: Primary<T> | Primary<T>[] | Record<string, Primary<T>>,
51
+ options?: Pick<FactoryOptions, 'merge' | 'convertCustomTypes' | 'schema' | 'key'>,
52
+ ): T;
53
+ /** Creates an embeddable entity instance from the provided data. */
54
+ createEmbeddable<T extends object>(
55
+ entityName: EntityName<T>,
56
+ data: EntityData<T>,
57
+ options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>,
58
+ ): T;
59
+ /** Returns the EntityComparator instance used for diffing entities. */
60
+ getComparator(): EntityComparator;
61
+ private createEntity;
62
+ private assignDefaultValues;
63
+ private hydrate;
64
+ private findEntity;
65
+ private processDiscriminatorColumn;
66
+ /**
67
+ * denormalize PK to value required by driver (e.g. ObjectId)
68
+ */
69
+ private denormalizePrimaryKey;
70
+ /**
71
+ * returns parameters for entity constructor, creating references from plain ids
72
+ */
73
+ private extractConstructorParams;
74
+ private get unitOfWork();
63
75
  }