UNPKG

sourcecontrol

Version:

A modern TypeScript CLI application for source control

151 lines 5.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigParser = void 0; const config_level_1 = require("./config-level"); class ConfigParser { static parse(content, source, level) { const result = new Map(); if (!content.trim()) return result; try { const configData = JSON.parse(content); this.parseSection(configData, result, source, level); } catch (error) { throw new Error(`Invalid JSON in configuration file ${source}: ${error.message}`); } return result; } static serialize(entries) { const configData = {}; entries.forEach((entryList, fullKey) => { entryList.forEach((entry) => this.setNestedValue(configData, fullKey, entry.value)); }); return JSON.stringify(configData, null, 2); } static validate(content) { const errors = []; try { const parsed = JSON.parse(content); if (typeof parsed !== 'object' || parsed === null) { errors.push('Configuration must be a JSON object'); } this.validateSection(parsed, '', errors); } catch (error) { errors.push(`Invalid JSON: ${error.message}`); } return { valid: errors.length === 0, errors }; } static formatForDisplay(entries) { const configData = {}; entries.forEach((entryList, fullKey) => { const effectiveEntry = entryList[entryList.length - 1]; if (effectiveEntry) this.setNestedValue(configData, fullKey, effectiveEntry.value); }); return JSON.stringify(configData, null, 2); } static parseSection(configData, result, source, level, keyPrefix = '') { Object.entries(configData).forEach(([sectionKey, sectionValue]) => { const fullKey = this.buildFullKey(keyPrefix, sectionKey); this.processConfigValue(fullKey, sectionValue, result, source, level); }); } static buildFullKey(prefix, key) { return prefix ? `${prefix}.${key}` : key; } static processConfigValue(key, value, result, source, level) { if (Array.isArray(value)) { this.processArrayValue(key, value, result, source, level); } else if (this.isNestedObject(value)) { this.parseSection(value, result, source, level, key); } else if (typeof value === 'string') { this.addEntry(result, key, value, source, level); } } static processArrayValue(key, values, result, source, level) { values.forEach((item) => { if (typeof item === 'string') { this.addEntry(result, key, item, source, level); } }); } static isNestedObject(value) { return typeof value === 'object' && value !== null && !Array.isArray(value); } static addEntry(entryMap, configKey, configValue, source, level) { this.ensureKeyExists(entryMap, configKey); const configEntry = this.createConfigEntry(configKey, configValue, level, source); entryMap.get(configKey).push(configEntry); } static ensureKeyExists(entryMap, key) { if (!entryMap.has(key)) { entryMap.set(key, []); } } static createConfigEntry(key, value, level, source) { const DEFAULT_LINE_NUMBER = 0; return new config_level_1.ConfigEntry(key, value, level, source, DEFAULT_LINE_NUMBER); } static setNestedValue(configObject, keyPath, value) { const pathSegments = keyPath.split('.'); const finalKey = pathSegments.pop(); const targetObject = this.navigateToTargetObject(configObject, pathSegments); this.setValueInObject(targetObject, finalKey, value); } static navigateToTargetObject(rootObject, pathSegments) { let currentObject = rootObject; for (const segment of pathSegments) { if (!this.hasValidObjectProperty(currentObject, segment)) { currentObject[segment] = {}; } currentObject = currentObject[segment]; } return currentObject; } static hasValidObjectProperty(obj, propertyKey) { return propertyKey in obj && typeof obj[propertyKey] === 'object' && !Array.isArray(obj[propertyKey]); } static setValueInObject(targetObject, key, newValue) { if (key in targetObject) { const existingValue = targetObject[key]; targetObject[key] = Array.isArray(existingValue) ? [...existingValue, newValue] : [existingValue, newValue]; } else { targetObject[key] = newValue; } } static validateSection(configSection, currentPath, errors) { Object.entries(configSection).forEach(([key, value]) => { const valuePath = this.buildFullKey(currentPath, key); this.validateConfigValue(valuePath, value, errors); }); } static validateConfigValue(path, value, errors) { if (Array.isArray(value)) { this.validateArrayValue(path, value, errors); } else if (this.isNestedObject(value)) { this.validateSection(value, path, errors); } else if (typeof value !== 'string') { errors.push(`Configuration value at '${path}' must be a string`); } } static validateArrayValue(path, values, errors) { values.forEach((item) => { if (typeof item !== 'string') { errors.push(`Configuration array at '${path}' must contain only strings`); } }); } } exports.ConfigParser = ConfigParser; //# sourceMappingURL=config-parser.js.map