{"version":3,"file":"db-repair.mjs","names":[],"sources":["../../src/cli/db-repair.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { type DoctorReport, diagnosePlugin } from \"./db-doctor\";\nimport type { PluginDbInfo } from \"./db-studio\";\n\nexport interface RepairResult {\n  status: \"repaired\" | \"refused\" | \"error\";\n  diagnosis: DoctorReport;\n  message: string;\n}\n\nexport async function repairPlugin(\n  info: PluginDbInfo,\n  mode: \"history-reset\" | \"recreate\",\n): Promise<RepairResult> {\n  const diagnosis = await diagnosePlugin(info);\n\n  if (diagnosis.diagnosis === \"error\") {\n    return {\n      status: \"refused\",\n      diagnosis,\n      message: `Cannot repair — diagnosis failed: ${diagnosis.error}`,\n    };\n  }\n\n  if (mode === \"recreate\") {\n    return {\n      status: \"refused\",\n      diagnosis,\n      message:\n        \"Recreate mode is not supported without per-plugin schemas. Use --mode history-reset instead.\",\n    };\n  }\n\n  if (diagnosis.diagnosis !== \"drift-safe-repair\" && diagnosis.diagnosis !== \"legacy-importable\") {\n    if (diagnosis.diagnosis === \"healthy\") {\n      return { status: \"refused\", diagnosis, message: \"Database is healthy — no repair needed.\" };\n    }\n    if (diagnosis.diagnosis === \"no-local-migrations\") {\n      return {\n        status: \"refused\",\n        diagnosis,\n        message: \"No local migrations found for this plugin.\",\n      };\n    }\n    if (diagnosis.diagnosis === \"drift-manual\") {\n      return {\n        status: \"refused\",\n        diagnosis,\n        message:\n          `Partial drift detected (${diagnosis.missingTables.length}/${diagnosis.expectedTables.length} tables missing). ` +\n          \"Manual intervention required — some tables exist but schema is incomplete.\",\n      };\n    }\n    if (diagnosis.diagnosis === \"unapplied\") {\n      return {\n        status: \"refused\",\n        diagnosis,\n        message: \"Migrations have not been applied yet. Start the dev server to apply them.\",\n      };\n    }\n    return {\n      status: \"refused\",\n      diagnosis,\n      message: `Cannot repair — diagnosis: ${diagnosis.diagnosis}`,\n    };\n  }\n\n  const { Pool } = await import(\"pg\");\n  const journalRef = `\"${diagnosis.journalSchema}\".\"${diagnosis.journalTable}\"`;\n  const pool = new Pool({\n    connectionString: info.databaseUrl,\n    ssl:\n      info.databaseUrl.includes(\"localhost\") || info.databaseUrl.includes(\"127.0.0.1\")\n        ? false\n        : { rejectUnauthorized: false },\n    max: 1,\n    connectionTimeoutMillis: 10_000,\n  });\n\n  try {\n    await pool.query(`DROP TABLE IF EXISTS ${journalRef}`);\n  } catch (error) {\n    return {\n      status: \"error\",\n      diagnosis,\n      message: `Failed to reset journal: ${error instanceof Error ? error.message : String(error)}`,\n    };\n  } finally {\n    await pool.end().catch(() => {});\n  }\n\n  if (info.workspaceDir) {\n    const configPath = join(info.workspaceDir, \"drizzle.config.ts\");\n    if (existsSync(configPath)) {\n      try {\n        await spawnDrizzleMigrate(info.workspaceDir, configPath);\n        return {\n          status: \"repaired\",\n          diagnosis,\n          message:\n            `Migration history reset for ${diagnosis.plugin}. ` +\n            `Migrations reapplied via drizzle-kit. Restart the dev server to confirm.`,\n        };\n      } catch (error) {\n        return {\n          status: \"repaired\",\n          diagnosis,\n          message:\n            `Migration history reset for ${diagnosis.plugin}. ` +\n            `Automatic reapply failed: ${error instanceof Error ? error.message : String(error)}. ` +\n            `Run \\`bun run --cwd ${info.workspaceDir} db:migrate\\` manually.`,\n        };\n      }\n    }\n  }\n\n  return {\n    status: \"repaired\",\n    diagnosis,\n    message:\n      `Migration history reset for ${diagnosis.plugin}. ` +\n      \"No local drizzle.config.ts found — start the dev server to reapply migrations.\",\n  };\n}\n\nfunction spawnDrizzleMigrate(cwd: string, configPath: string): Promise<void> {\n  return new Promise((resolvePromise, reject) => {\n    const child = spawn(\"npx\", [\"drizzle-kit\", \"migrate\", \"--config\", configPath], {\n      cwd,\n      stdio: \"pipe\",\n      shell: true,\n    });\n\n    let stderr = \"\";\n    child.stderr?.on(\"data\", (data: Buffer) => {\n      stderr += data.toString();\n    });\n\n    child.on(\"error\", (err) => reject(err));\n\n    child.on(\"exit\", (code) => {\n      if (code === 0) {\n        resolvePromise();\n      } else {\n        reject(new Error(`drizzle-kit migrate exited with code ${code}: ${stderr}`));\n      }\n    });\n  });\n}\n"],"mappings":";;;;;;AAYA,eAAsB,aACpB,MACA,MACuB;CACvB,MAAM,YAAY,MAAM,eAAe,KAAK;AAE5C,KAAI,UAAU,cAAc,QAC1B,QAAO;EACL,QAAQ;EACR;EACA,SAAS,qCAAqC,UAAU;EACzD;AAGH,KAAI,SAAS,WACX,QAAO;EACL,QAAQ;EACR;EACA,SACE;EACH;AAGH,KAAI,UAAU,cAAc,uBAAuB,UAAU,cAAc,qBAAqB;AAC9F,MAAI,UAAU,cAAc,UAC1B,QAAO;GAAE,QAAQ;GAAW;GAAW,SAAS;GAA2C;AAE7F,MAAI,UAAU,cAAc,sBAC1B,QAAO;GACL,QAAQ;GACR;GACA,SAAS;GACV;AAEH,MAAI,UAAU,cAAc,eAC1B,QAAO;GACL,QAAQ;GACR;GACA,SACE,2BAA2B,UAAU,cAAc,OAAO,GAAG,UAAU,eAAe,OAAO;GAEhG;AAEH,MAAI,UAAU,cAAc,YAC1B,QAAO;GACL,QAAQ;GACR;GACA,SAAS;GACV;AAEH,SAAO;GACL,QAAQ;GACR;GACA,SAAS,8BAA8B,UAAU;GAClD;;CAGH,MAAM,EAAE,SAAS,MAAM,OAAO;CAC9B,MAAM,aAAa,IAAI,UAAU,cAAc,KAAK,UAAU,aAAa;CAC3E,MAAM,OAAO,IAAI,KAAK;EACpB,kBAAkB,KAAK;EACvB,KACE,KAAK,YAAY,SAAS,YAAY,IAAI,KAAK,YAAY,SAAS,YAAY,GAC5E,QACA,EAAE,oBAAoB,OAAO;EACnC,KAAK;EACL,yBAAyB;EAC1B,CAAC;AAEF,KAAI;AACF,QAAM,KAAK,MAAM,wBAAwB,aAAa;UAC/C,OAAO;AACd,SAAO;GACL,QAAQ;GACR;GACA,SAAS,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAC5F;WACO;AACR,QAAM,KAAK,KAAK,CAAC,YAAY,GAAG;;AAGlC,KAAI,KAAK,cAAc;EACrB,MAAM,aAAa,KAAK,KAAK,cAAc,oBAAoB;AAC/D,MAAI,WAAW,WAAW,CACxB,KAAI;AACF,SAAM,oBAAoB,KAAK,cAAc,WAAW;AACxD,UAAO;IACL,QAAQ;IACR;IACA,SACE,+BAA+B,UAAU,OAAO;IAEnD;WACM,OAAO;AACd,UAAO;IACL,QAAQ;IACR;IACA,SACE,+BAA+B,UAAU,OAAO,8BACnB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC,wBAC7D,KAAK,aAAa;IAC5C;;;AAKP,QAAO;EACL,QAAQ;EACR;EACA,SACE,+BAA+B,UAAU,OAAO;EAEnD;;AAGH,SAAS,oBAAoB,KAAa,YAAmC;AAC3E,QAAO,IAAI,SAAS,gBAAgB,WAAW;EAC7C,MAAM,QAAQ,MAAM,OAAO;GAAC;GAAe;GAAW;GAAY;GAAW,EAAE;GAC7E;GACA,OAAO;GACP,OAAO;GACR,CAAC;EAEF,IAAI,SAAS;AACb,QAAM,QAAQ,GAAG,SAAS,SAAiB;AACzC,aAAU,KAAK,UAAU;IACzB;AAEF,QAAM,GAAG,UAAU,QAAQ,OAAO,IAAI,CAAC;AAEvC,QAAM,GAAG,SAAS,SAAS;AACzB,OAAI,SAAS,EACX,iBAAgB;OAEhB,wBAAO,IAAI,MAAM,wCAAwC,KAAK,IAAI,SAAS,CAAC;IAE9E;GACF"}