@mikro-orm/core 7.0.2 → 7.0.3-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 (205) hide show
  1. package/EntityManager.d.ts +583 -883
  2. package/EntityManager.js +1869 -1897
  3. package/MikroORM.d.ts +74 -103
  4. package/MikroORM.js +179 -178
  5. package/cache/CacheAdapter.d.ts +36 -36
  6. package/cache/FileCacheAdapter.d.ts +24 -30
  7. package/cache/FileCacheAdapter.js +78 -80
  8. package/cache/GeneratedCacheAdapter.d.ts +20 -18
  9. package/cache/GeneratedCacheAdapter.js +30 -30
  10. package/cache/MemoryCacheAdapter.d.ts +20 -18
  11. package/cache/MemoryCacheAdapter.js +36 -35
  12. package/cache/NullCacheAdapter.d.ts +16 -16
  13. package/cache/NullCacheAdapter.js +24 -24
  14. package/connections/Connection.d.ts +84 -95
  15. package/connections/Connection.js +168 -165
  16. package/drivers/DatabaseDriver.d.ts +80 -186
  17. package/drivers/DatabaseDriver.js +443 -450
  18. package/drivers/IDatabaseDriver.d.ts +301 -440
  19. package/entity/BaseEntity.d.ts +83 -120
  20. package/entity/BaseEntity.js +43 -43
  21. package/entity/Collection.d.ts +179 -212
  22. package/entity/Collection.js +721 -727
  23. package/entity/EntityAssigner.d.ts +77 -88
  24. package/entity/EntityAssigner.js +230 -231
  25. package/entity/EntityFactory.d.ts +54 -66
  26. package/entity/EntityFactory.js +383 -425
  27. package/entity/EntityHelper.d.ts +22 -34
  28. package/entity/EntityHelper.js +267 -280
  29. package/entity/EntityIdentifier.d.ts +4 -4
  30. package/entity/EntityIdentifier.js +10 -10
  31. package/entity/EntityLoader.d.ts +73 -103
  32. package/entity/EntityLoader.js +723 -753
  33. package/entity/EntityRepository.d.ts +201 -316
  34. package/entity/EntityRepository.js +213 -213
  35. package/entity/PolymorphicRef.d.ts +5 -5
  36. package/entity/PolymorphicRef.js +10 -10
  37. package/entity/Reference.d.ts +82 -126
  38. package/entity/Reference.js +274 -278
  39. package/entity/WrappedEntity.d.ts +72 -115
  40. package/entity/WrappedEntity.js +166 -168
  41. package/entity/defineEntity.d.ts +614 -1280
  42. package/entity/defineEntity.js +511 -520
  43. package/entity/utils.d.ts +3 -13
  44. package/entity/utils.js +73 -71
  45. package/entity/validators.js +43 -43
  46. package/entity/wrap.js +8 -8
  47. package/enums.d.ts +253 -258
  48. package/enums.js +252 -251
  49. package/errors.d.ts +72 -114
  50. package/errors.js +253 -350
  51. package/events/EventManager.d.ts +14 -26
  52. package/events/EventManager.js +77 -79
  53. package/events/EventSubscriber.d.ts +29 -29
  54. package/events/TransactionEventBroadcaster.d.ts +8 -15
  55. package/events/TransactionEventBroadcaster.js +14 -14
  56. package/exceptions.d.ts +40 -23
  57. package/exceptions.js +52 -35
  58. package/hydration/Hydrator.d.ts +17 -42
  59. package/hydration/Hydrator.js +43 -43
  60. package/hydration/ObjectHydrator.d.ts +17 -50
  61. package/hydration/ObjectHydrator.js +416 -479
  62. package/index.d.ts +2 -116
  63. package/index.js +1 -10
  64. package/logging/DefaultLogger.d.ts +32 -34
  65. package/logging/DefaultLogger.js +86 -86
  66. package/logging/Logger.d.ts +41 -41
  67. package/logging/SimpleLogger.d.ts +11 -13
  68. package/logging/SimpleLogger.js +22 -22
  69. package/logging/colors.d.ts +6 -6
  70. package/logging/colors.js +10 -11
  71. package/logging/inspect.js +7 -7
  72. package/metadata/EntitySchema.d.ts +127 -211
  73. package/metadata/EntitySchema.js +398 -397
  74. package/metadata/MetadataDiscovery.d.ts +114 -114
  75. package/metadata/MetadataDiscovery.js +1863 -1947
  76. package/metadata/MetadataProvider.d.ts +21 -24
  77. package/metadata/MetadataProvider.js +84 -82
  78. package/metadata/MetadataStorage.d.ts +32 -38
  79. package/metadata/MetadataStorage.js +118 -118
  80. package/metadata/MetadataValidator.d.ts +39 -39
  81. package/metadata/MetadataValidator.js +338 -381
  82. package/metadata/discover-entities.d.ts +2 -5
  83. package/metadata/discover-entities.js +27 -27
  84. package/metadata/types.d.ts +531 -615
  85. package/naming-strategy/AbstractNamingStrategy.d.ts +39 -54
  86. package/naming-strategy/AbstractNamingStrategy.js +85 -90
  87. package/naming-strategy/EntityCaseNamingStrategy.d.ts +6 -6
  88. package/naming-strategy/EntityCaseNamingStrategy.js +22 -22
  89. package/naming-strategy/MongoNamingStrategy.d.ts +6 -6
  90. package/naming-strategy/MongoNamingStrategy.js +18 -18
  91. package/naming-strategy/NamingStrategy.d.ts +99 -109
  92. package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
  93. package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
  94. package/not-supported.js +4 -7
  95. package/package.json +1 -1
  96. package/platforms/ExceptionConverter.d.ts +1 -1
  97. package/platforms/ExceptionConverter.js +4 -4
  98. package/platforms/Platform.d.ts +299 -308
  99. package/platforms/Platform.js +636 -659
  100. package/serialization/EntitySerializer.d.ts +26 -48
  101. package/serialization/EntitySerializer.js +218 -224
  102. package/serialization/EntityTransformer.d.ts +6 -10
  103. package/serialization/EntityTransformer.js +217 -219
  104. package/serialization/SerializationContext.d.ts +23 -27
  105. package/serialization/SerializationContext.js +105 -105
  106. package/types/ArrayType.d.ts +8 -8
  107. package/types/ArrayType.js +33 -33
  108. package/types/BigIntType.d.ts +10 -17
  109. package/types/BigIntType.js +37 -37
  110. package/types/BlobType.d.ts +3 -3
  111. package/types/BlobType.js +13 -13
  112. package/types/BooleanType.d.ts +4 -4
  113. package/types/BooleanType.js +12 -12
  114. package/types/CharacterType.d.ts +2 -2
  115. package/types/CharacterType.js +6 -6
  116. package/types/DateTimeType.d.ts +5 -5
  117. package/types/DateTimeType.js +15 -15
  118. package/types/DateType.d.ts +5 -5
  119. package/types/DateType.js +15 -15
  120. package/types/DecimalType.d.ts +7 -7
  121. package/types/DecimalType.js +26 -26
  122. package/types/DoubleType.d.ts +3 -3
  123. package/types/DoubleType.js +12 -12
  124. package/types/EnumArrayType.d.ts +5 -5
  125. package/types/EnumArrayType.js +24 -24
  126. package/types/EnumType.d.ts +3 -3
  127. package/types/EnumType.js +11 -11
  128. package/types/FloatType.d.ts +3 -3
  129. package/types/FloatType.js +9 -9
  130. package/types/IntegerType.d.ts +3 -3
  131. package/types/IntegerType.js +9 -9
  132. package/types/IntervalType.d.ts +4 -4
  133. package/types/IntervalType.js +12 -12
  134. package/types/JsonType.d.ts +8 -8
  135. package/types/JsonType.js +32 -32
  136. package/types/MediumIntType.d.ts +1 -1
  137. package/types/MediumIntType.js +3 -3
  138. package/types/SmallIntType.d.ts +3 -3
  139. package/types/SmallIntType.js +9 -9
  140. package/types/StringType.d.ts +4 -4
  141. package/types/StringType.js +12 -12
  142. package/types/TextType.d.ts +3 -3
  143. package/types/TextType.js +9 -9
  144. package/types/TimeType.d.ts +5 -5
  145. package/types/TimeType.js +17 -17
  146. package/types/TinyIntType.d.ts +3 -3
  147. package/types/TinyIntType.js +10 -10
  148. package/types/Type.d.ts +79 -83
  149. package/types/Type.js +82 -82
  150. package/types/Uint8ArrayType.d.ts +4 -4
  151. package/types/Uint8ArrayType.js +21 -21
  152. package/types/UnknownType.d.ts +4 -4
  153. package/types/UnknownType.js +12 -12
  154. package/types/UuidType.d.ts +5 -5
  155. package/types/UuidType.js +19 -19
  156. package/types/index.d.ts +49 -75
  157. package/types/index.js +26 -52
  158. package/typings.d.ts +729 -1211
  159. package/typings.js +231 -244
  160. package/unit-of-work/ChangeSet.d.ts +26 -26
  161. package/unit-of-work/ChangeSet.js +56 -56
  162. package/unit-of-work/ChangeSetComputer.d.ts +12 -12
  163. package/unit-of-work/ChangeSetComputer.js +170 -178
  164. package/unit-of-work/ChangeSetPersister.d.ts +44 -63
  165. package/unit-of-work/ChangeSetPersister.js +421 -442
  166. package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
  167. package/unit-of-work/CommitOrderCalculator.js +88 -89
  168. package/unit-of-work/IdentityMap.d.ts +31 -31
  169. package/unit-of-work/IdentityMap.js +105 -105
  170. package/unit-of-work/UnitOfWork.d.ts +141 -181
  171. package/unit-of-work/UnitOfWork.js +1183 -1200
  172. package/utils/AbstractMigrator.d.ts +91 -111
  173. package/utils/AbstractMigrator.js +275 -275
  174. package/utils/AbstractSchemaGenerator.d.ts +34 -43
  175. package/utils/AbstractSchemaGenerator.js +122 -121
  176. package/utils/AsyncContext.d.ts +3 -3
  177. package/utils/AsyncContext.js +35 -34
  178. package/utils/Configuration.d.ts +808 -852
  179. package/utils/Configuration.js +344 -359
  180. package/utils/Cursor.d.ts +22 -40
  181. package/utils/Cursor.js +127 -135
  182. package/utils/DataloaderUtils.d.ts +43 -58
  183. package/utils/DataloaderUtils.js +198 -203
  184. package/utils/EntityComparator.d.ts +81 -98
  185. package/utils/EntityComparator.js +728 -824
  186. package/utils/NullHighlighter.d.ts +1 -1
  187. package/utils/NullHighlighter.js +3 -3
  188. package/utils/QueryHelper.d.ts +51 -79
  189. package/utils/QueryHelper.js +361 -372
  190. package/utils/RawQueryFragment.d.ts +34 -50
  191. package/utils/RawQueryFragment.js +105 -107
  192. package/utils/RequestContext.d.ts +32 -32
  193. package/utils/RequestContext.js +53 -52
  194. package/utils/TransactionContext.d.ts +16 -16
  195. package/utils/TransactionContext.js +27 -27
  196. package/utils/TransactionManager.d.ts +58 -58
  197. package/utils/TransactionManager.js +197 -199
  198. package/utils/Utils.d.ts +145 -204
  199. package/utils/Utils.js +813 -814
  200. package/utils/clone.js +113 -104
  201. package/utils/env-vars.js +88 -90
  202. package/utils/fs-utils.d.ts +15 -15
  203. package/utils/fs-utils.js +181 -180
  204. package/utils/upsert-utils.d.ts +5 -20
  205. package/utils/upsert-utils.js +116 -114
