From dd70400abff7e7332cf7a7f3dee59e9e2e4b61b5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 02:03:10 +0000
Subject: [PATCH 01/52] feat(api): api update
---
.stats.yml | 4 ++--
node.go | 17 ++++++++++++++---
node_test.go | 3 ++-
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 649bd1e..a4da285 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-c9d6d56eabd56a40a29dc2639a77d22dd5394ecd3ec9aeaebb3a3977811571da.yml
-openapi_spec_hash: beda3f45c48679e14d6fe8bbe7003d51
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-7284b205c8d1bc77799405fdd08ca68120426b87031cbc22718da68e22ed5a4c.yml
+openapi_spec_hash: b0248957ae5bcf9896f6d74d5c05351b
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/node.go b/node.go
index b15c3ad..e37d18a 100644
--- a/node.go
+++ b/node.go
@@ -125,16 +125,16 @@ const (
AcceleratorTypeH200 AcceleratorType = "H200"
)
-// The properties DesiredCount, MaxPricePerNodeHour, Zone are required.
+// The properties DesiredCount, MaxPricePerNodeHour are required.
type CreateNodesRequestParam struct {
DesiredCount int64 `json:"desired_count,required"`
// Max price per hour for a node in cents
MaxPricePerNodeHour int64 `json:"max_price_per_node_hour,required"`
- // Zone to create the nodes in
- Zone string `json:"zone,required"`
// End time as Unix timestamp in seconds If provided, end time must be aligned to
// the hour If not provided, the node will be created as an autoreserved node
EndAt param.Opt[int64] `json:"end_at,omitzero"`
+ // Allow auto reserved nodes to be created in any zone that meets the requirements
+ AnyZone param.Opt[bool] `json:"any_zone,omitzero"`
// User script to be executed during the VM's boot process Data should be base64
// encoded
CloudInitUserData param.Opt[string] `json:"cloud_init_user_data,omitzero" format:"byte"`
@@ -143,6 +143,9 @@ type CreateNodesRequestParam struct {
// Start time as Unix timestamp in seconds Optional for reserved nodes. If not
// provided, defaults to now
StartAt param.Opt[int64] `json:"start_at,omitzero"`
+ // Zone to create the nodes in. Required for auto reserved nodes if any_zone is
+ // false.
+ Zone param.Opt[string] `json:"zone,omitzero"`
// Custom node names Names cannot begin with 'vm*' or 'n*' as this is reserved for
// system-generated IDs Names cannot be numeric strings Names cannot exceed 128
// characters
@@ -265,6 +268,7 @@ type ListResponseNodeDataCurrentVM struct {
// Any of "Pending", "Running", "Destroyed", "NodeFailure", "Unspecified".
Status string `json:"status,required"`
UpdatedAt int64 `json:"updated_at,required"`
+ Zone string `json:"zone,required"`
ImageID string `json:"image_id,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -275,6 +279,7 @@ type ListResponseNodeDataCurrentVM struct {
StartAt respjson.Field
Status respjson.Field
UpdatedAt respjson.Field
+ Zone respjson.Field
ImageID respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -314,6 +319,7 @@ type ListResponseNodeDataVMsData struct {
// Any of "Pending", "Running", "Destroyed", "NodeFailure", "Unspecified".
Status string `json:"status,required"`
UpdatedAt int64 `json:"updated_at,required"`
+ Zone string `json:"zone,required"`
ImageID string `json:"image_id,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -324,6 +330,7 @@ type ListResponseNodeDataVMsData struct {
StartAt respjson.Field
Status respjson.Field
UpdatedAt respjson.Field
+ Zone respjson.Field
ImageID respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -405,6 +412,7 @@ type NodeCurrentVM struct {
// Any of "Pending", "Running", "Destroyed", "NodeFailure", "Unspecified".
Status string `json:"status,required"`
UpdatedAt int64 `json:"updated_at,required"`
+ Zone string `json:"zone,required"`
ImageID string `json:"image_id,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -415,6 +423,7 @@ type NodeCurrentVM struct {
StartAt respjson.Field
Status respjson.Field
UpdatedAt respjson.Field
+ Zone respjson.Field
ImageID respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -454,6 +463,7 @@ type NodeVMsData struct {
// Any of "Pending", "Running", "Destroyed", "NodeFailure", "Unspecified".
Status string `json:"status,required"`
UpdatedAt int64 `json:"updated_at,required"`
+ Zone string `json:"zone,required"`
ImageID string `json:"image_id,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -464,6 +474,7 @@ type NodeVMsData struct {
StartAt respjson.Field
Status respjson.Field
UpdatedAt respjson.Field
+ Zone respjson.Field
ImageID respjson.Field
ExtraFields map[string]respjson.Field
raw string
diff --git a/node_test.go b/node_test.go
index 88ca793..026a72a 100644
--- a/node_test.go
+++ b/node_test.go
@@ -30,13 +30,14 @@ func TestNodeNewWithOptionalParams(t *testing.T) {
CreateNodesRequest: sfcnodes.CreateNodesRequestParam{
DesiredCount: 1,
MaxPricePerNodeHour: 1000,
- Zone: "hayesvalley",
+ AnyZone: sfcnodes.Bool(false),
CloudInitUserData: sfcnodes.String("aGVsbG8gd29ybGQ="),
EndAt: sfcnodes.Int(0),
ImageID: sfcnodes.String("vmi_1234567890abcdef"),
Names: []string{"cuda-crunch"},
NodeType: sfcnodes.NodeTypeAutoreserved,
StartAt: sfcnodes.Int(1640995200),
+ Zone: sfcnodes.String("hayesvalley"),
},
})
if err != nil {
From e40a3debee22efa7015e5230d14374245af79b1f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 04:29:23 +0000
Subject: [PATCH 02/52] chore(internal): codegen related update
---
internal/paramutil/sentinel.go | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 internal/paramutil/sentinel.go
diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go
new file mode 100644
index 0000000..ba8eaee
--- /dev/null
+++ b/internal/paramutil/sentinel.go
@@ -0,0 +1,31 @@
+package paramutil
+
+import (
+ "github.com/sfcompute/nodes-go/internal/encoding/json/sentinel"
+)
+
+// NullPtr returns a pointer to the zero value of the type T.
+// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
+//
+// It is unspecified behavior to mutate the value pointed to by the returned pointer.
+func NullPtr[T any]() *T {
+ return sentinel.NullPtr[T]()
+}
+
+// IsNullPtr returns true if the pointer was created by [NullPtr].
+func IsNullPtr[T any](ptr *T) bool {
+ return sentinel.IsNullPtr(ptr)
+}
+
+// NullSlice returns a non-nil slice with a length of 0.
+// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
+//
+// It is undefined behavior to mutate the slice returned by [NullSlice].
+func NullSlice[T any]() []T {
+ return sentinel.NullSlice[T]()
+}
+
+// IsNullSlice returns true if the slice was created by [NullSlice].
+func IsNullSlice[T any](slice []T) bool {
+ return sentinel.IsNullSlice(slice)
+}
From 9e83189fd37d851e8441c313c738656a72760483 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 04:30:09 +0000
Subject: [PATCH 03/52] chore: elide duplicate aliases
---
internal/paramutil/sentinel.go | 31 -------------------------------
1 file changed, 31 deletions(-)
delete mode 100644 internal/paramutil/sentinel.go
diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go
deleted file mode 100644
index ba8eaee..0000000
--- a/internal/paramutil/sentinel.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package paramutil
-
-import (
- "github.com/sfcompute/nodes-go/internal/encoding/json/sentinel"
-)
-
-// NullPtr returns a pointer to the zero value of the type T.
-// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
-//
-// It is unspecified behavior to mutate the value pointed to by the returned pointer.
-func NullPtr[T any]() *T {
- return sentinel.NullPtr[T]()
-}
-
-// IsNullPtr returns true if the pointer was created by [NullPtr].
-func IsNullPtr[T any](ptr *T) bool {
- return sentinel.IsNullPtr(ptr)
-}
-
-// NullSlice returns a non-nil slice with a length of 0.
-// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
-//
-// It is undefined behavior to mutate the slice returned by [NullSlice].
-func NullSlice[T any]() []T {
- return sentinel.NullSlice[T]()
-}
-
-// IsNullSlice returns true if the slice was created by [NullSlice].
-func IsNullSlice[T any](slice []T) bool {
- return sentinel.IsNullSlice(slice)
-}
From 2eeb64be8909979b8cb3524a077cb764c85a1f21 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 04:30:46 +0000
Subject: [PATCH 04/52] fix(mcp): correct code tool API endpoint
---
internal/paramutil/sentinel.go | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 internal/paramutil/sentinel.go
diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go
new file mode 100644
index 0000000..ba8eaee
--- /dev/null
+++ b/internal/paramutil/sentinel.go
@@ -0,0 +1,31 @@
+package paramutil
+
+import (
+ "github.com/sfcompute/nodes-go/internal/encoding/json/sentinel"
+)
+
+// NullPtr returns a pointer to the zero value of the type T.
+// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
+//
+// It is unspecified behavior to mutate the value pointed to by the returned pointer.
+func NullPtr[T any]() *T {
+ return sentinel.NullPtr[T]()
+}
+
+// IsNullPtr returns true if the pointer was created by [NullPtr].
+func IsNullPtr[T any](ptr *T) bool {
+ return sentinel.IsNullPtr(ptr)
+}
+
+// NullSlice returns a non-nil slice with a length of 0.
+// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
+//
+// It is undefined behavior to mutate the slice returned by [NullSlice].
+func NullSlice[T any]() []T {
+ return sentinel.NullSlice[T]()
+}
+
+// IsNullSlice returns true if the slice was created by [NullSlice].
+func IsNullSlice[T any](slice []T) bool {
+ return sentinel.IsNullSlice(slice)
+}
From f221c7569b746c43bd46c4ab3c1615b30fc0c05c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 04:31:27 +0000
Subject: [PATCH 05/52] fix: rename param to avoid collision
---
internal/paramutil/sentinel.go | 31 -------------------------------
1 file changed, 31 deletions(-)
delete mode 100644 internal/paramutil/sentinel.go
diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go
deleted file mode 100644
index ba8eaee..0000000
--- a/internal/paramutil/sentinel.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package paramutil
-
-import (
- "github.com/sfcompute/nodes-go/internal/encoding/json/sentinel"
-)
-
-// NullPtr returns a pointer to the zero value of the type T.
-// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
-//
-// It is unspecified behavior to mutate the value pointed to by the returned pointer.
-func NullPtr[T any]() *T {
- return sentinel.NullPtr[T]()
-}
-
-// IsNullPtr returns true if the pointer was created by [NullPtr].
-func IsNullPtr[T any](ptr *T) bool {
- return sentinel.IsNullPtr(ptr)
-}
-
-// NullSlice returns a non-nil slice with a length of 0.
-// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null.
-//
-// It is undefined behavior to mutate the slice returned by [NullSlice].
-func NullSlice[T any]() []T {
- return sentinel.NullSlice[T]()
-}
-
-// IsNullSlice returns true if the slice was created by [NullSlice].
-func IsNullSlice[T any](slice []T) bool {
- return sentinel.IsNullSlice(slice)
-}
From 0af4350619954ebd42478fe2d59dc4f17dcd8642 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 8 Dec 2025 07:21:45 +0000
Subject: [PATCH 06/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index a4da285..c0212fd 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-d630bbe1a2a6a2f640d4391fcde47e5d1e260ce7773132fbacaa2a1dad692f93.yml
+openapi_spec_hash: 0e328dfa7e269debc666a0d4f7fb349e
config_hash: a187153315a646ecf95709ee4a223df5
From 59ae9e5d89b240e99acc2ac64cc889be1a4d7665 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 9 Dec 2025 02:22:06 +0000
Subject: [PATCH 07/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c0212fd..4184093 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-d630bbe1a2a6a2f640d4391fcde47e5d1e260ce7773132fbacaa2a1dad692f93.yml
-openapi_spec_hash: 0e328dfa7e269debc666a0d4f7fb349e
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-00ce4132845e0412fe1cc0c1f490124468a13306eee4fa6110265cb74b0e44a9.yml
+openapi_spec_hash: e04281f57e0fe175d6614d0440a1e81f
config_hash: a187153315a646ecf95709ee4a223df5
From bf75f99a26c353742229dabb561684545d0835c7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 12 Dec 2025 04:39:29 +0000
Subject: [PATCH 08/52] feat(encoder): support bracket encoding form-data
object members
---
internal/apiform/encoder.go | 80 +++++++++++++++++++----------------
internal/apiform/form_test.go | 51 +++++++++++++++++++++-
2 files changed, 94 insertions(+), 37 deletions(-)
diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go
index 8fd59d9..cd7b726 100644
--- a/internal/apiform/encoder.go
+++ b/internal/apiform/encoder.go
@@ -60,6 +60,7 @@ type encoderField struct {
type encoderEntry struct {
reflect.Type
dateFormat string
+ arrayFmt string
root bool
}
@@ -77,6 +78,7 @@ func (e *encoder) typeEncoder(t reflect.Type) encoderFunc {
entry := encoderEntry{
Type: t,
dateFormat: e.dateFormat,
+ arrayFmt: e.arrayFmt,
root: e.root,
}
@@ -178,34 +180,9 @@ func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc {
}
}
-func arrayKeyEncoder(arrayFmt string) func(string, int) string {
- var keyFn func(string, int) string
- switch arrayFmt {
- case "comma", "repeat":
- keyFn = func(k string, _ int) string { return k }
- case "brackets":
- keyFn = func(key string, _ int) string { return key + "[]" }
- case "indices:dots":
- keyFn = func(k string, i int) string {
- if k == "" {
- return strconv.Itoa(i)
- }
- return k + "." + strconv.Itoa(i)
- }
- case "indices:brackets":
- keyFn = func(k string, i int) string {
- if k == "" {
- return strconv.Itoa(i)
- }
- return k + "[" + strconv.Itoa(i) + "]"
- }
- }
- return keyFn
-}
-
func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc {
itemEncoder := e.typeEncoder(t.Elem())
- keyFn := arrayKeyEncoder(e.arrayFmt)
+ keyFn := e.arrayKeyEncoder()
return func(key string, v reflect.Value, writer *multipart.Writer) error {
if keyFn == nil {
return fmt.Errorf("apiform: unsupported array format")
@@ -303,13 +280,10 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
})
return func(key string, value reflect.Value, writer *multipart.Writer) error {
- if key != "" {
- key = key + "."
- }
-
+ keyFn := e.objKeyEncoder(key)
for _, ef := range encoderFields {
field := value.FieldByIndex(ef.idx)
- err := ef.fn(key+ef.tag.name, field, writer)
+ err := ef.fn(keyFn(ef.tag.name), field, writer)
if err != nil {
return err
}
@@ -405,6 +379,43 @@ func (e *encoder) newReaderTypeEncoder() encoderFunc {
}
}
+func (e encoder) arrayKeyEncoder() func(string, int) string {
+ var keyFn func(string, int) string
+ switch e.arrayFmt {
+ case "comma", "repeat":
+ keyFn = func(k string, _ int) string { return k }
+ case "brackets":
+ keyFn = func(key string, _ int) string { return key + "[]" }
+ case "indices:dots":
+ keyFn = func(k string, i int) string {
+ if k == "" {
+ return strconv.Itoa(i)
+ }
+ return k + "." + strconv.Itoa(i)
+ }
+ case "indices:brackets":
+ keyFn = func(k string, i int) string {
+ if k == "" {
+ return strconv.Itoa(i)
+ }
+ return k + "[" + strconv.Itoa(i) + "]"
+ }
+ }
+ return keyFn
+}
+
+func (e encoder) objKeyEncoder(parent string) func(string) string {
+ if parent == "" {
+ return func(child string) string { return child }
+ }
+ switch e.arrayFmt {
+ case "brackets":
+ return func(child string) string { return parent + "[" + child + "]" }
+ default:
+ return func(child string) string { return parent + "." + child }
+ }
+}
+
// Given a []byte of json (may either be an empty object or an object that already contains entries)
// encode all of the entries in the map to the json byte array.
func (e *encoder) encodeMapEntries(key string, v reflect.Value, writer *multipart.Writer) error {
@@ -413,10 +424,6 @@ func (e *encoder) encodeMapEntries(key string, v reflect.Value, writer *multipar
value reflect.Value
}
- if key != "" {
- key = key + "."
- }
-
pairs := []mapPair{}
iter := v.MapRange()
@@ -434,8 +441,9 @@ func (e *encoder) encodeMapEntries(key string, v reflect.Value, writer *multipar
})
elementEncoder := e.typeEncoder(v.Type().Elem())
+ keyFn := e.objKeyEncoder(key)
for _, p := range pairs {
- err := elementEncoder(key+string(p.key), p.value, writer)
+ err := elementEncoder(keyFn(p.key), p.value, writer)
if err != nil {
return err
}
diff --git a/internal/apiform/form_test.go b/internal/apiform/form_test.go
index 0d05c4a..1874257 100644
--- a/internal/apiform/form_test.go
+++ b/internal/apiform/form_test.go
@@ -123,6 +123,18 @@ type StructUnion struct {
param.APIUnion
}
+type MultipartMarshalerParent struct {
+ Middle MultipartMarshalerMiddleNext `form:"middle"`
+}
+
+type MultipartMarshalerMiddleNext struct {
+ MiddleNext MultipartMarshalerMiddle `form:"middleNext"`
+}
+
+type MultipartMarshalerMiddle struct {
+ Child int `form:"child"`
+}
+
var tests = map[string]struct {
buf string
val any
@@ -366,6 +378,19 @@ true
},
},
},
+ "recursive_struct,brackets": {
+ `--xxx
+Content-Disposition: form-data; name="child[name]"
+
+Alex
+--xxx
+Content-Disposition: form-data; name="name"
+
+Robert
+--xxx--
+`,
+ Recursive{Name: "Robert", Child: &Recursive{Name: "Alex"}},
+ },
"recursive_struct": {
`--xxx
@@ -529,6 +554,30 @@ Content-Disposition: form-data; name="union"
Union: UnionTime(time.Date(2010, 05, 23, 0, 0, 0, 0, time.UTC)),
},
},
+ "deeply-nested-struct,brackets": {
+ `--xxx
+Content-Disposition: form-data; name="middle[middleNext][child]"
+
+10
+--xxx--
+`,
+ MultipartMarshalerParent{
+ Middle: MultipartMarshalerMiddleNext{
+ MiddleNext: MultipartMarshalerMiddle{
+ Child: 10,
+ },
+ },
+ },
+ },
+ "deeply-nested-map,brackets": {
+ `--xxx
+Content-Disposition: form-data; name="middle[middleNext][child]"
+
+10
+--xxx--
+`,
+ map[string]any{"middle": map[string]any{"middleNext": map[string]any{"child": 10}}},
+ },
}
func TestEncode(t *testing.T) {
@@ -553,7 +602,7 @@ func TestEncode(t *testing.T) {
}
raw := buf.Bytes()
if string(raw) != strings.ReplaceAll(test.buf, "\n", "\r\n") {
- t.Errorf("expected %+#v to serialize to '%s' but got '%s'", test.val, test.buf, string(raw))
+ t.Errorf("expected %+#v to serialize to '%s' but got '%s' (with format %s)", test.val, test.buf, string(raw), arrayFmt)
}
})
}
From aa2636805de581a3595d96e7b20de580696393ce Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Dec 2025 03:21:43 +0000
Subject: [PATCH 09/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 4184093..47588b8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-00ce4132845e0412fe1cc0c1f490124468a13306eee4fa6110265cb74b0e44a9.yml
-openapi_spec_hash: e04281f57e0fe175d6614d0440a1e81f
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-ad234e475934741940c514edea2d2cfb9e0576b6f58087bb26a5ca440d818eae.yml
+openapi_spec_hash: 5676172e7f99c37ad7425a4891525c9e
config_hash: a187153315a646ecf95709ee4a223df5
From e16239107a6784fcfbd90cd29e7c24343d83a11f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Dec 2025 06:21:58 +0000
Subject: [PATCH 10/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 47588b8..996b4fa 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-ad234e475934741940c514edea2d2cfb9e0576b6f58087bb26a5ca440d818eae.yml
-openapi_spec_hash: 5676172e7f99c37ad7425a4891525c9e
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-331baedc042497d9185a8161e2697f02086ca49f8bb15e6e8d162c881d493059.yml
+openapi_spec_hash: a37a2df2a9638363141188cdac38ea73
config_hash: a187153315a646ecf95709ee4a223df5
From 61d03bd3c1f7772a74bef48676020df27c371ab1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 18 Dec 2025 06:35:13 +0000
Subject: [PATCH 11/52] fix: skip usage tests that don't work with Prism
---
usage_test.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/usage_test.go b/usage_test.go
index 1117ee4..dc7e012 100644
--- a/usage_test.go
+++ b/usage_test.go
@@ -24,6 +24,7 @@ func TestUsage(t *testing.T) {
option.WithBaseURL(baseURL),
option.WithBearerToken("My Bearer Token"),
)
+ t.Skip("Prism tests are disabled")
listResponseNode, err := client.Nodes.List(context.TODO(), sfcnodes.NodeListParams{})
if err != nil {
t.Fatalf("err should be nil: %s", err.Error())
From e87a5d36d82b6df6fe59de944d341e4aaf8fccfb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 18 Dec 2025 22:21:39 +0000
Subject: [PATCH 12/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 996b4fa..883b0fa 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-331baedc042497d9185a8161e2697f02086ca49f8bb15e6e8d162c881d493059.yml
-openapi_spec_hash: a37a2df2a9638363141188cdac38ea73
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-54af1b82f474ebc6f28e82b3ad603a8fd9c5f9c0ebcc6e72c6d53876126bc432.yml
+openapi_spec_hash: 105d4fa4782b22a506739072d6905df7
config_hash: a187153315a646ecf95709ee4a223df5
From 499e663b659fa00c013ebe3db1e0622b5e2a6a51 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 19 Dec 2025 05:41:34 +0000
Subject: [PATCH 13/52] chore: add float64 to valid types for
RegisterFieldValidator
---
internal/apijson/enum.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/internal/apijson/enum.go b/internal/apijson/enum.go
index 18b218a..5bef11c 100644
--- a/internal/apijson/enum.go
+++ b/internal/apijson/enum.go
@@ -29,7 +29,7 @@ type validatorFunc func(reflect.Value) exactness
var validators sync.Map
var validationRegistry = map[reflect.Type][]validationEntry{}
-func RegisterFieldValidator[T any, V string | bool | int](fieldName string, values ...V) {
+func RegisterFieldValidator[T any, V string | bool | int | float64](fieldName string, values ...V) {
var t T
parentType := reflect.TypeOf(t)
From e871fac7f47970664bf5b4b608ffd83f02342d12 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 19 Dec 2025 09:21:47 +0000
Subject: [PATCH 14/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 883b0fa..1899ae9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-54af1b82f474ebc6f28e82b3ad603a8fd9c5f9c0ebcc6e72c6d53876126bc432.yml
-openapi_spec_hash: 105d4fa4782b22a506739072d6905df7
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-03edf542ab3939ae0c77273542f4f33e07924cc44316260f855e884f42ae9929.yml
+openapi_spec_hash: 52771530706e879f6c58d8f7ede21d1c
config_hash: a187153315a646ecf95709ee4a223df5
From 356e8a03ed9ed0763fb8f2bf8c7fd34616ee2c5a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 19 Dec 2025 23:21:58 +0000
Subject: [PATCH 15/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 1899ae9..a890fcc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-03edf542ab3939ae0c77273542f4f33e07924cc44316260f855e884f42ae9929.yml
-openapi_spec_hash: 52771530706e879f6c58d8f7ede21d1c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-7686e4482b4198d5272206797ea47239ffa1beba6e49f3db5a257e4c7d3f832d.yml
+openapi_spec_hash: 19955ca78c8b6ebca90ab66394aca311
config_hash: a187153315a646ecf95709ee4a223df5
From cd38e66b5e33c393d89e704f974306a8e6e67ac4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 29 Dec 2025 23:21:35 +0000
Subject: [PATCH 16/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index a890fcc..de13433 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-7686e4482b4198d5272206797ea47239ffa1beba6e49f3db5a257e4c7d3f832d.yml
-openapi_spec_hash: 19955ca78c8b6ebca90ab66394aca311
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-4771ae775cb15c3c1ac7cab3904f764898941fbb36dafa644166ade893c9074b.yml
+openapi_spec_hash: 659a535c0ff009b43b1613597c4c3ceb
config_hash: a187153315a646ecf95709ee4a223df5
From 44eb5d0a3f745631aebb3b0d2986a049302131fe Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 6 Jan 2026 05:18:51 +0000
Subject: [PATCH 17/52] chore(internal): codegen related update
---
LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/LICENSE b/LICENSE
index 30db98a..46b2b7e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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.
From 85e84598da4d5d93b421a3b6423324237b8d920a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 7 Jan 2026 22:21:23 +0000
Subject: [PATCH 18/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index de13433..d3f9adc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-4771ae775cb15c3c1ac7cab3904f764898941fbb36dafa644166ade893c9074b.yml
-openapi_spec_hash: 659a535c0ff009b43b1613597c4c3ceb
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-88e997c058061efbde49909c158c04e313ae55ad4dba3abc1329ea1643061742.yml
+openapi_spec_hash: 92c64a2de9bf5adc7a9bf624e9258311
config_hash: a187153315a646ecf95709ee4a223df5
From 56ca25e3a3d0cb929434d351360502607100ca5a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 8 Jan 2026 00:21:31 +0000
Subject: [PATCH 19/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d3f9adc..dedfea1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-88e997c058061efbde49909c158c04e313ae55ad4dba3abc1329ea1643061742.yml
-openapi_spec_hash: 92c64a2de9bf5adc7a9bf624e9258311
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-21dd022674a7acf0a6e59f9a31bdf67c60871a90a722af805e1bf80d298e2d54.yml
+openapi_spec_hash: e2f1054136094de246e281ca57277ce9
config_hash: a187153315a646ecf95709ee4a223df5
From a6b5b3e5b28ed8f498c1f4361d4d5dd648f5bd30 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 15 Jan 2026 04:21:32 +0000
Subject: [PATCH 20/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index dedfea1..f9e8bc0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-21dd022674a7acf0a6e59f9a31bdf67c60871a90a722af805e1bf80d298e2d54.yml
-openapi_spec_hash: e2f1054136094de246e281ca57277ce9
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-177125ec6e8076cee5d7a6bdd21e642b65741e7c037a1250e25e1ec93f05087d.yml
+openapi_spec_hash: b3c26f642a7b7fc1d65f05dc4470a856
config_hash: a187153315a646ecf95709ee4a223df5
From a36519dbacd50481e4e9d39f52ebf295f54ef7ac Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 15 Jan 2026 23:21:37 +0000
Subject: [PATCH 21/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index f9e8bc0..58710f6 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-177125ec6e8076cee5d7a6bdd21e642b65741e7c037a1250e25e1ec93f05087d.yml
-openapi_spec_hash: b3c26f642a7b7fc1d65f05dc4470a856
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-60bc3e1c43c0c297e5c78335fb472cf5ec6dd72f2125c4543d61e1b80cfd5f27.yml
+openapi_spec_hash: 8fe4d4d71aa3413725688f88cbe3376f
config_hash: a187153315a646ecf95709ee4a223df5
From c853455bd8e0c977606bc29049cfc84b2caea449 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 17 Jan 2026 05:50:37 +0000
Subject: [PATCH 22/52] chore(internal): update `actions/checkout` version
---
.github/workflows/ci.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 70f7f3f..d36dd9f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,7 +20,7 @@ jobs:
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Setup go
uses: actions/setup-go@v5
@@ -35,7 +35,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/sfc-nodes-go' && '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: Setup go
uses: actions/setup-go@v5
From 6dd1eadf389b5a9adf98195f624f0bba54f0b686 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 17 Jan 2026 05:56:15 +0000
Subject: [PATCH 23/52] fix(docs): add missing pointer prefix to api.md return
types
---
api.md | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/api.md b/api.md
index a45a8de..1348708 100644
--- a/api.md
+++ b/api.md
@@ -7,8 +7,8 @@ Response Types:
Methods:
-- client.VMs.Logs(ctx context.Context, query sfcnodes.VMLogsParams) (sfcnodes.VMLogsResponse, error)
-- client.VMs.SSH(ctx context.Context, query sfcnodes.VMSSHParams) (sfcnodes.VmsshResponse, error)
+- client.VMs.Logs(ctx context.Context, query sfcnodes.VMLogsParams) (\*sfcnodes.VMLogsResponse, error)
+- client.VMs.SSH(ctx context.Context, query sfcnodes.VMSSHParams) (\*sfcnodes.VmsshResponse, error)
## Script
@@ -24,8 +24,8 @@ Response Types:
Methods:
-- client.VMs.Script.New(ctx context.Context, body sfcnodes.VMScriptNewParams) (sfcnodes.VMScriptNewResponse, error)
-- client.VMs.Script.Get(ctx context.Context) (sfcnodes.VMScriptGetResponse, error)
+- client.VMs.Script.New(ctx context.Context, body sfcnodes.VMScriptNewParams) (\*sfcnodes.VMScriptNewResponse, error)
+- client.VMs.Script.Get(ctx context.Context) (\*sfcnodes.VMScriptGetResponse, error)
## Images
@@ -36,8 +36,8 @@ Response Types:
Methods:
-- client.VMs.Images.List(ctx context.Context) (sfcnodes.VMImageListResponse, error)
-- client.VMs.Images.Get(ctx context.Context, imageID string) (sfcnodes.VMImageGetResponse, error)
+- client.VMs.Images.List(ctx context.Context) (\*sfcnodes.VMImageListResponse, error)
+- client.VMs.Images.Get(ctx context.Context, imageID string) (\*sfcnodes.VMImageGetResponse, error)
# Nodes
@@ -57,13 +57,13 @@ Response Types:
Methods:
-- client.Nodes.New(ctx context.Context, body sfcnodes.NodeNewParams) (sfcnodes.ListResponseNode, error)
-- client.Nodes.List(ctx context.Context, query sfcnodes.NodeListParams) (sfcnodes.ListResponseNode, error)
+- client.Nodes.New(ctx context.Context, body sfcnodes.NodeNewParams) (\*sfcnodes.ListResponseNode, error)
+- client.Nodes.List(ctx context.Context, query sfcnodes.NodeListParams) (\*sfcnodes.ListResponseNode, error)
- client.Nodes.Delete(ctx context.Context, id string) error
-- client.Nodes.Extend(ctx context.Context, id string, body sfcnodes.NodeExtendParams) (sfcnodes.Node, error)
-- client.Nodes.Get(ctx context.Context, id string) (sfcnodes.Node, error)
-- client.Nodes.Redeploy(ctx context.Context, id string, body sfcnodes.NodeRedeployParams) (sfcnodes.Node, error)
-- client.Nodes.Release(ctx context.Context, id string) (sfcnodes.Node, error)
+- client.Nodes.Extend(ctx context.Context, id string, body sfcnodes.NodeExtendParams) (\*sfcnodes.Node, error)
+- client.Nodes.Get(ctx context.Context, id string) (\*sfcnodes.Node, error)
+- client.Nodes.Redeploy(ctx context.Context, id string, body sfcnodes.NodeRedeployParams) (\*sfcnodes.Node, error)
+- client.Nodes.Release(ctx context.Context, id string) (\*sfcnodes.Node, error)
# Zones
@@ -74,5 +74,5 @@ Response Types:
Methods:
-- client.Zones.List(ctx context.Context) (sfcnodes.ZoneListResponse, error)
-- client.Zones.Get(ctx context.Context, id string) (sfcnodes.ZoneGetResponse, error)
+- client.Zones.List(ctx context.Context) (\*sfcnodes.ZoneListResponse, error)
+- client.Zones.Get(ctx context.Context, id string) (\*sfcnodes.ZoneGetResponse, error)
From 434f76ce00f74783c1d53d533a61791cbb9b914d Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 20 Jan 2026 01:21:39 +0000
Subject: [PATCH 24/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 58710f6..0e52799 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-60bc3e1c43c0c297e5c78335fb472cf5ec6dd72f2125c4543d61e1b80cfd5f27.yml
-openapi_spec_hash: 8fe4d4d71aa3413725688f88cbe3376f
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-438ab8dcc9071da5a91824fb194fac4b51ee700e72a1ca0954f20e5080c8aa67.yml
+openapi_spec_hash: 94c5bad5fa92824b5552b6935cf51a8b
config_hash: a187153315a646ecf95709ee4a223df5
From e3b0cdc97a49eac1fa59e294e36eaae9ce86b639 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 20 Jan 2026 02:21:30 +0000
Subject: [PATCH 25/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0e52799..a4304a2 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-438ab8dcc9071da5a91824fb194fac4b51ee700e72a1ca0954f20e5080c8aa67.yml
-openapi_spec_hash: 94c5bad5fa92824b5552b6935cf51a8b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-cb712e28ea8e76d4fafc38d05d04c3aa18f19d09a35a91490681e28386540816.yml
+openapi_spec_hash: 38aff9c16f3a9feb27821aabc9908c93
config_hash: a187153315a646ecf95709ee4a223df5
From 6a064fdc947dd668159e8643e7cab0689254d4c6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 24 Jan 2026 01:21:20 +0000
Subject: [PATCH 26/52] feat(api): api update
---
.stats.yml | 4 ++--
node.go | 2 ++
node_test.go | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index a4304a2..4b81dcb 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-cb712e28ea8e76d4fafc38d05d04c3aa18f19d09a35a91490681e28386540816.yml
-openapi_spec_hash: 38aff9c16f3a9feb27821aabc9908c93
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-efc2aea65f9bfd1b1f14c95bd0b75ee8926664657def736214ba5c772cdeb8d5.yml
+openapi_spec_hash: 090908bae037a26c78b4fcff56698e01
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/node.go b/node.go
index e37d18a..606db63 100644
--- a/node.go
+++ b/node.go
@@ -138,6 +138,8 @@ type CreateNodesRequestParam struct {
// User script to be executed during the VM's boot process Data should be base64
// encoded
CloudInitUserData param.Opt[string] `json:"cloud_init_user_data,omitzero" format:"byte"`
+ // (Optional) If set, enables forwarding to the VM on port 443.
+ Forward443 param.Opt[bool] `json:"forward_443,omitzero"`
// Custom image ID to use for the VM instances
ImageID param.Opt[string] `json:"image_id,omitzero"`
// Start time as Unix timestamp in seconds Optional for reserved nodes. If not
diff --git a/node_test.go b/node_test.go
index 026a72a..c56eae1 100644
--- a/node_test.go
+++ b/node_test.go
@@ -33,6 +33,7 @@ func TestNodeNewWithOptionalParams(t *testing.T) {
AnyZone: sfcnodes.Bool(false),
CloudInitUserData: sfcnodes.String("aGVsbG8gd29ybGQ="),
EndAt: sfcnodes.Int(0),
+ Forward443: sfcnodes.Bool(false),
ImageID: sfcnodes.String("vmi_1234567890abcdef"),
Names: []string{"cuda-crunch"},
NodeType: sfcnodes.NodeTypeAutoreserved,
From a7293f32d7d9f676d53e6200ca7bd82f603029bb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 24 Jan 2026 05:16:18 +0000
Subject: [PATCH 27/52] feat(client): add a convenient param.SetJSON helper
---
packages/param/param.go | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/packages/param/param.go b/packages/param/param.go
index 500a3f5..684d7e9 100644
--- a/packages/param/param.go
+++ b/packages/param/param.go
@@ -41,6 +41,19 @@ func Override[T ParamStruct, PtrT InferPtr[T]](v any) T {
return *pt
}
+// SetJSON configures a param struct to serialize with the provided raw JSON data.
+// Use this when you have existing JSON that you want to send as request parameters.
+//
+// var req example.NewUserParams
+// var rawJSON = []byte(`{"name": "...", "age": 40}`)
+// param.SetJSON(rawJSON, &req)
+// res, err := client.Users.New(ctx, req)
+//
+// Note: The struct's existing fields will be ignored; only the provided JSON is serialized.
+func SetJSON(rawJSON []byte, ptr anyParamStruct) {
+ ptr.setMetadata(json.RawMessage(rawJSON))
+}
+
// IsOmitted returns true if v is the zero value of its type.
//
// If IsOmitted is true, and the field uses a `json:"...,omitzero"` tag,
@@ -91,6 +104,11 @@ type ParamStruct interface {
extraFields() map[string]any
}
+// A pointer to ParamStruct
+type anyParamStruct interface {
+ setMetadata(any)
+}
+
// This is an implementation detail and should never be explicitly set.
type InferPtr[T ParamStruct] interface {
setMetadata(any)
From a4e5181e44815a66b891ecd41790c9dab76c0375 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 24 Jan 2026 05:21:43 +0000
Subject: [PATCH 28/52] feat(api): api update
---
.stats.yml | 4 ++--
zone.go | 6 ++++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 4b81dcb..4d80d48 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-efc2aea65f9bfd1b1f14c95bd0b75ee8926664657def736214ba5c772cdeb8d5.yml
-openapi_spec_hash: 090908bae037a26c78b4fcff56698e01
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-c2b237165b63106e4152d9792d62b7e276c771706c33e65f2ebddafdbc97e3d2.yml
+openapi_spec_hash: cee63411975cbf87322dfaa8a789f57e
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/zone.go b/zone.go
index b294733..c71bc1c 100644
--- a/zone.go
+++ b/zone.go
@@ -86,6 +86,8 @@ type ZoneListResponseData struct {
Object string `json:"object,required"`
// Any of "NorthAmerica", "AsiaPacific", "EuropeMiddleEastAfrica".
Region string `json:"region,required"`
+ // User-facing zone name (e.g., "Hayes Valley", "Land's End")
+ DisplayName string `json:"display_name,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
AvailableCapacity respjson.Field
@@ -95,6 +97,7 @@ type ZoneListResponseData struct {
Name respjson.Field
Object respjson.Field
Region respjson.Field
+ DisplayName respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
@@ -143,6 +146,8 @@ type ZoneGetResponse struct {
Object string `json:"object,required"`
// Any of "NorthAmerica", "AsiaPacific", "EuropeMiddleEastAfrica".
Region ZoneGetResponseRegion `json:"region,required"`
+ // User-facing zone name (e.g., "Hayes Valley", "Land's End")
+ DisplayName string `json:"display_name,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
AvailableCapacity respjson.Field
@@ -152,6 +157,7 @@ type ZoneGetResponse struct {
Name respjson.Field
Object respjson.Field
Region respjson.Field
+ DisplayName respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
From c034a8932c90e34946e29a73789327db46232754 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 26 Jan 2026 03:21:23 +0000
Subject: [PATCH 29/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 4d80d48..d4faf63 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-c2b237165b63106e4152d9792d62b7e276c771706c33e65f2ebddafdbc97e3d2.yml
-openapi_spec_hash: cee63411975cbf87322dfaa8a789f57e
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-eedf47c34564d45f3dc1747e1490f944eed199e4145a1bd3dee4d2f187215414.yml
+openapi_spec_hash: d58d902254134d1dc56df10cf4659739
config_hash: a187153315a646ecf95709ee4a223df5
From b74fefc7042e3f4077c62322496ce76e5431e6e7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 26 Jan 2026 17:21:41 +0000
Subject: [PATCH 30/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d4faf63..1fdabb4 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-eedf47c34564d45f3dc1747e1490f944eed199e4145a1bd3dee4d2f187215414.yml
-openapi_spec_hash: d58d902254134d1dc56df10cf4659739
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-9ea76dd1f381c8a16c7c2e41e041df5f1d73fec8a5deed1a2bcd791aa0fa4dc4.yml
+openapi_spec_hash: 27c3f4754e4d254297ee3611d84c1295
config_hash: a187153315a646ecf95709ee4a223df5
From a3aa37bd7a2eaeaf6bc8d3bcd04bc1175ebac657 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 27 Jan 2026 05:21:25 +0000
Subject: [PATCH 31/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 1fdabb4..3556856 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-9ea76dd1f381c8a16c7c2e41e041df5f1d73fec8a5deed1a2bcd791aa0fa4dc4.yml
-openapi_spec_hash: 27c3f4754e4d254297ee3611d84c1295
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-d6ae1b3b2970b54a51f55a61c6a93af6396a1392ec61c567635832759d1e3c2e.yml
+openapi_spec_hash: 28daa6f66bc19c40c9904a3938fcb534
config_hash: a187153315a646ecf95709ee4a223df5
From 365b2912e639a8195b9a7d2d444b15d74aac92fd Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 28 Jan 2026 01:21:33 +0000
Subject: [PATCH 32/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3556856..528b847 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-d6ae1b3b2970b54a51f55a61c6a93af6396a1392ec61c567635832759d1e3c2e.yml
-openapi_spec_hash: 28daa6f66bc19c40c9904a3938fcb534
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-cd480aef9e1f9983ad0699819f40047608d63b3ef41f1bd76c932a3f862e60e9.yml
+openapi_spec_hash: 3ac3c63301d691f8fa3f4b652c556382
config_hash: a187153315a646ecf95709ee4a223df5
From 1b12266bc893fed6e969c003748e2297eedacb85 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 29 Jan 2026 23:21:37 +0000
Subject: [PATCH 33/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 528b847..e5f0db8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-cd480aef9e1f9983ad0699819f40047608d63b3ef41f1bd76c932a3f862e60e9.yml
-openapi_spec_hash: 3ac3c63301d691f8fa3f4b652c556382
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-7ac73b841fb339ec72ccd36421215fe588302224c96cb649af3908312d325672.yml
+openapi_spec_hash: 30268f26ac5bcc646c63b72d6717d28d
config_hash: a187153315a646ecf95709ee4a223df5
From f9747fcc26a0ca23bfd38f01185afae431421f12 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 30 Jan 2026 02:21:28 +0000
Subject: [PATCH 34/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e5f0db8..175dfdc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-7ac73b841fb339ec72ccd36421215fe588302224c96cb649af3908312d325672.yml
-openapi_spec_hash: 30268f26ac5bcc646c63b72d6717d28d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-bf763dc6630a118b2d271097b0c5e4a304a74dbb5720680a69b0996472c19de3.yml
+openapi_spec_hash: 426c41ad8cf139fccd658acae270899f
config_hash: a187153315a646ecf95709ee4a223df5
From 3068ae6937f3d6f6f5b36f8ac7c7e318866c3ce1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 31 Jan 2026 01:21:31 +0000
Subject: [PATCH 35/52] feat(api): api update
---
.stats.yml | 4 ++--
node_test.go | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 175dfdc..3bb1e93 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-bf763dc6630a118b2d271097b0c5e4a304a74dbb5720680a69b0996472c19de3.yml
-openapi_spec_hash: 426c41ad8cf139fccd658acae270899f
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-696f9a786cce7ce531b92168f355b6ba9285f56229de2946f51a7066cb2110f4.yml
+openapi_spec_hash: 8c944dde402324e52e1338ba1bb0cec3
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/node_test.go b/node_test.go
index c56eae1..31ea651 100644
--- a/node_test.go
+++ b/node_test.go
@@ -29,7 +29,7 @@ func TestNodeNewWithOptionalParams(t *testing.T) {
_, err := client.Nodes.New(context.TODO(), sfcnodes.NodeNewParams{
CreateNodesRequest: sfcnodes.CreateNodesRequestParam{
DesiredCount: 1,
- MaxPricePerNodeHour: 1000,
+ MaxPricePerNodeHour: 1600,
AnyZone: sfcnodes.Bool(false),
CloudInitUserData: sfcnodes.String("aGVsbG8gd29ybGQ="),
EndAt: sfcnodes.Int(0),
From f77e6d07e261819f07b68b9241218f42a0ab36a1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 3 Feb 2026 01:21:29 +0000
Subject: [PATCH 36/52] feat(api): api update
---
.stats.yml | 4 ++--
zone.go | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3bb1e93..d97134a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-696f9a786cce7ce531b92168f355b6ba9285f56229de2946f51a7066cb2110f4.yml
-openapi_spec_hash: 8c944dde402324e52e1338ba1bb0cec3
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-6a9bc97c42098f5e188671fef7ce59bef927cdc2ef90db317c91190654348740.yml
+openapi_spec_hash: 91e201e9e23c9883aeeed588eb4bd180
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/zone.go b/zone.go
index c71bc1c..553b56b 100644
--- a/zone.go
+++ b/zone.go
@@ -86,7 +86,7 @@ type ZoneListResponseData struct {
Object string `json:"object,required"`
// Any of "NorthAmerica", "AsiaPacific", "EuropeMiddleEastAfrica".
Region string `json:"region,required"`
- // User-facing zone name (e.g., "Hayes Valley", "Land's End")
+ // User-facing zone name (e.g., "Hayes Valley", "Lands End")
DisplayName string `json:"display_name,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -146,7 +146,7 @@ type ZoneGetResponse struct {
Object string `json:"object,required"`
// Any of "NorthAmerica", "AsiaPacific", "EuropeMiddleEastAfrica".
Region ZoneGetResponseRegion `json:"region,required"`
- // User-facing zone name (e.g., "Hayes Valley", "Land's End")
+ // User-facing zone name (e.g., "Hayes Valley", "Lands End")
DisplayName string `json:"display_name,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
From afa8e35b48706ac111a768c9a7a81c59aa1602b0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 6 Feb 2026 20:21:09 +0000
Subject: [PATCH 37/52] feat(api): api update
---
.stats.yml | 4 ++--
vmimage.go | 26 +++++++++-----------------
zone.go | 4 ++--
3 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d97134a..2fff16c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-6a9bc97c42098f5e188671fef7ce59bef927cdc2ef90db317c91190654348740.yml
-openapi_spec_hash: 91e201e9e23c9883aeeed588eb4bd180
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-3065e016d1993efc092a1672ce6fd4cd778c14d87eac0a00d9b1ed6e0fd16e6f.yml
+openapi_spec_hash: af7e135efe0cd96c31dd4310697295fe
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/vmimage.go b/vmimage.go
index 172d260..dc4ceb2 100644
--- a/vmimage.go
+++ b/vmimage.go
@@ -54,16 +54,13 @@ func (r *VMImageService) Get(ctx context.Context, imageID string, opts ...option
return
}
-// Response body for listing images
type VMImageListResponse struct {
- Data []VMImageListResponseData `json:"data,required"`
- HasMore bool `json:"has_more,required"`
+ Data []VMImageListResponseData `json:"data,required"`
// Any of "list".
Object VMImageListResponseObject `json:"object,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Data respjson.Field
- HasMore respjson.Field
Object respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -76,27 +73,22 @@ func (r *VMImageListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Response body for individual image info (used in lists)
type VMImageListResponseData struct {
- // Creation timestamp as Unix timestamp in seconds
- CreatedAt int64 `json:"created_at,required"`
- // The image ID
- ImageID string `json:"image_id,required"`
- // Client given name of the image. Must be unique per account.
- Name string `json:"name,required"`
- // Any of "image".
- Object string `json:"object,required"`
- // Upload status of the image
+ ID string `json:"id,required"`
+ // Unix timestamp in seconds since epoch
+ CreatedAt int64 `json:"created_at,required"`
+ Name string `json:"name,required"`
UploadStatus string `json:"upload_status,required"`
- // SHA256 hash of the image file for integrity verification
+ // Any of "image".
+ Object string `json:"object"`
Sha256Hash string `json:"sha256_hash,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
+ ID respjson.Field
CreatedAt respjson.Field
- ImageID respjson.Field
Name respjson.Field
- Object respjson.Field
UploadStatus respjson.Field
+ Object respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
raw string
diff --git a/zone.go b/zone.go
index 553b56b..c71bc1c 100644
--- a/zone.go
+++ b/zone.go
@@ -86,7 +86,7 @@ type ZoneListResponseData struct {
Object string `json:"object,required"`
// Any of "NorthAmerica", "AsiaPacific", "EuropeMiddleEastAfrica".
Region string `json:"region,required"`
- // User-facing zone name (e.g., "Hayes Valley", "Lands End")
+ // User-facing zone name (e.g., "Hayes Valley", "Land's End")
DisplayName string `json:"display_name,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -146,7 +146,7 @@ type ZoneGetResponse struct {
Object string `json:"object,required"`
// Any of "NorthAmerica", "AsiaPacific", "EuropeMiddleEastAfrica".
Region ZoneGetResponseRegion `json:"region,required"`
- // User-facing zone name (e.g., "Hayes Valley", "Lands End")
+ // User-facing zone name (e.g., "Hayes Valley", "Land's End")
DisplayName string `json:"display_name,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
From 1f23c5165da616f92243aa0b2d502a52ac856e12 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 6 Feb 2026 23:21:02 +0000
Subject: [PATCH 38/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 2fff16c..e0dce91 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-3065e016d1993efc092a1672ce6fd4cd778c14d87eac0a00d9b1ed6e0fd16e6f.yml
-openapi_spec_hash: af7e135efe0cd96c31dd4310697295fe
+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
From 3c1d05a679cf22aa13b3d4b16ed55d4eeb9e655b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 9 Feb 2026 19:20:53 +0000
Subject: [PATCH 39/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e0dce91..40de438 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-d5ffc2bd6330b6807eef6499bc998fec3a4fecadbccb22e11a362dd9d4a0a2ad.yml
-openapi_spec_hash: b7dff8adf3ec3fb0abd7e152cc6264b2
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-d74f9233a79f62c0498c9c83e93aee95cfa09435aa19934b1095a62a98e9204a.yml
+openapi_spec_hash: 8861cb5098fb473cc52774d5c95e40a1
config_hash: a187153315a646ecf95709ee4a223df5
From 894995db7b4a6347ef91fed5db242fbb14df34ef Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 10 Feb 2026 04:18:47 +0000
Subject: [PATCH 40/52] feat(api): api update
---
.stats.yml | 4 ++--
vmimage.go | 41 ++++++++++++++++-------------------------
2 files changed, 18 insertions(+), 27 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 40de438..49a9267 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-d74f9233a79f62c0498c9c83e93aee95cfa09435aa19934b1095a62a98e9204a.yml
-openapi_spec_hash: 8861cb5098fb473cc52774d5c95e40a1
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-e161bba8bfdad8ec58f1927fbe39c96004d03ab9b4c501bb210c6fce9178d539.yml
+openapi_spec_hash: 3c0dee5cd2aa3d2756ffa76feea57292
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/vmimage.go b/vmimage.go
index dc4ceb2..81aac95 100644
--- a/vmimage.go
+++ b/vmimage.go
@@ -55,13 +55,18 @@ func (r *VMImageService) Get(ctx context.Context, imageID string, opts ...option
}
type VMImageListResponse struct {
- Data []VMImageListResponseData `json:"data,required"`
+ Data []VMImageListResponseData `json:"data,required"`
+ HasMore bool `json:"has_more,required"`
// Any of "list".
Object VMImageListResponseObject `json:"object,required"`
+ // Opaque cursor for pagination. Pass as `starting_after` to get the next page.
+ Cursor string `json:"cursor,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Data respjson.Field
+ HasMore respjson.Field
Object respjson.Field
+ Cursor respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
@@ -74,10 +79,15 @@ func (r *VMImageListResponse) UnmarshalJSON(data []byte) error {
}
type VMImageListResponseData struct {
+ // Generated ID with format 'image\_[0-9a-zA-Z]+' used for referencing a ImageId
+ // resource.
ID string `json:"id,required"`
// Unix timestamp in seconds since epoch
- CreatedAt int64 `json:"created_at,required"`
- Name string `json:"name,required"`
+ CreatedAt int64 `json:"created_at,required"`
+ // A validated resource name. Must start with alphanumeric, followed by
+ // alphanumeric, '.', '\_', or '-'. Max 255 characters.
+ Name string `json:"name,required"`
+ // Any of "started", "uploading", "completed", "failed".
UploadStatus string `json:"upload_status,required"`
// Any of "image".
Object string `json:"object"`
@@ -107,29 +117,16 @@ const (
VMImageListResponseObjectList VMImageListResponseObject = "list"
)
-// Response body for image download presigned URL generation
type VMImageGetResponse struct {
- // The presigned URL that can be used to download the image
DownloadURL string `json:"download_url,required"`
- // Timestamp when the presigned URL expires (RFC 3339 format)
- ExpiresAt string `json:"expires_at,required"`
- // The image ID
- ImageID string `json:"image_id,required"`
- // Human readable name of the image. Must be unique per account.
- Name string `json:"name,required"`
- // Any of "image".
- Object VMImageGetResponseObject `json:"object,required"`
- // Size of the image file in bytes
- ObjectSize int64 `json:"object_size,required"`
- // SHA256 hash of the image file for integrity verification
+ // Unix timestamp in seconds since epoch
+ ExpiresAt int64 `json:"expires_at,required"`
+ ObjectSize int64 `json:"object_size,required"`
Sha256Hash string `json:"sha256_hash,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
DownloadURL respjson.Field
ExpiresAt respjson.Field
- ImageID respjson.Field
- Name respjson.Field
- Object respjson.Field
ObjectSize respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
@@ -142,9 +139,3 @@ func (r VMImageGetResponse) RawJSON() string { return r.JSON.raw }
func (r *VMImageGetResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-
-type VMImageGetResponseObject string
-
-const (
- VMImageGetResponseObjectImage VMImageGetResponseObject = "image"
-)
From ca18f27daf6688518636b18a4851308dcdae0db6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 11 Feb 2026 02:19:03 +0000
Subject: [PATCH 41/52] feat(api): api update
---
.stats.yml | 4 ++--
vmimage.go | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 49a9267..230266e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-e161bba8bfdad8ec58f1927fbe39c96004d03ab9b4c501bb210c6fce9178d539.yml
-openapi_spec_hash: 3c0dee5cd2aa3d2756ffa76feea57292
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-73ad90aa5d19b8c28fa19c87336e45eaabe5721ed46c30a8872097ca95612252.yml
+openapi_spec_hash: e7c645d9a4bb34744bcb0a64712a7ff9
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/vmimage.go b/vmimage.go
index 81aac95..6df44bd 100644
--- a/vmimage.go
+++ b/vmimage.go
@@ -79,8 +79,7 @@ func (r *VMImageListResponse) UnmarshalJSON(data []byte) error {
}
type VMImageListResponseData struct {
- // Generated ID with format 'image\_[0-9a-zA-Z]+' used for referencing a ImageId
- // resource.
+ // Unique identifier with prefix 'image\_'.
ID string `json:"id,required"`
// Unix timestamp in seconds since epoch
CreatedAt int64 `json:"created_at,required"`
From ed7b95dc7003020ff3f2738321d023ae3599e9e0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 11 Feb 2026 06:13:14 +0000
Subject: [PATCH 42/52] fix(encoder): correctly serialize NullStruct
---
packages/param/encoder.go | 3 +++
packages/param/encoder_test.go | 12 ++++++++++++
2 files changed, 15 insertions(+)
diff --git a/packages/param/encoder.go b/packages/param/encoder.go
index 7c3a221..01fe75f 100644
--- a/packages/param/encoder.go
+++ b/packages/param/encoder.go
@@ -83,6 +83,9 @@ func MarshalUnion[T ParamStruct](metadata T, variants ...any) ([]byte, error) {
}
}
if nPresent == 0 || presentIdx == -1 {
+ if metadata.null() {
+ return []byte("null"), nil
+ }
if ovr, ok := metadata.Overrides(); ok {
return shimjson.Marshal(ovr)
}
diff --git a/packages/param/encoder_test.go b/packages/param/encoder_test.go
index f64ff67..e72e18d 100644
--- a/packages/param/encoder_test.go
+++ b/packages/param/encoder_test.go
@@ -363,3 +363,15 @@ func TestOverriddenUnion(t *testing.T) {
})
}
}
+
+func TestNullStructUnion(t *testing.T) {
+ nullUnion := param.NullStruct[PrimitiveUnion]()
+
+ b, err := json.Marshal(nullUnion)
+ if err != nil {
+ t.Fatalf("didn't expect error %v", err)
+ }
+ if string(b) != "null" {
+ t.Fatalf("expected null, received %s", string(b))
+ }
+}
From a8e9f7ffc184506f4bbc1a47055fd9c07117e39f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 14 Feb 2026 03:19:09 +0000
Subject: [PATCH 43/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 230266e..84396c1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-73ad90aa5d19b8c28fa19c87336e45eaabe5721ed46c30a8872097ca95612252.yml
-openapi_spec_hash: e7c645d9a4bb34744bcb0a64712a7ff9
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-48ff5f0fb9eee042b52dc88ddaa85ed2800136fd2bf61c2fbce56be53e0112f6.yml
+openapi_spec_hash: 981f0e85bf2d3633917d35db47318555
config_hash: a187153315a646ecf95709ee4a223df5
From dff5f7f8daf4d7f353962442bf41e2d55ff028a1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 17 Feb 2026 02:19:09 +0000
Subject: [PATCH 44/52] feat(api): api update
---
.stats.yml | 4 ++--
vm.go | 4 ++--
vmimage.go | 50 ++++++++++++++++++++++++++++++++++----------------
zone.go | 8 ++++----
4 files changed, 42 insertions(+), 24 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 84396c1..dec97a3 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-48ff5f0fb9eee042b52dc88ddaa85ed2800136fd2bf61c2fbce56be53e0112f6.yml
-openapi_spec_hash: 981f0e85bf2d3633917d35db47318555
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-0222183e15b3c8b162f4c55dd6a9716580236e1f4566b1852fc28b03b796766b.yml
+openapi_spec_hash: e0932a81ea5592f6f726bfe71dd4f69e
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/vm.go b/vm.go
index ca30cf2..5cc5d4d 100644
--- a/vm.go
+++ b/vm.go
@@ -99,9 +99,9 @@ func (r *VMLogsResponseData) UnmarshalJSON(data []byte) error {
type VmsshResponse struct {
SSHHostname string `json:"ssh_hostname,required"`
SSHPort int64 `json:"ssh_port,required"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
LastAttemptedKeyUpdate int64 `json:"last_attempted_key_update,nullable"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
LastSuccessfulKeyUpdate int64 `json:"last_successful_key_update,nullable"`
SSHHostKeys []VmsshResponseSSHHostKey `json:"ssh_host_keys,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
diff --git a/vmimage.go b/vmimage.go
index 6df44bd..172d260 100644
--- a/vmimage.go
+++ b/vmimage.go
@@ -54,19 +54,17 @@ func (r *VMImageService) Get(ctx context.Context, imageID string, opts ...option
return
}
+// Response body for listing images
type VMImageListResponse struct {
Data []VMImageListResponseData `json:"data,required"`
HasMore bool `json:"has_more,required"`
// Any of "list".
Object VMImageListResponseObject `json:"object,required"`
- // Opaque cursor for pagination. Pass as `starting_after` to get the next page.
- Cursor string `json:"cursor,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Data respjson.Field
HasMore respjson.Field
Object respjson.Field
- Cursor respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
@@ -78,26 +76,27 @@ func (r *VMImageListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Response body for individual image info (used in lists)
type VMImageListResponseData struct {
- // Unique identifier with prefix 'image\_'.
- ID string `json:"id,required"`
- // Unix timestamp in seconds since epoch
+ // Creation timestamp as Unix timestamp in seconds
CreatedAt int64 `json:"created_at,required"`
- // A validated resource name. Must start with alphanumeric, followed by
- // alphanumeric, '.', '\_', or '-'. Max 255 characters.
+ // The image ID
+ ImageID string `json:"image_id,required"`
+ // Client given name of the image. Must be unique per account.
Name string `json:"name,required"`
- // Any of "started", "uploading", "completed", "failed".
- UploadStatus string `json:"upload_status,required"`
// Any of "image".
- Object string `json:"object"`
+ Object string `json:"object,required"`
+ // Upload status of the image
+ UploadStatus string `json:"upload_status,required"`
+ // SHA256 hash of the image file for integrity verification
Sha256Hash string `json:"sha256_hash,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
CreatedAt respjson.Field
+ ImageID respjson.Field
Name respjson.Field
- UploadStatus respjson.Field
Object respjson.Field
+ UploadStatus respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -116,16 +115,29 @@ const (
VMImageListResponseObjectList VMImageListResponseObject = "list"
)
+// Response body for image download presigned URL generation
type VMImageGetResponse struct {
+ // The presigned URL that can be used to download the image
DownloadURL string `json:"download_url,required"`
- // Unix timestamp in seconds since epoch
- ExpiresAt int64 `json:"expires_at,required"`
- ObjectSize int64 `json:"object_size,required"`
+ // Timestamp when the presigned URL expires (RFC 3339 format)
+ ExpiresAt string `json:"expires_at,required"`
+ // The image ID
+ ImageID string `json:"image_id,required"`
+ // Human readable name of the image. Must be unique per account.
+ Name string `json:"name,required"`
+ // Any of "image".
+ Object VMImageGetResponseObject `json:"object,required"`
+ // Size of the image file in bytes
+ ObjectSize int64 `json:"object_size,required"`
+ // SHA256 hash of the image file for integrity verification
Sha256Hash string `json:"sha256_hash,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
DownloadURL respjson.Field
ExpiresAt respjson.Field
+ ImageID respjson.Field
+ Name respjson.Field
+ Object respjson.Field
ObjectSize respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
@@ -138,3 +150,9 @@ func (r VMImageGetResponse) RawJSON() string { return r.JSON.raw }
func (r *VMImageGetResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+
+type VMImageGetResponseObject string
+
+const (
+ VMImageGetResponseObjectImage VMImageGetResponseObject = "image"
+)
diff --git a/zone.go b/zone.go
index c71bc1c..dc78902 100644
--- a/zone.go
+++ b/zone.go
@@ -110,11 +110,11 @@ func (r *ZoneListResponseData) UnmarshalJSON(data []byte) error {
}
type ZoneListResponseDataAvailableCapacity struct {
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
EndTimestamp int64 `json:"end_timestamp,required"`
// The number of nodes available during this time period
Quantity int64 `json:"quantity,required"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
StartTimestamp int64 `json:"start_timestamp,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -170,11 +170,11 @@ func (r *ZoneGetResponse) UnmarshalJSON(data []byte) error {
}
type ZoneGetResponseAvailableCapacity struct {
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
EndTimestamp int64 `json:"end_timestamp,required"`
// The number of nodes available during this time period
Quantity int64 `json:"quantity,required"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
StartTimestamp int64 `json:"start_timestamp,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
From 531d77efc30775a747cf3a96320e1a85c172fdb2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 17 Feb 2026 03:19:19 +0000
Subject: [PATCH 45/52] feat(api): api update
---
.stats.yml | 4 ++--
vm.go | 4 ++--
vmimage.go | 50 ++++++++++++++++----------------------------------
zone.go | 8 ++++----
4 files changed, 24 insertions(+), 42 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index dec97a3..84396c1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-0222183e15b3c8b162f4c55dd6a9716580236e1f4566b1852fc28b03b796766b.yml
-openapi_spec_hash: e0932a81ea5592f6f726bfe71dd4f69e
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-48ff5f0fb9eee042b52dc88ddaa85ed2800136fd2bf61c2fbce56be53e0112f6.yml
+openapi_spec_hash: 981f0e85bf2d3633917d35db47318555
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/vm.go b/vm.go
index 5cc5d4d..ca30cf2 100644
--- a/vm.go
+++ b/vm.go
@@ -99,9 +99,9 @@ func (r *VMLogsResponseData) UnmarshalJSON(data []byte) error {
type VmsshResponse struct {
SSHHostname string `json:"ssh_hostname,required"`
SSHPort int64 `json:"ssh_port,required"`
- // Unix timestamp.
+ // Unix timestamp in seconds since epoch
LastAttemptedKeyUpdate int64 `json:"last_attempted_key_update,nullable"`
- // Unix timestamp.
+ // Unix timestamp in seconds since epoch
LastSuccessfulKeyUpdate int64 `json:"last_successful_key_update,nullable"`
SSHHostKeys []VmsshResponseSSHHostKey `json:"ssh_host_keys,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
diff --git a/vmimage.go b/vmimage.go
index 172d260..6df44bd 100644
--- a/vmimage.go
+++ b/vmimage.go
@@ -54,17 +54,19 @@ func (r *VMImageService) Get(ctx context.Context, imageID string, opts ...option
return
}
-// Response body for listing images
type VMImageListResponse struct {
Data []VMImageListResponseData `json:"data,required"`
HasMore bool `json:"has_more,required"`
// Any of "list".
Object VMImageListResponseObject `json:"object,required"`
+ // Opaque cursor for pagination. Pass as `starting_after` to get the next page.
+ Cursor string `json:"cursor,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Data respjson.Field
HasMore respjson.Field
Object respjson.Field
+ Cursor respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
@@ -76,27 +78,26 @@ func (r *VMImageListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Response body for individual image info (used in lists)
type VMImageListResponseData struct {
- // Creation timestamp as Unix timestamp in seconds
+ // Unique identifier with prefix 'image\_'.
+ ID string `json:"id,required"`
+ // Unix timestamp in seconds since epoch
CreatedAt int64 `json:"created_at,required"`
- // The image ID
- ImageID string `json:"image_id,required"`
- // Client given name of the image. Must be unique per account.
+ // A validated resource name. Must start with alphanumeric, followed by
+ // alphanumeric, '.', '\_', or '-'. Max 255 characters.
Name string `json:"name,required"`
- // Any of "image".
- Object string `json:"object,required"`
- // Upload status of the image
+ // Any of "started", "uploading", "completed", "failed".
UploadStatus string `json:"upload_status,required"`
- // SHA256 hash of the image file for integrity verification
+ // Any of "image".
+ Object string `json:"object"`
Sha256Hash string `json:"sha256_hash,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
+ ID respjson.Field
CreatedAt respjson.Field
- ImageID respjson.Field
Name respjson.Field
- Object respjson.Field
UploadStatus respjson.Field
+ Object respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -115,29 +116,16 @@ const (
VMImageListResponseObjectList VMImageListResponseObject = "list"
)
-// Response body for image download presigned URL generation
type VMImageGetResponse struct {
- // The presigned URL that can be used to download the image
DownloadURL string `json:"download_url,required"`
- // Timestamp when the presigned URL expires (RFC 3339 format)
- ExpiresAt string `json:"expires_at,required"`
- // The image ID
- ImageID string `json:"image_id,required"`
- // Human readable name of the image. Must be unique per account.
- Name string `json:"name,required"`
- // Any of "image".
- Object VMImageGetResponseObject `json:"object,required"`
- // Size of the image file in bytes
- ObjectSize int64 `json:"object_size,required"`
- // SHA256 hash of the image file for integrity verification
+ // Unix timestamp in seconds since epoch
+ ExpiresAt int64 `json:"expires_at,required"`
+ ObjectSize int64 `json:"object_size,required"`
Sha256Hash string `json:"sha256_hash,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
DownloadURL respjson.Field
ExpiresAt respjson.Field
- ImageID respjson.Field
- Name respjson.Field
- Object respjson.Field
ObjectSize respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
@@ -150,9 +138,3 @@ func (r VMImageGetResponse) RawJSON() string { return r.JSON.raw }
func (r *VMImageGetResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-
-type VMImageGetResponseObject string
-
-const (
- VMImageGetResponseObjectImage VMImageGetResponseObject = "image"
-)
diff --git a/zone.go b/zone.go
index dc78902..c71bc1c 100644
--- a/zone.go
+++ b/zone.go
@@ -110,11 +110,11 @@ func (r *ZoneListResponseData) UnmarshalJSON(data []byte) error {
}
type ZoneListResponseDataAvailableCapacity struct {
- // Unix timestamp.
+ // Unix timestamp in seconds since epoch
EndTimestamp int64 `json:"end_timestamp,required"`
// The number of nodes available during this time period
Quantity int64 `json:"quantity,required"`
- // Unix timestamp.
+ // Unix timestamp in seconds since epoch
StartTimestamp int64 `json:"start_timestamp,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -170,11 +170,11 @@ func (r *ZoneGetResponse) UnmarshalJSON(data []byte) error {
}
type ZoneGetResponseAvailableCapacity struct {
- // Unix timestamp.
+ // Unix timestamp in seconds since epoch
EndTimestamp int64 `json:"end_timestamp,required"`
// The number of nodes available during this time period
Quantity int64 `json:"quantity,required"`
- // Unix timestamp.
+ // Unix timestamp in seconds since epoch
StartTimestamp int64 `json:"start_timestamp,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
From a0a7fa24667407359b24deb9a6391599873cfc4e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 17 Feb 2026 17:19:10 +0000
Subject: [PATCH 46/52] feat(api): api update
---
.stats.yml | 4 ++--
vm.go | 4 ++--
vmimage.go | 50 ++++++++++++++++++++++++++++++++++----------------
zone.go | 8 ++++----
4 files changed, 42 insertions(+), 24 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 84396c1..d04a7de 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-48ff5f0fb9eee042b52dc88ddaa85ed2800136fd2bf61c2fbce56be53e0112f6.yml
-openapi_spec_hash: 981f0e85bf2d3633917d35db47318555
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-ad9dff266598362df8e3ab4c76d44d965a4a6722e0b54300b7ea1e8956cef63a.yml
+openapi_spec_hash: c02ff6cf22b6762d1ddfd3908e194e3c
config_hash: a187153315a646ecf95709ee4a223df5
diff --git a/vm.go b/vm.go
index ca30cf2..5cc5d4d 100644
--- a/vm.go
+++ b/vm.go
@@ -99,9 +99,9 @@ func (r *VMLogsResponseData) UnmarshalJSON(data []byte) error {
type VmsshResponse struct {
SSHHostname string `json:"ssh_hostname,required"`
SSHPort int64 `json:"ssh_port,required"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
LastAttemptedKeyUpdate int64 `json:"last_attempted_key_update,nullable"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
LastSuccessfulKeyUpdate int64 `json:"last_successful_key_update,nullable"`
SSHHostKeys []VmsshResponseSSHHostKey `json:"ssh_host_keys,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
diff --git a/vmimage.go b/vmimage.go
index 6df44bd..172d260 100644
--- a/vmimage.go
+++ b/vmimage.go
@@ -54,19 +54,17 @@ func (r *VMImageService) Get(ctx context.Context, imageID string, opts ...option
return
}
+// Response body for listing images
type VMImageListResponse struct {
Data []VMImageListResponseData `json:"data,required"`
HasMore bool `json:"has_more,required"`
// Any of "list".
Object VMImageListResponseObject `json:"object,required"`
- // Opaque cursor for pagination. Pass as `starting_after` to get the next page.
- Cursor string `json:"cursor,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Data respjson.Field
HasMore respjson.Field
Object respjson.Field
- Cursor respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
@@ -78,26 +76,27 @@ func (r *VMImageListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Response body for individual image info (used in lists)
type VMImageListResponseData struct {
- // Unique identifier with prefix 'image\_'.
- ID string `json:"id,required"`
- // Unix timestamp in seconds since epoch
+ // Creation timestamp as Unix timestamp in seconds
CreatedAt int64 `json:"created_at,required"`
- // A validated resource name. Must start with alphanumeric, followed by
- // alphanumeric, '.', '\_', or '-'. Max 255 characters.
+ // The image ID
+ ImageID string `json:"image_id,required"`
+ // Client given name of the image. Must be unique per account.
Name string `json:"name,required"`
- // Any of "started", "uploading", "completed", "failed".
- UploadStatus string `json:"upload_status,required"`
// Any of "image".
- Object string `json:"object"`
+ Object string `json:"object,required"`
+ // Upload status of the image
+ UploadStatus string `json:"upload_status,required"`
+ // SHA256 hash of the image file for integrity verification
Sha256Hash string `json:"sha256_hash,nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
CreatedAt respjson.Field
+ ImageID respjson.Field
Name respjson.Field
- UploadStatus respjson.Field
Object respjson.Field
+ UploadStatus respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -116,16 +115,29 @@ const (
VMImageListResponseObjectList VMImageListResponseObject = "list"
)
+// Response body for image download presigned URL generation
type VMImageGetResponse struct {
+ // The presigned URL that can be used to download the image
DownloadURL string `json:"download_url,required"`
- // Unix timestamp in seconds since epoch
- ExpiresAt int64 `json:"expires_at,required"`
- ObjectSize int64 `json:"object_size,required"`
+ // Timestamp when the presigned URL expires (RFC 3339 format)
+ ExpiresAt string `json:"expires_at,required"`
+ // The image ID
+ ImageID string `json:"image_id,required"`
+ // Human readable name of the image. Must be unique per account.
+ Name string `json:"name,required"`
+ // Any of "image".
+ Object VMImageGetResponseObject `json:"object,required"`
+ // Size of the image file in bytes
+ ObjectSize int64 `json:"object_size,required"`
+ // SHA256 hash of the image file for integrity verification
Sha256Hash string `json:"sha256_hash,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
DownloadURL respjson.Field
ExpiresAt respjson.Field
+ ImageID respjson.Field
+ Name respjson.Field
+ Object respjson.Field
ObjectSize respjson.Field
Sha256Hash respjson.Field
ExtraFields map[string]respjson.Field
@@ -138,3 +150,9 @@ func (r VMImageGetResponse) RawJSON() string { return r.JSON.raw }
func (r *VMImageGetResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+
+type VMImageGetResponseObject string
+
+const (
+ VMImageGetResponseObjectImage VMImageGetResponseObject = "image"
+)
diff --git a/zone.go b/zone.go
index c71bc1c..dc78902 100644
--- a/zone.go
+++ b/zone.go
@@ -110,11 +110,11 @@ func (r *ZoneListResponseData) UnmarshalJSON(data []byte) error {
}
type ZoneListResponseDataAvailableCapacity struct {
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
EndTimestamp int64 `json:"end_timestamp,required"`
// The number of nodes available during this time period
Quantity int64 `json:"quantity,required"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
StartTimestamp int64 `json:"start_timestamp,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -170,11 +170,11 @@ func (r *ZoneGetResponse) UnmarshalJSON(data []byte) error {
}
type ZoneGetResponseAvailableCapacity struct {
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
EndTimestamp int64 `json:"end_timestamp,required"`
// The number of nodes available during this time period
Quantity int64 `json:"quantity,required"`
- // Unix timestamp in seconds since epoch
+ // Unix timestamp.
StartTimestamp int64 `json:"start_timestamp,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
From 197e7e62ae7cb06ee71a0012f1dfb576c9081222 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 17 Feb 2026 23:19:18 +0000
Subject: [PATCH 47/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d04a7de..0a2a3e8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-ad9dff266598362df8e3ab4c76d44d965a4a6722e0b54300b7ea1e8956cef63a.yml
-openapi_spec_hash: c02ff6cf22b6762d1ddfd3908e194e3c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-2b693aca1e07a47534ce7e26f61f58e1fdae0968e441c955112f95e3b0a7d7ac.yml
+openapi_spec_hash: b6bbc4db82c27c08a763bf149f20be76
config_hash: a187153315a646ecf95709ee4a223df5
From 8a8384932b6e74943b973c2dddf1a37e45f71cc1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 19 Feb 2026 23:19:08 +0000
Subject: [PATCH 48/52] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0a2a3e8..0c741d5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -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-2b693aca1e07a47534ce7e26f61f58e1fdae0968e441c955112f95e3b0a7d7ac.yml
-openapi_spec_hash: b6bbc4db82c27c08a763bf149f20be76
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/the-san-francisco-compute-company%2Fsfc-nodes-d786973209f42e6ca35f318f4d5bf01e4abd77205e210409c6a3fb371a99a4c5.yml
+openapi_spec_hash: 03857ab189ed9fcd889e7b3fe1cc2f2f
config_hash: a187153315a646ecf95709ee4a223df5
From f28644aaee0119dccf2223264f06703f00567327 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 20 Feb 2026 06:19:33 +0000
Subject: [PATCH 49/52] chore(internal): remove mock server code
---
scripts/mock | 41 -----------------------------------------
scripts/test | 46 ----------------------------------------------
2 files changed, 87 deletions(-)
delete mode 100755 scripts/mock
diff --git a/scripts/mock b/scripts/mock
deleted file mode 100755
index 0b28f6e..0000000
--- a/scripts/mock
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-cd "$(dirname "$0")/.."
-
-if [[ -n "$1" && "$1" != '--'* ]]; then
- URL="$1"
- shift
-else
- URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)"
-fi
-
-# Check if the URL is empty
-if [ -z "$URL" ]; then
- echo "Error: No OpenAPI spec path/url provided or found in .stats.yml"
- exit 1
-fi
-
-echo "==> Starting mock server with URL ${URL}"
-
-# Run prism mock on the given spec
-if [ "$1" == "--daemon" ]; then
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
-
- # Wait for server to come online
- echo -n "Waiting for server"
- while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
- echo -n "."
- sleep 0.1
- done
-
- if grep -q "✖ fatal" ".prism.log"; then
- cat .prism.log
- exit 1
- fi
-
- echo
-else
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
-fi
diff --git a/scripts/test b/scripts/test
index c26b122..8704b64 100755
--- a/scripts/test
+++ b/scripts/test
@@ -4,53 +4,7 @@ set -e
cd "$(dirname "$0")/.."
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[0;33m'
-NC='\033[0m' # No Color
-function prism_is_running() {
- curl --silent "http://localhost:4010" >/dev/null 2>&1
-}
-
-kill_server_on_port() {
- pids=$(lsof -t -i tcp:"$1" || echo "")
- if [ "$pids" != "" ]; then
- kill "$pids"
- echo "Stopped $pids."
- fi
-}
-
-function is_overriding_api_base_url() {
- [ -n "$TEST_API_BASE_URL" ]
-}
-
-if ! is_overriding_api_base_url && ! prism_is_running ; then
- # When we exit this script, make sure to kill the background mock server process
- trap 'kill_server_on_port 4010' EXIT
-
- # Start the dev server
- ./scripts/mock --daemon
-fi
-
-if is_overriding_api_base_url ; then
- echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}"
- echo
-elif ! prism_is_running ; then
- echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server"
- echo -e "running against your OpenAPI spec."
- echo
- echo -e "To run the server, pass in the path or url of your OpenAPI"
- echo -e "spec to the prism command:"
- echo
- echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
- echo
-
- exit 1
-else
- echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}"
- echo
-fi
echo "==> Running tests"
go test ./... "$@"
From 588eb6aca1879b14a61976f013b0155140dc1971 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 20 Feb 2026 06:20:48 +0000
Subject: [PATCH 50/52] chore: update mock server docs
---
CONTRIBUTING.md | 7 -------
internal/testutil/testutil.go | 4 ++--
node_test.go | 14 +++++++-------
usage_test.go | 2 +-
vm_test.go | 4 ++--
vmimage_test.go | 4 ++--
vmscript_test.go | 4 ++--
zone_test.go | 4 ++--
8 files changed, 18 insertions(+), 25 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 090e94c..796313f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -46,13 +46,6 @@ $ go mod edit -replace github.com/sfcompute/nodes-go=/path/to/nodes-go
## Running tests
-Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
-
-```sh
-# you will need npm installed
-$ npx prism mock path/to/your/openapi.yml
-```
-
```sh
$ ./scripts/test
```
diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go
index 826d266..31103e9 100644
--- a/internal/testutil/testutil.go
+++ b/internal/testutil/testutil.go
@@ -16,10 +16,10 @@ func CheckTestServer(t *testing.T, url string) bool {
t.Fatalf("strconv.ParseBool(os.LookupEnv(%s)) failed: %s", SKIP_MOCK_TESTS, err)
}
if skip {
- t.Skip("The test will not run without a mock Prism server running against your OpenAPI spec")
+ t.Skip("The test will not run without a mock server running against your OpenAPI spec")
return false
}
- t.Errorf("The test will not run without a mock Prism server running against your OpenAPI spec. You can set the environment variable %s to true to skip running any tests that require the mock server", SKIP_MOCK_TESTS)
+ t.Errorf("The test will not run without a mock server running against your OpenAPI spec. You can set the environment variable %s to true to skip running any tests that require the mock server", SKIP_MOCK_TESTS)
return false
}
}
diff --git a/node_test.go b/node_test.go
index 31ea651..85cf86f 100644
--- a/node_test.go
+++ b/node_test.go
@@ -14,7 +14,7 @@ import (
)
func TestNodeNewWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -51,7 +51,7 @@ func TestNodeNewWithOptionalParams(t *testing.T) {
}
func TestNodeListWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -78,7 +78,7 @@ func TestNodeListWithOptionalParams(t *testing.T) {
}
func TestNodeDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -101,7 +101,7 @@ func TestNodeDelete(t *testing.T) {
}
func TestNodeExtend(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -133,7 +133,7 @@ func TestNodeExtend(t *testing.T) {
}
func TestNodeGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -156,7 +156,7 @@ func TestNodeGet(t *testing.T) {
}
func TestNodeRedeployWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -187,7 +187,7 @@ func TestNodeRedeployWithOptionalParams(t *testing.T) {
}
func TestNodeRelease(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/usage_test.go b/usage_test.go
index dc7e012..a25bf6d 100644
--- a/usage_test.go
+++ b/usage_test.go
@@ -24,7 +24,7 @@ func TestUsage(t *testing.T) {
option.WithBaseURL(baseURL),
option.WithBearerToken("My Bearer Token"),
)
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
listResponseNode, err := client.Nodes.List(context.TODO(), sfcnodes.NodeListParams{})
if err != nil {
t.Fatalf("err should be nil: %s", err.Error())
diff --git a/vm_test.go b/vm_test.go
index 2adcbbd..74bf38f 100644
--- a/vm_test.go
+++ b/vm_test.go
@@ -14,7 +14,7 @@ import (
)
func TestVMLogsWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -45,7 +45,7 @@ func TestVMLogsWithOptionalParams(t *testing.T) {
}
func TestVMSSH(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/vmimage_test.go b/vmimage_test.go
index d27aa39..85daf31 100644
--- a/vmimage_test.go
+++ b/vmimage_test.go
@@ -14,7 +14,7 @@ import (
)
func TestVMImageList(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -37,7 +37,7 @@ func TestVMImageList(t *testing.T) {
}
func TestVMImageGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/vmscript_test.go b/vmscript_test.go
index 78af7cd..398e4b0 100644
--- a/vmscript_test.go
+++ b/vmscript_test.go
@@ -14,7 +14,7 @@ import (
)
func TestVMScriptNew(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -41,7 +41,7 @@ func TestVMScriptNew(t *testing.T) {
}
func TestVMScriptGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/zone_test.go b/zone_test.go
index 061d9ba..11ad8c7 100644
--- a/zone_test.go
+++ b/zone_test.go
@@ -14,7 +14,7 @@ import (
)
func TestZoneList(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -37,7 +37,7 @@ func TestZoneList(t *testing.T) {
}
func TestZoneGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
From b16eec05809da7c51496804b92be7f79a664860a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 20 Feb 2026 06:33:34 +0000
Subject: [PATCH 51/52] fix: allow canceling a request while it is waiting to
retry
---
internal/requestconfig/requestconfig.go | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go
index f36e5e7..d0ee6e7 100644
--- a/internal/requestconfig/requestconfig.go
+++ b/internal/requestconfig/requestconfig.go
@@ -466,7 +466,11 @@ func (cfg *RequestConfig) Execute() (err error) {
res.Body.Close()
}
- time.Sleep(retryDelay(res, retryCount))
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-time.After(retryDelay(res, retryCount)):
+ }
}
// Save *http.Response if it is requested to, even if there was an error making the request. This is
From 24ffc129d5a061b6d9a2bc09c1a65e5abe2a46c3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 20 Feb 2026 06:34:06 +0000
Subject: [PATCH 52/52] release: 0.1.0-alpha.5
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 41 +++++++++++++++++++++++++++++++++++
README.md | 2 +-
internal/version.go | 2 +-
4 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b56c3d0..e8285b7 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.4"
+ ".": "0.1.0-alpha.5"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 074875f..3eaaa82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,46 @@
# Changelog
+## 0.1.0-alpha.5 (2026-02-20)
+
+Full Changelog: [v0.1.0-alpha.4...v0.1.0-alpha.5](https://github.com/sfcompute/nodes-go/compare/v0.1.0-alpha.4...v0.1.0-alpha.5)
+
+### Features
+
+* **api:** api update ([a0a7fa2](https://github.com/sfcompute/nodes-go/commit/a0a7fa24667407359b24deb9a6391599873cfc4e))
+* **api:** api update ([531d77e](https://github.com/sfcompute/nodes-go/commit/531d77efc30775a747cf3a96320e1a85c172fdb2))
+* **api:** api update ([dff5f7f](https://github.com/sfcompute/nodes-go/commit/dff5f7f8daf4d7f353962442bf41e2d55ff028a1))
+* **api:** api update ([ca18f27](https://github.com/sfcompute/nodes-go/commit/ca18f27daf6688518636b18a4851308dcdae0db6))
+* **api:** api update ([894995d](https://github.com/sfcompute/nodes-go/commit/894995db7b4a6347ef91fed5db242fbb14df34ef))
+* **api:** api update ([afa8e35](https://github.com/sfcompute/nodes-go/commit/afa8e35b48706ac111a768c9a7a81c59aa1602b0))
+* **api:** api update ([f77e6d0](https://github.com/sfcompute/nodes-go/commit/f77e6d07e261819f07b68b9241218f42a0ab36a1))
+* **api:** api update ([3068ae6](https://github.com/sfcompute/nodes-go/commit/3068ae6937f3d6f6f5b36f8ac7c7e318866c3ce1))
+* **api:** api update ([a4e5181](https://github.com/sfcompute/nodes-go/commit/a4e5181e44815a66b891ecd41790c9dab76c0375))
+* **api:** api update ([6a064fd](https://github.com/sfcompute/nodes-go/commit/6a064fdc947dd668159e8643e7cab0689254d4c6))
+* **api:** api update ([dd70400](https://github.com/sfcompute/nodes-go/commit/dd70400abff7e7332cf7a7f3dee59e9e2e4b61b5))
+* **client:** add a convenient param.SetJSON helper ([a7293f3](https://github.com/sfcompute/nodes-go/commit/a7293f32d7d9f676d53e6200ca7bd82f603029bb))
+* **encoder:** support bracket encoding form-data object members ([bf75f99](https://github.com/sfcompute/nodes-go/commit/bf75f99a26c353742229dabb561684545d0835c7))
+
+
+### Bug Fixes
+
+* allow canceling a request while it is waiting to retry ([b16eec0](https://github.com/sfcompute/nodes-go/commit/b16eec05809da7c51496804b92be7f79a664860a))
+* **docs:** add missing pointer prefix to api.md return types ([6dd1ead](https://github.com/sfcompute/nodes-go/commit/6dd1eadf389b5a9adf98195f624f0bba54f0b686))
+* **encoder:** correctly serialize NullStruct ([ed7b95d](https://github.com/sfcompute/nodes-go/commit/ed7b95dc7003020ff3f2738321d023ae3599e9e0))
+* **mcp:** correct code tool API endpoint ([2eeb64b](https://github.com/sfcompute/nodes-go/commit/2eeb64be8909979b8cb3524a077cb764c85a1f21))
+* rename param to avoid collision ([f221c75](https://github.com/sfcompute/nodes-go/commit/f221c7569b746c43bd46c4ab3c1615b30fc0c05c))
+* skip usage tests that don't work with Prism ([61d03bd](https://github.com/sfcompute/nodes-go/commit/61d03bd3c1f7772a74bef48676020df27c371ab1))
+
+
+### Chores
+
+* add float64 to valid types for RegisterFieldValidator ([499e663](https://github.com/sfcompute/nodes-go/commit/499e663b659fa00c013ebe3db1e0622b5e2a6a51))
+* elide duplicate aliases ([9e83189](https://github.com/sfcompute/nodes-go/commit/9e83189fd37d851e8441c313c738656a72760483))
+* **internal:** codegen related update ([44eb5d0](https://github.com/sfcompute/nodes-go/commit/44eb5d0a3f745631aebb3b0d2986a049302131fe))
+* **internal:** codegen related update ([e40a3de](https://github.com/sfcompute/nodes-go/commit/e40a3debee22efa7015e5230d14374245af79b1f))
+* **internal:** remove mock server code ([f28644a](https://github.com/sfcompute/nodes-go/commit/f28644aaee0119dccf2223264f06703f00567327))
+* **internal:** update `actions/checkout` version ([c853455](https://github.com/sfcompute/nodes-go/commit/c853455bd8e0c977606bc29049cfc84b2caea449))
+* update mock server docs ([588eb6a](https://github.com/sfcompute/nodes-go/commit/588eb6aca1879b14a61976f013b0155140dc1971))
+
## 0.1.0-alpha.4 (2025-12-01)
Full Changelog: [v0.1.0-alpha.3...v0.1.0-alpha.4](https://github.com/sfcompute/nodes-go/compare/v0.1.0-alpha.3...v0.1.0-alpha.4)
diff --git a/README.md b/README.md
index 43ac98e..0d65833 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/sfcompute/nodes-go@v0.1.0-alpha.4'
+go get -u 'github.com/sfcompute/nodes-go@v0.1.0-alpha.5'
```
diff --git a/internal/version.go b/internal/version.go
index 5469df6..2aad167 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.1.0-alpha.4" // x-release-please-version
+const PackageVersion = "0.1.0-alpha.5" // x-release-please-version