Skip to content

Commit f9e9d7d

Browse files
chore(internal): codegen related update
1 parent 7dd0ffb commit f9e9d7d

File tree

4 files changed

+977
-1
lines changed

4 files changed

+977
-1
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/stretchr/testify v1.10.0
2020
github.com/tidwall/gjson v1.18.0
2121
github.com/tidwall/pretty v1.2.1
22+
github.com/tidwall/sjson v1.2.5
2223
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
2324
github.com/urfave/cli/v3 v3.3.2
2425
golang.org/x/sys v0.38.0
@@ -55,7 +56,6 @@ require (
5556
github.com/rivo/uniseg v0.4.7 // indirect
5657
github.com/russross/blackfriday/v2 v2.1.0 // indirect
5758
github.com/tidwall/match v1.1.1 // indirect
58-
github.com/tidwall/sjson v1.2.5 // indirect
5959
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
6060
github.com/yuin/goldmark v1.7.8 // indirect
6161
github.com/yuin/goldmark-emoji v1.0.5 // indirect

pkg/cmd/util.go

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package cmd
4+
5+
import (
6+
"bytes"
7+
"encoding/base64"
8+
"encoding/json"
9+
"fmt"
10+
"io"
11+
"log"
12+
"net/http"
13+
"net/http/httputil"
14+
"os"
15+
"reflect"
16+
"strings"
17+
18+
"golang.org/x/term"
19+
20+
"github.com/stainless-api/stainless-api-cli/pkg/jsonview"
21+
"github.com/stainless-api/stainless-api-go/option"
22+
23+
"github.com/itchyny/json2yaml"
24+
"github.com/tidwall/gjson"
25+
"github.com/tidwall/pretty"
26+
"github.com/tidwall/sjson"
27+
"github.com/urfave/cli/v3"
28+
)
29+
30+
func getDefaultRequestOptions(cmd *cli.Command) []option.RequestOption {
31+
opts := []option.RequestOption{
32+
option.WithHeader("User-Agent", fmt.Sprintf("Stainless/CLI %s", Version)),
33+
option.WithHeader("X-Stainless-Lang", "cli"),
34+
option.WithHeader("X-Stainless-Package-Version", Version),
35+
option.WithHeader("X-Stainless-Runtime", "cli"),
36+
option.WithHeader("X-Stainless-CLI-Command", cmd.FullName()),
37+
}
38+
39+
// Override base URL if the --base-url flag is provided
40+
if baseURL := cmd.String("base-url"); baseURL != "" {
41+
opts = append(opts, option.WithBaseURL(baseURL))
42+
}
43+
44+
// Set environment if the --environment flag is provided
45+
if environment := cmd.String("environment"); environment != "" {
46+
switch environment {
47+
case "production":
48+
opts = append(opts, option.WithEnvironmentProduction())
49+
case "staging":
50+
opts = append(opts, option.WithEnvironmentStaging())
51+
default:
52+
log.Fatalf("Unknown environment: %s. Valid environments are: production, staging", environment)
53+
}
54+
}
55+
56+
return opts
57+
}
58+
59+
type fileReader struct {
60+
Value io.Reader
61+
Base64Encoded bool
62+
}
63+
64+
func (f *fileReader) Set(filename string) error {
65+
reader, err := os.Open(filename)
66+
if err != nil {
67+
return fmt.Errorf("failed to read file %q: %w", filename, err)
68+
}
69+
f.Value = reader
70+
return nil
71+
}
72+
73+
func (f *fileReader) String() string {
74+
if f.Value == nil {
75+
return ""
76+
}
77+
buf := new(bytes.Buffer)
78+
buf.ReadFrom(f.Value)
79+
if f.Base64Encoded {
80+
return base64.StdEncoding.EncodeToString(buf.Bytes())
81+
}
82+
return buf.String()
83+
}
84+
85+
func (f *fileReader) Get() any {
86+
return f.String()
87+
}
88+
89+
func unmarshalWithReaders(data []byte, v any) error {
90+
var fields map[string]json.RawMessage
91+
if err := json.Unmarshal(data, &fields); err != nil {
92+
return err
93+
}
94+
95+
rv := reflect.ValueOf(v).Elem()
96+
rt := rv.Type()
97+
98+
for i := 0; i < rv.NumField(); i++ {
99+
fv := rv.Field(i)
100+
ft := rt.Field(i)
101+
102+
jsonKey := ft.Tag.Get("json")
103+
if jsonKey == "" {
104+
jsonKey = ft.Name
105+
} else if idx := strings.Index(jsonKey, ","); idx != -1 {
106+
jsonKey = jsonKey[:idx]
107+
}
108+
109+
rawVal, ok := fields[jsonKey]
110+
if !ok {
111+
continue
112+
}
113+
114+
if ft.Type == reflect.TypeOf((*io.Reader)(nil)).Elem() {
115+
var s string
116+
if err := json.Unmarshal(rawVal, &s); err != nil {
117+
return fmt.Errorf("field %s: %w", ft.Name, err)
118+
}
119+
fv.Set(reflect.ValueOf(strings.NewReader(s)))
120+
} else {
121+
ptr := fv.Addr().Interface()
122+
if err := json.Unmarshal(rawVal, ptr); err != nil {
123+
return fmt.Errorf("field %s: %w", ft.Name, err)
124+
}
125+
}
126+
}
127+
128+
return nil
129+
}
130+
131+
func unmarshalStdinWithFlags(cmd *cli.Command, flags map[string]string, target any) error {
132+
var data []byte
133+
if isInputPiped() {
134+
var err error
135+
if data, err = io.ReadAll(os.Stdin); err != nil {
136+
return err
137+
}
138+
}
139+
140+
// Merge CLI flags into the body
141+
for flag, path := range flags {
142+
if cmd.IsSet(flag) {
143+
var err error
144+
data, err = sjson.SetBytes(data, path, cmd.Value(flag))
145+
if err != nil {
146+
return err
147+
}
148+
}
149+
}
150+
151+
if data != nil {
152+
if err := unmarshalWithReaders(data, target); err != nil {
153+
return fmt.Errorf("failed to unmarshal JSON: %w", err)
154+
}
155+
}
156+
157+
return nil
158+
}
159+
160+
func debugMiddleware(debug bool) option.Middleware {
161+
return func(r *http.Request, mn option.MiddlewareNext) (*http.Response, error) {
162+
if debug {
163+
logger := log.Default()
164+
165+
if reqBytes, err := httputil.DumpRequest(r, true); err == nil {
166+
logger.Printf("Request Content:\n%s\n", reqBytes)
167+
}
168+
169+
resp, err := mn(r)
170+
if err != nil {
171+
return resp, err
172+
}
173+
174+
if respBytes, err := httputil.DumpResponse(resp, true); err == nil {
175+
logger.Printf("Response Content:\n%s\n", respBytes)
176+
}
177+
178+
return resp, err
179+
}
180+
181+
return mn(r)
182+
}
183+
}
184+
185+
func isInputPiped() bool {
186+
stat, _ := os.Stdin.Stat()
187+
return (stat.Mode() & os.ModeCharDevice) == 0
188+
}
189+
190+
func isTerminal(w io.Writer) bool {
191+
switch v := w.(type) {
192+
case *os.File:
193+
return term.IsTerminal(int(v.Fd()))
194+
default:
195+
return false
196+
}
197+
}
198+
199+
func shouldUseColors(w io.Writer) bool {
200+
force, ok := os.LookupEnv("FORCE_COLOR")
201+
202+
if ok {
203+
if force == "1" {
204+
return true
205+
}
206+
if force == "0" {
207+
return false
208+
}
209+
}
210+
211+
return isTerminal(w)
212+
}
213+
214+
func ShowJSON(title string, res gjson.Result, format string, transform string) error {
215+
if format != "raw" && transform != "" {
216+
transformed := res.Get(transform)
217+
if transformed.Exists() {
218+
res = transformed
219+
}
220+
}
221+
switch strings.ToLower(format) {
222+
case "auto":
223+
return ShowJSON(title, res, "json", "")
224+
case "explore":
225+
return jsonview.ExploreJSON(title, res)
226+
case "pretty":
227+
jsonview.DisplayJSON(title, res)
228+
return nil
229+
case "json":
230+
prettyJSON := pretty.Pretty([]byte(res.Raw))
231+
if shouldUseColors(os.Stdout) {
232+
fmt.Print(string(pretty.Color(prettyJSON, pretty.TerminalStyle)))
233+
} else {
234+
fmt.Print(string(prettyJSON))
235+
}
236+
return nil
237+
case "raw":
238+
fmt.Println(res.Raw)
239+
return nil
240+
case "yaml":
241+
input := strings.NewReader(res.Raw)
242+
var yaml strings.Builder
243+
if err := json2yaml.Convert(&yaml, input); err != nil {
244+
return err
245+
}
246+
fmt.Print(yaml.String())
247+
return nil
248+
default:
249+
return fmt.Errorf("Invalid format: %s, valid formats are: %s", format, strings.Join(OutputFormats, ", "))
250+
}
251+
}

0 commit comments

Comments
 (0)