vazco / uniforms

A React library for building forms from any schema.
https://uniforms.tools
MIT License
1.95k stars 241 forks source link

$ref in subschemas #1286

Open ph-poppe opened 1 year ago

ph-poppe commented 1 year ago

Before you open an issue, please check if a similar one already exists or has been closed before. Detailed information about the process of contributing can be found in CONTRIBUTING.md.

Let us know what is happening. Do provide us with:

versions: "uniforms": "^4.0.0-alpha.5", "uniforms-bridge-json-schema": "^4.0.0-alpha.5", "ajv": "^8.0.0",

run on chrome, React v 16.14

I have 2 schemas that are combined in a final one:

subschema1:

// note: instanceOf is handled by ajv
{
  $id: "/schemas/dateDef",
  oneOf: [{ type: "string", format: "date-time" }, { instanceof: "Date" }]
};

subschema 2:

{
  $id: "schemas/schema2",
  $schema: "http://json-schema.org/draft-07/schema#",
  type: "object",
  properties: {
    receivedDate: {
      $ref: "#/definitions/dateDef"
    },
    dueDate: {
      $ref: "#/definitions/dateDef"
    }
  },
  definitions:{
    dateDef:...
  }
}

final schema:

{
  type: "object",
  properties: {
     test: {$ref: "#/definitions/subSchema2"}
  },
  definitions: {
   subSchema2:...
 }
}

When this is loaded into the jonschemabridge, I hit the problem that dateDef is not resolved. In the jsonschemabridge he is looking for the dateDef definition in the parent schema, not in the subschema (subSchema2) and hence throwing an error. Is there a way for the bridge to look up the definition in the subschema?

current workaround:

thanks for the support!

zendranm commented 5 months ago

No solution yet but, it seems the problem is the recursive nature of the resolveRefIfNeeded function used in the getField method. In the initial iteration, in the resolveRef function, the reference is correctly resolved against the schema. But if the next reference points to a nested schema, the reduce still tries to resolve that against the first level of the schema, instead of the nested schema.

Using the example provided in the issue description, the reference #/definitions/subSchema2 is correctly resolved against the final schema as schema.definitions['subSchema2'].

However, the reference #/definitions/dateDef is resolved as schema.definitions['dateDef'] whereas it should be schema.definitions['subSchema2'].definitions['dateDef'].

The proposed workaround should add the nested schema to the parent, but in my case ajv throws an error "Error: reference resolves to more than one schema".