UNPKG

couchbase-index-manager

Version:
194 lines 7.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefinitionLoader = void 0; const tslib_1 = require("tslib"); const chalk_1 = tslib_1.__importDefault(require("chalk")); const fs_1 = tslib_1.__importDefault(require("fs")); const js_yaml_1 = tslib_1.__importDefault(require("js-yaml")); const lodash_1 = require("lodash"); const path_1 = tslib_1.__importDefault(require("path")); const util_1 = tslib_1.__importDefault(require("util")); const configuration_1 = require("../configuration"); const index_definition_1 = require("./index-definition"); const node_map_1 = require("./node-map"); const lstat = util_1.default.promisify(fs_1.default.lstat); const readdir = util_1.default.promisify(fs_1.default.readdir); const readFile = util_1.default.promisify(fs_1.default.readFile); const INDEX_EXTENSIONS = ['.json', '.yaml', '.yml']; function validateConfiguration(validatorSet, configuration) { var _a; let key; for (key in validatorSet) { try { if (key !== 'post_validate') { (_a = validatorSet[key]) === null || _a === void 0 ? void 0 : _a.call(configuration, configuration[key]); } } catch (e) { throw new Error(`${e} in ${configuration.name || 'unk'}.${new String(key)}`); } } // Don't perform post_validate step on overrides, as overrides // don't have the full set of properties. if (validatorSet.post_validate && !(0, configuration_1.isOverride)(configuration)) { try { validatorSet.post_validate.call(configuration); } catch (e) { throw new Error(`${e} in ${configuration.name || 'unk'}`); } } } /** * Loads index definitions from disk or stdin */ class DefinitionLoader { constructor(logger) { this.logger = logger || console; } /** * Loads definitions from disk */ async loadDefinitions(paths) { const definitions = []; const nodeMap = new node_map_1.NodeMap(); let files = []; for (const filePath of paths) { if (filePath === '-') { // read from stdin await this.loadFromStdIn((def) => this.processConfiguration(definitions, nodeMap, def)); continue; } try { if ((await lstat(filePath)).isDirectory()) { const filesInDir = await readdir(filePath); const joinedFilesInDir = filesInDir.map((fileName) => path_1.default.join(filePath, fileName)); files.push(...joinedFilesInDir); } else { files.push(filePath); } } catch (_a) { throw new Error('Path not found'); } } // Only look at specific file types files = files.filter((filename) => INDEX_EXTENSIONS.includes(path_1.default.extname(filename).toLowerCase())); for (let i = 0; i < files.length; i++) { await this.loadDefinition(files[i], (def) => this.processConfiguration(definitions, nodeMap, def)); } return { definitions, nodeMap, }; } /** * Loads index definitions from a file */ async loadDefinition(filename, handler) { const ext = path_1.default.extname(filename).toLowerCase(); const contents = await readFile(filename, 'utf8'); if (ext === '.json') { handler(JSON.parse(contents)); } else if (ext === '.yaml' || ext === '.yml') { js_yaml_1.default.loadAll(contents, handler); } } /** * @private * Loads index definitions from stdin */ loadFromStdIn(handler) { return new Promise((resolve, reject) => { process.stdin.resume(); process.stdin.setEncoding('utf8'); let data = ''; process.stdin.on('data', (chunk) => { data += chunk.toString(); }); process.stdin.on('end', () => { try { if (/^\s*{/.exec(data)) { // Appears to be JSON handler(JSON.parse(data)); } else { // Assume it's YAML js_yaml_1.default.loadAll(data, handler); } resolve(); } catch (e) { reject(e); } }); }); } /** * Processes a definition and adds to the current definitions or * applies overrides to the matching definition */ processConfiguration(definitions, nodeMap, configuration) { let match; if ((0, configuration_1.isOverride)(configuration) || (0, configuration_1.isIndex)(configuration)) { match = definitions.find((p) => (0, configuration_1.isSameIndex)(p, configuration)); } if (configuration.type === undefined) { configuration.type = configuration_1.ConfigurationType.Index; } this.validateConfiguration(configuration, match); if ((0, configuration_1.isNodeMap)(configuration)) { if (configuration.map && (0, lodash_1.isObjectLike)(configuration.map)) { nodeMap.merge(configuration.map); } else { throw new Error('Invalid nodeMap'); } } else if ((0, configuration_1.isOverride)(configuration)) { // Override definition if (match) { match.applyOverride(configuration); } else { // Ignore overrides with no matching index this.logger.warn(chalk_1.default.yellowBright(`No index definition found '${configuration.name}'`)); } } else if ((0, configuration_1.isIndex)(configuration)) { // Regular index definition if (match) { throw new Error(`Duplicate index definition '${configuration.name}'`); } definitions.push(new index_definition_1.IndexDefinition(configuration)); } else { throw new Error(`Unknown definition type '${configuration.type}'`); } } /** * Validates a definition based on its type, throwing an exception * if there is a problem. */ validateConfiguration(configuration, match) { let effectiveType = configuration.type; if (effectiveType === configuration_1.ConfigurationType.Override && match) { // Use validators based on the type of definition being overriden if (match instanceof index_definition_1.IndexDefinition) { effectiveType = configuration_1.ConfigurationType.Index; } } switch (effectiveType) { case configuration_1.ConfigurationType.Index: validateConfiguration(configuration_1.IndexValidators, configuration); break; case configuration_1.ConfigurationType.NodeMap: validateConfiguration(configuration_1.NodeMapValidators, configuration); break; } } } exports.DefinitionLoader = DefinitionLoader; //# sourceMappingURL=definition-loader.js.map