UNPKG

@deepbrainspace/nx-surrealdb

Version:

NX plugin for SurrealDB migrations with modular architecture

155 lines (153 loc) 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.migrationGenerator = migrationGenerator; const devkit_1 = require("@nx/devkit"); const migration_file_processor_1 = require("../../lib/filesystem/migration-file-processor"); const tree_utils_1 = require("../../lib/filesystem/tree-utils"); function generateUpMigration(options, moduleInfo) { return `-- Migration: ${options.name} -- Module: ${moduleInfo.moduleId} -- Number: ${moduleInfo.nextMigrationNumber} -- Created at: ${new Date().toISOString()} -- Add your up migration SQL here -- Example: -- DEFINE TABLE example SCHEMAFULL; -- DEFINE FIELD name ON example TYPE string; `; } function generateDownMigration(options, moduleInfo) { return `-- Migration: ${options.name} -- Module: ${moduleInfo.moduleId} -- Number: ${moduleInfo.nextMigrationNumber} -- Created at: ${new Date().toISOString()} -- Add your down migration SQL here -- Example: -- REMOVE TABLE example; `; } async function resolveModuleInfo(tree, migrationsPath, modulePattern, createModule) { // Check if we have a specific module pattern if (modulePattern) { // Try to find existing module const existingModule = await findExistingModule(tree, migrationsPath, String(modulePattern)); if (existingModule) { const nextNumber = getNextMigrationNumberFromTree(tree, existingModule.modulePath); return { moduleId: existingModule.moduleId, modulePath: existingModule.modulePath, nextMigrationNumber: nextNumber, }; } // Module doesn't exist if (createModule) { return await createNewModule(tree, migrationsPath, String(modulePattern)); } else { throw new Error(`Module '${modulePattern}' not found. Use --createModule to create it.`); } } // No module specified - find the highest numbered existing module const existingModules = await discoverExistingModules(tree, migrationsPath); if (existingModules.length === 0) { // No modules exist, create first one return await createNewModule(tree, migrationsPath, '000_admin'); } // Use the highest numbered module const lastModule = existingModules[existingModules.length - 1]; const nextNumber = getNextMigrationNumberFromTree(tree, lastModule.modulePath); return { moduleId: lastModule.moduleId, modulePath: lastModule.modulePath, nextMigrationNumber: nextNumber, }; } function getNextMigrationNumberFromTree(tree, modulePath) { return tree_utils_1.TreeUtils.getNextMigrationNumber(tree, modulePath); } async function findExistingModule(tree, migrationsPath, pattern) { const modules = await discoverExistingModules(tree, migrationsPath); const normalizedPattern = pattern.trim().toLowerCase(); const patternAsNumber = parseInt(normalizedPattern, 10); const normalizedPatternNumber = isNaN(patternAsNumber) ? null : patternAsNumber.toString(); for (const module of modules) { const match = module.moduleId.match(/^(\d{1,4})_(.+)$/); if (!match) continue; const [, number, name] = match; const normalizedNumber = parseInt(number, 10).toString(); if (module.moduleId.toLowerCase() === normalizedPattern || (normalizedPatternNumber !== null && normalizedPatternNumber === normalizedNumber) || normalizedPattern === name.toLowerCase() || normalizedPattern === `${normalizedNumber}_${name.toLowerCase()}` || normalizedPattern === `${number}_${name.toLowerCase()}`) { return module; } } return null; } async function discoverExistingModules(tree, migrationsPath) { return tree_utils_1.TreeUtils.findModuleDirectories(tree, migrationsPath).map(({ name, path }) => ({ moduleId: name, modulePath: path, })); } async function createNewModule(tree, migrationsPath, pattern) { // Parse the pattern to determine module ID let moduleId; if (/^\d{1,4}_/.test(pattern)) { // Already in XXX_name format moduleId = pattern; } else { // Need to determine next available number const existingModules = await discoverExistingModules(tree, migrationsPath); const cleanName = pattern.replace(/^\d+_?/, '').toLowerCase(); moduleId = migration_file_processor_1.MigrationFileProcessor.generateModuleId(cleanName, existingModules); } const modulePath = (0, devkit_1.joinPathFragments)(migrationsPath, moduleId); // Create the module directory tree_utils_1.TreeUtils.ensureDirectory(tree, modulePath); return { moduleId, modulePath, nextMigrationNumber: '0001', }; } async function migrationGenerator(tree, options) { const normalizedOptions = { ...options, name: options.name || options.positionalArgs?.[0] || '', project: options.project, migrationsDir: options.migrationsDir || 'migrations', module: options.module, createModule: options.createModule || false, }; if (!normalizedOptions.name) { throw new Error('The "name" property is required.'); } // Normalize migration name (replace spaces and special chars with underscores) const migrationName = normalizedOptions.name .toLowerCase() .replace(/[^a-z0-9_]/g, '_') .replace(/_{2,}/g, '_') .replace(/^_|_$/g, ''); const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, normalizedOptions.project); const projectRoot = projectConfig.root; const migrationsPath = (0, devkit_1.joinPathFragments)(projectRoot, normalizedOptions.migrationsDir); // Resolve module information const moduleInfo = await resolveModuleInfo(tree, migrationsPath, normalizedOptions.module, normalizedOptions.createModule); // Generate file names with sequential numbering const upFileName = `${moduleInfo.nextMigrationNumber}_${migrationName}_up.surql`; const downFileName = `${moduleInfo.nextMigrationNumber}_${migrationName}_down.surql`; // Create up migration const upContent = generateUpMigration(normalizedOptions, moduleInfo); tree.write((0, devkit_1.joinPathFragments)(moduleInfo.modulePath, upFileName), upContent); // Create down migration const downContent = generateDownMigration(normalizedOptions, moduleInfo); tree.write((0, devkit_1.joinPathFragments)(moduleInfo.modulePath, downFileName), downContent); // console.log(`Generated migration files:`); // console.log(` Up: ${moduleInfo.moduleId}/${upFileName}`); // console.log(` Down: ${moduleInfo.moduleId}/${downFileName}`); await (0, devkit_1.formatFiles)(tree); } //# sourceMappingURL=generator.js.map