@dealdesk/server 2026.528.2 → 2026.603.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/adapters/builtin-adapter-types.d.ts.map +1 -1
- package/dist/adapters/builtin-adapter-types.js +1 -0
- package/dist/adapters/builtin-adapter-types.js.map +1 -1
- package/dist/adapters/registry.d.ts.map +1 -1
- package/dist/adapters/registry.js +19 -0
- package/dist/adapters/registry.js.map +1 -1
- package/dist/deal-desk/enrichment/__tests__/hunter-client.test.d.ts +2 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-client.test.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-client.test.js +106 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-client.test.js.map +1 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-config.test.d.ts +2 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-config.test.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-config.test.js +73 -0
- package/dist/deal-desk/enrichment/__tests__/hunter-config.test.js.map +1 -0
- package/dist/deal-desk/enrichment/__tests__/provider.test.d.ts +2 -0
- package/dist/deal-desk/enrichment/__tests__/provider.test.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/__tests__/provider.test.js +77 -0
- package/dist/deal-desk/enrichment/__tests__/provider.test.js.map +1 -0
- package/dist/deal-desk/enrichment/__tests__/resolve-contact-email.test.js +33 -0
- package/dist/deal-desk/enrichment/__tests__/resolve-contact-email.test.js.map +1 -1
- package/dist/deal-desk/enrichment/enrichment-types.d.ts +38 -0
- package/dist/deal-desk/enrichment/enrichment-types.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/enrichment-types.js +3 -0
- package/dist/deal-desk/enrichment/enrichment-types.js.map +1 -0
- package/dist/deal-desk/enrichment/hunter-client.d.ts +44 -0
- package/dist/deal-desk/enrichment/hunter-client.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/hunter-client.js +112 -0
- package/dist/deal-desk/enrichment/hunter-client.js.map +1 -0
- package/dist/deal-desk/enrichment/hunter-config.d.ts +41 -0
- package/dist/deal-desk/enrichment/hunter-config.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/hunter-config.js +58 -0
- package/dist/deal-desk/enrichment/hunter-config.js.map +1 -0
- package/dist/deal-desk/enrichment/provider.d.ts +25 -0
- package/dist/deal-desk/enrichment/provider.d.ts.map +1 -0
- package/dist/deal-desk/enrichment/provider.js +43 -0
- package/dist/deal-desk/enrichment/provider.js.map +1 -0
- package/dist/deal-desk/enrichment/resolve-contact-email.d.ts +42 -7
- package/dist/deal-desk/enrichment/resolve-contact-email.d.ts.map +1 -1
- package/dist/deal-desk/enrichment/resolve-contact-email.js +120 -51
- package/dist/deal-desk/enrichment/resolve-contact-email.js.map +1 -1
- package/dist/deal-desk/tools/__tests__/enrichment-preference.test.d.ts +2 -0
- package/dist/deal-desk/tools/__tests__/enrichment-preference.test.d.ts.map +1 -0
- package/dist/deal-desk/tools/__tests__/enrichment-preference.test.js +90 -0
- package/dist/deal-desk/tools/__tests__/enrichment-preference.test.js.map +1 -0
- package/dist/deal-desk/tools/__tests__/hunter-api-key.test.d.ts +2 -0
- package/dist/deal-desk/tools/__tests__/hunter-api-key.test.d.ts.map +1 -0
- package/dist/deal-desk/tools/__tests__/hunter-api-key.test.js +101 -0
- package/dist/deal-desk/tools/__tests__/hunter-api-key.test.js.map +1 -0
- package/dist/deal-desk/tools/enrich-contact.d.ts +5 -2
- package/dist/deal-desk/tools/enrich-contact.d.ts.map +1 -1
- package/dist/deal-desk/tools/enrich-contact.js +26 -24
- package/dist/deal-desk/tools/enrich-contact.js.map +1 -1
- package/dist/deal-desk/tools/enrichment-preference.d.ts +8 -0
- package/dist/deal-desk/tools/enrichment-preference.d.ts.map +1 -0
- package/dist/deal-desk/tools/enrichment-preference.js +41 -0
- package/dist/deal-desk/tools/enrichment-preference.js.map +1 -0
- package/dist/deal-desk/tools/hunter-api-key.d.ts +11 -0
- package/dist/deal-desk/tools/hunter-api-key.d.ts.map +1 -0
- package/dist/deal-desk/tools/hunter-api-key.js +67 -0
- package/dist/deal-desk/tools/hunter-api-key.js.map +1 -0
- package/dist/deal-desk/tools/index.d.ts.map +1 -1
- package/dist/deal-desk/tools/index.js +42 -11
- package/dist/deal-desk/tools/index.js.map +1 -1
- package/dist/deal-desk/tools/outreach-approve.d.ts +4 -0
- package/dist/deal-desk/tools/outreach-approve.d.ts.map +1 -1
- package/dist/deal-desk/tools/outreach-approve.js +7 -8
- package/dist/deal-desk/tools/outreach-approve.js.map +1 -1
- package/dist/deal-desk/tools/outreach-draft.d.ts +4 -0
- package/dist/deal-desk/tools/outreach-draft.d.ts.map +1 -1
- package/dist/deal-desk/tools/outreach-draft.js +8 -6
- package/dist/deal-desk/tools/outreach-draft.js.map +1 -1
- package/package.json +15 -14
- package/ui-dist/assets/{_basePickBy-CaQZTZgE.js → _basePickBy-CBVIeEkV.js} +1 -1
- package/ui-dist/assets/{_baseUniq-DvA-iyvx.js → _baseUniq-BcwaQnkH.js} +1 -1
- package/ui-dist/assets/{arc-_uwl-PL9.js → arc-DqmTiJ9l.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-VXUJARFQ-hoEr3qym.js → architectureDiagram-VXUJARFQ-C2PZuz_4.js} +1 -1
- package/ui-dist/assets/{blockDiagram-VD42YOAC-BpNmbQ9P.js → blockDiagram-VD42YOAC-CHzu2Ctw.js} +1 -1
- package/ui-dist/assets/{c4Diagram-YG6GDRKO-BG14x8dM.js → c4Diagram-YG6GDRKO-DLvbjDP5.js} +1 -1
- package/ui-dist/assets/channel-HcwSzs_N.js +1 -0
- package/ui-dist/assets/{chunk-4BX2VUAB-Cb1YcG81.js → chunk-4BX2VUAB-D4IgQx7K.js} +1 -1
- package/ui-dist/assets/{chunk-55IACEB6-DkMTjrQj.js → chunk-55IACEB6-BH1i5XQo.js} +1 -1
- package/ui-dist/assets/{chunk-B4BG7PRW-BD6QmYfE.js → chunk-B4BG7PRW-CuPShkE9.js} +1 -1
- package/ui-dist/assets/{chunk-DI55MBZ5-B_xkiL3H.js → chunk-DI55MBZ5-Bi_J3Z0D.js} +1 -1
- package/ui-dist/assets/{chunk-FMBD7UC4-DC95tjc1.js → chunk-FMBD7UC4-BwRwTbFX.js} +1 -1
- package/ui-dist/assets/{chunk-QN33PNHL-BkIJ2KXA.js → chunk-QN33PNHL-BN35apwc.js} +1 -1
- package/ui-dist/assets/{chunk-QZHKN3VN-BWUNV7If.js → chunk-QZHKN3VN-COm56_LM.js} +1 -1
- package/ui-dist/assets/{chunk-TZMSLE5B-NQYnSIs1.js → chunk-TZMSLE5B-Xj2KL_0Y.js} +1 -1
- package/ui-dist/assets/classDiagram-2ON5EDUG-B07Ltkzj.js +1 -0
- package/ui-dist/assets/classDiagram-v2-WZHVMYZB-B07Ltkzj.js +1 -0
- package/ui-dist/assets/clone-B7h-gniq.js +1 -0
- package/ui-dist/assets/{cose-bilkent-S5V4N54A-BHo6DkZj.js → cose-bilkent-S5V4N54A-FLFC6_gO.js} +1 -1
- package/ui-dist/assets/{dagre-6UL2VRFP-CfzNlqfr.js → dagre-6UL2VRFP-0d32lGTp.js} +1 -1
- package/ui-dist/assets/{diagram-PSM6KHXK-DjPk4Vl5.js → diagram-PSM6KHXK-CDNGXG5P.js} +1 -1
- package/ui-dist/assets/{diagram-QEK2KX5R-ClmlUcpT.js → diagram-QEK2KX5R-C0vaPlrd.js} +1 -1
- package/ui-dist/assets/{diagram-S2PKOQOG-B68LEXtz.js → diagram-S2PKOQOG-UxrlUeu-.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q2GNP2WA-CJSnga5T.js → erDiagram-Q2GNP2WA-FL0kguuL.js} +1 -1
- package/ui-dist/assets/{flowDiagram-NV44I4VS-Drmp4DHd.js → flowDiagram-NV44I4VS-DnEzeK5O.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-JELNMOA3-C8ffQ-2u.js → ganttDiagram-JELNMOA3-f03KncDX.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-V2S2FVAM-CPjF6oPQ.js → gitGraphDiagram-V2S2FVAM-y4Oi65_k.js} +1 -1
- package/ui-dist/assets/{graph-B2qUgzgo.js → graph-CFWov-m4.js} +1 -1
- package/ui-dist/assets/{index-FnWH4Q9P.js → index-B-BAVU8b.js} +1 -1
- package/ui-dist/assets/{index-DY03uqeZ.js → index-Bd7zw6ip.js} +1 -1
- package/ui-dist/assets/{index-CtebvrC7.js → index-BmqFzV8-.js} +1 -1
- package/ui-dist/assets/{index-BJ9IksfS.js → index-Btdsi4zo.js} +1 -1
- package/ui-dist/assets/{index-CPGHpqpR.js → index-By5eCrIU.js} +1 -1
- package/ui-dist/assets/{index-CNEquZvK.js → index-C5zqtXrw.js} +1 -1
- package/ui-dist/assets/{index-DWfkKcGS.js → index-CFI3SAZE.js} +1 -1
- package/ui-dist/assets/{index-Cf8smU9e.js → index-CTJ29Xh5.js} +1 -1
- package/ui-dist/assets/{index-CrrVEpWP.js → index-CU0mrwVT.js} +156 -156
- package/ui-dist/assets/{index-BAhZurej.js → index-CV_d1E37.js} +1 -1
- package/ui-dist/assets/{index-DnDdXZYl.js → index-CddqJ4G5.js} +1 -1
- package/ui-dist/assets/{index-DvRp33UU.js → index-CgGLDqng.js} +1 -1
- package/ui-dist/assets/{index-BT7YS1Ir.js → index-CyvVv96c.js} +1 -1
- package/ui-dist/assets/{index-ARl1W2jj.js → index-D4ouuOrO.js} +1 -1
- package/ui-dist/assets/{index-DXzbokce.js → index-DCn3d1Sw.js} +1 -1
- package/ui-dist/assets/{index-CuwS3-lF.js → index-DWAFlBdn.js} +1 -1
- package/ui-dist/assets/{index-D1D5GrGc.js → index-DqYJhcon.js} +1 -1
- package/ui-dist/assets/{index-6t3ZNnLR.js → index-Dwv7AqVT.js} +1 -1
- package/ui-dist/assets/{index-Bkj-OIiI.js → index-DydmEOe-.js} +1 -1
- package/ui-dist/assets/{index-BKv2WUK1.js → index-FhdjGuIa.js} +1 -1
- package/ui-dist/assets/{index-CW2NmfmI.js → index-RDsxbDSf.js} +1 -1
- package/ui-dist/assets/{index-O_WP0QsK.js → index-ScEFFiXG.js} +1 -1
- package/ui-dist/assets/{index-B9T1xuwJ.js → index-swVBgd_3.js} +1 -1
- package/ui-dist/assets/{infoDiagram-HS3SLOUP-DLOW6p4c.js → infoDiagram-HS3SLOUP-BT8yT7sJ.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-XKPGCS4Q-oYaaSMQP.js → journeyDiagram-XKPGCS4Q-C8DG43aT.js} +1 -1
- package/ui-dist/assets/{kanban-definition-3W4ZIXB7-BE7mgk6q.js → kanban-definition-3W4ZIXB7-BbShlSAl.js} +1 -1
- package/ui-dist/assets/{layout-Cq5BDWzM.js → layout-CCS2XC8t.js} +1 -1
- package/ui-dist/assets/{linear-HnEHTC6F.js → linear-2TvgGQfb.js} +1 -1
- package/ui-dist/assets/{mermaid.core-JMROPF3S.js → mermaid.core-BAFI4dXm.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-VGOIOE7T-DoeZEBQU.js → mindmap-definition-VGOIOE7T-BcHv1Ud7.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ADFJNKIX-BtfKQ-xw.js → pieDiagram-ADFJNKIX-CNO1-Z0g.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-AYHSOK5B-CIrjVDBB.js → quadrantDiagram-AYHSOK5B-DfE50a-U.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-UZGBJVZJ-CNQ5h-EW.js → requirementDiagram-UZGBJVZJ-CgcgBiHz.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-TZEHDZUN-CrOSPDz5.js → sankeyDiagram-TZEHDZUN-BqpKVSYn.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-WL72ISMW-D96XuK7n.js → sequenceDiagram-WL72ISMW-Vbv-XA05.js} +1 -1
- package/ui-dist/assets/{stateDiagram-FKZM4ZOC-BOf9izkD.js → stateDiagram-FKZM4ZOC-C1GZ_hr8.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-D4JPxYX0.js +1 -0
- package/ui-dist/assets/{timeline-definition-IT6M3QCI-_lAaYcUI.js → timeline-definition-IT6M3QCI-Gcr-dBCd.js} +1 -1
- package/ui-dist/assets/{treemap-GDKQZRPO-BS18z8ox.js → treemap-GDKQZRPO-B_zJkapD.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-PRI3JC2R-X82nn6D0.js → xychartDiagram-PRI3JC2R-jk1Yj15T.js} +1 -1
- package/ui-dist/index.html +7 -6
- package/ui-dist/assets/channel-NmuAvKfd.js +0 -1
- package/ui-dist/assets/classDiagram-2ON5EDUG-eS4kRH8R.js +0 -1
- package/ui-dist/assets/classDiagram-v2-WZHVMYZB-eS4kRH8R.js +0 -1
- package/ui-dist/assets/clone-CbA0swX6.js +0 -1
- package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-DEhq019K.js +0 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EmailStatus } from "./enrichment-types.js";
|
|
2
|
+
export type HunterErrorCode = "hunter_auth_failed" | "hunter_rate_limited" | "hunter_pii_restricted" | "hunter_unknown";
|
|
3
|
+
export declare class HunterApiError extends Error {
|
|
4
|
+
readonly status: number;
|
|
5
|
+
readonly code: HunterErrorCode;
|
|
6
|
+
readonly rawBody: string;
|
|
7
|
+
constructor(status: number, rawBody: string);
|
|
8
|
+
}
|
|
9
|
+
export interface HunterFindInput {
|
|
10
|
+
firstName: string;
|
|
11
|
+
lastName: string;
|
|
12
|
+
companyDomain: string;
|
|
13
|
+
apiKey: string;
|
|
14
|
+
}
|
|
15
|
+
export interface HunterFindResult {
|
|
16
|
+
email: string | null;
|
|
17
|
+
emailStatus: EmailStatus | null;
|
|
18
|
+
score: number | null;
|
|
19
|
+
}
|
|
20
|
+
export declare function hunterFindEmail(input: HunterFindInput): Promise<HunterFindResult>;
|
|
21
|
+
export interface ResolveHunterEmailInput {
|
|
22
|
+
firstName: string;
|
|
23
|
+
lastName: string;
|
|
24
|
+
companyDomain: string;
|
|
25
|
+
/** Accepted for signature-compatibility with the Apollo resolver; Hunter ignores it. */
|
|
26
|
+
title?: string;
|
|
27
|
+
apiKey: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ResolveHunterEmailResult {
|
|
30
|
+
email: string | null;
|
|
31
|
+
emailStatus: EmailStatus | null;
|
|
32
|
+
}
|
|
33
|
+
/** Apollo-resolver-compatible entry point used by the shared orchestration. */
|
|
34
|
+
export declare function resolveHunterEmail(input: ResolveHunterEmailInput): Promise<ResolveHunterEmailResult>;
|
|
35
|
+
export interface HunterKeyCapabilities {
|
|
36
|
+
valid: boolean;
|
|
37
|
+
planName: string | null;
|
|
38
|
+
searchesUsed: number | null;
|
|
39
|
+
searchesAvailable: number | null;
|
|
40
|
+
lastValidatedAt: string;
|
|
41
|
+
}
|
|
42
|
+
/** Validate a key and read plan/search-credit info via GET /v2/account. */
|
|
43
|
+
export declare function probeHunterKeyCapabilities(apiKey: string): Promise<HunterKeyCapabilities>;
|
|
44
|
+
//# sourceMappingURL=hunter-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunter-client.d.ts","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/hunter-client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,MAAM,MAAM,eAAe,GACvB,oBAAoB,GACpB,qBAAqB,GACrB,uBAAuB,GACvB,gBAAgB,CAAC;AAsBrB,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAQ5C;AAsBD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8BvF;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;CACjC;AAED,+EAA+E;AAC/E,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,wBAAwB,CAAC,CAQnC;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,2EAA2E;AAC3E,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA2B/F"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const HUNTER_EMAIL_FINDER_ENDPOINT = "https://api.hunter.io/v2/email-finder";
|
|
2
|
+
const HUNTER_ACCOUNT_ENDPOINT = "https://api.hunter.io/v2/account";
|
|
3
|
+
function classifyHunterError(status) {
|
|
4
|
+
if (status === 401)
|
|
5
|
+
return "hunter_auth_failed";
|
|
6
|
+
if (status === 403 || status === 429)
|
|
7
|
+
return "hunter_rate_limited";
|
|
8
|
+
if (status === 451)
|
|
9
|
+
return "hunter_pii_restricted";
|
|
10
|
+
return "hunter_unknown";
|
|
11
|
+
}
|
|
12
|
+
function formatHunterErrorMessage(status, rawBody, code) {
|
|
13
|
+
if (code === "hunter_auth_failed") {
|
|
14
|
+
return "Hunter.io API key is invalid or unauthorized.";
|
|
15
|
+
}
|
|
16
|
+
if (code === "hunter_rate_limited") {
|
|
17
|
+
return "Hunter.io usage limit reached. Check your plan at https://hunter.io/api-keys";
|
|
18
|
+
}
|
|
19
|
+
if (code === "hunter_pii_restricted") {
|
|
20
|
+
return "Hunter.io cannot return this email for legal (PII) reasons.";
|
|
21
|
+
}
|
|
22
|
+
return `Hunter.io API failed (${status}): ${rawBody}`;
|
|
23
|
+
}
|
|
24
|
+
export class HunterApiError extends Error {
|
|
25
|
+
status;
|
|
26
|
+
code;
|
|
27
|
+
rawBody;
|
|
28
|
+
constructor(status, rawBody) {
|
|
29
|
+
const code = classifyHunterError(status);
|
|
30
|
+
super(formatHunterErrorMessage(status, rawBody, code));
|
|
31
|
+
this.name = "HunterApiError";
|
|
32
|
+
this.status = status;
|
|
33
|
+
this.code = code;
|
|
34
|
+
this.rawBody = rawBody;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function readHunterError(res) {
|
|
38
|
+
let body = "";
|
|
39
|
+
try {
|
|
40
|
+
body = await res.text();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
body = "";
|
|
44
|
+
}
|
|
45
|
+
throw new HunterApiError(res.status, body);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Map Hunter's verification.status to DealDesk's normalized EmailStatus.
|
|
49
|
+
* Hunter statuses: valid | invalid | accept_all | webmail | disposable | unknown.
|
|
50
|
+
*/
|
|
51
|
+
function normalizeHunterStatus(raw) {
|
|
52
|
+
if (raw === "valid")
|
|
53
|
+
return "verified";
|
|
54
|
+
if (raw === "invalid")
|
|
55
|
+
return "invalid";
|
|
56
|
+
return "unverified";
|
|
57
|
+
}
|
|
58
|
+
export async function hunterFindEmail(input) {
|
|
59
|
+
const params = new URLSearchParams();
|
|
60
|
+
params.set("domain", input.companyDomain);
|
|
61
|
+
params.set("first_name", input.firstName);
|
|
62
|
+
params.set("last_name", input.lastName);
|
|
63
|
+
params.set("api_key", input.apiKey);
|
|
64
|
+
const res = await fetch(`${HUNTER_EMAIL_FINDER_ENDPOINT}?${params.toString()}`, {
|
|
65
|
+
method: "GET",
|
|
66
|
+
headers: { Accept: "application/json" },
|
|
67
|
+
});
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
await readHunterError(res);
|
|
70
|
+
}
|
|
71
|
+
const payload = (await res.json());
|
|
72
|
+
const data = payload.data ?? null;
|
|
73
|
+
const email = data?.email ?? null;
|
|
74
|
+
const score = typeof data?.score === "number" ? data.score : null;
|
|
75
|
+
if (!email) {
|
|
76
|
+
return { email: null, emailStatus: null, score };
|
|
77
|
+
}
|
|
78
|
+
return { email, emailStatus: normalizeHunterStatus(data?.verification?.status), score };
|
|
79
|
+
}
|
|
80
|
+
/** Apollo-resolver-compatible entry point used by the shared orchestration. */
|
|
81
|
+
export async function resolveHunterEmail(input) {
|
|
82
|
+
const found = await hunterFindEmail({
|
|
83
|
+
firstName: input.firstName,
|
|
84
|
+
lastName: input.lastName,
|
|
85
|
+
companyDomain: input.companyDomain,
|
|
86
|
+
apiKey: input.apiKey,
|
|
87
|
+
});
|
|
88
|
+
return { email: found.email, emailStatus: found.emailStatus };
|
|
89
|
+
}
|
|
90
|
+
/** Validate a key and read plan/search-credit info via GET /v2/account. */
|
|
91
|
+
export async function probeHunterKeyCapabilities(apiKey) {
|
|
92
|
+
const lastValidatedAt = new Date().toISOString();
|
|
93
|
+
const params = new URLSearchParams({ api_key: apiKey });
|
|
94
|
+
const res = await fetch(`${HUNTER_ACCOUNT_ENDPOINT}?${params.toString()}`, {
|
|
95
|
+
method: "GET",
|
|
96
|
+
headers: { Accept: "application/json" },
|
|
97
|
+
});
|
|
98
|
+
if (!res.ok) {
|
|
99
|
+
await readHunterError(res);
|
|
100
|
+
}
|
|
101
|
+
const payload = (await res.json());
|
|
102
|
+
const data = payload.data ?? null;
|
|
103
|
+
const searches = data?.requests?.searches ?? null;
|
|
104
|
+
return {
|
|
105
|
+
valid: true,
|
|
106
|
+
planName: data?.plan_name ?? null,
|
|
107
|
+
searchesUsed: typeof searches?.used === "number" ? searches.used : null,
|
|
108
|
+
searchesAvailable: typeof searches?.available === "number" ? searches.available : null,
|
|
109
|
+
lastValidatedAt,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=hunter-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunter-client.js","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/hunter-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { SecretConfigStore } from "./enrichment-types.js";
|
|
2
|
+
export declare const HUNTER_API_KEY_SECRET_KEY: "hunter.api_key";
|
|
3
|
+
export declare const HUNTER_CAPABILITIES_SECRET_KEY: "hunter.capabilities";
|
|
4
|
+
export interface HunterCapabilities {
|
|
5
|
+
/** Key authenticated against GET /v2/account. */
|
|
6
|
+
valid: boolean;
|
|
7
|
+
planName: string | null;
|
|
8
|
+
searchesUsed: number | null;
|
|
9
|
+
searchesAvailable: number | null;
|
|
10
|
+
lastValidatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
/** Re-exported for callers that prefer the provider-specific name. */
|
|
13
|
+
export type HunterConfigStore = SecretConfigStore;
|
|
14
|
+
export declare function saveHunterApiKey(args: {
|
|
15
|
+
companyId: string;
|
|
16
|
+
apiKey: string;
|
|
17
|
+
}, ctx: {
|
|
18
|
+
store: SecretConfigStore;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export declare function loadHunterApiKey(args: {
|
|
21
|
+
companyId: string;
|
|
22
|
+
}, ctx: {
|
|
23
|
+
store: SecretConfigStore;
|
|
24
|
+
}): Promise<string | null>;
|
|
25
|
+
export declare function deleteHunterApiKey(args: {
|
|
26
|
+
companyId: string;
|
|
27
|
+
}, ctx: {
|
|
28
|
+
store: SecretConfigStore;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
export declare function saveHunterCapabilities(args: {
|
|
31
|
+
companyId: string;
|
|
32
|
+
capabilities: HunterCapabilities;
|
|
33
|
+
}, ctx: {
|
|
34
|
+
store: SecretConfigStore;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
export declare function loadHunterCapabilities(args: {
|
|
37
|
+
companyId: string;
|
|
38
|
+
}, ctx: {
|
|
39
|
+
store: SecretConfigStore;
|
|
40
|
+
}): Promise<HunterCapabilities | null>;
|
|
41
|
+
//# sourceMappingURL=hunter-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunter-config.d.ts","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/hunter-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,eAAO,MAAM,yBAAyB,EAAG,gBAAyB,CAAC;AACnE,eAAO,MAAM,8BAA8B,EAAG,qBAA8B,CAAC;AAE7E,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC3C,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC3B,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC3B,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,kBAAkB,CAAA;CAAE,EAC7D,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC3B,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAUpC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const HUNTER_API_KEY_SECRET_KEY = "hunter.api_key";
|
|
2
|
+
export const HUNTER_CAPABILITIES_SECRET_KEY = "hunter.capabilities";
|
|
3
|
+
export async function saveHunterApiKey(args, ctx) {
|
|
4
|
+
const existing = await ctx.store.getByKey(args.companyId, HUNTER_API_KEY_SECRET_KEY);
|
|
5
|
+
if (existing) {
|
|
6
|
+
await ctx.store.replace(existing.id, { value: args.apiKey });
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
await ctx.store.create(args.companyId, {
|
|
10
|
+
name: "Hunter.io API Key",
|
|
11
|
+
key: HUNTER_API_KEY_SECRET_KEY,
|
|
12
|
+
value: args.apiKey,
|
|
13
|
+
description: "Hunter.io API key for contact enrichment",
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export async function loadHunterApiKey(args, ctx) {
|
|
17
|
+
const existing = await ctx.store.getByKey(args.companyId, HUNTER_API_KEY_SECRET_KEY);
|
|
18
|
+
if (!existing)
|
|
19
|
+
return null;
|
|
20
|
+
return ctx.store.load(args.companyId, existing.id);
|
|
21
|
+
}
|
|
22
|
+
export async function deleteHunterApiKey(args, ctx) {
|
|
23
|
+
const existing = await ctx.store.getByKey(args.companyId, HUNTER_API_KEY_SECRET_KEY);
|
|
24
|
+
if (existing)
|
|
25
|
+
await ctx.store.remove(existing.id);
|
|
26
|
+
const caps = await ctx.store.getByKey(args.companyId, HUNTER_CAPABILITIES_SECRET_KEY);
|
|
27
|
+
if (caps)
|
|
28
|
+
await ctx.store.remove(caps.id);
|
|
29
|
+
}
|
|
30
|
+
export async function saveHunterCapabilities(args, ctx) {
|
|
31
|
+
const payload = JSON.stringify(args.capabilities);
|
|
32
|
+
const existing = await ctx.store.getByKey(args.companyId, HUNTER_CAPABILITIES_SECRET_KEY);
|
|
33
|
+
if (existing) {
|
|
34
|
+
await ctx.store.replace(existing.id, { value: payload });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
await ctx.store.create(args.companyId, {
|
|
38
|
+
name: "Hunter.io Capabilities",
|
|
39
|
+
key: HUNTER_CAPABILITIES_SECRET_KEY,
|
|
40
|
+
value: payload,
|
|
41
|
+
description: "Validated Hunter.io API capabilities for contact enrichment",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export async function loadHunterCapabilities(args, ctx) {
|
|
45
|
+
const existing = await ctx.store.getByKey(args.companyId, HUNTER_CAPABILITIES_SECRET_KEY);
|
|
46
|
+
if (!existing)
|
|
47
|
+
return null;
|
|
48
|
+
const raw = await ctx.store.load(args.companyId, existing.id);
|
|
49
|
+
if (!raw)
|
|
50
|
+
return null;
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(raw);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=hunter-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunter-config.js","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/hunter-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { EnrichmentProvider, SecretConfigStore } from "./enrichment-types.js";
|
|
2
|
+
export declare const PREFERRED_PROVIDER_SECRET_KEY: "enrichment.preferred_provider";
|
|
3
|
+
/**
|
|
4
|
+
* Decide which provider DealDesk should use for a company.
|
|
5
|
+
* - both configured -> the preferred provider (default "apollo")
|
|
6
|
+
* - one configured -> that provider
|
|
7
|
+
* - neither -> null
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveEffectiveProvider(args: {
|
|
10
|
+
apolloConfigured: boolean;
|
|
11
|
+
hunterConfigured: boolean;
|
|
12
|
+
preferred: EnrichmentProvider | null;
|
|
13
|
+
}): EnrichmentProvider | null;
|
|
14
|
+
export declare function savePreferredProvider(args: {
|
|
15
|
+
companyId: string;
|
|
16
|
+
provider: EnrichmentProvider;
|
|
17
|
+
}, ctx: {
|
|
18
|
+
store: SecretConfigStore;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export declare function loadPreferredProvider(args: {
|
|
21
|
+
companyId: string;
|
|
22
|
+
}, ctx: {
|
|
23
|
+
store: SecretConfigStore;
|
|
24
|
+
}): Promise<EnrichmentProvider | null>;
|
|
25
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAEnF,eAAO,MAAM,6BAA6B,EAAG,+BAAwC,CAAC;AAQtF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACtC,GAAG,kBAAkB,GAAG,IAAI,CAQ5B;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,kBAAkB,CAAA;CAAE,EACzD,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC3B,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAChC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAKpC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const PREFERRED_PROVIDER_SECRET_KEY = "enrichment.preferred_provider";
|
|
2
|
+
const PROVIDERS = ["apollo", "hunter"];
|
|
3
|
+
function isEnrichmentProvider(value) {
|
|
4
|
+
return typeof value === "string" && PROVIDERS.includes(value);
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Decide which provider DealDesk should use for a company.
|
|
8
|
+
* - both configured -> the preferred provider (default "apollo")
|
|
9
|
+
* - one configured -> that provider
|
|
10
|
+
* - neither -> null
|
|
11
|
+
*/
|
|
12
|
+
export function resolveEffectiveProvider(args) {
|
|
13
|
+
const { apolloConfigured, hunterConfigured, preferred } = args;
|
|
14
|
+
if (apolloConfigured && hunterConfigured) {
|
|
15
|
+
return preferred ?? "apollo";
|
|
16
|
+
}
|
|
17
|
+
if (apolloConfigured)
|
|
18
|
+
return "apollo";
|
|
19
|
+
if (hunterConfigured)
|
|
20
|
+
return "hunter";
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
export async function savePreferredProvider(args, ctx) {
|
|
24
|
+
const existing = await ctx.store.getByKey(args.companyId, PREFERRED_PROVIDER_SECRET_KEY);
|
|
25
|
+
if (existing) {
|
|
26
|
+
await ctx.store.replace(existing.id, { value: args.provider });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
await ctx.store.create(args.companyId, {
|
|
30
|
+
name: "Preferred enrichment provider",
|
|
31
|
+
key: PREFERRED_PROVIDER_SECRET_KEY,
|
|
32
|
+
value: args.provider,
|
|
33
|
+
description: "Which contact-enrichment provider DealDesk uses when more than one is configured",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export async function loadPreferredProvider(args, ctx) {
|
|
37
|
+
const existing = await ctx.store.getByKey(args.companyId, PREFERRED_PROVIDER_SECRET_KEY);
|
|
38
|
+
if (!existing)
|
|
39
|
+
return null;
|
|
40
|
+
const raw = await ctx.store.load(args.companyId, existing.id);
|
|
41
|
+
return isEnrichmentProvider(raw) ? raw : null;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/provider.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,6BAA6B,GAAG,+BAAwC,CAAC;AAEtF,MAAM,SAAS,GAAkC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEtE,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,SAA+B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACvF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAIxC;IACC,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC/D,IAAI,gBAAgB,IAAI,gBAAgB,EAAE,CAAC;QACzC,OAAO,SAAS,IAAI,QAAQ,CAAC;IAC/B,CAAC;IACD,IAAI,gBAAgB;QAAE,OAAO,QAAQ,CAAC;IACtC,IAAI,gBAAgB;QAAE,OAAO,QAAQ,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAyD,EACzD,GAAiC;IAEjC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;IACzF,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE;QACrC,IAAI,EAAE,+BAA+B;QACrC,GAAG,EAAE,6BAA6B;QAClC,KAAK,EAAE,IAAI,CAAC,QAAQ;QACpB,WAAW,EAAE,kFAAkF;KAChG,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA2B,EAC3B,GAAiC;IAEjC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;IACzF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC9D,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { Db } from "@dealdesk/db";
|
|
2
|
-
import { resolvePersonEmail
|
|
3
|
-
|
|
2
|
+
import { resolvePersonEmail } from "./apollo-client.js";
|
|
3
|
+
import { resolveHunterEmail } from "./hunter-client.js";
|
|
4
|
+
import type { EmailStatus, EnrichmentProvider, EnrichmentSelection } from "./enrichment-types.js";
|
|
5
|
+
export type ResolveContactEmailErrorCode = "apollo_not_configured" | "contact_not_found" | "company_mismatch" | "missing_contact_fields" | "apollo_master_key_required" | "apollo_plan_blocked" | "apollo_credits_exhausted" | "apollo_lookup_failed" | "hunter_auth_failed" | "hunter_rate_limited" | "hunter_pii_restricted" | "hunter_lookup_failed" | "no_email_found";
|
|
4
6
|
export type ResolveContactEmailSuccess = {
|
|
5
7
|
ok: true;
|
|
6
8
|
email: string;
|
|
7
|
-
emailStatus:
|
|
8
|
-
source:
|
|
9
|
+
emailStatus: EmailStatus;
|
|
10
|
+
source: EnrichmentProvider;
|
|
9
11
|
apolloPersonId?: string | null;
|
|
10
12
|
contactId: string;
|
|
11
13
|
firstName: string;
|
|
@@ -18,13 +20,28 @@ export type ResolveContactEmailFailure = {
|
|
|
18
20
|
code: ResolveContactEmailErrorCode;
|
|
19
21
|
};
|
|
20
22
|
export type ResolveContactEmailResult = ResolveContactEmailSuccess | ResolveContactEmailFailure;
|
|
23
|
+
/** Resolve the effective provider + key for a company. */
|
|
24
|
+
export type LoadEnrichment = (companyId: string) => Promise<EnrichmentSelection | null>;
|
|
21
25
|
export interface ResolveContactEmailDeps {
|
|
22
26
|
db: Db;
|
|
23
27
|
companyId: string;
|
|
24
28
|
contactId: string;
|
|
25
|
-
|
|
29
|
+
/** Provider-aware loader (preferred). */
|
|
30
|
+
loadEnrichment?: LoadEnrichment;
|
|
31
|
+
/** Legacy Apollo-only loader; wrapped as the apollo provider when present. */
|
|
32
|
+
loadApolloKey?: (companyId: string) => Promise<string | null>;
|
|
26
33
|
resolvePersonEmailFn?: typeof resolvePersonEmail;
|
|
34
|
+
resolveHunterEmailFn?: typeof resolveHunterEmail;
|
|
27
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Build a provider-aware selection loader from handler deps. Prefers an explicit
|
|
38
|
+
* `loadEnrichment`; otherwise wraps a legacy Apollo-only `loadApolloKey` as the
|
|
39
|
+
* apollo provider. Returns a loader that yields null when nothing is configured.
|
|
40
|
+
*/
|
|
41
|
+
export declare function enrichmentLoaderFrom(deps: {
|
|
42
|
+
loadEnrichment?: LoadEnrichment;
|
|
43
|
+
loadApolloKey?: (companyId: string) => Promise<string | null>;
|
|
44
|
+
}): LoadEnrichment;
|
|
28
45
|
export declare function loadContactForEnrichment(db: Db, args: {
|
|
29
46
|
companyId: string;
|
|
30
47
|
contactId: string;
|
|
@@ -39,24 +56,42 @@ export declare function loadContactForEnrichment(db: Db, args: {
|
|
|
39
56
|
emailStatus: string;
|
|
40
57
|
companyDomain: string | null;
|
|
41
58
|
} | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Whether a contact needs (re)enrichment. An email is trusted as-is only when it
|
|
61
|
+
* came from a known enrichment provider and is already verified; everything else
|
|
62
|
+
* gets resolved/verified again.
|
|
63
|
+
*
|
|
64
|
+
* Name retained for backwards compatibility; covers all providers.
|
|
65
|
+
*/
|
|
42
66
|
export declare function contactNeedsApolloEnrichment(contact: {
|
|
43
67
|
email: string | null;
|
|
44
68
|
source: string | null;
|
|
45
69
|
emailStatus: string;
|
|
46
70
|
}): boolean;
|
|
71
|
+
/** Provider-agnostic alias. */
|
|
72
|
+
export declare const contactNeedsEnrichment: typeof contactNeedsApolloEnrichment;
|
|
47
73
|
export declare function resolveContactEmail(deps: ResolveContactEmailDeps): Promise<ResolveContactEmailResult>;
|
|
48
74
|
export declare function persistResolvedContactEmail(db: Db, args: {
|
|
49
75
|
contactId: string;
|
|
50
76
|
email: string;
|
|
51
|
-
emailStatus:
|
|
77
|
+
emailStatus: EmailStatus;
|
|
78
|
+
source: EnrichmentProvider;
|
|
52
79
|
enrichedByAgentId?: string | null;
|
|
53
80
|
}): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Ensure a contact has a usable email, enriching via the company's configured
|
|
83
|
+
* provider when needed. Name retained for backwards compatibility; works for
|
|
84
|
+
* any provider.
|
|
85
|
+
*/
|
|
54
86
|
export declare function ensureContactEmailFromApollo(deps: ResolveContactEmailDeps & {
|
|
55
87
|
enrichedByAgentId?: string | null;
|
|
56
88
|
}): Promise<{
|
|
57
89
|
ok: true;
|
|
58
90
|
email: string;
|
|
59
|
-
emailStatus:
|
|
91
|
+
emailStatus: EmailStatus;
|
|
92
|
+
source: EnrichmentProvider;
|
|
60
93
|
enriched: boolean;
|
|
61
94
|
} | ResolveContactEmailFailure>;
|
|
95
|
+
/** Provider-agnostic alias. */
|
|
96
|
+
export declare const ensureContactEmail: typeof ensureContactEmailFromApollo;
|
|
62
97
|
//# sourceMappingURL=resolve-contact-email.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-contact-email.d.ts","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/resolve-contact-email.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,
|
|
1
|
+
{"version":3,"file":"resolve-contact-email.d.ts","sourceRoot":"","sources":["../../../src/deal-desk/enrichment/resolve-contact-email.ts"],"names":[],"mappings":"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"}
|