Skip to content

Conversation

@PSiemieniuk
Copy link

@PSiemieniuk PSiemieniuk commented Dec 17, 2025

Summary

Fixes enum key formatting to preserve mixed case names with underscores while still transforming pure lowercase snake_case to PascalCase. This resolves TypeScript compilation errors caused by stripping leading underscores from numeric-prefixed identifiers.

Problem

When generating TypeScript enums from OpenAPI schemas, the formatter was incorrectly transforming enum keys that contained underscores and mixed case (e.g., _123ValCamelCase, _Val_12_CamelCase, Val_Snake_Case) into camelCase variants, losing the original casing and underscore structure.

Critical Issue: The transformation of _123ValCamelCase to 123ValCamelCase produced invalid TypeScript code that failed to compile, since identifiers cannot start with a digit. The leading underscore is semantically important and must be preserved.

The issue occurred because the regex pattern in type-name-formatter.ts only checked for all-uppercase constants (/^(?!\d)([A-Z0-9_]{1,})$/g), causing mixed case values to fall through to the lodash.startCase transformation, which would strip meaningful casing information and create syntax errors.

Example Issue

Given this enum schema:

{
"type": "string",
"enum": [
"VAL_1", // SCREAMING_SNAKE_CASE (uppercase only)
"_123ValCamelCase", // Mixed case starting with underscore + digit
"_Val_12_CamelCase", // Mixed case with underscores
"Val_Snake_Case", // Mixed case with underscores
"local_only" // Pure lowercase snake_case
]
}Before:

  • _123ValCamelCase123ValCamelCaseTypeScript compilation error!
  • _Val_12_CamelCaseVal12CamelCase1
  • Val_Snake_CaseValSnakeCase
  • local_onlyLocalOnly ✅ (correct)

After:

  • _123ValCamelCase_123ValCamelCaseValid TypeScript
  • _Val_12_CamelCase_Val_12_CamelCase
  • Val_Snake_CaseVal_Snake_Case
  • local_onlyLocalOnly

Solution

Added specific logic in src/type-name-formatter.ts to detect and preserve mixed case enum keys with underscores. The fix distinguishes between:

  1. SCREAMING_SNAKE_CASE (all uppercase + underscores) - already preserved
  2. Mixed case with underscores (e.g., _123ValCamelCase, _Val_12_CamelCase) - now preserved
  3. Pure lowercase snake_case (e.g., local_only) - still transformed to PascalCase

The solution adds a new condition specifically for enum-key types that checks for:

  • Valid identifier pattern with alphanumeric + underscores
  • Presence of underscores
  • Presence of at least one uppercase letter (mixed case detection: /[A-Z]/.test(name))

This prevents unwanted transformation of intentionally mixed case enum keys while maintaining the existing behavior for pure lowercase snake_case, and critically prevents TypeScript syntax errors from removing semantically important leading underscores.

Changes

Core Fix

  • src/type-name-formatter.ts: Added mixed case detection logic (lines 39-46) that preserves enum keys containing both uppercase and lowercase letters with underscores

Test Coverage

  • tests/spec/enumIncludesNumber/schema.json: Includes test case for _123ValCamelCase (underscore + digit prefix) and added LowercaseSnakeCaseEnum to test pure lowercase transformation
  • tests/spec/enumIncludesNumber/basic.test.ts: Added third test case "transform pure lowercase snake_case to PascalCase" to verify both behaviors
  • tests/spec/enumIncludesNumber/snapshots/basic.test.ts.snap: Updated snapshots to reflect correct formatting

Meta

  • .changeset/preserve-mixed-case-enum-keys.md: Added changeset (patch)

Testing

All 134 tests pass, including:

  • Original enum formatting tests continue to work (SCREAMING_SNAKE_CASE preserved)
  • New test cases validate mixed case preservation, especially _123ValCamelCase_123ValCamelCase (preventing TS errors)
  • Existing tests confirm pure lowercase snake_case still transforms to PascalCase (local_onlyLocalOnly)
  • No regression in other test suites (extended.test.ts, simple.test.ts, etc.)

Note

Fixes enum key formatting by detecting mixed case (uppercase + lowercase) in enum keys and preserving their original form, preventing TypeScript compilation errors from invalid identifiers like 123ValCamelCase, while maintaining PascalCase transformation for pure lowercase snake_case values.

@changeset-bot
Copy link

changeset-bot bot commented Dec 17, 2025

🦋 Changeset detected

Latest commit: de5d6ec

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
swagger-typescript-api Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor
Copy link

cursor bot commented Dec 17, 2025

Skipping Bugbot: Unable to authenticate your request. Please make sure Bugbot is properly installed and configured for this repository.

@PSiemieniuk
Copy link
Author

bugbot run

@cursor
Copy link

cursor bot commented Dec 17, 2025

Skipping Bugbot: Bugbot is disabled for this repository

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant