UNPKG

@magic-mustard/sqlsync

Version:

SQLSync simplifies database schema evolution by allowing a declarative approach to table management

146 lines (145 loc) 6.85 kB
"use strict"; // config/index.ts var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = void 0; /** * ConfigLoader class for loading and validating sqlsync.yaml configuration files. */ const fs = __importStar(require("fs")); const path = __importStar(require("path")); const yaml = __importStar(require("js-yaml")); const logger_1 = require("../utils/logger"); /** * Default configuration filename. */ const DefaultConfigFilename = 'sqlsync.yaml'; /** * ConfigLoader implements the ConfigLoader interface from CLI types, * providing functionality to load and validate configuration from a yaml file. */ class Config { /** * Loads the configuration from the specified path or defaults to sqlsync.yaml in the current directory. * @param configPath Path to the configuration file. If not provided, defaults to sqlsync.yaml in the current directory. * @returns The parsed and validated SqlSyncConfig object. * @throws Error if the file is not found, cannot be parsed, or is invalid. */ load(configPath = path.join(process.cwd(), DefaultConfigFilename)) { console.log(`[DEBUG config/index.ts] loadConfig received raw configPath: ${configPath}`); const absoluteConfigPath = path.resolve(configPath); console.log(`Loading config from: ${absoluteConfigPath}`); if (!fs.existsSync(absoluteConfigPath)) { throw new Error(`Configuration file not found at ${absoluteConfigPath}`); } const fileContents = fs.readFileSync(absoluteConfigPath, 'utf8'); let parsedConfig; try { parsedConfig = yaml.load(fileContents); } catch (e) { throw new Error(`Error parsing YAML file ${absoluteConfigPath}: ${e.message}`); } if (!parsedConfig || typeof parsedConfig !== 'object') { throw new Error(`Invalid configuration format in ${absoluteConfigPath}: Expected an object.`); } // Perform validation this.validateConfig(parsedConfig, absoluteConfigPath); // Log success message in green logger_1.logger.success(`Configuration successfully loaded from ${absoluteConfigPath}`); return parsedConfig; } /** * Returns the absolute directory containing the loaded config file. */ static getConfigRoot(configPath = path.join(process.cwd(), DefaultConfigFilename)) { return path.dirname(path.resolve(configPath)); } /** * Validates the configuration object to ensure it meets the required structure and types. * @param config The configuration object to validate. * @param configPath The path to the configuration file (for error messages). * @throws Error if the configuration is invalid. */ validateConfig(config, configPath) { // Validate top-level config object if (!config.config || typeof config.config !== 'object') { throw new Error(`Invalid configuration in ${configPath}: "config" object is required.`); } // Validate config.migrations if (!config.config.migrations || typeof config.config.migrations !== 'object') { throw new Error(`Invalid configuration in ${configPath}: "config.migrations" object is required.`); } if (!config.config.migrations.outputDir) { throw new Error(`Invalid configuration in ${configPath}: "config.migrations.outputDir" is required.`); } if (typeof config.config.migrations.outputDir !== 'string') { throw new Error(`Invalid configuration in ${configPath}: "config.migrations.outputDir" should be a string.`); } if (config.config.migrations.maxRollbacks !== undefined && typeof config.config.migrations.maxRollbacks !== 'number') { throw new Error(`Invalid configuration in ${configPath}: "config.migrations.maxRollbacks" should be a number.`); } // Validate schema if (!config.schema || typeof config.schema !== 'object') { throw new Error(`Invalid configuration in ${configPath}: "schema" object is required.`); } } /** * Validates a folder configuration to ensure it meets the required structure and does not contain nested folders. * @param folderConfig The folder configuration to validate. * @param folderPath The path to the folder in the configuration (for error messages). * @param configPath The path to the configuration file (for error messages). * @throws Error if the folder configuration is invalid. */ validateFolderConfig(folderConfig, folderPath, configPath) { if (typeof folderConfig !== 'object') { throw new Error(`Invalid configuration in ${configPath}: "${folderPath}" should be an object.`); } if (folderConfig.order) { if (!Array.isArray(folderConfig.order)) { throw new Error(`Invalid configuration in ${configPath}: "${folderPath}.order" should be an array.`); } if (!folderConfig.order.every((item) => typeof item === 'string')) { throw new Error(`Invalid configuration in ${configPath}: All elements in "${folderPath}.order" should be strings.`); } } if (folderConfig.folders) { throw new Error(`Invalid configuration in ${configPath}: Nested folders are not allowed in "${folderPath}".`); } } } exports.Config = Config;