linkedin-secret-sauce 0.5.0 → 0.6.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.
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Authentication modules for enrichment providers
3
+ */
4
+ export { getSmartLeadToken, getSmartLeadUser, clearSmartLeadToken, clearAllSmartLeadTokens, getSmartLeadTokenCacheStats, enableFileCache, disableFileCache, isFileCacheEnabled, clearFileCache, type SmartLeadCredentials, type SmartLeadAuthConfig, type SmartLeadUser, type SmartLeadLoginResponse, } from './smartlead-auth';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Authentication modules for enrichment providers
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.clearFileCache = exports.isFileCacheEnabled = exports.disableFileCache = exports.enableFileCache = exports.getSmartLeadTokenCacheStats = exports.clearAllSmartLeadTokens = exports.clearSmartLeadToken = exports.getSmartLeadUser = exports.getSmartLeadToken = void 0;
7
+ var smartlead_auth_1 = require("./smartlead-auth");
8
+ Object.defineProperty(exports, "getSmartLeadToken", { enumerable: true, get: function () { return smartlead_auth_1.getSmartLeadToken; } });
9
+ Object.defineProperty(exports, "getSmartLeadUser", { enumerable: true, get: function () { return smartlead_auth_1.getSmartLeadUser; } });
10
+ Object.defineProperty(exports, "clearSmartLeadToken", { enumerable: true, get: function () { return smartlead_auth_1.clearSmartLeadToken; } });
11
+ Object.defineProperty(exports, "clearAllSmartLeadTokens", { enumerable: true, get: function () { return smartlead_auth_1.clearAllSmartLeadTokens; } });
12
+ Object.defineProperty(exports, "getSmartLeadTokenCacheStats", { enumerable: true, get: function () { return smartlead_auth_1.getSmartLeadTokenCacheStats; } });
13
+ // File cache utilities for development/testing
14
+ Object.defineProperty(exports, "enableFileCache", { enumerable: true, get: function () { return smartlead_auth_1.enableFileCache; } });
15
+ Object.defineProperty(exports, "disableFileCache", { enumerable: true, get: function () { return smartlead_auth_1.disableFileCache; } });
16
+ Object.defineProperty(exports, "isFileCacheEnabled", { enumerable: true, get: function () { return smartlead_auth_1.isFileCacheEnabled; } });
17
+ Object.defineProperty(exports, "clearFileCache", { enumerable: true, get: function () { return smartlead_auth_1.clearFileCache; } });
@@ -0,0 +1,82 @@
1
+ /**
2
+ * SmartLead Authentication Client
3
+ *
4
+ * Handles JWT token acquisition via email/password login.
5
+ * Tokens are cached in-memory with automatic refresh before expiry.
6
+ *
7
+ * For development/testing, file-based caching is supported to avoid
8
+ * repeated logins during test runs. Enable via `enableFileCache()`.
9
+ */
10
+ export interface SmartLeadCredentials {
11
+ email: string;
12
+ password: string;
13
+ }
14
+ export interface SmartLeadAuthConfig {
15
+ credentials: SmartLeadCredentials;
16
+ /** Login API URL (default: https://server.smartlead.ai/api/auth/login) */
17
+ loginUrl?: string;
18
+ /** Token refresh buffer in ms - refresh this much before expiry (default: 5 min) */
19
+ refreshBufferMs?: number;
20
+ }
21
+ export interface SmartLeadUser {
22
+ id: number;
23
+ uuid: string;
24
+ email: string;
25
+ name: string;
26
+ role: string;
27
+ api_key: string;
28
+ region: string;
29
+ }
30
+ export interface SmartLeadLoginResponse {
31
+ user: SmartLeadUser;
32
+ token: string;
33
+ }
34
+ export declare function getSmartLeadToken(config: SmartLeadAuthConfig): Promise<string>;
35
+ /**
36
+ * Get SmartLead user info (from cached login)
37
+ */
38
+ export declare function getSmartLeadUser(config: SmartLeadAuthConfig): Promise<SmartLeadUser>;
39
+ /**
40
+ * Force clear cached token (e.g., on 401 error)
41
+ */
42
+ export declare function clearSmartLeadToken(email: string): void;
43
+ /**
44
+ * Clear all cached tokens
45
+ */
46
+ export declare function clearAllSmartLeadTokens(): void;
47
+ /**
48
+ * Get token cache stats (for debugging)
49
+ */
50
+ export declare function getSmartLeadTokenCacheStats(): {
51
+ cachedEmails: string[];
52
+ totalCached: number;
53
+ fileCacheEnabled: boolean;
54
+ fileCachePath: string | null;
55
+ };
56
+ /**
57
+ * Enable file-based token caching for development/testing
58
+ *
59
+ * When enabled, tokens are persisted to ~/.smartlead-tokens.json
60
+ * This avoids repeated logins during test development.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * // In your test setup
65
+ * import { enableFileCache } from 'linkedin-secret-sauce/enrichment';
66
+ *
67
+ * enableFileCache(); // Now tokens persist between test runs
68
+ * ```
69
+ */
70
+ export declare function enableFileCache(): void;
71
+ /**
72
+ * Disable file-based token caching
73
+ */
74
+ export declare function disableFileCache(): void;
75
+ /**
76
+ * Check if file cache is enabled
77
+ */
78
+ export declare function isFileCacheEnabled(): boolean;
79
+ /**
80
+ * Clear the file cache
81
+ */
82
+ export declare function clearFileCache(): void;
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ /**
3
+ * SmartLead Authentication Client
4
+ *
5
+ * Handles JWT token acquisition via email/password login.
6
+ * Tokens are cached in-memory with automatic refresh before expiry.
7
+ *
8
+ * For development/testing, file-based caching is supported to avoid
9
+ * repeated logins during test runs. Enable via `enableFileCache()`.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.getSmartLeadToken = getSmartLeadToken;
46
+ exports.getSmartLeadUser = getSmartLeadUser;
47
+ exports.clearSmartLeadToken = clearSmartLeadToken;
48
+ exports.clearAllSmartLeadTokens = clearAllSmartLeadTokens;
49
+ exports.getSmartLeadTokenCacheStats = getSmartLeadTokenCacheStats;
50
+ exports.enableFileCache = enableFileCache;
51
+ exports.disableFileCache = disableFileCache;
52
+ exports.isFileCacheEnabled = isFileCacheEnabled;
53
+ exports.clearFileCache = clearFileCache;
54
+ const fs = __importStar(require("fs"));
55
+ const path = __importStar(require("path"));
56
+ const os = __importStar(require("os"));
57
+ const DEFAULT_LOGIN_URL = 'https://server.smartlead.ai/api/auth/login';
58
+ const DEFAULT_REFRESH_BUFFER_MS = 5 * 60 * 1000; // 5 minutes
59
+ const TOKEN_LIFETIME_MS = 24 * 60 * 60 * 1000; // Assume 24h JWT lifetime (conservative)
60
+ // In-memory token cache keyed by email
61
+ const tokenCache = new Map();
62
+ /**
63
+ * Parse JWT to extract expiration time
64
+ */
65
+ function parseJwtExpiry(token) {
66
+ try {
67
+ const parts = token.split('.');
68
+ if (parts.length !== 3)
69
+ return null;
70
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString('utf8'));
71
+ if (payload.exp) {
72
+ return payload.exp * 1000; // Convert to ms
73
+ }
74
+ return null;
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ /**
81
+ * Login to SmartLead and obtain JWT token
82
+ */
83
+ async function login(config) {
84
+ const { credentials, loginUrl = DEFAULT_LOGIN_URL } = config;
85
+ const response = await fetch(loginUrl, {
86
+ method: 'POST',
87
+ headers: {
88
+ Accept: 'application/json, text/plain, */*',
89
+ 'Content-Type': 'application/json',
90
+ Origin: 'https://app.smartlead.ai',
91
+ Referer: 'https://app.smartlead.ai/',
92
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
93
+ },
94
+ body: JSON.stringify({
95
+ email: credentials.email,
96
+ password: credentials.password,
97
+ }),
98
+ });
99
+ if (!response.ok) {
100
+ const errorText = await response.text().catch(() => '');
101
+ throw new Error(`SmartLead login failed: ${response.status} - ${errorText}`);
102
+ }
103
+ const data = (await response.json());
104
+ if (!data.token || !data.user) {
105
+ throw new Error('SmartLead login response missing token or user');
106
+ }
107
+ const now = Date.now();
108
+ // Try to parse expiry from JWT, fallback to assumed lifetime
109
+ let expiresAt = parseJwtExpiry(data.token);
110
+ if (!expiresAt) {
111
+ expiresAt = now + TOKEN_LIFETIME_MS;
112
+ }
113
+ return {
114
+ token: data.token,
115
+ user: data.user,
116
+ expiresAt,
117
+ obtainedAt: now,
118
+ };
119
+ }
120
+ /**
121
+ * Check if cached token is still valid (with buffer for refresh)
122
+ */
123
+ function isTokenValid(cached, refreshBufferMs) {
124
+ const now = Date.now();
125
+ return cached.expiresAt - refreshBufferMs > now;
126
+ }
127
+ /**
128
+ * Get a valid SmartLead JWT token
129
+ *
130
+ * Returns cached token if still valid, otherwise performs fresh login.
131
+ * Thread-safe via promise deduplication.
132
+ */
133
+ const pendingLogins = new Map();
134
+ async function getSmartLeadToken(config) {
135
+ const { credentials, refreshBufferMs = DEFAULT_REFRESH_BUFFER_MS } = config;
136
+ const cacheKey = credentials.email.toLowerCase();
137
+ // Check cache first
138
+ const cached = tokenCache.get(cacheKey);
139
+ if (cached && isTokenValid(cached, refreshBufferMs)) {
140
+ return cached.token;
141
+ }
142
+ // Check if login already in progress (dedup concurrent requests)
143
+ const pending = pendingLogins.get(cacheKey);
144
+ if (pending) {
145
+ const result = await pending;
146
+ return result.token;
147
+ }
148
+ // Perform login
149
+ const loginPromise = login(config);
150
+ pendingLogins.set(cacheKey, loginPromise);
151
+ try {
152
+ const result = await loginPromise;
153
+ tokenCache.set(cacheKey, result);
154
+ return result.token;
155
+ }
156
+ finally {
157
+ pendingLogins.delete(cacheKey);
158
+ }
159
+ }
160
+ /**
161
+ * Get SmartLead user info (from cached login)
162
+ */
163
+ async function getSmartLeadUser(config) {
164
+ const { credentials, refreshBufferMs = DEFAULT_REFRESH_BUFFER_MS } = config;
165
+ const cacheKey = credentials.email.toLowerCase();
166
+ // Check cache first
167
+ const cached = tokenCache.get(cacheKey);
168
+ if (cached && isTokenValid(cached, refreshBufferMs)) {
169
+ return cached.user;
170
+ }
171
+ // Perform login to get fresh user info
172
+ await getSmartLeadToken(config);
173
+ const freshCached = tokenCache.get(cacheKey);
174
+ if (!freshCached) {
175
+ throw new Error('SmartLead auth: failed to obtain user info');
176
+ }
177
+ return freshCached.user;
178
+ }
179
+ /**
180
+ * Force clear cached token (e.g., on 401 error)
181
+ */
182
+ function clearSmartLeadToken(email) {
183
+ tokenCache.delete(email.toLowerCase());
184
+ }
185
+ /**
186
+ * Clear all cached tokens
187
+ */
188
+ function clearAllSmartLeadTokens() {
189
+ tokenCache.clear();
190
+ }
191
+ /**
192
+ * Get token cache stats (for debugging)
193
+ */
194
+ function getSmartLeadTokenCacheStats() {
195
+ return {
196
+ cachedEmails: Array.from(tokenCache.keys()),
197
+ totalCached: tokenCache.size,
198
+ fileCacheEnabled,
199
+ fileCachePath: fileCacheEnabled ? getFileCachePath() : null,
200
+ };
201
+ }
202
+ // =============================================================================
203
+ // File-based Token Cache (for development/testing)
204
+ // =============================================================================
205
+ let fileCacheEnabled = false;
206
+ const FILE_CACHE_NAME = '.smartlead-tokens.json';
207
+ /**
208
+ * Get the file cache path
209
+ */
210
+ function getFileCachePath() {
211
+ // Store in user's home directory or temp
212
+ const homeDir = os.homedir();
213
+ return path.join(homeDir, FILE_CACHE_NAME);
214
+ }
215
+ /**
216
+ * Load tokens from file cache
217
+ */
218
+ function loadFileCache() {
219
+ const cache = new Map();
220
+ if (!fileCacheEnabled)
221
+ return cache;
222
+ try {
223
+ const filePath = getFileCachePath();
224
+ if (fs.existsSync(filePath)) {
225
+ const content = fs.readFileSync(filePath, 'utf8');
226
+ const data = JSON.parse(content);
227
+ for (const [key, value] of Object.entries(data)) {
228
+ // Validate structure
229
+ if (value && value.token && value.expiresAt && value.obtainedAt) {
230
+ cache.set(key, value);
231
+ }
232
+ }
233
+ }
234
+ }
235
+ catch {
236
+ // Ignore file read errors
237
+ }
238
+ return cache;
239
+ }
240
+ /**
241
+ * Save tokens to file cache
242
+ */
243
+ function saveFileCache() {
244
+ if (!fileCacheEnabled)
245
+ return;
246
+ try {
247
+ const filePath = getFileCachePath();
248
+ const data = {};
249
+ for (const [key, value] of tokenCache.entries()) {
250
+ data[key] = value;
251
+ }
252
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
253
+ }
254
+ catch {
255
+ // Ignore file write errors
256
+ }
257
+ }
258
+ /**
259
+ * Enable file-based token caching for development/testing
260
+ *
261
+ * When enabled, tokens are persisted to ~/.smartlead-tokens.json
262
+ * This avoids repeated logins during test development.
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * // In your test setup
267
+ * import { enableFileCache } from 'linkedin-secret-sauce/enrichment';
268
+ *
269
+ * enableFileCache(); // Now tokens persist between test runs
270
+ * ```
271
+ */
272
+ function enableFileCache() {
273
+ fileCacheEnabled = true;
274
+ // Load existing tokens from file into memory cache
275
+ const fileTokens = loadFileCache();
276
+ for (const [key, value] of fileTokens.entries()) {
277
+ // Only load if not already in memory and still valid
278
+ if (!tokenCache.has(key) && isTokenValid(value, DEFAULT_REFRESH_BUFFER_MS)) {
279
+ tokenCache.set(key, value);
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * Disable file-based token caching
285
+ */
286
+ function disableFileCache() {
287
+ fileCacheEnabled = false;
288
+ }
289
+ /**
290
+ * Check if file cache is enabled
291
+ */
292
+ function isFileCacheEnabled() {
293
+ return fileCacheEnabled;
294
+ }
295
+ /**
296
+ * Clear the file cache
297
+ */
298
+ function clearFileCache() {
299
+ try {
300
+ const filePath = getFileCachePath();
301
+ if (fs.existsSync(filePath)) {
302
+ fs.unlinkSync(filePath);
303
+ }
304
+ }
305
+ catch {
306
+ // Ignore errors
307
+ }
308
+ }
309
+ // Patch the existing getSmartLeadToken to save to file cache after login
310
+ const originalGetSmartLeadToken = getSmartLeadToken;
311
+ // We need to modify the token caching behavior to persist to file
312
+ // This is done by wrapping the cache set operation
313
+ // Override tokenCache.set to also persist to file
314
+ const originalSet = tokenCache.set.bind(tokenCache);
315
+ tokenCache.set = function (key, value) {
316
+ const result = originalSet(key, value);
317
+ if (fileCacheEnabled) {
318
+ saveFileCache();
319
+ }
320
+ return result;
321
+ };
@@ -26,7 +26,7 @@
26
26
  * });
27
27
  * ```
28
28
  */
29
- import type { EnrichmentClientConfig, EnrichmentClient } from './types';
29
+ import type { EnrichmentClientConfig, EnrichmentClient } from "./types";
30
30
  /**
31
31
  * Create an enrichment client with the given configuration
32
32
  *
@@ -34,10 +34,13 @@ import type { EnrichmentClientConfig, EnrichmentClient } from './types';
34
34
  * @returns An enrichment client with enrich and enrichBatch methods
35
35
  */
36
36
  export declare function createEnrichmentClient(config: EnrichmentClientConfig): EnrichmentClient;
37
- export * from './types';
38
- export { isPersonalEmail, isBusinessEmail, isPersonalDomain, PERSONAL_DOMAINS, } from './utils/personal-domains';
39
- export { isDisposableEmail, isDisposableDomain, DISPOSABLE_DOMAINS, } from './utils/disposable-domains';
40
- export { isValidEmailSyntax, isRoleAccount, asciiFold, cleanNamePart, hostnameFromUrl, extractLinkedInUsername, } from './utils/validation';
41
- export { verifyEmailMx } from './verification/mx';
42
- export { createConstructProvider, createLddProvider, createSmartProspectProvider, createHunterProvider, createApolloProvider, createDropcontactProvider, } from './providers';
43
- export { enrichBusinessEmail, enrichBatch } from './orchestrator';
37
+ export * from "./types";
38
+ export { isPersonalEmail, isBusinessEmail, isPersonalDomain, PERSONAL_DOMAINS, } from "./utils/personal-domains";
39
+ export { isDisposableEmail, isDisposableDomain, DISPOSABLE_DOMAINS, } from "./utils/disposable-domains";
40
+ export { isValidEmailSyntax, isRoleAccount, asciiFold, cleanNamePart, hostnameFromUrl, extractLinkedInUsername, } from "./utils/validation";
41
+ export { verifyEmailMx } from "./verification/mx";
42
+ export { createConstructProvider, createLddProvider, createSmartProspectProvider, createHunterProvider, createApolloProvider, createDropcontactProvider, } from "./providers";
43
+ export { createSmartProspectClient, type SmartProspectClient, type SmartProspectLocationOptions, } from "./providers/smartprospect";
44
+ export { enrichBusinessEmail, enrichBatch, enrichAllEmails, enrichAllBatch } from "./orchestrator";
45
+ export { getSmartLeadToken, getSmartLeadUser, clearSmartLeadToken, clearAllSmartLeadTokens, getSmartLeadTokenCacheStats, enableFileCache, disableFileCache, isFileCacheEnabled, clearFileCache, type SmartLeadCredentials, type SmartLeadAuthConfig, type SmartLeadUser, type SmartLeadLoginResponse, } from "./auth";
46
+ export { calculateMatchConfidence, classifyMatchQuality, findBestMatch, matchContacts, buildSmartProspectFiltersFromLinkedIn, parseLinkedInSearchResponse, enrichLinkedInContact, enrichLinkedInContactsBatch, createLinkedInEnricher, type LinkedInContact, type MatchResult, type MatchOptions, type LinkedInEnrichmentResult, type LinkedInEnrichmentOptions, } from "./matching";
@@ -42,7 +42,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
42
42
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.enrichBatch = exports.enrichBusinessEmail = exports.createDropcontactProvider = exports.createApolloProvider = exports.createHunterProvider = exports.createSmartProspectProvider = exports.createLddProvider = exports.createConstructProvider = exports.verifyEmailMx = exports.extractLinkedInUsername = exports.hostnameFromUrl = exports.cleanNamePart = exports.asciiFold = exports.isRoleAccount = exports.isValidEmailSyntax = exports.DISPOSABLE_DOMAINS = exports.isDisposableDomain = exports.isDisposableEmail = exports.PERSONAL_DOMAINS = exports.isPersonalDomain = exports.isBusinessEmail = exports.isPersonalEmail = void 0;
45
+ exports.createLinkedInEnricher = exports.enrichLinkedInContactsBatch = exports.enrichLinkedInContact = exports.parseLinkedInSearchResponse = exports.buildSmartProspectFiltersFromLinkedIn = exports.matchContacts = exports.findBestMatch = exports.classifyMatchQuality = exports.calculateMatchConfidence = exports.clearFileCache = exports.isFileCacheEnabled = exports.disableFileCache = exports.enableFileCache = exports.getSmartLeadTokenCacheStats = exports.clearAllSmartLeadTokens = exports.clearSmartLeadToken = exports.getSmartLeadUser = exports.getSmartLeadToken = exports.enrichAllBatch = exports.enrichAllEmails = exports.enrichBatch = exports.enrichBusinessEmail = exports.createSmartProspectClient = exports.createDropcontactProvider = exports.createApolloProvider = exports.createHunterProvider = exports.createSmartProspectProvider = exports.createLddProvider = exports.createConstructProvider = exports.verifyEmailMx = exports.extractLinkedInUsername = exports.hostnameFromUrl = exports.cleanNamePart = exports.asciiFold = exports.isRoleAccount = exports.isValidEmailSyntax = exports.DISPOSABLE_DOMAINS = exports.isDisposableDomain = exports.isDisposableEmail = exports.PERSONAL_DOMAINS = exports.isPersonalDomain = exports.isBusinessEmail = exports.isPersonalEmail = void 0;
46
46
  exports.createEnrichmentClient = createEnrichmentClient;
47
47
  const orchestrator_1 = require("./orchestrator");
48
48
  const construct_1 = require("./providers/construct");
@@ -55,12 +55,12 @@ const dropcontact_1 = require("./providers/dropcontact");
55
55
  * Default provider order
56
56
  */
57
57
  const DEFAULT_ORDER = [
58
- 'construct',
59
- 'ldd',
60
- 'smartprospect',
61
- 'hunter',
62
- 'apollo',
63
- 'dropcontact',
58
+ "construct",
59
+ "ldd",
60
+ "smartprospect",
61
+ "hunter",
62
+ "apollo",
63
+ "dropcontact",
64
64
  ];
65
65
  /**
66
66
  * Create an enrichment client with the given configuration
@@ -69,26 +69,26 @@ const DEFAULT_ORDER = [
69
69
  * @returns An enrichment client with enrich and enrichBatch methods
70
70
  */
71
71
  function createEnrichmentClient(config) {
72
- const { providers: providerConfigs, options = {}, cache, onCost, logger } = config;
72
+ const { providers: providerConfigs, options = {}, cache, onCost, logger, } = config;
73
73
  // Build provider functions based on configuration
74
74
  const providerFuncs = new Map();
75
75
  // Always create construct provider (free, no API key needed)
76
- providerFuncs.set('construct', (0, construct_1.createConstructProvider)(providerConfigs.construct));
76
+ providerFuncs.set("construct", (0, construct_1.createConstructProvider)(providerConfigs.construct));
77
77
  // Create other providers if configured
78
78
  if (providerConfigs.ldd) {
79
- providerFuncs.set('ldd', (0, ldd_1.createLddProvider)(providerConfigs.ldd));
79
+ providerFuncs.set("ldd", (0, ldd_1.createLddProvider)(providerConfigs.ldd));
80
80
  }
81
81
  if (providerConfigs.smartprospect) {
82
- providerFuncs.set('smartprospect', (0, smartprospect_1.createSmartProspectProvider)(providerConfigs.smartprospect));
82
+ providerFuncs.set("smartprospect", (0, smartprospect_1.createSmartProspectProvider)(providerConfigs.smartprospect));
83
83
  }
84
84
  if (providerConfigs.hunter) {
85
- providerFuncs.set('hunter', (0, hunter_1.createHunterProvider)(providerConfigs.hunter));
85
+ providerFuncs.set("hunter", (0, hunter_1.createHunterProvider)(providerConfigs.hunter));
86
86
  }
87
87
  if (providerConfigs.apollo) {
88
- providerFuncs.set('apollo', (0, apollo_1.createApolloProvider)(providerConfigs.apollo));
88
+ providerFuncs.set("apollo", (0, apollo_1.createApolloProvider)(providerConfigs.apollo));
89
89
  }
90
90
  if (providerConfigs.dropcontact) {
91
- providerFuncs.set('dropcontact', (0, dropcontact_1.createDropcontactProvider)(providerConfigs.dropcontact));
91
+ providerFuncs.set("dropcontact", (0, dropcontact_1.createDropcontactProvider)(providerConfigs.dropcontact));
92
92
  }
93
93
  // Build ordered provider list
94
94
  const providerOrder = options.providerOrder ?? DEFAULT_ORDER;
@@ -120,7 +120,7 @@ function createEnrichmentClient(config) {
120
120
  try {
121
121
  const cached = await cache.get(cacheKey);
122
122
  if (cached) {
123
- logger?.debug?.('enrichment.cache.hit', { cacheKey });
123
+ logger?.debug?.("enrichment.cache.hit", { cacheKey });
124
124
  return cached;
125
125
  }
126
126
  }
@@ -154,6 +154,25 @@ function createEnrichmentClient(config) {
154
154
  ...batchOptions,
155
155
  });
156
156
  },
157
+ /**
158
+ * Enrich a single candidate and return ALL found emails from ALL providers
159
+ *
160
+ * Unlike `enrich()` which returns the first valid business email,
161
+ * this method queries all providers and returns every email found,
162
+ * including personal emails, with type classifications and scores.
163
+ */
164
+ async enrichAll(candidate) {
165
+ return (0, orchestrator_1.enrichAllEmails)(candidate, orchestratorOptions);
166
+ },
167
+ /**
168
+ * Enrich multiple candidates and return ALL found emails for each
169
+ */
170
+ async enrichAllBatch(candidates, batchOptions) {
171
+ return (0, orchestrator_1.enrichAllBatch)(candidates, {
172
+ ...orchestratorOptions,
173
+ ...batchOptions,
174
+ });
175
+ },
157
176
  };
158
177
  }
159
178
  /**
@@ -176,10 +195,16 @@ function buildCacheKey(candidate) {
176
195
  }
177
196
  else {
178
197
  // Fall back to name + domain/company
179
- const firstName = candidate.firstName || candidate.first_name || candidate.first || '';
180
- const lastName = candidate.lastName || candidate.last_name || candidate.last || '';
181
- const domain = candidate.domain || candidate.companyDomain || candidate.company_domain || '';
182
- const company = candidate.company || candidate.currentCompany || candidate.organization || '';
198
+ const firstName = candidate.firstName || candidate.first_name || candidate.first || "";
199
+ const lastName = candidate.lastName || candidate.last_name || candidate.last || "";
200
+ const domain = candidate.domain ||
201
+ candidate.companyDomain ||
202
+ candidate.company_domain ||
203
+ "";
204
+ const company = candidate.company ||
205
+ candidate.currentCompany ||
206
+ candidate.organization ||
207
+ "";
183
208
  if (firstName && (domain || company)) {
184
209
  parts.push(`name:${firstName.toLowerCase()}`);
185
210
  if (lastName)
@@ -193,7 +218,7 @@ function buildCacheKey(candidate) {
193
218
  if (parts.length === 0) {
194
219
  return null;
195
220
  }
196
- return parts.join('|');
221
+ return parts.join("|");
197
222
  }
198
223
  // Re-export types
199
224
  __exportStar(require("./types"), exports);
@@ -225,7 +250,37 @@ Object.defineProperty(exports, "createSmartProspectProvider", { enumerable: true
225
250
  Object.defineProperty(exports, "createHunterProvider", { enumerable: true, get: function () { return providers_1.createHunterProvider; } });
226
251
  Object.defineProperty(exports, "createApolloProvider", { enumerable: true, get: function () { return providers_1.createApolloProvider; } });
227
252
  Object.defineProperty(exports, "createDropcontactProvider", { enumerable: true, get: function () { return providers_1.createDropcontactProvider; } });
253
+ // Re-export SmartProspect client for direct API access
254
+ var smartprospect_2 = require("./providers/smartprospect");
255
+ Object.defineProperty(exports, "createSmartProspectClient", { enumerable: true, get: function () { return smartprospect_2.createSmartProspectClient; } });
228
256
  // Re-export orchestrator (for advanced usage)
229
257
  var orchestrator_2 = require("./orchestrator");
230
258
  Object.defineProperty(exports, "enrichBusinessEmail", { enumerable: true, get: function () { return orchestrator_2.enrichBusinessEmail; } });
231
259
  Object.defineProperty(exports, "enrichBatch", { enumerable: true, get: function () { return orchestrator_2.enrichBatch; } });
260
+ Object.defineProperty(exports, "enrichAllEmails", { enumerable: true, get: function () { return orchestrator_2.enrichAllEmails; } });
261
+ Object.defineProperty(exports, "enrichAllBatch", { enumerable: true, get: function () { return orchestrator_2.enrichAllBatch; } });
262
+ // Re-export auth utilities (for advanced usage)
263
+ var auth_1 = require("./auth");
264
+ Object.defineProperty(exports, "getSmartLeadToken", { enumerable: true, get: function () { return auth_1.getSmartLeadToken; } });
265
+ Object.defineProperty(exports, "getSmartLeadUser", { enumerable: true, get: function () { return auth_1.getSmartLeadUser; } });
266
+ Object.defineProperty(exports, "clearSmartLeadToken", { enumerable: true, get: function () { return auth_1.clearSmartLeadToken; } });
267
+ Object.defineProperty(exports, "clearAllSmartLeadTokens", { enumerable: true, get: function () { return auth_1.clearAllSmartLeadTokens; } });
268
+ Object.defineProperty(exports, "getSmartLeadTokenCacheStats", { enumerable: true, get: function () { return auth_1.getSmartLeadTokenCacheStats; } });
269
+ // File cache utilities for development/testing
270
+ Object.defineProperty(exports, "enableFileCache", { enumerable: true, get: function () { return auth_1.enableFileCache; } });
271
+ Object.defineProperty(exports, "disableFileCache", { enumerable: true, get: function () { return auth_1.disableFileCache; } });
272
+ Object.defineProperty(exports, "isFileCacheEnabled", { enumerable: true, get: function () { return auth_1.isFileCacheEnabled; } });
273
+ Object.defineProperty(exports, "clearFileCache", { enumerable: true, get: function () { return auth_1.clearFileCache; } });
274
+ // Re-export matching utilities (LinkedIn <-> SmartProspect)
275
+ var matching_1 = require("./matching");
276
+ // Low-level matching functions
277
+ Object.defineProperty(exports, "calculateMatchConfidence", { enumerable: true, get: function () { return matching_1.calculateMatchConfidence; } });
278
+ Object.defineProperty(exports, "classifyMatchQuality", { enumerable: true, get: function () { return matching_1.classifyMatchQuality; } });
279
+ Object.defineProperty(exports, "findBestMatch", { enumerable: true, get: function () { return matching_1.findBestMatch; } });
280
+ Object.defineProperty(exports, "matchContacts", { enumerable: true, get: function () { return matching_1.matchContacts; } });
281
+ Object.defineProperty(exports, "buildSmartProspectFiltersFromLinkedIn", { enumerable: true, get: function () { return matching_1.buildSmartProspectFiltersFromLinkedIn; } });
282
+ Object.defineProperty(exports, "parseLinkedInSearchResponse", { enumerable: true, get: function () { return matching_1.parseLinkedInSearchResponse; } });
283
+ // High-level enrichment functions
284
+ Object.defineProperty(exports, "enrichLinkedInContact", { enumerable: true, get: function () { return matching_1.enrichLinkedInContact; } });
285
+ Object.defineProperty(exports, "enrichLinkedInContactsBatch", { enumerable: true, get: function () { return matching_1.enrichLinkedInContactsBatch; } });
286
+ Object.defineProperty(exports, "createLinkedInEnricher", { enumerable: true, get: function () { return matching_1.createLinkedInEnricher; } });