@ir-kit/openapi-kotlin 2.0.0 → 3.0.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 (297) hide show
  1. package/README.md +13 -13
  2. package/dist/ast/index.d.ts +152 -0
  3. package/dist/ast/index.d.ts.map +1 -0
  4. package/dist/ast/index.js +159 -0
  5. package/dist/ast/index.js.map +1 -0
  6. package/dist/generate.d.ts +1 -1
  7. package/dist/generate.d.ts.map +1 -1
  8. package/dist/generate.js +13 -27
  9. package/dist/generate.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/ir/identifiers.d.ts +7 -0
  15. package/dist/ir/identifiers.d.ts.map +1 -1
  16. package/dist/ir/identifiers.js +92 -3
  17. package/dist/ir/identifiers.js.map +1 -1
  18. package/dist/ir/impl/body.d.ts +4 -3
  19. package/dist/ir/impl/body.d.ts.map +1 -1
  20. package/dist/ir/impl/body.js +36 -37
  21. package/dist/ir/impl/body.js.map +1 -1
  22. package/dist/ir/impl/decode.d.ts +3 -2
  23. package/dist/ir/impl/decode.d.ts.map +1 -1
  24. package/dist/ir/impl/decode.js +16 -16
  25. package/dist/ir/impl/decode.js.map +1 -1
  26. package/dist/ir/impl/headers.d.ts +1 -1
  27. package/dist/ir/impl/headers.d.ts.map +1 -1
  28. package/dist/ir/impl/headers.js +3 -3
  29. package/dist/ir/impl/headers.js.map +1 -1
  30. package/dist/ir/impl/index.d.ts +5 -2
  31. package/dist/ir/impl/index.d.ts.map +1 -1
  32. package/dist/ir/impl/index.js +6 -7
  33. package/dist/ir/impl/index.js.map +1 -1
  34. package/dist/ir/impl/request.d.ts +6 -6
  35. package/dist/ir/impl/request.d.ts.map +1 -1
  36. package/dist/ir/impl/request.js +18 -8
  37. package/dist/ir/impl/request.js.map +1 -1
  38. package/dist/ir/impl/serializer.d.ts +4 -2
  39. package/dist/ir/impl/serializer.d.ts.map +1 -1
  40. package/dist/ir/impl/serializer.js +41 -60
  41. package/dist/ir/impl/serializer.js.map +1 -1
  42. package/dist/ir/impl/url.d.ts +1 -1
  43. package/dist/ir/impl/url.d.ts.map +1 -1
  44. package/dist/ir/impl/url.js +4 -4
  45. package/dist/ir/impl/url.js.map +1 -1
  46. package/dist/ir/index.d.ts +1 -1
  47. package/dist/ir/index.d.ts.map +1 -1
  48. package/dist/ir/index.js +1 -1
  49. package/dist/ir/index.js.map +1 -1
  50. package/dist/ir/operation/body.d.ts +1 -1
  51. package/dist/ir/operation/body.d.ts.map +1 -1
  52. package/dist/ir/operation/body.js +3 -3
  53. package/dist/ir/operation/body.js.map +1 -1
  54. package/dist/ir/operation/params.d.ts +1 -1
  55. package/dist/ir/operation/params.d.ts.map +1 -1
  56. package/dist/ir/operation/params.js +3 -3
  57. package/dist/ir/operation/params.js.map +1 -1
  58. package/dist/ir/operation/response.d.ts +3 -1
  59. package/dist/ir/operation/response.d.ts.map +1 -1
  60. package/dist/ir/operation/response.js +3 -4
  61. package/dist/ir/operation/response.js.map +1 -1
  62. package/dist/ir/operation/signature.d.ts +4 -2
  63. package/dist/ir/operation/signature.d.ts.map +1 -1
  64. package/dist/ir/operation/signature.js +5 -4
  65. package/dist/ir/operation/signature.js.map +1 -1
  66. package/dist/ir/operations.d.ts +7 -1
  67. package/dist/ir/operations.d.ts.map +1 -1
  68. package/dist/ir/operations.js +14 -17
  69. package/dist/ir/operations.js.map +1 -1
  70. package/dist/ir/runtime/index.d.ts +1 -1
  71. package/dist/ir/runtime/index.d.ts.map +1 -1
  72. package/dist/ir/runtime/index.js +1 -1
  73. package/dist/ir/runtime/index.js.map +1 -1
  74. package/dist/ir/runtime/templates.d.ts +1 -21
  75. package/dist/ir/runtime/templates.d.ts.map +1 -1
  76. package/dist/ir/runtime/templates.js +24 -428
  77. package/dist/ir/runtime/templates.js.map +1 -1
  78. package/dist/ir/schema.d.ts +3 -5
  79. package/dist/ir/schema.d.ts.map +1 -1
  80. package/dist/ir/schema.js +25 -37
  81. package/dist/ir/schema.js.map +1 -1
  82. package/dist/ir/type/context.d.ts +1 -1
  83. package/dist/ir/type/context.d.ts.map +1 -1
  84. package/dist/ir/type/index.d.ts +5 -3
  85. package/dist/ir/type/index.d.ts.map +1 -1
  86. package/dist/ir/type/index.js +12 -8
  87. package/dist/ir/type/index.js.map +1 -1
  88. package/dist/ir/type/primitive.d.ts +1 -1
  89. package/dist/ir/type/primitive.d.ts.map +1 -1
  90. package/dist/ir/type/primitive.js +1 -1
  91. package/dist/ir/type/primitive.js.map +1 -1
  92. package/dist/ir/type-ops.d.ts +2 -2
  93. package/dist/ir/type-ops.d.ts.map +1 -1
  94. package/dist/ir/type-ops.js +13 -17
  95. package/dist/ir/type-ops.js.map +1 -1
  96. package/dist/kt-compiler/index.d.ts +3 -6
  97. package/dist/kt-compiler/index.d.ts.map +1 -1
  98. package/dist/kt-compiler/index.js +7 -22
  99. package/dist/kt-compiler/index.js.map +1 -1
  100. package/dist/project/build.d.ts +1 -1
  101. package/dist/project/build.d.ts.map +1 -1
  102. package/dist/project/build.js +6 -8
  103. package/dist/project/build.js.map +1 -1
  104. package/dist/project/imports.d.ts +12 -12
  105. package/dist/project/imports.d.ts.map +1 -1
  106. package/dist/project/imports.js +60 -138
  107. package/dist/project/imports.js.map +1 -1
  108. package/dist/project/layout.d.ts +1 -1
  109. package/dist/project/layout.d.ts.map +1 -1
  110. package/dist/project/layout.js +1 -3
  111. package/dist/project/layout.js.map +1 -1
  112. package/package.json +12 -10
  113. package/runtime/APIClient.kt +140 -0
  114. package/runtime/APIError.kt +42 -0
  115. package/runtime/APIInterceptors.kt +14 -0
  116. package/runtime/APIKeyLocation.kt +7 -0
  117. package/runtime/Auth.kt +86 -0
  118. package/runtime/MultipartFormBody.kt +41 -0
  119. package/runtime/QueryStyle.kt +12 -0
  120. package/runtime/RequestOptions.kt +29 -0
  121. package/runtime/URLEncoding.kt +45 -0
  122. package/dist/kt-compiler/decl/class.d.ts +0 -6
  123. package/dist/kt-compiler/decl/class.d.ts.map +0 -1
  124. package/dist/kt-compiler/decl/class.js +0 -38
  125. package/dist/kt-compiler/decl/class.js.map +0 -1
  126. package/dist/kt-compiler/decl/dataClass.d.ts +0 -3
  127. package/dist/kt-compiler/decl/dataClass.d.ts.map +0 -1
  128. package/dist/kt-compiler/decl/dataClass.js +0 -18
  129. package/dist/kt-compiler/decl/dataClass.js.map +0 -1
  130. package/dist/kt-compiler/decl/enum.d.ts +0 -3
  131. package/dist/kt-compiler/decl/enum.d.ts.map +0 -1
  132. package/dist/kt-compiler/decl/enum.js +0 -32
  133. package/dist/kt-compiler/decl/enum.js.map +0 -1
  134. package/dist/kt-compiler/decl/fun.d.ts +0 -11
  135. package/dist/kt-compiler/decl/fun.d.ts.map +0 -1
  136. package/dist/kt-compiler/decl/fun.js +0 -69
  137. package/dist/kt-compiler/decl/fun.js.map +0 -1
  138. package/dist/kt-compiler/decl/index.d.ts +0 -13
  139. package/dist/kt-compiler/decl/index.d.ts.map +0 -1
  140. package/dist/kt-compiler/decl/index.js +0 -39
  141. package/dist/kt-compiler/decl/index.js.map +0 -1
  142. package/dist/kt-compiler/decl/interface.d.ts +0 -3
  143. package/dist/kt-compiler/decl/interface.d.ts.map +0 -1
  144. package/dist/kt-compiler/decl/interface.js +0 -15
  145. package/dist/kt-compiler/decl/interface.js.map +0 -1
  146. package/dist/kt-compiler/decl/object.d.ts +0 -3
  147. package/dist/kt-compiler/decl/object.d.ts.map +0 -1
  148. package/dist/kt-compiler/decl/object.js +0 -19
  149. package/dist/kt-compiler/decl/object.js.map +0 -1
  150. package/dist/kt-compiler/decl/prop.d.ts +0 -20
  151. package/dist/kt-compiler/decl/prop.d.ts.map +0 -1
  152. package/dist/kt-compiler/decl/prop.js +0 -42
  153. package/dist/kt-compiler/decl/prop.js.map +0 -1
  154. package/dist/kt-compiler/decl/sealedClass.d.ts +0 -3
  155. package/dist/kt-compiler/decl/sealedClass.d.ts.map +0 -1
  156. package/dist/kt-compiler/decl/sealedClass.js +0 -32
  157. package/dist/kt-compiler/decl/sealedClass.js.map +0 -1
  158. package/dist/kt-compiler/decl/topLevel.d.ts +0 -3
  159. package/dist/kt-compiler/decl/topLevel.d.ts.map +0 -1
  160. package/dist/kt-compiler/decl/topLevel.js +0 -5
  161. package/dist/kt-compiler/decl/topLevel.js.map +0 -1
  162. package/dist/kt-compiler/decl/typeAlias.d.ts +0 -3
  163. package/dist/kt-compiler/decl/typeAlias.d.ts.map +0 -1
  164. package/dist/kt-compiler/decl/typeAlias.js +0 -6
  165. package/dist/kt-compiler/decl/typeAlias.js.map +0 -1
  166. package/dist/kt-compiler/expr.d.ts +0 -4
  167. package/dist/kt-compiler/expr.d.ts.map +0 -1
  168. package/dist/kt-compiler/expr.js +0 -123
  169. package/dist/kt-compiler/expr.js.map +0 -1
  170. package/dist/kt-compiler/format.d.ts +0 -20
  171. package/dist/kt-compiler/format.d.ts.map +0 -1
  172. package/dist/kt-compiler/format.js +0 -27
  173. package/dist/kt-compiler/format.js.map +0 -1
  174. package/dist/kt-compiler/stmt.d.ts +0 -4
  175. package/dist/kt-compiler/stmt.d.ts.map +0 -1
  176. package/dist/kt-compiler/stmt.js +0 -72
  177. package/dist/kt-compiler/stmt.js.map +0 -1
  178. package/dist/kt-compiler/type.d.ts +0 -3
  179. package/dist/kt-compiler/type.d.ts.map +0 -1
  180. package/dist/kt-compiler/type.js +0 -28
  181. package/dist/kt-compiler/type.js.map +0 -1
  182. package/dist/kt-dsl/decl/class.d.ts +0 -50
  183. package/dist/kt-dsl/decl/class.d.ts.map +0 -1
  184. package/dist/kt-dsl/decl/class.js +0 -33
  185. package/dist/kt-dsl/decl/class.js.map +0 -1
  186. package/dist/kt-dsl/decl/dataClass.d.ts +0 -36
  187. package/dist/kt-dsl/decl/dataClass.d.ts.map +0 -1
  188. package/dist/kt-dsl/decl/dataClass.js +0 -25
  189. package/dist/kt-dsl/decl/dataClass.js.map +0 -1
  190. package/dist/kt-dsl/decl/enum.d.ts +0 -60
  191. package/dist/kt-dsl/decl/enum.d.ts.map +0 -1
  192. package/dist/kt-dsl/decl/enum.js +0 -38
  193. package/dist/kt-dsl/decl/enum.js.map +0 -1
  194. package/dist/kt-dsl/decl/index.d.ts +0 -11
  195. package/dist/kt-dsl/decl/index.d.ts.map +0 -1
  196. package/dist/kt-dsl/decl/index.js +0 -11
  197. package/dist/kt-dsl/decl/index.js.map +0 -1
  198. package/dist/kt-dsl/decl/interface.d.ts +0 -33
  199. package/dist/kt-dsl/decl/interface.d.ts.map +0 -1
  200. package/dist/kt-dsl/decl/interface.js +0 -24
  201. package/dist/kt-dsl/decl/interface.js.map +0 -1
  202. package/dist/kt-dsl/decl/object.d.ts +0 -34
  203. package/dist/kt-dsl/decl/object.d.ts.map +0 -1
  204. package/dist/kt-dsl/decl/object.js +0 -24
  205. package/dist/kt-dsl/decl/object.js.map +0 -1
  206. package/dist/kt-dsl/decl/prop.d.ts +0 -47
  207. package/dist/kt-dsl/decl/prop.d.ts.map +0 -1
  208. package/dist/kt-dsl/decl/prop.js +0 -28
  209. package/dist/kt-dsl/decl/prop.js.map +0 -1
  210. package/dist/kt-dsl/decl/sealedClass.d.ts +0 -68
  211. package/dist/kt-dsl/decl/sealedClass.d.ts.map +0 -1
  212. package/dist/kt-dsl/decl/sealedClass.js +0 -52
  213. package/dist/kt-dsl/decl/sealedClass.js.map +0 -1
  214. package/dist/kt-dsl/decl/topLevel.d.ts +0 -19
  215. package/dist/kt-dsl/decl/topLevel.d.ts.map +0 -1
  216. package/dist/kt-dsl/decl/topLevel.js +0 -17
  217. package/dist/kt-dsl/decl/topLevel.js.map +0 -1
  218. package/dist/kt-dsl/decl/typeAlias.d.ts +0 -23
  219. package/dist/kt-dsl/decl/typeAlias.d.ts.map +0 -1
  220. package/dist/kt-dsl/decl/typeAlias.js +0 -18
  221. package/dist/kt-dsl/decl/typeAlias.js.map +0 -1
  222. package/dist/kt-dsl/decl/types.d.ts +0 -10
  223. package/dist/kt-dsl/decl/types.d.ts.map +0 -1
  224. package/dist/kt-dsl/decl/types.js +0 -2
  225. package/dist/kt-dsl/decl/types.js.map +0 -1
  226. package/dist/kt-dsl/expr/access.d.ts +0 -48
  227. package/dist/kt-dsl/expr/access.d.ts.map +0 -1
  228. package/dist/kt-dsl/expr/access.js +0 -59
  229. package/dist/kt-dsl/expr/access.js.map +0 -1
  230. package/dist/kt-dsl/expr/call.d.ts +0 -38
  231. package/dist/kt-dsl/expr/call.d.ts.map +0 -1
  232. package/dist/kt-dsl/expr/call.js +0 -38
  233. package/dist/kt-dsl/expr/call.js.map +0 -1
  234. package/dist/kt-dsl/expr/index.d.ts +0 -7
  235. package/dist/kt-dsl/expr/index.d.ts.map +0 -1
  236. package/dist/kt-dsl/expr/index.js +0 -7
  237. package/dist/kt-dsl/expr/index.js.map +0 -1
  238. package/dist/kt-dsl/expr/literal.d.ts +0 -100
  239. package/dist/kt-dsl/expr/literal.d.ts.map +0 -1
  240. package/dist/kt-dsl/expr/literal.js +0 -108
  241. package/dist/kt-dsl/expr/literal.js.map +0 -1
  242. package/dist/kt-dsl/expr/misc.d.ts +0 -45
  243. package/dist/kt-dsl/expr/misc.d.ts.map +0 -1
  244. package/dist/kt-dsl/expr/misc.js +0 -63
  245. package/dist/kt-dsl/expr/misc.js.map +0 -1
  246. package/dist/kt-dsl/expr/op.d.ts +0 -25
  247. package/dist/kt-dsl/expr/op.d.ts.map +0 -1
  248. package/dist/kt-dsl/expr/op.js +0 -24
  249. package/dist/kt-dsl/expr/op.js.map +0 -1
  250. package/dist/kt-dsl/expr/types.d.ts +0 -93
  251. package/dist/kt-dsl/expr/types.d.ts.map +0 -1
  252. package/dist/kt-dsl/expr/types.js +0 -2
  253. package/dist/kt-dsl/expr/types.js.map +0 -1
  254. package/dist/kt-dsl/file.d.ts +0 -14
  255. package/dist/kt-dsl/file.d.ts.map +0 -1
  256. package/dist/kt-dsl/file.js +0 -9
  257. package/dist/kt-dsl/file.js.map +0 -1
  258. package/dist/kt-dsl/fun.d.ts +0 -73
  259. package/dist/kt-dsl/fun.d.ts.map +0 -1
  260. package/dist/kt-dsl/fun.js +0 -50
  261. package/dist/kt-dsl/fun.js.map +0 -1
  262. package/dist/kt-dsl/index.d.ts +0 -8
  263. package/dist/kt-dsl/index.d.ts.map +0 -1
  264. package/dist/kt-dsl/index.js +0 -8
  265. package/dist/kt-dsl/index.js.map +0 -1
  266. package/dist/kt-dsl/stmt/binding.d.ts +0 -56
  267. package/dist/kt-dsl/stmt/binding.d.ts.map +0 -1
  268. package/dist/kt-dsl/stmt/binding.js +0 -70
  269. package/dist/kt-dsl/stmt/binding.js.map +0 -1
  270. package/dist/kt-dsl/stmt/control.d.ts +0 -80
  271. package/dist/kt-dsl/stmt/control.d.ts.map +0 -1
  272. package/dist/kt-dsl/stmt/control.js +0 -77
  273. package/dist/kt-dsl/stmt/control.js.map +0 -1
  274. package/dist/kt-dsl/stmt/index.d.ts +0 -4
  275. package/dist/kt-dsl/stmt/index.d.ts.map +0 -1
  276. package/dist/kt-dsl/stmt/index.js +0 -4
  277. package/dist/kt-dsl/stmt/index.js.map +0 -1
  278. package/dist/kt-dsl/stmt/types.d.ts +0 -62
  279. package/dist/kt-dsl/stmt/types.d.ts.map +0 -1
  280. package/dist/kt-dsl/stmt/types.js +0 -2
  281. package/dist/kt-dsl/stmt/types.js.map +0 -1
  282. package/dist/kt-dsl/type/builders.d.ts +0 -75
  283. package/dist/kt-dsl/type/builders.d.ts.map +0 -1
  284. package/dist/kt-dsl/type/builders.js +0 -83
  285. package/dist/kt-dsl/type/builders.js.map +0 -1
  286. package/dist/kt-dsl/type/index.d.ts +0 -3
  287. package/dist/kt-dsl/type/index.d.ts.map +0 -1
  288. package/dist/kt-dsl/type/index.js +0 -3
  289. package/dist/kt-dsl/type/index.js.map +0 -1
  290. package/dist/kt-dsl/type/types.d.ts +0 -25
  291. package/dist/kt-dsl/type/types.d.ts.map +0 -1
  292. package/dist/kt-dsl/type/types.js +0 -2
  293. package/dist/kt-dsl/type/types.js.map +0 -1
  294. package/dist/kt-dsl/visibility.d.ts +0 -2
  295. package/dist/kt-dsl/visibility.d.ts.map +0 -1
  296. package/dist/kt-dsl/visibility.js +0 -2
  297. package/dist/kt-dsl/visibility.js.map +0 -1
