@jsondb-cloud/cli 1.0.13 → 1.0.15
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/README.md +5 -1
- package/dist/commands/documents.js +4 -2
- package/dist/commands/keys.js +3 -2
- package/dist/commands/pull.js +1 -1
- package/dist/index.js +9 -5
- package/dist/lib/client.d.ts +3 -0
- package/dist/lib/client.js +22 -32
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -5,8 +5,12 @@ The official CLI tool for [jsondb.cloud](https://jsondb.cloud) — a hosted JSON
|
|
|
5
5
|
[](https://www.npmjs.com/package/@jsondb-cloud/cli)
|
|
6
6
|
[](https://www.npmjs.com/package/@jsondb-cloud/cli)
|
|
7
7
|
[](https://github.com/JsonDBCloud/cli/actions)
|
|
8
|
-
[](https://www.typescriptlang.org/)
|
|
9
9
|
[](https://nodejs.org)
|
|
10
|
+
[](https://bundlephobia.com/package/@jsondb-cloud/cli)
|
|
11
|
+
[](https://github.com/JsonDBCloud/cli)
|
|
12
|
+
[](https://github.com/JsonDBCloud/cli)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
14
|
|
|
11
15
|
## Install
|
|
12
16
|
|
|
@@ -134,7 +134,8 @@ async function listCollectionsCommand(client) {
|
|
|
134
134
|
// List documents and extract unique collection names
|
|
135
135
|
const res = await client.get("?limit=100");
|
|
136
136
|
if (!res.ok) {
|
|
137
|
-
|
|
137
|
+
const data = await res.json().catch(() => ({}));
|
|
138
|
+
(0, output_1.error)(data.error?.message || `Failed to list collections: ${res.status}`);
|
|
138
139
|
process.exit(1);
|
|
139
140
|
}
|
|
140
141
|
const data = await res.json();
|
|
@@ -151,7 +152,8 @@ async function listDocumentsCommand(collection, client, options) {
|
|
|
151
152
|
const limit = options.limit || "20";
|
|
152
153
|
const res = await client.get(`${collection}?limit=${limit}`);
|
|
153
154
|
if (!res.ok) {
|
|
154
|
-
|
|
155
|
+
const data = await res.json().catch(() => ({}));
|
|
156
|
+
(0, output_1.error)(data.error?.message || `Failed to list documents: ${res.status}`);
|
|
155
157
|
process.exit(1);
|
|
156
158
|
}
|
|
157
159
|
const data = await res.json();
|
package/dist/commands/keys.js
CHANGED
|
@@ -7,7 +7,8 @@ const output_1 = require("../lib/output");
|
|
|
7
7
|
async function listKeysCommand(client) {
|
|
8
8
|
const res = await client.rawGet("/api/keys");
|
|
9
9
|
if (!res.ok) {
|
|
10
|
-
|
|
10
|
+
const errData = await res.json().catch(() => ({}));
|
|
11
|
+
(0, output_1.error)(errData.error?.message || `Failed to list API keys: ${res.status}`);
|
|
11
12
|
process.exit(1);
|
|
12
13
|
}
|
|
13
14
|
const data = await res.json();
|
|
@@ -28,7 +29,7 @@ async function listKeysCommand(client) {
|
|
|
28
29
|
(0, output_1.printTable)(headers, rows);
|
|
29
30
|
}
|
|
30
31
|
async function createKeyCommand(client, options) {
|
|
31
|
-
|
|
32
|
+
await client.rawGet("/api/keys"); // POST via the dashboard API
|
|
32
33
|
// Actually we need to post to create. Use a different approach
|
|
33
34
|
const body = {
|
|
34
35
|
name: options.name || "CLI-generated key",
|
package/dist/commands/pull.js
CHANGED
|
@@ -61,7 +61,7 @@ async function pullCommand(collection, client, options) {
|
|
|
61
61
|
if (options.out) {
|
|
62
62
|
fs.writeFileSync(options.out, content, "utf-8");
|
|
63
63
|
// Count documents
|
|
64
|
-
let count
|
|
64
|
+
let count;
|
|
65
65
|
if (format === "json") {
|
|
66
66
|
try {
|
|
67
67
|
count = JSON.parse(content).length;
|
package/dist/index.js
CHANGED
|
@@ -19,9 +19,10 @@ program
|
|
|
19
19
|
.description("The jsondb.cloud CLI — manage your JSON database from the terminal")
|
|
20
20
|
.version("1.0.0")
|
|
21
21
|
.option("--api-key <key>", "Use a specific API key")
|
|
22
|
-
.option("--project <ns>",
|
|
22
|
+
.option("--project <ns>", 'Target project (default: "default")')
|
|
23
23
|
.option("--base-url <url>", "API base URL")
|
|
24
|
-
.option("--format <fmt>", "Output format: json, raw, ndjson, table")
|
|
24
|
+
.option("--format <fmt>", "Output format: json, raw, ndjson, table")
|
|
25
|
+
.option("--verbose", "Show debug info (request URLs, status codes)");
|
|
25
26
|
function getClient() {
|
|
26
27
|
const opts = program.opts();
|
|
27
28
|
const config = (0, config_1.loadConfig)();
|
|
@@ -30,11 +31,14 @@ function getClient() {
|
|
|
30
31
|
(0, output_1.error)("Not authenticated", "Run `jsondb login` to authenticate, or pass --api-key");
|
|
31
32
|
process.exit(1);
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
const client = new client_1.ApiClient({
|
|
34
35
|
apiKey,
|
|
35
36
|
project: opts.project || config?.project || "default",
|
|
36
37
|
baseUrl: opts.baseUrl || config?.baseUrl || "https://api.jsondb.cloud",
|
|
37
38
|
});
|
|
39
|
+
if (opts.verbose)
|
|
40
|
+
client.verbose = true;
|
|
41
|
+
return client;
|
|
38
42
|
}
|
|
39
43
|
// ─── Auth commands ───
|
|
40
44
|
program
|
|
@@ -149,14 +153,14 @@ keys
|
|
|
149
153
|
.option("--name <name>", "Key name")
|
|
150
154
|
.option("--scope <scope>", "Scope: read-only, read-write", "read-write")
|
|
151
155
|
.option("--project <ns>", "Target project")
|
|
152
|
-
.action(async (
|
|
156
|
+
.action(async (_opts) => {
|
|
153
157
|
(0, output_1.error)("Key creation requires dashboard authentication. Use the web dashboard at https://jsondb.cloud/dashboard/api-keys");
|
|
154
158
|
process.exit(1);
|
|
155
159
|
});
|
|
156
160
|
keys
|
|
157
161
|
.command("revoke <id>")
|
|
158
162
|
.description("Revoke an API key")
|
|
159
|
-
.action(async (
|
|
163
|
+
.action(async (_id) => {
|
|
160
164
|
(0, output_1.error)("Key revocation requires dashboard authentication. Use the web dashboard at https://jsondb.cloud/dashboard/api-keys");
|
|
161
165
|
process.exit(1);
|
|
162
166
|
});
|
package/dist/lib/client.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { CliConfig } from "./config";
|
|
2
2
|
export declare class ApiClient {
|
|
3
3
|
private config;
|
|
4
|
+
verbose: boolean;
|
|
4
5
|
constructor(config: CliConfig);
|
|
6
|
+
private log;
|
|
5
7
|
private url;
|
|
6
8
|
private headers;
|
|
9
|
+
private request;
|
|
7
10
|
get(path: string, accept?: string): Promise<Response>;
|
|
8
11
|
post(path: string, body?: unknown, extraHeaders?: Record<string, string>): Promise<Response>;
|
|
9
12
|
postRaw(path: string, body: string, contentType: string): Promise<Response>;
|
package/dist/lib/client.js
CHANGED
|
@@ -3,9 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ApiClient = void 0;
|
|
4
4
|
class ApiClient {
|
|
5
5
|
config;
|
|
6
|
+
verbose = false;
|
|
6
7
|
constructor(config) {
|
|
7
8
|
this.config = config;
|
|
8
9
|
}
|
|
10
|
+
log(msg) {
|
|
11
|
+
if (this.verbose) {
|
|
12
|
+
console.error(`\x1b[2m[debug] ${msg}\x1b[0m`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
9
15
|
url(path) {
|
|
10
16
|
const base = this.config.baseUrl.replace(/\/$/, "");
|
|
11
17
|
return `${base}/${this.config.project}/${path}`;
|
|
@@ -17,54 +23,38 @@ class ApiClient {
|
|
|
17
23
|
...extra,
|
|
18
24
|
};
|
|
19
25
|
}
|
|
26
|
+
async request(method, url, headers, body) {
|
|
27
|
+
this.log(`${method} ${url}`);
|
|
28
|
+
const res = await fetch(url, { method, headers, body });
|
|
29
|
+
this.log(`${res.status} ${res.statusText}`);
|
|
30
|
+
return res;
|
|
31
|
+
}
|
|
20
32
|
async get(path, accept) {
|
|
21
33
|
const headers = this.headers(accept ? { Accept: accept } : undefined);
|
|
22
|
-
return
|
|
34
|
+
return this.request("GET", this.url(path), headers);
|
|
23
35
|
}
|
|
24
36
|
async post(path, body, extraHeaders) {
|
|
25
|
-
return
|
|
26
|
-
method: "POST",
|
|
27
|
-
headers: this.headers(extraHeaders),
|
|
28
|
-
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
29
|
-
});
|
|
37
|
+
return this.request("POST", this.url(path), this.headers(extraHeaders), body !== undefined ? JSON.stringify(body) : undefined);
|
|
30
38
|
}
|
|
31
39
|
async postRaw(path, body, contentType) {
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"Content-Type": contentType,
|
|
37
|
-
},
|
|
38
|
-
body,
|
|
39
|
-
});
|
|
40
|
+
return this.request("POST", this.url(path), {
|
|
41
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
42
|
+
"Content-Type": contentType,
|
|
43
|
+
}, body);
|
|
40
44
|
}
|
|
41
45
|
async put(path, body) {
|
|
42
|
-
return
|
|
43
|
-
method: "PUT",
|
|
44
|
-
headers: this.headers(),
|
|
45
|
-
body: JSON.stringify(body),
|
|
46
|
-
});
|
|
46
|
+
return this.request("PUT", this.url(path), this.headers(), JSON.stringify(body));
|
|
47
47
|
}
|
|
48
48
|
async patch(path, body, contentType) {
|
|
49
|
-
return
|
|
50
|
-
method: "PATCH",
|
|
51
|
-
headers: this.headers(contentType ? { "Content-Type": contentType } : undefined),
|
|
52
|
-
body: JSON.stringify(body),
|
|
53
|
-
});
|
|
49
|
+
return this.request("PATCH", this.url(path), this.headers(contentType ? { "Content-Type": contentType } : undefined), JSON.stringify(body));
|
|
54
50
|
}
|
|
55
51
|
async delete(path) {
|
|
56
|
-
return
|
|
57
|
-
method: "DELETE",
|
|
58
|
-
headers: this.headers(),
|
|
59
|
-
});
|
|
52
|
+
return this.request("DELETE", this.url(path), this.headers());
|
|
60
53
|
}
|
|
61
54
|
/** Raw API call without project prefix */
|
|
62
55
|
async rawGet(fullPath) {
|
|
63
56
|
const base = this.config.baseUrl.replace(/\/$/, "");
|
|
64
|
-
return
|
|
65
|
-
method: "GET",
|
|
66
|
-
headers: this.headers(),
|
|
67
|
-
});
|
|
57
|
+
return this.request("GET", `${base}${fullPath}`, this.headers());
|
|
68
58
|
}
|
|
69
59
|
}
|
|
70
60
|
exports.ApiClient = ApiClient;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsondb-cloud/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "CLI tool for jsondb.cloud — push, pull, manage your JSON database from the terminal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,14 +15,24 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc",
|
|
17
17
|
"dev": "tsc --watch",
|
|
18
|
-
"typecheck": "tsc --noEmit"
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"lint": "eslint src/",
|
|
20
|
+
"lint:fix": "eslint src/ --fix",
|
|
21
|
+
"format": "prettier --write 'src/**/*.ts'",
|
|
22
|
+
"format:check": "prettier --check 'src/**/*.ts'",
|
|
23
|
+
"test": "vitest run"
|
|
19
24
|
},
|
|
20
25
|
"dependencies": {
|
|
21
26
|
"commander": "^13.0.0"
|
|
22
27
|
},
|
|
23
28
|
"devDependencies": {
|
|
29
|
+
"@eslint/js": "^10.0.1",
|
|
30
|
+
"@types/node": "^20.0.0",
|
|
31
|
+
"eslint": "^10.0.2",
|
|
32
|
+
"prettier": "^3.8.1",
|
|
24
33
|
"typescript": "^5.4.0",
|
|
25
|
-
"
|
|
34
|
+
"typescript-eslint": "^8.56.1",
|
|
35
|
+
"vitest": "^4.0.18"
|
|
26
36
|
},
|
|
27
37
|
"keywords": [
|
|
28
38
|
"jsondb",
|