linkedin-secret-sauce 0.5.0 → 0.5.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/dist/enrichment/auth/index.d.ts +4 -0
- package/dist/enrichment/auth/index.js +12 -0
- package/dist/enrichment/auth/smartlead-auth.d.ts +50 -0
- package/dist/enrichment/auth/smartlead-auth.js +156 -0
- package/dist/enrichment/index.d.ts +9 -8
- package/dist/enrichment/index.js +33 -20
- package/dist/enrichment/providers/smartprospect.d.ts +9 -1
- package/dist/enrichment/providers/smartprospect.js +124 -40
- package/dist/enrichment/types.d.ts +17 -3
- package/dist/enrichment/types.js +6 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -1
- package/package.json +15 -16
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication modules for enrichment providers
|
|
3
|
+
*/
|
|
4
|
+
export { getSmartLeadToken, getSmartLeadUser, clearSmartLeadToken, clearAllSmartLeadTokens, getSmartLeadTokenCacheStats, type SmartLeadCredentials, type SmartLeadAuthConfig, type SmartLeadUser, type SmartLeadLoginResponse, } from './smartlead-auth';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Authentication modules for enrichment providers
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
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; } });
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
export interface SmartLeadCredentials {
|
|
8
|
+
email: string;
|
|
9
|
+
password: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SmartLeadAuthConfig {
|
|
12
|
+
credentials: SmartLeadCredentials;
|
|
13
|
+
/** Login API URL (default: https://server.smartlead.ai/api/auth/login) */
|
|
14
|
+
loginUrl?: string;
|
|
15
|
+
/** Token refresh buffer in ms - refresh this much before expiry (default: 5 min) */
|
|
16
|
+
refreshBufferMs?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface SmartLeadUser {
|
|
19
|
+
id: number;
|
|
20
|
+
uuid: string;
|
|
21
|
+
email: string;
|
|
22
|
+
name: string;
|
|
23
|
+
role: string;
|
|
24
|
+
api_key: string;
|
|
25
|
+
region: string;
|
|
26
|
+
}
|
|
27
|
+
export interface SmartLeadLoginResponse {
|
|
28
|
+
user: SmartLeadUser;
|
|
29
|
+
token: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function getSmartLeadToken(config: SmartLeadAuthConfig): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Get SmartLead user info (from cached login)
|
|
34
|
+
*/
|
|
35
|
+
export declare function getSmartLeadUser(config: SmartLeadAuthConfig): Promise<SmartLeadUser>;
|
|
36
|
+
/**
|
|
37
|
+
* Force clear cached token (e.g., on 401 error)
|
|
38
|
+
*/
|
|
39
|
+
export declare function clearSmartLeadToken(email: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Clear all cached tokens
|
|
42
|
+
*/
|
|
43
|
+
export declare function clearAllSmartLeadTokens(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get token cache stats (for debugging)
|
|
46
|
+
*/
|
|
47
|
+
export declare function getSmartLeadTokenCacheStats(): {
|
|
48
|
+
cachedEmails: string[];
|
|
49
|
+
totalCached: number;
|
|
50
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getSmartLeadToken = getSmartLeadToken;
|
|
10
|
+
exports.getSmartLeadUser = getSmartLeadUser;
|
|
11
|
+
exports.clearSmartLeadToken = clearSmartLeadToken;
|
|
12
|
+
exports.clearAllSmartLeadTokens = clearAllSmartLeadTokens;
|
|
13
|
+
exports.getSmartLeadTokenCacheStats = getSmartLeadTokenCacheStats;
|
|
14
|
+
const DEFAULT_LOGIN_URL = 'https://server.smartlead.ai/api/auth/login';
|
|
15
|
+
const DEFAULT_REFRESH_BUFFER_MS = 5 * 60 * 1000; // 5 minutes
|
|
16
|
+
const TOKEN_LIFETIME_MS = 24 * 60 * 60 * 1000; // Assume 24h JWT lifetime (conservative)
|
|
17
|
+
// In-memory token cache keyed by email
|
|
18
|
+
const tokenCache = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Parse JWT to extract expiration time
|
|
21
|
+
*/
|
|
22
|
+
function parseJwtExpiry(token) {
|
|
23
|
+
try {
|
|
24
|
+
const parts = token.split('.');
|
|
25
|
+
if (parts.length !== 3)
|
|
26
|
+
return null;
|
|
27
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString('utf8'));
|
|
28
|
+
if (payload.exp) {
|
|
29
|
+
return payload.exp * 1000; // Convert to ms
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Login to SmartLead and obtain JWT token
|
|
39
|
+
*/
|
|
40
|
+
async function login(config) {
|
|
41
|
+
const { credentials, loginUrl = DEFAULT_LOGIN_URL } = config;
|
|
42
|
+
const response = await fetch(loginUrl, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: {
|
|
45
|
+
Accept: 'application/json, text/plain, */*',
|
|
46
|
+
'Content-Type': 'application/json',
|
|
47
|
+
Origin: 'https://app.smartlead.ai',
|
|
48
|
+
Referer: 'https://app.smartlead.ai/',
|
|
49
|
+
'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',
|
|
50
|
+
},
|
|
51
|
+
body: JSON.stringify({
|
|
52
|
+
email: credentials.email,
|
|
53
|
+
password: credentials.password,
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
const errorText = await response.text().catch(() => '');
|
|
58
|
+
throw new Error(`SmartLead login failed: ${response.status} - ${errorText}`);
|
|
59
|
+
}
|
|
60
|
+
const data = (await response.json());
|
|
61
|
+
if (!data.token || !data.user) {
|
|
62
|
+
throw new Error('SmartLead login response missing token or user');
|
|
63
|
+
}
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
// Try to parse expiry from JWT, fallback to assumed lifetime
|
|
66
|
+
let expiresAt = parseJwtExpiry(data.token);
|
|
67
|
+
if (!expiresAt) {
|
|
68
|
+
expiresAt = now + TOKEN_LIFETIME_MS;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
token: data.token,
|
|
72
|
+
user: data.user,
|
|
73
|
+
expiresAt,
|
|
74
|
+
obtainedAt: now,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check if cached token is still valid (with buffer for refresh)
|
|
79
|
+
*/
|
|
80
|
+
function isTokenValid(cached, refreshBufferMs) {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
return cached.expiresAt - refreshBufferMs > now;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get a valid SmartLead JWT token
|
|
86
|
+
*
|
|
87
|
+
* Returns cached token if still valid, otherwise performs fresh login.
|
|
88
|
+
* Thread-safe via promise deduplication.
|
|
89
|
+
*/
|
|
90
|
+
const pendingLogins = new Map();
|
|
91
|
+
async function getSmartLeadToken(config) {
|
|
92
|
+
const { credentials, refreshBufferMs = DEFAULT_REFRESH_BUFFER_MS } = config;
|
|
93
|
+
const cacheKey = credentials.email.toLowerCase();
|
|
94
|
+
// Check cache first
|
|
95
|
+
const cached = tokenCache.get(cacheKey);
|
|
96
|
+
if (cached && isTokenValid(cached, refreshBufferMs)) {
|
|
97
|
+
return cached.token;
|
|
98
|
+
}
|
|
99
|
+
// Check if login already in progress (dedup concurrent requests)
|
|
100
|
+
const pending = pendingLogins.get(cacheKey);
|
|
101
|
+
if (pending) {
|
|
102
|
+
const result = await pending;
|
|
103
|
+
return result.token;
|
|
104
|
+
}
|
|
105
|
+
// Perform login
|
|
106
|
+
const loginPromise = login(config);
|
|
107
|
+
pendingLogins.set(cacheKey, loginPromise);
|
|
108
|
+
try {
|
|
109
|
+
const result = await loginPromise;
|
|
110
|
+
tokenCache.set(cacheKey, result);
|
|
111
|
+
return result.token;
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
pendingLogins.delete(cacheKey);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get SmartLead user info (from cached login)
|
|
119
|
+
*/
|
|
120
|
+
async function getSmartLeadUser(config) {
|
|
121
|
+
const { credentials, refreshBufferMs = DEFAULT_REFRESH_BUFFER_MS } = config;
|
|
122
|
+
const cacheKey = credentials.email.toLowerCase();
|
|
123
|
+
// Check cache first
|
|
124
|
+
const cached = tokenCache.get(cacheKey);
|
|
125
|
+
if (cached && isTokenValid(cached, refreshBufferMs)) {
|
|
126
|
+
return cached.user;
|
|
127
|
+
}
|
|
128
|
+
// Perform login to get fresh user info
|
|
129
|
+
await getSmartLeadToken(config);
|
|
130
|
+
const freshCached = tokenCache.get(cacheKey);
|
|
131
|
+
if (!freshCached) {
|
|
132
|
+
throw new Error('SmartLead auth: failed to obtain user info');
|
|
133
|
+
}
|
|
134
|
+
return freshCached.user;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Force clear cached token (e.g., on 401 error)
|
|
138
|
+
*/
|
|
139
|
+
function clearSmartLeadToken(email) {
|
|
140
|
+
tokenCache.delete(email.toLowerCase());
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Clear all cached tokens
|
|
144
|
+
*/
|
|
145
|
+
function clearAllSmartLeadTokens() {
|
|
146
|
+
tokenCache.clear();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get token cache stats (for debugging)
|
|
150
|
+
*/
|
|
151
|
+
function getSmartLeadTokenCacheStats() {
|
|
152
|
+
return {
|
|
153
|
+
cachedEmails: Array.from(tokenCache.keys()),
|
|
154
|
+
totalCached: tokenCache.size,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* });
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
|
-
import type { EnrichmentClientConfig, EnrichmentClient } from
|
|
29
|
+
import type { EnrichmentClientConfig, EnrichmentClient } from "./types";
|
|
30
30
|
/**
|
|
31
31
|
* Create an enrichment client with the given configuration
|
|
32
32
|
*
|
|
@@ -34,10 +34,11 @@ 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
|
|
38
|
-
export { isPersonalEmail, isBusinessEmail, isPersonalDomain, PERSONAL_DOMAINS, } from
|
|
39
|
-
export { isDisposableEmail, isDisposableDomain, DISPOSABLE_DOMAINS, } from
|
|
40
|
-
export { isValidEmailSyntax, isRoleAccount, asciiFold, cleanNamePart, hostnameFromUrl, extractLinkedInUsername, } from
|
|
41
|
-
export { verifyEmailMx } from
|
|
42
|
-
export { createConstructProvider, createLddProvider, createSmartProspectProvider, createHunterProvider, createApolloProvider, createDropcontactProvider, } from
|
|
43
|
-
export { enrichBusinessEmail, enrichBatch } from
|
|
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";
|
|
44
|
+
export { getSmartLeadToken, getSmartLeadUser, clearSmartLeadToken, clearAllSmartLeadTokens, getSmartLeadTokenCacheStats, type SmartLeadCredentials, type SmartLeadAuthConfig, type SmartLeadUser, type SmartLeadLoginResponse, } from "./auth";
|
package/dist/enrichment/index.js
CHANGED
|
@@ -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.getSmartLeadTokenCacheStats = exports.clearAllSmartLeadTokens = exports.clearSmartLeadToken = exports.getSmartLeadUser = exports.getSmartLeadToken = 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;
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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(
|
|
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(
|
|
79
|
+
providerFuncs.set("ldd", (0, ldd_1.createLddProvider)(providerConfigs.ldd));
|
|
80
80
|
}
|
|
81
81
|
if (providerConfigs.smartprospect) {
|
|
82
|
-
providerFuncs.set(
|
|
82
|
+
providerFuncs.set("smartprospect", (0, smartprospect_1.createSmartProspectProvider)(providerConfigs.smartprospect));
|
|
83
83
|
}
|
|
84
84
|
if (providerConfigs.hunter) {
|
|
85
|
-
providerFuncs.set(
|
|
85
|
+
providerFuncs.set("hunter", (0, hunter_1.createHunterProvider)(providerConfigs.hunter));
|
|
86
86
|
}
|
|
87
87
|
if (providerConfigs.apollo) {
|
|
88
|
-
providerFuncs.set(
|
|
88
|
+
providerFuncs.set("apollo", (0, apollo_1.createApolloProvider)(providerConfigs.apollo));
|
|
89
89
|
}
|
|
90
90
|
if (providerConfigs.dropcontact) {
|
|
91
|
-
providerFuncs.set(
|
|
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?.(
|
|
123
|
+
logger?.debug?.("enrichment.cache.hit", { cacheKey });
|
|
124
124
|
return cached;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -176,10 +176,16 @@ function buildCacheKey(candidate) {
|
|
|
176
176
|
}
|
|
177
177
|
else {
|
|
178
178
|
// 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 ||
|
|
182
|
-
|
|
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 ||
|
|
182
|
+
candidate.companyDomain ||
|
|
183
|
+
candidate.company_domain ||
|
|
184
|
+
"";
|
|
185
|
+
const company = candidate.company ||
|
|
186
|
+
candidate.currentCompany ||
|
|
187
|
+
candidate.organization ||
|
|
188
|
+
"";
|
|
183
189
|
if (firstName && (domain || company)) {
|
|
184
190
|
parts.push(`name:${firstName.toLowerCase()}`);
|
|
185
191
|
if (lastName)
|
|
@@ -193,7 +199,7 @@ function buildCacheKey(candidate) {
|
|
|
193
199
|
if (parts.length === 0) {
|
|
194
200
|
return null;
|
|
195
201
|
}
|
|
196
|
-
return parts.join(
|
|
202
|
+
return parts.join("|");
|
|
197
203
|
}
|
|
198
204
|
// Re-export types
|
|
199
205
|
__exportStar(require("./types"), exports);
|
|
@@ -229,3 +235,10 @@ Object.defineProperty(exports, "createDropcontactProvider", { enumerable: true,
|
|
|
229
235
|
var orchestrator_2 = require("./orchestrator");
|
|
230
236
|
Object.defineProperty(exports, "enrichBusinessEmail", { enumerable: true, get: function () { return orchestrator_2.enrichBusinessEmail; } });
|
|
231
237
|
Object.defineProperty(exports, "enrichBatch", { enumerable: true, get: function () { return orchestrator_2.enrichBatch; } });
|
|
238
|
+
// Re-export auth utilities (for advanced usage)
|
|
239
|
+
var auth_1 = require("./auth");
|
|
240
|
+
Object.defineProperty(exports, "getSmartLeadToken", { enumerable: true, get: function () { return auth_1.getSmartLeadToken; } });
|
|
241
|
+
Object.defineProperty(exports, "getSmartLeadUser", { enumerable: true, get: function () { return auth_1.getSmartLeadUser; } });
|
|
242
|
+
Object.defineProperty(exports, "clearSmartLeadToken", { enumerable: true, get: function () { return auth_1.clearSmartLeadToken; } });
|
|
243
|
+
Object.defineProperty(exports, "clearAllSmartLeadTokens", { enumerable: true, get: function () { return auth_1.clearAllSmartLeadTokens; } });
|
|
244
|
+
Object.defineProperty(exports, "getSmartLeadTokenCacheStats", { enumerable: true, get: function () { return auth_1.getSmartLeadTokenCacheStats; } });
|
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Smartlead's prospect database - a REVERSE-ENGINEERED private API.
|
|
5
5
|
* Two-phase process: search (free) then fetch (costs credits).
|
|
6
|
+
*
|
|
7
|
+
* Supports two authentication methods:
|
|
8
|
+
* 1. Direct token: Pass `apiToken` directly (for pre-authenticated scenarios)
|
|
9
|
+
* 2. Credentials: Pass `email` and `password` for automatic login with token caching
|
|
6
10
|
*/
|
|
7
|
-
import type { EnrichmentCandidate, ProviderResult, SmartProspectConfig } from
|
|
11
|
+
import type { EnrichmentCandidate, ProviderResult, SmartProspectConfig } from "../types";
|
|
8
12
|
/**
|
|
9
13
|
* Create the SmartProspect provider function
|
|
14
|
+
*
|
|
15
|
+
* Supports two auth methods:
|
|
16
|
+
* 1. Direct token: Pass `apiToken` in config
|
|
17
|
+
* 2. Credentials: Pass `email` and `password` in config for auto-login
|
|
10
18
|
*/
|
|
11
19
|
export declare function createSmartProspectProvider(config: SmartProspectConfig): (candidate: EnrichmentCandidate) => Promise<ProviderResult | null>;
|
|
@@ -4,10 +4,15 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Smartlead's prospect database - a REVERSE-ENGINEERED private API.
|
|
6
6
|
* Two-phase process: search (free) then fetch (costs credits).
|
|
7
|
+
*
|
|
8
|
+
* Supports two authentication methods:
|
|
9
|
+
* 1. Direct token: Pass `apiToken` directly (for pre-authenticated scenarios)
|
|
10
|
+
* 2. Credentials: Pass `email` and `password` for automatic login with token caching
|
|
7
11
|
*/
|
|
8
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
13
|
exports.createSmartProspectProvider = createSmartProspectProvider;
|
|
10
|
-
const
|
|
14
|
+
const smartlead_auth_1 = require("../auth/smartlead-auth");
|
|
15
|
+
const DEFAULT_API_URL = "https://prospect-api.smartlead.ai/api/search-email-leads";
|
|
11
16
|
/**
|
|
12
17
|
* Delay helper for retry logic
|
|
13
18
|
*/
|
|
@@ -28,7 +33,7 @@ async function requestWithRetry(url, options, retries = 2, backoffMs = 300) {
|
|
|
28
33
|
continue;
|
|
29
34
|
}
|
|
30
35
|
if (!res.ok) {
|
|
31
|
-
const errorText = await res.text().catch(() =>
|
|
36
|
+
const errorText = await res.text().catch(() => "");
|
|
32
37
|
throw new Error(`SmartProspect API error: ${res.status} - ${errorText}`);
|
|
33
38
|
}
|
|
34
39
|
return (await res.json());
|
|
@@ -41,7 +46,7 @@ async function requestWithRetry(url, options, retries = 2, backoffMs = 300) {
|
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
|
-
throw lastErr ?? new Error(
|
|
49
|
+
throw lastErr ?? new Error("smartprospect_http_error");
|
|
45
50
|
}
|
|
46
51
|
/**
|
|
47
52
|
* Calculate match score between search input and contact result
|
|
@@ -49,30 +54,33 @@ async function requestWithRetry(url, options, retries = 2, backoffMs = 300) {
|
|
|
49
54
|
function calculateMatchScore(contact, searchName, company, title) {
|
|
50
55
|
let score = 0;
|
|
51
56
|
// Name match scoring (0-50 points)
|
|
52
|
-
const contactName = contact.fullName?.toLowerCase() ||
|
|
57
|
+
const contactName = contact.fullName?.toLowerCase() || "";
|
|
53
58
|
const searchNameLower = searchName.toLowerCase();
|
|
54
59
|
if (contactName === searchNameLower) {
|
|
55
60
|
score += 50; // Exact match
|
|
56
61
|
}
|
|
57
|
-
else if (contactName.includes(searchNameLower) ||
|
|
62
|
+
else if (contactName.includes(searchNameLower) ||
|
|
63
|
+
searchNameLower.includes(contactName)) {
|
|
58
64
|
score += 30; // Partial match
|
|
59
65
|
}
|
|
60
66
|
// Company match scoring (0-30 points)
|
|
61
67
|
if (company) {
|
|
62
|
-
const contactCompany = contact.company?.name?.toLowerCase() ||
|
|
68
|
+
const contactCompany = contact.company?.name?.toLowerCase() || "";
|
|
63
69
|
const searchCompany = company.toLowerCase();
|
|
64
70
|
if (contactCompany === searchCompany) {
|
|
65
71
|
score += 30; // Exact match
|
|
66
72
|
}
|
|
67
|
-
else if (contactCompany.includes(searchCompany) ||
|
|
73
|
+
else if (contactCompany.includes(searchCompany) ||
|
|
74
|
+
searchCompany.includes(contactCompany)) {
|
|
68
75
|
score += 15; // Partial match
|
|
69
76
|
}
|
|
70
77
|
}
|
|
71
78
|
// Title match scoring (0-10 points)
|
|
72
79
|
if (title) {
|
|
73
|
-
const contactTitle = contact.title?.toLowerCase() ||
|
|
80
|
+
const contactTitle = contact.title?.toLowerCase() || "";
|
|
74
81
|
const searchTitle = title.toLowerCase();
|
|
75
|
-
if (contactTitle.includes(searchTitle) ||
|
|
82
|
+
if (contactTitle.includes(searchTitle) ||
|
|
83
|
+
searchTitle.includes(contactTitle)) {
|
|
76
84
|
score += 10;
|
|
77
85
|
}
|
|
78
86
|
}
|
|
@@ -89,37 +97,72 @@ function extractNames(candidate) {
|
|
|
89
97
|
const firstName = candidate.firstName ||
|
|
90
98
|
candidate.first_name ||
|
|
91
99
|
candidate.first ||
|
|
92
|
-
candidate.name?.split(
|
|
93
|
-
|
|
100
|
+
candidate.name?.split(" ")?.[0] ||
|
|
101
|
+
"";
|
|
94
102
|
const lastName = candidate.lastName ||
|
|
95
103
|
candidate.last_name ||
|
|
96
104
|
candidate.last ||
|
|
97
|
-
candidate.name?.split(
|
|
98
|
-
|
|
105
|
+
candidate.name?.split(" ")?.slice(1).join(" ") ||
|
|
106
|
+
"";
|
|
99
107
|
return { firstName, lastName };
|
|
100
108
|
}
|
|
101
109
|
/**
|
|
102
110
|
* Create the SmartProspect provider function
|
|
111
|
+
*
|
|
112
|
+
* Supports two auth methods:
|
|
113
|
+
* 1. Direct token: Pass `apiToken` in config
|
|
114
|
+
* 2. Credentials: Pass `email` and `password` in config for auto-login
|
|
103
115
|
*/
|
|
104
116
|
function createSmartProspectProvider(config) {
|
|
105
|
-
const { apiToken, apiUrl = DEFAULT_API_URL } = config;
|
|
106
|
-
if
|
|
117
|
+
const { apiToken, email, password, apiUrl = DEFAULT_API_URL, loginUrl, eagerInit = true, } = config;
|
|
118
|
+
// Check if we have valid auth config
|
|
119
|
+
const hasDirectToken = !!apiToken;
|
|
120
|
+
const hasCredentials = !!email && !!password;
|
|
121
|
+
if (!hasDirectToken && !hasCredentials) {
|
|
107
122
|
// Return a no-op provider if not configured
|
|
108
123
|
const noopProvider = async () => null;
|
|
109
|
-
noopProvider.__name =
|
|
124
|
+
noopProvider.__name = "smartprospect";
|
|
110
125
|
return noopProvider;
|
|
111
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Get the current auth token (either direct or via login)
|
|
129
|
+
*/
|
|
130
|
+
async function getAuthToken() {
|
|
131
|
+
if (hasDirectToken) {
|
|
132
|
+
return apiToken;
|
|
133
|
+
}
|
|
134
|
+
// Use credentials-based auth with token caching
|
|
135
|
+
return (0, smartlead_auth_1.getSmartLeadToken)({
|
|
136
|
+
credentials: { email: email, password: password },
|
|
137
|
+
loginUrl,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// Eager initialization: pre-fetch token so it's ready for first request
|
|
141
|
+
if (eagerInit && hasCredentials) {
|
|
142
|
+
// Fire and forget - don't block provider creation
|
|
143
|
+
getAuthToken().catch(() => {
|
|
144
|
+
// Silently ignore errors during eager init - will retry on first request
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handle 401 errors by clearing cached token
|
|
149
|
+
*/
|
|
150
|
+
async function handleAuthError() {
|
|
151
|
+
if (hasCredentials) {
|
|
152
|
+
(0, smartlead_auth_1.clearSmartLeadToken)(email);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
112
155
|
/**
|
|
113
156
|
* Search for contacts matching filters (FREE - no credits used)
|
|
114
157
|
*/
|
|
115
158
|
async function searchContacts(filters) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
method:
|
|
159
|
+
const makeRequest = async (token) => {
|
|
160
|
+
return requestWithRetry(`${apiUrl}/search-contacts`, {
|
|
161
|
+
method: "POST",
|
|
119
162
|
headers: {
|
|
120
|
-
Authorization: `Bearer ${
|
|
121
|
-
|
|
122
|
-
Accept:
|
|
163
|
+
Authorization: `Bearer ${token}`,
|
|
164
|
+
"Content-Type": "application/json",
|
|
165
|
+
Accept: "application/json",
|
|
123
166
|
},
|
|
124
167
|
body: JSON.stringify({
|
|
125
168
|
...filters,
|
|
@@ -128,12 +171,28 @@ function createSmartProspectProvider(config) {
|
|
|
128
171
|
titleExactMatch: filters.titleExactMatch ?? false,
|
|
129
172
|
}),
|
|
130
173
|
});
|
|
131
|
-
|
|
174
|
+
};
|
|
175
|
+
try {
|
|
176
|
+
const token = await getAuthToken();
|
|
177
|
+
return await makeRequest(token);
|
|
132
178
|
}
|
|
133
|
-
catch {
|
|
179
|
+
catch (err) {
|
|
180
|
+
// On 401, clear token and retry once with fresh token
|
|
181
|
+
if (err instanceof Error &&
|
|
182
|
+
err.message.includes("401") &&
|
|
183
|
+
hasCredentials) {
|
|
184
|
+
await handleAuthError();
|
|
185
|
+
try {
|
|
186
|
+
const freshToken = await getAuthToken();
|
|
187
|
+
return await makeRequest(freshToken);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Retry failed too
|
|
191
|
+
}
|
|
192
|
+
}
|
|
134
193
|
return {
|
|
135
194
|
success: false,
|
|
136
|
-
message:
|
|
195
|
+
message: "Search failed",
|
|
137
196
|
data: { list: [], total_count: 0 },
|
|
138
197
|
};
|
|
139
198
|
}
|
|
@@ -142,22 +201,38 @@ function createSmartProspectProvider(config) {
|
|
|
142
201
|
* Fetch/enrich emails for specific contact IDs (COSTS CREDITS)
|
|
143
202
|
*/
|
|
144
203
|
async function fetchContacts(contactIds) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
method:
|
|
204
|
+
const makeRequest = async (token) => {
|
|
205
|
+
return requestWithRetry(`${apiUrl}/fetch-contacts`, {
|
|
206
|
+
method: "POST",
|
|
148
207
|
headers: {
|
|
149
|
-
Authorization: `Bearer ${
|
|
150
|
-
|
|
151
|
-
Accept:
|
|
208
|
+
Authorization: `Bearer ${token}`,
|
|
209
|
+
"Content-Type": "application/json",
|
|
210
|
+
Accept: "application/json",
|
|
152
211
|
},
|
|
153
212
|
body: JSON.stringify({ contactIds }),
|
|
154
213
|
});
|
|
155
|
-
|
|
214
|
+
};
|
|
215
|
+
try {
|
|
216
|
+
const token = await getAuthToken();
|
|
217
|
+
return await makeRequest(token);
|
|
156
218
|
}
|
|
157
|
-
catch {
|
|
219
|
+
catch (err) {
|
|
220
|
+
// On 401, clear token and retry once with fresh token
|
|
221
|
+
if (err instanceof Error &&
|
|
222
|
+
err.message.includes("401") &&
|
|
223
|
+
hasCredentials) {
|
|
224
|
+
await handleAuthError();
|
|
225
|
+
try {
|
|
226
|
+
const freshToken = await getAuthToken();
|
|
227
|
+
return await makeRequest(freshToken);
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// Retry failed too
|
|
231
|
+
}
|
|
232
|
+
}
|
|
158
233
|
return {
|
|
159
234
|
success: false,
|
|
160
|
-
message:
|
|
235
|
+
message: "Fetch failed",
|
|
161
236
|
data: {
|
|
162
237
|
list: [],
|
|
163
238
|
total_count: 0,
|
|
@@ -183,9 +258,18 @@ function createSmartProspectProvider(config) {
|
|
|
183
258
|
return null; // Minimum requirement
|
|
184
259
|
}
|
|
185
260
|
const fullName = `${firstName} ${lastName}`.trim();
|
|
186
|
-
const company = candidate.company ||
|
|
187
|
-
|
|
188
|
-
|
|
261
|
+
const company = candidate.company ||
|
|
262
|
+
candidate.currentCompany ||
|
|
263
|
+
candidate.organization ||
|
|
264
|
+
undefined;
|
|
265
|
+
const title = candidate.title ||
|
|
266
|
+
candidate.currentRole ||
|
|
267
|
+
candidate.current_role ||
|
|
268
|
+
undefined;
|
|
269
|
+
const domain = candidate.domain ||
|
|
270
|
+
candidate.companyDomain ||
|
|
271
|
+
candidate.company_domain ||
|
|
272
|
+
undefined;
|
|
189
273
|
// Build search filters
|
|
190
274
|
const filters = {
|
|
191
275
|
name: [fullName],
|
|
@@ -227,8 +311,8 @@ function createSmartProspectProvider(config) {
|
|
|
227
311
|
return null;
|
|
228
312
|
}
|
|
229
313
|
// Calculate verification confidence
|
|
230
|
-
const isVerified = enrichedContact.verificationStatus ===
|
|
231
|
-
const isCatchAll = enrichedContact.verificationStatus ===
|
|
314
|
+
const isVerified = enrichedContact.verificationStatus === "valid";
|
|
315
|
+
const isCatchAll = enrichedContact.verificationStatus === "catch_all";
|
|
232
316
|
const deliverability = enrichedContact.emailDeliverability || 0;
|
|
233
317
|
let confidence = deliverability * 100;
|
|
234
318
|
if (isVerified) {
|
|
@@ -244,6 +328,6 @@ function createSmartProspectProvider(config) {
|
|
|
244
328
|
};
|
|
245
329
|
}
|
|
246
330
|
// Mark provider name for orchestrator
|
|
247
|
-
fetchEmail.__name =
|
|
331
|
+
fetchEmail.__name = "smartprospect";
|
|
248
332
|
return fetchEmail;
|
|
249
333
|
}
|
|
@@ -78,10 +78,24 @@ export interface ApolloConfig {
|
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
80
|
* SmartProspect/Smartlead provider configuration
|
|
81
|
+
*
|
|
82
|
+
* Supports two auth methods:
|
|
83
|
+
* 1. Direct token: Pass `apiToken` directly
|
|
84
|
+
* 2. Credentials: Pass `email` and `password` for auto-login with token caching
|
|
81
85
|
*/
|
|
82
86
|
export interface SmartProspectConfig {
|
|
83
|
-
|
|
87
|
+
/** Direct API/JWT token (if you already have one) */
|
|
88
|
+
apiToken?: string;
|
|
89
|
+
/** SmartLead account email (for credentials-based auth) */
|
|
90
|
+
email?: string;
|
|
91
|
+
/** SmartLead account password (for credentials-based auth) */
|
|
92
|
+
password?: string;
|
|
93
|
+
/** API URL override (default: https://prospect-api.smartlead.ai/api/search-email-leads) */
|
|
84
94
|
apiUrl?: string;
|
|
95
|
+
/** Login URL override (default: https://server.smartlead.ai/api/auth/login) */
|
|
96
|
+
loginUrl?: string;
|
|
97
|
+
/** Pre-fetch token on client creation (default: true) - ensures token is ready for first request */
|
|
98
|
+
eagerInit?: boolean;
|
|
85
99
|
}
|
|
86
100
|
/**
|
|
87
101
|
* LinkedIn Data Dump provider configuration
|
|
@@ -189,7 +203,7 @@ export interface EnrichmentClient {
|
|
|
189
203
|
/**
|
|
190
204
|
* Available provider names
|
|
191
205
|
*/
|
|
192
|
-
export type ProviderName =
|
|
206
|
+
export type ProviderName = "construct" | "ldd" | "smartprospect" | "hunter" | "apollo" | "dropcontact";
|
|
193
207
|
/**
|
|
194
208
|
* Default provider order
|
|
195
209
|
*/
|
|
@@ -207,7 +221,7 @@ export interface VerificationResult {
|
|
|
207
221
|
/** Confidence score 0-100 */
|
|
208
222
|
confidence: number;
|
|
209
223
|
/** Reason for the result */
|
|
210
|
-
reason?:
|
|
224
|
+
reason?: "valid" | "invalid" | "syntax" | "mx_missing" | "disposable" | "role_account" | "catch_all" | "timeout" | "error";
|
|
211
225
|
/** Whether this is a catch-all domain */
|
|
212
226
|
isCatchAll: boolean;
|
|
213
227
|
/** Whether this is a role account (info@, support@, etc.) */
|
package/dist/enrichment/types.js
CHANGED
|
@@ -11,12 +11,12 @@ exports.PROVIDER_COSTS = exports.DEFAULT_PROVIDER_ORDER = void 0;
|
|
|
11
11
|
* Default provider order
|
|
12
12
|
*/
|
|
13
13
|
exports.DEFAULT_PROVIDER_ORDER = [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
"construct",
|
|
15
|
+
"ldd",
|
|
16
|
+
"smartprospect",
|
|
17
|
+
"hunter",
|
|
18
|
+
"apollo",
|
|
19
|
+
"dropcontact",
|
|
20
20
|
];
|
|
21
21
|
/**
|
|
22
22
|
* Provider costs in USD per lookup
|
package/dist/index.d.ts
CHANGED
|
@@ -14,4 +14,5 @@ export type { RequestHistoryEntry } from "./utils/request-history";
|
|
|
14
14
|
export * from "./constants";
|
|
15
15
|
export { createEnrichmentClient } from "./enrichment";
|
|
16
16
|
export type { CanonicalEmail, EnrichmentCandidate, ProviderResult, ProviderFunc, ProviderName, EnrichmentClientConfig, EnrichmentClient, ProvidersConfig, EnrichmentOptions, BatchEnrichmentOptions, HunterConfig, ApolloConfig, SmartProspectConfig, LddConfig, DropcontactConfig, ConstructConfig, CacheAdapter, CostCallback, EnrichmentLogger, VerificationResult, SmartProspectContact, SmartProspectSearchFilters, LddProfileData, LddApiResponse, } from "./enrichment";
|
|
17
|
-
export { isPersonalEmail, isBusinessEmail, isPersonalDomain, isDisposableEmail, isDisposableDomain, isValidEmailSyntax, isRoleAccount, verifyEmailMx, PERSONAL_DOMAINS, DISPOSABLE_DOMAINS, DEFAULT_PROVIDER_ORDER, PROVIDER_COSTS, } from "./enrichment";
|
|
17
|
+
export { isPersonalEmail, isBusinessEmail, isPersonalDomain, isDisposableEmail, isDisposableDomain, isValidEmailSyntax, isRoleAccount, verifyEmailMx, PERSONAL_DOMAINS, DISPOSABLE_DOMAINS, DEFAULT_PROVIDER_ORDER, PROVIDER_COSTS, getSmartLeadToken, getSmartLeadUser, clearSmartLeadToken, clearAllSmartLeadTokens, getSmartLeadTokenCacheStats, } from "./enrichment";
|
|
18
|
+
export type { SmartLeadCredentials, SmartLeadAuthConfig, SmartLeadUser, SmartLeadLoginResponse, } from "./enrichment";
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PROVIDER_COSTS = exports.DEFAULT_PROVIDER_ORDER = exports.DISPOSABLE_DOMAINS = exports.PERSONAL_DOMAINS = exports.verifyEmailMx = exports.isRoleAccount = exports.isValidEmailSyntax = exports.isDisposableDomain = exports.isDisposableEmail = exports.isPersonalDomain = exports.isBusinessEmail = exports.isPersonalEmail = exports.createEnrichmentClient = exports.clearRequestHistory = exports.getRequestHistory = exports.parseSalesSearchResults = exports.parseFullProfile = exports.LinkedInClientError = exports.getConfig = exports.initializeLinkedInClient = void 0;
|
|
17
|
+
exports.getSmartLeadTokenCacheStats = exports.clearAllSmartLeadTokens = exports.clearSmartLeadToken = exports.getSmartLeadUser = exports.getSmartLeadToken = exports.PROVIDER_COSTS = exports.DEFAULT_PROVIDER_ORDER = exports.DISPOSABLE_DOMAINS = exports.PERSONAL_DOMAINS = exports.verifyEmailMx = exports.isRoleAccount = exports.isValidEmailSyntax = exports.isDisposableDomain = exports.isDisposableEmail = exports.isPersonalDomain = exports.isBusinessEmail = exports.isPersonalEmail = exports.createEnrichmentClient = exports.clearRequestHistory = exports.getRequestHistory = exports.parseSalesSearchResults = exports.parseFullProfile = exports.LinkedInClientError = exports.getConfig = exports.initializeLinkedInClient = void 0;
|
|
18
18
|
var config_1 = require("./config");
|
|
19
19
|
Object.defineProperty(exports, "initializeLinkedInClient", { enumerable: true, get: function () { return config_1.initializeLinkedInClient; } });
|
|
20
20
|
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_1.getConfig; } });
|
|
@@ -52,3 +52,9 @@ Object.defineProperty(exports, "PERSONAL_DOMAINS", { enumerable: true, get: func
|
|
|
52
52
|
Object.defineProperty(exports, "DISPOSABLE_DOMAINS", { enumerable: true, get: function () { return enrichment_2.DISPOSABLE_DOMAINS; } });
|
|
53
53
|
Object.defineProperty(exports, "DEFAULT_PROVIDER_ORDER", { enumerable: true, get: function () { return enrichment_2.DEFAULT_PROVIDER_ORDER; } });
|
|
54
54
|
Object.defineProperty(exports, "PROVIDER_COSTS", { enumerable: true, get: function () { return enrichment_2.PROVIDER_COSTS; } });
|
|
55
|
+
// SmartLead Auth
|
|
56
|
+
Object.defineProperty(exports, "getSmartLeadToken", { enumerable: true, get: function () { return enrichment_2.getSmartLeadToken; } });
|
|
57
|
+
Object.defineProperty(exports, "getSmartLeadUser", { enumerable: true, get: function () { return enrichment_2.getSmartLeadUser; } });
|
|
58
|
+
Object.defineProperty(exports, "clearSmartLeadToken", { enumerable: true, get: function () { return enrichment_2.clearSmartLeadToken; } });
|
|
59
|
+
Object.defineProperty(exports, "clearAllSmartLeadTokens", { enumerable: true, get: function () { return enrichment_2.clearAllSmartLeadTokens; } });
|
|
60
|
+
Object.defineProperty(exports, "getSmartLeadTokenCacheStats", { enumerable: true, get: function () { return enrichment_2.getSmartLeadTokenCacheStats; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkedin-secret-sauce",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Private LinkedIn Sales Navigator client with automatic cookie management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,20 +10,6 @@
|
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"registry": "https://registry.npmjs.org/"
|
|
12
12
|
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
"dev:playground": "pnpm -C apps/playground dev",
|
|
15
|
-
"search": "node scripts/rg-fast.mjs",
|
|
16
|
-
"rg:fast": "node scripts/rg-fast.mjs",
|
|
17
|
-
"build": "tsc -p tsconfig.json",
|
|
18
|
-
"lint": "eslint \"src/**/*.ts\" --max-warnings=0",
|
|
19
|
-
"lint:fix": "eslint \"src/**/*.ts\" --fix",
|
|
20
|
-
"dev": "tsc -w -p tsconfig.json",
|
|
21
|
-
"test": "vitest run",
|
|
22
|
-
"prepublishOnly": "npm run build",
|
|
23
|
-
"release:patch": "npm version patch && git push --follow-tags",
|
|
24
|
-
"release:minor": "npm version minor && git push --follow-tags",
|
|
25
|
-
"release:major": "npm version major && git push --follow-tags"
|
|
26
|
-
},
|
|
27
13
|
"keywords": [
|
|
28
14
|
"linkedin",
|
|
29
15
|
"sales-navigator",
|
|
@@ -53,5 +39,18 @@
|
|
|
53
39
|
"husky": "^9.0.11",
|
|
54
40
|
"typescript": "^5.9.3",
|
|
55
41
|
"vitest": "^1.6.0"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"dev:playground": "pnpm -C apps/playground dev",
|
|
45
|
+
"search": "node scripts/rg-fast.mjs",
|
|
46
|
+
"rg:fast": "node scripts/rg-fast.mjs",
|
|
47
|
+
"build": "tsc -p tsconfig.json",
|
|
48
|
+
"lint": "eslint \"src/**/*.ts\" --max-warnings=0",
|
|
49
|
+
"lint:fix": "eslint \"src/**/*.ts\" --fix",
|
|
50
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
51
|
+
"test": "vitest run",
|
|
52
|
+
"release:patch": "npm version patch && git push --follow-tags",
|
|
53
|
+
"release:minor": "npm version minor && git push --follow-tags",
|
|
54
|
+
"release:major": "npm version major && git push --follow-tags"
|
|
56
55
|
}
|
|
57
|
-
}
|
|
56
|
+
}
|