@@ -1,149 +1,71 @@
1
+ import { kt } from "@ir-kit/compiler-kotlin";
2
+ const K = kt.KotlinNodeKind;
3
+ const NAME_TOKEN = /[A-Za-z_][A-Za-z0-9_]*/g;
1
4
  /**
2
- * Compute the import list for a single Kotlin file by walking the
3
- * already-printed source and matching against known identifiers.
4
- * Coarse-import-everything caused unused imports per file; the
5
- * print-then-scan pattern is precise without needing a full type-tree
6
- * walker.
7
- *
8
- * Identifiers that share names across packages (e.g. `Response` exists
9
- * in both `okhttp3` and a hypothetical user model) are disambiguated
10
- * by file kind: API-layer files always pull `okhttp3.Response`, model
11
- * files never do.
5
+ * Every identifier, type and annotation name the declarations reference,
6
+ * collected from the AST (string literals and comments never count).
12
7
  */
13
- export function importsForSource(source, ctx) {
14
- const set = new Set();
15
- // kotlinx-serialization annotations.
16
- if (/@Serializable\b/.test(source)) {
17
- set.add("kotlinx.serialization.Serializable");
18
- }
19
- if (/@SerialName\b/.test(source)) {
20
- set.add("kotlinx.serialization.SerialName");
21
- }
22
- // kotlinx-datetime model fields.
23
- if (/\bInstant\b/.test(source))
24
- set.add("kotlinx.datetime.Instant");
25
- if (/\bLocalDate\b/.test(source))
26
- set.add("kotlinx.datetime.LocalDate");
27
- // kotlinx-serialization builtins (only when actually mentioned).
28
- if (/\bListSerializer\(/.test(source)) {
29
- set.add("kotlinx.serialization.builtins.ListSerializer");
30
- }
31
- if (/\bMapSerializer\(/.test(source)) {
32
- set.add("kotlinx.serialization.builtins.MapSerializer");
33
- }
34
- if (/\bByteArraySerializer\(\)/.test(source)) {
35
- set.add("kotlinx.serialization.builtins.ByteArraySerializer");
36
- }
37
- if (/\.nullable\b/.test(source)) {
38
- set.add("kotlinx.serialization.builtins.nullable");
39
- }
40
- if (/\bserializer\(\)/.test(source) && ctx.isApiSurface) {
41
- // Built-in `String.serializer()`, `Int.serializer()`, etc. live
42
- // under kotlinx.serialization.builtins. Only the API surface uses
43
- // them — model files use the auto-generated companion form.
44
- set.add("kotlinx.serialization.builtins.serializer");
45
- }
46
- if (/\bJsonElement\b/.test(source)) {
47
- set.add("kotlinx.serialization.json.JsonElement");
48
- }
49
- // OkHttp types — only API-surface files reference them.
50
- if (ctx.isApiSurface) {
51
- if (/\bHttpUrl\b/.test(source))
52
- set.add("okhttp3.HttpUrl");
53
- if (/\bRequest\b/.test(source))
54
- set.add("okhttp3.Request");
55
- if (/\bResponse\b/.test(source))
56
- set.add("okhttp3.Response");
57
- if (/\bFormBody\b/.test(source))
58
- set.add("okhttp3.FormBody");
59
- if (/\.toMediaType\(\)/.test(source)) {
60
- set.add("okhttp3.MediaType.Companion.toMediaType");
61
- }
62
- if (/\.toRequestBody\(/.test(source)) {
63
- set.add("okhttp3.RequestBody.Companion.toRequestBody");
8
+ export function referencedNames(decls) {
9
+ const names = new Set();
10
+ const visit = (value) => {
11
+ if (Array.isArray(value)) {
12
+ for (const item of value)
13
+ visit(item);
14
+ return;
64
15
  }
65
- // Cross-package model refs. The API surface lives in `<root>.api`
66
- // and references model types from `<root>.models`. Wildcard-import
67
- // when the file mentions any PascalCased identifier that isn't a
68
- // built-in (cheap heuristic; the alternative is walking every type
69
- // ref through the decl tree).
70
- if (ctx.subPkg === `${ctx.rootPkg}.api` &&
71
- /\b[A-Z][A-Za-z0-9_]*\b/.test(source) &&
72
- hasLikelyModelRef(source)) {
73
- set.add(`${ctx.rootPkg}.models.*`);
16
+ if (!value || typeof value !== "object")
17
+ return;
18
+ const node = value;
19
+ if ((node.kind === K.Identifier ||
20
+ node.kind === K.UserType ||
21
+ node.kind === K.Annotation) &&
22
+ typeof node.name === "string") {
23
+ for (const m of node.name.matchAll(NAME_TOKEN))
24
+ names.add(m[0]);
74
25
  }
75
- }
76
- // Drop self-package imports — Kotlin allows them but they're noise.
77
- return [...set].filter((i) => !i.startsWith(`${ctx.subPkg}.`)).sort();
26
+ for (const child of Object.values(value))
27
+ visit(child);
28
+ };
29
+ for (const decl of decls)
30
+ visit(decl.node);
31
+ return names;
78
32
  }
79
33
  /**
80
- * Identifiers that ship in `kotlin.*` / `okhttp3.*` / kotlinx — and so
81
- * do NOT trigger a `<root>.models.*` import. Used to keep the wildcard
82
- * model import out of files that never actually reference user types.
34
+ * Import list for one Kotlin file. Names shared across packages (e.g.
35
+ * `Response` in `okhttp3` vs. a user model) are disambiguated by file
36
+ * kind: API-layer files pull `okhttp3.Response`, model files never do.
83
37
  */
84
- const NON_MODEL_TYPES = new Set([
85
- // Kotlin stdlib
86
- "Any",
87
- "Unit",
88
- "Nothing",
89
- "String",
90
- "Int",
91
- "Long",
92
- "Short",
93
- "Byte",
94
- "Double",
95
- "Float",
96
- "Boolean",
97
- "ByteArray",
98
- "List",
99
- "Map",
100
- "Pair",
101
- "Triple",
102
- "Throwable",
103
- "Exception",
104
- "RuntimeException",
105
- "Result",
106
- "Charsets",
107
- "Base64",
108
- "TimeUnit",
109
- // kotlinx
110
- "Instant",
111
- "LocalDate",
112
- "JsonElement",
113
- "Json",
114
- "Dispatchers",
115
- "Serializable",
116
- "SerialName",
117
- "ListSerializer",
118
- "MapSerializer",
119
- "ByteArraySerializer",
120
- // OkHttp
121
- "HttpUrl",
122
- "Request",
123
- "Response",
124
- "OkHttpClient",
125
- "FormBody",
126
- "MultipartBody",
127
- "RequestBody",
128
- "MediaType",
129
- // Runtime helpers (same package)
130
- "APIClient",
131
- "APIError",
132
- "APIInterceptors",
133
- "Auth",
134
- "APIKeyLocation",
135
- "MultipartFormBody",
136
- "QueryStyle",
137
- "RequestOptions",
138
- "URLEncoding",
139
- ]);
140
- function hasLikelyModelRef(source) {
141
- const matches = source.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g);
142
- for (const m of matches) {
143
- if (!NON_MODEL_TYPES.has(m[1]))
144
- return true;
38
+ export function importsFor(names, ctx) {
39
+ const set = new Set();
40
+ const when = (name, imp) => {
41
+ if (names.has(name))
42
+ set.add(imp);
43
+ };
44
+ when("Serializable", "kotlinx.serialization.Serializable");
45
+ when("SerialName", "kotlinx.serialization.SerialName");
46
+ when("Instant", "kotlinx.datetime.Instant");
47
+ when("LocalDate", "kotlinx.datetime.LocalDate");
48
+ when("ListSerializer", "kotlinx.serialization.builtins.ListSerializer");
49
+ when("MapSerializer", "kotlinx.serialization.builtins.MapSerializer");
50
+ when("ByteArraySerializer", "kotlinx.serialization.builtins.ByteArraySerializer");
51
+ when("nullable", "kotlinx.serialization.builtins.nullable");
52
+ when("JsonElement", "kotlinx.serialization.json.JsonElement");
53
+ if (ctx.isApiSurface) {
54
+ // `String.serializer()` etc.; model files use generated companions.
55
+ when("serializer", "kotlinx.serialization.builtins.serializer");
56
+ when("HttpUrl", "okhttp3.HttpUrl");
57
+ when("Request", "okhttp3.Request");
58
+ when("Response", "okhttp3.Response");
59
+ when("FormBody", "okhttp3.FormBody");
60
+ when("toMediaType", "okhttp3.MediaType.Companion.toMediaType");
61
+ when("toRequestBody", "okhttp3.RequestBody.Companion.toRequestBody");
145
62
  }
146
- return false;
63
+ for (const name of names) {
64
+ const pkg = ctx.declared.get(name);
65
+ if (pkg && pkg !== ctx.subPkg)
66
+ set.add(`${pkg}.${name}`);
67
+ }
68
+ return [...set].filter((i) => !i.startsWith(`${ctx.subPkg}.`)).sort();
147
69
  }
148
70
  /** API-surface predicate, exposed for the build orchestrator. */
149
71
  export function isApiSurface(decl) {
@@ -1 +1 @@
1
- {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/project/imports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/project/imports.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { KtDecl } from "../kt-dsl/decl/types.js";
1
+ import type { KtDecl } from "../ast/index.js";
2
2
  export type LayoutKind = "flat" | "split";
3
3
  export interface PlacedDecl {
4
4
  decl: KtDecl;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/project/layout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,mEAAmE;IACnE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC9D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,UAAU,CAM1E;AAmCD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQjD"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/project/layout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,mEAAmE;IACnE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC9D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,UAAU,CAM1E;AAmCD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD"}
@@ -48,9 +48,7 @@ function isApiDecl(decl) {
48
48
  */
49
49
  export function declFileName(decl) {
50
50
  if (decl.kind === "topLevelFun") {
51
- const receiver = decl.fun.receiver;
52
- const recvName = receiver && receiver.kind === "ref" ? receiver.name : "Extensions";
53
- return `${recvName}Extensions.kt`;
51
+ return `${decl.receiver ?? "Extensions"}Extensions.kt`;
54
52
  }
55
53
  return `${decl.name}.kt`;
56
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/project/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAsB/C,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAsB;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;IACtC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACjD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;IACnD,IACE,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;QAChC,UAAU,KAAK,IAAI;QACnB,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAC5B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IAC7C,IACE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;QACnB,IAAI,CAAC,IAAI,KAAK,QAAQ;QACtB,IAAI,CAAC,IAAI,KAAK,aAAa;QAC3B,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;QAC5B,IAAI,CAAC,OAAO,EACZ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnC,MAAM,QAAQ,GACZ,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC;QACrE,OAAO,GAAG,QAAQ,eAAe,CAAC;IACpC,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/project/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAsB/C,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAsB;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;IACtC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACjD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;IACnD,IACE,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;QAChC,UAAU,KAAK,IAAI;QACnB,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAC5B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IAC7C,IACE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;QACnB,IAAI,CAAC,IAAI,KAAK,QAAQ;QACtB,IAAI,CAAC,IAAI,KAAK,aAAa;QAC3B,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;QAC5B,IAAI,CAAC,OAAO,EACZ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAChC,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,YAAY,eAAe,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC;AAC3B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ir-kit/openapi-kotlin",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Generate idiomatic Kotlin (OkHttp + kotlinx-serialization + suspend) client SDKs from an OpenAPI 3.x spec.",
5
5
  "keywords": [
6
6
  "openapi",
@@ -12,9 +12,9 @@
12
12
  "sdk",
13
13
  "client"
14
14
  ],
15
- "homepage": "https://github.com/ir-kit/ir-kit/tree/main/packages/openapi/kotlin",
15
+ "homepage": "https://github.com/ahmedrowaihi/ir-kit/tree/main/packages/openapi/kotlin",
16
16
  "bugs": {
17
- "url": "https://github.com/ir-kit/ir-kit/issues"
17
+ "url": "https://github.com/ahmedrowaihi/ir-kit/issues"
18
18
  },
19
19
  "license": "MIT",
20
20
  "author": {
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",
26
- "url": "git+https://github.com/ir-kit/ir-kit.git",
26
+ "url": "git+https://github.com/ahmedrowaihi/ir-kit.git",
27
27
  "directory": "packages/openapi/kotlin"
28
28
  },
29
29
  "type": "module",
@@ -39,6 +39,7 @@
39
39
  },
40
40
  "files": [
41
41
  "dist",
42
+ "runtime/*.kt",
42
43
  "README.md",
43
44
  "LICENSE.md"
44
45
  ],
@@ -49,19 +50,20 @@
49
50
  "peerDependencies": {
50
51
  "@hey-api/shared": ">=0.3.0",
51
52
  "@hey-api/spec-types": ">=0.2.0",
52
- "@ir-kit/openapi-tools": ">=0.3.0"
53
+ "@ir-kit/openapi-tools": ">=0.4.0"
53
54
  },
54
55
  "dependencies": {
55
- "@ir-kit/codegen-core": "0.1.0",
56
- "@ir-kit/openapi": "0.3.0",
57
- "@ir-kit/openapi-loader": "0.2.0"
56
+ "@ir-kit/codegen-core": "0.3.0",
57
+ "@ir-kit/openapi": "0.5.0",
58
+ "@ir-kit/compiler-kotlin": "0.1.1",
59
+ "@ir-kit/openapi-loader": "0.4.0"
58
60
  },
59
61
  "devDependencies": {
60
- "@hey-api/shared": "^0.4.2",
62
+ "@hey-api/shared": "^0.5.0",
61
63
  "@hey-api/spec-types": "^0.2.0",
62
64
  "@types/node": "^22",
63
65
  "vitest": "^4.0.0",
64
- "@ir-kit/openapi-tools": "0.3.0",
66
+ "@ir-kit/openapi-tools": "0.4.0",
65
67
  "@ir-kit/tsconfig": "0.0.0"
66
68
  },
67
69
  "engines": {
@@ -0,0 +1,140 @@
1
+ package dev.irkit.runtime
2
+
3
+ import kotlinx.coroutines.Dispatchers
4
+ import kotlinx.coroutines.withContext
5
+ import kotlinx.serialization.json.Json
6
+ import okhttp3.HttpUrl
7
+ import okhttp3.OkHttpClient
8
+ import okhttp3.Request
9
+ import okhttp3.Response
10
+ import java.util.concurrent.TimeUnit
11
+
12
+ /**
13
+ * Runtime helper every per-tag impl class delegates to. Owns the
14
+ * transport-level concerns — `OkHttpClient`, `Json`, the interceptor
15
+ * pipeline — and provides one source of truth for status-code
16
+ * dispatch and decoding.
17
+ *
18
+ * - `execute<T>(request, deserializer, …)` — decodes a 2xx body to `T`.
19
+ * - `executeUnit(request, …)` — discards the body.
20
+ * - `executeWithResponse<T>(request, deserializer,`
21
+ * `…)` — decode + raw `Response`.
22
+ * - `executeUnitWithResponse(request, …)` — raw `Response` only.
23
+ * - `executeRaw(request, …)` — raw `(ByteArray, Response)`,
24
+ * used by multi-2xx ops.
25
+ *
26
+ * Status-code dispatch lives in `sendAndDispatch`; 2xx returns the
27
+ * body bytes, 4xx/5xx throw the matching `APIError` subclass.
28
+ */
29
+ public class APIClient(
30
+ public var baseUrl: HttpUrl,
31
+ public val httpClient: OkHttpClient = OkHttpClient(),
32
+ public val json: Json =
33
+ Json {
34
+ ignoreUnknownKeys = true
35
+ encodeDefaults = true
36
+ },
37
+ public val interceptors: APIInterceptors = APIInterceptors(),
38
+ public val auth: MutableMap<String, Auth> = mutableMapOf(),
39
+ ) {
40
+ public suspend fun <T> execute(
41
+ request: Request,
42
+ deserializer: kotlinx.serialization.DeserializationStrategy<T>,
43
+ timeout: Long? = null,
44
+ extraInterceptors: List<suspend (Request) -> Request> = emptyList(),
45
+ responseValidator: (suspend (ByteArray, Response) -> Unit)? = null,
46
+ responseTransformer: (suspend (ByteArray) -> ByteArray)? = null,
47
+ ): T {
48
+ val (data, response) = sendAndDispatch(request, timeout, extraInterceptors)
49
+ responseValidator?.invoke(data, response)
50
+ val body = responseTransformer?.invoke(data) ?: data
51
+ return try {
52
+ json.decodeFromString(deserializer, body.decodeToString())
53
+ } catch (e: Throwable) {
54
+ throw APIError.DecodingFailed(e)
55
+ }
56
+ }
57
+
58
+ public suspend fun executeUnit(
59
+ request: Request,
60
+ timeout: Long? = null,
61
+ extraInterceptors: List<suspend (Request) -> Request> = emptyList(),
62
+ responseValidator: (suspend (ByteArray, Response) -> Unit)? = null,
63
+ ) {
64
+ val (data, response) = sendAndDispatch(request, timeout, extraInterceptors)
65
+ responseValidator?.invoke(data, response)
66
+ }
67
+
68
+ public suspend fun <T> executeWithResponse(
69
+ request: Request,
70
+ deserializer: kotlinx.serialization.DeserializationStrategy<T>,
71
+ timeout: Long? = null,
72
+ extraInterceptors: List<suspend (Request) -> Request> = emptyList(),
73
+ responseValidator: (suspend (ByteArray, Response) -> Unit)? = null,
74
+ responseTransformer: (suspend (ByteArray) -> ByteArray)? = null,
75
+ ): Pair<T, Response> {
76
+ val (data, response) = sendAndDispatch(request, timeout, extraInterceptors)
77
+ responseValidator?.invoke(data, response)
78
+ val body = responseTransformer?.invoke(data) ?: data
79
+ return try {
80
+ json.decodeFromString(deserializer, body.decodeToString()) to response
81
+ } catch (e: Throwable) {
82
+ throw APIError.DecodingFailed(e)
83
+ }
84
+ }
85
+
86
+ public suspend fun executeUnitWithResponse(
87
+ request: Request,
88
+ timeout: Long? = null,
89
+ extraInterceptors: List<suspend (Request) -> Request> = emptyList(),
90
+ responseValidator: (suspend (ByteArray, Response) -> Unit)? = null,
91
+ ): Response {
92
+ val (data, response) = sendAndDispatch(request, timeout, extraInterceptors)
93
+ responseValidator?.invoke(data, response)
94
+ return response
95
+ }
96
+
97
+ public suspend fun executeRaw(
98
+ request: Request,
99
+ timeout: Long? = null,
100
+ extraInterceptors: List<suspend (Request) -> Request> = emptyList(),
101
+ responseValidator: (suspend (ByteArray, Response) -> Unit)? = null,
102
+ responseTransformer: (suspend (ByteArray) -> ByteArray)? = null,
103
+ ): Pair<ByteArray, Response> {
104
+ val (data, response) = sendAndDispatch(request, timeout, extraInterceptors)
105
+ responseValidator?.invoke(data, response)
106
+ val body = responseTransformer?.invoke(data) ?: data
107
+ return body to response
108
+ }
109
+
110
+ private suspend fun sendAndDispatch(
111
+ request: Request,
112
+ timeout: Long?,
113
+ extraInterceptors: List<suspend (Request) -> Request>,
114
+ ): Pair<ByteArray, Response> {
115
+ var req = request
116
+ for (interceptor in interceptors.request) req = interceptor(req)
117
+ for (interceptor in extraInterceptors) req = interceptor(req)
118
+ val callClient =
119
+ if (timeout == null) {
120
+ httpClient
121
+ } else {
122
+ httpClient.newBuilder().callTimeout(timeout, TimeUnit.MILLISECONDS).build()
123
+ }
124
+ val response =
125
+ try {
126
+ withContext(Dispatchers.IO) {
127
+ callClient.newCall(req).execute()
128
+ }
129
+ } catch (e: Throwable) {
130
+ throw APIError.Transport(e)
131
+ }
132
+ val body = response.body?.bytes() ?: ByteArray(0)
133
+ return when (val code = response.code) {
134
+ in 200..299 -> body to response
135
+ in 400..499 -> throw APIError.ClientError(code, body)
136
+ in 500..599 -> throw APIError.ServerError(code, body)
137
+ else -> throw APIError.UnexpectedStatus(code, body)
138
+ }
139
+ }
140
+ }
@@ -0,0 +1,42 @@
1
+ package dev.irkit.runtime
2
+
3
+ /**
4
+ * The typed error every impl method throws on non-2xx responses.
5
+ *
6
+ * - `ClientError(statusCode, body)` — 4XX
7
+ * - `ServerError(statusCode, body)` — 5XX
8
+ * - `UnexpectedStatus(statusCode, body)` — 1XX/3XX/anything outside 2-5
9
+ * - `DecodingFailed(cause)` — kotlinx-serialization threw on a 2XX body
10
+ * - `Transport(cause)` — OkHttp / network-layer failure
11
+ *
12
+ * Consumers `catch` and pattern-match. Bodies are surfaced as raw
13
+ * `ByteArray` so callers can decode error envelopes themselves with the
14
+ * codec they prefer.
15
+ */
16
+ public sealed class APIError(
17
+ message: String? = null,
18
+ cause: Throwable? = null,
19
+ ) : RuntimeException(message, cause) {
20
+ public class ClientError(
21
+ public val statusCode: Int,
22
+ public val body: ByteArray,
23
+ ) : APIError("Client error: $statusCode")
24
+
25
+ public class ServerError(
26
+ public val statusCode: Int,
27
+ public val body: ByteArray,
28
+ ) : APIError("Server error: $statusCode")
29
+
30
+ public class UnexpectedStatus(
31
+ public val statusCode: Int,
32
+ public val body: ByteArray,
33
+ ) : APIError("Unexpected status: $statusCode")
34
+
35
+ public class DecodingFailed(
36
+ cause: Throwable,
37
+ ) : APIError("Decoding failed: ${cause.message}", cause)
38
+
39
+ public class Transport(
40
+ cause: Throwable,
41
+ ) : APIError("Transport failure: ${cause.message}", cause)
42
+ }
@@ -0,0 +1,14 @@
1
+ package dev.irkit.runtime
2
+
3
+ import okhttp3.Request
4
+
5
+ /**
6
+ * Bag of per-request mutation hooks. Mirrors hey-api's TS client where
7
+ * `client.interceptors.request.use(fn)` registers an interceptor that
8
+ * runs against every outgoing request. Multiple interceptors compose —
9
+ * auth, logging, and tracing all coexist as separate entries instead
10
+ * of being chained inside one closure.
11
+ */
12
+ public class APIInterceptors {
13
+ public val request: MutableList<suspend (Request) -> Request> = mutableListOf()
14
+ }
@@ -0,0 +1,7 @@
1
+ package dev.irkit.runtime
2
+
3
+ public enum class APIKeyLocation {
4
+ HEADER,
5
+ QUERY,
6
+ COOKIE,
7
+ }
@@ -0,0 +1,86 @@
1
+ package dev.irkit.runtime
2
+
3
+ import okhttp3.HttpUrl
4
+ import okhttp3.Request
5
+ import java.util.Base64
6
+
7
+ /**
8
+ * Auth schemes consumers reach for in practice:
9
+ *
10
+ * - `Bearer(token)` — `Authorization: Bearer <token>`.
11
+ * - `ApiKey(name, value, in)` — header / query / cookie placement,
12
+ * matching the spec's
13
+ * `securitySchemes.<name>.in`.
14
+ * - `Basic(username, password)` — `Authorization: Basic <base64>`.
15
+ *
16
+ * Per-operation auth is auto-wired by the generator when an op has
17
+ * `security` requirements; it walks the requirement names and applies
18
+ * any matching scheme value the consumer has placed on `APIClient.auth`.
19
+ *
20
+ * `apply` mutates the request builder in-place for header / cookie
21
+ * auth and returns the (possibly rewritten) `HttpUrl` so query auth
22
+ * can re-thread its name=value into the URL.
23
+ */
24
+ public sealed class Auth {
25
+ public abstract fun apply(
26
+ builder: Request.Builder,
27
+ url: HttpUrl,
28
+ ): HttpUrl
29
+
30
+ public data class Bearer(
31
+ public val token: String,
32
+ ) : Auth() {
33
+ override fun apply(
34
+ builder: Request.Builder,
35
+ url: HttpUrl,
36
+ ): HttpUrl {
37
+ builder.header("Authorization", "Bearer $token")
38
+ return url
39
+ }
40
+ }
41
+
42
+ public data class ApiKey(
43
+ public val name: String,
44
+ public val value: String,
45
+ public val location: APIKeyLocation,
46
+ ) : Auth() {
47
+ override fun apply(
48
+ builder: Request.Builder,
49
+ url: HttpUrl,
50
+ ): HttpUrl =
51
+ when (location) {
52
+ APIKeyLocation.HEADER -> {
53
+ builder.header(name, value)
54
+ url
55
+ }
56
+
57
+ APIKeyLocation.QUERY -> {
58
+ url.newBuilder().addQueryParameter(name, value).build()
59
+ }
60
+
61
+ APIKeyLocation.COOKIE -> {
62
+ val cookie = "$name=$value"
63
+ val existing = builder.build().header("Cookie")
64
+ builder.header("Cookie", existing?.let { "$it; $cookie" } ?: cookie)
65
+ url
66
+ }
67
+ }
68
+ }
69
+
70
+ public data class Basic(
71
+ public val username: String,
72
+ public val password: String,
73
+ ) : Auth() {
74
+ override fun apply(
75
+ builder: Request.Builder,
76
+ url: HttpUrl,
77
+ ): HttpUrl {
78
+ val encoded =
79
+ Base64
80
+ .getEncoder()
81
+ .encodeToString("$username:$password".toByteArray(Charsets.UTF_8))
82
+ builder.header("Authorization", "Basic $encoded")
83
+ return url
84
+ }
85
+ }
86
+ }