orangeslice 1.7.18 → 1.7.20

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/api.js CHANGED
@@ -14,6 +14,17 @@ const DEFAULT_POLL_INTERVAL_MS = 1000;
14
14
  function sleep(ms) {
15
15
  return new Promise((resolve) => setTimeout(resolve, ms));
16
16
  }
17
+ async function readResponseBody(res) {
18
+ const text = await res.text();
19
+ if (!text)
20
+ return null;
21
+ try {
22
+ return JSON.parse(text);
23
+ }
24
+ catch {
25
+ return text;
26
+ }
27
+ }
17
28
  function asErrorMessage(body) {
18
29
  if (!body || typeof body !== "object")
19
30
  return undefined;
@@ -74,7 +85,7 @@ async function pollUntilComplete(baseUrl, functionId, pending) {
74
85
  while (Date.now() < timeoutAt) {
75
86
  await sleep(pollAfterMs);
76
87
  const res = await fetch(pollUrl, { method: "GET", headers: { "Content-Type": "application/json" } });
77
- const data = (await res.json());
88
+ const data = await readResponseBody(res);
78
89
  if (isPendingResponse(data) || res.status === 202) {
79
90
  const next = data.pollAfterMs;
80
91
  pollAfterMs = typeof next === "number" && next > 0 ? next : DEFAULT_POLL_INTERVAL_MS;
@@ -103,16 +114,11 @@ async function post(functionId, payload, options = {}) {
103
114
  });
104
115
  if (!res.ok) {
105
116
  let message = `${res.status}`;
106
- try {
107
- const data = (await res.json());
108
- message = asErrorMessage(data) || JSON.stringify(data);
109
- }
110
- catch {
111
- message = await res.text();
112
- }
117
+ const data = await readResponseBody(res);
118
+ message = asErrorMessage(data) || (typeof data === "string" ? data : JSON.stringify(data));
113
119
  throw new Error(`[orangeslice] ${functionId}: ${res.status} ${message}`);
114
120
  }
115
- const data = (await res.json());
121
+ const data = await readResponseBody(res);
116
122
  if (isPendingResponse(data)) {
117
123
  return pollUntilComplete(baseUrl, functionId, data);
118
124
  }
package/dist/expansion.js CHANGED
@@ -22,15 +22,8 @@ function extractLinkedinUsername(url) {
22
22
  const slug = match[1].trim();
23
23
  return slug.length > 0 ? slug : undefined;
24
24
  }
25
- function extractLinkedinCompanySlug(url) {
26
- const match = url.match(/linkedin\.com\/company\/([^/?#]+)/i);
27
- if (!match?.[1])
28
- return undefined;
29
- const slug = match[1].trim().toLowerCase();
30
- return slug.length > 0 ? slug : undefined;
31
- }
32
25
  async function personLinkedinFindUrl(params) {
33
- return (0, api_1.post)("linkedin/find-profile-url", params, { direct: true });
26
+ return (0, api_1.post)("linkedin/find-profile-url", params);
34
27
  }
35
28
  async function personLinkedinEnrich(params) {
36
29
  const url = typeof params.url === "string" ? params.url.trim() : "";
@@ -81,7 +74,22 @@ async function personContactGet(params) {
81
74
  return (0, api_1.post)("contact", params);
82
75
  }
83
76
  async function companyLinkedinFindUrl(params) {
84
- return (0, api_1.post)("find-linkedin-company-url", params, { direct: true });
77
+ const companyName = typeof params.companyName === "string" && params.companyName.trim().length > 0
78
+ ? params.companyName.trim()
79
+ : typeof params.name === "string" && params.name.trim().length > 0
80
+ ? params.name.trim()
81
+ : undefined;
82
+ const website = typeof params.website === "string" && params.website.trim().length > 0
83
+ ? params.website.trim()
84
+ : typeof params.domain === "string" && params.domain.trim().length > 0
85
+ ? params.domain.trim()
86
+ : undefined;
87
+ const payload = {
88
+ ...params,
89
+ ...(companyName ? { companyName } : {}),
90
+ ...(website ? { website } : {}),
91
+ };
92
+ return (0, api_1.post)("find-linkedin-company-url", payload);
85
93
  }
86
94
  async function companyLinkedinEnrich(params) {
87
95
  const shorthand = typeof params.shorthand === "string" ? params.shorthand.trim() : "";
@@ -106,78 +114,9 @@ async function companyLinkedinEnrich(params) {
106
114
  return data.rows?.[0] ?? null;
107
115
  }
108
116
  async function companyGetEmployeesFromLinkedin(params) {
109
- const linkedinUrl = typeof params.linkedinUrl === "string" ? params.linkedinUrl.trim() : "";
110
- const companySlugInput = typeof params.companySlug === "string" ? params.companySlug.trim().toLowerCase() : "";
111
- const companySlug = companySlugInput || (linkedinUrl ? (extractLinkedinCompanySlug(linkedinUrl) ?? "") : "");
112
- const titleVariations = Array.isArray(params.titleVariations)
113
- ? params.titleVariations
114
- .filter((v) => typeof v === "string" && v.trim().length > 0)
115
- .map((v) => v.trim())
116
- : [];
117
- const titleSqlFilterRaw = typeof params.titleSqlFilter === "string" ? params.titleSqlFilter.trim() : "";
118
- const titleSqlFilter = titleSqlFilterRaw.replace(/\bpos\./g, "lp.");
119
- const limit = typeof params.limit === "number" && Number.isFinite(params.limit)
120
- ? Math.max(1, Math.min(200, Math.floor(params.limit)))
121
- : 50;
122
- const offset = typeof params.offset === "number" && Number.isFinite(params.offset) && params.offset >= 0
123
- ? Math.floor(params.offset)
124
- : 0;
125
- const minConnections = typeof params.minConnections === "number" && Number.isFinite(params.minConnections)
126
- ? Math.max(0, Math.floor(params.minConnections))
127
- : 20;
128
- const usOnly = params.usOnly === undefined ? true : params.usOnly === true;
129
- if (!companySlug) {
130
- throw new Error("[orangeslice] company.getEmployeesFromLinkedin: provide linkedinUrl or companySlug");
131
- }
132
- const filters = [
133
- `lp.linkedin_company_id = tc.linkedin_company_id`,
134
- `COALESCE(lp.connections, 0) >= ${minConnections}`,
135
- ];
136
- if (usOnly)
137
- filters.push(`COALESCE(lp.location_country_code, '') = 'US'`);
138
- if (titleSqlFilter) {
139
- filters.push(`(${titleSqlFilter})`);
140
- }
141
- else if (titleVariations.length > 0) {
142
- const or = titleVariations
143
- .map((title) => `lower(COALESCE(lp.title, '')) LIKE ${sqlString(`%${title.toLowerCase()}%`)}`)
144
- .join(" OR ");
145
- filters.push(`(${or})`);
146
- }
147
- const sql = `WITH tc AS (
148
- SELECT linkedin_company_id
149
- FROM linkedin_company_slug
150
- WHERE slug_key64 = key64(${sqlString(companySlug)})
151
- LIMIT 1
152
- )
153
- SELECT
154
- lp.first_name AS lp_first_name,
155
- lp.last_name AS lp_last_name,
156
- lp.formatted_name AS lp_formatted_name,
157
- lp.headline AS lp_headline,
158
- lp.location_name AS lp_location_name,
159
- COALESCE(lp.public_profile_url, lp.standard_profile_url) AS lp_public_profile_url,
160
- lp.title AS lp_title,
161
- lp.org AS lp_company_name,
162
- lp.connections AS lp_connections,
163
- COUNT(*) OVER() AS _total
164
- FROM linkedin_profile lp
165
- JOIN tc ON true
166
- WHERE ${filters.join(" AND ")}
167
- ORDER BY lp.connections DESC NULLS LAST, lp.updated_at DESC NULLS LAST
168
- LIMIT ${limit} OFFSET ${offset}`;
169
- const data = await (0, api_1.post)("b2b", { sql }, { direct: true });
170
- const rows = data.rows ?? [];
171
- const total = rows.length > 0 ? Number(rows[0]._total ?? 0) : 0;
172
- const employees = rows.map((row) => {
173
- const { _total, ...rest } = row;
174
- return rest;
175
- });
176
- return {
177
- employees,
178
- nextPage: employees.length === limit && offset + limit < total ? offset + limit : null,
179
- totalResults: total,
180
- };
117
+ // Route through the dedicated backend function, which uses optimized query plans.
118
+ // The raw SQL fallback can hit 60s statement timeouts on large companies.
119
+ return (0, api_1.post)("b2b-get-employees-for-company", params);
181
120
  }
182
121
  async function geoParseAddress(params) {
183
122
  return (0, api_1.post)("geo", params);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orangeslice",
3
- "version": "1.7.18",
3
+ "version": "1.7.20",
4
4
  "description": "B2B LinkedIn database prospector - 1.15B profiles, 85M companies",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",