@hyperbrowser/sdk 0.9.0 → 0.11.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 CHANGED
@@ -1,6 +1,6 @@
1
- # Hyperbrowser SDK
1
+ # Hyperbrowser Node SDK
2
2
 
3
- A TypeScript/JavaScript SDK for interacting with the Hyperbrowser API.
3
+ Checkout the full documentation [here](https://docs.hyperbrowser.ai/)
4
4
 
5
5
  ## Installation
6
6
 
package/dist/client.d.ts CHANGED
@@ -2,6 +2,8 @@ import { HyperbrowserConfig } from "./types/config";
2
2
  import { SessionsService } from "./services/sessions";
3
3
  import { ScrapeService } from "./services/scrape";
4
4
  import { CrawlService } from "./services/crawl";
5
+ import { ProfilesService } from "./services/profiles";
6
+ import { ExtensionService } from "./services/extensions";
5
7
  export declare class HyperbrowserError extends Error {
6
8
  statusCode?: number | undefined;
7
9
  constructor(message: string, statusCode?: number | undefined);
@@ -10,5 +12,7 @@ export declare class HyperbrowserClient {
10
12
  readonly sessions: SessionsService;
11
13
  readonly scrape: ScrapeService;
12
14
  readonly crawl: CrawlService;
15
+ readonly profiles: ProfilesService;
16
+ readonly extensions: ExtensionService;
13
17
  constructor(config: HyperbrowserConfig);
14
18
  }
package/dist/client.js CHANGED
@@ -4,6 +4,8 @@ exports.HyperbrowserClient = exports.HyperbrowserError = void 0;
4
4
  const sessions_1 = require("./services/sessions");
5
5
  const scrape_1 = require("./services/scrape");
6
6
  const crawl_1 = require("./services/crawl");
7
+ const profiles_1 = require("./services/profiles");
8
+ const extensions_1 = require("./services/extensions");
7
9
  class HyperbrowserError extends Error {
8
10
  constructor(message, statusCode) {
9
11
  super(`[Hyperbrowser]: ${message}`);
@@ -16,12 +18,15 @@ class HyperbrowserClient {
16
18
  constructor(config) {
17
19
  const apiKey = config.apiKey;
18
20
  const baseUrl = config.baseUrl || "https://app.hyperbrowser.ai";
21
+ const timeout = config.timeout || 30000;
19
22
  if (!apiKey) {
20
23
  throw new HyperbrowserError("API key is required");
21
24
  }
22
- this.sessions = new sessions_1.SessionsService(apiKey, baseUrl);
23
- this.scrape = new scrape_1.ScrapeService(apiKey, baseUrl);
24
- this.crawl = new crawl_1.CrawlService(apiKey, baseUrl);
25
+ this.sessions = new sessions_1.SessionsService(apiKey, baseUrl, timeout);
26
+ this.scrape = new scrape_1.ScrapeService(apiKey, baseUrl, timeout);
27
+ this.crawl = new crawl_1.CrawlService(apiKey, baseUrl, timeout);
28
+ this.profiles = new profiles_1.ProfilesService(apiKey, baseUrl, timeout);
29
+ this.extensions = new extensions_1.ExtensionService(apiKey, baseUrl, timeout);
25
30
  }
26
31
  }
27
32
  exports.HyperbrowserClient = HyperbrowserClient;
@@ -2,6 +2,7 @@ import { RequestInit } from "node-fetch";
2
2
  export declare class BaseService {
3
3
  protected readonly apiKey: string;
4
4
  protected readonly baseUrl: string;
5
- constructor(apiKey: string, baseUrl: string);
5
+ protected readonly timeout: number;
6
+ constructor(apiKey: string, baseUrl: string, timeout?: number);
6
7
  protected request<T>(path: string, init?: RequestInit, params?: Record<string, string | number | undefined>): Promise<T>;
7
8
  }
@@ -7,9 +7,10 @@ exports.BaseService = void 0;
7
7
  const node_fetch_1 = __importDefault(require("node-fetch"));
8
8
  const client_1 = require("../client");
9
9
  class BaseService {
10
- constructor(apiKey, baseUrl) {
10
+ constructor(apiKey, baseUrl, timeout = 30000) {
11
11
  this.apiKey = apiKey;
12
12
  this.baseUrl = baseUrl;
13
+ this.timeout = timeout;
13
14
  }
14
15
  async request(path, init, params) {
15
16
  try {
@@ -21,11 +22,16 @@ class BaseService {
21
22
  }
22
23
  });
23
24
  }
25
+ const headerKeys = Object.keys(init?.headers || {});
26
+ const contentTypeKey = headerKeys.find((key) => key.toLowerCase() === "content-type");
24
27
  const response = await (0, node_fetch_1.default)(url.toString(), {
25
28
  ...init,
29
+ timeout: this.timeout,
26
30
  headers: {
27
31
  "x-api-key": this.apiKey,
28
- "Content-Type": "application/json",
32
+ ...(contentTypeKey && init?.headers
33
+ ? { "content-type": init.headers[contentTypeKey] }
34
+ : { "content-type": "application/json" }),
29
35
  ...init?.headers,
30
36
  },
31
37
  });
@@ -0,0 +1,14 @@
1
+ import { CreateExtensionResponse, ListExtensionsResponse } from "../types/extension";
2
+ import { BaseService } from "./base";
3
+ export declare class ExtensionService extends BaseService {
4
+ /**
5
+ * Upload an extension to hyperbrowser
6
+ * @param {string} filePath Path to a zipped extension. Extension must be Manifest V3 compliant.
7
+ * @param {string} [fileName] Name to give to the extension.
8
+ */
9
+ create(filePath: string, fileName?: string | undefined): Promise<CreateExtensionResponse>;
10
+ /**
11
+ * List all uploaded extensions for the account
12
+ */
13
+ list(): Promise<ListExtensionsResponse>;
14
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ExtensionService = void 0;
7
+ const client_1 = require("../client");
8
+ const base_1 = require("./base");
9
+ const form_data_1 = __importDefault(require("form-data"));
10
+ const promises_1 = __importDefault(require("node:fs/promises"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ async function checkFileExists(filePath) {
13
+ try {
14
+ await promises_1.default.access(filePath, promises_1.default.constants.R_OK);
15
+ const extension = node_path_1.default.extname(filePath);
16
+ if (extension !== ".zip") {
17
+ throw new client_1.HyperbrowserError("Extension file provided is not zipped", undefined);
18
+ }
19
+ }
20
+ catch (err) {
21
+ if (err instanceof client_1.HyperbrowserError) {
22
+ throw err;
23
+ }
24
+ throw new client_1.HyperbrowserError("Could not find extension file", undefined);
25
+ }
26
+ }
27
+ class ExtensionService extends base_1.BaseService {
28
+ /**
29
+ * Upload an extension to hyperbrowser
30
+ * @param {string} filePath Path to a zipped extension. Extension must be Manifest V3 compliant.
31
+ * @param {string} [fileName] Name to give to the extension.
32
+ */
33
+ async create(filePath, fileName) {
34
+ try {
35
+ await checkFileExists(filePath);
36
+ const form = new form_data_1.default();
37
+ form.append("file", await promises_1.default.readFile(filePath), {
38
+ filename: node_path_1.default.basename(filePath),
39
+ contentType: "application/zip",
40
+ });
41
+ if (fileName) {
42
+ form.append("name", fileName);
43
+ }
44
+ const response = await this.request("/extensions/add", {
45
+ method: "POST",
46
+ body: form,
47
+ headers: form.getHeaders(),
48
+ });
49
+ return response;
50
+ }
51
+ catch (error) {
52
+ if (error instanceof client_1.HyperbrowserError) {
53
+ throw error;
54
+ }
55
+ throw new client_1.HyperbrowserError("Failed to upload extension", undefined);
56
+ }
57
+ }
58
+ /**
59
+ * List all uploaded extensions for the account
60
+ */
61
+ async list() {
62
+ try {
63
+ return await this.request("/extensions/list", { method: "GET" });
64
+ }
65
+ catch (err) {
66
+ if (err instanceof client_1.HyperbrowserError) {
67
+ throw err;
68
+ }
69
+ else {
70
+ throw new client_1.HyperbrowserError("Could not list extensions", undefined);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ exports.ExtensionService = ExtensionService;
@@ -0,0 +1,19 @@
1
+ import { BaseService } from "./base";
2
+ import { ProfileResponse, CreateProfileResponse } from "../types/profile";
3
+ import { BasicResponse } from "../types";
4
+ export declare class ProfilesService extends BaseService {
5
+ /**
6
+ * Create a new profile
7
+ */
8
+ create(): Promise<CreateProfileResponse>;
9
+ /**
10
+ * Get details of an existing profile
11
+ * @param id The ID of the profile to get
12
+ */
13
+ get(id: string): Promise<ProfileResponse>;
14
+ /**
15
+ * Delete an existing profile
16
+ * @param id The ID of the profile to delete
17
+ */
18
+ delete(id: string): Promise<BasicResponse>;
19
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProfilesService = void 0;
4
+ const base_1 = require("./base");
5
+ const client_1 = require("../client");
6
+ class ProfilesService extends base_1.BaseService {
7
+ /**
8
+ * Create a new profile
9
+ */
10
+ async create() {
11
+ try {
12
+ return await this.request("/profile", {
13
+ method: "POST",
14
+ });
15
+ }
16
+ catch (error) {
17
+ if (error instanceof client_1.HyperbrowserError) {
18
+ throw error;
19
+ }
20
+ throw new client_1.HyperbrowserError("Failed to create profile", undefined);
21
+ }
22
+ }
23
+ /**
24
+ * Get details of an existing profile
25
+ * @param id The ID of the profile to get
26
+ */
27
+ async get(id) {
28
+ try {
29
+ return await this.request(`/profile/${id}`);
30
+ }
31
+ catch (error) {
32
+ if (error instanceof client_1.HyperbrowserError) {
33
+ throw error;
34
+ }
35
+ throw new client_1.HyperbrowserError(`Failed to get profile ${id}`, undefined);
36
+ }
37
+ }
38
+ /**
39
+ * Delete an existing profile
40
+ * @param id The ID of the profile to delete
41
+ */
42
+ async delete(id) {
43
+ try {
44
+ return await this.request(`/profile/${id}`, {
45
+ method: "DELETE",
46
+ });
47
+ }
48
+ catch (error) {
49
+ if (error instanceof client_1.HyperbrowserError) {
50
+ throw error;
51
+ }
52
+ throw new client_1.HyperbrowserError(`Failed to delete profile ${id}`, undefined);
53
+ }
54
+ }
55
+ }
56
+ exports.ProfilesService = ProfilesService;
@@ -1,4 +1,5 @@
1
1
  export interface HyperbrowserConfig {
2
2
  apiKey: string;
3
3
  baseUrl?: string;
4
+ timeout?: number;
4
5
  }
@@ -1,4 +1,4 @@
1
- export type ScrapeFormat = "markdown" | "html" | "links";
1
+ export type ScrapeFormat = "markdown" | "html" | "links" | "screenshot";
2
2
  export type ScrapeJobStatus = "pending" | "running" | "completed" | "failed";
3
3
  export type CrawlJobStatus = "pending" | "running" | "completed" | "failed";
4
4
  export type CrawlPageStatus = "completed" | "failed";
@@ -0,0 +1,9 @@
1
+ interface ExtensionResponse {
2
+ name: string;
3
+ id: string;
4
+ createdAt: string;
5
+ updatedAt: string;
6
+ }
7
+ export type CreateExtensionResponse = ExtensionResponse;
8
+ export type ListExtensionsResponse = Array<ExtensionResponse>;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -2,4 +2,5 @@ export { HyperbrowserConfig } from "./config";
2
2
  export { StartCrawlJobParams, StartCrawlJobResponse, CrawledPage, CrawlJobResponse, GetCrawlJobParams, } from "./crawl";
3
3
  export { StartScrapeJobParams, StartScrapeJobResponse, ScrapeJobData, ScrapeJobResponse, } from "./scrape";
4
4
  export { BasicResponse, SessionStatus, Session, SessionDetail, SessionListParams, SessionListResponse, ScreenConfig, CreateSessionParams, } from "./session";
5
+ export { ProfileResponse, CreateProfileResponse } from "./profile";
5
6
  export { ScrapeJobStatus, CrawlJobStatus, Country, ISO639_1, OperatingSystem, Platform, } from "./constants";
@@ -0,0 +1,9 @@
1
+ export interface CreateProfileResponse {
2
+ id: string;
3
+ }
4
+ export interface ProfileResponse {
5
+ id: string;
6
+ teamId: string;
7
+ createdAt: string;
8
+ updatedAt: string;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -31,6 +31,10 @@ export interface ScreenConfig {
31
31
  width: number;
32
32
  height: number;
33
33
  }
34
+ export interface CreateSessionProfile {
35
+ id?: string;
36
+ persistChanges?: boolean;
37
+ }
34
38
  export interface CreateSessionParams {
35
39
  useStealth?: boolean;
36
40
  useProxy?: boolean;
@@ -48,6 +52,8 @@ export interface CreateSessionParams {
48
52
  trackers?: boolean;
49
53
  annoyances?: boolean;
50
54
  enableWebRecording?: boolean;
55
+ profile?: CreateSessionProfile;
56
+ extensionIds: Array<string>;
51
57
  }
52
58
  export interface SessionRecording {
53
59
  type: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperbrowser/sdk",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Node SDK for Hyperbrowser API",
5
5
  "author": "",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,8 @@
25
25
  "automation"
26
26
  ],
27
27
  "dependencies": {
28
- "node-fetch": "^2.6.7"
28
+ "form-data": "^4.0.1",
29
+ "node-fetch": "2.7.0"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@types/node": "^22.9.1",