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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0-alpha.3"
".": "0.1.0-alpha.4"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 7
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-c9d64df733f286f09d2203f4e3d820ce57e8d4c629c5e2db4e2bfac91fbc1598.yml
openapi_spec_hash: fa407611fc566d55f403864fbfaa6c23
config_hash: 7f67c5b95af1e4b39525515240b72275
configured_endpoints: 6
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-19b0d17ba368f32827ee322d15a7f4ff7e1f3bbf66606fad227b3465f8ffc5ab.yml
openapi_spec_hash: 4a3cb766898e8a134ef99fe6c4c87736
config_hash: 4dfa4d870ce0e23e31ce33ab6a53dd21
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## 0.1.0-alpha.4 (2025-05-20)

Full Changelog: [v0.1.0-alpha.3...v0.1.0-alpha.4](https://github.com/onkernel/kernel-go-sdk/compare/v0.1.0-alpha.3...v0.1.0-alpha.4)

### Features

* **api:** update via SDK Studio ([34dfea0](https://github.com/onkernel/kernel-go-sdk/commit/34dfea07fd8538b3a73f8ee7ea35f3a70e679b3b))


### Bug Fixes

* **client:** correctly set stream key for multipart ([2336290](https://github.com/onkernel/kernel-go-sdk/commit/23362905d1acb3616333407f70bdee259dc66ebe))
* **client:** don't panic on marshal with extra null field ([4208ce7](https://github.com/onkernel/kernel-go-sdk/commit/4208ce7bb382ac9bfb2cefeb406be6302df6cd7a))
* **client:** increase max stream buffer size ([eca7429](https://github.com/onkernel/kernel-go-sdk/commit/eca74291efed0e090b1a7437d832ee12a819f833))
* **client:** use scanner for streaming ([6fad3f9](https://github.com/onkernel/kernel-go-sdk/commit/6fad3f9d43fbb49c718a53ae6736ac273e43b7b3))

## 0.1.0-alpha.3 (2025-05-19)

Full Changelog: [v0.1.0-alpha.2...v0.1.0-alpha.3](https://github.com/onkernel/kernel-go-sdk/compare/v0.1.0-alpha.2...v0.1.0-alpha.3)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/onkernel/[email protected].3'
go get -u 'github.com/onkernel/[email protected].4'
```

<!-- x-release-please-end -->
Expand Down
8 changes: 0 additions & 8 deletions api.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
# Apps

Response Types:

- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#AppListResponse">AppListResponse</a>

Methods:

- <code title="get /apps">client.Apps.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#AppService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#AppListParams">AppListParams</a>) ([]<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#AppListResponse">AppListResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

## Deployments

Response Types:
Expand Down
64 changes: 0 additions & 64 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@
package kernel

import (
"context"
"net/http"
"net/url"

"github.com/onkernel/kernel-go-sdk/internal/apijson"
"github.com/onkernel/kernel-go-sdk/internal/apiquery"
"github.com/onkernel/kernel-go-sdk/internal/requestconfig"
"github.com/onkernel/kernel-go-sdk/option"
"github.com/onkernel/kernel-go-sdk/packages/param"
"github.com/onkernel/kernel-go-sdk/packages/respjson"
)

// AppService contains methods and other services that help with interacting with
Expand All @@ -37,58 +28,3 @@ func NewAppService(opts ...option.RequestOption) (r AppService) {
r.Invocations = NewAppInvocationService(opts...)
return
}

// List application versions for the authenticated user. Optionally filter by app
// name and/or version label.
func (r *AppService) List(ctx context.Context, query AppListParams, opts ...option.RequestOption) (res *[]AppListResponse, err error) {
opts = append(r.Options[:], opts...)
path := "apps"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
return
}

// Summary of an application version.
type AppListResponse struct {
// Unique identifier for the app version
ID string `json:"id,required"`
// Name of the application
AppName string `json:"app_name,required"`
// Deployment region code
Region string `json:"region,required"`
// Version label for the application
Version string `json:"version,required"`
// Environment variables configured for this app version
EnvVars map[string]string `json:"env_vars"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
AppName respjson.Field
Region respjson.Field
Version respjson.Field
EnvVars respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

// Returns the unmodified JSON received from the API
func (r AppListResponse) RawJSON() string { return r.JSON.raw }
func (r *AppListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

type AppListParams struct {
// Filter results by application name.
AppName param.Opt[string] `query:"app_name,omitzero" json:"-"`
// Filter results by version label.
Version param.Opt[string] `query:"version,omitzero" json:"-"`
paramObj
}

// URLQuery serializes [AppListParams]'s query parameters as `url.Values`.
func (r AppListParams) URLQuery() (v url.Values, err error) {
return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
ArrayFormat: apiquery.ArrayQueryFormatComma,
NestedFormat: apiquery.NestedQueryFormatBrackets,
})
}
40 changes: 0 additions & 40 deletions app_test.go

This file was deleted.

3 changes: 3 additions & 0 deletions appdeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ func (r AppDeploymentNewParams) MarshalMultipart() (data []byte, contentType str
buf := bytes.NewBuffer(nil)
writer := multipart.NewWriter(buf)
err = apiform.MarshalRoot(r, writer)
if err == nil {
err = apiform.WriteExtras(writer, r.ExtraFields())
}
if err != nil {
writer.Close()
return nil, "", err
Expand Down
14 changes: 14 additions & 0 deletions internal/apiform/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,17 @@ func (e *encoder) newMapEncoder(_ reflect.Type) encoderFunc {
return e.encodeMapEntries(key, value, writer)
}
}

func WriteExtras(writer *multipart.Writer, extras map[string]any) (err error) {
for k, v := range extras {
str, ok := v.(string)
if !ok {
break
}
err = writer.WriteField(k, str)
if err != nil {
break
}
}
return
}
2 changes: 1 addition & 1 deletion internal/apijson/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
}

// Handle null [param.Opt]
if itemNode.Type == gjson.Null && dest.Type().Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) {
if itemNode.Type == gjson.Null && dest.IsValid() && dest.Type().Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) {
dest.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(itemNode.Raw))
continue
}
Expand Down
30 changes: 30 additions & 0 deletions internal/apijson/decoderesp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package apijson_test

import (
"encoding/json"
"github.com/onkernel/kernel-go-sdk/internal/apijson"
"github.com/onkernel/kernel-go-sdk/packages/respjson"
"testing"
)

type StructWithNullExtraField struct {
Results []string `json:"results,required"`
JSON struct {
Results respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

func (r *StructWithNullExtraField) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

func TestDecodeWithNullExtraField(t *testing.T) {
raw := `{"something_else":null}`
var dst *StructWithNullExtraField
err := json.Unmarshal([]byte(raw), &dst)
if err != nil {
t.Fatalf("error: %s", err.Error())
}
}
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "0.1.0-alpha.3" // x-release-please-version
const PackageVersion = "0.1.0-alpha.4" // x-release-please-version
61 changes: 10 additions & 51 deletions packages/ssestream/ssestream.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"io"
"net/http"
"strings"
"fmt"
)

type Decoder interface {
Expand All @@ -29,7 +28,9 @@ func NewDecoder(res *http.Response) Decoder {
if t, ok := decoderTypes[contentType]; ok {
decoder = t(res.Body)
} else {
decoder = &eventStreamDecoder{rc: res.Body, rdr: bufio.NewReader(res.Body)}
scn := bufio.NewScanner(res.Body)
scn.Buffer(nil, bufio.MaxScanTokenSize<<4)
decoder = &eventStreamDecoder{rc: res.Body, scn: scn}
}
return decoder
}
Expand All @@ -49,48 +50,10 @@ type Event struct {
type eventStreamDecoder struct {
evt Event
rc io.ReadCloser
rdr *bufio.Reader
scn *bufio.Scanner
err error
}

func line(r *bufio.Reader) ([]byte, error) {
var overflow bytes.Buffer

// To prevent infinite loops, the failsafe stops when a line is
// 100 times longer than the [io.Reader] default buffer size,
// or after 20 failed attempts to find an end of line.
for f := 0; f < 100; f++ {
part, isPrefix, err := r.ReadLine()
if err != nil {
return nil, err
}

// Happy case, the line fits in the default buffer.
if !isPrefix && overflow.Len() == 0 {
return part, nil
}

// Overflow case, append to the buffer.
if isPrefix || overflow.Len() > 0 {
n, err := overflow.Write(part)
if err != nil {
return nil, err
}

// Didn't find an end of line, heavily increment the failsafe.
if n != r.Size() {
f += 5
}
}

if !isPrefix {
return overflow.Bytes(), nil
}
}

return nil, fmt.Errorf("ssestream: too many attempts to read a line")
}

func (s *eventStreamDecoder) Next() bool {
if s.err != nil {
return false
Expand All @@ -99,16 +62,8 @@ func (s *eventStreamDecoder) Next() bool {
event := ""
data := bytes.NewBuffer(nil)

for {
txt, err := line(s.rdr)
if err == io.EOF {
return false
}

if err != nil {
s.err = err
break
}
for s.scn.Scan() {
txt := s.scn.Bytes()

// Dispatch event on an empty line
if len(txt) == 0 {
Expand Down Expand Up @@ -145,6 +100,10 @@ func (s *eventStreamDecoder) Next() bool {
}
}

if s.scn.Err() != nil {
s.err = s.scn.Err()
}

return false
}

Expand Down