@hydrafetch/node-sdk 0.4.0 → 0.6.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/README.md +47 -1
- package/dist/index.cjs +19 -1
- package/dist/index.d.cts +91 -1
- package/dist/index.d.ts +91 -1
- package/dist/index.js +19 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ const page = await hf.scrape('https://example.com/article');
|
|
|
25
25
|
console.log(page.markdown);
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Copy your key from [app.hydrafetch.com](https://app.hydrafetch.com). The constructor reads `HYDRAFETCH_API_KEY` when no key is passed.
|
|
29
29
|
|
|
30
30
|
## Scraping
|
|
31
31
|
|
|
@@ -166,6 +166,31 @@ const { results } = await hf.search('post-quantum TLS adoption', {
|
|
|
166
166
|
results.forEach((r) => console.log(r.title, r.url, r.data?.markdown));
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
+
## Jobs
|
|
170
|
+
|
|
171
|
+
Search open jobs collected from company career sites and hiring platforms, by the words in the job title:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
const jobs = await hf.searchJobs('data engineer', {
|
|
175
|
+
location: 'Berlin',
|
|
176
|
+
postedWithinDays: 14,
|
|
177
|
+
limit: 20,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
jobs.forEach((j) => console.log(j.title, j.company, j.location, j.url));
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
See what changed in a company's hiring since a date: what is open now, what opened and what closed, by department, seniority and location, with the jobs themselves:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const [acme] = await hf.hiringChanges('acme.com', '2026-10-01');
|
|
187
|
+
|
|
188
|
+
console.log(acme.totals); // { open: 42, opened: 6, closed: 3 }
|
|
189
|
+
acme.opened.forEach((j) => console.log(j.title, j.seniority, j.firstSeenAt));
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
A search costs 1 credit per 10 jobs returned, and an empty one is free. Hiring changes cost 1 credit per company we have jobs for; companies we do not track yet come back empty and are free.
|
|
193
|
+
|
|
169
194
|
## Brand data
|
|
170
195
|
|
|
171
196
|
```ts
|
|
@@ -177,6 +202,24 @@ await hf.styleguide('https://stripe.com/pricing', { maxAge: 0 }); // one page, r
|
|
|
177
202
|
|
|
178
203
|
For logos in a browser use [`@hydrafetch/client-sdk`](https://github.com/Hydrafetch/client-sdk) or [`@hydrafetch/react`](https://github.com/Hydrafetch/react-sdk) with a publishable key. Those bill against logo pulls rather than credits.
|
|
179
204
|
|
|
205
|
+
## Rating results
|
|
206
|
+
|
|
207
|
+
Tell us when a result was wrong, so it gets looked at. It is free, and rating the same request again replaces the earlier rating.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
const page = await hf.scrape('https://stripe.com/pricing');
|
|
211
|
+
await hf.rateResult({
|
|
212
|
+
requestId: hf.lastRequestId,
|
|
213
|
+
rating: 'bad',
|
|
214
|
+
reasons: ['missing_content'],
|
|
215
|
+
note: 'The enterprise tier is missing',
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
await hf.rateResult({ url: 'https://stripe.com/pricing', rating: 'good' }); // by URL, last 24 hours
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Reasons are `missing_content`, `wrong_content`, `blocked`, `slow`, `formatting` and `other`.
|
|
222
|
+
|
|
180
223
|
## Error handling
|
|
181
224
|
|
|
182
225
|
All failures throw `HydrafetchError`, carrying the API's error code, HTTP status and request id.
|
|
@@ -233,6 +276,8 @@ const hf = new Hydrafetch({
|
|
|
233
276
|
| `markdown(url, options?)` | `string` | 1 |
|
|
234
277
|
| `map(url, options?)` | `MapResult` | 1 |
|
|
235
278
|
| `search(query, options?)` | `SearchResult` | 1 + 1 per scraped result |
|
|
279
|
+
| `searchJobs(query, options?)` | `OpenJob[]` | 1 per 10 jobs |
|
|
280
|
+
| `hiringChanges(domains, since, options?)` | `CompanyHiringChanges[]` | 1 per company with jobs |
|
|
236
281
|
| `extract(urls, options?)` | `ExtractResult<T>` | 5 per URL |
|
|
237
282
|
| `brand(domain)` | `BrandResult` | 5 |
|
|
238
283
|
| `logo(domain, options?)` | `LogoResult` | 1 |
|
|
@@ -245,6 +290,7 @@ const hf = new Hydrafetch({
|
|
|
245
290
|
| `startCrawl(url, options?)` | `string` | 1 per page |
|
|
246
291
|
| `startBatch(urls, options?)` | `string` | 1 per page |
|
|
247
292
|
| `crawlStatus(id)`, `batchStatus(id)` | `JobResult` | free |
|
|
293
|
+
| `rateResult(input)` | `RateResultResponse` | free |
|
|
248
294
|
|
|
249
295
|
Failed requests are not billed. Pricing does not vary with page difficulty, so there is no render, stealth or proxy option to set.
|
|
250
296
|
|
package/dist/index.cjs
CHANGED
|
@@ -129,6 +129,10 @@ var Hydrafetch = class {
|
|
|
129
129
|
timeoutMs;
|
|
130
130
|
maxRetries;
|
|
131
131
|
fetchImpl;
|
|
132
|
+
latestRequestId;
|
|
133
|
+
get lastRequestId() {
|
|
134
|
+
return this.latestRequestId;
|
|
135
|
+
}
|
|
132
136
|
constructor(options = {}) {
|
|
133
137
|
const opts = typeof options === "string" ? { apiKey: options } : options;
|
|
134
138
|
const env = globalThis.process?.env;
|
|
@@ -136,7 +140,7 @@ var Hydrafetch = class {
|
|
|
136
140
|
if (!apiKey) {
|
|
137
141
|
throw new HydrafetchError({
|
|
138
142
|
code: "MISSING_API_KEY",
|
|
139
|
-
message: "No API key. Pass one to the constructor or set HYDRAFETCH_API_KEY.
|
|
143
|
+
message: "No API key. Pass one to the constructor or set HYDRAFETCH_API_KEY. Copy your key from https://app.hydrafetch.com.",
|
|
140
144
|
status: 401
|
|
141
145
|
});
|
|
142
146
|
}
|
|
@@ -174,6 +178,7 @@ var Hydrafetch = class {
|
|
|
174
178
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
175
179
|
signal: controller.signal
|
|
176
180
|
});
|
|
181
|
+
this.latestRequestId = res.headers.get("x-request-id") ?? this.latestRequestId;
|
|
177
182
|
const text = await res.text();
|
|
178
183
|
let parsed;
|
|
179
184
|
try {
|
|
@@ -221,12 +226,25 @@ var Hydrafetch = class {
|
|
|
221
226
|
const page = await this.scrape(url, { ...options, formats: ["markdown"] });
|
|
222
227
|
return page.markdown;
|
|
223
228
|
}
|
|
229
|
+
rateResult(input) {
|
|
230
|
+
return this.request("POST", "/v1/web/feedback", input);
|
|
231
|
+
}
|
|
224
232
|
map(url, options = {}) {
|
|
225
233
|
return this.request("POST", "/v1/web/map", { url, ...options });
|
|
226
234
|
}
|
|
227
235
|
search(query, options = {}) {
|
|
228
236
|
return this.request("POST", "/v1/web/search", { query, ...options });
|
|
229
237
|
}
|
|
238
|
+
searchJobs(query, options = {}) {
|
|
239
|
+
return this.request("POST", "/v1/web/index/jobs/search", { query, ...options });
|
|
240
|
+
}
|
|
241
|
+
hiringChanges(domains, since, options = {}) {
|
|
242
|
+
return this.request("POST", "/v1/web/index/jobs/changes", {
|
|
243
|
+
domains: Array.isArray(domains) ? domains : [domains],
|
|
244
|
+
since: since instanceof Date ? since.toISOString() : since,
|
|
245
|
+
...options
|
|
246
|
+
});
|
|
247
|
+
}
|
|
230
248
|
async extract(urls, options = {}) {
|
|
231
249
|
const { schema, ...rest } = options;
|
|
232
250
|
return this.request("POST", "/v1/web/extract", {
|
package/dist/index.d.cts
CHANGED
|
@@ -238,6 +238,91 @@ interface WaitOptions {
|
|
|
238
238
|
pollIntervalMs?: number;
|
|
239
239
|
onProgress?: (job: JobResult) => void;
|
|
240
240
|
}
|
|
241
|
+
type ResultRating = 'good' | 'bad';
|
|
242
|
+
type ResultFeedbackReason = 'missing_content' | 'wrong_content' | 'blocked' | 'slow' | 'formatting' | 'other';
|
|
243
|
+
interface RateResultInput {
|
|
244
|
+
requestId?: string;
|
|
245
|
+
url?: string;
|
|
246
|
+
rating: ResultRating;
|
|
247
|
+
reasons?: ResultFeedbackReason[];
|
|
248
|
+
note?: string;
|
|
249
|
+
}
|
|
250
|
+
interface RateResultResponse {
|
|
251
|
+
id: string;
|
|
252
|
+
requestId: string;
|
|
253
|
+
rating: ResultRating;
|
|
254
|
+
}
|
|
255
|
+
interface SearchJobsOptions {
|
|
256
|
+
/** A city, region or country to match, like "Berlin". */
|
|
257
|
+
location?: string;
|
|
258
|
+
/** Only jobs marked remote. */
|
|
259
|
+
remoteOnly?: boolean;
|
|
260
|
+
/** Only jobs posted in the last N days (1 to 365). */
|
|
261
|
+
postedWithinDays?: number;
|
|
262
|
+
/** Max jobs to return, 1 to 100 (default 10). Each 10 jobs returned cost 1 credit. */
|
|
263
|
+
limit?: number;
|
|
264
|
+
/** Include each job's description text when we hold it. */
|
|
265
|
+
includeDescriptions?: boolean;
|
|
266
|
+
}
|
|
267
|
+
interface JobPay {
|
|
268
|
+
min: number | null;
|
|
269
|
+
max: number | null;
|
|
270
|
+
currency: string | null;
|
|
271
|
+
interval: string | null;
|
|
272
|
+
}
|
|
273
|
+
interface OpenJob {
|
|
274
|
+
title: string;
|
|
275
|
+
company: string | null;
|
|
276
|
+
/** The company's website. */
|
|
277
|
+
domain: string;
|
|
278
|
+
/** The hiring platform the job is posted on. */
|
|
279
|
+
board: string;
|
|
280
|
+
department: string | null;
|
|
281
|
+
location: string | null;
|
|
282
|
+
remote: boolean | null;
|
|
283
|
+
employmentType: string | null;
|
|
284
|
+
postedAt: string | null;
|
|
285
|
+
/** When the job was first seen open. */
|
|
286
|
+
firstSeenAt: string;
|
|
287
|
+
url: string | null;
|
|
288
|
+
applyUrl: string | null;
|
|
289
|
+
pay: JobPay | null;
|
|
290
|
+
description?: string | null;
|
|
291
|
+
}
|
|
292
|
+
interface HiringChangesOptions {
|
|
293
|
+
/** Include each opened and closed job's description text when we hold it. */
|
|
294
|
+
includeDescriptions?: boolean;
|
|
295
|
+
}
|
|
296
|
+
interface HiringCounts {
|
|
297
|
+
open: number;
|
|
298
|
+
opened: number;
|
|
299
|
+
closed: number;
|
|
300
|
+
}
|
|
301
|
+
interface HiringChangePosting {
|
|
302
|
+
title: string;
|
|
303
|
+
department: string | null;
|
|
304
|
+
location: string | null;
|
|
305
|
+
seniority: string;
|
|
306
|
+
board: string;
|
|
307
|
+
url: string | null;
|
|
308
|
+
postedAt: string | null;
|
|
309
|
+
firstSeenAt: string;
|
|
310
|
+
closedAt: string | null;
|
|
311
|
+
description?: string | null;
|
|
312
|
+
}
|
|
313
|
+
interface CompanyHiringChanges {
|
|
314
|
+
domain: string;
|
|
315
|
+
company: string | null;
|
|
316
|
+
lastReadAt: string | null;
|
|
317
|
+
since: string;
|
|
318
|
+
totals: HiringCounts;
|
|
319
|
+
byDepartment: Record<string, HiringCounts>;
|
|
320
|
+
bySeniority: Record<string, HiringCounts>;
|
|
321
|
+
byLocation: Record<string, HiringCounts>;
|
|
322
|
+
opened: HiringChangePosting[];
|
|
323
|
+
closed: HiringChangePosting[];
|
|
324
|
+
truncated: boolean;
|
|
325
|
+
}
|
|
241
326
|
|
|
242
327
|
interface HydrafetchOptions {
|
|
243
328
|
apiKey?: string;
|
|
@@ -252,12 +337,17 @@ declare class Hydrafetch {
|
|
|
252
337
|
private readonly timeoutMs;
|
|
253
338
|
private readonly maxRetries;
|
|
254
339
|
private readonly fetchImpl;
|
|
340
|
+
private latestRequestId;
|
|
341
|
+
get lastRequestId(): string | undefined;
|
|
255
342
|
constructor(options?: HydrafetchOptions | string);
|
|
256
343
|
private request;
|
|
257
344
|
scrape<const F extends readonly Format[] = ['markdown']>(url: string, options?: ScrapeOptions<F>): Promise<ScrapeResult<F[number]>>;
|
|
258
345
|
markdown(url: string, options?: Omit<ScrapeOptions, 'formats'>): Promise<string>;
|
|
346
|
+
rateResult(input: RateResultInput): Promise<RateResultResponse>;
|
|
259
347
|
map(url: string, options?: MapOptions): Promise<MapResult>;
|
|
260
348
|
search(query: string, options?: SearchOptions): Promise<SearchResult>;
|
|
349
|
+
searchJobs(query: string, options?: SearchJobsOptions): Promise<OpenJob[]>;
|
|
350
|
+
hiringChanges(domains: string | string[], since: string | Date, options?: HiringChangesOptions): Promise<CompanyHiringChanges[]>;
|
|
261
351
|
extract<T = unknown>(urls: string | string[], options?: ExtractOptions): Promise<ExtractResult<T>>;
|
|
262
352
|
brand(domain: string): Promise<BrandResult>;
|
|
263
353
|
logo(domain: string, options?: BrandOptions): Promise<LogoResult>;
|
|
@@ -297,4 +387,4 @@ declare class HydrafetchTimeoutError extends HydrafetchError {
|
|
|
297
387
|
constructor(message: string);
|
|
298
388
|
}
|
|
299
389
|
|
|
300
|
-
export { type BatchOptions, type BrandOptions, type BrandResult, type CrawlOptions, type ExtractItem, type ExtractOptions, type ExtractResult, type ExtractSchema, type Format, Hydrafetch, HydrafetchError, type HydrafetchOptions, HydrafetchTimeoutError, type ImagesResult, type JobPage, type JobResult, type JobStatus, type Location, type LogoResult, type MapOptions, type MapResult, type PageImage, type PageMetadata, type ScrapeBase, type ScrapeContent, type ScrapeOptions, type ScrapeResult, type ScreenshotOptions, type ScreenshotResult, type SearchOptions, type SearchResult, type SearchResultItem, type StyleguideOptions, type StyleguideResult, type Usage, type WaitOptions, type ZodLike };
|
|
390
|
+
export { type BatchOptions, type BrandOptions, type BrandResult, type CompanyHiringChanges, type CrawlOptions, type ExtractItem, type ExtractOptions, type ExtractResult, type ExtractSchema, type Format, type HiringChangePosting, type HiringChangesOptions, type HiringCounts, Hydrafetch, HydrafetchError, type HydrafetchOptions, HydrafetchTimeoutError, type ImagesResult, type JobPage, type JobPay, type JobResult, type JobStatus, type Location, type LogoResult, type MapOptions, type MapResult, type OpenJob, type PageImage, type PageMetadata, type RateResultInput, type RateResultResponse, type ResultFeedbackReason, type ResultRating, type ScrapeBase, type ScrapeContent, type ScrapeOptions, type ScrapeResult, type ScreenshotOptions, type ScreenshotResult, type SearchJobsOptions, type SearchOptions, type SearchResult, type SearchResultItem, type StyleguideOptions, type StyleguideResult, type Usage, type WaitOptions, type ZodLike };
|
package/dist/index.d.ts
CHANGED
|
@@ -238,6 +238,91 @@ interface WaitOptions {
|
|
|
238
238
|
pollIntervalMs?: number;
|
|
239
239
|
onProgress?: (job: JobResult) => void;
|
|
240
240
|
}
|
|
241
|
+
type ResultRating = 'good' | 'bad';
|
|
242
|
+
type ResultFeedbackReason = 'missing_content' | 'wrong_content' | 'blocked' | 'slow' | 'formatting' | 'other';
|
|
243
|
+
interface RateResultInput {
|
|
244
|
+
requestId?: string;
|
|
245
|
+
url?: string;
|
|
246
|
+
rating: ResultRating;
|
|
247
|
+
reasons?: ResultFeedbackReason[];
|
|
248
|
+
note?: string;
|
|
249
|
+
}
|
|
250
|
+
interface RateResultResponse {
|
|
251
|
+
id: string;
|
|
252
|
+
requestId: string;
|
|
253
|
+
rating: ResultRating;
|
|
254
|
+
}
|
|
255
|
+
interface SearchJobsOptions {
|
|
256
|
+
/** A city, region or country to match, like "Berlin". */
|
|
257
|
+
location?: string;
|
|
258
|
+
/** Only jobs marked remote. */
|
|
259
|
+
remoteOnly?: boolean;
|
|
260
|
+
/** Only jobs posted in the last N days (1 to 365). */
|
|
261
|
+
postedWithinDays?: number;
|
|
262
|
+
/** Max jobs to return, 1 to 100 (default 10). Each 10 jobs returned cost 1 credit. */
|
|
263
|
+
limit?: number;
|
|
264
|
+
/** Include each job's description text when we hold it. */
|
|
265
|
+
includeDescriptions?: boolean;
|
|
266
|
+
}
|
|
267
|
+
interface JobPay {
|
|
268
|
+
min: number | null;
|
|
269
|
+
max: number | null;
|
|
270
|
+
currency: string | null;
|
|
271
|
+
interval: string | null;
|
|
272
|
+
}
|
|
273
|
+
interface OpenJob {
|
|
274
|
+
title: string;
|
|
275
|
+
company: string | null;
|
|
276
|
+
/** The company's website. */
|
|
277
|
+
domain: string;
|
|
278
|
+
/** The hiring platform the job is posted on. */
|
|
279
|
+
board: string;
|
|
280
|
+
department: string | null;
|
|
281
|
+
location: string | null;
|
|
282
|
+
remote: boolean | null;
|
|
283
|
+
employmentType: string | null;
|
|
284
|
+
postedAt: string | null;
|
|
285
|
+
/** When the job was first seen open. */
|
|
286
|
+
firstSeenAt: string;
|
|
287
|
+
url: string | null;
|
|
288
|
+
applyUrl: string | null;
|
|
289
|
+
pay: JobPay | null;
|
|
290
|
+
description?: string | null;
|
|
291
|
+
}
|
|
292
|
+
interface HiringChangesOptions {
|
|
293
|
+
/** Include each opened and closed job's description text when we hold it. */
|
|
294
|
+
includeDescriptions?: boolean;
|
|
295
|
+
}
|
|
296
|
+
interface HiringCounts {
|
|
297
|
+
open: number;
|
|
298
|
+
opened: number;
|
|
299
|
+
closed: number;
|
|
300
|
+
}
|
|
301
|
+
interface HiringChangePosting {
|
|
302
|
+
title: string;
|
|
303
|
+
department: string | null;
|
|
304
|
+
location: string | null;
|
|
305
|
+
seniority: string;
|
|
306
|
+
board: string;
|
|
307
|
+
url: string | null;
|
|
308
|
+
postedAt: string | null;
|
|
309
|
+
firstSeenAt: string;
|
|
310
|
+
closedAt: string | null;
|
|
311
|
+
description?: string | null;
|
|
312
|
+
}
|
|
313
|
+
interface CompanyHiringChanges {
|
|
314
|
+
domain: string;
|
|
315
|
+
company: string | null;
|
|
316
|
+
lastReadAt: string | null;
|
|
317
|
+
since: string;
|
|
318
|
+
totals: HiringCounts;
|
|
319
|
+
byDepartment: Record<string, HiringCounts>;
|
|
320
|
+
bySeniority: Record<string, HiringCounts>;
|
|
321
|
+
byLocation: Record<string, HiringCounts>;
|
|
322
|
+
opened: HiringChangePosting[];
|
|
323
|
+
closed: HiringChangePosting[];
|
|
324
|
+
truncated: boolean;
|
|
325
|
+
}
|
|
241
326
|
|
|
242
327
|
interface HydrafetchOptions {
|
|
243
328
|
apiKey?: string;
|
|
@@ -252,12 +337,17 @@ declare class Hydrafetch {
|
|
|
252
337
|
private readonly timeoutMs;
|
|
253
338
|
private readonly maxRetries;
|
|
254
339
|
private readonly fetchImpl;
|
|
340
|
+
private latestRequestId;
|
|
341
|
+
get lastRequestId(): string | undefined;
|
|
255
342
|
constructor(options?: HydrafetchOptions | string);
|
|
256
343
|
private request;
|
|
257
344
|
scrape<const F extends readonly Format[] = ['markdown']>(url: string, options?: ScrapeOptions<F>): Promise<ScrapeResult<F[number]>>;
|
|
258
345
|
markdown(url: string, options?: Omit<ScrapeOptions, 'formats'>): Promise<string>;
|
|
346
|
+
rateResult(input: RateResultInput): Promise<RateResultResponse>;
|
|
259
347
|
map(url: string, options?: MapOptions): Promise<MapResult>;
|
|
260
348
|
search(query: string, options?: SearchOptions): Promise<SearchResult>;
|
|
349
|
+
searchJobs(query: string, options?: SearchJobsOptions): Promise<OpenJob[]>;
|
|
350
|
+
hiringChanges(domains: string | string[], since: string | Date, options?: HiringChangesOptions): Promise<CompanyHiringChanges[]>;
|
|
261
351
|
extract<T = unknown>(urls: string | string[], options?: ExtractOptions): Promise<ExtractResult<T>>;
|
|
262
352
|
brand(domain: string): Promise<BrandResult>;
|
|
263
353
|
logo(domain: string, options?: BrandOptions): Promise<LogoResult>;
|
|
@@ -297,4 +387,4 @@ declare class HydrafetchTimeoutError extends HydrafetchError {
|
|
|
297
387
|
constructor(message: string);
|
|
298
388
|
}
|
|
299
389
|
|
|
300
|
-
export { type BatchOptions, type BrandOptions, type BrandResult, type CrawlOptions, type ExtractItem, type ExtractOptions, type ExtractResult, type ExtractSchema, type Format, Hydrafetch, HydrafetchError, type HydrafetchOptions, HydrafetchTimeoutError, type ImagesResult, type JobPage, type JobResult, type JobStatus, type Location, type LogoResult, type MapOptions, type MapResult, type PageImage, type PageMetadata, type ScrapeBase, type ScrapeContent, type ScrapeOptions, type ScrapeResult, type ScreenshotOptions, type ScreenshotResult, type SearchOptions, type SearchResult, type SearchResultItem, type StyleguideOptions, type StyleguideResult, type Usage, type WaitOptions, type ZodLike };
|
|
390
|
+
export { type BatchOptions, type BrandOptions, type BrandResult, type CompanyHiringChanges, type CrawlOptions, type ExtractItem, type ExtractOptions, type ExtractResult, type ExtractSchema, type Format, type HiringChangePosting, type HiringChangesOptions, type HiringCounts, Hydrafetch, HydrafetchError, type HydrafetchOptions, HydrafetchTimeoutError, type ImagesResult, type JobPage, type JobPay, type JobResult, type JobStatus, type Location, type LogoResult, type MapOptions, type MapResult, type OpenJob, type PageImage, type PageMetadata, type RateResultInput, type RateResultResponse, type ResultFeedbackReason, type ResultRating, type ScrapeBase, type ScrapeContent, type ScrapeOptions, type ScrapeResult, type ScreenshotOptions, type ScreenshotResult, type SearchJobsOptions, type SearchOptions, type SearchResult, type SearchResultItem, type StyleguideOptions, type StyleguideResult, type Usage, type WaitOptions, type ZodLike };
|
package/dist/index.js
CHANGED
|
@@ -101,6 +101,10 @@ var Hydrafetch = class {
|
|
|
101
101
|
timeoutMs;
|
|
102
102
|
maxRetries;
|
|
103
103
|
fetchImpl;
|
|
104
|
+
latestRequestId;
|
|
105
|
+
get lastRequestId() {
|
|
106
|
+
return this.latestRequestId;
|
|
107
|
+
}
|
|
104
108
|
constructor(options = {}) {
|
|
105
109
|
const opts = typeof options === "string" ? { apiKey: options } : options;
|
|
106
110
|
const env = globalThis.process?.env;
|
|
@@ -108,7 +112,7 @@ var Hydrafetch = class {
|
|
|
108
112
|
if (!apiKey) {
|
|
109
113
|
throw new HydrafetchError({
|
|
110
114
|
code: "MISSING_API_KEY",
|
|
111
|
-
message: "No API key. Pass one to the constructor or set HYDRAFETCH_API_KEY.
|
|
115
|
+
message: "No API key. Pass one to the constructor or set HYDRAFETCH_API_KEY. Copy your key from https://app.hydrafetch.com.",
|
|
112
116
|
status: 401
|
|
113
117
|
});
|
|
114
118
|
}
|
|
@@ -146,6 +150,7 @@ var Hydrafetch = class {
|
|
|
146
150
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
147
151
|
signal: controller.signal
|
|
148
152
|
});
|
|
153
|
+
this.latestRequestId = res.headers.get("x-request-id") ?? this.latestRequestId;
|
|
149
154
|
const text = await res.text();
|
|
150
155
|
let parsed;
|
|
151
156
|
try {
|
|
@@ -193,12 +198,25 @@ var Hydrafetch = class {
|
|
|
193
198
|
const page = await this.scrape(url, { ...options, formats: ["markdown"] });
|
|
194
199
|
return page.markdown;
|
|
195
200
|
}
|
|
201
|
+
rateResult(input) {
|
|
202
|
+
return this.request("POST", "/v1/web/feedback", input);
|
|
203
|
+
}
|
|
196
204
|
map(url, options = {}) {
|
|
197
205
|
return this.request("POST", "/v1/web/map", { url, ...options });
|
|
198
206
|
}
|
|
199
207
|
search(query, options = {}) {
|
|
200
208
|
return this.request("POST", "/v1/web/search", { query, ...options });
|
|
201
209
|
}
|
|
210
|
+
searchJobs(query, options = {}) {
|
|
211
|
+
return this.request("POST", "/v1/web/index/jobs/search", { query, ...options });
|
|
212
|
+
}
|
|
213
|
+
hiringChanges(domains, since, options = {}) {
|
|
214
|
+
return this.request("POST", "/v1/web/index/jobs/changes", {
|
|
215
|
+
domains: Array.isArray(domains) ? domains : [domains],
|
|
216
|
+
since: since instanceof Date ? since.toISOString() : since,
|
|
217
|
+
...options
|
|
218
|
+
});
|
|
219
|
+
}
|
|
202
220
|
async extract(urls, options = {}) {
|
|
203
221
|
const { schema, ...rest } = options;
|
|
204
222
|
return this.request("POST", "/v1/web/extract", {
|
package/package.json
CHANGED