diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a6d1424..63b78ae 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,7 +19,7 @@ jobs:
timeout-minutes: 15
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/nuntly-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
@@ -46,7 +46,7 @@ jobs:
contents: read
id-token: write
runs-on: ${{ github.repository == 'stainless-sdks/nuntly-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 2aca35a..4208b5c 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.5.0"
+ ".": "0.6.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 5071f13..54e4c4e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 55
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/bazoud-corp%2Fnuntly-b843f02910523cb4ef8c23e1094c8421eb3bd6f78d9af975c12a162615bfd8e1.yml
-openapi_spec_hash: a6cd2ac946127a11e40151aa47452036
-config_hash: f7efb1381efa887568a5e7028908ebd3
+configured_endpoints: 56
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/bazoud-corp/nuntly-8c62ff49f7cf36d877996fed2351b4e8e81f2397f5c7cb9d54b417f37cda8cd7.yml
+openapi_spec_hash: 3e951a779e301ace98f73eabfe149e9b
+config_hash: cf044f6bbd66c7aaf276100fe2f65f7e
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a69880..416ad9b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,37 @@
# Changelog
+## 0.6.0 (2026-05-06)
+
+Full Changelog: [v0.5.0...v0.6.0](https://github.com/nuntly/nuntly-sdk-java/compare/v0.5.0...v0.6.0)
+
+### Features
+
+* **api:** implement label ([9106e39](https://github.com/nuntly/nuntly-sdk-java/commit/9106e39a9f68032114ada016fb3e6d6a1be4cf27))
+* **client:** more robust error parsing ([cc836e0](https://github.com/nuntly/nuntly-sdk-java/commit/cc836e0fed4853538d946b64125c6cc402fcbdbc))
+* **client:** support proxy authentication ([e6e0f39](https://github.com/nuntly/nuntly-sdk-java/commit/e6e0f3929ae6693a5d300ab4efdbc729819c0182))
+* support setting headers via env ([fba15cd](https://github.com/nuntly/nuntly-sdk-java/commit/fba15cddd34b79348161aa1036496e5aeb9e3170))
+
+
+### Performance Improvements
+
+* **client:** create one json mapper ([f349b91](https://github.com/nuntly/nuntly-sdk-java/commit/f349b91d30687e78cb5f1389fdbb8abb73e6a28c))
+
+
+### Chores
+
+* **ci:** skip lint on metadata-only changes ([be6c700](https://github.com/nuntly/nuntly-sdk-java/commit/be6c7000aa0ec54b5abd5acc023c3d2ffd69969a))
+* **internal:** update multipart form array serialization ([7cc35eb](https://github.com/nuntly/nuntly-sdk-java/commit/7cc35eb8ed276450e7fbc1617c32149a12818dd4))
+* remove duplicated dokka setup ([b905581](https://github.com/nuntly/nuntly-sdk-java/commit/b90558163d03ec7305341c5929a47a678c6f1889))
+* **tests:** bump steady to v0.19.7 ([9ad4c85](https://github.com/nuntly/nuntly-sdk-java/commit/9ad4c85cf8e51352f661d7ee640ae1d8dd724a8f))
+* **tests:** bump steady to v0.20.1 ([4ca6c5e](https://github.com/nuntly/nuntly-sdk-java/commit/4ca6c5e8299d69f16020dc83f95452a25e9de016))
+* **tests:** bump steady to v0.20.2 ([f406712](https://github.com/nuntly/nuntly-sdk-java/commit/f406712b2daed702c802028b63b1f97facd75454))
+* **tests:** bump steady to v0.22.1 ([0043aa0](https://github.com/nuntly/nuntly-sdk-java/commit/0043aa083c9f94bd71e9be4552431ffee23c76c9))
+
+
+### Documentation
+
+* clarify forwards compat behavior ([3dfae7a](https://github.com/nuntly/nuntly-sdk-java/commit/3dfae7a1b98935aba71e07f06e13f2e68888203d))
+
## 0.5.0 (2026-03-24)
Full Changelog: [v0.4.0...v0.5.0](https://github.com/nuntly/nuntly-sdk-java/compare/v0.4.0...v0.5.0)
diff --git a/README.md b/README.md
index b84b66f..8a6844a 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.nuntly/nuntly-java/0.5.0)
-[](https://javadoc.io/doc/com.nuntly/nuntly-java/0.5.0)
+[](https://central.sonatype.com/artifact/com.nuntly/nuntly-java/0.6.0)
+[](https://javadoc.io/doc/com.nuntly/nuntly-java/0.6.0)
@@ -22,7 +22,7 @@ Use the Nuntly MCP Server to enable AI assistants to interact with this API, all
-The REST API documentation can be found on [developers.nuntly.com](http://developers.nuntly.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.nuntly/nuntly-java/0.5.0).
+The REST API documentation can be found on [developers.nuntly.com](http://developers.nuntly.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.nuntly/nuntly-java/0.6.0).
@@ -33,7 +33,7 @@ The REST API documentation can be found on [developers.nuntly.com](http://develo
### Gradle
```kotlin
-implementation("com.nuntly:nuntly-java:0.5.0")
+implementation("com.nuntly:nuntly-java:0.6.0")
```
### Maven
@@ -42,7 +42,7 @@ implementation("com.nuntly:nuntly-java:0.5.0")
com.nuntly
nuntly-java
- 0.5.0
+ 0.6.0
```
@@ -460,6 +460,21 @@ NuntlyClient client = NuntlyOkHttpClient.builder()
.build();
```
+If the proxy responds with `407 Proxy Authentication Required`, supply credentials by also configuring `proxyAuthenticator`:
+
+```java
+import com.nuntly.client.NuntlyClient;
+import com.nuntly.client.okhttp.NuntlyOkHttpClient;
+import com.nuntly.core.http.ProxyAuthenticator;
+
+NuntlyClient client = NuntlyOkHttpClient.builder()
+ .fromEnv()
+ .proxy(...)
+ // Or a custom implementation of `ProxyAuthenticator`.
+ .proxyAuthenticator(ProxyAuthenticator.basic("username", "password"))
+ .build();
+```
+
### Connection pooling
To customize the underlying OkHttp connection pool, configure the client using the `maxIdleConnections` and `keepAliveDuration` methods:
@@ -700,7 +715,9 @@ In rare cases, the API may return a response that doesn't match the expected typ
By default, the SDK will not throw an exception in this case. It will throw [`NuntlyInvalidDataException`](nuntly-java-core/src/main/kotlin/com/nuntly/errors/NuntlyInvalidDataException.kt) only if you directly access the property.
-If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`:
+Validating the response is _not_ forwards compatible with new types from the API for existing fields.
+
+If you would still prefer to check that the response is completely well-typed upfront, then either call `validate()`:
```java
import com.nuntly.models.emails.EmailSendResponse;
diff --git a/build.gradle.kts b/build.gradle.kts
index a1ce5f5..fabc986 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.nuntly"
- version = "0.5.0" // x-release-please-version
+ version = "0.6.0" // x-release-please-version
}
subprojects {
@@ -21,7 +21,6 @@ subprojects {
group = "Verification"
description = "Verifies all source files are formatted."
}
- apply(plugin = "org.jetbrains.dokka")
}
subprojects {
diff --git a/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClient.kt b/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClient.kt
index 1bfd88d..5fde224 100644
--- a/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClient.kt
+++ b/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClient.kt
@@ -11,6 +11,7 @@ import com.nuntly.core.Timeout
import com.nuntly.core.http.AsyncStreamResponse
import com.nuntly.core.http.Headers
import com.nuntly.core.http.HttpClient
+import com.nuntly.core.http.ProxyAuthenticator
import com.nuntly.core.http.QueryParams
import com.nuntly.core.jsonMapper
import java.net.Proxy
@@ -49,6 +50,7 @@ class NuntlyOkHttpClient private constructor() {
private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
private var dispatcherExecutorService: ExecutorService? = null
private var proxy: Proxy? = null
+ private var proxyAuthenticator: ProxyAuthenticator? = null
private var maxIdleConnections: Int? = null
private var keepAliveDuration: Duration? = null
private var sslSocketFactory: SSLSocketFactory? = null
@@ -79,6 +81,20 @@ class NuntlyOkHttpClient private constructor() {
/** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */
fun proxy(proxy: Optional) = proxy(proxy.getOrNull())
+ /**
+ * Provides credentials when an HTTP proxy responds with `407 Proxy Authentication
+ * Required`.
+ */
+ fun proxyAuthenticator(proxyAuthenticator: ProxyAuthenticator?) = apply {
+ this.proxyAuthenticator = proxyAuthenticator
+ }
+
+ /**
+ * Alias for calling [Builder.proxyAuthenticator] with `proxyAuthenticator.orElse(null)`.
+ */
+ fun proxyAuthenticator(proxyAuthenticator: Optional) =
+ proxyAuthenticator(proxyAuthenticator.getOrNull())
+
/**
* The maximum number of idle connections kept by the underlying OkHttp connection pool.
*
@@ -230,6 +246,9 @@ class NuntlyOkHttpClient private constructor() {
/**
* Whether to call `validate` on every response before returning it.
*
+ * Setting this to `true` is _not_ forwards compatible with new types from the API for
+ * existing fields.
+ *
* Defaults to false, which means the shape of the response will not be validated upfront.
* Instead, validation will only occur for the parts of the response that are accessed.
*/
@@ -376,6 +395,7 @@ class NuntlyOkHttpClient private constructor() {
OkHttpClient.builder()
.timeout(clientOptions.timeout())
.proxy(proxy)
+ .proxyAuthenticator(proxyAuthenticator)
.maxIdleConnections(maxIdleConnections)
.keepAliveDuration(keepAliveDuration)
.dispatcherExecutorService(dispatcherExecutorService)
diff --git a/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClientAsync.kt b/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClientAsync.kt
index c5a2ff4..888eae3 100644
--- a/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClientAsync.kt
+++ b/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/NuntlyOkHttpClientAsync.kt
@@ -11,6 +11,7 @@ import com.nuntly.core.Timeout
import com.nuntly.core.http.AsyncStreamResponse
import com.nuntly.core.http.Headers
import com.nuntly.core.http.HttpClient
+import com.nuntly.core.http.ProxyAuthenticator
import com.nuntly.core.http.QueryParams
import com.nuntly.core.jsonMapper
import java.net.Proxy
@@ -49,6 +50,7 @@ class NuntlyOkHttpClientAsync private constructor() {
private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
private var dispatcherExecutorService: ExecutorService? = null
private var proxy: Proxy? = null
+ private var proxyAuthenticator: ProxyAuthenticator? = null
private var maxIdleConnections: Int? = null
private var keepAliveDuration: Duration? = null
private var sslSocketFactory: SSLSocketFactory? = null
@@ -79,6 +81,20 @@ class NuntlyOkHttpClientAsync private constructor() {
/** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */
fun proxy(proxy: Optional) = proxy(proxy.getOrNull())
+ /**
+ * Provides credentials when an HTTP proxy responds with `407 Proxy Authentication
+ * Required`.
+ */
+ fun proxyAuthenticator(proxyAuthenticator: ProxyAuthenticator?) = apply {
+ this.proxyAuthenticator = proxyAuthenticator
+ }
+
+ /**
+ * Alias for calling [Builder.proxyAuthenticator] with `proxyAuthenticator.orElse(null)`.
+ */
+ fun proxyAuthenticator(proxyAuthenticator: Optional) =
+ proxyAuthenticator(proxyAuthenticator.getOrNull())
+
/**
* The maximum number of idle connections kept by the underlying OkHttp connection pool.
*
@@ -230,6 +246,9 @@ class NuntlyOkHttpClientAsync private constructor() {
/**
* Whether to call `validate` on every response before returning it.
*
+ * Setting this to `true` is _not_ forwards compatible with new types from the API for
+ * existing fields.
+ *
* Defaults to false, which means the shape of the response will not be validated upfront.
* Instead, validation will only occur for the parts of the response that are accessed.
*/
@@ -376,6 +395,7 @@ class NuntlyOkHttpClientAsync private constructor() {
OkHttpClient.builder()
.timeout(clientOptions.timeout())
.proxy(proxy)
+ .proxyAuthenticator(proxyAuthenticator)
.maxIdleConnections(maxIdleConnections)
.keepAliveDuration(keepAliveDuration)
.dispatcherExecutorService(dispatcherExecutorService)
diff --git a/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/OkHttpClient.kt b/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/OkHttpClient.kt
index a8b59b1..ce980a9 100644
--- a/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/OkHttpClient.kt
+++ b/nuntly-java-client-okhttp/src/main/kotlin/com/nuntly/client/okhttp/OkHttpClient.kt
@@ -8,9 +8,11 @@ import com.nuntly.core.http.HttpMethod
import com.nuntly.core.http.HttpRequest
import com.nuntly.core.http.HttpRequestBody
import com.nuntly.core.http.HttpResponse
+import com.nuntly.core.http.ProxyAuthenticator
import com.nuntly.errors.NuntlyIoException
import java.io.IOException
import java.io.InputStream
+import java.io.OutputStream
import java.net.Proxy
import java.time.Duration
import java.util.concurrent.CancellationException
@@ -20,10 +22,12 @@ import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
+import kotlin.jvm.optionals.getOrNull
import okhttp3.Call
import okhttp3.Callback
import okhttp3.ConnectionPool
import okhttp3.Dispatcher
+import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
@@ -33,6 +37,8 @@ import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import okio.BufferedSink
+import okio.buffer
+import okio.sink
class OkHttpClient
internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient {
@@ -41,7 +47,7 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
val call = newCall(request, requestOptions)
return try {
- call.execute().toResponse()
+ call.execute().toHttpResponse()
} catch (e: IOException) {
throw NuntlyIoException("Request failed", e)
} finally {
@@ -59,7 +65,7 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
call.enqueue(
object : Callback {
override fun onResponse(call: Call, response: Response) {
- future.complete(response.toResponse())
+ future.complete(response.toHttpResponse())
}
override fun onFailure(call: Call, e: IOException) {
@@ -111,89 +117,6 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
return client.newCall(request.toRequest(client))
}
- private fun HttpRequest.toRequest(client: okhttp3.OkHttpClient): Request {
- var body: RequestBody? = body?.toRequestBody()
- if (body == null && requiresBody(method)) {
- body = "".toRequestBody()
- }
-
- val builder = Request.Builder().url(toUrl()).method(method.name, body)
- headers.names().forEach { name ->
- headers.values(name).forEach { builder.addHeader(name, it) }
- }
-
- if (
- !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0
- ) {
- builder.addHeader(
- "X-Stainless-Read-Timeout",
- Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(),
- )
- }
- if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) {
- builder.addHeader(
- "X-Stainless-Timeout",
- Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(),
- )
- }
-
- return builder.build()
- }
-
- /** `OkHttpClient` always requires a request body for some methods. */
- private fun requiresBody(method: HttpMethod): Boolean =
- when (method) {
- HttpMethod.POST,
- HttpMethod.PUT,
- HttpMethod.PATCH -> true
- else -> false
- }
-
- private fun HttpRequest.toUrl(): String {
- val builder = baseUrl.toHttpUrl().newBuilder()
- pathSegments.forEach(builder::addPathSegment)
- queryParams.keys().forEach { key ->
- queryParams.values(key).forEach { builder.addQueryParameter(key, it) }
- }
-
- return builder.toString()
- }
-
- private fun HttpRequestBody.toRequestBody(): RequestBody {
- val mediaType = contentType()?.toMediaType()
- val length = contentLength()
-
- return object : RequestBody() {
- override fun contentType(): MediaType? = mediaType
-
- override fun contentLength(): Long = length
-
- override fun isOneShot(): Boolean = !repeatable()
-
- override fun writeTo(sink: BufferedSink) = writeTo(sink.outputStream())
- }
- }
-
- private fun Response.toResponse(): HttpResponse {
- val headers = headers.toHeaders()
-
- return object : HttpResponse {
- override fun statusCode(): Int = code
-
- override fun headers(): Headers = headers
-
- override fun body(): InputStream = body!!.byteStream()
-
- override fun close() = body!!.close()
- }
- }
-
- private fun okhttp3.Headers.toHeaders(): Headers {
- val headersBuilder = Headers.builder()
- forEach { (name, value) -> headersBuilder.put(name, value) }
- return headersBuilder.build()
- }
-
companion object {
@JvmStatic fun builder() = Builder()
}
@@ -202,6 +125,7 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null
+ private var proxyAuthenticator: ProxyAuthenticator? = null
private var maxIdleConnections: Int? = null
private var keepAliveDuration: Duration? = null
private var dispatcherExecutorService: ExecutorService? = null
@@ -215,6 +139,10 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }
+ fun proxyAuthenticator(proxyAuthenticator: ProxyAuthenticator?) = apply {
+ this.proxyAuthenticator = proxyAuthenticator
+ }
+
/**
* Sets the maximum number of idle connections kept by the underlying [ConnectionPool].
*
@@ -264,6 +192,19 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
.callTimeout(timeout.request())
.proxy(proxy)
.apply {
+ proxyAuthenticator?.let { auth ->
+ proxyAuthenticator { route, response ->
+ auth
+ .authenticate(
+ route?.proxy ?: Proxy.NO_PROXY,
+ response.request.toHttpRequest(),
+ response.toHttpResponse(),
+ )
+ .getOrNull()
+ ?.toRequest(client = null)
+ }
+ }
+
dispatcherExecutorService?.let { dispatcher(Dispatcher(it)) }
val maxIdleConnections = maxIdleConnections
@@ -303,3 +244,126 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie
)
}
}
+
+private fun HttpRequest.toRequest(client: okhttp3.OkHttpClient?): Request {
+ var body: RequestBody? = body?.toRequestBody()
+ if (body == null && requiresBody(method)) {
+ body = "".toRequestBody()
+ }
+
+ val builder = Request.Builder().url(toUrl()).method(method.name, body)
+ headers.names().forEach { name -> headers.values(name).forEach { builder.addHeader(name, it) } }
+
+ if (client != null) {
+ if (
+ !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0
+ ) {
+ builder.addHeader(
+ "X-Stainless-Read-Timeout",
+ Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(),
+ )
+ }
+ if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) {
+ builder.addHeader(
+ "X-Stainless-Timeout",
+ Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(),
+ )
+ }
+ }
+
+ return builder.build()
+}
+
+/** `OkHttpClient` always requires a request body for some methods. */
+private fun requiresBody(method: HttpMethod): Boolean =
+ when (method) {
+ HttpMethod.POST,
+ HttpMethod.PUT,
+ HttpMethod.PATCH -> true
+ else -> false
+ }
+
+private fun HttpRequest.toUrl(): String {
+ val builder = baseUrl.toHttpUrl().newBuilder()
+ pathSegments.forEach(builder::addPathSegment)
+ queryParams.keys().forEach { key ->
+ queryParams.values(key).forEach { builder.addQueryParameter(key, it) }
+ }
+
+ return builder.toString()
+}
+
+private fun HttpRequestBody.toRequestBody(): RequestBody {
+ val mediaType = contentType()?.toMediaType()
+ val length = contentLength()
+
+ return object : RequestBody() {
+ override fun contentType(): MediaType? = mediaType
+
+ override fun contentLength(): Long = length
+
+ override fun isOneShot(): Boolean = !repeatable()
+
+ override fun writeTo(sink: BufferedSink) = writeTo(sink.outputStream())
+ }
+}
+
+private fun Request.toHttpRequest(): HttpRequest {
+ val builder = HttpRequest.builder().method(HttpMethod.valueOf(method)).baseUrl(url.toBaseUrl())
+ url.pathSegments.forEach(builder::addPathSegment)
+ url.queryParameterNames.forEach { name ->
+ url.queryParameterValues(name).filterNotNull().forEach { builder.putQueryParam(name, it) }
+ }
+ headers.forEach { (name, value) -> builder.putHeader(name, value) }
+ body?.let { builder.body(it.toHttpRequestBody()) }
+ return builder.build()
+}
+
+private fun HttpUrl.toBaseUrl(): String = buildString {
+ append(scheme).append("://").append(host)
+ if (port != HttpUrl.defaultPort(scheme)) {
+ append(":").append(port)
+ }
+}
+
+private fun RequestBody.toHttpRequestBody(): HttpRequestBody {
+ val mediaType = contentType()?.toString()
+ val length = contentLength()
+ val isOneShot = isOneShot()
+ val source = this
+ return object : HttpRequestBody {
+ override fun contentType(): String? = mediaType
+
+ override fun contentLength(): Long = length
+
+ override fun repeatable(): Boolean = !isOneShot
+
+ override fun writeTo(outputStream: OutputStream) {
+ val sink = outputStream.sink().buffer()
+ source.writeTo(sink)
+ sink.flush()
+ }
+
+ override fun close() {}
+ }
+}
+
+private fun Response.toHttpResponse(): HttpResponse {
+ val headers = headers.toHeaders()
+
+ return object : HttpResponse {
+ override fun statusCode(): Int = code
+
+ override fun headers(): Headers = headers
+
+ override fun body(): InputStream = body!!.byteStream()
+
+ override fun close() = body!!.close()
+ }
+}
+
+private fun okhttp3.Headers.toHeaders(): Headers {
+ val headersBuilder = Headers.builder()
+ forEach { (name, value) -> headersBuilder.put(name, value) }
+ return headersBuilder.build()
+}
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/core/ClientOptions.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/core/ClientOptions.kt
index 5dcce5c..083455c 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/core/ClientOptions.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/core/ClientOptions.kt
@@ -80,6 +80,9 @@ private constructor(
/**
* Whether to call `validate` on every response before returning it.
*
+ * Setting this to `true` is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
* Defaults to false, which means the shape of the response will not be validated upfront.
* Instead, validation will only occur for the parts of the response that are accessed.
*/
@@ -261,6 +264,9 @@ private constructor(
/**
* Whether to call `validate` on every response before returning it.
*
+ * Setting this to `true` is _not_ forwards compatible with new types from the API for
+ * existing fields.
+ *
* Defaults to false, which means the shape of the response will not be validated upfront.
* Instead, validation will only occur for the parts of the response that are accessed.
*/
@@ -409,6 +415,14 @@ private constructor(
(System.getProperty("nuntly.apiKey") ?: System.getenv("NUNTLY_API_KEY"))?.let {
apiKey(it)
}
+ System.getenv("NUNTLY_CUSTOM_HEADERS")?.let { customHeadersEnv ->
+ for (line in customHeadersEnv.split("\n")) {
+ val colon = line.indexOf(':')
+ if (colon >= 0) {
+ putHeader(line.substring(0, colon).trim(), line.substring(colon + 1).trim())
+ }
+ }
+ }
}
/**
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/core/ObjectMappers.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/core/ObjectMappers.kt
index ab3bad0..5768537 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/core/ObjectMappers.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/core/ObjectMappers.kt
@@ -29,7 +29,9 @@ import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoField
-fun jsonMapper(): JsonMapper =
+fun jsonMapper(): JsonMapper = JSON_MAPPER
+
+private val JSON_MAPPER: JsonMapper =
JsonMapper.builder()
.addModule(kotlinModule())
.addModule(Jdk8Module())
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/core/RequestOptions.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/core/RequestOptions.kt
index 7500bcd..62782b4 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/core/RequestOptions.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/core/RequestOptions.kt
@@ -33,6 +33,15 @@ class RequestOptions private constructor(val responseValidation: Boolean?, val t
private var responseValidation: Boolean? = null
private var timeout: Timeout? = null
+ /**
+ * Whether to call `validate` on the response before returning it.
+ *
+ * Setting this to `true` is _not_ forwards compatible with new types from the API for
+ * existing fields.
+ *
+ * Defaults to false, which means the shape of the response will not be validated upfront.
+ * Instead, validation will only occur for the parts of the response that are accessed.
+ */
fun responseValidation(responseValidation: Boolean) = apply {
this.responseValidation = responseValidation
}
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/core/http/ProxyAuthenticator.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/core/http/ProxyAuthenticator.kt
new file mode 100644
index 0000000..82d6969
--- /dev/null
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/core/http/ProxyAuthenticator.kt
@@ -0,0 +1,59 @@
+package com.nuntly.core.http
+
+import java.net.Proxy
+import java.nio.charset.Charset
+import java.nio.charset.StandardCharsets
+import java.util.Base64
+import java.util.Optional
+
+/**
+ * Provides credentials when an HTTP proxy responds with `407 Proxy Authentication Required`.
+ *
+ * Implementations inspect the 407 [response] (typically its `Proxy-Authenticate` header) and return
+ * the request to retry with a `Proxy-Authorization` header set, or [Optional.empty] to abandon
+ * authentication and surface the 407 to the caller.
+ *
+ * Implementations must be thread-safe; they may be invoked concurrently from multiple HTTP calls.
+ */
+fun interface ProxyAuthenticator {
+
+ /**
+ * @param proxy the proxy that produced the challenge, or [Proxy.NO_PROXY] if the route is not
+ * yet established
+ * @param request the request that produced [response]
+ * @param response the 407 challenge response
+ * @return the retry request to send (typically [request] with a `Proxy-Authorization` header
+ * added), or [Optional.empty] to abandon authentication
+ */
+ fun authenticate(
+ proxy: Proxy,
+ request: HttpRequest,
+ response: HttpResponse,
+ ): Optional
+
+ companion object {
+
+ /**
+ * A [ProxyAuthenticator] that uses RFC 7617 Basic authentication with the ISO-8859-1
+ * charset.
+ */
+ @JvmStatic
+ fun basic(username: String, password: String): ProxyAuthenticator =
+ basic(username, password, StandardCharsets.ISO_8859_1)
+
+ /**
+ * A [ProxyAuthenticator] that uses RFC 7617 Basic authentication with the given [charset].
+ */
+ @JvmStatic
+ fun basic(username: String, password: String, charset: Charset): ProxyAuthenticator {
+ val token =
+ Base64.getEncoder().encodeToString("$username:$password".toByteArray(charset))
+ val headerValue = "Basic $token"
+ return ProxyAuthenticator { _, request, _ ->
+ Optional.of(
+ request.toBuilder().putHeader("Proxy-Authorization", headerValue).build()
+ )
+ }
+ }
+ }
+}
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/BadRequestException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/BadRequestException.kt
index 06d0d7f..7d658ce 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/BadRequestException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/BadRequestException.kt
@@ -5,12 +5,16 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
class BadRequestException
private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) :
- NuntlyServiceException("400: $body", cause) {
+ NuntlyServiceException(
+ "400: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = 400
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/InternalServerException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/InternalServerException.kt
index 94f2b17..867efee 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/InternalServerException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/InternalServerException.kt
@@ -5,6 +5,7 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
@@ -14,7 +15,11 @@ private constructor(
private val headers: Headers,
private val body: JsonValue,
cause: Throwable?,
-) : NuntlyServiceException("$statusCode: $body", cause) {
+) :
+ NuntlyServiceException(
+ "$statusCode: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = statusCode
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/NotFoundException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/NotFoundException.kt
index 9a260fc..5cb8e27 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/NotFoundException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/NotFoundException.kt
@@ -5,12 +5,16 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
class NotFoundException
private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) :
- NuntlyServiceException("404: $body", cause) {
+ NuntlyServiceException(
+ "404: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = 404
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/PermissionDeniedException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/PermissionDeniedException.kt
index 8a6e3a1..4cceef0 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/PermissionDeniedException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/PermissionDeniedException.kt
@@ -5,12 +5,16 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
class PermissionDeniedException
private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) :
- NuntlyServiceException("403: $body", cause) {
+ NuntlyServiceException(
+ "403: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = 403
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/RateLimitException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/RateLimitException.kt
index 41ee65b..82f467e 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/RateLimitException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/RateLimitException.kt
@@ -5,12 +5,16 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
class RateLimitException
private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) :
- NuntlyServiceException("429: $body", cause) {
+ NuntlyServiceException(
+ "429: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = 429
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnauthorizedException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnauthorizedException.kt
index 46d6740..f93ca0c 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnauthorizedException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnauthorizedException.kt
@@ -5,12 +5,16 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
class UnauthorizedException
private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) :
- NuntlyServiceException("401: $body", cause) {
+ NuntlyServiceException(
+ "401: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = 401
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnexpectedStatusCodeException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnexpectedStatusCodeException.kt
index c2b72ae..26a608e 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnexpectedStatusCodeException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnexpectedStatusCodeException.kt
@@ -5,6 +5,7 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
@@ -14,7 +15,11 @@ private constructor(
private val headers: Headers,
private val body: JsonValue,
cause: Throwable?,
-) : NuntlyServiceException("$statusCode: $body", cause) {
+) :
+ NuntlyServiceException(
+ "$statusCode: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = statusCode
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnprocessableEntityException.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnprocessableEntityException.kt
index 3523075..7971988 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnprocessableEntityException.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/errors/UnprocessableEntityException.kt
@@ -5,12 +5,16 @@ package com.nuntly.errors
import com.nuntly.core.JsonValue
import com.nuntly.core.checkRequired
import com.nuntly.core.http.Headers
+import com.nuntly.core.jsonMapper
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
class UnprocessableEntityException
private constructor(private val headers: Headers, private val body: JsonValue, cause: Throwable?) :
- NuntlyServiceException("422: $body", cause) {
+ NuntlyServiceException(
+ "422: ${if (body.isMissing()) "Unknown" else jsonMapper().writeValueAsString(body)}",
+ cause,
+ ) {
override fun statusCode(): Int = 422
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/DataEnvelope.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/DataEnvelope.kt
index f4013e1..b3d5adf 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/DataEnvelope.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/DataEnvelope.kt
@@ -43,6 +43,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DataEnvelope = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/AgentMemory.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/AgentMemory.kt
index 65d2c0d..c98eae5 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/AgentMemory.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/AgentMemory.kt
@@ -373,6 +373,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): AgentMemory = apply {
if (validated) {
return@apply
@@ -472,6 +480,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Memory = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/memory/MemoryUpsertParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/memory/MemoryUpsertParams.kt
index 9faab49..8eb6bc2 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/memory/MemoryUpsertParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/agents/memory/MemoryUpsertParams.kt
@@ -560,6 +560,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
@@ -675,6 +684,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Memory = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateParams.kt
index 9b33159..413d503 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateParams.kt
@@ -545,6 +545,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
@@ -691,6 +700,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Permission = apply {
if (validated) {
return@apply
@@ -823,6 +841,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateResponse.kt
index 489bc79..c5da27c 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyCreateResponse.kt
@@ -266,6 +266,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ApiKeyCreateResponse = apply {
if (validated) {
return@apply
@@ -394,6 +402,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyDeleteResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyDeleteResponse.kt
index 636f195..691667f 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyDeleteResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyDeleteResponse.kt
@@ -127,6 +127,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ApiKeyDeleteResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListPageResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListPageResponse.kt
index fbaf6a3..66e502f 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListPageResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListPageResponse.kt
@@ -178,6 +178,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ApiKeyListPageResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListResponse.kt
index ed5fe11..d25ad0b 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyListResponse.kt
@@ -267,6 +267,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ApiKeyListResponse = apply {
if (validated) {
return@apply
@@ -395,6 +403,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyRetrieveResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyRetrieveResponse.kt
index 28a0984..7291633 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyRetrieveResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyRetrieveResponse.kt
@@ -267,6 +267,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ApiKeyRetrieveResponse = apply {
if (validated) {
return@apply
@@ -395,6 +403,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateParams.kt
index 4453c96..8e038b0 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateParams.kt
@@ -583,6 +583,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
@@ -729,6 +738,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Permission = apply {
if (validated) {
return@apply
@@ -854,6 +872,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateResponse.kt
index 0ec1010..17b70bc 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/apikeys/ApiKeyUpdateResponse.kt
@@ -127,6 +127,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ApiKeyUpdateResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateParams.kt
index 3728f11..de2939d 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateParams.kt
@@ -479,6 +479,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateResponse.kt
index 46dcfef..e8399c9 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainCreateResponse.kt
@@ -679,6 +679,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DomainCreateResponse = apply {
if (validated) {
return@apply
@@ -843,6 +851,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReceivingStatus = apply {
if (validated) {
return@apply
@@ -1335,6 +1352,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Record = apply {
if (validated) {
return@apply
@@ -1490,6 +1516,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Group = apply {
if (validated) {
return@apply
@@ -1628,6 +1664,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): RecordType = apply {
if (validated) {
return@apply
@@ -1776,6 +1822,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
@@ -1937,6 +1993,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Region = apply {
if (validated) {
return@apply
@@ -2073,6 +2138,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): SendingStatus = apply {
if (validated) {
return@apply
@@ -2217,6 +2291,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainDeleteResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainDeleteResponse.kt
index 45e8925..87fd700 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainDeleteResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainDeleteResponse.kt
@@ -127,6 +127,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DomainDeleteResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListPageResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListPageResponse.kt
index b6df5ee..a5e3bd3 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListPageResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListPageResponse.kt
@@ -178,6 +178,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DomainListPageResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListResponse.kt
index a45709e..3477b25 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainListResponse.kt
@@ -346,6 +346,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DomainListResponse = apply {
if (validated) {
return@apply
@@ -494,6 +502,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReceivingStatus = apply {
if (validated) {
return@apply
@@ -614,6 +631,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Region = apply {
if (validated) {
return@apply
@@ -750,6 +776,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): SendingStatus = apply {
if (validated) {
return@apply
@@ -894,6 +929,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainRetrieveResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainRetrieveResponse.kt
index 2c99ce4..f275409 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainRetrieveResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainRetrieveResponse.kt
@@ -679,6 +679,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DomainRetrieveResponse = apply {
if (validated) {
return@apply
@@ -843,6 +851,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReceivingStatus = apply {
if (validated) {
return@apply
@@ -1335,6 +1352,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Record = apply {
if (validated) {
return@apply
@@ -1490,6 +1516,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Group = apply {
if (validated) {
return@apply
@@ -1628,6 +1664,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): RecordType = apply {
if (validated) {
return@apply
@@ -1776,6 +1822,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
@@ -1937,6 +1993,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Region = apply {
if (validated) {
return@apply
@@ -2073,6 +2138,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): SendingStatus = apply {
if (validated) {
return@apply
@@ -2217,6 +2291,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateParams.kt
index 937fee1..6d35ae5 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateParams.kt
@@ -549,6 +549,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateResponse.kt
index df268ed..eff14a8 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/domains/DomainUpdateResponse.kt
@@ -210,6 +210,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): DomainUpdateResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailCancelResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailCancelResponse.kt
index eaf3e29..4e662b1 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailCancelResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailCancelResponse.kt
@@ -164,6 +164,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EmailCancelResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailContentItem.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailContentItem.kt
index 286a1a5..8f7e2be 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailContentItem.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailContentItem.kt
@@ -212,6 +212,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EmailContentItem = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListPageResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListPageResponse.kt
index 682eb8d..c04927b 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListPageResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListPageResponse.kt
@@ -177,6 +177,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EmailListPageResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListResponse.kt
index 0f6d113..092e17f 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailListResponse.kt
@@ -350,6 +350,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EmailListResponse = apply {
if (validated) {
return@apply
@@ -412,6 +420,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = to.accept(new To.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -421,6 +458,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): To = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailRetrieveResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailRetrieveResponse.kt
index 8c15cd6..450fb30 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailRetrieveResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailRetrieveResponse.kt
@@ -775,6 +775,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EmailRetrieveResponse = apply {
if (validated) {
return@apply
@@ -859,6 +867,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = to.accept(new To.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -868,6 +905,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): To = apply {
if (validated) {
return@apply
@@ -1171,6 +1217,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Attachment = apply {
if (validated) {
return@apply
@@ -1248,6 +1303,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = bcc.accept(new Bcc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1257,6 +1341,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Bcc = apply {
if (validated) {
return@apply
@@ -1415,6 +1508,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = cc.accept(new Cc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1424,6 +1546,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Cc = apply {
if (validated) {
return@apply
@@ -1617,6 +1748,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Headers = apply {
if (validated) {
return@apply
@@ -1685,6 +1825,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = replyTo.accept(new ReplyTo.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1694,6 +1863,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReplyTo = apply {
if (validated) {
return@apply
@@ -1891,6 +2069,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): StatusReason = apply {
if (validated) {
return@apply
@@ -1991,6 +2178,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Variables = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendParams.kt
index c91a60e..caabb17 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendParams.kt
@@ -1210,6 +1210,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
@@ -1332,6 +1341,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = to.accept(new To.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1341,6 +1379,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): To = apply {
if (validated) {
return@apply
@@ -1661,6 +1708,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Attachment = apply {
if (validated) {
return@apply
@@ -1738,6 +1794,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = bcc.accept(new Bcc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1747,6 +1832,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Bcc = apply {
if (validated) {
return@apply
@@ -1905,6 +1999,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = cc.accept(new Cc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1914,6 +2037,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Cc = apply {
if (validated) {
return@apply
@@ -2107,6 +2239,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Headers = apply {
if (validated) {
return@apply
@@ -2175,6 +2316,35 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API, unless
+ * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of
+ * the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = replyTo.accept(new ReplyTo.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in [visitor]
+ * and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -2184,6 +2354,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReplyTo = apply {
if (validated) {
return@apply
@@ -2381,6 +2560,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Variables = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendResponse.kt
index 6ffea56..30affae 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/EmailSendResponse.kt
@@ -164,6 +164,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EmailSendResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/Status.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/Status.kt
index 8fd6196..a9af90b 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/Status.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/Status.kt
@@ -147,6 +147,14 @@ class Status @JsonCreator private constructor(private val value: JsonField = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = bcc.accept(new Bcc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1106,6 +1154,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Bcc = apply {
if (validated) {
return@apply
@@ -1268,6 +1326,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = cc.accept(new Cc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1277,6 +1365,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Cc = apply {
if (validated) {
return@apply
@@ -1475,6 +1573,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Headers = apply {
if (validated) {
return@apply
@@ -1543,6 +1651,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = replyTo.accept(new ReplyTo.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1552,6 +1690,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReplyTo = apply {
if (validated) {
return@apply
@@ -1715,6 +1863,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = to.accept(new To.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -1724,6 +1902,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): To = apply {
if (validated) {
return@apply
@@ -1922,6 +2110,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Variables = apply {
if (validated) {
return@apply
@@ -2527,6 +2725,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Fallback = apply {
if (validated) {
return@apply
@@ -2600,6 +2807,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = bcc.accept(new Bcc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -2609,6 +2846,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Bcc = apply {
if (validated) {
return@apply
@@ -2771,6 +3018,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = cc.accept(new Cc.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -2780,6 +3057,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Cc = apply {
if (validated) {
return@apply
@@ -2978,6 +3265,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Headers = apply {
if (validated) {
return@apply
@@ -3046,6 +3343,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = replyTo.accept(new ReplyTo.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -3055,6 +3382,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ReplyTo = apply {
if (validated) {
return@apply
@@ -3218,6 +3555,36 @@ private constructor(
fun _json(): Optional = Optional.ofNullable(_json)
+ /**
+ * Maps this instance's current variant to a value of type [T] using the given
+ * [visitor].
+ *
+ * Note that this method is _not_ forwards compatible with new variants from the API,
+ * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this
+ * version of the SDK gracefully, consider overriding [Visitor.unknown]:
+ * ```java
+ * import com.nuntly.core.JsonValue;
+ * import java.util.Optional;
+ *
+ * Optional result = to.accept(new To.Visitor>() {
+ * @Override
+ * public Optional visitStrings(List strings) {
+ * return Optional.of(strings.toString());
+ * }
+ *
+ * // ...
+ *
+ * @Override
+ * public Optional unknown(JsonValue json) {
+ * // Or inspect the `json`.
+ * return Optional.empty();
+ * }
+ * });
+ * ```
+ *
+ * @throws NuntlyInvalidDataException if [Visitor.unknown] is not overridden in
+ * [visitor] and the current variant is unknown.
+ */
fun accept(visitor: Visitor): T =
when {
strings != null -> visitor.visitStrings(strings)
@@ -3227,6 +3594,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): To = apply {
if (validated) {
return@apply
@@ -3425,6 +3802,16 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Variables = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/bulk/BulkSendResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/bulk/BulkSendResponse.kt
index 2c19df0..9612276 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/bulk/BulkSendResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/bulk/BulkSendResponse.kt
@@ -178,6 +178,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): BulkSendResponse = apply {
if (validated) {
return@apply
@@ -350,6 +358,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Email = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/content/ContentRetrieveResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/content/ContentRetrieveResponse.kt
index 2226d09..736b1e7 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/content/ContentRetrieveResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/content/ContentRetrieveResponse.kt
@@ -347,6 +347,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ContentRetrieveResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/events/EventListResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/events/EventListResponse.kt
index 9b7f2e7..2533abc 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/events/EventListResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/events/EventListResponse.kt
@@ -316,6 +316,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): EventListResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/stats/StatListResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/stats/StatListResponse.kt
index 95abd2e..c55de2b 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/stats/StatListResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/emails/stats/StatListResponse.kt
@@ -210,6 +210,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): StatListResponse = apply {
if (validated) {
return@apply
@@ -1008,6 +1016,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Stat = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/Inbox.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/Inbox.kt
index bb8935c..8aa7702 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/Inbox.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/Inbox.kt
@@ -468,6 +468,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Inbox = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxCreateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxCreateParams.kt
index 0eae66c..7c9b94e 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxCreateParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxCreateParams.kt
@@ -606,6 +606,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxDeleteResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxDeleteResponse.kt
index 1353c32..8f3e58e 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxDeleteResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxDeleteResponse.kt
@@ -127,6 +127,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): InboxDeleteResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxListPageResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxListPageResponse.kt
index 1687db0..ae92378 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxListPageResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxListPageResponse.kt
@@ -175,6 +175,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): InboxListPageResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendParams.kt
index 3bb69bf..d246d3c 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendParams.kt
@@ -733,6 +733,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendResponse.kt
index 2a84170..dbeb9d6 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxSendResponse.kt
@@ -230,6 +230,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): InboxSendResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateParams.kt
index 92314b6..34116a4 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateParams.kt
@@ -351,6 +351,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateResponse.kt
index 8dfa2d6..890105b 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/InboxUpdateResponse.kt
@@ -127,6 +127,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): InboxUpdateResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListPageResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListPageResponse.kt
index 70806d7..5b011e2 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListPageResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListPageResponse.kt
@@ -176,6 +176,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): ThreadListPageResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListParams.kt
index 0f96013..25932a0 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/inboxes/threads/ThreadListParams.kt
@@ -14,8 +14,7 @@ class ThreadListParams
private constructor(
private val inboxId: String?,
private val cursor: String?,
- private val isRead: Boolean?,
- private val isSpam: Boolean?,
+ private val labels: String?,
private val limit: Double?,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
@@ -26,11 +25,11 @@ private constructor(
/** The cursor to retrieve the next page of results */
fun cursor(): Optional = Optional.ofNullable(cursor)
- /** Filter by read status. */
- fun isRead(): Optional = Optional.ofNullable(isRead)
-
- /** Filter by spam status. */
- fun isSpam(): Optional = Optional.ofNullable(isSpam)
+ /**
+ * Comma-separated labels to filter by (AND logic). Threads with spam/trash are excluded by
+ * default unless explicitly requested via ?labels=spam or ?labels=trash.
+ */
+ fun labels(): Optional = Optional.ofNullable(labels)
/** The maximum number of results to return */
fun limit(): Optional = Optional.ofNullable(limit)
@@ -56,8 +55,7 @@ private constructor(
private var inboxId: String? = null
private var cursor: String? = null
- private var isRead: Boolean? = null
- private var isSpam: Boolean? = null
+ private var labels: String? = null
private var limit: Double? = null
private var additionalHeaders: Headers.Builder = Headers.builder()
private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
@@ -66,8 +64,7 @@ private constructor(
internal fun from(threadListParams: ThreadListParams) = apply {
inboxId = threadListParams.inboxId
cursor = threadListParams.cursor
- isRead = threadListParams.isRead
- isSpam = threadListParams.isSpam
+ labels = threadListParams.labels
limit = threadListParams.limit
additionalHeaders = threadListParams.additionalHeaders.toBuilder()
additionalQueryParams = threadListParams.additionalQueryParams.toBuilder()
@@ -84,31 +81,14 @@ private constructor(
/** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */
fun cursor(cursor: Optional) = cursor(cursor.getOrNull())
- /** Filter by read status. */
- fun isRead(isRead: Boolean?) = apply { this.isRead = isRead }
-
/**
- * Alias for [Builder.isRead].
- *
- * This unboxed primitive overload exists for backwards compatibility.
- */
- fun isRead(isRead: Boolean) = isRead(isRead as Boolean?)
-
- /** Alias for calling [Builder.isRead] with `isRead.orElse(null)`. */
- fun isRead(isRead: Optional) = isRead(isRead.getOrNull())
-
- /** Filter by spam status. */
- fun isSpam(isSpam: Boolean?) = apply { this.isSpam = isSpam }
-
- /**
- * Alias for [Builder.isSpam].
- *
- * This unboxed primitive overload exists for backwards compatibility.
+ * Comma-separated labels to filter by (AND logic). Threads with spam/trash are excluded by
+ * default unless explicitly requested via ?labels=spam or ?labels=trash.
*/
- fun isSpam(isSpam: Boolean) = isSpam(isSpam as Boolean?)
+ fun labels(labels: String?) = apply { this.labels = labels }
- /** Alias for calling [Builder.isSpam] with `isSpam.orElse(null)`. */
- fun isSpam(isSpam: Optional) = isSpam(isSpam.getOrNull())
+ /** Alias for calling [Builder.labels] with `labels.orElse(null)`. */
+ fun labels(labels: Optional) = labels(labels.getOrNull())
/** The maximum number of results to return */
fun limit(limit: Double?) = apply { this.limit = limit }
@@ -230,8 +210,7 @@ private constructor(
ThreadListParams(
inboxId,
cursor,
- isRead,
- isSpam,
+ labels,
limit,
additionalHeaders.build(),
additionalQueryParams.build(),
@@ -250,8 +229,7 @@ private constructor(
QueryParams.builder()
.apply {
cursor?.let { put("cursor", it) }
- isRead?.let { put("isRead", it.toString()) }
- isSpam?.let { put("isSpam", it.toString()) }
+ labels?.let { put("labels", it) }
limit?.let { put("limit", it.toString()) }
putAll(additionalQueryParams)
}
@@ -265,24 +243,15 @@ private constructor(
return other is ThreadListParams &&
inboxId == other.inboxId &&
cursor == other.cursor &&
- isRead == other.isRead &&
- isSpam == other.isSpam &&
+ labels == other.labels &&
limit == other.limit &&
additionalHeaders == other.additionalHeaders &&
additionalQueryParams == other.additionalQueryParams
}
override fun hashCode(): Int =
- Objects.hash(
- inboxId,
- cursor,
- isRead,
- isSpam,
- limit,
- additionalHeaders,
- additionalQueryParams,
- )
+ Objects.hash(inboxId, cursor, labels, limit, additionalHeaders, additionalQueryParams)
override fun toString() =
- "ThreadListParams{inboxId=$inboxId, cursor=$cursor, isRead=$isRead, isSpam=$isSpam, limit=$limit, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
+ "ThreadListParams{inboxId=$inboxId, cursor=$cursor, labels=$labels, limit=$limit, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
}
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/Message.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/Message.kt
index 4f0662b..1476117 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/Message.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/Message.kt
@@ -30,6 +30,7 @@ private constructor(
private val createdAt: JsonField,
private val from: JsonField,
private val inboxId: JsonField,
+ private val labels: JsonField>,
private val messageId: JsonField,
private val receivedAt: JsonField,
private val replyTo: JsonField>,
@@ -51,6 +52,7 @@ private constructor(
@JsonProperty("createdAt") @ExcludeMissing createdAt: JsonField = JsonMissing.of(),
@JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(),
@JsonProperty("inboxId") @ExcludeMissing inboxId: JsonField = JsonMissing.of(),
+ @JsonProperty("labels") @ExcludeMissing labels: JsonField> = JsonMissing.of(),
@JsonProperty("messageId") @ExcludeMissing messageId: JsonField = JsonMissing.of(),
@JsonProperty("receivedAt")
@ExcludeMissing
@@ -70,6 +72,7 @@ private constructor(
createdAt,
from,
inboxId,
+ labels,
messageId,
receivedAt,
replyTo,
@@ -137,6 +140,14 @@ private constructor(
*/
fun inboxId(): Optional = inboxId.getOptional("inboxId")
+ /**
+ * The message labels.
+ *
+ * @throws NuntlyInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun labels(): List = labels.getRequired("labels")
+
/**
* The email Message-ID header.
*
@@ -244,6 +255,13 @@ private constructor(
*/
@JsonProperty("inboxId") @ExcludeMissing fun _inboxId(): JsonField = inboxId
+ /**
+ * Returns the raw JSON value of [labels].
+ *
+ * Unlike [labels], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("labels") @ExcludeMissing fun _labels(): JsonField> = labels
+
/**
* Returns the raw JSON value of [messageId].
*
@@ -319,6 +337,7 @@ private constructor(
* .createdAt()
* .from()
* .inboxId()
+ * .labels()
* .messageId()
* .receivedAt()
* .replyTo()
@@ -341,6 +360,7 @@ private constructor(
private var createdAt: JsonField? = null
private var from: JsonField? = null
private var inboxId: JsonField? = null
+ private var labels: JsonField>? = null
private var messageId: JsonField? = null
private var receivedAt: JsonField? = null
private var replyTo: JsonField>? = null
@@ -359,6 +379,7 @@ private constructor(
createdAt = message.createdAt
from = message.from
inboxId = message.inboxId
+ labels = message.labels.map { it.toMutableList() }
messageId = message.messageId
receivedAt = message.receivedAt
replyTo = message.replyTo.map { it.toMutableList() }
@@ -484,6 +505,32 @@ private constructor(
*/
fun inboxId(inboxId: JsonField) = apply { this.inboxId = inboxId }
+ /** The message labels. */
+ fun labels(labels: List) = labels(JsonField.of(labels))
+
+ /**
+ * Sets [Builder.labels] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.labels] with a well-typed `List` value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun labels(labels: JsonField>) = apply {
+ this.labels = labels.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [String] to [labels].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addLabel(label: String) = apply {
+ labels =
+ (labels ?: JsonField.of(mutableListOf())).also {
+ checkKnown("labels", it).add(label)
+ }
+ }
+
/** The email Message-ID header. */
fun messageId(messageId: String) = messageId(JsonField.of(messageId))
@@ -624,6 +671,7 @@ private constructor(
* .createdAt()
* .from()
* .inboxId()
+ * .labels()
* .messageId()
* .receivedAt()
* .replyTo()
@@ -644,6 +692,7 @@ private constructor(
checkRequired("createdAt", createdAt),
checkRequired("from", from),
checkRequired("inboxId", inboxId),
+ checkRequired("labels", labels).map { it.toImmutable() },
checkRequired("messageId", messageId),
checkRequired("receivedAt", receivedAt),
checkRequired("replyTo", replyTo).map { it.toImmutable() },
@@ -657,6 +706,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Message = apply {
if (validated) {
return@apply
@@ -669,6 +726,7 @@ private constructor(
createdAt()
from()
inboxId()
+ labels()
messageId()
receivedAt()
replyTo()
@@ -701,6 +759,7 @@ private constructor(
(if (createdAt.asKnown().isPresent) 1 else 0) +
(if (from.asKnown().isPresent) 1 else 0) +
(if (inboxId.asKnown().isPresent) 1 else 0) +
+ (labels.asKnown().getOrNull()?.size ?: 0) +
(if (messageId.asKnown().isPresent) 1 else 0) +
(if (receivedAt.asKnown().isPresent) 1 else 0) +
(replyTo.asKnown().getOrNull()?.size ?: 0) +
@@ -809,6 +868,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
@@ -860,6 +928,7 @@ private constructor(
createdAt == other.createdAt &&
from == other.from &&
inboxId == other.inboxId &&
+ labels == other.labels &&
messageId == other.messageId &&
receivedAt == other.receivedAt &&
replyTo == other.replyTo &&
@@ -879,6 +948,7 @@ private constructor(
createdAt,
from,
inboxId,
+ labels,
messageId,
receivedAt,
replyTo,
@@ -893,5 +963,5 @@ private constructor(
override fun hashCode(): Int = hashCode
override fun toString() =
- "Message{id=$id, attachmentCount=$attachmentCount, bcc=$bcc, cc=$cc, createdAt=$createdAt, from=$from, inboxId=$inboxId, messageId=$messageId, receivedAt=$receivedAt, replyTo=$replyTo, status=$status, subject=$subject, threadId=$threadId, to=$to, additionalProperties=$additionalProperties}"
+ "Message{id=$id, attachmentCount=$attachmentCount, bcc=$bcc, cc=$cc, createdAt=$createdAt, from=$from, inboxId=$inboxId, labels=$labels, messageId=$messageId, receivedAt=$receivedAt, replyTo=$replyTo, status=$status, subject=$subject, threadId=$threadId, to=$to, additionalProperties=$additionalProperties}"
}
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageAttachment.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageAttachment.kt
index 67bfc01..7c267f3 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageAttachment.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageAttachment.kt
@@ -366,6 +366,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageAttachment = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContent.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContent.kt
index edebecc..a0c27b0 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContent.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContent.kt
@@ -218,6 +218,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageContent = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContentItem.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContentItem.kt
index d2bd934..f523e6b 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContentItem.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageContentItem.kt
@@ -212,6 +212,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageContentItem = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageDetail.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageDetail.kt
index e599307..db87a95 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageDetail.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageDetail.kt
@@ -31,6 +31,7 @@ private constructor(
private val from: JsonField,
private val headers: JsonField,
private val inboxId: JsonField,
+ private val labels: JsonField>,
private val messageId: JsonField,
private val receivedAt: JsonField,
private val replyTo: JsonField>,
@@ -53,6 +54,7 @@ private constructor(
@JsonProperty("from") @ExcludeMissing from: JsonField = JsonMissing.of(),
@JsonProperty("headers") @ExcludeMissing headers: JsonField = JsonMissing.of(),
@JsonProperty("inboxId") @ExcludeMissing inboxId: JsonField = JsonMissing.of(),
+ @JsonProperty("labels") @ExcludeMissing labels: JsonField> = JsonMissing.of(),
@JsonProperty("messageId") @ExcludeMissing messageId: JsonField = JsonMissing.of(),
@JsonProperty("receivedAt")
@ExcludeMissing
@@ -73,6 +75,7 @@ private constructor(
from,
headers,
inboxId,
+ labels,
messageId,
receivedAt,
replyTo,
@@ -148,6 +151,14 @@ private constructor(
*/
fun inboxId(): Optional = inboxId.getOptional("inboxId")
+ /**
+ * The message labels.
+ *
+ * @throws NuntlyInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun labels(): List = labels.getRequired("labels")
+
/**
* The email Message-ID header.
*
@@ -262,6 +273,13 @@ private constructor(
*/
@JsonProperty("inboxId") @ExcludeMissing fun _inboxId(): JsonField = inboxId
+ /**
+ * Returns the raw JSON value of [labels].
+ *
+ * Unlike [labels], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("labels") @ExcludeMissing fun _labels(): JsonField> = labels
+
/**
* Returns the raw JSON value of [messageId].
*
@@ -338,6 +356,7 @@ private constructor(
* .from()
* .headers()
* .inboxId()
+ * .labels()
* .messageId()
* .receivedAt()
* .replyTo()
@@ -361,6 +380,7 @@ private constructor(
private var from: JsonField? = null
private var headers: JsonField? = null
private var inboxId: JsonField? = null
+ private var labels: JsonField>? = null
private var messageId: JsonField? = null
private var receivedAt: JsonField? = null
private var replyTo: JsonField>? = null
@@ -380,6 +400,7 @@ private constructor(
from = messageDetail.from
headers = messageDetail.headers
inboxId = messageDetail.inboxId
+ labels = messageDetail.labels.map { it.toMutableList() }
messageId = messageDetail.messageId
receivedAt = messageDetail.receivedAt
replyTo = messageDetail.replyTo.map { it.toMutableList() }
@@ -519,6 +540,32 @@ private constructor(
*/
fun inboxId(inboxId: JsonField) = apply { this.inboxId = inboxId }
+ /** The message labels. */
+ fun labels(labels: List) = labels(JsonField.of(labels))
+
+ /**
+ * Sets [Builder.labels] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.labels] with a well-typed `List` value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun labels(labels: JsonField>) = apply {
+ this.labels = labels.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [String] to [labels].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addLabel(label: String) = apply {
+ labels =
+ (labels ?: JsonField.of(mutableListOf())).also {
+ checkKnown("labels", it).add(label)
+ }
+ }
+
/** The email Message-ID header. */
fun messageId(messageId: String) = messageId(JsonField.of(messageId))
@@ -660,6 +707,7 @@ private constructor(
* .from()
* .headers()
* .inboxId()
+ * .labels()
* .messageId()
* .receivedAt()
* .replyTo()
@@ -681,6 +729,7 @@ private constructor(
checkRequired("from", from),
checkRequired("headers", headers),
checkRequired("inboxId", inboxId),
+ checkRequired("labels", labels).map { it.toImmutable() },
checkRequired("messageId", messageId),
checkRequired("receivedAt", receivedAt),
checkRequired("replyTo", replyTo).map { it.toImmutable() },
@@ -694,6 +743,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageDetail = apply {
if (validated) {
return@apply
@@ -707,6 +764,7 @@ private constructor(
from()
headers().ifPresent { it.validate() }
inboxId()
+ labels()
messageId()
receivedAt()
replyTo()
@@ -740,6 +798,7 @@ private constructor(
(if (from.asKnown().isPresent) 1 else 0) +
(headers.asKnown().getOrNull()?.validity() ?: 0) +
(if (inboxId.asKnown().isPresent) 1 else 0) +
+ (labels.asKnown().getOrNull()?.size ?: 0) +
(if (messageId.asKnown().isPresent) 1 else 0) +
(if (receivedAt.asKnown().isPresent) 1 else 0) +
(replyTo.asKnown().getOrNull()?.size ?: 0) +
@@ -807,6 +866,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Headers = apply {
if (validated) {
return@apply
@@ -948,6 +1016,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Status = apply {
if (validated) {
return@apply
@@ -1000,6 +1077,7 @@ private constructor(
from == other.from &&
headers == other.headers &&
inboxId == other.inboxId &&
+ labels == other.labels &&
messageId == other.messageId &&
receivedAt == other.receivedAt &&
replyTo == other.replyTo &&
@@ -1020,6 +1098,7 @@ private constructor(
from,
headers,
inboxId,
+ labels,
messageId,
receivedAt,
replyTo,
@@ -1034,5 +1113,5 @@ private constructor(
override fun hashCode(): Int = hashCode
override fun toString() =
- "MessageDetail{id=$id, attachmentCount=$attachmentCount, bcc=$bcc, cc=$cc, createdAt=$createdAt, from=$from, headers=$headers, inboxId=$inboxId, messageId=$messageId, receivedAt=$receivedAt, replyTo=$replyTo, status=$status, subject=$subject, threadId=$threadId, to=$to, additionalProperties=$additionalProperties}"
+ "MessageDetail{id=$id, attachmentCount=$attachmentCount, bcc=$bcc, cc=$cc, createdAt=$createdAt, from=$from, headers=$headers, inboxId=$inboxId, labels=$labels, messageId=$messageId, receivedAt=$receivedAt, replyTo=$replyTo, status=$status, subject=$subject, threadId=$threadId, to=$to, additionalProperties=$additionalProperties}"
}
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardParams.kt
index 95fd1de..e939415 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardParams.kt
@@ -454,6 +454,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardResponse.kt
index 0e78efb..8b636bd 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageForwardResponse.kt
@@ -230,6 +230,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageForwardResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageListPageResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageListPageResponse.kt
index 5908848..a5490fe 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageListPageResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageListPageResponse.kt
@@ -175,6 +175,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageListPageResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyParams.kt
index c5ea7c3..3291537 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyParams.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyParams.kt
@@ -464,6 +464,15 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): Body = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyResponse.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyResponse.kt
index dc5209a..4b896c2 100644
--- a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyResponse.kt
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageReplyResponse.kt
@@ -230,6 +230,14 @@ private constructor(
private var validated: Boolean = false
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws NuntlyInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
fun validate(): MessageReplyResponse = apply {
if (validated) {
return@apply
diff --git a/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageUpdateParams.kt b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageUpdateParams.kt
new file mode 100644
index 0000000..0c6ddf6
--- /dev/null
+++ b/nuntly-java-core/src/main/kotlin/com/nuntly/models/messages/MessageUpdateParams.kt
@@ -0,0 +1,544 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.nuntly.models.messages
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.nuntly.core.ExcludeMissing
+import com.nuntly.core.JsonField
+import com.nuntly.core.JsonMissing
+import com.nuntly.core.JsonValue
+import com.nuntly.core.Params
+import com.nuntly.core.checkKnown
+import com.nuntly.core.http.Headers
+import com.nuntly.core.http.QueryParams
+import com.nuntly.core.toImmutable
+import com.nuntly.errors.NuntlyInvalidDataException
+import java.util.Collections
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/** Update message labels. Only available for messages in user-created inboxes. */
+class MessageUpdateParams
+private constructor(
+ private val messageId: String?,
+ private val body: Body,
+ private val additionalHeaders: Headers,
+ private val additionalQueryParams: QueryParams,
+) : Params {
+
+ fun messageId(): Optional = Optional.ofNullable(messageId)
+
+ /**
+ * Labels to add to the message.
+ *
+ * @throws NuntlyInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun addLabels(): Optional> = body.addLabels()
+
+ /**
+ * Labels to remove from the message.
+ *
+ * @throws NuntlyInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun removeLabels(): Optional> = body.removeLabels()
+
+ /**
+ * Returns the raw JSON value of [addLabels].
+ *
+ * Unlike [addLabels], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _addLabels(): JsonField> = body._addLabels()
+
+ /**
+ * Returns the raw JSON value of [removeLabels].
+ *
+ * Unlike [removeLabels], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _removeLabels(): JsonField> = body._removeLabels()
+
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
+ /** Additional headers to send with the request. */
+ fun _additionalHeaders(): Headers = additionalHeaders
+
+ /** Additional query param to send with the request. */
+ fun _additionalQueryParams(): QueryParams = additionalQueryParams
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ @JvmStatic fun none(): MessageUpdateParams = builder().build()
+
+ /** Returns a mutable builder for constructing an instance of [MessageUpdateParams]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [MessageUpdateParams]. */
+ class Builder internal constructor() {
+
+ private var messageId: String? = null
+ private var body: Body.Builder = Body.builder()
+ private var additionalHeaders: Headers.Builder = Headers.builder()
+ private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
+
+ @JvmSynthetic
+ internal fun from(messageUpdateParams: MessageUpdateParams) = apply {
+ messageId = messageUpdateParams.messageId
+ body = messageUpdateParams.body.toBuilder()
+ additionalHeaders = messageUpdateParams.additionalHeaders.toBuilder()
+ additionalQueryParams = messageUpdateParams.additionalQueryParams.toBuilder()
+ }
+
+ fun messageId(messageId: String?) = apply { this.messageId = messageId }
+
+ /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */
+ fun messageId(messageId: Optional) = messageId(messageId.getOrNull())
+
+ /**
+ * Sets the entire request body.
+ *
+ * This is generally only useful if you are already constructing the body separately.
+ * Otherwise, it's more convenient to use the top-level setters instead:
+ * - [addLabels]
+ * - [removeLabels]
+ */
+ fun body(body: Body) = apply { this.body = body.toBuilder() }
+
+ /** Labels to add to the message. */
+ fun addLabels(addLabels: List) = apply { body.addLabels(addLabels) }
+
+ /**
+ * Sets [Builder.addLabels] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.addLabels] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun addLabels(addLabels: JsonField>) = apply { body.addLabels(addLabels) }
+
+ /**
+ * Adds a single [String] to [addLabels].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addAddLabel(addLabel: String) = apply { body.addAddLabel(addLabel) }
+
+ /** Labels to remove from the message. */
+ fun removeLabels(removeLabels: List) = apply { body.removeLabels(removeLabels) }
+
+ /**
+ * Sets [Builder.removeLabels] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.removeLabels] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun removeLabels(removeLabels: JsonField>) = apply {
+ body.removeLabels(removeLabels)
+ }
+
+ /**
+ * Adds a single [String] to [removeLabels].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addRemoveLabel(removeLabel: String) = apply { body.addRemoveLabel(removeLabel) }
+
+ fun additionalBodyProperties(additionalBodyProperties: Map) = apply {
+ body.additionalProperties(additionalBodyProperties)
+ }
+
+ fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply {
+ body.putAdditionalProperty(key, value)
+ }
+
+ fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) =
+ apply {
+ body.putAllAdditionalProperties(additionalBodyProperties)
+ }
+
+ fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) }
+
+ fun removeAllAdditionalBodyProperties(keys: Set) = apply {
+ body.removeAllAdditionalProperties(keys)
+ }
+
+ fun additionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun additionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun putAdditionalHeader(name: String, value: String) = apply {
+ additionalHeaders.put(name, value)
+ }
+
+ fun putAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.put(name, values)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun replaceAdditionalHeaders(name: String, value: String) = apply {
+ additionalHeaders.replace(name, value)
+ }
+
+ fun replaceAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.replace(name, values)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
+
+ fun removeAllAdditionalHeaders(names: Set) = apply {
+ additionalHeaders.removeAll(names)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: Map>) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun putAdditionalQueryParam(key: String, value: String) = apply {
+ additionalQueryParams.put(key, value)
+ }
+
+ fun putAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.put(key, values)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, value: String) = apply {
+ additionalQueryParams.replace(key, value)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.replace(key, values)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
+
+ fun removeAllAdditionalQueryParams(keys: Set) = apply {
+ additionalQueryParams.removeAll(keys)
+ }
+
+ /**
+ * Returns an immutable instance of [MessageUpdateParams].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): MessageUpdateParams =
+ MessageUpdateParams(
+ messageId,
+ body.build(),
+ additionalHeaders.build(),
+ additionalQueryParams.build(),
+ )
+ }
+
+ fun _body(): Body = body
+
+ fun _pathParam(index: Int): String =
+ when (index) {
+ 0 -> messageId ?: ""
+ else -> ""
+ }
+
+ override fun _headers(): Headers = additionalHeaders
+
+ override fun _queryParams(): QueryParams = additionalQueryParams
+
+ class Body
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val addLabels: JsonField>,
+ private val removeLabels: JsonField>,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("addLabels")
+ @ExcludeMissing
+ addLabels: JsonField> = JsonMissing.of(),
+ @JsonProperty("removeLabels")
+ @ExcludeMissing
+ removeLabels: JsonField> = JsonMissing.of(),
+ ) : this(addLabels, removeLabels, mutableMapOf())
+
+ /**
+ * Labels to add to the message.
+ *
+ * @throws NuntlyInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun addLabels(): Optional> = addLabels.getOptional("addLabels")
+
+ /**
+ * Labels to remove from the message.
+ *
+ * @throws NuntlyInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun removeLabels(): Optional> = removeLabels.getOptional("removeLabels")
+
+ /**
+ * Returns the raw JSON value of [addLabels].
+ *
+ * Unlike [addLabels], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("addLabels")
+ @ExcludeMissing
+ fun _addLabels(): JsonField> = addLabels
+
+ /**
+ * Returns the raw JSON value of [removeLabels].
+ *
+ * Unlike [removeLabels], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("removeLabels")
+ @ExcludeMissing
+ fun _removeLabels(): JsonField> = removeLabels
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /** Returns a mutable builder for constructing an instance of [Body]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [Body]. */
+ class Builder internal constructor() {
+
+ private var addLabels: JsonField>? = null
+ private var removeLabels: JsonField>? = null
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(body: Body) = apply {
+ addLabels = body.addLabels.map { it.toMutableList() }
+ removeLabels = body.removeLabels.map { it.toMutableList() }
+ additionalProperties = body.additionalProperties.toMutableMap()
+ }
+
+ /** Labels to add to the message. */
+ fun addLabels(addLabels: List) = addLabels(JsonField.of(addLabels))
+
+ /**
+ * Sets [Builder.addLabels] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.addLabels] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun addLabels(addLabels: JsonField>) = apply {
+ this.addLabels = addLabels.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [String] to [addLabels].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addAddLabel(addLabel: String) = apply {
+ addLabels =
+ (addLabels ?: JsonField.of(mutableListOf())).also {
+ checkKnown("addLabels", it).add(addLabel)
+ }
+ }
+
+ /** Labels to remove from the message. */
+ fun removeLabels(removeLabels: List) = removeLabels(JsonField.of(removeLabels))
+
+ /**
+ * Sets [Builder.removeLabels] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.removeLabels] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun removeLabels(removeLabels: JsonField>) = apply {
+ this.removeLabels = removeLabels.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [String] to [removeLabels].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addRemoveLabel(removeLabel: String) = apply {
+ removeLabels =
+ (removeLabels ?: JsonField.of(mutableListOf())).also {
+ checkKnown("removeLabels", it).add(removeLabel)
+ }
+ }
+
+ fun additionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.clear()
+ putAllAdditionalProperties(additionalProperties)
+ }
+
+ fun putAdditionalProperty(key: String, value: JsonValue) = apply {
+ additionalProperties.put(key, value)
+ }
+
+ fun putAllAdditionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.putAll(additionalProperties)
+ }
+
+ fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) }
+
+ fun removeAllAdditionalProperties(keys: Set