orangeslice 2.1.0 → 2.1.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.
- package/README.md +10 -0
- package/dist/cli.js +34 -2
- package/dist/crunchbase.d.ts +10 -0
- package/dist/crunchbase.js +13 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -1
- package/docs/integrations/gmail/index.md +1 -1
- package/docs/integrations/gmail/sendEmail.md +13 -13
- package/docs/prospecting/index.md +24 -16
- package/docs/services/company/linkedin/search.md +32 -0
- package/docs/services/crunchbase/search.md +337 -0
- package/docs/services/index.md +1 -1
- package/docs/services/person/linkedin/search.md +32 -0
- package/package.json +1 -1
- package/docs/providers/predictleads/openapi.json +0 -13209
- package/docs/services/healthcare/npi.md +0 -190
package/README.md
CHANGED
|
@@ -64,11 +64,21 @@ const [companies, searchPage, ai] = await Promise.all([
|
|
|
64
64
|
}
|
|
65
65
|
})
|
|
66
66
|
]);
|
|
67
|
+
|
|
68
|
+
const startups = await services.crunchbase.search({
|
|
69
|
+
sql: `
|
|
70
|
+
SELECT name, website_url, linkedin_url
|
|
71
|
+
FROM public.crunchbase_scraper_lean
|
|
72
|
+
WHERE operating_status = 'Active'
|
|
73
|
+
LIMIT 10
|
|
74
|
+
`
|
|
75
|
+
});
|
|
67
76
|
```
|
|
68
77
|
|
|
69
78
|
## Service map
|
|
70
79
|
|
|
71
80
|
- `services.company.linkedin.search/enrich`
|
|
81
|
+
- `services.crunchbase.search` (returns rows array directly)
|
|
72
82
|
- `services.company.getEmployeesFromLinkedin` (database-only B2B path)
|
|
73
83
|
- `services.person.linkedin.search/enrich`
|
|
74
84
|
- `services.web.search/batchSearch`
|
package/dist/cli.js
CHANGED
|
@@ -100,6 +100,19 @@ Use these docs as the source of truth. If there is any conflict between your pri
|
|
|
100
100
|
- Be concise, factual, and deterministic.
|
|
101
101
|
- Ask a clarifying question only when a missing detail blocks progress.
|
|
102
102
|
|
|
103
|
+
## Package Setup (Do Not Guess)
|
|
104
|
+
- Import from the package name, not a local file path:
|
|
105
|
+
- \`import { services } from "orangeslice"\`
|
|
106
|
+
- \`import { configure, services } from "orangeslice"\` when setting API key programmatically
|
|
107
|
+
- Do NOT use \`import { services } from "./orangeslice"\` unless the user explicitly has a local wrapper file at that path.
|
|
108
|
+
- \`npx orangeslice\` is a setup/bootstrap command (docs sync, package install, auth). It does NOT execute user app scripts.
|
|
109
|
+
|
|
110
|
+
## Runtime Requirements
|
|
111
|
+
- If writing standalone scripts that use top-level \`await\`, use ESM:
|
|
112
|
+
- Set \`"type": "module"\` in \`package.json\`, or
|
|
113
|
+
- Use \`.mjs\` files.
|
|
114
|
+
- If the project is CommonJS and cannot switch to ESM, avoid top-level \`await\` and wrap async code in an async function.
|
|
115
|
+
|
|
103
116
|
## Mandatory Read Order (Before writing code)
|
|
104
117
|
1. \`./services/index.md\` - service map and capabilities
|
|
105
118
|
2. Relevant docs under \`./services/**\` for every service you plan to call
|
|
@@ -304,6 +317,7 @@ function printHelp() {
|
|
|
304
317
|
console.log(" npx orangeslice");
|
|
305
318
|
console.log(" npx orangeslice login [--force]");
|
|
306
319
|
console.log(" npx orangeslice logout");
|
|
320
|
+
console.log(" npx orangeslice auth <API_KEY>");
|
|
307
321
|
console.log(" npx orangeslice auth status\n");
|
|
308
322
|
}
|
|
309
323
|
async function runLogin(args) {
|
|
@@ -322,6 +336,15 @@ function runLogout() {
|
|
|
322
336
|
console.log(" Note: ORANGESLICE_API_KEY env var is still set in this shell.");
|
|
323
337
|
}
|
|
324
338
|
}
|
|
339
|
+
function runAuthSet(apiKey) {
|
|
340
|
+
const trimmed = apiKey.trim();
|
|
341
|
+
if (!trimmed) {
|
|
342
|
+
console.log(" Usage: npx orangeslice auth <API_KEY>");
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
saveConfigFile({ apiKey: trimmed });
|
|
346
|
+
console.log(` ✓ API key saved to ${CONFIG_PATH} (${maskKey(trimmed)})`);
|
|
347
|
+
}
|
|
325
348
|
function runAuthStatus() {
|
|
326
349
|
const envKey = process.env.ORANGESLICE_API_KEY?.trim() || "";
|
|
327
350
|
if (envKey) {
|
|
@@ -346,8 +369,17 @@ async function main() {
|
|
|
346
369
|
runLogout();
|
|
347
370
|
return;
|
|
348
371
|
}
|
|
349
|
-
if (command === "auth"
|
|
350
|
-
|
|
372
|
+
if (command === "auth") {
|
|
373
|
+
const subcommand = args[1];
|
|
374
|
+
if (subcommand === "status") {
|
|
375
|
+
runAuthStatus();
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (subcommand && subcommand !== "--help" && subcommand !== "-h") {
|
|
379
|
+
runAuthSet(subcommand);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
printHelp();
|
|
351
383
|
return;
|
|
352
384
|
}
|
|
353
385
|
if (command && (command === "--help" || command === "-h" || command === "help")) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CrunchbaseSearchParams {
|
|
2
|
+
sql: string;
|
|
3
|
+
userId?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Search the Crunchbase lean table using SQL.
|
|
7
|
+
*
|
|
8
|
+
* Returns rows directly (no envelope).
|
|
9
|
+
*/
|
|
10
|
+
export declare function crunchbaseSearch<T = Record<string, unknown>>(params: CrunchbaseSearchParams): Promise<T[]>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.crunchbaseSearch = crunchbaseSearch;
|
|
4
|
+
const api_1 = require("./api");
|
|
5
|
+
/**
|
|
6
|
+
* Search the Crunchbase lean table using SQL.
|
|
7
|
+
*
|
|
8
|
+
* Returns rows directly (no envelope).
|
|
9
|
+
*/
|
|
10
|
+
async function crunchbaseSearch(params) {
|
|
11
|
+
const data = await (0, api_1.post)("/execute/crunchbase-sql", { sql: params.sql });
|
|
12
|
+
return data.rows ?? [];
|
|
13
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export { configure } from "./api";
|
|
|
2
2
|
export type { OrangesliceConfig } from "./api";
|
|
3
3
|
export { linkedinSearch } from "./b2b";
|
|
4
4
|
export type { LinkedInSearchParams, LinkedInSearchResponse } from "./b2b";
|
|
5
|
+
export { crunchbaseSearch } from "./crunchbase";
|
|
6
|
+
export type { CrunchbaseSearchParams } from "./crunchbase";
|
|
5
7
|
export { webSearch, webBatchSearch } from "./serp";
|
|
6
8
|
export type { WebSearchQuery, WebSearchResult, WebSearchResponse, BatchWebSearchParams } from "./serp";
|
|
7
9
|
export { generateObject } from "./generateObject";
|
|
@@ -21,12 +23,16 @@ export type { PersonLinkedinFindUrlParams, CompanyLinkedinFindUrlParams, PersonC
|
|
|
21
23
|
import { runApifyActor } from "./apify";
|
|
22
24
|
import { linkedinSearch } from "./b2b";
|
|
23
25
|
import { browserExecute } from "./browser";
|
|
26
|
+
import { crunchbaseSearch } from "./crunchbase";
|
|
24
27
|
import { personLinkedinEnrich, personLinkedinFindUrl, personContactGet, companyLinkedinEnrich, companyLinkedinFindUrl, companyGetEmployeesFromLinkedin, geoParseAddress, builtWithLookupDomain, builtWithRelationships, builtWithSearchByTech } from "./expansion";
|
|
25
28
|
import { scrapeWebsite } from "./firecrawl";
|
|
26
29
|
import { generateObject } from "./generateObject";
|
|
27
30
|
import { googleMapsScrape } from "./googleMaps";
|
|
28
31
|
import { webBatchSearch, webSearch } from "./serp";
|
|
29
32
|
export declare const services: {
|
|
33
|
+
crunchbase: {
|
|
34
|
+
search: typeof crunchbaseSearch;
|
|
35
|
+
};
|
|
30
36
|
company: {
|
|
31
37
|
linkedin: {
|
|
32
38
|
findUrl: typeof companyLinkedinFindUrl;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.services = exports.builtWithSearchByTech = exports.builtWithRelationships = exports.builtWithLookupDomain = exports.geoParseAddress = exports.companyGetEmployeesFromLinkedin = exports.companyLinkedinFindUrl = exports.companyLinkedinEnrich = exports.personContactGet = exports.personLinkedinFindUrl = exports.personLinkedinEnrich = exports.PREDICT_LEADS_OPERATION_IDS = exports.predictLeads = exports.executePredictLeads = exports.googleMapsScrape = exports.runApifyActor = exports.browserExecute = exports.scrapeWebsite = exports.generateObject = exports.webBatchSearch = exports.webSearch = exports.linkedinSearch = exports.configure = void 0;
|
|
3
|
+
exports.services = exports.builtWithSearchByTech = exports.builtWithRelationships = exports.builtWithLookupDomain = exports.geoParseAddress = exports.companyGetEmployeesFromLinkedin = exports.companyLinkedinFindUrl = exports.companyLinkedinEnrich = exports.personContactGet = exports.personLinkedinFindUrl = exports.personLinkedinEnrich = exports.PREDICT_LEADS_OPERATION_IDS = exports.predictLeads = exports.executePredictLeads = exports.googleMapsScrape = exports.runApifyActor = exports.browserExecute = exports.scrapeWebsite = exports.generateObject = exports.webBatchSearch = exports.webSearch = exports.crunchbaseSearch = exports.linkedinSearch = exports.configure = void 0;
|
|
4
4
|
var api_1 = require("./api");
|
|
5
5
|
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return api_1.configure; } });
|
|
6
6
|
var b2b_1 = require("./b2b");
|
|
7
7
|
Object.defineProperty(exports, "linkedinSearch", { enumerable: true, get: function () { return b2b_1.linkedinSearch; } });
|
|
8
|
+
var crunchbase_1 = require("./crunchbase");
|
|
9
|
+
Object.defineProperty(exports, "crunchbaseSearch", { enumerable: true, get: function () { return crunchbase_1.crunchbaseSearch; } });
|
|
8
10
|
var serp_1 = require("./serp");
|
|
9
11
|
Object.defineProperty(exports, "webSearch", { enumerable: true, get: function () { return serp_1.webSearch; } });
|
|
10
12
|
Object.defineProperty(exports, "webBatchSearch", { enumerable: true, get: function () { return serp_1.webBatchSearch; } });
|
|
@@ -36,6 +38,7 @@ Object.defineProperty(exports, "builtWithSearchByTech", { enumerable: true, get:
|
|
|
36
38
|
const apify_2 = require("./apify");
|
|
37
39
|
const b2b_2 = require("./b2b");
|
|
38
40
|
const browser_2 = require("./browser");
|
|
41
|
+
const crunchbase_2 = require("./crunchbase");
|
|
39
42
|
const expansion_2 = require("./expansion");
|
|
40
43
|
const firecrawl_2 = require("./firecrawl");
|
|
41
44
|
const generateObject_2 = require("./generateObject");
|
|
@@ -43,6 +46,9 @@ const googleMaps_2 = require("./googleMaps");
|
|
|
43
46
|
const predictLeads_2 = require("./predictLeads");
|
|
44
47
|
const serp_2 = require("./serp");
|
|
45
48
|
exports.services = {
|
|
49
|
+
crunchbase: {
|
|
50
|
+
search: crunchbase_2.crunchbaseSearch
|
|
51
|
+
},
|
|
46
52
|
company: {
|
|
47
53
|
linkedin: {
|
|
48
54
|
findUrl: expansion_2.companyLinkedinFindUrl,
|
|
@@ -9,4 +9,4 @@ Typed functions for Gmail actions powered by Orange Slice Google integrations.
|
|
|
9
9
|
## Email
|
|
10
10
|
|
|
11
11
|
- `integrations.gmail.sendEmail(input)` - Send an email through the connected Gmail account
|
|
12
|
-
- Heavy rate limit: `sendEmail` is capped at **
|
|
12
|
+
- Heavy rate limit: `sendEmail` is capped at **40 calls/day** per connected Gmail account
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Send an email from the connected Gmail account.
|
|
4
4
|
|
|
5
|
-
> Rate limit note for AI: `integrations.gmail.sendEmail(...)` is heavily rate-limited to **
|
|
5
|
+
> Rate limit note for AI: `integrations.gmail.sendEmail(...)` is heavily rate-limited to **40 calls/day** per connected Gmail account. Use sparingly and batch/aggregate where possible.
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
8
|
// Basic email
|
|
@@ -25,18 +25,18 @@ await integrations.gmail.sendEmail({
|
|
|
25
25
|
|
|
26
26
|
## Input
|
|
27
27
|
|
|
28
|
-
| Parameter | Type
|
|
29
|
-
| ------------------ |
|
|
30
|
-
| `recipient_email` | `string`
|
|
31
|
-
| `extra_recipients` | `string[]`
|
|
32
|
-
| `cc` | `string[]`
|
|
33
|
-
| `bcc` | `string[]`
|
|
34
|
-
| `subject` | `string`
|
|
35
|
-
| `body` | `string`
|
|
36
|
-
| `is_html` | `boolean`
|
|
37
|
-
| `from_email` | `string`
|
|
38
|
-
| `attachment` | `object`
|
|
39
|
-
| `user_id` | `string`
|
|
28
|
+
| Parameter | Type | Required | Description |
|
|
29
|
+
| ------------------ | ---------- | -------- | --------------------------------- |
|
|
30
|
+
| `recipient_email` | `string` | No\* | Primary `To` recipient |
|
|
31
|
+
| `extra_recipients` | `string[]` | No | Additional `To` recipients |
|
|
32
|
+
| `cc` | `string[]` | No | CC recipients |
|
|
33
|
+
| `bcc` | `string[]` | No | BCC recipients |
|
|
34
|
+
| `subject` | `string` | No\* | Email subject |
|
|
35
|
+
| `body` | `string` | No\* | Email body (plain text or HTML) |
|
|
36
|
+
| `is_html` | `boolean` | No | Set to `true` when body is HTML |
|
|
37
|
+
| `from_email` | `string` | No | Optional verified send-as alias |
|
|
38
|
+
| `attachment` | `object` | No | Optional attachment payload |
|
|
39
|
+
| `user_id` | `string` | No | Gmail user id (`"me"` by default) |
|
|
40
40
|
|
|
41
41
|
\*Gmail requires at least one recipient (`recipient_email`, `cc`, or `bcc`) and at least one of `subject` or `body`.
|
|
42
42
|
|
|
@@ -16,6 +16,7 @@ description: Strategies for searching or finding people and companies. This is a
|
|
|
16
16
|
Run queries with built-in filters when the criteria is searchable:
|
|
17
17
|
|
|
18
18
|
- **Web search (`services.web.search`)** — **Default for LinkedIn**. Use for keywords, niche queries, fuzzy matching, anything descriptive.
|
|
19
|
+
- **Crunchbase (`services.crunchbase.search`)** — **Default for funding data**. Use for funding-stage, round type, amount, date windows, and investor-backed company discovery.
|
|
19
20
|
- **LinkedIn B2B DB** — **Indexed lookups ONLY:** company by domain/slug/ID, employees at a known company (by company_id), basic funding (2-table join). Everything else = web search. See [QUICK_REF](./linkedin_data/QUICK_REF.md).
|
|
20
21
|
- **Google Maps** — industry, location, ratings
|
|
21
22
|
- **LinkedIn job search** — job filters, titles
|
|
@@ -83,11 +84,11 @@ When using qualification columns, think Circle & Star:
|
|
|
83
84
|
| Source | Use When | Limitations |
|
|
84
85
|
| ------------------------ | ----------------------------------------------------------- | -------------------------------------------------------- |
|
|
85
86
|
| **Web Search (Default)** | **Everything else** — keywords, niche, fuzzy, specific | Requires verification columns for false positives. |
|
|
87
|
+
| **Crunchbase (Funding Default)** | Funding-focused prospecting: stage, round type, amount, recency, investors | Best for funding intelligence; use other sources for non-funding discovery criteria. |
|
|
86
88
|
| **PredictLeads** | Company intelligence, buying signals, and structured company events at scale | Coverage varies by company/market; use web search for very niche long-tail discovery. |
|
|
87
89
|
| **Niche Directory Scrape** | Well-defined categories with existing lists (see below) | Requires finding the right directory first. |
|
|
88
90
|
| **LinkedIn B2B DB** | **Indexed lookups ONLY:** company by domain/slug/ID, employees at known company, basic 2-table funding. | **3s hard max. No keyword search, no LATERAL, no 3+ table joins.** Everything else = web search. |
|
|
89
91
|
| **Google Maps** | Local/SMB, physical locations, restaurants, retail | Limited to businesses with physical presence. |
|
|
90
|
-
| **NPI Database** | Healthcare providers | Healthcare only. Free. |
|
|
91
92
|
| **Apify Actors** | Platform-specific scraping (Instagram, TikTok, job boards) | Per-platform setup. May break with platform changes. |
|
|
92
93
|
|
|
93
94
|
### PredictLeads: When It Is Better Than Everything Else
|
|
@@ -105,6 +106,12 @@ Prefer other sources when:
|
|
|
105
106
|
- You need local storefront/SMB discovery -> use Google Maps
|
|
106
107
|
- You need fast indexed LinkedIn lookups by known IDs/domain/company -> use LinkedIn B2B DB
|
|
107
108
|
|
|
109
|
+
### Funding Prospecting Standard: Use Crunchbase First
|
|
110
|
+
|
|
111
|
+
For any request centered on funding data (for example: "Series A fintech companies", "companies that raised in the last 12 months", "recently funded startups"), use `services.crunchbase.search` as the **standard/default source**.
|
|
112
|
+
|
|
113
|
+
Use LinkedIn B2B DB funding joins only when the user explicitly needs a LinkedIn-only workflow or a narrow lookup tied to existing LinkedIn records. Otherwise, Crunchbase should be the first choice for funding-oriented discovery.
|
|
114
|
+
|
|
108
115
|
### Niche Directory Scraping — For Well-Defined Categories
|
|
109
116
|
|
|
110
117
|
When users ask for companies in a **specific, well-defined niche** (e.g., "fast food chains", "Fortune 500 companies", "Y Combinator startups"), the best approach is often to **find and scrape a curated directory or list**.
|
|
@@ -260,27 +267,28 @@ Don't overthink it — just create 2-3 views that match the columns you built. S
|
|
|
260
267
|
|
|
261
268
|
## Examples
|
|
262
269
|
|
|
263
|
-
| User Request | Approach | Why
|
|
264
|
-
| -------------------------------------------- | ---------------- |
|
|
265
|
-
| "AI CRM companies" | Web search | Keyword query → `"AI CRM" site:linkedin.com/company`
|
|
266
|
-
| "Fintech startups" | Web search | Fuzzy/descriptive → `"fintech" "startup" site:linkedin.com/company`
|
|
267
|
-
| "SDRs at Series A companies" | Web search | Specific criteria → `"SDR" "Series A" site:linkedin.com/in`
|
|
268
|
-
| "
|
|
269
|
-
| "
|
|
270
|
-
| "
|
|
271
|
-
| "
|
|
272
|
-
| "
|
|
273
|
-
| "
|
|
274
|
-
| "
|
|
275
|
-
| "
|
|
276
|
-
| "
|
|
270
|
+
| User Request | Approach | Why |
|
|
271
|
+
| -------------------------------------------- | ---------------- | --------------------------------------------------------------------------- |
|
|
272
|
+
| "AI CRM companies" | Web search | Keyword query → `"AI CRM" site:linkedin.com/company` |
|
|
273
|
+
| "Fintech startups" | Web search | Fuzzy/descriptive → `"fintech" "startup" site:linkedin.com/company` |
|
|
274
|
+
| "SDRs at Series A companies" | Web search | Specific criteria → `"SDR" "Series A" site:linkedin.com/in` |
|
|
275
|
+
| "Series A/B companies raised last year" | Crunchbase | Funding-specific discovery is best handled via `services.crunchbase.search` |
|
|
276
|
+
| "Companies using Kubernetes" | Web search | Technology match → `"Kubernetes" site:linkedin.com/company` |
|
|
277
|
+
| "VPs who worked at Google" | Web search | Fuzzy history match → `"VP" "Google" site:linkedin.com/in` |
|
|
278
|
+
| "1000 software engineers in Bay Area" | B2B DB | Simple title + location + high volume |
|
|
279
|
+
| "All healthcare companies 100-500 employees" | B2B DB | Industry + size + high volume |
|
|
280
|
+
| "Fast food chains that..." | Directory scrape | Scrape Wikipedia list → `browser.execute` |
|
|
281
|
+
| "Restaurants in Austin" | Google Maps | Local/SMB with physical presence |
|
|
282
|
+
| "Companies hiring SDRs" | LinkedIn Jobs | Job search with title filter |
|
|
283
|
+
| "Warehouses implementing WMS" | Circle + columns | Pull logistics companies → add "WMS Score" column |
|
|
284
|
+
| "Companies that recently switched CRMs" | Circle + columns | Pull SaaS companies → add "CRM Change Signals" column |
|
|
277
285
|
|
|
278
286
|
---
|
|
279
287
|
|
|
280
288
|
## Tools
|
|
281
289
|
|
|
282
290
|
- **LinkedIn:** `services.company.linkedin.search({ sql: "SELECT ... FROM linkedin_company ..." })`, `services.person.linkedin.search({ sql: "SELECT ... FROM linkedin_profile ..." })` — **Lookup tool only, 3s max, 2-table joins max. Use web search for anything else.**
|
|
283
|
-
- **
|
|
291
|
+
- **Funding:** `services.crunchbase.search({ sql: "SELECT ... FROM ... WHERE ..." })` — **Default for funding search and screening.**
|
|
284
292
|
- **Local/SMB:** `googleMaps.scrape`
|
|
285
293
|
- **Web:** `web.search` + `browser.execute`
|
|
286
294
|
- **Platforms:** `services.apify.runActor`
|
|
@@ -390,6 +390,38 @@ WHERE lc.company_size = '51-200 employees'
|
|
|
390
390
|
- **Use `lc` alias** for company tables
|
|
391
391
|
- **Default to US**: `lc.country_code = 'US'`
|
|
392
392
|
|
|
393
|
+
## Return Type
|
|
394
|
+
|
|
395
|
+
`services.company.linkedin.search()` returns an object envelope:
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
{
|
|
399
|
+
rows: (Record < string, unknown > []);
|
|
400
|
+
count: number;
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
- `rows`: Result rows from your SQL query, with exactly the columns you selected.
|
|
405
|
+
- `count`: Number of rows returned in `rows`.
|
|
406
|
+
|
|
407
|
+
Example:
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
const searchResult = await services.company.linkedin.search({
|
|
411
|
+
sql: `
|
|
412
|
+
SELECT
|
|
413
|
+
lc.company_name,
|
|
414
|
+
lc.domain,
|
|
415
|
+
'https://www.linkedin.com/company/' || lc.universal_name AS lc_linkedin_url
|
|
416
|
+
FROM linkedin_company lc
|
|
417
|
+
WHERE lc.domain = 'stripe.com'
|
|
418
|
+
LIMIT 1
|
|
419
|
+
`
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
return searchResult.rows; // Most spreadsheet snippets should return rows
|
|
423
|
+
```
|
|
424
|
+
|
|
393
425
|
---
|
|
394
426
|
|
|
395
427
|
## Table Aliases
|