function ok(stdout) {
  return { stdout, stderr: "", exitCode: 0 };
}
function err(stderr) {
  return { stdout: "", stderr, exitCode: 1 };
}
const TYPE_MAP = {
  serial: "SERIAL",
  bigserial: "BIGSERIAL",
  integer: "INTEGER",
  bigint: "BIGINT",
  smallint: "SMALLINT",
  text: "TEXT",
  varchar: "VARCHAR",
  boolean: "BOOLEAN",
  timestamp: "TIMESTAMP",
  date: "DATE",
  json: "JSON",
  jsonb: "JSONB",
  uuid: "UUID",
  real: "REAL",
  doublePrecision: "DOUBLE PRECISION",
  numeric: "NUMERIC"
};
function findMatchingBrace(source, start) {
  let depth = 0;
  for (let i = start; i < source.length; i++) {
    if (source[i] === "{") depth++;
    else if (source[i] === "}") {
      depth--;
      if (depth === 0) return i;
    }
  }
  return -1;
}
function parseColumnDef(propName, definition) {
  const typeMatch = definition.match(/^(\w+)\(\s*['"]([^'"]+)['"]/);
  if (!typeMatch) return null;
  const type = typeMatch[1];
  const sqlName = typeMatch[2];
  let sqlType = TYPE_MAP[type] || type.toUpperCase();
  const optsMatch = definition.match(/\(\s*['"][^'"]+['"]\s*,\s*\{([^}]*)\}/);
  if (optsMatch) {
    const optsStr = optsMatch[1];
    if (type === "timestamp" && /withTimezone\s*:\s*true/.test(optsStr)) {
      sqlType = "TIMESTAMPTZ";
    }
    if (type === "varchar") {
      const lenMatch = optsStr.match(/length\s*:\s*(\d+)/);
      if (lenMatch) sqlType = `VARCHAR(${lenMatch[1]})`;
    }
    if (type === "numeric") {
      const precMatch = optsStr.match(/precision\s*:\s*(\d+)/);
      const scaleMatch = optsStr.match(/scale\s*:\s*(\d+)/);
      if (precMatch) {
        sqlType = scaleMatch ? `NUMERIC(${precMatch[1]},${scaleMatch[1]})` : `NUMERIC(${precMatch[1]})`;
      }
    }
  }
  const modifiers = [];
  const modifierRegex = /\.(\w+)\(([^)]*)\)/g;
  let m;
  while ((m = modifierRegex.exec(definition)) !== null) {
    const name = m[1];
    const arg = m[2].trim();
    if (name === "references") continue;
    if (name === "primaryKey") modifiers.push("primaryKey");
    else if (name === "notNull") modifiers.push("notNull");
    else if (name === "defaultNow") modifiers.push("defaultNow");
    else if (name === "default") modifiers.push(`default(${arg})`);
  }
  let references;
  const refIdx = definition.indexOf(".references(");
  if (refIdx !== -1) {
    const parenStart = refIdx + ".references".length;
    let depth = 0;
    let endParen = -1;
    for (let i = parenStart; i < definition.length; i++) {
      if (definition[i] === "(") depth++;
      else if (definition[i] === ")") {
        depth--;
        if (depth === 0) {
          endParen = i;
          break;
        }
      }
    }
    if (endParen !== -1) {
      const refContent = definition.slice(parenStart + 1, endParen);
      const arrowMatch = refContent.match(/\(\)\s*=>\s*(\w+)\.(\w+)/);
      if (arrowMatch) {
        references = { table: arrowMatch[1], column: arrowMatch[2] };
        const onDeleteMatch = refContent.match(/onDelete\s*:\s*['"]([^'"]+)['"]/);
        if (onDeleteMatch) references.onDelete = onDeleteMatch[1];
        const onUpdateMatch = refContent.match(/onUpdate\s*:\s*['"]([^'"]+)['"]/);
        if (onUpdateMatch) references.onUpdate = onUpdateMatch[1];
      }
    }
  }
  return { propName, sqlName, type, sqlType, modifiers, references };
}
function parseDrizzleSchema(source) {
  const tables = [];
  const varToTable = /* @__PURE__ */ new Map();
  const varRegex = /(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*pgTable\s*\(\s*['"]([^'"]+)['"]/g;
  let varMatch;
  while ((varMatch = varRegex.exec(source)) !== null) {
    varToTable.set(varMatch[1], varMatch[2]);
  }
  const pgTableRegex = /pgTable\(\s*['"]([^'"]+)['"]\s*,\s*\{/g;
  let match;
  while ((match = pgTableRegex.exec(source)) !== null) {
    const tableName = match[1];
    const braceStart = match.index + match[0].length - 1;
    const braceEnd = findMatchingBrace(source, braceStart);
    if (braceEnd === -1) continue;
    const columnsBlock = source.slice(braceStart + 1, braceEnd);
    const columns = [];
    const entries = splitTopLevel(columnsBlock);
    for (const entry of entries) {
      const trimmed = entry.trim();
      if (!trimmed) continue;
      const colonIdx = trimmed.indexOf(":");
      if (colonIdx === -1) continue;
      const propName = trimmed.slice(0, colonIdx).trim();
      const definition = trimmed.slice(colonIdx + 1).trim();
      const col = parseColumnDef(propName, definition);
      if (col) columns.push(col);
    }
    tables.push({ name: tableName, columns });
  }
  const varToColumns = /* @__PURE__ */ new Map();
  for (const [varName, sqlTableName] of varToTable) {
    const table = tables.find((t) => t.name === sqlTableName);
    if (table) {
      const colMap = /* @__PURE__ */ new Map();
      for (const col of table.columns) {
        colMap.set(col.propName, col.sqlName);
      }
      varToColumns.set(varName, colMap);
    }
  }
  for (const table of tables) {
    for (const col of table.columns) {
      if (col.references) {
        const varName = col.references.table;
        const propName = col.references.column;
        const sqlTableName = varToTable.get(varName);
        if (sqlTableName) col.references.table = sqlTableName;
        const colMap = varToColumns.get(varName);
        if (colMap) {
          const sqlColName = colMap.get(propName);
          if (sqlColName) col.references.column = sqlColName;
        }
      }
    }
  }
  return tables;
}
function splitTopLevel(source) {
  const parts = [];
  let depth = 0;
  let current = "";
  for (let i = 0; i < source.length; i++) {
    const ch = source[i];
    if (ch === "(" || ch === "{" || ch === "[") depth++;
    else if (ch === ")" || ch === "}" || ch === "]") depth--;
    else if (ch === "," && depth === 0) {
      parts.push(current);
      current = "";
      continue;
    }
    current += ch;
  }
  if (current.trim()) parts.push(current);
  return parts;
}
function columnToSQL(col) {
  const parts = [col.sqlName, col.sqlType];
  if (col.modifiers.includes("primaryKey")) parts.push("PRIMARY KEY");
  if (col.modifiers.includes("notNull")) parts.push("NOT NULL");
  for (const mod of col.modifiers) {
    if (mod === "defaultNow") {
      parts.push("DEFAULT now()");
    } else if (mod.startsWith("default(")) {
      const val = mod.slice(8, -1);
      parts.push(`DEFAULT ${val}`);
    }
  }
  if (col.references) {
    let refStr = `REFERENCES ${col.references.table}(${col.references.column})`;
    if (col.references.onDelete) refStr += ` ON DELETE ${col.references.onDelete.toUpperCase()}`;
    if (col.references.onUpdate) refStr += ` ON UPDATE ${col.references.onUpdate.toUpperCase()}`;
    parts.push(refStr);
  }
  return parts.join(" ");
}
function generateCreateTableSQL(table) {
  const columnDefs = table.columns.map(columnToSQL);
  return `CREATE TABLE IF NOT EXISTS ${table.name} (
  ${columnDefs.join(",\n  ")}
);`;
}
function sortTablesByDependencies(tables) {
  const tableNames = new Set(tables.map((t) => t.name));
  const deps = /* @__PURE__ */ new Map();
  for (const table of tables) {
    const tableDeps = /* @__PURE__ */ new Set();
    for (const col of table.columns) {
      if (col.references && tableNames.has(col.references.table) && col.references.table !== table.name) {
        tableDeps.add(col.references.table);
      }
    }
    deps.set(table.name, tableDeps);
  }
  const sorted = [];
  const visited = /* @__PURE__ */ new Set();
  const visiting = /* @__PURE__ */ new Set();
  function visit(name) {
    if (visited.has(name)) return;
    if (visiting.has(name)) return;
    visiting.add(name);
    for (const dep of deps.get(name) || []) {
      visit(dep);
    }
    visiting.delete(name);
    visited.add(name);
    sorted.push(tables.find((t) => t.name === name));
  }
  for (const table of tables) {
    visit(table.name);
  }
  return sorted;
}
function generateMigrationSQL(diff) {
  const statements = [];
  const sortedCreateTables = sortTablesByDependencies(diff.createTables);
  for (const table of sortedCreateTables) {
    statements.push(generateCreateTableSQL(table));
  }
  for (const { table, columns } of diff.addColumns) {
    for (const col of columns) {
      statements.push(`ALTER TABLE ${table} ADD COLUMN ${columnToSQL(col)};`);
    }
  }
  for (const { table, columns } of diff.dropColumns) {
    for (const colName of columns) {
      statements.push(`ALTER TABLE ${table} DROP COLUMN ${colName};`);
    }
  }
  for (const tableName of diff.dropTables) {
    statements.push(`DROP TABLE ${tableName};`);
  }
  return statements.join("\n\n");
}
function buildIntrospectedSchema(rows) {
  const tableMap = /* @__PURE__ */ new Map();
  for (const row of rows) {
    const tableName = row.table_name;
    if (!tableMap.has(tableName)) tableMap.set(tableName, []);
    tableMap.get(tableName).push({
      column_name: row.column_name,
      data_type: row.data_type,
      is_nullable: row.is_nullable,
      column_default: row.column_default
    });
  }
  return Array.from(tableMap.entries()).map(([name, columns]) => ({ name, columns }));
}
function diffSchemas(desired, current) {
  const diff = {
    createTables: [],
    dropTables: [],
    addColumns: [],
    dropColumns: []
  };
  const currentMap = new Map(current.map((t) => [t.name, t]));
  const desiredMap = new Map(desired.map((t) => [t.name, t]));
  for (const table of desired) {
    if (!currentMap.has(table.name)) {
      diff.createTables.push(table);
    }
  }
  for (const table of current) {
    if (table.name === "_drizzle_migrations") continue;
    if (!desiredMap.has(table.name)) {
      diff.dropTables.push(table.name);
    }
  }
  for (const desiredTable of desired) {
    const currentTable = currentMap.get(desiredTable.name);
    if (!currentTable) continue;
    const currentColNames = new Set(currentTable.columns.map((c) => c.column_name));
    const desiredColNames = new Set(desiredTable.columns.map((c) => c.sqlName));
    const newCols = desiredTable.columns.filter((c) => !currentColNames.has(c.sqlName));
    if (newCols.length > 0) {
      diff.addColumns.push({ table: desiredTable.name, columns: newCols });
    }
    const droppedCols = currentTable.columns.filter((c) => !desiredColNames.has(c.column_name));
    if (droppedCols.length > 0) {
      diff.dropColumns.push({ table: desiredTable.name, columns: droppedCols.map((c) => c.column_name) });
    }
  }
  return diff;
}
function isDiffEmpty(diff) {
  return diff.createTables.length === 0 && diff.dropTables.length === 0 && diff.addColumns.length === 0 && diff.dropColumns.length === 0;
}
const DRIZZLE_DIR = "/project/drizzle";
const SCHEMA_PATH = "/project/src/db/schema.ts";
const MIGRATIONS_TABLE = "_drizzle_migrations";
async function ensureMigrationsTable() {
  const { handleDatabaseRequest } = await import("./pglite-database-DKRVlYOI.js");
  await handleDatabaseRequest("exec", {
    sql: `CREATE TABLE IF NOT EXISTS ${MIGRATIONS_TABLE} (
      id SERIAL PRIMARY KEY,
      name TEXT NOT NULL UNIQUE,
      applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
    )`
  });
}
async function getAppliedMigrations() {
  const { handleDatabaseRequest } = await import("./pglite-database-DKRVlYOI.js");
  const result = await handleDatabaseRequest("query", {
    sql: `SELECT name FROM ${MIGRATIONS_TABLE} ORDER BY name`
  });
  if (result.statusCode !== 200) return [];
  const data = JSON.parse(result.body);
  return (data.rows || []).map((r) => r.name);
}
async function introspectCurrentSchema() {
  const { handleDatabaseRequest } = await import("./pglite-database-DKRVlYOI.js");
  const result = await handleDatabaseRequest("query", {
    sql: `SELECT table_name, column_name, data_type, is_nullable, column_default
          FROM information_schema.columns
          WHERE table_schema = 'public'
          ORDER BY table_name, ordinal_position`
  });
  if (result.statusCode !== 200) return [];
  const data = JSON.parse(result.body);
  return buildIntrospectedSchema(data.rows || []);
}
function getMigrationFiles(vfs) {
  try {
    const files = vfs.readdirSync(DRIZZLE_DIR);
    return files.filter((f) => f.endsWith(".sql")).sort();
  } catch {
    return [];
  }
}
function getNextMigrationNumber(existingFiles) {
  if (existingFiles.length === 0) return "0000";
  let max = -1;
  for (const f of existingFiles) {
    const match = f.match(/^(\d+)/);
    if (match) max = Math.max(max, parseInt(match[1], 10));
  }
  return String(max + 1).padStart(4, "0");
}
async function cmdGenerate(args, vfs) {
  let name = "";
  let force = false;
  for (let i = 0; i < args.length; i++) {
    if (args[i] === "--name" && i + 1 < args.length) {
      name = args[++i];
    } else if (args[i] === "--force") {
      force = true;
    }
  }
  if (!name) return err("Usage: drizzle-kit generate --name <migration_name>");
  let schemaSource;
  try {
    const raw = vfs.readFileSync(SCHEMA_PATH);
    schemaSource = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
  } catch {
    return err(`Schema file not found: ${SCHEMA_PATH}`);
  }
  const desired = parseDrizzleSchema(schemaSource);
  const current = await introspectCurrentSchema();
  const diff = diffSchemas(desired, current);
  if (isDiffEmpty(diff)) {
    return ok("No schema changes detected.");
  }
  if (diff.dropTables.length > 0 && !force) {
    return err(
      `Migration would drop table(s): ${diff.dropTables.join(", ")}
Use --force to include DROP TABLE statements.`
    );
  }
  const sqlToWrite = force ? generateMigrationSQL(diff) : generateMigrationSQL({
    ...diff,
    dropTables: []
  });
  try {
    vfs.mkdirSync(DRIZZLE_DIR, { recursive: true });
  } catch {
  }
  const existingFiles = getMigrationFiles(vfs);
  const num = getNextMigrationNumber(existingFiles);
  const sanitizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_");
  const filename = `${num}_${sanitizedName}.sql`;
  const filePath = `${DRIZZLE_DIR}/${filename}`;
  vfs.writeFileSync(filePath, sqlToWrite);
  return ok(`Migration generated: drizzle/${filename}`);
}
async function cmdMigrate(_args, vfs) {
  await ensureMigrationsTable();
  const files = getMigrationFiles(vfs);
  if (files.length === 0) return ok("No migration files found in drizzle/");
  const applied = await getAppliedMigrations();
  const appliedSet = new Set(applied);
  const pending = files.filter((f) => !appliedSet.has(f));
  if (pending.length === 0) return ok("All migrations already applied.");
  const { handleDatabaseRequest } = await import("./pglite-database-DKRVlYOI.js");
  const results = [];
  const errors = [];
  for (const file of pending) {
    try {
      const raw = vfs.readFileSync(`${DRIZZLE_DIR}/${file}`);
      const sql = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
      const execResult = await handleDatabaseRequest("exec", { sql });
      if (execResult.statusCode !== 200) {
        const body = JSON.parse(execResult.body);
        errors.push(`${file}: ${body.error}`);
        break;
      }
      await handleDatabaseRequest("exec", {
        sql: `INSERT INTO ${MIGRATIONS_TABLE} (name) VALUES ('${file}')`
      });
      results.push(file);
    } catch (e) {
      errors.push(`${file}: ${e.message || String(e)}`);
      break;
    }
  }
  let output = "";
  if (results.length > 0) {
    output += `Applied ${results.length} migration(s):
${results.map((f) => `  [applied] ${f}`).join("\n")}`;
  }
  if (errors.length > 0) {
    output += (output ? "\n" : "") + `Errors:
${errors.map((e) => `  [error] ${e}`).join("\n")}`;
    return { stdout: output, stderr: "", exitCode: 1 };
  }
  return ok(output);
}
async function cmdPush(args, vfs) {
  let schemaSource;
  try {
    const raw = vfs.readFileSync(SCHEMA_PATH);
    schemaSource = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
  } catch {
    return err(`Schema file not found: ${SCHEMA_PATH}`);
  }
  let force = args.includes("--force");
  const desired = parseDrizzleSchema(schemaSource);
  const current = await introspectCurrentSchema();
  const diff = diffSchemas(desired, current);
  if (isDiffEmpty(diff)) {
    return ok("Schema is up to date.");
  }
  if (diff.dropTables.length > 0 && !force) {
    return err(
      `Push would drop table(s): ${diff.dropTables.join(", ")}
Use --force to include DROP TABLE statements.`
    );
  }
  const sql = force ? generateMigrationSQL(diff) : generateMigrationSQL({
    ...diff,
    dropTables: []
  });
  const { handleDatabaseRequest } = await import("./pglite-database-DKRVlYOI.js");
  const result = await handleDatabaseRequest("exec", { sql });
  if (result.statusCode !== 200) {
    const body = JSON.parse(result.body);
    return err(`Push failed: ${body.error}`);
  }
  const actions = [];
  if (diff.createTables.length > 0) actions.push(`Created table(s): ${diff.createTables.map((t) => t.name).join(", ")}`);
  if (diff.addColumns.length > 0) actions.push(`Added column(s): ${diff.addColumns.map((a) => `${a.table}(${a.columns.map((c) => c.sqlName).join(", ")})`).join(", ")}`);
  if (diff.dropColumns.length > 0) actions.push(`Dropped column(s): ${diff.dropColumns.map((d) => `${d.table}(${d.columns.join(", ")})`).join(", ")}`);
  if (force && diff.dropTables.length > 0) actions.push(`Dropped table(s): ${diff.dropTables.join(", ")}`);
  return ok(`Push complete.
${actions.join("\n")}`);
}
async function cmdStatus(_args, vfs) {
  await ensureMigrationsTable();
  const files = getMigrationFiles(vfs);
  if (files.length === 0) return ok("No migration files found in drizzle/");
  const applied = await getAppliedMigrations();
  const appliedSet = new Set(applied);
  const lines = files.map((f) => {
    const status = appliedSet.has(f) ? "[applied]" : "[pending]";
    return `  ${status} ${f}`;
  });
  return ok(`Migrations:
${lines.join("\n")}`);
}
const HELP_TEXT = `drizzle-kit — Schema migration tool for Drizzle ORM

Commands:
  drizzle-kit generate --name <name>   Generate migration from schema changes
  drizzle-kit migrate                  Apply pending migrations
  drizzle-kit push                     Push schema changes directly (no migration file)
  drizzle-kit status                   Show migration status

Flags:
  --force    Include DROP TABLE statements (generate/push)
  --name     Migration name (generate)`;
async function runDrizzleKitCommand(args, _ctx, vfs) {
  const subcommand = args[0];
  if (!subcommand || subcommand === "help" || subcommand === "--help") {
    return ok(HELP_TEXT);
  }
  try {
    switch (subcommand) {
      case "generate":
        return await cmdGenerate(args.slice(1), vfs);
      case "migrate":
        return await cmdMigrate(args.slice(1), vfs);
      case "push":
        return await cmdPush(args.slice(1), vfs);
      case "status":
        return await cmdStatus(args.slice(1), vfs);
      default:
        return err(`Unknown subcommand: ${subcommand}

${HELP_TEXT}`);
    }
  } catch (error) {
    return err(error.message || String(error));
  }
}
export {
  buildIntrospectedSchema,
  diffSchemas,
  generateCreateTableSQL,
  generateMigrationSQL,
  isDiffEmpty,
  parseDrizzleSchema,
  runDrizzleKitCommand
};
//# sourceMappingURL=drizzle-kit-command-D3Y40mtX.js.map
