@sendly/cli 1.0.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.
Files changed (60) hide show
  1. package/README.md +323 -0
  2. package/bin/run.js +5 -0
  3. package/dist/commands/config/get.d.ts +13 -0
  4. package/dist/commands/config/get.js +38 -0
  5. package/dist/commands/config/list.d.ts +10 -0
  6. package/dist/commands/config/list.js +45 -0
  7. package/dist/commands/config/set.d.ts +14 -0
  8. package/dist/commands/config/set.js +67 -0
  9. package/dist/commands/credits/balance.d.ts +10 -0
  10. package/dist/commands/credits/balance.js +38 -0
  11. package/dist/commands/credits/history.d.ts +11 -0
  12. package/dist/commands/credits/history.js +88 -0
  13. package/dist/commands/doctor.d.ts +23 -0
  14. package/dist/commands/doctor.js +336 -0
  15. package/dist/commands/keys/create.d.ts +12 -0
  16. package/dist/commands/keys/create.js +47 -0
  17. package/dist/commands/keys/list.d.ts +10 -0
  18. package/dist/commands/keys/list.js +65 -0
  19. package/dist/commands/keys/revoke.d.ts +15 -0
  20. package/dist/commands/keys/revoke.js +68 -0
  21. package/dist/commands/login.d.ts +12 -0
  22. package/dist/commands/login.js +114 -0
  23. package/dist/commands/logout.d.ts +10 -0
  24. package/dist/commands/logout.js +20 -0
  25. package/dist/commands/logs/tail.d.ts +17 -0
  26. package/dist/commands/logs/tail.js +183 -0
  27. package/dist/commands/sms/batch.d.ts +16 -0
  28. package/dist/commands/sms/batch.js +163 -0
  29. package/dist/commands/sms/cancel.d.ts +13 -0
  30. package/dist/commands/sms/cancel.js +46 -0
  31. package/dist/commands/sms/get.d.ts +13 -0
  32. package/dist/commands/sms/get.js +51 -0
  33. package/dist/commands/sms/list.d.ts +12 -0
  34. package/dist/commands/sms/list.js +79 -0
  35. package/dist/commands/sms/schedule.d.ts +14 -0
  36. package/dist/commands/sms/schedule.js +91 -0
  37. package/dist/commands/sms/scheduled.d.ts +12 -0
  38. package/dist/commands/sms/scheduled.js +82 -0
  39. package/dist/commands/sms/send.d.ts +13 -0
  40. package/dist/commands/sms/send.js +70 -0
  41. package/dist/commands/webhooks/list.d.ts +10 -0
  42. package/dist/commands/webhooks/list.js +80 -0
  43. package/dist/commands/webhooks/listen.d.ts +20 -0
  44. package/dist/commands/webhooks/listen.js +202 -0
  45. package/dist/commands/whoami.d.ts +10 -0
  46. package/dist/commands/whoami.js +51 -0
  47. package/dist/index.d.ts +26 -0
  48. package/dist/index.js +27 -0
  49. package/dist/lib/api-client.d.ts +52 -0
  50. package/dist/lib/api-client.js +129 -0
  51. package/dist/lib/auth.d.ts +52 -0
  52. package/dist/lib/auth.js +171 -0
  53. package/dist/lib/base-command.d.ts +17 -0
  54. package/dist/lib/base-command.js +60 -0
  55. package/dist/lib/config.d.ts +54 -0
  56. package/dist/lib/config.js +182 -0
  57. package/dist/lib/output.d.ts +43 -0
  58. package/dist/lib/output.js +222 -0
  59. package/oclif.manifest.json +1147 -0
  60. package/package.json +98 -0
