@batadata/cli 0.1.0

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.
Files changed (55) hide show
  1. package/dist/api.d.ts +28 -0
  2. package/dist/api.js +115 -0
  3. package/dist/api.js.map +1 -0
  4. package/dist/args.d.ts +20 -0
  5. package/dist/args.js +42 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/commands/api-keys.d.ts +11 -0
  8. package/dist/commands/api-keys.js +223 -0
  9. package/dist/commands/api-keys.js.map +1 -0
  10. package/dist/commands/auth.d.ts +3 -0
  11. package/dist/commands/auth.js +133 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/connect.d.ts +7 -0
  14. package/dist/commands/connect.js +103 -0
  15. package/dist/commands/connect.js.map +1 -0
  16. package/dist/commands/create.d.ts +7 -0
  17. package/dist/commands/create.js +197 -0
  18. package/dist/commands/create.js.map +1 -0
  19. package/dist/commands/db.d.ts +8 -0
  20. package/dist/commands/db.js +316 -0
  21. package/dist/commands/db.js.map +1 -0
  22. package/dist/commands/dev.d.ts +1 -0
  23. package/dist/commands/dev.js +28 -0
  24. package/dist/commands/dev.js.map +1 -0
  25. package/dist/commands/generate.d.ts +1 -0
  26. package/dist/commands/generate.js +83 -0
  27. package/dist/commands/generate.js.map +1 -0
  28. package/dist/commands/migrate.d.ts +1 -0
  29. package/dist/commands/migrate.js +38 -0
  30. package/dist/commands/migrate.js.map +1 -0
  31. package/dist/commands/projects.d.ts +5 -0
  32. package/dist/commands/projects.js +259 -0
  33. package/dist/commands/projects.js.map +1 -0
  34. package/dist/commands/schema.d.ts +1 -0
  35. package/dist/commands/schema.js +38 -0
  36. package/dist/commands/schema.js.map +1 -0
  37. package/dist/commands/status.d.ts +7 -0
  38. package/dist/commands/status.js +106 -0
  39. package/dist/commands/status.js.map +1 -0
  40. package/dist/config.d.ts +45 -0
  41. package/dist/config.js +96 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +169 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/utils/logger.d.ts +26 -0
  47. package/dist/utils/logger.js +130 -0
  48. package/dist/utils/logger.js.map +1 -0
  49. package/dist/utils/open.d.ts +1 -0
  50. package/dist/utils/open.js +20 -0
  51. package/dist/utils/open.js.map +1 -0
  52. package/dist/utils/prompts.d.ts +7 -0
  53. package/dist/utils/prompts.js +92 -0
  54. package/dist/utils/prompts.js.map +1 -0
  55. package/package.json +39 -0
