Skip to content

Commit

Permalink
Merge pull request #12 from nicolas-chaulet/fix/additional-properties
Browse files Browse the repository at this point in the history
fix(parser): type additional properties with properties
  • Loading branch information
mrlubos authored Feb 4, 2024
2 parents 22eef6c + fc55ad2 commit ecb60a0
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 38 deletions.
47 changes: 9 additions & 38 deletions src/openApi/v3/parser/getModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { extendEnum } from './extendEnum';
import { getEnum } from './getEnum';
import { findModelComposition, getModelComposition } from './getModelComposition';
import { getModelDefault } from './getModelDefault';
import { getModelProperties } from './getModelProperties';
import { getAdditionalPropertiesModel, getModelProperties } from './getModelProperties';
import { getType } from './getType';

export const getModel = (
Expand Down Expand Up @@ -103,33 +103,6 @@ export const getModel = (
return model;
}

if (
definition.type === 'object' &&
(typeof definition.additionalProperties === 'object' || definition.additionalProperties === true)
) {
const ap = typeof definition.additionalProperties === 'object' ? definition.additionalProperties : {};
if (ap.$ref) {
const additionalProperties = getType(ap.$ref);
model.export = 'dictionary';
model.type = additionalProperties.type;
model.base = additionalProperties.base;
model.template = additionalProperties.template;
model.imports.push(...additionalProperties.imports);
model.default = getModelDefault(definition, model);
return model;
} else {
const additionalProperties = getModel(openApi, ap);
model.export = 'dictionary';
model.type = additionalProperties.type;
model.base = additionalProperties.base;
model.template = additionalProperties.template;
model.link = additionalProperties;
model.imports.push(...additionalProperties.imports);
model.default = getModelDefault(definition, model);
return model;
}
}

const foundComposition = findModelComposition(definition);
if (foundComposition) {
const composition = getModelComposition({
Expand Down Expand Up @@ -158,18 +131,16 @@ export const getModel = (
model.enums.push(modelProperty);
}
});
return model;
} else {
const additionalProperties = getModel(openApi, {});
model.export = 'dictionary';
model.type = additionalProperties.type;
model.base = additionalProperties.base;
model.template = additionalProperties.template;
model.link = additionalProperties;
model.imports.push(...additionalProperties.imports);
model.default = getModelDefault(definition, model);

if (definition.additionalProperties === true) {
const modelProperty = getAdditionalPropertiesModel(openApi, definition, getModel, model);
model.properties.push(modelProperty);
}

return model;
}

return getAdditionalPropertiesModel(openApi, definition, getModel, model);
}

if (definition.const !== undefined) {
Expand Down
39 changes: 39 additions & 0 deletions src/openApi/v3/parser/getModelProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,50 @@ import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import { escapeName } from './escapeName';
import type { getModel } from './getModel';
import { getModelDefault } from './getModelDefault';
import { getType } from './getType';

// Fix for circular dependency
export type GetModelFn = typeof getModel;

export const getAdditionalPropertiesModel = (
openApi: OpenApi,
definition: OpenApiSchema,
getModel: GetModelFn,
model: Model
): Model => {
const ap = typeof definition.additionalProperties === 'object' ? definition.additionalProperties : {};
const apModel = getModel(openApi, ap);

if (definition.additionalProperties === true && definition.properties) {
apModel.default = getModelDefault(definition, model);
apModel.export = 'generic';
apModel.isRequired = true;
apModel.name = '[key: string]';
return apModel;
}

if (ap.$ref) {
const apType = getType(ap.$ref);
model.base = apType.base;
model.default = getModelDefault(definition, model);
model.export = 'dictionary';
model.imports.push(...apType.imports);
model.template = apType.template;
model.type = apType.type;
return model;
}

model.base = apModel.base;
model.default = getModelDefault(definition, model);
model.export = 'dictionary';
model.imports.push(...apModel.imports);
model.link = apModel;
model.template = apModel.template;
model.type = apModel.type;
return model;
};

export const getModelProperties = (
openApi: OpenApi,
definition: OpenApiSchema,
Expand Down
42 changes: 42 additions & 0 deletions test/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3740,6 +3740,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';
Expand Down Expand Up @@ -3819,6 +3820,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';
Expand Down Expand Up @@ -4650,6 +4652,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 */
Expand Down Expand Up @@ -6143,6 +6164,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 */
Expand Down
11 changes: 11 additions & 0 deletions test/spec/v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -2737,6 +2737,17 @@
}
}
},
"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
},
"NestedAnyOfArraysNullable": {
"properties": {
"nullableArray": {
Expand Down

0 comments on commit ecb60a0

Please sign in to comment.