UNPKG

ts-json-schema-generator

Version:

Generate JSON schema from your Typescript sources

132 lines 7.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MappedTypeNodeParser = void 0; const tslib_1 = require("tslib"); const typescript_1 = tslib_1.__importDefault(require("typescript")); const Errors_js_1 = require("../Error/Errors.js"); const NodeParser_js_1 = require("../NodeParser.js"); const AnnotatedType_js_1 = require("../Type/AnnotatedType.js"); const ArrayType_js_1 = require("../Type/ArrayType.js"); const DefinitionType_js_1 = require("../Type/DefinitionType.js"); const EnumType_js_1 = require("../Type/EnumType.js"); const LiteralType_js_1 = require("../Type/LiteralType.js"); const NeverType_js_1 = require("../Type/NeverType.js"); const NumberType_js_1 = require("../Type/NumberType.js"); const ObjectType_js_1 = require("../Type/ObjectType.js"); const StringType_js_1 = require("../Type/StringType.js"); const SymbolType_js_1 = require("../Type/SymbolType.js"); const UnionType_js_1 = require("../Type/UnionType.js"); const derefType_js_1 = require("../Utils/derefType.js"); const nodeKey_js_1 = require("../Utils/nodeKey.js"); const preserveAnnotation_js_1 = require("../Utils/preserveAnnotation.js"); const removeUndefined_js_1 = require("../Utils/removeUndefined.js"); const uniqueTypeArray_js_1 = require("../Utils/uniqueTypeArray.js"); class MappedTypeNodeParser { childNodeParser; additionalProperties; 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_js_1.derefType)(constraintType); const id = `indexed-type-${(0, nodeKey_js_1.getKey)(node, context)}`; if (keyListType instanceof UnionType_js_1.UnionType) { return new ObjectType_js_1.ObjectType(id, [], this.getProperties(node, keyListType, context), this.getAdditionalProperties(node, keyListType, context)); } if (keyListType instanceof LiteralType_js_1.LiteralType) { return new ObjectType_js_1.ObjectType(id, [], this.getProperties(node, new UnionType_js_1.UnionType([keyListType]), context), false); } if (keyListType instanceof StringType_js_1.StringType || keyListType instanceof NumberType_js_1.NumberType || keyListType instanceof SymbolType_js_1.SymbolType) { if (constraintType?.getId() === "number") { const type = this.childNodeParser.createType(node.type, this.createSubContext(node, keyListType, context)); return type instanceof NeverType_js_1.NeverType ? new NeverType_js_1.NeverType() : new ArrayType_js_1.ArrayType(type); } const type = this.childNodeParser.createType(node.type, context); const resultType = new ObjectType_js_1.ObjectType(id, [], [], type); if (resultType) { let annotations; if (constraintType instanceof AnnotatedType_js_1.AnnotatedType) { annotations = constraintType.getAnnotations(); } else if (constraintType instanceof DefinitionType_js_1.DefinitionType) { const childType = constraintType.getType(); if (childType instanceof AnnotatedType_js_1.AnnotatedType) { annotations = childType.getAnnotations(); } } if (annotations) { return new AnnotatedType_js_1.AnnotatedType(resultType, { propertyNames: annotations }, false); } } return resultType; } if (keyListType instanceof EnumType_js_1.EnumType) { return new ObjectType_js_1.ObjectType(id, [], this.getValues(node, keyListType, context), false); } if (keyListType instanceof NeverType_js_1.NeverType) { return new ObjectType_js_1.ObjectType(id, [], [], false); } throw new Errors_js_1.ExpectationFailedError(`Unexpected key type "${constraintType ? constraintType.getId() : constraintType}" for this node. (expected "UnionType" or "StringType")`, node); } mapKey(node, rawKey, context) { if (!node.nameType) { return rawKey; } return (0, derefType_js_1.derefType)(this.childNodeParser.createType(node.nameType, this.createSubContext(node, rawKey, context))); } getProperties(node, keyListType, context) { return (0, uniqueTypeArray_js_1.uniqueTypeArray)(keyListType.getFlattenedTypes(derefType_js_1.derefType)) .filter((type) => type instanceof LiteralType_js_1.LiteralType) .map((type) => [type, this.mapKey(node, type, context)]) .filter((value) => value[1] instanceof LiteralType_js_1.LiteralType) .reduce((result, [key, mappedKey]) => { const propertyType = this.childNodeParser.createType(node.type, this.createSubContext(node, key, context)); let newType = (0, derefType_js_1.derefAnnotatedType)(propertyType); let hasUndefined = false; if (newType instanceof UnionType_js_1.UnionType) { const { newType: newType_, numRemoved } = (0, removeUndefined_js_1.removeUndefined)(newType); hasUndefined = numRemoved > 0; newType = newType_; } const objectProperty = new ObjectType_js_1.ObjectProperty(mappedKey.getValue().toString(), (0, preserveAnnotation_js_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_js_1.LiteralType(value), context)); return new ObjectType_js_1.ObjectProperty(value.toString(), type, !node.questionToken); }); } getAdditionalProperties(node, keyListType, context) { const key = keyListType.getTypes().filter((type) => !(type instanceof LiteralType_js_1.LiteralType))[0]; if (key) { return (this.childNodeParser.createType(node.type, this.createSubContext(node, key, context)) ?? this.additionalProperties); } return this.additionalProperties; } createSubContext(node, key, parentContext) { const subContext = new NodeParser_js_1.Context(node); for (const parentParameter of parentContext.getParameters()) { 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