Skip to content

Commit

Permalink
fix: same values but different casing creates conflicting enums (#1259)
Browse files Browse the repository at this point in the history
Enums in schema which has same value but different casing creates same
enum values which conflicts with each other. For instance,
[observed](cdk8s-team/cdk8s-cli#578 (comment))
while importing a custom resource definition in cdk8s.

```
\| 1086   REPLACE = 'replace',
--
\|        ~~~~~~~
\| com.coreos.monitoring.ts:1088:3 - error TS2300: Duplicate identifier 'REPLACE'.
\| 1088   REPLACE = 'Replace',
\|        ~~~~~~~
\| com.coreos.monitoring.ts:1090:3 - error TS2300: Duplicate identifier 'KEEP'.
\| 1090   KEEP = 'keep',
\|        ~~~~
\| com.coreos.monitoring.ts:1092:3 - error TS2300: Duplicate identifier 'KEEP'.
\| 1092   KEEP = 'Keep',
\|        ~~~~
\| com.coreos.monitoring.ts:1094:3 - error TS2300: Duplicate identifier 'DROP'.
\| 1094   DROP = 'drop',
\|        ~~~~
\| com.coreos.monitoring.ts:1096:3 - error TS2300: Duplicate identifier 'DROP'.
\| 1096   DROP = 'Drop',
```

Fixes cdk8s-team/cdk8s-cli#578

---------

Signed-off-by: Vinayak Kukreja <vinakuk@amazon.com>
  • Loading branch information
vinayak-kukreja committed Nov 22, 2023
1 parent 52eac87 commit c5e809c
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/type-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,8 @@ export class TypeGenerator {

code.openBlock(`export enum ${typeName}`);

const processedValues = new Set<string>();

for (const value of def.enum) {
if (!['string', 'number'].includes(typeof(value))) {
throw new Error('only enums with string or number values are supported');
Expand All @@ -529,6 +531,15 @@ export class TypeGenerator {
// sluggify and turn to UPPER_SNAKE_CASE
let memberName = snakeCase(`${value}`.replace(/[^a-z0-9]/gi, '_')).split('_').filter(x => x).join('_').toUpperCase();

// If enums of same value exists, then we choose one of them and skip adding others
// since that would cause conflict
const lowerCaseValue = value?.toString().toLowerCase();
if (lowerCaseValue && !processedValues.has(lowerCaseValue)) {
processedValues.add(lowerCaseValue);
} else {
continue;
}

// if member name starts with a non-alpha character, add a prefix so it becomes a symbol
if (!/^[A-Z].*/i.test(memberName)) {
memberName = 'VALUE_' + memberName;
Expand Down
46 changes: 46 additions & 0 deletions test/__snapshots__/type-generator.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions test/type-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,26 @@ describe('enums', () => {
},
},
});

which('has repeated values', {
properties: {
Same: {
type: 'string',
enum: [
'replace',
'Replace',
'keep',
'Keep',
'hashmod',
'HashMod',
'labelmap',
'LabelMap',
'24',
'0.99',
],
},
},
});
});

which('primitives', {
Expand Down

0 comments on commit c5e809c

Please sign in to comment.