bs3m
Version:
TS/JS migrations framework for sqlite3 databases
111 lines • 4.62 kB
JavaScript
/** Migration module parsing and validation utilities. */
import { MigrationModuleParseError } from './errors.js';
/**
* Validates a migration module loaded from dynamic import.
*
* @param module - The module object loaded from dynamic import.
* @param migrationId - The migration ID for error context.
* @returns The validated migration object.
* @throws {@link MigrationModuleParseError} When validation fails.
*/
export function validateMigrationModule(module, migrationId) {
// Check if module is an object
if (!isObject(module)) {
throw new MigrationModuleParseError(migrationId, 'Module must be an object');
}
// Check if module has a default export
if (!('default' in module)) {
throw new MigrationModuleParseError(migrationId, 'Module must have a default export');
}
const migration = module.default;
// Check if default export is an object
if (!isObject(migration)) {
throw new MigrationModuleParseError(migrationId, 'Default export must be an object');
}
// Validate required properties
validateRequiredProperties(migration, migrationId);
// Validate optional properties
validateOptionalProperties(migration, migrationId);
return migration;
}
/**
* Validates required migration properties.
*
* @param migration - The migration object to validate.
* @param migrationId - The migration ID for error context.
*/
function validateRequiredProperties(migration, migrationId) {
// Validate dbs property
if (!('dbs' in migration)) {
throw new MigrationModuleParseError(migrationId, 'Missing required property: dbs');
}
if (!Array.isArray(migration.dbs)) {
throw new MigrationModuleParseError(migrationId, 'Property "dbs" must be an array');
}
if (migration.dbs.length === 0) {
throw new MigrationModuleParseError(migrationId, 'Property "dbs" must not be empty');
}
if (!migration.dbs.every((db) => typeof db === 'string')) {
throw new MigrationModuleParseError(migrationId, 'Property "dbs" must be an array of strings');
}
// Validate description property
if (!('description' in migration)) {
throw new MigrationModuleParseError(migrationId, 'Missing required property: description');
}
if (typeof migration.description !== 'string') {
throw new MigrationModuleParseError(migrationId, 'Property "description" must be a string');
}
// Validate up function
if (!('up' in migration)) {
throw new MigrationModuleParseError(migrationId, 'Missing required property: up');
}
if (typeof migration.up !== 'function') {
throw new MigrationModuleParseError(migrationId, 'Property "up" must be a function');
}
// Validate down function
if (!('down' in migration)) {
throw new MigrationModuleParseError(migrationId, 'Missing required property: down');
}
if (typeof migration.down !== 'function') {
throw new MigrationModuleParseError(migrationId, 'Property "down" must be a function');
}
}
/**
* Validates optional migration properties.
*
* @param migration - The migration object to validate.
* @param migrationId - The migration ID for error context.
*/
function validateOptionalProperties(migration, migrationId) {
// Validate mode property if present
if ('mode' in migration && migration.mode !== undefined) {
if (typeof migration.mode !== 'string') {
throw new MigrationModuleParseError(migrationId, 'Property "mode" must be a string');
}
if (migration.mode !== 'connections' && migration.mode !== 'attach') {
throw new MigrationModuleParseError(migrationId, 'Property "mode" must be "connections" or "attach"');
}
}
// Validate test function if present
if ('test' in migration && migration.test !== undefined) {
if (typeof migration.test !== 'function') {
throw new MigrationModuleParseError(migrationId, 'Property "test" must be a function');
}
}
// Validate metadata property if present
if ('metadata' in migration && migration.metadata !== undefined) {
if (!isObject(migration.metadata)) {
throw new MigrationModuleParseError(migrationId, 'Property "metadata" must be an object');
}
}
}
/**
* Type guard to check if a value is an object.
*
* @param value - The value to check.
* @returns True if the value is an object, false otherwise.
*/
function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
//# sourceMappingURL=migration_parser.js.map