xddq / schema2typebox

Creating TypeBox code from JSON schemas
MIT License
66 stars 15 forks source link

error parsing a ref based schema #38

Open croconut opened 8 months ago

croconut commented 8 months ago

Library version:

1.7.1

JSON schema version: draft-04

The current behavior

Fails to parse with Unsupported schema.

The expected behavior

Parsing correctly. What I would really like is a separate typebox definition for each defined schema, but getting the top level schema is good, since i can pull it apart when I use it.

Why does it happen? What/How to fix the issue?

Probably the top level ref -> definitions usage. It is valid tho afaik, was working with my other tools. Hard to say since this is the only thing I've attempted to use this cli for.

Content of minimal json schema file which causes the problem

Click to expand/collapse ```json { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3Event", "definitions": { "S3Bucket": { "required": [ "name", "ownerIdentity", "arn" ], "properties": { "arn": { "type": "string" }, "name": { "type": "string" }, "ownerIdentity": { "$ref": "#/definitions/S3UserIdentity" } }, "additionalProperties": false, "type": "object" }, "S3Entity": { "required": [ "s3SchemaVersion", "configurationId", "bucket", "object" ], "properties": { "bucket": { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3Bucket" }, "configurationId": { "type": "string" }, "object": { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3Object" }, "s3SchemaVersion": { "type": "string" } }, "additionalProperties": false, "type": "object" }, "S3Event": { "required": [ "Records" ], "properties": { "Records": { "items": { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3EventRecord" }, "type": "array" } }, "additionalProperties": false, "type": "object" }, "S3EventRecord": { "required": [ "eventVersion", "eventSource", "awsRegion", "eventTime", "eventName", "userIdentity", "requestParameters", "responseElements", "s3" ], "properties": { "awsRegion": { "type": "string" }, "eventName": { "type": "string" }, "eventSource": { "type": "string" }, "eventTime": { "type": "string", "format": "date-time" }, "eventVersion": { "type": "string" }, "requestParameters": { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3RequestParameters" }, "responseElements": { "patternProperties": { ".*": { "type": "string" } }, "type": "object" }, "s3": { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3Entity" }, "userIdentity": { "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/S3UserIdentity" } }, "additionalProperties": false, "type": "object" }, "S3Object": { "required": [ "key", "size", "urlDecodedKey", "versionId", "eTag", "sequencer" ], "properties": { "eTag": { "type": "string" }, "key": { "type": "string" }, "sequencer": { "type": "string" }, "size": { "type": "integer" }, "urlDecodedKey": { "type": "string" }, "versionId": { "type": "string" } }, "additionalProperties": false, "type": "object" }, "S3RequestParameters": { "required": [ "sourceIPAddress" ], "properties": { "sourceIPAddress": { "type": "string" } }, "additionalProperties": false, "type": "object" }, "S3UserIdentity": { "required": [ "principalId" ], "properties": { "principalId": { "type": "string" } }, "additionalProperties": false, "type": "object" } } } ```
croconut commented 8 months ago

I'll inline the top level object and see how that works

croconut commented 8 months ago

It worked once I did that. Looks like it was that it didnt expect the top level to be using a reference. Guess I'll do a minor rewrite for these schemas

luiscaro3 commented 3 days ago

Also, importing an array of $refs translates into a Type.Union() that doesn't include the square brackets which breaks the output. It actually shouldn't bring a Union, just the Type.Object

sinclairzx81 commented 3 days ago

@xddq @croconut Hi,

Just a heads up. The signature for Ref changed on 0.34.0. The Ref signature was updated to accept a string argument.

// 0.33.0

const T = Type.String({ $id: 'T' })

const R = Type.Ref(T)

// 0.34.0

const T = Type.String({ $id: 'T' })

const R = Type.Ref('T')

I have noticed this issue this morning, and for now reverted the 0.33.0 signature on 0.34.7 under a @deprecated flag (@croconut so if you update to 0.34.7 things should work again). @xddq To properly support to the new signature, the generated code should look as follows.

const T = Type.String({ $id: 'T' }) // previously generated type

// This is the recommend way to support raw references in 0.34.0 and beyond.

const R = Type.Unsafe<Static<typeof T>>(Type.Ref(T.$id!))

This should resolve any @deprecated warnings. Just note these changes are in support of bringing the Workbench / Codegen model into TypeBox under a new type called Module. This supports singular and mutually recursive inference. Details on the type can be found below.

https://github.com/sinclairzx81/typebox?tab=readme-ov-file#module-types

With code generation also integrated via the new Syntax Types feature

https://github.com/sinclairzx81/typebox?tab=readme-ov-file#module

Hope this helps S