@dench.com/cli 2.3.2 → 2.4.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/crm.ts +47 -0
- package/lib/command-registry.ts +64 -11
- package/lib/enrichment-gateway.ts +11 -0
- package/package.json +1 -1
package/crm.ts
CHANGED
|
@@ -88,6 +88,7 @@ type CrmCliContext = {
|
|
|
88
88
|
* organization context.
|
|
89
89
|
*/
|
|
90
90
|
sessionToken?: string;
|
|
91
|
+
runId?: string;
|
|
91
92
|
enrichmentGateway?: Pick<EnrichmentGatewayOptions, "apiKey" | "baseUrl">;
|
|
92
93
|
};
|
|
93
94
|
|
|
@@ -296,6 +297,7 @@ async function applyBatchOpsInChunks(
|
|
|
296
297
|
const chunkKey = chunkIdempotencyKey(idempotencyKey, chunkIndex);
|
|
297
298
|
await callMutation(ctx, api.batch.apply, {
|
|
298
299
|
ops: chunk,
|
|
300
|
+
...runContextArgs(ctx),
|
|
299
301
|
...(chunkKey ? { idempotencyKey: chunkKey } : {}),
|
|
300
302
|
...(allowUnknown ? { allowUnknown: true } : {}),
|
|
301
303
|
});
|
|
@@ -303,6 +305,10 @@ async function applyBatchOpsInChunks(
|
|
|
303
305
|
return chunks.length;
|
|
304
306
|
}
|
|
305
307
|
|
|
308
|
+
function runContextArgs(ctx: CrmCliContext): Record<string, string> {
|
|
309
|
+
return ctx.runId ? { runId: ctx.runId } : {};
|
|
310
|
+
}
|
|
311
|
+
|
|
306
312
|
/**
|
|
307
313
|
* Fetch the canonical field names for an object. Best-effort: returns
|
|
308
314
|
* `null` (rather than throwing) on any failure so the caller falls back
|
|
@@ -574,6 +580,11 @@ const api = {
|
|
|
574
580
|
"functions/crm/entries:bulkDelete",
|
|
575
581
|
),
|
|
576
582
|
},
|
|
583
|
+
history: {
|
|
584
|
+
listForEntry: makeFunctionReference<"query">(
|
|
585
|
+
"functions/crm/history:listForEntry",
|
|
586
|
+
),
|
|
587
|
+
},
|
|
577
588
|
cells: {
|
|
578
589
|
get: makeFunctionReference<"query">("functions/crm/cells:get"),
|
|
579
590
|
set: makeFunctionReference<"mutation">("functions/crm/cells:set"),
|
|
@@ -641,6 +652,7 @@ export async function runCrmCommand(opts: {
|
|
|
641
652
|
args,
|
|
642
653
|
jsonOutput,
|
|
643
654
|
sessionToken: opts.sessionToken,
|
|
655
|
+
runId: process.env.DENCH_RUN_ID?.trim() || undefined,
|
|
644
656
|
enrichmentGateway: opts.enrichmentGateway,
|
|
645
657
|
};
|
|
646
658
|
const subcommand = args.shift();
|
|
@@ -657,6 +669,8 @@ export async function runCrmCommand(opts: {
|
|
|
657
669
|
return await runFieldsCommand(ctx);
|
|
658
670
|
case "entries":
|
|
659
671
|
return await runEntriesCommand(ctx);
|
|
672
|
+
case "history":
|
|
673
|
+
return await runHistoryCommand(ctx);
|
|
660
674
|
case "cells":
|
|
661
675
|
return await runCellsCommand(ctx);
|
|
662
676
|
case "query":
|
|
@@ -1335,6 +1349,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1335
1349
|
await callMutation(ctx, api.entries.create, {
|
|
1336
1350
|
objectName,
|
|
1337
1351
|
data,
|
|
1352
|
+
...runContextArgs(ctx),
|
|
1338
1353
|
...(allowUnknown ? { allowUnknown: true } : {}),
|
|
1339
1354
|
}),
|
|
1340
1355
|
);
|
|
@@ -1392,6 +1407,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1392
1407
|
objectName,
|
|
1393
1408
|
entryId: entryId as any,
|
|
1394
1409
|
data,
|
|
1410
|
+
...runContextArgs(ctx),
|
|
1395
1411
|
...(allowUnknown ? { allowUnknown: true } : {}),
|
|
1396
1412
|
}),
|
|
1397
1413
|
);
|
|
@@ -1438,6 +1454,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1438
1454
|
ctx,
|
|
1439
1455
|
await callMutation(ctx, api.entries.remove, {
|
|
1440
1456
|
entryId: entryId as any,
|
|
1457
|
+
...runContextArgs(ctx),
|
|
1441
1458
|
}),
|
|
1442
1459
|
);
|
|
1443
1460
|
return;
|
|
@@ -1452,6 +1469,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1452
1469
|
ctx,
|
|
1453
1470
|
await callMutation(ctx, api.entries.bulkDelete, {
|
|
1454
1471
|
entryIds: entryIds as any,
|
|
1472
|
+
...runContextArgs(ctx),
|
|
1455
1473
|
}),
|
|
1456
1474
|
);
|
|
1457
1475
|
return;
|
|
@@ -1461,6 +1479,27 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1461
1479
|
}
|
|
1462
1480
|
}
|
|
1463
1481
|
|
|
1482
|
+
async function runHistoryCommand(ctx: CrmCliContext): Promise<void> {
|
|
1483
|
+
const objectName = shift(ctx.args, "object name");
|
|
1484
|
+
const entryId = shift(ctx.args, "entry id");
|
|
1485
|
+
const includeSystem = hasFlag(ctx.args, "--include-system");
|
|
1486
|
+
const limit = parseInt(getFlag(ctx.args, "--limit") ?? "50", 10);
|
|
1487
|
+
const cursor = getFlag(ctx.args, "--cursor");
|
|
1488
|
+
assertNoUnknownFlags(ctx.args, "crm history");
|
|
1489
|
+
out(
|
|
1490
|
+
ctx,
|
|
1491
|
+
await callQuery(ctx, api.history.listForEntry, {
|
|
1492
|
+
objectName,
|
|
1493
|
+
entryId,
|
|
1494
|
+
includeSystem,
|
|
1495
|
+
paginationOpts: {
|
|
1496
|
+
numItems: Number.isFinite(limit) ? Math.min(Math.max(limit, 1), 100) : 50,
|
|
1497
|
+
cursor: cursor ?? null,
|
|
1498
|
+
},
|
|
1499
|
+
}),
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1464
1503
|
async function runCellsCommand(ctx: CrmCliContext): Promise<void> {
|
|
1465
1504
|
const verb = ctx.args.shift();
|
|
1466
1505
|
switch (verb) {
|
|
@@ -1492,6 +1531,7 @@ async function runCellsCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1492
1531
|
entryId: entryId as any,
|
|
1493
1532
|
fieldName,
|
|
1494
1533
|
value,
|
|
1534
|
+
...runContextArgs(ctx),
|
|
1495
1535
|
}),
|
|
1496
1536
|
);
|
|
1497
1537
|
return;
|
|
@@ -1538,6 +1578,7 @@ async function runCellsCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1538
1578
|
entryId: entryId as any,
|
|
1539
1579
|
fieldName,
|
|
1540
1580
|
value,
|
|
1581
|
+
...runContextArgs(ctx),
|
|
1541
1582
|
}),
|
|
1542
1583
|
);
|
|
1543
1584
|
return;
|
|
@@ -1664,6 +1705,7 @@ async function runBatchCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1664
1705
|
ctx,
|
|
1665
1706
|
await callMutation(ctx, api.batch.apply, {
|
|
1666
1707
|
ops: ops as any,
|
|
1708
|
+
...runContextArgs(ctx),
|
|
1667
1709
|
...(idempotencyKey ? { idempotencyKey } : {}),
|
|
1668
1710
|
} as any),
|
|
1669
1711
|
);
|
|
@@ -1804,6 +1846,7 @@ async function runTransactionCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1804
1846
|
ctx,
|
|
1805
1847
|
await callMutation(ctx, api.transaction.commit, {
|
|
1806
1848
|
txnId: txnId as any,
|
|
1849
|
+
...runContextArgs(ctx),
|
|
1807
1850
|
}),
|
|
1808
1851
|
);
|
|
1809
1852
|
return;
|
|
@@ -1859,6 +1902,7 @@ async function runTransactionCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1859
1902
|
ctx,
|
|
1860
1903
|
await callMutation(ctx, api.transaction.commit, {
|
|
1861
1904
|
txnId: begun.txnId as any,
|
|
1905
|
+
...runContextArgs(ctx),
|
|
1862
1906
|
}),
|
|
1863
1907
|
);
|
|
1864
1908
|
} else {
|
|
@@ -2637,6 +2681,7 @@ async function runPeopleCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
2637
2681
|
await callMutation(ctx, api.entries.create, {
|
|
2638
2682
|
objectName: "people",
|
|
2639
2683
|
data,
|
|
2684
|
+
...runContextArgs(ctx),
|
|
2640
2685
|
}),
|
|
2641
2686
|
);
|
|
2642
2687
|
return;
|
|
@@ -2701,6 +2746,7 @@ async function runCompaniesCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
2701
2746
|
await callMutation(ctx, api.entries.create, {
|
|
2702
2747
|
objectName: "company",
|
|
2703
2748
|
data,
|
|
2749
|
+
...runContextArgs(ctx),
|
|
2704
2750
|
}),
|
|
2705
2751
|
);
|
|
2706
2752
|
return;
|
|
@@ -2895,6 +2941,7 @@ Fields (columns):
|
|
|
2895
2941
|
Entries (rows):
|
|
2896
2942
|
dench crm entries list <object> [--limit N] [--with-meta] [--json]
|
|
2897
2943
|
dench crm entries get <object> <entryId>
|
|
2944
|
+
dench crm history <object> <entryId> [--include-system] [--limit N] [--cursor CURSOR] [--json]
|
|
2898
2945
|
dench crm entries create <object> --data '{"Field":"Value",...}' (alias: --fields) [--allow-unknown]
|
|
2899
2946
|
dench crm entries create-many <object> --data '[{"Field":"Value",...}]' [--file rows.json] [--idempotency-key <key>] [--allow-unknown]
|
|
2900
2947
|
dench crm entries update <object> <entryId> --data '{...}' (alias: --fields) [--allow-unknown]
|
package/lib/command-registry.ts
CHANGED
|
@@ -716,6 +716,37 @@ const rawApiOperations = [
|
|
|
716
716
|
responseSchema: anyResponse,
|
|
717
717
|
backend: convex("query", "functions/crm/entries:get"),
|
|
718
718
|
}),
|
|
719
|
+
op({
|
|
720
|
+
id: "crm.entries.history",
|
|
721
|
+
group: "crm",
|
|
722
|
+
summary: "List a CRM entry's audit history.",
|
|
723
|
+
cli: "dench crm history",
|
|
724
|
+
method: "GET",
|
|
725
|
+
path: "/crm/objects/{objectName}/entries/{entryId}/history",
|
|
726
|
+
requestSchema: noBody,
|
|
727
|
+
responseSchema: anyResponse,
|
|
728
|
+
backend: {
|
|
729
|
+
...convex("query", "functions/crm/history:listForEntry"),
|
|
730
|
+
transformArgs: (input) => {
|
|
731
|
+
const limit =
|
|
732
|
+
typeof input.limit === "number"
|
|
733
|
+
? Math.min(Math.max(Math.floor(input.limit), 1), 100)
|
|
734
|
+
: 50;
|
|
735
|
+
return {
|
|
736
|
+
objectName: input.objectName,
|
|
737
|
+
entryId: input.entryId,
|
|
738
|
+
includeSystem: input.includeSystem === true,
|
|
739
|
+
paginationOpts: {
|
|
740
|
+
numItems: limit,
|
|
741
|
+
cursor:
|
|
742
|
+
typeof input.cursor === "string" && input.cursor.length > 0
|
|
743
|
+
? input.cursor
|
|
744
|
+
: null,
|
|
745
|
+
},
|
|
746
|
+
};
|
|
747
|
+
},
|
|
748
|
+
},
|
|
749
|
+
}),
|
|
719
750
|
op({
|
|
720
751
|
id: "crm.entries.create",
|
|
721
752
|
group: "crm",
|
|
@@ -725,7 +756,9 @@ const rawApiOperations = [
|
|
|
725
756
|
path: "/crm/objects/{objectName}/entries",
|
|
726
757
|
requestSchema: anyObject,
|
|
727
758
|
responseSchema: anyResponse,
|
|
728
|
-
backend: convex("mutation", "functions/crm/entries:create"
|
|
759
|
+
backend: convex("mutation", "functions/crm/entries:create", "bearer", {
|
|
760
|
+
includeRunId: true,
|
|
761
|
+
}),
|
|
729
762
|
}),
|
|
730
763
|
op({
|
|
731
764
|
id: "crm.entries.createMany",
|
|
@@ -736,7 +769,9 @@ const rawApiOperations = [
|
|
|
736
769
|
path: "/crm/objects/{objectName}/entries/batch",
|
|
737
770
|
requestSchema: anyObject,
|
|
738
771
|
responseSchema: anyResponse,
|
|
739
|
-
backend: convex("mutation", "functions/crm/entries:createMany"
|
|
772
|
+
backend: convex("mutation", "functions/crm/entries:createMany", "bearer", {
|
|
773
|
+
includeRunId: true,
|
|
774
|
+
}),
|
|
740
775
|
}),
|
|
741
776
|
op({
|
|
742
777
|
id: "crm.entries.update",
|
|
@@ -747,7 +782,9 @@ const rawApiOperations = [
|
|
|
747
782
|
path: "/crm/objects/{objectName}/entries/{entryId}",
|
|
748
783
|
requestSchema: anyObject,
|
|
749
784
|
responseSchema: anyResponse,
|
|
750
|
-
backend: convex("mutation", "functions/crm/entries:update"
|
|
785
|
+
backend: convex("mutation", "functions/crm/entries:update", "bearer", {
|
|
786
|
+
includeRunId: true,
|
|
787
|
+
}),
|
|
751
788
|
}),
|
|
752
789
|
op({
|
|
753
790
|
id: "crm.entries.updateMany",
|
|
@@ -758,7 +795,9 @@ const rawApiOperations = [
|
|
|
758
795
|
path: "/crm/objects/{objectName}/entries/batch",
|
|
759
796
|
requestSchema: anyObject,
|
|
760
797
|
responseSchema: anyResponse,
|
|
761
|
-
backend: convex("mutation", "functions/crm/batch:apply"
|
|
798
|
+
backend: convex("mutation", "functions/crm/batch:apply", "bearer", {
|
|
799
|
+
includeRunId: true,
|
|
800
|
+
}),
|
|
762
801
|
}),
|
|
763
802
|
op({
|
|
764
803
|
id: "crm.entries.delete",
|
|
@@ -769,7 +808,9 @@ const rawApiOperations = [
|
|
|
769
808
|
path: "/crm/objects/{objectName}/entries/{entryId}",
|
|
770
809
|
requestSchema: anyObject,
|
|
771
810
|
responseSchema: anyResponse,
|
|
772
|
-
backend: convex("mutation", "functions/crm/entries:remove"
|
|
811
|
+
backend: convex("mutation", "functions/crm/entries:remove", "bearer", {
|
|
812
|
+
includeRunId: true,
|
|
813
|
+
}),
|
|
773
814
|
}),
|
|
774
815
|
op({
|
|
775
816
|
id: "crm.entries.bulkDelete",
|
|
@@ -780,7 +821,9 @@ const rawApiOperations = [
|
|
|
780
821
|
path: "/crm/objects/{objectName}/entries/delete",
|
|
781
822
|
requestSchema: anyObject,
|
|
782
823
|
responseSchema: anyResponse,
|
|
783
|
-
backend: convex("mutation", "functions/crm/entries:bulkDelete"
|
|
824
|
+
backend: convex("mutation", "functions/crm/entries:bulkDelete", "bearer", {
|
|
825
|
+
includeRunId: true,
|
|
826
|
+
}),
|
|
784
827
|
}),
|
|
785
828
|
|
|
786
829
|
op({
|
|
@@ -803,7 +846,9 @@ const rawApiOperations = [
|
|
|
803
846
|
path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}",
|
|
804
847
|
requestSchema: anyObject,
|
|
805
848
|
responseSchema: anyResponse,
|
|
806
|
-
backend: convex("mutation", "functions/crm/cells:set"
|
|
849
|
+
backend: convex("mutation", "functions/crm/cells:set", "bearer", {
|
|
850
|
+
includeRunId: true,
|
|
851
|
+
}),
|
|
807
852
|
}),
|
|
808
853
|
op({
|
|
809
854
|
id: "crm.cells.setMany",
|
|
@@ -814,7 +859,9 @@ const rawApiOperations = [
|
|
|
814
859
|
path: "/crm/cells/batch",
|
|
815
860
|
requestSchema: anyObject,
|
|
816
861
|
responseSchema: anyResponse,
|
|
817
|
-
backend: convex("mutation", "functions/crm/cells:setMany"
|
|
862
|
+
backend: convex("mutation", "functions/crm/cells:setMany", "bearer", {
|
|
863
|
+
includeRunId: true,
|
|
864
|
+
}),
|
|
818
865
|
}),
|
|
819
866
|
op({
|
|
820
867
|
id: "crm.cells.append",
|
|
@@ -825,7 +872,9 @@ const rawApiOperations = [
|
|
|
825
872
|
path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}/append",
|
|
826
873
|
requestSchema: anyObject,
|
|
827
874
|
responseSchema: anyResponse,
|
|
828
|
-
backend: convex("mutation", "functions/crm/cells:append"
|
|
875
|
+
backend: convex("mutation", "functions/crm/cells:append", "bearer", {
|
|
876
|
+
includeRunId: true,
|
|
877
|
+
}),
|
|
829
878
|
}),
|
|
830
879
|
|
|
831
880
|
op({
|
|
@@ -903,7 +952,9 @@ const rawApiOperations = [
|
|
|
903
952
|
path: "/crm/batch",
|
|
904
953
|
requestSchema: anyObject,
|
|
905
954
|
responseSchema: anyResponse,
|
|
906
|
-
backend: convex("mutation", "functions/crm/batch:apply"
|
|
955
|
+
backend: convex("mutation", "functions/crm/batch:apply", "bearer", {
|
|
956
|
+
includeRunId: true,
|
|
957
|
+
}),
|
|
907
958
|
}),
|
|
908
959
|
op({
|
|
909
960
|
id: "crm.transaction.begin",
|
|
@@ -936,7 +987,9 @@ const rawApiOperations = [
|
|
|
936
987
|
path: "/crm/transactions/{txnId}/commit",
|
|
937
988
|
requestSchema: anyObject,
|
|
938
989
|
responseSchema: anyResponse,
|
|
939
|
-
backend: convex("mutation", "functions/crm/transaction:commit"
|
|
990
|
+
backend: convex("mutation", "functions/crm/transaction:commit", "bearer", {
|
|
991
|
+
includeRunId: true,
|
|
992
|
+
}),
|
|
940
993
|
}),
|
|
941
994
|
op({
|
|
942
995
|
id: "crm.transaction.abort",
|
|
@@ -1325,6 +1325,17 @@ async function buildGatewayError(
|
|
|
1325
1325
|
{ status: response.status, code },
|
|
1326
1326
|
);
|
|
1327
1327
|
}
|
|
1328
|
+
if (
|
|
1329
|
+
response.status === 402 ||
|
|
1330
|
+
code === "on_demand_disabled" ||
|
|
1331
|
+
code === "insufficient_credits" ||
|
|
1332
|
+
code === "spend_limit_reached"
|
|
1333
|
+
) {
|
|
1334
|
+
return new EnrichmentGatewayError(
|
|
1335
|
+
upstreamMessage ?? "AI credits exhausted.",
|
|
1336
|
+
{ status: response.status, code },
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1328
1339
|
|
|
1329
1340
|
const detail = upstreamMessage || rawText || response.statusText;
|
|
1330
1341
|
const truncated = detail.length > 500 ? `${detail.slice(0, 500)}...` : detail;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dench.com/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.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": {
|