kolaybase-cli 0.2.0 → 0.3.1
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/dist/index.js +404 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -106,25 +106,49 @@ function setApiUrl(url) {
|
|
|
106
106
|
}
|
|
107
107
|
async function writeEnvFile(project) {
|
|
108
108
|
const apiUrl = getApiUrl();
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
`
|
|
121
|
-
`
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
109
|
+
const kolaybaseVars = {
|
|
110
|
+
KOLAYBASE_PROJECT_ID: project.id,
|
|
111
|
+
KOLAYBASE_ANON_KEY: project.anonKey,
|
|
112
|
+
KOLAYBASE_SERVICE_KEY: project.serviceKey,
|
|
113
|
+
KOLAYBASE_API_URL: apiUrl,
|
|
114
|
+
KOLAYBASE_PROJECT_SLUG: project.slug,
|
|
115
|
+
KOLAYBASE_DB_HOST: project.dbHost,
|
|
116
|
+
KOLAYBASE_DB_PORT: String(project.dbPort),
|
|
117
|
+
KOLAYBASE_DB_NAME: project.dbName,
|
|
118
|
+
KOLAYBASE_DB_USER: project.dbUser,
|
|
119
|
+
KOLAYBASE_DB_PASSWORD: project.dbPassword,
|
|
120
|
+
KOLAYBASE_DATABASE_URL: `postgresql://${project.dbUser}:${project.dbPassword}@${project.dbHost}:${project.dbPort}/${project.dbName}`,
|
|
121
|
+
DATABASE_URL: `postgresql://${project.dbUser}:${project.dbPassword}@${project.dbHost}:${project.dbPort}/${project.dbName}`,
|
|
122
|
+
KOLAYBASE_KEYCLOAK_REALM: project.keycloakRealm
|
|
123
|
+
};
|
|
124
|
+
let existing = "";
|
|
125
|
+
try {
|
|
126
|
+
existing = await fs.readFile(".env", "utf-8");
|
|
127
|
+
} catch {
|
|
128
|
+
}
|
|
129
|
+
const existingLines = existing.split("\n");
|
|
130
|
+
const handled = /* @__PURE__ */ new Set();
|
|
131
|
+
const updatedLines = existingLines.map((line) => {
|
|
132
|
+
const match = line.match(/^([A-Z0-9_]+)\s*=/);
|
|
133
|
+
if (match && kolaybaseVars[match[1]] !== void 0) {
|
|
134
|
+
handled.add(match[1]);
|
|
135
|
+
return `${match[1]}=${kolaybaseVars[match[1]]}`;
|
|
136
|
+
}
|
|
137
|
+
return line;
|
|
138
|
+
});
|
|
139
|
+
while (updatedLines.length && updatedLines[updatedLines.length - 1].trim() === "") {
|
|
140
|
+
updatedLines.pop();
|
|
141
|
+
}
|
|
142
|
+
const newKeys = Object.keys(kolaybaseVars).filter((k) => !handled.has(k));
|
|
143
|
+
if (newKeys.length) {
|
|
144
|
+
updatedLines.push("");
|
|
145
|
+
updatedLines.push('# Kolaybase \u2014 added by "kb init" / "kb link"');
|
|
146
|
+
for (const key of newKeys) {
|
|
147
|
+
updatedLines.push(`${key}=${kolaybaseVars[key]}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
updatedLines.push("");
|
|
151
|
+
await fs.writeFile(".env", updatedLines.join("\n"));
|
|
128
152
|
try {
|
|
129
153
|
let gi = "";
|
|
130
154
|
try {
|
|
@@ -285,8 +309,8 @@ var init_api = __esm({
|
|
|
285
309
|
);
|
|
286
310
|
}
|
|
287
311
|
// Auth endpoints
|
|
288
|
-
async login(
|
|
289
|
-
const { data } = await this.client.post("/api/auth/login", {
|
|
312
|
+
async login(email, password) {
|
|
313
|
+
const { data } = await this.client.post("/api/auth/login", { email, password });
|
|
290
314
|
return data;
|
|
291
315
|
}
|
|
292
316
|
async signup(userData) {
|
|
@@ -420,6 +444,7 @@ __export(db_exports, {
|
|
|
420
444
|
dbCommand: () => dbCommand,
|
|
421
445
|
dbDiff: () => dbDiff,
|
|
422
446
|
dbDump: () => dbDump,
|
|
447
|
+
dbExecute: () => dbExecute,
|
|
423
448
|
dbPull: () => dbPull,
|
|
424
449
|
dbPush: () => dbPush,
|
|
425
450
|
dbReset: () => dbReset,
|
|
@@ -447,7 +472,10 @@ async function dbPush() {
|
|
|
447
472
|
const schemaPath = await findSchemaFile();
|
|
448
473
|
if (!schemaPath) {
|
|
449
474
|
spinner.fail("No schema file found");
|
|
450
|
-
error("Could not find schema.prisma, schema.sql, or
|
|
475
|
+
error("Could not find prisma/schema.prisma, db/schema.sql, or schema.sql");
|
|
476
|
+
console.log("");
|
|
477
|
+
console.log(" To push SQL directly use: kb db execute --file <file>");
|
|
478
|
+
console.log(" To apply migrations use: kb migration up");
|
|
451
479
|
process.exit(1);
|
|
452
480
|
}
|
|
453
481
|
spinner.text = "Pushing schema to database...";
|
|
@@ -481,6 +509,12 @@ async function dbPull() {
|
|
|
481
509
|
const spinner = createSpinner("Pulling schema from database...");
|
|
482
510
|
try {
|
|
483
511
|
const env = await getLocalEnv();
|
|
512
|
+
if (!env.DATABASE_URL && !env.KOLAYBASE_DATABASE_URL) {
|
|
513
|
+
spinner.fail("DATABASE_URL not found");
|
|
514
|
+
error("Run kb link to refresh credentials");
|
|
515
|
+
process.exit(1);
|
|
516
|
+
}
|
|
517
|
+
const dbUrl = env.DATABASE_URL || env.KOLAYBASE_DATABASE_URL;
|
|
484
518
|
const prismaPath = path4.join(process.cwd(), "prisma", "schema.prisma");
|
|
485
519
|
try {
|
|
486
520
|
await fs3.access(prismaPath);
|
|
@@ -489,14 +523,14 @@ async function dbPull() {
|
|
|
489
523
|
stdio: "inherit",
|
|
490
524
|
env: {
|
|
491
525
|
...process.env,
|
|
492
|
-
DATABASE_URL:
|
|
526
|
+
DATABASE_URL: dbUrl
|
|
493
527
|
}
|
|
494
528
|
});
|
|
495
529
|
spinner.succeed("Schema pulled successfully");
|
|
496
530
|
} catch {
|
|
497
531
|
spinner.text = "Generating SQL dump...";
|
|
498
532
|
const pool = new Pool({
|
|
499
|
-
connectionString:
|
|
533
|
+
connectionString: dbUrl
|
|
500
534
|
});
|
|
501
535
|
const client = await pool.connect();
|
|
502
536
|
try {
|
|
@@ -643,14 +677,67 @@ async function dbDiff() {
|
|
|
643
677
|
error("Not in a Kolaybase project. Run: kb init");
|
|
644
678
|
process.exit(1);
|
|
645
679
|
}
|
|
680
|
+
const env = await getLocalEnv();
|
|
681
|
+
const dbUrl = env.DATABASE_URL || env.KOLAYBASE_DATABASE_URL;
|
|
646
682
|
info("Checking for schema differences...");
|
|
647
683
|
try {
|
|
648
684
|
const { execa } = await import("execa");
|
|
649
|
-
await execa("npx", ["prisma", "migrate", "diff"], {
|
|
685
|
+
await execa("npx", ["prisma", "migrate", "diff", "--from-schema-datasource", "prisma/schema.prisma", "--to-url", dbUrl || ""], {
|
|
650
686
|
stdio: "inherit"
|
|
651
687
|
});
|
|
688
|
+
} catch {
|
|
689
|
+
warning("Could not generate diff. Make sure Prisma is configured and DATABASE_URL is set.");
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
async function dbExecute(options) {
|
|
693
|
+
console.log(chalk9.bold.cyan("Execute SQL\n"));
|
|
694
|
+
const config = await getProjectConfig();
|
|
695
|
+
if (!config?.projectId) {
|
|
696
|
+
error("Not in a Kolaybase project. Run: kb init");
|
|
697
|
+
process.exit(1);
|
|
698
|
+
}
|
|
699
|
+
if (!options.file && !options.query) {
|
|
700
|
+
error("Provide --file <path> or --query <sql>");
|
|
701
|
+
process.exit(1);
|
|
702
|
+
}
|
|
703
|
+
let sql;
|
|
704
|
+
if (options.file) {
|
|
705
|
+
try {
|
|
706
|
+
sql = await fs3.readFile(options.file, "utf-8");
|
|
707
|
+
info(`Executing ${chalk9.cyan(options.file)}\u2026`);
|
|
708
|
+
} catch {
|
|
709
|
+
error(`Could not read file: ${options.file}`);
|
|
710
|
+
process.exit(1);
|
|
711
|
+
}
|
|
712
|
+
} else {
|
|
713
|
+
sql = options.query;
|
|
714
|
+
info("Executing query\u2026");
|
|
715
|
+
}
|
|
716
|
+
const spinner = createSpinner("Running\u2026");
|
|
717
|
+
try {
|
|
718
|
+
const result = await apiClient.executeSQL(config.projectId, sql);
|
|
719
|
+
spinner.succeed("Done");
|
|
720
|
+
if (result?.rows?.length) {
|
|
721
|
+
console.log();
|
|
722
|
+
const cols = Object.keys(result.rows[0]);
|
|
723
|
+
const colWidths = cols.map(
|
|
724
|
+
(c) => Math.max(c.length, ...result.rows.map((r) => String(r[c] ?? "").length))
|
|
725
|
+
);
|
|
726
|
+
const header = cols.map((c, i) => c.padEnd(colWidths[i])).join(" ");
|
|
727
|
+
const divider = colWidths.map((w) => "\u2500".repeat(w)).join(" ");
|
|
728
|
+
console.log(" " + chalk9.bold(header));
|
|
729
|
+
console.log(" " + chalk9.gray(divider));
|
|
730
|
+
for (const row2 of result.rows) {
|
|
731
|
+
console.log(" " + cols.map((c, i) => String(row2[c] ?? "").padEnd(colWidths[i])).join(" "));
|
|
732
|
+
}
|
|
733
|
+
console.log();
|
|
734
|
+
console.log(chalk9.gray(` ${result.rows.length} row(s)`));
|
|
735
|
+
} else {
|
|
736
|
+
success(`Query executed. ${result?.rowCount ?? 0} row(s) affected.`);
|
|
737
|
+
}
|
|
652
738
|
} catch (err) {
|
|
653
|
-
|
|
739
|
+
spinner.fail("Execution failed");
|
|
740
|
+
handleApiError(err);
|
|
654
741
|
}
|
|
655
742
|
}
|
|
656
743
|
async function dbDump(options) {
|
|
@@ -707,13 +794,12 @@ async function findSchemaFile() {
|
|
|
707
794
|
const paths = [
|
|
708
795
|
"prisma/schema.prisma",
|
|
709
796
|
"db/schema.sql",
|
|
710
|
-
"schema.sql"
|
|
711
|
-
"migrations"
|
|
797
|
+
"schema.sql"
|
|
712
798
|
];
|
|
713
799
|
for (const p of paths) {
|
|
714
800
|
try {
|
|
715
|
-
await fs3.
|
|
716
|
-
return p;
|
|
801
|
+
const stat = await fs3.stat(p);
|
|
802
|
+
if (stat.isFile()) return p;
|
|
717
803
|
} catch {
|
|
718
804
|
}
|
|
719
805
|
}
|
|
@@ -1270,6 +1356,245 @@ var init_gen = __esm({
|
|
|
1270
1356
|
}
|
|
1271
1357
|
});
|
|
1272
1358
|
|
|
1359
|
+
// src/commands/migration.ts
|
|
1360
|
+
var migration_exports = {};
|
|
1361
|
+
__export(migration_exports, {
|
|
1362
|
+
migrationDown: () => migrationDown,
|
|
1363
|
+
migrationNew: () => migrationNew,
|
|
1364
|
+
migrationStatus: () => migrationStatus,
|
|
1365
|
+
migrationUp: () => migrationUp
|
|
1366
|
+
});
|
|
1367
|
+
import chalk12 from "chalk";
|
|
1368
|
+
import fs5 from "fs/promises";
|
|
1369
|
+
import path6 from "path";
|
|
1370
|
+
async function ensureTrackingTable(projectId) {
|
|
1371
|
+
await apiClient.executeSQL(projectId, `
|
|
1372
|
+
CREATE TABLE IF NOT EXISTS "${TRACKING_TABLE}" (
|
|
1373
|
+
id SERIAL PRIMARY KEY,
|
|
1374
|
+
name TEXT UNIQUE NOT NULL,
|
|
1375
|
+
applied_at TIMESTAMPTZ DEFAULT NOW()
|
|
1376
|
+
)
|
|
1377
|
+
`);
|
|
1378
|
+
}
|
|
1379
|
+
function parseMigration(content) {
|
|
1380
|
+
const upMatch = content.match(/--\s*up\s*\n([\s\S]*?)(?:--\s*down\s*\n|$)/i);
|
|
1381
|
+
const downMatch = content.match(/--\s*down\s*\n([\s\S]*?)$/i);
|
|
1382
|
+
if (upMatch) {
|
|
1383
|
+
return {
|
|
1384
|
+
up: upMatch[1].trim(),
|
|
1385
|
+
down: downMatch ? downMatch[1].trim() : null
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
return { up: content.trim(), down: null };
|
|
1389
|
+
}
|
|
1390
|
+
async function getApplied(projectId) {
|
|
1391
|
+
try {
|
|
1392
|
+
const result = await apiClient.executeSQL(
|
|
1393
|
+
projectId,
|
|
1394
|
+
`SELECT name FROM "${TRACKING_TABLE}" ORDER BY applied_at`
|
|
1395
|
+
);
|
|
1396
|
+
return new Set((result?.rows ?? []).map((r) => r.name));
|
|
1397
|
+
} catch {
|
|
1398
|
+
return /* @__PURE__ */ new Set();
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
async function getLocalMigrations() {
|
|
1402
|
+
try {
|
|
1403
|
+
const files = await fs5.readdir(MIGRATIONS_DIR);
|
|
1404
|
+
return files.filter((f) => f.endsWith(".sql") && !f.endsWith(".down.sql")).sort();
|
|
1405
|
+
} catch {
|
|
1406
|
+
return [];
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
async function migrationNew(name) {
|
|
1410
|
+
if (!name?.trim()) {
|
|
1411
|
+
error("Provide a migration name: kb migration new <name>");
|
|
1412
|
+
process.exit(1);
|
|
1413
|
+
}
|
|
1414
|
+
await fs5.mkdir(MIGRATIONS_DIR, { recursive: true });
|
|
1415
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[-T:\.Z]/g, "").slice(0, 14);
|
|
1416
|
+
const safeName = name.toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
1417
|
+
const filename = `${ts}_${safeName}.sql`;
|
|
1418
|
+
const filepath = path6.join(MIGRATIONS_DIR, filename);
|
|
1419
|
+
const template = `-- Migration: ${safeName}
|
|
1420
|
+
-- Created: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1421
|
+
|
|
1422
|
+
-- up
|
|
1423
|
+
|
|
1424
|
+
-- write your SQL here
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
-- down
|
|
1428
|
+
|
|
1429
|
+
-- write rollback SQL here (optional)
|
|
1430
|
+
|
|
1431
|
+
`;
|
|
1432
|
+
await fs5.writeFile(filepath, template);
|
|
1433
|
+
success(`Created ${chalk12.cyan(filepath)}`);
|
|
1434
|
+
}
|
|
1435
|
+
async function migrationStatus() {
|
|
1436
|
+
const config = await getProjectConfig();
|
|
1437
|
+
if (!config?.projectId) {
|
|
1438
|
+
error("Not linked to a project. Run: kb link or kb init");
|
|
1439
|
+
process.exit(1);
|
|
1440
|
+
}
|
|
1441
|
+
const spinner = createSpinner("Checking migration status\u2026");
|
|
1442
|
+
try {
|
|
1443
|
+
await ensureTrackingTable(config.projectId);
|
|
1444
|
+
const applied = await getApplied(config.projectId);
|
|
1445
|
+
const local = await getLocalMigrations();
|
|
1446
|
+
spinner.stop();
|
|
1447
|
+
if (!local.length) {
|
|
1448
|
+
info("No migration files found in ./migrations/");
|
|
1449
|
+
console.log(chalk12.gray(" Create one: kb migration new <name>"));
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
console.log();
|
|
1453
|
+
const nameW = Math.max(10, ...local.map((f) => f.length));
|
|
1454
|
+
console.log(
|
|
1455
|
+
` ${"Migration".padEnd(nameW)} Status`
|
|
1456
|
+
);
|
|
1457
|
+
console.log(chalk12.gray(` ${"\u2500".repeat(nameW + 12)}`));
|
|
1458
|
+
for (const file of local) {
|
|
1459
|
+
const isApplied = applied.has(file);
|
|
1460
|
+
const badge = isApplied ? chalk12.green("\u2713 applied") : chalk12.yellow("\u25CB pending");
|
|
1461
|
+
console.log(` ${chalk12.cyan(file.padEnd(nameW))} ${badge}`);
|
|
1462
|
+
}
|
|
1463
|
+
const pendingCount = local.filter((f) => !applied.has(f)).length;
|
|
1464
|
+
console.log();
|
|
1465
|
+
console.log(chalk12.gray(` ${local.length} migration(s) \u2014 ${applied.size} applied, ${pendingCount} pending`));
|
|
1466
|
+
if (pendingCount > 0) {
|
|
1467
|
+
console.log(chalk12.gray(" Run kb migration up to apply pending migrations"));
|
|
1468
|
+
}
|
|
1469
|
+
} catch (err) {
|
|
1470
|
+
spinner.fail("Failed to get migration status");
|
|
1471
|
+
handleApiError(err);
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
async function migrationUp(options = {}) {
|
|
1475
|
+
const config = await getProjectConfig();
|
|
1476
|
+
if (!config?.projectId) {
|
|
1477
|
+
error("Not linked to a project. Run: kb link or kb init");
|
|
1478
|
+
process.exit(1);
|
|
1479
|
+
}
|
|
1480
|
+
const maxStep = options.step ? parseInt(options.step, 10) : Infinity;
|
|
1481
|
+
const spinner = createSpinner("Preparing migrations\u2026");
|
|
1482
|
+
try {
|
|
1483
|
+
await ensureTrackingTable(config.projectId);
|
|
1484
|
+
const applied = await getApplied(config.projectId);
|
|
1485
|
+
const local = await getLocalMigrations();
|
|
1486
|
+
const pending = local.filter((f) => !applied.has(f)).slice(0, maxStep);
|
|
1487
|
+
spinner.stop();
|
|
1488
|
+
if (!pending.length) {
|
|
1489
|
+
success("Already up to date");
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
console.log();
|
|
1493
|
+
info(`${pending.length} pending migration(s) to apply:`);
|
|
1494
|
+
pending.forEach((f) => console.log(chalk12.gray(` \u2022 ${f}`)));
|
|
1495
|
+
console.log();
|
|
1496
|
+
if (options.dryRun) {
|
|
1497
|
+
warning("Dry run \u2014 no changes made");
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
let applied_count = 0;
|
|
1501
|
+
for (const file of pending) {
|
|
1502
|
+
const sp = createSpinner(`Applying ${chalk12.cyan(file)}\u2026`);
|
|
1503
|
+
try {
|
|
1504
|
+
const content = await fs5.readFile(path6.join(MIGRATIONS_DIR, file), "utf-8");
|
|
1505
|
+
const { up } = parseMigration(content);
|
|
1506
|
+
if (!up) {
|
|
1507
|
+
sp.fail(`No SQL found in ${file}`);
|
|
1508
|
+
continue;
|
|
1509
|
+
}
|
|
1510
|
+
await apiClient.executeSQL(config.projectId, up);
|
|
1511
|
+
await apiClient.executeSQL(
|
|
1512
|
+
config.projectId,
|
|
1513
|
+
`INSERT INTO "${TRACKING_TABLE}" (name) VALUES ('${file.replace(/'/g, "''")}')`
|
|
1514
|
+
);
|
|
1515
|
+
sp.succeed(`Applied ${chalk12.cyan(file)}`);
|
|
1516
|
+
applied_count++;
|
|
1517
|
+
} catch (err) {
|
|
1518
|
+
sp.fail(`Failed: ${file}`);
|
|
1519
|
+
error(err.message || String(err));
|
|
1520
|
+
error("Migration stopped. Fix the error and run kb migration up again.");
|
|
1521
|
+
process.exit(1);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
console.log();
|
|
1525
|
+
success(`${applied_count} migration(s) applied`);
|
|
1526
|
+
} catch (err) {
|
|
1527
|
+
spinner.fail("Migration failed");
|
|
1528
|
+
handleApiError(err);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
async function migrationDown(options = {}) {
|
|
1532
|
+
const config = await getProjectConfig();
|
|
1533
|
+
if (!config?.projectId) {
|
|
1534
|
+
error("Not linked to a project. Run: kb link or kb init");
|
|
1535
|
+
process.exit(1);
|
|
1536
|
+
}
|
|
1537
|
+
const stepCount = options.step ? parseInt(options.step, 10) : 1;
|
|
1538
|
+
const spinner = createSpinner("Preparing rollback\u2026");
|
|
1539
|
+
try {
|
|
1540
|
+
await ensureTrackingTable(config.projectId);
|
|
1541
|
+
const applied = await getApplied(config.projectId);
|
|
1542
|
+
const local = await getLocalMigrations();
|
|
1543
|
+
const toRollback = local.filter((f) => applied.has(f)).reverse().slice(0, stepCount);
|
|
1544
|
+
spinner.stop();
|
|
1545
|
+
if (!toRollback.length) {
|
|
1546
|
+
info("Nothing to rollback");
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
console.log();
|
|
1550
|
+
info(`Rolling back ${toRollback.length} migration(s):`);
|
|
1551
|
+
toRollback.forEach((f) => console.log(chalk12.gray(` \u2022 ${f}`)));
|
|
1552
|
+
console.log();
|
|
1553
|
+
if (options.dryRun) {
|
|
1554
|
+
warning("Dry run \u2014 no changes made");
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
for (const file of toRollback) {
|
|
1558
|
+
const sp = createSpinner(`Rolling back ${chalk12.cyan(file)}\u2026`);
|
|
1559
|
+
try {
|
|
1560
|
+
const content = await fs5.readFile(path6.join(MIGRATIONS_DIR, file), "utf-8");
|
|
1561
|
+
const { down } = parseMigration(content);
|
|
1562
|
+
if (!down) {
|
|
1563
|
+
sp.fail(`No -- down section in ${file} \u2014 skipping`);
|
|
1564
|
+
continue;
|
|
1565
|
+
}
|
|
1566
|
+
await apiClient.executeSQL(config.projectId, down);
|
|
1567
|
+
await apiClient.executeSQL(
|
|
1568
|
+
config.projectId,
|
|
1569
|
+
`DELETE FROM "${TRACKING_TABLE}" WHERE name = '${file.replace(/'/g, "''")}'`
|
|
1570
|
+
);
|
|
1571
|
+
sp.succeed(`Rolled back ${chalk12.cyan(file)}`);
|
|
1572
|
+
} catch (err) {
|
|
1573
|
+
sp.fail(`Failed: ${file}`);
|
|
1574
|
+
error(err.message || String(err));
|
|
1575
|
+
process.exit(1);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
console.log();
|
|
1579
|
+
success(`${toRollback.length} migration(s) rolled back`);
|
|
1580
|
+
} catch (err) {
|
|
1581
|
+
spinner.fail("Rollback failed");
|
|
1582
|
+
handleApiError(err);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
var MIGRATIONS_DIR, TRACKING_TABLE;
|
|
1586
|
+
var init_migration = __esm({
|
|
1587
|
+
"src/commands/migration.ts"() {
|
|
1588
|
+
"use strict";
|
|
1589
|
+
init_esm_shims();
|
|
1590
|
+
init_api();
|
|
1591
|
+
init_config();
|
|
1592
|
+
init_ui();
|
|
1593
|
+
MIGRATIONS_DIR = "migrations";
|
|
1594
|
+
TRACKING_TABLE = "_kb_migrations";
|
|
1595
|
+
}
|
|
1596
|
+
});
|
|
1597
|
+
|
|
1273
1598
|
// src/commands/secrets.ts
|
|
1274
1599
|
var secrets_exports = {};
|
|
1275
1600
|
__export(secrets_exports, {
|
|
@@ -1277,9 +1602,9 @@ __export(secrets_exports, {
|
|
|
1277
1602
|
setSecret: () => setSecret,
|
|
1278
1603
|
unsetSecret: () => unsetSecret
|
|
1279
1604
|
});
|
|
1280
|
-
import
|
|
1605
|
+
import chalk13 from "chalk";
|
|
1281
1606
|
async function listSecrets() {
|
|
1282
|
-
console.log(
|
|
1607
|
+
console.log(chalk13.bold.cyan("Environment Secrets\n"));
|
|
1283
1608
|
const config = await getProjectConfig();
|
|
1284
1609
|
if (!config) {
|
|
1285
1610
|
error("Not in a Kolaybase project. Run: kb init");
|
|
@@ -1290,7 +1615,7 @@ async function listSecrets() {
|
|
|
1290
1615
|
if (Object.keys(env).length === 0) {
|
|
1291
1616
|
info("No secrets configured");
|
|
1292
1617
|
console.log();
|
|
1293
|
-
console.log(
|
|
1618
|
+
console.log(chalk13.gray("Add a secret with:"), chalk13.cyan("kb secrets set KEY VALUE"));
|
|
1294
1619
|
return;
|
|
1295
1620
|
}
|
|
1296
1621
|
const masked = Object.entries(env).reduce((acc, [key, value]) => {
|
|
@@ -1302,13 +1627,13 @@ async function listSecrets() {
|
|
|
1302
1627
|
}, {});
|
|
1303
1628
|
printKeyValue(masked);
|
|
1304
1629
|
console.log();
|
|
1305
|
-
console.log(
|
|
1630
|
+
console.log(chalk13.gray(`Total: ${Object.keys(env).length} secret(s)`));
|
|
1306
1631
|
} catch (err) {
|
|
1307
1632
|
error(`Failed to list secrets: ${err.message}`);
|
|
1308
1633
|
}
|
|
1309
1634
|
}
|
|
1310
1635
|
async function setSecret(key, value) {
|
|
1311
|
-
console.log(
|
|
1636
|
+
console.log(chalk13.bold.cyan("Set Secret\n"));
|
|
1312
1637
|
const config = await getProjectConfig();
|
|
1313
1638
|
if (!config) {
|
|
1314
1639
|
error("Not in a Kolaybase project. Run: kb init");
|
|
@@ -1316,7 +1641,7 @@ async function setSecret(key, value) {
|
|
|
1316
1641
|
}
|
|
1317
1642
|
try {
|
|
1318
1643
|
await setLocalEnv(key, value);
|
|
1319
|
-
success(`Secret ${
|
|
1644
|
+
success(`Secret ${chalk13.cyan(key)} set successfully`);
|
|
1320
1645
|
console.log();
|
|
1321
1646
|
info("Secret saved to .env file");
|
|
1322
1647
|
} catch (err) {
|
|
@@ -1324,7 +1649,7 @@ async function setSecret(key, value) {
|
|
|
1324
1649
|
}
|
|
1325
1650
|
}
|
|
1326
1651
|
async function unsetSecret(key) {
|
|
1327
|
-
console.log(
|
|
1652
|
+
console.log(chalk13.bold.cyan("Remove Secret\n"));
|
|
1328
1653
|
const config = await getProjectConfig();
|
|
1329
1654
|
if (!config) {
|
|
1330
1655
|
error("Not in a Kolaybase project. Run: kb init");
|
|
@@ -1332,7 +1657,7 @@ async function unsetSecret(key) {
|
|
|
1332
1657
|
}
|
|
1333
1658
|
try {
|
|
1334
1659
|
await unsetLocalEnv(key);
|
|
1335
|
-
success(`Secret ${
|
|
1660
|
+
success(`Secret ${chalk13.cyan(key)} removed successfully`);
|
|
1336
1661
|
} catch (err) {
|
|
1337
1662
|
error(`Failed to remove secret: ${err.message}`);
|
|
1338
1663
|
}
|
|
@@ -1355,6 +1680,9 @@ var init_secrets = __esm({
|
|
|
1355
1680
|
// src/index.ts
|
|
1356
1681
|
init_esm_shims();
|
|
1357
1682
|
import { Command } from "commander";
|
|
1683
|
+
import { readFileSync } from "fs";
|
|
1684
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1685
|
+
import { dirname, resolve } from "path";
|
|
1358
1686
|
|
|
1359
1687
|
// src/commands/login.ts
|
|
1360
1688
|
init_esm_shims();
|
|
@@ -1371,9 +1699,9 @@ async function loginCommand(options) {
|
|
|
1371
1699
|
const answers = await inquirer.prompt([
|
|
1372
1700
|
{
|
|
1373
1701
|
type: "input",
|
|
1374
|
-
name: "
|
|
1375
|
-
message: "
|
|
1376
|
-
validate: (v) => v.length >
|
|
1702
|
+
name: "email",
|
|
1703
|
+
message: "Email:",
|
|
1704
|
+
validate: (v) => v.includes("@") && v.length > 3 || "Please enter a valid email"
|
|
1377
1705
|
},
|
|
1378
1706
|
{
|
|
1379
1707
|
type: "password",
|
|
@@ -1385,13 +1713,13 @@ async function loginCommand(options) {
|
|
|
1385
1713
|
]);
|
|
1386
1714
|
const spinner = createSpinner("Authenticating\u2026");
|
|
1387
1715
|
try {
|
|
1388
|
-
const data = await apiClient.login(answers.
|
|
1716
|
+
const data = await apiClient.login(answers.email, answers.password);
|
|
1389
1717
|
setAccessToken(data.accessToken);
|
|
1390
1718
|
setRefreshToken(data.refreshToken);
|
|
1391
|
-
setUserConfig({
|
|
1719
|
+
setUserConfig({ email: answers.email });
|
|
1392
1720
|
spinner.succeed("Logged in");
|
|
1393
1721
|
console.log();
|
|
1394
|
-
success(`Welcome, ${chalk3.cyan(answers.
|
|
1722
|
+
success(`Welcome, ${chalk3.cyan(answers.email)}`);
|
|
1395
1723
|
console.log(chalk3.gray(" Run kb init to create a project or kb link to connect to one"));
|
|
1396
1724
|
} catch (err) {
|
|
1397
1725
|
spinner.fail("Authentication failed");
|
|
@@ -1852,8 +2180,10 @@ function truncate(s, max) {
|
|
|
1852
2180
|
}
|
|
1853
2181
|
|
|
1854
2182
|
// src/index.ts
|
|
2183
|
+
var __dirname2 = dirname(fileURLToPath2(import.meta.url));
|
|
2184
|
+
var pkg = JSON.parse(readFileSync(resolve(__dirname2, "..", "package.json"), "utf-8"));
|
|
1855
2185
|
var program = new Command();
|
|
1856
|
-
program.name("kb").description("Kolaybase CLI \u2014 manage your Kolaybase projects").version(
|
|
2186
|
+
program.name("kb").description("Kolaybase CLI \u2014 manage your Kolaybase projects").version(pkg.version);
|
|
1857
2187
|
program.command("login").description("Authenticate with the Kolaybase platform").option("--api-url <url>", "Platform API URL (default: https://api.kolaybase.com)").action(loginCommand);
|
|
1858
2188
|
program.command("init").description("Create a new Kolaybase project and link it to the current directory").option("-n, --name <name>", "Project name").action(initCommand);
|
|
1859
2189
|
program.command("link").description("Link current directory to an existing remote project").option("--project-id <id>", "Project ID to link directly").action(linkCommand);
|
|
@@ -1883,6 +2213,14 @@ db.command("dump").description("Dump the full database schema to SQL").option("-
|
|
|
1883
2213
|
const { dbDump: dbDump2 } = await Promise.resolve().then(() => (init_db(), db_exports));
|
|
1884
2214
|
await dbDump2(options);
|
|
1885
2215
|
});
|
|
2216
|
+
db.command("diff").description("Show schema differences between local Prisma schema and remote database").action(async () => {
|
|
2217
|
+
const { dbDiff: dbDiff2 } = await Promise.resolve().then(() => (init_db(), db_exports));
|
|
2218
|
+
await dbDiff2();
|
|
2219
|
+
});
|
|
2220
|
+
db.command("execute").description("Execute a SQL file or inline query against the project database").option("-f, --file <path>", "SQL file to execute").option("-q, --query <sql>", "SQL query to run directly").action(async (options) => {
|
|
2221
|
+
const { dbExecute: dbExecute2 } = await Promise.resolve().then(() => (init_db(), db_exports));
|
|
2222
|
+
await dbExecute2(options);
|
|
2223
|
+
});
|
|
1886
2224
|
program.command("inspect").description("Show database tables, columns, sizes, and row counts").option("-t, --table <name>", "Inspect a specific table").action(async (options) => {
|
|
1887
2225
|
const { inspectCommand: inspectCommand2 } = await Promise.resolve().then(() => (init_inspect(), inspect_exports));
|
|
1888
2226
|
await inspectCommand2(options);
|
|
@@ -1896,6 +2234,27 @@ gen.command("client").description("Generate a ready-to-use API client").option("
|
|
|
1896
2234
|
const { genClient: genClient2 } = await Promise.resolve().then(() => (init_gen(), gen_exports));
|
|
1897
2235
|
await genClient2(options);
|
|
1898
2236
|
});
|
|
2237
|
+
var migration = program.command("migration").alias("migrate").description("Manage database migrations");
|
|
2238
|
+
migration.command("new <name>").description("Create a new migration file").action(async (name) => {
|
|
2239
|
+
const { migrationNew: migrationNew2 } = await Promise.resolve().then(() => (init_migration(), migration_exports));
|
|
2240
|
+
await migrationNew2(name);
|
|
2241
|
+
});
|
|
2242
|
+
migration.command("up").description("Apply pending migrations").option("-s, --step <n>", "Apply at most N migrations").option("--dry-run", "Preview without applying").action(async (options) => {
|
|
2243
|
+
const { migrationUp: migrationUp2 } = await Promise.resolve().then(() => (init_migration(), migration_exports));
|
|
2244
|
+
await migrationUp2(options);
|
|
2245
|
+
});
|
|
2246
|
+
migration.command("down").description("Rollback the last applied migration").option("-s, --step <n>", "Roll back N migrations (default: 1)").option("--dry-run", "Preview without rolling back").action(async (options) => {
|
|
2247
|
+
const { migrationDown: migrationDown2 } = await Promise.resolve().then(() => (init_migration(), migration_exports));
|
|
2248
|
+
await migrationDown2(options);
|
|
2249
|
+
});
|
|
2250
|
+
migration.command("status").alias("list").description("Show applied and pending migrations").action(async () => {
|
|
2251
|
+
const { migrationStatus: migrationStatus2 } = await Promise.resolve().then(() => (init_migration(), migration_exports));
|
|
2252
|
+
await migrationStatus2();
|
|
2253
|
+
});
|
|
2254
|
+
program.command("push").description("Shortcut for: kb db push").action(async () => {
|
|
2255
|
+
const { dbPush: dbPush2 } = await Promise.resolve().then(() => (init_db(), db_exports));
|
|
2256
|
+
await dbPush2();
|
|
2257
|
+
});
|
|
1899
2258
|
program.command("logs").description("Show SQL audit logs for the linked project").option("-n, --tail <lines>", "Number of recent entries", "50").action(logsCommand);
|
|
1900
2259
|
var secrets = program.command("secrets").description("Manage local .env variables for the linked project");
|
|
1901
2260
|
secrets.command("list").description("List all variables (sensitive values masked)").action(async () => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/lib/config.ts","../src/lib/api.ts","../src/lib/ui.ts","../src/commands/db.ts","../src/commands/inspect.ts","../src/commands/gen.ts","../src/commands/secrets.ts","../src/index.ts","../src/commands/login.ts","../src/commands/init.ts","../src/commands/projects.ts","../src/commands/status.ts","../src/commands/link.ts","../src/commands/logs.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import Conf from 'conf';\r\nimport path from 'path';\r\nimport fs from 'fs/promises';\r\n\r\nexport interface UserConfig {\r\n apiUrl?: string;\r\n accessToken?: string;\r\n refreshToken?: string;\r\n userId?: string;\r\n username?: string;\r\n email?: string;\r\n}\r\n\r\nexport interface ProjectConfig {\r\n projectId?: string;\r\n projectName?: string;\r\n projectSlug?: string;\r\n teamId?: string;\r\n linkedAt?: string;\r\n}\r\n\r\nconst userConfig = new Conf<UserConfig>({\r\n projectName: 'kolaybase',\r\n configName: 'config',\r\n});\r\n\r\n// Get current project directory\r\nexport async function getProjectRoot(): Promise<string | null> {\r\n let currentDir = process.cwd();\r\n \r\n while (currentDir !== path.parse(currentDir).root) {\r\n const configPath = path.join(currentDir, '.kolaybase');\r\n try {\r\n await fs.access(configPath);\r\n return currentDir;\r\n } catch {\r\n currentDir = path.dirname(currentDir);\r\n }\r\n }\r\n \r\n return null;\r\n}\r\n\r\n// Project-specific configuration\r\nexport async function getProjectConfig(): Promise<ProjectConfig | null> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) return null;\r\n\r\n const configPath = path.join(projectRoot, '.kolaybase', 'config.json');\r\n \r\n try {\r\n const data = await fs.readFile(configPath, 'utf-8');\r\n return JSON.parse(data);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport async function setProjectConfig(config: ProjectConfig): Promise<void> {\r\n const projectRoot = process.cwd();\r\n const configDir = path.join(projectRoot, '.kolaybase');\r\n const configPath = path.join(configDir, 'config.json');\r\n\r\n await fs.mkdir(configDir, { recursive: true });\r\n await fs.writeFile(configPath, JSON.stringify(config, null, 2));\r\n}\r\n\r\n// User configuration helpers\r\nexport function getUserConfig(): UserConfig {\r\n return userConfig.store;\r\n}\r\n\r\nexport function setUserConfig(config: Partial<UserConfig>): void {\r\n userConfig.set(config);\r\n}\r\n\r\nexport function clearUserConfig(): void {\r\n userConfig.clear();\r\n}\r\n\r\nexport const DEFAULT_API_URL = 'https://api.kolaybase.com';\r\n\r\nexport function getApiUrl(): string {\r\n return userConfig.get('apiUrl') || DEFAULT_API_URL;\r\n}\r\n\r\nexport function getAccessToken(): string | undefined {\r\n return userConfig.get('accessToken');\r\n}\r\n\r\nexport function setAccessToken(token: string): void {\r\n userConfig.set('accessToken', token);\r\n}\r\n\r\nexport function getRefreshToken(): string | undefined {\r\n return userConfig.get('refreshToken');\r\n}\r\n\r\nexport function setRefreshToken(token: string): void {\r\n userConfig.set('refreshToken', token);\r\n}\r\n\r\nexport function isLoggedIn(): boolean {\r\n return !!userConfig.get('accessToken');\r\n}\r\n\r\nexport function setApiUrl(url: string): void {\r\n userConfig.set('apiUrl', url);\r\n}\r\n\r\n// Write a .env file with all project credentials\r\nexport async function writeEnvFile(project: any): Promise<void> {\r\n const apiUrl = getApiUrl();\r\n const lines = [\r\n '# Kolaybase — generated by \"kb init\" / \"kb link\"',\r\n '',\r\n `KOLAYBASE_PROJECT_ID=${project.id}`,\r\n `KOLAYBASE_ANON_KEY=${project.anonKey}`,\r\n `KOLAYBASE_SERVICE_KEY=${project.serviceKey}`,\r\n `KOLAYBASE_API_URL=${apiUrl}`,\r\n '',\r\n `KOLAYBASE_PROJECT_SLUG=${project.slug}`,\r\n `KOLAYBASE_DB_HOST=${project.dbHost}`,\r\n `KOLAYBASE_DB_PORT=${project.dbPort}`,\r\n `KOLAYBASE_DB_NAME=${project.dbName}`,\r\n `KOLAYBASE_DB_USER=${project.dbUser}`,\r\n `KOLAYBASE_DB_PASSWORD=${project.dbPassword}`,\r\n `KOLAYBASE_DATABASE_URL=postgresql://${project.dbUser}:${project.dbPassword}@${project.dbHost}:${project.dbPort}/${project.dbName}`,\r\n `KOLAYBASE_KEYCLOAK_REALM=${project.keycloakRealm}`,\r\n '',\r\n ];\r\n\r\n await fs.writeFile('.env', lines.join('\\n'));\r\n\r\n // Make sure .gitignore has .env\r\n try {\r\n let gi = '';\r\n try { gi = await fs.readFile('.gitignore', 'utf-8'); } catch { /* noop */ }\r\n if (!gi.includes('.env')) {\r\n await fs.writeFile('.gitignore', gi + '\\n.env\\n');\r\n }\r\n } catch { /* best-effort */ }\r\n}\r\n\r\n// Local .env management\r\nexport async function getLocalEnv(): Promise<Record<string, string>> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) return {};\r\n\r\n const envPath = path.join(projectRoot, '.env');\r\n \r\n try {\r\n const content = await fs.readFile(envPath, 'utf-8');\r\n const env: Record<string, string> = {};\r\n \r\n content.split('\\n').forEach(line => {\r\n line = line.trim();\r\n if (!line || line.startsWith('#')) return;\r\n \r\n const [key, ...valueParts] = line.split('=');\r\n if (key && valueParts.length > 0) {\r\n env[key.trim()] = valueParts.join('=').trim();\r\n }\r\n });\r\n \r\n return env;\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\nexport async function setLocalEnv(key: string, value: string): Promise<void> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) {\r\n throw new Error('Not in a Kolaybase project directory');\r\n }\r\n\r\n const envPath = path.join(projectRoot, '.env');\r\n let content = '';\r\n \r\n try {\r\n content = await fs.readFile(envPath, 'utf-8');\r\n } catch {\r\n // File doesn't exist, will create new\r\n }\r\n\r\n const lines = content.split('\\n');\r\n let found = false;\r\n \r\n const newLines = lines.map(line => {\r\n const trimmed = line.trim();\r\n if (trimmed.startsWith(`${key}=`)) {\r\n found = true;\r\n return `${key}=${value}`;\r\n }\r\n return line;\r\n });\r\n\r\n if (!found) {\r\n newLines.push(`${key}=${value}`);\r\n }\r\n\r\n await fs.writeFile(envPath, newLines.join('\\n'));\r\n}\r\n\r\nexport async function unsetLocalEnv(key: string): Promise<void> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) {\r\n throw new Error('Not in a Kolaybase project directory');\r\n }\r\n\r\n const envPath = path.join(projectRoot, '.env');\r\n \r\n try {\r\n const content = await fs.readFile(envPath, 'utf-8');\r\n const lines = content.split('\\n').filter(line => {\r\n const trimmed = line.trim();\r\n return !trimmed.startsWith(`${key}=`);\r\n });\r\n \r\n await fs.writeFile(envPath, lines.join('\\n'));\r\n } catch {\r\n // File doesn't exist, nothing to do\r\n }\r\n}\r\n","import axios, { AxiosInstance, AxiosError } from 'axios';\r\nimport chalk from 'chalk';\r\nimport { getApiUrl, getAccessToken, setAccessToken, getRefreshToken, setRefreshToken } from './config.js';\r\n\r\nexport class ApiClient {\r\n private client: AxiosInstance;\r\n\r\n constructor() {\r\n this.client = axios.create({\r\n baseURL: getApiUrl(),\r\n timeout: 30000,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n // Add auth token to requests\r\n this.client.interceptors.request.use((config) => {\r\n const token = getAccessToken();\r\n if (token) {\r\n config.headers.Authorization = `Bearer ${token}`;\r\n }\r\n return config;\r\n });\r\n\r\n // Handle token refresh\r\n this.client.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n const originalRequest = error.config;\r\n \r\n if (error.response?.status === 401 && originalRequest && !(originalRequest as any)._retry) {\r\n (originalRequest as any)._retry = true;\r\n \r\n try {\r\n const refreshToken = getRefreshToken();\r\n if (!refreshToken) {\r\n throw new Error('No refresh token available');\r\n }\r\n\r\n const { data } = await axios.post(`${getApiUrl()}/api/auth/refresh`, {\r\n refreshToken,\r\n });\r\n\r\n setAccessToken(data.accessToken);\r\n setRefreshToken(data.refreshToken);\r\n\r\n originalRequest.headers!.Authorization = `Bearer ${data.accessToken}`;\r\n return this.client(originalRequest);\r\n } catch (refreshError) {\r\n console.error(chalk.red('Session expired. Please login again with: kb login'));\r\n process.exit(1);\r\n }\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n }\r\n\r\n // Auth endpoints\r\n async login(username: string, password: string) {\r\n const { data } = await this.client.post('/api/auth/login', { username, password });\r\n return data;\r\n }\r\n\r\n async signup(userData: {\r\n username: string;\r\n email: string;\r\n password: string;\r\n firstName?: string;\r\n lastName?: string;\r\n }) {\r\n const { data } = await this.client.post('/api/auth/signup', userData);\r\n return data;\r\n }\r\n\r\n // Projects endpoints\r\n async getProjects(teamId: string) {\r\n const { data } = await this.client.get('/api/projects', {\r\n params: { teamId },\r\n });\r\n return data;\r\n }\r\n\r\n async getProject(projectId: string) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}`);\r\n return data;\r\n }\r\n\r\n async createProject(projectData: {\r\n name: string;\r\n description?: string;\r\n teamId: string;\r\n }) {\r\n const { data } = await this.client.post('/api/projects', projectData);\r\n return data;\r\n }\r\n\r\n async deleteProject(projectId: string) {\r\n const { data } = await this.client.delete(`/api/projects/${projectId}`);\r\n return data;\r\n }\r\n\r\n // SQL endpoints\r\n async executeSQL(projectId: string, query: string) {\r\n const { data } = await this.client.post('/api/sql/execute', {\r\n projectId,\r\n query,\r\n });\r\n return data;\r\n }\r\n\r\n // Teams endpoints\r\n async getTeams() {\r\n const { data } = await this.client.get('/api/teams');\r\n return data;\r\n }\r\n\r\n async getActiveTeam() {\r\n const { data } = await this.client.get('/api/teams/active');\r\n return data;\r\n }\r\n\r\n // Project data endpoints\r\n async getTables(projectId: string) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}/data/tables`);\r\n return data;\r\n }\r\n\r\n async getTableSchema(projectId: string, tableName: string) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}/data/tables/${tableName}/schema`);\r\n return data;\r\n }\r\n\r\n async getTableData(projectId: string, tableName: string, options?: {\r\n limit?: number;\r\n offset?: number;\r\n orderBy?: string;\r\n order?: 'asc' | 'desc';\r\n }) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}/data/tables/${tableName}/rows`, {\r\n params: options,\r\n });\r\n return data;\r\n }\r\n}\r\n\r\nexport const apiClient = new ApiClient();\r\n\r\nexport function handleApiError(error: any) {\r\n if (axios.isAxiosError(error)) {\r\n if (error.response) {\r\n const message = error.response.data?.message || error.response.data?.error || error.message;\r\n console.error(chalk.red(`API Error: ${message}`));\r\n \r\n if (error.response.status === 401) {\r\n console.error(chalk.yellow('Please login first with: kb login'));\r\n }\r\n } else if (error.request) {\r\n console.error(chalk.red('Network error: Could not connect to Kolaybase API'));\r\n console.error(chalk.yellow(`Make sure the API is running at: ${getApiUrl()}`));\r\n } else {\r\n console.error(chalk.red(`Error: ${error.message}`));\r\n }\r\n } else {\r\n console.error(chalk.red(`Error: ${error.message || error}`));\r\n }\r\n \r\n process.exit(1);\r\n}\r\n","import chalk from 'chalk';\r\nimport ora, { Ora } from 'ora';\r\nimport boxen from 'boxen';\r\n\r\nexport function success(message: string): void {\r\n console.log(chalk.green('✓'), message);\r\n}\r\n\r\nexport function error(message: string): void {\r\n console.log(chalk.red('✗'), message);\r\n}\r\n\r\nexport function warning(message: string): void {\r\n console.log(chalk.yellow('⚠'), message);\r\n}\r\n\r\nexport function info(message: string): void {\r\n console.log(chalk.blue('ℹ'), message);\r\n}\r\n\r\nexport function log(message: string): void {\r\n console.log(message);\r\n}\r\n\r\nexport function createSpinner(text: string): Ora {\r\n return ora(text).start();\r\n}\r\n\r\nexport function printBox(content: string, options?: {\r\n title?: string;\r\n padding?: number;\r\n borderColor?: string;\r\n}): void {\r\n console.log(\r\n boxen(content, {\r\n padding: options?.padding ?? 1,\r\n margin: 1,\r\n borderStyle: 'round',\r\n title: options?.title,\r\n titleAlignment: 'center',\r\n borderColor: options?.borderColor as any || 'cyan',\r\n })\r\n );\r\n}\r\n\r\nexport function printHeader(text: string): void {\r\n console.log();\r\n console.log(chalk.bold.cyan(text));\r\n console.log(chalk.cyan('─'.repeat(text.length)));\r\n}\r\n\r\nexport function printTable(headers: string[], rows: string[][]): void {\r\n const columnWidths = headers.map((header, i) => {\r\n const maxRowWidth = Math.max(...rows.map(row => (row[i] || '').length));\r\n return Math.max(header.length, maxRowWidth);\r\n });\r\n\r\n // Print headers\r\n const headerRow = headers.map((header, i) => \r\n header.padEnd(columnWidths[i])\r\n ).join(' ');\r\n console.log(chalk.bold(headerRow));\r\n console.log(chalk.gray('─'.repeat(headerRow.length)));\r\n\r\n // Print rows\r\n rows.forEach(row => {\r\n const rowStr = row.map((cell, i) => \r\n (cell || '').padEnd(columnWidths[i])\r\n ).join(' ');\r\n console.log(rowStr);\r\n });\r\n}\r\n\r\nexport function printKeyValue(data: Record<string, string | number | boolean | null | undefined>): void {\r\n const maxKeyLength = Math.max(...Object.keys(data).map(k => k.length));\r\n \r\n Object.entries(data).forEach(([key, value]) => {\r\n const paddedKey = chalk.bold(key.padEnd(maxKeyLength));\r\n const displayValue = value ?? chalk.gray('(not set)');\r\n console.log(`${paddedKey} ${displayValue}`);\r\n });\r\n}\r\n\r\nexport function printJson(data: any): void {\r\n console.log(JSON.stringify(data, null, 2));\r\n}\r\n\r\nexport function clearLine(): void {\r\n process.stdout.write('\\r\\x1b[K');\r\n}\r\n\r\nexport function printLogo(): void {\r\n const logo = `\r\n${chalk.cyan('┌─────────────────────────────────────┐')}\r\n${chalk.cyan('│')} ${chalk.bold.cyan('K O L A Y B A S E')} ${chalk.cyan('│')}\r\n${chalk.cyan('│')} ${chalk.gray('Backend-as-a-Service Platform')} ${chalk.cyan('│')}\r\n${chalk.cyan('└─────────────────────────────────────┘')}\r\n `;\r\n console.log(logo);\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport { Pool } from 'pg';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, getLocalEnv } from '../lib/config.js';\r\nimport { success, error, warning, info, createSpinner } from '../lib/ui.js';\r\n\r\nexport async function dbCommand() {\r\n console.log(chalk.bold.cyan('Database Management\\n'));\r\n info('Use db subcommands: push, pull, reset, seed, diff');\r\n}\r\n\r\nexport async function dbPush() {\r\n console.log(chalk.bold.cyan('Push Database Schema\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Analyzing schema changes...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const schemaPath = await findSchemaFile();\r\n\r\n if (!schemaPath) {\r\n spinner.fail('No schema file found');\r\n error('Could not find schema.prisma, schema.sql, or migrations directory');\r\n process.exit(1);\r\n }\r\n\r\n spinner.text = 'Pushing schema to database...';\r\n\r\n // If Prisma schema exists, use Prisma\r\n if (schemaPath.endsWith('.prisma')) {\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'db', 'push'], {\r\n stdio: 'inherit',\r\n env: {\r\n ...process.env,\r\n DATABASE_URL: env.DATABASE_URL,\r\n },\r\n });\r\n } else {\r\n // Execute SQL file\r\n const sql = await fs.readFile(schemaPath, 'utf-8');\r\n await apiClient.executeSQL(config.projectId!, sql);\r\n }\r\n\r\n spinner.succeed('Schema pushed successfully');\r\n success('Database is up to date');\r\n } catch (err) {\r\n spinner.fail('Failed to push schema');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function dbPull() {\r\n console.log(chalk.bold.cyan('Pull Database Schema\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Pulling schema from database...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n\r\n // Check if Prisma is being used\r\n const prismaPath = path.join(process.cwd(), 'prisma', 'schema.prisma');\r\n \r\n try {\r\n await fs.access(prismaPath);\r\n \r\n // Use Prisma introspection\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'db', 'pull'], {\r\n stdio: 'inherit',\r\n env: {\r\n ...process.env,\r\n DATABASE_URL: env.DATABASE_URL,\r\n },\r\n });\r\n\r\n spinner.succeed('Schema pulled successfully');\r\n } catch {\r\n // No Prisma, generate SQL dump\r\n spinner.text = 'Generating SQL dump...';\r\n \r\n const pool = new Pool({\r\n connectionString: env.DATABASE_URL,\r\n });\r\n\r\n const client = await pool.connect();\r\n \r\n try {\r\n const { rows } = await client.query(`\r\n SELECT table_name \r\n FROM information_schema.tables \r\n WHERE table_schema = 'public'\r\n ORDER BY table_name\r\n `);\r\n\r\n const tables = rows.map(r => r.table_name);\r\n \r\n let schemaDump = '-- Database schema dump\\n\\n';\r\n \r\n for (const table of tables) {\r\n const { rows: columns } = await client.query(`\r\n SELECT column_name, data_type, is_nullable, column_default\r\n FROM information_schema.columns\r\n WHERE table_name = $1\r\n ORDER BY ordinal_position\r\n `, [table]);\r\n\r\n schemaDump += `CREATE TABLE IF NOT EXISTS ${table} (\\n`;\r\n schemaDump += columns.map(col => {\r\n let def = ` ${col.column_name} ${col.data_type}`;\r\n if (col.is_nullable === 'NO') def += ' NOT NULL';\r\n if (col.column_default) def += ` DEFAULT ${col.column_default}`;\r\n return def;\r\n }).join(',\\n');\r\n schemaDump += '\\n);\\n\\n';\r\n }\r\n\r\n await fs.mkdir('db', { recursive: true });\r\n await fs.writeFile('db/schema.sql', schemaDump);\r\n\r\n spinner.succeed('Schema pulled successfully');\r\n info('Schema saved to db/schema.sql');\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to pull schema');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface ResetOptions {\r\n force?: boolean;\r\n}\r\n\r\nexport async function dbReset(options: ResetOptions) {\r\n console.log(chalk.bold.cyan('Reset Database\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n console.log(chalk.yellow('⚠ WARNING: This will delete all data in the database!'));\r\n console.log();\r\n\r\n if (!options.force) {\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'confirm',\r\n message: 'Are you sure you want to reset the database?',\r\n default: false,\r\n },\r\n ]);\r\n\r\n if (!answers.confirm) {\r\n info('Reset cancelled');\r\n return;\r\n }\r\n }\r\n\r\n const spinner = createSpinner('Resetting database...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const pool = new Pool({\r\n connectionString: env.DATABASE_URL,\r\n });\r\n\r\n const client = await pool.connect();\r\n\r\n try {\r\n // Get all tables\r\n const { rows } = await client.query(`\r\n SELECT tablename \r\n FROM pg_tables \r\n WHERE schemaname = 'public'\r\n `);\r\n\r\n // Drop all tables\r\n for (const row of rows) {\r\n await client.query(`DROP TABLE IF EXISTS \"${row.tablename}\" CASCADE`);\r\n }\r\n\r\n spinner.succeed('Database reset successfully');\r\n success('All tables dropped');\r\n \r\n console.log();\r\n info('To recreate schema, run: kb db push');\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to reset database');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function dbSeed() {\r\n console.log(chalk.bold.cyan('Seed Database\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Looking for seed file...');\r\n\r\n try {\r\n const seedPaths = [\r\n 'prisma/seed.ts',\r\n 'prisma/seed.js',\r\n 'db/seed.sql',\r\n 'seeds/seed.sql',\r\n ];\r\n\r\n let seedPath: string | null = null;\r\n\r\n for (const p of seedPaths) {\r\n try {\r\n await fs.access(p);\r\n seedPath = p;\r\n break;\r\n } catch {\r\n // Continue searching\r\n }\r\n }\r\n\r\n if (!seedPath) {\r\n spinner.fail('No seed file found');\r\n warning('Create a seed file at prisma/seed.ts or db/seed.sql');\r\n return;\r\n }\r\n\r\n spinner.text = 'Running seed...';\r\n\r\n if (seedPath.endsWith('.sql')) {\r\n const sql = await fs.readFile(seedPath, 'utf-8');\r\n await apiClient.executeSQL(config.projectId!, sql);\r\n } else {\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'db', 'seed'], {\r\n stdio: 'inherit',\r\n });\r\n }\r\n\r\n spinner.succeed('Database seeded successfully');\r\n } catch (err) {\r\n spinner.fail('Failed to seed database');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function dbDiff() {\r\n console.log(chalk.bold.cyan('Database Schema Diff\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n info('Checking for schema differences...');\r\n \r\n try {\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'migrate', 'diff'], {\r\n stdio: 'inherit',\r\n });\r\n } catch (err) {\r\n warning('Could not generate diff. Make sure Prisma is configured.');\r\n }\r\n}\r\n\r\ninterface DumpOptions {\r\n output?: string;\r\n}\r\n\r\nexport async function dbDump(options: DumpOptions) {\r\n console.log(chalk.bold.cyan('Dump Database Schema\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Dumping schema…');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const pool = new Pool({ connectionString: env.DATABASE_URL });\r\n const client = await pool.connect();\r\n\r\n try {\r\n const { rows: tables } = await client.query(`\r\n SELECT table_name\r\n FROM information_schema.tables\r\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'\r\n ORDER BY table_name\r\n `);\r\n\r\n let dump = '-- Kolaybase schema dump\\n-- Generated: ' + new Date().toISOString() + '\\n\\n';\r\n\r\n for (const t of tables) {\r\n const { rows: cols } = await client.query(`\r\n SELECT column_name, udt_name, is_nullable, column_default, character_maximum_length\r\n FROM information_schema.columns\r\n WHERE table_name = $1\r\n ORDER BY ordinal_position\r\n `, [t.table_name]);\r\n\r\n dump += `CREATE TABLE IF NOT EXISTS \"${t.table_name}\" (\\n`;\r\n dump += cols.map((c: any) => {\r\n let def = ` \"${c.column_name}\" ${c.udt_name}`;\r\n if (c.character_maximum_length) def += `(${c.character_maximum_length})`;\r\n if (c.is_nullable === 'NO') def += ' NOT NULL';\r\n if (c.column_default) def += ` DEFAULT ${c.column_default}`;\r\n return def;\r\n }).join(',\\n');\r\n dump += '\\n);\\n\\n';\r\n }\r\n\r\n const outFile = options.output || 'schema.sql';\r\n await fs.writeFile(outFile, dump);\r\n\r\n spinner.succeed(`Schema dumped to ${chalk.cyan(outFile)}`);\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to dump schema');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nasync function findSchemaFile(): Promise<string | null> {\r\n const paths = [\r\n 'prisma/schema.prisma',\r\n 'db/schema.sql',\r\n 'schema.sql',\r\n 'migrations',\r\n ];\r\n\r\n for (const p of paths) {\r\n try {\r\n await fs.access(p);\r\n return p;\r\n } catch {\r\n // Continue searching\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n","import chalk from 'chalk';\r\nimport { Pool } from 'pg';\r\nimport { getProjectConfig, getLocalEnv } from '../lib/config.js';\r\nimport { error, printHeader, createSpinner } from '../lib/ui.js';\r\n\r\ninterface InspectOptions {\r\n table?: string;\r\n}\r\n\r\nexport async function inspectCommand(options: InspectOptions) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n const env = await getLocalEnv();\r\n if (!env.DATABASE_URL) {\r\n error('DATABASE_URL not found in .env — run kb link to refresh credentials');\r\n process.exit(1);\r\n }\r\n\r\n const pool = new Pool({ connectionString: env.DATABASE_URL });\r\n\r\n try {\r\n if (options.table) {\r\n await inspectTable(pool, options.table);\r\n } else {\r\n await inspectAll(pool);\r\n }\r\n } catch (err: any) {\r\n error(`Database error: ${err.message}`);\r\n process.exit(1);\r\n } finally {\r\n await pool.end();\r\n }\r\n}\r\n\r\nasync function inspectAll(pool: Pool) {\r\n const spinner = createSpinner('Querying database…');\r\n\r\n const { rows } = await pool.query(`\r\n SELECT\r\n t.table_name,\r\n pg_total_relation_size(quote_ident(t.table_name)) AS total_bytes,\r\n pg_size_pretty(pg_total_relation_size(quote_ident(t.table_name))) AS size,\r\n (SELECT reltuples::bigint FROM pg_class WHERE relname = t.table_name) AS est_rows\r\n FROM information_schema.tables t\r\n WHERE t.table_schema = 'public' AND t.table_type = 'BASE TABLE'\r\n ORDER BY total_bytes DESC\r\n `);\r\n\r\n spinner.stop();\r\n\r\n if (!rows.length) {\r\n console.log(chalk.gray(' No tables found. Push a schema first: kb db push'));\r\n return;\r\n }\r\n\r\n printHeader('Tables');\r\n console.log();\r\n\r\n const nameW = Math.max(10, ...rows.map((r: any) => r.table_name.length));\r\n\r\n console.log(\r\n ` ${chalk.bold('Table'.padEnd(nameW))} ${chalk.bold('Rows'.padStart(10))} ${chalk.bold('Size'.padStart(10))}`,\r\n );\r\n console.log(chalk.gray(' ' + '─'.repeat(nameW + 24)));\r\n\r\n for (const r of rows) {\r\n const rowCount = Number(r.est_rows) >= 0 ? Number(r.est_rows).toLocaleString() : '—';\r\n console.log(\r\n ` ${chalk.cyan(r.table_name.padEnd(nameW))} ${rowCount.padStart(10)} ${String(r.size).padStart(10)}`,\r\n );\r\n }\r\n\r\n console.log();\r\n console.log(chalk.gray(` ${rows.length} table(s)`));\r\n console.log(chalk.gray(' Inspect a table: kb inspect --table <name>'));\r\n}\r\n\r\nasync function inspectTable(pool: Pool, tableName: string) {\r\n const spinner = createSpinner(`Inspecting ${tableName}…`);\r\n\r\n // Columns\r\n const { rows: columns } = await pool.query(`\r\n SELECT\r\n c.column_name,\r\n c.data_type,\r\n c.udt_name,\r\n c.is_nullable,\r\n c.column_default,\r\n c.character_maximum_length\r\n FROM information_schema.columns c\r\n WHERE c.table_schema = 'public' AND c.table_name = $1\r\n ORDER BY c.ordinal_position\r\n `, [tableName]);\r\n\r\n if (!columns.length) {\r\n spinner.fail(`Table \"${tableName}\" not found`);\r\n process.exit(1);\r\n }\r\n\r\n // Indexes\r\n const { rows: indexes } = await pool.query(`\r\n SELECT indexname, indexdef\r\n FROM pg_indexes\r\n WHERE schemaname = 'public' AND tablename = $1\r\n `, [tableName]);\r\n\r\n // Foreign keys\r\n const { rows: fkeys } = await pool.query(`\r\n SELECT\r\n kcu.column_name,\r\n ccu.table_name AS foreign_table,\r\n ccu.column_name AS foreign_column\r\n FROM information_schema.table_constraints tc\r\n JOIN information_schema.key_column_usage kcu\r\n ON tc.constraint_name = kcu.constraint_name\r\n JOIN information_schema.constraint_column_usage ccu\r\n ON tc.constraint_name = ccu.constraint_name\r\n WHERE tc.table_name = $1 AND tc.constraint_type = 'FOREIGN KEY'\r\n `, [tableName]);\r\n\r\n // Row count + size\r\n const { rows: meta } = await pool.query(`\r\n SELECT\r\n pg_size_pretty(pg_total_relation_size(quote_ident($1))) AS size,\r\n (SELECT reltuples::bigint FROM pg_class WHERE relname = $1) AS est_rows\r\n `, [tableName]);\r\n\r\n spinner.stop();\r\n\r\n printHeader(`Table: ${tableName}`);\r\n console.log();\r\n\r\n if (meta[0]) {\r\n console.log(` ${chalk.gray('Rows')} ${Number(meta[0].est_rows).toLocaleString()}`);\r\n console.log(` ${chalk.gray('Size')} ${meta[0].size}`);\r\n console.log();\r\n }\r\n\r\n // Columns table\r\n console.log(chalk.bold(' Columns'));\r\n\r\n const nameW = Math.max(6, ...columns.map((c: any) => c.column_name.length));\r\n const typeW = Math.max(4, ...columns.map((c: any) => formatType(c).length));\r\n\r\n console.log(\r\n ` ${chalk.gray('Name'.padEnd(nameW))} ${chalk.gray('Type'.padEnd(typeW))} ${chalk.gray('Nullable')} ${chalk.gray('Default')}`,\r\n );\r\n console.log(chalk.gray(' ' + '─'.repeat(nameW + typeW + 24)));\r\n\r\n for (const col of columns) {\r\n const nullable = col.is_nullable === 'YES' ? chalk.yellow('YES') : chalk.gray('NO ');\r\n const def = col.column_default ? chalk.gray(truncate(col.column_default, 30)) : '';\r\n const fk = fkeys.find((f: any) => f.column_name === col.column_name);\r\n const fkLabel = fk ? chalk.blue(` → ${fk.foreign_table}.${fk.foreign_column}`) : '';\r\n\r\n console.log(\r\n ` ${chalk.cyan(col.column_name.padEnd(nameW))} ${formatType(col).padEnd(typeW)} ${nullable} ${def}${fkLabel}`,\r\n );\r\n }\r\n\r\n // Indexes\r\n if (indexes.length) {\r\n console.log();\r\n console.log(chalk.bold(' Indexes'));\r\n for (const idx of indexes) {\r\n console.log(` ${chalk.gray('•')} ${idx.indexname}`);\r\n }\r\n }\r\n\r\n console.log();\r\n}\r\n\r\nfunction formatType(col: any): string {\r\n let t = col.udt_name || col.data_type;\r\n if (col.character_maximum_length) t += `(${col.character_maximum_length})`;\r\n return t;\r\n}\r\n\r\nfunction truncate(s: string, max: number): string {\r\n return s.length > max ? s.slice(0, max - 1) + '…' : s;\r\n}\r\n","import chalk from 'chalk';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { Pool } from 'pg';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, getLocalEnv } from '../lib/config.js';\r\nimport { success, error, info, createSpinner } from '../lib/ui.js';\r\n\r\ninterface GenTypesOptions {\r\n output?: string;\r\n}\r\n\r\nexport async function genTypes(options: GenTypesOptions) {\r\n console.log(chalk.bold.cyan('Generate TypeScript Types\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Generating types from database schema...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const pool = new Pool({\r\n connectionString: env.DATABASE_URL,\r\n });\r\n\r\n const client = await pool.connect();\r\n \r\n try {\r\n // Get all tables\r\n const { rows: tables } = await client.query(`\r\n SELECT table_name \r\n FROM information_schema.tables \r\n WHERE table_schema = 'public'\r\n ORDER BY table_name\r\n `);\r\n\r\n let typesContent = `// Generated by Kolaybase CLI\r\n// Do not edit manually\r\n\r\nexport interface Database {\r\n${tables.map((t: any) => ` ${t.table_name}: ${toPascalCase(t.table_name)};`).join('\\n')}\r\n}\r\n\r\n`;\r\n\r\n // Generate types for each table\r\n for (const table of tables) {\r\n const { rows: columns } = await client.query(`\r\n SELECT \r\n column_name, \r\n data_type, \r\n is_nullable,\r\n column_default\r\n FROM information_schema.columns\r\n WHERE table_name = $1\r\n ORDER BY ordinal_position\r\n `, [table.table_name]);\r\n\r\n const typeName = toPascalCase(table.table_name);\r\n \r\n typesContent += `export interface ${typeName} {\\n`;\r\n \r\n columns.forEach((col: any) => {\r\n const tsType = pgTypeToTs(col.data_type);\r\n const optional = col.is_nullable === 'YES' || col.column_default ? '?' : '';\r\n typesContent += ` ${col.column_name}${optional}: ${tsType};\\n`;\r\n });\r\n \r\n typesContent += `}\\n\\n`;\r\n }\r\n\r\n // Write to file\r\n const outputDir = options.output || 'types';\r\n await fs.mkdir(outputDir, { recursive: true });\r\n const outputPath = path.join(outputDir, 'database.ts');\r\n await fs.writeFile(outputPath, typesContent);\r\n\r\n spinner.succeed('Types generated successfully');\r\n success(`Written to ${chalk.cyan(outputPath)}`);\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to generate types');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface GenClientOptions {\r\n lang?: string;\r\n output?: string;\r\n}\r\n\r\nexport async function genClient(options: GenClientOptions) {\r\n console.log(chalk.bold.cyan('Generate API Client\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Generating API client...');\r\n\r\n try {\r\n const lang = options.lang || 'typescript';\r\n const outputDir = options.output || 'lib';\r\n\r\n if (lang === 'typescript') {\r\n await generateTsClient(config, outputDir);\r\n } else if (lang === 'javascript') {\r\n await generateJsClient(config, outputDir);\r\n } else if (lang === 'python') {\r\n await generatePyClient(config, outputDir);\r\n } else {\r\n throw new Error(`Unsupported language: ${lang}`);\r\n }\r\n\r\n spinner.succeed('Client generated successfully');\r\n success(`Written to ${chalk.cyan(outputDir)}`);\r\n } catch (err) {\r\n spinner.fail('Failed to generate client');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nasync function generateTsClient(config: any, outputDir: string) {\r\n const clientContent = `// Generated by Kolaybase CLI\r\nimport axios, { AxiosInstance } from 'axios';\r\n\r\nexport interface KolaybaseConfig {\r\n url?: string;\r\n anonKey?: string;\r\n serviceKey?: string;\r\n}\r\n\r\nexport class KolaybaseClient {\r\n private client: AxiosInstance;\r\n private projectId: string;\r\n\r\n constructor(config: KolaybaseConfig = {}) {\r\n this.projectId = '${config.projectId}';\r\n \r\n this.client = axios.create({\r\n baseURL: config.url || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': \\`Bearer \\${config.anonKey || process.env.ANON_KEY}\\`,\r\n },\r\n });\r\n }\r\n\r\n // Execute raw SQL\r\n async sql<T = any>(query: string): Promise<T[]> {\r\n const { data } = await this.client.post('/sql/execute', {\r\n projectId: this.projectId,\r\n query,\r\n });\r\n return data.rows;\r\n }\r\n\r\n // Table operations\r\n table<T = any>(tableName: string) {\r\n return {\r\n select: async (columns = '*', options?: {\r\n where?: Record<string, any>;\r\n limit?: number;\r\n offset?: number;\r\n orderBy?: string;\r\n }): Promise<T[]> => {\r\n let query = \\`SELECT \\${columns} FROM \\${tableName}\\`;\r\n \r\n if (options?.where) {\r\n const conditions = Object.entries(options.where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n query += \\` WHERE \\${conditions}\\`;\r\n }\r\n \r\n if (options?.orderBy) {\r\n query += \\` ORDER BY \\${options.orderBy}\\`;\r\n }\r\n \r\n if (options?.limit) {\r\n query += \\` LIMIT \\${options.limit}\\`;\r\n }\r\n \r\n if (options?.offset) {\r\n query += \\` OFFSET \\${options.offset}\\`;\r\n }\r\n\r\n return this.sql<T>(query);\r\n },\r\n\r\n insert: async (data: Partial<T> | Partial<T>[]): Promise<T[]> => {\r\n const rows = Array.isArray(data) ? data : [data];\r\n const keys = Object.keys(rows[0]);\r\n const values = rows.map(row => \r\n \\`(\\${keys.map(k => \\`'\\${(row as any)[k]}'\\`).join(', ')})\\`\r\n ).join(', ');\r\n\r\n const query = \\`\r\n INSERT INTO \\${tableName} (\\${keys.join(', ')}) \r\n VALUES \\${values}\r\n RETURNING *\r\n \\`;\r\n\r\n return this.sql<T>(query);\r\n },\r\n\r\n update: async (data: Partial<T>, where: Record<string, any>): Promise<T[]> => {\r\n const sets = Object.entries(data)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(', ');\r\n \r\n const conditions = Object.entries(where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n\r\n const query = \\`\r\n UPDATE \\${tableName} \r\n SET \\${sets} \r\n WHERE \\${conditions}\r\n RETURNING *\r\n \\`;\r\n\r\n return this.sql<T>(query);\r\n },\r\n\r\n delete: async (where: Record<string, any>): Promise<T[]> => {\r\n const conditions = Object.entries(where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n\r\n const query = \\`DELETE FROM \\${tableName} WHERE \\${conditions} RETURNING *\\`;\r\n return this.sql<T>(query);\r\n },\r\n };\r\n }\r\n}\r\n\r\nexport function createClient(config?: KolaybaseConfig): KolaybaseClient {\r\n return new KolaybaseClient(config);\r\n}\r\n`;\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(path.join(outputDir, 'kolaybase.ts'), clientContent);\r\n}\r\n\r\nasync function generateJsClient(config: any, outputDir: string) {\r\n const clientContent = `// Generated by Kolaybase CLI\r\nconst axios = require('axios');\r\n\r\nclass KolaybaseClient {\r\n constructor(config = {}) {\r\n this.projectId = '${config.projectId}';\r\n \r\n this.client = axios.create({\r\n baseURL: config.url || process.env.API_URL || 'http://localhost:4000',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': \\`Bearer \\${config.anonKey || process.env.ANON_KEY}\\`,\r\n },\r\n });\r\n }\r\n\r\n async sql(query) {\r\n const { data } = await this.client.post('/sql/execute', {\r\n projectId: this.projectId,\r\n query,\r\n });\r\n return data.rows;\r\n }\r\n\r\n table(tableName) {\r\n return {\r\n select: async (columns = '*', options = {}) => {\r\n let query = \\`SELECT \\${columns} FROM \\${tableName}\\`;\r\n \r\n if (options.where) {\r\n const conditions = Object.entries(options.where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n query += \\` WHERE \\${conditions}\\`;\r\n }\r\n\r\n return this.sql(query);\r\n },\r\n\r\n insert: async (data) => {\r\n const rows = Array.isArray(data) ? data : [data];\r\n const keys = Object.keys(rows[0]);\r\n const values = rows.map(row => \r\n \\`(\\${keys.map(k => \\`'\\${row[k]}'\\`).join(', ')})\\`\r\n ).join(', ');\r\n\r\n const query = \\`INSERT INTO \\${tableName} (\\${keys.join(', ')}) VALUES \\${values} RETURNING *\\`;\r\n return this.sql(query);\r\n },\r\n };\r\n }\r\n}\r\n\r\nfunction createClient(config) {\r\n return new KolaybaseClient(config);\r\n}\r\n\r\nmodule.exports = { KolaybaseClient, createClient };\r\n`;\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(path.join(outputDir, 'kolaybase.js'), clientContent);\r\n}\r\n\r\nasync function generatePyClient(config: any, outputDir: string) {\r\n const clientContent = `# Generated by Kolaybase CLI\r\nimport os\r\nimport requests\r\nfrom typing import List, Dict, Any, Optional\r\n\r\nclass KolaybaseClient:\r\n def __init__(self, config: Optional[Dict[str, str]] = None):\r\n config = config or {}\r\n self.project_id = '${config.projectId}'\r\n self.base_url = config.get('url', os.getenv('API_URL', 'http://localhost:4000'))\r\n self.anon_key = config.get('anon_key', os.getenv('ANON_KEY'))\r\n \r\n self.session = requests.Session()\r\n self.session.headers.update({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': f'Bearer {self.anon_key}'\r\n })\r\n \r\n def sql(self, query: str) -> List[Dict[str, Any]]:\r\n response = self.session.post(\r\n f'{self.base_url}/sql/execute',\r\n json={'projectId': self.project_id, 'query': query}\r\n )\r\n response.raise_for_status()\r\n return response.json()['rows']\r\n \r\n def table(self, table_name: str):\r\n class TableOperations:\r\n def __init__(self, client, table):\r\n self.client = client\r\n self.table = table\r\n \r\n def select(self, columns='*', where=None, limit=None):\r\n query = f'SELECT {columns} FROM {self.table}'\r\n \r\n if where:\r\n conditions = ' AND '.join([f\"{k} = '{v}'\" for k, v in where.items()])\r\n query += f' WHERE {conditions}'\r\n \r\n if limit:\r\n query += f' LIMIT {limit}'\r\n \r\n return self.client.sql(query)\r\n \r\n return TableOperations(self, table_name)\r\n\r\ndef create_client(config: Optional[Dict[str, str]] = None) -> KolaybaseClient:\r\n return KolaybaseClient(config)\r\n`;\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(path.join(outputDir, 'kolaybase.py'), clientContent);\r\n}\r\n\r\nfunction toPascalCase(str: string): string {\r\n return str\r\n .split('_')\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\r\n .join('');\r\n}\r\n\r\nfunction pgTypeToTs(pgType: string): string {\r\n const typeMap: Record<string, string> = {\r\n 'integer': 'number',\r\n 'bigint': 'number',\r\n 'smallint': 'number',\r\n 'decimal': 'number',\r\n 'numeric': 'number',\r\n 'real': 'number',\r\n 'double precision': 'number',\r\n 'serial': 'number',\r\n 'bigserial': 'number',\r\n 'character varying': 'string',\r\n 'varchar': 'string',\r\n 'character': 'string',\r\n 'char': 'string',\r\n 'text': 'string',\r\n 'boolean': 'boolean',\r\n 'date': 'string',\r\n 'timestamp': 'string',\r\n 'timestamp without time zone': 'string',\r\n 'timestamp with time zone': 'string',\r\n 'time': 'string',\r\n 'json': 'any',\r\n 'jsonb': 'any',\r\n 'uuid': 'string',\r\n 'bytea': 'Buffer',\r\n };\r\n\r\n return typeMap[pgType.toLowerCase()] || 'any';\r\n}\r\n","import chalk from 'chalk';\r\nimport { getProjectConfig, setLocalEnv, unsetLocalEnv, getLocalEnv } from '../lib/config.js';\r\nimport { error, success, info, printKeyValue } from '../lib/ui.js';\r\n\r\nexport async function listSecrets() {\r\n console.log(chalk.bold.cyan('Environment Secrets\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n \r\n if (Object.keys(env).length === 0) {\r\n info('No secrets configured');\r\n console.log();\r\n console.log(chalk.gray('Add a secret with:'), chalk.cyan('kb secrets set KEY VALUE'));\r\n return;\r\n }\r\n\r\n // Hide sensitive values\r\n const masked = Object.entries(env).reduce((acc, [key, value]) => {\r\n const sensitive = ['PASSWORD', 'SECRET', 'KEY', 'TOKEN'].some(s => \r\n key.toUpperCase().includes(s)\r\n );\r\n \r\n acc[key] = sensitive ? maskValue(value) : value;\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n printKeyValue(masked);\r\n \r\n console.log();\r\n console.log(chalk.gray(`Total: ${Object.keys(env).length} secret(s)`));\r\n } catch (err: any) {\r\n error(`Failed to list secrets: ${err.message}`);\r\n }\r\n}\r\n\r\nexport async function setSecret(key: string, value: string) {\r\n console.log(chalk.bold.cyan('Set Secret\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n await setLocalEnv(key, value);\r\n success(`Secret ${chalk.cyan(key)} set successfully`);\r\n \r\n console.log();\r\n info('Secret saved to .env file');\r\n } catch (err: any) {\r\n error(`Failed to set secret: ${err.message}`);\r\n }\r\n}\r\n\r\nexport async function unsetSecret(key: string) {\r\n console.log(chalk.bold.cyan('Remove Secret\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n await unsetLocalEnv(key);\r\n success(`Secret ${chalk.cyan(key)} removed successfully`);\r\n } catch (err: any) {\r\n error(`Failed to remove secret: ${err.message}`);\r\n }\r\n}\r\n\r\nfunction maskValue(value: string): string {\r\n if (value.length <= 8) {\r\n return '*'.repeat(value.length);\r\n }\r\n \r\n return value.substring(0, 4) + '*'.repeat(value.length - 8) + value.substring(value.length - 4);\r\n}\r\n","import { Command } from 'commander';\r\nimport { loginCommand } from './commands/login.js';\r\nimport { initCommand } from './commands/init.js';\r\nimport { projectsCommand, createProject, deleteProject } from './commands/projects.js';\r\nimport { statusCommand } from './commands/status.js';\r\nimport { linkCommand, unlinkProject } from './commands/link.js';\r\nimport { logsCommand } from './commands/logs.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('kb')\r\n .description('Kolaybase CLI — manage your Kolaybase projects')\r\n .version('0.1.0');\r\n\r\n// ── Authentication ──────────────────────────────────────────\r\n\r\nprogram\r\n .command('login')\r\n .description('Authenticate with the Kolaybase platform')\r\n .option('--api-url <url>', 'Platform API URL (default: https://api.kolaybase.com)')\r\n .action(loginCommand);\r\n\r\n// ── Project lifecycle ───────────────────────────────────────\r\n\r\nprogram\r\n .command('init')\r\n .description('Create a new Kolaybase project and link it to the current directory')\r\n .option('-n, --name <name>', 'Project name')\r\n .action(initCommand);\r\n\r\nprogram\r\n .command('link')\r\n .description('Link current directory to an existing remote project')\r\n .option('--project-id <id>', 'Project ID to link directly')\r\n .action(linkCommand);\r\n\r\nprogram\r\n .command('unlink')\r\n .description('Remove the project link from the current directory')\r\n .action(unlinkProject);\r\n\r\n// ── Project info ────────────────────────────────────────────\r\n\r\nprogram\r\n .command('status')\r\n .description('Show credentials, keys, and connection info for the linked project')\r\n .option('--show-keys', 'Reveal secret values instead of masking them')\r\n .action(statusCommand);\r\n\r\nprogram\r\n .command('projects')\r\n .alias('list')\r\n .description('List all projects in your team')\r\n .action(projectsCommand);\r\n\r\nprogram\r\n .command('projects:create')\r\n .description('Create a new project without linking')\r\n .option('-n, --name <name>', 'Project name')\r\n .option('-d, --description <description>', 'Project description')\r\n .action(createProject);\r\n\r\nprogram\r\n .command('projects:delete <projectId>')\r\n .description('Delete a remote project (requires confirmation)')\r\n .action(deleteProject);\r\n\r\n// ── Database ────────────────────────────────────────────────\r\n\r\nconst db = program\r\n .command('db')\r\n .description('Manage the project database');\r\n\r\ndb.command('push')\r\n .description('Push local schema to the project database')\r\n .action(async () => {\r\n const { dbPush } = await import('./commands/db.js');\r\n await dbPush();\r\n });\r\n\r\ndb.command('pull')\r\n .description('Introspect the remote database and save schema locally')\r\n .action(async () => {\r\n const { dbPull } = await import('./commands/db.js');\r\n await dbPull();\r\n });\r\n\r\ndb.command('reset')\r\n .description('Drop all tables in the project database')\r\n .option('-f, --force', 'Skip confirmation prompt')\r\n .action(async (options) => {\r\n const { dbReset } = await import('./commands/db.js');\r\n await dbReset(options);\r\n });\r\n\r\ndb.command('seed')\r\n .description('Run the seed file against the project database')\r\n .action(async () => {\r\n const { dbSeed } = await import('./commands/db.js');\r\n await dbSeed();\r\n });\r\n\r\ndb.command('dump')\r\n .description('Dump the full database schema to SQL')\r\n .option('-o, --output <file>', 'Output file', 'schema.sql')\r\n .action(async (options) => {\r\n const { dbDump } = await import('./commands/db.js');\r\n await dbDump(options);\r\n });\r\n\r\n// ── Inspect ─────────────────────────────────────────────────\r\n\r\nprogram\r\n .command('inspect')\r\n .description('Show database tables, columns, sizes, and row counts')\r\n .option('-t, --table <name>', 'Inspect a specific table')\r\n .action(async (options) => {\r\n const { inspectCommand } = await import('./commands/inspect.js');\r\n await inspectCommand(options);\r\n });\r\n\r\n// ── Code generation ─────────────────────────────────────────\r\n\r\nconst gen = program\r\n .command('gen')\r\n .description('Generate code from the project database');\r\n\r\ngen.command('types')\r\n .description('Generate TypeScript types from the database schema')\r\n .option('-o, --output <path>', 'Output directory', './types')\r\n .action(async (options) => {\r\n const { genTypes } = await import('./commands/gen.js');\r\n await genTypes(options);\r\n });\r\n\r\ngen.command('client')\r\n .description('Generate a ready-to-use API client')\r\n .option('-l, --lang <language>', 'Language: typescript | javascript | python', 'typescript')\r\n .option('-o, --output <path>', 'Output directory', './lib')\r\n .action(async (options) => {\r\n const { genClient } = await import('./commands/gen.js');\r\n await genClient(options);\r\n });\r\n\r\n// ── Logs ────────────────────────────────────────────────────\r\n\r\nprogram\r\n .command('logs')\r\n .description('Show SQL audit logs for the linked project')\r\n .option('-n, --tail <lines>', 'Number of recent entries', '50')\r\n .action(logsCommand);\r\n\r\n// ── Secrets / env ───────────────────────────────────────────\r\n\r\nconst secrets = program\r\n .command('secrets')\r\n .description('Manage local .env variables for the linked project');\r\n\r\nsecrets.command('list')\r\n .description('List all variables (sensitive values masked)')\r\n .action(async () => {\r\n const { listSecrets } = await import('./commands/secrets.js');\r\n await listSecrets();\r\n });\r\n\r\nsecrets.command('set <key> <value>')\r\n .description('Set or update a variable')\r\n .action(async (key, value) => {\r\n const { setSecret } = await import('./commands/secrets.js');\r\n await setSecret(key, value);\r\n });\r\n\r\nsecrets.command('unset <key>')\r\n .description('Remove a variable')\r\n .action(async (key) => {\r\n const { unsetSecret } = await import('./commands/secrets.js');\r\n await unsetSecret(key);\r\n });\r\n\r\nprogram.parse();\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { setUserConfig, setAccessToken, setRefreshToken, setApiUrl } from '../lib/config.js';\r\nimport { success, createSpinner, printLogo } from '../lib/ui.js';\r\n\r\ninterface LoginOptions {\r\n apiUrl?: string;\r\n}\r\n\r\nexport async function loginCommand(options: LoginOptions) {\r\n printLogo();\r\n\r\n if (options.apiUrl) {\r\n setApiUrl(options.apiUrl);\r\n }\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'username',\r\n message: 'Username:',\r\n validate: (v: string) => v.length > 0 || 'Required',\r\n },\r\n {\r\n type: 'password',\r\n name: 'password',\r\n message: 'Password:',\r\n mask: '*',\r\n validate: (v: string) => v.length > 0 || 'Required',\r\n },\r\n ]);\r\n\r\n const spinner = createSpinner('Authenticating…');\r\n\r\n try {\r\n const data = await apiClient.login(answers.username, answers.password);\r\n\r\n setAccessToken(data.accessToken);\r\n setRefreshToken(data.refreshToken);\r\n setUserConfig({ username: answers.username });\r\n\r\n spinner.succeed('Logged in');\r\n console.log();\r\n success(`Welcome, ${chalk.cyan(answers.username)}`);\r\n console.log(chalk.gray(' Run kb init to create a project or kb link to connect to one'));\r\n } catch (err) {\r\n spinner.fail('Authentication failed');\r\n handleApiError(err);\r\n }\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport path from 'path';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { setProjectConfig, isLoggedIn, getProjectConfig, writeEnvFile } from '../lib/config.js';\r\nimport { success, error, warning, createSpinner, printHeader } from '../lib/ui.js';\r\n\r\ninterface InitOptions {\r\n name?: string;\r\n}\r\n\r\nexport async function initCommand(options: InitOptions) {\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n const existingConfig = await getProjectConfig();\r\n if (existingConfig?.projectId) {\r\n warning(`This directory is already linked to project \"${existingConfig.projectName}\"`);\r\n console.log(chalk.gray(` ID: ${existingConfig.projectId}`));\r\n console.log();\r\n console.log(chalk.gray(' To link to a different project run: kb link'));\r\n console.log(chalk.gray(' To unlink first: kb unlink'));\r\n return;\r\n }\r\n\r\n const spinner = createSpinner('Loading teams…');\r\n\r\n try {\r\n const teams = await apiClient.getTeams();\r\n spinner.stop();\r\n\r\n if (!teams?.length) {\r\n error('No teams found. Create an account first via the Admin UI.');\r\n process.exit(1);\r\n }\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'teamId',\r\n message: 'Team:',\r\n choices: teams.map((t: any) => ({\r\n name: t.personalForUserId ? `${t.name} ${chalk.gray('(personal)')}` : t.name,\r\n value: t.id,\r\n })),\r\n when: teams.length > 1,\r\n },\r\n {\r\n type: 'input',\r\n name: 'name',\r\n message: 'Project name:',\r\n default: options.name || path.basename(process.cwd()),\r\n validate: (v: string) => v.trim().length > 0 || 'Required',\r\n },\r\n {\r\n type: 'input',\r\n name: 'description',\r\n message: 'Description (optional):',\r\n },\r\n ]);\r\n\r\n const teamId = answers.teamId || teams[0].id;\r\n\r\n const createSpinnerInstance = createSpinner('Creating project…');\r\n\r\n const project = await apiClient.createProject({\r\n name: answers.name,\r\n description: answers.description || undefined,\r\n teamId,\r\n });\r\n\r\n createSpinnerInstance.succeed('Project created');\r\n\r\n await setProjectConfig({\r\n projectId: project.id,\r\n projectName: project.name,\r\n projectSlug: project.slug,\r\n teamId: project.teamId,\r\n linkedAt: new Date().toISOString(),\r\n });\r\n\r\n await writeEnvFile(project);\r\n\r\n console.log();\r\n printHeader('Project ready');\r\n console.log();\r\n console.log(` ${chalk.gray('Name')} ${project.name}`);\r\n console.log(` ${chalk.gray('ID')} ${project.id}`);\r\n console.log(` ${chalk.gray('Database')} ${project.dbName}`);\r\n console.log(` ${chalk.gray('Realm')} ${project.keycloakRealm}`);\r\n console.log();\r\n success('Configuration saved to .kolaybase/config.json');\r\n success('Credentials saved to .env');\r\n console.log();\r\n console.log(chalk.gray(' Next steps:'));\r\n console.log(chalk.gray(' kb status — view full connection details'));\r\n console.log(chalk.gray(' kb inspect — list database tables'));\r\n console.log(chalk.gray(' kb gen types — generate TypeScript types'));\r\n console.log(chalk.gray(' kb db push — push a local schema'));\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { isLoggedIn } from '../lib/config.js';\r\nimport { success, error, info, createSpinner, printTable, printHeader } from '../lib/ui.js';\r\n\r\nexport async function projectsCommand() {\r\n if (!isLoggedIn()) {\r\n error('You must be logged in to view projects');\r\n console.log(chalk.gray('Run: kb login'));\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Loading projects...');\r\n\r\n try {\r\n const teams = await apiClient.getTeams();\r\n const team = teams[0]; // Use first team\r\n const projects = await apiClient.getProjects(team.id);\r\n \r\n spinner.stop();\r\n\r\n if (!projects || projects.length === 0) {\r\n info('No projects found');\r\n console.log();\r\n console.log(chalk.gray('Create your first project with:'), chalk.cyan('kb init'));\r\n return;\r\n }\r\n\r\n printHeader('Your Projects');\r\n console.log();\r\n\r\n const rows = projects.map((project: any) => [\r\n chalk.cyan(project.name),\r\n project.slug,\r\n project.status,\r\n new Date(project.createdAt).toLocaleDateString(),\r\n project.id,\r\n ]);\r\n\r\n printTable(\r\n ['Name', 'Slug', 'Status', 'Created', 'ID'],\r\n rows\r\n );\r\n\r\n console.log();\r\n console.log(chalk.gray(`Total: ${projects.length} project(s)`));\r\n } catch (err) {\r\n spinner.fail('Failed to load projects');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface CreateProjectOptions {\r\n name?: string;\r\n description?: string;\r\n}\r\n\r\nexport async function createProject(options: CreateProjectOptions) {\r\n if (!isLoggedIn()) {\r\n error('You must be logged in to create a project');\r\n console.log(chalk.gray('Run: kb login'));\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n const teams = await apiClient.getTeams();\r\n const team = teams[0];\r\n\r\n let name = options.name;\r\n let description = options.description;\r\n\r\n if (!name) {\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'name',\r\n message: 'Project name:',\r\n validate: (input) => input.length > 0 || 'Project name is required',\r\n },\r\n {\r\n type: 'input',\r\n name: 'description',\r\n message: 'Description (optional):',\r\n },\r\n ]);\r\n\r\n name = answers.name;\r\n description = answers.description;\r\n }\r\n\r\n const spinner = createSpinner('Creating project...');\r\n\r\n const project = await apiClient.createProject({\r\n name: name!,\r\n description,\r\n teamId: team.id,\r\n });\r\n\r\n spinner.succeed('Project created successfully');\r\n \r\n console.log();\r\n console.log(chalk.gray('Name:'), chalk.cyan(project.name));\r\n console.log(chalk.gray('ID:'), project.id);\r\n console.log(chalk.gray('Slug:'), project.slug);\r\n console.log(chalk.gray('Database:'), project.dbName);\r\n \r\n console.log();\r\n console.log(chalk.gray('To start working with this project:'));\r\n console.log(chalk.cyan(' kb init --link'));\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function deleteProject(projectId: string) {\r\n if (!isLoggedIn()) {\r\n error('You must be logged in to delete a project');\r\n console.log(chalk.gray('Run: kb login'));\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n const spinner = createSpinner('Loading project...');\r\n const project = await apiClient.getProject(projectId);\r\n spinner.stop();\r\n\r\n console.log();\r\n console.log(chalk.yellow('⚠ WARNING: This action cannot be undone!'));\r\n console.log();\r\n console.log(chalk.gray('Project:'), chalk.cyan(project.name));\r\n console.log(chalk.gray('Database:'), project.dbName);\r\n console.log();\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'confirm',\r\n message: 'Are you sure you want to delete this project?',\r\n default: false,\r\n },\r\n {\r\n type: 'input',\r\n name: 'confirmName',\r\n message: `Type the project name \"${project.name}\" to confirm:`,\r\n when: (answers) => answers.confirm,\r\n validate: (input) => \r\n input === project.name || `You must type \"${project.name}\" exactly`,\r\n },\r\n ]);\r\n\r\n if (!answers.confirm) {\r\n info('Deletion cancelled');\r\n return;\r\n }\r\n\r\n const deleteSpinner = createSpinner('Deleting project...');\r\n await apiClient.deleteProject(projectId);\r\n deleteSpinner.succeed('Project deleted successfully');\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n","import chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, isLoggedIn } from '../lib/config.js';\r\nimport { error, printHeader, createSpinner } from '../lib/ui.js';\r\n\r\ninterface StatusOptions {\r\n showKeys?: boolean;\r\n}\r\n\r\nexport async function statusCommand(options: StatusOptions) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Fetching project details…');\r\n\r\n try {\r\n const project = await apiClient.getProject(config.projectId);\r\n spinner.stop();\r\n\r\n const mask = (val: string) =>\r\n options.showKeys ? val : val.slice(0, 6) + '•'.repeat(Math.max(0, val.length - 10)) + val.slice(-4);\r\n\r\n printHeader(`Project: ${project.name}`);\r\n console.log();\r\n\r\n // ── General ──────────────────────────────────────────\r\n section('General');\r\n row('Project ID', project.id);\r\n row('Name', project.name);\r\n row('Slug', project.slug);\r\n row('Status', statusBadge(project.status));\r\n row('Created', new Date(project.createdAt).toLocaleString());\r\n console.log();\r\n\r\n // ── Database ─────────────────────────────────────────\r\n section('Database');\r\n row('Host', project.dbHost);\r\n row('Port', String(project.dbPort));\r\n row('Database', project.dbName);\r\n row('User', project.dbUser);\r\n row('Password', mask(project.dbPassword));\r\n console.log();\r\n\r\n const connStr = `postgresql://${project.dbUser}:${options.showKeys ? project.dbPassword : '••••••'}@${project.dbHost}:${project.dbPort}/${project.dbName}`;\r\n row('Connection string', chalk.cyan(connStr));\r\n console.log();\r\n\r\n // ── Auth / Keycloak ──────────────────────────────────\r\n section('Authentication (Keycloak)');\r\n row('Realm', project.keycloakRealm);\r\n row('Anon Key', mask(project.anonKey));\r\n row('Service Key', mask(project.serviceKey));\r\n console.log();\r\n\r\n // ── Hint ─────────────────────────────────────────────\r\n if (!options.showKeys) {\r\n console.log(chalk.gray(' Tip: use kb status --show-keys to reveal secrets'));\r\n }\r\n console.log();\r\n } catch (err) {\r\n spinner.fail('Could not fetch project');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nfunction section(title: string) {\r\n console.log(chalk.bold(` ${title}`));\r\n}\r\n\r\nfunction row(label: string, value: string) {\r\n console.log(` ${chalk.gray(label.padEnd(20))} ${value}`);\r\n}\r\n\r\nfunction statusBadge(status: string): string {\r\n switch (status) {\r\n case 'ACTIVE':\r\n return chalk.green('● ACTIVE');\r\n case 'PAUSED':\r\n return chalk.yellow('● PAUSED');\r\n case 'DELETED':\r\n return chalk.red('● DELETED');\r\n default:\r\n return status;\r\n }\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport fs from 'fs/promises';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { setProjectConfig, isLoggedIn, writeEnvFile } from '../lib/config.js';\r\nimport { success, error, createSpinner } from '../lib/ui.js';\r\n\r\ninterface LinkOptions {\r\n projectId?: string;\r\n}\r\n\r\nexport async function linkCommand(options: LinkOptions) {\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n let projectId = options.projectId;\r\n\r\n if (!projectId) {\r\n const spinner = createSpinner('Loading projects…');\r\n const teams = await apiClient.getTeams();\r\n\r\n let allProjects: any[] = [];\r\n for (const team of teams) {\r\n const projects = await apiClient.getProjects(team.id);\r\n allProjects.push(\r\n ...projects.map((p: any) => ({ ...p, teamName: team.name })),\r\n );\r\n }\r\n spinner.stop();\r\n\r\n if (!allProjects.length) {\r\n error('No projects found. Create one first: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const { selected } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'selected',\r\n message: 'Select a project to link:',\r\n choices: allProjects.map((p) => ({\r\n name: `${p.name} ${chalk.gray(p.slug)} ${chalk.gray('— ' + p.teamName)}`,\r\n value: p.id,\r\n })),\r\n },\r\n ]);\r\n\r\n projectId = selected;\r\n }\r\n\r\n const spinner = createSpinner('Linking…');\r\n const project = await apiClient.getProject(projectId!);\r\n\r\n await setProjectConfig({\r\n projectId: project.id,\r\n projectName: project.name,\r\n projectSlug: project.slug,\r\n teamId: project.teamId,\r\n linkedAt: new Date().toISOString(),\r\n });\r\n\r\n await writeEnvFile(project);\r\n\r\n spinner.succeed(`Linked to ${chalk.cyan(project.name)}`);\r\n console.log();\r\n console.log(` ${chalk.gray('Database')} ${project.dbName}`);\r\n console.log(` ${chalk.gray('Realm')} ${project.keycloakRealm}`);\r\n console.log();\r\n success('Credentials saved to .env');\r\n console.log(chalk.gray(' Run kb status to see full connection details'));\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function unlinkProject() {\r\n try {\r\n await fs.rm('.kolaybase', { recursive: true, force: true });\r\n success('Project unlinked');\r\n } catch (err: any) {\r\n error(`Failed to unlink: ${err.message}`);\r\n }\r\n}\r\n","import chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, isLoggedIn } from '../lib/config.js';\r\nimport { error, printHeader, createSpinner } from '../lib/ui.js';\r\n\r\ninterface LogsOptions {\r\n tail?: string;\r\n}\r\n\r\nexport async function logsCommand(options: LogsOptions) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n const limit = parseInt(options.tail || '50', 10);\r\n\r\n const spinner = createSpinner('Fetching SQL audit logs…');\r\n\r\n try {\r\n const result = await apiClient.executeSQL(\r\n config.projectId!,\r\n `SELECT 1`, // quick connectivity test\r\n );\r\n } catch {\r\n // If SQL endpoint fails we try a direct query via project info\r\n }\r\n\r\n try {\r\n // The audit logs live in the platform DB, not the project DB.\r\n // We'll expose them via the existing SQL endpoint against the project.\r\n // For now, show the last N entries from the API (requires a future endpoint).\r\n\r\n // Fallback: connect directly to the platform database\r\n const { Pool } = await import('pg');\r\n const { getLocalEnv } = await import('../lib/config.js');\r\n const env = await getLocalEnv();\r\n\r\n // Platform DB is the same host but database 'kolaybase'\r\n const host = env.DB_HOST || 'localhost';\r\n const port = env.DB_PORT || '5432';\r\n const platformUrl = `postgresql://kolaybase:kolaybase_secret@${host}:${port}/kolaybase`;\r\n\r\n const pool = new Pool({ connectionString: platformUrl });\r\n const client = await pool.connect();\r\n\r\n try {\r\n const { rows } = await client.query(\r\n `SELECT created_at, user_id, query, row_count, duration, error\r\n FROM sql_audit_logs\r\n WHERE project_id = $1\r\n ORDER BY created_at DESC\r\n LIMIT $2`,\r\n [config.projectId, limit],\r\n );\r\n\r\n spinner.stop();\r\n\r\n if (!rows.length) {\r\n console.log(chalk.gray(' No SQL logs yet for this project.'));\r\n return;\r\n }\r\n\r\n printHeader('SQL Audit Logs');\r\n console.log();\r\n\r\n // Show oldest first\r\n rows.reverse().forEach((r: any) => {\r\n const ts = new Date(r.created_at).toLocaleString();\r\n const dur = r.duration != null ? `${r.duration}ms` : '';\r\n const badge = r.error\r\n ? chalk.red('ERR')\r\n : chalk.green('OK ');\r\n\r\n console.log(` ${chalk.gray(ts)} ${badge} ${chalk.gray(dur)}`);\r\n console.log(` ${chalk.cyan(truncate(r.query, 100))}`);\r\n\r\n if (r.error) {\r\n console.log(` ${chalk.red(r.error)}`);\r\n } else if (r.row_count != null) {\r\n console.log(chalk.gray(` ${r.row_count} row(s)`));\r\n }\r\n console.log();\r\n });\r\n\r\n console.log(chalk.gray(` Showing ${rows.length} entries`));\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err: any) {\r\n spinner.fail('Could not fetch logs');\r\n console.log(chalk.gray(` ${err.message}`));\r\n console.log(chalk.gray(' Make sure the platform database is accessible.'));\r\n }\r\n}\r\n\r\nfunction truncate(s: string, max: number): string {\r\n const oneLine = s.replace(/\\s+/g, ' ').trim();\r\n return oneLine.length > max ? oneLine.slice(0, max - 1) + '…' : oneLine;\r\n}\r\n"],"mappings":"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","names":["path","error","chalk","row","inquirer","chalk","fs","path","row","chalk","Pool","truncate","chalk","fs","path","Pool","chalk","chalk","inquirer","chalk","path","inquirer","chalk","answers","chalk","inquirer","chalk","fs","spinner","chalk","Pool","getLocalEnv","dbPush","dbPull","dbReset","dbSeed","dbDump","inspectCommand","genTypes","genClient","listSecrets","setSecret","unsetSecret"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/lib/config.ts","../src/lib/api.ts","../src/lib/ui.ts","../src/commands/db.ts","../src/commands/inspect.ts","../src/commands/gen.ts","../src/commands/migration.ts","../src/commands/secrets.ts","../src/index.ts","../src/commands/login.ts","../src/commands/init.ts","../src/commands/projects.ts","../src/commands/status.ts","../src/commands/link.ts","../src/commands/logs.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import Conf from 'conf';\r\nimport path from 'path';\r\nimport fs from 'fs/promises';\r\n\r\nexport interface UserConfig {\r\n apiUrl?: string;\r\n accessToken?: string;\r\n refreshToken?: string;\r\n userId?: string;\r\n username?: string;\r\n email?: string;\r\n}\r\n\r\nexport interface ProjectConfig {\r\n projectId?: string;\r\n projectName?: string;\r\n projectSlug?: string;\r\n teamId?: string;\r\n linkedAt?: string;\r\n}\r\n\r\nconst userConfig = new Conf<UserConfig>({\r\n projectName: 'kolaybase',\r\n configName: 'config',\r\n});\r\n\r\n// Get current project directory\r\nexport async function getProjectRoot(): Promise<string | null> {\r\n let currentDir = process.cwd();\r\n \r\n while (currentDir !== path.parse(currentDir).root) {\r\n const configPath = path.join(currentDir, '.kolaybase');\r\n try {\r\n await fs.access(configPath);\r\n return currentDir;\r\n } catch {\r\n currentDir = path.dirname(currentDir);\r\n }\r\n }\r\n \r\n return null;\r\n}\r\n\r\n// Project-specific configuration\r\nexport async function getProjectConfig(): Promise<ProjectConfig | null> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) return null;\r\n\r\n const configPath = path.join(projectRoot, '.kolaybase', 'config.json');\r\n \r\n try {\r\n const data = await fs.readFile(configPath, 'utf-8');\r\n return JSON.parse(data);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport async function setProjectConfig(config: ProjectConfig): Promise<void> {\r\n const projectRoot = process.cwd();\r\n const configDir = path.join(projectRoot, '.kolaybase');\r\n const configPath = path.join(configDir, 'config.json');\r\n\r\n await fs.mkdir(configDir, { recursive: true });\r\n await fs.writeFile(configPath, JSON.stringify(config, null, 2));\r\n}\r\n\r\n// User configuration helpers\r\nexport function getUserConfig(): UserConfig {\r\n return userConfig.store;\r\n}\r\n\r\nexport function setUserConfig(config: Partial<UserConfig>): void {\r\n userConfig.set(config);\r\n}\r\n\r\nexport function clearUserConfig(): void {\r\n userConfig.clear();\r\n}\r\n\r\nexport const DEFAULT_API_URL = 'https://api.kolaybase.com';\r\n\r\nexport function getApiUrl(): string {\r\n return userConfig.get('apiUrl') || DEFAULT_API_URL;\r\n}\r\n\r\nexport function getAccessToken(): string | undefined {\r\n return userConfig.get('accessToken');\r\n}\r\n\r\nexport function setAccessToken(token: string): void {\r\n userConfig.set('accessToken', token);\r\n}\r\n\r\nexport function getRefreshToken(): string | undefined {\r\n return userConfig.get('refreshToken');\r\n}\r\n\r\nexport function setRefreshToken(token: string): void {\r\n userConfig.set('refreshToken', token);\r\n}\r\n\r\nexport function isLoggedIn(): boolean {\r\n return !!userConfig.get('accessToken');\r\n}\r\n\r\nexport function setApiUrl(url: string): void {\r\n userConfig.set('apiUrl', url);\r\n}\r\n\r\n// Write Kolaybase variables into .env without touching existing content.\r\n// Existing KOLAYBASE_* keys are updated in-place; new ones are appended.\r\nexport async function writeEnvFile(project: any): Promise<void> {\r\n const apiUrl = getApiUrl();\r\n\r\n const kolaybaseVars: Record<string, string> = {\r\n KOLAYBASE_PROJECT_ID: project.id,\r\n KOLAYBASE_ANON_KEY: project.anonKey,\r\n KOLAYBASE_SERVICE_KEY: project.serviceKey,\r\n KOLAYBASE_API_URL: apiUrl,\r\n KOLAYBASE_PROJECT_SLUG: project.slug,\r\n KOLAYBASE_DB_HOST: project.dbHost,\r\n KOLAYBASE_DB_PORT: String(project.dbPort),\r\n KOLAYBASE_DB_NAME: project.dbName,\r\n KOLAYBASE_DB_USER: project.dbUser,\r\n KOLAYBASE_DB_PASSWORD: project.dbPassword,\r\n KOLAYBASE_DATABASE_URL: `postgresql://${project.dbUser}:${project.dbPassword}@${project.dbHost}:${project.dbPort}/${project.dbName}`,\r\n DATABASE_URL: `postgresql://${project.dbUser}:${project.dbPassword}@${project.dbHost}:${project.dbPort}/${project.dbName}`,\r\n KOLAYBASE_KEYCLOAK_REALM: project.keycloakRealm,\r\n };\r\n\r\n // Read existing .env (or start empty)\r\n let existing = '';\r\n try { existing = await fs.readFile('.env', 'utf-8'); } catch { /* new file */ }\r\n\r\n const existingLines = existing.split('\\n');\r\n const handled = new Set<string>();\r\n\r\n // Update existing KOLAYBASE_* lines in-place\r\n const updatedLines = existingLines.map((line) => {\r\n const match = line.match(/^([A-Z0-9_]+)\\s*=/);\r\n if (match && kolaybaseVars[match[1]] !== undefined) {\r\n handled.add(match[1]);\r\n return `${match[1]}=${kolaybaseVars[match[1]]}`;\r\n }\r\n return line;\r\n });\r\n\r\n // Remove trailing empty lines before appending\r\n while (updatedLines.length && updatedLines[updatedLines.length - 1].trim() === '') {\r\n updatedLines.pop();\r\n }\r\n\r\n // Append any new keys not already present\r\n const newKeys = Object.keys(kolaybaseVars).filter((k) => !handled.has(k));\r\n if (newKeys.length) {\r\n updatedLines.push('');\r\n updatedLines.push('# Kolaybase — added by \"kb init\" / \"kb link\"');\r\n for (const key of newKeys) {\r\n updatedLines.push(`${key}=${kolaybaseVars[key]}`);\r\n }\r\n }\r\n\r\n updatedLines.push('');\r\n await fs.writeFile('.env', updatedLines.join('\\n'));\r\n\r\n // Make sure .gitignore has .env\r\n try {\r\n let gi = '';\r\n try { gi = await fs.readFile('.gitignore', 'utf-8'); } catch { /* noop */ }\r\n if (!gi.includes('.env')) {\r\n await fs.writeFile('.gitignore', gi + '\\n.env\\n');\r\n }\r\n } catch { /* best-effort */ }\r\n}\r\n\r\n// Local .env management\r\nexport async function getLocalEnv(): Promise<Record<string, string>> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) return {};\r\n\r\n const envPath = path.join(projectRoot, '.env');\r\n \r\n try {\r\n const content = await fs.readFile(envPath, 'utf-8');\r\n const env: Record<string, string> = {};\r\n \r\n content.split('\\n').forEach(line => {\r\n line = line.trim();\r\n if (!line || line.startsWith('#')) return;\r\n \r\n const [key, ...valueParts] = line.split('=');\r\n if (key && valueParts.length > 0) {\r\n env[key.trim()] = valueParts.join('=').trim();\r\n }\r\n });\r\n \r\n return env;\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\nexport async function setLocalEnv(key: string, value: string): Promise<void> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) {\r\n throw new Error('Not in a Kolaybase project directory');\r\n }\r\n\r\n const envPath = path.join(projectRoot, '.env');\r\n let content = '';\r\n \r\n try {\r\n content = await fs.readFile(envPath, 'utf-8');\r\n } catch {\r\n // File doesn't exist, will create new\r\n }\r\n\r\n const lines = content.split('\\n');\r\n let found = false;\r\n \r\n const newLines = lines.map(line => {\r\n const trimmed = line.trim();\r\n if (trimmed.startsWith(`${key}=`)) {\r\n found = true;\r\n return `${key}=${value}`;\r\n }\r\n return line;\r\n });\r\n\r\n if (!found) {\r\n newLines.push(`${key}=${value}`);\r\n }\r\n\r\n await fs.writeFile(envPath, newLines.join('\\n'));\r\n}\r\n\r\nexport async function unsetLocalEnv(key: string): Promise<void> {\r\n const projectRoot = await getProjectRoot();\r\n if (!projectRoot) {\r\n throw new Error('Not in a Kolaybase project directory');\r\n }\r\n\r\n const envPath = path.join(projectRoot, '.env');\r\n \r\n try {\r\n const content = await fs.readFile(envPath, 'utf-8');\r\n const lines = content.split('\\n').filter(line => {\r\n const trimmed = line.trim();\r\n return !trimmed.startsWith(`${key}=`);\r\n });\r\n \r\n await fs.writeFile(envPath, lines.join('\\n'));\r\n } catch {\r\n // File doesn't exist, nothing to do\r\n }\r\n}\r\n","import axios, { AxiosInstance, AxiosError } from 'axios';\r\nimport chalk from 'chalk';\r\nimport { getApiUrl, getAccessToken, setAccessToken, getRefreshToken, setRefreshToken } from './config.js';\r\n\r\nexport class ApiClient {\r\n private client: AxiosInstance;\r\n\r\n constructor() {\r\n this.client = axios.create({\r\n baseURL: getApiUrl(),\r\n timeout: 30000,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n // Add auth token to requests\r\n this.client.interceptors.request.use((config) => {\r\n const token = getAccessToken();\r\n if (token) {\r\n config.headers.Authorization = `Bearer ${token}`;\r\n }\r\n return config;\r\n });\r\n\r\n // Handle token refresh\r\n this.client.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n const originalRequest = error.config;\r\n \r\n if (error.response?.status === 401 && originalRequest && !(originalRequest as any)._retry) {\r\n (originalRequest as any)._retry = true;\r\n \r\n try {\r\n const refreshToken = getRefreshToken();\r\n if (!refreshToken) {\r\n throw new Error('No refresh token available');\r\n }\r\n\r\n const { data } = await axios.post(`${getApiUrl()}/api/auth/refresh`, {\r\n refreshToken,\r\n });\r\n\r\n setAccessToken(data.accessToken);\r\n setRefreshToken(data.refreshToken);\r\n\r\n originalRequest.headers!.Authorization = `Bearer ${data.accessToken}`;\r\n return this.client(originalRequest);\r\n } catch (refreshError) {\r\n console.error(chalk.red('Session expired. Please login again with: kb login'));\r\n process.exit(1);\r\n }\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n }\r\n\r\n // Auth endpoints\r\n async login(email: string, password: string) {\r\n const { data } = await this.client.post('/api/auth/login', { email, password });\r\n return data;\r\n }\r\n\r\n async signup(userData: {\r\n email: string;\r\n password: string;\r\n firstName?: string;\r\n lastName?: string;\r\n }) {\r\n const { data } = await this.client.post('/api/auth/signup', userData);\r\n return data;\r\n }\r\n\r\n // Projects endpoints\r\n async getProjects(teamId: string) {\r\n const { data } = await this.client.get('/api/projects', {\r\n params: { teamId },\r\n });\r\n return data;\r\n }\r\n\r\n async getProject(projectId: string) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}`);\r\n return data;\r\n }\r\n\r\n async createProject(projectData: {\r\n name: string;\r\n description?: string;\r\n teamId: string;\r\n }) {\r\n const { data } = await this.client.post('/api/projects', projectData);\r\n return data;\r\n }\r\n\r\n async deleteProject(projectId: string) {\r\n const { data } = await this.client.delete(`/api/projects/${projectId}`);\r\n return data;\r\n }\r\n\r\n // SQL endpoints\r\n async executeSQL(projectId: string, query: string): Promise<{ rows: Record<string, unknown>[]; rowCount: number }> {\r\n const { data } = await this.client.post('/api/sql/execute', {\r\n projectId,\r\n query,\r\n });\r\n return data;\r\n }\r\n\r\n // Teams endpoints\r\n async getTeams() {\r\n const { data } = await this.client.get('/api/teams');\r\n return data;\r\n }\r\n\r\n async getActiveTeam() {\r\n const { data } = await this.client.get('/api/teams/active');\r\n return data;\r\n }\r\n\r\n // Project data endpoints\r\n async getTables(projectId: string) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}/data/tables`);\r\n return data;\r\n }\r\n\r\n async getTableSchema(projectId: string, tableName: string) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}/data/tables/${tableName}/schema`);\r\n return data;\r\n }\r\n\r\n async getTableData(projectId: string, tableName: string, options?: {\r\n limit?: number;\r\n offset?: number;\r\n orderBy?: string;\r\n order?: 'asc' | 'desc';\r\n }) {\r\n const { data } = await this.client.get(`/api/projects/${projectId}/data/tables/${tableName}/rows`, {\r\n params: options,\r\n });\r\n return data;\r\n }\r\n}\r\n\r\nexport const apiClient = new ApiClient();\r\n\r\nexport function handleApiError(error: any) {\r\n if (axios.isAxiosError(error)) {\r\n if (error.response) {\r\n const message = error.response.data?.message || error.response.data?.error || error.message;\r\n console.error(chalk.red(`API Error: ${message}`));\r\n \r\n if (error.response.status === 401) {\r\n console.error(chalk.yellow('Please login first with: kb login'));\r\n }\r\n } else if (error.request) {\r\n console.error(chalk.red('Network error: Could not connect to Kolaybase API'));\r\n console.error(chalk.yellow(`Make sure the API is running at: ${getApiUrl()}`));\r\n } else {\r\n console.error(chalk.red(`Error: ${error.message}`));\r\n }\r\n } else {\r\n console.error(chalk.red(`Error: ${error.message || error}`));\r\n }\r\n \r\n process.exit(1);\r\n}\r\n","import chalk from 'chalk';\r\nimport ora, { Ora } from 'ora';\r\nimport boxen from 'boxen';\r\n\r\nexport function success(message: string): void {\r\n console.log(chalk.green('✓'), message);\r\n}\r\n\r\nexport function error(message: string): void {\r\n console.log(chalk.red('✗'), message);\r\n}\r\n\r\nexport function warning(message: string): void {\r\n console.log(chalk.yellow('⚠'), message);\r\n}\r\n\r\nexport function info(message: string): void {\r\n console.log(chalk.blue('ℹ'), message);\r\n}\r\n\r\nexport function log(message: string): void {\r\n console.log(message);\r\n}\r\n\r\nexport function createSpinner(text: string): Ora {\r\n return ora(text).start();\r\n}\r\n\r\nexport function printBox(content: string, options?: {\r\n title?: string;\r\n padding?: number;\r\n borderColor?: string;\r\n}): void {\r\n console.log(\r\n boxen(content, {\r\n padding: options?.padding ?? 1,\r\n margin: 1,\r\n borderStyle: 'round',\r\n title: options?.title,\r\n titleAlignment: 'center',\r\n borderColor: options?.borderColor as any || 'cyan',\r\n })\r\n );\r\n}\r\n\r\nexport function printHeader(text: string): void {\r\n console.log();\r\n console.log(chalk.bold.cyan(text));\r\n console.log(chalk.cyan('─'.repeat(text.length)));\r\n}\r\n\r\nexport function printTable(headers: string[], rows: string[][]): void {\r\n const columnWidths = headers.map((header, i) => {\r\n const maxRowWidth = Math.max(...rows.map(row => (row[i] || '').length));\r\n return Math.max(header.length, maxRowWidth);\r\n });\r\n\r\n // Print headers\r\n const headerRow = headers.map((header, i) => \r\n header.padEnd(columnWidths[i])\r\n ).join(' ');\r\n console.log(chalk.bold(headerRow));\r\n console.log(chalk.gray('─'.repeat(headerRow.length)));\r\n\r\n // Print rows\r\n rows.forEach(row => {\r\n const rowStr = row.map((cell, i) => \r\n (cell || '').padEnd(columnWidths[i])\r\n ).join(' ');\r\n console.log(rowStr);\r\n });\r\n}\r\n\r\nexport function printKeyValue(data: Record<string, string | number | boolean | null | undefined>): void {\r\n const maxKeyLength = Math.max(...Object.keys(data).map(k => k.length));\r\n \r\n Object.entries(data).forEach(([key, value]) => {\r\n const paddedKey = chalk.bold(key.padEnd(maxKeyLength));\r\n const displayValue = value ?? chalk.gray('(not set)');\r\n console.log(`${paddedKey} ${displayValue}`);\r\n });\r\n}\r\n\r\nexport function printJson(data: any): void {\r\n console.log(JSON.stringify(data, null, 2));\r\n}\r\n\r\nexport function clearLine(): void {\r\n process.stdout.write('\\r\\x1b[K');\r\n}\r\n\r\nexport function printLogo(): void {\r\n const logo = `\r\n${chalk.cyan('┌─────────────────────────────────────┐')}\r\n${chalk.cyan('│')} ${chalk.bold.cyan('K O L A Y B A S E')} ${chalk.cyan('│')}\r\n${chalk.cyan('│')} ${chalk.gray('Backend-as-a-Service Platform')} ${chalk.cyan('│')}\r\n${chalk.cyan('└─────────────────────────────────────┘')}\r\n `;\r\n console.log(logo);\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport { Pool } from 'pg';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, getLocalEnv } from '../lib/config.js';\r\nimport { success, error, warning, info, createSpinner } from '../lib/ui.js';\r\n\r\nexport async function dbCommand() {\r\n console.log(chalk.bold.cyan('Database Management\\n'));\r\n info('Use db subcommands: push, pull, reset, seed, diff');\r\n}\r\n\r\nexport async function dbPush() {\r\n console.log(chalk.bold.cyan('Push Database Schema\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Analyzing schema changes...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const schemaPath = await findSchemaFile();\r\n\r\n if (!schemaPath) {\r\n spinner.fail('No schema file found');\r\n error('Could not find prisma/schema.prisma, db/schema.sql, or schema.sql');\r\n console.log('');\r\n console.log(' To push SQL directly use: kb db execute --file <file>');\r\n console.log(' To apply migrations use: kb migration up');\r\n process.exit(1);\r\n }\r\n\r\n spinner.text = 'Pushing schema to database...';\r\n\r\n // If Prisma schema exists, use Prisma\r\n if (schemaPath.endsWith('.prisma')) {\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'db', 'push'], {\r\n stdio: 'inherit',\r\n env: {\r\n ...process.env,\r\n DATABASE_URL: env.DATABASE_URL,\r\n },\r\n });\r\n } else {\r\n // Execute SQL file\r\n const sql = await fs.readFile(schemaPath, 'utf-8');\r\n await apiClient.executeSQL(config.projectId!, sql);\r\n }\r\n\r\n spinner.succeed('Schema pushed successfully');\r\n success('Database is up to date');\r\n } catch (err) {\r\n spinner.fail('Failed to push schema');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function dbPull() {\r\n console.log(chalk.bold.cyan('Pull Database Schema\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Pulling schema from database...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n\r\n if (!env.DATABASE_URL && !env.KOLAYBASE_DATABASE_URL) {\r\n spinner.fail('DATABASE_URL not found');\r\n error('Run kb link to refresh credentials');\r\n process.exit(1);\r\n }\r\n\r\n const dbUrl = env.DATABASE_URL || env.KOLAYBASE_DATABASE_URL;\r\n\r\n // Check if Prisma is being used\r\n const prismaPath = path.join(process.cwd(), 'prisma', 'schema.prisma');\r\n \r\n try {\r\n await fs.access(prismaPath);\r\n \r\n // Use Prisma introspection\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'db', 'pull'], {\r\n stdio: 'inherit',\r\n env: {\r\n ...process.env,\r\n DATABASE_URL: dbUrl,\r\n },\r\n });\r\n\r\n spinner.succeed('Schema pulled successfully');\r\n } catch {\r\n // No Prisma, generate SQL dump\r\n spinner.text = 'Generating SQL dump...';\r\n\r\n const pool = new Pool({\r\n connectionString: dbUrl,\r\n });\r\n\r\n const client = await pool.connect();\r\n \r\n try {\r\n const { rows } = await client.query(`\r\n SELECT table_name \r\n FROM information_schema.tables \r\n WHERE table_schema = 'public'\r\n ORDER BY table_name\r\n `);\r\n\r\n const tables = rows.map(r => r.table_name);\r\n \r\n let schemaDump = '-- Database schema dump\\n\\n';\r\n \r\n for (const table of tables) {\r\n const { rows: columns } = await client.query(`\r\n SELECT column_name, data_type, is_nullable, column_default\r\n FROM information_schema.columns\r\n WHERE table_name = $1\r\n ORDER BY ordinal_position\r\n `, [table]);\r\n\r\n schemaDump += `CREATE TABLE IF NOT EXISTS ${table} (\\n`;\r\n schemaDump += columns.map(col => {\r\n let def = ` ${col.column_name} ${col.data_type}`;\r\n if (col.is_nullable === 'NO') def += ' NOT NULL';\r\n if (col.column_default) def += ` DEFAULT ${col.column_default}`;\r\n return def;\r\n }).join(',\\n');\r\n schemaDump += '\\n);\\n\\n';\r\n }\r\n\r\n await fs.mkdir('db', { recursive: true });\r\n await fs.writeFile('db/schema.sql', schemaDump);\r\n\r\n spinner.succeed('Schema pulled successfully');\r\n info('Schema saved to db/schema.sql');\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to pull schema');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface ResetOptions {\r\n force?: boolean;\r\n}\r\n\r\nexport async function dbReset(options: ResetOptions) {\r\n console.log(chalk.bold.cyan('Reset Database\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n console.log(chalk.yellow('⚠ WARNING: This will delete all data in the database!'));\r\n console.log();\r\n\r\n if (!options.force) {\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'confirm',\r\n message: 'Are you sure you want to reset the database?',\r\n default: false,\r\n },\r\n ]);\r\n\r\n if (!answers.confirm) {\r\n info('Reset cancelled');\r\n return;\r\n }\r\n }\r\n\r\n const spinner = createSpinner('Resetting database...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const pool = new Pool({\r\n connectionString: env.DATABASE_URL,\r\n });\r\n\r\n const client = await pool.connect();\r\n\r\n try {\r\n // Get all tables\r\n const { rows } = await client.query(`\r\n SELECT tablename \r\n FROM pg_tables \r\n WHERE schemaname = 'public'\r\n `);\r\n\r\n // Drop all tables\r\n for (const row of rows) {\r\n await client.query(`DROP TABLE IF EXISTS \"${row.tablename}\" CASCADE`);\r\n }\r\n\r\n spinner.succeed('Database reset successfully');\r\n success('All tables dropped');\r\n \r\n console.log();\r\n info('To recreate schema, run: kb db push');\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to reset database');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function dbSeed() {\r\n console.log(chalk.bold.cyan('Seed Database\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Looking for seed file...');\r\n\r\n try {\r\n const seedPaths = [\r\n 'prisma/seed.ts',\r\n 'prisma/seed.js',\r\n 'db/seed.sql',\r\n 'seeds/seed.sql',\r\n ];\r\n\r\n let seedPath: string | null = null;\r\n\r\n for (const p of seedPaths) {\r\n try {\r\n await fs.access(p);\r\n seedPath = p;\r\n break;\r\n } catch {\r\n // Continue searching\r\n }\r\n }\r\n\r\n if (!seedPath) {\r\n spinner.fail('No seed file found');\r\n warning('Create a seed file at prisma/seed.ts or db/seed.sql');\r\n return;\r\n }\r\n\r\n spinner.text = 'Running seed...';\r\n\r\n if (seedPath.endsWith('.sql')) {\r\n const sql = await fs.readFile(seedPath, 'utf-8');\r\n await apiClient.executeSQL(config.projectId!, sql);\r\n } else {\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'db', 'seed'], {\r\n stdio: 'inherit',\r\n });\r\n }\r\n\r\n spinner.succeed('Database seeded successfully');\r\n } catch (err) {\r\n spinner.fail('Failed to seed database');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function dbDiff() {\r\n console.log(chalk.bold.cyan('Database Schema Diff\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const env = await getLocalEnv();\r\n const dbUrl = env.DATABASE_URL || env.KOLAYBASE_DATABASE_URL;\r\n\r\n info('Checking for schema differences...');\r\n\r\n try {\r\n const { execa } = await import('execa');\r\n await execa('npx', ['prisma', 'migrate', 'diff', '--from-schema-datasource', 'prisma/schema.prisma', '--to-url', dbUrl || ''], {\r\n stdio: 'inherit',\r\n });\r\n } catch {\r\n warning('Could not generate diff. Make sure Prisma is configured and DATABASE_URL is set.');\r\n }\r\n}\r\n\r\ninterface ExecuteOptions {\r\n file?: string;\r\n query?: string;\r\n}\r\n\r\nexport async function dbExecute(options: ExecuteOptions) {\r\n console.log(chalk.bold.cyan('Execute SQL\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n if (!options.file && !options.query) {\r\n error('Provide --file <path> or --query <sql>');\r\n process.exit(1);\r\n }\r\n\r\n let sql: string;\r\n\r\n if (options.file) {\r\n try {\r\n sql = await fs.readFile(options.file, 'utf-8');\r\n info(`Executing ${chalk.cyan(options.file)}…`);\r\n } catch {\r\n error(`Could not read file: ${options.file}`);\r\n process.exit(1);\r\n }\r\n } else {\r\n sql = options.query!;\r\n info('Executing query…');\r\n }\r\n\r\n const spinner = createSpinner('Running…');\r\n\r\n try {\r\n const result = await apiClient.executeSQL(config.projectId, sql);\r\n spinner.succeed('Done');\r\n\r\n if (result?.rows?.length) {\r\n console.log();\r\n // Print column headers\r\n const cols = Object.keys(result.rows[0]);\r\n const colWidths = cols.map((c) =>\r\n Math.max(c.length, ...result.rows.map((r: any) => String(r[c] ?? '').length)),\r\n );\r\n\r\n const header = cols.map((c, i) => c.padEnd(colWidths[i])).join(' ');\r\n const divider = colWidths.map((w) => '─'.repeat(w)).join(' ');\r\n\r\n console.log(' ' + chalk.bold(header));\r\n console.log(' ' + chalk.gray(divider));\r\n for (const row of result.rows) {\r\n console.log(' ' + cols.map((c, i) => String(row[c] ?? '').padEnd(colWidths[i])).join(' '));\r\n }\r\n console.log();\r\n console.log(chalk.gray(` ${result.rows.length} row(s)`));\r\n } else {\r\n success(`Query executed. ${result?.rowCount ?? 0} row(s) affected.`);\r\n }\r\n } catch (err) {\r\n spinner.fail('Execution failed');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface DumpOptions {\r\n output?: string;\r\n}\r\n\r\nexport async function dbDump(options: DumpOptions) {\r\n console.log(chalk.bold.cyan('Dump Database Schema\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Dumping schema…');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const pool = new Pool({ connectionString: env.DATABASE_URL });\r\n const client = await pool.connect();\r\n\r\n try {\r\n const { rows: tables } = await client.query(`\r\n SELECT table_name\r\n FROM information_schema.tables\r\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'\r\n ORDER BY table_name\r\n `);\r\n\r\n let dump = '-- Kolaybase schema dump\\n-- Generated: ' + new Date().toISOString() + '\\n\\n';\r\n\r\n for (const t of tables) {\r\n const { rows: cols } = await client.query(`\r\n SELECT column_name, udt_name, is_nullable, column_default, character_maximum_length\r\n FROM information_schema.columns\r\n WHERE table_name = $1\r\n ORDER BY ordinal_position\r\n `, [t.table_name]);\r\n\r\n dump += `CREATE TABLE IF NOT EXISTS \"${t.table_name}\" (\\n`;\r\n dump += cols.map((c: any) => {\r\n let def = ` \"${c.column_name}\" ${c.udt_name}`;\r\n if (c.character_maximum_length) def += `(${c.character_maximum_length})`;\r\n if (c.is_nullable === 'NO') def += ' NOT NULL';\r\n if (c.column_default) def += ` DEFAULT ${c.column_default}`;\r\n return def;\r\n }).join(',\\n');\r\n dump += '\\n);\\n\\n';\r\n }\r\n\r\n const outFile = options.output || 'schema.sql';\r\n await fs.writeFile(outFile, dump);\r\n\r\n spinner.succeed(`Schema dumped to ${chalk.cyan(outFile)}`);\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to dump schema');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nasync function findSchemaFile(): Promise<string | null> {\r\n const paths = [\r\n 'prisma/schema.prisma',\r\n 'db/schema.sql',\r\n 'schema.sql',\r\n ];\r\n\r\n for (const p of paths) {\r\n try {\r\n const stat = await fs.stat(p);\r\n if (stat.isFile()) return p;\r\n } catch {\r\n // not found, continue\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n","import chalk from 'chalk';\r\nimport { Pool } from 'pg';\r\nimport { getProjectConfig, getLocalEnv } from '../lib/config.js';\r\nimport { error, printHeader, createSpinner } from '../lib/ui.js';\r\n\r\ninterface InspectOptions {\r\n table?: string;\r\n}\r\n\r\nexport async function inspectCommand(options: InspectOptions) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n const env = await getLocalEnv();\r\n if (!env.DATABASE_URL) {\r\n error('DATABASE_URL not found in .env — run kb link to refresh credentials');\r\n process.exit(1);\r\n }\r\n\r\n const pool = new Pool({ connectionString: env.DATABASE_URL });\r\n\r\n try {\r\n if (options.table) {\r\n await inspectTable(pool, options.table);\r\n } else {\r\n await inspectAll(pool);\r\n }\r\n } catch (err: any) {\r\n error(`Database error: ${err.message}`);\r\n process.exit(1);\r\n } finally {\r\n await pool.end();\r\n }\r\n}\r\n\r\nasync function inspectAll(pool: Pool) {\r\n const spinner = createSpinner('Querying database…');\r\n\r\n const { rows } = await pool.query(`\r\n SELECT\r\n t.table_name,\r\n pg_total_relation_size(quote_ident(t.table_name)) AS total_bytes,\r\n pg_size_pretty(pg_total_relation_size(quote_ident(t.table_name))) AS size,\r\n (SELECT reltuples::bigint FROM pg_class WHERE relname = t.table_name) AS est_rows\r\n FROM information_schema.tables t\r\n WHERE t.table_schema = 'public' AND t.table_type = 'BASE TABLE'\r\n ORDER BY total_bytes DESC\r\n `);\r\n\r\n spinner.stop();\r\n\r\n if (!rows.length) {\r\n console.log(chalk.gray(' No tables found. Push a schema first: kb db push'));\r\n return;\r\n }\r\n\r\n printHeader('Tables');\r\n console.log();\r\n\r\n const nameW = Math.max(10, ...rows.map((r: any) => r.table_name.length));\r\n\r\n console.log(\r\n ` ${chalk.bold('Table'.padEnd(nameW))} ${chalk.bold('Rows'.padStart(10))} ${chalk.bold('Size'.padStart(10))}`,\r\n );\r\n console.log(chalk.gray(' ' + '─'.repeat(nameW + 24)));\r\n\r\n for (const r of rows) {\r\n const rowCount = Number(r.est_rows) >= 0 ? Number(r.est_rows).toLocaleString() : '—';\r\n console.log(\r\n ` ${chalk.cyan(r.table_name.padEnd(nameW))} ${rowCount.padStart(10)} ${String(r.size).padStart(10)}`,\r\n );\r\n }\r\n\r\n console.log();\r\n console.log(chalk.gray(` ${rows.length} table(s)`));\r\n console.log(chalk.gray(' Inspect a table: kb inspect --table <name>'));\r\n}\r\n\r\nasync function inspectTable(pool: Pool, tableName: string) {\r\n const spinner = createSpinner(`Inspecting ${tableName}…`);\r\n\r\n // Columns\r\n const { rows: columns } = await pool.query(`\r\n SELECT\r\n c.column_name,\r\n c.data_type,\r\n c.udt_name,\r\n c.is_nullable,\r\n c.column_default,\r\n c.character_maximum_length\r\n FROM information_schema.columns c\r\n WHERE c.table_schema = 'public' AND c.table_name = $1\r\n ORDER BY c.ordinal_position\r\n `, [tableName]);\r\n\r\n if (!columns.length) {\r\n spinner.fail(`Table \"${tableName}\" not found`);\r\n process.exit(1);\r\n }\r\n\r\n // Indexes\r\n const { rows: indexes } = await pool.query(`\r\n SELECT indexname, indexdef\r\n FROM pg_indexes\r\n WHERE schemaname = 'public' AND tablename = $1\r\n `, [tableName]);\r\n\r\n // Foreign keys\r\n const { rows: fkeys } = await pool.query(`\r\n SELECT\r\n kcu.column_name,\r\n ccu.table_name AS foreign_table,\r\n ccu.column_name AS foreign_column\r\n FROM information_schema.table_constraints tc\r\n JOIN information_schema.key_column_usage kcu\r\n ON tc.constraint_name = kcu.constraint_name\r\n JOIN information_schema.constraint_column_usage ccu\r\n ON tc.constraint_name = ccu.constraint_name\r\n WHERE tc.table_name = $1 AND tc.constraint_type = 'FOREIGN KEY'\r\n `, [tableName]);\r\n\r\n // Row count + size\r\n const { rows: meta } = await pool.query(`\r\n SELECT\r\n pg_size_pretty(pg_total_relation_size(quote_ident($1))) AS size,\r\n (SELECT reltuples::bigint FROM pg_class WHERE relname = $1) AS est_rows\r\n `, [tableName]);\r\n\r\n spinner.stop();\r\n\r\n printHeader(`Table: ${tableName}`);\r\n console.log();\r\n\r\n if (meta[0]) {\r\n console.log(` ${chalk.gray('Rows')} ${Number(meta[0].est_rows).toLocaleString()}`);\r\n console.log(` ${chalk.gray('Size')} ${meta[0].size}`);\r\n console.log();\r\n }\r\n\r\n // Columns table\r\n console.log(chalk.bold(' Columns'));\r\n\r\n const nameW = Math.max(6, ...columns.map((c: any) => c.column_name.length));\r\n const typeW = Math.max(4, ...columns.map((c: any) => formatType(c).length));\r\n\r\n console.log(\r\n ` ${chalk.gray('Name'.padEnd(nameW))} ${chalk.gray('Type'.padEnd(typeW))} ${chalk.gray('Nullable')} ${chalk.gray('Default')}`,\r\n );\r\n console.log(chalk.gray(' ' + '─'.repeat(nameW + typeW + 24)));\r\n\r\n for (const col of columns) {\r\n const nullable = col.is_nullable === 'YES' ? chalk.yellow('YES') : chalk.gray('NO ');\r\n const def = col.column_default ? chalk.gray(truncate(col.column_default, 30)) : '';\r\n const fk = fkeys.find((f: any) => f.column_name === col.column_name);\r\n const fkLabel = fk ? chalk.blue(` → ${fk.foreign_table}.${fk.foreign_column}`) : '';\r\n\r\n console.log(\r\n ` ${chalk.cyan(col.column_name.padEnd(nameW))} ${formatType(col).padEnd(typeW)} ${nullable} ${def}${fkLabel}`,\r\n );\r\n }\r\n\r\n // Indexes\r\n if (indexes.length) {\r\n console.log();\r\n console.log(chalk.bold(' Indexes'));\r\n for (const idx of indexes) {\r\n console.log(` ${chalk.gray('•')} ${idx.indexname}`);\r\n }\r\n }\r\n\r\n console.log();\r\n}\r\n\r\nfunction formatType(col: any): string {\r\n let t = col.udt_name || col.data_type;\r\n if (col.character_maximum_length) t += `(${col.character_maximum_length})`;\r\n return t;\r\n}\r\n\r\nfunction truncate(s: string, max: number): string {\r\n return s.length > max ? s.slice(0, max - 1) + '…' : s;\r\n}\r\n","import chalk from 'chalk';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { Pool } from 'pg';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, getLocalEnv } from '../lib/config.js';\r\nimport { success, error, info, createSpinner } from '../lib/ui.js';\r\n\r\ninterface GenTypesOptions {\r\n output?: string;\r\n}\r\n\r\nexport async function genTypes(options: GenTypesOptions) {\r\n console.log(chalk.bold.cyan('Generate TypeScript Types\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Generating types from database schema...');\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n const pool = new Pool({\r\n connectionString: env.DATABASE_URL,\r\n });\r\n\r\n const client = await pool.connect();\r\n \r\n try {\r\n // Get all tables\r\n const { rows: tables } = await client.query(`\r\n SELECT table_name \r\n FROM information_schema.tables \r\n WHERE table_schema = 'public'\r\n ORDER BY table_name\r\n `);\r\n\r\n let typesContent = `// Generated by Kolaybase CLI\r\n// Do not edit manually\r\n\r\nexport interface Database {\r\n${tables.map((t: any) => ` ${t.table_name}: ${toPascalCase(t.table_name)};`).join('\\n')}\r\n}\r\n\r\n`;\r\n\r\n // Generate types for each table\r\n for (const table of tables) {\r\n const { rows: columns } = await client.query(`\r\n SELECT \r\n column_name, \r\n data_type, \r\n is_nullable,\r\n column_default\r\n FROM information_schema.columns\r\n WHERE table_name = $1\r\n ORDER BY ordinal_position\r\n `, [table.table_name]);\r\n\r\n const typeName = toPascalCase(table.table_name);\r\n \r\n typesContent += `export interface ${typeName} {\\n`;\r\n \r\n columns.forEach((col: any) => {\r\n const tsType = pgTypeToTs(col.data_type);\r\n const optional = col.is_nullable === 'YES' || col.column_default ? '?' : '';\r\n typesContent += ` ${col.column_name}${optional}: ${tsType};\\n`;\r\n });\r\n \r\n typesContent += `}\\n\\n`;\r\n }\r\n\r\n // Write to file\r\n const outputDir = options.output || 'types';\r\n await fs.mkdir(outputDir, { recursive: true });\r\n const outputPath = path.join(outputDir, 'database.ts');\r\n await fs.writeFile(outputPath, typesContent);\r\n\r\n spinner.succeed('Types generated successfully');\r\n success(`Written to ${chalk.cyan(outputPath)}`);\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to generate types');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface GenClientOptions {\r\n lang?: string;\r\n output?: string;\r\n}\r\n\r\nexport async function genClient(options: GenClientOptions) {\r\n console.log(chalk.bold.cyan('Generate API Client\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Generating API client...');\r\n\r\n try {\r\n const lang = options.lang || 'typescript';\r\n const outputDir = options.output || 'lib';\r\n\r\n if (lang === 'typescript') {\r\n await generateTsClient(config, outputDir);\r\n } else if (lang === 'javascript') {\r\n await generateJsClient(config, outputDir);\r\n } else if (lang === 'python') {\r\n await generatePyClient(config, outputDir);\r\n } else {\r\n throw new Error(`Unsupported language: ${lang}`);\r\n }\r\n\r\n spinner.succeed('Client generated successfully');\r\n success(`Written to ${chalk.cyan(outputDir)}`);\r\n } catch (err) {\r\n spinner.fail('Failed to generate client');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nasync function generateTsClient(config: any, outputDir: string) {\r\n const clientContent = `// Generated by Kolaybase CLI\r\nimport axios, { AxiosInstance } from 'axios';\r\n\r\nexport interface KolaybaseConfig {\r\n url?: string;\r\n anonKey?: string;\r\n serviceKey?: string;\r\n}\r\n\r\nexport class KolaybaseClient {\r\n private client: AxiosInstance;\r\n private projectId: string;\r\n\r\n constructor(config: KolaybaseConfig = {}) {\r\n this.projectId = '${config.projectId}';\r\n \r\n this.client = axios.create({\r\n baseURL: config.url || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': \\`Bearer \\${config.anonKey || process.env.ANON_KEY}\\`,\r\n },\r\n });\r\n }\r\n\r\n // Execute raw SQL\r\n async sql<T = any>(query: string): Promise<T[]> {\r\n const { data } = await this.client.post('/sql/execute', {\r\n projectId: this.projectId,\r\n query,\r\n });\r\n return data.rows;\r\n }\r\n\r\n // Table operations\r\n table<T = any>(tableName: string) {\r\n return {\r\n select: async (columns = '*', options?: {\r\n where?: Record<string, any>;\r\n limit?: number;\r\n offset?: number;\r\n orderBy?: string;\r\n }): Promise<T[]> => {\r\n let query = \\`SELECT \\${columns} FROM \\${tableName}\\`;\r\n \r\n if (options?.where) {\r\n const conditions = Object.entries(options.where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n query += \\` WHERE \\${conditions}\\`;\r\n }\r\n \r\n if (options?.orderBy) {\r\n query += \\` ORDER BY \\${options.orderBy}\\`;\r\n }\r\n \r\n if (options?.limit) {\r\n query += \\` LIMIT \\${options.limit}\\`;\r\n }\r\n \r\n if (options?.offset) {\r\n query += \\` OFFSET \\${options.offset}\\`;\r\n }\r\n\r\n return this.sql<T>(query);\r\n },\r\n\r\n insert: async (data: Partial<T> | Partial<T>[]): Promise<T[]> => {\r\n const rows = Array.isArray(data) ? data : [data];\r\n const keys = Object.keys(rows[0]);\r\n const values = rows.map(row => \r\n \\`(\\${keys.map(k => \\`'\\${(row as any)[k]}'\\`).join(', ')})\\`\r\n ).join(', ');\r\n\r\n const query = \\`\r\n INSERT INTO \\${tableName} (\\${keys.join(', ')}) \r\n VALUES \\${values}\r\n RETURNING *\r\n \\`;\r\n\r\n return this.sql<T>(query);\r\n },\r\n\r\n update: async (data: Partial<T>, where: Record<string, any>): Promise<T[]> => {\r\n const sets = Object.entries(data)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(', ');\r\n \r\n const conditions = Object.entries(where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n\r\n const query = \\`\r\n UPDATE \\${tableName} \r\n SET \\${sets} \r\n WHERE \\${conditions}\r\n RETURNING *\r\n \\`;\r\n\r\n return this.sql<T>(query);\r\n },\r\n\r\n delete: async (where: Record<string, any>): Promise<T[]> => {\r\n const conditions = Object.entries(where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n\r\n const query = \\`DELETE FROM \\${tableName} WHERE \\${conditions} RETURNING *\\`;\r\n return this.sql<T>(query);\r\n },\r\n };\r\n }\r\n}\r\n\r\nexport function createClient(config?: KolaybaseConfig): KolaybaseClient {\r\n return new KolaybaseClient(config);\r\n}\r\n`;\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(path.join(outputDir, 'kolaybase.ts'), clientContent);\r\n}\r\n\r\nasync function generateJsClient(config: any, outputDir: string) {\r\n const clientContent = `// Generated by Kolaybase CLI\r\nconst axios = require('axios');\r\n\r\nclass KolaybaseClient {\r\n constructor(config = {}) {\r\n this.projectId = '${config.projectId}';\r\n \r\n this.client = axios.create({\r\n baseURL: config.url || process.env.API_URL || 'http://localhost:4000',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': \\`Bearer \\${config.anonKey || process.env.ANON_KEY}\\`,\r\n },\r\n });\r\n }\r\n\r\n async sql(query) {\r\n const { data } = await this.client.post('/sql/execute', {\r\n projectId: this.projectId,\r\n query,\r\n });\r\n return data.rows;\r\n }\r\n\r\n table(tableName) {\r\n return {\r\n select: async (columns = '*', options = {}) => {\r\n let query = \\`SELECT \\${columns} FROM \\${tableName}\\`;\r\n \r\n if (options.where) {\r\n const conditions = Object.entries(options.where)\r\n .map(([k, v]) => \\`\\${k} = '\\${v}'\\`)\r\n .join(' AND ');\r\n query += \\` WHERE \\${conditions}\\`;\r\n }\r\n\r\n return this.sql(query);\r\n },\r\n\r\n insert: async (data) => {\r\n const rows = Array.isArray(data) ? data : [data];\r\n const keys = Object.keys(rows[0]);\r\n const values = rows.map(row => \r\n \\`(\\${keys.map(k => \\`'\\${row[k]}'\\`).join(', ')})\\`\r\n ).join(', ');\r\n\r\n const query = \\`INSERT INTO \\${tableName} (\\${keys.join(', ')}) VALUES \\${values} RETURNING *\\`;\r\n return this.sql(query);\r\n },\r\n };\r\n }\r\n}\r\n\r\nfunction createClient(config) {\r\n return new KolaybaseClient(config);\r\n}\r\n\r\nmodule.exports = { KolaybaseClient, createClient };\r\n`;\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(path.join(outputDir, 'kolaybase.js'), clientContent);\r\n}\r\n\r\nasync function generatePyClient(config: any, outputDir: string) {\r\n const clientContent = `# Generated by Kolaybase CLI\r\nimport os\r\nimport requests\r\nfrom typing import List, Dict, Any, Optional\r\n\r\nclass KolaybaseClient:\r\n def __init__(self, config: Optional[Dict[str, str]] = None):\r\n config = config or {}\r\n self.project_id = '${config.projectId}'\r\n self.base_url = config.get('url', os.getenv('API_URL', 'http://localhost:4000'))\r\n self.anon_key = config.get('anon_key', os.getenv('ANON_KEY'))\r\n \r\n self.session = requests.Session()\r\n self.session.headers.update({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': f'Bearer {self.anon_key}'\r\n })\r\n \r\n def sql(self, query: str) -> List[Dict[str, Any]]:\r\n response = self.session.post(\r\n f'{self.base_url}/sql/execute',\r\n json={'projectId': self.project_id, 'query': query}\r\n )\r\n response.raise_for_status()\r\n return response.json()['rows']\r\n \r\n def table(self, table_name: str):\r\n class TableOperations:\r\n def __init__(self, client, table):\r\n self.client = client\r\n self.table = table\r\n \r\n def select(self, columns='*', where=None, limit=None):\r\n query = f'SELECT {columns} FROM {self.table}'\r\n \r\n if where:\r\n conditions = ' AND '.join([f\"{k} = '{v}'\" for k, v in where.items()])\r\n query += f' WHERE {conditions}'\r\n \r\n if limit:\r\n query += f' LIMIT {limit}'\r\n \r\n return self.client.sql(query)\r\n \r\n return TableOperations(self, table_name)\r\n\r\ndef create_client(config: Optional[Dict[str, str]] = None) -> KolaybaseClient:\r\n return KolaybaseClient(config)\r\n`;\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(path.join(outputDir, 'kolaybase.py'), clientContent);\r\n}\r\n\r\nfunction toPascalCase(str: string): string {\r\n return str\r\n .split('_')\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\r\n .join('');\r\n}\r\n\r\nfunction pgTypeToTs(pgType: string): string {\r\n const typeMap: Record<string, string> = {\r\n 'integer': 'number',\r\n 'bigint': 'number',\r\n 'smallint': 'number',\r\n 'decimal': 'number',\r\n 'numeric': 'number',\r\n 'real': 'number',\r\n 'double precision': 'number',\r\n 'serial': 'number',\r\n 'bigserial': 'number',\r\n 'character varying': 'string',\r\n 'varchar': 'string',\r\n 'character': 'string',\r\n 'char': 'string',\r\n 'text': 'string',\r\n 'boolean': 'boolean',\r\n 'date': 'string',\r\n 'timestamp': 'string',\r\n 'timestamp without time zone': 'string',\r\n 'timestamp with time zone': 'string',\r\n 'time': 'string',\r\n 'json': 'any',\r\n 'jsonb': 'any',\r\n 'uuid': 'string',\r\n 'bytea': 'Buffer',\r\n };\r\n\r\n return typeMap[pgType.toLowerCase()] || 'any';\r\n}\r\n","import chalk from 'chalk';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig } from '../lib/config.js';\r\nimport { success, error, info, warning, createSpinner } from '../lib/ui.js';\r\n\r\nconst MIGRATIONS_DIR = 'migrations';\r\nconst TRACKING_TABLE = '_kb_migrations';\r\n\r\n// ── Ensure tracking table exists ─────────────────────────────\r\n\r\nasync function ensureTrackingTable(projectId: string) {\r\n await apiClient.executeSQL(projectId, `\r\n CREATE TABLE IF NOT EXISTS \"${TRACKING_TABLE}\" (\r\n id SERIAL PRIMARY KEY,\r\n name TEXT UNIQUE NOT NULL,\r\n applied_at TIMESTAMPTZ DEFAULT NOW()\r\n )\r\n `);\r\n}\r\n\r\n// ── Parse up/down sections from a migration file ─────────────\r\n\r\nfunction parseMigration(content: string): { up: string; down: string | null } {\r\n const upMatch = content.match(/--\\s*up\\s*\\n([\\s\\S]*?)(?:--\\s*down\\s*\\n|$)/i);\r\n const downMatch = content.match(/--\\s*down\\s*\\n([\\s\\S]*?)$/i);\r\n\r\n if (upMatch) {\r\n return {\r\n up: upMatch[1].trim(),\r\n down: downMatch ? downMatch[1].trim() : null,\r\n };\r\n }\r\n\r\n // No markers → treat entire file as up migration\r\n return { up: content.trim(), down: null };\r\n}\r\n\r\n// ── Get applied migration names from DB ──────────────────────\r\n\r\nasync function getApplied(projectId: string): Promise<Set<string>> {\r\n try {\r\n const result = await apiClient.executeSQL(\r\n projectId,\r\n `SELECT name FROM \"${TRACKING_TABLE}\" ORDER BY applied_at`,\r\n );\r\n return new Set((result?.rows ?? []).map((r: any) => r.name));\r\n } catch {\r\n return new Set();\r\n }\r\n}\r\n\r\n// ── Get local migration files sorted by timestamp ────────────\r\n\r\nasync function getLocalMigrations(): Promise<string[]> {\r\n try {\r\n const files = await fs.readdir(MIGRATIONS_DIR);\r\n return files\r\n .filter((f) => f.endsWith('.sql') && !f.endsWith('.down.sql'))\r\n .sort();\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────\r\n// Commands\r\n// ─────────────────────────────────────────────────────────────\r\n\r\nexport async function migrationNew(name: string) {\r\n if (!name?.trim()) {\r\n error('Provide a migration name: kb migration new <name>');\r\n process.exit(1);\r\n }\r\n\r\n await fs.mkdir(MIGRATIONS_DIR, { recursive: true });\r\n\r\n const ts = new Date()\r\n .toISOString()\r\n .replace(/[-T:\\.Z]/g, '')\r\n .slice(0, 14); // e.g. 20260314153000\r\n\r\n const safeName = name.toLowerCase().replace(/[^a-z0-9]/g, '_');\r\n const filename = `${ts}_${safeName}.sql`;\r\n const filepath = path.join(MIGRATIONS_DIR, filename);\r\n\r\n const template = `-- Migration: ${safeName}\r\n-- Created: ${new Date().toISOString()}\r\n\r\n-- up\r\n\r\n-- write your SQL here\r\n\r\n\r\n-- down\r\n\r\n-- write rollback SQL here (optional)\r\n\r\n`;\r\n\r\n await fs.writeFile(filepath, template);\r\n success(`Created ${chalk.cyan(filepath)}`);\r\n}\r\n\r\nexport async function migrationStatus() {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Checking migration status…');\r\n\r\n try {\r\n await ensureTrackingTable(config.projectId);\r\n const applied = await getApplied(config.projectId);\r\n const local = await getLocalMigrations();\r\n spinner.stop();\r\n\r\n if (!local.length) {\r\n info('No migration files found in ./migrations/');\r\n console.log(chalk.gray(' Create one: kb migration new <name>'));\r\n return;\r\n }\r\n\r\n console.log();\r\n const nameW = Math.max(10, ...local.map((f) => f.length));\r\n console.log(\r\n ` ${'Migration'.padEnd(nameW)} Status`,\r\n );\r\n console.log(chalk.gray(` ${'─'.repeat(nameW + 12)}`));\r\n\r\n for (const file of local) {\r\n const isApplied = applied.has(file);\r\n const badge = isApplied ? chalk.green('✓ applied') : chalk.yellow('○ pending');\r\n console.log(` ${chalk.cyan(file.padEnd(nameW))} ${badge}`);\r\n }\r\n\r\n const pendingCount = local.filter((f) => !applied.has(f)).length;\r\n console.log();\r\n console.log(chalk.gray(` ${local.length} migration(s) — ${applied.size} applied, ${pendingCount} pending`));\r\n if (pendingCount > 0) {\r\n console.log(chalk.gray(' Run kb migration up to apply pending migrations'));\r\n }\r\n } catch (err) {\r\n spinner.fail('Failed to get migration status');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface UpOptions {\r\n step?: string;\r\n dryRun?: boolean;\r\n}\r\n\r\nexport async function migrationUp(options: UpOptions = {}) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n const maxStep = options.step ? parseInt(options.step, 10) : Infinity;\r\n\r\n const spinner = createSpinner('Preparing migrations…');\r\n\r\n try {\r\n await ensureTrackingTable(config.projectId);\r\n const applied = await getApplied(config.projectId);\r\n const local = await getLocalMigrations();\r\n const pending = local.filter((f) => !applied.has(f)).slice(0, maxStep);\r\n spinner.stop();\r\n\r\n if (!pending.length) {\r\n success('Already up to date');\r\n return;\r\n }\r\n\r\n console.log();\r\n info(`${pending.length} pending migration(s) to apply:`);\r\n pending.forEach((f) => console.log(chalk.gray(` • ${f}`)));\r\n console.log();\r\n\r\n if (options.dryRun) {\r\n warning('Dry run — no changes made');\r\n return;\r\n }\r\n\r\n let applied_count = 0;\r\n\r\n for (const file of pending) {\r\n const sp = createSpinner(`Applying ${chalk.cyan(file)}…`);\r\n try {\r\n const content = await fs.readFile(path.join(MIGRATIONS_DIR, file), 'utf-8');\r\n const { up } = parseMigration(content);\r\n\r\n if (!up) {\r\n sp.fail(`No SQL found in ${file}`);\r\n continue;\r\n }\r\n\r\n await apiClient.executeSQL(config.projectId!, up);\r\n await apiClient.executeSQL(\r\n config.projectId!,\r\n `INSERT INTO \"${TRACKING_TABLE}\" (name) VALUES ('${file.replace(/'/g, \"''\")}')`,\r\n );\r\n\r\n sp.succeed(`Applied ${chalk.cyan(file)}`);\r\n applied_count++;\r\n } catch (err: any) {\r\n sp.fail(`Failed: ${file}`);\r\n error(err.message || String(err));\r\n error('Migration stopped. Fix the error and run kb migration up again.');\r\n process.exit(1);\r\n }\r\n }\r\n\r\n console.log();\r\n success(`${applied_count} migration(s) applied`);\r\n } catch (err) {\r\n spinner.fail('Migration failed');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface DownOptions {\r\n step?: string;\r\n dryRun?: boolean;\r\n}\r\n\r\nexport async function migrationDown(options: DownOptions = {}) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n const stepCount = options.step ? parseInt(options.step, 10) : 1;\r\n\r\n const spinner = createSpinner('Preparing rollback…');\r\n\r\n try {\r\n await ensureTrackingTable(config.projectId);\r\n const applied = await getApplied(config.projectId);\r\n const local = await getLocalMigrations();\r\n\r\n // Rollback in reverse order\r\n const toRollback = local\r\n .filter((f) => applied.has(f))\r\n .reverse()\r\n .slice(0, stepCount);\r\n\r\n spinner.stop();\r\n\r\n if (!toRollback.length) {\r\n info('Nothing to rollback');\r\n return;\r\n }\r\n\r\n console.log();\r\n info(`Rolling back ${toRollback.length} migration(s):`);\r\n toRollback.forEach((f) => console.log(chalk.gray(` • ${f}`)));\r\n console.log();\r\n\r\n if (options.dryRun) {\r\n warning('Dry run — no changes made');\r\n return;\r\n }\r\n\r\n for (const file of toRollback) {\r\n const sp = createSpinner(`Rolling back ${chalk.cyan(file)}…`);\r\n try {\r\n const content = await fs.readFile(path.join(MIGRATIONS_DIR, file), 'utf-8');\r\n const { down } = parseMigration(content);\r\n\r\n if (!down) {\r\n sp.fail(`No -- down section in ${file} — skipping`);\r\n continue;\r\n }\r\n\r\n await apiClient.executeSQL(config.projectId!, down);\r\n await apiClient.executeSQL(\r\n config.projectId!,\r\n `DELETE FROM \"${TRACKING_TABLE}\" WHERE name = '${file.replace(/'/g, \"''\")}'`,\r\n );\r\n\r\n sp.succeed(`Rolled back ${chalk.cyan(file)}`);\r\n } catch (err: any) {\r\n sp.fail(`Failed: ${file}`);\r\n error(err.message || String(err));\r\n process.exit(1);\r\n }\r\n }\r\n\r\n console.log();\r\n success(`${toRollback.length} migration(s) rolled back`);\r\n } catch (err) {\r\n spinner.fail('Rollback failed');\r\n handleApiError(err);\r\n }\r\n}\r\n","import chalk from 'chalk';\r\nimport { getProjectConfig, setLocalEnv, unsetLocalEnv, getLocalEnv } from '../lib/config.js';\r\nimport { error, success, info, printKeyValue } from '../lib/ui.js';\r\n\r\nexport async function listSecrets() {\r\n console.log(chalk.bold.cyan('Environment Secrets\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n const env = await getLocalEnv();\r\n \r\n if (Object.keys(env).length === 0) {\r\n info('No secrets configured');\r\n console.log();\r\n console.log(chalk.gray('Add a secret with:'), chalk.cyan('kb secrets set KEY VALUE'));\r\n return;\r\n }\r\n\r\n // Hide sensitive values\r\n const masked = Object.entries(env).reduce((acc, [key, value]) => {\r\n const sensitive = ['PASSWORD', 'SECRET', 'KEY', 'TOKEN'].some(s => \r\n key.toUpperCase().includes(s)\r\n );\r\n \r\n acc[key] = sensitive ? maskValue(value) : value;\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n printKeyValue(masked);\r\n \r\n console.log();\r\n console.log(chalk.gray(`Total: ${Object.keys(env).length} secret(s)`));\r\n } catch (err: any) {\r\n error(`Failed to list secrets: ${err.message}`);\r\n }\r\n}\r\n\r\nexport async function setSecret(key: string, value: string) {\r\n console.log(chalk.bold.cyan('Set Secret\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n await setLocalEnv(key, value);\r\n success(`Secret ${chalk.cyan(key)} set successfully`);\r\n \r\n console.log();\r\n info('Secret saved to .env file');\r\n } catch (err: any) {\r\n error(`Failed to set secret: ${err.message}`);\r\n }\r\n}\r\n\r\nexport async function unsetSecret(key: string) {\r\n console.log(chalk.bold.cyan('Remove Secret\\n'));\r\n\r\n const config = await getProjectConfig();\r\n if (!config) {\r\n error('Not in a Kolaybase project. Run: kb init');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n await unsetLocalEnv(key);\r\n success(`Secret ${chalk.cyan(key)} removed successfully`);\r\n } catch (err: any) {\r\n error(`Failed to remove secret: ${err.message}`);\r\n }\r\n}\r\n\r\nfunction maskValue(value: string): string {\r\n if (value.length <= 8) {\r\n return '*'.repeat(value.length);\r\n }\r\n \r\n return value.substring(0, 4) + '*'.repeat(value.length - 8) + value.substring(value.length - 4);\r\n}\r\n","import { Command } from 'commander';\r\nimport { readFileSync } from 'fs';\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname, resolve } from 'path';\r\nimport { loginCommand } from './commands/login.js';\r\nimport { initCommand } from './commands/init.js';\r\nimport { projectsCommand, createProject, deleteProject } from './commands/projects.js';\r\nimport { statusCommand } from './commands/status.js';\r\nimport { linkCommand, unlinkProject } from './commands/link.js';\r\nimport { logsCommand } from './commands/logs.js';\r\n\r\nconst __dirname = dirname(fileURLToPath(import.meta.url));\r\nconst pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('kb')\r\n .description('Kolaybase CLI — manage your Kolaybase projects')\r\n .version(pkg.version);\r\n\r\n// ── Authentication ──────────────────────────────────────────\r\n\r\nprogram\r\n .command('login')\r\n .description('Authenticate with the Kolaybase platform')\r\n .option('--api-url <url>', 'Platform API URL (default: https://api.kolaybase.com)')\r\n .action(loginCommand);\r\n\r\n// ── Project lifecycle ───────────────────────────────────────\r\n\r\nprogram\r\n .command('init')\r\n .description('Create a new Kolaybase project and link it to the current directory')\r\n .option('-n, --name <name>', 'Project name')\r\n .action(initCommand);\r\n\r\nprogram\r\n .command('link')\r\n .description('Link current directory to an existing remote project')\r\n .option('--project-id <id>', 'Project ID to link directly')\r\n .action(linkCommand);\r\n\r\nprogram\r\n .command('unlink')\r\n .description('Remove the project link from the current directory')\r\n .action(unlinkProject);\r\n\r\n// ── Project info ────────────────────────────────────────────\r\n\r\nprogram\r\n .command('status')\r\n .description('Show credentials, keys, and connection info for the linked project')\r\n .option('--show-keys', 'Reveal secret values instead of masking them')\r\n .action(statusCommand);\r\n\r\nprogram\r\n .command('projects')\r\n .alias('list')\r\n .description('List all projects in your team')\r\n .action(projectsCommand);\r\n\r\nprogram\r\n .command('projects:create')\r\n .description('Create a new project without linking')\r\n .option('-n, --name <name>', 'Project name')\r\n .option('-d, --description <description>', 'Project description')\r\n .action(createProject);\r\n\r\nprogram\r\n .command('projects:delete <projectId>')\r\n .description('Delete a remote project (requires confirmation)')\r\n .action(deleteProject);\r\n\r\n// ── Database ────────────────────────────────────────────────\r\n\r\nconst db = program\r\n .command('db')\r\n .description('Manage the project database');\r\n\r\ndb.command('push')\r\n .description('Push local schema to the project database')\r\n .action(async () => {\r\n const { dbPush } = await import('./commands/db.js');\r\n await dbPush();\r\n });\r\n\r\ndb.command('pull')\r\n .description('Introspect the remote database and save schema locally')\r\n .action(async () => {\r\n const { dbPull } = await import('./commands/db.js');\r\n await dbPull();\r\n });\r\n\r\ndb.command('reset')\r\n .description('Drop all tables in the project database')\r\n .option('-f, --force', 'Skip confirmation prompt')\r\n .action(async (options) => {\r\n const { dbReset } = await import('./commands/db.js');\r\n await dbReset(options);\r\n });\r\n\r\ndb.command('seed')\r\n .description('Run the seed file against the project database')\r\n .action(async () => {\r\n const { dbSeed } = await import('./commands/db.js');\r\n await dbSeed();\r\n });\r\n\r\ndb.command('dump')\r\n .description('Dump the full database schema to SQL')\r\n .option('-o, --output <file>', 'Output file', 'schema.sql')\r\n .action(async (options) => {\r\n const { dbDump } = await import('./commands/db.js');\r\n await dbDump(options);\r\n });\r\n\r\ndb.command('diff')\r\n .description('Show schema differences between local Prisma schema and remote database')\r\n .action(async () => {\r\n const { dbDiff } = await import('./commands/db.js');\r\n await dbDiff();\r\n });\r\n\r\ndb.command('execute')\r\n .description('Execute a SQL file or inline query against the project database')\r\n .option('-f, --file <path>', 'SQL file to execute')\r\n .option('-q, --query <sql>', 'SQL query to run directly')\r\n .action(async (options) => {\r\n const { dbExecute } = await import('./commands/db.js');\r\n await dbExecute(options);\r\n });\r\n\r\n// ── Inspect ─────────────────────────────────────────────────\r\n\r\nprogram\r\n .command('inspect')\r\n .description('Show database tables, columns, sizes, and row counts')\r\n .option('-t, --table <name>', 'Inspect a specific table')\r\n .action(async (options) => {\r\n const { inspectCommand } = await import('./commands/inspect.js');\r\n await inspectCommand(options);\r\n });\r\n\r\n// ── Code generation ─────────────────────────────────────────\r\n\r\nconst gen = program\r\n .command('gen')\r\n .description('Generate code from the project database');\r\n\r\ngen.command('types')\r\n .description('Generate TypeScript types from the database schema')\r\n .option('-o, --output <path>', 'Output directory', './types')\r\n .action(async (options) => {\r\n const { genTypes } = await import('./commands/gen.js');\r\n await genTypes(options);\r\n });\r\n\r\ngen.command('client')\r\n .description('Generate a ready-to-use API client')\r\n .option('-l, --lang <language>', 'Language: typescript | javascript | python', 'typescript')\r\n .option('-o, --output <path>', 'Output directory', './lib')\r\n .action(async (options) => {\r\n const { genClient } = await import('./commands/gen.js');\r\n await genClient(options);\r\n });\r\n\r\n// ── Migrations ──────────────────────────────────────────────\r\n\r\nconst migration = program\r\n .command('migration')\r\n .alias('migrate')\r\n .description('Manage database migrations');\r\n\r\nmigration\r\n .command('new <name>')\r\n .description('Create a new migration file')\r\n .action(async (name) => {\r\n const { migrationNew } = await import('./commands/migration.js');\r\n await migrationNew(name);\r\n });\r\n\r\nmigration\r\n .command('up')\r\n .description('Apply pending migrations')\r\n .option('-s, --step <n>', 'Apply at most N migrations')\r\n .option('--dry-run', 'Preview without applying')\r\n .action(async (options) => {\r\n const { migrationUp } = await import('./commands/migration.js');\r\n await migrationUp(options);\r\n });\r\n\r\nmigration\r\n .command('down')\r\n .description('Rollback the last applied migration')\r\n .option('-s, --step <n>', 'Roll back N migrations (default: 1)')\r\n .option('--dry-run', 'Preview without rolling back')\r\n .action(async (options) => {\r\n const { migrationDown } = await import('./commands/migration.js');\r\n await migrationDown(options);\r\n });\r\n\r\nmigration\r\n .command('status')\r\n .alias('list')\r\n .description('Show applied and pending migrations')\r\n .action(async () => {\r\n const { migrationStatus } = await import('./commands/migration.js');\r\n await migrationStatus();\r\n });\r\n\r\n// ── Top-level shortcuts ──────────────────────────────────────\r\n\r\nprogram\r\n .command('push')\r\n .description('Shortcut for: kb db push')\r\n .action(async () => {\r\n const { dbPush } = await import('./commands/db.js');\r\n await dbPush();\r\n });\r\n\r\n// ── Logs ────────────────────────────────────────────────────\r\n\r\nprogram\r\n .command('logs')\r\n .description('Show SQL audit logs for the linked project')\r\n .option('-n, --tail <lines>', 'Number of recent entries', '50')\r\n .action(logsCommand);\r\n\r\n// ── Secrets / env ───────────────────────────────────────────\r\n\r\nconst secrets = program\r\n .command('secrets')\r\n .description('Manage local .env variables for the linked project');\r\n\r\nsecrets.command('list')\r\n .description('List all variables (sensitive values masked)')\r\n .action(async () => {\r\n const { listSecrets } = await import('./commands/secrets.js');\r\n await listSecrets();\r\n });\r\n\r\nsecrets.command('set <key> <value>')\r\n .description('Set or update a variable')\r\n .action(async (key, value) => {\r\n const { setSecret } = await import('./commands/secrets.js');\r\n await setSecret(key, value);\r\n });\r\n\r\nsecrets.command('unset <key>')\r\n .description('Remove a variable')\r\n .action(async (key) => {\r\n const { unsetSecret } = await import('./commands/secrets.js');\r\n await unsetSecret(key);\r\n });\r\n\r\nprogram.parse();\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { setUserConfig, setAccessToken, setRefreshToken, setApiUrl } from '../lib/config.js';\r\nimport { success, createSpinner, printLogo } from '../lib/ui.js';\r\n\r\ninterface LoginOptions {\r\n apiUrl?: string;\r\n}\r\n\r\nexport async function loginCommand(options: LoginOptions) {\r\n printLogo();\r\n\r\n if (options.apiUrl) {\r\n setApiUrl(options.apiUrl);\r\n }\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'email',\r\n message: 'Email:',\r\n validate: (v: string) => (v.includes('@') && v.length > 3) || 'Please enter a valid email',\r\n },\r\n {\r\n type: 'password',\r\n name: 'password',\r\n message: 'Password:',\r\n mask: '*',\r\n validate: (v: string) => v.length > 0 || 'Required',\r\n },\r\n ]);\r\n\r\n const spinner = createSpinner('Authenticating…');\r\n\r\n try {\r\n const data = await apiClient.login(answers.email, answers.password);\r\n\r\n setAccessToken(data.accessToken);\r\n setRefreshToken(data.refreshToken);\r\n setUserConfig({ email: answers.email });\r\n\r\n spinner.succeed('Logged in');\r\n console.log();\r\n success(`Welcome, ${chalk.cyan(answers.email)}`);\r\n console.log(chalk.gray(' Run kb init to create a project or kb link to connect to one'));\r\n } catch (err) {\r\n spinner.fail('Authentication failed');\r\n handleApiError(err);\r\n }\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport path from 'path';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { setProjectConfig, isLoggedIn, getProjectConfig, writeEnvFile } from '../lib/config.js';\r\nimport { success, error, warning, createSpinner, printHeader } from '../lib/ui.js';\r\n\r\ninterface InitOptions {\r\n name?: string;\r\n}\r\n\r\nexport async function initCommand(options: InitOptions) {\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n const existingConfig = await getProjectConfig();\r\n if (existingConfig?.projectId) {\r\n warning(`This directory is already linked to project \"${existingConfig.projectName}\"`);\r\n console.log(chalk.gray(` ID: ${existingConfig.projectId}`));\r\n console.log();\r\n console.log(chalk.gray(' To link to a different project run: kb link'));\r\n console.log(chalk.gray(' To unlink first: kb unlink'));\r\n return;\r\n }\r\n\r\n const spinner = createSpinner('Loading teams…');\r\n\r\n try {\r\n const teams = await apiClient.getTeams();\r\n spinner.stop();\r\n\r\n if (!teams?.length) {\r\n error('No teams found. Create an account first via the Admin UI.');\r\n process.exit(1);\r\n }\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'teamId',\r\n message: 'Team:',\r\n choices: teams.map((t: any) => ({\r\n name: t.personalForUserId ? `${t.name} ${chalk.gray('(personal)')}` : t.name,\r\n value: t.id,\r\n })),\r\n when: teams.length > 1,\r\n },\r\n {\r\n type: 'input',\r\n name: 'name',\r\n message: 'Project name:',\r\n default: options.name || path.basename(process.cwd()),\r\n validate: (v: string) => v.trim().length > 0 || 'Required',\r\n },\r\n {\r\n type: 'input',\r\n name: 'description',\r\n message: 'Description (optional):',\r\n },\r\n ]);\r\n\r\n const teamId = answers.teamId || teams[0].id;\r\n\r\n const createSpinnerInstance = createSpinner('Creating project…');\r\n\r\n const project = await apiClient.createProject({\r\n name: answers.name,\r\n description: answers.description || undefined,\r\n teamId,\r\n });\r\n\r\n createSpinnerInstance.succeed('Project created');\r\n\r\n await setProjectConfig({\r\n projectId: project.id,\r\n projectName: project.name,\r\n projectSlug: project.slug,\r\n teamId: project.teamId,\r\n linkedAt: new Date().toISOString(),\r\n });\r\n\r\n await writeEnvFile(project);\r\n\r\n console.log();\r\n printHeader('Project ready');\r\n console.log();\r\n console.log(` ${chalk.gray('Name')} ${project.name}`);\r\n console.log(` ${chalk.gray('ID')} ${project.id}`);\r\n console.log(` ${chalk.gray('Database')} ${project.dbName}`);\r\n console.log(` ${chalk.gray('Realm')} ${project.keycloakRealm}`);\r\n console.log();\r\n success('Configuration saved to .kolaybase/config.json');\r\n success('Credentials saved to .env');\r\n console.log();\r\n console.log(chalk.gray(' Next steps:'));\r\n console.log(chalk.gray(' kb status — view full connection details'));\r\n console.log(chalk.gray(' kb inspect — list database tables'));\r\n console.log(chalk.gray(' kb gen types — generate TypeScript types'));\r\n console.log(chalk.gray(' kb db push — push a local schema'));\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { isLoggedIn } from '../lib/config.js';\r\nimport { success, error, info, createSpinner, printTable, printHeader } from '../lib/ui.js';\r\n\r\nexport async function projectsCommand() {\r\n if (!isLoggedIn()) {\r\n error('You must be logged in to view projects');\r\n console.log(chalk.gray('Run: kb login'));\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Loading projects...');\r\n\r\n try {\r\n const teams = await apiClient.getTeams();\r\n const team = teams[0]; // Use first team\r\n const projects = await apiClient.getProjects(team.id);\r\n \r\n spinner.stop();\r\n\r\n if (!projects || projects.length === 0) {\r\n info('No projects found');\r\n console.log();\r\n console.log(chalk.gray('Create your first project with:'), chalk.cyan('kb init'));\r\n return;\r\n }\r\n\r\n printHeader('Your Projects');\r\n console.log();\r\n\r\n const rows = projects.map((project: any) => [\r\n chalk.cyan(project.name),\r\n project.slug,\r\n project.status,\r\n new Date(project.createdAt).toLocaleDateString(),\r\n project.id,\r\n ]);\r\n\r\n printTable(\r\n ['Name', 'Slug', 'Status', 'Created', 'ID'],\r\n rows\r\n );\r\n\r\n console.log();\r\n console.log(chalk.gray(`Total: ${projects.length} project(s)`));\r\n } catch (err) {\r\n spinner.fail('Failed to load projects');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\ninterface CreateProjectOptions {\r\n name?: string;\r\n description?: string;\r\n}\r\n\r\nexport async function createProject(options: CreateProjectOptions) {\r\n if (!isLoggedIn()) {\r\n error('You must be logged in to create a project');\r\n console.log(chalk.gray('Run: kb login'));\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n const teams = await apiClient.getTeams();\r\n const team = teams[0];\r\n\r\n let name = options.name;\r\n let description = options.description;\r\n\r\n if (!name) {\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'name',\r\n message: 'Project name:',\r\n validate: (input) => input.length > 0 || 'Project name is required',\r\n },\r\n {\r\n type: 'input',\r\n name: 'description',\r\n message: 'Description (optional):',\r\n },\r\n ]);\r\n\r\n name = answers.name;\r\n description = answers.description;\r\n }\r\n\r\n const spinner = createSpinner('Creating project...');\r\n\r\n const project = await apiClient.createProject({\r\n name: name!,\r\n description,\r\n teamId: team.id,\r\n });\r\n\r\n spinner.succeed('Project created successfully');\r\n \r\n console.log();\r\n console.log(chalk.gray('Name:'), chalk.cyan(project.name));\r\n console.log(chalk.gray('ID:'), project.id);\r\n console.log(chalk.gray('Slug:'), project.slug);\r\n console.log(chalk.gray('Database:'), project.dbName);\r\n \r\n console.log();\r\n console.log(chalk.gray('To start working with this project:'));\r\n console.log(chalk.cyan(' kb init --link'));\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function deleteProject(projectId: string) {\r\n if (!isLoggedIn()) {\r\n error('You must be logged in to delete a project');\r\n console.log(chalk.gray('Run: kb login'));\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n const spinner = createSpinner('Loading project...');\r\n const project = await apiClient.getProject(projectId);\r\n spinner.stop();\r\n\r\n console.log();\r\n console.log(chalk.yellow('⚠ WARNING: This action cannot be undone!'));\r\n console.log();\r\n console.log(chalk.gray('Project:'), chalk.cyan(project.name));\r\n console.log(chalk.gray('Database:'), project.dbName);\r\n console.log();\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'confirm',\r\n message: 'Are you sure you want to delete this project?',\r\n default: false,\r\n },\r\n {\r\n type: 'input',\r\n name: 'confirmName',\r\n message: `Type the project name \"${project.name}\" to confirm:`,\r\n when: (answers) => answers.confirm,\r\n validate: (input) => \r\n input === project.name || `You must type \"${project.name}\" exactly`,\r\n },\r\n ]);\r\n\r\n if (!answers.confirm) {\r\n info('Deletion cancelled');\r\n return;\r\n }\r\n\r\n const deleteSpinner = createSpinner('Deleting project...');\r\n await apiClient.deleteProject(projectId);\r\n deleteSpinner.succeed('Project deleted successfully');\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n","import chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, isLoggedIn } from '../lib/config.js';\r\nimport { error, printHeader, createSpinner } from '../lib/ui.js';\r\n\r\ninterface StatusOptions {\r\n showKeys?: boolean;\r\n}\r\n\r\nexport async function statusCommand(options: StatusOptions) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n const spinner = createSpinner('Fetching project details…');\r\n\r\n try {\r\n const project = await apiClient.getProject(config.projectId);\r\n spinner.stop();\r\n\r\n const mask = (val: string) =>\r\n options.showKeys ? val : val.slice(0, 6) + '•'.repeat(Math.max(0, val.length - 10)) + val.slice(-4);\r\n\r\n printHeader(`Project: ${project.name}`);\r\n console.log();\r\n\r\n // ── General ──────────────────────────────────────────\r\n section('General');\r\n row('Project ID', project.id);\r\n row('Name', project.name);\r\n row('Slug', project.slug);\r\n row('Status', statusBadge(project.status));\r\n row('Created', new Date(project.createdAt).toLocaleString());\r\n console.log();\r\n\r\n // ── Database ─────────────────────────────────────────\r\n section('Database');\r\n row('Host', project.dbHost);\r\n row('Port', String(project.dbPort));\r\n row('Database', project.dbName);\r\n row('User', project.dbUser);\r\n row('Password', mask(project.dbPassword));\r\n console.log();\r\n\r\n const connStr = `postgresql://${project.dbUser}:${options.showKeys ? project.dbPassword : '••••••'}@${project.dbHost}:${project.dbPort}/${project.dbName}`;\r\n row('Connection string', chalk.cyan(connStr));\r\n console.log();\r\n\r\n // ── Auth / Keycloak ──────────────────────────────────\r\n section('Authentication (Keycloak)');\r\n row('Realm', project.keycloakRealm);\r\n row('Anon Key', mask(project.anonKey));\r\n row('Service Key', mask(project.serviceKey));\r\n console.log();\r\n\r\n // ── Hint ─────────────────────────────────────────────\r\n if (!options.showKeys) {\r\n console.log(chalk.gray(' Tip: use kb status --show-keys to reveal secrets'));\r\n }\r\n console.log();\r\n } catch (err) {\r\n spinner.fail('Could not fetch project');\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nfunction section(title: string) {\r\n console.log(chalk.bold(` ${title}`));\r\n}\r\n\r\nfunction row(label: string, value: string) {\r\n console.log(` ${chalk.gray(label.padEnd(20))} ${value}`);\r\n}\r\n\r\nfunction statusBadge(status: string): string {\r\n switch (status) {\r\n case 'ACTIVE':\r\n return chalk.green('● ACTIVE');\r\n case 'PAUSED':\r\n return chalk.yellow('● PAUSED');\r\n case 'DELETED':\r\n return chalk.red('● DELETED');\r\n default:\r\n return status;\r\n }\r\n}\r\n","import inquirer from 'inquirer';\r\nimport chalk from 'chalk';\r\nimport fs from 'fs/promises';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { setProjectConfig, isLoggedIn, writeEnvFile } from '../lib/config.js';\r\nimport { success, error, createSpinner } from '../lib/ui.js';\r\n\r\ninterface LinkOptions {\r\n projectId?: string;\r\n}\r\n\r\nexport async function linkCommand(options: LinkOptions) {\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n try {\r\n let projectId = options.projectId;\r\n\r\n if (!projectId) {\r\n const spinner = createSpinner('Loading projects…');\r\n const teams = await apiClient.getTeams();\r\n\r\n let allProjects: any[] = [];\r\n for (const team of teams) {\r\n const projects = await apiClient.getProjects(team.id);\r\n allProjects.push(\r\n ...projects.map((p: any) => ({ ...p, teamName: team.name })),\r\n );\r\n }\r\n spinner.stop();\r\n\r\n if (!allProjects.length) {\r\n error('No projects found. Create one first: kb init');\r\n process.exit(1);\r\n }\r\n\r\n const { selected } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'selected',\r\n message: 'Select a project to link:',\r\n choices: allProjects.map((p) => ({\r\n name: `${p.name} ${chalk.gray(p.slug)} ${chalk.gray('— ' + p.teamName)}`,\r\n value: p.id,\r\n })),\r\n },\r\n ]);\r\n\r\n projectId = selected;\r\n }\r\n\r\n const spinner = createSpinner('Linking…');\r\n const project = await apiClient.getProject(projectId!);\r\n\r\n await setProjectConfig({\r\n projectId: project.id,\r\n projectName: project.name,\r\n projectSlug: project.slug,\r\n teamId: project.teamId,\r\n linkedAt: new Date().toISOString(),\r\n });\r\n\r\n await writeEnvFile(project);\r\n\r\n spinner.succeed(`Linked to ${chalk.cyan(project.name)}`);\r\n console.log();\r\n console.log(` ${chalk.gray('Database')} ${project.dbName}`);\r\n console.log(` ${chalk.gray('Realm')} ${project.keycloakRealm}`);\r\n console.log();\r\n success('Credentials saved to .env');\r\n console.log(chalk.gray(' Run kb status to see full connection details'));\r\n } catch (err) {\r\n handleApiError(err);\r\n }\r\n}\r\n\r\nexport async function unlinkProject() {\r\n try {\r\n await fs.rm('.kolaybase', { recursive: true, force: true });\r\n success('Project unlinked');\r\n } catch (err: any) {\r\n error(`Failed to unlink: ${err.message}`);\r\n }\r\n}\r\n","import chalk from 'chalk';\r\nimport { apiClient, handleApiError } from '../lib/api.js';\r\nimport { getProjectConfig, isLoggedIn } from '../lib/config.js';\r\nimport { error, printHeader, createSpinner } from '../lib/ui.js';\r\n\r\ninterface LogsOptions {\r\n tail?: string;\r\n}\r\n\r\nexport async function logsCommand(options: LogsOptions) {\r\n const config = await getProjectConfig();\r\n if (!config?.projectId) {\r\n error('Not linked to a project. Run: kb link or kb init');\r\n process.exit(1);\r\n }\r\n\r\n if (!isLoggedIn()) {\r\n error('Not logged in. Run: kb login');\r\n process.exit(1);\r\n }\r\n\r\n const limit = parseInt(options.tail || '50', 10);\r\n\r\n const spinner = createSpinner('Fetching SQL audit logs…');\r\n\r\n try {\r\n const result = await apiClient.executeSQL(\r\n config.projectId!,\r\n `SELECT 1`, // quick connectivity test\r\n );\r\n } catch {\r\n // If SQL endpoint fails we try a direct query via project info\r\n }\r\n\r\n try {\r\n // The audit logs live in the platform DB, not the project DB.\r\n // We'll expose them via the existing SQL endpoint against the project.\r\n // For now, show the last N entries from the API (requires a future endpoint).\r\n\r\n // Fallback: connect directly to the platform database\r\n const { Pool } = await import('pg');\r\n const { getLocalEnv } = await import('../lib/config.js');\r\n const env = await getLocalEnv();\r\n\r\n // Platform DB is the same host but database 'kolaybase'\r\n const host = env.DB_HOST || 'localhost';\r\n const port = env.DB_PORT || '5432';\r\n const platformUrl = `postgresql://kolaybase:kolaybase_secret@${host}:${port}/kolaybase`;\r\n\r\n const pool = new Pool({ connectionString: platformUrl });\r\n const client = await pool.connect();\r\n\r\n try {\r\n const { rows } = await client.query(\r\n `SELECT created_at, user_id, query, row_count, duration, error\r\n FROM sql_audit_logs\r\n WHERE project_id = $1\r\n ORDER BY created_at DESC\r\n LIMIT $2`,\r\n [config.projectId, limit],\r\n );\r\n\r\n spinner.stop();\r\n\r\n if (!rows.length) {\r\n console.log(chalk.gray(' No SQL logs yet for this project.'));\r\n return;\r\n }\r\n\r\n printHeader('SQL Audit Logs');\r\n console.log();\r\n\r\n // Show oldest first\r\n rows.reverse().forEach((r: any) => {\r\n const ts = new Date(r.created_at).toLocaleString();\r\n const dur = r.duration != null ? `${r.duration}ms` : '';\r\n const badge = r.error\r\n ? chalk.red('ERR')\r\n : chalk.green('OK ');\r\n\r\n console.log(` ${chalk.gray(ts)} ${badge} ${chalk.gray(dur)}`);\r\n console.log(` ${chalk.cyan(truncate(r.query, 100))}`);\r\n\r\n if (r.error) {\r\n console.log(` ${chalk.red(r.error)}`);\r\n } else if (r.row_count != null) {\r\n console.log(chalk.gray(` ${r.row_count} row(s)`));\r\n }\r\n console.log();\r\n });\r\n\r\n console.log(chalk.gray(` Showing ${rows.length} entries`));\r\n } finally {\r\n client.release();\r\n await pool.end();\r\n }\r\n } catch (err: any) {\r\n spinner.fail('Could not fetch logs');\r\n console.log(chalk.gray(` ${err.message}`));\r\n console.log(chalk.gray(' Make sure the platform database is accessible.'));\r\n }\r\n}\r\n\r\nfunction truncate(s: string, max: number): string {\r\n const oneLine = s.replace(/\\s+/g, ' ').trim();\r\n return oneLine.length > max ? oneLine.slice(0, max - 1) + '…' : oneLine;\r\n}\r\n"],"mappings":"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","names":["path","error","chalk","row","inquirer","chalk","fs","path","row","chalk","Pool","truncate","chalk","fs","path","Pool","chalk","fs","path","chalk","fileURLToPath","chalk","inquirer","chalk","path","inquirer","chalk","answers","chalk","inquirer","chalk","fs","spinner","chalk","Pool","getLocalEnv","__dirname","fileURLToPath","dbPush","dbPull","dbReset","dbSeed","dbDump","dbDiff","dbExecute","inspectCommand","genTypes","genClient","migrationNew","migrationUp","migrationDown","migrationStatus","listSecrets","setSecret","unsetSecret"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kolaybase-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Kolaybase CLI — manage your backend projects from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
"dotenv": "^16.4.0",
|
|
45
45
|
"execa": "^8.0.1",
|
|
46
46
|
"inquirer": "^9.2.0",
|
|
47
|
-
"kolaybase-cli": "^0.1.2",
|
|
48
47
|
"ora": "^8.0.1",
|
|
49
48
|
"pg": "^8.12.0",
|
|
50
49
|
"table": "^6.8.0"
|