@@ -1,44 +1,33 @@
1
- import type {
2
- ArrayElement,
3
- AutoPath,
4
- CleanTypeConfig,
5
- SerializeDTO,
6
- FromEntityType,
7
- TypeConfig,
8
- UnboxArray,
9
- } from '../typings.js';
1
+ import type { ArrayElement, AutoPath, CleanTypeConfig, SerializeDTO, FromEntityType, TypeConfig, UnboxArray } from '../typings.js';
10
2
  import { type PopulatePath } from '../enums.js';
11
3
  /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
12
4
  export declare class EntitySerializer {
13
- /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
14
- static serialize<T extends object, P extends string = never, E extends string = never>(
15
- entity: T,
16
- options?: SerializeOptions<T, P, E>,
17
- ): SerializeDTO<T, P, E>;
18
- private static propertyName;
19
- private static processProperty;
20
- private static processCustomType;
21
- private static extractChildOptions;
22
- private static processEntity;
23
- private static processCollection;
5
+ /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
6
+ static serialize<T extends object, P extends string = never, E extends string = never>(entity: T, options?: SerializeOptions<T, P, E>): SerializeDTO<T, P, E>;
7
+ private static propertyName;
8
+ private static processProperty;
9
+ private static processCustomType;
10
+ private static extractChildOptions;
11
+ private static processEntity;
12
+ private static processCollection;
24
13
  }
