Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9e23e52
fix(mcp): return correct lines on typescript errors
stainless-app[bot] Dec 6, 2025
43c1b91
chore(internal): codegen related update
stainless-app[bot] Dec 6, 2025
e1d8df1
fix(mcp): correct code tool API endpoint
stainless-app[bot] Dec 6, 2025
efcc324
chore(internal): codegen related update
stainless-app[bot] Dec 6, 2025
f157a69
codegen metadata
stainless-app[bot] Dec 8, 2025
b703bb5
codegen metadata
stainless-app[bot] Dec 9, 2025
279de67
codegen metadata
stainless-app[bot] Dec 16, 2025
0d68c1f
codegen metadata
stainless-app[bot] Dec 16, 2025
fe83e26
feat(api): api update
stainless-app[bot] Dec 18, 2025
bbebe4a
feat(api): api update
stainless-app[bot] Dec 19, 2025
7f4433d
codegen metadata
stainless-app[bot] Dec 19, 2025
197cdca
codegen metadata
stainless-app[bot] Dec 29, 2025
e7ffd0c
chore(internal): codegen related update
stainless-app[bot] Jan 6, 2026
2a92dd1
chore: break long lines in snippets into multiline
stainless-app[bot] Jan 7, 2026
02d2330
codegen metadata
stainless-app[bot] Jan 7, 2026
b90b238
codegen metadata
stainless-app[bot] Jan 8, 2026
508b400
codegen metadata
stainless-app[bot] Jan 15, 2026
fe821a3
chore(internal): upgrade babel, qs, js-yaml
stainless-app[bot] Jan 15, 2026
3eece52
codegen metadata
stainless-app[bot] Jan 15, 2026
0a620ee
chore(internal): update `actions/checkout` version
stainless-app[bot] Jan 17, 2026
63946c7
codegen metadata
stainless-app[bot] Jan 20, 2026
924599d
codegen metadata
stainless-app[bot] Jan 20, 2026
a93a07c
feat(api): api update
stainless-app[bot] Jan 24, 2026
16bd5ac
chore(ci): upgrade `actions/github-script`
stainless-app[bot] Jan 24, 2026
d8ddd0a
feat(api): api update
stainless-app[bot] Jan 24, 2026
6286210
codegen metadata
stainless-app[bot] Jan 26, 2026
d90179c
codegen metadata
stainless-app[bot] Jan 26, 2026
3125a12
codegen metadata
stainless-app[bot] Jan 27, 2026
81cd1ab
codegen metadata
stainless-app[bot] Jan 28, 2026
fee3f3a
codegen metadata
stainless-app[bot] Jan 29, 2026
0ec5e60
codegen metadata
stainless-app[bot] Jan 30, 2026
01abc61
feat(api): api update
stainless-app[bot] Jan 31, 2026
58aa0a6
feat(api): api update
stainless-app[bot] Feb 3, 2026
a1c5d0e
fix(client): avoid memory leak with abort signals
stainless-app[bot] Feb 3, 2026
b9f61a8
chore(client): do not parse responses with empty content-length
stainless-app[bot] Feb 3, 2026
9acb0f7
chore(client): restructure abort controller binding
stainless-app[bot] Feb 5, 2026
7088589
fix(client): avoid removing abort listener too early
stainless-app[bot] Feb 6, 2026
4df6efb
feat(api): api update
stainless-app[bot] Feb 6, 2026
0f22218
codegen metadata
stainless-app[bot] Feb 6, 2026
ad47c1f
release: 0.1.0-alpha.28
stainless-app[bot] Feb 6, 2026
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
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/sfc-nodes-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v4
Expand All @@ -41,7 +41,7 @@ jobs:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v4
Expand All @@ -57,7 +57,7 @@ jobs:
- name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/sfc-nodes-typescript'
id: github-oidc
uses: actions/github-script@v6
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());

