@sendly/cli 3.37.0 → 3.38.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/README.md +178 -0
- package/dist/commands/business-upgrade/resubmit.js +3 -3
- package/dist/commands/business-upgrade/start.js +3 -3
- package/dist/commands/config/list.js +14 -2
- package/dist/commands/config/set.js +16 -3
- package/dist/commands/countries.js +2 -2
- package/dist/commands/credits/index.d.ts +1 -0
- package/dist/commands/credits/index.js +4 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.js +51 -8
- package/dist/commands/enterprise/upload-verification-document.js +3 -3
- package/dist/commands/enterprise/verification/resubmit.js +2 -2
- package/dist/commands/enterprise/verification/submit.js +2 -2
- package/dist/commands/events/listen.js +3 -3
- package/dist/commands/numbers/buy.js +19 -4
- package/dist/commands/rcs/agents.d.ts +10 -0
- package/dist/commands/rcs/agents.js +89 -0
- package/dist/commands/rcs/capability.d.ts +12 -0
- package/dist/commands/rcs/capability.js +85 -0
- package/dist/commands/rcs/send.d.ts +21 -0
- package/dist/commands/rcs/send.js +240 -0
- package/dist/commands/send.d.ts +1 -0
- package/dist/commands/send.js +5 -2
- package/dist/commands/sms/batch.d.ts +1 -0
- package/dist/commands/sms/batch.js +11 -1
- package/dist/commands/sms/group.d.ts +1 -0
- package/dist/commands/sms/group.js +5 -2
- package/dist/commands/sms/schedule.d.ts +1 -0
- package/dist/commands/sms/schedule.js +5 -2
- package/dist/commands/sms/send.d.ts +1 -0
- package/dist/commands/sms/send.js +5 -2
- package/dist/commands/webhooks/listen.js +2 -2
- package/dist/commands/whatsapp/connect.d.ts +17 -0
- package/dist/commands/whatsapp/connect.js +166 -0
- package/dist/commands/whatsapp/profile/get.d.ts +13 -0
- package/dist/commands/whatsapp/profile/get.js +67 -0
- package/dist/commands/whatsapp/profile/update.d.ts +20 -0
- package/dist/commands/whatsapp/profile/update.js +109 -0
- package/dist/commands/whatsapp/send.d.ts +17 -0
- package/dist/commands/whatsapp/send.js +151 -0
- package/dist/commands/whatsapp/senders.d.ts +10 -0
- package/dist/commands/whatsapp/senders.js +74 -0
- package/dist/commands/whatsapp/status.d.ts +13 -0
- package/dist/commands/whatsapp/status.js +92 -0
- package/dist/commands/whatsapp/templates/create.d.ts +19 -0
- package/dist/commands/whatsapp/templates/create.js +205 -0
- package/dist/commands/whatsapp/templates/delete.d.ts +14 -0
- package/dist/commands/whatsapp/templates/delete.js +69 -0
- package/dist/commands/whatsapp/templates/list.d.ts +10 -0
- package/dist/commands/whatsapp/templates/list.js +77 -0
- package/dist/commands/whatsapp/templates/update.d.ts +18 -0
- package/dist/commands/whatsapp/templates/update.js +160 -0
- package/dist/commands/whoami.js +32 -6
- package/dist/hooks/command-not-found.js +46 -61
- package/dist/lib/api-client.d.ts +9 -1
- package/dist/lib/api-client.js +78 -9
- package/dist/lib/auth.js +10 -6
- package/dist/lib/base-command.js +9 -1
- package/dist/lib/config.d.ts +50 -1
- package/dist/lib/config.js +144 -7
- package/dist/lib/help.d.ts +10 -0
- package/dist/lib/help.js +23 -0
- package/dist/lib/onboarding.js +3 -3
- package/oclif.manifest.json +1735 -764
- package/package.json +8 -1
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { AuthenticatedCommand } from "../../lib/base-command.js";
|
|
3
|
+
import { apiClient, ApiError, ApiKeyRequiredError, AuthenticationError, NotFoundError, ValidationError, } from "../../lib/api-client.js";
|
|
4
|
+
import { success, error, json, colors, spinner, isJsonMode, formatStatus, formatCredits, } from "../../lib/output.js";
|
|
5
|
+
/** Parse repeatable "text=postback" pairs into reply suggestions. */
|
|
6
|
+
function parseReplies(raw) {
|
|
7
|
+
if (!raw || raw.length === 0)
|
|
8
|
+
return [];
|
|
9
|
+
const out = [];
|
|
10
|
+
for (const item of raw) {
|
|
11
|
+
const idx = item.indexOf("=");
|
|
12
|
+
if (idx <= 0 || idx === item.length - 1) {
|
|
13
|
+
return `Invalid --suggest-reply "${item}" — use text=postback (e.g. "Track order=TRACK")`;
|
|
14
|
+
}
|
|
15
|
+
out.push({
|
|
16
|
+
reply: {
|
|
17
|
+
text: item.slice(0, idx).trim(),
|
|
18
|
+
postbackData: item.slice(idx + 1),
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
/** Parse repeatable "text=postback=url" triples into open-URL suggestions. */
|
|
25
|
+
function parseUrlActions(raw) {
|
|
26
|
+
if (!raw || raw.length === 0)
|
|
27
|
+
return [];
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const item of raw) {
|
|
30
|
+
const first = item.indexOf("=");
|
|
31
|
+
const second = first === -1 ? -1 : item.indexOf("=", first + 1);
|
|
32
|
+
const text = first > 0 ? item.slice(0, first).trim() : "";
|
|
33
|
+
const postbackData = second > first + 1 ? item.slice(first + 1, second) : "";
|
|
34
|
+
const url = second === -1 ? "" : item.slice(second + 1);
|
|
35
|
+
if (!text || !postbackData || !url) {
|
|
36
|
+
return `Invalid --suggest-url "${item}" — use text=postback=url (e.g. "View order=VIEW=https://example.com/o/4821")`;
|
|
37
|
+
}
|
|
38
|
+
out.push({ action: { text, postbackData, url } });
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
export default class RcsSend extends AuthenticatedCommand {
|
|
43
|
+
static description = "Send an RCS message — rich text with suggestion chips or a rich card; recipients without RCS get it as plain SMS unless --no-fallback";
|
|
44
|
+
static examples = [
|
|
45
|
+
'<%= config.bin %> rcs send --to +15125550190 --text "Your order shipped!"',
|
|
46
|
+
'<%= config.bin %> rcs send --to +15125550190 --text "Need anything else?" --suggest-reply "Track order=TRACK" --suggest-url "View receipt=RECEIPT=https://example.com/r/4821"',
|
|
47
|
+
'<%= config.bin %> rcs send --to +15125550190 --card-title "Spring sale" --card-description "20% off everything this weekend" --card-media https://example.com/sale.jpg',
|
|
48
|
+
'<%= config.bin %> rcs send --to +15125550190 --text "RCS only please" --no-fallback',
|
|
49
|
+
];
|
|
50
|
+
static flags = {
|
|
51
|
+
...AuthenticatedCommand.baseFlags,
|
|
52
|
+
to: Flags.string({
|
|
53
|
+
char: "t",
|
|
54
|
+
description: "Recipient phone number (E.164 format)",
|
|
55
|
+
required: true,
|
|
56
|
+
}),
|
|
57
|
+
text: Flags.string({
|
|
58
|
+
char: "m",
|
|
59
|
+
description: "Message text (falls back to SMS for non-RCS recipients)",
|
|
60
|
+
exclusive: [
|
|
61
|
+
"card-title",
|
|
62
|
+
"card-description",
|
|
63
|
+
"card-media",
|
|
64
|
+
"card-orientation",
|
|
65
|
+
],
|
|
66
|
+
}),
|
|
67
|
+
agent: Flags.string({
|
|
68
|
+
description: "RCS agent id to send from (only needed when your workspace has more than one — see `rcs agents`)",
|
|
69
|
+
}),
|
|
70
|
+
"card-title": Flags.string({
|
|
71
|
+
description: "Rich card title (cards have no SMS form — RCS-capable recipients only)",
|
|
72
|
+
}),
|
|
73
|
+
"card-description": Flags.string({
|
|
74
|
+
description: "Rich card body text; required with --card-title",
|
|
75
|
+
dependsOn: ["card-title"],
|
|
76
|
+
}),
|
|
77
|
+
"card-media": Flags.string({
|
|
78
|
+
description: "Public JPEG, PNG, or GIF image URL for the card",
|
|
79
|
+
dependsOn: ["card-title"],
|
|
80
|
+
}),
|
|
81
|
+
"card-orientation": Flags.string({
|
|
82
|
+
description: "Card layout",
|
|
83
|
+
options: ["vertical", "horizontal"],
|
|
84
|
+
dependsOn: ["card-title"],
|
|
85
|
+
}),
|
|
86
|
+
"suggest-reply": Flags.string({
|
|
87
|
+
description: 'Reply chip as "text=postback" (e.g. --suggest-reply "Track order=TRACK"). Repeatable.',
|
|
88
|
+
multiple: true,
|
|
89
|
+
}),
|
|
90
|
+
"suggest-url": Flags.string({
|
|
91
|
+
description: 'Open-URL chip as "text=postback=url" (e.g. --suggest-url "View order=VIEW=https://example.com/o/4821"). Repeatable.',
|
|
92
|
+
multiple: true,
|
|
93
|
+
}),
|
|
94
|
+
"no-fallback": Flags.boolean({
|
|
95
|
+
description: "Fail with an error instead of delivering as SMS when the recipient doesn't support RCS",
|
|
96
|
+
default: false,
|
|
97
|
+
}),
|
|
98
|
+
"idempotency-key": Flags.string({
|
|
99
|
+
description: "Idempotency key (1-255 printable ASCII characters). Re-running with the same key within 24 hours returns the original result instead of sending again.",
|
|
100
|
+
}),
|
|
101
|
+
};
|
|
102
|
+
async run() {
|
|
103
|
+
const { flags } = await this.parse(RcsSend);
|
|
104
|
+
const hasCard = flags["card-title"] !== undefined;
|
|
105
|
+
if (!flags.text && !hasCard) {
|
|
106
|
+
error("Provide either --text or --card-title", {
|
|
107
|
+
hint: 'Text: --text "Hello!" · Card: --card-title "Spring sale" --card-description "20% off"',
|
|
108
|
+
});
|
|
109
|
+
this.exit(1);
|
|
110
|
+
}
|
|
111
|
+
if (hasCard && flags["card-description"] === undefined) {
|
|
112
|
+
error("Missing --card-description for the card", {
|
|
113
|
+
hint: "Rich cards need both a title and a description",
|
|
114
|
+
});
|
|
115
|
+
this.exit(1);
|
|
116
|
+
}
|
|
117
|
+
const replies = parseReplies(flags["suggest-reply"]);
|
|
118
|
+
if (typeof replies === "string") {
|
|
119
|
+
error(replies);
|
|
120
|
+
this.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const urlActions = parseUrlActions(flags["suggest-url"]);
|
|
123
|
+
if (typeof urlActions === "string") {
|
|
124
|
+
error(urlActions);
|
|
125
|
+
this.exit(1);
|
|
126
|
+
}
|
|
127
|
+
const suggestions = [
|
|
128
|
+
...replies,
|
|
129
|
+
...urlActions,
|
|
130
|
+
];
|
|
131
|
+
const sendSpinner = spinner("Sending RCS message...");
|
|
132
|
+
if (!isJsonMode()) {
|
|
133
|
+
sendSpinner.start();
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const response = await apiClient.post("/api/v1/messages", {
|
|
137
|
+
channel: "rcs",
|
|
138
|
+
to: flags.to,
|
|
139
|
+
...(flags.agent && { agentId: flags.agent }),
|
|
140
|
+
...(hasCard
|
|
141
|
+
? {
|
|
142
|
+
card: {
|
|
143
|
+
title: flags["card-title"],
|
|
144
|
+
description: flags["card-description"],
|
|
145
|
+
...(flags["card-media"] && {
|
|
146
|
+
mediaUrl: flags["card-media"],
|
|
147
|
+
}),
|
|
148
|
+
...(flags["card-orientation"] && {
|
|
149
|
+
orientation: flags["card-orientation"],
|
|
150
|
+
}),
|
|
151
|
+
...(suggestions.length > 0 && { suggestions }),
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
: {
|
|
155
|
+
text: flags.text,
|
|
156
|
+
...(suggestions.length > 0 && { suggestions }),
|
|
157
|
+
}),
|
|
158
|
+
...(flags["no-fallback"] && { fallbackToSms: false }),
|
|
159
|
+
}, true, { idempotencyKey: flags["idempotency-key"] });
|
|
160
|
+
sendSpinner.stop();
|
|
161
|
+
if (isJsonMode()) {
|
|
162
|
+
json(response);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (response.fellBackTo === "sms") {
|
|
166
|
+
success("Message queued as SMS — recipient doesn't support RCS", {
|
|
167
|
+
"Message ID": colors.code(response.id),
|
|
168
|
+
To: response.to,
|
|
169
|
+
From: response.from,
|
|
170
|
+
Status: formatStatus(response.status),
|
|
171
|
+
Segments: response.segments,
|
|
172
|
+
Credits: formatCredits(response.creditsUsed),
|
|
173
|
+
});
|
|
174
|
+
if (response.rcs?.suggestionsDropped) {
|
|
175
|
+
console.log();
|
|
176
|
+
console.log(colors.dim("Suggestion chips have no SMS form and were dropped from this message."));
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
success("RCS message queued", {
|
|
181
|
+
"Message ID": colors.code(response.id),
|
|
182
|
+
To: response.to,
|
|
183
|
+
From: response.from,
|
|
184
|
+
Kind: response.rcs?.kind ?? (hasCard ? "card" : "text"),
|
|
185
|
+
Status: formatStatus(response.status),
|
|
186
|
+
Credits: formatCredits(response.creditsUsed),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
sendSpinner.stop();
|
|
191
|
+
if (err instanceof ApiError &&
|
|
192
|
+
err.code === "rcs_not_supported_for_recipient") {
|
|
193
|
+
error(err.message, {
|
|
194
|
+
hint: hasCard
|
|
195
|
+
? "Cards have no SMS form — send a text message to reach non-RCS recipients"
|
|
196
|
+
: "Drop --no-fallback to deliver to non-RCS recipients as SMS",
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
else if (err instanceof NotFoundError) {
|
|
200
|
+
error(err.message === "Resource not found"
|
|
201
|
+
? "RCS isn't available on your workspace yet."
|
|
202
|
+
: err.message, {
|
|
203
|
+
hint: "RCS is rolling out gradually — contact support@sendly.live for early access.",
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
else if (err instanceof ApiKeyRequiredError) {
|
|
207
|
+
error("RCS messages require a live API key.", {
|
|
208
|
+
hint: "RCS delivery is never simulated on a test key — create one with `sendly keys create --type live`",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
else if (err instanceof ValidationError &&
|
|
212
|
+
/more than one RCS agent/i.test(err.message ?? "")) {
|
|
213
|
+
error(err.message, {
|
|
214
|
+
hint: "Pass --agent <id> — list them with `sendly rcs agents`",
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else if (err instanceof AuthenticationError &&
|
|
218
|
+
/opted out/i.test(err.message ?? "")) {
|
|
219
|
+
error(err.message);
|
|
220
|
+
}
|
|
221
|
+
else if (err instanceof AuthenticationError &&
|
|
222
|
+
/agent/i.test(err.message ?? "")) {
|
|
223
|
+
error(err.message, {
|
|
224
|
+
hint: "See which agents can send with `sendly rcs agents`",
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
else if (err instanceof AuthenticationError &&
|
|
228
|
+
/rcs|verification|not supported|registration/i.test(err.message ?? "")) {
|
|
229
|
+
error(err.message, {
|
|
230
|
+
hint: "This recipient can't receive RCS and your account can't send SMS to this destination — complete verification, or message an RCS-capable recipient",
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
this.exit(1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9yY3Mvc2VuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsUUFBUSxFQUNSLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIsYUFBYSxFQUNiLGVBQWUsR0FDaEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQ0wsT0FBTyxFQUNQLEtBQUssRUFDTCxJQUFJLEVBQ0osTUFBTSxFQUNOLE9BQU8sRUFDUCxVQUFVLEVBQ1YsWUFBWSxFQUNaLGFBQWEsR0FDZCxNQUFNLHFCQUFxQixDQUFDO0FBNEI3QixxRUFBcUU7QUFDckUsU0FBUyxZQUFZLENBQ25CLEdBQXlCO0lBRXpCLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDeEMsTUFBTSxHQUFHLEdBQW9CLEVBQUUsQ0FBQztJQUNoQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUIsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU8sNEJBQTRCLElBQUksa0RBQWtELENBQUM7UUFDNUYsQ0FBQztRQUNELEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxLQUFLLEVBQUU7Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRTtnQkFDL0IsWUFB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Q0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxFQUNoQyxDQUFDO2dCQUNELEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFO29CQUNqQixJQUFJLEVBQUUsb0RBQW9EO2lCQUMzRCxDQUFDLENBQUM7WUFDTCxDQUFDO2lCQUFNLElBQ0wsR0FBRyxZQUFZLG1CQUFtQjtnQkFDbEMsOENBQThDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLEVBQ3RFLENBQUM7Z0JBQ0QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUU7b0JBQ2pCLElBQUksRUFBRSxtSkFBbUo7aUJBQzFKLENBQUMsQ0FBQztZQUNMLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLEdBQUcsQ0FBQztZQUNaLENBQUM7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGbGFncyB9IGZyb20gXCJAb2NsaWYvY29yZVwiO1xuaW1wb3J0IHsgQXV0aGVudGljYXRlZENvbW1hbmQgfSBmcm9tIFwiLi4vLi4vbGliL2Jhc2UtY29tbWFuZC5qc1wiO1xuaW1wb3J0IHtcbiAgYXBpQ2xpZW50LFxuICBBcGlFcnJvcixcbiAgQXBpS2V5UmVxdWlyZWRFcnJvcixcbiAgQXV0aGVudGljYXRpb25FcnJvcixcbiAgTm90Rm91bmRFcnJvcixcbiAgVmFsaWRhdGlvbkVycm9yLFxufSBmcm9tIFwiLi4vLi4vbGliL2FwaS1jbGllbnQuanNcIjtcbmltcG9ydCB7XG4gIHN1Y2Nlc3MsXG4gIGVycm9yLFxuICBqc29uLFxuICBjb2xvcnMsXG4gIHNwaW5uZXIsXG4gIGlzSnNvbk1vZGUsXG4gIGZvcm1hdFN0YXR1cyxcbiAgZm9ybWF0Q3JlZGl0cyxcbn0gZnJvbSBcIi4uLy4uL2xpYi9vdXRwdXQuanNcIjtcblxuaW50ZXJmYWNlIFJjc1NlbmRSZXNwb25zZSB7XG4gIGlkOiBzdHJpbmc7XG4gIGNoYW5uZWw6IHN0cmluZztcbiAgZmVsbEJhY2tUbz86IHN0cmluZztcbiAgbWVzc2FnZV9mb3JtYXQ6IHN0cmluZztcbiAgdG86IHN0cmluZztcbiAgZnJvbTogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmcgfCBudWxsO1xuICBzdGF0dXM6IHN0cmluZztcbiAgc2VnbWVudHM6IG51bWJlcjtcbiAgY3JlZGl0c1VzZWQ6IG51bWJlcjtcbiAgcmNzOiB7XG4gICAga2luZD86IHN0cmluZztcbiAgICBhZ2VudElkOiBzdHJpbmc7XG4gICAgYWdlbnROYW1lPzogc3RyaW5nO1xuICAgIHJlcXVlc3RlZENoYW5uZWw/OiBzdHJpbmc7XG4gICAgc3VnZ2VzdGlvbnNEcm9wcGVkPzogYm9vbGVhbjtcbiAgfTtcbiAgY3JlYXRlZEF0OiBzdHJpbmc7XG4gIG1ldGFkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxudHlwZSBSY3NTdWdnZXN0aW9uID1cbiAgfCB7IHJlcGx5OiB7IHRleHQ6IHN0cmluZzsgcG9zdGJhY2tEYXRhOiBzdHJpbmcgfSB9XG4gIHwgeyBhY3Rpb246IHsgdGV4dDogc3RyaW5nOyBwb3N0YmFja0RhdGE6IHN0cmluZzsgdXJsOiBzdHJpbmcgfSB9O1xuXG4vKiogUGFyc2UgcmVwZWF0YWJsZSBcInRleHQ9cG9zdGJhY2tcIiBwYWlycyBpbnRvIHJlcGx5IHN1Z2dlc3Rpb25zLiAqL1xuZnVuY3Rpb24gcGFyc2VSZXBsaWVzKFxuICByYXc6IHN0cmluZ1tdIHwgdW5kZWZpbmVkLFxuKTogUmNzU3VnZ2VzdGlvbltdIHwgc3RyaW5nIHtcbiAgaWYgKCFyYXcgfHwgcmF3Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuICBjb25zdCBvdXQ6IFJjc1N1Z2dlc3Rpb25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IGl0ZW0gb2YgcmF3KSB7XG4gICAgY29uc3QgaWR4ID0gaXRlbS5pbmRleE9mKFwiPVwiKTtcbiAgICBpZiAoaWR4IDw9IDAgfHwgaWR4ID09PSBpdGVtLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiBgSW52YWxpZCAtLXN1Z2dlc3QtcmVwbHkgXCIke2l0ZW19XCIg4oCUIHVzZSB0ZXh0PXBvc3RiYWNrIChlLmcuIFwiVHJhY2sgb3JkZXI9VFJBQ0tcIilgO1xuICAgIH1cbiAgICBvdXQucHVzaCh7XG4gICAgICByZXBseToge1xuICAgICAgICB0ZXh0OiBpdGVtLnNsaWNlKDAsIGlkeCkudHJpbSgpLFxuICAgICAgICBwb3N0YmFja0RhdGE6IGl0ZW0uc2xpY2UoaWR4ICsgMSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBQYXJzZSByZXBlYXRhYmxlIFwidGV4dD1wb3N0YmFjaz11cmxcIiB0cmlwbGVzIGludG8gb3Blbi1VUkwgc3VnZ2VzdGlvbnMuICovXG5mdW5jdGlvbiBwYXJzZVVybEFjdGlvbnMoXG4gIHJhdzogc3RyaW5nW10gfCB1bmRlZmluZWQsXG4pOiBSY3NTdWdnZXN0aW9uW10gfCBzdHJpbmcge1xuICBpZiAoIXJhdyB8fCByYXcubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gIGNvbnN0IG91dDogUmNzU3VnZ2VzdGlvbltdID0gW107XG4gIGZvciAoY29uc3QgaXRlbSBvZiByYXcpIHtcbiAgICBjb25zdCBmaXJzdCA9IGl0ZW0uaW5kZXhPZihcIj1cIik7XG4gICAgY29uc3Qgc2Vjb25kID0gZmlyc3QgPT09IC0xID8gLTEgOiBpdGVtLmluZGV4T2YoXCI9XCIsIGZpcnN0ICsgMSk7XG4gICAgY29uc3QgdGV4dCA9IGZpcnN0ID4gMCA/IGl0ZW0uc2xpY2UoMCwgZmlyc3QpLnRyaW0oKSA6IFwiXCI7XG4gICAgY29uc3QgcG9zdGJhY2tEYXRhID0gc2Vjb25kID4gZmlyc3QgKyAxID8gaXRlbS5zbGljZShmaXJzdCArIDEsIHNlY29uZCkgOiBcIlwiO1xuICAgIGNvbnN0IHVybCA9IHNlY29uZCA9PT0gLTEgPyBcIlwiIDogaXRlbS5zbGljZShzZWNvbmQgKyAxKTtcbiAgICBpZiAoIXRleHQgfHwgIXBvc3RiYWNrRGF0YSB8fCAhdXJsKSB7XG4gICAgICByZXR1cm4gYEludmFsaWQgLS1zdWdnZXN0LXVybCBcIiR7aXRlbX1cIiDigJQgdXNlIHRleHQ9cG9zdGJhY2s9dXJsIChlLmcuIFwiVmlldyBvcmRlcj1WSUVXPWh0dHBzOi8vZXhhbXBsZS5jb20vby80ODIxXCIpYDtcbiAgICB9XG4gICAgb3V0LnB1c2goeyBhY3Rpb246IHsgdGV4dCwgcG9zdGJhY2tEYXRhLCB1cmwgfSB9KTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSY3NTZW5kIGV4dGVuZHMgQXV0aGVudGljYXRlZENvbW1hbmQge1xuICBzdGF0aWMgZGVzY3JpcHRpb24gPVxuICAgIFwiU2VuZCBhbiBSQ1MgbWVzc2FnZSDigJQgcmljaCB0ZXh0IHdpdGggc3VnZ2VzdGlvbiBjaGlwcyBvciBhIHJpY2ggY2FyZDsgcmVjaXBpZW50cyB3aXRob3V0IFJDUyBnZXQgaXQgYXMgcGxhaW4gU01TIHVubGVzcyAtLW5vLWZhbGxiYWNrXCI7XG5cbiAgc3RhdGljIGV4YW1wbGVzID0gW1xuICAgICc8JT0gY29uZmlnLmJpbiAlPiByY3Mgc2VuZCAtLXRvICsxNTEyNTU1MDE5MCAtLXRleHQgXCJZb3VyIG9yZGVyIHNoaXBwZWQhXCInLFxuICAgICc8JT0gY29uZmlnLmJpbiAlPiByY3Mgc2VuZCAtLXRvICsxNTEyNTU1MDE5MCAtLXRleHQgXCJOZWVkIGFueXRoaW5nIGVsc2U/XCIgLS1zdWdnZXN0LXJlcGx5IFwiVHJhY2sgb3JkZXI9VFJBQ0tcIiAtLXN1Z2dlc3QtdXJsIFwiVmlldyByZWNlaXB0PVJFQ0VJUFQ9aHR0cHM6Ly9leGFtcGxlLmNvbS9yLzQ4MjFcIicsXG4gICAgJzwlPSBjb25maWcuYmluICU+IHJjcyBzZW5kIC0tdG8gKzE1MTI1NTUwMTkwIC0tY2FyZC10aXRsZSBcIlNwcmluZyBzYWxlXCIgLS1jYXJkLWRlc2NyaXB0aW9uIFwiMjAlIG9mZiBldmVyeXRoaW5nIHRoaXMgd2Vla2VuZFwiIC0tY2FyZC1tZWRpYSBodHRwczovL2V4YW1wbGUuY29tL3NhbGUuanBnJyxcbiAgICAnPCU9IGNvbmZpZy5iaW4gJT4gcmNzIHNlbmQgLS10byArMTUxMjU1NTAxOTAgLS10ZXh0IFwiUkNTIG9ubHkgcGxlYXNlXCIgLS1uby1mYWxsYmFjaycsXG4gIF07XG5cbiAgc3RhdGljIGZsYWdzID0ge1xuICAgIC4uLkF1dGhlbnRpY2F0ZWRDb21tYW5kLmJhc2VGbGFncyxcbiAgICB0bzogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGNoYXI6IFwidFwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiUmVjaXBpZW50IHBob25lIG51bWJlciAoRS4xNjQgZm9ybWF0KVwiLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSksXG4gICAgdGV4dDogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGNoYXI6IFwibVwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiTWVzc2FnZSB0ZXh0IChmYWxscyBiYWNrIHRvIFNNUyBmb3Igbm9uLVJDUyByZWNpcGllbnRzKVwiLFxuICAgICAgZXhjbHVzaXZlOiBbXG4gICAgICAgIFwiY2FyZC10aXRsZVwiLFxuICAgICAgICBcImNhcmQtZGVzY3JpcHRpb25cIixcbiAgICAgICAgXCJjYXJkLW1lZGlhXCIsXG4gICAgICAgIFwiY2FyZC1vcmllbnRhdGlvblwiLFxuICAgICAgXSxcbiAgICB9KSxcbiAgICBhZ2VudDogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIlJDUyBhZ2VudCBpZCB0byBzZW5kIGZyb20gKG9ubHkgbmVlZGVkIHdoZW4geW91ciB3b3Jrc3BhY2UgaGFzIG1vcmUgdGhhbiBvbmUg4oCUIHNlZSBgcmNzIGFnZW50c2ApXCIsXG4gICAgfSksXG4gICAgXCJjYXJkLXRpdGxlXCI6IEZsYWdzLnN0cmluZyh7XG4gICAgICBkZXNjcmlwdGlvbjogXCJSaWNoIGNhcmQgdGl0bGUgKGNhcmRzIGhhdmUgbm8gU01TIGZvcm0g4oCUIFJDUy1jYXBhYmxlIHJlY2lwaWVudHMgb25seSlcIixcbiAgICB9KSxcbiAgICBcImNhcmQtZGVzY3JpcHRpb25cIjogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlJpY2ggY2FyZCBib2R5IHRleHQ7IHJlcXVpcmVkIHdpdGggLS1jYXJkLXRpdGxlXCIsXG4gICAgICBkZXBlbmRzT246IFtcImNhcmQtdGl0bGVcIl0sXG4gICAgfSksXG4gICAgXCJjYXJkLW1lZGlhXCI6IEZsYWdzLnN0cmluZyh7XG4gICAgICBkZXNjcmlwdGlvbjogXCJQdWJsaWMgSlBFRywgUE5HLCBvciBHSUYgaW1hZ2UgVVJMIGZvciB0aGUgY2FyZFwiLFxuICAgICAgZGVwZW5kc09uOiBbXCJjYXJkLXRpdGxlXCJdLFxuICAgIH0pLFxuICAgIFwiY2FyZC1vcmllbnRhdGlvblwiOiBGbGFncy5zdHJpbmcoe1xuICAgICAgZGVzY3JpcHRpb246IFwiQ2FyZCBsYXlvdXRcIixcbiAgICAgIG9wdGlvbnM6IFtcInZlcnRpY2FsXCIsIFwiaG9yaXpvbnRhbFwiXSxcbiAgICAgIGRlcGVuZHNPbjogW1wiY2FyZC10aXRsZVwiXSxcbiAgICB9KSxcbiAgICBcInN1Z2dlc3QtcmVwbHlcIjogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnUmVwbHkgY2hpcCBhcyBcInRleHQ9cG9zdGJhY2tcIiAoZS5nLiAtLXN1Z2dlc3QtcmVwbHkgXCJUcmFjayBvcmRlcj1UUkFDS1wiKS4gUmVwZWF0YWJsZS4nLFxuICAgICAgbXVsdGlwbGU6IHRydWUsXG4gICAgfSksXG4gICAgXCJzdWdnZXN0LXVybFwiOiBGbGFncy5zdHJpbmcoe1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdPcGVuLVVSTCBjaGlwIGFzIFwidGV4dD1wb3N0YmFjaz11cmxcIiAoZS5nLiAtLXN1Z2dlc3QtdXJsIFwiVmlldyBvcmRlcj1WSUVXPWh0dHBzOi8vZXhhbXBsZS5jb20vby80ODIxXCIpLiBSZXBlYXRhYmxlLicsXG4gICAgICBtdWx0aXBsZTogdHJ1ZSxcbiAgICB9KSxcbiAgICBcIm5vLWZhbGxiYWNrXCI6IEZsYWdzLmJvb2xlYW4oe1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRmFpbCB3aXRoIGFuIGVycm9yIGluc3RlYWQgb2YgZGVsaXZlcmluZyBhcyBTTVMgd2hlbiB0aGUgcmVjaXBpZW50IGRvZXNuJ3Qgc3VwcG9ydCBSQ1NcIixcbiAgICAgIGRlZmF1bHQ6IGZhbHNlLFxuICAgIH0pLFxuICAgIFwiaWRlbXBvdGVuY3kta2V5XCI6IEZsYWdzLnN0cmluZyh7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJJZGVtcG90ZW5jeSBrZXkgKDEtMjU1IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXJzKS4gUmUtcnVubmluZyB3aXRoIHRoZSBzYW1lIGtleSB3aXRoaW4gMjQgaG91cnMgcmV0dXJucyB0aGUgb3JpZ2luYWwgcmVzdWx0IGluc3RlYWQgb2Ygc2VuZGluZyBhZ2Fpbi5cIixcbiAgICB9KSxcbiAgfTtcblxuICBhc3luYyBydW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBmbGFncyB9ID0gYXdhaXQgdGhpcy5wYXJzZShSY3NTZW5kKTtcblxuICAgIGNvbnN0IGhhc0NhcmQgPSBmbGFnc1tcImNhcmQtdGl0bGVcIl0gIT09IHVuZGVmaW5lZDtcbiAgICBpZiAoIWZsYWdzLnRleHQgJiYgIWhhc0NhcmQpIHtcbiAgICAgIGVycm9yKFwiUHJvdmlkZSBlaXRoZXIgLS10ZXh0IG9yIC0tY2FyZC10aXRsZVwiLCB7XG4gICAgICAgIGhpbnQ6ICdUZXh0OiAtLXRleHQgXCJIZWxsbyFcIiDCtyBDYXJkOiAtLWNhcmQtdGl0bGUgXCJTcHJpbmcgc2FsZVwiIC0tY2FyZC1kZXNjcmlwdGlvbiBcIjIwJSBvZmZcIicsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZXhpdCgxKTtcbiAgICB9XG4gICAgaWYgKGhhc0NhcmQgJiYgZmxhZ3NbXCJjYXJkLWRlc2NyaXB0aW9uXCJdID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGVycm9yKFwiTWlzc2luZyAtLWNhcmQtZGVzY3JpcHRpb24gZm9yIHRoZSBjYXJkXCIsIHtcbiAgICAgICAgaGludDogXCJSaWNoIGNhcmRzIG5lZWQgYm90aCBhIHRpdGxlIGFuZCBhIGRlc2NyaXB0aW9uXCIsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZXhpdCgxKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXBsaWVzID0gcGFyc2VSZXBsaWVzKGZsYWdzW1wic3VnZ2VzdC1yZXBseVwiXSk7XG4gICAgaWYgKHR5cGVvZiByZXBsaWVzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBlcnJvcihyZXBsaWVzKTtcbiAgICAgIHRoaXMuZXhpdCgxKTtcbiAgICB9XG4gICAgY29uc3QgdXJsQWN0aW9ucyA9IHBhcnNlVXJsQWN0aW9ucyhmbGFnc1tcInN1Z2dlc3QtdXJsXCJdKTtcbiAgICBpZiAodHlwZW9mIHVybEFjdGlvbnMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGVycm9yKHVybEFjdGlvbnMpO1xuICAgICAgdGhpcy5leGl0KDEpO1xuICAgIH1cbiAgICBjb25zdCBzdWdnZXN0aW9ucyA9IFtcbiAgICAgIC4uLihyZXBsaWVzIGFzIFJjc1N1Z2dlc3Rpb25bXSksXG4gICAgICAuLi4odXJsQWN0aW9ucyBhcyBSY3NTdWdnZXN0aW9uW10pLFxuICAgIF07XG5cbiAgICBjb25zdCBzZW5kU3Bpbm5lciA9IHNwaW5uZXIoXCJTZW5kaW5nIFJDUyBtZXNzYWdlLi4uXCIpO1xuICAgIGlmICghaXNKc29uTW9kZSgpKSB7XG4gICAgICBzZW5kU3Bpbm5lci5zdGFydCgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGFwaUNsaWVudC5wb3N0PFJjc1NlbmRSZXNwb25zZT4oXG4gICAgICAgIFwiL2FwaS92MS9tZXNzYWdlc1wiLFxuICAgICAgICB7XG4gICAgICAgICAgY2hhbm5lbDogXCJyY3NcIixcbiAgICAgICAgICB0bzogZmxhZ3MudG8sXG4gICAgICAgICAgLi4uKGZsYWdzLmFnZW50ICYmIHsgYWdlbnRJZDogZmxhZ3MuYWdlbnQgfSksXG4gICAgICAgICAgLi4uKGhhc0NhcmRcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGNhcmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRpdGxlOiBmbGFnc1tcImNhcmQtdGl0bGVcIl0sXG4gICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogZmxhZ3NbXCJjYXJkLWRlc2NyaXB0aW9uXCJdLFxuICAgICAgICAgICAgICAgICAgLi4uKGZsYWdzW1wiY2FyZC1tZWRpYVwiXSAmJiB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhVXJsOiBmbGFnc1tcImNhcmQtbWVkaWFcIl0sXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgIC4uLihmbGFnc1tcImNhcmQtb3JpZW50YXRpb25cIl0gJiYge1xuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbjogZmxhZ3NbXCJjYXJkLW9yaWVudGF0aW9uXCJdLFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAuLi4oc3VnZ2VzdGlvbnMubGVuZ3RoID4gMCAmJiB7IHN1Z2dlc3Rpb25zIH0pLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHRleHQ6IGZsYWdzLnRleHQsXG4gICAgICAgICAgICAgICAgLi4uKHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDAgJiYgeyBzdWdnZXN0aW9ucyB9KSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgLi4uKGZsYWdzW1wibm8tZmFsbGJhY2tcIl0gJiYgeyBmYWxsYmFja1RvU21zOiBmYWxzZSB9KSxcbiAgICAgICAgfSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgeyBpZGVtcG90ZW5jeUtleTogZmxhZ3NbXCJpZGVtcG90ZW5jeS1rZXlcIl0gfSxcbiAgICAgICk7XG5cbiAgICAgIHNlbmRTcGlubmVyLnN0b3AoKTtcblxuICAgICAgaWYgKGlzSnNvbk1vZGUoKSkge1xuICAgICAgICBqc29uKHJlc3BvbnNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2UuZmVsbEJhY2tUbyA9PT0gXCJzbXNcIikge1xuICAgICAgICBzdWNjZXNzKFwiTWVzc2FnZSBxdWV1ZWQgYXMgU01TIOKAlCByZWNpcGllbnQgZG9lc24ndCBzdXBwb3J0IFJDU1wiLCB7XG4gICAgICAgICAgXCJNZXNzYWdlIElEXCI6IGNvbG9ycy5jb2RlKHJlc3BvbnNlLmlkKSxcbiAgICAgICAgICBUbzogcmVzcG9uc2UudG8sXG4gICAgICAgICAgRnJvbTogcmVzcG9uc2UuZnJvbSxcbiAgICAgICAgICBTdGF0dXM6IGZvcm1hdFN0YXR1cyhyZXNwb25zZS5zdGF0dXMpLFxuICAgICAgICAgIFNlZ21lbnRzOiByZXNwb25zZS5zZWdtZW50cyxcbiAgICAgICAgICBDcmVkaXRzOiBmb3JtYXRDcmVkaXRzKHJlc3BvbnNlLmNyZWRpdHNVc2VkKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXNwb25zZS5yY3M/LnN1Z2dlc3Rpb25zRHJvcHBlZCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCk7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjb2xvcnMuZGltKFxuICAgICAgICAgICAgICBcIlN1Z2dlc3Rpb24gY2hpcHMgaGF2ZSBubyBTTVMgZm9ybSBhbmQgd2VyZSBkcm9wcGVkIGZyb20gdGhpcyBtZXNzYWdlLlwiLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc3VjY2VzcyhcIlJDUyBtZXNzYWdlIHF1ZXVlZFwiLCB7XG4gICAgICAgIFwiTWVzc2FnZSBJRFwiOiBjb2xvcnMuY29kZShyZXNwb25zZS5pZCksXG4gICAgICAgIFRvOiByZXNwb25zZS50byxcbiAgICAgICAgRnJvbTogcmVzcG9uc2UuZnJvbSxcbiAgICAgICAgS2luZDogcmVzcG9uc2UucmNzPy5raW5kID8/IChoYXNDYXJkID8gXCJjYXJkXCIgOiBcInRleHRcIiksXG4gICAgICAgIFN0YXR1czogZm9ybWF0U3RhdHVzKHJlc3BvbnNlLnN0YXR1cyksXG4gICAgICAgIENyZWRpdHM6IGZvcm1hdENyZWRpdHMocmVzcG9uc2UuY3JlZGl0c1VzZWQpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIHNlbmRTcGlubmVyLnN0b3AoKTtcblxuICAgICAgaWYgKFxuICAgICAgICBlcnIgaW5zdGFuY2VvZiBBcGlFcnJvciAmJlxuICAgICAgICBlcnIuY29kZSA9PT0gXCJyY3Nfbm90X3N1cHBvcnRlZF9mb3JfcmVjaXBpZW50XCJcbiAgICAgICkge1xuICAgICAgICBlcnJvcihlcnIubWVzc2FnZSwge1xuICAgICAgICAgIGhpbnQ6IGhhc0NhcmRcbiAgICAgICAgICAgID8gXCJDYXJkcyBoYXZlIG5vIFNNUyBmb3JtIOKAlCBzZW5kIGEgdGV4dCBtZXNzYWdlIHRvIHJlYWNoIG5vbi1SQ1MgcmVjaXBpZW50c1wiXG4gICAgICAgICAgICA6IFwiRHJvcCAtLW5vLWZhbGxiYWNrIHRvIGRlbGl2ZXIgdG8gbm9uLVJDUyByZWNpcGllbnRzIGFzIFNNU1wiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgTm90Rm91bmRFcnJvcikge1xuICAgICAgICBlcnJvcihcbiAgICAgICAgICBlcnIubWVzc2FnZSA9PT0gXCJSZXNvdXJjZSBub3QgZm91bmRcIlxuICAgICAgICAgICAgPyBcIlJDUyBpc24ndCBhdmFpbGFibGUgb24geW91ciB3b3Jrc3BhY2UgeWV0LlwiXG4gICAgICAgICAgICA6IGVyci5tZXNzYWdlLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGhpbnQ6IFwiUkNTIGlzIHJvbGxpbmcgb3V0IGdyYWR1YWxseSDigJQgY29udGFjdCBzdXBwb3J0QHNlbmRseS5saXZlIGZvciBlYXJseSBhY2Nlc3MuXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgQXBpS2V5UmVxdWlyZWRFcnJvcikge1xuICAgICAgICBlcnJvcihcIlJDUyBtZXNzYWdlcyByZXF1aXJlIGEgbGl2ZSBBUEkga2V5LlwiLCB7XG4gICAgICAgICAgaGludDogXCJSQ1MgZGVsaXZlcnkgaXMgbmV2ZXIgc2ltdWxhdGVkIG9uIGEgdGVzdCBrZXkg4oCUIGNyZWF0ZSBvbmUgd2l0aCBgc2VuZGx5IGtleXMgY3JlYXRlIC0tdHlwZSBsaXZlYFwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGVyciBpbnN0YW5jZW9mIFZhbGlkYXRpb25FcnJvciAmJlxuICAgICAgICAvbW9yZSB0aGFuIG9uZSBSQ1MgYWdlbnQvaS50ZXN0KGVyci5tZXNzYWdlID8/IFwiXCIpXG4gICAgICApIHtcbiAgICAgICAgZXJyb3IoZXJyLm1lc3NhZ2UsIHtcbiAgICAgICAgICBoaW50OiBcIlBhc3MgLS1hZ2VudCA8aWQ+IOKAlCBsaXN0IHRoZW0gd2l0aCBgc2VuZGx5IHJjcyBhZ2VudHNgXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXJyIGluc3RhbmNlb2YgQXV0aGVudGljYXRpb25FcnJvciAmJlxuICAgICAgICAvb3B0ZWQgb3V0L2kudGVzdChlcnIubWVzc2FnZSA/PyBcIlwiKVxuICAgICAgKSB7XG4gICAgICAgIGVycm9yKGVyci5tZXNzYWdlKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGVyciBpbnN0YW5jZW9mIEF1dGhlbnRpY2F0aW9uRXJyb3IgJiZcbiAgICAgICAgL2FnZW50L2kudGVzdChlcnIubWVzc2FnZSA/PyBcIlwiKVxuICAgICAgKSB7XG4gICAgICAgIGVycm9yKGVyci5tZXNzYWdlLCB7XG4gICAgICAgICAgaGludDogXCJTZWUgd2hpY2ggYWdlbnRzIGNhbiBzZW5kIHdpdGggYHNlbmRseSByY3MgYWdlbnRzYFwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGVyciBpbnN0YW5jZW9mIEF1dGhlbnRpY2F0aW9uRXJyb3IgJiZcbiAgICAgICAgL3Jjc3x2ZXJpZmljYXRpb258bm90IHN1cHBvcnRlZHxyZWdpc3RyYXRpb24vaS50ZXN0KGVyci5tZXNzYWdlID8/IFwiXCIpXG4gICAgICApIHtcbiAgICAgICAgZXJyb3IoZXJyLm1lc3NhZ2UsIHtcbiAgICAgICAgICBoaW50OiBcIlRoaXMgcmVjaXBpZW50IGNhbid0IHJlY2VpdmUgUkNTIGFuZCB5b3VyIGFjY291bnQgY2FuJ3Qgc2VuZCBTTVMgdG8gdGhpcyBkZXN0aW5hdGlvbiDigJQgY29tcGxldGUgdmVyaWZpY2F0aW9uLCBvciBtZXNzYWdlIGFuIFJDUy1jYXBhYmxlIHJlY2lwaWVudFwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZXhpdCgxKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
package/dist/commands/send.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export default class Send extends AuthenticatedCommand {
|
|
|
6
6
|
to: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
7
7
|
text: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
8
|
from: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
"idempotency-key": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
10
|
json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
10
11
|
quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
12
|
};
|
package/dist/commands/send.js
CHANGED
|
@@ -25,6 +25,9 @@ export default class Send extends AuthenticatedCommand {
|
|
|
25
25
|
char: "f",
|
|
26
26
|
description: "Sender phone number (optional, uses default if not set)",
|
|
27
27
|
}),
|
|
28
|
+
"idempotency-key": Flags.string({
|
|
29
|
+
description: "Idempotency key (1-255 printable ASCII characters). Re-running with the same key within 24 hours returns the original result instead of sending again.",
|
|
30
|
+
}),
|
|
28
31
|
};
|
|
29
32
|
async run() {
|
|
30
33
|
const { flags } = await this.parse(Send);
|
|
@@ -37,7 +40,7 @@ export default class Send extends AuthenticatedCommand {
|
|
|
37
40
|
to: flags.to,
|
|
38
41
|
text: flags.text,
|
|
39
42
|
...(flags.from && { from: flags.from }),
|
|
40
|
-
});
|
|
43
|
+
}, true, { idempotencyKey: flags["idempotency-key"] });
|
|
41
44
|
sendSpinner.stop();
|
|
42
45
|
if (isJsonMode()) {
|
|
43
46
|
json(response);
|
|
@@ -72,4 +75,4 @@ export default class Send extends AuthenticatedCommand {
|
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9zZW5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQVEsTUFBTSxhQUFhLENBQUM7QUFDMUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sRUFDTCxPQUFPLEVBQ1AsS0FBSyxFQUNMLElBQUksRUFDSixNQUFNLEVBQ04sT0FBTyxFQUNQLFVBQVUsR0FDWCxNQUFNLGtCQUFrQixDQUFDO0FBYTFCLE1BQU0sQ0FBQyxPQUFPLE9BQU8sSUFBSyxTQUFRLG9CQUFvQjtJQUNwRCxNQUFNLENBQUMsV0FBVyxHQUFHLCtDQUErQyxDQUFDO0lBRXJFLE1BQU0sQ0FBQyxRQUFRLEdBQUc7UUFDaEIsMkRBQTJEO1FBQzNELDZEQUE2RDtRQUM3RCxrRUFBa0U7S0FDbkUsQ0FBQztJQUVGLE1BQU0sQ0FBQyxLQUFLLEdBQUc7UUFDYixHQUFHLG9CQUFvQixDQUFDLFNBQVM7UUFDakMsRUFBRSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDZixJQUFJLEVBQUUsR0FBRztZQUNULFdBQVcsRUFBRSx1Q0FBdUM7WUFDcEQsUUFBUSxFQUFFLElBQUk7U0FDZixDQUFDO1FBQ0YsSUFBSSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDakIsSUFBSSxFQUFFLEdBQUc7WUFDVCxXQUFXLEVBQUUsY0FBYztZQUMzQixRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUM7UUFDRixJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUNqQixJQUFJLEVBQUUsR0FBRztZQUNULFdBQVcsRUFBRSx5REFBeUQ7U0FDdkUsQ0FBQztRQUNGLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDOUIsV0FBVyxFQUNULHdKQUF3SjtTQUMzSixDQUFDO0tBQ0gsQ0FBQztJQUVGLEtBQUssQ0FBQyxHQUFHO1FBQ1AsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV6QyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUVsRCxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztZQUNsQixXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sU0FBUyxDQUFDLElBQUksQ0FDbkMsa0JBQWtCLEVBQ2xCO2dCQUNFLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDWixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUN4QyxFQUNELElBQUksRUFDSixFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUM3QyxDQUFDO1lBRUYsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO1lBRW5CLElBQUksVUFBVSxFQUFFLEVBQUUsQ0FBQztnQkFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNmLE9BQU87WUFDVCxDQUFDO1lBRUQsT0FBTyxDQUFDLGNBQWMsRUFBRTtnQkFDdEIsWUFBWSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxFQUFFO2dCQUNmLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTSxLQUFLLE1BQU07b0JBQ2hDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7b0JBQ2pDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7Z0JBQ25DLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDbkMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDO2FBQ3RDLENBQUMsQ0FBQztRQUVMLENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1lBQ2xCLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUVuQixJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLHNCQUFzQixDQUFDLEVBQUUsQ0FBQztnQkFDbEQsS0FBSyxDQUFDLHNCQUFzQixFQUFFO29CQUM1QixJQUFJLEVBQUUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLHdCQUF3QjtpQkFDM0UsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xELEtBQUssQ0FBQyw2QkFBNkIsRUFBRTtvQkFDbkMsSUFBSSxFQUFFLCtCQUErQjtpQkFDdEMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sR0FBRyxDQUFDO1lBQ1osQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZsYWdzLCBBcmdzIH0gZnJvbSBcIkBvY2xpZi9jb3JlXCI7XG5pbXBvcnQgeyBBdXRoZW50aWNhdGVkQ29tbWFuZCB9IGZyb20gXCIuLi9saWIvYmFzZS1jb21tYW5kLmpzXCI7XG5pbXBvcnQgeyBhcGlDbGllbnQgfSBmcm9tIFwiLi4vbGliL2FwaS1jbGllbnQuanNcIjtcbmltcG9ydCB7XG4gIHN1Y2Nlc3MsXG4gIGVycm9yLFxuICBqc29uLFxuICBjb2xvcnMsXG4gIHNwaW5uZXIsXG4gIGlzSnNvbk1vZGUsXG59IGZyb20gXCIuLi9saWIvb3V0cHV0LmpzXCI7XG5cbmludGVyZmFjZSBTZW5kTWVzc2FnZVJlc3BvbnNlIHtcbiAgaWQ6IHN0cmluZztcbiAgdG86IHN0cmluZztcbiAgZnJvbTogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xuICBzZWdtZW50czogbnVtYmVyO1xuICBjcmVkaXRzVXNlZDogbnVtYmVyO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VuZCBleHRlbmRzIEF1dGhlbnRpY2F0ZWRDb21tYW5kIHtcbiAgc3RhdGljIGRlc2NyaXB0aW9uID0gXCJTZW5kIGFuIFNNUyBtZXNzYWdlIChzaG9ydGN1dCBmb3IgJ3NtcyBzZW5kJylcIjtcblxuICBzdGF0aWMgZXhhbXBsZXMgPSBbXG4gICAgJzwlPSBjb25maWcuYmluICU+IHNlbmQgLS10byBcIisxMjM0NTY3ODkwXCIgLS10ZXh0IFwiSGVsbG8hXCInLFxuICAgICc8JT0gY29uZmlnLmJpbiAlPiBzZW5kIC10IFwiKzEyMzQ1Njc4OTBcIiAtbSBcIk1lZXRpbmcgYXQgM3BtXCInLFxuICAgICc8JT0gY29uZmlnLmJpbiAlPiBzZW5kIC0tdG8gXCIrMTIzNDU2Nzg5MFwiIC0tdGV4dCBcIkhlbGxvIVwiIC0tanNvbicsXG4gIF07XG5cbiAgc3RhdGljIGZsYWdzID0ge1xuICAgIC4uLkF1dGhlbnRpY2F0ZWRDb21tYW5kLmJhc2VGbGFncyxcbiAgICB0bzogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGNoYXI6IFwidFwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiUmVjaXBpZW50IHBob25lIG51bWJlciAoRS4xNjQgZm9ybWF0KVwiLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSksXG4gICAgdGV4dDogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGNoYXI6IFwibVwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiTWVzc2FnZSB0ZXh0XCIsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9KSxcbiAgICBmcm9tOiBGbGFncy5zdHJpbmcoe1xuICAgICAgY2hhcjogXCJmXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJTZW5kZXIgcGhvbmUgbnVtYmVyIChvcHRpb25hbCwgdXNlcyBkZWZhdWx0IGlmIG5vdCBzZXQpXCIsXG4gICAgfSksXG4gICAgXCJpZGVtcG90ZW5jeS1rZXlcIjogRmxhZ3Muc3RyaW5nKHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIklkZW1wb3RlbmN5IGtleSAoMS0yNTUgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlcnMpLiBSZS1ydW5uaW5nIHdpdGggdGhlIHNhbWUga2V5IHdpdGhpbiAyNCBob3VycyByZXR1cm5zIHRoZSBvcmlnaW5hbCByZXN1bHQgaW5zdGVhZCBvZiBzZW5kaW5nIGFnYWluLlwiLFxuICAgIH0pLFxuICB9O1xuXG4gIGFzeW5jIHJ1bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGZsYWdzIH0gPSBhd2FpdCB0aGlzLnBhcnNlKFNlbmQpO1xuXG4gICAgY29uc3Qgc2VuZFNwaW5uZXIgPSBzcGlubmVyKFwiU2VuZGluZyBtZXNzYWdlLi4uXCIpO1xuXG4gICAgaWYgKCFpc0pzb25Nb2RlKCkpIHtcbiAgICAgIHNlbmRTcGlubmVyLnN0YXJ0KCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXBpQ2xpZW50LnBvc3Q8U2VuZE1lc3NhZ2VSZXNwb25zZT4oXG4gICAgICAgIFwiL2FwaS92MS9tZXNzYWdlc1wiLFxuICAgICAgICB7XG4gICAgICAgICAgdG86IGZsYWdzLnRvLFxuICAgICAgICAgIHRleHQ6IGZsYWdzLnRleHQsXG4gICAgICAgICAgLi4uKGZsYWdzLmZyb20gJiYgeyBmcm9tOiBmbGFncy5mcm9tIH0pLFxuICAgICAgICB9LFxuICAgICAgICB0cnVlLFxuICAgICAgICB7IGlkZW1wb3RlbmN5S2V5OiBmbGFnc1tcImlkZW1wb3RlbmN5LWtleVwiXSB9LFxuICAgICAgKTtcblxuICAgICAgc2VuZFNwaW5uZXIuc3RvcCgpO1xuXG4gICAgICBpZiAoaXNKc29uTW9kZSgpKSB7XG4gICAgICAgIGpzb24ocmVzcG9uc2UpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHN1Y2Nlc3MoXCJNZXNzYWdlIHNlbnRcIiwge1xuICAgICAgICBcIk1lc3NhZ2UgSURcIjogY29sb3JzLmNvZGUocmVzcG9uc2UuaWQpLFxuICAgICAgICBUbzogcmVzcG9uc2UudG8sXG4gICAgICAgIFN0YXR1czogcmVzcG9uc2Uuc3RhdHVzID09PSBcInNlbnRcIlxuICAgICAgICAgID8gY29sb3JzLnN1Y2Nlc3MocmVzcG9uc2Uuc3RhdHVzKVxuICAgICAgICAgIDogY29sb3JzLnByaW1hcnkocmVzcG9uc2Uuc3RhdHVzKSxcbiAgICAgICAgU2VnbWVudHM6IFN0cmluZyhyZXNwb25zZS5zZWdtZW50cyksXG4gICAgICAgIENyZWRpdHM6IFN0cmluZyhyZXNwb25zZS5jcmVkaXRzVXNlZCksXG4gICAgICB9KTtcblxuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBzZW5kU3Bpbm5lci5zdG9wKCk7XG5cbiAgICAgIGlmIChlcnIubWVzc2FnZT8uaW5jbHVkZXMoXCJpbnN1ZmZpY2llbnRfY3JlZGl0c1wiKSkge1xuICAgICAgICBlcnJvcihcIkluc3VmZmljaWVudCBjcmVkaXRzXCIsIHtcbiAgICAgICAgICBoaW50OiBgUnVuICR7Y29sb3JzLmNvZGUoXCJzZW5kbHkgY3JlZGl0cyBiYWxhbmNlXCIpfSB0byBjaGVjayB5b3VyIGJhbGFuY2VgLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZXJyLm1lc3NhZ2U/LmluY2x1ZGVzKFwiaW52YWxpZF9waG9uZVwiKSkge1xuICAgICAgICBlcnJvcihcIkludmFsaWQgcGhvbmUgbnVtYmVyIGZvcm1hdFwiLCB7XG4gICAgICAgICAgaGludDogXCJVc2UgRS4xNjQgZm9ybWF0OiArMTIzNDU2Nzg5MFwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZXhpdCgxKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -11,6 +11,7 @@ export default class SmsBatch extends AuthenticatedCommand {
|
|
|
11
11
|
"dry-run": import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
12
12
|
reuse: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
13
|
history: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
14
|
+
"idempotency-key": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
14
15
|
json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
15
16
|
quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
16
17
|
};
|