@noego/proper 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +11 -3
- package/bin/cli.js.map +1 -1
- package/bin/cli.mjs +11 -3
- package/bin/cli.mjs.map +1 -1
- package/bin/index.js +11 -3
- package/bin/index.js.map +1 -1
- package/bin/index.mjs +11 -9
- package/bin/index.mjs.map +1 -1
- package/lib/runner.d.mts +5 -0
- package/lib/runner.d.ts +5 -0
- package/lib/runner.js +11 -0
- package/lib/runner.js.map +1 -1
- package/lib/runner.mjs +11 -0
- package/lib/runner.mjs.map +1 -1
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -721,6 +721,9 @@ var SQLiteRunner = class extends BaseSQLRunner {
|
|
|
721
721
|
}
|
|
722
722
|
_execute(_0) {
|
|
723
723
|
return __async(this, arguments, function* (sql, params = []) {
|
|
724
|
+
if (this.isEmptySQL(sql)) {
|
|
725
|
+
return { changes: 0, lastID: 0 };
|
|
726
|
+
}
|
|
724
727
|
if (this.isMultiStatement(sql)) {
|
|
725
728
|
return yield this.executeMultiStatement(sql, params).catch((err) => {
|
|
726
729
|
console.error(`Error executing multi-statement SQL:
|
|
@@ -738,6 +741,14 @@ ${sql}
|
|
|
738
741
|
}
|
|
739
742
|
});
|
|
740
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* Checks if SQL is empty or contains only comments/whitespace.
|
|
746
|
+
* Returns true if there is no actual SQL to execute.
|
|
747
|
+
*/
|
|
748
|
+
isEmptySQL(sql) {
|
|
749
|
+
const withoutComments = sql.replace(/--.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").trim();
|
|
750
|
+
return withoutComments.length === 0;
|
|
751
|
+
}
|
|
741
752
|
isMultiStatement(sql) {
|
|
742
753
|
return sql.split(";").length > 1;
|
|
743
754
|
}
|
|
@@ -1274,9 +1285,6 @@ function runSqlSeed(runner, resolved, direction) {
|
|
|
1274
1285
|
function loadSeedModule(modulePath) {
|
|
1275
1286
|
return __async(this, null, function* () {
|
|
1276
1287
|
const resolved = import_path2.default.resolve(modulePath);
|
|
1277
|
-
if (resolved.endsWith(".ts")) {
|
|
1278
|
-
return require(resolved);
|
|
1279
|
-
}
|
|
1280
1288
|
return import(resolved);
|
|
1281
1289
|
});
|
|
1282
1290
|
}
|
package/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli.ts","../framework/MigrationCLi.ts","../framework/MigrationFilter.ts","../framework/MigrationRunner.ts","../framework/MigrationDirectoryReader.ts","../framework/errors.ts","../framework/MigrationNode.ts","../framework/SqlMigrationBuilder.ts","../framework/MigrationSetup.ts","../framework/MigrationDialectParser.ts","../framework/SQLRunner.ts","../framework/SeedRunner.ts"],"sourcesContent":["#!/usr/bin/env node\nimport 'source-map-support/register';\nimport 'tsx/cjs';\n\nimport { MigrationCLIFactory } from \"./framework/MigrationCLi\";\nimport { migration_filter } from \"./framework/MigrationFilter\";\nimport { MigrationRunnerFactory, FileMigrationConfigReader } from \"./framework/MigrationRunner\";\nimport { CLIError } from \"./framework/errors\";\nimport { runSeedsWithRunner, SeedOptions } from \"./framework/SeedRunner\";\n\nconst args = MigrationCLIFactory.setup(process.argv);\n\n// Validate that at least one command is provided\nif (!args.commands || args.commands.length === 0) {\n console.error(\"Error: No command specified\");\n printUsage();\n process.exit(1);\n}\n\nconst commands = args.commands;\nconst command = commands[0];\nconst load_database = ![\"init\", 'create', 'help'].includes(command.toLowerCase());\nconst config_file = args.flags.config || \"proper.json\";\n\n// Handle help command\nif (command.toLowerCase() === 'help') {\n printUsage();\n process.exit(0);\n}\n\nconsole.log(`Loading database: ${load_database}`);\n\nconst pending_runner = load_database ?\n MigrationRunnerFactory.create(config_file) :\n MigrationRunnerFactory.createEmpty(config_file);\n\npending_runner.then(async runner => {\n try {\n if (load_database) {\n await runner.setup();\n }\n\n switch (command.toLowerCase()) {\n case \"up\":\n const migrations_forward = await runner.getMigrations();\n let upgraded = await migration_filter(migrations_forward, false);\n\n if (args.flags.increment) {\n const increment = parseInt(args.flags.increment);\n upgraded = upgraded.slice(0, increment);\n }\n\n console.log(`Applying ${upgraded.length} migration(s)`);\n\n if (upgraded.length > 0) {\n for (const migration of upgraded) {\n console.log(` - ${migration.name}`);\n }\n\n await runner.migrate(upgraded, true);\n console.log(\"Migration completed successfully\");\n } else {\n console.log(\"No pending migrations\");\n }\n await runner.close();\n break;\n\n case \"down\":\n const migrations_rollback = await runner.getMigrations();\n let downgraded = await migration_filter(migrations_rollback, true);\n\n downgraded = downgraded.reverse();\n\n if (args.flags.all) {\n // Roll back all migrations - use the full list\n } else {\n // Default to 1 migration if no increment specified\n const increment = parseInt(args.flags.increment || '1');\n downgraded = downgraded.slice(0, increment);\n }\n\n console.log(`Rolling back ${downgraded.length} migration(s)`);\n if (downgraded.length > 0) {\n for (const migration of downgraded) {\n console.log(` - ${migration.name}`);\n }\n\n await runner.migrate(downgraded, false);\n console.log(\"Rollback completed successfully\");\n } else {\n console.log(\"No migrations to roll back\");\n }\n\n await runner.close();\n break;\n\n case \"reset\":\n console.log(\"Resetting all migrations...\");\n await runner.reset();\n console.log(\"Reset completed successfully\");\n await runner.close();\n break;\n\n case \"create\":\n let filename = args.flags.name || commands[1];\n\n if (!filename) {\n throw new CLIError(\"Migration name is required\");\n }\n\n filename = filename.replace(/\\s/g, \"_\");\n runner.createMigration(filename);\n runner.close();\n break;\n\n case \"init\":\n await runner.init(config_file);\n runner.close();\n break;\n\n case \"status\":\n const { printTable } = require('console-table-printer');\n const migrations = await runner.getMigrations();\n\n console.log(\"Migration Status:\");\n\n const table = migrations.map(async m => {\n const status = await m.status();\n return {\n key: m.get_key(),\n status: status.completed ? \"completed\" : \"pending\",\n };\n });\n\n printTable(await Promise.all(table));\n runner.close();\n break;\n\n case \"query\":\n const sql_query = args.flags.query || commands[1];\n const format = (args.flags.format || 'table').toLowerCase();\n\n if (!sql_query) {\n throw new CLIError(\"SQL query is required. Usage: proper query \\\"SELECT * FROM table\\\"\");\n }\n\n // Validate that query is a SELECT or CTE (WITH) statement\n const trimmed_query = sql_query.trim().toUpperCase();\n const is_select = trimmed_query.startsWith('SELECT');\n const is_cte = trimmed_query.startsWith('WITH');\n\n if (!is_select && !is_cte) {\n throw new CLIError(\"Only SELECT queries and CTEs (WITH clauses) are allowed\");\n }\n\n // Block dangerous keywords\n const dangerous_keywords = ['INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER', 'TRUNCATE', 'GRANT', 'REVOKE'];\n const has_dangerous_keyword = dangerous_keywords.some(keyword => {\n // Check for keyword not as part of a word (word boundaries)\n const regex = new RegExp(`\\\\b${keyword}\\\\b`, 'i');\n return regex.test(sql_query);\n });\n\n if (has_dangerous_keyword) {\n throw new CLIError(\"Query contains disallowed keywords. Only SELECT and CTE queries are permitted\");\n }\n\n if (!['table', 'json'].includes(format)) {\n throw new CLIError(\"Invalid format. Use --format table or --format json\");\n }\n\n try {\n const [results] = await runner.query(sql_query);\n\n if (Array.isArray(results) && results.length > 0) {\n if (format === 'json') {\n console.log(JSON.stringify(results, null, 2));\n } else {\n const { printTable } = require('console-table-printer');\n printTable(results);\n }\n console.log(`\\nReturned ${results.length} row(s)`);\n } else if (Array.isArray(results) && results.length === 0) {\n console.log(\"Query returned 0 rows\");\n } else {\n console.log(\"Query executed successfully\");\n }\n } catch (error: any) {\n throw new CLIError(`Query execution failed: ${error.message}`);\n }\n\n await runner.close();\n break;\n\n case \"seed\": {\n const subCommands = commands.slice(1);\n const actionFlag = (args.flags.action || \"\").toString().toLowerCase();\n const firstSub = (subCommands[0] || \"\").toString().toLowerCase();\n\n const action = (actionFlag === \"down\" || firstSub === \"down\") ? \"down\" : \"up\";\n\n const positionalNames = actionFlag\n ? subCommands\n : (firstSub === \"up\" || firstSub === \"down\")\n ? subCommands.slice(1)\n : subCommands;\n\n const aliasFlag = args.flags.alias as string | string[] | undefined;\n const aliasMap: Record<string, string> = {};\n if (aliasFlag) {\n const aliases = Array.isArray(aliasFlag) ? aliasFlag : [aliasFlag];\n for (const entry of aliases) {\n const eq = entry.indexOf(\"=\");\n if (eq > 0) {\n const key = entry.slice(0, eq);\n const value = entry.slice(eq + 1);\n if (key) aliasMap[key] = value;\n }\n }\n }\n\n const seedOptions: SeedOptions = {\n migrationsDir: args.flags.migrationsDir || args.flags[\"migrations-dir\"],\n dataDir: args.flags.dataDir || args.flags[\"data-dir\"],\n validate: args.flags.validate === undefined\n ? true\n : String(args.flags.validate).toLowerCase() !== \"false\",\n transactional: args.flags.transactional,\n aliasMap: Object.keys(aliasMap).length ? aliasMap : undefined,\n names: positionalNames.length ? positionalNames : undefined,\n log: (msg: string) => console.log(msg),\n };\n\n const reader = new FileMigrationConfigReader(config_file);\n const migrationConfig = reader.loadFile();\n\n await runSeedsWithRunner(runner as any, migrationConfig, action, seedOptions);\n await runner.close();\n break;\n }\n\n default:\n throw CLIError.unknownCommand(command);\n }\n\n } catch (error: any) {\n console.error(`Error: ${error.message}`);\n if (error.stack && process.env.DEBUG) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n});\n\nfunction printUsage() {\n console.log(`\nSQL Proper - Database migration tool\n\nUsage:\n proper <command> [options]\n\nCommands:\n up Apply pending migrations\n down Roll back completed migrations\n reset Roll back all migrations and reapply them\n create Create a new migration\n init Initialize a new config file\n status Show migration status\n query Execute a SQL query and display results\n help Show this help message\n\nOptions:\n -c, --config Specify the config file (default: proper.json)\n --increment <n> Limit the number of migrations to apply or roll back\n --all Roll back all completed migrations (down command only)\n --format <fmt> Output format for query command: 'table' (default) or 'json'\n\nExamples:\n proper up Apply all pending migrations\n proper up --increment 1 Apply only the next pending migration\n proper down Roll back the last applied migration (default: 1)\n proper down --increment 3 Roll back the last 3 applied migrations\n proper down --all Roll back all completed migrations\n proper create my_migration Create a new migration named \"my_migration\"\n proper init Create a new config file\n proper status Show the status of all migrations\n proper query \"select * from users\" Execute a SQL query\n proper query \"select * from users\" --format json Execute a query and output as JSON\n proper -c custom.json up Use a custom config file\n `);\n}\n","import minimist from \"minimist\";\n\nexport class MigrationCLIFactory {\n /**\n * Parse command line arguments into commands and flags\n * @param argv Optional array of command line arguments. If not provided, process.argv will be used.\n * @returns Object containing parsed commands and flags\n */\n static setup(argv?: string[]): { commands: string[], flags: Record<string, any> } {\n // Use provided args or default to process.argv\n const args = argv || process.argv;\n \n // Determine where to start slicing the arguments\n // We need to handle different invocation patterns:\n // 1. node script.js command => skip 'node' and 'script.js' \n // 2. ./cli.js command => skip './cli.js'\n // 3. proper command => skip 'proper' (likely a symlink to the script)\n // 4. command arg1 arg2 => don't skip anything (direct command invocation)\n let startIndex = 0;\n \n // Check for node\n if (args[0]?.includes('node')) {\n startIndex = 2; // Skip 'node' and script name\n }\n // Check for script file extensions\n else if (args[0] && /\\.(js|ts|mjs|cjs)$/i.test(args[0])) {\n startIndex = 1; // Skip just the script name\n }\n // Check for command name that might be a symlink to this script\n else if (args[0] && ['proper', 'migration', 'sql-proper'].includes(args[0].toLowerCase())) {\n startIndex = 1; // Skip the command name\n }\n \n // Parse the arguments\n const cli = minimist(args.slice(startIndex), {\n alias: {\n c: 'config',\n },\n });\n\n const { _: commands, ...flags } = cli;\n\n return {\n commands,\n flags\n };\n }\n}","import { MigrationNode } from \"./MigrationNode\";\n\n\n\n\nexport async function migration_filter(migrations:MigrationNode[],completed:boolean=true,keep:MigrationNode[]=[]){\n if(migrations.length === 0){\n return keep\n }\n\n const [first,...rest] = migrations\n\n const status = await first.status()\n\n if(status.completed == completed){\n keep.push(first)\n }\n\n return migration_filter(rest,completed,keep)\n}","// Node built-in modules\nimport fs from 'fs';\n\n// Database drivers\nimport mysql from 'mysql2/promise';\nimport * as sqlite from 'sqlite';\nimport * as sqlite3 from 'sqlite3';\n\n// Helper function to convert any error to Error object\nfunction toError(error: unknown): Error {\n if (error instanceof Error) return error;\n return new Error(String(error));\n}\n\n// Migration framework\nimport { MigrationConfig } from \"./MigrationConfig\";\nimport { MigrationDirectoryReader } from './MigrationDirectoryReader';\nimport { MigrationNode } from './MigrationNode';\nimport { MigrationSetup } from './MigrationSetup';\nimport { migration_filter } from './MigrationFilter';\nimport * as dialect from \"./MigrationDialectParser\";\n\n\nimport { ISQLRunner,SQLRunner,SQLiteRunner } from './SQLRunner';\nimport { ErrorMessage } from './ErrorMessage';\nimport { \n ConfigurationError, \n DatabaseConnectionError, \n MigrationExecutionError,\n CLIError \n} from './errors';\n\n\nexport function loadMigrationConfig(configFile: string): MigrationConfig {\n const reader = new FileMigrationConfigReader(configFile);\n return reader.loadFile();\n}\n\nexport class MigrationRunnerFactory {\n\n private static isSQLRunner(conn: any): conn is ISQLRunner {\n return !!conn\n && typeof conn.query === \"function\"\n && typeof conn.execute === \"function\"\n && typeof conn.end === \"function\";\n }\n\n static async create(configFile:string,conn?:any){\n const configReader = new FileMigrationConfigReader(configFile);\n const config = configReader.loadFile();\n\n if(!conn){\n conn = await this.createConnection(config)\n }\n return new MigrationRunnerFactory().create(config,conn)\n }\n\n static async createConnection(config:MigrationConfig){\n let conn = null as any\n switch(config.database){\n case \"sql\":\n if (!config.sql){\n throw ConfigurationError.missingDatabaseConfiguration(\"sql\");\n }\n const settings = Object.assign({\n password:process.env.SQL_PASSWORD\n },config.sql);\n try {\n conn = await mysql.createConnection(settings);\n return conn;\n } catch (error) {\n throw DatabaseConnectionError.connectionFailed(\"sql\", toError(error).message);\n }\n case \"sqlite\":\n if (!config.sqlite){\n throw ConfigurationError.missingDatabaseConfiguration(\"sqlite\");\n }\n try {\n conn = await sqlite.open({\n filename:config.sqlite.database,\n driver:sqlite3.Database\n });\n return conn;\n } catch (error) {\n throw DatabaseConnectionError.connectionFailed(\"sqlite\", toError(error).message);\n }\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n \n }\n\n static async createEmpty(configFile:string){\n const configReader = new FileMigrationConfigReader(configFile);\n const config = configReader.loadFile();\n return new MigrationRunnerFactory().createEmpty(config)\n }\n\n\n async create(config:MigrationConfig,conn:any):Promise<MySQLMigrationRunner>{\n let sqlrunner:ISQLRunner;\n let driverConnection = conn;\n\n if (MigrationRunnerFactory.isSQLRunner(conn)) {\n sqlrunner = conn;\n driverConnection = null;\n } else {\n switch(config.database){\n case \"sql\":\n sqlrunner = new SQLRunner(conn)\n break;\n case \"sqlite\":\n sqlrunner = new SQLiteRunner(conn)\n break;\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n }\n const setup = new MigrationSetup(sqlrunner,config);\n const read_strategy = this.getReadStategy(config)\n\n const migration_files = new MigrationDirectoryReader(config.migration_folder,read_strategy,sqlrunner,config.database as 'sql' | 'sqlite')\n\n // Ensure the migrations infrastructure (i.e. the migrations table)\n // exists before we hand the runner back to the caller – most callers\n // expect the runner to be immediately usable without having to invoke\n // `setup()` manually. This is particularly important for projects\n // (like Groom) that directly call `getMigrations()` and\n // `migrate(...)` after obtaining the runner.\n await setup.setup();\n\n return new MySQLMigrationRunner(config,migration_files,setup,sqlrunner,driverConnection);\n }\n\n\n async createEmpty(config:MigrationConfig):Promise<MySQLMigrationRunner>{\n const conn = null as any\n let sqlrunner:ISQLRunner\n\n switch(config.database){\n case \"sql\":\n sqlrunner = new SQLRunner(conn)\n break;\n case \"sqlite\":\n sqlrunner = new SQLiteRunner(conn)\n break;\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n const setup = new MigrationSetup(sqlrunner,config);\n const read_strategy = this.getReadStategy(config)\n\n const migration_files = new MigrationDirectoryReader(config.migration_folder,read_strategy,sqlrunner,config.database as 'sql' | 'sqlite')\n return new MySQLMigrationRunner(config,migration_files,setup,sqlrunner,conn);\n }\n\n private getReadStategy(config:MigrationConfig){\n switch(config.database){\n case \"sql\":\n return dialect.MySqlDialectParser\n case \"sqlite\":\n return dialect.SqliteDialectParser\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n }\n}\n\n\nexport interface MigrationHistory{\n name:string\n up:string\n down:string\n}\n\nexport interface IMigrationRunner {\n setup(): Promise<void>;\n terminate(): Promise<void>;\n getMigrationsHistory(): Promise<MigrationHistory[]>;\n getMigrations(): Promise<MigrationNode[]>;\n getPendingMigrations(): Promise<MigrationNode[]>;\n getCompletedMigrations(): Promise<MigrationNode[]>;\n migrate(migrationNodes: MigrationNode[], forward: boolean): Promise<void>;\n reset(): Promise<void>;\n createMigration(name: string): void;\n close(): Promise<void>;\n init(config_file: string): Promise<void>;\n query(sql: string, params?: any[]): Promise<any>;\n}\n\nexport class MySQLMigrationRunner implements IMigrationRunner {\n constructor(\n private config:MigrationConfig,\n private directory:MigrationDirectoryReader,\n private setupRunner:MigrationSetup,\n private sqlrunner:ISQLRunner,\n private connection:mysql.Connection\n){\n\n }\n\n async setup(){\n try {\n await this.setupRunner.setup();\n } catch (error) {\n throw new MigrationExecutionError('Failed to set up migration database', undefined, undefined, toError(error));\n }\n }\n\n async terminate(){\n try {\n await this.setupRunner.teardown();\n } catch (error) {\n throw new MigrationExecutionError('Failed to tear down migration database', undefined, undefined, toError(error));\n }\n }\n\n async getMigrationsHistory():Promise<MigrationHistory[]>{\n try {\n const results = await this.sqlrunner.query(`\n select * \n from ${this.config.migration_table}\n `);\n return results[0] as any;\n } catch (error) {\n throw new MigrationExecutionError('Failed to get migration history', undefined, undefined, toError(error));\n }\n }\n\n\n async getMigrations(){\n try {\n return this.directory.loadMigrations(this.config.migration_table,this.connection);\n } catch (error) {\n throw new MigrationExecutionError('Failed to load migrations', undefined, undefined, toError(error));\n }\n }\n\n async getPendingMigrations(){\n try {\n const migrations = await this.getMigrations();\n return migration_filter(migrations,false);\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw error;\n }\n throw new MigrationExecutionError('Failed to get pending migrations', undefined, undefined, toError(error));\n }\n }\n\n async getCompletedMigrations(){\n try {\n const migrations = await this.getMigrations();\n return migration_filter(migrations,true);\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw error;\n }\n throw new MigrationExecutionError('Failed to get completed migrations', undefined, undefined, toError(error));\n }\n }\n\n async migrate(migrationNodes:MigrationNode[],forward:boolean):Promise<void>{\n for(let node of migrationNodes){\n try {\n if(forward){\n await node.up();\n }else{\n await node.down();\n }\n } catch (error) {\n throw new MigrationExecutionError(\n `Failed to ${forward ? 'apply' : 'rollback'} migration`,\n node.name || String(node),\n forward ? node.up_sql() : node.down_sql(),\n toError(error)\n );\n }\n }\n }\n\n\n async reset(){\n try {\n let migrations = await this.getMigrations();\n const rollback = await migration_filter(migrations,true);\n await this.migrate(rollback.reverse(),false);\n migrations = await this.getMigrations();\n const rollforward = await migration_filter(migrations,false);\n await this.migrate(rollforward,true);\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw error;\n }\n throw new MigrationExecutionError('Failed to reset migrations', undefined, undefined, toError(error));\n }\n }\n\n\n createMigration(name:string){\n try {\n const creator = new MigrationCreator(this.config);\n creator.create(name);\n } catch (error) {\n throw new MigrationExecutionError(`Failed to create migration: ${name}`, undefined, undefined, toError(error));\n }\n }\n\n\n async close(){\n if (this.sqlrunner) {\n try {\n await this.sqlrunner.end();\n } catch (error) {\n throw new DatabaseConnectionError(`Failed to close database connection: ${toError(error).message}`);\n }\n }\n }\n\n async query(sql: string, params?: any[]): Promise<any> {\n return await this.sqlrunner.query(sql, params);\n }\n\n async init(config_file:string){\n try {\n console.log(`Checking for ${config_file}`);\n const config_exist = fs.existsSync(config_file);\n\n if(!config_exist){\n console.log(`Creating ${config_file}`);\n const default_config = {\n \"migration_folder\":\"migrations\",\n \"migration_table\":\"proper_migrations\",\n \"database\": \"sql\",\n \"sql\":{\n \"host\":\"localhost\",\n \"user\":\"root\",\n \"database\":\"proper\",\n \"password\":\"\"\n }\n };\n fs.writeFileSync(config_file,JSON.stringify(default_config,null,2)); \n console.log(`Created ${config_file}`);\n }\n } catch (error) {\n throw new ConfigurationError(`Failed to initialize config file: ${toError(error).message}`);\n }\n }\n}\n\n\nexport class FileMigrationConfigReader{\n\n constructor(private configFile:string){\n\n }\n\n loadFile(){\n try {\n const fileContent = fs.readFileSync(this.configFile);\n const config:MigrationConfig = JSON.parse(fileContent.toString());\n \n // Validate required fields\n if (!config.migration_folder) {\n throw ConfigurationError.missingRequiredProperty('migration_folder');\n }\n \n if (!config.migration_table) {\n throw ConfigurationError.missingRequiredProperty('migration_table');\n }\n \n // For backward compatibility: if database type is omitted we derive\n // it from the presence of the dialect specific configuration\n // blocks. This keeps older `proper.json` files – that only defined\n // an \"sql\" or \"sqlite\" section – working without modification.\n if (!config.database) {\n if (config.sql) {\n config.database = 'sql';\n } else if (config.sqlite) {\n config.database = 'sqlite';\n } else {\n throw ConfigurationError.missingRequiredProperty('database');\n }\n }\n \n return config;\n } catch (error) {\n if (error instanceof ConfigurationError) {\n throw error;\n }\n const err = toError(error);\n if (err.message.includes('ENOENT')) {\n throw new ConfigurationError(`Config file not found: ${this.configFile}`);\n }\n throw new ConfigurationError(`Failed to load config file: ${err.message}`);\n }\n }\n}\n\n\nexport class MigrationCreator{\n constructor(private config:MigrationConfig){\n \n }\n\n\n create(name:string){\n if (!name) {\n throw new CLIError('Migration name is required');\n }\n\n try {\n // Ensure the migration folder exists\n if (!fs.existsSync(this.config.migration_folder)) {\n fs.mkdirSync(this.config.migration_folder, { recursive: true });\n }\n\n const now_timestamp = Date.now();\n\n const filename_up = `${now_timestamp}_${name}.up.sql`;\n const filename_down = `${now_timestamp}_${name}.down.sql`;\n\n fs.writeFileSync(`${this.config.migration_folder}/${filename_up}`,`\n-- Write your up migration here\n `.trim());\n\n fs.writeFileSync(`${this.config.migration_folder}/${filename_down}`,`\n-- Write your down migration here\n `.trim());\n \n console.log(`Created migration files:`);\n console.log(` ${filename_up}`);\n console.log(` ${filename_down}`);\n } catch (error) {\n if (error instanceof CLIError) {\n throw error;\n }\n throw new MigrationExecutionError(`Failed to create migration files: ${toError(error).message}`);\n }\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { MigrationNode } from './MigrationNode';\nimport { SqlMigrationBuilder } from './SqlMigrationBuilder';\nimport mysql from \"mysql2/promise\";\nimport { ISQLRunner } from \"./SQLRunner\";\n\n\nexport interface MigrationOptions{\n conn:mysql.Connection\n}\n\nexport class MigrationDirectoryReader {\n\n constructor(\n private directory: string,\n private read_strategy: any,\n private sqlrunner: ISQLRunner,\n private dialect: 'sql' | 'sqlite' = 'sql'\n ) {\n\n }\n\n /**\n * Resolves the appropriate file for a migration based on dialect.\n * Priority: dialect-specific file > generic file\n */\n private resolveFile(baseName: string, direction: 'up' | 'down'): string | null {\n const dialectExt = this.dialect === 'sql' ? 'mysql' : 'sqlite';\n\n // Priority 1: Dialect-specific file\n const dialectFile = path.join(this.directory, `${baseName}.${dialectExt}.${direction}.sql`);\n if (fs.existsSync(dialectFile)) return dialectFile;\n\n // Priority 2: Generic file\n const genericFile = path.join(this.directory, `${baseName}.${direction}.sql`);\n if (fs.existsSync(genericFile)) return genericFile;\n\n return null;\n }\n\n /**\n * Checks if a file path is dialect-specific (contains .mysql. or .sqlite. in the name)\n */\n private isDialectSpecific(filePath: string): boolean {\n return /\\.(mysql|sqlite)\\.(up|down)\\.sql$/i.test(filePath);\n }\n\n loadMigrations(table:string,connection:any):MigrationNode[] {\n\n fs.existsSync(this.directory) || fs.mkdirSync(this.directory);\n const dir_content = fs.readdirSync(this.directory,{withFileTypes:true}).filter(file=>file.isFile()).map(file=>file.name);\n\n // Extract unique migration keys (stripping dialect extensions)\n const uniqueKeys = new Set<string>();\n dir_content.forEach(file => {\n // Strip dialect extension (.mysql or .sqlite) and direction (.up or .down) to get base key\n const key = file.replace(/(?:\\.(mysql|sqlite))?\\.(up|down)\\.(sql|js)/i, \"\").toLowerCase();\n uniqueKeys.add(key);\n });\n\n const migration_sorter: any = {};\n\n // For each unique key, resolve the correct files based on dialect\n uniqueKeys.forEach((migration_key) => {\n const builder = new SqlMigrationBuilder(migration_key);\n\n const upFile = this.resolveFile(migration_key, 'up');\n const downFile = this.resolveFile(migration_key, 'down');\n\n if (upFile) {\n this.loadMigration(builder, upFile);\n }\n if (downFile) {\n this.loadMigration(builder, downFile);\n }\n\n migration_sorter[migration_key] = builder;\n });\n\n const keys = Object.keys(migration_sorter)\n\n keys.sort()\n\n const built = keys.map(key=>{\n return migration_sorter[key].build(table,this.sqlrunner)\n })\n return built\n\n }\n\n\n loadMigration(builder: SqlMigrationBuilder, file: string) {\n const is_sql = /sql$/i.test(file);\n const is_js = /js$/i.test(file);\n const is_up = /up\\.(js|sql)/i.test(file);\n const is_down = /down\\.(js|sql)/i.test(file);\n if (is_sql && is_up) {\n const content = this.sql_up(file);\n builder.set_up(file,content);\n } else if (is_sql && is_down) {\n const content = this.sql_down(file);\n builder.set_down(file,content);\n } else {\n throw new Error(`Invalid migration file: ${file}`);\n }\n return builder;\n }\n\n\n sql_up(file: string) {\n let content = fs.readFileSync(file).toString();\n // Dialect-specific files bypass read_strategy (no inline marker parsing needed)\n if (!this.isDialectSpecific(file)) {\n content = this.read_strategy(content);\n }\n return content.trim();\n }\n\n sql_down(file: string) {\n let content = fs.readFileSync(file).toString();\n // Dialect-specific files bypass read_strategy (no inline marker parsing needed)\n if (!this.isDialectSpecific(file)) {\n content = this.read_strategy(content);\n }\n return content.trim();\n }\n\n}\n","/**\n * Base class for all migration-related errors\n */\nexport class MigrationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MigrationError';\n // This is needed to make instanceof work correctly in ES5\n Object.setPrototypeOf(this, MigrationError.prototype);\n }\n}\n\n/**\n * Error thrown when there is an issue with the configuration\n */\nexport class ConfigurationError extends MigrationError {\n constructor(message: string) {\n super(`Configuration Error: ${message}`);\n this.name = 'ConfigurationError';\n Object.setPrototypeOf(this, ConfigurationError.prototype);\n }\n\n /**\n * Helper method for missing database configuration\n * @param dbType The database type (e.g., 'sql', 'sqlite')\n * @returns A ConfigurationError with appropriate message\n */\n static missingDatabaseConfiguration(dbType: string): ConfigurationError {\n return new ConfigurationError(`Missing ${dbType} configuration`);\n }\n\n /**\n * Helper method for unknown database type\n * @param dbType The unknown database type\n * @returns A ConfigurationError with appropriate message\n */\n static unknownDatabaseType(dbType: string): ConfigurationError {\n return new ConfigurationError(`Unknown database type: ${dbType}`);\n }\n\n /**\n * Helper method for missing required configuration properties\n * @param property The name of the missing property\n * @returns A ConfigurationError with appropriate message\n */\n static missingRequiredProperty(property: string): ConfigurationError {\n return new ConfigurationError(`Missing required property: ${property}`);\n }\n}\n\n/**\n * Error thrown when there is an issue with the database connection\n */\nexport class DatabaseConnectionError extends MigrationError {\n constructor(message: string) {\n super(`Database Connection Error: ${message}`);\n this.name = 'DatabaseConnectionError';\n Object.setPrototypeOf(this, DatabaseConnectionError.prototype);\n }\n\n /**\n * Helper method for connection errors\n * @param dbType The database type (e.g., 'sql', 'sqlite')\n * @param details Additional error details\n * @returns A DatabaseConnectionError with appropriate message\n */\n static connectionFailed(dbType: string, details?: string): DatabaseConnectionError {\n const message = details \n ? `Failed to connect to ${dbType} database: ${details}`\n : `Failed to connect to ${dbType} database`;\n return new DatabaseConnectionError(message);\n }\n\n /**\n * Helper method for authentication errors\n * @param dbType The database type (e.g., 'sql', 'sqlite')\n * @returns A DatabaseConnectionError with appropriate message\n */\n static authenticationFailed(dbType: string): DatabaseConnectionError {\n return new DatabaseConnectionError(`Authentication failed for ${dbType} database`);\n }\n}\n\n/**\n * Error thrown when there is an issue with executing a migration\n */\nexport class MigrationExecutionError extends MigrationError {\n constructor(\n message: string,\n public readonly migrationName?: string,\n public readonly sql?: string,\n public readonly originalError?: Error\n ) {\n /*\n * The public `message` that gets surfaced to callers **must not** include the\n * raw SQL text. The SQL string is already exposed through the dedicated\n * `sql` property and adding it to the message makes it unnecessarily noisy\n * and difficult to assert against in unit-tests. Therefore we only embed\n * the essential information (error type, optional migration name and the\n * short error message) in the main message string while keeping the full\n * SQL available separately.\n */\n let fullMessage = `Migration Execution Error${migrationName ? ` in '${migrationName}'` : ''}: ${message}`;\n\n if(originalError){\n fullMessage += `\\nOriginal Error:\\n${originalError.message}`;\n }\n\n super(fullMessage);\n this.name = 'MigrationExecutionError';\n Object.setPrototypeOf(this, MigrationExecutionError.prototype);\n }\n\n /**\n * Helper method for SQL execution errors\n * @param migrationName The name of the migration\n * @param sql The SQL that caused the error\n * @param originalError The original error thrown by the database driver\n * @returns A MigrationExecutionError with appropriate message\n */\n static sqlExecutionFailed(migrationName: string, sql: string, originalError: Error): MigrationExecutionError {\n return new MigrationExecutionError(\n originalError.message,\n migrationName,\n sql,\n originalError\n );\n }\n\n /**\n * Helper method for missing migration file errors\n * @param filename The missing file\n * @returns A MigrationExecutionError with appropriate message\n */\n static missingMigrationFile(filename: string): MigrationExecutionError {\n return new MigrationExecutionError(`Migration file not found: ${filename}`);\n }\n\n /**\n * Helper method for invalid migration file format errors\n * @param filename The invalid file\n * @param details Additional error details\n * @returns A MigrationExecutionError with appropriate message\n */\n static invalidMigrationFile(filename: string, details?: string): MigrationExecutionError {\n const message = details\n ? `Invalid migration file format in ${filename}: ${details}`\n : `Invalid migration file format in ${filename}`;\n return new MigrationExecutionError(message);\n }\n}\n\n/**\n * Error thrown when there is an issue with the migration CLI\n */\nexport class CLIError extends MigrationError {\n constructor(message: string) {\n super(`CLI Error: ${message}`);\n this.name = 'CLIError';\n Object.setPrototypeOf(this, CLIError.prototype);\n }\n\n /**\n * Helper method for missing command errors\n * @returns A CLIError with appropriate message\n */\n static missingCommand(): CLIError {\n return new CLIError('No command specified. Run with --help for usage information.');\n }\n\n /**\n * Helper method for unknown command errors\n * @param command The unknown command\n * @returns A CLIError with appropriate message\n */\n static unknownCommand(command: string): CLIError {\n return new CLIError(`Unknown command: ${command}. Run with --help for usage information.`);\n }\n\n /**\n * Helper method for missing required argument errors\n * @param argument The missing argument\n * @returns A CLIError with appropriate message\n */\n static missingRequiredArgument(argument: string): CLIError {\n return new CLIError(`Missing required argument: ${argument}`);\n }\n}\n","import { Connection } from 'mysql2/promise';\nimport { MigrationStatus } from './MigrationStatus';\nimport { ISQLRunner } from './SQLRunner';\nimport { MigrationExecutionError } from './errors';\n\nexport abstract class MigrationNode {\n name: string;\n\n constructor(name?: string) {\n this.name = name || '';\n }\n\n abstract get_key():string;\n abstract status(): Promise<MigrationStatus>;\n abstract up(): Promise<void>;\n abstract down(): Promise<void>;\n abstract up_sql(): string;\n abstract down_sql(): string;\n}\n\n\nexport class SqlMigrationNode extends MigrationNode {\n up_sql(): string {\n return this.sql_up;\n }\n down_sql(): string {\n return this.sql_down;\n }\n get_key(): string {\n return this.key;\n }\n\n constructor(private conn:ISQLRunner,\n private table:string, \n private key:string,\n private up_file:string,\n private sql_up:string,\n private down_file:string,\n private sql_down:string) {\n super(key);\n }\n\n async status(): Promise<MigrationStatus> {\n try {\n const result = await this.conn.query(`\n select * \n from ${this.table}\n where migration_key = ?;\n `, [this.key]);\n\n if(result.length > 0 && result[0].length > 0){\n return {\n completed: true\n };\n } else {\n return {\n completed: false\n };\n }\n } catch (error) {\n throw new MigrationExecutionError(\n `Error checking status for migration`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n async up(): Promise<void> {\n try {\n await this.conn.execute(this.sql_up);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing UP migration`,\n this.key,\n this.sql_up,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n \n try {\n await this.conn.execute(`\n insert into ${this.table} (migration_key,up,down)\n values (?,?,?)\n `, [this.key, this.up_file, this.down_file]);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error recording migration completion`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n async down(): Promise<void> {\n try {\n await this.conn.execute(this.sql_down);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing DOWN migration`,\n this.key,\n this.sql_down,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n \n try {\n await this.conn.execute(`\n delete from ${this.table}\n where migration_key = ?\n `, [this.key]);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error removing migration record`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n}\n\n\nexport class SqliteMigrationNode extends MigrationNode {\n up_sql(): string {\n return this.sql_up;\n }\n down_sql(): string {\n return this.sql_down;\n }\n constructor(\n private conn: ISQLRunner, // your SQLite runner\n private table: string,\n private key: string,\n private up_file: string,\n private sql_up: string,\n private down_file: string,\n private sql_down: string\n ) {\n super(key);\n }\n\n /**\n * Returns the unique key for this migration (e.g. timestamp + name).\n */\n get_key(): string {\n return this.key;\n }\n\n /**\n * Check if this migration is already completed by looking in the migration table.\n */\n async status(): Promise<MigrationStatus> {\n try {\n // Usually `this.conn.query(...)` returns an array of rows.\n // The first element might be the row set, depending on your runner.\n const cursor = await this.conn.query(\n `SELECT * FROM ${this.table} WHERE migration_key = ?;`,\n [this.key]\n );\n\n // Usually, `cursor[0]` is the row array in many MySQL runners;\n // In a SQLite scenario, it may be just `cursor`\n // So adjust depending on your actual runner's return shape.\n const rows = cursor[0] as any[];\n\n if (rows && rows.length > 0) {\n return { completed: true };\n } else {\n return { completed: false };\n }\n } catch (error) {\n throw new MigrationExecutionError(\n `Error checking status for migration`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n /**\n * Run the 'up' SQL, then record this migration in the table.\n */\n async up(): Promise<void> {\n try {\n // Execute the 'up' script\n await this.conn.execute(this.sql_up);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing UP migration`,\n this.key,\n this.sql_up,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n\n // Insert a record of this migration having completed\n try {\n await this.conn.execute(\n `\n INSERT INTO ${this.table} (migration_key, up, down)\n VALUES (?, ?, ?)\n `,\n [this.key, this.up_file, this.down_file]\n );\n } catch (error) {\n throw new MigrationExecutionError(\n `Error recording migration completion`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n /**\n * Run the 'down' SQL, then remove this migration record from the table.\n */\n async down(): Promise<void> {\n try {\n // Execute the 'down' script\n await this.conn.execute(this.sql_down);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing DOWN migration`,\n this.key,\n this.sql_down,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n\n // Remove the migration from the table\n try {\n await this.conn.execute(\n `\n DELETE FROM ${this.table}\n WHERE migration_key = ?\n `,\n [this.key]\n );\n } catch (error) {\n throw new MigrationExecutionError(\n `Error removing migration record`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n}","import { Connection } from 'mysql2/promise';\nimport { SqlMigrationNode } from './MigrationNode';\nimport { ISQLRunner } from './SQLRunner';\n\n\n\nexport class SqlMigrationBuilder {\n\n private up: string = '';\n private up_file: string = '';\n private down: string = '';\n private down_file: string = '';\n\n constructor(private key: string) {\n }\n\n set_up(file:string,up: string) {\n this.up_file = file;\n this.up = up;\n }\n\n set_down(file:string,down: string) {\n this.down_file = file;\n this.down = down;\n }\n\n build(table:string,conn: ISQLRunner) {\n return new SqlMigrationNode(conn, table,this.key, this.up_file, this.up, this.down_file,this.down);\n }\n}\n","import { MigrationConfig } from \"./MigrationConfig\";\nimport fs from \"fs\";\nimport { ISQLRunner } from './SQLRunner';\n\nexport class MigrationSetup {\n constructor(private sqlrunner: ISQLRunner, private config: MigrationConfig) {}\n\n\n async setup() {\n\n fs.existsSync(this.config.migration_folder) || fs.mkdirSync(this.config.migration_folder);\n\n const tableName = this.config.migration_table;\n\n // Use dialect-specific DDL so that the migrations table can be created\n // both in MySQL/MariaDB and in SQLite. The two dialects differ mainly\n // in the auto-increment syntax and the column types.\n const createTableSql = this.config.database === 'sqlite'\n ? `CREATE TABLE IF NOT EXISTS ${tableName} (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n migration_key TEXT,\n up TEXT,\n down TEXT,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )`\n : `CREATE TABLE IF NOT EXISTS ${tableName} (\n id INT AUTO_INCREMENT PRIMARY KEY,\n migration_key VARCHAR(255),\n up VARCHAR(255),\n down VARCHAR(255),\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )`;\n\n await this.sqlrunner.query(createTableSql);\n }\n\n async teardown() {\n await this.sqlrunner.execute(`DROP TABLE ${this.config.migration_table}`);\n }\n}\n\n\n\n\n","export function MySqlDialectParser(sql: string): string {\n const lines = sql.split('\\n');\n let result = '';\n \n // We start \"in MySQL\" so that lines before [sql] are kept.\n let isInMySQLBlock = true;\n \n // e.g. `-- [sql]`, `-- [ sql ]`, `-- [mysql]`, ignoring case/spaces\n const startSQLRegex = /^\\s*--\\s*\\[\\s*(sql|mysql)\\s*\\]\\s*$/i;\n // e.g. `-- [sqlite]`, `-- [ pg ]`, `-- [mydialect]` (any bracket means \"turn off MySQL\")\n const anyDialectRegex = /^\\s*--\\s*\\[\\s*\\w+\\s*\\]\\s*$/i;\n \n for (const line of lines) {\n const trimmed = line.trim();\n \n // If line is \" -- [sql] \" or \" -- [mysql] \", we *turn on* MySQL capturing:\n if (startSQLRegex.test(trimmed)) {\n isInMySQLBlock = true;\n // We also include this line in output\n result += line + '\\n';\n continue;\n }\n \n // If line is *some other* bracket, e.g. \" -- [sqlite] \"\n // then switch MySQL off, and do NOT keep that line\n if (anyDialectRegex.test(trimmed) && !startSQLRegex.test(trimmed)) {\n isInMySQLBlock = false;\n // Skip to next line\n continue;\n }\n \n // If we get here and see a line without a [dialect] marker,\n // and we were previously turned off because of non-mysql dialect,\n // then check if it's common SQL (like CREATE INDEX).\n // Turn MySQL back on for this line\n if (!isInMySQLBlock && line.toLowerCase().includes('create index')) {\n isInMySQLBlock = true;\n }\n \n // If we're in MySQL mode, keep the line\n if (isInMySQLBlock) {\n result += line + '\\n';\n }\n }\n \n return result;\n}\n\nexport function SqliteDialectParser(sql: string): string {\n const lines = sql.split('\\n');\n let result = '';\n let isInSqliteBlock = true;\n\n // Regex to detect a line that starts Sqlite code block:\n const startSqliteRegex = /^\\s*--\\s*\\[\\s*sqlite\\s*\\]\\s*$/i;\n const anyDialectRegex = /^\\s*--\\s*\\[\\s*\\w+\\s*\\]\\s*$/i;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (startSqliteRegex.test(trimmed)) {\n // If we see a \"-- [sqlite]\" line, start capturing\n isInSqliteBlock = true;\n result += line + '\\n';\n continue;\n } else if (anyDialectRegex.test(trimmed) && !startSqliteRegex.test(trimmed)) {\n // If we see a *different* bracket line, turn off capturing\n isInSqliteBlock = false;\n continue;\n }\n \n // If we get here and see a line without a [dialect] marker,\n // and we were previously turned off because of non-sqlite dialect,\n // then check if it's common SQL (like CREATE INDEX).\n // Turn SQLite back on for this line\n if (!isInSqliteBlock && line.toLowerCase().includes('create index')) {\n isInSqliteBlock = true;\n }\n \n // If we are in the Sqlite block, capture the line\n if (isInSqliteBlock) {\n result += line + '\\n';\n }\n }\n \n return result;\n}","\nimport * as sqlite from 'sqlite';\nimport { Statement } from 'sqlite3';\nimport mysql from 'mysql2/promise';\n\n\n\ntype QueryResult = {\n stmt: Statement;\n lastID: number;\n changes: number;\n}\n\nexport interface ISQLRunner {\n query(sql: string, params?: any[]): Promise<any>;\n execute(sql: string, params?: any[]): Promise<any>;\n end(): Promise<void>;\n}\n\n/**\n * Base class that implements the common contract and helper utilities that are\n * shared between the different dialect runners. The concrete subclasses only\n * need to implement the three primitive methods `_query`, `_execute` and\n * `_end` that perform the actual driver-specific interaction. Everything else\n * – such as ensuring a uniform return shape – is handled here once.\n */\nexport abstract class BaseSQLRunner implements ISQLRunner {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n abstract _query(sql: string, params?: any[]): Promise<any>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n abstract _execute(sql: string, params?: any[]): Promise<any>;\n abstract _end(): Promise<void>;\n\n /**\n * Ensures that both MySQL and SQLite return the same tuple shape that callers\n * expect: `[rowsOrResult, extra]`. For SQLite there is no `extra` metadata\n * comparable to MySQL's `FieldPacket[]`, so we just use `undefined`.\n */\n async query(sql: string, params: any[] = []): Promise<any> {\n const result = await this._query(sql, params);\n\n // MySQL already returns the desired tuple. For SQLite we need to wrap.\n return Array.isArray(result) && result.length === 2 ? result : [result, undefined];\n }\n\n async execute(sql: string, params: any[] = []): Promise<any> {\n const result = await this._execute(sql, params);\n return Array.isArray(result) && result.length === 2 ? result : [result, undefined];\n }\n\n async end(): Promise<void> {\n await this._end();\n }\n}\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === \"function\";\n}\n\nexport class SQLRunner extends BaseSQLRunner {\n constructor(private connection: mysql.Connection) {\n super();\n }\n\n // The MySQL driver already returns the correct tuple shapes.\n async _query(sql: string, params: any[] = []) {\n return await this.connection.query(sql, params);\n }\n\n async _execute(sql: string, params: any[] = []) {\n return await this.connection.execute(sql, params);\n }\n\n async _end() {\n if (this.connection) {\n await this.connection.end();\n }\n }\n}\n\nexport class SQLiteRunner extends BaseSQLRunner {\n constructor(private connection: sqlite.Database | any) {\n super();\n }\n\n private async prepareStatement(sql: string) {\n if (typeof this.connection.prepare !== \"function\") {\n throw new Error(\"SQLite connection does not support prepare()\");\n }\n const stmt = this.connection.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n }\n\n private async finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== \"function\") return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n }\n\n private async statementAll(stmt: any, params: any[]) {\n if (typeof stmt.all !== \"function\") {\n throw new Error(\"SQLite statement does not support all()\");\n }\n // sqlite3 callback-style API\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...params);\n return isPromiseLike(result) ? await result : result;\n }\n\n private async statementRun(stmt: any, params: any[]) {\n if (typeof stmt.run !== \"function\") {\n throw new Error(\"SQLite statement does not support run()\");\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastID: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...params);\n return isPromiseLike(result) ? await result : result;\n }\n\n async _query(sql: string, params: any[] = []) {\n const stmt = await this.prepareStatement(sql);\n try {\n const rows = await this.statementAll(stmt, params);\n return rows;\n } finally {\n await this.finalizeStatement(stmt);\n }\n }\n\n async _execute(sql: string, params: any[] = []) {\n if (this.isMultiStatement(sql)) {\n return await this.executeMultiStatement(sql, params)\n .catch((err) => {\n console.error((\n \"Error executing multi-statement SQL:\\n\"+\n `${sql}\\n`\n ), err);\n throw err;\n });\n }\n \n const stmt = await this.prepareStatement(sql);\n try {\n const info = await this.statementRun(stmt, params);\n return info;\n } finally {\n await this.finalizeStatement(stmt);\n }\n }\n\n private isMultiStatement(sql: string): boolean {\n // SQLite does not support multiple statements in a single query.\n return sql.split(';').length > 1;\n }\n\n private async executeMultiStatement(sql: string, params: any[] = []) {\n const statements = sql.split(';')\n .map((s) => s.split('\\n')\n .map(\n s=>this.removeComments(s))\n .filter(s=>s.trim()!='')\n .join('\\n')\n )\n .filter((s) => s.trim() !== '');\n \n const infos = await statements.reduce(async (prev,statement) => {\n const infos = await prev;\n const stmt = await this.prepareStatement(`${statement};`);\n try {\n const info = await this.statementRun(stmt, params);\n infos.push(info);\n return infos;\n } finally {\n await this.finalizeStatement(stmt);\n }\n },Promise.resolve([null] as any[]))\n .then((infos:QueryResult[]) => {\n return infos.filter((info) => info !== null);\n })\n return infos.reduce((acc,latest)=>{\n if(latest){\n acc.stmt = latest.stmt;\n acc.lastID = latest.lastID;\n acc.changes += latest.changes;\n }\n return acc\n })\n }\n\n private removeComments(sql: string): string {\n // Remove single-line comments\n sql = sql.replace(/--.*$/gm, '');\n return sql;\n }\n\n\n async _end() {\n if (this.connection) {\n await this.connection.close();\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\n\nimport type { IMigrationRunner, MigrationHistory } from './MigrationRunner';\nimport { MigrationRunnerFactory, FileMigrationConfigReader, loadMigrationConfig } from './MigrationRunner';\nimport type { MigrationConfig } from './MigrationConfig';\n\nexport type SeedTransactionalMode = 'runner' | 'seed' | 'none';\n\nexport type SeedOptions = {\n migrationsDir?: string;\n dataDir?: string;\n validate?: boolean;\n transactional?: SeedTransactionalMode;\n aliasMap?: Record<string, string>;\n preloadedData?: Record<string, unknown>;\n log?: (msg: string) => void;\n names?: string[];\n};\n\nexport type ResolvedSeed = {\n kind: 'sql' | 'ts' | 'js';\n name: string;\n alias: string;\n upPath: string;\n downPath?: string;\n dataPath: string | null;\n schemaPath: string | null;\n};\n\nfunction resolveAlias(name: string, aliasMap?: Record<string, string>): string {\n if (!aliasMap) return name;\n return aliasMap[name] ?? name;\n}\n\nfunction walkForFile(rootDir: string, fileName: string): string | null {\n if (!fs.existsSync(rootDir)) return null;\n const entries = fs.readdirSync(rootDir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(rootDir, entry.name);\n if (entry.isDirectory()) {\n const found = walkForFile(full, fileName);\n if (found) return found;\n } else if (entry.isFile() && entry.name === fileName) {\n return full;\n }\n }\n return null;\n}\n\nfunction resolveMigrationsDir(migrationConfig: MigrationConfig, options: SeedOptions): string {\n const fromOptions = options.migrationsDir;\n const fromConfig = migrationConfig.seeds?.migrationsDir;\n\n const dir = fromOptions ?? fromConfig;\n if (!dir) {\n throw new Error('Seed migrationsDir not configured. Set seeds.migrationsDir in proper.json or pass it explicitly.');\n }\n return dir;\n}\n\nfunction mergeSeedConfig(\n migrationConfig: MigrationConfig,\n options: SeedOptions,\n): { names: string[]; finalOptions: SeedOptions & { migrationsDir: string; validate: boolean; transactional: SeedTransactionalMode } } {\n const names = options.names && options.names.length\n ? options.names\n : migrationConfig.seeds?.list && migrationConfig.seeds.list.length\n ? migrationConfig.seeds.list\n : [];\n\n if (!names.length) {\n throw new Error('No seed names provided and no seeds.list defined in proper config');\n }\n\n const migrationsDir = resolveMigrationsDir(migrationConfig, options);\n const dataDir = options.dataDir ?? migrationConfig.seeds?.dataDir;\n const validate = options.validate !== undefined ? options.validate : true;\n const transactional = options.transactional ?? 'none';\n\n const finalOptions: SeedOptions & { migrationsDir: string; validate: boolean; transactional: SeedTransactionalMode } = {\n ...options,\n migrationsDir,\n dataDir,\n validate,\n transactional,\n };\n\n return { names, finalOptions };\n}\n\n// export function loadMigrationConfig(configFile: string): MigrationConfig {\n// const reader = new FileMigrationConfigReader(configFile);\n// return reader.loadFile();\n// }\n\nfunction resolveSqlPair(name: string, migrationsDir: string): { upPath: string; downPath: string } | null {\n const up = walkForFile(migrationsDir, `${name}.up.sql`);\n const down = walkForFile(migrationsDir, `${name}.down.sql`);\n if (up && down) {\n return { upPath: up, downPath: down };\n }\n return null;\n}\n\nfunction resolveModule(name: string, migrationsDir: string): { kind: 'ts' | 'js'; modulePath: string } | null {\n const ts = walkForFile(migrationsDir, `${name}.ts`);\n if (ts) return { kind: 'ts', modulePath: ts };\n const js = walkForFile(migrationsDir, `${name}.js`);\n if (js) return { kind: 'js', modulePath: js };\n return null;\n}\n\nexport async function resolveSeed(\n name: string,\n migrationConfig: MigrationConfig,\n options: SeedOptions,\n): Promise<ResolvedSeed> {\n const migrationsDir = resolveMigrationsDir(migrationConfig, options);\n const alias = resolveAlias(name, options.aliasMap);\n\n const sqlPair = resolveSqlPair(name, migrationsDir);\n if (sqlPair) {\n return {\n kind: 'sql',\n name,\n alias,\n upPath: sqlPair.upPath,\n downPath: sqlPair.downPath,\n dataPath: null,\n schemaPath: null,\n };\n }\n\n const module = resolveModule(name, migrationsDir);\n if (!module) {\n throw new Error(`Seed implementation not found for \"${name}\" under ${migrationsDir}`);\n }\n\n const dataDir = options.dataDir ?? migrationConfig.seeds?.dataDir;\n let dataPath: string | null = null;\n let schemaPath: string | null = null;\n\n if (dataDir) {\n dataPath = walkForFile(dataDir, `${alias}.json`);\n schemaPath = walkForFile(dataDir, `${alias}.schema.json`);\n }\n\n return {\n kind: module.kind,\n name,\n alias,\n upPath: module.modulePath,\n downPath: module.modulePath,\n dataPath,\n schemaPath,\n };\n}\n\nasync function loadJson(filePath: string): Promise<unknown> {\n const content = await fs.promises.readFile(filePath, 'utf8');\n return JSON.parse(content);\n}\n\nfunction createValidator() {\n const ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(ajv);\n return ajv;\n}\n\nasync function validateData(schemaPath: string | null, data: unknown, validate: boolean, log?: (msg: string) => void) {\n if (!validate || !schemaPath) return;\n const content = await fs.promises.readFile(schemaPath, 'utf8');\n const schema = JSON.parse(content);\n const ajv = createValidator();\n const validateFn = ajv.compile(schema);\n const ok = validateFn(data);\n if (!ok) {\n log?.(`Validation failed for seed data (${schemaPath})`);\n throw new Error(`Seed data validation failed: ${ajv.errorsText(validateFn.errors || [])}`);\n }\n}\n\nasync function runSqlSeed(\n runner: IMigrationRunner,\n resolved: ResolvedSeed,\n direction: 'up' | 'down',\n): Promise<void> {\n const sqlPath = direction === 'up' ? resolved.upPath : resolved.downPath!;\n const sql = await fs.promises.readFile(sqlPath, 'utf8');\n await runner.query(sql);\n}\n\nexport type SeedContext = {\n data: unknown;\n log?: (msg: string) => void;\n dialect: string;\n};\n\nasync function loadSeedModule(modulePath: string): Promise<any> {\n const resolved = path.resolve(modulePath);\n\n // For .ts files, use require (works with tsx/cjs loader)\n // For .js files, use dynamic import\n if (resolved.endsWith('.ts')) {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n return require(resolved);\n }\n\n return import(resolved);\n}\n\nasync function runModuleSeed(\n runner: IMigrationRunner,\n resolved: ResolvedSeed,\n migrationConfig: MigrationConfig,\n options: SeedOptions & { validate: boolean },\n direction: 'up' | 'down',\n): Promise<void> {\n const { log } = options;\n const module = await loadSeedModule(resolved.upPath);\n const handler = module[direction];\n if (typeof handler !== 'function') {\n throw new Error(`Seed module \"${resolved.name}\" does not export ${direction}()`);\n }\n\n let data: unknown = null;\n if (options.preloadedData && Object.prototype.hasOwnProperty.call(options.preloadedData, resolved.name)) {\n data = options.preloadedData[resolved.name];\n } else if (resolved.dataPath) {\n data = await loadJson(resolved.dataPath);\n }\n\n await validateData(resolved.schemaPath, data, options.validate, log);\n\n const ctx: SeedContext = {\n data,\n log,\n dialect: migrationConfig.database || 'sql',\n };\n\n await handler(runner, ctx);\n}\n\nasync function runSingleSeed(\n runner: IMigrationRunner,\n migrationConfig: MigrationConfig,\n name: string,\n options: SeedOptions & { validate: boolean; transactional: SeedTransactionalMode },\n direction: 'up' | 'down',\n): Promise<void> {\n const resolved = await resolveSeed(name, migrationConfig, options);\n\n if (resolved.kind === 'sql') {\n await runSqlSeed(runner, resolved, direction);\n } else {\n await runModuleSeed(runner, resolved, migrationConfig, options, direction);\n }\n}\n\nasync function withTransactionalMode(\n runner: IMigrationRunner,\n migrationConfig: MigrationConfig,\n names: string[],\n options: SeedOptions & { validate: boolean; transactional: SeedTransactionalMode },\n direction: 'up' | 'down',\n): Promise<void> {\n const mode = options.transactional;\n\n if (mode === 'runner') {\n await runner.query('BEGIN');\n try {\n for (const name of names) {\n await runSingleSeed(runner, migrationConfig, name, options, direction);\n }\n await runner.query('COMMIT');\n } catch (err) {\n try {\n await runner.query('ROLLBACK');\n } catch {\n }\n throw err;\n }\n return;\n }\n\n if (mode === 'seed') {\n for (const name of names) {\n await runner.query('BEGIN');\n try {\n await runSingleSeed(runner, migrationConfig, name, options, direction);\n await runner.query('COMMIT');\n } catch (err) {\n try {\n await runner.query('ROLLBACK');\n } catch {\n }\n throw err;\n }\n }\n return;\n }\n\n for (const name of names) {\n await runSingleSeed(runner, migrationConfig, name, options, direction);\n }\n}\n\nexport async function runSeedsWithRunner(\n runner: IMigrationRunner,\n migrationConfig: MigrationConfig,\n direction: 'up' | 'down',\n options: SeedOptions,\n): Promise<void> {\n const { names, finalOptions } = mergeSeedConfig(migrationConfig, options);\n await withTransactionalMode(runner, migrationConfig, names, finalOptions, direction);\n}\n\nexport type SeedFactoryOptions = SeedOptions & {\n configFile?: string;\n};\n\nexport type SeedFactory = {\n up(names?: string[]): Promise<void>;\n down(names?: string[]): Promise<void>;\n};\n\nexport function createSeedFactory(options: SeedFactoryOptions): SeedFactory {\n const configFile = options.configFile ?? 'proper.json';\n\n return {\n async up(names?: string[]) {\n const runner = await MigrationRunnerFactory.create(configFile);\n const migrationConfig = loadMigrationConfig(configFile);\n try {\n await runSeedsWithRunner(runner, migrationConfig, 'up', {\n ...options,\n names: names && names.length ? names : options.names,\n });\n } finally {\n await runner.close();\n }\n },\n\n async down(names?: string[]) {\n const runner = await MigrationRunnerFactory.create(configFile);\n const migrationConfig = loadMigrationConfig(configFile);\n try {\n await runSeedsWithRunner(runner, migrationConfig, 'down', {\n ...options,\n names: names && names.length ? names : options.names,\n });\n } finally {\n await runner.close();\n }\n },\n };\n}\n"],"mappings":"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","names":["args","minimist","commands","import_fs","command","path","fs","import_fs","fs","s","infos","mysql","config_file","fs","import_fs","import_path","fs","path","module","Ajv","addFormats","printTable"]}
|
|
1
|
+
{"version":3,"sources":["../cli.ts","../framework/MigrationCLi.ts","../framework/MigrationFilter.ts","../framework/MigrationRunner.ts","../framework/MigrationDirectoryReader.ts","../framework/errors.ts","../framework/MigrationNode.ts","../framework/SqlMigrationBuilder.ts","../framework/MigrationSetup.ts","../framework/MigrationDialectParser.ts","../framework/SQLRunner.ts","../framework/SeedRunner.ts"],"sourcesContent":["#!/usr/bin/env node\nimport 'source-map-support/register';\nimport 'tsx/cjs';\n\nimport { MigrationCLIFactory } from \"./framework/MigrationCLi\";\nimport { migration_filter } from \"./framework/MigrationFilter\";\nimport { MigrationRunnerFactory, FileMigrationConfigReader } from \"./framework/MigrationRunner\";\nimport { CLIError } from \"./framework/errors\";\nimport { runSeedsWithRunner, SeedOptions } from \"./framework/SeedRunner\";\n\nconst args = MigrationCLIFactory.setup(process.argv);\n\n// Validate that at least one command is provided\nif (!args.commands || args.commands.length === 0) {\n console.error(\"Error: No command specified\");\n printUsage();\n process.exit(1);\n}\n\nconst commands = args.commands;\nconst command = commands[0];\nconst load_database = ![\"init\", 'create', 'help'].includes(command.toLowerCase());\nconst config_file = args.flags.config || \"proper.json\";\n\n// Handle help command\nif (command.toLowerCase() === 'help') {\n printUsage();\n process.exit(0);\n}\n\nconsole.log(`Loading database: ${load_database}`);\n\nconst pending_runner = load_database ?\n MigrationRunnerFactory.create(config_file) :\n MigrationRunnerFactory.createEmpty(config_file);\n\npending_runner.then(async runner => {\n try {\n if (load_database) {\n await runner.setup();\n }\n\n switch (command.toLowerCase()) {\n case \"up\":\n const migrations_forward = await runner.getMigrations();\n let upgraded = await migration_filter(migrations_forward, false);\n\n if (args.flags.increment) {\n const increment = parseInt(args.flags.increment);\n upgraded = upgraded.slice(0, increment);\n }\n\n console.log(`Applying ${upgraded.length} migration(s)`);\n\n if (upgraded.length > 0) {\n for (const migration of upgraded) {\n console.log(` - ${migration.name}`);\n }\n\n await runner.migrate(upgraded, true);\n console.log(\"Migration completed successfully\");\n } else {\n console.log(\"No pending migrations\");\n }\n await runner.close();\n break;\n\n case \"down\":\n const migrations_rollback = await runner.getMigrations();\n let downgraded = await migration_filter(migrations_rollback, true);\n\n downgraded = downgraded.reverse();\n\n if (args.flags.all) {\n // Roll back all migrations - use the full list\n } else {\n // Default to 1 migration if no increment specified\n const increment = parseInt(args.flags.increment || '1');\n downgraded = downgraded.slice(0, increment);\n }\n\n console.log(`Rolling back ${downgraded.length} migration(s)`);\n if (downgraded.length > 0) {\n for (const migration of downgraded) {\n console.log(` - ${migration.name}`);\n }\n\n await runner.migrate(downgraded, false);\n console.log(\"Rollback completed successfully\");\n } else {\n console.log(\"No migrations to roll back\");\n }\n\n await runner.close();\n break;\n\n case \"reset\":\n console.log(\"Resetting all migrations...\");\n await runner.reset();\n console.log(\"Reset completed successfully\");\n await runner.close();\n break;\n\n case \"create\":\n let filename = args.flags.name || commands[1];\n\n if (!filename) {\n throw new CLIError(\"Migration name is required\");\n }\n\n filename = filename.replace(/\\s/g, \"_\");\n runner.createMigration(filename);\n runner.close();\n break;\n\n case \"init\":\n await runner.init(config_file);\n runner.close();\n break;\n\n case \"status\":\n const { printTable } = require('console-table-printer');\n const migrations = await runner.getMigrations();\n\n console.log(\"Migration Status:\");\n\n const table = migrations.map(async m => {\n const status = await m.status();\n return {\n key: m.get_key(),\n status: status.completed ? \"completed\" : \"pending\",\n };\n });\n\n printTable(await Promise.all(table));\n runner.close();\n break;\n\n case \"query\":\n const sql_query = args.flags.query || commands[1];\n const format = (args.flags.format || 'table').toLowerCase();\n\n if (!sql_query) {\n throw new CLIError(\"SQL query is required. Usage: proper query \\\"SELECT * FROM table\\\"\");\n }\n\n // Validate that query is a SELECT or CTE (WITH) statement\n const trimmed_query = sql_query.trim().toUpperCase();\n const is_select = trimmed_query.startsWith('SELECT');\n const is_cte = trimmed_query.startsWith('WITH');\n\n if (!is_select && !is_cte) {\n throw new CLIError(\"Only SELECT queries and CTEs (WITH clauses) are allowed\");\n }\n\n // Block dangerous keywords\n const dangerous_keywords = ['INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER', 'TRUNCATE', 'GRANT', 'REVOKE'];\n const has_dangerous_keyword = dangerous_keywords.some(keyword => {\n // Check for keyword not as part of a word (word boundaries)\n const regex = new RegExp(`\\\\b${keyword}\\\\b`, 'i');\n return regex.test(sql_query);\n });\n\n if (has_dangerous_keyword) {\n throw new CLIError(\"Query contains disallowed keywords. Only SELECT and CTE queries are permitted\");\n }\n\n if (!['table', 'json'].includes(format)) {\n throw new CLIError(\"Invalid format. Use --format table or --format json\");\n }\n\n try {\n const [results] = await runner.query(sql_query);\n\n if (Array.isArray(results) && results.length > 0) {\n if (format === 'json') {\n console.log(JSON.stringify(results, null, 2));\n } else {\n const { printTable } = require('console-table-printer');\n printTable(results);\n }\n console.log(`\\nReturned ${results.length} row(s)`);\n } else if (Array.isArray(results) && results.length === 0) {\n console.log(\"Query returned 0 rows\");\n } else {\n console.log(\"Query executed successfully\");\n }\n } catch (error: any) {\n throw new CLIError(`Query execution failed: ${error.message}`);\n }\n\n await runner.close();\n break;\n\n case \"seed\": {\n const subCommands = commands.slice(1);\n const actionFlag = (args.flags.action || \"\").toString().toLowerCase();\n const firstSub = (subCommands[0] || \"\").toString().toLowerCase();\n\n const action = (actionFlag === \"down\" || firstSub === \"down\") ? \"down\" : \"up\";\n\n const positionalNames = actionFlag\n ? subCommands\n : (firstSub === \"up\" || firstSub === \"down\")\n ? subCommands.slice(1)\n : subCommands;\n\n const aliasFlag = args.flags.alias as string | string[] | undefined;\n const aliasMap: Record<string, string> = {};\n if (aliasFlag) {\n const aliases = Array.isArray(aliasFlag) ? aliasFlag : [aliasFlag];\n for (const entry of aliases) {\n const eq = entry.indexOf(\"=\");\n if (eq > 0) {\n const key = entry.slice(0, eq);\n const value = entry.slice(eq + 1);\n if (key) aliasMap[key] = value;\n }\n }\n }\n\n const seedOptions: SeedOptions = {\n migrationsDir: args.flags.migrationsDir || args.flags[\"migrations-dir\"],\n dataDir: args.flags.dataDir || args.flags[\"data-dir\"],\n validate: args.flags.validate === undefined\n ? true\n : String(args.flags.validate).toLowerCase() !== \"false\",\n transactional: args.flags.transactional,\n aliasMap: Object.keys(aliasMap).length ? aliasMap : undefined,\n names: positionalNames.length ? positionalNames : undefined,\n log: (msg: string) => console.log(msg),\n };\n\n const reader = new FileMigrationConfigReader(config_file);\n const migrationConfig = reader.loadFile();\n\n await runSeedsWithRunner(runner as any, migrationConfig, action, seedOptions);\n await runner.close();\n break;\n }\n\n default:\n throw CLIError.unknownCommand(command);\n }\n\n } catch (error: any) {\n console.error(`Error: ${error.message}`);\n if (error.stack && process.env.DEBUG) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n});\n\nfunction printUsage() {\n console.log(`\nSQL Proper - Database migration tool\n\nUsage:\n proper <command> [options]\n\nCommands:\n up Apply pending migrations\n down Roll back completed migrations\n reset Roll back all migrations and reapply them\n create Create a new migration\n init Initialize a new config file\n status Show migration status\n query Execute a SQL query and display results\n help Show this help message\n\nOptions:\n -c, --config Specify the config file (default: proper.json)\n --increment <n> Limit the number of migrations to apply or roll back\n --all Roll back all completed migrations (down command only)\n --format <fmt> Output format for query command: 'table' (default) or 'json'\n\nExamples:\n proper up Apply all pending migrations\n proper up --increment 1 Apply only the next pending migration\n proper down Roll back the last applied migration (default: 1)\n proper down --increment 3 Roll back the last 3 applied migrations\n proper down --all Roll back all completed migrations\n proper create my_migration Create a new migration named \"my_migration\"\n proper init Create a new config file\n proper status Show the status of all migrations\n proper query \"select * from users\" Execute a SQL query\n proper query \"select * from users\" --format json Execute a query and output as JSON\n proper -c custom.json up Use a custom config file\n `);\n}\n","import minimist from \"minimist\";\n\nexport class MigrationCLIFactory {\n /**\n * Parse command line arguments into commands and flags\n * @param argv Optional array of command line arguments. If not provided, process.argv will be used.\n * @returns Object containing parsed commands and flags\n */\n static setup(argv?: string[]): { commands: string[], flags: Record<string, any> } {\n // Use provided args or default to process.argv\n const args = argv || process.argv;\n \n // Determine where to start slicing the arguments\n // We need to handle different invocation patterns:\n // 1. node script.js command => skip 'node' and 'script.js' \n // 2. ./cli.js command => skip './cli.js'\n // 3. proper command => skip 'proper' (likely a symlink to the script)\n // 4. command arg1 arg2 => don't skip anything (direct command invocation)\n let startIndex = 0;\n \n // Check for node\n if (args[0]?.includes('node')) {\n startIndex = 2; // Skip 'node' and script name\n }\n // Check for script file extensions\n else if (args[0] && /\\.(js|ts|mjs|cjs)$/i.test(args[0])) {\n startIndex = 1; // Skip just the script name\n }\n // Check for command name that might be a symlink to this script\n else if (args[0] && ['proper', 'migration', 'sql-proper'].includes(args[0].toLowerCase())) {\n startIndex = 1; // Skip the command name\n }\n \n // Parse the arguments\n const cli = minimist(args.slice(startIndex), {\n alias: {\n c: 'config',\n },\n });\n\n const { _: commands, ...flags } = cli;\n\n return {\n commands,\n flags\n };\n }\n}","import { MigrationNode } from \"./MigrationNode\";\n\n\n\n\nexport async function migration_filter(migrations:MigrationNode[],completed:boolean=true,keep:MigrationNode[]=[]){\n if(migrations.length === 0){\n return keep\n }\n\n const [first,...rest] = migrations\n\n const status = await first.status()\n\n if(status.completed == completed){\n keep.push(first)\n }\n\n return migration_filter(rest,completed,keep)\n}","// Node built-in modules\nimport fs from 'fs';\n\n// Database drivers\nimport mysql from 'mysql2/promise';\nimport * as sqlite from 'sqlite';\nimport * as sqlite3 from 'sqlite3';\n\n// Helper function to convert any error to Error object\nfunction toError(error: unknown): Error {\n if (error instanceof Error) return error;\n return new Error(String(error));\n}\n\n// Migration framework\nimport { MigrationConfig } from \"./MigrationConfig\";\nimport { MigrationDirectoryReader } from './MigrationDirectoryReader';\nimport { MigrationNode } from './MigrationNode';\nimport { MigrationSetup } from './MigrationSetup';\nimport { migration_filter } from './MigrationFilter';\nimport * as dialect from \"./MigrationDialectParser\";\n\n\nimport { ISQLRunner,SQLRunner,SQLiteRunner } from './SQLRunner';\nimport { ErrorMessage } from './ErrorMessage';\nimport { \n ConfigurationError, \n DatabaseConnectionError, \n MigrationExecutionError,\n CLIError \n} from './errors';\n\n\nexport function loadMigrationConfig(configFile: string): MigrationConfig {\n const reader = new FileMigrationConfigReader(configFile);\n return reader.loadFile();\n}\n\nexport class MigrationRunnerFactory {\n\n private static isSQLRunner(conn: any): conn is ISQLRunner {\n return !!conn\n && typeof conn.query === \"function\"\n && typeof conn.execute === \"function\"\n && typeof conn.end === \"function\";\n }\n\n static async create(configFile:string,conn?:any){\n const configReader = new FileMigrationConfigReader(configFile);\n const config = configReader.loadFile();\n\n if(!conn){\n conn = await this.createConnection(config)\n }\n return new MigrationRunnerFactory().create(config,conn)\n }\n\n static async createConnection(config:MigrationConfig){\n let conn = null as any\n switch(config.database){\n case \"sql\":\n if (!config.sql){\n throw ConfigurationError.missingDatabaseConfiguration(\"sql\");\n }\n const settings = Object.assign({\n password:process.env.SQL_PASSWORD\n },config.sql);\n try {\n conn = await mysql.createConnection(settings);\n return conn;\n } catch (error) {\n throw DatabaseConnectionError.connectionFailed(\"sql\", toError(error).message);\n }\n case \"sqlite\":\n if (!config.sqlite){\n throw ConfigurationError.missingDatabaseConfiguration(\"sqlite\");\n }\n try {\n conn = await sqlite.open({\n filename:config.sqlite.database,\n driver:sqlite3.Database\n });\n return conn;\n } catch (error) {\n throw DatabaseConnectionError.connectionFailed(\"sqlite\", toError(error).message);\n }\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n \n }\n\n static async createEmpty(configFile:string){\n const configReader = new FileMigrationConfigReader(configFile);\n const config = configReader.loadFile();\n return new MigrationRunnerFactory().createEmpty(config)\n }\n\n\n async create(config:MigrationConfig,conn:any):Promise<MySQLMigrationRunner>{\n let sqlrunner:ISQLRunner;\n let driverConnection = conn;\n\n if (MigrationRunnerFactory.isSQLRunner(conn)) {\n sqlrunner = conn;\n driverConnection = null;\n } else {\n switch(config.database){\n case \"sql\":\n sqlrunner = new SQLRunner(conn)\n break;\n case \"sqlite\":\n sqlrunner = new SQLiteRunner(conn)\n break;\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n }\n const setup = new MigrationSetup(sqlrunner,config);\n const read_strategy = this.getReadStategy(config)\n\n const migration_files = new MigrationDirectoryReader(config.migration_folder,read_strategy,sqlrunner,config.database as 'sql' | 'sqlite')\n\n // Ensure the migrations infrastructure (i.e. the migrations table)\n // exists before we hand the runner back to the caller – most callers\n // expect the runner to be immediately usable without having to invoke\n // `setup()` manually. This is particularly important for projects\n // (like Groom) that directly call `getMigrations()` and\n // `migrate(...)` after obtaining the runner.\n await setup.setup();\n\n return new MySQLMigrationRunner(config,migration_files,setup,sqlrunner,driverConnection);\n }\n\n\n async createEmpty(config:MigrationConfig):Promise<MySQLMigrationRunner>{\n const conn = null as any\n let sqlrunner:ISQLRunner\n\n switch(config.database){\n case \"sql\":\n sqlrunner = new SQLRunner(conn)\n break;\n case \"sqlite\":\n sqlrunner = new SQLiteRunner(conn)\n break;\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n const setup = new MigrationSetup(sqlrunner,config);\n const read_strategy = this.getReadStategy(config)\n\n const migration_files = new MigrationDirectoryReader(config.migration_folder,read_strategy,sqlrunner,config.database as 'sql' | 'sqlite')\n return new MySQLMigrationRunner(config,migration_files,setup,sqlrunner,conn);\n }\n\n private getReadStategy(config:MigrationConfig){\n switch(config.database){\n case \"sql\":\n return dialect.MySqlDialectParser\n case \"sqlite\":\n return dialect.SqliteDialectParser\n default:\n throw ConfigurationError.unknownDatabaseType(config.database);\n }\n }\n}\n\n\nexport interface MigrationHistory{\n name:string\n up:string\n down:string\n}\n\nexport interface IMigrationRunner {\n setup(): Promise<void>;\n terminate(): Promise<void>;\n getMigrationsHistory(): Promise<MigrationHistory[]>;\n getMigrations(): Promise<MigrationNode[]>;\n getPendingMigrations(): Promise<MigrationNode[]>;\n getCompletedMigrations(): Promise<MigrationNode[]>;\n migrate(migrationNodes: MigrationNode[], forward: boolean): Promise<void>;\n reset(): Promise<void>;\n createMigration(name: string): void;\n close(): Promise<void>;\n init(config_file: string): Promise<void>;\n query(sql: string, params?: any[]): Promise<any>;\n}\n\nexport class MySQLMigrationRunner implements IMigrationRunner {\n constructor(\n private config:MigrationConfig,\n private directory:MigrationDirectoryReader,\n private setupRunner:MigrationSetup,\n private sqlrunner:ISQLRunner,\n private connection:mysql.Connection\n){\n\n }\n\n async setup(){\n try {\n await this.setupRunner.setup();\n } catch (error) {\n throw new MigrationExecutionError('Failed to set up migration database', undefined, undefined, toError(error));\n }\n }\n\n async terminate(){\n try {\n await this.setupRunner.teardown();\n } catch (error) {\n throw new MigrationExecutionError('Failed to tear down migration database', undefined, undefined, toError(error));\n }\n }\n\n async getMigrationsHistory():Promise<MigrationHistory[]>{\n try {\n const results = await this.sqlrunner.query(`\n select * \n from ${this.config.migration_table}\n `);\n return results[0] as any;\n } catch (error) {\n throw new MigrationExecutionError('Failed to get migration history', undefined, undefined, toError(error));\n }\n }\n\n\n async getMigrations(){\n try {\n return this.directory.loadMigrations(this.config.migration_table,this.connection);\n } catch (error) {\n throw new MigrationExecutionError('Failed to load migrations', undefined, undefined, toError(error));\n }\n }\n\n async getPendingMigrations(){\n try {\n const migrations = await this.getMigrations();\n return migration_filter(migrations,false);\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw error;\n }\n throw new MigrationExecutionError('Failed to get pending migrations', undefined, undefined, toError(error));\n }\n }\n\n async getCompletedMigrations(){\n try {\n const migrations = await this.getMigrations();\n return migration_filter(migrations,true);\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw error;\n }\n throw new MigrationExecutionError('Failed to get completed migrations', undefined, undefined, toError(error));\n }\n }\n\n async migrate(migrationNodes:MigrationNode[],forward:boolean):Promise<void>{\n for(let node of migrationNodes){\n try {\n if(forward){\n await node.up();\n }else{\n await node.down();\n }\n } catch (error) {\n throw new MigrationExecutionError(\n `Failed to ${forward ? 'apply' : 'rollback'} migration`,\n node.name || String(node),\n forward ? node.up_sql() : node.down_sql(),\n toError(error)\n );\n }\n }\n }\n\n\n async reset(){\n try {\n let migrations = await this.getMigrations();\n const rollback = await migration_filter(migrations,true);\n await this.migrate(rollback.reverse(),false);\n migrations = await this.getMigrations();\n const rollforward = await migration_filter(migrations,false);\n await this.migrate(rollforward,true);\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw error;\n }\n throw new MigrationExecutionError('Failed to reset migrations', undefined, undefined, toError(error));\n }\n }\n\n\n createMigration(name:string){\n try {\n const creator = new MigrationCreator(this.config);\n creator.create(name);\n } catch (error) {\n throw new MigrationExecutionError(`Failed to create migration: ${name}`, undefined, undefined, toError(error));\n }\n }\n\n\n async close(){\n if (this.sqlrunner) {\n try {\n await this.sqlrunner.end();\n } catch (error) {\n throw new DatabaseConnectionError(`Failed to close database connection: ${toError(error).message}`);\n }\n }\n }\n\n async query(sql: string, params?: any[]): Promise<any> {\n return await this.sqlrunner.query(sql, params);\n }\n\n async init(config_file:string){\n try {\n console.log(`Checking for ${config_file}`);\n const config_exist = fs.existsSync(config_file);\n\n if(!config_exist){\n console.log(`Creating ${config_file}`);\n const default_config = {\n \"migration_folder\":\"migrations\",\n \"migration_table\":\"proper_migrations\",\n \"database\": \"sql\",\n \"sql\":{\n \"host\":\"localhost\",\n \"user\":\"root\",\n \"database\":\"proper\",\n \"password\":\"\"\n }\n };\n fs.writeFileSync(config_file,JSON.stringify(default_config,null,2)); \n console.log(`Created ${config_file}`);\n }\n } catch (error) {\n throw new ConfigurationError(`Failed to initialize config file: ${toError(error).message}`);\n }\n }\n}\n\n\nexport class FileMigrationConfigReader{\n\n constructor(private configFile:string){\n\n }\n\n loadFile(){\n try {\n const fileContent = fs.readFileSync(this.configFile);\n const config:MigrationConfig = JSON.parse(fileContent.toString());\n \n // Validate required fields\n if (!config.migration_folder) {\n throw ConfigurationError.missingRequiredProperty('migration_folder');\n }\n \n if (!config.migration_table) {\n throw ConfigurationError.missingRequiredProperty('migration_table');\n }\n \n // For backward compatibility: if database type is omitted we derive\n // it from the presence of the dialect specific configuration\n // blocks. This keeps older `proper.json` files – that only defined\n // an \"sql\" or \"sqlite\" section – working without modification.\n if (!config.database) {\n if (config.sql) {\n config.database = 'sql';\n } else if (config.sqlite) {\n config.database = 'sqlite';\n } else {\n throw ConfigurationError.missingRequiredProperty('database');\n }\n }\n \n return config;\n } catch (error) {\n if (error instanceof ConfigurationError) {\n throw error;\n }\n const err = toError(error);\n if (err.message.includes('ENOENT')) {\n throw new ConfigurationError(`Config file not found: ${this.configFile}`);\n }\n throw new ConfigurationError(`Failed to load config file: ${err.message}`);\n }\n }\n}\n\n\nexport class MigrationCreator{\n constructor(private config:MigrationConfig){\n \n }\n\n\n create(name:string){\n if (!name) {\n throw new CLIError('Migration name is required');\n }\n\n try {\n // Ensure the migration folder exists\n if (!fs.existsSync(this.config.migration_folder)) {\n fs.mkdirSync(this.config.migration_folder, { recursive: true });\n }\n\n const now_timestamp = Date.now();\n\n const filename_up = `${now_timestamp}_${name}.up.sql`;\n const filename_down = `${now_timestamp}_${name}.down.sql`;\n\n fs.writeFileSync(`${this.config.migration_folder}/${filename_up}`,`\n-- Write your up migration here\n `.trim());\n\n fs.writeFileSync(`${this.config.migration_folder}/${filename_down}`,`\n-- Write your down migration here\n `.trim());\n \n console.log(`Created migration files:`);\n console.log(` ${filename_up}`);\n console.log(` ${filename_down}`);\n } catch (error) {\n if (error instanceof CLIError) {\n throw error;\n }\n throw new MigrationExecutionError(`Failed to create migration files: ${toError(error).message}`);\n }\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { MigrationNode } from './MigrationNode';\nimport { SqlMigrationBuilder } from './SqlMigrationBuilder';\nimport mysql from \"mysql2/promise\";\nimport { ISQLRunner } from \"./SQLRunner\";\n\n\nexport interface MigrationOptions{\n conn:mysql.Connection\n}\n\nexport class MigrationDirectoryReader {\n\n constructor(\n private directory: string,\n private read_strategy: any,\n private sqlrunner: ISQLRunner,\n private dialect: 'sql' | 'sqlite' = 'sql'\n ) {\n\n }\n\n /**\n * Resolves the appropriate file for a migration based on dialect.\n * Priority: dialect-specific file > generic file\n */\n private resolveFile(baseName: string, direction: 'up' | 'down'): string | null {\n const dialectExt = this.dialect === 'sql' ? 'mysql' : 'sqlite';\n\n // Priority 1: Dialect-specific file\n const dialectFile = path.join(this.directory, `${baseName}.${dialectExt}.${direction}.sql`);\n if (fs.existsSync(dialectFile)) return dialectFile;\n\n // Priority 2: Generic file\n const genericFile = path.join(this.directory, `${baseName}.${direction}.sql`);\n if (fs.existsSync(genericFile)) return genericFile;\n\n return null;\n }\n\n /**\n * Checks if a file path is dialect-specific (contains .mysql. or .sqlite. in the name)\n */\n private isDialectSpecific(filePath: string): boolean {\n return /\\.(mysql|sqlite)\\.(up|down)\\.sql$/i.test(filePath);\n }\n\n loadMigrations(table:string,connection:any):MigrationNode[] {\n\n fs.existsSync(this.directory) || fs.mkdirSync(this.directory);\n const dir_content = fs.readdirSync(this.directory,{withFileTypes:true}).filter(file=>file.isFile()).map(file=>file.name);\n\n // Extract unique migration keys (stripping dialect extensions)\n const uniqueKeys = new Set<string>();\n dir_content.forEach(file => {\n // Strip dialect extension (.mysql or .sqlite) and direction (.up or .down) to get base key\n const key = file.replace(/(?:\\.(mysql|sqlite))?\\.(up|down)\\.(sql|js)/i, \"\").toLowerCase();\n uniqueKeys.add(key);\n });\n\n const migration_sorter: any = {};\n\n // For each unique key, resolve the correct files based on dialect\n uniqueKeys.forEach((migration_key) => {\n const builder = new SqlMigrationBuilder(migration_key);\n\n const upFile = this.resolveFile(migration_key, 'up');\n const downFile = this.resolveFile(migration_key, 'down');\n\n if (upFile) {\n this.loadMigration(builder, upFile);\n }\n if (downFile) {\n this.loadMigration(builder, downFile);\n }\n\n migration_sorter[migration_key] = builder;\n });\n\n const keys = Object.keys(migration_sorter)\n\n keys.sort()\n\n const built = keys.map(key=>{\n return migration_sorter[key].build(table,this.sqlrunner)\n })\n return built\n\n }\n\n\n loadMigration(builder: SqlMigrationBuilder, file: string) {\n const is_sql = /sql$/i.test(file);\n const is_js = /js$/i.test(file);\n const is_up = /up\\.(js|sql)/i.test(file);\n const is_down = /down\\.(js|sql)/i.test(file);\n if (is_sql && is_up) {\n const content = this.sql_up(file);\n builder.set_up(file,content);\n } else if (is_sql && is_down) {\n const content = this.sql_down(file);\n builder.set_down(file,content);\n } else {\n throw new Error(`Invalid migration file: ${file}`);\n }\n return builder;\n }\n\n\n sql_up(file: string) {\n let content = fs.readFileSync(file).toString();\n // Dialect-specific files bypass read_strategy (no inline marker parsing needed)\n if (!this.isDialectSpecific(file)) {\n content = this.read_strategy(content);\n }\n return content.trim();\n }\n\n sql_down(file: string) {\n let content = fs.readFileSync(file).toString();\n // Dialect-specific files bypass read_strategy (no inline marker parsing needed)\n if (!this.isDialectSpecific(file)) {\n content = this.read_strategy(content);\n }\n return content.trim();\n }\n\n}\n","/**\n * Base class for all migration-related errors\n */\nexport class MigrationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MigrationError';\n // This is needed to make instanceof work correctly in ES5\n Object.setPrototypeOf(this, MigrationError.prototype);\n }\n}\n\n/**\n * Error thrown when there is an issue with the configuration\n */\nexport class ConfigurationError extends MigrationError {\n constructor(message: string) {\n super(`Configuration Error: ${message}`);\n this.name = 'ConfigurationError';\n Object.setPrototypeOf(this, ConfigurationError.prototype);\n }\n\n /**\n * Helper method for missing database configuration\n * @param dbType The database type (e.g., 'sql', 'sqlite')\n * @returns A ConfigurationError with appropriate message\n */\n static missingDatabaseConfiguration(dbType: string): ConfigurationError {\n return new ConfigurationError(`Missing ${dbType} configuration`);\n }\n\n /**\n * Helper method for unknown database type\n * @param dbType The unknown database type\n * @returns A ConfigurationError with appropriate message\n */\n static unknownDatabaseType(dbType: string): ConfigurationError {\n return new ConfigurationError(`Unknown database type: ${dbType}`);\n }\n\n /**\n * Helper method for missing required configuration properties\n * @param property The name of the missing property\n * @returns A ConfigurationError with appropriate message\n */\n static missingRequiredProperty(property: string): ConfigurationError {\n return new ConfigurationError(`Missing required property: ${property}`);\n }\n}\n\n/**\n * Error thrown when there is an issue with the database connection\n */\nexport class DatabaseConnectionError extends MigrationError {\n constructor(message: string) {\n super(`Database Connection Error: ${message}`);\n this.name = 'DatabaseConnectionError';\n Object.setPrototypeOf(this, DatabaseConnectionError.prototype);\n }\n\n /**\n * Helper method for connection errors\n * @param dbType The database type (e.g., 'sql', 'sqlite')\n * @param details Additional error details\n * @returns A DatabaseConnectionError with appropriate message\n */\n static connectionFailed(dbType: string, details?: string): DatabaseConnectionError {\n const message = details \n ? `Failed to connect to ${dbType} database: ${details}`\n : `Failed to connect to ${dbType} database`;\n return new DatabaseConnectionError(message);\n }\n\n /**\n * Helper method for authentication errors\n * @param dbType The database type (e.g., 'sql', 'sqlite')\n * @returns A DatabaseConnectionError with appropriate message\n */\n static authenticationFailed(dbType: string): DatabaseConnectionError {\n return new DatabaseConnectionError(`Authentication failed for ${dbType} database`);\n }\n}\n\n/**\n * Error thrown when there is an issue with executing a migration\n */\nexport class MigrationExecutionError extends MigrationError {\n constructor(\n message: string,\n public readonly migrationName?: string,\n public readonly sql?: string,\n public readonly originalError?: Error\n ) {\n /*\n * The public `message` that gets surfaced to callers **must not** include the\n * raw SQL text. The SQL string is already exposed through the dedicated\n * `sql` property and adding it to the message makes it unnecessarily noisy\n * and difficult to assert against in unit-tests. Therefore we only embed\n * the essential information (error type, optional migration name and the\n * short error message) in the main message string while keeping the full\n * SQL available separately.\n */\n let fullMessage = `Migration Execution Error${migrationName ? ` in '${migrationName}'` : ''}: ${message}`;\n\n if(originalError){\n fullMessage += `\\nOriginal Error:\\n${originalError.message}`;\n }\n\n super(fullMessage);\n this.name = 'MigrationExecutionError';\n Object.setPrototypeOf(this, MigrationExecutionError.prototype);\n }\n\n /**\n * Helper method for SQL execution errors\n * @param migrationName The name of the migration\n * @param sql The SQL that caused the error\n * @param originalError The original error thrown by the database driver\n * @returns A MigrationExecutionError with appropriate message\n */\n static sqlExecutionFailed(migrationName: string, sql: string, originalError: Error): MigrationExecutionError {\n return new MigrationExecutionError(\n originalError.message,\n migrationName,\n sql,\n originalError\n );\n }\n\n /**\n * Helper method for missing migration file errors\n * @param filename The missing file\n * @returns A MigrationExecutionError with appropriate message\n */\n static missingMigrationFile(filename: string): MigrationExecutionError {\n return new MigrationExecutionError(`Migration file not found: ${filename}`);\n }\n\n /**\n * Helper method for invalid migration file format errors\n * @param filename The invalid file\n * @param details Additional error details\n * @returns A MigrationExecutionError with appropriate message\n */\n static invalidMigrationFile(filename: string, details?: string): MigrationExecutionError {\n const message = details\n ? `Invalid migration file format in ${filename}: ${details}`\n : `Invalid migration file format in ${filename}`;\n return new MigrationExecutionError(message);\n }\n}\n\n/**\n * Error thrown when there is an issue with the migration CLI\n */\nexport class CLIError extends MigrationError {\n constructor(message: string) {\n super(`CLI Error: ${message}`);\n this.name = 'CLIError';\n Object.setPrototypeOf(this, CLIError.prototype);\n }\n\n /**\n * Helper method for missing command errors\n * @returns A CLIError with appropriate message\n */\n static missingCommand(): CLIError {\n return new CLIError('No command specified. Run with --help for usage information.');\n }\n\n /**\n * Helper method for unknown command errors\n * @param command The unknown command\n * @returns A CLIError with appropriate message\n */\n static unknownCommand(command: string): CLIError {\n return new CLIError(`Unknown command: ${command}. Run with --help for usage information.`);\n }\n\n /**\n * Helper method for missing required argument errors\n * @param argument The missing argument\n * @returns A CLIError with appropriate message\n */\n static missingRequiredArgument(argument: string): CLIError {\n return new CLIError(`Missing required argument: ${argument}`);\n }\n}\n","import { Connection } from 'mysql2/promise';\nimport { MigrationStatus } from './MigrationStatus';\nimport { ISQLRunner } from './SQLRunner';\nimport { MigrationExecutionError } from './errors';\n\nexport abstract class MigrationNode {\n name: string;\n\n constructor(name?: string) {\n this.name = name || '';\n }\n\n abstract get_key():string;\n abstract status(): Promise<MigrationStatus>;\n abstract up(): Promise<void>;\n abstract down(): Promise<void>;\n abstract up_sql(): string;\n abstract down_sql(): string;\n}\n\n\nexport class SqlMigrationNode extends MigrationNode {\n up_sql(): string {\n return this.sql_up;\n }\n down_sql(): string {\n return this.sql_down;\n }\n get_key(): string {\n return this.key;\n }\n\n constructor(private conn:ISQLRunner,\n private table:string, \n private key:string,\n private up_file:string,\n private sql_up:string,\n private down_file:string,\n private sql_down:string) {\n super(key);\n }\n\n async status(): Promise<MigrationStatus> {\n try {\n const result = await this.conn.query(`\n select * \n from ${this.table}\n where migration_key = ?;\n `, [this.key]);\n\n if(result.length > 0 && result[0].length > 0){\n return {\n completed: true\n };\n } else {\n return {\n completed: false\n };\n }\n } catch (error) {\n throw new MigrationExecutionError(\n `Error checking status for migration`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n async up(): Promise<void> {\n try {\n await this.conn.execute(this.sql_up);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing UP migration`,\n this.key,\n this.sql_up,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n \n try {\n await this.conn.execute(`\n insert into ${this.table} (migration_key,up,down)\n values (?,?,?)\n `, [this.key, this.up_file, this.down_file]);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error recording migration completion`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n async down(): Promise<void> {\n try {\n await this.conn.execute(this.sql_down);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing DOWN migration`,\n this.key,\n this.sql_down,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n \n try {\n await this.conn.execute(`\n delete from ${this.table}\n where migration_key = ?\n `, [this.key]);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error removing migration record`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n}\n\n\nexport class SqliteMigrationNode extends MigrationNode {\n up_sql(): string {\n return this.sql_up;\n }\n down_sql(): string {\n return this.sql_down;\n }\n constructor(\n private conn: ISQLRunner, // your SQLite runner\n private table: string,\n private key: string,\n private up_file: string,\n private sql_up: string,\n private down_file: string,\n private sql_down: string\n ) {\n super(key);\n }\n\n /**\n * Returns the unique key for this migration (e.g. timestamp + name).\n */\n get_key(): string {\n return this.key;\n }\n\n /**\n * Check if this migration is already completed by looking in the migration table.\n */\n async status(): Promise<MigrationStatus> {\n try {\n // Usually `this.conn.query(...)` returns an array of rows.\n // The first element might be the row set, depending on your runner.\n const cursor = await this.conn.query(\n `SELECT * FROM ${this.table} WHERE migration_key = ?;`,\n [this.key]\n );\n\n // Usually, `cursor[0]` is the row array in many MySQL runners;\n // In a SQLite scenario, it may be just `cursor`\n // So adjust depending on your actual runner's return shape.\n const rows = cursor[0] as any[];\n\n if (rows && rows.length > 0) {\n return { completed: true };\n } else {\n return { completed: false };\n }\n } catch (error) {\n throw new MigrationExecutionError(\n `Error checking status for migration`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n /**\n * Run the 'up' SQL, then record this migration in the table.\n */\n async up(): Promise<void> {\n try {\n // Execute the 'up' script\n await this.conn.execute(this.sql_up);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing UP migration`,\n this.key,\n this.sql_up,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n\n // Insert a record of this migration having completed\n try {\n await this.conn.execute(\n `\n INSERT INTO ${this.table} (migration_key, up, down)\n VALUES (?, ?, ?)\n `,\n [this.key, this.up_file, this.down_file]\n );\n } catch (error) {\n throw new MigrationExecutionError(\n `Error recording migration completion`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n /**\n * Run the 'down' SQL, then remove this migration record from the table.\n */\n async down(): Promise<void> {\n try {\n // Execute the 'down' script\n await this.conn.execute(this.sql_down);\n } catch (error) {\n throw new MigrationExecutionError(\n `Error executing DOWN migration`,\n this.key,\n this.sql_down,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n\n // Remove the migration from the table\n try {\n await this.conn.execute(\n `\n DELETE FROM ${this.table}\n WHERE migration_key = ?\n `,\n [this.key]\n );\n } catch (error) {\n throw new MigrationExecutionError(\n `Error removing migration record`,\n this.key,\n undefined,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n}","import { Connection } from 'mysql2/promise';\nimport { SqlMigrationNode } from './MigrationNode';\nimport { ISQLRunner } from './SQLRunner';\n\n\n\nexport class SqlMigrationBuilder {\n\n private up: string = '';\n private up_file: string = '';\n private down: string = '';\n private down_file: string = '';\n\n constructor(private key: string) {\n }\n\n set_up(file:string,up: string) {\n this.up_file = file;\n this.up = up;\n }\n\n set_down(file:string,down: string) {\n this.down_file = file;\n this.down = down;\n }\n\n build(table:string,conn: ISQLRunner) {\n return new SqlMigrationNode(conn, table,this.key, this.up_file, this.up, this.down_file,this.down);\n }\n}\n","import { MigrationConfig } from \"./MigrationConfig\";\nimport fs from \"fs\";\nimport { ISQLRunner } from './SQLRunner';\n\nexport class MigrationSetup {\n constructor(private sqlrunner: ISQLRunner, private config: MigrationConfig) {}\n\n\n async setup() {\n\n fs.existsSync(this.config.migration_folder) || fs.mkdirSync(this.config.migration_folder);\n\n const tableName = this.config.migration_table;\n\n // Use dialect-specific DDL so that the migrations table can be created\n // both in MySQL/MariaDB and in SQLite. The two dialects differ mainly\n // in the auto-increment syntax and the column types.\n const createTableSql = this.config.database === 'sqlite'\n ? `CREATE TABLE IF NOT EXISTS ${tableName} (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n migration_key TEXT,\n up TEXT,\n down TEXT,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )`\n : `CREATE TABLE IF NOT EXISTS ${tableName} (\n id INT AUTO_INCREMENT PRIMARY KEY,\n migration_key VARCHAR(255),\n up VARCHAR(255),\n down VARCHAR(255),\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )`;\n\n await this.sqlrunner.query(createTableSql);\n }\n\n async teardown() {\n await this.sqlrunner.execute(`DROP TABLE ${this.config.migration_table}`);\n }\n}\n\n\n\n\n","export function MySqlDialectParser(sql: string): string {\n const lines = sql.split('\\n');\n let result = '';\n \n // We start \"in MySQL\" so that lines before [sql] are kept.\n let isInMySQLBlock = true;\n \n // e.g. `-- [sql]`, `-- [ sql ]`, `-- [mysql]`, ignoring case/spaces\n const startSQLRegex = /^\\s*--\\s*\\[\\s*(sql|mysql)\\s*\\]\\s*$/i;\n // e.g. `-- [sqlite]`, `-- [ pg ]`, `-- [mydialect]` (any bracket means \"turn off MySQL\")\n const anyDialectRegex = /^\\s*--\\s*\\[\\s*\\w+\\s*\\]\\s*$/i;\n \n for (const line of lines) {\n const trimmed = line.trim();\n \n // If line is \" -- [sql] \" or \" -- [mysql] \", we *turn on* MySQL capturing:\n if (startSQLRegex.test(trimmed)) {\n isInMySQLBlock = true;\n // We also include this line in output\n result += line + '\\n';\n continue;\n }\n \n // If line is *some other* bracket, e.g. \" -- [sqlite] \"\n // then switch MySQL off, and do NOT keep that line\n if (anyDialectRegex.test(trimmed) && !startSQLRegex.test(trimmed)) {\n isInMySQLBlock = false;\n // Skip to next line\n continue;\n }\n \n // If we get here and see a line without a [dialect] marker,\n // and we were previously turned off because of non-mysql dialect,\n // then check if it's common SQL (like CREATE INDEX).\n // Turn MySQL back on for this line\n if (!isInMySQLBlock && line.toLowerCase().includes('create index')) {\n isInMySQLBlock = true;\n }\n \n // If we're in MySQL mode, keep the line\n if (isInMySQLBlock) {\n result += line + '\\n';\n }\n }\n \n return result;\n}\n\nexport function SqliteDialectParser(sql: string): string {\n const lines = sql.split('\\n');\n let result = '';\n let isInSqliteBlock = true;\n\n // Regex to detect a line that starts Sqlite code block:\n const startSqliteRegex = /^\\s*--\\s*\\[\\s*sqlite\\s*\\]\\s*$/i;\n const anyDialectRegex = /^\\s*--\\s*\\[\\s*\\w+\\s*\\]\\s*$/i;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (startSqliteRegex.test(trimmed)) {\n // If we see a \"-- [sqlite]\" line, start capturing\n isInSqliteBlock = true;\n result += line + '\\n';\n continue;\n } else if (anyDialectRegex.test(trimmed) && !startSqliteRegex.test(trimmed)) {\n // If we see a *different* bracket line, turn off capturing\n isInSqliteBlock = false;\n continue;\n }\n \n // If we get here and see a line without a [dialect] marker,\n // and we were previously turned off because of non-sqlite dialect,\n // then check if it's common SQL (like CREATE INDEX).\n // Turn SQLite back on for this line\n if (!isInSqliteBlock && line.toLowerCase().includes('create index')) {\n isInSqliteBlock = true;\n }\n \n // If we are in the Sqlite block, capture the line\n if (isInSqliteBlock) {\n result += line + '\\n';\n }\n }\n \n return result;\n}","\nimport * as sqlite from 'sqlite';\nimport { Statement } from 'sqlite3';\nimport mysql from 'mysql2/promise';\n\n\n\ntype QueryResult = {\n stmt: Statement;\n lastID: number;\n changes: number;\n}\n\nexport interface ISQLRunner {\n query(sql: string, params?: any[]): Promise<any>;\n execute(sql: string, params?: any[]): Promise<any>;\n end(): Promise<void>;\n}\n\n/**\n * Base class that implements the common contract and helper utilities that are\n * shared between the different dialect runners. The concrete subclasses only\n * need to implement the three primitive methods `_query`, `_execute` and\n * `_end` that perform the actual driver-specific interaction. Everything else\n * – such as ensuring a uniform return shape – is handled here once.\n */\nexport abstract class BaseSQLRunner implements ISQLRunner {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n abstract _query(sql: string, params?: any[]): Promise<any>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n abstract _execute(sql: string, params?: any[]): Promise<any>;\n abstract _end(): Promise<void>;\n\n /**\n * Ensures that both MySQL and SQLite return the same tuple shape that callers\n * expect: `[rowsOrResult, extra]`. For SQLite there is no `extra` metadata\n * comparable to MySQL's `FieldPacket[]`, so we just use `undefined`.\n */\n async query(sql: string, params: any[] = []): Promise<any> {\n const result = await this._query(sql, params);\n\n // MySQL already returns the desired tuple. For SQLite we need to wrap.\n return Array.isArray(result) && result.length === 2 ? result : [result, undefined];\n }\n\n async execute(sql: string, params: any[] = []): Promise<any> {\n const result = await this._execute(sql, params);\n return Array.isArray(result) && result.length === 2 ? result : [result, undefined];\n }\n\n async end(): Promise<void> {\n await this._end();\n }\n}\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === \"function\";\n}\n\nexport class SQLRunner extends BaseSQLRunner {\n constructor(private connection: mysql.Connection) {\n super();\n }\n\n // The MySQL driver already returns the correct tuple shapes.\n async _query(sql: string, params: any[] = []) {\n return await this.connection.query(sql, params);\n }\n\n async _execute(sql: string, params: any[] = []) {\n return await this.connection.execute(sql, params);\n }\n\n async _end() {\n if (this.connection) {\n await this.connection.end();\n }\n }\n}\n\nexport class SQLiteRunner extends BaseSQLRunner {\n constructor(private connection: sqlite.Database | any) {\n super();\n }\n\n private async prepareStatement(sql: string) {\n if (typeof this.connection.prepare !== \"function\") {\n throw new Error(\"SQLite connection does not support prepare()\");\n }\n const stmt = this.connection.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n }\n\n private async finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== \"function\") return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n }\n\n private async statementAll(stmt: any, params: any[]) {\n if (typeof stmt.all !== \"function\") {\n throw new Error(\"SQLite statement does not support all()\");\n }\n // sqlite3 callback-style API\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...params);\n return isPromiseLike(result) ? await result : result;\n }\n\n private async statementRun(stmt: any, params: any[]) {\n if (typeof stmt.run !== \"function\") {\n throw new Error(\"SQLite statement does not support run()\");\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastID: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...params);\n return isPromiseLike(result) ? await result : result;\n }\n\n async _query(sql: string, params: any[] = []) {\n const stmt = await this.prepareStatement(sql);\n try {\n const rows = await this.statementAll(stmt, params);\n return rows;\n } finally {\n await this.finalizeStatement(stmt);\n }\n }\n\n async _execute(sql: string, params: any[] = []) {\n // Handle empty or comment-only SQL gracefully\n if (this.isEmptySQL(sql)) {\n return { changes: 0, lastID: 0 }; // No-op result\n }\n\n if (this.isMultiStatement(sql)) {\n return await this.executeMultiStatement(sql, params)\n .catch((err) => {\n console.error((\n \"Error executing multi-statement SQL:\\n\"+\n `${sql}\\n`\n ), err);\n throw err;\n });\n }\n\n const stmt = await this.prepareStatement(sql);\n try {\n const info = await this.statementRun(stmt, params);\n return info;\n } finally {\n await this.finalizeStatement(stmt);\n }\n }\n\n /**\n * Checks if SQL is empty or contains only comments/whitespace.\n * Returns true if there is no actual SQL to execute.\n */\n private isEmptySQL(sql: string): boolean {\n // Remove all comments and whitespace\n const withoutComments = sql\n .replace(/--.*$/gm, '') // Remove single-line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Remove multi-line comments\n .trim();\n return withoutComments.length === 0;\n }\n\n private isMultiStatement(sql: string): boolean {\n // SQLite does not support multiple statements in a single query.\n return sql.split(';').length > 1;\n }\n\n private async executeMultiStatement(sql: string, params: any[] = []) {\n const statements = sql.split(';')\n .map((s) => s.split('\\n')\n .map(\n s=>this.removeComments(s))\n .filter(s=>s.trim()!='')\n .join('\\n')\n )\n .filter((s) => s.trim() !== '');\n \n const infos = await statements.reduce(async (prev,statement) => {\n const infos = await prev;\n const stmt = await this.prepareStatement(`${statement};`);\n try {\n const info = await this.statementRun(stmt, params);\n infos.push(info);\n return infos;\n } finally {\n await this.finalizeStatement(stmt);\n }\n },Promise.resolve([null] as any[]))\n .then((infos:QueryResult[]) => {\n return infos.filter((info) => info !== null);\n })\n return infos.reduce((acc,latest)=>{\n if(latest){\n acc.stmt = latest.stmt;\n acc.lastID = latest.lastID;\n acc.changes += latest.changes;\n }\n return acc\n })\n }\n\n private removeComments(sql: string): string {\n // Remove single-line comments\n sql = sql.replace(/--.*$/gm, '');\n return sql;\n }\n\n\n async _end() {\n if (this.connection) {\n await this.connection.close();\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\n\nimport type { IMigrationRunner, MigrationHistory } from './MigrationRunner';\nimport { MigrationRunnerFactory, FileMigrationConfigReader, loadMigrationConfig } from './MigrationRunner';\nimport type { MigrationConfig } from './MigrationConfig';\n\nexport type SeedTransactionalMode = 'runner' | 'seed' | 'none';\n\nexport type SeedOptions = {\n migrationsDir?: string;\n dataDir?: string;\n validate?: boolean;\n transactional?: SeedTransactionalMode;\n aliasMap?: Record<string, string>;\n preloadedData?: Record<string, unknown>;\n log?: (msg: string) => void;\n names?: string[];\n};\n\nexport type ResolvedSeed = {\n kind: 'sql' | 'ts' | 'js';\n name: string;\n alias: string;\n upPath: string;\n downPath?: string;\n dataPath: string | null;\n schemaPath: string | null;\n};\n\nfunction resolveAlias(name: string, aliasMap?: Record<string, string>): string {\n if (!aliasMap) return name;\n return aliasMap[name] ?? name;\n}\n\nfunction walkForFile(rootDir: string, fileName: string): string | null {\n if (!fs.existsSync(rootDir)) return null;\n const entries = fs.readdirSync(rootDir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(rootDir, entry.name);\n if (entry.isDirectory()) {\n const found = walkForFile(full, fileName);\n if (found) return found;\n } else if (entry.isFile() && entry.name === fileName) {\n return full;\n }\n }\n return null;\n}\n\nfunction resolveMigrationsDir(migrationConfig: MigrationConfig, options: SeedOptions): string {\n const fromOptions = options.migrationsDir;\n const fromConfig = migrationConfig.seeds?.migrationsDir;\n\n const dir = fromOptions ?? fromConfig;\n if (!dir) {\n throw new Error('Seed migrationsDir not configured. Set seeds.migrationsDir in proper.json or pass it explicitly.');\n }\n return dir;\n}\n\nfunction mergeSeedConfig(\n migrationConfig: MigrationConfig,\n options: SeedOptions,\n): { names: string[]; finalOptions: SeedOptions & { migrationsDir: string; validate: boolean; transactional: SeedTransactionalMode } } {\n const names = options.names && options.names.length\n ? options.names\n : migrationConfig.seeds?.list && migrationConfig.seeds.list.length\n ? migrationConfig.seeds.list\n : [];\n\n if (!names.length) {\n throw new Error('No seed names provided and no seeds.list defined in proper config');\n }\n\n const migrationsDir = resolveMigrationsDir(migrationConfig, options);\n const dataDir = options.dataDir ?? migrationConfig.seeds?.dataDir;\n const validate = options.validate !== undefined ? options.validate : true;\n const transactional = options.transactional ?? 'none';\n\n const finalOptions: SeedOptions & { migrationsDir: string; validate: boolean; transactional: SeedTransactionalMode } = {\n ...options,\n migrationsDir,\n dataDir,\n validate,\n transactional,\n };\n\n return { names, finalOptions };\n}\n\n// export function loadMigrationConfig(configFile: string): MigrationConfig {\n// const reader = new FileMigrationConfigReader(configFile);\n// return reader.loadFile();\n// }\n\nfunction resolveSqlPair(name: string, migrationsDir: string): { upPath: string; downPath: string } | null {\n const up = walkForFile(migrationsDir, `${name}.up.sql`);\n const down = walkForFile(migrationsDir, `${name}.down.sql`);\n if (up && down) {\n return { upPath: up, downPath: down };\n }\n return null;\n}\n\nfunction resolveModule(name: string, migrationsDir: string): { kind: 'ts' | 'js'; modulePath: string } | null {\n const ts = walkForFile(migrationsDir, `${name}.ts`);\n if (ts) return { kind: 'ts', modulePath: ts };\n const js = walkForFile(migrationsDir, `${name}.js`);\n if (js) return { kind: 'js', modulePath: js };\n return null;\n}\n\nexport async function resolveSeed(\n name: string,\n migrationConfig: MigrationConfig,\n options: SeedOptions,\n): Promise<ResolvedSeed> {\n const migrationsDir = resolveMigrationsDir(migrationConfig, options);\n const alias = resolveAlias(name, options.aliasMap);\n\n const sqlPair = resolveSqlPair(name, migrationsDir);\n if (sqlPair) {\n return {\n kind: 'sql',\n name,\n alias,\n upPath: sqlPair.upPath,\n downPath: sqlPair.downPath,\n dataPath: null,\n schemaPath: null,\n };\n }\n\n const module = resolveModule(name, migrationsDir);\n if (!module) {\n throw new Error(`Seed implementation not found for \"${name}\" under ${migrationsDir}`);\n }\n\n const dataDir = options.dataDir ?? migrationConfig.seeds?.dataDir;\n let dataPath: string | null = null;\n let schemaPath: string | null = null;\n\n if (dataDir) {\n dataPath = walkForFile(dataDir, `${alias}.json`);\n schemaPath = walkForFile(dataDir, `${alias}.schema.json`);\n }\n\n return {\n kind: module.kind,\n name,\n alias,\n upPath: module.modulePath,\n downPath: module.modulePath,\n dataPath,\n schemaPath,\n };\n}\n\nasync function loadJson(filePath: string): Promise<unknown> {\n const content = await fs.promises.readFile(filePath, 'utf8');\n return JSON.parse(content);\n}\n\nfunction createValidator() {\n const ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(ajv);\n return ajv;\n}\n\nasync function validateData(schemaPath: string | null, data: unknown, validate: boolean, log?: (msg: string) => void) {\n if (!validate || !schemaPath) return;\n const content = await fs.promises.readFile(schemaPath, 'utf8');\n const schema = JSON.parse(content);\n const ajv = createValidator();\n const validateFn = ajv.compile(schema);\n const ok = validateFn(data);\n if (!ok) {\n log?.(`Validation failed for seed data (${schemaPath})`);\n throw new Error(`Seed data validation failed: ${ajv.errorsText(validateFn.errors || [])}`);\n }\n}\n\nasync function runSqlSeed(\n runner: IMigrationRunner,\n resolved: ResolvedSeed,\n direction: 'up' | 'down',\n): Promise<void> {\n const sqlPath = direction === 'up' ? resolved.upPath : resolved.downPath!;\n const sql = await fs.promises.readFile(sqlPath, 'utf8');\n await runner.query(sql);\n}\n\nexport type SeedContext = {\n data: unknown;\n log?: (msg: string) => void;\n dialect: string;\n};\n\nasync function loadSeedModule(modulePath: string): Promise<any> {\n const resolved = path.resolve(modulePath);\n // Use dynamic import for all module types (works in both ESM and CJS contexts)\n return import(resolved);\n}\n\nasync function runModuleSeed(\n runner: IMigrationRunner,\n resolved: ResolvedSeed,\n migrationConfig: MigrationConfig,\n options: SeedOptions & { validate: boolean },\n direction: 'up' | 'down',\n): Promise<void> {\n const { log } = options;\n const module = await loadSeedModule(resolved.upPath);\n const handler = module[direction];\n if (typeof handler !== 'function') {\n throw new Error(`Seed module \"${resolved.name}\" does not export ${direction}()`);\n }\n\n let data: unknown = null;\n if (options.preloadedData && Object.prototype.hasOwnProperty.call(options.preloadedData, resolved.name)) {\n data = options.preloadedData[resolved.name];\n } else if (resolved.dataPath) {\n data = await loadJson(resolved.dataPath);\n }\n\n await validateData(resolved.schemaPath, data, options.validate, log);\n\n const ctx: SeedContext = {\n data,\n log,\n dialect: migrationConfig.database || 'sql',\n };\n\n await handler(runner, ctx);\n}\n\nasync function runSingleSeed(\n runner: IMigrationRunner,\n migrationConfig: MigrationConfig,\n name: string,\n options: SeedOptions & { validate: boolean; transactional: SeedTransactionalMode },\n direction: 'up' | 'down',\n): Promise<void> {\n const resolved = await resolveSeed(name, migrationConfig, options);\n\n if (resolved.kind === 'sql') {\n await runSqlSeed(runner, resolved, direction);\n } else {\n await runModuleSeed(runner, resolved, migrationConfig, options, direction);\n }\n}\n\nasync function withTransactionalMode(\n runner: IMigrationRunner,\n migrationConfig: MigrationConfig,\n names: string[],\n options: SeedOptions & { validate: boolean; transactional: SeedTransactionalMode },\n direction: 'up' | 'down',\n): Promise<void> {\n const mode = options.transactional;\n\n if (mode === 'runner') {\n await runner.query('BEGIN');\n try {\n for (const name of names) {\n await runSingleSeed(runner, migrationConfig, name, options, direction);\n }\n await runner.query('COMMIT');\n } catch (err) {\n try {\n await runner.query('ROLLBACK');\n } catch {\n }\n throw err;\n }\n return;\n }\n\n if (mode === 'seed') {\n for (const name of names) {\n await runner.query('BEGIN');\n try {\n await runSingleSeed(runner, migrationConfig, name, options, direction);\n await runner.query('COMMIT');\n } catch (err) {\n try {\n await runner.query('ROLLBACK');\n } catch {\n }\n throw err;\n }\n }\n return;\n }\n\n for (const name of names) {\n await runSingleSeed(runner, migrationConfig, name, options, direction);\n }\n}\n\nexport async function runSeedsWithRunner(\n runner: IMigrationRunner,\n migrationConfig: MigrationConfig,\n direction: 'up' | 'down',\n options: SeedOptions,\n): Promise<void> {\n const { names, finalOptions } = mergeSeedConfig(migrationConfig, options);\n await withTransactionalMode(runner, migrationConfig, names, finalOptions, direction);\n}\n\nexport type SeedFactoryOptions = SeedOptions & {\n configFile?: string;\n};\n\nexport type SeedFactory = {\n up(names?: string[]): Promise<void>;\n down(names?: string[]): Promise<void>;\n};\n\nexport function createSeedFactory(options: SeedFactoryOptions): SeedFactory {\n const configFile = options.configFile ?? 'proper.json';\n\n return {\n async up(names?: string[]) {\n const runner = await MigrationRunnerFactory.create(configFile);\n const migrationConfig = loadMigrationConfig(configFile);\n try {\n await runSeedsWithRunner(runner, migrationConfig, 'up', {\n ...options,\n names: names && names.length ? names : options.names,\n });\n } finally {\n await runner.close();\n }\n },\n\n async down(names?: string[]) {\n const runner = await MigrationRunnerFactory.create(configFile);\n const migrationConfig = loadMigrationConfig(configFile);\n try {\n await runSeedsWithRunner(runner, migrationConfig, 'down', {\n ...options,\n names: names && names.length ? names : options.names,\n });\n } finally {\n await runner.close();\n }\n },\n };\n}\n"],"mappings":"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","names":["args","minimist","commands","import_fs","command","path","fs","import_fs","fs","s","infos","mysql","config_file","fs","import_fs","import_path","fs","path","module","Ajv","addFormats","printTable"]}
|
package/bin/cli.mjs
CHANGED
|
@@ -746,6 +746,9 @@ var init_SQLRunner = __esm({
|
|
|
746
746
|
}
|
|
747
747
|
_execute(_0) {
|
|
748
748
|
return __async(this, arguments, function* (sql, params = []) {
|
|
749
|
+
if (this.isEmptySQL(sql)) {
|
|
750
|
+
return { changes: 0, lastID: 0 };
|
|
751
|
+
}
|
|
749
752
|
if (this.isMultiStatement(sql)) {
|
|
750
753
|
return yield this.executeMultiStatement(sql, params).catch((err) => {
|
|
751
754
|
console.error(`Error executing multi-statement SQL:
|
|
@@ -763,6 +766,14 @@ ${sql}
|
|
|
763
766
|
}
|
|
764
767
|
});
|
|
765
768
|
}
|
|
769
|
+
/**
|
|
770
|
+
* Checks if SQL is empty or contains only comments/whitespace.
|
|
771
|
+
* Returns true if there is no actual SQL to execute.
|
|
772
|
+
*/
|
|
773
|
+
isEmptySQL(sql) {
|
|
774
|
+
const withoutComments = sql.replace(/--.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").trim();
|
|
775
|
+
return withoutComments.length === 0;
|
|
776
|
+
}
|
|
766
777
|
isMultiStatement(sql) {
|
|
767
778
|
return sql.split(";").length > 1;
|
|
768
779
|
}
|
|
@@ -1316,9 +1327,6 @@ function runSqlSeed(runner, resolved, direction) {
|
|
|
1316
1327
|
function loadSeedModule(modulePath) {
|
|
1317
1328
|
return __async(this, null, function* () {
|
|
1318
1329
|
const resolved = path2.resolve(modulePath);
|
|
1319
|
-
if (resolved.endsWith(".ts")) {
|
|
1320
|
-
return __require(resolved);
|
|
1321
|
-
}
|
|
1322
1330
|
return import(resolved);
|
|
1323
1331
|
});
|
|
1324
1332
|
}
|