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
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.12.0"
".": "2.13.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: 23
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/browserbase-b2831c9c836f039762834825afdc20569587a825d29ac5c3748c78b009bf059b.yml
openapi_spec_hash: dd85a934900cb6583f12ebf6117be884
config_hash: 40fbac80e24faaa0dc19e93368bcd821
configured_endpoints: 27
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/browserbase-9bab373fc62ce19147560ed3ec29fe09ad59d9a5b406d9ed21a22f15a511d9cb.yml
openapi_spec_hash: 518fdefff1eabc4bb8a3b54ddf7fa293
config_hash: d4b0c534eaf7665ea25168e0e824c9d3
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 2.13.0 (2026-06-05)

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

### Features

* [CORE-2194][apps/api] Add BYOC (cert) CRUD to SDKs ([06b3a85](https://github.com/browserbase/sdk-node/commit/06b3a850b9e8955a7770ecdb43cd0820480b7c5f))

## 2.12.0 (2026-05-20)

Full Changelog: [v2.11.0...v2.12.0](https://github.com/browserbase/sdk-node/compare/v2.11.0...v2.12.0)
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ import Browserbase, { toFile } from '@browserbasehq/sdk';
const client = new Browserbase();

// If you have access to Node `fs` we recommend using `fs.createReadStream()`:
await client.extensions.create({ file: fs.createReadStream('/path/to/file') });
await client.certificates.create({ file: fs.createReadStream('/path/to/file') });

// Or if you have the web `File` API you can pass a `File` instance:
await client.extensions.create({ file: new File(['my bytes'], 'file') });
await client.certificates.create({ file: new File(['my bytes'], 'file') });

// You can also pass a `fetch` `Response`:
await client.extensions.create({ file: await fetch('https://somesite/file') });
await client.certificates.create({ file: await fetch('https://somesite/file') });

// Finally, if none of the above are convenient, you can use our `toFile` helper:
await client.extensions.create({ file: await toFile(Buffer.from('my bytes'), 'file') });
await client.extensions.create({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
await client.certificates.create({ file: await toFile(Buffer.from('my bytes'), 'file') });
await client.certificates.create({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
```

## Handling errors
Expand Down
14 changes: 14 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Certificates

Types:

- <code><a href="./src/resources/certificates.ts">Certificate</a></code>
- <code><a href="./src/resources/certificates.ts">CertificateListResponse</a></code>

Methods:

- <code title="post /v1/certificates">client.certificates.<a href="./src/resources/certificates.ts">create</a>({ ...params }) -> Certificate</code>
- <code title="get /v1/certificates/{id}">client.certificates.<a href="./src/resources/certificates.ts">retrieve</a>(id) -> Certificate</code>
- <code title="get /v1/certificates">client.certificates.<a href="./src/resources/certificates.ts">list</a>() -> CertificateListResponse</code>
- <code title="delete /v1/certificates/{id}">client.certificates.<a href="./src/resources/certificates.ts">delete</a>(id) -> void</code>

# Contexts

Types:
Expand Down
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.12.0",
"version": "2.13.0",
"description": "The official Node.js library for the Browserbase API",
"author": "Browserbase <support@browserbase.com>",
"types": "dist/index.d.ts",
Expand Down
15 changes: 15 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import * as Core from './core';
import * as Errors from './error';
import * as Uploads from './uploads';
import * as API from './resources/index';
import {
Certificate,
CertificateCreateParams,
CertificateListResponse,
Certificates,
} from './resources/certificates';
import {
Context,
ContextCreateParams,
Expand Down Expand Up @@ -156,6 +162,7 @@ export class Browserbase extends Core.APIClient {
this.apiKey = apiKey;
}

certificates: API.Certificates = new API.Certificates(this);
contexts: API.Contexts = new API.Contexts(this);
extensions: API.Extensions = new API.Extensions(this);
fetchAPI: API.FetchAPI = new API.FetchAPI(this);
Expand Down Expand Up @@ -206,6 +213,7 @@ export class Browserbase extends Core.APIClient {
static fileFromPath = Uploads.fileFromPath;
}

Browserbase.Certificates = Certificates;
Browserbase.Contexts = Contexts;
Browserbase.Extensions = Extensions;
Browserbase.FetchAPI = FetchAPI;
Expand All @@ -216,6 +224,13 @@ Browserbase.Sessions = Sessions;
export declare namespace Browserbase {
export type RequestOptions = Core.RequestOptions;

export {
Certificates as Certificates,
type Certificate as Certificate,
type CertificateListResponse as CertificateListResponse,
type CertificateCreateParams as CertificateCreateParams,
};

export {
Contexts as Contexts,
type Context as Context,
Expand Down
64 changes: 64 additions & 0 deletions src/resources/certificates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import { APIResource } from '../resource';
import * as Core from '../core';

export class Certificates extends APIResource {
/**
* Upload a Certificate
*/
create(body: CertificateCreateParams, options?: Core.RequestOptions): Core.APIPromise<Certificate> {
return this._client.post('/v1/certificates', Core.multipartFormRequestOptions({ body, ...options }));
}

/**
* Get a Certificate
*/
retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise<Certificate> {
return this._client.get(`/v1/certificates/${id}`, options);
}

/**
* List Certificates
*/
list(options?: Core.RequestOptions): Core.APIPromise<CertificateListResponse> {
return this._client.get('/v1/certificates', options);
}

/**
* Delete a Certificate
*/
delete(id: string, options?: Core.RequestOptions): Core.APIPromise<void> {
return this._client.delete(`/v1/certificates/${id}`, {
...options,
headers: { Accept: '*/*', ...options?.headers },
});
}
}

export interface Certificate {
id: string;

createdAt: string;

/**
* The Project ID linked to the uploaded Certificate.
*/
projectId: string;

updatedAt: string;
}

export type CertificateListResponse = Array<Certificate>;

export interface CertificateCreateParams {
file: Core.Uploadable;
}

export declare namespace Certificates {
export {
type Certificate as Certificate,
type CertificateListResponse as CertificateListResponse,
type CertificateCreateParams as CertificateCreateParams,
};
}
6 changes: 6 additions & 0 deletions src/resources/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

export {
Certificates,
type Certificate,
type CertificateListResponse,
type CertificateCreateParams,
} from './certificates';
export {
Contexts,
type Context,
Expand Down
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.12.0'; // x-release-please-version
export const VERSION = '2.13.0'; // x-release-please-version
84 changes: 84 additions & 0 deletions tests/api-resources/certificates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import Browserbase, { toFile } 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 certificates', () => {
test('create: only required params', async () => {
const responsePromise = client.certificates.create({
file: await toFile(Buffer.from('Example data'), 'README.md'),
});
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('create: required and optional params', async () => {
const response = await client.certificates.create({
file: await toFile(Buffer.from('Example data'), 'README.md'),
});
});

test('retrieve', async () => {
const responsePromise = client.certificates.retrieve('id');
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.certificates.retrieve('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
Browserbase.NotFoundError,
);
});

test('list', async () => {
const responsePromise = client.certificates.list();
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('list: 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.certificates.list({ path: '/_stainless_unknown_path' })).rejects.toThrow(
Browserbase.NotFoundError,
);
});

test('delete', async () => {
const responsePromise = client.certificates.delete('id');
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('delete: 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.certificates.delete('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
Browserbase.NotFoundError,
);
});
});
Loading