25
14
  export interface SerializeOptions<T, P extends string = never, E extends string = never> {
26
- /** Specify which relation should be serialized as populated and which as a FK. */
27
- populate?: readonly AutoPath<T, P, `${PopulatePath.ALL}`>[];
28
- /** Specify which properties should be omitted. */
29
- exclude?: readonly AutoPath<T, E>[];
30
- /** Enforce unpopulated references to be returned as objects, e.g. `{ author: { id: 1 } }` instead of `{ author: 1 }`. */
31
- forceObject?: boolean;
32
- /** Ignore custom property serializers. */
33
- ignoreSerializers?: boolean;
34
- /** Include properties marked as `hidden`. */
35
- includeHidden?: boolean;
36
- /** Skip properties with `null` value. */
37
- skipNull?: boolean;
38
- /** Only include properties for a specific group. If a property does not specify any group, it will be included, otherwise only properties with a matching group are included. */
39
- groups?: string[];
40
- /** Convert custom types to their database representation. By default, the `Type.toJSON` method is invoked instead. */
41
- convertCustomTypes?: boolean;
15
+ /** Specify which relation should be serialized as populated and which as a FK. */
16
+ populate?: readonly AutoPath<T, P, `${PopulatePath.ALL}`>[];
17
+ /** Specify which properties should be omitted. */
18
+ exclude?: readonly AutoPath<T, E>[];
19
+ /** Enforce unpopulated references to be returned as objects, e.g. `{ author: { id: 1 } }` instead of `{ author: 1 }`. */
20
+ forceObject?: boolean;
21
+ /** Ignore custom property serializers. */
22
+ ignoreSerializers?: boolean;
23
+ /** Include properties marked as `hidden`. */
24
+ includeHidden?: boolean;
25
+ /** Skip properties with `null` value. */
26
+ skipNull?: boolean;
27
+ /** Only include properties for a specific group. If a property does not specify any group, it will be included, otherwise only properties with a matching group are included. */
28
+ groups?: string[];
29
+ /** Convert custom types to their database representation. By default, the `Type.toJSON` method is invoked instead. */
30
+ convertCustomTypes?: boolean;
42
31
  }
