@mikro-orm/core 7.0.4 → 7.0.5-dev.1

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 +583 -884
  2. package/EntityManager.js +1895 -1922
  3. package/MikroORM.d.ts +74 -103
  4. package/MikroORM.js +179 -178
  5. package/README.md +1 -1
  6. package/cache/CacheAdapter.d.ts +36 -36
  7. package/cache/FileCacheAdapter.d.ts +24 -30
  8. package/cache/FileCacheAdapter.js +78 -80
  9. package/cache/GeneratedCacheAdapter.d.ts +20 -18
  10. package/cache/GeneratedCacheAdapter.js +30 -30
  11. package/cache/MemoryCacheAdapter.d.ts +20 -18
  12. package/cache/MemoryCacheAdapter.js +36 -35
  13. package/cache/NullCacheAdapter.d.ts +16 -16
  14. package/cache/NullCacheAdapter.js +24 -24
  15. package/connections/Connection.d.ts +84 -95
  16. package/connections/Connection.js +168 -165
  17. package/drivers/DatabaseDriver.d.ts +80 -186
  18. package/drivers/DatabaseDriver.js +443 -450
  19. package/drivers/IDatabaseDriver.d.ts +301 -440
  20. package/entity/BaseEntity.d.ts +83 -120
  21. package/entity/BaseEntity.js +43 -43
  22. package/entity/Collection.d.ts +179 -212
  23. package/entity/Collection.js +721 -727
  24. package/entity/EntityAssigner.d.ts +77 -88
  25. package/entity/EntityAssigner.js +230 -231
  26. package/entity/EntityFactory.d.ts +54 -66
  27. package/entity/EntityFactory.js +383 -425
  28. package/entity/EntityHelper.d.ts +22 -34
  29. package/entity/EntityHelper.js +267 -280
  30. package/entity/EntityIdentifier.d.ts +4 -4
  31. package/entity/EntityIdentifier.js +10 -10
  32. package/entity/EntityLoader.d.ts +72 -98
  33. package/entity/EntityLoader.js +723 -753
  34. package/entity/EntityRepository.d.ts +201 -316
  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 +82 -126
  39. package/entity/Reference.js +274 -278
  40. package/entity/WrappedEntity.d.ts +72 -115
  41. package/entity/WrappedEntity.js +166 -168
  42. package/entity/defineEntity.d.ts +636 -1315
  43. package/entity/defineEntity.js +518 -527
  44. package/entity/utils.d.ts +3 -13
  45. package/entity/utils.js +73 -71
  46. package/entity/validators.js +43 -43
  47. package/entity/wrap.js +8 -8
  48. package/enums.d.ts +253 -258
  49. package/enums.js +252 -251
  50. package/errors.d.ts +72 -114
  51. package/errors.js +253 -350
  52. package/events/EventManager.d.ts +14 -26
  53. package/events/EventManager.js +77 -79
  54. package/events/EventSubscriber.d.ts +29 -29
  55. package/events/TransactionEventBroadcaster.d.ts +8 -15
  56. package/events/TransactionEventBroadcaster.js +14 -14
  57. package/exceptions.d.ts +40 -23
  58. package/exceptions.js +52 -35
  59. package/hydration/Hydrator.d.ts +17 -42
  60. package/hydration/Hydrator.js +43 -43
  61. package/hydration/ObjectHydrator.d.ts +17 -50
  62. package/hydration/ObjectHydrator.js +416 -481
  63. package/index.d.ts +2 -116
  64. package/index.js +1 -10
  65. package/logging/DefaultLogger.d.ts +32 -34
  66. package/logging/DefaultLogger.js +86 -86
  67. package/logging/Logger.d.ts +41 -41
  68. package/logging/SimpleLogger.d.ts +11 -13
  69. package/logging/SimpleLogger.js +22 -22
  70. package/logging/colors.d.ts +6 -6
  71. package/logging/colors.js +10 -11
  72. package/logging/inspect.js +7 -7
  73. package/metadata/EntitySchema.d.ts +127 -211
  74. package/metadata/EntitySchema.js +398 -397
  75. package/metadata/MetadataDiscovery.d.ts +114 -114
  76. package/metadata/MetadataDiscovery.js +1870 -1951
  77. package/metadata/MetadataProvider.d.ts +21 -24
  78. package/metadata/MetadataProvider.js +84 -82
  79. package/metadata/MetadataStorage.d.ts +32 -38
  80. package/metadata/MetadataStorage.js +118 -118
  81. package/metadata/MetadataValidator.d.ts +39 -39
  82. package/metadata/MetadataValidator.js +338 -381
  83. package/metadata/discover-entities.d.ts +2 -5
  84. package/metadata/discover-entities.js +37 -35
  85. package/metadata/types.d.ts +531 -615
  86. package/naming-strategy/AbstractNamingStrategy.d.ts +39 -54
  87. package/naming-strategy/AbstractNamingStrategy.js +85 -90
  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 +99 -109
  93. package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
  94. package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
  95. package/not-supported.js +4 -7
  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 +301 -310
  100. package/platforms/Platform.js +640 -663
  101. package/serialization/EntitySerializer.d.ts +26 -49
  102. package/serialization/EntitySerializer.js +218 -224
  103. package/serialization/EntityTransformer.d.ts +6 -10
  104. package/serialization/EntityTransformer.js +217 -219
  105. package/serialization/SerializationContext.d.ts +23 -27
  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 +10 -17
  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 +79 -83
  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 +49 -75
  158. package/types/index.js +26 -52
  159. package/typings.d.ts +737 -1250
  160. package/typings.js +231 -244
  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 +170 -178
  165. package/unit-of-work/ChangeSetPersister.d.ts +44 -63
  166. package/unit-of-work/ChangeSetPersister.js +421 -442
  167. package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
  168. package/unit-of-work/CommitOrderCalculator.js +88 -89
  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 +141 -181
  172. package/unit-of-work/UnitOfWork.js +1183 -1200
  173. package/utils/AbstractMigrator.d.ts +91 -111
  174. package/utils/AbstractMigrator.js +275 -275
  175. package/utils/AbstractSchemaGenerator.d.ts +34 -43
  176. package/utils/AbstractSchemaGenerator.js +122 -121
  177. package/utils/AsyncContext.d.ts +3 -3
  178. package/utils/AsyncContext.js +35 -34
  179. package/utils/Configuration.d.ts +808 -852
  180. package/utils/Configuration.js +344 -359
  181. package/utils/Cursor.d.ts +22 -40
  182. package/utils/Cursor.js +127 -135
  183. package/utils/DataloaderUtils.d.ts +43 -58
  184. package/utils/DataloaderUtils.js +198 -203
  185. package/utils/EntityComparator.d.ts +81 -98
  186. package/utils/EntityComparator.js +732 -828
  187. package/utils/NullHighlighter.d.ts +1 -1
  188. package/utils/NullHighlighter.js +3 -3
  189. package/utils/QueryHelper.d.ts +51 -79
  190. package/utils/QueryHelper.js +361 -372
  191. package/utils/RawQueryFragment.d.ts +34 -50
  192. package/utils/RawQueryFragment.js +105 -107
  193. package/utils/RequestContext.d.ts +32 -32
  194. package/utils/RequestContext.js +53 -52
  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 +197 -199
  199. package/utils/Utils.d.ts +145 -204
  200. package/utils/Utils.js +812 -812
  201. package/utils/clone.js +113 -104
  202. package/utils/env-vars.js +88 -90
  203. package/utils/fs-utils.d.ts +15 -15
  204. package/utils/fs-utils.js +181 -180
  205. package/utils/upsert-utils.d.ts +5 -20
  206. package/utils/upsert-utils.js +116 -114
