@ir-kit/openapi-kotlin 0.1.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.
- package/LICENSE.md +21 -0
- package/README.md +259 -0
- package/dist/generate.d.ts +41 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +64 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/constants.d.ts +6 -0
- package/dist/ir/constants.d.ts.map +1 -0
- package/dist/ir/constants.js +6 -0
- package/dist/ir/constants.js.map +1 -0
- package/dist/ir/identifiers.d.ts +23 -0
- package/dist/ir/identifiers.d.ts.map +1 -0
- package/dist/ir/identifiers.js +71 -0
- package/dist/ir/identifiers.js.map +1 -0
- package/dist/ir/impl/body.d.ts +30 -0
- package/dist/ir/impl/body.d.ts.map +1 -0
- package/dist/ir/impl/body.js +116 -0
- package/dist/ir/impl/body.js.map +1 -0
- package/dist/ir/impl/decode.d.ts +14 -0
- package/dist/ir/impl/decode.d.ts.map +1 -0
- package/dist/ir/impl/decode.js +110 -0
- package/dist/ir/impl/decode.js.map +1 -0
- package/dist/ir/impl/headers.d.ts +8 -0
- package/dist/ir/impl/headers.d.ts.map +1 -0
- package/dist/ir/impl/headers.js +22 -0
- package/dist/ir/impl/headers.js.map +1 -0
- package/dist/ir/impl/index.d.ts +23 -0
- package/dist/ir/impl/index.d.ts.map +1 -0
- package/dist/ir/impl/index.js +141 -0
- package/dist/ir/impl/index.js.map +1 -0
- package/dist/ir/impl/request.d.ts +14 -0
- package/dist/ir/impl/request.d.ts.map +1 -0
- package/dist/ir/impl/request.js +25 -0
- package/dist/ir/impl/request.js.map +1 -0
- package/dist/ir/impl/serializer.d.ts +20 -0
- package/dist/ir/impl/serializer.d.ts.map +1 -0
- package/dist/ir/impl/serializer.js +62 -0
- package/dist/ir/impl/serializer.js.map +1 -0
- package/dist/ir/impl/url.d.ts +16 -0
- package/dist/ir/impl/url.d.ts.map +1 -0
- package/dist/ir/impl/url.js +77 -0
- package/dist/ir/impl/url.js.map +1 -0
- package/dist/ir/index.d.ts +4 -0
- package/dist/ir/index.d.ts.map +1 -0
- package/dist/ir/index.js +3 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/ir/operation/body.d.ts +18 -0
- package/dist/ir/operation/body.d.ts.map +1 -0
- package/dist/ir/operation/body.js +51 -0
- package/dist/ir/operation/body.js.map +1 -0
- package/dist/ir/operation/index.d.ts +7 -0
- package/dist/ir/operation/index.d.ts.map +1 -0
- package/dist/ir/operation/index.js +5 -0
- package/dist/ir/operation/index.js.map +1 -0
- package/dist/ir/operation/params.d.ts +16 -0
- package/dist/ir/operation/params.d.ts.map +1 -0
- package/dist/ir/operation/params.js +28 -0
- package/dist/ir/operation/params.js.map +1 -0
- package/dist/ir/operation/response.d.ts +26 -0
- package/dist/ir/operation/response.d.ts.map +1 -0
- package/dist/ir/operation/response.js +58 -0
- package/dist/ir/operation/response.js.map +1 -0
- package/dist/ir/operation/signature.d.ts +32 -0
- package/dist/ir/operation/signature.d.ts.map +1 -0
- package/dist/ir/operation/signature.js +53 -0
- package/dist/ir/operation/signature.js.map +1 -0
- package/dist/ir/operations.d.ts +43 -0
- package/dist/ir/operations.d.ts.map +1 -0
- package/dist/ir/operations.js +124 -0
- package/dist/ir/operations.js.map +1 -0
- package/dist/ir/runtime/index.d.ts +3 -0
- package/dist/ir/runtime/index.d.ts.map +1 -0
- package/dist/ir/runtime/index.js +2 -0
- package/dist/ir/runtime/index.js.map +1 -0
- package/dist/ir/runtime/templates.d.ts +31 -0
- package/dist/ir/runtime/templates.d.ts.map +1 -0
- package/dist/ir/runtime/templates.js +431 -0
- package/dist/ir/runtime/templates.js.map +1 -0
- package/dist/ir/schema.d.ts +11 -0
- package/dist/ir/schema.d.ts.map +1 -0
- package/dist/ir/schema.js +51 -0
- package/dist/ir/schema.js.map +1 -0
- package/dist/ir/type/context.d.ts +4 -0
- package/dist/ir/type/context.d.ts.map +1 -0
- package/dist/ir/type/context.js +2 -0
- package/dist/ir/type/context.js.map +1 -0
- package/dist/ir/type/index.d.ts +27 -0
- package/dist/ir/type/index.d.ts.map +1 -0
- package/dist/ir/type/index.js +35 -0
- package/dist/ir/type/index.js.map +1 -0
- package/dist/ir/type/primitive.d.ts +9 -0
- package/dist/ir/type/primitive.d.ts.map +1 -0
- package/dist/ir/type/primitive.js +50 -0
- package/dist/ir/type/primitive.js.map +1 -0
- package/dist/ir/type/property-naming.d.ts +26 -0
- package/dist/ir/type/property-naming.d.ts.map +1 -0
- package/dist/ir/type/property-naming.js +27 -0
- package/dist/ir/type/property-naming.js.map +1 -0
- package/dist/ir/type-ops.d.ts +13 -0
- package/dist/ir/type-ops.d.ts.map +1 -0
- package/dist/ir/type-ops.js +80 -0
- package/dist/ir/type-ops.js.map +1 -0
- package/dist/kt-compiler/decl/class.d.ts +6 -0
- package/dist/kt-compiler/decl/class.d.ts.map +1 -0
- package/dist/kt-compiler/decl/class.js +38 -0
- package/dist/kt-compiler/decl/class.js.map +1 -0
- package/dist/kt-compiler/decl/dataClass.d.ts +3 -0
- package/dist/kt-compiler/decl/dataClass.d.ts.map +1 -0
- package/dist/kt-compiler/decl/dataClass.js +18 -0
- package/dist/kt-compiler/decl/dataClass.js.map +1 -0
- package/dist/kt-compiler/decl/enum.d.ts +3 -0
- package/dist/kt-compiler/decl/enum.d.ts.map +1 -0
- package/dist/kt-compiler/decl/enum.js +32 -0
- package/dist/kt-compiler/decl/enum.js.map +1 -0
- package/dist/kt-compiler/decl/fun.d.ts +11 -0
- package/dist/kt-compiler/decl/fun.d.ts.map +1 -0
- package/dist/kt-compiler/decl/fun.js +69 -0
- package/dist/kt-compiler/decl/fun.js.map +1 -0
- package/dist/kt-compiler/decl/index.d.ts +13 -0
- package/dist/kt-compiler/decl/index.d.ts.map +1 -0
- package/dist/kt-compiler/decl/index.js +39 -0
- package/dist/kt-compiler/decl/index.js.map +1 -0
- package/dist/kt-compiler/decl/interface.d.ts +3 -0
- package/dist/kt-compiler/decl/interface.d.ts.map +1 -0
- package/dist/kt-compiler/decl/interface.js +15 -0
- package/dist/kt-compiler/decl/interface.js.map +1 -0
- package/dist/kt-compiler/decl/object.d.ts +3 -0
- package/dist/kt-compiler/decl/object.d.ts.map +1 -0
- package/dist/kt-compiler/decl/object.js +19 -0
- package/dist/kt-compiler/decl/object.js.map +1 -0
- package/dist/kt-compiler/decl/prop.d.ts +20 -0
- package/dist/kt-compiler/decl/prop.d.ts.map +1 -0
- package/dist/kt-compiler/decl/prop.js +42 -0
- package/dist/kt-compiler/decl/prop.js.map +1 -0
- package/dist/kt-compiler/decl/sealedClass.d.ts +3 -0
- package/dist/kt-compiler/decl/sealedClass.d.ts.map +1 -0
- package/dist/kt-compiler/decl/sealedClass.js +32 -0
- package/dist/kt-compiler/decl/sealedClass.js.map +1 -0
- package/dist/kt-compiler/decl/topLevel.d.ts +3 -0
- package/dist/kt-compiler/decl/topLevel.d.ts.map +1 -0
- package/dist/kt-compiler/decl/topLevel.js +5 -0
- package/dist/kt-compiler/decl/topLevel.js.map +1 -0
- package/dist/kt-compiler/decl/typeAlias.d.ts +3 -0
- package/dist/kt-compiler/decl/typeAlias.d.ts.map +1 -0
- package/dist/kt-compiler/decl/typeAlias.js +6 -0
- package/dist/kt-compiler/decl/typeAlias.js.map +1 -0
- package/dist/kt-compiler/expr.d.ts +4 -0
- package/dist/kt-compiler/expr.d.ts.map +1 -0
- package/dist/kt-compiler/expr.js +123 -0
- package/dist/kt-compiler/expr.js.map +1 -0
- package/dist/kt-compiler/format.d.ts +20 -0
- package/dist/kt-compiler/format.d.ts.map +1 -0
- package/dist/kt-compiler/format.js +27 -0
- package/dist/kt-compiler/format.js.map +1 -0
- package/dist/kt-compiler/index.d.ts +7 -0
- package/dist/kt-compiler/index.d.ts.map +1 -0
- package/dist/kt-compiler/index.js +24 -0
- package/dist/kt-compiler/index.js.map +1 -0
- package/dist/kt-compiler/stmt.d.ts +4 -0
- package/dist/kt-compiler/stmt.d.ts.map +1 -0
- package/dist/kt-compiler/stmt.js +72 -0
- package/dist/kt-compiler/stmt.js.map +1 -0
- package/dist/kt-compiler/type.d.ts +3 -0
- package/dist/kt-compiler/type.d.ts.map +1 -0
- package/dist/kt-compiler/type.js +28 -0
- package/dist/kt-compiler/type.js.map +1 -0
- package/dist/kt-dsl/decl/class.d.ts +50 -0
- package/dist/kt-dsl/decl/class.d.ts.map +1 -0
- package/dist/kt-dsl/decl/class.js +33 -0
- package/dist/kt-dsl/decl/class.js.map +1 -0
- package/dist/kt-dsl/decl/dataClass.d.ts +36 -0
- package/dist/kt-dsl/decl/dataClass.d.ts.map +1 -0
- package/dist/kt-dsl/decl/dataClass.js +25 -0
- package/dist/kt-dsl/decl/dataClass.js.map +1 -0
- package/dist/kt-dsl/decl/enum.d.ts +60 -0
- package/dist/kt-dsl/decl/enum.d.ts.map +1 -0
- package/dist/kt-dsl/decl/enum.js +38 -0
- package/dist/kt-dsl/decl/enum.js.map +1 -0
- package/dist/kt-dsl/decl/index.d.ts +11 -0
- package/dist/kt-dsl/decl/index.d.ts.map +1 -0
- package/dist/kt-dsl/decl/index.js +11 -0
- package/dist/kt-dsl/decl/index.js.map +1 -0
- package/dist/kt-dsl/decl/interface.d.ts +33 -0
- package/dist/kt-dsl/decl/interface.d.ts.map +1 -0
- package/dist/kt-dsl/decl/interface.js +24 -0
- package/dist/kt-dsl/decl/interface.js.map +1 -0
- package/dist/kt-dsl/decl/object.d.ts +34 -0
- package/dist/kt-dsl/decl/object.d.ts.map +1 -0
- package/dist/kt-dsl/decl/object.js +24 -0
- package/dist/kt-dsl/decl/object.js.map +1 -0
- package/dist/kt-dsl/decl/prop.d.ts +47 -0
- package/dist/kt-dsl/decl/prop.d.ts.map +1 -0
- package/dist/kt-dsl/decl/prop.js +28 -0
- package/dist/kt-dsl/decl/prop.js.map +1 -0
- package/dist/kt-dsl/decl/sealedClass.d.ts +68 -0
- package/dist/kt-dsl/decl/sealedClass.d.ts.map +1 -0
- package/dist/kt-dsl/decl/sealedClass.js +52 -0
- package/dist/kt-dsl/decl/sealedClass.js.map +1 -0
- package/dist/kt-dsl/decl/topLevel.d.ts +19 -0
- package/dist/kt-dsl/decl/topLevel.d.ts.map +1 -0
- package/dist/kt-dsl/decl/topLevel.js +17 -0
- package/dist/kt-dsl/decl/topLevel.js.map +1 -0
- package/dist/kt-dsl/decl/typeAlias.d.ts +23 -0
- package/dist/kt-dsl/decl/typeAlias.d.ts.map +1 -0
- package/dist/kt-dsl/decl/typeAlias.js +18 -0
- package/dist/kt-dsl/decl/typeAlias.js.map +1 -0
- package/dist/kt-dsl/decl/types.d.ts +10 -0
- package/dist/kt-dsl/decl/types.d.ts.map +1 -0
- package/dist/kt-dsl/decl/types.js +2 -0
- package/dist/kt-dsl/decl/types.js.map +1 -0
- package/dist/kt-dsl/expr/access.d.ts +48 -0
- package/dist/kt-dsl/expr/access.d.ts.map +1 -0
- package/dist/kt-dsl/expr/access.js +59 -0
- package/dist/kt-dsl/expr/access.js.map +1 -0
- package/dist/kt-dsl/expr/call.d.ts +38 -0
- package/dist/kt-dsl/expr/call.d.ts.map +1 -0
- package/dist/kt-dsl/expr/call.js +38 -0
- package/dist/kt-dsl/expr/call.js.map +1 -0
- package/dist/kt-dsl/expr/index.d.ts +7 -0
- package/dist/kt-dsl/expr/index.d.ts.map +1 -0
- package/dist/kt-dsl/expr/index.js +7 -0
- package/dist/kt-dsl/expr/index.js.map +1 -0
- package/dist/kt-dsl/expr/literal.d.ts +100 -0
- package/dist/kt-dsl/expr/literal.d.ts.map +1 -0
- package/dist/kt-dsl/expr/literal.js +108 -0
- package/dist/kt-dsl/expr/literal.js.map +1 -0
- package/dist/kt-dsl/expr/misc.d.ts +45 -0
- package/dist/kt-dsl/expr/misc.d.ts.map +1 -0
- package/dist/kt-dsl/expr/misc.js +63 -0
- package/dist/kt-dsl/expr/misc.js.map +1 -0
- package/dist/kt-dsl/expr/op.d.ts +25 -0
- package/dist/kt-dsl/expr/op.d.ts.map +1 -0
- package/dist/kt-dsl/expr/op.js +24 -0
- package/dist/kt-dsl/expr/op.js.map +1 -0
- package/dist/kt-dsl/expr/types.d.ts +93 -0
- package/dist/kt-dsl/expr/types.d.ts.map +1 -0
- package/dist/kt-dsl/expr/types.js +2 -0
- package/dist/kt-dsl/expr/types.js.map +1 -0
- package/dist/kt-dsl/file.d.ts +14 -0
- package/dist/kt-dsl/file.d.ts.map +1 -0
- package/dist/kt-dsl/file.js +9 -0
- package/dist/kt-dsl/file.js.map +1 -0
- package/dist/kt-dsl/fun.d.ts +73 -0
- package/dist/kt-dsl/fun.d.ts.map +1 -0
- package/dist/kt-dsl/fun.js +50 -0
- package/dist/kt-dsl/fun.js.map +1 -0
- package/dist/kt-dsl/index.d.ts +8 -0
- package/dist/kt-dsl/index.d.ts.map +1 -0
- package/dist/kt-dsl/index.js +8 -0
- package/dist/kt-dsl/index.js.map +1 -0
- package/dist/kt-dsl/stmt/binding.d.ts +56 -0
- package/dist/kt-dsl/stmt/binding.d.ts.map +1 -0
- package/dist/kt-dsl/stmt/binding.js +70 -0
- package/dist/kt-dsl/stmt/binding.js.map +1 -0
- package/dist/kt-dsl/stmt/control.d.ts +80 -0
- package/dist/kt-dsl/stmt/control.d.ts.map +1 -0
- package/dist/kt-dsl/stmt/control.js +77 -0
- package/dist/kt-dsl/stmt/control.js.map +1 -0
- package/dist/kt-dsl/stmt/index.d.ts +4 -0
- package/dist/kt-dsl/stmt/index.d.ts.map +1 -0
- package/dist/kt-dsl/stmt/index.js +4 -0
- package/dist/kt-dsl/stmt/index.js.map +1 -0
- package/dist/kt-dsl/stmt/types.d.ts +62 -0
- package/dist/kt-dsl/stmt/types.d.ts.map +1 -0
- package/dist/kt-dsl/stmt/types.js +2 -0
- package/dist/kt-dsl/stmt/types.js.map +1 -0
- package/dist/kt-dsl/type/builders.d.ts +75 -0
- package/dist/kt-dsl/type/builders.d.ts.map +1 -0
- package/dist/kt-dsl/type/builders.js +83 -0
- package/dist/kt-dsl/type/builders.js.map +1 -0
- package/dist/kt-dsl/type/index.d.ts +3 -0
- package/dist/kt-dsl/type/index.d.ts.map +1 -0
- package/dist/kt-dsl/type/index.js +3 -0
- package/dist/kt-dsl/type/index.js.map +1 -0
- package/dist/kt-dsl/type/types.d.ts +25 -0
- package/dist/kt-dsl/type/types.d.ts.map +1 -0
- package/dist/kt-dsl/type/types.js +2 -0
- package/dist/kt-dsl/type/types.js.map +1 -0
- package/dist/kt-dsl/visibility.d.ts +2 -0
- package/dist/kt-dsl/visibility.d.ts.map +1 -0
- package/dist/kt-dsl/visibility.js +2 -0
- package/dist/kt-dsl/visibility.js.map +1 -0
- package/dist/project/build.d.ts +33 -0
- package/dist/project/build.d.ts.map +1 -0
- package/dist/project/build.js +73 -0
- package/dist/project/build.js.map +1 -0
- package/dist/project/gradle.d.ts +48 -0
- package/dist/project/gradle.d.ts.map +1 -0
- package/dist/project/gradle.js +46 -0
- package/dist/project/gradle.js.map +1 -0
- package/dist/project/imports.d.ts +21 -0
- package/dist/project/imports.d.ts.map +1 -0
- package/dist/project/imports.js +162 -0
- package/dist/project/imports.js.map +1 -0
- package/dist/project/index.d.ts +6 -0
- package/dist/project/index.d.ts.map +1 -0
- package/dist/project/index.js +3 -0
- package/dist/project/index.js.map +1 -0
- package/dist/project/layout.d.ts +30 -0
- package/dist/project/layout.d.ts.map +1 -0
- package/dist/project/layout.js +57 -0
- package/dist/project/layout.js.map +1 -0
- package/package.json +76 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ahmed Rowaihi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# @ir-kit/openapi-kotlin
|
|
2
|
+
|
|
3
|
+
Generate idiomatic Android / JVM Kotlin client SDKs from an OpenAPI 3.x spec — `@Serializable` data classes, `String`-raw enums, per-tag interfaces with `suspend` functions, and an OkHttp + kotlinx-serialization impl class. Per-call `RequestOptions`, composable interceptors, typed `APIError`, multipart + form-urlencoded wire encoding, multi-2xx sum-type returns, and per-op security auto-wiring all included.
|
|
4
|
+
|
|
5
|
+
Built on the [`@hey-api`](https://github.com/hey-api/openapi-ts) toolchain (`@hey-api/json-schema-ref-parser` for spec loading, `@hey-api/shared` IR for normalization). 2.0 / 3.0 / 3.1 inputs all produce the same output.
|
|
6
|
+
|
|
7
|
+
Sibling package to [`@ir-kit/openapi-swift`](../openapi-swift). Part of [ir-kit](https://github.com/ir-kit/ir-kit). Companion to the [`petstore-sdk` example](../../examples/petstore-sdk).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @ir-kit/openapi-kotlin @ir-kit/openapi-tools @hey-api/shared @hey-api/spec-types
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { generate } from "@ir-kit/openapi-kotlin";
|
|
19
|
+
|
|
20
|
+
await generate({
|
|
21
|
+
input: "https://api.example.com/openapi.json",
|
|
22
|
+
output: "./sdk-kotlin",
|
|
23
|
+
packageName: "com.example.petstore",
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Reads any of: a filesystem path, an http(s) URL, or a pre-parsed object. YAML and JSON are both supported. External `$ref`s are bundled inline.
|
|
28
|
+
|
|
29
|
+
## Output
|
|
30
|
+
|
|
31
|
+
### Schemas → `@Serializable` data classes / enums / typealiases
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
@Serializable
|
|
35
|
+
public data class Pet(
|
|
36
|
+
public val id: Long? = null,
|
|
37
|
+
public val name: String,
|
|
38
|
+
public val category: Category? = null,
|
|
39
|
+
public val photoUrls: List<String>,
|
|
40
|
+
public val tags: List<Tag>? = null,
|
|
41
|
+
public val status: Pet_Status? = null,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
@Serializable
|
|
45
|
+
public enum class Pet_Status(public val raw: String) {
|
|
46
|
+
@SerialName("available") AVAILABLE("available"),
|
|
47
|
+
@SerialName("pending") PENDING("pending"),
|
|
48
|
+
@SerialName("sold") SOLD("sold"),
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Inline enums on a property get promoted to a top-level `Owner_Property` enum class. Renamed JSON keys (snake_case → camelCase) get a `@SerialName` so the wire format stays untouched.
|
|
53
|
+
|
|
54
|
+
### Operations → interfaces + impls
|
|
55
|
+
|
|
56
|
+
For each tag the generator emits:
|
|
57
|
+
|
|
58
|
+
- `interface <Tag>Api` with `suspend fun` requirements
|
|
59
|
+
- top-level `<Tag>Api.<op>(…)` extension funs as no-options convenience overloads (forward to the with-options form using `RequestOptions()` defaults)
|
|
60
|
+
- `class OkHttp<Tag>Api(client: APIClient) : <Tag>Api` with the wire impl
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
public interface PetApi {
|
|
64
|
+
/** GET /pet/{petId} */
|
|
65
|
+
public suspend fun getPetById(petId: Long, options: RequestOptions): Pet
|
|
66
|
+
public suspend fun getPetByIdWithResponse(petId: Long, options: RequestOptions): Pair<Pet, Response>
|
|
67
|
+
// …
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public suspend fun PetApi.getPetById(petId: Long): Pet =
|
|
71
|
+
getPetById(petId = petId, options = RequestOptions())
|
|
72
|
+
|
|
73
|
+
public class OkHttpPetApi(public val client: APIClient) : PetApi {
|
|
74
|
+
public override suspend fun getPetById(petId: Long, options: RequestOptions): Pet { /* … */ }
|
|
75
|
+
// …
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Every operation also emits a sibling `*WithResponse` overload that returns `Pair<T, Response>` — for callers that need response headers (pagination cursors, `ETag`, rate limits). Void-returning operations get `*WithResponse(): Response` instead.
|
|
80
|
+
|
|
81
|
+
### Per-call control via `RequestOptions`
|
|
82
|
+
|
|
83
|
+
```kotlin
|
|
84
|
+
public data class RequestOptions(
|
|
85
|
+
public val client: APIClient? = null,
|
|
86
|
+
public val baseUrl: HttpUrl? = null,
|
|
87
|
+
public val timeout: Long? = null, // milliseconds
|
|
88
|
+
public val headers: Map<String, String> = emptyMap(),
|
|
89
|
+
public val requestInterceptors: List<suspend (Request) -> Request> = emptyList(),
|
|
90
|
+
public val responseValidator: (suspend (ByteArray, Response) -> Unit)? = null,
|
|
91
|
+
public val responseTransformer: (suspend (ByteArray) -> ByteArray)? = null,
|
|
92
|
+
)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```kotlin
|
|
96
|
+
pets.getPetById(1) // defaults
|
|
97
|
+
pets.getPetById(1, RequestOptions(client = customClient)) // swap transport
|
|
98
|
+
pets.getPetById(1, RequestOptions(headers = mapOf("X-Trace" to id))) // extra headers
|
|
99
|
+
pets.getPetById(1, RequestOptions(baseUrl = stagingUrl)) // hit staging
|
|
100
|
+
pets.getPetById(1, RequestOptions(timeout = 60_000)) // long-poll override
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Composable interceptors + auth
|
|
104
|
+
|
|
105
|
+
The runtime `APIClient` carries an `interceptors.request` list that runs against every outgoing request. Interceptors compose — auth, logging, tracing all coexist:
|
|
106
|
+
|
|
107
|
+
```kotlin
|
|
108
|
+
val client = APIClient(baseUrl = "https://api.example.com/".toHttpUrl())
|
|
109
|
+
client.interceptors.request += { request ->
|
|
110
|
+
request.newBuilder()
|
|
111
|
+
.header("Authorization", "Bearer ${TokenStore.access()}")
|
|
112
|
+
.build()
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
When the spec declares any `securitySchemes`, the generator additionally emits an `Auth` sealed class (with `Bearer`, `ApiKey`, `Basic` subclasses — `ApiKey` carries an `APIKeyLocation` of `HEADER` / `QUERY` / `COOKIE`) and the client gains a `var auth: MutableMap<String, Auth>` keyed by scheme name. Operations with `security:` requirements walk the map and apply the matching scheme automatically:
|
|
117
|
+
|
|
118
|
+
```kotlin
|
|
119
|
+
client.auth["bearerAuth"] = Auth.Bearer(token)
|
|
120
|
+
client.auth["xApiKey"] = Auth.ApiKey("X-API-Key", key, APIKeyLocation.HEADER)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Body media-type dispatch
|
|
124
|
+
|
|
125
|
+
| Input media type | Generated parameter shape | Wire encoding |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `application/json` (and `+json`) | `body: T` | `Json.encodeToString(<ser>, body).toRequestBody("application/json".toMediaType())` |
|
|
128
|
+
| `multipart/form-data` (object schema) | one param per property; binary fields → `ByteArray` | emitted `MultipartFormBody` helper (wraps `MultipartBody.Builder`) |
|
|
129
|
+
| `application/x-www-form-urlencoded` (object schema) | one param per property | `FormBody.Builder()` |
|
|
130
|
+
| `application/octet-stream`, image, etc. | `body: ByteArray` | raw bytes via `toRequestBody("<mt>".toMediaType())` |
|
|
131
|
+
| `oneOf` / unresolvable JSON | `body: ByteArray` | raw bytes (caller pre-encodes) |
|
|
132
|
+
|
|
133
|
+
### Typed errors
|
|
134
|
+
|
|
135
|
+
Every non-2xx response funnels into `APIError`:
|
|
136
|
+
|
|
137
|
+
```kotlin
|
|
138
|
+
public sealed class APIError(message: String? = null, cause: Throwable? = null) :
|
|
139
|
+
RuntimeException(message, cause) {
|
|
140
|
+
public class ClientError(public val statusCode: Int, public val body: ByteArray) : APIError(/* … */) // 4XX
|
|
141
|
+
public class ServerError(public val statusCode: Int, public val body: ByteArray) : APIError(/* … */) // 5XX
|
|
142
|
+
public class UnexpectedStatus(public val statusCode: Int, public val body: ByteArray) : APIError(/* … */) // 1XX/3XX/etc.
|
|
143
|
+
public class DecodingFailed(cause: Throwable) : APIError(/* … */) // kotlinx-serialization threw
|
|
144
|
+
public class Transport(cause: Throwable) : APIError(/* … */) // OkHttp/network layer
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Multi-2xx → sum-type return
|
|
149
|
+
|
|
150
|
+
When an operation declares more than one 2xx response code with distinct schemas, the generator emits a sealed-class hierarchy and the impl dispatches on `response.code`:
|
|
151
|
+
|
|
152
|
+
```kotlin
|
|
153
|
+
public sealed class SubmitJob_Response {
|
|
154
|
+
public data class Status200(public val value: JobResult) : SubmitJob_Response()
|
|
155
|
+
public data class Status202(public val value: Pending) : SubmitJob_Response()
|
|
156
|
+
public object Status204 : SubmitJob_Response()
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Generator options
|
|
161
|
+
|
|
162
|
+
Every option is optional. Pass them to `generate({ ... })`:
|
|
163
|
+
|
|
164
|
+
| Option | Purpose |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `input` / `output` | Spec source (path / URL / object) and SDK output dir. |
|
|
167
|
+
| `packageName` | Kotlin package every file declares. Default `"com.example.api"`. |
|
|
168
|
+
| `clean` | Wipe `output` before writing. Default `true`. Refuses to wipe cwd or filesystem root. |
|
|
169
|
+
| `gradle` | Emit `build.gradle.kts` + `settings.gradle.kts` for standalone-module mode. `true` → defaults. Object → custom `group`, `version`, plugin/dependency versions, JVM target. Omit → mode 1 (raw kotlin source tree only). |
|
|
170
|
+
| `defaultTag` | Tag to use when an op has none. Default `"Default"`. |
|
|
171
|
+
| `interfaceName` | `(tag) => string`. Default `(tag) => `${PascalCase(tag)}Api``. |
|
|
172
|
+
| `clientClassName` | `(interfaceName) => string`. Default `(p) => `OkHttp${p}``. |
|
|
173
|
+
| `interfaceOnly` | Skip impl class emission. Default `false`. |
|
|
174
|
+
| `openImpl` | Emit impl class as `open` so consumers can subclass. Default `false`. |
|
|
175
|
+
| `layout` | `"split"` (default — `api/` + `models/` sub-packages) or `"flat"` (one package). |
|
|
176
|
+
| `fileLocation` | `(decl) => { dir }` — full per-decl override. Rejects `..` traversal and absolute paths. |
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
generate({
|
|
180
|
+
input,
|
|
181
|
+
output,
|
|
182
|
+
packageName: "com.example.petstore",
|
|
183
|
+
gradle: { group: "com.example", version: "1.0.0" },
|
|
184
|
+
openImpl: true,
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Two consumption modes
|
|
189
|
+
|
|
190
|
+
| Mode | Setup | When |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| **Drop into an existing Gradle module** | Paste the package directory (e.g. `com/example/petstore/`) into your module's `src/main/kotlin/` tree. The surrounding module must apply `kotlin("plugin.serialization")` and depend on OkHttp + kotlinx-serialization-json + kotlinx-coroutines-core + kotlinx-datetime. | Adding the SDK directly to one app or library. |
|
|
193
|
+
| **Standalone Gradle module** | Pass `gradle: true` (or an options object) to `generate()`; `build.gradle.kts` + `settings.gradle.kts` are emitted alongside the source. Run `gradle build` from the output dir. | Sharing across multiple modules, publishing privately, or wanting a clean dependency boundary. |
|
|
194
|
+
|
|
195
|
+
## Output layout
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
sdk-kotlin/
|
|
199
|
+
├── com/example/petstore/
|
|
200
|
+
│ ├── api/
|
|
201
|
+
│ │ ├── PetApi.kt # interface
|
|
202
|
+
│ │ ├── PetApiExtensions.kt # convenience overloads (no-options)
|
|
203
|
+
│ │ ├── OkHttpPetApi.kt # impl class
|
|
204
|
+
│ │ ├── APIClient.kt # runtime helper (transport, dispatch, decode)
|
|
205
|
+
│ │ ├── APIInterceptors.kt # interceptor pipeline
|
|
206
|
+
│ │ ├── APIError.kt # typed errors
|
|
207
|
+
│ │ ├── Auth.kt # (when spec has securitySchemes)
|
|
208
|
+
│ │ ├── APIKeyLocation.kt # (when spec has securitySchemes)
|
|
209
|
+
│ │ ├── MultipartFormBody.kt # (when any op uses multipart/form-data)
|
|
210
|
+
│ │ ├── URLEncoding.kt # query helpers
|
|
211
|
+
│ │ ├── QueryStyle.kt # form / spaceDelimited / pipeDelimited
|
|
212
|
+
│ │ └── RequestOptions.kt
|
|
213
|
+
│ └── models/
|
|
214
|
+
│ ├── Pet.kt # @Serializable data classes
|
|
215
|
+
│ ├── Pet_Status.kt # enum classes
|
|
216
|
+
│ └── …
|
|
217
|
+
└── (build.gradle.kts + settings.gradle.kts when `gradle:` is set)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Requirements
|
|
221
|
+
|
|
222
|
+
The generated code uses Kotlin coroutines + kotlinx-serialization, so:
|
|
223
|
+
|
|
224
|
+
- **Kotlin** 2.0 or newer (with `kotlin("plugin.serialization")` applied)
|
|
225
|
+
- **JVM target** 17 or newer (configurable via the `gradle` option)
|
|
226
|
+
|
|
227
|
+
Runtime dependencies (set up by the `gradle:` option, or by the consuming module in drop-in mode):
|
|
228
|
+
|
|
229
|
+
- `org.jetbrains.kotlinx:kotlinx-serialization-json:1.7+`
|
|
230
|
+
- `org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9+`
|
|
231
|
+
- `org.jetbrains.kotlinx:kotlinx-datetime:0.6+` (only if any model uses `Instant` / `LocalDate`)
|
|
232
|
+
- `com.squareup.okhttp3:okhttp:4.12+`
|
|
233
|
+
|
|
234
|
+
## API surface
|
|
235
|
+
|
|
236
|
+
| Export | Purpose |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `generate(opts)` | High-level entry: load → IR → decls → files on disk. |
|
|
239
|
+
| `schemasToDecls(schemas)` | `IR.Model.components.schemas` → `KtDecl[]`. |
|
|
240
|
+
| `operationsToDecls(paths, opts?)` | `IR.PathsObject` → `{ decls, needsAuth, needsMultipart }` (interfaces + impls grouped by tag). |
|
|
241
|
+
| `buildKotlinProject(decls, opts?)` | `KtDecl[]` → `{ path, content }[]` with package / import resolution. |
|
|
242
|
+
| `buildRuntimeFiles(opts, pkg)` | Standalone runtime helper files (APIClient, APIError, …) keyed off the consumer's package. |
|
|
243
|
+
| `buildGradleFile(opts?)` | Build a `build.gradle.kts` for a standalone Gradle module wrapping the SDK. |
|
|
244
|
+
| `securityKey(path, method)` | Key into `OperationsOptions.securitySchemeNames`. |
|
|
245
|
+
| `printFile(file)` / `kt*` builders | Lower-level Kotlin AST + printer. |
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
src/kt-dsl/ Kotlin AST: type/, expr/, stmt/, decl/, fun.ts, file.ts
|
|
249
|
+
src/kt-compiler/ AST → string, mirrors the AST tree
|
|
250
|
+
src/ir/
|
|
251
|
+
├── type/ IR.SchemaObject → KtType
|
|
252
|
+
├── operation/ IR.OperationObject → signature shared by interface + impl
|
|
253
|
+
├── impl/ OkHttp body builders (url, request, headers, body, decode)
|
|
254
|
+
├── runtime/ Templated Kotlin source for runtime helpers
|
|
255
|
+
├── schema.ts schemasToDecls
|
|
256
|
+
└── operations.ts paths → interfaces + impl classes (orchestrator)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Adding a new statement / expression node: add to `kt-dsl/{expr,stmt}/types.ts`, builder, one printer case. Per-method bodies are AST-built; runtime helpers (the same Kotlin every time) ship as templated strings in `ir/runtime/templates.ts`.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type NormalizeOptions } from "@ir-kit/openapi-core";
|
|
2
|
+
import { type OperationsOptions } from "./ir/index.js";
|
|
3
|
+
import { type BuildOptions, type BuiltFile, type GradleOptions } from "./project/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Operations options the consumer can pass through `generate()`. The
|
|
6
|
+
* orchestrator owns `securitySchemeNames` (extracted from the bundled
|
|
7
|
+
* spec), so it's stripped from the public surface.
|
|
8
|
+
*/
|
|
9
|
+
type ForwardedOperationsOptions = Omit<OperationsOptions, "securitySchemeNames">;
|
|
10
|
+
export interface GenerateOptions extends BuildOptions, ForwardedOperationsOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The OpenAPI spec source: a filesystem path, http(s) URL, or a
|
|
13
|
+
* pre-parsed object. YAML and JSON inputs both work. External
|
|
14
|
+
* `$ref`s are bundled inline; the spec is normalized to hey-api IR
|
|
15
|
+
* before generation, so 2.0 / 3.0 / 3.1 inputs all produce the same
|
|
16
|
+
* output shape.
|
|
17
|
+
*/
|
|
18
|
+
input: string | Record<string, unknown>;
|
|
19
|
+
/** Directory the SDK is written to (created if missing). */
|
|
20
|
+
output: string;
|
|
21
|
+
/** Wipe `output` before writing. Default: `true`. */
|
|
22
|
+
clean?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* When set, emit a `build.gradle.kts` + `settings.gradle.kts` at the
|
|
25
|
+
* output root so the SDK is a self-contained Gradle library. Pass
|
|
26
|
+
* `true` for sensible defaults (project name keyed off the output
|
|
27
|
+
* dir basename) or a `GradleOptions` object for fine-grained
|
|
28
|
+
* control. Default: omitted — the output is just the Kotlin source
|
|
29
|
+
* tree, ready to drop into an existing Gradle module.
|
|
30
|
+
*/
|
|
31
|
+
gradle?: boolean | GradleOptions;
|
|
32
|
+
/** Pre-codegen spec normalization. `true` enables the safe preset. */
|
|
33
|
+
normalize?: boolean | NormalizeOptions;
|
|
34
|
+
}
|
|
35
|
+
export interface GenerateResult {
|
|
36
|
+
files: BuiltFile[];
|
|
37
|
+
output: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function generate(opts: GenerateOptions): Promise<GenerateResult>;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,SAAS,EAGd,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,KAAK,0BAA0B,GAAG,IAAI,CACpC,iBAAiB,EACjB,qBAAqB,CACtB,CAAC;AAEF,MAAM,WAAW,eACf,SAAQ,YAAY,EAClB,0BAA0B;IAC5B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IACjC,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAqD7E"}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { assertSafeOutputDir, defaultProjectName } from "@ir-kit/codegen-core";
|
|
4
|
+
import { extractSecuritySchemeNames, } from "@ir-kit/openapi-core";
|
|
5
|
+
import { loadSpec } from "@ir-kit/openapi-tools";
|
|
6
|
+
import { parseSpec } from "@ir-kit/openapi-tools/parse";
|
|
7
|
+
import { operationsToDecls, schemasToDecls, } from "./ir/index.js";
|
|
8
|
+
import { buildRuntimeFiles } from "./ir/runtime/index.js";
|
|
9
|
+
import { buildGradleFile, buildKotlinProject, settingsGradleFile, } from "./project/index.js";
|
|
10
|
+
export async function generate(opts) {
|
|
11
|
+
const bundled = await loadSpec({
|
|
12
|
+
input: opts.input,
|
|
13
|
+
normalize: opts.normalize,
|
|
14
|
+
});
|
|
15
|
+
const ir = parseSpec(bundled);
|
|
16
|
+
const schemaDecls = schemasToDecls(ir.components?.schemas ?? {});
|
|
17
|
+
const opsResult = operationsToDecls(ir.paths, {
|
|
18
|
+
defaultTag: opts.defaultTag,
|
|
19
|
+
interfaceName: opts.interfaceName,
|
|
20
|
+
clientClassName: opts.clientClassName,
|
|
21
|
+
interfaceOnly: opts.interfaceOnly,
|
|
22
|
+
openImpl: opts.openImpl,
|
|
23
|
+
securitySchemeNames: extractSecuritySchemeNames(bundled),
|
|
24
|
+
});
|
|
25
|
+
const decls = [...schemaDecls, ...opsResult.decls];
|
|
26
|
+
const sdkFiles = buildKotlinProject(decls, opts);
|
|
27
|
+
const pkg = opts.packageName ?? "com.example.api";
|
|
28
|
+
const apiSubDir = (opts.layout ?? "split") === "flat" ? "" : "api";
|
|
29
|
+
const runtimeFiles = buildRuntimeFiles({
|
|
30
|
+
hasAuth: opsResult.needsAuth,
|
|
31
|
+
hasMultipart: opsResult.needsMultipart,
|
|
32
|
+
hasFormUrlEncoded: false,
|
|
33
|
+
}, runtimeSubPackage(pkg, apiSubDir)).map((rf) => ({
|
|
34
|
+
path: runtimePath(pkg, apiSubDir, rf.name),
|
|
35
|
+
content: rf.content,
|
|
36
|
+
}));
|
|
37
|
+
const files = [...sdkFiles, ...runtimeFiles];
|
|
38
|
+
const out = resolve(opts.output);
|
|
39
|
+
if (opts.gradle) {
|
|
40
|
+
const gradleOpts = typeof opts.gradle === "object" ? opts.gradle : {};
|
|
41
|
+
files.push(buildGradleFile(gradleOpts));
|
|
42
|
+
files.push(settingsGradleFile(defaultProjectName(out)));
|
|
43
|
+
}
|
|
44
|
+
if (opts.clean !== false) {
|
|
45
|
+
assertSafeOutputDir(out);
|
|
46
|
+
await rm(out, { recursive: true, force: true });
|
|
47
|
+
}
|
|
48
|
+
for (const file of files) {
|
|
49
|
+
const full = join(out, file.path);
|
|
50
|
+
await mkdir(dirname(full), { recursive: true });
|
|
51
|
+
await writeFile(full, file.content);
|
|
52
|
+
}
|
|
53
|
+
return { files, output: out };
|
|
54
|
+
}
|
|
55
|
+
function runtimeSubPackage(rootPkg, dir) {
|
|
56
|
+
if (dir === "")
|
|
57
|
+
return rootPkg;
|
|
58
|
+
return `${rootPkg}.${dir}`;
|
|
59
|
+
}
|
|
60
|
+
function runtimePath(rootPkg, dir, name) {
|
|
61
|
+
const pkgPath = rootPkg.replace(/\./g, "/");
|
|
62
|
+
return dir === "" ? `${pkgPath}/${name}` : `${pkgPath}/${dir}/${name}`;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/ir/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/ir/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kotlin-specific identifier transforms. Generic case helpers
|
|
3
|
+
* (`pascal`, `camel`, `safeIdent`, `safeCaseName`, `synthName`,
|
|
4
|
+
* `softCamel`, `escapeIfReserved`, `avoidLeadingDigit`) live in
|
|
5
|
+
* `@ir-kit/codegen-core`. The exports here cover what's unique to
|
|
6
|
+
* Kotlin: reserved-keyword backtick-escaping and SCREAMING_SNAKE
|
|
7
|
+
* enum entry names.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Translate an arbitrary string to a Kotlin identifier safe to use as
|
|
11
|
+
* a parameter / property name. Reserved keywords are escaped with
|
|
12
|
+
* backticks (Kotlin's syntax for arbitrary identifiers). Uses
|
|
13
|
+
* `softCamel` (preserves first-letter casing) so PascalCase inputs
|
|
14
|
+
* pass through unchanged.
|
|
15
|
+
*/
|
|
16
|
+
export declare function paramIdent(name: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Constant-style identifier for enum entries — `SCREAMING_SNAKE_CASE`.
|
|
19
|
+
* Kotlin convention for `enum class` entry names. Falls back to a
|
|
20
|
+
* leading underscore if the result starts with a digit.
|
|
21
|
+
*/
|
|
22
|
+
export declare function enumEntryIdent(s: string): string;
|
|
23
|
+
//# sourceMappingURL=identifiers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifiers.d.ts","sourceRoot":"","sources":["../../src/ir/identifiers.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAShD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { avoidLeadingDigit, escapeIfReserved, softCamel, } from "@ir-kit/codegen-core";
|
|
2
|
+
/**
|
|
3
|
+
* Kotlin-specific identifier transforms. Generic case helpers
|
|
4
|
+
* (`pascal`, `camel`, `safeIdent`, `safeCaseName`, `synthName`,
|
|
5
|
+
* `softCamel`, `escapeIfReserved`, `avoidLeadingDigit`) live in
|
|
6
|
+
* `@ir-kit/codegen-core`. The exports here cover what's unique to
|
|
7
|
+
* Kotlin: reserved-keyword backtick-escaping and SCREAMING_SNAKE
|
|
8
|
+
* enum entry names.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Translate an arbitrary string to a Kotlin identifier safe to use as
|
|
12
|
+
* a parameter / property name. Reserved keywords are escaped with
|
|
13
|
+
* backticks (Kotlin's syntax for arbitrary identifiers). Uses
|
|
14
|
+
* `softCamel` (preserves first-letter casing) so PascalCase inputs
|
|
15
|
+
* pass through unchanged.
|
|
16
|
+
*/
|
|
17
|
+
export function paramIdent(name) {
|
|
18
|
+
return escapeIfReserved(avoidLeadingDigit(softCamel(name)), KOTLIN_RESERVED_KEYWORDS, (s) => `\`${s}\``);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Constant-style identifier for enum entries — `SCREAMING_SNAKE_CASE`.
|
|
22
|
+
* Kotlin convention for `enum class` entry names. Falls back to a
|
|
23
|
+
* leading underscore if the result starts with a digit.
|
|
24
|
+
*/
|
|
25
|
+
export function enumEntryIdent(s) {
|
|
26
|
+
const cleaned = s.replace(/[^a-zA-Z0-9]+/g, "_");
|
|
27
|
+
// Split on case boundaries so "firstName" -> ["first", "Name"] -> FIRST_NAME.
|
|
28
|
+
const parts = cleaned
|
|
29
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
30
|
+
.split(/_+/)
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
const upper = parts.join("_").toUpperCase();
|
|
33
|
+
return avoidLeadingDigit(upper) || "EMPTY";
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Kotlin's hard keywords (the ones that can't be used as identifiers
|
|
37
|
+
* unbacktick-escaped). Picked from the Kotlin reference's "Keywords
|
|
38
|
+
* and operators" section. Soft keywords (`override`, `data`, `inline`,
|
|
39
|
+
* `suspend`, etc.) are valid identifiers and don't need escaping.
|
|
40
|
+
*/
|
|
41
|
+
const KOTLIN_RESERVED_KEYWORDS = new Set([
|
|
42
|
+
"as",
|
|
43
|
+
"break",
|
|
44
|
+
"class",
|
|
45
|
+
"continue",
|
|
46
|
+
"do",
|
|
47
|
+
"else",
|
|
48
|
+
"false",
|
|
49
|
+
"for",
|
|
50
|
+
"fun",
|
|
51
|
+
"if",
|
|
52
|
+
"in",
|
|
53
|
+
"interface",
|
|
54
|
+
"is",
|
|
55
|
+
"null",
|
|
56
|
+
"object",
|
|
57
|
+
"package",
|
|
58
|
+
"return",
|
|
59
|
+
"super",
|
|
60
|
+
"this",
|
|
61
|
+
"throw",
|
|
62
|
+
"true",
|
|
63
|
+
"try",
|
|
64
|
+
"typealias",
|
|
65
|
+
"typeof",
|
|
66
|
+
"val",
|
|
67
|
+
"var",
|
|
68
|
+
"when",
|
|
69
|
+
"while",
|
|
70
|
+
]);
|
|
71
|
+
//# sourceMappingURL=identifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../../src/ir/identifiers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,gBAAgB,CACrB,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAClC,wBAAwB,EACxB,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAClB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACjD,8EAA8E;IAC9E,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,MAAM,wBAAwB,GAAwB,IAAI,GAAG,CAAC;IAC5D,IAAI;IACJ,OAAO;IACP,OAAO;IACP,UAAU;IACV,IAAI;IACJ,MAAM;IACN,OAAO;IACP,KAAK;IACL,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,WAAW;IACX,IAAI;IACJ,MAAM;IACN,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,KAAK;IACL,WAAW;IACX,QAAQ;IACR,KAAK;IACL,KAAK;IACL,MAAM;IACN,OAAO;CACR,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IR } from "@hey-api/shared";
|
|
2
|
+
import type { HttpMethod } from "@ir-kit/openapi-core";
|
|
3
|
+
import type { KtType } from "../../kt-dsl/index.js";
|
|
4
|
+
import { type KtStmt } from "../../kt-dsl/index.js";
|
|
5
|
+
export interface BodyResult {
|
|
6
|
+
stmts: ReadonlyArray<KtStmt>;
|
|
7
|
+
/** Set when the body builder uses `MultipartFormBody` so the
|
|
8
|
+
* orchestrator emits that runtime helper. */
|
|
9
|
+
needsMultipart: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build the request body and re-set the HTTP method on `builder` to
|
|
13
|
+
* carry it. Dispatches on media type:
|
|
14
|
+
*
|
|
15
|
+
* - `application/json` (and `+json`) → `client.json.encodeToString(<ser>, body)`
|
|
16
|
+
* becomes a `RequestBody` via `.toRequestBody("application/json".toMediaType())`.
|
|
17
|
+
* For opaque bodies (oneOf/anyOf), the impl receives `body: ByteArray`
|
|
18
|
+
* and ships it raw.
|
|
19
|
+
* - `multipart/form-data` (object schema) → assemble a
|
|
20
|
+
* `MultipartFormBody`, append text/file fields per property, take
|
|
21
|
+
* `multipart.build()` as the RequestBody.
|
|
22
|
+
* - `application/x-www-form-urlencoded` (object schema) → build a
|
|
23
|
+
* `FormBody.Builder()`, `add(name, value)` per property, take
|
|
24
|
+
* `formBody.build()` as the RequestBody.
|
|
25
|
+
* - octet-stream / image / etc. → `body.toRequestBody("<mt>".toMediaType())`.
|
|
26
|
+
*
|
|
27
|
+
* Optional fields are wrapped in `if (<id> != null)`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildBodyStmts(body: IR.BodyObject, method: HttpMethod, bodyType: KtType): BodyResult;
|
|
30
|
+
//# sourceMappingURL=body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/ir/impl/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAEL,KAAK,MAAM,EAYZ,MAAM,uBAAuB,CAAC;AAK/B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B;kDAC8C;IAC9C,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,EAAE,CAAC,UAAU,EACnB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,GACf,UAAU,CA6BZ"}
|