43
32
  /**
44
33
  * Converts entity instance to POJO, converting the `Collection`s to arrays and unwrapping the `Reference` wrapper, while respecting the serialization options.
@@ -52,15 +41,4 @@ export interface SerializeOptions<T, P extends string = never, E extends string
52
41
  * const dto2 = wrap(user).serialize({ exclude: ['id', 'email'], forceObject: true });
53
42
  * ```
54
43
  */
55
- export declare function serialize<
56
- Entity extends object,
57
- Naked extends FromEntityType<Entity> = FromEntityType<Entity>,
58
- Populate extends string = never,
59
- Exclude extends string = never,
60
- Config extends TypeConfig = never,
61
- >(
62
- entity: Entity,
63
- options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>,
64
- ): Naked extends object[]
65
- ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>>[]
66
- : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>>;
44
+ export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>): Naked extends object[] ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>>[] : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>>;
@@ -5,235 +5,229 @@ import { Reference } from '../entity/Reference.js';
5
5
  import { SerializationContext } from './SerializationContext.js';
6
6
  import { isRaw } from '../utils/RawQueryFragment.js';
7
7
  function isVisible(meta, propName, options) {
8
- const prop = meta.properties[propName];
9
- if (options.groups && prop?.groups) {
10
- return prop.groups.some(g => options.groups.includes(g));
11
- }
12
- if (
13
- Array.isArray(options.populate) &&
14
- options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')
15
- ) {
16
- return true;
17
- }
18
- if (options.exclude?.find(item => item === propName)) {
19
- return false;
20
- }
21
- const visible = prop && !(prop.hidden && !options.includeHidden);
22
- const prefixed = prop && !prop.primary && !prop.accessor && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
23
- return visible && !prefixed;
24
- }
25
- function isPopulated(propName, options) {
26
- if (
27
- typeof options.populate !== 'boolean' &&
28
- options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')
29
- ) {
30
- return true;
31
- }
32
- if (typeof options.populate === 'boolean') {
33
- return options.populate;
34
- }
35
- return false;
36
- }
37
- /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
38
- export class EntitySerializer {
39
- /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
40
- static serialize(entity, options = {}) {
41
- const wrapped = helper(entity);
42
- const meta = wrapped.__meta;
43
- let contextCreated = false;
44
- if (!wrapped.__serializationContext.root) {
45
- const root = new SerializationContext();
46
- SerializationContext.propagate(
47
- root,
48
- entity,
49
- (meta, prop) => meta.properties[prop]?.kind !== ReferenceKind.SCALAR,
50
- );
51
- options.populate = options.populate ? Utils.asArray(options.populate) : options.populate;
52
- contextCreated = true;
53
- }
54
- const root = wrapped.__serializationContext.root;
55
- const ret = {};
56
- const props = new Set();
57
- if (meta.serializedPrimaryKey && !meta.compositePK) {
58
- props.add(meta.serializedPrimaryKey);
59
- } else {
60
- meta.primaryKeys.forEach(pk => props.add(pk));
61
- }
62
- if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
63
- const entityKeys = new Set(Object.keys(entity));
64
- for (const prop of meta.props) {
65
- if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
66
- props.add(prop.name);
67
- }
68
- }
69
- for (const key of entityKeys) {
70
- if (!meta.properties[key]) {
71
- props.add(key);
72
- }
73
- }
74
- }
75
- const visited = root.visited.has(entity);
76
- if (!visited) {
77
- root.visited.add(entity);
78
- }
79
- for (const prop of props) {
80
- if (!isVisible(meta, prop, options)) {
81
- continue;
82
- }
83
- const cycle = root.visit(meta.class, prop);
84
- if (cycle && visited) {
85
- continue;
86
- }
87
- const val = this.processProperty(prop, entity, options);
88
- if (!cycle) {
89
- root.leave(meta.class, prop);
90
- }
91
- if (options.skipNull && Utils.isPlainObject(val)) {
92
- Utils.dropUndefinedProperties(val, null);
93
- }
94
- if (isRaw(val)) {
95
- throw new Error(`Trying to serialize raw SQL fragment: '${val.sql}'`);
96
- }
97
- const visible = typeof val !== 'undefined' && !(val === null && options.skipNull);
98
- if (visible) {
99
- ret[this.propertyName(meta, prop)] = val;
100
- }
101
- }
102
- if (contextCreated) {
103
- root.close();
104
- }
105
- if (!wrapped.isInitialized()) {
106
- return ret;
107
- }
108
- for (const prop of meta.getterProps) {
109
- // decorated get methods
110
- if (prop.getterName != null) {
111
- const visible = entity[prop.getterName] instanceof Function && isVisible(meta, prop.name, options);
112
- if (visible) {
113
- ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.getterName, entity, options);
114
- }
115
- } else {
116
- // decorated getters
117
- const visible = typeof entity[prop.name] !== 'undefined' && isVisible(meta, prop.name, options);
118
- if (visible) {
119
- ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.name, entity, options);
120
- }
121
- }
8
+ const prop = meta.properties[propName];
9
+ if (options.groups && prop?.groups) {
10
+ return prop.groups.some(g => options.groups.includes(g));
122
11
  }
123
- return ret;
124
- }
125
- static propertyName(meta, prop) {
126
- /* v8 ignore next */
127
- if (meta.properties[prop]?.serializedName) {
128
- return meta.properties[prop].serializedName;
12
+ if (Array.isArray(options.populate) &&
13
+ options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
14
+ return true;
129
15
  }
130
- if (meta.properties[prop]?.primary && meta.serializedPrimaryKey) {
131
- return meta.serializedPrimaryKey;
16
+ if (options.exclude?.find(item => item === propName)) {
17
+ return false;
132
18
  }
133
- return prop;
134
- }
135
- static processProperty(prop, entity, options) {
136
- const parts = prop.split('.');
137
- prop = parts[0];
138
- const wrapped = helper(entity);
139
- const property = wrapped.__meta.properties[prop] ?? { name: prop };
140
- const serializer = property?.serializer;
141
- const value = entity[prop];
142
- // getter method
143
- if (entity[prop] instanceof Function) {
144
- const returnValue = entity[prop]();
145
- if (!options.ignoreSerializers && serializer) {
146
- return serializer(returnValue, this.extractChildOptions(options, prop));
147
- }
148
- return returnValue;
149
- }
150
- /* v8 ignore next */
151
- if (!options.ignoreSerializers && serializer) {
152
- return serializer(value);
153
- }
154
- if (Utils.isCollection(value)) {
155
- return this.processCollection(property, entity, options);
156
- }
157
- if (Utils.isEntity(value, true)) {
158
- return this.processEntity(property, entity, wrapped.__platform, options);
159
- }
160
- if (Utils.isScalarReference(value)) {
161
- return value.unwrap();
162
- }
163
- /* v8 ignore next */
164
- if (property?.kind === ReferenceKind.EMBEDDED) {
165
- if (Array.isArray(value)) {
166
- return value.map(item => helper(item).toJSON());
167
- }
168
- if (Utils.isObject(value)) {
169
- return helper(value).toJSON();
170
- }
171
- }
172
- if (property.customType) {
173
- return this.processCustomType(value, property, wrapped.__platform, options.convertCustomTypes);
174
- }
175
- return wrapped.__platform.normalizePrimaryKey(value);
176
- }
177
- static processCustomType(value, prop, platform, convertCustomTypes) {
178
- if (!prop.customType) {
179
- return value;
19
+ const visible = prop && !(prop.hidden && !options.includeHidden);
20
+ const prefixed = prop && !prop.primary && !prop.accessor && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
21
+ return visible && !prefixed;
22
+ }
23
+ function isPopulated(propName, options) {
24
+ if (typeof options.populate !== 'boolean' &&
25
+ options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
26
+ return true;
180
27
  }
181
- if (convertCustomTypes) {
182
- return prop.customType.convertToDatabaseValue(value, platform, { mode: 'serialization' });
28
+ if (typeof options.populate === 'boolean') {
29
+ return options.populate;
183
30
  }
184
- return prop.customType.toJSON(value, platform);
185
- }
186
- static extractChildOptions(options, prop) {
187
- return {
188
- ...options,
189
- populate: Array.isArray(options.populate)
190
- ? Utils.extractChildElements(options.populate, prop, '*')
191
- : options.populate,
192
- exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop) : options.exclude,
193
- };
194
- }
195
- static processEntity(prop, entity, platform, options) {
196
- const child = Reference.unwrapReference(entity[prop.name]);
197
- const wrapped = helper(child);
198
- const populated = isPopulated(prop.name, options) && wrapped.isInitialized();
199
- const expand = populated || !wrapped.__managed;
200
- const meta = wrapped.__meta;
201
- const childOptions = this.extractChildOptions(options, prop.name);
202
- const visible = meta.primaryKeys.filter(prop => isVisible(meta, prop, childOptions));
203
- if (expand) {
204
- return this.serialize(child, childOptions);
31
+ return false;
32
+ }
33
+ /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
34
+ export class EntitySerializer {
35
+ /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
36
+ static serialize(entity, options = {}) {
37
+ const wrapped = helper(entity);
38
+ const meta = wrapped.__meta;
39
+ let contextCreated = false;
40
+ if (!wrapped.__serializationContext.root) {
41
+ const root = new SerializationContext();
42
+ SerializationContext.propagate(root, entity, (meta, prop) => meta.properties[prop]?.kind !== ReferenceKind.SCALAR);
43
+ options.populate = (options.populate ? Utils.asArray(options.populate) : options.populate);
44
+ contextCreated = true;
45
+ }
46
+ const root = wrapped.__serializationContext.root;
47
+ const ret = {};
48
+ const props = new Set();
49
+ if (meta.serializedPrimaryKey && !meta.compositePK) {
50
+ props.add(meta.serializedPrimaryKey);
51
+ }
52
+ else {
53
+ meta.primaryKeys.forEach(pk => props.add(pk));
54
+ }
55
+ if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
56
+ const entityKeys = new Set(Object.keys(entity));
57
+ for (const prop of meta.props) {
58
+ if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
59
+ props.add(prop.name);
60
+ }
61
+ }
62
+ for (const key of entityKeys) {
63
+ if (!meta.properties[key]) {
64
+ props.add(key);
65
+ }
66
+ }
67
+ }
68
+ const visited = root.visited.has(entity);
69
+ if (!visited) {
70
+ root.visited.add(entity);
71
+ }
72
+ for (const prop of props) {
73
+ if (!isVisible(meta, prop, options)) {
74
+ continue;
75
+ }
76
+ const cycle = root.visit(meta.class, prop);
77
+ if (cycle && visited) {
78
+ continue;
79
+ }
80
+ const val = this.processProperty(prop, entity, options);
81
+ if (!cycle) {
82
+ root.leave(meta.class, prop);
83
+ }
84
+ if (options.skipNull && Utils.isPlainObject(val)) {
85
+ Utils.dropUndefinedProperties(val, null);
86
+ }
87
+ if (isRaw(val)) {
88
+ throw new Error(`Trying to serialize raw SQL fragment: '${val.sql}'`);
89
+ }
90
+ const visible = typeof val !== 'undefined' && !(val === null && options.skipNull);
91
+ if (visible) {
92
+ ret[this.propertyName(meta, prop)] = val;
93
+ }
94
+ }
95
+ if (contextCreated) {
96
+ root.close();
97
+ }
98
+ if (!wrapped.isInitialized()) {
99
+ return ret;
100
+ }
101
+ for (const prop of meta.getterProps) {
102
+ // decorated get methods
103
+ if (prop.getterName != null) {
104
+ const visible = entity[prop.getterName] instanceof Function && isVisible(meta, prop.name, options);
105
+ if (visible) {
106
+ ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.getterName, entity, options);
107
+ }
108
+ }
109
+ else {
110
+ // decorated getters
111
+ const visible = typeof entity[prop.name] !== 'undefined' && isVisible(meta, prop.name, options);
112
+ if (visible) {
113
+ ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.name, entity, options);
114
+ }
115
+ }
116
+ }
117
+ return ret;
205
118
  }
206
- const pk = this.processCustomType(wrapped.getPrimaryKey(), prop, wrapped.__platform, options.convertCustomTypes);
207
- if (options.forceObject || wrapped.__config.get('serialization').forceObject) {
208
- return Utils.primaryKeyToObject(meta, pk, visible);
119
+ static propertyName(meta, prop) {
120
+ /* v8 ignore next */
121
+ if (meta.properties[prop]?.serializedName) {
122
+ return meta.properties[prop].serializedName;
123
+ }
124
+ if (meta.properties[prop]?.primary && meta.serializedPrimaryKey) {
125
+ return meta.serializedPrimaryKey;
126
+ }
127
+ return prop;
128
+ }
129
+ static processProperty(prop, entity, options) {
130
+ const parts = prop.split('.');
131
+ prop = parts[0];
132
+ const wrapped = helper(entity);
133
+ const property = wrapped.__meta.properties[prop] ?? { name: prop };
134
+ const serializer = property?.serializer;
135
+ const value = entity[prop];
136
+ // getter method
137
+ if (entity[prop] instanceof Function) {
138
+ const returnValue = entity[prop]();
139
+ if (!options.ignoreSerializers && serializer) {
140
+ return serializer(returnValue, this.extractChildOptions(options, prop));
141
+ }
142
+ return returnValue;
143
+ }
144
+ /* v8 ignore next */
145
+ if (!options.ignoreSerializers && serializer) {
146
+ return serializer(value);
147
+ }
148
+ if (Utils.isCollection(value)) {
149
+ return this.processCollection(property, entity, options);
150
+ }
151
+ if (Utils.isEntity(value, true)) {
152
+ return this.processEntity(property, entity, wrapped.__platform, options);
153
+ }
154
+ if (Utils.isScalarReference(value)) {
155
+ return value.unwrap();
156
+ }
157
+ /* v8 ignore next */
158
+ if (property?.kind === ReferenceKind.EMBEDDED) {
159
+ if (Array.isArray(value)) {
160
+ return value.map(item => helper(item).toJSON());
161
+ }
162
+ if (Utils.isObject(value)) {
163
+ return helper(value).toJSON();
164
+ }
165
+ }
166
+ if (property.customType) {
167
+ return this.processCustomType(value, property, wrapped.__platform, options.convertCustomTypes);
168
+ }
169
+ return wrapped.__platform.normalizePrimaryKey(value);
209
170
  }
210
- if (Utils.isPlainObject(pk)) {
211
- const pruned = Utils.primaryKeyToObject(meta, pk, visible);
212
- if (visible.length === 1) {
213
- return platform.normalizePrimaryKey(pruned[visible[0]]);
214
- }
215
- return pruned;
171
+ static processCustomType(value, prop, platform, convertCustomTypes) {
172
+ if (!prop.customType) {
173
+ return value;
174
+ }
175
+ if (convertCustomTypes) {
176
+ return prop.customType.convertToDatabaseValue(value, platform, { mode: 'serialization' });
177
+ }
178
+ return prop.customType.toJSON(value, platform);
179
+ }
180
+ static extractChildOptions(options, prop) {
181
+ return {
182
+ ...options,
183
+ populate: Array.isArray(options.populate)
184
+ ? Utils.extractChildElements(options.populate, prop, '*')
185
+ : options.populate,
186
+ exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop) : options.exclude,
187
+ };
188
+ }
189
+ static processEntity(prop, entity, platform, options) {
190
+ const child = Reference.unwrapReference(entity[prop.name]);
191
+ const wrapped = helper(child);
192
+ const populated = isPopulated(prop.name, options) && wrapped.isInitialized();
193
+ const expand = populated || !wrapped.__managed;
194
+ const meta = wrapped.__meta;
195
+ const childOptions = this.extractChildOptions(options, prop.name);
196
+ const visible = meta.primaryKeys.filter(prop => isVisible(meta, prop, childOptions));
197
+ if (expand) {
198
+ return this.serialize(child, childOptions);
199
+ }
200
+ const pk = this.processCustomType(wrapped.getPrimaryKey(), prop, wrapped.__platform, options.convertCustomTypes);
201
+ if (options.forceObject || wrapped.__config.get('serialization').forceObject) {
202
+ return Utils.primaryKeyToObject(meta, pk, visible);
203
+ }
204
+ if (Utils.isPlainObject(pk)) {
205
+ const pruned = Utils.primaryKeyToObject(meta, pk, visible);
206
+ if (visible.length === 1) {
207
+ return platform.normalizePrimaryKey(pruned[visible[0]]);
208
+ }
209
+ return pruned;
210
+ }
211
+ return platform.normalizePrimaryKey(pk);
216
212
  }
217
- return platform.normalizePrimaryKey(pk);
218
- }
219
- static processCollection(prop, entity, options) {
220
- const col = entity[prop.name];
221
- if (!col.isInitialized()) {
222
- return undefined;
213
+ static processCollection(prop, entity, options) {
214
+ const col = entity[prop.name];
215
+ if (!col.isInitialized()) {
216
+ return undefined;
217
+ }
218
+ return col.getItems(false).map(item => {
219
+ const populated = isPopulated(prop.name, options);
220
+ const wrapped = helper(item);
221
+ if (populated || !wrapped.__managed) {
222
+ return this.serialize(item, this.extractChildOptions(options, prop.name));
223
+ }
224
+ const pk = this.processCustomType(wrapped.getPrimaryKey(), prop, wrapped.__platform, options.convertCustomTypes);
225
+ if (options.forceObject || wrapped.__config.get('serialization').forceObject) {
226
+ return Utils.primaryKeyToObject(wrapped.__meta, pk);
227
+ }
228
+ return pk;
229
+ });
223
230
  }
224
- return col.getItems(false).map(item => {
225
- const populated = isPopulated(prop.name, options);
226
- const wrapped = helper(item);
227
- if (populated || !wrapped.__managed) {
228
- return this.serialize(item, this.extractChildOptions(options, prop.name));
229
- }
230
- const pk = this.processCustomType(wrapped.getPrimaryKey(), prop, wrapped.__platform, options.convertCustomTypes);
231
- if (options.forceObject || wrapped.__config.get('serialization').forceObject) {
232
- return Utils.primaryKeyToObject(wrapped.__meta, pk);
233
- }
234
- return pk;
235
- });
236
- }
237
231
  }
238
232
  /**
239
233
  * Converts entity instance to POJO, converting the `Collection`s to arrays and unwrapping the `Reference` wrapper, while respecting the serialization options.
@@ -248,8 +242,8 @@ export class EntitySerializer {
248
242
  * ```
249
243
  */
250
244
  export function serialize(entities, options) {
251
- if (Array.isArray(entities)) {
252
- return entities.map(e => EntitySerializer.serialize(e, options));
253
- }
254
- return EntitySerializer.serialize(entities, options);
245
+ if (Array.isArray(entities)) {
246
+ return entities.map(e => EntitySerializer.serialize(e, options));
247
+ }
248
+ return EntitySerializer.serialize(entities, options);
255
249
  }
@@ -1,14 +1,10 @@
1
1
  import type { EntityDTO, EntityKey } from '../typings.js';
2
2
  /** Converts entity instances to plain objects via `toObject()`, respecting populate hints, hidden fields, and serialization context. */
3
3
  export declare class EntityTransformer {
4
- /** Converts an entity to a plain object, respecting populate hints, hidden fields, and custom serializers. */
5
- static toObject<Entity extends object, Ignored extends EntityKey<Entity> = never>(
6
- entity: Entity,
7
- ignoreFields?: Ignored[],
8
- raw?: boolean,
9
- ): Omit<EntityDTO<Entity>, Ignored>;
10
- private static propertyName;
11
- private static processProperty;
12
- private static processEntity;
13
- private static processCollection;
4
+ /** Converts an entity to a plain object, respecting populate hints, hidden fields, and custom serializers. */
5
+ static toObject<Entity extends object, Ignored extends EntityKey<Entity> = never>(entity: Entity, ignoreFields?: Ignored[], raw?: boolean): Omit<EntityDTO<Entity>, Ignored>;
6
+ private static propertyName;
7
+ private static processProperty;
8
+ private static processEntity;
9
+ private static processCollection;
14
10
  }