UNPKG

@ipp/cli

Version:

An image build orchestrator for the modern web

79 lines (78 loc) 3.66 kB
"use strict"; /** * Image Processing Pipeline - Copyright (c) Marcus Cemes * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getConfig = void 0; const common_1 = require("@ipp/common"); const ajv_1 = __importDefault(require("ajv")); const chalk_1 = __importDefault(require("chalk")); const cosmiconfig_1 = require("cosmiconfig"); const exception_1 = require("../lib/exception"); const config_json_1 = __importDefault(require("../schema/config.json")); const default_config_json_1 = __importDefault(require("./default_config.json")); const MODULE_NAME = "ipp"; async function getConfig(initial, path) { const config = await loadConfig(path); return validateConfig({ ...config, ...initial }); } exports.getConfig = getConfig; /** Attempts to load a config from a path, or by looking in well known locations */ async function loadConfig(path) { try { const configExplorer = (0, cosmiconfig_1.cosmiconfig)(MODULE_NAME); const explorerResult = await (path ? configExplorer.load(path) : configExplorer.search()); if (!(explorerResult === null || explorerResult === void 0 ? void 0 : explorerResult.config)) { return default_config_json_1.default; } return explorerResult.config; } catch (err) { throw new exception_1.CliException("Configuration load failure", exception_1.CliExceptionCode.CONFIG_LOAD, `Configuration load error -> ${err.name}`, err.message).extend(err); } } /** Validate the configuration */ function validateConfig(config) { var _a; friendlyParse(config); const filteredConfig = { ...config }; const ajv = new ajv_1.default({ allErrors: true }); ajv.addSchema(common_1.PipelineSchema); const valid = ajv.validate(config_json_1.default, filteredConfig); if (!valid) throw new exception_1.CliException("Invalid config", exception_1.CliExceptionCode.CONFIG_PARSE, "Configuration validation failed", (_a = ajv.errors) === null || _a === void 0 ? void 0 : _a.map(parseAjvError).join("\n")); return filteredConfig; } /** Check for some easy mistakes and supply user-friendly errors */ function friendlyParse(config = {}) { const errors = []; const criteria = [ [config.input, "An input directory containing images must be specified"], [config.output, "An output directory for generated formats must be specified"], [config.pipeline, "A processing pipeline must be specified"], ]; for (const [key, message] of criteria) { if (!key) errors.push(message); } if (errors.length > 0) throw new exception_1.CliException("Invalid configuration", exception_1.CliExceptionCode.CONFIG_PARSE, "Invalid configuration", errors.join("\n") + `\n\n${chalk_1.default.white("Did you create a configuration file?")}`); } /** Friendlier hints as to why the validation faled */ function parseAjvError({ keyword, message, params, instancePath }) { const property = chalk_1.default.bold(`Config${instancePath}`); switch (keyword) { case "additionalProperties": return `${property} has an unknown property "${chalk_1.default.bold(params.additionalProperty)}"`; case "required": return `${property} is missing property "${chalk_1.default.bold(params.missingProperty)}"`; default: return `${property} ${message}`; } }