@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.
- package/EntityManager.d.ts +884 -583
- package/EntityManager.js +1922 -1895
- package/MikroORM.d.ts +103 -74
- package/MikroORM.js +178 -179
- package/README.md +1 -1
- package/cache/CacheAdapter.d.ts +36 -36
- package/cache/FileCacheAdapter.d.ts +30 -24
- package/cache/FileCacheAdapter.js +80 -78
- package/cache/GeneratedCacheAdapter.d.ts +18 -20
- package/cache/GeneratedCacheAdapter.js +30 -30
- package/cache/MemoryCacheAdapter.d.ts +18 -20
- package/cache/MemoryCacheAdapter.js +35 -36
- package/cache/NullCacheAdapter.d.ts +16 -16
- package/cache/NullCacheAdapter.js +24 -24
- package/connections/Connection.d.ts +95 -84
- package/connections/Connection.js +165 -168
- package/drivers/DatabaseDriver.d.ts +186 -80
- package/drivers/DatabaseDriver.js +450 -443
- package/drivers/IDatabaseDriver.d.ts +440 -301
- package/entity/BaseEntity.d.ts +120 -83
- package/entity/BaseEntity.js +43 -43
- package/entity/Collection.d.ts +212 -179
- package/entity/Collection.js +727 -721
- package/entity/EntityAssigner.d.ts +88 -77
- package/entity/EntityAssigner.js +231 -230
- package/entity/EntityFactory.d.ts +66 -54
- package/entity/EntityFactory.js +425 -383
- package/entity/EntityHelper.d.ts +34 -22
- package/entity/EntityHelper.js +280 -267
- package/entity/EntityIdentifier.d.ts +4 -4
- package/entity/EntityIdentifier.js +10 -10
- package/entity/EntityLoader.d.ts +98 -72
- package/entity/EntityLoader.js +753 -723
- package/entity/EntityRepository.d.ts +316 -201
- package/entity/EntityRepository.js +213 -213
- package/entity/PolymorphicRef.d.ts +5 -5
- package/entity/PolymorphicRef.js +10 -10
- package/entity/Reference.d.ts +126 -82
- package/entity/Reference.js +278 -274
- package/entity/WrappedEntity.d.ts +115 -72
- package/entity/WrappedEntity.js +168 -166
- package/entity/defineEntity.d.ts +1315 -636
- package/entity/defineEntity.js +527 -518
- package/entity/utils.d.ts +13 -3
- package/entity/utils.js +71 -73
- package/entity/validators.js +43 -43
- package/entity/wrap.js +8 -8
- package/enums.d.ts +258 -253
- package/enums.js +251 -252
- package/errors.d.ts +114 -72
- package/errors.js +350 -253
- package/events/EventManager.d.ts +26 -14
- package/events/EventManager.js +79 -77
- package/events/EventSubscriber.d.ts +29 -29
- package/events/TransactionEventBroadcaster.d.ts +15 -8
- package/events/TransactionEventBroadcaster.js +14 -14
- package/exceptions.d.ts +23 -40
- package/exceptions.js +35 -52
- package/hydration/Hydrator.d.ts +42 -17
- package/hydration/Hydrator.js +43 -43
- package/hydration/ObjectHydrator.d.ts +50 -17
- package/hydration/ObjectHydrator.js +481 -416
- package/index.d.ts +116 -2
- package/index.js +10 -1
- package/logging/DefaultLogger.d.ts +34 -32
- package/logging/DefaultLogger.js +86 -86
- package/logging/Logger.d.ts +41 -41
- package/logging/SimpleLogger.d.ts +13 -11
- package/logging/SimpleLogger.js +22 -22
- package/logging/colors.d.ts +6 -6
- package/logging/colors.js +11 -10
- package/logging/inspect.js +7 -7
- package/metadata/EntitySchema.d.ts +211 -127
- package/metadata/EntitySchema.js +397 -398
- package/metadata/MetadataDiscovery.d.ts +114 -114
- package/metadata/MetadataDiscovery.js +1951 -1863
- package/metadata/MetadataProvider.d.ts +24 -21
- package/metadata/MetadataProvider.js +82 -84
- package/metadata/MetadataStorage.d.ts +38 -32
- package/metadata/MetadataStorage.js +118 -118
- package/metadata/MetadataValidator.d.ts +39 -39
- package/metadata/MetadataValidator.js +381 -338
- package/metadata/discover-entities.d.ts +5 -2
- package/metadata/discover-entities.js +35 -27
- package/metadata/types.d.ts +615 -531
- package/naming-strategy/AbstractNamingStrategy.d.ts +54 -39
- package/naming-strategy/AbstractNamingStrategy.js +90 -85
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +6 -6
- package/naming-strategy/EntityCaseNamingStrategy.js +22 -22
- package/naming-strategy/MongoNamingStrategy.d.ts +6 -6
- package/naming-strategy/MongoNamingStrategy.js +18 -18
- package/naming-strategy/NamingStrategy.d.ts +109 -99
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
- package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
- package/not-supported.js +7 -4
- package/package.json +1 -1
- package/platforms/ExceptionConverter.d.ts +1 -1
- package/platforms/ExceptionConverter.js +4 -4
- package/platforms/Platform.d.ts +310 -299
- package/platforms/Platform.js +663 -636
- package/serialization/EntitySerializer.d.ts +49 -26
- package/serialization/EntitySerializer.js +224 -218
- package/serialization/EntityTransformer.d.ts +10 -6
- package/serialization/EntityTransformer.js +219 -217
- package/serialization/SerializationContext.d.ts +27 -23
- package/serialization/SerializationContext.js +105 -105
- package/types/ArrayType.d.ts +8 -8
- package/types/ArrayType.js +33 -33
- package/types/BigIntType.d.ts +17 -10
- package/types/BigIntType.js +37 -37
- package/types/BlobType.d.ts +3 -3
- package/types/BlobType.js +13 -13
- package/types/BooleanType.d.ts +4 -4
- package/types/BooleanType.js +12 -12
- package/types/CharacterType.d.ts +2 -2
- package/types/CharacterType.js +6 -6
- package/types/DateTimeType.d.ts +5 -5
- package/types/DateTimeType.js +15 -15
- package/types/DateType.d.ts +5 -5
- package/types/DateType.js +15 -15
- package/types/DecimalType.d.ts +7 -7
- package/types/DecimalType.js +26 -26
- package/types/DoubleType.d.ts +3 -3
- package/types/DoubleType.js +12 -12
- package/types/EnumArrayType.d.ts +5 -5
- package/types/EnumArrayType.js +24 -24
- package/types/EnumType.d.ts +3 -3
- package/types/EnumType.js +11 -11
- package/types/FloatType.d.ts +3 -3
- package/types/FloatType.js +9 -9
- package/types/IntegerType.d.ts +3 -3
- package/types/IntegerType.js +9 -9
- package/types/IntervalType.d.ts +4 -4
- package/types/IntervalType.js +12 -12
- package/types/JsonType.d.ts +8 -8
- package/types/JsonType.js +32 -32
- package/types/MediumIntType.d.ts +1 -1
- package/types/MediumIntType.js +3 -3
- package/types/SmallIntType.d.ts +3 -3
- package/types/SmallIntType.js +9 -9
- package/types/StringType.d.ts +4 -4
- package/types/StringType.js +12 -12
- package/types/TextType.d.ts +3 -3
- package/types/TextType.js +9 -9
- package/types/TimeType.d.ts +5 -5
- package/types/TimeType.js +17 -17
- package/types/TinyIntType.d.ts +3 -3
- package/types/TinyIntType.js +10 -10
- package/types/Type.d.ts +83 -79
- package/types/Type.js +82 -82
- package/types/Uint8ArrayType.d.ts +4 -4
- package/types/Uint8ArrayType.js +21 -21
- package/types/UnknownType.d.ts +4 -4
- package/types/UnknownType.js +12 -12
- package/types/UuidType.d.ts +5 -5
- package/types/UuidType.js +19 -19
- package/types/index.d.ts +75 -49
- package/types/index.js +52 -26
- package/typings.d.ts +1250 -737
- package/typings.js +244 -231
- package/unit-of-work/ChangeSet.d.ts +26 -26
- package/unit-of-work/ChangeSet.js +56 -56
- package/unit-of-work/ChangeSetComputer.d.ts +12 -12
- package/unit-of-work/ChangeSetComputer.js +178 -170
- package/unit-of-work/ChangeSetPersister.d.ts +63 -44
- package/unit-of-work/ChangeSetPersister.js +442 -421
- package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
- package/unit-of-work/CommitOrderCalculator.js +89 -88
- package/unit-of-work/IdentityMap.d.ts +31 -31
- package/unit-of-work/IdentityMap.js +105 -105
- package/unit-of-work/UnitOfWork.d.ts +181 -141
- package/unit-of-work/UnitOfWork.js +1200 -1183
- package/utils/AbstractMigrator.d.ts +111 -91
- package/utils/AbstractMigrator.js +275 -275
- package/utils/AbstractSchemaGenerator.d.ts +43 -34
- package/utils/AbstractSchemaGenerator.js +121 -122
- package/utils/AsyncContext.d.ts +3 -3
- package/utils/AsyncContext.js +34 -35
- package/utils/Configuration.d.ts +852 -808
- package/utils/Configuration.js +359 -344
- package/utils/Cursor.d.ts +40 -22
- package/utils/Cursor.js +135 -127
- package/utils/DataloaderUtils.d.ts +58 -43
- package/utils/DataloaderUtils.js +203 -198
- package/utils/EntityComparator.d.ts +98 -81
- package/utils/EntityComparator.js +828 -728
- package/utils/NullHighlighter.d.ts +1 -1
- package/utils/NullHighlighter.js +3 -3
- package/utils/QueryHelper.d.ts +79 -51
- package/utils/QueryHelper.js +372 -361
- package/utils/RawQueryFragment.d.ts +50 -34
- package/utils/RawQueryFragment.js +107 -105
- package/utils/RequestContext.d.ts +32 -32
- package/utils/RequestContext.js +52 -53
- package/utils/TransactionContext.d.ts +16 -16
- package/utils/TransactionContext.js +27 -27
- package/utils/TransactionManager.d.ts +58 -58
- package/utils/TransactionManager.js +199 -197
- package/utils/Utils.d.ts +204 -145
- package/utils/Utils.js +812 -810
- package/utils/clone.js +104 -113
- package/utils/env-vars.js +90 -88
- package/utils/fs-utils.d.ts +15 -15
- package/utils/fs-utils.js +180 -181
- package/utils/upsert-utils.d.ts +20 -5
- package/utils/upsert-utils.js +114 -116
|
@@ -1,33 +1,45 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ArrayElement,
|
|
3
|
+
AutoPath,
|
|
4
|
+
CleanTypeConfig,
|
|
5
|
+
ExtractFieldsHint,
|
|
6
|
+
FromEntityType,
|
|
7
|
+
SerializeDTO,
|
|
8
|
+
TypeConfig,
|
|
9
|
+
UnboxArray,
|
|
10
|
+
} from '../typings.js';
|
|
2
11
|
import { type PopulatePath } from '../enums.js';
|
|
3
12
|
/** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
|
|
4
13
|
export declare class EntitySerializer {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
/** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
|
|
15
|
+
static serialize<T extends object, P extends string = never, E extends string = never>(
|
|
16
|
+
entity: T,
|
|
17
|
+
options?: SerializeOptions<T, P, E>,
|
|
18
|
+
): SerializeDTO<T, P, E>;
|
|
19
|
+
private static propertyName;
|
|
20
|
+
private static processProperty;
|
|
21
|
+
private static processCustomType;
|
|
22
|
+
private static extractChildOptions;
|
|
23
|
+
private static processEntity;
|
|
24
|
+
private static processCollection;
|
|
13
25
|
}
|
|
14
26
|
export interface SerializeOptions<T, P extends string = never, E extends string = never> {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
/** Specify which relation should be serialized as populated and which as a FK. */
|
|
28
|
+
populate?: readonly AutoPath<T, P, `${PopulatePath.ALL}`>[];
|
|
29
|
+
/** Specify which properties should be omitted. */
|
|
30
|
+
exclude?: readonly AutoPath<T, E>[];
|
|
31
|
+
/** Enforce unpopulated references to be returned as objects, e.g. `{ author: { id: 1 } }` instead of `{ author: 1 }`. */
|
|
32
|
+
forceObject?: boolean;
|
|
33
|
+
/** Ignore custom property serializers. */
|
|
34
|
+
ignoreSerializers?: boolean;
|
|
35
|
+
/** Include properties marked as `hidden`. */
|
|
36
|
+
includeHidden?: boolean;
|
|
37
|
+
/** Skip properties with `null` value. */
|
|
38
|
+
skipNull?: boolean;
|
|
39
|
+
/** 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. */
|
|
40
|
+
groups?: string[];
|
|
41
|
+
/** Convert custom types to their database representation. By default, the `Type.toJSON` method is invoked instead. */
|
|
42
|
+
convertCustomTypes?: boolean;
|
|
31
43
|
}
|
|
32
44
|
/**
|
|
33
45
|
* Converts entity instance to POJO, converting the `Collection`s to arrays and unwrapping the `Reference` wrapper, while respecting the serialization options.
|
|
@@ -41,4 +53,15 @@ export interface SerializeOptions<T, P extends string = never, E extends string
|
|
|
41
53
|
* const dto2 = wrap(user).serialize({ exclude: ['id', 'email'], forceObject: true });
|
|
42
54
|
* ```
|
|
43
55
|
*/
|
|
44
|
-
export declare function serialize<
|
|
56
|
+
export declare function serialize<
|
|
57
|
+
Entity extends object,
|
|
58
|
+
Naked extends FromEntityType<Entity> = FromEntityType<Entity>,
|
|
59
|
+
Populate extends string = never,
|
|
60
|
+
Exclude extends string = never,
|
|
61
|
+
Config extends TypeConfig = never,
|
|
62
|
+
>(
|
|
63
|
+
entity: Entity,
|
|
64
|
+
options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>,
|
|
65
|
+
): Naked extends object[]
|
|
66
|
+
? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>>[]
|
|
67
|
+
: SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>, ExtractFieldsHint<Entity>>;
|
|
@@ -5,229 +5,235 @@ 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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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;
|
|
22
24
|
}
|
|
23
25
|
function isPopulated(propName, options) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return
|
|
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;
|
|
32
36
|
}
|
|
33
37
|
/** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
|
|
34
38
|
export class EntitySerializer {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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;
|
|
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;
|
|
118
53
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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);
|
|
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));
|
|
170
61
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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);
|
|
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
|
+
}
|
|
212
74
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
+
}
|
|
122
|
+
}
|
|
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;
|
|
129
|
+
}
|
|
130
|
+
if (meta.properties[prop]?.primary && meta.serializedPrimaryKey) {
|
|
131
|
+
return meta.serializedPrimaryKey;
|
|
132
|
+
}
|
|
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);
|
|
230
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;
|
|
180
|
+
}
|
|
181
|
+
if (convertCustomTypes) {
|
|
182
|
+
return prop.customType.convertToDatabaseValue(value, platform, { mode: 'serialization' });
|
|
183
|
+
}
|
|
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);
|
|
205
|
+
}
|
|
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);
|
|
209
|
+
}
|
|
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;
|
|
216
|
+
}
|
|
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;
|
|
223
|
+
}
|
|
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
|
+
}
|
|
231
237
|
}
|
|
232
238
|
/**
|
|
233
239
|
* Converts entity instance to POJO, converting the `Collection`s to arrays and unwrapping the `Reference` wrapper, while respecting the serialization options.
|
|
@@ -242,8 +248,8 @@ export class EntitySerializer {
|
|
|
242
248
|
* ```
|
|
243
249
|
*/
|
|
244
250
|
export function serialize(entities, options) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
251
|
+
if (Array.isArray(entities)) {
|
|
252
|
+
return entities.map(e => EntitySerializer.serialize(e, options));
|
|
253
|
+
}
|
|
254
|
+
return EntitySerializer.serialize(entities, options);
|
|
249
255
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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;
|
|
10
14
|
}
|