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

Handle duplicate enum keys #3

Closed
wants to merge 1 commit into from
Closed

Conversation

gregorym
Copy link

@gregorym gregorym commented Jan 9, 2025

It is possible for input (or output) to expect an enum. However, when another input has an enum with the same name as a previously generated class, then the final output have multiple enums with the same name.

This PR detects generated enum and makes them unique to avoid duplicates.

Handle duplicate enums
@polvallverdu
Copy link
Collaborator

Hey, I've tried multiple times to solve stuff like this, even doing a custom quicktype build for this, and looks like there's still conflicts 😅. Thank you so much for your PR. I'll try to test it in the following days.

Are you able to link me to a recreation so I can test it faster? Or just sending the specific files works for me.

@polvallverdu polvallverdu added bug Something isn't working good first issue Good for newcomers and removed good first issue Good for newcomers labels Jan 9, 2025
@gregorym
Copy link
Author

gregorym commented Jan 9, 2025

Here's an example of my generated classes.

@freezed
class Stories_createInput with _$Stories_createInput {
  const factory Stories_createInput({
    required Duration0 duration,
    String? extRefId,
    required double? locationId,
    double? narrationDuration,
    String? narrationUrl,
    required double? objectId,
    required List<double> protagonists,
    required double? styleId,
    String? synopsis,
    required double? themeId,
    dynamic timestamps,
    String? title,
    String? transcript,
  }) = _Stories_createInput;

  factory Stories_createInput.fromJson(Map<String, dynamic> json) =>
      _$Stories_createInputFromJson(json);
}

enum Duration0 { LONG, MEDIUM, SHORT }
@freezed
class Admin_stories_updateInput with _$Admin_stories_updateInput {
  const factory Admin_stories_updateInput({
    dynamic authorName,
    dynamic caption,
    dynamic characters,
    dynamic coverUrl,
    String? createdAt,
    Duration2? duration,
    dynamic extRefId,
    double? id,
    required bool isPublic,
    String? lang,
    dynamic name,
    dynamic narrationDuration,
    dynamic narrationUrl,
    double? playCount,
    dynamic rating,
    dynamic scenes,
    dynamic shareId,
    dynamic slug,
    Status3? status,
    dynamic storyFinalUrl,
    dynamic synopsis,
    dynamic transcript,
    dynamic transcriptChunks,
    dynamic transcriptPrompt,
    Type4? type,
    required String userId,
    dynamic videoUrl,
    bool? withImages,
    bool? withVideos,
  }) = _Admin_stories_updateInput;

  factory Admin_stories_updateInput.fromJson(Map<String, dynamic> json) =>
      _$Admin_stories_updateInputFromJson(json);
}

enum Duration2 { LONG, MEDIUM, SHORT }
enum Status3 { DRAFT, ERROR, IN_REVIEW, PENDING, QUEUED, READY }
enum Type4 { CUSTOM, EPISODE, SINGLE }

routes.json (modified)

{
  "routes": {
     "stories.create": {
      "path": "stories.create",
      "routeType": "mutation",
      "input": {
        "type": "object",
        "properties": {
          "style_id": {
            "type": ["number", "null"]
          },
          "location_id": {
            "type": ["number", "null"]
          },
          "object_id": {
            "type": ["number", "null"]
          },
          "protagonists": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "theme_id": {
            "type": ["number", "null"]
          },
          "duration": {
            "type": "string",
            "enum": ["SHORT", "MEDIUM", "LONG"]
          },
          "title": {
            "type": "string"
          },
          "transcript": {
            "type": "string"
          },
          "timestamps": {},
          "narrationUrl": {
            "type": "string"
          },
          "extRefId": {
            "type": "string"
          },
          "synopsis": {
            "type": "string"
          },
          "narrationDuration": {
            "type": "number"
          }
        },
        "required": [
          "style_id",
          "location_id",
          "object_id",
          "protagonists",
          "theme_id",
          "duration"
        ],
        "additionalProperties": false,
        "$schema": "http://json-schema.org/draft-07/schema#"
      },
      "output": null
    },
    "admin.stories.update": {
      "path": "admin.stories.update",
      "routeType": "mutation",
      "input": {
        "type": "object",
        "properties": {
          "author_name": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "caption": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "characters": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "anyOf": [
                      {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "object",
                            "additionalProperties": {
                              "anyOf": [
                                {
                                  "$ref": "#/properties/characters/anyOf/0/anyOf/1"
                                },
                                {
                                  "not": {}
                                }
                              ]
                            }
                          },
                          {
                            "type": "array",
                            "items": {
                              "$ref": "#/properties/characters/anyOf/0/anyOf/1"
                            }
                          }
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "cover_url": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": "string"
          },
          "duration": {
            "type": "string",
            "enum": ["SHORT", "MEDIUM", "LONG"]
          },
          "ext_ref_id": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "id": {
            "type": "number"
          },
          "is_public": {
            "type": "boolean"
          },
          "lang": {
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "narration_duration": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "narration_url": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "play_count": {
            "type": "number"
          },
          "rating": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "scenes": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "$ref": "#/properties/characters/anyOf/0/anyOf/1"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "share_id": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "slug": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "QUEUED",
              "PENDING",
              "READY",
              "ERROR",
              "IN_REVIEW"
            ]
          },
          "story_final_url": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "synopsis": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "transcript": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "transcript_chunks": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "$ref": "#/properties/characters/anyOf/0/anyOf/1"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "transcript_prompt": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "$ref": "#/properties/characters/anyOf/0/anyOf/1"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "type": {
            "type": "string",
            "enum": ["CUSTOM", "SINGLE", "EPISODE"]
          },
          "user_id": {
            "type": "string"
          },
          "video_url": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "with_images": {
            "type": "boolean"
          },
          "with_videos": {
            "type": "boolean"
          }
        },
        "required": ["is_public", "user_id"],
        "additionalProperties": false,
        "$schema": "http://json-schema.org/draft-07/schema#"
      },
      "output": null
    },
 }
}

