@prisma/compute-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.
- package/README.md +118 -0
- package/bin/compute +4 -0
- package/bin/compute-bun +4 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +28 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/deploy.d.ts +56 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +106 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/env.d.ts +2 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +84 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/helpers.d.ts +27 -0
- package/dist/commands/helpers.d.ts.map +1 -0
- package/dist/commands/helpers.js +128 -0
- package/dist/commands/helpers.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +17 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +17 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/projects.d.ts +2 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +43 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/services.d.ts +2 -0
- package/dist/commands/services.d.ts.map +1 -0
- package/dist/commands/services.js +318 -0
- package/dist/commands/services.js.map +1 -0
- package/dist/commands/versions.d.ts +2 -0
- package/dist/commands/versions.d.ts.map +1 -0
- package/dist/commands/versions.js +321 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth/client.d.ts +7 -0
- package/dist/lib/auth/client.d.ts.map +1 -0
- package/dist/lib/auth/client.js +26 -0
- package/dist/lib/auth/client.js.map +1 -0
- package/dist/lib/auth/guard.d.ts +12 -0
- package/dist/lib/auth/guard.d.ts.map +1 -0
- package/dist/lib/auth/guard.js +39 -0
- package/dist/lib/auth/guard.js.map +1 -0
- package/dist/lib/auth/login.d.ts +15 -0
- package/dist/lib/auth/login.d.ts.map +1 -0
- package/dist/lib/auth/login.js +128 -0
- package/dist/lib/auth/login.js.map +1 -0
- package/dist/lib/auth/token-storage.d.ts +9 -0
- package/dist/lib/auth/token-storage.d.ts.map +1 -0
- package/dist/lib/auth/token-storage.js +55 -0
- package/dist/lib/auth/token-storage.js.map +1 -0
- package/dist/lib/compute-config.d.ts +12 -0
- package/dist/lib/compute-config.d.ts.map +1 -0
- package/dist/lib/compute-config.js +69 -0
- package/dist/lib/compute-config.js.map +1 -0
- package/dist/lib/format.d.ts +2 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +11 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/interaction.d.ts +17 -0
- package/dist/lib/interaction.d.ts.map +1 -0
- package/dist/lib/interaction.js +131 -0
- package/dist/lib/interaction.js.map +1 -0
- package/dist/lib/json-output.d.ts +3 -0
- package/dist/lib/json-output.d.ts.map +1 -0
- package/dist/lib/json-output.js +9 -0
- package/dist/lib/json-output.js.map +1 -0
- package/dist/lib/progress.d.ts +6 -0
- package/dist/lib/progress.d.ts.map +1 -0
- package/dist/lib/progress.js +156 -0
- package/dist/lib/progress.js.map +1 -0
- package/package.json +45 -0
- package/src/cli.ts +30 -0
- package/src/commands/deploy.ts +127 -0
- package/src/commands/env.ts +104 -0
- package/src/commands/helpers.ts +153 -0
- package/src/commands/login.ts +18 -0
- package/src/commands/logout.ts +18 -0
- package/src/commands/projects.ts +54 -0
- package/src/commands/services.ts +385 -0
- package/src/commands/versions.ts +389 -0
- package/src/index.ts +2 -0
- package/src/lib/auth/client.ts +39 -0
- package/src/lib/auth/guard.ts +51 -0
- package/src/lib/auth/login.ts +175 -0
- package/src/lib/auth/token-storage.ts +73 -0
- package/src/lib/compute-config.ts +95 -0
- package/src/lib/format.ts +16 -0
- package/src/lib/interaction.ts +166 -0
- package/src/lib/json-output.ts +9 -0
- package/src/lib/progress.ts +172 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { ComputeClient } from "@prisma/compute-sdk";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
import { formatTable } from "../lib/format.ts";
|
|
4
|
+
import {
|
|
5
|
+
createDeployInteraction,
|
|
6
|
+
isInteractiveSession,
|
|
7
|
+
promptForConfirmation,
|
|
8
|
+
} from "../lib/interaction.ts";
|
|
9
|
+
import { printJsonResult } from "../lib/json-output.ts";
|
|
10
|
+
import { createDestroyServiceProgress } from "../lib/progress.ts";
|
|
11
|
+
import {
|
|
12
|
+
endFlow,
|
|
13
|
+
handleError,
|
|
14
|
+
parsePollOptions,
|
|
15
|
+
startFlow,
|
|
16
|
+
withAuthAndSignal,
|
|
17
|
+
} from "./helpers.ts";
|
|
18
|
+
|
|
19
|
+
const servicesListCommand = defineCommand({
|
|
20
|
+
meta: { name: "list", description: "List compute services" },
|
|
21
|
+
args: {
|
|
22
|
+
project: { type: "string", description: "Project ID" },
|
|
23
|
+
json: { type: "boolean", default: false, description: "Output JSON" },
|
|
24
|
+
},
|
|
25
|
+
run: async ({ args }) => {
|
|
26
|
+
const exitCode = await withAuthAndSignal(
|
|
27
|
+
async (managementClient, signal) => {
|
|
28
|
+
const flowStarted =
|
|
29
|
+
!args.json && startFlow("Prisma Compute · Services");
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const sdk = new ComputeClient(managementClient);
|
|
33
|
+
|
|
34
|
+
let projectId = args.project;
|
|
35
|
+
if (!projectId) {
|
|
36
|
+
const interaction = args.json
|
|
37
|
+
? undefined
|
|
38
|
+
: createDeployInteraction();
|
|
39
|
+
if (!interaction?.selectProject) {
|
|
40
|
+
console.error("Missing required flag: --project <id>");
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
const projectsResult = await sdk.listProjects({ signal });
|
|
44
|
+
if (projectsResult.isErr()) {
|
|
45
|
+
console.error(projectsResult.error.message);
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
projectId = await interaction.selectProject(projectsResult.value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const result = await sdk.listServices({ projectId, signal });
|
|
52
|
+
|
|
53
|
+
if (args.json) {
|
|
54
|
+
printJsonResult(result);
|
|
55
|
+
return result.isOk() ? 0 : 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (result.isErr()) {
|
|
59
|
+
console.error(result.error.message);
|
|
60
|
+
return 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (result.value.length === 0) {
|
|
64
|
+
console.log("No compute services found.");
|
|
65
|
+
endFlow(flowStarted);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log(
|
|
70
|
+
formatTable(
|
|
71
|
+
["ID", "Name", "Region"],
|
|
72
|
+
result.value.map((s) => [s.id, s.name, s.region]),
|
|
73
|
+
),
|
|
74
|
+
);
|
|
75
|
+
endFlow(flowStarted);
|
|
76
|
+
return 0;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return handleError(error);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (exitCode !== 0) process.exit(exitCode);
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const servicesCreateCommand = defineCommand({
|
|
88
|
+
meta: { name: "create", description: "Create a compute service" },
|
|
89
|
+
args: {
|
|
90
|
+
project: { type: "string", description: "Project ID" },
|
|
91
|
+
name: { type: "string", description: "Service display name" },
|
|
92
|
+
region: { type: "string", description: "Region ID" },
|
|
93
|
+
json: { type: "boolean", default: false, description: "Output JSON" },
|
|
94
|
+
},
|
|
95
|
+
run: async ({ args }) => {
|
|
96
|
+
const exitCode = await withAuthAndSignal(
|
|
97
|
+
async (managementClient, signal) => {
|
|
98
|
+
const flowStarted =
|
|
99
|
+
!args.json && startFlow("Prisma Compute · Services");
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const sdk = new ComputeClient(managementClient);
|
|
103
|
+
const interaction = args.json ? undefined : createDeployInteraction();
|
|
104
|
+
|
|
105
|
+
let projectId = args.project;
|
|
106
|
+
if (!projectId) {
|
|
107
|
+
if (!interaction?.selectProject) {
|
|
108
|
+
console.error("Missing required flag: --project <id>");
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
const projectsResult = await sdk.listProjects({ signal });
|
|
112
|
+
if (projectsResult.isErr()) {
|
|
113
|
+
console.error(projectsResult.error.message);
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
projectId = await interaction.selectProject(projectsResult.value);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let serviceName = args.name;
|
|
120
|
+
if (!serviceName) {
|
|
121
|
+
if (!interaction?.provideServiceName) {
|
|
122
|
+
console.error("Missing required flag: --name <name>");
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
serviceName = await interaction.provideServiceName();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let region = args.region;
|
|
129
|
+
if (!region) {
|
|
130
|
+
if (!interaction?.selectRegion) {
|
|
131
|
+
console.error("Missing required flag: --region <region>");
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
const { REGIONS } = await import("@prisma/compute-sdk");
|
|
135
|
+
region = await interaction.selectRegion(REGIONS);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const result = await sdk.createService({
|
|
139
|
+
projectId,
|
|
140
|
+
serviceName,
|
|
141
|
+
region,
|
|
142
|
+
signal,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
if (args.json) {
|
|
146
|
+
printJsonResult(result);
|
|
147
|
+
return result.isOk() ? 0 : 1;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (result.isErr()) {
|
|
151
|
+
console.error(result.error.message);
|
|
152
|
+
return 1;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
console.log(
|
|
156
|
+
`Created compute service ${result.value.name} (${result.value.id})`,
|
|
157
|
+
);
|
|
158
|
+
endFlow(flowStarted);
|
|
159
|
+
return 0;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
return handleError(error);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
if (exitCode !== 0) process.exit(exitCode);
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const servicesShowCommand = defineCommand({
|
|
171
|
+
meta: { name: "show", description: "Show compute service details" },
|
|
172
|
+
args: {
|
|
173
|
+
id: {
|
|
174
|
+
type: "positional",
|
|
175
|
+
description: "Compute service ID",
|
|
176
|
+
required: false,
|
|
177
|
+
},
|
|
178
|
+
json: { type: "boolean", default: false, description: "Output JSON" },
|
|
179
|
+
},
|
|
180
|
+
run: async ({ args }) => {
|
|
181
|
+
const exitCode = await withAuthAndSignal(
|
|
182
|
+
async (managementClient, signal) => {
|
|
183
|
+
try {
|
|
184
|
+
const sdk = new ComputeClient(managementClient);
|
|
185
|
+
const serviceId = args.id;
|
|
186
|
+
|
|
187
|
+
if (!serviceId) {
|
|
188
|
+
console.error("Usage: compute services show <id>");
|
|
189
|
+
return 1;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const result = await sdk.showService({ serviceId, signal });
|
|
193
|
+
|
|
194
|
+
if (args.json) {
|
|
195
|
+
printJsonResult(result);
|
|
196
|
+
return result.isOk() ? 0 : 1;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (result.isErr()) {
|
|
200
|
+
console.error(result.error.message);
|
|
201
|
+
return 1;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const s = result.value;
|
|
205
|
+
console.log(`ID: ${s.id}`);
|
|
206
|
+
console.log(`Name: ${s.name}`);
|
|
207
|
+
console.log(`Region: ${s.region}`);
|
|
208
|
+
console.log(`Project: ${s.projectId ?? "-"}`);
|
|
209
|
+
if (s.latestVersionId) {
|
|
210
|
+
console.log(`Latest Version: ${s.latestVersionId}`);
|
|
211
|
+
}
|
|
212
|
+
return 0;
|
|
213
|
+
} catch (error) {
|
|
214
|
+
return handleError(error);
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
if (exitCode !== 0) process.exit(exitCode);
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const servicesDeleteCommand = defineCommand({
|
|
224
|
+
meta: { name: "delete", description: "Delete a compute service" },
|
|
225
|
+
args: {
|
|
226
|
+
id: {
|
|
227
|
+
type: "positional",
|
|
228
|
+
description: "Compute service ID",
|
|
229
|
+
required: false,
|
|
230
|
+
},
|
|
231
|
+
json: { type: "boolean", default: false, description: "Output JSON" },
|
|
232
|
+
},
|
|
233
|
+
run: async ({ args }) => {
|
|
234
|
+
const exitCode = await withAuthAndSignal(
|
|
235
|
+
async (managementClient, signal) => {
|
|
236
|
+
try {
|
|
237
|
+
const sdk = new ComputeClient(managementClient);
|
|
238
|
+
const serviceId = args.id;
|
|
239
|
+
|
|
240
|
+
if (!serviceId) {
|
|
241
|
+
console.error("Usage: compute services delete <id>");
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!args.json && isInteractiveSession()) {
|
|
246
|
+
const confirmed = await promptForConfirmation(
|
|
247
|
+
`Delete service ${serviceId}?`,
|
|
248
|
+
);
|
|
249
|
+
if (!confirmed) {
|
|
250
|
+
console.log("Delete cancelled.");
|
|
251
|
+
return 0;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const result = await sdk.deleteService({ serviceId, signal });
|
|
256
|
+
|
|
257
|
+
if (args.json) {
|
|
258
|
+
printJsonResult(result);
|
|
259
|
+
return result.isOk() ? 0 : 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (result.isErr()) {
|
|
263
|
+
console.error(result.error.message);
|
|
264
|
+
return 1;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log(`Deleted compute service: ${serviceId}`);
|
|
268
|
+
return 0;
|
|
269
|
+
} catch (error) {
|
|
270
|
+
return handleError(error);
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
if (exitCode !== 0) process.exit(exitCode);
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const servicesDestroyCommand = defineCommand({
|
|
280
|
+
meta: {
|
|
281
|
+
name: "destroy",
|
|
282
|
+
description:
|
|
283
|
+
"Destroy a service: stop and delete all versions, then delete the service",
|
|
284
|
+
},
|
|
285
|
+
args: {
|
|
286
|
+
id: {
|
|
287
|
+
type: "positional",
|
|
288
|
+
description: "Compute service ID",
|
|
289
|
+
required: false,
|
|
290
|
+
},
|
|
291
|
+
keepService: {
|
|
292
|
+
type: "boolean",
|
|
293
|
+
default: false,
|
|
294
|
+
description: "Keep the service, only destroy versions",
|
|
295
|
+
},
|
|
296
|
+
timeout: {
|
|
297
|
+
type: "string",
|
|
298
|
+
default: "120",
|
|
299
|
+
description: "Poll timeout in seconds",
|
|
300
|
+
},
|
|
301
|
+
pollInterval: {
|
|
302
|
+
type: "string",
|
|
303
|
+
default: "1000",
|
|
304
|
+
description: "Poll interval in milliseconds",
|
|
305
|
+
},
|
|
306
|
+
json: { type: "boolean", default: false, description: "Output JSON" },
|
|
307
|
+
},
|
|
308
|
+
run: async ({ args }) => {
|
|
309
|
+
const exitCode = await withAuthAndSignal(
|
|
310
|
+
async (managementClient, signal) => {
|
|
311
|
+
const flowStarted =
|
|
312
|
+
!args.json && startFlow("Prisma Compute · Services");
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
const sdk = new ComputeClient(managementClient);
|
|
316
|
+
const serviceId = args.id;
|
|
317
|
+
|
|
318
|
+
if (!serviceId) {
|
|
319
|
+
console.error("Usage: compute services destroy <id>");
|
|
320
|
+
return 1;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (!args.json && isInteractiveSession()) {
|
|
324
|
+
const action = args.keepService
|
|
325
|
+
? "stop and delete all its versions"
|
|
326
|
+
: "stop and delete all versions, then delete the service";
|
|
327
|
+
const confirmed = await promptForConfirmation(
|
|
328
|
+
`Destroy service ${serviceId}? This will ${action}.`,
|
|
329
|
+
);
|
|
330
|
+
if (!confirmed) {
|
|
331
|
+
console.log("Destroy cancelled.");
|
|
332
|
+
endFlow(flowStarted);
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const result = await sdk.destroyService({
|
|
338
|
+
serviceId,
|
|
339
|
+
keepService: args.keepService,
|
|
340
|
+
...parsePollOptions(args),
|
|
341
|
+
progress: args.json ? undefined : createDestroyServiceProgress(),
|
|
342
|
+
signal,
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
if (args.json) {
|
|
346
|
+
printJsonResult(result);
|
|
347
|
+
return result.isOk() ? 0 : 1;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (result.isErr()) {
|
|
351
|
+
const err = result.error;
|
|
352
|
+
if (err._tag === "DestroyAggregateError") {
|
|
353
|
+
for (const f of err.failures) {
|
|
354
|
+
console.error(`${f.versionId}: ${f.error.message}`);
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
console.error(err.message);
|
|
358
|
+
}
|
|
359
|
+
return 1;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const suffix = args.keepService ? " (service kept)" : "";
|
|
363
|
+
console.log(`Destroyed service: ${serviceId}${suffix}`);
|
|
364
|
+
endFlow(flowStarted);
|
|
365
|
+
return 0;
|
|
366
|
+
} catch (error) {
|
|
367
|
+
return handleError(error);
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
if (exitCode !== 0) process.exit(exitCode);
|
|
373
|
+
},
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
export const servicesGroup = defineCommand({
|
|
377
|
+
meta: { name: "services", description: "Compute service management" },
|
|
378
|
+
subCommands: {
|
|
379
|
+
list: servicesListCommand,
|
|
380
|
+
create: servicesCreateCommand,
|
|
381
|
+
show: servicesShowCommand,
|
|
382
|
+
delete: servicesDeleteCommand,
|
|
383
|
+
destroy: servicesDestroyCommand,
|
|
384
|
+
},
|
|
385
|
+
});
|