@redocly/cli 0.0.0-snapshot.1787132334 → 0.0.0-snapshot.1787213166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/lib/chunks/3DFTNVIZ.js +875 -0
  2. package/lib/chunks/3GFYSU6P.js +7 -0
  3. package/lib/chunks/3J7TYMNY.js +12 -0
  4. package/lib/chunks/3XBPOSEL.js +9 -0
  5. package/lib/chunks/437JJBFI.js +9 -0
  6. package/lib/chunks/43GCSHRC.js +2669 -0
  7. package/lib/chunks/5CNLBXMA.js +7 -0
  8. package/lib/chunks/{INO3K4ZT.js → 5UA5LBQR.js} +1 -1
  9. package/lib/chunks/633P7WGD.js +7 -0
  10. package/lib/chunks/66SRVT5P.js +7 -0
  11. package/lib/chunks/6XZCMSUQ.js +7 -0
  12. package/lib/chunks/A66YYMVS.js +519 -0
  13. package/lib/chunks/ATNTAOVB.js +21 -0
  14. package/lib/chunks/BDG6IUCF.js +12 -0
  15. package/lib/chunks/BKWLBNAY.js +8 -0
  16. package/lib/chunks/CYTKNF4B.js +32 -0
  17. package/lib/chunks/D63AL5JQ.js +7 -0
  18. package/lib/chunks/DSV3ACCR.js +9 -0
  19. package/lib/chunks/DXLDMRME.js +7 -0
  20. package/lib/chunks/FLFI42AS.js +41 -0
  21. package/lib/chunks/{GAJNF7OK.js → G7Q7L6SS.js} +1 -1
  22. package/lib/chunks/GFUSM635.js +7 -0
  23. package/lib/chunks/GRNUYN6X.js +7 -0
  24. package/lib/chunks/{X6Q5KQDP.js → GTSJ3BAP.js} +1 -1
  25. package/lib/chunks/{A7WPX7IN.js → HX2FFDOL.js} +1 -1
  26. package/lib/chunks/{JWE6N3HA.js → IFGW4ORS.js} +1 -1
  27. package/lib/chunks/{L2KDP4QO.js → IFQUUR3G.js} +1 -1
  28. package/lib/chunks/IHICMXLQ.js +7 -0
  29. package/lib/chunks/IWSGIYUF.js +7 -0
  30. package/lib/chunks/J5UU3PWO.js +7 -0
  31. package/lib/chunks/JAEMYDV4.js +18 -0
  32. package/lib/chunks/{BCMHACSX.js → JIXLIIZV.js} +1 -1
  33. package/lib/chunks/JKEX4O5F.js +7 -0
  34. package/lib/chunks/{62EHE3FD.js → JNERJ3VR.js} +2 -2
  35. package/lib/chunks/{N264HAKF.js → JSYUI5YX.js} +1 -1
  36. package/lib/chunks/JWWD4Q3V.js +176 -0
  37. package/lib/chunks/K4VSUIRV.js +7 -0
  38. package/lib/chunks/L5QMCITI.js +460 -0
  39. package/lib/chunks/L6CYFTBX.js +7 -0
  40. package/lib/chunks/M3JDOVCW.js +911 -0
  41. package/lib/chunks/{5VPVDCTR.js → NBYGLUQF.js} +1 -1
  42. package/lib/chunks/{FOZ2GXNX.js → NY3X26BD.js} +1 -1
  43. package/lib/chunks/OSMFPTOV.js +7 -0
  44. package/lib/chunks/QOHNT5HA.js +7 -0
  45. package/lib/chunks/R7X55KCC.js +7 -0
  46. package/lib/chunks/{LSZDC6IW.js → S4I2R55X.js} +1 -1
  47. package/lib/chunks/{43QLIHPO.js → SKPLCW2A.js} +1 -1
  48. package/lib/chunks/T6AYNJRF.js +184 -0
  49. package/lib/chunks/VYAPZWZF.js +13 -0
  50. package/lib/chunks/{BBUY2DN4.js → WXUTF626.js} +1 -1
  51. package/lib/chunks/XICBZCC4.js +48 -0
  52. package/lib/chunks/XOCXUWKN.js +71 -0
  53. package/lib/chunks/XSPNMYMZ.js +15 -0
  54. package/lib/chunks/{JTBULWP6.js → YBSUKQHU.js} +1 -1
  55. package/lib/chunks/YSMUBJCG.js +7 -0
  56. package/lib/chunks/{VEENOHE7.js → YUFGUVRF.js} +1 -1
  57. package/lib/chunks/ZTS6JG4V.js +7 -0
  58. package/lib/eject-assets/AGENTS.md +131 -0
  59. package/lib/eject-assets/generators/cli.mjs +796 -0
  60. package/lib/eject-assets/generators/go.mjs +866 -0
  61. package/lib/eject-assets/generators/mock.mjs +689 -0
  62. package/lib/eject-assets/generators/php.mjs +840 -0
  63. package/lib/eject-assets/generators/python.mjs +823 -0
  64. package/lib/eject-assets/generators/swr.mjs +193 -0
  65. package/lib/eject-assets/generators/tanstack-query.mjs +626 -0
  66. package/lib/eject-assets/generators/transformers.mjs +403 -0
  67. package/lib/eject-assets/generators/typescript.mjs +1821 -0
  68. package/lib/eject-assets/generators/zod.mjs +520 -0
  69. package/lib/eject-assets/skills/cli-generator/SKILL.md +112 -0
  70. package/lib/eject-assets/skills/client-generators/SKILL.md +136 -0
  71. package/lib/eject-assets/skills/go-generator/SKILL.md +94 -0
  72. package/lib/eject-assets/skills/mock-generator/SKILL.md +45 -0
  73. package/lib/eject-assets/skills/php-generator/SKILL.md +110 -0
  74. package/lib/eject-assets/skills/python-generator/SKILL.md +108 -0
  75. package/lib/eject-assets/skills/swr-generator/SKILL.md +44 -0
  76. package/lib/eject-assets/skills/tanstack-query-generator/SKILL.md +48 -0
  77. package/lib/eject-assets/skills/transformers-generator/SKILL.md +43 -0
  78. package/lib/eject-assets/skills/typescript-generator/SKILL.md +80 -0
  79. package/lib/eject-assets/skills/zod-generator/SKILL.md +49 -0
  80. package/lib/index.js +265 -232
  81. package/package.json +1 -1
  82. package/lib/chunks/7RS7GK5N.js +0 -8
  83. package/lib/chunks/N5E3KSKU.js +0 -2542
  84. package/lib/chunks/SJZFGAFW.js +0 -187
