@apollo-deploy/tesseract 0.9.1 → 1.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.
- package/dist/adapters/csharp/index.d.ts +12 -0
- package/dist/adapters/csharp/index.d.ts.map +1 -0
- package/dist/adapters/csharp/index.js +99 -0
- package/dist/adapters/csharp/index.js.map +1 -0
- package/dist/adapters/go/index.d.ts +12 -0
- package/dist/adapters/go/index.d.ts.map +1 -0
- package/dist/adapters/go/index.js +135 -0
- package/dist/adapters/go/index.js.map +1 -0
- package/dist/adapters/kotlin/index.d.ts +13 -0
- package/dist/adapters/kotlin/index.d.ts.map +1 -0
- package/dist/adapters/kotlin/index.js +186 -0
- package/dist/adapters/kotlin/index.js.map +1 -0
- package/dist/adapters/php/index.d.ts +20 -0
- package/dist/adapters/php/index.d.ts.map +1 -0
- package/dist/adapters/php/index.js +123 -0
- package/dist/adapters/php/index.js.map +1 -0
- package/dist/adapters/python/index.d.ts +12 -0
- package/dist/adapters/python/index.d.ts.map +1 -0
- package/dist/adapters/python/index.js +145 -0
- package/dist/adapters/python/index.js.map +1 -0
- package/dist/adapters/ruby/index.d.ts +12 -0
- package/dist/adapters/ruby/index.d.ts.map +1 -0
- package/dist/adapters/ruby/index.js +86 -0
- package/dist/adapters/ruby/index.js.map +1 -0
- package/dist/adapters/rust/index.d.ts +13 -0
- package/dist/adapters/rust/index.d.ts.map +1 -0
- package/dist/adapters/rust/index.js +213 -0
- package/dist/adapters/rust/index.js.map +1 -0
- package/dist/adapters/typescript/emitter/emitSchema.d.ts +1 -1
- package/dist/adapters/typescript/emitter/emitSchema.d.ts.map +1 -1
- package/dist/adapters/typescript/emitter/emitSchema.js +1 -1
- package/dist/adapters/typescript/emitter/emitSchema.js.map +1 -1
- package/dist/adapters/typescript/emitter/emitTypeScriptModels.d.ts +2 -2
- package/dist/adapters/typescript/emitter/emitTypeScriptModels.d.ts.map +1 -1
- package/dist/adapters/typescript/emitter/emitTypeScriptModels.js +2 -2
- package/dist/adapters/typescript/emitter/emitTypeScriptModels.js.map +1 -1
- package/dist/adapters/typescript/emitter/importCollector.d.ts +1 -1
- package/dist/adapters/typescript/emitter/importCollector.d.ts.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/intake.js +23 -16
- package/dist/pipeline/intake.js.map +1 -1
- package/dist/types/ir.d.ts +1 -1
- package/dist/types/ir.d.ts.map +1 -1
- package/dist/types/sdk-module.d.ts +22 -2
- package/dist/types/sdk-module.d.ts.map +1 -1
- package/dist/types/sdk-module.js +1 -1
- package/package.json +1 -1
- package/templates/csharp/client.hbs +95 -0
- package/templates/csharp/csproj.hbs +18 -0
- package/templates/csharp/domain.hbs +183 -0
- package/templates/csharp/errors.hbs +45 -0
- package/templates/csharp/readme.hbs +76 -0
- package/templates/csharp/transport.hbs +291 -0
- package/templates/csharp/types.hbs +104 -0
- package/templates/go/client.hbs +158 -0
- package/templates/go/domain.hbs +89 -0
- package/templates/go/errors.hbs +38 -0
- package/templates/go/go-mod.hbs +6 -0
- package/templates/go/readme.hbs +73 -0
- package/templates/go/transport.hbs +379 -0
- package/templates/go/types.hbs +80 -0
- package/templates/go/utils.hbs +45 -0
- package/templates/kotlin/build-gradle.hbs +41 -0
- package/templates/kotlin/client.hbs +57 -0
- package/templates/kotlin/domain.hbs +73 -0
- package/templates/kotlin/errors.hbs +42 -0
- package/templates/kotlin/gradle-properties.hbs +2 -0
- package/templates/kotlin/readme.hbs +105 -0
- package/templates/kotlin/settings-gradle.hbs +1 -0
- package/templates/kotlin/transport.hbs +246 -0
- package/templates/kotlin/types.hbs +100 -0
- package/templates/php/client.hbs +74 -0
- package/templates/php/composer.hbs +19 -0
- package/templates/php/domain.hbs +173 -0
- package/templates/php/errors.hbs +131 -0
- package/templates/php/readme.hbs +89 -0
- package/templates/php/transport.hbs +285 -0
- package/templates/php/types.hbs +95 -0
- package/templates/python/client.hbs +102 -0
- package/templates/python/domain.hbs +139 -0
- package/templates/python/index.hbs +20 -0
- package/templates/python/pyproject.hbs +26 -0
- package/templates/python/readme.hbs +64 -0
- package/templates/python/resources-init.hbs +11 -0
- package/templates/python/transport.hbs +191 -0
- package/templates/python/types-errors.hbs +75 -0
- package/templates/python/types.hbs +79 -0
- package/templates/ruby/Gemfile.hbs +5 -0
- package/templates/ruby/client.hbs +86 -0
- package/templates/ruby/domain.hbs +110 -0
- package/templates/ruby/errors.hbs +150 -0
- package/templates/ruby/gemspec.hbs +30 -0
- package/templates/ruby/index.hbs +54 -0
- package/templates/ruby/readme.hbs +113 -0
- package/templates/ruby/transport.hbs +177 -0
- package/templates/ruby/types.hbs +126 -0
- package/templates/ruby/version.hbs +5 -0
- package/templates/rust/api-mod.hbs +3 -0
- package/templates/rust/cargo.hbs +22 -0
- package/templates/rust/client.hbs +114 -0
- package/templates/rust/domain.hbs +94 -0
- package/templates/rust/error.hbs +74 -0
- package/templates/rust/lib.hbs +85 -0
- package/templates/rust/readme.hbs +77 -0
- package/templates/rust/transport.hbs +287 -0
- package/templates/rust/types.hbs +142 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package {{packageName}}
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Primary exception type for the {{packageName}} SDK.
|
|
5
|
+
*
|
|
6
|
+
* All API methods throw [SdkException] on failure.
|
|
7
|
+
*/
|
|
8
|
+
class SdkException(
|
|
9
|
+
/** HTTP status code, if this is an API error. */
|
|
10
|
+
val status: Int?,
|
|
11
|
+
/** Machine-readable error code (if available). */
|
|
12
|
+
val code: String?,
|
|
13
|
+
/** Human-readable error message. */
|
|
14
|
+
override val message: String,
|
|
15
|
+
/** Server-assigned request ID for support. */
|
|
16
|
+
val requestId: String?,
|
|
17
|
+
/** The underlying cause, if any. */
|
|
18
|
+
cause: Throwable? = null,
|
|
19
|
+
) : Exception(message, cause) {
|
|
20
|
+
|
|
21
|
+
/** Returns `true` if this error was caused by the server (5xx). */
|
|
22
|
+
fun isServerError(): Boolean = status != null && status in 500..599
|
|
23
|
+
|
|
24
|
+
/** Returns `true` if this error was caused by the client (4xx). */
|
|
25
|
+
fun isClientError(): Boolean = status != null && status in 400..499
|
|
26
|
+
|
|
27
|
+
/** Returns `true` if this is a network error (should be retried safely). */
|
|
28
|
+
fun isNetworkError(): Boolean = status == null
|
|
29
|
+
|
|
30
|
+
/** Returns `true` if this error is retryable. */
|
|
31
|
+
fun isRetryable(): Boolean = isNetworkError() || status in setOf(429, 502, 503, 504)
|
|
32
|
+
|
|
33
|
+
override fun toString(): String {
|
|
34
|
+
val sb = StringBuilder("SdkException(")
|
|
35
|
+
if (status != null) sb.append("status=$status, ")
|
|
36
|
+
if (code != null) sb.append("code='$code', ")
|
|
37
|
+
sb.append("message='$message'")
|
|
38
|
+
if (requestId != null) sb.append(", requestId='$requestId'")
|
|
39
|
+
sb.append(")")
|
|
40
|
+
return sb.toString()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# {{title}}
|
|
2
|
+
|
|
3
|
+
{{#if description}}{{description}}{{/if}}
|
|
4
|
+
|
|
5
|
+
{{#unless description}}An auto-generated Kotlin SDK for the {{title}} API.{{/unless}}
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### Gradle
|
|
10
|
+
|
|
11
|
+
Add the dependency to your `build.gradle.kts`:
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
repositories {
|
|
15
|
+
mavenCentral()
|
|
16
|
+
// If publishing to a private repository, add it here.
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
dependencies {
|
|
20
|
+
implementation("{{groupId}}:{{artifactId}}:{{#if packageVersion}}{{packageVersion}}{{else}}0.1.0{{/if}}")
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Maven
|
|
25
|
+
|
|
26
|
+
```xml
|
|
27
|
+
<dependency>
|
|
28
|
+
<groupId>{{groupId}}</groupId>
|
|
29
|
+
<artifactId>{{artifactId}}</artifactId>
|
|
30
|
+
<version>{{#if packageVersion}}{{packageVersion}}{{else}}0.1.0{{/if}}</version>
|
|
31
|
+
</dependency>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```kotlin
|
|
37
|
+
import {{packageName}}.Client
|
|
38
|
+
import {{packageName}}.ClientConfig
|
|
39
|
+
import kotlinx.coroutines.runBlocking
|
|
40
|
+
|
|
41
|
+
fun main() = runBlocking {
|
|
42
|
+
val config = ClientConfig(
|
|
43
|
+
{{#each securitySchemes}}
|
|
44
|
+
{{#if (eq type "apiKey")}}
|
|
45
|
+
{{configKey}} = "your-api-key",
|
|
46
|
+
{{/if}}
|
|
47
|
+
{{#if (and (eq type "http") (eq scheme "bearer"))}}
|
|
48
|
+
{{configKey}} = "your-bearer-token",
|
|
49
|
+
{{/if}}
|
|
50
|
+
{{/each}}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
val client = Client(config)
|
|
54
|
+
|
|
55
|
+
{{#each groups}}
|
|
56
|
+
{{#if @first}}
|
|
57
|
+
// val result = client.{{name}}.someOperation()
|
|
58
|
+
{{/if}}
|
|
59
|
+
{{/each}}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## API Reference
|
|
64
|
+
|
|
65
|
+
{{#each groups}}
|
|
66
|
+
### {{interfaceName}}
|
|
67
|
+
|
|
68
|
+
{{#if description}}
|
|
69
|
+
{{description}}
|
|
70
|
+
{{/if}}
|
|
71
|
+
|
|
72
|
+
| Method | HTTP | Description |
|
|
73
|
+
|--------|------|-------------|
|
|
74
|
+
{{#each operations}}
|
|
75
|
+
| `{{name}}()` | `{{httpMethod}}` | {{#if summary}}{{summary}}{{else}}—{{/if}} |
|
|
76
|
+
{{/each}}
|
|
77
|
+
|
|
78
|
+
{{/each}}
|
|
79
|
+
|
|
80
|
+
## Error Handling
|
|
81
|
+
|
|
82
|
+
All API methods throw `SdkException` on failure. The exception contains:
|
|
83
|
+
|
|
84
|
+
- `status`: HTTP status code (for API errors)
|
|
85
|
+
- `code`: Machine-readable error code (if available)
|
|
86
|
+
- `message`: Human-readable error message
|
|
87
|
+
- `requestId`: Server-assigned request ID for support
|
|
88
|
+
|
|
89
|
+
```kotlin
|
|
90
|
+
try {
|
|
91
|
+
val result = client.users.getUser("user-123")
|
|
92
|
+
println("Success: $result")
|
|
93
|
+
} catch (e: SdkException) {
|
|
94
|
+
when {
|
|
95
|
+
e.isClientError() -> println("Bad request: ${e.message}")
|
|
96
|
+
e.isServerError() -> println("Server error (${e.status}): ${e.message}")
|
|
97
|
+
e.isNetworkError() -> println("Network error: ${e.message}")
|
|
98
|
+
else -> println("Error: ${e.message}")
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rootProject.name = "{{artifactId}}"
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
package {{packageName}}
|
|
2
|
+
|
|
3
|
+
import io.ktor.client.*
|
|
4
|
+
import io.ktor.client.engine.cio.*
|
|
5
|
+
import io.ktor.client.plugins.*
|
|
6
|
+
import io.ktor.client.plugins.contentnegotiation.*
|
|
7
|
+
import io.ktor.client.request.*
|
|
8
|
+
import io.ktor.client.statement.*
|
|
9
|
+
import io.ktor.http.*
|
|
10
|
+
import io.ktor.serialization.kotlinx.json.*
|
|
11
|
+
import kotlinx.serialization.json.Json
|
|
12
|
+
import kotlinx.serialization.json.JsonObject
|
|
13
|
+
import kotlinx.serialization.json.jsonPrimitive
|
|
14
|
+
import kotlinx.coroutines.*
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal transport configuration.
|
|
18
|
+
*/
|
|
19
|
+
data class TransportConfig(
|
|
20
|
+
val baseUrl: String,
|
|
21
|
+
{{#each securitySchemes}}
|
|
22
|
+
val {{configKey}}: String? = null,
|
|
23
|
+
{{/each}}
|
|
24
|
+
val timeoutMs: Long = 15000,
|
|
25
|
+
val maxRetries: Int = 3,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* HTTP transport layer for the SDK.
|
|
30
|
+
*
|
|
31
|
+
* Handles request building, authentication, retries, and error mapping
|
|
32
|
+
* using Ktor's HttpClient.
|
|
33
|
+
*/
|
|
34
|
+
class Transport(
|
|
35
|
+
private val config: TransportConfig
|
|
36
|
+
) {
|
|
37
|
+
private val json = Json {
|
|
38
|
+
ignoreUnknownKeys = true
|
|
39
|
+
isLenient = true
|
|
40
|
+
encodeDefaults = true
|
|
41
|
+
coerceInputValues = true
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private val client = HttpClient(CIO) {
|
|
45
|
+
install(ContentNegotiation) {
|
|
46
|
+
json(json)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
install(HttpTimeout) {
|
|
50
|
+
requestTimeoutMillis = config.timeoutMs
|
|
51
|
+
connectTimeoutMillis = config.timeoutMs
|
|
52
|
+
socketTimeoutMillis = config.timeoutMs
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
defaultRequest {
|
|
56
|
+
url(config.baseUrl)
|
|
57
|
+
contentType(ContentType.Application.Json)
|
|
58
|
+
accept(ContentType.Application.Json)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Execute an HTTP request, deserializing the response body as JSON.
|
|
64
|
+
*/
|
|
65
|
+
suspend inline fun <reified T> execute(
|
|
66
|
+
method: HttpMethod,
|
|
67
|
+
path: String,
|
|
68
|
+
query: Map<String, String?>? = null,
|
|
69
|
+
body: Any? = null,
|
|
70
|
+
headers: Map<String, String>? = null,
|
|
71
|
+
): T {
|
|
72
|
+
val response = executeRaw(method, path, query, body, headers)
|
|
73
|
+
return json.decodeFromString<T>(response)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Execute an HTTP request, returning the raw response body as a string.
|
|
78
|
+
*/
|
|
79
|
+
suspend fun executeRaw(
|
|
80
|
+
method: HttpMethod,
|
|
81
|
+
path: String,
|
|
82
|
+
query: Map<String, String?>? = null,
|
|
83
|
+
body: Any? = null,
|
|
84
|
+
headers: Map<String, String>? = null,
|
|
85
|
+
): String {
|
|
86
|
+
return executeWithRetry(method, path, query, body, headers)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Close the underlying HTTP client. Call this when the SDK is no longer needed.
|
|
91
|
+
*/
|
|
92
|
+
fun close() {
|
|
93
|
+
client.close()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ── private helpers ─────────────────────────────────────────────────────
|
|
97
|
+
|
|
98
|
+
@OptIn(ExperimentalCoroutinesApi::class)
|
|
99
|
+
private suspend fun executeWithRetry(
|
|
100
|
+
method: HttpMethod,
|
|
101
|
+
path: String,
|
|
102
|
+
query: Map<String, String?>? = null,
|
|
103
|
+
body: Any? = null,
|
|
104
|
+
headers: Map<String, String>? = null,
|
|
105
|
+
attempt: Int = 0,
|
|
106
|
+
): String {
|
|
107
|
+
return try {
|
|
108
|
+
val response = client.request {
|
|
109
|
+
this.method = method
|
|
110
|
+
url {
|
|
111
|
+
// Base URL is set as default; append the path
|
|
112
|
+
val fullUrl = "${config.baseUrl.trimEnd('/')}${path}"
|
|
113
|
+
takeFrom(fullUrl)
|
|
114
|
+
|
|
115
|
+
// Add query parameters
|
|
116
|
+
query?.forEach { (key, value) ->
|
|
117
|
+
if (value != null) {
|
|
118
|
+
parameters.append(key, value)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Set request body
|
|
124
|
+
if (body != null) {
|
|
125
|
+
setBody(body)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Set custom headers
|
|
129
|
+
headers?.forEach { (key, value) ->
|
|
130
|
+
this.headers.append(key, value)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Apply authentication
|
|
134
|
+
applyAuth()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
val status = response.status.value
|
|
138
|
+
|
|
139
|
+
if (status in 200..299) {
|
|
140
|
+
response.bodyAsText()
|
|
141
|
+
} else if ((status >= 500 || status == 429) && attempt < config.maxRetries) {
|
|
142
|
+
// Retry on server errors and rate limiting
|
|
143
|
+
val backoffMs = 200L * (1L shl attempt)
|
|
144
|
+
delay(backoffMs)
|
|
145
|
+
executeWithRetry(method, path, query, body, headers, attempt + 1)
|
|
146
|
+
} else {
|
|
147
|
+
throw buildSdkException(response)
|
|
148
|
+
}
|
|
149
|
+
} catch (e: SdkException) {
|
|
150
|
+
throw e
|
|
151
|
+
} catch (e: CancellationException) {
|
|
152
|
+
throw e
|
|
153
|
+
} catch (e: Exception) {
|
|
154
|
+
if (attempt < config.maxRetries) {
|
|
155
|
+
val backoffMs = 200L * (1L shl attempt)
|
|
156
|
+
delay(backoffMs)
|
|
157
|
+
executeWithRetry(method, path, query, body, headers, attempt + 1)
|
|
158
|
+
} else {
|
|
159
|
+
throw SdkException(
|
|
160
|
+
status = null,
|
|
161
|
+
code = null,
|
|
162
|
+
message = "Network error: ${e.message}",
|
|
163
|
+
requestId = null,
|
|
164
|
+
cause = e,
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private suspend fun buildSdkException(response: HttpResponse): SdkException {
|
|
171
|
+
val status = response.status.value
|
|
172
|
+
val body = try {
|
|
173
|
+
response.bodyAsText()
|
|
174
|
+
} catch (e: Exception) {
|
|
175
|
+
null
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
val requestId = response.headers["x-request-id"]
|
|
179
|
+
?: response.headers["request-id"]
|
|
180
|
+
|
|
181
|
+
// Try to extract structured error info from the JSON body
|
|
182
|
+
var code: String? = null
|
|
183
|
+
var message: String = body ?: "API error (status $status)"
|
|
184
|
+
|
|
185
|
+
if (body != null) {
|
|
186
|
+
try {
|
|
187
|
+
val jsonBody = json.decodeFromString<JsonObject>(body)
|
|
188
|
+
code = jsonBody["code"]?.jsonPrimitive?.content
|
|
189
|
+
?: jsonBody["error"]?.let { err ->
|
|
190
|
+
when (err) {
|
|
191
|
+
is JsonObject -> err["code"]?.jsonPrimitive?.content
|
|
192
|
+
else -> err.jsonPrimitive?.content
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
message = jsonBody["message"]?.jsonPrimitive?.content
|
|
196
|
+
?: jsonBody["error"]?.let { err ->
|
|
197
|
+
when (err) {
|
|
198
|
+
is JsonObject -> err["message"]?.jsonPrimitive?.content
|
|
199
|
+
else -> err.jsonPrimitive?.content
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
?: message
|
|
203
|
+
} catch (_: Exception) {
|
|
204
|
+
// Use raw body as the message
|
|
205
|
+
message = body
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return SdkException(
|
|
210
|
+
status = status,
|
|
211
|
+
code = code,
|
|
212
|
+
message = message,
|
|
213
|
+
requestId = requestId,
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private fun HttpRequestBuilder.applyAuth() {
|
|
218
|
+
{{#each securitySchemes}}
|
|
219
|
+
{{#if (eq type "apiKey")}}
|
|
220
|
+
{{#if (eq in "header")}}
|
|
221
|
+
config.{{configKey}}?.let { key ->
|
|
222
|
+
headers.append("{{paramName}}", key)
|
|
223
|
+
}
|
|
224
|
+
{{/if}}
|
|
225
|
+
{{#if (eq in "query")}}
|
|
226
|
+
// API key via query parameter handled during URL construction
|
|
227
|
+
{{/if}}
|
|
228
|
+
{{/if}}
|
|
229
|
+
{{#if (and (eq type "http") (eq scheme "bearer"))}}
|
|
230
|
+
config.{{configKey}}?.let { token ->
|
|
231
|
+
headers.append("Authorization", "Bearer $token")
|
|
232
|
+
}
|
|
233
|
+
{{/if}}
|
|
234
|
+
{{#if (eq type "oauth2")}}
|
|
235
|
+
config.{{configKey}}?.let { token ->
|
|
236
|
+
headers.append("Authorization", "Bearer $token")
|
|
237
|
+
}
|
|
238
|
+
{{/if}}
|
|
239
|
+
{{#if (eq type "openIdConnect")}}
|
|
240
|
+
config.{{configKey}}?.let { token ->
|
|
241
|
+
headers.append("Authorization", "Bearer $token")
|
|
242
|
+
}
|
|
243
|
+
{{/if}}
|
|
244
|
+
{{/each}}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
package {{packageName}}
|
|
2
|
+
|
|
3
|
+
import kotlinx.serialization.*
|
|
4
|
+
import kotlinx.serialization.descriptors.*
|
|
5
|
+
import kotlinx.serialization.encoding.*
|
|
6
|
+
import kotlinx.serialization.json.*
|
|
7
|
+
|
|
8
|
+
{{#each schemas}}
|
|
9
|
+
{{#if (not ownership)}}
|
|
10
|
+
{{#unless (or externalImport (eq ownership.kind "external"))}}
|
|
11
|
+
{{#if (not isEnum)}}
|
|
12
|
+
{{#if (not isUnionType)}}
|
|
13
|
+
{{#if (not isIntersectionType)}}
|
|
14
|
+
{{#if (not isTypeAlias)}}
|
|
15
|
+
{{#if description}}
|
|
16
|
+
/**
|
|
17
|
+
* {{description}}
|
|
18
|
+
*/
|
|
19
|
+
{{/if}}
|
|
20
|
+
@Serializable
|
|
21
|
+
data class {{name}}(
|
|
22
|
+
{{#each properties}}
|
|
23
|
+
{{#if description}}
|
|
24
|
+
/** {{description}} */
|
|
25
|
+
{{/if}}
|
|
26
|
+
{{#if deprecated}}
|
|
27
|
+
@Deprecated("{{#if deprecationMessage}}{{deprecationMessage}}{{else}}Use a different property.{{/if}}")
|
|
28
|
+
{{/if}}
|
|
29
|
+
{{#if (and nullable (not required))}}
|
|
30
|
+
@SerialName("{{name}}")
|
|
31
|
+
val {{name}}: {{{kotlinType type}}}? = null,
|
|
32
|
+
{{else if nullable}}
|
|
33
|
+
@SerialName("{{name}}")
|
|
34
|
+
val {{name}}: {{{kotlinType type}}}? = null,
|
|
35
|
+
{{else if required}}
|
|
36
|
+
@SerialName("{{name}}")
|
|
37
|
+
val {{name}}: {{{kotlinType type}}},
|
|
38
|
+
{{else}}
|
|
39
|
+
@SerialName("{{name}}")
|
|
40
|
+
val {{name}}: {{{kotlinType type}}}? = null,
|
|
41
|
+
{{/if}}
|
|
42
|
+
{{/each}}
|
|
43
|
+
)
|
|
44
|
+
{{/if}}
|
|
45
|
+
{{/if}}
|
|
46
|
+
{{/if}}
|
|
47
|
+
{{/if}}
|
|
48
|
+
{{/unless}}
|
|
49
|
+
{{/if}}
|
|
50
|
+
|
|
51
|
+
{{#if isEnum}}
|
|
52
|
+
{{#if description}}
|
|
53
|
+
/**
|
|
54
|
+
* {{description}}
|
|
55
|
+
*/
|
|
56
|
+
{{/if}}
|
|
57
|
+
@Serializable
|
|
58
|
+
enum class {{name}} {
|
|
59
|
+
{{#each enumValues}}
|
|
60
|
+
@SerialName("{{this}}")
|
|
61
|
+
{{pascalCase this}},
|
|
62
|
+
{{/each}}
|
|
63
|
+
}
|
|
64
|
+
{{/if}}
|
|
65
|
+
|
|
66
|
+
{{#if isUnionType}}
|
|
67
|
+
{{#if unionMembers.length}}
|
|
68
|
+
{{#if description}}
|
|
69
|
+
/**
|
|
70
|
+
* {{description}}
|
|
71
|
+
*/
|
|
72
|
+
{{/if}}
|
|
73
|
+
@Serializable
|
|
74
|
+
sealed class {{name}} {
|
|
75
|
+
{{#each unionMembers}}
|
|
76
|
+
@Serializable
|
|
77
|
+
data class {{pascalCase this}}(val value: {{{kotlinType this}}}) : {{../name}}()
|
|
78
|
+
{{/each}}
|
|
79
|
+
}
|
|
80
|
+
{{/if}}
|
|
81
|
+
{{/if}}
|
|
82
|
+
|
|
83
|
+
{{#if isIntersectionType}}
|
|
84
|
+
{{#if intersectionMembers.length}}
|
|
85
|
+
{{#if description}}
|
|
86
|
+
/**
|
|
87
|
+
* {{description}}
|
|
88
|
+
*/
|
|
89
|
+
{{/if}}
|
|
90
|
+
{{! Intersection type — emit as interface implemented by concrete types }}
|
|
91
|
+
@Serializable
|
|
92
|
+
data class {{name}}(
|
|
93
|
+
// Intersection of: {{join intersectionMembers ", "}}
|
|
94
|
+
// Fields from all intersected types should be inlined here.
|
|
95
|
+
// TODO: generate combined fields
|
|
96
|
+
)
|
|
97
|
+
{{/if}}
|
|
98
|
+
{{/if}}
|
|
99
|
+
|
|
100
|
+
{{/each}}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @generated
|
|
5
|
+
* This file was automatically generated by Tesseract.
|
|
6
|
+
* DO NOT MODIFY THIS FILE DIRECTLY.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
declare(strict_types=1);
|
|
10
|
+
|
|
11
|
+
namespace {{namespace}};
|
|
12
|
+
|
|
13
|
+
{{#each groups}}
|
|
14
|
+
use {{namespace}}\Api\{{className}};
|
|
15
|
+
{{/each}}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* {{title}} SDK Client.
|
|
19
|
+
*
|
|
20
|
+
* Entry point for all API operations. Provides accessor methods
|
|
21
|
+
* for each domain group and manages shared transport configuration.
|
|
22
|
+
*
|
|
23
|
+
* Usage:
|
|
24
|
+
* <code>
|
|
25
|
+
* $client = new Client(['baseUrl' => '{{baseUrl}}']);
|
|
26
|
+
* $result = $client->{{groups.[0].name}}()->{{groups.[0].operations.[0].name}}(...);
|
|
27
|
+
* </code>
|
|
28
|
+
*/
|
|
29
|
+
class Client
|
|
30
|
+
{
|
|
31
|
+
private Transport $transport;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param array{
|
|
35
|
+
* baseUrl?: string,
|
|
36
|
+
* timeoutMs?: int,
|
|
37
|
+
* retries?: array{attempts?: int, backoffMs?: int, jitter?: bool, maxBackoffMs?: int},
|
|
38
|
+
* defaultHeaders?: array<string, string>,
|
|
39
|
+
{{#each securitySchemes}}
|
|
40
|
+
* {{configKey}}?: string,
|
|
41
|
+
{{/each}}
|
|
42
|
+
* } $config
|
|
43
|
+
*/
|
|
44
|
+
public function __construct(array $config = [])
|
|
45
|
+
{
|
|
46
|
+
$this->transport = new Transport($config);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get the underlying transport instance for advanced use.
|
|
51
|
+
*/
|
|
52
|
+
public function getTransport(): Transport
|
|
53
|
+
{
|
|
54
|
+
return $this->transport;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
{{#each groups}}
|
|
58
|
+
/** @var {{className}}|null */
|
|
59
|
+
private ?{{className}} $_{{{name}}} = null;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
{{#if description}}
|
|
63
|
+
* {{description}}
|
|
64
|
+
*
|
|
65
|
+
{{/if}}
|
|
66
|
+
* @return {{className}}
|
|
67
|
+
*/
|
|
68
|
+
public function {{name}}(): {{className}}
|
|
69
|
+
{
|
|
70
|
+
return $this->_{{{name}}} ??= new {{className}}($this->transport);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
{{/each}}
|
|
74
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{composerName}}",
|
|
3
|
+
"description": "{{#if description}}{{description}}{{else}}PHP SDK for {{title}}{{/if}}",
|
|
4
|
+
"type": "library",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"autoload": {
|
|
7
|
+
"psr-4": {
|
|
8
|
+
"{{namespace}}\\": "src/"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"require": {
|
|
12
|
+
"php": ">=8.1",
|
|
13
|
+
"guzzlehttp/guzzle": "^7.0",
|
|
14
|
+
"ext-json": "*"
|
|
15
|
+
},
|
|
16
|
+
"require-dev": {
|
|
17
|
+
"phpunit/phpunit": "^10.0"
|
|
18
|
+
}
|
|
19
|
+
}
|