@polvallverdu
Copy link
Collaborator

polvallverdu commented Jan 10, 2025

Thanks. I thought I had that case solved already. I'm going to check if it can be solved from a lower level (quicktype) to it imitates the same functionality of having the parents with underscores.

polvallverdu added a commit to wosherco/quicktype that referenced this pull request Jan 10, 2025
polvallverdu added a commit to wosherco/quicktype that referenced this pull request Jan 10, 2025
@polvallverdu
Copy link
Collaborator

Can you try version of generator 0.1.7 (latest)? I think this should be fixed. If not, as a fallback, this PR can be merged.

@polvallverdu polvallverdu self-requested a review January 11, 2025 00:07
@gregorym
Copy link
Author

Just tried and it did not work. updateInput_status appears multiple times in the file. Secondly, the factory is still expecting Status instead of updateInput_status.

class Admin_stories_updateInput with _$Admin_stories_updateInput {
  const factory Admin_stories_updateInput({
    dynamic authorName,
    dynamic caption,
    dynamic characters,
    dynamic coverUrl,
    String? createdAt,
    Duration? duration,
    dynamic extRefId,
    double? id,
    required bool isPublic,
    String? lang,
    dynamic name,
    dynamic narrationDuration,
    dynamic narrationUrl,
    double? playCount,
    dynamic rating,
    dynamic scenes,
    dynamic shareId,
    dynamic slug,
    Status? status,
    dynamic storyFinalUrl,
    dynamic synopsis,
    dynamic transcript,
    dynamic transcriptChunks,
    dynamic transcriptPrompt,
    Type? type,
    required String userId,
    dynamic videoUrl,
    bool? withImages,
    bool? withVideos,
  }) = _Admin_stories_updateInput;

  factory Admin_stories_updateInput.fromJson(Map<String, dynamic> json) =>
      _$Admin_stories_updateInputFromJson(json);
}

enum updateInput_duration { LONG, MEDIUM, SHORT }

enum updateInput_status { DRAFT, ERROR, IN_REVIEW, PENDING, QUEUED, READY }

enum updateInput_type { CUSTOM, EPISODE, SINGLE }

@polvallverdu
Copy link
Collaborator

Crap. What I'll do is revert the change and apply your PR. Can you check if your PR also works for lists of objects? There should be the same collision issue.

@polvallverdu polvallverdu reopened this Jan 15, 2025
@gregorym
Copy link
Author

CAn you provide an example?

@polvallverdu
Copy link
Collaborator

Hey sorry, I've been busy. I'll try to do it later today

@polvallverdu
Copy link
Collaborator

@gregorym I fixed the issue with enum names, but I'm also looking to merge something like this as a backup. Would you mind doing it so it will put numbers in case there's a repeated name only?

Again, thank you for your help 🙌

@gregorym
Copy link
Author

@gregorym I fixed the issue with enum names, but I'm also looking to merge something like this as a backup. Would you mind doing it so it will put numbers in case there's a repeated name only?

Again, thank you for your help 🙌

Sure. I was going to change the logic from using a number to using use the class name instead.
ex: MyClass_MyEnum instead of MyEnum1.

Having a number makes is very confusing to use the enum in your code if there's a number in it.

@polvallverdu
Copy link
Collaborator

Can you wait 5 minutes and try 0.1.8 for the generator? I think I fixed the enum thing, and works as you mentioned.

@gregorym
Copy link
Author

Yes of course :D

@polvallverdu
Copy link
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants