-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathedmx-to-vdm-util.ts
180 lines (161 loc) · 5.48 KB
/
edmx-to-vdm-util.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import { createLogger, last } from '@sap-cloud-sdk/util';
import { EdmxMetadata } from '../edmx-parser/edmx-file-reader';
import { EdmxProperty } from '../edmx-parser/common';
import {
edmToFieldType,
edmToTsType,
getFallbackEdmTypeIfNeeded
} from '../generator-utils';
import { VdmComplexType, VdmEnumType, VdmMappedEdmType } from '../vdm-types';
import { EdmxAction, EdmxFunction } from '../edmx-parser/v4';
import { EdmxFunctionImport } from '../edmx-parser/v2';
import {
complexTypeForName,
enumTypeForName,
findComplexType,
findEnumType
} from './common';
const logger = createLogger({
package: 'generator',
messageContext: 'edmx-to-vdm-util'
});
export function stripNamespace(name: string): string {
const nameParts = name.split('.');
return nameParts[nameParts.length - 1];
}
export function isCollectionType(typeName: string): boolean {
return collectionRegExp.test(typeName);
}
export function isEdmType(typeName: string): boolean {
return typeName.startsWith('Edm');
}
export function complexTypeName(type: string): string | undefined {
return last(type.split('.'));
}
export const collectionRegExp = /Collection\((?<collectionType>.*)\)/;
/**
* @deprecated since version 1.27.0. Use [[isEdmType]] and [[complexTypeName]] if you want to extract type names of non Edm types.
* @param typeName Name of the edm type for example "Edm.String" or "Namespace.ComplexType"
* @returns the typename input for Edm types e.g. "Edm.String" or the type without the namesapce.
*/
export function parseType(typeName: string): string {
return typeName.startsWith('Edm')
? typeName
: typeName.split('.')[typeName.split('.').length - 1];
}
export function parseTypeName(typeName: string): string {
return isCollectionType(typeName)
? parseCollectionTypeName(typeName)
: typeName;
}
export function parseCollectionTypeName(typeName: string): string {
const name = typeName.match(collectionRegExp)?.groups?.collectionType;
if (!name) {
throw new Error(`Cannot parse type name ${typeName}.`);
}
return name;
}
export function isV2Metadata(metadata: EdmxMetadata): boolean {
return metadata.oDataVersion === 'v2';
}
export function isComplexTypeOrEnumType(typeName: string): boolean {
const typeParts = typeName.split('.');
return typeParts[0] !== 'Edm' && typeParts[1] !== undefined;
}
export function isComplexType(
name: string,
complexTypes: Omit<VdmComplexType, 'factoryName'>[]
): boolean {
return isComplexTypeOrEnumType(name)
? !!findComplexType(name, complexTypes)
: false;
}
export function isEnumType(name: string, enumTypes: VdmEnumType[]): boolean {
return isComplexTypeOrEnumType(name)
? !!findEnumType(name, enumTypes)
: false;
}
export function checkCollectionKind(property: EdmxProperty) {
if (property.hasOwnProperty('CollectionKind')) {
logger.warn(
`"CollectionKind" attribute found in the "${property.Name}" property. Currently, handling collection of properties is not supported by the generator.`
);
}
}
export function complexTypeFieldType(typeName: string) {
return typeName + 'Field';
}
export function getTypeMappingActionFunction(
typeName: string
): VdmMappedEdmType {
if (isEdmType(typeName)) {
const edmFallback = getFallbackEdmTypeIfNeeded(typeName);
return {
edmType: edmFallback,
jsType: edmToTsType(edmFallback),
fieldType: edmToFieldType(edmFallback)
};
}
throw new Error(
`Tries to get a action/function parameter with type ${typeName} which is not a Edm type.`
);
}
export function typesForCollection(
typeName: string,
enumTypes: VdmEnumType[],
complexTypes?: Omit<VdmComplexType, 'factoryName'>[],
formattedTypes?: Record<string, any>
): VdmMappedEdmType {
const typeInsideCollection = parseCollectionTypeName(typeName);
if (isEdmType(typeInsideCollection)) {
const typeEdm = getFallbackEdmTypeIfNeeded(typeInsideCollection);
return {
edmType: typeEdm,
jsType: edmToTsType(typeEdm),
fieldType: 'CollectionField'
};
}
if (isComplexTypeOrEnumType(typeInsideCollection)) {
if (isEnumType(typeInsideCollection, enumTypes)) {
return {
edmType: typeInsideCollection,
jsType: enumTypeForName(typeInsideCollection, enumTypes),
fieldType: 'CollectionField'
};
}
const typeComplex =
complexTypeName(typeInsideCollection) || typeInsideCollection;
return {
edmType: typeInsideCollection,
jsType: complexTypes
? complexTypeForName(typeInsideCollection, complexTypes)
: formattedTypes![typeComplex],
fieldType: 'CollectionField'
};
}
throw new Error(
'Types in inside a collection must be either have complex or edm types'
);
}
export const propertyJsType = (type: string): string | undefined =>
type.startsWith('Edm.') ? edmToTsType(type) : undefined;
export function hasUnsupportedParameterTypes(
functionOrAction: EdmxAction | EdmxFunction | EdmxFunctionImport
): boolean {
const unsupportedParameters = functionOrAction.Parameter.filter(
p => !isEdmType(p.Type)
);
if (unsupportedParameters.length > 0) {
logger.warn(
`Unsupported function or action import parameter types "${unsupportedParameters
.map(p => p.Type)
.join(
', '
)}" found, which is used by the function import or action import "${
functionOrAction.Name
}". The SAP Cloud SDK currently only supports Edm types in parameters. Skipping code generation for function/action import.`
);
return true;
}
return false;
}