From 0ae4db4f61cdc9afbe13bf527b24657c3e25163f Mon Sep 17 00:00:00 2001 From: Ferdi Koomen Date: Tue, 31 May 2022 17:53:03 +0200 Subject: [PATCH] - Added better support for deprecated prop --- rollup.config.js | 1 + src/client/interfaces/Model.d.ts | 1 + src/openApi/v3/parser/getModel.ts | 1 + src/openApi/v3/parser/getModelProperties.ts | 1 + .../v3/parser/getOperationParameter.ts | 1 + src/templates/partials/exportComposition.hbs | 18 +++-- src/templates/partials/exportEnum.hbs | 9 ++- src/templates/partials/exportInterface.hbs | 18 +++-- src/templates/partials/exportType.hbs | 9 ++- src/templates/partials/parameters.hbs | 9 ++- src/templates/partials/typeInterface.hbs | 9 ++- src/utils/registerHandlebarHelpers.spec.ts | 1 + src/utils/registerHandlebarHelpers.ts | 8 +++ test/__snapshots__/index.spec.ts.snap | 72 +++++++++++++++++++ test/index.js | 2 + test/spec/v3.json | 34 +++++++++ 16 files changed, 179 insertions(+), 15 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index 6f085f8d..1a513b5a 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -28,6 +28,7 @@ const handlebarsPlugin = () => ({ preventIndent: true, knownHelpersOnly: true, knownHelpers: { + ifdef: true, equals: true, notEquals: true, containsSpaces: true, diff --git a/src/client/interfaces/Model.d.ts b/src/client/interfaces/Model.d.ts index ccd1b908..5f031894 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; + deprecated?: boolean; default?: string; imports: string[]; enum: Enum[]; diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index c724029c..b2037135 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -23,6 +23,7 @@ export const getModel = ( template: null, link: null, description: definition.description || null, + deprecated: definition.deprecated === true, isDefinition, isReadOnly: definition.readOnly === true, isNullable: definition.nullable === true, diff --git a/src/openApi/v3/parser/getModelProperties.ts b/src/openApi/v3/parser/getModelProperties.ts index 1c2cbff0..6e25ca83 100644 --- a/src/openApi/v3/parser/getModelProperties.ts +++ b/src/openApi/v3/parser/getModelProperties.ts @@ -37,6 +37,7 @@ export const getModelProperties = ( > = { name: escapeName(propertyName), description: property.description || null, + deprecated: property.deprecated === true, isDefinition: false, isReadOnly: property.readOnly === true, isRequired: propertyRequired, diff --git a/src/openApi/v3/parser/getOperationParameter.ts b/src/openApi/v3/parser/getOperationParameter.ts index 90b8a8e7..97a719c9 100644 --- a/src/openApi/v3/parser/getOperationParameter.ts +++ b/src/openApi/v3/parser/getOperationParameter.ts @@ -20,6 +20,7 @@ export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParame template: null, link: null, description: parameter.description || null, + deprecated: parameter.deprecated === true, isDefinition: false, isReadOnly: false, isRequired: parameter.required === true, diff --git a/src/templates/partials/exportComposition.hbs b/src/templates/partials/exportComposition.hbs index a494260c..15bf6f65 100644 --- a/src/templates/partials/exportComposition.hbs +++ b/src/templates/partials/exportComposition.hbs @@ -1,8 +1,13 @@ -{{#if description}} +{{#ifdef description deprecated}} /** +{{#if description}} * {{{escapeComment description}}} - */ {{/if}} +{{#if deprecated}} + * @deprecated +{{/if}} + */ +{{/ifdef}} export type {{{name}}} = {{>type parent=name}}; {{#if enums}} {{#unless @root.useUnionTypes}} @@ -10,11 +15,16 @@ export type {{{name}}} = {{>type parent=name}}; export namespace {{{name}}} { {{#each enums}} - {{#if description}} + {{#ifdef description deprecated}} /** + {{#if description}} * {{{escapeComment description}}} - */ {{/if}} + {{#if deprecated}} + * @deprecated + {{/if}} + */ + {{/ifdef}} export enum {{{name}}} { {{#each enum}} {{{name}}} = {{{value}}}, diff --git a/src/templates/partials/exportEnum.hbs b/src/templates/partials/exportEnum.hbs index bcaeb24e..f47622ef 100644 --- a/src/templates/partials/exportEnum.hbs +++ b/src/templates/partials/exportEnum.hbs @@ -1,8 +1,13 @@ -{{#if description}} +{{#ifdef description deprecated}} /** +{{#if description}} * {{{escapeComment description}}} - */ {{/if}} +{{#if deprecated}} + * @deprecated +{{/if}} + */ +{{/ifdef}} export enum {{{name}}} { {{#each enum}} {{#if description}} diff --git a/src/templates/partials/exportInterface.hbs b/src/templates/partials/exportInterface.hbs index 645f8f42..b61e2644 100644 --- a/src/templates/partials/exportInterface.hbs +++ b/src/templates/partials/exportInterface.hbs @@ -1,15 +1,25 @@ -{{#if description}} +{{#ifdef description deprecated}} /** +{{#if description}} * {{{escapeComment description}}} - */ {{/if}} +{{#if deprecated}} + * @deprecated +{{/if}} + */ +{{/ifdef}} export type {{{name}}} = { {{#each properties}} - {{#if description}} + {{#ifdef description deprecated}} /** + {{#if description}} * {{{escapeComment description}}} - */ {{/if}} + {{#if deprecated}} + * @deprecated + {{/if}} + */ + {{/ifdef}} {{>isReadOnly}}{{{name}}}{{>isRequired}}: {{>type parent=../name}}; {{/each}} }; diff --git a/src/templates/partials/exportType.hbs b/src/templates/partials/exportType.hbs index 3fce9bef..b57790a0 100644 --- a/src/templates/partials/exportType.hbs +++ b/src/templates/partials/exportType.hbs @@ -1,6 +1,11 @@ -{{#if description}} +{{#ifdef description deprecated}} /** +{{#if description}} * {{{escapeComment description}}} - */ {{/if}} +{{#if deprecated}} + * @deprecated +{{/if}} + */ +{{/ifdef}} export type {{{name}}} = {{>type}}; diff --git a/src/templates/partials/parameters.hbs b/src/templates/partials/parameters.hbs index afbb74f4..57ab5a7d 100644 --- a/src/templates/partials/parameters.hbs +++ b/src/templates/partials/parameters.hbs @@ -6,9 +6,16 @@ {{/each}} }: { {{#each parameters}} +{{#ifdef description deprecated}} +/** {{#if description}} -/** {{{escapeComment description}}} **/ + * {{{escapeComment description}}} {{/if}} +{{#if deprecated}} + * @deprecated +{{/if}} + */ +{{/ifdef}} {{{name}}}{{>isRequired}}: {{>type}}, {{/each}} } diff --git a/src/templates/partials/typeInterface.hbs b/src/templates/partials/typeInterface.hbs index 649e916c..3d5acad0 100644 --- a/src/templates/partials/typeInterface.hbs +++ b/src/templates/partials/typeInterface.hbs @@ -1,11 +1,16 @@ {{~#if properties~}} { {{#each properties}} -{{#if description}} +{{#ifdef description deprecated}} /** +{{#if description}} * {{{escapeComment description}}} - */ {{/if}} +{{#if deprecated}} + * @deprecated +{{/if}} + */ +{{/ifdef}} {{#if ../parent}} {{>isReadOnly}}{{{name}}}{{>isRequired}}: {{>type parent=../parent}}; {{else}} diff --git a/src/utils/registerHandlebarHelpers.spec.ts b/src/utils/registerHandlebarHelpers.spec.ts index f71ca000..f8347abd 100644 --- a/src/utils/registerHandlebarHelpers.spec.ts +++ b/src/utils/registerHandlebarHelpers.spec.ts @@ -11,6 +11,7 @@ describe('registerHandlebarHelpers', () => { useUnionTypes: false, }); const helpers = Object.keys(Handlebars.helpers); + expect(helpers).toContain('ifdef'); expect(helpers).toContain('equals'); expect(helpers).toContain('notEquals'); expect(helpers).toContain('containsSpaces'); diff --git a/src/utils/registerHandlebarHelpers.ts b/src/utils/registerHandlebarHelpers.ts index 58b2ad18..88f47c19 100644 --- a/src/utils/registerHandlebarHelpers.ts +++ b/src/utils/registerHandlebarHelpers.ts @@ -12,6 +12,14 @@ export const registerHandlebarHelpers = (root: { useOptions: boolean; useUnionTypes: boolean; }): void => { + Handlebars.registerHelper('ifdef', function (this: any, ...args): string { + const options = args.pop(); + if (!args.every(value => !value)) { + return options.fn(this); + } + return options.inverse(this); + }); + Handlebars.registerHelper( 'equals', function (this: any, a: string, b: string, options: Handlebars.HelperOptions): string { diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index 7610f8ad..d76eb3d5 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -3632,6 +3632,7 @@ export type { CompositionWithOneOfAndSimpleArrayDictionary } from './models/Comp export type { CompositionWithOneOfAndSimpleDictionary } from './models/CompositionWithOneOfAndSimpleDictionary'; export type { CompositionWithOneOfAnonymous } from './models/CompositionWithOneOfAnonymous'; export type { CompositionWithOneOfDiscriminator } from './models/CompositionWithOneOfDiscriminator'; +export type { DeprecatedModel } from './models/DeprecatedModel'; export type { DictionaryWithArray } from './models/DictionaryWithArray'; export type { DictionaryWithDictionary } from './models/DictionaryWithDictionary'; export type { DictionaryWithProperties } from './models/DictionaryWithProperties'; @@ -3696,6 +3697,7 @@ export { $CompositionWithOneOfAndSimpleArrayDictionary } from './schemas/$Compos export { $CompositionWithOneOfAndSimpleDictionary } from './schemas/$CompositionWithOneOfAndSimpleDictionary'; export { $CompositionWithOneOfAnonymous } from './schemas/$CompositionWithOneOfAnonymous'; export { $CompositionWithOneOfDiscriminator } from './schemas/$CompositionWithOneOfDiscriminator'; +export { $DeprecatedModel } from './schemas/$DeprecatedModel'; export { $DictionaryWithArray } from './schemas/$DictionaryWithArray'; export { $DictionaryWithDictionary } from './schemas/$DictionaryWithDictionary'; export { $DictionaryWithProperties } from './schemas/$DictionaryWithProperties'; @@ -3739,6 +3741,7 @@ export { CollectionFormatService } from './services/CollectionFormatService'; export { ComplexService } from './services/ComplexService'; export { DefaultService } from './services/DefaultService'; export { DefaultsService } from './services/DefaultsService'; +export { DeprecatedService } from './services/DeprecatedService'; export { DescriptionsService } from './services/DescriptionsService'; export { DuplicateService } from './services/DuplicateService'; export { ErrorService } from './services/ErrorService'; @@ -4145,6 +4148,26 @@ export type CompositionWithOneOfDiscriminator = (ModelCircle | ModelSquare); " `; +exports[`v3 should generate: ./test/generated/v3/models/DeprecatedModel.ts 1`] = ` +"/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * This is a deprecated model with a deprecated property + * @deprecated + */ +export type DeprecatedModel = { + /** + * This is a deprecated property + * @deprecated + */ + prop?: string; +}; + +" +`; + exports[`v3 should generate: ./test/generated/v3/models/DictionaryWithArray.ts 1`] = ` "/* istanbul ignore file */ /* tslint:disable */ @@ -5319,6 +5342,22 @@ export const $CompositionWithOneOfDiscriminator = { " `; +exports[`v3 should generate: ./test/generated/v3/schemas/$DeprecatedModel.ts 1`] = ` +"/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $DeprecatedModel = { + description: \`This is a deprecated model with a deprecated property\`, + properties: { + prop: { + type: 'string', + description: \`This is a deprecated property\`, + }, + }, +} as const; +" +`; + exports[`v3 should generate: ./test/generated/v3/schemas/$DictionaryWithArray.ts 1`] = ` "/* istanbul ignore file */ /* tslint:disable */ @@ -6337,6 +6376,39 @@ export class DefaultsService { " `; +exports[`v3 should generate: ./test/generated/v3/services/DeprecatedService.ts 1`] = ` +"/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DeprecatedModel } from '../models/DeprecatedModel'; + +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; + +export class DeprecatedService { + + /** + * @deprecated + * @param parameter This parameter is deprecated + * @throws ApiError + */ + public static deprecatedCall( + parameter: DeprecatedModel | null, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v{api-version}/parameters/deprecated', + headers: { + 'parameter': parameter, + }, + }); + } + +} +" +`; + exports[`v3 should generate: ./test/generated/v3/services/DescriptionsService.ts 1`] = ` "/* istanbul ignore file */ /* tslint:disable */ diff --git a/test/index.js b/test/index.js index 6d276c41..9ffa7e2e 100644 --- a/test/index.js +++ b/test/index.js @@ -59,6 +59,8 @@ const generateRealWorldSpecs = async () => { const main = async () => { await generate('./test/spec/v2.json', './test/generated/v2/'); await generate('./test/spec/v3.json', './test/generated/v3/'); + await generate('./test/spec/swagger.json', './test/generated/swagger/'); + await generate('./test/spec/swagger_klara_2.json', './test/generated/swagger_klara_2/'); // await generateRealWorldSpecs(); }; diff --git a/test/spec/v3.json b/test/spec/v3.json index 70373897..aca05aca 100644 --- a/test/spec/v3.json +++ b/test/spec/v3.json @@ -106,6 +106,28 @@ ] } }, + "/api/v{api-version}/parameters/deprecated": { + "post": { + "tags": [ + "Deprecated" + ], + "deprecated": true, + "operationId": "DeprecatedCall", + "parameters": [ + { + "deprecated": true, + "description": "This parameter is deprecated", + "name": "parameter", + "in": "header", + "required": true, + "nullable": true, + "schema": { + "$ref": "#/components/schemas/DeprecatedModel" + } + } + ] + } + }, "/api/v{api-version}/parameters/{parameterPath}": { "post": { "tags": [ @@ -1877,6 +1899,18 @@ } } }, + "DeprecatedModel": { + "deprecated": true, + "description": "This is a deprecated model with a deprecated property", + "type": "object", + "properties": { + "prop": { + "deprecated": true, + "description": "This is a deprecated property", + "type": "string" + } + } + }, "ModelWithCircularReference": { "description": "This is a model with one property containing a circular reference", "type": "object",