From 0e5f5e4edee00c990208c3bfd616f292c8b5fafc Mon Sep 17 00:00:00 2001 From: John Cutburth Date: Thu, 25 Jan 2024 12:20:41 -0600 Subject: [PATCH 1/3] add title to schema output --- rollup.config.mjs | 1 + src/client/interfaces/Model.d.ts | 1 + src/openApi/v2/interfaces/OpenApiParameter.d.ts | 1 + src/openApi/v2/interfaces/OpenApiResponse.d.ts | 1 + src/openApi/v2/parser/getModel.ts | 1 + src/openApi/v2/parser/getModelComposition.ts | 1 + src/openApi/v2/parser/getModelProperties.ts | 2 ++ src/openApi/v2/parser/getOperationParameter.ts | 1 + src/openApi/v2/parser/getOperationResponse.ts | 1 + src/openApi/v2/parser/getOperationResults.ts | 1 + src/openApi/v2/parser/getRef.spec.ts | 2 ++ src/openApi/v2/parser/getServices.spec.ts | 2 ++ src/openApi/v3/interfaces/OpenApiParameter.d.ts | 1 + src/openApi/v3/interfaces/OpenApiResponse.d.ts | 1 + src/openApi/v3/parser/getModel.ts | 1 + src/openApi/v3/parser/getModelComposition.ts | 1 + src/openApi/v3/parser/getModelProperties.ts | 1 + src/openApi/v3/parser/getModels.ts | 1 + src/openApi/v3/parser/getOperationParameter.ts | 1 + src/openApi/v3/parser/getOperationRequestBody.ts | 1 + src/openApi/v3/parser/getOperationResponse.ts | 1 + src/openApi/v3/parser/getOperationResults.ts | 1 + src/openApi/v3/parser/getServices.spec.ts | 2 ++ src/templates/partials/schemaGeneric.hbs | 3 +++ src/utils/getModelNames.spec.ts | 3 +++ src/utils/registerHandlebarHelpers.spec.ts | 1 + src/utils/registerHandlebarHelpers.ts | 4 ++++ src/utils/sortModelsByName.spec.ts | 3 +++ src/utils/writeClientModels.spec.ts | 1 + src/utils/writeClientSchemas.spec.ts | 1 + 30 files changed, 43 insertions(+) diff --git a/rollup.config.mjs b/rollup.config.mjs index b25ca8442..daa507542 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -38,6 +38,7 @@ const handlebarsPlugin = () => ({ enumerator: true, escapeComment: true, escapeDescription: true, + escapeTitle: true, camelCase: true, }, }); diff --git a/src/client/interfaces/Model.d.ts b/src/client/interfaces/Model.d.ts index 5f0318942..905ff9e8c 100644 --- a/src/client/interfaces/Model.d.ts +++ b/src/client/interfaces/Model.d.ts @@ -3,6 +3,7 @@ import type { Schema } from './Schema'; export interface Model extends Schema { name: string; + title: string | null; export: 'reference' | 'generic' | 'enum' | 'array' | 'dictionary' | 'interface' | 'one-of' | 'any-of' | 'all-of'; type: string; base: string; diff --git a/src/openApi/v2/interfaces/OpenApiParameter.d.ts b/src/openApi/v2/interfaces/OpenApiParameter.d.ts index bdff0bb6f..77ee7cb44 100644 --- a/src/openApi/v2/interfaces/OpenApiParameter.d.ts +++ b/src/openApi/v2/interfaces/OpenApiParameter.d.ts @@ -9,6 +9,7 @@ import type { OpenApiSchema } from './OpenApiSchema'; */ export interface OpenApiParameter extends OpenApiReference, WithEnumExtension, WithNullableExtension { name: string; + title?: string; in: 'path' | 'query' | 'header' | 'formData' | 'body'; description?: string; required?: boolean; diff --git a/src/openApi/v2/interfaces/OpenApiResponse.d.ts b/src/openApi/v2/interfaces/OpenApiResponse.d.ts index 64a0bc85a..b7f2627ad 100644 --- a/src/openApi/v2/interfaces/OpenApiResponse.d.ts +++ b/src/openApi/v2/interfaces/OpenApiResponse.d.ts @@ -9,6 +9,7 @@ import type { OpenApiSchema } from './OpenApiSchema'; */ export interface OpenApiResponse extends OpenApiReference { description: string; + title: string; schema?: OpenApiSchema & OpenApiReference; headers?: Dictionary; examples?: OpenApiExample; diff --git a/src/openApi/v2/parser/getModel.ts b/src/openApi/v2/parser/getModel.ts index 22f3528aa..01e36c80f 100644 --- a/src/openApi/v2/parser/getModel.ts +++ b/src/openApi/v2/parser/getModel.ts @@ -16,6 +16,7 @@ export const getModel = ( ): Model => { const model: Model = { name, + title: definition.title || null, export: 'interface', type: 'any', base: 'any', diff --git a/src/openApi/v2/parser/getModelComposition.ts b/src/openApi/v2/parser/getModelComposition.ts index 6b5e4c305..783bdc0f7 100644 --- a/src/openApi/v2/parser/getModelComposition.ts +++ b/src/openApi/v2/parser/getModelComposition.ts @@ -69,6 +69,7 @@ export const getModelComposition = ( if (properties.length) { composition.properties.push({ name: 'properties', + title: '', export: 'interface', type: 'any', base: 'any', diff --git a/src/openApi/v2/parser/getModelProperties.ts b/src/openApi/v2/parser/getModelProperties.ts index 7560be765..560d74ef0 100644 --- a/src/openApi/v2/parser/getModelProperties.ts +++ b/src/openApi/v2/parser/getModelProperties.ts @@ -19,6 +19,7 @@ export const getModelProperties = (openApi: OpenApi, definition: OpenApiSchema, const model = getType(property.$ref); models.push({ name: escapeName(propertyName), + title: property.title || null, export: 'reference', type: model.type, base: model.base, @@ -52,6 +53,7 @@ export const getModelProperties = (openApi: OpenApi, definition: OpenApiSchema, const model = getModel(openApi, property); models.push({ name: escapeName(propertyName), + title: property.title || null, export: model.export, type: model.type, base: model.base, diff --git a/src/openApi/v2/parser/getOperationParameter.ts b/src/openApi/v2/parser/getOperationParameter.ts index 6b68c9d5a..a25f8228f 100644 --- a/src/openApi/v2/parser/getOperationParameter.ts +++ b/src/openApi/v2/parser/getOperationParameter.ts @@ -17,6 +17,7 @@ export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParame prop: parameter.name, export: 'interface', name: getOperationParameterName(parameter.name), + title: parameter.title || null, type: 'any', base: 'any', template: null, diff --git a/src/openApi/v2/parser/getOperationResponse.ts b/src/openApi/v2/parser/getOperationResponse.ts index 8f6c3ca56..7f38b34b0 100644 --- a/src/openApi/v2/parser/getOperationResponse.ts +++ b/src/openApi/v2/parser/getOperationResponse.ts @@ -15,6 +15,7 @@ export const getOperationResponse = ( const operationResponse: OperationResponse = { in: 'response', name: '', + title: response.title || null, code: responseCode, description: response.description || null, export: 'generic', diff --git a/src/openApi/v2/parser/getOperationResults.ts b/src/openApi/v2/parser/getOperationResults.ts index 9d8111fe8..fabfb7ca7 100644 --- a/src/openApi/v2/parser/getOperationResults.ts +++ b/src/openApi/v2/parser/getOperationResults.ts @@ -24,6 +24,7 @@ export const getOperationResults = (operationResponses: OperationResponse[]): Op operationResults.push({ in: 'response', name: '', + title: '', code: 200, description: '', export: 'generic', diff --git a/src/openApi/v2/parser/getRef.spec.ts b/src/openApi/v2/parser/getRef.spec.ts index c475208b2..a7bec4529 100644 --- a/src/openApi/v2/parser/getRef.spec.ts +++ b/src/openApi/v2/parser/getRef.spec.ts @@ -16,6 +16,7 @@ describe('getRef', () => { paths: {}, definitions: { Example: { + title: 'Example model', description: 'This is an Example model ', type: 'integer', }, @@ -26,6 +27,7 @@ describe('getRef', () => { } ) ).toEqual({ + title: 'Example model', description: 'This is an Example model ', type: 'integer', }); diff --git a/src/openApi/v2/parser/getServices.spec.ts b/src/openApi/v2/parser/getServices.spec.ts index 915ee6b09..079ca3e9e 100644 --- a/src/openApi/v2/parser/getServices.spec.ts +++ b/src/openApi/v2/parser/getServices.spec.ts @@ -14,9 +14,11 @@ describe('getServices', () => { tags: [], responses: { 200: { + title: 'x', description: 'x', }, default: { + title: 'Default', description: 'default', }, }, diff --git a/src/openApi/v3/interfaces/OpenApiParameter.d.ts b/src/openApi/v3/interfaces/OpenApiParameter.d.ts index 7172feb7b..50d01f9fe 100644 --- a/src/openApi/v3/interfaces/OpenApiParameter.d.ts +++ b/src/openApi/v3/interfaces/OpenApiParameter.d.ts @@ -8,6 +8,7 @@ import type { OpenApiSchema } from './OpenApiSchema'; */ export interface OpenApiParameter extends OpenApiReference { name: string; + title?: string; in: 'path' | 'query' | 'header' | 'formData' | 'cookie'; description?: string; required?: boolean; diff --git a/src/openApi/v3/interfaces/OpenApiResponse.d.ts b/src/openApi/v3/interfaces/OpenApiResponse.d.ts index d6509bd7b..b5c94588d 100644 --- a/src/openApi/v3/interfaces/OpenApiResponse.d.ts +++ b/src/openApi/v3/interfaces/OpenApiResponse.d.ts @@ -9,6 +9,7 @@ import type { OpenApiReference } from './OpenApiReference'; */ export interface OpenApiResponse extends OpenApiReference { description: string; + title: string; headers?: Dictionary; content?: Dictionary; links?: Dictionary; diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index 9e9c60a98..288b91b35 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -17,6 +17,7 @@ export const getModel = ( ): Model => { const model: Model = { name, + title: definition.title || null, export: 'interface', type: 'any', base: 'any', diff --git a/src/openApi/v3/parser/getModelComposition.ts b/src/openApi/v3/parser/getModelComposition.ts index 2c27d1815..a5024d38f 100644 --- a/src/openApi/v3/parser/getModelComposition.ts +++ b/src/openApi/v3/parser/getModelComposition.ts @@ -70,6 +70,7 @@ export const getModelComposition = ( if (properties.length) { composition.properties.push({ name: 'properties', + title: '', export: 'interface', type: 'any', base: 'any', diff --git a/src/openApi/v3/parser/getModelProperties.ts b/src/openApi/v3/parser/getModelProperties.ts index 6e25ca833..c27b9c36e 100644 --- a/src/openApi/v3/parser/getModelProperties.ts +++ b/src/openApi/v3/parser/getModelProperties.ts @@ -36,6 +36,7 @@ export const getModelProperties = ( | 'properties' > = { name: escapeName(propertyName), + title: property.title || null, description: property.description || null, deprecated: property.deprecated === true, isDefinition: false, diff --git a/src/openApi/v3/parser/getModels.ts b/src/openApi/v3/parser/getModels.ts index 6df7cf1e5..55d261ec1 100644 --- a/src/openApi/v3/parser/getModels.ts +++ b/src/openApi/v3/parser/getModels.ts @@ -22,6 +22,7 @@ export const getModels = (openApi: OpenApi): Model[] => { const schema = definition.schema; if (schema) { const model = getModel(openApi, schema, true, definitionType.base.replace(reservedWords, '_$1')); + model.title = definition.title || null; model.description = definition.description || null; model.deprecated = definition.deprecated; models.push(model); diff --git a/src/openApi/v3/parser/getOperationParameter.ts b/src/openApi/v3/parser/getOperationParameter.ts index 97a719c96..3d3319deb 100644 --- a/src/openApi/v3/parser/getOperationParameter.ts +++ b/src/openApi/v3/parser/getOperationParameter.ts @@ -15,6 +15,7 @@ export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParame prop: parameter.name, export: 'interface', name: getOperationParameterName(parameter.name), + title: parameter.title || null, type: 'any', base: 'any', template: null, diff --git a/src/openApi/v3/parser/getOperationRequestBody.ts b/src/openApi/v3/parser/getOperationRequestBody.ts index 9f9cca241..cacdcee98 100644 --- a/src/openApi/v3/parser/getOperationRequestBody.ts +++ b/src/openApi/v3/parser/getOperationRequestBody.ts @@ -12,6 +12,7 @@ export const getOperationRequestBody = (openApi: OpenApi, body: OpenApiRequestBo export: 'interface', prop: 'requestBody', name: 'requestBody', + title: null, type: 'any', base: 'any', template: null, diff --git a/src/openApi/v3/parser/getOperationResponse.ts b/src/openApi/v3/parser/getOperationResponse.ts index dff19ec13..6dd130196 100644 --- a/src/openApi/v3/parser/getOperationResponse.ts +++ b/src/openApi/v3/parser/getOperationResponse.ts @@ -16,6 +16,7 @@ export const getOperationResponse = ( const operationResponse: OperationResponse = { in: 'response', name: '', + title: response.title || null, code: responseCode, description: response.description || null, export: 'generic', diff --git a/src/openApi/v3/parser/getOperationResults.ts b/src/openApi/v3/parser/getOperationResults.ts index 9d8111fe8..fabfb7ca7 100644 --- a/src/openApi/v3/parser/getOperationResults.ts +++ b/src/openApi/v3/parser/getOperationResults.ts @@ -24,6 +24,7 @@ export const getOperationResults = (operationResponses: OperationResponse[]): Op operationResults.push({ in: 'response', name: '', + title: '', code: 200, description: '', export: 'generic', diff --git a/src/openApi/v3/parser/getServices.spec.ts b/src/openApi/v3/parser/getServices.spec.ts index baea07e66..efe8f9119 100644 --- a/src/openApi/v3/parser/getServices.spec.ts +++ b/src/openApi/v3/parser/getServices.spec.ts @@ -14,9 +14,11 @@ describe('getServices', () => { tags: [], responses: { 200: { + title: 'x', description: 'x', }, default: { + title: 'Default', description: 'default', }, }, diff --git a/src/templates/partials/schemaGeneric.hbs b/src/templates/partials/schemaGeneric.hbs index 23580a673..64ab41792 100644 --- a/src/templates/partials/schemaGeneric.hbs +++ b/src/templates/partials/schemaGeneric.hbs @@ -2,6 +2,9 @@ {{#if type}} type: '{{{type}}}', {{/if}} +{{#if title}} + title: '{{{escapeTitle title}}}', +{{/if}} {{#if description}} description: `{{{escapeDescription description}}}`, {{/if}} diff --git a/src/utils/getModelNames.spec.ts b/src/utils/getModelNames.spec.ts index a5a17d4b4..eb202a898 100644 --- a/src/utils/getModelNames.spec.ts +++ b/src/utils/getModelNames.spec.ts @@ -6,6 +6,7 @@ describe('getModelNames', () => { const john: Model = { export: 'interface', name: 'John', + title: null, type: 'John', base: 'John', template: null, @@ -23,6 +24,7 @@ describe('getModelNames', () => { const jane: Model = { export: 'interface', name: 'Jane', + title: null, type: 'Jane', base: 'Jane', template: null, @@ -40,6 +42,7 @@ describe('getModelNames', () => { const doe: Model = { export: 'interface', name: 'Doe', + title: null, type: 'Doe', base: 'Doe', template: null, diff --git a/src/utils/registerHandlebarHelpers.spec.ts b/src/utils/registerHandlebarHelpers.spec.ts index f8347abdb..1ebb9cfd6 100644 --- a/src/utils/registerHandlebarHelpers.spec.ts +++ b/src/utils/registerHandlebarHelpers.spec.ts @@ -20,6 +20,7 @@ describe('registerHandlebarHelpers', () => { expect(helpers).toContain('enumerator'); expect(helpers).toContain('escapeComment'); expect(helpers).toContain('escapeDescription'); + expect(helpers).toContain('escapeTitle'); expect(helpers).toContain('camelCase'); }); }); diff --git a/src/utils/registerHandlebarHelpers.ts b/src/utils/registerHandlebarHelpers.ts index 88f47c19b..081587890 100644 --- a/src/utils/registerHandlebarHelpers.ts +++ b/src/utils/registerHandlebarHelpers.ts @@ -101,6 +101,10 @@ export const registerHandlebarHelpers = (root: { return value.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\${/g, '\\${'); }); + Handlebars.registerHelper('escapeTitle', function (value: string): string { + return value.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\${/g, '\\${'); + }); + Handlebars.registerHelper('camelCase', function (value: string): string { return camelCase(value); }); diff --git a/src/utils/sortModelsByName.spec.ts b/src/utils/sortModelsByName.spec.ts index ab57a7d98..952b1f3ff 100644 --- a/src/utils/sortModelsByName.spec.ts +++ b/src/utils/sortModelsByName.spec.ts @@ -6,6 +6,7 @@ describe('sortModelsByName', () => { const john: Model = { export: 'interface', name: 'John', + title: null, type: 'John', base: 'John', template: null, @@ -23,6 +24,7 @@ describe('sortModelsByName', () => { const jane: Model = { export: 'interface', name: 'Jane', + title: null, type: 'Jane', base: 'Jane', template: null, @@ -40,6 +42,7 @@ describe('sortModelsByName', () => { const doe: Model = { export: 'interface', name: 'Doe', + title: null, type: 'Doe', base: 'Doe', template: null, diff --git a/src/utils/writeClientModels.spec.ts b/src/utils/writeClientModels.spec.ts index ee0f2b4f6..2ce0040ad 100644 --- a/src/utils/writeClientModels.spec.ts +++ b/src/utils/writeClientModels.spec.ts @@ -16,6 +16,7 @@ describe('writeClientModels', () => { { export: 'interface', name: 'User', + title: null, type: 'User', base: 'User', template: null, diff --git a/src/utils/writeClientSchemas.spec.ts b/src/utils/writeClientSchemas.spec.ts index e75928b8c..2aa6c4e5a 100644 --- a/src/utils/writeClientSchemas.spec.ts +++ b/src/utils/writeClientSchemas.spec.ts @@ -16,6 +16,7 @@ describe('writeClientSchemas', () => { { export: 'interface', name: 'User', + title: null, type: 'User', base: 'User', template: null, From 237156bc46c08f2e5e401459288784b3e623c760 Mon Sep 17 00:00:00 2001 From: John Cutburth Date: Wed, 6 Mar 2024 17:07:53 -0600 Subject: [PATCH 2/3] Remove 'title' property from Model interface and add 'title' property to Schema interface --- src/client/interfaces/Model.d.ts | 1 - src/client/interfaces/Schema.d.ts | 1 + src/templates/partials/schemaInterface.hbs | 3 +++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/client/interfaces/Model.d.ts b/src/client/interfaces/Model.d.ts index 905ff9e8c..5f0318942 100644 --- a/src/client/interfaces/Model.d.ts +++ b/src/client/interfaces/Model.d.ts @@ -3,7 +3,6 @@ import type { Schema } from './Schema'; export interface Model extends Schema { name: string; - title: string | null; export: 'reference' | 'generic' | 'enum' | 'array' | 'dictionary' | 'interface' | 'one-of' | 'any-of' | 'all-of'; type: string; base: string; diff --git a/src/client/interfaces/Schema.d.ts b/src/client/interfaces/Schema.d.ts index 26a116dbf..239e3825b 100644 --- a/src/client/interfaces/Schema.d.ts +++ b/src/client/interfaces/Schema.d.ts @@ -1,4 +1,5 @@ export interface Schema { + title: string | null; isDefinition: boolean; isReadOnly: boolean; isRequired: boolean; diff --git a/src/templates/partials/schemaInterface.hbs b/src/templates/partials/schemaInterface.hbs index 3417c5fb9..4adbd217a 100644 --- a/src/templates/partials/schemaInterface.hbs +++ b/src/templates/partials/schemaInterface.hbs @@ -1,4 +1,7 @@ { +{{#if title}} +title: '{{{escapeTitle title}}}', +{{/if}} {{#if description}} description: `{{{escapeDescription description}}}`, {{/if}} From 4ddd46337e3f4c317a3cb979d18345e16b380629 Mon Sep 17 00:00:00 2001 From: John Cutburth Date: Wed, 6 Mar 2024 19:42:09 -0600 Subject: [PATCH 3/3] Add title and description to schemaArray, schemaComposition, schemaDictionary, and schemaInterface partials --- src/templates/partials/schemaArray.hbs | 6 ++++++ src/templates/partials/schemaComposition.hbs | 3 +++ src/templates/partials/schemaDictionary.hbs | 6 ++++++ src/templates/partials/schemaInterface.hbs | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/templates/partials/schemaArray.hbs b/src/templates/partials/schemaArray.hbs index 44871265b..df5a11bef 100644 --- a/src/templates/partials/schemaArray.hbs +++ b/src/templates/partials/schemaArray.hbs @@ -1,5 +1,11 @@ { type: 'array', +{{#if title}} +title: '{{{escapeTitle title}}}', +{{/if}} +{{#if description}} +description: `{{{escapeDescription description}}}`, +{{/if}} {{#if link}} contains: {{>schema link}}, {{else}} diff --git a/src/templates/partials/schemaComposition.hbs b/src/templates/partials/schemaComposition.hbs index 050f6696d..654ce5f45 100644 --- a/src/templates/partials/schemaComposition.hbs +++ b/src/templates/partials/schemaComposition.hbs @@ -1,5 +1,8 @@ { type: '{{export}}', +{{#if title}} + title: '{{{escapeTitle title}}}', +{{/if}} {{#if description}} description: `{{{escapeDescription description}}}`, {{/if}} diff --git a/src/templates/partials/schemaDictionary.hbs b/src/templates/partials/schemaDictionary.hbs index 1e755f7af..726c2a0b3 100644 --- a/src/templates/partials/schemaDictionary.hbs +++ b/src/templates/partials/schemaDictionary.hbs @@ -1,5 +1,11 @@ { type: 'dictionary', +{{#if title}} +title: '{{{escapeTitle title}}}', +{{/if}} +{{#if description}} +description: `{{{escapeDescription description}}}`, +{{/if}} {{#if link}} contains: {{>schema link}}, {{else}} diff --git a/src/templates/partials/schemaInterface.hbs b/src/templates/partials/schemaInterface.hbs index 4adbd217a..d3928d790 100644 --- a/src/templates/partials/schemaInterface.hbs +++ b/src/templates/partials/schemaInterface.hbs @@ -1,6 +1,6 @@ { {{#if title}} -title: '{{{escapeTitle title}}}', + title: '{{{escapeTitle title}}}', {{/if}} {{#if description}} description: `{{{escapeDescription description}}}`,