orangeslice 2.1.3 → 2.1.4-beta.0

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/ctx.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Spreadsheet context API for the orangeslice SDK.
3
+ *
4
+ * Usage:
5
+ * import { ctx } from "orangeslice";
6
+ *
7
+ * const ss = await ctx.createSpreadsheet({ name: "Leads" });
8
+ * await ctx.sql(ss.id, 'CREATE TABLE contacts (name, email, website)');
9
+ * await ctx.sql(ss.id, "INSERT INTO contacts (name, email) VALUES ('Acme', 'hi@acme.com')");
10
+ * const { rows } = await ctx.sql(ss.id, "SELECT * FROM contacts");
11
+ *
12
+ * // Or bind to a spreadsheet for convenience:
13
+ * const bound = ctx.spreadsheet(ss.id);
14
+ * await bound.sql("SELECT * FROM contacts WHERE name = 'Acme'");
15
+ * await bound.sheet("contacts").addRow({ name: "Corp", email: "corp@example.com" });
16
+ */
17
+ export interface Spreadsheet {
18
+ id: string;
19
+ name: string;
20
+ }
21
+ export interface SpreadsheetListItem {
22
+ id: string;
23
+ name: string;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ orgId: string | null;
27
+ userId: string | null;
28
+ }
29
+ export interface SqlQueryResult {
30
+ rows: Record<string, unknown>[];
31
+ rowIds: string[];
32
+ count?: number;
33
+ sql?: string;
34
+ }
35
+ export interface SqlActionResult {
36
+ success: boolean;
37
+ id?: string;
38
+ columns?: Array<{
39
+ id: string;
40
+ name: string;
41
+ }>;
42
+ }
43
+ export type SqlResult = SqlQueryResult | SqlActionResult;
44
+ export declare const ctx: {
45
+ createSpreadsheet: (opts: {
46
+ name: string;
47
+ }) => Promise<Spreadsheet>;
48
+ listSpreadsheets: () => Promise<{
49
+ spreadsheets: SpreadsheetListItem[];
50
+ }>;
51
+ deleteSpreadsheet: (spreadsheetId: string) => Promise<{
52
+ success: boolean;
53
+ }>;
54
+ sql: (spreadsheetId: string, sql: string) => Promise<SqlResult>;
55
+ spreadsheet: (spreadsheetId: string) => {
56
+ sql: (sql: string) => Promise<SqlResult>;
57
+ sheet: (sheetName: string) => {
58
+ addRow: (row: Record<string, unknown>) => Promise<SqlResult>;
59
+ addRows: (rows: Record<string, unknown>[]) => Promise<SqlResult>;
60
+ };
61
+ };
62
+ };
package/dist/ctx.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * Spreadsheet context API for the orangeslice SDK.
4
+ *
5
+ * Usage:
6
+ * import { ctx } from "orangeslice";
7
+ *
8
+ * const ss = await ctx.createSpreadsheet({ name: "Leads" });
9
+ * await ctx.sql(ss.id, 'CREATE TABLE contacts (name, email, website)');
10
+ * await ctx.sql(ss.id, "INSERT INTO contacts (name, email) VALUES ('Acme', 'hi@acme.com')");
11
+ * const { rows } = await ctx.sql(ss.id, "SELECT * FROM contacts");
12
+ *
13
+ * // Or bind to a spreadsheet for convenience:
14
+ * const bound = ctx.spreadsheet(ss.id);
15
+ * await bound.sql("SELECT * FROM contacts WHERE name = 'Acme'");
16
+ * await bound.sheet("contacts").addRow({ name: "Corp", email: "corp@example.com" });
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.ctx = void 0;
20
+ const api_1 = require("./api");
21
+ // ---------------------------------------------------------------------------
22
+ // SQL builder helpers
23
+ // ---------------------------------------------------------------------------
24
+ function escapeValue(val) {
25
+ if (val === null || val === undefined)
26
+ return "NULL";
27
+ if (typeof val === "number") {
28
+ if (!Number.isFinite(val))
29
+ throw new Error(`[orangeslice] Cannot use ${val} as a SQL value`);
30
+ return String(val);
31
+ }
32
+ if (typeof val === "boolean")
33
+ return String(val);
34
+ const str = String(val).replace(/'/g, "''");
35
+ return `'${str}'`;
36
+ }
37
+ function escapeName(name) {
38
+ return `"${name.replace(/"/g, '""')}"`;
39
+ }
40
+ function buildInsertSQL(sheetName, rows) {
41
+ if (rows.length === 0)
42
+ throw new Error("[orangeslice] addRows requires at least one row");
43
+ const allKeys = new Set();
44
+ for (const row of rows) {
45
+ for (const key of Object.keys(row))
46
+ allKeys.add(key);
47
+ }
48
+ const columns = Array.from(allKeys);
49
+ const colList = columns.map(escapeName).join(", ");
50
+ const valueClauses = rows.map((row) => {
51
+ const vals = columns.map((col) => escapeValue(row[col]));
52
+ return `(${vals.join(", ")})`;
53
+ });
54
+ return `INSERT INTO ${escapeName(sheetName)} (${colList}) VALUES ${valueClauses.join(", ")}`;
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // Validation
58
+ // ---------------------------------------------------------------------------
59
+ function assertNotRun(sql) {
60
+ const trimmed = sql.trim().toUpperCase();
61
+ if (trimmed.startsWith("RUN ") || trimmed === "RUN") {
62
+ throw new Error("[orangeslice] RUN commands are not supported via the API");
63
+ }
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // Bound spreadsheet handle
67
+ // ---------------------------------------------------------------------------
68
+ function createSheetHandle(spreadsheetId, sheetName) {
69
+ return {
70
+ addRow: (row) => (0, api_1.post)("/ctx/sql", {
71
+ spreadsheetId,
72
+ sql: buildInsertSQL(sheetName, [row])
73
+ }),
74
+ addRows: (rows) => (0, api_1.post)("/ctx/sql", {
75
+ spreadsheetId,
76
+ sql: buildInsertSQL(sheetName, rows)
77
+ })
78
+ };
79
+ }
80
+ function createSpreadsheetHandle(spreadsheetId) {
81
+ return {
82
+ sql: (sql) => {
83
+ assertNotRun(sql);
84
+ return (0, api_1.post)("/ctx/sql", { spreadsheetId, sql });
85
+ },
86
+ sheet: (sheetName) => createSheetHandle(spreadsheetId, sheetName)
87
+ };
88
+ }
89
+ // ---------------------------------------------------------------------------
90
+ // Top-level ctx object
91
+ // ---------------------------------------------------------------------------
92
+ exports.ctx = {
93
+ createSpreadsheet: (opts) => (0, api_1.post)("/ctx/spreadsheet/create", opts),
94
+ listSpreadsheets: () => (0, api_1.post)("/ctx/spreadsheet/list", {}),
95
+ deleteSpreadsheet: (spreadsheetId) => (0, api_1.post)("/ctx/spreadsheet/delete", { spreadsheetId }),
96
+ sql: (spreadsheetId, sql) => {
97
+ assertNotRun(sql);
98
+ return (0, api_1.post)("/ctx/sql", { spreadsheetId, sql });
99
+ },
100
+ spreadsheet: (spreadsheetId) => createSpreadsheetHandle(spreadsheetId)
101
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { configure } from "./api";
2
2
  export type { OrangesliceConfig } from "./api";
3
+ export { ctx } from "./ctx";
4
+ export type { Spreadsheet, SpreadsheetListItem, SqlResult, SqlQueryResult, SqlActionResult } from "./ctx";
3
5
  export { linkedinSearch } from "./b2b";
4
6
  export type { LinkedInSearchParams, LinkedInSearchResponse } from "./b2b";
5
7
  export { crunchbaseSearch } from "./crunchbase";
package/dist/index.js CHANGED
@@ -1,8 +1,10 @@
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.crunchbaseSearch = 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.ctx = 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
+ var ctx_1 = require("./ctx");
7
+ Object.defineProperty(exports, "ctx", { enumerable: true, get: function () { return ctx_1.ctx; } });
6
8
  var b2b_1 = require("./b2b");
7
9
  Object.defineProperty(exports, "linkedinSearch", { enumerable: true, get: function () { return b2b_1.linkedinSearch; } });
8
10
  var crunchbase_1 = require("./crunchbase");
@@ -0,0 +1,68 @@
1
+ ---
2
+ description: Spreadsheet management — create spreadsheets, run SQL, add rows
3
+ ---
4
+
5
+ # ctx — Spreadsheet Context API
6
+
7
+ Manage Orange Slice spreadsheets programmatically. Create spreadsheets, add sheets and columns via SQL, query data, insert rows.
8
+
9
+ ## Quick start
10
+
11
+ ```typescript
12
+ import { ctx } from "orangeslice";
13
+
14
+ // Create a spreadsheet
15
+ const ss = await ctx.createSpreadsheet({ name: "Leads" });
16
+
17
+ // Create a sheet with columns
18
+ await ctx.sql(ss.id, "CREATE TABLE contacts (name, email, website)");
19
+
20
+ // Insert data
21
+ await ctx.sql(ss.id, "INSERT INTO contacts (name, email) VALUES ('Acme', 'hi@acme.com')");
22
+
23
+ // Query data
24
+ const result = await ctx.sql(ss.id, "SELECT * FROM contacts WHERE name = 'Acme'");
25
+ console.log(result.rows);
26
+ ```
27
+
28
+ ## Methods
29
+
30
+ ### Top-level
31
+
32
+ - **`ctx.createSpreadsheet({ name })`** — Create a new spreadsheet. The scope (personal vs org) is determined by the API key. Returns `{ id, name }`.
33
+ - **`ctx.listSpreadsheets()`** — List spreadsheets visible to the API key's scope. Returns `{ spreadsheets: [...] }`.
34
+ - **`ctx.deleteSpreadsheet(spreadsheetId)`** — Soft-delete a spreadsheet (must be within the API key's scope).
35
+ - **`ctx.sql(spreadsheetId, sql)`** — Execute EAV-SQL against a spreadsheet within the API key's scope (see SQL reference below).
36
+
37
+ ### Bound spreadsheet
38
+
39
+ Call `ctx.spreadsheet(id)` to get a handle bound to a specific spreadsheet:
40
+
41
+ ```typescript
42
+ const ss = ctx.spreadsheet("uuid-here");
43
+ await ss.sql("SELECT * FROM contacts");
44
+ await ss.sheet("contacts").addRow({ name: "Corp", email: "corp@example.com" });
45
+ await ss.sheet("contacts").addRows([
46
+ { name: "Foo", email: "foo@example.com" },
47
+ { name: "Bar", email: "bar@example.com" }
48
+ ]);
49
+ ```
50
+
51
+ - **`ss.sql(sql)`** — Execute EAV-SQL (same as `ctx.sql` but without needing to pass spreadsheetId).
52
+ - **`ss.sheet(name).addRow(row)`** — Insert a single row into the named sheet.
53
+ - **`ss.sheet(name).addRows(rows)`** — Insert multiple rows.
54
+
55
+ ## EAV-SQL Reference
56
+
57
+ The `sql` method supports a subset of SQL mapped to Orange Slice's EAV storage:
58
+
59
+ | Statement | Example | Description |
60
+ | -------------- | ---------------------------------------------------------- | -------------------------------- |
61
+ | `CREATE TABLE` | `CREATE TABLE leads (name, email, website)` | Creates a new sheet with columns |
62
+ | `SELECT` | `SELECT name, email FROM leads WHERE email LIKE '%@acme%'` | Query rows |
63
+ | `INSERT INTO` | `INSERT INTO leads (name) VALUES ('Acme')` | Add rows |
64
+ | `ALTER TABLE` | `ALTER TABLE leads ADD COLUMN phone` | Add/rename/drop columns |
65
+ | `DELETE FROM` | `DELETE FROM leads WHERE email IS NULL` | Delete rows |
66
+ | `DROP TABLE` | `DROP TABLE leads` | Delete a sheet |
67
+
68
+ > **Note:** `RUN` commands are not supported via the API.
@@ -1,3 +1,4 @@
1
+ - **ctx**: Spreadsheet management — create spreadsheets, run SQL, add sheets/columns/rows programmatically.
1
2
  - **ai**: AI helpers (summaries, classifications, scoring).
2
3
  - **apify**: Run any of 10,000+ Apify actors for web scraping, social media, e-commerce, and more.
3
4
  - **browser**: Kernel browser automation - spin up cloud browsers, execute Playwright code, take screenshots. **Use this for scraping structured lists of repeated data** (e.g., product listings, search results, table rows) where you know the DOM structure. Also ideal for **intercepting network requests** to discover underlying APIs, then paginate those APIs directly in your code (faster & cheaper than clicking through pages). Perfect for JS-heavy sites that don't work with simple HTTP scraping.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orangeslice",
3
- "version": "2.1.3",
3
+ "version": "2.1.4-beta.0",
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",