@@ -0,0 +1,82 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
3
+ import { apiClient } from "../../lib/api-client.js";
4
+ import { table, json, info, formatStatus, formatPhone, colors, isJsonMode, } from "../../lib/output.js";
5
+ export default class SmsScheduled extends AuthenticatedCommand {
6
+ static description = "List scheduled messages";
7
+ static examples = [
8
+ "<%= config.bin %> sms scheduled",
9
+ "<%= config.bin %> sms scheduled --limit 10",
10
+ "<%= config.bin %> sms scheduled --status scheduled",
11
+ "<%= config.bin %> sms scheduled --json",
12
+ ];
13
+ static flags = {
14
+ ...AuthenticatedCommand.baseFlags,
15
+ limit: Flags.integer({
16
+ char: "l",
17
+ description: "Number of messages to show",
18
+ default: 20,
19
+ }),
20
+ status: Flags.string({
21
+ char: "s",
22
+ description: "Filter by status (scheduled, sent, cancelled, failed)",
23
+ }),
24
+ };
25
+ async run() {
26
+ const { flags } = await this.parse(SmsScheduled);
27
+ const response = await apiClient.get("/api/v1/messages/scheduled", {
28
+ limit: flags.limit,
29
+ ...(flags.status && { status: flags.status }),
30
+ });
31
+ if (isJsonMode()) {
32
+ json(response);
33
+ return;
34
+ }
35
+ if (response.data.length === 0) {
36
+ info("No scheduled messages found");
37
+ return;
38
+ }
39
+ console.log();
40
+ console.log(colors.dim(`Showing ${response.data.length} of ${response.count} scheduled messages`));
41
+ console.log();
42
+ table(response.data, [
43
+ {
44
+ header: "ID",
45
+ key: "id",
46
+ width: 20,
47
+ formatter: (v) => colors.dim(String(v).slice(0, 16) + "..."),
48
+ },
49
+ {
50
+ header: "To",
51
+ key: "to",
52
+ width: 18,
53
+ formatter: (v) => formatPhone(String(v)),
54
+ },
55
+ {
56
+ header: "Status",
57
+ key: "status",
58
+ width: 12,
59
+ formatter: (v) => formatStatus(String(v)),
60
+ },
61
+ {
62
+ header: "Scheduled For",
63
+ key: "scheduledAt",
64
+ width: 20,
65
+ formatter: (v) => {
66
+ const date = new Date(String(v));
67
+ return colors.code(date.toLocaleString());
68
+ },
69
+ },
70
+ {
71
+ header: "Text",
72
+ key: "text",
73
+ width: 25,
74
+ formatter: (v) => {
75
+ const text = String(v);
76
+ return text.length > 22 ? text.slice(0, 22) + "..." : text;
77
+ },
78
+ },
79
+ ]);
80
+ }
81
+ }
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZWR1bGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3Ntcy9zY2hlZHVsZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUNMLEtBQUssRUFDTCxJQUFJLEVBQ0osSUFBSSxFQUNKLFlBQVksRUFDWixXQUFXLEVBQ1gsTUFBTSxFQUNOLFVBQVUsR0FDWCxNQUFNLHFCQUFxQixDQUFDO0FBaUI3QixNQUFNLENBQUMsT0FBTyxPQUFPLFlBQWEsU0FBUSxvQkFBb0I7SUFDNUQsTUFBTSxDQUFDLFdBQVcsR0FBRyx5QkFBeUIsQ0FBQztJQUUvQyxNQUFNLENBQUMsUUFBUSxHQUFHO1FBQ2hCLGlDQUFpQztRQUNqQyw0Q0FBNEM7UUFDNUMsb0RBQW9EO1FBQ3BELHdDQUF3QztLQUN6QyxDQUFDO0lBRUYsTUFBTSxDQUFDLEtBQUssR0FBRztRQUNiLEdBQUcsb0JBQW9CLENBQUMsU0FBUztRQUNqQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQztZQUNuQixJQUFJLEVBQUUsR0FBRztZQUNULFdBQVcsRUFBRSw0QkFBNEI7WUFDekMsT0FBTyxFQUFFLEVBQUU7U0FDWixDQUFDO1FBQ0YsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDbkIsSUFBSSxFQUFFLEdBQUc7WUFDVCxXQUFXLEVBQUUsdURBQXVEO1NBQ3JFLENBQUM7S0FDSCxDQUFDO0lBRUYsS0FBSyxDQUFDLEdBQUc7UUFDUCxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWpELE1BQU0sUUFBUSxHQUFHLE1BQU0sU0FBUyxDQUFDLEdBQUcsQ0FDbEMsNEJBQTRCLEVBQzVCO1lBQ0UsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO1lBQ2xCLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUM5QyxDQUNGLENBQUM7UUFFRixJQUFJLFVBQVUsRUFBRSxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2YsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQ3BDLE9BQU87UUFDVCxDQUFDO1FBRUQsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FDVCxNQUFNLENBQUMsR0FBRyxDQUNSLFdBQVcsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLE9BQU8sUUFBUSxDQUFDLEtBQUsscUJBQXFCLENBQzFFLENBQ0YsQ0FBQztRQUNGLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUVkLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO1lBQ25CO2dCQUNFLE1BQU0sRUFBRSxJQUFJO2dCQUNaLEdBQUcsRUFBRSxJQUFJO2dCQUNULEtBQUssRUFBRSxFQUFFO2dCQUNULFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUM7YUFDN0Q7WUFDRDtnQkFDRSxNQUFNLEVBQUUsSUFBSTtnQkFDWixHQUFHLEVBQUUsSUFBSTtnQkFDVCxLQUFLLEVBQUUsRUFBRTtnQkFDVCxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDekM7WUFDRDtnQkFDRSxNQUFNLEVBQUUsUUFBUTtnQkFDaEIsR0FBRyxFQUFFLFFBQVE7Z0JBQ2IsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsU0FBUyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzFDO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLGVBQWU7Z0JBQ3ZCLEdBQUcsRUFBRSxhQUFhO2dCQUNsQixLQUFLLEVBQUUsRUFBRTtnQkFDVCxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtvQkFDZixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDakMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QyxDQUFDO2FBQ0Y7WUFDRDtnQkFDRSxNQUFNLEVBQUUsTUFBTTtnQkFDZCxHQUFHLEVBQUUsTUFBTTtnQkFDWCxLQUFLLEVBQUUsRUFBRTtnQkFDVCxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtvQkFDZixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZCLE9BQU8sSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUM3RCxDQUFDO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRmxhZ3MgfSBmcm9tIFwiQG9jbGlmL2NvcmVcIjtcbmltcG9ydCB7IEF1dGhlbnRpY2F0ZWRDb21tYW5kIH0gZnJvbSBcIi4uLy4uL2xpYi9iYXNlLWNvbW1hbmQuanNcIjtcbmltcG9ydCB7IGFwaUNsaWVudCB9IGZyb20gXCIuLi8uLi9saWIvYXBpLWNsaWVudC5qc1wiO1xuaW1wb3J0IHtcbiAgdGFibGUsXG4gIGpzb24sXG4gIGluZm8sXG4gIGZvcm1hdFN0YXR1cyxcbiAgZm9ybWF0UGhvbmUsXG4gIGNvbG9ycyxcbiAgaXNKc29uTW9kZSxcbn0gZnJvbSBcIi4uLy4uL2xpYi9vdXRwdXQuanNcIjtcblxuaW50ZXJmYWNlIFNjaGVkdWxlZE1lc3NhZ2Uge1xuICBpZDogc3RyaW5nO1xuICB0bzogc3RyaW5nO1xuICBmcm9tPzogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xuICBzY2hlZHVsZWRBdDogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIExpc3RTY2hlZHVsZWRSZXNwb25zZSB7XG4gIGRhdGE6IFNjaGVkdWxlZE1lc3NhZ2VbXTtcbiAgY291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU21zU2NoZWR1bGVkIGV4dGVuZHMgQXV0aGVudGljYXRlZENvbW1hbmQge1xuICBzdGF0aWMgZGVzY3JpcHRpb24gPSBcIkxpc3Qgc2NoZWR1bGVkIG1lc3NhZ2VzXCI7XG5cbiAgc3RhdGljIGV4YW1wbGVzID0gW1xuICAgIFwiPCU9IGNvbmZpZy5iaW4gJT4gc21zIHNjaGVkdWxlZFwiLFxuICAgIFwiPCU9IGNvbmZpZy5iaW4gJT4gc21zIHNjaGVkdWxlZCAtLWxpbWl0IDEwXCIsXG4gICAgXCI8JT0gY29uZmlnLmJpbiAlPiBzbXMgc2NoZWR1bGVkIC0tc3RhdHVzIHNjaGVkdWxlZFwiLFxuICAgIFwiPCU9IGNvbmZpZy5iaW4gJT4gc21zIHNjaGVkdWxlZCAtLWpzb25cIixcbiAgXTtcblxuICBzdGF0aWMgZmxhZ3MgPSB7XG4gICAgLi4uQXV0aGVudGljYXRlZENvbW1hbmQuYmFzZUZsYWdzLFxuICAgIGxpbWl0OiBGbGFncy5pbnRlZ2VyKHtcbiAgICAgIGNoYXI6IFwibFwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiTnVtYmVyIG9mIG1lc3NhZ2VzIHRvIHNob3dcIixcbiAgICAgIGRlZmF1bHQ6IDIwLFxuICAgIH0pLFxuICAgIHN0YXR1czogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGNoYXI6IFwic1wiLFxuICAgICAgZGVzY3JpcHRpb246IFwiRmlsdGVyIGJ5IHN0YXR1cyAoc2NoZWR1bGVkLCBzZW50LCBjYW5jZWxsZWQsIGZhaWxlZClcIixcbiAgICB9KSxcbiAgfTtcblxuICBhc3luYyBydW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBmbGFncyB9ID0gYXdhaXQgdGhpcy5wYXJzZShTbXNTY2hlZHVsZWQpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBhcGlDbGllbnQuZ2V0PExpc3RTY2hlZHVsZWRSZXNwb25zZT4oXG4gICAgICBcIi9hcGkvdjEvbWVzc2FnZXMvc2NoZWR1bGVkXCIsXG4gICAgICB7XG4gICAgICAgIGxpbWl0OiBmbGFncy5saW1pdCxcbiAgICAgICAgLi4uKGZsYWdzLnN0YXR1cyAmJiB7IHN0YXR1czogZmxhZ3Muc3RhdHVzIH0pLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgaWYgKGlzSnNvbk1vZGUoKSkge1xuICAgICAganNvbihyZXNwb25zZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHJlc3BvbnNlLmRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICBpbmZvKFwiTm8gc2NoZWR1bGVkIG1lc3NhZ2VzIGZvdW5kXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCk7XG4gICAgY29uc29sZS5sb2coXG4gICAgICBjb2xvcnMuZGltKFxuICAgICAgICBgU2hvd2luZyAke3Jlc3BvbnNlLmRhdGEubGVuZ3RofSBvZiAke3Jlc3BvbnNlLmNvdW50fSBzY2hlZHVsZWQgbWVzc2FnZXNgLFxuICAgICAgKSxcbiAgICApO1xuICAgIGNvbnNvbGUubG9nKCk7XG5cbiAgICB0YWJsZShyZXNwb25zZS5kYXRhLCBbXG4gICAgICB7XG4gICAgICAgIGhlYWRlcjogXCJJRFwiLFxuICAgICAgICBrZXk6IFwiaWRcIixcbiAgICAgICAgd2lkdGg6IDIwLFxuICAgICAgICBmb3JtYXR0ZXI6ICh2KSA9PiBjb2xvcnMuZGltKFN0cmluZyh2KS5zbGljZSgwLCAxNikgKyBcIi4uLlwiKSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGhlYWRlcjogXCJUb1wiLFxuICAgICAgICBrZXk6IFwidG9cIixcbiAgICAgICAgd2lkdGg6IDE4LFxuICAgICAgICBmb3JtYXR0ZXI6ICh2KSA9PiBmb3JtYXRQaG9uZShTdHJpbmcodikpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaGVhZGVyOiBcIlN0YXR1c1wiLFxuICAgICAgICBrZXk6IFwic3RhdHVzXCIsXG4gICAgICAgIHdpZHRoOiAxMixcbiAgICAgICAgZm9ybWF0dGVyOiAodikgPT4gZm9ybWF0U3RhdHVzKFN0cmluZyh2KSksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBoZWFkZXI6IFwiU2NoZWR1bGVkIEZvclwiLFxuICAgICAgICBrZXk6IFwic2NoZWR1bGVkQXRcIixcbiAgICAgICAgd2lkdGg6IDIwLFxuICAgICAgICBmb3JtYXR0ZXI6ICh2KSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKFN0cmluZyh2KSk7XG4gICAgICAgICAgcmV0dXJuIGNvbG9ycy5jb2RlKGRhdGUudG9Mb2NhbGVTdHJpbmcoKSk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBoZWFkZXI6IFwiVGV4dFwiLFxuICAgICAgICBrZXk6IFwidGV4dFwiLFxuICAgICAgICB3aWR0aDogMjUsXG4gICAgICAgIGZvcm1hdHRlcjogKHYpID0+IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gU3RyaW5nKHYpO1xuICAgICAgICAgIHJldHVybiB0ZXh0Lmxlbmd0aCA+IDIyID8gdGV4dC5zbGljZSgwLCAyMikgKyBcIi4uLlwiIDogdGV4dDtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,13 @@
1
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
2
+ export default class SmsSend extends AuthenticatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ to: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ text: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ from: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
+ json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
+ quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,70 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
3
+ import { apiClient } from "../../lib/api-client.js";
4
+ import { success, error, spinner, formatStatus, formatCredits, json, isJsonMode, } from "../../lib/output.js";
5
+ export default class SmsSend extends AuthenticatedCommand {
6
+ static description = "Send an SMS message";
7
+ static examples = [
8
+ '<%= config.bin %> sms send --to +15551234567 --text "Hello!"',
9
+ '<%= config.bin %> sms send --to +15551234567 --text "Hello!" --from "Sendly"',
10
+ '<%= config.bin %> sms send --to +15551234567 --text "Hello!" --json',
11
+ ];
12
+ static flags = {
13
+ ...AuthenticatedCommand.baseFlags,
14
+ to: Flags.string({
15
+ char: "t",
16
+ description: "Recipient phone number (E.164 format)",
17
+ required: true,
18
+ }),
19
+ text: Flags.string({
20
+ char: "m",
21
+ description: "Message text",
22
+ required: true,
23
+ }),
24
+ from: Flags.string({
25
+ char: "f",
26
+ description: "Sender ID or phone number",
27
+ }),
28
+ };
29
+ async run() {
30
+ const { flags } = await this.parse(SmsSend);
31
+ // Validate phone number format
32
+ if (!/^\+[1-9]\d{1,14}$/.test(flags.to)) {
33
+ error("Invalid phone number format", {
34
+ hint: "Use E.164 format: +15551234567",
35
+ });
36
+ this.exit(1);
37
+ }
38
+ // Validate message text
39
+ if (!flags.text.trim()) {
40
+ error("Message text cannot be empty");
41
+ this.exit(1);
42
+ }
43
+ const spin = spinner("Sending message...");
44
+ spin.start();
45
+ try {
46
+ const response = await apiClient.post("/api/v1/messages", {
47
+ to: flags.to,
48
+ text: flags.text,
49
+ ...(flags.from && { from: flags.from }),
50
+ });
51
+ spin.stop();
52
+ if (isJsonMode()) {
53
+ json(response);
54
+ return;
55
+ }
56
+ success("Message sent", {
57
+ ID: response.id,
58
+ To: response.to,
59
+ Status: formatStatus(response.status),
60
+ Segments: response.segments,
61
+ Credits: formatCredits(response.creditsUsed),
62
+ });
63
+ }
64
+ catch (err) {
65
+ spin.stop();
66
+ throw err;
67
+ }
68
+ }
69
+ }
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9zbXMvc2VuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQ0wsT0FBTyxFQUNQLEtBQUssRUFDTCxPQUFPLEVBRVAsWUFBWSxFQUNaLGFBQWEsRUFDYixJQUFJLEVBQ0osVUFBVSxHQUNYLE1BQU0scUJBQXFCLENBQUM7QUFhN0IsTUFBTSxDQUFDLE9BQU8sT0FBTyxPQUFRLFNBQVEsb0JBQW9CO0lBQ3ZELE1BQU0sQ0FBQyxXQUFXLEdBQUcscUJBQXFCLENBQUM7SUFFM0MsTUFBTSxDQUFDLFFBQVEsR0FBRztRQUNoQiw4REFBOEQ7UUFDOUQsOEVBQThFO1FBQzlFLHFFQUFxRTtLQUN0RSxDQUFDO0lBRUYsTUFBTSxDQUFDLEtBQUssR0FBRztRQUNiLEdBQUcsb0JBQW9CLENBQUMsU0FBUztRQUNqQyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUNmLElBQUksRUFBRSxHQUFHO1lBQ1QsV0FBVyxFQUFFLHVDQUF1QztZQUNwRCxRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUM7UUFDRixJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUNqQixJQUFJLEVBQUUsR0FBRztZQUNULFdBQVcsRUFBRSxjQUFjO1lBQzNCLFFBQVEsRUFBRSxJQUFJO1NBQ2YsQ0FBQztRQUNGLElBQUksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ2pCLElBQUksRUFBRSxHQUFHO1lBQ1QsV0FBVyxFQUFFLDJCQUEyQjtTQUN6QyxDQUFDO0tBQ0gsQ0FBQztJQUVGLEtBQUssQ0FBQyxHQUFHO1FBQ1AsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU1QywrQkFBK0I7UUFDL0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN4QyxLQUFLLENBQUMsNkJBQTZCLEVBQUU7Z0JBQ25DLElBQUksRUFBRSxnQ0FBZ0M7YUFDdkMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNmLENBQUM7UUFFRCx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2YsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUViLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sU0FBUyxDQUFDLElBQUksQ0FDbkMsa0JBQWtCLEVBQ2xCO2dCQUNFLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDWixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUN4QyxDQUNGLENBQUM7WUFFRixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFWixJQUFJLFVBQVUsRUFBRSxFQUFFLENBQUM7Z0JBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDZixPQUFPO1lBQ1QsQ0FBQztZQUVELE9BQU8sQ0FBQyxjQUFjLEVBQUU7Z0JBQ3RCLEVBQUUsRUFBRSxRQUFRLENBQUMsRUFBRTtnQkFDZixFQUFFLEVBQUUsUUFBUSxDQUFDLEVBQUU7Z0JBQ2YsTUFBTSxFQUFFLFlBQVksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO2dCQUNyQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVE7Z0JBQzNCLE9BQU8sRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQzthQUM3QyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNaLE1BQU0sR0FBRyxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGbGFncyB9IGZyb20gXCJAb2NsaWYvY29yZVwiO1xuaW1wb3J0IHsgQXV0aGVudGljYXRlZENvbW1hbmQgfSBmcm9tIFwiLi4vLi4vbGliL2Jhc2UtY29tbWFuZC5qc1wiO1xuaW1wb3J0IHsgYXBpQ2xpZW50IH0gZnJvbSBcIi4uLy4uL2xpYi9hcGktY2xpZW50LmpzXCI7XG5pbXBvcnQge1xuICBzdWNjZXNzLFxuICBlcnJvcixcbiAgc3Bpbm5lcixcbiAgY29sb3JzLFxuICBmb3JtYXRTdGF0dXMsXG4gIGZvcm1hdENyZWRpdHMsXG4gIGpzb24sXG4gIGlzSnNvbk1vZGUsXG59IGZyb20gXCIuLi8uLi9saWIvb3V0cHV0LmpzXCI7XG5cbmludGVyZmFjZSBTZW5kTWVzc2FnZVJlc3BvbnNlIHtcbiAgaWQ6IHN0cmluZztcbiAgdG86IHN0cmluZztcbiAgZnJvbTogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xuICBzZWdtZW50czogbnVtYmVyO1xuICBjcmVkaXRzVXNlZDogbnVtYmVyO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU21zU2VuZCBleHRlbmRzIEF1dGhlbnRpY2F0ZWRDb21tYW5kIHtcbiAgc3RhdGljIGRlc2NyaXB0aW9uID0gXCJTZW5kIGFuIFNNUyBtZXNzYWdlXCI7XG5cbiAgc3RhdGljIGV4YW1wbGVzID0gW1xuICAgICc8JT0gY29uZmlnLmJpbiAlPiBzbXMgc2VuZCAtLXRvICsxNTU1MTIzNDU2NyAtLXRleHQgXCJIZWxsbyFcIicsXG4gICAgJzwlPSBjb25maWcuYmluICU+IHNtcyBzZW5kIC0tdG8gKzE1NTUxMjM0NTY3IC0tdGV4dCBcIkhlbGxvIVwiIC0tZnJvbSBcIlNlbmRseVwiJyxcbiAgICAnPCU9IGNvbmZpZy5iaW4gJT4gc21zIHNlbmQgLS10byArMTU1NTEyMzQ1NjcgLS10ZXh0IFwiSGVsbG8hXCIgLS1qc29uJyxcbiAgXTtcblxuICBzdGF0aWMgZmxhZ3MgPSB7XG4gICAgLi4uQXV0aGVudGljYXRlZENvbW1hbmQuYmFzZUZsYWdzLFxuICAgIHRvOiBGbGFncy5zdHJpbmcoe1xuICAgICAgY2hhcjogXCJ0XCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJSZWNpcGllbnQgcGhvbmUgbnVtYmVyIChFLjE2NCBmb3JtYXQpXCIsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9KSxcbiAgICB0ZXh0OiBGbGFncy5zdHJpbmcoe1xuICAgICAgY2hhcjogXCJtXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJNZXNzYWdlIHRleHRcIixcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0pLFxuICAgIGZyb206IEZsYWdzLnN0cmluZyh7XG4gICAgICBjaGFyOiBcImZcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlNlbmRlciBJRCBvciBwaG9uZSBudW1iZXJcIixcbiAgICB9KSxcbiAgfTtcblxuICBhc3luYyBydW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBmbGFncyB9ID0gYXdhaXQgdGhpcy5wYXJzZShTbXNTZW5kKTtcblxuICAgIC8vIFZhbGlkYXRlIHBob25lIG51bWJlciBmb3JtYXRcbiAgICBpZiAoIS9eXFwrWzEtOV1cXGR7MSwxNH0kLy50ZXN0KGZsYWdzLnRvKSkge1xuICAgICAgZXJyb3IoXCJJbnZhbGlkIHBob25lIG51bWJlciBmb3JtYXRcIiwge1xuICAgICAgICBoaW50OiBcIlVzZSBFLjE2NCBmb3JtYXQ6ICsxNTU1MTIzNDU2N1wiLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmV4aXQoMSk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbWVzc2FnZSB0ZXh0XG4gICAgaWYgKCFmbGFncy50ZXh0LnRyaW0oKSkge1xuICAgICAgZXJyb3IoXCJNZXNzYWdlIHRleHQgY2Fubm90IGJlIGVtcHR5XCIpO1xuICAgICAgdGhpcy5leGl0KDEpO1xuICAgIH1cblxuICAgIGNvbnN0IHNwaW4gPSBzcGlubmVyKFwiU2VuZGluZyBtZXNzYWdlLi4uXCIpO1xuICAgIHNwaW4uc3RhcnQoKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGFwaUNsaWVudC5wb3N0PFNlbmRNZXNzYWdlUmVzcG9uc2U+KFxuICAgICAgICBcIi9hcGkvdjEvbWVzc2FnZXNcIixcbiAgICAgICAge1xuICAgICAgICAgIHRvOiBmbGFncy50byxcbiAgICAgICAgICB0ZXh0OiBmbGFncy50ZXh0LFxuICAgICAgICAgIC4uLihmbGFncy5mcm9tICYmIHsgZnJvbTogZmxhZ3MuZnJvbSB9KSxcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgc3Bpbi5zdG9wKCk7XG5cbiAgICAgIGlmIChpc0pzb25Nb2RlKCkpIHtcbiAgICAgICAganNvbihyZXNwb25zZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc3VjY2VzcyhcIk1lc3NhZ2Ugc2VudFwiLCB7XG4gICAgICAgIElEOiByZXNwb25zZS5pZCxcbiAgICAgICAgVG86IHJlc3BvbnNlLnRvLFxuICAgICAgICBTdGF0dXM6IGZvcm1hdFN0YXR1cyhyZXNwb25zZS5zdGF0dXMpLFxuICAgICAgICBTZWdtZW50czogcmVzcG9uc2Uuc2VnbWVudHMsXG4gICAgICAgIENyZWRpdHM6IGZvcm1hdENyZWRpdHMocmVzcG9uc2UuY3JlZGl0c1VzZWQpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBzcGluLnN0b3AoKTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,10 @@
1
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
2
+ export default class WebhooksList extends AuthenticatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
+ quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,80 @@
1
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
2
+ import { apiClient } from "../../lib/api-client.js";
3
+ import { table, json, info, colors, isJsonMode, } from "../../lib/output.js";
4
+ export default class WebhooksList extends AuthenticatedCommand {
5
+ static description = "List configured webhooks";
6
+ static examples = [
7
+ "<%= config.bin %> webhooks list",
8
+ "<%= config.bin %> webhooks list --json",
9
+ ];
10
+ static flags = {
11
+ ...AuthenticatedCommand.baseFlags,
12
+ };
13
+ async run() {
14
+ const webhooks = await apiClient.get("/api/webhooks");
15
+ if (isJsonMode()) {
16
+ json(webhooks);
17
+ return;
18
+ }
19
+ if (webhooks.length === 0) {
20
+ info("No webhooks configured");
21
+ console.log();
22
+ console.log(` Create one with ${colors.code("sendly webhooks create")}`);
23
+ console.log(` Or test locally with ${colors.code("sendly webhooks listen")}`);
24
+ return;
25
+ }
26
+ console.log();
27
+ table(webhooks, [
28
+ {
29
+ header: "ID",
30
+ key: "id",
31
+ width: 18,
32
+ formatter: (v) => colors.dim(String(v).slice(0, 15) + "..."),
33
+ },
34
+ {
35
+ header: "URL",
36
+ key: "url",
37
+ width: 35,
38
+ formatter: (v) => {
39
+ const url = String(v);
40
+ return url.length > 32 ? url.slice(0, 32) + "..." : url;
41
+ },
42
+ },
43
+ {
44
+ header: "Events",
45
+ key: "events",
46
+ width: 15,
47
+ formatter: (v) => {
48
+ const events = v;
49
+ return events.length > 2
50
+ ? `${events.length} events`
51
+ : events.join(", ").replace(/message\./g, "");
52
+ },
53
+ },
54
+ {
55
+ header: "Status",
56
+ key: "isActive",
57
+ width: 10,
58
+ formatter: (v) => v ? colors.success("active") : colors.error("disabled"),
59
+ },
60
+ {
61
+ header: "Circuit",
62
+ key: "circuitState",
63
+ width: 10,
64
+ formatter: (v) => {
65
+ switch (v) {
66
+ case "closed":
67
+ return colors.success("closed");
68
+ case "open":
69
+ return colors.error("open");
70
+ case "half_open":
71
+ return colors.warning("half_open");
72
+ default:
73
+ return String(v);
74
+ }
75
+ },
76
+ },
77
+ ]);
78
+ }
79
+ }
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy93ZWJob29rcy9saXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQ0wsS0FBSyxFQUNMLElBQUksRUFDSixJQUFJLEVBRUosTUFBTSxFQUNOLFVBQVUsR0FDWCxNQUFNLHFCQUFxQixDQUFDO0FBYTdCLE1BQU0sQ0FBQyxPQUFPLE9BQU8sWUFBYSxTQUFRLG9CQUFvQjtJQUM1RCxNQUFNLENBQUMsV0FBVyxHQUFHLDBCQUEwQixDQUFDO0lBRWhELE1BQU0sQ0FBQyxRQUFRLEdBQUc7UUFDaEIsaUNBQWlDO1FBQ2pDLHdDQUF3QztLQUN6QyxDQUFDO0lBRUYsTUFBTSxDQUFDLEtBQUssR0FBRztRQUNiLEdBQUcsb0JBQW9CLENBQUMsU0FBUztLQUNsQyxDQUFDO0lBRUYsS0FBSyxDQUFDLEdBQUc7UUFDUCxNQUFNLFFBQVEsR0FBRyxNQUFNLFNBQVMsQ0FBQyxHQUFHLENBQVksZUFBZSxDQUFDLENBQUM7UUFFakUsSUFBSSxVQUFVLEVBQUUsRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNmLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQy9CLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDMUUsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsTUFBTSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMvRSxPQUFPO1FBQ1QsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUVkLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDZDtnQkFDRSxNQUFNLEVBQUUsSUFBSTtnQkFDWixHQUFHLEVBQUUsSUFBSTtnQkFDVCxLQUFLLEVBQUUsRUFBRTtnQkFDVCxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDO2FBQzdEO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsR0FBRyxFQUFFLEtBQUs7Z0JBQ1YsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsU0FBUyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7b0JBQ2YsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN0QixPQUFPLEdBQUcsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDMUQsQ0FBQzthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLFFBQVE7Z0JBQ2hCLEdBQUcsRUFBRSxRQUFRO2dCQUNiLEtBQUssRUFBRSxFQUFFO2dCQUNULFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO29CQUNmLE1BQU0sTUFBTSxHQUFHLENBQWEsQ0FBQztvQkFDN0IsT0FBTyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7d0JBQ3RCLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLFNBQVM7d0JBQzNCLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ2xELENBQUM7YUFDRjtZQUNEO2dCQUNFLE1BQU0sRUFBRSxRQUFRO2dCQUNoQixHQUFHLEVBQUUsVUFBVTtnQkFDZixLQUFLLEVBQUUsRUFBRTtnQkFDVCxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNmLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7YUFDMUQ7WUFDRDtnQkFDRSxNQUFNLEVBQUUsU0FBUztnQkFDakIsR0FBRyxFQUFFLGNBQWM7Z0JBQ25CLEtBQUssRUFBRSxFQUFFO2dCQUNULFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO29CQUNmLFFBQVEsQ0FBQyxFQUFFLENBQUM7d0JBQ1YsS0FBSyxRQUFROzRCQUNYLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDbEMsS0FBSyxNQUFNOzRCQUNULE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDOUIsS0FBSyxXQUFXOzRCQUNkLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQzt3QkFDckM7NEJBQ0UsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3JCLENBQUM7Z0JBQ0gsQ0FBQzthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEF1dGhlbnRpY2F0ZWRDb21tYW5kIH0gZnJvbSBcIi4uLy4uL2xpYi9iYXNlLWNvbW1hbmQuanNcIjtcbmltcG9ydCB7IGFwaUNsaWVudCB9IGZyb20gXCIuLi8uLi9saWIvYXBpLWNsaWVudC5qc1wiO1xuaW1wb3J0IHtcbiAgdGFibGUsXG4gIGpzb24sXG4gIGluZm8sXG4gIGZvcm1hdFN0YXR1cyxcbiAgY29sb3JzLFxuICBpc0pzb25Nb2RlLFxufSBmcm9tIFwiLi4vLi4vbGliL291dHB1dC5qc1wiO1xuXG5pbnRlcmZhY2UgV2ViaG9vayB7XG4gIGlkOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgZXZlbnRzOiBzdHJpbmdbXTtcbiAgaXNBY3RpdmU6IGJvb2xlYW47XG4gIGZhaWx1cmVDb3VudDogbnVtYmVyO1xuICBjaXJjdWl0U3RhdGU6IFwiY2xvc2VkXCIgfCBcIm9wZW5cIiB8IFwiaGFsZl9vcGVuXCI7XG4gIGNyZWF0ZWRBdDogc3RyaW5nO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBXZWJob29rc0xpc3QgZXh0ZW5kcyBBdXRoZW50aWNhdGVkQ29tbWFuZCB7XG4gIHN0YXRpYyBkZXNjcmlwdGlvbiA9IFwiTGlzdCBjb25maWd1cmVkIHdlYmhvb2tzXCI7XG5cbiAgc3RhdGljIGV4YW1wbGVzID0gW1xuICAgIFwiPCU9IGNvbmZpZy5iaW4gJT4gd2ViaG9va3MgbGlzdFwiLFxuICAgIFwiPCU9IGNvbmZpZy5iaW4gJT4gd2ViaG9va3MgbGlzdCAtLWpzb25cIixcbiAgXTtcblxuICBzdGF0aWMgZmxhZ3MgPSB7XG4gICAgLi4uQXV0aGVudGljYXRlZENvbW1hbmQuYmFzZUZsYWdzLFxuICB9O1xuXG4gIGFzeW5jIHJ1bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB3ZWJob29rcyA9IGF3YWl0IGFwaUNsaWVudC5nZXQ8V2ViaG9va1tdPihcIi9hcGkvd2ViaG9va3NcIik7XG5cbiAgICBpZiAoaXNKc29uTW9kZSgpKSB7XG4gICAgICBqc29uKHdlYmhvb2tzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAod2ViaG9va3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBpbmZvKFwiTm8gd2ViaG9va3MgY29uZmlndXJlZFwiKTtcbiAgICAgIGNvbnNvbGUubG9nKCk7XG4gICAgICBjb25zb2xlLmxvZyhgICBDcmVhdGUgb25lIHdpdGggJHtjb2xvcnMuY29kZShcInNlbmRseSB3ZWJob29rcyBjcmVhdGVcIil9YCk7XG4gICAgICBjb25zb2xlLmxvZyhgICBPciB0ZXN0IGxvY2FsbHkgd2l0aCAke2NvbG9ycy5jb2RlKFwic2VuZGx5IHdlYmhvb2tzIGxpc3RlblwiKX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygpO1xuXG4gICAgdGFibGUod2ViaG9va3MsIFtcbiAgICAgIHtcbiAgICAgICAgaGVhZGVyOiBcIklEXCIsXG4gICAgICAgIGtleTogXCJpZFwiLFxuICAgICAgICB3aWR0aDogMTgsXG4gICAgICAgIGZvcm1hdHRlcjogKHYpID0+IGNvbG9ycy5kaW0oU3RyaW5nKHYpLnNsaWNlKDAsIDE1KSArIFwiLi4uXCIpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaGVhZGVyOiBcIlVSTFwiLFxuICAgICAgICBrZXk6IFwidXJsXCIsXG4gICAgICAgIHdpZHRoOiAzNSxcbiAgICAgICAgZm9ybWF0dGVyOiAodikgPT4ge1xuICAgICAgICAgIGNvbnN0IHVybCA9IFN0cmluZyh2KTtcbiAgICAgICAgICByZXR1cm4gdXJsLmxlbmd0aCA+IDMyID8gdXJsLnNsaWNlKDAsIDMyKSArIFwiLi4uXCIgOiB1cmw7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBoZWFkZXI6IFwiRXZlbnRzXCIsXG4gICAgICAgIGtleTogXCJldmVudHNcIixcbiAgICAgICAgd2lkdGg6IDE1LFxuICAgICAgICBmb3JtYXR0ZXI6ICh2KSA9PiB7XG4gICAgICAgICAgY29uc3QgZXZlbnRzID0gdiBhcyBzdHJpbmdbXTtcbiAgICAgICAgICByZXR1cm4gZXZlbnRzLmxlbmd0aCA+IDJcbiAgICAgICAgICAgID8gYCR7ZXZlbnRzLmxlbmd0aH0gZXZlbnRzYFxuICAgICAgICAgICAgOiBldmVudHMuam9pbihcIiwgXCIpLnJlcGxhY2UoL21lc3NhZ2VcXC4vZywgXCJcIik7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBoZWFkZXI6IFwiU3RhdHVzXCIsXG4gICAgICAgIGtleTogXCJpc0FjdGl2ZVwiLFxuICAgICAgICB3aWR0aDogMTAsXG4gICAgICAgIGZvcm1hdHRlcjogKHYpID0+XG4gICAgICAgICAgdiA/IGNvbG9ycy5zdWNjZXNzKFwiYWN0aXZlXCIpIDogY29sb3JzLmVycm9yKFwiZGlzYWJsZWRcIiksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBoZWFkZXI6IFwiQ2lyY3VpdFwiLFxuICAgICAgICBrZXk6IFwiY2lyY3VpdFN0YXRlXCIsXG4gICAgICAgIHdpZHRoOiAxMCxcbiAgICAgICAgZm9ybWF0dGVyOiAodikgPT4ge1xuICAgICAgICAgIHN3aXRjaCAodikge1xuICAgICAgICAgICAgY2FzZSBcImNsb3NlZFwiOlxuICAgICAgICAgICAgICByZXR1cm4gY29sb3JzLnN1Y2Nlc3MoXCJjbG9zZWRcIik7XG4gICAgICAgICAgICBjYXNlIFwib3BlblwiOlxuICAgICAgICAgICAgICByZXR1cm4gY29sb3JzLmVycm9yKFwib3BlblwiKTtcbiAgICAgICAgICAgIGNhc2UgXCJoYWxmX29wZW5cIjpcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbG9ycy53YXJuaW5nKFwiaGFsZl9vcGVuXCIpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZyh2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,20 @@
1
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
2
+ export default class WebhooksListen extends AuthenticatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ forward: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ events: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ port: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
+ json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
+ quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
11
+ };
12
+ private tunnel;
13
+ private webhookId;
14
+ run(): Promise<void>;
15
+ private pollEvents;
16
+ private displayEvent;
17
+ private forwardEvent;
18
+ private generateSignature;
19
+ private cleanup;
20
+ }
@@ -0,0 +1,202 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { AuthenticatedCommand } from "../../lib/base-command.js";
3
+ import { apiClient } from "../../lib/api-client.js";
4
+ import { error, warn, colors, spinner, } from "../../lib/output.js";
5
+ import { getConfigValue } from "../../lib/config.js";
6
+ import localtunnel from "localtunnel";
7
+ export default class WebhooksListen extends AuthenticatedCommand {
8
+ static description = "Listen for webhooks locally (like Stripe CLI). Creates a secure tunnel to forward events to your local server.";
9
+ static examples = [
10
+ "<%= config.bin %> webhooks listen",
11
+ "<%= config.bin %> webhooks listen --forward http://localhost:3000/webhook",
12
+ "<%= config.bin %> webhooks listen --events message.delivered,message.failed",
13
+ ];
14
+ static flags = {
15
+ ...AuthenticatedCommand.baseFlags,
16
+ forward: Flags.string({
17
+ char: "f",
18
+ description: "Local URL to forward events to",
19
+ default: "http://localhost:3000/webhook",
20
+ }),
21
+ events: Flags.string({
22
+ char: "e",
23
+ description: "Comma-separated list of events to listen for",
24
+ default: "message.sent,message.delivered,message.failed,message.bounced",
25
+ }),
26
+ port: Flags.integer({
27
+ char: "p",
28
+ description: "Local port for the tunnel (auto-detected from forward URL if not specified)",
29
+ }),
30
+ };
31
+ tunnel = null;
32
+ webhookId = null;
33
+ async run() {
34
+ const { flags } = await this.parse(WebhooksListen);
35
+ const forwardUrl = new URL(flags.forward);
36
+ const localPort = flags.port || parseInt(forwardUrl.port) || 3000;
37
+ const events = flags.events.split(",").map((e) => e.trim());
38
+ const spin = spinner("Starting webhook listener...");
39
+ spin.start();
40
+ try {
41
+ // Create localtunnel
42
+ this.tunnel = await localtunnel({
43
+ port: localPort,
44
+ subdomain: `sendly-${Date.now().toString(36)}`,
45
+ });
46
+ const tunnelUrl = this.tunnel.url;
47
+ spin.succeed("Tunnel established");
48
+ // Register temporary webhook with Sendly
49
+ const webhookResponse = await apiClient.post("/api/cli/webhooks/listen", {
50
+ url: `${tunnelUrl}/cli-webhook`,
51
+ events,
52
+ forwardUrl: flags.forward,
53
+ });
54
+ this.webhookId = webhookResponse.id;
55
+ const secret = webhookResponse.secret;
56
+ // Display connection info
57
+ console.log();
58
+ console.log(colors.bold(colors.primary("Webhook listener ready!")));
59
+ console.log();
60
+ console.log(` ${colors.dim("Tunnel URL:")} ${colors.code(tunnelUrl)}`);
61
+ console.log(` ${colors.dim("Forwarding to:")} ${colors.code(flags.forward)}`);
62
+ console.log(` ${colors.dim("Events:")} ${events.join(", ")}`);
63
+ console.log();
64
+ console.log(` ${colors.dim("Webhook Secret:")}`);
65
+ console.log(` ${colors.primary(secret)}`);
66
+ console.log();
67
+ console.log(colors.dim("Use this secret to verify webhook signatures in your app."));
68
+ console.log();
69
+ console.log(colors.bold("Waiting for events..."));
70
+ console.log(colors.dim("─".repeat(60)));
71
+ console.log();
72
+ // Set up event forwarding
73
+ this.tunnel.on("request", (info) => {
74
+ // This is just for logging - actual forwarding happens server-side
75
+ });
76
+ // Handle tunnel close
77
+ this.tunnel.on("close", () => {
78
+ warn("Tunnel closed");
79
+ this.cleanup();
80
+ process.exit(0);
81
+ });
82
+ this.tunnel.on("error", (err) => {
83
+ error(`Tunnel error: ${err.message}`);
84
+ });
85
+ // Poll for events and display them
86
+ await this.pollEvents(flags.forward, secret);
87
+ }
88
+ catch (err) {
89
+ spin.fail("Failed to start listener");
90
+ throw err;
91
+ }
92
+ }
93
+ async pollEvents(forwardUrl, secret) {
94
+ const baseUrl = getConfigValue("baseUrl") || "https://sendly.live";
95
+ // Set up SSE connection for real-time events
96
+ const eventSource = new EventSource(`${baseUrl}/api/cli/webhooks/events?webhookId=${this.webhookId}`, {
97
+ // @ts-ignore - headers not in type but supported
98
+ headers: {
99
+ Authorization: `Bearer ${getConfigValue("apiKey") || getConfigValue("accessToken")}`,
100
+ },
101
+ });
102
+ // Fallback to polling if SSE not available
103
+ const pollInterval = setInterval(async () => {
104
+ try {
105
+ const events = await apiClient.get(`/api/cli/webhooks/events?webhookId=${this.webhookId}&since=${Date.now() - 5000}`);
106
+ for (const event of events) {
107
+ this.displayEvent(event);
108
+ await this.forwardEvent(forwardUrl, event, secret);
109
+ }
110
+ }
111
+ catch {
112
+ // Ignore polling errors
113
+ }
114
+ }, 2000);
115
+ // Handle graceful shutdown
116
+ const cleanup = () => {
117
+ clearInterval(pollInterval);
118
+ this.cleanup();
119
+ process.exit(0);
120
+ };
121
+ process.on("SIGINT", cleanup);
122
+ process.on("SIGTERM", cleanup);
123
+ // Keep process alive
124
+ await new Promise(() => { });
125
+ }
126
+ displayEvent(event) {
127
+ const timestamp = new Date(event.created * 1000).toLocaleTimeString();
128
+ const eventType = event.type;
129
+ let statusColor = colors.info;
130
+ if (eventType.includes("delivered"))
131
+ statusColor = colors.success;
132
+ if (eventType.includes("failed"))
133
+ statusColor = colors.error;
134
+ console.log(`${colors.dim(timestamp)} ${statusColor("→")} ${colors.bold(eventType)}`);
135
+ if (event.data) {
136
+ const messageId = event.data.message_id || event.data.id;
137
+ const to = event.data.to;
138
+ if (messageId) {
139
+ console.log(` ${colors.dim("message_id:")} ${messageId}`);
140
+ }
141
+ if (to) {
142
+ console.log(` ${colors.dim("to:")} ${to}`);
143
+ }
144
+ }
145
+ console.log();
146
+ }
147
+ async forwardEvent(forwardUrl, event, secret) {
148
+ try {
149
+ const payload = JSON.stringify(event);
150
+ const signature = await this.generateSignature(payload, secret);
151
+ const response = await fetch(forwardUrl, {
152
+ method: "POST",
153
+ headers: {
154
+ "Content-Type": "application/json",
155
+ "X-Sendly-Signature": signature,
156
+ "X-Sendly-Event": event.type,
157
+ },
158
+ body: payload,
159
+ });
160
+ if (response.ok) {
161
+ console.log(` ${colors.success("✓")} Forwarded to ${forwardUrl} (${response.status})`);
162
+ }
163
+ else {
164
+ console.log(` ${colors.error("✗")} Forward failed (${response.status})`);
165
+ }
166
+ }
167
+ catch (err) {
168
+ console.log(` ${colors.error("✗")} Forward error: ${err.message}`);
169
+ }
170
+ console.log();
171
+ }
172
+ async generateSignature(payload, secret) {
173
+ const encoder = new TextEncoder();
174
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
175
+ const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(payload));
176
+ const hashArray = Array.from(new Uint8Array(signature));
177
+ const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
178
+ return `v1=${hashHex}`;
179
+ }
180
+ async cleanup() {
181
+ // Clean up tunnel
182
+ if (this.tunnel) {
183
+ this.tunnel.close();
184
+ }
185
+ // Clean up temporary webhook
186
+ if (this.webhookId) {
187
+ try {
188
+ await apiClient.delete(`/api/cli/webhooks/listen/${this.webhookId}`);
189
+ }
190
+ catch {
191
+ // Ignore cleanup errors
192
+ }
193
+ }
194
+ }
195
+ }
196
+ // Polyfill EventSource for Node.js if needed
197
+ class EventSource {
198
+ constructor(url, options) {
199
+ // Simple implementation - in production use a proper polyfill
200
+ }
201
+ }
202
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdGVuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3dlYmhvb2tzL2xpc3Rlbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBRUwsS0FBSyxFQUVMLElBQUksRUFDSixNQUFNLEVBR04sT0FBTyxHQUdSLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sV0FBVyxNQUFNLGFBQWEsQ0FBQztBQVN0QyxNQUFNLENBQUMsT0FBTyxPQUFPLGNBQWUsU0FBUSxvQkFBb0I7SUFDOUQsTUFBTSxDQUFDLFdBQVcsR0FDaEIsZ0hBQWdILENBQUM7SUFFbkgsTUFBTSxDQUFDLFFBQVEsR0FBRztRQUNoQixtQ0FBbUM7UUFDbkMsMkVBQTJFO1FBQzNFLDZFQUE2RTtLQUM5RSxDQUFDO0lBRUYsTUFBTSxDQUFDLEtBQUssR0FBRztRQUNiLEdBQUcsb0JBQW9CLENBQUMsU0FBUztRQUNqQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUNwQixJQUFJLEVBQUUsR0FBRztZQUNULFdBQVcsRUFBRSxnQ0FBZ0M7WUFDN0MsT0FBTyxFQUFFLCtCQUErQjtTQUN6QyxDQUFDO1FBQ0YsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDbkIsSUFBSSxFQUFFLEdBQUc7WUFDVCxXQUFXLEVBQUUsOENBQThDO1lBQzNELE9BQU8sRUFBRSwrREFBK0Q7U0FDekUsQ0FBQztRQUNGLElBQUksRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDO1lBQ2xCLElBQUksRUFBRSxHQUFHO1lBQ1QsV0FB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UUFDbkIsa0JBQWtCO1FBQ2xCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsQ0FBQztRQUVELDZCQUE2QjtRQUM3QixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDLDRCQUE0QixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLHdCQUF3QjtZQUMxQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7O0FBR0gsNkNBQTZDO0FBQzdDLE1BQU0sV0FBVztJQUNmLFlBQVksR0FBVyxFQUFFLE9BQWE7UUFDcEMsOERBQThEO0lBQ2hFLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZsYWdzIH0gZnJvbSBcIkBvY2xpZi9jb3JlXCI7XG5pbXBvcnQgeyBBdXRoZW50aWNhdGVkQ29tbWFuZCB9IGZyb20gXCIuLi8uLi9saWIvYmFzZS1jb21tYW5kLmpzXCI7XG5pbXBvcnQgeyBhcGlDbGllbnQgfSBmcm9tIFwiLi4vLi4vbGliL2FwaS1jbGllbnQuanNcIjtcbmltcG9ydCB7XG4gIHN1Y2Nlc3MsXG4gIGVycm9yLFxuICBpbmZvLFxuICB3YXJuLFxuICBjb2xvcnMsXG4gIGZvcm1hdFN0YXR1cyxcbiAgZm9ybWF0RGF0ZSxcbiAgc3Bpbm5lcixcbiAganNvbiBhcyBqc29uT3V0cHV0LFxuICBpc0pzb25Nb2RlLFxufSBmcm9tIFwiLi4vLi4vbGliL291dHB1dC5qc1wiO1xuaW1wb3J0IHsgZ2V0Q29uZmlnVmFsdWUgfSBmcm9tIFwiLi4vLi4vbGliL2NvbmZpZy5qc1wiO1xuaW1wb3J0IGxvY2FsdHVubmVsIGZyb20gXCJsb2NhbHR1bm5lbFwiO1xuXG5pbnRlcmZhY2UgV2ViaG9va0V2ZW50IHtcbiAgaWQ6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY3JlYXRlZDogbnVtYmVyO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBXZWJob29rc0xpc3RlbiBleHRlbmRzIEF1dGhlbnRpY2F0ZWRDb21tYW5kIHtcbiAgc3RhdGljIGRlc2NyaXB0aW9uID1cbiAgICBcIkxpc3RlbiBmb3Igd2ViaG9va3MgbG9jYWxseSAobGlrZSBTdHJpcGUgQ0xJKS4gQ3JlYXRlcyBhIHNlY3VyZSB0dW5uZWwgdG8gZm9yd2FyZCBldmVudHMgdG8geW91ciBsb2NhbCBzZXJ2ZXIuXCI7XG5cbiAgc3RhdGljIGV4YW1wbGVzID0gW1xuICAgIFwiPCU9IGNvbmZpZy5iaW4gJT4gd2ViaG9va3MgbGlzdGVuXCIsXG4gICAgXCI8JT0gY29uZmlnLmJpbiAlPiB3ZWJob29rcyBsaXN0ZW4gLS1mb3J3YXJkIGh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC93ZWJob29rXCIsXG4gICAgXCI8JT0gY29uZmlnLmJpbiAlPiB3ZWJob29rcyBsaXN0ZW4gLS1ldmVudHMgbWVzc2FnZS5kZWxpdmVyZWQsbWVzc2FnZS5mYWlsZWRcIixcbiAgXTtcblxuICBzdGF0aWMgZmxhZ3MgPSB7XG4gICAgLi4uQXV0aGVudGljYXRlZENvbW1hbmQuYmFzZUZsYWdzLFxuICAgIGZvcndhcmQ6IEZsYWdzLnN0cmluZyh7XG4gICAgICBjaGFyOiBcImZcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkxvY2FsIFVSTCB0byBmb3J3YXJkIGV2ZW50cyB0b1wiLFxuICAgICAgZGVmYXVsdDogXCJodHRwOi8vbG9jYWxob3N0OjMwMDAvd2ViaG9va1wiLFxuICAgIH0pLFxuICAgIGV2ZW50czogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGNoYXI6IFwiZVwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiQ29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgZXZlbnRzIHRvIGxpc3RlbiBmb3JcIixcbiAgICAgIGRlZmF1bHQ6IFwibWVzc2FnZS5zZW50LG1lc3NhZ2UuZGVsaXZlcmVkLG1lc3NhZ2UuZmFpbGVkLG1lc3NhZ2UuYm91bmNlZFwiLFxuICAgIH0pLFxuICAgIHBvcnQ6IEZsYWdzLmludGVnZXIoe1xuICAgICAgY2hhcjogXCJwXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJMb2NhbCBwb3J0IGZvciB0aGUgdHVubmVsIChhdXRvLWRldGVjdGVkIGZyb20gZm9yd2FyZCBVUkwgaWYgbm90IHNwZWNpZmllZClcIixcbiAgICB9KSxcbiAgfTtcblxuICBwcml2YXRlIHR1bm5lbDogbG9jYWx0dW5uZWwuVHVubmVsIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgd2ViaG9va0lkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBydW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBmbGFncyB9ID0gYXdhaXQgdGhpcy5wYXJzZShXZWJob29rc0xpc3Rlbik7XG5cbiAgICBjb25zdCBmb3J3YXJkVXJsID0gbmV3IFVSTChmbGFncy5mb3J3YXJkKTtcbiAgICBjb25zdCBsb2NhbFBvcnQgPSBmbGFncy5wb3J0IHx8IHBhcnNlSW50KGZvcndhcmRVcmwucG9ydCkgfHwgMzAwMDtcbiAgICBjb25zdCBldmVudHMgPSBmbGFncy5ldmVudHMuc3BsaXQoXCIsXCIpLm1hcCgoZSkgPT4gZS50cmltKCkpO1xuXG4gICAgY29uc3Qgc3BpbiA9IHNwaW5uZXIoXCJTdGFydGluZyB3ZWJob29rIGxpc3RlbmVyLi4uXCIpO1xuICAgIHNwaW4uc3RhcnQoKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBDcmVhdGUgbG9jYWx0dW5uZWxcbiAgICAgIHRoaXMudHVubmVsID0gYXdhaXQgbG9jYWx0dW5uZWwoe1xuICAgICAgICBwb3J0OiBsb2NhbFBvcnQsXG4gICAgICAgIHN1YmRvbWFpbjogYHNlbmRseS0ke0RhdGUubm93KCkudG9TdHJpbmcoMzYpfWAsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHVubmVsVXJsID0gdGhpcy50dW5uZWwudXJsO1xuICAgICAgc3Bpbi5zdWNjZWVkKFwiVHVubmVsIGVzdGFibGlzaGVkXCIpO1xuXG4gICAgICAvLyBSZWdpc3RlciB0ZW1wb3Jhcnkgd2ViaG9vayB3aXRoIFNlbmRseVxuICAgICAgY29uc3Qgd2ViaG9va1Jlc3BvbnNlID0gYXdhaXQgYXBpQ2xpZW50LnBvc3Q8e1xuICAgICAgICBpZDogc3RyaW5nO1xuICAgICAgICBzZWNyZXQ6IHN0cmluZztcbiAgICAgIH0+KFwiL2FwaS9jbGkvd2ViaG9va3MvbGlzdGVuXCIsIHtcbiAgICAgICAgdXJsOiBgJHt0dW5uZWxVcmx9L2NsaS13ZWJob29rYCxcbiAgICAgICAgZXZlbnRzLFxuICAgICAgICBmb3J3YXJkVXJsOiBmbGFncy5mb3J3YXJkLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMud2ViaG9va0lkID0gd2ViaG9va1Jlc3BvbnNlLmlkO1xuICAgICAgY29uc3Qgc2VjcmV0ID0gd2ViaG9va1Jlc3BvbnNlLnNlY3JldDtcblxuICAgICAgLy8gRGlzcGxheSBjb25uZWN0aW9uIGluZm9cbiAgICAgIGNvbnNvbGUubG9nKCk7XG4gICAgICBjb25zb2xlLmxvZyhjb2xvcnMuYm9sZChjb2xvcnMucHJpbWFyeShcIldlYmhvb2sgbGlzdGVuZXIgcmVhZHkhXCIpKSk7XG4gICAgICBjb25zb2xlLmxvZygpO1xuICAgICAgY29uc29sZS5sb2coYCAgJHtjb2xvcnMuZGltKFwiVHVubmVsIFVSTDpcIil9ICAgICAke2NvbG9ycy5jb2RlKHR1bm5lbFVybCl9YCk7XG4gICAgICBjb25zb2xlLmxvZyhgICAke2NvbG9ycy5kaW0oXCJGb3J3YXJkaW5nIHRvOlwiKX0gJHtjb2xvcnMuY29kZShmbGFncy5mb3J3YXJkKX1gKTtcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7Y29sb3JzLmRpbShcIkV2ZW50czpcIil9ICAgICAgICAke2V2ZW50cy5qb2luKFwiLCBcIil9YCk7XG4gICAgICBjb25zb2xlLmxvZygpO1xuICAgICAgY29uc29sZS5sb2coYCAgJHtjb2xvcnMuZGltKFwiV2ViaG9vayBTZWNyZXQ6XCIpfWApO1xuICAgICAgY29uc29sZS5sb2coYCAgJHtjb2xvcnMucHJpbWFyeShzZWNyZXQpfWApO1xuICAgICAgY29uc29sZS5sb2coKTtcbiAgICAgIGNvbnNvbGUubG9nKGNvbG9ycy5kaW0oXCJVc2UgdGhpcyBzZWNyZXQgdG8gdmVyaWZ5IHdlYmhvb2sgc2lnbmF0dXJlcyBpbiB5b3VyIGFwcC5cIikpO1xuICAgICAgY29uc29sZS5sb2coKTtcbiAgICAgIGNvbnNvbGUubG9nKGNvbG9ycy5ib2xkKFwiV2FpdGluZyBmb3IgZXZlbnRzLi4uXCIpKTtcbiAgICAgIGNvbnNvbGUubG9nKGNvbG9ycy5kaW0oXCLilIBcIi5yZXBlYXQoNjApKSk7XG4gICAgICBjb25zb2xlLmxvZygpO1xuXG4gICAgICAvLyBTZXQgdXAgZXZlbnQgZm9yd2FyZGluZ1xuICAgICAgdGhpcy50dW5uZWwub24oXCJyZXF1ZXN0XCIsIChpbmZvKSA9PiB7XG4gICAgICAgIC8vIFRoaXMgaXMganVzdCBmb3IgbG9nZ2luZyAtIGFjdHVhbCBmb3J3YXJkaW5nIGhhcHBlbnMgc2VydmVyLXNpZGVcbiAgICAgIH0pO1xuXG4gICAgICAvLyBIYW5kbGUgdHVubmVsIGNsb3NlXG4gICAgICB0aGlzLnR1bm5lbC5vbihcImNsb3NlXCIsICgpID0+IHtcbiAgICAgICAgd2FybihcIlR1bm5lbCBjbG9zZWRcIik7XG4gICAgICAgIHRoaXMuY2xlYW51cCgpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy50dW5uZWwub24oXCJlcnJvclwiLCAoZXJyKSA9PiB7XG4gICAgICAgIGVycm9yKGBUdW5uZWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gUG9sbCBmb3IgZXZlbnRzIGFuZCBkaXNwbGF5IHRoZW1cbiAgICAgIGF3YWl0IHRoaXMucG9sbEV2ZW50cyhmbGFncy5mb3J3YXJkLCBzZWNyZXQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgc3Bpbi5mYWlsKFwiRmFpbGVkIHRvIHN0YXJ0IGxpc3RlbmVyXCIpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcG9sbEV2ZW50cyhmb3J3YXJkVXJsOiBzdHJpbmcsIHNlY3JldDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYmFzZVVybCA9IGdldENvbmZpZ1ZhbHVlKFwiYmFzZVVybFwiKSB8fCBcImh0dHBzOi8vc2VuZGx5LmxpdmVcIjtcblxuICAgIC8vIFNldCB1cCBTU0UgY29ubmVjdGlvbiBmb3IgcmVhbC10aW1lIGV2ZW50c1xuICAgIGNvbnN0IGV2ZW50U291cmNlID0gbmV3IEV2ZW50U291cmNlKFxuICAgICAgYCR7YmFzZVVybH0vYXBpL2NsaS93ZWJob29rcy9ldmVudHM/d2ViaG9va0lkPSR7dGhpcy53ZWJob29rSWR9YCxcbiAgICAgIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZSAtIGhlYWRlcnMgbm90IGluIHR5cGUgYnV0IHN1cHBvcnRlZFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2dldENvbmZpZ1ZhbHVlKFwiYXBpS2V5XCIpIHx8IGdldENvbmZpZ1ZhbHVlKFwiYWNjZXNzVG9rZW5cIil9YCxcbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gRmFsbGJhY2sgdG8gcG9sbGluZyBpZiBTU0Ugbm90IGF2YWlsYWJsZVxuICAgIGNvbnN0IHBvbGxJbnRlcnZhbCA9IHNldEludGVydmFsKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IGF3YWl0IGFwaUNsaWVudC5nZXQ8V2ViaG9va0V2ZW50W10+KFxuICAgICAgICAgIGAvYXBpL2NsaS93ZWJob29rcy9ldmVudHM/d2ViaG9va0lkPSR7dGhpcy53ZWJob29rSWR9JnNpbmNlPSR7RGF0ZS5ub3coKSAtIDUwMDB9YFxuICAgICAgICApO1xuXG4gICAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICAgICAgdGhpcy5kaXNwbGF5RXZlbnQoZXZlbnQpO1xuICAgICAgICAgIGF3YWl0IHRoaXMuZm9yd2FyZEV2ZW50KGZvcndhcmRVcmwsIGV2ZW50LCBzZWNyZXQpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gSWdub3JlIHBvbGxpbmcgZXJyb3JzXG4gICAgICB9XG4gICAgfSwgMjAwMCk7XG5cbiAgICAvLyBIYW5kbGUgZ3JhY2VmdWwgc2h1dGRvd25cbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgY2xlYXJJbnRlcnZhbChwb2xsSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgY2xlYW51cCk7XG4gICAgcHJvY2Vzcy5vbihcIlNJR1RFUk1cIiwgY2xlYW51cCk7XG5cbiAgICAvLyBLZWVwIHByb2Nlc3MgYWxpdmVcbiAgICBhd2FpdCBuZXcgUHJvbWlzZSgoKSA9PiB7fSk7XG4gIH1cblxuICBwcml2YXRlIGRpc3BsYXlFdmVudChldmVudDogV2ViaG9va0V2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoZXZlbnQuY3JlYXRlZCAqIDEwMDApLnRvTG9jYWxlVGltZVN0cmluZygpO1xuICAgIGNvbnN0IGV2ZW50VHlwZSA9IGV2ZW50LnR5cGU7XG5cbiAgICBsZXQgc3RhdHVzQ29sb3IgPSBjb2xvcnMuaW5mbztcbiAgICBpZiAoZXZlbnRUeXBlLmluY2x1ZGVzKFwiZGVsaXZlcmVkXCIpKSBzdGF0dXNDb2xvciA9IGNvbG9ycy5zdWNjZXNzO1xuICAgIGlmIChldmVudFR5cGUuaW5jbHVkZXMoXCJmYWlsZWRcIikpIHN0YXR1c0NvbG9yID0gY29sb3JzLmVycm9yO1xuXG4gICAgY29uc29sZS5sb2coXG4gICAgICBgJHtjb2xvcnMuZGltKHRpbWVzdGFtcCl9ICR7c3RhdHVzQ29sb3IoXCLihpJcIil9ICR7Y29sb3JzLmJvbGQoZXZlbnRUeXBlKX1gXG4gICAgKTtcblxuICAgIGlmIChldmVudC5kYXRhKSB7XG4gICAgICBjb25zdCBtZXNzYWdlSWQgPSAoZXZlbnQuZGF0YSBhcyBhbnkpLm1lc3NhZ2VfaWQgfHwgKGV2ZW50LmRhdGEgYXMgYW55KS5pZDtcbiAgICAgIGNvbnN0IHRvID0gKGV2ZW50LmRhdGEgYXMgYW55KS50bztcbiAgICAgIGlmIChtZXNzYWdlSWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgJHtjb2xvcnMuZGltKFwibWVzc2FnZV9pZDpcIil9ICR7bWVzc2FnZUlkfWApO1xuICAgICAgfVxuICAgICAgaWYgKHRvKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAgICR7Y29sb3JzLmRpbShcInRvOlwiKX0gJHt0b31gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZm9yd2FyZEV2ZW50KFxuICAgIGZvcndhcmRVcmw6IHN0cmluZyxcbiAgICBldmVudDogV2ViaG9va0V2ZW50LFxuICAgIHNlY3JldDogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkoZXZlbnQpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgdGhpcy5nZW5lcmF0ZVNpZ25hdHVyZShwYXlsb2FkLCBzZWNyZXQpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGZvcndhcmRVcmwsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICAgIFwiWC1TZW5kbHktU2lnbmF0dXJlXCI6IHNpZ25hdHVyZSxcbiAgICAgICAgICBcIlgtU2VuZGx5LUV2ZW50XCI6IGV2ZW50LnR5cGUsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IHBheWxvYWQsXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGAgICR7Y29sb3JzLnN1Y2Nlc3MoXCLinJNcIil9IEZvcndhcmRlZCB0byAke2ZvcndhcmRVcmx9ICgke3Jlc3BvbnNlLnN0YXR1c30pYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgYCAgJHtjb2xvcnMuZXJyb3IoXCLinJdcIil9IEZvcndhcmQgZmFpbGVkICgke3Jlc3BvbnNlLnN0YXR1c30pYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGAgICR7Y29sb3JzLmVycm9yKFwi4pyXXCIpfSBGb3J3YXJkIGVycm9yOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2VuZXJhdGVTaWduYXR1cmUoXG4gICAgcGF5bG9hZDogc3RyaW5nLFxuICAgIHNlY3JldDogc3RyaW5nXG4gICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAgIGNvbnN0IGtleSA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KFxuICAgICAgXCJyYXdcIixcbiAgICAgIGVuY29kZXIuZW5jb2RlKHNlY3JldCksXG4gICAgICB7IG5hbWU6IFwiSE1BQ1wiLCBoYXNoOiBcIlNIQS0yNTZcIiB9LFxuICAgICAgZmFsc2UsXG4gICAgICBbXCJzaWduXCJdXG4gICAgKTtcbiAgICBjb25zdCBzaWduYXR1cmUgPSBhd2FpdCBjcnlwdG8uc3VidGxlLnNpZ24oXG4gICAgICBcIkhNQUNcIixcbiAgICAgIGtleSxcbiAgICAgIGVuY29kZXIuZW5jb2RlKHBheWxvYWQpXG4gICAgKTtcbiAgICBjb25zdCBoYXNoQXJyYXkgPSBBcnJheS5mcm9tKG5ldyBVaW50OEFycmF5KHNpZ25hdHVyZSkpO1xuICAgIGNvbnN0IGhhc2hIZXggPSBoYXNoQXJyYXkubWFwKChiKSA9PiBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIikpLmpvaW4oXCJcIik7XG4gICAgcmV0dXJuIGB2MT0ke2hhc2hIZXh9YDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2xlYW51cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBDbGVhbiB1cCB0dW5uZWxcbiAgICBpZiAodGhpcy50dW5uZWwpIHtcbiAgICAgIHRoaXMudHVubmVsLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYW4gdXAgdGVtcG9yYXJ5IHdlYmhvb2tcbiAgICBpZiAodGhpcy53ZWJob29rSWQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGFwaUNsaWVudC5kZWxldGUoYC9hcGkvY2xpL3dlYmhvb2tzL2xpc3Rlbi8ke3RoaXMud2ViaG9va0lkfWApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIElnbm9yZSBjbGVhbnVwIGVycm9yc1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBQb2x5ZmlsbCBFdmVudFNvdXJjZSBmb3IgTm9kZS5qcyBpZiBuZWVkZWRcbmNsYXNzIEV2ZW50U291cmNlIHtcbiAgY29uc3RydWN0b3IodXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBhbnkpIHtcbiAgICAvLyBTaW1wbGUgaW1wbGVtZW50YXRpb24gLSBpbiBwcm9kdWN0aW9uIHVzZSBhIHByb3BlciBwb2x5ZmlsbFxuICB9XG59XG4iXX0=
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from "../lib/base-command.js";
2
+ export default class Whoami extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
+ quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,51 @@
1
+ import { BaseCommand } from "../lib/base-command.js";
2
+ import { getAuthInfo } from "../lib/auth.js";
3
+ import { success, info, keyValue, colors, json } from "../lib/output.js";
4
+ import { getConfigPath } from "../lib/config.js";
5
+ export default class Whoami extends BaseCommand {
6
+ static description = "Show current authentication status";
7
+ static examples = ["<%= config.bin %> whoami"];
8
+ static flags = {
9
+ ...BaseCommand.baseFlags,
10
+ };
11
+ async run() {
12
+ const { flags } = await this.parse(Whoami);
13
+ const authInfo = await getAuthInfo();
14
+ if (flags.json) {
15
+ json({
16
+ authenticated: authInfo.authenticated,
17
+ email: authInfo.email,
18
+ userId: authInfo.userId,
19
+ environment: authInfo.environment,
20
+ keyType: authInfo.keyType,
21
+ configPath: getConfigPath(),
22
+ });
23
+ return;
24
+ }
25
+ if (!authInfo.authenticated) {
26
+ info("Not logged in");
27
+ console.log();
28
+ console.log(` Run ${colors.code("sendly login")} to authenticate`);
29
+ return;
30
+ }
31
+ success("Authenticated");
32
+ console.log();
33
+ const displayData = {
34
+ Environment: colors.primary(authInfo.environment),
35
+ };
36
+ if (authInfo.email) {
37
+ displayData["Email"] = authInfo.email;
38
+ }
39
+ if (authInfo.keyType) {
40
+ displayData["Key Type"] = authInfo.keyType === "test"
41
+ ? colors.warning("test")
42
+ : colors.success("live");
43
+ }
44
+ if (authInfo.userId) {
45
+ displayData["User ID"] = colors.dim(authInfo.userId);
46
+ }
47
+ displayData["Config"] = colors.dim(getConfigPath());
48
+ keyValue(displayData);
49
+ }
50
+ }
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2hvYW1pLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL3dob2FtaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDekUsT0FBTyxFQUFrQixhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVqRSxNQUFNLENBQUMsT0FBTyxPQUFPLE1BQU8sU0FBUSxXQUFXO0lBQzdDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsb0NBQW9DLENBQUM7SUFFMUQsTUFBTSxDQUFDLFFBQVEsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFFL0MsTUFBTSxDQUFDLEtBQUssR0FBRztRQUNiLEdBQUcsV0FBVyxDQUFDLFNBQVM7S0FDekIsQ0FBQztJQUVGLEtBQUssQ0FBQyxHQUFHO1FBQ1AsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUzQyxNQUFNLFFBQVEsR0FBRyxNQUFNLFdBQVcsRUFBRSxDQUFDO1FBRXJDLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDO2dCQUNILGFBQWEsRUFBRSxRQUFRLENBQUMsYUFBYTtnQkFDckMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO2dCQUNyQixNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07Z0JBQ3ZCLFdBQVcsRUFBRSxRQUFRLENBQUMsV0FBVztnQkFDakMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPO2dCQUN6QixVQUFVLEVBQUUsYUFBYSxFQUFFO2FBQzVCLENBQUMsQ0FBQztZQUNILE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDdEIsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDcEUsT0FBTztRQUNULENBQUM7UUFFRCxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDekIsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRWQsTUFBTSxXQUFXLEdBQTJCO1lBQzFDLFdBQVcsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7U0FDbEQsQ0FBQztRQUVGLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25CLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQ3hDLENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNyQixXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxDQUFDLE9BQU8sS0FBSyxNQUFNO2dCQUNuRCxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7Z0JBQ3hCLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNwQixXQUFXLENBQUMsU0FBUyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELFdBQVcsQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFFcEQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCYXNlQ29tbWFuZCB9IGZyb20gXCIuLi9saWIvYmFzZS1jb21tYW5kLmpzXCI7XG5pbXBvcnQgeyBnZXRBdXRoSW5mbyB9IGZyb20gXCIuLi9saWIvYXV0aC5qc1wiO1xuaW1wb3J0IHsgc3VjY2VzcywgaW5mbywga2V5VmFsdWUsIGNvbG9ycywganNvbiB9IGZyb20gXCIuLi9saWIvb3V0cHV0LmpzXCI7XG5pbXBvcnQgeyBnZXRDb25maWdWYWx1ZSwgZ2V0Q29uZmlnUGF0aCB9IGZyb20gXCIuLi9saWIvY29uZmlnLmpzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdob2FtaSBleHRlbmRzIEJhc2VDb21tYW5kIHtcbiAgc3RhdGljIGRlc2NyaXB0aW9uID0gXCJTaG93IGN1cnJlbnQgYXV0aGVudGljYXRpb24gc3RhdHVzXCI7XG5cbiAgc3RhdGljIGV4YW1wbGVzID0gW1wiPCU9IGNvbmZpZy5iaW4gJT4gd2hvYW1pXCJdO1xuXG4gIHN0YXRpYyBmbGFncyA9IHtcbiAgICAuLi5CYXNlQ29tbWFuZC5iYXNlRmxhZ3MsXG4gIH07XG5cbiAgYXN5bmMgcnVuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgZmxhZ3MgfSA9IGF3YWl0IHRoaXMucGFyc2UoV2hvYW1pKTtcblxuICAgIGNvbnN0IGF1dGhJbmZvID0gYXdhaXQgZ2V0QXV0aEluZm8oKTtcblxuICAgIGlmIChmbGFncy5qc29uKSB7XG4gICAgICBqc29uKHtcbiAgICAgICAgYXV0aGVudGljYXRlZDogYXV0aEluZm8uYXV0aGVudGljYXRlZCxcbiAgICAgICAgZW1haWw6IGF1dGhJbmZvLmVtYWlsLFxuICAgICAgICB1c2VySWQ6IGF1dGhJbmZvLnVzZXJJZCxcbiAgICAgICAgZW52aXJvbm1lbnQ6IGF1dGhJbmZvLmVudmlyb25tZW50LFxuICAgICAgICBrZXlUeXBlOiBhdXRoSW5mby5rZXlUeXBlLFxuICAgICAgICBjb25maWdQYXRoOiBnZXRDb25maWdQYXRoKCksXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWF1dGhJbmZvLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIGluZm8oXCJOb3QgbG9nZ2VkIGluXCIpO1xuICAgICAgY29uc29sZS5sb2coKTtcbiAgICAgIGNvbnNvbGUubG9nKGAgIFJ1biAke2NvbG9ycy5jb2RlKFwic2VuZGx5IGxvZ2luXCIpfSB0byBhdXRoZW50aWNhdGVgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzdWNjZXNzKFwiQXV0aGVudGljYXRlZFwiKTtcbiAgICBjb25zb2xlLmxvZygpO1xuXG4gICAgY29uc3QgZGlzcGxheURhdGE6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICBFbnZpcm9ubWVudDogY29sb3JzLnByaW1hcnkoYXV0aEluZm8uZW52aXJvbm1lbnQpLFxuICAgIH07XG5cbiAgICBpZiAoYXV0aEluZm8uZW1haWwpIHtcbiAgICAgIGRpc3BsYXlEYXRhW1wiRW1haWxcIl0gPSBhdXRoSW5mby5lbWFpbDtcbiAgICB9XG5cbiAgICBpZiAoYXV0aEluZm8ua2V5VHlwZSkge1xuICAgICAgZGlzcGxheURhdGFbXCJLZXkgVHlwZVwiXSA9IGF1dGhJbmZvLmtleVR5cGUgPT09IFwidGVzdFwiXG4gICAgICAgID8gY29sb3JzLndhcm5pbmcoXCJ0ZXN0XCIpXG4gICAgICAgIDogY29sb3JzLnN1Y2Nlc3MoXCJsaXZlXCIpO1xuICAgIH1cblxuICAgIGlmIChhdXRoSW5mby51c2VySWQpIHtcbiAgICAgIGRpc3BsYXlEYXRhW1wiVXNlciBJRFwiXSA9IGNvbG9ycy5kaW0oYXV0aEluZm8udXNlcklkKTtcbiAgICB9XG5cbiAgICBkaXNwbGF5RGF0YVtcIkNvbmZpZ1wiXSA9IGNvbG9ycy5kaW0oZ2V0Q29uZmlnUGF0aCgpKTtcblxuICAgIGtleVZhbHVlKGRpc3BsYXlEYXRhKTtcbiAgfVxufVxuIl19