asteasolutions / zod-to-openapi

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

support for custom names for dynamic keys in `additionalProperties` #246

Closed pswenson closed 1 month ago

pswenson commented 4 months ago

problem:

when an API object has a dynamically generated key name from z.record in the zod schema, tools like redocly and swagger show the key name as "Property1", "Property2". This is very confusing to the API users as these key names have specific meaning.

CleanShot 2024-07-03 at 08 56 21@2x

notice in this redocly screen where you see Property1/Property2 we want to indicate this is a context specific ID, e.g. slotId1 or any arbitrary name/ID.

To support human readable names when there are additional properties on openapi map like objects <z.record>, redocly and some other renderers have added x-additionalPropertiesName to allow overriding the auto-generated names such as Property1 or Property2.

see https://github.com/Redocly/redoc/blob/main/docs/redoc-vendor-extensions.md#x-additionalpropertiesname

we request being able to pass in x-additionalPropertiesName when openApi is called on the z.record method.

AGalabov commented 4 months ago

Hello @pswenson we've previously had one discussion around redoc and its additionally defined properties. See here. Based on the example from the documentation that you just send:

Player:
  required:
  - name

  properties:
    name:
      type: string

  additionalProperties:
    x-additionalPropertiesName: attribute-name
    type: string

you can achieve that by using the following schema:

const PlayerSchema = z.record(z.string()).openapi('Player', {
  additionalProperties: {
    type: 'string',
    'x-additionalPropertiesName': 'attribute-name',
  },
});

Please not that the type has to be written manually here. I understand that this might be inconvenient but this an overall design decision of the library - if the user consumer explicitly provides a root level value we automatically take that with higher precedence over anything else => since there is an additionalProperties field in the .openapi method - we would not work on inferring the type automatically.

Doest that work for you?