YousefED / typescript-json-schema

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

The generator `getMainFileSymbols` function ignores types if it is a built-in Node type #487

Open dhondtlaurens opened 2 years ago

dhondtlaurens commented 2 years ago

When I try to generate a scheme from the following types, only UserInfoBla will be generated because UserInfo is a built-in node type.

export interface UserInfo {
  id: string
  email: string
  userName: string
  fullName: string
}

export interface UserInfoBla {
  id: string
  email: string
  userName: string
  fullName: string
}

Below console.log statement will refer to the built-in node type instead of our own defined type. This probably discards the type and so it is ignored in the output.

    JsonSchemaGenerator.prototype.getMainFileSymbols = function (program, onlyIncludeFiles) {
        var _this = this;
        function includeFile(file) {
            if (onlyIncludeFiles === undefined) {
                return !file.isDeclarationFile;
            }
            return onlyIncludeFiles.filter(function (f) { return (0, path_equal_1.pathEqual)(f, file.fileName); }).length > 0;
        }
        var files = program.getSourceFiles().filter(includeFile);
        if (files.length) {
            return Object.keys(this.userSymbols).filter(function (key) {
                var symbol = _this.userSymbols[key];
                console.log(symbol)
                if (!symbol || !symbol.declarations || !symbol.declarations.length) {
                    return false;
                }
                var node = symbol.declarations[0];
                while (node === null || node === void 0 ? void 0 : node.parent) {
                    node = node.parent;
                }
                return files.indexOf(node.getSourceFile()) > -1;
            });
        }
        return [];
    };

My current workaround is to manually push the symbol name before passing it to the getSchemaForSymbols function. This works but is very error-prone cause we didn't know the UserInfo type was built-in, which might lead to further errors in the future.

/* eslint-disable @typescript-eslint/no-var-requires */

const fs = require('fs')
const TJS = require('typescript-json-schema')

const settings = {
  id: 'jsonSchema',
  required: true,
}

const options = {
  strictNullChecks: true,
  esModuleInterop: true,
}

const files = [
  './src/xxx/xxx.ts',
  './src/xxx.ts',
]

const program = TJS.getProgramFromFiles(files, options)
const generator = TJS.buildGenerator(program, settings)

const mainFileSymbols = generator.getMainFileSymbols(program)
// mainFileSymbols.push('UserInfo')

const jsonSchema = generator.getSchemaForSymbols(mainFileSymbols)
const content = `export default ${JSON.stringify(jsonSchema, null, 2)}`

fs.writeFileSync('./src/schema.ts', content)
zenatshockbyte commented 1 year ago

We seem to be having a similar issue but with types like 'Text' and 'Image' (though I think these are gotten from ts itself)