{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli-typegen.ts","../src/cli.ts"],"sourcesContent":["/**\n * `kick/db` typegen — reads the adopter's schema (`src/db/schema.ts` or a\n * `src/db/schema/` barrel) and emits `.kickjs/types/kick__db.d.ts` with\n * three augmentations:\n *\n *   1. global `KickDbSchema = SchemaToTypes<typeof appSchema>` — column\n *      shapes computed at type-check time, no runtime cost.\n *   2. `KickDbRegister.db = KickDbClient<KickDbSchema>` — bare\n *      `KickDbClient` widens automatically.\n *   3. `KickDbRelationsRegister.db = SchemaToRelationsRegister<typeof\n *      appSchema>` — typed `with` keys for `db.query.X.findMany`.\n *\n * Shipped on {@link dbCliPlugin} (`typegens`) so mounting the db plugin\n * brings both the `kick db` commands and this type generation. Typed\n * against the `@forinda/kickjs-cli-kit` `CliTypegen` contract so it needs\n * no kickjs-cli internals — it only reads `ctx.cwd`.\n */\nimport path from 'node:path'\nimport { existsSync } from 'node:fs'\n\nimport type { CliTypegen } from '@forinda/kickjs-cli-kit'\n\nconst DEFAULT_SCHEMA_PATHS = [\n  'src/db/schema.ts',\n  'src/db/schema/index.ts',\n  'src/db/schema',\n] as const\n\nexport const kickDbTypegen = (): CliTypegen => ({\n  id: 'kick/db',\n  inputs: ['src/db/schema.ts', 'src/db/schema/**/*.ts'],\n  async generate(ctx: { cwd: string; config?: { db?: { schemaPath?: string } } }) {\n    // Parity with `kick db generate` (cli/config.ts resolveDbConfig):\n    // an adopter-configured `db.schemaPath` must drive BOTH the\n    // migration engine and this augmentation — previously only the\n    // default candidates were probed, so a custom path produced\n    // working migrations but a silently untyped client.\n    const schemaAbs = resolveSchema(ctx.cwd, ctx.config?.db?.schemaPath)\n    if (!schemaAbs) return null\n\n    // Strip the `.ts` extension and any trailing `/index` so the import\n    // specifier stays stable across single-file vs barrel-folder layouts.\n    const typesDir = path.resolve(ctx.cwd, '.kickjs/types')\n    const rel = posix(path.relative(typesDir, schemaAbs))\n      .replace(/\\.ts$/, '')\n      .replace(/\\/index$/, '')\n\n    return [\n      `import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,\n      `import type * as appSchema from '${rel}'`,\n      ``,\n      `declare global {`,\n      `  interface KickDbSchema extends SchemaToTypes<typeof appSchema> {}`,\n      `}`,\n      ``,\n      `declare module '@forinda/kickjs-db' {`,\n      `  interface KickDbRegister {`,\n      `    db: KickDbClient<KickDbSchema>`,\n      `  }`,\n      ``,\n      `  interface KickDbRelationsRegister {`,\n      `    db: SchemaToRelationsRegister<typeof appSchema>`,\n      `  }`,\n      `}`,\n    ].join('\\n')\n  },\n})\n\nfunction resolveSchema(cwd: string, configuredPath?: string): string | null {\n  // kick.config `db.schemaPath` wins when the file exists; a configured-\n  // but-missing path falls through to the candidates rather than\n  // emitting an augmentation with a broken import specifier.\n  if (configuredPath) {\n    const abs = path.resolve(cwd, configuredPath)\n    if (existsSync(abs)) return abs\n    const idx = path.join(abs, 'index.ts')\n    if (existsSync(idx)) return idx\n  }\n  for (const candidate of DEFAULT_SCHEMA_PATHS) {\n    const abs = path.resolve(cwd, candidate)\n    if (candidate.endsWith('.ts')) {\n      if (existsSync(abs)) return abs\n    } else {\n      const idx = path.join(abs, 'index.ts')\n      if (existsSync(idx)) return idx\n    }\n  }\n  return null\n}\n\nfunction posix(p: string): string {\n  return p.replace(/\\\\/g, '/')\n}\n","/**\n * `@forinda/kickjs-db/cli` — the database command tree as a mountable CLI\n * plugin + the building blocks for a standalone `kickjs-db` bin.\n *\n * Two ways to use it:\n *  1. **As a kickjs-cli plugin** — add `dbCliPlugin` to `kick.config.ts`\n *     `plugins: []`. The host CLI calls `register(program, ctx)` and the\n *     db config is read from `ctx.config.db` (already loaded — no re-parse).\n *  2. **Standalone** — the `kickjs-db` bin builds a commander program,\n *     resolves config from `kickjs-db.config.ts` (or a `kick.config.ts`\n *     `db` block), and calls {@link registerDbCommands} directly. Lets\n *     `npx kickjs-db migrate latest` work without installing kickjs-cli.\n *\n * @module @forinda/kickjs-db/cli\n */\n\nimport { writeFile } from 'node:fs/promises'\nimport type { Command } from 'commander'\n\nimport { defineCliPlugin, type KickCliPlugin } from '@forinda/kickjs-cli-kit'\nimport { kickDbTypegen } from './cli-typegen'\n\nexport { kickDbTypegen } from './cli-typegen'\n\nimport {\n  detectCompositeReferences,\n  generate,\n  migrateLatest,\n  migrateUp,\n  migrateDown,\n  migrateRollback,\n  migrateStatus,\n  reviewMigration,\n  renderSchemaSource,\n  type CompositeQueryRunner,\n  type DbConfig,\n  type MigrationAdapter,\n} from './index'\nimport type { Dialect } from './snapshot/types'\nimport type { MigrationAdapterFactory } from './cli/config'\nimport type { DriftBehavior } from './migrate/drift'\n\n/**\n * Authoring shape for the db config — every field optional, defaults\n * applied by {@link resolveKickDbConfig}. This is the same shape as the\n * `db` block in `kick.config.ts`, so a config authored with\n * `defineKickDbConfig` drops straight into either place.\n */\nexport interface KickDbConfigInput {\n  schemaPath?: string\n  migrationsDir?: string\n  dialect?: Dialect\n  connectionString?: string\n  adapter?: MigrationAdapterFactory\n  /**\n   * How `migrate` reacts to out-of-band schema (drift): `'error'`\n   * (default), `'warn'`, or `'ignore'`. The check is dialect-normalised,\n   * so SQLite/MySQL's lossy introspection doesn't false-positive.\n   */\n  driftCheck?: DriftBehavior\n}\n\n/**\n * Identity helper for type inference — mirrors vite's `defineConfig`.\n * Use it in a standalone `kickjs-db.config.ts` (`export default\n * defineKickDbConfig({ ... })`) or as the value of `kick.config.ts`'s\n * `db` field. Both resolve through {@link resolveKickDbConfig}.\n */\nexport function defineKickDbConfig(cfg: KickDbConfigInput): KickDbConfigInput {\n  return cfg\n}\n\n/**\n * Shallow-merge db configs, later wins (vite's `mergeConfig` spirit).\n * Lets a standalone `kickjs-db.config.ts` layer over a project's\n * `kick.config.ts` `db` block, or vice versa.\n */\nexport function mergeKickDbConfig(\n  ...configs: (KickDbConfigInput | undefined)[]\n): KickDbConfigInput {\n  return Object.assign({}, ...configs.filter(Boolean))\n}\n\n/** Apply defaults to a {@link KickDbConfigInput}, yielding a resolved {@link DbConfig}. */\nexport function resolveKickDbConfig(block: KickDbConfigInput | undefined): DbConfig {\n  const db = block ?? {}\n  return {\n    schemaPath: db.schemaPath ?? 'src/db/schema.ts',\n    migrationsDir: db.migrationsDir ?? 'db/migrations',\n    dialect: db.dialect ?? 'postgres',\n    connectionString: db.connectionString ?? process.env.DATABASE_URL,\n    adapter: db.adapter,\n    driftCheck: db.driftCheck,\n  }\n}\n\n/**\n * Resolve a MigrationAdapter from config:\n *  1. config.adapter() — explicit factory wins.\n *  2. config.connectionString — built-in pgAdapter path; dynamically\n *     imports `./pg` + `pg` so non-PG workflows don't pull pg.\n */\nasync function resolveAdapter(config: DbConfig): Promise<{\n  adapter: MigrationAdapter\n  cleanup: () => Promise<void>\n}> {\n  if (config.adapter) {\n    const adapter = await config.adapter()\n    return { adapter, cleanup: async () => adapter.close() }\n  }\n  if (!config.connectionString) {\n    throw new Error(\n      'kickjs-db: no adapter resolved — set db.connectionString (or DATABASE_URL), or supply a db.adapter() factory',\n    )\n  }\n  const dialect = config.dialect ?? 'postgres'\n  if (dialect !== 'postgres') {\n    throw new Error(\n      `kickjs-db: the built-in CLI adapter only supports postgres (dialect=${dialect}); supply a db.adapter() factory for other dialects`,\n    )\n  }\n  // Dynamic import so we don't hard-require pg unless this path runs.\n  const [{ pgAdapter }, pg] = await Promise.all([import('./pg'), import('pg')])\n  const pool = new pg.default.Pool({ connectionString: config.connectionString })\n  const adapter = pgAdapter({ pool })\n  return {\n    adapter,\n    cleanup: async () => {\n      await adapter.close()\n      await pool.end()\n    },\n  }\n}\n\ninterface PgQueryRunnerProbe {\n  runner: CompositeQueryRunner\n  cleanup: () => Promise<void>\n}\n\n/**\n * Resolve a pg-protocol query runner for the composite-type check at\n * `generate` time. Only fires for the built-in pgAdapter path\n * (dialect=postgres + connection string, no custom adapter factory).\n */\nasync function tryResolvePgQueryRunner(config: DbConfig): Promise<PgQueryRunnerProbe | null> {\n  if (config.adapter) return null\n  if ((config.dialect ?? 'postgres') !== 'postgres') return null\n  if (!config.connectionString) return null\n\n  const pg = await import('pg')\n  const pool = new pg.default.Pool({ connectionString: config.connectionString })\n  return { runner: pool, cleanup: async () => void (await pool.end()) }\n}\n\nfunction printStatusTable(status: Awaited<ReturnType<typeof migrateStatus>>): void {\n  if (status.length === 0) {\n    console.log('No migrations.')\n    return\n  }\n  console.table(\n    status.map((s) => ({\n      id: s.id,\n      state: s.state,\n      batch: s.batch ?? '-',\n      reviewed: s.reviewed,\n      applied: s.appliedAt ?? '-',\n    })),\n  )\n}\n\n/** A config source — resolved lazily so each command reads fresh config. */\nexport type DbConfigResolver = () => DbConfig | Promise<DbConfig>\n\n/**\n * Attach the db commands (`generate`, `migrate *`, `introspect`) onto a\n * commander command. `parent` is the command they hang off — the plugin\n * passes a `db` subcommand (so `kick db generate`), the standalone bin\n * passes the root program (so `kickjs-db generate`). `getConfig` supplies\n * the resolved {@link DbConfig} — under kickjs-cli from `ctx.config.db`,\n * standalone from `kickjs-db.config.ts`.\n */\nexport function registerDbCommands(parent: Command, getConfig: DbConfigResolver): void {\n  parent\n    .command('generate <name>')\n    .description('Generate a new migration from schema diff')\n    .option(\n      '-e, --empty',\n      'Skip schema diff and create an empty migration shell (data migration, seed, freeform SQL)',\n    )\n    .action(async (name: string, opts: { empty?: boolean }) => {\n      const cwd = process.cwd()\n      const config = await getConfig()\n\n      const probe = await tryResolvePgQueryRunner(config)\n      const detectCompositeRefs = probe\n        ? (enumName: string) => detectCompositeReferences(probe.runner, enumName)\n        : undefined\n\n      try {\n        const result = await generate({ name, config, cwd, empty: opts.empty, detectCompositeRefs })\n        if (result.status === 'no-changes') {\n          console.log('No schema changes detected.')\n          return\n        }\n        if (result.empty) {\n          console.log(`Created empty migration ${result.migrationDir} (author up.sql + down.sql).`)\n          return\n        }\n        const plural = result.changeCount === 1 ? '' : 's'\n        console.log(\n          `Created migration ${result.migrationDir} (${result.changeCount} change${plural}).`,\n        )\n      } finally {\n        await probe?.cleanup()\n      }\n    })\n\n  // ── migrate runner subcommands ─────────────────────────────────────────\n  const migrate = parent.command('migrate').description('Migration runner subcommands')\n\n  migrate\n    .command('latest')\n    .description('Apply all pending migrations in a new batch')\n    .option(\n      '--confirm-enum-drop',\n      'Allow migrations carrying the `-- KICK ENUM REMOVE` header to apply',\n      false,\n    )\n    .action(async (opts: { confirmEnumDrop?: boolean }) => {\n      const config = await getConfig()\n      const { adapter, cleanup } = await resolveAdapter(config)\n      try {\n        const r = await migrateLatest({\n          adapter,\n          migrationsDir: config.migrationsDir,\n          driftCheck: config.driftCheck,\n          confirmEnumDrop: opts.confirmEnumDrop,\n        })\n        console.log(\n          r.applied.length === 0\n            ? 'No pending migrations.'\n            : `Applied batch ${r.batch}: ${r.applied.join(', ')}`,\n        )\n      } finally {\n        await cleanup()\n      }\n    })\n\n  migrate\n    .command('up')\n    .description('Apply the next single pending migration')\n    .option(\n      '--confirm-enum-drop',\n      'Allow migrations carrying the `-- KICK ENUM REMOVE` header to apply',\n      false,\n    )\n    .action(async (opts: { confirmEnumDrop?: boolean }) => {\n      const config = await getConfig()\n      const { adapter, cleanup } = await resolveAdapter(config)\n      try {\n        const r = await migrateUp({\n          adapter,\n          migrationsDir: config.migrationsDir,\n          driftCheck: config.driftCheck,\n          confirmEnumDrop: opts.confirmEnumDrop,\n        })\n        console.log(\n          r.applied.length === 0\n            ? 'No pending migrations.'\n            : `Applied ${r.applied[0]} (batch ${r.batch})`,\n        )\n      } finally {\n        await cleanup()\n      }\n    })\n\n  migrate\n    .command('down')\n    .description('Reverse the most recent applied migration')\n    .action(async () => {\n      const config = await getConfig()\n      const { adapter, cleanup } = await resolveAdapter(config)\n      try {\n        const r = await migrateDown({\n          adapter,\n          migrationsDir: config.migrationsDir,\n          driftCheck: config.driftCheck,\n        })\n        console.log(r.reversed ? `Reversed ${r.reversed}.` : 'Nothing to reverse.')\n      } finally {\n        await cleanup()\n      }\n    })\n\n  migrate\n    .command('rollback')\n    .description('Reverse the entire last batch as a single unit')\n    .action(async () => {\n      const config = await getConfig()\n      const { adapter, cleanup } = await resolveAdapter(config)\n      try {\n        const r = await migrateRollback({\n          adapter,\n          migrationsDir: config.migrationsDir,\n          driftCheck: config.driftCheck,\n        })\n        console.log(\n          r.reversed.length === 0\n            ? 'Nothing to roll back.'\n            : `Rolled back batch ${r.batch}: ${r.reversed.join(', ')}`,\n        )\n      } finally {\n        await cleanup()\n      }\n    })\n\n  migrate\n    .command('status')\n    .description('Print applied + pending migrations')\n    .action(async () => {\n      const config = await getConfig()\n      const { adapter, cleanup } = await resolveAdapter(config)\n      try {\n        printStatusTable(await migrateStatus({ adapter, migrationsDir: config.migrationsDir }))\n      } finally {\n        await cleanup()\n      }\n    })\n\n  migrate\n    .command('review <id>')\n    .description('Mark a migration reviewed (flips meta.json; migrates legacy -- REVIEWED markers)')\n    .action(async (id: string) => {\n      // No adapter/DB needed — review only touches the migration files.\n      const config = await getConfig()\n      const r = await reviewMigration(config.migrationsDir, id)\n      console.log(\n        r.alreadyReviewed\n          ? `${r.id} was already reviewed.`\n          : `Reviewed ${r.id} — it can now be applied.`,\n      )\n    })\n\n  // ── kick db introspect ─────────────────────────────────────────────────\n  parent\n    .command('introspect')\n    .description('Generate a TypeScript schema file from a live database')\n    .option('--out <path>', 'Output file (defaults to db.schemaPath from config)')\n    .option('--json', 'Print the raw SchemaSnapshot JSON to stdout instead of writing TS source')\n    .action(async (opts: { out?: string; json?: boolean }) => {\n      const config = await getConfig()\n      const { adapter, cleanup } = await resolveAdapter(config)\n      try {\n        const snapshot = await adapter.introspect()\n        if (opts.json) {\n          console.log(JSON.stringify(snapshot, null, 2))\n          return\n        }\n        const out = opts.out ?? config.schemaPath\n        await writeFile(out, renderSchemaSource(snapshot), 'utf8')\n        const n = Object.keys(snapshot.tables).length\n        console.log(`Wrote ${out} (${n} table${n === 1 ? '' : 's'}).`)\n      } finally {\n        await cleanup()\n      }\n    })\n}\n\n/**\n * Read the `db` block off a host CLI config object. The kit types\n * `ctx.config` as `unknown`; the db block is structurally a\n * {@link KickDbConfigInput}.\n */\nfunction dbBlockOf(config: unknown): KickDbConfigInput | undefined {\n  return (config as { db?: KickDbConfigInput } | null)?.db\n}\n\n/**\n * The database CLI plugin. Mount it in `kick.config.ts`:\n *\n * ```ts\n * import { defineConfig } from '@forinda/kickjs-cli'\n * import { dbCliPlugin } from '@forinda/kickjs-db/cli'\n *\n * export default defineConfig({ plugins: [dbCliPlugin] })\n * ```\n *\n * `kick db generate|migrate|introspect` then read config from the\n * `db` block of the same `kick.config.ts`.\n */\nexport const dbCliPlugin: KickCliPlugin = defineCliPlugin({\n  name: 'kick/db',\n  register(program, ctx) {\n    const db = program.command('db').description('Database commands (kickjs-db)')\n    registerDbCommands(db, () => resolveKickDbConfig(dbBlockOf(ctx.config)))\n  },\n  // Mounting the plugin also wires `.kickjs/types/kick__db.d.ts` generation\n  // into `kick typegen` — db commands + db types from one opt-in plugin.\n  typegens: [kickDbTypegen()],\n})\n"],"mappings":"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"}