@@ -2,96 +2,85 @@ import type { EntityManager } from '../EntityManager.js';
2
2
  import type { EntityData, EntityDTO, EntityProperty, FromEntityType, IsSubset, MergeSelected } from '../typings.js';
3
3
  /** Handles assigning data to entities, resolving relations, and propagating changes. */
4
4
  export declare class EntityAssigner {
5
- /** Assigns the given data to the entity, resolving relations and handling custom types. */
6
- static assign<
7
- Entity extends object,
8
- Naked extends FromEntityType<Entity> = FromEntityType<Entity>,
9
- Convert extends boolean = false,
10
- Data extends EntityData<Naked, Convert> | Partial<EntityDTO<Naked>> =
11
- | EntityData<Naked, Convert>
12
- | Partial<EntityDTO<Naked>>,
13
- >(
14
- entity: Entity,
15
- data: Data & IsSubset<EntityData<Naked, Convert>, Data>,
16
- options?: AssignOptions<Convert>,
17
- ): MergeSelected<Entity, Naked, keyof Data & string>;
18
- private static assignProperty;
19
- /**
20
- * auto-wire 1:1 inverse side with owner as in no-sql drivers it can't be joined
21
- * also makes sure the link is bidirectional when creating new entities from nested structures
22
- * @internal
23
- */
24
- static autoWireOneToOne<T extends object, O extends object>(prop: EntityProperty<O, T>, entity: O): void;
25
- private static validateEM;
26
- private static assignReference;
27
- private static assignCollection;
28
- private static assignEmbeddable;
29
- private static createCollectionItem;
5
+ /** Assigns the given data to the entity, resolving relations and handling custom types. */
6
+ static assign<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Convert extends boolean = false, Data extends EntityData<Naked, Convert> | Partial<EntityDTO<Naked>> = EntityData<Naked, Convert> | Partial<EntityDTO<Naked>>>(entity: Entity, data: Data & IsSubset<EntityData<Naked, Convert>, Data>, options?: AssignOptions<Convert>): MergeSelected<Entity, Naked, keyof Data & string>;
7
+ private static assignProperty;
8
+ /**
9
+ * auto-wire 1:1 inverse side with owner as in no-sql drivers it can't be joined
10
+ * also makes sure the link is bidirectional when creating new entities from nested structures
11
+ * @internal
12
+ */
13
+ static autoWireOneToOne<T extends object, O extends object>(prop: EntityProperty<O, T>, entity: O): void;
14
+ private static validateEM;
15
+ private static assignReference;
16
+ private static assignCollection;
17
+ private static assignEmbeddable;
18
+ private static createCollectionItem;
30
19
  }
