UNPKG

dgeni-packages

Version:

A collection of dgeni packages for generating documentation from source code

177 lines 9.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReadTypeScriptModules = exports.readTypeScriptModules = void 0; const ClassExportDoc_1 = require("../../api-doc-types/ClassExportDoc"); const ConstExportDoc_1 = require("../../api-doc-types/ConstExportDoc"); const EnumExportDoc_1 = require("../../api-doc-types/EnumExportDoc"); const FunctionExportDoc_1 = require("../../api-doc-types/FunctionExportDoc"); const InterfaceExportDoc_1 = require("../../api-doc-types/InterfaceExportDoc"); const MethodMemberDoc_1 = require("../../api-doc-types/MethodMemberDoc"); const ModuleDoc_1 = require("../../api-doc-types/ModuleDoc"); const PropertyMemberDoc_1 = require("../../api-doc-types/PropertyMemberDoc"); const TypeAliasExportDoc_1 = require("../../api-doc-types/TypeAliasExportDoc"); const TsParser_1 = require("../../services/TsParser"); const SourcePattern_1 = require("./SourcePattern"); // This import lacks type definitions. const path = require('canonical-path'); function readTypeScriptModules(tsParser, tsHost, modules, exportSymbolsToDocsMap, createDocMessage, log) { return new ReadTypeScriptModules(tsParser, tsHost, modules, exportSymbolsToDocsMap, createDocMessage, log); } exports.readTypeScriptModules = readTypeScriptModules; class ReadTypeScriptModules { constructor(tsParser, host, modules, exportSymbolsToDocsMap, createDocMessage, log) { this.tsParser = tsParser; this.host = host; this.modules = modules; this.exportSymbolsToDocsMap = exportSymbolsToDocsMap; this.createDocMessage = createDocMessage; this.log = log; this.$runAfter = ['files-read']; this.$runBefore = ['parsing-tags']; this.$validate = { basePath: { presence: true }, hidePrivateMembers: { inclusion: [true, false] }, ignoreExportsMatching: {}, sortClassMembers: { inclusion: [true, false] }, sourceFiles: { presence: true }, }; // A collection of globs that identify those modules for which we should create docs this.sourceFiles = []; // The base path from which to load the source files this.basePath = '.'; // We can ignore members of classes that are private this.hidePrivateMembers = true; // We leave class members sorted in order of declaration this.sortClassMembers = false; // We can provide a collection of strings or regexes to ignore exports whose export names match this.ignoreExportsMatching = ['__esModule']; this.ignoreExportsRegexes = []; } $process(docs) { // Convert ignoreExportsMatching to an array of regexes this.ignoreExportsRegexes = convertToRegexCollection(this.ignoreExportsMatching); // Extract the modules from source files via the TypeScript parser const basePath = path.resolve(this.basePath); const filesPaths = (0, SourcePattern_1.expandSourceFiles)(this.sourceFiles, basePath); const parseInfo = this.tsParser.parse(filesPaths, this.basePath); this.addModuleDocs(docs, parseInfo.moduleSymbols, basePath); } addModuleDocs(docs, moduleSymbols, basePath) { // Iterate through each of the modules to generate module docs, export docs and member docs. moduleSymbols.forEach(moduleSymbol => { // Create a doc for this module and add it to the module lookup collection and the docs collection const moduleDoc = new ModuleDoc_1.ModuleDoc(moduleSymbol, basePath, this.hidePrivateMembers, moduleSymbols.typeChecker); this.modules[moduleDoc.id] = moduleDoc; docs.push(moduleDoc); this.addExportDocs(docs, moduleDoc); }); } addExportDocs(docs, moduleDoc) { // Iterate through this module's exports and generate a doc for each moduleDoc.symbol.exportArray.forEach(exportSymbol => { // Ignore exports that match the configured regular expressions if (anyMatches(this.ignoreExportsRegexes, exportSymbol.name)) return; // If `exportSymbol.resolvedSymbol` is defined then the symbol has been "aliased": // * `exportSymbol.resolvedSymbol` holds the actual info about the symbol being exported // * `exportSymbol` is the "alias" symbol, which has the new name for the symbol being exported const resolvedExport = exportSymbol.resolvedSymbol || exportSymbol; const aliasSymbol = exportSymbol.resolvedSymbol ? exportSymbol : undefined; // If the resolved symbol contains no declarations then it is invalid (perhaps an abstract class?) // For the moment we are just going to ignore such exports (:scream:) // TODO: find a way of generating docs for them if (!resolvedExport.declarations) { this.log.info(`Export has no declarations: ${resolvedExport.name}`); return; } switch ((0, TsParser_1.getExportDocType)(resolvedExport)) { case 'class': const classDoc = new ClassExportDoc_1.ClassExportDoc(this.host, moduleDoc, resolvedExport, aliasSymbol); this.addMemberDocs(docs, classDoc.members); this.addMemberDocs(docs, classDoc.statics); if (classDoc.constructorDoc) this.addMemberDocs(docs, [classDoc.constructorDoc]); this.addExportDoc(docs, moduleDoc, classDoc); break; case 'interface': const interfaceDoc = new InterfaceExportDoc_1.InterfaceExportDoc(this.host, moduleDoc, resolvedExport, aliasSymbol); this.addMemberDocs(docs, interfaceDoc.members); this.addExportDoc(docs, moduleDoc, interfaceDoc); break; case 'enum': const enumDoc = new EnumExportDoc_1.EnumExportDoc(this.host, moduleDoc, resolvedExport, aliasSymbol); enumDoc.members.forEach(doc => docs.push(doc)); this.addExportDoc(docs, moduleDoc, enumDoc); break; case 'const': case 'let': case 'var': this.addExportDoc(docs, moduleDoc, new ConstExportDoc_1.ConstExportDoc(this.host, moduleDoc, resolvedExport, aliasSymbol)); break; case 'type-alias': this.addExportDoc(docs, moduleDoc, new TypeAliasExportDoc_1.TypeAliasExportDoc(this.host, moduleDoc, resolvedExport, aliasSymbol)); break; case 'function': const functionDoc = new FunctionExportDoc_1.FunctionExportDoc(this.host, moduleDoc, resolvedExport, aliasSymbol); this.addExportDoc(docs, moduleDoc, functionDoc); this.addParamDocs(docs, functionDoc.parameterDocs); functionDoc.overloads.forEach(overloadDoc => { docs.push(overloadDoc); this.addParamDocs(docs, overloadDoc.parameterDocs); }); break; default: this.log.error(`Don't know how to create export document for ${resolvedExport.name}`); break; } }); } addExportDoc(docs, moduleDoc, exportDoc) { this.log.debug('>>>> EXPORT: ' + exportDoc.name + ' (' + exportDoc.docType + ') from ' + moduleDoc.id); moduleDoc.exports.push(exportDoc); docs.push(exportDoc); this.exportSymbolsToDocsMap.set(exportDoc.symbol, exportDoc); } addMemberDocs(docs, members) { members.forEach(member => { docs.push(member); if (member instanceof MethodMemberDoc_1.MethodMemberDoc) { this.addParamDocs(docs, member.parameterDocs); member.overloads.forEach(overloadDoc => { docs.push(overloadDoc); this.addParamDocs(docs, overloadDoc.parameterDocs); }); } if (member instanceof PropertyMemberDoc_1.PropertyMemberDoc) { if (member.getAccessor) docs.push(member.getAccessor); if (member.setAccessor) { docs.push(member.setAccessor); this.addParamDocs(docs, member.setAccessor.parameterDocs); } } }); } addParamDocs(docs, parameters) { parameters.forEach(parameter => docs.push(parameter)); } } exports.ReadTypeScriptModules = ReadTypeScriptModules; function convertToRegexCollection(items) { if (!items) return []; // Must be an array if (!Array.isArray(items)) items = [items]; // Convert string to exact matching regexes return items.map(item => item instanceof RegExp ? item : new RegExp('^' + item + '$')); } function anyMatches(regexes, item) { for (const regex of regexes) { if (item.match(regex)) { return true; } } return false; } //# sourceMappingURL=index.js.map