thordata 0.0.0-stage → 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Added an independent SERP client and raw response access.
6
+ - Added task creation, polling, downloading, and status results for seven Web Scraper products.
7
+ - Fixed rawSearch engine normalization, cancellation errors, and Web Scraper parameter messages.
8
+ - Added cross-language contract fixture checks and non-zero example failure exit codes.
9
+ - Added request ID fallback for bare SERP results, business error classification, and parameter messages.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thordata
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,95 @@
1
- # Temporary Holding Version
1
+ # Thordata JavaScript SDK
2
+
3
+ JavaScript/Node.js client for the Thordata SERP API and seven verified Web Scraper products. The package is independent of LangChain and requires Node.js 18 or newer.
2
4
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
5
+ Turn live web data into reliable Node.js applications faster. Thordata JavaScript SDK gives developers one interface for real-time search and structured web scraping, making it easier to build research tools, monitoring services, data pipelines, RAG systems, and AI agents.
6
+
7
+ Use it to track search visibility, enrich business and product data, monitor markets, or bring fresh web data into JavaScript and TypeScript applications without maintaining a separate scraper for every target.
8
+
9
+ ## Why Thordata JavaScript SDK
10
+
11
+ - **Search and scrape through one client**: Query live search engines and collect structured records through ready-to-use Web Scraper actions.
12
+ - **Built for Node.js workflows**: Add web intelligence to backend services, scheduled jobs, automation, and AI applications with a familiar JavaScript interface.
13
+ - **Simple async integration**: Use promises and standard Node.js patterns for search and structured data collection.
14
+ - **Ready for downstream systems**: Pass structured results into analytics, enrichment, RAG, agents, and internal applications.
15
+ - **Designed for dependable use**: Benefit from predictable response handling, bounded task polling, and redacted diagnostics in production workflows.
16
+
17
+ Create a Thordata account to get started:
18
+
19
+ - [Get started with Thordata](https://www.thordata.com/?ls=github&lk=thordata)
20
+ - [Read the official documentation](https://doc.thordata.com)
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ npm install thordata
26
+ ```
27
+
28
+ Set `THORDATA_API_KEY`, `THORDATA_API_TOKEN`, or the compatible `TALORDATA_API_TOKEN` environment variable. `apiKey`, `apiToken`, or `token` constructor options take precedence.
29
+
30
+ ## SERP
31
+
32
+ ```js
33
+ const { Client } = require("thordata");
34
+
35
+ async function main() {
36
+ const client = new Client();
37
+ const result = await client.search({
38
+ engine: "google_search",
39
+ q: "latest AI agent research",
40
+ gl: "us",
41
+ hl: "en",
42
+ });
43
+ console.log(result);
44
+ }
45
+
46
+ main().catch(console.error);
47
+ ```
48
+
49
+ Requests are form-encoded `POST` calls to `https://scraperapi.thordata.com/request` with Bearer authentication. SERP source headers are `Origin: JavaScript`, `platform: javascript`, and `api-source: sdk`. The client supports the verified Thordata engines and API-native parameters. `google_search` maps to `google`, `google_places` maps to `google_local`, and `query`, `country`, and `language` map to `q`, `gl`, and `hl`. Yandex sends `q` as `text`. Boolean values become `1` or `0`, and unknown fields are ignored.
50
+
51
+ Use `searchResponse()` for task metadata and the raw response envelope, and `rawSearch()` for the unparsed response body. `taskId` comes from the upstream envelope when present and falls back to `search_metadata.id` for bare SERP results. The raw response keeps the engine-specific shape; Google commonly returns `organic`/`images`/`places`, while other engines may return `organic_results` or similar fields. `rawSearch()` returns text without interpreting business error codes. The SDK does not expose `searchHtml()` because the current `/request` endpoint does not guarantee HTML.
52
+
53
+ ## Web Scraper
54
+
55
+ The initial SDK supports these spider IDs:
56
+
57
+ - `linkedin_company_information_by-url`: `url`
58
+ - `linkedin_job_listings_information_by-job-url`: `job_url`
59
+ - `youtube_video-post_by-keyword`: `keyword`, optional `num_of_posts`
60
+ - `facebook_profile_by-profiles-url`: `url`
61
+ - `youtube_video-post_by-explore`: `url`, optional `all_tabs`
62
+ - `twitter_profile_by-profileurl`: `url`
63
+ - `amazon_product_by-category-url`: `url`, `page_turning`, optional `sort_by`
64
+
65
+ ```js
66
+ const { Client } = require("thordata");
67
+
68
+ const client = new Client();
69
+ const records = await client.scrape(
70
+ "linkedin_company_information_by-url",
71
+ { url: "https://www.linkedin.com/company/microsoft" },
72
+ );
73
+ console.log(records);
74
+ ```
75
+
76
+ `scrape()` submits one task, polls every five seconds, and downloads final JSON records. Web Scraper source fields are form parameters `api_source=sdk` and `source_platform=javascript`; they are not request headers. Amazon uses `Best Sellers` when `sort_by` is omitted. The total wait is capped at 300 seconds by default. Use `scrapeResponse()` for `taskId`, `spiderId`, `status`, `recordCount`, and `errorRecordCount`. Status is `completed`, `partial`, or `empty`. Pass an `AbortSignal` to cancel local waiting.
77
+
78
+ For API errors, `code` is the Thordata business code and `statusCode` is the HTTP status. Business errors can therefore have `statusCode: 200`.
79
+
80
+ Web Scraper errors retain their stage and task ID when safe, while API keys and signed URLs are redacted from error text and diagnostic data.
81
+
82
+ ## Local checks
83
+
84
+ ```bash
85
+ npm test
86
+ npm run check
87
+ ```
88
+
89
+ Tests use a mocked `fetch` and do not consume Thordata credits. See `examples/` for runnable SERP and Web Scraper examples.
90
+
91
+ ## Start Building
92
+
93
+ Start with a SERP query for live web intelligence, add a Web Scraper action when you need structured records, and connect the results to the systems your team already uses. The same SDK can support a quick prototype today and a repeatable Node.js data pipeline tomorrow.
94
+
95
+ [Explore Thordata SERP API](https://www.thordata.com/products/serp-api?op=flora&from=github) | [Explore Thordata Web Scraper](https://www.thordata.com/products/web-scraper?op=flora&from=github)
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ const { Client } = require("../src");
4
+
5
+ async function main() {
6
+ const client = new Client();
7
+ const result = await client.search({
8
+ engine: "google_search",
9
+ q: "latest AI agent research",
10
+ gl: "us",
11
+ hl: "en",
12
+ num: 5,
13
+ });
14
+ console.log(result);
15
+ }
16
+
17
+ main().catch((error) => {
18
+ console.error(error);
19
+ process.exitCode = 1;
20
+ });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ const { Client } = require("../src");
4
+
5
+ async function main() {
6
+ const client = new Client();
7
+ const records = await client.scrape(
8
+ "linkedin_company_information_by-url",
9
+ { url: "https://www.linkedin.com/company/microsoft" },
10
+ );
11
+ console.log(records);
12
+ }
13
+
14
+ main().catch((error) => {
15
+ console.error(error);
16
+ process.exitCode = 1;
17
+ });
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ const { Client } = require("../src");
4
+
5
+ async function main() {
6
+ const client = new Client();
7
+ const result = await client.search({
8
+ engine: "google_flights",
9
+ departure_id: "SFO",
10
+ arrival_id: "JFK",
11
+ outbound_date: "2026-12-01",
12
+ return_date: "2026-12-08",
13
+ });
14
+ console.log(result);
15
+ }
16
+
17
+ main().catch((error) => {
18
+ console.error(error);
19
+ process.exitCode = 1;
20
+ });
package/package.json CHANGED
@@ -1,6 +1,36 @@
1
1
  {
2
2
  "name": "thordata",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "JavaScript SDK for the Thordata SERP API and Web Scraper",
5
+ "author": {
6
+ "name": "Thordata",
7
+ "email": "cianna@thordata.com"
8
+ },
9
+ "homepage": "https://github.com/Thordata/thordata-javascript#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/Thordata/thordata-javascript.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/Thordata/thordata-javascript/issues"
16
+ },
17
+ "main": "src/index.js",
18
+ "types": "src/index.d.ts",
19
+ "type": "commonjs",
20
+ "files": [
21
+ "src",
22
+ "examples",
23
+ "README.md",
24
+ "CHANGELOG.md",
25
+ "LICENSE"
26
+ ],
27
+ "scripts": {
28
+ "test": "node --test",
29
+ "check": "node --check src/index.js && node --check src/serp.js && node --check src/web-scraper.js && node --check src/errors.js"
30
+ },
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "keywords": ["thordata", "serp", "search", "web-scraper", "sdk"],
35
+ "license": "MIT"
36
+ }
package/src/errors.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ class ThorDataError extends Error {
4
+ constructor(message, options = {}) {
5
+ super(message, options);
6
+ this.name = new.target.name;
7
+ }
8
+ }
9
+
10
+ module.exports = { ThorDataError };
package/src/index.d.ts ADDED
@@ -0,0 +1,198 @@
1
+ export type SearchEngine =
2
+ | "google"
3
+ | "google_search"
4
+ | "google_light"
5
+ | "google_web"
6
+ | "google_images"
7
+ | "google_videos"
8
+ | "google_news"
9
+ | "google_shopping"
10
+ | "google_local"
11
+ | "google_places"
12
+ | "google_product"
13
+ | "google_lens"
14
+ | "google_trends"
15
+ | "google_maps"
16
+ | "google_hotels"
17
+ | "google_jobs"
18
+ | "google_scholar"
19
+ | "google_scholar_cite"
20
+ | "google_scholar_author"
21
+ | "google_play"
22
+ | "google_play_product"
23
+ | "google_play_games"
24
+ | "google_play_movies"
25
+ | "google_play_books"
26
+ | "google_finance"
27
+ | "google_finance_markets"
28
+ | "google_flights"
29
+ | "google_patents"
30
+ | "google_patents_details"
31
+ | "google_ai_mode"
32
+ | "bing"
33
+ | "bing_images"
34
+ | "bing_videos"
35
+ | "bing_news"
36
+ | "bing_shopping"
37
+ | "bing_maps"
38
+ | "yandex"
39
+ | "duckduckgo";
40
+
41
+ export type SearchParams = Record<string, unknown> & {
42
+ engine?: SearchEngine | string;
43
+ q?: string;
44
+ query?: string;
45
+ gl?: string;
46
+ country?: string;
47
+ hl?: string;
48
+ language?: string;
49
+ json?: string | number;
50
+ isjson?: string | number | boolean;
51
+ };
52
+
53
+ export type WebScraperId =
54
+ | "linkedin_company_information_by-url"
55
+ | "linkedin_job_listings_information_by-job-url"
56
+ | "youtube_video-post_by-keyword"
57
+ | "facebook_profile_by-profiles-url"
58
+ | "youtube_video-post_by-explore"
59
+ | "twitter_profile_by-profileurl"
60
+ | "amazon_product_by-category-url";
61
+
62
+ export type WebScraperParams = Record<string, unknown>;
63
+
64
+ export interface WebScraperOptions {
65
+ maxWaitSeconds?: number;
66
+ includeErrors?: boolean;
67
+ fileName?: string;
68
+ signal?: AbortSignal;
69
+ }
70
+
71
+ export interface WebScraperResponse<T = unknown> {
72
+ result: T;
73
+ taskId: string;
74
+ spiderId: WebScraperId;
75
+ status: "completed" | "partial" | "empty";
76
+ recordCount: number;
77
+ errorRecordCount: number;
78
+ raw: unknown;
79
+ }
80
+
81
+ export interface SearchResponse<T = unknown> {
82
+ result: T;
83
+ taskId: string | null;
84
+ raw: Record<string, unknown> | unknown;
85
+ }
86
+
87
+ export interface RequestOptions {
88
+ headers?: Record<string, string>;
89
+ signal?: AbortSignal;
90
+ filterParams?: boolean;
91
+ }
92
+
93
+ export interface ThorDataClientOptions {
94
+ apiKey?: string;
95
+ apiToken?: string;
96
+ token?: string;
97
+ apiUrl?: string;
98
+ baseUrl?: string;
99
+ timeout?: number;
100
+ headers?: Record<string, string>;
101
+ }
102
+
103
+ export declare const DEFAULT_API_URL: string;
104
+ export declare const DEFAULT_TIMEOUT_MS: number;
105
+ export declare const DEFAULT_MAX_WAIT_SECONDS: number;
106
+ export declare const INTEGRATION_PLATFORM: string;
107
+ export declare const INTEGRATION_SOURCE: string;
108
+ export declare const REQUEST_PARAMETERS: ReadonlySet<string>;
109
+ export declare const SUPPORTED_ENGINES: readonly SearchEngine[];
110
+ export declare const SUPPORTED_WEB_SCRAPERS: readonly WebScraperId[];
111
+
112
+ export declare class ThorDataError extends Error {}
113
+ export declare class ThorDataConfigurationError extends ThorDataError {}
114
+ export declare class ThorDataConnectionError extends ThorDataError {}
115
+ export declare class ThorDataTimeoutError extends ThorDataConnectionError {}
116
+
117
+ export interface ThorDataAPIErrorOptions {
118
+ code?: number | null;
119
+ statusCode?: number | null;
120
+ responseData?: unknown;
121
+ }
122
+
123
+ export declare class ThorDataAPIError extends ThorDataError {
124
+ code: number | null;
125
+ statusCode: number | null;
126
+ responseData: unknown;
127
+ constructor(message: string, options?: ThorDataAPIErrorOptions);
128
+ }
129
+
130
+ export declare class ThorDataAuthenticationError extends ThorDataAPIError {}
131
+ export declare class ThorDataPermissionError extends ThorDataAPIError {}
132
+ export declare class ThorDataRateLimitError extends ThorDataAPIError {}
133
+ export declare class ThorDataInvalidRequestError extends ThorDataAPIError {}
134
+ export declare class ThorDataNotCollectedError extends ThorDataAPIError {}
135
+
136
+ export interface ThorDataWebScraperErrorOptions {
137
+ stage?: string;
138
+ taskId?: string | null;
139
+ spiderId?: string | null;
140
+ reason?: unknown;
141
+ serviceCode?: string | number | null;
142
+ secrets?: readonly string[];
143
+ }
144
+
145
+ export declare class ThorDataWebScraperError extends ThorDataError {
146
+ errorCode: string;
147
+ stage: string;
148
+ taskId: string | null;
149
+ spiderId: string | null;
150
+ reason: string | null;
151
+ serviceCode: string | number | null;
152
+ constructor(errorCode: string, options?: ThorDataWebScraperErrorOptions);
153
+ }
154
+
155
+ export declare class ThorDataClient {
156
+ readonly apiKey: string;
157
+ readonly apiUrl: string;
158
+ readonly baseUrl: string;
159
+ readonly timeout: number;
160
+ readonly headers: Record<string, string>;
161
+
162
+ constructor(options?: ThorDataClientOptions);
163
+ toString(): string;
164
+ request(
165
+ method: string,
166
+ path?: string,
167
+ params?: Record<string, unknown>,
168
+ options?: RequestOptions,
169
+ ): Promise<Response>;
170
+ search<T = unknown>(params?: SearchParams, options?: RequestOptions): Promise<T>;
171
+ searchJson<T = unknown>(params?: SearchParams, options?: RequestOptions): Promise<T>;
172
+ searchResponse<T = unknown>(params?: SearchParams, options?: RequestOptions): Promise<SearchResponse<T>>;
173
+ rawSearch(params?: Record<string, unknown>, options?: RequestOptions): Promise<string>;
174
+ scrape<T = unknown>(
175
+ spiderId: WebScraperId,
176
+ params?: WebScraperParams,
177
+ options?: WebScraperOptions,
178
+ ): Promise<T>;
179
+ scrapeResponse<T = unknown>(
180
+ spiderId: WebScraperId,
181
+ params?: WebScraperParams,
182
+ options?: WebScraperOptions,
183
+ ): Promise<WebScraperResponse<T>>;
184
+ }
185
+
186
+ export declare const Client: typeof ThorDataClient;
187
+ export declare function search<T = unknown>(
188
+ params?: SearchParams,
189
+ options?: ThorDataClientOptions & RequestOptions,
190
+ ): Promise<T>;
191
+ export declare function searchJson<T = unknown>(
192
+ params?: SearchParams,
193
+ options?: ThorDataClientOptions & RequestOptions,
194
+ ): Promise<T>;
195
+ export declare function rawSearch(
196
+ params?: Record<string, unknown>,
197
+ options?: ThorDataClientOptions & RequestOptions,
198
+ ): Promise<string>;