arktype icon indicating copy to clipboard operation
arktype copied to clipboard

jsonSchemaToType is not allowing $ref

Open sukeshpabolu opened this issue 6 months ago • 6 comments

Report a bug

Getting Uncaught (in promise) ParseError: Provided JSON Schema must have at least one of the keys 'type', 'enum', 'const', 'allOf', 'anyOf', 'oneOf' and 'not' exception while trying to use $ref.

🔎 Search Terms

$ref, jsonSchemaToType, parseJsonSchema

🧩 Context

  • ArkType version: 2.1.20
  • TypeScript version (5.1+): 5.8.3
  • Other context you think may be relevant (JS flavor, OS, etc.): deno, windows 10

🧑‍💻 Repro

Playground Link: https://arktype.io/playground

import { scope, type } from "npm:arktype"
import { jsonSchemaToType } from "npm:@ark/json-schema"

const types = scope({ a: { b: "b" }, b: { a: "a" } }).export();

const jsonSchema = types.a.toJsonSchema();

T = jsonSchemaToType(jsonSchema)

sukeshpabolu avatar Aug 04 '25 09:08 sukeshpabolu

As the person who implemented @ark/json-schema, lack of $ref support was deliberate, in the interest of getting something of value out as soon as possible.

I think the bug here is primarily that it's not listed as a limitation in the README, like dependencies and if/else/then support.

It's an interesting side-effect that this breaks ArkType scopes like the one you provided here. Maybe a nicer error could be provided instead (e.g. "conversion of scopes to json schema is not currently supported") in the interim?

Will leave @ssalbdivad to formally classify this, but fwiw my thoughts are that at its core this is ultimately a feature requests for adding $ref support to @ark/json-schema.

TizzySaurus avatar Aug 04 '25 14:08 TizzySaurus

I can understand the lack of support for dependencies or if, else. But why there is no support for $ref? Could you suggest any alternative?

SukeshP1995 avatar Aug 05 '25 06:08 SukeshP1995

@SukeshP1995 if you're writing the actual JSON Schema yourself, then you can do something like:

const repeatedSchema = {
    type: "string",
    minLength: 1,
    maxLength: 10
} as const;

const t = jsonSchemaToType({
    type: "object",
    properties: {
        name: repeatedSchema,
        surname: repeatedSchema,
        age: { type: "number" },
    }
});

TizzySaurus avatar Aug 05 '25 06:08 TizzySaurus

I already have json-schema in a file. I need 1 clarification. Can we use jsonSchemaToType like how we use ajv? I just need validation and get the errors.

sukeshpabolu avatar Aug 05 '25 06:08 sukeshpabolu

@sukeshpabolu Yes, jsonSchemaToType can be used similarly to ajv.

Once you have your arktype type (in my example above, t), you can do either:

import { ArkErrors } from "arktype";
...

const validationResult = t(someData);
if (validationResult instanceof ArkErrors) {
    console.log(validationResult.summary); // log validation errors
    return
}

or:

const validationResult = t.assert(someData); // automatically throw if validation fails

TizzySaurus avatar Aug 05 '25 07:08 TizzySaurus

This is cool. I just need a way to handle those refs. I may have to use something like this

sukeshpabolu avatar Aug 05 '25 07:08 sukeshpabolu