An open API service indexing awesome lists of open source software.

https://github.com/mrmarble/openapi-typescript-generator-one-of


https://github.com/mrmarble/openapi-typescript-generator-one-of

Last synced: 3 months ago
JSON representation

Awesome Lists containing this project

README

          

# OpenAPI Generator TypeScript-Fetch OneOf Enum Bug

This repository demonstrates a critical bug in the OpenAPI Generator's TypeScript-Fetch generator where enum types are not properly generated when used within `oneOf` schemas under specific naming conditions.
https://github.com/OpenAPITools/openapi-generator/issues/21999

## Bug Description

The OpenAPI Generator fails to generate enum constants when **all** of the following conditions are met:

1. An enum schema is referenced within a `oneOf` construct
2. The enum schema name follows the pattern `{ModelName}{FieldName}` (e.g., `BuggyOneOfExampleSource` for model `BuggyOneOfExample` with field `source`)
3. The generator is set to `typescript-fetch`

When this occurs, instead of generating the actual enum constants, the generator creates a recursive type definition that references itself, making the enum unusable.

## Environment

- **OpenAPI Generator Version**: 7.15.0
- **Generator**: typescript-fetch
- **OpenAPI Specification**: 3.0.3

## Reproduction

1. Clone this repository
2. Run `npm install`
3. Run `npm run generate`
4. Examine the generated file `src/generated/models/index.ts`

## Test Scenarios

This repository includes three distinct scenarios to demonstrate the bug and working alternatives:

### 1. 🐛 Broken Scenario (`/broken-oneof`)

**OpenAPI Schema:**
```yaml
BuggyOneOfExample:
type: object
properties:
source:
oneOf:
- $ref: '#/components/schemas/BuggyOneOfExampleSource'
- $ref: '#/components/schemas/EmptyValue'

BuggyOneOfExampleSource:
type: string
enum:
- MANUAL
- SCANNER
- OTHER
```

**Problem**: The enum name `BuggyOneOfExampleSource` follows the `{ModelName}{FieldName}` pattern, causing the generator to fail.

### 2. ✅ Working Scenario (`/working-oneof`)

**OpenAPI Schema:**
```yaml
WorkingOneOfExample:
type: object
properties:
source:
oneOf:
- $ref: '#/components/schemas/CustomNamedSourceEnum'
- $ref: '#/components/schemas/EmptyValue'

CustomNamedSourceEnum:
type: string
enum:
- MANUAL
- SCANNER
- OTHER
```

**Solution**: Using a custom name `CustomNamedSourceEnum` that doesn't match the `{ModelName}{FieldName}` pattern works correctly.

### 3. ✅ Direct Reference Scenario (`/direct-reference`)

**OpenAPI Schema:**
```yaml
DirectReferenceExample:
type: object
properties:
source:
$ref: '#/components/schemas/DirectReferenceExampleSource'

DirectReferenceExampleSource:
type: string
enum:
- MANUAL
- SCANNER
- OTHER
```

**Solution**: Direct references (without `oneOf`) work correctly even when following the `{ModelName}{FieldName}` naming pattern.

## Generated TypeScript Code

After running `npm run generate`, examine `src/generated/models/index.ts` to see the difference:

### 🐛 Broken Output (BuggyOneOfExampleSource)

```typescript
/**
* @type BuggyOneOfExampleSource
*
* @export
*/
export type BuggyOneOfExampleSource = BuggyOneOfExampleSource | EmptyValue;
```

**Issue**: The enum constants (`MANUAL`, `SCANNER`, `OTHER`) are missing! Instead, there's a recursive type definition that references itself.

### ✅ Working Output (CustomNamedSourceEnum)

```typescript
/**
*
* @export
*/
export const CustomNamedSourceEnum = {
Manual: 'MANUAL',
Scanner: 'SCANNER',
Other: 'OTHER'
} as const;
export type CustomNamedSourceEnum = typeof CustomNamedSourceEnum[keyof typeof CustomNamedSourceEnum];
```

**Correct**: The enum constants are properly generated and usable.

### ✅ Working Output (DirectReferenceExampleSource)

```typescript
/**
*
* @export
*/
export const DirectReferenceExampleSource = {
Manual: 'MANUAL',
Scanner: 'SCANNER',
Other: 'OTHER'
} as const;
export type DirectReferenceExampleSource = typeof DirectReferenceExampleSource[keyof typeof DirectReferenceExampleSource];
```

**Correct**: Even with the `{ModelName}{FieldName}` pattern, direct references work fine.

## Impact

This bug makes it impossible to use properly named enum schemas within `oneOf` constructs, forcing developers to use non-intuitive naming conventions or restructure their API specifications.