@brew.new/cli 0.6.0 → 0.8.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 +8 -3
- package/dist/bin.js +1434 -415
- package/dist/bin.js.map +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -31,6 +31,14 @@ var CliApiError = class extends Error {
|
|
|
31
31
|
suggestion;
|
|
32
32
|
docs;
|
|
33
33
|
requestId;
|
|
34
|
+
/**
|
|
35
|
+
* The envelope's `details` object when the API sent one — for a
|
|
36
|
+
* trigger-fire `payload_mismatch` that is `{ errors[], warnings[],
|
|
37
|
+
* payloadSchema, … }`, naming every field the payload got wrong.
|
|
38
|
+
*/
|
|
39
|
+
details;
|
|
40
|
+
/** The parsed response body exactly as received (`undefined` if not JSON). */
|
|
41
|
+
body;
|
|
34
42
|
constructor(input) {
|
|
35
43
|
super(input.message);
|
|
36
44
|
this.status = input.status;
|
|
@@ -40,8 +48,38 @@ var CliApiError = class extends Error {
|
|
|
40
48
|
this.suggestion = input.suggestion;
|
|
41
49
|
this.docs = input.docs;
|
|
42
50
|
this.requestId = input.requestId;
|
|
51
|
+
this.details = input.details;
|
|
52
|
+
this.body = input.body;
|
|
43
53
|
}
|
|
44
54
|
};
|
|
55
|
+
function errorTypeForStatus(status) {
|
|
56
|
+
switch (status) {
|
|
57
|
+
case 401:
|
|
58
|
+
return "authentication_error";
|
|
59
|
+
case 402:
|
|
60
|
+
return "payment_required";
|
|
61
|
+
case 403:
|
|
62
|
+
return "authorization_error";
|
|
63
|
+
case 404:
|
|
64
|
+
return "not_found";
|
|
65
|
+
case 409:
|
|
66
|
+
return "conflict";
|
|
67
|
+
case 429:
|
|
68
|
+
return "rate_limit";
|
|
69
|
+
case 501:
|
|
70
|
+
return "not_implemented";
|
|
71
|
+
case 503:
|
|
72
|
+
return "service_unavailable";
|
|
73
|
+
default:
|
|
74
|
+
return status >= 400 && status < 500 ? "invalid_request" : "internal_error";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function suggestionForStatus(status) {
|
|
78
|
+
if (status === 408 || status === 429 || status >= 500) {
|
|
79
|
+
return "Retry the request. If it keeps failing, contact support.";
|
|
80
|
+
}
|
|
81
|
+
return "Fix the request before sending it again \u2014 the same request fails the same way. See `details` for the specifics when present.";
|
|
82
|
+
}
|
|
45
83
|
var ConfirmationRequiredError = class extends Error {
|
|
46
84
|
envelope;
|
|
47
85
|
constructor(envelope) {
|
|
@@ -67,6 +105,7 @@ function toExitCode(error) {
|
|
|
67
105
|
}
|
|
68
106
|
function toErrorEnvelope(error) {
|
|
69
107
|
if (error instanceof BrewApiError || error instanceof CliApiError) {
|
|
108
|
+
const details = readErrorDetails(error);
|
|
70
109
|
return {
|
|
71
110
|
code: error.code,
|
|
72
111
|
type: error.type,
|
|
@@ -75,6 +114,7 @@ function toErrorEnvelope(error) {
|
|
|
75
114
|
...error.suggestion ? { suggestion: error.suggestion } : {},
|
|
76
115
|
...error.docs ? { docs: error.docs } : {},
|
|
77
116
|
...error.requestId ? { requestId: error.requestId } : {},
|
|
117
|
+
...details === void 0 ? {} : { details },
|
|
78
118
|
status: error.status
|
|
79
119
|
};
|
|
80
120
|
}
|
|
@@ -134,7 +174,10 @@ function printError(ctx, error) {
|
|
|
134
174
|
`);
|
|
135
175
|
return;
|
|
136
176
|
}
|
|
137
|
-
const lines = [
|
|
177
|
+
const lines = [
|
|
178
|
+
`brew-cli: ${envelope.message}`,
|
|
179
|
+
...formatDetailLines(envelope.details)
|
|
180
|
+
];
|
|
138
181
|
if (envelope.suggestion) {
|
|
139
182
|
lines.push(envelope.suggestion);
|
|
140
183
|
}
|
|
@@ -147,6 +190,29 @@ function printError(ctx, error) {
|
|
|
147
190
|
ctx.io.stderr.write(`${lines.join("\n")}
|
|
148
191
|
`);
|
|
149
192
|
}
|
|
193
|
+
function readErrorDetails(error) {
|
|
194
|
+
const details = error.details;
|
|
195
|
+
return isRecord(details) ? details : void 0;
|
|
196
|
+
}
|
|
197
|
+
function formatDetailLines(details) {
|
|
198
|
+
if (details === void 0) {
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
const issues = details.errors;
|
|
202
|
+
if (Array.isArray(issues) && issues.length > 0 && issues.every(isIssue)) {
|
|
203
|
+
return issues.map((issue) => {
|
|
204
|
+
const types = typeof issue.expectedType === "string" ? typeof issue.actualType === "string" ? ` (expected ${issue.expectedType}, got ${issue.actualType})` : ` (expected ${issue.expectedType})` : "";
|
|
205
|
+
return ` - ${issue.field}: ${issue.message}${types}`;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return [`Details: ${JSON.stringify(details)}`];
|
|
209
|
+
}
|
|
210
|
+
function isIssue(value) {
|
|
211
|
+
return isRecord(value) && typeof value.field === "string" && typeof value.message === "string";
|
|
212
|
+
}
|
|
213
|
+
function isRecord(value) {
|
|
214
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
215
|
+
}
|
|
150
216
|
function apiErrorStatus(error) {
|
|
151
217
|
if (error instanceof BrewApiError || error instanceof CliApiError) {
|
|
152
218
|
return error.status;
|
|
@@ -215,7 +281,7 @@ function shellQuote(token) {
|
|
|
215
281
|
|
|
216
282
|
// src/version.ts
|
|
217
283
|
var CLI_NAME = "brew-cli";
|
|
218
|
-
var CLI_VERSION = "0.
|
|
284
|
+
var CLI_VERSION = "0.8.0" ;
|
|
219
285
|
var CONFIG_KEYS = ["apiKey", "brandId", "apiUrl"];
|
|
220
286
|
function isConfigKey(value) {
|
|
221
287
|
return CONFIG_KEYS.includes(value);
|
|
@@ -286,6 +352,7 @@ var ORG_LEVEL_PATH_PREFIXES = [
|
|
|
286
352
|
"/v1/brands",
|
|
287
353
|
"/v1/usage",
|
|
288
354
|
"/v1/templates",
|
|
355
|
+
"/v1/flows",
|
|
289
356
|
"/v1/health",
|
|
290
357
|
"/v1/help",
|
|
291
358
|
"/v1/llms.txt",
|
|
@@ -668,58 +735,128 @@ function renderAutomationRows(rows) {
|
|
|
668
735
|
]);
|
|
669
736
|
}
|
|
670
737
|
|
|
671
|
-
// src/commands/
|
|
672
|
-
var
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
738
|
+
// src/commands/sends/list.ts
|
|
739
|
+
var SEND_STATUS_SUMMARY = "scheduled | queued | running | paused | completed | partially_completed | failed | canceled";
|
|
740
|
+
var sendsListCommand = defineCommand({
|
|
741
|
+
path: ["sends", "list"],
|
|
742
|
+
summary: "List sends (the unit of delivery and analytics) with lifetime stats",
|
|
743
|
+
sdkMethod: "sends.list",
|
|
744
|
+
route: { method: "GET", path: "/v1/sends" },
|
|
677
745
|
commandClass: "read",
|
|
678
|
-
flags: [
|
|
746
|
+
flags: [
|
|
747
|
+
{ flag: "--email <emailId>", summary: "Only sends of this design" },
|
|
748
|
+
{ flag: "--kind <kind>", summary: "campaign | automation" },
|
|
749
|
+
{ flag: "--automation <automationId>", summary: "Filter by automation" },
|
|
750
|
+
{
|
|
751
|
+
flag: "--automation-run <automationRunId>",
|
|
752
|
+
summary: "Deliveries of one automation run"
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
flag: "--audience-run <audienceRunId>",
|
|
756
|
+
summary: "Deliveries of one manual-audience run"
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
flag: "--trigger-instance <triggerInstanceId>",
|
|
760
|
+
summary: "Deliveries started by one fired trigger instance"
|
|
761
|
+
},
|
|
762
|
+
{ flag: "--status <status>", summary: SEND_STATUS_SUMMARY },
|
|
763
|
+
{
|
|
764
|
+
flag: "--message-class <class>",
|
|
765
|
+
summary: "marketing | transactional"
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
flag: "--since <datetime>",
|
|
769
|
+
summary: "Inclusive lower bound on updatedAt (ISO-8601)"
|
|
770
|
+
},
|
|
771
|
+
{
|
|
772
|
+
flag: "--until <datetime>",
|
|
773
|
+
summary: "Inclusive upper bound on updatedAt (ISO-8601)"
|
|
774
|
+
},
|
|
775
|
+
LIMIT_FLAG,
|
|
776
|
+
CURSOR_FLAG,
|
|
777
|
+
ALL_FLAG,
|
|
778
|
+
INPUT_FLAG
|
|
779
|
+
],
|
|
679
780
|
examples: [
|
|
680
|
-
"brew-cli
|
|
681
|
-
"brew-cli
|
|
781
|
+
"brew-cli sends list --status completed",
|
|
782
|
+
"brew-cli sends list --email eml_1 --all --json",
|
|
783
|
+
"brew-cli sends list --automation-run arun_9f2kX"
|
|
682
784
|
],
|
|
683
785
|
run: async ({ ctx, flags }) => {
|
|
684
786
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
685
787
|
const input = mergeInput(base, {
|
|
788
|
+
emailId: flagString(flags.email),
|
|
789
|
+
kind: flagString(flags.kind),
|
|
790
|
+
automationId: flagString(flags.automation),
|
|
791
|
+
automationRunId: flagString(flags.automationRun),
|
|
792
|
+
audienceRunId: flagString(flags.audienceRun),
|
|
793
|
+
triggerInstanceId: flagString(flags.triggerInstance),
|
|
794
|
+
status: flagString(flags.status),
|
|
795
|
+
messageClass: flagString(flags.messageClass),
|
|
796
|
+
from: flagString(flags.since),
|
|
797
|
+
to: flagString(flags.until),
|
|
686
798
|
limit: flagInt(flags.limit, "--limit"),
|
|
687
799
|
cursor: flagString(flags.cursor)
|
|
688
800
|
});
|
|
689
|
-
|
|
690
|
-
if (flags.all === true) {
|
|
691
|
-
const rows = await collectAll(
|
|
692
|
-
ctx,
|
|
693
|
-
(cursor) => analytics.campaigns(
|
|
694
|
-
asSdkInput({
|
|
695
|
-
...input,
|
|
696
|
-
...cursor === void 0 ? {} : { cursor }
|
|
697
|
-
})
|
|
698
|
-
)
|
|
699
|
-
);
|
|
700
|
-
return {
|
|
701
|
-
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
702
|
-
human: renderCampaigns(rows)
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
const result = await analytics.campaigns(
|
|
706
|
-
asSdkInput(input)
|
|
707
|
-
);
|
|
708
|
-
return { data: result, human: renderCampaigns(result.data) };
|
|
801
|
+
return await listSends(ctx, input, flags.all === true);
|
|
709
802
|
}
|
|
710
803
|
});
|
|
711
|
-
function
|
|
804
|
+
async function listSends(ctx, input, followCursor) {
|
|
805
|
+
const sends = ctx.client().sends;
|
|
806
|
+
if (followCursor) {
|
|
807
|
+
const rows = await collectAll(
|
|
808
|
+
ctx,
|
|
809
|
+
(cursor) => sends.list(
|
|
810
|
+
asSdkInput({
|
|
811
|
+
...input,
|
|
812
|
+
...cursor === void 0 ? {} : { cursor }
|
|
813
|
+
})
|
|
814
|
+
)
|
|
815
|
+
);
|
|
816
|
+
return {
|
|
817
|
+
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
818
|
+
human: renderSends(rows)
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
const result = await sends.list(asSdkInput(input));
|
|
822
|
+
return { data: result, human: renderSends(result.data) };
|
|
823
|
+
}
|
|
824
|
+
function renderSends(rows) {
|
|
712
825
|
if (rows.length === 0) {
|
|
713
|
-
return "No
|
|
826
|
+
return "No sends found.";
|
|
714
827
|
}
|
|
715
828
|
return renderTable(rows, [
|
|
716
829
|
{ key: "sendId", header: "SEND" },
|
|
717
|
-
{ key: "
|
|
830
|
+
{ key: "kind", header: "KIND" },
|
|
718
831
|
{ key: "status", header: "STATUS" },
|
|
719
|
-
{ key: "
|
|
832
|
+
{ key: "subject", header: "SUBJECT" }
|
|
720
833
|
]);
|
|
721
834
|
}
|
|
722
835
|
|
|
836
|
+
// src/commands/analytics/campaigns.ts
|
|
837
|
+
var analyticsCampaignsCommand = defineCommand({
|
|
838
|
+
path: ["analytics", "campaigns"],
|
|
839
|
+
summary: "Lifetime per-campaign KPIs (`sends list --kind campaign`; stats ride each row)",
|
|
840
|
+
sdkMethod: null,
|
|
841
|
+
derivedFrom: "sends.list",
|
|
842
|
+
route: { method: "GET", path: "/v1/sends" },
|
|
843
|
+
commandClass: "read",
|
|
844
|
+
flags: [LIMIT_FLAG, CURSOR_FLAG, ALL_FLAG, INPUT_FLAG],
|
|
845
|
+
examples: [
|
|
846
|
+
"brew-cli analytics campaigns",
|
|
847
|
+
"brew-cli analytics campaigns --all --json"
|
|
848
|
+
],
|
|
849
|
+
run: async ({ ctx, flags }) => {
|
|
850
|
+
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
851
|
+
const input = mergeInput(base, {
|
|
852
|
+
kind: "campaign",
|
|
853
|
+
limit: flagInt(flags.limit, "--limit"),
|
|
854
|
+
cursor: flagString(flags.cursor)
|
|
855
|
+
});
|
|
856
|
+
return await listSends(ctx, input, flags.all === true);
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
|
|
723
860
|
// src/commands/analytics/events.ts
|
|
724
861
|
var analyticsEventsCommand = defineCommand({
|
|
725
862
|
path: ["analytics", "events"],
|
|
@@ -730,7 +867,10 @@ var analyticsEventsCommand = defineCommand({
|
|
|
730
867
|
flags: [
|
|
731
868
|
{ flag: "--since <datetime>", summary: "Window start (ISO-8601)" },
|
|
732
869
|
{ flag: "--until <datetime>", summary: "Window end (ISO-8601)" },
|
|
733
|
-
{
|
|
870
|
+
{
|
|
871
|
+
flag: "--recipient <rules>",
|
|
872
|
+
summary: "CSV of recipient rules (max 10): an address, @domain, or substring; prefix ! to exclude"
|
|
873
|
+
},
|
|
734
874
|
{
|
|
735
875
|
flag: "--event-type <type>",
|
|
736
876
|
summary: "Filter by event type (e.g. opened, clicked)"
|
|
@@ -751,7 +891,7 @@ var analyticsEventsCommand = defineCommand({
|
|
|
751
891
|
const input = mergeInput(base, {
|
|
752
892
|
from: flagString(flags.since),
|
|
753
893
|
to: flagString(flags.until),
|
|
754
|
-
|
|
894
|
+
recipient: flagString(flags.recipient),
|
|
755
895
|
eventType: flagString(flags.eventType),
|
|
756
896
|
automationId: flagString(flags.automation),
|
|
757
897
|
sendId: flagString(flags.send),
|
|
@@ -852,10 +992,10 @@ var analyticsOverviewCommand = defineCommand({
|
|
|
852
992
|
// src/commands/analytics/sends/get.ts
|
|
853
993
|
var analyticsSendsGetCommand = defineCommand({
|
|
854
994
|
path: ["analytics", "sends", "get"],
|
|
855
|
-
summary: "Fetch one send by id",
|
|
995
|
+
summary: "Fetch one send by id \u2014 the bare row (`sends get`)",
|
|
856
996
|
sdkMethod: null,
|
|
857
|
-
derivedFrom: "
|
|
858
|
-
route: { method: "GET", path: "/v1/
|
|
997
|
+
derivedFrom: "sends.get",
|
|
998
|
+
route: { method: "GET", path: "/v1/sends/{sendId}" },
|
|
859
999
|
commandClass: "read",
|
|
860
1000
|
args: [
|
|
861
1001
|
{
|
|
@@ -875,46 +1015,54 @@ var analyticsSendsGetCommand = defineCommand({
|
|
|
875
1015
|
"brew-cli analytics sends get snd_123 --include events"
|
|
876
1016
|
],
|
|
877
1017
|
run: async ({ ctx, args, flags }) => {
|
|
878
|
-
const sendId = args.sendId ?? "";
|
|
879
1018
|
const include = flagString(flags.include);
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
sendId,
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
const send = result.data[0];
|
|
887
|
-
if (send === void 0) {
|
|
888
|
-
throw new CliApiError({
|
|
889
|
-
status: 404,
|
|
890
|
-
code: "SEND_NOT_FOUND",
|
|
891
|
-
type: "not_found",
|
|
892
|
-
message: `No send found for ${sendId}`,
|
|
893
|
-
suggestion: "List sends with `brew-cli analytics sends list`."
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
return { data: send };
|
|
1019
|
+
return {
|
|
1020
|
+
data: await ctx.client().sends.get(
|
|
1021
|
+
args.sendId ?? "",
|
|
1022
|
+
include === void 0 ? void 0 : { include }
|
|
1023
|
+
)
|
|
1024
|
+
};
|
|
897
1025
|
}
|
|
898
1026
|
});
|
|
899
1027
|
|
|
1028
|
+
// src/lib/compat.ts
|
|
1029
|
+
function singleRowPage(row) {
|
|
1030
|
+
return { data: [row], pagination: { cursor: null, hasMore: false } };
|
|
1031
|
+
}
|
|
1032
|
+
function inputField(base, key) {
|
|
1033
|
+
if (base === null || typeof base !== "object") {
|
|
1034
|
+
return void 0;
|
|
1035
|
+
}
|
|
1036
|
+
const value = base[key];
|
|
1037
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
1038
|
+
}
|
|
1039
|
+
function includeRidesDetailRead(getCommand, idFlag) {
|
|
1040
|
+
const pairing = idFlag === void 0 ? "" : `, or pair it with ${idFlag}`;
|
|
1041
|
+
return new CliUsageError(
|
|
1042
|
+
`--include rides the detail read: use \`brew-cli ${getCommand} <id> --include \u2026\`${pairing}.`
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
900
1046
|
// src/commands/analytics/sends/list.ts
|
|
901
1047
|
var analyticsSendsListCommand = defineCommand({
|
|
902
1048
|
path: ["analytics", "sends", "list"],
|
|
903
|
-
summary: "List campaign/automation sends with delivery stats",
|
|
904
|
-
sdkMethod:
|
|
905
|
-
|
|
1049
|
+
summary: "List campaign/automation sends with delivery stats (`sends list`)",
|
|
1050
|
+
sdkMethod: null,
|
|
1051
|
+
derivedFrom: "sends.list",
|
|
1052
|
+
route: { method: "GET", path: "/v1/sends" },
|
|
906
1053
|
commandClass: "read",
|
|
907
1054
|
flags: [
|
|
908
|
-
{ flag: "--send <sendId>", summary: "Fetch one send (single-row page)" },
|
|
909
|
-
{ flag: "--email <emailId>", summary: "Filter by email design" },
|
|
910
1055
|
{
|
|
911
|
-
flag: "--
|
|
912
|
-
summary: "
|
|
1056
|
+
flag: "--send <sendId>",
|
|
1057
|
+
summary: "0.6 shim: read ONE send as a single-row page (`sends get` is the real read)"
|
|
913
1058
|
},
|
|
914
1059
|
{
|
|
915
|
-
flag: "--
|
|
916
|
-
summary: "
|
|
1060
|
+
flag: "--include <tokens>",
|
|
1061
|
+
summary: "With --send only: detail includes (`events`)"
|
|
917
1062
|
},
|
|
1063
|
+
{ flag: "--email <emailId>", summary: "Filter by email design" },
|
|
1064
|
+
{ flag: "--kind <kind>", summary: "campaign | automation" },
|
|
1065
|
+
{ flag: "--status <status>", summary: SEND_STATUS_SUMMARY },
|
|
918
1066
|
{ flag: "--since <datetime>", summary: "Window start (ISO-8601)" },
|
|
919
1067
|
{ flag: "--until <datetime>", summary: "Window end (ISO-8601)" },
|
|
920
1068
|
LIMIT_FLAG,
|
|
@@ -923,59 +1071,105 @@ var analyticsSendsListCommand = defineCommand({
|
|
|
923
1071
|
INPUT_FLAG
|
|
924
1072
|
],
|
|
925
1073
|
examples: [
|
|
926
|
-
"brew-cli analytics sends list --status
|
|
927
|
-
"brew-cli analytics sends list --email
|
|
1074
|
+
"brew-cli analytics sends list --status completed",
|
|
1075
|
+
"brew-cli analytics sends list --email eml_1 --all --json"
|
|
928
1076
|
],
|
|
929
1077
|
run: async ({ ctx, flags }) => {
|
|
930
1078
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
1079
|
+
const sendId = flagString(flags.send) ?? inputField(base, "sendId");
|
|
1080
|
+
const include = flagString(flags.include) ?? inputField(base, "include");
|
|
1081
|
+
if (sendId !== void 0) {
|
|
1082
|
+
const row = await ctx.client().sends.get(sendId, include === void 0 ? void 0 : { include });
|
|
1083
|
+
return { data: singleRowPage(row), human: renderSends([row]) };
|
|
1084
|
+
}
|
|
1085
|
+
if (include !== void 0) {
|
|
1086
|
+
throw includeRidesDetailRead("sends get", "--send");
|
|
1087
|
+
}
|
|
931
1088
|
const input = mergeInput(base, {
|
|
932
|
-
sendId: flagString(flags.send),
|
|
933
1089
|
emailId: flagString(flags.email),
|
|
934
|
-
|
|
1090
|
+
kind: flagString(flags.kind),
|
|
935
1091
|
status: flagString(flags.status),
|
|
936
1092
|
from: flagString(flags.since),
|
|
937
1093
|
to: flagString(flags.until),
|
|
938
1094
|
limit: flagInt(flags.limit, "--limit"),
|
|
939
1095
|
cursor: flagString(flags.cursor)
|
|
940
1096
|
});
|
|
941
|
-
|
|
942
|
-
if (flags.all === true) {
|
|
943
|
-
const rows = await collectAll(
|
|
944
|
-
ctx,
|
|
945
|
-
(cursor) => sends.list(
|
|
946
|
-
asSdkInput({
|
|
947
|
-
...input,
|
|
948
|
-
...cursor === void 0 ? {} : { cursor }
|
|
949
|
-
})
|
|
950
|
-
)
|
|
951
|
-
);
|
|
952
|
-
return {
|
|
953
|
-
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
954
|
-
human: renderSends(rows)
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
const result = await sends.list(asSdkInput(input));
|
|
958
|
-
return { data: result, human: renderSends(result.data) };
|
|
1097
|
+
return await listSends(ctx, input, flags.all === true);
|
|
959
1098
|
}
|
|
960
1099
|
});
|
|
961
|
-
|
|
1100
|
+
|
|
1101
|
+
// src/commands/automations/trigger-instances/list.ts
|
|
1102
|
+
var automationsTriggerInstancesListCommand = defineCommand({
|
|
1103
|
+
path: ["automations", "trigger-instances", "list"],
|
|
1104
|
+
summary: "List fired-trigger instances (the inbound-fire audit log); each row carries a lifecycle `state`",
|
|
1105
|
+
sdkMethod: "automations.triggerInstances.list",
|
|
1106
|
+
route: { method: "GET", path: "/v1/automations/trigger-instances" },
|
|
1107
|
+
commandClass: "read",
|
|
1108
|
+
flags: [
|
|
1109
|
+
{
|
|
1110
|
+
flag: "--trigger <triggerEventId>",
|
|
1111
|
+
summary: "Filter by trigger event"
|
|
1112
|
+
},
|
|
1113
|
+
LIMIT_FLAG,
|
|
1114
|
+
CURSOR_FLAG,
|
|
1115
|
+
ALL_FLAG,
|
|
1116
|
+
INPUT_FLAG
|
|
1117
|
+
],
|
|
1118
|
+
examples: [
|
|
1119
|
+
"brew-cli automations trigger-instances list --trigger tri_signup",
|
|
1120
|
+
"brew-cli automations trigger-instances list --all --json"
|
|
1121
|
+
],
|
|
1122
|
+
run: async ({ ctx, flags }) => {
|
|
1123
|
+
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
1124
|
+
const input = mergeInput(base, {
|
|
1125
|
+
triggerEventId: flagString(flags.trigger),
|
|
1126
|
+
limit: flagInt(flags.limit, "--limit"),
|
|
1127
|
+
cursor: flagString(flags.cursor)
|
|
1128
|
+
});
|
|
1129
|
+
return await listTriggerInstances(ctx, input, flags.all === true);
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
async function listTriggerInstances(ctx, input, followCursor) {
|
|
1133
|
+
const triggerInstances = ctx.client().automations.triggerInstances;
|
|
1134
|
+
if (followCursor) {
|
|
1135
|
+
const rows = await collectAll(
|
|
1136
|
+
ctx,
|
|
1137
|
+
(cursor) => triggerInstances.list(
|
|
1138
|
+
asSdkInput({
|
|
1139
|
+
...input,
|
|
1140
|
+
...cursor === void 0 ? {} : { cursor }
|
|
1141
|
+
})
|
|
1142
|
+
)
|
|
1143
|
+
);
|
|
1144
|
+
return {
|
|
1145
|
+
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
1146
|
+
human: renderInstances(rows)
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
const result = await triggerInstances.list(
|
|
1150
|
+
asSdkInput(input)
|
|
1151
|
+
);
|
|
1152
|
+
return { data: result, human: renderInstances(result.data) };
|
|
1153
|
+
}
|
|
1154
|
+
function renderInstances(rows) {
|
|
962
1155
|
if (rows.length === 0) {
|
|
963
|
-
return "No
|
|
1156
|
+
return "No trigger instances found.";
|
|
964
1157
|
}
|
|
965
1158
|
return renderTable(rows, [
|
|
966
|
-
{ key: "
|
|
967
|
-
{ key: "
|
|
968
|
-
{ key: "
|
|
969
|
-
{ key: "
|
|
1159
|
+
{ key: "triggerInstanceId", header: "INSTANCE" },
|
|
1160
|
+
{ key: "source", header: "SOURCE" },
|
|
1161
|
+
{ key: "state", header: "STATE" },
|
|
1162
|
+
{ key: "receivedAt", header: "RECEIVED" }
|
|
970
1163
|
]);
|
|
971
1164
|
}
|
|
972
1165
|
|
|
973
1166
|
// src/commands/analytics/trigger-instances/list.ts
|
|
974
1167
|
var analyticsTriggerInstancesListCommand = defineCommand({
|
|
975
1168
|
path: ["analytics", "trigger-instances", "list"],
|
|
976
|
-
summary: "List fired-trigger instances (
|
|
977
|
-
sdkMethod:
|
|
978
|
-
|
|
1169
|
+
summary: "List fired-trigger instances with their lifecycle `state` (`automations trigger-instances list`)",
|
|
1170
|
+
sdkMethod: null,
|
|
1171
|
+
derivedFrom: "automations.triggerInstances.list",
|
|
1172
|
+
route: { method: "GET", path: "/v1/automations/trigger-instances" },
|
|
979
1173
|
commandClass: "read",
|
|
980
1174
|
flags: [
|
|
981
1175
|
{
|
|
@@ -984,7 +1178,7 @@ var analyticsTriggerInstancesListCommand = defineCommand({
|
|
|
984
1178
|
},
|
|
985
1179
|
{
|
|
986
1180
|
flag: "--trigger-instance <triggerInstanceId>",
|
|
987
|
-
summary: "
|
|
1181
|
+
summary: "0.6 shim: read ONE instance as a single-row page (`automations trigger-instances get` is the real read)"
|
|
988
1182
|
},
|
|
989
1183
|
LIMIT_FLAG,
|
|
990
1184
|
CURSOR_FLAG,
|
|
@@ -992,50 +1186,24 @@ var analyticsTriggerInstancesListCommand = defineCommand({
|
|
|
992
1186
|
INPUT_FLAG
|
|
993
1187
|
],
|
|
994
1188
|
examples: [
|
|
995
|
-
"brew-cli analytics trigger-instances list --trigger
|
|
1189
|
+
"brew-cli analytics trigger-instances list --trigger tri_signup",
|
|
996
1190
|
"brew-cli analytics trigger-instances list --all --json"
|
|
997
1191
|
],
|
|
998
1192
|
run: async ({ ctx, flags }) => {
|
|
999
1193
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
1194
|
+
const triggerInstanceId = flagString(flags.triggerInstance) ?? inputField(base, "triggerInstanceId");
|
|
1195
|
+
if (triggerInstanceId !== void 0) {
|
|
1196
|
+
const row = await ctx.client().automations.triggerInstances.get(triggerInstanceId);
|
|
1197
|
+
return { data: singleRowPage(row), human: renderInstances([row]) };
|
|
1198
|
+
}
|
|
1000
1199
|
const input = mergeInput(base, {
|
|
1001
1200
|
triggerEventId: flagString(flags.trigger),
|
|
1002
|
-
triggerInstanceId: flagString(flags.triggerInstance),
|
|
1003
1201
|
limit: flagInt(flags.limit, "--limit"),
|
|
1004
1202
|
cursor: flagString(flags.cursor)
|
|
1005
1203
|
});
|
|
1006
|
-
|
|
1007
|
-
if (flags.all === true) {
|
|
1008
|
-
const rows = await collectAll(
|
|
1009
|
-
ctx,
|
|
1010
|
-
(cursor) => triggerInstances.list(
|
|
1011
|
-
asSdkInput({
|
|
1012
|
-
...input,
|
|
1013
|
-
...cursor === void 0 ? {} : { cursor }
|
|
1014
|
-
})
|
|
1015
|
-
)
|
|
1016
|
-
);
|
|
1017
|
-
return {
|
|
1018
|
-
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
1019
|
-
human: renderInstances(rows)
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
1022
|
-
const result = await triggerInstances.list(
|
|
1023
|
-
asSdkInput(input)
|
|
1024
|
-
);
|
|
1025
|
-
return { data: result, human: renderInstances(result.data) };
|
|
1204
|
+
return await listTriggerInstances(ctx, input, flags.all === true);
|
|
1026
1205
|
}
|
|
1027
1206
|
});
|
|
1028
|
-
function renderInstances(rows) {
|
|
1029
|
-
if (rows.length === 0) {
|
|
1030
|
-
return "No trigger instances found.";
|
|
1031
|
-
}
|
|
1032
|
-
return renderTable(rows, [
|
|
1033
|
-
{ key: "triggerInstanceId", header: "INSTANCE" },
|
|
1034
|
-
{ key: "source", header: "SOURCE" },
|
|
1035
|
-
{ key: "state", header: "STATE" },
|
|
1036
|
-
{ key: "receivedAt", header: "RECEIVED" }
|
|
1037
|
-
]);
|
|
1038
|
-
}
|
|
1039
1207
|
|
|
1040
1208
|
// src/lib/raw-request.ts
|
|
1041
1209
|
async function rawRequest(ctx, request) {
|
|
@@ -1107,26 +1275,33 @@ function buildRawHeaders(input) {
|
|
|
1107
1275
|
}
|
|
1108
1276
|
function responseToApiError(response, parsed) {
|
|
1109
1277
|
const requestId = response.headers.get("x-request-id") ?? void 0;
|
|
1110
|
-
const record = parsed
|
|
1111
|
-
const
|
|
1278
|
+
const record = isRecord2(parsed) ? parsed : void 0;
|
|
1279
|
+
const standard = record !== void 0 && isRecord2(record.error) ? record.error : void 0;
|
|
1280
|
+
const envelope = standard ?? record;
|
|
1112
1281
|
const readField = (key) => {
|
|
1113
1282
|
const value = envelope?.[key];
|
|
1114
1283
|
return typeof value === "string" ? value : void 0;
|
|
1115
1284
|
};
|
|
1116
1285
|
const param = readField("param");
|
|
1117
|
-
const suggestion = readField("suggestion");
|
|
1286
|
+
const suggestion = readField("suggestion") ?? (envelope === void 0 ? void 0 : suggestionForStatus(response.status));
|
|
1118
1287
|
const docs = readField("docs");
|
|
1288
|
+
const details = isRecord2(envelope?.details) ? envelope.details : void 0;
|
|
1119
1289
|
return new CliApiError({
|
|
1120
1290
|
status: response.status,
|
|
1121
1291
|
code: readField("code") ?? "HTTP_ERROR",
|
|
1122
|
-
type: readField("type") ??
|
|
1292
|
+
type: readField("type") ?? errorTypeForStatus(response.status),
|
|
1123
1293
|
message: readField("message") ?? `Request failed with status ${response.status}`,
|
|
1124
1294
|
...param === void 0 ? {} : { param },
|
|
1125
1295
|
...suggestion === void 0 ? {} : { suggestion },
|
|
1126
1296
|
...docs === void 0 ? {} : { docs },
|
|
1127
|
-
...requestId === void 0 ? {} : { requestId }
|
|
1297
|
+
...requestId === void 0 ? {} : { requestId },
|
|
1298
|
+
...details === void 0 ? {} : { details },
|
|
1299
|
+
...parsed === void 0 ? {} : { body: parsed }
|
|
1128
1300
|
});
|
|
1129
1301
|
}
|
|
1302
|
+
function isRecord2(value) {
|
|
1303
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1304
|
+
}
|
|
1130
1305
|
function tryParseJson(text) {
|
|
1131
1306
|
try {
|
|
1132
1307
|
return JSON.parse(text);
|
|
@@ -1479,10 +1654,9 @@ var audiencesFromEventsCommand = defineCommand({
|
|
|
1479
1654
|
// src/commands/audiences/get.ts
|
|
1480
1655
|
var audiencesGetCommand = defineCommand({
|
|
1481
1656
|
path: ["audiences", "get"],
|
|
1482
|
-
summary: "Fetch one audience segment by id",
|
|
1483
|
-
sdkMethod:
|
|
1484
|
-
|
|
1485
|
-
route: { method: "GET", path: "/v1/audiences" },
|
|
1657
|
+
summary: "Fetch one audience segment by id \u2014 the bare row",
|
|
1658
|
+
sdkMethod: "audiences.get",
|
|
1659
|
+
route: { method: "GET", path: "/v1/audiences/{audienceId}" },
|
|
1486
1660
|
commandClass: "read",
|
|
1487
1661
|
args: [
|
|
1488
1662
|
{ name: "audienceId", summary: "Audience id to fetch", isRequired: true }
|
|
@@ -1490,42 +1664,35 @@ var audiencesGetCommand = defineCommand({
|
|
|
1490
1664
|
flags: [
|
|
1491
1665
|
{
|
|
1492
1666
|
flag: "--include <tokens>",
|
|
1493
|
-
summary: "Comma-separated expansions: count"
|
|
1667
|
+
summary: "Comma-separated expansions: count, build"
|
|
1494
1668
|
}
|
|
1495
1669
|
],
|
|
1496
|
-
examples: [
|
|
1670
|
+
examples: [
|
|
1671
|
+
"brew-cli audiences get aud_3k9sQ",
|
|
1672
|
+
"brew-cli audiences get aud_3k9sQ --include count,build"
|
|
1673
|
+
],
|
|
1497
1674
|
run: async ({ ctx, args, flags }) => {
|
|
1498
|
-
const audienceId = args.audienceId ?? "";
|
|
1499
1675
|
const include = flagString(flags.include);
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
throw new CliApiError({
|
|
1507
|
-
status: 404,
|
|
1508
|
-
code: "AUDIENCE_NOT_FOUND",
|
|
1509
|
-
type: "not_found",
|
|
1510
|
-
message: `No audience found for ${audienceId}`,
|
|
1511
|
-
suggestion: "List audiences with `brew-cli audiences list`."
|
|
1512
|
-
});
|
|
1513
|
-
}
|
|
1514
|
-
return { data: audience };
|
|
1676
|
+
return {
|
|
1677
|
+
data: await ctx.client().audiences.get(
|
|
1678
|
+
args.audienceId ?? "",
|
|
1679
|
+
include === void 0 ? void 0 : { include }
|
|
1680
|
+
)
|
|
1681
|
+
};
|
|
1515
1682
|
}
|
|
1516
1683
|
});
|
|
1517
1684
|
|
|
1518
1685
|
// src/commands/audiences/list.ts
|
|
1519
1686
|
var audiencesListCommand = defineCommand({
|
|
1520
1687
|
path: ["audiences", "list"],
|
|
1521
|
-
summary: "List audience segments",
|
|
1688
|
+
summary: "List audience segments; one segment is `audiences get`",
|
|
1522
1689
|
sdkMethod: "audiences.list",
|
|
1523
1690
|
route: { method: "GET", path: "/v1/audiences" },
|
|
1524
1691
|
commandClass: "read",
|
|
1525
1692
|
flags: [
|
|
1526
1693
|
{
|
|
1527
1694
|
flag: "--include <tokens>",
|
|
1528
|
-
summary: "
|
|
1695
|
+
summary: "0.6 flag: includes ride the detail read now (`audiences get --include count,build`)"
|
|
1529
1696
|
},
|
|
1530
1697
|
LIMIT_FLAG,
|
|
1531
1698
|
CURSOR_FLAG,
|
|
@@ -1534,13 +1701,15 @@ var audiencesListCommand = defineCommand({
|
|
|
1534
1701
|
],
|
|
1535
1702
|
examples: [
|
|
1536
1703
|
"brew-cli audiences list",
|
|
1537
|
-
"brew-cli audiences list --
|
|
1704
|
+
"brew-cli audiences list --limit 10",
|
|
1538
1705
|
"brew-cli audiences list --all --json"
|
|
1539
1706
|
],
|
|
1540
1707
|
run: async ({ ctx, flags }) => {
|
|
1541
1708
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
1709
|
+
if ((flagString(flags.include) ?? inputField(base, "include")) !== void 0) {
|
|
1710
|
+
throw includeRidesDetailRead("audiences get");
|
|
1711
|
+
}
|
|
1542
1712
|
const input = mergeInput(base, {
|
|
1543
|
-
include: flagString(flags.include),
|
|
1544
1713
|
limit: flagInt(flags.limit, "--limit"),
|
|
1545
1714
|
cursor: flagString(flags.cursor)
|
|
1546
1715
|
});
|
|
@@ -1607,16 +1776,45 @@ var audiencesUpdateCommand = defineCommand({
|
|
|
1607
1776
|
}
|
|
1608
1777
|
});
|
|
1609
1778
|
|
|
1610
|
-
// src/commands/automations/audience-runs/
|
|
1611
|
-
var
|
|
1612
|
-
path: ["automations", "audience-runs", "
|
|
1613
|
-
summary: "
|
|
1614
|
-
sdkMethod: "automations.audienceRuns.
|
|
1779
|
+
// src/commands/automations/audience-runs/cancel.ts
|
|
1780
|
+
var automationsAudienceRunsCancelCommand = defineCommand({
|
|
1781
|
+
path: ["automations", "audience-runs", "cancel"],
|
|
1782
|
+
summary: "Cancel a manual-audience run for good \u2014 it can never be resumed",
|
|
1783
|
+
sdkMethod: "automations.audienceRuns.cancel",
|
|
1615
1784
|
route: {
|
|
1616
1785
|
method: "POST",
|
|
1617
|
-
path: "/v1/automations/audience-runs/{audienceRunId}/
|
|
1786
|
+
path: "/v1/automations/audience-runs/{audienceRunId}/cancel"
|
|
1618
1787
|
},
|
|
1619
1788
|
commandClass: "destructive",
|
|
1789
|
+
args: [
|
|
1790
|
+
{
|
|
1791
|
+
name: "audienceRunId",
|
|
1792
|
+
summary: "Audience run id to cancel",
|
|
1793
|
+
isRequired: true
|
|
1794
|
+
}
|
|
1795
|
+
],
|
|
1796
|
+
flags: [IDEMPOTENCY_FLAG],
|
|
1797
|
+
examples: ["brew-cli automations audience-runs cancel arun_01HZ --yes"],
|
|
1798
|
+
confirmSummary: ({ args }) => `Cancel audience run ${args.audienceRunId ?? ""} for good. Emails already sent are not recalled, and a canceled run cannot be resumed.`,
|
|
1799
|
+
run: async ({ ctx, args, flags }) => ({
|
|
1800
|
+
data: await ctx.client().automations.audienceRuns.cancel(
|
|
1801
|
+
args.audienceRunId ?? "",
|
|
1802
|
+
requestOptions(flags)
|
|
1803
|
+
)
|
|
1804
|
+
})
|
|
1805
|
+
});
|
|
1806
|
+
|
|
1807
|
+
// src/commands/automations/audience-runs/control.ts
|
|
1808
|
+
var automationsAudienceRunsControlCommand = defineCommand({
|
|
1809
|
+
path: ["automations", "audience-runs", "control"],
|
|
1810
|
+
summary: "Pause, resume, or cancel an in-flight manual-audience run (0.6 form of `audience-runs pause|resume|cancel`)",
|
|
1811
|
+
sdkMethod: null,
|
|
1812
|
+
derivedFrom: [
|
|
1813
|
+
"automations.audienceRuns.pause",
|
|
1814
|
+
"automations.audienceRuns.resume",
|
|
1815
|
+
"automations.audienceRuns.cancel"
|
|
1816
|
+
],
|
|
1817
|
+
commandClass: "destructive",
|
|
1620
1818
|
args: [
|
|
1621
1819
|
{
|
|
1622
1820
|
name: "audienceRunId",
|
|
@@ -1628,7 +1826,8 @@ var automationsAudienceRunsControlCommand = defineCommand({
|
|
|
1628
1826
|
{
|
|
1629
1827
|
flag: "--action <action>",
|
|
1630
1828
|
summary: "pause (resumable) | resume | cancel (final)"
|
|
1631
|
-
}
|
|
1829
|
+
},
|
|
1830
|
+
IDEMPOTENCY_FLAG
|
|
1632
1831
|
],
|
|
1633
1832
|
examples: [
|
|
1634
1833
|
"brew-cli automations audience-runs control arun_01HZ --action pause",
|
|
@@ -1637,57 +1836,181 @@ var automationsAudienceRunsControlCommand = defineCommand({
|
|
|
1637
1836
|
// Only cancel is irreversible; pause and resume proceed ungated.
|
|
1638
1837
|
confirmSummary: ({ args, flags }) => flagString(flags.action) === "cancel" ? `Cancel audience run ${args.audienceRunId ?? ""} for good. Emails already sent are not recalled, and a canceled run cannot be resumed.` : void 0,
|
|
1639
1838
|
run: async ({ ctx, args, flags }) => {
|
|
1640
|
-
const
|
|
1641
|
-
|
|
1642
|
-
|
|
1839
|
+
const audienceRuns = ctx.client().automations.audienceRuns;
|
|
1840
|
+
const audienceRunId = args.audienceRunId ?? "";
|
|
1841
|
+
const options = requestOptions(flags);
|
|
1842
|
+
switch (flagString(flags.action)) {
|
|
1843
|
+
case "pause":
|
|
1844
|
+
return { data: await audienceRuns.pause(audienceRunId, options) };
|
|
1845
|
+
case "resume":
|
|
1846
|
+
return { data: await audienceRuns.resume(audienceRunId, options) };
|
|
1847
|
+
case "cancel":
|
|
1848
|
+
return { data: await audienceRuns.cancel(audienceRunId, options) };
|
|
1849
|
+
default:
|
|
1850
|
+
throw new CliUsageError(
|
|
1851
|
+
"--action is required: pause, resume, or cancel."
|
|
1852
|
+
);
|
|
1643
1853
|
}
|
|
1644
|
-
return {
|
|
1645
|
-
data: await ctx.client().automations.audienceRuns.control(
|
|
1646
|
-
asSdkInput({
|
|
1647
|
-
audienceRunId: args.audienceRunId ?? "",
|
|
1648
|
-
action
|
|
1649
|
-
})
|
|
1650
|
-
)
|
|
1651
|
-
};
|
|
1652
1854
|
}
|
|
1653
1855
|
});
|
|
1654
1856
|
|
|
1857
|
+
// src/commands/automations/audience-runs/get.ts
|
|
1858
|
+
var automationsAudienceRunsGetCommand = defineCommand({
|
|
1859
|
+
path: ["automations", "audience-runs", "get"],
|
|
1860
|
+
summary: "Fetch one manual-audience run by id \u2014 the bare row",
|
|
1861
|
+
sdkMethod: "automations.audienceRuns.get",
|
|
1862
|
+
route: {
|
|
1863
|
+
method: "GET",
|
|
1864
|
+
path: "/v1/automations/audience-runs/{audienceRunId}"
|
|
1865
|
+
},
|
|
1866
|
+
commandClass: "read",
|
|
1867
|
+
args: [
|
|
1868
|
+
{
|
|
1869
|
+
name: "audienceRunId",
|
|
1870
|
+
summary: "Audience run id to fetch",
|
|
1871
|
+
isRequired: true
|
|
1872
|
+
}
|
|
1873
|
+
],
|
|
1874
|
+
examples: ["brew-cli automations audience-runs get arun_01HZ"],
|
|
1875
|
+
run: async ({ ctx, args }) => ({
|
|
1876
|
+
data: await ctx.client().automations.audienceRuns.get(args.audienceRunId ?? "")
|
|
1877
|
+
})
|
|
1878
|
+
});
|
|
1879
|
+
|
|
1655
1880
|
// src/commands/automations/audience-runs/list.ts
|
|
1656
1881
|
var automationsAudienceRunsListCommand = defineCommand({
|
|
1657
1882
|
path: ["automations", "audience-runs", "list"],
|
|
1658
|
-
summary: "List manual-audience runs
|
|
1883
|
+
summary: "List manual-audience runs, newest first; one run is `automations audience-runs get`",
|
|
1659
1884
|
sdkMethod: "automations.audienceRuns.list",
|
|
1660
1885
|
route: { method: "GET", path: "/v1/automations/audience-runs" },
|
|
1661
1886
|
commandClass: "read",
|
|
1662
|
-
// The spec paginates by --limit only: no cursor, and the response carries
|
|
1663
|
-
// no pagination envelope, so there is no --all here.
|
|
1664
1887
|
flags: [
|
|
1665
1888
|
{
|
|
1666
|
-
flag: "--
|
|
1667
|
-
summary: "
|
|
1889
|
+
flag: "--automation <automationId>",
|
|
1890
|
+
summary: "Only runs of this automation"
|
|
1891
|
+
},
|
|
1892
|
+
{
|
|
1893
|
+
flag: "--automation-id <automationId>",
|
|
1894
|
+
summary: "0.6 alias of --automation"
|
|
1895
|
+
},
|
|
1896
|
+
{
|
|
1897
|
+
flag: "--audience-run-id <audienceRunId>",
|
|
1898
|
+
summary: "0.6 shim: read ONE run as a single-row page (`automations audience-runs get` is the real read)"
|
|
1668
1899
|
},
|
|
1669
1900
|
{
|
|
1670
|
-
flag: "--
|
|
1671
|
-
summary: "
|
|
1901
|
+
flag: "--status <status>",
|
|
1902
|
+
summary: "queued | scheduled | running | paused | completed | failed | canceled"
|
|
1672
1903
|
},
|
|
1673
|
-
|
|
1904
|
+
LIMIT_FLAG,
|
|
1905
|
+
CURSOR_FLAG,
|
|
1906
|
+
ALL_FLAG,
|
|
1907
|
+
INPUT_FLAG
|
|
1674
1908
|
],
|
|
1675
1909
|
examples: [
|
|
1676
1910
|
"brew-cli automations audience-runs list",
|
|
1677
|
-
"brew-cli automations audience-runs list --automation
|
|
1911
|
+
"brew-cli automations audience-runs list --automation am_123 --status running"
|
|
1678
1912
|
],
|
|
1679
1913
|
run: async ({ ctx, flags }) => {
|
|
1680
|
-
const
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
)
|
|
1689
|
-
|
|
1914
|
+
const audienceRuns = ctx.client().automations.audienceRuns;
|
|
1915
|
+
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
1916
|
+
const audienceRunId = flagString(flags.audienceRunId) ?? inputField(base, "audienceRunId");
|
|
1917
|
+
if (audienceRunId !== void 0) {
|
|
1918
|
+
const row = await audienceRuns.get(audienceRunId);
|
|
1919
|
+
return { data: singleRowPage(row), human: renderAudienceRuns([row]) };
|
|
1920
|
+
}
|
|
1921
|
+
const input = mergeInput(base, {
|
|
1922
|
+
automationId: flagString(flags.automation) ?? flagString(flags.automationId),
|
|
1923
|
+
status: flagString(flags.status),
|
|
1924
|
+
limit: flagInt(flags.limit, "--limit"),
|
|
1925
|
+
cursor: flagString(flags.cursor)
|
|
1926
|
+
});
|
|
1927
|
+
if (flags.all === true) {
|
|
1928
|
+
const rows = await collectAll(
|
|
1929
|
+
ctx,
|
|
1930
|
+
(cursor) => audienceRuns.list(
|
|
1931
|
+
asSdkInput({
|
|
1932
|
+
...input,
|
|
1933
|
+
...cursor === void 0 ? {} : { cursor }
|
|
1934
|
+
})
|
|
1935
|
+
)
|
|
1936
|
+
);
|
|
1937
|
+
return {
|
|
1938
|
+
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
1939
|
+
human: renderAudienceRuns(rows)
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
const result = await audienceRuns.list(
|
|
1943
|
+
asSdkInput(input)
|
|
1944
|
+
);
|
|
1945
|
+
return { data: result, human: renderAudienceRuns(result.data) };
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1948
|
+
function renderAudienceRuns(rows) {
|
|
1949
|
+
if (rows.length === 0) {
|
|
1950
|
+
return "No audience runs found.";
|
|
1690
1951
|
}
|
|
1952
|
+
return renderTable(rows, [
|
|
1953
|
+
{ key: "audienceRunId", header: "AUDIENCE RUN" },
|
|
1954
|
+
{ key: "automationId", header: "AUTOMATION" },
|
|
1955
|
+
{ key: "status", header: "STATUS" },
|
|
1956
|
+
{ key: "totalRecipients", header: "RECIPIENTS" }
|
|
1957
|
+
]);
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
// src/commands/automations/audience-runs/pause.ts
|
|
1961
|
+
var automationsAudienceRunsPauseCommand = defineCommand({
|
|
1962
|
+
path: ["automations", "audience-runs", "pause"],
|
|
1963
|
+
summary: "Pause a running manual-audience run at its next step boundary (resumable)",
|
|
1964
|
+
sdkMethod: "automations.audienceRuns.pause",
|
|
1965
|
+
route: {
|
|
1966
|
+
method: "POST",
|
|
1967
|
+
path: "/v1/automations/audience-runs/{audienceRunId}/pause"
|
|
1968
|
+
},
|
|
1969
|
+
commandClass: "write",
|
|
1970
|
+
args: [
|
|
1971
|
+
{
|
|
1972
|
+
name: "audienceRunId",
|
|
1973
|
+
summary: "Audience run id to pause",
|
|
1974
|
+
isRequired: true
|
|
1975
|
+
}
|
|
1976
|
+
],
|
|
1977
|
+
flags: [IDEMPOTENCY_FLAG],
|
|
1978
|
+
examples: ["brew-cli automations audience-runs pause arun_01HZ"],
|
|
1979
|
+
run: async ({ ctx, args, flags }) => ({
|
|
1980
|
+
data: await ctx.client().automations.audienceRuns.pause(
|
|
1981
|
+
args.audienceRunId ?? "",
|
|
1982
|
+
requestOptions(flags)
|
|
1983
|
+
)
|
|
1984
|
+
})
|
|
1985
|
+
});
|
|
1986
|
+
|
|
1987
|
+
// src/commands/automations/audience-runs/resume.ts
|
|
1988
|
+
var automationsAudienceRunsResumeCommand = defineCommand({
|
|
1989
|
+
path: ["automations", "audience-runs", "resume"],
|
|
1990
|
+
summary: "Resume a paused manual-audience run, or restart a failed one from its first undelivered send",
|
|
1991
|
+
sdkMethod: "automations.audienceRuns.resume",
|
|
1992
|
+
route: {
|
|
1993
|
+
method: "POST",
|
|
1994
|
+
path: "/v1/automations/audience-runs/{audienceRunId}/resume"
|
|
1995
|
+
},
|
|
1996
|
+
commandClass: "write",
|
|
1997
|
+
args: [
|
|
1998
|
+
{
|
|
1999
|
+
name: "audienceRunId",
|
|
2000
|
+
summary: "Audience run id to resume",
|
|
2001
|
+
isRequired: true
|
|
2002
|
+
}
|
|
2003
|
+
],
|
|
2004
|
+
flags: [IDEMPOTENCY_FLAG],
|
|
2005
|
+
// `resumedFrom` on the response reports which case ran: `paused` or
|
|
2006
|
+
// `failed`. A failed restart never resends a step the failed run finished.
|
|
2007
|
+
examples: ["brew-cli automations audience-runs resume arun_01HZ"],
|
|
2008
|
+
run: async ({ ctx, args, flags }) => ({
|
|
2009
|
+
data: await ctx.client().automations.audienceRuns.resume(
|
|
2010
|
+
args.audienceRunId ?? "",
|
|
2011
|
+
requestOptions(flags)
|
|
2012
|
+
)
|
|
2013
|
+
})
|
|
1691
2014
|
});
|
|
1692
2015
|
|
|
1693
2016
|
// src/commands/automations/create.ts
|
|
@@ -1755,10 +2078,9 @@ var automationsDeleteCommand = defineCommand({
|
|
|
1755
2078
|
// src/commands/automations/get.ts
|
|
1756
2079
|
var automationsGetCommand = defineCommand({
|
|
1757
2080
|
path: ["automations", "get"],
|
|
1758
|
-
summary: "Fetch one automation by id",
|
|
1759
|
-
sdkMethod:
|
|
1760
|
-
|
|
1761
|
-
route: { method: "GET", path: "/v1/automations" },
|
|
2081
|
+
summary: "Fetch one automation by id \u2014 the bare row, lean by default",
|
|
2082
|
+
sdkMethod: "automations.get",
|
|
2083
|
+
route: { method: "GET", path: "/v1/automations/{automationId}" },
|
|
1762
2084
|
commandClass: "read",
|
|
1763
2085
|
args: [
|
|
1764
2086
|
{
|
|
@@ -1770,7 +2092,7 @@ var automationsGetCommand = defineCommand({
|
|
|
1770
2092
|
flags: [
|
|
1771
2093
|
{
|
|
1772
2094
|
flag: "--include <tokens>",
|
|
1773
|
-
summary: "Comma-separated expansions: graph
|
|
2095
|
+
summary: "Comma-separated expansions: graph, versions"
|
|
1774
2096
|
}
|
|
1775
2097
|
],
|
|
1776
2098
|
examples: [
|
|
@@ -1778,23 +2100,13 @@ var automationsGetCommand = defineCommand({
|
|
|
1778
2100
|
"brew-cli automations get am_123 --include graph,versions"
|
|
1779
2101
|
],
|
|
1780
2102
|
run: async ({ ctx, args, flags }) => {
|
|
1781
|
-
const automationId = args.automationId ?? "";
|
|
1782
2103
|
const include = flagString(flags.include);
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
throw new CliApiError({
|
|
1790
|
-
status: 404,
|
|
1791
|
-
code: "AUTOMATION_NOT_FOUND",
|
|
1792
|
-
type: "not_found",
|
|
1793
|
-
message: `No automation found for ${automationId}`,
|
|
1794
|
-
suggestion: "List automations with `brew-cli automations list`."
|
|
1795
|
-
});
|
|
1796
|
-
}
|
|
1797
|
-
return { data: automation };
|
|
2104
|
+
return {
|
|
2105
|
+
data: await ctx.client().automations.get(
|
|
2106
|
+
args.automationId ?? "",
|
|
2107
|
+
include === void 0 ? void 0 : { include }
|
|
2108
|
+
)
|
|
2109
|
+
};
|
|
1798
2110
|
}
|
|
1799
2111
|
});
|
|
1800
2112
|
|
|
@@ -1918,7 +2230,7 @@ var automationsRunCommand = defineCommand({
|
|
|
1918
2230
|
],
|
|
1919
2231
|
confirmSummary: ({ args, flags }) => {
|
|
1920
2232
|
const inline = parseInlineInput(flags.input);
|
|
1921
|
-
if (flags.dryRun === true || inline?.
|
|
2233
|
+
if (flags.dryRun === true || inline?.dryRun === true) {
|
|
1922
2234
|
return;
|
|
1923
2235
|
}
|
|
1924
2236
|
const scheduleAt = flagString(flags.scheduleAt) ?? asString(inline?.scheduledAt);
|
|
@@ -1928,8 +2240,7 @@ var automationsRunCommand = defineCommand({
|
|
|
1928
2240
|
run: async ({ ctx, args, flags }) => {
|
|
1929
2241
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
1930
2242
|
const input = mergeInput(base, {
|
|
1931
|
-
|
|
1932
|
-
dry_run: flags.dryRun === true ? true : void 0,
|
|
2243
|
+
dryRun: flags.dryRun === true ? true : void 0,
|
|
1933
2244
|
scheduledAt: flagString(flags.scheduleAt)
|
|
1934
2245
|
});
|
|
1935
2246
|
return {
|
|
@@ -1957,22 +2268,89 @@ function asString(value) {
|
|
|
1957
2268
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
1958
2269
|
}
|
|
1959
2270
|
|
|
2271
|
+
// src/commands/automations/runs/cancel.ts
|
|
2272
|
+
var automationsRunsCancelCommand = defineCommand({
|
|
2273
|
+
path: ["automations", "runs", "cancel"],
|
|
2274
|
+
summary: "Cancel one in-flight automation run (event execution or test run) \u2014 nothing further is sent, and it can never be resumed",
|
|
2275
|
+
sdkMethod: "automations.runs.cancel",
|
|
2276
|
+
route: {
|
|
2277
|
+
method: "POST",
|
|
2278
|
+
path: "/v1/automations/runs/{automationRunId}/cancel"
|
|
2279
|
+
},
|
|
2280
|
+
commandClass: "destructive",
|
|
2281
|
+
args: [
|
|
2282
|
+
{
|
|
2283
|
+
name: "automationRunId",
|
|
2284
|
+
summary: "Run id to cancel (from `automations runs list`, a test start, or a fire response)",
|
|
2285
|
+
isRequired: true
|
|
2286
|
+
}
|
|
2287
|
+
],
|
|
2288
|
+
flags: [
|
|
2289
|
+
{ flag: "--reason <text>", summary: "Operator note stored on the run" },
|
|
2290
|
+
IDEMPOTENCY_FLAG
|
|
2291
|
+
],
|
|
2292
|
+
examples: [
|
|
2293
|
+
'brew-cli automations runs cancel run_9f2kX --reason "wrong audience" --yes'
|
|
2294
|
+
],
|
|
2295
|
+
confirmSummary: ({ args }) => `Cancel automation run ${args.automationRunId ?? ""}. Nothing further is sent; emails already delivered are not recalled, and a canceled run can never be resumed.`,
|
|
2296
|
+
run: async ({ ctx, args, flags }) => {
|
|
2297
|
+
const reason = flagString(flags.reason);
|
|
2298
|
+
const options = {
|
|
2299
|
+
...requestOptions(flags),
|
|
2300
|
+
...reason === void 0 ? {} : { reason }
|
|
2301
|
+
};
|
|
2302
|
+
return {
|
|
2303
|
+
data: await ctx.client().automations.runs.cancel(
|
|
2304
|
+
args.automationRunId ?? "",
|
|
2305
|
+
Object.keys(options).length === 0 ? void 0 : options
|
|
2306
|
+
)
|
|
2307
|
+
};
|
|
2308
|
+
}
|
|
2309
|
+
});
|
|
2310
|
+
|
|
2311
|
+
// src/commands/automations/runs/get.ts
|
|
2312
|
+
var automationsRunsGetCommand = defineCommand({
|
|
2313
|
+
path: ["automations", "runs", "get"],
|
|
2314
|
+
summary: "Fetch one automation run by id \u2014 the bare row",
|
|
2315
|
+
sdkMethod: "automations.runs.get",
|
|
2316
|
+
route: { method: "GET", path: "/v1/automations/runs/{automationRunId}" },
|
|
2317
|
+
commandClass: "read",
|
|
2318
|
+
args: [
|
|
2319
|
+
{
|
|
2320
|
+
name: "automationRunId",
|
|
2321
|
+
summary: "Run id (from `automations runs list`, a test start, or a fire)",
|
|
2322
|
+
isRequired: true
|
|
2323
|
+
}
|
|
2324
|
+
],
|
|
2325
|
+
flags: [
|
|
2326
|
+
{
|
|
2327
|
+
flag: "--include <tokens>",
|
|
2328
|
+
summary: "Expansions: logs (newest 100 per-node execution logs)"
|
|
2329
|
+
}
|
|
2330
|
+
],
|
|
2331
|
+
examples: [
|
|
2332
|
+
"brew-cli automations runs get run_9f2kX",
|
|
2333
|
+
"brew-cli automations runs get run_9f2kX --include logs"
|
|
2334
|
+
],
|
|
2335
|
+
run: async ({ ctx, args, flags }) => {
|
|
2336
|
+
const include = flagString(flags.include);
|
|
2337
|
+
return {
|
|
2338
|
+
data: await ctx.client().automations.runs.get(
|
|
2339
|
+
args.automationRunId ?? "",
|
|
2340
|
+
include === void 0 ? void 0 : { include }
|
|
2341
|
+
)
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
});
|
|
2345
|
+
|
|
1960
2346
|
// src/commands/automations/runs/list.ts
|
|
1961
2347
|
var automationsRunsListCommand = defineCommand({
|
|
1962
2348
|
path: ["automations", "runs", "list"],
|
|
1963
|
-
summary: "List automation runs (live + test history)",
|
|
2349
|
+
summary: "List automation runs (live + test history); one run is `automations runs get`",
|
|
1964
2350
|
sdkMethod: "automations.runs.list",
|
|
1965
2351
|
route: { method: "GET", path: "/v1/automations/runs" },
|
|
1966
2352
|
commandClass: "read",
|
|
1967
2353
|
flags: [
|
|
1968
|
-
{
|
|
1969
|
-
flag: "--run <automationRunId>",
|
|
1970
|
-
summary: "Fetch one run (single-row page)"
|
|
1971
|
-
},
|
|
1972
|
-
{
|
|
1973
|
-
flag: "--include <tokens>",
|
|
1974
|
-
summary: "Comma-separated expansions: logs"
|
|
1975
|
-
},
|
|
1976
2354
|
{ flag: "--automation <automationId>", summary: "Filter by automation" },
|
|
1977
2355
|
{
|
|
1978
2356
|
flag: "--trigger <triggerEventId>",
|
|
@@ -1982,12 +2360,23 @@ var automationsRunsListCommand = defineCommand({
|
|
|
1982
2360
|
flag: "--trigger-instance <triggerInstanceId>",
|
|
1983
2361
|
summary: "Filter by fired trigger instance"
|
|
1984
2362
|
},
|
|
1985
|
-
{ flag: "--recipient <email>", summary: "Filter by recipient email" },
|
|
1986
2363
|
{
|
|
1987
2364
|
flag: "--status <status>",
|
|
1988
|
-
summary: "
|
|
2365
|
+
summary: "queued | running | completed | failed | canceled"
|
|
1989
2366
|
},
|
|
1990
2367
|
{ flag: "--mode <mode>", summary: "live | test" },
|
|
2368
|
+
{
|
|
2369
|
+
flag: "--recipient <email>",
|
|
2370
|
+
summary: "Only runs for this recipient (case-insensitive match on the run row's recipientEmail)"
|
|
2371
|
+
},
|
|
2372
|
+
{
|
|
2373
|
+
flag: "--run <automationRunId>",
|
|
2374
|
+
summary: "0.6 shim: read ONE run as a single-row page (`automations runs get` is the real read)"
|
|
2375
|
+
},
|
|
2376
|
+
{
|
|
2377
|
+
flag: "--include <tokens>",
|
|
2378
|
+
summary: "With --run only: detail includes (`logs`)"
|
|
2379
|
+
},
|
|
1991
2380
|
{ flag: "--since <datetime>", summary: "Runs started at/after (ISO-8601)" },
|
|
1992
2381
|
{
|
|
1993
2382
|
flag: "--until <datetime>",
|
|
@@ -2000,13 +2389,24 @@ var automationsRunsListCommand = defineCommand({
|
|
|
2000
2389
|
],
|
|
2001
2390
|
examples: [
|
|
2002
2391
|
"brew-cli automations runs list --automation am_123 --status failed",
|
|
2003
|
-
"brew-cli automations runs list --
|
|
2392
|
+
"brew-cli automations runs list --trigger-instance tin_2f1c9d8a"
|
|
2004
2393
|
],
|
|
2005
2394
|
run: async ({ ctx, flags }) => {
|
|
2395
|
+
const runs = ctx.client().automations.runs;
|
|
2006
2396
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
2397
|
+
const runId = flagString(flags.run) ?? inputField(base, "automationRunId");
|
|
2398
|
+
const include = flagString(flags.include) ?? inputField(base, "include");
|
|
2399
|
+
if (runId !== void 0) {
|
|
2400
|
+
const row = await runs.get(
|
|
2401
|
+
runId,
|
|
2402
|
+
include === void 0 ? void 0 : { include }
|
|
2403
|
+
);
|
|
2404
|
+
return { data: singleRowPage(row), human: renderRuns([row]) };
|
|
2405
|
+
}
|
|
2406
|
+
if (include !== void 0) {
|
|
2407
|
+
throw includeRidesDetailRead("automations runs get", "--run");
|
|
2408
|
+
}
|
|
2007
2409
|
const input = mergeInput(base, {
|
|
2008
|
-
automationRunId: flagString(flags.run),
|
|
2009
|
-
include: flagString(flags.include),
|
|
2010
2410
|
automationId: flagString(flags.automation),
|
|
2011
2411
|
triggerEventId: flagString(flags.trigger),
|
|
2012
2412
|
triggerInstanceId: flagString(flags.triggerInstance),
|
|
@@ -2018,7 +2418,6 @@ var automationsRunsListCommand = defineCommand({
|
|
|
2018
2418
|
limit: flagInt(flags.limit, "--limit"),
|
|
2019
2419
|
cursor: flagString(flags.cursor)
|
|
2020
2420
|
});
|
|
2021
|
-
const runs = ctx.client().automations.runs;
|
|
2022
2421
|
if (flags.all === true) {
|
|
2023
2422
|
const rows = await collectAll(
|
|
2024
2423
|
ctx,
|
|
@@ -2083,6 +2482,29 @@ var automationsTestCommand = defineCommand({
|
|
|
2083
2482
|
}
|
|
2084
2483
|
});
|
|
2085
2484
|
|
|
2485
|
+
// src/commands/automations/trigger-instances/get.ts
|
|
2486
|
+
var automationsTriggerInstancesGetCommand = defineCommand({
|
|
2487
|
+
path: ["automations", "trigger-instances", "get"],
|
|
2488
|
+
summary: "Fetch one fired-trigger instance by id \u2014 the bare row, with its lifecycle `state` and the runs it started",
|
|
2489
|
+
sdkMethod: "automations.triggerInstances.get",
|
|
2490
|
+
route: {
|
|
2491
|
+
method: "GET",
|
|
2492
|
+
path: "/v1/automations/trigger-instances/{triggerInstanceId}"
|
|
2493
|
+
},
|
|
2494
|
+
commandClass: "read",
|
|
2495
|
+
args: [
|
|
2496
|
+
{
|
|
2497
|
+
name: "triggerInstanceId",
|
|
2498
|
+
summary: "Instance id returned by a fire, or by the instances list",
|
|
2499
|
+
isRequired: true
|
|
2500
|
+
}
|
|
2501
|
+
],
|
|
2502
|
+
examples: ["brew-cli automations trigger-instances get tin_2f1c9d8a"],
|
|
2503
|
+
run: async ({ ctx, args }) => ({
|
|
2504
|
+
data: await ctx.client().automations.triggerInstances.get(args.triggerInstanceId ?? "")
|
|
2505
|
+
})
|
|
2506
|
+
});
|
|
2507
|
+
|
|
2086
2508
|
// src/commands/automations/triggers/contract.ts
|
|
2087
2509
|
var FORMAT_FLAG = {
|
|
2088
2510
|
flag: "--format <format>",
|
|
@@ -2355,17 +2777,52 @@ var automationsTriggersFireCommand = defineCommand({
|
|
|
2355
2777
|
}
|
|
2356
2778
|
});
|
|
2357
2779
|
|
|
2780
|
+
// src/commands/automations/triggers/get.ts
|
|
2781
|
+
var automationsTriggersGetCommand = defineCommand({
|
|
2782
|
+
path: ["automations", "triggers", "get"],
|
|
2783
|
+
summary: "Fetch one trigger by id \u2014 the bare row with its payload schema",
|
|
2784
|
+
sdkMethod: "automations.triggers.get",
|
|
2785
|
+
route: { method: "GET", path: "/v1/automations/triggers/{triggerEventId}" },
|
|
2786
|
+
commandClass: "read",
|
|
2787
|
+
args: [
|
|
2788
|
+
{
|
|
2789
|
+
name: "triggerEventId",
|
|
2790
|
+
summary: "Trigger id (tri_\u2026, or an integration composite id)",
|
|
2791
|
+
isRequired: true
|
|
2792
|
+
}
|
|
2793
|
+
],
|
|
2794
|
+
flags: [
|
|
2795
|
+
{
|
|
2796
|
+
flag: "--include <tokens>",
|
|
2797
|
+
summary: "Expansions: skill (a SKILL.md-shaped wiring brief)"
|
|
2798
|
+
}
|
|
2799
|
+
],
|
|
2800
|
+
examples: [
|
|
2801
|
+
"brew-cli automations triggers get tri_signup",
|
|
2802
|
+
"brew-cli automations triggers get tri_signup --include skill"
|
|
2803
|
+
],
|
|
2804
|
+
run: async ({ ctx, args, flags }) => {
|
|
2805
|
+
const include = flagString(flags.include);
|
|
2806
|
+
return {
|
|
2807
|
+
data: await ctx.client().automations.triggers.get(
|
|
2808
|
+
args.triggerEventId ?? "",
|
|
2809
|
+
include === void 0 ? void 0 : { include }
|
|
2810
|
+
)
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
});
|
|
2814
|
+
|
|
2358
2815
|
// src/commands/automations/triggers/list.ts
|
|
2359
2816
|
var automationsTriggersListCommand = defineCommand({
|
|
2360
2817
|
path: ["automations", "triggers", "list"],
|
|
2361
|
-
summary: "List trigger events (their payload schemas drive fires)",
|
|
2818
|
+
summary: "List trigger events (their payload schemas drive fires); one trigger is `automations triggers get`",
|
|
2362
2819
|
sdkMethod: "automations.triggers.list",
|
|
2363
2820
|
route: { method: "GET", path: "/v1/automations/triggers" },
|
|
2364
2821
|
commandClass: "read",
|
|
2365
2822
|
flags: [
|
|
2366
2823
|
{
|
|
2367
2824
|
flag: "--trigger <triggerEventId>",
|
|
2368
|
-
summary: "
|
|
2825
|
+
summary: "0.6 shim: read ONE trigger as a single-row page (`automations triggers get` is the real read)"
|
|
2369
2826
|
},
|
|
2370
2827
|
LIMIT_FLAG,
|
|
2371
2828
|
CURSOR_FLAG,
|
|
@@ -2374,16 +2831,20 @@ var automationsTriggersListCommand = defineCommand({
|
|
|
2374
2831
|
],
|
|
2375
2832
|
examples: [
|
|
2376
2833
|
"brew-cli automations triggers list",
|
|
2377
|
-
"brew-cli automations triggers list --
|
|
2834
|
+
"brew-cli automations triggers list --all --json"
|
|
2378
2835
|
],
|
|
2379
2836
|
run: async ({ ctx, flags }) => {
|
|
2837
|
+
const triggers = ctx.client().automations.triggers;
|
|
2380
2838
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
2839
|
+
const triggerEventId = flagString(flags.trigger) ?? inputField(base, "triggerEventId");
|
|
2840
|
+
if (triggerEventId !== void 0) {
|
|
2841
|
+
const row = await triggers.get(triggerEventId);
|
|
2842
|
+
return { data: singleRowPage(row), human: renderTriggers([row]) };
|
|
2843
|
+
}
|
|
2381
2844
|
const input = mergeInput(base, {
|
|
2382
|
-
triggerEventId: flagString(flags.trigger),
|
|
2383
2845
|
limit: flagInt(flags.limit, "--limit"),
|
|
2384
2846
|
cursor: flagString(flags.cursor)
|
|
2385
2847
|
});
|
|
2386
|
-
const triggers = ctx.client().automations.triggers;
|
|
2387
2848
|
if (flags.all === true) {
|
|
2388
2849
|
const rows = await collectAll(
|
|
2389
2850
|
ctx,
|
|
@@ -2418,10 +2879,10 @@ function renderTriggers(rows) {
|
|
|
2418
2879
|
var automationsTriggersReadyCommand = defineCommand({
|
|
2419
2880
|
path: ["automations", "triggers", "ready"],
|
|
2420
2881
|
summary: "Preflight a trigger without firing: key + scope + permissions pass/fail, the payload contract, and what a fire would start",
|
|
2421
|
-
sdkMethod: "automations.triggers.
|
|
2882
|
+
sdkMethod: "automations.triggers.readiness",
|
|
2422
2883
|
route: {
|
|
2423
2884
|
method: "GET",
|
|
2424
|
-
path: "/v1/automations/triggers/{triggerEventId}/
|
|
2885
|
+
path: "/v1/automations/triggers/{triggerEventId}/readiness"
|
|
2425
2886
|
},
|
|
2426
2887
|
commandClass: "read",
|
|
2427
2888
|
args: [
|
|
@@ -2432,17 +2893,13 @@ var automationsTriggersReadyCommand = defineCommand({
|
|
|
2432
2893
|
}
|
|
2433
2894
|
],
|
|
2434
2895
|
examples: ["brew-cli automations triggers ready tri_signup"],
|
|
2435
|
-
// 200 `
|
|
2436
|
-
// trigger
|
|
2437
|
-
// logged but start no runs until a wired
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
})
|
|
2443
|
-
);
|
|
2444
|
-
return { data: result };
|
|
2445
|
-
}
|
|
2896
|
+
// 200 `ready: true` means the exact credential in use can fire this
|
|
2897
|
+
// trigger. A `NO_PUBLISHED_AUTOMATION` blocker with `ready: false` means
|
|
2898
|
+
// fires are accepted and logged but start no runs until a wired
|
|
2899
|
+
// automation is published — still a 200, because a probe has to say why.
|
|
2900
|
+
run: async ({ ctx, args }) => ({
|
|
2901
|
+
data: await ctx.client().automations.triggers.readiness(args.triggerEventId ?? "")
|
|
2902
|
+
})
|
|
2446
2903
|
});
|
|
2447
2904
|
|
|
2448
2905
|
// src/commands/automations/triggers/update.ts
|
|
@@ -2962,37 +3419,21 @@ function inlineEmailCount(input) {
|
|
|
2962
3419
|
// src/commands/contacts/get.ts
|
|
2963
3420
|
var contactsGetCommand = defineCommand({
|
|
2964
3421
|
path: ["contacts", "get"],
|
|
2965
|
-
summary: "Fetch one contact by email",
|
|
2966
|
-
sdkMethod:
|
|
2967
|
-
|
|
2968
|
-
route: { method: "POST", path: "/v1/contacts/search" },
|
|
3422
|
+
summary: "Fetch one contact by email \u2014 the bare row",
|
|
3423
|
+
sdkMethod: "contacts.get",
|
|
3424
|
+
route: { method: "GET", path: "/v1/contacts/{email}" },
|
|
2969
3425
|
commandClass: "read",
|
|
2970
3426
|
args: [
|
|
2971
3427
|
{
|
|
2972
3428
|
name: "email",
|
|
2973
|
-
summary: "Email address of the contact",
|
|
3429
|
+
summary: "Email address of the contact (the contact primary key)",
|
|
2974
3430
|
isRequired: true
|
|
2975
3431
|
}
|
|
2976
3432
|
],
|
|
2977
3433
|
examples: ["brew-cli contacts get jane@example.com"],
|
|
2978
|
-
run: async ({ ctx, args }) => {
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
filters: [{ field: "email", operator: "equals", value: email }],
|
|
2982
|
-
limit: 1
|
|
2983
|
-
});
|
|
2984
|
-
const contact = result.data[0];
|
|
2985
|
-
if (contact === void 0) {
|
|
2986
|
-
throw new CliApiError({
|
|
2987
|
-
status: 404,
|
|
2988
|
-
code: "CONTACT_NOT_FOUND",
|
|
2989
|
-
type: "not_found",
|
|
2990
|
-
message: `No contact found for ${email}`,
|
|
2991
|
-
suggestion: "Check the address, or create the contact with `brew-cli contacts upsert`."
|
|
2992
|
-
});
|
|
2993
|
-
}
|
|
2994
|
-
return { data: contact };
|
|
2995
|
-
}
|
|
3434
|
+
run: async ({ ctx, args }) => ({
|
|
3435
|
+
data: await ctx.client().contacts.get(args.email ?? "")
|
|
3436
|
+
})
|
|
2996
3437
|
});
|
|
2997
3438
|
|
|
2998
3439
|
// src/commands/contacts/import-csv.ts
|
|
@@ -3033,22 +3474,23 @@ var contactsImportCsvCommand = defineCommand({
|
|
|
3033
3474
|
}
|
|
3034
3475
|
});
|
|
3035
3476
|
|
|
3036
|
-
// src/commands/contacts/
|
|
3037
|
-
var
|
|
3038
|
-
path: ["contacts", "
|
|
3039
|
-
summary: "
|
|
3040
|
-
sdkMethod: "contacts.
|
|
3041
|
-
route: { method: "
|
|
3477
|
+
// src/commands/contacts/list.ts
|
|
3478
|
+
var contactsListCommand = defineCommand({
|
|
3479
|
+
path: ["contacts", "list"],
|
|
3480
|
+
summary: "List contacts, newest first \u2014 free-text search and one audience; typed clauses are `contacts search`",
|
|
3481
|
+
sdkMethod: "contacts.list",
|
|
3482
|
+
route: { method: "GET", path: "/v1/contacts" },
|
|
3042
3483
|
commandClass: "read",
|
|
3043
3484
|
flags: [
|
|
3044
3485
|
{ flag: "--search <text>", summary: "Free-text search" },
|
|
3045
3486
|
{
|
|
3046
|
-
flag: "--
|
|
3047
|
-
summary: "
|
|
3487
|
+
flag: "--audience <audienceId>",
|
|
3488
|
+
summary: "Only members of this saved audience"
|
|
3489
|
+
},
|
|
3490
|
+
{
|
|
3491
|
+
flag: "--sort <field>",
|
|
3492
|
+
summary: "Any core column or custom field (default createdAt)"
|
|
3048
3493
|
},
|
|
3049
|
-
{ flag: "--audience <audienceId>", summary: "Scope to one audience" },
|
|
3050
|
-
{ flag: "--logic <logic>", summary: "Filter combinator: and | or" },
|
|
3051
|
-
{ flag: "--sort <field>", summary: "Sort field" },
|
|
3052
3494
|
{ flag: "--order <order>", summary: "Sort order: asc | desc" },
|
|
3053
3495
|
LIMIT_FLAG,
|
|
3054
3496
|
CURSOR_FLAG,
|
|
@@ -3056,17 +3498,15 @@ var contactsSearchCommand = defineCommand({
|
|
|
3056
3498
|
INPUT_FLAG
|
|
3057
3499
|
],
|
|
3058
3500
|
examples: [
|
|
3059
|
-
"brew-cli contacts
|
|
3060
|
-
"brew-cli contacts
|
|
3061
|
-
"brew-cli contacts search --
|
|
3501
|
+
"brew-cli contacts list --limit 20",
|
|
3502
|
+
"brew-cli contacts list --audience aud_3k9sQ --all --json",
|
|
3503
|
+
"brew-cli contacts list --search acme --sort email --order asc"
|
|
3062
3504
|
],
|
|
3063
3505
|
run: async ({ ctx, flags }) => {
|
|
3064
3506
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
3065
3507
|
const input = mergeInput(base, {
|
|
3066
3508
|
search: flagString(flags.search),
|
|
3067
|
-
filters: parseFilterFlags(flags.filter),
|
|
3068
3509
|
audienceId: flagString(flags.audience),
|
|
3069
|
-
logic: flagString(flags.logic),
|
|
3070
3510
|
sort: flagString(flags.sort),
|
|
3071
3511
|
order: flagString(flags.order),
|
|
3072
3512
|
limit: flagInt(flags.limit, "--limit"),
|
|
@@ -3076,7 +3516,7 @@ var contactsSearchCommand = defineCommand({
|
|
|
3076
3516
|
if (flags.all === true) {
|
|
3077
3517
|
const rows = await collectAll(
|
|
3078
3518
|
ctx,
|
|
3079
|
-
(cursor) => contacts.
|
|
3519
|
+
(cursor) => contacts.list(
|
|
3080
3520
|
asSdkInput({
|
|
3081
3521
|
...input,
|
|
3082
3522
|
...cursor === void 0 ? {} : { cursor }
|
|
@@ -3088,13 +3528,13 @@ var contactsSearchCommand = defineCommand({
|
|
|
3088
3528
|
human: renderContacts(rows)
|
|
3089
3529
|
};
|
|
3090
3530
|
}
|
|
3091
|
-
const result = await contacts.
|
|
3531
|
+
const result = await contacts.list(asSdkInput(input));
|
|
3092
3532
|
return { data: result, human: renderContacts(result.data) };
|
|
3093
3533
|
}
|
|
3094
3534
|
});
|
|
3095
3535
|
function renderContacts(rows) {
|
|
3096
3536
|
if (rows.length === 0) {
|
|
3097
|
-
return "No contacts
|
|
3537
|
+
return "No contacts found.";
|
|
3098
3538
|
}
|
|
3099
3539
|
return renderTable(rows, [
|
|
3100
3540
|
{ key: "email", header: "EMAIL" },
|
|
@@ -3104,15 +3544,86 @@ function renderContacts(rows) {
|
|
|
3104
3544
|
]);
|
|
3105
3545
|
}
|
|
3106
3546
|
|
|
3107
|
-
// src/commands/contacts/
|
|
3108
|
-
var
|
|
3109
|
-
path: ["contacts", "
|
|
3110
|
-
summary: "
|
|
3111
|
-
sdkMethod: "contacts.
|
|
3112
|
-
route: { method: "
|
|
3113
|
-
commandClass: "
|
|
3114
|
-
|
|
3115
|
-
{
|
|
3547
|
+
// src/commands/contacts/search.ts
|
|
3548
|
+
var contactsSearchCommand = defineCommand({
|
|
3549
|
+
path: ["contacts", "search"],
|
|
3550
|
+
summary: "Search contacts with structured filters (the contacts read)",
|
|
3551
|
+
sdkMethod: "contacts.search",
|
|
3552
|
+
route: { method: "POST", path: "/v1/contacts/search" },
|
|
3553
|
+
commandClass: "read",
|
|
3554
|
+
flags: [
|
|
3555
|
+
{ flag: "--search <text>", summary: "Free-text search" },
|
|
3556
|
+
{
|
|
3557
|
+
flag: "--filter <filters...>",
|
|
3558
|
+
summary: "Structured filter field:operator[:value], repeatable"
|
|
3559
|
+
},
|
|
3560
|
+
{ flag: "--audience <audienceId>", summary: "Scope to one audience" },
|
|
3561
|
+
{ flag: "--logic <logic>", summary: "Filter combinator: and | or" },
|
|
3562
|
+
{ flag: "--sort <field>", summary: "Sort field" },
|
|
3563
|
+
{ flag: "--order <order>", summary: "Sort order: asc | desc" },
|
|
3564
|
+
LIMIT_FLAG,
|
|
3565
|
+
CURSOR_FLAG,
|
|
3566
|
+
ALL_FLAG,
|
|
3567
|
+
INPUT_FLAG
|
|
3568
|
+
],
|
|
3569
|
+
examples: [
|
|
3570
|
+
"brew-cli contacts search --filter email:equals:jane@example.com",
|
|
3571
|
+
"brew-cli contacts search --search jane --limit 10",
|
|
3572
|
+
"brew-cli contacts search --all --json"
|
|
3573
|
+
],
|
|
3574
|
+
run: async ({ ctx, flags }) => {
|
|
3575
|
+
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
3576
|
+
const input = mergeInput(base, {
|
|
3577
|
+
search: flagString(flags.search),
|
|
3578
|
+
filters: parseFilterFlags(flags.filter),
|
|
3579
|
+
audienceId: flagString(flags.audience),
|
|
3580
|
+
logic: flagString(flags.logic),
|
|
3581
|
+
sort: flagString(flags.sort),
|
|
3582
|
+
order: flagString(flags.order),
|
|
3583
|
+
limit: flagInt(flags.limit, "--limit"),
|
|
3584
|
+
cursor: flagString(flags.cursor)
|
|
3585
|
+
});
|
|
3586
|
+
const contacts = ctx.client().contacts;
|
|
3587
|
+
if (flags.all === true) {
|
|
3588
|
+
const rows = await collectAll(
|
|
3589
|
+
ctx,
|
|
3590
|
+
(cursor) => contacts.search(
|
|
3591
|
+
asSdkInput({
|
|
3592
|
+
...input,
|
|
3593
|
+
...cursor === void 0 ? {} : { cursor }
|
|
3594
|
+
})
|
|
3595
|
+
)
|
|
3596
|
+
);
|
|
3597
|
+
return {
|
|
3598
|
+
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
3599
|
+
human: renderContacts2(rows)
|
|
3600
|
+
};
|
|
3601
|
+
}
|
|
3602
|
+
const result = await contacts.search(asSdkInput(input));
|
|
3603
|
+
return { data: result, human: renderContacts2(result.data) };
|
|
3604
|
+
}
|
|
3605
|
+
});
|
|
3606
|
+
function renderContacts2(rows) {
|
|
3607
|
+
if (rows.length === 0) {
|
|
3608
|
+
return "No contacts matched.";
|
|
3609
|
+
}
|
|
3610
|
+
return renderTable(rows, [
|
|
3611
|
+
{ key: "email", header: "EMAIL" },
|
|
3612
|
+
{ key: "firstName", header: "FIRST" },
|
|
3613
|
+
{ key: "lastName", header: "LAST" },
|
|
3614
|
+
{ key: "subscribed", header: "SUBSCRIBED" }
|
|
3615
|
+
]);
|
|
3616
|
+
}
|
|
3617
|
+
|
|
3618
|
+
// src/commands/contacts/update.ts
|
|
3619
|
+
var contactsUpdateCommand = defineCommand({
|
|
3620
|
+
path: ["contacts", "update"],
|
|
3621
|
+
summary: "Partially update one contact (PATCH; never retried)",
|
|
3622
|
+
sdkMethod: "contacts.patch",
|
|
3623
|
+
route: { method: "PATCH", path: "/v1/contacts/{email}" },
|
|
3624
|
+
commandClass: "write",
|
|
3625
|
+
args: [
|
|
3626
|
+
{
|
|
3116
3627
|
name: "email",
|
|
3117
3628
|
summary: "Email address of the contact",
|
|
3118
3629
|
isRequired: true
|
|
@@ -3641,12 +4152,12 @@ var SDK_SKIP_LIST = [
|
|
|
3641
4152
|
reason: "auto-pager covered by `analytics events --all`"
|
|
3642
4153
|
},
|
|
3643
4154
|
{
|
|
3644
|
-
sdkPath: "
|
|
3645
|
-
reason: "auto-pager covered by `
|
|
4155
|
+
sdkPath: "sends.listAll",
|
|
4156
|
+
reason: "auto-pager covered by `sends list --all`"
|
|
3646
4157
|
},
|
|
3647
4158
|
{
|
|
3648
|
-
sdkPath: "
|
|
3649
|
-
reason: "auto-pager covered by `
|
|
4159
|
+
sdkPath: "automations.triggerInstances.listAll",
|
|
4160
|
+
reason: "auto-pager covered by `automations trigger-instances list --all`"
|
|
3650
4161
|
},
|
|
3651
4162
|
{
|
|
3652
4163
|
sdkPath: "brand.update",
|
|
@@ -3722,7 +4233,7 @@ function buildManifest() {
|
|
|
3722
4233
|
|
|
3723
4234
|
// src/commands/docs.ts
|
|
3724
4235
|
var DOCS_POINTERS = {
|
|
3725
|
-
documentation: "https://docs.
|
|
4236
|
+
documentation: "https://docs.brew.new",
|
|
3726
4237
|
openapiSpec: "https://brew.new/openapi/public-api-v1.yaml",
|
|
3727
4238
|
agentGuide: "https://brew.new/api/v1/llms.txt",
|
|
3728
4239
|
apiCatalog: "https://brew.new/api/v1/help",
|
|
@@ -3913,28 +4424,15 @@ var domainsDeleteCommand = defineCommand({
|
|
|
3913
4424
|
// src/commands/domains/get.ts
|
|
3914
4425
|
var domainsGetCommand = defineCommand({
|
|
3915
4426
|
path: ["domains", "get"],
|
|
3916
|
-
summary: "Fetch one sending domain by id",
|
|
3917
|
-
sdkMethod:
|
|
3918
|
-
|
|
3919
|
-
route: { method: "GET", path: "/v1/domains" },
|
|
4427
|
+
summary: "Fetch one sending domain by id \u2014 the bare row",
|
|
4428
|
+
sdkMethod: "domains.get",
|
|
4429
|
+
route: { method: "GET", path: "/v1/domains/{domainId}" },
|
|
3920
4430
|
commandClass: "read",
|
|
3921
4431
|
args: [{ name: "domainId", summary: "Domain id to fetch", isRequired: true }],
|
|
3922
4432
|
examples: ["brew-cli domains get dom_3k9sQ"],
|
|
3923
|
-
run: async ({ ctx, args }) => {
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
const domain = result.data[0];
|
|
3927
|
-
if (domain === void 0) {
|
|
3928
|
-
throw new CliApiError({
|
|
3929
|
-
status: 404,
|
|
3930
|
-
code: "DOMAIN_NOT_FOUND",
|
|
3931
|
-
type: "not_found",
|
|
3932
|
-
message: `No domain found for ${domainId}`,
|
|
3933
|
-
suggestion: "List domains with `brew-cli domains list`."
|
|
3934
|
-
});
|
|
3935
|
-
}
|
|
3936
|
-
return { data: domain };
|
|
3937
|
-
}
|
|
4433
|
+
run: async ({ ctx, args }) => ({
|
|
4434
|
+
data: await ctx.client().domains.get(args.domainId ?? "")
|
|
4435
|
+
})
|
|
3938
4436
|
});
|
|
3939
4437
|
|
|
3940
4438
|
// src/commands/domains/health.ts
|
|
@@ -4184,7 +4682,7 @@ var emailsCloneCommand = defineCommand({
|
|
|
4184
4682
|
var emailsCreateInboxPlacementTestCommand = defineCommand({
|
|
4185
4683
|
path: ["emails", "create-inbox-placement-test"],
|
|
4186
4684
|
summary: "Seed-test where the design lands (inbox vs spam) via a real small send (10 credits)",
|
|
4187
|
-
sdkMethod: "emails.
|
|
4685
|
+
sdkMethod: "emails.inboxPlacementTests.create",
|
|
4188
4686
|
route: { method: "POST", path: "/v1/emails/{emailId}/inbox-placement-tests" },
|
|
4189
4687
|
commandClass: "write",
|
|
4190
4688
|
isCredited: true,
|
|
@@ -4228,9 +4726,9 @@ var emailsCreateInboxPlacementTestCommand = defineCommand({
|
|
|
4228
4726
|
const emailVersionId = flagString(flags.emailVersionId);
|
|
4229
4727
|
const providers = toStringArray(flags.providers);
|
|
4230
4728
|
return {
|
|
4231
|
-
// The API answers 202 with a pending test (status: "
|
|
4232
|
-
//
|
|
4233
|
-
data: await ctx.client().emails.
|
|
4729
|
+
// The API answers 202 with a pending test (status: "queued"); poll
|
|
4730
|
+
// `emails get-inbox-placement-results --test-id` for the outcome.
|
|
4731
|
+
data: await ctx.client().emails.inboxPlacementTests.create(
|
|
4234
4732
|
asSdkInput({
|
|
4235
4733
|
emailId: args.emailId ?? "",
|
|
4236
4734
|
domainId,
|
|
@@ -4261,9 +4759,13 @@ var emailsDeleteCommand = defineCommand({
|
|
|
4261
4759
|
});
|
|
4262
4760
|
|
|
4263
4761
|
// src/commands/emails/edit.ts
|
|
4762
|
+
var ENVELOPE_FIELDS = ["title", "subjectLine", "groupId"];
|
|
4763
|
+
function isText(value) {
|
|
4764
|
+
return typeof value === "string" && value !== "";
|
|
4765
|
+
}
|
|
4264
4766
|
var emailsEditCommand = defineCommand({
|
|
4265
4767
|
path: ["emails", "edit"],
|
|
4266
|
-
summary: "AI-edit an email design, and/or set its subject line (
|
|
4768
|
+
summary: "AI-edit an email design, and/or set its subject line, title or group (free without a prompt)",
|
|
4267
4769
|
sdkMethod: "emails.edit",
|
|
4268
4770
|
route: { method: "PATCH", path: "/v1/emails/{emailId}" },
|
|
4269
4771
|
commandClass: "write",
|
|
@@ -4283,30 +4785,54 @@ var emailsEditCommand = defineCommand({
|
|
|
4283
4785
|
flag: "--subject-line <text>",
|
|
4284
4786
|
summary: "The design's default inbox subject line; alone it skips the AI run"
|
|
4285
4787
|
},
|
|
4788
|
+
{
|
|
4789
|
+
flag: "--title <text>",
|
|
4790
|
+
summary: "Rename the design (its canvas name); alone it skips the AI run"
|
|
4791
|
+
},
|
|
4792
|
+
{
|
|
4793
|
+
flag: "--group-id <groupId>",
|
|
4794
|
+
summary: "Move the design into this existing group; alone it skips the AI run"
|
|
4795
|
+
},
|
|
4796
|
+
{
|
|
4797
|
+
flag: "--ungroup",
|
|
4798
|
+
summary: "Move the design to Ungrouped (groupId: null)"
|
|
4799
|
+
},
|
|
4286
4800
|
INPUT_FLAG
|
|
4287
4801
|
],
|
|
4288
4802
|
examples: [
|
|
4289
4803
|
'brew-cli emails edit eml_2SmZOWV3ZQ7W5x6g3m4p --prompt "Tighten the hero copy"',
|
|
4290
|
-
'brew-cli emails edit eml_2SmZOWV3ZQ7W5x6g3m4p --subject-line "Your September roundup"'
|
|
4804
|
+
'brew-cli emails edit eml_2SmZOWV3ZQ7W5x6g3m4p --subject-line "Your September roundup"',
|
|
4805
|
+
'brew-cli emails edit eml_2SmZOWV3ZQ7W5x6g3m4p --title "Fall sale v2" --group-id grp_7Hq2',
|
|
4806
|
+
"brew-cli emails edit eml_2SmZOWV3ZQ7W5x6g3m4p --ungroup"
|
|
4291
4807
|
],
|
|
4292
4808
|
run: async ({ ctx, args, flags }) => {
|
|
4809
|
+
const groupId = flagString(flags.groupId);
|
|
4810
|
+
if (groupId !== void 0 && flags.ungroup === true) {
|
|
4811
|
+
throw new CliUsageError(
|
|
4812
|
+
"--group-id and --ungroup conflict: pick one group move."
|
|
4813
|
+
);
|
|
4814
|
+
}
|
|
4293
4815
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
4294
4816
|
const input = mergeInput(base, {
|
|
4295
4817
|
prompt: flagString(flags.prompt),
|
|
4296
4818
|
emailVersionId: flagString(flags.emailVersionId),
|
|
4297
4819
|
contentUrls: toStringArray(flags.contentUrls),
|
|
4298
|
-
subjectLine: flagString(flags.subjectLine)
|
|
4820
|
+
subjectLine: flagString(flags.subjectLine),
|
|
4821
|
+
title: flagString(flags.title),
|
|
4822
|
+
groupId: flags.ungroup === true ? null : groupId
|
|
4299
4823
|
});
|
|
4300
|
-
const isPromptEdit =
|
|
4301
|
-
const
|
|
4302
|
-
|
|
4824
|
+
const isPromptEdit = isText(input.prompt);
|
|
4825
|
+
const envelope = ENVELOPE_FIELDS.filter(
|
|
4826
|
+
(field) => isText(input[field]) || field === "groupId" && input[field] === null
|
|
4827
|
+
);
|
|
4828
|
+
if (!isPromptEdit && envelope.length === 0) {
|
|
4303
4829
|
throw new CliUsageError(
|
|
4304
|
-
"--prompt or --subject-line
|
|
4830
|
+
"Pass --prompt, or at least one of --subject-line, --title, --group-id or --ungroup (or those fields via --input)."
|
|
4305
4831
|
);
|
|
4306
4832
|
}
|
|
4307
4833
|
progress(
|
|
4308
4834
|
ctx,
|
|
4309
|
-
isPromptEdit ? "Editing email\u2026 (typically 30-90s)" : "Setting the subject line\u2026"
|
|
4835
|
+
isPromptEdit ? "Editing email\u2026 (typically 30-90s)" : envelope.length === 1 && envelope[0] === "subjectLine" ? "Setting the subject line\u2026" : "Updating the design (no AI run)\u2026"
|
|
4310
4836
|
);
|
|
4311
4837
|
const result = await ctx.client().emails.edit(
|
|
4312
4838
|
asSdkInput({ ...input, emailId: args.emailId ?? "" }),
|
|
@@ -4358,7 +4884,7 @@ var emailsExportCommand = defineCommand({
|
|
|
4358
4884
|
provider,
|
|
4359
4885
|
...templateName === void 0 ? {} : { templateName },
|
|
4360
4886
|
// The spec field is snake_case, unlike the rest of the API surface.
|
|
4361
|
-
...flags.dryRun === true ? {
|
|
4887
|
+
...flags.dryRun === true ? { dryRun: true } : {}
|
|
4362
4888
|
}),
|
|
4363
4889
|
requestOptions(flags)
|
|
4364
4890
|
)
|
|
@@ -4427,10 +4953,9 @@ var emailsGenerateCommand = defineCommand({
|
|
|
4427
4953
|
// src/commands/emails/get.ts
|
|
4428
4954
|
var emailsGetCommand = defineCommand({
|
|
4429
4955
|
path: ["emails", "get"],
|
|
4430
|
-
summary: "Fetch one email design by id",
|
|
4431
|
-
sdkMethod:
|
|
4432
|
-
|
|
4433
|
-
route: { method: "GET", path: "/v1/emails" },
|
|
4956
|
+
summary: "Fetch one email design by id \u2014 the bare row",
|
|
4957
|
+
sdkMethod: "emails.get",
|
|
4958
|
+
route: { method: "GET", path: "/v1/emails/{emailId}" },
|
|
4434
4959
|
commandClass: "read",
|
|
4435
4960
|
args: [
|
|
4436
4961
|
{
|
|
@@ -4442,7 +4967,7 @@ var emailsGetCommand = defineCommand({
|
|
|
4442
4967
|
flags: [
|
|
4443
4968
|
{
|
|
4444
4969
|
flag: "--include <tokens>",
|
|
4445
|
-
summary: "Comma-separated expansions: html,versions"
|
|
4970
|
+
summary: "Comma-separated expansions: html, versions"
|
|
4446
4971
|
}
|
|
4447
4972
|
],
|
|
4448
4973
|
examples: [
|
|
@@ -4450,31 +4975,89 @@ var emailsGetCommand = defineCommand({
|
|
|
4450
4975
|
"brew-cli emails get eml_2SmZOWV3ZQ7W5x6g3m4p --include html,versions"
|
|
4451
4976
|
],
|
|
4452
4977
|
run: async ({ ctx, args, flags }) => {
|
|
4453
|
-
const emailId = args.emailId ?? "";
|
|
4454
4978
|
const include = flagString(flags.include);
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4979
|
+
return {
|
|
4980
|
+
data: await ctx.client().emails.get(
|
|
4981
|
+
args.emailId ?? "",
|
|
4982
|
+
include === void 0 ? void 0 : { include }
|
|
4983
|
+
)
|
|
4984
|
+
};
|
|
4985
|
+
}
|
|
4986
|
+
});
|
|
4987
|
+
|
|
4988
|
+
// src/commands/emails/get-audit.ts
|
|
4989
|
+
var emailsGetAuditCommand = defineCommand({
|
|
4990
|
+
path: ["emails", "get-audit"],
|
|
4991
|
+
summary: "Read a saved email audit: one page of its findings (free; never reruns the audit)",
|
|
4992
|
+
sdkMethod: null,
|
|
4993
|
+
isRawTransport: true,
|
|
4994
|
+
route: { method: "GET", path: "/v1/emails/audits/{auditId}" },
|
|
4995
|
+
commandClass: "read",
|
|
4996
|
+
args: [
|
|
4997
|
+
{
|
|
4998
|
+
name: "auditId",
|
|
4999
|
+
summary: "The auditId `emails audit` returned (reports are kept 7 days)",
|
|
5000
|
+
isRequired: true
|
|
5001
|
+
}
|
|
5002
|
+
],
|
|
5003
|
+
flags: [LIMIT_FLAG, CURSOR_FLAG],
|
|
5004
|
+
examples: [
|
|
5005
|
+
"brew-cli emails get-audit 6f1e2d3c-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
|
|
5006
|
+
"brew-cli emails get-audit 6f1e2d3c-4b5a-4c7d-8e9f-0a1b2c3d4e5f --limit 20"
|
|
5007
|
+
],
|
|
5008
|
+
// The next page is `--cursor <pagination.cursor>`; `pagination.hasMore`
|
|
5009
|
+
// says whether one exists.
|
|
5010
|
+
run: async ({ ctx, args, flags }) => {
|
|
5011
|
+
const limit = flagInt(flags.limit, "--limit");
|
|
5012
|
+
const body = await rawRequest(ctx, {
|
|
5013
|
+
method: "GET",
|
|
5014
|
+
path: `/v1/emails/audits/${encodeURIComponent(args.auditId ?? "")}`,
|
|
5015
|
+
query: {
|
|
5016
|
+
cursor: flagString(flags.cursor),
|
|
5017
|
+
limit: limit === void 0 ? void 0 : String(limit)
|
|
5018
|
+
}
|
|
4458
5019
|
});
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
5020
|
+
return { data: body };
|
|
5021
|
+
}
|
|
5022
|
+
});
|
|
5023
|
+
|
|
5024
|
+
// src/commands/emails/get-client-preview.ts
|
|
5025
|
+
var emailsGetClientPreviewCommand = defineCommand({
|
|
5026
|
+
path: ["emails", "get-client-preview"],
|
|
5027
|
+
summary: "Poll a client-preview rendering job: per-client screenshot links once it settles (free; never re-renders)",
|
|
5028
|
+
sdkMethod: null,
|
|
5029
|
+
isRawTransport: true,
|
|
5030
|
+
route: { method: "GET", path: "/v1/emails/client-previews/{previewId}" },
|
|
5031
|
+
commandClass: "read",
|
|
5032
|
+
args: [
|
|
5033
|
+
{
|
|
5034
|
+
name: "previewId",
|
|
5035
|
+
summary: "The previewId `emails preview-clients` returned",
|
|
5036
|
+
isRequired: true
|
|
4468
5037
|
}
|
|
4469
|
-
|
|
5038
|
+
],
|
|
5039
|
+
examples: [
|
|
5040
|
+
"brew-cli emails get-client-preview prv_0b7f3c1e-9a2d-4e8b-b6c5-3d1f2a9e8c47",
|
|
5041
|
+
"brew-cli emails get-client-preview prv_0b7f3c1e-9a2d-4e8b-b6c5-3d1f2a9e8c47 --json | jq '.previews[] | {label, status, imageUrl}'"
|
|
5042
|
+
],
|
|
5043
|
+
// While `status` is `queued` or `running`, poll again after
|
|
5044
|
+
// `nextPollAfterMs`. It settles as `completed`, `partially_completed` or
|
|
5045
|
+
// `failed`; each client then carries its `imageUrl`, or a `reason` and
|
|
5046
|
+
// whether it is `retryable`.
|
|
5047
|
+
run: async ({ ctx, args }) => {
|
|
5048
|
+
const body = await rawRequest(ctx, {
|
|
5049
|
+
method: "GET",
|
|
5050
|
+
path: `/v1/emails/client-previews/${encodeURIComponent(args.previewId ?? "")}`
|
|
5051
|
+
});
|
|
5052
|
+
return { data: body };
|
|
4470
5053
|
}
|
|
4471
5054
|
});
|
|
4472
5055
|
|
|
4473
5056
|
// src/commands/emails/get-inbox-placement-results.ts
|
|
4474
5057
|
var emailsGetInboxPlacementResultsCommand = defineCommand({
|
|
4475
5058
|
path: ["emails", "get-inbox-placement-results"],
|
|
4476
|
-
summary: "Inbox placement results: one test with --test-id
|
|
4477
|
-
sdkMethod: "emails.
|
|
5059
|
+
summary: "Inbox placement results: the recent tests, or one test with --test-id",
|
|
5060
|
+
sdkMethod: "emails.inboxPlacementTests.list",
|
|
4478
5061
|
route: { method: "GET", path: "/v1/emails/{emailId}/inbox-placement-tests" },
|
|
4479
5062
|
commandClass: "read",
|
|
4480
5063
|
args: [
|
|
@@ -4486,22 +5069,38 @@ var emailsGetInboxPlacementResultsCommand = defineCommand({
|
|
|
4486
5069
|
],
|
|
4487
5070
|
flags: [
|
|
4488
5071
|
{
|
|
5072
|
+
// The list no longer filters by test id: --test-id reads the real
|
|
5073
|
+
// detail route, the same one `emails inbox-placement-tests get` binds.
|
|
4489
5074
|
flag: "--test-id <id>",
|
|
4490
5075
|
summary: "One test: live status + per-provider placement (re-poll ~30s until completed)"
|
|
4491
|
-
}
|
|
5076
|
+
},
|
|
5077
|
+
LIMIT_FLAG,
|
|
5078
|
+
CURSOR_FLAG,
|
|
5079
|
+
INPUT_FLAG
|
|
4492
5080
|
],
|
|
4493
5081
|
examples: [
|
|
4494
5082
|
"brew-cli emails get-inbox-placement-results eml_2SmZOWV3ZQ7W5x6g3m4p",
|
|
4495
5083
|
"brew-cli emails get-inbox-placement-results eml_2SmZOWV3ZQ7W5x6g3m4p --test-id ibp_2f1c9d8a"
|
|
4496
5084
|
],
|
|
4497
|
-
run: async ({ ctx, args, flags }) =>
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
}
|
|
4503
|
-
|
|
4504
|
-
|
|
5085
|
+
run: async ({ ctx, args, flags }) => {
|
|
5086
|
+
const emailId = args.emailId ?? "";
|
|
5087
|
+
const testId = flagString(flags.testId);
|
|
5088
|
+
const inboxPlacementTests = ctx.client().emails.inboxPlacementTests;
|
|
5089
|
+
if (testId !== void 0) {
|
|
5090
|
+
return { data: await inboxPlacementTests.get(emailId, testId) };
|
|
5091
|
+
}
|
|
5092
|
+
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
5093
|
+
const input = mergeInput(base, {
|
|
5094
|
+
emailId,
|
|
5095
|
+
limit: flagInt(flags.limit, "--limit"),
|
|
5096
|
+
cursor: flagString(flags.cursor)
|
|
5097
|
+
});
|
|
5098
|
+
return {
|
|
5099
|
+
data: await inboxPlacementTests.list(
|
|
5100
|
+
asSdkInput(input)
|
|
5101
|
+
)
|
|
5102
|
+
};
|
|
5103
|
+
}
|
|
4505
5104
|
});
|
|
4506
5105
|
|
|
4507
5106
|
// src/commands/emails/groups/create.ts
|
|
@@ -4558,6 +5157,29 @@ var emailsGroupsDeleteCommand = defineCommand({
|
|
|
4558
5157
|
})
|
|
4559
5158
|
});
|
|
4560
5159
|
|
|
5160
|
+
// src/commands/emails/groups/get.ts
|
|
5161
|
+
var emailsGroupsGetCommand = defineCommand({
|
|
5162
|
+
path: ["emails", "groups", "get"],
|
|
5163
|
+
summary: "Fetch one email group by id \u2014 the bare row",
|
|
5164
|
+
sdkMethod: "emailGroups.get",
|
|
5165
|
+
route: { method: "GET", path: "/v1/email-groups/{groupId}" },
|
|
5166
|
+
commandClass: "read",
|
|
5167
|
+
args: [
|
|
5168
|
+
{
|
|
5169
|
+
name: "groupId",
|
|
5170
|
+
summary: "Group id (`grp_\u2026`, or the literal `ungrouped`)",
|
|
5171
|
+
isRequired: true
|
|
5172
|
+
}
|
|
5173
|
+
],
|
|
5174
|
+
examples: [
|
|
5175
|
+
"brew-cli emails groups get grp_2f1c9d8a",
|
|
5176
|
+
"brew-cli emails groups get ungrouped"
|
|
5177
|
+
],
|
|
5178
|
+
run: async ({ ctx, args }) => ({
|
|
5179
|
+
data: await ctx.client().emailGroups.get(args.groupId ?? "")
|
|
5180
|
+
})
|
|
5181
|
+
});
|
|
5182
|
+
|
|
4561
5183
|
// src/commands/emails/groups/list.ts
|
|
4562
5184
|
var emailsGroupsListCommand = defineCommand({
|
|
4563
5185
|
path: ["emails", "groups", "list"],
|
|
@@ -4748,53 +5370,108 @@ var emailsImportFigmaCommand = defineCommand({
|
|
|
4748
5370
|
}
|
|
4749
5371
|
});
|
|
4750
5372
|
|
|
5373
|
+
// src/commands/emails/inbox-placement-tests/get.ts
|
|
5374
|
+
var emailsInboxPlacementTestsGetCommand = defineCommand({
|
|
5375
|
+
path: ["emails", "inbox-placement-tests", "get"],
|
|
5376
|
+
summary: "Fetch one inbox-placement (seed) test \u2014 the bare row, re-poll ~30s until completed",
|
|
5377
|
+
sdkMethod: "emails.inboxPlacementTests.get",
|
|
5378
|
+
route: {
|
|
5379
|
+
method: "GET",
|
|
5380
|
+
path: "/v1/emails/{emailId}/inbox-placement-tests/{testId}"
|
|
5381
|
+
},
|
|
5382
|
+
commandClass: "read",
|
|
5383
|
+
args: [
|
|
5384
|
+
{
|
|
5385
|
+
name: "emailId",
|
|
5386
|
+
summary: "Design id the test ran on",
|
|
5387
|
+
isRequired: true
|
|
5388
|
+
},
|
|
5389
|
+
{
|
|
5390
|
+
name: "testId",
|
|
5391
|
+
summary: "Test id returned by `emails create-inbox-placement-test`",
|
|
5392
|
+
isRequired: true
|
|
5393
|
+
}
|
|
5394
|
+
],
|
|
5395
|
+
examples: [
|
|
5396
|
+
"brew-cli emails inbox-placement-tests get eml_2SmZOWV3ZQ7W5x6g3m4p ibp_2f1c9d8a"
|
|
5397
|
+
],
|
|
5398
|
+
run: async ({ ctx, args }) => ({
|
|
5399
|
+
data: await ctx.client().emails.inboxPlacementTests.get(args.emailId ?? "", args.testId ?? "")
|
|
5400
|
+
})
|
|
5401
|
+
});
|
|
5402
|
+
|
|
4751
5403
|
// src/commands/emails/list.ts
|
|
4752
5404
|
var emailsListCommand = defineCommand({
|
|
4753
5405
|
path: ["emails", "list"],
|
|
4754
|
-
summary: "List email designs
|
|
5406
|
+
summary: "List email designs; one design is `emails get`",
|
|
4755
5407
|
sdkMethod: "emails.list",
|
|
4756
5408
|
route: { method: "GET", path: "/v1/emails" },
|
|
4757
5409
|
commandClass: "read",
|
|
4758
5410
|
flags: [
|
|
4759
5411
|
{
|
|
4760
5412
|
flag: "--status <status>",
|
|
4761
|
-
summary: "Filter by status:
|
|
5413
|
+
summary: "Filter by status: generating | ready | failed"
|
|
4762
5414
|
},
|
|
4763
5415
|
{
|
|
4764
5416
|
flag: "--group-id <groupId>",
|
|
4765
5417
|
summary: "Filter by one group id; use ungrouped for no saved group"
|
|
4766
5418
|
},
|
|
4767
5419
|
{
|
|
4768
|
-
flag: "--sort <field>",
|
|
4769
|
-
summary: "
|
|
5420
|
+
flag: "--sort-by <field>",
|
|
5421
|
+
summary: "Timestamp the page is ordered by and that --since/--until bound: updatedAt (default) | createdAt"
|
|
5422
|
+
},
|
|
5423
|
+
{
|
|
5424
|
+
flag: "--since <iso>",
|
|
5425
|
+
summary: "Inclusive lower bound on the --sort-by timestamp (ISO-8601)"
|
|
5426
|
+
},
|
|
5427
|
+
{
|
|
5428
|
+
flag: "--until <iso>",
|
|
5429
|
+
summary: "Inclusive upper bound on the --sort-by timestamp (ISO-8601)"
|
|
5430
|
+
},
|
|
5431
|
+
{ flag: "--sort <field>", summary: "0.6 alias of --sort-by" },
|
|
5432
|
+
{
|
|
5433
|
+
flag: "--order <order>",
|
|
5434
|
+
summary: "0.6 flag: pages are newest first; only desc is accepted"
|
|
5435
|
+
},
|
|
5436
|
+
{
|
|
5437
|
+
flag: "--created-at-from <iso>",
|
|
5438
|
+
summary: "0.6 alias of --sort-by createdAt --since <iso>"
|
|
5439
|
+
},
|
|
5440
|
+
{
|
|
5441
|
+
flag: "--created-at-to <iso>",
|
|
5442
|
+
summary: "0.6 alias of --sort-by createdAt --until <iso>"
|
|
5443
|
+
},
|
|
5444
|
+
{
|
|
5445
|
+
flag: "--updated-at-from <iso>",
|
|
5446
|
+
summary: "0.6 alias of --sort-by updatedAt --since <iso>"
|
|
5447
|
+
},
|
|
5448
|
+
{
|
|
5449
|
+
flag: "--updated-at-to <iso>",
|
|
5450
|
+
summary: "0.6 alias of --sort-by updatedAt --until <iso>"
|
|
4770
5451
|
},
|
|
4771
|
-
{ flag: "--order <order>", summary: "Sort order: asc | desc" },
|
|
4772
|
-
{ flag: "--created-at-from <iso>", summary: "Created at or after (ISO)" },
|
|
4773
|
-
{ flag: "--created-at-to <iso>", summary: "Created at or before (ISO)" },
|
|
4774
|
-
{ flag: "--updated-at-from <iso>", summary: "Updated at or after (ISO)" },
|
|
4775
|
-
{ flag: "--updated-at-to <iso>", summary: "Updated at or before (ISO)" },
|
|
4776
5452
|
LIMIT_FLAG,
|
|
4777
5453
|
CURSOR_FLAG,
|
|
4778
5454
|
ALL_FLAG,
|
|
4779
5455
|
INPUT_FLAG
|
|
4780
5456
|
],
|
|
4781
5457
|
examples: [
|
|
4782
|
-
"brew-cli emails list --status
|
|
4783
|
-
"brew-cli emails list --group-id ungrouped
|
|
4784
|
-
"brew-cli emails list --
|
|
5458
|
+
"brew-cli emails list --status ready --limit 10",
|
|
5459
|
+
"brew-cli emails list --group-id ungrouped",
|
|
5460
|
+
"brew-cli emails list --sort-by createdAt --since 2026-08-01T00:00:00Z",
|
|
4785
5461
|
"brew-cli emails list --all --json"
|
|
4786
5462
|
],
|
|
4787
5463
|
run: async ({ ctx, flags }) => {
|
|
5464
|
+
const legacy = legacyWindow(
|
|
5465
|
+
flags,
|
|
5466
|
+
flagString(flags.sortBy) ?? flagString(flags.sort)
|
|
5467
|
+
);
|
|
4788
5468
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
4789
5469
|
const input = mergeInput(base, {
|
|
4790
5470
|
status: flagString(flags.status),
|
|
4791
5471
|
groupId: flagString(flags.groupId),
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
createdAtTo: flagString(flags.createdAtTo),
|
|
4796
|
-
updatedAtFrom: flagString(flags.updatedAtFrom),
|
|
4797
|
-
updatedAtTo: flagString(flags.updatedAtTo),
|
|
5472
|
+
sortBy: flagString(flags.sortBy) ?? flagString(flags.sort) ?? legacy.sortBy,
|
|
5473
|
+
from: flagString(flags.since) ?? legacy.from,
|
|
5474
|
+
to: flagString(flags.until) ?? legacy.to,
|
|
4798
5475
|
limit: flagInt(flags.limit, "--limit"),
|
|
4799
5476
|
cursor: flagString(flags.cursor)
|
|
4800
5477
|
});
|
|
@@ -4818,6 +5495,40 @@ var emailsListCommand = defineCommand({
|
|
|
4818
5495
|
return { data: result, human: renderEmails(result.data) };
|
|
4819
5496
|
}
|
|
4820
5497
|
});
|
|
5498
|
+
function legacyWindow(flags, explicitSortBy) {
|
|
5499
|
+
const order = flagString(flags.order);
|
|
5500
|
+
if (order !== void 0 && order !== "desc") {
|
|
5501
|
+
throw new CliUsageError(
|
|
5502
|
+
"GET /v1/emails pages newest first only; --order asc has no equivalent."
|
|
5503
|
+
);
|
|
5504
|
+
}
|
|
5505
|
+
const created = {
|
|
5506
|
+
from: flagString(flags.createdAtFrom),
|
|
5507
|
+
to: flagString(flags.createdAtTo)
|
|
5508
|
+
};
|
|
5509
|
+
const updated = {
|
|
5510
|
+
from: flagString(flags.updatedAtFrom),
|
|
5511
|
+
to: flagString(flags.updatedAtTo)
|
|
5512
|
+
};
|
|
5513
|
+
const hasCreated = created.from !== void 0 || created.to !== void 0;
|
|
5514
|
+
const hasUpdated = updated.from !== void 0 || updated.to !== void 0;
|
|
5515
|
+
if (hasCreated && hasUpdated) {
|
|
5516
|
+
throw new CliUsageError(
|
|
5517
|
+
"The API bounds one timestamp per page: pass --created-at-* or --updated-at-*, not both (or --sort-by with --since/--until)."
|
|
5518
|
+
);
|
|
5519
|
+
}
|
|
5520
|
+
if (!(hasCreated || hasUpdated)) {
|
|
5521
|
+
return { sortBy: void 0, from: void 0, to: void 0 };
|
|
5522
|
+
}
|
|
5523
|
+
const column = hasCreated ? "createdAt" : "updatedAt";
|
|
5524
|
+
if (explicitSortBy !== void 0 && explicitSortBy !== column) {
|
|
5525
|
+
const prefix = hasCreated ? "--created-at-*" : "--updated-at-*";
|
|
5526
|
+
throw new CliUsageError(
|
|
5527
|
+
`${prefix} bounds ${column}, but the page is ordered by ${explicitSortBy}; the API bounds the --sort-by timestamp only.`
|
|
5528
|
+
);
|
|
5529
|
+
}
|
|
5530
|
+
return { sortBy: column, ...hasCreated ? created : updated };
|
|
5531
|
+
}
|
|
4821
5532
|
function renderEmails(rows) {
|
|
4822
5533
|
if (rows.length === 0) {
|
|
4823
5534
|
return "No email designs found.";
|
|
@@ -4834,7 +5545,7 @@ function renderEmails(rows) {
|
|
|
4834
5545
|
// src/commands/emails/preview-clients.ts
|
|
4835
5546
|
var emailsPreviewClientsCommand = defineCommand({
|
|
4836
5547
|
path: ["emails", "preview-clients"],
|
|
4837
|
-
summary: "
|
|
5548
|
+
summary: "Start a rendering job across real email clients (10 credits); poll it with `emails get-client-preview`",
|
|
4838
5549
|
sdkMethod: "emails.previewClients",
|
|
4839
5550
|
route: { method: "POST", path: "/v1/emails/{emailId}/client-previews" },
|
|
4840
5551
|
commandClass: "write",
|
|
@@ -4847,25 +5558,49 @@ var emailsPreviewClientsCommand = defineCommand({
|
|
|
4847
5558
|
flag: "--clients <ids...>",
|
|
4848
5559
|
summary: "Client id(s) to render, repeatable (e.g. applemail16 iphone16_18); default: a popular spread"
|
|
4849
5560
|
},
|
|
5561
|
+
{
|
|
5562
|
+
flag: "--email-version-id <id>",
|
|
5563
|
+
summary: "Render this saved version (default: the latest)"
|
|
5564
|
+
},
|
|
4850
5565
|
IDEMPOTENCY_FLAG
|
|
4851
5566
|
],
|
|
4852
5567
|
examples: [
|
|
4853
5568
|
"brew-cli emails preview-clients eml_2SmZOWV3ZQ7W5x6g3m4p",
|
|
4854
|
-
"brew-cli emails preview-clients eml_2SmZOWV3ZQ7W5x6g3m4p --clients applemail16 outlook2021_win11_lm_dt"
|
|
5569
|
+
"brew-cli emails preview-clients eml_2SmZOWV3ZQ7W5x6g3m4p --clients applemail16 outlook2021_win11_lm_dt",
|
|
5570
|
+
'PREVIEW_ID=$(brew-cli emails preview-clients eml_2SmZOWV3ZQ7W5x6g3m4p --json | jq -r .previewId) && brew-cli emails get-client-preview "$PREVIEW_ID"'
|
|
4855
5571
|
],
|
|
5572
|
+
// The API answers 202 with the admitted job (or 200 with the existing job
|
|
5573
|
+
// for the same version and clients): `previewId`, its `status` and
|
|
5574
|
+
// per-client progress. Screenshots arrive on the job once it settles, so
|
|
5575
|
+
// `emails get-client-preview <previewId>` is how they are read.
|
|
4856
5576
|
run: async ({ ctx, args, flags }) => {
|
|
4857
5577
|
const clients = toStringArray(flags.clients);
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
}
|
|
4864
|
-
|
|
4865
|
-
)
|
|
4866
|
-
|
|
5578
|
+
const emailVersionId = flagString(flags.emailVersionId);
|
|
5579
|
+
const job = await ctx.client().emails.previewClients(
|
|
5580
|
+
asSdkInput({
|
|
5581
|
+
emailId: args.emailId ?? "",
|
|
5582
|
+
...clients === void 0 ? {} : { clients },
|
|
5583
|
+
...emailVersionId === void 0 ? {} : { emailVersionId }
|
|
5584
|
+
}),
|
|
5585
|
+
requestOptions(flags)
|
|
5586
|
+
);
|
|
5587
|
+
const hint = pollHint(job);
|
|
5588
|
+
if (hint !== void 0) {
|
|
5589
|
+
progress(ctx, hint);
|
|
5590
|
+
}
|
|
5591
|
+
return { data: job };
|
|
4867
5592
|
}
|
|
4868
5593
|
});
|
|
5594
|
+
function pollHint(job) {
|
|
5595
|
+
if (typeof job !== "object" || job === null || !("previewId" in job) || !("status" in job)) {
|
|
5596
|
+
return;
|
|
5597
|
+
}
|
|
5598
|
+
const { previewId, status } = job;
|
|
5599
|
+
if (typeof previewId !== "string" || status !== "queued" && status !== "running") {
|
|
5600
|
+
return;
|
|
5601
|
+
}
|
|
5602
|
+
return `Rendering job ${previewId} is ${status}. Poll it with: brew-cli emails get-client-preview ${previewId}`;
|
|
5603
|
+
}
|
|
4869
5604
|
|
|
4870
5605
|
// src/commands/emails/restore.ts
|
|
4871
5606
|
var emailsRestoreCommand = defineCommand({
|
|
@@ -4879,19 +5614,24 @@ var emailsRestoreCommand = defineCommand({
|
|
|
4879
5614
|
],
|
|
4880
5615
|
// --version is taken by the CLI itself, hence --to-version.
|
|
4881
5616
|
flags: [
|
|
4882
|
-
{
|
|
5617
|
+
{
|
|
5618
|
+
flag: "--to-version <emailVersionId>",
|
|
5619
|
+
summary: "Version id to restore (from `emails get <emailId> --include versions`)"
|
|
5620
|
+
},
|
|
4883
5621
|
IDEMPOTENCY_FLAG
|
|
4884
5622
|
],
|
|
4885
|
-
examples: [
|
|
5623
|
+
examples: [
|
|
5624
|
+
"brew-cli emails restore eml_2SmZOWV3ZQ7W5x6g3m4p --to-version emv_7Hq2"
|
|
5625
|
+
],
|
|
4886
5626
|
run: async ({ ctx, args, flags }) => {
|
|
4887
|
-
const
|
|
4888
|
-
if (
|
|
5627
|
+
const emailVersionId = flagString(flags.toVersion);
|
|
5628
|
+
if (emailVersionId === void 0) {
|
|
4889
5629
|
throw new CliUsageError(
|
|
4890
|
-
"--to-version is required (see `brew-cli emails get <emailId> --include versions`)."
|
|
5630
|
+
"--to-version is required (a version id; see `brew-cli emails get <emailId> --include versions`)."
|
|
4891
5631
|
);
|
|
4892
5632
|
}
|
|
4893
5633
|
const result = await ctx.client().emails.restore(
|
|
4894
|
-
{ emailId: args.emailId ?? "",
|
|
5634
|
+
{ emailId: args.emailId ?? "", emailVersionId },
|
|
4895
5635
|
requestOptions(flags)
|
|
4896
5636
|
);
|
|
4897
5637
|
return { data: result };
|
|
@@ -5061,6 +5801,26 @@ var fieldsDeleteCommand = defineCommand({
|
|
|
5061
5801
|
})
|
|
5062
5802
|
});
|
|
5063
5803
|
|
|
5804
|
+
// src/commands/fields/get.ts
|
|
5805
|
+
var fieldsGetCommand = defineCommand({
|
|
5806
|
+
path: ["fields", "get"],
|
|
5807
|
+
summary: "Fetch one contact field definition by name \u2014 the bare row",
|
|
5808
|
+
sdkMethod: "fields.get",
|
|
5809
|
+
route: { method: "GET", path: "/v1/fields/{fieldName}" },
|
|
5810
|
+
commandClass: "read",
|
|
5811
|
+
args: [
|
|
5812
|
+
{
|
|
5813
|
+
name: "fieldName",
|
|
5814
|
+
summary: "Field name (a core column or a custom field)",
|
|
5815
|
+
isRequired: true
|
|
5816
|
+
}
|
|
5817
|
+
],
|
|
5818
|
+
examples: ["brew-cli fields get loyalty_tier"],
|
|
5819
|
+
run: async ({ ctx, args }) => ({
|
|
5820
|
+
data: await ctx.client().fields.get(args.fieldName ?? "")
|
|
5821
|
+
})
|
|
5822
|
+
});
|
|
5823
|
+
|
|
5064
5824
|
// src/commands/fields/list.ts
|
|
5065
5825
|
var fieldsListCommand = defineCommand({
|
|
5066
5826
|
path: ["fields", "list"],
|
|
@@ -5072,6 +5832,178 @@ var fieldsListCommand = defineCommand({
|
|
|
5072
5832
|
run: async ({ ctx }) => ({ data: await ctx.client().fields.list() })
|
|
5073
5833
|
});
|
|
5074
5834
|
|
|
5835
|
+
// src/commands/flows/get.ts
|
|
5836
|
+
var flowsGetCommand = defineCommand({
|
|
5837
|
+
path: ["flows", "get"],
|
|
5838
|
+
summary: "Fetch one public email flow by brand domain, with every step (day offset, wait, subject, template id)",
|
|
5839
|
+
sdkMethod: "flows.get",
|
|
5840
|
+
route: { method: "GET", path: "/v1/flows/{slug}" },
|
|
5841
|
+
commandClass: "read",
|
|
5842
|
+
args: [
|
|
5843
|
+
{
|
|
5844
|
+
name: "slug",
|
|
5845
|
+
summary: "The brand domain a `flows list` card carries (e.g. brew.new)",
|
|
5846
|
+
isRequired: true
|
|
5847
|
+
}
|
|
5848
|
+
],
|
|
5849
|
+
flags: [
|
|
5850
|
+
{
|
|
5851
|
+
flag: "--include <keys>",
|
|
5852
|
+
summary: "Comma-separated expansions: html (each step\u2019s rendered HTML, best-effort per step)"
|
|
5853
|
+
}
|
|
5854
|
+
],
|
|
5855
|
+
examples: [
|
|
5856
|
+
"brew-cli flows get brew.new",
|
|
5857
|
+
"brew-cli flows get brew.new --include html --json"
|
|
5858
|
+
],
|
|
5859
|
+
run: async ({ ctx, args, flags }) => {
|
|
5860
|
+
const include = flagString(flags.include);
|
|
5861
|
+
const flow = await ctx.client().flows.get(
|
|
5862
|
+
args.slug ?? "",
|
|
5863
|
+
include === void 0 ? void 0 : { include }
|
|
5864
|
+
);
|
|
5865
|
+
return { data: flow, human: renderSteps(flow) };
|
|
5866
|
+
}
|
|
5867
|
+
});
|
|
5868
|
+
function renderSteps(flow) {
|
|
5869
|
+
const header = `${flow.title} \u2014 ${flow.brand.name} (${flow.slug}), ${flow.emailCount} emails over ${flow.spanDays} days${flow.anchor === void 0 ? "" : `, day 0 = ${flow.anchor}`}`;
|
|
5870
|
+
const table = renderTable(
|
|
5871
|
+
(flow.steps ?? []).map((step) => ({
|
|
5872
|
+
order: step.order,
|
|
5873
|
+
day: step.dayOffset,
|
|
5874
|
+
wait: step.delayDays,
|
|
5875
|
+
subject: step.subject,
|
|
5876
|
+
category: step.category,
|
|
5877
|
+
emailId: step.emailId
|
|
5878
|
+
})),
|
|
5879
|
+
[
|
|
5880
|
+
{ key: "order", header: "#" },
|
|
5881
|
+
{ key: "day", header: "DAY" },
|
|
5882
|
+
{ key: "wait", header: "WAIT" },
|
|
5883
|
+
{ key: "subject", header: "SUBJECT" },
|
|
5884
|
+
{ key: "category", header: "CATEGORY" },
|
|
5885
|
+
{ key: "emailId", header: "TEMPLATE" }
|
|
5886
|
+
]
|
|
5887
|
+
);
|
|
5888
|
+
return `${header}
|
|
5889
|
+
|
|
5890
|
+
${table}`;
|
|
5891
|
+
}
|
|
5892
|
+
|
|
5893
|
+
// src/commands/flows/list.ts
|
|
5894
|
+
var flowsListCommand = defineCommand({
|
|
5895
|
+
path: ["flows", "list"],
|
|
5896
|
+
summary: "List public email flows (real multi-step sequences by brand) as cards; `flows get <slug>` reads one",
|
|
5897
|
+
sdkMethod: "flows.list",
|
|
5898
|
+
route: { method: "GET", path: "/v1/flows" },
|
|
5899
|
+
commandClass: "read",
|
|
5900
|
+
flags: [
|
|
5901
|
+
{
|
|
5902
|
+
// --brand is taken by the global brand-selection flag.
|
|
5903
|
+
flag: "--brand-domain <domain>",
|
|
5904
|
+
summary: "Filter the list by brand domain"
|
|
5905
|
+
},
|
|
5906
|
+
{
|
|
5907
|
+
flag: "--category <category>",
|
|
5908
|
+
summary: "Filter by dominant step category (welcome, newsletter, \u2026)"
|
|
5909
|
+
},
|
|
5910
|
+
{
|
|
5911
|
+
flag: "--type <type>",
|
|
5912
|
+
summary: "Filter by how the sequence starts: signup | newsletter"
|
|
5913
|
+
},
|
|
5914
|
+
{
|
|
5915
|
+
flag: "--semantic <text>",
|
|
5916
|
+
summary: "Semantic search over the sequences (relevance order)"
|
|
5917
|
+
},
|
|
5918
|
+
{
|
|
5919
|
+
flag: "--sort <order>",
|
|
5920
|
+
summary: "List order: newest (default) | emails | span | remixes"
|
|
5921
|
+
},
|
|
5922
|
+
{
|
|
5923
|
+
flag: "--slug <domain>",
|
|
5924
|
+
summary: "0.6 shim: read ONE flow with its steps as a single-row page (`flows get <slug>` is the real read)"
|
|
5925
|
+
},
|
|
5926
|
+
{
|
|
5927
|
+
flag: "--include <keys>",
|
|
5928
|
+
summary: "With --slug only: `html` adds each step's rendered HTML"
|
|
5929
|
+
},
|
|
5930
|
+
LIMIT_FLAG,
|
|
5931
|
+
CURSOR_FLAG,
|
|
5932
|
+
ALL_FLAG,
|
|
5933
|
+
INPUT_FLAG
|
|
5934
|
+
],
|
|
5935
|
+
examples: [
|
|
5936
|
+
"brew-cli flows list --type signup --sort emails",
|
|
5937
|
+
"brew-cli flows list --brand-domain brew.new --json",
|
|
5938
|
+
'brew-cli flows list --semantic "developer onboarding drip"'
|
|
5939
|
+
],
|
|
5940
|
+
run: async ({ ctx, flags }) => {
|
|
5941
|
+
const flows = ctx.client().flows;
|
|
5942
|
+
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
5943
|
+
const slug = flagString(flags.slug) ?? inputField(base, "slug");
|
|
5944
|
+
const include = flagString(flags.include) ?? inputField(base, "include");
|
|
5945
|
+
if (slug !== void 0) {
|
|
5946
|
+
const flow = await flows.get(
|
|
5947
|
+
slug,
|
|
5948
|
+
include === void 0 ? void 0 : { include }
|
|
5949
|
+
);
|
|
5950
|
+
return { data: singleRowPage(flow), human: renderFlows([flow]) };
|
|
5951
|
+
}
|
|
5952
|
+
if (include !== void 0) {
|
|
5953
|
+
throw includeRidesDetailRead("flows get", "--slug");
|
|
5954
|
+
}
|
|
5955
|
+
const input = mergeInput(base, {
|
|
5956
|
+
brand: flagString(flags.brandDomain),
|
|
5957
|
+
category: flagString(flags.category),
|
|
5958
|
+
type: flagString(flags.type),
|
|
5959
|
+
semantic: flagString(flags.semantic),
|
|
5960
|
+
sort: flagString(flags.sort),
|
|
5961
|
+
limit: flagInt(flags.limit, "--limit"),
|
|
5962
|
+
cursor: flagString(flags.cursor)
|
|
5963
|
+
});
|
|
5964
|
+
if (flags.all === true) {
|
|
5965
|
+
const rows = await collectAll(
|
|
5966
|
+
ctx,
|
|
5967
|
+
(cursor) => flows.list(
|
|
5968
|
+
asSdkInput({
|
|
5969
|
+
...input,
|
|
5970
|
+
...cursor === void 0 ? {} : { cursor }
|
|
5971
|
+
})
|
|
5972
|
+
)
|
|
5973
|
+
);
|
|
5974
|
+
return {
|
|
5975
|
+
data: { data: rows, pagination: { cursor: null, hasMore: false } },
|
|
5976
|
+
human: renderFlows(rows)
|
|
5977
|
+
};
|
|
5978
|
+
}
|
|
5979
|
+
const result = await flows.list(asSdkInput(input));
|
|
5980
|
+
return { data: result, human: renderFlows(result.data) };
|
|
5981
|
+
}
|
|
5982
|
+
});
|
|
5983
|
+
function renderFlows(rows) {
|
|
5984
|
+
if (rows.length === 0) {
|
|
5985
|
+
return "No flows found.";
|
|
5986
|
+
}
|
|
5987
|
+
return renderTable(
|
|
5988
|
+
rows.map((row) => ({
|
|
5989
|
+
slug: row.slug,
|
|
5990
|
+
brand: row.brand.name,
|
|
5991
|
+
type: row.type,
|
|
5992
|
+
category: row.category,
|
|
5993
|
+
emails: row.emailCount,
|
|
5994
|
+
spanDays: row.spanDays
|
|
5995
|
+
})),
|
|
5996
|
+
[
|
|
5997
|
+
{ key: "slug", header: "SLUG" },
|
|
5998
|
+
{ key: "brand", header: "BRAND" },
|
|
5999
|
+
{ key: "type", header: "TYPE" },
|
|
6000
|
+
{ key: "category", header: "CATEGORY" },
|
|
6001
|
+
{ key: "emails", header: "EMAILS" },
|
|
6002
|
+
{ key: "spanDays", header: "SPAN (DAYS)" }
|
|
6003
|
+
]
|
|
6004
|
+
);
|
|
6005
|
+
}
|
|
6006
|
+
|
|
5075
6007
|
// src/commands/health.ts
|
|
5076
6008
|
var healthCommand = defineCommand({
|
|
5077
6009
|
path: ["health"],
|
|
@@ -5198,6 +6130,35 @@ var sendsCancelCommand = defineCommand({
|
|
|
5198
6130
|
})
|
|
5199
6131
|
});
|
|
5200
6132
|
|
|
6133
|
+
// src/commands/sends/get.ts
|
|
6134
|
+
var sendsGetCommand = defineCommand({
|
|
6135
|
+
path: ["sends", "get"],
|
|
6136
|
+
summary: "Fetch one send by id \u2014 the bare row with its lifetime stats",
|
|
6137
|
+
sdkMethod: "sends.get",
|
|
6138
|
+
route: { method: "GET", path: "/v1/sends/{sendId}" },
|
|
6139
|
+
commandClass: "read",
|
|
6140
|
+
args: [{ name: "sendId", summary: "Send id to fetch", isRequired: true }],
|
|
6141
|
+
flags: [
|
|
6142
|
+
{
|
|
6143
|
+
flag: "--include <tokens>",
|
|
6144
|
+
summary: "Comma-separated expansions: events"
|
|
6145
|
+
}
|
|
6146
|
+
],
|
|
6147
|
+
examples: [
|
|
6148
|
+
"brew-cli sends get snd_9f2kX",
|
|
6149
|
+
"brew-cli sends get snd_9f2kX --include events"
|
|
6150
|
+
],
|
|
6151
|
+
run: async ({ ctx, args, flags }) => {
|
|
6152
|
+
const include = flagString(flags.include);
|
|
6153
|
+
return {
|
|
6154
|
+
data: await ctx.client().sends.get(
|
|
6155
|
+
args.sendId ?? "",
|
|
6156
|
+
include === void 0 ? void 0 : { include }
|
|
6157
|
+
)
|
|
6158
|
+
};
|
|
6159
|
+
}
|
|
6160
|
+
});
|
|
6161
|
+
|
|
5201
6162
|
// src/commands/sends/pause.ts
|
|
5202
6163
|
var sendsPauseCommand = defineCommand({
|
|
5203
6164
|
path: ["sends", "pause"],
|
|
@@ -5216,7 +6177,7 @@ var sendsPauseCommand = defineCommand({
|
|
|
5216
6177
|
// src/commands/sends/resume.ts
|
|
5217
6178
|
var sendsResumeCommand = defineCommand({
|
|
5218
6179
|
path: ["sends", "resume"],
|
|
5219
|
-
summary: "Resume a paused gradual send (the unsent tail is re-spread)",
|
|
6180
|
+
summary: "Resume a paused gradual send (the unsent tail is re-spread); the send reports `running` again",
|
|
5220
6181
|
sdkMethod: "sends.resume",
|
|
5221
6182
|
route: { method: "POST", path: "/v1/sends/{sendId}/resume" },
|
|
5222
6183
|
commandClass: "write",
|
|
@@ -5228,6 +6189,41 @@ var sendsResumeCommand = defineCommand({
|
|
|
5228
6189
|
})
|
|
5229
6190
|
});
|
|
5230
6191
|
|
|
6192
|
+
// src/commands/templates/get.ts
|
|
6193
|
+
var templatesGetCommand = defineCommand({
|
|
6194
|
+
path: ["templates", "get"],
|
|
6195
|
+
summary: "Fetch one public template: its links and the referenceEmailId to remix; --include html adds its HTML",
|
|
6196
|
+
sdkMethod: null,
|
|
6197
|
+
isRawTransport: true,
|
|
6198
|
+
route: { method: "GET", path: "/v1/templates/{templateId}" },
|
|
6199
|
+
commandClass: "read",
|
|
6200
|
+
args: [
|
|
6201
|
+
{
|
|
6202
|
+
name: "templateId",
|
|
6203
|
+
summary: "Template id: the TEMPLATE column (emailId) of `templates list`",
|
|
6204
|
+
isRequired: true
|
|
6205
|
+
}
|
|
6206
|
+
],
|
|
6207
|
+
flags: [
|
|
6208
|
+
{
|
|
6209
|
+
flag: "--include <tokens>",
|
|
6210
|
+
summary: "Expansions: html (the rendered HTML; a large page arrives as a content.url download link instead)"
|
|
6211
|
+
}
|
|
6212
|
+
],
|
|
6213
|
+
examples: [
|
|
6214
|
+
"brew-cli templates get seed-vercel-newsletter",
|
|
6215
|
+
"brew-cli templates get seed-vercel-newsletter --include html --json"
|
|
6216
|
+
],
|
|
6217
|
+
run: async ({ ctx, args, flags }) => {
|
|
6218
|
+
const body = await rawRequest(ctx, {
|
|
6219
|
+
method: "GET",
|
|
6220
|
+
path: `/v1/templates/${encodeURIComponent(args.templateId ?? "")}`,
|
|
6221
|
+
query: { include: flagString(flags.include) }
|
|
6222
|
+
});
|
|
6223
|
+
return { data: body };
|
|
6224
|
+
}
|
|
6225
|
+
});
|
|
6226
|
+
|
|
5231
6227
|
// src/commands/templates/list.ts
|
|
5232
6228
|
var templatesListCommand = defineCommand({
|
|
5233
6229
|
path: ["templates", "list"],
|
|
@@ -5535,6 +6531,7 @@ var ALL_COMMANDS = [
|
|
|
5535
6531
|
configGetCommand,
|
|
5536
6532
|
configSetCommand,
|
|
5537
6533
|
configUnsetCommand,
|
|
6534
|
+
contactsListCommand,
|
|
5538
6535
|
contactsSearchCommand,
|
|
5539
6536
|
contactsGetCommand,
|
|
5540
6537
|
contactsCountCommand,
|
|
@@ -5546,10 +6543,12 @@ var ALL_COMMANDS = [
|
|
|
5546
6543
|
contactsValidateCommand,
|
|
5547
6544
|
contactsImportCsvCommand,
|
|
5548
6545
|
fieldsListCommand,
|
|
6546
|
+
fieldsGetCommand,
|
|
5549
6547
|
fieldsCreateCommand,
|
|
5550
6548
|
fieldsDeleteCommand,
|
|
5551
6549
|
emailsListCommand,
|
|
5552
6550
|
emailsGroupsListCommand,
|
|
6551
|
+
emailsGroupsGetCommand,
|
|
5553
6552
|
emailsGroupsCreateCommand,
|
|
5554
6553
|
emailsGroupsUpdateCommand,
|
|
5555
6554
|
emailsGroupsDeleteCommand,
|
|
@@ -5563,10 +6562,15 @@ var ALL_COMMANDS = [
|
|
|
5563
6562
|
emailsDeleteCommand,
|
|
5564
6563
|
emailsExportCommand,
|
|
5565
6564
|
emailsAuditCommand,
|
|
6565
|
+
emailsGetAuditCommand,
|
|
5566
6566
|
emailsPreviewClientsCommand,
|
|
6567
|
+
emailsGetClientPreviewCommand,
|
|
5567
6568
|
emailsCreateInboxPlacementTestCommand,
|
|
5568
6569
|
emailsGetInboxPlacementResultsCommand,
|
|
6570
|
+
emailsInboxPlacementTestsGetCommand,
|
|
5569
6571
|
emailsSendCommand,
|
|
6572
|
+
sendsListCommand,
|
|
6573
|
+
sendsGetCommand,
|
|
5570
6574
|
sendsCancelCommand,
|
|
5571
6575
|
sendsPauseCommand,
|
|
5572
6576
|
sendsResumeCommand,
|
|
@@ -5588,6 +6592,7 @@ var ALL_COMMANDS = [
|
|
|
5588
6592
|
automationsTestCommand,
|
|
5589
6593
|
automationsRunCommand,
|
|
5590
6594
|
automationsTriggersListCommand,
|
|
6595
|
+
automationsTriggersGetCommand,
|
|
5591
6596
|
automationsTriggersReadyCommand,
|
|
5592
6597
|
automationsTriggersContractGetCommand,
|
|
5593
6598
|
automationsTriggersContractPutCommand,
|
|
@@ -5599,8 +6604,16 @@ var ALL_COMMANDS = [
|
|
|
5599
6604
|
automationsTriggersDeleteCommand,
|
|
5600
6605
|
automationsTriggersFireCommand,
|
|
5601
6606
|
automationsRunsListCommand,
|
|
6607
|
+
automationsRunsGetCommand,
|
|
6608
|
+
automationsRunsCancelCommand,
|
|
5602
6609
|
automationsAudienceRunsListCommand,
|
|
6610
|
+
automationsAudienceRunsGetCommand,
|
|
6611
|
+
automationsAudienceRunsPauseCommand,
|
|
6612
|
+
automationsAudienceRunsResumeCommand,
|
|
6613
|
+
automationsAudienceRunsCancelCommand,
|
|
5603
6614
|
automationsAudienceRunsControlCommand,
|
|
6615
|
+
automationsTriggerInstancesListCommand,
|
|
6616
|
+
automationsTriggerInstancesGetCommand,
|
|
5604
6617
|
analyticsOverviewCommand,
|
|
5605
6618
|
analyticsCampaignsCommand,
|
|
5606
6619
|
analyticsAutomationsCommand,
|
|
@@ -5630,6 +6643,9 @@ var ALL_COMMANDS = [
|
|
|
5630
6643
|
contentHtmlToPngCommand,
|
|
5631
6644
|
contentAddImageCommand,
|
|
5632
6645
|
templatesListCommand,
|
|
6646
|
+
templatesGetCommand,
|
|
6647
|
+
flowsListCommand,
|
|
6648
|
+
flowsGetCommand,
|
|
5633
6649
|
integrationsListCommand,
|
|
5634
6650
|
chatsGetCommand,
|
|
5635
6651
|
healthCommand,
|
|
@@ -5642,7 +6658,8 @@ var ALL_COMMANDS = [
|
|
|
5642
6658
|
|
|
5643
6659
|
// src/cli.ts
|
|
5644
6660
|
var GROUP_SUMMARIES = {
|
|
5645
|
-
analytics: "
|
|
6661
|
+
analytics: "Reports: overview, events, and automation analytics",
|
|
6662
|
+
"audience-runs": "Manual-audience launches: read, pause, resume, cancel",
|
|
5646
6663
|
"api-keys": "Manage organization API keys",
|
|
5647
6664
|
audiences: "Manage audience segments",
|
|
5648
6665
|
automations: "Manage automation graphs, triggers, and runs",
|
|
@@ -5656,15 +6673,17 @@ var GROUP_SUMMARIES = {
|
|
|
5656
6673
|
domains: "Manage sending domains",
|
|
5657
6674
|
emails: "Manage email designs and send campaigns",
|
|
5658
6675
|
fields: "Manage custom contact fields",
|
|
6676
|
+
flows: "Browse public email flows (real multi-step sequences by brand)",
|
|
5659
6677
|
groups: "Manage email folders (groups)",
|
|
5660
6678
|
integrations: "Read the connected-integration catalog",
|
|
5661
|
-
|
|
6679
|
+
"inbox-placement-tests": "Inbox placement (seed) test results",
|
|
6680
|
+
sends: "Read sends, and control one in flight or scheduled",
|
|
5662
6681
|
templates: "Browse the template gallery",
|
|
5663
6682
|
contract: "Stored payload contracts (get, put, validate)",
|
|
5664
6683
|
contracts: "Payload-contract helpers",
|
|
5665
6684
|
triggers: "Manage trigger events",
|
|
5666
|
-
runs: "Automation run history",
|
|
5667
|
-
"trigger-instances": "Fired trigger instances"
|
|
6685
|
+
runs: "Automation run history, and cancel one in-flight run",
|
|
6686
|
+
"trigger-instances": "Fired trigger instances (the inbound-fire audit log)"
|
|
5668
6687
|
};
|
|
5669
6688
|
var AGENT_HELP_FOOTER = `
|
|
5670
6689
|
Environment:
|