@hogsend/cli 0.7.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/dist/bin.js +440 -4
- package/dist/bin.js.map +1 -1
- package/package.json +2 -2
- package/skills/hogsend-cli/SKILL.md +1 -0
- package/skills/hogsend-client-sdk/SKILL.md +40 -1
- package/skills/hogsend-client-sdk/references/api-surface.md +99 -0
- package/skills/hogsend-webhooks-and-workflows/SKILL.md +20 -5
- package/skills/hogsend-webhooks-and-workflows/references/webhook-source.md +57 -12
- package/src/commands/index.ts +2 -0
- package/src/commands/webhooks.ts +563 -0
- package/src/lib/http.ts +6 -0
package/dist/bin.js
CHANGED
|
@@ -85,6 +85,10 @@ function createAdminClient(cfg) {
|
|
|
85
85
|
post: (path, body) => request(cfg.baseUrl, cfg.adminKey, missing, "POST", path, {
|
|
86
86
|
body,
|
|
87
87
|
auth: true
|
|
88
|
+
}),
|
|
89
|
+
del: (path, body) => request(cfg.baseUrl, cfg.adminKey, missing, "DELETE", path, {
|
|
90
|
+
body,
|
|
91
|
+
auth: true
|
|
88
92
|
})
|
|
89
93
|
};
|
|
90
94
|
}
|
|
@@ -1057,8 +1061,8 @@ async function run3(ctx) {
|
|
|
1057
1061
|
if (!ok) process.exit(1);
|
|
1058
1062
|
return;
|
|
1059
1063
|
}
|
|
1060
|
-
const
|
|
1061
|
-
ctx.out.intro(
|
|
1064
|
+
const badge6 = `${color.bgMagenta(color.black(" hogsend "))} doctor`;
|
|
1065
|
+
ctx.out.intro(badge6);
|
|
1062
1066
|
const verdictColor = verdict === "ok" ? color.green : verdict === "degraded" ? color.red : color.yellow;
|
|
1063
1067
|
const lines = [
|
|
1064
1068
|
`${verdictColor("\u25CF")} ${color.bold(verdict)}`,
|
|
@@ -2944,6 +2948,437 @@ var upgradeCommand = {
|
|
|
2944
2948
|
run: run13
|
|
2945
2949
|
};
|
|
2946
2950
|
|
|
2951
|
+
// src/commands/webhooks.ts
|
|
2952
|
+
import { parseArgs as parseArgs14 } from "util";
|
|
2953
|
+
var WEBHOOK_EVENT_TYPES = [
|
|
2954
|
+
"contact.created",
|
|
2955
|
+
"contact.updated",
|
|
2956
|
+
"contact.deleted",
|
|
2957
|
+
"contact.unsubscribed",
|
|
2958
|
+
"email.sent",
|
|
2959
|
+
"email.delivered",
|
|
2960
|
+
"email.opened",
|
|
2961
|
+
"email.clicked",
|
|
2962
|
+
"email.bounced",
|
|
2963
|
+
"journey.completed",
|
|
2964
|
+
"bucket.entered",
|
|
2965
|
+
"bucket.left"
|
|
2966
|
+
];
|
|
2967
|
+
var usage14 = `hogsend webhooks <subcommand> [options]
|
|
2968
|
+
|
|
2969
|
+
Manage outbound webhook endpoints \u2014 the Svix-style signed event stream Hogsend
|
|
2970
|
+
emits to your URLs. Wraps the admin routes (/v1/admin/webhooks), so this command
|
|
2971
|
+
REQUIRES an admin key (--admin-key / HOGSEND_ADMIN_KEY), not the data key.
|
|
2972
|
+
|
|
2973
|
+
Subcommands:
|
|
2974
|
+
list List endpoints.
|
|
2975
|
+
get <id> Show one endpoint.
|
|
2976
|
+
create Register an endpoint (prints the secret ONCE).
|
|
2977
|
+
update <id> Patch an endpoint.
|
|
2978
|
+
delete <id> Hard-delete an endpoint (drops its deliveries).
|
|
2979
|
+
rotate-secret <id> Issue a new signing secret (prints it ONCE).
|
|
2980
|
+
test <id> Enqueue an out-of-band webhook.test delivery.
|
|
2981
|
+
|
|
2982
|
+
list options:
|
|
2983
|
+
--include-disabled Include disabled endpoints.
|
|
2984
|
+
--limit <n> Page size.
|
|
2985
|
+
--offset <n> Page offset.
|
|
2986
|
+
|
|
2987
|
+
create options (--url required, plus at least one event):
|
|
2988
|
+
--url <url> Destination URL (required).
|
|
2989
|
+
--event <type> Subscribe to an event; repeatable.
|
|
2990
|
+
--all-events Subscribe to all 12 event types.
|
|
2991
|
+
--description <text> Human label.
|
|
2992
|
+
--disabled Create the endpoint disabled.
|
|
2993
|
+
|
|
2994
|
+
update options (only the provided fields change):
|
|
2995
|
+
--url <url> New destination URL.
|
|
2996
|
+
--event <type> Replace the subscribed events (repeatable).
|
|
2997
|
+
--all-events Subscribe to all 12 event types.
|
|
2998
|
+
--description <text> New description.
|
|
2999
|
+
--disabled / --enabled Disable or enable the endpoint.
|
|
3000
|
+
|
|
3001
|
+
Event types:
|
|
3002
|
+
${WEBHOOK_EVENT_TYPES.join(", ")}
|
|
3003
|
+
|
|
3004
|
+
Global options (handled by the router): --url, --admin-key, --data-key, --json,
|
|
3005
|
+
-h/--help.
|
|
3006
|
+
|
|
3007
|
+
Examples:
|
|
3008
|
+
hogsend webhooks create --url https://x.com/hook --event contact.created --event email.sent
|
|
3009
|
+
hogsend webhooks create --url https://x.com/hook --all-events --json
|
|
3010
|
+
hogsend webhooks list --include-disabled
|
|
3011
|
+
hogsend webhooks rotate-secret we_123
|
|
3012
|
+
hogsend webhooks test we_123`;
|
|
3013
|
+
var badge5 = `${color.bgMagenta(color.black(" hogsend "))} webhooks`;
|
|
3014
|
+
async function fetchOrFail2(ctx, label, fn) {
|
|
3015
|
+
try {
|
|
3016
|
+
return await ctx.out.step(label, fn);
|
|
3017
|
+
} catch (err) {
|
|
3018
|
+
if (isHttpError(err)) {
|
|
3019
|
+
if (err.status === 404) {
|
|
3020
|
+
ctx.out.fail(err.message || "webhook endpoint not found");
|
|
3021
|
+
}
|
|
3022
|
+
ctx.out.fail(err.message);
|
|
3023
|
+
}
|
|
3024
|
+
throw err;
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
function resolveEvents(ctx, allEvents, events) {
|
|
3028
|
+
if (allEvents) {
|
|
3029
|
+
return [...WEBHOOK_EVENT_TYPES];
|
|
3030
|
+
}
|
|
3031
|
+
if (!events || events.length === 0) {
|
|
3032
|
+
return void 0;
|
|
3033
|
+
}
|
|
3034
|
+
const valid = new Set(WEBHOOK_EVENT_TYPES);
|
|
3035
|
+
const out = [];
|
|
3036
|
+
for (const ev of events) {
|
|
3037
|
+
if (!valid.has(ev)) {
|
|
3038
|
+
ctx.out.fail(
|
|
3039
|
+
`unknown event type "${ev}" \u2014 expected one of: ${WEBHOOK_EVENT_TYPES.join(", ")}`
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
if (!out.includes(ev)) {
|
|
3043
|
+
out.push(ev);
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
return out;
|
|
3047
|
+
}
|
|
3048
|
+
function printSecretOnce(ctx, secret) {
|
|
3049
|
+
ctx.out.note(
|
|
3050
|
+
`${color.yellow("Store this signing secret now \u2014 it is shown only once and cannot be recovered.")}
|
|
3051
|
+
|
|
3052
|
+
${color.bold(secret)}`,
|
|
3053
|
+
color.yellow("Signing secret")
|
|
3054
|
+
);
|
|
3055
|
+
}
|
|
3056
|
+
async function runList4(ctx, argv) {
|
|
3057
|
+
const { values } = parseArgs14({
|
|
3058
|
+
args: argv,
|
|
3059
|
+
allowPositionals: true,
|
|
3060
|
+
options: {
|
|
3061
|
+
"include-disabled": { type: "boolean", default: false },
|
|
3062
|
+
limit: { type: "string" },
|
|
3063
|
+
offset: { type: "string" },
|
|
3064
|
+
help: { type: "boolean", short: "h", default: false }
|
|
3065
|
+
}
|
|
3066
|
+
});
|
|
3067
|
+
if (values.help) {
|
|
3068
|
+
ctx.out.log(usage14);
|
|
3069
|
+
return;
|
|
3070
|
+
}
|
|
3071
|
+
const query = {
|
|
3072
|
+
includeDisabled: values["include-disabled"] ? "true" : void 0,
|
|
3073
|
+
limit: values.limit,
|
|
3074
|
+
offset: values.offset
|
|
3075
|
+
};
|
|
3076
|
+
if (!ctx.json) ctx.out.intro(`${badge5} list`);
|
|
3077
|
+
const res = await fetchOrFail2(
|
|
3078
|
+
ctx,
|
|
3079
|
+
"Fetching webhooks",
|
|
3080
|
+
() => ctx.http.get("/v1/admin/webhooks", query)
|
|
3081
|
+
);
|
|
3082
|
+
if (ctx.json) {
|
|
3083
|
+
ctx.out.json(res);
|
|
3084
|
+
return;
|
|
3085
|
+
}
|
|
3086
|
+
ctx.out.table(
|
|
3087
|
+
res.endpoints.map((ep) => ({
|
|
3088
|
+
id: ep.id,
|
|
3089
|
+
url: ep.url,
|
|
3090
|
+
status: ep.status === "enabled" ? color.green(ep.status) : color.yellow(ep.status),
|
|
3091
|
+
events: ep.eventTypes.length,
|
|
3092
|
+
lastDeliveryAt: ep.lastDeliveryAt ?? color.dim("(never)")
|
|
3093
|
+
})),
|
|
3094
|
+
["id", "url", "status", "events", "lastDeliveryAt"]
|
|
3095
|
+
);
|
|
3096
|
+
ctx.out.outro(
|
|
3097
|
+
`${res.endpoints.length} of ${res.total} endpoint(s) \u2014 offset ${res.offset}, limit ${res.limit}`
|
|
3098
|
+
);
|
|
3099
|
+
}
|
|
3100
|
+
function renderEndpoint(ctx, ep, title) {
|
|
3101
|
+
ctx.out.kv(
|
|
3102
|
+
{
|
|
3103
|
+
id: ep.id,
|
|
3104
|
+
url: ep.url,
|
|
3105
|
+
description: ep.description ?? color.dim("(none)"),
|
|
3106
|
+
status: ep.status === "enabled" ? color.green(ep.status) : color.yellow(ep.status),
|
|
3107
|
+
eventTypes: ep.eventTypes,
|
|
3108
|
+
secretPrefix: ep.secretPrefix,
|
|
3109
|
+
lastDeliveryAt: ep.lastDeliveryAt ?? color.dim("(never)"),
|
|
3110
|
+
createdAt: ep.createdAt,
|
|
3111
|
+
updatedAt: ep.updatedAt
|
|
3112
|
+
},
|
|
3113
|
+
title
|
|
3114
|
+
);
|
|
3115
|
+
}
|
|
3116
|
+
async function runGet3(ctx, argv) {
|
|
3117
|
+
const { values, positionals } = parseArgs14({
|
|
3118
|
+
args: argv,
|
|
3119
|
+
allowPositionals: true,
|
|
3120
|
+
options: { help: { type: "boolean", short: "h", default: false } }
|
|
3121
|
+
});
|
|
3122
|
+
if (values.help) {
|
|
3123
|
+
ctx.out.log(usage14);
|
|
3124
|
+
return;
|
|
3125
|
+
}
|
|
3126
|
+
const id = positionals[0];
|
|
3127
|
+
if (!id) {
|
|
3128
|
+
ctx.out.fail(
|
|
3129
|
+
"webhooks get requires an endpoint id, e.g. hogsend webhooks get we_123"
|
|
3130
|
+
);
|
|
3131
|
+
}
|
|
3132
|
+
if (!ctx.json) ctx.out.intro(`${badge5} get`);
|
|
3133
|
+
const res = await fetchOrFail2(
|
|
3134
|
+
ctx,
|
|
3135
|
+
"Fetching webhook",
|
|
3136
|
+
() => ctx.http.get(
|
|
3137
|
+
`/v1/admin/webhooks/${encodeURIComponent(id)}`
|
|
3138
|
+
)
|
|
3139
|
+
);
|
|
3140
|
+
if (ctx.json) {
|
|
3141
|
+
ctx.out.json(res);
|
|
3142
|
+
return;
|
|
3143
|
+
}
|
|
3144
|
+
renderEndpoint(ctx, res, "Endpoint");
|
|
3145
|
+
ctx.out.outro(`${res.url} \u2192 ${res.status}`);
|
|
3146
|
+
}
|
|
3147
|
+
async function runCreate(ctx, argv) {
|
|
3148
|
+
const { values } = parseArgs14({
|
|
3149
|
+
args: argv,
|
|
3150
|
+
allowPositionals: true,
|
|
3151
|
+
options: {
|
|
3152
|
+
url: { type: "string" },
|
|
3153
|
+
event: { type: "string", multiple: true },
|
|
3154
|
+
"all-events": { type: "boolean", default: false },
|
|
3155
|
+
description: { type: "string" },
|
|
3156
|
+
disabled: { type: "boolean", default: false },
|
|
3157
|
+
help: { type: "boolean", short: "h", default: false }
|
|
3158
|
+
}
|
|
3159
|
+
});
|
|
3160
|
+
if (values.help) {
|
|
3161
|
+
ctx.out.log(usage14);
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
const url = values.url;
|
|
3165
|
+
if (!url) {
|
|
3166
|
+
ctx.out.fail(
|
|
3167
|
+
"webhooks create requires --url, e.g. hogsend webhooks create --url https://x.com/hook --all-events"
|
|
3168
|
+
);
|
|
3169
|
+
}
|
|
3170
|
+
const eventTypes = resolveEvents(ctx, values["all-events"], values.event);
|
|
3171
|
+
if (!eventTypes || eventTypes.length === 0) {
|
|
3172
|
+
ctx.out.fail(
|
|
3173
|
+
"webhooks create requires at least one --event <type> (or --all-events)"
|
|
3174
|
+
);
|
|
3175
|
+
}
|
|
3176
|
+
const body = { url, eventTypes };
|
|
3177
|
+
if (values.description !== void 0) body.description = values.description;
|
|
3178
|
+
if (values.disabled) body.disabled = true;
|
|
3179
|
+
if (!ctx.json) ctx.out.intro(`${badge5} create`);
|
|
3180
|
+
const res = await fetchOrFail2(
|
|
3181
|
+
ctx,
|
|
3182
|
+
"Creating webhook",
|
|
3183
|
+
() => ctx.http.post("/v1/admin/webhooks", body)
|
|
3184
|
+
);
|
|
3185
|
+
if (ctx.json) {
|
|
3186
|
+
ctx.out.json(res);
|
|
3187
|
+
return;
|
|
3188
|
+
}
|
|
3189
|
+
const { secret, ...endpoint } = res;
|
|
3190
|
+
renderEndpoint(ctx, endpoint, "Endpoint created");
|
|
3191
|
+
printSecretOnce(ctx, secret);
|
|
3192
|
+
ctx.out.outro(`${color.green("Created")} ${res.id} \u2192 ${res.url}`);
|
|
3193
|
+
}
|
|
3194
|
+
async function runUpdate(ctx, argv) {
|
|
3195
|
+
const { values, positionals } = parseArgs14({
|
|
3196
|
+
args: argv,
|
|
3197
|
+
allowPositionals: true,
|
|
3198
|
+
options: {
|
|
3199
|
+
url: { type: "string" },
|
|
3200
|
+
event: { type: "string", multiple: true },
|
|
3201
|
+
"all-events": { type: "boolean", default: false },
|
|
3202
|
+
description: { type: "string" },
|
|
3203
|
+
disabled: { type: "boolean", default: false },
|
|
3204
|
+
enabled: { type: "boolean", default: false },
|
|
3205
|
+
help: { type: "boolean", short: "h", default: false }
|
|
3206
|
+
}
|
|
3207
|
+
});
|
|
3208
|
+
if (values.help) {
|
|
3209
|
+
ctx.out.log(usage14);
|
|
3210
|
+
return;
|
|
3211
|
+
}
|
|
3212
|
+
const id = positionals[0];
|
|
3213
|
+
if (!id) {
|
|
3214
|
+
ctx.out.fail(
|
|
3215
|
+
"webhooks update requires an endpoint id, e.g. hogsend webhooks update we_123 --enabled"
|
|
3216
|
+
);
|
|
3217
|
+
}
|
|
3218
|
+
if (values.disabled && values.enabled) {
|
|
3219
|
+
ctx.out.fail("webhooks update: pass at most one of --disabled / --enabled");
|
|
3220
|
+
}
|
|
3221
|
+
const eventTypes = resolveEvents(ctx, values["all-events"], values.event);
|
|
3222
|
+
const body = {};
|
|
3223
|
+
if (values.url !== void 0) body.url = values.url;
|
|
3224
|
+
if (eventTypes !== void 0) body.eventTypes = eventTypes;
|
|
3225
|
+
if (values.description !== void 0) body.description = values.description;
|
|
3226
|
+
if (values.disabled) body.disabled = true;
|
|
3227
|
+
if (values.enabled) body.disabled = false;
|
|
3228
|
+
if (Object.keys(body).length === 0) {
|
|
3229
|
+
ctx.out.fail(
|
|
3230
|
+
"webhooks update: nothing to change \u2014 pass --url / --event / --description / --disabled / --enabled"
|
|
3231
|
+
);
|
|
3232
|
+
}
|
|
3233
|
+
if (!ctx.json) ctx.out.intro(`${badge5} update`);
|
|
3234
|
+
const res = await fetchOrFail2(
|
|
3235
|
+
ctx,
|
|
3236
|
+
"Updating webhook",
|
|
3237
|
+
() => ctx.http.patch(
|
|
3238
|
+
`/v1/admin/webhooks/${encodeURIComponent(id)}`,
|
|
3239
|
+
body
|
|
3240
|
+
)
|
|
3241
|
+
);
|
|
3242
|
+
if (ctx.json) {
|
|
3243
|
+
ctx.out.json(res);
|
|
3244
|
+
return;
|
|
3245
|
+
}
|
|
3246
|
+
renderEndpoint(ctx, res, "Endpoint updated");
|
|
3247
|
+
ctx.out.outro(`${color.green("Updated")} ${res.id} \u2192 ${res.status}`);
|
|
3248
|
+
}
|
|
3249
|
+
async function runDelete(ctx, argv) {
|
|
3250
|
+
const { values, positionals } = parseArgs14({
|
|
3251
|
+
args: argv,
|
|
3252
|
+
allowPositionals: true,
|
|
3253
|
+
options: { help: { type: "boolean", short: "h", default: false } }
|
|
3254
|
+
});
|
|
3255
|
+
if (values.help) {
|
|
3256
|
+
ctx.out.log(usage14);
|
|
3257
|
+
return;
|
|
3258
|
+
}
|
|
3259
|
+
const id = positionals[0];
|
|
3260
|
+
if (!id) {
|
|
3261
|
+
ctx.out.fail(
|
|
3262
|
+
"webhooks delete requires an endpoint id, e.g. hogsend webhooks delete we_123"
|
|
3263
|
+
);
|
|
3264
|
+
}
|
|
3265
|
+
if (!ctx.json) ctx.out.intro(`${badge5} delete`);
|
|
3266
|
+
const res = await fetchOrFail2(
|
|
3267
|
+
ctx,
|
|
3268
|
+
"Deleting webhook",
|
|
3269
|
+
() => ctx.http.del(
|
|
3270
|
+
`/v1/admin/webhooks/${encodeURIComponent(id)}`
|
|
3271
|
+
)
|
|
3272
|
+
);
|
|
3273
|
+
if (ctx.json) {
|
|
3274
|
+
ctx.out.json(res);
|
|
3275
|
+
return;
|
|
3276
|
+
}
|
|
3277
|
+
ctx.out.outro(`${color.green("Deleted")} ${id}`);
|
|
3278
|
+
}
|
|
3279
|
+
async function runRotate(ctx, argv) {
|
|
3280
|
+
const { values, positionals } = parseArgs14({
|
|
3281
|
+
args: argv,
|
|
3282
|
+
allowPositionals: true,
|
|
3283
|
+
options: { help: { type: "boolean", short: "h", default: false } }
|
|
3284
|
+
});
|
|
3285
|
+
if (values.help) {
|
|
3286
|
+
ctx.out.log(usage14);
|
|
3287
|
+
return;
|
|
3288
|
+
}
|
|
3289
|
+
const id = positionals[0];
|
|
3290
|
+
if (!id) {
|
|
3291
|
+
ctx.out.fail(
|
|
3292
|
+
"webhooks rotate-secret requires an endpoint id, e.g. hogsend webhooks rotate-secret we_123"
|
|
3293
|
+
);
|
|
3294
|
+
}
|
|
3295
|
+
if (!ctx.json) ctx.out.intro(`${badge5} rotate-secret`);
|
|
3296
|
+
const res = await fetchOrFail2(
|
|
3297
|
+
ctx,
|
|
3298
|
+
"Rotating signing secret",
|
|
3299
|
+
() => ctx.http.post(
|
|
3300
|
+
`/v1/admin/webhooks/${encodeURIComponent(id)}/rotate-secret`,
|
|
3301
|
+
{}
|
|
3302
|
+
)
|
|
3303
|
+
);
|
|
3304
|
+
if (ctx.json) {
|
|
3305
|
+
ctx.out.json(res);
|
|
3306
|
+
return;
|
|
3307
|
+
}
|
|
3308
|
+
ctx.out.kv({ id: res.id, secretPrefix: res.secretPrefix }, "Secret rotated");
|
|
3309
|
+
printSecretOnce(ctx, res.secret);
|
|
3310
|
+
ctx.out.outro(
|
|
3311
|
+
`${color.green("Rotated")} \u2014 the old secret is now invalid. Update every subscriber.`
|
|
3312
|
+
);
|
|
3313
|
+
}
|
|
3314
|
+
async function runTest(ctx, argv) {
|
|
3315
|
+
const { values, positionals } = parseArgs14({
|
|
3316
|
+
args: argv,
|
|
3317
|
+
allowPositionals: true,
|
|
3318
|
+
options: { help: { type: "boolean", short: "h", default: false } }
|
|
3319
|
+
});
|
|
3320
|
+
if (values.help) {
|
|
3321
|
+
ctx.out.log(usage14);
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
3324
|
+
const id = positionals[0];
|
|
3325
|
+
if (!id) {
|
|
3326
|
+
ctx.out.fail(
|
|
3327
|
+
"webhooks test requires an endpoint id, e.g. hogsend webhooks test we_123"
|
|
3328
|
+
);
|
|
3329
|
+
}
|
|
3330
|
+
if (!ctx.json) ctx.out.intro(`${badge5} test`);
|
|
3331
|
+
const res = await fetchOrFail2(
|
|
3332
|
+
ctx,
|
|
3333
|
+
"Enqueuing test delivery",
|
|
3334
|
+
() => ctx.http.post(
|
|
3335
|
+
`/v1/admin/webhooks/${encodeURIComponent(id)}/test`,
|
|
3336
|
+
{}
|
|
3337
|
+
)
|
|
3338
|
+
);
|
|
3339
|
+
if (ctx.json) {
|
|
3340
|
+
ctx.out.json(res);
|
|
3341
|
+
return;
|
|
3342
|
+
}
|
|
3343
|
+
ctx.out.outro(
|
|
3344
|
+
`${color.green("Enqueued")} a ${color.cyan(res.eventType)} delivery to ${id}.`
|
|
3345
|
+
);
|
|
3346
|
+
}
|
|
3347
|
+
async function run14(ctx) {
|
|
3348
|
+
const sub = ctx.argv[0];
|
|
3349
|
+
switch (sub) {
|
|
3350
|
+
case "list":
|
|
3351
|
+
return runList4(ctx, ctx.argv.slice(1));
|
|
3352
|
+
case "get":
|
|
3353
|
+
return runGet3(ctx, ctx.argv.slice(1));
|
|
3354
|
+
case "create":
|
|
3355
|
+
return runCreate(ctx, ctx.argv.slice(1));
|
|
3356
|
+
case "update":
|
|
3357
|
+
return runUpdate(ctx, ctx.argv.slice(1));
|
|
3358
|
+
case "delete":
|
|
3359
|
+
return runDelete(ctx, ctx.argv.slice(1));
|
|
3360
|
+
case "rotate-secret":
|
|
3361
|
+
return runRotate(ctx, ctx.argv.slice(1));
|
|
3362
|
+
case "test":
|
|
3363
|
+
return runTest(ctx, ctx.argv.slice(1));
|
|
3364
|
+
case void 0:
|
|
3365
|
+
ctx.out.fail(
|
|
3366
|
+
"webhooks requires a subcommand: list | get | create | update | delete | rotate-secret | test (see hogsend webhooks --help)"
|
|
3367
|
+
);
|
|
3368
|
+
break;
|
|
3369
|
+
default:
|
|
3370
|
+
ctx.out.fail(
|
|
3371
|
+
`unknown webhooks subcommand "${sub}" \u2014 expected one of list | get | create | update | delete | rotate-secret | test`
|
|
3372
|
+
);
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
var webhooksCommand = {
|
|
3376
|
+
name: "webhooks",
|
|
3377
|
+
summary: "Manage outbound webhook endpoints (create, rotate, test)",
|
|
3378
|
+
usage: usage14,
|
|
3379
|
+
run: run14
|
|
3380
|
+
};
|
|
3381
|
+
|
|
2947
3382
|
// src/commands/index.ts
|
|
2948
3383
|
var commands = [
|
|
2949
3384
|
doctorCommand,
|
|
@@ -2953,6 +3388,7 @@ var commands = [
|
|
|
2953
3388
|
eventsCommand,
|
|
2954
3389
|
emailsCommand,
|
|
2955
3390
|
campaignsCommand,
|
|
3391
|
+
webhooksCommand,
|
|
2956
3392
|
studioCommand,
|
|
2957
3393
|
setupCommand,
|
|
2958
3394
|
skillsCommand,
|
|
@@ -2964,10 +3400,10 @@ var commands = [
|
|
|
2964
3400
|
// src/lib/config.ts
|
|
2965
3401
|
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
|
|
2966
3402
|
import { join as join8 } from "path";
|
|
2967
|
-
import { parseArgs as
|
|
3403
|
+
import { parseArgs as parseArgs15 } from "util";
|
|
2968
3404
|
var DEFAULT_BASE_URL = "http://localhost:3002";
|
|
2969
3405
|
function parseGlobalFlags(argv) {
|
|
2970
|
-
const { values, tokens } =
|
|
3406
|
+
const { values, tokens } = parseArgs15({
|
|
2971
3407
|
args: argv,
|
|
2972
3408
|
allowPositionals: true,
|
|
2973
3409
|
strict: false,
|