UNPKG

dgeni

Version:

Flexible JavaScript documentation generator used by both AngularJS and Angular

254 lines 11.4 kB
"use strict"; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Dgeni = void 0; /* tslint globals: require: true */ var di = require('di'); var Package_1 = require("./Package"); var processorValidation_1 = require("./legacyPackages/processorValidation"); var dependency_sort_1 = require("./util/dependency-sort"); var getInjectables_1 = require("./util/getInjectables"); var log_1 = require("./util/log"); /** * Create an instance of the Dgeni documentation generator, loading any packages passed in as a * parameter. * @param {Package[]} [packages] A collection of packages to load */ var Dgeni = /** @class */ (function () { function Dgeni(packages) { var _this = this; if (packages === void 0) { packages = []; } this.packages = {}; if (!Array.isArray(packages)) { throw new Error('packages must be an array'); } // Add in the legacy validation that was originally part of the core Dgeni tool. this.package(processorValidation_1.processorValidationPackage); packages.map(function (p) { return _this.package(p); }); } /** * Load a package into dgeni * @param package The package to load or the name of a new package to create. * @param dependencies A collection of dependencies for this package * @return The package that was loaded, to allow chaining */ Dgeni.prototype.package = function (pkg, dependencies) { var _this = this; if (dependencies === void 0) { dependencies = []; } if (this.injector) { throw new Error('injector already configured - you cannot add a new package'); } if (typeof pkg === 'string') { pkg = new Package_1.Package(pkg, dependencies); } if (!(Package_1.Package.isPackage(pkg))) { throw new Error('package must be an instance of Package'); } if (this.packages[pkg.name]) { throw new Error('The "' + pkg.name + '" package has already been loaded'); } this.packages[pkg.name] = pkg; // Extract all inline packages and load them into dgeni; pkg.namedDependencies = pkg.dependencies.map(function (dependency) { if (Package_1.Package.isPackage(dependency)) { // Only load dependent package if not already loaded if (!_this.packages[dependency.name]) { _this.package(dependency); } return dependency.name; } return dependency; }); // Return the package to allow chaining return pkg; }; /** * Configure the injector using the loaded packages. * * The injector is assigned to the `injector` property on `this`, which is used by the * `generate()` method. Subsequent calls to this method will just return the same injector. * * This method is useful in unit testing services and processors as it gives an easy way to * get hold of an instance of a ready instantiated component without having to load in all * the potential dependencies manually: * * ``` * const Dgeni = require('dgeni'); * * function getInjector() { * const dgeni = new Dgeni(); * dgeni.package('testPackage', [require('dgeni-packages/base')]) * .factory('templateEngine', function dummyTemplateEngine() {}); * return dgeni.configureInjector(); * }; * * describe('someService', function() { * const someService; * beforeEach(function() { * const injector = getInjector(); * someService = injector.get('someService'); * }); * * it("should do something", function() { * someService.doSomething(); * ... * }); * }); * ``` */ Dgeni.prototype.configureInjector = function () { var _this = this; if (!this.injector) { // Sort the packages by their dependency - ensures that services and configs are loaded in the // correct order var packages = this.packages = dependency_sort_1.sortByDependency(this.packages, 'namedDependencies'); // Create a module containing basic shared services this.stopOnProcessingError = true; var dgeniModule = new di.Module() .value('dgeni', this) .factory('log', log_1.logFactory) .factory('getInjectables', getInjectables_1.getInjectablesFactory); // Create the dependency injection container, from all the packages' modules var modules = packages.map(function (pkg) { return pkg.module; }); modules.unshift(dgeniModule); // Create the injector and var injector_1 = this.injector = new di.Injector(modules); // Apply the config blocks packages.forEach(function (pkg) { return pkg.configFns.forEach(function (configFn) { return injector_1.invoke(configFn); }); }); // Get the the processors and event handlers var processorMap_1 = {}; this.handlerMap = {}; packages.forEach(function (pkg) { pkg.processors.forEach(function (processorName) { var processor = injector_1.get(processorName); // Update the processor's name and package processor.name = processorName; processor.$package = pkg.name; // Ignore disabled processors if (processor.$enabled !== false) { processorMap_1[processorName] = processor; } }); var _loop_1 = function (eventName) { var handlers = _this.handlerMap[eventName] = (_this.handlerMap[eventName] || []); pkg.handlers[eventName].forEach(function (handlerName) { return handlers.push(injector_1.get(handlerName)); }); }; for (var eventName in pkg.handlers) { _loop_1(eventName); } }); // Once we have configured everything sort the processors. // This allows the config blocks to modify the $runBefore and $runAfter properties of processors. // (Crazy idea, I know, but useful for things like debugDumpProcessor) this.processors = dependency_sort_1.sortByDependency(processorMap_1, '$runAfter', '$runBefore'); } return this.injector; }; /** * Generate the documentation using the loaded packages * @return {Promise} A promise to the generated documents */ Dgeni.prototype.generate = function () { var _this = this; var injector = this.configureInjector(); var log = injector.get('log'); var processingPromise = this.triggerEvent('generationStart'); // Process the docs var currentDocs = []; processingPromise = processingPromise.then(function () { return currentDocs; }); this.processors.forEach(function (processor) { processingPromise = processingPromise.then(function (docs) { return _this.runProcessor(processor, docs); }); }); processingPromise.catch(function (error) { log.error(error.message); if (error.stack) { log.debug(error.stack); } log.error('Failed to process the docs'); }); return processingPromise.then(function (docs) { _this.triggerEvent('generationEnd'); return docs; }); }; Dgeni.prototype.runProcessor = function (processor, docs) { var _this = this; var log = this.injector.get('log'); var promise = Promise.resolve(docs); if (!processor.$process) { return promise; } return promise .then(function () { log.info('running processor:', processor.name); return _this.triggerProcessorEvent('processorStart', processor, docs); }) // We need to wrap this $process call in a new promise handler so that we can catch // errors triggered by exceptions thrown in the $process method // before they reach the promise handlers .then(function (docs) { return processor.$process(docs) || docs; }) .then(function (docs) { return _this.triggerProcessorEvent('processorEnd', processor, docs); }) .catch(function (error) { error.message = 'Error running processor "' + processor.name + '":\n' + error.message; if (_this.stopOnProcessingError) { return Promise.reject(error); } else { log.error(error.message); } return docs; }); }; /** * Trigger a dgeni event and run all the registered handlers * All the arguments to this call are passed through to each handler * @param {string} eventName The event being triggered * @return {Promise} A promise to an array of the results from each of the handlers */ Dgeni.prototype.triggerEvent = function (eventName) { var extras = []; for (var _i = 1; _i < arguments.length; _i++) { extras[_i - 1] = arguments[_i]; } var handlers = this.handlerMap[eventName]; var handlersPromise = Promise.resolve(); var results = []; if (handlers) { handlers.forEach(function (handler) { handlersPromise = handlersPromise.then(function () { var handlerPromise = Promise.resolve(handler.apply(void 0, __spreadArrays([eventName], extras))); handlerPromise.then(function (result) { return results.push(result); }); return handlerPromise; }); }); } return handlersPromise.then(function () { return results; }); }; Dgeni.prototype.triggerProcessorEvent = function (eventName, processor, docs) { return this.triggerEvent(eventName, processor, docs).then(function () { return docs; }); }; Dgeni.prototype.info = function () { var injector = this.configureInjector(); var log = injector.get('log'); for (var pkgName in this.packages) { log.info(pkgName, '[' + this.packages[pkgName].dependencies.map(function (dep) { return JSON.stringify(dep.name); }).join(', ') + ']'); } log.info('== Processors (processing order) =='); this.processors.forEach(function (processor, index) { log.info((index + 1) + ': ' + processor.name, processor.$process ? '' : '(abstract)', ' from ', processor.$package); if (processor.description) { log.info(' ', processor.description); } }); }; Dgeni.Package = Package_1.Package; return Dgeni; }()); exports.Dgeni = Dgeni; //# sourceMappingURL=Dgeni.js.map