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

typeorm / typeorm / 19549987525

20 Nov 2025 08:11PM UTC coverage: 80.769% (+4.3%) from 76.433%
19549987525

push

github

web-flow
ci: run tests on commits to master and next (#11783)

Co-authored-by: Oleg "OSA413" Sokolov <OSA413@users.noreply.github.com>

26500 of 32174 branches covered (82.36%)

Branch coverage included in aggregate %.

91252 of 113615 relevant lines covered (80.32%)

88980.79 hits per line

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

82.14
/src/query-builder/relation-count/RelationCountAttribute.ts
1
import { EntityMetadata } from "../../metadata/EntityMetadata"
26✔
2
import { QueryBuilderUtils } from "../QueryBuilderUtils"
26✔
3
import { RelationMetadata } from "../../metadata/RelationMetadata"
26✔
4
import { QueryExpressionMap } from "../QueryExpressionMap"
26✔
5
import { SelectQueryBuilder } from "../SelectQueryBuilder"
26✔
6
import { ObjectUtils } from "../../util/ObjectUtils"
26✔
7
import { TypeORMError } from "../../error/TypeORMError"
26✔
8

26✔
9
export class RelationCountAttribute {
26✔
10
    /**
26✔
11
     * Alias of the joined (destination) table.
26✔
12
     */
26✔
13
    alias?: string
26✔
14

26✔
15
    /**
26✔
16
     * Name of relation.
26✔
17
     */
26✔
18
    relationName: string
26✔
19

26✔
20
    /**
26✔
21
     * Property + alias of the object where to joined data should be mapped.
26✔
22
     */
26✔
23
    mapToProperty: string
26✔
24

26✔
25
    /**
26✔
26
     * Extra condition applied to "ON" section of join.
26✔
27
     */
26✔
28
    queryBuilderFactory?: (
26✔
29
        qb: SelectQueryBuilder<any>,
26✔
30
    ) => SelectQueryBuilder<any>
26✔
31

26✔
32
    // -------------------------------------------------------------------------
26✔
33
    // Constructor
26✔
34
    // -------------------------------------------------------------------------
26✔
35

26✔
36
    constructor(
26✔
37
        private expressionMap: QueryExpressionMap,
7,812✔
38
        relationCountAttribute?: Partial<RelationCountAttribute>,
7,812✔
39
    ) {
7,812✔
40
        ObjectUtils.assign(this, relationCountAttribute || {})
7,812✔
41
    }
7,812✔
42

26✔
43
    // -------------------------------------------------------------------------
26✔
44
    // Public Methods
26✔
45
    // -------------------------------------------------------------------------
26✔
46

26✔
47
    get joinInverseSideMetadata(): EntityMetadata {
26✔
48
        return this.relation.inverseEntityMetadata
2,632✔
49
    }
2,632✔
50

26✔
51
    /**
26✔
52
     * Alias of the parent of this join.
26✔
53
     * For example, if we join ("post.category", "categoryAlias") then "post" is a parent alias.
26✔
54
     * This value is extracted from entityOrProperty value.
26✔
55
     * This is available when join was made using "post.category" syntax.
26✔
56
     */
26✔
57
    get parentAlias(): string {
26✔
58
        if (!QueryBuilderUtils.isAliasProperty(this.relationName))
19,600✔
59
            throw new TypeORMError(
19,600!
60
                `Given value must be a string representation of alias property`,
×
61
            )
×
62

19,600✔
63
        return this.relationName.split(".")[0]
19,600✔
64
    }
19,600✔
65

26✔
66
    /**
26✔
67
     * Relation property name of the parent.
26✔
68
     * This is used to understand what is joined.
26✔
69
     * For example, if we join ("post.category", "categoryAlias") then "category" is a relation property.
26✔
70
     * This value is extracted from entityOrProperty value.
26✔
71
     * This is available when join was made using "post.category" syntax.
26✔
72
     */
26✔
73
    get relationProperty(): string | undefined {
26✔
74
        if (!QueryBuilderUtils.isAliasProperty(this.relationName))
×
75
            throw new TypeORMError(
×
76
                `Given value is a string representation of alias property`,
×
77
            )
×
78

×
79
        return this.relationName.split(".")[1]
×
80
    }
×
81

26✔
82
    get junctionAlias(): string {
26✔
83
        const [parentAlias, relationProperty] = this.relationName.split(".")
5,376✔
84
        return parentAlias + "_" + relationProperty + "_rc"
5,376✔
85
    }
5,376✔
86

26✔
87
    /**
26✔
88
     * Relation of the parent.
26✔
89
     * This is used to understand what is joined.
26✔
90
     * This is available when join was made using "post.category" syntax.
26✔
91
     */
26✔
92
    get relation(): RelationMetadata {
26✔
93
        if (!QueryBuilderUtils.isAliasProperty(this.relationName))
31,780✔
94
            throw new TypeORMError(
31,780!
95
                `Given value is a string representation of alias property`,
×
96
            )
×
97

31,780✔
98
        const [parentAlias, propertyPath] = this.relationName.split(".")
31,780✔
99
        const relationOwnerSelection =
31,780✔
100
            this.expressionMap.findAliasByName(parentAlias)
31,780✔
101
        const relation =
31,780✔
102
            relationOwnerSelection.metadata.findRelationWithPropertyPath(
31,780✔
103
                propertyPath,
31,780✔
104
            )
31,780✔
105
        if (!relation)
31,780✔
106
            throw new TypeORMError(
31,780!
107
                `Relation with property path ${propertyPath} in entity was not found.`,
×
108
            )
×
109
        return relation
31,780✔
110
    }
31,780✔
111

26✔
112
    /**
26✔
113
     * Metadata of the joined entity.
26✔
114
     * If table without entity was joined, then it will return undefined.
26✔
115
     */
26✔
116
    get metadata(): EntityMetadata {
26✔
117
        if (!QueryBuilderUtils.isAliasProperty(this.relationName))
×
118
            throw new TypeORMError(
×
119
                `Given value is a string representation of alias property`,
×
120
            )
×
121

×
122
        const parentAlias = this.relationName.split(".")[0]
×
123
        const selection = this.expressionMap.findAliasByName(parentAlias)
×
124
        return selection.metadata
×
125
    }
×
126

26✔
127
    get mapToPropertyPropertyName(): string {
26✔
128
        return this.mapToProperty!.split(".")[1]
10,892✔
129
    }
10,892✔
130
}
26✔
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

© 2026 Coveralls, Inc