@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.
Files changed (2) hide show
  1. package/dist/index.js +102 -8
  2. 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: { authorization: `Bearer ${credentials.token}`, accept: "application/json", ...init?.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 ? args[apiUrlIndex + 1] : await prompt("URL da API HAD Deploy: ");
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.map((column, index) => column.toUpperCase().padEnd(widths[index] ?? column.length)).join(" "));
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.map((column, index) => (row[column] ?? "").padEnd(widths[index] ?? 0)).join(" "));
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) => ({ id: project.id, name: project.name, status: project.status })));
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) => ({ id: application.id, name: application.name, framework: application.framework, status: application.status })));
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([{ id: deployment.id, status: deployment.status, trigger: deployment.trigger, queued: deployment.queuedAt, started: deployment.startedAt ?? "-", finished: deployment.finishedAt ?? "-", error: deployment.errorCode ?? "-" }]);
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 ? error.message : "Não foi possível concluir o comando.");
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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hadcloud/deploy-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {