nubot-lite 0.1.0 → 0.1.1

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.
@@ -25,27 +25,28 @@ export async function ensureLogin(workerDir) {
25
25
  if (login.code !== 0) throw new CliError("No se pudo entrar a Cloudflare. Vuelve a intentar con: npx nubot-lite init");
26
26
  }
27
27
 
28
+ /** Otro CRM de la cuenta ya usa ese nombre: reusarlo sería adueñarse de sus datos y cambiarle las llaves. */
29
+ export class NameTakenError extends CliError {}
30
+
31
+ const taken = (name) =>
32
+ new NameTakenError(
33
+ `Ya hay un CRM llamado ${name} en tu cuenta de Cloudflare. Para no pisarlo, instala con otro nombre de empresa (o con --name otro-nombre).`,
34
+ );
35
+
28
36
  export async function createD1(workerDir, name) {
29
37
  const r = await wrangler(workerDir, ["d1", "create", name], { capture: true });
30
38
  const id = parseD1Id(r.out);
31
39
  if (id) return id;
32
- if (/already exists/i.test(r.out)) {
33
- const list = await wrangler(workerDir, ["d1", "list", "--json"], { capture: true });
34
- const found = JSON.parse(list.out.slice(list.out.indexOf("["))).find((db) => db.name === name);
35
- if (found) return found.uuid;
36
- }
40
+ if (/already exists/i.test(r.out)) throw taken(name);
37
41
  throw new CliError(`No se pudo crear la base de datos D1.\n${r.out}`);
38
42
  }
39
43
 
40
- export async function createKv(workerDir, title) {
41
- const r = await wrangler(workerDir, ["kv", "namespace", "create", title], { capture: true });
44
+ /** Cada CRM tiene su propio espacio de archivos, con su nombre. */
45
+ export async function createKv(workerDir, name) {
46
+ const r = await wrangler(workerDir, ["kv", "namespace", "create", `${name}-archivos`], { capture: true });
42
47
  const id = parseKvId(r.out);
43
48
  if (id) return id;
44
- if (/already exists/i.test(r.out)) {
45
- const list = await wrangler(workerDir, ["kv", "namespace", "list"], { capture: true });
46
- const found = JSON.parse(list.out.slice(list.out.indexOf("["))).find((ns) => ns.title === title || ns.title.endsWith(title));
47
- if (found) return found.id;
48
- }
49
+ if (/already exists/i.test(r.out)) throw taken(name);
49
50
  throw new CliError(`No se pudo crear el espacio de archivos (KV).\n${r.out}`);
50
51
  }
51
52
 
@@ -1,8 +1,8 @@
1
- import { existsSync, readdirSync } from "node:fs";
1
+ import { existsSync, readdirSync, rmSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
3
  import { apiClient, ensureWebhook, whatsappAccounts } from "../api.mjs";
4
4
  import { slugify } from "../args.mjs";
5
- import { createD1, createKv, deploy, ensureLogin, migrate, putSecrets } from "../cloudflare.mjs";
5
+ import { createD1, createKv, deploy, ensureLogin, migrate, NameTakenError, putSecrets } from "../cloudflare.mjs";
6
6
  import { copyTemplate, packageVersion, readState, secret, writeState, writeWranglerConfig } from "../project.mjs";
7
7
  import { npmInstall } from "../sh.mjs";
8
8
  import { ask, bold, choose, CliError, closePrompts, dim, info, ok, part, pause, warn } from "../ui.mjs";
@@ -81,6 +81,7 @@ ${bold("Nubot Lite")} · instalación en tu cuenta de Cloudflare`);
81
81
  part(1, PARTS, "Tu empresa", [dim("Con el nombre preparo una carpeta en tu computadora con todo lo necesario.")]);
82
82
  let dir = flags.dir && flags.dir !== true ? resolve(String(flags.dir)) : null;
83
83
  let state = dir ? readState(dir, "config.json") : null;
84
+ const created = !state;
84
85
  if (state) {
85
86
  ok(`Retomo la instalación de ${state.business}`);
86
87
  } else {
@@ -117,13 +118,19 @@ ${bold("Nubot Lite")} · instalación en tu cuenta de Cloudflare`);
117
118
  await ensureLogin(workerDir);
118
119
  ok("Conectado a tu cuenta de Cloudflare");
119
120
  writeWranglerConfig(dir, { name: state.name, d1Id: state.d1Id ?? "00000000-0000-0000-0000-000000000000", kvId: state.kvId ?? "0".repeat(32) });
120
- if (!state.d1Id) {
121
- state.d1Id = await createD1(workerDir, state.name);
122
- save();
123
- }
124
- if (!state.kvId) {
125
- state.kvId = await createKv(workerDir, "archivos");
126
- save();
121
+ try {
122
+ if (!state.d1Id) {
123
+ state.d1Id = await createD1(workerDir, state.name);
124
+ save();
125
+ }
126
+ if (!state.kvId) {
127
+ state.kvId = await createKv(workerDir, state.name);
128
+ save();
129
+ }
130
+ } catch (err) {
131
+ // Si el nombre ya estaba tomado y no se creó nada, la carpeta recién armada sobra: así se puede reintentar.
132
+ if (err instanceof NameTakenError && created && !state.d1Id) rmSync(dir, { recursive: true, force: true });
133
+ throw err;
127
134
  }
128
135
  writeWranglerConfig(dir, { name: state.name, d1Id: state.d1Id, kvId: state.kvId });
129
136
  ok("Base de datos y espacio para archivos creados");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nubot-lite",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Instala Nubot Lite (bandeja de WhatsApp con agente de IA) en tu cuenta de Cloudflare.",
5
5
  "license": "(MIT AND LicenseRef-Nubot-Lite-Panel)",
6
6
  "type": "module",