UNPKG

compodoc

Version:

The missing documentation tool for your Angular application

1,307 lines (1,288 loc) 504 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var fs = require('fs-extra'); var path = require('path'); var _ = require('lodash'); var LiveServer = require('live-server'); var marked = require('marked'); var marked__default = _interopDefault(marked); var Handlebars = require('handlebars'); var highlightjs = _interopDefault(require('highlight.js')); var ts = require('typescript'); var util = require('util'); function __extends(d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var gutil = require('gulp-util'); var c = gutil.colors; var pkg$1 = require('../package.json'); var LEVEL; (function (LEVEL) { LEVEL[LEVEL["INFO"] = 0] = "INFO"; LEVEL[LEVEL["DEBUG"] = 1] = "DEBUG"; LEVEL[LEVEL["ERROR"] = 2] = "ERROR"; })(LEVEL || (LEVEL = {})); var Logger = (function () { function Logger() { this.name = pkg$1.name; this.version = pkg$1.version; this.logger = gutil.log; this.silent = true; } Logger.prototype.info = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!this.silent) return; this.logger(this.format.apply(this, [LEVEL.INFO].concat(args))); }; Logger.prototype.error = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!this.silent) return; this.logger(this.format.apply(this, [LEVEL.ERROR].concat(args))); }; Logger.prototype.debug = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!this.silent) return; this.logger(this.format.apply(this, [LEVEL.DEBUG].concat(args))); }; Logger.prototype.format = function (level) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var pad = function (s, l, c) { if (c === void 0) { c = ''; } return s + Array(Math.max(0, l - s.length + 1)).join(c); }; var msg = args.join(' '); if (args.length > 1) { msg = pad(args.shift(), 15, ' ') + ": " + args.join(' '); } switch (level) { case LEVEL.INFO: msg = c.green(msg); break; case LEVEL.DEBUG: msg = c.cyan(msg); break; case LEVEL.ERROR: msg = c.red(msg); break; } return [ msg ].join(''); }; return Logger; }()); var logger = new Logger(); var AngularAPIs = require('../src/data/api-list.json'); function finderInAngularAPIs(type) { var _result = { source: 'external', data: null }; _.forEach(AngularAPIs, function (angularModuleAPIs, angularModule) { var i = 0, len = angularModuleAPIs.length; for (i; i < len; i++) { if (angularModuleAPIs[i].title === type) { _result.data = angularModuleAPIs[i]; } } }); return _result; } var DependenciesEngine = (function () { function DependenciesEngine() { if (DependenciesEngine._instance) { throw new Error('Error: Instantiation failed: Use DependenciesEngine.getInstance() instead of new.'); } DependenciesEngine._instance = this; } DependenciesEngine.getInstance = function () { return DependenciesEngine._instance; }; DependenciesEngine.prototype.cleanModules = function (modules) { var _m = modules, i = 0, len = modules.length; for (i; i < len; i++) { var j = 0, leng = _m[i].declarations.length; for (j; j < leng; j++) { var k = 0, lengt = void 0; if (_m[i].declarations[j].jsdoctags) { lengt = _m[i].declarations[j].jsdoctags.length; for (k; k < lengt; k++) { delete _m[i].declarations[j].jsdoctags[k].parent; } } } } return _m; }; DependenciesEngine.prototype.init = function (data) { this.rawData = data; this.modules = _.sortBy(this.rawData.modules, ['name']); this.rawModules = _.sortBy(_.cloneDeep(this.cleanModules(data.modules)), ['name']); this.components = _.sortBy(this.rawData.components, ['name']); this.directives = _.sortBy(this.rawData.directives, ['name']); this.injectables = _.sortBy(this.rawData.injectables, ['name']); this.interfaces = _.sortBy(this.rawData.interfaces, ['name']); this.routes = _.sortBy(_.uniqWith(this.rawData.routes, _.isEqual), ['name']); this.pipes = _.sortBy(this.rawData.pipes, ['name']); this.classes = _.sortBy(this.rawData.classes, ['name']); this.miscellaneous = this.rawData.miscellaneous; }; DependenciesEngine.prototype.find = function (type) { var finderInCompodocDependencies = function (data) { var _result = { source: 'internal', data: null }, i = 0, len = data.length; for (i; i < len; i++) { if (typeof type !== 'undefined') { if (type.indexOf(data[i].name) !== -1) { _result.data = data[i]; } } } return _result; }, resultInCompodocInjectables = finderInCompodocDependencies(this.injectables), resultInCompodocClasses = finderInCompodocDependencies(this.classes), resultInAngularAPIs = finderInAngularAPIs(type); if (resultInCompodocInjectables.data !== null) { return resultInCompodocInjectables; } else if (resultInCompodocClasses.data !== null) { return resultInCompodocClasses; } else if (resultInAngularAPIs.data !== null) { return resultInAngularAPIs; } }; DependenciesEngine.prototype.findInCompodoc = function (name) { var mergedData = _.concat([], this.modules, this.components, this.directives, this.injectables, this.interfaces, this.pipes, this.classes), result = _.find(mergedData, { 'name': name }); return result || false; }; DependenciesEngine.prototype.getModule = function (name) { return _.find(this.modules, ['name', name]); }; DependenciesEngine.prototype.getRawModule = function (name) { return _.find(this.rawModules, ['name', name]); }; DependenciesEngine.prototype.getModules = function () { return this.modules; }; DependenciesEngine.prototype.getComponents = function () { return this.components; }; DependenciesEngine.prototype.getDirectives = function () { return this.directives; }; DependenciesEngine.prototype.getInjectables = function () { return this.injectables; }; DependenciesEngine.prototype.getInterfaces = function () { return this.interfaces; }; DependenciesEngine.prototype.getRoutes = function () { return this.routes; }; DependenciesEngine.prototype.getPipes = function () { return this.pipes; }; DependenciesEngine.prototype.getClasses = function () { return this.classes; }; DependenciesEngine.prototype.getMiscellaneous = function () { return this.miscellaneous; }; return DependenciesEngine; }()); DependenciesEngine._instance = new DependenciesEngine(); var $dependenciesEngine = DependenciesEngine.getInstance(); function extractLeadingText(string, completeTag) { var tagIndex = string.indexOf(completeTag); var leadingText = null; var leadingTextRegExp = /\[(.+?)\]/g; var leadingTextInfo = leadingTextRegExp.exec(string); // did we find leading text, and if so, does it immediately precede the tag? while (leadingTextInfo && leadingTextInfo.length) { if (leadingTextInfo.index + leadingTextInfo[0].length === tagIndex) { string = string.replace(leadingTextInfo[0], ''); leadingText = leadingTextInfo[1]; break; } leadingTextInfo = leadingTextRegExp.exec(string); } return { leadingText: leadingText, string: string }; } function splitLinkText(text) { var linkText; var target; var splitIndex; // if a pipe is not present, we split on the first space splitIndex = text.indexOf('|'); if (splitIndex === -1) { splitIndex = text.search(/\s/); } if (splitIndex !== -1) { linkText = text.substr(splitIndex + 1); // Normalize subsequent newlines to a single space. linkText = linkText.replace(/\n+/, ' '); target = text.substr(0, splitIndex); } return { linkText: linkText, target: target || text }; } var LinkParser = (function () { var processTheLink = function (string, tagInfo) { var leading = extractLeadingText(string, tagInfo.completeTag), linkText = leading.leadingText || '', split, target, stringtoReplace; split = splitLinkText(tagInfo.text); target = split.target; if (leading.leadingText !== null) { stringtoReplace = '[' + leading.leadingText + ']' + tagInfo.completeTag; } else if (typeof split.linkText !== 'undefined') { stringtoReplace = tagInfo.completeTag; linkText = split.linkText; } return string.replace(stringtoReplace, '[' + linkText + '](' + target + ')'); }; /** * Convert * {@link http://www.google.com|Google} or {@link https://github.com GitHub} to [Github](https://github.com) */ var replaceLinkTag = function (str) { var tagRegExp = new RegExp('\\{@link\\s+((?:.|\n)+?)\\}', 'i'), matches, previousString, tagInfo = []; function replaceMatch(replacer, tag, match, text) { var matchedTag = { completeTag: match, tag: tag, text: text }; tagInfo.push(matchedTag); return replacer(str, matchedTag); } do { matches = tagRegExp.exec(str); if (matches) { previousString = str; str = replaceMatch(processTheLink, 'link', matches[0], matches[1]); } } while (matches && previousString !== str); return { newString: str }; }; var _resolveLinks = function (str) { return replaceLinkTag(str).newString; }; return { resolveLinks: _resolveLinks }; })(); var COMPODOC_DEFAULTS = { title: 'Application documentation', additionalEntryName: 'Additional documentation', additionalEntryPath: 'additional-documentation', folder: './documentation/', port: 8080, theme: 'gitbook', base: '/', disableSourceCode: false, disableGraph: false, disableCoverage: false, disablePrivateOrInternalSupport: false, PAGE_TYPES: { ROOT: 'root', INTERNAL: 'internal' } }; //import * as helpers from 'handlebars-helpers'; var HtmlEngine = (function () { function HtmlEngine() { this.cache = {}; //TODO use this instead : https://github.com/assemble/handlebars-helpers Handlebars.registerHelper("compare", function (a, operator, b, options) { if (arguments.length < 4) { throw new Error('handlebars Helper {{compare}} expects 4 arguments'); } var result; switch (operator) { case 'indexof': result = (b.indexOf(a) !== -1); break; case '===': result = a === b; break; case '!==': result = a !== b; break; case '>': result = a > b; break; default: { throw new Error('helper {{compare}}: invalid operator: `' + operator + '`'); } } if (result === false) { return options.inverse(this); } return options.fn(this); }); Handlebars.registerHelper("or", function () { var len = arguments.length - 1; var options = arguments[len]; for (var i = 0; i < len; i++) { if (arguments[i]) { return options.fn(this); } } return options.inverse(this); }); Handlebars.registerHelper("filterAngular2Modules", function (text, options) { var NG2_MODULES = [ 'BrowserModule', 'FormsModule', 'HttpModule', 'RouterModule' ], len = NG2_MODULES.length; var i = 0, result = false; for (i; i < len; i++) { if (text.indexOf(NG2_MODULES[i]) > -1) { result = true; } } if (result) { return options.fn(this); } else { return options.inverse(this); } }); Handlebars.registerHelper("debug", function (optionalValue) { console.log("Current Context"); console.log("===================="); console.log(this); if (optionalValue) { console.log("OptionalValue"); console.log("===================="); console.log(optionalValue); } }); Handlebars.registerHelper('breaklines', function (text) { text = Handlebars.Utils.escapeExpression(text); text = text.replace(/(\r\n|\n|\r)/gm, '<br>'); text = text.replace(/ /gm, '&nbsp;'); text = text.replace(/ /gm, '&nbsp;&nbsp;&nbsp;&nbsp;'); return new Handlebars.SafeString(text); }); Handlebars.registerHelper('breakComma', function (text) { text = Handlebars.Utils.escapeExpression(text); text = text.replace(/,/g, ',<br>'); return new Handlebars.SafeString(text); }); Handlebars.registerHelper('modifKind', function (kind) { var _kindText = ''; switch (kind) { case 111: _kindText = 'Private'; break; case 112: _kindText = 'Protected'; break; case 113: _kindText = 'Public'; break; case 114: _kindText = 'Static'; break; } return new Handlebars.SafeString(_kindText); }); Handlebars.registerHelper('modifIcon', function (kind) { var _kindText = ''; switch (kind) { case 111: _kindText = 'lock'; break; case 112: _kindText = 'lock'; break; case 113: _kindText = 'circle'; break; case 114: _kindText = 'square'; case 83: _kindText = 'export'; break; } return _kindText; }); /** * Convert {@link MyClass} to [MyClass](http://localhost:8080/classes/MyClass.html) */ Handlebars.registerHelper('parseDescription', function (description, depth) { var tagRegExp = new RegExp('\\{@link\\s+((?:.|\n)+?)\\}', 'i'), matches, previousString, tagInfo = []; var processTheLink = function (string, tagInfo) { var leading = extractLeadingText(string, tagInfo.completeTag), split, result, newLink, rootPath, stringtoReplace; split = splitLinkText(tagInfo.text); if (typeof split.linkText !== 'undefined') { result = $dependenciesEngine.findInCompodoc(split.target); } else { result = $dependenciesEngine.findInCompodoc(tagInfo.text); } if (result) { if (leading.leadingText !== null) { stringtoReplace = '[' + leading.leadingText + ']' + tagInfo.completeTag; } else if (typeof split.linkText !== 'undefined') { stringtoReplace = tagInfo.completeTag; } else { stringtoReplace = tagInfo.completeTag; } if (result.type === 'class') result.type = 'classe'; rootPath = '../'; if (depth && depth === 1) rootPath = './'; newLink = "<a href=\"" + rootPath + result.type + "s/" + result.name + ".html\" >" + result.name + "</a>"; return string.replace(stringtoReplace, newLink); } else { return string; } }; function replaceMatch(replacer, tag, match, text) { var matchedTag = { completeTag: match, tag: tag, text: text }; tagInfo.push(matchedTag); return replacer(description, matchedTag); } do { matches = tagRegExp.exec(description); if (matches) { previousString = description; description = replaceMatch(processTheLink, 'link', matches[0], matches[1]); } } while (matches && previousString !== description); return description; }); Handlebars.registerHelper('relativeURL', function (depth, currentPageType, targetPageType) { //console.log('relativeURL: ', depth, currentPageType, targetPageType); // if depth 2 & type == internal, set on same level, otherwise go up var result = ''; if (currentPageType === COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL && targetPageType === COMPODOC_DEFAULTS.PAGE_TYPES.ROOT) { result = '../'; } else if (currentPageType === COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL && targetPageType === COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL) { result = '../'; } else if (currentPageType === COMPODOC_DEFAULTS.PAGE_TYPES.ROOT && targetPageType === COMPODOC_DEFAULTS.PAGE_TYPES.ROOT) { result = './'; } return result; }); Handlebars.registerHelper('functionSignature', function (method) { var args = method.args.map(function (arg) { var _result = $dependenciesEngine.find(arg.type); if (_result) { if (_result.source === 'internal') { var path_1 = _result.data.type; if (_result.data.type === 'class') path_1 = 'classe'; return arg.name + ": <a href=\"../" + path_1 + "s/" + _result.data.name + ".html\" >" + arg.type + "</a>"; } else { var path_2 = 'https://angular.io/docs/ts/latest/api/' + _result.data.path; return arg.name + ": <a href=\"" + path_2 + "\" target=\"_blank\" >" + arg.type + "</a>"; } } else { return arg.name + ": " + arg.type; } }).join(', '); if (method.name) { return method.name + "(" + args + ")"; } else { return "(" + args + ")"; } }); Handlebars.registerHelper('jsdoc-returns-comment', function (jsdocTags, options) { var i = 0, len = jsdocTags.length, result; for (i; i < len; i++) { if (jsdocTags[i].tagName) { if (jsdocTags[i].tagName.text === 'returns') { result = jsdocTags[i].comment; break; } } } return result; }); Handlebars.registerHelper('jsdoc-component-example', function (jsdocTags, options) { var i = 0, len = jsdocTags.length, tags = []; var cleanTag = function (comment) { if (comment.charAt(0) === '*') { comment = comment.substring(1, comment.length); } if (comment.charAt(0) === ' ') { comment = comment.substring(1, comment.length); } return comment; }; var type = 'html'; if (options.hash.type) { type = options.hash.type; } function htmlEntities(str) { return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); } for (i; i < len; i++) { if (jsdocTags[i].tagName) { if (jsdocTags[i].tagName.text === 'example') { var tag = {}; if (jsdocTags[i].comment) { tag.comment = "<pre><code class=\"hljs " + type + "\">" + htmlEntities(cleanTag(jsdocTags[i].comment)) + "</code></pre>"; } tags.push(tag); } } } if (tags.length > 0) { this.tags = tags; return options.fn(this); } }); Handlebars.registerHelper('jsdoc-example', function (jsdocTags, options) { var i = 0, len = jsdocTags.length, tags = []; for (i; i < len; i++) { if (jsdocTags[i].tagName) { if (jsdocTags[i].tagName.text === 'example') { var tag = {}; if (jsdocTags[i].comment) { tag.comment = jsdocTags[i].comment.replace(/<caption>/g, '<b><i>').replace(/\/caption>/g, '/b></i>'); } tags.push(tag); } } } if (tags.length > 0) { this.tags = tags; return options.fn(this); } }); Handlebars.registerHelper('jsdoc-params', function (jsdocTags, options) { var i = 0, len = jsdocTags.length, tags = []; for (i; i < len; i++) { if (jsdocTags[i].tagName) { if (jsdocTags[i].tagName.text === 'param') { var tag = {}; if (jsdocTags[i].typeExpression && jsdocTags[i].typeExpression.type.name) { tag.type = jsdocTags[i].typeExpression.type.name.text; } if (jsdocTags[i].comment) { tag.comment = jsdocTags[i].comment; } if (jsdocTags[i].parameterName) { tag.name = jsdocTags[i].parameterName.text; } tags.push(tag); } } } if (tags.length >= 1) { this.tags = tags; return options.fn(this); } }); Handlebars.registerHelper('linkType', function (name, options) { var _result = $dependenciesEngine.find(name); if (_result) { this.type = { raw: name }; if (_result.source === 'internal') { if (_result.data.type === 'class') _result.data.type = 'classe'; this.type.href = '../' + _result.data.type + 's/' + _result.data.name + '.html'; this.type.target = '_self'; } else { this.type.href = 'https://angular.io/docs/ts/latest/api/' + _result.data.path; this.type.target = '_blank'; } return options.fn(this); } else { return options.inverse(this); } }); Handlebars.registerHelper('indexableSignature', function (method) { var args = method.args.map(function (arg) { return arg.name + ": " + arg.type; }).join(', '); if (method.name) { return method.name + "[" + args + "]"; } else { return "[" + args + "]"; } }); Handlebars.registerHelper('object', function (text) { text = JSON.stringify(text); text = text.replace(/{"/, '{<br>&nbsp;&nbsp;&nbsp;&nbsp;"'); text = text.replace(/,"/, ',<br>&nbsp;&nbsp;&nbsp;&nbsp;"'); text = text.replace(/}$/, '<br>}'); return new Handlebars.SafeString(text); }); } HtmlEngine.prototype.init = function () { var partials = [ 'menu', 'overview', 'readme', 'modules', 'module', 'components', 'component', 'component-detail', 'directives', 'directive', 'injectables', 'injectable', 'pipes', 'pipe', 'classes', 'class', 'interface', 'routes', 'search-results', 'search-input', 'link-type', 'block-method', 'block-property', 'block-index', 'block-constructor', 'coverage-report', 'miscellaneous' ], i = 0, len = partials.length, loop = function (resolve$$1, reject) { if (i <= len - 1) { fs.readFile(path.resolve(__dirname + '/../src/templates/partials/' + partials[i] + '.hbs'), 'utf8', function (err, data) { if (err) { reject(); } Handlebars.registerPartial(partials[i], data); i++; loop(resolve$$1, reject); }); } else { resolve$$1(); } }; return new Promise(function (resolve$$1, reject) { loop(resolve$$1, reject); }); }; HtmlEngine.prototype.render = function (mainData, page) { var o = mainData, that = this; Object.assign(o, page); return new Promise(function (resolve$$1, reject) { if (that.cache['page']) { var template = Handlebars.compile(that.cache['page']), result = template({ data: o }); resolve$$1(result); } else { fs.readFile(path.resolve(__dirname + '/../src/templates/page.hbs'), 'utf8', function (err, data) { if (err) { reject('Error during index ' + page.name + ' generation'); } else { that.cache['page'] = data; var template = Handlebars.compile(data), result = template({ data: o }); resolve$$1(result); } }); } }); }; return HtmlEngine; }()); var MarkdownEngine = (function () { function MarkdownEngine() { var renderer = new marked.Renderer(); renderer.code = function (code, language) { var validLang = !!(language && highlightjs.getLanguage(language)); var highlighted = validLang ? highlightjs.highlight(language, code).value : code; highlighted = highlighted.replace(/(\r\n|\n|\r)/gm, '<br>'); return "<pre><code class=\"hljs " + language + "\">" + highlighted + "</code></pre>"; }; renderer.table = function (header, body) { return '<table class="table table-bordered compodoc-table">\n' + '<thead>\n' + header + '</thead>\n' + '<tbody>\n' + body + '</tbody>\n' + '</table>\n'; }; renderer.image = function (href, title, text) { var out = '<img src="' + href + '" alt="' + text + '" class="img-responsive"'; if (title) { out += ' title="' + title + '"'; } out += this.options.xhtml ? '/>' : '>'; return out; }; marked__default.setOptions({ renderer: renderer, breaks: true }); } MarkdownEngine.prototype.getReadmeFile = function () { return new Promise(function (resolve$$1, reject) { fs.readFile(path.resolve(process.cwd() + '/README.md'), 'utf8', function (err, data) { if (err) { reject('Error during README.md file reading'); } else { resolve$$1(marked__default(data)); } }); }); }; return MarkdownEngine; }()); var FileEngine = (function () { function FileEngine() { } FileEngine.prototype.get = function (filepath) { return new Promise(function (resolve$$1, reject) { fs.readFile(path.resolve(process.cwd() + path.sep + filepath), 'utf8', function (err, data) { if (err) { reject('Error during ' + filepath + ' read'); } else { resolve$$1(data); } }); }); }; return FileEngine; }()); var Configuration = (function () { function Configuration() { this._pages = []; this._mainData = { output: COMPODOC_DEFAULTS.folder, theme: COMPODOC_DEFAULTS.theme, extTheme: '', serve: false, port: COMPODOC_DEFAULTS.port, open: false, assetsFolder: '', documentationMainName: COMPODOC_DEFAULTS.title, documentationMainDescription: '', base: COMPODOC_DEFAULTS.base, hideGenerator: false, modules: [], readme: '', additionalpages: {}, pipes: [], classes: [], interfaces: [], components: [], directives: [], injectables: [], routes: [], miscellaneous: [], tsconfig: '', includes: false, disableSourceCode: COMPODOC_DEFAULTS.disableSourceCode, disableGraph: COMPODOC_DEFAULTS.disableGraph, disableCoverage: COMPODOC_DEFAULTS.disableCoverage, disablePrivateOrInternalSupport: COMPODOC_DEFAULTS.disablePrivateOrInternalSupport }; if (Configuration._instance) { throw new Error('Error: Instantiation failed: Use Configuration.getInstance() instead of new.'); } Configuration._instance = this; } Configuration.getInstance = function () { return Configuration._instance; }; Configuration.prototype.addPage = function (page) { this._pages.push(page); }; Object.defineProperty(Configuration.prototype, "pages", { get: function () { return this._pages; }, set: function (pages) { this._pages = []; }, enumerable: true, configurable: true }); Object.defineProperty(Configuration.prototype, "mainData", { get: function () { return this._mainData; }, set: function (data) { Object.assign(this._mainData, data); }, enumerable: true, configurable: true }); return Configuration; }()); Configuration._instance = new Configuration(); var ngdCr = require('@compodoc/ngd-core'); var ngdT = require('@compodoc/ngd-transformer'); var NgdEngine = (function () { function NgdEngine() { } NgdEngine.prototype.renderGraph = function (filepath, outputpath, type, name) { return new Promise(function (resolve$$1, reject) { ngdCr.logger.silent = false; var engine = new ngdT.DotEngine({ output: outputpath, displayLegend: true, outputFormats: 'svg' }); if (type === 'f') { engine .generateGraph([$dependenciesEngine.getRawModule(name)]) .then(function (file) { resolve$$1(); }, function (error) { reject(error); }); } else { engine .generateGraph($dependenciesEngine.rawModules) .then(function (file) { resolve$$1(); }, function (error) { reject(error); }); } }); }; return NgdEngine; }()); var lunr = require('lunr'); var cheerio = require('cheerio'); var Entities = require('html-entities').AllHtmlEntities; var $configuration = Configuration.getInstance(); var Html = new Entities(); var SearchEngine = (function () { function SearchEngine() { this.documentsStore = {}; } SearchEngine.prototype.getSearchIndex = function () { if (!this.searchIndex) { this.searchIndex = lunr(function () { this.ref('url'); this.field('title', { boost: 10 }); this.field('body'); }); } return this.searchIndex; }; SearchEngine.prototype.indexPage = function (page) { var text, $ = cheerio.load(page.rawData); text = $('.content').html(); text = Html.decode(text); text = text.replace(/(<([^>]+)>)/ig, ''); page.url = page.url.replace($configuration.mainData.output, ''); var doc = { url: page.url, title: page.infos.context + ' - ' + page.infos.name, body: text }; this.documentsStore[doc.url] = doc; this.getSearchIndex().add(doc); }; SearchEngine.prototype.generateSearchIndexJson = function (outputFolder) { var _this = this; return new Promise(function (resolve$$1, reject) { fs.readFile(path.resolve(__dirname + '/../src/templates/partials/search-index.hbs'), 'utf8', function (err, data) { if (err) { reject('Error during search index generation'); } else { var template = Handlebars.compile(data), result = template({ index: JSON.stringify(_this.getSearchIndex()), store: JSON.stringify(_this.documentsStore) }); fs.outputFile(path.resolve(process.cwd() + path.sep + outputFolder + path.sep + '/js/search/search_index.js'), result, function (err) { if (err) { logger.error('Error during search index file generation ', err); reject(err); } resolve$$1(); }); } }); }); }; return SearchEngine; }()); function detectIndent(str, count, indent) { var stripIndent = function (str) { var match = str.match(/^[ \t]*(?=\S)/gm); if (!match) { return str; } // TODO: use spread operator when targeting Node.js 6 var indent = Math.min.apply(Math, match.map(function (x) { return x.length; })); // eslint-disable-line var re = new RegExp("^[ \\t]{" + indent + "}", 'gm'); return indent > 0 ? str.replace(re, '') : str; }, repeating = function (n, str) { str = str === undefined ? ' ' : str; if (typeof str !== 'string') { throw new TypeError("Expected `input` to be a `string`, got `" + typeof str + "`"); } if (n < 0 || !Number.isFinite(n)) { throw new TypeError("Expected `count` to be a positive finite number, got `" + n + "`"); } var ret = ''; do { if (n & 1) { ret += str; } str += str; } while ((n >>= 1)); return ret; }, indentString = function (str, count, indent) { indent = indent === undefined ? ' ' : indent; count = count === undefined ? 1 : count; if (typeof str !== 'string') { throw new TypeError("Expected `input` to be a `string`, got `" + typeof str + "`"); } if (typeof count !== 'number') { throw new TypeError("Expected `count` to be a `number`, got `" + typeof count + "`"); } if (typeof indent !== 'string') { throw new TypeError("Expected `indent` to be a `string`, got `" + typeof indent + "`"); } if (count === 0) { return str; } indent = count > 1 ? repeating(count, indent) : indent; return str.replace(/^(?!\s*$)/mg, indent); }; return indentString(stripIndent(str), count || 0, indent); } // Create a compilerHost object to allow the compiler to read and write files function compilerHost(transpileOptions) { var inputFileName = transpileOptions.fileName || (transpileOptions.jsx ? 'module.tsx' : 'module.ts'); var compilerHost = { getSourceFile: function (fileName) { if (fileName.lastIndexOf('.ts') !== -1) { if (fileName === 'lib.d.ts') { return undefined; } if (fileName.substr(-5) === '.d.ts') { return undefined; } if (path.isAbsolute(fileName) === false) { fileName = path.join(transpileOptions.tsconfigDirectory, fileName); } if (!fs.existsSync(fileName)) { return undefined; } var libSource = ''; try { libSource = fs.readFileSync(fileName).toString(); } catch (e) { logger.debug(e, fileName); } return ts.createSourceFile(fileName, libSource, transpileOptions.target, false); } return undefined; }, writeFile: function (name, text) { }, getDefaultLibFileName: function () { return 'lib.d.ts'; }, useCaseSensitiveFileNames: function () { return false; }, getCanonicalFileName: function (fileName) { return fileName; }, getCurrentDirectory: function () { return ''; }, getNewLine: function () { return '\n'; }, fileExists: function (fileName) { return fileName === inputFileName; }, readFile: function () { return ''; }, directoryExists: function () { return true; }, getDirectories: function () { return []; } }; return compilerHost; } var RouterParser = (function () { var routes = [], modules = [], modulesTree, rootModule, modulesWithRoutes = []; return { addRoute: function (route) { routes.push(route); routes = _.sortBy(_.uniqWith(routes, _.isEqual), ['name']); }, addModuleWithRoutes: function (moduleName, moduleImports) { modulesWithRoutes.push({ name: moduleName, importsNode: moduleImports }); modulesWithRoutes = _.sortBy(_.uniqWith(modulesWithRoutes, _.isEqual), ['name']); }, addModule: function (moduleName, moduleImports) { modules.push({ name: moduleName, importsNode: moduleImports }); modules = _.sortBy(_.uniqWith(modules, _.isEqual), ['name']); }, setRootModule: function (module) { rootModule = module; }, printRoutes: function () { console.log(''); console.log('printRoutes: '); console.log(routes); }, printModulesRoutes: function () { console.log(''); console.log('modulesWithRoutes: '); console.log(modulesWithRoutes); }, hasRouterModuleInImports: function (imports) { var result = false, i = 0, len = imports.length; for (i; i < len; i++) { if (imports[i].name.indexOf('RouterModule.forChild') !== -1 || imports[i].name.indexOf('RouterModule.forRoot') !== -1) { result = true; } } return result; }, linkModulesAndRoutes: function () { //scan each module imports AST for each routes, and link routes with module var i = 0, len = modulesWithRoutes.length; for (i; i < len; i++) { _.forEach(modulesWithRoutes[i].importsNode, function (node) { if (node.initializer) { if (node.initializer.elements) { _.forEach(node.initializer.elements, function (element) { //find element with arguments if (element.arguments) { _.forEach(element.arguments, function (argument) { _.forEach(routes, function (route) { if (argument.text && route.name === argument.text) { route.module = modulesWithRoutes[i].name; } }); }); } }); } } }); } console.log(''); console.log('end linkModulesAndRoutes: '); console.log(routes); }, constructRoutesTree: function () { console.log(''); console.log('constructRoutesTree'); // routes[] contains routes with module link // modulesTree contains modules tree // make a final routes tree with that var cleanModulesTree = _.cloneDeep(modulesTree), modulesCleaner = function (arr) { for (var i in arr) { if (arr[i].importsNode) { delete arr[i].importsNode; } if (arr[i].parent) { delete arr[i].parent; } if (arr[i].children) { modulesCleaner(arr[i].children); } } }; modulesCleaner(cleanModulesTree); //fs.outputJson('./modules.json', cleanModulesTree); console.log(''); console.log(' cleanModulesTree light: ', util.inspect(cleanModulesTree, { depth: 10 })); console.log(''); var routesTree = { tag: '<root>', kind: 'ngModule', name: rootModule, children: [] }; var foundRouteWithModuleName = function (moduleName) { return _.find(routes, { 'module': moduleName }); }; var loopModulesParser = function (node) { if (node.children && node.children.length > 0) { //If module has child modules console.log(' If module has child modules'); for (var i in node.children) { var route = foundRouteWithModuleName(node.children[i].name); if (route) { route.routes = JSON.parse(route.data); delete route.data; route.kind = 'ngModule'; routesTree.children.push(route); } if (node.children[i].children) { loopModulesParser(node.children[i]); } } } else { //else routes are directly inside the module console.log(' else routes are directly inside the module'); } }; console.log(''); console.log(' rootModule: ', rootModule); console.log(''); loopModulesParser(_.find(cleanModulesTree, { 'name': rootModule })); console.log(''); console.log(' routesTree: ', routesTree); console.log(''); //fs.outputJson('./routes-tree.json', routesTree); var cleanedRoutesTree; var cleanRoutesTree = function (route) { for (var i in route.children) { var routes = route.children[i].routes; console.log(routes); } return route; }; cleanedRoutesTree = cleanRoutesTree(routesTree); console.log(''); console.log(' cleanedRoutesTree: ', util.inspect(cleanedRoutesTree, { depth: 10 })); }, constructModulesTree: function () { console.log(''); console.log('constructModulesTree'); var getNestedChildren = function (arr, parent) { var out = []; for (var i in arr) { if (arr[i].parent === parent) { var children = getNestedChildren(arr, arr[i].name); if (children.length) { arr[i].children = children; } out.push(arr[i]); } } return out; }; //Scan each module and add parent property _.forEach(modules, function (firstLoopModule) { _.forEach(firstLoopModule.importsNode, function (importNode) { _.forEach(modules, function (module) { if (module.name === importNode.name) { module.parent = firstLoopModule.name; } }); }); }); modulesTree = getNestedChildren(modules); console.log(''); console.log('end constructModulesTree'); console.log(modulesTree); } }; })(); function isVariableLike(node) { if (node) { switch (node.kind) { case ts.SyntaxKind.BindingElement: case ts.SyntaxKind.EnumMember: case ts.SyntaxKind.Parameter: case ts.SyntaxKind.PropertyAssignment: case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.PropertySignature: case ts.SyntaxKind.ShorthandPropertyAssignment: case ts.SyntaxKind.VariableDeclaration: return true; } } return false; } function some(array, predicate) { if (array) { if (predicate) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { var v = array_1[_i]; if (predicate(v)) { return true; } } } else { return array.length > 0; } } return false; } function concatenate(array1, array2) { if (!some(array2)) return array1; if (!some(array1)) return array2; return array1.concat(array2); } function isParameter(node) { return node.kind === ts.SyntaxKind.Parameter; } function getJSDocParameterTags(param) { if (!isParameter(param)) { return undefined; } var func = param.parent; var tags = getJSDocTags(func, ts.SyntaxKind.JSDocParameterTag); if (!param.name) { // this is an anonymous jsdoc param from a `function(type1, type2): type3` specification var i = func.parameters.indexOf(param); var paramTags = filter(tags, function (tag) { return tag.kind === ts.SyntaxKind.JSDocParameterTag; }); if (paramTags && 0 <= i && i < paramTags.length) { return [paramTags[i]]; } } else if (param.name.kind === ts.SyntaxKind.Identifier) { var name_1 = param.name.text; return filter(tags, function (tag) { return tag.kind === ts.SyntaxKind.JSDocParameterTag && tag.parameterName.text === name_1; }); } else { // TODO: it's a destructured parame