31
20
  export declare const assign: typeof EntityAssigner.assign;
32
21
  /** Options controlling how data is assigned to an entity via `assign()`. */
33
22
  export interface AssignOptions<Convert extends boolean> {
34
- /**
35
- * Allows disabling processing of nested relations. When disabled, an object payload in place of a relation always
36
- * results in an `INSERT` query. To assign a value of the relation, use the foreign key instead of an object.
37
- * Defaults to `true`.
38
- */
39
- updateNestedEntities?: boolean;
40
- /**
41
- * When assigning to a relation property with object payload and `updateNestedEntities` enabled (default), you can
42
- * control how a payload without a primary key is handled. By default, it is considered as a new object, resulting
43
- * in an `INSERT` query. Use `updateByPrimaryKey: false` to allow assigning the data on an existing relation instead.
44
- * Defaults to `true`.
45
- */
46
- updateByPrimaryKey?: boolean;
47
- /**
48
- * When you have some properties in the payload that are not represented by an entity property mapping, you can skip
49
- * such unknown properties via `onlyProperties: true`. Defaults to `false`.
50
- */
51
- onlyProperties?: boolean;
52
- /**
53
- * With `onlyOwnProperties` enabled, inverse sides of to-many relations are skipped, and payloads of other relations are converted
54
- * to foreign keys. Defaults to `false`.
55
- */
56
- onlyOwnProperties?: boolean;
57
- /**
58
- * With `ignoreUndefined` enabled, `undefined` properties passed in the payload are skipped. Defaults to `false`.
59
- */
60
- ignoreUndefined?: boolean;
61
- /**
62
- * `assign` excepts runtime values for properties using custom types. To be able to assign raw database values, you
63
- * can enable the `convertCustomTypes` option. Defaults to `false`.
64
- */
65
- convertCustomTypes?: Convert;
66
- /**
67
- * When assigning to a JSON property, the value is replaced. Use `mergeObjectProperties: true` to enable deep merging
68
- * of the payload with the existing value. Defaults to `false`.
69
- */
70
- mergeObjectProperties?: boolean;
71
- /**
72
- * When assigning to an embedded property, the values are deeply merged with the existing data.
73
- * Use `mergeEmbeddedProperties: false` to replace them instead. Defaults to `true`.
74
- */
75
- mergeEmbeddedProperties?: boolean;
76
- /**
77
- * When assigning to a relation property, if the value is a POJO and `updateByPrimaryKey` is enabled, we check if
78
- * the target exists in the identity map based on its primary key and call `assign` on it recursively. If there is
79
- * no primary key provided, or the entity is not present in the context, such an entity is considered as new
80
- * (resulting in `INSERT` query), created via `em.create()`. You can use `merge: true` to use `em.merge()` instead,
81
- * which means there won't be any query used for persisting the relation. Defaults to `false`.
82
- */
83
- merge?: boolean;
84
- /**
85
- * When assigning to a to-many relation properties (`Collection`) with `updateNestedEntities` and `updateByPrimaryKey`
86
- * enabled (default), you can use this option to override the relation schema. This is used only when trying to find
87
- * the entity reference in the current context. If it is not found, we create the relation entity using the target
88
- * entity schema. The value is automatically inferred from the target entity.
89
- */
90
- schema?: string;
91
- /**
92
- * When using the static `assign()` helper, you can pass the EntityManager instance explicitly via the `em` option.
93
- * This is only needed when you try to assign a relation property. The value is automatically inferred from the target
94
- * entity when it is managed, or when you use `em.assign()` instead.
95
- */
96
- em?: EntityManager;
23
+ /**
24
+ * Allows disabling processing of nested relations. When disabled, an object payload in place of a relation always
25
+ * results in an `INSERT` query. To assign a value of the relation, use the foreign key instead of an object.
26
+ * Defaults to `true`.
27
+ */
28
+ updateNestedEntities?: boolean;
29
+ /**
30
+ * When assigning to a relation property with object payload and `updateNestedEntities` enabled (default), you can
31
+ * control how a payload without a primary key is handled. By default, it is considered as a new object, resulting
32
+ * in an `INSERT` query. Use `updateByPrimaryKey: false` to allow assigning the data on an existing relation instead.
33
+ * Defaults to `true`.
34
+ */
35
+ updateByPrimaryKey?: boolean;
36
+ /**
37
+ * When you have some properties in the payload that are not represented by an entity property mapping, you can skip
38
+ * such unknown properties via `onlyProperties: true`. Defaults to `false`.
39
+ */
40
+ onlyProperties?: boolean;
41
+ /**
42
+ * With `onlyOwnProperties` enabled, inverse sides of to-many relations are skipped, and payloads of other relations are converted
43
+ * to foreign keys. Defaults to `false`.
44
+ */
45
+ onlyOwnProperties?: boolean;
46
+ /**
47
+ * With `ignoreUndefined` enabled, `undefined` properties passed in the payload are skipped. Defaults to `false`.
48
+ */
49
+ ignoreUndefined?: boolean;
50
+ /**
51
+ * `assign` excepts runtime values for properties using custom types. To be able to assign raw database values, you
52
+ * can enable the `convertCustomTypes` option. Defaults to `false`.
53
+ */
54
+ convertCustomTypes?: Convert;
55
+ /**
56
+ * When assigning to a JSON property, the value is replaced. Use `mergeObjectProperties: true` to enable deep merging
57
+ * of the payload with the existing value. Defaults to `false`.
58
+ */
59
+ mergeObjectProperties?: boolean;
60
+ /**
61
+ * When assigning to an embedded property, the values are deeply merged with the existing data.
62
+ * Use `mergeEmbeddedProperties: false` to replace them instead. Defaults to `true`.
63
+ */
64
+ mergeEmbeddedProperties?: boolean;
65
+ /**
66
+ * When assigning to a relation property, if the value is a POJO and `updateByPrimaryKey` is enabled, we check if
67
+ * the target exists in the identity map based on its primary key and call `assign` on it recursively. If there is
68
+ * no primary key provided, or the entity is not present in the context, such an entity is considered as new
69
+ * (resulting in `INSERT` query), created via `em.create()`. You can use `merge: true` to use `em.merge()` instead,
70
+ * which means there won't be any query used for persisting the relation. Defaults to `false`.
71
+ */
72
+ merge?: boolean;
73
+ /**
74
+ * When assigning to a to-many relation properties (`Collection`) with `updateNestedEntities` and `updateByPrimaryKey`
75
+ * enabled (default), you can use this option to override the relation schema. This is used only when trying to find
76
+ * the entity reference in the current context. If it is not found, we create the relation entity using the target
77
+ * entity schema. The value is automatically inferred from the target entity.
78
+ */
79
+ schema?: string;
80
+ /**
81
+ * When using the static `assign()` helper, you can pass the EntityManager instance explicitly via the `em` option.
82
+ * This is only needed when you try to assign a relation property. The value is automatically inferred from the target
83
+ * entity when it is managed, or when you use `em.assign()` instead.
84
+ */
85
+ em?: EntityManager;
97
86
  }
