UNPKG

@magic-mustard/sqlsync

Version:

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

117 lines (116 loc) 5.28 kB
"use strict"; 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.SchemaFileLoader = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const logger_1 = require("../utils/logger"); /** * FileLoader is responsible for loading and validating files based on the Schema configuration. * It ensures that mandatory files and folders specified in the 'order' attribute exist, * and prepares an ordered structure for SchemaFiles to process. */ class SchemaFileLoader { constructor(schema, basePath = process.cwd()) { this.schema = schema; // Remove trailing slash if present let normalizedBase = basePath.replace(/[\\/]+$/, ''); const lastPart = path.basename(normalizedBase); if (lastPart !== SchemaFileLoader.SCHEMA_DIR) { normalizedBase = path.join(normalizedBase, SchemaFileLoader.SCHEMA_DIR); } this.schemaBasePath = path.normalize(normalizedBase); } /** * Loads and validates the schema configuration, returning an ordered structure of files and folders. * @returns An object representing the ordered structure of files and folders. * @throws Error if mandatory files or folders are missing. */ loadSchema() { const schemaStructure = {}; // Explicitly handle the top-level 'schema' key and its order array if (this.schema && 'order' in this.schema && Array.isArray(this.schema.order)) { schemaStructure['schema'] = { order: this.validateAndResolveOrder('schema', this.schema.order, this.schemaBasePath), orderedSubdirectoryFileOrder: [] }; } // Process each top-level key in schema (e.g., roles, tables, seeds) for (const [key, value] of Object.entries(this.schema)) { if (value && typeof value === 'object' && 'order' in value && Array.isArray(value.order)) { schemaStructure[key] = { order: this.validateAndResolveOrder(key, value.order, this.schemaBasePath), orderedSubdirectoryFileOrder: value.orderedSubdirectoryFileOrder || [], }; } else { schemaStructure[key] = value; } } return schemaStructure; } /** * Validates the existence of files and folders in the specified order array. * @param category The parent key in the schema for error messaging. * @param orderArray Array of file or folder names to validate. * @param basePath The base path to resolve the files and folders. * @returns Array of resolved paths for the ordered items. * @throws Error if a mandatory file or folder is missing or if a file does not end with .sql. */ validateAndResolveOrder(category, orderArray, basePath) { return orderArray.map((item) => { const resolvedPath = category === SchemaFileLoader.SCHEMA_DIR ? path.resolve(basePath, item) : path.resolve(basePath, category, item); if (!fs.existsSync(resolvedPath)) { const errorMessage = `Missing mandatory file or folder '${item}' in '${category}' (expected at: ${resolvedPath})`; logger_1.logger.error(errorMessage); throw new Error(errorMessage); } const stat = fs.statSync(resolvedPath); if (stat.isFile() && !item.endsWith('.sql')) { const errorMessage = `Invalid file type in '${category}': '${item}' must be a .sql file (found at: ${resolvedPath})`; logger_1.logger.error(errorMessage); throw new Error(errorMessage); } return resolvedPath; }); } } exports.SchemaFileLoader = SchemaFileLoader; SchemaFileLoader.SCHEMA_DIR = 'schema';