asteasolutions / zod-to-openapi

A library that generates OpenAPI (Swagger) docs from Zod schemas
MIT License
916 stars 57 forks source link

Turn union of literals into OpenAPI enum of numbers #237

Closed forcia-tishii closed 3 months ago

forcia-tishii commented 3 months ago

Thank you for the great library!

I define enum of numbers using Zod union of literals. For example,

const Schema = z.object({
  hoge: z.union([z.literal(0), z.literal(1)]
})

That generates OpenAPI like this:

{
  "type": "object",
  "properties": {
    "hoge": {
      "anyOf": {
        { "type": "number", "enum": [0] },
        { "type": "number", "enum": [1] }
      }
    }
  }
}

But, I want that generates it like this:

{
  "type": "object",
  "properties": {
    "hoge": {
      "type": "number",
      "enum": [0, 1]
    }
  }
}
AGalabov commented 3 months ago

@forcia-tishii thank you for the kind words. I definitely do see your point. However implementing this within our library would be "hacky" and would be as some sort of an edge case and I am currently against that.

This would ideally be implemented with z.enum([0,1]). However that is not supported from zod itself - https://github.com/colinhacks/zod/issues/2686

The suggested workaround there to use nativeEnum would also work in our case:

enum Numbers {
  zero = 0,
  one = 1,
}

const Schema = z
  .object({
    hoge: z.nativeEnum(Numbers),
  })

Finally if you insist on that validation with numbers you can just opt in for manual documentation and it probably won't hurt you too much:

const Schema = z
  .object({
    hoge: z.union([z.literal(0), z.literal(1)]).openapi({
      type: 'number',
      enum: [0, 1],
    }),
  })

Hope that helps! I am closing this issue since I do not think there is anything else we can help with. If you have further questions feel free to ask and even reopen the issue without hesitation.

forcia-tishii commented 3 months ago

@AGalabov Thank you for your response. I understand your thought. I think this is an edge case.

Thank you for your sample codes!