@brew.new/cli 0.5.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 +1483 -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
|
|
@@ -3582,8 +4093,56 @@ var contractsInferCommand = defineCommand({
|
|
|
3582
4093
|
}
|
|
3583
4094
|
});
|
|
3584
4095
|
|
|
4096
|
+
// src/commands/data/run.ts
|
|
4097
|
+
var dataRunCommand = defineCommand({
|
|
4098
|
+
path: ["data", "run"],
|
|
4099
|
+
summary: "Run a `db \u2026` command over the brand's data",
|
|
4100
|
+
sdkMethod: "data.run",
|
|
4101
|
+
route: { method: "POST", path: "/v1/data" },
|
|
4102
|
+
commandClass: "read",
|
|
4103
|
+
args: [
|
|
4104
|
+
{
|
|
4105
|
+
name: "command",
|
|
4106
|
+
summary: "The db command line, e.g. 'db find audiences --fields name'",
|
|
4107
|
+
isRequired: true
|
|
4108
|
+
}
|
|
4109
|
+
],
|
|
4110
|
+
flags: [],
|
|
4111
|
+
examples: [
|
|
4112
|
+
"brew-cli data run 'db ls'",
|
|
4113
|
+
"brew-cli data run 'db find contacts --since 30d --fields email --limit 20'",
|
|
4114
|
+
"brew-cli data run 'db agg analyticsEvents --since 7d --group-by eventType --bucket day'"
|
|
4115
|
+
],
|
|
4116
|
+
run: async ({ ctx, args }) => {
|
|
4117
|
+
const result = await ctx.client().data.run({
|
|
4118
|
+
command: args.command ?? ""
|
|
4119
|
+
});
|
|
4120
|
+
return {
|
|
4121
|
+
data: result,
|
|
4122
|
+
human: result.output,
|
|
4123
|
+
exitCode: result.exitCode === 0 ? 0 : 1
|
|
4124
|
+
};
|
|
4125
|
+
}
|
|
4126
|
+
});
|
|
4127
|
+
|
|
3585
4128
|
// src/skip-list.ts
|
|
3586
4129
|
var SDK_SKIP_LIST = [
|
|
4130
|
+
{
|
|
4131
|
+
sdkPath: "automations.triggers.getContract",
|
|
4132
|
+
reason: "covered by `automations triggers contract get` (raw route, bound pre-SDK-v9; SDK-method migration tracked separately)"
|
|
4133
|
+
},
|
|
4134
|
+
{
|
|
4135
|
+
sdkPath: "automations.triggers.putContract",
|
|
4136
|
+
reason: "covered by `automations triggers contract put` (raw route, bound pre-SDK-v9)"
|
|
4137
|
+
},
|
|
4138
|
+
{
|
|
4139
|
+
sdkPath: "automations.triggers.validatePayload",
|
|
4140
|
+
reason: "covered by `automations triggers contract validate` (raw route, bound pre-SDK-v9)"
|
|
4141
|
+
},
|
|
4142
|
+
{
|
|
4143
|
+
sdkPath: "payloadContracts.infer",
|
|
4144
|
+
reason: "covered by `contracts infer` (raw route, bound pre-SDK-v9)"
|
|
4145
|
+
},
|
|
3587
4146
|
{
|
|
3588
4147
|
sdkPath: "contacts.searchAll",
|
|
3589
4148
|
reason: "auto-pager covered by `contacts search --all`"
|
|
@@ -3593,12 +4152,12 @@ var SDK_SKIP_LIST = [
|
|
|
3593
4152
|
reason: "auto-pager covered by `analytics events --all`"
|
|
3594
4153
|
},
|
|
3595
4154
|
{
|
|
3596
|
-
sdkPath: "
|
|
3597
|
-
reason: "auto-pager covered by `
|
|
4155
|
+
sdkPath: "sends.listAll",
|
|
4156
|
+
reason: "auto-pager covered by `sends list --all`"
|
|
3598
4157
|
},
|
|
3599
4158
|
{
|
|
3600
|
-
sdkPath: "
|
|
3601
|
-
reason: "auto-pager covered by `
|
|
4159
|
+
sdkPath: "automations.triggerInstances.listAll",
|
|
4160
|
+
reason: "auto-pager covered by `automations trigger-instances list --all`"
|
|
3602
4161
|
},
|
|
3603
4162
|
{
|
|
3604
4163
|
sdkPath: "brand.update",
|
|
@@ -3674,7 +4233,7 @@ function buildManifest() {
|
|
|
3674
4233
|
|
|
3675
4234
|
// src/commands/docs.ts
|
|
3676
4235
|
var DOCS_POINTERS = {
|
|
3677
|
-
documentation: "https://docs.
|
|
4236
|
+
documentation: "https://docs.brew.new",
|
|
3678
4237
|
openapiSpec: "https://brew.new/openapi/public-api-v1.yaml",
|
|
3679
4238
|
agentGuide: "https://brew.new/api/v1/llms.txt",
|
|
3680
4239
|
apiCatalog: "https://brew.new/api/v1/help",
|
|
@@ -3865,28 +4424,15 @@ var domainsDeleteCommand = defineCommand({
|
|
|
3865
4424
|
// src/commands/domains/get.ts
|
|
3866
4425
|
var domainsGetCommand = defineCommand({
|
|
3867
4426
|
path: ["domains", "get"],
|
|
3868
|
-
summary: "Fetch one sending domain by id",
|
|
3869
|
-
sdkMethod:
|
|
3870
|
-
|
|
3871
|
-
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}" },
|
|
3872
4430
|
commandClass: "read",
|
|
3873
4431
|
args: [{ name: "domainId", summary: "Domain id to fetch", isRequired: true }],
|
|
3874
4432
|
examples: ["brew-cli domains get dom_3k9sQ"],
|
|
3875
|
-
run: async ({ ctx, args }) => {
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
const domain = result.data[0];
|
|
3879
|
-
if (domain === void 0) {
|
|
3880
|
-
throw new CliApiError({
|
|
3881
|
-
status: 404,
|
|
3882
|
-
code: "DOMAIN_NOT_FOUND",
|
|
3883
|
-
type: "not_found",
|
|
3884
|
-
message: `No domain found for ${domainId}`,
|
|
3885
|
-
suggestion: "List domains with `brew-cli domains list`."
|
|
3886
|
-
});
|
|
3887
|
-
}
|
|
3888
|
-
return { data: domain };
|
|
3889
|
-
}
|
|
4433
|
+
run: async ({ ctx, args }) => ({
|
|
4434
|
+
data: await ctx.client().domains.get(args.domainId ?? "")
|
|
4435
|
+
})
|
|
3890
4436
|
});
|
|
3891
4437
|
|
|
3892
4438
|
// src/commands/domains/health.ts
|
|
@@ -4136,7 +4682,7 @@ var emailsCloneCommand = defineCommand({
|
|
|
4136
4682
|
var emailsCreateInboxPlacementTestCommand = defineCommand({
|
|
4137
4683
|
path: ["emails", "create-inbox-placement-test"],
|
|
4138
4684
|
summary: "Seed-test where the design lands (inbox vs spam) via a real small send (10 credits)",
|
|
4139
|
-
sdkMethod: "emails.
|
|
4685
|
+
sdkMethod: "emails.inboxPlacementTests.create",
|
|
4140
4686
|
route: { method: "POST", path: "/v1/emails/{emailId}/inbox-placement-tests" },
|
|
4141
4687
|
commandClass: "write",
|
|
4142
4688
|
isCredited: true,
|
|
@@ -4180,9 +4726,9 @@ var emailsCreateInboxPlacementTestCommand = defineCommand({
|
|
|
4180
4726
|
const emailVersionId = flagString(flags.emailVersionId);
|
|
4181
4727
|
const providers = toStringArray(flags.providers);
|
|
4182
4728
|
return {
|
|
4183
|
-
// The API answers 202 with a pending test (status: "
|
|
4184
|
-
//
|
|
4185
|
-
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(
|
|
4186
4732
|
asSdkInput({
|
|
4187
4733
|
emailId: args.emailId ?? "",
|
|
4188
4734
|
domainId,
|
|
@@ -4213,9 +4759,13 @@ var emailsDeleteCommand = defineCommand({
|
|
|
4213
4759
|
});
|
|
4214
4760
|
|
|
4215
4761
|
// src/commands/emails/edit.ts
|
|
4762
|
+
var ENVELOPE_FIELDS = ["title", "subjectLine", "groupId"];
|
|
4763
|
+
function isText(value) {
|
|
4764
|
+
return typeof value === "string" && value !== "";
|
|
4765
|
+
}
|
|
4216
4766
|
var emailsEditCommand = defineCommand({
|
|
4217
4767
|
path: ["emails", "edit"],
|
|
4218
|
-
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)",
|
|
4219
4769
|
sdkMethod: "emails.edit",
|
|
4220
4770
|
route: { method: "PATCH", path: "/v1/emails/{emailId}" },
|
|
4221
4771
|
commandClass: "write",
|
|
@@ -4235,30 +4785,54 @@ var emailsEditCommand = defineCommand({
|
|
|
4235
4785
|
flag: "--subject-line <text>",
|
|
4236
4786
|
summary: "The design's default inbox subject line; alone it skips the AI run"
|
|
4237
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
|
+
},
|
|
4238
4800
|
INPUT_FLAG
|
|
4239
4801
|
],
|
|
4240
4802
|
examples: [
|
|
4241
4803
|
'brew-cli emails edit eml_2SmZOWV3ZQ7W5x6g3m4p --prompt "Tighten the hero copy"',
|
|
4242
|
-
'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"
|
|
4243
4807
|
],
|
|
4244
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
|
+
}
|
|
4245
4815
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
4246
4816
|
const input = mergeInput(base, {
|
|
4247
4817
|
prompt: flagString(flags.prompt),
|
|
4248
4818
|
emailVersionId: flagString(flags.emailVersionId),
|
|
4249
4819
|
contentUrls: toStringArray(flags.contentUrls),
|
|
4250
|
-
subjectLine: flagString(flags.subjectLine)
|
|
4820
|
+
subjectLine: flagString(flags.subjectLine),
|
|
4821
|
+
title: flagString(flags.title),
|
|
4822
|
+
groupId: flags.ungroup === true ? null : groupId
|
|
4251
4823
|
});
|
|
4252
|
-
const isPromptEdit =
|
|
4253
|
-
const
|
|
4254
|
-
|
|
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) {
|
|
4255
4829
|
throw new CliUsageError(
|
|
4256
|
-
"--prompt or --subject-line
|
|
4830
|
+
"Pass --prompt, or at least one of --subject-line, --title, --group-id or --ungroup (or those fields via --input)."
|
|
4257
4831
|
);
|
|
4258
4832
|
}
|
|
4259
4833
|
progress(
|
|
4260
4834
|
ctx,
|
|
4261
|
-
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"
|
|
4262
4836
|
);
|
|
4263
4837
|
const result = await ctx.client().emails.edit(
|
|
4264
4838
|
asSdkInput({ ...input, emailId: args.emailId ?? "" }),
|
|
@@ -4310,7 +4884,7 @@ var emailsExportCommand = defineCommand({
|
|
|
4310
4884
|
provider,
|
|
4311
4885
|
...templateName === void 0 ? {} : { templateName },
|
|
4312
4886
|
// The spec field is snake_case, unlike the rest of the API surface.
|
|
4313
|
-
...flags.dryRun === true ? {
|
|
4887
|
+
...flags.dryRun === true ? { dryRun: true } : {}
|
|
4314
4888
|
}),
|
|
4315
4889
|
requestOptions(flags)
|
|
4316
4890
|
)
|
|
@@ -4379,10 +4953,9 @@ var emailsGenerateCommand = defineCommand({
|
|
|
4379
4953
|
// src/commands/emails/get.ts
|
|
4380
4954
|
var emailsGetCommand = defineCommand({
|
|
4381
4955
|
path: ["emails", "get"],
|
|
4382
|
-
summary: "Fetch one email design by id",
|
|
4383
|
-
sdkMethod:
|
|
4384
|
-
|
|
4385
|
-
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}" },
|
|
4386
4959
|
commandClass: "read",
|
|
4387
4960
|
args: [
|
|
4388
4961
|
{
|
|
@@ -4394,7 +4967,7 @@ var emailsGetCommand = defineCommand({
|
|
|
4394
4967
|
flags: [
|
|
4395
4968
|
{
|
|
4396
4969
|
flag: "--include <tokens>",
|
|
4397
|
-
summary: "Comma-separated expansions: html,versions"
|
|
4970
|
+
summary: "Comma-separated expansions: html, versions"
|
|
4398
4971
|
}
|
|
4399
4972
|
],
|
|
4400
4973
|
examples: [
|
|
@@ -4402,31 +4975,89 @@ var emailsGetCommand = defineCommand({
|
|
|
4402
4975
|
"brew-cli emails get eml_2SmZOWV3ZQ7W5x6g3m4p --include html,versions"
|
|
4403
4976
|
],
|
|
4404
4977
|
run: async ({ ctx, args, flags }) => {
|
|
4405
|
-
const emailId = args.emailId ?? "";
|
|
4406
4978
|
const include = flagString(flags.include);
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
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
|
+
}
|
|
4410
5019
|
});
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
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
|
|
4420
5037
|
}
|
|
4421
|
-
|
|
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 };
|
|
4422
5053
|
}
|
|
4423
5054
|
});
|
|
4424
5055
|
|
|
4425
5056
|
// src/commands/emails/get-inbox-placement-results.ts
|
|
4426
5057
|
var emailsGetInboxPlacementResultsCommand = defineCommand({
|
|
4427
5058
|
path: ["emails", "get-inbox-placement-results"],
|
|
4428
|
-
summary: "Inbox placement results: one test with --test-id
|
|
4429
|
-
sdkMethod: "emails.
|
|
5059
|
+
summary: "Inbox placement results: the recent tests, or one test with --test-id",
|
|
5060
|
+
sdkMethod: "emails.inboxPlacementTests.list",
|
|
4430
5061
|
route: { method: "GET", path: "/v1/emails/{emailId}/inbox-placement-tests" },
|
|
4431
5062
|
commandClass: "read",
|
|
4432
5063
|
args: [
|
|
@@ -4438,22 +5069,38 @@ var emailsGetInboxPlacementResultsCommand = defineCommand({
|
|
|
4438
5069
|
],
|
|
4439
5070
|
flags: [
|
|
4440
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.
|
|
4441
5074
|
flag: "--test-id <id>",
|
|
4442
5075
|
summary: "One test: live status + per-provider placement (re-poll ~30s until completed)"
|
|
4443
|
-
}
|
|
5076
|
+
},
|
|
5077
|
+
LIMIT_FLAG,
|
|
5078
|
+
CURSOR_FLAG,
|
|
5079
|
+
INPUT_FLAG
|
|
4444
5080
|
],
|
|
4445
5081
|
examples: [
|
|
4446
5082
|
"brew-cli emails get-inbox-placement-results eml_2SmZOWV3ZQ7W5x6g3m4p",
|
|
4447
5083
|
"brew-cli emails get-inbox-placement-results eml_2SmZOWV3ZQ7W5x6g3m4p --test-id ibp_2f1c9d8a"
|
|
4448
5084
|
],
|
|
4449
|
-
run: async ({ ctx, args, flags }) =>
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
}
|
|
4455
|
-
|
|
4456
|
-
|
|
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
|
+
}
|
|
4457
5104
|
});
|
|
4458
5105
|
|
|
4459
5106
|
// src/commands/emails/groups/create.ts
|
|
@@ -4510,6 +5157,29 @@ var emailsGroupsDeleteCommand = defineCommand({
|
|
|
4510
5157
|
})
|
|
4511
5158
|
});
|
|
4512
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
|
+
|
|
4513
5183
|
// src/commands/emails/groups/list.ts
|
|
4514
5184
|
var emailsGroupsListCommand = defineCommand({
|
|
4515
5185
|
path: ["emails", "groups", "list"],
|
|
@@ -4700,53 +5370,108 @@ var emailsImportFigmaCommand = defineCommand({
|
|
|
4700
5370
|
}
|
|
4701
5371
|
});
|
|
4702
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
|
+
|
|
4703
5403
|
// src/commands/emails/list.ts
|
|
4704
5404
|
var emailsListCommand = defineCommand({
|
|
4705
5405
|
path: ["emails", "list"],
|
|
4706
|
-
summary: "List email designs
|
|
5406
|
+
summary: "List email designs; one design is `emails get`",
|
|
4707
5407
|
sdkMethod: "emails.list",
|
|
4708
5408
|
route: { method: "GET", path: "/v1/emails" },
|
|
4709
5409
|
commandClass: "read",
|
|
4710
5410
|
flags: [
|
|
4711
5411
|
{
|
|
4712
5412
|
flag: "--status <status>",
|
|
4713
|
-
summary: "Filter by status:
|
|
5413
|
+
summary: "Filter by status: generating | ready | failed"
|
|
4714
5414
|
},
|
|
4715
5415
|
{
|
|
4716
5416
|
flag: "--group-id <groupId>",
|
|
4717
5417
|
summary: "Filter by one group id; use ungrouped for no saved group"
|
|
4718
5418
|
},
|
|
4719
5419
|
{
|
|
4720
|
-
flag: "--sort <field>",
|
|
4721
|
-
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>"
|
|
4722
5451
|
},
|
|
4723
|
-
{ flag: "--order <order>", summary: "Sort order: asc | desc" },
|
|
4724
|
-
{ flag: "--created-at-from <iso>", summary: "Created at or after (ISO)" },
|
|
4725
|
-
{ flag: "--created-at-to <iso>", summary: "Created at or before (ISO)" },
|
|
4726
|
-
{ flag: "--updated-at-from <iso>", summary: "Updated at or after (ISO)" },
|
|
4727
|
-
{ flag: "--updated-at-to <iso>", summary: "Updated at or before (ISO)" },
|
|
4728
5452
|
LIMIT_FLAG,
|
|
4729
5453
|
CURSOR_FLAG,
|
|
4730
5454
|
ALL_FLAG,
|
|
4731
5455
|
INPUT_FLAG
|
|
4732
5456
|
],
|
|
4733
5457
|
examples: [
|
|
4734
|
-
"brew-cli emails list --status
|
|
4735
|
-
"brew-cli emails list --group-id ungrouped
|
|
4736
|
-
"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",
|
|
4737
5461
|
"brew-cli emails list --all --json"
|
|
4738
5462
|
],
|
|
4739
5463
|
run: async ({ ctx, flags }) => {
|
|
5464
|
+
const legacy = legacyWindow(
|
|
5465
|
+
flags,
|
|
5466
|
+
flagString(flags.sortBy) ?? flagString(flags.sort)
|
|
5467
|
+
);
|
|
4740
5468
|
const base = await readJsonFlag(ctx, flags.input, "--input");
|
|
4741
5469
|
const input = mergeInput(base, {
|
|
4742
5470
|
status: flagString(flags.status),
|
|
4743
5471
|
groupId: flagString(flags.groupId),
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
createdAtTo: flagString(flags.createdAtTo),
|
|
4748
|
-
updatedAtFrom: flagString(flags.updatedAtFrom),
|
|
4749
|
-
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,
|
|
4750
5475
|
limit: flagInt(flags.limit, "--limit"),
|
|
4751
5476
|
cursor: flagString(flags.cursor)
|
|
4752
5477
|
});
|
|
@@ -4770,6 +5495,40 @@ var emailsListCommand = defineCommand({
|
|
|
4770
5495
|
return { data: result, human: renderEmails(result.data) };
|
|
4771
5496
|
}
|
|
4772
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
|
+
}
|
|
4773
5532
|
function renderEmails(rows) {
|
|
4774
5533
|
if (rows.length === 0) {
|
|
4775
5534
|
return "No email designs found.";
|
|
@@ -4786,7 +5545,7 @@ function renderEmails(rows) {
|
|
|
4786
5545
|
// src/commands/emails/preview-clients.ts
|
|
4787
5546
|
var emailsPreviewClientsCommand = defineCommand({
|
|
4788
5547
|
path: ["emails", "preview-clients"],
|
|
4789
|
-
summary: "
|
|
5548
|
+
summary: "Start a rendering job across real email clients (10 credits); poll it with `emails get-client-preview`",
|
|
4790
5549
|
sdkMethod: "emails.previewClients",
|
|
4791
5550
|
route: { method: "POST", path: "/v1/emails/{emailId}/client-previews" },
|
|
4792
5551
|
commandClass: "write",
|
|
@@ -4799,25 +5558,49 @@ var emailsPreviewClientsCommand = defineCommand({
|
|
|
4799
5558
|
flag: "--clients <ids...>",
|
|
4800
5559
|
summary: "Client id(s) to render, repeatable (e.g. applemail16 iphone16_18); default: a popular spread"
|
|
4801
5560
|
},
|
|
5561
|
+
{
|
|
5562
|
+
flag: "--email-version-id <id>",
|
|
5563
|
+
summary: "Render this saved version (default: the latest)"
|
|
5564
|
+
},
|
|
4802
5565
|
IDEMPOTENCY_FLAG
|
|
4803
5566
|
],
|
|
4804
5567
|
examples: [
|
|
4805
5568
|
"brew-cli emails preview-clients eml_2SmZOWV3ZQ7W5x6g3m4p",
|
|
4806
|
-
"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"'
|
|
4807
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.
|
|
4808
5576
|
run: async ({ ctx, args, flags }) => {
|
|
4809
5577
|
const clients = toStringArray(flags.clients);
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
}
|
|
4816
|
-
|
|
4817
|
-
)
|
|
4818
|
-
|
|
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 };
|
|
4819
5592
|
}
|
|
4820
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
|
+
}
|
|
4821
5604
|
|
|
4822
5605
|
// src/commands/emails/restore.ts
|
|
4823
5606
|
var emailsRestoreCommand = defineCommand({
|
|
@@ -4831,19 +5614,24 @@ var emailsRestoreCommand = defineCommand({
|
|
|
4831
5614
|
],
|
|
4832
5615
|
// --version is taken by the CLI itself, hence --to-version.
|
|
4833
5616
|
flags: [
|
|
4834
|
-
{
|
|
5617
|
+
{
|
|
5618
|
+
flag: "--to-version <emailVersionId>",
|
|
5619
|
+
summary: "Version id to restore (from `emails get <emailId> --include versions`)"
|
|
5620
|
+
},
|
|
4835
5621
|
IDEMPOTENCY_FLAG
|
|
4836
5622
|
],
|
|
4837
|
-
examples: [
|
|
5623
|
+
examples: [
|
|
5624
|
+
"brew-cli emails restore eml_2SmZOWV3ZQ7W5x6g3m4p --to-version emv_7Hq2"
|
|
5625
|
+
],
|
|
4838
5626
|
run: async ({ ctx, args, flags }) => {
|
|
4839
|
-
const
|
|
4840
|
-
if (
|
|
5627
|
+
const emailVersionId = flagString(flags.toVersion);
|
|
5628
|
+
if (emailVersionId === void 0) {
|
|
4841
5629
|
throw new CliUsageError(
|
|
4842
|
-
"--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`)."
|
|
4843
5631
|
);
|
|
4844
5632
|
}
|
|
4845
5633
|
const result = await ctx.client().emails.restore(
|
|
4846
|
-
{ emailId: args.emailId ?? "",
|
|
5634
|
+
{ emailId: args.emailId ?? "", emailVersionId },
|
|
4847
5635
|
requestOptions(flags)
|
|
4848
5636
|
);
|
|
4849
5637
|
return { data: result };
|
|
@@ -5013,6 +5801,26 @@ var fieldsDeleteCommand = defineCommand({
|
|
|
5013
5801
|
})
|
|
5014
5802
|
});
|
|
5015
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
|
+
|
|
5016
5824
|
// src/commands/fields/list.ts
|
|
5017
5825
|
var fieldsListCommand = defineCommand({
|
|
5018
5826
|
path: ["fields", "list"],
|
|
@@ -5024,6 +5832,178 @@ var fieldsListCommand = defineCommand({
|
|
|
5024
5832
|
run: async ({ ctx }) => ({ data: await ctx.client().fields.list() })
|
|
5025
5833
|
});
|
|
5026
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
|
+
|
|
5027
6007
|
// src/commands/health.ts
|
|
5028
6008
|
var healthCommand = defineCommand({
|
|
5029
6009
|
path: ["health"],
|
|
@@ -5150,6 +6130,35 @@ var sendsCancelCommand = defineCommand({
|
|
|
5150
6130
|
})
|
|
5151
6131
|
});
|
|
5152
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
|
+
|
|
5153
6162
|
// src/commands/sends/pause.ts
|
|
5154
6163
|
var sendsPauseCommand = defineCommand({
|
|
5155
6164
|
path: ["sends", "pause"],
|
|
@@ -5168,7 +6177,7 @@ var sendsPauseCommand = defineCommand({
|
|
|
5168
6177
|
// src/commands/sends/resume.ts
|
|
5169
6178
|
var sendsResumeCommand = defineCommand({
|
|
5170
6179
|
path: ["sends", "resume"],
|
|
5171
|
-
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",
|
|
5172
6181
|
sdkMethod: "sends.resume",
|
|
5173
6182
|
route: { method: "POST", path: "/v1/sends/{sendId}/resume" },
|
|
5174
6183
|
commandClass: "write",
|
|
@@ -5180,6 +6189,41 @@ var sendsResumeCommand = defineCommand({
|
|
|
5180
6189
|
})
|
|
5181
6190
|
});
|
|
5182
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
|
+
|
|
5183
6227
|
// src/commands/templates/list.ts
|
|
5184
6228
|
var templatesListCommand = defineCommand({
|
|
5185
6229
|
path: ["templates", "list"],
|
|
@@ -5487,6 +6531,7 @@ var ALL_COMMANDS = [
|
|
|
5487
6531
|
configGetCommand,
|
|
5488
6532
|
configSetCommand,
|
|
5489
6533
|
configUnsetCommand,
|
|
6534
|
+
contactsListCommand,
|
|
5490
6535
|
contactsSearchCommand,
|
|
5491
6536
|
contactsGetCommand,
|
|
5492
6537
|
contactsCountCommand,
|
|
@@ -5498,10 +6543,12 @@ var ALL_COMMANDS = [
|
|
|
5498
6543
|
contactsValidateCommand,
|
|
5499
6544
|
contactsImportCsvCommand,
|
|
5500
6545
|
fieldsListCommand,
|
|
6546
|
+
fieldsGetCommand,
|
|
5501
6547
|
fieldsCreateCommand,
|
|
5502
6548
|
fieldsDeleteCommand,
|
|
5503
6549
|
emailsListCommand,
|
|
5504
6550
|
emailsGroupsListCommand,
|
|
6551
|
+
emailsGroupsGetCommand,
|
|
5505
6552
|
emailsGroupsCreateCommand,
|
|
5506
6553
|
emailsGroupsUpdateCommand,
|
|
5507
6554
|
emailsGroupsDeleteCommand,
|
|
@@ -5515,10 +6562,15 @@ var ALL_COMMANDS = [
|
|
|
5515
6562
|
emailsDeleteCommand,
|
|
5516
6563
|
emailsExportCommand,
|
|
5517
6564
|
emailsAuditCommand,
|
|
6565
|
+
emailsGetAuditCommand,
|
|
5518
6566
|
emailsPreviewClientsCommand,
|
|
6567
|
+
emailsGetClientPreviewCommand,
|
|
5519
6568
|
emailsCreateInboxPlacementTestCommand,
|
|
5520
6569
|
emailsGetInboxPlacementResultsCommand,
|
|
6570
|
+
emailsInboxPlacementTestsGetCommand,
|
|
5521
6571
|
emailsSendCommand,
|
|
6572
|
+
sendsListCommand,
|
|
6573
|
+
sendsGetCommand,
|
|
5522
6574
|
sendsCancelCommand,
|
|
5523
6575
|
sendsPauseCommand,
|
|
5524
6576
|
sendsResumeCommand,
|
|
@@ -5540,18 +6592,28 @@ var ALL_COMMANDS = [
|
|
|
5540
6592
|
automationsTestCommand,
|
|
5541
6593
|
automationsRunCommand,
|
|
5542
6594
|
automationsTriggersListCommand,
|
|
6595
|
+
automationsTriggersGetCommand,
|
|
5543
6596
|
automationsTriggersReadyCommand,
|
|
5544
6597
|
automationsTriggersContractGetCommand,
|
|
5545
6598
|
automationsTriggersContractPutCommand,
|
|
5546
6599
|
automationsTriggersContractValidateCommand,
|
|
5547
6600
|
contractsInferCommand,
|
|
6601
|
+
dataRunCommand,
|
|
5548
6602
|
automationsTriggersCreateCommand,
|
|
5549
6603
|
automationsTriggersUpdateCommand,
|
|
5550
6604
|
automationsTriggersDeleteCommand,
|
|
5551
6605
|
automationsTriggersFireCommand,
|
|
5552
6606
|
automationsRunsListCommand,
|
|
6607
|
+
automationsRunsGetCommand,
|
|
6608
|
+
automationsRunsCancelCommand,
|
|
5553
6609
|
automationsAudienceRunsListCommand,
|
|
6610
|
+
automationsAudienceRunsGetCommand,
|
|
6611
|
+
automationsAudienceRunsPauseCommand,
|
|
6612
|
+
automationsAudienceRunsResumeCommand,
|
|
6613
|
+
automationsAudienceRunsCancelCommand,
|
|
5554
6614
|
automationsAudienceRunsControlCommand,
|
|
6615
|
+
automationsTriggerInstancesListCommand,
|
|
6616
|
+
automationsTriggerInstancesGetCommand,
|
|
5555
6617
|
analyticsOverviewCommand,
|
|
5556
6618
|
analyticsCampaignsCommand,
|
|
5557
6619
|
analyticsAutomationsCommand,
|
|
@@ -5581,6 +6643,9 @@ var ALL_COMMANDS = [
|
|
|
5581
6643
|
contentHtmlToPngCommand,
|
|
5582
6644
|
contentAddImageCommand,
|
|
5583
6645
|
templatesListCommand,
|
|
6646
|
+
templatesGetCommand,
|
|
6647
|
+
flowsListCommand,
|
|
6648
|
+
flowsGetCommand,
|
|
5584
6649
|
integrationsListCommand,
|
|
5585
6650
|
chatsGetCommand,
|
|
5586
6651
|
healthCommand,
|
|
@@ -5593,7 +6658,8 @@ var ALL_COMMANDS = [
|
|
|
5593
6658
|
|
|
5594
6659
|
// src/cli.ts
|
|
5595
6660
|
var GROUP_SUMMARIES = {
|
|
5596
|
-
analytics: "
|
|
6661
|
+
analytics: "Reports: overview, events, and automation analytics",
|
|
6662
|
+
"audience-runs": "Manual-audience launches: read, pause, resume, cancel",
|
|
5597
6663
|
"api-keys": "Manage organization API keys",
|
|
5598
6664
|
audiences: "Manage audience segments",
|
|
5599
6665
|
automations: "Manage automation graphs, triggers, and runs",
|
|
@@ -5607,15 +6673,17 @@ var GROUP_SUMMARIES = {
|
|
|
5607
6673
|
domains: "Manage sending domains",
|
|
5608
6674
|
emails: "Manage email designs and send campaigns",
|
|
5609
6675
|
fields: "Manage custom contact fields",
|
|
6676
|
+
flows: "Browse public email flows (real multi-step sequences by brand)",
|
|
5610
6677
|
groups: "Manage email folders (groups)",
|
|
5611
6678
|
integrations: "Read the connected-integration catalog",
|
|
5612
|
-
|
|
6679
|
+
"inbox-placement-tests": "Inbox placement (seed) test results",
|
|
6680
|
+
sends: "Read sends, and control one in flight or scheduled",
|
|
5613
6681
|
templates: "Browse the template gallery",
|
|
5614
6682
|
contract: "Stored payload contracts (get, put, validate)",
|
|
5615
6683
|
contracts: "Payload-contract helpers",
|
|
5616
6684
|
triggers: "Manage trigger events",
|
|
5617
|
-
runs: "Automation run history",
|
|
5618
|
-
"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)"
|
|
5619
6687
|
};
|
|
5620
6688
|
var AGENT_HELP_FOOTER = `
|
|
5621
6689
|
Environment:
|