webcrawlerapi-js 1.1.1 → 1.1.3

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.
@@ -0,0 +1,19 @@
1
+ import { CrawlRequest, Job, JobId, ScrapeRequest, ScrapeResponse } from "./model";
2
+ import { JobStatus } from "./constants";
3
+ import { WebcrawlerApiError } from "./errors";
4
+ export { WebcrawlerApiError, JobStatus };
5
+ export * from "./model";
6
+ export declare class WebcrawlerClient {
7
+ protected apiVersion: string;
8
+ protected apiKey: string;
9
+ protected basePath: string;
10
+ constructor(apiKey: string, basePath?: string, apiVersion?: string);
11
+ scrapeAsync(scrapeRequest: ScrapeRequest): Promise<JobId>;
12
+ scrapeWithMeta(scrapeRequest: ScrapeRequest, maxPollingRetries?: number): Promise<ScrapeResponse>;
13
+ scrape(scrapeRequest: ScrapeRequest, maxPollingRetries?: number): Promise<any>;
14
+ getScrapeResult(scrapeID: string): Promise<ScrapeResponse>;
15
+ crawl(crawlRequest: CrawlRequest): Promise<Job>;
16
+ crawlAsync(crawlRequest: CrawlRequest): Promise<JobId>;
17
+ getJob(jobID: string): Promise<Job>;
18
+ private sendRequest;
19
+ }
@@ -0,0 +1,13 @@
1
+ export declare const JobStatus: {
2
+ readonly IN_PROGRESS: "in_progress";
3
+ readonly NEW: "new";
4
+ readonly DONE: "done";
5
+ };
6
+ export declare const HttpStatus: {
7
+ readonly OK: 200;
8
+ readonly BAD_REQUEST: 400;
9
+ readonly UNAUTHORIZED: 401;
10
+ readonly FORBIDDEN: 403;
11
+ readonly NOT_FOUND: 404;
12
+ readonly INTERNAL_SERVER_ERROR: 500;
13
+ };
@@ -0,0 +1,12 @@
1
+ export declare class WebcrawlerApiError extends Error {
2
+ errorCode: string;
3
+ errorMessage: string;
4
+ statusCode?: number;
5
+ constructor(errorCode: string, errorMessage: string, statusCode?: number);
6
+ }
7
+ export interface ErrorResponse {
8
+ error_code?: string;
9
+ error_message?: string;
10
+ error?: string;
11
+ }
12
+ export declare function createErrorFromResponse(response: Response, data: ErrorResponse): WebcrawlerApiError;
@@ -5,11 +5,9 @@ export interface ScrapeRequest {
5
5
  debug?: boolean;
6
6
  omit_cache?: boolean;
7
7
  }
8
-
9
8
  export interface JobId {
10
9
  id: string;
11
10
  }
