• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

typeorm / typeorm / 14796576772

02 May 2025 01:52PM UTC coverage: 45.367% (-30.9%) from 76.309%
14796576772

Pull #11434

github

web-flow
Merge ec4ce2d00 into fadad1a74
Pull Request #11434: feat: release PR releases using pkg.pr.new

5216 of 12761 branches covered (40.87%)

Branch coverage included in aggregate %.

11439 of 23951 relevant lines covered (47.76%)

15712.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.39
/src/query-builder/transformer/DocumentToEntityTransformer.ts
1
import { EntityMetadata } from "../../metadata/EntityMetadata"
2
import { ObjectLiteral } from "../../common/ObjectLiteral"
3
import { EmbeddedMetadata } from "../../metadata/EmbeddedMetadata"
4

5
/**
6
 * Transforms raw document into entity object.
7
 * Entity is constructed based on its entity metadata.
8
 */
9
export class DocumentToEntityTransformer {
4✔
10
    // -------------------------------------------------------------------------
11
    // Constructor
12
    // -------------------------------------------------------------------------
13

14
    constructor(
15
        // private selectionMap: AliasMap,
16
        // private joinMappings: JoinMapping[],
17
        // private relationCountMetas: RelationCountAttribute[],
18
        private enableRelationIdValues: boolean = false,
×
19
    ) {}
20

21
    // -------------------------------------------------------------------------
22
    // Public Methods
23
    // -------------------------------------------------------------------------
24

25
    transformAll(documents: ObjectLiteral[], metadata: EntityMetadata) {
26
        return documents.map((document) => this.transform(document, metadata))
×
27
    }
28

29
    transform(document: any, metadata: EntityMetadata) {
30
        const entity: any = metadata.create(undefined, {
×
31
            fromDeserializer: true,
32
        })
33
        let hasData = false
×
34

35
        // handle _id property the special way
36
        if (metadata.objectIdColumn) {
×
37
            // todo: we can't use driver in this class
38
            // do we really need prepare hydrated value here? If no then no problem. If yes then think maybe prepareHydratedValue process should be extracted out of driver class?
39
            // entity[metadata.ObjectIdColumn.propertyName] = this.driver.prepareHydratedValue(document[metadata.ObjectIdColumn.name"], metadata.ObjectIdColumn);
40
            const { databaseNameWithoutPrefixes, propertyName } =
41
                metadata.objectIdColumn
×
42

43
            const documentIdWithoutPrefixes =
44
                document[databaseNameWithoutPrefixes]
×
45
            const documentIdWithPropertyName = document[propertyName]
×
46

47
            if (documentIdWithoutPrefixes) {
×
48
                entity[propertyName] = documentIdWithoutPrefixes
×
49
                hasData = true
×
50
            } else if (documentIdWithPropertyName) {
×
51
                entity[propertyName] = documentIdWithPropertyName
×
52
                hasData = true
×
53
            }
54
        }
55

56
        // add special columns that contains relation ids
57
        if (this.enableRelationIdValues) {
×
58
            metadata.columns
×
59
                .filter((column) => !!column.relationMetadata)
×
60
                .forEach((column) => {
61
                    const valueInObject =
62
                        document[column.databaseNameWithoutPrefixes]
×
63
                    if (
×
64
                        valueInObject !== undefined &&
×
65
                        valueInObject !== null &&
66
                        column.propertyName
67
                    ) {
68
                        // todo: we can't use driver in this class
69
                        // const value = this.driver.prepareHydratedValue(valueInObject, column);
70
                        entity[column.propertyName] = valueInObject
×
71
                        hasData = true
×
72
                    }
73
                })
74
        }
75

76
        /*this.joinMappings
77
            .filter(joinMapping => joinMapping.parentName === alias.name && !joinMapping.alias.relationOwnerSelection && joinMapping.alias.target)
78
            .map(joinMapping => {
79
                const relatedEntities = this.transformRawResultsGroup(rawSqlResults, joinMapping.alias);
80
                const isResultArray = joinMapping.isMany;
81
                const result = !isResultArray ? relatedEntities[0] : relatedEntities;
82

83
                if (result && (!isResultArray || result.length > 0)) {
84
                    entity[joinMapping.propertyName] = result;
85
                    hasData = true;
86
                }
87
            });*/
88

89
        // get value from columns selections and put them into object
90
        metadata.ownColumns.forEach((column) => {
×
91
            const valueInObject = document[column.databaseNameWithoutPrefixes]
×
92
            if (
×
93
                valueInObject !== undefined &&
×
94
                column.propertyName &&
95
                !column.isVirtual
96
            ) {
97
                // const value = this.driver.prepareHydratedValue(valueInObject, column);
98

99
                entity[column.propertyName] = valueInObject
×
100
                hasData = true
×
101
            }
102
        })
103

104
        const addEmbeddedValuesRecursively = (
×
105
            entity: any,
106
            document: any,
107
            embeddeds: EmbeddedMetadata[],
108
        ) => {
109
            embeddeds.forEach((embedded) => {
×
110
                if (!document[embedded.prefix]) return
×
111

112
                if (embedded.isArray) {
×
113
                    entity[embedded.propertyName] = (
×
114
                        document[embedded.prefix] as any[]
115
                    ).map((subValue: any, index: number) => {
116
                        const newItem = embedded.create({
×
117
                            fromDeserializer: true,
118
                        })
119
                        embedded.columns.forEach((column) => {
×
120
                            newItem[column.propertyName] =
×
121
                                subValue[column.databaseNameWithoutPrefixes]
122
                        })
123
                        addEmbeddedValuesRecursively(
×
124
                            newItem,
125
                            document[embedded.prefix][index],
126
                            embedded.embeddeds,
127
                        )
128
                        return newItem
×
129
                    })
130
                } else {
131
                    if (
×
132
                        embedded.embeddeds.length &&
×
133
                        !entity[embedded.propertyName]
134
                    )
135
                        entity[embedded.propertyName] = embedded.create({
×
136
                            fromDeserializer: true,
137
                        })
138

139
                    embedded.columns.forEach((column) => {
×
140
                        const value =
141
                            document[embedded.prefix][
×
142
                                column.databaseNameWithoutPrefixes
143
                            ]
144
                        if (value === undefined) return
×
145

146
                        if (!entity[embedded.propertyName])
×
147
                            entity[embedded.propertyName] = embedded.create({
×
148
                                fromDeserializer: true,
149
                            })
150

151
                        entity[embedded.propertyName][column.propertyName] =
×
152
                            value
153
                    })
154

155
                    addEmbeddedValuesRecursively(
×
156
                        entity[embedded.propertyName],
157
                        document[embedded.prefix],
158
                        embedded.embeddeds,
159
                    )
160
                }
161
            })
162
        }
163

164
        addEmbeddedValuesRecursively(entity, document, metadata.embeddeds)
×
165

166
        // if relation is loaded then go into it recursively and transform its values too
167
        /*metadata.relations.forEach(relation => {
168
            const relationAlias = this.selectionMap.findSelectionByParent(alias.name, relation.propertyName);
169
            if (relationAlias) {
170
                const joinMapping = this.joinMappings.find(joinMapping => joinMapping.type === "join" && joinMapping.alias === relationAlias);
171
                const relatedEntities = this.transformRawResultsGroup(rawSqlResults, relationAlias);
172
                const isResultArray = relation.isManyToMany || relation.isOneToMany;
173
                const result = !isResultArray ? relatedEntities[0] : relatedEntities;
174

175
                if (result) {
176
                    let propertyName = relation.propertyName;
177
                    if (joinMapping) {
178
                        propertyName = joinMapping.propertyName;
179
                    }
180

181
                    if (relation.isLazy) {
182
                        entity["__" + propertyName + "__"] = result;
183
                    } else {
184
                        entity[propertyName] = result;
185
                    }
186

187
                    if (!isResultArray || result.length > 0)
188
                        hasData = true;
189
                }
190
            }
191

192
            // if relation has id field then relation id/ids to that field.
193
            if (relation.isManyToMany) {
194
                if (relationAlias) {
195
                    const ids: any[] = [];
196
                    const joinMapping = this.joinMappings.find(joinMapping => joinMapping.type === "relationId" && joinMapping.alias === relationAlias);
197

198
                    if (relation.idField || joinMapping) {
199
                        const propertyName = joinMapping ? joinMapping.propertyName : relation.idField as string;
200
                        const junctionMetadata = relation.junctionEntityMetadata;
201
                        const columnName = relation.isOwning ? junctionMetadata.columns[1].name : junctionMetadata.columns[0].name;
202

203
                        rawSqlResults.forEach(results => {
204
                            if (relationAlias) {
205
                                const resultsKey = relationAlias.name + "_" + columnName;
206
                                const value = this.driver.prepareHydratedValue(results[resultsKey], relation.referencedColumn);
207
                                if (value !== undefined && value !== null)
208
                                    ids.push(value);
209
                            }
210
                        });
211

212
                        if (ids && ids.length)
213
                            entity[propertyName] = ids;
214
                    }
215
                }
216
            } else if (relation.idField) {
217
                const relationName = relation.name;
218
                entity[relation.idField] = this.driver.prepareHydratedValue(rawSqlResults[0][alias.name + "_" + relationName], relation.referencedColumn);
219
            }
220

221
            // if relation counter
222
            this.relationCountMetas.forEach(joinMeta => {
223
                if (joinMeta.alias === relationAlias) {
224
                    // console.log("relation count was found for relation: ", relation);
225
                    // joinMeta.entity = entity;
226
                    joinMeta.entities.push({ entity: entity, metadata: metadata });
227
                    // console.log(joinMeta);
228
                    // console.log("---------------------");
229
                }
230
            });
231
        });*/
232

233
        return hasData ? entity : null
×
234
    }
235
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc