#!/usr/bin/env node // mysql-CLI-compatible shim for harness (CODEX_HARNESS_MYSQL) on hosts without a mysql client. // Supports the subset harness uses: -h HOST -u USER [-N] [--flags] [DATABASE] [-e SQL | stdin]. import fs from 'node:fs'; import { createRequire } from 'node:module'; import { pathToFileURL } from 'node:url'; export function parseArgs(argv) { const opts = { host: '', user: '', database: '', sql: '', noHeaders: false }; for (let i = 0; i < argv.length; i += 1) { const arg = argv[i]; if (arg === '-h' && i + 1 < argv.length) { opts.host = argv[++i]; } else if (arg === '-u' && i + 1 < argv.length) { opts.user = argv[++i]; } else if (arg === '-N') { opts.noHeaders = true; } else if (arg === '-e' && i + 1 < argv.length) { opts.sql = argv[++i]; } else if (!arg.startsWith('-') && !opts.database) { opts.database = arg; } } return opts; } export function resolveMysql2Module(env = process.env, requireFrom = import.meta.url) { const explicit = String(env.MEMIND_MYSQL2_MODULE || '').trim(); if (explicit) return explicit; return createRequire(requireFrom).resolve('mysql2/promise'); } // With rowsAsArray, a row set is an array of rows and each row is an array of scalar cells. // Multi-statement results are an array of row sets and ResultSetHeader objects. const isRow = (value) => Array.isArray(value) && value.every((cell) => !Array.isArray(cell)); const isRowSet = (value) => Array.isArray(value) && value.every(isRow); export function findLastRowSet(result) { if (isRowSet(result)) return result; if (!Array.isArray(result)) return null; for (let i = result.length - 1; i >= 0; i -= 1) { if (isRowSet(result[i])) return result[i]; } return null; } export function formatRows(rows) { if (!rows || rows.length === 0) return ''; const lines = rows.map((row) => { const values = Array.isArray(row) ? row : Object.values(row); return values.map((value) => (value == null ? 'NULL' : String(value))).join('\t'); }); return `${lines.join('\n')}\n`; } async function main() { const opts = parseArgs(process.argv.slice(2)); const sql = opts.sql || fs.readFileSync(0, 'utf8'); const modulePath = resolveMysql2Module(); const mysqlModule = await import(pathToFileURL(modulePath).href); const mysql = mysqlModule.default ?? mysqlModule; const connection = await mysql.createConnection({ host: opts.host || process.env.CODEX_HARNESS_DB_HOST || '127.0.0.1', user: opts.user || process.env.CODEX_HARNESS_DB_USER || 'boot', password: process.env.MYSQL_PWD || process.env.CODEX_HARNESS_DB_PASSWORD || '', database: opts.database || undefined, charset: 'utf8mb4', multipleStatements: true, rowsAsArray: true, }); try { const [result] = await connection.query({ sql, rowsAsArray: true }); process.stdout.write(formatRows(findLastRowSet(result))); } finally { await connection.end(); } } if (import.meta.url === pathToFileURL(process.argv[1] ?? '').href) { main().catch((error) => { process.stderr.write(`${error?.code ? `${error.code}: ` : ''}${error?.message ?? error}\n`); process.exit(1); }); }