UNPKG

ts-json-schema-generator

Version:

Generate JSON schema from your Typescript sources

120 lines 6.27 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MappedTypeNodeParser = void 0; const typescript_1 = __importDefault(require("typescript")); const LogicError_1 = require("../Error/LogicError"); const NodeParser_1 = require("../NodeParser"); const AnnotatedType_1 = require("../Type/AnnotatedType"); const ArrayType_1 = require("../Type/ArrayType"); const EnumType_1 = require("../Type/EnumType"); const LiteralType_1 = require("../Type/LiteralType"); 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 nodeKey_1 = require("../Utils/nodeKey"); const preserveAnnotation_1 = require("../Utils/preserveAnnotation"); const removeUndefined_1 = require("../Utils/removeUndefined"); const notUndefined_1 = require("../Utils/notUndefined"); const SymbolType_1 = require("../Type/SymbolType"); class MappedTypeNodeParser { constructor(childNodeParser, additionalProperties) { this.childNodeParser = childNodeParser; this.additionalProperties = additionalProperties; } supportsNode(node) { return node.kind === typescript_1.default.SyntaxKind.MappedType; } createType(node, context) { const constraintType = this.childNodeParser.createType(node.typeParameter.constraint, context); const keyListType = (0, derefType_1.derefType)(constraintType); const id = `indexed-type-${(0, nodeKey_1.getKey)(node, context)}`; if (keyListType instanceof UnionType_1.UnionType) { return new ObjectType_1.ObjectType(id, [], this.getProperties(node, keyListType, context), this.getAdditionalProperties(node, keyListType, context)); } else if (keyListType instanceof LiteralType_1.LiteralType) { return new ObjectType_1.ObjectType(id, [], this.getProperties(node, new UnionType_1.UnionType([keyListType]), context), false); } else if (keyListType instanceof StringType_1.StringType || keyListType instanceof SymbolType_1.SymbolType) { const type = this.childNodeParser.createType(node.type, context); const resultType = type === undefined ? undefined : new ObjectType_1.ObjectType(id, [], [], type); if (resultType && constraintType instanceof AnnotatedType_1.AnnotatedType) { const annotations = constraintType.getAnnotations(); if (annotations) { return new AnnotatedType_1.AnnotatedType(resultType, { propertyNames: annotations }, false); } } return resultType; } else if (keyListType instanceof NumberType_1.NumberType) { const type = this.childNodeParser.createType(node.type, this.createSubContext(node, keyListType, context)); return type === undefined ? undefined : new ArrayType_1.ArrayType(type); } else if (keyListType instanceof EnumType_1.EnumType) { return new ObjectType_1.ObjectType(id, [], this.getValues(node, keyListType, context), false); } else { throw new LogicError_1.LogicError(`Unexpected key type "${constraintType ? constraintType.getId() : constraintType}" for type "${node.getText()}" (expected "UnionType" or "StringType")`); } } getProperties(node, keyListType, context) { return keyListType .getTypes() .filter((type) => type instanceof LiteralType_1.LiteralType) .reduce((result, key) => { const propertyType = this.childNodeParser.createType(node.type, this.createSubContext(node, key, context)); if (propertyType === undefined) { return result; } let newType = (0, derefType_1.derefAnnotatedType)(propertyType); let hasUndefined = false; if (newType instanceof UnionType_1.UnionType) { const { newType: newType_, numRemoved } = (0, removeUndefined_1.removeUndefined)(newType); hasUndefined = numRemoved > 0; newType = newType_; } const objectProperty = new ObjectType_1.ObjectProperty(key.getValue().toString(), (0, preserveAnnotation_1.preserveAnnotation)(propertyType, newType), !node.questionToken && !hasUndefined); result.push(objectProperty); return result; }, []); } getValues(node, keyListType, context) { return keyListType .getValues() .filter((value) => value != null) .map((value) => { const type = this.childNodeParser.createType(node.type, this.createSubContext(node, new LiteralType_1.LiteralType(value), context)); if (type === undefined) { return undefined; } return new ObjectType_1.ObjectProperty(value.toString(), type, !node.questionToken); }) .filter(notUndefined_1.notUndefined); } getAdditionalProperties(node, keyListType, context) { var _a; const key = keyListType.getTypes().filter((type) => !(type instanceof LiteralType_1.LiteralType))[0]; if (key) { return ((_a = this.childNodeParser.createType(node.type, this.createSubContext(node, key, context))) !== null && _a !== void 0 ? _a : this.additionalProperties); } else { return this.additionalProperties; } } createSubContext(node, key, parentContext) { const subContext = new NodeParser_1.Context(node); parentContext.getParameters().forEach((parentParameter) => { subContext.pushParameter(parentParameter); subContext.pushArgument(parentContext.getArgument(parentParameter)); }); subContext.pushParameter(node.typeParameter.name.text); subContext.pushArgument(key); return subContext; } } exports.MappedTypeNodeParser = MappedTypeNodeParser; //# sourceMappingURL=MappedTypeNodeParser.js.map