diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7a48e52..d18e944 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.12.0" + ".": "2.13.0" } diff --git a/.stats.yml b/.stats.yml index f40d116..17cb18b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 460a81b..230c535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/README.md b/README.md index 2a98f47..e767652 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/api.md b/api.md index 11f9afd..04af9b4 100644 --- a/api.md +++ b/api.md @@ -1,3 +1,17 @@ +# Certificates + +Types: + +- Certificate +- CertificateListResponse + +Methods: + +- client.certificates.create({ ...params }) -> Certificate +- client.certificates.retrieve(id) -> Certificate +- client.certificates.list() -> CertificateListResponse +- client.certificates.delete(id) -> void + # Contexts Types: diff --git a/package-lock.json b/package-lock.json index 1298b90..519523a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@browserbasehq/sdk", - "version": "2.12.0", + "version": "2.13.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@browserbasehq/sdk", - "version": "2.12.0", + "version": "2.13.0", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", diff --git a/package.json b/package.json index c303732..bfaaf83 100644 --- a/package.json +++ b/package.json @@ -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 ", "types": "dist/index.d.ts", diff --git a/src/index.ts b/src/index.ts index 19c7fb5..68d3aee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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, @@ -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); @@ -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; @@ -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, diff --git a/src/resources/certificates.ts b/src/resources/certificates.ts new file mode 100644 index 0000000..5f6413f --- /dev/null +++ b/src/resources/certificates.ts @@ -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 { + return this._client.post('/v1/certificates', Core.multipartFormRequestOptions({ body, ...options })); + } + + /** + * Get a Certificate + */ + retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise { + return this._client.get(`/v1/certificates/${id}`, options); + } + + /** + * List Certificates + */ + list(options?: Core.RequestOptions): Core.APIPromise { + return this._client.get('/v1/certificates', options); + } + + /** + * Delete a Certificate + */ + delete(id: string, options?: Core.RequestOptions): Core.APIPromise { + 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; + +export interface CertificateCreateParams { + file: Core.Uploadable; +} + +export declare namespace Certificates { + export { + type Certificate as Certificate, + type CertificateListResponse as CertificateListResponse, + type CertificateCreateParams as CertificateCreateParams, + }; +} diff --git a/src/resources/index.ts b/src/resources/index.ts index f1ec403..7192b67 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -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, diff --git a/src/version.ts b/src/version.ts index e06ef68..31707fe 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '2.12.0'; // x-release-please-version +export const VERSION = '2.13.0'; // x-release-please-version diff --git a/tests/api-resources/certificates.test.ts b/tests/api-resources/certificates.test.ts new file mode 100644 index 0000000..f795a51 --- /dev/null +++ b/tests/api-resources/certificates.test.ts @@ -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, + ); + }); +});