New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ts-json-schema-generator

Package Overview
Dependencies
Maintainers
1
Versions
340
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ts-json-schema-generator - npm Package Compare versions

Comparing version 0.46.0 to 0.47.0

dist/src/NodeParser/FunctionNodeParser.d.ts

2

dist/factory/parser.js

@@ -40,2 +40,3 @@ "use strict";

const TopRefNodeParser_1 = require("../src/TopRefNodeParser");
const FunctionNodeParser_1 = require("./../src/NodeParser/FunctionNodeParser");
function createParser(program, config) {

@@ -75,2 +76,3 @@ const typeChecker = program.getTypeChecker();

.addNodeParser(new NullLiteralNodeParser_1.NullLiteralNodeParser())
.addNodeParser(new FunctionNodeParser_1.FunctionNodeParser())
.addNodeParser(new PrefixUnaryExpressionNodeParser_1.PrefixUnaryExpressionNodeParser(chainNodeParser))

@@ -77,0 +79,0 @@ .addNodeParser(new LiteralNodeParser_1.LiteralNodeParser(chainNodeParser))

14

dist/src/NodeParser/IndexedAccessTypeNodeParser.js

@@ -6,2 +6,4 @@ "use strict";

const LiteralType_1 = require("../Type/LiteralType");
const NumberType_1 = require("../Type/NumberType");
const StringType_1 = require("../Type/StringType");
const typeKeys_1 = require("../Utils/typeKeys");

@@ -17,4 +19,5 @@ class IndexedAccessTypeNodeParser {

const indexType = this.childNodeParser.createType(node.indexType, context);
if (!(indexType instanceof LiteralType_1.LiteralType)) {
throw new LogicError_1.LogicError(`Unexpected type "${indexType.getId()}" (expected "LiteralType")`);
if (!(indexType instanceof LiteralType_1.LiteralType || indexType instanceof StringType_1.StringType || indexType instanceof NumberType_1.NumberType)) {
throw new LogicError_1.LogicError(`Unexpected type "${indexType.getId()}" (expected "LiteralType" or "StringType" ` +
`or "NumberType")`);
}

@@ -24,3 +27,8 @@ const objectType = this.childNodeParser.createType(node.objectType, context);

if (!propertyType) {
throw new LogicError_1.LogicError(`Invalid index "${indexType.getValue()}" in type "${objectType.getId()}"`);
if (indexType instanceof LiteralType_1.LiteralType) {
throw new LogicError_1.LogicError(`Invalid index "${indexType.getValue()}" in type "${objectType.getId()}"`);
}
else {
throw new LogicError_1.LogicError(`No additional properties in type "${objectType.getId()}"`);
}
}

@@ -27,0 +35,0 @@ return propertyType;

@@ -11,3 +11,4 @@ import * as ts from "typescript";

private getProperties;
private getAdditionalProperties;
private createSubContext;
}

@@ -6,3 +6,5 @@ "use strict";

const NodeParser_1 = require("../NodeParser");
const ArrayType_1 = require("../Type/ArrayType");
const LiteralType_1 = require("../Type/LiteralType");
const NumberType_1 = require("../Type/NumberType");
const ObjectType_1 = require("../Type/ObjectType");

@@ -25,3 +27,3 @@ const StringType_1 = require("../Type/StringType");

if (keyListType instanceof UnionType_1.UnionType) {
return new ObjectType_1.ObjectType(id, [], this.getProperties(node, keyListType, context), false);
return new ObjectType_1.ObjectType(id, [], this.getProperties(node, keyListType, context), this.getAdditionalProperties(node, keyListType, context));
}

@@ -34,2 +36,5 @@ else if (keyListType instanceof LiteralType_1.LiteralType) {

}
else if (keyListType instanceof NumberType_1.NumberType) {
return new ArrayType_1.ArrayType(this.childNodeParser.createType(node.type, this.createSubContext(node, keyListType, context)));
}
else {

@@ -40,3 +45,5 @@ throw new LogicError_1.LogicError(`Unexpected key type "${constraintType.getId()}" for type "${node.getText()}" (expected "UnionType" or "StringType")`);

getProperties(node, keyListType, context) {
return keyListType.getTypes().reduce((result, key) => {
return keyListType.getTypes()
.filter(type => type instanceof LiteralType_1.LiteralType)
.reduce((result, key) => {
const objectProperty = new ObjectType_1.ObjectProperty(key.getValue().toString(), this.childNodeParser.createType(node.type, this.createSubContext(node, key, context)), !node.questionToken);

@@ -47,2 +54,11 @@ result.push(objectProperty);

}
getAdditionalProperties(node, keyListType, context) {
const key = keyListType.getTypes().filter(type => !(type instanceof LiteralType_1.LiteralType))[0];
if (key) {
return this.childNodeParser.createType(node.type, this.createSubContext(node, key, context));
}
else {
return false;
}
}
createSubContext(node, key, parentContext) {

@@ -49,0 +65,0 @@ const subContext = new NodeParser_1.Context(node);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ts = require("typescript");
const ArrayType_1 = require("../Type/ArrayType");
const NumberType_1 = require("../Type/NumberType");
const ObjectType_1 = require("../Type/ObjectType");
const StringType_1 = require("../Type/StringType");
const UnionType_1 = require("../Type/UnionType");
const derefType_1 = require("../Utils/derefType");
const typeKeys_1 = require("../Utils/typeKeys");

@@ -15,3 +20,10 @@ class TypeOperatorNodeParser {

const type = this.childNodeParser.createType(node.type, context);
const derefed = derefType_1.derefType(type);
if (derefed instanceof ArrayType_1.ArrayType) {
return new NumberType_1.NumberType();
}
const keys = typeKeys_1.getTypeKeys(type);
if (derefed instanceof ObjectType_1.ObjectType && derefed.getAdditionalProperties()) {
return new UnionType_1.UnionType([...keys, new StringType_1.StringType()]);
}
return new UnionType_1.UnionType(keys);

@@ -18,0 +30,0 @@ }

@@ -6,11 +6,13 @@ import * as ts from "typescript";

export declare class SchemaGenerator {
private program;
private nodeParser;
private typeFormatter;
private allTypes;
private prioritizedFiles;
private unprioritizedFiles;
private readonly program;
private readonly nodeParser;
private readonly typeFormatter;
constructor(program: ts.Program, nodeParser: NodeParser, typeFormatter: TypeFormatter);
createSchema(fullName: string): Schema;
private findRootNode;
createSchema(fullName: string | undefined): Schema;
private getRootNodes;
private findNamedNode;
private getRootTypeDefinition;
private appendRootChildDefinitions;
private partitionFiles;
private appendTypes;
private inspectNode;

@@ -20,4 +22,2 @@ private isExportType;

private getFullName;
private getRootTypeDefinition;
private getRootChildDefinitions;
}

@@ -13,75 +13,43 @@ "use strict";

this.typeFormatter = typeFormatter;
this.allTypes = new Map();
const sourceFiles = this.program.getSourceFiles();
this.prioritizedFiles = [];
this.unprioritizedFiles = [];
for (const f of sourceFiles) {
if (!f.fileName.includes("/node_modules/")) {
this.prioritizedFiles.push(f);
}
else {
this.unprioritizedFiles.push(f);
}
}
}
createSchema(fullName) {
const rootNode = this.findRootNode(fullName);
const rootType = this.nodeParser.createType(rootNode, new NodeParser_1.Context());
return Object.assign({ $schema: "http://json-schema.org/draft-07/schema#", definitions: this.getRootChildDefinitions(rootType) }, this.getRootTypeDefinition(rootType));
const rootNodes = this.getRootNodes(fullName);
const rootTypes = rootNodes.map(rootNode => {
return this.nodeParser.createType(rootNode, new NodeParser_1.Context());
});
const rootTypeDefinition = rootTypes.length === 1 ? this.getRootTypeDefinition(rootTypes[0]) : {};
const definitions = {};
rootTypes.forEach(rootType => this.appendRootChildDefinitions(rootType, definitions));
return Object.assign({ $schema: "http://json-schema.org/draft-07/schema#" }, rootTypeDefinition, { definitions });
}
findRootNode(fullName) {
const typeChecker = this.program.getTypeChecker();
if (this.prioritizedFiles.length) {
for (const sourceFile of this.prioritizedFiles) {
this.inspectNode(sourceFile, typeChecker, this.allTypes);
}
this.prioritizedFiles = [];
getRootNodes(fullName) {
if (fullName && (fullName !== "*")) {
return [this.findNamedNode(fullName)];
}
if (this.allTypes.has(fullName)) {
return this.allTypes.get(fullName);
else {
const rootFileNames = this.program.getRootFileNames();
const rootSourceFiles = this.program.getSourceFiles().filter(sourceFile => rootFileNames.includes(sourceFile.fileName));
const rootNodes = new Map();
this.appendTypes(rootSourceFiles, this.program.getTypeChecker(), rootNodes);
return [...rootNodes.values()];
}
if (this.unprioritizedFiles.length) {
for (const sourceFile of this.unprioritizedFiles) {
this.inspectNode(sourceFile, typeChecker, this.allTypes);
}
this.unprioritizedFiles = [];
}
findNamedNode(fullName) {
const typeChecker = this.program.getTypeChecker();
const allTypes = new Map();
const { projectFiles, externalFiles } = this.partitionFiles();
this.appendTypes(projectFiles, typeChecker, allTypes);
if (allTypes.has(fullName)) {
return allTypes.get(fullName);
}
if (this.allTypes.has(fullName)) {
return this.allTypes.get(fullName);
this.appendTypes(externalFiles, typeChecker, allTypes);
if (allTypes.has(fullName)) {
return allTypes.get(fullName);
}
throw new NoRootTypeError_1.NoRootTypeError(fullName);
}
inspectNode(node, typeChecker, allTypes) {
if (node.kind === ts.SyntaxKind.InterfaceDeclaration ||
node.kind === ts.SyntaxKind.ClassDeclaration ||
node.kind === ts.SyntaxKind.EnumDeclaration ||
node.kind === ts.SyntaxKind.TypeAliasDeclaration) {
if (!this.isExportType(node)) {
return;
}
else if (this.isGenericType(node)) {
return;
}
allTypes.set(this.getFullName(node, typeChecker), node);
}
else {
ts.forEachChild(node, (subnode) => this.inspectNode(subnode, typeChecker, allTypes));
}
}
isExportType(node) {
const localSymbol = symbolAtNode_1.localSymbolAtNode(node);
return localSymbol ? "exportSymbol" in localSymbol : false;
}
isGenericType(node) {
return !!(node.typeParameters &&
node.typeParameters.length > 0);
}
getFullName(node, typeChecker) {
const symbol = symbolAtNode_1.symbolAtNode(node);
return typeChecker.getFullyQualifiedName(symbol).replace(/".*"\./, "");
}
getRootTypeDefinition(rootType) {
return this.typeFormatter.getDefinition(rootType);
}
getRootChildDefinitions(rootType) {
appendRootChildDefinitions(rootType, childDefinitions) {
const seen = new Set();

@@ -98,13 +66,56 @@ const children = this

});
return children
.reduce((result, child) => {
children
.reduce((definitions, child) => {
const name = child.getName();
if (name in result) {
if (name in definitions) {
throw new Error(`Type "${name}" has multiple definitions.`);
}
return Object.assign({}, result, { [name]: this.typeFormatter.getDefinition(child.getType()) });
}, {});
definitions[name] = this.typeFormatter.getDefinition(child.getType());
return definitions;
}, childDefinitions);
}
partitionFiles() {
const projectFiles = new Array();
const externalFiles = new Array();
for (const sourceFile of this.program.getSourceFiles()) {
const destination = sourceFile.fileName.includes("/node_modules/") ? externalFiles : projectFiles;
destination.push(sourceFile);
}
return { projectFiles, externalFiles };
}
appendTypes(sourceFiles, typeChecker, types) {
for (const sourceFile of sourceFiles) {
this.inspectNode(sourceFile, typeChecker, types);
}
}
inspectNode(node, typeChecker, allTypes) {
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.EnumDeclaration:
case ts.SyntaxKind.TypeAliasDeclaration:
if (!this.isExportType(node) || (this.isGenericType(node))) {
return;
}
allTypes.set(this.getFullName(node, typeChecker), node);
break;
default:
ts.forEachChild(node, (subnode) => this.inspectNode(subnode, typeChecker, allTypes));
break;
}
}
isExportType(node) {
const localSymbol = symbolAtNode_1.localSymbolAtNode(node);
return localSymbol ? "exportSymbol" in localSymbol : false;
}
isGenericType(node) {
return !!(node.typeParameters &&
node.typeParameters.length > 0);
}
getFullName(node, typeChecker) {
const symbol = symbolAtNode_1.symbolAtNode(node);
return typeChecker.getFullyQualifiedName(symbol).replace(/".*"\./, "");
}
}
exports.SchemaGenerator = SchemaGenerator;
//# sourceMappingURL=SchemaGenerator.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const DefinitionType_1 = require("../Type/DefinitionType");
const IntersectionType_1 = require("../Type/IntersectionType");
const ObjectType_1 = require("../Type/ObjectType");
const allOfDefinition_1 = require("../Utils/allOfDefinition");

@@ -20,3 +20,3 @@ class IntersectionTypeFormatter {

return type.getTypes().reduce((result, item) => {
const slice = item instanceof ObjectType_1.ObjectType ? 0 : 1;
const slice = item instanceof DefinitionType_1.DefinitionType ? 1 : 0;
return [

@@ -23,0 +23,0 @@ ...result,

import { BaseType } from "../Type/BaseType";
import { LiteralType } from "../Type/LiteralType";
import { StringType } from "../Type/StringType";
export declare function getTypeKeys(type: BaseType): LiteralType[];
export declare function getTypeByKey(type: BaseType, index: LiteralType): BaseType | undefined;
export declare function getTypeByKey(type: BaseType, index: LiteralType | StringType): BaseType | undefined;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AnyType_1 = require("../Type/AnyType");
const ArrayType_1 = require("../Type/ArrayType");
const BaseType_1 = require("../Type/BaseType");
const IntersectionType_1 = require("../Type/IntersectionType");
const LiteralType_1 = require("../Type/LiteralType");
const NumberType_1 = require("../Type/NumberType");
const ObjectType_1 = require("../Type/ObjectType");

@@ -51,14 +53,19 @@ const TupleType_1 = require("../Type/TupleType");

}
if (type instanceof TupleType_1.TupleType) {
if (type instanceof TupleType_1.TupleType && index instanceof LiteralType_1.LiteralType) {
return type.getTypes().find((it, idx) => idx === index.getValue());
}
if (type instanceof ArrayType_1.ArrayType && index instanceof NumberType_1.NumberType) {
return type.getItem();
}
if (type instanceof ObjectType_1.ObjectType) {
const property = type.getProperties().find((it) => it.getName() === index.getValue());
if (property) {
const propertyType = property.getType();
if (!property.isRequired() && !(propertyType instanceof UnionType_1.UnionType &&
propertyType.getTypes().some(subType => subType instanceof UndefinedType_1.UndefinedType))) {
return new UnionType_1.UnionType([propertyType, new UndefinedType_1.UndefinedType()]);
if (index instanceof LiteralType_1.LiteralType) {
const property = type.getProperties().find((it) => it.getName() === index.getValue());
if (property) {
const propertyType = property.getType();
if (!property.isRequired() && !(propertyType instanceof UnionType_1.UnionType &&
propertyType.getTypes().some(subType => subType instanceof UndefinedType_1.UndefinedType))) {
return new UnionType_1.UnionType([propertyType, new UndefinedType_1.UndefinedType()]);
}
return propertyType;
}
return propertyType;
}

@@ -65,0 +72,0 @@ const additionalProperty = type.getAdditionalProperties();

@@ -97,2 +97,3 @@ "use strict";

it("type-keyof-object", assertSchema("type-keyof-object", "MyType"));
it("type-keyof-object-function", assertSchema("type-keyof-object-function", "MyType"));
it("type-mapped-simple", assertSchema("type-mapped-simple", "MyObject"));

@@ -106,2 +107,5 @@ it("type-mapped-index", assertSchema("type-mapped-index", "MyObject"));

it("type-mapped-optional", assertSchema("type-mapped-optional", "MyObject"));
it("type-mapped-additional-props", assertSchema("type-mapped-additional-props", "MyObject"));
it("type-mapped-array", assertSchema("type-mapped-array", "MyObject"));
it("type-mapped-union-intersection", assertSchema("type-mapped-union-intersection", "MyObject"));
it("generic-simple", assertSchema("generic-simple", "MyObject"));

@@ -108,0 +112,0 @@ it("generic-arrays", assertSchema("generic-arrays", "MyObject"));

{
"name": "ts-json-schema-generator",
"version": "0.46.0",
"version": "0.47.0",
"description": "Generate JSON schema from your Typescript sources",

@@ -44,10 +44,10 @@ "main": "dist/index.js",

"json-stable-stringify": "^1.0.1",
"typescript": "~3.5.1"
"typescript": "~3.5.2"
},
"devDependencies": {
"@types/glob": "^7.1.1",
"@types/jest": "^24.0.13",
"@types/jest": "^24.0.15",
"@types/json-schema": "^7.0.3",
"@types/json-stable-stringify": "^1.0.32",
"@types/node": "^12.0.4",
"@types/node": "^12.0.8",
"ajv": "~6.10.0",

@@ -59,3 +59,3 @@ "chai": "~4.2.0",

"ts-jest": "^24.0.2",
"ts-node": "^8.2.0",
"ts-node": "^8.3.0",
"tslint": "~5.17.0"

@@ -62,0 +62,0 @@ },

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc