OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.9k stars 6.58k forks source link

[BUG] Supprt JsonLD, allow property names @id, @type and @context (specifically for typescript-fetch) #13999

Open Richard87 opened 2 years ago

Richard87 commented 2 years ago

Bug Report Checklist

Description

Json-LD includes a few fields that starts with a @ sign, like @id, @type and ´@context, when usingtypescript-fetchthe@sign is stripped wich leads to invalid code (often duplicateid` properties).

I assumed modelPropertyNaming=original would work, but it had no effect.

openapi-generator version

npm: @openapitools/openapi-generator-cli 2.5.2

OpenAPI declaration file content or url
{
    "openapi": "3.0.0",
    "info": {
        "title": "Hello API Platform",
        "description": "",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "/",
            "description": ""
        }
    ],
    "paths": {
        "/users/{id}": {
            "get": {
                "operationId": "api_users_id_get",
                "tags": [
                    "User"
                ],
                "responses": {
                    "200": {
                        "description": "User resource",
                        "content": {
                            "application/ld+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/User.jsonld"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "summary": "Retrieves a User resource.",
                "description": "Retrieves a User resource.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "User identifier",
                        "required": true,
                        "deprecated": false,
                        "allowEmptyValue": false,
                        "schema": {
                            "type": "string"
                        },
                        "style": "simple",
                        "explode": false,
                        "allowReserved": false
                    }
                ],
                "deprecated": false
            },
            "parameters": []
        }
    },
    "components": {
        "schemas": {
            "User.jsonld": {
                "type": "object",
                "description": "",
                "deprecated": false,
                "properties": {
                    "@context": {
                        "readOnly": true,
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "object",
                                "properties": {
                                    "@vocab": {
                                        "type": "string"
                                    },
                                    "hydra": {
                                        "type": "string",
                                        "enum": [
                                            "http://www.w3.org/ns/hydra/core#"
                                        ]
                                    }
                                },
                                "required": [
                                    "@vocab",
                                    "hydra"
                                ],
                                "additionalProperties": true
                            }
                        ]
                    },
                    "@id": {
                        "readOnly": true,
                        "type": "string"
                    },
                    "@type": {
                        "readOnly": true,
                        "type": "string"
                    },
                    "id": {
                        "readOnly": true,
                        "type": "string",
                        "format": "ulid"
                    },
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "roles": {
                        "readOnly": true,
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "userIdentifier": {
                        "readOnly": true,
                        "type": "string"
                    }
                }
            }
        },
        "responses": {},
        "parameters": {},
        "examples": {},
        "requestBodies": {},
        "headers": {},
        "securitySchemes": {}
    },
    "security": [],
    "tags": []
}
Generation Details

I run this command as a php composer.json script:

        "generate-api": [
            "rm -Rf ../pwa/components/openapi",
            "bin/console api:openapi:export > openapi.json",
            "../pwa/node_modules/.bin/openapi-generator-cli generate -i openapi.json -o ../pwa/components/openapi -g typescript-fetch --additional-properties=supportsES6=true,npmVersion=6.9.0,typescriptThreePlus=true,allowUnicodeIdentifiers=true,disallowAdditionalPropertiesIfNotPresent=false,paramNaming=original,modelPropertyNaming=original,enumPropertyNaming=original,nullSafeAdditionalProps=true"
        ]
Steps to reproduce
// create openapi.json file
./node_modules/.bin/openapi-generator-cli generate -i openapi.json -o ./components/openapi -g typescript-fetch --additional-properties=supportsES6=true,npmVersion=6.9.0,typescriptThreePlus=true,allowUnicodeIdentifiers=true,disallowAdditionalPropertiesIfNotPresent=false,paramNaming=original,modelPropertyNaming=original,enumPropertyNaming=original,nullSafeAdditionalProps=true
Related issues/PRs

https://github.com/OpenAPITools/openapi-generator/issues/5899

Suggest a fix
Mauriceu commented 1 year ago

Any news?

I guess one solution would be to set a different "serializedName" for those properties that intersect with hydra, granted that requires touching a lot of stuff

Edit:

Found a dirty but simple workaround that involves a custom generator.

First create the scaffolding for the custom generator:

Now open the file located in custom-generator/src/main/java/company/codegen/CustomCodegenGenerator.java. Replace everything but the first line with:

import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen;

public class CustomCodegenGenerator extends TypeScriptAngularClientCodegen implements CodegenConfig {
    public String getName() {
        return "custom-codegen";
    }

    @Override
    public String toVarName(String name) {
        switch(name) {
            case "@context":
            case "@id":
            case "@type":
                return ("\"" + name + "\"");
        }
        return super.sanitizeName(name);
    }
}

You basically just intercept any call to "toVarName" and make sure that certain properties are quoted and not passed to the sanitize-function.

Compile the generator by executing

wherever the pom.xml is located in.

And then generate your Code with:

One could go ahead and add all other hydra-context properties to the switch, or just check if an @ is at the beginning of "name", though that may catch unwanted properties as well.

PierreTraversFamileo commented 1 year ago

i have the same issues thank's for the work arroud