Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/preserve-mixed-case-enum-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"swagger-typescript-api": patch
---

Fix enum key formatting to preserve mixed case names with underscores (e.g., `_123ValCamelCase`, `Val_Snake_Case`, `_Val_12_CamelCase`) while still transforming pure lowercase snake_case to PascalCase (e.g., `local_only``LocalOnly`)
11 changes: 11 additions & 0 deletions src/type-name-formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ export class TypeNameFormatter {
return lodash.compact([typePrefix, name, typeSuffix]).join("_");
}

// for enum keys, preserve mixed case names with underscores like Val_Snake_Case, _Val_12_CamelCase
// but transform pure lowercase snake_case like local_only to PascalCase
if (
schemaType === "enum-key" &&
/^(?!\d)([A-Za-z0-9_]{1,})$/g.test(name) &&
name.includes("_") &&
/[A-Z]/.test(name)
) {
return lodash.compact([typePrefix, name, typeSuffix]).join("_");
}

if (this.formattedModelNamesMap.has(hashKey)) {
return this.formattedModelNamesMap.get(hashKey);
}
Expand Down
98 changes: 98 additions & 0 deletions tests/spec/enumIncludesNumber/__snapshots__/basic.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,89 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`basic > edge case with prefix and suffix 1`] = `
"/* eslint-disable */
/* tslint:disable */
// @ts-nocheck
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
* ## ##
* ## AUTHOR: acacode ##
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
* ---------------------------------------------------------------
*/
/** Pure lowercase snake_case values that should be transformed to PascalCase */
export enum LowercaseSnakeCaseEnum {
VALLocalOnlyCaSeCamelCase = "local_only",
VALPhoneNumberCaSeCamelCase = "phone_number",
VALWaitDependencyCaSeCamelCase = "wait_dependency",
VALAuthFailedCaSeCamelCase = "auth_failed",
VALWaitingToPushCaSeCamelCase = "waiting_to_push",
}
export enum StringEnumIncludesNumbersAndUnderscore {
/** Foo */
V_aL_VAL_1_Ca_Se_CamelCase = "VAL_1",
/** Bar */
V_aL_VAL_2_Ca_Se_CamelCase = "VAL_2",
/** Baz */
V_aL_VAL_3_Ca_Se_CamelCase = "VAL_3",
V_aL__1_VAL_Ca_Se_CamelCase = "_1_VAL",
V_aL_A_1_B_2_C_3_Ca_Se_CamelCase = "A_1_B_2_C_3",
V_aL__A_1_B_2_C_3_Ca_Se_CamelCase = "_A_1_B_2_C_3",
V_aL__1_A_2_B_3_C_Ca_Se_CamelCase = "_1_A_2_B_3_C",
V_aL__123ValCamelCase_Ca_Se_CamelCase = "_123ValCamelCase",
V_aL_Val_Snake_Case_Ca_Se_CamelCase = "Val_Snake_Case",
V_aL_Val_12_CamelCase_Ca_Se_CamelCase = "Val_12_CamelCase",
V_aL__Val_12_Snake_Case_Ca_Se_CamelCase = "_Val_12_Snake_Case",
V_aL__Val_12_CamelCase_Ca_Se_CamelCase = "_Val_12_CamelCase",
}
"
`;

exports[`basic > transform pure lowercase snake_case to PascalCase 1`] = `
"/* eslint-disable */
/* tslint:disable */
// @ts-nocheck
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
* ## ##
* ## AUTHOR: acacode ##
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
* ---------------------------------------------------------------
*/
/** Pure lowercase snake_case values that should be transformed to PascalCase */
export enum LowercaseSnakeCaseEnum {
LocalOnly = "local_only",
PhoneNumber = "phone_number",
WaitDependency = "wait_dependency",
AuthFailed = "auth_failed",
WaitingToPush = "waiting_to_push",
}
export enum StringEnumIncludesNumbersAndUnderscore {
/** Foo */
VAL_1 = "VAL_1",
/** Bar */
VAL_2 = "VAL_2",
/** Baz */
VAL_3 = "VAL_3",
_1_VAL = "_1_VAL",
A_1_B_2_C_3 = "A_1_B_2_C_3",
_A_1_B_2_C_3 = "_A_1_B_2_C_3",
_1_A_2_B_3_C = "_1_A_2_B_3_C",
_123ValCamelCase = "_123ValCamelCase",
Val_Snake_Case = "Val_Snake_Case",
Val_12_CamelCase = "Val_12_CamelCase",
_Val_12_Snake_Case = "_Val_12_Snake_Case",
_Val_12_CamelCase = "_Val_12_CamelCase",
}
"
`;

exports[`basic > use x-enumNames as the key for enum 1`] = `
"/* eslint-disable */
/* tslint:disable */
Expand All @@ -13,6 +97,15 @@ exports[`basic > use x-enumNames as the key for enum 1`] = `
* ---------------------------------------------------------------
*/
/** Pure lowercase snake_case values that should be transformed to PascalCase */
export enum LowercaseSnakeCaseEnum {
LocalOnly = "local_only",
PhoneNumber = "phone_number",
WaitDependency = "wait_dependency",
AuthFailed = "auth_failed",
WaitingToPush = "waiting_to_push",
}
export enum StringEnumIncludesNumbersAndUnderscore {
/** Foo */
VAL_1 = "VAL_1",
Expand All @@ -24,6 +117,11 @@ export enum StringEnumIncludesNumbersAndUnderscore {
A_1_B_2_C_3 = "A_1_B_2_C_3",
_A_1_B_2_C_3 = "_A_1_B_2_C_3",
_1_A_2_B_3_C = "_1_A_2_B_3_C",
_123ValCamelCase = "_123ValCamelCase",
Val_Snake_Case = "Val_Snake_Case",
Val_12_CamelCase = "Val_12_CamelCase",
_Val_12_Snake_Case = "_Val_12_Snake_Case",
_Val_12_CamelCase = "_Val_12_CamelCase",
}
"
`;
37 changes: 37 additions & 0 deletions tests/spec/enumIncludesNumber/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,41 @@ describe("basic", async () => {

expect(content).toMatchSnapshot();
});

test("edge case with prefix and suffix", async () => {
await generateApi({
fileName: "schema",
input: path.resolve(import.meta.dirname, "schema.json"),
output: tmpdir,
silent: true,
enumNamesAsValues: false,
generateClient: false,
enumKeyPrefix: "V_aL",
enumKeySuffix: "Ca_Se_CamelCase",
});

const content = await fs.readFile(path.join(tmpdir, "schema.ts"), {
encoding: "utf8",
});

expect(content).toMatchSnapshot();
});

test("transform pure lowercase snake_case to PascalCase", async () => {
await generateApi({
fileName: "schema",
input: path.resolve(import.meta.dirname, "schema.json"),
output: tmpdir,
silent: true,
enumNamesAsValues: false,
generateClient: false,
});

const content = await fs.readFile(path.join(tmpdir, "schema.ts"), {
encoding: "utf8",
});

// Check that pure lowercase snake_case values are transformed to PascalCase
expect(content).toMatchSnapshot();
});
});
18 changes: 17 additions & 1 deletion tests/spec/enumIncludesNumber/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,25 @@
"_1_VAL",
"A_1_B_2_C_3",
"_A_1_B_2_C_3",
"_1_A_2_B_3_C"
"_1_A_2_B_3_C",
"_123ValCamelCase",
"Val_Snake_Case",
"Val_12_CamelCase",
"_Val_12_Snake_Case",
"_Val_12_CamelCase"
],
"x-enum-descriptions": ["Foo", "Bar", "Baz"]
},
"LowercaseSnakeCaseEnum": {
"type": "string",
"enum": [
"local_only",
"phone_number",
"wait_dependency",
"auth_failed",
"waiting_to_push"
],
"description": "Pure lowercase snake_case values that should be transformed to PascalCase"
}
}
}
Expand Down