UNPKG

@argdown/node

Version:

Async Argdown application for node.js

291 lines 12.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AsyncArgdownApplication = void 0; const lodash_defaultsdeep_1 = __importDefault(require("lodash.defaultsdeep")); const lodash_isfunction_1 = __importDefault(require("lodash.isfunction")); const lodash_isstring_1 = __importDefault(require("lodash.isstring")); const lodash_isempty_1 = __importDefault(require("lodash.isempty")); const lodash_isobject_1 = __importDefault(require("lodash.isobject")); const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep")); const core_1 = require("@argdown/core"); const IAsyncArgdownPlugin_1 = require("./IAsyncArgdownPlugin"); const path_1 = __importDefault(require("path")); const chokidar_1 = __importDefault(require("chokidar")); const glob_1 = __importDefault(require("glob")); const util_1 = require("util"); const import_fresh_1 = __importDefault(require("import-fresh")); const fs_1 = require("fs"); const readFileAsync = (0, util_1.promisify)(fs_1.readFile); class AsyncArgdownApplication extends core_1.ArgdownApplication { constructor() { super(...arguments); this.load = async (request) => { const processObj = request.processes && (0, lodash_isstring_1.default)(request.process) ? request.processes[request.process] : undefined; let req = request; if (processObj) { req = (0, lodash_defaultsdeep_1.default)({}, processObj, req); } let inputGlob = req.inputPath || "./*.argdown"; const ignoreFiles = req.ignore || [ "**/_*", "**/_*/**" ]; if (req.logger && (0, lodash_isfunction_1.default)(req.logger.log) && (0, lodash_isfunction_1.default)(req.logger.setLevel)) { if (!this.defaultLogger) { this.defaultLogger = this.logger; } this.logger = req.logger; } else if (this.defaultLogger) { this.logger = this.defaultLogger; } if (!req.rootPath) { req.rootPath = process.cwd(); } if (req.logLevel) { this.logger.setLevel(req.logLevel); } if (req.plugins) { for (let pluginData of req.plugins) { if ((0, lodash_isobject_1.default)(pluginData.plugin) && (0, lodash_isstring_1.default)(pluginData.processor)) { this.addPlugin(pluginData.plugin, pluginData.processor); } } } if (req.input && !req.inputPath) { await this.runAsync((0, lodash_clonedeep_1.default)(request)); return; } const $ = this; let absoluteInputGlob = path_1.default.resolve(req.rootPath, inputGlob); const loadOptions = {}; if (ignoreFiles) { loadOptions.ignore = ignoreFiles; } if (req.watch) { const watcher = chokidar_1.default.watch(absoluteInputGlob, loadOptions); const watcherRequest = (0, lodash_clonedeep_1.default)(req); watcherRequest.watch = false; watcher .on("add", path => { this.logger.log("verbose", `File ${path} has been added.`); watcherRequest.inputPath = path; $.load(watcherRequest); }) .on("change", path => { this.logger.log("verbose", `File ${path} has been changed.`); watcherRequest.inputPath = path; $.load(watcherRequest); }) .on("unlink", path => { this.logger.log("verbose", `File ${path} has been removed.`); }); } else { let files = await new Promise((resolve, reject) => { (0, glob_1.default)(absoluteInputGlob, loadOptions, (er, files) => { if (er) { reject(er); } resolve(files); }); }); const promises = []; if (files.length == 0) { throw new core_1.ArgdownPluginError("AsyncArgdownApplication.load", "no-files-found", `No Argdown files found at: '${absoluteInputGlob}'`); } for (let file of files) { const requestForFile = (0, lodash_clonedeep_1.default)(request); requestForFile.inputPath = file; promises.push(this.runAsync(requestForFile)); } if (req.plugins) { for (let pluginData of req.plugins) { this.removePlugin(pluginData.plugin, pluginData.processor); } } return await Promise.all(promises); } return; }; this.loadConfig = async (filePath) => { let config = {}; filePath = filePath || "argdown.config.json"; filePath = path_1.default.resolve(process.cwd(), filePath); const extension = path_1.default.extname(filePath); if (extension === ".json") { try { const buffer = await readFileAsync(filePath, "utf8"); config = JSON.parse(buffer); } catch (e) { if (e instanceof Error) { this.logger.log("verbose", "[AsyncArgdownApplication]: No config found: " + e.toString()); } } } else if (extension === ".js") { try { let jsModuleExports = loadJSFile(filePath); if (jsModuleExports.config) { config = jsModuleExports.config; } else { config = jsModuleExports; } } catch (e) { if (e instanceof Error) { this.logger.log("verbose", "[AsyncArgdownApplication]: No config found: " + e.toString()); } } } return config; }; } async runAsync(request, response) { let processorsToRun = []; this.logger.setLevel("error"); let resp = response || {}; let req = request; if (req) { if (req.logLevel) { this.logger.setLevel(req.logLevel); } if (req.process) { if (Array.isArray(req.process)) { processorsToRun = req.process; } else if ((0, lodash_isstring_1.default)(req.process) && req.processes && req.processes[req.process]) { const processObj = req.processes[req.process]; req = (0, lodash_defaultsdeep_1.default)({}, processObj, req); if ((0, lodash_isstring_1.default)(req.process)) { processorsToRun = this.defaultProcesses[req.process]; } else if (req.process && req.process.constructor === Array) { processorsToRun = req.process; } } else if ((0, lodash_isstring_1.default)(req.process)) { processorsToRun = this.defaultProcesses[req.process]; } } } if ((0, lodash_isempty_1.default)(processorsToRun)) { this.logger.log("error", "[AsyncArgdownApplication]: No processors to run."); return resp; } const exceptions = []; resp.exceptions = exceptions; for (let processorId of processorsToRun) { let cancelProcessor = false; let processor = this.processors[processorId]; if (!processor) { this.logger.log("error", "[AsyncArgdownApplication]: Processor not found: " + processorId); continue; } this.logger.log("verbose", "[AsyncArgdownApplication]: Running processor: " + processorId); for (let plugin of processor.plugins) { if ((0, lodash_isfunction_1.default)(plugin.prepare)) { this.logger.log("verbose", "[AsyncArgdownApplication]: Preparing plugin: " + plugin.name); try { plugin.prepare(req, resp, this.logger); } catch (e) { if (req.throwExceptions) { throw e; } else if (e instanceof core_1.ArgdownPluginError) { e.processor = processorId; exceptions.push(e); cancelProcessor = true; this.logger.log("warning", `Processor ${processorId} canceled.`); break; } } } } if (cancelProcessor) { break; } if (resp.ast && processor.walker) { try { processor.walker.walk(req, resp, this.logger); } catch (e) { if (req.throwExceptions) { throw e; } else if (e instanceof core_1.ArgdownPluginError) { e.processor = processorId; cancelProcessor = true; exceptions.push(e); this.logger.log("warning", `[ArgdownApplication]: Processor ${processorId} canceled.`); break; } } } if (cancelProcessor) { break; } for (let plugin of processor.plugins) { this.logger.log("verbose", "[AsyncArgdownApplication]: Running plugin: " + plugin.name); try { if ((0, IAsyncArgdownPlugin_1.isAsyncPlugin)(plugin)) { await plugin.runAsync(req, resp, this.logger); } else if ((0, lodash_isfunction_1.default)(plugin.run)) { plugin.run(req, resp, this.logger); } } catch (e) { if (req.throwExceptions) { throw e; } else if (e instanceof core_1.ArgdownPluginError) { e.processor = processorId; cancelProcessor = true; this.logger.log("warning", `Processor ${processorId} canceled.`); exceptions.push(e); break; } } } if (cancelProcessor) { break; } } if (req.logExceptions === undefined || req.logExceptions) { for (let exception of exceptions) { let msg = exception.stack || exception.message; if (exception instanceof core_1.ArgdownPluginError) { msg = `[${exception.processor}/${exception.plugin}]: ${msg}`; } this.logger.log("error", msg); } } return resp; } } exports.AsyncArgdownApplication = AsyncArgdownApplication; const loadJSFile = (filePath) => { try { return (0, import_fresh_1.default)(filePath); } catch (e) { if (e instanceof Error) { e.message = `Cannot read file: ${filePath}\nError: ${e.message}`; } throw e; } }; //# sourceMappingURL=AsyncArgdownApplication.js.map