@@ -8,244 +8,243 @@ 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
- } 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
- }
59
- }
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);
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);
94
59
  }
95
- }
96
- return EntityAssigner.assignReference(entity, value, prop, options.em, options);
97
60
  }
98
- if (wrapped.__managed && wrap(unwrappedEntity).isInitialized()) {
99
- return EntityAssigner.assign(unwrappedEntity, value, options);
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;
100
116
  }
101
- }
102
- return EntityAssigner.assignReference(entity, value, prop, options.em, options);
103
- }
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
117
  }
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;
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
+ }
237
139
  }
238
- if (Utils.isPrimaryKey(item) && EntityAssigner.validateEM(em)) {
239
- return em.getReference(prop.targetMeta.class, item, options);
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;
240
145
  }
241
- if (Utils.isPlainObject(item) && options.merge && EntityAssigner.validateEM(em)) {
242
- return em.merge(prop.targetMeta.class, item, options);
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);
191
+ }
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);
197
+ }
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);
204
+ }
243
205
  }
244
- if (Utils.isPlainObject(item) && EntityAssigner.validateEM(em)) {
245
- return em.create(prop.targetMeta.class, item, options);
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;
246
248
  }
247
- invalid.push(item);
248
- return item;
249
- }
250
249
  }
251
250
  export const assign = EntityAssigner.assign;