linkedin-secret-sauce 0.12.1 → 0.12.2

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.
Files changed (44) hide show
  1. package/README.md +50 -21
  2. package/dist/cosiall-client.d.ts +1 -1
  3. package/dist/cosiall-client.js +1 -1
  4. package/dist/enrichment/index.d.ts +1 -1
  5. package/dist/enrichment/index.js +11 -2
  6. package/dist/enrichment/matching.d.ts +16 -2
  7. package/dist/enrichment/matching.js +387 -65
  8. package/dist/enrichment/providers/bounceban.d.ts +82 -0
  9. package/dist/enrichment/providers/bounceban.js +447 -0
  10. package/dist/enrichment/providers/bouncer.d.ts +1 -1
  11. package/dist/enrichment/providers/bouncer.js +19 -21
  12. package/dist/enrichment/providers/construct.d.ts +1 -1
  13. package/dist/enrichment/providers/construct.js +22 -38
  14. package/dist/enrichment/providers/cosiall.d.ts +1 -1
  15. package/dist/enrichment/providers/cosiall.js +3 -4
  16. package/dist/enrichment/providers/dropcontact.d.ts +15 -9
  17. package/dist/enrichment/providers/dropcontact.js +188 -19
  18. package/dist/enrichment/providers/hunter.d.ts +8 -1
  19. package/dist/enrichment/providers/hunter.js +52 -28
  20. package/dist/enrichment/providers/index.d.ts +2 -0
  21. package/dist/enrichment/providers/index.js +10 -1
  22. package/dist/enrichment/providers/ldd.d.ts +1 -10
  23. package/dist/enrichment/providers/ldd.js +20 -97
  24. package/dist/enrichment/providers/smartprospect.js +28 -48
  25. package/dist/enrichment/providers/snovio.d.ts +1 -1
  26. package/dist/enrichment/providers/snovio.js +29 -31
  27. package/dist/enrichment/providers/trykitt.d.ts +63 -0
  28. package/dist/enrichment/providers/trykitt.js +210 -0
  29. package/dist/enrichment/types.d.ts +210 -7
  30. package/dist/enrichment/types.js +16 -8
  31. package/dist/enrichment/utils/candidate-parser.d.ts +107 -0
  32. package/dist/enrichment/utils/candidate-parser.js +173 -0
  33. package/dist/enrichment/utils/noop-provider.d.ts +39 -0
  34. package/dist/enrichment/utils/noop-provider.js +37 -0
  35. package/dist/enrichment/utils/rate-limiter.d.ts +103 -0
  36. package/dist/enrichment/utils/rate-limiter.js +204 -0
  37. package/dist/enrichment/utils/validation.d.ts +75 -3
  38. package/dist/enrichment/utils/validation.js +164 -11
  39. package/dist/linkedin-api.d.ts +40 -1
  40. package/dist/linkedin-api.js +160 -27
  41. package/dist/types.d.ts +50 -1
  42. package/dist/utils/lru-cache.d.ts +105 -0
  43. package/dist/utils/lru-cache.js +175 -0
  44. package/package.json +25 -26
package/README.md CHANGED
@@ -8,10 +8,16 @@ A complete LinkedIn Sales Navigator client + Email Enrichment library for Node.j
8
8
 
9
9
  ## Documentation
10
10
 
