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

satanTime / ngrx-entity-relationship / 475a6fe6-862e-42f9-b95e-23a40dfab79b

26 Jan 2024 01:24AM CUT coverage: 100.0%. Remained the same
475a6fe6-862e-42f9-b95e-23a40dfab79b

Pull #2048

circleci

web-flow
chore(deps): update dependency husky to v9
Pull Request #2048: chore(deps): update dependency husky to v9

443 of 443 branches covered (100.0%)

Branch coverage included in aggregate %.

680 of 680 relevant lines covered (100.0%)

33.45 hits per line

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

100.0
/libs/ngrx-entity-relationship/graphql/src/lib/toGraphQL.ts
1
import {ENTITY_SELECTOR} from 'ngrx-entity-relationship';
2

3
const resolveGraphQL = (
1✔
4
    selector: ENTITY_SELECTOR,
5
    options: {
6
        include: Array<keyof any>;
7
        prefix: string;
8
        level: number;
9
    },
10
) => {
11
    const prefix = options.prefix ? options.prefix.repeat(options.level) : '';
48✔
12
    let query = '';
48✔
13
    const included: Array<string | number> = [];
48✔
14
    for (const relationship of selector.relationships) {
48✔
15
        // istanbul ignore if
16
        if (typeof relationship.keyId !== 'string' && typeof relationship.keyId !== 'number') {
34✔
17
            continue;
18
        }
19
        // istanbul ignore if
20
        if (typeof relationship.keyValue !== 'string' && typeof relationship.keyValue !== 'number') {
34✔
21
            continue;
22
        }
23
        if (relationship.ngrxEntityRelationship === 'childrenEntities') {
34✔
24
            included.push(relationship.keyValue);
10✔
25
            query += `${prefix}${relationship.keyValue}`;
10✔
26
            query += `${prefix ? ' ' : ''}{${prefix ? '\n' : ''}${resolveGraphQL(relationship, {
10✔
27
                include: [relationship.keyId],
28
                prefix: options.prefix,
29
                level: options.level + 1,
30
            })}${prefix}}${prefix ? '\n' : ''}`;
10✔
31
        } else if (relationship.ngrxEntityRelationship === 'childEntity') {
24✔
32
            included.push(relationship.keyValue);
13✔
33
            query += `${prefix}${relationship.keyValue}`;
13✔
34
            query += `${prefix ? ' ' : ''}{${prefix ? '\n' : ''}${resolveGraphQL(relationship, {
13✔
35
                include: [relationship.keyId],
36
                prefix: options.prefix,
37
                level: options.level + 1,
38
            })}${prefix}}${prefix ? '\n' : ''}`;
13✔
39
        } else {
40
            included.push(relationship.keyId);
11✔
41
            included.push(relationship.keyValue);
11✔
42
            query += `${prefix}${relationship.keyId}`;
11✔
43
            query += `\n${prefix}${relationship.keyValue}`;
11✔
44
            query += `${prefix ? ' ' : ''}{${prefix ? '\n' : ''}${resolveGraphQL(relationship, {
11✔
45
                include: [],
46
                prefix: options.prefix,
47
                level: options.level + 1,
48
            })}${prefix}}${prefix ? '\n' : ''}`;
11✔
49
        }
50
    }
51
    for (const field of options.include) {
48✔
52
        // istanbul ignore if
53
        if (typeof field !== 'string' && typeof field !== 'number') {
23✔
54
            continue;
55
        }
56
        // istanbul ignore if
57
        if (included.indexOf(field) !== -1) {
23✔
58
            continue;
59
        }
60
        included.push(field);
23✔
61
        query += `${prefix}${field}\n`;
23✔
62
    }
63
    if (Array.isArray(selector.meta.gqlFields)) {
48✔
64
        for (const field of selector.meta.gqlFields) {
37✔
65
            if (included.indexOf(field) !== -1) {
114✔
66
                continue;
10✔
67
            }
68
            included.push(field);
104✔
69
            query += `${prefix}${field}\n`;
104✔
70
        }
71
    } else if (selector.meta.gqlFields) {
11✔
72
        for (const field of Object.keys(selector.meta.gqlFields)) {
1✔
73
            if (included.indexOf(field) !== -1) {
5✔
74
                continue;
1✔
75
            }
76
            included.push(field);
4✔
77
            query += `${prefix}${field}${selector.meta.gqlFields[field]}\n`;
4✔
78
        }
79
    }
80
    return query;
48✔
81
};
82

