type2docfx
Version:
A tool to convert json format output from TypeDoc to schema driven reference model for DocFx to consume.
371 lines • 13.9 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertToTypeSDP = exports.convertToSDP = exports.mergeElementsToPackageSDP = exports.getAllUids = void 0;
var prettier = require("prettier");
function getAllUids(elements) {
var allUid = elements
.map(function (item) {
return item.items.map(function (m) {
return flattenYamlModelToUidArray(m);
}).reduce(function (a, b) { return a.concat(b); }, []);
})
.reduce(function (a, b) { return a.concat(b); }, []);
return Array.from(new Set(allUid));
}
exports.getAllUids = getAllUids;
function flattenYamlModelToUidArray(model) {
var result = [model.uid];
if (model.children && model.children.length > 0) {
var childern = model.children
.map(function (child) {
if (typeof child === "string") {
return [child];
}
return flattenYamlModelToUidArray(child);
})
.reduce(function (a, b) { return a.concat(b); }, []);
result = result.concat(childern);
}
return result;
}
function mergeElementsToPackageSDP(elements, allUids) {
var packageModel = null;
if (elements && elements.length) {
packageModel = {
uid: null,
name: null,
summary: "",
type: "package",
};
elements.forEach(function (element) {
switch (element.type) {
case "class":
if (!packageModel.classes) {
packageModel.classes = [];
}
packageModel.classes.push(element.uid);
break;
case "interface":
if (!packageModel.interfaces) {
packageModel.interfaces = [];
}
packageModel.interfaces.push(element.uid);
break;
case "enum":
if (!packageModel.enums) {
packageModel.enums = [];
}
packageModel.enums.push(element.uid);
break;
case "type alias":
if (!packageModel.typeAliases) {
packageModel.typeAliases = [];
}
packageModel.typeAliases.push(element.uid);
break;
case "function":
if (!packageModel.functions) {
packageModel.functions = [];
}
packageModel.functions.push(convertToFunctionSDP(element, allUids));
break;
default:
console.log("[warning] not applied type(package): ", element.type);
}
// (packageModel.children as string[]).push(element.uid);
if (!packageModel.uid && element.package) {
packageModel.uid = element.package;
packageModel.name = element.package;
}
});
}
return packageModel;
}
exports.mergeElementsToPackageSDP = mergeElementsToPackageSDP;
function convertToModule(transfomredClass, allUids, baseModel) {
var item = transfomredClass.items[0];
var module = __assign(__assign({}, baseModel), { uid: item.uid, name: item.name, type: "module", package: item.package, summary: tryMakeXrefRight(item.summary, allUids) });
if (item.previewState) {
module.previewState = item.previewState;
}
else {
delete module.previewState;
}
// add own sub items to target type
for (var i = 1; i < transfomredClass.items.length; i++) {
var ele = transfomredClass.items[i];
switch (ele.type) {
case "property":
if (!module.properties) {
module.properties = [];
}
module.properties.push(convertToFunctionSDP(ele, allUids));
break;
case "function":
if (!module.functions) {
module.functions = [];
}
module.functions.push(convertToFunctionSDP(ele, allUids));
break;
default:
console.log("[warning] not applied type(module): ", ele.type);
}
}
return module;
}
function convertToSDP(transfomredClass, allTransfomredClasses, allUids) {
var element = transfomredClass.items[0];
switch (element.type) {
case "class":
case "interface":
return {
model: convertToTypeSDP(transfomredClass, element.type === "class", allUids),
type: "Type",
};
case "enum":
if (transfomredClass.items.length < 2) {
console.log("[warning] enum " + element.uid + "/" + element.name + " does not have fields");
return undefined;
}
return {
model: convertToEnumSDP(transfomredClass, allUids),
type: "Enum",
};
case "type alias":
return {
model: convertToTypeAliasSDP(element, allUids),
type: "TypeAlias",
};
case "module":
var moduleChildren_1 = [];
allTransfomredClasses
.filter(function (value) {
var uid = value.items[0].uid;
return element.children.indexOf(uid) !== -1;
})
.forEach(function (item) {
moduleChildren_1.push(item.items[0]);
});
return {
model: convertToModule(transfomredClass, allUids, mergeElementsToPackageSDP(moduleChildren_1, allUids)),
type: "Package",
};
default:
console.log("not applied type: ", element.type);
return undefined;
}
}
exports.convertToSDP = convertToSDP;
function convertToEnumSDP(transfomredClass, allUids) {
var element = transfomredClass.items[0];
var fields = [];
for (var i = 1; i < transfomredClass.items.length; i++) {
var ele = transfomredClass.items[i];
var field = {
name: ele.name,
uid: ele.uid,
package: ele.package,
summary: tryMakeXrefRight(ele.summary, allUids),
};
if (ele.numericValue !== null && !isNaN(ele.numericValue)) {
field.numericValue = ele.numericValue;
}
fields.push(field);
}
var result = __assign(__assign({}, convertCommonYamlModel(element, allUids)), { fields: fields });
return result;
}
function convertToTypeAliasSDP(element, allUids) {
return __assign(__assign({}, convertCommonYamlModel(element, allUids)), { syntax: format(element.syntax.content) });
}
function format(content) {
try {
return prettier.format(content, { semi: false, parser: "babel" });
}
catch (_a) {
return content;
}
}
function convertToTypeSDP(transfomredClass, isClass, allUids) {
var element = transfomredClass.items[0];
var constructors = [];
var properties = [];
var inheritedProperties = [];
var methods = [];
var inheritedMethods = [];
for (var i = 1; i < transfomredClass.items.length; i++) {
var ele = transfomredClass.items[i];
var item = convertCommonYamlModel(ele, allUids);
if (ele.type === "constructor") {
// interface does not have constructor
isClass && constructors.push(item);
}
else if (ele.type === "property") {
if (ele.inherited) {
inheritedProperties.push(item);
}
else {
properties.push(item);
}
}
else if (ele.type === "method") {
if (ele.inherited) {
inheritedMethods.push(item);
}
else {
methods.push(item);
}
}
else {
console.log("[warning] " + ele.uid + "#" + ele.name + " is not applied sub type " + ele.type + " for type yaml");
}
}
var result = __assign(__assign({}, convertCommonYamlModel(element, allUids)), { type: isClass ? "class" : "interface" });
if (constructors.length > 0) {
result.constructors = constructors;
}
if (properties.length > 0) {
result.properties = properties;
}
if (inheritedProperties.length > 0) {
result.inheritedProperties = inheritedProperties;
}
if (inheritedMethods.length > 0) {
result.inheritedMethods = inheritedMethods;
}
if (methods.length > 0) {
result.methods = methods;
}
if (element.extends) {
result.extends = convertSelfTypeToXref(element.extends.name);
}
return result;
}
exports.convertToTypeSDP = convertToTypeSDP;
function convertToFunctionSDP(element, allUids) {
var model = convertCommonYamlModel(element, allUids);
// don't need these fields
delete model.fullName;
delete model.inheritanceDescription;
return model;
}
function convertCommonYamlModel(element, allUids) {
var _a;
var result = {
name: element.name,
uid: element.uid,
package: element.package,
summary: tryMakeXrefRight(element.summary, allUids),
};
if (element.fullName) {
result.fullName = element.fullName;
}
// because mustache meet same variable in different level
// such as: { "pre": true, "list": [{}]}
// if item in list wants to use pre but the pre is not assigned, it will use outer pre field.
// so, there need to set below variable explict
if (element.remarks) {
result.remarks = tryMakeXrefRight(element.remarks, allUids);
}
else {
result.remarks = "";
}
if (element.previewState) {
result.previewState = element.previewState;
}
else {
delete result.previewState;
}
if (element.deprecated) {
result.isDeprecated = true;
result.customDeprecatedMessage = tryMakeXrefRight(element.deprecated.content, allUids);
}
else {
result.isDeprecated = false;
}
if (element.syntax) {
result.syntax = {};
var syntax = element.syntax;
result.syntax.content = syntax.content;
if (syntax.parameters && syntax.parameters.length > 0) {
(_a = syntax.parameters) === null || _a === void 0 ? void 0 : _a.forEach(function (it) {
delete it.optional;
});
// type(return, parameters) when type is self class, we will change it to xref
result.syntax.parameters = syntax.parameters.map(function (it) {
return __assign(__assign({}, it), { description: tryMakeXrefRight(it.description, allUids), type: convertSelfTypeToXref(escapeMarkdown(it.type[0])) });
});
}
if (syntax.return) {
result.syntax.return = {
description: tryMakeXrefRight(syntax.return.description, allUids),
type: convertSelfTypeToXref(escapeMarkdown(syntax.return.type[0])),
};
}
if (element.inheritanceDescription) {
result.inheritanceDescription = tryMakeXrefRight(element.inheritanceDescription, allUids);
}
}
return result;
}
function escapeMarkdown(name) {
// eg: [key: string]: string
var markdownLinkRegEx = /^\s*(\[.+\]):(.+)/g;
return name.replace(markdownLinkRegEx, "$1\\:$2");
}
function convertSelfTypeToXref(name) {
var result = name;
// parse < >
result = result.replace(/</g, "<").replace(/>/g, ">");
var uidRegEx = /(@?[\w\d\-/]+\.[\w\d\-\./]+)/g;
return result.replace(uidRegEx, "<xref uid=\"$1\" />");
}
var xrefRegex = /(?<start>[<(]xref:)(?<uid>.*?)(?<end>[>)])/g;
function tryMakeXrefRight(content, uids) {
var result = content;
// because we will leave xref:xx if xx is not in uids
var re;
while ((re = xrefRegex.exec(result))) {
var name = re.groups.uid;
var replaced = re.groups.start + convertToRealXrefName(name, uids) + re.groups.end;
result = result.replace(re[0], replaced);
}
return result;
}
function convertToRealXrefName(name, uids) {
// find all matches
var matches = uids.filter(function (uid) {
return uid.endsWith(name);
});
var replaced = name;
if (matches.length === 1) {
replaced = matches[0];
}
else if (matches.length > 1) {
// use editdistance to find nearest one
var curDis = matches[0].length;
for (var _i = 0, matches_1 = matches; _i < matches_1.length; _i++) {
var match = matches_1[_i];
// matches are endswith name
// edit distance is prefix character length, same with match length - name length
var distance = match.length - name.length;
if (curDis > distance) {
curDis = distance;
replaced = match;
}
}
}
return replaced;
}
//# sourceMappingURL=toSdpConvertHelper.js.map