YousefED / typescript-json-schema

Generate json-schema from your Typescript sources
BSD 3-Clause "New" or "Revised" License
3.08k stars 318 forks source link

πŸ› different output in `cli` than `programatically` #565

Open lukas-runge opened 10 months ago

lukas-runge commented 10 months ago

When trying to use typescript-json-schema programatically I stubled across some weird behaviour that did not match the cli output. I build a minimal example to reproduce this issue fast: https://github.com/lukas-runge/tjs-bug-demo. πŸ™Œ

The cli command:

typescript-json-schema --required src/udr.next.d.ts Device

The programatic implementation of the "same" thing:

import * as TJS from "typescript-json-schema";

const settings: TJS.PartialArgs = { required: true };

const program = TJS.getProgramFromFiles(["src/udr.next.d.ts"]);

const schema = TJS.buildGenerator(program, settings)?.getSchemaForSymbol("Device")

console.log(JSON.stringify(schema, null, 4));

The programatically generated schema is missing one required property (test):

$ yarn cli && yarn programatic
$ typescript-json-schema --required src/udr.next.d.ts Device
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "properties": {
        "class": {
            "type": "string"
        },
        "friendlyName": {
            "type": "string"
        },
        "test": {
            "type": "string"
        },
        "unitNumber": {
            "type": "string"
        },
        "userIdentifier": {
            "type": "string"
        }
    },
    "required": [
        "class",
        "test",
        "userIdentifier"
    ],
    "type": "object"
}

$ ts-node main.ts
{
    "type": "object",
    "additionalProperties": {},
    "properties": {
        "class": {
            "type": "string"
        },
        "userIdentifier": {
            "type": "string"
        },
        "friendlyName": {
            "type": "string"
        },
        "unitNumber": {
            "type": "string"
        }
    },
    "required": [
        "class",
        "userIdentifier"
    ],
    "$schema": "http://json-schema.org/draft-07/schema#"
}
✨  Done in 3.15s.

I tried to fix or workaround this on my own but didn't get it resolved. I would really appreciate if someone has an idea for a quick workaround or even fix. πŸ™

Looking forward to getting this resolved! πŸš€

Best regards, @lukas-runge

lukas-runge commented 10 months ago

I just found a workaround when having a deeper look into the inner workings of typescript-json-schema and at least found a viable workaround for my use case.

By passing the files array into the buildGenerator as onlyIncludeFiles-parameter I can match the cli's behaviour. πŸ₯³ I published the workaround under a new branch in my demo repo for reference: https://github.com/lukas-runge/tjs-bug-demo/commit/5f3de743f08f3ca838659fa701353fcb1d344c66

import * as TJS from "typescript-json-schema";

const settings: TJS.PartialArgs = { required: true };

const files = ["src/udr.next.d.ts"];

const program = TJS.getProgramFromFiles(files);

const schema = TJS.buildGenerator(program, settings, files)?.getSchemaForSymbol("Device")

console.log(JSON.stringify(schema, null, 4));

I still find this shouldn't be the default behaviour. Maybe someone more experienced can explain what's actually going on here under the hood and if it's a bug or a feature. In any case I'd say there needs to be documentation on a programmatical implementation that matches the one of the cli. πŸ™Œ

Best regards, @lukas-runge