UNPKG

@sqb/migrator

Version:

Database migrator for SQB

160 lines (159 loc) 7.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MigrationPackage = void 0; exports.isSqlScriptMigrationTask = isSqlScriptMigrationTask; exports.isInsertDataMigrationTask = isInsertDataMigrationTask; exports.isCustomMigrationTask = isCustomMigrationTask; const tslib_1 = require("tslib"); const fast_glob_1 = tslib_1.__importDefault(require("fast-glob")); const promises_1 = tslib_1.__importDefault(require("fs/promises")); const path_1 = tslib_1.__importDefault(require("path")); const get_calling_filename_js_1 = require("./utils/get-calling-filename.js"); function isSqlScriptMigrationTask(x) { return (typeof x === 'object' && (typeof x.script === 'string' || typeof x.script === 'function')); } function isInsertDataMigrationTask(x) { return (typeof x === 'object' && typeof x.tableName === 'string' && Array.isArray(x.rows)); } function isCustomMigrationTask(x) { return typeof x === 'object' && typeof x.fn === 'function'; } var MigrationPackage; (function (MigrationPackage) { async function load(asyncConfig) { const baseDir = asyncConfig.baseDir || path_1.default.dirname((0, get_calling_filename_js_1.getCallingFilename)(1)); const out = { ...asyncConfig, baseDir, migrations: [], }; if (!Array.isArray(asyncConfig.migrations)) { throw new TypeError('You must provide array of MigrationConfig in "migrations" property'); } if (asyncConfig.migrations?.length) { const srcMigrations = []; const trgMigrations = []; out.migrations = trgMigrations; let x; for (x of asyncConfig.migrations) { x = typeof x === 'function' ? await x() : x; if (typeof x === 'object' && x.tasks) srcMigrations.push(x); else if (typeof x === 'string') { srcMigrations.push(...(await loadMigrations(baseDir, x.replace(/\\/g, '/')))); } } srcMigrations.sort((a, b) => a.version - b.version); for (const migration of srcMigrations) { const trgMigration = { baseDir: '', ...migration, tasks: [], }; trgMigrations.push(trgMigration); const srcTasks = migration.tasks; trgMigration.tasks = []; for (const t of srcTasks) { if (typeof t === 'object') { trgMigration.tasks.push(t); } else if (typeof t === 'string') { let pattern = t.replace(/\\/g, '/'); pattern = path_1.default.resolve(path_1.default.join(baseDir, trgMigration.baseDir, pattern)); const files = await (0, fast_glob_1.default)(pattern, { absolute: true, onlyFiles: true, }); files.sort(); for (const filename of files) { const ext = path_1.default.extname(filename).toLowerCase(); if (!path_1.default.basename(filename, ext).endsWith('.task')) continue; if (ext === '.sql') { const script = await promises_1.default.readFile(filename, 'utf-8'); trgMigration.tasks.push({ title: path_1.default.basename(filename, ext), filename, script, }); } else if (['.json', '.js', '.ts', '.cjs', '.mjs'].includes(ext)) { try { let json = ext === '.json' ? JSON.parse(await promises_1.default.readFile(filename, 'utf-8')) : await Promise.resolve(`${filename}`).then(s => tslib_1.__importStar(require(s))); if (typeof json !== 'object') continue; if (json.__esModule) json = json.default; if (json.script) { json.title = json.title || 'Run sql script'; json.filename = filename; trgMigration.tasks.push(json); continue; } if (json.tableName && json.rows) { json.title = json.title || 'Migrate data into ' + json.tableName; json.filename = filename; trgMigration.tasks.push(json); continue; } if (typeof json.fn === 'function') { json.title = json.title || 'Run custom function'; json.filename = filename; trgMigration.tasks.push(json); } } catch (e) { e.message = `Error in ${filename}\n` + e.message; throw e; } } } } } } } return out; } MigrationPackage.load = load; })(MigrationPackage || (exports.MigrationPackage = MigrationPackage = {})); async function loadMigrations(baseDir, pattern) { const out = []; const files = await (0, fast_glob_1.default)(path_1.default.join(baseDir, pattern), { absolute: true, onlyFiles: true, }); for (const filename of files) { const ext = path_1.default.extname(filename).toLowerCase(); if (path_1.default.basename(filename, ext) !== 'migration') continue; let json; if (['.js', '.ts', '.cjs', '.mjs', 'mts', 'cts'].includes(ext)) { json = await Promise.resolve(`${filename}`).then(s => tslib_1.__importStar(require(s))); if (json.default?.version) json = json.default; } else if (ext === '.json') { try { json = JSON.parse(await promises_1.default.readFile(filename, 'utf-8')); } catch (e) { e.message = `Error in ${filename}\n` + e.message; throw e; } } if (json && typeof json === 'object' && json.version && Array.isArray(json.tasks)) { json.baseDir = path_1.default.relative(baseDir, path_1.default.dirname(filename)); out.push(json); } } return out; }