openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] [typescript-fetch] Model and property name collision with other model can cause weird codegen bugs

Open iliastsa opened this issue 2 years ago • 1 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [x] Have you validated the input using an OpenAPI validator (example)?
  • [x] Have you tested with the latest master to confirm the issue still exists?
  • [x] Have you searched for related issues/PRs?
  • [x] What's the actual output vs expected output?
  • [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

There is a weird name collision issue when the model of a property is "similar" to the name of an actual model. More specifically, similar here means that camelize(object_property_field) == some_model_name. To make this more concrete, in the following example, the User model has a tier property, which internally is represented as User_tier (at least that's what I found when stepping with the debugger). It happens that camelize("User_tier") == "UserTier" which causes troubles when it's time to process the actual UserTier model (early returns in the code path, uses the cached model processing).

For this specific example, a weird side-effect is that the generated model code is incorrect, with cyclic imports and missing definitions:

/* tslint:disable */
/* eslint-disable */
/**
 * FastAPI
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 0.1.0
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

import { exists, mapValues } from '../runtime';
import type { UserTier } from './UserTier';
import {
    UserTierFromJSON,
    UserTierFromJSONTyped,
    UserTierToJSON,
} from './UserTier';

/**
 * 
 * @export
 * @interface UserTier
 */
export interface UserTier {
}

/**
 * Check if a given object implements the UserTier interface.
 */
export function instanceOfUserTier(value: object): boolean {
    let isInstance = true;

    return isInstance;
}

export function UserTierFromJSON(json: any): UserTier {
    return UserTierFromJSONTyped(json, false);
}

export function UserTierFromJSONTyped(json: any, ignoreDiscriminator: boolean): UserTier {
    return json;
}

export function UserTierToJSON(value?: UserTier | null): any {
    return value;
}

Simply changing the property name fixes issue, since there is no longer a collision.

openapi-generator version

7.3.0

OpenAPI declaration file content or url
{
    "openapi": "3.1.0",
    "info": {
        "title": "FastAPI",
        "version": "0.1.0"
    },
    "components": {
        "schemas": {
            "UserTier": {
                "type": "string",
                "enum": [
                    "Tier1",
                    "Tier2"
                ],
                "title": "UserTier"
            },
            "User": {
                "properties": {
                    "tier": {
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/UserTier"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    }
                },
                "type": "object",
                "title": "User"
            }
        }
    }
}
Generation Details

I'm using the npm wrapper to invoke the generator: npx openapi-generator-cli generate -g "typescript-fetch" -i openapi.json -o ./out --additional-properties packageName=test,projectName=test,useSingleRequestParameter=false

Steps to reproduce

Pass the weird collision schema to the generator.

Related issues/PRs
Suggest a fix

Some logic must be added to check if the camelized schema name of a model property is already taken by a "top level" model. For example here, camelize("User_tier") produces UserTier which is inserted in the model map, causing the subsequent processing of the actual UserTier model to follow an early-return path and skip further processing.

iliastsa avatar Feb 20 '24 20:02 iliastsa

I am having the same issue.

ghost avatar Aug 23 '24 12:08 ghost

I am having the same issue, which produced code that doesn't compile. Can you take care of it?

pbrzosko avatar Jan 16 '25 12:01 pbrzosko