11
- - [Full API Documentation](https://enerage.github.io/LinkedInSecretSauce/) - Auto-generated TypeDoc
12
11
  - [Integration Guide](docs/INTEGRATION.md) - Step-by-step setup
13
12
  - [Sales Search Guide](docs/SALES_SEARCH.md) - Advanced search filters
14
13
  - [Playground Guide](docs/PLAYGROUND.md) - Local dev UI
14
+ - [Cosiall Profile Emails](docs/COSIALL_PROFILE_EMAILS.md) - Profile email lookups
15
+
16
+ **Generate API docs locally:**
17
+ ```bash
18
+ pnpm docs
19
+ # Opens TypeDoc documentation in your browser
20
+ ```
15
21
 
16
22
  ## Installation
17
23
 
@@ -193,13 +199,40 @@ Find and verify business emails using multiple providers with waterfall/parallel
193
199
 
194
200
  | Provider | Type | Cost | Best For |
195
201
  |----------|------|------|----------|
196
- | **Construct** | Pattern + MX | FREE | Quick pattern matching |
197
- | **LDD** | Database | FREE | LinkedIn profile emails |
202
+ | **LDD** | Database | FREE | LinkedIn profile emails (~500M profiles) |
203
+ | **SmartProspect** | Database | FREE* | SmartLead's prospect database |
204
+ | **Cosiall** | Profile Lookup | FREE | Emails from LinkedIn profiles |
205
+ | **Construct** | Pattern + MX | FREE | Pattern guessing with MX verification |
198
206
  | **Bouncer** | SMTP Verify | $0.006/email | Catch-all detection, 99%+ accuracy |
199
207
  | **Snov.io** | Email Finder | $0.02/email | Finding emails by name+domain |
200
208
  | **Hunter** | Email Finder | $0.005/email | Domain search, email finder |
201
- | **Apollo** | Database | FREE | B2B contact database |
202
- | **SmartProspect** | Database | $0.01/email | Lead database search |
209
+
210
+ *SmartProspect is FREE if you have a SmartLead subscription
211
+
212
+ ### Cosiall Profile Emails (Standalone)
213
+
214
+ Lookup emails directly from LinkedIn profiles without the full enrichment pipeline:
215
+
216
+ ```typescript
217
+ import { fetchProfileEmailsFromCosiall } from 'linkedin-secret-sauce';
218
+
219
+ // Lookup by ObjectURN (most precise)
220
+ const result = await fetchProfileEmailsFromCosiall({
221
+ objectUrn: 'urn:li:member:129147375'
222
+ });
223
+
224
+ // Or by LinkedIn URL
225
+ const result = await fetchProfileEmailsFromCosiall({
226
+ linkedInUrl: 'https://www.linkedin.com/in/john-doe/'
227
+ });
228
+
229
+ // Or by vanity name
230
+ const result = await fetchProfileEmailsFromCosiall({
231
+ vanity: 'john-doe'
232
+ });
233
+
234
+ console.log(result.emails); // ['john@company.com', 'john.doe@gmail.com']
235
+ ```
203
236
 
204
237
  ### Quick Start
205
238
 
@@ -208,29 +241,25 @@ import { createEnrichmentClient } from 'linkedin-secret-sauce';
208
241
 
209
242
  const enrichment = createEnrichmentClient({
210
243
  providers: {
211
- // FREE providers (no API key needed)
212
- construct: {},
213
-
214
- // Paid providers (add your API keys)
215
- hunter: { apiKey: process.env.HUNTER_API_KEY },
216
- apollo: { apiKey: process.env.APOLLO_API_KEY },
217
- bouncer: { apiKey: process.env.BOUNCER_API_KEY },
218
- snovio: {
219
- clientId: process.env.SNOVIO_CLIENT_ID,
220
- clientSecret: process.env.SNOVIO_CLIENT_SECRET
221
- },
222
-
223
- // Your private LinkedIn data dump
244
+ // FREE providers - all run automatically in parallel
224
245
  ldd: {
225
246
  apiUrl: process.env.LDD_API_URL,
226
247
  apiToken: process.env.LDD_API_TOKEN
227
248
  },
228
-
229
- // SmartLead (supports credentials or direct token)
230
249
  smartprospect: {
231
250
  email: process.env.SMARTLEAD_EMAIL,
232
251
  password: process.env.SMARTLEAD_PASSWORD,
233
252
  },
253
+ // cosiall: enabled by default (uses global Cosiall config)
254
+ // construct: enabled by default (pattern guessing)
255
+
256
+ // PAID providers - only used if FREE providers don't find email
257
+ bouncer: { apiKey: process.env.BOUNCER_API_KEY },
258
+ snovio: {
259
+ userId: process.env.SNOVIO_USER_ID,
260
+ apiSecret: process.env.SNOVIO_API_SECRET
261
+ },
262
+ hunter: { apiKey: process.env.HUNTER_API_KEY },
234
263
  },
235
264
 
236
265
  // Optional: cost tracking callback
@@ -554,4 +583,4 @@ UNLICENSED - Private package
554
583
  ## Support
555
584
 
556
585
  - Issues: [GitHub Issues](https://github.com/enerage/LinkedInSecretSauce/issues)
557
- - Docs: [API Documentation](https://enerage.github.io/LinkedInSecretSauce/)
586
+ - Docs: Run `pnpm docs` to generate TypeDoc locally
@@ -41,7 +41,7 @@ export declare function fetchCookiesFromCosiall(): Promise<AccountCookies[]>;
41
41
  * ```typescript
42
42
  * // Lookup by ObjectURN (most precise)
43
43
  * const result = await fetchProfileEmailsFromCosiall({
44
- * objectUrn: 'urn:li:fsd_profile:ACoAABcdEfG'
44
+ * objectUrn: 'urn:li:member:129147375'
45
45
  * });
46
46
  *
47
47
  * // Lookup by LinkedIn URL
@@ -149,7 +149,7 @@ async function fetchCookiesFromCosiall() {
149
149
  * ```typescript
150
150
  * // Lookup by ObjectURN (most precise)
151
151
  * const result = await fetchProfileEmailsFromCosiall({
152
- * objectUrn: 'urn:li:fsd_profile:ACoAABcdEfG'
152
+ * objectUrn: 'urn:li:member:129147375'
153
153
  * });
154
154
  *
155
155
  * // Lookup by LinkedIn URL
@@ -41,7 +41,7 @@ export { isPersonalEmail, isBusinessEmail, isPersonalDomain, PERSONAL_DOMAINS, }
41
41
  export { isDisposableEmail, isDisposableDomain, DISPOSABLE_DOMAINS, } from "./utils/disposable-domains";
42
42
  export { isValidEmailSyntax, isRoleAccount, asciiFold, cleanNamePart, hostnameFromUrl, extractLinkedInUsername, } from "./utils/validation";
43
43
  export { verifyEmailMx, checkDomainCatchAll, verifyEmailsExist, } from "./verification/mx";
44
- export { createConstructProvider, createLddProvider, createSmartProspectProvider, createCosiallProvider, createHunterProvider, createDropcontactProvider, createBouncerProvider, createSnovioProvider, verifyEmailWithBouncer, checkCatchAllDomain, verifyEmailsBatch, findEmailsWithSnovio, verifyEmailWithSnovio, clearSnovioTokenCache, } from "./providers";
44
+ export { createConstructProvider, createLddProvider, createSmartProspectProvider, createCosiallProvider, createTryKittProvider, createHunterProvider, createDropcontactProvider, createBouncerProvider, createBounceBanProvider, createSnovioProvider, findEmailWithTryKitt, verifyEmailWithTryKitt, verifyEmailWithBouncer, checkCatchAllDomain, verifyEmailsBatch, verifyEmailWithBounceBan, verifyEmailsBatchWithBounceBan, checkCatchAllWithBounceBan, findEmailsWithSnovio, verifyEmailWithSnovio, clearSnovioTokenCache, } from "./providers";
45
45
  export { extractNumericLinkedInId } from "./providers/ldd";
46
46
  export { createSmartProspectClient, type SmartProspectClient, type SmartProspectLocationOptions, } from "./providers/smartprospect";
47
47
  export { enrichBusinessEmail, enrichBatch, enrichAllEmails, enrichAllBatch, } from "./orchestrator";
@@ -43,8 +43,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
43
43
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
44
44
  };
45
45
  Object.defineProperty(exports, "__esModule", { value: true });
46
- 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.extractNumericLinkedInId = exports.clearSnovioTokenCache = exports.verifyEmailWithSnovio = exports.findEmailsWithSnovio = exports.verifyEmailsBatch = exports.checkCatchAllDomain = exports.verifyEmailWithBouncer = exports.createSnovioProvider = exports.createBouncerProvider = exports.createDropcontactProvider = exports.createHunterProvider = exports.createCosiallProvider = exports.createSmartProspectProvider = exports.createLddProvider = exports.createConstructProvider = exports.verifyEmailsExist = exports.checkDomainCatchAll = 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 = exports.DEFAULT_PROVIDER_ORDER = exports.PROVIDER_COSTS = void 0;
47
- exports.salesLeadToContact = exports.getEmailsForLinkedInContactsBatch = exports.getEmailsForLinkedInContact = exports.createLinkedInEnricher = exports.enrichLinkedInContactsBatch = exports.enrichLinkedInContact = exports.parseLinkedInSearchResponse = exports.buildSmartProspectFiltersFromLinkedIn = exports.matchContacts = void 0;
46
+ exports.getSmartLeadTokenCacheStats = exports.clearAllSmartLeadTokens = exports.clearSmartLeadToken = exports.getSmartLeadUser = exports.getSmartLeadToken = exports.enrichAllBatch = exports.enrichAllEmails = exports.enrichBatch = exports.enrichBusinessEmail = exports.createSmartProspectClient = exports.extractNumericLinkedInId = exports.clearSnovioTokenCache = exports.verifyEmailWithSnovio = exports.findEmailsWithSnovio = exports.checkCatchAllWithBounceBan = exports.verifyEmailsBatchWithBounceBan = exports.verifyEmailWithBounceBan = exports.verifyEmailsBatch = exports.checkCatchAllDomain = exports.verifyEmailWithBouncer = exports.verifyEmailWithTryKitt = exports.findEmailWithTryKitt = exports.createSnovioProvider = exports.createBounceBanProvider = exports.createBouncerProvider = exports.createDropcontactProvider = exports.createHunterProvider = exports.createTryKittProvider = exports.createCosiallProvider = exports.createSmartProspectProvider = exports.createLddProvider = exports.createConstructProvider = exports.verifyEmailsExist = exports.checkDomainCatchAll = 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 = exports.DEFAULT_PROVIDER_ORDER = exports.PROVIDER_COSTS = void 0;
47
+ exports.salesLeadToContact = exports.getEmailsForLinkedInContactsBatch = exports.getEmailsForLinkedInContact = 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 = void 0;
48
48
  exports.createEnrichmentClient = createEnrichmentClient;
49
49
  const orchestrator_1 = require("./orchestrator");
50
50
  const construct_1 = require("./providers/construct");
@@ -278,14 +278,23 @@ Object.defineProperty(exports, "createConstructProvider", { enumerable: true, ge
278
278
  Object.defineProperty(exports, "createLddProvider", { enumerable: true, get: function () { return providers_1.createLddProvider; } });
279
279
  Object.defineProperty(exports, "createSmartProspectProvider", { enumerable: true, get: function () { return providers_1.createSmartProspectProvider; } });
280
280
  Object.defineProperty(exports, "createCosiallProvider", { enumerable: true, get: function () { return providers_1.createCosiallProvider; } });
281
+ Object.defineProperty(exports, "createTryKittProvider", { enumerable: true, get: function () { return providers_1.createTryKittProvider; } });
281
282
  Object.defineProperty(exports, "createHunterProvider", { enumerable: true, get: function () { return providers_1.createHunterProvider; } });
282
283
  Object.defineProperty(exports, "createDropcontactProvider", { enumerable: true, get: function () { return providers_1.createDropcontactProvider; } });
283
284
  Object.defineProperty(exports, "createBouncerProvider", { enumerable: true, get: function () { return providers_1.createBouncerProvider; } });
285
+ Object.defineProperty(exports, "createBounceBanProvider", { enumerable: true, get: function () { return providers_1.createBounceBanProvider; } });
284
286
  Object.defineProperty(exports, "createSnovioProvider", { enumerable: true, get: function () { return providers_1.createSnovioProvider; } });
287
+ // TryKitt utilities
288
+ Object.defineProperty(exports, "findEmailWithTryKitt", { enumerable: true, get: function () { return providers_1.findEmailWithTryKitt; } });
289
+ Object.defineProperty(exports, "verifyEmailWithTryKitt", { enumerable: true, get: function () { return providers_1.verifyEmailWithTryKitt; } });
285
290
  // Bouncer utilities
286
291
  Object.defineProperty(exports, "verifyEmailWithBouncer", { enumerable: true, get: function () { return providers_1.verifyEmailWithBouncer; } });
287
292
  Object.defineProperty(exports, "checkCatchAllDomain", { enumerable: true, get: function () { return providers_1.checkCatchAllDomain; } });
288
293
  Object.defineProperty(exports, "verifyEmailsBatch", { enumerable: true, get: function () { return providers_1.verifyEmailsBatch; } });
294
+ // BounceBan utilities
295
+ Object.defineProperty(exports, "verifyEmailWithBounceBan", { enumerable: true, get: function () { return providers_1.verifyEmailWithBounceBan; } });
296
+ Object.defineProperty(exports, "verifyEmailsBatchWithBounceBan", { enumerable: true, get: function () { return providers_1.verifyEmailsBatchWithBounceBan; } });
297
+ Object.defineProperty(exports, "checkCatchAllWithBounceBan", { enumerable: true, get: function () { return providers_1.checkCatchAllWithBounceBan; } });
289
298
  // Snov.io utilities
290
299
  Object.defineProperty(exports, "findEmailsWithSnovio", { enumerable: true, get: function () { return providers_1.findEmailsWithSnovio; } });
291
300
  Object.defineProperty(exports, "verifyEmailWithSnovio", { enumerable: true, get: function () { return providers_1.verifyEmailWithSnovio; } });
@@ -258,7 +258,7 @@ export declare function createLinkedInEnricher(smartProspectConfig: SmartProspec
258
258
  /**
259
259
  * Email source - where the email was found
260
260
  */
261
- export type EmailSource = "ldd" | "smartprospect" | "cosiall" | "linkedin" | "pattern" | "hunter" | "bouncer" | "snovio";
261
+ export type EmailSource = "ldd" | "smartprospect" | "cosiall" | "trykitt" | "linkedin" | "pattern" | "hunter" | "bouncer" | "bounceban" | "snovio";
262
262
  /**
263
263
  * Email result from unified lookup
264
264
  */
@@ -309,6 +309,10 @@ export interface GetEmailsConfig {
309
309
  cosiall?: {
310
310
  enabled?: boolean;
311
311
  };
312
+ /** TryKitt.ai configuration (FREE for individuals - unlimited) */
313
+ trykitt?: {
314
+ apiKey: string;
315
+ };
312
316
  /** Company domain for email pattern guessing (optional - if not provided, will try to discover) */
313
317
  companyDomain?: string;
314
318
  /**
@@ -327,6 +331,12 @@ export interface GetEmailsConfig {
327
331
  bouncer?: {
328
332
  apiKey: string;
329
333
  };
334
+ /** BounceBan configuration (FREE single / catch-all specialist) */
335
+ bounceban?: {
336
+ apiKey: string;
337
+ useDeepVerify?: boolean;
338
+ useWaterfall?: boolean;
339
+ };
330
340
  /** Snov.io configuration (PAID - email finder) */
331
341
  snovio?: {
332
342
  userId: string;
@@ -343,11 +353,15 @@ export interface GetEmailsOptions {
343
353
  skipSmartProspect?: boolean;
344
354
  /** Skip Cosiall Profile Emails lookup (default: false) */
345
355
  skipCosiall?: boolean;
356
+ /** Skip TryKitt.ai lookup (default: false) */
357
+ skipTryKitt?: boolean;
346
358
  /** Skip email pattern guessing (default: false) */
347
359
  skipPatternGuessing?: boolean;
360
+ /** Skip BounceBan catch-all verification (default: false) */
361
+ skipBounceBan?: boolean;
348
362
  /** Skip LinkedIn company lookup for domain discovery (default: false) */
349
363
  skipLinkedInCompanyLookup?: boolean;
350
- /** Skip paid providers Hunter/Apollo (default: false) */
364
+ /** Skip paid providers Hunter/Snovio (default: false) */
351
365
  skipPaidProviders?: boolean;
352
366
  /** Minimum match confidence for SmartProspect (default: 60) */
353
367
  minMatchConfidence?: number;