sprntrl 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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/client.d.ts +33 -0
  4. package/dist/client.js +57 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/core/error.d.ts +46 -0
  7. package/dist/core/error.js +72 -0
  8. package/dist/core/error.js.map +1 -0
  9. package/dist/core/request.d.ts +24 -0
  10. package/dist/core/request.js +107 -0
  11. package/dist/core/request.js.map +1 -0
  12. package/dist/core/resource.d.ts +5 -0
  13. package/dist/core/resource.js +7 -0
  14. package/dist/core/resource.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.js +4 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/lib/browser.d.ts +7 -0
  19. package/dist/lib/browser.js +56 -0
  20. package/dist/lib/browser.js.map +1 -0
  21. package/dist/resources/api-keys.d.ts +11 -0
  22. package/dist/resources/api-keys.js +28 -0
  23. package/dist/resources/api-keys.js.map +1 -0
  24. package/dist/resources/ip-whitelist.d.ts +10 -0
  25. package/dist/resources/ip-whitelist.js +28 -0
  26. package/dist/resources/ip-whitelist.js.map +1 -0
  27. package/dist/resources/profiles.d.ts +19 -0
  28. package/dist/resources/profiles.js +51 -0
  29. package/dist/resources/profiles.js.map +1 -0
  30. package/dist/resources/session-files.d.ts +10 -0
  31. package/dist/resources/session-files.js +36 -0
  32. package/dist/resources/session-files.js.map +1 -0
  33. package/dist/resources/sessions.d.ts +72 -0
  34. package/dist/resources/sessions.js +195 -0
  35. package/dist/resources/sessions.js.map +1 -0
  36. package/dist/resources/templates.d.ts +5 -0
  37. package/dist/resources/templates.js +11 -0
  38. package/dist/resources/templates.js.map +1 -0
  39. package/dist/resources/usage.d.ts +6 -0
  40. package/dist/resources/usage.js +17 -0
  41. package/dist/resources/usage.js.map +1 -0
  42. package/dist/resources/user.d.ts +26 -0
  43. package/dist/resources/user.js +38 -0
  44. package/dist/resources/user.js.map +1 -0
  45. package/dist/types.d.ts +148 -0
  46. package/dist/types.js +2 -0
  47. package/dist/types.js.map +1 -0
  48. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Supernatural
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 ADDED
@@ -0,0 +1,128 @@
1
+ # Supernatural Node SDK
2
+
3
+ Official Node.js / TypeScript client for the [Supernatural](https://supernatural.sh) stealth browser-as-a-service API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install sprntrl
9
+ # Optional — pick whichever browser automation library you use:
10
+ npm install playwright
11
+ npm install puppeteer
12
+ ```
13
+
14
+ ## Quick start
15
+
16
+ ```ts
17
+ import { Sprntrl } from "sprntrl";
18
+ import type { Browser } from "playwright";
19
+
20
+ const client = new Sprntrl(); // reads SPRNTRL_API_KEY from env
21
+
22
+ const session = await client.sessions.create({ os: "macos", location: "us-east" });
23
+
24
+ // browserSession waits for the session, connects Playwright, and hands you
25
+ // a disposable handle. autoWhitelist registers your IP (CDP is IP-gated).
26
+ const handle = await client.sessions.browserSession(session.id, { autoWhitelist: true });
27
+ try {
28
+ const browser = handle.browser as Browser;
29
+ const page = await browser.contexts()[0].newPage();
30
+ await page.goto("https://bot.sannysoft.com");
31
+ await page.screenshot({ path: "out.png" });
32
+ } finally {
33
+ await handle.close();
34
+ await client.sessions.stop(session.id);
35
+ }
36
+ ```
37
+
38
+ ### With `await using` (Node 24+ / TS 5.2+)
39
+
40
+ ```ts
41
+ {
42
+ await using handle = await client.sessions.browserSession(session.id, { autoWhitelist: true });
43
+ const page = await handle.browser.contexts()[0].newPage();
44
+ await page.goto("https://example.com");
45
+ } // browser auto-closes here
46
+ ```
47
+
48
+ ### Puppeteer
49
+
50
+ ```ts
51
+ const handle = await client.sessions.browserSession(session.id, {
52
+ framework: "puppeteer",
53
+ autoWhitelist: true,
54
+ });
55
+ ```
56
+
57
+ ### Lower-level `connect()` and `cdpUrl()`
58
+
59
+ If you want to manage the browser lifecycle yourself:
60
+
61
+ ```ts
62
+ const browser = await client.sessions.connect(session.id, { autoWhitelist: true });
63
+ // ...
64
+ await browser.close();
65
+ ```
66
+
67
+ Or get the raw CDP WebSocket URL for any CDP client (chrome-remote-interface, raw ws, etc.):
68
+
69
+ ```ts
70
+ const url = client.sessions.cdpUrl(session.id);
71
+ // wss://api.supernatural.sh/api/v1/sessions/<id>/cdp
72
+ ```
73
+
74
+ ## Configuration
75
+
76
+ | Env var | Default |
77
+ |---------------------|----------------------------|
78
+ | `SPRNTRL_API_KEY` | — |
79
+ | `SPRNTRL_BASE_URL` | `https://api.supernatural.sh` |
80
+
81
+ Or per client:
82
+
83
+ ```ts
84
+ const client = new Sprntrl({
85
+ apiKey: "sk_...",
86
+ baseURL: "https://api.supernatural.sh",
87
+ timeout: 30_000,
88
+ maxRetries: 2,
89
+ });
90
+ ```
91
+
92
+ ## Resources
93
+
94
+ - `client.sessions` — `create`, `list`, `listActive`, `listHistory`, `listResumable`, `listLocations`, `get`, `stop`, `resume`, `deletePersistent`, `waitUntilReady`, `connect`, `browserSession`, `cdpUrl`
95
+ - `client.sessions.files` — `list`, `download`, `upload`
96
+ - `client.profiles` — `create`, `list`, `get`, `update`, `duplicate`, `delete`
97
+ - `client.templates.list()`
98
+ - `client.ipWhitelist` — `list`, `add`, `remove`
99
+ - `client.usage` — `current`, `history`
100
+ - `client.user` — `me`, `update`, `updateSettings`, `changePassword`
101
+ - `client.apiKeys` — `list`, `create` (full key returned ONCE), `revoke`
102
+
103
+ ## Error handling
104
+
105
+ ```ts
106
+ import { Sprntrl, APIError, RateLimitError, AuthenticationError } from "sprntrl";
107
+
108
+ try {
109
+ await client.sessions.create({ os: "macos", location: "us-east" });
110
+ } catch (err) {
111
+ if (err instanceof RateLimitError) console.log("rate limited", err.status);
112
+ else if (err instanceof AuthenticationError) console.log("bad API key");
113
+ else if (err instanceof APIError) console.log("api error", err.status, err.body);
114
+ else throw err;
115
+ }
116
+ ```
117
+
118
+ Transient errors (5xx, 429, 408, connection errors) are retried automatically up to `maxRetries` with exponential backoff.
119
+
120
+ ## Gotchas
121
+
122
+ - **CDP access is IP-whitelist gated.** The WebSocket at `/api/v1/sessions/:id/cdp` does not accept bearer auth — instead your public IP (as Cloudflare sees it) must be in your account's whitelist. Use `client.ipWhitelist.add("current")` or pass `{ autoWhitelist: true }` to `sessions.connect`.
123
+ - **Sessions start async.** `sessions.create` returns immediately with `status: "creating"`. Call `sessions.waitUntilReady(id)` before connecting, or just use `sessions.connect()` which waits for you.
124
+ - **API key is shown only once.** `apiKeys.create()` returns the full `key` field exactly once — store it immediately.
125
+
126
+ ## License
127
+
128
+ MIT
@@ -0,0 +1,33 @@
1
+ import { type RequestOptions } from "./core/request.js";
2
+ import { Sessions } from "./resources/sessions.js";
3
+ import { Profiles } from "./resources/profiles.js";
4
+ import { Templates } from "./resources/templates.js";
5
+ import { IPWhitelist } from "./resources/ip-whitelist.js";
6
+ import { Usage } from "./resources/usage.js";
7
+ import { User } from "./resources/user.js";
8
+ import { APIKeys } from "./resources/api-keys.js";
9
+ export interface ClientOptions {
10
+ apiKey?: string;
11
+ baseURL?: string;
12
+ timeout?: number;
13
+ maxRetries?: number;
14
+ defaultHeaders?: Record<string, string>;
15
+ fetch?: typeof fetch;
16
+ }
17
+ export declare class Sprntrl {
18
+ readonly apiKey: string;
19
+ readonly baseURL: string;
20
+ readonly timeout: number;
21
+ readonly maxRetries: number;
22
+ private readonly _config;
23
+ readonly sessions: Sessions;
24
+ readonly profiles: Profiles;
25
+ readonly templates: Templates;
26
+ readonly ipWhitelist: IPWhitelist;
27
+ readonly usage: Usage;
28
+ readonly user: User;
29
+ readonly apiKeys: APIKeys;
30
+ constructor(opts?: ClientOptions);
31
+ /** Low-level request escape hatch. Resources use this under the hood. */
32
+ request<T = unknown>(opts: RequestOptions): Promise<T>;
33
+ }
package/dist/client.js ADDED
@@ -0,0 +1,57 @@
1
+ import { SprntrlError } from "./core/error.js";
2
+ import { request as coreRequest } from "./core/request.js";
3
+ import { Sessions } from "./resources/sessions.js";
4
+ import { Profiles } from "./resources/profiles.js";
5
+ import { Templates } from "./resources/templates.js";
6
+ import { IPWhitelist } from "./resources/ip-whitelist.js";
7
+ import { Usage } from "./resources/usage.js";
8
+ import { User } from "./resources/user.js";
9
+ import { APIKeys } from "./resources/api-keys.js";
10
+ const DEFAULT_BASE_URL = "https://api.supernatural.sh";
11
+ const DEFAULT_TIMEOUT = 60_000;
12
+ const DEFAULT_MAX_RETRIES = 2;
13
+ export class Sprntrl {
14
+ apiKey;
15
+ baseURL;
16
+ timeout;
17
+ maxRetries;
18
+ _config;
19
+ sessions;
20
+ profiles;
21
+ templates;
22
+ ipWhitelist;
23
+ usage;
24
+ user;
25
+ apiKeys;
26
+ constructor(opts = {}) {
27
+ const apiKey = opts.apiKey ?? process.env.SPRNTRL_API_KEY;
28
+ if (!apiKey) {
29
+ throw new SprntrlError("No API key provided. Pass apiKey or set SPRNTRL_API_KEY.");
30
+ }
31
+ const baseURL = (opts.baseURL ?? process.env.SPRNTRL_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
32
+ this.apiKey = apiKey;
33
+ this.baseURL = baseURL;
34
+ this.timeout = opts.timeout ?? DEFAULT_TIMEOUT;
35
+ this.maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES;
36
+ this._config = {
37
+ apiKey,
38
+ baseURL,
39
+ timeout: this.timeout,
40
+ maxRetries: this.maxRetries,
41
+ defaultHeaders: opts.defaultHeaders ?? {},
42
+ fetch: opts.fetch,
43
+ };
44
+ this.sessions = new Sessions(this);
45
+ this.profiles = new Profiles(this);
46
+ this.templates = new Templates(this);
47
+ this.ipWhitelist = new IPWhitelist(this);
48
+ this.usage = new Usage(this);
49
+ this.user = new User(this);
50
+ this.apiKeys = new APIKeys(this);
51
+ }
52
+ /** Low-level request escape hatch. Resources use this under the hood. */
53
+ request(opts) {
54
+ return coreRequest(this._config, opts);
55
+ }
56
+ }
57
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,WAAW,EAA2C,MAAM,mBAAmB,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAWlD,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AACvD,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,MAAM,OAAO,OAAO;IACT,MAAM,CAAS;IACf,OAAO,CAAS;IAChB,OAAO,CAAS;IAChB,UAAU,CAAS;IAEX,OAAO,CAAgB;IAE/B,QAAQ,CAAW;IACnB,QAAQ,CAAW;IACnB,SAAS,CAAY;IACrB,WAAW,CAAc;IACzB,KAAK,CAAQ;IACb,IAAI,CAAO;IACX,OAAO,CAAU;IAE1B,YAAY,OAAsB,EAAE;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,YAAY,CACpB,0DAA0D,CAC3D,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,OAAO,CACxF,MAAM,EACN,EAAE,CACH,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,mBAAmB,CAAC;QAEzD,IAAI,CAAC,OAAO,GAAG;YACb,MAAM;YACN,OAAO;YACP,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;YACzC,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;QAEF,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,yEAAyE;IACzE,OAAO,CAAc,IAAoB;QACvC,OAAO,WAAW,CAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,46 @@
1
+ export declare class SprntrlError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class APIError extends SprntrlError {
5
+ readonly status?: number;
6
+ readonly body?: unknown;
7
+ readonly headers?: Headers;
8
+ constructor(message: string, opts?: {
9
+ status?: number;
10
+ body?: unknown;
11
+ headers?: Headers;
12
+ });
13
+ }
14
+ export declare class BadRequestError extends APIError {
15
+ name: string;
16
+ }
17
+ export declare class AuthenticationError extends APIError {
18
+ name: string;
19
+ }
20
+ export declare class PermissionDeniedError extends APIError {
21
+ name: string;
22
+ }
23
+ export declare class NotFoundError extends APIError {
24
+ name: string;
25
+ }
26
+ export declare class ConflictError extends APIError {
27
+ name: string;
28
+ }
29
+ export declare class UnprocessableEntityError extends APIError {
30
+ name: string;
31
+ }
32
+ export declare class RateLimitError extends APIError {
33
+ name: string;
34
+ }
35
+ export declare class InternalServerError extends APIError {
36
+ name: string;
37
+ }
38
+ export declare class APIConnectionError extends APIError {
39
+ constructor(message?: string, opts?: {
40
+ cause?: unknown;
41
+ });
42
+ }
43
+ export declare class APIConnectionTimeoutError extends APIConnectionError {
44
+ constructor(message?: string);
45
+ }
46
+ export declare function errorForStatus(status: number, message: string, body?: unknown, headers?: Headers): APIError;
@@ -0,0 +1,72 @@
1
+ export class SprntrlError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "SprntrlError";
5
+ }
6
+ }
7
+ export class APIError extends SprntrlError {
8
+ status;
9
+ body;
10
+ headers;
11
+ constructor(message, opts = {}) {
12
+ super(message);
13
+ this.name = "APIError";
14
+ this.status = opts.status;
15
+ this.body = opts.body;
16
+ this.headers = opts.headers;
17
+ }
18
+ }
19
+ export class BadRequestError extends APIError {
20
+ name = "BadRequestError";
21
+ }
22
+ export class AuthenticationError extends APIError {
23
+ name = "AuthenticationError";
24
+ }
25
+ export class PermissionDeniedError extends APIError {
26
+ name = "PermissionDeniedError";
27
+ }
28
+ export class NotFoundError extends APIError {
29
+ name = "NotFoundError";
30
+ }
31
+ export class ConflictError extends APIError {
32
+ name = "ConflictError";
33
+ }
34
+ export class UnprocessableEntityError extends APIError {
35
+ name = "UnprocessableEntityError";
36
+ }
37
+ export class RateLimitError extends APIError {
38
+ name = "RateLimitError";
39
+ }
40
+ export class InternalServerError extends APIError {
41
+ name = "InternalServerError";
42
+ }
43
+ export class APIConnectionError extends APIError {
44
+ constructor(message = "Connection error", opts = {}) {
45
+ super(message);
46
+ this.name = "APIConnectionError";
47
+ if (opts.cause !== undefined)
48
+ this.cause = opts.cause;
49
+ }
50
+ }
51
+ export class APIConnectionTimeoutError extends APIConnectionError {
52
+ constructor(message = "Request timed out") {
53
+ super(message);
54
+ this.name = "APIConnectionTimeoutError";
55
+ }
56
+ }
57
+ export function errorForStatus(status, message, body, headers) {
58
+ const opts = { status, body, headers };
59
+ switch (status) {
60
+ case 400: return new BadRequestError(message, opts);
61
+ case 401: return new AuthenticationError(message, opts);
62
+ case 403: return new PermissionDeniedError(message, opts);
63
+ case 404: return new NotFoundError(message, opts);
64
+ case 409: return new ConflictError(message, opts);
65
+ case 422: return new UnprocessableEntityError(message, opts);
66
+ case 429: return new RateLimitError(message, opts);
67
+ }
68
+ if (status >= 500)
69
+ return new InternalServerError(message, opts);
70
+ return new APIError(message, opts);
71
+ }
72
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/core/error.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface RequestConfig {
2
+ apiKey: string;
3
+ baseURL: string;
4
+ timeout: number;
5
+ maxRetries: number;
6
+ defaultHeaders: Record<string, string>;
7
+ fetch?: typeof fetch;
8
+ }
9
+ export interface RequestOptions {
10
+ method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
11
+ path: string;
12
+ query?: Record<string, string | number | boolean | undefined>;
13
+ body?: unknown;
14
+ headers?: Record<string, string>;
15
+ /** If body is FormData/Blob/ArrayBuffer, don't set content-type/JSON-encode. */
16
+ rawBody?: boolean;
17
+ /** If true, return the raw Response (for binary downloads). */
18
+ stream?: boolean;
19
+ signal?: AbortSignal;
20
+ /** Per-request override. */
21
+ timeout?: number;
22
+ maxRetries?: number;
23
+ }
24
+ export declare function request<T = unknown>(config: RequestConfig, opts: RequestOptions): Promise<T>;
@@ -0,0 +1,107 @@
1
+ import { APIConnectionError, APIConnectionTimeoutError, APIError, errorForStatus, } from "./error.js";
2
+ const USER_AGENT = "sprntrl-node/0.1.0";
3
+ function buildURL(baseURL, path, query) {
4
+ const url = path.startsWith("http") ? new URL(path) : new URL(path, baseURL);
5
+ if (query) {
6
+ for (const [k, v] of Object.entries(query)) {
7
+ if (v !== undefined && v !== null)
8
+ url.searchParams.set(k, String(v));
9
+ }
10
+ }
11
+ return url.toString();
12
+ }
13
+ function shouldRetry(status) {
14
+ if (status === null)
15
+ return true;
16
+ return status === 408 || status === 409 || status === 429 || status >= 500;
17
+ }
18
+ function backoff(attempt) {
19
+ const base = 500 * 2 ** attempt;
20
+ return base + Math.floor(Math.random() * 250);
21
+ }
22
+ async function parseError(response) {
23
+ let body;
24
+ try {
25
+ body = await response.clone().json();
26
+ }
27
+ catch {
28
+ body = await response.clone().text().catch(() => undefined);
29
+ }
30
+ let message;
31
+ if (body && typeof body === "object") {
32
+ const b = body;
33
+ message = b.error || b.message || b.detail;
34
+ }
35
+ return { message: message ?? `HTTP ${response.status}`, body };
36
+ }
37
+ export async function request(config, opts) {
38
+ const url = buildURL(config.baseURL, opts.path, opts.query);
39
+ const headers = {
40
+ Authorization: `ApiKey ${config.apiKey}`,
41
+ Accept: "application/json",
42
+ "User-Agent": USER_AGENT,
43
+ ...config.defaultHeaders,
44
+ ...(opts.headers ?? {}),
45
+ };
46
+ let init = { method: opts.method, headers };
47
+ if (opts.body !== undefined) {
48
+ if (opts.rawBody) {
49
+ init.body = opts.body;
50
+ }
51
+ else {
52
+ headers["Content-Type"] = "application/json";
53
+ init.body = JSON.stringify(opts.body);
54
+ }
55
+ }
56
+ const fetchFn = config.fetch ?? fetch;
57
+ const timeout = opts.timeout ?? config.timeout;
58
+ const maxRetries = opts.maxRetries ?? config.maxRetries;
59
+ let lastErr;
60
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
61
+ const controller = new AbortController();
62
+ const timer = setTimeout(() => controller.abort(new Error("timeout")), timeout);
63
+ const signal = opts.signal
64
+ ? AbortSignal.any([opts.signal, controller.signal])
65
+ : controller.signal;
66
+ try {
67
+ const response = await fetchFn(url, { ...init, signal });
68
+ clearTimeout(timer);
69
+ if (response.ok) {
70
+ if (opts.stream)
71
+ return response;
72
+ if (response.status === 204)
73
+ return undefined;
74
+ const ctype = response.headers.get("content-type") ?? "";
75
+ if (ctype.includes("application/json"))
76
+ return (await response.json());
77
+ return (await response.arrayBuffer());
78
+ }
79
+ if (shouldRetry(response.status) && attempt < maxRetries) {
80
+ await sleep(backoff(attempt));
81
+ continue;
82
+ }
83
+ const { message, body } = await parseError(response);
84
+ throw errorForStatus(response.status, message, body, response.headers);
85
+ }
86
+ catch (err) {
87
+ clearTimeout(timer);
88
+ if (err instanceof APIError)
89
+ throw err;
90
+ // network/abort
91
+ const isTimeout = err?.name === "AbortError";
92
+ lastErr = isTimeout
93
+ ? new APIConnectionTimeoutError()
94
+ : new APIConnectionError(err instanceof Error ? err.message : "Connection error", { cause: err });
95
+ if (attempt < maxRetries) {
96
+ await sleep(backoff(attempt));
97
+ continue;
98
+ }
99
+ throw lastErr;
100
+ }
101
+ }
102
+ throw lastErr;
103
+ }
104
+ function sleep(ms) {
105
+ return new Promise((r) => setTimeout(r, ms));
106
+ }
107
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/core/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Sprntrl } from "../client.js";
2
+ export declare class APIResource {
3
+ protected _client: Sprntrl;
4
+ constructor(client: Sprntrl);
5
+ }
@@ -0,0 +1,7 @@
1
+ export class APIResource {
2
+ _client;
3
+ constructor(client) {
4
+ this._client = client;
5
+ }
6
+ }
7
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/core/resource.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAW;IACZ,OAAO,CAAU;IAE3B,YAAY,MAAe;QACzB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ export { Sprntrl, type ClientOptions } from "./client.js";
2
+ export { SprntrlError, APIError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, APIConnectionError, APIConnectionTimeoutError, } from "./core/error.js";
3
+ export type { OS, ProxyProtocol, ProxyConfig, SessionStatus, Session, ProxySummary, PaginatedSessions, Profile, Template, IPWhitelistEntry, APIKey, APIKeyCreated, Usage, UsageMonth, User, AccountStatus, FileInfo, } from "./types.js";
4
+ export type { SessionCreateParams, ConnectOptions, BrowserHandle } from "./resources/sessions.js";
5
+ export type { UserSettings, ChangePasswordResult } from "./resources/user.js";
6
+ export type { ProfileCreateParams } from "./resources/profiles.js";
7
+ export type { FileContent } from "./resources/session-files.js";
8
+ export { Sprntrl as default } from "./client.js";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { Sprntrl } from "./client.js";
2
+ export { SprntrlError, APIError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, APIConnectionError, APIConnectionTimeoutError, } from "./core/error.js";
3
+ export { Sprntrl as default } from "./client.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,wBAAwB,EACxB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAyBzB,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Sprntrl } from "../client.js";
2
+ import type { Session } from "../types.js";
3
+ export interface ConnectArgs {
4
+ framework?: "playwright" | "puppeteer";
5
+ autoWhitelist?: boolean;
6
+ }
7
+ export declare function connect(client: Sprntrl, session: Session, opts?: ConnectArgs): Promise<unknown>;
@@ -0,0 +1,56 @@
1
+ import { SprntrlError } from "../core/error.js";
2
+ function cdpUrlFor(client, session) {
3
+ // Build the URL from the client's base URL. The API proxies the WebSocket
4
+ // through /api/v1/sessions/:id/cdp with an IP-whitelist check — this is what
5
+ // external callers must hit. The server also returns session.cdp_url but
6
+ // that's an internal host:port that isn't reachable from outside the API host.
7
+ const base = new URL(client.baseURL);
8
+ const scheme = base.protocol === "https:" ? "wss:" : "ws:";
9
+ return `${scheme}//${base.host}/api/v1/sessions/${session.id}/cdp`;
10
+ }
11
+ export async function connect(client, session, opts = {}) {
12
+ const framework = opts.framework ?? "playwright";
13
+ if (opts.autoWhitelist) {
14
+ try {
15
+ await client.request({
16
+ method: "POST",
17
+ path: "/api/v1/settings/ip-whitelist",
18
+ body: { ip: "current" },
19
+ });
20
+ }
21
+ catch {
22
+ // Already-whitelisted or race; the connect attempt will surface real errors.
23
+ }
24
+ }
25
+ const cdpUrl = cdpUrlFor(client, session);
26
+ // Use a variable-indirected import so TypeScript does not resolve the
27
+ // optional peer dependency's types at compile time.
28
+ const dynImport = (name) => import(name);
29
+ if (framework === "playwright") {
30
+ let mod;
31
+ try {
32
+ mod = (await dynImport("playwright"));
33
+ }
34
+ catch {
35
+ throw new SprntrlError("playwright is not installed. Run `npm install playwright`.");
36
+ }
37
+ return mod.chromium.connectOverCDP(cdpUrl);
38
+ }
39
+ if (framework === "puppeteer") {
40
+ let mod;
41
+ try {
42
+ mod = (await dynImport("puppeteer-core"));
43
+ }
44
+ catch {
45
+ try {
46
+ mod = (await dynImport("puppeteer"));
47
+ }
48
+ catch {
49
+ throw new SprntrlError("puppeteer is not installed. Run `npm install puppeteer` (or puppeteer-core).");
50
+ }
51
+ }
52
+ return mod.connect({ browserWSEndpoint: cdpUrl });
53
+ }
54
+ throw new SprntrlError(`Unsupported framework '${framework}'`);
55
+ }
56
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/lib/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAShD,SAAS,SAAS,CAAC,MAAe,EAAE,OAAgB;IAClD,0EAA0E;IAC1E,6EAA6E;IAC7E,yEAAyE;IACzE,+EAA+E;IAC/E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3D,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC,IAAI,oBAAoB,OAAO,CAAC,EAAE,MAAM,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAe,EACf,OAAgB,EAChB,OAAoB,EAAE;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,YAAY,CAAC;IACjD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC;gBACnB,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,+BAA+B;gBACrC,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;aACxB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,6EAA6E;QAC/E,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE1C,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,SAAS,GAAuC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAE7E,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,IAAI,GAAwE,CAAC;QAC7E,IAAI,CAAC;YACH,GAAG,GAAG,CAAC,MAAM,SAAS,CAAC,YAAY,CAAC,CAAe,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,YAAY,CACpB,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;QAC9B,IAAI,GAA2E,CAAC;QAChF,IAAI,CAAC;YACH,GAAG,GAAG,CAAC,MAAM,SAAS,CAAC,gBAAgB,CAAC,CAAe,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,GAAG,GAAG,CAAC,MAAM,SAAS,CAAC,WAAW,CAAC,CAAe,CAAC;YACrD,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,YAAY,CACpB,8EAA8E,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC,OAAO,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,IAAI,YAAY,CAAC,0BAA0B,SAAS,GAAG,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { APIResource } from "../core/resource.js";
2
+ import type { APIKey, APIKeyCreated } from "../types.js";
3
+ export declare class APIKeys extends APIResource {
4
+ list(): Promise<APIKey[]>;
5
+ /**
6
+ * Create an API key. The full `key` field is returned ONLY on creation —
7
+ * store it immediately; the server cannot show it again.
8
+ */
9
+ create(name: string): Promise<APIKeyCreated>;
10
+ revoke(keyId: string): Promise<void>;
11
+ }