@microsoft/api-documenter
Version:
Read JSON files from api-extractor, generate documentation pages
331 lines • 12.1 kB
JavaScript
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertUDPYamlToSDP = void 0;
const path_1 = __importDefault(require("path"));
const node_core_library_1 = require("@rushstack/node-core-library");
const yaml = require("js-yaml");
function convertUDPYamlToSDP(folderPath) {
convert(folderPath, folderPath);
}
exports.convertUDPYamlToSDP = convertUDPYamlToSDP;
function convert(inputPath, outputPath) {
console.log();
if (!node_core_library_1.FileSystem.exists(inputPath)) {
console.error(`input path: ${inputPath} is not exist`);
return;
}
node_core_library_1.FileSystem.readFolderItemNames(inputPath).forEach((name) => {
const fpath = path_1.default.join(inputPath, name);
if (node_core_library_1.FileSystem.getStatistics(fpath).isFile()) {
// only convert yaml
if (!name.endsWith('.yml')) {
return;
}
// parse file
const yamlContent = node_core_library_1.FileSystem.readFile(fpath, { encoding: node_core_library_1.Encoding.Utf8 });
// only convert universalreference yaml
const isLegacyYaml = yamlContent.startsWith('### YamlMime:UniversalReference');
if (!isLegacyYaml) {
return;
}
console.log(`convert file ${fpath} from udp to sdp`);
const file = yaml.safeLoad(yamlContent);
const result = convertToSDP(file);
if (result && result.model) {
const stringified = `### YamlMime:TS${result.type}\n${yaml.safeDump(result.model, {
lineWidth: 120
})}`;
node_core_library_1.FileSystem.writeFile(`${outputPath}/${name}`, stringified, {
convertLineEndings: node_core_library_1.NewlineKind.CrLf,
ensureFolderExists: true
});
}
else {
console.log('not target file ', fpath);
}
}
else {
// read contents
convert(fpath, path_1.default.join(outputPath, name));
}
});
}
function convertToPackageSDP(transfomredClass) {
const element = transfomredClass.items[0];
const packageModel = {
uid: element.uid,
name: element.name,
type: 'package'
};
if (element.summary) {
packageModel.summary = element.summary;
}
else {
packageModel.summary = '';
}
// search in children
if (element.children) {
element.children.forEach((child) => {
if (child.endsWith(':class')) {
assignPackageModelFields(packageModel, 'classes', child);
}
else if (child.endsWith(':interface')) {
assignPackageModelFields(packageModel, 'interfaces', child);
}
else if (child.endsWith(':enum')) {
assignPackageModelFields(packageModel, 'enums', child);
}
else if (child.endsWith(':type')) {
assignPackageModelFields(packageModel, 'typeAliases', child);
}
else {
// console.log("other type: ", child)
}
});
}
for (let i = 1; i < transfomredClass.items.length; i++) {
const ele = transfomredClass.items[i];
switch (ele.type) {
case 'typealias':
// need generate typeAlias file for this
break;
case 'function':
if (!packageModel.functions) {
packageModel.functions = [];
}
packageModel.functions.push(convertToFunctionSDP(ele, element.uid, transfomredClass));
break;
default:
// console.log(transfomredClass.items[0].name)
console.log('[warning] not applied type(package): ', ele.type);
}
}
return packageModel;
}
function assignPackageModelFields(packageModel, name, uid) {
if (!packageModel[name]) {
packageModel[name] = [];
}
packageModel[name].push(uid);
}
function convertToSDP(transfomredClass) {
const element = transfomredClass.items[0];
switch (element.type) {
case 'class':
case 'interface':
return {
model: convertToTypeSDP(transfomredClass, element.type === 'class'),
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), type: 'Enum' };
case 'typealias':
return { model: convertToTypeAliasSDP(element, transfomredClass), type: 'TypeAlias' };
case 'package':
return {
model: convertToPackageSDP(transfomredClass),
type: 'Package'
};
default:
console.log('not applied type: ', element.type);
return undefined;
}
}
function convertToEnumSDP(transfomredClass) {
const element = transfomredClass.items[0];
const fields = [];
for (let i = 1; i < transfomredClass.items.length; i++) {
const ele = transfomredClass.items[i];
const field = {
name: ele.name,
uid: ele.uid,
package: element.package
};
if (ele.summary) {
field.summary = ele.summary;
}
else {
field.summary = '';
}
if (ele.numericValue) {
field.value = ele.numericValue;
}
fields.push(field);
}
const result = Object.assign(Object.assign({}, convertCommonYamlModel(element, element.package, transfomredClass)), { fields: fields });
return result;
}
function convertToTypeAliasSDP(element, transfomredClass) {
const result = Object.assign({}, convertCommonYamlModel(element, element.package, transfomredClass));
if (element.syntax) {
result.syntax = element.syntax.content;
}
return result;
}
function convertToTypeSDP(transfomredClass, isClass) {
const element = transfomredClass.items[0];
const constructors = [];
const properties = [];
const methods = [];
const events = [];
for (let i = 1; i < transfomredClass.items.length; i++) {
const ele = transfomredClass.items[i];
const item = convertCommonYamlModel(ele, element.package, transfomredClass);
if (ele.type === 'constructor') {
// interface does not need this field
if (isClass) {
constructors.push(item);
}
}
else if (ele.type === 'property') {
properties.push(item);
}
else if (ele.type === 'method') {
methods.push(item);
}
else if (ele.type === 'event') {
events.push(item);
}
else {
console.log(`[warning] ${ele.uid}#${ele.name} is not applied sub type ${ele.type} for type yaml`);
}
}
const result = Object.assign(Object.assign({}, convertCommonYamlModel(element, element.package, transfomredClass)), { type: isClass ? 'class' : 'interface' });
delete result.syntax;
if (constructors.length > 0) {
result.constructors = constructors;
}
if (properties.length > 0) {
result.properties = properties;
}
if (methods.length > 0) {
result.methods = methods;
}
if (events.length > 0) {
result.events = events;
}
if (element.extends && element.extends.length > 0) {
result.extends = convertSelfTypeToXref(element.extends[0], transfomredClass);
}
return result;
}
function convertToFunctionSDP(element, packageName, transfomredClass) {
const model = convertCommonYamlModel(element, packageName, transfomredClass);
// don't need these fields
delete model.fullName;
return model;
}
function convertCommonYamlModel(element, packageName, transfomredClass) {
var _a;
const result = {
name: element.name,
uid: element.uid,
package: packageName
};
if (element.fullName) {
result.fullName = element.fullName;
}
if (element.summary) {
result.summary = element.summary;
}
else {
result.summary = '';
}
// 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 = element.remarks;
}
else {
result.remarks = '';
}
if (element.example) {
result.example = element.example;
}
else {
result.example = [];
}
result.isPreview = element.isPreview;
if (!result.isPreview) {
result.isPreview = false;
}
if (element.deprecated) {
result.isDeprecated = true;
result.customDeprecatedMessage = element.deprecated.content;
}
else {
result.isDeprecated = false;
}
if (element.syntax) {
result.syntax = {};
const 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((it) => {
delete it.optional;
delete it.defaultValue;
});
result.syntax.parameters = syntax.parameters.map((it) => {
return Object.assign(Object.assign({}, it), { id: it.id, type: convertSelfTypeToXref(escapeMarkdown(it.type[0]), transfomredClass) });
});
}
if (syntax.return) {
result.syntax.return = Object.assign(Object.assign({}, syntax.return), { type: convertSelfTypeToXref(escapeMarkdown(syntax.return.type[0]), transfomredClass) });
}
}
return result;
}
function escapeMarkdown(name) {
// eg: [key: string]: string
const markdownLinkRegEx = /^\s*(\[.+\]):(.+)/g;
return name.replace(markdownLinkRegEx, `$1\\:$2`);
}
function convertSelfTypeToXref(name, transfomredClass) {
var _a, _b, _c;
let result = name;
// if complex type, need to get real type from references
if (result.endsWith(':complex')) {
const specs = (_b = (_a = transfomredClass.references) === null || _a === void 0 ? void 0 : _a.find((item) => {
return item.uid === name;
})) === null || _b === void 0 ? void 0 : _b['spec.typeScript'];
if (specs && specs.length > 0) {
result = '';
for (const spec of specs) {
// start with ! will be node base type
if (spec.uid && !spec.uid.startsWith('!')) {
result += spec.uid;
}
else {
result += spec.name;
}
}
}
}
else if (result.startsWith('!')) {
// uid: '!Object:interface'
// name: Object
// start with !, not complex type, use reference name directly
const ref = (_c = transfomredClass.references) === null || _c === void 0 ? void 0 : _c.find((item) => {
return item.uid === name;
});
if (ref && ref.name) {
result = ref.name;
}
}
// parse < >
result = result.replace(/</g, '<').replace(/>/g, '>');
const uidRegEx = /(@?[\w\d\-/!~\.]+\:[\w\d\-\(/]+)/g;
return result.replace(uidRegEx, `<xref uid="$1" />`);
}
//# sourceMappingURL=ToSdpConvertHelper.js.map
;