@hadcloud/deploy-cli 0.1.0 → 0.1.2
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 +102 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,7 +10,10 @@ Uso:
|
|
|
10
10
|
had logout
|
|
11
11
|
had config
|
|
12
12
|
had projects list
|
|
13
|
+
had projects create <name> [--description <text>]
|
|
13
14
|
had apps list <project-id>
|
|
15
|
+
had templates list
|
|
16
|
+
had apps create <project-id> --template <template-id> [--region <region-code>]
|
|
14
17
|
had deploy <project-id> <app-id>
|
|
15
18
|
had status <deployment-id>
|
|
16
19
|
had logs <deployment-id> [tail]
|
|
@@ -24,7 +27,11 @@ async function request(path, init) {
|
|
|
24
27
|
const credentials = await loadCredentials();
|
|
25
28
|
const response = await fetch(`${credentials.apiUrl}${path}`, {
|
|
26
29
|
...init,
|
|
27
|
-
headers: {
|
|
30
|
+
headers: {
|
|
31
|
+
authorization: `Bearer ${credentials.token}`,
|
|
32
|
+
accept: "application/json",
|
|
33
|
+
...init?.headers,
|
|
34
|
+
},
|
|
28
35
|
});
|
|
29
36
|
if (!response.ok) {
|
|
30
37
|
const payload = (await response.json().catch(() => ({})));
|
|
@@ -83,7 +90,9 @@ async function promptSecret(question) {
|
|
|
83
90
|
}
|
|
84
91
|
async function login(args) {
|
|
85
92
|
const apiUrlIndex = args.indexOf("--api-url");
|
|
86
|
-
const apiInput = apiUrlIndex >= 0
|
|
93
|
+
const apiInput = apiUrlIndex >= 0
|
|
94
|
+
? args[apiUrlIndex + 1]
|
|
95
|
+
: await prompt("URL da API HAD Deploy: ");
|
|
87
96
|
if (!apiInput)
|
|
88
97
|
throw new Error("A URL da API é obrigatória.");
|
|
89
98
|
const fromStdin = args.includes("--token-stdin");
|
|
@@ -102,10 +111,28 @@ function printRows(rows) {
|
|
|
102
111
|
}
|
|
103
112
|
const columns = Object.keys(rows[0] ?? {});
|
|
104
113
|
const widths = columns.map((column) => Math.max(column.length, ...rows.map((row) => (row[column] ?? "").length)));
|
|
105
|
-
console.log(columns
|
|
114
|
+
console.log(columns
|
|
115
|
+
.map((column, index) => column.toUpperCase().padEnd(widths[index] ?? column.length))
|
|
116
|
+
.join(" "));
|
|
106
117
|
console.log(widths.map((width) => "-".repeat(width)).join(" "));
|
|
107
118
|
for (const row of rows)
|
|
108
|
-
console.log(columns
|
|
119
|
+
console.log(columns
|
|
120
|
+
.map((column, index) => (row[column] ?? "").padEnd(widths[index] ?? 0))
|
|
121
|
+
.join(" "));
|
|
122
|
+
}
|
|
123
|
+
function optionValue(args, option) {
|
|
124
|
+
const positions = args
|
|
125
|
+
.map((value, index) => (value === option ? index : -1))
|
|
126
|
+
.filter((index) => index >= 0);
|
|
127
|
+
if (positions.length > 1)
|
|
128
|
+
throw new Error(`A opção ${option} só pode ser informada uma vez.`);
|
|
129
|
+
const position = positions[0];
|
|
130
|
+
if (position === undefined)
|
|
131
|
+
return undefined;
|
|
132
|
+
const value = args[position + 1];
|
|
133
|
+
if (!value || value.startsWith("--"))
|
|
134
|
+
throw new Error(`Informe um valor para ${option}.`);
|
|
135
|
+
return value;
|
|
109
136
|
}
|
|
110
137
|
export async function main(args) {
|
|
111
138
|
const [group, action, resourceId, extra] = args;
|
|
@@ -123,12 +150,67 @@ export async function main(args) {
|
|
|
123
150
|
}
|
|
124
151
|
if (group === "projects" && action === "list" && !resourceId) {
|
|
125
152
|
const { projects } = await request("/api/v1/automation/projects");
|
|
126
|
-
printRows(projects.map((project) => ({
|
|
153
|
+
printRows(projects.map((project) => ({
|
|
154
|
+
id: project.id,
|
|
155
|
+
name: project.name,
|
|
156
|
+
status: project.status,
|
|
157
|
+
})));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (group === "projects" && action === "create" && resourceId) {
|
|
161
|
+
const description = optionValue(args, "--description");
|
|
162
|
+
const response = await request("/api/v1/projects", {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers: {
|
|
165
|
+
"content-type": "application/json",
|
|
166
|
+
"idempotency-key": crypto.randomUUID(),
|
|
167
|
+
},
|
|
168
|
+
body: JSON.stringify({
|
|
169
|
+
name: resourceId,
|
|
170
|
+
...(description ? { description } : {}),
|
|
171
|
+
}),
|
|
172
|
+
});
|
|
173
|
+
console.log(`Projeto ${response.project.name} (${response.project.id}) criado: ${response.project.status}`);
|
|
127
174
|
return;
|
|
128
175
|
}
|
|
129
176
|
if (group === "apps" && action === "list" && resourceId) {
|
|
130
177
|
const { applications } = await request(`/api/v1/automation/projects/${encodeURIComponent(resourceId)}/apps`);
|
|
131
|
-
printRows(applications.map((application) => ({
|
|
178
|
+
printRows(applications.map((application) => ({
|
|
179
|
+
id: application.id,
|
|
180
|
+
name: application.name,
|
|
181
|
+
framework: application.framework,
|
|
182
|
+
status: application.status,
|
|
183
|
+
})));
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (group === "templates" && action === "list" && !resourceId) {
|
|
187
|
+
const { templates } = await request("/api/v1/automation/templates");
|
|
188
|
+
printRows(templates.map((template) => ({
|
|
189
|
+
id: template.id,
|
|
190
|
+
name: template.name,
|
|
191
|
+
version: template.version ?? "latest",
|
|
192
|
+
tags: template.tags.join(", "),
|
|
193
|
+
})));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (group === "apps" && action === "create" && resourceId) {
|
|
197
|
+
const templateId = optionValue(args, "--template");
|
|
198
|
+
const regionCode = optionValue(args, "--region");
|
|
199
|
+
if (!templateId) {
|
|
200
|
+
throw new Error("Use --template <template-id>. Consulte os modelos com 'had templates list'.");
|
|
201
|
+
}
|
|
202
|
+
const response = await request(`/api/v1/automation/templates/${encodeURIComponent(templateId)}/services`, {
|
|
203
|
+
method: "POST",
|
|
204
|
+
headers: {
|
|
205
|
+
"content-type": "application/json",
|
|
206
|
+
"idempotency-key": crypto.randomUUID(),
|
|
207
|
+
},
|
|
208
|
+
body: JSON.stringify({
|
|
209
|
+
projectId: resourceId,
|
|
210
|
+
...(regionCode ? { regionCode } : {}),
|
|
211
|
+
}),
|
|
212
|
+
});
|
|
213
|
+
console.log(`Serviço ${response.service.name} (${response.service.id}) criado: ${response.service.status}`);
|
|
132
214
|
return;
|
|
133
215
|
}
|
|
134
216
|
if (group === "deploy" && action && resourceId && !extra) {
|
|
@@ -138,7 +220,17 @@ export async function main(args) {
|
|
|
138
220
|
}
|
|
139
221
|
if (group === "status" && action && !resourceId) {
|
|
140
222
|
const { deployment } = await request(`/api/v1/automation/deployments/${encodeURIComponent(action)}`);
|
|
141
|
-
printRows([
|
|
223
|
+
printRows([
|
|
224
|
+
{
|
|
225
|
+
id: deployment.id,
|
|
226
|
+
status: deployment.status,
|
|
227
|
+
trigger: deployment.trigger,
|
|
228
|
+
queued: deployment.queuedAt,
|
|
229
|
+
started: deployment.startedAt ?? "-",
|
|
230
|
+
finished: deployment.finishedAt ?? "-",
|
|
231
|
+
error: deployment.errorCode ?? "-",
|
|
232
|
+
},
|
|
233
|
+
]);
|
|
142
234
|
return;
|
|
143
235
|
}
|
|
144
236
|
if (group === "logs" && action && (!resourceId || /^\d+$/.test(resourceId))) {
|
|
@@ -151,6 +243,8 @@ export async function main(args) {
|
|
|
151
243
|
usage();
|
|
152
244
|
}
|
|
153
245
|
main(process.argv.slice(2)).catch((error) => {
|
|
154
|
-
console.error(error instanceof Error
|
|
246
|
+
console.error(error instanceof Error
|
|
247
|
+
? error.message
|
|
248
|
+
: "Não foi possível concluir o comando.");
|
|
155
249
|
process.exitCode = 1;
|
|
156
250
|
});
|