Expand All @@ -74,7 +74,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/sfc-nodes-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v3
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 == 'sfcompute/nodes-typescript' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- 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 @@
{
".": "0.1.0-alpha.27"
".": "0.1.0-alpha.28"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 15
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-7284b205c8d1bc77799405fdd08ca68120426b87031cbc22718da68e22ed5a4c.yml
openapi_spec_hash: b0248957ae5bcf9896f6d74d5c05351b
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-d5ffc2bd6330b6807eef6499bc998fec3a4fecadbccb22e11a362dd9d4a0a2ad.yml
openapi_spec_hash: b7dff8adf3ec3fb0abd7e152cc6264b2
config_hash: a187153315a646ecf95709ee4a223df5
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
# Changelog

## 0.1.0-alpha.28 (2026-02-06)

Full Changelog: [v0.1.0-alpha.27...v0.1.0-alpha.28](https://github.com/sfcompute/nodes-typescript/compare/v0.1.0-alpha.27...v0.1.0-alpha.28)

### Features

* **api:** api update ([4df6efb](https://github.com/sfcompute/nodes-typescript/commit/4df6efb7e1e4d00a8a7eaf41c67363771adcc56f))
* **api:** api update ([58aa0a6](https://github.com/sfcompute/nodes-typescript/commit/58aa0a6527b383deb0612308a6d6639af8488aaa))
* **api:** api update ([01abc61](https://github.com/sfcompute/nodes-typescript/commit/01abc6189822a16326fddfe3c772fc5747024699))
* **api:** api update ([d8ddd0a](https://github.com/sfcompute/nodes-typescript/commit/d8ddd0a62ea2c7cc12de16b2c3198e84e62c867d))
* **api:** api update ([a93a07c](https://github.com/sfcompute/nodes-typescript/commit/a93a07c6ac7774864fc54059a3ce6c02002f298e))
* **api:** api update ([bbebe4a](https://github.com/sfcompute/nodes-typescript/commit/bbebe4afcdcae6e389e7f25a15ed924d7dbd25b3))
* **api:** api update ([fe83e26](https://github.com/sfcompute/nodes-typescript/commit/fe83e263cf3bef0a4d231172b231b126d4bc81da))


### Bug Fixes

* **client:** avoid memory leak with abort signals ([a1c5d0e](https://github.com/sfcompute/nodes-typescript/commit/a1c5d0e09b6c77eb7b982a82ef87f5d0e3150268))
* **client:** avoid removing abort listener too early ([7088589](https://github.com/sfcompute/nodes-typescript/commit/7088589b8f94f2f5d1200ccbf44f21856789fdea))
* **mcp:** correct code tool API endpoint ([e1d8df1](https://github.com/sfcompute/nodes-typescript/commit/e1d8df157f5bd1c9922ff4689a6ff69288ea31c0))
* **mcp:** return correct lines on typescript errors ([9e23e52](https://github.com/sfcompute/nodes-typescript/commit/9e23e52f4e9e18876ea7454bf2dc1f3e393ba9b4))


### Chores

* break long lines in snippets into multiline ([2a92dd1](https://github.com/sfcompute/nodes-typescript/commit/2a92dd1fadce15736de21aef47c6a09053fcfdbe))
* **ci:** upgrade `actions/github-script` ([16bd5ac](https://github.com/sfcompute/nodes-typescript/commit/16bd5ac8c6a4ca5370c03e4105abd1b5f9f3bcf1))
* **client:** do not parse responses with empty content-length ([b9f61a8](https://github.com/sfcompute/nodes-typescript/commit/b9f61a83ea06509354396c66604bc811f90d18b5))
* **client:** restructure abort controller binding ([9acb0f7](https://github.com/sfcompute/nodes-typescript/commit/9acb0f7b00ca428a1e0681214c41fa59146d41fc))
* **internal:** codegen related update ([e7ffd0c](https://github.com/sfcompute/nodes-typescript/commit/e7ffd0c274c456917d2ef7dcd7b78d2b12370bd9))
* **internal:** codegen related update ([efcc324](https://github.com/sfcompute/nodes-typescript/commit/efcc3241aab120b1e10d771c14f0fa97763c38c5))
* **internal:** codegen related update ([43c1b91](https://github.com/sfcompute/nodes-typescript/commit/43c1b91d4522c19e7000542db9b26d0ba5b96b32))
* **internal:** update `actions/checkout` version ([0a620ee](https://github.com/sfcompute/nodes-typescript/commit/0a620ee1a5685cf84a5a05d471c12bbc3713aab6))
* **internal:** upgrade babel, qs, js-yaml ([fe821a3](https://github.com/sfcompute/nodes-typescript/commit/fe821a3fa77954f51049813e63d58342795f65e3))

## 0.1.0-alpha.27 (2025-12-06)

Full Changelog: [v0.1.0-alpha.26...v0.1.0-alpha.27](https://github.com/sfcompute/nodes-typescript/compare/v0.1.0-alpha.26...v0.1.0-alpha.27)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2025 SFC Nodes
Copyright 2026 SFC Nodes

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sfcompute/nodes-sdk-alpha",
"version": "0.1.0-alpha.27",
"version": "0.1.0-alpha.28",
"description": "The official TypeScript library for the SFC Nodes API",
"author": "SFC Nodes <hello@sfcompute.com>",
"types": "dist/index.d.ts",
Expand Down
11 changes: 9 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,10 @@ export class SFCNodes {
controller: AbortController,
): Promise<Response> {
const { signal, method, ...options } = init || {};
if (signal) signal.addEventListener('abort', () => controller.abort());
const abort = this._makeAbort(controller);
if (signal) signal.addEventListener('abort', abort, { once: true });

const timeout = setTimeout(() => controller.abort(), ms);
const timeout = setTimeout(abort, ms);

const isReadableBody =
((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
Expand Down Expand Up @@ -668,6 +669,12 @@ export class SFCNodes {
return headers.values;
}

private _makeAbort(controller: AbortController) {
// note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
// would capture all request options, and cause a memory leak.
return () => controller.abort();
}

private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): {
bodyHeaders: HeadersLike;
body: BodyInit | undefined;
Expand Down
6 changes: 6 additions & 0 deletions src/internal/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export async function defaultParseResponse<T>(client: SFCNodes, props: APIRespon
const mediaType = contentType?.split(';')[0]?.trim();
const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json');
if (isJSON) {
const contentLength = response.headers.get('content-length');
if (contentLength === '0') {
// if there is no content we can't do anything
return undefined as T;
}

const json = await response.json();
return json as T;
}
Expand Down
12 changes: 11 additions & 1 deletion src/resources/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class Nodes extends APIResource {
* ```ts
* const listResponseNode = await client.nodes.create({
* desired_count: 1,
* max_price_per_node_hour: 1000,
* max_price_per_node_hour: 1600,
* });
* ```
*/
Expand Down Expand Up @@ -134,6 +134,11 @@ export interface CreateNodesRequest {
*/
end_at?: number | null;

/**
* (Optional) If set, enables forwarding to the VM on port 443.
*/
forward_443?: boolean;

/**
* Custom image ID to use for the VM instances
*/
Expand Down Expand Up @@ -480,6 +485,11 @@ export interface NodeCreateParams {
*/
end_at?: number | null;

/**
* (Optional) If set, enables forwarding to the VM on port 443.
*/
forward_443?: boolean;

/**
* Custom image ID to use for the VM instances
*/
Expand Down
30 changes: 5 additions & 25 deletions src/resources/vms/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,27 @@ export class Images extends APIResource {
}
}

/**
* Response body for listing images
*/
export interface ImageListResponse {
data: Array<ImageListResponse.Data>;

has_more: boolean;

object: 'list';
}

export namespace ImageListResponse {
/**
* Response body for individual image info (used in lists)
*/
export interface Data {
/**
* Creation timestamp as Unix timestamp in seconds
*/
created_at: number;
id: string;

/**
* The image ID
* Unix timestamp in seconds since epoch
*/
image_id: string;
created_at: number;

/**
* Client given name of the image. Must be unique per account.
*/
name: string;

object: 'image';

/**
* Upload status of the image
*/
upload_status: string;

/**
* SHA256 hash of the image file for integrity verification
*/
object?: 'image';

sha256_hash?: string | null;
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/resources/zones.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export namespace ZoneListResponse {
object: string;

region: 'NorthAmerica' | 'AsiaPacific' | 'EuropeMiddleEastAfrica';

/**
* User-facing zone name (e.g., "Hayes Valley", "Land's End")
*/
display_name?: string | null;
}

export namespace Data {
Expand Down Expand Up @@ -87,6 +92,11 @@ export interface ZoneGetResponse {
object: string;

region: 'NorthAmerica' | 'AsiaPacific' | 'EuropeMiddleEastAfrica';

/**
* User-facing zone name (e.g., "Hayes Valley", "Land's End")
*/
display_name?: string | null;
}

export namespace ZoneGetResponse {
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 = '0.1.0-alpha.27'; // x-release-please-version
export const VERSION = '0.1.0-alpha.28'; // x-release-please-version
11 changes: 8 additions & 3 deletions tests/api-resources/nodes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const client = new SFCNodes({
describe('resource nodes', () => {
// Prism tests are disabled
test.skip('create: only required params', async () => {
const responsePromise = client.nodes.create({ desired_count: 1, max_price_per_node_hour: 1000 });
const responsePromise = client.nodes.create({ desired_count: 1, max_price_per_node_hour: 1600 });
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
const response = await responsePromise;
Expand All @@ -24,10 +24,11 @@ describe('resource nodes', () => {
test.skip('create: required and optional params', async () => {
const response = await client.nodes.create({
desired_count: 1,
max_price_per_node_hour: 1000,
max_price_per_node_hour: 1600,
any_zone: false,
cloud_init_user_data: 'aGVsbG8gd29ybGQ=',
end_at: 0,
forward_443: false,
image_id: 'vmi_1234567890abcdef',
names: ['cuda-crunch'],
node_type: 'autoreserved',
Expand All @@ -53,7 +54,11 @@ describe('resource nodes', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.nodes.list(
{ id: ['string'], name: ['string'], type: 'autoreserved' },
{
id: ['string'],
name: ['string'],
type: 'autoreserved',
},
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(SFCNodes.NotFoundError);
Expand Down
Loading