asteasolutions / zod-to-openapi

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

Question. Why is z.custom not required by default #252

Open brupxxxlgroup opened 2 months ago

brupxxxlgroup commented 2 months ago

Following schema definition

const dataSourceSchema = registry.register(
    "DataSource",
    z
      .object({
        urn: z.custom<string>().openapi({
          description: "A unique URN for this datasource.",
        }),
        uri: z.string().openapi({
          description: "A URI where this data originated from.",
        }),
        date: z.string().openapi({
          description: "A point in time when this datasource was processed.",
        }),
      })
      .openapi({
        description: "wsdsdsdsd",
      })
  );

will produce following yaml


  DataSource:
    type: object
    properties:
      urn:
        nullable: true
        description: A unique URN for this datasource.
      uri:
        type: string
        description: A URI where this data originated from.
      date:
        type: string
        description: A point in time when this datasource was processed.
    required:
      - uri
      - date
    description: wsdsdsdsd

Why is it that

I have tried to work around with

const dataSourceSchema = registry.register(
    "DataSource",
    z
      .object({
        urn: z.custom<string>().openapi({
          description: "A unique URN for this datasource.",
        }),
        uri: z.string().openapi({
          description: "A URI where this data originated from.",
        }),
        date: z.string().openapi({
          description: "A point in time when this datasource was processed.",
        }),
      })
      .openapi({
        description: "wsdsdsdsd",
        required : ["urn", "uri", "date"]
      })
  );

But when referencing this schema from another schema like this

  const otherSchema = zodOpenApiController.getRegistry().register(
    "OtherSchema",
    z.object({
      datasource: dataSourceSchema,
    })
  );

the yaml seems not correct to me

    DataSource:
      type: object
      properties:
        urn:
          nullable: true
          description: A unique URN for this datasource.
        uri:
          type: string
          description: A URI where this data originated from.
        date:
          type: string
          description: A point in time when this datasource was processed.
      required:
        - urn
        - uri
        - date
      description: wsdsdsdsd
    OtherSchema:
      type: object
      properties:
        datasource:
          allOf:
            - $ref: "#/components/schemas/DataSource"
            - required:
                - uri
                - date

What am i doing wrong? Why is it generating this strange allOff

Thx. for help!

AGalabov commented 1 month ago

@brupxxxlgroup as for your initial question - well because this is the way zod works when it parses data. Using your example the following:

  dataSourceSchema.safeParse({
    uri: 'some uri',
    date: 'some date',
  })

would result in { success: true, data: { uri: 'some uri', date: 'some date' } }

and so would passing urn: null. So it should be nullable.

As for your other question. This is an interesting one. We should look into it, however I do not know when we would be able to present a fix.