Skip to content

Cabidela mutates schema and remove $defs when using applyDefaults: true #16

@mattallty

Description

@mattallty

Hello,

And thanks for this library!

I noticed a serious bug where Cabidela mutates the original schema when validating data.

Here is the bug demo where $defs are completely removed from the original schema when using applyDefaults: true.

import { describe, expect, test } from "vitest";
import { Cabidela } from "@cloudflare/cabidela";

describe("Cabidela schema validation bug with applyDefaults and $defs", () => {
  const schema = {
    $id: "http://example.com/schemas/main",
    type: "object",
    properties: {
      name: { type: "string" },
      balance: { $ref: "$defs#/balance" },
    },
    required: ["name", "balance"],
    $defs: {
      balance: {
        type: "object",
        properties: {
          currency: { type: "string" },
          amount: { type: "number" },
        },
      },
    },
  };

  const schemaBeforeValidationSerialized = JSON.stringify(schema);

  // Using applyDefaults: true should not mutate the original schema, but it does
  const validator = new Cabidela(schema, {
    applyDefaults: true,
  });

  // PASS
  test("validation passes for valid data", () => {
    const validData = { name: "Alice", balance: { currency: "USD", amount: 100 } };
    expect(validator.validate(validData)).toBe(true);
  });

  const schemeAfterValidationSerialized = JSON.stringify(schema);

  // PASS
  test("schemaBeforeValidationSerialized contains $defs", () => {
    expect(schemaBeforeValidationSerialized).toContain(`"$defs"`);
  });

  // FAILING TEST: This test fails because the schema is mutated by Cabidela and $defs disappears :(
  test("schemaAfterValidationSerialized still contains $defs", () => {
    expect(schemeAfterValidationSerialized).toContain(`"$defs"`);
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions