From c297889e533accd8b2c14e9b93cc4474179eb02f Mon Sep 17 00:00:00 2001 From: Tom Crasset <25140344+tcrasset@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:51:52 +0200 Subject: [PATCH] feat: combine 'additionalProperties: true' with explicit properties --- src/openApi/v3/parser/getModel.ts | 22 +++++++++++--- test/__snapshots__/index.spec.ts.snap | 42 +++++++++++++++++++++++++++ test/spec/v3.json | 11 +++++++ 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index 9e9c60a98..f2647b38b 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -95,10 +95,7 @@ export const getModel = ( } } - if ( - definition.type === 'object' && - (typeof definition.additionalProperties === 'object' || definition.additionalProperties === true) - ) { + if (definition.type === 'object' && typeof definition.additionalProperties === 'object') { const ap = typeof definition.additionalProperties === 'object' ? definition.additionalProperties : {}; if (ap.$ref) { const additionalProperties = getType(ap.$ref); @@ -165,6 +162,23 @@ export const getModel = ( model.enums.push(modelProperty); } }); + + if (definition.additionalProperties === true) { + const additionalPropertiesModel = JSON.parse(JSON.stringify(model)); //deepcopy + const additionalProperties = getModel(openApi, {}); + additionalPropertiesModel.name = '[key: string]'; + additionalPropertiesModel.export = 'generic'; + additionalPropertiesModel.type = 'any'; + additionalPropertiesModel.base = 'any'; + additionalPropertiesModel.isRequired = true; + additionalPropertiesModel.template = additionalProperties.template; + additionalPropertiesModel.link = additionalProperties; + additionalPropertiesModel.imports.push(...additionalProperties.imports); + additionalPropertiesModel.default = getModelDefault(definition, model); + additionalPropertiesModel.description = null; + model.properties.push(additionalPropertiesModel); + } + return model; } else { const additionalProperties = getModel(openApi, {}); diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index ef6b18554..7bc1d86c3 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -3707,6 +3707,7 @@ export type { ModelCircle } from './models/ModelCircle'; export type { ModelSquare } from './models/ModelSquare'; export type { ModelThatExtends } from './models/ModelThatExtends'; export type { ModelThatExtendsExtends } from './models/ModelThatExtendsExtends'; +export type { ModelWithAdditionalPropertiesEqTrue } from './models/ModelWithAdditionalPropertiesEqTrue'; export type { ModelWithArray } from './models/ModelWithArray'; export type { ModelWithBoolean } from './models/ModelWithBoolean'; export type { ModelWithCircularReference } from './models/ModelWithCircularReference'; @@ -3777,6 +3778,7 @@ export { $ModelCircle } from './schemas/$ModelCircle'; export { $ModelSquare } from './schemas/$ModelSquare'; export { $ModelThatExtends } from './schemas/$ModelThatExtends'; export { $ModelThatExtendsExtends } from './schemas/$ModelThatExtendsExtends'; +export { $ModelWithAdditionalPropertiesEqTrue } from './schemas/$ModelWithAdditionalPropertiesEqTrue'; export { $ModelWithArray } from './schemas/$ModelWithArray'; export { $ModelWithBoolean } from './schemas/$ModelWithBoolean'; export { $ModelWithCircularReference } from './schemas/$ModelWithCircularReference'; @@ -4504,6 +4506,25 @@ export type ModelThatExtendsExtends = (ModelWithString & ModelThatExtends & { " `; +exports[`v3 should generate: test/generated/v3/models/ModelWithAdditionalPropertiesEqTrue.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +/** + * This is a model with one property and additionalProperties: true + */ +export type ModelWithAdditionalPropertiesEqTrue = { + /** + * This is a simple string property + */ + prop?: string; + [key: string]: any; +}; + +" +`; + exports[`v3 should generate: test/generated/v3/models/ModelWithArray.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ @@ -5802,6 +5823,27 @@ export const $ModelThatExtendsExtends = { " `; +exports[`v3 should generate: test/generated/v3/schemas/$ModelWithAdditionalPropertiesEqTrue.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $ModelWithAdditionalPropertiesEqTrue = { + description: \`This is a model with one property and additionalProperties: true\`, + properties: { + prop: { + type: 'string', + description: \`This is a simple string property\`, + }, + [key: string]: { + type: 'any', + isRequired: true, + }, + }, +} as const; +" +`; + exports[`v3 should generate: test/generated/v3/schemas/$ModelWithArray.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ diff --git a/test/spec/v3.json b/test/spec/v3.json index cb590d0b7..740cde554 100644 --- a/test/spec/v3.json +++ b/test/spec/v3.json @@ -2549,6 +2549,17 @@ "type": "object", "additionalProperties": true }, + "ModelWithAdditionalPropertiesEqTrue": { + "description": "This is a model with one property and additionalProperties: true", + "type": "object", + "properties": { + "prop": { + "description": "This is a simple string property", + "type": "string" + } + }, + "additionalProperties": true + }, "FreeFormObjectWithAdditionalPropertiesEqEmptyObject": { "description": "This is a free-form object with additionalProperties: {}.", "type": "object",