Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][TYPESCRIPT] Enum with single space value fails to generate a valid TS enum #20561

Open
4 of 6 tasks
bgroff-trdrev opened this issue Jan 30, 2025 · 2 comments
Open
4 of 6 tasks

Comments

@bgroff-trdrev
Copy link

Bug Report Checklist

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

Enumeration containing a single char space as a valid value fails to generate valid Typescript enum.

openapi-generator version

latest

"@openapitools/openapi-generator-cli": "^2.15.3"
OpenAPI declaration file content or url
openapi: 3.0.1
info:
  title: Unnamed Service
  version: v1
paths: {}
components:
  schemas:
    "Enum.Values":
        enum:
          - " "
          - "*"
          - "9"
          - "A"
          - "B"
          - "C"
          - "D"
          - "E"
          - "F"
          - "G"
          - "H"
          - "I"
          - "J"
          - "K"
          - "L"
          - "M"
          - "N"
          - "O"
          - "P"
          - "Q"
          - "R"
          - "T"
          - "U"
          - "V"
          - "W"
          - "X"
          - "Y"
          - "Z"
        type: "string"
Generation Details

v1.json file schema (see schema file above, converted to JSON)

package.json - using node version 20.12.2, npm 10.5.0

{
    "name": "openapi-gen-testbed",
    "version": "",
    "description": "API $api_version client for $repo",
    "main": "dist/index.js",
    "types": "dist/index.d.ts",
    "exports": {
        "." : "./dist/index.js",
        "./v1": "./dist/v1/index.js"
    },
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "generate": "openapi-generator-cli generate --generator-key v1",
        "update-api": "npm run generate && npm run build",
        "build": "rm -rf dist/ && npx tsc"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@openapitools/openapi-generator-cli": "^2.15.3",
        "@tsconfig/node20": "^20.1.4",
        "typescript": "^5.4.5"
    },
    "engines": {
        "node": "20.12.2"
    }
}

openapitools.json - I've tried this with various combinations of additionalProperties

  • enumNameMappings
  • nameMapping
  • enumPropertyNamingReplaceSpecialChar
  • enumAsString
    the outcome is the same regardless, the enum generated is invalid
{
  "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
  "spaces": 2,
  "generator-cli": {
    "version": "7.10.0",
    "generators": {
      "v1": {
        "inputSpec": "#{cwd}/v1.json",
        "generatorName": "typescript-fetch",
        "output": "#{cwd}/src/v1",
        "skipValidateSpec": true,
        "typeMappings": {
          "string+date-time":"string"
        },
        "additionalProperties": {
          "supportsES6": true,
          "withInterfaces": true,
          "typescriptThreePlus": true,
          "withoutRuntimeChecks": true,
          "enumNameMappings": {
            " ": "space"
          },
          "nameMapping": {
            " ": "space"
          },
          "enumPropertyNamingReplaceSpecialChar": false
        }
      }
    }  
  }
}
Steps to reproduce

Setup files above:

| v1.json // convert the yaml schema to json
| package.json
| openapitools.json
npm i
npm run update-api

during the build command, the code will fail to compile. It will point to a fault in the TS code where the enum generated a map with no key.

Actual Output

src/v1/models/index.ts

export const EnumValues = {
    : ' ',
    Star: '*',
    _9: '9',
  // ...
}
Expected Output
export const EnumValues = {
    " " : ' ',
    Star: '*',
    _9: '9',
  // ...
}

OR

export const EnumValues = {
    Space : ' ',
    Star: '*',
    _9: '9',
  // ...
}
Related issues/PRs

N/A

Suggest a fix

specialCharReplacements within DefaultCodegen.java corrects the '*' case, but this is presumably not a safe place to put a " " text replacement..

toEnumVarName method within either DefaultCodegen.java and/or AbstractTypeScriptClientCodegen.java looks like it might be the place where this would come from.

@bgroff-trdrev
Copy link
Author

I've written up the changes to fix this issue but I'm having issues pushing the branch to the remote.

ERROR: Permission to OpenAPITools/openapi-generator.git denied to bgroff-trdrev.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

In any case, here are the proposed changes..

AbstractTypeScriptClientCodegen.java:939

        if (varName.matches("^ +$")) {
            int count = varName.length();
            varName = count > 1 ? count + "_SPACES" : "SPACE";
        }

src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml:1462

      enum_string_spaces:
        type: string
        enum:
          - ' '     # single space
          - '     ' ## 5 spaces

TypeScriptFetchModelTest.java:438

    // Assert fix to Issue #20561
    @Test(description = "test enum model for string space values")
    public void enumModelSpaceValuesTest() {
        final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml");
        final DefaultCodegen codegen = new TypeScriptFetchClientCodegen();
        codegen.processOpts();
        codegen.setOpenAPI(openAPI);
        final Schema schema = openAPI.getComponents().getSchemas().get("Enum_Test");
        final String space = " ";
        final String _5Spaces = "     ";

        Schema property = (Schema) schema.getProperties().get("enum_string_spaces");
        CodegenProperty prope = codegen.fromProperty("enum_string_spaces", property);
        codegen.updateCodegenPropertyEnum(prope);
        Assert.assertEquals(prope.datatypeWithEnum, "EnumStringSpacesEnum");
        Assert.assertEquals(prope.enumName, "EnumStringSpacesEnum");
        Assert.assertTrue(prope.isEnum);
        Assert.assertFalse(prope.isContainer);
        Assert.assertNull(prope.items);
        Assert.assertEquals(prope.allowableValues.get("values"), Arrays.asList(space, _5Spaces));

        HashMap<String, Object> oneSpace = new HashMap<String, Object>();
        oneSpace.put("name", "Space");
        oneSpace.put("value", "'" + space + "'");
        oneSpace.put("isString", false);
        HashMap<String, Object> fiveSpaces = new HashMap<String, Object>();
        fiveSpaces.put("name", "_5Spaces");
        fiveSpaces.put("value", "'" + _5Spaces + "'");
        fiveSpaces.put("isString", false);
        Assert.assertEquals(prope.allowableValues.get("enumVars"), Arrays.asList(oneSpace, fiveSpaces));

        //IMPORTANT: these are not final enum values, which may be further updated
        //by postProcessModels

    }

@bgroff-trdrev
Copy link
Author

There is a workaround to this issue via the Vendor Extensions. Per this issue over here, #893, the resolution which added x-enum-varnames to the spec processing allows a way to workaround this issue if the extension is specified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant