diff --git a/.changeset/slimy-points-learn.md b/.changeset/slimy-points-learn.md new file mode 100644 index 000000000..1d664486d --- /dev/null +++ b/.changeset/slimy-points-learn.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript": patch +--- + +fix: replace special characters using `SPECIAL_CHARACTER_MAP` for duplicate-identifiers diff --git a/packages/openapi-typescript/src/lib/ts.ts b/packages/openapi-typescript/src/lib/ts.ts index c090a2eac..e658e2680 100644 --- a/packages/openapi-typescript/src/lib/ts.ts +++ b/packages/openapi-typescript/src/lib/ts.ts @@ -4,6 +4,10 @@ import ts, { type LiteralTypeNode, type TypeLiteralNode } from "typescript"; export const JS_PROPERTY_INDEX_RE = /^[A-Za-z_$][A-Za-z_$0-9]*$/; export const JS_ENUM_INVALID_CHARS_RE = /[^A-Za-z_$0-9]+(.)?/g; export const JS_PROPERTY_INDEX_INVALID_CHARS_RE = /[^A-Za-z_$0-9]+/g; +export const SPECIAL_CHARACTER_MAP: Record = { + "+": "Plus", + // Add more mappings as needed +}; export const BOOLEAN = ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); export const FALSE = ts.factory.createLiteralTypeNode(ts.factory.createFalse()); @@ -308,7 +312,9 @@ export function tsEnumMember(value: string | number, metadata: { name?: string; if (invalidCharMatch[0] === name) { name = `"${name}"`; } else { - name = name.replace(JS_PROPERTY_INDEX_INVALID_CHARS_RE, "_"); + name = name.replace(JS_PROPERTY_INDEX_INVALID_CHARS_RE, (s) => { + return s in SPECIAL_CHARACTER_MAP ? SPECIAL_CHARACTER_MAP[s] : "_"; + }); } } } diff --git a/packages/openapi-typescript/test/lib/ts.test.ts b/packages/openapi-typescript/test/lib/ts.test.ts index 517a00d58..d6169181d 100644 --- a/packages/openapi-typescript/test/lib/ts.test.ts +++ b/packages/openapi-typescript/test/lib/ts.test.ts @@ -208,6 +208,14 @@ describe("tsEnum", () => { NotFound = 101, // User doesn't have permissions PermissionDenied = 102 +}`); + }); + + test("replace special character", () => { + expect(astToString(tsEnum("FOO_ENUM", ["Etc/GMT+0", "Etc/GMT+1", "Etc/GMT-1"])).trim()).toBe(`enum FOO_ENUM { + Etc_GMTPlus0 = "Etc/GMT+0", + Etc_GMTPlus1 = "Etc/GMT+1", + Etc_GMT_1 = "Etc/GMT-1" }`); }); });