Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/browserbase-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20'

Expand All @@ -43,10 +43,10 @@ jobs:
contents: read
id-token: write
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20'

Expand All @@ -61,7 +61,7 @@ jobs:
github.repository == 'stainless-sdks/browserbase-node' &&
!startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: core.setOutput('github_token', await core.getIDToken());

Expand All @@ -80,10 +80,10 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/browserbase-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20'

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
with:
node-version: '20'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
if: github.repository == 'browserbase/sdk-node' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Check release environment
run: |
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.10.0"
".": "2.11.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 21
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fbrowserbase-921d3c61c7aa06269f74bee63cee993597944f913429caa2aa2e00dd51fab60f.yml
openapi_spec_hash: d35b9613c41bf172fa2b28aceef10b39
config_hash: cf04ecfb8dad5fbd8b85be25d6e9ec55
configured_endpoints: 23
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/browserbase-2118fd938d408dda6ed82d06c48b0785fad91fd54b5397acc3421a49a386c791.yml
openapi_spec_hash: 8e48a39a55a11b128028b47747aea775
config_hash: 40fbac80e24faaa0dc19e93368bcd821
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 2.11.0 (2026-05-13)

Full Changelog: [v2.10.0...v2.11.0](https://github.com/browserbase/sdk-node/compare/v2.10.0...v2.11.0)

### Features

* [CORE-1928][apps/api] Add `PENDING` as a valid session state ([6c1dc59](https://github.com/browserbase/sdk-node/commit/6c1dc59e8ed581d88c26483a84efecd3903f4379))
* [CORE-1979] [apps/api] Regenerate OpenAPI spec to match current routes ([90f048c](https://github.com/browserbase/sdk-node/commit/90f048c79e02ead952b73d6bd185f6d58fa25076))
* **api:** add replays ([c1bcc8b](https://github.com/browserbase/sdk-node/commit/c1bcc8b9e6baff112a6672b24dccba0cec683c72))
* support setting headers via env ([c4bce5e](https://github.com/browserbase/sdk-node/commit/c4bce5e45f6dc0d2f560313ea70fd9bb1ac28fa6))


### Chores

* **internal:** codegen related update ([e079c39](https://github.com/browserbase/sdk-node/commit/e079c39733d21312ee5d9e11fed35a2b8bba93be))
* **internal:** more robust bootstrap script ([39adddf](https://github.com/browserbase/sdk-node/commit/39adddf3d60bcf94349cb9103a7f41a1b0bb9f9f))
* **tests:** bump steady to v0.22.1 ([cd4bf1a](https://github.com/browserbase/sdk-node/commit/cd4bf1aad650b63d38638218919715a790c1c819))

## 2.10.0 (2026-04-06)

Full Changelog: [v2.9.0...v2.10.0](https://github.com/browserbase/sdk-node/compare/v2.9.0...v2.10.0)
Expand Down
11 changes: 11 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,14 @@ Types:
Methods:

- <code title="post /v1/sessions/{id}/uploads">client.sessions.uploads.<a href="./src/resources/sessions/uploads.ts">create</a>(id, { ...params }) -> UploadCreateResponse</code>

## Replays

Types:

- <code><a href="./src/resources/sessions/replays.ts">ReplayRetrieveResponse</a></code>

Methods:

- <code title="get /v1/sessions/{id}/replays">client.sessions.replays.<a href="./src/resources/sessions/replays.ts">retrieve</a>(id) -> ReplayRetrieveResponse</code>
- <code title="get /v1/sessions/{id}/replays/{pageId}">client.sessions.replays.<a href="./src/resources/sessions/replays.ts">retrievePage</a>(id, pageId) -> Response</code>
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@browserbasehq/sdk",
"version": "2.10.0",
"version": "2.11.0",
"description": "The official Node.js library for the Browserbase API",
"author": "Browserbase <support@browserbase.com>",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion scripts/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -e

cd "$(dirname "$0")/.."

if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then
brew bundle check >/dev/null 2>&1 || {
echo -n "==> Install Homebrew dependencies? (y/N): "
read -r response
Expand Down
6 changes: 3 additions & 3 deletions scripts/mock
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ echo "==> Starting mock server with URL ${URL}"
# Run steady mock on the given spec
if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
npm exec --package=@stdy/cli@0.20.2 -- steady --version
npm exec --package=@stdy/cli@0.22.1 -- steady --version

npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &

# Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
Expand All @@ -48,5 +48,5 @@ if [ "$1" == "--daemon" ]; then

echo
else
npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
2 changes: 1 addition & 1 deletion scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ elif ! steady_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the steady command:"
echo
echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.20.2 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo

exit 1
Expand Down
4 changes: 2 additions & 2 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1054,10 +1054,10 @@ export const ensurePresent = <T>(value: T | null | undefined): T => {
*/
export const readEnv = (env: string): string | undefined => {
if (typeof process !== 'undefined') {
return process.env?.[env]?.trim() ?? undefined;
return process.env?.[env]?.trim() || undefined;
}
if (typeof Deno !== 'undefined') {
return Deno.env?.get?.(env)?.trim();
return Deno.env?.get?.(env)?.trim() || undefined;
}
return undefined;
};
Expand Down
12 changes: 12 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ export class Browserbase extends Core.APIClient {
fetch: options.fetch,
});

const customHeadersEnv = Core.readEnv('BROWSERBASE_CUSTOM_HEADERS');
if (customHeadersEnv) {
const parsed: Record<string, string> = {};
for (const line of customHeadersEnv.split('\n')) {
const colon = line.indexOf(':');
if (colon >= 0) {
parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim();
}
}
options.defaultHeaders = { ...parsed, ...options.defaultHeaders };
}

this._options = options;

this.apiKey = apiKey;
Expand Down
1 change: 1 addition & 0 deletions src/resources/sessions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
export { Downloads } from './downloads';
export { Logs, type SessionLog, type LogListResponse } from './logs';
export { Recording, type SessionRecording, type RecordingRetrieveResponse } from './recording';
export { Replays, type ReplayRetrieveResponse } from './replays';
export {
Sessions,
type Session,
Expand Down
49 changes: 49 additions & 0 deletions src/resources/sessions/replays.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import { APIResource } from '../../resource';
import * as Core from '../../core';
import { type Response } from '../../_shims/index';

export class Replays extends APIResource {
/**
* Returns page metadata for a session replay, including timing information and the
* URL of each page's HLS playlist.
*/
retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise<ReplayRetrieveResponse> {
return this._client.get(`/v1/sessions/${id}/replays`, options);
}

/**
* Returns an HLS VOD media playlist (.m3u8) for a specific page of a session
* replay.
*/
retrievePage(id: string, pageId: string, options?: Core.RequestOptions): Core.APIPromise<Response> {
return this._client.get(`/v1/sessions/${id}/replays/${pageId}`, {
...options,
headers: { Accept: 'application/vnd.apple.mpegurl', ...options?.headers },
__binaryResponse: true,
});
}
}

export interface ReplayRetrieveResponse {
pageCount: number;

pages: Array<ReplayRetrieveResponse.Page>;
}

export namespace ReplayRetrieveResponse {
export interface Page {
endTimeMs: number;

pageId: string;

startTimeMs: number;

url: string;
}
}

export declare namespace Replays {
export { type ReplayRetrieveResponse as ReplayRetrieveResponse };
}
16 changes: 14 additions & 2 deletions src/resources/sessions/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as LogsAPI from './logs';
import { LogListResponse, Logs, SessionLog } from './logs';
import * as RecordingAPI from './recording';
import { Recording, RecordingRetrieveResponse, SessionRecording } from './recording';
import * as ReplaysAPI from './replays';
import { ReplayRetrieveResponse, Replays } from './replays';
import * as UploadsAPI from './uploads';
import { UploadCreateParams, UploadCreateResponse, Uploads } from './uploads';

Expand All @@ -17,6 +19,7 @@ export class Sessions extends APIResource {
logs: LogsAPI.Logs = new LogsAPI.Logs(this._client);
recording: RecordingAPI.Recording = new RecordingAPI.Recording(this._client);
uploads: UploadsAPI.Uploads = new UploadsAPI.Uploads(this._client);
replays: ReplaysAPI.Replays = new ReplaysAPI.Replays(this._client);

/**
* Create a Session
Expand Down Expand Up @@ -99,7 +102,7 @@ export interface Session {

startedAt: string;

status: 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';
status: 'PENDING' | 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';

updatedAt: string;

Expand Down Expand Up @@ -263,6 +266,12 @@ export namespace SessionCreateParams {
*/
extensionId?: string;

/**
* Enable or disable ignoring of certificate errors in the browser. Defaults to
* `true`.
*/
ignoreCertificateErrors?: boolean;

/**
* Enable or disable session logging. Defaults to `true`.
*/
Expand Down Expand Up @@ -424,13 +433,14 @@ export interface SessionListParams {
*/
q?: string;

status?: 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';
status?: 'PENDING' | 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';
}

Sessions.Downloads = Downloads;
Sessions.Logs = Logs;
Sessions.Recording = Recording;
Sessions.Uploads = Uploads;
Sessions.Replays = Replays;

export declare namespace Sessions {
export {
Expand Down Expand Up @@ -459,4 +469,6 @@ export declare namespace Sessions {
type UploadCreateResponse as UploadCreateResponse,
type UploadCreateParams as UploadCreateParams,
};

export { Replays as Replays, type ReplayRetrieveResponse as ReplayRetrieveResponse };
}
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const VERSION = '2.10.0'; // x-release-please-version
export const VERSION = '2.11.0'; // x-release-please-version
40 changes: 40 additions & 0 deletions tests/api-resources/sessions/replays.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import Browserbase from '@browserbasehq/sdk';
import { Response } from 'node-fetch';

const client = new Browserbase({
apiKey: 'My API Key',
baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
});

describe('resource replays', () => {
test('retrieve', async () => {
const responsePromise = client.sessions.replays.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
const response = await responsePromise;
expect(response).not.toBeInstanceOf(Response);
const dataAndResponse = await responsePromise.withResponse();
expect(dataAndResponse.data).toBe(response);
expect(dataAndResponse.response).toBe(rawResponse);
});

test('retrieve: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.sessions.replays.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
path: '/_stainless_unknown_path',
}),
).rejects.toThrow(Browserbase.NotFoundError);
});

test('retrievePage: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.sessions.replays.retrievePage('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', '090', {
path: '/_stainless_unknown_path',
}),
).rejects.toThrow(Browserbase.NotFoundError);
});
});
3 changes: 2 additions & 1 deletion tests/api-resources/sessions/sessions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe('resource sessions', () => {
captchaInputSelector: 'captchaInputSelector',
context: { id: 'id', persist: true },
extensionId: 'extensionId',
ignoreCertificateErrors: true,
logSession: true,
os: 'windows',
recordSession: true,
Expand Down Expand Up @@ -126,7 +127,7 @@ describe('resource sessions', () => {
test('list: request options and params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.sessions.list({ q: 'q', status: 'RUNNING' }, { path: '/_stainless_unknown_path' }),
client.sessions.list({ q: 'q', status: 'PENDING' }, { path: '/_stainless_unknown_path' }),
).rejects.toThrow(Browserbase.NotFoundError);
});

Expand Down
Loading