12
-
13
11
  export interface ScrapeResponse {
14
12
  id: string;
15
13
  url: string;
@@ -19,7 +17,6 @@ export interface ScrapeResponse {
19
17
  structured_data: any;
20
18
  recommended_pull_delay_ms: number;
21
19
  }
22
-
23
20
  export interface CrawlRequest {
24
21
  url: string;
25
22
  items_limit?: number;
@@ -29,7 +26,6 @@ export interface CrawlRequest {
29
26
  allow_subdomains?: boolean;
30
27
  webhook_url?: string;
31
28
  }
32
-
33
29
  export interface Job {
34
30
  id: string;
35
31
  org_id: string;
@@ -47,7 +43,6 @@ export interface Job {
47
43
  recommended_pull_delay_ms: number;
48
44
  job_items: JobItem[];
49
45
  }
50
-
51
46
  export interface JobItem {
52
47
  id: string;
53
48
  job_id: string;
@@ -64,4 +59,4 @@ export interface JobItem {
64
59
  raw_content_url?: string;
65
60
  cleaned_content_url?: string;
66
61
  getContent(): Promise<string | null>;
67
- }
62
+ }
@@ -1,28 +1,37 @@
1
- import {CrawlRequest, Job, JobId, ScrapeRequest, ScrapeResponse} from "./model";
2
- import { JobStatus } from "./constants";
3
- import { WebcrawlerApiError, createErrorFromResponse, ErrorResponse } from "./errors";
4
-
5
- const BASE_PATH = "https://api.webcrawlerapi.com"
6
- const initialPullDelayMs = 2000
7
- const MaxPullRetries = 100
8
-
9
- export { WebcrawlerApiError, JobStatus };
10
- export * from "./model";
11
-
12
- export class WebcrawlerClient {
13
- protected apiVersion: string = "v1";
14
- protected apiKey: string
15
- protected basePath: string
16
-
17
- constructor(apiKey: string, basePath: string = BASE_PATH, apiVersion: string = "v1") {
18
- this.apiKey = apiKey ;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.WebcrawlerClient = exports.JobStatus = exports.WebcrawlerApiError = void 0;
18
+ const constants_1 = require("./constants");
19
+ Object.defineProperty(exports, "JobStatus", { enumerable: true, get: function () { return constants_1.JobStatus; } });
20
+ const errors_1 = require("./errors");
21
+ Object.defineProperty(exports, "WebcrawlerApiError", { enumerable: true, get: function () { return errors_1.WebcrawlerApiError; } });
22
+ const BASE_PATH = "https://api.webcrawlerapi.com";
23
+ const initialPullDelayMs = 2000;
24
+ const MaxPullRetries = 100;
25
+ __exportStar(require("./model"), exports);
26
+ class WebcrawlerClient {
27
+ constructor(apiKey, basePath = BASE_PATH, apiVersion = "v1") {
28
+ this.apiVersion = "v1";
29
+ this.apiKey = apiKey;
19
30
  this.basePath = basePath;
20
31
  this.apiVersion = apiVersion;
21
32
  }
22
-
23
- public async scrapeAsync(scrapeRequest: ScrapeRequest): Promise<JobId> {
33
+ async scrapeAsync(scrapeRequest) {
24
34
  const url = `${this.basePath}/${this.apiVersion}/scrape`;
25
-
26
35
  const requestOptions = {
27
36
  'method': 'POST',
28
37
  'headers': {
@@ -32,13 +41,10 @@ export class WebcrawlerClient {
32
41
  },
33
42
  'body': JSON.stringify(scrapeRequest),
34
43
  };
35
-
36
44
  return await this.sendRequest(url, requestOptions);
37
45
  }
38
-
39
- public async scrapeWithMeta(scrapeRequest: ScrapeRequest, maxPollingRetries: number = MaxPullRetries): Promise<ScrapeResponse> {
46
+ async scrapeWithMeta(scrapeRequest, maxPollingRetries = MaxPullRetries) {
40
47
  const url = `${this.basePath}/${this.apiVersion}/scrape`;
41
-
42
48
  const requestOptions = {
43
49
  'method': 'POST',
44
50
  'headers': {
@@ -47,13 +53,10 @@ export class WebcrawlerClient {
47
53
  },
48
54
  'body': JSON.stringify(scrapeRequest),
49
55
  };
50
-
51
- const jobIdResponse: JobId = await this.sendRequest(url, requestOptions);
52
-
56
+ const jobIdResponse = await this.sendRequest(url, requestOptions);
53
57
  if (jobIdResponse.id === '') {
54
- throw new WebcrawlerApiError('invalid_response', 'Failed to fetch job status', 0);
58
+ throw new errors_1.WebcrawlerApiError('invalid_response', 'Failed to fetch job status', 0);
55
59
  }
56
-
57
60
  let delayIntervalMs = initialPullDelayMs;
58
61
  for (let i = 0; i < maxPollingRetries; i++) {
59
62
  await new Promise(resolve => setTimeout(resolve, delayIntervalMs));
@@ -61,22 +64,20 @@ export class WebcrawlerClient {
61
64
  if (scrapeRequest.debug) {
62
65
  console.log(`Scrape result: ${JSON.stringify(scrapeResult)}`);
63
66
  }
64
- if (scrapeResult.status !== JobStatus.IN_PROGRESS && scrapeResult.status !== JobStatus.NEW) {
67
+ if (scrapeResult.status !== constants_1.JobStatus.IN_PROGRESS && scrapeResult.status !== constants_1.JobStatus.NEW) {
65
68
  return scrapeResult;
66
69
  }
67
70
  if (scrapeResult.recommended_pull_delay_ms > 0) {
68
71
  delayIntervalMs = scrapeResult.recommended_pull_delay_ms;
69
72
  }
70
73
  }
71
- throw new WebcrawlerApiError('timeout', 'Scraping took too long, please retry or increase the number of polling retries', 0);
74
+ throw new errors_1.WebcrawlerApiError('timeout', 'Scraping took too long, please retry or increase the number of polling retries', 0);
72
75
  }
73
-
74
- public async scrape(scrapeRequest: ScrapeRequest, maxPollingRetries: number = MaxPullRetries): Promise<any> {
76
+ async scrape(scrapeRequest, maxPollingRetries = MaxPullRetries) {
75
77
  const scrapeResult = await this.scrapeWithMeta(scrapeRequest, maxPollingRetries);
76
78
  return scrapeResult.structured_data;
77
79
  }
78
-
79
- public async getScrapeResult(scrapeID: string): Promise<ScrapeResponse> {
80
+ async getScrapeResult(scrapeID) {
80
81
  const url = `${this.basePath}/${this.apiVersion}/scrape/${scrapeID}`;
81
82
  const requestOptions = {
82
83
  'method': 'GET',
@@ -91,10 +92,8 @@ export class WebcrawlerClient {
91
92
  };
92
93
  return await this.sendRequest(url, requestOptions);
93
94
  }
94
-
95
- public async crawl(crawlRequest: CrawlRequest): Promise<Job> {
95
+ async crawl(crawlRequest) {
96
96
  const url = `${this.basePath}/${this.apiVersion}/crawl`;
97
-
98
97
  const requestOptions = {
99
98
  'method': 'POST',
100
99
  'headers': {
@@ -107,28 +106,24 @@ export class WebcrawlerClient {
107
106
  },
108
107
  'body': JSON.stringify(crawlRequest),
109
108
  };
110
-
111
- const jobIdResponse: JobId = await this.sendRequest(url, requestOptions);
112
-
109
+ const jobIdResponse = await this.sendRequest(url, requestOptions);
113
110
  if (jobIdResponse.id === '') {
114
- throw new WebcrawlerApiError('invalid_response', 'Failed to fetch job status', 0);
111
+ throw new errors_1.WebcrawlerApiError('invalid_response', 'Failed to fetch job status', 0);
115
112
  }
116
-
117
113
  let delayIntervalMs = initialPullDelayMs;
118
114
  for (let i = 0; i < MaxPullRetries; i++) {
119
115
  await new Promise(resolve => setTimeout(resolve, delayIntervalMs));
120
116
  const timestamp = new Date().getTime();
121
117
  const job = await this.getJob(`${jobIdResponse.id}?t=${timestamp}`);
122
- if (job.status !== JobStatus.IN_PROGRESS && job.status !== JobStatus.NEW) {
118
+ if (job.status !== constants_1.JobStatus.IN_PROGRESS && job.status !== constants_1.JobStatus.NEW) {
123
119
  // Transform each job item to include getContent method
124
120
  job.job_items = job.job_items.map(item => ({
125
121
  ...item,
126
- getContent: async function(): Promise<string | null> {
127
- if (job.status !== JobStatus.DONE || this.status !== JobStatus.DONE) {
122
+ getContent: async function () {
123
+ if (job.status !== constants_1.JobStatus.DONE || this.status !== constants_1.JobStatus.DONE) {
128
124
  return null;
129
125
  }
130
-
131
- let contentUrl: string | undefined;
126
+ let contentUrl;
132
127
  switch (job.scrape_type) {
133
128
  case 'html':
134
129
  contentUrl = this.raw_content_url;
@@ -140,22 +135,18 @@ export class WebcrawlerClient {
140
135
  contentUrl = this.markdown_content_url;
141
136
  break;
142
137
  }
143
-
144
138
  if (!contentUrl) {
145
139
  return null;
146
140
  }
147
-
148
141
  const response = await fetch(contentUrl, {
149
142
  headers: {
150
143
  'Accept-Encoding': 'gzip, deflate, br',
151
144
  'Accept': '*/*'
152
145
  }
153
146
  });
154
-
155
147
  if (!response.ok) {
156
148
  throw new Error(`Failed to fetch content: ${response.statusText}`);
157
149
  }
158
-
159
150
  return await response.text();
160
151
  }
161
152
  }));
@@ -165,12 +156,10 @@ export class WebcrawlerClient {
165
156
  delayIntervalMs = job.recommended_pull_delay_ms;
166
157
  }
167
158
  }
168
- throw new WebcrawlerApiError('timeout', 'Crawling took too long, please retry or increase the number of polling retries', 0);
159
+ throw new errors_1.WebcrawlerApiError('timeout', 'Crawling took too long, please retry or increase the number of polling retries', 0);
169
160
  }
170
-
171
- public async crawlAsync(crawlRequest: CrawlRequest): Promise<JobId> {
161
+ async crawlAsync(crawlRequest) {
172
162
  const url = `${this.basePath}/${this.apiVersion}/crawl`;
173
-
174
163
  const requestOptions = {
175
164
  'method': 'POST',
176
165
  'headers': {
@@ -179,11 +168,9 @@ export class WebcrawlerClient {
179
168
  },
180
169
  'body': JSON.stringify(crawlRequest),
181
170
  };
182
-
183
171
  return await this.sendRequest(url, requestOptions);
184
172
  }
185
-
186
- public async getJob(jobID: string): Promise<Job> {
173
+ async getJob(jobID) {
187
174
  const url = `${this.basePath}/${this.apiVersion}/job/${jobID}`;
188
175
  const requestOptions = {
189
176
  'method': 'GET',
@@ -198,35 +185,28 @@ export class WebcrawlerClient {
198
185
  };
199
186
  return await this.sendRequest(url, requestOptions);
200
187
  }
201
-
202
- private async sendRequest(url: string, requestOptions: any): Promise<any> {
203
- let response: Response;
188
+ async sendRequest(url, requestOptions) {
189
+ let response;
204
190
  try {
205
191
  response = await fetch(url, requestOptions);
206
- } catch (e) {
207
- throw new WebcrawlerApiError('network_error', `Failed to send request: ${e}`, 0);
208
192
  }
209
-
193
+ catch (e) {
194
+ throw new errors_1.WebcrawlerApiError('network_error', `Failed to send request: ${e}`, 0);
195
+ }
210
196
  if (!response.ok) {
211
197
  try {
212
- const errorData = await response.json() as ErrorResponse;
213
- throw createErrorFromResponse(response, errorData);
214
- } catch (e) {
215
- if (e instanceof WebcrawlerApiError) {
198
+ const errorData = await response.json();
199
+ throw (0, errors_1.createErrorFromResponse)(response, errorData);
200
+ }
201
+ catch (e) {
202
+ if (e instanceof errors_1.WebcrawlerApiError) {
216
203
  throw e;
217
204
  }
218
205
  // If we can't parse the error response, create a generic error
219
- throw new WebcrawlerApiError(
220
- 'unknown_error',
221
- `Request failed with status ${response.status} ${response.statusText}`,
222
- response.status
223
- );
206
+ throw new errors_1.WebcrawlerApiError('unknown_error', `Request failed with status ${response.status} ${response.statusText}`, response.status);
224
207
  }
225
208
  }
226
-
227
209
  return response.json();
228
210
  }
229
211
  }
230
-
231
-
232
-
212
+ exports.WebcrawlerClient = WebcrawlerClient;
@@ -1,14 +1,16 @@
1
- export const JobStatus = {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpStatus = exports.JobStatus = void 0;
4
+ exports.JobStatus = {
2
5
  IN_PROGRESS: 'in_progress',
3
6
  NEW: 'new',
4
7
  DONE: 'done'
5
- } as const;
6
-
7
- export const HttpStatus = {
8
+ };
9
+ exports.HttpStatus = {
8
10
  OK: 200,
9
11
  BAD_REQUEST: 400,
10
12
  UNAUTHORIZED: 401,
11
13
  FORBIDDEN: 403,
12
14
  NOT_FOUND: 404,
13
15
  INTERNAL_SERVER_ERROR: 500
14
- } as const;
16
+ };
package/dist/errors.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebcrawlerApiError = void 0;
4
+ exports.createErrorFromResponse = createErrorFromResponse;
5
+ class WebcrawlerApiError extends Error {
6
+ constructor(errorCode, errorMessage, statusCode) {
7
+ super(errorMessage);
8
+ this.name = 'WebcrawlerApiError';
9
+ this.errorCode = errorCode;
10
+ this.errorMessage = errorMessage;
11
+ this.statusCode = statusCode;
12
+ }
13
+ }
14
+ exports.WebcrawlerApiError = WebcrawlerApiError;
15
+ function createErrorFromResponse(response, data) {
16
+ const errorCode = data.error_code || 'unknown_error';
17
+ const errorMessage = data.error_message || data.error || 'Unknown error';
18
+ return new WebcrawlerApiError(errorCode, errorMessage, response.status);
19
+ }
package/dist/model.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "webcrawlerapi-js",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
 
5
5
  "description": "JS client for WebcrawlerAPI",
6
6
  "main": "./dist/api.js",
7
7
  "types": "./dist/@types/api.d.ts",
8
+ "files": [
9
+ "dist/",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
8
13
  "scripts": {
9
14
  "build": "tsc --outDir dist/"
10
15
  },
@@ -21,7 +26,7 @@
21
26
  "@types/node": "^22.4.0",
22
27
  "typescript": "^5.5.4"
23
28
  },
24
- "author": "Andrew <sdk@webcrawlerapi.com>",
29
+ "author": "WebcrawlerAPI <sdk@webcrawlerapi.com>",
25
30
  "license": "MIT",
26
31
  "dependencies": {}
27
32
  }
package/src/errors.ts DELETED
@@ -1,25 +0,0 @@
1
- export class WebcrawlerApiError extends Error {
2
- public errorCode: string;
3
- public errorMessage: string;
4
- public statusCode?: number;
5
-
6
- constructor(errorCode: string, errorMessage: string, statusCode?: number) {
7
- super(errorMessage);
8
- this.name = 'WebcrawlerApiError';
9
- this.errorCode = errorCode;
10
- this.errorMessage = errorMessage;
11
- this.statusCode = statusCode;
12
- }
13
- }
14
-
15
- export interface ErrorResponse {
16
- error_code?: string;
17
- error_message?: string;
18
- error?: string;
19
- }
20
-
21
- export function createErrorFromResponse(response: Response, data: ErrorResponse): WebcrawlerApiError {
22
- const errorCode = data.error_code || 'unknown_error';
23
- const errorMessage = data.error_message || data.error || 'Unknown error';
24
- return new WebcrawlerApiError(errorCode, errorMessage, response.status);
25
- }
package/tsconfig.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "lib": [
4
- "es2021"
5
- ],
6
- "module": "commonjs",
7
- "target": "es2021",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "outDir": "dist",
13
- "declarationDir": "dist/@types",
14
- "declaration": true
15
- },
16
- "include": [
17
- "src/**/*"
18
- ],
19
- "exclude": [
20
- "dist",
21
- "node_modules"
22
- ]
23
- }