@dench.com/cli 2.1.0 → 2.1.1
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 +82 -37
- package/lib/enrichment-gateway.ts +22 -0
- package/package.json +1 -1
package/crm.ts
CHANGED
|
@@ -94,6 +94,32 @@ type CrmCliContext = {
|
|
|
94
94
|
// don't need to change their try/catch shape.
|
|
95
95
|
class CrmCliError extends Error {}
|
|
96
96
|
|
|
97
|
+
function userFacingConvexErrorMessage(error: unknown): string | null {
|
|
98
|
+
if (!error || typeof error !== "object") return null;
|
|
99
|
+
const data = (error as { data?: unknown }).data;
|
|
100
|
+
if (typeof data === "string" && data.trim().length > 0) {
|
|
101
|
+
return data.trim();
|
|
102
|
+
}
|
|
103
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
104
|
+
const record = data as Record<string, unknown>;
|
|
105
|
+
for (const key of ["message", "error", "reason"]) {
|
|
106
|
+
const value = record[key];
|
|
107
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
108
|
+
return value.trim();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function normalizeRpcError(error: unknown): Error {
|
|
116
|
+
if (error instanceof CrmCliError) return error;
|
|
117
|
+
return new CrmCliError(
|
|
118
|
+
userFacingConvexErrorMessage(error) ??
|
|
119
|
+
(error instanceof Error ? error.message : String(error)),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
97
123
|
function shift(args: string[], expected: string): string {
|
|
98
124
|
try {
|
|
99
125
|
return shiftRaw(args, expected);
|
|
@@ -279,10 +305,14 @@ async function callQuery(
|
|
|
279
305
|
fn: Parameters<ConvexHttpClient["query"]>[0],
|
|
280
306
|
args: Record<string, unknown> = {},
|
|
281
307
|
): Promise<unknown> {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
308
|
+
try {
|
|
309
|
+
return await ctx.convex.query(fn, {
|
|
310
|
+
...args,
|
|
311
|
+
...(ctx.sessionToken ? { sessionToken: ctx.sessionToken } : {}),
|
|
312
|
+
} as never);
|
|
313
|
+
} catch (error) {
|
|
314
|
+
throw normalizeRpcError(error);
|
|
315
|
+
}
|
|
286
316
|
}
|
|
287
317
|
|
|
288
318
|
async function callMutation(
|
|
@@ -290,10 +320,14 @@ async function callMutation(
|
|
|
290
320
|
fn: Parameters<ConvexHttpClient["mutation"]>[0],
|
|
291
321
|
args: Record<string, unknown> = {},
|
|
292
322
|
): Promise<unknown> {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
323
|
+
try {
|
|
324
|
+
return await ctx.convex.mutation(fn, {
|
|
325
|
+
...args,
|
|
326
|
+
...(ctx.sessionToken ? { sessionToken: ctx.sessionToken } : {}),
|
|
327
|
+
} as never);
|
|
328
|
+
} catch (error) {
|
|
329
|
+
throw normalizeRpcError(error);
|
|
330
|
+
}
|
|
297
331
|
}
|
|
298
332
|
|
|
299
333
|
function out(ctx: CrmCliContext, value: unknown): void {
|
|
@@ -743,7 +777,9 @@ async function runFieldsCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
743
777
|
const color = getFlag(ctx.args, "--color");
|
|
744
778
|
const positionStr = getFlag(ctx.args, "--position");
|
|
745
779
|
const position =
|
|
746
|
-
positionStr !== undefined
|
|
780
|
+
positionStr !== undefined
|
|
781
|
+
? Number.parseInt(positionStr, 10)
|
|
782
|
+
: undefined;
|
|
747
783
|
if (position !== undefined && !Number.isFinite(position)) {
|
|
748
784
|
throw new CrmCliError(
|
|
749
785
|
`--position must be an integer, got "${positionStr}"`,
|
|
@@ -1902,14 +1938,22 @@ async function callEnrichmentGatewayForEntry(args: {
|
|
|
1902
1938
|
|
|
1903
1939
|
const PEOPLE_FULL_NAME_FIELDS = ["Name", "Full Name", "Person Name"] as const;
|
|
1904
1940
|
const PEOPLE_FIRST_NAME_FIELDS = ["First Name", "Given Name"] as const;
|
|
1905
|
-
const PEOPLE_LAST_NAME_FIELDS = [
|
|
1941
|
+
const PEOPLE_LAST_NAME_FIELDS = [
|
|
1942
|
+
"Last Name",
|
|
1943
|
+
"Family Name",
|
|
1944
|
+
"Surname",
|
|
1945
|
+
] as const;
|
|
1906
1946
|
const PEOPLE_EMAIL_FIELDS = [
|
|
1907
1947
|
"Email",
|
|
1908
1948
|
"Email Address",
|
|
1909
1949
|
"Work Email",
|
|
1910
1950
|
"Personal Email",
|
|
1911
1951
|
] as const;
|
|
1912
|
-
const PEOPLE_LINKEDIN_FIELDS = [
|
|
1952
|
+
const PEOPLE_LINKEDIN_FIELDS = [
|
|
1953
|
+
"LinkedIn URL",
|
|
1954
|
+
"LinkedIn",
|
|
1955
|
+
"Linkedin URL",
|
|
1956
|
+
] as const;
|
|
1913
1957
|
const PEOPLE_DOMAIN_FIELDS = ["Domain", "Company Domain"] as const;
|
|
1914
1958
|
|
|
1915
1959
|
const COMPANY_WEBSITE_FIELDS = ["Website", "Domain", "URL", "Site"] as const;
|
|
@@ -2012,6 +2056,7 @@ async function enrichOneEntry(
|
|
|
2012
2056
|
entry: CrmEntryForEnrichment;
|
|
2013
2057
|
},
|
|
2014
2058
|
): Promise<Record<string, unknown>> {
|
|
2059
|
+
let value: unknown;
|
|
2015
2060
|
try {
|
|
2016
2061
|
const payload = await callEnrichmentGatewayForEntry({
|
|
2017
2062
|
target: args.target,
|
|
@@ -2019,32 +2064,7 @@ async function enrichOneEntry(
|
|
|
2019
2064
|
provider: args.provider,
|
|
2020
2065
|
gateway: ctx.enrichmentGateway,
|
|
2021
2066
|
});
|
|
2022
|
-
|
|
2023
|
-
if (value === null) {
|
|
2024
|
-
return {
|
|
2025
|
-
entryId: args.entry.id,
|
|
2026
|
-
ok: false,
|
|
2027
|
-
reason: "value_not_found",
|
|
2028
|
-
};
|
|
2029
|
-
}
|
|
2030
|
-
const writeResult = (await callMutation(
|
|
2031
|
-
ctx,
|
|
2032
|
-
api.enrich.applyCellEnrichmentResult,
|
|
2033
|
-
{
|
|
2034
|
-
objectName: args.objectName,
|
|
2035
|
-
entryId: args.entry.id,
|
|
2036
|
-
fieldName: args.fieldName,
|
|
2037
|
-
value,
|
|
2038
|
-
provider: args.provider ?? "gateway",
|
|
2039
|
-
overwrite: args.overwrite,
|
|
2040
|
-
},
|
|
2041
|
-
)) as Record<string, unknown>;
|
|
2042
|
-
return {
|
|
2043
|
-
entryId: args.entry.id,
|
|
2044
|
-
ok: writeResult.ok === true,
|
|
2045
|
-
value,
|
|
2046
|
-
...writeResult,
|
|
2047
|
-
};
|
|
2067
|
+
value = extractEnrichmentValue(payload, args.target.column);
|
|
2048
2068
|
} catch (error) {
|
|
2049
2069
|
if (
|
|
2050
2070
|
error instanceof EnrichmentGatewayError ||
|
|
@@ -2062,6 +2082,31 @@ async function enrichOneEntry(
|
|
|
2062
2082
|
}
|
|
2063
2083
|
throw error;
|
|
2064
2084
|
}
|
|
2085
|
+
if (value === null) {
|
|
2086
|
+
return {
|
|
2087
|
+
entryId: args.entry.id,
|
|
2088
|
+
ok: false,
|
|
2089
|
+
reason: "value_not_found",
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2092
|
+
const writeResult = (await callMutation(
|
|
2093
|
+
ctx,
|
|
2094
|
+
api.enrich.applyCellEnrichmentResult,
|
|
2095
|
+
{
|
|
2096
|
+
objectName: args.objectName,
|
|
2097
|
+
entryId: args.entry.id,
|
|
2098
|
+
fieldName: args.fieldName,
|
|
2099
|
+
value,
|
|
2100
|
+
provider: args.provider ?? "gateway",
|
|
2101
|
+
overwrite: args.overwrite,
|
|
2102
|
+
},
|
|
2103
|
+
)) as Record<string, unknown>;
|
|
2104
|
+
return {
|
|
2105
|
+
entryId: args.entry.id,
|
|
2106
|
+
ok: writeResult.ok === true,
|
|
2107
|
+
value,
|
|
2108
|
+
...writeResult,
|
|
2109
|
+
};
|
|
2065
2110
|
}
|
|
2066
2111
|
|
|
2067
2112
|
async function enrichCellThroughGateway(
|
|
@@ -1280,6 +1280,28 @@ async function buildGatewayError(
|
|
|
1280
1280
|
code: code ?? "not_found",
|
|
1281
1281
|
});
|
|
1282
1282
|
}
|
|
1283
|
+
if (
|
|
1284
|
+
response.status === 401 ||
|
|
1285
|
+
code === "invalid_api_key" ||
|
|
1286
|
+
code === "unauthorized"
|
|
1287
|
+
) {
|
|
1288
|
+
return new EnrichmentGatewayError(
|
|
1289
|
+
upstreamMessage ?? "Unauthorized gateway request",
|
|
1290
|
+
{ status: response.status, code: "unauthorized" },
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
if (response.status === 403 || code === "forbidden") {
|
|
1294
|
+
return new EnrichmentGatewayError(
|
|
1295
|
+
upstreamMessage ?? "Forbidden gateway request",
|
|
1296
|
+
{ status: response.status, code: "forbidden" },
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
if (code === "aviato_unauthorized") {
|
|
1300
|
+
return new EnrichmentGatewayError(
|
|
1301
|
+
upstreamMessage ?? "Aviato provider unauthorized",
|
|
1302
|
+
{ status: response.status || 401, code: "aviato_unauthorized" },
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1283
1305
|
if (response.status === 503 || code === "provider_unavailable") {
|
|
1284
1306
|
return new EnrichmentGatewayError("Gateway providers unavailable", {
|
|
1285
1307
|
status: response.status,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dench.com/cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
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": {
|