-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathget-select.ts
59 lines (52 loc) · 1.95 KB
/
get-select.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { EntityV2 } from '../entity';
import { Selectable, Link } from '../../odata-common';
/**
* Get an object containing the given Selectables as query parameter, or an empty object if none were given.
* This retrieves where in addition to the selection (`select`) there is also an expansion (`expand`) needed.
*
* @typeparam EntityT - Type of the entity to get the selection for
* @param selects - The list of selectables to be transformed to query parameters
* @returns An object containing the query parameters or an empty object
*/
export function getSelectV2<EntityT extends EntityV2>(
selects: Selectable<EntityT>[] = []
): Partial<{ select: string }> {
const select = getSelectsAsStrings(selects);
return select.length ? { select: filterSelects(select).join(',') } : {};
}
function selectionLevel(select: string): string {
return select.split('/').slice(0, -1).join('/');
}
function filterSelects(selects: string[]): string[] {
const allFieldSelects = selects.filter(select => select.endsWith('*'));
const selectionLevels = allFieldSelects.map(select => selectionLevel(select));
return [
...allFieldSelects,
...selects.filter(
select => !selectionLevels.includes(selectionLevel(select))
)
];
}
function getSelectsAsStrings<EntityT extends EntityV2>(
selectables: Selectable<EntityT>[],
initialSelect: string[] = [],
parent = ''
): string[] {
return selectables.reduce((select: string[], selectable) => {
const fullFieldName = getPath(parent, selectable._fieldName);
if (selectable instanceof Link) {
if (selectable._selects.length) {
return getSelectsAsStrings(selectable._selects, select, fullFieldName);
}
return [...select, `${fullFieldName}/*`];
}
return [...select, fullFieldName];
}, initialSelect);
}
function getPath(parent: string, fieldName: string): string {
if (parent) {
return `${parent}/${fieldName}`;
}
return fieldName;
}
export { getSelectV2 as getSelect };