Skip to content

fix(massimo-cli): quote enum members by value type - #174

Open
fgiova wants to merge 1 commit into
platformatic:mainfrom
fgiova:fix/fix-enums-whitout-type
Open

fix(massimo-cli): quote enum members by value type#174
fgiova wants to merge 1 commit into
platformatic:mainfrom
fgiova:fix/fix-enums-whitout-type

Conversation

@fgiova

@fgiova fgiova commented Aug 11, 2026

Copy link
Copy Markdown

Fixes #173

Problem

getType() decided whether to quote enum members from the schema's type keyword. type is optional in JSON Schema / OpenAPI 3.x — the enum already constrains the value — so a spec like

"tone": { "enum": ["informale", "formale", "amichevole"] }

fell into the else branch and emitted bare identifiers:

'tone': informale | formale | amichevole;   // TS2304: Cannot find name 'informale'

making the generated index.d.mts non-compilable. The same enum with "type": "string" was generated correctly.

A literal null inside an enum was also stringified to an empty union member ('a' | ), another syntax error.

Change

Quote each member by its own runtime type instead of by the schema type:

.map(en => {
  // Quote by the runtime type of the value: the schema may omit `type`
  if (en === null) return 'null'
  if (typeof en === 'string') return `'${en.replace(/'/g, "\\'")}'`
  return en
})

The pre-existing early return above it (type === undefined + an enum containing the string 'null'null) is left untouched: that is the existing encoding for nullable types and would otherwise start emitting 'null'.

Behaviour

input schema before after
{ enum: ['a','b'] } a | b 'a' | 'b'
{ type: 'string', enum: ['a','b'] } 'a' | 'b' unchanged
{ enum: [1,2] } 1 | 2 unchanged
{ enum: [true,false] } true | false unchanged
{ enum: ["it's"] } it's 'it\'s'
{ enum: ['a', null] } 'a' | 'a' | null

Tests

Added support enum without type to packages/massimo-cli/test/get-type.test.js, covering the table above plus an untyped enum nested in an object.

test/get-type.test.js passes (21/21), as do test/cli-openapi*.test.js and test/frontend-openapi.test.js (81/81). Lint is clean.

getType decided enum quoting from the schema `type`, so a valid
untyped enum (`{ enum: ['a', 'b'] }`) emitted bare identifiers
(`a | b`) instead of string literals, producing non-compilable
.d.ts. A literal `null` in an enum also stringified to an empty
member (`'a' | `).

Quote per value by its runtime type instead. The pre-existing
early return for `type === undefined` + the string `'null'`
(nullable encoding) is untouched.

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

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.

massimo-cli emits invalid TypeScript for enums declared without an explicit type

2 participants