-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathparameters.ts
92 lines (85 loc) · 2.78 KB
/
parameters.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
import { $Refs } from '@apidevtools/swagger-parser';
import {
camelCase,
filterDuplicatesRight,
partition
} from '@sap-cloud-sdk/util';
import { OpenAPIV3 } from 'openapi-types';
import { OpenApiParameter } from '../openapi-types';
import { resolveObject } from './refs';
import { getType } from './type-mapping';
/**
* Parse parameters of an operation.
* @param operation The original operation definition.
* @param refs List of cross references that can occur in the document.
* @returns A list of parsed parameters.
*/
export function parseParameters(
operation: OpenAPIV3.OperationObject,
refs: $Refs
): OpenApiParameter[] {
// TODO: What if this is a reference? What does OpenApi do?
// TODO: What about one of and other operations?
let parameters =
operation.parameters?.map(param => resolveObject(param, refs)) || [];
parameters = filterDuplicateParams(parameters);
parameters = reorderParameters(parameters);
parameters = renameEquallyNamedParams(parameters);
return parameters.map(param => ({
...param,
name: camelCase(param.name),
// TODO: Check whether types are correct here and whether we can use union types here.
type: parseType(param, refs)
}));
}
function parseType(param: OpenAPIV3.ParameterObject, refs: $Refs): string {
const originalType = resolveObject(param.schema, refs)?.type?.toString();
const tsType = getType(originalType);
const enumValue = resolveObject(param.schema, refs)?.enum;
return enumValue && isValidEnumType(tsType)
? enumAsUnionType(tsType, enumValue, originalType)
: tsType;
}
function isValidEnumType(tsType: string): boolean {
return tsType === 'number' || tsType === 'string';
}
function enumAsUnionType(
tsType: string,
enumValue: any[],
originalType
): string {
if (tsType === 'number') {
return enumValue.join(' | ');
}
if (tsType === 'string') {
return enumValue.map(e => `'${e}'`).join(' | ');
}
throw new Error(`Cannot parse enum with original type: ${originalType}.`);
}
export function filterDuplicateParams(
parameters: OpenAPIV3.ParameterObject[]
): OpenAPIV3.ParameterObject[] {
return filterDuplicatesRight(
parameters,
(left, right) => left.name === right.name && left.in === right.in
);
}
function reorderParameters(
parameters: OpenAPIV3.ParameterObject[]
): OpenAPIV3.ParameterObject[] {
const [required, optional] = partition(parameters, param => !!param.required);
return [...required, ...optional];
}
export function renameEquallyNamedParams(
parameters: OpenAPIV3.ParameterObject[]
): OpenAPIV3.ParameterObject[] {
return parameters.map((param, i) => {
const duplicate = parameters
.slice(0, i)
.find(previousParam => previousParam.name === param.name);
if (duplicate) {
param.name = `${param.name}2`;
}
return param;
});
}