@sqb/migrator
Version:
Database migrator for SQB
160 lines (159 loc) • 7.43 kB
JavaScript
;
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;
}