package/dist/api.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ export interface ApiResponse<T = unknown> {
2
+ ok: boolean;
3
+ status: number;
4
+ data: T;
5
+ }
6
+ export declare function request<T = unknown>(method: string, path: string, options?: {
7
+ token?: string;
8
+ body?: Record<string, unknown>;
9
+ query?: Record<string, string>;
10
+ }): Promise<ApiResponse<T>>;
11
+ /**
12
+ * Extract a human-readable error message from a failed API response.
13
+ * Surfaces the real server error (e.g. "Invalid API key") instead of a
14
+ * generic placeholder so agents see what actually went wrong.
15
+ */
16
+ export declare function apiError(res: ApiResponse, fallback?: string): string;
17
+ export declare function resolveTeamId(token: string): Promise<string | undefined>;
18
+ /**
19
+ * List endpoints return `{ data: [...], pagination }` (not a bare array).
20
+ * Older/other endpoints may return a bare array or `{ projects: [...] }`.
21
+ * Normalize all of them to a plain array.
22
+ */
23
+ export declare function asList<T = unknown>(data: unknown): T[];
24
+ export declare const api: {
25
+ get: <T = unknown>(path: string, token?: string, query?: Record<string, string>) => Promise<ApiResponse<T>>;
26
+ post: <T = unknown>(path: string, body: Record<string, unknown>, token?: string) => Promise<ApiResponse<T>>;
27
+ del: <T = unknown>(path: string, token?: string, query?: Record<string, string>) => Promise<ApiResponse<T>>;
28
+ };
package/dist/api.js ADDED
@@ -0,0 +1,115 @@
1
+ import * as https from "node:https";
2
+ import * as http from "node:http";
3
+ import { URL } from "node:url";
4
+ import { getApiUrl, loadConfig } from "./config.js";
5
+ export async function request(method, path, options = {}) {
6
+ const baseUrl = getApiUrl();
7
+ const url = new URL(path, baseUrl);
8
+ if (options.query) {
9
+ for (const [key, value] of Object.entries(options.query)) {
10
+ if (value !== undefined) {
11
+ url.searchParams.set(key, value);
12
+ }
13
+ }
14
+ }
15
+ const headers = {
16
+ "Content-Type": "application/json",
17
+ "User-Agent": "@batadata/cli 0.1.0",
18
+ };
19
+ if (options.token) {
20
+ headers["Authorization"] = `Bearer ${options.token}`;
21
+ }
22
+ const bodyStr = options.body ? JSON.stringify(options.body) : undefined;
23
+ return new Promise((resolve, reject) => {
24
+ const transport = url.protocol === "https:" ? https : http;
25
+ const req = transport.request(url, {
26
+ method,
27
+ headers,
28
+ }, (res) => {
29
+ let data = "";
30
+ res.on("data", (chunk) => (data += chunk));
31
+ res.on("end", () => {
32
+ try {
33
+ const parsed = data ? JSON.parse(data) : {};
34
+ resolve({
35
+ ok: (res.statusCode || 0) >= 200 && (res.statusCode || 0) < 300,
36
+ status: res.statusCode || 0,
37
+ data: parsed,
38
+ });
39
+ }
40
+ catch {
41
+ resolve({
42
+ ok: false,
43
+ status: res.statusCode || 0,
44
+ data: { error: data },
45
+ });
46
+ }
47
+ });
48
+ });
49
+ req.on("error", reject);
50
+ req.setTimeout(30000, () => {
51
+ req.destroy();
52
+ reject(new Error("Request timed out"));
53
+ });
54
+ if (bodyStr) {
55
+ req.write(bodyStr);
56
+ }
57
+ req.end();
58
+ });
59
+ }
60
+ /**
61
+ * Extract a human-readable error message from a failed API response.
62
+ * Surfaces the real server error (e.g. "Invalid API key") instead of a
63
+ * generic placeholder so agents see what actually went wrong.
64
+ */
65
+ export function apiError(res, fallback = "Request failed") {
66
+ const data = res.data;
67
+ const msg = data && typeof data.error === "string" ? data.error : undefined;
68
+ const code = data && typeof data.code === "string" ? ` (${data.code})` : "";
69
+ if (msg)
70
+ return `${msg}${code}`;
71
+ return `${fallback} (HTTP ${res.status || "?"})`;
72
+ }
73
+ /**
74
+ * Resolve the team id to operate on. Headless agents (just BATA_API_KEY, no
75
+ * prior `bata login`) have no saved defaultTeam, and the API requires a team
76
+ * for project list/create. So fall back to the user's first team. Cached for
77
+ * the process lifetime. Returns undefined only if the user has no teams.
78
+ */
79
+ let _cachedTeamId;
80
+ export async function resolveTeamId(token) {
81
+ const saved = loadConfig().defaultTeam;
82
+ if (saved)
83
+ return saved;
84
+ if (_cachedTeamId)
85
+ return _cachedTeamId;
86
+ const res = await request("GET", "/v1/teams", { token });
87
+ if (!res.ok)
88
+ return undefined;
89
+ const data = res.data;
90
+ const teams = Array.isArray(data) ? data : data?.teams ?? [];
91
+ _cachedTeamId = teams[0]?.id;
92
+ return _cachedTeamId;
93
+ }
94
+ /**
95
+ * List endpoints return `{ data: [...], pagination }` (not a bare array).
96
+ * Older/other endpoints may return a bare array or `{ projects: [...] }`.
97
+ * Normalize all of them to a plain array.
98
+ */
99
+ export function asList(data) {
100
+ if (Array.isArray(data))
101
+ return data;
102
+ const d = data;
103
+ if (d && Array.isArray(d.data))
104
+ return d.data;
105
+ if (d && Array.isArray(d.projects))
106
+ return d.projects;
107
+ return [];
108
+ }
109
+ // Convenience methods
110
+ export const api = {
111
+ get: (path, token, query) => request("GET", path, { token, query }),
112
+ post: (path, body, token) => request("POST", path, { token, body }),
113
+ del: (path, token, query) => request("DELETE", path, { token, query }),
114
+ };
115
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/args.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export interface GlobalFlags {
2
+ json: boolean;
3
+ apiKey?: string;
4
+ apiUrl?: string;
5
+ yes: boolean;
6
+ }
7
+ /**
8
+ * Extract global flags from anywhere in argv, install them into the runtime
9
+ * context, and return the remaining (non-global) args plus the parsed flags.
10
+ *
11
+ * Recognized global flags (work in any position):
12
+ * --json emit machine-readable JSON for read commands
13
+ * --api-key <key> credential (overrides BATA_API_KEY / saved token)
14
+ * --api-url <url> API base URL (overrides BATA_API_URL / saved / default)
15
+ * --yes, -y skip interactive confirmations
16
+ */
17
+ export declare function parseGlobalFlags(argv: string[]): {
18
+ rest: string[];
19
+ flags: GlobalFlags;
20
+ };
package/dist/args.js ADDED
@@ -0,0 +1,42 @@
1
+ import { setRuntime } from "./config.js";
2
+ /**
3
+ * Extract global flags from anywhere in argv, install them into the runtime
4
+ * context, and return the remaining (non-global) args plus the parsed flags.
5
+ *
6
+ * Recognized global flags (work in any position):
7
+ * --json emit machine-readable JSON for read commands
8
+ * --api-key <key> credential (overrides BATA_API_KEY / saved token)
9
+ * --api-url <url> API base URL (overrides BATA_API_URL / saved / default)
10
+ * --yes, -y skip interactive confirmations
11
+ */
12
+ export function parseGlobalFlags(argv) {
13
+ const flags = { json: false, yes: false };
14
+ const rest = [];
15
+ for (let i = 0; i < argv.length; i++) {
16
+ const arg = argv[i];
17
+ if (arg === "--json") {
18
+ flags.json = true;
19
+ }
20
+ else if (arg === "--yes" || arg === "-y") {
21
+ flags.yes = true;
22
+ }
23
+ else if (arg === "--api-key") {
24
+ flags.apiKey = argv[++i];
25
+ }
26
+ else if (arg.startsWith("--api-key=")) {
27
+ flags.apiKey = arg.slice("--api-key=".length);
28
+ }
29
+ else if (arg === "--api-url") {
30
+ flags.apiUrl = argv[++i];
31
+ }
32
+ else if (arg.startsWith("--api-url=")) {
33
+ flags.apiUrl = arg.slice("--api-url=".length);
34
+ }
35
+ else {
36
+ rest.push(arg);
37
+ }
38
+ }
39
+ setRuntime({ json: flags.json, apiKey: flags.apiKey, apiUrl: flags.apiUrl });
40
+ return { rest, flags };
41
+ }
42
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,MAAM,KAAK,GAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IACvD,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC3C,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * bata api-keys — Manage API keys for headless / agent access.
3
+ *
4
+ * Subcommands:
5
+ * create [--name <n>] Generate a new key (shown ONCE).
6
+ * list List active (non-revoked) keys.
7
+ * revoke <id> [--yes] Revoke a key.
8
+ *
9
+ * Honors --json, --api-key / BATA_API_KEY, --api-url / BATA_API_URL.
10
+ */
11
+ export declare function handleApiKeys(args: string[]): Promise<void>;
@@ -0,0 +1,223 @@
1
+ /**
2
+ * bata api-keys — Manage API keys for headless / agent access.
3
+ *
4
+ * Subcommands:
5
+ * create [--name <n>] Generate a new key (shown ONCE).
6
+ * list List active (non-revoked) keys.
7
+ * revoke <id> [--yes] Revoke a key.
8
+ *
9
+ * Honors --json, --api-key / BATA_API_KEY, --api-url / BATA_API_URL.
10
+ */
11
+ import { api, apiError } from "../api.js";
12
+ import { requireToken, isJsonMode } from "../config.js";
13
+ import { colors, log, json, success, error, warn, spinner, table, kvList, heading } from "../utils/logger.js";
14
+ import { prompt, confirm } from "../utils/prompts.js";
15
+ function parseFlag(args, name) {
16
+ for (let i = 0; i < args.length; i++) {
17
+ if (args[i] === name && args[i + 1])
18
+ return args[i + 1];
19
+ if (args[i].startsWith(`${name}=`))
20
+ return args[i].slice(name.length + 1);
21
+ }
22
+ return undefined;
23
+ }
24
+ function positional(args) {
25
+ const out = [];
26
+ for (let i = 0; i < args.length; i++) {
27
+ const a = args[i];
28
+ if (a === "--name") {
29
+ i++; // skip value
30
+ continue;
31
+ }
32
+ if (a.startsWith("--"))
33
+ continue;
34
+ out.push(a);
35
+ }
36
+ return out;
37
+ }
38
+ function formatDate(iso) {
39
+ if (!iso)
40
+ return "-";
41
+ const d = new Date(iso);
42
+ if (isNaN(d.getTime()))
43
+ return "-";
44
+ return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
45
+ }
46
+ async function create(args) {
47
+ const token = requireToken();
48
+ const jsonMode = isJsonMode();
49
+ let name = parseFlag(args, "--name");
50
+ if (!name) {
51
+ if (jsonMode || !process.stdin.isTTY) {
52
+ // Headless: default a sensible name rather than block on a prompt.
53
+ name = `cli-${new Date().toISOString().slice(0, 10)}`;
54
+ }
55
+ else {
56
+ name = await prompt("Key name", `cli-${new Date().toISOString().slice(0, 10)}`);
57
+ }
58
+ }
59
+ const s = jsonMode ? null : spinner("Creating API key");
60
+ const res = await api.post("/v1/api-keys", { name }, token);
61
+ s?.stop();
62
+ if (!res.ok) {
63
+ if (jsonMode) {
64
+ json({ error: apiError(res, "Failed to create API key") });
65
+ }
66
+ else {
67
+ error(apiError(res, "Failed to create API key"));
68
+ }
69
+ process.exit(1);
70
+ }
71
+ const k = res.data;
72
+ if (jsonMode) {
73
+ json({
74
+ id: k.id,
75
+ name: k.name,
76
+ key: k.key,
77
+ prefix: k.prefix,
78
+ scopes: k.scopes,
79
+ max_lifetime_days: k.max_lifetime_days,
80
+ expires_at: k.expires_at,
81
+ created_at: k.created_at,
82
+ });
83
+ return;
84
+ }
85
+ heading("API key created");
86
+ kvList([
87
+ ["ID", colors.dim(k.id)],
88
+ ["Name", k.name],
89
+ ["Expires", formatDate(k.expires_at)],
90
+ ]);
91
+ log();
92
+ warn(colors.bold("Save this key now — it will NOT be shown again:"));
93
+ log();
94
+ log(` ${colors.green(k.key)}`);
95
+ log();
96
+ log(` ${colors.dim("Use it headless with:")} ${colors.cyan(`BATA_API_KEY=${k.prefix}... bata status`)}`);
97
+ log();
98
+ }
99
+ async function list(args) {
100
+ void args;
101
+ const token = requireToken();
102
+ const jsonMode = isJsonMode();
103
+ const s = jsonMode ? null : spinner("Fetching API keys");
104
+ const res = await api.get("/v1/api-keys", token);
105
+ s?.stop();
106
+ if (!res.ok) {
107
+ if (jsonMode) {
108
+ json({ error: apiError(res, "Failed to list API keys") });
109
+ }
110
+ else {
111
+ error(apiError(res, "Failed to list API keys"));
112
+ }
113
+ process.exit(1);
114
+ }
115
+ const keys = Array.isArray(res.data) ? res.data : [];
116
+ if (jsonMode) {
117
+ json(keys.map((k) => ({
118
+ id: k.id,
119
+ name: k.name,
120
+ prefix: k.keyPrefix,
121
+ scopes: k.scopes,
122
+ expires_at: k.expiresAt,
123
+ last_used_at: k.lastUsedAt,
124
+ created_at: k.createdAt,
125
+ })));
126
+ return;
127
+ }
128
+ heading("API Keys");
129
+ if (keys.length === 0) {
130
+ log(` ${colors.dim("No active API keys.")} Run ${colors.cyan("bata api-keys create")} to make one.`);
131
+ log();
132
+ return;
133
+ }
134
+ table(["ID", "NAME", "PREFIX", "LAST USED", "EXPIRES"], keys.map((k) => [
135
+ k.id,
136
+ k.name,
137
+ k.keyPrefix,
138
+ formatDate(k.lastUsedAt),
139
+ formatDate(k.expiresAt),
140
+ ]));
141
+ log();
142
+ log(` ${colors.dim(`${keys.length} active key(s)`)}`);
143
+ log();
144
+ }
145
+ async function revoke(args) {
146
+ const token = requireToken();
147
+ const jsonMode = isJsonMode();
148
+ const skipConfirm = args.includes("--yes") || args.includes("-y");
149
+ const id = positional(args)[0];
150
+ if (!id) {
151
+ const msg = "API key ID is required. Usage: bata api-keys revoke <id> [--yes]";
152
+ if (jsonMode)
153
+ json({ error: msg });
154
+ else
155
+ error(msg);
156
+ process.exit(1);
157
+ }
158
+ if (!skipConfirm && !jsonMode && process.stdin.isTTY) {
159
+ const ok = await confirm(`Revoke API key ${colors.cyan(id)}? This cannot be undone.`, false);
160
+ if (!ok) {
161
+ log(" Aborted.");
162
+ return;
163
+ }
164
+ }
165
+ const s = jsonMode ? null : spinner("Revoking API key");
166
+ const res = await api.del(`/v1/api-keys/${id}`, token);
167
+ s?.stop();
168
+ if (!res.ok) {
169
+ if (jsonMode)
170
+ json({ error: apiError(res, "Failed to revoke API key") });
171
+ else
172
+ error(apiError(res, "Failed to revoke API key"));
173
+ process.exit(1);
174
+ }
175
+ if (jsonMode) {
176
+ json({ id, revoked: true });
177
+ return;
178
+ }
179
+ log();
180
+ success(`API key ${colors.cyan(id)} revoked.`);
181
+ log();
182
+ }
183
+ function printHelp() {
184
+ log();
185
+ log(` ${colors.bold("bata api-keys")} ${colors.dim("— manage API keys for headless / agent access")}`);
186
+ log();
187
+ log(` ${colors.bold("Subcommands")}`);
188
+ log(` ${colors.cyan("create")} ${colors.dim("[--name <n>] [--json]")} Generate a new key (shown once)`);
189
+ log(` ${colors.cyan("list")} ${colors.dim("[--json]")} List active keys`);
190
+ log(` ${colors.cyan("revoke <id>")} ${colors.dim("[--yes]")} Revoke a key`);
191
+ log();
192
+ log(` ${colors.bold("Auth")} ${colors.dim("(any subcommand)")}`);
193
+ log(` ${colors.dim("--api-key <key>")} Credential (else BATA_API_KEY, else saved login)`);
194
+ log(` ${colors.dim("--api-url <url>")} API base URL (else BATA_API_URL, else config/default)`);
195
+ log();
196
+ log(` ${colors.bold("Examples")}`);
197
+ log(` ${colors.cyan("bata api-keys create --name ci --json")}`);
198
+ log(` ${colors.cyan("BATA_API_KEY=bata_xxx bata api-keys list --json")}`);
199
+ log(` ${colors.cyan("bata api-keys revoke akey_123 --yes")}`);
200
+ log();
201
+ }
202
+ export async function handleApiKeys(args) {
203
+ const sub = args[0];
204
+ const rest = args.slice(1);
205
+ if (sub === "--help" || sub === "-h" || sub === "help") {
206
+ printHelp();
207
+ return;
208
+ }
209
+ switch (sub) {
210
+ case "create":
211
+ return create(rest);
212
+ case "list":
213
+ case undefined:
214
+ return list(rest);
215
+ case "revoke":
216
+ return revoke(rest);
217
+ default:
218
+ error(`Unknown subcommand: api-keys ${sub}`);
219
+ log(` ${colors.dim("Available:")} create, list, revoke`);
220
+ process.exit(1);
221
+ }
222
+ }
223
+ //# sourceMappingURL=api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../src/commands/api-keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function login(): Promise<void>;
2
+ export declare function logout(): Promise<void>;
3
+ export declare function whoami(): Promise<void>;
@@ -0,0 +1,133 @@
1
+ import { api, apiError } from "../api.js";
2
+ import { saveConfig, clearConfig, requireToken, loadConfig, isJsonMode } from "../config.js";
3
+ import { colors, log, json, success, error, spinner, kvList, heading } from "../utils/logger.js";
4
+ import { prompt, promptSecret } from "../utils/prompts.js";
5
+ export async function login() {
6
+ heading("Log in to BataDB");
7
+ const email = await prompt("Email");
8
+ if (!email) {
9
+ error("Email is required.");
10
+ process.exit(1);
11
+ }
12
+ const password = await promptSecret("Password");
13
+ if (!password) {
14
+ error("Password is required.");
15
+ process.exit(1);
16
+ }
17
+ const s = spinner("Authenticating");
18
+ const res = await api.post("/auth/login", { email, password });
19
+ if (!res.ok) {
20
+ s.stop();
21
+ error(apiError(res, "Login failed"));
22
+ process.exit(1);
23
+ }
24
+ const { token, user, teams } = res.data;
25
+ // Save token and default team
26
+ const config = { token };
27
+ if (teams && teams.length > 0) {
28
+ config.defaultTeam = teams[0].id;
29
+ }
30
+ saveConfig(config);
31
+ s.stop();
32
+ log();
33
+ success("Logged in successfully");
34
+ log();
35
+ kvList([
36
+ ["User", colors.white(user.name || user.email)],
37
+ ["Email", user.email],
38
+ ...(teams && teams.length > 0
39
+ ? [["Team", colors.cyan(teams[0].name)]]
40
+ : []),
41
+ ]);
42
+ log();
43
+ }
44
+ export async function logout() {
45
+ clearConfig();
46
+ log();
47
+ success("Logged out. Token cleared from ~/.batarc");
48
+ log();
49
+ }
50
+ export async function whoami() {
51
+ const token = requireToken();
52
+ const jsonMode = isJsonMode();
53
+ const s = jsonMode ? null : spinner("Fetching user info");
54
+ // /auth/me only accepts a JWT session token. When authenticating with an
55
+ // API key (the agent/headless path), fall back to /v1/teams which the auth
56
+ // middleware accepts with `Bearer bata_...`.
57
+ const meRes = await api.get("/auth/me", token);
58
+ if (meRes.ok) {
59
+ s?.stop();
60
+ const { user, teams } = meRes.data;
61
+ if (jsonMode) {
62
+ json({
63
+ auth: "session",
64
+ user: { id: user.id, email: user.email, name: user.name },
65
+ teams: teams ?? [],
66
+ default_project: loadConfig().defaultProject ?? null,
67
+ });
68
+ return;
69
+ }
70
+ heading("Current User");
71
+ kvList([
72
+ ["Name", colors.white(user.name || "-")],
73
+ ["Email", user.email],
74
+ ["User ID", colors.dim(user.id)],
75
+ ]);
76
+ if (teams && teams.length > 0) {
77
+ log();
78
+ log(` ${colors.dim("Teams")}`);
79
+ for (const team of teams) {
80
+ log(` ${colors.cyan(">")} ${team.name} ${colors.dim(`(${team.slug})`)}`);
81
+ }
82
+ }
83
+ const config = loadConfig();
84
+ if (config.defaultProject) {
85
+ log();
86
+ log(` ${colors.dim("Default project:")} ${config.defaultProject}`);
87
+ }
88
+ log();
89
+ return;
90
+ }
91
+ // Fall back to API-key identity via /v1/teams.
92
+ const teamsRes = await api.get("/v1/teams", token);
93
+ s?.stop();
94
+ if (!teamsRes.ok) {
95
+ if (jsonMode) {
96
+ json({ error: apiError(teamsRes, "Could not fetch identity") });
97
+ }
98
+ else {
99
+ error(apiError(teamsRes, "Could not fetch identity"));
100
+ }
101
+ process.exit(1);
102
+ }
103
+ const teams = Array.isArray(teamsRes.data) ? teamsRes.data : [];
104
+ if (jsonMode) {
105
+ json({
106
+ auth: "api_key",
107
+ user: null,
108
+ teams,
109
+ default_project: loadConfig().defaultProject ?? null,
110
+ });
111
+ return;
112
+ }
113
+ heading("Current Identity");
114
+ log(` ${colors.dim("Authenticated via API key.")}`);
115
+ log();
116
+ if (teams.length > 0) {
117
+ log(` ${colors.dim("Teams")}`);
118
+ for (const team of teams) {
119
+ const role = team.role ? colors.dim(` [${team.role}]`) : "";
120
+ log(` ${colors.cyan(">")} ${team.name} ${colors.dim(`(${team.slug})`)}${role}`);
121
+ }
122
+ }
123
+ else {
124
+ log(` ${colors.dim("No teams found for this key.")}`);
125
+ }
126
+ const config = loadConfig();
127
+ if (config.defaultProject) {
128
+ log();
129
+ log(` ${colors.dim("Default project:")} ${config.defaultProject}`);
130
+ }
131
+ log();
132
+ }
133
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * bata connect <project-name> — Quick psql connection.
3
+ *
4
+ * Fetches the connection string from the API, auto-wakes suspended computes,
5
+ * and execs psql with the connection string.
6
+ */
7
+ export declare function connect(args: string[]): Promise<void>;