supersendtx-cli 0.1.1 → 0.3.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/dist/cli.js +205 -12
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -82,21 +82,182 @@ async function runSendCommandWithClient(args, env = process.env) {
|
|
|
82
82
|
return { exitCode };
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// src/commands/
|
|
85
|
+
// src/commands/domains/shared.ts
|
|
86
86
|
function readFlag2(args, flag) {
|
|
87
87
|
const index = args.indexOf(flag);
|
|
88
88
|
if (index === -1) return void 0;
|
|
89
89
|
return args[index + 1];
|
|
90
90
|
}
|
|
91
|
-
function
|
|
91
|
+
function parseDomainsCommonArgs(args) {
|
|
92
92
|
return {
|
|
93
93
|
apiKey: readFlag2(args, "--api-key"),
|
|
94
|
-
baseUrl: readFlag2(args, "--base-url")
|
|
94
|
+
baseUrl: readFlag2(args, "--base-url"),
|
|
95
|
+
name: readFlag2(args, "--name") || readFlag2(args, "--domain"),
|
|
96
|
+
id: readFlag2(args, "--id")
|
|
95
97
|
};
|
|
96
98
|
}
|
|
97
99
|
function resolveApiKey(options, env) {
|
|
98
100
|
return options.apiKey || env.SUPERSENDTX_API_KEY || env.SUPERTX_API_KEY || null;
|
|
99
101
|
}
|
|
102
|
+
async function createDomainsClient(apiKey, baseUrl) {
|
|
103
|
+
const { SuperSendTX } = await import("supersendtx");
|
|
104
|
+
return new SuperSendTX(apiKey, baseUrl ? { baseUrl } : void 0);
|
|
105
|
+
}
|
|
106
|
+
function formatDnsRecords(records) {
|
|
107
|
+
const lines = ["DNS records to add:", ""];
|
|
108
|
+
for (const record of records) {
|
|
109
|
+
lines.push(` ${record.type.padEnd(6)} ${record.host}`);
|
|
110
|
+
lines.push(` ${record.value}`);
|
|
111
|
+
lines.push(` (${record.purpose})`);
|
|
112
|
+
lines.push("");
|
|
113
|
+
}
|
|
114
|
+
return lines.join("\n").trimEnd();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/commands/domains/add.ts
|
|
118
|
+
async function runAddCommand(args, env = process.env) {
|
|
119
|
+
const options = parseDomainsCommonArgs(args);
|
|
120
|
+
const apiKey = resolveApiKey(options, env);
|
|
121
|
+
if (!apiKey) {
|
|
122
|
+
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
123
|
+
}
|
|
124
|
+
const name = options.name || args.find((arg) => !arg.startsWith("--") && arg.includes("."));
|
|
125
|
+
if (!name) {
|
|
126
|
+
return {
|
|
127
|
+
exitCode: 1,
|
|
128
|
+
error: "Missing domain. Usage: supersendtx domains add example.com"
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const client = await createDomainsClient(apiKey, options.baseUrl);
|
|
133
|
+
const result = await client.domains.create({ name });
|
|
134
|
+
console.log(JSON.stringify(result));
|
|
135
|
+
console.error("");
|
|
136
|
+
console.error(`Domain ${result.domain.name} added (${result.domain.status}).`);
|
|
137
|
+
console.error(formatDnsRecords(result.records));
|
|
138
|
+
console.error("");
|
|
139
|
+
console.error(`Then: supersendtx domains verify ${result.domain.name}`);
|
|
140
|
+
return { exitCode: 0 };
|
|
141
|
+
} catch (error) {
|
|
142
|
+
return { exitCode: 1, error: error instanceof Error ? error.message : String(error) };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/commands/domains/apply.ts
|
|
147
|
+
async function runApplyCommand(args, env = process.env) {
|
|
148
|
+
const options = parseDomainsCommonArgs(args);
|
|
149
|
+
const apiKey = resolveApiKey(options, env);
|
|
150
|
+
if (!apiKey) {
|
|
151
|
+
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
152
|
+
}
|
|
153
|
+
const providerFlag = args.includes("--provider") ? args[args.indexOf("--provider") + 1] : void 0;
|
|
154
|
+
const provider = (providerFlag || "").toLowerCase();
|
|
155
|
+
if (provider !== "cloudflare" && provider !== "godaddy") {
|
|
156
|
+
return {
|
|
157
|
+
exitCode: 1,
|
|
158
|
+
error: "Missing or invalid --provider. Use --provider cloudflare or --provider godaddy."
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const idOrName = options.id || options.name || args.find((arg, i) => {
|
|
162
|
+
if (arg.startsWith("--")) return false;
|
|
163
|
+
const prev = args[i - 1];
|
|
164
|
+
if (prev === "--provider" || prev === "--api-key" || prev === "--base-url" || prev === "--name" || prev === "--domain" || prev === "--id") {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
return arg.includes(".") || arg.length > 8;
|
|
168
|
+
});
|
|
169
|
+
if (!idOrName) {
|
|
170
|
+
return {
|
|
171
|
+
exitCode: 1,
|
|
172
|
+
error: "Missing domain. Usage: supersendtx domains apply example.com --provider cloudflare"
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const client = await createDomainsClient(apiKey, options.baseUrl);
|
|
177
|
+
const localCloudflare = env.CLOUDFLARE_API_TOKEN || env.CLOUDFLARE_API_KEY;
|
|
178
|
+
const useStoredCloudflare = provider === "cloudflare" && !localCloudflare;
|
|
179
|
+
const result = useStoredCloudflare ? await client.domains.apply(idOrName, { provider: "cloudflare" }) : await client.domains.applyDns({
|
|
180
|
+
idOrName,
|
|
181
|
+
provider,
|
|
182
|
+
cloudflareApiToken: localCloudflare,
|
|
183
|
+
cloudflareZoneId: env.CLOUDFLARE_ZONE_ID,
|
|
184
|
+
godaddyApiKey: env.GODADDY_API_KEY,
|
|
185
|
+
godaddyApiSecret: env.GODADDY_API_SECRET
|
|
186
|
+
});
|
|
187
|
+
console.log(JSON.stringify(result));
|
|
188
|
+
console.error(
|
|
189
|
+
useStoredCloudflare ? `Applied ${result.results.length} DNS change(s) via stored Cloudflare credentials for ${result.domain}.` : `Applied ${result.results.length} DNS change(s) via ${result.provider} for ${result.domain}.`
|
|
190
|
+
);
|
|
191
|
+
for (const row of result.results) {
|
|
192
|
+
console.error(` ${row.action.padEnd(10)} ${row.purpose} \u2192 ${row.host}`);
|
|
193
|
+
}
|
|
194
|
+
console.error("");
|
|
195
|
+
console.error(`Next: supersendtx domains verify ${result.domain}`);
|
|
196
|
+
return { exitCode: 0 };
|
|
197
|
+
} catch (error) {
|
|
198
|
+
return { exitCode: 1, error: error instanceof Error ? error.message : String(error) };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/commands/domains/list.ts
|
|
203
|
+
async function runListCommand(args, env = process.env) {
|
|
204
|
+
const options = parseDomainsCommonArgs(args);
|
|
205
|
+
const apiKey = resolveApiKey(options, env);
|
|
206
|
+
if (!apiKey) {
|
|
207
|
+
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const client = await createDomainsClient(apiKey, options.baseUrl);
|
|
211
|
+
const result = await client.domains.list();
|
|
212
|
+
console.log(JSON.stringify(result));
|
|
213
|
+
return { exitCode: 0 };
|
|
214
|
+
} catch (error) {
|
|
215
|
+
return { exitCode: 1, error: error instanceof Error ? error.message : String(error) };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/commands/domains/verify.ts
|
|
220
|
+
async function runVerifyCommand(args, env = process.env) {
|
|
221
|
+
const options = parseDomainsCommonArgs(args);
|
|
222
|
+
const apiKey = resolveApiKey(options, env);
|
|
223
|
+
if (!apiKey) {
|
|
224
|
+
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
225
|
+
}
|
|
226
|
+
const idOrName = options.id || options.name || args.find((arg) => !arg.startsWith("--") && (arg.includes(".") || arg.length > 8));
|
|
227
|
+
if (!idOrName) {
|
|
228
|
+
return {
|
|
229
|
+
exitCode: 1,
|
|
230
|
+
error: "Missing domain. Usage: supersendtx domains verify example.com"
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
const client = await createDomainsClient(apiKey, options.baseUrl);
|
|
235
|
+
const result = await client.domains.verify(idOrName);
|
|
236
|
+
console.log(JSON.stringify(result));
|
|
237
|
+
if (result.verified) {
|
|
238
|
+
console.error(`Domain ${result.domain.name} verified.`);
|
|
239
|
+
}
|
|
240
|
+
return { exitCode: 0 };
|
|
241
|
+
} catch (error) {
|
|
242
|
+
return { exitCode: 1, error: error instanceof Error ? error.message : String(error) };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/commands/webhooks/shared.ts
|
|
247
|
+
function readFlag3(args, flag) {
|
|
248
|
+
const index = args.indexOf(flag);
|
|
249
|
+
if (index === -1) return void 0;
|
|
250
|
+
return args[index + 1];
|
|
251
|
+
}
|
|
252
|
+
function parseWebhooksCommonArgs(args) {
|
|
253
|
+
return {
|
|
254
|
+
apiKey: readFlag3(args, "--api-key"),
|
|
255
|
+
baseUrl: readFlag3(args, "--base-url")
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function resolveApiKey2(options, env) {
|
|
259
|
+
return options.apiKey || env.SUPERSENDTX_API_KEY || env.SUPERTX_API_KEY || null;
|
|
260
|
+
}
|
|
100
261
|
async function createWebhooksClient(apiKey, baseUrl) {
|
|
101
262
|
const { SuperSendTX } = await import("supersendtx");
|
|
102
263
|
return new SuperSendTX(apiKey, baseUrl ? { baseUrl } : void 0);
|
|
@@ -105,11 +266,11 @@ async function createWebhooksClient(apiKey, baseUrl) {
|
|
|
105
266
|
// src/commands/webhooks/create.ts
|
|
106
267
|
async function runCreateCommand(args, env = process.env) {
|
|
107
268
|
const options = parseWebhooksCommonArgs(args);
|
|
108
|
-
const apiKey =
|
|
269
|
+
const apiKey = resolveApiKey2(options, env);
|
|
109
270
|
if (!apiKey) {
|
|
110
271
|
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
111
272
|
}
|
|
112
|
-
const url =
|
|
273
|
+
const url = readFlag3(args, "--url");
|
|
113
274
|
if (!url) {
|
|
114
275
|
return { exitCode: 1, error: "Required flag: --url" };
|
|
115
276
|
}
|
|
@@ -126,11 +287,11 @@ async function runCreateCommand(args, env = process.env) {
|
|
|
126
287
|
// src/commands/webhooks/delete.ts
|
|
127
288
|
async function runDeleteCommand(args, env = process.env) {
|
|
128
289
|
const options = parseWebhooksCommonArgs(args);
|
|
129
|
-
const apiKey =
|
|
290
|
+
const apiKey = resolveApiKey2(options, env);
|
|
130
291
|
if (!apiKey) {
|
|
131
292
|
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
132
293
|
}
|
|
133
|
-
const id =
|
|
294
|
+
const id = readFlag3(args, "--id");
|
|
134
295
|
if (!id) {
|
|
135
296
|
return { exitCode: 1, error: "Required flag: --id" };
|
|
136
297
|
}
|
|
@@ -145,9 +306,9 @@ async function runDeleteCommand(args, env = process.env) {
|
|
|
145
306
|
}
|
|
146
307
|
|
|
147
308
|
// src/commands/webhooks/list.ts
|
|
148
|
-
async function
|
|
309
|
+
async function runListCommand2(args, env = process.env) {
|
|
149
310
|
const options = parseWebhooksCommonArgs(args);
|
|
150
|
-
const apiKey =
|
|
311
|
+
const apiKey = resolveApiKey2(options, env);
|
|
151
312
|
if (!apiKey) {
|
|
152
313
|
return { exitCode: 1, error: "Missing API key. Set SUPERSENDTX_API_KEY or pass --api-key." };
|
|
153
314
|
}
|
|
@@ -164,22 +325,54 @@ async function runListCommand(args, env = process.env) {
|
|
|
164
325
|
// src/cli.ts
|
|
165
326
|
function printUsage() {
|
|
166
327
|
console.error("Usage:");
|
|
167
|
-
console.error(
|
|
328
|
+
console.error(" supersendtx domains add example.com");
|
|
329
|
+
console.error(" supersendtx domains apply example.com --provider cloudflare");
|
|
330
|
+
console.error(" supersendtx domains apply example.com --provider godaddy");
|
|
331
|
+
console.error(" supersendtx domains list");
|
|
332
|
+
console.error(" supersendtx domains verify example.com");
|
|
333
|
+
console.error(
|
|
334
|
+
' supersendtx emails send --from you@domain.com --to user@example.com --subject "Hello" --html "<p>Hi</p>"'
|
|
335
|
+
);
|
|
168
336
|
console.error(" supersendtx webhooks list");
|
|
169
337
|
console.error(" supersendtx webhooks create --url https://yourapp.com/hooks");
|
|
170
338
|
console.error(" supersendtx webhooks delete --id <webhook-id>");
|
|
171
339
|
console.error("");
|
|
172
|
-
console.error("Environment:
|
|
340
|
+
console.error("Environment:");
|
|
341
|
+
console.error(" SUPERSENDTX_API_KEY=stx_\u2026");
|
|
342
|
+
console.error(" CLOUDFLARE_API_TOKEN=\u2026 (optional local apply; else uses dashboard Integrations)");
|
|
343
|
+
console.error(" GODADDY_API_KEY=\u2026 GODADDY_API_SECRET=\u2026 (domains apply --provider godaddy)");
|
|
173
344
|
}
|
|
174
345
|
async function main() {
|
|
175
346
|
const [, , command, subcommand, ...rest] = process.argv;
|
|
347
|
+
if (command === "domains") {
|
|
348
|
+
if (subcommand === "add" || subcommand === "create") {
|
|
349
|
+
const result = await runAddCommand(rest);
|
|
350
|
+
if (result.error) console.error(result.error);
|
|
351
|
+
process.exit(result.exitCode);
|
|
352
|
+
}
|
|
353
|
+
if (subcommand === "apply") {
|
|
354
|
+
const result = await runApplyCommand(rest);
|
|
355
|
+
if (result.error) console.error(result.error);
|
|
356
|
+
process.exit(result.exitCode);
|
|
357
|
+
}
|
|
358
|
+
if (subcommand === "list") {
|
|
359
|
+
const result = await runListCommand(rest);
|
|
360
|
+
if (result.error) console.error(result.error);
|
|
361
|
+
process.exit(result.exitCode);
|
|
362
|
+
}
|
|
363
|
+
if (subcommand === "verify") {
|
|
364
|
+
const result = await runVerifyCommand(rest);
|
|
365
|
+
if (result.error) console.error(result.error);
|
|
366
|
+
process.exit(result.exitCode);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
176
369
|
if (command === "emails" && subcommand === "send") {
|
|
177
370
|
const result = await runSendCommandWithClient(rest);
|
|
178
371
|
process.exit(result.exitCode);
|
|
179
372
|
}
|
|
180
373
|
if (command === "webhooks") {
|
|
181
374
|
if (subcommand === "list") {
|
|
182
|
-
const result = await
|
|
375
|
+
const result = await runListCommand2(rest);
|
|
183
376
|
if (result.error) console.error(result.error);
|
|
184
377
|
process.exit(result.exitCode);
|
|
185
378
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supersendtx-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "SuperSend TX CLI — send transactional email from the terminal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"prepublishOnly": "npm run build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"supersendtx": "^0.
|
|
42
|
+
"supersendtx": "^0.3.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"tsup": "^8.5.0",
|