83
function encodeValuePrimitives(data: any): string | undefined {
84
    if (typeof data === 'number') {
26✔
85
        return JSON.stringify(data);
4✔
86
    }
87
    if (typeof data === 'string') {
22✔
88
        return JSON.stringify(data);
7✔
89
    }
90
    if (typeof data === 'boolean') {
15✔
91
        return JSON.stringify(data);
5✔
92
    }
93

94
    return undefined;
10✔
95
}
96

97
function encodeValue(data: any): string | undefined {
98
    const primitives = encodeValuePrimitives(data);
26✔
99
    if (primitives !== undefined) {
26✔
100
        return primitives;
16✔
101
    }
102

103
    if (data === null || data === undefined) {
10✔
104
        return JSON.stringify(null);
4✔
105
    }
106
    if (typeof data === 'function') {
6✔
107
        return undefined;
2✔
108
    }
109
    if (Array.isArray(data)) {
4✔
110
        return `[${data
2✔
111
            .map(encodeValue)
112
            .filter(v => v !== undefined)
6✔
113
            .join(',')}]`;
114
    }
115
    const fields: Array<string> = [];
2✔
116
    for (const key of Object.keys(data)) {
2✔
117
        const value = encodeValue(data[key]);
9✔
118
        if (value === undefined) {
9✔
119
            continue;
1✔
120
        }
121
        fields.push(`${key}:${value}`);
8✔
122
    }
123
    return `{${fields.join(',')}}`;
2✔
124
}
125

126
export function toGraphQL(...queries: Array<string>): string;
127
export function toGraphQL(query: string, params: object, selector: ENTITY_SELECTOR): string;
128
export function toGraphQL(query: string, selector: ENTITY_SELECTOR): string;
129
export function toGraphQL(selector: ENTITY_SELECTOR): string;
130

131
export function toGraphQL(...queries: Array<any>): string {
132
    const prefix = (window as any).ngrxGraphqlPrefix || '';
17✔
133
    let query: string | undefined = '';
17✔
134
    let selector: ENTITY_SELECTOR | undefined;
135
    let params: Record<string, any> | null | string | undefined;
136
    if (queries.length >= 2 && typeof queries[1] !== 'string') {
17✔
137
        if (queries[2] && typeof queries[2] !== 'string') {
14✔
138
            [query, params, selector] = queries;
7✔
139
        } else {
140
            [query, selector] = queries;
7✔
141
        }
142
    } else if (queries.length === 1 && typeof queries[0] !== 'string') {
3✔
143
        [selector] = queries;
1✔
144
        query = undefined;
1✔
145
    }
146

147
    const stringParams: Array<string> = [];
17✔
148
    if (params && typeof params === 'object') {
17✔
149
        for (const key of Object.keys(params)) {
7✔
150
            if (key === '$') {
16✔
151
                continue;
5✔
152
            }
153
            const value = encodeValue(params[key]);
11✔
154
            if (value === undefined) {
11✔
155
                continue;
1✔
156
            }
157
            stringParams.push(`${key}:${prefix ? ' ' : ''}${value}`);
10✔
158
        }
159
    }
160
    if (params && typeof params === 'object' && params.$ && typeof params.$ === 'object') {
17✔
161
        const params$ = params.$;
4✔
162
        for (const key of Object.keys(params$)) {
4✔
163
            if (typeof params$[key] !== 'string' || params$[key][0] !== '$') {
5✔
164
                throw new Error(`${key} should be a variable that starts with $ symbol`);
1✔
165
            }
166
            stringParams.push(`${key}:${prefix ? ' ' : ''}${params$[key]}`);
4✔
167
        }
168
    }
169
    params = stringParams.length ? `(${stringParams.join(`,${prefix ? ' ' : ''}`)})` : '';
16✔
170

171
    if (selector) {
16✔
172
        let gql = resolveGraphQL(selector, {
14✔
173
            include: [],
174
            prefix: `${prefix}`,
175
            level: 2,
176
        });
177

178
        if (query === undefined) {
14✔
179
            return gql;
1✔
180
        }
181

182
        gql = `{\n${gql}${prefix}}`;
13✔
183

184
        return query ? `{\n${prefix}${query}${params}${prefix ? ' ' : ''}${gql}\n}` : gql;
13✔
185
    }
186
    const parts: Array<string> = [];
2✔
187
    for (let part of queries) {
2✔
188
        if (typeof part !== 'string') {
10✔
189
            continue;
5✔
190
        }
191
        part = part.trim();
5✔
192
        if (part.substr(0, 1) === '{' && part.substr(part.length - 1, 1) === '}') {
5✔
193
            part = part.substr(1, part.length - 2);
2✔
194
        }
195
        parts.push(part.trim());
5✔
196
    }
197

198
    return `{${parts.join('\n')}}`;
2✔
199
}
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