@digitalpresence/cliclaw 0.4.3 → 0.5.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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/__tests__/vercel.integration.test.d.ts +2 -0
- package/dist/__tests__/vercel.integration.test.d.ts.map +1 -0
- package/dist/__tests__/vercel.integration.test.js +111 -0
- package/dist/__tests__/vercel.integration.test.js.map +1 -0
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/vercel.d.ts +6 -0
- package/dist/commands/vercel.d.ts.map +1 -0
- package/dist/commands/vercel.js +200 -0
- package/dist/commands/vercel.js.map +1 -0
- package/dist/vercel/api.d.ts +5 -0
- package/dist/vercel/api.d.ts.map +1 -0
- package/dist/vercel/api.js +68 -0
- package/dist/vercel/api.js.map +1 -0
- package/dist/vercel/handlers.d.ts +23 -0
- package/dist/vercel/handlers.d.ts.map +1 -0
- package/dist/vercel/handlers.js +253 -0
- package/dist/vercel/handlers.js.map +1 -0
- package/package.json +11 -11
- package/src/__tests__/vercel.integration.test.ts +164 -0
- package/src/cli.ts +3 -1
- package/src/commands/vercel.ts +236 -0
- package/src/vercel/api.ts +89 -0
- package/src/vercel/handlers.ts +369 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { getToken, vercelFetch, vercelFetchPaginated } from "./api.js";
|
|
2
|
+
import { outputJson, outputError } from "../lib/output.js";
|
|
3
|
+
// --- Account ---
|
|
4
|
+
export async function handleWhoami(tokenStore, account) {
|
|
5
|
+
const token = getToken(tokenStore, account);
|
|
6
|
+
try {
|
|
7
|
+
const user = await vercelFetch(token, "/v2/user");
|
|
8
|
+
outputJson(user);
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
outputError("whoami_failed", err instanceof Error ? err.message : String(err));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// --- Projects ---
|
|
15
|
+
export async function handleProjects(tokenStore, account, maxResults) {
|
|
16
|
+
const token = getToken(tokenStore, account);
|
|
17
|
+
try {
|
|
18
|
+
const projects = await vercelFetchPaginated(token, "/v9/projects", "projects", maxResults);
|
|
19
|
+
outputJson(projects);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
outputError("projects_failed", err instanceof Error ? err.message : String(err));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function handleProject(tokenStore, account, projectId) {
|
|
26
|
+
const token = getToken(tokenStore, account);
|
|
27
|
+
try {
|
|
28
|
+
const project = await vercelFetch(token, `/v9/projects/${projectId}`);
|
|
29
|
+
outputJson(project);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
outputError("project_get_failed", err instanceof Error ? err.message : String(err));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function handleProjectCreate(tokenStore, account, name, framework, gitRepo) {
|
|
36
|
+
const token = getToken(tokenStore, account);
|
|
37
|
+
try {
|
|
38
|
+
const payload = { name };
|
|
39
|
+
if (framework)
|
|
40
|
+
payload.framework = framework;
|
|
41
|
+
if (gitRepo)
|
|
42
|
+
payload.gitRepository = { type: "github", repo: gitRepo };
|
|
43
|
+
const project = await vercelFetch(token, "/v9/projects", {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { "Content-Type": "application/json" },
|
|
46
|
+
body: JSON.stringify(payload),
|
|
47
|
+
});
|
|
48
|
+
outputJson(project);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
outputError("project_create_failed", err instanceof Error ? err.message : String(err));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function handleProjectDelete(tokenStore, account, projectId) {
|
|
55
|
+
const token = getToken(tokenStore, account);
|
|
56
|
+
try {
|
|
57
|
+
const result = await vercelFetch(token, `/v9/projects/${projectId}`, { method: "DELETE" });
|
|
58
|
+
outputJson(result);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
outputError("project_delete_failed", err instanceof Error ? err.message : String(err));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// --- Deployments ---
|
|
65
|
+
export async function handleDeployments(tokenStore, account, projectId, maxResults) {
|
|
66
|
+
const token = getToken(tokenStore, account);
|
|
67
|
+
try {
|
|
68
|
+
const path = projectId ? `/v6/deployments?projectId=${projectId}` : "/v6/deployments";
|
|
69
|
+
const deployments = await vercelFetchPaginated(token, path, "deployments", maxResults ?? 20);
|
|
70
|
+
outputJson(deployments);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
outputError("deployments_failed", err instanceof Error ? err.message : String(err));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export async function handleDeployment(tokenStore, account, deploymentId) {
|
|
77
|
+
const token = getToken(tokenStore, account);
|
|
78
|
+
try {
|
|
79
|
+
const deployment = await vercelFetch(token, `/v13/deployments/${deploymentId}`);
|
|
80
|
+
outputJson(deployment);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
outputError("deployment_get_failed", err instanceof Error ? err.message : String(err));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function handleRedeploy(tokenStore, account, deploymentId, target) {
|
|
87
|
+
const token = getToken(tokenStore, account);
|
|
88
|
+
try {
|
|
89
|
+
const payload = { deploymentId };
|
|
90
|
+
if (target)
|
|
91
|
+
payload.target = target;
|
|
92
|
+
const result = await vercelFetch(token, "/v13/deployments", {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: { "Content-Type": "application/json" },
|
|
95
|
+
body: JSON.stringify(payload),
|
|
96
|
+
});
|
|
97
|
+
outputJson(result);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
outputError("redeploy_failed", err instanceof Error ? err.message : String(err));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export async function handlePromote(tokenStore, account, projectId, deploymentId) {
|
|
104
|
+
const token = getToken(tokenStore, account);
|
|
105
|
+
try {
|
|
106
|
+
const result = await vercelFetch(token, `/v10/projects/${projectId}/promote/${deploymentId}`, { method: "POST" });
|
|
107
|
+
outputJson(result);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
outputError("promote_failed", err instanceof Error ? err.message : String(err));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export async function handleDeploymentDelete(tokenStore, account, deploymentId) {
|
|
114
|
+
const token = getToken(tokenStore, account);
|
|
115
|
+
try {
|
|
116
|
+
const result = await vercelFetch(token, `/v13/deployments/${deploymentId}`, {
|
|
117
|
+
method: "DELETE",
|
|
118
|
+
});
|
|
119
|
+
outputJson(result);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
outputError("deployment_delete_failed", err instanceof Error ? err.message : String(err));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export async function handleBuildLogs(tokenStore, account, deploymentId) {
|
|
126
|
+
const token = getToken(tokenStore, account);
|
|
127
|
+
try {
|
|
128
|
+
const logs = await vercelFetch(token, `/v2/deployments/${deploymentId}/events`);
|
|
129
|
+
outputJson(logs);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
outputError("build_logs_failed", err instanceof Error ? err.message : String(err));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// --- Domains ---
|
|
136
|
+
export async function handleDomains(tokenStore, account, maxResults) {
|
|
137
|
+
const token = getToken(tokenStore, account);
|
|
138
|
+
try {
|
|
139
|
+
const domains = await vercelFetchPaginated(token, "/v5/domains", "domains", maxResults ?? 20);
|
|
140
|
+
outputJson(domains);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
outputError("domains_failed", err instanceof Error ? err.message : String(err));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export async function handleDomain(tokenStore, account, domain) {
|
|
147
|
+
const token = getToken(tokenStore, account);
|
|
148
|
+
try {
|
|
149
|
+
const data = await vercelFetch(token, `/v5/domains/${domain}`);
|
|
150
|
+
outputJson(data);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
outputError("domain_get_failed", err instanceof Error ? err.message : String(err));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export async function handleDomainAdd(tokenStore, account, projectId, domain) {
|
|
157
|
+
const token = getToken(tokenStore, account);
|
|
158
|
+
try {
|
|
159
|
+
const result = await vercelFetch(token, `/v9/projects/${projectId}/domains`, {
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers: { "Content-Type": "application/json" },
|
|
162
|
+
body: JSON.stringify({ name: domain }),
|
|
163
|
+
});
|
|
164
|
+
outputJson(result);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
outputError("domain_add_failed", err instanceof Error ? err.message : String(err));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
export async function handleDomainRemove(tokenStore, account, projectId, domain) {
|
|
171
|
+
const token = getToken(tokenStore, account);
|
|
172
|
+
try {
|
|
173
|
+
const result = await vercelFetch(token, `/v9/projects/${projectId}/domains/${domain}`, {
|
|
174
|
+
method: "DELETE",
|
|
175
|
+
});
|
|
176
|
+
outputJson(result);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
outputError("domain_remove_failed", err instanceof Error ? err.message : String(err));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export async function handleDomainVerify(tokenStore, account, projectId, domain) {
|
|
183
|
+
const token = getToken(tokenStore, account);
|
|
184
|
+
try {
|
|
185
|
+
const result = await vercelFetch(token, `/v9/projects/${projectId}/domains/${domain}/verify`, { method: "POST" });
|
|
186
|
+
outputJson(result);
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
outputError("domain_verify_failed", err instanceof Error ? err.message : String(err));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// --- Environment Variables ---
|
|
193
|
+
export async function handleEnvs(tokenStore, account, projectId) {
|
|
194
|
+
const token = getToken(tokenStore, account);
|
|
195
|
+
try {
|
|
196
|
+
const data = await vercelFetch(token, `/v10/projects/${projectId}/env`);
|
|
197
|
+
outputJson(data.envs);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
outputError("envs_failed", err instanceof Error ? err.message : String(err));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
export async function handleEnvGet(tokenStore, account, projectId, envId) {
|
|
204
|
+
const token = getToken(tokenStore, account);
|
|
205
|
+
try {
|
|
206
|
+
const env = await vercelFetch(token, `/v10/projects/${projectId}/env/${envId}`);
|
|
207
|
+
outputJson(env);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
outputError("env_get_failed", err instanceof Error ? err.message : String(err));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
export async function handleEnvCreate(tokenStore, account, projectId, key, value, target, type) {
|
|
214
|
+
const token = getToken(tokenStore, account);
|
|
215
|
+
try {
|
|
216
|
+
const env = await vercelFetch(token, `/v10/projects/${projectId}/env`, {
|
|
217
|
+
method: "POST",
|
|
218
|
+
headers: { "Content-Type": "application/json" },
|
|
219
|
+
body: JSON.stringify({ key, value, target, type: type || "encrypted" }),
|
|
220
|
+
});
|
|
221
|
+
outputJson(env);
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
outputError("env_create_failed", err instanceof Error ? err.message : String(err));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
export async function handleEnvUpdate(tokenStore, account, projectId, envId, value) {
|
|
228
|
+
const token = getToken(tokenStore, account);
|
|
229
|
+
try {
|
|
230
|
+
const env = await vercelFetch(token, `/v10/projects/${projectId}/env/${envId}`, {
|
|
231
|
+
method: "PATCH",
|
|
232
|
+
headers: { "Content-Type": "application/json" },
|
|
233
|
+
body: JSON.stringify({ value }),
|
|
234
|
+
});
|
|
235
|
+
outputJson(env);
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
outputError("env_update_failed", err instanceof Error ? err.message : String(err));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export async function handleEnvDelete(tokenStore, account, projectId, envId) {
|
|
242
|
+
const token = getToken(tokenStore, account);
|
|
243
|
+
try {
|
|
244
|
+
const result = await vercelFetch(token, `/v10/projects/${projectId}/env/${envId}`, {
|
|
245
|
+
method: "DELETE",
|
|
246
|
+
});
|
|
247
|
+
outputJson(result);
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
outputError("env_delete_failed", err instanceof Error ? err.message : String(err));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/vercel/handlers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitalpresence/cliclaw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cliclaw": "./dist/cli.js"
|
|
7
7
|
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsx src/cli.ts",
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"test:watch": "vitest"
|
|
14
|
+
},
|
|
8
15
|
"peerDependencies": {
|
|
9
16
|
"@anthropic-ai/claude-agent-sdk": ">=0.2.74"
|
|
10
17
|
},
|
|
11
18
|
"dependencies": {
|
|
19
|
+
"@digitalpresence/cliclaw-auth": "workspace:*",
|
|
12
20
|
"commander": "^13.0.0",
|
|
13
21
|
"google-auth-library": "^10.5.0",
|
|
14
22
|
"googleapis": "^144.0.0",
|
|
15
23
|
"mime-types": "^3.0.2",
|
|
16
24
|
"node-cron": "^4.2.1",
|
|
17
|
-
"open": "^10.1.0"
|
|
18
|
-
"@digitalpresence/cliclaw-auth": "0.4.1"
|
|
25
|
+
"open": "^10.1.0"
|
|
19
26
|
},
|
|
20
27
|
"devDependencies": {
|
|
21
28
|
"@types/mime-types": "^3.0.1",
|
|
@@ -24,12 +31,5 @@
|
|
|
24
31
|
"tsx": "^4.19.0",
|
|
25
32
|
"typescript": "^5.8.0",
|
|
26
33
|
"vitest": "^3.0.0"
|
|
27
|
-
},
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsc",
|
|
30
|
-
"dev": "tsx src/cli.ts",
|
|
31
|
-
"typecheck": "tsc --noEmit",
|
|
32
|
-
"test": "vitest run",
|
|
33
|
-
"test:watch": "vitest"
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { execFile } from "child_process";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { describe, it, expect, afterAll } from "vitest";
|
|
5
|
+
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const CLI = join(import.meta.dirname, "../../dist/cli.js");
|
|
8
|
+
|
|
9
|
+
interface CliResult {
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
exitCode: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function run(...args: string[]): Promise<CliResult> {
|
|
16
|
+
try {
|
|
17
|
+
const { stdout, stderr } = await execFileAsync("node", [CLI, ...args], {
|
|
18
|
+
timeout: 30000,
|
|
19
|
+
});
|
|
20
|
+
return { stdout, stderr, exitCode: 0 };
|
|
21
|
+
} catch (err: any) {
|
|
22
|
+
return {
|
|
23
|
+
stdout: err.stdout ?? "",
|
|
24
|
+
stderr: err.stderr ?? "",
|
|
25
|
+
exitCode: err.code ?? 1,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function parseJson(result: CliResult): any {
|
|
31
|
+
return JSON.parse(result.stdout);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe.sequential("Vercel CLI integration", () => {
|
|
35
|
+
const testProjectName = `cliclaw-test-${Date.now()}`;
|
|
36
|
+
let testProjectId: string;
|
|
37
|
+
let testEnvId: string;
|
|
38
|
+
|
|
39
|
+
afterAll(async () => {
|
|
40
|
+
if (testProjectId) {
|
|
41
|
+
await run("vercel", "project-delete", "--project", testProjectId);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("whoami — returns authenticated user info", async () => {
|
|
46
|
+
const result = await run("vercel", "whoami");
|
|
47
|
+
expect(result.exitCode).toBe(0);
|
|
48
|
+
|
|
49
|
+
const data = parseJson(result);
|
|
50
|
+
expect(data).toHaveProperty("user");
|
|
51
|
+
expect(data.user).toHaveProperty("email");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("projects — returns a list of projects", async () => {
|
|
55
|
+
const result = await run("vercel", "projects", "--max-results", "5");
|
|
56
|
+
expect(result.exitCode).toBe(0);
|
|
57
|
+
|
|
58
|
+
const data = parseJson(result);
|
|
59
|
+
expect(Array.isArray(data)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("project-create — creates a test project", async () => {
|
|
63
|
+
const result = await run("vercel", "project-create", "--name", testProjectName);
|
|
64
|
+
expect(result.exitCode).toBe(0);
|
|
65
|
+
|
|
66
|
+
const data = parseJson(result);
|
|
67
|
+
expect(data).toHaveProperty("id");
|
|
68
|
+
expect(data.name).toBe(testProjectName);
|
|
69
|
+
|
|
70
|
+
testProjectId = data.id;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("project — gets the test project by ID", async () => {
|
|
74
|
+
const result = await run("vercel", "project", "--project", testProjectId);
|
|
75
|
+
expect(result.exitCode).toBe(0);
|
|
76
|
+
|
|
77
|
+
const data = parseJson(result);
|
|
78
|
+
expect(data.id).toBe(testProjectId);
|
|
79
|
+
expect(data.name).toBe(testProjectName);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("env-create — creates an env var on the test project", async () => {
|
|
83
|
+
const result = await run(
|
|
84
|
+
"vercel", "env-create",
|
|
85
|
+
"--project", testProjectId,
|
|
86
|
+
"--key", "CLICLAW_TEST_VAR",
|
|
87
|
+
"--value", "test-value",
|
|
88
|
+
"--target", "development,preview",
|
|
89
|
+
"--type", "plain",
|
|
90
|
+
);
|
|
91
|
+
expect(result.exitCode).toBe(0);
|
|
92
|
+
|
|
93
|
+
const data = parseJson(result);
|
|
94
|
+
expect(data).toHaveProperty("id");
|
|
95
|
+
testEnvId = data.id;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("envs — lists env vars for the test project", async () => {
|
|
99
|
+
const result = await run("vercel", "envs", "--project", testProjectId);
|
|
100
|
+
expect(result.exitCode).toBe(0);
|
|
101
|
+
|
|
102
|
+
const data = parseJson(result);
|
|
103
|
+
expect(Array.isArray(data)).toBe(true);
|
|
104
|
+
|
|
105
|
+
const ids = data.map((e: any) => e.id);
|
|
106
|
+
expect(ids).toContain(testEnvId);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("env — gets the created env var", async () => {
|
|
110
|
+
const result = await run(
|
|
111
|
+
"vercel", "env",
|
|
112
|
+
"--project", testProjectId,
|
|
113
|
+
"--env-id", testEnvId,
|
|
114
|
+
);
|
|
115
|
+
expect(result.exitCode).toBe(0);
|
|
116
|
+
|
|
117
|
+
const data = parseJson(result);
|
|
118
|
+
expect(data.key).toBe("CLICLAW_TEST_VAR");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("env-update — updates the env var value", async () => {
|
|
122
|
+
const result = await run(
|
|
123
|
+
"vercel", "env-update",
|
|
124
|
+
"--project", testProjectId,
|
|
125
|
+
"--env-id", testEnvId,
|
|
126
|
+
"--value", "updated-value",
|
|
127
|
+
);
|
|
128
|
+
expect(result.exitCode).toBe(0);
|
|
129
|
+
|
|
130
|
+
const data = parseJson(result);
|
|
131
|
+
expect(data).toHaveProperty("id");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("env-delete — deletes the env var", async () => {
|
|
135
|
+
const result = await run(
|
|
136
|
+
"vercel", "env-delete",
|
|
137
|
+
"--project", testProjectId,
|
|
138
|
+
"--env-id", testEnvId,
|
|
139
|
+
);
|
|
140
|
+
expect(result.exitCode).toBe(0);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("deployments — lists deployments", async () => {
|
|
144
|
+
const result = await run("vercel", "deployments", "--max-results", "5");
|
|
145
|
+
expect(result.exitCode).toBe(0);
|
|
146
|
+
|
|
147
|
+
const data = parseJson(result);
|
|
148
|
+
expect(Array.isArray(data)).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("domains — lists domains", async () => {
|
|
152
|
+
const result = await run("vercel", "domains", "--max-results", "5");
|
|
153
|
+
expect(result.exitCode).toBe(0);
|
|
154
|
+
|
|
155
|
+
const data = parseJson(result);
|
|
156
|
+
expect(Array.isArray(data)).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("project-delete — deletes the test project", async () => {
|
|
160
|
+
const result = await run("vercel", "project-delete", "--project", testProjectId);
|
|
161
|
+
expect(result.exitCode).toBe(0);
|
|
162
|
+
testProjectId = ""; // prevent afterAll cleanup
|
|
163
|
+
});
|
|
164
|
+
});
|
package/src/cli.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { registerFormsCommands } from "./commands/forms.js";
|
|
|
11
11
|
import { registerAgentCommands } from "./commands/agent.js";
|
|
12
12
|
import { registerCronCommands } from "./commands/cron.js";
|
|
13
13
|
import { registerGithubCommands } from "./commands/github.js";
|
|
14
|
+
import { registerVercelCommands } from "./commands/vercel.js";
|
|
14
15
|
import { registerInitCommand } from "./commands/init.js";
|
|
15
16
|
import { outputError } from "./lib/output.js";
|
|
16
17
|
|
|
@@ -26,7 +27,7 @@ const program = new Command();
|
|
|
26
27
|
|
|
27
28
|
program
|
|
28
29
|
.name("cliclaw")
|
|
29
|
-
.description("CLI tool for Gmail, Google Drive, Google Slides, Google Sheets, Google Calendar, Google Forms, and
|
|
30
|
+
.description("CLI tool for Gmail, Google Drive, Google Slides, Google Sheets, Google Calendar, Google Forms, GitHub, and Vercel operations")
|
|
30
31
|
.version("0.1.0");
|
|
31
32
|
|
|
32
33
|
registerGmailCommands(program, getClientManager);
|
|
@@ -36,6 +37,7 @@ registerSheetsCommands(program, getClientManager);
|
|
|
36
37
|
registerCalendarCommands(program, getClientManager);
|
|
37
38
|
registerFormsCommands(program, getClientManager);
|
|
38
39
|
registerGithubCommands(program, () => new TokenStore(getTokensPath()));
|
|
40
|
+
registerVercelCommands(program, () => new TokenStore(getTokensPath()));
|
|
39
41
|
registerAgentCommands(program, () => new AgentStore(getAgentsDir()));
|
|
40
42
|
registerCronCommands(program, () => new AgentStore(getAgentsDir()));
|
|
41
43
|
registerInitCommand(program);
|