Skip to content

Commit 0e26c53

Browse files
committed
feat(api-client): referenced method parameters generated and used
1 parent 3e694ad commit 0e26c53

File tree

2 files changed

+57
-23
lines changed

2 files changed

+57
-23
lines changed

src/helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function dashCase(text: string = ''): string {
2525
* @param {string} refString
2626
* @returns {string}
2727
*/
28-
export function dereferenceType(refString: string): string {
28+
export function dereferenceType(refString: string | undefined): string {
2929
if (!refString) {
3030
return '';
3131
}

src/parser.ts

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Response, Schema, Spec as Swagger } from 'swagger-schema-official';
1+
import { BodyParameter, QueryParameter, Response, Schema, Spec as Swagger } from 'swagger-schema-official';
22
import { Definition, Method, MethodType, MustacheData, Parameter, Property, Render, RenderFileName } from './types';
33
import { camelCase, dereferenceType, determineDomain, fileName, prefixImportedModels, toTypescriptType, typeName } from './helper';
44

@@ -10,11 +10,11 @@ export function createMustacheViewModel(swagger: Swagger): MustacheData {
1010
swagger: swagger,
1111
domain: determineDomain(swagger),
1212
methods: parseMethods(swagger),
13-
definitions: parseDefinitions(swagger.definitions)
13+
definitions: parseDefinitions(swagger.definitions, swagger.parameters)
1414
};
1515
}
1616

17-
function parseMethods({paths, security}: Swagger): Method[] {
17+
function parseMethods({paths, security, parameters}: Swagger): Method[] {
1818
const authorizedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
1919

2020
return [].concat.apply([], Object.entries(paths)
@@ -30,26 +30,32 @@ function parseMethods({paths, security}: Swagger): Method[] {
3030
methodType: methodType.toUpperCase() as MethodType,
3131
summaryLines: operation.description ? operation.description.split('\n') : [], // description summary is optional
3232
isSecure: security !== undefined || operation.security !== undefined,
33-
parameters: transformParameters(operation.parameters),
33+
parameters: transformParameters(operation.parameters, parameters || {}),
3434
hasJsonResponse: true,
3535
response: prefixImportedModels(determineResponseType(operation.responses)),
3636
})
3737
)
3838
));
3939
}
4040

41-
function parseDefinitions(definitions: { [definitionsName: string]: Schema } = {}): Definition[] {
42-
return Object.entries(definitions).map(([key, definition]) =>
41+
function parseDefinitions(
42+
definitions: { [definitionsName: string]: Schema } = {},
43+
parameters: { [parameterName: string]: BodyParameter | QueryParameter } = {},
44+
): Definition[] {
45+
return Object.entries({
46+
...definitions,
47+
...(parameters as { [key: string]: Schema }), // type cast because of wrong typing in BaseParameter (should contain enum property)
48+
}).map(([key, definition]) =>
4349
definition.enum && definition.enum.length !== 0
4450
? defineEnum(definition.enum, key)
4551
: defineInterface(definition, key)
4652
);
4753
}
4854

49-
function defineEnum(enumSchema: (string | boolean | number | {})[], definitionKey: string): Definition {
55+
function defineEnum(enumSchema: (string | boolean | number | {})[] = [], definitionKey: string): Definition {
5056
return {
5157
name: typeName(definitionKey),
52-
properties: enumSchema.map((val) => ({
58+
properties: enumSchema && enumSchema.map((val) => ({
5359
name: val.toString(),
5460
})),
5561
isEnum: true,
@@ -58,7 +64,7 @@ function defineEnum(enumSchema: (string | boolean | number | {})[], definitionKe
5864
};
5965
}
6066

61-
function parseInterfaceProperties(properties: {[propertyName: string]: Schema} = {}): Property[] {
67+
function parseInterfaceProperties(properties: { [propertyName: string]: Schema } = {}): Property[] {
6268
return Object.entries<Schema>(properties).map(
6369
([propName, propSchema]: [string, Schema]) => {
6470
const property: Property = {
@@ -67,8 +73,6 @@ function parseInterfaceProperties(properties: {[propertyName: string]: Schema} =
6773
isArray: propSchema.type === 'array',
6874
};
6975

70-
// console.log('prop', property.name);
71-
7276
if (Array.isArray(propSchema.items)) {
7377
console.warn('Arrays with type diversity are currently not supported');
7478
property.type = 'any';
@@ -143,33 +147,63 @@ function determineResponseType(responses: { [responseName: string]: Response }):
143147
return 'any';
144148
}
145149

146-
function transformParameters(parameters: Parameter[]): Parameter[] {
150+
function transformParameters(
151+
parameters: Parameter[],
152+
swaggerParams: { [parameterName: string]: BodyParameter | QueryParameter }
153+
): Parameter[] {
147154
return Array.isArray(parameters)
148155
// todo: required params
149156
? parameters.map((param) => {
150157
// console.log('==>', param);
151158

159+
const ref = param.$ref || (param.schema && param.schema.$ref) || '';
160+
const derefName = dereferenceType(ref);
161+
const paramRef = swaggerParams[derefName];
162+
const name = paramRef ? paramRef.name : param.name;
152163
const typescriptType = toTypescriptType(
153-
dereferenceType(param.$ref || ('schema' in param && param.schema.$ref)) || param.type,
164+
ref ? derefName : param.type,
154165
param.items
155166
);
156-
const camelCaseName = camelCase(param.name ? param.name : typescriptType); // if name is not defined, use type name
157167

158168
return {
159169
...param,
170+
...determineParamType(paramRef ? paramRef.in : param.in),
160171

161-
camelCaseName,
172+
camelCaseName: camelCase(name),
162173
importType: prefixImportedModels(typescriptType),
163-
isBodyParameter: param.in === 'body',
164-
isFormParameter: param.in === 'formData'
165-
? console.warn(`Form parameters are currently unsupported and will not be generated properly [ ${param.name} ]`) || true
166-
: false,
167-
isHeaderParameter: param.in === 'header',
168-
isPathParameter: param.in === 'path',
169-
isQueryParameter: param.in === 'query' || param.in === 'modelbinding',
174+
name,
170175
typescriptType,
171176
};
172177
}
173178
)
174179
: [];
175180
}
181+
182+
function determineParamType(paramType: string | undefined):
183+
{ isBodyParameter?: boolean } |
184+
{ isFormParameter?: boolean } |
185+
{ isHeaderParameter?: boolean } |
186+
{ isPathParameter?: boolean } |
187+
{ isQueryParameter?: boolean } {
188+
189+
if (!paramType) {
190+
return {};
191+
}
192+
193+
switch (paramType) {
194+
case 'body':
195+
return {isBodyParameter: true};
196+
case 'formData':
197+
console.warn(`Form parameters are currently unsupported and will not be generated properly`);
198+
return {isFormParameter: true};
199+
case 'header':
200+
return {isHeaderParameter: true};
201+
case 'path':
202+
return {isPathParameter: true};
203+
case 'query' || 'modelbinding':
204+
return {isQueryParameter: true};
205+
default:
206+
console.warn(`Unsupported parameter type [ ${paramType} ]`);
207+
return {};
208+
}
209+
}

0 commit comments

Comments
 (0)