morpheus4j
Version:
Morpheus is a migration tool for Neo4j. It aims to be a simple and intuitive way to migrate your database.
116 lines • 4.93 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateService = void 0;
const fs_extra_1 = require("fs-extra");
const node_path_1 = __importDefault(require("node:path"));
const slugify_1 = __importDefault(require("slugify"));
const constants_1 = require("../constants");
const errors_1 = require("../errors");
const logger_1 = require("./logger");
class CreateService {
config;
migrationTemplate = 'CREATE (agent:`007`) RETURN agent;';
constructor(config) {
this.config = config;
}
async generateMigration(fileName) {
try {
this.validateFileName(fileName);
const safeFileName = this.sanitizeFileName(fileName);
const migrationsPath = this.getMigrationsPath();
await this.createMigrationsFolder();
const newVersion = await this.generateMigrationVersion();
const fileNameWithPrefix = `V${newVersion}__${safeFileName}.cypher`;
const filePath = node_path_1.default.join(migrationsPath, fileNameWithPrefix);
await this.createMigrationFile(filePath, this.migrationTemplate);
logger_1.Logger.info(`Migration file created: ${filePath}`);
}
catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error occurred';
throw new errors_1.MigrationError(`Failed to generate migration: ${message}`);
}
}
compareVersions(v1, v2) {
return v1.localeCompare(v2, undefined, {
numeric: true,
sensitivity: 'base',
});
}
async createMigrationFile(filePath, content) {
try {
await (0, fs_extra_1.writeFile)(filePath, content.trim() + '\n');
}
catch (error) {
throw new errors_1.MigrationError(`Failed to write migration file: ${error}`);
}
}
async createMigrationsFolder() {
try {
const migrationsPath = this.getMigrationsPath();
await (0, fs_extra_1.ensureDir)(migrationsPath);
}
catch (error) {
throw new errors_1.MigrationError(`Failed to create migrations folder: ${error}`);
}
}
async generateMigrationVersion() {
const fileNames = await this.getFileNamesFromMigrationsFolder();
let latestVersion = constants_1.STARTING_VERSION;
for (const fileName of fileNames) {
const version = this.getMigrationVersionFromFileName(fileName);
if (this.compareVersions(version, latestVersion) > 0) {
latestVersion = version;
}
}
const [major] = latestVersion.split('.').map(Number);
return `${major + 1}_0_0`;
}
async getFileNamesFromMigrationsFolder() {
try {
const migrationsPath = this.getMigrationsPath();
await this.createMigrationsFolder();
const files = await (0, fs_extra_1.readdir)(migrationsPath, { withFileTypes: true });
return files
.filter((file) => file.isFile() && this.isValidMigrationFile(file.name))
.map((file) => file.name)
.sort();
}
catch (error) {
throw new errors_1.MigrationError(`Failed to read migrations folder: ${error}`);
}
}
getMigrationsPath() {
const basePath = this.config.migrationsPath ?? constants_1.DEFAULT_MIGRATIONS_PATH;
return node_path_1.default.resolve(process.cwd(), basePath);
}
getMigrationVersionFromFileName(fileName) {
const result = fileName.match(constants_1.MIGRATION_NAME_REGEX);
if (!result?.groups?.version) {
throw new errors_1.MigrationError(`Invalid or missing version in migration file name: ${fileName}`);
}
return result.groups.version.replaceAll('_', '.');
}
isValidMigrationFile(fileName) {
const extension = node_path_1.default.extname(fileName).toLowerCase();
return constants_1.VALID_FILE_EXTENSIONS.includes(extension) && constants_1.MIGRATION_NAME_REGEX.test(fileName);
}
sanitizeFileName(fileName) {
return (0, slugify_1.default)(fileName, { lower: false });
}
validateFileName(fileName) {
if (!fileName || fileName.trim().length === 0) {
throw new errors_1.MigrationError('Migration file name cannot be empty');
}
if (fileName.length > 100) {
throw new errors_1.MigrationError('Migration file name is too long (max 100 characters)');
}
if (/["*/:<>?\\|]/.test(fileName)) {
throw new errors_1.MigrationError('Migration file name contains invalid characters');
}
}
}
exports.CreateService = CreateService;
//# sourceMappingURL=create.service.js.map