Skip to content

Commit dafa40f

Browse files
feat(cli): automatic streaming for paginated endpoints
1 parent 4e96ad8 commit dafa40f

31 files changed

+812
-548
lines changed

cmd/dodopayments/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func main() {
2222
fmt.Fprintf(os.Stderr, "%s %q: %d %s\n", apierr.Request.Method, apierr.Request.URL, apierr.Response.StatusCode, http.StatusText(apierr.Response.StatusCode))
2323
format := app.String("format-error")
2424
json := gjson.Parse(apierr.JSON.RawJSON())
25-
show_err := cmd.ShowJSON("Error", json, format, app.String("transform-error"))
25+
show_err := cmd.ShowJSON(os.Stdout, "Error", json, format, app.String("transform-error"))
2626
if show_err != nil {
2727
// Just print the original error:
2828
fmt.Fprintf(os.Stderr, "%s\n", err.Error())

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/tidwall/pretty v1.2.1
1616
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
1717
github.com/urfave/cli/v3 v3.3.2
18+
golang.org/x/sys v0.38.0
1819
golang.org/x/term v0.37.0
1920
)
2021

@@ -39,6 +40,5 @@ require (
3940
github.com/tidwall/sjson v1.2.5 // indirect
4041
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
4142
golang.org/x/sync v0.15.0 // indirect
42-
golang.org/x/sys v0.38.0 // indirect
4343
golang.org/x/text v0.3.8 // indirect
4444
)

pkg/cmd/addon.go

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package cmd
55
import (
66
"context"
77
"fmt"
8+
"os"
89

910
"github.com/dodopayments/dodopayments-cli/internal/apiquery"
1011
"github.com/dodopayments/dodopayments-cli/internal/requestflag"
@@ -160,6 +161,7 @@ var addonsUpdateImages = cli.Command{
160161
func handleAddonsCreate(ctx context.Context, cmd *cli.Command) error {
161162
client := dodopayments.NewClient(getDefaultRequestOptions(cmd)...)
162163
unusedArgs := cmd.Args().Slice()
164+
163165
if len(unusedArgs) > 0 {
164166
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
165167
}
@@ -174,21 +176,18 @@ func handleAddonsCreate(ctx context.Context, cmd *cli.Command) error {
174176
if err != nil {
175177
return err
176178
}
179+
177180
var res []byte
178181
options = append(options, option.WithResponseBodyInto(&res))
179-
_, err = client.Addons.New(
180-
ctx,
181-
params,
182-
options...,
183-
)
182+
_, err = client.Addons.New(ctx, params, options...)
184183
if err != nil {
185184
return err
186185
}
187186

188-
json := gjson.Parse(string(res))
187+
obj := gjson.ParseBytes(res)
189188
format := cmd.Root().String("format")
190189
transform := cmd.Root().String("transform")
191-
return ShowJSON("addons create", json, format, transform)
190+
return ShowJSON(os.Stdout, "addons create", obj, format, transform)
192191
}
193192

194193
func handleAddonsRetrieve(ctx context.Context, cmd *cli.Command) error {
@@ -210,21 +209,18 @@ func handleAddonsRetrieve(ctx context.Context, cmd *cli.Command) error {
210209
if err != nil {
211210
return err
212211
}
212+
213213
var res []byte
214214
options = append(options, option.WithResponseBodyInto(&res))
215-
_, err = client.Addons.Get(
216-
ctx,
217-
requestflag.CommandRequestValue[string](cmd, "id"),
218-
options...,
219-
)
215+
_, err = client.Addons.Get(ctx, requestflag.CommandRequestValue[string](cmd, "id"), options...)
220216
if err != nil {
221217
return err
222218
}
223219

224-
json := gjson.Parse(string(res))
220+
obj := gjson.ParseBytes(res)
225221
format := cmd.Root().String("format")
226222
transform := cmd.Root().String("transform")
227-
return ShowJSON("addons retrieve", json, format, transform)
223+
return ShowJSON(os.Stdout, "addons retrieve", obj, format, transform)
228224
}
229225

230226
func handleAddonsUpdate(ctx context.Context, cmd *cli.Command) error {
@@ -248,6 +244,7 @@ func handleAddonsUpdate(ctx context.Context, cmd *cli.Command) error {
248244
if err != nil {
249245
return err
250246
}
247+
251248
var res []byte
252249
options = append(options, option.WithResponseBodyInto(&res))
253250
_, err = client.Addons.Update(
@@ -260,15 +257,16 @@ func handleAddonsUpdate(ctx context.Context, cmd *cli.Command) error {
260257
return err
261258
}
262259

263-
json := gjson.Parse(string(res))
260+
obj := gjson.ParseBytes(res)
264261
format := cmd.Root().String("format")
265262
transform := cmd.Root().String("transform")
266-
return ShowJSON("addons update", json, format, transform)
263+
return ShowJSON(os.Stdout, "addons update", obj, format, transform)
267264
}
268265

269266
func handleAddonsList(ctx context.Context, cmd *cli.Command) error {
270267
client := dodopayments.NewClient(getDefaultRequestOptions(cmd)...)
271268
unusedArgs := cmd.Args().Slice()
269+
272270
if len(unusedArgs) > 0 {
273271
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
274272
}
@@ -283,21 +281,31 @@ func handleAddonsList(ctx context.Context, cmd *cli.Command) error {
283281
if err != nil {
284282
return err
285283
}
286-
var res []byte
287-
options = append(options, option.WithResponseBodyInto(&res))
288-
_, err = client.Addons.List(
289-
ctx,
290-
params,
291-
options...,
292-
)
293-
if err != nil {
294-
return err
295-
}
296284

297-
json := gjson.Parse(string(res))
298285
format := cmd.Root().String("format")
299286
transform := cmd.Root().String("transform")
300-
return ShowJSON("addons list", json, format, transform)
287+
if format == "raw" {
288+
var res []byte
289+
options = append(options, option.WithResponseBodyInto(&res))
290+
_, err = client.Addons.List(ctx, params, options...)
291+
if err != nil {
292+
return err
293+
}
294+
obj := gjson.ParseBytes(res)
295+
return ShowJSON(os.Stdout, "addons list", obj, format, transform)
296+
} else {
297+
iter := client.Addons.ListAutoPaging(ctx, params, options...)
298+
return streamOutput("addons list", func(w *os.File) error {
299+
for iter.Next() {
300+
item := iter.Current()
301+
obj := gjson.Parse(item.JSON.RawJSON())
302+
if err := ShowJSON(w, "addons list", obj, format, transform); err != nil {
303+
return err
304+
}
305+
}
306+
return iter.Err()
307+
})
308+
}
301309
}
302310

303311
func handleAddonsUpdateImages(ctx context.Context, cmd *cli.Command) error {
@@ -319,19 +327,16 @@ func handleAddonsUpdateImages(ctx context.Context, cmd *cli.Command) error {
319327
if err != nil {
320328
return err
321329
}
330+
322331
var res []byte
323332
options = append(options, option.WithResponseBodyInto(&res))
324-
_, err = client.Addons.UpdateImages(
325-
ctx,
326-
requestflag.CommandRequestValue[string](cmd, "id"),
327-
options...,
328-
)
333+
_, err = client.Addons.UpdateImages(ctx, requestflag.CommandRequestValue[string](cmd, "id"), options...)
329334
if err != nil {
330335
return err
331336
}
332337

333-
json := gjson.Parse(string(res))
338+
obj := gjson.ParseBytes(res)
334339
format := cmd.Root().String("format")
335340
transform := cmd.Root().String("transform")
336-
return ShowJSON("addons update-images", json, format, transform)
341+
return ShowJSON(os.Stdout, "addons update-images", obj, format, transform)
337342
}

pkg/cmd/brand.go

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package cmd
55
import (
66
"context"
77
"fmt"
8+
"os"
89

910
"github.com/dodopayments/dodopayments-cli/internal/apiquery"
1011
"github.com/dodopayments/dodopayments-cli/internal/requestflag"
@@ -125,6 +126,7 @@ var brandsUpdateImages = cli.Command{
125126
func handleBrandsCreate(ctx context.Context, cmd *cli.Command) error {
126127
client := dodopayments.NewClient(getDefaultRequestOptions(cmd)...)
127128
unusedArgs := cmd.Args().Slice()
129+
128130
if len(unusedArgs) > 0 {
129131
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
130132
}
@@ -139,21 +141,18 @@ func handleBrandsCreate(ctx context.Context, cmd *cli.Command) error {
139141
if err != nil {
140142
return err
141143
}
144+
142145
var res []byte
143146
options = append(options, option.WithResponseBodyInto(&res))
144-
_, err = client.Brands.New(
145-
ctx,
146-
params,
147-
options...,
148-
)
147+
_, err = client.Brands.New(ctx, params, options...)
149148
if err != nil {
150149
return err
151150
}
152151

153-
json := gjson.Parse(string(res))
152+
obj := gjson.ParseBytes(res)
154153
format := cmd.Root().String("format")
155154
transform := cmd.Root().String("transform")
156-
return ShowJSON("brands create", json, format, transform)
155+
return ShowJSON(os.Stdout, "brands create", obj, format, transform)
157156
}
158157

159158
func handleBrandsRetrieve(ctx context.Context, cmd *cli.Command) error {
@@ -175,21 +174,18 @@ func handleBrandsRetrieve(ctx context.Context, cmd *cli.Command) error {
175174
if err != nil {
176175
return err
177176
}
177+
178178
var res []byte
179179
options = append(options, option.WithResponseBodyInto(&res))
180-
_, err = client.Brands.Get(
181-
ctx,
182-
requestflag.CommandRequestValue[string](cmd, "id"),
183-
options...,
184-
)
180+
_, err = client.Brands.Get(ctx, requestflag.CommandRequestValue[string](cmd, "id"), options...)
185181
if err != nil {
186182
return err
187183
}
188184

189-
json := gjson.Parse(string(res))
185+
obj := gjson.ParseBytes(res)
190186
format := cmd.Root().String("format")
191187
transform := cmd.Root().String("transform")
192-
return ShowJSON("brands retrieve", json, format, transform)
188+
return ShowJSON(os.Stdout, "brands retrieve", obj, format, transform)
193189
}
194190

195191
func handleBrandsUpdate(ctx context.Context, cmd *cli.Command) error {
@@ -213,6 +209,7 @@ func handleBrandsUpdate(ctx context.Context, cmd *cli.Command) error {
213209
if err != nil {
214210
return err
215211
}
212+
216213
var res []byte
217214
options = append(options, option.WithResponseBodyInto(&res))
218215
_, err = client.Brands.Update(
@@ -225,15 +222,16 @@ func handleBrandsUpdate(ctx context.Context, cmd *cli.Command) error {
225222
return err
226223
}
227224

228-
json := gjson.Parse(string(res))
225+
obj := gjson.ParseBytes(res)
229226
format := cmd.Root().String("format")
230227
transform := cmd.Root().String("transform")
231-
return ShowJSON("brands update", json, format, transform)
228+
return ShowJSON(os.Stdout, "brands update", obj, format, transform)
232229
}
233230

234231
func handleBrandsList(ctx context.Context, cmd *cli.Command) error {
235232
client := dodopayments.NewClient(getDefaultRequestOptions(cmd)...)
236233
unusedArgs := cmd.Args().Slice()
234+
237235
if len(unusedArgs) > 0 {
238236
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
239237
}
@@ -246,17 +244,18 @@ func handleBrandsList(ctx context.Context, cmd *cli.Command) error {
246244
if err != nil {
247245
return err
248246
}
247+
249248
var res []byte
250249
options = append(options, option.WithResponseBodyInto(&res))
251250
_, err = client.Brands.List(ctx, options...)
252251
if err != nil {
253252
return err
254253
}
255254

256-
json := gjson.Parse(string(res))
255+
obj := gjson.ParseBytes(res)
257256
format := cmd.Root().String("format")
258257
transform := cmd.Root().String("transform")
259-
return ShowJSON("brands list", json, format, transform)
258+
return ShowJSON(os.Stdout, "brands list", obj, format, transform)
260259
}
261260

262261
func handleBrandsUpdateImages(ctx context.Context, cmd *cli.Command) error {
@@ -278,19 +277,16 @@ func handleBrandsUpdateImages(ctx context.Context, cmd *cli.Command) error {
278277
if err != nil {
279278
return err
280279
}
280+
281281
var res []byte
282282
options = append(options, option.WithResponseBodyInto(&res))
283-
_, err = client.Brands.UpdateImages(
284-
ctx,
285-
requestflag.CommandRequestValue[string](cmd, "id"),
286-
options...,
287-
)
283+
_, err = client.Brands.UpdateImages(ctx, requestflag.CommandRequestValue[string](cmd, "id"), options...)
288284
if err != nil {
289285
return err
290286
}
291287

292-
json := gjson.Parse(string(res))
288+
obj := gjson.ParseBytes(res)
293289
format := cmd.Root().String("format")
294290
transform := cmd.Root().String("transform")
295-
return ShowJSON("brands update-images", json, format, transform)
291+
return ShowJSON(os.Stdout, "brands update-images", obj, format, transform)
296292
}

pkg/cmd/checkoutsession.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package cmd
55
import (
66
"context"
77
"fmt"
8+
"os"
89

910
"github.com/dodopayments/dodopayments-cli/internal/apiquery"
1011
"github.com/dodopayments/dodopayments-cli/internal/requestflag"
@@ -130,6 +131,7 @@ var checkoutSessionsRetrieve = cli.Command{
130131
func handleCheckoutSessionsCreate(ctx context.Context, cmd *cli.Command) error {
131132
client := dodopayments.NewClient(getDefaultRequestOptions(cmd)...)
132133
unusedArgs := cmd.Args().Slice()
134+
133135
if len(unusedArgs) > 0 {
134136
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
135137
}
@@ -144,21 +146,18 @@ func handleCheckoutSessionsCreate(ctx context.Context, cmd *cli.Command) error {
144146
if err != nil {
145147
return err
146148
}
149+
147150
var res []byte
148151
options = append(options, option.WithResponseBodyInto(&res))
149-
_, err = client.CheckoutSessions.New(
150-
ctx,
151-
params,
152-
options...,
153-
)
152+
_, err = client.CheckoutSessions.New(ctx, params, options...)
154153
if err != nil {
155154
return err
156155
}
157156

158-
json := gjson.Parse(string(res))
157+
obj := gjson.ParseBytes(res)
159158
format := cmd.Root().String("format")
160159
transform := cmd.Root().String("transform")
161-
return ShowJSON("checkout-sessions create", json, format, transform)
160+
return ShowJSON(os.Stdout, "checkout-sessions create", obj, format, transform)
162161
}
163162

164163
func handleCheckoutSessionsRetrieve(ctx context.Context, cmd *cli.Command) error {
@@ -180,19 +179,16 @@ func handleCheckoutSessionsRetrieve(ctx context.Context, cmd *cli.Command) error
180179
if err != nil {
181180
return err
182181
}
182+
183183
var res []byte
184184
options = append(options, option.WithResponseBodyInto(&res))
185-
_, err = client.CheckoutSessions.Get(
186-
ctx,
187-
requestflag.CommandRequestValue[string](cmd, "id"),
188-
options...,
189-
)
185+
_, err = client.CheckoutSessions.Get(ctx, requestflag.CommandRequestValue[string](cmd, "id"), options...)
190186
if err != nil {
191187
return err
192188
}
193189

194-
json := gjson.Parse(string(res))
190+
obj := gjson.ParseBytes(res)
195191
format := cmd.Root().String("format")
196192
transform := cmd.Root().String("transform")
197-
return ShowJSON("checkout-sessions retrieve", json, format, transform)
193+
return ShowJSON(os.Stdout, "checkout-sessions retrieve", obj, format, transform)
198194
}

0 commit comments

Comments
 (0)