UNPKG

type2docfx

Version:

A tool to convert json format output from TypeDoc to universal reference model for DocFx to consume.

470 lines (469 loc) 17.4 kB
"use strict"; exports.__esModule = true; var linkConvertHelper_1 = require("./helpers/linkConvertHelper"); var idResolver_1 = require("./idResolver"); var flags_1 = require("./common/flags"); var _ = require("lodash"); function traverse(node, parentUid, parentContainer, moduleName, uidMapping, repoConfig) { if (node.flags.isPrivate || node.flags.isProtected) { return; } if (parentUid.length && !node.flags.isExported) { return; } if (node.name && node.name[0] === '_') { return; } var uid = parentUid; if (node.kind === 0) { uid = node.name; } if (node.kindString === 'Module') { if (!moduleName) { moduleName = node.name.replace(/"/g, ''); } else { moduleName = moduleName + "." + node.name.replace(/"/g, ''); } uid += "." + moduleName.replace(/\//g, '.'); console.log(node.kindString + ": " + uid); } var myself = null; if ((node.kindString === 'Class' || node.kindString === 'Interface' || node.kindString === 'Enumeration' || node.kindString === 'Type alias') && node.name) { uid += "." + node.name; console.log(node.kindString + ": " + uid); var customModuleName = findModuleInfoInComment(node.comment); if (customModuleName) { if (moduleName) { moduleName += "." + customModuleName; } else { moduleName = customModuleName; } } myself = { uid: uid, name: node.name, fullName: node.name + getGenericType(node.typeParameter), children: [], langs: ['typeScript'], type: node.kindString.toLowerCase(), summary: node.comment ? findDescriptionInComment(node.comment) : '' }; if (myself.type === 'enumeration') { myself.type = 'enum'; } if (myself.type === 'type alias') { myself.type = 'class'; myself.summary += "\n" + generateTypeAliasInformation(node); } if (node.extendedTypes && node.extendedTypes.length) { myself["extends"] = { name: extractType(node.extendedTypes[0])[0] }; } if (repoConfig && node.sources && node.sources.length) { myself.source = { path: node.sources[0].fileName, // shift one line up as systematic off for TypeDoc startLine: node.sources[0].line, remote: { path: repoConfig.basePath + "\\" + node.sources[0].fileName, repo: repoConfig.repo, branch: repoConfig.branch } }; } var tokens = parentUid.split('.'); myself.package = tokens[0]; } if ((node.kindString === 'Method' || node.kindString === 'Function' || node.kindString === 'Constructor') && node.name) { if (!node.signatures || node.inheritedFrom) { return; } uid += '.' + node.name; console.log(" - " + node.kindString + ": " + uid); myself = { uid: uid, name: node.name, children: [], type: '', langs: ['typeScript'], summary: '', syntax: { content: '' } }; extractInformationFromSignature(myself, node, 0); } if (node.kindString === 'Enumeration member' && node.name) { uid += '.' + node.name; console.log(" - " + node.kindString + ": " + uid); myself = { uid: uid, name: node.name, children: [], langs: ['typeScript'], summary: node.comment ? findDescriptionInComment(node.comment) : '', type: 'field' }; if (node.defaultValue) { myself.numericValue = parseInt(node.defaultValue, 10); } } if (node.kindString === 'Property' && node.name) { if (node.inheritedFrom) { return; } uid += '.' + node.name; console.log(" - " + node.kindString + ": " + uid); var isPublic = node.flags && node.flags.isPublic ? 'public ' : ''; var isStatic = node.flags && node.flags.isStatic ? 'static ' : ''; var isOptional = node.flags && node.flags.isOptional ? '?' : ''; var defaultValue = node.defaultValue ? " = " + _.trim(node.defaultValue) : ''; myself = { uid: uid, name: node.name, fullName: node.name, children: [], langs: ['typeScript'], type: node.kindString.toLowerCase(), summary: node.comment ? findDescriptionInComment(node.comment) : '', optional: node.flags && node.flags.isOptional, syntax: { content: "" + isPublic + isStatic + node.name + isOptional + ": " + idResolver_1.typeToString(extractType(node.type)[0]) + defaultValue, "return": { type: extractType(node.type) } } }; } if (node.kindString === 'Accessor' && node.name) { if (node.inheritedFrom) { return; } uid += '.' + node.name; console.log(" - " + node.kindString + ": " + uid); var signatureType = void 0; if (node.getSignature) { if (Array.isArray(node.getSignature)) { signatureType = node.getSignature[0].type; } else { signatureType = node.getSignature.type; } } else if (node.setSignature) { if (Array.isArray(node.setSignature)) { signatureType = node.setSignature[0].type; } else { signatureType = node.setSignature.type; } } myself = { uid: uid, name: node.name, fullName: node.name, children: [], langs: ['typeScript'], type: 'property', summary: node.comment ? findDescriptionInComment(node.comment) : '', syntax: { content: "" + (node.flags && node.flags.isStatic ? 'static ' : '') + idResolver_1.typeToString(extractType(signatureType)[0]) + " " + node.name, "return": { type: extractType(signatureType) } } }; } if (myself) { myself.summary = linkConvertHelper_1.convertLinkToGfm(myself.summary); uidMapping[node.id] = myself.uid; parentContainer.push(myself); if (flags_1.flags.hasModule && moduleName) { myself.module = moduleName; } if (node.comment || node.signatures && node.signatures.length && node.signatures[0].comment) { var comment = node.comment ? node.comment : node.signatures[0].comment; var deprecated = findDeprecatedInfoInComment(comment); if (deprecated != null) { myself.deprecated = { content: linkConvertHelper_1.convertLinkToGfm(deprecated) }; } var inherits = findInheritsInfoInComment(comment); if (inherits != null) { var tokens = linkConvertHelper_1.getTextAndLink(inherits); if (tokens.length === 2) { myself["extends"] = { name: tokens[0], href: tokens[1] }; } } var isPreview = findPreviewInfoInComment(comment); if (isPreview != null) { myself.isPreview = true; } var remarks = findRemarkInfoInComment(comment); if (remarks != null) { myself.remarks = linkConvertHelper_1.convertLinkToGfm(remarks); } } if (node.signatures && node.signatures.length > 1) { for (var index = 1; index < node.signatures.length; index++) { var newMethod = _.cloneDeep(myself); newMethod.uid = newMethod.uid + "_" + index; extractInformationFromSignature(newMethod, node, index); parentContainer.push(newMethod); } } } if (node.children && node.children.length > 0) { node.children.forEach(function (subNode) { if (myself) { traverse(subNode, uid, myself.children, moduleName, uidMapping, repoConfig); } else { traverse(subNode, uid, parentContainer, moduleName, uidMapping, repoConfig); } }); } } exports.traverse = traverse; function extractInformationFromSignature(method, node, signatureIndex) { if (node.signatures[signatureIndex].comment) { method.summary = findDescriptionInComment(node.signatures[signatureIndex].comment); } method.syntax.parameters = fillParameters(node.signatures[signatureIndex].parameters); if (node.signatures[signatureIndex].type && node.kindString !== 'Constructor' && node.signatures[signatureIndex].type.name !== 'void') { method.syntax["return"] = { type: extractType(node.signatures[signatureIndex].type) }; } var exceptions; if (node.signatures[signatureIndex].comment && node.signatures[signatureIndex].comment.tags) { exceptions = node.signatures[signatureIndex].comment.tags.filter(function (tag) { return tag.tag === 'throws'; }); } if (exceptions && exceptions.length) { method.exceptions = exceptions.map(function (e) { return extractException(e); }); } if (node.kindString === 'Method' || node.kindString === 'Function') { method.name = node.name; var functionBody = generateCallFunction(method.name, method.syntax.parameters, node.signatures[signatureIndex].typeParameter); method.syntax.content = (node.flags && node.flags.isStatic ? 'static ' : '') + "function " + functionBody; method.type = node.kindString.toLowerCase(); } else { method.name = method.uid.split('.').reverse()[1]; var functionBody = generateCallFunction(method.name, method.syntax.parameters); method.syntax.content = "new " + functionBody; method.type = 'constructor'; } } function hasCommonPrefix(types) { if (types && types.length > 1 && types[0].name) { if (types[0].name.indexOf('.') < 0) { return false; } var prefix_1 = types[0].name.split('.')[0]; types.forEach(function (t) { if (!t.name || t.name.split('.')[0] !== prefix_1) { return false; } }); return true; } return false; } function extractType(type) { var result = []; if (type === undefined) { return result; } if (type.type === 'union' && type.types && type.types.length) { if (hasCommonPrefix(type.types)) { result.push({ typeName: type.types[0].name.split('.')[0] }); } else { result.push({ unionType: { types: type.types.map(function (t) { return extractType(t)[0]; }) } }); } } else if (type.type === 'array') { var newType = extractType(type.elementType); result.push({ arrayType: newType[0] }); } else if (type.type === 'intersection' && type.types.length) { result.push({ intersectionType: { types: type.types.map(function (t) { return extractType(t)[0]; }) } }); } else if (type.type === 'reflection' && type.declaration) { if (type.declaration.indexSignature && type.declaration.indexSignature.length) { result.push({ reflectedType: { key: { typeName: type.declaration.indexSignature[0].parameters[0].type.name, typeId: type.declaration.indexSignature[0].parameters[0].type.id }, value: { typeName: type.declaration.indexSignature[0].type.name, typeId: type.declaration.indexSignature[0].type.id } } }); } else if (type.declaration.signatures && type.declaration.signatures.length) { result.push({ typeName: generateCallFunction('', fillParameters(type.declaration.signatures[0].parameters)) + " => " + idResolver_1.typeToString(extractType(type.declaration.signatures[0].type)[0]) }); } else { result.push({ typeName: 'function' }); } } else if (type.typeArguments && type.typeArguments.length) { result.push({ genericType: { outter: { typeName: type.name, typeId: type.id }, inner: type.typeArguments.map(function (t) { return extractType(t)[0]; }) } }); } else if (type.name) { result.push({ typeName: type.name, typeId: type.id }); } else if (type.value) { result.push({ typeName: "\"" + type.value + "\"" }); } else { result.push({ typeName: 'function' }); } return result; } function extractException(exception) { var tokens = exception.text.match(/{(.*)} +((.|\s)+)/); if (tokens.length >= 3) { return { type: tokens[1], description: tokens[2] }; } return null; } function findModuleInfoInComment(comment) { return findInfoInComment('module', comment); } function findInheritsInfoInComment(comment) { return findInfoInComment('inherits', comment); } function findDeprecatedInfoInComment(comment) { return findInfoInComment('deprecated', comment); } function findPreviewInfoInComment(comment) { return findInfoInComment('beta', comment); } function findRemarkInfoInComment(comment) { return findInfoInComment('remarks', comment); } function findInfoInComment(infoName, comment) { if (comment && comment.tags) { var text_1 = null; comment.tags.forEach(function (tag) { if (tag.tag === infoName) { text_1 = tag.text; return; } }); if (text_1) { return text_1.trim(); } } return null; } function findDescriptionInComment(comment) { if (!comment) { return ''; } if (comment.tags) { var text_2 = null; comment.tags.forEach(function (tag) { if (tag.tag === 'classdesc' || tag.tag === 'description' || tag.tag === 'exemptedapi') { text_2 = tag.text; return; } }); if (text_2) { return text_2.trim(); } } if (comment.shortText && comment.text) { return comment.shortText + "\n" + comment.text; } if (comment.text) { return comment.text.trim(); } if (comment.shortText) { return comment.shortText.trim(); } return ''; } function fillParameters(parameters) { if (parameters) { return parameters.map(function (p) { var description = ''; if (p.comment) { description = (p.comment.shortText && p.comment.shortText !== '') ? p.comment.shortText : p.comment.text; } return { id: p.name, type: extractType(p.type), description: linkConvertHelper_1.convertLinkToGfm(description), optional: p.flags && p.flags.isOptional }; }); } return []; } function generateCallFunction(prefix, parameters, typeParameters) { if (parameters) { return "" + prefix + getGenericType(typeParameters) + "(" + parameters.map(function (p) { return "" + p.id + (p.optional ? '?' : '') + ": " + (idResolver_1.typeToString(p.type[0])); }).join(', ') + ")"; } return ''; } function getGenericType(typeParameters) { if (typeParameters && typeParameters.length) { return "<" + typeParameters[0].name + ">"; } return ''; } function generateTypeAliasInformation(node) { if (!node || !node.type || !node.type.types || node.type.type.length < 2) { return ''; } var typeAliases = node.type.types.map(function (t) { return idResolver_1.typeToString(extractType(t)[0]); }); return "\"" + node.name + "\" is a type alias. It refers to " + _.take(typeAliases, typeAliases.length - 1).join(', ') + " and " + _.last(typeAliases) + "."; }