@redocly/cli 2.60.0 → 2.61.0

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 (137) hide show
  1. package/THIRD_PARTY_NOTICES +2 -2
  2. package/lib/chunks/{AP2GA7RS.js → 22EANOP2.js} +87 -87
  3. package/lib/chunks/{G4ZIYGF5.js → 2KG4GEMM.js} +1 -1
  4. package/lib/chunks/2OVI7BIW.js +105 -0
  5. package/lib/chunks/{7C244K4X.js → 2WJSVZYJ.js} +1 -1
  6. package/lib/chunks/{B5GZ7KU2.js → 3QZ3M2JX.js} +1 -1
  7. package/lib/chunks/{W7VT3BOM.js → 3TBVUHVH.js} +1 -1
  8. package/lib/chunks/{IAN3UOJT.js → 3VI3PRNZ.js} +1 -1
  9. package/lib/chunks/45DZYRBQ.js +7 -0
  10. package/lib/chunks/{SDNESV5E.js → 47H7SS4U.js} +1 -1
  11. package/lib/chunks/{SXOXAG7R.js → 5PG3ST2N.js} +2 -2
  12. package/lib/chunks/{V46KUEYR.js → 6DO6IN4A.js} +1 -1
  13. package/lib/chunks/6ETCN64B.js +20 -0
  14. package/lib/chunks/{XZKUPNLZ.js → 6GH5BRNP.js} +1 -1
  15. package/lib/chunks/{O5WCU6SC.js → 6L6AYZQS.js} +10 -10
  16. package/lib/chunks/{72ZX5WSN.js → 6NGWHZCB.js} +1 -1
  17. package/lib/chunks/{HSHAARAO.js → 6ZVVKLZR.js} +1 -1
  18. package/lib/chunks/{DAAOXDSB.js → 7FLYZDPU.js} +1 -1
  19. package/lib/chunks/{SL6UQOKE.js → 7RZON3J3.js} +1 -1
  20. package/lib/chunks/{GYKYFMW3.js → B6HOY6AV.js} +1 -1
  21. package/lib/chunks/DDAZZC3I.js +20 -0
  22. package/lib/chunks/{PKYNMOKV.js → DNQSGL2N.js} +1 -1
  23. package/lib/chunks/{UXSV2J6V.js → E5BMYA7V.js} +1 -1
  24. package/lib/chunks/ERFYZ47T.js +11 -0
  25. package/lib/chunks/{MJYI42E6.js → F6IXS3RL.js} +1 -1
  26. package/lib/chunks/{BHUCIWQF.js → FAIK7Y6U.js} +1 -1
  27. package/lib/chunks/{SNR3DAVL.js → FAZWASU6.js} +1 -1
  28. package/lib/chunks/{HFGKPU2P.js → FDMXHRDK.js} +1 -1
  29. package/lib/chunks/{HZZP3BZQ.js → FUH5ZFZ2.js} +1 -1
  30. package/lib/chunks/{RDMFHSDB.js → GGRILIN6.js} +1 -1
  31. package/lib/chunks/{HNKSHJLU.js → GJDVFWVH.js} +1 -1
  32. package/lib/chunks/{GHPOEF7A.js → GLOLLUKD.js} +1 -1
  33. package/lib/chunks/{N4AA4DRD.js → GZ7EDJXV.js} +1 -1
  34. package/lib/chunks/{WFIIXHF3.js → HBPMIV7U.js} +1 -1
  35. package/lib/chunks/{HVO5F4MP.js → HHJX3B7U.js} +1 -1
  36. package/lib/chunks/{HQUG6XPO.js → IKDYY4XW.js} +2 -2
  37. package/lib/chunks/{Q526MFO3.js → IMYWYFYT.js} +1 -1
  38. package/lib/chunks/{MCJLOALK.js → IRHTRVFK.js} +1 -1
  39. package/lib/chunks/{CEPC3LL4.js → JP2RKFML.js} +1 -1
  40. package/lib/chunks/{52MW7SRF.js → KRCCY64H.js} +1 -1
  41. package/lib/chunks/{QGUZ4KFX.js → KVXNE2UB.js} +1 -1
  42. package/lib/chunks/{S5G22GL5.js → LR2FZ43E.js} +1 -1
  43. package/lib/chunks/{4XDEFJCF.js → LRLGVYCG.js} +1 -1
  44. package/lib/chunks/{DJWI7SF7.js → LXU55G2P.js} +1 -1
  45. package/lib/chunks/{NADFEIIN.js → MAHMSXK6.js} +1 -1
  46. package/lib/chunks/{3MPID4OC.js → MK6X55UC.js} +1 -1
  47. package/lib/chunks/{XHDOW23C.js → MNH2K4WM.js} +1 -1
  48. package/lib/chunks/{ZJAFKITR.js → MUKYSFRK.js} +1 -1
  49. package/lib/chunks/MXOINKB2.js +7 -0
  50. package/lib/chunks/{YNPWONFN.js → OP7NIAI7.js} +1 -1
  51. package/lib/chunks/{LF35KJ5M.js → OXA7GLZA.js} +1 -1
  52. package/lib/chunks/{CKZ35ARL.js → PSEWUH36.js} +1 -1
  53. package/lib/chunks/{ACVFQG4D.js → PTNNX4IU.js} +1 -1
  54. package/lib/chunks/{J4NCFMOR.js → QFJ6QZPG.js} +1 -1
  55. package/lib/chunks/{W3K4YAMS.js → RPHIT72T.js} +1 -1
  56. package/lib/chunks/{DTMC35L3.js → RPQMBRTA.js} +1 -1
  57. package/lib/chunks/{CAJM6OL3.js → SFNDGMJM.js} +1 -1
  58. package/lib/chunks/{VCV3FKMW.js → SLQPKXO2.js} +1 -1
  59. package/lib/chunks/{7ED6ZTTH.js → SYWAPWW7.js} +1 -1
  60. package/lib/chunks/{UPHYYNN3.js → SZVRKEMY.js} +5 -5
  61. package/lib/chunks/{O4RAFGZA.js → TBZEEKTV.js} +1 -1
  62. package/lib/chunks/{EXCIOEBN.js → US7X4XPD.js} +1 -1
  63. package/lib/chunks/{4WAQNM63.js → V5CIDI6D.js} +58 -12
  64. package/lib/chunks/WCWEP2X5.js +20 -0
  65. package/lib/chunks/{4HEJ6GQB.js → WEOCCL26.js} +2 -2
  66. package/lib/chunks/{2F2YM4RD.js → WSOBFTCE.js} +1 -1
  67. package/lib/chunks/{2U6O26CV.js → XJE2OFDN.js} +116 -16
  68. package/lib/chunks/{GD6WKI2C.js → YEOWW3LR.js} +1 -1
  69. package/lib/chunks/{S46ENZHC.js → ZH5HJBCG.js} +1 -1
  70. package/lib/chunks/{S27TE7KZ.js → ZOE6CZ74.js} +1 -1
  71. package/lib/eject-assets/AGENTS.md +24 -23
  72. package/lib/eject-assets/generators/cli/docs.ts +1 -1
  73. package/lib/eject-assets/generators/cli/engine-source.ts +1 -1
  74. package/lib/eject-assets/generators/cli/index.ts +2 -2
  75. package/lib/eject-assets/generators/cli/render.ts +1 -1
  76. package/lib/eject-assets/generators/go/client.ts +1 -1
  77. package/lib/eject-assets/generators/go/descriptor.ts +1 -1
  78. package/lib/eject-assets/generators/go/index.ts +2 -2
  79. package/lib/eject-assets/generators/go/models.ts +1 -1
  80. package/lib/eject-assets/generators/go/naming.ts +1 -1
  81. package/lib/eject-assets/generators/go/operations.ts +35 -3
  82. package/lib/eject-assets/generators/go/pagination.ts +1 -1
  83. package/lib/eject-assets/generators/go/types.ts +1 -1
  84. package/lib/eject-assets/generators/mock/faker.ts +1 -1
  85. package/lib/eject-assets/generators/mock/index.ts +2 -2
  86. package/lib/eject-assets/generators/mock/render.ts +1 -1
  87. package/lib/eject-assets/generators/mock/sample.ts +1 -1
  88. package/lib/eject-assets/generators/mock/values.ts +1 -1
  89. package/lib/eject-assets/generators/php/client.ts +1 -1
  90. package/lib/eject-assets/generators/php/descriptor.ts +1 -1
  91. package/lib/eject-assets/generators/php/index.ts +2 -2
  92. package/lib/eject-assets/generators/php/models.ts +1 -1
  93. package/lib/eject-assets/generators/php/naming.ts +1 -1
  94. package/lib/eject-assets/generators/php/operations.ts +21 -3
  95. package/lib/eject-assets/generators/php/pagination.ts +1 -1
  96. package/lib/eject-assets/generators/php/types.ts +1 -1
  97. package/lib/eject-assets/generators/python/client.ts +1 -1
  98. package/lib/eject-assets/generators/python/descriptor.ts +1 -1
  99. package/lib/eject-assets/generators/python/index.ts +2 -2
  100. package/lib/eject-assets/generators/python/models.ts +1 -1
  101. package/lib/eject-assets/generators/python/naming.ts +1 -1
  102. package/lib/eject-assets/generators/python/operations.ts +19 -6
  103. package/lib/eject-assets/generators/python/pagination.ts +1 -1
  104. package/lib/eject-assets/generators/python/types.ts +1 -1
  105. package/lib/eject-assets/generators/swr/index.ts +2 -2
  106. package/lib/eject-assets/generators/swr/render.ts +1 -1
  107. package/lib/eject-assets/generators/tanstack-query/index.ts +2 -2
  108. package/lib/eject-assets/generators/tanstack-query/render.ts +1 -1
  109. package/lib/eject-assets/generators/transformers/index.ts +2 -2
  110. package/lib/eject-assets/generators/transformers/render.ts +1 -1
  111. package/lib/eject-assets/generators/typescript/banner.ts +1 -1
  112. package/lib/eject-assets/generators/typescript/client.ts +1 -1
  113. package/lib/eject-assets/generators/typescript/descriptor.ts +1 -1
  114. package/lib/eject-assets/generators/typescript/index.ts +2 -2
  115. package/lib/eject-assets/generators/typescript/inline-runtime.ts +1 -1
  116. package/lib/eject-assets/generators/typescript/operation-signature.ts +1 -1
  117. package/lib/eject-assets/generators/typescript/operation-types.ts +1 -1
  118. package/lib/eject-assets/generators/typescript/operations.ts +3 -4
  119. package/lib/eject-assets/generators/typescript/response-headers.ts +1 -1
  120. package/lib/eject-assets/generators/typescript/type-guards.ts +1 -1
  121. package/lib/eject-assets/generators/typescript/types.ts +1 -1
  122. package/lib/eject-assets/generators/zod/index.ts +2 -2
  123. package/lib/eject-assets/generators/zod/schemas.ts +1 -1
  124. package/lib/eject-assets/skills/client-generators/SKILL.md +24 -23
  125. package/lib/eject-assets/skills/go-generator/SKILL.md +11 -0
  126. package/lib/eject-assets/skills/php-generator/SKILL.md +16 -0
  127. package/lib/eject-assets/skills/python-generator/SKILL.md +13 -0
  128. package/lib/eject-assets/skills/typescript-generator/SKILL.md +16 -0
  129. package/lib/index.js +54 -54
  130. package/package.json +1 -1
  131. package/lib/chunks/BZBFESBB.js +0 -11
  132. package/lib/chunks/DJXBNZCO.js +0 -7
  133. package/lib/chunks/GC26XZYZ.js +0 -20
  134. package/lib/chunks/IJ43XWPG.js +0 -20
  135. package/lib/chunks/OKTLNLO3.js +0 -7
  136. package/lib/chunks/PGZIUA7J.js +0 -105
  137. package/lib/chunks/XQA4EEZA.js +0 -20
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "php" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "php" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator php --update`.
@@ -8,7 +8,9 @@
8
8
  import {
9
9
  type ApiModel,
10
10
  type DateType,
11
+ isBinaryContentType,
11
12
  isMultipartBody,
13
+ isUntypedMultipartBody,
12
14
  jsonSuccessSchema,
13
15
  type OperationModel,
14
16
  sseResponse,
@@ -36,6 +38,14 @@ type MethodArgs = {
36
38
  */
37
39
  const SIGNATURE_ARG_SLOTS = ['body', 'headers', 'idempotencyKey'];
38
40
 
41
+ /** Whether the body is `mixed` and the runtime sorts out what it got (`multipartBody` / `binaryBody`). */
42
+ function passesThrough(op: OperationModel): boolean {
43
+ return (
44
+ isUntypedMultipartBody(op) ||
45
+ (op.requestBody !== undefined && isBinaryContentType(op.requestBody.contentType))
46
+ );
47
+ }
48
+
39
49
  export function methodArgs(
40
50
  op: OperationModel,
41
51
  model: ApiModel,
@@ -68,7 +78,7 @@ export function methodArgs(
68
78
  ...pathArgs.map(({ php, type }) => `${type} ${'$'}${php}`),
69
79
  ...(includeBody && op.requestBody
70
80
  ? [
71
- `${isMultipartBody(op) ? 'array' : phpType(op.requestBody.schema, model, dateType)} ${'$'}body`,
81
+ `${passesThrough(op) ? 'mixed' : isMultipartBody(op) ? 'array' : phpType(op.requestBody.schema, model, dateType)} ${'$'}body`,
72
82
  ]
73
83
  : []),
74
84
  ...queryArgs.map(({ php, type }) => {
@@ -181,7 +191,15 @@ export function writePhpMethod(
181
191
  `'headers' => $requestHeaders`,
182
192
  `'query' => $query`,
183
193
  ];
184
- if (op.requestBody && isMultipartBody(op)) {
194
+ if (isUntypedMultipartBody(op)) {
195
+ printer.line('[$contentType, $encoded] = multipartBody($body);');
196
+ request.push(`'body' => $encoded`, `'contentType' => $contentType`);
197
+ } else if (op.requestBody && passesThrough(op)) {
198
+ request.push(
199
+ `'body' => binaryBody($body)`,
200
+ `'contentType' => ${phpString(op.requestBody.contentType)}`
201
+ );
202
+ } else if (op.requestBody && isMultipartBody(op)) {
185
203
  printer.line('[$contentType, $encoded] = toMultipart($body);');
186
204
  request.push(`'body' => $encoded`, `'contentType' => $contentType`);
187
205
  } else if (op.requestBody) {
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "php" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "php" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator php --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "php" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "php" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator php --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -247,5 +247,5 @@ export default {
247
247
  "argsStyle": "inputs follow the target language's own idiom",
248
248
  "importExt": "the generated file has no relative imports"
249
249
  },
250
- requiresGenerator: '^0.4.25',
250
+ requiresGenerator: '^0.5.0',
251
251
  };
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -8,7 +8,9 @@
8
8
  import {
9
9
  type ApiModel,
10
10
  type DateType,
11
+ isBinaryContentType,
11
12
  isMultipartBody,
13
+ isUntypedMultipartBody,
12
14
  jsonSuccessSchema,
13
15
  type OperationModel,
14
16
  sseResponse,
@@ -46,7 +48,12 @@ export function writeMethod(
46
48
  const positional = pathArgs.map(
47
49
  ({ param, python }) => `${python}: ${pythonType(param.schema, dateType)}`
48
50
  );
49
- const bodyArg = op.requestBody ? [`body: ${pythonType(op.requestBody.schema, dateType)}`] : [];
51
+ const passThrough =
52
+ isUntypedMultipartBody(op) ||
53
+ (op.requestBody !== undefined && isBinaryContentType(op.requestBody.contentType));
54
+ const bodyArg = op.requestBody
55
+ ? [`body: ${passThrough ? 'Any' : pythonType(op.requestBody.schema, dateType)}`]
56
+ : [];
50
57
  const kwargs = [
51
58
  ...queryArgs.map(({ param, python }) => {
52
59
  const annotation = pythonType(param.schema, dateType);
@@ -105,11 +112,17 @@ export function writeMethod(
105
112
  printer.line(`return ${isAsync ? 'aiter_sse' : 'iter_sse'}(_open, data_kind="${dataKind}")`);
106
113
  return;
107
114
  }
108
- if (isMultipartBody(op)) printer.line('form_data, form_files = to_multipart(body)');
115
+ if (isMultipartBody(op) && !isUntypedMultipartBody(op)) {
116
+ printer.line('form_data, form_files = to_multipart(body)');
117
+ }
109
118
  const bodyKw = op.requestBody
110
- ? isMultipartBody(op)
111
- ? ', data=form_data, files=form_files'
112
- : ', json_body=encode(body)'
119
+ ? isUntypedMultipartBody(op)
120
+ ? ', **multipart_arguments(body)'
121
+ : isMultipartBody(op)
122
+ ? ', data=form_data, files=form_files'
123
+ : isBinaryContentType(op.requestBody.contentType)
124
+ ? `, content=body, content_type=${naming.string(op.requestBody.contentType)}`
125
+ : ', json_body=encode(body)'
113
126
  : '';
114
127
  printer.line(
115
128
  `response = ${awaitKw}${sendFn}(self._http, self._config, op, url, method=op["method"], ` +
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "python" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "python" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator python --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "swr" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "swr" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator swr --update`.
@@ -33,5 +33,5 @@ export default {
33
33
  run: swrGenerator,
34
34
  requires: ["typescript"],
35
35
  errorModes: ["throw"],
36
- requiresGenerator: '^0.4.25',
36
+ requiresGenerator: '^0.5.0',
37
37
  };
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "swr" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "swr" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator swr --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "tanstack-query" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "tanstack-query" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator tanstack-query --update`.
@@ -44,5 +44,5 @@ export default {
44
44
  run: tanstackQueryGenerator('react'),
45
45
  requires: ["typescript"],
46
46
  errorModes: ["throw"],
47
- requiresGenerator: '^0.4.25',
47
+ requiresGenerator: '^0.5.0',
48
48
  };
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "tanstack-query" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "tanstack-query" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator tanstack-query --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "transformers" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "transformers" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator transformers --update`.
@@ -42,5 +42,5 @@ export default {
42
42
  run: transformersGenerator,
43
43
  requires: ["typescript"],
44
44
  dateTypes: ["Date"],
45
- requiresGenerator: '^0.4.25',
45
+ requiresGenerator: '^0.5.0',
46
46
  };
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "transformers" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "transformers" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator transformers --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -97,5 +97,5 @@ export default {
97
97
  run: typescriptGenerator,
98
98
  sample: typescriptSample,
99
99
  docs: typescriptDocs,
100
- requiresGenerator: '^0.4.25',
100
+ requiresGenerator: '^0.5.0',
101
101
  };
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -51,13 +51,12 @@ const INDENT = ' ';
51
51
  /** The request-body TS type: special wrapper types per content-type, else the schema. */
52
52
  export function bodyTypeText(rb: RequestBodyModel, dateType: DateType, indent = ''): string {
53
53
  if (isTypedMultipart(rb)) return tsType(rb.schema, dateType, indent);
54
+ if (isBinaryContentType(rb.contentType)) return 'Blob | ArrayBuffer | ReadableStream';
54
55
  switch (rb.contentType) {
55
56
  case 'multipart/form-data':
56
- return 'FormData';
57
+ return 'FormData | ReadableStream';
57
58
  case 'application/x-www-form-urlencoded':
58
59
  return 'URLSearchParams';
59
- case 'application/octet-stream':
60
- return 'Blob | ArrayBuffer';
61
60
  default:
62
61
  return tsType(rb.schema, dateType, indent);
63
62
  }
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "typescript" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "typescript" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator typescript --update`.
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "zod" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "zod" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator zod --update`.
@@ -28,5 +28,5 @@ export const zodGenerator: Generator = ({ model, output, banner }) => {
28
28
  export default {
29
29
  name: 'zod',
30
30
  run: zodGenerator,
31
- requiresGenerator: '^0.4.25',
31
+ requiresGenerator: '^0.5.0',
32
32
  };
@@ -1,4 +1,4 @@
1
- // Ejected from @redocly/client-generator@0.4.25 — the built-in "zod" generator.
1
+ // Ejected from @redocly/client-generator@0.5.0 — the built-in "zod" generator.
2
2
  // This file is yours: edit freely; the generated client stays machine-owned and is
3
3
  // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
4
  // `redocly eject-generator zod --update`.
@@ -96,29 +96,30 @@ discriminated union on `kind`: `scalar`, `array`, `object`, `record`, `ref`,
96
96
 
97
97
  ## Helpers (import from '@redocly/client-generator')
98
98
 
99
- | Helper | Use |
100
- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
101
- | `flattenAllOf(schema, model)` | The merged property view of allOf compositions — languages without intersection types render this. |
102
- | `deref(schema, model)` | Follow a `ref` chain to the schema it names (cycle-guarded). |
103
- | `jsonSuccessSchema(op)` / `sseResponse(op)` | The primary JSON success schema; the `text/event-stream` response when the operation streams. |
104
- | `isMultipartBody(op)` | Whether the request body is multipart. |
105
- | `isBinaryContentType(contentType)` | Whether a body of this content type is bytes (archives, PDF, images, media) — decode it as a Blob, not JSON or text. |
106
- | `serverUrlParts(server)` | A server-URL template as literal/variable parts, ready for any concatenation syntax. |
107
- | `securityRequirements(op, model)` | The operation's security as OR-alternatives of AND-sets, denormalized against the declared schemes. |
108
- | `paginationItemSchema(pageSchema, itemsPointer, model)` | The raw element schema behind a pagination rule's `items` pointer — a `ref` element keeps its name. |
109
- | `discriminatorCases(schema, model)` | `{ property, cases }` dispatch table for discriminated unions. |
110
- | `isNullable(schema)` / `unwrapNullable(schema)` | Detect and strip `null` union members (`Optional[T]`, pointers, `Option<T>`). |
111
- | `enumValues(schema)` | Values plus SCREAMING_SNAKE member-name suggestions. |
112
- | `headerCoerceType(schema, model)` | Response-header coerce hint (`integer`/`number`/`boolean`/`string`) through refs, nullables, and allOf wrappers. |
113
- | `casing` / `identifierFor(name, { style, reserved })` | camel/pascal/snake/screaming; keyword-safe identifiers (`RESERVED_WORDS.python/go/typescript` shipped). |
114
- | `uniqueIdentifiers(names, { style, reserved, taken })` | The same, made unique among themselves and among names you already took — for a signature that takes one argument per parameter. |
115
- | `Printer` | Indentation-aware text builder — no manual whitespace bookkeeping. |
116
- | `docText(description)` | Description as trimmed lines for any comment syntax. |
117
- | `schemaAtPointer(schema, pointer, model)` | Resolve an RFC 6901 JSON pointer over a schema (through refs and allOf) — e.g. a pagination `items` pointer to its element type. |
118
- | `paginationRuleFor(op, config)` | The pagination rule that applies to an operation (per-op config > extension > fitting convention), normalized. |
119
- | `renderReferencePage(model, options)` | The Markdown reference page a generator's `docs` hook returns — your `sample` hook supplies its call snippets. |
120
- | `NotSupportedError` | Throw it to reject an option the generator can't honor — the CLI prints the message as a user error, not a crash. |
121
- | `AUTHORING_HELPER_NAMES` | The list of the above (introspection). |
99
+ | Helper | Use |
100
+ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
101
+ | `flattenAllOf(schema, model)` | The merged property view of allOf compositions — languages without intersection types render this. |
102
+ | `deref(schema, model)` | Follow a `ref` chain to the schema it names (cycle-guarded). |
103
+ | `jsonSuccessSchema(op)` / `sseResponse(op)` | The primary JSON success schema; the `text/event-stream` response when the operation streams. |
104
+ | `isMultipartBody(op)` | Whether the request body is multipart. |
105
+ | `isUntypedMultipartBody(op)` | Whether the request body is multipart with a schema that is neither an object nor a `$ref`, so the caller supplies the encoded body. |
106
+ | `isBinaryContentType(contentType)` | Whether a body of this content type is bytes (archives, PDF, images, media) — decode it as a Blob, not JSON or text. |
107
+ | `serverUrlParts(server)` | A server-URL template as literal/variable parts, ready for any concatenation syntax. |
108
+ | `securityRequirements(op, model)` | The operation's security as OR-alternatives of AND-sets, denormalized against the declared schemes. |
109
+ | `paginationItemSchema(pageSchema, itemsPointer, model)` | The raw element schema behind a pagination rule's `items` pointer — a `ref` element keeps its name. |
110
+ | `discriminatorCases(schema, model)` | `{ property, cases }` dispatch table for discriminated unions. |
111
+ | `isNullable(schema)` / `unwrapNullable(schema)` | Detect and strip `null` union members (`Optional[T]`, pointers, `Option<T>`). |
112
+ | `enumValues(schema)` | Values plus SCREAMING_SNAKE member-name suggestions. |
113
+ | `headerCoerceType(schema, model)` | Response-header coerce hint (`integer`/`number`/`boolean`/`string`) through refs, nullables, and allOf wrappers. |
114
+ | `casing` / `identifierFor(name, { style, reserved })` | camel/pascal/snake/screaming; keyword-safe identifiers (`RESERVED_WORDS.python/go/typescript` shipped). |
115
+ | `uniqueIdentifiers(names, { style, reserved, taken })` | The same, made unique among themselves and among names you already took — for a signature that takes one argument per parameter. |
116
+ | `Printer` | Indentation-aware text builder — no manual whitespace bookkeeping. |
117
+ | `docText(description)` | Description as trimmed lines for any comment syntax. |
118
+ | `schemaAtPointer(schema, pointer, model)` | Resolve an RFC 6901 JSON pointer over a schema (through refs and allOf) — e.g. a pagination `items` pointer to its element type. |
119
+ | `paginationRuleFor(op, config)` | The pagination rule that applies to an operation (per-op config > extension > fitting convention), normalized. |
120
+ | `renderReferencePage(model, options)` | The Markdown reference page a generator's `docs` hook returns — your `sample` hook supplies its call snippets. |
121
+ | `NotSupportedError` | Throw it to reject an option the generator can't honor — the CLI prints the message as a user error, not a crash. |
122
+ | `AUTHORING_HELPER_NAMES` | The list of the above (introspection). |
122
123
 
123
124
  Worked example: the built-in `python` generator
124
125
  (`packages/client-generator/src/generators/python/index.ts` in the Redocly CLI repo) is
@@ -55,6 +55,17 @@ runtime. Go ≥ 1.21, standard library only — zero dependencies.
55
55
  parameters (Go has no defaults — the doc comment states the spec default), so templated
56
56
  base URLs need no manual string building. The client's baked default stays `servers[0]`
57
57
  with variable defaults substituted.
58
+ - **Stream bodies pass through.** For an untyped `multipart/form-data` operation
59
+ (`isUntypedMultipartBody` from the toolkit: a schema that is neither an object nor a
60
+ `$ref`) or a binary operation (`isBinaryContentType`), the body argument is `any` and
61
+ the runtime sorts it out (`multipartBody` / `binaryBody`): an `io.Reader` is the
62
+ request body as is, with no `io.ReadAll` and exactly one attempt (a consumed reader
63
+ cannot be replayed, whatever the retry policy says); a `[]byte` or a `string` is sent as
64
+ bytes, not JSON-marshalled, and stays replayable, so retries stay; a map or struct body
65
+ of an untyped multipart operation keeps the `toMultipart` path. The description's (or
66
+ the multipart boundary's) `Content-Type` is applied only when the caller set none, so a
67
+ forwarded boundary survives; that rule holds for every operation. The per-attempt
68
+ timeout still applies. Typed multipart bodies are unaffected.
58
69
  - **Parity surface:** auth, retries with `Retry-After` + jittered backoff, per-attempt
59
70
  `context.WithTimeout`, idempotency keys, middleware, pagination (`<Op>Pages`/`<Op>Items`
60
71
  as `func(yield func(T, error) bool)` — `range`-over-func needs Go ≥ 1.23; 1.21 calls
@@ -76,6 +76,22 @@ extension — zero Composer dependencies. The namespace derives from the API tit
76
76
  to the spec's defaults (`Servers::production(organizationId: 'org_x')`), so templated
77
77
  base URLs need no manual string building. The client's baked default stays `servers[0]`
78
78
  with variable defaults substituted.
79
+ - **Stream bodies pass through.** For an untyped `multipart/form-data` operation
80
+ (`isUntypedMultipartBody` from the toolkit: a schema that is neither an object nor a
81
+ `$ref`) or a binary operation (`isBinaryContentType`), the body is `mixed` and the
82
+ runtime sorts it out (`multipartBody` / `binaryBody`): a stream `resource` is uploaded
83
+ by curl in chunks (`CURLOPT_UPLOAD` + `CURLOPT_INFILE`, the method kept by
84
+ `CURLOPT_CUSTOMREQUEST`), never read into a string, in exactly one attempt, whatever
85
+ the retry policy says (the default is three attempts for any method), because a
86
+ consumed stream cannot be replayed. `CURLOPT_INFILESIZE` is set only when the stream is
87
+ seekable AND `fstat` returns an array (the bytes left from the current position);
88
+ `php://input`, pipes, and wrappers without `stream_stat` go chunked. A `string` body of
89
+ either operation is sent raw, not `json_encode`d; any other binary-operation value is
90
+ still `json_encode`d; an `array` body of an untyped multipart operation keeps the
91
+ `toMultipart` path. The caller's `Content-Type` wins over the description's or the
92
+ multipart boundary's, matched case-insensitively in `send` so the header is never sent
93
+ twice; that rule holds for every operation. The whole-request curl timeout still
94
+ applies (`timeout: null` disables it). Typed multipart bodies are unaffected.
79
95
  - **Parity surface:** auth, retries with `Retry-After` + jittered backoff, per-attempt
80
96
  curl timeouts, middleware callables, pagination (`<op>Pages()` / `<op>Items()` as
81
97
  `\Generator`s), SSE (`iterSse` over a curl_multi pump), multipart.
@@ -82,6 +82,19 @@ One self-contained `<stem>.py`: typed dataclass models, a sync `Client` and an a
82
82
  the spec's defaults (`Servers.production(organization_id="org_x")`), so templated base
83
83
  URLs need no manual string building. The client's baked default stays `servers[0]`
84
84
  with variable defaults substituted.
85
+ - **Stream bodies pass through.** For an untyped `multipart/form-data` operation
86
+ (`isUntypedMultipartBody`) or a binary operation (`isBinaryContentType`), the body
87
+ argument is `Any`, and a body that is `bytes`/`bytearray`, a `str`, a
88
+ file-like object (a callable `.read`), or an iterator/async iterator of bytes goes to httpx
89
+ `content=`, never through `json=` or `to_multipart`; a `dict` body of an untyped
90
+ multipart operation keeps the `to_multipart` path. The runtime sets the operation's
91
+ declared content type only when the caller set none (matched case-insensitively), and
92
+ never for a multipart body, whose boundary is the caller's. A body that cannot be
93
+ replayed (a file-like object or iterator, as opposed to `bytes` or `str`) is sent in
94
+ exactly one attempt, whatever the retry policy says. The per-attempt `timeout` still
95
+ applies. Both the sync and the async `send` behave the same. Typed multipart bodies
96
+ are unaffected: they go straight to `to_multipart` and never through stream detection,
97
+ so a model field named `read` cannot turn one into a raw upload.
85
98
  - **Parity surface:** auth (bearer/basic/apiKey), retries with `Retry-After` + jittered
86
99
  backoff, timeouts, idempotency keys, middleware, pagination (`<op>_pages()` /
87
100
  `<op>_items()` + `aiter` mirrors), SSE (`iter_sse`/`aiter_sse`), multipart.
@@ -40,6 +40,22 @@ relatively (`runtime: module`).
40
40
  layer — `path`, `query`, `headers`, `cookies`, `body` — and `flat` merges them into one
41
41
  object, which the runtime converts back using the descriptor's own parameter list. An
42
42
  operation whose merged names would collide keeps the grouped shape.
43
+ - **Stream bodies pass through.** A request body that is a `ReadableStream`, or any
44
+ async iterable of bytes (a Node `Readable`), is a pass-through upload: `send()` hands it
45
+ to `fetch` untouched with `duplex: 'half'` and makes exactly one attempt, because a
46
+ consumed stream cannot be replayed, whatever the retry policy says. The whole-attempt
47
+ `timeout` still applies; callers pass `timeout: 0` or a budget that fits the upload per
48
+ call. The body type of an untyped `multipart/form-data` operation is
49
+ `FormData | ReadableStream`, and of a binary operation (`isBinaryContentType`:
50
+ `application/octet-stream`, `application/pdf`, images, audio, video, fonts, zip)
51
+ `Blob | ArrayBuffer | ReadableStream`. The client stays free of Node types: a Node
52
+ request becomes a web stream with `Readable.toWeb(request)`. Typed multipart objects
53
+ are unaffected.
54
+ - **The caller's `Content-Type` wins; the description's fills the gap.** For a
55
+ pass-through body other than `FormData` or `URLSearchParams` (whose type `fetch`
56
+ derives, boundary included), `send()` sets the operation's declared content type only
57
+ when the caller set none, the same rule the JSON branch already follows. A forwarded
58
+ multipart boundary therefore survives, and a binary upload is never sent untyped.
43
59
  - **Throw mode returns the body**; `{ envelope: true }` opts into
44
60
  `{ data, headers, response }` with typed declared headers. Result mode returns
45
61
  `{ data, error, response }` and ignores `envelope`.