Skip to content

Schema refs are assigned regardless of .describe() calls #123

@kachkaev

Description

@kachkaev

I believe I have found a small bug similar to #66. Using [email protected]. Here is a reproduction:

const sharedFieldSchema = /* ... see below ... */;
const schema = z.object({
  foo: sharedFieldSchema.describe('This is foo'),
  bar: sharedFieldSchema.describe('This is bar'),
  baz: sharedFieldSchema,
});
console.log(zodToJsonSchema(schema));

z.string()

No description in baz, as expected.

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "description": "This is foo"
    },
    "bar": {
      "type": "string",
      "description": "This is bar"
    },
    "baz": {
      "type": "string"
    }
  },
  "required": [
    "foo",
    "bar",
    "baz"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

z.string().min(1).max(255)

No description in baz, as expected.

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "description": "This is foo"
    },
    "bar": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "description": "This is bar"
    },
    "baz": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    }
  },
  "required": [
    "foo",
    "bar",
    "baz"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

z.string().default('default value')

Both bar and baz refer to foo, so baz unexpectedly inherits foo’s description.

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "default": "default value",
      "description": "This is foo"
    },
    "bar": {
      "$ref": "#/properties/foo",
      "default": "default value",
      "description": "This is bar"
    },
    "baz": {
      "$ref": "#/properties/foo",
      "default": "default value"
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

z.string().catch('caught value')

Same as above: Both bar and baz refer to foo, so baz unexpectedly inherits foo’s description.

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "description": "This is foo"
    },
    "bar": {
      "$ref": "#/properties/foo",
      "description": "This is bar"
    },
    "baz": {
      "$ref": "#/properties/foo"
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

If I call zodToJsonSchema(schema, { $refStrategy: 'none' }), description no longer ‘leaks’, which is great. However, it’d be great to see it not leaking by default because misplaced tooltips with description are confusing.

PS: Thanks for the lib! It’s really neat an super-useful! 🙌

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions