UNPKG

v8r

Version:

A command-line JSON, YAML and TOML validator that's on your wavelength

100 lines (88 loc) 2.89 kB
import path from "node:path"; import { isSea } from "node:sea"; import logger from "./logger.js"; import { BasePlugin } from "./plugins.js"; import ParserJson from "./plugins/parser-json.js"; import ParserJson5 from "./plugins/parser-json5.js"; import ParserToml from "./plugins/parser-toml.js"; import ParserYaml from "./plugins/parser-yaml.js"; import OutputText from "./plugins/output-text.js"; import OutputJson from "./plugins/output-json.js"; function validatePlugin(plugin) { if ( typeof plugin.name !== "string" || !plugin.name.startsWith("v8r-plugin-") ) { throw new Error(`Plugin ${plugin.name} does not declare a valid name`); } if (!(plugin.prototype instanceof BasePlugin)) { throw new Error(`Plugin ${plugin.name} does not extend BasePlugin`); } for (const prop of Object.getOwnPropertyNames(BasePlugin.prototype)) { const method = plugin.prototype[prop]; const argCount = plugin.prototype[prop].length; if (typeof method !== "function") { throw new Error( `Error loading plugin ${plugin.name}: must have a method called ${method}`, ); } const expectedArgs = BasePlugin.prototype[prop].length; if (expectedArgs !== argCount) { throw new Error( `Error loading plugin ${plugin.name}: ${prop} must take exactly ${expectedArgs} arguments`, ); } } } function resolveUserPlugins(userPlugins) { let plugins = []; for (let plugin of userPlugins) { if (plugin.startsWith("package:")) { plugins.push(plugin.slice(8)); } if (plugin.startsWith("file:")) { plugins.push(path.resolve(process.cwd(), plugin.slice(5))); } } return plugins; } function loadCorePlugins(plugins) { plugins.forEach((plugin) => validatePlugin(plugin)); const loadedPlugins = plugins.map((plugin) => new plugin()); return loadedPlugins; } async function loadUserPlugins(plugins) { let loadedPlugins = []; for (const plugin of plugins) { loadedPlugins.push(await import(plugin)); } loadedPlugins = loadedPlugins.map((plugin) => plugin.default); loadedPlugins.forEach((plugin) => validatePlugin(plugin)); loadedPlugins = loadedPlugins.map((plugin) => new plugin()); return loadedPlugins; } async function loadAllPlugins(userPlugins) { let loadedUserPlugins = []; if (isSea() && userPlugins.length > 0) { logger.warning( "loading plugins is not supported when running as a standalone binary", ); } else { loadedUserPlugins = await loadUserPlugins(userPlugins); } const corePlugins = [ ParserJson, ParserJson5, ParserToml, ParserYaml, OutputText, OutputJson, ]; const loadedCorePlugins = loadCorePlugins(corePlugins); return { allLoadedPlugins: loadedUserPlugins.concat(loadedCorePlugins), loadedCorePlugins, loadedUserPlugins, }; } export { loadAllPlugins, resolveUserPlugins };