orangeslice 1.4.0 → 1.4.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/dist/b2b.d.ts +1 -1
- package/dist/b2b.js +29 -11
- package/dist/cli.js +21 -21
- package/dist/firecrawl.js +26 -5
- package/dist/serp.js +26 -8
- package/package.json +1 -1
package/dist/b2b.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export interface QueryResult<T = Record<string, unknown>> {
|
|
|
18
18
|
* @example
|
|
19
19
|
* const companies = await b2b.sql<Company[]>("SELECT * FROM linkedin_company WHERE domain = 'stripe.com'");
|
|
20
20
|
*/
|
|
21
|
-
export declare function sql<T = Record<string, unknown>[]>(
|
|
21
|
+
export declare function sql<T = Record<string, unknown>[]>(sqlQuery: string): Promise<T>;
|
|
22
22
|
/**
|
|
23
23
|
* Execute a SQL query and get full result with metadata
|
|
24
24
|
*/
|
package/dist/b2b.js
CHANGED
|
@@ -14,6 +14,30 @@ let config = {
|
|
|
14
14
|
// Create queue and rate limiter with defaults
|
|
15
15
|
let queue = (0, queue_1.createQueue)(config.concurrency);
|
|
16
16
|
let rateLimiter = (0, queue_1.createRateLimiter)(config.minDelayMs);
|
|
17
|
+
/**
|
|
18
|
+
* Helper to make POST request, handling redirects manually
|
|
19
|
+
* (Node.js fetch has issues with POST body on redirects)
|
|
20
|
+
*/
|
|
21
|
+
async function fetchWithRedirect(url, body) {
|
|
22
|
+
let response = await fetch(url, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
body,
|
|
26
|
+
redirect: "manual",
|
|
27
|
+
});
|
|
28
|
+
// Handle redirect manually - re-POST to the new location
|
|
29
|
+
if (response.status >= 300 && response.status < 400) {
|
|
30
|
+
const location = response.headers.get("location");
|
|
31
|
+
if (location) {
|
|
32
|
+
response = await fetch(location, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: { "Content-Type": "application/json" },
|
|
35
|
+
body,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return response;
|
|
40
|
+
}
|
|
17
41
|
/**
|
|
18
42
|
* Configure the B2B client
|
|
19
43
|
*/
|
|
@@ -36,14 +60,11 @@ function configure(options) {
|
|
|
36
60
|
* @example
|
|
37
61
|
* const companies = await b2b.sql<Company[]>("SELECT * FROM linkedin_company WHERE domain = 'stripe.com'");
|
|
38
62
|
*/
|
|
39
|
-
async function sql(
|
|
63
|
+
async function sql(sqlQuery) {
|
|
40
64
|
return queue(async () => {
|
|
41
65
|
return rateLimiter(async () => {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
headers: { "Content-Type": "application/json" },
|
|
45
|
-
body: JSON.stringify({ sql: query }),
|
|
46
|
-
});
|
|
66
|
+
const body = JSON.stringify({ sql: sqlQuery });
|
|
67
|
+
const response = await fetchWithRedirect(config.proxyUrl, body);
|
|
47
68
|
if (!response.ok) {
|
|
48
69
|
throw new Error(`B2B SQL request failed: ${response.status} ${response.statusText}`);
|
|
49
70
|
}
|
|
@@ -61,11 +82,8 @@ async function sql(query) {
|
|
|
61
82
|
async function query(sqlQuery) {
|
|
62
83
|
return queue(async () => {
|
|
63
84
|
return rateLimiter(async () => {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
headers: { "Content-Type": "application/json" },
|
|
67
|
-
body: JSON.stringify({ sql: sqlQuery }),
|
|
68
|
-
});
|
|
85
|
+
const body = JSON.stringify({ sql: sqlQuery });
|
|
86
|
+
const response = await fetchWithRedirect(config.proxyUrl, body);
|
|
69
87
|
if (!response.ok) {
|
|
70
88
|
throw new Error(`B2B SQL request failed: ${response.status} ${response.statusText}`);
|
|
71
89
|
}
|
package/dist/cli.js
CHANGED
|
@@ -39,10 +39,18 @@ const path = __importStar(require("path"));
|
|
|
39
39
|
const child_process_1 = require("child_process");
|
|
40
40
|
const DOCS_DIR = path.join(__dirname, "..", "docs");
|
|
41
41
|
const TARGET_DIR = path.join(process.cwd(), "orangeslice-docs");
|
|
42
|
+
const AGENTS_MD = path.join(DOCS_DIR, "AGENTS.md");
|
|
43
|
+
const ROOT_AGENTS_MD = path.join(process.cwd(), "AGENTS.md");
|
|
42
44
|
async function main() {
|
|
43
|
-
console.log("\n orangeslice - setting up
|
|
44
|
-
// 1. Copy
|
|
45
|
-
console.log("1.
|
|
45
|
+
console.log("\n🍊 orangeslice - setting up sales agent for AI...\n");
|
|
46
|
+
// 1. Copy AGENTS.md to project root (for auto-detection by Claude Code, etc.)
|
|
47
|
+
console.log("1. Installing AGENTS.md at project root...");
|
|
48
|
+
if (fs.existsSync(AGENTS_MD)) {
|
|
49
|
+
fs.copyFileSync(AGENTS_MD, ROOT_AGENTS_MD);
|
|
50
|
+
console.log(" ✓ AGENTS.md → ./AGENTS.md (auto-detected by AI agents)\n");
|
|
51
|
+
}
|
|
52
|
+
// 2. Copy full docs to orangeslice-docs/
|
|
53
|
+
console.log("2. Copying detailed documentation...");
|
|
46
54
|
if (!fs.existsSync(TARGET_DIR)) {
|
|
47
55
|
fs.mkdirSync(TARGET_DIR, { recursive: true });
|
|
48
56
|
}
|
|
@@ -51,30 +59,22 @@ async function main() {
|
|
|
51
59
|
const src = path.join(DOCS_DIR, file);
|
|
52
60
|
const dest = path.join(TARGET_DIR, file);
|
|
53
61
|
fs.copyFileSync(src, dest);
|
|
54
|
-
console.log(` ${file}`);
|
|
55
62
|
}
|
|
56
|
-
console.log(`
|
|
57
|
-
//
|
|
58
|
-
console.log("
|
|
63
|
+
console.log(` ✓ ${files.length} docs → ./orangeslice-docs/\n`);
|
|
64
|
+
// 3. Install package
|
|
65
|
+
console.log("3. Installing orangeslice package...");
|
|
59
66
|
try {
|
|
60
67
|
(0, child_process_1.execSync)("npm install orangeslice", { stdio: "inherit", cwd: process.cwd() });
|
|
61
68
|
}
|
|
62
69
|
catch {
|
|
63
70
|
console.log(" (skipped - no package.json or npm not available)\n");
|
|
64
71
|
}
|
|
65
|
-
//
|
|
66
|
-
console.log("\n Done! Your AI agent is
|
|
67
|
-
console.log("
|
|
68
|
-
console.log("
|
|
69
|
-
console.log("
|
|
70
|
-
console.log("
|
|
71
|
-
console.log("
|
|
72
|
-
console.log(' import { orangeslice } from "orangeslice";');
|
|
73
|
-
console.log("");
|
|
74
|
-
console.log(" const company = await orangeslice.b2b.sql(`");
|
|
75
|
-
console.log(" SELECT company_name, employee_count, description");
|
|
76
|
-
console.log(" FROM linkedin_company");
|
|
77
|
-
console.log(" WHERE domain = 'stripe.com'");
|
|
78
|
-
console.log(" `);\n");
|
|
72
|
+
// 4. Done
|
|
73
|
+
console.log("\n✅ Done! Your AI agent is now a sales research assistant.\n");
|
|
74
|
+
console.log(" AGENTS.md is at your project root - Claude Code will auto-detect it.\n");
|
|
75
|
+
console.log(" Your agent can now:\n");
|
|
76
|
+
console.log(" • Query 1B+ LinkedIn profiles (orangeslice.b2b.sql)");
|
|
77
|
+
console.log(" • Search Google (orangeslice.serp.search)");
|
|
78
|
+
console.log(" • Scrape websites (orangeslice.firecrawl.scrape)\n");
|
|
79
79
|
}
|
|
80
80
|
main().catch(console.error);
|
package/dist/firecrawl.js
CHANGED
|
@@ -9,6 +9,30 @@ const API_URL = process.env.ORANGESLICE_API_URL || "https://orangeslice.ai/api/f
|
|
|
9
9
|
// Shared queue for all Firecrawl requests
|
|
10
10
|
const queue = (0, queue_1.createQueue)(2);
|
|
11
11
|
const rateLimiter = (0, queue_1.createRateLimiter)(500); // 500ms between requests (crawls are expensive)
|
|
12
|
+
/**
|
|
13
|
+
* Helper to make POST request, handling redirects manually
|
|
14
|
+
* (Node.js fetch has issues with POST body on redirects)
|
|
15
|
+
*/
|
|
16
|
+
async function fetchWithRedirect(url, body) {
|
|
17
|
+
let response = await fetch(url, {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: { "Content-Type": "application/json" },
|
|
20
|
+
body,
|
|
21
|
+
redirect: "manual",
|
|
22
|
+
});
|
|
23
|
+
// Handle redirect manually - re-POST to the new location
|
|
24
|
+
if (response.status >= 300 && response.status < 400) {
|
|
25
|
+
const location = response.headers.get("location");
|
|
26
|
+
if (location) {
|
|
27
|
+
response = await fetch(location, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { "Content-Type": "application/json" },
|
|
30
|
+
body,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return response;
|
|
35
|
+
}
|
|
12
36
|
/**
|
|
13
37
|
* Scrape a website and get markdown content.
|
|
14
38
|
* Automatically rate-limited.
|
|
@@ -26,11 +50,8 @@ const rateLimiter = (0, queue_1.createRateLimiter)(500); // 500ms between reques
|
|
|
26
50
|
async function scrape(url, limit = 1) {
|
|
27
51
|
return queue(async () => {
|
|
28
52
|
return rateLimiter(async () => {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
headers: { "Content-Type": "application/json" },
|
|
32
|
-
body: JSON.stringify({ url, limit }),
|
|
33
|
-
});
|
|
53
|
+
const body = JSON.stringify({ url, limit });
|
|
54
|
+
const response = await fetchWithRedirect(API_URL, body);
|
|
34
55
|
if (!response.ok) {
|
|
35
56
|
throw new Error(`Firecrawl request failed: ${response.status} ${response.statusText}`);
|
|
36
57
|
}
|
package/dist/serp.js
CHANGED
|
@@ -8,6 +8,30 @@ const API_URL = process.env.ORANGESLICE_API_URL || "https://orangeslice.ai/api/f
|
|
|
8
8
|
// Shared queue for all SERP requests
|
|
9
9
|
const queue = (0, queue_1.createQueue)(2);
|
|
10
10
|
const rateLimiter = (0, queue_1.createRateLimiter)(200); // 200ms between requests
|
|
11
|
+
/**
|
|
12
|
+
* Helper to make POST request, handling redirects manually
|
|
13
|
+
* (Node.js fetch has issues with POST body on redirects)
|
|
14
|
+
*/
|
|
15
|
+
async function fetchWithRedirect(url, body) {
|
|
16
|
+
let response = await fetch(url, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: { "Content-Type": "application/json" },
|
|
19
|
+
body,
|
|
20
|
+
redirect: "manual",
|
|
21
|
+
});
|
|
22
|
+
// Handle redirect manually - re-POST to the new location
|
|
23
|
+
if (response.status >= 300 && response.status < 400) {
|
|
24
|
+
const location = response.headers.get("location");
|
|
25
|
+
if (location) {
|
|
26
|
+
response = await fetch(location, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: { "Content-Type": "application/json" },
|
|
29
|
+
body,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
11
35
|
/**
|
|
12
36
|
* Search Google via SERP API.
|
|
13
37
|
* Automatically rate-limited.
|
|
@@ -19,14 +43,8 @@ const rateLimiter = (0, queue_1.createRateLimiter)(200); // 200ms between reques
|
|
|
19
43
|
async function search(query, options = {}) {
|
|
20
44
|
return queue(async () => {
|
|
21
45
|
return rateLimiter(async () => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
headers: { "Content-Type": "application/json" },
|
|
25
|
-
body: JSON.stringify({
|
|
26
|
-
query,
|
|
27
|
-
...options,
|
|
28
|
-
}),
|
|
29
|
-
});
|
|
46
|
+
const body = JSON.stringify({ query, ...options });
|
|
47
|
+
const response = await fetchWithRedirect(API_URL, body);
|
|
30
48
|
if (!response.ok) {
|
|
31
49
|
throw new Error(`SERP request failed: ${response.status} ${response.statusText}`);
|
|
32
50
|
}
|