@dench.com/cli 2.6.0 → 2.7.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/cron.ts +29 -9
- package/email.ts +31 -0
- package/lib/command-registry.ts +2 -1
- package/package.json +1 -1
package/cron.ts
CHANGED
|
@@ -18,11 +18,9 @@
|
|
|
18
18
|
* both formats; we just pass whichever bearer the parent runtime
|
|
19
19
|
* resolved through `sessionToken`.
|
|
20
20
|
*
|
|
21
|
-
* Convex calls go direct via `ConvexHttpClient` (same pattern as
|
|
22
|
-
* `cli/crm.ts`)
|
|
23
|
-
*
|
|
24
|
-
* needs to start a Vercel Workflow which can only be done from a
|
|
25
|
-
* Next.js route.
|
|
21
|
+
* Convex calls generally go direct via `ConvexHttpClient` (same pattern as
|
|
22
|
+
* `cli/crm.ts`). Run-now and delete go through REST: run-now starts a Vercel
|
|
23
|
+
* Workflow, while delete coordinates upstream app-event cleanup.
|
|
26
24
|
*
|
|
27
25
|
* Subcommands:
|
|
28
26
|
* list List all cron jobs in the org.
|
|
@@ -166,6 +164,28 @@ async function getJson(
|
|
|
166
164
|
return json;
|
|
167
165
|
}
|
|
168
166
|
|
|
167
|
+
async function deleteJson(
|
|
168
|
+
url: string,
|
|
169
|
+
headers: Record<string, string>,
|
|
170
|
+
): Promise<unknown> {
|
|
171
|
+
const response = await fetch(url, { method: "DELETE", headers });
|
|
172
|
+
const text = await response.text();
|
|
173
|
+
let json: unknown;
|
|
174
|
+
try {
|
|
175
|
+
json = text ? JSON.parse(text) : null;
|
|
176
|
+
} catch {
|
|
177
|
+
json = { raw: text };
|
|
178
|
+
}
|
|
179
|
+
if (!response.ok) {
|
|
180
|
+
const detail =
|
|
181
|
+
json && typeof json === "object" && "error" in json
|
|
182
|
+
? String((json as Record<string, unknown>).error)
|
|
183
|
+
: JSON.stringify(json);
|
|
184
|
+
throw new CronCliError(`${url} failed (${response.status}): ${detail}`);
|
|
185
|
+
}
|
|
186
|
+
return json;
|
|
187
|
+
}
|
|
188
|
+
|
|
169
189
|
async function callQuery(
|
|
170
190
|
ctx: CronCliContext,
|
|
171
191
|
fn: Parameters<ConvexHttpClient["query"]>[0],
|
|
@@ -339,9 +359,6 @@ const createCronTriggerRef = makeFunctionReference<"mutation">(
|
|
|
339
359
|
const updateCronTriggerRef = makeFunctionReference<"mutation">(
|
|
340
360
|
"functions/triggers:updateCronTrigger",
|
|
341
361
|
);
|
|
342
|
-
const deleteCronTriggerRef = makeFunctionReference<"mutation">(
|
|
343
|
-
"functions/triggers:deleteCronTrigger",
|
|
344
|
-
);
|
|
345
362
|
const setCronEnabledRef = makeFunctionReference<"mutation">(
|
|
346
363
|
"functions/triggers:setCronEnabled",
|
|
347
364
|
);
|
|
@@ -709,7 +726,10 @@ async function runUpdate(ctx: CronCliContext): Promise<void> {
|
|
|
709
726
|
|
|
710
727
|
async function runDelete(ctx: CronCliContext): Promise<void> {
|
|
711
728
|
const jobId = shift(ctx.args, "job id");
|
|
712
|
-
const result = await
|
|
729
|
+
const result = await deleteJson(
|
|
730
|
+
`${getApiBase()}/api/cron/jobs/${encodeURIComponent(jobId)}`,
|
|
731
|
+
apiKeyHeaders(ctx.sessionToken ?? ""),
|
|
732
|
+
);
|
|
713
733
|
out(ctx, result);
|
|
714
734
|
}
|
|
715
735
|
|
package/email.ts
CHANGED
|
@@ -197,6 +197,8 @@ Usage:
|
|
|
197
197
|
dench email identity disable --identity <identityId|email|domain> [--json]
|
|
198
198
|
dench email identity restore --identity <identityId|email|domain> [--json]
|
|
199
199
|
dench email identity delete --identity <identityId|email|domain> [--json]
|
|
200
|
+
dench email identity forward --identity <identityId|email> --to inbox@you.com [--json] # forward this sender's sequence replies
|
|
201
|
+
dench email identity forward --identity <identityId|email> --off [--json] # turn forwarding off
|
|
200
202
|
dench email send --from founder@example.com --to "Ada <ada@x.com>,bob@y.com" --subject "Hi" (--html-file body.html | --text "...") [--cc ...] [--bcc ...] [--from-name "Ada"] [--reply-to support@x.com] [--reply-message-id <messageId|rfc-id>] [--json]
|
|
201
203
|
dench email message status --message <messageId> [--json]
|
|
202
204
|
dench email message list [--limit 25] [--json]
|
|
@@ -500,6 +502,7 @@ async function runIdentity(ctx: EmailCliContext) {
|
|
|
500
502
|
`${identity.identityId} ${identity.fromEmail} type=${identity.type}` +
|
|
501
503
|
`${identity.domain ? ` domain=${identity.domain}` : ""}` +
|
|
502
504
|
` delivery=${identity.deliveryVerificationStatus} workspace=${identity.denchVerificationStatus}` +
|
|
505
|
+
`${identity.forwardRepliesTo ? ` forward=${identity.forwardRepliesTo}` : ""}` +
|
|
503
506
|
`${identity.disabled ? " DISABLED" : ""}`,
|
|
504
507
|
)
|
|
505
508
|
.join("\n");
|
|
@@ -545,6 +548,34 @@ async function runIdentity(ctx: EmailCliContext) {
|
|
|
545
548
|
out(ctx, payload, text);
|
|
546
549
|
return;
|
|
547
550
|
}
|
|
551
|
+
if (sub === "forward") {
|
|
552
|
+
// Configure where a sender's managed sequence replies are forwarded.
|
|
553
|
+
// `--to <email>` turns it on (composed from the verified sender, Reply-To =
|
|
554
|
+
// the prospect); `--off` clears it. Replies are always still captured
|
|
555
|
+
// in-app regardless — forwarding is an extra copy to a chosen inbox.
|
|
556
|
+
const identity = requiredFlag(ctx.args, "--identity");
|
|
557
|
+
const off = hasFlag(ctx.args, "--off");
|
|
558
|
+
const to = off ? "" : (getFlag(ctx.args, "--to")?.trim() ?? "");
|
|
559
|
+
if (!off && !to) {
|
|
560
|
+
throw new Error(
|
|
561
|
+
"Provide --to <email> to forward this sender's replies, or --off to turn forwarding off.",
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
const payload = (await callMutation(
|
|
565
|
+
ctx,
|
|
566
|
+
"functions/emailCampaigns:setSenderReplyForward",
|
|
567
|
+
{ identity, forwardRepliesTo: to },
|
|
568
|
+
)) as JsonRecord;
|
|
569
|
+
const forwardTo =
|
|
570
|
+
typeof payload.forwardRepliesTo === "string"
|
|
571
|
+
? payload.forwardRepliesTo
|
|
572
|
+
: null;
|
|
573
|
+
const text = forwardTo
|
|
574
|
+
? `Replies to ${identity}'s sequences will be forwarded to ${forwardTo}.`
|
|
575
|
+
: `Reply forwarding turned off for ${identity}.`;
|
|
576
|
+
out(ctx, { ok: true, ...payload }, text);
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
548
579
|
if (sub === "dns") {
|
|
549
580
|
const identity = requiredFlag(ctx.args, "--identity");
|
|
550
581
|
if (!identity.includes("@") && !identity.includes(".")) {
|
package/lib/command-registry.ts
CHANGED
|
@@ -29,6 +29,7 @@ export type CustomOperation = {
|
|
|
29
29
|
| "commandsList"
|
|
30
30
|
| "chatSpawn"
|
|
31
31
|
| "chatFollow"
|
|
32
|
+
| "cronDelete"
|
|
32
33
|
| "cronRunNow"
|
|
33
34
|
| "billingTopup"
|
|
34
35
|
| "upgrade"
|
|
@@ -1895,7 +1896,7 @@ const rawApiOperations = [
|
|
|
1895
1896
|
path: "/routines/{jobId}",
|
|
1896
1897
|
requestSchema: anyObject,
|
|
1897
1898
|
responseSchema: anyResponse,
|
|
1898
|
-
backend:
|
|
1899
|
+
backend: custom("cronDelete", "bearer"),
|
|
1899
1900
|
}),
|
|
1900
1901
|
op({
|
|
1901
1902
|
id: "cron.enable",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dench.com/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Dench agent workspace CLI. v2 unifies auth behind `dench signin`; the legacy `dench login` / `dench onboard` / `dench setup` / `dench what-can-i-do` / `dench register` commands now error with a redirect.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|