@ipp/cli
Version:
An image build orchestrator for the modern web
79 lines (78 loc) • 3.66 kB
JavaScript
;
/**
* 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}`;
}
}