@@ -0,0 +1,875 @@
1
+ import { createRequire as __createRequire } from 'node:module';
2
+ import { fileURLToPath as __fileURLToPath } from 'node:url';
3
+ import { dirname as __pathDirname } from 'node:path';
4
+ const require = __createRequire(import.meta.url);
5
+ var __filename = __fileURLToPath(import.meta.url);
6
+ var __dirname = __pathDirname(__filename);
7
+ import{a as C,b as I,c as U}from"./VYAPZWZF.js";import{a as P}from"./WZXA5XPB.js";import{a as D,b as T,c as $,d as E,e as q,f as x,g as L,h as A,i as J,j as B,k as H,l as M}from"./L6CYFTBX.js";var j=`// Package client \u2014 the embedded runtime for generated Go SDKs. Hand-authored
8
+ // once and stitched into every generated client (see
9
+ // scripts/generate-runtime-sources.mjs), semantically in lockstep with the
10
+ // TypeScript runtime: auth OR-alternatives, a retry loop with Retry-After and
11
+ // full-jitter backoff, per-attempt timeouts, idempotency keys, and middleware
12
+ // hooks. Standard library only \u2014 a generated Go SDK has zero dependencies.
13
+ package client
14
+
15
+ import (
16
+ "bytes"
17
+ "context"
18
+ "encoding/base64"
19
+ "encoding/json"
20
+ "errors"
21
+ "fmt"
22
+ "io"
23
+ "math/rand"
24
+ "mime/multipart"
25
+ "net/http"
26
+ "net/url"
27
+ "strconv"
28
+ "strings"
29
+ "time"
30
+ )
31
+
32
+ // APIError is returned for a non-2xx response, carrying the decoded error body.
33
+ type APIError struct {
34
+ URL string
35
+ Status int
36
+ StatusText string
37
+ Body any
38
+ }
39
+
40
+ func (e *APIError) Error() string {
41
+ return fmt.Sprintf("request failed with status %d", e.Status)
42
+ }
43
+
44
+ // TimeoutError is returned when a request attempt exceeds the configured
45
+ // timeout \u2014 carrying the context a log line needs.
46
+ type TimeoutError struct {
47
+ OperationID string
48
+ Timeout time.Duration
49
+ Attempt int
50
+ }
51
+
52
+ func (e *TimeoutError) Error() string {
53
+ return fmt.Sprintf("request %q timed out after %s (attempt %d)", e.OperationID, e.Timeout, e.Attempt)
54
+ }
55
+
56
+ // SecuritySpec mirrors the descriptor table's security entries.
57
+ type SecuritySpec struct {
58
+ Scheme string
59
+ Kind string // "bearer" | "basic" | "apiKey"
60
+ Name string // header/query/cookie name for apiKey
61
+ In string // "header" | "query" | "cookie"
62
+ }
63
+
64
+ // Auth holds the client credentials; zero value = anonymous.
65
+ type Auth struct {
66
+ Bearer func() string
67
+ Basic *BasicAuth
68
+ APIKey map[string]func() string
69
+ }
70
+
71
+ type BasicAuth struct {
72
+ Username string
73
+ Password string
74
+ }
75
+
76
+ // RetryConfig mirrors the TypeScript runtime's retry policy knobs.
77
+ type RetryConfig struct {
78
+ Retries int
79
+ RetryDelay time.Duration // base; default 1s
80
+ RetryStrategy string // "" (exponential) | "fixed"
81
+ NoJitter bool
82
+ // RetryOn fully replaces the default predicate when set.
83
+ RetryOn func(attempt int, resp *http.Response, err error) bool
84
+ }
85
+
86
+ // Middleware hooks run around every request (OnRequest before serialization order
87
+ // is N/A in Go \u2014 bodies are values; OnResponse runs in reverse registration order).
88
+ type Middleware struct {
89
+ OnRequest func(req *http.Request)
90
+ OnResponse func(resp *http.Response)
91
+ }
92
+
93
+ // Date is an RFC 3339 full-date \u2014 a calendar date with no time component. Fields
94
+ // typed \`date\` under \`dateType: Date\` use it because encoding/json speaks only
95
+ // RFC 3339 date-time for time.Time, which a bare "2006-01-02" fails to satisfy.
96
+ type Date struct {
97
+ time.Time
98
+ }
99
+
100
+ const dateLayout = "2006-01-02"
101
+
102
+ // UnmarshalJSON parses a "2006-01-02" string; an empty string leaves the zero value.
103
+ func (d *Date) UnmarshalJSON(data []byte) error {
104
+ var raw string
105
+ if err := json.Unmarshal(data, &raw); err != nil {
106
+ return err
107
+ }
108
+ if raw == "" {
109
+ return nil
110
+ }
111
+ parsed, err := time.Parse(dateLayout, raw)
112
+ if err != nil {
113
+ return err
114
+ }
115
+ d.Time = parsed
116
+ return nil
117
+ }
118
+
119
+ // MarshalJSON writes the date back without a time component.
120
+ func (d Date) MarshalJSON() ([]byte, error) {
121
+ return json.Marshal(d.Format(dateLayout))
122
+ }
123
+
124
+ // Config is the per-client configuration shared by every operation method.
125
+ type Config struct {
126
+ ServerURL string
127
+ HTTPClient *http.Client
128
+ Headers map[string]string
129
+ Timeout time.Duration
130
+ Retry RetryConfig
131
+ Middleware []Middleware
132
+ IdempotencyKey func() string
133
+ Auth Auth
134
+ }
135
+
136
+ func resolveToken(provider func() string) string {
137
+ if provider == nil {
138
+ return ""
139
+ }
140
+ return provider()
141
+ }
142
+
143
+ func schemeConfigured(spec SecuritySpec, auth Auth) bool {
144
+ switch spec.Kind {
145
+ case "apiKey":
146
+ _, ok := auth.APIKey[spec.Scheme]
147
+ return ok
148
+ case "bearer":
149
+ return auth.Bearer != nil
150
+ default:
151
+ return auth.Basic != nil
152
+ }
153
+ }
154
+
155
+ // resolveAuth applies the first fully-configured OR-alternative; when none is,
156
+ // the first alternative's configured schemes are still sent (the server rejects
157
+ // the request \u2014 same behavior as the TypeScript runtime).
158
+ func resolveAuth(security [][]SecuritySpec, auth Auth) (map[string]string, url.Values) {
159
+ headers := map[string]string{}
160
+ query := url.Values{}
161
+ if len(security) == 0 {
162
+ return headers, query
163
+ }
164
+ alternative := security[0]
165
+ for _, candidate := range security {
166
+ all := true
167
+ for _, spec := range candidate {
168
+ if !schemeConfigured(spec, auth) {
169
+ all = false
170
+ break
171
+ }
172
+ }
173
+ if all {
174
+ alternative = candidate
175
+ break
176
+ }
177
+ }
178
+ var cookies []string
179
+ for _, spec := range alternative {
180
+ switch spec.Kind {
181
+ case "apiKey":
182
+ provider, ok := auth.APIKey[spec.Scheme]
183
+ if !ok {
184
+ continue
185
+ }
186
+ value := resolveToken(provider)
187
+ switch spec.In {
188
+ case "query":
189
+ query.Set(spec.Name, value)
190
+ case "cookie":
191
+ cookies = append(cookies, spec.Name+"="+url.QueryEscape(value))
192
+ default:
193
+ headers[spec.Name] = value
194
+ }
195
+ case "bearer":
196
+ if auth.Bearer != nil {
197
+ headers["Authorization"] = "Bearer " + resolveToken(auth.Bearer)
198
+ }
199
+ default:
200
+ if auth.Basic != nil {
201
+ token := base64.StdEncoding.EncodeToString([]byte(auth.Basic.Username + ":" + auth.Basic.Password))
202
+ headers["Authorization"] = "Basic " + token
203
+ }
204
+ }
205
+ }
206
+ if len(cookies) > 0 {
207
+ headers["Cookie"] = strings.Join(cookies, "; ")
208
+ }
209
+ return headers, query
210
+ }
211
+
212
+ // buildURL substitutes {param} path placeholders with percent-encoded values.
213
+ func buildURL(serverURL, path string, pathParams map[string]string) string {
214
+ filled := path
215
+ for name, value := range pathParams {
216
+ filled = strings.ReplaceAll(filled, "{"+name+"}", url.PathEscape(value))
217
+ }
218
+ return strings.TrimRight(serverURL, "/") + filled
219
+ }
220
+
221
+ var transientStatus = map[int]bool{408: true, 429: true, 500: true, 502: true, 503: true, 504: true}
222
+
223
+ func defaultRetryOn(method string, headers map[string]string, resp *http.Response, err error) bool {
224
+ safe := false
225
+ switch strings.ToUpper(method) {
226
+ case "GET", "HEAD", "PUT", "DELETE", "OPTIONS":
227
+ safe = true
228
+ }
229
+ if _, ok := headers["Idempotency-Key"]; ok {
230
+ safe = true
231
+ }
232
+ if !safe {
233
+ return false
234
+ }
235
+ if err != nil {
236
+ return true
237
+ }
238
+ return resp != nil && transientStatus[resp.StatusCode]
239
+ }
240
+
241
+ func retryDelay(retry RetryConfig, attempt int, retryAfter string) time.Duration {
242
+ if retryAfter != "" {
243
+ if seconds, err := strconv.ParseFloat(retryAfter, 64); err == nil {
244
+ return time.Duration(seconds * float64(time.Second))
245
+ }
246
+ }
247
+ base := retry.RetryDelay
248
+ if base == 0 {
249
+ base = time.Second
250
+ }
251
+ raw := base
252
+ if retry.RetryStrategy != "fixed" {
253
+ raw = base * time.Duration(1<<(attempt-1))
254
+ }
255
+ if retry.NoJitter {
256
+ return raw
257
+ }
258
+ return time.Duration(rand.Int63n(int64(raw) + 1))
259
+ }
260
+
261
+ type requestSpec struct {
262
+ OperationID string
263
+ Method string
264
+ URL string
265
+ Headers map[string]string
266
+ Query url.Values
267
+ Body io.Reader
268
+ ContentType string
269
+ Timeout time.Duration
270
+ Retry *RetryConfig
271
+ IdempotencyKey string
272
+ // bodyBytes is retained so retries can replay the body.
273
+ bodyBytes []byte
274
+ }
275
+
276
+ // send is the request core: header merge, idempotency keys, the retry loop
277
+ // (fresh timeout budget per attempt), and the middleware onion.
278
+ func send(ctx context.Context, config *Config, spec requestSpec) (*http.Response, error) {
279
+ retry := config.Retry
280
+ if spec.Retry != nil {
281
+ retry = *spec.Retry
282
+ }
283
+ timeout := config.Timeout
284
+ if spec.Timeout != 0 {
285
+ timeout = spec.Timeout
286
+ }
287
+ headers := map[string]string{}
288
+ for key, value := range config.Headers {
289
+ headers[key] = value
290
+ }
291
+ for key, value := range spec.Headers {
292
+ headers[key] = value
293
+ }
294
+ method := strings.ToUpper(spec.Method)
295
+ if (method == "POST" || method == "PATCH") && headers["Idempotency-Key"] == "" {
296
+ if spec.IdempotencyKey != "" {
297
+ headers["Idempotency-Key"] = spec.IdempotencyKey
298
+ } else if config.IdempotencyKey != nil {
299
+ headers["Idempotency-Key"] = config.IdempotencyKey()
300
+ }
301
+ }
302
+ httpClient := config.HTTPClient
303
+ if httpClient == nil {
304
+ httpClient = http.DefaultClient
305
+ }
306
+ if spec.Body != nil {
307
+ payload, err := io.ReadAll(spec.Body)
308
+ if err != nil {
309
+ return nil, err
310
+ }
311
+ spec.bodyBytes = payload
312
+ }
313
+ fullURL := spec.URL
314
+ if len(spec.Query) > 0 {
315
+ separator := "?"
316
+ if strings.Contains(fullURL, "?") {
317
+ separator = "&"
318
+ }
319
+ fullURL += separator + spec.Query.Encode()
320
+ }
321
+ maxAttempts := 1 + retry.Retries
322
+ for attempt := 1; ; attempt++ {
323
+ attemptCtx := ctx
324
+ var cancel context.CancelFunc
325
+ if timeout > 0 {
326
+ attemptCtx, cancel = context.WithTimeout(ctx, timeout)
327
+ }
328
+ var bodyReader io.Reader
329
+ if spec.bodyBytes != nil {
330
+ bodyReader = bytes.NewReader(spec.bodyBytes)
331
+ }
332
+ req, err := http.NewRequestWithContext(attemptCtx, method, fullURL, bodyReader)
333
+ if err != nil {
334
+ if cancel != nil {
335
+ cancel()
336
+ }
337
+ return nil, err
338
+ }
339
+ for key, value := range headers {
340
+ req.Header.Set(key, value)
341
+ }
342
+ if spec.ContentType != "" && spec.bodyBytes != nil {
343
+ req.Header.Set("Content-Type", spec.ContentType)
344
+ }
345
+ for _, mw := range config.Middleware {
346
+ if mw.OnRequest != nil {
347
+ mw.OnRequest(req)
348
+ }
349
+ }
350
+ resp, err := httpClient.Do(req)
351
+ shouldRetry := retry.RetryOn
352
+ retryable := false
353
+ if shouldRetry != nil {
354
+ retryable = shouldRetry(attempt, resp, err)
355
+ } else {
356
+ retryable = defaultRetryOn(method, headers, resp, err)
357
+ }
358
+ if err != nil {
359
+ if cancel != nil {
360
+ cancel()
361
+ }
362
+ timedOut := errors.Is(err, context.DeadlineExceeded) && ctx.Err() == nil
363
+ if attempt < maxAttempts && retryable {
364
+ time.Sleep(retryDelay(retry, attempt, ""))
365
+ continue
366
+ }
367
+ if timedOut {
368
+ return nil, &TimeoutError{OperationID: spec.OperationID, Timeout: timeout, Attempt: attempt}
369
+ }
370
+ return nil, err
371
+ }
372
+ for i := len(config.Middleware) - 1; i >= 0; i-- {
373
+ if config.Middleware[i].OnResponse != nil {
374
+ config.Middleware[i].OnResponse(resp)
375
+ }
376
+ }
377
+ if resp.StatusCode >= 400 && attempt < maxAttempts && retryable {
378
+ after := resp.Header.Get("Retry-After")
379
+ io.Copy(io.Discard, resp.Body)
380
+ resp.Body.Close()
381
+ if cancel != nil {
382
+ cancel()
383
+ }
384
+ time.Sleep(retryDelay(retry, attempt, after))
385
+ continue
386
+ }
387
+ // The response body outlives this call; tie the attempt context's lifetime to it.
388
+ if cancel != nil {
389
+ resp.Body = &cancelOnClose{ReadCloser: resp.Body, cancel: cancel}
390
+ }
391
+ return resp, nil
392
+ }
393
+ }
394
+
395
+ type cancelOnClose struct {
396
+ io.ReadCloser
397
+ cancel context.CancelFunc
398
+ }
399
+
400
+ func (c *cancelOnClose) Close() error {
401
+ c.cancel()
402
+ return c.ReadCloser.Close()
403
+ }
404
+
405
+ // decodeJSON decodes a response body into target; a nil target drains and closes.
406
+ func decodeJSON(resp *http.Response, target any) error {
407
+ defer resp.Body.Close()
408
+ if target == nil {
409
+ _, err := io.Copy(io.Discard, resp.Body)
410
+ return err
411
+ }
412
+ return json.NewDecoder(resp.Body).Decode(target)
413
+ }
414
+
415
+ // headerString returns the named response header, or nil when absent.
416
+ func headerString(header http.Header, name string) *string {
417
+ value := header.Get(name)
418
+ if value == "" {
419
+ return nil
420
+ }
421
+ return &value
422
+ }
423
+
424
+ // headerInt64 parses the named header as an integer; nil when absent or unparsable.
425
+ func headerInt64(header http.Header, name string) *int64 {
426
+ raw := strings.TrimSpace(header.Get(name))
427
+ if raw == "" {
428
+ return nil
429
+ }
430
+ value, err := strconv.ParseInt(raw, 10, 64)
431
+ if err != nil {
432
+ return nil
433
+ }
434
+ return &value
435
+ }
436
+
437
+ // headerFloat64 parses the named header as a number; nil when absent or unparsable.
438
+ func headerFloat64(header http.Header, name string) *float64 {
439
+ raw := strings.TrimSpace(header.Get(name))
440
+ if raw == "" {
441
+ return nil
442
+ }
443
+ value, err := strconv.ParseFloat(raw, 64)
444
+ if err != nil {
445
+ return nil
446
+ }
447
+ return &value
448
+ }
449
+
450
+ // headerBool parses a \`true\`/\`false\` header; nil when absent or anything else.
451
+ func headerBool(header http.Header, name string) *bool {
452
+ raw := strings.ToLower(strings.TrimSpace(header.Get(name)))
453
+ if raw != "true" && raw != "false" {
454
+ return nil
455
+ }
456
+ value := raw == "true"
457
+ return &value
458
+ }
459
+
460
+ // apiErrorFrom builds the structured error for a non-2xx response.
461
+ func apiErrorFrom(resp *http.Response, requestURL string) error {
462
+ defer resp.Body.Close()
463
+ var body any
464
+ data, _ := io.ReadAll(resp.Body)
465
+ if len(data) > 0 {
466
+ if err := json.Unmarshal(data, &body); err != nil {
467
+ body = string(data)
468
+ }
469
+ }
470
+ return &APIError{URL: requestURL, Status: resp.StatusCode, StatusText: resp.Status, Body: body}
471
+ }
472
+
473
+ // \u2500\u2500\u2500 Pagination \u2500\u2500\u2500
474
+
475
+ // PaginationSpec mirrors the descriptor table's pagination entries.
476
+ type PaginationSpec struct {
477
+ Style string
478
+ Param string
479
+ NextCursor string
480
+ HasMore string
481
+ LimitParam string
482
+ Items string
483
+ }
484
+
485
+ // resolvePointer walks an RFC 6901 JSON pointer over decoded JSON; nil on any miss.
486
+ func resolvePointer(data any, pointer string) any {
487
+ if pointer == "" {
488
+ return data
489
+ }
490
+ if !strings.HasPrefix(pointer, "/") {
491
+ return nil
492
+ }
493
+ current := data
494
+ for _, token := range strings.Split(pointer[1:], "/") {
495
+ key := strings.ReplaceAll(strings.ReplaceAll(token, "~1", "/"), "~0", "~")
496
+ switch typed := current.(type) {
497
+ case map[string]any:
498
+ current = typed[key]
499
+ case []any:
500
+ index, err := strconv.Atoi(key)
501
+ if err != nil || index < 0 || index >= len(typed) {
502
+ return nil
503
+ }
504
+ current = typed[index]
505
+ default:
506
+ return nil
507
+ }
508
+ if current == nil {
509
+ return nil
510
+ }
511
+ }
512
+ return current
513
+ }
514
+
515
+ // reencode converts decoded JSON (maps/slices) into a typed value via a JSON round-trip.
516
+ func reencode(raw any, target any) error {
517
+ data, err := json.Marshal(raw)
518
+ if err != nil {
519
+ return err
520
+ }
521
+ return json.Unmarshal(data, target)
522
+ }
523
+
524
+ type pageCall func(params url.Values) (any, *http.Response, error)
525
+
526
+ // iterPages yields raw page JSON per the pagination spec \u2014 the same stop
527
+ // conditions and infinite-loop guards as the TypeScript runtime. The returned
528
+ // function is a range-over-func iterator (Go 1.23+) and plainly callable before that.
529
+ func iterPages(call pageCall, spec PaginationSpec, base url.Values) func(yield func(any, error) bool) {
530
+ return func(yield func(any, error) bool) {
531
+ switch spec.Style {
532
+ case "cursor":
533
+ var cursor any
534
+ if values, ok := base[spec.Param]; ok && len(values) > 0 {
535
+ cursor = values[0]
536
+ }
537
+ for {
538
+ params := cloneValues(base)
539
+ if cursor != nil {
540
+ params.Set(spec.Param, fmt.Sprint(cursor))
541
+ }
542
+ page, _, err := call(params)
543
+ if err != nil {
544
+ yield(nil, err)
545
+ return
546
+ }
547
+ if !yield(page, nil) {
548
+ return
549
+ }
550
+ if spec.HasMore != "" {
551
+ if more, ok := resolvePointer(page, spec.HasMore).(bool); ok && !more {
552
+ return
553
+ }
554
+ }
555
+ next := resolvePointer(page, spec.NextCursor)
556
+ if next == nil || next == "" {
557
+ return
558
+ }
559
+ switch next.(type) {
560
+ case string, float64:
561
+ default:
562
+ yield(nil, fmt.Errorf("pagination cursor at %s is not a string or number", spec.NextCursor))
563
+ return
564
+ }
565
+ if cursor != nil && fmt.Sprint(next) == fmt.Sprint(cursor) {
566
+ yield(nil, errors.New("pagination did not advance: the operation returned the same cursor twice"))
567
+ return
568
+ }
569
+ cursor = next
570
+ }
571
+ case "link":
572
+ params := cloneValues(base)
573
+ previous := ""
574
+ for {
575
+ page, resp, err := call(params)
576
+ if err != nil {
577
+ yield(nil, err)
578
+ return
579
+ }
580
+ if !yield(page, nil) {
581
+ return
582
+ }
583
+ target := linkNext(resp.Header.Get("Link"))
584
+ if target == "" {
585
+ return
586
+ }
587
+ pageURL := ""
588
+ if resp.Request != nil && resp.Request.URL != nil {
589
+ pageURL = resp.Request.URL.String()
590
+ }
591
+ baseURL, err := url.Parse(pageURL)
592
+ if err != nil || pageURL == "" {
593
+ baseURL, _ = url.Parse("http://relative.invalid")
594
+ }
595
+ targetURL, err := baseURL.Parse(target)
596
+ if err != nil {
597
+ yield(nil, err)
598
+ return
599
+ }
600
+ next := targetURL.String()
601
+ if next == previous || next == pageURL {
602
+ yield(nil, errors.New(\`pagination did not advance: the Link rel="next" target repeats\`))
603
+ return
604
+ }
605
+ previous = next
606
+ params = cloneValues(base)
607
+ for key, values := range targetURL.Query() {
608
+ for _, value := range values {
609
+ params.Add(key, value)
610
+ }
611
+ }
612
+ }
613
+ default: // offset / page
614
+ position := 0
615
+ if spec.Style == "page" {
616
+ position = 1
617
+ }
618
+ if values, ok := base[spec.Param]; ok && len(values) > 0 && values[0] != "" {
619
+ if parsed, err := strconv.Atoi(values[0]); err == nil {
620
+ position = parsed
621
+ }
622
+ }
623
+ previousItems := ""
624
+ for {
625
+ params := cloneValues(base)
626
+ params.Set(spec.Param, strconv.Itoa(position))
627
+ page, _, err := call(params)
628
+ if err != nil {
629
+ yield(nil, err)
630
+ return
631
+ }
632
+ items, _ := resolvePointer(page, spec.Items).([]any)
633
+ serialized := ""
634
+ if items != nil {
635
+ serialized = fmt.Sprint(items)
636
+ if serialized == previousItems {
637
+ yield(nil, errors.New("pagination did not advance: the operation returned the same page twice"))
638
+ return
639
+ }
640
+ }
641
+ if !yield(page, nil) {
642
+ return
643
+ }
644
+ if len(items) == 0 {
645
+ return
646
+ }
647
+ previousItems = serialized
648
+ if spec.Style == "page" {
649
+ position++
650
+ } else {
651
+ position += len(items)
652
+ }
653
+ }
654
+ }
655
+ }
656
+ }
657
+
658
+ func cloneValues(values url.Values) url.Values {
659
+ out := url.Values{}
660
+ for key, entries := range values {
661
+ for _, entry := range entries {
662
+ out.Add(key, entry)
663
+ }
664
+ }
665
+ return out
666
+ }
667
+
668
+ func linkNext(header string) string {
669
+ if header == "" {
670
+ return ""
671
+ }
672
+ for _, entry := range strings.Split(header, ",") {
673
+ parts := strings.Split(entry, ";")
674
+ if len(parts) < 2 {
675
+ continue
676
+ }
677
+ target := strings.TrimSpace(parts[0])
678
+ if !strings.HasPrefix(target, "<") || !strings.HasSuffix(target, ">") {
679
+ continue
680
+ }
681
+ for _, param := range parts[1:] {
682
+ trimmed := strings.TrimSpace(param)
683
+ if strings.HasPrefix(trimmed, "rel=") {
684
+ rel := strings.Trim(strings.TrimPrefix(trimmed, "rel="), \`"\`)
685
+ for _, kind := range strings.Fields(rel) {
686
+ if kind == "next" {
687
+ return strings.Trim(target, "<>")
688
+ }
689
+ }
690
+ }
691
+ }
692
+ }
693
+ return ""
694
+ }
695
+
696
+ // \u2500\u2500\u2500 Server-Sent Events \u2500\u2500\u2500
697
+
698
+ // ServerSentEvent is one decoded event; Data is the raw text (or parsed JSON
699
+ // for operations that declare a JSON event stream).
700
+ type ServerSentEvent struct {
701
+ Event string
702
+ Data any
703
+ ID string
704
+ Retry int
705
+ }
706
+
707
+ func parseSSEFrame(raw string, jsonData bool) (ServerSentEvent, bool, error) {
708
+ event := ServerSentEvent{Retry: -1}
709
+ sawField := false
710
+ var dataLines []string
711
+ normalized := strings.ReplaceAll(strings.ReplaceAll(raw, "\\r\\n", "\\n"), "\\r", "\\n")
712
+ for _, line := range strings.Split(normalized, "\\n") {
713
+ if line == "" || strings.HasPrefix(line, ":") {
714
+ continue
715
+ }
716
+ field, value, _ := strings.Cut(line, ":")
717
+ value = strings.TrimPrefix(value, " ")
718
+ sawField = true
719
+ switch field {
720
+ case "event":
721
+ event.Event = value
722
+ case "data":
723
+ dataLines = append(dataLines, value)
724
+ case "id":
725
+ event.ID = value
726
+ case "retry":
727
+ if parsed, err := strconv.Atoi(value); err == nil && parsed >= 0 && value != "" {
728
+ event.Retry = parsed
729
+ }
730
+ }
731
+ }
732
+ if !sawField {
733
+ return event, false, nil
734
+ }
735
+ text := strings.Join(dataLines, "\\n")
736
+ event.Data = text
737
+ if jsonData && text != "" {
738
+ var parsed any
739
+ if err := json.Unmarshal([]byte(text), &parsed); err != nil {
740
+ return event, false, err
741
+ }
742
+ event.Data = parsed
743
+ }
744
+ return event, true, nil
745
+ }
746
+
747
+ // iterSSE streams events, reconnecting on dropped connections with Last-Event-ID
748
+ // (a fresh open call = fresh auth); a 4xx/5xx or a bad JSON payload is definitive.
749
+ func iterSSE(open func(extraHeaders map[string]string) (*http.Response, error), jsonData bool) func(yield func(ServerSentEvent, error) bool) {
750
+ return func(yield func(ServerSentEvent, error) bool) {
751
+ lastEventID := ""
752
+ serverRetry := -1
753
+ failures := 0
754
+ for {
755
+ headers := map[string]string{"Accept": "text/event-stream"}
756
+ if lastEventID != "" {
757
+ headers["Last-Event-ID"] = lastEventID
758
+ }
759
+ resp, err := open(headers)
760
+ if err == nil && resp.StatusCode >= 400 {
761
+ yield(ServerSentEvent{}, apiErrorFrom(resp, ""))
762
+ return
763
+ }
764
+ if err == nil {
765
+ failures = 0
766
+ buffer := ""
767
+ chunk := make([]byte, 4096)
768
+ clean := false
769
+ for {
770
+ n, readErr := resp.Body.Read(chunk)
771
+ buffer += string(chunk[:n])
772
+ for {
773
+ frame, rest, found := strings.Cut(buffer, "\\n\\n")
774
+ if !found {
775
+ break
776
+ }
777
+ buffer = rest
778
+ event, ok, parseErr := parseSSEFrame(frame, jsonData)
779
+ if parseErr != nil {
780
+ resp.Body.Close()
781
+ yield(ServerSentEvent{}, parseErr)
782
+ return
783
+ }
784
+ if ok {
785
+ if event.ID != "" {
786
+ lastEventID = event.ID
787
+ }
788
+ if event.Retry >= 0 {
789
+ serverRetry = event.Retry
790
+ }
791
+ if !yield(event, nil) {
792
+ resp.Body.Close()
793
+ return
794
+ }
795
+ }
796
+ }
797
+ if readErr == io.EOF {
798
+ clean = true
799
+ break
800
+ }
801
+ if readErr != nil {
802
+ break
803
+ }
804
+ }
805
+ resp.Body.Close()
806
+ if clean {
807
+ if strings.TrimSpace(buffer) != "" {
808
+ if event, ok, parseErr := parseSSEFrame(buffer, jsonData); parseErr == nil && ok {
809
+ yield(event, nil)
810
+ }
811
+ }
812
+ return
813
+ }
814
+ }
815
+ failures++
816
+ base := time.Second
817
+ if serverRetry >= 0 {
818
+ base = time.Duration(serverRetry) * time.Millisecond
819
+ }
820
+ delay := base * time.Duration(1<<(failures-1))
821
+ if delay > 30*time.Second {
822
+ delay = 30 * time.Second
823
+ }
824
+ time.Sleep(time.Duration(rand.Int63n(int64(delay) + 1)))
825
+ }
826
+ }
827
+ }
828
+
829
+ // \u2500\u2500\u2500 Multipart \u2500\u2500\u2500
830
+
831
+ // toMultipart splits a typed body into a multipart/form-data payload: []byte
832
+ // values upload as file parts, everything else as form fields (nested values
833
+ // JSON-encoded) \u2014 mirroring the TypeScript runtime's FormData serialization.
834
+ func toMultipart(body any) (string, io.Reader, error) {
835
+ var wire map[string]any
836
+ if err := reencode(body, &wire); err != nil {
837
+ return "", nil, err
838
+ }
839
+ buffer := &bytes.Buffer{}
840
+ writer := multipart.NewWriter(buffer)
841
+ for key, value := range wire {
842
+ switch typed := value.(type) {
843
+ case string:
844
+ if err := writer.WriteField(key, typed); err != nil {
845
+ return "", nil, err
846
+ }
847
+ case float64, bool:
848
+ if err := writer.WriteField(key, fmt.Sprint(typed)); err != nil {
849
+ return "", nil, err
850
+ }
851
+ default:
852
+ encoded, err := json.Marshal(typed)
853
+ if err != nil {
854
+ return "", nil, err
855
+ }
856
+ if err := writer.WriteField(key, string(encoded)); err != nil {
857
+ return "", nil, err
858
+ }
859
+ }
860
+ }
861
+ if err := writer.Close(); err != nil {
862
+ return "", nil, err
863
+ }
864
+ return writer.FormDataContentType(), buffer, nil
865
+ }
866
+ `;var S=T.go;function Z(t){if(t===void 0)return"client";if(!/^[a-z_][a-z0-9_]*$/.test(t)||S.has(t))throw new P(`goPackage "${t}" is not a valid Go package name: use lowercase letters, digits, and underscores, don't start with a digit, and avoid Go keywords.`);return t}function p(t){let r=$(t,{style:"pascal",reserved:S});return r.startsWith("_")?`N${r.slice(1)}`:r}function h(t,r="string"){if(L(t)){let e=h(A(t),r);return e.startsWith("*")||e==="any"?e:`*${e}`}switch(t.kind){case"scalar":if(r==="Date"&&t.scalar==="string"){if(t.metadata?.format==="date-time")return"time.Time";if(t.metadata?.format==="date")return"Date"}return{string:"string",integer:"int64",number:"float64",boolean:"bool"}[t.scalar];case"array":return`[]${h(t.items,r)}`;case"record":return`map[string]${h(t.value,r)}`;case"ref":return p(t.name);case"literal":return typeof t.value=="string"?"string":typeof t.value=="boolean"?"bool":"float64";case"enum":return{string:"string",integer:"int64",number:"float64",boolean:"bool"}[t.scalar];case"omit":return p(t.base);case"union":case"null":case"object":case"intersection":case"unknown":return"any"}}function R(t,r,e){let n=B(e);if(n.length===0)return;t.line(`// ${r} \u2014 ${n[0]}`);let a=!1;for(let i of n.slice(1)){if(i===""){a||t.line("//"),a=!0;continue}t.line(`// ${i}`),a=!1}}function Y(t,r,e,n,a){R(t,p(r),a),t.block(`type ${p(r)} struct {`,()=>{for(let i of e){let l=p(i.name),s=h(i.schema,n),c=`\`json:"${i.name}"\``;i.required||(!s.startsWith("*")&&!s.startsWith("[]")&&!s.startsWith("map[")&&s!=="any"&&(s=`*${s}`),c=`\`json:"${i.name},omitempty"\``),t.line(`${l} ${s} ${c}`)}},"}"),t.blank()}function K(t){return`${t.replace(/\n{3,}/g,`
867
+
868
+ `).trimEnd()}
869
+ `}function X(t,r="string"){let e=new C(" ");e.line("package client"),e.blank(),t.schemas.some(({schema:i})=>x(i,t)!==void 0)&&(e.line('import "encoding/json"'),e.blank());let a=tt(t,r);return r==="Date"&&a.includes("time.Time")&&(e.line('import "time"'),e.blank()),e.line(a),K(W(e.toString()))}function tt(t,r){let e=new C(" ");for(let{name:n,schema:a}of t.schemas){let i=J(a);if(i!==void 0){let s=i.scalar==="string"?"string":"int64";R(e,p(n),a.description),e.line(`type ${p(n)} ${s}`),e.blank(),e.block("const (",()=>{i.values.forEach(c=>{let o=p(n)+D.pascal(String(c));e.line(`${o} ${p(n)} = ${JSON.stringify(c)}`)})},")"),e.blank();continue}if(a.kind==="object"||a.kind==="intersection"){let s=q(a,t);if(s!==void 0){Y(e,n,s.properties,r,s.description??a.description);continue}}let l=x(a,t);if(l!==void 0){let s=p(n),c=l.cases.map(o=>`${o.value} -> ${p(o.schemaName)}`).join(", ");e.line(`// ${s} is a discriminated union ("${l.property}"): ${c}.`),e.line(`type ${s} = any`),e.blank(),e.line(`// Unmarshal${s} decodes into the member selected by "${l.property}".`),e.block(`func Unmarshal${s}(data []byte) (${s}, error) {`,()=>{e.block("var probe struct {",()=>{e.line(`Discriminant string \`json:"${l.property}"\``)},"}"),e.block("if err := json.Unmarshal(data, &probe); err != nil {",()=>{e.line("return nil, err")},"}"),e.line("switch probe.Discriminant {");for(let o of l.cases)e.block(`case ${JSON.stringify(o.value)}:`,()=>{e.line(`var value ${p(o.schemaName)}`),e.line("err := json.Unmarshal(data, &value)"),e.line("return value, err")});e.line("}"),e.line("var fallback any"),e.line("err := json.Unmarshal(data, &fallback)"),e.line("return fallback, err")},"}"),e.blank();continue}R(e,p(n),a.description),e.line(`type ${p(n)} = ${h(a,r)}`),e.blank()}return e.toString()}function G(t){return t.successResponses.find(r=>r.contentType.toLowerCase().includes("json"))?.schema}function et(t,r){let e=t.security.map(n=>n.flatMap(a=>{let i=r.securitySchemes.find(c=>c.key===a);if(i===void 0)return[];if(i.kind==="bearer"||i.kind==="basic")return[`{Scheme: ${JSON.stringify(a)}, Kind: ${JSON.stringify(i.kind)}}`];let l=i.kind==="apiKeyHeader"?i.headerName:i.kind==="apiKeyQuery"?i.paramName:i.cookieName,s=i.kind==="apiKeyHeader"?"header":i.kind==="apiKeyQuery"?"query":"cookie";return[`{Scheme: ${JSON.stringify(a)}, Kind: "apiKey", Name: ${JSON.stringify(l)}, In: ${JSON.stringify(s)}}`]})).filter(n=>n.length>0);if(e.length!==0)return`[][]SecuritySpec{${e.map(n=>`{${n.join(", ")}}`).join(", ")}}`}function N(t){let r=new Set,e=[];for(let n of t.services)for(let a of n.operations){let i=p(a.name),l=2;for(;r.has(i);)i=`${p(a.name)}${l++}`;r.add(i),e.push({op:a,ident:i})}return e}function O(t,r){if(r==="string")return t;let e=t.startsWith("*")?`(${t})`:t;return r==="time.Time"?`${e}.Format(time.RFC3339)`:r==="Date"?`${e}.Format("2006-01-02")`:r==="int64"?`strconv.FormatInt(${t}, 10)`:r==="float64"?`strconv.FormatFloat(${t}, 'f', -1, 64)`:r==="bool"?`strconv.FormatBool(${t})`:`fmt.Sprint(${t})`}function W(t){let r=t.split(`
870
+ `),e=[...r],n=/^(\t+)([A-Za-z_]\w*) (\S+)( `[^`]*`)?$/,a=/^(\t+)([A-Za-z_]\w*) (\S+) = (.+)$/,i=/^(\t+)("(?:[^"\\]|\\.)*":) (.+)$/,l=o=>{if(o.length<2)return;let u=[];for(let{parts:d}of o)d.forEach((f,m)=>{m<d.length-1&&(u[m]=Math.max(u[m]??0,f.length))});for(let{index:d,parts:f,indent:m}of o){let g=f.map((b,y)=>y<f.length-1?b.padEnd(u[y]??0):b);e[d]=m+g.join(" ").trimEnd()}},s=[],c;return r.forEach((o,u)=>{let d=i.exec(o),f=d===null?a.exec(o):null,m=d===null&&f===null?n.exec(o):null,g=m!==null&&!S.has(m[2])?m:null,b=d!==null?"entry":f!==null?"const":g!==null?"field":void 0;if((b===void 0||b!==c)&&(l(s),s=[],c=b),d!==null){s.push({index:u,indent:d[1],parts:[d[2],d[3]]});return}if(f!==null){s.push({index:u,indent:f[1],parts:[f[2],f[3],"=",f[4]]});return}if(g!==null){let y=[g[2],g[3]];g[4]!==void 0&&y.push(g[4].trimStart()),s.push({index:u,indent:g[1],parts:y})}}),l(s),e.join(`
871
+ `)}function F(t){let r=t.split(`
872
+ `),e=[],n=!1;for(let a of r)if(!a.startsWith("package ")){if(a.startsWith("import (")){n=!0;continue}if(n){a.startsWith(")")&&(n=!1);continue}a.startsWith("import ")||e.push(a)}return e.join(`
873
+ `).trim()}function z(t){return t.successResponses.find(r=>r.contentType.toLowerCase().includes("text/event-stream"))}function nt(t){return t.requestBody?.contentType.toLowerCase().includes("multipart")??!1}function rt(t){return`&PaginationSpec{${[`Style: ${JSON.stringify(t.style)}`,...t.param!==void 0?[`Param: ${JSON.stringify(t.param)}`]:[],...t.nextCursor!==void 0?[`NextCursor: ${JSON.stringify(t.nextCursor)}`]:[],...t.hasMore!==void 0?[`HasMore: ${JSON.stringify(t.hasMore)}`]:[],...t.limitParam!==void 0?[`LimitParam: ${JSON.stringify(t.limitParam)}`]:[],...t.items!==void 0?[`Items: ${JSON.stringify(t.items)}`]:[]].join(", ")}}`}var at=["c","ctx","body","params","out","op"];function V(t,r){let e=E(t.pathParams.map(n=>n.name),{style:"camel",reserved:S,taken:at});return t.pathParams.map((n,a)=>({param:n,go:e[a],type:h(n.schema,r)}))}function it(t,r){let e=new Set;return(t.successResponseHeaders??[]).map(n=>{let a=p(n.name),i=a,l=2;for(;e.has(i);)i=`${a}${l++}`;e.add(i);let s=M(n.schema,r),c={integer:{goType:"*int64",helper:"headerInt64"},number:{goType:"*float64",helper:"headerFloat64"},boolean:{goType:"*bool",helper:"headerBool"},string:{goType:"*string",helper:"headerString"}}[s];return{field:i,name:n.name,...c}})}function _(t,r,e,n,a,i=!1){let l=V(r,n),s=r.queryParams.length>0,c=G(r),o=c===void 0?void 0:h(c,n),u=i?it(r,a):[];i&&(t.line(`// ${e}Headers carries the declared response headers of ${e}WithHeaders (nil when absent or unparsable).`),t.block(`type ${e}Headers struct {`,()=>{for(let y of u)t.line(`${y.field} ${y.goType}`)},"}"),t.blank());let d=["ctx context.Context",...l.map(({go:y,type:k})=>`${y} ${k}`),...r.requestBody?[`body ${h(r.requestBody.schema,n)}`]:[],...s?[`params *${e}Params`]:[]],f=z(r),m=i?o===void 0?`(${e}Headers, error)`:`(${o}, ${e}Headers, error)`:f!==void 0?"func(yield func(ServerSentEvent, error) bool)":o===void 0?"error":`(${o}, error)`,g=y=>i?o===void 0?`return headers, ${y}`:`return out, headers, ${y}`:o===void 0?`return ${y}`:`return out, ${y}`,b=i?`${e}WithHeaders`:e;R(t,b,i?`Like ${e}, also returning the declared response headers.`:r.summary),t.block(`func (c *Client) ${b}(${d.join(", ")}) ${m} {`,()=>{f===void 0&&o!==void 0&&t.line(`var out ${o}`),i&&t.line(`var headers ${e}Headers`),t.line(`op := operations[${JSON.stringify(r.specName??r.name)}]`),t.line("authHeaders, query := resolveAuth(op.Security, c.config.Auth)"),s&&t.block("if params != nil {",()=>{for(let v of r.queryParams){let w=p(v.name);t.block(`if params.${w} != nil {`,()=>{t.line(`query.Set(${JSON.stringify(v.name)}, ${O(`*params.${w}`,h(v.schema,n))})`)},"}")}},"}");let y=l.map(({param:v,go:w,type:Q})=>`${JSON.stringify(v.name)}: ${O(w,Q)}`).join(", ");if(t.line(`requestURL := buildURL(c.config.ServerURL, op.Path, map[string]string{${y}})`),f!==void 0){t.block("open := func(extraHeaders map[string]string) (*http.Response, error) {",()=>{t.line("merged := map[string]string{}"),t.block("for key, value := range authHeaders {",()=>{t.line("merged[key] = value")},"}"),t.block("for key, value := range extraHeaders {",()=>{t.line("merged[key] = value")},"}"),t.line("return send(ctx, &c.config, requestSpec{OperationID: op.ID, Method: op.Method, URL: requestURL, Headers: merged, Query: query})")},"}"),t.line(`return iterSSE(open, ${f.schema!==void 0&&f.schema.kind!=="unknown"})`);return}let k=["OperationID: op.ID","Method: op.Method","URL: requestURL","Headers: authHeaders","Query: query"];if(r.requestBody&&nt(r)?(t.line("contentType, reader, err := toMultipart(body)"),t.block("if err != nil {",()=>{t.line(g("err"))},"}"),k.push("Body: reader"),k.push("ContentType: contentType")):r.requestBody&&(t.line("payload, err := json.Marshal(body)"),t.block("if err != nil {",()=>{t.line(g("err"))},"}"),k.push("Body: bytes.NewReader(payload)"),k.push(`ContentType: ${JSON.stringify(r.requestBody.contentType)}`)),t.line(`resp, err := send(ctx, &c.config, requestSpec{${k.join(", ")}})`),t.block("if err != nil {",()=>{t.line(g("err"))},"}"),t.block("if resp.StatusCode >= 400 {",()=>{t.line(g("apiErrorFrom(resp, requestURL)"))},"}"),i){t.block(`if err := decodeJSON(resp, ${o===void 0?"nil":"&out"}); err != nil {`,()=>{t.line(g("err"))},"}");for(let v of u)t.line(`headers.${v.field} = ${v.helper}(resp.Header, ${JSON.stringify(v.name)})`);t.line(o===void 0?"return headers, nil":"return out, headers, nil")}else o===void 0?t.line("return decodeJSON(resp, nil)"):(t.block("if err := decodeJSON(resp, &out); err != nil {",()=>{t.line("return out, err")},"}"),t.line("return out, nil"))},"}"),t.blank()}function st(t,r,e,n,a,i){let l=V(r,n),s=r.queryParams.length>0,c=["ctx context.Context",...l.map(({go:u,type:d})=>`${u} ${d}`),...s?[`params *${e}Params`]:[]].join(", "),o=()=>{t.line(`op := operations[${JSON.stringify(r.specName??r.name)}]`),t.line("base := url.Values{}"),s&&t.block("if params != nil {",()=>{for(let u of r.queryParams){let d=p(u.name);t.block(`if params.${d} != nil {`,()=>{t.line(`base.Set(${JSON.stringify(u.name)}, ${O(`*params.${d}`,h(u.schema,n))})`)},"}")}},"}"),t.block("call := func(pageParams url.Values) (any, *http.Response, error) {",()=>{t.line("authHeaders, query := resolveAuth(op.Security, c.config.Auth)"),t.block("for key, values := range pageParams {",()=>{t.block("for _, value := range values {",()=>{t.line("query.Set(key, value)")},"}")},"}");let u=l.map(({param:d,go:f,type:m})=>`${JSON.stringify(d.name)}: ${O(f,m)}`).join(", ");t.line(`requestURL := buildURL(c.config.ServerURL, op.Path, map[string]string{${u}})`),t.line("resp, err := send(ctx, &c.config, requestSpec{OperationID: op.ID, Method: op.Method, URL: requestURL, Headers: authHeaders, Query: query})"),t.block("if err != nil {",()=>{t.line("return nil, nil, err")},"}"),t.block("if resp.StatusCode >= 400 {",()=>{t.line("return nil, resp, apiErrorFrom(resp, requestURL)")},"}"),t.line("var raw any"),t.block("if err := decodeJSON(resp, &raw); err != nil {",()=>{t.line("return nil, resp, err")},"}"),t.line("return raw, resp, nil")},"}"),t.line("pages := iterPages(call, *op.Pagination, base)")};t.line(`// ${e}Pages iterates ${e} response pages; use with \`for page, err := range\`.`),t.block(`func (c *Client) ${e}Pages(${c}) func(yield func(${a}, error) bool) {`,()=>{o(),t.block(`return func(yield func(${a}, error) bool) {`,()=>{t.block("pages(func(raw any, err error) bool {",()=>{t.line(`var page ${a}`),t.block("if err == nil {",()=>{t.line("err = reencode(raw, &page)")},"}"),t.line("return yield(page, err)")},"})")},"}")},"}"),t.blank(),t.line(`// ${e}Items iterates the items of every ${e} page.`),t.block(`func (c *Client) ${e}Items(${c}) func(yield func(${i}, error) bool) {`,()=>{o(),t.block(`return func(yield func(${i}, error) bool) {`,()=>{t.block("pages(func(raw any, err error) bool {",()=>{t.block("if err != nil {",()=>{t.line(`var zero ${i}`),t.line("return yield(zero, err)")},"}"),t.line("pageItems, _ := resolvePointer(raw, op.Pagination.Items).([]any)"),t.block("for _, item := range pageItems {",()=>{t.line(`var typed ${i}`),t.block("if err := reencode(item, &typed); err != nil {",()=>{t.line("return yield(typed, err)")},"}"),t.block("if !yield(typed, nil) {",()=>{t.line("return false")},"}")},"}"),t.line("return true")},"})")},"}")},"}"),t.blank()}function ot(t){let r=new Set(t.variables.map(l=>l.name)),e=[],n="",a=t.url,i=/\{([^{}]+)\}/;for(let l=i.exec(a);l!==null;l=i.exec(a))n+=a.slice(0,l.index),r.has(l[1])?(n!==""&&e.push(JSON.stringify(n)),n="",e.push($(l[1],{style:"camel",reserved:S}))):n+=l[0],a=a.slice(l.index+l[0].length);return n+=a,(n!==""||e.length===0)&&e.push(JSON.stringify(n)),e.join(" + ")}function lt(t,r){let e=r.servers??[];if(e.length===0)return;let n=new Set;e.forEach((a,i)=>{let l=`${p(a.description??`server${i+1}`)}URL`;n.has(l)&&(l=`${l}${i+1}`),n.add(l);let s=a.variables.map(o=>`${$(o.name,{style:"camel",reserved:S})} string`),c=a.variables.map(o=>`${$(o.name,{style:"camel",reserved:S})} default: ${JSON.stringify(o.default)}`).join(", ");t.line(`// ${l} returns the ${JSON.stringify(a.description??a.url)} base URL${c===""?".":` (${c}).`}`),t.block(`func ${l}(${s.join(", ")}) string {`,()=>{t.line(`return ${ot(a)}`)},"}"),t.blank()})}var pt=({model:t,outputPath:r,emit:e})=>{let n=new C(" "),a=e.dateType??"string",i=Z(e.goPackage),l=new Map;for(let{op:s,ident:c}of N(t)){let o=I(s,e.pagination);o!==void 0&&l.set(c,o)}n.line(`// Code generated by @redocly/client-generator (go) from "${t.title}" ${t.version}. DO NOT EDIT.`),n.line("// Regenerate with `redocly generate-client`. Standard library only \u2014 zero dependencies."),n.line(`package ${i}`),n.blank(),n.block("import (",()=>{for(let s of["bytes","context","encoding/base64","encoding/json","errors","fmt","io","math/rand","mime/multipart","net/http","net/url","strconv","strings","time"])n.line(JSON.stringify(s))},")"),n.blank(),n.line(F(X(t,a))),n.blank(),lt(n,t),n.line("// \u2500\u2500\u2500 Embedded runtime (@redocly/client-generator go runtime) \u2500\u2500\u2500"),n.line(F(j)),n.blank(),n.block("type operationMeta struct {",()=>{n.line("ID string"),n.line("Method string"),n.line("Path string"),n.line("Security [][]SecuritySpec"),n.line("Pagination *PaginationSpec")},"}"),n.blank(),n.block("var operations = map[string]operationMeta{",()=>{for(let{op:s,ident:c}of N(t)){let o=s.specName??s.name,u=et(s,t),d=l.get(c),f=[`ID: ${JSON.stringify(o)}`,`Method: ${JSON.stringify(s.method.toUpperCase())}`,`Path: ${JSON.stringify(s.path)}`,...u!==void 0?[`Security: ${u}`]:[],...d!==void 0?[`Pagination: ${rt(d)}`]:[]];n.line(`${JSON.stringify(o)}: {${f.join(", ")}},`)}},"}"),n.blank();for(let{op:s,ident:c}of N(t))s.queryParams.length!==0&&(n.block(`type ${c}Params struct {`,()=>{for(let o of s.queryParams){let u=h(o.schema,a);n.line(`${p(o.name)} ${u.startsWith("*")?u:`*${u}`}`)}},"}"),n.blank());R(n,"Client",`Client for ${t.title} (${t.version}).`),n.block("type Client struct {",()=>{n.line("config Config")},"}"),n.blank(),n.block("func New(config Config) *Client {",()=>{n.block('if config.ServerURL == "" {',()=>{n.line(`config.ServerURL = ${JSON.stringify(e.serverUrl??t.serverUrl??"")}`)},"}"),n.line("return &Client{config: config}")},"}"),n.blank();for(let{op:s,ident:c}of N(t)){_(n,s,c,a),z(s)===void 0&&(s.successResponseHeaders?.length??0)>0&&_(n,s,c,a,t,!0);let o=l.get(c);if(o===void 0)continue;let u=G(s),d=u===void 0?"any":h(u,a),f=u!==void 0&&o.items!==void 0?H(u,o.items,t):void 0,m=f?.kind==="array"?f.items:void 0;st(n,s,c,a,d,m===void 0?"any":h(m,a))}return[{path:r.replace(/\.[^.\\/]+$/,".go"),content:K(W(n.toString()))}]};function ct(t,r){let e=r.emit.dateType??"string",n=r.emit.goPackage??"client",a=p(t.name),i=["ctx",...t.pathParams.map(l=>`"<${$(l.name,{style:"camel",reserved:S})}>"`),...t.requestBody?[`${h(t.requestBody.schema,e)}{ /* \u2026 */ }`]:[],...t.queryParams.length>0?["nil"]:[]];return{lang:"go",label:"Go SDK",source:`client := ${n}.New(${n}.Config{})
874
+ result, err := client.${a}(${i.join(", ")})
875
+ `}}var yt=({model:t,outputPath:r,emit:e})=>[{path:r.replace(/\.[^.\\/]+$/,".go.md"),content:U(t,{title:`${t.title} Go SDK reference`,frontmatter:e.docsFrontmatter===!0,language:{name:"go",label:"Go",fence:"go",requires:"The SDK needs the standard library only."},sample:n=>ct(n,{model:t,emit:e,outputPath:r}),pagination:e.pagination})}];export{h as a,X as b,pt as c,ct as d,yt as e};