UNPKG

@asyncapi/generator

Version:

The AsyncAPI generator. It can generate documentation, code, anything!

135 lines (118 loc) 5.26 kB
const path = require('path'); const fs = require('fs'); const xfs = require('fs.extra'); const { isAsyncFunction, registerTypeScript } = require('./utils'); const nunjucksFilters = require('@asyncapi/nunjucks-filters'); /** * Registers all template filters. * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0 * @param {Object} nunjucks Nunjucks environment. * @param {Object} templateConfig Template configuration. * @param {String} templateDir Directory where template is located. * @param {String} filtersDir Directory where local filters are located. */ module.exports.registerFilters = async (nunjucks, templateConfig, templateDir, filtersDir) => { await registerLocalFilters(nunjucks, templateDir, filtersDir); registerConfigFilters(nunjucks, templateDir, templateConfig); // Register Nunjucks filters from the 'nunjucks-filters' module without needing to list them in package.json or .ageneratorrc file. addFilters(nunjucks, nunjucksFilters); }; /** * Registers the local template filters. * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0 * @private * @param {Object} nunjucks Nunjucks environment. * @param {String} templateDir Directory where template is located. * @param {String} filtersDir Directory where local filters are located. */ function registerLocalFilters(nunjucks, templateDir, filtersDir) { return new Promise((resolve, reject) => { const localFilters = path.resolve(templateDir, filtersDir); if (!fs.existsSync(localFilters)) return resolve(); const walker = xfs.walk(localFilters, { followLinks: false }); walker.on('file', async (root, stats, next) => { try { const filePath = path.resolve( templateDir, path.resolve(root, stats.name) ); registerTypeScript(filePath); // If it's a module constructor, inject dependencies to ensure consistent usage in remote templates in other projects or plain directories. delete require.cache[require.resolve(filePath)]; const mod = require(filePath); addFilters(nunjucks, mod); next(); } catch (e) { reject(e); } }); walker.on('errors', (root, nodeStatsArray) => { reject(nodeStatsArray); }); walker.on('end', async () => { resolve(); }); }); } /** * Registers the additionally configured filters. * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0 * @private * @param {Object} nunjucks Nunjucks environment. * @param {String} templateDir Directory where template is located. * @param {Object} templateConfig Template configuration. */ async function registerConfigFilters(nunjucks, templateDir, templateConfig) { const confFilters = templateConfig.filters; const DEFAULT_MODULES_DIR = 'node_modules'; if (!Array.isArray(confFilters)) return; const promises = confFilters.map(async filtersModule => { let mod; let filterName = filtersModule; try { //first we try to grab module with filters by the module name //this is when generation is used on production using remote templates mod = require(filterName); } catch (error) { //in case template is local but was not installed in node_modules of the generator then we need to explicitly provide modules location try { filterName = path.resolve(templateDir, DEFAULT_MODULES_DIR, filtersModule); mod = require(filterName); } catch (e) { //sometimes it may happen that template is located in node_modules with other templates and its filter package is on the same level as template, as it is shared with other templates try { filterName = path.resolve(templateDir, '../..', filtersModule); mod = require(filterName); } catch (error) { //in rare cases, especially in isolated tests, it may happen that installation //ends but is not yet fully completed, so initial require of the same path do not work //but in next attempt it works //we need to keep this workaround until we find a solution mod = require(filterName); } } } return addFilters(nunjucks, mod); }); await Promise.all(promises); } /** * Add filter functions to Nunjucks environment. Only owned functions from the module are added. * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0 * @private * @param {Object} nunjucks Nunjucks environment. * @param {Object} filters Module with functions. */ function addFilters(nunjucks, filters) { Object.getOwnPropertyNames(filters).forEach((key) => { const value = filters[key]; if (!(value instanceof Function)) return; if (isAsyncFunction(value)) { nunjucks.addFilter(key, value, true); } else { nunjucks.addFilter(key, value); } }); }