run402 1.19.0 → 1.19.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/lib/email.mjs +41 -5
  2. package/package.json +1 -1
package/lib/email.mjs CHANGED
@@ -7,6 +7,7 @@ Usage:
7
7
 
8
8
  Subcommands:
9
9
  create <slug> [--project <id>] Create a mailbox (<slug>@mail.run402.com)
10
+ status [--project <id>] Show mailbox info (ID, address, slug)
10
11
  send --template <name> --to <email> [--var key=value ...] [--project <id>]
11
12
  Send a template email
12
13
  list [--project <id>] List sent emails
@@ -71,14 +72,15 @@ async function resolveMailboxId(projectId, serviceKey) {
71
72
  console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
72
73
  process.exit(1);
73
74
  }
74
- const mailboxes = await res.json();
75
+ const body = await res.json();
76
+ const mailboxes = body.mailboxes || body;
75
77
  if (!Array.isArray(mailboxes) || mailboxes.length === 0) {
76
78
  console.error(JSON.stringify({ status: "error", message: "No mailbox found. Run: run402 email create <slug>" }));
77
79
  process.exit(1);
78
80
  }
79
81
  const mb = mailboxes[0];
80
- updateProject(projectId, { mailbox_id: mb.id, mailbox_address: mb.address });
81
- return mb.id;
82
+ updateProject(projectId, { mailbox_id: mb.mailbox_id, mailbox_address: mb.address });
83
+ return mb.mailbox_id;
82
84
  }
83
85
 
84
86
  async function create(args) {
@@ -110,12 +112,22 @@ async function create(args) {
110
112
  });
111
113
  const data = await res.json();
112
114
  if (!res.ok) {
115
+ // On 409 (mailbox already exists), discover existing mailbox and return it
116
+ if (res.status === 409) {
117
+ const mbId = await resolveMailboxId(projectId, p.service_key).catch(() => null);
118
+ if (mbId) {
119
+ const store = loadKeyStore();
120
+ const proj = store.projects[projectId];
121
+ console.log(JSON.stringify({ status: "ok", mailbox_id: mbId, address: proj?.mailbox_address || mbId, already_existed: true }));
122
+ return;
123
+ }
124
+ }
113
125
  console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
114
126
  process.exit(1);
115
127
  }
116
128
 
117
- updateProject(projectId, { mailbox_id: data.id, mailbox_address: data.address });
118
- console.log(JSON.stringify({ status: "ok", mailbox_id: data.id, address: data.address, slug: data.slug }));
129
+ updateProject(projectId, { mailbox_id: data.mailbox_id, mailbox_address: data.address });
130
+ console.log(JSON.stringify({ status: "ok", mailbox_id: data.mailbox_id, address: data.address, slug: data.slug }));
119
131
  }
120
132
 
121
133
  async function send(args) {
@@ -191,10 +203,34 @@ async function get(args) {
191
203
  console.log(JSON.stringify(data, null, 2));
192
204
  }
193
205
 
206
+ async function status(args) {
207
+ const projectId = resolveProjectId(parseFlag(args, "--project"));
208
+ const p = findProject(projectId);
209
+
210
+ const res = await fetch(`${API}/mailboxes/v1`, {
211
+ headers: { "Authorization": `Bearer ${p.service_key}` },
212
+ });
213
+ if (!res.ok) {
214
+ const data = await res.json().catch(() => ({}));
215
+ console.error(JSON.stringify({ status: "error", http: res.status, ...data }));
216
+ process.exit(1);
217
+ }
218
+ const body = await res.json();
219
+ const mailboxes = body.mailboxes || body;
220
+ if (!Array.isArray(mailboxes) || mailboxes.length === 0) {
221
+ console.error(JSON.stringify({ status: "error", message: "No mailbox found. Run: run402 email create <slug>" }));
222
+ process.exit(1);
223
+ }
224
+ const mb = mailboxes[0];
225
+ updateProject(projectId, { mailbox_id: mb.mailbox_id, mailbox_address: mb.address });
226
+ console.log(JSON.stringify({ status: "ok", mailbox_id: mb.mailbox_id, address: mb.address, slug: mb.slug }));
227
+ }
228
+
194
229
  export async function run(sub, args) {
195
230
  if (!sub || sub === '--help' || sub === '-h') { console.log(HELP); process.exit(0); }
196
231
  switch (sub) {
197
232
  case "create": await create(args); break;
233
+ case "status": await status(args); break;
198
234
  case "send": await send(args); break;
199
235
  case "list": await list(args); break;
200
236
  case "get": await get(args); break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "1.19.0",
3
+ "version": "1.19.2",
4
4
  "description": "CLI for Run402 — provision Postgres databases, deploy static sites, generate images, and manage wallets via x402 and MPP micropayments.",
5
5
  "type": "module",
6
6
  "bin": {