From e56a98a6caaaef867bade59c27856382d78efd8f Mon Sep 17 00:00:00 2001 From: Ferdi Koomen Date: Thu, 28 Nov 2019 23:47:52 +0100 Subject: [PATCH] - Added all checks for defaults --- src/client/interfaces/Model.d.ts | 1 + src/client/interfaces/OperationParameter.d.ts | 1 - .../v2/parser/getOperationParameter.ts | 9 +- .../v2/parser/getOperationParameterDefault.ts | 26 +++++- src/openApi/v3/parser/getModel.ts | 10 ++ src/openApi/v3/parser/getModelDefault.ts | 31 +++++++ .../v3/parser/getOperationParameter.ts | 5 +- .../v3/parser/getOperationParameterDefault.ts | 15 --- src/templates/typescript/service.hbs | 2 +- test/mock/spec-v2.json | 67 +++++++++++++ test/mock/spec-v3.json | 93 +++++++++++++++++-- 11 files changed, 228 insertions(+), 32 deletions(-) create mode 100644 src/openApi/v3/parser/getModelDefault.ts delete mode 100644 src/openApi/v3/parser/getOperationParameterDefault.ts diff --git a/src/client/interfaces/Model.d.ts b/src/client/interfaces/Model.d.ts index 3ef18600..8c2d2064 100644 --- a/src/client/interfaces/Model.d.ts +++ b/src/client/interfaces/Model.d.ts @@ -9,6 +9,7 @@ export interface Model extends Schema { template: string | null; link: Model | null; description: string | null; + default?: any; isProperty: boolean; isReadOnly: boolean; isRequired: boolean; diff --git a/src/client/interfaces/OperationParameter.d.ts b/src/client/interfaces/OperationParameter.d.ts index 9d31776e..0fea3746 100644 --- a/src/client/interfaces/OperationParameter.d.ts +++ b/src/client/interfaces/OperationParameter.d.ts @@ -3,5 +3,4 @@ import { Model } from './Model'; export interface OperationParameter extends Model { in: 'path' | 'query' | 'header' | 'formData' | 'body' | 'cookie'; prop: string; - default?: any; } diff --git a/src/openApi/v2/parser/getOperationParameter.ts b/src/openApi/v2/parser/getOperationParameter.ts index db750b82..d48e6eb8 100644 --- a/src/openApi/v2/parser/getOperationParameter.ts +++ b/src/openApi/v2/parser/getOperationParameter.ts @@ -21,7 +21,6 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame template: null, link: null, description: getComment(parameter.description), - default: getOperationParameterDefault(parameter.default), isProperty: false, isReadOnly: false, isRequired: parameter.required === true, @@ -40,6 +39,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.base = definitionRef.base; operationParameter.template = definitionRef.template; operationParameter.imports.push(...definitionRef.imports); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } @@ -50,6 +50,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.type = PrimaryType.STRING; operationParameter.base = PrimaryType.STRING; operationParameter.enum.push(...enumerators); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } } @@ -61,6 +62,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.type = PrimaryType.NUMBER; operationParameter.base = PrimaryType.NUMBER; operationParameter.enum.push(...enumerators); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } } @@ -72,6 +74,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.base = items.base; operationParameter.template = items.template; operationParameter.imports.push(...items.imports); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } @@ -83,6 +86,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.template = items.template; operationParameter.imports.push(...items.imports); operationParameter.imports.push('Dictionary'); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } @@ -94,6 +98,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.base = model.base; operationParameter.template = model.template; operationParameter.imports.push(...model.imports); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } else { const model = getModel(openApi, parameter.schema); @@ -107,6 +112,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.enum.push(...model.enum); operationParameter.enums.push(...model.enums); operationParameter.properties.push(...model.properties); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } } @@ -119,6 +125,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.base = definitionType.base; operationParameter.template = definitionType.template; operationParameter.imports.push(...definitionType.imports); + operationParameter.default = getOperationParameterDefault(parameter, operationParameter); return operationParameter; } diff --git a/src/openApi/v2/parser/getOperationParameterDefault.ts b/src/openApi/v2/parser/getOperationParameterDefault.ts index 5685a7db..4420dd96 100644 --- a/src/openApi/v2/parser/getOperationParameterDefault.ts +++ b/src/openApi/v2/parser/getOperationParameterDefault.ts @@ -1,14 +1,30 @@ -export function getOperationParameterDefault(value: any): string | null { - if (value === null) { +import { OpenApiParameter } from '../interfaces/OpenApiParameter'; +import { OperationParameter } from '../../../client/interfaces/OperationParameter'; + +export function getOperationParameterDefault(parameter: OpenApiParameter, operationParameter: OperationParameter): string | null { + if (parameter.default === null) { return 'null'; } - switch (typeof value) { + switch (typeof parameter.default) { case 'number': + if (operationParameter.export == 'enum' && operationParameter.enum.length && operationParameter.enum[parameter.default]) { + return operationParameter.enum[parameter.default].value; + } + return JSON.stringify(parameter.default); + case 'boolean': - return JSON.stringify(value); + return JSON.stringify(parameter.default); + case 'string': - return `'${value}'`; + return `'${parameter.default}'`; + + case 'object': + try { + return JSON.stringify(parameter.default, null, 4); + } catch (e) { + // Ignore + } } return null; diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index 1163280a..853eb29c 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -5,6 +5,7 @@ import { PrimaryType } from './constants'; import { getComment } from './getComment'; import { getEnum } from './getEnum'; import { getEnumFromDescription } from './getEnumFromDescription'; +import { getModelDefault } from './getModelDefault'; import { getModelProperties } from './getModelProperties'; import { getType } from './getType'; @@ -35,6 +36,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.base = definitionRef.base; model.template = definitionRef.template; model.imports.push(...definitionRef.imports); + model.default = getModelDefault(definition, model); return model; } @@ -45,6 +47,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.type = PrimaryType.STRING; model.base = PrimaryType.STRING; model.enum.push(...enumerators); + model.default = getModelDefault(definition, model); return model; } } @@ -56,6 +59,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.type = PrimaryType.NUMBER; model.base = PrimaryType.NUMBER; model.enum.push(...enumerators); + model.default = getModelDefault(definition, model); return model; } } @@ -68,6 +72,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.base = arrayItems.base; model.template = arrayItems.template; model.imports.push(...arrayItems.imports); + model.default = getModelDefault(definition, model); return model; } else { const arrayItems = getModel(openApi, definition.items, true); @@ -77,6 +82,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.template = arrayItems.template; model.link = arrayItems; model.imports.push(...arrayItems.imports); + model.default = getModelDefault(definition, model); return model; } } @@ -90,6 +96,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.template = additionalProperties.template; model.imports.push(...additionalProperties.imports); model.imports.push('Dictionary'); + model.default = getModelDefault(definition, model); return model; } else { const additionalProperties = getModel(openApi, definition.additionalProperties); @@ -100,6 +107,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.link = additionalProperties; model.imports.push(...additionalProperties.imports); model.imports.push('Dictionary'); + model.default = getModelDefault(definition, model); return model; } } @@ -108,6 +116,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.export = 'interface'; model.type = PrimaryType.OBJECT; model.base = PrimaryType.OBJECT; + model.default = getModelDefault(definition, model); if (definition.allOf) { definition.allOf.forEach(parent => { @@ -151,6 +160,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty model.base = definitionType.base; model.template = definitionType.template; model.imports.push(...definitionType.imports); + model.default = getModelDefault(definition, model); return model; } diff --git a/src/openApi/v3/parser/getModelDefault.ts b/src/openApi/v3/parser/getModelDefault.ts new file mode 100644 index 00000000..cfb317ab --- /dev/null +++ b/src/openApi/v3/parser/getModelDefault.ts @@ -0,0 +1,31 @@ +import { Model } from '../../../client/interfaces/Model'; +import { OpenApiSchema } from '../interfaces/OpenApiSchema'; + +export function getModelDefault(definition: OpenApiSchema, model?: Model): string | null { + if (definition.default === null) { + return 'null'; + } + + switch (typeof definition.default) { + case 'number': + if (model && model.export == 'enum' && model.enum.length && model.enum[definition.default]) { + return model.enum[definition.default].value; + } + return JSON.stringify(definition.default); + + case 'boolean': + return JSON.stringify(definition.default); + + case 'string': + return `'${definition.default}'`; + + case 'object': + try { + return JSON.stringify(definition.default, null, 4); + } catch (e) { + // Ignore + } + } + + return null; +} diff --git a/src/openApi/v3/parser/getOperationParameter.ts b/src/openApi/v3/parser/getOperationParameter.ts index cbee64e9..8d770d41 100644 --- a/src/openApi/v3/parser/getOperationParameter.ts +++ b/src/openApi/v3/parser/getOperationParameter.ts @@ -4,6 +4,7 @@ import { OperationParameter } from '../../../client/interfaces/OperationParamete import { PrimaryType } from './constants'; import { getComment } from './getComment'; import { getModel } from './getModel'; +import { getModelDefault } from './getModelDefault'; import { getOperationParameterName } from './getOperationParameterName'; import { getType } from './getType'; @@ -18,7 +19,6 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame template: null, link: null, description: getComment(parameter.description), - default: undefined, isProperty: false, isReadOnly: false, isRequired: parameter.required === true, @@ -48,6 +48,8 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.base = model.base; operationParameter.template = model.template; operationParameter.imports.push(...model.imports); + operationParameter.default = getModelDefault(parameter.schema); + return operationParameter; } else { const model = getModel(openApi, parameter.schema); @@ -56,6 +58,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame operationParameter.base = model.base; operationParameter.template = model.template; operationParameter.link = model.link; + operationParameter.default = model.default; operationParameter.imports.push(...model.imports); operationParameter.extends.push(...model.extends); operationParameter.enum.push(...model.enum); diff --git a/src/openApi/v3/parser/getOperationParameterDefault.ts b/src/openApi/v3/parser/getOperationParameterDefault.ts deleted file mode 100644 index 5685a7db..00000000 --- a/src/openApi/v3/parser/getOperationParameterDefault.ts +++ /dev/null @@ -1,15 +0,0 @@ -export function getOperationParameterDefault(value: any): string | null { - if (value === null) { - return 'null'; - } - - switch (typeof value) { - case 'number': - case 'boolean': - return JSON.stringify(value); - case 'string': - return `'${value}'`; - } - - return null; -} diff --git a/src/templates/typescript/service.hbs b/src/templates/typescript/service.hbs index 5a354112..27d91a2f 100644 --- a/src/templates/typescript/service.hbs +++ b/src/templates/typescript/service.hbs @@ -37,7 +37,7 @@ export class {{{name}}} { */ public static async {{{name}}}({{#if parameters}} {{#each parameters}} - {{{name}}}{{#unless isRequired}}?{{/unless}}: {{>type}}{{#if isNullable}} | null{{/if}}{{#if default}} = {{{default}}}{{/if}}{{#unless @last}},{{/unless}} + {{{name}}}{{#unless isRequired}}{{#unless default}}?{{/unless}}{{/unless}}: {{>type}}{{#if isNullable}} | null{{/if}}{{#if default}} = {{{default}}}{{/if}}{{#unless @last}},{{/unless}} {{/each}} {{/if}}): Promise<{{>result}}> { diff --git a/test/mock/spec-v2.json b/test/mock/spec-v2.json index 5edbb343..97ca5f59 100644 --- a/test/mock/spec-v2.json +++ b/test/mock/spec-v2.json @@ -98,6 +98,61 @@ ] } }, + "/api/v{api-version}/defaults": { + "get": { + "tags": [ + "Defaults" + ], + "operationId": "CallWithDefaultParameters", + "parameters": [ + { + "description": "This is a simple string", + "name": "parameterString", + "in": "query", + "default": "Hello World!", + "type": "string" + }, + { + "description": "This is a simple number", + "name": "parameterNumber", + "in": "query", + "default": 123, + "type": "number" + }, + { + "description": "This is a simple boolean", + "name": "parameterBoolean", + "in": "query", + "default": true, + "type": "boolean" + }, + { + "description": "This is a simple enum", + "name": "parameterEnum", + "in": "query", + "default": 0, + "schema": { + "enum": [ + "Success", + "Warning", + "Error" + ] + } + }, + { + "description": "This is a simple model", + "name": "parameterModel", + "in": "query", + "default": { + "prop": "Hello World" + }, + "schema": { + "$ref": "#/definitions/ModelWithString" + } + } + ] + } + }, "/api/v{api-version}/response": { "get": { "tags": [ @@ -629,6 +684,18 @@ "items": { "$ref": "#/definitions/ModelWithString" } + }, + "propWithFile": { + "type": "array", + "items": { + "type": "File" + } + }, + "propWithNumber": { + "type": "array", + "items": { + "type": "int" + } } } }, diff --git a/test/mock/spec-v3.json b/test/mock/spec-v3.json index 1b6d5df0..8f6ad801 100644 --- a/test/mock/spec-v3.json +++ b/test/mock/spec-v3.json @@ -124,6 +124,71 @@ } } }, + "/api/v{api-version}/defaults": { + "get": { + "tags": [ + "Defaults" + ], + "operationId": "CallWithDefaultParameters", + "parameters": [ + { + "description": "This is a simple string", + "name": "parameterString", + "in": "query", + "nullable": true, + "schema": { + "type": "string", + "default": "Hello World!" + } + }, + { + "description": "This is a simple number", + "name": "parameterNumber", + "in": "query", + "nullable": true, + "schema": { + "type": "number", + "default": 123 + } + }, + { + "description": "This is a simple boolean", + "name": "parameterBoolean", + "in": "query", + "nullable": true, + "schema": { + "type": "boolean", + "default": true + } + }, + { + "description": "This is a simple enum", + "name": "parameterEnum", + "in": "query", + "schema": { + "enum": [ + "Success", + "Warning", + "Error" + ], + "default": 0 + } + }, + { + "description": "This is a simple model", + "name": "parameterModel", + "in": "query", + "nullable": true, + "schema": { + "$ref": "#/components/schemas/ModelWithString", + "default": { + "prop": "Hello World" + } + } + } + ] + } + }, "/api/v{api-version}/response": { "get": { "tags": [ @@ -292,9 +357,9 @@ "name": "parameterNumber", "in": "query", "required": true, - "default": 123, "schema": { - "type": "int" + "type": "int", + "default": 123 } }, { @@ -303,9 +368,9 @@ "in": "query", "required": true, "nullable": true, - "default": "default", "schema": { - "type": "string" + "type": "string", + "default": "default" } }, { @@ -314,9 +379,9 @@ "in": "query", "required": true, "nullable": true, - "default": true, "schema": { - "type": "boolean" + "type": "boolean", + "default": true } }, { @@ -325,9 +390,9 @@ "in": "query", "required": true, "nullable": true, - "default": null, "schema": { - "type": "object" + "type": "object", + "default": null } }, { @@ -745,6 +810,18 @@ "items": { "$ref": "#/components/schemas/ModelWithString" } + }, + "propWithFile": { + "type": "array", + "items": { + "type": "File" + } + }, + "propWithNumber": { + "type": "array", + "items": { + "type": "int" + } } } },